opencode-swarm 7.179.0 → 7.180.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.
Files changed (118) hide show
  1. package/.opencode/skills/execute/SKILL.md +9 -8
  2. package/.opencode/skills/running-tests/SKILL.md +41 -36
  3. package/.opencode/skills/writing-tests/SKILL.md +11 -4
  4. package/binaries/win32-arm64/swarm-sandbox-runner.exe +0 -0
  5. package/binaries/win32-x64/swarm-sandbox-runner.exe +0 -0
  6. package/dist/agents/explorer.d.ts +1 -1
  7. package/dist/background/pr-event-subscribers.d.ts +2 -0
  8. package/dist/background/pr-feedback-event-queue.d.ts +7 -0
  9. package/dist/background/pr-feedback-loop.d.ts +162 -0
  10. package/dist/cli/{coder-settlement-7pt3a0y0.js → coder-settlement-34z9xgnx.js} +13 -13
  11. package/dist/cli/{config-doctor-82w4bp4b.js → config-doctor-tkfrwztz.js} +2 -2
  12. package/dist/cli/{core-9rqzs794.js → core-z9ybzpvr.js} +4 -5
  13. package/dist/cli/{curation-policy-c7mdsf7m.js → curation-policy-gwzmjmt7.js} +6 -5
  14. package/dist/cli/{curator-drift-d93pwt8h.js → curator-drift-3bbn011w.js} +22 -12
  15. package/dist/cli/curator-llm-factory-e162g7xp.js +74 -0
  16. package/dist/cli/{curator-m8act07j.js → curator-zv4qs07j.js} +46 -44
  17. package/dist/cli/{dispatch-3rwdxpp2.js → dispatch-p5zjg5e6.js} +1 -1
  18. package/dist/cli/{evidence-summary-service-a99bgje1.js → evidence-summary-service-wrfth5tr.js} +22 -20
  19. package/dist/cli/{explorer-z0cf5cz0.js → explorer-m50sfrp7.js} +1 -1
  20. package/dist/cli/{gate-evidence-yssmxba5.js → gate-evidence-adqbxnm7.js} +8 -8
  21. package/dist/cli/guardrail-explain-dn96802k.js +75 -0
  22. package/dist/cli/{guardrail-log-j2wtq7p2.js → guardrail-log-rcza6v3y.js} +6 -6
  23. package/dist/cli/{guardrail-reset-07byr7nr.js → guardrail-reset-fjn42e0n.js} +46 -44
  24. package/dist/cli/hive-promoter-hgqqn7qw.js +89 -0
  25. package/dist/cli/{index-7zmbtxw1.js → index-06crt1ej.js} +2 -2
  26. package/dist/cli/{index-wrt875kh.js → index-0725jpp7.js} +1 -1
  27. package/dist/cli/{index-f2v90gfc.js → index-0v1rtanv.js} +24 -165
  28. package/dist/cli/{index-0bc8jdnv.js → index-1hzqyx13.js} +9 -1
  29. package/dist/cli/{index-80q47hpw.js → index-1p8fk9jb.js} +2 -2
  30. package/dist/cli/{index-1rwyfvq2.js → index-2h0qng38.js} +3 -3
  31. package/dist/cli/{index-amf88k1e.js → index-3jap3516.js} +1 -1
  32. package/dist/cli/{index-8815e95e.js → index-5gmn0a3j.js} +8 -8
  33. package/dist/cli/{index-yagqxt2p.js → index-5m378633.js} +4 -4
  34. package/dist/cli/{index-0h3cr7pn.js → index-5yc5n4ae.js} +1 -1
  35. package/dist/cli/{index-pxtye2ng.js → index-7pj0x345.js} +50 -48
  36. package/dist/cli/{index-etmwjgre.js → index-7w6dnpvc.js} +46 -44
  37. package/dist/cli/{index-6tnkvqr9.js → index-8b1f2t5q.js} +8 -10
  38. package/dist/cli/{index-cvg402ha.js → index-91dhg3wr.js} +2 -2
  39. package/dist/cli/{index-3pzwsesm.js → index-92m05mew.js} +2 -2
  40. package/dist/cli/{index-6r92fw88.js → index-93vk5s7v.js} +8 -8
  41. package/dist/cli/{index-ne9zamcs.js → index-989v83pb.js} +1 -1
  42. package/dist/cli/{index-g6nyk713.js → index-aspxz5r5.js} +1 -1
  43. package/dist/cli/index-b9z9gvx0.js +339 -0
  44. package/dist/cli/{index-2b0ktpbf.js → index-bdpgfep1.js} +5 -5
  45. package/dist/cli/{index-nzekzzs2.js → index-bv4b8tpa.js} +5 -5
  46. package/dist/cli/{index-n1tcj1q7.js → index-bx70zs8d.js} +187 -47
  47. package/dist/cli/{index-kmhnkn6t.js → index-caj76d0f.js} +6 -8
  48. package/dist/cli/{index-549wxbe1.js → index-cjapb4hy.js} +1 -1
  49. package/dist/cli/{index-3hne91yd.js → index-cxgr6ad5.js} +13 -15
  50. package/dist/cli/{index-kanxpgf8.js → index-dcttq1mn.js} +2 -2
  51. package/dist/cli/{index-twtez316.js → index-defq2crz.js} +13 -3
  52. package/dist/cli/{index-d66zb40k.js → index-dnbqmay5.js} +3054 -1454
  53. package/dist/cli/index-ejhxgyvm.js +147 -0
  54. package/dist/cli/{index-hwcra3y9.js → index-ekgc71m1.js} +10 -10
  55. package/dist/cli/{index-s4bkey0q.js → index-gc6h1fmf.js} +4 -4
  56. package/dist/cli/index-gx2vp8gx.js +100 -0
  57. package/dist/cli/{index-zgvzbz48.js → index-hamqvzqn.js} +69 -13
  58. package/dist/cli/{index-h59vsbch.js → index-htrb9ec3.js} +1 -1
  59. package/dist/cli/{index-yfpswnjt.js → index-jmrsfhwq.js} +3 -3
  60. package/dist/cli/{index-9p1pqykb.js → index-jrfv2am8.js} +7 -7
  61. package/dist/cli/{index-pskba939.js → index-jscqefqm.js} +1 -1
  62. package/dist/cli/{index-wvpsm8ja.js → index-kp654qcw.js} +32 -17
  63. package/dist/cli/{index-tmy46dtd.js → index-mhrn7hbb.js} +8 -7
  64. package/dist/cli/{index-h4nh6s8b.js → index-nhxykfyy.js} +1 -1
  65. package/dist/cli/{index-ndwbb3xm.js → index-pnt98k7z.js} +7 -7
  66. package/dist/cli/{index-1c1dbwze.js → index-rdec0y3z.js} +1 -1
  67. package/dist/cli/{index-qxk5qkfh.js → index-ret97f1t.js} +5 -5
  68. package/dist/cli/{index-sv4y1cma.js → index-v1sc1gxv.js} +6 -6
  69. package/dist/cli/{index-a11ztzs5.js → index-vmthakz0.js} +1 -1
  70. package/dist/cli/{index-09wm3963.js → index-x6kjbjya.js} +9 -7
  71. package/dist/cli/{index-1sz02k85.js → index-zptq8mp1.js} +4 -103
  72. package/dist/cli/{index-34bwqcea.js → index-zvxy0mev.js} +1 -1
  73. package/dist/cli/{index-zz7gzw57.js → index-zxdawwc7.js} +88 -4
  74. package/dist/cli/index.js +47 -45
  75. package/dist/cli/{knowledge-escalator-yx97q9c1.js → knowledge-escalator-x8vcmb6k.js} +16 -15
  76. package/dist/cli/{knowledge-events-p269fyvv.js → knowledge-events-naf9kyyc.js} +14 -13
  77. package/dist/cli/{knowledge-link-gfz47ves.js → knowledge-link-g0q25hqv.js} +5 -4
  78. package/dist/cli/{knowledge-store-36zemyqa.js → knowledge-store-dnv0ph42.js} +6 -5
  79. package/dist/cli/{knowledge-validator-rd20yq41.js → knowledge-validator-a1rfzkmv.js} +8 -7
  80. package/dist/cli/{mcp-sg9zrkz2.js → mcp-hnb0m05a.js} +1 -1
  81. package/dist/cli/{pending-delegations-8p2gf4kt.js → pending-delegations-05p6cmbh.js} +13 -12
  82. package/dist/cli/{pr-subscriptions-4dj9r71h.js → pr-subscriptions-a2djfzyx.js} +13 -12
  83. package/dist/cli/{pr-workflow-gate-8dgz5z1h.js → pr-workflow-gate-wkmx8nr6.js} +48 -44
  84. package/dist/cli/{runner-16b691ba.js → runner-hkbds12j.js} +6 -5
  85. package/dist/cli/{scan-cursor-nx0jv9ya.js → scan-cursor-4khfn5pm.js} +8 -8
  86. package/dist/cli/{schema-q6gsrxwz.js → schema-a5zb02h8.js} +3 -1
  87. package/dist/cli/{scope-persistence-1k4xsyh7.js → scope-persistence-nsw324ce.js} +18 -17
  88. package/dist/cli/{server-shhxq34t.js → server-exj4wt8j.js} +54 -52
  89. package/dist/cli/{skill-generator-6j7tq2tb.js → skill-generator-r2cdtx7b.js} +18 -17
  90. package/dist/cli/{snapshot-coordination-init-h8n8w1cm.js → snapshot-coordination-init-sad6q0a2.js} +46 -44
  91. package/dist/cli/speckit-checkoff-46g9sqak.js +31 -0
  92. package/dist/cli/{workspace-snapshot-rfnn80dg.js → workspace-snapshot-4m2ex1ey.js} +4 -5
  93. package/dist/cli/{worktree-collision-ownership-97jzh4ra.js → worktree-collision-ownership-4znkfq1t.js} +16 -16
  94. package/dist/cli/{worktree-isolation-g4w74ccb.js → worktree-isolation-mv9ee00v.js} +46 -44
  95. package/dist/commands/pr-feedback-loop.d.ts +1 -0
  96. package/dist/commands/registry.d.ts +10 -2
  97. package/dist/config/schema.d.ts +27 -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/index.js +639 -606
  101. package/dist/lang/backends/go.d.ts +2 -0
  102. package/dist/mutation/engine.d.ts +1 -0
  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/test-impact/analyzer.d.ts +46 -4
  110. package/dist/test-impact/constants.d.ts +4 -0
  111. package/dist/tools/mutation-test.d.ts +11 -5
  112. package/dist/tools/test-runner.d.ts +34 -6
  113. package/opencode-swarm.schema.json +40 -0
  114. package/package.json +1 -1
  115. package/dist/cli/curator-llm-factory-cbm1ny30.js +0 -72
  116. package/dist/cli/guardrail-explain-ffwmhf7s.js +0 -73
  117. package/dist/cli/hive-promoter-ewrz7vh1.js +0 -87
  118. package/dist/cli/index-4ddpvd5c.js +0 -94
@@ -0,0 +1,339 @@
1
+ // @bun
2
+ import {
3
+ tryAcquireLock
4
+ } from "./index-ejhxgyvm.js";
5
+ import {
6
+ atomicWriteFileAnyRoot,
7
+ atomicWriteSwarmFileSync
8
+ } from "./index-989v83pb.js";
9
+ import {
10
+ init_loader,
11
+ loadPluginConfig
12
+ } from "./index-zptq8mp1.js";
13
+ import {
14
+ init_logger,
15
+ log,
16
+ warn
17
+ } from "./index-zgwm4ryv.js";
18
+
19
+ // src/sdd/speckit-checkoff.ts
20
+ init_loader();
21
+ import { createHash } from "crypto";
22
+ import * as fs from "fs";
23
+ import * as path from "path";
24
+ init_logger();
25
+ var SPECKIT_CHECKOFF_LEDGER_REL = path.join(".swarm", "speckit-checkoff-ledger.json");
26
+ var TASK_LINE_REGEX = /^\s*-\s+\[[ xX]\]\s+(T\d+)/;
27
+ var FR_REF_REGEX = /(?:[A-Za-z0-9][A-Za-z0-9._-]*\/)?FR-\d{3}/g;
28
+ var MAX_TASKS_FILE_BYTES = 512 * 1024;
29
+ var FR_BARE_SUFFIX = /FR-\d{3}$/;
30
+ function refsMatch(a, b) {
31
+ if (a === b)
32
+ return true;
33
+ const aBare = !a.includes("/");
34
+ const bBare = !b.includes("/");
35
+ if (aBare && !bBare && FR_BARE_SUFFIX.test(b) && b.endsWith(`/${a}`))
36
+ return true;
37
+ if (bBare && !aBare && FR_BARE_SUFFIX.test(a) && a.endsWith(`/${b}`))
38
+ return true;
39
+ return false;
40
+ }
41
+ function sha256(text) {
42
+ return createHash("sha256").update(text, "utf-8").digest("hex");
43
+ }
44
+ function readBounded(filePath) {
45
+ try {
46
+ const stat = fs.lstatSync(filePath);
47
+ if (!stat.isFile() || stat.size > MAX_TASKS_FILE_BYTES)
48
+ return null;
49
+ return fs.readFileSync(filePath, "utf-8");
50
+ } catch {
51
+ return null;
52
+ }
53
+ }
54
+ function parseSpeckitTasksContent(content, namespaced, featureId) {
55
+ const tasks = [];
56
+ const taskLines = [];
57
+ for (const rawLine of content.replace(/\r\n/g, `
58
+ `).split(`
59
+ `)) {
60
+ const match = rawLine.match(TASK_LINE_REGEX);
61
+ if (!match)
62
+ continue;
63
+ const snapshot = rawLine.trim();
64
+ taskLines.push(snapshot.replace(/\[[xX]\]/g, "[ ]"));
65
+ const refs = [...snapshot.matchAll(FR_REF_REGEX)].map((m) => m[0]);
66
+ const frRefs = refs.map((ref) => namespaced && !ref.includes("/") ? `${featureId}/${ref}` : ref);
67
+ tasks.push({
68
+ taskId: match[1],
69
+ frRefs,
70
+ lineSnapshot: snapshot,
71
+ initiallyChecked: /\[x\]/i.test(snapshot)
72
+ });
73
+ }
74
+ return { tasks, taskLinesDigest: sha256(taskLines.join(`
75
+ `)) };
76
+ }
77
+ function writeSpeckitCheckoffLedger(root, resolution) {
78
+ const features = [];
79
+ resolution.features.forEach((featureId, index) => {
80
+ const specRel = resolution.spec.sourcePaths[index] ?? `specs/${featureId}/spec.md`;
81
+ const tasksRelPath = `${path.dirname(specRel).split(path.sep).join("/")}/tasks.md`;
82
+ const content = readBounded(path.join(root, tasksRelPath));
83
+ if (content === null)
84
+ return;
85
+ const parsed = parseSpeckitTasksContent(content, resolution.namespaced, featureId);
86
+ if (parsed.tasks.length === 0)
87
+ return;
88
+ const requirementIds = resolution.featureRequirementIds[index] ?? [];
89
+ for (const task of parsed.tasks) {
90
+ const refs = new Set(task.frRefs);
91
+ for (const storyMatch of task.lineSnapshot.matchAll(/\[US(\d+)\]/gi)) {
92
+ const storyIndex = Number(storyMatch[1]) - 1;
93
+ const mapped = requirementIds[storyIndex];
94
+ if (mapped)
95
+ refs.add(mapped);
96
+ }
97
+ task.frRefs = [...refs];
98
+ }
99
+ features.push({
100
+ featureId,
101
+ tasksRelPath,
102
+ taskLinesDigest: parsed.taskLinesDigest,
103
+ tasks: parsed.tasks
104
+ });
105
+ });
106
+ const ledger = {
107
+ version: 1,
108
+ namespaced: resolution.namespaced,
109
+ projectedAt: new Date().toISOString(),
110
+ features
111
+ };
112
+ atomicWriteSwarmFileSync(path.join(root, SPECKIT_CHECKOFF_LEDGER_REL), `${JSON.stringify(ledger, null, 2)}
113
+ `);
114
+ }
115
+ function readLedger(root) {
116
+ const raw = readBounded(path.join(root, SPECKIT_CHECKOFF_LEDGER_REL));
117
+ if (raw === null)
118
+ return null;
119
+ try {
120
+ const parsed = JSON.parse(raw);
121
+ if (parsed?.version !== 1 || !Array.isArray(parsed.features))
122
+ return null;
123
+ return parsed;
124
+ } catch {
125
+ return null;
126
+ }
127
+ }
128
+ function writeLedger(root, ledger) {
129
+ atomicWriteSwarmFileSync(path.join(root, SPECKIT_CHECKOFF_LEDGER_REL), `${JSON.stringify(ledger, null, 2)}
130
+ `);
131
+ }
132
+ function normalizeCheckboxState(line) {
133
+ return line.replace(/\[[xX]\]/g, "[ ]");
134
+ }
135
+ function applyCheckoffEdit(taskEntry, _baselineContent, currentContent) {
136
+ const lines = currentContent.split(/(?=\r?\n)/);
137
+ for (let i = 0;i < lines.length; i++) {
138
+ const line = lines[i];
139
+ const lineTrimmed = line.trim();
140
+ if (normalizeCheckboxState(lineTrimmed) !== normalizeCheckboxState(taskEntry.lineSnapshot)) {
141
+ const idMatch = line.match(TASK_LINE_REGEX);
142
+ if (idMatch && idMatch[1] === taskEntry.taskId) {
143
+ return {
144
+ applied: false,
145
+ content: currentContent,
146
+ reason: "task-line-changed"
147
+ };
148
+ }
149
+ continue;
150
+ }
151
+ if (/\[x\]/i.test(lineTrimmed)) {
152
+ return {
153
+ applied: false,
154
+ content: currentContent,
155
+ reason: "already-checked"
156
+ };
157
+ }
158
+ const boxIndex = line.indexOf("[ ]");
159
+ if (boxIndex === -1) {
160
+ return {
161
+ applied: false,
162
+ content: currentContent,
163
+ reason: "task-line-changed"
164
+ };
165
+ }
166
+ lines[i] = `${line.slice(0, boxIndex)}[x]${line.slice(boxIndex + 3)}`;
167
+ return { applied: true, content: lines.join(""), reason: "ok" };
168
+ }
169
+ return {
170
+ applied: false,
171
+ content: currentContent,
172
+ reason: "task-line-not-found"
173
+ };
174
+ }
175
+ function extractFrRefsFromText(text) {
176
+ return [...text.matchAll(FR_REF_REGEX)].map((m) => m[0]);
177
+ }
178
+ async function propagateSpeckitCheckoff(directory, completed, options) {
179
+ if (!options.enabled) {
180
+ return { ran: false, reason: "disabled", features: [] };
181
+ }
182
+ const root = path.resolve(directory);
183
+ const ledger = readLedger(root);
184
+ if (!ledger) {
185
+ return { ran: false, reason: "no-ledger", features: [] };
186
+ }
187
+ const completedRefs = [
188
+ ...completed.frRefs,
189
+ ...extractFrRefsFromText(`${completed.text ?? ""}`)
190
+ ];
191
+ const results = [];
192
+ let anyMatch = false;
193
+ let ledgerDirty = false;
194
+ const checkedAt = new Date().toISOString();
195
+ for (const feature of ledger.features) {
196
+ const result = {
197
+ featureId: feature.featureId,
198
+ tasksRelPath: feature.tasksRelPath,
199
+ checked: [],
200
+ reopenedSkipped: [],
201
+ stale: false,
202
+ refused: []
203
+ };
204
+ const matchedTasks = feature.tasks.filter((task) => task.frRefs.some((taskRef) => completedRefs.some((completedRef) => refsMatch(completedRef, taskRef))));
205
+ const hasSwarmChecked = feature.tasks.some((t) => t.swarmCheckedAt);
206
+ if (matchedTasks.length === 0 && !hasSwarmChecked) {
207
+ results.push(result);
208
+ continue;
209
+ }
210
+ if (matchedTasks.length > 0)
211
+ anyMatch = true;
212
+ const tasksAbs = path.join(root, feature.tasksRelPath);
213
+ let current = readBounded(tasksAbs);
214
+ if (current === null) {
215
+ result.stale = true;
216
+ result.refused.push(...matchedTasks.map((t) => t.taskId));
217
+ results.push(result);
218
+ continue;
219
+ }
220
+ const currentDigest = parseSpeckitTasksContent(current, ledger.namespaced, feature.featureId).taskLinesDigest;
221
+ if (currentDigest !== feature.taskLinesDigest) {
222
+ result.stale = true;
223
+ result.refused.push(...matchedTasks.map((t) => t.taskId));
224
+ results.push(result);
225
+ continue;
226
+ }
227
+ for (const task of feature.tasks) {
228
+ if (!task.swarmCheckedAt)
229
+ continue;
230
+ const line = current.replace(/\r\n/g, `
231
+ `).split(`
232
+ `).find((l) => normalizeCheckboxState(l.trim()) === normalizeCheckboxState(task.lineSnapshot));
233
+ if (line !== undefined && /\[ \]/.test(line)) {
234
+ result.reopenedSkipped.push(task.taskId);
235
+ }
236
+ }
237
+ let contentChanged = false;
238
+ for (const task of matchedTasks) {
239
+ if (task.swarmCheckedAt && result.reopenedSkipped.includes(task.taskId)) {
240
+ continue;
241
+ }
242
+ const outcome = applyCheckoffEdit(task, current, current);
243
+ if (outcome.applied) {
244
+ current = outcome.content;
245
+ contentChanged = true;
246
+ task.swarmCheckedAt = checkedAt;
247
+ ledgerDirty = true;
248
+ result.checked.push(task.taskId);
249
+ } else if (outcome.reason === "already-checked") {
250
+ if (!task.swarmCheckedAt) {
251
+ task.swarmCheckedAt = checkedAt;
252
+ ledgerDirty = true;
253
+ }
254
+ } else {
255
+ result.refused.push(task.taskId);
256
+ }
257
+ }
258
+ if (contentChanged && current !== null) {
259
+ const lock = await tryAcquireLock(root, feature.tasksRelPath, "speckit-checkoff", completed.taskId);
260
+ if (!lock.acquired) {
261
+ result.refused.push(...result.checked);
262
+ result.checked = [];
263
+ results.push(result);
264
+ continue;
265
+ }
266
+ try {
267
+ const latest = readBounded(tasksAbs);
268
+ if (latest === null || latest !== current) {
269
+ if (latest !== null) {
270
+ let reconciled = latest;
271
+ let ok = true;
272
+ for (const taskId of [...result.checked]) {
273
+ const task = feature.tasks.find((t) => t.taskId === taskId);
274
+ const outcome = applyCheckoffEdit(task, latest, reconciled);
275
+ if (outcome.applied) {
276
+ reconciled = outcome.content;
277
+ } else if (outcome.reason !== "already-checked") {
278
+ ok = false;
279
+ result.checked = result.checked.filter((id) => id !== taskId);
280
+ result.refused.push(taskId);
281
+ }
282
+ }
283
+ if (ok && result.checked.length > 0) {
284
+ await atomicWriteFileAnyRoot(tasksAbs, reconciled);
285
+ current = reconciled;
286
+ } else {
287
+ current = latest;
288
+ }
289
+ } else {
290
+ result.refused.push(...result.checked);
291
+ result.checked = [];
292
+ }
293
+ } else {
294
+ await atomicWriteFileAnyRoot(tasksAbs, current);
295
+ }
296
+ } finally {
297
+ if (lock.lock._release) {
298
+ await lock.lock._release().catch(() => {});
299
+ }
300
+ }
301
+ }
302
+ results.push(result);
303
+ }
304
+ if (ledgerDirty) {
305
+ try {
306
+ writeLedger(root, ledger);
307
+ } catch (err) {
308
+ warn(`[speckit-checkoff] ledger update failed after check-off: ${err instanceof Error ? err.message : String(err)}`);
309
+ }
310
+ }
311
+ return {
312
+ ran: true,
313
+ features: results,
314
+ unmatched: !anyMatch || undefined
315
+ };
316
+ }
317
+ async function maybePropagateSpeckitCheckoff(directory, completed) {
318
+ try {
319
+ const config = loadPluginConfig(directory);
320
+ if (config?.speckit_checkoff?.enabled !== true)
321
+ return;
322
+ const result = await propagateSpeckitCheckoff(directory, completed, {
323
+ enabled: true
324
+ });
325
+ if (result.ran && result.features.some((f) => f.checked.length > 0)) {
326
+ log(`[speckit-checkoff] task ${completed.taskId} checked off: ${result.features.map((f) => `${f.featureId}:[${f.checked.join(", ")}]`).join(" ")}`);
327
+ }
328
+ } catch (err) {
329
+ warn(`[speckit-checkoff] propagation for ${completed.taskId} failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
330
+ }
331
+ }
332
+ var _internals = {
333
+ applyCheckoffEdit,
334
+ parseSpeckitTasksContent,
335
+ readBounded,
336
+ sha256
337
+ };
338
+
339
+ export { SPECKIT_CHECKOFF_LEDGER_REL, parseSpeckitTasksContent, writeSpeckitCheckoffLedger, applyCheckoffEdit, propagateSpeckitCheckoff, maybePropagateSpeckitCheckoff, _internals };
@@ -1,21 +1,21 @@
1
1
  // @bun
2
2
  import {
3
3
  validateSwarmPath
4
- } from "./index-s4bkey0q.js";
4
+ } from "./index-gc6h1fmf.js";
5
5
  import {
6
6
  bunSpawn
7
7
  } from "./index-2s7dvzff.js";
8
- import {
9
- atomicWriteSwarmFile
10
- } from "./index-ne9zamcs.js";
11
8
  import {
12
9
  canonicalRootKey,
13
10
  sameProjectRoot
14
11
  } from "./index-1xnse449.js";
12
+ import {
13
+ atomicWriteSwarmFile
14
+ } from "./index-989v83pb.js";
15
15
  import {
16
16
  init_git_executable,
17
17
  resolveGitExecutable
18
- } from "./index-zz7gzw57.js";
18
+ } from "./index-zxdawwc7.js";
19
19
 
20
20
  // src/background/workspace-snapshot.ts
21
21
  import * as child_process from "child_process";
@@ -1,17 +1,17 @@
1
1
  // @bun
2
- import {
3
- canonicalExistingFilesystemPath
4
- } from "./index-ry16d01s.js";
5
2
  import {
6
3
  loadDatabaseCtor
7
4
  } from "./index-rdm3px0g.js";
8
5
  import {
9
- atomicWriteSwarmFileSync
10
- } from "./index-ne9zamcs.js";
6
+ canonicalExistingFilesystemPath
7
+ } from "./index-ry16d01s.js";
11
8
  import {
12
9
  canonicalRootKeyFresh,
13
10
  lexicalRootAliasKey
14
11
  } from "./index-1xnse449.js";
12
+ import {
13
+ atomicWriteSwarmFileSync
14
+ } from "./index-989v83pb.js";
15
15
 
16
16
  // src/db/project-db.ts
17
17
  import { existsSync, mkdirSync, unlinkSync } from "fs";