conductor-board 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +5 -1
- package/cli/complete.js +26 -0
- package/cli/writer.js +205 -64
- package/dist/assets/index-CKHEldJ6.css +1 -0
- package/dist/assets/index-D5hLWXgI.js +34 -0
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/server/server.js +77 -1
- package/dist/assets/index-DvTrz5lj.js +0 -34
- package/dist/assets/index-ilfk-igS.css +0 -1
package/dist/index.html
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<meta name="theme-color" content="#0a0a0f" />
|
|
8
8
|
<title>Agent Conductor — Board</title>
|
|
9
|
-
<script type="module" crossorigin src="./assets/index-
|
|
9
|
+
<script type="module" crossorigin src="./assets/index-D5hLWXgI.js"></script>
|
|
10
10
|
<link rel="modulepreload" crossorigin href="./assets/motion-Dmvx5jlk.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="./assets/yaml-NA7d4LV6.js">
|
|
12
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
12
|
+
<link rel="stylesheet" crossorigin href="./assets/index-CKHEldJ6.css">
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
|
15
15
|
<div id="root"></div>
|
package/package.json
CHANGED
package/server/server.js
CHANGED
|
@@ -223,6 +223,7 @@ function archiveIfDone(historyDir, snapshot, archived) {
|
|
|
223
223
|
|
|
224
224
|
const record = {
|
|
225
225
|
run_id: runId,
|
|
226
|
+
run_name: status.run_name || null,
|
|
226
227
|
workflow: status.workflow || "workflow",
|
|
227
228
|
status: status.status,
|
|
228
229
|
started_at: status.started_at || null,
|
|
@@ -508,7 +509,15 @@ function serveStatic(req, res) {
|
|
|
508
509
|
return;
|
|
509
510
|
}
|
|
510
511
|
const ext = path.extname(filePath);
|
|
511
|
-
|
|
512
|
+
const headers = { "content-type": MIME[ext] || "application/octet-stream" };
|
|
513
|
+
// index.html must always revalidate so a fresh build is picked up on reload;
|
|
514
|
+
// the hashed /assets/ files are content-addressed, so cache them hard.
|
|
515
|
+
if (ext === ".html") {
|
|
516
|
+
headers["cache-control"] = "no-cache, no-store, must-revalidate";
|
|
517
|
+
} else if (urlPath.startsWith("/assets/")) {
|
|
518
|
+
headers["cache-control"] = "public, max-age=31536000, immutable";
|
|
519
|
+
}
|
|
520
|
+
res.writeHead(200, headers);
|
|
512
521
|
fs.createReadStream(filePath).pipe(res);
|
|
513
522
|
}
|
|
514
523
|
|
|
@@ -900,6 +909,73 @@ export function startServer({ statusPath, conductorPath: explicitConductor, port
|
|
|
900
909
|
});
|
|
901
910
|
return;
|
|
902
911
|
}
|
|
912
|
+
// developer notes / directives on activity cards — the flow-manager feedback loop.
|
|
913
|
+
// Body actions: create {card, cardTitle, step, text, directive, scope}; edit {id, text, directive,
|
|
914
|
+
// scope}; remove {id, action:"remove"}. Edits/removals are logged to the note's audit history,
|
|
915
|
+
// never destroyed — the record stays, the footnote grows ("edited from X to Y").
|
|
916
|
+
if (req.method === "POST" && (m = url.match(/^\/api\/workflow\/([^/]+)\/comment$/))) {
|
|
917
|
+
const wf = findWf(decodeURIComponent(m[1]));
|
|
918
|
+
if (!wf) return json(res, 404, { error: "not found" });
|
|
919
|
+
readBody(req).then((bodyStr) => {
|
|
920
|
+
let body;
|
|
921
|
+
try {
|
|
922
|
+
body = JSON.parse(bodyStr || "{}");
|
|
923
|
+
} catch {
|
|
924
|
+
return json(res, 400, { error: "invalid request body" });
|
|
925
|
+
}
|
|
926
|
+
let status;
|
|
927
|
+
try {
|
|
928
|
+
status = JSON.parse(fs.readFileSync(wf.statusPath, "utf8"));
|
|
929
|
+
} catch {
|
|
930
|
+
return json(res, 500, { error: "could not read status.json" });
|
|
931
|
+
}
|
|
932
|
+
const notes = (status.developer_notes = Array.isArray(status.developer_notes) ? status.developer_notes : []);
|
|
933
|
+
const at = new Date().toISOString();
|
|
934
|
+
const text = typeof body.text === "string" ? body.text.trim() : "";
|
|
935
|
+
|
|
936
|
+
if (body.id) {
|
|
937
|
+
const n = notes.find((x) => x && x.id === body.id);
|
|
938
|
+
if (!n) return json(res, 404, { error: "note not found" });
|
|
939
|
+
n.history = Array.isArray(n.history) ? n.history : [];
|
|
940
|
+
if (body.action === "remove") {
|
|
941
|
+
n.history.push({ at, action: "removed", from: n.text });
|
|
942
|
+
n.status = "removed";
|
|
943
|
+
} else {
|
|
944
|
+
if (n.text !== text)
|
|
945
|
+
n.history.push({ at, action: n.status === "removed" ? "restored" : "edited", from: n.text, to: text });
|
|
946
|
+
n.text = text;
|
|
947
|
+
n.directive = !!body.directive;
|
|
948
|
+
if (typeof body.scope === "string") n.scope = body.scope;
|
|
949
|
+
n.updated_at = at;
|
|
950
|
+
n.status = "open"; // an edit reopens the ask so the next run reconsiders it
|
|
951
|
+
delete n.resolution;
|
|
952
|
+
}
|
|
953
|
+
} else {
|
|
954
|
+
// create
|
|
955
|
+
if (!body.card || !text) return json(res, 400, { error: "card id and text required" });
|
|
956
|
+
notes.push({
|
|
957
|
+
id: `${body.card}:${Date.now()}`,
|
|
958
|
+
at,
|
|
959
|
+
updated_at: at,
|
|
960
|
+
step: body.step || "",
|
|
961
|
+
card: body.card,
|
|
962
|
+
card_title: typeof body.cardTitle === "string" ? body.cardTitle : undefined,
|
|
963
|
+
text,
|
|
964
|
+
directive: !!body.directive,
|
|
965
|
+
scope: typeof body.scope === "string" ? body.scope : undefined,
|
|
966
|
+
status: "open",
|
|
967
|
+
history: [{ at, action: "created", to: text }],
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
try {
|
|
971
|
+
fs.writeFileSync(wf.statusPath, JSON.stringify(status, null, 2));
|
|
972
|
+
} catch (e) {
|
|
973
|
+
return json(res, 500, { error: `write failed: ${e.message}` });
|
|
974
|
+
}
|
|
975
|
+
return json(res, 200, { ok: true });
|
|
976
|
+
});
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
903
979
|
if ((m = url.match(/^\/api\/workflow\/([^/]+)\/history$/))) {
|
|
904
980
|
const wf = findWf(decodeURIComponent(m[1]));
|
|
905
981
|
return wf ? json(res, 200, listHistory(wf.historyDir)) : json(res, 404, { error: "not found" });
|