opencode-swarm 7.124.0 → 7.125.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 (70) hide show
  1. package/.opencode/skills/critic-gate/SKILL.md +8 -0
  2. package/.opencode/skills/swarm/SKILL.md +12 -8
  3. package/.opencode/skills/swarm-pr-feedback/SKILL.md +245 -171
  4. package/.opencode/skills/swarm-pr-feedback/references/bot-claim-verification.md +71 -0
  5. package/.opencode/skills/swarm-pr-feedback/references/operational-gotchas.md +49 -0
  6. package/.opencode/skills/swarm-pr-review/SKILL.md +238 -412
  7. package/.opencode/skills/swarm-pr-review/references/parser-dry-run.md +235 -0
  8. package/.opencode/skills/swarm-pr-review/references/prompt-templates.md +103 -0
  9. package/.opencode/skills/writing-tests/SKILL.md +4 -123
  10. package/.opencode/skills/writing-tests/references/mock-and-seam-inventory.md +43 -0
  11. package/README.md +3 -1
  12. package/dist/background/lane-output-store.d.ts +10 -0
  13. package/dist/background/pending-delegations.d.ts +3 -0
  14. package/dist/background/workspace-snapshot.d.ts +59 -0
  15. package/dist/cli/{config-doctor-53mnpeke.js → config-doctor-g3m2q646.js} +2 -2
  16. package/dist/cli/{curation-policy-ny033330.js → curation-policy-vgbx8530.js} +2 -2
  17. package/dist/cli/{curator-llm-factory-e0tjz8qq.js → curator-llm-factory-7pvqy94w.js} +15 -14
  18. package/dist/cli/{curator-nvn1pdq6.js → curator-xk4g1nx2.js} +15 -14
  19. package/dist/cli/{evidence-summary-service-9hq7n9k9.js → evidence-summary-service-v4h2w487.js} +1 -1
  20. package/dist/cli/{guardrail-explain-d3dd57nf.js → guardrail-explain-wfk16bpr.js} +16 -15
  21. package/dist/cli/{guardrail-log-3q2z9axs.js → guardrail-log-5zz9xx6z.js} +3 -3
  22. package/dist/cli/{hive-promoter-9gbpepgm.js → hive-promoter-njwc5rt0.js} +15 -14
  23. package/dist/cli/{pending-delegations-e3bcqj77.js → index-0cz1ws47.js} +4 -18
  24. package/dist/cli/{index-3yyr4ynk.js → index-3k8pg467.js} +1 -1
  25. package/dist/cli/{index-x2mmnrnx.js → index-83rwq7pb.js} +1 -1
  26. package/dist/cli/{index-c6crt5rs.js → index-8yvqkbw7.js} +12 -2
  27. package/dist/cli/{index-z0m4angq.js → index-93cq8t5b.js} +5 -5
  28. package/dist/cli/{index-8pz0ypxz.js → index-cz6fv84h.js} +17 -16
  29. package/dist/cli/{index-mkkx1a4f.js → index-dsf1yv4s.js} +1588 -891
  30. package/dist/cli/{index-4rzzzjtg.js → index-fs02c7tz.js} +277 -16
  31. package/dist/cli/{index-zjedv2bd.js → index-ghteqdy1.js} +2 -2
  32. package/dist/cli/{index-13d2g7k9.js → index-kvrk3h8p.js} +1 -1
  33. package/dist/cli/{index-eeg04r0x.js → index-kws8zn6y.js} +1 -1
  34. package/dist/cli/index-mg54y5gc.js +564 -0
  35. package/dist/cli/{index-qd77aft9.js → index-mhhmecsw.js} +2 -2
  36. package/dist/cli/{index-2x4maxte.js → index-mwdcvh0e.js} +4 -4
  37. package/dist/cli/{index-e19mxn9f.js → index-pbjenws7.js} +1 -1
  38. package/dist/cli/{index-wqwpzhv1.js → index-rpg8qqjs.js} +2 -2
  39. package/dist/cli/{index-tyg0zezw.js → index-tn3shyqj.js} +3 -3
  40. package/dist/cli/{index-htbjqftb.js → index-txragda9.js} +1 -1
  41. package/dist/cli/{index-v5ecczts.js → index-z4sc6yxc.js} +1 -1
  42. package/dist/cli/index.js +15 -14
  43. package/dist/cli/{knowledge-escalator-r1s01m3z.js → knowledge-escalator-jtyykzqc.js} +3 -3
  44. package/dist/cli/{knowledge-events-a9hmxvke.js → knowledge-events-qhr97sy9.js} +1 -1
  45. package/dist/cli/{knowledge-store-jt31br5k.js → knowledge-store-332x3pjv.js} +1 -1
  46. package/dist/cli/{knowledge-validator-9vrwxr3z.js → knowledge-validator-3t8tgzsz.js} +4 -4
  47. package/dist/cli/pending-delegations-7j8xqg5f.js +34 -0
  48. package/dist/cli/{scan-cursor-bkjtsawg.js → scan-cursor-q21c9k9q.js} +2 -2
  49. package/dist/cli/{schema-y3z416z7.js → schema-y2d7j2jk.js} +1 -1
  50. package/dist/cli/{skill-generator-794hyndw.js → skill-generator-3gkxx98d.js} +5 -5
  51. package/dist/cli/workspace-snapshot-c9pxxt9a.js +48 -0
  52. package/dist/commands/close.d.ts +4 -2
  53. package/dist/commands/registry.d.ts +1 -1
  54. package/dist/config/schema.d.ts +4 -0
  55. package/dist/evidence/documents-retention.d.ts +116 -0
  56. package/dist/evidence/manager.d.ts +17 -0
  57. package/dist/hooks/pr-workflow-gate.d.ts +211 -0
  58. package/dist/hooks/pr-workflow-response-gate.d.ts +23 -0
  59. package/dist/hooks/pr-workflow-session-resolver.d.ts +14 -0
  60. package/dist/index.js +563 -523
  61. package/dist/tools/complete-pr-workflow.d.ts +5 -0
  62. package/dist/tools/dispatch-lanes.d.ts +44 -0
  63. package/dist/tools/index.d.ts +2 -0
  64. package/dist/tools/manifest.d.ts +2 -0
  65. package/dist/tools/run-pr-feedback-stage-a.d.ts +69 -0
  66. package/dist/tools/tool-metadata.d.ts +8 -0
  67. package/dist/tools/write-pr-review-trigger-eval.d.ts +56 -46
  68. package/package.json +1 -1
  69. package/dist/cli/index-dqh3zhhc.js +0 -133
  70. package/dist/cli/workspace-snapshot-eyf6gd0d.js +0 -22
@@ -0,0 +1,564 @@
1
+ // @bun
2
+ // src/background/workspace-snapshot.ts
3
+ import * as child_process from "child_process";
4
+ import { createHash } from "crypto";
5
+ import * as fs from "fs";
6
+ import * as path from "path";
7
+ var GIT_SNAPSHOT_TIMEOUT_MS = 3000;
8
+ var GIT_SNAPSHOT_MAX_BUFFER = 512 * 1024;
9
+ var REVISION_MAX_FILES = 5000;
10
+ var REVISION_MAX_TOTAL_BYTES = 64 * 1024 * 1024;
11
+ var REVISION_READ_CHUNK_BYTES = 64 * 1024;
12
+ var REVISION_YIELD_EVERY_CHUNKS = 16;
13
+ function runGit(directory, args, timeoutMs = GIT_SNAPSHOT_TIMEOUT_MS) {
14
+ const result = _internals.spawnSync("git", ["-C", directory, ...args], {
15
+ cwd: directory,
16
+ encoding: "utf-8",
17
+ timeout: timeoutMs,
18
+ maxBuffer: GIT_SNAPSHOT_MAX_BUFFER,
19
+ stdio: ["ignore", "pipe", "pipe"]
20
+ });
21
+ if (result.error || result.status !== 0)
22
+ return null;
23
+ return typeof result.stdout === "string" ? result.stdout.trimEnd() : null;
24
+ }
25
+ async function runGitAsync(directory, args, timeoutMs = GIT_SNAPSHOT_TIMEOUT_MS) {
26
+ return await new Promise((resolve2) => {
27
+ let settled = false;
28
+ let stdout = "";
29
+ let stderrBytes = 0;
30
+ let timeout;
31
+ let child;
32
+ const finish = (value) => {
33
+ if (settled)
34
+ return;
35
+ settled = true;
36
+ if (timeout)
37
+ clearTimeout(timeout);
38
+ try {
39
+ child?.kill();
40
+ } catch {}
41
+ resolve2(value);
42
+ };
43
+ try {
44
+ child = child_process.spawn("git", ["-C", directory, ...args], {
45
+ cwd: directory,
46
+ stdio: ["ignore", "pipe", "pipe"],
47
+ windowsHide: true
48
+ });
49
+ } catch {
50
+ finish(null);
51
+ return;
52
+ }
53
+ timeout = setTimeout(() => finish(null), timeoutMs);
54
+ child.stdout?.setEncoding("utf-8");
55
+ child.stdout?.on("data", (chunk) => {
56
+ stdout += chunk;
57
+ if (Buffer.byteLength(stdout, "utf-8") > GIT_SNAPSHOT_MAX_BUFFER) {
58
+ finish(null);
59
+ }
60
+ });
61
+ child.stderr?.on("data", (chunk) => {
62
+ stderrBytes += chunk.length;
63
+ if (stderrBytes > GIT_SNAPSHOT_MAX_BUFFER) {
64
+ finish(null);
65
+ }
66
+ });
67
+ child.once("error", () => finish(null));
68
+ child.once("close", (code) => finish(code === 0 ? stdout.trimEnd() : null));
69
+ });
70
+ }
71
+ function readGitTextAtRevision(directory, revision, relativePath) {
72
+ if (!isSafeGitRevisionToken(revision) || !/^\.?(?:[A-Za-z0-9][A-Za-z0-9._-]*\/)*[A-Za-z0-9][A-Za-z0-9._-]*$/.test(relativePath) || relativePath.split("/").includes("..")) {
73
+ return null;
74
+ }
75
+ const result = _internals.spawnSync("git", ["-C", directory, "show", `${revision}:${relativePath}`], {
76
+ cwd: directory,
77
+ encoding: "utf-8",
78
+ timeout: GIT_SNAPSHOT_TIMEOUT_MS,
79
+ maxBuffer: GIT_SNAPSHOT_MAX_BUFFER,
80
+ stdio: ["ignore", "pipe", "pipe"]
81
+ });
82
+ if (result.error || result.status !== 0 || typeof result.stdout !== "string")
83
+ return null;
84
+ return result.stdout;
85
+ }
86
+ function resolveCurrentGitHead(directory) {
87
+ return runGit(directory, ["rev-parse", "--verify", "HEAD^{commit}"]);
88
+ }
89
+ function resolveExactMergeBase(directory, baseRef, prHeadSha) {
90
+ if (!isSafeGitRevisionToken(baseRef) || !isSafeGitRevisionToken(prHeadSha))
91
+ return null;
92
+ const mergeBase = runGit(directory, ["merge-base", "--", baseRef, prHeadSha]);
93
+ return mergeBase && /^[0-9a-f]{6,64}$/i.test(mergeBase) ? mergeBase : null;
94
+ }
95
+ function isSafeGitRevisionToken(value) {
96
+ return /^(?!-)[A-Za-z0-9][A-Za-z0-9._/-]{0,255}$/.test(value) && !value.includes("..") && !value.includes("//") && !value.includes("@{");
97
+ }
98
+ function resolveCurrentUpstreamRemoteRef(directory) {
99
+ const upstream = runGit(directory, [
100
+ "rev-parse",
101
+ "--symbolic-full-name",
102
+ "@{upstream}"
103
+ ]);
104
+ if (!upstream?.startsWith("refs/remotes/") || upstream.endsWith("/HEAD")) {
105
+ return null;
106
+ }
107
+ return upstream;
108
+ }
109
+ function resolveCurrentUpstreamPushTarget(directory) {
110
+ const localBranchRef = runGit(directory, ["symbolic-ref", "--quiet", "HEAD"]);
111
+ if (!localBranchRef?.startsWith("refs/heads/"))
112
+ return null;
113
+ const encoded = runGit(directory, [
114
+ "for-each-ref",
115
+ "--format=%(upstream:remotename)%00%(upstream:remoteref)%00%(upstream)",
116
+ localBranchRef
117
+ ]);
118
+ if (!encoded)
119
+ return null;
120
+ const [remoteName, remoteBranchRef, remoteTrackingRef, ...extras] = encoded.split("\x00");
121
+ if (extras.length > 0 || !remoteName || remoteName.startsWith("-") || /[\s;&|<>`]/.test(remoteName) || !remoteBranchRef?.startsWith("refs/heads/") || remoteBranchRef === "refs/heads/" || /[\s;&|<>`]/.test(remoteBranchRef) || !remoteTrackingRef?.startsWith("refs/remotes/") || remoteTrackingRef.endsWith("/HEAD")) {
122
+ return null;
123
+ }
124
+ return { remoteName, remoteBranchRef, remoteTrackingRef };
125
+ }
126
+ function resolveExactRemoteBranchHead(directory, remoteName, remoteBranchRef) {
127
+ if (!remoteName || remoteName.startsWith("-") || /[\s;&|<>`]/.test(remoteName) || !remoteBranchRef.startsWith("refs/heads/") || remoteBranchRef === "refs/heads/" || /[\s;&|<>`]/.test(remoteBranchRef)) {
128
+ return null;
129
+ }
130
+ const output = runGit(directory, ["ls-remote", "--exit-code", "--heads", remoteName, remoteBranchRef], 20000);
131
+ if (!output)
132
+ return null;
133
+ const rows = output.split(/\r?\n/).filter(Boolean);
134
+ if (rows.length !== 1)
135
+ return null;
136
+ const [objectName, refName, ...extras] = rows[0].split(/\s+/);
137
+ if (extras.length > 0 || refName !== remoteBranchRef || !objectName || !(/^[0-9a-f]{40}$/i.test(objectName) || /^[0-9a-f]{64}$/i.test(objectName))) {
138
+ return null;
139
+ }
140
+ return objectName;
141
+ }
142
+ function resolveGitControlStateDigest(directory) {
143
+ const head = runGit(directory, ["rev-parse", "--verify", "HEAD^{commit}"]);
144
+ const symbolicHead = runGit(directory, ["symbolic-ref", "--quiet", "HEAD"]);
145
+ const upstream = resolveCurrentUpstreamPushTarget(directory);
146
+ const refs = runGit(directory, [
147
+ "for-each-ref",
148
+ "--format=%(refname)%00%(objectname)",
149
+ "refs/heads",
150
+ "refs/remotes",
151
+ "refs/tags"
152
+ ]);
153
+ const config = runGit(directory, [
154
+ "config",
155
+ "--null",
156
+ "--show-origin",
157
+ "--show-scope",
158
+ "--list"
159
+ ]);
160
+ const index = runGit(directory, ["ls-files", "--stage", "-z"]);
161
+ if (head === null || symbolicHead === null || !upstream || refs === null || config === null || index === null) {
162
+ return null;
163
+ }
164
+ return digest(`head\x00${head}\x00symbolic\x00${symbolicHead}\x00upstream\x00${upstream.remoteName}\x00${upstream.remoteBranchRef}\x00${upstream.remoteTrackingRef}\x00refs\x00${refs}\x00config\x00${config}\x00index\x00${index}`);
165
+ }
166
+ function resolveIsWorkingTreeClean(directory) {
167
+ const status = runGit(directory, [
168
+ "status",
169
+ "--porcelain=v1",
170
+ "--untracked-files=all"
171
+ ]);
172
+ return status === null ? null : status.length === 0;
173
+ }
174
+ function resolveCommitCountSince(directory, baseHeadSha, currentHeadSha) {
175
+ const output = runGit(directory, [
176
+ "rev-list",
177
+ "--count",
178
+ "--ancestry-path",
179
+ `${baseHeadSha}..${currentHeadSha}`
180
+ ]);
181
+ if (!output || !/^\d+$/.test(output))
182
+ return null;
183
+ const count = Number(output);
184
+ return Number.isSafeInteger(count) ? count : null;
185
+ }
186
+ function resolveIsExactSingleChildCommit(directory, baseHeadSha, currentHeadSha) {
187
+ const base = runGit(directory, [
188
+ "rev-parse",
189
+ "--verify",
190
+ `${baseHeadSha}^{commit}`
191
+ ]);
192
+ const current = runGit(directory, [
193
+ "rev-parse",
194
+ "--verify",
195
+ `${currentHeadSha}^{commit}`
196
+ ]);
197
+ if (!base || !current)
198
+ return null;
199
+ const commitAndParents = runGit(directory, [
200
+ "rev-list",
201
+ "--parents",
202
+ "-n",
203
+ "1",
204
+ current
205
+ ]);
206
+ if (commitAndParents === null)
207
+ return null;
208
+ const fields = commitAndParents.trim().split(/\s+/);
209
+ return fields.length === 2 && fields[0]?.toLowerCase() === current.toLowerCase() && fields[1]?.toLowerCase() === base.toLowerCase();
210
+ }
211
+ function resolveRemoteRefsContainingHead(directory, headSha) {
212
+ const output = runGit(directory, [
213
+ "for-each-ref",
214
+ "--format=%(refname)%09%(objectname)",
215
+ "refs/remotes"
216
+ ]);
217
+ if (output === null)
218
+ return null;
219
+ return output.split(/\r?\n/).map((line) => line.trim().split("\t")).filter(([ref, objectName]) => ref?.startsWith("refs/remotes/") && !ref.endsWith("/HEAD") && objectName?.toLowerCase() === headSha.toLowerCase()).map(([ref]) => ref);
220
+ }
221
+ function resolvePrWorkflowRevisionDigest(directory, baseHeadSha) {
222
+ const projectRoot = path.resolve(directory);
223
+ const baseHead = runGit(projectRoot, [
224
+ "rev-parse",
225
+ "--verify",
226
+ `${baseHeadSha}^{commit}`
227
+ ]);
228
+ const diffNames = runGit(projectRoot, [
229
+ "diff",
230
+ "--no-ext-diff",
231
+ "--name-only",
232
+ "-z",
233
+ baseHeadSha
234
+ ]);
235
+ const porcelain = runGit(projectRoot, [
236
+ "status",
237
+ "--porcelain=v1",
238
+ "-z",
239
+ "--untracked-files=all"
240
+ ]);
241
+ if (!baseHead || diffNames === null || porcelain === null)
242
+ return null;
243
+ const porcelainPaths = parsePorcelainPaths(porcelain);
244
+ if (!porcelainPaths)
245
+ return null;
246
+ const changedPaths = [
247
+ ...new Set([...parseNulPaths(diffNames), ...porcelainPaths])
248
+ ].sort((left, right) => left.localeCompare(right));
249
+ if (changedPaths.length > REVISION_MAX_FILES)
250
+ return null;
251
+ const hash = createHash("sha256");
252
+ hash.update(`base\x00${baseHead}\x00`);
253
+ let totalBytes = 0;
254
+ for (const relativePath of changedPaths) {
255
+ const resolvedPath = path.resolve(projectRoot, relativePath);
256
+ const relativeToRoot = path.relative(projectRoot, resolvedPath);
257
+ if (!relativeToRoot || relativeToRoot.startsWith("..") || path.isAbsolute(relativeToRoot))
258
+ return null;
259
+ hash.update(`path\x00${relativePath}\x00`);
260
+ let stats;
261
+ try {
262
+ stats = fs.lstatSync(resolvedPath);
263
+ } catch (error) {
264
+ if (error.code === "ENOENT") {
265
+ hash.update("deleted\x00");
266
+ continue;
267
+ }
268
+ return null;
269
+ }
270
+ if (stats.isSymbolicLink()) {
271
+ try {
272
+ hash.update(`symlink\x00${fs.readlinkSync(resolvedPath)}\x00`);
273
+ continue;
274
+ } catch {
275
+ return null;
276
+ }
277
+ }
278
+ if (!stats.isFile()) {
279
+ hash.update(`node\x00${stats.mode}\x00`);
280
+ continue;
281
+ }
282
+ totalBytes += stats.size;
283
+ if (totalBytes > REVISION_MAX_TOTAL_BYTES)
284
+ return null;
285
+ try {
286
+ hash.update(`file\x00${stats.mode}\x00`);
287
+ hash.update(fs.readFileSync(resolvedPath));
288
+ hash.update("\x00");
289
+ } catch {
290
+ return null;
291
+ }
292
+ }
293
+ return hash.digest("hex");
294
+ }
295
+ async function resolvePrWorkflowRevisionDigestAsync(directory, baseHeadSha) {
296
+ const projectRoot = path.resolve(directory);
297
+ const [baseHead, diffNames, porcelain] = await Promise.all([
298
+ runGitAsync(projectRoot, [
299
+ "rev-parse",
300
+ "--verify",
301
+ `${baseHeadSha}^{commit}`
302
+ ]),
303
+ runGitAsync(projectRoot, [
304
+ "diff",
305
+ "--no-ext-diff",
306
+ "--name-only",
307
+ "-z",
308
+ baseHeadSha
309
+ ]),
310
+ runGitAsync(projectRoot, [
311
+ "status",
312
+ "--porcelain=v1",
313
+ "-z",
314
+ "--untracked-files=all"
315
+ ])
316
+ ]);
317
+ if (!baseHead || diffNames === null || porcelain === null)
318
+ return null;
319
+ const porcelainPaths = parsePorcelainPaths(porcelain);
320
+ if (!porcelainPaths)
321
+ return null;
322
+ const changedPaths = [
323
+ ...new Set([...parseNulPaths(diffNames), ...porcelainPaths])
324
+ ].sort((left, right) => left.localeCompare(right));
325
+ if (changedPaths.length > REVISION_MAX_FILES)
326
+ return null;
327
+ const hash = createHash("sha256");
328
+ hash.update(`base\x00${baseHead}\x00`);
329
+ let totalBytes = 0;
330
+ let chunksSinceYield = 0;
331
+ for (const relativePath of changedPaths) {
332
+ const resolvedPath = path.resolve(projectRoot, relativePath);
333
+ const relativeToRoot = path.relative(projectRoot, resolvedPath);
334
+ if (!relativeToRoot || relativeToRoot.startsWith("..") || path.isAbsolute(relativeToRoot))
335
+ return null;
336
+ hash.update(`path\x00${relativePath}\x00`);
337
+ let stats;
338
+ try {
339
+ stats = await fs.promises.lstat(resolvedPath);
340
+ } catch (error) {
341
+ if (error.code === "ENOENT") {
342
+ hash.update("deleted\x00");
343
+ continue;
344
+ }
345
+ return null;
346
+ }
347
+ if (stats.isSymbolicLink()) {
348
+ try {
349
+ hash.update(`symlink\x00${await fs.promises.readlink(resolvedPath)}\x00`);
350
+ continue;
351
+ } catch {
352
+ return null;
353
+ }
354
+ }
355
+ if (!stats.isFile()) {
356
+ hash.update(`node\x00${stats.mode}\x00`);
357
+ continue;
358
+ }
359
+ totalBytes += stats.size;
360
+ if (totalBytes > REVISION_MAX_TOTAL_BYTES)
361
+ return null;
362
+ hash.update(`file\x00${stats.mode}\x00`);
363
+ let handle;
364
+ try {
365
+ handle = await fs.promises.open(resolvedPath, "r");
366
+ const buffer = Buffer.allocUnsafe(REVISION_READ_CHUNK_BYTES);
367
+ for (let position = 0;position < stats.size; ) {
368
+ const length = Math.min(REVISION_READ_CHUNK_BYTES, stats.size - position);
369
+ const { bytesRead } = await handle.read(buffer, 0, length, position);
370
+ if (bytesRead <= 0)
371
+ return null;
372
+ hash.update(buffer.subarray(0, bytesRead));
373
+ position += bytesRead;
374
+ chunksSinceYield++;
375
+ if (chunksSinceYield >= REVISION_YIELD_EVERY_CHUNKS) {
376
+ chunksSinceYield = 0;
377
+ await _internals.yieldControl();
378
+ }
379
+ }
380
+ hash.update("\x00");
381
+ } catch {
382
+ return null;
383
+ } finally {
384
+ await handle?.close().catch(() => {
385
+ return;
386
+ });
387
+ }
388
+ }
389
+ return hash.digest("hex");
390
+ }
391
+ function parseNulPaths(output) {
392
+ return output.split("\x00").filter((entry) => entry.length > 0);
393
+ }
394
+ function parsePorcelainPaths(output) {
395
+ const entries = parseNulPaths(output);
396
+ const paths = [];
397
+ for (let index = 0;index < entries.length; index++) {
398
+ const entry = entries[index];
399
+ if (entry.length < 4 || entry[2] !== " ")
400
+ return null;
401
+ const status = entry.slice(0, 2);
402
+ const changedPath = entry.slice(3);
403
+ if (!changedPath)
404
+ return null;
405
+ paths.push(changedPath);
406
+ if (status.includes("R") || status.includes("C")) {
407
+ const originalPath = entries[++index];
408
+ if (!originalPath)
409
+ return null;
410
+ paths.push(originalPath);
411
+ }
412
+ }
413
+ return [...new Set(paths)];
414
+ }
415
+ function parsePorcelainV2Snapshot(output) {
416
+ const records = output.split("\x00");
417
+ const headers = [];
418
+ while (records[0]?.startsWith("# ")) {
419
+ headers.push(records.shift());
420
+ }
421
+ const oidMatch = headers.join(`
422
+ `).match(/^# branch\.oid (.+)$/m);
423
+ if (!oidMatch)
424
+ return null;
425
+ const gitHead = /^[0-9a-f]{6,64}$/i.test(oidMatch[1]) ? oidMatch[1] : oidMatch[1] === "(initial)" ? null : null;
426
+ const paths = [];
427
+ for (let index = 0;index < records.length; index++) {
428
+ const record = records[index];
429
+ if (!record)
430
+ continue;
431
+ if (record.startsWith("? ")) {
432
+ paths.push(record.slice(2));
433
+ continue;
434
+ }
435
+ if (record.startsWith("1 ")) {
436
+ const changedPath = porcelainV2PathAfterFields(record, 8);
437
+ if (!changedPath)
438
+ return null;
439
+ paths.push(changedPath);
440
+ continue;
441
+ }
442
+ if (record.startsWith("2 ")) {
443
+ const changedPath = porcelainV2PathAfterFields(record, 9);
444
+ const originalPath = records[++index];
445
+ if (!changedPath || !originalPath)
446
+ return null;
447
+ paths.push(changedPath, originalPath);
448
+ continue;
449
+ }
450
+ if (record.startsWith("u ")) {
451
+ const changedPath = porcelainV2PathAfterFields(record, 10);
452
+ if (!changedPath)
453
+ return null;
454
+ paths.push(changedPath);
455
+ continue;
456
+ }
457
+ return null;
458
+ }
459
+ return { gitHead, changedFiles: [...new Set(paths)] };
460
+ }
461
+ function porcelainV2PathAfterFields(record, fields) {
462
+ let offset = 0;
463
+ for (let index = 0;index < fields; index++) {
464
+ const delimiter = record.indexOf(" ", offset);
465
+ if (delimiter < 0)
466
+ return null;
467
+ offset = delimiter + 1;
468
+ }
469
+ const pathValue = record.slice(offset);
470
+ return pathValue || null;
471
+ }
472
+ function captureWorkspaceSnapshot(directory, optionsOrScope = null, prHeadShaArg = null) {
473
+ const scope = typeof optionsOrScope === "object" && optionsOrScope !== null ? optionsOrScope.scope ?? null : optionsOrScope;
474
+ const configuredPrHeadSha = (() => {
475
+ if (typeof optionsOrScope !== "object" || optionsOrScope === null) {
476
+ return prHeadShaArg;
477
+ }
478
+ return optionsOrScope.prHeadSha ?? null;
479
+ })();
480
+ const resolveCurrentPrHeadSha = typeof optionsOrScope === "object" && optionsOrScope !== null && optionsOrScope.resolveCurrentPrHeadSha === true;
481
+ const upstreamBefore = resolveCurrentPrHeadSha ? runGit(directory, ["rev-parse", "@{upstream}"]) : null;
482
+ const porcelain = runGit(directory, [
483
+ "status",
484
+ "--porcelain=v2",
485
+ "--branch",
486
+ "-z",
487
+ "--untracked-files=all"
488
+ ]);
489
+ const snapshot = porcelain === null ? null : parsePorcelainV2Snapshot(porcelain);
490
+ const upstreamAfter = resolveCurrentPrHeadSha ? runGit(directory, ["rev-parse", "@{upstream}"]) : null;
491
+ const prHeadSha = resolveCurrentPrHeadSha ? upstreamBefore && upstreamBefore === upstreamAfter ? upstreamBefore : null : configuredPrHeadSha;
492
+ return {
493
+ directory: path.resolve(directory),
494
+ gitHead: snapshot?.gitHead ?? null,
495
+ dirtyHash: porcelain === null ? null : digest(porcelain),
496
+ changedFiles: snapshot?.changedFiles ?? null,
497
+ prHeadSha,
498
+ scope
499
+ };
500
+ }
501
+ function changedFilesSinceSnapshot(directory, baseline) {
502
+ if (!baseline?.gitHead || baseline.changedFiles == null)
503
+ return null;
504
+ if (baseline.changedFiles.length > 0)
505
+ return null;
506
+ const current = captureWorkspaceSnapshot(directory);
507
+ if (!current.gitHead || current.changedFiles == null)
508
+ return null;
509
+ const changed = new Set(current.changedFiles);
510
+ if (baseline.gitHead !== current.gitHead) {
511
+ const committed = runGit(directory, [
512
+ "diff",
513
+ "--name-only",
514
+ "-z",
515
+ baseline.gitHead,
516
+ current.gitHead
517
+ ]);
518
+ if (committed === null)
519
+ return null;
520
+ for (const changedPath of parseNulPaths(committed))
521
+ changed.add(changedPath);
522
+ }
523
+ return [...changed];
524
+ }
525
+ function workspaceSnapshotMatches(expected, current) {
526
+ if (!expected)
527
+ return { ok: true };
528
+ if (path.resolve(expected.directory) !== path.resolve(current.directory)) {
529
+ return {
530
+ ok: false,
531
+ reason: `directory changed: expected ${expected.directory}, got ${current.directory}`
532
+ };
533
+ }
534
+ const checks = ["gitHead", "dirtyHash", "prHeadSha"];
535
+ for (const key of checks) {
536
+ const expectedValue = expected[key];
537
+ if (expectedValue === null)
538
+ continue;
539
+ if (current[key] !== expectedValue) {
540
+ return {
541
+ ok: false,
542
+ reason: `${key} changed: expected ${expectedValue}, got ${current[key] ?? "unknown"}`
543
+ };
544
+ }
545
+ }
546
+ return { ok: true };
547
+ }
548
+ var compareWorkspaceSnapshot = workspaceSnapshotMatches;
549
+ function compareWorkspaceSnapshots(expected, current) {
550
+ const result = workspaceSnapshotMatches(expected, current);
551
+ if (result.ok)
552
+ return { stale: false };
553
+ return { stale: true, reason: result.reason };
554
+ }
555
+ function digest(text) {
556
+ return createHash("sha256").update(text).digest("hex");
557
+ }
558
+ var _internals = {
559
+ spawnSync: child_process.spawnSync,
560
+ yieldControl: () => new Promise((resolve2) => setImmediate(resolve2)),
561
+ parsePorcelainV2Snapshot
562
+ };
563
+
564
+ export { readGitTextAtRevision, resolveCurrentGitHead, resolveExactMergeBase, resolveCurrentUpstreamRemoteRef, resolveCurrentUpstreamPushTarget, resolveExactRemoteBranchHead, resolveGitControlStateDigest, resolveIsWorkingTreeClean, resolveCommitCountSince, resolveIsExactSingleChildCommit, resolveRemoteRefsContainingHead, resolvePrWorkflowRevisionDigest, resolvePrWorkflowRevisionDigestAsync, parsePorcelainPaths, captureWorkspaceSnapshot, changedFilesSinceSnapshot, workspaceSnapshotMatches, compareWorkspaceSnapshot, compareWorkspaceSnapshots, digest, _internals };
@@ -12,14 +12,14 @@ import {
12
12
  detectPosixWrites,
13
13
  detectWindowsWrites,
14
14
  resolveWriteTargets
15
- } from "./index-mkkx1a4f.js";
15
+ } from "./index-dsf1yv4s.js";
16
16
  import {
17
17
  checkFileAuthority,
18
18
  classifyFile,
19
19
  isInDeclaredScope,
20
20
  redactPath,
21
21
  redactShellCommand
22
- } from "./index-e19mxn9f.js";
22
+ } from "./index-pbjenws7.js";
23
23
 
24
24
  // src/services/guardrail-explain-service.ts
25
25
  import path from "path";
@@ -650,7 +650,7 @@ async function applyConfidenceFloorAction(directory, touched, options) {
650
650
  const recovered = touched.filter((e) => e.confidence > CONFIDENCE_FLOOR + FLOOR_EPSILON && e.confidence_floor_demoted);
651
651
  if (atFloor.length === 0 && recovered.length === 0)
652
652
  return;
653
- const { readKnowledgeCounterRollups, effectiveRetrievalOutcomes } = await import("./knowledge-events-a9hmxvke.js");
653
+ const { readKnowledgeCounterRollups, effectiveRetrievalOutcomes } = await import("./knowledge-events-qhr97sy9.js");
654
654
  const rollups = await readKnowledgeCounterRollups(directory);
655
655
  const flagIds = new Set;
656
656
  for (const e of atFloor) {
@@ -717,11 +717,11 @@ async function applyConfidenceFloorAction(directory, touched, options) {
717
717
  });
718
718
  }
719
719
  if (action === "quarantine" && toQuarantine.length > 0) {
720
- const { quarantineEntry } = await import("./knowledge-validator-9vrwxr3z.js");
721
- const { KnowledgeConfigSchema } = await import("./schema-y3z416z7.js");
720
+ const { quarantineEntry } = await import("./knowledge-validator-3t8tgzsz.js");
721
+ const { KnowledgeConfigSchema } = await import("./schema-y2d7j2jk.js");
722
722
  let config;
723
723
  try {
724
- const { loadPluginConfigWithMeta } = await import("./index-wqwpzhv1.js");
724
+ const { loadPluginConfigWithMeta } = await import("./index-rpg8qqjs.js");
725
725
  const { config: loadedConfig } = loadPluginConfigWithMeta(directory);
726
726
  config = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
727
727
  } catch {
@@ -3,7 +3,7 @@ import {
3
3
  init_constants,
4
4
  init_schema,
5
5
  stripKnownSwarmPrefix
6
- } from "./index-c6crt5rs.js";
6
+ } from "./index-8yvqkbw7.js";
7
7
  import {
8
8
  init_logger,
9
9
  warn
@@ -6,7 +6,7 @@ import {
6
6
  loadPluginConfigWithMeta,
7
7
  loadPluginConfigWithMetaAsync,
8
8
  resolveWorktreeIsolationConfig
9
- } from "./index-3yyr4ynk.js";
9
+ } from "./index-3k8pg467.js";
10
10
  import {
11
11
  ApprovalEvidenceSchema,
12
12
  BaseEvidenceSchema,
@@ -58,7 +58,7 @@ import {
58
58
  WorktreeIsolationConfigSchema,
59
59
  isQAAgent,
60
60
  isSubagent
61
- } from "./index-c6crt5rs.js";
61
+ } from "./index-8yvqkbw7.js";
62
62
  import"./index-bk5tah7q.js";
63
63
  import {
64
64
  MigrationStatusSchema,
@@ -2,18 +2,18 @@
2
2
  import {
3
3
  ALLOWED_SKILL_PATH_PREFIXES,
4
4
  validateSkillPath
5
- } from "./index-zjedv2bd.js";
5
+ } from "./index-ghteqdy1.js";
6
6
  import {
7
7
  computeOutcomeSignal,
8
8
  readKnowledge,
9
9
  resolveHiveKnowledgePath,
10
10
  resolveSwarmKnowledgePath,
11
11
  transactKnowledge
12
- } from "./index-2x4maxte.js";
12
+ } from "./index-mwdcvh0e.js";
13
13
  import {
14
14
  effectiveRetrievalOutcomes,
15
15
  readKnowledgeCounterRollups
16
- } from "./index-x2mmnrnx.js";
16
+ } from "./index-83rwq7pb.js";
17
17
  import {
18
18
  init_knowledge_types,
19
19
  isActiveStatus
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  redactPath,
4
4
  redactShellCommand
5
- } from "./index-e19mxn9f.js";
5
+ } from "./index-pbjenws7.js";
6
6
 
7
7
  // src/services/guardrail-log-service.ts
8
8
  import * as fs from "fs/promises";
@@ -7,7 +7,7 @@ import {
7
7
  init_constants,
8
8
  init_schema,
9
9
  stripKnownSwarmPrefix
10
- } from "./index-c6crt5rs.js";
10
+ } from "./index-8yvqkbw7.js";
11
11
  import {
12
12
  log
13
13
  } from "./index-zgwm4ryv.js";