@gobing-ai/spur 0.3.58 → 0.3.61

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 (93) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/config.example.yaml +2 -2
  3. package/config/config.global.yaml +137 -0
  4. package/config/corpus-baseline.json +96 -8
  5. package/config/workflow-composition-baseline.json +1 -1
  6. package/config/workflows/wayfinder-resolution.yaml +4 -6
  7. package/package.json +9 -9
  8. package/plugins/README.md +5 -4
  9. package/plugins/sp/README.md +3 -3
  10. package/plugins/sp/agents/super-planner.md +1 -1
  11. package/plugins/sp/commands/dev-pr-review.md +1 -1
  12. package/plugins/sp/commands/dev-wrap.md +2 -2
  13. package/plugins/sp/commands/dev-wrapall.md +2 -2
  14. package/plugins/sp/plugin.json +1 -1
  15. package/plugins/sp/references/roles.md +12 -9
  16. package/plugins/sp/scripts/surface-drift-inventory.ts +51 -17
  17. package/plugins/sp/scripts/validate-commands.ts +11 -4
  18. package/plugins/sp/skills/code-verification/SKILL.md +1 -1
  19. package/plugins/sp/skills/code-verification/references/verdict-schema.md +1 -1
  20. package/plugins/sp/skills/issue-finding/SKILL.md +1 -1
  21. package/plugins/sp/skills/next-router/references/routing-table.md +1 -1
  22. package/plugins/sp/skills/pr-reviewing/SKILL.md +2 -2
  23. package/plugins/sp/skills/spec-decomposition/references/decomposition.md +1 -1
  24. package/plugins/sp/skills/spur-cli/references/init.md +1 -1
  25. package/plugins/sp/skills/spur-cli/references/tasks/l3-guard-cheatsheet.md +1 -1
  26. package/plugins/sp/skills/spur-cli/references/workflows/operations.md +1 -1
  27. package/plugins/sp/skills/spur-cli/references/workflows.md +4 -4
  28. package/plugins/sp/skills/spur-dev/SKILL.md +4 -4
  29. package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +4 -4
  30. package/plugins/sp/skills/spur-dev/references/dev-operations.md +9 -9
  31. package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +1 -1
  32. package/plugins/sp/skills/spur-dev/references/execution-batch.md +3 -3
  33. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +1 -1
  34. package/plugins/sp/skills/spur-dev/references/feature-link-helper.md +3 -2
  35. package/plugins/sp/skills/spur-dev/references/gate-checklists.md +1 -1
  36. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +5 -2
  37. package/plugins/sp/skills/spur-dev/references/planning-workflow.md +2 -2
  38. package/schemas/spur-config.schema.json +1 -2
  39. package/spur.js +1381 -527
  40. package/web/_astro/BoardApp.BtRfVADq.js +1 -0
  41. package/web/_astro/BoardApp.CBIzcvqi.js +178 -0
  42. package/web/_astro/{TaskDetail.DHjEt5vl.js → TaskDetail.D2N60cfE.js} +1 -1
  43. package/web/_astro/{arc.XgRC1Ij_.js → arc.D-EfJJwf.js} +1 -1
  44. package/web/_astro/{architectureDiagram-3BPJPVTR.DOZWrfHc.js → architectureDiagram-3BPJPVTR.CgvTTzqp.js} +1 -1
  45. package/web/_astro/{blockDiagram-GPEHLZMM.ClQnCGf_.js → blockDiagram-GPEHLZMM.CnOohvvn.js} +1 -1
  46. package/web/_astro/{c4Diagram-AAUBKEIU.CKCtUD0Y.js → c4Diagram-AAUBKEIU.BFcBGUy_.js} +1 -1
  47. package/web/_astro/channel.kIu33Gui.js +1 -0
  48. package/web/_astro/{chunk-2J33WTMH.c7J8OHq5.js → chunk-2J33WTMH.C-6MR-XY.js} +1 -1
  49. package/web/_astro/{chunk-4BX2VUAB.C-A1Dv27.js → chunk-4BX2VUAB.BN4LP5AR.js} +1 -1
  50. package/web/_astro/{chunk-55IACEB6.C4kGGALB.js → chunk-55IACEB6.tUJ_CTtZ.js} +1 -1
  51. package/web/_astro/{chunk-727SXJPM.Bith2NHt.js → chunk-727SXJPM.BNCk-sxv.js} +1 -1
  52. package/web/_astro/{chunk-AQP2D5EJ.qeSXhsVY.js → chunk-AQP2D5EJ.BkpFIbNa.js} +1 -1
  53. package/web/_astro/{chunk-FMBD7UC4.DdQQnTAy.js → chunk-FMBD7UC4.DcSZ87PN.js} +1 -1
  54. package/web/_astro/{chunk-ND2GUHAM.BZYQVeZd.js → chunk-ND2GUHAM.BkLvHFFf.js} +1 -1
  55. package/web/_astro/{chunk-QZHKN3VN.BiUWwHaV.js → chunk-QZHKN3VN.HOdgszax.js} +1 -1
  56. package/web/_astro/{classDiagram-4FO5ZUOK.OGRhcldh.js → classDiagram-4FO5ZUOK.CWfRiY6b.js} +1 -1
  57. package/web/_astro/{classDiagram-v2-Q7XG4LA2.OGRhcldh.js → classDiagram-v2-Q7XG4LA2.CWfRiY6b.js} +1 -1
  58. package/web/_astro/{cose-bilkent-S5V4N54A.DxYklM_j.js → cose-bilkent-S5V4N54A.C6j4PxoN.js} +1 -1
  59. package/web/_astro/{dagre-BM42HDAG.BSb2dEbo.js → dagre-BM42HDAG.BATZG1II.js} +1 -1
  60. package/web/_astro/{diagram-2AECGRRQ.mOrItPK2.js → diagram-2AECGRRQ.B0f5yY6x.js} +1 -1
  61. package/web/_astro/{diagram-5GNKFQAL.C99r7J3C.js → diagram-5GNKFQAL.Bewupqv0.js} +1 -1
  62. package/web/_astro/{diagram-KO2AKTUF.BKbnisJO.js → diagram-KO2AKTUF.C23r1tB2.js} +1 -1
  63. package/web/_astro/{diagram-LMA3HP47.D8FJGo4V.js → diagram-LMA3HP47.DUErdBOR.js} +1 -1
  64. package/web/_astro/{diagram-OG6HWLK6.DVBs7n4Q.js → diagram-OG6HWLK6.BubmwAjb.js} +1 -1
  65. package/web/_astro/{erDiagram-TEJ5UH35.CddMTl4l.js → erDiagram-TEJ5UH35.BE_Qs5mv.js} +1 -1
  66. package/web/_astro/{flowDiagram-I6XJVG4X.B7WclnjQ.js → flowDiagram-I6XJVG4X.COWdbzon.js} +1 -1
  67. package/web/_astro/{ganttDiagram-6RSMTGT7.CRh7ggvz.js → ganttDiagram-6RSMTGT7.5EGYC4MK.js} +1 -1
  68. package/web/_astro/{gitGraphDiagram-PVQCEYII.du-L7V8A.js → gitGraphDiagram-PVQCEYII.bUUV7iEw.js} +1 -1
  69. package/web/_astro/index.Cestp9nh.css +1 -0
  70. package/web/_astro/{infoDiagram-5YYISTIA.CClGl9Px.js → infoDiagram-5YYISTIA.CbiInFvz.js} +1 -1
  71. package/web/_astro/{ishikawaDiagram-YF4QCWOH.BuTETIPz.js → ishikawaDiagram-YF4QCWOH.CB7lrSsJ.js} +1 -1
  72. package/web/_astro/{journeyDiagram-JHISSGLW.Cyg1zCiE.js → journeyDiagram-JHISSGLW.rhGZgWt8.js} +1 -1
  73. package/web/_astro/{kanban-definition-UN3LZRKU.aH8eDXwX.js → kanban-definition-UN3LZRKU.DPeZD_lP.js} +1 -1
  74. package/web/_astro/{linear.paE_RY_i.js → linear.l60Nyp5b.js} +1 -1
  75. package/web/_astro/{mermaid.core.BhdKkI85.js → mermaid.core.DmtMJcmL.js} +4 -4
  76. package/web/_astro/{mindmap-definition-RKZ34NQL.aZNfv8Nx.js → mindmap-definition-RKZ34NQL.Cc47AcCn.js} +1 -1
  77. package/web/_astro/{pieDiagram-4H26LBE5.5psni0hC.js → pieDiagram-4H26LBE5.B8cN-S9g.js} +1 -1
  78. package/web/_astro/{quadrantDiagram-W4KKPZXB.DcGPGrFd.js → quadrantDiagram-W4KKPZXB.DY1FN89L.js} +1 -1
  79. package/web/_astro/{requirementDiagram-4Y6WPE33.BwPD2lzi.js → requirementDiagram-4Y6WPE33.CnM6VbV8.js} +1 -1
  80. package/web/_astro/{sankeyDiagram-5OEKKPKP.B3jGVk0l.js → sankeyDiagram-5OEKKPKP.B9DcGfNV.js} +1 -1
  81. package/web/_astro/{sequenceDiagram-3UESZ5HK.BdWsx3LW.js → sequenceDiagram-3UESZ5HK.ymxaNlAY.js} +1 -1
  82. package/web/_astro/{stateDiagram-AJRCARHV.DRpG4ClZ.js → stateDiagram-AJRCARHV.DDOJ3d8P.js} +1 -1
  83. package/web/_astro/{stateDiagram-v2-BHNVJYJU.Su0ML9Wo.js → stateDiagram-v2-BHNVJYJU.Ck0Nb_KY.js} +1 -1
  84. package/web/_astro/{timeline-definition-PNZ67QCA.Cg_Uv8A5.js → timeline-definition-PNZ67QCA.BNOvZwAN.js} +1 -1
  85. package/web/_astro/{vennDiagram-CIIHVFJN.DVouKT4b.js → vennDiagram-CIIHVFJN.D3k5ivSF.js} +1 -1
  86. package/web/_astro/{wardley-L42UT6IY.CexIVQli.js → wardley-L42UT6IY.BylaxVqn.js} +1 -1
  87. package/web/_astro/{wardleyDiagram-YWT4CUSO.ChSAzcvx.js → wardleyDiagram-YWT4CUSO.HLNtFUm9.js} +1 -1
  88. package/web/_astro/{xychartDiagram-2RQKCTM6.CN-Yp50J.js → xychartDiagram-2RQKCTM6.B-WooKSU.js} +1 -1
  89. package/web/index.html +2 -2
  90. package/web/_astro/BoardApp.CrusGeQ4.js +0 -1
  91. package/web/_astro/BoardApp.P8SRAD5Q.js +0 -179
  92. package/web/_astro/channel.CmK546kO.js +0 -1
  93. package/web/_astro/index.B4x8fe52.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.41/node_modules/@gobing-ai/ts-utils/dist/errors.js
50
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.42/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.41/node_modules/@gobing-ai/ts-utils/dist/api-response.js
61
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.42/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,13 +81,13 @@ 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.41/node_modules/@gobing-ai/ts-utils/dist/cursor.js
84
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.42/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.41/node_modules/@gobing-ai/ts-utils/dist/event-severity.js
87
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.42/node_modules/@gobing-ai/ts-utils/dist/event-severity.js
88
88
  var init_event_severity = () => {};
89
89
 
90
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.41/node_modules/@gobing-ai/ts-utils/dist/object.js
90
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.42/node_modules/@gobing-ai/ts-utils/dist/object.js
91
91
  function isPlainObject(value) {
92
92
  return typeof value === "object" && value !== null && !Array.isArray(value);
93
93
  }
@@ -105,7 +105,7 @@ function deepMerge(target, source) {
105
105
  return result;
106
106
  }
107
107
 
108
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.41/node_modules/@gobing-ai/ts-utils/dist/output.js
108
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.42/node_modules/@gobing-ai/ts-utils/dist/output.js
109
109
  function processStream(name) {
110
110
  const proc = globalThis.process;
111
111
  const stream = proc?.[name];
@@ -126,7 +126,7 @@ function echoError(message, target = defaultStderrTarget ?? processStream("stder
126
126
  }
127
127
  var defaultStdoutTarget, defaultStderrTarget;
128
128
 
129
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.41/node_modules/@gobing-ai/ts-utils/dist/index.js
129
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.42/node_modules/@gobing-ai/ts-utils/dist/index.js
130
130
  var init_dist = __esm(() => {
131
131
  init_api_response();
132
132
  init_cursor();
@@ -21749,7 +21749,7 @@ var init_zod = __esm(() => {
21749
21749
  init_external();
21750
21750
  });
21751
21751
 
21752
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+4acea4302d059ca5/node_modules/@gobing-ai/ts-runtime/dist/config.js
21752
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+65e77bb9e86f02cf/node_modules/@gobing-ai/ts-runtime/dist/config.js
21753
21753
  function getProcessEnv() {
21754
21754
  return process.env;
21755
21755
  }
@@ -21827,7 +21827,7 @@ var init_config = __esm(() => {
21827
21827
  };
21828
21828
  });
21829
21829
 
21830
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+4acea4302d059ca5/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
21830
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+65e77bb9e86f02cf/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
21831
21831
  import { appendFileSync, cpSync, createReadStream, createWriteStream, existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "fs";
21832
21832
  import { dirname, resolve as resolvePath } from "path";
21833
21833
  function createNodeFileSystem(root, paths) {
@@ -21914,7 +21914,7 @@ function findProjectRoot(startDir) {
21914
21914
  }
21915
21915
  var init_file_system_node = () => {};
21916
21916
 
21917
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+4acea4302d059ca5/node_modules/@gobing-ai/ts-runtime/dist/db-errors.js
21917
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+65e77bb9e86f02cf/node_modules/@gobing-ai/ts-runtime/dist/db-errors.js
21918
21918
  var DbModuleNotInstalledError;
21919
21919
  var init_db_errors = __esm(() => {
21920
21920
  DbModuleNotInstalledError = class DbModuleNotInstalledError extends Error {
@@ -29125,7 +29125,7 @@ var init_execa = __esm(() => {
29125
29125
  } = getIpcExport());
29126
29126
  });
29127
29127
 
29128
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+4acea4302d059ca5/node_modules/@gobing-ai/ts-runtime/dist/process-executor.js
29128
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+65e77bb9e86f02cf/node_modules/@gobing-ai/ts-runtime/dist/process-executor.js
29129
29129
  import { isatty } from "tty";
29130
29130
  function processEventSeverity(reason, exitCode) {
29131
29131
  if (reason === "error")
@@ -29489,7 +29489,7 @@ var init_process_executor = __esm(() => {
29489
29489
  init_config();
29490
29490
  });
29491
29491
 
29492
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+4acea4302d059ca5/node_modules/@gobing-ai/ts-runtime/dist/runtime-node-bun.js
29492
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+65e77bb9e86f02cf/node_modules/@gobing-ai/ts-runtime/dist/runtime-node-bun.js
29493
29493
  function getNodeFileSystem() {
29494
29494
  if (!_nodeFileSystem)
29495
29495
  _nodeFileSystem = createNodeFileSystem();
@@ -29549,7 +29549,7 @@ var init_runtime_node_bun = __esm(() => {
29549
29549
  };
29550
29550
  });
29551
29551
 
29552
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+4acea4302d059ca5/node_modules/@gobing-ai/ts-runtime/dist/context.js
29552
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+65e77bb9e86f02cf/node_modules/@gobing-ai/ts-runtime/dist/context.js
29553
29553
  class RuntimeContext {
29554
29554
  scope;
29555
29555
  runtimeName;
@@ -29619,7 +29619,7 @@ var init_context = __esm(() => {
29619
29619
  init_runtime_node_bun();
29620
29620
  });
29621
29621
 
29622
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+4acea4302d059ca5/node_modules/@gobing-ai/ts-runtime/dist/path.js
29622
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+65e77bb9e86f02cf/node_modules/@gobing-ai/ts-runtime/dist/path.js
29623
29623
  function normalizeSeparators(path6) {
29624
29624
  return path6.replaceAll("\\", "/");
29625
29625
  }
@@ -29680,17 +29680,17 @@ var init_path = __esm(() => {
29680
29680
  SEP = globalThis.process?.platform === "win32" ? "\\" : "/";
29681
29681
  });
29682
29682
 
29683
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+4acea4302d059ca5/node_modules/@gobing-ai/ts-runtime/dist/schema-validation.js
29683
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+65e77bb9e86f02cf/node_modules/@gobing-ai/ts-runtime/dist/schema-validation.js
29684
29684
  var REMOTE_SCHEMA_MAX_BYTES;
29685
29685
  var init_schema_validation = __esm(() => {
29686
29686
  init_dist2();
29687
29687
  REMOTE_SCHEMA_MAX_BYTES = 5 * 1024 * 1024;
29688
29688
  });
29689
29689
 
29690
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+4acea4302d059ca5/node_modules/@gobing-ai/ts-runtime/dist/types.js
29690
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+65e77bb9e86f02cf/node_modules/@gobing-ai/ts-runtime/dist/types.js
29691
29691
  var init_types = () => {};
29692
29692
 
29693
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+4acea4302d059ca5/node_modules/@gobing-ai/ts-runtime/dist/index.js
29693
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+65e77bb9e86f02cf/node_modules/@gobing-ai/ts-runtime/dist/index.js
29694
29694
  var init_dist3 = __esm(() => {
29695
29695
  init_config();
29696
29696
  init_context();
@@ -29699,7 +29699,7 @@ var init_dist3 = __esm(() => {
29699
29699
  init_types();
29700
29700
  });
29701
29701
 
29702
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+4acea4302d059ca5/node_modules/@gobing-ai/ts-runtime/dist/bun-sqlite.js
29702
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+65e77bb9e86f02cf/node_modules/@gobing-ai/ts-runtime/dist/bun-sqlite.js
29703
29703
  import { Database } from "bun:sqlite";
29704
29704
  var init_bun_sqlite = () => {};
29705
29705
 
@@ -34129,7 +34129,7 @@ var init_bun_sqlite2 = __esm(() => {
34129
34129
  init_session2();
34130
34130
  });
34131
34131
 
34132
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/schema/inbox-messages.js
34132
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/schema/inbox-messages.js
34133
34133
  var inboxMessages;
34134
34134
  var init_inbox_messages = __esm(() => {
34135
34135
  init_sqlite_core();
@@ -34148,7 +34148,7 @@ var init_inbox_messages = __esm(() => {
34148
34148
  }, (table2) => [index("idx_inbox_messages_to_status").on(table2.toId, table2.status)]);
34149
34149
  });
34150
34150
 
34151
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/schema/common.js
34151
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/schema/common.js
34152
34152
  function nowTimestamp() {
34153
34153
  return Date.now();
34154
34154
  }
@@ -34177,7 +34177,7 @@ var init_common3 = __esm(() => {
34177
34177
  appendOnlyColumns = buildAppendOnlyColumns();
34178
34178
  });
34179
34179
 
34180
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/schema/queue-jobs.js
34180
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/schema/queue-jobs.js
34181
34181
  var queueJobs;
34182
34182
  var init_queue_jobs = __esm(() => {
34183
34183
  init_sqlite_core();
@@ -34197,7 +34197,7 @@ var init_queue_jobs = __esm(() => {
34197
34197
  }, (table2) => [index("queue_jobs_ready_idx").on(table2.status, table2.nextRetryAt, table2.createdAt)]);
34198
34198
  });
34199
34199
 
34200
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/schema/runtime.js
34200
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/schema/runtime.js
34201
34201
  var exports_runtime = {};
34202
34202
  __export(exports_runtime, {
34203
34203
  queueJobs: () => queueJobs,
@@ -34208,7 +34208,7 @@ var init_runtime = __esm(() => {
34208
34208
  init_queue_jobs();
34209
34209
  });
34210
34210
 
34211
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/adapters/bun-sqlite.js
34211
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/adapters/bun-sqlite.js
34212
34212
  var exports_bun_sqlite = {};
34213
34213
  __export(exports_bun_sqlite, {
34214
34214
  BunSqliteAdapter: () => BunSqliteAdapter
@@ -34519,7 +34519,7 @@ var init_d1 = __esm(() => {
34519
34519
  init_session3();
34520
34520
  });
34521
34521
 
34522
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/adapters/d1.js
34522
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/adapters/d1.js
34523
34523
  var exports_d1 = {};
34524
34524
  __export(exports_d1, {
34525
34525
  D1Adapter: () => D1Adapter
@@ -34583,7 +34583,7 @@ var init_d12 = __esm(() => {
34583
34583
  init_runtime();
34584
34584
  });
34585
34585
 
34586
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/adapter.js
34586
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/adapter.js
34587
34587
  async function createDbAdapter(config3) {
34588
34588
  switch (config3.driver) {
34589
34589
  case "bun-sqlite": {
@@ -34617,7 +34617,7 @@ var init_drizzle_orm = __esm(() => {
34617
34617
  init_view_common();
34618
34618
  });
34619
34619
 
34620
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/query-spec.js
34620
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/query-spec.js
34621
34621
  function compilePredicate(predicate) {
34622
34622
  if ("and" in predicate) {
34623
34623
  const parts = predicate.and.map(compilePredicate).filter((p) => p !== undefined);
@@ -34655,7 +34655,7 @@ var init_query_spec = __esm(() => {
34655
34655
  };
34656
34656
  });
34657
34657
 
34658
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/base-dao.js
34658
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/base-dao.js
34659
34659
  function asSelectQuery(query) {
34660
34660
  return query;
34661
34661
  }
@@ -34697,7 +34697,7 @@ var init_base_dao = __esm(() => {
34697
34697
  init_query_spec();
34698
34698
  });
34699
34699
 
34700
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/embedded-migrations.js
34700
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/embedded-migrations.js
34701
34701
  var embeddedMigrations;
34702
34702
  var init_embedded_migrations = __esm(() => {
34703
34703
  embeddedMigrations = [
@@ -34729,7 +34729,7 @@ var init_embedded_migrations = __esm(() => {
34729
34729
  ];
34730
34730
  });
34731
34731
 
34732
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/entity-dao.js
34732
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/entity-dao.js
34733
34733
  var EntityDao;
34734
34734
  var init_entity_dao = __esm(() => {
34735
34735
  init_drizzle_orm();
@@ -34891,7 +34891,7 @@ var init_entity_dao = __esm(() => {
34891
34891
  };
34892
34892
  });
34893
34893
 
34894
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/inbox-message-dao.js
34894
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/inbox-message-dao.js
34895
34895
  function isPromiseLike(value) {
34896
34896
  return value !== null && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
34897
34897
  }
@@ -35069,7 +35069,7 @@ var init_migrator2 = __esm(() => {
35069
35069
  init_migrator();
35070
35070
  });
35071
35071
 
35072
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/migrate.js
35072
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/migrate.js
35073
35073
  async function ensureJournalTable(adapter, table3) {
35074
35074
  await adapter.exec(`CREATE TABLE IF NOT EXISTS "${table3}" (` + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "hash text NOT NULL, " + "created_at numeric" + ")");
35075
35075
  }
@@ -35144,7 +35144,7 @@ var init_migrate = __esm(() => {
35144
35144
  init_embedded_migrations();
35145
35145
  });
35146
35146
 
35147
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/queue-job-dao.js
35147
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/queue-job-dao.js
35148
35148
  var QueueJobDao;
35149
35149
  var init_queue_job_dao = __esm(() => {
35150
35150
  init_drizzle_orm();
@@ -35285,7 +35285,7 @@ var init_queue_job_dao = __esm(() => {
35285
35285
  };
35286
35286
  });
35287
35287
 
35288
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/index.js
35288
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/index.js
35289
35289
  var exports_dist = {};
35290
35290
  __export(exports_dist, {
35291
35291
  embeddedMigrations: () => embeddedMigrations,
@@ -37592,6 +37592,18 @@ function resolveHistoryRefreshTrigger(config3) {
37592
37592
  const parsed = HistoryRefreshConfigSchema.parse(config3?.history?.refresh ?? {});
37593
37593
  return { onCompletion: parsed.on_completion, debounceMs: parsed.debounce_ms };
37594
37594
  }
37595
+ function misplacedGlobalKeys(parsed) {
37596
+ const misplaced = [];
37597
+ for (const key of PROJECT_SHAPED_GLOBAL_KEYS) {
37598
+ if (key in parsed)
37599
+ misplaced.push(key);
37600
+ }
37601
+ const agent = parsed.agent;
37602
+ if (typeof agent === "object" && agent !== null && "team" in agent) {
37603
+ misplaced.push("agent.team");
37604
+ }
37605
+ return misplaced;
37606
+ }
37595
37607
  function parseEnvBoolean(value) {
37596
37608
  if (value === undefined || value === "")
37597
37609
  return;
@@ -37620,7 +37632,7 @@ function buildConfigFromEnv(env = process.env) {
37620
37632
  }
37621
37633
  });
37622
37634
  }
37623
- 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, AGENT_ROLE_NAMES, DEFAULT_AGENT_ROLES, AgentExecutorConfigSchema, AgentRoleConfigSchema, AGENT_ID_REGEX, TeamMemberConfigSchema, TeamConfigSchema, AgentOutputConfigSchema, AgentConfigSchema, RulesConfigSchema, WorkflowsConfigSchema, WorkflowConfigSchema, RedactionConfigSchema, HistoryRefreshConfigSchema, HistoryConfigSchema, spurConfigSchema, configSchema2;
37635
+ 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, AGENT_ROLE_NAMES, DEFAULT_AGENT_ROLES, AgentExecutorConfigSchema, AgentRoleConfigSchema, AGENT_ID_REGEX, TeamMemberConfigSchema, TeamConfigSchema, AgentOutputConfigSchema, AgentConfigSchema, RulesConfigSchema, WorkflowsConfigSchema, WorkflowConfigSchema, RedactionConfigSchema, HistoryRefreshConfigSchema, HistoryConfigSchema, spurConfigSchema, PROJECT_SHAPED_GLOBAL_KEYS, configSchema2;
37624
37636
  var init_src = __esm(() => {
37625
37637
  init_zod();
37626
37638
  init_finding_codes();
@@ -37661,7 +37673,7 @@ var init_src = __esm(() => {
37661
37673
  executorCapabilityTierSchema = exports_external.preprocess((value) => {
37662
37674
  if (value === undefined || value === null)
37663
37675
  return;
37664
- return normalizeExecutorTier(value);
37676
+ return typeof value === "string" ? normalizeExecutorTier(value) : value;
37665
37677
  }, exports_external.enum(EXECUTOR_CAPABILITY_TIERS).optional());
37666
37678
  AGENT_ROLE_NAMES = ["scribe", "coder", "reviewer", "planner"];
37667
37679
  DEFAULT_AGENT_ROLES = new Map([
@@ -37858,6 +37870,7 @@ var init_src = __esm(() => {
37858
37870
  tasks: tasksConfigSchema.optional(),
37859
37871
  features: featuresConfigSchema.optional()
37860
37872
  });
37873
+ PROJECT_SHAPED_GLOBAL_KEYS = ["name", "bootstrap", "rules", "redaction", "tasks", "features"];
37861
37874
  configSchema2 = exports_external.object({
37862
37875
  database: exports_external.object({
37863
37876
  url: exports_external.string().default(DEFAULT_DATABASE_URL)
@@ -37878,7 +37891,7 @@ var init_src = __esm(() => {
37878
37891
  });
37879
37892
  });
37880
37893
 
37881
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/config.js
37894
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/config.js
37882
37895
  function parseYamlObject(text3) {
37883
37896
  let parsed;
37884
37897
  try {
@@ -38005,7 +38018,7 @@ var init_config2 = __esm(() => {
38005
38018
  };
38006
38019
  });
38007
38020
 
38008
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
38021
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
38009
38022
  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";
38010
38023
  import { dirname as dirname2, resolve as resolvePath3 } from "path";
38011
38024
  function createNodeFileSystem3(root, paths) {
@@ -38092,7 +38105,7 @@ function findProjectRoot3(startDir) {
38092
38105
  }
38093
38106
  var init_file_system_node2 = () => {};
38094
38107
 
38095
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/db-errors.js
38108
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/db-errors.js
38096
38109
  var D1NotConfiguredError2, DbModuleNotInstalledError3;
38097
38110
  var init_db_errors2 = __esm(() => {
38098
38111
  D1NotConfiguredError2 = class D1NotConfiguredError2 extends Error {
@@ -38109,7 +38122,7 @@ var init_db_errors2 = __esm(() => {
38109
38122
  };
38110
38123
  });
38111
38124
 
38112
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/file-system-cf.js
38125
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/file-system-cf.js
38113
38126
  function createCfFileSystem2() {
38114
38127
  return {
38115
38128
  getProjectRoot: () => "/bundle",
@@ -38148,7 +38161,7 @@ function createCfFileSystem2() {
38148
38161
  }
38149
38162
  var UNSUPPORTED = "FileSystem is not available on Cloudflare Workers. Use D1, KV, or R2 for persistent storage.";
38150
38163
 
38151
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/runtime-cf.js
38164
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/runtime-cf.js
38152
38165
  var exports_runtime_cf = {};
38153
38166
  __export(exports_runtime_cf, {
38154
38167
  cloudflareWorkersFactory: () => cloudflareWorkersFactory2
@@ -38186,7 +38199,7 @@ var init_runtime_cf = __esm(() => {
38186
38199
  };
38187
38200
  });
38188
38201
 
38189
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/process-executor.js
38202
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/process-executor.js
38190
38203
  import { isatty as isatty2 } from "tty";
38191
38204
  function processEventSeverity2(reason, exitCode) {
38192
38205
  if (reason === "error")
@@ -38597,7 +38610,7 @@ var init_process_executor2 = __esm(() => {
38597
38610
  ProcessExecutor2 = NodeProcessExecutor3;
38598
38611
  });
38599
38612
 
38600
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/runtime-node-bun.js
38613
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/runtime-node-bun.js
38601
38614
  var exports_runtime_node_bun = {};
38602
38615
  __export(exports_runtime_node_bun, {
38603
38616
  nodeBunFactory: () => nodeBunFactory3,
@@ -38665,7 +38678,7 @@ var init_runtime_node_bun2 = __esm(() => {
38665
38678
  };
38666
38679
  });
38667
38680
 
38668
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/platform.js
38681
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/platform.js
38669
38682
  function isCloudflareWorkerRuntime2() {
38670
38683
  return globalThis.navigator?.userAgent?.startsWith("Cloudflare-Workers") ?? false;
38671
38684
  }
@@ -38695,7 +38708,7 @@ function _resetRuntimeFactory2() {
38695
38708
  }
38696
38709
  var _factory, _runtimeName;
38697
38710
 
38698
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/context.js
38711
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/context.js
38699
38712
  class RuntimeContext2 {
38700
38713
  scope;
38701
38714
  runtimeName;
@@ -38785,7 +38798,7 @@ var init_context2 = __esm(() => {
38785
38798
  init_runtime_node_bun2();
38786
38799
  });
38787
38800
 
38788
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/path.js
38801
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/path.js
38789
38802
  function normalizeSeparators2(path7) {
38790
38803
  return path7.replaceAll("\\", "/");
38791
38804
  }
@@ -38908,7 +38921,7 @@ var init_path2 = __esm(() => {
38908
38921
  SEP2 = globalThis.process?.platform === "win32" ? "\\" : "/";
38909
38922
  });
38910
38923
 
38911
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/fs.js
38924
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/fs.js
38912
38925
  async function ensureDirForFile2(path7, fs2 = createNodeFileSystem3()) {
38913
38926
  await fs2.ensureDir(dirnamePath(path7));
38914
38927
  }
@@ -38976,7 +38989,7 @@ var init_fs = __esm(() => {
38976
38989
  init_path2();
38977
38990
  });
38978
38991
 
38979
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/process-registry.js
38992
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/process-registry.js
38980
38993
  function allocateId() {
38981
38994
  nextIdSeq += 1;
38982
38995
  return `pe_${Date.now().toString(36)}_${nextIdSeq.toString(36)}`;
@@ -39100,7 +39113,7 @@ function createInMemoryProcessRegistry2(options) {
39100
39113
  }
39101
39114
  var nextIdSeq = 0;
39102
39115
 
39103
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/runtime-paths.js
39116
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/runtime-paths.js
39104
39117
  function ambientRuntimePaths2() {
39105
39118
  const cwd = getProcessCwd2();
39106
39119
  return { cwd, home: getHomeDir() ?? cwd };
@@ -39110,7 +39123,7 @@ var init_runtime_paths = __esm(() => {
39110
39123
  init_path2();
39111
39124
  });
39112
39125
 
39113
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/schema-validation.js
39126
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/schema-validation.js
39114
39127
  async function loadStructuredConfig(path7, options = {}) {
39115
39128
  const content = await (options.fileSystem ?? createNodeFileSystem3()).readFile(path7);
39116
39129
  return await parseStructuredConfig(content, path7, options);
@@ -39393,10 +39406,10 @@ var init_schema_validation2 = __esm(() => {
39393
39406
  defaultResolve = typeof Bun !== "undefined" ? (specifier, from) => Bun.resolveSync(specifier, from) : undefined;
39394
39407
  });
39395
39408
 
39396
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/types.js
39409
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/types.js
39397
39410
  var init_types2 = () => {};
39398
39411
 
39399
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/index.js
39412
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/index.js
39400
39413
  var exports_dist2 = {};
39401
39414
  __export(exports_dist2, {
39402
39415
  writeJsonFile: () => writeJsonFile2,
@@ -39520,13 +39533,24 @@ function walk(dir, relPrefix, filter = /\.(ya?ml|json)$/i) {
39520
39533
  }
39521
39534
  return acc;
39522
39535
  }
39536
+ function isDroppedFromProjectSeed(rel) {
39537
+ if (rel === BUNDLED_GLOBAL_CONFIG)
39538
+ return true;
39539
+ if (rel.startsWith("templates/"))
39540
+ return true;
39541
+ if (rel.startsWith("workflows/"))
39542
+ return true;
39543
+ if (rel.startsWith("plugins/"))
39544
+ return true;
39545
+ return !rel.includes("/") && rel.endsWith(".json");
39546
+ }
39523
39547
  function listBundledProjectSeedFiles() {
39524
39548
  const root = bundledConfigRoot();
39525
39549
  if (root === null)
39526
39550
  return [];
39527
- return walk(root, "", PROJECT_SEED_FILTER).filter((rel) => rel !== BUNDLED_CONFIG_EXAMPLE).sort();
39551
+ return walk(root, "", PROJECT_SEED_FILTER).filter((rel) => !isDroppedFromProjectSeed(rel)).sort();
39528
39552
  }
39529
- var BUNDLED_CONFIG_DIRS, cachedRoot, PROJECT_SEED_FILTER, BUNDLED_CONFIG_EXAMPLE = "config.example.yaml";
39553
+ var BUNDLED_CONFIG_DIRS, cachedRoot, PROJECT_SEED_FILTER, BUNDLED_GLOBAL_CONFIG = "config.global.yaml";
39530
39554
  var init_bundled_config = __esm(() => {
39531
39555
  BUNDLED_CONFIG_DIRS = ["config", "spur-cli/config"];
39532
39556
  PROJECT_SEED_FILTER = /\.(ya?ml|json|md|gitkeep)$/i;
@@ -39572,15 +39596,19 @@ function resolveSchemaSpecifier(specifier, manifestSpecifier) {
39572
39596
  return specifier;
39573
39597
  }
39574
39598
  }
39575
- function resolveConfigFile(cwd) {
39599
+ function resolveConfigLayers(cwd) {
39600
+ const layers = {};
39576
39601
  const projectConfig = join3(cwd ?? process.cwd(), SPUR_CONFIG_DIR, SPUR_CONFIG_FILE);
39577
39602
  if (existsSync4(projectConfig))
39578
- return projectConfig;
39579
- if (process.env.SPUR_SKIP_GLOBAL_CONFIG === "true")
39580
- return;
39581
- if (existsSync4(GLOBAL_CONFIG_FILE))
39582
- return GLOBAL_CONFIG_FILE;
39583
- return;
39603
+ layers.project = projectConfig;
39604
+ if (process.env.SPUR_SKIP_GLOBAL_CONFIG !== "true" && existsSync4(GLOBAL_CONFIG_FILE)) {
39605
+ layers.global = GLOBAL_CONFIG_FILE;
39606
+ }
39607
+ return layers;
39608
+ }
39609
+ function resolveConfigFile(cwd) {
39610
+ const { global: global3, project } = resolveConfigLayers(cwd);
39611
+ return project ?? global3;
39584
39612
  }
39585
39613
  function makeEmbeddedReader(embeddedSchemas) {
39586
39614
  return async function readEmbeddedOrDisk(path8) {
@@ -39596,17 +39624,22 @@ function makeEmbeddedReader(embeddedSchemas) {
39596
39624
  };
39597
39625
  }
39598
39626
  async function loadSpurConfig(cwd = process.cwd(), opts) {
39599
- const configPath = resolveConfigFile(cwd);
39600
- if (configPath === undefined) {
39627
+ const layers = resolveConfigLayers(cwd);
39628
+ if (layers.global === undefined && layers.project === undefined) {
39601
39629
  return spurConfigSchema.parse({});
39602
39630
  }
39603
39631
  const validateJsonSchema2 = opts?.validateJsonSchema ?? true;
39604
- const mtimeMs = statSync5(configPath).mtimeMs;
39605
- const key = `${cacheKey(configPath, opts, validateJsonSchema2)}\x00${mtimeMs}`;
39632
+ const mtimeOf = (path8) => path8 !== undefined ? String(statSync5(path8).mtimeMs) : "-";
39633
+ const key = [
39634
+ cacheKey(layers.project ?? layers.global ?? "", opts, validateJsonSchema2),
39635
+ layers.global ?? "-",
39636
+ mtimeOf(layers.project),
39637
+ mtimeOf(layers.global)
39638
+ ].join("\x00");
39606
39639
  const cached2 = spurConfigCache.get(key);
39607
39640
  if (cached2 !== undefined)
39608
39641
  return cached2;
39609
- const promise2 = loadSpurConfigFile(configPath, opts, validateJsonSchema2);
39642
+ const promise2 = loadMergedConfig(layers, opts, validateJsonSchema2);
39610
39643
  spurConfigCache.set(key, promise2);
39611
39644
  promise2.catch(() => spurConfigCache.delete(key));
39612
39645
  return promise2;
@@ -39632,30 +39665,230 @@ function expandTeamTildes(config4) {
39632
39665
  }
39633
39666
  return { ...config4, agent: { ...config4.agent, team: expanded } };
39634
39667
  }
39635
- async function loadSpurConfigFile(configPath, opts, validateJsonSchema2) {
39636
- let raw;
39637
- if (validateJsonSchema2) {
39638
- const embeddedSchemas = opts?.embeddedSchemas;
39639
- const manifestSpecifier = opts?.schemaManifestSpecifier ?? "@gobing-ai/spur/package.json";
39640
- const resolveFn = (specifier) => {
39641
- if (embeddedSchemas !== undefined && specifier === manifestSpecifier) {
39642
- return `${EMBEDDED_PREFIX}/package.json`;
39668
+ function schemaValidationContext(opts) {
39669
+ const embeddedSchemas = opts?.embeddedSchemas;
39670
+ const manifestSpecifier = opts?.schemaManifestSpecifier ?? "@gobing-ai/spur/package.json";
39671
+ const resolve = (specifier) => {
39672
+ if (embeddedSchemas !== undefined && specifier === manifestSpecifier) {
39673
+ return `${EMBEDDED_PREFIX}/package.json`;
39674
+ }
39675
+ return resolveSchemaSpecifier(specifier, manifestSpecifier);
39676
+ };
39677
+ const fileSystem = embeddedSchemas ? { readFile: makeEmbeddedReader(embeddedSchemas) } : undefined;
39678
+ return { resolve, ...fileSystem !== undefined ? { fileSystem } : {} };
39679
+ }
39680
+ async function readRawYamlLayer(configPath, kind) {
39681
+ const nodeFs = createNodeFileSystem3();
39682
+ let text3;
39683
+ try {
39684
+ text3 = await nodeFs.readFile(nodeFs.resolve(configPath));
39685
+ } catch (error51) {
39686
+ throw new Error(`Failed to read ${kind} config ${configPath}: ${error51.message}`);
39687
+ }
39688
+ try {
39689
+ return $parse(text3) ?? {};
39690
+ } catch (error51) {
39691
+ throw new Error(`Failed to parse ${kind} config ${configPath}: ${error51.message}`);
39692
+ }
39693
+ }
39694
+ function parseConfigYaml2(text3) {
39695
+ return $parse(text3) ?? {};
39696
+ }
39697
+ function isPlainObject6(value) {
39698
+ return typeof value === "object" && value !== null && !Array.isArray(value);
39699
+ }
39700
+ function memberIdentityOf(item) {
39701
+ if (typeof item === "string")
39702
+ return item;
39703
+ if (isPlainObject6(item)) {
39704
+ if (typeof item.id === "string")
39705
+ return item.id;
39706
+ if (typeof item.executor === "string")
39707
+ return item.executor;
39708
+ }
39709
+ return;
39710
+ }
39711
+ function executorNameOf(item) {
39712
+ return isPlainObject6(item) && typeof item.name === "string" ? item.name : undefined;
39713
+ }
39714
+ function isConcatPath(segments) {
39715
+ return segments.length === 2 && segments[0] === "rules" && segments[1] === "paths" || segments.length === 2 && segments[0] === "workflows" && segments[1] === "paths";
39716
+ }
39717
+ function byKeyIdentityFor(segments) {
39718
+ if (segments.length === 2 && segments[0] === "agent" && segments[1] === "executors") {
39719
+ return executorNameOf;
39720
+ }
39721
+ if (segments.length === 4 && segments[0] === "agent" && segments[1] === "team" && segments[3] === "members") {
39722
+ return memberIdentityOf;
39723
+ }
39724
+ return;
39725
+ }
39726
+ function concatUnique(globalItems, projectItems) {
39727
+ const out = [...globalItems];
39728
+ for (const item of projectItems) {
39729
+ if (!out.includes(item))
39730
+ out.push(item);
39731
+ }
39732
+ return out;
39733
+ }
39734
+ function mergeByKeyIdentity(globalItems, projectItems, identityOf, segments) {
39735
+ const merged = [];
39736
+ const indexByIdentity = new Map;
39737
+ for (const item of globalItems) {
39738
+ const identity4 = identityOf(item);
39739
+ if (identity4 !== undefined && !indexByIdentity.has(identity4))
39740
+ indexByIdentity.set(identity4, merged.length);
39741
+ merged.push(item);
39742
+ }
39743
+ const matchedProjectIdentities = new Set;
39744
+ for (const item of projectItems) {
39745
+ const identity4 = identityOf(item);
39746
+ const existing = identity4 === undefined || matchedProjectIdentities.has(identity4) ? undefined : indexByIdentity.get(identity4);
39747
+ if (existing === undefined) {
39748
+ merged.push(item);
39749
+ continue;
39750
+ }
39751
+ if (identity4 !== undefined)
39752
+ matchedProjectIdentities.add(identity4);
39753
+ const base2 = merged[existing];
39754
+ merged[existing] = isPlainObject6(base2) && isPlainObject6(item) ? mergeDeep(base2, item, [...segments, existing]) : item;
39755
+ }
39756
+ return merged;
39757
+ }
39758
+ function mergeDeep(globalValue, projectValue, segments) {
39759
+ if (isPlainObject6(globalValue) && isPlainObject6(projectValue)) {
39760
+ const out = { ...globalValue };
39761
+ for (const [key, projectItem] of Object.entries(projectValue)) {
39762
+ out[key] = key in out ? mergeDeep(out[key], projectItem, [...segments, key]) : projectItem;
39763
+ }
39764
+ return out;
39765
+ }
39766
+ if (Array.isArray(globalValue) && Array.isArray(projectValue)) {
39767
+ if (isConcatPath(segments))
39768
+ return concatUnique(globalValue, projectValue);
39769
+ const identityOf = byKeyIdentityFor(segments);
39770
+ if (identityOf !== undefined)
39771
+ return mergeByKeyIdentity(globalValue, projectValue, identityOf, segments);
39772
+ return projectValue;
39773
+ }
39774
+ return projectValue;
39775
+ }
39776
+ function mergeSpurConfigLayers(globalRaw, projectRaw) {
39777
+ return mergeDeep(globalRaw, projectRaw, []);
39778
+ }
39779
+ function formatZodPath(path8) {
39780
+ return path8.map((segment, index2) => typeof segment === "number" ? `[${segment}]` : index2 === 0 ? segment : `.${segment}`).join("");
39781
+ }
39782
+ function parseViolationPath(path8) {
39783
+ const segments = [];
39784
+ for (const part of path8.split(".")) {
39785
+ const bracket = part.indexOf("[");
39786
+ const key = bracket === -1 ? part : part.slice(0, bracket);
39787
+ if (key !== "")
39788
+ segments.push(key);
39789
+ if (bracket !== -1) {
39790
+ for (const match of part.slice(bracket).matchAll(/\[(\d+)\]/g)) {
39791
+ segments.push(Number(match[1]));
39792
+ }
39793
+ }
39794
+ }
39795
+ return segments;
39796
+ }
39797
+ function findItemByIdentity(node, identityOf, identity4) {
39798
+ return Array.isArray(node) ? node.find((entry) => identityOf(entry) === identity4) : undefined;
39799
+ }
39800
+ function describeIssueProvenance(issuePath, merged, globalRaw, projectRaw) {
39801
+ let g = globalRaw;
39802
+ let p = projectRaw;
39803
+ let m = merged;
39804
+ let segments = [];
39805
+ let parentG = globalRaw;
39806
+ let parentP = projectRaw;
39807
+ let identityPrefix = "";
39808
+ for (const segment of issuePath) {
39809
+ parentG = g;
39810
+ parentP = p;
39811
+ segments = [...segments, segment];
39812
+ if (typeof segment === "number") {
39813
+ const mergedItem = Array.isArray(m) ? m[segment] : undefined;
39814
+ const identityOf = byKeyIdentityFor(segments.slice(0, -1));
39815
+ if (identityOf !== undefined && mergedItem !== undefined) {
39816
+ const identity4 = identityOf(mergedItem);
39817
+ if (identity4 !== undefined) {
39818
+ identityPrefix = `${segments.length === 3 ? "executor" : "member"} "${identity4}" `;
39819
+ g = findItemByIdentity(g, identityOf, identity4);
39820
+ p = findItemByIdentity(p, identityOf, identity4);
39821
+ }
39822
+ } else {
39823
+ g = Array.isArray(g) && segment < g.length ? g[segment] : undefined;
39824
+ p = Array.isArray(p) && segment < p.length ? p[segment] : undefined;
39643
39825
  }
39644
- return resolveSchemaSpecifier(specifier, manifestSpecifier);
39645
- };
39646
- const fileSystem = embeddedSchemas ? { readFile: makeEmbeddedReader(embeddedSchemas) } : undefined;
39647
- raw = await loadStructuredConfig(configPath, {
39648
- validateSchema: true,
39649
- resolve: resolveFn,
39650
- ...fileSystem !== undefined ? { fileSystem } : {}
39651
- });
39826
+ m = mergedItem;
39827
+ continue;
39828
+ }
39829
+ g = isPlainObject6(g) ? g[segment] : undefined;
39830
+ p = isPlainObject6(p) ? p[segment] : undefined;
39831
+ m = isPlainObject6(m) ? m[segment] : undefined;
39832
+ }
39833
+ let label;
39834
+ if (g !== undefined && p !== undefined) {
39835
+ label = "set in both layers (project value wins)";
39836
+ } else if (g !== undefined) {
39837
+ label = "from global layer";
39838
+ } else if (p !== undefined) {
39839
+ label = "from project layer";
39840
+ } else if (parentP !== undefined && parentG === undefined) {
39841
+ label = "from project layer (key absent there)";
39842
+ } else if (parentG !== undefined && parentP === undefined) {
39843
+ label = "from global layer (key absent there)";
39652
39844
  } else {
39653
- const nodeFs = createNodeFileSystem3();
39654
- const resolved = nodeFs.resolve(configPath);
39655
- const text3 = await nodeFs.readFile(resolved);
39656
- raw = $parse(text3) ?? {};
39845
+ label = "missing in both layers";
39846
+ }
39847
+ return `${identityPrefix}${label}`;
39848
+ }
39849
+ function parseMergedWithProvenance(merged, globalRaw, projectRaw, layers) {
39850
+ try {
39851
+ return spurConfigSchema.parse(merged);
39852
+ } catch (error51) {
39853
+ if (!(error51 instanceof ZodError))
39854
+ throw error51;
39855
+ const details = error51.issues.map((issue2) => {
39856
+ const path8 = issue2.path.filter((segment) => typeof segment !== "symbol");
39857
+ return ` ${formatZodPath(path8)}: ${issue2.message} (${describeIssueProvenance(path8, merged, globalRaw, projectRaw)})`;
39858
+ }).join(`
39859
+ `);
39860
+ throw new Error(`Spur config validation failed after merging global ${layers.global ?? "(absent)"} with project ${layers.project ?? "(absent)"}:
39861
+ ${details}`);
39862
+ }
39863
+ }
39864
+ function enrichSchemaViolationError(error51, merged, globalRaw, projectRaw, layers) {
39865
+ const violations = error51.violations;
39866
+ if (!Array.isArray(violations))
39867
+ return error51;
39868
+ const details = violations.map((violation) => {
39869
+ const v = violation;
39870
+ const path8 = typeof v.path === "string" ? v.path : "(root)";
39871
+ const message = typeof v.message === "string" ? v.message : "schema violation";
39872
+ const label = describeIssueProvenance(parseViolationPath(path8), merged, globalRaw, projectRaw);
39873
+ return ` ${path8}: ${message} (${label})`;
39874
+ }).join(`
39875
+ `);
39876
+ return new Error(`Merged Spur config failed JSON Schema validation (global ${layers.global ?? "(absent)"} + project ${layers.project ?? "(absent)"}):
39877
+ ${details}`);
39878
+ }
39879
+ async function loadMergedConfig(layers, opts, validateJsonSchema2) {
39880
+ const globalRaw = layers.global !== undefined ? await readRawYamlLayer(layers.global, "global") : {};
39881
+ const projectRaw = layers.project !== undefined ? await readRawYamlLayer(layers.project, "project") : {};
39882
+ const merged = mergeSpurConfigLayers(globalRaw, projectRaw);
39883
+ if (validateJsonSchema2) {
39884
+ const source = layers.project ?? layers.global ?? "";
39885
+ try {
39886
+ await validateDeclaredJsonSchema(merged, source, schemaValidationContext(opts));
39887
+ } catch (error51) {
39888
+ throw enrichSchemaViolationError(error51, merged, globalRaw, projectRaw, layers);
39889
+ }
39657
39890
  }
39658
- return expandTeamTildes(spurConfigSchema.parse(raw));
39891
+ return expandTeamTildes(parseMergedWithProvenance(merged, globalRaw, projectRaw, layers));
39659
39892
  }
39660
39893
  async function loadStructuredSpurConfig(configPath, opts) {
39661
39894
  const validateJsonSchema2 = opts?.validateJsonSchema ?? true;
@@ -39665,19 +39898,9 @@ async function loadStructuredSpurConfig(configPath, opts) {
39665
39898
  const text3 = await nodeFs.readFile(resolved);
39666
39899
  return $parse(text3) ?? {};
39667
39900
  }
39668
- const embeddedSchemas = opts?.embeddedSchemas;
39669
- const manifestSpecifier = opts?.schemaManifestSpecifier ?? "@gobing-ai/spur/package.json";
39670
- const resolveFn = (specifier) => {
39671
- if (embeddedSchemas !== undefined && specifier === manifestSpecifier) {
39672
- return `${EMBEDDED_PREFIX}/package.json`;
39673
- }
39674
- return resolveSchemaSpecifier(specifier, manifestSpecifier);
39675
- };
39676
- const fileSystem = embeddedSchemas ? { readFile: makeEmbeddedReader(embeddedSchemas) } : undefined;
39677
39901
  return await loadStructuredConfig(configPath, {
39678
39902
  validateSchema: true,
39679
- resolve: resolveFn,
39680
- ...fileSystem !== undefined ? { fileSystem } : {}
39903
+ ...schemaValidationContext(opts)
39681
39904
  });
39682
39905
  }
39683
39906
  function defaultFoldersConfig() {
@@ -39735,6 +39958,7 @@ var SPUR_CONFIG_DIR = ".spur", SPUR_CONFIG_FILE = "config.yaml", GLOBAL_CONFIG_F
39735
39958
  var init_loader = __esm(() => {
39736
39959
  init_dist5();
39737
39960
  init_dist2();
39961
+ init_zod();
39738
39962
  init_src();
39739
39963
  init_bundled_config();
39740
39964
  init_template_renderer();
@@ -41547,7 +41771,7 @@ var init_mod = __esm(() => {
41547
41771
  init_config3();
41548
41772
  });
41549
41773
 
41550
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/logger.js
41774
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/logger.js
41551
41775
  function toLogTapeLevel(level) {
41552
41776
  return level === "warn" ? "warning" : level;
41553
41777
  }
@@ -43100,7 +43324,7 @@ var require_src = __commonJS((exports) => {
43100
43324
  };
43101
43325
  });
43102
43326
 
43103
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/telemetry/sdk.js
43327
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/telemetry/sdk.js
43104
43328
  function getTelemetryConfig(configPartial = {}) {
43105
43329
  return {
43106
43330
  enabled: configPartial.enabled ?? CONFIG_DEFAULTS.enabled,
@@ -43136,7 +43360,7 @@ var init_sdk = __esm(() => {
43136
43360
  resolvedConfig = getTelemetryConfig();
43137
43361
  });
43138
43362
 
43139
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/telemetry/tracing.js
43363
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/telemetry/tracing.js
43140
43364
  function isSuppressed(tracer2) {
43141
43365
  return tracer2 === undefined && !getResolvedConfig().enabled;
43142
43366
  }
@@ -43176,7 +43400,7 @@ var init_tracing2 = __esm(() => {
43176
43400
  import_api2 = __toESM(require_src(), 1);
43177
43401
  });
43178
43402
 
43179
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/telemetry/metrics.js
43403
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/telemetry/metrics.js
43180
43404
  function getMeter() {
43181
43405
  return import_api3.metrics.getMeter(METER_NAME, METER_VERSION);
43182
43406
  }
@@ -43273,7 +43497,7 @@ var init_metrics = __esm(() => {
43273
43497
  instruments = {};
43274
43498
  });
43275
43499
 
43276
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/event-bus/event-bus.js
43500
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/event-bus/event-bus.js
43277
43501
  function busLogger() {
43278
43502
  if (!_busLogger)
43279
43503
  _busLogger = getLogger2("event-bus");
@@ -43526,7 +43750,7 @@ var init_event_bus = __esm(() => {
43526
43750
  init_metrics();
43527
43751
  });
43528
43752
 
43529
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/event-bus/default-observers.js
43753
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/event-bus/default-observers.js
43530
43754
  function obsLogger() {
43531
43755
  if (!_obsLogger)
43532
43756
  _obsLogger = getLogger2("event-bus.observers");
@@ -43590,7 +43814,7 @@ var init_default_observers = __esm(() => {
43590
43814
  init_event_bus();
43591
43815
  });
43592
43816
 
43593
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/event-bus/file-observer.js
43817
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/event-bus/file-observer.js
43594
43818
  function parentDir(filePath) {
43595
43819
  const idx = filePath.lastIndexOf("/");
43596
43820
  return idx <= 0 ? "." : filePath.slice(0, idx);
@@ -43688,7 +43912,7 @@ var init_file_observer = __esm(() => {
43688
43912
  init_logger3();
43689
43913
  });
43690
43914
 
43691
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/internals/drain.js
43915
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/internals/drain.js
43692
43916
  function settleWithin(promise2, deadline) {
43693
43917
  const remaining = deadline - Date.now();
43694
43918
  if (remaining <= 0)
@@ -43703,7 +43927,7 @@ function settleWithin(promise2, deadline) {
43703
43927
  return settled;
43704
43928
  }
43705
43929
 
43706
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/scheduler/node.js
43930
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/scheduler/node.js
43707
43931
  function parseInterval(cron) {
43708
43932
  const trimmed = cron.trim();
43709
43933
  const num = Number(trimmed);
@@ -43797,7 +44021,7 @@ var init_node3 = __esm(() => {
43797
44021
  init_metrics();
43798
44022
  });
43799
44023
 
43800
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/scheduler-node.js
44024
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/scheduler-node.js
43801
44025
  var exports_scheduler_node = {};
43802
44026
  __export(exports_scheduler_node, {
43803
44027
  NodeSchedulerAdapter: () => NodeSchedulerAdapter
@@ -46202,7 +46426,7 @@ var require_lodash_merge = __commonJS((exports) => {
46202
46426
  var hasOwnProperty = objectProto.hasOwnProperty;
46203
46427
  var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
46204
46428
  var nativeObjectToString = objectProto.toString;
46205
- function isPlainObject6(value) {
46429
+ function isPlainObject7(value) {
46206
46430
  if (!isObjectLike(value) || baseGetTag(value) !== objectTag) {
46207
46431
  return false;
46208
46432
  }
@@ -46213,7 +46437,7 @@ var require_lodash_merge = __commonJS((exports) => {
46213
46437
  const Ctor = hasOwnProperty.call(proto, "constructor") && proto.constructor;
46214
46438
  return typeof Ctor == "function" && Ctor instanceof Ctor && funcToString.call(Ctor) === objectCtorString;
46215
46439
  }
46216
- exports.isPlainObject = isPlainObject6;
46440
+ exports.isPlainObject = isPlainObject7;
46217
46441
  function isObjectLike(value) {
46218
46442
  return value != null && typeof value == "object";
46219
46443
  }
@@ -50483,14 +50707,32 @@ function buildMessageWhereClauses(sel, alias3) {
50483
50707
  clauses.push(`${alias3}.session_id = ?`);
50484
50708
  params.push(sel.sessionId);
50485
50709
  }
50486
- if (sel.runId != null) {
50487
- clauses.push(`${alias3}.provenance = 'spur-run'`);
50488
- clauses.push(`${alias3}.run_id = ?`);
50710
+ if (sel.runId != null && sel.taskWbs != null) {
50711
+ clauses.push(`EXISTS (
50712
+ SELECT 1 FROM history_run_session hrs_scope
50713
+ JOIN task_run_links trl_scope ON trl_scope.run_id = hrs_scope.run_id
50714
+ WHERE hrs_scope.run_id = ? AND trl_scope.wbs = ?
50715
+ AND hrs_scope.session_id IS NOT NULL
50716
+ AND hrs_scope.source = ${alias3}.source
50717
+ AND hrs_scope.session_id = ${alias3}.session_id
50718
+ )`);
50719
+ params.push(sel.runId, sel.taskWbs);
50720
+ } else if (sel.runId != null) {
50721
+ clauses.push(`EXISTS (
50722
+ SELECT 1 FROM history_run_session hrs_scope
50723
+ WHERE hrs_scope.run_id = ? AND hrs_scope.session_id IS NOT NULL
50724
+ AND hrs_scope.source = ${alias3}.source
50725
+ AND hrs_scope.session_id = ${alias3}.session_id
50726
+ )`);
50489
50727
  params.push(sel.runId);
50490
- }
50491
- if (sel.taskWbs != null) {
50492
- clauses.push(`${alias3}.provenance = 'spur-run'`);
50493
- clauses.push(`${alias3}.task_wbs = ?`);
50728
+ } else if (sel.taskWbs != null) {
50729
+ clauses.push(`EXISTS (
50730
+ SELECT 1 FROM task_run_links trl_scope
50731
+ JOIN history_run_session hrs_scope ON hrs_scope.run_id = trl_scope.run_id
50732
+ WHERE trl_scope.wbs = ? AND hrs_scope.session_id IS NOT NULL
50733
+ AND hrs_scope.source = ${alias3}.source
50734
+ AND hrs_scope.session_id = ${alias3}.session_id
50735
+ )`);
50494
50736
  params.push(sel.taskWbs);
50495
50737
  }
50496
50738
  return { clauses, params };
@@ -50820,72 +51062,238 @@ async function bucketedTokenSeries(db2, sel, bucket, dim2, opts) {
50820
51062
  GROUP BY bucketStart, key
50821
51063
  ORDER BY bucketStart ASC`, ...params, ...wm.params);
50822
51064
  }
50823
- async function sessionTimeline(db2, sessionId, limit = 5000) {
51065
+ function formatToolPayload(toolName, status, argsRaw, argsDigest, errorText) {
51066
+ if (errorText != null && errorText.trim().length > 0)
51067
+ return errorText;
51068
+ if (argsRaw != null && argsRaw.trim().length > 0)
51069
+ return argsRaw;
51070
+ if (argsDigest != null && argsDigest.trim().length > 0) {
51071
+ return `tool: ${toolName ?? ""}
51072
+ status: ${status ?? "ok"}
51073
+ args_digest: ${argsDigest} (raw payload omitted at import)`;
51074
+ }
51075
+ return null;
51076
+ }
51077
+ function finalizeSessionDurations(events) {
51078
+ events.sort((a2, b) => {
51079
+ const aTs = a2.ts ? Date.parse(a2.ts) : Infinity;
51080
+ const bTs = b.ts ? Date.parse(b.ts) : Infinity;
51081
+ if (aTs !== bTs)
51082
+ return (Number.isNaN(aTs) ? Infinity : aTs) - (Number.isNaN(bTs) ? Infinity : bTs);
51083
+ if (a2.messageRowId !== b.messageRowId)
51084
+ return a2.messageRowId - b.messageRowId;
51085
+ if (a2.eventType !== b.eventType)
51086
+ return a2.eventType === "message" ? -1 : 1;
51087
+ return a2.toolSeq - b.toolSeq;
51088
+ });
51089
+ for (let i2 = 0;i2 < events.length; i2++) {
51090
+ const ev = events[i2];
51091
+ if (!ev)
51092
+ continue;
51093
+ if (ev.durationMs != null && Number.isFinite(ev.durationMs) && ev.durationMs > 0) {
51094
+ ev.durationSource = "measured";
51095
+ } else {
51096
+ if (i2 + 1 < events.length) {
51097
+ const nextEv = events[i2 + 1];
51098
+ const currTs = ev.ts ? Date.parse(ev.ts) : Number.NaN;
51099
+ const nextTs = nextEv?.ts ? Date.parse(nextEv.ts) : Number.NaN;
51100
+ const delta = !Number.isNaN(currTs) && !Number.isNaN(nextTs) ? nextTs - currTs : Number.NaN;
51101
+ if (delta > 0 && delta <= 600000) {
51102
+ ev.durationMs = delta;
51103
+ ev.durationSource = "inferred";
51104
+ } else {
51105
+ ev.durationMs = null;
51106
+ ev.durationSource = "unmeasured";
51107
+ }
51108
+ } else {
51109
+ ev.durationMs = null;
51110
+ ev.durationSource = "unmeasured";
51111
+ }
51112
+ }
51113
+ }
51114
+ }
51115
+ async function queryTimelineEvents(db2, whereClause, params, subWhereClause, subParams, limit, correlationMap) {
51116
+ const fetchLimit = limit + 1;
51117
+ const mainCondition = whereClause.startsWith("WHERE ") ? whereClause.slice(6) : whereClause;
51118
+ const subCondition = subWhereClause.startsWith("WHERE ") ? subWhereClause.slice(6) : subWhereClause;
51119
+ const dedupSubWhere = subCondition ? `WHERE ${subCondition} AND ` : "WHERE ";
51120
+ const fullWhere = mainCondition ? `WHERE ${mainCondition} AND (m.request_id IS NULL OR m.rowid IN (SELECT MIN(dm.rowid) FROM history_message dm ${dedupSubWhere}dm.request_id IS NOT NULL GROUP BY dm.request_id))` : `WHERE (m.request_id IS NULL OR m.rowid IN (SELECT MIN(dm.rowid) FROM history_message dm ${dedupSubWhere}dm.request_id IS NOT NULL GROUP BY dm.request_id))`;
50824
51121
  const rows = await db2.queryAll(`SELECT m.record_hash AS messageHash, m.seq AS messageSeq,
50825
51122
  COALESCE(m.turn_index, m.seq) AS turnIndex,
50826
- m.ts AS messageTs, m.role AS messageRole, m.source, m.model,
51123
+ m.ts AS messageTs, m.role AS messageRole, COALESCE(m.record_type, m.role) AS recordType,
51124
+ m.source, m.session_id AS sessionId, m.model,
50827
51125
  m.duration_ms AS messageDurationMs, m.input_tokens AS inputTokens,
50828
51126
  m.cache_read_tokens AS cacheReadTokens, m.output_tokens AS outputTokens,
50829
51127
  m.content_text AS messagePayload,
50830
51128
  (SELECT COUNT(*) FROM history_tool_call links WHERE links.message_hash = m.record_hash) AS links,
50831
51129
  tc.tool_name AS toolName, COALESCE(tc.started_at, m.ts) AS toolTs,
50832
51130
  tc.duration_ms AS toolDurationMs, tc.status AS toolStatus,
50833
- COALESCE(tc.error_text, tc.args_raw, tc.args_digest) AS toolPayload
51131
+ tc.args_raw AS toolArgsRaw, tc.args_digest AS toolArgsDigest, tc.error_text AS toolErrorText,
51132
+ COALESCE(tc.seq, 0) AS toolSeq, m.rowid AS messageRowId
50834
51133
  FROM history_message m
50835
51134
  LEFT JOIN history_tool_call tc ON tc.message_hash = m.record_hash
50836
- WHERE m.session_id = ? AND (
50837
- m.request_id IS NULL OR m.rowid IN (
50838
- SELECT MIN(dm.rowid) FROM history_message dm
50839
- WHERE dm.session_id = ? AND dm.request_id IS NOT NULL
50840
- GROUP BY dm.request_id
50841
- )
50842
- )
50843
- ORDER BY m.seq, m.rowid, COALESCE(tc.seq, 0)
50844
- LIMIT ?`, sessionId, sessionId, limit);
50845
- const events = [];
51135
+ ${fullWhere}
51136
+ ORDER BY COALESCE(m.ts, '0000-00-00') DESC, m.rowid DESC, COALESCE(tc.seq, 0) DESC
51137
+ LIMIT ?`, ...params, ...subParams, fetchLimit);
51138
+ const rawEvents = [];
50846
51139
  let previousMessage = "";
50847
51140
  for (const row of rows) {
50848
51141
  if (row.messageHash !== previousMessage) {
50849
- events.push({
51142
+ rawEvents.push({
51143
+ sessionId: row.sessionId,
50850
51144
  messageSeq: row.messageSeq,
50851
51145
  turnIndex: row.turnIndex,
50852
51146
  eventType: "message",
51147
+ recordType: row.recordType,
50853
51148
  ts: row.messageTs,
50854
51149
  role: row.messageRole,
50855
51150
  source: row.source,
50856
51151
  model: row.model,
50857
51152
  toolName: null,
50858
51153
  durationMs: row.messageDurationMs,
51154
+ durationSource: "unmeasured",
50859
51155
  inputTokens: row.links > 0 ? 0 : row.inputTokens,
50860
51156
  cacheReadTokens: row.links > 0 ? 0 : row.cacheReadTokens,
50861
51157
  outputTokens: row.links > 0 ? 0 : row.outputTokens,
50862
51158
  exitCode: null,
50863
- payload: row.messagePayload
51159
+ payload: row.messagePayload,
51160
+ messageRowId: row.messageRowId,
51161
+ toolSeq: 0
50864
51162
  });
50865
51163
  previousMessage = row.messageHash;
50866
51164
  }
50867
- if (row.toolName !== null && events.length < limit) {
50868
- events.push({
51165
+ if (row.toolName !== null) {
51166
+ rawEvents.push({
51167
+ sessionId: row.sessionId,
50869
51168
  messageSeq: row.messageSeq,
50870
51169
  turnIndex: row.turnIndex,
50871
51170
  eventType: "tool",
51171
+ recordType: row.recordType,
50872
51172
  ts: row.toolTs,
50873
51173
  role: "tool",
50874
51174
  source: row.source,
50875
51175
  model: row.model,
50876
51176
  toolName: row.toolName,
50877
51177
  durationMs: row.toolDurationMs,
50878
- inputTokens: (row.inputTokens ?? 0) / row.links,
50879
- cacheReadTokens: (row.cacheReadTokens ?? 0) / row.links,
50880
- outputTokens: (row.outputTokens ?? 0) / row.links,
51178
+ durationSource: "unmeasured",
51179
+ inputTokens: row.links > 0 ? (row.inputTokens ?? 0) / row.links : row.inputTokens,
51180
+ cacheReadTokens: row.links > 0 ? (row.cacheReadTokens ?? 0) / row.links : row.cacheReadTokens,
51181
+ outputTokens: row.links > 0 ? (row.outputTokens ?? 0) / row.links : row.outputTokens,
50881
51182
  exitCode: row.toolStatus === "error" ? 1 : 0,
50882
- payload: row.toolPayload
51183
+ payload: formatToolPayload(row.toolName, row.toolStatus, row.toolArgsRaw, row.toolArgsDigest, row.toolErrorText),
51184
+ messageRowId: row.messageRowId,
51185
+ toolSeq: row.toolSeq ?? 0
50883
51186
  });
50884
51187
  }
50885
- if (events.length >= limit)
50886
- break;
50887
51188
  }
50888
- return events.map((row, index2) => ({ ...row, seq: index2 + 1 }));
51189
+ const truncated = rows.length > limit || rawEvents.length > limit;
51190
+ rawEvents.sort((a2, b) => {
51191
+ const aTs = a2.ts ? Date.parse(a2.ts) : Infinity;
51192
+ const bTs = b.ts ? Date.parse(b.ts) : Infinity;
51193
+ if (aTs !== bTs)
51194
+ return (Number.isNaN(aTs) ? Infinity : aTs) - (Number.isNaN(bTs) ? Infinity : bTs);
51195
+ if (a2.source !== b.source)
51196
+ return a2.source.localeCompare(b.source);
51197
+ if (a2.sessionId !== b.sessionId)
51198
+ return a2.sessionId.localeCompare(b.sessionId);
51199
+ if (a2.messageRowId !== b.messageRowId)
51200
+ return a2.messageRowId - b.messageRowId;
51201
+ if (a2.eventType !== b.eventType)
51202
+ return a2.eventType === "message" ? -1 : 1;
51203
+ return a2.toolSeq - b.toolSeq;
51204
+ });
51205
+ const boundedEvents = rawEvents.length > limit ? rawEvents.slice(rawEvents.length - limit) : rawEvents;
51206
+ const sessionMap = new Map;
51207
+ for (const ev of boundedEvents) {
51208
+ const sessionKey = `${ev.source}:::${ev.sessionId}`;
51209
+ let list = sessionMap.get(sessionKey);
51210
+ if (list === undefined) {
51211
+ list = [];
51212
+ sessionMap.set(sessionKey, list);
51213
+ }
51214
+ list.push(ev);
51215
+ if (correlationMap !== undefined) {
51216
+ ev.correlationExactness = correlationMap.get(sessionKey) ?? null;
51217
+ } else {
51218
+ ev.correlationExactness = null;
51219
+ }
51220
+ }
51221
+ for (const sessionEvents of sessionMap.values()) {
51222
+ finalizeSessionDurations(sessionEvents);
51223
+ }
51224
+ boundedEvents.sort((a2, b) => {
51225
+ const aTs = a2.ts ? Date.parse(a2.ts) : Infinity;
51226
+ const bTs = b.ts ? Date.parse(b.ts) : Infinity;
51227
+ if (aTs !== bTs)
51228
+ return (Number.isNaN(aTs) ? Infinity : aTs) - (Number.isNaN(bTs) ? Infinity : bTs);
51229
+ if (a2.source !== b.source)
51230
+ return a2.source.localeCompare(b.source);
51231
+ if (a2.sessionId !== b.sessionId)
51232
+ return a2.sessionId.localeCompare(b.sessionId);
51233
+ if (a2.messageRowId !== b.messageRowId)
51234
+ return a2.messageRowId - b.messageRowId;
51235
+ if (a2.eventType !== b.eventType)
51236
+ return a2.eventType === "message" ? -1 : 1;
51237
+ return a2.toolSeq - b.toolSeq;
51238
+ });
51239
+ return {
51240
+ truncated,
51241
+ events: boundedEvents.map((row, index2) => ({
51242
+ seq: index2 + 1,
51243
+ sessionId: row.sessionId,
51244
+ messageSeq: row.messageSeq,
51245
+ turnIndex: row.turnIndex,
51246
+ eventType: row.eventType,
51247
+ recordType: row.recordType,
51248
+ ts: row.ts,
51249
+ role: row.role,
51250
+ source: row.source,
51251
+ model: row.model,
51252
+ toolName: row.toolName,
51253
+ durationMs: row.durationMs,
51254
+ durationSource: row.durationSource,
51255
+ inputTokens: row.inputTokens,
51256
+ cacheReadTokens: row.cacheReadTokens,
51257
+ outputTokens: row.outputTokens,
51258
+ exitCode: row.exitCode,
51259
+ payload: row.payload,
51260
+ correlationExactness: row.correlationExactness
51261
+ }))
51262
+ };
51263
+ }
51264
+ async function sessionTimeline(db2, source, sessionId, limit = 5000) {
51265
+ return queryTimelineEvents(db2, "WHERE m.source = ? AND m.session_id = ?", [source, sessionId], "WHERE dm.source = ? AND dm.session_id = ?", [source, sessionId], limit);
51266
+ }
51267
+ async function consolidatedTimeline(db2, sel, limit = 5000) {
51268
+ const built = buildMessageWhere(sel, "m");
51269
+ const subBuilt = buildMessageWhere(sel, "dm");
51270
+ let correlationMap;
51271
+ if (sel.runId != null || sel.taskWbs != null) {
51272
+ correlationMap = new Map;
51273
+ const correlationClauses = ["hrs.session_id IS NOT NULL"];
51274
+ const correlationParams = [];
51275
+ if (sel.runId != null) {
51276
+ correlationClauses.push("hrs.run_id = ?");
51277
+ correlationParams.push(sel.runId);
51278
+ }
51279
+ if (sel.taskWbs != null) {
51280
+ correlationClauses.push("EXISTS (SELECT 1 FROM task_run_links trl WHERE trl.run_id = hrs.run_id AND trl.wbs = ?)");
51281
+ correlationParams.push(sel.taskWbs);
51282
+ }
51283
+ const rows = await db2.queryAll(`SELECT hrs.source, hrs.session_id, hrs.exactness
51284
+ FROM history_run_session hrs
51285
+ WHERE ${correlationClauses.join(" AND ")}`, ...correlationParams);
51286
+ for (const r of rows) {
51287
+ const key = `${r.source}:::${r.session_id}`;
51288
+ const existing = correlationMap.get(key);
51289
+ if (r.exactness === "exact") {
51290
+ correlationMap.set(key, "exact");
51291
+ } else if (r.exactness === "estimated" && existing !== "exact") {
51292
+ correlationMap.set(key, "estimated");
51293
+ }
51294
+ }
51295
+ }
51296
+ return queryTimelineEvents(db2, built.where, built.params, subBuilt.where, subBuilt.params, limit, correlationMap);
50889
51297
  }
50890
51298
  async function dailyTokenMatrix(db2, days = 90) {
50891
51299
  return db2.queryAll(`WITH messages AS (
@@ -50966,7 +51374,7 @@ async function historyKpiTrend(db2, sel, opts) {
50966
51374
  ORDER BY day ASC`, ...params, ...wm.params);
50967
51375
  }
50968
51376
  var MESSAGE_DEDUP = `(m.rowid IN (
50969
- SELECT MIN(rowid) FROM history_message WHERE request_id IS NOT NULL GROUP BY request_id
51377
+ SELECT MAX(rowid) FROM history_message WHERE request_id IS NOT NULL GROUP BY request_id
50970
51378
  ) OR m.request_id IS NULL)`, CACHE_WASTE_MIN_INPUT_TOKENS = 1e5, CACHE_WASTE_MAX_REUSE_FRACTION = 0.1, BUCKET_SECONDS, HISTORY_SKILL_NAME_SQL = `CASE
50971
51379
  WHEN LOWER(tc.tool_name) IN ('skill', 'use_skill', 'invoke_skill') AND json_valid(tc.args_raw)
50972
51380
  THEN COALESCE(
@@ -52473,6 +52881,35 @@ class RunSessionDao {
52473
52881
  throw error51;
52474
52882
  }
52475
52883
  }
52884
+ async listRunSources() {
52885
+ try {
52886
+ return await this.db.queryAll(`SELECT DISTINCT run_id, source FROM history_run_session ORDER BY run_id, source`);
52887
+ } catch (error51) {
52888
+ if (error51 instanceof Error && error51.message.includes("no such table: history_run_session"))
52889
+ return [];
52890
+ throw error51;
52891
+ }
52892
+ }
52893
+ async observeImportedSessions(input) {
52894
+ try {
52895
+ await this.db.run(`INSERT INTO history_run_session (run_id, source, session_id, exactness, mechanism, resolved_at)
52896
+ SELECT DISTINCT ?, ?, h.session_id, 'exact', 'observed', ?
52897
+ FROM history_message h
52898
+ WHERE h.source = ? AND h.session_id IS NOT NULL
52899
+ AND substr(h.source_file, 1, length(?)) = ?
52900
+ AND NOT EXISTS (
52901
+ SELECT 1 FROM history_run_session m
52902
+ WHERE m.run_id = ? AND m.source = ? AND m.session_id = h.session_id
52903
+ AND m.exactness = 'exact'
52904
+ )`, input.runId, input.source, input.resolvedAt, input.source, input.sourceFilePrefix, input.sourceFilePrefix, input.runId, input.source);
52905
+ } catch (error51) {
52906
+ if (error51 instanceof Error && error51.message.includes("no such table: history_run_session"))
52907
+ return;
52908
+ if (error51 instanceof Error && error51.message.includes("no such table: history_message"))
52909
+ return;
52910
+ throw error51;
52911
+ }
52912
+ }
52476
52913
  async insertInferred(input) {
52477
52914
  const blocked = await this.db.queryFirst(`SELECT EXISTS(
52478
52915
  SELECT 1 FROM history_run_session
@@ -53759,7 +54196,7 @@ class ActionRunDao {
53759
54196
  }
53760
54197
  }
53761
54198
 
53762
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/schema/drizzle-internals.js
54199
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/schema/drizzle-internals.js
53763
54200
  function sqlExpressionToText(value) {
53764
54201
  if (typeof value !== "object" || value === null || !("queryChunks" in value)) {
53765
54202
  return;
@@ -53782,7 +54219,7 @@ function getDrizzleTableName(table3) {
53782
54219
  return String(table3[nameSym]);
53783
54220
  }
53784
54221
 
53785
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/schema/ddl.js
54222
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/schema/ddl.js
53786
54223
  function quoteIdent(name) {
53787
54224
  return `"${name.replace(/"/g, '""')}"`;
53788
54225
  }
@@ -54154,7 +54591,7 @@ var init_drizzle_zod = __esm(() => {
54154
54591
  };
54155
54592
  });
54156
54593
 
54157
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/schema/define-table.js
54594
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/schema/define-table.js
54158
54595
  function defineTable(name, columns2) {
54159
54596
  const table3 = sqliteTable(name, columns2);
54160
54597
  let insert2;
@@ -54188,7 +54625,7 @@ var init_define_table = __esm(() => {
54188
54625
  init_ddl();
54189
54626
  });
54190
54627
 
54191
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/schema/index.js
54628
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/schema/index.js
54192
54629
  var exports_schema = {};
54193
54630
  __export(exports_schema, {
54194
54631
  text: () => text,
@@ -54810,7 +55247,7 @@ var init_dao = __esm(() => {
54810
55247
  init_workspace_dao();
54811
55248
  });
54812
55249
 
54813
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/errors.js
55250
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/errors.js
54814
55251
  var WorkflowValidationError, FSMError, RunCollisionError, WorkflowResumeError;
54815
55252
  var init_errors5 = __esm(() => {
54816
55253
  WorkflowValidationError = class WorkflowValidationError extends Error {
@@ -54845,12 +55282,12 @@ var init_errors5 = __esm(() => {
54845
55282
  };
54846
55283
  });
54847
55284
 
54848
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/event-bus/index.js
55285
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/event-bus/index.js
54849
55286
  var init_event_bus2 = __esm(() => {
54850
55287
  init_event_bus();
54851
55288
  });
54852
55289
 
54853
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/api-client.js
55290
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/api-client.js
54854
55291
  function sanitizeUrlForObservability(url2) {
54855
55292
  try {
54856
55293
  const parsed = new URL(url2);
@@ -55081,12 +55518,12 @@ var init_api_client = __esm(() => {
55081
55518
  };
55082
55519
  });
55083
55520
 
55084
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/telemetry/index.js
55521
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/telemetry/index.js
55085
55522
  var init_telemetry = __esm(() => {
55086
55523
  init_tracing2();
55087
55524
  });
55088
55525
 
55089
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/index.js
55526
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/index.js
55090
55527
  var init_dist6 = __esm(() => {
55091
55528
  init_api_client();
55092
55529
  init_event_bus2();
@@ -55094,7 +55531,7 @@ var init_dist6 = __esm(() => {
55094
55531
  init_telemetry();
55095
55532
  });
55096
55533
 
55097
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/run-lifecycle.js
55534
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/run-lifecycle.js
55098
55535
  function runtimeBuiltins(workflowName, stateOrNodeId, runId, transitionsTaken, mode) {
55099
55536
  return {
55100
55537
  workflow: workflowName,
@@ -55378,7 +55815,7 @@ var init_run_lifecycle = __esm(() => {
55378
55815
  ];
55379
55816
  });
55380
55817
 
55381
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/extension/capability-registry.js
55818
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/extension/capability-registry.js
55382
55819
  class CapabilityRegistry {
55383
55820
  kind;
55384
55821
  capabilities = new Map;
@@ -55409,7 +55846,7 @@ class CapabilityRegistry {
55409
55846
  }
55410
55847
  }
55411
55848
 
55412
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-path.js
55849
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-path.js
55413
55850
  function assertRelativeExtensionPath(path9, options = {}) {
55414
55851
  const where = options.sourceName !== undefined ? ` declared by "${options.sourceName}"` : "";
55415
55852
  if (/^([/\\]|[A-Za-z]:[/\\])/.test(path9)) {
@@ -55420,7 +55857,7 @@ function assertRelativeExtensionPath(path9, options = {}) {
55420
55857
  }
55421
55858
  }
55422
55859
 
55423
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-loader.js
55860
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-loader.js
55424
55861
  import { isAbsolute, resolve } from "path";
55425
55862
  async function loadExtensionModules(refs, options, register) {
55426
55863
  if (refs.length === 0)
@@ -55459,17 +55896,17 @@ async function loadExtensionModules(refs, options, register) {
55459
55896
  }
55460
55897
  var init_extension_loader = () => {};
55461
55898
 
55462
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/extension/index.js
55899
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/extension/index.js
55463
55900
  var init_extension = __esm(() => {
55464
55901
  init_extension_loader();
55465
55902
  });
55466
55903
 
55467
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/extension.js
55904
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/extension.js
55468
55905
  var init_extension2 = __esm(() => {
55469
55906
  init_extension();
55470
55907
  });
55471
55908
 
55472
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/schema.js
55909
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/schema.js
55473
55910
  var RESERVED_VAR_NAMES, IDENTIFIER, VarsSchema, EnvSchema, relativeExtensionPath, WorkflowExtensionsSchema, ActionDefSchema, GuardDefSchema, StateMachineWorkflowDefSchema, TransitionFlowWorkflowDefSchema, WorkflowDefSchema;
55474
55911
  var init_schema2 = __esm(() => {
55475
55912
  init_extension2();
@@ -55571,7 +56008,7 @@ var init_schema2 = __esm(() => {
55571
56008
  WorkflowDefSchema = exports_external.union([StateMachineWorkflowDefSchema, TransitionFlowWorkflowDefSchema]);
55572
56009
  });
55573
56010
 
55574
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/config.js
56011
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/config.js
55575
56012
  async function loadWorkflowDef(path9, options = {}) {
55576
56013
  return parseWorkflowDef(await loadStructuredConfig(path9, options), path9);
55577
56014
  }
@@ -55738,7 +56175,7 @@ var init_config4 = __esm(() => {
55738
56175
  RUNTIME_TEMPLATE_NAMESPACES = new Set(RUNTIME_BUILTIN_KEYS);
55739
56176
  });
55740
56177
 
55741
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/extensions.js
56178
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/extensions.js
55742
56179
  function collectWorkflowExtensions(sourceName, sourceDir, extensions) {
55743
56180
  if (extensions === undefined)
55744
56181
  return [];
@@ -55802,7 +56239,7 @@ var init_extensions = __esm(() => {
55802
56239
  init_errors5();
55803
56240
  });
55804
56241
 
55805
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/host.js
56242
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/host.js
55806
56243
  class WorkflowEngineHost {
55807
56244
  lifecycleBus;
55808
56245
  actions = new CapabilityRegistry("workflow action");
@@ -55972,7 +56409,7 @@ var init_host = __esm(() => {
55972
56409
  init_errors5();
55973
56410
  });
55974
56411
 
55975
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/schema-sql.js
56412
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/schema-sql.js
55976
56413
  var WORKFLOW_ENGINE_SCHEMA_SQL;
55977
56414
  var init_schema_sql = __esm(() => {
55978
56415
  WORKFLOW_ENGINE_SCHEMA_SQL = `
@@ -56045,7 +56482,7 @@ CREATE TABLE IF NOT EXISTS action_runs (
56045
56482
  `.trim();
56046
56483
  });
56047
56484
 
56048
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/persistence.js
56485
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/persistence.js
56049
56486
  async function applyWorkflowEngineSchema(db2) {
56050
56487
  for (const statement of WORKFLOW_ENGINE_SCHEMA_SQL.split(";")) {
56051
56488
  const sql4 = statement.trim();
@@ -56361,7 +56798,7 @@ var init_persistence = __esm(() => {
56361
56798
  init_schema_sql();
56362
56799
  });
56363
56800
 
56364
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/variables.js
56801
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/variables.js
56365
56802
  function mergeVars(workflowVars = {}, overrideVars = {}) {
56366
56803
  return { ...workflowVars, ...overrideVars };
56367
56804
  }
@@ -56421,7 +56858,7 @@ var init_variables = __esm(() => {
56421
56858
  TEMPLATE_REF = /\$\{([^}]+)\}/g;
56422
56859
  });
56423
56860
 
56424
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/action-step.js
56861
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/action-step.js
56425
56862
  async function runActionStep(action, vars, deps) {
56426
56863
  const { host, persistence, lifecycle, stateOrNodeId, runId } = deps;
56427
56864
  const resolved = resolveTemplates(action.options ?? {}, {
@@ -56485,7 +56922,7 @@ var init_action_step = __esm(() => {
56485
56922
  init_variables();
56486
56923
  });
56487
56924
 
56488
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/state-machine.js
56925
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/state-machine.js
56489
56926
  class StateMachineDriver {
56490
56927
  options;
56491
56928
  constructor(options) {
@@ -56621,7 +57058,7 @@ var init_state_machine = __esm(() => {
56621
57058
  EMPTY_OUTCOME = { outcome: "completed", result: undefined, setVars: undefined };
56622
57059
  });
56623
57060
 
56624
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/transition-flow.js
57061
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/transition-flow.js
56625
57062
  class TransitionFlowDriver {
56626
57063
  options;
56627
57064
  constructor(options) {
@@ -56740,7 +57177,7 @@ var init_transition_flow = __esm(() => {
56740
57177
  init_variables();
56741
57178
  });
56742
57179
 
56743
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/service.js
57180
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/service.js
56744
57181
  class WorkflowService {
56745
57182
  host;
56746
57183
  persistence;
@@ -56965,7 +57402,7 @@ var init_service = __esm(() => {
56965
57402
  init_variables();
56966
57403
  });
56967
57404
 
56968
- // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/index.js
57405
+ // ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/index.js
56969
57406
  var init_dist7 = __esm(() => {
56970
57407
  init_config4();
56971
57408
  init_extensions();
@@ -56975,7 +57412,7 @@ var init_dist7 = __esm(() => {
56975
57412
  init_service();
56976
57413
  });
56977
57414
 
56978
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.41+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/hash.js
57415
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.42+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/hash.js
56979
57416
  import { createHash as createHash2 } from "crypto";
56980
57417
  function stableJson(value) {
56981
57418
  if (Array.isArray(value)) {
@@ -56992,7 +57429,7 @@ function sha256(value) {
56992
57429
  }
56993
57430
  var init_hash = () => {};
56994
57431
 
56995
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.41+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/errors.js
57432
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.42+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/errors.js
56996
57433
  var HistoryImportError;
56997
57434
  var init_errors6 = __esm(() => {
56998
57435
  HistoryImportError = class HistoryImportError extends Error {
@@ -57005,7 +57442,7 @@ var init_errors6 = __esm(() => {
57005
57442
  };
57006
57443
  });
57007
57444
 
57008
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.41+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/schema-sql.js
57445
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.42+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/schema-sql.js
57009
57446
  var HISTORY_IMPORT_SCHEMA_SQL;
57010
57447
  var init_schema_sql2 = __esm(() => {
57011
57448
  HISTORY_IMPORT_SCHEMA_SQL = `
@@ -57089,7 +57526,7 @@ CREATE INDEX IF NOT EXISTS idx_history_tool_call_message_hash
57089
57526
  `.trim();
57090
57527
  });
57091
57528
 
57092
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.41+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/mappers.js
57529
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.42+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/mappers.js
57093
57530
  function identityFieldMap(keys) {
57094
57531
  const map2 = {};
57095
57532
  for (const key of keys) {
@@ -57467,15 +57904,24 @@ function claudeToolResultTiming(raw) {
57467
57904
  }
57468
57905
  return null;
57469
57906
  }
57470
- function codexSplit(raw) {
57907
+ function codexSplit(raw, context4) {
57471
57908
  const entries = [];
57472
57909
  const payload = raw.payload ?? raw;
57473
- const sessionId = s(raw.session_id, o2(raw.session_meta).id, raw.id) ?? "unknown";
57474
57910
  const seq = typeof raw.seq === "number" ? raw.seq : 0;
57475
57911
  const ts = timestampOf(raw.timestamp, raw.ts, payload.ts);
57476
57912
  const recordType = String(raw.type ?? "");
57477
57913
  const payloadType = String(payload.type ?? "");
57478
- if (recordType === "" && raw.id && raw.timestamp && raw.instructions) {
57914
+ const isShortFormat = recordType === "" && raw.id !== undefined && raw.timestamp !== undefined && raw.instructions !== undefined;
57915
+ let explicitSessionId = s(raw.session_id, o2(raw.session_meta).id);
57916
+ if (explicitSessionId === undefined && recordType === "session_meta") {
57917
+ explicitSessionId = s(payload.id, o2(raw.payload).id);
57918
+ }
57919
+ if (explicitSessionId === undefined && isShortFormat) {
57920
+ explicitSessionId = s(raw.id);
57921
+ }
57922
+ const pathSessionId = context4?.sourceFile ? sessionIdFromSourcePath("codex", context4.sourceFile) : undefined;
57923
+ const sessionId = explicitSessionId ?? pathSessionId ?? "unknown";
57924
+ if (isShortFormat) {
57479
57925
  return [
57480
57926
  {
57481
57927
  targetTable: "history_message",
@@ -57603,10 +58049,12 @@ function codexSplit(raw) {
57603
58049
  }
57604
58050
  return entries;
57605
58051
  }
57606
- function agySplit(raw) {
58052
+ function agySplit(raw, context4) {
57607
58053
  const entries = [];
57608
58054
  const recordType = String(raw.type ?? "");
57609
- const sessionId = s(raw.session_id, raw.conversation_id) ?? "unknown";
58055
+ const explicitSessionId = s(raw.session_id, raw.conversation_id);
58056
+ const pathSessionId = context4?.sourceFile ? sessionIdFromSourcePath("agy", context4.sourceFile) : undefined;
58057
+ const sessionId = explicitSessionId ?? pathSessionId ?? "unknown";
57610
58058
  const seq = typeof raw.seq === "number" ? raw.seq : typeof raw.step_index === "number" ? raw.step_index : 0;
57611
58059
  const ts = timestampOf(raw.created_at, raw.timestamp, raw.ts);
57612
58060
  let role;
@@ -57785,6 +58233,23 @@ function geminiSplit(raw, context4) {
57785
58233
  }
57786
58234
  return entries;
57787
58235
  }
58236
+ function sessionIdFromSourcePath(source, sourceFile) {
58237
+ const normalized = sourceFile.replace(/\\/g, "/");
58238
+ const sLower = source.toLowerCase();
58239
+ if (sLower === "agy" || sLower === "antigravity") {
58240
+ const match = normalized.match(AGY_BRAIN_REGEX);
58241
+ return match?.[1];
58242
+ }
58243
+ if (sLower === "codex") {
58244
+ const basename = normalized.split("/").at(-1) ?? "";
58245
+ if (basename.startsWith("rollout-") && basename.endsWith(".jsonl")) {
58246
+ const stem = basename.slice(0, -6);
58247
+ const match = stem.match(CODEX_ROLLOUT_REGEX);
58248
+ return match?.[1];
58249
+ }
58250
+ }
58251
+ return;
58252
+ }
57788
58253
  function sessionIdFromContext(context4, raw) {
57789
58254
  if (context4 !== undefined) {
57790
58255
  const file2 = context4.sourceFile.split("/").at(-1);
@@ -58218,7 +58683,7 @@ function extractContentText(content) {
58218
58683
  function stableFieldShape(raw) {
58219
58684
  return Object.keys(raw).map((k) => k.toLowerCase()).sort().join("+");
58220
58685
  }
58221
- var MESSAGE_MAPPER_KEYS, TOOL_CALL_MAPPER_KEYS, TODO_TOOL_ALLOWLIST, GROK_META_TYPES, CLAUDE_FIELD_MAP, PI_FIELD_MAP, OMP_FIELD_MAP, CODEX_FIELD_MAP, AGY_FIELD_MAP, GROK_FIELD_MAP, GEMINI_FIELD_MAP, passthroughSchema, CLAUDE_SCHEMA, PI_SCHEMA, OMP_SCHEMA, CODEX_SCHEMA, AGY_SCHEMA, GROK_SCHEMA, GEMINI_SCHEMA;
58686
+ var MESSAGE_MAPPER_KEYS, TOOL_CALL_MAPPER_KEYS, TODO_TOOL_ALLOWLIST, UUID_PATTERN = "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}", AGY_BRAIN_REGEX, CODEX_ROLLOUT_REGEX, GROK_META_TYPES, CLAUDE_FIELD_MAP, PI_FIELD_MAP, OMP_FIELD_MAP, CODEX_FIELD_MAP, AGY_FIELD_MAP, GROK_FIELD_MAP, GEMINI_FIELD_MAP, passthroughSchema, CLAUDE_SCHEMA, PI_SCHEMA, OMP_SCHEMA, CODEX_SCHEMA, AGY_SCHEMA, GROK_SCHEMA, GEMINI_SCHEMA;
58222
58687
  var init_mappers = __esm(() => {
58223
58688
  init_zod();
58224
58689
  init_hash();
@@ -58269,6 +58734,8 @@ var init_mappers = __esm(() => {
58269
58734
  agy: [],
58270
58735
  gemini: []
58271
58736
  };
58737
+ AGY_BRAIN_REGEX = new RegExp(`(?:^|\\/)brain\\/(${UUID_PATTERN})(?:\\/|$)`, "i");
58738
+ CODEX_ROLLOUT_REGEX = new RegExp(`(?:^|-|_)(${UUID_PATTERN})$`, "i");
58272
58739
  GROK_META_TYPES = new Set([
58273
58740
  "phase_changed",
58274
58741
  "permission_requested",
@@ -58316,7 +58783,7 @@ var init_mappers = __esm(() => {
58316
58783
  GEMINI_SCHEMA = passthroughSchema;
58317
58784
  });
58318
58785
 
58319
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.41+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/sources.js
58786
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.42+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/sources.js
58320
58787
  function firstString(...values) {
58321
58788
  for (const value of values) {
58322
58789
  if (typeof value === "string" && value.length > 0)
@@ -58473,7 +58940,7 @@ var init_sources = __esm(() => {
58473
58940
  };
58474
58941
  });
58475
58942
 
58476
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.41+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/jsonl-importer-dao.js
58943
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.42+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/jsonl-importer-dao.js
58477
58944
  function targetTableFor(table3) {
58478
58945
  if (!VALID_TABLE_NAME.test(table3)) {
58479
58946
  throw new HistoryImportError(`Invalid history ETL target table: ${table3}`, { table: table3 });
@@ -58788,7 +59255,7 @@ var init_jsonl_importer_dao = __esm(() => {
58788
59255
  TYPED_IGNORED_KEYS = new Set(["_meta", "split_index"]);
58789
59256
  });
58790
59257
 
58791
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.41+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/redaction.js
59258
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.42+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/redaction.js
58792
59259
  function redactValue(value, rules = DEFAULT_REDACTION_RULES) {
58793
59260
  if (typeof value === "string") {
58794
59261
  return rules.reduce((current, rule) => current.replace(rule.pattern, rule.replacement), value);
@@ -58840,7 +59307,7 @@ var init_redaction = __esm(() => {
58840
59307
  ];
58841
59308
  });
58842
59309
 
58843
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.41+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/importer.js
59310
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.42+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/importer.js
58844
59311
  function toolCallKey(source, sessionId, callId) {
58845
59312
  return `${source}${TOOL_CALL_KEY_SEP}${sessionId}${TOOL_CALL_KEY_SEP}${callId}`;
58846
59313
  }
@@ -59184,7 +59651,7 @@ var init_importer = __esm(() => {
59184
59651
  init_sources();
59185
59652
  });
59186
59653
 
59187
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.41+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/opencode-importer.js
59654
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.42+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/opencode-importer.js
59188
59655
  async function runOpenCodeImport(options) {
59189
59656
  const paths = options.paths ?? ambientRuntimePaths2();
59190
59657
  const sourceDatabase = options.sourceDatabase ?? joinPath2(paths.home, ".local/share/opencode/opencode.db");
@@ -59439,15 +59906,16 @@ var init_opencode_importer = __esm(() => {
59439
59906
  init_redaction();
59440
59907
  });
59441
59908
 
59442
- // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.41+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/index.js
59909
+ // ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.42+f66f1d7f0d37c145/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/index.js
59443
59910
  var init_dist8 = __esm(() => {
59444
59911
  init_importer();
59912
+ init_mappers();
59445
59913
  init_opencode_importer();
59446
59914
  init_schema_sql2();
59447
59915
  init_sources();
59448
59916
  });
59449
59917
 
59450
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/config/extensions.js
59918
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/config/extensions.js
59451
59919
  function collectExtensions(sourceName, sourceDir, extensions) {
59452
59920
  if (extensions === undefined)
59453
59921
  return [];
@@ -59461,7 +59929,7 @@ function collectExtensions(sourceName, sourceDir, extensions) {
59461
59929
  }
59462
59930
  var init_extensions2 = () => {};
59463
59931
 
59464
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/types.js
59932
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/types.js
59465
59933
  function createFinding(rule, message, filePath, extras = {}) {
59466
59934
  return {
59467
59935
  ruleId: rule.id,
@@ -59532,7 +60000,7 @@ var init_types3 = __esm(() => {
59532
60000
  });
59533
60001
  });
59534
60002
 
59535
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/config/loader.js
60003
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/config/loader.js
59536
60004
  async function loadPreset(name, options) {
59537
60005
  const merged = await buildMergedRoots(options.roots.map((root) => resolvePath4(root)), options.fileSystem);
59538
60006
  const presetPath = findMergedPreset(merged, name);
@@ -59747,7 +60215,7 @@ var init_loader2 = __esm(() => {
59747
60215
  FIX_MODE_AUTHORITY = { none: 0, suggest: 1, auto: 2 };
59748
60216
  });
59749
60217
 
59750
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/fixers/test-stub-fixer.js
60218
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/fixers/test-stub-fixer.js
59751
60219
  function normalizeFindingPath(filePath) {
59752
60220
  if (!filePath || isAbsolutePath2(filePath))
59753
60221
  return null;
@@ -59812,7 +60280,7 @@ var init_test_stub_fixer = __esm(() => {
59812
60280
  realFileSystem = createNodeFileSystem3();
59813
60281
  });
59814
60282
 
59815
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/fixers/fixers.js
60283
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/fixers/fixers.js
59816
60284
  function registerBuiltinFixers(host, exec) {
59817
60285
  const regexFixer = new RegexFixerProvider;
59818
60286
  const pathFixer = new PathFixerProvider;
@@ -60015,7 +60483,7 @@ var init_fixers = __esm(() => {
60015
60483
  };
60016
60484
  });
60017
60485
 
60018
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/agents/shims.js
60486
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/agents/shims.js
60019
60487
  function getAgentSessionCapability(agent) {
60020
60488
  return AGENT_SESSION_CAPABILITY[agent];
60021
60489
  }
@@ -60307,7 +60775,7 @@ var init_shims = __esm(() => {
60307
60775
  ALIAS_TO_CANONICAL = Object.fromEntries(Object.values(AGENT_SHIMS).flatMap((shim) => (shim.aliases ?? []).map((alias3) => [alias3, shim.name])));
60308
60776
  });
60309
60777
 
60310
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/identity.js
60778
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/identity.js
60311
60779
  function buildIdentityPreamble(ctx) {
60312
60780
  const sections = [
60313
60781
  `You are agent \`${ctx.agentId}\` (${ctx.agentType}) in workspace \`${ctx.workspace}\`.`
@@ -60383,7 +60851,7 @@ var init_identity = __esm(() => {
60383
60851
  init_dist5();
60384
60852
  });
60385
60853
 
60386
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/slash-command.js
60854
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/slash-command.js
60387
60855
  function isClaudeStyleSlashCommand(input) {
60388
60856
  return SLASH_COMMAND_RE.test(input);
60389
60857
  }
@@ -60411,7 +60879,7 @@ var init_slash_command = __esm(() => {
60411
60879
  SLASH_COMMAND_RE = /^\/([a-zA-Z0-9._-]+):([a-zA-Z0-9._-]+)(\s.*)?$/;
60412
60880
  });
60413
60881
 
60414
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/ai-runner.js
60882
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/ai-runner.js
60415
60883
  function buildCorrelationEnv(correlation) {
60416
60884
  return {
60417
60885
  [AGENT_RUN_ID_ENV]: correlation.runId,
@@ -60549,7 +61017,7 @@ var init_ai_runner = __esm(() => {
60549
61017
  init_slash_command();
60550
61018
  });
60551
61019
 
60552
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/agent-detector.js
61020
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/agent-detector.js
60553
61021
  class AgentDetector {
60554
61022
  runner;
60555
61023
  timeout;
@@ -60625,7 +61093,7 @@ var init_agent_detector = __esm(() => {
60625
61093
  VERSION_PATTERN = /(?<version>\d+\.\d+(?:\.\d+)?)/;
60626
61094
  });
60627
61095
 
60628
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/agent-spec.js
61096
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/agent-spec.js
60629
61097
  function validateAgentId(id) {
60630
61098
  if (!/^[a-z][a-z0-9_-]{1,63}$/.test(id)) {
60631
61099
  throw new ValueError(`Invalid agent id "${id}": expected 2-64 chars, lowercase alphanumeric, "_" or "-"`);
@@ -60724,7 +61192,7 @@ var init_agent_spec = __esm(() => {
60724
61192
  };
60725
61193
  });
60726
61194
 
60727
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/agents/auth-shims.js
61195
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/agents/auth-shims.js
60728
61196
  function isNonEmpty(value) {
60729
61197
  return value !== undefined && value.trim().length > 0;
60730
61198
  }
@@ -60849,7 +61317,7 @@ var init_auth_shims = __esm(() => {
60849
61317
  };
60850
61318
  });
60851
61319
 
60852
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/model-health-probe.js
61320
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/model-health-probe.js
60853
61321
  class ModelHealthProbeRegistry {
60854
61322
  probes = new Map;
60855
61323
  register(providerPrefix, probe) {
@@ -60957,7 +61425,7 @@ var init_model_health_probe = __esm(() => {
60957
61425
  };
60958
61426
  });
60959
61427
 
60960
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/doctor-runner.js
61428
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/doctor-runner.js
60961
61429
  class DoctorRunner {
60962
61430
  detector;
60963
61431
  runner;
@@ -61094,15 +61562,15 @@ var init_doctor_runner = __esm(() => {
61094
61562
  init_model_health_probe();
61095
61563
  });
61096
61564
 
61097
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/events.js
61565
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/events.js
61098
61566
  var init_events = () => {};
61099
61567
 
61100
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/messages.js
61568
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/messages.js
61101
61569
  function formatMessage(msg) {
61102
61570
  return `[task from=${msg.fromId ?? "operator"} id=${msg.id}] ${msg.body}`;
61103
61571
  }
61104
61572
 
61105
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/team-agent-process.js
61573
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/team-agent-process.js
61106
61574
  import { Buffer as Buffer5 } from "buffer";
61107
61575
 
61108
61576
  class TeamAgentProcess {
@@ -61236,7 +61704,7 @@ var init_team_agent_process = __esm(() => {
61236
61704
  init_dist5();
61237
61705
  });
61238
61706
 
61239
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/team-orchestrator.js
61707
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/team-orchestrator.js
61240
61708
  class TeamOrchestrator {
61241
61709
  configDir;
61242
61710
  inbox;
@@ -61377,7 +61845,7 @@ var init_team_orchestrator = __esm(() => {
61377
61845
  init_team_agent_process();
61378
61846
  });
61379
61847
 
61380
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/index.js
61848
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/index.js
61381
61849
  var exports_dist3 = {};
61382
61850
  __export(exports_dist3, {
61383
61851
  validateAgentId: () => validateAgentId,
@@ -61430,7 +61898,7 @@ var init_dist9 = __esm(() => {
61430
61898
  init_team_orchestrator();
61431
61899
  });
61432
61900
 
61433
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/config-access.js
61901
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/config-access.js
61434
61902
  function stringArray(value) {
61435
61903
  return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : undefined;
61436
61904
  }
@@ -61468,7 +61936,7 @@ function parseInlineFlags(source) {
61468
61936
  return { flags, rest: source.slice(match[0].length) };
61469
61937
  }
61470
61938
 
61471
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/glob-match.js
61939
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/glob-match.js
61472
61940
  function matchesAny(path9, patterns) {
61473
61941
  if (patterns === undefined || patterns.length === 0)
61474
61942
  return true;
@@ -61516,7 +61984,7 @@ function escapeRegExp(value) {
61516
61984
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
61517
61985
  }
61518
61986
 
61519
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/file-discovery.js
61987
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/file-discovery.js
61520
61988
  async function discoverFiles2(options) {
61521
61989
  const fs3 = options.fs ?? createNodeFileSystem3();
61522
61990
  const allFiles = await walkDir2(options.workdir, fs3, DEFAULT_EXCLUDES);
@@ -61547,12 +62015,12 @@ var init_file_discovery = __esm(() => {
61547
62015
  DEFAULT_EXCLUDES = new Set([".git", "node_modules", "dist", ".coverage", ".astro", ".wrangler"]);
61548
62016
  });
61549
62017
 
61550
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/file-utils.js
62018
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/file-utils.js
61551
62019
  var init_file_utils = __esm(() => {
61552
62020
  init_file_discovery();
61553
62021
  });
61554
62022
 
61555
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/agent-detection-evaluator.js
62023
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/agent-detection-evaluator.js
61556
62024
  class AgentDetectionEvaluator {
61557
62025
  detector;
61558
62026
  constructor(detector = new AgentDetector) {
@@ -61580,7 +62048,7 @@ var init_agent_detection_evaluator = __esm(() => {
61580
62048
  init_file_utils();
61581
62049
  });
61582
62050
 
61583
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/coverage-gate-evaluator.js
62051
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/coverage-gate-evaluator.js
61584
62052
  class CoverageGateEvaluator {
61585
62053
  constructor() {}
61586
62054
  async evaluate(rule, context4) {
@@ -61664,7 +62132,7 @@ var init_coverage_gate_evaluator = __esm(() => {
61664
62132
  init_file_utils();
61665
62133
  });
61666
62134
 
61667
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/exit-code-evaluator.js
62135
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/exit-code-evaluator.js
61668
62136
  class ExitCodeEvaluator {
61669
62137
  executor;
61670
62138
  constructor(executor = nodeBunFactory3.createProcessExecutor()) {
@@ -61700,7 +62168,7 @@ var init_exit_code_evaluator = __esm(() => {
61700
62168
  init_file_utils();
61701
62169
  });
61702
62170
 
61703
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/forbidden-import-evaluator.js
62171
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/forbidden-import-evaluator.js
61704
62172
  class ForbiddenImportEvaluator {
61705
62173
  constructor() {}
61706
62174
  async evaluate(rule, context4) {
@@ -61781,7 +62249,7 @@ var init_forbidden_import_evaluator = __esm(() => {
61781
62249
  init_file_utils();
61782
62250
  });
61783
62251
 
61784
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/import-boundary-evaluator.js
62252
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/import-boundary-evaluator.js
61785
62253
  class ImportBoundaryEvaluator {
61786
62254
  async evaluate(rule, context4) {
61787
62255
  const config4 = rule.evaluator.config ?? {};
@@ -61874,7 +62342,7 @@ var init_import_boundary_evaluator = __esm(() => {
61874
62342
  init_file_utils();
61875
62343
  });
61876
62344
 
61877
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/path-evaluator.js
62345
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/path-evaluator.js
61878
62346
  class PathEvaluator {
61879
62347
  constructor() {}
61880
62348
  async evaluate(rule, context4) {
@@ -61935,7 +62403,7 @@ var init_path_evaluator = __esm(() => {
61935
62403
  init_file_utils();
61936
62404
  });
61937
62405
 
61938
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/regex-evaluator.js
62406
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/regex-evaluator.js
61939
62407
  class RegexEvaluator {
61940
62408
  constructor() {}
61941
62409
  async evaluate(rule, context4) {
@@ -62013,7 +62481,7 @@ var init_regex_evaluator = __esm(() => {
62013
62481
  init_file_utils();
62014
62482
  });
62015
62483
 
62016
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/ripgrep-evaluator.js
62484
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/ripgrep-evaluator.js
62017
62485
  class RipgrepEvaluator {
62018
62486
  executor;
62019
62487
  constructor(executor = nodeBunFactory3.createProcessExecutor()) {
@@ -62106,7 +62574,7 @@ var init_ripgrep_evaluator = __esm(() => {
62106
62574
  init_file_utils();
62107
62575
  });
62108
62576
 
62109
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/schema-artifact-evaluator.js
62577
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/schema-artifact-evaluator.js
62110
62578
  class SchemaArtifactEvaluator {
62111
62579
  constructor() {}
62112
62580
  async evaluate(rule, context4) {
@@ -62184,7 +62652,7 @@ var init_schema_artifact_evaluator = __esm(() => {
62184
62652
  init_file_utils();
62185
62653
  });
62186
62654
 
62187
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/secrets-scanner-evaluator.js
62655
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/secrets-scanner-evaluator.js
62188
62656
  class SecretsScannerEvaluator {
62189
62657
  constructor() {}
62190
62658
  async evaluate(rule, context4) {
@@ -62252,7 +62720,7 @@ var init_secrets_scanner_evaluator = __esm(() => {
62252
62720
  ALL_CATEGORIES = Object.keys(BUILTIN_PATTERNS);
62253
62721
  });
62254
62722
 
62255
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/sg-evaluator.js
62723
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/sg-evaluator.js
62256
62724
  class SgEvaluator {
62257
62725
  executor;
62258
62726
  constructor(executor = nodeBunFactory3.createProcessExecutor()) {
@@ -62349,7 +62817,7 @@ var init_sg_evaluator = __esm(() => {
62349
62817
  init_file_utils();
62350
62818
  });
62351
62819
 
62352
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/resolvers/test-path-resolver.js
62820
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/resolvers/test-path-resolver.js
62353
62821
  class TypeScriptTestPathResolver {
62354
62822
  name = "typescript";
62355
62823
  constructor() {}
@@ -62432,7 +62900,7 @@ function testify(rel) {
62432
62900
  return `${dir}test_${base2}`;
62433
62901
  }
62434
62902
 
62435
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/test-location-evaluator.js
62903
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/test-location-evaluator.js
62436
62904
  class TestLocationEvaluator {
62437
62905
  resolvers;
62438
62906
  constructor(resolvers) {
@@ -62507,7 +62975,7 @@ var init_test_location_evaluator = __esm(() => {
62507
62975
  TYPESCRIPT_FALLBACK = new TypeScriptTestPathResolver;
62508
62976
  });
62509
62977
 
62510
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/tsdoc-export-evaluator.js
62978
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/tsdoc-export-evaluator.js
62511
62979
  class TsdocExportEvaluator {
62512
62980
  constructor() {}
62513
62981
  async evaluate(rule, context4) {
@@ -62592,7 +63060,7 @@ var init_tsdoc_export_evaluator = __esm(() => {
62592
63060
  };
62593
63061
  });
62594
63062
 
62595
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/json.js
63063
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/json.js
62596
63064
  class JsonFormatter {
62597
63065
  constructor() {}
62598
63066
  format(result) {
@@ -62600,7 +63068,7 @@ class JsonFormatter {
62600
63068
  }
62601
63069
  }
62602
63070
 
62603
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/text.js
63071
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/text.js
62604
63072
  class TextFormatter {
62605
63073
  constructor() {}
62606
63074
  format(result) {
@@ -62614,7 +63082,7 @@ class TextFormatter {
62614
63082
  }
62615
63083
  }
62616
63084
 
62617
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/host/builtins.js
63085
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/host/builtins.js
62618
63086
  function registerBuiltins(host, executor) {
62619
63087
  const path9 = new PathEvaluator;
62620
63088
  host.evaluators.register("regex", new RegexEvaluator, "builtin");
@@ -62654,7 +63122,7 @@ var init_builtins = __esm(() => {
62654
63122
  init_tsdoc_export_evaluator();
62655
63123
  });
62656
63124
 
62657
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/host/rule-engine-host.js
63125
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/host/rule-engine-host.js
62658
63126
  class RuleEngineHost {
62659
63127
  evaluators;
62660
63128
  formatters;
@@ -62671,7 +63139,7 @@ var init_rule_engine_host = __esm(() => {
62671
63139
  init_extension2();
62672
63140
  });
62673
63141
 
62674
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/engine.js
63142
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/engine.js
62675
63143
  class RuleEngine {
62676
63144
  host;
62677
63145
  events;
@@ -62857,7 +63325,7 @@ var init_engine = __esm(() => {
62857
63325
  init_types3();
62858
63326
  });
62859
63327
 
62860
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/host/bundled-rules.js
63328
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/host/bundled-rules.js
62861
63329
  async function bundledRulesRoot() {
62862
63330
  if (cachedRoot2 !== undefined)
62863
63331
  return cachedRoot2;
@@ -62908,7 +63376,7 @@ var init_bundled_rules = __esm(() => {
62908
63376
  init_dist5();
62909
63377
  });
62910
63378
 
62911
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/db-adapter.js
63379
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/db-adapter.js
62912
63380
  class DbRulePersistenceAdapter {
62913
63381
  db;
62914
63382
  constructor(db2) {
@@ -62942,7 +63410,7 @@ class DbRulePersistenceAdapter {
62942
63410
  }
62943
63411
  }
62944
63412
 
62945
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/schema.js
63413
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/schema.js
62946
63414
  var RULE_ENGINE_SCHEMA_SQL = `
62947
63415
  CREATE TABLE IF NOT EXISTS rule_runs (
62948
63416
  id TEXT PRIMARY KEY,
@@ -62988,10 +63456,10 @@ CREATE TABLE IF NOT EXISTS rule_eval_runs (
62988
63456
  CREATE INDEX IF NOT EXISTS idx_rule_eval_runs_run_id ON rule_eval_runs (run_id);
62989
63457
  `;
62990
63458
 
62991
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/index.js
63459
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/index.js
62992
63460
  var init_persistence2 = () => {};
62993
63461
 
62994
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/index.js
63462
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/index.js
62995
63463
  var init_dist10 = __esm(() => {
62996
63464
  init_extensions2();
62997
63465
  init_loader2();
@@ -63232,6 +63700,10 @@ ALTER TABLE history_tool_call ADD COLUMN args_raw TEXT;
63232
63700
  ALTER TABLE history_tool_call ADD COLUMN call_id TEXT;
63233
63701
  `, HISTORY_MESSAGE_REQUEST_ID_SCHEMA_SQL = `
63234
63702
  ALTER TABLE history_message ADD COLUMN request_id TEXT;
63703
+ `, HISTORY_MESSAGE_REQUEST_ID_INDEX_SCHEMA_SQL = `
63704
+ CREATE INDEX IF NOT EXISTS idx_history_message_request_id
63705
+ ON history_message (request_id)
63706
+ WHERE request_id IS NOT NULL;
63235
63707
  `, HISTORY_ETL_TABLES_DROP_SCHEMA_SQL = `
63236
63708
  DROP TABLE IF EXISTS history_etl_pi;
63237
63709
  DROP TABLE IF EXISTS history_etl_claude;
@@ -63563,11 +64035,15 @@ ${HISTORY_RUN_SESSION_SCHEMA_SQL}
63563
64035
  {
63564
64036
  id: "0022_spur_cli_history_performance_indexes",
63565
64037
  sql: HISTORY_PERFORMANCE_INDEXES_SCHEMA_SQL
64038
+ },
64039
+ {
64040
+ id: "0023_spur_cli_history_message_request_id_idx",
64041
+ sql: HISTORY_MESSAGE_REQUEST_ID_INDEX_SCHEMA_SQL
63566
64042
  }
63567
64043
  ];
63568
64044
  });
63569
64045
 
63570
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/job-queue/db-job-queue.js
64046
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/job-queue/db-job-queue.js
63571
64047
  function queueLogger() {
63572
64048
  if (!_queueLogger)
63573
64049
  _queueLogger = getLogger2("job-queue");
@@ -63870,7 +64346,7 @@ var init_db_job_queue = __esm(() => {
63870
64346
  init_tracing2();
63871
64347
  });
63872
64348
 
63873
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/job-queue-db.js
64349
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/job-queue-db.js
63874
64350
  var exports_job_queue_db = {};
63875
64351
  __export(exports_job_queue_db, {
63876
64352
  DBQueueConsumer: () => DBQueueConsumer,
@@ -66232,6 +66708,7 @@ __export(exports_src, {
66232
66708
  createBoundaryContext: () => createBoundaryContext,
66233
66709
  countToolCallsSince: () => countToolCallsSince,
66234
66710
  countCheckpointsBySource: () => countCheckpointsBySource,
66711
+ consolidatedTimeline: () => consolidatedTimeline,
66235
66712
  computeSnapshotHash: () => computeSnapshotHash,
66236
66713
  computeRecordCost: () => computeRecordCost,
66237
66714
  computeInvalidationFingerprint: () => computeInvalidationFingerprint,
@@ -67238,6 +67715,11 @@ class RunSessionObserver {
67238
67715
  return;
67239
67716
  }
67240
67717
  const sessionId = await this.sessionIdFor(wm.source, candidates[0]);
67718
+ if (sessionId === undefined) {
67719
+ this.warn(`run-session resolve for ${wm.source}: candidate has no canonical session id`);
67720
+ await this.writeUnresolved(wm.source);
67721
+ return;
67722
+ }
67241
67723
  await this.write({
67242
67724
  runId: this.options.runId,
67243
67725
  source: wm.source,
@@ -67275,20 +67757,38 @@ class RunSessionObserver {
67275
67757
  return candidates.sort();
67276
67758
  }
67277
67759
  async sessionIdFor(source, filePath) {
67278
- const stem = basename(filePath).replace(/\.[^.]+$/, "");
67760
+ let firstRecordId;
67279
67761
  try {
67280
67762
  const firstLine = (await createNodeFileSystem3().readFile(filePath)).split(`
67281
67763
  `, 1)[0] ?? "";
67282
67764
  const raw = JSON.parse(firstLine);
67283
67765
  if (source === "claude")
67284
- return firstString2(raw.sessionId, raw.conversation_uuid) ?? stem;
67285
- if (source === "codex") {
67766
+ firstRecordId = firstString2(raw.sessionId, raw.conversation_uuid);
67767
+ else if (source === "codex") {
67286
67768
  const payload = asRecord(raw.payload);
67287
- return firstString2(raw.session_id, payload?.id, raw.id) ?? stem;
67769
+ const recordType = typeof raw.type === "string" ? raw.type : "";
67770
+ const isShortFormat = recordType === "" && raw.id !== undefined && raw.timestamp !== undefined && raw.instructions !== undefined;
67771
+ firstRecordId = firstString2(raw.session_id, asRecord(raw.session_meta)?.id);
67772
+ if (firstRecordId === undefined && recordType === "session_meta") {
67773
+ firstRecordId = firstString2(payload?.id);
67774
+ }
67775
+ if (firstRecordId === undefined && isShortFormat) {
67776
+ firstRecordId = firstString2(raw.id);
67777
+ }
67778
+ } else if (source === "pi") {
67779
+ firstRecordId = firstString2(raw.id, asRecord(raw.session)?.id);
67780
+ } else if (source === "agy" || source === "antigravity") {
67781
+ firstRecordId = firstString2(raw.session_id, raw.conversation_id);
67288
67782
  }
67289
- if (source === "pi")
67290
- return firstString2(raw.id, asRecord(raw.session)?.id) ?? stem;
67291
67783
  } catch {}
67784
+ if (firstRecordId)
67785
+ return firstRecordId;
67786
+ const fromPath = sessionIdFromSourcePath(source, filePath);
67787
+ if (fromPath)
67788
+ return fromPath;
67789
+ if (source === "agy" || source === "antigravity" || source === "codex")
67790
+ return;
67791
+ const stem = basename(filePath).replace(/\.[^.]+$/, "");
67292
67792
  return stem;
67293
67793
  }
67294
67794
  async writeUnresolved(source) {
@@ -74931,125 +75431,180 @@ class MockHistoryBoardService {
74931
75431
  }
74932
75432
  return points;
74933
75433
  }
74934
- async getTimeline(sessionId) {
74935
- const session4 = this.sessions.find((s3) => s3.id === sessionId);
74936
- if (!session4)
74937
- throw new Error(`History session not found: ${sessionId}`);
74938
- const sessionStart = session4.start;
74939
- const blocks = [
74940
- {
74941
- turnIndex: 0,
74942
- timestamp: new Date(sessionStart).toISOString(),
74943
- source: session4.source,
74944
- model: session4.model,
74945
- totalDurationMs: 4200,
74946
- totalTokens: 18500,
74947
- operationCount: 3,
74948
- events: [
74949
- {
74950
- seq: 1,
74951
- eventType: "message",
74952
- kind: "user",
74953
- title: "User Prompt: Analyze repository architecture and find performance bottlenecks",
74954
- durationMs: 0,
74955
- tokens: 450,
74956
- freshInputTokens: 450,
74957
- cacheReadTokens: 0,
74958
- outputTokens: 0,
74959
- exitCode: null,
74960
- payload: "User prompt content",
74961
- agent: session4.source,
74962
- model: session4.model
74963
- },
74964
- {
74965
- seq: 2,
74966
- eventType: "tool",
74967
- kind: "search",
74968
- title: "Glob: src/**/*.ts",
74969
- durationMs: 320,
74970
- tokens: 4200,
74971
- freshInputTokens: 200,
74972
- cacheReadTokens: 3800,
74973
- outputTokens: 200,
74974
- exitCode: 0,
74975
- payload: "Matched 48 files",
74976
- agent: session4.source,
74977
- model: session4.model
74978
- },
74979
- {
74980
- seq: 3,
74981
- eventType: "tool",
74982
- kind: "read",
74983
- title: "Read: docs/03_ARCHITECTURE.md",
74984
- durationMs: 780,
74985
- tokens: 13850,
74986
- freshInputTokens: 600,
74987
- cacheReadTokens: 12500,
74988
- outputTokens: 750,
74989
- exitCode: 0,
74990
- payload: `# Architecture
75434
+ async getTimeline(input) {
75435
+ if (input.mode === "session") {
75436
+ const session4 = this.sessions.find((s3) => s3.id === input.sessionId);
75437
+ if (!session4)
75438
+ throw new Error(`History session not found: ${input.sessionId}`);
75439
+ const sessionStart = session4.start;
75440
+ const blocks = [
75441
+ {
75442
+ key: `${session4.source}:::${session4.id}:::0`,
75443
+ sessionId: session4.id,
75444
+ turnIndex: 0,
75445
+ timestamp: new Date(sessionStart).toISOString(),
75446
+ source: session4.source,
75447
+ model: session4.model,
75448
+ correlationExactness: null,
75449
+ totalDurationMs: 4200,
75450
+ totalTokens: 18500,
75451
+ operationCount: 3,
75452
+ events: [
75453
+ {
75454
+ seq: 1,
75455
+ eventType: "message",
75456
+ kind: "user",
75457
+ title: "user turn",
75458
+ toolName: null,
75459
+ durationMs: null,
75460
+ durationSource: "unmeasured",
75461
+ tokens: 450,
75462
+ freshInputTokens: 450,
75463
+ cacheReadTokens: 0,
75464
+ outputTokens: 0,
75465
+ promptTokens: {
75466
+ billedTokens: 18050,
75467
+ cacheSavedTokens: 16300,
75468
+ cacheReadTokens: 16300,
75469
+ freshInputTokens: 800,
75470
+ outputTokens: 950
75471
+ },
75472
+ exitCode: null,
75473
+ payload: "User prompt content",
75474
+ agent: session4.source,
75475
+ model: session4.model
75476
+ },
75477
+ {
75478
+ seq: 2,
75479
+ eventType: "tool",
75480
+ kind: "search",
75481
+ title: "src/**/*.ts",
75482
+ toolName: "Glob",
75483
+ durationMs: 320,
75484
+ durationSource: "measured",
75485
+ tokens: 4200,
75486
+ freshInputTokens: 200,
75487
+ cacheReadTokens: 3800,
75488
+ outputTokens: 200,
75489
+ promptTokens: null,
75490
+ exitCode: 0,
75491
+ payload: "Matched 48 files",
75492
+ agent: session4.source,
75493
+ model: session4.model
75494
+ },
75495
+ {
75496
+ seq: 3,
75497
+ eventType: "tool",
75498
+ kind: "read",
75499
+ title: "docs/03_ARCHITECTURE.md",
75500
+ toolName: "Read",
75501
+ durationMs: 780,
75502
+ durationSource: "measured",
75503
+ tokens: 13850,
75504
+ freshInputTokens: 600,
75505
+ cacheReadTokens: 12500,
75506
+ outputTokens: 750,
75507
+ promptTokens: null,
75508
+ exitCode: 0,
75509
+ payload: `# Architecture
74991
75510
 
74992
75511
  System components and dataflow...`,
74993
- agent: session4.source,
74994
- model: session4.model
74995
- }
74996
- ]
74997
- },
74998
- {
74999
- turnIndex: 1,
75000
- timestamp: new Date(sessionStart + 60000).toISOString(),
75001
- source: session4.source,
75002
- model: session4.model,
75003
- totalDurationMs: 8900,
75004
- totalTokens: 32400,
75005
- operationCount: 2,
75006
- events: [
75007
- {
75008
- seq: 4,
75009
- eventType: "tool",
75010
- kind: "bash",
75011
- title: "Bash: bun run test",
75012
- durationMs: 6400,
75013
- tokens: 18200,
75014
- freshInputTokens: 800,
75015
- cacheReadTokens: 16500,
75016
- outputTokens: 900,
75017
- exitCode: 0,
75018
- payload: "All 64 tests passed",
75019
- agent: session4.source,
75020
- model: session4.model
75021
- },
75022
- {
75023
- seq: 5,
75024
- eventType: "tool",
75025
- kind: "write",
75026
- title: "Edit: packages/contracts/src/history.ts",
75027
- durationMs: 2500,
75028
- tokens: 14200,
75029
- freshInputTokens: 400,
75030
- cacheReadTokens: 13000,
75031
- outputTokens: 800,
75032
- exitCode: 0,
75033
- payload: "Replaced 42 lines",
75034
- agent: session4.source,
75035
- model: session4.model
75036
- }
75037
- ]
75038
- }
75039
- ];
75512
+ agent: session4.source,
75513
+ model: session4.model
75514
+ }
75515
+ ]
75516
+ },
75517
+ {
75518
+ key: `${session4.source}:::${session4.id}:::1`,
75519
+ sessionId: session4.id,
75520
+ turnIndex: 1,
75521
+ timestamp: new Date(sessionStart + 60000).toISOString(),
75522
+ source: session4.source,
75523
+ model: session4.model,
75524
+ correlationExactness: null,
75525
+ totalDurationMs: 8900,
75526
+ totalTokens: 32400,
75527
+ operationCount: 2,
75528
+ events: [
75529
+ {
75530
+ seq: 4,
75531
+ eventType: "tool",
75532
+ kind: "bash",
75533
+ title: "bun run test",
75534
+ toolName: "Bash",
75535
+ durationMs: 6400,
75536
+ durationSource: "measured",
75537
+ tokens: 18200,
75538
+ freshInputTokens: 800,
75539
+ cacheReadTokens: 16500,
75540
+ outputTokens: 900,
75541
+ promptTokens: null,
75542
+ exitCode: 0,
75543
+ payload: "All 64 tests passed",
75544
+ agent: session4.source,
75545
+ model: session4.model
75546
+ },
75547
+ {
75548
+ seq: 5,
75549
+ eventType: "tool",
75550
+ kind: "write",
75551
+ title: "packages/contracts/src/history.ts",
75552
+ toolName: "Edit",
75553
+ durationMs: 2500,
75554
+ durationSource: "measured",
75555
+ tokens: 14200,
75556
+ freshInputTokens: 400,
75557
+ cacheReadTokens: 13000,
75558
+ outputTokens: 800,
75559
+ promptTokens: null,
75560
+ exitCode: 0,
75561
+ payload: "Replaced 42 lines",
75562
+ agent: session4.source,
75563
+ model: session4.model
75564
+ }
75565
+ ]
75566
+ }
75567
+ ];
75568
+ return {
75569
+ mode: "session",
75570
+ scope: {
75571
+ sessionId: session4.id,
75572
+ source: session4.source,
75573
+ model: session4.model,
75574
+ start: new Date(session4.start).toISOString(),
75575
+ end: new Date(session4.start + session4.durationMs).toISOString(),
75576
+ durationMs: session4.durationMs,
75577
+ tokens: session4.tokens,
75578
+ messageCount: session4.messages,
75579
+ toolCallCount: session4.toolCalls,
75580
+ sessionCount: 1
75581
+ },
75582
+ truncated: false,
75583
+ blocks
75584
+ };
75585
+ }
75040
75586
  return {
75041
- session: {
75042
- id: session4.id,
75043
- source: session4.source,
75044
- model: session4.model,
75045
- modelDetail: session4.modelDetail,
75046
- start: new Date(session4.start).toISOString(),
75047
- durationMs: session4.durationMs,
75048
- tokens: session4.tokens,
75049
- messageCount: session4.messages,
75050
- toolCallCount: session4.toolCalls
75587
+ mode: "consolidated",
75588
+ scope: {
75589
+ sessionId: null,
75590
+ source: null,
75591
+ model: null,
75592
+ start: this.sessions[0] ? new Date(this.sessions[0].start).toISOString() : null,
75593
+ end: this.sessions.length > 0 && this.sessions[this.sessions.length - 1] ? new Date(this.sessions[this.sessions.length - 1]?.start ?? "").toISOString() : null,
75594
+ durationMs: this.sessions.reduce((s3, x) => s3 + x.durationMs, 0),
75595
+ tokens: {
75596
+ billedTokens: this.sessions.reduce((s3, x) => s3 + x.tokens.billedTokens, 0),
75597
+ cacheSavedTokens: this.sessions.reduce((s3, x) => s3 + x.tokens.cacheSavedTokens, 0),
75598
+ cacheReadTokens: this.sessions.reduce((s3, x) => s3 + x.tokens.cacheReadTokens, 0),
75599
+ freshInputTokens: this.sessions.reduce((s3, x) => s3 + x.tokens.freshInputTokens, 0),
75600
+ outputTokens: this.sessions.reduce((s3, x) => s3 + x.tokens.outputTokens, 0)
75601
+ },
75602
+ messageCount: this.sessions.reduce((s3, x) => s3 + x.messages, 0),
75603
+ toolCallCount: this.sessions.reduce((s3, x) => s3 + x.toolCalls, 0),
75604
+ sessionCount: this.sessions.length
75051
75605
  },
75052
- blocks
75606
+ truncated: false,
75607
+ blocks: []
75053
75608
  };
75054
75609
  }
75055
75610
  async getSessions(input) {
@@ -75492,6 +76047,26 @@ function classifyTimelineKind(toolName, role) {
75492
76047
  }
75493
76048
  return "run";
75494
76049
  }
76050
+ function extractToolTitle(payload) {
76051
+ if (payload == null || payload.trim().length === 0)
76052
+ return "";
76053
+ try {
76054
+ const parsed = JSON.parse(payload);
76055
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
76056
+ return "";
76057
+ const summaryKeys = ["path", "file_path", "target", "cmd", "command", "query", "pattern", "url"];
76058
+ for (const key2 of summaryKeys) {
76059
+ const val = parsed[key2];
76060
+ if (val !== undefined && val !== null) {
76061
+ if (typeof val === "string" && val.length > 0)
76062
+ return val;
76063
+ if (typeof val === "number" || typeof val === "boolean")
76064
+ return String(val);
76065
+ }
76066
+ }
76067
+ } catch {}
76068
+ return "";
76069
+ }
75495
76070
  function projectSummary(rows, extras) {
75496
76071
  const tokenTotal = (row) => row.freshInputTokens + row.outputTokens;
75497
76072
  const totalBilledTokens = rows.models.reduce((sum, row) => sum + tokenTotal(row), 0);
@@ -75814,15 +76389,17 @@ class LiveHistoryBoardService {
75814
76389
  toolErrors: toolStats.reduce((sum, row) => sum + row.errors, 0)
75815
76390
  }, extras);
75816
76391
  }
75817
- async getTimeline(sessionId) {
76392
+ async getTimeline(input) {
75818
76393
  const db2 = await this.resolveDb();
75819
76394
  if (!db2) {
75820
76395
  return {
75821
- session: {
75822
- id: sessionId,
75823
- source: "unknown",
75824
- model: "unknown",
75825
- start: new Date(0).toISOString(),
76396
+ mode: input.mode,
76397
+ scope: {
76398
+ sessionId: input.mode === "session" ? input.sessionId : null,
76399
+ source: input.mode === "session" ? input.source : null,
76400
+ model: null,
76401
+ start: null,
76402
+ end: null,
75826
76403
  durationMs: 0,
75827
76404
  tokens: {
75828
76405
  billedTokens: 0,
@@ -75832,38 +76409,84 @@ class LiveHistoryBoardService {
75832
76409
  outputTokens: 0
75833
76410
  },
75834
76411
  messageCount: 0,
75835
- toolCallCount: 0
76412
+ toolCallCount: 0,
76413
+ sessionCount: 0
75836
76414
  },
76415
+ truncated: false,
75837
76416
  blocks: []
75838
76417
  };
75839
76418
  }
75840
- if (sessionId === "" || sessionId === "unknown" || sessionId === "session") {
75841
- throw new Error(`History session not found: ${sessionId || "(empty)"}`);
75842
- }
75843
- const events2 = await sessionTimeline(db2, sessionId, 5000);
76419
+ let queryResult;
76420
+ if (input.mode === "session") {
76421
+ if (input.sessionId === "" || input.sessionId === "unknown" || input.sessionId === "session") {
76422
+ throw new Error(`History session not found: ${input.sessionId || "(empty)"}`);
76423
+ }
76424
+ if (input.source === "" || input.source === "unknown") {
76425
+ throw new Error(`History source not found: ${input.source || "(empty)"}`);
76426
+ }
76427
+ queryResult = await sessionTimeline(db2, input.source, input.sessionId, 5000);
76428
+ if (queryResult.events.length === 0) {
76429
+ throw new Error(`History session not found: ${input.sessionId}`);
76430
+ }
76431
+ } else {
76432
+ const sel = toArtifactSelector(input.filter);
76433
+ if (input.runId)
76434
+ sel.runId = input.runId;
76435
+ if (input.taskWbs)
76436
+ sel.taskWbs = input.taskWbs;
76437
+ queryResult = await consolidatedTimeline(db2, sel, 5000);
76438
+ }
76439
+ const events2 = queryResult.events;
75844
76440
  if (events2.length === 0) {
75845
- throw new Error(`History session not found: ${sessionId}`);
76441
+ return {
76442
+ mode: input.mode,
76443
+ scope: {
76444
+ sessionId: input.mode === "session" ? input.sessionId : null,
76445
+ source: input.mode === "session" ? input.source : null,
76446
+ model: null,
76447
+ start: null,
76448
+ end: null,
76449
+ durationMs: 0,
76450
+ tokens: {
76451
+ billedTokens: 0,
76452
+ cacheSavedTokens: 0,
76453
+ cacheReadTokens: 0,
76454
+ freshInputTokens: 0,
76455
+ outputTokens: 0
76456
+ },
76457
+ messageCount: 0,
76458
+ toolCallCount: 0,
76459
+ sessionCount: 0
76460
+ },
76461
+ truncated: false,
76462
+ blocks: []
76463
+ };
75846
76464
  }
75847
- let firstTs = null;
75848
- let lastTs = null;
75849
- let source = "unknown";
75850
- let model = "unknown";
76465
+ const projectedEvents = [];
75851
76466
  let totalFresh = 0;
75852
76467
  let totalCache = 0;
75853
76468
  let totalOut = 0;
75854
76469
  let totalDuration = 0;
75855
76470
  let toolCallCount = 0;
75856
76471
  let messageCount = 0;
75857
- const blocksByTurn = new Map;
76472
+ const uniqueSources = new Set;
76473
+ const uniqueModels = new Set;
76474
+ const uniqueSessions = new Set;
76475
+ let firstTs = null;
76476
+ let lastTs = null;
75858
76477
  for (const ev of events2) {
75859
- if (ev.ts && (firstTs === null || ev.ts < firstTs))
75860
- firstTs = ev.ts;
75861
- if (ev.ts && (lastTs === null || ev.ts > lastTs))
75862
- lastTs = ev.ts;
76478
+ if (ev.ts) {
76479
+ if (firstTs === null || ev.ts < firstTs)
76480
+ firstTs = ev.ts;
76481
+ if (lastTs === null || ev.ts > lastTs)
76482
+ lastTs = ev.ts;
76483
+ }
75863
76484
  if (ev.source)
75864
- source = ev.source;
76485
+ uniqueSources.add(ev.source);
75865
76486
  if (ev.model)
75866
- model = ev.model;
76487
+ uniqueModels.add(ev.model);
76488
+ if (ev.sessionId)
76489
+ uniqueSessions.add(`${ev.source}:::${ev.sessionId}`);
75867
76490
  const fresh = ev.inputTokens ?? 0;
75868
76491
  const cache2 = ev.cacheReadTokens ?? 0;
75869
76492
  const out = ev.outputTokens ?? 0;
@@ -75877,47 +76500,126 @@ class LiveHistoryBoardService {
75877
76500
  toolCallCount += 1;
75878
76501
  else
75879
76502
  messageCount += 1;
75880
- const event = {
76503
+ const title = ev.eventType === "tool" ? extractToolTitle(ev.payload) : ev.role === "user" ? "user turn" : `${ev.role} turn`;
76504
+ projectedEvents.push({
75881
76505
  seq: ev.seq,
75882
76506
  eventType: ev.eventType,
75883
76507
  kind: classifyTimelineKind(ev.toolName, ev.role),
75884
- title: ev.toolName ? `${ev.toolName}` : `${ev.role} turn`,
75885
- durationMs: dur,
76508
+ title,
76509
+ toolName: ev.toolName,
76510
+ durationMs: ev.durationMs,
76511
+ durationSource: ev.durationSource,
75886
76512
  tokens: billed,
75887
76513
  freshInputTokens: fresh,
75888
76514
  cacheReadTokens: cache2,
75889
76515
  outputTokens: out,
76516
+ promptTokens: null,
75890
76517
  exitCode: ev.exitCode,
75891
76518
  payload: ev.payload,
75892
76519
  agent: ev.source,
75893
- model: ev.model ?? "unknown"
75894
- };
75895
- const turn = blocksByTurn.get(ev.turnIndex) ?? {
75896
- turnIndex: ev.turnIndex,
75897
- timestamp: ev.ts ?? new Date(0).toISOString(),
75898
- source: ev.source,
75899
76520
  model: ev.model ?? "unknown",
75900
- totalDurationMs: 0,
75901
- totalTokens: 0,
75902
- operationCount: 0,
75903
- events: []
75904
- };
75905
- turn.totalDurationMs += dur;
75906
- turn.totalTokens += billed;
75907
- turn.operationCount += 1;
75908
- turn.events.push(event);
75909
- blocksByTurn.set(ev.turnIndex, turn);
76521
+ source: ev.source,
76522
+ sessionId: ev.sessionId,
76523
+ turnIndex: ev.turnIndex,
76524
+ ts: ev.ts,
76525
+ correlationExactness: ev.correlationExactness
76526
+ });
76527
+ }
76528
+ const eventsBySession = new Map;
76529
+ for (const ev of projectedEvents) {
76530
+ const sKey = `${ev.source}:::${ev.sessionId}`;
76531
+ let list = eventsBySession.get(sKey);
76532
+ if (list === undefined) {
76533
+ list = [];
76534
+ eventsBySession.set(sKey, list);
76535
+ }
76536
+ list.push(ev);
76537
+ }
76538
+ for (const sessionEvents of eventsBySession.values()) {
76539
+ let activeUserEvent = null;
76540
+ let accFresh = 0;
76541
+ let accCache = 0;
76542
+ let accOut = 0;
76543
+ for (const ev of sessionEvents) {
76544
+ if (ev.kind === "user" || ev.eventType === "message" && ev.title === "user turn") {
76545
+ if (activeUserEvent !== null) {
76546
+ activeUserEvent.promptTokens = {
76547
+ billedTokens: accFresh + accOut,
76548
+ cacheSavedTokens: accCache,
76549
+ cacheReadTokens: accCache,
76550
+ freshInputTokens: accFresh,
76551
+ outputTokens: accOut
76552
+ };
76553
+ }
76554
+ activeUserEvent = ev;
76555
+ accFresh = 0;
76556
+ accCache = 0;
76557
+ accOut = 0;
76558
+ } else {
76559
+ accFresh += ev.freshInputTokens;
76560
+ accCache += ev.cacheReadTokens;
76561
+ accOut += ev.outputTokens;
76562
+ }
76563
+ }
76564
+ if (activeUserEvent !== null) {
76565
+ activeUserEvent.promptTokens = {
76566
+ billedTokens: accFresh + accOut,
76567
+ cacheSavedTokens: accCache,
76568
+ cacheReadTokens: accCache,
76569
+ freshInputTokens: accFresh,
76570
+ outputTokens: accOut
76571
+ };
76572
+ }
75910
76573
  }
76574
+ const blocksByKey = new Map;
76575
+ for (const ev of projectedEvents) {
76576
+ const blockKey = `${ev.source}:::${ev.sessionId}:::${ev.turnIndex}`;
76577
+ let block = blocksByKey.get(blockKey);
76578
+ if (block === undefined) {
76579
+ block = {
76580
+ key: blockKey,
76581
+ sessionId: ev.sessionId,
76582
+ turnIndex: ev.turnIndex,
76583
+ timestamp: ev.ts,
76584
+ source: ev.source,
76585
+ model: ev.model,
76586
+ correlationExactness: ev.correlationExactness ?? null,
76587
+ totalDurationMs: 0,
76588
+ totalTokens: 0,
76589
+ operationCount: 0,
76590
+ events: []
76591
+ };
76592
+ blocksByKey.set(blockKey, block);
76593
+ }
76594
+ block.totalDurationMs += ev.durationMs ?? 0;
76595
+ block.totalTokens += ev.tokens;
76596
+ block.operationCount += 1;
76597
+ if (block.timestamp === null && ev.ts !== null) {
76598
+ block.timestamp = ev.ts;
76599
+ }
76600
+ const { source: _s, sessionId: _sid, turnIndex: _t, ts: _ts, correlationExactness: _ce, ...cleanEv } = ev;
76601
+ block.events.push(cleanEv);
76602
+ }
76603
+ const sortedBlocks = Array.from(blocksByKey.values()).sort((a2, b) => {
76604
+ const aTs = a2.timestamp ? Date.parse(a2.timestamp) : Infinity;
76605
+ const bTs = b.timestamp ? Date.parse(b.timestamp) : Infinity;
76606
+ if (aTs !== bTs)
76607
+ return (Number.isNaN(aTs) ? Infinity : aTs) - (Number.isNaN(bTs) ? Infinity : bTs);
76608
+ return a2.key.localeCompare(b.key);
76609
+ });
75911
76610
  const totalBilled = totalFresh + totalOut;
75912
76611
  const startMs = firstTs ? Date.parse(firstTs) : 0;
75913
76612
  const endMs = lastTs ? Date.parse(lastTs) : startMs;
75914
76613
  const spanMs = Number.isFinite(startMs) && Number.isFinite(endMs) ? Math.max(0, endMs - startMs) : 0;
75915
- const sessionMeta = {
75916
- id: sessionId,
75917
- source,
75918
- model,
75919
- start: firstTs ?? new Date(0).toISOString(),
75920
- durationMs: spanMs > 0 ? spanMs : totalDuration,
76614
+ const firstSource = Array.from(uniqueSources)[0] ?? null;
76615
+ const firstModel = Array.from(uniqueModels)[0] ?? null;
76616
+ const scope = {
76617
+ sessionId: input.mode === "session" ? input.sessionId : null,
76618
+ source: input.mode === "session" ? input.source : uniqueSources.size === 1 ? firstSource : null,
76619
+ model: input.mode === "session" ? uniqueModels.size > 0 ? firstModel : null : uniqueModels.size === 1 ? firstModel : null,
76620
+ start: firstTs,
76621
+ end: lastTs,
76622
+ durationMs: input.mode === "session" && spanMs > 0 ? spanMs : totalDuration,
75921
76623
  tokens: {
75922
76624
  billedTokens: totalBilled,
75923
76625
  cacheSavedTokens: totalCache,
@@ -75926,11 +76628,14 @@ class LiveHistoryBoardService {
75926
76628
  outputTokens: totalOut
75927
76629
  },
75928
76630
  messageCount,
75929
- toolCallCount
76631
+ toolCallCount,
76632
+ sessionCount: input.mode === "session" ? 1 : uniqueSessions.size
75930
76633
  };
75931
76634
  return {
75932
- session: sessionMeta,
75933
- blocks: Array.from(blocksByTurn.values()).sort((a2, b) => a2.turnIndex - b.turnIndex)
76635
+ mode: input.mode,
76636
+ scope,
76637
+ truncated: queryResult.truncated,
76638
+ blocks: sortedBlocks
75934
76639
  };
75935
76640
  }
75936
76641
  async getSessions(input) {
@@ -76240,35 +76945,48 @@ import {
76240
76945
  readdirSync as readdirSync6,
76241
76946
  readFileSync as readFileSync8,
76242
76947
  readlinkSync,
76948
+ realpathSync as realpathSync3,
76243
76949
  rmSync as rmSync4,
76244
76950
  symlinkSync,
76245
76951
  unlinkSync as unlinkSync2,
76246
76952
  writeFileSync as writeFileSync4
76247
76953
  } from "fs";
76248
76954
  import { homedir as homedir5 } from "os";
76249
- import { dirname as dirname11, isAbsolute as isAbsolute3, join as join14, resolve as resolve4 } from "path";
76955
+ import { dirname as dirname11, isAbsolute as isAbsolute3, join as join14, resolve as resolve4, sep } from "path";
76250
76956
  async function buildRefreshCoverage(db2, selector, fanOut) {
76251
76957
  const statusBySource = new Map(fanOut.entries.map((e) => [e.source, e.status]));
76252
76958
  const refreshed = FULL_FIDELITY_SOURCES.filter((s3) => statusBySource.has(s3) && statusBySource.get(s3) !== "failed");
76253
76959
  const { since, until } = await dataWindow(db2, selector);
76254
76960
  return { refreshed, skipped: [...DEFERRED_SOURCES], window: { since, until } };
76255
76961
  }
76256
- function runSessionAugmentedRoots(source, home, cwd) {
76962
+ async function runSessionAugmentedRoots(source, home, cwd, dao2) {
76257
76963
  const roots = getSourceDefinition(source).defaultRoots.map((root) => resolve4(home, root));
76964
+ const runRoots = [];
76258
76965
  const runRoot = join14(cwd, ".spur", "run");
76259
76966
  if (!existsSync5(runRoot))
76260
- return roots;
76967
+ return { roots, runRoots };
76968
+ const sourcesByRun = new Map;
76969
+ for (const row of await dao2.listRunSources()) {
76970
+ const sources = sourcesByRun.get(row.run_id) ?? new Set;
76971
+ sources.add(row.source);
76972
+ sourcesByRun.set(row.run_id, sources);
76973
+ }
76261
76974
  for (const runId of readdirSync6(runRoot)) {
76262
76975
  const sessionsRoot = join14(runRoot, runId, "agent-sessions");
76263
76976
  if (!existsSync5(sessionsRoot))
76264
76977
  continue;
76978
+ const mappedSources = sourcesByRun.get(runId);
76265
76979
  for (const agent of readdirSync6(sessionsRoot)) {
76266
- if (agent === source || agent.startsWith(`${source}-`)) {
76267
- roots.push(join14(sessionsRoot, agent));
76268
- }
76980
+ const directMatch = agent === source || agent.startsWith(`${source}-`);
76981
+ const soleMappedSource = mappedSources?.size === 1 && mappedSources.has(source);
76982
+ if (!directMatch && !soleMappedSource)
76983
+ continue;
76984
+ const root = realpathSync3(join14(sessionsRoot, agent));
76985
+ roots.push(root);
76986
+ runRoots.push({ runId, root });
76269
76987
  }
76270
76988
  }
76271
- return roots;
76989
+ return { roots, runRoots };
76272
76990
  }
76273
76991
 
76274
76992
  class HistoryService {
@@ -76280,21 +76998,31 @@ class HistoryService {
76280
76998
  const parsedSource = parseSource(source);
76281
76999
  const mode = parseMode(opts.mode ?? (opts.file !== undefined ? "force-file" : "incremental"));
76282
77000
  const dryRun = opts.dryRun ?? false;
77001
+ const db2 = await this.ctx.getDb();
77002
+ const dao2 = new RunSessionDao(db2);
77003
+ const discovery = parsedSource !== "opencode" && opts.file === undefined && opts.root === undefined ? await runSessionAugmentedRoots(parsedSource, this.ctx.historyHome ?? homedir5(), this.ctx.cwd ?? process.cwd(), dao2) : undefined;
76283
77004
  const result = parsedSource === "opencode" && opts.file === undefined && opts.root === undefined ? await runOpenCodeImport({
76284
- db: await this.ctx.getDb(),
77005
+ db: db2,
76285
77006
  sourceDatabase: this.ctx.openCodeSourceDatabase,
76286
77007
  mode,
76287
77008
  dryRun
76288
77009
  }) : await runJsonlImport(parsedSource, {
76289
- db: await this.ctx.getDb(),
77010
+ db: db2,
76290
77011
  mode,
76291
- ...opts.file !== undefined && opts.file.length > 0 ? { files: [opts.file] } : opts.root !== undefined && opts.root.length > 0 ? { roots: [opts.root] } : {
76292
- roots: runSessionAugmentedRoots(parsedSource, this.ctx.historyHome ?? homedir5(), this.ctx.cwd ?? process.cwd())
76293
- },
77012
+ ...opts.file !== undefined && opts.file.length > 0 ? { files: [opts.file] } : opts.root !== undefined && opts.root.length > 0 ? { roots: [opts.root] } : { roots: discovery?.roots ?? [] },
76294
77013
  dryRun
76295
77014
  });
76296
77015
  if (!dryRun) {
76297
- await new RunSessionDao(await this.ctx.getDb()).alignMessageProvenance();
77016
+ for (const runRoot of discovery?.runRoots ?? []) {
77017
+ const sourceFilePrefix = runRoot.root.endsWith(sep) ? runRoot.root : `${runRoot.root}${sep}`;
77018
+ await dao2.observeImportedSessions({
77019
+ runId: runRoot.runId,
77020
+ source: parsedSource,
77021
+ sourceFilePrefix,
77022
+ resolvedAt: new Date().toISOString()
77023
+ });
77024
+ }
77025
+ await dao2.alignMessageProvenance();
76298
77026
  }
76299
77027
  return result;
76300
77028
  }
@@ -77649,7 +78377,7 @@ var init_process_inventory_service = __esm(() => {
77649
78377
  });
77650
78378
 
77651
78379
  // ../../packages/app/src/services/project-registry.ts
77652
- import { existsSync as existsSync6, mkdirSync as mkdirSync7, readFileSync as readFileSync9, realpathSync as realpathSync3, renameSync as renameSync4, rmSync as rmSync5, writeFileSync as writeFileSync5 } from "fs";
78380
+ import { existsSync as existsSync6, mkdirSync as mkdirSync7, readFileSync as readFileSync9, realpathSync as realpathSync4, renameSync as renameSync4, rmSync as rmSync5, writeFileSync as writeFileSync5 } from "fs";
77653
78381
  import { connect, createServer } from "net";
77654
78382
  import { homedir as homedir6 } from "os";
77655
78383
  import { dirname as dirname12, join as join15, resolve as resolve5 } from "path";
@@ -77665,7 +78393,7 @@ function normalizeProjectPath(pathInput) {
77665
78393
  }
77666
78394
  try {
77667
78395
  if (existsSync6(expanded)) {
77668
- return realpathSync3(expanded);
78396
+ return realpathSync4(expanded);
77669
78397
  }
77670
78398
  } catch {}
77671
78399
  return expanded;
@@ -82758,7 +83486,7 @@ var init_command_gate = __esm(() => {
82758
83486
  });
82759
83487
 
82760
83488
  // ../../packages/app/src/workflow/actions/doctor-probe.ts
82761
- import { normalize as normalize2, resolve as resolve10, sep } from "path";
83489
+ import { normalize as normalize2, resolve as resolve10, sep as sep2 } from "path";
82762
83490
  function splitSpurBin(spurBin) {
82763
83491
  if (SHELL_METACHARACTERS2.test(spurBin)) {
82764
83492
  return { error: `doctor.probe "spurBin" must not contain shell metacharacters (got ${spurBin})` };
@@ -82822,7 +83550,7 @@ class DoctorProbeActionRunner {
82822
83550
  const workdir = context4.workdir ?? process.cwd();
82823
83551
  const allowedDir = resolve10(workdir, ".spur", "run");
82824
83552
  const normalized = normalize2(resolve10(workdir, resultFileRaw));
82825
- const withinAllowed = normalized === allowedDir || normalized.startsWith(allowedDir + sep);
83553
+ const withinAllowed = normalized === allowedDir || normalized.startsWith(allowedDir + sep2);
82826
83554
  if (!withinAllowed) {
82827
83555
  return {
82828
83556
  ok: false,
@@ -84196,10 +84924,19 @@ class WorkflowAppService {
84196
84924
  };
84197
84925
  }
84198
84926
  async validate(file2, opts = {}) {
84199
- const absolute = resolve13(this.ctx.cwd, file2);
84200
- if (!await fileExists(absolute)) {
84201
- return { ok: false, valid: false, file: file2, errors: [`File not found: ${absolute}`] };
84927
+ const resolved = resolveWorkflowFile(this.ctx.cwd, file2);
84928
+ if (resolved.path === null) {
84929
+ const [probedProject, probedBundled] = resolved.probed;
84930
+ return {
84931
+ ok: false,
84932
+ valid: false,
84933
+ file: file2,
84934
+ errors: [
84935
+ `File not found: ${probedProject}${probedBundled !== null ? ` (bundled: ${probedBundled})` : ""}`
84936
+ ]
84937
+ };
84202
84938
  }
84939
+ const absolute = resolved.path;
84203
84940
  try {
84204
84941
  const embedded = this.embeddedSchemaOptions();
84205
84942
  const workflow = await loadWorkflowDef(absolute, {
@@ -84248,7 +84985,12 @@ class WorkflowAppService {
84248
84985
  }
84249
84986
  async run(file2, opts = {}) {
84250
84987
  const eventsBus = this.ctx.events?.();
84251
- const absolute = resolve13(this.ctx.cwd, file2);
84988
+ const resolved = resolveWorkflowFile(this.ctx.cwd, file2);
84989
+ if (resolved.path === null) {
84990
+ const [probedProject, probedBundled] = resolved.probed;
84991
+ throw new Error(`Workflow not found: ${probedProject}${probedBundled !== null ? ` (bundled: ${probedBundled})` : ""}`);
84992
+ }
84993
+ const absolute = resolved.path;
84252
84994
  const embedded = this.embeddedSchemaOptions();
84253
84995
  const workflow = await loadWorkflowDef(absolute, {
84254
84996
  validateSchema: true,
@@ -84308,7 +85050,10 @@ class WorkflowAppService {
84308
85050
  return;
84309
85051
  let workflowName;
84310
85052
  try {
84311
- const def = await loadWorkflowDef(resolve13(this.ctx.cwd, file2), { validateSchema: false });
85053
+ const resolved = resolveWorkflowFile(this.ctx.cwd, file2);
85054
+ if (resolved.path === null)
85055
+ return;
85056
+ const def = await loadWorkflowDef(resolved.path, { validateSchema: false });
84312
85057
  workflowName = def.name;
84313
85058
  } catch {
84314
85059
  return;
@@ -84821,6 +85566,21 @@ async function fileExists(path9) {
84821
85566
  const fs3 = createNodeFileSystem3();
84822
85567
  return await fs3.exists(path9);
84823
85568
  }
85569
+ function resolveWorkflowFile(cwd, file2) {
85570
+ const projectPath = resolve13(cwd, file2);
85571
+ if (existsSync10(projectPath)) {
85572
+ return { path: projectPath, source: "project" };
85573
+ }
85574
+ const bundledRoot = bundledConfigRoot();
85575
+ if (bundledRoot !== null) {
85576
+ const bundledPath = join22(bundledRoot, "workflows", basename7(file2));
85577
+ if (existsSync10(bundledPath)) {
85578
+ return { path: bundledPath, source: "bundled" };
85579
+ }
85580
+ return { path: null, probed: [projectPath, bundledPath] };
85581
+ }
85582
+ return { path: null, probed: [projectPath, null] };
85583
+ }
84824
85584
  async function resolveDefaultAgentVar(cwd, callerVars, warn) {
84825
85585
  const result = {};
84826
85586
  if (callerVars?.implementAgent === undefined && callerVars?.agent !== undefined) {
@@ -85823,6 +86583,7 @@ __export(exports_src2, {
85823
86583
  runHistoryReport: () => runHistoryReport,
85824
86584
  runCorpusCheck: () => runCorpusCheck,
85825
86585
  resolveWorkflowLogRetentionDays: () => resolveWorkflowLogRetentionDays,
86586
+ resolveWorkflowFile: () => resolveWorkflowFile,
85826
86587
  resolveSpurServeCommand: () => resolveSpurServeCommand,
85827
86588
  resolveRetentionQuotas: () => resolveRetentionQuotas,
85828
86589
  resolvePlanningFolders: () => resolvePlanningFolders,
@@ -86151,19 +86912,19 @@ var {
86151
86912
  init_src();
86152
86913
  init_loader();
86153
86914
 
86154
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/application-node.js
86915
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/application-node.js
86155
86916
  init_dist4();
86156
86917
  init_dist5();
86157
86918
  import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync5 } from "fs";
86158
86919
  import { dirname as dirname5 } from "path";
86159
86920
 
86160
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/application/index.js
86921
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/application/index.js
86161
86922
  init_default_observers();
86162
86923
  init_event_bus();
86163
86924
  init_file_observer();
86164
86925
  init_logger3();
86165
86926
 
86166
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/scheduler/noop.js
86927
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/scheduler/noop.js
86167
86928
  class NoopSchedulerAdapter {
86168
86929
  constructor() {}
86169
86930
  register(_cron, _action) {}
@@ -86171,7 +86932,7 @@ class NoopSchedulerAdapter {
86171
86932
  async stop() {}
86172
86933
  }
86173
86934
 
86174
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/scheduler/factory.js
86935
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/scheduler/factory.js
86175
86936
  function initScheduler(adapter, cronEntries) {
86176
86937
  const resolved = adapter ?? new NoopSchedulerAdapter;
86177
86938
  if (cronEntries) {
@@ -86182,7 +86943,7 @@ function initScheduler(adapter, cronEntries) {
86182
86943
  return resolved;
86183
86944
  }
86184
86945
 
86185
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/application/plugins/builtins.js
86946
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/application/plugins/builtins.js
86186
86947
  init_logger3();
86187
86948
  init_metrics();
86188
86949
  init_sdk();
@@ -86275,7 +87036,7 @@ function dbPlugin(db2) {
86275
87036
  };
86276
87037
  }
86277
87038
 
86278
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/application/plugins/host.js
87039
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/application/plugins/host.js
86279
87040
  init_logger3();
86280
87041
 
86281
87042
  class PluginHost {
@@ -86363,7 +87124,7 @@ class PluginHost {
86363
87124
  }
86364
87125
  }
86365
87126
 
86366
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/application/index.js
87127
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/application/index.js
86367
87128
  async function performShutdown(state, reason) {
86368
87129
  if (state.stopped)
86369
87130
  return;
@@ -86474,10 +87235,10 @@ async function runApplication(options) {
86474
87235
  }
86475
87236
  }
86476
87237
 
86477
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/application-node.js
87238
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/application-node.js
86478
87239
  init_scheduler_node();
86479
87240
 
86480
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
87241
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
86481
87242
  var import_api14 = __toESM(require_src(), 1);
86482
87243
 
86483
87244
  // ../../node_modules/.bun/@opentelemetry+exporter-metrics-otlp-http@0.218.0+e40b0dfdd726a224/node_modules/@opentelemetry/exporter-metrics-otlp-http/build/esm/OTLPMetricExporterBase.js
@@ -89493,7 +90254,7 @@ class OTLPTraceExporter extends import_otlp_exporter_base2.OTLPExporterBase {
89493
90254
  }), JsonTraceSerializer));
89494
90255
  }
89495
90256
  }
89496
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
90257
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
89497
90258
  var import_resources2 = __toESM(require_src4(), 1);
89498
90259
  var import_sdk_trace_node = __toESM(require_src8(), 1);
89499
90260
  var import_semantic_conventions = __toESM(require_src2(), 1);
@@ -89544,7 +90305,7 @@ async function shutdownNodeTelemetry() {
89544
90305
  await Promise.all(pending);
89545
90306
  }
89546
90307
 
89547
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/application-node.js
90308
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/application-node.js
89548
90309
  class ConfigValidationError extends Error {
89549
90310
  constructor(message) {
89550
90311
  super(message);
@@ -94215,9 +94976,9 @@ Done (local). Review, then push to release:`);
94215
94976
  }
94216
94977
  output2.write(`
94217
94978
  Pushing branch ${branch} (tags excluded)...`);
94218
- await git2(ctx.repoRoot, ["push", "origin", branch]);
94979
+ await git2(ctx.repoRoot, ["push", "--no-follow-tags", "origin", branch]);
94219
94980
  output2.write(`Pushing release trigger tag ${tag}...`);
94220
- await git2(ctx.repoRoot, ["push", "origin", tag]);
94981
+ await git2(ctx.repoRoot, ["push", "--no-follow-tags", "origin", tag]);
94221
94982
  output2.write(`
94222
94983
  Released ${version3}. The publish workflow should now be running:`);
94223
94984
  output2.write(` gh run list --workflow=${config4.publishWorkflow} --limit ${config4.ghRunListLimit}`);
@@ -94298,9 +95059,9 @@ Done (local). Review, then push to release:`);
94298
95059
  }
94299
95060
  output2.write(`
94300
95061
  Pushing branch ${branch} (tags excluded)...`);
94301
- await git2(ctx.repoRoot, ["push", "origin", branch]);
95062
+ await git2(ctx.repoRoot, ["push", "--no-follow-tags", "origin", branch]);
94302
95063
  output2.write(`Pushing release trigger tag ${aggregateTag}...`);
94303
- await git2(ctx.repoRoot, ["push", "origin", aggregateTag]);
95064
+ await git2(ctx.repoRoot, ["push", "--no-follow-tags", "origin", aggregateTag]);
94304
95065
  output2.write(`
94305
95066
  Released ${version3}. The publish workflow should now be running:`);
94306
95067
  output2.write(" gh run list --workflow=publish.yml --limit 3");
@@ -94489,8 +95250,7 @@ init_loader();
94489
95250
  init_src2();
94490
95251
  await init_src3();
94491
95252
  import { existsSync as existsSync12 } from "fs";
94492
- import { homedir as homedir9 } from "os";
94493
- import { join as join25, resolve as resolve16 } from "path";
95253
+ import { join as join25 } from "path";
94494
95254
 
94495
95255
  // src/workflow/resolve-spur-bin.ts
94496
95256
  import { basename as basename8 } from "path";
@@ -94508,11 +95268,6 @@ function resolveSpurBin() {
94508
95268
  }
94509
95269
 
94510
95270
  // src/workflow/make-lifecycle-adapter.ts
94511
- var GLOBAL_CONFIG_DIR = join25(".config", "spur");
94512
- function globalConfigRoot(context4) {
94513
- const override = context4.env.SPUR_GLOBAL_RULES_DIR;
94514
- return override !== undefined && override.length > 0 ? resolve16(context4.cwd, override) : join25(homedir9(), GLOBAL_CONFIG_DIR);
94515
- }
94516
95271
  function resolveWorkflowPath(context4, profile) {
94517
95272
  const bundledRoot = bundledConfigRoot();
94518
95273
  if (bundledRoot !== null) {
@@ -94523,9 +95278,6 @@ function resolveWorkflowPath(context4, profile) {
94523
95278
  const projectPath = join25(context4.cwd, ".spur", "workflows", `${profile.workflowName}.yaml`);
94524
95279
  if (existsSync12(projectPath))
94525
95280
  return projectPath;
94526
- const globalPath = join25(globalConfigRoot(context4), "workflows", `${profile.workflowName}.yaml`);
94527
- if (existsSync12(globalPath))
94528
- return globalPath;
94529
95281
  return null;
94530
95282
  }
94531
95283
  function makeLifecycleAdapter(context4, profile) {
@@ -94941,7 +95693,7 @@ import { createRequire } from "module";
94941
95693
  var CLI_CONFIG = {
94942
95694
  binaryName: "spur",
94943
95695
  binaryLabel: "spur",
94944
- binaryVersion: "0.3.58",
95696
+ binaryVersion: "0.3.61",
94945
95697
  configDir: ".spur",
94946
95698
  configFile: ".spur/config.yaml",
94947
95699
  databaseFile: ".spur/spur.db"
@@ -95215,24 +95967,17 @@ function formatDailyResult(r) {
95215
95967
  }
95216
95968
 
95217
95969
  // src/commands/init.ts
95970
+ init_src();
95218
95971
  init_loader();
95219
95972
  init_src2();
95220
95973
  init_dist10();
95221
- import { homedir as homedir10 } from "os";
95222
- import { join as join26, resolve as resolve17 } from "path";
95974
+ import { homedir as homedir9 } from "os";
95975
+ import { join as join26, resolve as resolve16 } from "path";
95223
95976
 
95224
95977
  // src/config/scaffold-manifest.ts
95225
95978
  var SCAFFOLD_MANIFEST = [
95226
95979
  { source: "rules/recommended-pre-check.yaml", target: "rules/recommended-pre-check.yaml" },
95227
95980
  { source: "rules/recommended-post-check.yaml", target: "rules/recommended-post-check.yaml" },
95228
- { source: "workflows/basic.yaml", target: "workflows/basic.yaml" },
95229
- { source: "workflows/task-lifecycle.yaml", target: "workflows/task-lifecycle.yaml" },
95230
- { source: "workflows/feature-lifecycle.yaml", target: "workflows/feature-lifecycle.yaml" },
95231
- { source: "workflows/feature-dev.yaml", target: "workflows/feature-dev.yaml" },
95232
- { source: "workflows/task-pipeline.yaml", target: "workflows/task-pipeline.yaml" },
95233
- { source: "workflows/idea-pipeline.yaml", target: "workflows/idea-pipeline.yaml" },
95234
- { source: "workflows/wrapup-pipeline.yaml", target: "workflows/wrapup-pipeline.yaml" },
95235
- { source: "workflows/pr-review.yaml", target: "workflows/pr-review.yaml" },
95236
95981
  { source: "tasks/section-matrix.yaml", target: "tasks/section-matrix.yaml" },
95237
95982
  { source: "templates/task/standard.md", target: "tasks/templates/standard.md" },
95238
95983
  { source: "templates/task/feature-impl.md", target: "tasks/templates/feature-impl.md" },
@@ -95240,9 +95985,6 @@ var SCAFFOLD_MANIFEST = [
95240
95985
  { source: "templates/task/review.md", target: "tasks/templates/review.md" },
95241
95986
  { source: "templates/task/brainstorm.md", target: "tasks/templates/brainstorm.md" },
95242
95987
  { source: "templates/task/meta.md", target: "tasks/templates/meta.md" },
95243
- { source: "templates/feature/default.md", target: "templates/feature/default.md" },
95244
- { source: "templates/bdd/gherkin.md", target: "templates/bdd/gherkin.md" },
95245
- { source: "templates/bdd/checklist.md", target: "templates/bdd/checklist.md" },
95246
95988
  {
95247
95989
  source: "templates/docs/99_PROJECT_CONSTITUTION.md",
95248
95990
  target: "docs/99_PROJECT_CONSTITUTION.md",
@@ -95255,20 +95997,13 @@ var SCAFFOLD_MANIFEST = [
95255
95997
  { source: "templates/docs/03_ARCHITECTURE.md", target: "docs/03_ARCHITECTURE.md", root: true, preserve: true },
95256
95998
  { source: "templates/docs/04_DESIGN.md", target: "docs/04_DESIGN.md", root: true, preserve: true },
95257
95999
  { source: "templates/docs/05_FEATURES.md", target: "docs/05_FEATURES.md", root: true, preserve: true },
95258
- { source: "templates/docs/99_PROJECT_CONSTITUTION.md", target: "templates/docs/99_PROJECT_CONSTITUTION.md" },
95259
- { source: "templates/docs/00_ADR.md", target: "templates/docs/00_ADR.md" },
95260
- { source: "templates/docs/01_PRD.md", target: "templates/docs/01_PRD.md" },
95261
- { source: "templates/docs/02_ROADMAP.md", target: "templates/docs/02_ROADMAP.md" },
95262
- { source: "templates/docs/03_ARCHITECTURE.md", target: "templates/docs/03_ARCHITECTURE.md" },
95263
- { source: "templates/docs/04_DESIGN.md", target: "templates/docs/04_DESIGN.md" },
95264
- { source: "templates/docs/05_FEATURES.md", target: "templates/docs/05_FEATURES.md" },
95265
96000
  { source: "templates/AGENTS.md", target: "AGENTS.md", root: true, preserve: true }
95266
96001
  ];
95267
96002
 
95268
96003
  // src/commands/init.ts
95269
- var GLOBAL_CONFIG_DIR2 = join26(".config", "spur");
95270
- var GLOBAL_RULES_DIR2 = join26(GLOBAL_CONFIG_DIR2, "rules");
95271
- var GLOBAL_CONFIG_EXAMPLE = "config.example.yaml";
96004
+ var GLOBAL_CONFIG_DIR = join26(".config", "spur");
96005
+ var GLOBAL_RULES_DIR2 = join26(GLOBAL_CONFIG_DIR, "rules");
96006
+ var GLOBAL_CONFIG_EXAMPLE = BUNDLED_GLOBAL_CONFIG;
95272
96007
  var GLOBAL_CONFIG_FILE2 = "config.yaml";
95273
96008
  var INDEXED_CONTEXT_MARKER = "## Indexed context";
95274
96009
  function substituteAgentsMdTemplate(content, projectName) {
@@ -95298,7 +96033,7 @@ If \`.spur/context/\` is absent, proceed normally. Never block work on its absen
95298
96033
  `;
95299
96034
  function globalRulesRoot(context4) {
95300
96035
  const override = context4.env.SPUR_GLOBAL_RULES_DIR;
95301
- return override !== undefined && override.length > 0 ? resolve17(context4.cwd, override) : join26(homedir10(), GLOBAL_RULES_DIR2);
96036
+ return override !== undefined && override.length > 0 ? resolve16(context4.cwd, override) : join26(homedir9(), GLOBAL_RULES_DIR2);
95302
96037
  }
95303
96038
  async function writeIfNew(context4, path9, content, force, result) {
95304
96039
  if (!force && await context4.fs.exists(path9)) {
@@ -95324,12 +96059,15 @@ async function seedGlobalRules(context4) {
95324
96059
  }
95325
96060
  return written;
95326
96061
  }
96062
+ function resolveGlobalConfigDir(context4) {
96063
+ const globalOverride = context4.env.SPUR_GLOBAL_RULES_DIR;
96064
+ return globalOverride !== undefined && globalOverride.length > 0 ? resolve16(context4.cwd, globalOverride) : join26(homedir9(), GLOBAL_CONFIG_DIR);
96065
+ }
95327
96066
  async function seedGlobalConfig(context4) {
95328
96067
  const source = bundledConfigRoot();
95329
96068
  if (source === null)
95330
96069
  return 0;
95331
- const globalOverride = context4.env.SPUR_GLOBAL_RULES_DIR;
95332
- const target = globalOverride !== undefined && globalOverride.length > 0 ? resolve17(context4.cwd, globalOverride) : join26(homedir10(), GLOBAL_CONFIG_DIR2);
96070
+ const target = resolveGlobalConfigDir(context4);
95333
96071
  let written = 0;
95334
96072
  for (const relPath of listBundledConfigFiles()) {
95335
96073
  if (relPath === GLOBAL_CONFIG_EXAMPLE)
@@ -95351,25 +96089,107 @@ async function seedGlobalConfig(context4) {
95351
96089
  return written;
95352
96090
  }
95353
96091
  function registerInitCommand(program2, context4, options = {}) {
95354
- program2.command("init", { hidden: options.hidden === true }).summary("scaffold a local Spur project").option(...SHARED_OPTIONS.nameProjectInit).option(...SHARED_OPTIONS.forceInitRecreate).option("--minimal", "Only write the minimal .spur scaffold").option(...SHARED_OPTIONS.json).action(async (options2) => {
96092
+ program2.command("init", { hidden: options.hidden === true }).summary("scaffold a local Spur project").option(...SHARED_OPTIONS.nameProjectInit).option(...SHARED_OPTIONS.forceInitRecreate).option("--minimal", "Only write the minimal .spur scaffold").option("--adopt-global-config", "Also rewrite ~/.config/spur/config.yaml from the shipped global default (backed up first)").option(...SHARED_OPTIONS.json).action(async (options2) => {
95355
96093
  const json3 = options2.json === true;
95356
96094
  const force = options2.force === true;
95357
96095
  const minimal = options2.minimal === true;
96096
+ const adoptGlobal = options2.adoptGlobalConfig === true;
95358
96097
  const projectName = options2.name ?? "default";
95359
96098
  const configPath = join26(context4.cwd, CLI_CONFIG.configFile);
96099
+ const result = { created: [], skipped: [] };
96100
+ const globalConfigDir = resolveGlobalConfigDir(context4);
96101
+ const globalConfigPath = join26(globalConfigDir, GLOBAL_CONFIG_FILE2);
96102
+ const globalConfigExists = await context4.fs.exists(globalConfigPath);
96103
+ let misplacedKeys = [];
96104
+ if (globalConfigExists) {
96105
+ try {
96106
+ const raw = await context4.fs.readFile(globalConfigPath);
96107
+ misplacedKeys = misplacedGlobalKeys(parseConfigYaml2(raw));
96108
+ } catch {}
96109
+ }
95360
96110
  if (!force && await context4.fs.exists(configPath)) {
95361
- const message = `Already initialized: ${CLI_CONFIG.configFile}. Use --force to overwrite.`;
95362
- context4.output.write(json3 ? toJson2({ ok: false, reason: "already-initialized", config: CLI_CONFIG.configFile }) : message);
95363
- context4.setExitCode(1);
96111
+ const configRoot = bundledConfigRoot();
96112
+ if (configRoot !== null && !minimal) {
96113
+ for (const relPath of listBundledProjectSeedFiles()) {
96114
+ const sourcePath = join26(configRoot, relPath);
96115
+ if (!await context4.fs.exists(sourcePath))
96116
+ continue;
96117
+ const targetPath = join26(context4.cwd, CLI_CONFIG.configDir, relPath);
96118
+ await context4.fs.ensureDir(join26(targetPath, ".."));
96119
+ await writeIfNew(context4, targetPath, await context4.fs.readFile(sourcePath), false, result);
96120
+ }
96121
+ for (const entry of SCAFFOLD_MANIFEST) {
96122
+ const sourcePath = join26(configRoot, entry.source);
96123
+ if (!await context4.fs.exists(sourcePath))
96124
+ continue;
96125
+ const baseDir = entry.root === true ? context4.cwd : join26(context4.cwd, CLI_CONFIG.configDir);
96126
+ const targetPath = join26(baseDir, entry.target);
96127
+ await context4.fs.ensureDir(join26(targetPath, ".."));
96128
+ const entryForce = false;
96129
+ let body = await context4.fs.readFile(sourcePath);
96130
+ if (entry.target === "AGENTS.md") {
96131
+ body = substituteAgentsMdTemplate(body, projectName);
96132
+ }
96133
+ if (entry.source.startsWith("templates/docs/")) {
96134
+ body = substituteDocTemplateTokens(body);
96135
+ }
96136
+ await writeIfNew(context4, targetPath, body, entryForce, result);
96137
+ }
96138
+ }
96139
+ let adoptedGlobal = false;
96140
+ if (adoptGlobal && globalConfigExists) {
96141
+ const backupPath = `${globalConfigPath}.bak-${new Date().toISOString().replace(/[:.]/g, "-")}`;
96142
+ await context4.fs.writeFile(backupPath, await context4.fs.readFile(globalConfigPath));
96143
+ const bundledRoot = bundledConfigRoot();
96144
+ const examplePath = bundledRoot !== null ? join26(bundledRoot, GLOBAL_CONFIG_EXAMPLE) : null;
96145
+ if (examplePath !== null && await context4.fs.exists(examplePath)) {
96146
+ await context4.fs.writeFile(globalConfigPath, await context4.fs.readFile(examplePath));
96147
+ adoptedGlobal = true;
96148
+ }
96149
+ result.created.push(backupPath);
96150
+ }
96151
+ const rulesSeeded2 = await seedGlobalRules(context4);
96152
+ const configSeeded2 = await seedGlobalConfig(context4);
96153
+ const payload = {
96154
+ ok: true,
96155
+ converged: true,
96156
+ config: CLI_CONFIG.configFile,
96157
+ ...result,
96158
+ globalRulesSeeded: rulesSeeded2,
96159
+ globalConfigSeeded: configSeeded2,
96160
+ ...adoptedGlobal ? { adoptGlobalConfig: adoptedGlobal } : {},
96161
+ ...misplacedKeys.length > 0 ? { misplacedGlobalKeys: misplacedKeys } : {}
96162
+ };
96163
+ if (json3) {
96164
+ context4.output.write(toJson2(payload));
96165
+ } else {
96166
+ context4.output.write("Already initialized \u2014 converged (no project files overwritten)");
96167
+ for (const path9 of result.created)
96168
+ context4.output.write(` \u2713 ${path9}`);
96169
+ for (const path9 of result.skipped)
96170
+ context4.output.write(` - ${path9} (exists)`);
96171
+ if (rulesSeeded2 > 0) {
96172
+ context4.output.write(` \u2713 seeded ${rulesSeeded2} rule file(s) to ~/${GLOBAL_RULES_DIR2}`);
96173
+ }
96174
+ if (configSeeded2 > 0) {
96175
+ context4.output.write(` \u2713 seeded ${configSeeded2} config file(s) to ~/${GLOBAL_CONFIG_DIR}`);
96176
+ }
96177
+ if (adoptedGlobal) {
96178
+ context4.output.write(" \u2713 adopted global config from bundled default (backup written)");
96179
+ }
96180
+ if (misplacedKeys.length > 0) {
96181
+ context4.output.write(` \u26A0 global config carries project-shaped key(s): ${misplacedKeys.join(", ")}`);
96182
+ }
96183
+ }
96184
+ context4.setExitCode(0);
95364
96185
  return;
95365
96186
  }
95366
- const result = { created: [], skipped: [] };
95367
96187
  const configYaml = `${[
95368
96188
  `# Spur project configuration for ${projectName}`,
95369
96189
  `# Generated by \`spur init\``,
95370
96190
  "",
95371
96191
  '$schema: "@gobing-ai/spur/schemas/spur-config.schema.json"',
95372
- `version: "1.1"`,
96192
+ `version: "1.2"`,
95373
96193
  `name: ${projectName}`,
95374
96194
  "",
95375
96195
  "bootstrap:",
@@ -95417,8 +96237,6 @@ ${contextEntry}
95417
96237
  const configRoot = bundledConfigRoot();
95418
96238
  if (configRoot !== null) {
95419
96239
  for (const relPath of listBundledProjectSeedFiles()) {
95420
- if (relPath.startsWith("templates/docs/"))
95421
- continue;
95422
96240
  const sourcePath = join26(configRoot, relPath);
95423
96241
  if (!await context4.fs.exists(sourcePath))
95424
96242
  continue;
@@ -95477,7 +96295,7 @@ ${contextEntry}
95477
96295
  context4.output.write(` \u2713 seeded ${rulesSeeded} rule file(s) to ~/${GLOBAL_RULES_DIR2}`);
95478
96296
  }
95479
96297
  if (configSeeded > 0) {
95480
- context4.output.write(` \u2713 seeded ${configSeeded} config file(s) to ~/${GLOBAL_CONFIG_DIR2}`);
96298
+ context4.output.write(` \u2713 seeded ${configSeeded} config file(s) to ~/${GLOBAL_CONFIG_DIR}`);
95481
96299
  }
95482
96300
  }
95483
96301
  });
@@ -95690,15 +96508,15 @@ async function runMessageWatch(svc, output2, options, runtime = {}) {
95690
96508
  }
95691
96509
  }
95692
96510
  function defaultSleep(ms, signal) {
95693
- return new Promise((resolve18) => {
96511
+ return new Promise((resolve17) => {
95694
96512
  if (signal?.aborted) {
95695
- resolve18();
96513
+ resolve17();
95696
96514
  return;
95697
96515
  }
95698
- const timer = setTimeout(resolve18, ms);
96516
+ const timer = setTimeout(resolve17, ms);
95699
96517
  signal?.addEventListener("abort", () => {
95700
96518
  clearTimeout(timer);
95701
- resolve18();
96519
+ resolve17();
95702
96520
  }, { once: true });
95703
96521
  });
95704
96522
  }
@@ -95725,15 +96543,15 @@ function parseTimeout2(raw) {
95725
96543
  return n3;
95726
96544
  }
95727
96545
  function sendSleep(ms, signal) {
95728
- return new Promise((resolve18) => {
96546
+ return new Promise((resolve17) => {
95729
96547
  if (signal?.aborted) {
95730
- resolve18();
96548
+ resolve17();
95731
96549
  return;
95732
96550
  }
95733
- const timer = setTimeout(resolve18, ms);
96551
+ const timer = setTimeout(resolve17, ms);
95734
96552
  signal?.addEventListener("abort", () => {
95735
96553
  clearTimeout(timer);
95736
- resolve18();
96554
+ resolve17();
95737
96555
  }, { once: true });
95738
96556
  });
95739
96557
  }
@@ -95803,12 +96621,12 @@ function registerMigrateCommand(program2, context4, options = {}) {
95803
96621
  // src/commands/projects.ts
95804
96622
  init_dist5();
95805
96623
  await init_src3();
95806
- import { basename as basename9, resolve as resolve18 } from "path";
96624
+ import { basename as basename9, resolve as resolve17 } from "path";
95807
96625
  function registerProjectsCommand(program2, context4) {
95808
96626
  const projectsCmd = program2.command("projects").summary("manage the Spur multi-project registry");
95809
96627
  projectsCmd.command("add").argument("<path>", "Project root directory path").option(...SHARED_OPTIONS.nameProjectDisplay).option(...SHARED_OPTIONS.jsonProjectsResponse).action(async (pathArg, options) => {
95810
96628
  try {
95811
- const absolutePath = resolve18(context4.cwd, pathArg);
96629
+ const absolutePath = resolve17(context4.cwd, pathArg);
95812
96630
  if (!await context4.fs.exists(absolutePath)) {
95813
96631
  throw new Error(`Directory does not exist: ${absolutePath}`);
95814
96632
  }
@@ -96516,8 +97334,8 @@ class EventPublisher {
96516
97334
  if (bufferedEvents.length > 0) {
96517
97335
  return { done: false, value: bufferedEvents.shift() };
96518
97336
  }
96519
- return new Promise((resolve19, reject) => {
96520
- pullResolvers.push([resolve19, reject]);
97337
+ return new Promise((resolve18, reject) => {
97338
+ pullResolvers.push([resolve18, reject]);
96521
97339
  });
96522
97340
  }, async () => {
96523
97341
  unsubscribe();
@@ -102210,44 +103028,68 @@ var historyTimelineEventKindEnum = exports_external.enum([
102210
103028
  "assistant",
102211
103029
  "unknown"
102212
103030
  ]);
103031
+ var historyDurationSourceEnum = exports_external.enum(["measured", "inferred", "unmeasured"]);
103032
+ var historyCorrelationExactnessEnum = exports_external.enum(["exact", "estimated"]);
103033
+ var historyTimelineInputSchema = exports_external.discriminatedUnion("mode", [
103034
+ exports_external.object({
103035
+ mode: exports_external.literal("session"),
103036
+ source: exports_external.string().min(1),
103037
+ sessionId: exports_external.string().min(1)
103038
+ }),
103039
+ exports_external.object({
103040
+ mode: exports_external.literal("consolidated"),
103041
+ filter: historyFilterSchema.optional(),
103042
+ taskWbs: exports_external.string().optional(),
103043
+ runId: exports_external.string().optional()
103044
+ })
103045
+ ]);
102213
103046
  var historyTimelineEventSchema = exports_external.object({
102214
103047
  seq: exports_external.number(),
102215
103048
  eventType: exports_external.enum(["message", "tool"]),
102216
103049
  kind: historyTimelineEventKindEnum,
102217
103050
  title: exports_external.string(),
102218
- durationMs: exports_external.number(),
103051
+ toolName: exports_external.string().nullable(),
103052
+ durationMs: exports_external.number().nullable(),
103053
+ durationSource: historyDurationSourceEnum,
102219
103054
  tokens: exports_external.number(),
102220
103055
  freshInputTokens: exports_external.number(),
102221
103056
  cacheReadTokens: exports_external.number(),
102222
103057
  outputTokens: exports_external.number(),
103058
+ promptTokens: historyTokensSchema.nullable(),
102223
103059
  exitCode: exports_external.number().nullable(),
102224
103060
  payload: exports_external.string().nullable(),
102225
103061
  agent: exports_external.string(),
102226
103062
  model: exports_external.string()
102227
103063
  });
102228
103064
  var historyTimelineBlockSchema = exports_external.object({
103065
+ key: exports_external.string(),
103066
+ sessionId: exports_external.string(),
102229
103067
  turnIndex: exports_external.number(),
102230
- timestamp: exports_external.string(),
103068
+ timestamp: exports_external.string().nullable(),
102231
103069
  source: exports_external.string(),
102232
103070
  model: exports_external.string(),
103071
+ correlationExactness: historyCorrelationExactnessEnum.nullable(),
102233
103072
  totalDurationMs: exports_external.number(),
102234
103073
  totalTokens: exports_external.number(),
102235
103074
  operationCount: exports_external.number(),
102236
103075
  events: exports_external.array(historyTimelineEventSchema)
102237
103076
  });
102238
- var historyTimelineSessionMetaSchema = exports_external.object({
102239
- id: exports_external.string(),
102240
- source: exports_external.string(),
102241
- model: exports_external.string(),
102242
- modelDetail: exports_external.string().optional(),
102243
- start: exports_external.string(),
103077
+ var historyTimelineScopeSchema = exports_external.object({
103078
+ sessionId: exports_external.string().nullable(),
103079
+ source: exports_external.string().nullable(),
103080
+ model: exports_external.string().nullable(),
103081
+ start: exports_external.string().nullable(),
103082
+ end: exports_external.string().nullable(),
102244
103083
  durationMs: exports_external.number(),
102245
103084
  tokens: historyTokensSchema,
102246
103085
  messageCount: exports_external.number(),
102247
- toolCallCount: exports_external.number()
103086
+ toolCallCount: exports_external.number(),
103087
+ sessionCount: exports_external.number()
102248
103088
  });
102249
103089
  var historyTimelineResponseDataSchema = exports_external.object({
102250
- session: historyTimelineSessionMetaSchema,
103090
+ mode: exports_external.enum(["session", "consolidated"]),
103091
+ scope: historyTimelineScopeSchema,
103092
+ truncated: exports_external.boolean(),
102251
103093
  blocks: exports_external.array(historyTimelineBlockSchema)
102252
103094
  });
102253
103095
  var historyTimelineResponseSchema = apiSuccessSchema(historyTimelineResponseDataSchema);
@@ -102392,11 +103234,11 @@ var historyContract = {
102392
103234
  tags: ["history"]
102393
103235
  }).input(historyFilterSchema.optional()).output(historySummaryResponseSchema),
102394
103236
  getTimeline: oc.route({
102395
- method: "GET",
102396
- path: "/history/timeline/{sessionId}",
102397
- summary: "Get chronological session execution timeline",
103237
+ method: "POST",
103238
+ path: "/history/timeline",
103239
+ summary: "Get chronological session or consolidated execution timeline",
102398
103240
  tags: ["history"]
102399
- }).input(exports_external.object({ sessionId: exports_external.string() })).output(historyTimelineResponseSchema),
103241
+ }).input(historyTimelineInputSchema).output(historyTimelineResponseSchema),
102400
103242
  getSessions: oc.route({
102401
103243
  method: "POST",
102402
103244
  path: "/history/sessions",
@@ -102806,7 +103648,7 @@ function createHistoryHandlers(ctx) {
102806
103648
  return { ok: true, data };
102807
103649
  }),
102808
103650
  getTimeline: os3.history.getTimeline.handler(async ({ input }) => {
102809
- const data = await ctx.historyBoardService().getTimeline(input.sessionId);
103651
+ const data = await ctx.historyBoardService().getTimeline(input);
102810
103652
  return { ok: true, data };
102811
103653
  }),
102812
103654
  getSessions: os3.history.getSessions.handler(async ({ input }) => {
@@ -106422,7 +107264,6 @@ var spur_config_schema_default = {
106422
107264
  title: "Spur Project Configuration",
106423
107265
  description: "Schema for .spur/config.yaml \u2014 the single project configuration surface consumed by spur and (future) spur-server.",
106424
107266
  type: "object",
106425
- required: ["version", "name"],
106426
107267
  properties: {
106427
107268
  $schema: {
106428
107269
  type: "string",
@@ -106430,7 +107271,7 @@ var spur_config_schema_default = {
106430
107271
  },
106431
107272
  version: {
106432
107273
  type: "string",
106433
- description: "Config schema version (string, not integer). Current recommended: '1.1' (ADR-033 executor tiers + planning blocks). '1' remains accepted for backward compatibility."
107274
+ description: "Config schema version (string, not integer). Current recommended: '1.2' (config-1.2 layered global/project merge, ADR-033 executor tiers + planning blocks). '1' remains accepted for backward compatibility."
106434
107275
  },
106435
107276
  name: {
106436
107277
  type: "string",
@@ -108462,7 +109303,7 @@ init_dist6();
108462
109303
  init_dist5();
108463
109304
  await init_src3();
108464
109305
  import { closeSync as closeSync5, fstatSync as fstatSync3, openSync as openSync5, readSync as readSync3 } from "fs";
108465
- import { join as join34, resolve as resolve19 } from "path";
109306
+ import { join as join34 } from "path";
108466
109307
  import { createInterface } from "readline";
108467
109308
  import { setTimeout as sleep5 } from "timers/promises";
108468
109309
 
@@ -108772,8 +109613,11 @@ Monitor with: spur workflow trace ${runId2} --follow`);
108772
109613
  let planPreview;
108773
109614
  if (options.plan !== false) {
108774
109615
  try {
108775
- const def = await loadWorkflowDef(resolve19(context4.cwd, file2), { validateSchema: false });
108776
- planPreview = renderRunPlan(def);
109616
+ const resolved = resolveWorkflowFile(context4.cwd, file2);
109617
+ if (resolved.path !== null) {
109618
+ const def = await loadWorkflowDef(resolved.path, { validateSchema: false });
109619
+ planPreview = renderRunPlan(def);
109620
+ }
108777
109621
  } catch {}
108778
109622
  }
108779
109623
  const runLog = options.log === false ? undefined : new WorkflowRunLogSink({
@@ -108828,10 +109672,13 @@ Monitor with: spur workflow trace ${runId2} --follow`);
108828
109672
  const steeringController = options.steer === true ? await (async () => {
108829
109673
  let identity7;
108830
109674
  try {
108831
- const def = await loadWorkflowDef(resolve19(context4.cwd, file2), {
108832
- validateSchema: false
108833
- });
108834
- identity7 = createWorkflowEventIdentity(def);
109675
+ const resolved = resolveWorkflowFile(context4.cwd, file2);
109676
+ if (resolved.path !== null) {
109677
+ const def = await loadWorkflowDef(resolved.path, {
109678
+ validateSchema: false
109679
+ });
109680
+ identity7 = createWorkflowEventIdentity(def);
109681
+ }
108835
109682
  } catch {}
108836
109683
  return new WorkflowSteeringController((ack) => {
108837
109684
  bus.emit("workflow.steering", identity7 === undefined ? ack : decorateWorkflowEvent(identity7, "workflow.steering", ack));
@@ -108998,7 +109845,14 @@ Monitor with: spur workflow trace ${runId2} --follow`);
108998
109845
  }
108999
109846
  });
109000
109847
  workflow.command("show").description("Render a workflow definition as a mermaid FSM diagram.").argument("<file>", "Workflow YAML file").action(async (file2) => {
109001
- const filePath = resolve19(context4.cwd, file2);
109848
+ const resolved = resolveWorkflowFile(context4.cwd, file2);
109849
+ if (resolved.path === null) {
109850
+ const [probedProject, probedBundled] = resolved.probed;
109851
+ context4.output.error(`workflow show: file not found: ${probedProject}${probedBundled !== null ? ` (bundled: ${probedBundled})` : ""}`);
109852
+ context4.setExitCode(1);
109853
+ return;
109854
+ }
109855
+ const filePath = resolved.path;
109002
109856
  let def;
109003
109857
  try {
109004
109858
  def = await loadWorkflowDef(filePath, { validateSchema: true });
@@ -109312,7 +110166,7 @@ init_src();
109312
110166
  init_src2();
109313
110167
  init_dist5();
109314
110168
  await init_src3();
109315
- import { dirname as dirname22, join as join35, resolve as resolve20 } from "path";
110169
+ import { dirname as dirname22, join as join35, resolve as resolve18 } from "path";
109316
110170
  import { isatty as isatty4 } from "tty";
109317
110171
 
109318
110172
  // ../../node_modules/.bun/@clack+core@1.4.1/node_modules/@clack/core/dist/index.mjs
@@ -110727,7 +111581,7 @@ function resolveAgentRoles(agentConfig) {
110727
111581
  return resolved;
110728
111582
  }
110729
111583
  function createCliContext(options) {
110730
- const cwd = resolve20(options.cwd ?? process.cwd());
111584
+ const cwd = resolve18(options.cwd ?? process.cwd());
110731
111585
  const env = options.env ?? process.env;
110732
111586
  const fs3 = createNodeFileSystem3(cwd);
110733
111587
  const agentRoles = options.agentRoles ?? resolveAgentRoles(options.agentConfig);