@gobing-ai/spur 0.3.30 → 0.3.31

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 (68) hide show
  1. package/config/rules/strict/runtime-boundaries.yaml +2 -1
  2. package/config/workflows/basic.yaml +92 -14
  3. package/config/workflows/docs-pipeline.yaml +71 -25
  4. package/config/workflows/feature-dev.yaml +104 -35
  5. package/config/workflows/feature-lifecycle.yaml +10 -2
  6. package/config/workflows/idea-pipeline.yaml +118 -54
  7. package/config/workflows/planning-pipeline.yaml +78 -30
  8. package/config/workflows/task-lifecycle.yaml +10 -2
  9. package/config/workflows/task-pipeline.yaml +214 -56
  10. package/config/workflows/wayfinder-resolution.yaml +64 -27
  11. package/config/workflows/wrapup-pipeline.yaml +79 -39
  12. package/package.json +9 -9
  13. package/schemas/state-machine-workflow.schema.json +5 -0
  14. package/spur.js +1210 -677
  15. package/web/_astro/BoardApp.CBVEjvSW.js +1 -0
  16. package/web/_astro/{BoardApp.BwAdAgK9.js → BoardApp.CyyIiK76.js} +74 -74
  17. package/web/_astro/TaskDetail.BfUuRsfM.js +1 -0
  18. package/web/_astro/{arc.CO-I_PZe.js → arc.C7fql4LL.js} +1 -1
  19. package/web/_astro/{architectureDiagram-3BPJPVTR.Si-A1Ncl.js → architectureDiagram-3BPJPVTR.IJPsRX-V.js} +1 -1
  20. package/web/_astro/{blockDiagram-GPEHLZMM.CeNy_ta6.js → blockDiagram-GPEHLZMM.B1AUwBxq.js} +1 -1
  21. package/web/_astro/{c4Diagram-AAUBKEIU.BgN_scEU.js → c4Diagram-AAUBKEIU.BuSJPR3z.js} +1 -1
  22. package/web/_astro/channel.D3uZSASb.js +1 -0
  23. package/web/_astro/{chunk-2J33WTMH.C3oDtmdi.js → chunk-2J33WTMH.CaOPTr9l.js} +1 -1
  24. package/web/_astro/{chunk-4BX2VUAB.Bv8Fxh4H.js → chunk-4BX2VUAB.DQzxExn8.js} +1 -1
  25. package/web/_astro/{chunk-55IACEB6.BT-TqtV6.js → chunk-55IACEB6.IIb103c7.js} +1 -1
  26. package/web/_astro/{chunk-727SXJPM.DkGMsI0B.js → chunk-727SXJPM.DOYz1K1b.js} +1 -1
  27. package/web/_astro/{chunk-AQP2D5EJ.B_-SqGnF.js → chunk-AQP2D5EJ.CFcfW-wt.js} +1 -1
  28. package/web/_astro/{chunk-FMBD7UC4.DwR3skMv.js → chunk-FMBD7UC4.C7Hn0jo3.js} +1 -1
  29. package/web/_astro/{chunk-ND2GUHAM.BaTQutFl.js → chunk-ND2GUHAM.Ba83VQ1m.js} +1 -1
  30. package/web/_astro/{chunk-QZHKN3VN.BJMSqqJp.js → chunk-QZHKN3VN.CizNbIIP.js} +1 -1
  31. package/web/_astro/{classDiagram-4FO5ZUOK.SaqCNUPF.js → classDiagram-4FO5ZUOK.2NYYPXHq.js} +1 -1
  32. package/web/_astro/{classDiagram-v2-Q7XG4LA2.SaqCNUPF.js → classDiagram-v2-Q7XG4LA2.2NYYPXHq.js} +1 -1
  33. package/web/_astro/{cose-bilkent-S5V4N54A.BkmjA_E2.js → cose-bilkent-S5V4N54A.DwBqVzml.js} +1 -1
  34. package/web/_astro/{dagre-BM42HDAG.CNUvWhrX.js → dagre-BM42HDAG.DqnYsHWG.js} +1 -1
  35. package/web/_astro/{diagram-2AECGRRQ.C68Cg9uE.js → diagram-2AECGRRQ.D8TKhgy-.js} +1 -1
  36. package/web/_astro/{diagram-5GNKFQAL.DbHkPLEn.js → diagram-5GNKFQAL.BUD6Prj5.js} +1 -1
  37. package/web/_astro/{diagram-KO2AKTUF.Dt0EdErs.js → diagram-KO2AKTUF.Cvg7hmND.js} +1 -1
  38. package/web/_astro/{diagram-LMA3HP47.Bixs6mnm.js → diagram-LMA3HP47.FUG_B9eS.js} +1 -1
  39. package/web/_astro/{diagram-OG6HWLK6.B4KBI6KT.js → diagram-OG6HWLK6.XsBZQ0hQ.js} +1 -1
  40. package/web/_astro/{erDiagram-TEJ5UH35.C_4i9Xvx.js → erDiagram-TEJ5UH35.M_LSGgLQ.js} +1 -1
  41. package/web/_astro/{flowDiagram-I6XJVG4X.CfGFczAY.js → flowDiagram-I6XJVG4X.DZikZBRa.js} +1 -1
  42. package/web/_astro/{ganttDiagram-6RSMTGT7.C2AIvtmg.js → ganttDiagram-6RSMTGT7.DTKuEmXY.js} +1 -1
  43. package/web/_astro/{gitGraphDiagram-PVQCEYII.HlXuGqQg.js → gitGraphDiagram-PVQCEYII.Dt-E9XmY.js} +1 -1
  44. package/web/_astro/index.yAse9IaO.css +1 -0
  45. package/web/_astro/{infoDiagram-5YYISTIA.BWQJsJ4Z.js → infoDiagram-5YYISTIA.D5snevU1.js} +1 -1
  46. package/web/_astro/{ishikawaDiagram-YF4QCWOH.CCHgIHik.js → ishikawaDiagram-YF4QCWOH.DmXdBf9W.js} +1 -1
  47. package/web/_astro/{journeyDiagram-JHISSGLW.D9M6YwOJ.js → journeyDiagram-JHISSGLW.HPJSRkkU.js} +1 -1
  48. package/web/_astro/{kanban-definition-UN3LZRKU.K20D-a1_.js → kanban-definition-UN3LZRKU.BxCqCnL1.js} +1 -1
  49. package/web/_astro/{linear.DeP5Qsol.js → linear.BnXQUpS-.js} +1 -1
  50. package/web/_astro/{mermaid.core.ClzxNMPU.js → mermaid.core.D-ZeOmpg.js} +4 -4
  51. package/web/_astro/{mindmap-definition-RKZ34NQL.CGn9RUNj.js → mindmap-definition-RKZ34NQL.DxrftiFR.js} +1 -1
  52. package/web/_astro/{pieDiagram-4H26LBE5.CoA92Csb.js → pieDiagram-4H26LBE5.D-ZcWxwg.js} +1 -1
  53. package/web/_astro/{quadrantDiagram-W4KKPZXB.CJ_UPjM1.js → quadrantDiagram-W4KKPZXB.C-dVJ7GW.js} +1 -1
  54. package/web/_astro/{requirementDiagram-4Y6WPE33.KkEPNNUU.js → requirementDiagram-4Y6WPE33.lalE_R8X.js} +1 -1
  55. package/web/_astro/{sankeyDiagram-5OEKKPKP.CoCWbQgh.js → sankeyDiagram-5OEKKPKP.C4uPynAF.js} +1 -1
  56. package/web/_astro/{sequenceDiagram-3UESZ5HK.DUFpV3EP.js → sequenceDiagram-3UESZ5HK.uBOenkqh.js} +1 -1
  57. package/web/_astro/{stateDiagram-AJRCARHV.CgWX0_9m.js → stateDiagram-AJRCARHV.CQOusSP2.js} +1 -1
  58. package/web/_astro/{stateDiagram-v2-BHNVJYJU.BKUXeGSf.js → stateDiagram-v2-BHNVJYJU.Bw0ZdjYb.js} +1 -1
  59. package/web/_astro/{timeline-definition-PNZ67QCA.CXayAguY.js → timeline-definition-PNZ67QCA.DbkPA5ce.js} +1 -1
  60. package/web/_astro/{vennDiagram-CIIHVFJN.DPak_Elh.js → vennDiagram-CIIHVFJN.CIKhzwoA.js} +1 -1
  61. package/web/_astro/{wardley-L42UT6IY.t3ZlDKd0.js → wardley-L42UT6IY.0P-tqaFs.js} +1 -1
  62. package/web/_astro/{wardleyDiagram-YWT4CUSO.CwPSVASQ.js → wardleyDiagram-YWT4CUSO.DrwTvM_M.js} +1 -1
  63. package/web/_astro/{xychartDiagram-2RQKCTM6.CJfrQgpF.js → xychartDiagram-2RQKCTM6.BgJsQVms.js} +1 -1
  64. package/web/index.html +2 -2
  65. package/web/_astro/BoardApp.Bk3T0o6s.js +0 -1
  66. package/web/_astro/TaskDetail.L36slEqE.js +0 -1
  67. package/web/_astro/channel.CYdGnFHM.js +0 -1
  68. package/web/_astro/index.D5Wqk2Tw.css +0 -1
package/spur.js CHANGED
@@ -47,7 +47,7 @@ var __export = (target, all) => {
47
47
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
48
48
  var __require = import.meta.require;
49
49
 
50
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.16/node_modules/@gobing-ai/ts-utils/dist/errors.js
50
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.18/node_modules/@gobing-ai/ts-utils/dist/errors.js
51
51
  var ErrorCode;
52
52
  var init_errors = __esm(() => {
53
53
  ErrorCode = {
@@ -58,7 +58,7 @@ var init_errors = __esm(() => {
58
58
  };
59
59
  });
60
60
 
61
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.16/node_modules/@gobing-ai/ts-utils/dist/api-response.js
61
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.18/node_modules/@gobing-ai/ts-utils/dist/api-response.js
62
62
  var API_ERROR_CODES, ERROR_CODE_TO_HTTP, CLIENT_SAFE_CODES;
63
63
  var init_api_response = __esm(() => {
64
64
  init_errors();
@@ -81,10 +81,10 @@ var init_api_response = __esm(() => {
81
81
  CLIENT_SAFE_CODES = new Set([ErrorCode.NotFound, ErrorCode.Validation, ErrorCode.Conflict]);
82
82
  });
83
83
 
84
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.16/node_modules/@gobing-ai/ts-utils/dist/cursor.js
84
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.18/node_modules/@gobing-ai/ts-utils/dist/cursor.js
85
85
  var init_cursor = () => {};
86
86
 
87
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.16/node_modules/@gobing-ai/ts-utils/dist/object.js
87
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.18/node_modules/@gobing-ai/ts-utils/dist/object.js
88
88
  function isPlainObject(value) {
89
89
  return typeof value === "object" && value !== null && !Array.isArray(value);
90
90
  }
@@ -102,7 +102,7 @@ function deepMerge(target, source) {
102
102
  return result;
103
103
  }
104
104
 
105
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.16/node_modules/@gobing-ai/ts-utils/dist/output.js
105
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.18/node_modules/@gobing-ai/ts-utils/dist/output.js
106
106
  function processStream(name) {
107
107
  const proc = globalThis.process;
108
108
  const stream = proc?.[name];
@@ -123,7 +123,7 @@ function echoError(message, target = defaultStderrTarget ?? processStream("stder
123
123
  }
124
124
  var defaultStdoutTarget, defaultStderrTarget;
125
125
 
126
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.16/node_modules/@gobing-ai/ts-utils/dist/index.js
126
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.18/node_modules/@gobing-ai/ts-utils/dist/index.js
127
127
  var init_dist = __esm(() => {
128
128
  init_api_response();
129
129
  init_cursor();
@@ -21745,7 +21745,7 @@ var init_zod = __esm(() => {
21745
21745
  init_external();
21746
21746
  });
21747
21747
 
21748
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+a1f7d493e005a6ca/node_modules/@gobing-ai/ts-runtime/dist/config.js
21748
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+3ba223a3e166c92f/node_modules/@gobing-ai/ts-runtime/dist/config.js
21749
21749
  function getProcessEnv() {
21750
21750
  return process.env;
21751
21751
  }
@@ -21823,7 +21823,7 @@ var init_config = __esm(() => {
21823
21823
  };
21824
21824
  });
21825
21825
 
21826
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+a1f7d493e005a6ca/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
21826
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+3ba223a3e166c92f/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
21827
21827
  import { appendFileSync, cpSync, createReadStream, createWriteStream, existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "fs";
21828
21828
  import { dirname, resolve as resolvePath } from "path";
21829
21829
  function createNodeFileSystem(root, paths) {
@@ -21910,7 +21910,7 @@ function findProjectRoot(startDir) {
21910
21910
  }
21911
21911
  var init_file_system_node = () => {};
21912
21912
 
21913
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+a1f7d493e005a6ca/node_modules/@gobing-ai/ts-runtime/dist/db-errors.js
21913
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+3ba223a3e166c92f/node_modules/@gobing-ai/ts-runtime/dist/db-errors.js
21914
21914
  var DbModuleNotInstalledError;
21915
21915
  var init_db_errors = __esm(() => {
21916
21916
  DbModuleNotInstalledError = class DbModuleNotInstalledError extends Error {
@@ -29101,7 +29101,7 @@ var init_execa = __esm(() => {
29101
29101
  } = getIpcExport());
29102
29102
  });
29103
29103
 
29104
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+a1f7d493e005a6ca/node_modules/@gobing-ai/ts-runtime/dist/process-executor.js
29104
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+3ba223a3e166c92f/node_modules/@gobing-ai/ts-runtime/dist/process-executor.js
29105
29105
  import { isatty } from "tty";
29106
29106
 
29107
29107
  class NodeProcessExecutor {
@@ -29144,6 +29144,14 @@ class NodeProcessExecutor {
29144
29144
  });
29145
29145
  try {
29146
29146
  const subprocess = execa(options.command, args, execaOptions);
29147
+ if (subprocess.pid !== undefined) {
29148
+ this.config.registry?.update(registryId, { pid: subprocess.pid });
29149
+ if (options.onSpawn !== undefined) {
29150
+ try {
29151
+ options.onSpawn(subprocess.pid);
29152
+ } catch {}
29153
+ }
29154
+ }
29147
29155
  const stopGroupCancellation = observeProcessGroupCancellation(subprocess, options.signal);
29148
29156
  observeOutput(subprocess.stdout, "stdout", options.onOutput);
29149
29157
  observeOutput(subprocess.stderr, "stderr", options.onOutput);
@@ -29431,7 +29439,7 @@ var init_process_executor = __esm(() => {
29431
29439
  init_execa();
29432
29440
  });
29433
29441
 
29434
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+a1f7d493e005a6ca/node_modules/@gobing-ai/ts-runtime/dist/runtime-node-bun.js
29442
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+3ba223a3e166c92f/node_modules/@gobing-ai/ts-runtime/dist/runtime-node-bun.js
29435
29443
  function getNodeFileSystem() {
29436
29444
  if (!_nodeFileSystem)
29437
29445
  _nodeFileSystem = createNodeFileSystem();
@@ -29491,7 +29499,7 @@ var init_runtime_node_bun = __esm(() => {
29491
29499
  };
29492
29500
  });
29493
29501
 
29494
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+a1f7d493e005a6ca/node_modules/@gobing-ai/ts-runtime/dist/context.js
29502
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+3ba223a3e166c92f/node_modules/@gobing-ai/ts-runtime/dist/context.js
29495
29503
  class RuntimeContext {
29496
29504
  scope;
29497
29505
  runtimeName;
@@ -29561,7 +29569,7 @@ var init_context = __esm(() => {
29561
29569
  init_runtime_node_bun();
29562
29570
  });
29563
29571
 
29564
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+a1f7d493e005a6ca/node_modules/@gobing-ai/ts-runtime/dist/path.js
29572
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+3ba223a3e166c92f/node_modules/@gobing-ai/ts-runtime/dist/path.js
29565
29573
  function normalizeSeparators(path6) {
29566
29574
  return path6.replaceAll("\\", "/");
29567
29575
  }
@@ -29622,17 +29630,17 @@ var init_path = __esm(() => {
29622
29630
  SEP = globalThis.process?.platform === "win32" ? "\\" : "/";
29623
29631
  });
29624
29632
 
29625
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+a1f7d493e005a6ca/node_modules/@gobing-ai/ts-runtime/dist/schema-validation.js
29633
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+3ba223a3e166c92f/node_modules/@gobing-ai/ts-runtime/dist/schema-validation.js
29626
29634
  var REMOTE_SCHEMA_MAX_BYTES;
29627
29635
  var init_schema_validation = __esm(() => {
29628
29636
  init_dist2();
29629
29637
  REMOTE_SCHEMA_MAX_BYTES = 5 * 1024 * 1024;
29630
29638
  });
29631
29639
 
29632
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+a1f7d493e005a6ca/node_modules/@gobing-ai/ts-runtime/dist/types.js
29640
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+3ba223a3e166c92f/node_modules/@gobing-ai/ts-runtime/dist/types.js
29633
29641
  var init_types = () => {};
29634
29642
 
29635
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+a1f7d493e005a6ca/node_modules/@gobing-ai/ts-runtime/dist/index.js
29643
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+3ba223a3e166c92f/node_modules/@gobing-ai/ts-runtime/dist/index.js
29636
29644
  var init_dist3 = __esm(() => {
29637
29645
  init_config();
29638
29646
  init_context();
@@ -29641,7 +29649,7 @@ var init_dist3 = __esm(() => {
29641
29649
  init_types();
29642
29650
  });
29643
29651
 
29644
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+a1f7d493e005a6ca/node_modules/@gobing-ai/ts-runtime/dist/bun-sqlite.js
29652
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+3ba223a3e166c92f/node_modules/@gobing-ai/ts-runtime/dist/bun-sqlite.js
29645
29653
  import { Database } from "bun:sqlite";
29646
29654
  var init_bun_sqlite = () => {};
29647
29655
 
@@ -33833,7 +33841,7 @@ var init_bun_sqlite2 = __esm(() => {
33833
33841
  init_session2();
33834
33842
  });
33835
33843
 
33836
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/schema/inbox-messages.js
33844
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/schema/inbox-messages.js
33837
33845
  var inboxMessages;
33838
33846
  var init_inbox_messages = __esm(() => {
33839
33847
  init_sqlite_core();
@@ -33852,7 +33860,7 @@ var init_inbox_messages = __esm(() => {
33852
33860
  }, (table2) => [index("idx_inbox_messages_to_status").on(table2.toId, table2.status)]);
33853
33861
  });
33854
33862
 
33855
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/schema/common.js
33863
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/schema/common.js
33856
33864
  function nowTimestamp() {
33857
33865
  return Date.now();
33858
33866
  }
@@ -33881,7 +33889,7 @@ var init_common3 = __esm(() => {
33881
33889
  appendOnlyColumns = buildAppendOnlyColumns();
33882
33890
  });
33883
33891
 
33884
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/schema/queue-jobs.js
33892
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/schema/queue-jobs.js
33885
33893
  var queueJobs;
33886
33894
  var init_queue_jobs = __esm(() => {
33887
33895
  init_sqlite_core();
@@ -33901,7 +33909,7 @@ var init_queue_jobs = __esm(() => {
33901
33909
  }, (table2) => [index("queue_jobs_ready_idx").on(table2.status, table2.nextRetryAt, table2.createdAt)]);
33902
33910
  });
33903
33911
 
33904
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/schema/runtime.js
33912
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/schema/runtime.js
33905
33913
  var exports_runtime = {};
33906
33914
  __export(exports_runtime, {
33907
33915
  queueJobs: () => queueJobs,
@@ -33912,7 +33920,7 @@ var init_runtime = __esm(() => {
33912
33920
  init_queue_jobs();
33913
33921
  });
33914
33922
 
33915
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/adapters/bun-sqlite.js
33923
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/adapters/bun-sqlite.js
33916
33924
  var exports_bun_sqlite = {};
33917
33925
  __export(exports_bun_sqlite, {
33918
33926
  BunSqliteAdapter: () => BunSqliteAdapter
@@ -34203,7 +34211,7 @@ var init_d1 = __esm(() => {
34203
34211
  init_session3();
34204
34212
  });
34205
34213
 
34206
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/adapters/d1.js
34214
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/adapters/d1.js
34207
34215
  var exports_d1 = {};
34208
34216
  __export(exports_d1, {
34209
34217
  D1Adapter: () => D1Adapter
@@ -34267,7 +34275,7 @@ var init_d12 = __esm(() => {
34267
34275
  init_runtime();
34268
34276
  });
34269
34277
 
34270
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/adapter.js
34278
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/adapter.js
34271
34279
  async function createDbAdapter(config3) {
34272
34280
  switch (config3.driver) {
34273
34281
  case "bun-sqlite": {
@@ -34307,7 +34315,7 @@ var init_drizzle_orm = __esm(() => {
34307
34315
  init_view_common();
34308
34316
  });
34309
34317
 
34310
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/query-spec.js
34318
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/query-spec.js
34311
34319
  function compilePredicate(predicate) {
34312
34320
  if ("and" in predicate) {
34313
34321
  const parts = predicate.and.map(compilePredicate).filter((p) => p !== undefined);
@@ -34345,7 +34353,7 @@ var init_query_spec = __esm(() => {
34345
34353
  };
34346
34354
  });
34347
34355
 
34348
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/base-dao.js
34356
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/base-dao.js
34349
34357
  function asSelectQuery(query) {
34350
34358
  return query;
34351
34359
  }
@@ -34387,7 +34395,7 @@ var init_base_dao = __esm(() => {
34387
34395
  init_query_spec();
34388
34396
  });
34389
34397
 
34390
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/embedded-migrations.js
34398
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/embedded-migrations.js
34391
34399
  var embeddedMigrations;
34392
34400
  var init_embedded_migrations = __esm(() => {
34393
34401
  embeddedMigrations = [
@@ -34419,7 +34427,7 @@ var init_embedded_migrations = __esm(() => {
34419
34427
  ];
34420
34428
  });
34421
34429
 
34422
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/entity-dao.js
34430
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/entity-dao.js
34423
34431
  var EntityDao;
34424
34432
  var init_entity_dao = __esm(() => {
34425
34433
  init_drizzle_orm();
@@ -34581,7 +34589,7 @@ var init_entity_dao = __esm(() => {
34581
34589
  };
34582
34590
  });
34583
34591
 
34584
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/inbox-message-dao.js
34592
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/inbox-message-dao.js
34585
34593
  function isPromiseLike(value) {
34586
34594
  return value !== null && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
34587
34595
  }
@@ -34754,7 +34762,7 @@ var init_migrator2 = __esm(() => {
34754
34762
  init_migrator();
34755
34763
  });
34756
34764
 
34757
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/migrate.js
34765
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/migrate.js
34758
34766
  async function ensureJournalTable(adapter, table3) {
34759
34767
  await adapter.exec(`CREATE TABLE IF NOT EXISTS "${table3}" (` + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "hash text NOT NULL, " + "created_at numeric" + ")");
34760
34768
  }
@@ -34829,7 +34837,7 @@ var init_migrate = __esm(() => {
34829
34837
  init_embedded_migrations();
34830
34838
  });
34831
34839
 
34832
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/queue-job-dao.js
34840
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/queue-job-dao.js
34833
34841
  var QueueJobDao;
34834
34842
  var init_queue_job_dao = __esm(() => {
34835
34843
  init_drizzle_orm();
@@ -34970,7 +34978,7 @@ var init_queue_job_dao = __esm(() => {
34970
34978
  };
34971
34979
  });
34972
34980
 
34973
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/index.js
34981
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/index.js
34974
34982
  var exports_dist = {};
34975
34983
  __export(exports_dist, {
34976
34984
  embeddedMigrations: () => embeddedMigrations,
@@ -37275,7 +37283,7 @@ function buildConfigFromEnv(env = process.env) {
37275
37283
  }
37276
37284
  });
37277
37285
  }
37278
- var SPUR_ENV_VARS, SPUR_LOG_LEVELS, DEFAULT_TASKS_DIR = "docs/tasks", DEFAULT_FEATURES_DIR = "docs/features", DEFAULT_DATABASE_URL = ".spur/spur.db", IN_MEMORY_DATABASE_URL = ":memory:", folderConfigSchema, tasksConfigSchema, featuresConfigSchema, EXECUTOR_CAPABILITY_TIERS, executorCapabilityTierSchema, AgentExecutorConfigSchema, AGENT_ID_REGEX, TeamMemberConfigSchema, TeamConfigSchema, AgentOutputConfigSchema, AgentConfigSchema, RulesConfigSchema, WorkflowsConfigSchema, RedactionConfigSchema, spurConfigSchema, configSchema2;
37286
+ var SPUR_ENV_VARS, SPUR_LOG_LEVELS, DEFAULT_TASKS_DIR = "docs/tasks", DEFAULT_FEATURES_DIR = "docs/features", DEFAULT_DATABASE_URL = ".spur/spur.db", IN_MEMORY_DATABASE_URL = ":memory:", folderConfigSchema, tasksConfigSchema, featuresConfigSchema, EXECUTOR_CAPABILITY_TIERS, executorCapabilityTierSchema, AgentExecutorConfigSchema, AGENT_ID_REGEX, TeamMemberConfigSchema, TeamConfigSchema, AgentOutputConfigSchema, AgentConfigSchema, RulesConfigSchema, WorkflowsConfigSchema, WorkflowConfigSchema, RedactionConfigSchema, spurConfigSchema, configSchema2;
37279
37287
  var init_src = __esm(() => {
37280
37288
  init_zod();
37281
37289
  init_finding_codes();
@@ -37419,6 +37427,9 @@ var init_src = __esm(() => {
37419
37427
  WorkflowsConfigSchema = exports_external.object({
37420
37428
  paths: exports_external.array(exports_external.string()).optional()
37421
37429
  });
37430
+ WorkflowConfigSchema = exports_external.object({
37431
+ logRetentionDays: exports_external.number().int().positive().default(30)
37432
+ });
37422
37433
  RedactionConfigSchema = exports_external.object({
37423
37434
  enabled: exports_external.boolean().optional()
37424
37435
  });
@@ -37428,6 +37439,7 @@ var init_src = __esm(() => {
37428
37439
  agent: AgentConfigSchema.optional(),
37429
37440
  rules: RulesConfigSchema.optional(),
37430
37441
  workflows: WorkflowsConfigSchema.optional(),
37442
+ workflow: WorkflowConfigSchema.optional(),
37431
37443
  redaction: RedactionConfigSchema.optional(),
37432
37444
  tasks: tasksConfigSchema.optional(),
37433
37445
  features: featuresConfigSchema.optional()
@@ -37452,7 +37464,7 @@ var init_src = __esm(() => {
37452
37464
  });
37453
37465
  });
37454
37466
 
37455
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/config.js
37467
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/config.js
37456
37468
  function parseYamlObject(text3) {
37457
37469
  let parsed;
37458
37470
  try {
@@ -37579,7 +37591,7 @@ var init_config2 = __esm(() => {
37579
37591
  };
37580
37592
  });
37581
37593
 
37582
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
37594
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
37583
37595
  import { appendFileSync as appendFileSync3, cpSync as cpSync2, createReadStream as createReadStream3, createWriteStream as createWriteStream3, existsSync as existsSync2, mkdirSync as mkdirSync2, readdirSync as readdirSync2, readFileSync as readFileSync4, realpathSync as realpathSync2, renameSync as renameSync2, rmSync as rmSync2, statSync as statSync3, writeFileSync as writeFileSync3 } from "fs";
37584
37596
  import { dirname as dirname2, resolve as resolvePath3 } from "path";
37585
37597
  function createNodeFileSystem3(root, paths) {
@@ -37666,7 +37678,7 @@ function findProjectRoot3(startDir) {
37666
37678
  }
37667
37679
  var init_file_system_node2 = () => {};
37668
37680
 
37669
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/db-errors.js
37681
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/db-errors.js
37670
37682
  var D1NotConfiguredError2, DbModuleNotInstalledError3;
37671
37683
  var init_db_errors2 = __esm(() => {
37672
37684
  D1NotConfiguredError2 = class D1NotConfiguredError2 extends Error {
@@ -37683,7 +37695,7 @@ var init_db_errors2 = __esm(() => {
37683
37695
  };
37684
37696
  });
37685
37697
 
37686
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/file-system-cf.js
37698
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/file-system-cf.js
37687
37699
  function createCfFileSystem2() {
37688
37700
  return {
37689
37701
  getProjectRoot: () => "/bundle",
@@ -37722,7 +37734,7 @@ function createCfFileSystem2() {
37722
37734
  }
37723
37735
  var UNSUPPORTED = "FileSystem is not available on Cloudflare Workers. Use D1, KV, or R2 for persistent storage.";
37724
37736
 
37725
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/runtime-cf.js
37737
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/runtime-cf.js
37726
37738
  var exports_runtime_cf = {};
37727
37739
  __export(exports_runtime_cf, {
37728
37740
  cloudflareWorkersFactory: () => cloudflareWorkersFactory2
@@ -37760,7 +37772,7 @@ var init_runtime_cf = __esm(() => {
37760
37772
  };
37761
37773
  });
37762
37774
 
37763
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/process-executor.js
37775
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/process-executor.js
37764
37776
  import { isatty as isatty2 } from "tty";
37765
37777
 
37766
37778
  class NodeProcessExecutor3 {
@@ -37803,6 +37815,14 @@ class NodeProcessExecutor3 {
37803
37815
  });
37804
37816
  try {
37805
37817
  const subprocess = execa(options.command, args, execaOptions);
37818
+ if (subprocess.pid !== undefined) {
37819
+ this.config.registry?.update(registryId, { pid: subprocess.pid });
37820
+ if (options.onSpawn !== undefined) {
37821
+ try {
37822
+ options.onSpawn(subprocess.pid);
37823
+ } catch {}
37824
+ }
37825
+ }
37806
37826
  const stopGroupCancellation = observeProcessGroupCancellation2(subprocess, options.signal);
37807
37827
  observeOutput2(subprocess.stdout, "stdout", options.onOutput);
37808
37828
  observeOutput2(subprocess.stderr, "stderr", options.onOutput);
@@ -38137,7 +38157,7 @@ var init_process_executor2 = __esm(() => {
38137
38157
  ProcessExecutor2 = NodeProcessExecutor3;
38138
38158
  });
38139
38159
 
38140
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/runtime-node-bun.js
38160
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/runtime-node-bun.js
38141
38161
  var exports_runtime_node_bun = {};
38142
38162
  __export(exports_runtime_node_bun, {
38143
38163
  nodeBunFactory: () => nodeBunFactory3,
@@ -38205,7 +38225,7 @@ var init_runtime_node_bun2 = __esm(() => {
38205
38225
  };
38206
38226
  });
38207
38227
 
38208
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/platform.js
38228
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/platform.js
38209
38229
  function isCloudflareWorkerRuntime2() {
38210
38230
  return globalThis.navigator?.userAgent?.startsWith("Cloudflare-Workers") ?? false;
38211
38231
  }
@@ -38235,7 +38255,7 @@ function _resetRuntimeFactory2() {
38235
38255
  }
38236
38256
  var _factory, _runtimeName;
38237
38257
 
38238
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/context.js
38258
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/context.js
38239
38259
  class RuntimeContext2 {
38240
38260
  scope;
38241
38261
  runtimeName;
@@ -38325,7 +38345,7 @@ var init_context2 = __esm(() => {
38325
38345
  init_runtime_node_bun2();
38326
38346
  });
38327
38347
 
38328
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/path.js
38348
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/path.js
38329
38349
  function normalizeSeparators2(path7) {
38330
38350
  return path7.replaceAll("\\", "/");
38331
38351
  }
@@ -38448,7 +38468,7 @@ var init_path2 = __esm(() => {
38448
38468
  SEP2 = globalThis.process?.platform === "win32" ? "\\" : "/";
38449
38469
  });
38450
38470
 
38451
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/fs.js
38471
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/fs.js
38452
38472
  async function ensureDirForFile2(path7, fs2 = createNodeFileSystem3()) {
38453
38473
  await fs2.ensureDir(dirnamePath(path7));
38454
38474
  }
@@ -38499,7 +38519,7 @@ var init_fs = __esm(() => {
38499
38519
  init_path2();
38500
38520
  });
38501
38521
 
38502
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/process-registry.js
38522
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/process-registry.js
38503
38523
  function allocateId() {
38504
38524
  nextIdSeq += 1;
38505
38525
  return `pe_${Date.now().toString(36)}_${nextIdSeq.toString(36)}`;
@@ -38623,7 +38643,7 @@ function createInMemoryProcessRegistry2(options) {
38623
38643
  }
38624
38644
  var nextIdSeq = 0;
38625
38645
 
38626
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/runtime-paths.js
38646
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/runtime-paths.js
38627
38647
  function ambientRuntimePaths2() {
38628
38648
  const cwd = getProcessCwd2();
38629
38649
  return { cwd, home: getHomeDir() ?? cwd };
@@ -38633,7 +38653,7 @@ var init_runtime_paths = __esm(() => {
38633
38653
  init_path2();
38634
38654
  });
38635
38655
 
38636
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/schema-validation.js
38656
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/schema-validation.js
38637
38657
  async function loadStructuredConfig(path7, options = {}) {
38638
38658
  const content = await (options.fileSystem ?? createNodeFileSystem3()).readFile(path7);
38639
38659
  return await parseStructuredConfig(content, path7, options);
@@ -38910,10 +38930,10 @@ var init_schema_validation2 = __esm(() => {
38910
38930
  defaultResolve = typeof Bun !== "undefined" ? (specifier, from) => Bun.resolveSync(specifier, from) : undefined;
38911
38931
  });
38912
38932
 
38913
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/types.js
38933
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/types.js
38914
38934
  var init_types2 = () => {};
38915
38935
 
38916
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/index.js
38936
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/index.js
38917
38937
  var exports_dist2 = {};
38918
38938
  __export(exports_dist2, {
38919
38939
  writeJsonFile: () => writeJsonFile2,
@@ -41064,7 +41084,7 @@ var init_mod = __esm(() => {
41064
41084
  init_config3();
41065
41085
  });
41066
41086
 
41067
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/logger.js
41087
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/logger.js
41068
41088
  function toLogTapeLevel(level) {
41069
41089
  return level === "warn" ? "warning" : level;
41070
41090
  }
@@ -42617,7 +42637,7 @@ var require_src = __commonJS((exports) => {
42617
42637
  };
42618
42638
  });
42619
42639
 
42620
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/telemetry/sdk.js
42640
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/telemetry/sdk.js
42621
42641
  function getTelemetryConfig(configPartial = {}) {
42622
42642
  return {
42623
42643
  enabled: configPartial.enabled ?? CONFIG_DEFAULTS.enabled,
@@ -42653,7 +42673,7 @@ var init_sdk = __esm(() => {
42653
42673
  resolvedConfig = getTelemetryConfig();
42654
42674
  });
42655
42675
 
42656
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/telemetry/tracing.js
42676
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/telemetry/tracing.js
42657
42677
  function isSuppressed(tracer2) {
42658
42678
  return tracer2 === undefined && !getResolvedConfig().enabled;
42659
42679
  }
@@ -42693,7 +42713,7 @@ var init_tracing2 = __esm(() => {
42693
42713
  import_api2 = __toESM(require_src(), 1);
42694
42714
  });
42695
42715
 
42696
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/telemetry/metrics.js
42716
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/telemetry/metrics.js
42697
42717
  function getMeter() {
42698
42718
  return import_api3.metrics.getMeter(METER_NAME, METER_VERSION);
42699
42719
  }
@@ -42790,7 +42810,7 @@ var init_metrics = __esm(() => {
42790
42810
  instruments = {};
42791
42811
  });
42792
42812
 
42793
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/event-bus/event-bus.js
42813
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/event-bus/event-bus.js
42794
42814
  function busLogger() {
42795
42815
  if (!_busLogger)
42796
42816
  _busLogger = getLogger2("event-bus");
@@ -43035,7 +43055,7 @@ var init_event_bus = __esm(() => {
43035
43055
  init_metrics();
43036
43056
  });
43037
43057
 
43038
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/event-bus/default-observers.js
43058
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/event-bus/default-observers.js
43039
43059
  function obsLogger() {
43040
43060
  if (!_obsLogger)
43041
43061
  _obsLogger = getLogger2("event-bus.observers");
@@ -43099,7 +43119,7 @@ var init_default_observers = __esm(() => {
43099
43119
  init_event_bus();
43100
43120
  });
43101
43121
 
43102
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/event-bus/file-observer.js
43122
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/event-bus/file-observer.js
43103
43123
  function parentDir(filePath) {
43104
43124
  const idx = filePath.lastIndexOf("/");
43105
43125
  return idx <= 0 ? "." : filePath.slice(0, idx);
@@ -43197,7 +43217,7 @@ var init_file_observer = __esm(() => {
43197
43217
  init_logger3();
43198
43218
  });
43199
43219
 
43200
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/internals/drain.js
43220
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/internals/drain.js
43201
43221
  function settleWithin(promise2, deadline) {
43202
43222
  const remaining = deadline - Date.now();
43203
43223
  if (remaining <= 0)
@@ -43212,7 +43232,7 @@ function settleWithin(promise2, deadline) {
43212
43232
  return settled;
43213
43233
  }
43214
43234
 
43215
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/scheduler/node.js
43235
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/scheduler/node.js
43216
43236
  function parseInterval(cron) {
43217
43237
  const trimmed = cron.trim();
43218
43238
  const num = Number(trimmed);
@@ -43305,7 +43325,7 @@ var init_node3 = __esm(() => {
43305
43325
  init_metrics();
43306
43326
  });
43307
43327
 
43308
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/scheduler-node.js
43328
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/scheduler-node.js
43309
43329
  var exports_scheduler_node = {};
43310
43330
  __export(exports_scheduler_node, {
43311
43331
  NodeSchedulerAdapter: () => NodeSchedulerAdapter
@@ -49574,6 +49594,7 @@ class AgentExecutionLifecycle {
49574
49594
  heartbeat;
49575
49595
  startedAt = 0;
49576
49596
  timeoutMs;
49597
+ pid;
49577
49598
  outputCarry = { stdout: "", stderr: "" };
49578
49599
  constructor(observer, correlation, secrets, heartbeatMs = 30000) {
49579
49600
  this.observer = observer;
@@ -49587,6 +49608,10 @@ class AgentExecutionLifecycle {
49587
49608
  get identity() {
49588
49609
  return this.correlation;
49589
49610
  }
49611
+ setPid(pid) {
49612
+ if (Number.isInteger(pid) && pid > 0)
49613
+ this.pid = pid;
49614
+ }
49590
49615
  start(detail) {
49591
49616
  this.startedAt = Date.now();
49592
49617
  this.timeoutMs = detail.timeoutMs;
@@ -49684,6 +49709,7 @@ class AgentExecutionLifecycle {
49684
49709
  runId: this.correlation.runId,
49685
49710
  executionId: this.correlation.executionId,
49686
49711
  ...this.correlation.actionId !== undefined ? { actionId: this.correlation.actionId } : {},
49712
+ ...this.pid !== undefined ? { pid: this.pid } : {},
49687
49713
  at: new Date().toISOString()
49688
49714
  };
49689
49715
  }
@@ -49723,6 +49749,436 @@ var init_agent_execution = __esm(() => {
49723
49749
  SECRET_PATTERN = /(?:sk-[a-z0-9_-]{8,}|(?:api[_-]?key|token|secret|password)\s*[:=]\s*\S+|bearer\s+\S+)/gi;
49724
49750
  });
49725
49751
 
49752
+ // ../../packages/app/src/workflow/observability.ts
49753
+ function bounded(value, maxLength = MAX_FIELD_LENGTH) {
49754
+ const redacted = value.replace(SECRET_PATTERN2, "[REDACTED]");
49755
+ return redacted.length <= maxLength ? redacted : `${redacted.slice(0, maxLength)}\u2026`;
49756
+ }
49757
+ function projectActionMetadata(kind, options) {
49758
+ if (options === undefined)
49759
+ return;
49760
+ const metadata = {};
49761
+ if (typeof options.agent === "string" && options.agent !== "")
49762
+ metadata.agent = bounded(options.agent);
49763
+ if (typeof options.model === "string" && options.model !== "")
49764
+ metadata.model = bounded(options.model);
49765
+ if (typeof options.timeoutMs === "number" && Number.isFinite(options.timeoutMs)) {
49766
+ metadata.timeoutMs = Math.max(0, options.timeoutMs);
49767
+ }
49768
+ const input = typeof options.input === "string" ? options.input.trim() : "";
49769
+ if (kind === "agent.run" && input !== "") {
49770
+ const command = input.startsWith("/") ? input.split(/\s+/, 1)[0] : undefined;
49771
+ metadata.invocation = command === undefined ? `[prompt ${input.length} chars]` : bounded(command);
49772
+ } else if (kind === "shell" && typeof options.command === "string" && options.command.trim() !== "") {
49773
+ metadata.invocation = bounded(sanitizeCommand(options.command), 80);
49774
+ } else if (kind === "note" && typeof options.message === "string" && options.message.trim() !== "") {
49775
+ metadata.invocation = bounded(options.message.trim(), 80);
49776
+ }
49777
+ return Object.keys(metadata).length === 0 ? undefined : metadata;
49778
+ }
49779
+ function sanitizeCommand(cmd) {
49780
+ const trimmed = cmd.replace(/\n+/g, " ").replace(/\s+/g, " ").trim();
49781
+ if (/(?:authorization|bearer|password|secret|token|api_key|private_key)/i.test(trimmed)) {
49782
+ return "[shell command redacted]";
49783
+ }
49784
+ return trimmed;
49785
+ }
49786
+ function projectResult(result) {
49787
+ if (result === undefined)
49788
+ return;
49789
+ if (typeof result !== "object" || result === null)
49790
+ return { usage: "unavailable" };
49791
+ const obj = result;
49792
+ const error51 = typeof obj.error === "string" ? bounded(obj.error) : undefined;
49793
+ const stderr = typeof obj.stderr === "string" && obj.stderr.trim() !== "" ? bounded(obj.stderr.trim(), 120) : undefined;
49794
+ const stdout = typeof obj.stdout === "string" && obj.stdout.trim() !== "" ? bounded(obj.stdout.trim(), 120) : undefined;
49795
+ const detail = error51 ?? stderr ?? stdout;
49796
+ return { ...detail !== undefined ? { error: detail } : {}, usage: "unavailable" };
49797
+ }
49798
+
49799
+ class ObservableWorkflowAdapter {
49800
+ inner;
49801
+ bus;
49802
+ sequences = new Map;
49803
+ workflowNames = new Map;
49804
+ actions = new Map;
49805
+ constructor(inner, bus) {
49806
+ this.inner = inner;
49807
+ this.bus = bus;
49808
+ }
49809
+ async createRun(record2) {
49810
+ await this.inner.createRun(record2);
49811
+ this.workflowNames.set(record2.id, record2.workflow_name);
49812
+ await this.bus.emit("workflow.run.started", {
49813
+ ...this.envelope(record2.id),
49814
+ workflowName: record2.workflow_name
49815
+ });
49816
+ }
49817
+ async finalizeRun(runId, status, completedAt) {
49818
+ await this.inner.finalizeRun(runId, status, completedAt);
49819
+ await this.bus.emit("workflow.run.finalized", { ...this.envelope(runId, completedAt), status });
49820
+ }
49821
+ async savePhase(runId, phase, status) {
49822
+ await this.inner.savePhase(runId, phase, status);
49823
+ await this.bus.emit("workflow.phase", { ...this.envelope(runId), phase, status });
49824
+ }
49825
+ async saveTransition(runId, from, to, trigger) {
49826
+ await this.inner.saveTransition(runId, from, to, trigger);
49827
+ await this.bus.emit("workflow.transition", { ...this.envelope(runId), from, to, trigger });
49828
+ }
49829
+ async commitTransition(runId, from, to, trigger, _state, _data, phase) {
49830
+ await this.inner.commitTransition(runId, from, to, trigger, _state, _data, phase);
49831
+ await this.bus.emit("workflow.transition", { ...this.envelope(runId), from, to, trigger });
49832
+ if (phase) {
49833
+ await this.bus.emit("workflow.phase", {
49834
+ ...this.envelope(runId),
49835
+ phase: phase.phase,
49836
+ status: phase.status
49837
+ });
49838
+ }
49839
+ }
49840
+ async saveActionStart(runId, node, kind, options) {
49841
+ const actionId = await this.inner.saveActionStart(runId, node, kind, options);
49842
+ this.actions.set(actionId, { runId, node, kind });
49843
+ const metadata = projectActionMetadata(kind, options);
49844
+ await this.bus.emit("workflow.action.started", {
49845
+ ...this.envelope(runId),
49846
+ actionId,
49847
+ node,
49848
+ kind,
49849
+ ...metadata !== undefined ? { metadata } : {}
49850
+ });
49851
+ return actionId;
49852
+ }
49853
+ async saveActionFinalize(actionId, status, durationMs, ok, result, redactor) {
49854
+ await this.inner.saveActionFinalize(actionId, status, durationMs, ok, result, redactor);
49855
+ const action = this.actions.get(actionId);
49856
+ if (action === undefined) {
49857
+ return;
49858
+ }
49859
+ this.actions.delete(actionId);
49860
+ const projected = projectResult(result);
49861
+ await this.bus.emit("workflow.action.finished", {
49862
+ ...this.envelope(action.runId),
49863
+ actionId,
49864
+ status,
49865
+ durationMs,
49866
+ ok,
49867
+ node: action.node,
49868
+ kind: action.kind,
49869
+ ...projected !== undefined ? { result: projected } : {}
49870
+ });
49871
+ }
49872
+ envelope(runId, at = now()) {
49873
+ const sequence = (this.sequences.get(runId) ?? 0) + 1;
49874
+ this.sequences.set(runId, sequence);
49875
+ const workflowName = this.workflowNames.get(runId);
49876
+ return {
49877
+ schemaVersion: 1,
49878
+ eventId: crypto.randomUUID(),
49879
+ sequence,
49880
+ runId,
49881
+ ...workflowName !== undefined ? { workflowName } : {},
49882
+ at
49883
+ };
49884
+ }
49885
+ saveWorkflowState(runId, state, data) {
49886
+ return this.inner.saveWorkflowState(runId, state, data);
49887
+ }
49888
+ loadRun(runId) {
49889
+ return this.inner.loadRun(runId);
49890
+ }
49891
+ listRuns() {
49892
+ return this.inner.listRuns();
49893
+ }
49894
+ findRunByKey(workflowName, externalKey) {
49895
+ return this.inner.findRunByKey(workflowName, externalKey);
49896
+ }
49897
+ createOrAttachRun(record2) {
49898
+ return this.inner.createOrAttachRun(record2);
49899
+ }
49900
+ reseedRun(runId, newState) {
49901
+ return this.inner.reseedRun(runId, newState);
49902
+ }
49903
+ loadCurrentState(runId) {
49904
+ return this.inner.loadCurrentState(runId);
49905
+ }
49906
+ loadLatestStateSnapshot(runId) {
49907
+ return this.inner.loadLatestStateSnapshot(runId);
49908
+ }
49909
+ listPausedRuns(options) {
49910
+ return this.inner.listPausedRuns(options);
49911
+ }
49912
+ }
49913
+ var now = () => new Date().toISOString(), MAX_FIELD_LENGTH = 256, SECRET_PATTERN2;
49914
+ var init_observability = __esm(() => {
49915
+ SECRET_PATTERN2 = /(?:sk-[a-z0-9_-]{8,}|(?:api[_-]?key|token|secret|password)\s*[:=]\s*\S+|bearer\s+\S+)/gi;
49916
+ });
49917
+
49918
+ // ../../packages/app/src/workflow/step-reporter.ts
49919
+ function runPrefix(runId, options) {
49920
+ if (options.showRunId === false)
49921
+ return "";
49922
+ return `[run ${runId.slice(0, 8)}] `;
49923
+ }
49924
+ function renderStepLine(event, options = {}) {
49925
+ const detail = options.detail ?? "invocation";
49926
+ const pfx = runPrefix(event.runId, options);
49927
+ if (isAgentExecution(event)) {
49928
+ if (event.kind === "output") {
49929
+ if (detail === "minimal")
49930
+ return null;
49931
+ const label = event.stream === "stderr" ? "stderr" : "stdout";
49932
+ return `${pfx} ${label}> ${event.chunk.replace(/\s+$/, "")}`;
49933
+ }
49934
+ if (event.kind === "heartbeat") {
49935
+ if (detail === "minimal")
49936
+ return null;
49937
+ const budget = event.timeoutMs === undefined ? "unbounded" : `${formatDuration(Math.max(0, event.timeoutMs - event.elapsedMs))} remaining`;
49938
+ const pidPart = event.pid === undefined ? "" : ` \xB7 pid=${event.pid}`;
49939
+ return `${pfx} \u2026 agent execution \xB7 elapsed=${formatDuration(event.elapsedMs)} \xB7 budget=${budget}${pidPart}`;
49940
+ }
49941
+ if (event.kind === "dropped") {
49942
+ return detail === "minimal" ? null : `${pfx}\u2026 output pressure \xB7 dropped=${event.chunks} chunks`;
49943
+ }
49944
+ if (event.kind === "started") {
49945
+ if (detail === "minimal")
49946
+ return null;
49947
+ const model = event.model === undefined ? "" : `(${event.model})`;
49948
+ const pidPart = event.pid === undefined ? "" : ` \xB7 pid=${event.pid}`;
49949
+ const full2 = detail === "full" ? ` \xB7 execution=${event.executionId}` : "";
49950
+ return `${pfx} agent=${event.agent}${model} => ${event.invocation}${pidPart}${full2}`;
49951
+ }
49952
+ const mark = event.outcome === "done" ? "\u2713" : "\u2717";
49953
+ const full = detail === "full" ? ` \xB7 execution=${event.executionId}` : "";
49954
+ const exitPart = event.exitCode !== null && event.exitCode !== undefined ? ` \xB7 exit ${event.exitCode}` : "";
49955
+ return detail === "minimal" ? null : `${pfx}${mark} agent ${event.outcome} (${formatDuration(event.durationMs)})${exitPart} \xB7 usage ${event.usage}${event.reason ? ` \xB7 ${event.reason}` : ""}${full}`;
49956
+ }
49957
+ if (isActionOutput(event)) {
49958
+ if (detail === "minimal")
49959
+ return null;
49960
+ const label = event.stream === "stderr" ? "stderr" : "stdout";
49961
+ return `${pfx} ${label}> ${event.chunk.replace(/\s+$/, "")}`;
49962
+ }
49963
+ if (isActionFinished(event)) {
49964
+ const mark = event.ok ? "\u2713" : "\u2717";
49965
+ if (detail === "minimal")
49966
+ return ` ${mark} ${event.status} (${formatDuration(event.durationMs)})`;
49967
+ const failure = event.result?.error === undefined ? "" : ` \xB7 ${event.result.error}`;
49968
+ const usagePart = event.result?.usage !== undefined && event.result.usage !== "unavailable" ? ` \xB7 usage ${event.result.usage}` : "";
49969
+ const full = detail === "full" ? ` \xB7 action=${event.actionId} \xB7 seq=${event.sequence}` : "";
49970
+ return `${pfx}${mark} ${event.node}/${event.kind} (${formatDuration(event.durationMs)})${usagePart}${failure}${full}`;
49971
+ }
49972
+ if (isActionStarted(event)) {
49973
+ if (detail === "minimal")
49974
+ return ` \u2192 ${event.node}: ${event.kind}\u2026`;
49975
+ const agentPart = event.metadata?.agent && event.metadata.agent !== "unavailable" ? ` \xB7 agent=${event.metadata.agent}` : "";
49976
+ const modelPart = event.metadata?.model && event.metadata.model !== "unavailable" ? ` \xB7 model=${event.metadata.model}` : "";
49977
+ const invocationPart = event.metadata?.invocation && event.metadata.invocation !== "unavailable" ? ` => ${event.metadata.invocation}` : "";
49978
+ const timeout = event.metadata?.timeoutMs === undefined ? "unbounded" : formatDuration(event.metadata.timeoutMs);
49979
+ const full = detail === "full" ? ` \xB7 action=${event.actionId} \xB7 seq=${event.sequence}` : "";
49980
+ return `${pfx}\u2192 ${event.node}/${event.kind}${agentPart}${modelPart}${invocationPart} \xB7 timeout=${timeout}${full}`;
49981
+ }
49982
+ if (isPhase(event)) {
49983
+ return detail === "minimal" ? `\u25B6 ${event.phase} [${event.status}]` : `${pfx}\u25B6 ${event.phase} [${event.status}]`;
49984
+ }
49985
+ if (isTransition(event)) {
49986
+ if (detail === "minimal")
49987
+ return null;
49988
+ const seqPart = detail === "full" ? ` \xB7 seq=${event.sequence}` : "";
49989
+ return `${pfx}\u21AA ${event.from} \u2192 ${event.to}${event.trigger ? ` [${event.trigger}]` : ""}${seqPart}`;
49990
+ }
49991
+ return null;
49992
+ }
49993
+ function renderActionHeartbeat(event, elapsedMs, options = {}) {
49994
+ const detail = options.detail ?? "invocation";
49995
+ if (detail === "minimal")
49996
+ return null;
49997
+ const elapsed = formatDuration(elapsedMs);
49998
+ const budget = event.metadata?.timeoutMs === undefined ? "unbounded" : `${formatDuration(Math.max(0, event.metadata.timeoutMs - elapsedMs))} remaining`;
49999
+ const full = detail === "full" ? ` \xB7 action=${event.actionId}` : "";
50000
+ return `${runPrefix(event.runId, options)}\u2026 ${event.node}/${event.kind} \xB7 elapsed=${elapsed} \xB7 budget=${budget}${full}`;
50001
+ }
50002
+ function renderRunPlan(def) {
50003
+ const steps = def.kind === "transition-flow" ? def.nodes.map((n2) => n2.id) : def.states.map((s) => s.id);
50004
+ return `plan: ${steps.join(" \u2192 ")}`;
50005
+ }
50006
+ function formatDuration(ms) {
50007
+ const totalSeconds = Math.round(ms / 1000);
50008
+ if (totalSeconds < 60)
50009
+ return `${totalSeconds}s`;
50010
+ const minutes = Math.floor(totalSeconds / 60);
50011
+ const seconds = totalSeconds % 60;
50012
+ return `${minutes}m ${seconds}s`;
50013
+ }
50014
+ var isAgentExecution = (e) => ("executionId" in e), isActionOutput = (e) => ("stream" in e) && ("chunk" in e) && !("executionId" in e), isActionStarted = (e) => ("kind" in e) && ("node" in e), isActionFinished = (e) => ("durationMs" in e) && ("ok" in e), isPhase = (e) => ("phase" in e), isTransition = (e) => ("from" in e) && ("to" in e);
50015
+
50016
+ // ../../packages/app/src/observability/workflow-run-log-sink.ts
50017
+ import { closeSync, mkdirSync as mkdirSync4, openSync, writeSync } from "fs";
50018
+ import { join as join5 } from "path";
50019
+
50020
+ class WorkflowRunLogSink {
50021
+ filePath;
50022
+ maxBytes;
50023
+ maxLines;
50024
+ planPreview;
50025
+ fd;
50026
+ bytes = 0;
50027
+ lines = 0;
50028
+ truncated = false;
50029
+ closed = false;
50030
+ headerWritten = false;
50031
+ bus;
50032
+ handlers;
50033
+ constructor(options) {
50034
+ this.filePath = join5(options.dir, `${options.runId}.log`);
50035
+ this.maxBytes = options.maxBytes ?? DEFAULT_RUN_LOG_MAX_BYTES;
50036
+ this.maxLines = options.maxLines;
50037
+ this.planPreview = options.planPreview;
50038
+ try {
50039
+ mkdirSync4(options.dir, { recursive: true });
50040
+ this.fd = openSync(this.filePath, "a");
50041
+ } catch {
50042
+ this.fd = undefined;
50043
+ }
50044
+ this.bus = options.bus;
50045
+ this.handlers = {
50046
+ "workflow.run.started": (event) => this.onRunStarted(event),
50047
+ "workflow.phase": (event) => this.onProgress(event),
50048
+ "workflow.transition": (event) => this.onProgress(event),
50049
+ "workflow.action.started": (event) => this.onProgress(event),
50050
+ "workflow.action.finished": (event) => this.onProgress(event),
50051
+ "workflow.action.output": (event) => this.onProgress(event),
50052
+ "workflow.agent": (event) => this.onAgent(event),
50053
+ "workflow.steering": (event) => this.onSteering(event),
50054
+ "workflow.run.finalized": (event) => this.onRunFinalized(event)
50055
+ };
50056
+ this.register(true);
50057
+ }
50058
+ get isTruncated() {
50059
+ return this.truncated;
50060
+ }
50061
+ close() {
50062
+ if (this.closed)
50063
+ return;
50064
+ this.closed = true;
50065
+ this.register(false);
50066
+ if (this.fd !== undefined) {
50067
+ try {
50068
+ closeSync(this.fd);
50069
+ } catch {}
50070
+ this.fd = undefined;
50071
+ }
50072
+ }
50073
+ register(attach) {
50074
+ for (const name of RUN_LOG_EVENT_NAMES) {
50075
+ if (attach)
50076
+ this.bus.on(name, this.handlers[name]);
50077
+ else
50078
+ this.bus.off(name, this.handlers[name]);
50079
+ }
50080
+ }
50081
+ onRunStarted(event) {
50082
+ if (this.headerWritten)
50083
+ return;
50084
+ this.headerWritten = true;
50085
+ this.append(`# spur workflow run ${event.runId} \u2014 ${event.workflowName} \u2014 started ${event.at}
50086
+ `);
50087
+ if (this.planPreview !== undefined)
50088
+ this.append(`# ${this.planPreview}
50089
+ `);
50090
+ }
50091
+ onProgress(event) {
50092
+ const line = renderStepLine(event, { detail: "full", showRunId: true });
50093
+ if (line === null)
50094
+ return;
50095
+ this.append(`[${event.at}] ${line}
50096
+ `);
50097
+ }
50098
+ onRunFinalized(event) {
50099
+ this.append(`
50100
+ === workflow run ${event.runId} finished \u2014 status ${event.status} \u2014 ${event.at} ===
50101
+ `);
50102
+ }
50103
+ onSteering(ack) {
50104
+ const note = ack.note === undefined ? "" : ` \xB7 ${bounded(ack.note, MAX_STEERING_NOTE_CHARS)}`;
50105
+ this.append(`[${ack.at}] [steer] ${ack.accepted ? "ack" : "nack"} ${ack.operation}${note}
50106
+ `);
50107
+ }
50108
+ onAgent(event) {
50109
+ if (this.fd === undefined || this.closed)
50110
+ return;
50111
+ switch (event.kind) {
50112
+ case "output":
50113
+ this.append(`[${event.at}] ${event.stream}: ${event.chunk}
50114
+ `);
50115
+ break;
50116
+ case "started":
50117
+ this.append(`# agent output \u2014 run ${event.runId} \u2014 ${event.agent} \u2014 ${event.at}
50118
+ `);
50119
+ this.append(`# invocation: ${event.invocation}
50120
+ `);
50121
+ break;
50122
+ case "dropped":
50123
+ this.append(`
50124
+ === [dropped] ${event.chunks} chunk(s) discarded by the lifecycle relay under backpressure ===
50125
+ `);
50126
+ break;
50127
+ case "finished":
50128
+ this.append(`
50129
+ === run ${event.outcome} (exit ${event.exitCode}) after ${event.durationMs}ms ===
50130
+ `);
50131
+ break;
50132
+ default:
50133
+ break;
50134
+ }
50135
+ }
50136
+ append(text3) {
50137
+ if (this.fd === undefined || this.closed || this.truncated)
50138
+ return;
50139
+ const textBytes = Buffer.byteLength(text3);
50140
+ const textLines = countNewlines(text3);
50141
+ if (this.bytes + textBytes > this.maxBytes || this.maxLines !== undefined && this.lines + textLines > this.maxLines) {
50142
+ this.truncated = true;
50143
+ try {
50144
+ writeSync(this.fd, TRUNCATION_MARKER);
50145
+ } catch {}
50146
+ return;
50147
+ }
50148
+ try {
50149
+ writeSync(this.fd, text3);
50150
+ this.bytes += textBytes;
50151
+ this.lines += textLines;
50152
+ } catch {}
50153
+ }
50154
+ }
50155
+ function countNewlines(text3) {
50156
+ let count3 = 0;
50157
+ for (let i2 = 0;i2 < text3.length; i2 += 1) {
50158
+ if (text3.charCodeAt(i2) === 10)
50159
+ count3 += 1;
50160
+ }
50161
+ return count3;
50162
+ }
50163
+ var DEFAULT_RUN_LOG_MAX_BYTES, MAX_STEERING_NOTE_CHARS = 1024, TRUNCATION_MARKER = `
50164
+ === [truncated] consolidated run log reached its configured bound; further lines were not written ===
50165
+ `, RUN_LOG_EVENT_NAMES;
50166
+ var init_workflow_run_log_sink = __esm(() => {
50167
+ init_observability();
50168
+ DEFAULT_RUN_LOG_MAX_BYTES = 1024 * 1024;
50169
+ RUN_LOG_EVENT_NAMES = [
50170
+ "workflow.run.started",
50171
+ "workflow.phase",
50172
+ "workflow.transition",
50173
+ "workflow.action.started",
50174
+ "workflow.action.finished",
50175
+ "workflow.action.output",
50176
+ "workflow.agent",
50177
+ "workflow.steering",
50178
+ "workflow.run.finalized"
50179
+ ];
50180
+ });
50181
+
49726
50182
  // ../../packages/domain/src/analytics/models.ts
49727
50183
  function resolvePricing(model) {
49728
50184
  if (model === undefined || model.length === 0)
@@ -51009,7 +51465,7 @@ var init_drizzle_zod = __esm(() => {
51009
51465
  };
51010
51466
  });
51011
51467
 
51012
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/schema/drizzle-internals.js
51468
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/schema/drizzle-internals.js
51013
51469
  function sqlExpressionToText(value) {
51014
51470
  if (typeof value !== "object" || value === null || !("queryChunks" in value)) {
51015
51471
  return;
@@ -51032,7 +51488,7 @@ function getDrizzleTableName(table3) {
51032
51488
  return String(table3[nameSym]);
51033
51489
  }
51034
51490
 
51035
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/schema/ddl.js
51491
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/schema/ddl.js
51036
51492
  function quoteIdent(name) {
51037
51493
  return `"${name.replace(/"/g, '""')}"`;
51038
51494
  }
@@ -51126,7 +51582,7 @@ var init_ddl = __esm(() => {
51126
51582
  init_sqlite_core();
51127
51583
  });
51128
51584
 
51129
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/schema/define-table.js
51585
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/schema/define-table.js
51130
51586
  function defineTable(name, columns2) {
51131
51587
  const table3 = sqliteTable(name, columns2);
51132
51588
  let insert2;
@@ -51160,7 +51616,7 @@ var init_define_table = __esm(() => {
51160
51616
  init_ddl();
51161
51617
  });
51162
51618
 
51163
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.16+fec36642bac873ee/node_modules/@gobing-ai/ts-db/dist/schema/index.js
51619
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.18+c31add66cbc22fb3/node_modules/@gobing-ai/ts-db/dist/schema/index.js
51164
51620
  var init_schema = __esm(() => {
51165
51621
  init_sqlite_core();
51166
51622
  init_define_table();
@@ -51785,7 +52241,7 @@ var init_dao = __esm(() => {
51785
52241
  init_workspace_dao();
51786
52242
  });
51787
52243
 
51788
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/errors.js
52244
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/errors.js
51789
52245
  var WorkflowValidationError, FSMError, RunCollisionError, WorkflowResumeError;
51790
52246
  var init_errors6 = __esm(() => {
51791
52247
  WorkflowValidationError = class WorkflowValidationError extends Error {
@@ -51820,12 +52276,12 @@ var init_errors6 = __esm(() => {
51820
52276
  };
51821
52277
  });
51822
52278
 
51823
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/event-bus/index.js
52279
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/event-bus/index.js
51824
52280
  var init_event_bus2 = __esm(() => {
51825
52281
  init_event_bus();
51826
52282
  });
51827
52283
 
51828
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/api-client.js
52284
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/api-client.js
51829
52285
  function sanitizeUrlForObservability(url2) {
51830
52286
  try {
51831
52287
  const parsed = new URL(url2);
@@ -52055,12 +52511,12 @@ var init_api_client = __esm(() => {
52055
52511
  };
52056
52512
  });
52057
52513
 
52058
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/telemetry/index.js
52514
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/telemetry/index.js
52059
52515
  var init_telemetry = __esm(() => {
52060
52516
  init_tracing2();
52061
52517
  });
52062
52518
 
52063
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/index.js
52519
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/index.js
52064
52520
  var init_dist6 = __esm(() => {
52065
52521
  init_api_client();
52066
52522
  init_event_bus2();
@@ -52068,7 +52524,7 @@ var init_dist6 = __esm(() => {
52068
52524
  init_telemetry();
52069
52525
  });
52070
52526
 
52071
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/run-lifecycle.js
52527
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/run-lifecycle.js
52072
52528
  function runtimeBuiltins(workflowName, stateOrNodeId, runId, transitionsTaken, mode) {
52073
52529
  return {
52074
52530
  workflow: workflowName,
@@ -52327,7 +52783,7 @@ var init_run_lifecycle = __esm(() => {
52327
52783
  ];
52328
52784
  });
52329
52785
 
52330
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/schema.js
52786
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/schema.js
52331
52787
  var RESERVED_VAR_NAMES, IDENTIFIER, VarsSchema, EnvSchema, ActionDefSchema, GuardDefSchema, StateMachineWorkflowDefSchema, TransitionFlowWorkflowDefSchema, WorkflowDefSchema;
52332
52788
  var init_schema2 = __esm(() => {
52333
52789
  init_zod();
@@ -52363,6 +52819,7 @@ var init_schema2 = __esm(() => {
52363
52819
  description: exports_external.string().optional(),
52364
52820
  initialState: exports_external.string().min(1),
52365
52821
  terminalStates: exports_external.array(exports_external.string().min(1)).optional(),
52822
+ failureStates: exports_external.array(exports_external.string().min(1)).optional(),
52366
52823
  iterationBound: exports_external.number().int().positive().optional(),
52367
52824
  defaultOnError: exports_external.enum(["fail", "continue"]).optional(),
52368
52825
  vars: VarsSchema.optional(),
@@ -52411,7 +52868,7 @@ var init_schema2 = __esm(() => {
52411
52868
  WorkflowDefSchema = exports_external.union([StateMachineWorkflowDefSchema, TransitionFlowWorkflowDefSchema]);
52412
52869
  });
52413
52870
 
52414
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/config.js
52871
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/config.js
52415
52872
  async function loadWorkflowDef(path9, options = {}) {
52416
52873
  return parseWorkflowDef(await loadStructuredConfig(path9, options), path9);
52417
52874
  }
@@ -52427,8 +52884,16 @@ function validateStateMachine(workflow) {
52427
52884
  const ids = workflow.states.map((state) => state.id);
52428
52885
  const states = new Set(ids);
52429
52886
  const terminals = new Set(workflow.terminalStates ?? []);
52887
+ const failures = new Set(workflow.failureStates ?? []);
52430
52888
  for (const id of duplicates(ids))
52431
52889
  errors6.push(`State "${id}" is declared more than once`);
52890
+ for (const failure of failures) {
52891
+ if (!states.has(failure))
52892
+ errors6.push(`Failure state "${failure}" is not declared`);
52893
+ else if (!terminals.has(failure)) {
52894
+ errors6.push(`Failure state "${failure}" must also be declared as a terminal state`);
52895
+ }
52896
+ }
52432
52897
  if (!states.has(workflow.initialState)) {
52433
52898
  errors6.push(`Initial state "${workflow.initialState}" is not declared`);
52434
52899
  } else if (terminals.has(workflow.initialState)) {
@@ -52570,7 +53035,7 @@ var init_config4 = __esm(() => {
52570
53035
  RUNTIME_TEMPLATE_NAMESPACES = new Set(RUNTIME_BUILTIN_KEYS);
52571
53036
  });
52572
53037
 
52573
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/extension/capability-registry.js
53038
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/extension/capability-registry.js
52574
53039
  class CapabilityRegistry {
52575
53040
  kind;
52576
53041
  capabilities = new Map;
@@ -52601,7 +53066,7 @@ class CapabilityRegistry {
52601
53066
  }
52602
53067
  }
52603
53068
 
52604
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-path.js
53069
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-path.js
52605
53070
  function assertRelativeExtensionPath(path9, options = {}) {
52606
53071
  const where = options.sourceName !== undefined ? ` declared by "${options.sourceName}"` : "";
52607
53072
  if (/^([/\\]|[A-Za-z]:[/\\])/.test(path9)) {
@@ -52612,20 +53077,20 @@ function assertRelativeExtensionPath(path9, options = {}) {
52612
53077
  }
52613
53078
  }
52614
53079
 
52615
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-loader.js
53080
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-loader.js
52616
53081
  var init_extension_loader = () => {};
52617
53082
 
52618
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/extension/index.js
53083
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/extension/index.js
52619
53084
  var init_extension = __esm(() => {
52620
53085
  init_extension_loader();
52621
53086
  });
52622
53087
 
52623
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.16+d8250d61be64a872/node_modules/@gobing-ai/ts-runtime/dist/extension.js
53088
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.18+0c3519262b4dbb18/node_modules/@gobing-ai/ts-runtime/dist/extension.js
52624
53089
  var init_extension2 = __esm(() => {
52625
53090
  init_extension();
52626
53091
  });
52627
53092
 
52628
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/host.js
53093
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/host.js
52629
53094
  class WorkflowEngineHost {
52630
53095
  lifecycleBus;
52631
53096
  actions = new CapabilityRegistry("workflow action");
@@ -52794,7 +53259,7 @@ var init_host = __esm(() => {
52794
53259
  init_errors6();
52795
53260
  });
52796
53261
 
52797
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/schema-sql.js
53262
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/schema-sql.js
52798
53263
  var WORKFLOW_ENGINE_SCHEMA_SQL;
52799
53264
  var init_schema_sql = __esm(() => {
52800
53265
  WORKFLOW_ENGINE_SCHEMA_SQL = `
@@ -52867,7 +53332,7 @@ CREATE TABLE IF NOT EXISTS action_runs (
52867
53332
  `.trim();
52868
53333
  });
52869
53334
 
52870
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/persistence.js
53335
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/persistence.js
52871
53336
  async function applyWorkflowEngineSchema(db2) {
52872
53337
  for (const statement of WORKFLOW_ENGINE_SCHEMA_SQL.split(";")) {
52873
53338
  const sql4 = statement.trim();
@@ -52911,17 +53376,17 @@ class DbWorkflowPersistenceAdapter {
52911
53376
  }
52912
53377
  async commitTransition(runId, from, to, trigger, state, data, phase) {
52913
53378
  await this.ensureSchema();
52914
- const now = Date.now();
53379
+ const now2 = Date.now();
52915
53380
  const ops = [
52916
- this.transitionRow(runId, from, to, trigger, now),
52917
- this.stateRow(runId, state, data, now)
53381
+ this.transitionRow(runId, from, to, trigger, now2),
53382
+ this.stateRow(runId, state, data, now2)
52918
53383
  ];
52919
53384
  if (phase) {
52920
- ops.push(this.phaseRow(runId, phase.phase, phase.status, now));
53385
+ ops.push(this.phaseRow(runId, phase.phase, phase.status, now2));
52921
53386
  }
52922
53387
  await this.db.batch(ops);
52923
53388
  }
52924
- transitionRow(runId, from, to, trigger, now) {
53389
+ transitionRow(runId, from, to, trigger, now2) {
52925
53390
  return {
52926
53391
  sql: `INSERT INTO transition_runs (id, run_id, from_state, to_state, trigger, status, created_at, updated_at)
52927
53392
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
@@ -52932,19 +53397,19 @@ class DbWorkflowPersistenceAdapter {
52932
53397
  to,
52933
53398
  trigger,
52934
53399
  "done",
52935
- now,
52936
- now
53400
+ now2,
53401
+ now2
52937
53402
  ]
52938
53403
  };
52939
53404
  }
52940
- stateRow(runId, state, data, now) {
53405
+ stateRow(runId, state, data, now2) {
52941
53406
  return {
52942
53407
  sql: `INSERT INTO workflow_states (id, run_id, state, data_json, created_at, updated_at)
52943
53408
  VALUES (?, ?, ?, ?, ?, ?)`,
52944
- params: [`${runId}:state:${state}:${crypto.randomUUID()}`, runId, state, JSON.stringify(data), now, now]
53409
+ params: [`${runId}:state:${state}:${crypto.randomUUID()}`, runId, state, JSON.stringify(data), now2, now2]
52945
53410
  };
52946
53411
  }
52947
- phaseRow(runId, phase, status, now) {
53412
+ phaseRow(runId, phase, status, now2) {
52948
53413
  return {
52949
53414
  sql: `INSERT INTO phase_runs (id, run_id, phase, status, started_at, completed_at, created_at, updated_at)
52950
53415
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
@@ -52953,25 +53418,25 @@ class DbWorkflowPersistenceAdapter {
52953
53418
  runId,
52954
53419
  phase,
52955
53420
  status,
52956
- new Date(now).toISOString(),
52957
- status === "running" ? null : new Date(now).toISOString(),
52958
- now,
52959
- now
53421
+ new Date(now2).toISOString(),
53422
+ status === "running" ? null : new Date(now2).toISOString(),
53423
+ now2,
53424
+ now2
52960
53425
  ]
52961
53426
  };
52962
53427
  }
52963
53428
  async saveActionStart(runId, node, kind, _options) {
52964
53429
  const id = crypto.randomUUID();
52965
- const now = Date.now();
53430
+ const now2 = Date.now();
52966
53431
  await this.db.run(`INSERT INTO action_runs (id, run_id, node, kind, status, started_at, created_at, updated_at)
52967
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, id, runId, node, kind, "running", new Date(now).toISOString(), now, now);
53432
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, id, runId, node, kind, "running", new Date(now2).toISOString(), now2, now2);
52968
53433
  return id;
52969
53434
  }
52970
53435
  async saveActionFinalize(actionId, status, durationMs, ok, result, _redactor) {
52971
- const now = Date.now();
53436
+ const now2 = Date.now();
52972
53437
  await this.db.run(`UPDATE action_runs
52973
53438
  SET status = ?, duration_ms = ?, ok = ?, result_json = ?, completed_at = ?, updated_at = ?
52974
- WHERE id = ?`, status, durationMs, ok ? 1 : 0, result !== undefined ? JSON.stringify(result) : null, new Date(now).toISOString(), now, actionId);
53439
+ WHERE id = ?`, status, durationMs, ok ? 1 : 0, result !== undefined ? JSON.stringify(result) : null, new Date(now2).toISOString(), now2, actionId);
52975
53440
  }
52976
53441
  async loadRun(runId) {
52977
53442
  await this.ensureSchema();
@@ -53007,10 +53472,10 @@ class DbWorkflowPersistenceAdapter {
53007
53472
  return { ...record2 };
53008
53473
  }
53009
53474
  async reseedRun(runId, newState) {
53010
- const now = Date.now();
53475
+ const now2 = Date.now();
53011
53476
  await this.ensureSchema();
53012
53477
  const previous = await this.db.queryFirst("SELECT state FROM workflow_states WHERE run_id = ? ORDER BY created_at DESC, rowid DESC LIMIT 1", runId);
53013
- await this.saveWorkflowState(runId, newState, { reseeded: true, reseededAt: new Date(now).toISOString() });
53478
+ await this.saveWorkflowState(runId, newState, { reseeded: true, reseededAt: new Date(now2).toISOString() });
53014
53479
  await this.saveTransition(runId, previous?.state ?? "", newState, "__reseed__");
53015
53480
  return { fromState: previous?.state ?? null, toState: newState };
53016
53481
  }
@@ -53156,7 +53621,7 @@ var init_persistence = __esm(() => {
53156
53621
  init_schema_sql();
53157
53622
  });
53158
53623
 
53159
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/variables.js
53624
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/variables.js
53160
53625
  function mergeVars(workflowVars = {}, overrideVars = {}) {
53161
53626
  return { ...workflowVars, ...overrideVars };
53162
53627
  }
@@ -53216,7 +53681,7 @@ var init_variables = __esm(() => {
53216
53681
  TEMPLATE_REF = /\$\{([^}]+)\}/g;
53217
53682
  });
53218
53683
 
53219
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/action-step.js
53684
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/action-step.js
53220
53685
  async function runActionStep(action, vars, deps) {
53221
53686
  const { host, persistence, lifecycle, stateOrNodeId, runId } = deps;
53222
53687
  const resolved = resolveTemplates(action.options ?? {}, {
@@ -53274,7 +53739,7 @@ var init_action_step = __esm(() => {
53274
53739
  init_variables();
53275
53740
  });
53276
53741
 
53277
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/state-machine.js
53742
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/state-machine.js
53278
53743
  class StateMachineDriver {
53279
53744
  options;
53280
53745
  constructor(options) {
@@ -53290,6 +53755,7 @@ class StateMachineDriver {
53290
53755
  const runId = lifecycle.runId;
53291
53756
  const states = new Map(workflow.states.map((state) => [state.id, state]));
53292
53757
  const terminal = new Set(workflow.terminalStates ?? []);
53758
+ const failure = new Set(workflow.failureStates ?? []);
53293
53759
  let vars = mergeVars(workflow.vars, options.vars);
53294
53760
  const env = allowedEnv(workflow.env?.allow ?? [], options.env);
53295
53761
  let current = resumeFromState !== undefined ? states.get(resumeFromState) : states.get(workflow.initialState);
@@ -53327,7 +53793,7 @@ class StateMachineDriver {
53327
53793
  if (enter.result?.setVars)
53328
53794
  vars = mergeSetVars(vars, enter.result.setVars);
53329
53795
  if (enter.outcome === "terminal") {
53330
- return await lifecycle.done(current.id, transitionsTaken);
53796
+ return failure.has(current.id) ? await lifecycle.fail(current.id, transitionsTaken, `terminal:${current.id}`) : await lifecycle.done(current.id, transitionsTaken);
53331
53797
  }
53332
53798
  if (enter.outcome === "fail") {
53333
53799
  return await lifecycle.fail(current.id, transitionsTaken, lastActionResult?.error);
@@ -53338,13 +53804,14 @@ class StateMachineDriver {
53338
53804
  }
53339
53805
  const outbound = workflow.transitions.filter((transition) => transition.from === current?.id);
53340
53806
  if (terminal.has(current.id) || outbound.length === 0) {
53341
- return await lifecycle.done(current.id, transitionsTaken);
53807
+ return failure.has(current.id) ? await lifecycle.fail(current.id, transitionsTaken, `terminal:${current.id}`) : await lifecycle.done(current.id, transitionsTaken);
53342
53808
  }
53343
53809
  const nextTransition = await firstPassingTransition(outbound, this.options.host, {
53344
53810
  runId,
53345
53811
  current: current.id,
53346
53812
  vars,
53347
- lastActionResult
53813
+ lastActionResult,
53814
+ workdir: options.workdir
53348
53815
  }, lifecycle);
53349
53816
  if (nextTransition === undefined) {
53350
53817
  return await lifecycle.fail(current.id, transitionsTaken, "no-passing-transition");
@@ -53408,7 +53875,7 @@ var init_state_machine = __esm(() => {
53408
53875
  EMPTY_OUTCOME = { outcome: "completed", result: undefined };
53409
53876
  });
53410
53877
 
53411
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/transition-flow.js
53878
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/transition-flow.js
53412
53879
  class TransitionFlowDriver {
53413
53880
  options;
53414
53881
  constructor(options) {
@@ -53483,7 +53950,8 @@ class TransitionFlowDriver {
53483
53950
  runId,
53484
53951
  current: current.id,
53485
53952
  vars,
53486
- lastActionResult
53953
+ lastActionResult,
53954
+ workdir: options.workdir
53487
53955
  }, lifecycle);
53488
53956
  if (edge === undefined) {
53489
53957
  return await lifecycle.fail(current.id, transitionsTaken, "no-passing-edge");
@@ -53526,7 +53994,7 @@ var init_transition_flow = __esm(() => {
53526
53994
  init_variables();
53527
53995
  });
53528
53996
 
53529
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/service.js
53997
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/service.js
53530
53998
  class WorkflowService {
53531
53999
  host;
53532
54000
  persistence;
@@ -53743,7 +54211,7 @@ var init_service = __esm(() => {
53743
54211
  init_variables();
53744
54212
  });
53745
54213
 
53746
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/index.js
54214
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/index.js
53747
54215
  var init_dist7 = __esm(() => {
53748
54216
  init_config4();
53749
54217
  init_host();
@@ -53752,7 +54220,7 @@ var init_dist7 = __esm(() => {
53752
54220
  init_service();
53753
54221
  });
53754
54222
 
53755
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.16+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/hash.js
54223
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.18+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/hash.js
53756
54224
  import { createHash } from "crypto";
53757
54225
  function stableJson(value) {
53758
54226
  if (Array.isArray(value)) {
@@ -53769,7 +54237,7 @@ function sha256(value) {
53769
54237
  }
53770
54238
  var init_hash = () => {};
53771
54239
 
53772
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.16+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/errors.js
54240
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.18+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/errors.js
53773
54241
  var HistoryImportError;
53774
54242
  var init_errors7 = __esm(() => {
53775
54243
  HistoryImportError = class HistoryImportError extends Error {
@@ -53782,7 +54250,7 @@ var init_errors7 = __esm(() => {
53782
54250
  };
53783
54251
  });
53784
54252
 
53785
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.16+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/schema-sql.js
54253
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.18+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/schema-sql.js
53786
54254
  var HISTORY_IMPORT_SCHEMA_SQL;
53787
54255
  var init_schema_sql2 = __esm(() => {
53788
54256
  HISTORY_IMPORT_SCHEMA_SQL = `
@@ -53869,7 +54337,7 @@ CREATE TABLE IF NOT EXISTS history_etl_openclaw (
53869
54337
  `.trim();
53870
54338
  });
53871
54339
 
53872
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.16+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/sources.js
54340
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.18+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/sources.js
53873
54341
  function firstString(...values) {
53874
54342
  for (const value of values) {
53875
54343
  if (typeof value === "string" && value.length > 0)
@@ -54006,15 +54474,15 @@ var init_sources = __esm(() => {
54006
54474
  };
54007
54475
  });
54008
54476
 
54009
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.16+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/jsonl-importer-dao.js
54477
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.18+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/jsonl-importer-dao.js
54010
54478
  function targetTableFor(table3) {
54011
54479
  if (!VALID_TABLE_NAME.test(table3)) {
54012
54480
  throw new HistoryImportError(`Invalid history ETL target table: ${table3}`, { table: table3 });
54013
54481
  }
54014
54482
  return table3;
54015
54483
  }
54016
- function timestamp(now) {
54017
- return (now?.() ?? new Date).toISOString();
54484
+ function timestamp(now2) {
54485
+ return (now2?.() ?? new Date).toISOString();
54018
54486
  }
54019
54487
  function ETL_TABLE_DDL(table3) {
54020
54488
  return `CREATE TABLE IF NOT EXISTS ${table3} (
@@ -54052,26 +54520,26 @@ async function resetCheckpoints(db2, source, files) {
54052
54520
  await db2.run("DELETE FROM history_import_checkpoint WHERE source = ? AND source_file = ?", source, file2);
54053
54521
  }
54054
54522
  }
54055
- async function writeCheckpoint(db2, source, sourceFile, line, now) {
54523
+ async function writeCheckpoint(db2, source, sourceFile, line, now2) {
54056
54524
  await db2.run(`INSERT INTO history_import_checkpoint (source, source_file, last_imported_line, updated_at)
54057
54525
  VALUES (?, ?, ?, ?)
54058
54526
  ON CONFLICT(source, source_file) DO UPDATE SET
54059
54527
  last_imported_line = excluded.last_imported_line,
54060
- updated_at = excluded.updated_at`, source, sourceFile, line, timestamp(now));
54528
+ updated_at = excluded.updated_at`, source, sourceFile, line, timestamp(now2));
54061
54529
  }
54062
54530
  async function ledgerExists(db2, recordHash) {
54063
54531
  const row = await db2.queryFirst("SELECT record_hash FROM history_import_ledger WHERE record_hash = ?", recordHash);
54064
54532
  return row !== undefined && row !== null;
54065
54533
  }
54066
- async function insertRecord(db2, targetTable, recordHash, sourceFile, sourceLine, splitIndex, payload, now) {
54534
+ async function insertRecord(db2, targetTable, recordHash, sourceFile, sourceLine, splitIndex, payload, now2) {
54067
54535
  const table3 = targetTableFor(targetTable);
54068
54536
  await db2.run(`INSERT INTO ${table3} (record_hash, source_file, source_line, split_index, payload_json, imported_at)
54069
54537
  VALUES (?, ?, ?, ?, ?, ?)
54070
- ON CONFLICT(record_hash) DO NOTHING`, recordHash, sourceFile, sourceLine, splitIndex, JSON.stringify(payload), timestamp(now));
54538
+ ON CONFLICT(record_hash) DO NOTHING`, recordHash, sourceFile, sourceLine, splitIndex, JSON.stringify(payload), timestamp(now2));
54071
54539
  }
54072
- async function insertLedger(db2, recordHash, source, sourceFile, sourceLine, splitIndex, targetTable, now) {
54540
+ async function insertLedger(db2, recordHash, source, sourceFile, sourceLine, splitIndex, targetTable, now2) {
54073
54541
  await db2.run(`INSERT INTO history_import_ledger (record_hash, source, source_file, source_line, split_index, target_table, imported_at)
54074
- VALUES (?, ?, ?, ?, ?, ?, ?)`, recordHash, source, sourceFile, sourceLine, splitIndex, targetTable, timestamp(now));
54542
+ VALUES (?, ?, ?, ?, ?, ?, ?)`, recordHash, source, sourceFile, sourceLine, splitIndex, targetTable, timestamp(now2));
54075
54543
  }
54076
54544
  var init_jsonl_importer_dao = __esm(() => {
54077
54545
  init_errors7();
@@ -54079,7 +54547,7 @@ var init_jsonl_importer_dao = __esm(() => {
54079
54547
  init_sources();
54080
54548
  });
54081
54549
 
54082
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.16+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/redaction.js
54550
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.18+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/redaction.js
54083
54551
  function redactValue(value, rules = DEFAULT_REDACTION_RULES) {
54084
54552
  if (typeof value === "string") {
54085
54553
  return rules.reduce((current, rule) => current.replace(rule.pattern, rule.replacement), value);
@@ -54116,7 +54584,7 @@ var init_redaction = __esm(() => {
54116
54584
  ];
54117
54585
  });
54118
54586
 
54119
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.16+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/importer.js
54587
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.18+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/importer.js
54120
54588
  async function runJsonlImport(source, options) {
54121
54589
  const definition = resolveSourceDefinition(source);
54122
54590
  const resolvedSource = definition.source;
@@ -54306,13 +54774,13 @@ var init_importer = __esm(() => {
54306
54774
  init_sources();
54307
54775
  });
54308
54776
 
54309
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.16+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/index.js
54777
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.18+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/index.js
54310
54778
  var init_dist8 = __esm(() => {
54311
54779
  init_importer();
54312
54780
  init_schema_sql2();
54313
54781
  });
54314
54782
 
54315
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/config/extensions.js
54783
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/config/extensions.js
54316
54784
  function collectExtensions(sourceName, sourceDir, extensions) {
54317
54785
  if (extensions === undefined)
54318
54786
  return [];
@@ -54328,7 +54796,7 @@ var init_extensions = __esm(() => {
54328
54796
  init_dist5();
54329
54797
  });
54330
54798
 
54331
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/types.js
54799
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/types.js
54332
54800
  function createFinding(rule, message, filePath, extras = {}) {
54333
54801
  return {
54334
54802
  ruleId: rule.id,
@@ -54399,7 +54867,7 @@ var init_types3 = __esm(() => {
54399
54867
  });
54400
54868
  });
54401
54869
 
54402
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/config/loader.js
54870
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/config/loader.js
54403
54871
  async function loadPreset(name, options) {
54404
54872
  const merged = await buildMergedRoots(options.roots.map((root) => resolvePath4(root)), options.fileSystem);
54405
54873
  const presetPath = findMergedPreset(merged, name);
@@ -54614,7 +55082,7 @@ var init_loader2 = __esm(() => {
54614
55082
  FIX_MODE_AUTHORITY = { none: 0, suggest: 1, auto: 2 };
54615
55083
  });
54616
55084
 
54617
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/fixers/test-stub-fixer.js
55085
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/fixers/test-stub-fixer.js
54618
55086
  function normalizeFindingPath(filePath) {
54619
55087
  if (!filePath || isAbsolutePath2(filePath))
54620
55088
  return null;
@@ -54679,7 +55147,7 @@ var init_test_stub_fixer = __esm(() => {
54679
55147
  realFileSystem = createNodeFileSystem3();
54680
55148
  });
54681
55149
 
54682
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/fixers/fixers.js
55150
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/fixers/fixers.js
54683
55151
  function registerBuiltinFixers(host, exec) {
54684
55152
  const regexFixer = new RegexFixerProvider;
54685
55153
  const pathFixer = new PathFixerProvider;
@@ -54882,7 +55350,7 @@ var init_fixers = __esm(() => {
54882
55350
  };
54883
55351
  });
54884
55352
 
54885
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.16+ae22402965cb65aa/node_modules/@gobing-ai/ts-ai-runner/dist/agents/shims.js
55353
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.18+aa81d3e2be8bffb2/node_modules/@gobing-ai/ts-ai-runner/dist/agents/shims.js
54886
55354
  function resolveAgentName(input) {
54887
55355
  if (isCanonicalName(input))
54888
55356
  return input;
@@ -55133,7 +55601,7 @@ var init_shims = __esm(() => {
55133
55601
  ALIAS_TO_CANONICAL = Object.fromEntries(Object.values(AGENT_SHIMS).flatMap((shim) => (shim.aliases ?? []).map((alias3) => [alias3, shim.name])));
55134
55602
  });
55135
55603
 
55136
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.16+ae22402965cb65aa/node_modules/@gobing-ai/ts-ai-runner/dist/identity.js
55604
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.18+aa81d3e2be8bffb2/node_modules/@gobing-ai/ts-ai-runner/dist/identity.js
55137
55605
  function buildIdentityPreamble(ctx) {
55138
55606
  const sections = [
55139
55607
  `You are agent \`${ctx.agentId}\` (${ctx.agentType}) in workspace \`${ctx.workspace}\`.`
@@ -55193,7 +55661,7 @@ var init_identity = __esm(() => {
55193
55661
  init_dist5();
55194
55662
  });
55195
55663
 
55196
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.16+ae22402965cb65aa/node_modules/@gobing-ai/ts-ai-runner/dist/slash-command.js
55664
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.18+aa81d3e2be8bffb2/node_modules/@gobing-ai/ts-ai-runner/dist/slash-command.js
55197
55665
  function isClaudeStyleSlashCommand(input) {
55198
55666
  return SLASH_COMMAND_RE.test(input);
55199
55667
  }
@@ -55221,7 +55689,7 @@ var init_slash_command = __esm(() => {
55221
55689
  SLASH_COMMAND_RE = /^\/([a-zA-Z0-9._-]+):([a-zA-Z0-9._-]+)(\s.*)?$/;
55222
55690
  });
55223
55691
 
55224
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.16+ae22402965cb65aa/node_modules/@gobing-ai/ts-ai-runner/dist/ai-runner.js
55692
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.18+aa81d3e2be8bffb2/node_modules/@gobing-ai/ts-ai-runner/dist/ai-runner.js
55225
55693
  function buildCorrelationEnv(correlation) {
55226
55694
  return {
55227
55695
  [AGENT_RUN_ID_ENV]: correlation.runId,
@@ -55357,7 +55825,7 @@ var init_ai_runner = __esm(() => {
55357
55825
  init_slash_command();
55358
55826
  });
55359
55827
 
55360
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.16+ae22402965cb65aa/node_modules/@gobing-ai/ts-ai-runner/dist/agent-detector.js
55828
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.18+aa81d3e2be8bffb2/node_modules/@gobing-ai/ts-ai-runner/dist/agent-detector.js
55361
55829
  class AgentDetector {
55362
55830
  runner;
55363
55831
  timeout;
@@ -55433,7 +55901,7 @@ var init_agent_detector = __esm(() => {
55433
55901
  VERSION_PATTERN = /(?<version>\d+\.\d+(?:\.\d+)?)/;
55434
55902
  });
55435
55903
 
55436
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.16+ae22402965cb65aa/node_modules/@gobing-ai/ts-ai-runner/dist/agent-spec.js
55904
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.18+aa81d3e2be8bffb2/node_modules/@gobing-ai/ts-ai-runner/dist/agent-spec.js
55437
55905
  function validateAgentId(id) {
55438
55906
  if (!/^[a-z][a-z0-9_-]{1,63}$/.test(id)) {
55439
55907
  throw new ValueError(`Invalid agent id "${id}": expected 2-64 chars, lowercase alphanumeric, "_" or "-"`);
@@ -55530,7 +55998,7 @@ var init_agent_spec = __esm(() => {
55530
55998
  };
55531
55999
  });
55532
56000
 
55533
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.16+ae22402965cb65aa/node_modules/@gobing-ai/ts-ai-runner/dist/agents/auth-shims.js
56001
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.18+aa81d3e2be8bffb2/node_modules/@gobing-ai/ts-ai-runner/dist/agents/auth-shims.js
55534
56002
  function isNonEmpty(value) {
55535
56003
  return value !== undefined && value.trim().length > 0;
55536
56004
  }
@@ -55635,7 +56103,7 @@ var init_auth_shims = __esm(() => {
55635
56103
  };
55636
56104
  });
55637
56105
 
55638
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.16+ae22402965cb65aa/node_modules/@gobing-ai/ts-ai-runner/dist/model-health-probe.js
56106
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.18+aa81d3e2be8bffb2/node_modules/@gobing-ai/ts-ai-runner/dist/model-health-probe.js
55639
56107
  class ModelHealthProbeRegistry {
55640
56108
  probes = new Map;
55641
56109
  register(providerPrefix, probe) {
@@ -55743,7 +56211,7 @@ var init_model_health_probe = __esm(() => {
55743
56211
  };
55744
56212
  });
55745
56213
 
55746
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.16+ae22402965cb65aa/node_modules/@gobing-ai/ts-ai-runner/dist/doctor-runner.js
56214
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.18+aa81d3e2be8bffb2/node_modules/@gobing-ai/ts-ai-runner/dist/doctor-runner.js
55747
56215
  class DoctorRunner {
55748
56216
  detector;
55749
56217
  runner;
@@ -55880,15 +56348,15 @@ var init_doctor_runner = __esm(() => {
55880
56348
  init_model_health_probe();
55881
56349
  });
55882
56350
 
55883
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.16+ae22402965cb65aa/node_modules/@gobing-ai/ts-ai-runner/dist/events.js
56351
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.18+aa81d3e2be8bffb2/node_modules/@gobing-ai/ts-ai-runner/dist/events.js
55884
56352
  var init_events = () => {};
55885
56353
 
55886
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.16+ae22402965cb65aa/node_modules/@gobing-ai/ts-ai-runner/dist/messages.js
56354
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.18+aa81d3e2be8bffb2/node_modules/@gobing-ai/ts-ai-runner/dist/messages.js
55887
56355
  function formatMessage(msg) {
55888
56356
  return `[task from=${msg.fromId ?? "operator"} id=${msg.id}] ${msg.body}`;
55889
56357
  }
55890
56358
 
55891
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.16+ae22402965cb65aa/node_modules/@gobing-ai/ts-ai-runner/dist/team-agent-process.js
56359
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.18+aa81d3e2be8bffb2/node_modules/@gobing-ai/ts-ai-runner/dist/team-agent-process.js
55892
56360
  import { Buffer as Buffer5 } from "buffer";
55893
56361
 
55894
56362
  class TeamAgentProcess {
@@ -56022,7 +56490,7 @@ var init_team_agent_process = __esm(() => {
56022
56490
  init_dist5();
56023
56491
  });
56024
56492
 
56025
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.16+ae22402965cb65aa/node_modules/@gobing-ai/ts-ai-runner/dist/team-orchestrator.js
56493
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.18+aa81d3e2be8bffb2/node_modules/@gobing-ai/ts-ai-runner/dist/team-orchestrator.js
56026
56494
  class TeamOrchestrator {
56027
56495
  configDir;
56028
56496
  inbox;
@@ -56151,7 +56619,7 @@ var init_team_orchestrator = __esm(() => {
56151
56619
  init_team_agent_process();
56152
56620
  });
56153
56621
 
56154
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.16+ae22402965cb65aa/node_modules/@gobing-ai/ts-ai-runner/dist/index.js
56622
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.18+aa81d3e2be8bffb2/node_modules/@gobing-ai/ts-ai-runner/dist/index.js
56155
56623
  var exports_dist3 = {};
56156
56624
  __export(exports_dist3, {
56157
56625
  validateAgentId: () => validateAgentId,
@@ -56202,7 +56670,7 @@ var init_dist9 = __esm(() => {
56202
56670
  init_team_orchestrator();
56203
56671
  });
56204
56672
 
56205
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/config-access.js
56673
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/config-access.js
56206
56674
  function stringArray(value) {
56207
56675
  return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : undefined;
56208
56676
  }
@@ -56240,7 +56708,7 @@ function parseInlineFlags(source) {
56240
56708
  return { flags, rest: source.slice(match[0].length) };
56241
56709
  }
56242
56710
 
56243
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/glob-match.js
56711
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/glob-match.js
56244
56712
  function matchesAny(path9, patterns) {
56245
56713
  if (patterns === undefined || patterns.length === 0)
56246
56714
  return true;
@@ -56288,7 +56756,7 @@ function escapeRegExp(value) {
56288
56756
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
56289
56757
  }
56290
56758
 
56291
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/file-discovery.js
56759
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/file-discovery.js
56292
56760
  async function discoverFiles2(options) {
56293
56761
  const fs3 = options.fs ?? createNodeFileSystem3();
56294
56762
  const allFiles = await walkDir2(options.workdir, fs3, DEFAULT_EXCLUDES);
@@ -56316,12 +56784,12 @@ var init_file_discovery = __esm(() => {
56316
56784
  DEFAULT_EXCLUDES = new Set([".git", "node_modules", "dist", ".coverage", ".astro", ".wrangler"]);
56317
56785
  });
56318
56786
 
56319
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/file-utils.js
56787
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/file-utils.js
56320
56788
  var init_file_utils = __esm(() => {
56321
56789
  init_file_discovery();
56322
56790
  });
56323
56791
 
56324
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/agent-detection-evaluator.js
56792
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/agent-detection-evaluator.js
56325
56793
  class AgentDetectionEvaluator {
56326
56794
  detector;
56327
56795
  constructor(detector = new AgentDetector) {
@@ -56349,7 +56817,7 @@ var init_agent_detection_evaluator = __esm(() => {
56349
56817
  init_file_utils();
56350
56818
  });
56351
56819
 
56352
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/coverage-gate-evaluator.js
56820
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/coverage-gate-evaluator.js
56353
56821
  class CoverageGateEvaluator {
56354
56822
  constructor() {}
56355
56823
  async evaluate(rule, context4) {
@@ -56433,7 +56901,7 @@ var init_coverage_gate_evaluator = __esm(() => {
56433
56901
  init_file_utils();
56434
56902
  });
56435
56903
 
56436
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/exit-code-evaluator.js
56904
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/exit-code-evaluator.js
56437
56905
  class ExitCodeEvaluator {
56438
56906
  executor;
56439
56907
  constructor(executor = nodeBunFactory3.createProcessExecutor()) {
@@ -56469,7 +56937,7 @@ var init_exit_code_evaluator = __esm(() => {
56469
56937
  init_file_utils();
56470
56938
  });
56471
56939
 
56472
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/forbidden-import-evaluator.js
56940
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/forbidden-import-evaluator.js
56473
56941
  class ForbiddenImportEvaluator {
56474
56942
  constructor() {}
56475
56943
  async evaluate(rule, context4) {
@@ -56550,7 +57018,7 @@ var init_forbidden_import_evaluator = __esm(() => {
56550
57018
  init_file_utils();
56551
57019
  });
56552
57020
 
56553
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/import-boundary-evaluator.js
57021
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/import-boundary-evaluator.js
56554
57022
  class ImportBoundaryEvaluator {
56555
57023
  async evaluate(rule, context4) {
56556
57024
  const config4 = rule.evaluator.config ?? {};
@@ -56643,7 +57111,7 @@ var init_import_boundary_evaluator = __esm(() => {
56643
57111
  init_file_utils();
56644
57112
  });
56645
57113
 
56646
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/path-evaluator.js
57114
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/path-evaluator.js
56647
57115
  class PathEvaluator {
56648
57116
  constructor() {}
56649
57117
  async evaluate(rule, context4) {
@@ -56704,7 +57172,7 @@ var init_path_evaluator = __esm(() => {
56704
57172
  init_file_utils();
56705
57173
  });
56706
57174
 
56707
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/regex-evaluator.js
57175
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/regex-evaluator.js
56708
57176
  class RegexEvaluator {
56709
57177
  constructor() {}
56710
57178
  async evaluate(rule, context4) {
@@ -56782,7 +57250,7 @@ var init_regex_evaluator = __esm(() => {
56782
57250
  init_file_utils();
56783
57251
  });
56784
57252
 
56785
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/ripgrep-evaluator.js
57253
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/ripgrep-evaluator.js
56786
57254
  class RipgrepEvaluator {
56787
57255
  executor;
56788
57256
  constructor(executor = nodeBunFactory3.createProcessExecutor()) {
@@ -56875,7 +57343,7 @@ var init_ripgrep_evaluator = __esm(() => {
56875
57343
  init_file_utils();
56876
57344
  });
56877
57345
 
56878
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/schema-artifact-evaluator.js
57346
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/schema-artifact-evaluator.js
56879
57347
  class SchemaArtifactEvaluator {
56880
57348
  constructor() {}
56881
57349
  async evaluate(rule, context4) {
@@ -56953,7 +57421,7 @@ var init_schema_artifact_evaluator = __esm(() => {
56953
57421
  init_file_utils();
56954
57422
  });
56955
57423
 
56956
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/secrets-scanner-evaluator.js
57424
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/secrets-scanner-evaluator.js
56957
57425
  class SecretsScannerEvaluator {
56958
57426
  constructor() {}
56959
57427
  async evaluate(rule, context4) {
@@ -57021,7 +57489,7 @@ var init_secrets_scanner_evaluator = __esm(() => {
57021
57489
  ALL_CATEGORIES = Object.keys(BUILTIN_PATTERNS);
57022
57490
  });
57023
57491
 
57024
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/sg-evaluator.js
57492
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/sg-evaluator.js
57025
57493
  class SgEvaluator {
57026
57494
  executor;
57027
57495
  constructor(executor = nodeBunFactory3.createProcessExecutor()) {
@@ -57118,7 +57586,7 @@ var init_sg_evaluator = __esm(() => {
57118
57586
  init_file_utils();
57119
57587
  });
57120
57588
 
57121
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/resolvers/test-path-resolver.js
57589
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/resolvers/test-path-resolver.js
57122
57590
  class TypeScriptTestPathResolver {
57123
57591
  name = "typescript";
57124
57592
  constructor() {}
@@ -57201,7 +57669,7 @@ function testify(rel) {
57201
57669
  return `${dir}test_${base2}`;
57202
57670
  }
57203
57671
 
57204
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/test-location-evaluator.js
57672
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/test-location-evaluator.js
57205
57673
  class TestLocationEvaluator {
57206
57674
  resolvers;
57207
57675
  constructor(resolvers) {
@@ -57276,7 +57744,7 @@ var init_test_location_evaluator = __esm(() => {
57276
57744
  TYPESCRIPT_FALLBACK = new TypeScriptTestPathResolver;
57277
57745
  });
57278
57746
 
57279
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/tsdoc-export-evaluator.js
57747
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/tsdoc-export-evaluator.js
57280
57748
  class TsdocExportEvaluator {
57281
57749
  constructor() {}
57282
57750
  async evaluate(rule, context4) {
@@ -57361,7 +57829,7 @@ var init_tsdoc_export_evaluator = __esm(() => {
57361
57829
  };
57362
57830
  });
57363
57831
 
57364
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/json.js
57832
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/json.js
57365
57833
  class JsonFormatter {
57366
57834
  constructor() {}
57367
57835
  format(result) {
@@ -57369,7 +57837,7 @@ class JsonFormatter {
57369
57837
  }
57370
57838
  }
57371
57839
 
57372
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/text.js
57840
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/text.js
57373
57841
  class TextFormatter {
57374
57842
  constructor() {}
57375
57843
  format(result) {
@@ -57383,7 +57851,7 @@ class TextFormatter {
57383
57851
  }
57384
57852
  }
57385
57853
 
57386
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/host/builtins.js
57854
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/host/builtins.js
57387
57855
  function registerBuiltins(host, executor) {
57388
57856
  const path9 = new PathEvaluator;
57389
57857
  host.evaluators.register("regex", new RegexEvaluator, "builtin");
@@ -57423,7 +57891,7 @@ var init_builtins = __esm(() => {
57423
57891
  init_tsdoc_export_evaluator();
57424
57892
  });
57425
57893
 
57426
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/host/rule-engine-host.js
57894
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/host/rule-engine-host.js
57427
57895
  class RuleEngineHost {
57428
57896
  evaluators;
57429
57897
  formatters;
@@ -57440,7 +57908,7 @@ var init_rule_engine_host = __esm(() => {
57440
57908
  init_extension2();
57441
57909
  });
57442
57910
 
57443
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/engine.js
57911
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/engine.js
57444
57912
  class RuleEngine {
57445
57913
  host;
57446
57914
  events;
@@ -57611,7 +58079,7 @@ var init_engine = __esm(() => {
57611
58079
  init_types3();
57612
58080
  });
57613
58081
 
57614
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/host/bundled-rules.js
58082
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/host/bundled-rules.js
57615
58083
  async function bundledRulesRoot() {
57616
58084
  if (cachedRoot2 !== undefined)
57617
58085
  return cachedRoot2;
@@ -57662,41 +58130,41 @@ var init_bundled_rules = __esm(() => {
57662
58130
  init_dist5();
57663
58131
  });
57664
58132
 
57665
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/db-adapter.js
58133
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/db-adapter.js
57666
58134
  class DbRulePersistenceAdapter {
57667
58135
  db;
57668
58136
  constructor(db2) {
57669
58137
  this.db = db2;
57670
58138
  }
57671
58139
  async insertRun(input) {
57672
- const now = new Date().toISOString();
58140
+ const now2 = new Date().toISOString();
57673
58141
  await this.db.run(`INSERT INTO rule_runs (id, preset, source_kind, source_value, status, rule_count,
57674
58142
  fail_on, stop_on_first, fix_mode, dry_run, metadata_json, started_at, created_at, updated_at)
57675
- VALUES (?, ?, ?, ?, 'running', ?, ?, ?, ?, ?, ?, ?, ?, ?)`, input.id, input.preset ?? null, input.sourceKind, input.sourceValue ?? null, input.ruleCount, input.failOn ?? null, input.stopOnFirst ?? null, input.fixMode, input.dryRun ? 1 : 0, input.metadataJson ?? "{}", now, now, now);
58143
+ VALUES (?, ?, ?, ?, 'running', ?, ?, ?, ?, ?, ?, ?, ?, ?)`, input.id, input.preset ?? null, input.sourceKind, input.sourceValue ?? null, input.ruleCount, input.failOn ?? null, input.stopOnFirst ?? null, input.fixMode, input.dryRun ? 1 : 0, input.metadataJson ?? "{}", now2, now2, now2);
57676
58144
  }
57677
58145
  async updateRunStatus(runId, status, findingCount, fixCount, appliedFixCount, durationMs) {
57678
- const now = new Date().toISOString();
58146
+ const now2 = new Date().toISOString();
57679
58147
  await this.db.run(`UPDATE rule_runs
57680
58148
  SET status = ?, finding_count = ?, fix_count = ?, applied_fix_count = ?,
57681
58149
  duration_ms = ?, completed_at = ?, updated_at = ?
57682
- WHERE id = ?`, status, findingCount, fixCount, appliedFixCount, durationMs, now, now, runId);
58150
+ WHERE id = ?`, status, findingCount, fixCount, appliedFixCount, durationMs, now2, now2, runId);
57683
58151
  }
57684
58152
  async insertEvalRun(input) {
57685
- const now = new Date().toISOString();
58153
+ const now2 = new Date().toISOString();
57686
58154
  await this.db.run(`INSERT INTO rule_eval_runs (id, run_id, rule_id, severity, evaluator, status,
57687
58155
  started_at, created_at, updated_at)
57688
- VALUES (?, ?, ?, ?, ?, 'running', ?, ?, ?)`, input.id, input.runId, input.ruleId, input.severity, input.evaluator, now, now, now);
58156
+ VALUES (?, ?, ?, ?, ?, 'running', ?, ?, ?)`, input.id, input.runId, input.ruleId, input.severity, input.evaluator, now2, now2, now2);
57689
58157
  }
57690
58158
  async updateEvalRun(input) {
57691
- const now = new Date().toISOString();
58159
+ const now2 = new Date().toISOString();
57692
58160
  await this.db.run(`UPDATE rule_eval_runs
57693
58161
  SET status = ?, finding_count = ?, fix_count = ?, duration_ms = ?,
57694
58162
  error = ?, findings_json = ?, fixes_json = ?, completed_at = ?, updated_at = ?
57695
- WHERE run_id = ? AND rule_id = ?`, input.status, input.findingCount, input.fixCount, input.durationMs, input.error ?? null, input.findingsJson ?? null, input.fixesJson ?? null, now, now, input.runId, input.ruleId);
58163
+ WHERE run_id = ? AND rule_id = ?`, input.status, input.findingCount, input.fixCount, input.durationMs, input.error ?? null, input.findingsJson ?? null, input.fixesJson ?? null, now2, now2, input.runId, input.ruleId);
57696
58164
  }
57697
58165
  }
57698
58166
 
57699
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/schema.js
58167
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/schema.js
57700
58168
  var RULE_ENGINE_SCHEMA_SQL = `
57701
58169
  CREATE TABLE IF NOT EXISTS rule_runs (
57702
58170
  id TEXT PRIMARY KEY,
@@ -57742,10 +58210,10 @@ CREATE TABLE IF NOT EXISTS rule_eval_runs (
57742
58210
  CREATE INDEX IF NOT EXISTS idx_rule_eval_runs_run_id ON rule_eval_runs (run_id);
57743
58211
  `;
57744
58212
 
57745
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/index.js
58213
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/index.js
57746
58214
  var init_persistence2 = () => {};
57747
58215
 
57748
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.16+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/index.js
58216
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.18+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/index.js
57749
58217
  var init_dist10 = __esm(() => {
57750
58218
  init_extensions();
57751
58219
  init_loader2();
@@ -57814,7 +58282,7 @@ var init_schema3 = __esm(() => {
57814
58282
  });
57815
58283
 
57816
58284
  // ../../packages/domain/src/migrations.ts
57817
- import { join as join5 } from "path";
58285
+ import { join as join6 } from "path";
57818
58286
  async function applyCliMigrations(adapter, migrations = CLI_MIGRATIONS) {
57819
58287
  await adapter.exec('CREATE TABLE IF NOT EXISTS "__spur_cli_migrations" (id TEXT PRIMARY KEY, applied_at INTEGER NOT NULL)');
57820
58288
  let applied = 0;
@@ -57842,7 +58310,7 @@ async function loadSqlMigrations(folder) {
57842
58310
  for (const entry of entries) {
57843
58311
  migrations.push({
57844
58312
  id: entry.replace(/\.sql$/, ""),
57845
- sql: await fs3.readFile(join5(folder, entry))
58313
+ sql: await fs3.readFile(join6(folder, entry))
57846
58314
  });
57847
58315
  }
57848
58316
  return migrations.length > 0 ? migrations : CLI_MIGRATIONS;
@@ -57965,7 +58433,7 @@ ${SYSTEM_EVENTS_SCHEMA_SQL}
57965
58433
  ];
57966
58434
  });
57967
58435
 
57968
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/job-queue/db-job-queue.js
58436
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/job-queue/db-job-queue.js
57969
58437
  function queueLogger() {
57970
58438
  if (!_queueLogger)
57971
58439
  _queueLogger = getLogger2("job-queue");
@@ -58242,7 +58710,7 @@ var init_db_job_queue = __esm(() => {
58242
58710
  init_tracing2();
58243
58711
  });
58244
58712
 
58245
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/job-queue-db.js
58713
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/job-queue-db.js
58246
58714
  var exports_job_queue_db = {};
58247
58715
  __export(exports_job_queue_db, {
58248
58716
  DBQueueConsumer: () => DBQueueConsumer,
@@ -59213,13 +59681,13 @@ var init_envelope = __esm(() => {
59213
59681
  });
59214
59682
 
59215
59683
  // ../../packages/domain/src/planning/locks.ts
59216
- import { closeSync, fsyncSync, mkdirSync as mkdirSync4, openSync, readFileSync as readFileSync7, renameSync as renameSync3, unlinkSync, writeSync } from "fs";
59217
- import { dirname as dirname7, join as join6 } from "path";
59684
+ import { closeSync as closeSync2, fsyncSync, mkdirSync as mkdirSync5, openSync as openSync2, readFileSync as readFileSync7, renameSync as renameSync3, unlinkSync, writeSync as writeSync2 } from "fs";
59685
+ import { dirname as dirname7, join as join7 } from "path";
59218
59686
  function lockPathForEntity(folder, entityId) {
59219
- return join6(folder, `.${entityId}.lock`);
59687
+ return join7(folder, `.${entityId}.lock`);
59220
59688
  }
59221
59689
  function createLockPath(folder) {
59222
- return join6(folder, ".create.lock");
59690
+ return join7(folder, ".create.lock");
59223
59691
  }
59224
59692
  function parseLockContent(raw) {
59225
59693
  const str = typeof raw === "string" ? raw : raw.toString();
@@ -59282,14 +59750,14 @@ function acquireLock(path9, _fs, ttlMs, label) {
59282
59750
  },
59283
59751
  staleWarning
59284
59752
  });
59285
- mkdirSync4(dirname7(path9), { recursive: true });
59753
+ mkdirSync5(dirname7(path9), { recursive: true });
59286
59754
  for (let attempt = 0;attempt < 2; attempt++) {
59287
59755
  try {
59288
- const fd = openSync(path9, "wx");
59756
+ const fd = openSync2(path9, "wx");
59289
59757
  try {
59290
- writeSync(fd, content);
59758
+ writeSync2(fd, content);
59291
59759
  } finally {
59292
- closeSync(fd);
59760
+ closeSync2(fd);
59293
59761
  }
59294
59762
  return makeResult();
59295
59763
  } catch (err) {
@@ -59311,20 +59779,20 @@ function acquireLock(path9, _fs, ttlMs, label) {
59311
59779
  function fsyncPath(path9, swallowErrors = false) {
59312
59780
  let fd;
59313
59781
  try {
59314
- fd = openSync(path9, "r");
59782
+ fd = openSync2(path9, "r");
59315
59783
  fsyncSync(fd);
59316
59784
  } catch (err) {
59317
59785
  if (!swallowErrors)
59318
59786
  throw err;
59319
59787
  } finally {
59320
59788
  if (fd !== undefined)
59321
- closeSync(fd);
59789
+ closeSync2(fd);
59322
59790
  }
59323
59791
  }
59324
59792
  function atomicWrite(dest, content, entityId, fs3, projectName = "spur") {
59325
59793
  const dir = dirname7(dest);
59326
59794
  const rand = Math.random().toString(36).slice(2, 10);
59327
- const tempPath = join6(dir, `.${projectName}.${entityId}.${rand}.tmp`);
59795
+ const tempPath = join7(dir, `.${projectName}.${entityId}.${rand}.tmp`);
59328
59796
  fs3.writeFile(tempPath, content);
59329
59797
  fsyncPath(tempPath);
59330
59798
  renameSync3(tempPath, dest);
@@ -59333,7 +59801,7 @@ function atomicWrite(dest, content, entityId, fs3, projectName = "spur") {
59333
59801
  async function atomicWriteAsync(dest, content, entityId, fs3, projectName = "spur") {
59334
59802
  const dir = dirname7(dest);
59335
59803
  const rand = Math.random().toString(36).slice(2, 10);
59336
- const tempPath = join6(dir, `.${projectName}.${entityId}.${rand}.tmp`);
59804
+ const tempPath = join7(dir, `.${projectName}.${entityId}.${rand}.tmp`);
59337
59805
  await fs3.writeFile(tempPath, content);
59338
59806
  fsyncPath(tempPath);
59339
59807
  renameSync3(tempPath, dest);
@@ -59348,7 +59816,7 @@ function cleanupTempFiles(folder, entityId, fs3, projectName = "spur") {
59348
59816
  let count3 = 0;
59349
59817
  for (const entry of entries) {
59350
59818
  if (entry.startsWith(prefix) && entry.endsWith(suffix)) {
59351
- fs3.deleteFile(join6(folder, entry));
59819
+ fs3.deleteFile(join7(folder, entry));
59352
59820
  count3++;
59353
59821
  }
59354
59822
  }
@@ -60618,11 +61086,12 @@ class AgentService {
60618
61086
  const forceBuffered = silent || nonInteractive;
60619
61087
  const outputPolicy = forceBuffered ? { mode: "buffered" } : jsonOutput ? { mode: "buffered" } : { mode: "stream", isTTY: isatty3(1) };
60620
61088
  const outputMode = outputPolicy.mode;
61089
+ let publishPid;
60621
61090
  const runner = deps?.runner ?? new AiRunner({
60622
- processExecutor: new NodeProcessExecutor3({
61091
+ processExecutor: new PidObservingProcessExecutor({
60623
61092
  output: outputPolicy,
60624
61093
  ...this.ctx.processRegistry !== undefined ? { registry: this.ctx.processRegistry } : {}
60625
- }),
61094
+ }, (pid) => publishPid?.(pid)),
60626
61095
  ...this.ctx.events !== undefined ? { events: bridgeEventBus(this.ctx.events) } : {},
60627
61096
  ...this.ctx.events !== undefined ? { processEvents: bridgeEventBus(this.ctx.events) } : {}
60628
61097
  });
@@ -60651,6 +61120,7 @@ class AgentService {
60651
61120
  const onTerminate = () => controller.abort();
60652
61121
  const onExternalAbort = () => controller.abort();
60653
61122
  const lifecycle = new AgentExecutionLifecycle(options.execution?.observer, options.execution?.correlation, configuredSecretValues(this.ctx.env), options.execution?.heartbeatMs);
61123
+ publishPid = (pid) => lifecycle.setPid(pid);
60654
61124
  process.on("SIGTERM", onTerminate);
60655
61125
  process.on("SIGINT", onTerminate);
60656
61126
  options.execution?.signal?.addEventListener("abort", onExternalAbort, { once: true });
@@ -60818,7 +61288,7 @@ class AgentService {
60818
61288
  return {
60819
61289
  ok: false,
60820
61290
  exitCode: 2,
60821
- message: "'inline' selects in-session execution and cannot be passed to 'spur agent run', which always starts a subprocess. Run the backing skill directly in the current session, or use '--agent auto' for subprocess dispatch with a tier-resolved executor."
61291
+ message: "'inline' selects in-session execution and cannot be passed to 'spur agent run', which always starts a subprocess. Run the backing skill directly in the current session, or redirect pipeline stages via agent.default / '--agent auto' / '--agent <name>' (ADR-046)."
60822
61292
  };
60823
61293
  }
60824
61294
  return this.resolveExecutorSelector(raw, doctorRunner, "explicit");
@@ -61150,12 +61620,28 @@ function classifyObjectiveFailure(result) {
61150
61620
  }
61151
61621
  return;
61152
61622
  }
61153
- var TRACE_SAFE_SLASH_COMMAND, TRACE_SAFE_SLASH_TOKEN, SENSITIVE_FLAG, SENSITIVE_INLINE_FLAG;
61623
+ var PidObservingProcessExecutor, TRACE_SAFE_SLASH_COMMAND, TRACE_SAFE_SLASH_TOKEN, SENSITIVE_FLAG, SENSITIVE_INLINE_FLAG;
61154
61624
  var init_agent_service = __esm(() => {
61155
61625
  init_src2();
61156
61626
  init_dist9();
61157
61627
  init_dist5();
61158
61628
  init_agent_execution();
61629
+ PidObservingProcessExecutor = class PidObservingProcessExecutor extends NodeProcessExecutor3 {
61630
+ publishPid;
61631
+ constructor(config4, publishPid) {
61632
+ super(config4);
61633
+ this.publishPid = publishPid;
61634
+ }
61635
+ async run(options) {
61636
+ return super.run({
61637
+ ...options,
61638
+ onSpawn: (pid) => {
61639
+ options.onSpawn?.(pid);
61640
+ this.publishPid(pid);
61641
+ }
61642
+ });
61643
+ }
61644
+ };
61159
61645
  TRACE_SAFE_SLASH_COMMAND = /^(?:\/skill:(?:sp|rd3)-|\/(?:sp|rd3)[:-]|\$(?:sp|rd3)-)[A-Za-z0-9._-]+(?:\s|$)/;
61160
61646
  TRACE_SAFE_SLASH_TOKEN = /^(?:\d{4}|--(?:auto|next|force|bdd)|--(?:mode|fix|focus)|implement|test|review|verify|all|none|blockers-first|quick|requirements|background|constraints|acceptance)$/;
61161
61647
  SENSITIVE_FLAG = /^--?(?:api[-_]?key|authorization|credential|password|secret|token)$/i;
@@ -61163,7 +61649,7 @@ var init_agent_service = __esm(() => {
61163
61649
  });
61164
61650
 
61165
61651
  // ../../packages/app/src/services/corpus-migrator.ts
61166
- import { join as join7, relative } from "path";
61652
+ import { join as join8, relative } from "path";
61167
61653
  function applyM1(data, flags) {
61168
61654
  const raw = data.status;
61169
61655
  if (typeof raw !== "string")
@@ -61463,7 +61949,7 @@ class CorpusMigrator {
61463
61949
  }
61464
61950
  async discoverFiles() {
61465
61951
  const entries = await this.fs.readDir(this.corpusDir);
61466
- return entries.filter((name) => name.endsWith(".md")).filter((name) => name !== "kanban.md").map((name) => join7(this.corpusDir, name)).sort();
61952
+ return entries.filter((name) => name.endsWith(".md")).filter((name) => name !== "kanban.md").map((name) => join8(this.corpusDir, name)).sort();
61467
61953
  }
61468
61954
  async migrateFile(filePath, dryRun, gitDates = new Map) {
61469
61955
  const flags = [];
@@ -61770,7 +62256,7 @@ function normalizeSystemEventPayload(entry, eventPayload, secretValues = []) {
61770
62256
  }
61771
62257
  function redactSecretValue(value, secretValues) {
61772
62258
  if (typeof value === "string")
61773
- return redactAndBound(value, secretValues, MAX_FIELD_LENGTH);
62259
+ return redactAndBound(value, secretValues, MAX_FIELD_LENGTH2);
61774
62260
  if (Array.isArray(value))
61775
62261
  return value.map((item) => redactSecretValue(item, secretValues));
61776
62262
  if (value !== null && typeof value === "object") {
@@ -61784,7 +62270,7 @@ function redactSecretValues(payload, secretValues) {
61784
62270
  }
61785
62271
  return payload;
61786
62272
  }
61787
- var SYSTEM_EVENT_CATALOG, SYSTEM_EVENT_NAMES, SYSTEM_EVENT_PERSISTED_NAMES, SYSTEM_EVENT_STREAMED_NAMES, SYSTEM_EVENT_PREFIXES, SYSTEM_EVENT_DEFAULT_NAMES, SYSTEM_EVENT_DIAGNOSTIC_NAMES, PLANNING_EVENT_NAMES, SYSTEM_EVENT_CATALOG_METADATA, MAX_FIELD_LENGTH = 256;
62273
+ var SYSTEM_EVENT_CATALOG, SYSTEM_EVENT_NAMES, SYSTEM_EVENT_PERSISTED_NAMES, SYSTEM_EVENT_STREAMED_NAMES, SYSTEM_EVENT_PREFIXES, SYSTEM_EVENT_DEFAULT_NAMES, SYSTEM_EVENT_DIAGNOSTIC_NAMES, PLANNING_EVENT_NAMES, SYSTEM_EVENT_CATALOG_METADATA, MAX_FIELD_LENGTH2 = 256;
61788
62274
  var init_event_names = __esm(() => {
61789
62275
  init_agent_execution();
61790
62276
  SYSTEM_EVENT_CATALOG = [
@@ -62008,7 +62494,7 @@ __export(exports_feature_check, {
62008
62494
  FeatureCheckService: () => FeatureCheckService,
62009
62495
  DEFAULT_FEATURE_MATRIX: () => DEFAULT_FEATURE_MATRIX
62010
62496
  });
62011
- import { dirname as dirname8, join as join8 } from "path";
62497
+ import { dirname as dirname8, join as join9 } from "path";
62012
62498
  function isGroupFeature(fm) {
62013
62499
  const tags = fm.tags;
62014
62500
  return Array.isArray(tags) && tags.includes("group") ? "group" : "standard";
@@ -62106,9 +62592,9 @@ function decodeVerdictRows(source, sectionName, required2) {
62106
62592
  function defaultVerdictRunDir(tasksDir) {
62107
62593
  const norm = tasksDir.replace(/\\/g, "/");
62108
62594
  if (/\/docs\/tasks\d*$/.test(norm) || /\/docs\/tasks$/.test(norm)) {
62109
- return join8(dirname8(dirname8(tasksDir)), ".spur", "run");
62595
+ return join9(dirname8(dirname8(tasksDir)), ".spur", "run");
62110
62596
  }
62111
- return join8(dirname8(tasksDir), ".spur", "run");
62597
+ return join9(dirname8(tasksDir), ".spur", "run");
62112
62598
  }
62113
62599
  function rowMatchesScenario(id, sc) {
62114
62600
  const stripped = id.replace(/^\[[^\]]*\]\s*/, "").replace(/^Scenario:\s*/i, "").replace(/^\[[^\]]*\]\s*/, "").trim();
@@ -62207,7 +62693,7 @@ var init_feature_check = __esm(() => {
62207
62693
  await this.checkOneActiveGoal(fm, featureId2, options.featuresDir, findings, options.asStatus);
62208
62694
  await this.checkChildrenLimit(featureId2, options.featuresDir, findings);
62209
62695
  }
62210
- const dogfoodDir = options?.dogfoodDir ?? (options?.featuresDir ? join8(dirname8(options.featuresDir), "dogfood") : undefined);
62696
+ const dogfoodDir = options?.dogfoodDir ?? (options?.featuresDir ? join9(dirname8(options.featuresDir), "dogfood") : undefined);
62211
62697
  const runDir = options?.runDir ?? (options?.tasksDir ? defaultVerdictRunDir(options.tasksDir) : undefined);
62212
62698
  await this.runL4(doc2, featureId2, status, options?.tasksDir, dogfoodDir, runDir, findings);
62213
62699
  return { id: featureId2, ...this.summarizeWithStatus(status, findings, strict, options?.severityOverrides) };
@@ -63066,7 +63552,7 @@ class FeatureService {
63066
63552
  }
63067
63553
  }
63068
63554
  async applyMove(all, movedSet, mapping, affectedTasks, movedCount) {
63069
- const now = new Date().toISOString();
63555
+ const now2 = new Date().toISOString();
63070
63556
  const created = [];
63071
63557
  const removed = [];
63072
63558
  try {
@@ -63077,8 +63563,8 @@ class FeatureService {
63077
63563
  const raw = await this.ctx.fs.readFile(f.filePath);
63078
63564
  const doc2 = MarkdownDocument.parse(raw, "feature");
63079
63565
  doc2.setFrontmatterField("id", `"${newId}"`);
63080
- doc2.setFrontmatterField("updated_at", now);
63081
- appendFeatureHistory(doc2, now, `moved ${f.id} \u2192 ${newId}`);
63566
+ doc2.setFrontmatterField("updated_at", now2);
63567
+ appendFeatureHistory(doc2, now2, `moved ${f.id} \u2192 ${newId}`);
63082
63568
  const slug = basename(f.filePath).replace(/^[A-Z][1-9]*_/, "").replace(/\.md$/, "");
63083
63569
  const newPath = `${this.ctx.featuresDir}/${newId}_${slug}.md`;
63084
63570
  removed.push({ path: f.filePath, content: raw });
@@ -63094,7 +63580,7 @@ class FeatureService {
63094
63580
  const raw = await this.ctx.fs.readFile(task.path);
63095
63581
  const doc2 = MarkdownDocument.parse(raw, "task");
63096
63582
  doc2.setFrontmatterField("feature_id", newFid);
63097
- doc2.setFrontmatterField("updated_at", now);
63583
+ doc2.setFrontmatterField("updated_at", now2);
63098
63584
  removed.push({ path: task.path, content: raw });
63099
63585
  await atomicWriteAsync(task.path, doc2.serialize(), task.wbs, this.ctx.fs, this.ctx.projectName ?? "spur");
63100
63586
  }
@@ -63215,7 +63701,7 @@ class FeatureService {
63215
63701
  throw new Error(`Parent ${parentId} has reached the 9-child limit`);
63216
63702
  }
63217
63703
  templateContent(id, name) {
63218
- const now = new Date().toISOString();
63704
+ const now2 = new Date().toISOString();
63219
63705
  return `---
63220
63706
  schema_version: 1
63221
63707
  id: "${id}"
@@ -63223,8 +63709,8 @@ name: "${name}"
63223
63709
  status: backlog
63224
63710
  priority: P2
63225
63711
  tags: []
63226
- created_at: "${now}"
63227
- updated_at: "${now}"
63712
+ created_at: "${now2}"
63713
+ updated_at: "${now2}"
63228
63714
  ---
63229
63715
 
63230
63716
  # ${id}: ${name}
@@ -63567,10 +64053,10 @@ class PlanningWriteService {
63567
64053
  fromStatus = resolved.from;
63568
64054
  toStatus = resolved.to;
63569
64055
  }
63570
- const now = new Date().toISOString();
63571
- doc2.setFrontmatterField("updated_at", now);
64056
+ const now2 = new Date().toISOString();
64057
+ doc2.setFrontmatterField("updated_at", now2);
63572
64058
  if (statusChanged && fromStatus !== undefined && toStatus !== undefined) {
63573
- appendHistoryLine(doc2, now, fromStatus, toStatus, mutation.actor ?? "system");
64059
+ appendHistoryLine(doc2, now2, fromStatus, toStatus, mutation.actor ?? "system");
63574
64060
  }
63575
64061
  const serialized = doc2.serialize();
63576
64062
  await atomicWriteAsync(ref.filePath, serialized, ref.id, this.fs, this.projectName);
@@ -63578,7 +64064,7 @@ class PlanningWriteService {
63578
64064
  const event2 = {
63579
64065
  event: eventName,
63580
64066
  entity: { kind: domain2, id: ref.id },
63581
- at: now,
64067
+ at: now2,
63582
64068
  ...fromStatus !== undefined ? { from: fromStatus } : {},
63583
64069
  ...toStatus !== undefined ? { to: toStatus } : {}
63584
64070
  };
@@ -63893,17 +64379,17 @@ var init_process_inventory_service = __esm(() => {
63893
64379
  });
63894
64380
 
63895
64381
  // ../../packages/app/src/services/project-registry.ts
63896
- import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync8, realpathSync as realpathSync3, renameSync as renameSync4, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
64382
+ import { existsSync as existsSync5, mkdirSync as mkdirSync6, readFileSync as readFileSync8, realpathSync as realpathSync3, renameSync as renameSync4, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
63897
64383
  import { connect, createServer } from "net";
63898
64384
  import { homedir as homedir3 } from "os";
63899
- import { dirname as dirname9, join as join9, resolve } from "path";
64385
+ import { dirname as dirname9, join as join10, resolve } from "path";
63900
64386
  function normalizeProjectPath(pathInput) {
63901
64387
  const trimmed = pathInput.trim();
63902
64388
  let expanded = trimmed;
63903
64389
  if (trimmed === "~") {
63904
64390
  expanded = homedir3();
63905
64391
  } else if (trimmed.startsWith("~/")) {
63906
- expanded = join9(homedir3(), trimmed.slice(2));
64392
+ expanded = join10(homedir3(), trimmed.slice(2));
63907
64393
  } else {
63908
64394
  expanded = resolve(trimmed);
63909
64395
  }
@@ -63963,13 +64449,13 @@ class ProjectRegistry {
63963
64449
  async withLock(fn) {
63964
64450
  const lockParent = dirname9(this.lockDir);
63965
64451
  if (!existsSync5(lockParent)) {
63966
- mkdirSync5(lockParent, { recursive: true });
64452
+ mkdirSync6(lockParent, { recursive: true });
63967
64453
  }
63968
64454
  const maxTries = 50;
63969
64455
  let acquired = false;
63970
64456
  for (let i2 = 0;i2 < maxTries; i2++) {
63971
64457
  try {
63972
- mkdirSync5(this.lockDir);
64458
+ mkdirSync6(this.lockDir);
63973
64459
  acquired = true;
63974
64460
  break;
63975
64461
  } catch {
@@ -63979,7 +64465,7 @@ class ProjectRegistry {
63979
64465
  if (!acquired) {
63980
64466
  try {
63981
64467
  rmSync3(this.lockDir, { recursive: true, force: true });
63982
- mkdirSync5(this.lockDir);
64468
+ mkdirSync6(this.lockDir);
63983
64469
  acquired = true;
63984
64470
  } catch {
63985
64471
  throw new Error(`Failed to acquire lock for project registry: ${this.lockDir}`);
@@ -64010,7 +64496,7 @@ class ProjectRegistry {
64010
64496
  writeRaw(data) {
64011
64497
  const parentDir2 = dirname9(this.filePath);
64012
64498
  if (!existsSync5(parentDir2)) {
64013
- mkdirSync5(parentDir2, { recursive: true });
64499
+ mkdirSync6(parentDir2, { recursive: true });
64014
64500
  }
64015
64501
  const tmpFile = `${this.filePath}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
64016
64502
  const content = JSON.stringify(data, null, 2);
@@ -64284,7 +64770,7 @@ var init_project_start = __esm(() => {
64284
64770
 
64285
64771
  // ../../packages/app/src/services/rule-service.ts
64286
64772
  import { homedir as homedir4 } from "os";
64287
- import { delimiter, join as join10, relative as relative2, resolve as resolve3 } from "path";
64773
+ import { delimiter, join as join11, relative as relative2, resolve as resolve3 } from "path";
64288
64774
 
64289
64775
  class RuleService {
64290
64776
  context;
@@ -64472,13 +64958,13 @@ ${ruleIds.join(`
64472
64958
  const hasGlobalOverride = globalOverride !== undefined && globalOverride.length > 0;
64473
64959
  layers.push({
64474
64960
  id: "global",
64475
- path: hasGlobalOverride ? resolve3(cwd, globalOverride) : join10(homedir4(), GLOBAL_RULES_DIR),
64961
+ path: hasGlobalOverride ? resolve3(cwd, globalOverride) : join11(homedir4(), GLOBAL_RULES_DIR),
64476
64962
  priority: 10
64477
64963
  });
64478
64964
  if (opts.includeBundled && !hasGlobalOverride) {
64479
64965
  const bundledConfig = bundledConfigRoot();
64480
64966
  if (bundledConfig !== null) {
64481
- layers.push({ id: "bundled-config", path: join10(bundledConfig, "rules"), priority: 15 });
64967
+ layers.push({ id: "bundled-config", path: join11(bundledConfig, "rules"), priority: 15 });
64482
64968
  }
64483
64969
  const bundled = await bundledRulesRoot();
64484
64970
  if (bundled !== null)
@@ -64652,7 +65138,7 @@ ${ruleIds.join(`
64652
65138
  const { fs: fs3 } = this.context;
64653
65139
  for (const root of await this.ruleRoots()) {
64654
65140
  for (const ext of ["yaml", "yml", "json"]) {
64655
- if (await fs3.exists(join10(root, `${name}.${ext}`)))
65141
+ if (await fs3.exists(join11(root, `${name}.${ext}`)))
64656
65142
  return true;
64657
65143
  }
64658
65144
  }
@@ -64688,7 +65174,7 @@ ${ruleIds.join(`
64688
65174
  for (const layer of await this.existingRuleSourceLayers()) {
64689
65175
  const entries = await this.context.fs.readDir(layer.path);
64690
65176
  const named = entries.map((entry) => ({ entry, name: entry.match(/^([\w-]+)\.(?:ya?ml|json)$/i)?.[1] ?? "" })).filter(({ name }) => name.length > 0);
64691
- const stats = await Promise.all(named.map(({ entry }) => this.context.fs.stat(join10(layer.path, entry))));
65177
+ const stats = await Promise.all(named.map(({ entry }) => this.context.fs.stat(join11(layer.path, entry))));
64692
65178
  named.forEach(({ name }, i2) => {
64693
65179
  if (stats[i2]?.isFile())
64694
65180
  candidates.add(name);
@@ -64710,7 +65196,7 @@ ${ruleIds.join(`
64710
65196
  for (const layer of layers) {
64711
65197
  for (const file2 of await this.listRuleFilesInLayer(layer.path)) {
64712
65198
  if (!merged.has(file2))
64713
- merged.set(file2, { absolutePath: join10(layer.path, file2), source: layer.id });
65199
+ merged.set(file2, { absolutePath: join11(layer.path, file2), source: layer.id });
64714
65200
  }
64715
65201
  }
64716
65202
  const files = [];
@@ -64778,7 +65264,7 @@ ${ruleIds.join(`
64778
65264
  for (const entry of entries.sort()) {
64779
65265
  if (entry === "presets")
64780
65266
  continue;
64781
- const stat = await this.context.fs.stat(join10(root, entry));
65267
+ const stat = await this.context.fs.stat(join11(root, entry));
64782
65268
  if (stat?.isDirectory())
64783
65269
  dirs.push(entry);
64784
65270
  }
@@ -64786,12 +65272,12 @@ ${ruleIds.join(`
64786
65272
  }
64787
65273
  async listRuleFiles(root, relativeDir) {
64788
65274
  const { fs: fs3 } = this.context;
64789
- const dir = join10(root, relativeDir);
65275
+ const dir = join11(root, relativeDir);
64790
65276
  const entries = await fs3.readDir(dir);
64791
65277
  const files = [];
64792
65278
  for (const entry of entries.sort()) {
64793
- const relativePath2 = relativeDir.length === 0 ? entry : join10(relativeDir, entry);
64794
- const absolutePath = join10(root, relativePath2);
65279
+ const relativePath2 = relativeDir.length === 0 ? entry : join11(relativeDir, entry);
65280
+ const absolutePath = join11(root, relativePath2);
64795
65281
  const stat = await fs3.stat(absolutePath);
64796
65282
  if (stat?.isDirectory()) {
64797
65283
  files.push(...await this.listRuleFiles(root, relativePath2));
@@ -64816,8 +65302,8 @@ var init_rule_service = __esm(() => {
64816
65302
  init_src2();
64817
65303
  init_dist6();
64818
65304
  init_dist10();
64819
- LOCAL_RULES_DIR = join10(".spur", "rules");
64820
- GLOBAL_RULES_DIR = join10(".config", "spur", "rules");
65305
+ LOCAL_RULES_DIR = join11(".spur", "rules");
65306
+ GLOBAL_RULES_DIR = join11(".config", "spur", "rules");
64821
65307
  SEVERITY_RANK2 = {
64822
65308
  info: 0,
64823
65309
  warning: 1,
@@ -64885,7 +65371,7 @@ function summarizeActionResult(resultJson, secretValues = []) {
64885
65371
  return redactValue3(parsed, secretValues);
64886
65372
  }
64887
65373
  function redactString(value, secretValues) {
64888
- return redactAndBound(value, secretValues, MAX_FIELD_LENGTH2);
65374
+ return redactAndBound(value, secretValues, MAX_FIELD_LENGTH3);
64889
65375
  }
64890
65376
  function redactValue3(value, secretValues) {
64891
65377
  if (value === null || value === undefined)
@@ -65008,7 +65494,7 @@ class RunStoreService {
65008
65494
  return { wbs, links, count: links.length };
65009
65495
  }
65010
65496
  }
65011
- var RUN_STORE_LIST_DEFAULT_LIMIT = 50, RUN_STORE_LIST_MAX_LIMIT = 200, RUN_STORE_WBS_DEFAULT_LIMIT = 50, RUN_STORE_WBS_MAX_LIMIT = 200, MAX_FIELD_LENGTH2 = 256, SENSITIVE_KEYS, RunStoreNotFoundError, RunStoreBadCursorError;
65497
+ var RUN_STORE_LIST_DEFAULT_LIMIT = 50, RUN_STORE_LIST_MAX_LIMIT = 200, RUN_STORE_WBS_DEFAULT_LIMIT = 50, RUN_STORE_WBS_MAX_LIMIT = 200, MAX_FIELD_LENGTH3 = 256, SENSITIVE_KEYS, RunStoreNotFoundError, RunStoreBadCursorError;
65012
65498
  var init_run_store_service = __esm(() => {
65013
65499
  init_src2();
65014
65500
  init_agent_execution();
@@ -65451,7 +65937,7 @@ var init_system_event_emitter = __esm(() => {
65451
65937
  });
65452
65938
 
65453
65939
  // ../../packages/app/src/services/task-check.ts
65454
- import { dirname as dirname10, join as join11 } from "path";
65940
+ import { dirname as dirname10, join as join12 } from "path";
65455
65941
  function isPlaceholderBody(body) {
65456
65942
  const stripped = body.replace(/<!--[\s\S]*?-->/g, "").replace(/^\s*>\s*TBD\s*$/gim, "").trim();
65457
65943
  return stripped.length === 0;
@@ -65600,7 +66086,7 @@ var init_task_check = __esm(() => {
65600
66086
  this.runL2(doc2, entry, findings);
65601
66087
  this.runL3(doc2, entry, status, findings);
65602
66088
  const tasksDir = dirname10(filePath);
65603
- const featuresDir = join11(dirname10(tasksDir), "features");
66089
+ const featuresDir = join12(dirname10(tasksDir), "features");
65604
66090
  await this.runL4(doc2, fm, status, findings, featuresDir, tasksDir);
65605
66091
  await this.runL4Rollup(doc2, wbs, status, findings, tasksDir);
65606
66092
  if (status !== "done" && status !== "cancelled") {
@@ -65996,7 +66482,7 @@ var init_task_check = __esm(() => {
65996
66482
  for (const cite of citations) {
65997
66483
  if (reported >= 5)
65998
66484
  break;
65999
- const abs = join11(projectRoot, cite.path);
66485
+ const abs = join12(projectRoot, cite.path);
66000
66486
  let exists2 = false;
66001
66487
  try {
66002
66488
  exists2 = await this.fs.exists(abs);
@@ -66539,7 +67025,7 @@ class TaskService {
66539
67025
  }
66540
67026
  async findDuplicateFollowUp(featureId2, title, withinSec) {
66541
67027
  const siblings = await this.list({ featureId: featureId2 });
66542
- const now = Date.now();
67028
+ const now2 = Date.now();
66543
67029
  const lowerTitle = title.toLowerCase();
66544
67030
  for (const t of siblings) {
66545
67031
  if ((t.name ?? "").toLowerCase() !== lowerTitle)
@@ -66550,7 +67036,7 @@ class TaskService {
66550
67036
  const createdMs = Date.parse(createdAt);
66551
67037
  if (Number.isNaN(createdMs))
66552
67038
  continue;
66553
- const ageSec = (now - createdMs) / 1000;
67039
+ const ageSec = (now2 - createdMs) / 1000;
66554
67040
  if (ageSec >= 0 && ageSec <= withinSec) {
66555
67041
  return { wbs: t.wbs, name: t.name };
66556
67042
  }
@@ -66575,7 +67061,7 @@ class TaskService {
66575
67061
  }
66576
67062
  const slug = this.slugify(params.title);
66577
67063
  const { wbs, filePath } = await this.allocateWbsChecked(slug);
66578
- const now = new Date().toISOString();
67064
+ const now2 = new Date().toISOString();
66579
67065
  const rawTemplate = this.ctx.resolveTemplate?.(variant);
66580
67066
  if (rawTemplate !== undefined) {
66581
67067
  const content2 = renderCreatedTaskContent({
@@ -66583,7 +67069,7 @@ class TaskService {
66583
67069
  name: params.title,
66584
67070
  wbs,
66585
67071
  background,
66586
- createdAt: now,
67072
+ createdAt: now2,
66587
67073
  status,
66588
67074
  variant,
66589
67075
  featureId: params.featureId,
@@ -66597,8 +67083,8 @@ class TaskService {
66597
67083
  `name: "${params.title}"`,
66598
67084
  `status: ${status}`,
66599
67085
  `template: ${variant}`,
66600
- `created_at: ${now}`,
66601
- `updated_at: ${now}`,
67086
+ `created_at: ${now2}`,
67087
+ `updated_at: ${now2}`,
66602
67088
  params.featureId !== undefined ? `feature_id: ${params.featureId}` : null,
66603
67089
  params.parentWbs !== undefined ? `parent_wbs: "${params.parentWbs}"` : null
66604
67090
  ].filter(Boolean).join(`
@@ -66979,7 +67465,7 @@ ${issues}`);
66979
67465
  return this.writeService.createAllocated(folder, async () => {
66980
67466
  const slug = this.slugify(item.name);
66981
67467
  const { wbs, filePath } = await this.allocateWbsChecked(slug);
66982
- const now = new Date().toISOString();
67468
+ const now2 = new Date().toISOString();
66983
67469
  const rawTemplate = this.ctx.resolveTemplate?.(variant);
66984
67470
  if (rawTemplate !== undefined) {
66985
67471
  const content2 = renderCreatedTaskContent({
@@ -66987,7 +67473,7 @@ ${issues}`);
66987
67473
  name: item.name,
66988
67474
  wbs,
66989
67475
  background,
66990
- createdAt: now,
67476
+ createdAt: now2,
66991
67477
  status,
66992
67478
  variant,
66993
67479
  featureId: item.feature_id ?? undefined,
@@ -67007,8 +67493,8 @@ ${issues}`);
67007
67493
  `name: "${item.name}"`,
67008
67494
  `status: ${status}`,
67009
67495
  `template: ${variant}`,
67010
- `created_at: ${now}`,
67011
- `updated_at: ${now}`,
67496
+ `created_at: ${now2}`,
67497
+ `updated_at: ${now2}`,
67012
67498
  item.feature_id !== undefined ? `feature_id: ${item.feature_id}` : null,
67013
67499
  item.parent_wbs !== undefined ? `parent_wbs: "${item.parent_wbs}"` : null,
67014
67500
  item.priority !== undefined ? `priority: ${item.priority}` : null,
@@ -67532,7 +68018,7 @@ var init_task_verdict = __esm(() => {
67532
68018
  });
67533
68019
 
67534
68020
  // ../../packages/app/src/services/team-service.ts
67535
- import { join as join12 } from "path";
68021
+ import { join as join13 } from "path";
67536
68022
 
67537
68023
  class TeamService {
67538
68024
  ctx;
@@ -67540,7 +68026,7 @@ class TeamService {
67540
68026
  orchestratorPromise;
67541
68027
  constructor(ctx) {
67542
68028
  this.ctx = ctx;
67543
- this.configDir = join12(ctx.cwd, ".spur", "agents");
68029
+ this.configDir = join13(ctx.cwd, ".spur", "agents");
67544
68030
  }
67545
68031
  async sendMessage(fromId, toId, body, replyTo) {
67546
68032
  validateAgentId(toId);
@@ -67950,7 +68436,7 @@ class TeamService {
67950
68436
  async resolveTaskFile(taskId) {
67951
68437
  const fs3 = this.ctx.fs;
67952
68438
  const { foldersConfig } = await resolvePlanningFolders(fs3);
67953
- const dirs = [...new Set([foldersConfig.active_folder, ...Object.keys(foldersConfig.folders)])].map((dir) => join12(this.ctx.cwd, dir));
68439
+ const dirs = [...new Set([foldersConfig.active_folder, ...Object.keys(foldersConfig.folders)])].map((dir) => join13(this.ctx.cwd, dir));
67954
68440
  return await TaskLocator.forDirs(fs3, dirs).findPathByWbs(taskId);
67955
68441
  }
67956
68442
  }
@@ -67986,8 +68472,8 @@ var init_team_service = __esm(() => {
67986
68472
  });
67987
68473
 
67988
68474
  // ../../packages/app/src/services/token-ledger-service.ts
67989
- import { closeSync as closeSync2, existsSync as existsSync7, fstatSync, openSync as openSync2, readSync } from "fs";
67990
- import { join as join13 } from "path";
68475
+ import { closeSync as closeSync3, existsSync as existsSync7, fstatSync, openSync as openSync3, readSync } from "fs";
68476
+ import { join as join14 } from "path";
67991
68477
  function isSparseToolActivity(events2) {
67992
68478
  return events2.length === 0 || !events2.some((e) => TOOL_ACTIVITY_TYPES.has(e.type));
67993
68479
  }
@@ -68042,7 +68528,7 @@ function tailTokenLedgerFile(filePath, limit, chunkSize = DEFAULT_CHUNK, before)
68042
68528
  return { events: [], truncated: false };
68043
68529
  }
68044
68530
  const target = limit + 1;
68045
- const fd = openSync2(filePath, "r");
68531
+ const fd = openSync3(filePath, "r");
68046
68532
  try {
68047
68533
  const { size } = fstatSync(fd);
68048
68534
  if (size === 0)
@@ -68080,7 +68566,7 @@ function tailTokenLedgerFile(filePath, limit, chunkSize = DEFAULT_CHUNK, before)
68080
68566
  truncated
68081
68567
  };
68082
68568
  } finally {
68083
- closeSync2(fd);
68569
+ closeSync3(fd);
68084
68570
  }
68085
68571
  }
68086
68572
 
@@ -68088,7 +68574,7 @@ class TokenLedgerService {
68088
68574
  ledgerPath;
68089
68575
  chunkSize;
68090
68576
  constructor(options) {
68091
- this.ledgerPath = options.ledgerPath ?? join13(options.cwd, TOKEN_LEDGER_RELATIVE_PATH);
68577
+ this.ledgerPath = options.ledgerPath ?? join14(options.cwd, TOKEN_LEDGER_RELATIVE_PATH);
68092
68578
  this.chunkSize = options.chunkSize ?? DEFAULT_CHUNK;
68093
68579
  }
68094
68580
  get path() {
@@ -68129,12 +68615,12 @@ class TokenLedgerService {
68129
68615
  var TOOL_ACTIVITY_TYPES, TOKEN_LEDGER_DEFAULT_LIMIT = 200, TOKEN_LEDGER_MAX_LIMIT = 1000, TOKEN_LEDGER_RELATIVE_PATH, DEFAULT_CHUNK;
68130
68616
  var init_token_ledger_service = __esm(() => {
68131
68617
  TOOL_ACTIVITY_TYPES = new Set(["read", "write", "bash", "grep", "glob"]);
68132
- TOKEN_LEDGER_RELATIVE_PATH = join13(".spur", "context", "token-ledger.jsonl");
68618
+ TOKEN_LEDGER_RELATIVE_PATH = join14(".spur", "context", "token-ledger.jsonl");
68133
68619
  DEFAULT_CHUNK = 64 * 1024;
68134
68620
  });
68135
68621
 
68136
68622
  // ../../packages/app/src/services/token-ledger-watcher.ts
68137
- import { closeSync as closeSync3, existsSync as existsSync8, fstatSync as fstatSync2, openSync as openSync3, readSync as readSync2, watch } from "fs";
68623
+ import { closeSync as closeSync4, existsSync as existsSync8, fstatSync as fstatSync2, openSync as openSync4, readSync as readSync2, watch } from "fs";
68138
68624
 
68139
68625
  class TokenLedgerWatcher {
68140
68626
  ledgerPath;
@@ -68193,11 +68679,11 @@ class TokenLedgerWatcher {
68193
68679
  if (!existsSync8(this.ledgerPath))
68194
68680
  return 0;
68195
68681
  try {
68196
- const fd = openSync3(this.ledgerPath, "r");
68682
+ const fd = openSync4(this.ledgerPath, "r");
68197
68683
  try {
68198
68684
  return fstatSync2(fd).size;
68199
68685
  } finally {
68200
- closeSync3(fd);
68686
+ closeSync4(fd);
68201
68687
  }
68202
68688
  } catch {
68203
68689
  return 0;
@@ -68219,7 +68705,7 @@ class TokenLedgerWatcher {
68219
68705
  }
68220
68706
  let size;
68221
68707
  try {
68222
- const fd = openSync3(this.ledgerPath, "r");
68708
+ const fd = openSync4(this.ledgerPath, "r");
68223
68709
  try {
68224
68710
  size = fstatSync2(fd).size;
68225
68711
  if (size < this.offset) {
@@ -68247,7 +68733,7 @@ class TokenLedgerWatcher {
68247
68733
  }
68248
68734
  }
68249
68735
  } finally {
68250
- closeSync3(fd);
68736
+ closeSync4(fd);
68251
68737
  }
68252
68738
  } catch {}
68253
68739
  }
@@ -68256,110 +68742,6 @@ var init_token_ledger_watcher = __esm(() => {
68256
68742
  init_token_ledger_service();
68257
68743
  });
68258
68744
 
68259
- // ../../packages/app/src/observability/run-output-sink.ts
68260
- import { closeSync as closeSync4, mkdirSync as mkdirSync6, openSync as openSync4, writeSync as writeSync2 } from "fs";
68261
- import { join as join14 } from "path";
68262
-
68263
- class RunOutputSink {
68264
- filePath;
68265
- maxBytes;
68266
- maxLines;
68267
- fd;
68268
- bytes = 0;
68269
- lines = 0;
68270
- truncated = false;
68271
- closed = false;
68272
- constructor(options) {
68273
- this.filePath = join14(options.dir, `${options.runId}-output.log`);
68274
- this.maxBytes = options.maxBytes ?? DEFAULT_OUTPUT_MAX_BYTES;
68275
- this.maxLines = options.maxLines;
68276
- try {
68277
- mkdirSync6(options.dir, { recursive: true });
68278
- this.fd = openSync4(this.filePath, "a");
68279
- } catch {
68280
- this.fd = undefined;
68281
- }
68282
- }
68283
- get isTruncated() {
68284
- return this.truncated;
68285
- }
68286
- observe(event2) {
68287
- if (this.fd === undefined || this.closed)
68288
- return;
68289
- switch (event2.kind) {
68290
- case "output":
68291
- this.appendChunk(event2.at, event2.stream, event2.chunk);
68292
- break;
68293
- case "started":
68294
- this.append(`# agent output \u2014 run ${event2.runId} \u2014 ${event2.agent} \u2014 ${event2.at}
68295
- `);
68296
- this.append(`# invocation: ${event2.invocation}
68297
- `);
68298
- break;
68299
- case "dropped":
68300
- this.append(`
68301
- === [dropped] ${event2.chunks} chunk(s) discarded by the lifecycle relay under backpressure ===
68302
- `);
68303
- break;
68304
- case "finished":
68305
- this.append(`
68306
- === run ${event2.outcome} (exit ${event2.exitCode}) after ${event2.durationMs}ms ===
68307
- `);
68308
- break;
68309
- default:
68310
- break;
68311
- }
68312
- }
68313
- close() {
68314
- if (this.closed)
68315
- return;
68316
- this.closed = true;
68317
- if (this.fd !== undefined) {
68318
- try {
68319
- closeSync4(this.fd);
68320
- } catch {}
68321
- this.fd = undefined;
68322
- }
68323
- }
68324
- appendChunk(at, stream, chunk) {
68325
- if (this.truncated)
68326
- return;
68327
- const text4 = `[${at}] ${stream}: ${chunk}
68328
- `;
68329
- const chunkBytes = Buffer.byteLength(text4);
68330
- const chunkLines = countNewlines(text4);
68331
- if (this.bytes + chunkBytes > this.maxBytes || this.maxLines !== undefined && this.lines + chunkLines > this.maxLines) {
68332
- this.truncated = true;
68333
- this.append(TRUNCATION_MARKER);
68334
- return;
68335
- }
68336
- this.append(text4);
68337
- }
68338
- append(text4) {
68339
- if (this.fd === undefined || this.closed)
68340
- return;
68341
- try {
68342
- writeSync2(this.fd, text4);
68343
- this.bytes += Buffer.byteLength(text4);
68344
- this.lines += countNewlines(text4);
68345
- } catch {}
68346
- }
68347
- }
68348
- function countNewlines(text4) {
68349
- let count3 = 0;
68350
- for (let i2 = 0;i2 < text4.length; i2 += 1) {
68351
- if (text4.charCodeAt(i2) === 10)
68352
- count3 += 1;
68353
- }
68354
- return count3;
68355
- }
68356
- var DEFAULT_OUTPUT_MAX_BYTES, TRUNCATION_MARKER = `
68357
- === [truncated] agent output capture reached its configured bound; further chunks were not written ===
68358
- `;
68359
- var init_run_output_sink = __esm(() => {
68360
- DEFAULT_OUTPUT_MAX_BYTES = 1024 * 1024;
68361
- });
68362
-
68363
68745
  // ../../packages/app/src/workflow/steering.ts
68364
68746
  class WorkflowSteeringController {
68365
68747
  onAck;
@@ -68607,13 +68989,11 @@ import { dirname as dirname12, isAbsolute as isAbsolute2, join as join15 } from
68607
68989
  class AgentRunActionRunner {
68608
68990
  observabilityBus;
68609
68991
  steeringController;
68610
- outputLog;
68611
68992
  kind = KIND;
68612
68993
  agentService;
68613
- constructor(agentService, observabilityBus, steeringController, outputLog) {
68994
+ constructor(agentService, observabilityBus, steeringController) {
68614
68995
  this.observabilityBus = observabilityBus;
68615
68996
  this.steeringController = steeringController;
68616
- this.outputLog = outputLog;
68617
68997
  this.agentService = agentService;
68618
68998
  }
68619
68999
  async execute(options, context4) {
@@ -68655,17 +69035,10 @@ class AgentRunActionRunner {
68655
69035
  flags.continue = continueFlag;
68656
69036
  const answerFile = asOptionalString(options.answerFile);
68657
69037
  const expectFile = asOptionalString(options.expectFile);
69038
+ const requireDiff = asOptionalBoolean(options.requireDiff);
68658
69039
  const capture = asOptionalBoolean(options.capture) || answerFile !== undefined;
68659
69040
  const agentLabel = agent ?? "<default>";
68660
- const outputLog = this.outputLog;
68661
- const sink = outputLog === undefined ? undefined : new RunOutputSink({
68662
- dir: join15(cwd, ".spur", "run"),
68663
- runId: context4.runId,
68664
- ...outputLog.maxBytes !== undefined ? { maxBytes: outputLog.maxBytes } : {},
68665
- ...outputLog.maxLines !== undefined ? { maxLines: outputLog.maxLines } : {}
68666
- });
68667
- const observer = this.observabilityBus === undefined && sink === undefined ? undefined : (event2) => {
68668
- sink?.observe(event2);
69041
+ const observer = this.observabilityBus === undefined ? undefined : (event2) => {
68669
69042
  this.observabilityBus?.emit("workflow.agent", event2);
68670
69043
  };
68671
69044
  const actionId = context4.actionId ?? `${context4.runId}:${context4.stateOrNodeId}`;
@@ -68734,11 +69107,19 @@ class AgentRunActionRunner {
68734
69107
  };
68735
69108
  }
68736
69109
  }
69110
+ const stepLabel = context4.stateOrNodeId;
69111
+ if (ok && requireDiff === true && !await gitHasNonCorpusChanges(cwd)) {
69112
+ return {
69113
+ ok: false,
69114
+ data: buildResultData(exitCode, agentLabel, capture, answer, invocation),
69115
+ error: `agent.run '${stepLabel}' (${agentLabel}) exited 0 but produced zero non-corpus file changes \u2014 empty implement (no-op). The implement agent must change at least one file outside docs/tasks3|docs/features; fix the implement input and re-run the pipeline.`
69116
+ };
69117
+ }
68737
69118
  if (!ok) {
68738
69119
  await writePartialWorkArtifact(context4, agentLabel, model, traced, cwd);
68739
69120
  }
68740
- const stepLabel = context4.stateOrNodeId;
68741
- const error51 = ok ? undefined : traced.signal !== undefined ? timeoutMs !== undefined ? `agent.run '${stepLabel}' (${agentLabel}) terminated by signal ${traced.signal} (configured timeout: ${timeoutMs}ms; timeout or cancellation); see partial-work artifact` : `agent.run '${stepLabel}' (${agentLabel}) was cancelled by signal ${traced.signal}; see partial-work artifact` : traced.message !== undefined ? `agent.run '${stepLabel}' (${agentLabel}) dispatch failed: ${traced.message}` : `agent.run '${stepLabel}' (${agentLabel}) exited with code ${exitCode}`;
69121
+ const partialWorkHint = `partial work (if any) preserved at .spur/run/${context4.runId}-${stepLabel}-partial.md; resume from that tree per the timed-out-implement runbook (plugins/sp/skills/spur-dev/references/execution-workflow.md)`;
69122
+ const error51 = ok ? undefined : traced.signal !== undefined ? timeoutMs !== undefined ? `agent.run '${stepLabel}' (${agentLabel}) terminated by signal ${traced.signal} (configured timeout: ${timeoutMs}ms; timeout or cancellation); ${partialWorkHint}` : `agent.run '${stepLabel}' (${agentLabel}) was cancelled by signal ${traced.signal}; ${partialWorkHint}` : traced.message !== undefined ? `agent.run '${stepLabel}' (${agentLabel}) dispatch failed: ${traced.message}` : `agent.run '${stepLabel}' (${agentLabel}) exited with code ${exitCode}; ${partialWorkHint}`;
68742
69123
  return {
68743
69124
  ok,
68744
69125
  data: buildResultData(exitCode, agentLabel, capture, answer, invocation),
@@ -68748,9 +69129,7 @@ class AgentRunActionRunner {
68748
69129
  ...steeringNote !== undefined ? { __steeringNote: steeringNote } : {}
68749
69130
  } : undefined
68750
69131
  };
68751
- } finally {
68752
- sink?.close();
68753
- }
69132
+ } finally {}
68754
69133
  }
68755
69134
  }
68756
69135
  function buildResultData(exitCode, agentLabel, capture, answer, invocation) {
@@ -68857,6 +69236,21 @@ async function gitDiffStat(cwd) {
68857
69236
  return "";
68858
69237
  }
68859
69238
  }
69239
+ async function gitHasNonCorpusChanges(cwd) {
69240
+ try {
69241
+ const result = await new NodeProcessExecutor3().run({
69242
+ command: "git",
69243
+ args: ["status", "--porcelain", "--", ".", ":(exclude)docs/tasks3/*", ":(exclude)docs/features/*"],
69244
+ cwd,
69245
+ maxOutput: 1024 * 1024,
69246
+ forceBuffered: true,
69247
+ rejectOnError: false
69248
+ });
69249
+ return result.exitCode === 0 && result.stdout.trim() !== "";
69250
+ } catch {
69251
+ return false;
69252
+ }
69253
+ }
68860
69254
  function tail(text4, maxChars) {
68861
69255
  if (text4.length <= maxChars)
68862
69256
  return text4;
@@ -68866,7 +69260,6 @@ ${text4.slice(text4.length - maxChars)}`;
68866
69260
  var PARTIAL_ARTIFACT_TAIL_CHARS = 4000, KIND = "agent.run";
68867
69261
  var init_agent_run = __esm(() => {
68868
69262
  init_dist5();
68869
- init_run_output_sink();
68870
69263
  init_steering();
68871
69264
  });
68872
69265
 
@@ -69392,10 +69785,179 @@ var init_rule_check = __esm(() => {
69392
69785
  init_utils3();
69393
69786
  });
69394
69787
 
69788
+ // ../../packages/app/src/workflow/actions/shell.ts
69789
+ function stringOption2(options, key, fallback) {
69790
+ const value = options[key];
69791
+ if (typeof value === "string")
69792
+ return value;
69793
+ if (fallback !== undefined)
69794
+ return fallback;
69795
+ throw new Error(`Action option "${key}" must be a string`);
69796
+ }
69797
+ function arrayOption2(options, key) {
69798
+ const value = options[key];
69799
+ if (value === undefined)
69800
+ return [];
69801
+ if (Array.isArray(value) && value.every((entry) => typeof entry === "string"))
69802
+ return value;
69803
+ throw new Error(`Action option "${key}" must be a string array`);
69804
+ }
69805
+
69806
+ class StreamingShellActionRunner {
69807
+ processExecutor;
69808
+ observabilityBus;
69809
+ kind = KIND11;
69810
+ constructor(processExecutor, observabilityBus) {
69811
+ this.processExecutor = processExecutor;
69812
+ this.observabilityBus = observabilityBus;
69813
+ }
69814
+ async execute(options, context4) {
69815
+ const command = stringOption2(options, "command");
69816
+ const explicitArgs = arrayOption2(options, "args");
69817
+ const usesShell = explicitArgs.length === 0;
69818
+ const spawn2 = usesShell ? { command: "/bin/sh", args: ["-c", command] } : { command, args: explicitArgs };
69819
+ const cwd = stringOption2(options, "cwd", context4.workdir);
69820
+ const env = {};
69821
+ for (const [key, value] of Object.entries({ ...process.env, ...context4.vars })) {
69822
+ if (value !== undefined)
69823
+ env[key] = value;
69824
+ }
69825
+ const pipe2 = this.processExecutor.runStreaming({
69826
+ command: spawn2.command,
69827
+ args: spawn2.args,
69828
+ ...cwd !== undefined ? { cwd } : {},
69829
+ env
69830
+ });
69831
+ let stdout = "";
69832
+ let stderr = "";
69833
+ const readers = [];
69834
+ const consume = (stream, readable2) => {
69835
+ if (readable2 === null)
69836
+ return;
69837
+ const reader = readable2.getReader();
69838
+ const decoder = new TextDecoder;
69839
+ readers.push((async () => {
69840
+ for (;; ) {
69841
+ const { done, value } = await reader.read();
69842
+ if (done)
69843
+ break;
69844
+ const chunk = decoder.decode(value, { stream: true });
69845
+ if (chunk === "")
69846
+ continue;
69847
+ if (stream === "stdout")
69848
+ stdout += chunk;
69849
+ else
69850
+ stderr += chunk;
69851
+ if (this.observabilityBus !== undefined) {
69852
+ const event2 = {
69853
+ schemaVersion: 1,
69854
+ eventId: crypto.randomUUID(),
69855
+ sequence: 0,
69856
+ runId: context4.runId,
69857
+ at: new Date().toISOString(),
69858
+ kind: KIND11,
69859
+ node: context4.stateOrNodeId,
69860
+ stream,
69861
+ chunk: bounded(chunk)
69862
+ };
69863
+ this.observabilityBus.emit("workflow.action.output", event2);
69864
+ }
69865
+ }
69866
+ const tail2 = decoder.decode();
69867
+ if (tail2 !== "") {
69868
+ if (stream === "stdout")
69869
+ stdout += tail2;
69870
+ else
69871
+ stderr += tail2;
69872
+ if (this.observabilityBus !== undefined) {
69873
+ this.observabilityBus.emit("workflow.action.output", {
69874
+ schemaVersion: 1,
69875
+ eventId: crypto.randomUUID(),
69876
+ sequence: 0,
69877
+ runId: context4.runId,
69878
+ at: new Date().toISOString(),
69879
+ kind: KIND11,
69880
+ node: context4.stateOrNodeId,
69881
+ stream,
69882
+ chunk: bounded(tail2)
69883
+ });
69884
+ }
69885
+ }
69886
+ })());
69887
+ };
69888
+ consume("stdout", pipe2.stdout);
69889
+ consume("stderr", pipe2.stderr);
69890
+ const exitCode = await pipe2.exited;
69891
+ await Promise.allSettled(readers);
69892
+ return {
69893
+ ok: exitCode === 0,
69894
+ data: { stdout, stderr, exitCode },
69895
+ ...exitCode === 0 ? {} : { error: `Command "${command}" exited with ${exitCode}` }
69896
+ };
69897
+ }
69898
+ }
69899
+ var KIND11 = "shell";
69900
+ var init_shell = __esm(() => {
69901
+ init_observability();
69902
+ });
69903
+
69904
+ // ../../packages/app/src/workflow/guards/shell.ts
69905
+ function stringOption3(options, key, fallback) {
69906
+ const value = options[key];
69907
+ if (typeof value === "string")
69908
+ return value;
69909
+ if (fallback !== undefined)
69910
+ return fallback;
69911
+ throw new Error(`Guard option "${key}" must be a string`);
69912
+ }
69913
+ function arrayOption3(options, key) {
69914
+ const value = options[key];
69915
+ if (value === undefined)
69916
+ return [];
69917
+ if (Array.isArray(value) && value.every((entry) => typeof entry === "string"))
69918
+ return value;
69919
+ throw new Error(`Guard option "${key}" must be a string array`);
69920
+ }
69921
+
69922
+ class EnvShellGuardRunner {
69923
+ processExecutor;
69924
+ kind = KIND12;
69925
+ constructor(processExecutor) {
69926
+ this.processExecutor = processExecutor;
69927
+ }
69928
+ async evaluate(options, context4) {
69929
+ const command = stringOption3(options, "command");
69930
+ const explicitArgs = arrayOption3(options, "args");
69931
+ const usesShell = explicitArgs.length === 0;
69932
+ const spawn2 = usesShell ? { command: "/bin/sh", args: ["-c", command] } : { command, args: explicitArgs };
69933
+ const cwd = options.cwd === undefined ? context4.workdir : stringOption3(options, "cwd");
69934
+ const env = {};
69935
+ for (const [key, value] of Object.entries({ ...process.env, ...context4.vars })) {
69936
+ if (value !== undefined)
69937
+ env[key] = String(value);
69938
+ }
69939
+ const result = await this.processExecutor.run({
69940
+ command: spawn2.command,
69941
+ args: spawn2.args,
69942
+ ...cwd !== undefined ? { cwd } : {},
69943
+ env,
69944
+ rejectOnError: false,
69945
+ forceBuffered: true
69946
+ });
69947
+ return {
69948
+ passed: result.exitCode === 0,
69949
+ report: { stdout: result.stdout, stderr: result.stderr, exitCode: result.exitCode }
69950
+ };
69951
+ }
69952
+ }
69953
+ var KIND12 = "shell";
69954
+
69395
69955
  // ../../packages/app/src/workflow/builtins.ts
69396
69956
  function registerSpurBuiltins(host, options) {
69397
69957
  const fileSystem = options.fileSystem ?? createNodeFileSystem3();
69398
- host.registerAction(new AgentRunActionRunner(options.agentService, options.observabilityBus, options.steeringController, options.outputLog), "builtin");
69958
+ host.registerAction(new AgentRunActionRunner(options.agentService, options.observabilityBus, options.steeringController), "builtin");
69959
+ host.registerAction(new StreamingShellActionRunner(options.processExecutor ?? new NodeProcessExecutor3, options.observabilityBus), "builtin");
69960
+ host.registerGuard(new EnvShellGuardRunner(options.processExecutor ?? new NodeProcessExecutor3), "builtin");
69399
69961
  host.registerAction(new RuleCheckActionRunner(options.ruleService), "builtin");
69400
69962
  host.registerAction(new FileExistsActionRunner(fileSystem), "builtin");
69401
69963
  host.registerAction(new FileReadActionRunner(fileSystem), "builtin");
@@ -69418,159 +69980,7 @@ var init_builtins2 = __esm(() => {
69418
69980
  init_file_read_into_var();
69419
69981
  init_http_request();
69420
69982
  init_rule_check();
69421
- });
69422
-
69423
- // ../../packages/app/src/workflow/observability.ts
69424
- function bounded(value) {
69425
- const redacted = value.replace(SECRET_PATTERN2, "[REDACTED]");
69426
- return redacted.length <= MAX_FIELD_LENGTH3 ? redacted : `${redacted.slice(0, MAX_FIELD_LENGTH3)}\u2026`;
69427
- }
69428
- function projectActionMetadata(kind, options) {
69429
- if (options === undefined)
69430
- return;
69431
- const metadata = {};
69432
- if (typeof options.agent === "string" && options.agent !== "")
69433
- metadata.agent = bounded(options.agent);
69434
- if (typeof options.model === "string" && options.model !== "")
69435
- metadata.model = bounded(options.model);
69436
- if (typeof options.timeoutMs === "number" && Number.isFinite(options.timeoutMs)) {
69437
- metadata.timeoutMs = Math.max(0, options.timeoutMs);
69438
- }
69439
- const input = typeof options.input === "string" ? options.input.trim() : "";
69440
- if (kind === "agent.run" && input !== "") {
69441
- const command = input.startsWith("/") ? input.split(/\s+/, 1)[0] : undefined;
69442
- metadata.invocation = command === undefined ? `[prompt ${input.length} chars]` : bounded(command);
69443
- } else if (kind === "shell" && typeof options.command === "string") {
69444
- metadata.invocation = "[shell command redacted]";
69445
- }
69446
- return Object.keys(metadata).length === 0 ? undefined : metadata;
69447
- }
69448
- function projectResult(result) {
69449
- if (result === undefined)
69450
- return;
69451
- if (typeof result !== "object" || result === null)
69452
- return { usage: "unavailable" };
69453
- const error51 = "error" in result && typeof result.error === "string" ? bounded(result.error) : undefined;
69454
- return { ...error51 !== undefined ? { error: error51 } : {}, usage: "unavailable" };
69455
- }
69456
-
69457
- class ObservableWorkflowAdapter {
69458
- inner;
69459
- bus;
69460
- sequences = new Map;
69461
- workflowNames = new Map;
69462
- actions = new Map;
69463
- constructor(inner, bus) {
69464
- this.inner = inner;
69465
- this.bus = bus;
69466
- }
69467
- async createRun(record2) {
69468
- await this.inner.createRun(record2);
69469
- this.workflowNames.set(record2.id, record2.workflow_name);
69470
- await this.bus.emit("workflow.run.started", {
69471
- ...this.envelope(record2.id),
69472
- workflowName: record2.workflow_name
69473
- });
69474
- }
69475
- async finalizeRun(runId, status, completedAt) {
69476
- await this.inner.finalizeRun(runId, status, completedAt);
69477
- await this.bus.emit("workflow.run.finalized", { ...this.envelope(runId, completedAt), status });
69478
- }
69479
- async savePhase(runId, phase, status) {
69480
- await this.inner.savePhase(runId, phase, status);
69481
- await this.bus.emit("workflow.phase", { ...this.envelope(runId), phase, status });
69482
- }
69483
- async saveTransition(runId, from, to, trigger) {
69484
- await this.inner.saveTransition(runId, from, to, trigger);
69485
- await this.bus.emit("workflow.transition", { ...this.envelope(runId), from, to, trigger });
69486
- }
69487
- async commitTransition(runId, from, to, trigger, _state, _data, phase) {
69488
- await this.inner.commitTransition(runId, from, to, trigger, _state, _data, phase);
69489
- await this.bus.emit("workflow.transition", { ...this.envelope(runId), from, to, trigger });
69490
- if (phase) {
69491
- await this.bus.emit("workflow.phase", {
69492
- ...this.envelope(runId),
69493
- phase: phase.phase,
69494
- status: phase.status
69495
- });
69496
- }
69497
- }
69498
- async saveActionStart(runId, node, kind, options) {
69499
- const actionId = await this.inner.saveActionStart(runId, node, kind, options);
69500
- this.actions.set(actionId, { runId, node, kind });
69501
- const metadata = projectActionMetadata(kind, options);
69502
- await this.bus.emit("workflow.action.started", {
69503
- ...this.envelope(runId),
69504
- actionId,
69505
- node,
69506
- kind,
69507
- ...metadata !== undefined ? { metadata } : {}
69508
- });
69509
- return actionId;
69510
- }
69511
- async saveActionFinalize(actionId, status, durationMs, ok, result, redactor) {
69512
- await this.inner.saveActionFinalize(actionId, status, durationMs, ok, result, redactor);
69513
- const action = this.actions.get(actionId);
69514
- if (action === undefined) {
69515
- return;
69516
- }
69517
- this.actions.delete(actionId);
69518
- const projected = projectResult(result);
69519
- await this.bus.emit("workflow.action.finished", {
69520
- ...this.envelope(action.runId),
69521
- actionId,
69522
- status,
69523
- durationMs,
69524
- ok,
69525
- node: action.node,
69526
- kind: action.kind,
69527
- ...projected !== undefined ? { result: projected } : {}
69528
- });
69529
- }
69530
- envelope(runId, at = now()) {
69531
- const sequence = (this.sequences.get(runId) ?? 0) + 1;
69532
- this.sequences.set(runId, sequence);
69533
- const workflowName = this.workflowNames.get(runId);
69534
- return {
69535
- schemaVersion: 1,
69536
- eventId: crypto.randomUUID(),
69537
- sequence,
69538
- runId,
69539
- ...workflowName !== undefined ? { workflowName } : {},
69540
- at
69541
- };
69542
- }
69543
- saveWorkflowState(runId, state, data) {
69544
- return this.inner.saveWorkflowState(runId, state, data);
69545
- }
69546
- loadRun(runId) {
69547
- return this.inner.loadRun(runId);
69548
- }
69549
- listRuns() {
69550
- return this.inner.listRuns();
69551
- }
69552
- findRunByKey(workflowName, externalKey) {
69553
- return this.inner.findRunByKey(workflowName, externalKey);
69554
- }
69555
- createOrAttachRun(record2) {
69556
- return this.inner.createOrAttachRun(record2);
69557
- }
69558
- reseedRun(runId, newState) {
69559
- return this.inner.reseedRun(runId, newState);
69560
- }
69561
- loadCurrentState(runId) {
69562
- return this.inner.loadCurrentState(runId);
69563
- }
69564
- loadLatestStateSnapshot(runId) {
69565
- return this.inner.loadLatestStateSnapshot(runId);
69566
- }
69567
- listPausedRuns(options) {
69568
- return this.inner.listPausedRuns(options);
69569
- }
69570
- }
69571
- var now = () => new Date().toISOString(), MAX_FIELD_LENGTH3 = 256, SECRET_PATTERN2;
69572
- var init_observability = __esm(() => {
69573
- SECRET_PATTERN2 = /(?:sk-[a-z0-9_-]{8,}|(?:api[_-]?key|token|secret|password)\s*[:=]\s*\S+|bearer\s+\S+)/gi;
69983
+ init_shell();
69574
69984
  });
69575
69985
 
69576
69986
  // ../../packages/app/src/services/workflow-service.ts
@@ -69674,8 +70084,18 @@ class WorkflowAppService {
69674
70084
  });
69675
70085
  const runId = opts.runId ?? crypto.randomUUID();
69676
70086
  const isDry = opts.dryRun === true;
69677
- const runVars = { ...opts.vars ?? {}, __runId: runId };
69678
- const result = await svc.runFile(file2, {
70087
+ const runVars = {
70088
+ ...await resolveDefaultAgentVar(this.ctx.cwd, opts.vars),
70089
+ ...opts.vars ?? {},
70090
+ __runId: runId
70091
+ };
70092
+ const absolute = resolve4(this.ctx.cwd, file2);
70093
+ const embedded = this.embeddedSchemaOptions();
70094
+ const workflow = await loadWorkflowDef(absolute, {
70095
+ validateSchema: true,
70096
+ ...embedded !== undefined ? embedded : {}
70097
+ });
70098
+ const result = await svc.run(workflow, {
69679
70099
  workdir: this.ctx.cwd,
69680
70100
  runId,
69681
70101
  vars: runVars,
@@ -69696,7 +70116,7 @@ class WorkflowAppService {
69696
70116
  return;
69697
70117
  let workflowName;
69698
70118
  try {
69699
- const def = await loadWorkflowDef(resolve4(this.ctx.cwd, file2));
70119
+ const def = await loadWorkflowDef(resolve4(this.ctx.cwd, file2), { validateSchema: false });
69700
70120
  workflowName = def.name;
69701
70121
  } catch {
69702
70122
  return;
@@ -69740,6 +70160,37 @@ class WorkflowAppService {
69740
70160
  cleaned: stale.map((r) => ({ runId: r.id, startedAt: r.started_at }))
69741
70161
  };
69742
70162
  }
70163
+ async cleanRunLogs(retentionDays = 30, dryRun = false) {
70164
+ const runDir = join16(this.ctx.cwd, ".spur", "run");
70165
+ const fs3 = createNodeFileSystem3();
70166
+ const cutoffMs = Date.now() - retentionDays * 24 * 60 * 60 * 1000;
70167
+ const reclaimed = [];
70168
+ const failures = [];
70169
+ let entries;
70170
+ try {
70171
+ entries = (await fs3.readDir(runDir)).filter((name) => name.endsWith(".log"));
70172
+ } catch {
70173
+ return { retentionDays, dryRun, reclaimed, failures };
70174
+ }
70175
+ for (const name of entries) {
70176
+ const path9 = join16(runDir, name);
70177
+ const stat = await fs3.stat(path9);
70178
+ if (stat === null || !stat.isFile() || stat.mtimeMs >= cutoffMs)
70179
+ continue;
70180
+ const entry = { runId: name.slice(0, -".log".length), path: path9, mtime: new Date(stat.mtimeMs).toISOString() };
70181
+ if (dryRun) {
70182
+ reclaimed.push(entry);
70183
+ continue;
70184
+ }
70185
+ try {
70186
+ await fs3.deleteFile(path9);
70187
+ reclaimed.push(entry);
70188
+ } catch (err) {
70189
+ failures.push({ path: path9, error: String(err) });
70190
+ }
70191
+ }
70192
+ return { retentionDays, dryRun, reclaimed, failures };
70193
+ }
69743
70194
  async cancel(runId) {
69744
70195
  const db2 = await this.ctx.getDb();
69745
70196
  const dao2 = new RunDao(db2);
@@ -69755,20 +70206,23 @@ class WorkflowAppService {
69755
70206
  const finalized = after?.status === "failed" && before.status !== "failed";
69756
70207
  return { runId, finalized, status: after?.status ?? "not_found", killed };
69757
70208
  }
69758
- async continuePaused(runId) {
70209
+ async continuePaused(runId, opts) {
69759
70210
  const eventsBus = this.ctx.events?.();
69760
70211
  const svc = await this.createEngineService({ events: eventsBus });
69761
70212
  const run = await svc.listPausedRuns();
69762
70213
  const target = run.find((r) => r.id === runId);
69763
70214
  if (target === undefined) {
69764
- throw new Error(`Run "${runId}" is not paused (or does not exist) \u2014 nothing to continue.`);
70215
+ throw new Error(`Run "${runId}" is not paused (or does not exist) - nothing to continue.`);
69765
70216
  }
69766
70217
  const workflow = await this.resolveWorkflowDefByName(target.workflow_name);
69767
70218
  if (workflow === null) {
69768
70219
  throw new Error(`Cannot resume run "${runId}": workflow definition "${target.workflow_name}" not found in the workflow search paths.`);
69769
70220
  }
70221
+ const hitlVar = opts?.hitlVar ?? "__hitlAnswer";
70222
+ const resumeVars = opts?.hitlAnswer !== undefined ? { [hitlVar]: opts.hitlAnswer } : undefined;
69770
70223
  const result = await svc.resumeRun(workflow, runId, {
69771
70224
  workdir: this.ctx.cwd,
70225
+ ...resumeVars !== undefined ? { vars: resumeVars } : {},
69772
70226
  ...eventsBus !== undefined ? { events: bridgeEventBus(eventsBus) } : {}
69773
70227
  });
69774
70228
  await this.stampFailureReason(runId, result);
@@ -69920,8 +70374,8 @@ class WorkflowAppService {
69920
70374
  httpRequester: this.ctx.httpRequester?.(),
69921
70375
  hostAllowlist: this.ctx.hostAllowlist?.(),
69922
70376
  ...bus !== undefined ? { observabilityBus: bus } : {},
69923
- ...opts.steeringController !== undefined ? { steeringController: opts.steeringController } : {},
69924
- outputLog: await resolveOutputLogConfig(this.ctx.cwd)
70377
+ ...processExec !== undefined ? { processExecutor: processExec } : {},
70378
+ ...opts.steeringController !== undefined ? { steeringController: opts.steeringController } : {}
69925
70379
  });
69926
70380
  const db2 = await this.ctx.getDb();
69927
70381
  let persistence2 = new DbWorkflowPersistenceAdapter(db2);
@@ -69936,6 +70390,23 @@ async function fileExists(path9) {
69936
70390
  const fs3 = createNodeFileSystem3();
69937
70391
  return await fs3.exists(path9);
69938
70392
  }
70393
+ async function resolveDefaultAgentVar(cwd, callerVars) {
70394
+ if (callerVars?.agent !== undefined)
70395
+ return {};
70396
+ try {
70397
+ const configured = (await loadSpurConfig(cwd)).agent?.default;
70398
+ return typeof configured === "string" && configured.length > 0 ? { agent: configured } : {};
70399
+ } catch {
70400
+ return {};
70401
+ }
70402
+ }
70403
+ async function resolveWorkflowLogRetentionDays(cwd) {
70404
+ try {
70405
+ return (await loadSpurConfig(cwd)).workflow?.logRetentionDays ?? 30;
70406
+ } catch {
70407
+ return 30;
70408
+ }
70409
+ }
69939
70410
  async function resolveOutputLogConfig(cwd) {
69940
70411
  try {
69941
70412
  const output2 = (await loadSpurConfig(cwd)).agent?.output;
@@ -69950,7 +70421,7 @@ async function resolveOutputLogConfig(cwd) {
69950
70421
  }
69951
70422
  }
69952
70423
  async function outputArtifactForRun(cwd, runId) {
69953
- const relative4 = join16(".spur", "run", `${runId}-output.log`);
70424
+ const relative4 = join16(".spur", "run", `${runId}.log`);
69954
70425
  return await fileExists(join16(cwd, relative4)) ? relative4 : undefined;
69955
70426
  }
69956
70427
  async function scanWorkflowFiles(rootPath, source) {
@@ -70050,7 +70521,9 @@ class LifecycleAdapter {
70050
70521
  async requestTransition(ref, currentStatus, to) {
70051
70522
  const { profile } = this.opts;
70052
70523
  const db2 = await this.opts.getDb();
70053
- const svc = new WorkflowService(createDefaultWorkflowEngineHost(), new DbWorkflowPersistenceAdapter(db2));
70524
+ const host = createDefaultWorkflowEngineHost();
70525
+ host.registerGuard(new EnvShellGuardRunner(new NodeProcessExecutor3), "builtin");
70526
+ const svc = new WorkflowService(host, new DbWorkflowPersistenceAdapter(db2));
70054
70527
  const workflow = this.bindGuardVar(await this.loadWorkflow(), ref.id);
70055
70528
  const externalKey = `${profile.entityPrefix}:${ref.id}`;
70056
70529
  const now2 = new Date().toISOString();
@@ -70184,87 +70657,6 @@ var init_lifecycle_adapter = __esm(() => {
70184
70657
  };
70185
70658
  });
70186
70659
 
70187
- // ../../packages/app/src/workflow/step-reporter.ts
70188
- function renderStepLine(event2, options = {}) {
70189
- const detail = options.detail ?? "invocation";
70190
- if (isAgentExecution(event2)) {
70191
- if (event2.kind === "output") {
70192
- if (detail === "minimal")
70193
- return null;
70194
- const label = event2.stream === "stderr" ? "stderr" : "stdout";
70195
- return `[run ${event2.runId}] ${label}> ${event2.chunk.replace(/\s+$/, "")}`;
70196
- }
70197
- if (event2.kind === "heartbeat") {
70198
- if (detail === "minimal")
70199
- return null;
70200
- const budget = event2.timeoutMs === undefined ? "unbounded" : `${formatDuration(Math.max(0, event2.timeoutMs - event2.elapsedMs))} remaining`;
70201
- return `[run ${event2.runId}] \u2026 agent execution \xB7 elapsed=${formatDuration(event2.elapsedMs)} \xB7 budget=${budget}`;
70202
- }
70203
- if (event2.kind === "dropped") {
70204
- return detail === "minimal" ? null : `[run ${event2.runId}] \u2026 output pressure \xB7 dropped=${event2.chunks} chunks`;
70205
- }
70206
- if (event2.kind === "started") {
70207
- if (detail === "minimal")
70208
- return null;
70209
- const model = event2.model === undefined ? "" : `(${event2.model})`;
70210
- const full2 = detail === "full" ? ` \xB7 execution=${event2.executionId}` : "";
70211
- return `[run ${event2.runId}] agent=${event2.agent}${model} => ${event2.invocation}${full2}`;
70212
- }
70213
- const mark = event2.outcome === "done" ? "\u2713" : "\u2717";
70214
- const full = detail === "full" ? ` \xB7 execution=${event2.executionId}` : "";
70215
- return detail === "minimal" ? null : `[run ${event2.runId}] ${mark} agent ${event2.outcome} (${formatDuration(event2.durationMs)}) \xB7 usage ${event2.usage}${event2.reason ? ` \xB7 ${event2.reason}` : ""}${full}`;
70216
- }
70217
- if (isActionFinished(event2)) {
70218
- const mark = event2.ok ? "\u2713" : "\u2717";
70219
- if (detail === "minimal")
70220
- return ` ${mark} ${event2.status} (${formatDuration(event2.durationMs)})`;
70221
- const failure = event2.result?.error === undefined ? "" : ` \xB7 ${event2.result.error}`;
70222
- const full = detail === "full" ? ` \xB7 action=${event2.actionId} \xB7 seq=${event2.sequence}` : "";
70223
- return `[run ${event2.runId}] ${mark} ${event2.node}/${event2.kind} (${formatDuration(event2.durationMs)}) \xB7 usage ${event2.result?.usage ?? "unavailable"}${failure}${full}`;
70224
- }
70225
- if (isActionStarted(event2)) {
70226
- if (detail === "minimal")
70227
- return ` \u2192 ${event2.node}: ${event2.kind}\u2026`;
70228
- const agent = event2.metadata?.agent ?? "unavailable";
70229
- const model = event2.metadata?.model ?? "unavailable";
70230
- const invocation = event2.metadata?.invocation ?? "unavailable";
70231
- const timeout = event2.metadata?.timeoutMs === undefined ? "unbounded" : formatDuration(event2.metadata.timeoutMs);
70232
- const full = detail === "full" ? ` \xB7 action=${event2.actionId} \xB7 seq=${event2.sequence}` : "";
70233
- return `[run ${event2.runId}] \u2192 ${event2.node}/${event2.kind} \xB7 agent=${agent} \xB7 model=${model} => ${invocation} \xB7 timeout=${timeout}${full}`;
70234
- }
70235
- if (isPhase(event2)) {
70236
- return detail === "minimal" ? `\u25B6 ${event2.phase} [${event2.status}]` : `[run ${event2.runId}] \u25B6 ${event2.phase} [${event2.status}]`;
70237
- }
70238
- if (isTransition(event2)) {
70239
- if (detail !== "full")
70240
- return null;
70241
- return `[run ${event2.runId}] \u21AA ${event2.from} \u2192 ${event2.to}${event2.trigger ? ` [${event2.trigger}]` : ""} \xB7 seq=${event2.sequence}`;
70242
- }
70243
- return null;
70244
- }
70245
- function renderActionHeartbeat(event2, elapsedMs, options = {}) {
70246
- const detail = options.detail ?? "invocation";
70247
- if (detail === "minimal")
70248
- return null;
70249
- const elapsed = formatDuration(elapsedMs);
70250
- const budget = event2.metadata?.timeoutMs === undefined ? "unbounded" : `${formatDuration(Math.max(0, event2.metadata.timeoutMs - elapsedMs))} remaining`;
70251
- const full = detail === "full" ? ` \xB7 action=${event2.actionId}` : "";
70252
- return `[run ${event2.runId}] \u2026 ${event2.node}/${event2.kind} \xB7 elapsed=${elapsed} \xB7 budget=${budget}${full}`;
70253
- }
70254
- function renderRunPlan(def) {
70255
- const steps = def.kind === "transition-flow" ? def.nodes.map((n2) => n2.id) : def.states.map((s) => s.id);
70256
- return `plan: ${steps.join(" \u2192 ")}`;
70257
- }
70258
- function formatDuration(ms) {
70259
- const totalSeconds = Math.round(ms / 1000);
70260
- if (totalSeconds < 60)
70261
- return `${totalSeconds}s`;
70262
- const minutes = Math.floor(totalSeconds / 60);
70263
- const seconds = totalSeconds % 60;
70264
- return `${minutes}m ${seconds}s`;
70265
- }
70266
- var isAgentExecution = (e) => ("executionId" in e), isActionStarted = (e) => ("kind" in e) && ("node" in e), isActionFinished = (e) => ("durationMs" in e) && ("ok" in e), isPhase = (e) => ("phase" in e), isTransition = (e) => ("from" in e) && ("to" in e);
70267
-
70268
70660
  // ../../packages/app/src/workflow/trace-writer.ts
70269
70661
  import { dirname as dirname13, join as join17 } from "path";
70270
70662
 
@@ -70317,9 +70709,11 @@ __export(exports_src2, {
70317
70709
  summarizeActionResult: () => summarizeActionResult,
70318
70710
  startRegisteredProject: () => startRegisteredProject,
70319
70711
  setDetachedServeSpawnForTests: () => setDetachedServeSpawnForTests,
70712
+ resolveWorkflowLogRetentionDays: () => resolveWorkflowLogRetentionDays,
70320
70713
  resolveSpurServeCommand: () => resolveSpurServeCommand,
70321
70714
  resolveRetentionQuotas: () => resolveRetentionQuotas,
70322
70715
  resolvePlanningFolders: () => resolvePlanningFolders,
70716
+ resolveOutputLogConfig: () => resolveOutputLogConfig,
70323
70717
  resolveAutostartSet: () => resolveAutostartSet,
70324
70718
  renderTesting: () => renderTesting,
70325
70719
  renderStepLine: () => renderStepLine,
@@ -70365,6 +70759,7 @@ __export(exports_src2, {
70365
70759
  aggregateBatchVerdicts: () => aggregateBatchVerdicts,
70366
70760
  WorkflowTraceWriter: () => WorkflowTraceWriter,
70367
70761
  WorkflowSteeringController: () => WorkflowSteeringController,
70762
+ WorkflowRunLogSink: () => WorkflowRunLogSink,
70368
70763
  WorkflowAppService: () => WorkflowAppService,
70369
70764
  WbsCollisionError: () => WbsCollisionError,
70370
70765
  UnsupportedProcessPlatformError: () => UnsupportedProcessPlatformError,
@@ -70426,6 +70821,7 @@ __export(exports_src2, {
70426
70821
  DuplicateFollowUpError: () => DuplicateFollowUpError,
70427
70822
  DependencyMutationError: () => DependencyMutationError,
70428
70823
  DEFAULT_SYSTEM_EVENT_RETENTION_QUOTA: () => DEFAULT_SYSTEM_EVENT_RETENTION_QUOTA,
70824
+ DEFAULT_RUN_LOG_MAX_BYTES: () => DEFAULT_RUN_LOG_MAX_BYTES,
70429
70825
  DEFAULT_FEATURE_MATRIX: () => DEFAULT_FEATURE_MATRIX,
70430
70826
  CorpusMigrator: () => CorpusMigrator,
70431
70827
  BusPlanningEventEmitter: () => BusPlanningEventEmitter,
@@ -70438,6 +70834,7 @@ var init_src3 = __esm(() => {
70438
70834
  init_planning_folders();
70439
70835
  init_errors5();
70440
70836
  init_agent_execution();
70837
+ init_workflow_run_log_sink();
70441
70838
  init_agent_service();
70442
70839
  init_corpus_migrator();
70443
70840
  init_event_names();
@@ -70557,19 +70954,19 @@ var {
70557
70954
  init_src();
70558
70955
  init_loader();
70559
70956
 
70560
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/application-node.js
70957
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/application-node.js
70561
70958
  init_dist4();
70562
70959
  init_dist5();
70563
70960
  import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync5 } from "fs";
70564
70961
  import { dirname as dirname5 } from "path";
70565
70962
 
70566
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/application/index.js
70963
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/application/index.js
70567
70964
  init_default_observers();
70568
70965
  init_event_bus();
70569
70966
  init_file_observer();
70570
70967
  init_logger3();
70571
70968
 
70572
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/scheduler/noop.js
70969
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/scheduler/noop.js
70573
70970
  class NoopSchedulerAdapter {
70574
70971
  constructor() {}
70575
70972
  register(_cron, _action) {}
@@ -70577,7 +70974,7 @@ class NoopSchedulerAdapter {
70577
70974
  async stop() {}
70578
70975
  }
70579
70976
 
70580
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/scheduler/factory.js
70977
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/scheduler/factory.js
70581
70978
  function initScheduler(adapter, cronEntries) {
70582
70979
  const resolved = adapter ?? new NoopSchedulerAdapter;
70583
70980
  if (cronEntries) {
@@ -70588,7 +70985,7 @@ function initScheduler(adapter, cronEntries) {
70588
70985
  return resolved;
70589
70986
  }
70590
70987
 
70591
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/application/plugins/builtins.js
70988
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/application/plugins/builtins.js
70592
70989
  init_logger3();
70593
70990
  init_metrics();
70594
70991
  init_sdk();
@@ -70681,7 +71078,7 @@ function dbPlugin(db2) {
70681
71078
  };
70682
71079
  }
70683
71080
 
70684
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/application/plugins/host.js
71081
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/application/plugins/host.js
70685
71082
  init_logger3();
70686
71083
 
70687
71084
  class PluginHost {
@@ -70769,7 +71166,7 @@ class PluginHost {
70769
71166
  }
70770
71167
  }
70771
71168
 
70772
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/application/index.js
71169
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/application/index.js
70773
71170
  async function performShutdown(state, reason) {
70774
71171
  if (state.stopped)
70775
71172
  return;
@@ -70880,10 +71277,10 @@ async function runApplication(options) {
70880
71277
  }
70881
71278
  }
70882
71279
 
70883
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/application-node.js
71280
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/application-node.js
70884
71281
  init_scheduler_node();
70885
71282
 
70886
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
71283
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
70887
71284
  var import_api14 = __toESM(require_src(), 1);
70888
71285
 
70889
71286
  // ../../node_modules/.bun/@opentelemetry+exporter-metrics-otlp-http@0.218.0+e40b0dfdd726a224/node_modules/@opentelemetry/exporter-metrics-otlp-http/build/esm/OTLPMetricExporterBase.js
@@ -73899,7 +74296,7 @@ class OTLPTraceExporter extends import_otlp_exporter_base2.OTLPExporterBase {
73899
74296
  }), JsonTraceSerializer));
73900
74297
  }
73901
74298
  }
73902
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
74299
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
73903
74300
  var import_resources2 = __toESM(require_src4(), 1);
73904
74301
  var import_sdk_trace_node = __toESM(require_src8(), 1);
73905
74302
  var import_semantic_conventions = __toESM(require_src2(), 1);
@@ -73950,7 +74347,7 @@ async function shutdownNodeTelemetry() {
73950
74347
  await Promise.all(pending);
73951
74348
  }
73952
74349
 
73953
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.16+4e212f5ced9864ce/node_modules/@gobing-ai/ts-infra/dist/application-node.js
74350
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.18+863f28addc1a7cdc/node_modules/@gobing-ai/ts-infra/dist/application-node.js
73954
74351
  class ConfigValidationError extends Error {
73955
74352
  constructor(message) {
73956
74353
  super(message);
@@ -78348,7 +78745,15 @@ function registerFeatureCommand(program2, context4) {
78348
78745
  context4.setExitCode(1);
78349
78746
  }
78350
78747
  });
78351
- feature.command("refresh").summary("Regenerate INDEX.md (ID-encoded tree) and repopulate each feature ## Tasks region.").option("--feature <id>", "Restrict the ## Tasks rewrite to one feature (INDEX.md still regenerated)").option("--folder <path>", "Custom features folder").option("--json", "Output machine-readable JSON").action(async (options) => {
78748
+ feature.command("refresh").summary("Rebuild INDEX.md and each feature ## Tasks table from task edges (docs only \u2014 no status change).").description([
78749
+ "Regenerate derived views so feature markdown matches the task graph:",
78750
+ " \u2022 docs/features/INDEX.md (ID-encoded tree)",
78751
+ " \u2022 each feature ## Tasks auto-gen region (WBS / title / status from feature_id edges)",
78752
+ "",
78753
+ "Does NOT change feature frontmatter status. For lifecycle alignment use `spur feature sync`.",
78754
+ "Use after task create/link/done when the ## Tasks table is stale."
78755
+ ].join(`
78756
+ `)).option("--feature <id>", "Restrict the ## Tasks rewrite to one feature (INDEX.md still regenerated)").option("--folder <path>", "Custom features folder").option("--json", "Output machine-readable JSON").action(async (options) => {
78352
78757
  const svc = await makeService(context4, options.folder);
78353
78758
  try {
78354
78759
  const result = await svc.refresh({ featureId: options.feature });
@@ -78410,7 +78815,16 @@ ${result.id} (${result.status}): ${result.pass ? "PASS" : "FAIL"}`);
78410
78815
  context4.setExitCode(1);
78411
78816
  }
78412
78817
  });
78413
- feature.command("sync").summary("Sync feature status with linked task states.").argument("[id]", "Feature ID to sync (optional if --all is passed)").option("--all", "Sync all features with linked tasks").option("--dry-run", "Report proposed status sync transitions without applying").option("--force", "Force applying reopen proposals without confirmation").option("--folder <path>", "Custom features folder").option("--json", "Output machine-readable JSON").action(async (id, options) => {
78818
+ feature.command("sync").summary("Align feature lifecycle status with linked task states (status only \u2014 runs transition guards).").description([
78819
+ "Derive a feature status proposal from linked task statuses and apply legal hops",
78820
+ "(e.g. all tasks done \u2192 advance toward done; reopened work \u2192 reopen the feature).",
78821
+ "",
78822
+ "Applies real lifecycle transitions \u2014 gates such as dogfood, one-active-goal, and",
78823
+ "L4 AC readiness may deny a hop. Preview with --dry-run first.",
78824
+ "",
78825
+ "Does NOT rewrite INDEX.md or ## Tasks tables. For stale rosters use `spur feature refresh`."
78826
+ ].join(`
78827
+ `)).argument("[id]", "Feature ID to sync (optional if --all is passed)").option("--all", "Sync all features with linked tasks").option("--dry-run", "Report proposed status sync transitions without applying").option("--force", "Force applying reopen proposals without confirmation").option("--folder <path>", "Custom features folder").option("--json", "Output machine-readable JSON").action(async (id, options) => {
78414
78828
  const svc = await makeService(context4, options.folder);
78415
78829
  try {
78416
78830
  if (!options.all && !id) {
@@ -78541,7 +78955,7 @@ import { join as join19, resolve as resolve6 } from "path";
78541
78955
  var CLI_CONFIG = {
78542
78956
  binaryName: "spur",
78543
78957
  binaryLabel: "spur",
78544
- binaryVersion: "0.3.30",
78958
+ binaryVersion: "0.3.31",
78545
78959
  configDir: ".spur",
78546
78960
  configFile: ".spur/config.yaml",
78547
78961
  databaseFile: ".spur/spur.db"
@@ -89406,6 +89820,11 @@ var state_machine_workflow_schema_default = {
89406
89820
  description: { type: "string" },
89407
89821
  initialState: { type: "string", minLength: 1 },
89408
89822
  terminalStates: { type: "array", items: { type: "string", minLength: 1 } },
89823
+ failureStates: {
89824
+ type: "array",
89825
+ items: { type: "string", minLength: 1 },
89826
+ description: "Subset of terminalStates whose reach finalizes the run as failed. Absent \u21D2 every terminal is a success."
89827
+ },
89409
89828
  iterationBound: { type: "integer", exclusiveMinimum: 0 },
89410
89829
  vars: {
89411
89830
  type: "object",
@@ -90692,7 +91111,8 @@ init_loader();
90692
91111
  init_dist7();
90693
91112
  init_dist6();
90694
91113
  init_dist5();
90695
- import { resolve as resolve8 } from "path";
91114
+ import { closeSync as closeSync5, fstatSync as fstatSync3, openSync as openSync5, readSync as readSync3 } from "fs";
91115
+ import { join as join27, resolve as resolve8 } from "path";
90696
91116
  import { createInterface } from "readline";
90697
91117
  import { setTimeout as sleep3 } from "timers/promises";
90698
91118
  function shQuote2(value2) {
@@ -90776,7 +91196,7 @@ ${result.errors.map((m) => ` - ${m}`).join(`
90776
91196
  }
90777
91197
  context4.setExitCode(result.valid ? 0 : 1);
90778
91198
  });
90779
- workflow.command("run").description("Execute a workflow definition.").argument("<file>", "Workflow YAML file").option("--run-id <id>", "Persisted run id for workflow run").option("--vars <json>", `Per-run variable overrides as a JSON object, e.g. '{"taskId":"0042"}'`).option("--dry-run", "Validate and walk transitions without executing actions").option("--async", "Start the workflow in the background and exit immediately \u2014 monitor with `spur workflow trace <run-id>`").option("--no-plan", "Suppress the run-start plan preview (synchronous runs only)").option("--quiet", "Suppress plan and per-step progress; keep the final summary").option("--silent", "Suppress all routine output; errors still set a non-zero exit status").option("--verbose", "Include transitions and correlation diagnostics in human progress").option("--detail <level>", "Human detail level: minimal, invocation, or full").option("--trace-file", "Append a redacted schema-versioned JSONL trace under .spur/runs/workflow/").option("--steer", "Accept local in-process steering commands on stdin at declared action boundaries").option("--json", "Output machine-readable JSON where supported").action(async (file2, options) => {
91199
+ workflow.command("run").description("Execute a workflow definition.").argument("<file>", "Workflow YAML file").option("--run-id <id>", "Persisted run id for workflow run").option("--vars <json>", `Per-run variable overrides as a JSON object, e.g. '{"taskId":"0042"}'`).option("--dry-run", "Validate and walk transitions without executing actions").option("--async", "Start the workflow in the background and exit immediately \u2014 monitor with `spur workflow trace <run-id>`").option("--no-plan", "Suppress the run-start plan preview (synchronous runs only)").option("--quiet", "Suppress plan and per-step progress; keep the final summary").option("--silent", "Suppress all routine output; errors still set a non-zero exit status").option("--verbose", "Include transitions and correlation diagnostics in human progress").option("--detail <level>", "Human detail level: minimal, invocation, or full").option("--trace-file", "Append a redacted schema-versioned JSONL trace under .spur/runs/workflow/").option("--no-log", "Opt out of writing the consolidated .spur/run/<RUNID>.log").option("--steer", "Accept local in-process steering commands on stdin at declared action boundaries").option("--json", "Output machine-readable JSON where supported").action(async (file2, options) => {
90780
91200
  const json3 = options.json === true;
90781
91201
  const silent = !json3 && options.silent === true;
90782
91202
  const quiet = !json3 && options.quiet === true;
@@ -90817,6 +91237,9 @@ ${result.errors.map((m) => ` - ${m}`).join(`
90817
91237
  if (options.traceFile) {
90818
91238
  cmd.push("--trace-file");
90819
91239
  }
91240
+ if (options.log === false) {
91241
+ cmd.push("--no-log");
91242
+ }
90820
91243
  try {
90821
91244
  await spawnAsyncWorkflowWorker(spurBin, cmd);
90822
91245
  } catch {
@@ -90854,27 +91277,38 @@ Monitor with: spur workflow trace ${runId2} --follow`);
90854
91277
  traceWriter = new WorkflowTraceWriter(context4.cwd, runId);
90855
91278
  traceWriter.attach(bus);
90856
91279
  }
91280
+ let planPreview;
91281
+ if (options.plan !== false) {
91282
+ try {
91283
+ const def = await loadWorkflowDef(resolve8(context4.cwd, file2), { validateSchema: false });
91284
+ planPreview = renderRunPlan(def);
91285
+ } catch {}
91286
+ }
91287
+ const runLog = options.log === false ? undefined : new WorkflowRunLogSink({
91288
+ bus,
91289
+ dir: join27(context4.cwd, ".spur", "run"),
91290
+ runId,
91291
+ ...planPreview !== undefined ? { planPreview } : {},
91292
+ ...await resolveOutputLogConfig(context4.cwd)
91293
+ });
90857
91294
  if (humanProgress) {
90858
91295
  context4.output.write(`Run: ${runId}`);
90859
- if (options.plan !== false) {
90860
- try {
90861
- const def = await loadWorkflowDef(resolve8(context4.cwd, file2), { validateSchema: false });
90862
- context4.output.write(renderRunPlan(def));
90863
- } catch {}
90864
- }
91296
+ if (planPreview !== undefined)
91297
+ context4.output.write(planPreview);
91298
+ const stepOptions = { detail, showRunId: false };
90865
91299
  const report = (event2) => {
90866
- const line = renderStepLine(event2, { detail });
91300
+ const line = renderStepLine(event2, stepOptions);
90867
91301
  if (line !== null)
90868
91302
  context4.output.write(line);
90869
91303
  };
90870
91304
  bus.on("workflow.phase", report);
90871
- if (detail === "full")
91305
+ if (detail !== "minimal")
90872
91306
  bus.on("workflow.transition", report);
90873
91307
  bus.on("workflow.action.started", (event2) => {
90874
91308
  report(event2);
90875
91309
  const startedAt3 = Date.parse(event2.at);
90876
91310
  const timer = setInterval(() => {
90877
- const line = renderActionHeartbeat(event2, Math.max(0, Date.now() - startedAt3), { detail });
91311
+ const line = renderActionHeartbeat(event2, Math.max(0, Date.now() - startedAt3), stepOptions);
90878
91312
  if (line !== null)
90879
91313
  context4.output.write(line);
90880
91314
  }, 30000);
@@ -90897,6 +91331,7 @@ Monitor with: spur workflow trace ${runId2} --follow`);
90897
91331
  }
90898
91332
  report(event2);
90899
91333
  });
91334
+ bus.on("workflow.action.output", report);
90900
91335
  }
90901
91336
  const steeringController = options.steer === true ? new WorkflowSteeringController((ack) => {
90902
91337
  bus.emit("workflow.steering", ack);
@@ -90924,6 +91359,7 @@ Monitor with: spur workflow trace ${runId2} --follow`);
90924
91359
  clearInterval(timer);
90925
91360
  heartbeats.clear();
90926
91361
  await traceWriter?.flush();
91362
+ runLog?.close();
90927
91363
  await ledger.flush();
90928
91364
  ledger.unsubscribe();
90929
91365
  steeringInput?.close();
@@ -90935,8 +91371,18 @@ Monitor with: spur workflow trace ${runId2} --follow`);
90935
91371
  }
90936
91372
  context4.setExitCode(result.status === "done" ? 0 : 1);
90937
91373
  });
90938
- workflow.command("continue").description("Resume a paused (HITL) workflow run. Omit run-id to resume the most recent paused run.").argument("[run-id]", "Run ID to resume (default: the most recent paused run)").option("--yes", "Skip the CLI resume confirmation (does not set the persisted HITL answer)").option("--json", "Output machine-readable JSON where supported").action(async (runId, options) => {
91374
+ workflow.command("continue").description("Resume a paused (HITL) workflow run. Omit run-id to resume the most recent paused run.").argument("[run-id]", "Run ID to resume (default: the most recent paused run)").option("--yes", "Skip the CLI resume confirmation (does not set the persisted HITL answer)").option("--answer <yes|no|cancel>", "Inject a HITL gate answer before guard re-evaluation (0433). Does not imply --yes.").option("--json", "Output machine-readable JSON where supported").action(async (runId, options) => {
90939
91375
  const json3 = options.json === true;
91376
+ let hitlAnswer;
91377
+ if (options.answer !== undefined) {
91378
+ const v = String(options.answer).toLowerCase();
91379
+ if (v !== "yes" && v !== "no" && v !== "cancel") {
91380
+ context4.output.error(`Invalid --answer value "${options.answer}" - must be yes, no, or cancel.`);
91381
+ context4.setExitCode(2);
91382
+ return;
91383
+ }
91384
+ hitlAnswer = v;
91385
+ }
90940
91386
  const bus = new EventBus;
90941
91387
  const ledger = await attachSystemEventLedger(bus, context4);
90942
91388
  const svc = makeSvc(json3, bus);
@@ -90958,13 +91404,15 @@ Monitor with: spur workflow trace ${runId2} --follow`);
90958
91404
  node: "continue"
90959
91405
  });
90960
91406
  if (answer.value !== "yes") {
90961
- context4.output.error(`Aborted \u2014 run ${latest.runId} not resumed.`);
91407
+ context4.output.error(`Aborted - run ${latest.runId} not resumed.`);
90962
91408
  context4.setExitCode(1);
90963
91409
  return;
90964
91410
  }
90965
91411
  }
90966
91412
  }
90967
- const result = await svc.continuePaused(targetId);
91413
+ const result = await svc.continuePaused(targetId, {
91414
+ ...hitlAnswer !== undefined ? { hitlAnswer } : {}
91415
+ });
90968
91416
  context4.output.write(json3 ? toJson2(result) : `workflow ${result.status}: ${result.workflowName} -> ${result.finalState}`);
90969
91417
  context4.setExitCode(result.status === "done" ? 0 : 1);
90970
91418
  } catch (err) {
@@ -90975,7 +91423,9 @@ Monitor with: spur workflow trace ${runId2} --follow`);
90975
91423
  ledger.unsubscribe();
90976
91424
  }
90977
91425
  });
90978
- workflow.command("clean").description("Finalize orphaned runs stuck in running/pending past a staleness threshold (mark as failed). " + "To cancel a single live run by id, use `spur workflow cancel <run-id>` instead.").option("--older-than <minutes>", "Staleness threshold in minutes", "30").option("--force", "Clean ALL non-terminal runs regardless of age (overrides --older-than)").option("--dry-run", "List what would be cleaned without writing").option("--json", "Output machine-readable JSON where supported").action(async (options) => {
91426
+ workflow.command("clean").description("Housekeeping: finalize orphaned runs stuck in running/pending past a staleness threshold " + "(mark as failed) and reclaim retained run logs older than workflow.logRetentionDays. " + "`--logs` scopes to log reclamation only. To cancel a single live run by id, use " + "`spur workflow cancel <run-id>` instead.").option("--older-than <minutes>", "Staleness threshold in minutes (stale-run scope only)", "30").option("--force", "Clean ALL non-terminal runs regardless of age (overrides --older-than)").option("--logs", "Scope to retained run-log reclamation only (skip stale-run finalization)").option("--dry-run", "List what would be cleaned without writing (applies to both scopes)").option("--json", "Output machine-readable JSON where supported").action(async (options) => {
91427
+ const dryRun = options.dryRun === true;
91428
+ const logsOnly = options.logs === true;
90979
91429
  const force = options.force === true;
90980
91430
  const minutes = force ? 0 : Number.parseInt(options.olderThan ?? "30", 10);
90981
91431
  if (!Number.isFinite(minutes) || minutes < 0) {
@@ -90983,19 +91433,35 @@ Monitor with: spur workflow trace ${runId2} --follow`);
90983
91433
  context4.setExitCode(2);
90984
91434
  return;
90985
91435
  }
90986
- const result = await makeSvc(options.json).clean(minutes, options.dryRun === true);
91436
+ const svc = makeSvc(options.json);
91437
+ const result = logsOnly ? undefined : await svc.clean(minutes, dryRun);
91438
+ const retentionDays = await resolveWorkflowLogRetentionDays(context4.cwd);
91439
+ const logResult2 = await svc.cleanRunLogs(retentionDays, dryRun);
90987
91440
  if (options.json) {
90988
- context4.output.write(toJson2(result));
91441
+ context4.output.write(toJson2(logsOnly ? logResult2 : { ...result, logs: logResult2 }));
90989
91442
  } else {
90990
- const verb = result.dryRun ? "Would finalize" : "Finalized";
90991
- if (result.cleaned.length === 0) {
90992
- const ageMsg = force ? "" : ` older than ${minutes}m`;
90993
- context4.output.write(`No stale runs${ageMsg}.`);
90994
- } else {
90995
- const ageMsg = force ? " (all non-terminal)" : ` (>${minutes}m)`;
90996
- context4.output.write(`${verb} ${result.cleaned.length} stale run(s)${ageMsg}:
91443
+ if (result !== undefined) {
91444
+ const verb = dryRun ? "Would finalize" : "Finalized";
91445
+ if (result.cleaned.length === 0) {
91446
+ const ageMsg = force ? "" : ` older than ${minutes}m`;
91447
+ context4.output.write(`No stale runs${ageMsg}.`);
91448
+ } else {
91449
+ const ageMsg = force ? " (all non-terminal)" : ` (>${minutes}m)`;
91450
+ context4.output.write(`${verb} ${result.cleaned.length} stale run(s)${ageMsg}:
90997
91451
  ` + result.cleaned.map((r2) => ` ${r2.runId} (started ${r2.startedAt})`).join(`
90998
91452
  `));
91453
+ }
91454
+ }
91455
+ const logVerb = dryRun ? "Would reclaim" : "Reclaimed";
91456
+ if (logResult2.reclaimed.length === 0) {
91457
+ context4.output.write(`No retained run logs older than ${retentionDays}d.`);
91458
+ } else {
91459
+ context4.output.write(`${logVerb} ${logResult2.reclaimed.length} retained run log(s) (>${retentionDays}d):
91460
+ ` + logResult2.reclaimed.map((l) => ` ${l.runId} (mtime ${l.mtime})`).join(`
91461
+ `));
91462
+ }
91463
+ for (const failure of logResult2.failures) {
91464
+ context4.output.error(`Failed to remove run log ${failure.path}: ${failure.error}`);
90999
91465
  }
91000
91466
  }
91001
91467
  });
@@ -91026,7 +91492,7 @@ Monitor with: spur workflow trace ${runId2} --follow`);
91026
91492
  context4.output.write(formatListHuman(result));
91027
91493
  }
91028
91494
  });
91029
- workflow.command("trace").description("Show persisted workflow run history.").argument("[run-id]", "Run ID for per-run timeline detail").option("--workflow <name>", "Filter by workflow name").option("--status <status>", "Filter by status: done, failed, running").option("--since <iso-date>", "Filter runs started on or after this date").option("--last <n>", "Limit results (default 20)", "20").option("--follow", "Replay a run timeline and poll persisted state until it becomes terminal").option("--poll <ms>", "Follow polling interval in milliseconds", "1000").option("--json", "Output machine-readable JSON where supported").action(async (runId, options) => {
91495
+ workflow.command("trace").description("Show persisted workflow run history.").argument("[run-id]", "Run ID for per-run timeline detail").option("--workflow <name>", "Filter by workflow name").option("--status <status>", "Filter by status: done, failed, running").option("--since <iso-date>", "Filter runs started on or after this date").option("--last <n>", "Limit results (default 20)", "20").option("--follow", "Replay a run timeline and poll persisted state until it becomes terminal").option("--poll <ms>", "Follow polling interval in milliseconds", "1000").option("--output", "With --follow: stream .spur/run/<RUNID>.log instead of the DB timeline").option("--json", "Output machine-readable JSON where supported").action(async (runId, options) => {
91030
91496
  const svc = makeSvc();
91031
91497
  const last = parseInt(options.last, 10);
91032
91498
  if (Number.isNaN(last) || last < 1) {
@@ -91050,13 +91516,27 @@ Monitor with: spur workflow trace ${runId2} --follow`);
91050
91516
  context4.setExitCode(1);
91051
91517
  return;
91052
91518
  }
91519
+ if (options.output === true && options.follow !== true) {
91520
+ context4.output.error("--output requires --follow");
91521
+ context4.setExitCode(1);
91522
+ return;
91523
+ }
91524
+ if (options.output === true && options.json === true) {
91525
+ context4.output.error("--output is a human streaming mode and cannot be combined with --json");
91526
+ context4.setExitCode(1);
91527
+ return;
91528
+ }
91053
91529
  if (options.status !== undefined && !["done", "failed", "running"].includes(options.status)) {
91054
91530
  context4.output.error("--status must be one of: done, failed, running");
91055
91531
  context4.setExitCode(1);
91056
91532
  return;
91057
91533
  }
91058
91534
  if (options.follow === true && runId !== undefined) {
91059
- await followTrace(svc, runId, pollMs, (line) => context4.output.write(line));
91535
+ if (options.output === true) {
91536
+ await followRunLog(svc, runId, context4.cwd, pollMs, (line) => context4.output.write(line));
91537
+ } else {
91538
+ await followTrace(svc, runId, pollMs, (line) => context4.output.write(line));
91539
+ }
91060
91540
  return;
91061
91541
  }
91062
91542
  const result = runId ? await svc.trace(runId) : await svc.trace({
@@ -91128,7 +91608,7 @@ function formatTraceTimeline(result) {
91128
91608
  ""
91129
91609
  ];
91130
91610
  if (result.outputArtifact !== undefined) {
91131
- lines.push(`Agent output: ${result.outputArtifact} (tail -f for live view)`);
91611
+ lines.push(`Run log: ${result.outputArtifact} (tail -f for live view)`);
91132
91612
  lines.push("");
91133
91613
  }
91134
91614
  for (const event2 of events2) {
@@ -91191,6 +91671,59 @@ async function followTrace(service, runId, pollMs, write, wait = (ms) => sleep3(
91191
91671
  function isTerminalTraceStatus(status) {
91192
91672
  return status !== "running" && status !== "pending";
91193
91673
  }
91674
+ function readRunLogChunk(logPath, offset) {
91675
+ let fd;
91676
+ try {
91677
+ fd = openSync5(logPath, "r");
91678
+ } catch {
91679
+ return { exists: false, lines: [], offset };
91680
+ }
91681
+ try {
91682
+ const size = fstatSync3(fd).size;
91683
+ if (size <= offset)
91684
+ return { exists: true, lines: [], offset };
91685
+ const buffer = Buffer.alloc(size - offset);
91686
+ readSync3(fd, buffer, 0, buffer.length, offset);
91687
+ const text4 = buffer.toString("utf8");
91688
+ const lastNewline = text4.lastIndexOf(`
91689
+ `);
91690
+ const consumed = lastNewline >= 0 ? lastNewline + 1 : 0;
91691
+ const parts = consumed === 0 ? [] : text4.slice(0, consumed).split(`
91692
+ `);
91693
+ const lines = parts.length > 0 && parts.at(-1) === "" ? parts.slice(0, -1) : parts;
91694
+ return { exists: true, lines, offset: offset + consumed };
91695
+ } finally {
91696
+ closeSync5(fd);
91697
+ }
91698
+ }
91699
+ async function followRunLog(service, runId, dir, pollMs, write, wait = (ms) => sleep3(ms)) {
91700
+ const logPath = join27(dir, ".spur", "run", `${runId}.log`);
91701
+ let offset = 0;
91702
+ let everRead = false;
91703
+ while (true) {
91704
+ const chunk = readRunLogChunk(logPath, offset);
91705
+ if (chunk.exists && (chunk.lines.length > 0 || chunk.offset > offset)) {
91706
+ everRead = true;
91707
+ for (const line of chunk.lines)
91708
+ write(line);
91709
+ offset = chunk.offset;
91710
+ }
91711
+ let terminal = false;
91712
+ try {
91713
+ terminal = isTerminalTraceStatus((await service.trace(runId)).run.status);
91714
+ } catch (error51) {
91715
+ if (!String(error51).includes("Run not found"))
91716
+ throw error51;
91717
+ }
91718
+ if (terminal) {
91719
+ if (!everRead) {
91720
+ write(`No run log at ${logPath} \u2014 the run may have been started with --no-log.`);
91721
+ }
91722
+ return;
91723
+ }
91724
+ await wait(pollMs);
91725
+ }
91726
+ }
91194
91727
  function formatActionCost(event2) {
91195
91728
  if (event2.kind !== "action")
91196
91729
  return "";
@@ -91211,7 +91744,7 @@ init_src3();
91211
91744
  init_src();
91212
91745
  init_src2();
91213
91746
  init_dist5();
91214
- import { dirname as dirname16, join as join27, resolve as resolve9 } from "path";
91747
+ import { dirname as dirname16, join as join28, resolve as resolve9 } from "path";
91215
91748
  import { isatty as isatty4 } from "tty";
91216
91749
 
91217
91750
  // ../../node_modules/.bun/@clack+core@1.4.1/node_modules/@clack/core/dist/index.mjs
@@ -92633,7 +93166,7 @@ function createCliContext(options) {
92633
93166
  function noopSetExitCode(_code) {}
92634
93167
  async function createMigratedDbAdapter(cwd = process.cwd(), env = process.env, dbUrl) {
92635
93168
  const config4 = buildConfigFromEnv(env);
92636
- const configuredUrl = env.DATABASE_URL === undefined ? join27(cwd, DEFAULT_DATABASE_URL) : config4.database.url;
93169
+ const configuredUrl = env.DATABASE_URL === undefined ? join28(cwd, DEFAULT_DATABASE_URL) : config4.database.url;
92637
93170
  const url2 = dbUrl ?? configuredUrl;
92638
93171
  if (url2 !== IN_MEMORY_DATABASE_URL) {
92639
93172
  await createNodeFileSystem3().ensureDir(dirname16(url2));