@iowarp/clio-coder 0.3.6 → 0.3.7
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/CHANGELOG.md +28 -0
- package/README.md +16 -5
- package/dist/{acp-2BEHC4DL.js → acp-SK4MD6MM.js} +10 -10
- package/dist/{agents-LNNFTM53.js → agents-2FN2K6ME.js} +30 -25
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-KXXFI2VS.js → auth-QIYZWM5I.js} +13 -13
- package/dist/{chunk-KHSFENX2.js → chunk-3HAPLH5M.js} +10 -10
- package/dist/{chunk-24I7BN55.js → chunk-465YSENW.js} +2 -2
- package/dist/{chunk-4OC57DA6.js → chunk-4DGYLA73.js} +53 -2
- package/dist/{chunk-CYQKWTG3.js → chunk-4DWFMQDR.js} +4 -4
- package/dist/{chunk-E2ER4LJF.js → chunk-5C3AQNDW.js} +25 -1
- package/dist/{chunk-22NAGB7X.js → chunk-5C77SEEY.js} +5 -94
- package/dist/{chunk-43AOLP7E.js → chunk-5FR74PWO.js} +2 -1
- package/dist/{chunk-K7T3E2SR.js → chunk-5UJ6ECTS.js} +10 -9
- package/dist/{chunk-6US73PDB.js → chunk-6M7VS3J3.js} +5 -5
- package/dist/{chunk-CJUB2JJ2.js → chunk-6TUKSZVF.js} +5 -5
- package/dist/{chunk-5JGRAMKL.js → chunk-AB4XIIVB.js} +8 -6
- package/dist/{chunk-R46L2BIR.js → chunk-BMWK7ZIZ.js} +14 -20
- package/dist/{chunk-4BPJXDWC.js → chunk-C4JBQ5SR.js} +30 -14
- package/dist/{chunk-XXQNGV4M.js → chunk-CEYBNUGC.js} +243 -63
- package/dist/{chunk-VEZEGCGW.js → chunk-D4MDIG46.js} +20 -18
- package/dist/chunk-DJNLUABN.js +843 -0
- package/dist/{chunk-RY3LY4J5.js → chunk-DMD2AGVS.js} +5 -4
- package/dist/{chunk-KOHPCX4K.js → chunk-DOOEX22V.js} +2 -2
- package/dist/chunk-DQA7QLMD.js +123 -0
- package/dist/chunk-DR52UMZW.js +21 -0
- package/dist/{chunk-XF5N4U5A.js → chunk-EBEFWSGL.js} +6 -5
- package/dist/{chunk-EYPA3EGJ.js → chunk-EELBMBT6.js} +120 -13
- package/dist/{chunk-CKXWIANG.js → chunk-EOOQZZDE.js} +16 -14
- package/dist/{chunk-WR67VIZY.js → chunk-FOT2FX5J.js} +63 -5
- package/dist/{chunk-FYYLNIL5.js → chunk-GH5622CP.js} +2 -2
- package/dist/chunk-GWS3VEIW.js +195 -0
- package/dist/{chunk-LYF7OHWH.js → chunk-J7PIKKWC.js} +8 -463
- package/dist/{chunk-NILBFAPG.js → chunk-JNXPYBB4.js} +2 -2
- package/dist/{chunk-4VP4KH3K.js → chunk-JRIO5UD2.js} +4 -4
- package/dist/{chunk-6XXKFVSN.js → chunk-JTSEDYVQ.js} +7 -7
- package/dist/{chunk-QKMUKYO7.js → chunk-KCMKRQX4.js} +236 -84
- package/dist/chunk-KZ2H5X4G.js +1026 -0
- package/dist/{chunk-QNQHSOLF.js → chunk-LADCF22A.js} +12 -12
- package/dist/chunk-M4AKACEO.js +382 -0
- package/dist/{chunk-XYDYPRZI.js → chunk-MXI6J5JF.js} +7 -7
- package/dist/{chunk-G7MUEIGA.js → chunk-OB5HIGJY.js} +1 -1
- package/dist/{chunk-EKY57CSP.js → chunk-OBMAI2DP.js} +61 -767
- package/dist/chunk-PD3MESLB.js +242 -0
- package/dist/{chunk-ZRGEBJ4T.js → chunk-QCTRSGHQ.js} +21 -21
- package/dist/chunk-RVG5JXAL.js +41 -0
- package/dist/{chunk-RD5U66HV.js → chunk-SROCI7ZU.js} +7 -7
- package/dist/{chunk-MFFY33HR.js → chunk-THKY7CD7.js} +466 -205
- package/dist/{chunk-PCZJO5TI.js → chunk-UFQ3F4FW.js} +13 -178
- package/dist/{chunk-AD2SYQYC.js → chunk-UHXRNZ2J.js} +121 -3
- package/dist/chunk-UND3GU2L.js +103 -0
- package/dist/{chunk-QM3F2GKX.js → chunk-UUANF5CR.js} +2247 -2096
- package/dist/chunk-UVDSQ6LW.js +472 -0
- package/dist/{chunk-DJVECN66.js → chunk-VQNODYQ4.js} +14 -14
- package/dist/{chunk-3BPUFZDL.js → chunk-VREKEFLL.js} +3 -3
- package/dist/{chunk-PBTHKCPN.js → chunk-WJHBC77E.js} +6 -6
- package/dist/{chunk-XE2VEJHX.js → chunk-X2KV5FXT.js} +2 -2
- package/dist/{chunk-ZXF4XRKW.js → chunk-XEGB6BCN.js} +157 -7
- package/dist/{chunk-E25LMLRW.js → chunk-YD734TPH.js} +2 -2
- package/dist/{verifiers-NCBTHHN2.js → chunk-YTYFXUI3.js} +65 -322
- package/dist/{chunk-OH3TOQTB.js → chunk-ZGH7FGS5.js} +13 -7
- package/dist/cli/index.js +32 -30
- package/dist/{clio-M2KGYUFZ.js → clio-WBVQEBKO.js} +7 -7
- package/dist/{code-nav-GQNL7XA6.js → code-nav-FGGFIE7L.js} +3 -3
- package/dist/{components-5TTYYX6G.js → components-F7OEATSO.js} +4 -4
- package/dist/{config-XUUYQIWO.js → config-TRBL3RCF.js} +34 -29
- package/dist/{configure-IHJ7YOMV.js → configure-OLCVPHNM.js} +15 -15
- package/dist/{context-74JLXAWD.js → context-MJIJ6GOX.js} +11 -11
- package/dist/{context-ZQ7SIFJV.js → context-WFPKQSM6.js} +19 -3
- package/dist/{context-75MIWW3U.js → context-XEWE3MOJ.js} +31 -26
- package/dist/{context-clear-GYKWNUML.js → context-clear-KNOS2JPB.js} +31 -26
- package/dist/{context-working-set-UX5KEP4J.js → context-working-set-EUXAZI6N.js} +8 -8
- package/dist/{dispatch-runner-GIJBHNFL.js → dispatch-runner-B7MTOVKL.js} +313 -53
- package/dist/{docs-6FZSCG5B.js → docs-FLJTIDSE.js} +4 -4
- package/dist/{doctor-SVJ5BZCW.js → doctor-RN4YKO2X.js} +14 -14
- package/dist/{eval-CG6LLBLD.js → eval-RUBJVSNQ.js} +8 -7
- package/dist/{evidence-ZYFIEN42.js → evidence-JZNBUOQZ.js} +30 -25
- package/dist/{evolve-QGEXEMDW.js → evolve-FJVC4KKI.js} +30 -25
- package/dist/{extensions-ADGNCJJD.js → extensions-IQL36S7K.js} +4 -4
- package/dist/{fleet-S5R4ZOQY.js → fleet-BDKYJFCP.js} +214 -360
- package/dist/fleet-commands-ZFIWZSB3.js +70 -0
- package/dist/fleet-graph-Y6HPXIVF.js +125 -0
- package/dist/fleet-new-RDVJLHHH.js +48 -0
- package/dist/fleet-validate-BIYREGIK.js +79 -0
- package/dist/{init-5DRU55YR.js → init-LQUB5COQ.js} +44 -37
- package/dist/library-NJAHIGG4.js +217 -0
- package/dist/{memory-7YKKR6UC.js → memory-OG6HOYKM.js} +31 -26
- package/dist/{models-ZPOLRU2C.js → models-5ZG5XY7J.js} +21 -20
- package/dist/{monitor-US5F5YGZ.js → monitor-TJ7AMTGB.js} +49 -30
- package/dist/{orchestrator-E2AL4T5N.js → orchestrator-WZYB54DM.js} +3827 -581
- package/dist/{paths-E7KYAQWE.js → paths-XUC7GS6E.js} +4 -4
- package/dist/{reset-KZ652EK6.js → reset-PXQT45IY.js} +7 -7
- package/dist/{run-SRNBKDWD.js → run-FQ74YF62.js} +53 -45
- package/dist/{share-CGZE33UP.js → share-FW7SVCL3.js} +33 -9
- package/dist/{skills-S2X4DLY5.js → skills-7E7IRB3R.js} +24 -8
- package/dist/{skills-eval-W2GGIC4R.js → skills-eval-LI75W6OK.js} +34 -27
- package/dist/{targets-54SWINWB.js → targets-4CIFKCTW.js} +23 -22
- package/dist/{terminal-lease-SAIF2OGY.js → terminal-lease-WUZY7ZV5.js} +4 -4
- package/dist/{uninstall-BVLWXKBT.js → uninstall-7FV7IP4E.js} +4 -4
- package/dist/{upgrade-JKAR27XC.js → upgrade-K2HVIVMQ.js} +20 -19
- package/dist/{usage-MSAWCLX4.js → usage-GTZELZQX.js} +116 -49
- package/dist/verifiers-RLAHT27O.js +336 -0
- package/dist/{verify-X5HDROLA.js → verify-BX3BRKH5.js} +7 -6
- package/dist/{wiki-generate-GUSOQ6ZP.js → wiki-generate-ASIFASCN.js} +45 -37
- package/dist/worker/entry.js +38 -35
- package/docs/README.md +3 -2
- package/docs/acp.md +1 -1
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-versions.md +10 -6
- package/docs/built-in-agents.md +26 -2
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +82 -2
- package/docs/configuration-and-targets.md +79 -2
- package/docs/context-engine.md +1 -1
- package/docs/development-pipeline.md +1 -1
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +3 -3
- package/docs/documentation-guide.md +3 -3
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +1 -1
- package/docs/evidence-and-memory.md +5 -5
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +4 -1
- package/docs/extensions-and-sharing.md +6 -2
- package/docs/fleet-demo-runbook.md +2 -2
- package/docs/fleet-dispatch.md +197 -10
- package/docs/git-commit-provenance.md +2 -2
- package/docs/glossary.md +1 -1
- package/docs/installation-and-lifecycle.md +2 -2
- package/docs/middleware-and-components.md +2 -1
- package/docs/model-catalog.md +1 -1
- package/docs/observability.md +55 -8
- package/docs/proactive-memory.md +1 -1
- package/docs/prompt-envelope-and-tools.md +1 -1
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +79 -64
- package/docs/resource-library.md +59 -0
- package/docs/safety-model.md +2 -2
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +37 -1
- package/docs/skills-marketplace.md +16 -3
- package/docs/tool-usage.md +14 -7
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +1 -1
- package/docs/tui-design.md +1 -1
- package/docs/worker-dispatch-mechanics.md +3 -3
- package/package.json +1 -1
- package/src/cli/fleet-commands.ts +37 -0
- package/src/cli/fleet-graph.ts +102 -0
- package/src/cli/fleet-new.ts +36 -0
- package/src/cli/fleet-preflight.ts +121 -0
- package/src/cli/fleet-validate.ts +30 -0
- package/src/cli/fleet.ts +173 -335
- package/src/cli/index.ts +3 -1
- package/src/cli/library.ts +190 -0
- package/src/cli/share.ts +13 -1
- package/src/cli/usage.ts +111 -19
- package/src/core/bus-events.ts +4 -0
- package/src/core/commit-attribution.ts +4 -4
- package/src/core/config.ts +130 -0
- package/src/core/defaults.ts +81 -0
- package/src/domains/agents/builtins/architect.md +1 -0
- package/src/domains/agents/builtins/oracle.md +33 -0
- package/src/domains/agents/catalog.ts +13 -1
- package/src/domains/agents/fleet-contract.ts +278 -16
- package/src/domains/agents/index.ts +14 -0
- package/src/domains/agents/result-contract.ts +235 -1
- package/src/domains/config/classify.ts +4 -0
- package/src/domains/dispatch/active-route-planner.ts +14 -0
- package/src/domains/dispatch/backoff.ts +2 -1
- package/src/domains/dispatch/capability-match.ts +1 -0
- package/src/domains/dispatch/checkout-writer-lease.ts +175 -0
- package/src/domains/dispatch/contract.ts +34 -0
- package/src/domains/dispatch/delegation-plan.ts +167 -0
- package/src/domains/dispatch/execution-plan.ts +76 -5
- package/src/domains/dispatch/execution-role.ts +3 -1
- package/src/domains/dispatch/execution-scheduler.ts +183 -67
- package/src/domains/dispatch/extension.ts +258 -9
- package/src/domains/dispatch/fleet-gate.ts +14 -0
- package/src/domains/dispatch/fleet-plan.ts +63 -3
- package/src/domains/dispatch/fleet-run.ts +737 -0
- package/src/domains/dispatch/gate-role-prompts.ts +9 -0
- package/src/domains/dispatch/host-verification.ts +178 -0
- package/src/domains/dispatch/index.ts +38 -0
- package/src/domains/dispatch/intent.ts +159 -0
- package/src/domains/dispatch/receipt-integrity.ts +8 -4
- package/src/domains/dispatch/state.ts +36 -3
- package/src/domains/dispatch/types.ts +51 -6
- package/src/domains/dispatch/validation.ts +66 -6
- package/src/domains/evidence/trust-status.ts +10 -1
- package/src/domains/middleware/index.ts +15 -0
- package/src/domains/middleware/watchdog.ts +281 -0
- package/src/domains/observability/contract.ts +3 -1
- package/src/domains/observability/cost.ts +12 -1
- package/src/domains/observability/extension.ts +2 -2
- package/src/domains/observability/index.ts +10 -0
- package/src/domains/observability/out-of-turn-usage.ts +223 -0
- package/src/domains/resources/index.ts +20 -0
- package/src/domains/resources/library.ts +326 -0
- package/src/domains/resources/skills/marketplace.ts +37 -12
- package/src/domains/session/handoff.ts +629 -0
- package/src/domains/share/archive.ts +67 -2
- package/src/entry/orchestrator.ts +37 -0
- package/src/interactive/bus-notices.ts +26 -0
- package/src/interactive/chat-loop.ts +235 -1
- package/src/interactive/chat-renderer.ts +22 -0
- package/src/interactive/cost-overlay.ts +31 -3
- package/src/interactive/council-dispatch.ts +30 -0
- package/src/interactive/council-grid.ts +213 -0
- package/src/interactive/council.ts +99 -0
- package/src/interactive/dispatch-board.ts +260 -16
- package/src/interactive/fleet-run-preview.ts +307 -0
- package/src/interactive/footer/notifications.ts +219 -0
- package/src/interactive/handoff-round.ts +56 -0
- package/src/interactive/interactive-application.ts +43 -1
- package/src/interactive/interactive-event-projection.ts +9 -1
- package/src/interactive/interactive-slash-runtime.ts +52 -2
- package/src/interactive/interactive-subscriptions.ts +14 -2
- package/src/interactive/oracle.ts +179 -0
- package/src/interactive/overlay-ask-user-lifecycle.ts +6 -0
- package/src/interactive/overlay-general-openers.ts +190 -1
- package/src/interactive/overlay-key-routing.ts +17 -1
- package/src/interactive/overlay-lifecycle.ts +41 -1
- package/src/interactive/overlay-permission-lifecycle.ts +10 -0
- package/src/interactive/overlay-resource-openers.ts +11 -3
- package/src/interactive/overlay-session-lifecycle.ts +234 -2
- package/src/interactive/overlays/fleet-run-approval.ts +208 -0
- package/src/interactive/overlays/handoff-review.ts +185 -0
- package/src/interactive/overlays/library-install-confirm.ts +151 -0
- package/src/interactive/overlays/list-overlay.ts +168 -2
- package/src/interactive/overlays/settings.ts +101 -4
- package/src/interactive/overlays/side-question.ts +139 -0
- package/src/interactive/overlays/skills-hub.ts +401 -15
- package/src/interactive/side-question.ts +171 -0
- package/src/interactive/slash-commands.ts +432 -5
- package/src/interactive/slash-spec.ts +19 -6
- package/src/interactive/theme/tokens.ts +30 -0
- package/src/interactive/turn-middleware.ts +15 -1
- package/src/interactive/watchdog-run.ts +75 -0
- package/src/interactive/worker-share.ts +56 -1
- package/src/interactive/worker-stream.ts +7 -0
- package/src/tools/bootstrap.ts +3 -0
- package/src/tools/compete-worktrees.ts +13 -79
- package/src/tools/dispatch-admission.ts +242 -8
- package/src/tools/dispatch-arguments.ts +57 -1
- package/src/tools/dispatch-plan.ts +136 -6
- package/src/tools/dispatch-runner.ts +319 -13
- package/src/tools/dispatch-types.ts +20 -1
- package/src/tools/dispatch.ts +72 -2
- package/src/tools/monitor.ts +16 -0
- package/src/tools/profiles.ts +18 -4
- package/src/tools/task-worktree.ts +238 -0
- package/src/tools/verify/authoring.ts +61 -1
- package/src/tools/verify/scripts.ts +62 -0
- package/src/tools/worker-evidence.ts +2 -1
- package/src/worker/spec-contract.ts +1 -0
- package/dist/chunk-HC4CLZ2Y.js +0 -68
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The watchdog's run: one read-only verifier dispatch, one transcript notice.
|
|
3
|
+
*
|
|
4
|
+
* The middleware registration decides when to fire and what the turn changed;
|
|
5
|
+
* this decides nothing. It dispatches through the ordinary path so admission,
|
|
6
|
+
* the receipt, and the Fleet Runs island treat a watchdog run exactly as they
|
|
7
|
+
* treat any other, reads the failed checks out of the `verifier-report`
|
|
8
|
+
* contract, and hands the operator one line. A passing report produces nothing
|
|
9
|
+
* at all.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { BusChannels } from "../core/bus-events.js";
|
|
13
|
+
import type { SafeEventBus } from "../core/event-bus.js";
|
|
14
|
+
import { parseVerifierResult } from "../domains/agents/index.js";
|
|
15
|
+
import type { DispatchContract, DispatchRequest } from "../domains/dispatch/contract.js";
|
|
16
|
+
import { type AgentRoleFactsResolver, requestExecutionRole } from "../domains/dispatch/execution-role.js";
|
|
17
|
+
import { WATCHDOG_TASK, type WatchdogTrigger, watchdogBriefing } from "../domains/middleware/index.js";
|
|
18
|
+
import { watchdogBlockersNotice } from "./bus-notices.js";
|
|
19
|
+
|
|
20
|
+
/** The builtin recipe the watchdog reviews with. */
|
|
21
|
+
export const WATCHDOG_AGENT_ID = "verifier";
|
|
22
|
+
|
|
23
|
+
export interface WatchdogRunDeps {
|
|
24
|
+
dispatch: DispatchContract;
|
|
25
|
+
bus?: SafeEventBus;
|
|
26
|
+
getAgentRoleFacts?: AgentRoleFactsResolver;
|
|
27
|
+
/** `watchdog.target` when the operator set one; the session's active target otherwise. */
|
|
28
|
+
target?: string | undefined;
|
|
29
|
+
/** One transcript line for the operator. Absent means the finding has nowhere to go and the run is skipped. */
|
|
30
|
+
emitNotice?: (text: string) => void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Dispatch one watchdog review and report what it found.
|
|
35
|
+
*
|
|
36
|
+
* Resolves when the run has settled, whatever the outcome. A watchdog that
|
|
37
|
+
* failed is not a turn that failed: the review is advisory, so a broken run
|
|
38
|
+
* stays silent rather than raising an alarm about itself in the middle of the
|
|
39
|
+
* operator's work.
|
|
40
|
+
*/
|
|
41
|
+
export async function runWatchdogReview(trigger: WatchdogTrigger, deps: WatchdogRunDeps): Promise<void> {
|
|
42
|
+
if (!deps.emitNotice) return;
|
|
43
|
+
const request: DispatchRequest = {
|
|
44
|
+
agentId: WATCHDOG_AGENT_ID,
|
|
45
|
+
task: WATCHDOG_TASK,
|
|
46
|
+
briefing: watchdogBriefing(trigger),
|
|
47
|
+
executionRole: requestExecutionRole({
|
|
48
|
+
agentId: WATCHDOG_AGENT_ID,
|
|
49
|
+
...(deps.getAgentRoleFacts ? { resolveFacts: deps.getAgentRoleFacts } : {}),
|
|
50
|
+
}),
|
|
51
|
+
requestOrigin: "internal",
|
|
52
|
+
// Narrowed below whatever the session holds. A reviewer that could write
|
|
53
|
+
// would be a second builder nobody admitted.
|
|
54
|
+
autonomy: "read-only",
|
|
55
|
+
...(deps.target ? { target: deps.target } : {}),
|
|
56
|
+
};
|
|
57
|
+
const progressBus = deps.dispatch.ownsProgressBus?.(deps.bus) === true ? undefined : deps.bus;
|
|
58
|
+
try {
|
|
59
|
+
const handle = await deps.dispatch.dispatch(request);
|
|
60
|
+
for await (const event of handle.events) {
|
|
61
|
+
const typed = event as { type?: string };
|
|
62
|
+
if (!typed.type || typed.type === "heartbeat") continue;
|
|
63
|
+
progressBus?.emit(BusChannels.DispatchProgress, { runId: handle.runId, agentId: WATCHDOG_AGENT_ID, event });
|
|
64
|
+
}
|
|
65
|
+
const receipt = await handle.finalPromise;
|
|
66
|
+
const report = parseVerifierResult(receipt.output?.text ?? null);
|
|
67
|
+
if (report === null) return;
|
|
68
|
+
const notice = watchdogBlockersNotice(report.checks);
|
|
69
|
+
if (notice === null) return;
|
|
70
|
+
deps.emitNotice(notice.text);
|
|
71
|
+
} catch {
|
|
72
|
+
// An advisory review that could not run says nothing. The receipt, if one
|
|
73
|
+
// was written at all, is in the dispatch board like every other run.
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* Pure: no I/O, no bus, no session.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
+
import type { CouncilReport } from "../domains/agents/result-contract.js";
|
|
14
15
|
import { WORKER_OUTPUT_MAX_BYTES } from "../domains/dispatch/event-pump.js";
|
|
15
16
|
import { truncateUtf8 } from "../tools/truncate-utf8.js";
|
|
16
17
|
import { type WorkerEntryState, workerAskedByModel } from "./worker-stream.js";
|
|
@@ -56,12 +57,66 @@ export const WORKER_SHARE_ORIGIN = "shared by the operator";
|
|
|
56
57
|
* produced no text is not worth a turn.
|
|
57
58
|
*/
|
|
58
59
|
export function formatWorkerShareNote(facts: WorkerShareFacts): string | null {
|
|
59
|
-
|
|
60
|
+
return shareNote(facts, facts.text);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** The header every shared note carries, plus one bounded body under it. */
|
|
64
|
+
function shareNote(facts: WorkerShareFacts, body: string): string | null {
|
|
65
|
+
const text = body.trim();
|
|
60
66
|
if (text.length === 0) return null;
|
|
61
67
|
const header = `${WORKER_SHARE_NOTE_PREFIX} ${facts.agentId} · run ${facts.runId} · ${outcomeWord(facts.outcome)} · ${WORKER_SHARE_ORIGIN}`;
|
|
62
68
|
return `${header}\n${truncateUtf8(text, WORKER_SHARE_MAX_BYTES, SHARE_TRUNCATION_MARKER)}`;
|
|
63
69
|
}
|
|
64
70
|
|
|
71
|
+
/** One member's answer under its roster label, or its failure when it produced none. */
|
|
72
|
+
function councilMemberLine(member: CouncilReport["members"][number]): string {
|
|
73
|
+
if (member.failed !== undefined) return `[${member.label}] failed: ${member.failed.reason}`;
|
|
74
|
+
const verdict = member.verdict === undefined ? "" : ` (verdict ${member.verdict})`;
|
|
75
|
+
return `[${member.label}]${verdict} ${member.answer.trim()}`;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** The synthesis line: what the council concluded, and how it concluded it. */
|
|
79
|
+
function councilSynthesisLines(synthesis: CouncilReport["synthesis"]): string[] {
|
|
80
|
+
if (synthesis.kind === "none") return ["[synthesis none] the members answered separately; no synthesis was run."];
|
|
81
|
+
const facts = [
|
|
82
|
+
...(synthesis.verdict !== undefined ? [`verdict ${synthesis.verdict}`] : []),
|
|
83
|
+
...(synthesis.tally !== undefined
|
|
84
|
+
? [
|
|
85
|
+
`tally ${Object.entries(synthesis.tally)
|
|
86
|
+
.map(([key, count]) => `${key}=${count}`)
|
|
87
|
+
.join(" ")}`,
|
|
88
|
+
]
|
|
89
|
+
: []),
|
|
90
|
+
...(synthesis.judgeRunId !== undefined ? [`judge run ${synthesis.judgeRunId}`] : []),
|
|
91
|
+
];
|
|
92
|
+
const head = `[synthesis ${synthesis.kind}]${facts.length > 0 ? ` ${facts.join(" · ")}` : ""}`;
|
|
93
|
+
const text = synthesis.text?.trim() ?? "";
|
|
94
|
+
return text.length > 0 ? [head, text] : [head];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* A whole council as one operator note: every member's labelled answer, in the
|
|
99
|
+
* order the report seals them, then the synthesis. Sharing a synthesis run id
|
|
100
|
+
* means sharing what the council decided, and the members' answers are what it
|
|
101
|
+
* decided from, so they travel together in one bounded block rather than as
|
|
102
|
+
* several notes the main agent would have to reassemble.
|
|
103
|
+
*/
|
|
104
|
+
export function formatCouncilShareNote(facts: WorkerShareFacts, report: CouncilReport): string | null {
|
|
105
|
+
const finalRound = report.members.reduce((highest, member) => Math.max(highest, member.round), 1);
|
|
106
|
+
const body = [
|
|
107
|
+
...report.members.filter((member) => member.round === finalRound).map(councilMemberLine),
|
|
108
|
+
...councilSynthesisLines(report.synthesis),
|
|
109
|
+
].join("\n\n");
|
|
110
|
+
return shareNote(facts, body);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** One council member's answer, labelled with the roster label the operator watched it under. */
|
|
114
|
+
export function formatCouncilMemberShareNote(facts: WorkerShareFacts, label: string): string | null {
|
|
115
|
+
const text = facts.text.trim();
|
|
116
|
+
if (text.length === 0) return null;
|
|
117
|
+
return shareNote(facts, `[${label}] ${text}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
65
120
|
/**
|
|
66
121
|
* Whether operator text is a shared worker note. The header is the first line,
|
|
67
122
|
* so the chat loop can tell the honesty rail a worker result entered the turn
|
|
@@ -113,6 +113,12 @@ export interface WorkerEntryState {
|
|
|
113
113
|
/** Every attempt of this assignment, oldest first. */
|
|
114
114
|
attempts: WorkerAttempt[];
|
|
115
115
|
pending: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Council provenance, present only on a run of a council group. `/share`
|
|
118
|
+
* reads it so a member's answer reaches the main agent under the roster label
|
|
119
|
+
* the operator watched it under, rather than as one unattributed voice.
|
|
120
|
+
*/
|
|
121
|
+
council?: { group: string; label: string; color?: string; round: number };
|
|
116
122
|
receipt?: WorkerReceiptSummary;
|
|
117
123
|
/** Agent origin: the tool call whose execution spawned this run. */
|
|
118
124
|
parentToolCallId?: string;
|
|
@@ -323,6 +329,7 @@ export function createWorkerStream(options: WorkerStreamOptions = {}): WorkerStr
|
|
|
323
329
|
progress: progress.snapshot(),
|
|
324
330
|
attempts: [{ runId, targetLabel: workerTargetLabel(runtime) }],
|
|
325
331
|
pending: true,
|
|
332
|
+
...(payload.council !== undefined ? { council: { ...payload.council } } : {}),
|
|
326
333
|
...(payload.parentToolCallId !== undefined ? { parentToolCallId: payload.parentToolCallId } : {}),
|
|
327
334
|
};
|
|
328
335
|
byAssignment.set(assignmentId, entry);
|
package/src/tools/bootstrap.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { WorkerRosters } from "../core/defaults.js";
|
|
1
2
|
import type { SafeEventBus } from "../core/event-bus.js";
|
|
2
3
|
import type { AgentSpec } from "../domains/agents/spec.js";
|
|
3
4
|
import type { DispatchContract } from "../domains/dispatch/contract.js";
|
|
@@ -22,6 +23,7 @@ export interface ToolBootstrapDeps extends CoreToolBootstrapDeps {
|
|
|
22
23
|
getAgentRoleFacts?: AgentRoleFactsResolver;
|
|
23
24
|
getAutonomy?: () => AutonomyLevel;
|
|
24
25
|
getCostCeilingUsd?: () => number;
|
|
26
|
+
getWorkerRosters?: () => WorkerRosters;
|
|
25
27
|
dispatchBackground?: DispatchBackgroundRegistry;
|
|
26
28
|
}
|
|
27
29
|
|
|
@@ -44,6 +46,7 @@ export function registerAllTools(registry: ToolRegistry, deps: ToolBootstrapDeps
|
|
|
44
46
|
...(deps.getAgentRoleFacts ? { getAgentRoleFacts: deps.getAgentRoleFacts } : {}),
|
|
45
47
|
...(deps.getAutonomy ? { getAutonomy: deps.getAutonomy } : {}),
|
|
46
48
|
...(deps.getCostCeilingUsd ? { getCostCeilingUsd: deps.getCostCeilingUsd } : {}),
|
|
49
|
+
...(deps.getWorkerRosters ? { getWorkerRosters: deps.getWorkerRosters } : {}),
|
|
47
50
|
...(deps.dispatchBackground ? { background: deps.dispatchBackground } : {}),
|
|
48
51
|
};
|
|
49
52
|
registry.register({
|
|
@@ -33,8 +33,15 @@ import {
|
|
|
33
33
|
writeFileSync,
|
|
34
34
|
} from "node:fs";
|
|
35
35
|
import { hostname } from "node:os";
|
|
36
|
-
import {
|
|
36
|
+
import { join, relative, resolve } from "node:path";
|
|
37
37
|
import type { RunKind } from "../domains/dispatch/types.js";
|
|
38
|
+
import {
|
|
39
|
+
commitWorktreePath,
|
|
40
|
+
isCanonicalWorktreePathInside,
|
|
41
|
+
mergeWorktreeBranch,
|
|
42
|
+
protectedPathsChangedByWorktreeBranch,
|
|
43
|
+
worktreeBranchDiffStat,
|
|
44
|
+
} from "./task-worktree.js";
|
|
38
45
|
|
|
39
46
|
export interface CandidateWorktree {
|
|
40
47
|
index: number;
|
|
@@ -300,20 +307,7 @@ function isCanonicalDirectoryAt(path: string): boolean {
|
|
|
300
307
|
* be mistaken for a child of `/group-a` as it can with textual startsWith.
|
|
301
308
|
*/
|
|
302
309
|
export function isCanonicalPathInside(parent: string, candidate: string): boolean {
|
|
303
|
-
|
|
304
|
-
let canonicalCandidate: string;
|
|
305
|
-
try {
|
|
306
|
-
canonicalParent = realpathSync(parent);
|
|
307
|
-
} catch {
|
|
308
|
-
canonicalParent = resolve(parent);
|
|
309
|
-
}
|
|
310
|
-
try {
|
|
311
|
-
canonicalCandidate = realpathSync(candidate);
|
|
312
|
-
} catch {
|
|
313
|
-
canonicalCandidate = resolve(candidate);
|
|
314
|
-
}
|
|
315
|
-
const rel = relative(canonicalParent, canonicalCandidate);
|
|
316
|
-
return rel.length > 0 && rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
|
|
310
|
+
return isCanonicalWorktreePathInside(parent, candidate);
|
|
317
311
|
}
|
|
318
312
|
|
|
319
313
|
function manifestFromUnknown(value: unknown): CompeteGroupManifest | null {
|
|
@@ -557,29 +551,12 @@ export function createCandidateWorktree(
|
|
|
557
551
|
* builder changed nothing (an empty candidate is a legitimate ranking fact).
|
|
558
552
|
*/
|
|
559
553
|
export function commitCandidateWork(worktree: CandidateWorktree, message: string): boolean {
|
|
560
|
-
|
|
561
|
-
const staged = git(worktree.path, ["status", "--porcelain"]);
|
|
562
|
-
if (staged.length === 0) return false;
|
|
563
|
-
git(worktree.path, [
|
|
564
|
-
"-c",
|
|
565
|
-
`user.name=${COMPETE_COMMIT_IDENTITY}`,
|
|
566
|
-
"-c",
|
|
567
|
-
`user.email=${COMPETE_COMMIT_IDENTITY}@local`,
|
|
568
|
-
"commit",
|
|
569
|
-
"-m",
|
|
570
|
-
message,
|
|
571
|
-
"--no-verify",
|
|
572
|
-
]);
|
|
573
|
-
return true;
|
|
554
|
+
return commitWorktreePath(worktree.path, COMPETE_COMMIT_IDENTITY, message);
|
|
574
555
|
}
|
|
575
556
|
|
|
576
557
|
/** One-line stat summary of what a candidate branch changed relative to HEAD. */
|
|
577
558
|
export function candidateDiffStat(root: string, branch: string): string {
|
|
578
|
-
|
|
579
|
-
return git(root, ["diff", "--shortstat", `HEAD...${branch}`]) || "no changes";
|
|
580
|
-
} catch {
|
|
581
|
-
return "diff unavailable";
|
|
582
|
-
}
|
|
559
|
+
return worktreeBranchDiffStat(root, branch);
|
|
583
560
|
}
|
|
584
561
|
|
|
585
562
|
/**
|
|
@@ -592,31 +569,7 @@ export function protectedPathsChangedByCompeteBranch(
|
|
|
592
569
|
branch: string,
|
|
593
570
|
protectedPaths: ReadonlyArray<string>,
|
|
594
571
|
): string[] {
|
|
595
|
-
|
|
596
|
-
const protectedInside = protectedPaths
|
|
597
|
-
.map((path) => resolve(path))
|
|
598
|
-
.filter((path) => {
|
|
599
|
-
const rel = relative(canonical, path);
|
|
600
|
-
return rel.length > 0 && rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
|
|
601
|
-
});
|
|
602
|
-
if (protectedInside.length === 0) return [];
|
|
603
|
-
const changed = git(canonical, ["diff", "--name-only", "-z", "--no-renames", `HEAD...${branch}`])
|
|
604
|
-
.split("\0")
|
|
605
|
-
.filter((path) => path.length > 0)
|
|
606
|
-
.map((path) => resolve(canonical, path));
|
|
607
|
-
const blocked = new Set<string>();
|
|
608
|
-
for (const candidate of changed) {
|
|
609
|
-
for (const protectedPath of protectedInside) {
|
|
610
|
-
const rel = relative(protectedPath, candidate);
|
|
611
|
-
if (
|
|
612
|
-
candidate === protectedPath ||
|
|
613
|
-
(rel.length > 0 && rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel))
|
|
614
|
-
) {
|
|
615
|
-
blocked.add(protectedPath);
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
return [...blocked].sort();
|
|
572
|
+
return protectedPathsChangedByWorktreeBranch(root, branch, protectedPaths);
|
|
620
573
|
}
|
|
621
574
|
|
|
622
575
|
function registeredWorktreePaths(root: string): string[] {
|
|
@@ -687,26 +640,7 @@ export function removeCandidateWorktree(
|
|
|
687
640
|
* the merge and reports failure so the operator decides.
|
|
688
641
|
*/
|
|
689
642
|
export function mergeWinnerBranch(root: string, branch: string): { ok: true } | { ok: false; reason: string } {
|
|
690
|
-
|
|
691
|
-
git(root, [
|
|
692
|
-
"-c",
|
|
693
|
-
`user.name=${COMPETE_COMMIT_IDENTITY}`,
|
|
694
|
-
"-c",
|
|
695
|
-
`user.email=${COMPETE_COMMIT_IDENTITY}@local`,
|
|
696
|
-
"merge",
|
|
697
|
-
"--no-edit",
|
|
698
|
-
"--no-verify",
|
|
699
|
-
branch,
|
|
700
|
-
]);
|
|
701
|
-
return { ok: true };
|
|
702
|
-
} catch (err) {
|
|
703
|
-
try {
|
|
704
|
-
git(root, ["merge", "--abort"]);
|
|
705
|
-
} catch {
|
|
706
|
-
// No merge in progress; nothing to abort.
|
|
707
|
-
}
|
|
708
|
-
return { ok: false, reason: err instanceof Error ? (err.message.split("\n")[0] ?? "merge failed") : String(err) };
|
|
709
|
-
}
|
|
643
|
+
return mergeWorktreeBranch(root, branch, COMPETE_COMMIT_IDENTITY);
|
|
710
644
|
}
|
|
711
645
|
|
|
712
646
|
/**
|