opencode-swarm 7.160.1 → 7.161.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/.opencode/skills/critic-gate/SKILL.md +8 -1
- package/.opencode/skills/execute/SKILL.md +4 -3
- package/.opencode/skills/phase-wrap/SKILL.md +2 -0
- package/.opencode/skills/running-tests/SKILL.md +6 -0
- package/.opencode/skills/swarm-implement/SKILL.md +2 -0
- package/.opencode/skills/swarm-pr-review/SKILL.md +1 -0
- package/dist/agents/architect.d.ts +1 -1
- package/dist/background/delegation-lifecycle.d.ts +374 -0
- package/dist/background/pending-delegations.d.ts +6 -0
- package/dist/build/command-resolution.d.ts +13 -0
- package/dist/build/discovery.d.ts +11 -4
- package/dist/cli/{coder-settlement-678ccmnf.js → coder-settlement-nayk1bbf.js} +8 -8
- package/dist/cli/{config-doctor-fr8dfrt2.js → config-doctor-b1w7yvcs.js} +2 -2
- package/dist/cli/{core-4j1hbhey.js → core-whesnhpf.js} +1 -1
- package/dist/cli/{curation-policy-47przjwg.js → curation-policy-ej9xc0cd.js} +5 -5
- package/dist/cli/{curator-85d97240.js → curator-1rzb285s.js} +31 -31
- package/dist/cli/{curator-llm-factory-s9s4s0q3.js → curator-llm-factory-bqfkaq6y.js} +31 -31
- package/dist/cli/{dispatch-7r46tfr9.js → dispatch-q4v8x2pk.js} +1 -1
- package/dist/cli/{evidence-summary-service-9dyt2kzh.js → evidence-summary-service-ma8drpv5.js} +13 -13
- package/dist/cli/{gate-evidence-a6paafg8.js → gate-evidence-7eh82zs0.js} +5 -5
- package/dist/cli/{guardrail-explain-4a2xdtew.js → guardrail-explain-em2mqz9a.js} +32 -32
- package/dist/cli/{guardrail-log-27nkntrx.js → guardrail-log-845tfrwb.js} +6 -6
- package/dist/cli/{guardrail-reset-xn7k3hn8.js → guardrail-reset-091xw53a.js} +31 -31
- package/dist/cli/{hive-promoter-k57j3kp6.js → hive-promoter-kx8t5em3.js} +31 -31
- package/dist/cli/{index-zpzvpybn.js → index-14dgnwmh.js} +2 -2
- package/dist/cli/{index-nj6rmyeh.js → index-3146wmgv.js} +352 -149
- package/dist/cli/{index-wccdm7jv.js → index-3cxfqdpv.js} +4 -4
- package/dist/cli/{index-e1ygmd4q.js → index-52f67bbh.js} +33 -33
- package/dist/cli/{index-gjx53y3c.js → index-54jznpq7.js} +1 -1
- package/dist/cli/{index-7h2armwf.js → index-7619tk9a.js} +2 -2
- package/dist/cli/{index-7v0ex0jt.js → index-7qera0f6.js} +2 -2
- package/dist/cli/{index-v8dsmee1.js → index-93pf824c.js} +3 -3
- package/dist/cli/{index-drqvph47.js → index-ambz0ryy.js} +4 -4
- package/dist/cli/{index-prv20xq6.js → index-c6zyqgpq.js} +1 -1
- package/dist/cli/{index-nnzdayvk.js → index-d1h4sf8f.js} +6 -6
- package/dist/cli/{index-7ezv5j23.js → index-d8st72j7.js} +1 -1
- package/dist/cli/{index-nk498mx6.js → index-dq41vsf9.js} +2 -2
- package/dist/cli/{index-m84z3aa8.js → index-et1jpj6z.js} +3 -3
- package/dist/cli/{index-bqxffayb.js → index-etdtfhhv.js} +1 -1
- package/dist/cli/{index-m1cw9fsh.js → index-f4dmccpd.js} +8 -8
- package/dist/cli/{index-znf683sm.js → index-f5axf6vq.js} +1 -1
- package/dist/cli/{index-dke4wzkn.js → index-fx3em0dr.js} +17 -1
- package/dist/cli/{index-98jmggma.js → index-gkv7s4xy.js} +8 -8
- package/dist/cli/{index-f72612zc.js → index-h6wtxzvm.js} +1 -1
- package/dist/cli/{index-mmr96pwr.js → index-k55td019.js} +1 -1
- package/dist/cli/{index-61c3d769.js → index-mbktm1ah.js} +7 -4
- package/dist/cli/{index-jszabr0r.js → index-mj6ndvee.js} +4 -4
- package/dist/cli/{index-b5adxpy6.js → index-nqbqkx4c.js} +1 -1
- package/dist/cli/{index-8c9qzpy7.js → index-q8hm27yj.js} +7 -1
- package/dist/cli/{index-zdv914xa.js → index-qjge2m9r.js} +81 -74
- package/dist/cli/{index-j3ss86kf.js → index-s33ee2w3.js} +1 -1
- package/dist/cli/{index-z0bxbb9g.js → index-t81fmfjj.js} +4 -4
- package/dist/cli/{index-pkz91fwm.js → index-trmqq4wm.js} +2 -2
- package/dist/cli/{index-dq93ar40.js → index-w9g58t3j.js} +5 -5
- package/dist/cli/{index-ny0g8fdg.js → index-wrtgyvre.js} +5 -5
- package/dist/cli/{index-qc53dfzh.js → index-xy0e0r5f.js} +1 -1
- package/dist/cli/{index-pqjcyj0p.js → index-y0ra2v4w.js} +3 -3
- package/dist/cli/{index-497a3hhj.js → index-y14mwbk8.js} +3 -3
- package/dist/cli/{index-7npz9n4s.js → index-zkgrayya.js} +1 -1
- package/dist/cli/index.js +31 -31
- package/dist/cli/{knowledge-escalator-3q2x34cg.js → knowledge-escalator-9eqpsbw5.js} +12 -12
- package/dist/cli/{knowledge-events-5y34w84b.js → knowledge-events-a8r4ej12.js} +10 -10
- package/dist/cli/{knowledge-link-xezm8hr3.js → knowledge-link-8knefv8x.js} +4 -4
- package/dist/cli/{knowledge-store-fqv89q5k.js → knowledge-store-ydzeppv7.js} +5 -5
- package/dist/cli/{knowledge-validator-fsdx14tk.js → knowledge-validator-mnv58he9.js} +7 -7
- package/dist/cli/{pending-delegations-6ae7wy5q.js → pending-delegations-9mwmrwwm.js} +6 -4
- package/dist/cli/{pr-review-reentry-authorization-986tk381.js → pr-review-reentry-authorization-h1ssfq37.js} +31 -31
- package/dist/cli/{pr-subscriptions-asjevc5p.js → pr-subscriptions-3zwthnan.js} +4 -4
- package/dist/cli/{runner-wsdcy2d6.js → runner-fzgkd6m1.js} +5 -5
- package/dist/cli/{scan-cursor-shn926r6.js → scan-cursor-5rmaqw2t.js} +6 -6
- package/dist/cli/{schema-98tdb9h0.js → schema-72vpr9xy.js} +1 -1
- package/dist/cli/{scope-persistence-cn34xnwr.js → scope-persistence-39mwns79.js} +8 -8
- package/dist/cli/{skill-generator-kck7087c.js → skill-generator-9aay0t53.js} +14 -14
- package/dist/cli/{telemetry-gpr9s3sm.js → telemetry-cmbjv240.js} +1 -1
- package/dist/cli/{worktree-collision-ownership-6b3kshcv.js → worktree-collision-ownership-ybhktnq4.js} +4 -4
- package/dist/cli/{worktree-isolation-he01qhss.js → worktree-isolation-w8ett6bs.js} +31 -31
- package/dist/config/evidence-schema.d.ts +20 -2
- package/dist/config/schema.d.ts +7 -7
- package/dist/hooks/delegate-ack-collector.d.ts +74 -0
- package/dist/hooks/knowledge-injector.d.ts +12 -1
- package/dist/index.js +280 -279
- package/dist/lang/default-backend.d.ts +1 -13
- package/dist/learning/admission.d.ts +2 -2
- package/dist/memory/schema.d.ts +3 -3
- package/dist/observability/catalog.d.ts +2 -2
- package/dist/prm/types.d.ts +9 -0
- package/dist/telemetry.d.ts +9 -1
- package/dist/tools/build-check.d.ts +4 -0
- package/dist/tools/repo-graph/retrieval-router.d.ts +57 -0
- package/dist/tools/repo-graph.d.ts +2 -0
- package/dist/tools/repo-map.d.ts +202 -0
- package/dist/tools/search.d.ts +2 -2
- package/dist/tools/test-runner.d.ts +2 -0
- package/package.json +1 -1
|
@@ -41,13 +41,20 @@ one-line `reason` (or ask the user to run `/swarm approve-plan-critic
|
|
|
41
41
|
<reason>`). This records a manual `plan_critic_gate` approval snapshot
|
|
42
42
|
tagged `method: "manual_override"`, audited to `.swarm/events.jsonl`.
|
|
43
43
|
Architect-only. Use ONLY when a legitimate APPROVED was lost — this is an
|
|
44
|
-
escape hatch, not a substitute for running the critic review.
|
|
44
|
+
escape hatch, not a substitute for running the critic review. It is also the sanctioned recovery for a bookkeeping-grade hashed-field repair under PLAN FREEZE below.
|
|
45
45
|
|
|
46
46
|
CRITIC-GATE TRIGGER: Run ONCE when you first write the complete .swarm/plan.md.
|
|
47
47
|
Do NOT re-run CRITIC-GATE before every project phase.
|
|
48
48
|
If resuming a project with an existing approved plan, CRITIC-GATE is already satisfied.
|
|
49
49
|
Caveat: this assumption breaks if the plan lacks a `plan_critic_gate`-tagged approval snapshot (e.g. a plan approved before this mechanical gate existed, or one where the recording heuristic didn't fire) — in that case the first coder dispatch will fail with `PLAN_CRITIC_GATE_VIOLATION`. If that happens, do not assume CRITIC-GATE is satisfied; re-run it and get a fresh APPROVED verdict.
|
|
50
50
|
|
|
51
|
+
PLAN FREEZE AFTER APPROVAL (issue #1994 P1): once the critic returns APPROVED, the plan is frozen. The coder dispatch gate compares the plan against the approval snapshot via the structure hash (`computePlanStructureHash`), so classify post-approval changes by what that hash actually covers:
|
|
52
|
+
- STATUS-ONLY changes (task status transitions via `update_task_status`) are excluded from the hash and never invalidate the approval — no re-critic needed.
|
|
53
|
+
- MATERIAL (invalidates the approval): adding or removing tasks; changing any task's `id`, `phase`, `description`, `acceptance`, or `depends`; or enumerating `removed_task_ids` on a re-save. Re-run MODE: CRITIC-GATE exactly ONCE on the revised plan and get a fresh APPROVED before the next coder dispatch — the dispatch fails `PLAN_CRITIC_GATE_VIOLATION` against the stale snapshot otherwise.
|
|
54
|
+
- `fr_refs` changes are MATERIAL on process grounds (spec traceability feeds the critic's obligation check) even though the hash deliberately excludes `fr_refs` — the runtime will not catch this for you; re-critic is still required.
|
|
55
|
+
- BOOKKEEPING-GRADE hashed fields (`size`, `evidence_path`, `blocked_reason`, `title`, `current_phase`, `files_touched`) trip the gate mechanically even for pure bookkeeping edits. For a genuine bookkeeping repair — most commonly a `files_touched`-only reconciliation aligned with an active `declare_scope` binding (the sanctioned `SCOPE_CONFLICT` repair path in the execute skill) — use the gate's own recovery: `approve_plan_critic` with a truthful one-line reason (audited to `.swarm/events.jsonl`), not a full re-critic. Any substantive scope growth beyond reconciliation is MATERIAL: re-critic.
|
|
56
|
+
Batching rule: material changes accumulated across multiple `save_plan` calls since the last APPROVED count as ONE batch — re-critic that batch once, and never split material changes across separate calls to dodge the re-critic. The pre-change approval is never valid for the changed plan.
|
|
57
|
+
|
|
51
58
|
6j. SPEC-GATE (Execute BEFORE any save_plan call):
|
|
52
59
|
- An effective spec exists iff `/swarm sdd status` reports a resolved spec (it reflects `readEffectiveSpecSync`, which returns null — NO effective spec — for no sources, multiple competing sources (openspec+specify), multi-feature Spec-Kit without a selected feature, or any unresolvable state). `save_plan` rejects (SPEC_REQUIRED) when `/swarm sdd status` reports no resolved spec. The gate is overridable via `SWARM_SKIP_SPEC_GATE=1`.
|
|
53
60
|
- Before calling save_plan, verify an effective spec exists (via `/swarm sdd status` or `lint_spec`).
|
|
@@ -73,8 +73,9 @@ All other gates: failure → return to coder. No self-fixes. No workarounds.
|
|
|
73
73
|
→ REQUIRED: Print "diff: [PASS | CONTRACT CHANGE — details]"
|
|
74
74
|
5d. Run `syntax_check` tool. SYNTACTIC ERRORS → return to coder. NO ERRORS → proceed to placeholder_scan.
|
|
75
75
|
→ REQUIRED: Print "syntaxcheck: [PASS | FAIL — N errors]"
|
|
76
|
-
5e. Run `placeholder_scan` tool. PLACEHOLDER FINDINGS → return to coder. NO FINDINGS → proceed to imports.
|
|
77
|
-
→
|
|
76
|
+
5e. Run `placeholder_scan` tool WITH DIFF SCOPING: pass `added_lines` — a map of workspace-relative file path → the line numbers ADDED by this task's uncommitted work (from `git diff -U0 HEAD -- <task files>` for tracked files; the coder's edits are not committed yet, so a commit-range diff like `<base>...HEAD` returns zero added lines here) — so only task-added lines drive the verdict. PLACEHOLDER FINDINGS (on added lines) → return to coder. NO FINDINGS → proceed to imports.
|
|
77
|
+
→ Diff-scope fallback: for a file whose added lines you cannot map (new/untracked file, no diff available) or whose computed added-line set is EMPTY, OMIT that file from `added_lines` entirely — the tool then scans it unfiltered (fail-closed) — and manually cross-check that file's findings against the changed lines before returning to coder. NEVER pass an empty line array for a file (an empty array suppresses every finding in it) and NEVER hand-enumerate guessed line numbers (a wrong map silently suppresses findings). A pre-existing TODO/FIXME on an unchanged line is existing debt to surface to the reviewer, not a coder bounce.
|
|
78
|
+
→ REQUIRED: Print "placeholderscan: [PASS | FAIL — N findings (diff-scoped) | FAIL — N findings (unscoped — cross-checked against changed lines)]"
|
|
78
79
|
5f. Run `imports` tool for dependency audit. ISSUES → return to coder.
|
|
79
80
|
→ REQUIRED: Print "imports: [PASS | ISSUES — details]"
|
|
80
81
|
5g. Run `lint` tool with fix mode for auto-fixes. If issues remain → run `lint` tool with check mode. FAIL → return to coder.
|
|
@@ -193,7 +194,7 @@ This step supplements (not replaces) the existing regression-sweep and test-drif
|
|
|
193
194
|
5o. ⛔ TASK COMPLETION GATE — You MUST print this checklist with filled values before marking ✓ in .swarm/plan.md:
|
|
194
195
|
[TOOL] diff: PASS / SKIP — value: ___
|
|
195
196
|
[TOOL] syntax_check: PASS — value: ___
|
|
196
|
-
[TOOL] placeholder_scan: PASS — value: ___
|
|
197
|
+
[TOOL] placeholder_scan: PASS — value: ___ (diff-scoped | unscoped — cross-checked)
|
|
197
198
|
[TOOL] imports: PASS — value: ___
|
|
198
199
|
[TOOL] lint: PASS — value: ___
|
|
199
200
|
[TOOL] build_check: PASS / SKIPPED — value: ___
|
|
@@ -105,6 +105,8 @@ If any required agent is missing, `phase_complete` returns `{ success: false, st
|
|
|
105
105
|
|
|
106
106
|
The `docs` agent requirement is controlled by `phase_complete.require_docs` in plugin configuration, not by the QA gate profile returned by `get_qa_gate_profile`. It defaults to `true`. Set it to `false` only when the phase genuinely has no documentation obligation. A successful docs completion is persisted as plan- and phase-bound participation proof so `phase_complete` can recover it after a session restart; unrelated task-gate evidence does not count as docs participation.
|
|
107
107
|
|
|
108
|
+
Docs-attestation integrity (issue #1994 P2): when the docs agent concludes that a phase — especially a doc-only phase — needs no further documentation edits, that attestation is valid ONLY if the docs agent actually inspected the phase's changed files and recorded what it checked (files read, per-file verdict) in its completion report. A mechanical "no edits needed" reply dispatched only to satisfy `agentsDispatched` — without inspecting the phase's changes — is a process violation: the gate exists to catch documentation drift, not to be acknowledged past.
|
|
109
|
+
|
|
108
110
|
The `coder` and `test_engineer` agents are required because every phase that modifies source code or tests must have at least one implementation and one test-verification delegation. For pure documentation or retrospective phases, these may be waived by the user explicitly.
|
|
109
111
|
|
|
110
112
|
This is a hard enforcement mechanism, not a suggestion. `phase_complete` will not return `status: success` if any required agent is missing from `agentsDispatched`.
|
|
@@ -232,6 +232,12 @@ git worktree remove "$env:TEMP\repro-check"
|
|
|
232
232
|
|
|
233
233
|
---
|
|
234
234
|
|
|
235
|
+
## Placeholder Scans Without Diff Line Numbers
|
|
236
|
+
|
|
237
|
+
`placeholder_scan` is diff-aware: when you can supply `added_lines` (a map of workspace-relative file path → added line numbers from the task/PR diff), its verdict covers only the added lines, so a pre-existing TODO/FIXME on an unchanged line inside a changed file no longer fails the gate. When you CANNOT map a file's added lines (new/untracked file, no diff access) — or the computed added-line set is EMPTY — omit that file from `added_lines` entirely: the tool scans it unfiltered, fail-closed, and you manually cross-check that file's findings against the changed lines before treating a finding as introduced by the change. NEVER pass an empty line array for a file (an empty array suppresses every finding in it) and NEVER hand-enumerate guessed line numbers: a wrong `added_lines` map silently suppresses findings.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
235
241
|
## Failure Classification
|
|
236
242
|
|
|
237
243
|
Not all failures are equal. Before deciding what to do, classify the failure:
|
|
@@ -117,6 +117,8 @@ Implement in coherent, reviewable chunks. Follow existing repository patterns.
|
|
|
117
117
|
|
|
118
118
|
**`declare_scope` discipline.** Before every coder or test-engineer delegation (and before every retry), call `declare_scope({ taskId, files, replace_existing: true })` with the exact workspace-relative file list the delegated agent may modify — including generated or lockfile paths the change will produce (for example, `dist/*`, `package-lock.json`, or `bun.lock`). Direct and shell writes are both scope-enforced. If the file list is not completely obvious, declare the containing workspace-relative directories instead. Treat `SCOPE_CONFLICT`, `SCOPE_BINDING_EXPIRED`, `SCOPE_BINDING_AMBIGUOUS`, and `SCOPE_WORKSPACE_MISMATCH` as architect-owned recovery signals: reconcile the named scope sources or lane root, replace the declaration, then redispatch. Never instruct the delegated agent to bypass the gate or switch write mechanisms.
|
|
119
119
|
|
|
120
|
+
**Smallest justified scope on `SCOPE_CONFLICT` (issue #1994 S4).** The replacement declaration must be the SMALLEST justified scope: first reconcile what the delegation actually intends to write (the task's files vs the conflicting scope source named in the diagnostic), then narrow the conflicting lower-precedence source to a subset of that list — repair stale plan scope with `save_plan` and/or the delegation's `FILE:` lines — and only then re-declare exactly that file list; re-declaring alone leaves the non-subset relation and reproduces the same `SCOPE_CONFLICT`. Split the task into separate delegations if the conflict reveals two disjoint write sets. NEVER resolve a `SCOPE_CONFLICT` by widening to a plan-inferred superset: auto-widening over-authorizes writes and hides an inaccurate plan or delegation prompt behind a bigger scope. This matches the execute skill's scope-recovery contract ("Do not widen scope just to make the sets agree"); a `save_plan` scope repair is a bookkeeping change covered by the critic-gate plan-freeze rule.
|
|
121
|
+
|
|
120
122
|
If the project exposes `sast_scan` with `capture_baseline`, capture the
|
|
121
123
|
phase-scoped SAST baseline before first coder delegation so later scans fail only
|
|
122
124
|
on new findings rather than pre-existing infrastructure noise.
|
|
@@ -832,6 +832,7 @@ Tool candidate rules:
|
|
|
832
832
|
|
|
833
833
|
- Confirm reachability before reporting.
|
|
834
834
|
- Confirm PR-introducedness before reporting as a PR blocker.
|
|
835
|
+
- When `placeholder_scan` output is used as a signal, pass `added_lines` (file path → PR-added line numbers from the merge-base diff) so only added lines drive the scan; a placeholder finding on an unchanged line is a pre-existing-debt candidate, not a PR blocker. If added-line mapping is unavailable, treat the findings as unscoped and cross-check them against the PR diff before recording the row.
|
|
835
836
|
- Confirm that a framework, schema, middleware, caller guard, or test isolation rule does not already mitigate it.
|
|
836
837
|
- Do not report scanner output verbatim without reviewer validation.
|
|
837
838
|
- Redact secrets; never paste raw credentials into the final output.
|
|
@@ -20,7 +20,7 @@ export declare const ARCHITECT_MEMORY_OUTCOME_GUIDANCE = "After using recalled m
|
|
|
20
20
|
* 5. Memory Rule (line ~101): Never store swarm identity in memory blocks
|
|
21
21
|
* 6. CRITIC GATE (lines ~102-107): Plan review before implementation
|
|
22
22
|
* 7. MANDATORY QA GATE (lines ~108-165):
|
|
23
|
-
* - Stage A: Automated tool gates (diff → syntax_check → placeholder_scan → imports → lint → build_check → pre_check_batch)
|
|
23
|
+
* - Stage A: Automated tool gates (diff → syntax_check → placeholder_scan (diff-scoped via added_lines) → imports → lint → build_check → pre_check_batch)
|
|
24
24
|
* - Stage B: Agent review gates (reviewer → security reviewer → test_engineer)
|
|
25
25
|
* - ANTI-EXEMPTION RULES: 8 "WRONG thoughts" to ignore
|
|
26
26
|
* - PARTIAL GATE RATIONALIZATIONS: 6 "WRONG thoughts" to ignore
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Task/lane delegation lifecycle operations (issue #2045).
|
|
3
|
+
*
|
|
4
|
+
* Task-tool delegations and `dispatch_lanes` lanes both persist their state in
|
|
5
|
+
* the background-delegations ledger and both record their start through
|
|
6
|
+
* `recordPendingDelegationDetailed`; before issue #2045 only the Task side
|
|
7
|
+
* settled terminals through `claimTerminalResult`, leaving lanes with the
|
|
8
|
+
* weaker status-only `appendDelegationTransition` write. This module gives
|
|
9
|
+
* lanes the same exactly-once terminal semantics — `settleDelegationTerminal`
|
|
10
|
+
* wraps the SAME `claimTerminalResult` primitive the Task completion observer
|
|
11
|
+
* calls directly (one claim implementation, no second lifecycle state machine)
|
|
12
|
+
* — and emits the lane-side terminal observations the Task side produces
|
|
13
|
+
* through its `tool.execute.*` hooks (cost telemetry, trajectory, knowledge
|
|
14
|
+
* receipt reconciliation), so equivalent Task and lane dispatches leave
|
|
15
|
+
* equivalent lifecycle facts behind.
|
|
16
|
+
*
|
|
17
|
+
* Every observation is fail-open and split into two durability classes — see
|
|
18
|
+
* the `settleDelegationTerminal` docstring for the contract: AUTHORITATIVE
|
|
19
|
+
* ledger-committed receipts re-run on `duplicate` replays (crash recovery),
|
|
20
|
+
* while DIAGNOSTIC observations run only on `claimed` (exactly-once-at-emit).
|
|
21
|
+
*/
|
|
22
|
+
import { type PricingConfig } from '../services/cost-accounting.js';
|
|
23
|
+
import { type BackgroundDelegationRecord, type BackgroundDelegationResult, type BackgroundTerminalResult, claimTerminalResult, findByCorrelationId } from './pending-delegations.js';
|
|
24
|
+
/** Terminal statuses a shared settle may establish (mirrors Task semantics). */
|
|
25
|
+
export type DelegationTerminalStatus = 'completed' | 'error' | 'cancelled';
|
|
26
|
+
/**
|
|
27
|
+
* Why `settleDelegationTerminal` returned without a fresh claim.
|
|
28
|
+
*
|
|
29
|
+
* `already_terminal_without_event` is deliberately distinct from `conflict`:
|
|
30
|
+
* a record terminalized WITHOUT an immutable event (the 30-minute stale sweep
|
|
31
|
+
* or a legacy status-only writer won the race) is a benign outcome that must
|
|
32
|
+
* not tick the late-terminal audit — the audit belongs to the writer that
|
|
33
|
+
* owns the conflicting *event*, and there is none.
|
|
34
|
+
*/
|
|
35
|
+
export type DelegationSettleKind = 'claimed' | 'duplicate' | 'conflict' | 'already_terminal_without_event' | 'not_open' | 'missing';
|
|
36
|
+
export interface DelegationSettleOutcome {
|
|
37
|
+
kind: DelegationSettleKind;
|
|
38
|
+
record?: BackgroundDelegationRecord;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Settle outcomes that mean "the work item is already durably terminal; the
|
|
42
|
+
* caller's benign already-terminal handling applies" (no retry, no failure
|
|
43
|
+
* diagnostic — the race was routine).
|
|
44
|
+
*/
|
|
45
|
+
export declare function isBenignSettleOutcome(kind: DelegationSettleKind): boolean;
|
|
46
|
+
export interface DelegationTerminalInput {
|
|
47
|
+
status: DelegationTerminalStatus;
|
|
48
|
+
result: BackgroundDelegationResult;
|
|
49
|
+
}
|
|
50
|
+
export interface DelegationObservationInput {
|
|
51
|
+
/** Full lane/delegate transcript text; drives knowledge reconciliation. */
|
|
52
|
+
transcript?: string;
|
|
53
|
+
/** Raw cost-evidence source (assistant info/metadata), when available. */
|
|
54
|
+
costRaw?: unknown;
|
|
55
|
+
/** Configured model for cost projection fallback. */
|
|
56
|
+
model?: string;
|
|
57
|
+
/** Pricing config for normalized cost estimation. */
|
|
58
|
+
pricing?: PricingConfig;
|
|
59
|
+
/** Wall-clock dispatch start (ms epoch), for trajectory elapsed_ms. */
|
|
60
|
+
startedAt?: number;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Build the immutable terminal event for a delegation record. The eventId is
|
|
64
|
+
* derived from trusted correlation + immutable result metadata (no timestamps,
|
|
65
|
+
* no process state), so a replayed observation of the same result claims
|
|
66
|
+
* idempotently and a different result is a distinct, auditable event.
|
|
67
|
+
*/
|
|
68
|
+
export declare function buildDelegationTerminal(record: Pick<BackgroundDelegationRecord, 'correlationId' | 'jobId'>, terminal: DelegationTerminalInput, now: number): BackgroundTerminalResult;
|
|
69
|
+
/**
|
|
70
|
+
* Settle a delegation terminal exactly once through the shared claim, then —
|
|
71
|
+
* only on a fresh `claimed` disposition — run the terminal observations.
|
|
72
|
+
*
|
|
73
|
+
* Durability model (final-critic challenge, crash between claim and
|
|
74
|
+
* observations):
|
|
75
|
+
* - The AUTHORITATIVE receipts (validator/ledger-committed delegate ACK
|
|
76
|
+
* terminals, unacknowledged-critical violations, and reviewer verdicts) are
|
|
77
|
+
* re-run on `duplicate` replays: the receipt ledger's terminal authority is
|
|
78
|
+
* idempotent (same-outcome replays are `idempotent_skips`), so a replay
|
|
79
|
+
* after a crash closes the receipts exactly once — a lane whose observation
|
|
80
|
+
* pass died mid-flight recovers on any later settle replay (restart,
|
|
81
|
+
* concurrent collector).
|
|
82
|
+
* - The DIAGNOSTIC observations are exactly-once-at-emit on `claimed` only —
|
|
83
|
+
* they have no deduplicating sink, and re-emitting them on replay would
|
|
84
|
+
* duplicate records. This covers cost telemetry, trajectory, AND the
|
|
85
|
+
* audit-only non-critical `unacknowledged` knowledge observation (which
|
|
86
|
+
* bypasses the receipt ledger). It is the same crash window the Task
|
|
87
|
+
* transport's `tool.execute.*` hook emissions have always had (documented
|
|
88
|
+
* transport parity, not a regression).
|
|
89
|
+
*
|
|
90
|
+
* See {@link DelegationSettleKind} for the non-claim outcomes; callers map
|
|
91
|
+
* `duplicate`/`conflict`/`already_terminal_without_event` to their benign
|
|
92
|
+
* already-terminal handling and `missing`/`not_open` to their
|
|
93
|
+
* settle-failure diagnostics.
|
|
94
|
+
*/
|
|
95
|
+
export declare function settleDelegationTerminal(directory: string, record: BackgroundDelegationRecord, terminal: DelegationTerminalInput, observations?: DelegationObservationInput, now?: number): Promise<DelegationSettleOutcome>;
|
|
96
|
+
/**
|
|
97
|
+
* Emit the `delegation_begin` pairing observation when a lane/delegation start
|
|
98
|
+
* record lands (issue #2045 Task/lane cost-event parity). Best-effort.
|
|
99
|
+
*/
|
|
100
|
+
export declare function emitDelegationBegin(record: Pick<BackgroundDelegationRecord, 'parentSessionId' | 'swarmPrefixedAgent' | 'planTaskId'>): void;
|
|
101
|
+
/**
|
|
102
|
+
* Canonical cost-record identity material for a lane/delegation terminal.
|
|
103
|
+
* Joining back to the delegation record uses exactly these record fields —
|
|
104
|
+
* never agent-name matching. The `lane:` discriminator keeps lane identities
|
|
105
|
+
* disjoint from Task-tool records, whose material is `${sessionId}\0${callID}`.
|
|
106
|
+
*/
|
|
107
|
+
export declare function delegationCostRecordMaterial(record: Pick<BackgroundDelegationRecord, 'parentSessionId' | 'callID' | 'laneId'>): string;
|
|
108
|
+
/** Bounded per-pass cap for terminal-lane receipt recovery (crash window). */
|
|
109
|
+
export declare const MAX_TERMINAL_LANE_RECEIPT_RECOVERY = 64;
|
|
110
|
+
/**
|
|
111
|
+
* Pre-record admission deadline for the directory-wide recovery pass
|
|
112
|
+
* (session-close hook): checked before EACH reconciliation, bounding how many
|
|
113
|
+
* records a pass may START — not the enumeration read/sort or an
|
|
114
|
+
* already-started reconciliation.
|
|
115
|
+
*/
|
|
116
|
+
export declare const TERMINAL_LANE_RECEIPT_RECOVERY_DEADLINE_MS = 5000;
|
|
117
|
+
export interface TerminalLaneReceiptRecoveryResult {
|
|
118
|
+
/** Terminal lane records whose receipt reconciliation replay was attempted. */
|
|
119
|
+
recovered: number;
|
|
120
|
+
/** True when the pass ended before every candidate was attempted. */
|
|
121
|
+
exhaustedBudget: boolean;
|
|
122
|
+
}
|
|
123
|
+
export interface RecoverTerminalLaneReceiptsOptions {
|
|
124
|
+
/**
|
|
125
|
+
* Admission budget for STARTING a reconciliation. Default 5s; the pass
|
|
126
|
+
* stops cleanly before the next record when exhausted. Does not bound the
|
|
127
|
+
* enumeration or an in-flight reconciliation.
|
|
128
|
+
*/
|
|
129
|
+
deadlineMs?: number;
|
|
130
|
+
/** Test seam for the clock. */
|
|
131
|
+
now?: () => number;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Durable crash-recovery pass for terminal lane records (final-critic
|
|
135
|
+
* challenge): a lane whose terminal claim landed but whose observation pass
|
|
136
|
+
* died is TERMINAL, so the collector's active-record filter skips it forever —
|
|
137
|
+
* the duplicate-replay path in {@link settleDelegationTerminal} would never be
|
|
138
|
+
* entered again on its own. This pass re-enters it: the durable transcript
|
|
139
|
+
* (`terminalResult.result.text`, persisted by the claim) is replayed through
|
|
140
|
+
* the ledger-idempotent receipt reconciliation in replay mode — authoritative
|
|
141
|
+
* receipts close exactly once; diagnostics never re-emit.
|
|
142
|
+
*
|
|
143
|
+
* Production wiring: (a) `collect_lane_results` runs it once per invocation
|
|
144
|
+
* over the batch's terminal records (the async-lane restart path — a batch is
|
|
145
|
+
* at most MAX_LANES records, so batch mode needs no cursor), and (b) the
|
|
146
|
+
* session-close maintenance trigger runs it directory-wide, which is what
|
|
147
|
+
* recovers BLOCKING lane records that have no collector.
|
|
148
|
+
*
|
|
149
|
+
* Forward progress (final-critic round 3): the directory-wide pass is bounded
|
|
150
|
+
* by a record cap and a pre-record admission deadline (checked before EACH
|
|
151
|
+
* reconciliation; it does not bound the candidate enumeration read/sort or an
|
|
152
|
+
* already-started reconciliation — those are bounded by the ledger read and
|
|
153
|
+
* the cap), and it persists an advancing
|
|
154
|
+
* cursor (`.swarm/lane-receipt-recovery-cursor.json`, ordered by
|
|
155
|
+
* `(updatedAt, correlationId)`), so each pass resumes after the last processed
|
|
156
|
+
* record and wraps to the oldest once the end is reached. Guarantees, stated
|
|
157
|
+
* exactly: under steady arrivals a candidate whose terminal commits with an
|
|
158
|
+
* ordering key OLDER than the cursor's position (a lock-contention straggler)
|
|
159
|
+
* is skipped until the next wrap — so a straggler is deferred, not lost, and
|
|
160
|
+
* an idle drain (a pass with nothing after the cursor) wraps immediately.
|
|
161
|
+
* Replays are ledger-idempotent, so a lost, stale, or wrapped cursor only
|
|
162
|
+
* causes harmless rework. Fail-open per record; never throws.
|
|
163
|
+
*/
|
|
164
|
+
export declare function recoverTerminalLaneReceipts(directory: string, records?: readonly BackgroundDelegationRecord[], options?: RecoverTerminalLaneReceiptsOptions): Promise<TerminalLaneReceiptRecoveryResult>;
|
|
165
|
+
/**
|
|
166
|
+
* Test seam (repo convention): the telemetry sink and the claim are injectable
|
|
167
|
+
* so tests can stub them without `mock.module`.
|
|
168
|
+
*/
|
|
169
|
+
export declare const _internals: {
|
|
170
|
+
claimTerminalResult: typeof claimTerminalResult;
|
|
171
|
+
findByCorrelationId: typeof findByCorrelationId;
|
|
172
|
+
telemetry: {
|
|
173
|
+
sessionStarted(sessionId: string, agentName: string): void;
|
|
174
|
+
sessionEnded(sessionId: string, reason: string): void;
|
|
175
|
+
agentActivated(sessionId: string, agentName: string, oldName?: string): void;
|
|
176
|
+
delegationBegin(sessionId: string, agentName: string, taskId: string): void;
|
|
177
|
+
delegationEnd(sessionId: string, agentName: string, taskId: string, result: string, costFields?: Partial<import("../services/cost-accounting.js").DelegationCostFields>): void;
|
|
178
|
+
taskStateChanged(sessionId: string, taskId: string, newState: string, oldState?: string): void;
|
|
179
|
+
gatePassed(sessionId: string, gate: string, taskId: string): void;
|
|
180
|
+
gateParseError(taskId: string, error: Error): void;
|
|
181
|
+
gateFailed(sessionId: string, gate: string, taskId: string, reason: string): void;
|
|
182
|
+
reviewerGateDecision(sessionId: string, taskId: string, blocked: boolean, reasonCode: import("../telemetry.js").ReviewerGateReasonCode, evidenceKind: import("../telemetry.js").ReviewerGateEvidenceKind): void;
|
|
183
|
+
phaseChanged(sessionId: string, oldPhase: number, newPhase: number): void;
|
|
184
|
+
budgetUpdated(sessionId: string, budgetPct: number, agentName: string): void;
|
|
185
|
+
contextPruned(data: {
|
|
186
|
+
sessionId: string;
|
|
187
|
+
agentName: string;
|
|
188
|
+
trigger: "agent_switch" | "critical_threshold";
|
|
189
|
+
usageSource: "provider" | "estimated";
|
|
190
|
+
beforeTokens: number;
|
|
191
|
+
afterTokens: number;
|
|
192
|
+
modelLimit: number;
|
|
193
|
+
maskedMessages: number;
|
|
194
|
+
maskedToolParts: number;
|
|
195
|
+
maskedTokensFreed: number;
|
|
196
|
+
prunedMessages: number;
|
|
197
|
+
prunedTextParts: number;
|
|
198
|
+
prunedToolParts: number;
|
|
199
|
+
prunedTokensFreed: number;
|
|
200
|
+
}): void;
|
|
201
|
+
modelFallback(sessionId: string, agentName: string, fromModel: string, toModel: string, reason: string): void;
|
|
202
|
+
modelUnresolved(agentName: string, model: string, detail: string): void;
|
|
203
|
+
hardLimitHit(sessionId: string, agentName: string, limitType: string, value: number): void;
|
|
204
|
+
revisionLimitHit(sessionId: string, agentName: string): void;
|
|
205
|
+
loopDetected(sessionId: string, agentName: string, loopType: string): void;
|
|
206
|
+
noOpStrongWarning(sessionId: string, agentName: string, count: number, threshold: number): void;
|
|
207
|
+
gateDenialLoop(sessionId: string, tool: string, code: string, count: number): void;
|
|
208
|
+
executionStallWarning(sessionId: string, count: number, threshold: number): void;
|
|
209
|
+
executionStallDenied(sessionId: string, tool: string, count: number, threshold: number): void;
|
|
210
|
+
swarmInternalsReadDenied(sessionId: string, tool: string, target: string): void;
|
|
211
|
+
scopeViolation(sessionId: string, agentName: string, file: string, reason: string): void;
|
|
212
|
+
qaSkipViolation(sessionId: string, agentName: string, skipCount: number): void;
|
|
213
|
+
heartbeat(sessionId: string): void;
|
|
214
|
+
turboModeChanged(sessionId: string, enabled: boolean, agentName: string): void;
|
|
215
|
+
autoOversightEscalation(sessionId: string, reason: string, interactionCount: number, deadlockCount: number, phase?: number): void;
|
|
216
|
+
environmentDetected(sessionId: string, hostOS: string, shellFamily: string, executionMode: string): void;
|
|
217
|
+
prmPatternDetected(sessionId: string, pattern: string, severity: string, category: string, stepRange: [number, number]): void;
|
|
218
|
+
prmCourseCorrectionInjected(sessionId: string, pattern: string, level: number): void;
|
|
219
|
+
prmEscalationTriggered(sessionId: string, pattern: string, level: number, occurrenceCount: number): void;
|
|
220
|
+
prmHardStop(sessionId: string, pattern: string, level: number, occurrenceCount: number): void;
|
|
221
|
+
closeArchiveResult(data: {
|
|
222
|
+
archive_valid: boolean;
|
|
223
|
+
archive_empty: boolean;
|
|
224
|
+
file_count: number;
|
|
225
|
+
bundle: string;
|
|
226
|
+
artifacts: Array<{
|
|
227
|
+
artifact: string;
|
|
228
|
+
requiredness: string;
|
|
229
|
+
attempt: string;
|
|
230
|
+
validation: string;
|
|
231
|
+
source_disposition: string;
|
|
232
|
+
method: string;
|
|
233
|
+
reason_code: string;
|
|
234
|
+
row_counts?: {
|
|
235
|
+
schema_migrations_max_version: number | null;
|
|
236
|
+
project_constraints: number;
|
|
237
|
+
qa_gate_profile: number;
|
|
238
|
+
};
|
|
239
|
+
}>;
|
|
240
|
+
}): void;
|
|
241
|
+
residueHealth(data: {
|
|
242
|
+
trigger: string;
|
|
243
|
+
scanned: number;
|
|
244
|
+
matched: number;
|
|
245
|
+
eligible: number;
|
|
246
|
+
ambiguous: number;
|
|
247
|
+
quarantined: number;
|
|
248
|
+
preserved: number;
|
|
249
|
+
total_bytes: number;
|
|
250
|
+
oldest_age_ms: number;
|
|
251
|
+
grammar_counts: Record<string, number>;
|
|
252
|
+
}): void;
|
|
253
|
+
contextTelemetryHealth(data: {
|
|
254
|
+
trigger: "compaction" | "close";
|
|
255
|
+
accepted_count: number;
|
|
256
|
+
compacted_count: number;
|
|
257
|
+
retained_count: number;
|
|
258
|
+
dropped_count: number;
|
|
259
|
+
corrupt_count: number;
|
|
260
|
+
oldest_timestamp: string | null;
|
|
261
|
+
newest_timestamp: string | null;
|
|
262
|
+
bytes: number;
|
|
263
|
+
limit_bytes: number;
|
|
264
|
+
}): void;
|
|
265
|
+
skillUsageHealth(data: {
|
|
266
|
+
trigger: "compaction" | "migration" | "consumption" | "pressure";
|
|
267
|
+
accepted: number;
|
|
268
|
+
compacted: number;
|
|
269
|
+
dropped: number;
|
|
270
|
+
skills_dropped: number;
|
|
271
|
+
corrupt: number;
|
|
272
|
+
pending_retained: number;
|
|
273
|
+
uncertain_retained: number;
|
|
274
|
+
uncertain_expired: number;
|
|
275
|
+
pending_evicted: number;
|
|
276
|
+
no_source_knowledge: number;
|
|
277
|
+
no_matching_knowledge: number;
|
|
278
|
+
bump_retry: number;
|
|
279
|
+
bump_unrecoverable: number;
|
|
280
|
+
bump_applied_zero: number;
|
|
281
|
+
pressure: number;
|
|
282
|
+
curator_skipped: number;
|
|
283
|
+
bytes: number;
|
|
284
|
+
limit_bytes: number;
|
|
285
|
+
oldest_timestamp: string | null;
|
|
286
|
+
newest_timestamp: string | null;
|
|
287
|
+
coverage: boolean;
|
|
288
|
+
}): void;
|
|
289
|
+
coreEventsHealth(data: {
|
|
290
|
+
trigger: "compaction" | "close";
|
|
291
|
+
accepted_count: number;
|
|
292
|
+
compacted_count: number;
|
|
293
|
+
retained_count: number;
|
|
294
|
+
dropped_count: number;
|
|
295
|
+
corrupt_count: number;
|
|
296
|
+
authority_index_count: number;
|
|
297
|
+
authority_evicted_count: number;
|
|
298
|
+
oldest_timestamp: string | null;
|
|
299
|
+
newest_timestamp: string | null;
|
|
300
|
+
bytes: number;
|
|
301
|
+
limit_bytes: number;
|
|
302
|
+
}): void;
|
|
303
|
+
shellAuditHealth(data: {
|
|
304
|
+
trigger: "compaction" | "close";
|
|
305
|
+
accepted_count: number;
|
|
306
|
+
compacted_count: number;
|
|
307
|
+
retained_count: number;
|
|
308
|
+
dropped_count: number;
|
|
309
|
+
corrupt_count: number;
|
|
310
|
+
oldest_timestamp: string | null;
|
|
311
|
+
newest_timestamp: string | null;
|
|
312
|
+
bytes: number;
|
|
313
|
+
limit_bytes: number;
|
|
314
|
+
}): void;
|
|
315
|
+
trajectoryHealth(data: {
|
|
316
|
+
trigger: "compaction" | "cleanup" | "append_skip";
|
|
317
|
+
retained_count: number;
|
|
318
|
+
dropped_count: number;
|
|
319
|
+
corrupt_count: number;
|
|
320
|
+
skipped_lock_count: number;
|
|
321
|
+
bytes: number;
|
|
322
|
+
limit_bytes: number;
|
|
323
|
+
}): void;
|
|
324
|
+
prSubscriptionHealth(data: {
|
|
325
|
+
trigger: "compact" | "migrate-complete" | "archive" | "foreign-rebind" | "corrupt-quarantine";
|
|
326
|
+
active_count: number;
|
|
327
|
+
terminal_count: number;
|
|
328
|
+
compactions: number;
|
|
329
|
+
corrupt_count: number;
|
|
330
|
+
dropped_audit_count: number;
|
|
331
|
+
recovery_resets: number;
|
|
332
|
+
checkpoint_bytes: number;
|
|
333
|
+
limit_bytes: number;
|
|
334
|
+
}): void;
|
|
335
|
+
learningHealthAlarm(data: {
|
|
336
|
+
alarm: string;
|
|
337
|
+
transition: "raised" | "sustained" | "recovered";
|
|
338
|
+
severity: "warning" | "critical";
|
|
339
|
+
scope_class: "session" | "identity" | "project";
|
|
340
|
+
session_ref?: string;
|
|
341
|
+
model?: string;
|
|
342
|
+
provider?: string;
|
|
343
|
+
window_ms: number;
|
|
344
|
+
coverage_facts: number;
|
|
345
|
+
raise_facts: number;
|
|
346
|
+
age_ms: number;
|
|
347
|
+
limit_source?: string;
|
|
348
|
+
denominator_fallback?: boolean;
|
|
349
|
+
pressure_pct?: number;
|
|
350
|
+
band?: string;
|
|
351
|
+
share_pct?: number;
|
|
352
|
+
field_count?: number;
|
|
353
|
+
non_field_count?: number;
|
|
354
|
+
store?: string;
|
|
355
|
+
dropped?: number;
|
|
356
|
+
corrupt?: number;
|
|
357
|
+
retained?: number;
|
|
358
|
+
accepted?: number;
|
|
359
|
+
gap_type?: "membership_to_terminal" | "terminal_to_application";
|
|
360
|
+
role?: string;
|
|
361
|
+
phase?: number;
|
|
362
|
+
reason?: string;
|
|
363
|
+
}): void;
|
|
364
|
+
prmHardStopDelivered(sessionId: string, pattern: string, level: number, occurrenceCount: number): void;
|
|
365
|
+
retrievalRouted(sessionId: string, data: {
|
|
366
|
+
mode: "graph" | "lexical" | "semantic" | "security" | "test" | "hybrid";
|
|
367
|
+
graph_hit: boolean;
|
|
368
|
+
fallback_reason: string | null;
|
|
369
|
+
token_budget_requested: number;
|
|
370
|
+
token_budget_used: number;
|
|
371
|
+
omitted_context_count: number;
|
|
372
|
+
}): void;
|
|
373
|
+
};
|
|
374
|
+
};
|
|
@@ -711,6 +711,12 @@ export declare function findByBatchId(directory: string, batchId: string, opts?:
|
|
|
711
711
|
parentSessionId?: string;
|
|
712
712
|
}): BackgroundDelegationRecord[];
|
|
713
713
|
export declare function findOpenAsyncLaneBatches(directory: string): BackgroundDelegationRecord[];
|
|
714
|
+
/**
|
|
715
|
+
* Public alias of the internal terminal predicate so shared lifecycle callers
|
|
716
|
+
* (issue #2045: `delegation-lifecycle.ts`) classify post-claim re-reads with
|
|
717
|
+
* the exact same status set as the store's own guards — never a second copy.
|
|
718
|
+
*/
|
|
719
|
+
export declare function isTerminalDelegationStatus(status: BackgroundDelegationStatus): boolean;
|
|
714
720
|
/**
|
|
715
721
|
* Public stale sweep: acquires the store lock and marks overdue pendings as `stale`.
|
|
716
722
|
* Best-effort; returns the number swept (0 on lock timeout / error).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface ResolvedCommand {
|
|
2
|
+
argv: string[];
|
|
3
|
+
shellCommand: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Tokenize a generated command into argv without invoking a shell. Supports
|
|
7
|
+
* single and double quotes for grouping, but never interprets shell
|
|
8
|
+
* metacharacters.
|
|
9
|
+
*/
|
|
10
|
+
export declare function tokenizeCommand(command: string): string[];
|
|
11
|
+
/** Resolve a plugin-generated command without invoking a package downloader. */
|
|
12
|
+
export declare function resolveLocalCommand(command: string, workingDir: string, isAvailable: (binary: string) => boolean, platform?: NodeJS.Platform): ResolvedCommand | null;
|
|
13
|
+
export declare function resolveLocalNodeTool(tool: string, args: string[], workingDir: string, platform?: NodeJS.Platform, isAvailable?: (binary: string) => boolean): string[] | null;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { tool } from '@opencode-ai/plugin';
|
|
2
|
+
import { detectProjectLanguages } from '../lang/detector';
|
|
3
|
+
import { LANGUAGE_REGISTRY } from '../lang/profiles';
|
|
2
4
|
import { bunSpawnSync } from '../utils/bun-compat';
|
|
3
5
|
export interface BuildCommand {
|
|
4
6
|
ecosystem: string;
|
|
@@ -8,10 +10,13 @@ export interface BuildCommand {
|
|
|
8
10
|
}
|
|
9
11
|
export interface BuildDiscoveryResult {
|
|
10
12
|
commands: BuildCommand[];
|
|
11
|
-
skipped:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
skipped: BuildDiscoverySkip[];
|
|
14
|
+
}
|
|
15
|
+
export interface BuildDiscoverySkip {
|
|
16
|
+
ecosystem: string;
|
|
17
|
+
reason: string;
|
|
18
|
+
code?: 'environment_unavailable';
|
|
19
|
+
required_commands?: string[];
|
|
15
20
|
}
|
|
16
21
|
export interface BuildDiscoveryOptions {
|
|
17
22
|
scope?: 'changed' | 'all';
|
|
@@ -27,6 +32,8 @@ export declare const _internals: {
|
|
|
27
32
|
discoverBuildCommands: typeof discoverBuildCommands;
|
|
28
33
|
clearToolchainCache: typeof clearToolchainCache;
|
|
29
34
|
getEcosystems: typeof getEcosystems;
|
|
35
|
+
detectProjectLanguagesImpl: typeof detectProjectLanguages;
|
|
36
|
+
getLanguageProfileImpl: typeof LANGUAGE_REGISTRY.get;
|
|
30
37
|
spawnSyncImpl: typeof bunSpawnSync;
|
|
31
38
|
};
|
|
32
39
|
export declare function discoverBuildCommandsFromProfiles(workingDir: string): Promise<BuildDiscoveryResult>;
|
|
@@ -13,27 +13,27 @@ import {
|
|
|
13
13
|
releaseCoderDispatchOwnership,
|
|
14
14
|
settleCoderDispatch,
|
|
15
15
|
transferCoderSettlementToBackground
|
|
16
|
-
} from "./index-
|
|
16
|
+
} from "./index-w9g58t3j.js";
|
|
17
17
|
import"./index-3f7hqtgg.js";
|
|
18
18
|
import"./index-awjx0wgk.js";
|
|
19
|
-
import"./index-
|
|
20
|
-
import"./index-
|
|
19
|
+
import"./index-t81fmfjj.js";
|
|
20
|
+
import"./index-xy0e0r5f.js";
|
|
21
21
|
import"./index-ddszzne4.js";
|
|
22
|
-
import"./index-
|
|
22
|
+
import"./index-7619tk9a.js";
|
|
23
23
|
import"./index-556ja8an.js";
|
|
24
24
|
import"./index-dtn0pne5.js";
|
|
25
25
|
import"./index-z6xqpmqg.js";
|
|
26
26
|
import"./index-r3mvsbtq.js";
|
|
27
27
|
import"./index-9e6fdz2h.js";
|
|
28
28
|
import"./index-4rhhvd1a.js";
|
|
29
|
-
import"./index-
|
|
29
|
+
import"./index-k55td019.js";
|
|
30
30
|
import"./index-c9zp4xwc.js";
|
|
31
31
|
import"./index-zjygnfay.js";
|
|
32
|
-
import"./index-
|
|
33
|
-
import"./index-
|
|
32
|
+
import"./index-d8st72j7.js";
|
|
33
|
+
import"./index-nqbqkx4c.js";
|
|
34
34
|
import"./index-dh5q6z7y.js";
|
|
35
35
|
import"./index-ed5ykebp.js";
|
|
36
|
-
import"./index-
|
|
36
|
+
import"./index-fx3em0dr.js";
|
|
37
37
|
import"./index-7g4c7s5r.js";
|
|
38
38
|
import"./index-bpmtbmy9.js";
|
|
39
39
|
import"./index-zgwm4ryv.js";
|
|
@@ -12,9 +12,9 @@ import {
|
|
|
12
12
|
shouldRunOnStartup,
|
|
13
13
|
writeBackupArtifact,
|
|
14
14
|
writeDoctorArtifact
|
|
15
|
-
} from "./index-
|
|
15
|
+
} from "./index-h6wtxzvm.js";
|
|
16
16
|
import"./index-z6xqpmqg.js";
|
|
17
|
-
import"./index-
|
|
17
|
+
import"./index-zkgrayya.js";
|
|
18
18
|
import"./index-c9zp4xwc.js";
|
|
19
19
|
import"./index-zjygnfay.js";
|
|
20
20
|
import"./index-bk5tah7q.js";
|
|
@@ -4,14 +4,14 @@ import {
|
|
|
4
4
|
authorizeCuration,
|
|
5
5
|
buildConfigFingerprintInput,
|
|
6
6
|
readCohortConfigFingerprint
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-f5axf6vq.js";
|
|
8
8
|
import"./index-rtry5xyf.js";
|
|
9
|
-
import"./index-
|
|
10
|
-
import"./index-
|
|
11
|
-
import"./index-
|
|
9
|
+
import"./index-c6zyqgpq.js";
|
|
10
|
+
import"./index-d8st72j7.js";
|
|
11
|
+
import"./index-nqbqkx4c.js";
|
|
12
12
|
import"./index-dh5q6z7y.js";
|
|
13
13
|
import"./index-ed5ykebp.js";
|
|
14
|
-
import"./index-
|
|
14
|
+
import"./index-fx3em0dr.js";
|
|
15
15
|
import"./index-7g4c7s5r.js";
|
|
16
16
|
import"./index-bpmtbmy9.js";
|
|
17
17
|
import"./index-zgwm4ryv.js";
|