@gobing-ai/spur 0.4.1 → 0.4.2

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 (104) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/config.global.yaml +4 -2
  3. package/config/templates/AGENTS.md +1 -1
  4. package/config/workflows/wrapup-pipeline.yaml +1 -1
  5. package/package.json +10 -10
  6. package/plugins/sp/README.md +1 -2
  7. package/plugins/sp/agents/super-planner.md +5 -6
  8. package/plugins/sp/commands/dev-review-session.md +2 -1
  9. package/plugins/sp/commands/dev-runall.md +18 -9
  10. package/plugins/sp/hooks/context-owner.ts +56 -0
  11. package/plugins/sp/hooks/context-post-tool.ts +23 -0
  12. package/plugins/sp/hooks/context-session-start.ts +49 -27
  13. package/plugins/sp/hooks/context-session-stop.ts +131 -30
  14. package/plugins/sp/hooks/pi/guard-extension.ts +21 -8
  15. package/plugins/sp/lib/idea-handoff.generated.mjs +4 -2
  16. package/plugins/sp/lib/inline-run.generated.mjs +47 -30
  17. package/plugins/sp/lib/plan-projection.generated.d.mts +19 -0
  18. package/plugins/sp/lib/plan-projection.generated.mjs +113 -0
  19. package/plugins/sp/lib/quality-gate.generated.d.mts +0 -12
  20. package/plugins/sp/lib/quality-gate.generated.mjs +48 -230
  21. package/plugins/sp/lib/transcript.ts +49 -21
  22. package/plugins/sp/plugin.json +1 -1
  23. package/plugins/sp/references/roles.md +1 -1
  24. package/plugins/sp/scripts/batch-plan.mjs +154 -1
  25. package/plugins/sp/scripts/batch-plan.ts +48 -3
  26. package/plugins/sp/scripts/inline-run-setup.mjs +24 -13
  27. package/plugins/sp/scripts/pr-reviewing.mjs +19 -5
  28. package/plugins/sp/scripts/pr-reviewing.ts +34 -9
  29. package/plugins/sp/scripts/quality-gate.mjs +25 -207
  30. package/plugins/sp/scripts/run-summary.mjs +24 -13
  31. package/plugins/sp/scripts/session-timeline.mjs +26 -25
  32. package/plugins/sp/scripts/session-timeline.ts +4 -18
  33. package/plugins/sp/scripts/task-diffstat.mjs +32 -29
  34. package/plugins/sp/scripts/task-diffstat.ts +34 -34
  35. package/plugins/sp/skills/indexed-context/SKILL.md +14 -7
  36. package/plugins/sp/skills/parallel-execution/SKILL.md +2 -2
  37. package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +1 -1
  38. package/plugins/sp/skills/parallel-execution/references/fan-out-patterns.md +2 -2
  39. package/plugins/sp/skills/pr-reviewing/SKILL.md +7 -3
  40. package/plugins/sp/skills/session-review/SKILL.md +5 -3
  41. package/plugins/sp/skills/spur-cli/references/decision.md +9 -2
  42. package/plugins/sp/skills/spur-cli/references/projects.md +7 -5
  43. package/plugins/sp/skills/spur-dev/SKILL.md +2 -0
  44. package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +27 -0
  45. package/plugins/sp/skills/spur-dev/references/dev-operations.md +2 -3
  46. package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +5 -0
  47. package/plugins/sp/skills/spur-dev/references/execution-batch.md +43 -4
  48. package/plugins/sp/skills/spur-dev/references/execution-parallel-isolation.md +4 -1
  49. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +13 -11
  50. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +8 -13
  51. package/spur.js +14261 -2846
  52. package/web/_astro/{BoardApp.D66k_s_T.js → BoardApp.B3GQZvj8.js} +1 -1
  53. package/web/_astro/{BoardApp.D6sjAJr_.js → BoardApp.BT7L2kSb.js} +192 -192
  54. package/web/_astro/TaskDetail.Cxov1_N_.js +1 -0
  55. package/web/_astro/{arc._BUadrdH.js → arc.vaT7tPOB.js} +1 -1
  56. package/web/_astro/{architectureDiagram-3BPJPVTR.Dh7xS1Pp.js → architectureDiagram-3BPJPVTR.DRMmTjkN.js} +1 -1
  57. package/web/_astro/{blockDiagram-GPEHLZMM.DFDVpfXm.js → blockDiagram-GPEHLZMM.cla0LO_q.js} +1 -1
  58. package/web/_astro/{c4Diagram-AAUBKEIU.V7_3_glh.js → c4Diagram-AAUBKEIU.D4YAIBKn.js} +1 -1
  59. package/web/_astro/channel.D4nG9YLf.js +1 -0
  60. package/web/_astro/{chunk-2J33WTMH.De1yx7Jz.js → chunk-2J33WTMH.BrSJbMRZ.js} +1 -1
  61. package/web/_astro/{chunk-4BX2VUAB.BDhHFuxx.js → chunk-4BX2VUAB.CuLMgKF5.js} +1 -1
  62. package/web/_astro/{chunk-55IACEB6.DDLkWnmC.js → chunk-55IACEB6.zkvgu54F.js} +1 -1
  63. package/web/_astro/{chunk-727SXJPM.CwfiLnA7.js → chunk-727SXJPM.DxWkACh8.js} +1 -1
  64. package/web/_astro/{chunk-AQP2D5EJ.CtGDmUnM.js → chunk-AQP2D5EJ.42XrmIlH.js} +1 -1
  65. package/web/_astro/{chunk-FMBD7UC4.BOLjpw73.js → chunk-FMBD7UC4.Bao2wMK9.js} +1 -1
  66. package/web/_astro/{chunk-ND2GUHAM.BDhQls6O.js → chunk-ND2GUHAM.BhydojD1.js} +1 -1
  67. package/web/_astro/{chunk-QZHKN3VN.76qBynDF.js → chunk-QZHKN3VN.CmZ82g-H.js} +1 -1
  68. package/web/_astro/{classDiagram-4FO5ZUOK.N0mpPHT0.js → classDiagram-4FO5ZUOK.Blr83Gt_.js} +1 -1
  69. package/web/_astro/{classDiagram-v2-Q7XG4LA2.N0mpPHT0.js → classDiagram-v2-Q7XG4LA2.Blr83Gt_.js} +1 -1
  70. package/web/_astro/{cose-bilkent-S5V4N54A.CKknFfjB.js → cose-bilkent-S5V4N54A.qmfv0SPn.js} +1 -1
  71. package/web/_astro/{cynefin-OW5HDTMX.Cw3ZWBAh.js → cynefin-OW5HDTMX.BtELhXPR.js} +1 -1
  72. package/web/_astro/{dagre-BM42HDAG.D3yIKCRD.js → dagre-BM42HDAG.AWmaAvXo.js} +1 -1
  73. package/web/_astro/{diagram-2AECGRRQ.D51dO83Z.js → diagram-2AECGRRQ.DdH34KDi.js} +1 -1
  74. package/web/_astro/{diagram-5GNKFQAL.Bb-FViDj.js → diagram-5GNKFQAL.BmNPix1k.js} +1 -1
  75. package/web/_astro/{diagram-KO2AKTUF.D3mN8S6x.js → diagram-KO2AKTUF.BNQd_Ppo.js} +1 -1
  76. package/web/_astro/{diagram-LMA3HP47.dMMyPcbJ.js → diagram-LMA3HP47.BAPgDi0e.js} +1 -1
  77. package/web/_astro/{diagram-OG6HWLK6.AzbvzY4C.js → diagram-OG6HWLK6.DZ4zyLdC.js} +1 -1
  78. package/web/_astro/{erDiagram-TEJ5UH35.BR5I4OZb.js → erDiagram-TEJ5UH35.Q1TySMmw.js} +1 -1
  79. package/web/_astro/{flowDiagram-I6XJVG4X.DFqvhGkn.js → flowDiagram-I6XJVG4X.BXhFBicG.js} +1 -1
  80. package/web/_astro/{ganttDiagram-6RSMTGT7.ByJbhH6J.js → ganttDiagram-6RSMTGT7.vHSgcuo2.js} +1 -1
  81. package/web/_astro/{gitGraphDiagram-PVQCEYII.CInHjQR3.js → gitGraphDiagram-PVQCEYII.Bi1f73C7.js} +1 -1
  82. package/web/_astro/{index.COh_kBxN.css → index.BhSwN8yY.css} +1 -1
  83. package/web/_astro/{infoDiagram-5YYISTIA.Cm0dGVjJ.js → infoDiagram-5YYISTIA.DPvXZEWm.js} +1 -1
  84. package/web/_astro/{ishikawaDiagram-YF4QCWOH.C3nOP6Sj.js → ishikawaDiagram-YF4QCWOH.Cz829fsV.js} +1 -1
  85. package/web/_astro/{journeyDiagram-JHISSGLW.4IvLa2MW.js → journeyDiagram-JHISSGLW.enRnB9Me.js} +1 -1
  86. package/web/_astro/{kanban-definition-UN3LZRKU.DS87Cl-k.js → kanban-definition-UN3LZRKU.DnTNk6d2.js} +1 -1
  87. package/web/_astro/{linear.MzmRrNER.js → linear.BzGnBwNL.js} +1 -1
  88. package/web/_astro/{mermaid.core.fK-WNswS.js → mermaid.core.CSbTpIVz.js} +4 -4
  89. package/web/_astro/{mindmap-definition-RKZ34NQL.BqipOHhY.js → mindmap-definition-RKZ34NQL.DGJDy8zT.js} +1 -1
  90. package/web/_astro/{pieDiagram-4H26LBE5.0nBiPqFG.js → pieDiagram-4H26LBE5.HSPdi5_8.js} +1 -1
  91. package/web/_astro/{quadrantDiagram-W4KKPZXB.Szj7Zpx5.js → quadrantDiagram-W4KKPZXB.6Gv8mz2Y.js} +1 -1
  92. package/web/_astro/{requirementDiagram-4Y6WPE33.D4UR6TWo.js → requirementDiagram-4Y6WPE33.CnBCtFwa.js} +1 -1
  93. package/web/_astro/{sankeyDiagram-5OEKKPKP.DAE7BdOs.js → sankeyDiagram-5OEKKPKP.5M8VWAu8.js} +1 -1
  94. package/web/_astro/{sequenceDiagram-3UESZ5HK.BP9ZVq25.js → sequenceDiagram-3UESZ5HK.DN41XN-U.js} +1 -1
  95. package/web/_astro/{stateDiagram-AJRCARHV.BQW7mIxk.js → stateDiagram-AJRCARHV.ErOO3W8j.js} +1 -1
  96. package/web/_astro/{stateDiagram-v2-BHNVJYJU.PbK4nDih.js → stateDiagram-v2-BHNVJYJU.B_ZHICM-.js} +1 -1
  97. package/web/_astro/{timeline-definition-PNZ67QCA.Ci_GvUpo.js → timeline-definition-PNZ67QCA.CWdosr07.js} +1 -1
  98. package/web/_astro/{vennDiagram-CIIHVFJN.DNw1Y5qx.js → vennDiagram-CIIHVFJN.BHzYjNV5.js} +1 -1
  99. package/web/_astro/{wardleyDiagram-YWT4CUSO.CwlkaaNe.js → wardleyDiagram-YWT4CUSO.h8x4IwPX.js} +1 -1
  100. package/web/_astro/{xychartDiagram-2RQKCTM6.MI6ZuiH_.js → xychartDiagram-2RQKCTM6.RTapW2X8.js} +1 -1
  101. package/web/index.html +2 -2
  102. package/plugins/sp/commands/dev-parallel.md +0 -37
  103. package/web/_astro/TaskDetail.BynLnMNc.js +0 -1
  104. package/web/_astro/channel.DZVfto-r.js +0 -1
@@ -21,6 +21,25 @@ export declare function buildPhasedPlan(def: unknown): PhasedPlanItem[] | null;
21
21
  export declare function validatePhaseTable(def: unknown): string[];
22
22
  export declare function insertOnEntry(items: PhasedPlanItem[], stateId: string, def: unknown): PhasedPlanItem[];
23
23
  export declare function buildBatchPlan(tasks: BatchTask[]): PhasedPlanItem[][];
24
+ export declare interface ScheduleTask {
25
+ wbs: string;
26
+ dependencies?: string[];
27
+ files?: string[];
28
+ }
29
+ export declare interface ScheduleOverlap {
30
+ before: string;
31
+ after: string;
32
+ files: string[];
33
+ }
34
+ export declare interface BatchSchedule {
35
+ order: string[];
36
+ waves: string[][];
37
+ cycle: string[] | null;
38
+ overlaps: ScheduleOverlap[];
39
+ mode: 'sequential' | 'parallel';
40
+ reason: string;
41
+ }
42
+ export declare function scheduleBatch(tasks: ScheduleTask[], opts?: { concurrency?: number }): BatchSchedule;
24
43
  export declare function taskPhaseChildren(taskLetter: string, plan: PhasedPlanItem[]): PhasedPlanItem[];
25
44
  export declare function hostStatus(
26
45
  outcome: 'pending' | 'active' | 'completed' | 'skipped' | 'failed' | 'blocked' | 'unattempted',
@@ -216,6 +216,118 @@ function buildBatchPlan(tasks) {
216
216
  }
217
217
  return waves;
218
218
  }
219
+ var byWbs = (a, b) => a.localeCompare(b, "en", { numeric: true });
220
+ function kahnOrder(nodes, preds) {
221
+ const indegree = new Map(nodes.map((n) => [n, preds.get(n)?.size ?? 0]));
222
+ const succ = new Map(nodes.map((n) => [n, []]));
223
+ for (const [n, ps] of preds)
224
+ for (const p of ps)
225
+ succ.get(p)?.push(n);
226
+ const ready = nodes.filter((n) => indegree.get(n) === 0).sort(byWbs);
227
+ const order = [];
228
+ for (let n = ready.shift();n !== undefined; n = ready.shift()) {
229
+ order.push(n);
230
+ for (const s of succ.get(n) ?? []) {
231
+ const d = (indegree.get(s) ?? 0) - 1;
232
+ indegree.set(s, d);
233
+ if (d === 0) {
234
+ ready.push(s);
235
+ ready.sort(byWbs);
236
+ }
237
+ }
238
+ }
239
+ return order;
240
+ }
241
+ function findCycle(remaining, preds) {
242
+ const state = new Map;
243
+ const stack = [];
244
+ const visit = (n) => {
245
+ state.set(n, "visiting");
246
+ stack.push(n);
247
+ for (const p of [...preds.get(n) ?? []].sort(byWbs)) {
248
+ if (!remaining.has(p))
249
+ continue;
250
+ if (state.get(p) === "visiting")
251
+ return [...stack.slice(stack.indexOf(p)), p];
252
+ if (!state.has(p)) {
253
+ const cycle = visit(p);
254
+ if (cycle)
255
+ return cycle;
256
+ }
257
+ }
258
+ stack.pop();
259
+ state.set(n, "done");
260
+ return null;
261
+ };
262
+ for (const n of [...remaining].sort(byWbs)) {
263
+ if (state.has(n))
264
+ continue;
265
+ const cycle = visit(n);
266
+ if (cycle)
267
+ return cycle;
268
+ }
269
+ return [];
270
+ }
271
+ function scheduleBatch(tasks, opts = {}) {
272
+ const byId = new Map;
273
+ for (const t of tasks)
274
+ if (!byId.has(t.wbs))
275
+ byId.set(t.wbs, t);
276
+ const nodes = [...byId.keys()].sort(byWbs);
277
+ const preds = new Map(nodes.map((n) => [n, new Set((byId.get(n)?.dependencies ?? []).filter((d) => byId.has(d)))]));
278
+ const depOrder = kahnOrder(nodes, preds);
279
+ if (depOrder.length < nodes.length) {
280
+ const cycle = findCycle(new Set(nodes.filter((n) => !depOrder.includes(n))), preds);
281
+ return {
282
+ order: [],
283
+ waves: [],
284
+ cycle,
285
+ overlaps: [],
286
+ mode: "sequential",
287
+ reason: `dependency cycle ${cycle.join(" → ")}`
288
+ };
289
+ }
290
+ const files = new Map(nodes.map((n) => [n, new Set((byId.get(n)?.files ?? []).map(normalizeTaskPath))]));
291
+ const overlaps = [];
292
+ for (let i = 0;i < depOrder.length; i++) {
293
+ const before = depOrder[i];
294
+ const beforeFiles = files.get(before) ?? new Set;
295
+ for (const after of depOrder.slice(i + 1)) {
296
+ const shared = [...beforeFiles].filter((f) => files.get(after)?.has(f)).sort();
297
+ if (shared.length === 0)
298
+ continue;
299
+ overlaps.push({ before, after, files: shared });
300
+ preds.get(after)?.add(before);
301
+ }
302
+ }
303
+ const order = kahnOrder(nodes, preds);
304
+ const level = new Map;
305
+ for (const n of order) {
306
+ let l = 0;
307
+ for (const p of preds.get(n) ?? [])
308
+ l = Math.max(l, (level.get(p) ?? 0) + 1);
309
+ level.set(n, l);
310
+ }
311
+ const waves = [];
312
+ for (const n of order) {
313
+ const l = level.get(n) ?? 0;
314
+ waves[l] = [...waves[l] ?? [], n].sort(byWbs);
315
+ }
316
+ const widest = Math.max(0, ...waves.map((w) => w.length));
317
+ const concurrency = opts.concurrency ?? 2;
318
+ let reason = `widest wave holds ${widest} independent tasks`;
319
+ if (nodes.length < 2)
320
+ reason = "fewer than two tasks";
321
+ else if (concurrency < 2)
322
+ reason = "concurrency is 1";
323
+ else if (widest < 2)
324
+ reason = "every wave holds one task (dependency or file-overlap chain)";
325
+ const mode = nodes.length >= 2 && concurrency >= 2 && widest >= 2 ? "parallel" : "sequential";
326
+ return { order, waves, cycle: null, overlaps, mode, reason };
327
+ }
328
+ function normalizeTaskPath(path) {
329
+ return path.trim().replace(/^\.\//, "");
330
+ }
219
331
  function taskPhaseChildren(taskLetter, plan) {
220
332
  if (!Array.isArray(plan))
221
333
  return [];
@@ -245,6 +357,7 @@ function hostText(item) {
245
357
  export {
246
358
  validatePhaseTable,
247
359
  taskPhaseChildren,
360
+ scheduleBatch,
248
361
  planLetter,
249
362
  planChild,
250
363
  insertOnEntry,
@@ -10,18 +10,6 @@ export declare const LOCKED_PATTERN: RegExp;
10
10
  export declare const FINDINGS_PATTERN: RegExp;
11
11
  export declare const COVERAGE_ROW_PATTERN: RegExp;
12
12
  export declare const RECEIPT_SCHEMA_VERSION: 'check-receipt/v1';
13
- export declare const GATE_LOCK_DIR_ENV: string;
14
- export declare const GATE_LOCK_POLL_MS_ENV: string;
15
- export declare const GATE_LOCK_OFF_ENV: string;
16
- export declare const GATE_LOCK_TOKEN_ENV: string;
17
- export declare const GATE_LOCK_POLL_MS_DEFAULT: number;
18
- export declare const GATE_LOCK_MKDIR_HOLD_MS_ENV: string;
19
- export declare interface GateLock {
20
- release(): void;
21
- queueWaitMs: number;
22
- token: string;
23
- }
24
- export declare function acquireGateLock(env: QualityGateEnv, logLine?: (line: string) => void): GateLock;
25
13
  export declare interface QualityGateEnv {
26
14
  wbs: string;
27
15
  qualityGateCmd?: string;
@@ -17,7 +17,7 @@ var __export = (target, all) => {
17
17
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
18
18
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
19
19
 
20
- // node_modules/.bun/@gobing-ai+ts-utils@0.5.21/node_modules/@gobing-ai/ts-utils/dist/errors.js
20
+ // node_modules/.bun/@gobing-ai+ts-utils@0.5.22/node_modules/@gobing-ai/ts-utils/dist/errors.js
21
21
  var ErrorCode;
22
22
  var init_errors = __esm(() => {
23
23
  ErrorCode = {
@@ -28,7 +28,7 @@ var init_errors = __esm(() => {
28
28
  };
29
29
  });
30
30
 
31
- // node_modules/.bun/@gobing-ai+ts-utils@0.5.21/node_modules/@gobing-ai/ts-utils/dist/api-response.js
31
+ // node_modules/.bun/@gobing-ai+ts-utils@0.5.22/node_modules/@gobing-ai/ts-utils/dist/api-response.js
32
32
  var API_ERROR_CODES, ERROR_CODE_TO_HTTP, CLIENT_SAFE_CODES;
33
33
  var init_api_response = __esm(() => {
34
34
  init_errors();
@@ -51,28 +51,18 @@ var init_api_response = __esm(() => {
51
51
  CLIENT_SAFE_CODES = new Set([ErrorCode.NotFound, ErrorCode.Validation, ErrorCode.Conflict]);
52
52
  });
53
53
 
54
- // node_modules/.bun/@gobing-ai+ts-utils@0.5.21/node_modules/@gobing-ai/ts-utils/dist/cursor.js
54
+ // node_modules/.bun/@gobing-ai+ts-utils@0.5.22/node_modules/@gobing-ai/ts-utils/dist/cursor.js
55
55
  var init_cursor = () => {};
56
56
 
57
- // node_modules/.bun/@gobing-ai+ts-utils@0.5.21/node_modules/@gobing-ai/ts-utils/dist/env.js
58
- function getEnvVar(name, fallback) {
59
- const raw = process.env[name];
60
- return raw === undefined ? fallback : raw;
61
- }
57
+ // node_modules/.bun/@gobing-ai+ts-utils@0.5.22/node_modules/@gobing-ai/ts-utils/dist/env.js
62
58
  function getEnvVars() {
63
59
  return process.env;
64
60
  }
65
- function setEnvVar(name, value) {
66
- if (value === undefined)
67
- delete process.env[name];
68
- else
69
- process.env[name] = value;
70
- }
71
61
 
72
- // node_modules/.bun/@gobing-ai+ts-utils@0.5.21/node_modules/@gobing-ai/ts-utils/dist/event-severity.js
62
+ // node_modules/.bun/@gobing-ai+ts-utils@0.5.22/node_modules/@gobing-ai/ts-utils/dist/event-severity.js
73
63
  var init_event_severity = () => {};
74
64
 
75
- // node_modules/.bun/@gobing-ai+ts-utils@0.5.21/node_modules/@gobing-ai/ts-utils/dist/index.js
65
+ // node_modules/.bun/@gobing-ai+ts-utils@0.5.22/node_modules/@gobing-ai/ts-utils/dist/index.js
76
66
  var init_dist = __esm(() => {
77
67
  init_api_response();
78
68
  init_cursor();
@@ -23896,7 +23886,7 @@ var init_dist2 = __esm(() => {
23896
23886
  $visitAsync = visit.visitAsync;
23897
23887
  });
23898
23888
 
23899
- // node_modules/.bun/@gobing-ai+ts-db@0.5.21+3862528db3f84042/node_modules/@gobing-ai/ts-db/dist/schema/common.js
23889
+ // node_modules/.bun/@gobing-ai+ts-db@0.5.22+4e07478ab737d0a0/node_modules/@gobing-ai/ts-db/dist/schema/common.js
23900
23890
  function nowTimestamp() {
23901
23891
  return Date.now();
23902
23892
  }
@@ -23925,7 +23915,7 @@ var init_common3 = __esm(() => {
23925
23915
  appendOnlyColumns = buildAppendOnlyColumns();
23926
23916
  });
23927
23917
 
23928
- // node_modules/.bun/@gobing-ai+ts-db@0.5.21+3862528db3f84042/node_modules/@gobing-ai/ts-db/dist/schema/drizzle-internals.js
23918
+ // node_modules/.bun/@gobing-ai+ts-db@0.5.22+4e07478ab737d0a0/node_modules/@gobing-ai/ts-db/dist/schema/drizzle-internals.js
23929
23919
  function sqlExpressionToText(value) {
23930
23920
  if (typeof value !== "object" || value === null || !("queryChunks" in value)) {
23931
23921
  return;
@@ -23948,7 +23938,7 @@ function getDrizzleTableName(table3) {
23948
23938
  return String(table3[nameSym]);
23949
23939
  }
23950
23940
 
23951
- // node_modules/.bun/@gobing-ai+ts-db@0.5.21+3862528db3f84042/node_modules/@gobing-ai/ts-db/dist/schema/ddl.js
23941
+ // node_modules/.bun/@gobing-ai+ts-db@0.5.22+4e07478ab737d0a0/node_modules/@gobing-ai/ts-db/dist/schema/ddl.js
23952
23942
  function quoteIdent(name) {
23953
23943
  return `"${name.replace(/"/g, '""')}"`;
23954
23944
  }
@@ -24320,7 +24310,7 @@ var init_drizzle_zod = __esm(() => {
24320
24310
  };
24321
24311
  });
24322
24312
 
24323
- // node_modules/.bun/@gobing-ai+ts-db@0.5.21+3862528db3f84042/node_modules/@gobing-ai/ts-db/dist/schema/define-table.js
24313
+ // node_modules/.bun/@gobing-ai+ts-db@0.5.22+4e07478ab737d0a0/node_modules/@gobing-ai/ts-db/dist/schema/define-table.js
24324
24314
  function defineTable(name, columns2) {
24325
24315
  const table3 = sqliteTable(name, columns2);
24326
24316
  let insert2;
@@ -24354,7 +24344,7 @@ var init_define_table = __esm(() => {
24354
24344
  init_ddl();
24355
24345
  });
24356
24346
 
24357
- // node_modules/.bun/@gobing-ai+ts-db@0.5.21+3862528db3f84042/node_modules/@gobing-ai/ts-db/dist/schema/index.js
24347
+ // node_modules/.bun/@gobing-ai+ts-db@0.5.22+4e07478ab737d0a0/node_modules/@gobing-ai/ts-db/dist/schema/index.js
24358
24348
  var init_schema = __esm(() => {
24359
24349
  init_sqlite_core();
24360
24350
  init_define_table();
@@ -24372,16 +24362,14 @@ import {
24372
24362
  mkdirSync,
24373
24363
  mkdtempSync,
24374
24364
  openSync,
24375
- readdirSync,
24376
24365
  readFileSync,
24377
- rmdirSync,
24378
24366
  rmSync,
24379
24367
  statSync,
24380
24368
  unlinkSync,
24381
24369
  writeFileSync
24382
24370
  } from "node:fs";
24383
- import { homedir, tmpdir } from "node:os";
24384
- import { dirname, join, resolve } from "node:path";
24371
+ import { tmpdir } from "node:os";
24372
+ import { join, resolve } from "node:path";
24385
24373
 
24386
24374
  // packages/app/src/workflow/composition-baseline.ts
24387
24375
  function canonicalJsonStringify(obj) {
@@ -24926,8 +24914,8 @@ var POST_WATERMARK_TABLES = [
24926
24914
  "history_daily_stats",
24927
24915
  "history_board_source_daily"
24928
24916
  ];
24929
- // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.21+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/schema-sql.js
24930
- var HISTORY_IMPORT_SCHEMA_VERSION = "0.5.21";
24917
+ // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.22+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/schema-sql.js
24918
+ var HISTORY_IMPORT_SCHEMA_VERSION = "0.5.22";
24931
24919
  var HISTORY_IMPORT_SCHEMA_SQL = `
24932
24920
  CREATE TABLE IF NOT EXISTS history_import_checkpoint (
24933
24921
  source TEXT NOT NULL,
@@ -25054,13 +25042,13 @@ CREATE INDEX IF NOT EXISTS idx_history_skill_call_invocation_kind
25054
25042
  ON history_skill_call(invocation_kind);
25055
25043
  `.trim();
25056
25044
 
25057
- // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.21+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/sources.js
25045
+ // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.22+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/sources.js
25058
25046
  init_zod();
25059
25047
 
25060
- // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.21+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/mappers.js
25048
+ // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.22+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/mappers.js
25061
25049
  init_zod();
25062
25050
 
25063
- // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.21+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/hash.js
25051
+ // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.22+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/hash.js
25064
25052
  import { createHash } from "node:crypto";
25065
25053
  function stableJson(value) {
25066
25054
  if (Array.isArray(value)) {
@@ -25079,7 +25067,7 @@ function sha256Text(text) {
25079
25067
  return createHash("sha256").update(text, "utf8").digest("hex");
25080
25068
  }
25081
25069
 
25082
- // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.21+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/capability.js
25070
+ // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.22+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/capability.js
25083
25071
  function matchCapabilityOrigin(origins, source, canonicalName, observable) {
25084
25072
  let candidates = origins.filter((origin2) => origin2.source === source && origin2.skillName === canonicalName);
25085
25073
  if (candidates.length === 0)
@@ -25344,7 +25332,7 @@ function extractNestedExecCommandLiterals(payloadText) {
25344
25332
  return literals;
25345
25333
  }
25346
25334
 
25347
- // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.21+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/redaction.js
25335
+ // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.22+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/redaction.js
25348
25336
  var DEFAULT_REDACTION_RULES = [
25349
25337
  {
25350
25338
  name: "api-key",
@@ -25386,7 +25374,7 @@ function applyRules(value, rules = DEFAULT_REDACTION_RULES) {
25386
25374
  return rules.reduce((current, rule) => current.replace(rule.pattern, rule.replacement), value);
25387
25375
  }
25388
25376
 
25389
- // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.21+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/mappers.js
25377
+ // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.22+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/mappers.js
25390
25378
  var MESSAGE_MAPPER_KEYS = [
25391
25379
  "_codexUsageCarrier",
25392
25380
  "session_id",
@@ -27492,7 +27480,7 @@ var GROK_SCHEMA = passthroughSchema;
27492
27480
  var GEMINI_SCHEMA = passthroughSchema;
27493
27481
  var DSH_SCHEMA = passthroughSchema;
27494
27482
 
27495
- // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.21+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/sources.js
27483
+ // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.22+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/sources.js
27496
27484
  var sourceRecordSchema = exports_external.object({
27497
27485
  source_record_id: exports_external.string().min(1),
27498
27486
  created_at: exports_external.string().min(1),
@@ -27596,10 +27584,10 @@ var SOURCE_DEFINITIONS = {
27596
27584
  openclaw: sourceDefinition("openclaw", "OpenClaw", [".openclaw"], ["*.jsonl"])
27597
27585
  };
27598
27586
 
27599
- // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.21+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/jsonl-importer-dao.js
27587
+ // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.22+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/jsonl-importer-dao.js
27600
27588
  var TYPED_HISTORY_TABLES = ["history_message", "history_tool_call", "history_skill_call"];
27601
27589
  var TYPED_IGNORED_KEYS = new Set(["_meta", "split_index", "source_record_id", "_capabilityConflict"]);
27602
- // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.21+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/tables.js
27590
+ // node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.5.22+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/tables.js
27603
27591
  var BOOKKEEPING_HISTORY_TABLES = ["history_import_checkpoint", "history_import_ledger"];
27604
27592
  var IMPORTER_OWNED_TABLES = [
27605
27593
  ...TYPED_HISTORY_TABLES,
@@ -27713,7 +27701,7 @@ var workflowStatesTable = defineTable("workflow_states", {
27713
27701
  ...standardColumns
27714
27702
  });
27715
27703
  var workflowStates = workflowStatesTable.table;
27716
- // node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.5.21+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/schema-sql.js
27704
+ // node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.5.22+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/schema-sql.js
27717
27705
  var WORKFLOW_ENGINE_SCHEMA_SQL = `
27718
27706
  CREATE TABLE IF NOT EXISTS runs (
27719
27707
  id TEXT PRIMARY KEY,
@@ -27812,7 +27800,7 @@ ALTER TABLE runs ADD COLUMN owner_pid INTEGER;
27812
27800
  ALTER TABLE runs ADD COLUMN interrupt_reason TEXT;
27813
27801
  ALTER TABLE runs ADD COLUMN terminal_reason TEXT;
27814
27802
  `.trim();
27815
- // node_modules/.bun/@gobing-ai+ts-rule-engine@0.5.21+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/schema.js
27803
+ // node_modules/.bun/@gobing-ai+ts-rule-engine@0.5.22+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/schema.js
27816
27804
  var RULE_ENGINE_SCHEMA_SQL = `
27817
27805
  CREATE TABLE IF NOT EXISTS rule_runs (
27818
27806
  id TEXT PRIMARY KEY,
@@ -27922,6 +27910,9 @@ var INBOX_MESSAGES_REQUEST_KEY_SCHEMA_SQL = `
27922
27910
  ALTER TABLE inbox_messages ADD COLUMN request_key TEXT;
27923
27911
  CREATE UNIQUE INDEX IF NOT EXISTS idx_inbox_messages_request_key ON inbox_messages (request_key) WHERE request_key IS NOT NULL;
27924
27912
  `;
27913
+ var INBOX_MESSAGES_READ_AT_SCHEMA_SQL = `
27914
+ ALTER TABLE inbox_messages ADD COLUMN read_at INTEGER;
27915
+ `;
27925
27916
  var QUEUE_JOBS_SCHEMA_SQL = `
27926
27917
  CREATE TABLE IF NOT EXISTS queue_jobs (
27927
27918
  id TEXT PRIMARY KEY,
@@ -28934,6 +28925,11 @@ var CLI_MIGRATIONS = [
28934
28925
  {
28935
28926
  id: "0052_spur_cli_decision_logs",
28936
28927
  sql: DECISION_LOGS_SCHEMA_SQL
28928
+ },
28929
+ {
28930
+ id: "0053_spur_cli_inbox_messages_read_at",
28931
+ sql: INBOX_MESSAGES_READ_AT_SCHEMA_SQL,
28932
+ addColumnIfMissing: { table: "inbox_messages", column: "read_at" }
28937
28933
  }
28938
28934
  ];
28939
28935
  // packages/domain/src/envelope/schema.ts
@@ -30436,159 +30432,6 @@ function runShellCommand(cmd, cwd, extraEnv) {
30436
30432
  rmSync(dir, { recursive: true, force: true });
30437
30433
  }
30438
30434
  }
30439
- var GATE_LOCK_DIR_ENV = "SPUR_GATE_LOCK_DIR";
30440
- var GATE_LOCK_POLL_MS_ENV = "SPUR_GATE_LOCK_POLL_MS";
30441
- var GATE_LOCK_OFF_ENV = "SPUR_GATE_LOCK";
30442
- var GATE_LOCK_TOKEN_ENV = "SPUR_GATE_LOCK_TOKEN";
30443
- var GATE_LOCK_POLL_MS_DEFAULT = 5000;
30444
- var GATE_LOCK_MKDIR_HOLD_MS_ENV = "SPUR_GATE_LOCK_TEST_MKDIR_HOLD_MS";
30445
- var GATE_LOCK_LOST_RACE_SLEEP_MS = 20;
30446
- var GATE_LOCK_LOST_RACE_LOG_AT = 250;
30447
- function gateLockDir() {
30448
- const raw = getEnvVar(GATE_LOCK_DIR_ENV);
30449
- return raw !== undefined && raw.length > 0 ? raw : join(homedir(), ".config", "spur", "run", "full-gate.lock");
30450
- }
30451
- function gateLockPollMs() {
30452
- const raw = Number.parseInt(getEnvVar(GATE_LOCK_POLL_MS_ENV) ?? "", 10);
30453
- return Number.isFinite(raw) && raw > 0 ? raw : GATE_LOCK_POLL_MS_DEFAULT;
30454
- }
30455
- function isProcessAlive(pid) {
30456
- try {
30457
- process.kill(pid, 0);
30458
- return true;
30459
- } catch (error51) {
30460
- return error51.code !== "ESRCH";
30461
- }
30462
- }
30463
- function readGateLockClaim(dir) {
30464
- let markers;
30465
- try {
30466
- markers = readdirSync(dir).sort();
30467
- } catch {
30468
- return null;
30469
- }
30470
- for (const marker of markers) {
30471
- try {
30472
- const claim = JSON.parse(readFileSync(join(dir, marker), "utf8"));
30473
- if (typeof claim.pid === "number")
30474
- return { claim, marker };
30475
- } catch {
30476
- const pid = Number.parseInt(/^(\d+)-/.exec(marker)?.[1] ?? "", 10);
30477
- if (pid > 0) {
30478
- return { claim: { pid, startedAt: Date.now(), wbs: "?", runId: "?", cwd: "?" }, marker };
30479
- }
30480
- }
30481
- }
30482
- return null;
30483
- }
30484
- function acquireGateLock(env2, logLine = () => {}) {
30485
- if ((getEnvVar(GATE_LOCK_OFF_ENV) ?? "") === "off") {
30486
- return { release() {}, queueWaitMs: 0, token: "" };
30487
- }
30488
- const dir = gateLockDir();
30489
- mkdirSync(dirname(dir), { recursive: true });
30490
- const pollMs = gateLockPollMs();
30491
- const claim = {
30492
- pid: process.pid,
30493
- startedAt: Date.now(),
30494
- wbs: env2.wbs,
30495
- runId: receiptRunId(env2),
30496
- cwd: process.cwd()
30497
- };
30498
- const marker = `${process.pid}-${randomUUID()}`;
30499
- const startedWaitingAt = Date.now();
30500
- let holderLogged = false;
30501
- let graceLogged = false;
30502
- let lostRaces = 0;
30503
- let lostRaceLogged = false;
30504
- const mkdirHoldMs = Number.parseInt(getEnvVar(GATE_LOCK_MKDIR_HOLD_MS_ENV) ?? "", 10);
30505
- for (;; ) {
30506
- let dirIno = null;
30507
- try {
30508
- mkdirSync(dir);
30509
- dirIno = statSync(dir).ino;
30510
- if (Number.isFinite(mkdirHoldMs) && mkdirHoldMs > 0)
30511
- gateSleep(mkdirHoldMs);
30512
- writeFileSync(join(dir, marker), JSON.stringify(claim), { flag: "wx" });
30513
- } catch (error51) {
30514
- const code = error51.code;
30515
- if (code === "ENOENT" || code === "EINVAL") {
30516
- lostRaces += 1;
30517
- if (lostRaces === GATE_LOCK_LOST_RACE_LOG_AT && !lostRaceLogged) {
30518
- lostRaceLogged = true;
30519
- logLine(`quality gate lock: still losing the claim race after ${lostRaces} attempts (dir ${dir})
30520
- `);
30521
- }
30522
- gateSleep(GATE_LOCK_LOST_RACE_SLEEP_MS);
30523
- continue;
30524
- }
30525
- if (code !== "EEXIST") {
30526
- throw error51;
30527
- }
30528
- }
30529
- if (dirIno !== null) {
30530
- let currentIno = null;
30531
- let entries = [];
30532
- try {
30533
- currentIno = statSync(dir).ino;
30534
- entries = readdirSync(dir);
30535
- } catch {}
30536
- if (currentIno !== dirIno || entries.length !== 1 || entries[0] !== marker) {
30537
- try {
30538
- unlinkSync(join(dir, marker));
30539
- } catch {}
30540
- lostRaces += 1;
30541
- gateSleep(GATE_LOCK_LOST_RACE_SLEEP_MS);
30542
- continue;
30543
- }
30544
- return {
30545
- release() {
30546
- try {
30547
- rmSync(join(dir, marker), { force: true });
30548
- rmdirSync(dir);
30549
- } catch {}
30550
- },
30551
- queueWaitMs: Date.now() - startedWaitingAt,
30552
- token: marker
30553
- };
30554
- }
30555
- const held = readGateLockClaim(dir);
30556
- if (held !== null && isProcessAlive(held.claim.pid)) {
30557
- if (getEnvVar(GATE_LOCK_TOKEN_ENV) === held.marker) {
30558
- return { release() {}, queueWaitMs: Date.now() - startedWaitingAt, token: held.marker };
30559
- }
30560
- if (!holderLogged) {
30561
- holderLogged = true;
30562
- logLine(`quality gate lock: waiting for holder (wbs ${held.claim.wbs}, run ${held.claim.runId}, pid ${held.claim.pid}, cwd ${held.claim.cwd}, held ${Date.now() - held.claim.startedAt}ms)
30563
- `);
30564
- }
30565
- } else if (held !== null) {
30566
- logLine(`quality gate lock: reclaimed stale claim (pid ${held.claim.pid})
30567
- `);
30568
- try {
30569
- unlinkSync(join(dir, held.marker));
30570
- rmdirSync(dir);
30571
- } catch {}
30572
- } else {
30573
- try {
30574
- rmdirSync(dir);
30575
- graceLogged = false;
30576
- } catch {
30577
- gateSleep(pollMs);
30578
- try {
30579
- rmdirSync(dir);
30580
- graceLogged = false;
30581
- } catch {
30582
- if (!graceLogged) {
30583
- graceLogged = true;
30584
- logLine(`quality gate lock: dir has no readable claim and is not empty — waiting
30585
- `);
30586
- }
30587
- }
30588
- }
30589
- }
30590
- }
30591
- }
30592
30435
  function recomputeGateProofFingerprint(cwd, env2) {
30593
30436
  const taskSpecPath = env2.taskSpecPath ?? env2.taskFile;
30594
30437
  if (!taskSpecPath || taskSpecPath.trim() === "") {
@@ -30712,44 +30555,27 @@ function runQualityGate(mode, env2, options = {}) {
30712
30555
  appendFileSync(abs(logFile), probe.output);
30713
30556
  rmSync(abs(`${logFile}.probe`), { force: true });
30714
30557
  }
30715
- let queueWaitMs = 0;
30716
30558
  let gateRuntimeMs = 0;
30717
30559
  if (gateRc === 0) {
30718
30560
  const delayMs = retryDelayMs(env2);
30719
- const lockLine = (line) => {
30561
+ const gateRuntimeStartMs = Date.now();
30562
+ for (gateAttempt = 1;gateAttempt <= MAX_GATE_ATTEMPTS; gateAttempt++) {
30563
+ const attemptLogPath = `${logFile}.attempt-${gateAttempt}`;
30564
+ const attempt = runShellCommand(env2.qualityGateCmd ?? "", cwd);
30565
+ writeFileSync(abs(attemptLogPath), attempt.output);
30566
+ const locked = isTransientLock(attempt.output);
30567
+ appendFileSync(abs(logFile), attempt.output);
30568
+ rmSync(abs(attemptLogPath), { force: true });
30569
+ gateRc = attempt.code;
30570
+ if (gateRc === 0 || !locked || gateAttempt >= MAX_GATE_ATTEMPTS)
30571
+ break;
30572
+ const line = retryMessage(gateAttempt);
30720
30573
  process.stdout.write(line);
30721
30574
  appendFileSync(abs(logFile), line);
30722
- };
30723
- const lock = acquireGateLock(env2, lockLine);
30724
- queueWaitMs = lock.queueWaitMs;
30725
- lockLine(`quality gate lock: queueWaitMs=${queueWaitMs}
30726
- `);
30727
- const gateRuntimeStartMs = Date.now();
30728
- const previousToken = getEnvVar(GATE_LOCK_TOKEN_ENV);
30729
- if (lock.token.length > 0)
30730
- setEnvVar(GATE_LOCK_TOKEN_ENV, lock.token);
30731
- try {
30732
- for (gateAttempt = 1;gateAttempt <= MAX_GATE_ATTEMPTS; gateAttempt++) {
30733
- const attemptLogPath = `${logFile}.attempt-${gateAttempt}`;
30734
- const attempt = runShellCommand(env2.qualityGateCmd ?? "", cwd, lock.token.length > 0 ? { [GATE_LOCK_TOKEN_ENV]: lock.token } : undefined);
30735
- writeFileSync(abs(attemptLogPath), attempt.output);
30736
- const locked = isTransientLock(attempt.output);
30737
- appendFileSync(abs(logFile), attempt.output);
30738
- rmSync(abs(attemptLogPath), { force: true });
30739
- gateRc = attempt.code;
30740
- if (gateRc === 0 || !locked || gateAttempt >= MAX_GATE_ATTEMPTS)
30741
- break;
30742
- const line = retryMessage(gateAttempt);
30743
- process.stdout.write(line);
30744
- appendFileSync(abs(logFile), line);
30745
- gateSleep(delayMs);
30746
- }
30747
- } finally {
30748
- setEnvVar(GATE_LOCK_TOKEN_ENV, previousToken);
30749
- lock.release();
30575
+ gateSleep(delayMs);
30750
30576
  }
30751
30577
  gateRuntimeMs = Date.now() - gateRuntimeStartMs;
30752
- appendFileSync(abs(logFile), `quality gate lock: queueWaitMs=${queueWaitMs} gateRuntimeMs=${gateRuntimeMs}
30578
+ appendFileSync(abs(logFile), `gate runtime: ${gateRuntimeMs}ms
30753
30579
  `);
30754
30580
  }
30755
30581
  if (gateRc !== 0) {
@@ -30802,7 +30628,6 @@ function runQualityGate(mode, env2, options = {}) {
30802
30628
  }
30803
30629
  ],
30804
30630
  completedAt: new Date().toISOString(),
30805
- queueWaitMs,
30806
30631
  gateRuntimeMs
30807
30632
  });
30808
30633
  writeFileSync(abs(receiptFile), `${JSON.stringify(receipt, null, 2)}
@@ -30834,19 +30659,12 @@ export {
30834
30659
  isTransientLock,
30835
30660
  extractFindings,
30836
30661
  buildReceipt,
30837
- acquireGateLock,
30838
30662
  RETRY_DELAY_MS_ENV,
30839
30663
  RETRY_DELAY_MS_DEFAULT,
30840
30664
  RECEIPT_SCHEMA_VERSION,
30841
30665
  MAX_GATE_ATTEMPTS,
30842
30666
  MAX_FINDINGS,
30843
30667
  LOCKED_PATTERN,
30844
- GATE_LOCK_TOKEN_ENV,
30845
- GATE_LOCK_POLL_MS_ENV,
30846
- GATE_LOCK_POLL_MS_DEFAULT,
30847
- GATE_LOCK_OFF_ENV,
30848
- GATE_LOCK_MKDIR_HOLD_MS_ENV,
30849
- GATE_LOCK_DIR_ENV,
30850
30668
  FINDINGS_PATTERN,
30851
30669
  COVERAGE_ROW_PATTERN
30852
30670
  };