cool-workflow 0.2.2 → 0.2.3
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/apps/architecture-review/app.json +1 -1
- package/apps/architecture-review-fast/app.json +1 -1
- package/apps/end-to-end-golden-path/app.json +1 -1
- package/apps/pr-review-fix-ci/app.json +1 -1
- package/apps/release-cut/app.json +1 -1
- package/apps/research-synthesis/app.json +1 -1
- package/dist/cli/dispatch.js +11 -5
- package/dist/cli/entry.js +41 -1
- package/dist/cli/io.js +6 -2
- package/dist/cli/parseargv.js +1 -0
- package/dist/core/capability-data.js +1 -0
- package/dist/core/format/completion.js +68 -0
- package/dist/core/format/help.js +25 -6
- package/dist/core/format/safe-json.js +73 -0
- package/dist/core/format/state-explosion-text.js +1 -1
- package/dist/core/multi-agent/candidate-scoring.js +5 -1
- package/dist/core/multi-agent/collaboration.js +3 -3
- package/dist/core/multi-agent/coordinator.js +5 -5
- package/dist/core/multi-agent/runtime.js +4 -4
- package/dist/core/multi-agent/topology.js +3 -3
- package/dist/core/pipeline/dispatch.js +18 -4
- package/dist/core/pipeline/drive-decide.js +2 -1
- package/dist/core/state/migrations.js +16 -1
- package/dist/core/state/state-explosion/digest.js +13 -13
- package/dist/core/state/state-explosion/graph.js +17 -11
- package/dist/core/state/state-explosion/report.js +6 -6
- package/dist/core/util/numeric-flag.js +40 -0
- package/dist/core/version.js +1 -1
- package/dist/mcp/server.js +99 -11
- package/dist/shell/audit-cli.js +57 -25
- package/dist/shell/coordinator-io.js +73 -13
- package/dist/shell/dispatch.js +1 -1
- package/dist/shell/doctor.js +80 -1
- package/dist/shell/drive.js +243 -49
- package/dist/shell/eval-text.js +2 -2
- package/dist/shell/evidence-reasoning.js +4 -4
- package/dist/shell/execution-backend/agent.js +20 -1
- package/dist/shell/execution-backend/container.js +4 -1
- package/dist/shell/execution-backend/local.js +4 -1
- package/dist/shell/feedback-cli.js +6 -6
- package/dist/shell/fs-atomic.js +218 -29
- package/dist/shell/man-cli.js +6 -0
- package/dist/shell/metrics-cli.js +2 -1
- package/dist/shell/multi-agent-cli.js +367 -323
- package/dist/shell/multi-agent-host.js +9 -9
- package/dist/shell/multi-agent-operator-ux.js +80 -38
- package/dist/shell/node-store.js +10 -4
- package/dist/shell/observability.js +1 -1
- package/dist/shell/operator-ux-text.js +22 -22
- package/dist/shell/operator-ux.js +15 -14
- package/dist/shell/orchestrator.js +49 -38
- package/dist/shell/pipeline-cli.js +87 -40
- package/dist/shell/reclamation-io.js +14 -4
- package/dist/shell/registry-cli.js +19 -17
- package/dist/shell/remote-source.js +13 -8
- package/dist/shell/report-cli.js +45 -0
- package/dist/shell/report.js +2 -1
- package/dist/shell/run-registry-io.js +77 -19
- package/dist/shell/run-store.js +74 -2
- package/dist/shell/scheduling-io.js +12 -13
- package/dist/shell/state-cli.js +2 -7
- package/dist/shell/state-explosion-cli.js +17 -9
- package/dist/shell/topology-io.js +36 -5
- package/dist/shell/trust-audit.js +224 -22
- package/dist/shell/trust-policy-io.js +1 -1
- package/dist/shell/worker-cli.js +35 -31
- package/dist/wiring/capability-table/basics.js +33 -8
- package/dist/wiring/capability-table/exec-backend.js +20 -11
- package/dist/wiring/capability-table/multi-agent.js +172 -165
- package/dist/wiring/capability-table/parity.js +1 -0
- package/dist/wiring/capability-table/pipeline.js +54 -42
- package/dist/wiring/capability-table/registry-core.js +29 -10
- package/dist/wiring/capability-table/reporting.js +137 -96
- package/dist/wiring/capability-table/scheduling-registry.js +195 -161
- package/dist/wiring/capability-table/state.js +36 -28
- package/dist/wiring/capability-table/trust-ledger.js +46 -22
- package/dist/wiring/capability-table/workflow-apps.js +83 -68
- package/docs/agent-delegation-drive.7.md +2 -0
- package/docs/candidate-scoring.7.md +1 -1
- package/docs/canonical-workflow-apps.7.md +7 -7
- package/docs/cli-mcp-parity.7.md +8 -3
- package/docs/contract-migration-tooling.7.md +2 -0
- package/docs/control-plane-scheduling.7.md +2 -0
- package/docs/coordinator-blackboard.7.md +17 -17
- package/docs/dogfood-one-real-repo.7.md +11 -11
- package/docs/durable-state-and-locking.7.md +2 -0
- package/docs/end-to-end-golden-path.7.md +14 -14
- package/docs/evidence-adoption-reasoning-chain.7.md +2 -0
- package/docs/execution-backends.7.md +2 -0
- package/docs/getting-started.md +37 -37
- package/docs/multi-agent-cli-mcp-surface.7.md +19 -17
- package/docs/multi-agent-eval-replay-harness.7.md +15 -13
- package/docs/multi-agent-operator-ux.7.md +21 -19
- package/docs/multi-agent-runtime-core.7.md +22 -22
- package/docs/multi-agent-topologies.7.md +6 -6
- package/docs/multi-agent-trust-policy-audit.7.md +11 -11
- package/docs/node-snapshot-diff-replay.7.md +2 -0
- package/docs/observability-cost-accounting.7.md +2 -0
- package/docs/operator-ux.7.md +34 -34
- package/docs/pipeline-runner.7.md +4 -4
- package/docs/project-index.md +27 -4
- package/docs/real-execution-backends.7.md +2 -0
- package/docs/release-and-migration.7.md +3 -1
- package/docs/release-tooling.7.md +2 -0
- package/docs/routines.md +4 -4
- package/docs/run-registry-control-plane.7.md +21 -19
- package/docs/run-retention-reclamation.7.md +2 -0
- package/docs/scheduled-tasks.md +14 -14
- package/docs/security-trust-hardening.7.md +15 -15
- package/docs/state-explosion-management.7.md +12 -10
- package/docs/team-collaboration.7.md +2 -0
- package/docs/trust-audit-anchor.7.md +2 -0
- package/docs/unix-principles.md +3 -1
- package/docs/verifier-gated-commit.7.md +1 -1
- package/docs/web-desktop-workbench.7.md +2 -0
- package/docs/workflow-app-framework.7.md +13 -13
- package/manifest/plugin.manifest.json +1 -1
- package/package.json +2 -2
- package/scripts/agents/claude-p-agent.js +2 -2
- package/scripts/block-unapproved-tag.sh +23 -2
- package/scripts/canonical-apps.js +4 -4
- package/scripts/children/batch-delegate-child.js +52 -2
- package/scripts/dogfood-release.js +1 -1
- package/scripts/fake-date-for-reproduction.js +44 -0
- package/scripts/golden-path.js +4 -4
- package/scripts/purity-baseline.json +3 -0
- package/scripts/release-flow.js +57 -1
- package/scripts/verdict-keygen.js +83 -0
- package/scripts/verify-bump-reproduction.sh +148 -0
- package/scripts/verify-verdict-signature.js +61 -0
- package/skills/cool-workflow/SKILL.md +9 -9
- package/skills/cool-workflow/references/commands.md +89 -88
- package/ui/workbench/app.css +37 -1
- package/ui/workbench/app.js +124 -6
|
@@ -113,6 +113,7 @@ exports.evalScoreCli = evalScoreCli;
|
|
|
113
113
|
exports.evalGateCli = evalGateCli;
|
|
114
114
|
exports.evalReportCli = evalReportCli;
|
|
115
115
|
const path = __importStar(require("node:path"));
|
|
116
|
+
const numeric_flag_1 = require("../core/util/numeric-flag");
|
|
116
117
|
const run_store_1 = require("./run-store");
|
|
117
118
|
const report_1 = require("./report");
|
|
118
119
|
const mai = __importStar(require("./multi-agent-io"));
|
|
@@ -140,6 +141,18 @@ function invocationCwd(args) {
|
|
|
140
141
|
function loadRun(args, runId) {
|
|
141
142
|
return (0, run_store_1.loadRunFromCwd)(runId, invocationCwd(args));
|
|
142
143
|
}
|
|
144
|
+
/** Hold the run's state.json lock across the WHOLE load -> change ->
|
|
145
|
+
* persist cycle. A bare loadRun + persist pair races: two processes both
|
|
146
|
+
* load the same state and the later persist silently drops the earlier
|
|
147
|
+
* change (reproduced — N concurrent `blackboard topic create` on one run
|
|
148
|
+
* kept only 1). withRunStateLock loads the run UNDER the lock, and the
|
|
149
|
+
* saveCheckpoint inside persist re-enters that same lock (withFileLock is
|
|
150
|
+
* in-process re-entrant), exactly as pipeline-cli.ts's dispatchRun /
|
|
151
|
+
* recordResultRun already do. Every persist()-calling verb in this file
|
|
152
|
+
* runs through here; read-only verbs keep the lock-free loadRun. */
|
|
153
|
+
function mutateRun(args, runId, fn) {
|
|
154
|
+
return (0, run_store_1.withRunStateLock)(runId, invocationCwd(args), fn);
|
|
155
|
+
}
|
|
143
156
|
function persist(run) {
|
|
144
157
|
(0, run_store_1.saveCheckpoint)(run);
|
|
145
158
|
(0, report_1.writeReport)(run);
|
|
@@ -294,27 +307,28 @@ function topologyValidateCli(topologyId) {
|
|
|
294
307
|
function topologyApplyCli(args) {
|
|
295
308
|
const runId = requireArg(args.runId, "run id");
|
|
296
309
|
const topologyId = requireArg(args.topologyId ?? args.id, "topology id");
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
310
|
+
return mutateRun(args, runId, (run) => {
|
|
311
|
+
const record = topio.applyTopology(run, topologyId, {
|
|
312
|
+
// #30: `topology apply <run> <topology> --id <custom>` — the custom
|
|
313
|
+
// topology-run id arrives as `--id` (parseArgv key `id`), NOT `id2`
|
|
314
|
+
// (which no CLI/MCP surface ever emits). On CLI the topology id comes
|
|
315
|
+
// from positional[1] (capability-table), so `args.id` is free for the
|
|
316
|
+
// run-id override; on MCP the handler pre-maps topologyId from
|
|
317
|
+
// `topologyId ?? id`. Byte-exact to the old build's
|
|
318
|
+
// `id: stringOption(options.id)` (orchestrator/topology-operations.ts).
|
|
319
|
+
id: optionalString(args.id),
|
|
320
|
+
task: undefined,
|
|
321
|
+
taskIds: arrayArg(args.task ?? args.taskId),
|
|
322
|
+
mapperCount: numberArg(args.mapperCount ?? args["mapper-count"] ?? args.mappers ?? args.mapper),
|
|
323
|
+
judgeCount: numberArg(args.judgeCount ?? args["judge-count"] ?? args.judges ?? args.judge),
|
|
324
|
+
debateRounds: numberArg(args.debateRounds ?? args["debate-rounds"] ?? args.rounds),
|
|
325
|
+
blackboardId: blackboardIdArg(args),
|
|
326
|
+
multiAgentRunId: multiAgentRunArg(args),
|
|
327
|
+
collectInitialFanin: boolArg(args.collectInitialFanin ?? args["collect-initial-fanin"]),
|
|
328
|
+
});
|
|
329
|
+
persist(run);
|
|
330
|
+
return record;
|
|
315
331
|
});
|
|
316
|
-
persist(run);
|
|
317
|
-
return record;
|
|
318
332
|
}
|
|
319
333
|
function topologySummaryCli(args) {
|
|
320
334
|
const runId = requireArg(args.runId, "run id");
|
|
@@ -338,59 +352,60 @@ function topologyRunShowCli(args, topologyRunId) {
|
|
|
338
352
|
// ---------------------------------------------------------------------------
|
|
339
353
|
function multiAgentRunCli(args) {
|
|
340
354
|
const runId = requireArg(args.runId, "run id");
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
355
|
+
return mutateRun(args, runId, (run) => {
|
|
356
|
+
const topology = optionalString(args.topology);
|
|
357
|
+
// `multi-agent run <run> <id> --status <status>` — port of the old CLI
|
|
358
|
+
// handler's `id && args.options.status` arm (cli/handlers/multi-agent.ts):
|
|
359
|
+
// transition the MultiAgentRun lifecycle (the core cascades completion to
|
|
360
|
+
// owned roles/groups/fanouts/fanins, or fails closed when a fanin is not
|
|
361
|
+
// verifier-ready). `multiAgentRunId` is the positional entity id the CLI
|
|
362
|
+
// binding forwards (or the `--id`/`--multi-agent-run` alias the MCP peer
|
|
363
|
+
// sends).
|
|
364
|
+
const transitionId = optionalString(args.multiAgentRunId ?? args.id ?? args.multiAgentRun);
|
|
365
|
+
const status = optionalString(args.status);
|
|
366
|
+
const app = optionalString(args.app ?? args.appId);
|
|
367
|
+
const workflow = optionalString(args.workflow ?? args.workflowId);
|
|
368
|
+
const isHostRun = !runId || topology !== undefined || app !== undefined || workflow !== undefined;
|
|
369
|
+
if (!isHostRun && transitionId && status && args.title === undefined && args.objective === undefined) {
|
|
370
|
+
const record = mai.transitionMultiAgentRun(run, transitionId, status, {
|
|
371
|
+
reason: optionalString(args.reason),
|
|
372
|
+
actor: optionalString(args.actor),
|
|
373
|
+
});
|
|
374
|
+
persist(run);
|
|
375
|
+
return record;
|
|
376
|
+
}
|
|
377
|
+
if (!isHostRun && transitionId && !status && args.title === undefined && args.objective === undefined && args.id === undefined) {
|
|
378
|
+
// `multi-agent run <run> <id>` (positional id, no status/create flags) —
|
|
379
|
+
// SHOW the MultiAgentRun record (old handler's showMultiAgentRun arm).
|
|
380
|
+
const record = (0, runtime_1.getMultiAgentRun)(run, transitionId);
|
|
381
|
+
if (!record)
|
|
382
|
+
throw new Error(`Unknown MultiAgentRun id: ${transitionId}`);
|
|
383
|
+
return record;
|
|
384
|
+
}
|
|
385
|
+
let result;
|
|
386
|
+
if (topology === undefined && (args.id !== undefined || args.title !== undefined)) {
|
|
387
|
+
// #28: forward `--blackboard`/`--topic` (plus the old build's
|
|
388
|
+
// objective/parent/phase reads) into the kernel input so a plain
|
|
389
|
+
// `multi-agent run <run> --id ma --blackboard bb --topic t` carries the
|
|
390
|
+
// blackboard linkage. Byte-exact to the old build's createMultiAgentRun
|
|
391
|
+
// option map (orchestrator/multi-agent-operations.ts).
|
|
392
|
+
result = mai.createMultiAgentRun(run, {
|
|
393
|
+
id: optionalString(args.id),
|
|
394
|
+
title: optionalString(args.title),
|
|
395
|
+
objective: optionalString(args.objective ?? args.reason),
|
|
396
|
+
parentMultiAgentRunId: optionalString(args.parent ?? args.parentMultiAgentRunId),
|
|
397
|
+
phase: optionalString(args.phase),
|
|
398
|
+
phaseId: optionalString(args.phaseId),
|
|
399
|
+
blackboardId: blackboardIdArg(args),
|
|
400
|
+
topicIds: topicIdsArg(args),
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
result = host.hostRun(run, args);
|
|
405
|
+
}
|
|
360
406
|
persist(run);
|
|
361
|
-
return
|
|
362
|
-
}
|
|
363
|
-
if (!isHostRun && transitionId && !status && args.title === undefined && args.objective === undefined && args.id === undefined) {
|
|
364
|
-
// `multi-agent run <run> <id>` (positional id, no status/create flags) —
|
|
365
|
-
// SHOW the MultiAgentRun record (old handler's showMultiAgentRun arm).
|
|
366
|
-
const record = (0, runtime_1.getMultiAgentRun)(run, transitionId);
|
|
367
|
-
if (!record)
|
|
368
|
-
throw new Error(`Unknown MultiAgentRun id: ${transitionId}`);
|
|
369
|
-
return record;
|
|
370
|
-
}
|
|
371
|
-
let result;
|
|
372
|
-
if (topology === undefined && (args.id !== undefined || args.title !== undefined)) {
|
|
373
|
-
// #28: forward `--blackboard`/`--topic` (plus the old build's
|
|
374
|
-
// objective/parent/phase reads) into the kernel input so a plain
|
|
375
|
-
// `multi-agent run <run> --id ma --blackboard bb --topic t` carries the
|
|
376
|
-
// blackboard linkage. Byte-exact to the old build's createMultiAgentRun
|
|
377
|
-
// option map (orchestrator/multi-agent-operations.ts).
|
|
378
|
-
result = mai.createMultiAgentRun(run, {
|
|
379
|
-
id: optionalString(args.id),
|
|
380
|
-
title: optionalString(args.title),
|
|
381
|
-
objective: optionalString(args.objective ?? args.reason),
|
|
382
|
-
parentMultiAgentRunId: optionalString(args.parent ?? args.parentMultiAgentRunId),
|
|
383
|
-
phase: optionalString(args.phase),
|
|
384
|
-
phaseId: optionalString(args.phaseId),
|
|
385
|
-
blackboardId: blackboardIdArg(args),
|
|
386
|
-
topicIds: topicIdsArg(args),
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
else {
|
|
390
|
-
result = host.hostRun(run, args);
|
|
391
|
-
}
|
|
392
|
-
persist(run);
|
|
393
|
-
return result;
|
|
407
|
+
return result;
|
|
408
|
+
});
|
|
394
409
|
}
|
|
395
410
|
function multiAgentStatusCli(args) {
|
|
396
411
|
const runId = requireArg(args.runId, "run id");
|
|
@@ -447,14 +462,15 @@ function multiAgentEvidenceCli(args) {
|
|
|
447
462
|
* the old runner.multiAgentReasoning / multiAgentReasoningRefresh. */
|
|
448
463
|
function multiAgentReasoningCli(args) {
|
|
449
464
|
const runId = requireArg(args.runId, "run id");
|
|
450
|
-
const run = loadRun(args, runId);
|
|
451
465
|
const evidenceId = optionalString(args.evidence ?? args.evidenceId ?? args.id);
|
|
452
466
|
if (args.refresh && !evidenceId) {
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
467
|
+
return mutateRun(args, runId, (run) => {
|
|
468
|
+
const index = reasoning.refreshEvidenceReasoning(run);
|
|
469
|
+
persist(run);
|
|
470
|
+
return index;
|
|
471
|
+
});
|
|
456
472
|
}
|
|
457
|
-
return reasoning.showEvidenceReasoning(
|
|
473
|
+
return reasoning.showEvidenceReasoning(loadRun(args, runId), { evidenceId });
|
|
458
474
|
}
|
|
459
475
|
function multiAgentReasoningText(args) {
|
|
460
476
|
const runId = requireArg(args.runId, "run id");
|
|
@@ -464,10 +480,11 @@ function multiAgentReasoningText(args) {
|
|
|
464
480
|
}
|
|
465
481
|
function multiAgentReasoningRefreshCli(args) {
|
|
466
482
|
const runId = requireArg(args.runId, "run id");
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
483
|
+
return mutateRun(args, runId, (run) => {
|
|
484
|
+
const index = reasoning.refreshEvidenceReasoning(run);
|
|
485
|
+
persist(run);
|
|
486
|
+
return index;
|
|
487
|
+
});
|
|
471
488
|
}
|
|
472
489
|
function multiAgentEvidenceText(args) {
|
|
473
490
|
const runId = requireArg(args.runId, "run id");
|
|
@@ -481,182 +498,197 @@ function multiAgentEvidenceText(args) {
|
|
|
481
498
|
}
|
|
482
499
|
function multiAgentStepCli(args) {
|
|
483
500
|
const runId = requireArg(args.runId, "run id");
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
501
|
+
return mutateRun(args, runId, (run) => {
|
|
502
|
+
const result = host.hostStep(run, args);
|
|
503
|
+
persist(run);
|
|
504
|
+
return result;
|
|
505
|
+
});
|
|
488
506
|
}
|
|
489
507
|
function multiAgentBlackboardCli(args, action) {
|
|
490
508
|
const runId = requireArg(args.runId, "run id");
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
509
|
+
return mutateRun(args, runId, (run) => {
|
|
510
|
+
const result = host.hostBlackboard(run, action, args);
|
|
511
|
+
persist(run);
|
|
512
|
+
return result;
|
|
513
|
+
});
|
|
495
514
|
}
|
|
496
515
|
function multiAgentScoreCli(args) {
|
|
497
516
|
const runId = requireArg(args.runId, "run id");
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
517
|
+
return mutateRun(args, runId, (run) => {
|
|
518
|
+
const result = host.hostScore(run, args);
|
|
519
|
+
persist(run);
|
|
520
|
+
return result;
|
|
521
|
+
});
|
|
502
522
|
}
|
|
503
523
|
function multiAgentSelectCli(args) {
|
|
504
524
|
const runId = requireArg(args.runId, "run id");
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
525
|
+
return mutateRun(args, runId, (run) => {
|
|
526
|
+
const result = host.hostSelect(run, args);
|
|
527
|
+
persist(run);
|
|
528
|
+
return result;
|
|
529
|
+
});
|
|
509
530
|
}
|
|
510
531
|
function multiAgentRoleCli(args) {
|
|
511
532
|
const runId = requireArg(args.runId, "run id");
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
533
|
+
return mutateRun(args, runId, (run) => {
|
|
534
|
+
const roleId = optionalString(args.roleId);
|
|
535
|
+
const multiAgentRunId = multiAgentRunArg(args);
|
|
536
|
+
if (roleId && !args.id && !multiAgentRunId) {
|
|
537
|
+
const role = (0, runtime_1.getAgentRole)(run, roleId);
|
|
538
|
+
if (!role)
|
|
539
|
+
throw new Error(`Unknown AgentRole id: ${roleId}`);
|
|
540
|
+
return role;
|
|
541
|
+
}
|
|
542
|
+
// #29: parseArgv keeps `--required-evidence` etc. as their literal kebab
|
|
543
|
+
// keys, so the old camelCase-only reads folded to []. Read BOTH the kebab
|
|
544
|
+
// CLI key and the camelCase MCP alias, byte-exact to the old build's
|
|
545
|
+
// createAgentRole option map (orchestrator/multi-agent-operations.ts).
|
|
546
|
+
const role = mai.createAgentRole(run, {
|
|
547
|
+
id: optionalString(args.id) ?? roleId,
|
|
548
|
+
multiAgentRunId: requireArg(multiAgentRunId, "multi-agent run id"),
|
|
549
|
+
title: optionalString(args.title),
|
|
550
|
+
responsibilities: arrayArg(args.responsibility ?? args.responsibilities),
|
|
551
|
+
requiredEvidence: arrayArg(args.requiredEvidence ?? args["required-evidence"]),
|
|
552
|
+
sandboxProfileHints: arrayArg(args.sandbox ?? args.sandboxProfile ?? args.sandboxProfileHint ?? args["sandbox-profile"]),
|
|
553
|
+
expectedArtifacts: arrayArg(args.expectedArtifact ?? args.expectedArtifacts ?? args["expected-artifact"]),
|
|
554
|
+
faninObligations: arrayArg(args.faninObligation ?? args.faninObligations ?? args["fanin-obligation"]),
|
|
555
|
+
parentRoleId: optionalString(args.parent ?? args.parentRoleId),
|
|
556
|
+
blackboardId: blackboardIdArg(args),
|
|
557
|
+
topicIds: topicIdsArg(args),
|
|
558
|
+
});
|
|
559
|
+
persist(run);
|
|
519
560
|
return role;
|
|
520
|
-
}
|
|
521
|
-
// #29: parseArgv keeps `--required-evidence` etc. as their literal kebab
|
|
522
|
-
// keys, so the old camelCase-only reads folded to []. Read BOTH the kebab
|
|
523
|
-
// CLI key and the camelCase MCP alias, byte-exact to the old build's
|
|
524
|
-
// createAgentRole option map (orchestrator/multi-agent-operations.ts).
|
|
525
|
-
const role = mai.createAgentRole(run, {
|
|
526
|
-
id: optionalString(args.id) ?? roleId,
|
|
527
|
-
multiAgentRunId: requireArg(multiAgentRunId, "multi-agent run id"),
|
|
528
|
-
title: optionalString(args.title),
|
|
529
|
-
responsibilities: arrayArg(args.responsibility ?? args.responsibilities),
|
|
530
|
-
requiredEvidence: arrayArg(args.requiredEvidence ?? args["required-evidence"]),
|
|
531
|
-
sandboxProfileHints: arrayArg(args.sandbox ?? args.sandboxProfile ?? args.sandboxProfileHint ?? args["sandbox-profile"]),
|
|
532
|
-
expectedArtifacts: arrayArg(args.expectedArtifact ?? args.expectedArtifacts ?? args["expected-artifact"]),
|
|
533
|
-
faninObligations: arrayArg(args.faninObligation ?? args.faninObligations ?? args["fanin-obligation"]),
|
|
534
|
-
parentRoleId: optionalString(args.parent ?? args.parentRoleId),
|
|
535
|
-
blackboardId: blackboardIdArg(args),
|
|
536
|
-
topicIds: topicIdsArg(args),
|
|
537
561
|
});
|
|
538
|
-
persist(run);
|
|
539
|
-
return role;
|
|
540
562
|
}
|
|
541
563
|
function multiAgentGroupCli(args) {
|
|
542
564
|
const runId = requireArg(args.runId, "run id");
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
565
|
+
return mutateRun(args, runId, (run) => {
|
|
566
|
+
const groupId = optionalString(args.groupId);
|
|
567
|
+
const multiAgentRunId = multiAgentRunArg(args);
|
|
568
|
+
if (groupId && !args.id && !multiAgentRunId) {
|
|
569
|
+
const group = (0, runtime_1.getAgentGroup)(run, groupId);
|
|
570
|
+
if (!group)
|
|
571
|
+
throw new Error(`Unknown AgentGroup id: ${groupId}`);
|
|
572
|
+
return group;
|
|
573
|
+
}
|
|
574
|
+
// #28: forward `--blackboard`/`--topic` (plus phaseId/parent) into the
|
|
575
|
+
// kernel input. Byte-exact to the old createAgentGroup option map.
|
|
576
|
+
const group = mai.createAgentGroup(run, {
|
|
577
|
+
id: optionalString(args.id) ?? groupId,
|
|
578
|
+
multiAgentRunId: requireArg(multiAgentRunId, "multi-agent run id"),
|
|
579
|
+
title: optionalString(args.title),
|
|
580
|
+
phase: optionalString(args.phase),
|
|
581
|
+
phaseId: optionalString(args.phaseId),
|
|
582
|
+
taskIds: arrayArg(args.task ?? args.taskId ?? args.tasks),
|
|
583
|
+
parentGroupId: optionalString(args.parent ?? args.parentGroupId),
|
|
584
|
+
blackboardId: blackboardIdArg(args),
|
|
585
|
+
topicIds: topicIdsArg(args),
|
|
586
|
+
});
|
|
587
|
+
persist(run);
|
|
550
588
|
return group;
|
|
551
|
-
}
|
|
552
|
-
// #28: forward `--blackboard`/`--topic` (plus phaseId/parent) into the
|
|
553
|
-
// kernel input. Byte-exact to the old createAgentGroup option map.
|
|
554
|
-
const group = mai.createAgentGroup(run, {
|
|
555
|
-
id: optionalString(args.id) ?? groupId,
|
|
556
|
-
multiAgentRunId: requireArg(multiAgentRunId, "multi-agent run id"),
|
|
557
|
-
title: optionalString(args.title),
|
|
558
|
-
phase: optionalString(args.phase),
|
|
559
|
-
phaseId: optionalString(args.phaseId),
|
|
560
|
-
taskIds: arrayArg(args.task ?? args.taskId ?? args.tasks),
|
|
561
|
-
parentGroupId: optionalString(args.parent ?? args.parentGroupId),
|
|
562
|
-
blackboardId: blackboardIdArg(args),
|
|
563
|
-
topicIds: topicIdsArg(args),
|
|
564
589
|
});
|
|
565
|
-
persist(run);
|
|
566
|
-
return group;
|
|
567
590
|
}
|
|
568
591
|
function multiAgentMembershipCli(args) {
|
|
569
592
|
const runId = requireArg(args.runId, "run id");
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
593
|
+
return mutateRun(args, runId, (run) => {
|
|
594
|
+
const membershipId = optionalString(args.membershipId);
|
|
595
|
+
const groupId = groupArg(args);
|
|
596
|
+
const roleId = optionalString(args.roleId ?? args.role);
|
|
597
|
+
if (membershipId && !args.id && !groupId && !roleId) {
|
|
598
|
+
const membership = (0, runtime_1.getAgentMembership)(run, membershipId);
|
|
599
|
+
if (!membership)
|
|
600
|
+
throw new Error(`Unknown AgentMembership id: ${membershipId}`);
|
|
601
|
+
return membership;
|
|
602
|
+
}
|
|
603
|
+
// #28: forward `--blackboard`/`--topic` (plus multiAgentRunId/status) into
|
|
604
|
+
// the kernel input. Byte-exact to the old assignAgentMembership option map.
|
|
605
|
+
const membership = mai.assignAgentMembership(run, {
|
|
606
|
+
id: optionalString(args.id) ?? membershipId,
|
|
607
|
+
multiAgentRunId: multiAgentRunArg(args),
|
|
608
|
+
groupId: requireArg(groupId, "group id"),
|
|
609
|
+
roleId: requireArg(roleId, "role id"),
|
|
610
|
+
taskId: requireArg(args.taskId ?? args.task, "task id"),
|
|
611
|
+
workerId: optionalString(args.workerId ?? args.worker),
|
|
612
|
+
dispatchId: optionalString(args.dispatchId ?? args.dispatch),
|
|
613
|
+
fanoutId: optionalString(args.fanoutId ?? args.fanout ?? args["multi-agent-fanout"]),
|
|
614
|
+
status: optionalString(args.status),
|
|
615
|
+
blackboardId: blackboardIdArg(args),
|
|
616
|
+
topicIds: topicIdsArg(args),
|
|
617
|
+
});
|
|
618
|
+
persist(run);
|
|
578
619
|
return membership;
|
|
579
|
-
}
|
|
580
|
-
// #28: forward `--blackboard`/`--topic` (plus multiAgentRunId/status) into
|
|
581
|
-
// the kernel input. Byte-exact to the old assignAgentMembership option map.
|
|
582
|
-
const membership = mai.assignAgentMembership(run, {
|
|
583
|
-
id: optionalString(args.id) ?? membershipId,
|
|
584
|
-
multiAgentRunId: multiAgentRunArg(args),
|
|
585
|
-
groupId: requireArg(groupId, "group id"),
|
|
586
|
-
roleId: requireArg(roleId, "role id"),
|
|
587
|
-
taskId: requireArg(args.taskId ?? args.task, "task id"),
|
|
588
|
-
workerId: optionalString(args.workerId ?? args.worker),
|
|
589
|
-
dispatchId: optionalString(args.dispatchId ?? args.dispatch),
|
|
590
|
-
fanoutId: optionalString(args.fanoutId ?? args.fanout ?? args["multi-agent-fanout"]),
|
|
591
|
-
status: optionalString(args.status),
|
|
592
|
-
blackboardId: blackboardIdArg(args),
|
|
593
|
-
topicIds: topicIdsArg(args),
|
|
594
620
|
});
|
|
595
|
-
persist(run);
|
|
596
|
-
return membership;
|
|
597
621
|
}
|
|
598
622
|
function multiAgentFanoutCli(args) {
|
|
599
623
|
const runId = requireArg(args.runId, "run id");
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
624
|
+
return mutateRun(args, runId, (run) => {
|
|
625
|
+
const fanoutId = optionalString(args.fanoutId);
|
|
626
|
+
const groupId = groupArg(args);
|
|
627
|
+
if (fanoutId && !args.id && !groupId) {
|
|
628
|
+
const fanout = (0, runtime_1.getAgentFanout)(run, fanoutId);
|
|
629
|
+
if (!fanout)
|
|
630
|
+
throw new Error(`Unknown AgentFanout id: ${fanoutId}`);
|
|
631
|
+
return fanout;
|
|
632
|
+
}
|
|
633
|
+
// #28: forward `--blackboard`/`--topic` so `fanout.blackboardId` inherits
|
|
634
|
+
// the board (kernel: input.blackboardId || group.blackboardId ||
|
|
635
|
+
// multiAgentRun.blackboardId). Also port the old build's fuller fanout
|
|
636
|
+
// reads (multiAgentRunId, workerIds/membershipIds/dispatchIds,
|
|
637
|
+
// sandboxProfileChoices, expectedReturnShape).
|
|
638
|
+
const fanout = mai.createAgentFanout(run, {
|
|
639
|
+
id: optionalString(args.id) ?? fanoutId,
|
|
640
|
+
multiAgentRunId: multiAgentRunArg(args),
|
|
641
|
+
groupId: requireArg(groupId, "group id"),
|
|
642
|
+
reason: requireArg(args.reason, "reason"),
|
|
643
|
+
roleIds: arrayArg(args.role ?? args.roleId ?? args.roles),
|
|
644
|
+
taskIds: arrayArg(args.task ?? args.taskId ?? args.tasks),
|
|
645
|
+
workerIds: arrayArg(args.worker ?? args.workerId ?? args.workers),
|
|
646
|
+
membershipIds: arrayArg(args.membership ?? args.membershipId ?? args.memberships),
|
|
647
|
+
dispatchIds: arrayArg(args.dispatch ?? args.dispatchId ?? args.dispatches),
|
|
648
|
+
// This one flag (aliased --limit/--concurrency/--concurrencyLimit) goes
|
|
649
|
+
// through requiredNumberFlag, not the file's own lenient numberArg — a
|
|
650
|
+
// bare flag here used to silently mean "no limit" (fan out unbounded),
|
|
651
|
+
// the opposite of the "silently means 1" bug the same audit found in
|
|
652
|
+
// metrics-cli.ts/registry-cli.ts's own --limit handling; both now fail
|
|
653
|
+
// loud instead of guessing in either direction.
|
|
654
|
+
concurrencyLimit: (0, numeric_flag_1.requiredNumberFlag)(args.limit ?? args.concurrency ?? args.concurrencyLimit, "--limit"),
|
|
655
|
+
sandboxProfileChoices: parseSandboxChoicesCli(args),
|
|
656
|
+
expectedReturnShape: optionalString(args.expectedReturnShape ?? args["expected-return-shape"]),
|
|
657
|
+
blackboardId: blackboardIdArg(args),
|
|
658
|
+
topicIds: topicIdsArg(args),
|
|
659
|
+
});
|
|
660
|
+
persist(run);
|
|
607
661
|
return fanout;
|
|
608
|
-
}
|
|
609
|
-
// #28: forward `--blackboard`/`--topic` so `fanout.blackboardId` inherits
|
|
610
|
-
// the board (kernel: input.blackboardId || group.blackboardId ||
|
|
611
|
-
// multiAgentRun.blackboardId). Also port the old build's fuller fanout
|
|
612
|
-
// reads (multiAgentRunId, workerIds/membershipIds/dispatchIds,
|
|
613
|
-
// sandboxProfileChoices, expectedReturnShape).
|
|
614
|
-
const fanout = mai.createAgentFanout(run, {
|
|
615
|
-
id: optionalString(args.id) ?? fanoutId,
|
|
616
|
-
multiAgentRunId: multiAgentRunArg(args),
|
|
617
|
-
groupId: requireArg(groupId, "group id"),
|
|
618
|
-
reason: requireArg(args.reason, "reason"),
|
|
619
|
-
roleIds: arrayArg(args.role ?? args.roleId ?? args.roles),
|
|
620
|
-
taskIds: arrayArg(args.task ?? args.taskId ?? args.tasks),
|
|
621
|
-
workerIds: arrayArg(args.worker ?? args.workerId ?? args.workers),
|
|
622
|
-
membershipIds: arrayArg(args.membership ?? args.membershipId ?? args.memberships),
|
|
623
|
-
dispatchIds: arrayArg(args.dispatch ?? args.dispatchId ?? args.dispatches),
|
|
624
|
-
concurrencyLimit: numberArg(args.limit ?? args.concurrency ?? args.concurrencyLimit),
|
|
625
|
-
sandboxProfileChoices: parseSandboxChoicesCli(args),
|
|
626
|
-
expectedReturnShape: optionalString(args.expectedReturnShape ?? args["expected-return-shape"]),
|
|
627
|
-
blackboardId: blackboardIdArg(args),
|
|
628
|
-
topicIds: topicIdsArg(args),
|
|
629
662
|
});
|
|
630
|
-
persist(run);
|
|
631
|
-
return fanout;
|
|
632
663
|
}
|
|
633
664
|
function multiAgentFaninCli(args) {
|
|
634
665
|
const runId = requireArg(args.runId, "run id");
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
666
|
+
return mutateRun(args, runId, (run) => {
|
|
667
|
+
const faninId = optionalString(args.faninId);
|
|
668
|
+
const groupId = groupArg(args);
|
|
669
|
+
const fanoutId = optionalString(args.fanoutId ?? args.fanout);
|
|
670
|
+
if (faninId && !args.id && !groupId && !fanoutId) {
|
|
671
|
+
const fanin = (0, runtime_1.getAgentFanin)(run, faninId);
|
|
672
|
+
if (!fanin)
|
|
673
|
+
throw new Error(`Unknown AgentFanin id: ${faninId}`);
|
|
674
|
+
return fanin;
|
|
675
|
+
}
|
|
676
|
+
// #29: `--required-role` folds to the kebab key `required-role`; read the
|
|
677
|
+
// kebab + camelCase aliases. #28: forward `--blackboard`/`--topic` +
|
|
678
|
+
// multiAgentRunId. Byte-exact to the old collectAgentFanin option map.
|
|
679
|
+
const fanin = mai.collectAgentFanin(run, {
|
|
680
|
+
id: optionalString(args.id) ?? faninId,
|
|
681
|
+
multiAgentRunId: multiAgentRunArg(args),
|
|
682
|
+
groupId,
|
|
683
|
+
fanoutId,
|
|
684
|
+
requiredRoleIds: arrayArg(args.requiredRole ?? args.requiredRoleId ?? args["required-role"]),
|
|
685
|
+
strategy: optionalString(args.strategy),
|
|
686
|
+
blackboardId: blackboardIdArg(args),
|
|
687
|
+
topicIds: topicIdsArg(args),
|
|
688
|
+
});
|
|
689
|
+
persist(run);
|
|
643
690
|
return fanin;
|
|
644
|
-
}
|
|
645
|
-
// #29: `--required-role` folds to the kebab key `required-role`; read the
|
|
646
|
-
// kebab + camelCase aliases. #28: forward `--blackboard`/`--topic` +
|
|
647
|
-
// multiAgentRunId. Byte-exact to the old collectAgentFanin option map.
|
|
648
|
-
const fanin = mai.collectAgentFanin(run, {
|
|
649
|
-
id: optionalString(args.id) ?? faninId,
|
|
650
|
-
multiAgentRunId: multiAgentRunArg(args),
|
|
651
|
-
groupId,
|
|
652
|
-
fanoutId,
|
|
653
|
-
requiredRoleIds: arrayArg(args.requiredRole ?? args.requiredRoleId ?? args["required-role"]),
|
|
654
|
-
strategy: optionalString(args.strategy),
|
|
655
|
-
blackboardId: blackboardIdArg(args),
|
|
656
|
-
topicIds: topicIdsArg(args),
|
|
657
691
|
});
|
|
658
|
-
persist(run);
|
|
659
|
-
return fanin;
|
|
660
692
|
}
|
|
661
693
|
function multiAgentShowCli(args, id) {
|
|
662
694
|
const runId = requireArg(args.runId, "run id");
|
|
@@ -736,24 +768,27 @@ function blackboardGraphCli(args) {
|
|
|
736
768
|
}
|
|
737
769
|
function blackboardResolveCli(args) {
|
|
738
770
|
const runId = requireArg(args.runId, "run id");
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
771
|
+
return mutateRun(args, runId, (run) => {
|
|
772
|
+
const board = coord.resolveBlackboard(run, { id: optionalString(args.id), title: optionalString(args.title), multiAgentRunId: optionalString(args.multiAgentRunId), groupId: optionalString(args.groupId), roleId: optionalString(args.roleId), membershipId: optionalString(args.membershipId) });
|
|
773
|
+
persist(run);
|
|
774
|
+
return board;
|
|
775
|
+
});
|
|
743
776
|
}
|
|
744
777
|
function blackboardTopicCreateCli(args) {
|
|
745
778
|
const runId = requireArg(args.runId, "run id");
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
779
|
+
return mutateRun(args, runId, (run) => {
|
|
780
|
+
const topic = coord.createBlackboardTopic(run, { id: optionalString(args.id), title: requireArg(args.title, "topic title"), description: optionalString(args.description), blackboardId: optionalString(args.blackboardId), author: parseBlackboardAuthorCli(args), scope: parseBlackboardScopeCli(args), tags: arrayArg(args.tag) });
|
|
781
|
+
persist(run);
|
|
782
|
+
return topic;
|
|
783
|
+
});
|
|
750
784
|
}
|
|
751
785
|
function blackboardMessagePostCli(args) {
|
|
752
786
|
const runId = requireArg(args.runId, "run id");
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
787
|
+
return mutateRun(args, runId, (run) => {
|
|
788
|
+
const message = coord.postBlackboardMessage(run, { id: optionalString(args.id), topicId: requireArg(args.topic ?? args.topicId, "topic id"), blackboardId: optionalString(args.blackboardId), body: requireArg(args.body, "message body"), replyToId: optionalString(args.replyTo), visibility: optionalString(args.visibility), author: parseBlackboardAuthorCli(args), scope: parseBlackboardScopeCli(args), links: parseBlackboardLinksCli(runId, args), tags: arrayArg(args.tag), evidenceRefs: arrayArg(args.evidence), artifactRefIds: arrayArg(args.artifact) });
|
|
789
|
+
persist(run);
|
|
790
|
+
return message;
|
|
791
|
+
});
|
|
757
792
|
}
|
|
758
793
|
function blackboardMessageListCli(args) {
|
|
759
794
|
const runId = requireArg(args.runId, "run id");
|
|
@@ -762,17 +797,19 @@ function blackboardMessageListCli(args) {
|
|
|
762
797
|
}
|
|
763
798
|
function blackboardContextPutCli(args) {
|
|
764
799
|
const runId = requireArg(args.runId, "run id");
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
800
|
+
return mutateRun(args, runId, (run) => {
|
|
801
|
+
const context = coord.putBlackboardContext(run, { id: optionalString(args.id), topicId: requireArg(args.topic ?? args.topicId, "topic id"), kind: requireArg(args.kind, "context kind"), key: optionalString(args.key), value: requireArg(args.value ?? args.body, "context value"), blackboardId: optionalString(args.blackboardId), supersedesContextIds: arrayArg(args.supersedes), author: parseBlackboardAuthorCli(args), scope: parseBlackboardScopeCli(args), links: parseBlackboardLinksCli(runId, args), tags: arrayArg(args.tag), evidenceRefs: arrayArg(args.evidence), artifactRefIds: arrayArg(args.artifact) });
|
|
802
|
+
persist(run);
|
|
803
|
+
return context;
|
|
804
|
+
});
|
|
769
805
|
}
|
|
770
806
|
function blackboardArtifactAddCli(args) {
|
|
771
807
|
const runId = requireArg(args.runId, "run id");
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
808
|
+
return mutateRun(args, runId, (run) => {
|
|
809
|
+
const artifact = coord.addBlackboardArtifact(run, { id: optionalString(args.id), topicId: optionalString(args.topic ?? args.topicId), kind: requireArg(args.kind, "artifact kind"), path: optionalString(args.path), locator: optionalString(args.locator), blackboardId: optionalString(args.blackboardId), source: optionalString(args.source), author: parseBlackboardAuthorCli(args), scope: parseBlackboardScopeCli(args), links: parseBlackboardLinksCli(runId, args), tags: arrayArg(args.tag), evidenceRefs: arrayArg(args.evidence) });
|
|
810
|
+
persist(run);
|
|
811
|
+
return artifact;
|
|
812
|
+
});
|
|
776
813
|
}
|
|
777
814
|
function blackboardArtifactListCli(args) {
|
|
778
815
|
const runId = requireArg(args.runId, "run id");
|
|
@@ -781,10 +818,11 @@ function blackboardArtifactListCli(args) {
|
|
|
781
818
|
}
|
|
782
819
|
function blackboardSnapshotCli(args) {
|
|
783
820
|
const runId = requireArg(args.runId, "run id");
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
821
|
+
return mutateRun(args, runId, (run) => {
|
|
822
|
+
const snapshot = coord.createBlackboardSnapshot(run, optionalString(args.blackboardId));
|
|
823
|
+
persist(run);
|
|
824
|
+
return snapshot;
|
|
825
|
+
});
|
|
788
826
|
}
|
|
789
827
|
function coordinatorSummaryCli(args) {
|
|
790
828
|
const runId = requireArg(args.runId, "run id");
|
|
@@ -793,10 +831,11 @@ function coordinatorSummaryCli(args) {
|
|
|
793
831
|
}
|
|
794
832
|
function coordinatorDecisionCli(args) {
|
|
795
833
|
const runId = requireArg(args.runId, "run id");
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
834
|
+
return mutateRun(args, runId, (run) => {
|
|
835
|
+
const decision = coord.recordCoordinatorDecision(run, { id: optionalString(args.id), blackboardId: optionalString(args.blackboardId), kind: requireArg(args.kind, "decision kind"), outcome: requireArg(args.outcome, "decision outcome"), reason: requireArg(args.reason, "decision reason"), subjectIds: arrayArg(args.subject), evidenceRefs: arrayArg(args.evidence), artifactRefIds: arrayArg(args.artifact), messageIds: arrayArg(args.message) });
|
|
836
|
+
persist(run);
|
|
837
|
+
return decision;
|
|
838
|
+
});
|
|
800
839
|
}
|
|
801
840
|
// ---------------------------------------------------------------------------
|
|
802
841
|
// Candidate scoring
|
|
@@ -816,33 +855,34 @@ function candidateShowCli(args, candidateId) {
|
|
|
816
855
|
}
|
|
817
856
|
function candidateRegisterCli(args) {
|
|
818
857
|
const runId = requireArg(args.runId, "run id");
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
858
|
+
return mutateRun(args, runId, (run) => {
|
|
859
|
+
// `candidate register --worker <id>` — derive the worker's accepted
|
|
860
|
+
// result/verifier state nodes (and result path) from the worker scope +
|
|
861
|
+
// its backing task, so a candidate registered from a verified worker
|
|
862
|
+
// carries the verifier gate the selection gate requires. Port of the old
|
|
863
|
+
// orchestrator/candidate-operations.ts registerCandidate worker read
|
|
864
|
+
// (v2's candidateRegisterCli only forwarded --result-node/--verifier-node).
|
|
865
|
+
const workerId = optionalString(args.worker ?? args.workerId);
|
|
866
|
+
const worker = workerId ? (0, worker_isolation_1.getWorkerScope)(run, workerId) : undefined;
|
|
867
|
+
if (workerId && !worker)
|
|
868
|
+
throw new Error(`Unknown worker id for run ${run.id}: ${workerId}`);
|
|
869
|
+
const workerOutput = worker?.output;
|
|
870
|
+
const task = worker ? run.tasks.find((entry) => entry.id === worker.taskId) : undefined;
|
|
871
|
+
const resultNodeId = optionalString(args.resultNode) || worker?.resultNodeId || task?.resultNodeId;
|
|
872
|
+
const verifierNodeId = optionalString(args.verifierNode) || workerOutput?.verifierNodeId || task?.verifierNodeId;
|
|
873
|
+
const resultPath = optionalString(args.resultPath) || workerOutput?.resultPath || task?.resultPath;
|
|
874
|
+
const candidate = cs.registerCandidate(run, {
|
|
875
|
+
id: optionalString(args.id),
|
|
876
|
+
kind: optionalString(args.kind),
|
|
877
|
+
workerId,
|
|
878
|
+
taskId: optionalString(args.task ?? args.taskId) || worker?.taskId,
|
|
879
|
+
resultNodeId,
|
|
880
|
+
verifierNodeId,
|
|
881
|
+
resultPath,
|
|
882
|
+
});
|
|
883
|
+
persist(run);
|
|
884
|
+
return candidate;
|
|
843
885
|
});
|
|
844
|
-
persist(run);
|
|
845
|
-
return candidate;
|
|
846
886
|
}
|
|
847
887
|
function parseCriteriaCli(args) {
|
|
848
888
|
const criteria = {};
|
|
@@ -868,32 +908,36 @@ function parseCriteriaCli(args) {
|
|
|
868
908
|
}
|
|
869
909
|
function candidateScoreCli(args, candidateId) {
|
|
870
910
|
const runId = requireArg(args.runId, "run id");
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
911
|
+
return mutateRun(args, runId, (run) => {
|
|
912
|
+
const evidence = arrayArg(args.evidence).map((entry, index) => ({ id: `score:${index + 1}`, source: "cli", locator: entry, summary: entry }));
|
|
913
|
+
const score = cs.scoreCandidate(run, candidateId, { id: optionalString(args.id), scorer: optionalString(args.scorer), criteria: parseCriteriaCli(args), maxTotal: numberArg(args.maxTotal ?? args.max), verdict: optionalString(args.verdict), evidence, notes: optionalString(args.notes) });
|
|
914
|
+
persist(run);
|
|
915
|
+
return score;
|
|
916
|
+
});
|
|
876
917
|
}
|
|
877
918
|
function candidateRankCli(args) {
|
|
878
919
|
const runId = requireArg(args.runId, "run id");
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
920
|
+
return mutateRun(args, runId, (run) => {
|
|
921
|
+
const ranking = cs.rankCandidates(run, { includeRejected: boolArg(args.includeRejected), policy: { minNormalized: numberArg(args.minNormalized), requireEvidence: args.requireEvidence === undefined ? undefined : boolArg(args.requireEvidence), requireVerifierGate: args.requireVerifierGate === undefined ? undefined : boolArg(args.requireVerifierGate), tieBreaker: optionalString(args.tieBreaker) } });
|
|
922
|
+
persist(run);
|
|
923
|
+
return ranking;
|
|
924
|
+
});
|
|
883
925
|
}
|
|
884
926
|
function candidateSelectCli(args, candidateId) {
|
|
885
927
|
const runId = requireArg(args.runId, "run id");
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
928
|
+
return mutateRun(args, runId, (run) => {
|
|
929
|
+
const selection = cs.selectCandidate(run, candidateId, { selectedBy: optionalString(args.selectedBy ?? args.by), reason: optionalString(args.reason), scoreId: optionalString(args.score), allowUnverified: boolArg(args.allowUnverified) }, { policy: { minNormalized: numberArg(args.minNormalized), requireVerifierGate: args.requireVerifierGate === undefined ? undefined : boolArg(args.requireVerifierGate) } });
|
|
930
|
+
persist(run);
|
|
931
|
+
return selection;
|
|
932
|
+
});
|
|
890
933
|
}
|
|
891
934
|
function candidateRejectCli(args, candidateId) {
|
|
892
935
|
const runId = requireArg(args.runId, "run id");
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
936
|
+
return mutateRun(args, runId, (run) => {
|
|
937
|
+
const candidate = cs.rejectCandidate(run, candidateId, requireArg(args.reason, "reject reason"));
|
|
938
|
+
persist(run);
|
|
939
|
+
return candidate;
|
|
940
|
+
});
|
|
897
941
|
}
|
|
898
942
|
function candidateSummaryCli(args) {
|
|
899
943
|
const runId = requireArg(args.runId, "run id");
|
|
@@ -915,24 +959,24 @@ function targetFromArgs(args, positionalKind, positionalId) {
|
|
|
915
959
|
}
|
|
916
960
|
function approveCli(args, positionalKind, positionalId) {
|
|
917
961
|
const runId = requireArg(args.runId, "run id");
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
962
|
+
return mutateRun(args, runId, (run) => {
|
|
963
|
+
const target = targetFromArgs(args, positionalKind, positionalId);
|
|
964
|
+
return collab.recordApproval(run, { target: target, decision: "approve", actor: optionalString(args.actor), actorKind: optionalString(args.actorKind), role: optionalString(args.role), displayName: optionalString(args.displayName), attested: boolArg(args.attested), attestation: optionalString(args.attestation), rationale: optionalString(args.rationale), supersedes: optionalString(args.supersedes) });
|
|
965
|
+
});
|
|
922
966
|
}
|
|
923
967
|
function rejectCollabCli(args, positionalKind, positionalId) {
|
|
924
968
|
const runId = requireArg(args.runId, "run id");
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
969
|
+
return mutateRun(args, runId, (run) => {
|
|
970
|
+
const target = targetFromArgs(args, positionalKind, positionalId);
|
|
971
|
+
return collab.recordApproval(run, { target: target, decision: "reject", actor: optionalString(args.actor), actorKind: optionalString(args.actorKind), role: optionalString(args.role), displayName: optionalString(args.displayName), attested: boolArg(args.attested), attestation: optionalString(args.attestation), rationale: optionalString(args.rationale) });
|
|
972
|
+
});
|
|
929
973
|
}
|
|
930
974
|
function commentAddCli(args, positionalKind, positionalId) {
|
|
931
975
|
const runId = requireArg(args.runId, "run id");
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
976
|
+
return mutateRun(args, runId, (run) => {
|
|
977
|
+
const target = targetFromArgs(args, positionalKind, positionalId);
|
|
978
|
+
return collab.recordComment(run, { target: target, body: requireArg(args.body ?? args.message ?? args.text, "comment body"), actor: optionalString(args.actor), actorKind: optionalString(args.actorKind), role: optionalString(args.role), threadId: optionalString(args.thread), parentId: optionalString(args.parent) });
|
|
979
|
+
});
|
|
936
980
|
}
|
|
937
981
|
function commentListCli(args) {
|
|
938
982
|
const runId = requireArg(args.runId, "run id");
|
|
@@ -943,10 +987,10 @@ function commentListCli(args) {
|
|
|
943
987
|
}
|
|
944
988
|
function handoffCli(args, positionalKind, positionalId) {
|
|
945
989
|
const runId = requireArg(args.runId, "run id");
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
990
|
+
return mutateRun(args, runId, (run) => {
|
|
991
|
+
const target = targetFromArgs(args, positionalKind, positionalId);
|
|
992
|
+
return collab.recordHandoff(run, { target: target, toActor: optionalString(args.to ?? args.toActor), toRole: optionalString(args.toRole), fromActor: optionalString(args.from), reason: requireArg(args.reason, "handoff reason"), actor: optionalString(args.actor), actorKind: optionalString(args.actorKind), role: optionalString(args.role) });
|
|
993
|
+
});
|
|
950
994
|
}
|
|
951
995
|
function reviewStatusCli(args) {
|
|
952
996
|
const runId = requireArg(args.runId, "run id");
|
|
@@ -957,19 +1001,19 @@ function reviewStatusCli(args) {
|
|
|
957
1001
|
}
|
|
958
1002
|
function reviewPolicyCli(args) {
|
|
959
1003
|
const runId = requireArg(args.runId, "run id");
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
1004
|
+
return mutateRun(args, runId, (run) => {
|
|
1005
|
+
// Read BOTH the MCP camelCase keys and the CLI kebab-case flags: the CLI
|
|
1006
|
+
// parser emits `--required-approvals` as `required-approvals`, not
|
|
1007
|
+
// `requiredApprovals`, so without the fallback every flag was silently
|
|
1008
|
+
// dropped and the CLI wrote the default policy (caught by parity-check's
|
|
1009
|
+
// cw --json vs cw_review_policy payload probe).
|
|
1010
|
+
const requiredApprovals = args.requiredApprovals ?? args["required-approvals"];
|
|
1011
|
+
const authorizedRoles = args.authorizedRoles ?? args["authorized-roles"];
|
|
1012
|
+
const allowSelfApproval = args.allowSelfApproval ?? args["allow-self-approval"];
|
|
1013
|
+
const requireAttestedActor = args.requireAttestedActor ?? args["require-attested-actor"];
|
|
1014
|
+
const appliesTo = args.appliesTo ?? args["applies-to"];
|
|
1015
|
+
return collab.setReviewPolicy(run, { requiredApprovals: numberArg(requiredApprovals), authorizedRoles: arrayArg(authorizedRoles).length ? arrayArg(authorizedRoles) : optionalString(authorizedRoles), allowSelfApproval: allowSelfApproval === undefined ? undefined : boolArg(allowSelfApproval), requireAttestedActor: requireAttestedActor === undefined ? undefined : boolArg(requireAttestedActor), appliesTo: arrayArg(appliesTo).length ? arrayArg(appliesTo) : optionalString(appliesTo) });
|
|
1016
|
+
});
|
|
973
1017
|
}
|
|
974
1018
|
// ---------------------------------------------------------------------------
|
|
975
1019
|
// Eval replay
|