opencode-swarm 7.179.1 → 7.180.1

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.
Files changed (115) hide show
  1. package/binaries/win32-arm64/swarm-sandbox-runner.exe +0 -0
  2. package/binaries/win32-x64/swarm-sandbox-runner.exe +0 -0
  3. package/dist/agents/architect.d.ts +67 -0
  4. package/dist/agents/council-prompts.d.ts +3 -3
  5. package/dist/agents/index.d.ts +1 -1
  6. package/dist/background/pr-event-subscribers.d.ts +2 -0
  7. package/dist/background/pr-feedback-event-queue.d.ts +7 -0
  8. package/dist/background/pr-feedback-loop.d.ts +162 -0
  9. package/dist/cli/{coder-settlement-f1nmezzv.js → coder-settlement-b57917a3.js} +14 -14
  10. package/dist/cli/{config-doctor-ena2803f.js → config-doctor-ebat06eq.js} +2 -2
  11. package/dist/cli/{core-fcfzme3m.js → core-8k41qh0d.js} +4 -5
  12. package/dist/cli/{curation-policy-c7mdsf7m.js → curation-policy-m3x9mkj9.js} +7 -6
  13. package/dist/cli/{curator-q9s5q9v4.js → curator-8yb3qkxs.js} +45 -43
  14. package/dist/cli/{curator-drift-d93pwt8h.js → curator-drift-3av9hffm.js} +22 -12
  15. package/dist/cli/curator-llm-factory-htgqafq0.js +74 -0
  16. package/dist/cli/{evidence-summary-service-wtj8mkm6.js → evidence-summary-service-s258ea5t.js} +23 -21
  17. package/dist/cli/{gate-evidence-h83yb8nd.js → gate-evidence-fqxpf3xz.js} +9 -9
  18. package/dist/cli/guardrail-explain-r0qxa4zy.js +75 -0
  19. package/dist/cli/{guardrail-log-zf1htf1d.js → guardrail-log-j2wdmvmy.js} +7 -7
  20. package/dist/cli/{guardrail-reset-f2p198j3.js → guardrail-reset-wb2eqbvf.js} +45 -43
  21. package/dist/cli/hive-promoter-kxpc3r17.js +89 -0
  22. package/dist/cli/{index-wrt875kh.js → index-0725jpp7.js} +1 -1
  23. package/dist/cli/{index-34bwqcea.js → index-12ewkms0.js} +1 -1
  24. package/dist/cli/{index-epfjc1c1.js → index-2q5m4m2r.js} +11 -11
  25. package/dist/cli/{index-h59vsbch.js → index-38cfx8g8.js} +2 -2
  26. package/dist/cli/{index-xy7k7f3k.js → index-3bbjpbmn.js} +2 -2
  27. package/dist/cli/{index-vp9pn7sv.js → index-3zvp7t5d.js} +5 -5
  28. package/dist/cli/{index-dz12bshh.js → index-50v672wd.js} +8 -8
  29. package/dist/cli/{index-yfpswnjt.js → index-516j9vsk.js} +4 -4
  30. package/dist/cli/{index-w4c2repz.js → index-600aqfvm.js} +47 -43
  31. package/dist/cli/{index-0h3cr7pn.js → index-6gcxgx84.js} +1 -1
  32. package/dist/cli/{index-qt0793qm.js → index-6mwha20t.js} +3 -3
  33. package/dist/cli/{index-93nx95me.js → index-855qxtdm.js} +8 -7
  34. package/dist/cli/{index-cvg402ha.js → index-91dhg3wr.js} +2 -2
  35. package/dist/cli/{index-3pzwsesm.js → index-92m05mew.js} +2 -2
  36. package/dist/cli/{index-ne9zamcs.js → index-989v83pb.js} +1 -1
  37. package/dist/cli/{index-9fb01jk5.js → index-as4xaams.js} +1 -1
  38. package/dist/cli/{index-2b0ktpbf.js → index-bdpgfep1.js} +5 -5
  39. package/dist/cli/{index-q375xdcw.js → index-bhmrgbyv.js} +9 -1
  40. package/dist/cli/{index-nzekzzs2.js → index-bv4b8tpa.js} +5 -5
  41. package/dist/cli/{index-rb9jmj30.js → index-cj64vp08.js} +7 -7
  42. package/dist/cli/{index-549wxbe1.js → index-cjapb4hy.js} +1 -1
  43. package/dist/cli/{index-5d224akk.js → index-dzm5nfh7.js} +4 -4
  44. package/dist/cli/{index-f2v90gfc.js → index-ea9fk6v0.js} +25 -166
  45. package/dist/cli/index-ejhxgyvm.js +147 -0
  46. package/dist/cli/{index-n1tcj1q7.js → index-g062wnw1.js} +187 -47
  47. package/dist/cli/{index-s4bkey0q.js → index-gc6h1fmf.js} +4 -4
  48. package/dist/cli/{index-pn023bf9.js → index-gw5egd8j.js} +49 -47
  49. package/dist/cli/index-gx2vp8gx.js +100 -0
  50. package/dist/cli/{index-yp25bc9n.js → index-gy3tcmk4.js} +7 -7
  51. package/dist/cli/{index-n2wjrgcs.js → index-k5vwnnym.js} +7 -9
  52. package/dist/cli/{index-ajm7ebyd.js → index-k6f0nryj.js} +2 -2
  53. package/dist/cli/{index-zbhvr9st.js → index-n5carmk0.js} +8 -10
  54. package/dist/cli/{index-h4nh6s8b.js → index-nhxykfyy.js} +1 -1
  55. package/dist/cli/{index-pskba939.js → index-rejpbgxp.js} +1 -1
  56. package/dist/cli/{index-9s1xzvnn.js → index-rp4akjrm.js} +13 -3
  57. package/dist/cli/{index-g6nyk713.js → index-s0zgz4p1.js} +1 -1
  58. package/dist/cli/{index-aqpwm350.js → index-tnhk72rs.js} +3 -3
  59. package/dist/cli/{index-sj29n50e.js → index-v0par978.js} +7 -7
  60. package/dist/cli/index-v7fx8q3z.js +339 -0
  61. package/dist/cli/{index-a11ztzs5.js → index-vmthakz0.js} +1 -1
  62. package/dist/cli/{index-b567t0cr.js → index-wx3wz7ya.js} +10 -8
  63. package/dist/cli/{index-y98fvmb8.js → index-xd0e4amf.js} +33 -18
  64. package/dist/cli/{index-m1w40kfw.js → index-xj5z92qz.js} +4 -103
  65. package/dist/cli/{index-6r92fw88.js → index-y30y1rkg.js} +9 -9
  66. package/dist/cli/{index-pfg3jwe9.js → index-yf7tdhpz.js} +3 -3
  67. package/dist/cli/{index-y94vwx2q.js → index-z2xf153n.js} +13 -15
  68. package/dist/cli/{index-ky262b73.js → index-z2zrcecq.js} +1721 -902
  69. package/dist/cli/{index-zz7gzw57.js → index-zxdawwc7.js} +88 -4
  70. package/dist/cli/index.js +46 -44
  71. package/dist/cli/{knowledge-escalator-z6tkgrjq.js → knowledge-escalator-n30h6ran.js} +17 -16
  72. package/dist/cli/{knowledge-events-2bgefatz.js → knowledge-events-k2qqase2.js} +15 -14
  73. package/dist/cli/{knowledge-link-gfz47ves.js → knowledge-link-s2qs178z.js} +6 -5
  74. package/dist/cli/{knowledge-store-1fphg9sa.js → knowledge-store-zy226v5a.js} +7 -6
  75. package/dist/cli/{knowledge-validator-723h2vck.js → knowledge-validator-qgyxdpc9.js} +9 -8
  76. package/dist/cli/{mcp-xyswgya5.js → mcp-pj7acze3.js} +1 -1
  77. package/dist/cli/{pending-delegations-5zm19yvv.js → pending-delegations-sgnnyw55.js} +14 -13
  78. package/dist/cli/{pr-subscriptions-5hm6hzv6.js → pr-subscriptions-7fb7xm3q.js} +14 -13
  79. package/dist/cli/{pr-workflow-gate-48rzb2bh.js → pr-workflow-gate-5dqcrkz6.js} +47 -43
  80. package/dist/cli/{runner-16b691ba.js → runner-p9hstpxn.js} +7 -6
  81. package/dist/cli/{scan-cursor-m28tddrg.js → scan-cursor-jc7wwb7e.js} +9 -9
  82. package/dist/cli/{schema-jt9axyj6.js → schema-5k68crjb.js} +3 -1
  83. package/dist/cli/{scope-persistence-d0358pw7.js → scope-persistence-xeg4khwk.js} +19 -18
  84. package/dist/cli/{server-d5jxcbxz.js → server-ej6tzd7t.js} +53 -51
  85. package/dist/cli/{skill-generator-qanka67x.js → skill-generator-nspt9b3n.js} +19 -18
  86. package/dist/cli/{snapshot-coordination-init-mhrq11p8.js → snapshot-coordination-init-3rs3zpaa.js} +45 -43
  87. package/dist/cli/speckit-checkoff-dqf636ya.js +31 -0
  88. package/dist/cli/{telemetry-qxav5cdk.js → telemetry-zhcgfe70.js} +1 -1
  89. package/dist/cli/{workspace-snapshot-rfnn80dg.js → workspace-snapshot-4m2ex1ey.js} +4 -5
  90. package/dist/cli/{worktree-collision-ownership-ygdbpexh.js → worktree-collision-ownership-rbzgbvj4.js} +17 -17
  91. package/dist/cli/{worktree-isolation-4855f2az.js → worktree-isolation-6zpnzr70.js} +45 -43
  92. package/dist/commands/pr-feedback-loop.d.ts +1 -0
  93. package/dist/commands/registry.d.ts +10 -2
  94. package/dist/config/schema.d.ts +27 -0
  95. package/dist/council/disagreement-detector.d.ts +23 -1
  96. package/dist/council/general-council-service.d.ts +40 -3
  97. package/dist/failures/invocation-failure.d.ts +11 -0
  98. package/dist/hooks/delegation-tracker.d.ts +6 -1
  99. package/dist/hooks/pr-workflow-gate.d.ts +1 -1
  100. package/dist/hooks/system-enhancer.d.ts +4 -2
  101. package/dist/hooks/system-render-boundary.d.ts +68 -0
  102. package/dist/index.js +634 -606
  103. package/dist/sdd/effective-spec.d.ts +35 -22
  104. package/dist/sdd/speckit-checkoff.d.ts +113 -0
  105. package/dist/session/hydration-ownership.d.ts +83 -0
  106. package/dist/session/snapshot-coordination-init.d.ts +2 -1
  107. package/dist/session/snapshot-reader.d.ts +25 -7
  108. package/dist/state.d.ts +32 -2
  109. package/dist/utils/provider-error-classification.d.ts +11 -0
  110. package/opencode-swarm.schema.json +40 -0
  111. package/package.json +1 -1
  112. package/dist/cli/curator-llm-factory-dds2fnhj.js +0 -72
  113. package/dist/cli/guardrail-explain-qm5wej7v.js +0 -73
  114. package/dist/cli/hive-promoter-1mhx2jh0.js +0 -87
  115. package/dist/cli/index-4ddpvd5c.js +0 -94
@@ -47,31 +47,36 @@ export interface SpeckitDetection {
47
47
  features: SpeckitFeatureEntry[];
48
48
  }
49
49
  /**
50
- * Discriminated union returned by {@link resolveSpeckitProjection} (task 1.4).
50
+ * Discriminated union returned by {@link resolveSpeckitProjection}.
51
51
  *
52
- * Each kind carries exactly the information the command layer (task 2.2) needs to
52
+ * Each kind carries exactly the information the command layer needs to
53
53
  * produce the correct error message per FR-008, FR-012, FR-013 without re-detecting.
54
54
  *
55
+ * Issue #2501 (Spec-Kit v2): the `ambiguous` kind is GONE — with more than one
56
+ * detected feature and no `options.feature`, the projector now projects ALL
57
+ * features into one effective spec with feature-scoped requirement ids
58
+ * (`<featureId>/FR-###`). Selecting a single feature (explicit `options.feature`)
59
+ * keeps the v1 single-feature, bare-id output byte-for-byte.
60
+ *
55
61
  * - `not_speckit` — no `.specify/` marker at the repo root (A-001).
56
62
  * - `empty` — marker present but no `specs/NNN/spec.md` feature dirs (FR-012).
57
- * - `ambiguous` — more than one feature and no `options.feature` given (FR-008);
58
- * `features` = sorted feature ids for naming in the error message.
59
63
  * - `unknown_feature` — `options.feature` was given but matches no detected feature.
60
- * - `zero_requirements`— the selected feature's spec.md yielded zero parsable functional
61
- * requirements (covers unreadable/oversized *input* files too) (FR-013).
64
+ * - `zero_requirements`— a projected feature's spec.md yielded zero parsable functional
65
+ * requirements (covers unreadable/oversized *input* files too)
66
+ * (FR-013). In multi-feature mode the whole projection refuses —
67
+ * a partially-dropped feature must never project silently.
62
68
  * - `too_large` — requirements parsed, but the projected *output* exceeds the byte
63
69
  * cap and is refused; `bytes` is the projected size. Distinct from
64
70
  * zero_requirements so the command layer reports the real reason.
65
- * - `ok` — a valid projection was built; `spec` is ready for use, `feature`
66
- * identifies the projected feature dir name.
71
+ * - `ok` — a valid projection was built; `spec` is ready for use.
72
+ * `features` lists the projected feature dir names and
73
+ * `namespaced` is true when ids are feature-scoped (multi-feature
74
+ * projection; single-feature output stays bare-id v1 form).
67
75
  */
68
76
  export type SpeckitResolution = {
69
77
  kind: 'not_speckit';
70
78
  } | {
71
79
  kind: 'empty';
72
- } | {
73
- kind: 'ambiguous';
74
- features: string[];
75
80
  } | {
76
81
  kind: 'unknown_feature';
77
82
  feature: string;
@@ -86,7 +91,14 @@ export type SpeckitResolution = {
86
91
  } | {
87
92
  kind: 'ok';
88
93
  spec: EffectiveSpec;
89
- feature: string;
94
+ features: string[];
95
+ namespaced: boolean;
96
+ /**
97
+ * Rendered requirement ids per feature, in projection order (parallel to
98
+ * `features`). Basis for the check-off ledger's story-index mapping
99
+ * (#2501 Part B: `[US n]` on a task line maps to the n-th requirement).
100
+ */
101
+ featureRequirementIds: string[][];
90
102
  };
91
103
  /**
92
104
  * Detect whether `directory` is a GitHub Spec-Kit project (FR-001, A-001).
@@ -113,10 +125,11 @@ export declare function detectSpeckit(directory: string): SpeckitDetection;
113
125
  * re-running detection:
114
126
  * - `not_speckit` — no `.specify/` marker (A-001).
115
127
  * - `empty` — marker present but no feature dirs (FR-012).
116
- * - `ambiguous` — multiple features, no `options.feature` (FR-008).
117
128
  * - `unknown_feature` — `options.feature` not among detected features.
118
129
  * - `zero_requirements` — feature found but yields zero parsable FRs, or spec.md unreadable
119
- * (FR-013; covers oversized files too).
130
+ * (FR-013; covers oversized *input* files too).
131
+ * - `too_large` — requirements parsed, but the projected output exceeds the byte
132
+ * cap (FR-013; `bytes` is the projected size).
120
133
  * - `ok` — valid EffectiveSpec built (FR-002, FR-003, FR-004, FR-005).
121
134
  *
122
135
  * This function is the single source of truth for feature selection logic.
@@ -126,15 +139,16 @@ export declare function resolveSpeckitProjection(directory: string, options?: {
126
139
  feature?: string;
127
140
  }): SpeckitResolution;
128
141
  /**
129
- * Project a single Spec-Kit feature into an EffectiveSpec (FR-002, FR-003, FR-004, FR-005).
142
+ * Project Spec-Kit feature(s) into an EffectiveSpec (FR-002, FR-003, FR-004, FR-005;
143
+ * #2501 multi-feature).
130
144
  *
131
145
  * Delegates all selection and build logic to {@link resolveSpeckitProjection} — that function
132
146
  * is the single source of truth for feature selection. This wrapper preserves the existing
133
147
  * `EffectiveSpec | null` contract so all call sites (task 2.2, tests) are unchanged.
134
148
  *
135
- * Returns null when resolution is anything other than `ok` (not_speckit, empty, ambiguous,
136
- * unknown_feature, zero_requirements). Callers that need the failure reason should call
137
- * {@link resolveSpeckitProjection} directly.
149
+ * Returns null when resolution is anything other than `ok` (not_speckit, empty,
150
+ * unknown_feature, zero_requirements, too_large). Callers that need the failure reason
151
+ * should call {@link resolveSpeckitProjection} directly.
138
152
  */
139
153
  export declare function buildSpeckitProjectionSync(directory: string, options?: {
140
154
  feature?: string;
@@ -254,10 +268,9 @@ export declare function writeProjectedSpecSync(directory: string, options?: {
254
268
  * - Missing required spec.md sections (`SPECKIT_REQUIRED_SECTIONS`).
255
269
  * - `tasks.md` task lines that carry no `[US#]` user-story reference (FR-007).
256
270
  *
257
- * For other resolution kinds (`not_speckit`, `empty`, `ambiguous`,
258
- * `unknown_feature`, `too_large`) the command layer uses
259
- * {@link formatSpeckitError} on the returned resolution — same messaging path
260
- * as task 2.2 (plan.md task 2.3 requirement: no second messaging scheme).
271
+ * For other resolution kinds (`not_speckit`, `empty`, `unknown_feature`,
272
+ * `too_large`) the command layer uses {@link formatSpeckitError} on the
273
+ * returned resolution — same messaging path as the project command.
261
274
  */
262
275
  export declare function validateSpeckit(directory: string, options?: {
263
276
  feature?: string;
@@ -0,0 +1,113 @@
1
+ export declare const SPECKIT_CHECKOFF_LEDGER_REL: string;
2
+ /** One captured Spec-Kit task line in the ledger. */
3
+ export interface SpeckitCheckoffTaskEntry {
4
+ taskId: string;
5
+ /** Canonical requirement refs (namespaced in multi-feature mode, bare otherwise). */
6
+ frRefs: string[];
7
+ /** Trimmed snapshot of the task line at projection time (staleness + locate basis). */
8
+ lineSnapshot: string;
9
+ initiallyChecked: boolean;
10
+ /** ISO timestamp when Swarm checked this task off (absent until then). */
11
+ swarmCheckedAt?: string;
12
+ }
13
+ /** Per-feature ledger record. */
14
+ export interface SpeckitCheckoffFeatureRecord {
15
+ featureId: string;
16
+ /** Posix path of tasks.md relative to the project root. */
17
+ tasksRelPath: string;
18
+ /** sha256 over the trimmed task lines at projection time (staleness basis). */
19
+ taskLinesDigest: string;
20
+ tasks: SpeckitCheckoffTaskEntry[];
21
+ }
22
+ export interface SpeckitCheckoffLedger {
23
+ version: 1;
24
+ namespaced: boolean;
25
+ projectedAt: string;
26
+ features: SpeckitCheckoffFeatureRecord[];
27
+ }
28
+ /** Per-feature outcome of one propagation run. */
29
+ export interface SpeckitCheckoffFeatureResult {
30
+ featureId: string;
31
+ tasksRelPath: string;
32
+ checked: string[];
33
+ reopenedSkipped: string[];
34
+ stale: boolean;
35
+ refused: string[];
36
+ }
37
+ export interface SpeckitCheckoffResult {
38
+ ran: boolean;
39
+ reason?: string;
40
+ features: SpeckitCheckoffFeatureResult[];
41
+ /** True when the completed task matched no ledger task anywhere (reported, not guessed). */
42
+ unmatched?: boolean;
43
+ }
44
+ declare function sha256(text: string): string;
45
+ declare function readBounded(filePath: string): string | null;
46
+ /** Parse the T### checkbox lines of a tasks.md into task entries (no writes). */
47
+ export declare function parseSpeckitTasksContent(content: string, namespaced: boolean, featureId: string): {
48
+ tasks: SpeckitCheckoffTaskEntry[];
49
+ taskLinesDigest: string;
50
+ };
51
+ /**
52
+ * Build and atomically write the check-off ledger for a successful Spec-Kit
53
+ * projection. Called from `writeProjectedSpecSync` (both write paths); the
54
+ * projection write stays authoritative — a ledger failure is logged, never
55
+ * thrown to the caller.
56
+ *
57
+ * Task→requirement mapping basis (#2501): Spec-Kit task lines reference user
58
+ * STORIES (`[US n]`), not necessarily FR ids. The ledger derives each task's
59
+ * requirement refs from (a) any explicit FR refs on the line, plus (b) the
60
+ * story-index mapping: `[US n]` maps to the feature's n-th requirement in
61
+ * projection order (`featureRequirementIds`, captured at projection time).
62
+ * Out-of-range story indices map to nothing (the task reports unmatched rather
63
+ * than guessing).
64
+ */
65
+ export declare function writeSpeckitCheckoffLedger(root: string, resolution: {
66
+ features: string[];
67
+ namespaced: boolean;
68
+ featureRequirementIds: string[][];
69
+ spec: {
70
+ sourcePaths: string[];
71
+ };
72
+ }): void;
73
+ export interface ApplyCheckoffEditOutcome {
74
+ applied: boolean;
75
+ content: string;
76
+ reason: string;
77
+ }
78
+ export declare function applyCheckoffEdit(taskEntry: SpeckitCheckoffTaskEntry, _baselineContent: string, currentContent: string): ApplyCheckoffEditOutcome;
79
+ /**
80
+ * Propagate one completed plan task's check-off into the source tasks.md files.
81
+ *
82
+ * `completed.frRefs` are the task's requirement refs (plan `fr_refs`); refs are
83
+ * also mined from `completed.text` (descriptions often carry the natural ids).
84
+ * Never throws for expected refusal paths; structural I/O failures throw only
85
+ * from the atomic-write core and are caught by {@link
86
+ * maybePropagateSpeckitCheckoff}.
87
+ */
88
+ export declare function propagateSpeckitCheckoff(directory: string, completed: {
89
+ taskId: string;
90
+ frRefs: string[];
91
+ text: string;
92
+ }, options: {
93
+ enabled: boolean;
94
+ }): Promise<SpeckitCheckoffResult>;
95
+ /**
96
+ * Fail-open wrapper for the plan-manager wiring: loads the plugin config,
97
+ * no-ops unless `speckit_checkoff.enabled`, and never lets a check-off failure
98
+ * propagate into the task-status update (AGENTS.md #5/#9 — bookkeeping is
99
+ * advisory to the durable plan write).
100
+ */
101
+ export declare function maybePropagateSpeckitCheckoff(directory: string, completed: {
102
+ taskId: string;
103
+ frRefs: string[];
104
+ text: string;
105
+ }): Promise<void>;
106
+ /** DI seam for tests/checks (repo convention: restore in afterEach). */
107
+ export declare const _internals: {
108
+ applyCheckoffEdit: typeof applyCheckoffEdit;
109
+ parseSpeckitTasksContent: typeof parseSpeckitTasksContent;
110
+ readBounded: typeof readBounded;
111
+ sha256: typeof sha256;
112
+ };
113
+ export {};
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Project-owned, generation-fenced hydration state (issue #2667).
3
+ *
4
+ * The live maps on `swarmState` are process-resident and keyed by sessionID;
5
+ * hydration is a per-PROJECT operation. This module owns the per-project
6
+ * registries that scope a hydration's blast radius to the project that
7
+ * initiated it and fence stale generations from publishing over newer state:
8
+ *
9
+ * - `projectHydrationGenerations` — monotonic counter per canonical project
10
+ * key, bumped ONLY when a hydration is initiated (`beginHydrationScope`).
11
+ * Session creation NEVER bumps it; new sessions stamp `current + 1` so a
12
+ * session created while generation `g` is latest survives any later apply
13
+ * at `g`.
14
+ * - `rehydrationCaches` — the plan/evidence rehydration cache, keyed per
15
+ * project (replaces the former process-singleton `_rehydrationCache`).
16
+ * - `hydratedAggregateKeys` — the toolAggregates keys each project's last
17
+ * hydration published, so a re-hydration replaces only its own keys.
18
+ *
19
+ * Fence rule: a hydration whose scope generation `g` satisfies
20
+ * `projectHydrationGenerations[K] > g` is REJECTED before any mutation —
21
+ * some newer hydration began for that project. Stamp rule: an accepted
22
+ * hydration at `g` evicts only sessions owned by `K` with
23
+ * `hydrationStamp <= g`.
24
+ *
25
+ * All maps are bounded (FIFO) with an explicit reset path
26
+ * (`clearHydrationOwnershipState`, called by `resetSwarmState`) per
27
+ * AGENTS.md invariant 8.
28
+ */
29
+ /** Upper bound for tracked per-project registries (matches MAX_READY_ROOTS). */
30
+ export declare const MAX_TRACKED_PROJECTS = 32;
31
+ /** Upper bound for the raw-spelling → canonical-key memo. */
32
+ export declare const MAX_DIRECTORY_KEY_MEMO = 64;
33
+ /** Opaque cache payload owned by state.ts; opaque here by design. */
34
+ export type ProjectRehydrationCache = unknown;
35
+ /** Fence token captured when a hydration is initiated; see beginHydrationScope. */
36
+ export interface HydrationScope {
37
+ projectKey: string;
38
+ generation: number;
39
+ }
40
+ /**
41
+ * Resolve the canonical project key for a directory spelling through a
42
+ * module-owned bounded memo: exactly ONE realpath-equivalent resolution per
43
+ * distinct spelling per process; every later call is a pure Map hit.
44
+ *
45
+ * The memo is keyed by `canonicalRootKeyLexical` (the shared filesystem-free
46
+ * lexical alias key, per the path-identity ratchet — raw resolved paths must
47
+ * not key project maps) so distinct spellings memoize independently while
48
+ * lexically-identical spellings share one entry — whose canonical resolution
49
+ * is identical anyway.
50
+ *
51
+ * `canonicalProjectKey` itself is intentionally NOT memoized (it calls
52
+ * `canonicalRootKeyFresh`, bypassing the shared `canonicalRootMemo`), which
53
+ * is why this memo exists — `beginHydrationScope`/`startAgentSession` sit on
54
+ * the plugin-init and chat.message hot paths. A symlink retargeted
55
+ * mid-process yields a second key: fail-safe isolation (separate ownership
56
+ * buckets), never corruption. `canonicalProjectKey` never throws (lexical
57
+ * `path.resolve` fallback on realpath failure) — that fallback is accepted.
58
+ */
59
+ export declare function hydrationProjectKey(directory: string): string;
60
+ /**
61
+ * Begin a hydration scope: bump the project's generation counter and return
62
+ * the fence token. The token must be captured when the hydration is
63
+ * INITIATED (e.g. at `loadSnapshot` entry) and carried into
64
+ * `rehydrateState`, which refuses to apply it once any newer generation has
65
+ * begun.
66
+ */
67
+ export declare function beginHydrationScope(directory: string): HydrationScope;
68
+ /** Latest initiated hydration generation for a project (0 when never). */
69
+ export declare function currentHydrationGeneration(projectKey: string): number;
70
+ /**
71
+ * Stamp value for a session created NOW under `projectKey`:
72
+ * `current + 1`, i.e. newer than any already-initiated hydration, so an
73
+ * in-flight or late apply at the current generation can never evict it.
74
+ */
75
+ export declare function nextSessionHydrationStamp(projectKey: string): number;
76
+ export declare function getRehydrationCache(projectKey: string): ProjectRehydrationCache | undefined;
77
+ export declare function setRehydrationCache(projectKey: string, cache: ProjectRehydrationCache): void;
78
+ /** Record the aggregate keys a project's hydration published (replace set). */
79
+ export declare function recordHydratedAggregateKeys(projectKey: string, keys: Set<string>): void;
80
+ /** The aggregate keys the project's last hydration published (empty if none). */
81
+ export declare function hydratedAggregateKeysFor(projectKey: string): Set<string>;
82
+ /** Reset every registry (invariant 8: bounded state with an explicit reset). */
83
+ export declare function clearHydrationOwnershipState(): void;
@@ -1,4 +1,5 @@
1
1
  /** Post-resolution SQLite snapshot import/readiness lifecycle (#2481). */
2
+ import { type HydrationScope } from './hydration-ownership.js';
2
3
  import type { SnapshotData } from './snapshot-writer.js';
3
4
  type ReadinessState = 'running' | 'succeeded' | 'failed' | 'timed_out' | 'closing';
4
5
  interface ReadinessEntry {
@@ -41,7 +42,7 @@ export declare function closeSnapshotCoordinationInitialization(directory: strin
41
42
  export declare function markSnapshotCoordinationClosing(directory: string): void;
42
43
  export declare const _snapshotCoordinationInternals: {
43
44
  entries: Map<string, ReadinessEntry>;
44
- initialize: (directory: string) => Promise<void>;
45
+ initialize: (directory: string, scope?: HydrationScope) => Promise<void>;
45
46
  renameLegacySnapshot: (from: string, to: string) => void;
46
47
  writeProjection: (directory: string, snapshot: SnapshotData) => Promise<void>;
47
48
  timeoutMs: number;
@@ -3,6 +3,7 @@
3
3
  * Reads .swarm/session/state.json and rehydrates swarmState on plugin init.
4
4
  */
5
5
  import type { AgentSessionState } from '../state';
6
+ import { type HydrationScope } from './hydration-ownership.js';
6
7
  import type { SerializedAgentSession, SnapshotData } from './snapshot-writer';
7
8
  /**
8
9
  * Transient session fields that must be reset on rehydration.
@@ -33,7 +34,19 @@ export declare function readSnapshot(directory: string): Promise<SnapshotData |
33
34
  export declare function readSnapshotFileStrict(directory: string, relativePath: string): Promise<SnapshotData>;
34
35
  /**
35
36
  * Rehydrate swarmState from a SnapshotData object.
36
- * Clears existing maps first, then populates from snapshot.
37
+ *
38
+ * Issue #2667 — project-owned and generation-fenced:
39
+ * - With a `directory`, this replaces ONLY the state owned by that project
40
+ * (sessions whose `owningProjectKey` matches and whose `hydrationStamp` is
41
+ * at or below the applying generation). Other projects' live state — and
42
+ * this project's sessions created after the hydration began — survive.
43
+ * - With an explicit `scope` captured at initiation, the apply is refused
44
+ * outright (zero mutation) once any NEWER hydration has begun for the
45
+ * project, so a late/timed-out callback cannot publish over newer state.
46
+ * - WITHOUT a `directory`, the legacy process-global clear-all semantics are
47
+ * preserved verbatim (direct-test path only; every production caller passes
48
+ * a directory).
49
+ *
37
50
  * Does NOT touch activeToolCalls or pendingEvents (remain at defaults).
38
51
  *
39
52
  * activeAgent and delegationChains are restored only for session IDs that are
@@ -41,16 +54,21 @@ export declare function readSnapshotFileStrict(directory: string, relativePath:
41
54
  * eviction existed can carry far more activeAgent entries than agentSessions
42
55
  * (sessions were evicted but their satellite entries never were); restoring
43
56
  * those wholesale would resurrect the ghosts into memory and re-serialize them
44
- * into every subsequent snapshot forever. Rehydration runs at plugin init,
45
- * before any turn is in flight; a session that resumes afterwards gets its
46
- * entry re-established by chat.message (delegation-tracker), and until then
47
- * tool-path readers fall back to ORCHESTRATOR_NAME — the same treatment a
48
- * fresh process gives an unknown session.
57
+ * into every subsequent snapshot forever.
49
58
  */
50
- export declare function rehydrateState(snapshot: SnapshotData, directory?: string): Promise<void>;
59
+ export interface RehydrateOutcome {
60
+ applied: boolean;
61
+ reason?: 'superseded';
62
+ }
63
+ export declare function rehydrateState(snapshot: SnapshotData, directory?: string, scope?: HydrationScope): Promise<RehydrateOutcome>;
51
64
  /**
52
65
  * Load snapshot from disk and rehydrate swarmState.
53
66
  * Called on plugin init to restore state from previous session.
54
67
  * NEVER throws - swallows any errors silently.
68
+ *
69
+ * Issue #2667: a hydration scope is captured at entry so the eventual
70
+ * rehydrateState apply is generation-fenced — a loadSnapshot whose 5 s init
71
+ * timeout (src/index.ts) abandoned the await is refused once any newer
72
+ * hydration for the same project has begun.
55
73
  */
56
74
  export declare function loadSnapshot(directory: string): Promise<void>;
package/dist/state.d.ts CHANGED
@@ -448,6 +448,30 @@ export interface AgentSessionState {
448
448
  lastProviderRecoveryFingerprint?: string;
449
449
  /** Timestamp when session was rehydrated from snapshot (0 if never rehydrated) */
450
450
  sessionRehydratedAt: number;
451
+ /**
452
+ * Canonical project key that owns this session's live state. Written ONLY
453
+ * by `startAgentSession` (from its `directory` argument) and by
454
+ * `rehydrateState` (from the HYDRATING directory). A hydration for project
455
+ * K evicts only sessions whose `owningProjectKey` is K.
456
+ *
457
+ * DELIBERATELY NOT SNAPSHOTTED: `serializeAgentSession` is field-explicit
458
+ * so this never round-trips. Ownership is defined by which project's
459
+ * plugin instance created/restored the session, never by snapshot bytes —
460
+ * a snapshot is per-project on disk, so the hydrating directory is the
461
+ * only trustworthy attribution source. `undefined` = unowned (created
462
+ * without a directory): such sessions survive every hydration — fail-open
463
+ * toward preservation.
464
+ */
465
+ owningProjectKey?: string;
466
+ /**
467
+ * Hydration generation this session was created/restored AT.
468
+ * `startAgentSession` stamps `currentGeneration + 1` (newer than any
469
+ * in-flight hydration); `rehydrateState` stamps its applying generation.
470
+ * A hydration at generation `g` evicts only owned sessions with
471
+ * `hydrationStamp <= g`, so live sessions created after `g` began always
472
+ * survive. Also never snapshotted.
473
+ */
474
+ hydrationStamp?: number;
451
475
  /** Pattern type to detection count mapping */
452
476
  prmPatternCounts: Map<string, number>;
453
477
  /** Current escalation level (0=none, 1=guidance, 2=strong guidance, 3=hard stop) */
@@ -1357,9 +1381,15 @@ export declare function buildRehydrationCache(directory: string): Promise<void>;
1357
1381
  * Merge rules:
1358
1382
  * - evidence-derived state: only applied if it advances past existing state
1359
1383
  * - plan-only derived state: only applied if it advances past existing state
1360
- * No-op when the cache has not been built yet.
1384
+ * No-op when no cache exists for the session's project.
1385
+ *
1386
+ * Issue #2667: the cache is project-owned. `projectKey` wins when given;
1387
+ * otherwise it resolves from `session.owningProjectKey`. New callers must
1388
+ * ensure ownership is stamped on the session (or pass the key explicitly)
1389
+ * BEFORE calling — a session with no project context intentionally gets no
1390
+ * cache application rather than another project's data.
1361
1391
  */
1362
- export declare function applyRehydrationCache(session: AgentSessionState): void;
1392
+ export declare function applyRehydrationCache(session: AgentSessionState, projectKey?: string): void;
1363
1393
  /**
1364
1394
  * Rehydrates session workflow state from durable swarm files.
1365
1395
  * Builds (or refreshes) the rehydration cache from disk, then applies it
@@ -37,6 +37,17 @@ export declare const TRANSIENT_MODEL_ERROR_PATTERN: RegExp;
37
37
  * tool stdout, so `Disk quota exceeded` shell output cannot false-trigger it.
38
38
  */
39
39
  export declare const QUOTA_ERROR_PATTERN: RegExp;
40
+ /**
41
+ * Issue #2673: deterministic request-SHAPE rejection by a strict provider —
42
+ * the payload itself is invalid for this provider's request contract (the
43
+ * canonical case: a strict single-system provider rejecting a multi-system
44
+ * request). This is NOT transient: retrying the identical payload can never
45
+ * succeed, so it must never match {@link TRANSIENT_MODEL_ERROR_PATTERN} nor
46
+ * enter the generic retry path (AGENTS.md invariant 9: "deterministic
47
+ * provider payload failures are not generic retries"). Kept disjoint from the
48
+ * transient vocabulary by construction and pinned by negative-control tests.
49
+ */
50
+ export declare const REQUEST_SHAPE_REJECTION_PATTERN: RegExp;
40
51
  /**
41
52
  * True when a model-DISPATCH error is a transient provider failure OR a
42
53
  * quota/rate-limit exhaustion — both are retry + model-fallback eligible.
@@ -1759,6 +1759,17 @@
1759
1759
  }
1760
1760
  }
1761
1761
  },
1762
+ "speckit_checkoff": {
1763
+ "description": "Spec-Kit tasks.md check-off round trip (issue #2501) — opt-in, never on by default.",
1764
+ "type": "object",
1765
+ "properties": {
1766
+ "enabled": {
1767
+ "default": false,
1768
+ "description": "Check off mapped Spec-Kit tasks in the source tasks.md when Swarm completes a plan task (issue #2501). Off by default — write-back to user-owned files is opt-in.",
1769
+ "type": "boolean"
1770
+ }
1771
+ }
1772
+ },
1762
1773
  "git": {
1763
1774
  "description": "Git executable resolution override (issue #2236 hardening).",
1764
1775
  "type": "object",
@@ -5083,6 +5094,35 @@
5083
5094
  }
5084
5095
  }
5085
5096
  },
5097
+ "pr_feedback_loop": {
5098
+ "description": "Autonomous PR babysitting settling loop (issue #2502) — triple opt-in with pr_monitor.enabled + pr_monitor.auto_pr_feedback; off by default; publication profile is none-only.",
5099
+ "type": "object",
5100
+ "properties": {
5101
+ "enabled": {
5102
+ "default": false,
5103
+ "type": "boolean"
5104
+ },
5105
+ "max_actions_per_pr": {
5106
+ "default": 3,
5107
+ "type": "integer",
5108
+ "minimum": 1,
5109
+ "maximum": 10
5110
+ },
5111
+ "max_session_actions": {
5112
+ "default": 10,
5113
+ "type": "integer",
5114
+ "minimum": 1,
5115
+ "maximum": 50
5116
+ },
5117
+ "publication": {
5118
+ "default": "none",
5119
+ "type": "string",
5120
+ "enum": [
5121
+ "none"
5122
+ ]
5123
+ }
5124
+ }
5125
+ },
5086
5126
  "pr_monitor": {
5087
5127
  "description": "GitHub PR subscription and polling (FR-001) — disabled by default; opt-in for real-time PR status updates.",
5088
5128
  "type": "object",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.179.1",
3
+ "version": "7.180.1",
4
4
  "description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,72 +0,0 @@
1
- // @bun
2
- import {
3
- createCuratorLLMDelegate
4
- } from "./index-ky262b73.js";
5
- import"./index-hamqvzqn.js";
6
- import"./index-pskba939.js";
7
- import"./index-aqpwm350.js";
8
- import"./index-h4nh6s8b.js";
9
- import"./index-q375xdcw.js";
10
- import"./index-y98fvmb8.js";
11
- import"./index-g6nyk713.js";
12
- import"./index-txdagbh7.js";
13
- import"./index-n1tcj1q7.js";
14
- import"./index-6b295cas.js";
15
- import"./index-dz12bshh.js";
16
- import"./index-vp9pn7sv.js";
17
- import"./index-pfg3jwe9.js";
18
- import"./index-rdec0y3z.js";
19
- import"./index-6r92fw88.js";
20
- import"./index-549wxbe1.js";
21
- import"./index-zsrtt42s.js";
22
- import"./index-y94vwx2q.js";
23
- import"./index-2b0ktpbf.js";
24
- import"./index-3pzwsesm.js";
25
- import"./index-pt7h91zc.js";
26
- import"./index-q7sjgr1y.js";
27
- import"./index-n2wjrgcs.js";
28
- import"./index-zbhvr9st.js";
29
- import"./index-sj29n50e.js";
30
- import"./index-epfjc1c1.js";
31
- import"./index-s4bkey0q.js";
32
- import"./index-2s7dvzff.js";
33
- import"./index-5d224akk.js";
34
- import"./index-0h3cr7pn.js";
35
- import"./index-rtry5xyf.js";
36
- import"./index-ajm7ebyd.js";
37
- import"./index-frcemc0b.js";
38
- import"./index-wrt875kh.js";
39
- import"./index-rb9jmj30.js";
40
- import"./index-b567t0cr.js";
41
- import"./index-h59vsbch.js";
42
- import"./index-cvg402ha.js";
43
- import"./index-a11ztzs5.js";
44
- import"./index-nzekzzs2.js";
45
- import"./index-ry16d01s.js";
46
- import"./index-rdm3px0g.js";
47
- import"./index-yfpswnjt.js";
48
- import"./index-yp25bc9n.js";
49
- import"./index-vzm6zre7.js";
50
- import"./index-ae75rja9.js";
51
- import"./index-34bwqcea.js";
52
- import"./index-f2v90gfc.js";
53
- import"./index-7g4c7s5r.js";
54
- import"./index-qt0793qm.js";
55
- import"./index-ne9zamcs.js";
56
- import"./index-1xnse449.js";
57
- import"./index-c1ggtmpm.js";
58
- import"./index-m1w40kfw.js";
59
- import"./index-zz7gzw57.js";
60
- import"./index-4ddpvd5c.js";
61
- import"./index-9s1xzvnn.js";
62
- import"./index-w872yykk.js";
63
- import"./index-bk5tah7q.js";
64
- import"./index-gknz3bv1.js";
65
- import"./index-zpsr8rpc.js";
66
- import"./index-wvghb3x6.js";
67
- import"./index-9rwhas09.js";
68
- import"./index-zgwm4ryv.js";
69
- import"./index-a76rekgs.js";
70
- export {
71
- createCuratorLLMDelegate
72
- };
@@ -1,73 +0,0 @@
1
- // @bun
2
- import {
3
- handleGuardrailExplain
4
- } from "./index-xy7k7f3k.js";
5
- import"./index-ky262b73.js";
6
- import"./index-hamqvzqn.js";
7
- import"./index-pskba939.js";
8
- import"./index-aqpwm350.js";
9
- import"./index-h4nh6s8b.js";
10
- import"./index-q375xdcw.js";
11
- import"./index-y98fvmb8.js";
12
- import"./index-g6nyk713.js";
13
- import"./index-txdagbh7.js";
14
- import"./index-n1tcj1q7.js";
15
- import"./index-6b295cas.js";
16
- import"./index-dz12bshh.js";
17
- import"./index-vp9pn7sv.js";
18
- import"./index-pfg3jwe9.js";
19
- import"./index-rdec0y3z.js";
20
- import"./index-6r92fw88.js";
21
- import"./index-549wxbe1.js";
22
- import"./index-zsrtt42s.js";
23
- import"./index-y94vwx2q.js";
24
- import"./index-2b0ktpbf.js";
25
- import"./index-3pzwsesm.js";
26
- import"./index-pt7h91zc.js";
27
- import"./index-q7sjgr1y.js";
28
- import"./index-n2wjrgcs.js";
29
- import"./index-zbhvr9st.js";
30
- import"./index-sj29n50e.js";
31
- import"./index-epfjc1c1.js";
32
- import"./index-s4bkey0q.js";
33
- import"./index-2s7dvzff.js";
34
- import"./index-5d224akk.js";
35
- import"./index-0h3cr7pn.js";
36
- import"./index-rtry5xyf.js";
37
- import"./index-ajm7ebyd.js";
38
- import"./index-frcemc0b.js";
39
- import"./index-wrt875kh.js";
40
- import"./index-rb9jmj30.js";
41
- import"./index-b567t0cr.js";
42
- import"./index-h59vsbch.js";
43
- import"./index-cvg402ha.js";
44
- import"./index-a11ztzs5.js";
45
- import"./index-nzekzzs2.js";
46
- import"./index-ry16d01s.js";
47
- import"./index-rdm3px0g.js";
48
- import"./index-yfpswnjt.js";
49
- import"./index-yp25bc9n.js";
50
- import"./index-vzm6zre7.js";
51
- import"./index-ae75rja9.js";
52
- import"./index-34bwqcea.js";
53
- import"./index-f2v90gfc.js";
54
- import"./index-7g4c7s5r.js";
55
- import"./index-qt0793qm.js";
56
- import"./index-ne9zamcs.js";
57
- import"./index-1xnse449.js";
58
- import"./index-c1ggtmpm.js";
59
- import"./index-m1w40kfw.js";
60
- import"./index-zz7gzw57.js";
61
- import"./index-4ddpvd5c.js";
62
- import"./index-9s1xzvnn.js";
63
- import"./index-w872yykk.js";
64
- import"./index-bk5tah7q.js";
65
- import"./index-gknz3bv1.js";
66
- import"./index-zpsr8rpc.js";
67
- import"./index-wvghb3x6.js";
68
- import"./index-9rwhas09.js";
69
- import"./index-zgwm4ryv.js";
70
- import"./index-a76rekgs.js";
71
- export {
72
- handleGuardrailExplain
73
- };