conductor-board 2.2.0 → 2.3.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/cli/writer.js +88 -63
- package/dist/assets/index-B-Kwn4YB.js +34 -0
- package/dist/assets/index-a4RLv680.css +1 -0
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/server/server.js +10 -1
- package/dist/assets/index-DvTrz5lj.js +0 -34
- package/dist/assets/index-ilfk-igS.css +0 -1
package/cli/writer.js
CHANGED
|
@@ -338,72 +338,95 @@ export async function runStatusInit(args) {
|
|
|
338
338
|
const runId =
|
|
339
339
|
(typeof flag(args, ["--run-id"]) === "string" && flag(args, ["--run-id"])) ||
|
|
340
340
|
now().replace(/\.\d+Z$/, "").replace(/:/g, "-");
|
|
341
|
-
const
|
|
341
|
+
const wfName = doc.name || "workflow";
|
|
342
342
|
|
|
343
|
-
//
|
|
344
|
-
//
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
(
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
const seen = new Set();
|
|
353
|
-
|
|
354
|
-
// _improve::read-knowledge leads the phase: read + categorize the knowledge.
|
|
355
|
-
if (knowledge.length > 0) {
|
|
356
|
-
const cat = (s) => knowledge.filter((k) => (k.status || "emerging") === s).length;
|
|
357
|
-
const cross = knowledge.filter((k) => (k.scope || "this-conductor") !== "this-conductor").length;
|
|
358
|
-
steps["_improve::read-knowledge"] = {
|
|
359
|
-
status: "pending",
|
|
360
|
-
gate: "pending",
|
|
361
|
-
attempt: 1,
|
|
362
|
-
improve: {
|
|
363
|
-
title: "Read knowledge",
|
|
364
|
-
kind: "read-knowledge",
|
|
365
|
-
note:
|
|
366
|
-
`${cat("proven")} proven · ${cat("emerging")} emerging · ${cat("applied")} applied · ` +
|
|
367
|
-
`${cross} cross-cutting`,
|
|
368
|
-
},
|
|
369
|
-
};
|
|
343
|
+
// §6.2 — every run gets a human name: {workflow}-run-{N}-{timestamp}. N is the
|
|
344
|
+
// count of archived runs + 1; the timestamp is the run id trimmed to minutes.
|
|
345
|
+
const nameSlug = String(wfName).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
346
|
+
const historyDir = path.join(path.dirname(sp), "history");
|
|
347
|
+
let priorRuns = 0;
|
|
348
|
+
try {
|
|
349
|
+
priorRuns = fs.readdirSync(historyDir).filter((f) => f.endsWith(".json")).length;
|
|
350
|
+
} catch {
|
|
351
|
+
/* no history yet */
|
|
370
352
|
}
|
|
353
|
+
const tsShort = runId.replace(/-\d{2}$/, ""); // 2026-06-04T12-30-00 → 2026-06-04T12-30
|
|
354
|
+
const runName =
|
|
355
|
+
(typeof flag(args, ["--run-name"]) === "string" && flag(args, ["--run-name"])) ||
|
|
356
|
+
`${nameSlug}-run-${priorRuns + 1}-${tsShort}`;
|
|
357
|
+
|
|
358
|
+
// §6.1 — auto_improve (default on). When off, the Phase 0 self-improvement
|
|
359
|
+
// pass is fully disabled: no improvement cards injected at all.
|
|
360
|
+
const autoImprove = doc.auto_improve !== false;
|
|
371
361
|
|
|
362
|
+
const steps = {};
|
|
372
363
|
let improvements = 0;
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
364
|
+
|
|
365
|
+
if (autoImprove) {
|
|
366
|
+
// Phase 0 (§10.2): auto-inject improvement cards from PROVEN this-conductor
|
|
367
|
+
// knowledge BEFORE the workflow steps. Entries with current/proposed apply
|
|
368
|
+
// automatically; structural ones (new_step/remove_step/reorder) are flagged
|
|
369
|
+
// for human approval. A _validate card closes the phase.
|
|
370
|
+
const STRUCTURAL = new Set(["new_step", "remove_step", "reorder"]);
|
|
371
|
+
const knowledge = (Array.isArray(doc.knowledge) ? doc.knowledge : []).filter(
|
|
372
|
+
(k) => k && typeof k === "object" && k.title,
|
|
373
|
+
);
|
|
374
|
+
const slug = (t) => String(t).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 40);
|
|
375
|
+
const seen = new Set();
|
|
376
|
+
|
|
377
|
+
// _improve::read-knowledge leads the phase: read + categorize the knowledge.
|
|
378
|
+
if (knowledge.length > 0) {
|
|
379
|
+
const cat = (s) => knowledge.filter((k) => (k.status || "emerging") === s).length;
|
|
380
|
+
const cross = knowledge.filter((k) => (k.scope || "this-conductor") !== "this-conductor").length;
|
|
381
|
+
steps["_improve::read-knowledge"] = {
|
|
382
|
+
status: "pending",
|
|
383
|
+
gate: "pending",
|
|
384
|
+
attempt: 1,
|
|
385
|
+
improve: {
|
|
386
|
+
title: "Read knowledge",
|
|
387
|
+
kind: "read-knowledge",
|
|
388
|
+
note:
|
|
389
|
+
`${cat("proven")} proven · ${cat("emerging")} emerging · ${cat("applied")} applied · ` +
|
|
390
|
+
`${cross} cross-cutting`,
|
|
391
|
+
},
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
for (const k of knowledge) {
|
|
396
|
+
if ((k.status || "emerging") !== "proven") continue;
|
|
397
|
+
if ((k.scope || "this-conductor") !== "this-conductor") continue;
|
|
398
|
+
const structural = STRUCTURAL.has(k.type);
|
|
399
|
+
const textChange = k.current && k.proposed;
|
|
400
|
+
if (!structural && !textChange) continue; // proven but nothing actionable
|
|
401
|
+
let id = `_improve::${slug(k.title)}`;
|
|
402
|
+
while (seen.has(id)) id += "-x";
|
|
403
|
+
seen.add(id);
|
|
404
|
+
steps[id] = {
|
|
405
|
+
status: "pending",
|
|
406
|
+
gate: "pending",
|
|
407
|
+
attempt: 1,
|
|
408
|
+
improve: {
|
|
409
|
+
step: k.step,
|
|
410
|
+
title: k.title,
|
|
411
|
+
current: k.current,
|
|
412
|
+
proposed: k.proposed,
|
|
413
|
+
note: k.note,
|
|
414
|
+
observed: k.observed || 1,
|
|
415
|
+
scope: k.scope || "this-conductor",
|
|
416
|
+
structural,
|
|
417
|
+
kind: k.type || "instruction",
|
|
418
|
+
},
|
|
419
|
+
};
|
|
420
|
+
improvements += 1;
|
|
421
|
+
}
|
|
422
|
+
if (improvements > 0) {
|
|
423
|
+
steps["_improve::validate"] = {
|
|
424
|
+
status: "pending",
|
|
425
|
+
gate: "pending",
|
|
426
|
+
attempt: 1,
|
|
427
|
+
improve: { title: "Validate conductor", kind: "validate" },
|
|
428
|
+
};
|
|
429
|
+
}
|
|
407
430
|
}
|
|
408
431
|
|
|
409
432
|
for (const st of doc.steps || []) {
|
|
@@ -414,8 +437,10 @@ export async function runStatusInit(args) {
|
|
|
414
437
|
: { status: "pending", gate: "pending", attempt: 1 };
|
|
415
438
|
}
|
|
416
439
|
const status = {
|
|
417
|
-
workflow:
|
|
440
|
+
workflow: wfName,
|
|
418
441
|
run_id: runId,
|
|
442
|
+
run_name: runName,
|
|
443
|
+
auto_improve: autoImprove,
|
|
419
444
|
status: "running",
|
|
420
445
|
goal: (doc.description || "").trim().replace(/\s+/g, " "),
|
|
421
446
|
current_step: null,
|