The previous commit incorrectly deleted all workflows. Only restart-gateway should be removed (replaced by direct shell trigger). Other workflows (solve-issue, extract-knowledge, develop-sense, develop-workflow) are CLI-triggered and independent of sense coupling.
87 lines
2.4 KiB
TypeScript
87 lines
2.4 KiB
TypeScript
import { join } from "node:path";
|
|
import type { RoleStep, WorkflowMessage } from "@uncaged/nerve-core";
|
|
|
|
type SolveIssueParse = {
|
|
host: string;
|
|
owner: string;
|
|
repo: string;
|
|
number: number;
|
|
};
|
|
|
|
type SolveIssueRepo = {
|
|
path: string;
|
|
defaultBranch: string;
|
|
packageManager: string;
|
|
};
|
|
|
|
const HOME = process.env.HOME ?? "/home/azureuser";
|
|
|
|
function extractMarkedSection(text: string, marker: string): Record<string, string> | null {
|
|
const escaped = marker.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
const re = new RegExp(`---${escaped}---\\s*([\\s\\S]*?)(?:\\n---|$)`);
|
|
const m = text.match(re);
|
|
if (m === null) {
|
|
return null;
|
|
}
|
|
const rec: Record<string, string> = {};
|
|
for (const line of m[1].split("\n")) {
|
|
const kv = line.match(/^([a-zA-Z]+):\s*(.+)$/);
|
|
if (kv !== null) {
|
|
rec[kv[1]] = kv[2].trim();
|
|
}
|
|
}
|
|
return Object.keys(rec).length > 0 ? rec : null;
|
|
}
|
|
|
|
function parseSolveIssueParse(text: string): SolveIssueParse | null {
|
|
const rec = extractMarkedSection(text, "SOLVE_ISSUE_PARSE");
|
|
if (rec === null) {
|
|
return null;
|
|
}
|
|
const host = rec.host ?? "";
|
|
const owner = rec.owner ?? "";
|
|
const repo = rec.repo ?? "";
|
|
const num = Number(rec.number ?? "");
|
|
if (host.length === 0 || owner.length === 0 || repo.length === 0 || !Number.isFinite(num) || num <= 0) {
|
|
return null;
|
|
}
|
|
return { host, owner, repo, number: num };
|
|
}
|
|
|
|
function parseSolveIssueRepo(text: string): SolveIssueRepo | null {
|
|
const rec = extractMarkedSection(text, "SOLVE_ISSUE_REPO");
|
|
if (rec === null) {
|
|
return null;
|
|
}
|
|
const path = rec.path ?? "";
|
|
if (path.length === 0) {
|
|
return null;
|
|
}
|
|
return {
|
|
path,
|
|
defaultBranch: rec.defaultBranch ?? "main",
|
|
packageManager: rec.packageManager ?? "pnpm",
|
|
};
|
|
}
|
|
|
|
/** Prefer explicit prepare marker; else ~/Code/<owner>/<repo> from read-issue parse block. */
|
|
export function resolveRepoCwd(messages: WorkflowMessage[]): string | null {
|
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
if (messages[i].role === "prepare") {
|
|
const repo = parseSolveIssueRepo(messages[i].content);
|
|
if (repo !== null) {
|
|
return repo.path;
|
|
}
|
|
}
|
|
}
|
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
if (messages[i].role === "read-issue") {
|
|
const parsed = parseSolveIssueParse(messages[i].content);
|
|
if (parsed !== null) {
|
|
return join(HOME, "Code", parsed.owner, parsed.repo);
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|