@gobing-ai/spur 0.3.58 → 0.3.60

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 (60) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/config.global.yaml +133 -0
  3. package/package.json +9 -9
  4. package/plugins/sp/plugin.json +1 -1
  5. package/schemas/spur-config.schema.json +0 -1
  6. package/spur.js +1188 -454
  7. package/web/_astro/BoardApp.BJs3l7O8.js +179 -0
  8. package/web/_astro/BoardApp.D8InuCYx.js +1 -0
  9. package/web/_astro/{TaskDetail.DHjEt5vl.js → TaskDetail.B0l1uzsB.js} +1 -1
  10. package/web/_astro/{arc.XgRC1Ij_.js → arc.DPruHC3P.js} +1 -1
  11. package/web/_astro/{architectureDiagram-3BPJPVTR.DOZWrfHc.js → architectureDiagram-3BPJPVTR.CuOqAck6.js} +1 -1
  12. package/web/_astro/{blockDiagram-GPEHLZMM.ClQnCGf_.js → blockDiagram-GPEHLZMM.Cxb7HDIA.js} +1 -1
  13. package/web/_astro/{c4Diagram-AAUBKEIU.CKCtUD0Y.js → c4Diagram-AAUBKEIU.Dw7wa-0S.js} +1 -1
  14. package/web/_astro/channel.XCf1DcsL.js +1 -0
  15. package/web/_astro/{chunk-2J33WTMH.c7J8OHq5.js → chunk-2J33WTMH.MECQitzo.js} +1 -1
  16. package/web/_astro/{chunk-4BX2VUAB.C-A1Dv27.js → chunk-4BX2VUAB.p3ofhIGE.js} +1 -1
  17. package/web/_astro/{chunk-55IACEB6.C4kGGALB.js → chunk-55IACEB6.BmQGsPZP.js} +1 -1
  18. package/web/_astro/{chunk-727SXJPM.Bith2NHt.js → chunk-727SXJPM.CwrK23OA.js} +1 -1
  19. package/web/_astro/{chunk-AQP2D5EJ.qeSXhsVY.js → chunk-AQP2D5EJ.CUKI_QXp.js} +1 -1
  20. package/web/_astro/{chunk-FMBD7UC4.DdQQnTAy.js → chunk-FMBD7UC4.7AtDgShM.js} +1 -1
  21. package/web/_astro/{chunk-ND2GUHAM.BZYQVeZd.js → chunk-ND2GUHAM.f_YJbTs3.js} +1 -1
  22. package/web/_astro/{chunk-QZHKN3VN.BiUWwHaV.js → chunk-QZHKN3VN.0q7V3gEg.js} +1 -1
  23. package/web/_astro/{classDiagram-4FO5ZUOK.OGRhcldh.js → classDiagram-4FO5ZUOK.C_hG3HMK.js} +1 -1
  24. package/web/_astro/{classDiagram-v2-Q7XG4LA2.OGRhcldh.js → classDiagram-v2-Q7XG4LA2.C_hG3HMK.js} +1 -1
  25. package/web/_astro/{cose-bilkent-S5V4N54A.DxYklM_j.js → cose-bilkent-S5V4N54A.vsaaaEMy.js} +1 -1
  26. package/web/_astro/{dagre-BM42HDAG.BSb2dEbo.js → dagre-BM42HDAG.BN7XFqQ4.js} +1 -1
  27. package/web/_astro/{diagram-2AECGRRQ.mOrItPK2.js → diagram-2AECGRRQ.ED6AfryZ.js} +1 -1
  28. package/web/_astro/{diagram-5GNKFQAL.C99r7J3C.js → diagram-5GNKFQAL.Dxllzg8R.js} +1 -1
  29. package/web/_astro/{diagram-KO2AKTUF.BKbnisJO.js → diagram-KO2AKTUF.RuWppieD.js} +1 -1
  30. package/web/_astro/{diagram-LMA3HP47.D8FJGo4V.js → diagram-LMA3HP47.CL32Xn6s.js} +1 -1
  31. package/web/_astro/{diagram-OG6HWLK6.DVBs7n4Q.js → diagram-OG6HWLK6.CUneEhqB.js} +1 -1
  32. package/web/_astro/{erDiagram-TEJ5UH35.CddMTl4l.js → erDiagram-TEJ5UH35.DI-92Lec.js} +1 -1
  33. package/web/_astro/{flowDiagram-I6XJVG4X.B7WclnjQ.js → flowDiagram-I6XJVG4X.69Aqa1FF.js} +1 -1
  34. package/web/_astro/{ganttDiagram-6RSMTGT7.CRh7ggvz.js → ganttDiagram-6RSMTGT7.DdpClZpa.js} +1 -1
  35. package/web/_astro/{gitGraphDiagram-PVQCEYII.du-L7V8A.js → gitGraphDiagram-PVQCEYII.xqWfkvB4.js} +1 -1
  36. package/web/_astro/index.DJl2RAVZ.css +1 -0
  37. package/web/_astro/{infoDiagram-5YYISTIA.CClGl9Px.js → infoDiagram-5YYISTIA.B3G5sfKm.js} +1 -1
  38. package/web/_astro/{ishikawaDiagram-YF4QCWOH.BuTETIPz.js → ishikawaDiagram-YF4QCWOH.ahVNsoAQ.js} +1 -1
  39. package/web/_astro/{journeyDiagram-JHISSGLW.Cyg1zCiE.js → journeyDiagram-JHISSGLW.PmFHLc-X.js} +1 -1
  40. package/web/_astro/{kanban-definition-UN3LZRKU.aH8eDXwX.js → kanban-definition-UN3LZRKU.Co1qOPTd.js} +1 -1
  41. package/web/_astro/{linear.paE_RY_i.js → linear.DoHZ-iRt.js} +1 -1
  42. package/web/_astro/{mermaid.core.BhdKkI85.js → mermaid.core.DNRElYN2.js} +4 -4
  43. package/web/_astro/{mindmap-definition-RKZ34NQL.aZNfv8Nx.js → mindmap-definition-RKZ34NQL.CdfJZidJ.js} +1 -1
  44. package/web/_astro/{pieDiagram-4H26LBE5.5psni0hC.js → pieDiagram-4H26LBE5.C1A8dby4.js} +1 -1
  45. package/web/_astro/{quadrantDiagram-W4KKPZXB.DcGPGrFd.js → quadrantDiagram-W4KKPZXB.NmZqjG_c.js} +1 -1
  46. package/web/_astro/{requirementDiagram-4Y6WPE33.BwPD2lzi.js → requirementDiagram-4Y6WPE33.tY36zYtK.js} +1 -1
  47. package/web/_astro/{sankeyDiagram-5OEKKPKP.B3jGVk0l.js → sankeyDiagram-5OEKKPKP.rOEGZYjo.js} +1 -1
  48. package/web/_astro/{sequenceDiagram-3UESZ5HK.BdWsx3LW.js → sequenceDiagram-3UESZ5HK.Dpnw3S9J.js} +1 -1
  49. package/web/_astro/{stateDiagram-AJRCARHV.DRpG4ClZ.js → stateDiagram-AJRCARHV.DGpvQ3Wz.js} +1 -1
  50. package/web/_astro/{stateDiagram-v2-BHNVJYJU.Su0ML9Wo.js → stateDiagram-v2-BHNVJYJU.CbwQdEfu.js} +1 -1
  51. package/web/_astro/{timeline-definition-PNZ67QCA.Cg_Uv8A5.js → timeline-definition-PNZ67QCA.DAYUpUJT.js} +1 -1
  52. package/web/_astro/{vennDiagram-CIIHVFJN.DVouKT4b.js → vennDiagram-CIIHVFJN.C7JCCd6-.js} +1 -1
  53. package/web/_astro/{wardley-L42UT6IY.CexIVQli.js → wardley-L42UT6IY.BGgwOH5_.js} +1 -1
  54. package/web/_astro/{wardleyDiagram-YWT4CUSO.ChSAzcvx.js → wardleyDiagram-YWT4CUSO.oIZqzI2l.js} +1 -1
  55. package/web/_astro/{xychartDiagram-2RQKCTM6.CN-Yp50J.js → xychartDiagram-2RQKCTM6.DohcJzqm.js} +1 -1
  56. package/web/index.html +2 -2
  57. package/web/_astro/BoardApp.CrusGeQ4.js +0 -1
  58. package/web/_astro/BoardApp.P8SRAD5Q.js +0 -179
  59. package/web/_astro/channel.CmK546kO.js +0 -1
  60. 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,
@@ -37878,7 +37878,7 @@ var init_src = __esm(() => {
37878
37878
  });
37879
37879
  });
37880
37880
 
37881
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/config.js
37881
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/config.js
37882
37882
  function parseYamlObject(text3) {
37883
37883
  let parsed;
37884
37884
  try {
@@ -38005,7 +38005,7 @@ var init_config2 = __esm(() => {
38005
38005
  };
38006
38006
  });
38007
38007
 
38008
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
38008
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
38009
38009
  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
38010
  import { dirname as dirname2, resolve as resolvePath3 } from "path";
38011
38011
  function createNodeFileSystem3(root, paths) {
@@ -38092,7 +38092,7 @@ function findProjectRoot3(startDir) {
38092
38092
  }
38093
38093
  var init_file_system_node2 = () => {};
38094
38094
 
38095
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/db-errors.js
38095
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/db-errors.js
38096
38096
  var D1NotConfiguredError2, DbModuleNotInstalledError3;
38097
38097
  var init_db_errors2 = __esm(() => {
38098
38098
  D1NotConfiguredError2 = class D1NotConfiguredError2 extends Error {
@@ -38109,7 +38109,7 @@ var init_db_errors2 = __esm(() => {
38109
38109
  };
38110
38110
  });
38111
38111
 
38112
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/file-system-cf.js
38112
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/file-system-cf.js
38113
38113
  function createCfFileSystem2() {
38114
38114
  return {
38115
38115
  getProjectRoot: () => "/bundle",
@@ -38148,7 +38148,7 @@ function createCfFileSystem2() {
38148
38148
  }
38149
38149
  var UNSUPPORTED = "FileSystem is not available on Cloudflare Workers. Use D1, KV, or R2 for persistent storage.";
38150
38150
 
38151
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/runtime-cf.js
38151
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/runtime-cf.js
38152
38152
  var exports_runtime_cf = {};
38153
38153
  __export(exports_runtime_cf, {
38154
38154
  cloudflareWorkersFactory: () => cloudflareWorkersFactory2
@@ -38186,7 +38186,7 @@ var init_runtime_cf = __esm(() => {
38186
38186
  };
38187
38187
  });
38188
38188
 
38189
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/process-executor.js
38189
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/process-executor.js
38190
38190
  import { isatty as isatty2 } from "tty";
38191
38191
  function processEventSeverity2(reason, exitCode) {
38192
38192
  if (reason === "error")
@@ -38597,7 +38597,7 @@ var init_process_executor2 = __esm(() => {
38597
38597
  ProcessExecutor2 = NodeProcessExecutor3;
38598
38598
  });
38599
38599
 
38600
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/runtime-node-bun.js
38600
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/runtime-node-bun.js
38601
38601
  var exports_runtime_node_bun = {};
38602
38602
  __export(exports_runtime_node_bun, {
38603
38603
  nodeBunFactory: () => nodeBunFactory3,
@@ -38665,7 +38665,7 @@ var init_runtime_node_bun2 = __esm(() => {
38665
38665
  };
38666
38666
  });
38667
38667
 
38668
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/platform.js
38668
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/platform.js
38669
38669
  function isCloudflareWorkerRuntime2() {
38670
38670
  return globalThis.navigator?.userAgent?.startsWith("Cloudflare-Workers") ?? false;
38671
38671
  }
@@ -38695,7 +38695,7 @@ function _resetRuntimeFactory2() {
38695
38695
  }
38696
38696
  var _factory, _runtimeName;
38697
38697
 
38698
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/context.js
38698
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/context.js
38699
38699
  class RuntimeContext2 {
38700
38700
  scope;
38701
38701
  runtimeName;
@@ -38785,7 +38785,7 @@ var init_context2 = __esm(() => {
38785
38785
  init_runtime_node_bun2();
38786
38786
  });
38787
38787
 
38788
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/path.js
38788
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/path.js
38789
38789
  function normalizeSeparators2(path7) {
38790
38790
  return path7.replaceAll("\\", "/");
38791
38791
  }
@@ -38908,7 +38908,7 @@ var init_path2 = __esm(() => {
38908
38908
  SEP2 = globalThis.process?.platform === "win32" ? "\\" : "/";
38909
38909
  });
38910
38910
 
38911
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/fs.js
38911
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/fs.js
38912
38912
  async function ensureDirForFile2(path7, fs2 = createNodeFileSystem3()) {
38913
38913
  await fs2.ensureDir(dirnamePath(path7));
38914
38914
  }
@@ -38976,7 +38976,7 @@ var init_fs = __esm(() => {
38976
38976
  init_path2();
38977
38977
  });
38978
38978
 
38979
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/process-registry.js
38979
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/process-registry.js
38980
38980
  function allocateId() {
38981
38981
  nextIdSeq += 1;
38982
38982
  return `pe_${Date.now().toString(36)}_${nextIdSeq.toString(36)}`;
@@ -39100,7 +39100,7 @@ function createInMemoryProcessRegistry2(options) {
39100
39100
  }
39101
39101
  var nextIdSeq = 0;
39102
39102
 
39103
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/runtime-paths.js
39103
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/runtime-paths.js
39104
39104
  function ambientRuntimePaths2() {
39105
39105
  const cwd = getProcessCwd2();
39106
39106
  return { cwd, home: getHomeDir() ?? cwd };
@@ -39110,7 +39110,7 @@ var init_runtime_paths = __esm(() => {
39110
39110
  init_path2();
39111
39111
  });
39112
39112
 
39113
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/schema-validation.js
39113
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/schema-validation.js
39114
39114
  async function loadStructuredConfig(path7, options = {}) {
39115
39115
  const content = await (options.fileSystem ?? createNodeFileSystem3()).readFile(path7);
39116
39116
  return await parseStructuredConfig(content, path7, options);
@@ -39393,10 +39393,10 @@ var init_schema_validation2 = __esm(() => {
39393
39393
  defaultResolve = typeof Bun !== "undefined" ? (specifier, from) => Bun.resolveSync(specifier, from) : undefined;
39394
39394
  });
39395
39395
 
39396
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/types.js
39396
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/types.js
39397
39397
  var init_types2 = () => {};
39398
39398
 
39399
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/index.js
39399
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/index.js
39400
39400
  var exports_dist2 = {};
39401
39401
  __export(exports_dist2, {
39402
39402
  writeJsonFile: () => writeJsonFile2,
@@ -39520,13 +39520,22 @@ function walk(dir, relPrefix, filter = /\.(ya?ml|json)$/i) {
39520
39520
  }
39521
39521
  return acc;
39522
39522
  }
39523
+ function isDroppedFromProjectSeed(rel) {
39524
+ if (rel === BUNDLED_GLOBAL_CONFIG)
39525
+ return true;
39526
+ if (rel.startsWith("templates/task/"))
39527
+ return true;
39528
+ if (rel.startsWith("plugins/"))
39529
+ return true;
39530
+ return !rel.includes("/") && rel.endsWith(".json");
39531
+ }
39523
39532
  function listBundledProjectSeedFiles() {
39524
39533
  const root = bundledConfigRoot();
39525
39534
  if (root === null)
39526
39535
  return [];
39527
- return walk(root, "", PROJECT_SEED_FILTER).filter((rel) => rel !== BUNDLED_CONFIG_EXAMPLE).sort();
39536
+ return walk(root, "", PROJECT_SEED_FILTER).filter((rel) => !isDroppedFromProjectSeed(rel)).sort();
39528
39537
  }
39529
- var BUNDLED_CONFIG_DIRS, cachedRoot, PROJECT_SEED_FILTER, BUNDLED_CONFIG_EXAMPLE = "config.example.yaml";
39538
+ var BUNDLED_CONFIG_DIRS, cachedRoot, PROJECT_SEED_FILTER, BUNDLED_GLOBAL_CONFIG = "config.global.yaml";
39530
39539
  var init_bundled_config = __esm(() => {
39531
39540
  BUNDLED_CONFIG_DIRS = ["config", "spur-cli/config"];
39532
39541
  PROJECT_SEED_FILTER = /\.(ya?ml|json|md|gitkeep)$/i;
@@ -39572,15 +39581,19 @@ function resolveSchemaSpecifier(specifier, manifestSpecifier) {
39572
39581
  return specifier;
39573
39582
  }
39574
39583
  }
39575
- function resolveConfigFile(cwd) {
39584
+ function resolveConfigLayers(cwd) {
39585
+ const layers = {};
39576
39586
  const projectConfig = join3(cwd ?? process.cwd(), SPUR_CONFIG_DIR, SPUR_CONFIG_FILE);
39577
39587
  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;
39588
+ layers.project = projectConfig;
39589
+ if (process.env.SPUR_SKIP_GLOBAL_CONFIG !== "true" && existsSync4(GLOBAL_CONFIG_FILE)) {
39590
+ layers.global = GLOBAL_CONFIG_FILE;
39591
+ }
39592
+ return layers;
39593
+ }
39594
+ function resolveConfigFile(cwd) {
39595
+ const { global: global3, project } = resolveConfigLayers(cwd);
39596
+ return project ?? global3;
39584
39597
  }
39585
39598
  function makeEmbeddedReader(embeddedSchemas) {
39586
39599
  return async function readEmbeddedOrDisk(path8) {
@@ -39596,17 +39609,22 @@ function makeEmbeddedReader(embeddedSchemas) {
39596
39609
  };
39597
39610
  }
39598
39611
  async function loadSpurConfig(cwd = process.cwd(), opts) {
39599
- const configPath = resolveConfigFile(cwd);
39600
- if (configPath === undefined) {
39612
+ const layers = resolveConfigLayers(cwd);
39613
+ if (layers.global === undefined && layers.project === undefined) {
39601
39614
  return spurConfigSchema.parse({});
39602
39615
  }
39603
39616
  const validateJsonSchema2 = opts?.validateJsonSchema ?? true;
39604
- const mtimeMs = statSync5(configPath).mtimeMs;
39605
- const key = `${cacheKey(configPath, opts, validateJsonSchema2)}\x00${mtimeMs}`;
39617
+ const mtimeOf = (path8) => path8 !== undefined ? String(statSync5(path8).mtimeMs) : "-";
39618
+ const key = [
39619
+ cacheKey(layers.project ?? layers.global ?? "", opts, validateJsonSchema2),
39620
+ layers.global ?? "-",
39621
+ mtimeOf(layers.project),
39622
+ mtimeOf(layers.global)
39623
+ ].join("\x00");
39606
39624
  const cached2 = spurConfigCache.get(key);
39607
39625
  if (cached2 !== undefined)
39608
39626
  return cached2;
39609
- const promise2 = loadSpurConfigFile(configPath, opts, validateJsonSchema2);
39627
+ const promise2 = loadMergedConfig(layers, opts, validateJsonSchema2);
39610
39628
  spurConfigCache.set(key, promise2);
39611
39629
  promise2.catch(() => spurConfigCache.delete(key));
39612
39630
  return promise2;
@@ -39632,30 +39650,228 @@ function expandTeamTildes(config4) {
39632
39650
  }
39633
39651
  return { ...config4, agent: { ...config4.agent, team: expanded } };
39634
39652
  }
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`;
39653
+ function schemaValidationContext(opts) {
39654
+ const embeddedSchemas = opts?.embeddedSchemas;
39655
+ const manifestSpecifier = opts?.schemaManifestSpecifier ?? "@gobing-ai/spur/package.json";
39656
+ const resolve = (specifier) => {
39657
+ if (embeddedSchemas !== undefined && specifier === manifestSpecifier) {
39658
+ return `${EMBEDDED_PREFIX}/package.json`;
39659
+ }
39660
+ return resolveSchemaSpecifier(specifier, manifestSpecifier);
39661
+ };
39662
+ const fileSystem = embeddedSchemas ? { readFile: makeEmbeddedReader(embeddedSchemas) } : undefined;
39663
+ return { resolve, ...fileSystem !== undefined ? { fileSystem } : {} };
39664
+ }
39665
+ async function readRawYamlLayer(configPath, kind) {
39666
+ const nodeFs = createNodeFileSystem3();
39667
+ let text3;
39668
+ try {
39669
+ text3 = await nodeFs.readFile(nodeFs.resolve(configPath));
39670
+ } catch (error51) {
39671
+ throw new Error(`Failed to read ${kind} config ${configPath}: ${error51.message}`);
39672
+ }
39673
+ try {
39674
+ return $parse(text3) ?? {};
39675
+ } catch (error51) {
39676
+ throw new Error(`Failed to parse ${kind} config ${configPath}: ${error51.message}`);
39677
+ }
39678
+ }
39679
+ function isPlainObject6(value) {
39680
+ return typeof value === "object" && value !== null && !Array.isArray(value);
39681
+ }
39682
+ function memberIdentityOf(item) {
39683
+ if (typeof item === "string")
39684
+ return item;
39685
+ if (isPlainObject6(item)) {
39686
+ if (typeof item.id === "string")
39687
+ return item.id;
39688
+ if (typeof item.executor === "string")
39689
+ return item.executor;
39690
+ }
39691
+ return;
39692
+ }
39693
+ function executorNameOf(item) {
39694
+ return isPlainObject6(item) && typeof item.name === "string" ? item.name : undefined;
39695
+ }
39696
+ function isConcatPath(segments) {
39697
+ return segments.length === 2 && segments[0] === "rules" && segments[1] === "paths" || segments.length === 2 && segments[0] === "workflows" && segments[1] === "paths";
39698
+ }
39699
+ function byKeyIdentityFor(segments) {
39700
+ if (segments.length === 2 && segments[0] === "agent" && segments[1] === "executors") {
39701
+ return executorNameOf;
39702
+ }
39703
+ if (segments.length === 4 && segments[0] === "agent" && segments[1] === "team" && segments[3] === "members") {
39704
+ return memberIdentityOf;
39705
+ }
39706
+ return;
39707
+ }
39708
+ function concatUnique(globalItems, projectItems) {
39709
+ const out = [...globalItems];
39710
+ for (const item of projectItems) {
39711
+ if (!out.includes(item))
39712
+ out.push(item);
39713
+ }
39714
+ return out;
39715
+ }
39716
+ function mergeByKeyIdentity(globalItems, projectItems, identityOf, segments) {
39717
+ const merged = [];
39718
+ const indexByIdentity = new Map;
39719
+ for (const item of globalItems) {
39720
+ const identity4 = identityOf(item);
39721
+ if (identity4 === undefined || !indexByIdentity.has(identity4)) {
39722
+ if (identity4 !== undefined)
39723
+ indexByIdentity.set(identity4, merged.length);
39724
+ merged.push(item);
39725
+ }
39726
+ }
39727
+ for (const item of projectItems) {
39728
+ const identity4 = identityOf(item);
39729
+ const existing = identity4 === undefined ? undefined : indexByIdentity.get(identity4);
39730
+ if (existing === undefined) {
39731
+ if (identity4 !== undefined)
39732
+ indexByIdentity.set(identity4, merged.length);
39733
+ merged.push(item);
39734
+ continue;
39735
+ }
39736
+ const base2 = merged[existing];
39737
+ merged[existing] = isPlainObject6(base2) && isPlainObject6(item) ? mergeDeep(base2, item, [...segments, existing]) : item;
39738
+ }
39739
+ return merged;
39740
+ }
39741
+ function mergeDeep(globalValue, projectValue, segments) {
39742
+ if (isPlainObject6(globalValue) && isPlainObject6(projectValue)) {
39743
+ const out = { ...globalValue };
39744
+ for (const [key, projectItem] of Object.entries(projectValue)) {
39745
+ out[key] = key in out ? mergeDeep(out[key], projectItem, [...segments, key]) : projectItem;
39746
+ }
39747
+ return out;
39748
+ }
39749
+ if (Array.isArray(globalValue) && Array.isArray(projectValue)) {
39750
+ if (isConcatPath(segments))
39751
+ return concatUnique(globalValue, projectValue);
39752
+ const identityOf = byKeyIdentityFor(segments);
39753
+ if (identityOf !== undefined)
39754
+ return mergeByKeyIdentity(globalValue, projectValue, identityOf, segments);
39755
+ return projectValue;
39756
+ }
39757
+ return projectValue;
39758
+ }
39759
+ function mergeSpurConfigLayers(globalRaw, projectRaw) {
39760
+ return mergeDeep(globalRaw, projectRaw, []);
39761
+ }
39762
+ function formatZodPath(path8) {
39763
+ return path8.map((segment, index2) => typeof segment === "number" ? `[${segment}]` : index2 === 0 ? segment : `.${segment}`).join("");
39764
+ }
39765
+ function parseViolationPath(path8) {
39766
+ const segments = [];
39767
+ for (const part of path8.split(".")) {
39768
+ const bracket = part.indexOf("[");
39769
+ const key = bracket === -1 ? part : part.slice(0, bracket);
39770
+ if (key !== "")
39771
+ segments.push(key);
39772
+ if (bracket !== -1) {
39773
+ for (const match of part.slice(bracket).matchAll(/\[(\d+)\]/g)) {
39774
+ segments.push(Number(match[1]));
39775
+ }
39776
+ }
39777
+ }
39778
+ return segments;
39779
+ }
39780
+ function findItemByIdentity(node, identityOf, identity4) {
39781
+ return Array.isArray(node) ? node.find((entry) => identityOf(entry) === identity4) : undefined;
39782
+ }
39783
+ function describeIssueProvenance(issuePath, merged, globalRaw, projectRaw) {
39784
+ let g = globalRaw;
39785
+ let p = projectRaw;
39786
+ let m = merged;
39787
+ let segments = [];
39788
+ let parentG = globalRaw;
39789
+ let parentP = projectRaw;
39790
+ let identityPrefix = "";
39791
+ for (const segment of issuePath) {
39792
+ parentG = g;
39793
+ parentP = p;
39794
+ segments = [...segments, segment];
39795
+ if (typeof segment === "number") {
39796
+ const mergedItem = Array.isArray(m) ? m[segment] : undefined;
39797
+ const identityOf = byKeyIdentityFor(segments.slice(0, -1));
39798
+ if (identityOf !== undefined && mergedItem !== undefined) {
39799
+ const identity4 = identityOf(mergedItem);
39800
+ if (identity4 !== undefined) {
39801
+ identityPrefix = `${segments.length === 3 ? "executor" : "member"} "${identity4}" `;
39802
+ g = findItemByIdentity(g, identityOf, identity4);
39803
+ p = findItemByIdentity(p, identityOf, identity4);
39804
+ }
39805
+ } else {
39806
+ g = Array.isArray(g) && segment < g.length ? g[segment] : undefined;
39807
+ p = Array.isArray(p) && segment < p.length ? p[segment] : undefined;
39643
39808
  }
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
- });
39809
+ m = mergedItem;
39810
+ continue;
39811
+ }
39812
+ g = isPlainObject6(g) ? g[segment] : undefined;
39813
+ p = isPlainObject6(p) ? p[segment] : undefined;
39814
+ m = isPlainObject6(m) ? m[segment] : undefined;
39815
+ }
39816
+ let label;
39817
+ if (g !== undefined && p !== undefined) {
39818
+ label = "set in both layers (project value wins)";
39819
+ } else if (g !== undefined) {
39820
+ label = "from global layer";
39821
+ } else if (p !== undefined) {
39822
+ label = "from project layer";
39823
+ } else if (parentP !== undefined && parentG === undefined) {
39824
+ label = "from project layer (key absent there)";
39825
+ } else if (parentG !== undefined && parentP === undefined) {
39826
+ label = "from global layer (key absent there)";
39652
39827
  } else {
39653
- const nodeFs = createNodeFileSystem3();
39654
- const resolved = nodeFs.resolve(configPath);
39655
- const text3 = await nodeFs.readFile(resolved);
39656
- raw = $parse(text3) ?? {};
39828
+ label = "missing in both layers";
39657
39829
  }
39658
- return expandTeamTildes(spurConfigSchema.parse(raw));
39830
+ return `${identityPrefix}${label}`;
39831
+ }
39832
+ function parseMergedWithProvenance(merged, globalRaw, projectRaw, layers) {
39833
+ try {
39834
+ return spurConfigSchema.parse(merged);
39835
+ } catch (error51) {
39836
+ if (!(error51 instanceof ZodError))
39837
+ throw error51;
39838
+ const details = error51.issues.map((issue2) => {
39839
+ const path8 = issue2.path.filter((segment) => typeof segment !== "symbol");
39840
+ return ` ${formatZodPath(path8)}: ${issue2.message} (${describeIssueProvenance(path8, merged, globalRaw, projectRaw)})`;
39841
+ }).join(`
39842
+ `);
39843
+ throw new Error(`Spur config validation failed after merging global ${layers.global ?? "(absent)"} with project ${layers.project ?? "(absent)"}:
39844
+ ${details}`);
39845
+ }
39846
+ }
39847
+ function enrichSchemaViolationError(error51, merged, globalRaw, projectRaw, layers) {
39848
+ const violations = error51.violations;
39849
+ if (!Array.isArray(violations))
39850
+ return error51;
39851
+ const details = violations.map((violation) => {
39852
+ const v = violation;
39853
+ const path8 = typeof v.path === "string" ? v.path : "(root)";
39854
+ const message = typeof v.message === "string" ? v.message : "schema violation";
39855
+ const label = describeIssueProvenance(parseViolationPath(path8), merged, globalRaw, projectRaw);
39856
+ return ` ${path8}: ${message} (${label})`;
39857
+ }).join(`
39858
+ `);
39859
+ return new Error(`Merged Spur config failed JSON Schema validation (global ${layers.global ?? "(absent)"} + project ${layers.project ?? "(absent)"}):
39860
+ ${details}`);
39861
+ }
39862
+ async function loadMergedConfig(layers, opts, validateJsonSchema2) {
39863
+ const globalRaw = layers.global !== undefined ? await readRawYamlLayer(layers.global, "global") : {};
39864
+ const projectRaw = layers.project !== undefined ? await readRawYamlLayer(layers.project, "project") : {};
39865
+ const merged = mergeSpurConfigLayers(globalRaw, projectRaw);
39866
+ if (validateJsonSchema2) {
39867
+ const source = layers.project ?? layers.global ?? "";
39868
+ try {
39869
+ await validateDeclaredJsonSchema(merged, source, schemaValidationContext(opts));
39870
+ } catch (error51) {
39871
+ throw enrichSchemaViolationError(error51, merged, globalRaw, projectRaw, layers);
39872
+ }
39873
+ }
39874
+ return expandTeamTildes(parseMergedWithProvenance(merged, globalRaw, projectRaw, layers));
39659
39875
  }
39660
39876
  async function loadStructuredSpurConfig(configPath, opts) {
39661
39877
  const validateJsonSchema2 = opts?.validateJsonSchema ?? true;
@@ -39665,19 +39881,9 @@ async function loadStructuredSpurConfig(configPath, opts) {
39665
39881
  const text3 = await nodeFs.readFile(resolved);
39666
39882
  return $parse(text3) ?? {};
39667
39883
  }
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
39884
  return await loadStructuredConfig(configPath, {
39678
39885
  validateSchema: true,
39679
- resolve: resolveFn,
39680
- ...fileSystem !== undefined ? { fileSystem } : {}
39886
+ ...schemaValidationContext(opts)
39681
39887
  });
39682
39888
  }
39683
39889
  function defaultFoldersConfig() {
@@ -39735,6 +39941,7 @@ var SPUR_CONFIG_DIR = ".spur", SPUR_CONFIG_FILE = "config.yaml", GLOBAL_CONFIG_F
39735
39941
  var init_loader = __esm(() => {
39736
39942
  init_dist5();
39737
39943
  init_dist2();
39944
+ init_zod();
39738
39945
  init_src();
39739
39946
  init_bundled_config();
39740
39947
  init_template_renderer();
@@ -41547,7 +41754,7 @@ var init_mod = __esm(() => {
41547
41754
  init_config3();
41548
41755
  });
41549
41756
 
41550
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/logger.js
41757
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/logger.js
41551
41758
  function toLogTapeLevel(level) {
41552
41759
  return level === "warn" ? "warning" : level;
41553
41760
  }
@@ -43100,7 +43307,7 @@ var require_src = __commonJS((exports) => {
43100
43307
  };
43101
43308
  });
43102
43309
 
43103
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/telemetry/sdk.js
43310
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/telemetry/sdk.js
43104
43311
  function getTelemetryConfig(configPartial = {}) {
43105
43312
  return {
43106
43313
  enabled: configPartial.enabled ?? CONFIG_DEFAULTS.enabled,
@@ -43136,7 +43343,7 @@ var init_sdk = __esm(() => {
43136
43343
  resolvedConfig = getTelemetryConfig();
43137
43344
  });
43138
43345
 
43139
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/telemetry/tracing.js
43346
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/telemetry/tracing.js
43140
43347
  function isSuppressed(tracer2) {
43141
43348
  return tracer2 === undefined && !getResolvedConfig().enabled;
43142
43349
  }
@@ -43176,7 +43383,7 @@ var init_tracing2 = __esm(() => {
43176
43383
  import_api2 = __toESM(require_src(), 1);
43177
43384
  });
43178
43385
 
43179
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/telemetry/metrics.js
43386
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/telemetry/metrics.js
43180
43387
  function getMeter() {
43181
43388
  return import_api3.metrics.getMeter(METER_NAME, METER_VERSION);
43182
43389
  }
@@ -43273,7 +43480,7 @@ var init_metrics = __esm(() => {
43273
43480
  instruments = {};
43274
43481
  });
43275
43482
 
43276
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/event-bus/event-bus.js
43483
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/event-bus/event-bus.js
43277
43484
  function busLogger() {
43278
43485
  if (!_busLogger)
43279
43486
  _busLogger = getLogger2("event-bus");
@@ -43526,7 +43733,7 @@ var init_event_bus = __esm(() => {
43526
43733
  init_metrics();
43527
43734
  });
43528
43735
 
43529
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/event-bus/default-observers.js
43736
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/event-bus/default-observers.js
43530
43737
  function obsLogger() {
43531
43738
  if (!_obsLogger)
43532
43739
  _obsLogger = getLogger2("event-bus.observers");
@@ -43590,7 +43797,7 @@ var init_default_observers = __esm(() => {
43590
43797
  init_event_bus();
43591
43798
  });
43592
43799
 
43593
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/event-bus/file-observer.js
43800
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/event-bus/file-observer.js
43594
43801
  function parentDir(filePath) {
43595
43802
  const idx = filePath.lastIndexOf("/");
43596
43803
  return idx <= 0 ? "." : filePath.slice(0, idx);
@@ -43688,7 +43895,7 @@ var init_file_observer = __esm(() => {
43688
43895
  init_logger3();
43689
43896
  });
43690
43897
 
43691
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/internals/drain.js
43898
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/internals/drain.js
43692
43899
  function settleWithin(promise2, deadline) {
43693
43900
  const remaining = deadline - Date.now();
43694
43901
  if (remaining <= 0)
@@ -43703,7 +43910,7 @@ function settleWithin(promise2, deadline) {
43703
43910
  return settled;
43704
43911
  }
43705
43912
 
43706
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/scheduler/node.js
43913
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/scheduler/node.js
43707
43914
  function parseInterval(cron) {
43708
43915
  const trimmed = cron.trim();
43709
43916
  const num = Number(trimmed);
@@ -43797,7 +44004,7 @@ var init_node3 = __esm(() => {
43797
44004
  init_metrics();
43798
44005
  });
43799
44006
 
43800
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/scheduler-node.js
44007
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/scheduler-node.js
43801
44008
  var exports_scheduler_node = {};
43802
44009
  __export(exports_scheduler_node, {
43803
44010
  NodeSchedulerAdapter: () => NodeSchedulerAdapter
@@ -46202,7 +46409,7 @@ var require_lodash_merge = __commonJS((exports) => {
46202
46409
  var hasOwnProperty = objectProto.hasOwnProperty;
46203
46410
  var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
46204
46411
  var nativeObjectToString = objectProto.toString;
46205
- function isPlainObject6(value) {
46412
+ function isPlainObject7(value) {
46206
46413
  if (!isObjectLike(value) || baseGetTag(value) !== objectTag) {
46207
46414
  return false;
46208
46415
  }
@@ -46213,7 +46420,7 @@ var require_lodash_merge = __commonJS((exports) => {
46213
46420
  const Ctor = hasOwnProperty.call(proto, "constructor") && proto.constructor;
46214
46421
  return typeof Ctor == "function" && Ctor instanceof Ctor && funcToString.call(Ctor) === objectCtorString;
46215
46422
  }
46216
- exports.isPlainObject = isPlainObject6;
46423
+ exports.isPlainObject = isPlainObject7;
46217
46424
  function isObjectLike(value) {
46218
46425
  return value != null && typeof value == "object";
46219
46426
  }
@@ -50483,14 +50690,32 @@ function buildMessageWhereClauses(sel, alias3) {
50483
50690
  clauses.push(`${alias3}.session_id = ?`);
50484
50691
  params.push(sel.sessionId);
50485
50692
  }
50486
- if (sel.runId != null) {
50487
- clauses.push(`${alias3}.provenance = 'spur-run'`);
50488
- clauses.push(`${alias3}.run_id = ?`);
50693
+ if (sel.runId != null && sel.taskWbs != null) {
50694
+ clauses.push(`EXISTS (
50695
+ SELECT 1 FROM history_run_session hrs_scope
50696
+ JOIN task_run_links trl_scope ON trl_scope.run_id = hrs_scope.run_id
50697
+ WHERE hrs_scope.run_id = ? AND trl_scope.wbs = ?
50698
+ AND hrs_scope.session_id IS NOT NULL
50699
+ AND hrs_scope.source = ${alias3}.source
50700
+ AND hrs_scope.session_id = ${alias3}.session_id
50701
+ )`);
50702
+ params.push(sel.runId, sel.taskWbs);
50703
+ } else if (sel.runId != null) {
50704
+ clauses.push(`EXISTS (
50705
+ SELECT 1 FROM history_run_session hrs_scope
50706
+ WHERE hrs_scope.run_id = ? AND hrs_scope.session_id IS NOT NULL
50707
+ AND hrs_scope.source = ${alias3}.source
50708
+ AND hrs_scope.session_id = ${alias3}.session_id
50709
+ )`);
50489
50710
  params.push(sel.runId);
50490
- }
50491
- if (sel.taskWbs != null) {
50492
- clauses.push(`${alias3}.provenance = 'spur-run'`);
50493
- clauses.push(`${alias3}.task_wbs = ?`);
50711
+ } else if (sel.taskWbs != null) {
50712
+ clauses.push(`EXISTS (
50713
+ SELECT 1 FROM task_run_links trl_scope
50714
+ JOIN history_run_session hrs_scope ON hrs_scope.run_id = trl_scope.run_id
50715
+ WHERE trl_scope.wbs = ? 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
+ )`);
50494
50719
  params.push(sel.taskWbs);
50495
50720
  }
50496
50721
  return { clauses, params };
@@ -50820,72 +51045,238 @@ async function bucketedTokenSeries(db2, sel, bucket, dim2, opts) {
50820
51045
  GROUP BY bucketStart, key
50821
51046
  ORDER BY bucketStart ASC`, ...params, ...wm.params);
50822
51047
  }
50823
- async function sessionTimeline(db2, sessionId, limit = 5000) {
51048
+ function formatToolPayload(toolName, status, argsRaw, argsDigest, errorText) {
51049
+ if (errorText != null && errorText.trim().length > 0)
51050
+ return errorText;
51051
+ if (argsRaw != null && argsRaw.trim().length > 0)
51052
+ return argsRaw;
51053
+ if (argsDigest != null && argsDigest.trim().length > 0) {
51054
+ return `tool: ${toolName ?? ""}
51055
+ status: ${status ?? "ok"}
51056
+ args_digest: ${argsDigest} (raw payload omitted at import)`;
51057
+ }
51058
+ return null;
51059
+ }
51060
+ function finalizeSessionDurations(events) {
51061
+ events.sort((a2, b) => {
51062
+ const aTs = a2.ts ? Date.parse(a2.ts) : Infinity;
51063
+ const bTs = b.ts ? Date.parse(b.ts) : Infinity;
51064
+ if (aTs !== bTs)
51065
+ return (Number.isNaN(aTs) ? Infinity : aTs) - (Number.isNaN(bTs) ? Infinity : bTs);
51066
+ if (a2.messageRowId !== b.messageRowId)
51067
+ return a2.messageRowId - b.messageRowId;
51068
+ if (a2.eventType !== b.eventType)
51069
+ return a2.eventType === "message" ? -1 : 1;
51070
+ return a2.toolSeq - b.toolSeq;
51071
+ });
51072
+ for (let i2 = 0;i2 < events.length; i2++) {
51073
+ const ev = events[i2];
51074
+ if (!ev)
51075
+ continue;
51076
+ if (ev.durationMs != null && Number.isFinite(ev.durationMs) && ev.durationMs > 0) {
51077
+ ev.durationSource = "measured";
51078
+ } else {
51079
+ if (i2 + 1 < events.length) {
51080
+ const nextEv = events[i2 + 1];
51081
+ const currTs = ev.ts ? Date.parse(ev.ts) : Number.NaN;
51082
+ const nextTs = nextEv?.ts ? Date.parse(nextEv.ts) : Number.NaN;
51083
+ const delta = !Number.isNaN(currTs) && !Number.isNaN(nextTs) ? nextTs - currTs : Number.NaN;
51084
+ if (delta > 0 && delta <= 600000) {
51085
+ ev.durationMs = delta;
51086
+ ev.durationSource = "inferred";
51087
+ } else {
51088
+ ev.durationMs = null;
51089
+ ev.durationSource = "unmeasured";
51090
+ }
51091
+ } else {
51092
+ ev.durationMs = null;
51093
+ ev.durationSource = "unmeasured";
51094
+ }
51095
+ }
51096
+ }
51097
+ }
51098
+ async function queryTimelineEvents(db2, whereClause, params, subWhereClause, subParams, limit, correlationMap) {
51099
+ const fetchLimit = limit + 1;
51100
+ const mainCondition = whereClause.startsWith("WHERE ") ? whereClause.slice(6) : whereClause;
51101
+ const subCondition = subWhereClause.startsWith("WHERE ") ? subWhereClause.slice(6) : subWhereClause;
51102
+ const dedupSubWhere = subCondition ? `WHERE ${subCondition} AND ` : "WHERE ";
51103
+ 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
51104
  const rows = await db2.queryAll(`SELECT m.record_hash AS messageHash, m.seq AS messageSeq,
50825
51105
  COALESCE(m.turn_index, m.seq) AS turnIndex,
50826
- m.ts AS messageTs, m.role AS messageRole, m.source, m.model,
51106
+ m.ts AS messageTs, m.role AS messageRole, COALESCE(m.record_type, m.role) AS recordType,
51107
+ m.source, m.session_id AS sessionId, m.model,
50827
51108
  m.duration_ms AS messageDurationMs, m.input_tokens AS inputTokens,
50828
51109
  m.cache_read_tokens AS cacheReadTokens, m.output_tokens AS outputTokens,
50829
51110
  m.content_text AS messagePayload,
50830
51111
  (SELECT COUNT(*) FROM history_tool_call links WHERE links.message_hash = m.record_hash) AS links,
50831
51112
  tc.tool_name AS toolName, COALESCE(tc.started_at, m.ts) AS toolTs,
50832
51113
  tc.duration_ms AS toolDurationMs, tc.status AS toolStatus,
50833
- COALESCE(tc.error_text, tc.args_raw, tc.args_digest) AS toolPayload
51114
+ tc.args_raw AS toolArgsRaw, tc.args_digest AS toolArgsDigest, tc.error_text AS toolErrorText,
51115
+ COALESCE(tc.seq, 0) AS toolSeq, m.rowid AS messageRowId
50834
51116
  FROM history_message m
50835
51117
  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 = [];
51118
+ ${fullWhere}
51119
+ ORDER BY COALESCE(m.ts, '0000-00-00') DESC, m.rowid DESC, COALESCE(tc.seq, 0) DESC
51120
+ LIMIT ?`, ...params, ...subParams, fetchLimit);
51121
+ const rawEvents = [];
50846
51122
  let previousMessage = "";
50847
51123
  for (const row of rows) {
50848
51124
  if (row.messageHash !== previousMessage) {
50849
- events.push({
51125
+ rawEvents.push({
51126
+ sessionId: row.sessionId,
50850
51127
  messageSeq: row.messageSeq,
50851
51128
  turnIndex: row.turnIndex,
50852
51129
  eventType: "message",
51130
+ recordType: row.recordType,
50853
51131
  ts: row.messageTs,
50854
51132
  role: row.messageRole,
50855
51133
  source: row.source,
50856
51134
  model: row.model,
50857
51135
  toolName: null,
50858
51136
  durationMs: row.messageDurationMs,
51137
+ durationSource: "unmeasured",
50859
51138
  inputTokens: row.links > 0 ? 0 : row.inputTokens,
50860
51139
  cacheReadTokens: row.links > 0 ? 0 : row.cacheReadTokens,
50861
51140
  outputTokens: row.links > 0 ? 0 : row.outputTokens,
50862
51141
  exitCode: null,
50863
- payload: row.messagePayload
51142
+ payload: row.messagePayload,
51143
+ messageRowId: row.messageRowId,
51144
+ toolSeq: 0
50864
51145
  });
50865
51146
  previousMessage = row.messageHash;
50866
51147
  }
50867
- if (row.toolName !== null && events.length < limit) {
50868
- events.push({
51148
+ if (row.toolName !== null) {
51149
+ rawEvents.push({
51150
+ sessionId: row.sessionId,
50869
51151
  messageSeq: row.messageSeq,
50870
51152
  turnIndex: row.turnIndex,
50871
51153
  eventType: "tool",
51154
+ recordType: row.recordType,
50872
51155
  ts: row.toolTs,
50873
51156
  role: "tool",
50874
51157
  source: row.source,
50875
51158
  model: row.model,
50876
51159
  toolName: row.toolName,
50877
51160
  durationMs: row.toolDurationMs,
50878
- inputTokens: (row.inputTokens ?? 0) / row.links,
50879
- cacheReadTokens: (row.cacheReadTokens ?? 0) / row.links,
50880
- outputTokens: (row.outputTokens ?? 0) / row.links,
51161
+ durationSource: "unmeasured",
51162
+ inputTokens: row.links > 0 ? (row.inputTokens ?? 0) / row.links : row.inputTokens,
51163
+ cacheReadTokens: row.links > 0 ? (row.cacheReadTokens ?? 0) / row.links : row.cacheReadTokens,
51164
+ outputTokens: row.links > 0 ? (row.outputTokens ?? 0) / row.links : row.outputTokens,
50881
51165
  exitCode: row.toolStatus === "error" ? 1 : 0,
50882
- payload: row.toolPayload
51166
+ payload: formatToolPayload(row.toolName, row.toolStatus, row.toolArgsRaw, row.toolArgsDigest, row.toolErrorText),
51167
+ messageRowId: row.messageRowId,
51168
+ toolSeq: row.toolSeq ?? 0
50883
51169
  });
50884
51170
  }
50885
- if (events.length >= limit)
50886
- break;
50887
51171
  }
50888
- return events.map((row, index2) => ({ ...row, seq: index2 + 1 }));
51172
+ const truncated = rows.length > limit || rawEvents.length > limit;
51173
+ rawEvents.sort((a2, b) => {
51174
+ const aTs = a2.ts ? Date.parse(a2.ts) : Infinity;
51175
+ const bTs = b.ts ? Date.parse(b.ts) : Infinity;
51176
+ if (aTs !== bTs)
51177
+ return (Number.isNaN(aTs) ? Infinity : aTs) - (Number.isNaN(bTs) ? Infinity : bTs);
51178
+ if (a2.source !== b.source)
51179
+ return a2.source.localeCompare(b.source);
51180
+ if (a2.sessionId !== b.sessionId)
51181
+ return a2.sessionId.localeCompare(b.sessionId);
51182
+ if (a2.messageRowId !== b.messageRowId)
51183
+ return a2.messageRowId - b.messageRowId;
51184
+ if (a2.eventType !== b.eventType)
51185
+ return a2.eventType === "message" ? -1 : 1;
51186
+ return a2.toolSeq - b.toolSeq;
51187
+ });
51188
+ const boundedEvents = rawEvents.length > limit ? rawEvents.slice(rawEvents.length - limit) : rawEvents;
51189
+ const sessionMap = new Map;
51190
+ for (const ev of boundedEvents) {
51191
+ const sessionKey = `${ev.source}:::${ev.sessionId}`;
51192
+ let list = sessionMap.get(sessionKey);
51193
+ if (list === undefined) {
51194
+ list = [];
51195
+ sessionMap.set(sessionKey, list);
51196
+ }
51197
+ list.push(ev);
51198
+ if (correlationMap !== undefined) {
51199
+ ev.correlationExactness = correlationMap.get(sessionKey) ?? null;
51200
+ } else {
51201
+ ev.correlationExactness = null;
51202
+ }
51203
+ }
51204
+ for (const sessionEvents of sessionMap.values()) {
51205
+ finalizeSessionDurations(sessionEvents);
51206
+ }
51207
+ boundedEvents.sort((a2, b) => {
51208
+ const aTs = a2.ts ? Date.parse(a2.ts) : Infinity;
51209
+ const bTs = b.ts ? Date.parse(b.ts) : Infinity;
51210
+ if (aTs !== bTs)
51211
+ return (Number.isNaN(aTs) ? Infinity : aTs) - (Number.isNaN(bTs) ? Infinity : bTs);
51212
+ if (a2.source !== b.source)
51213
+ return a2.source.localeCompare(b.source);
51214
+ if (a2.sessionId !== b.sessionId)
51215
+ return a2.sessionId.localeCompare(b.sessionId);
51216
+ if (a2.messageRowId !== b.messageRowId)
51217
+ return a2.messageRowId - b.messageRowId;
51218
+ if (a2.eventType !== b.eventType)
51219
+ return a2.eventType === "message" ? -1 : 1;
51220
+ return a2.toolSeq - b.toolSeq;
51221
+ });
51222
+ return {
51223
+ truncated,
51224
+ events: boundedEvents.map((row, index2) => ({
51225
+ seq: index2 + 1,
51226
+ sessionId: row.sessionId,
51227
+ messageSeq: row.messageSeq,
51228
+ turnIndex: row.turnIndex,
51229
+ eventType: row.eventType,
51230
+ recordType: row.recordType,
51231
+ ts: row.ts,
51232
+ role: row.role,
51233
+ source: row.source,
51234
+ model: row.model,
51235
+ toolName: row.toolName,
51236
+ durationMs: row.durationMs,
51237
+ durationSource: row.durationSource,
51238
+ inputTokens: row.inputTokens,
51239
+ cacheReadTokens: row.cacheReadTokens,
51240
+ outputTokens: row.outputTokens,
51241
+ exitCode: row.exitCode,
51242
+ payload: row.payload,
51243
+ correlationExactness: row.correlationExactness
51244
+ }))
51245
+ };
51246
+ }
51247
+ async function sessionTimeline(db2, source, sessionId, limit = 5000) {
51248
+ return queryTimelineEvents(db2, "WHERE m.source = ? AND m.session_id = ?", [source, sessionId], "WHERE dm.source = ? AND dm.session_id = ?", [source, sessionId], limit);
51249
+ }
51250
+ async function consolidatedTimeline(db2, sel, limit = 5000) {
51251
+ const built = buildMessageWhere(sel, "m");
51252
+ const subBuilt = buildMessageWhere(sel, "dm");
51253
+ let correlationMap;
51254
+ if (sel.runId != null || sel.taskWbs != null) {
51255
+ correlationMap = new Map;
51256
+ const correlationClauses = ["hrs.session_id IS NOT NULL"];
51257
+ const correlationParams = [];
51258
+ if (sel.runId != null) {
51259
+ correlationClauses.push("hrs.run_id = ?");
51260
+ correlationParams.push(sel.runId);
51261
+ }
51262
+ if (sel.taskWbs != null) {
51263
+ correlationClauses.push("EXISTS (SELECT 1 FROM task_run_links trl WHERE trl.run_id = hrs.run_id AND trl.wbs = ?)");
51264
+ correlationParams.push(sel.taskWbs);
51265
+ }
51266
+ const rows = await db2.queryAll(`SELECT hrs.source, hrs.session_id, hrs.exactness
51267
+ FROM history_run_session hrs
51268
+ WHERE ${correlationClauses.join(" AND ")}`, ...correlationParams);
51269
+ for (const r of rows) {
51270
+ const key = `${r.source}:::${r.session_id}`;
51271
+ const existing = correlationMap.get(key);
51272
+ if (r.exactness === "exact") {
51273
+ correlationMap.set(key, "exact");
51274
+ } else if (r.exactness === "estimated" && existing !== "exact") {
51275
+ correlationMap.set(key, "estimated");
51276
+ }
51277
+ }
51278
+ }
51279
+ return queryTimelineEvents(db2, built.where, built.params, subBuilt.where, subBuilt.params, limit, correlationMap);
50889
51280
  }
50890
51281
  async function dailyTokenMatrix(db2, days = 90) {
50891
51282
  return db2.queryAll(`WITH messages AS (
@@ -50966,7 +51357,7 @@ async function historyKpiTrend(db2, sel, opts) {
50966
51357
  ORDER BY day ASC`, ...params, ...wm.params);
50967
51358
  }
50968
51359
  var MESSAGE_DEDUP = `(m.rowid IN (
50969
- SELECT MIN(rowid) FROM history_message WHERE request_id IS NOT NULL GROUP BY request_id
51360
+ SELECT MAX(rowid) FROM history_message WHERE request_id IS NOT NULL GROUP BY request_id
50970
51361
  ) 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
51362
  WHEN LOWER(tc.tool_name) IN ('skill', 'use_skill', 'invoke_skill') AND json_valid(tc.args_raw)
50972
51363
  THEN COALESCE(
@@ -52473,6 +52864,35 @@ class RunSessionDao {
52473
52864
  throw error51;
52474
52865
  }
52475
52866
  }
52867
+ async listRunSources() {
52868
+ try {
52869
+ return await this.db.queryAll(`SELECT DISTINCT run_id, source FROM history_run_session ORDER BY run_id, source`);
52870
+ } catch (error51) {
52871
+ if (error51 instanceof Error && error51.message.includes("no such table: history_run_session"))
52872
+ return [];
52873
+ throw error51;
52874
+ }
52875
+ }
52876
+ async observeImportedSessions(input) {
52877
+ try {
52878
+ await this.db.run(`INSERT INTO history_run_session (run_id, source, session_id, exactness, mechanism, resolved_at)
52879
+ SELECT DISTINCT ?, ?, h.session_id, 'exact', 'observed', ?
52880
+ FROM history_message h
52881
+ WHERE h.source = ? AND h.session_id IS NOT NULL
52882
+ AND substr(h.source_file, 1, length(?)) = ?
52883
+ AND NOT EXISTS (
52884
+ SELECT 1 FROM history_run_session m
52885
+ WHERE m.run_id = ? AND m.source = ? AND m.session_id = h.session_id
52886
+ AND m.exactness = 'exact'
52887
+ )`, input.runId, input.source, input.resolvedAt, input.source, input.sourceFilePrefix, input.sourceFilePrefix, input.runId, input.source);
52888
+ } catch (error51) {
52889
+ if (error51 instanceof Error && error51.message.includes("no such table: history_run_session"))
52890
+ return;
52891
+ if (error51 instanceof Error && error51.message.includes("no such table: history_message"))
52892
+ return;
52893
+ throw error51;
52894
+ }
52895
+ }
52476
52896
  async insertInferred(input) {
52477
52897
  const blocked = await this.db.queryFirst(`SELECT EXISTS(
52478
52898
  SELECT 1 FROM history_run_session
@@ -53759,7 +54179,7 @@ class ActionRunDao {
53759
54179
  }
53760
54180
  }
53761
54181
 
53762
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/schema/drizzle-internals.js
54182
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/schema/drizzle-internals.js
53763
54183
  function sqlExpressionToText(value) {
53764
54184
  if (typeof value !== "object" || value === null || !("queryChunks" in value)) {
53765
54185
  return;
@@ -53782,7 +54202,7 @@ function getDrizzleTableName(table3) {
53782
54202
  return String(table3[nameSym]);
53783
54203
  }
53784
54204
 
53785
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/schema/ddl.js
54205
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/schema/ddl.js
53786
54206
  function quoteIdent(name) {
53787
54207
  return `"${name.replace(/"/g, '""')}"`;
53788
54208
  }
@@ -54154,7 +54574,7 @@ var init_drizzle_zod = __esm(() => {
54154
54574
  };
54155
54575
  });
54156
54576
 
54157
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/schema/define-table.js
54577
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/schema/define-table.js
54158
54578
  function defineTable(name, columns2) {
54159
54579
  const table3 = sqliteTable(name, columns2);
54160
54580
  let insert2;
@@ -54188,7 +54608,7 @@ var init_define_table = __esm(() => {
54188
54608
  init_ddl();
54189
54609
  });
54190
54610
 
54191
- // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.41+49dc96a15d528fb2/node_modules/@gobing-ai/ts-db/dist/schema/index.js
54611
+ // ../../node_modules/.bun/@gobing-ai+ts-db@0.4.42+88214ba569abd6d3/node_modules/@gobing-ai/ts-db/dist/schema/index.js
54192
54612
  var exports_schema = {};
54193
54613
  __export(exports_schema, {
54194
54614
  text: () => text,
@@ -54810,7 +55230,7 @@ var init_dao = __esm(() => {
54810
55230
  init_workspace_dao();
54811
55231
  });
54812
55232
 
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
55233
+ // ../../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
55234
  var WorkflowValidationError, FSMError, RunCollisionError, WorkflowResumeError;
54815
55235
  var init_errors5 = __esm(() => {
54816
55236
  WorkflowValidationError = class WorkflowValidationError extends Error {
@@ -54845,12 +55265,12 @@ var init_errors5 = __esm(() => {
54845
55265
  };
54846
55266
  });
54847
55267
 
54848
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/event-bus/index.js
55268
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/event-bus/index.js
54849
55269
  var init_event_bus2 = __esm(() => {
54850
55270
  init_event_bus();
54851
55271
  });
54852
55272
 
54853
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/api-client.js
55273
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/api-client.js
54854
55274
  function sanitizeUrlForObservability(url2) {
54855
55275
  try {
54856
55276
  const parsed = new URL(url2);
@@ -55081,12 +55501,12 @@ var init_api_client = __esm(() => {
55081
55501
  };
55082
55502
  });
55083
55503
 
55084
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/telemetry/index.js
55504
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/telemetry/index.js
55085
55505
  var init_telemetry = __esm(() => {
55086
55506
  init_tracing2();
55087
55507
  });
55088
55508
 
55089
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/index.js
55509
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/index.js
55090
55510
  var init_dist6 = __esm(() => {
55091
55511
  init_api_client();
55092
55512
  init_event_bus2();
@@ -55094,7 +55514,7 @@ var init_dist6 = __esm(() => {
55094
55514
  init_telemetry();
55095
55515
  });
55096
55516
 
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
55517
+ // ../../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
55518
  function runtimeBuiltins(workflowName, stateOrNodeId, runId, transitionsTaken, mode) {
55099
55519
  return {
55100
55520
  workflow: workflowName,
@@ -55378,7 +55798,7 @@ var init_run_lifecycle = __esm(() => {
55378
55798
  ];
55379
55799
  });
55380
55800
 
55381
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/extension/capability-registry.js
55801
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/extension/capability-registry.js
55382
55802
  class CapabilityRegistry {
55383
55803
  kind;
55384
55804
  capabilities = new Map;
@@ -55409,7 +55829,7 @@ class CapabilityRegistry {
55409
55829
  }
55410
55830
  }
55411
55831
 
55412
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-path.js
55832
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-path.js
55413
55833
  function assertRelativeExtensionPath(path9, options = {}) {
55414
55834
  const where = options.sourceName !== undefined ? ` declared by "${options.sourceName}"` : "";
55415
55835
  if (/^([/\\]|[A-Za-z]:[/\\])/.test(path9)) {
@@ -55420,7 +55840,7 @@ function assertRelativeExtensionPath(path9, options = {}) {
55420
55840
  }
55421
55841
  }
55422
55842
 
55423
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-loader.js
55843
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-loader.js
55424
55844
  import { isAbsolute, resolve } from "path";
55425
55845
  async function loadExtensionModules(refs, options, register) {
55426
55846
  if (refs.length === 0)
@@ -55459,17 +55879,17 @@ async function loadExtensionModules(refs, options, register) {
55459
55879
  }
55460
55880
  var init_extension_loader = () => {};
55461
55881
 
55462
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/extension/index.js
55882
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/extension/index.js
55463
55883
  var init_extension = __esm(() => {
55464
55884
  init_extension_loader();
55465
55885
  });
55466
55886
 
55467
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.41+13f4d6b9667ffd20/node_modules/@gobing-ai/ts-runtime/dist/extension.js
55887
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.42+815552c3ca302057/node_modules/@gobing-ai/ts-runtime/dist/extension.js
55468
55888
  var init_extension2 = __esm(() => {
55469
55889
  init_extension();
55470
55890
  });
55471
55891
 
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
55892
+ // ../../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
55893
  var RESERVED_VAR_NAMES, IDENTIFIER, VarsSchema, EnvSchema, relativeExtensionPath, WorkflowExtensionsSchema, ActionDefSchema, GuardDefSchema, StateMachineWorkflowDefSchema, TransitionFlowWorkflowDefSchema, WorkflowDefSchema;
55474
55894
  var init_schema2 = __esm(() => {
55475
55895
  init_extension2();
@@ -55571,7 +55991,7 @@ var init_schema2 = __esm(() => {
55571
55991
  WorkflowDefSchema = exports_external.union([StateMachineWorkflowDefSchema, TransitionFlowWorkflowDefSchema]);
55572
55992
  });
55573
55993
 
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
55994
+ // ../../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
55995
  async function loadWorkflowDef(path9, options = {}) {
55576
55996
  return parseWorkflowDef(await loadStructuredConfig(path9, options), path9);
55577
55997
  }
@@ -55738,7 +56158,7 @@ var init_config4 = __esm(() => {
55738
56158
  RUNTIME_TEMPLATE_NAMESPACES = new Set(RUNTIME_BUILTIN_KEYS);
55739
56159
  });
55740
56160
 
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
56161
+ // ../../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
56162
  function collectWorkflowExtensions(sourceName, sourceDir, extensions) {
55743
56163
  if (extensions === undefined)
55744
56164
  return [];
@@ -55802,7 +56222,7 @@ var init_extensions = __esm(() => {
55802
56222
  init_errors5();
55803
56223
  });
55804
56224
 
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
56225
+ // ../../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
56226
  class WorkflowEngineHost {
55807
56227
  lifecycleBus;
55808
56228
  actions = new CapabilityRegistry("workflow action");
@@ -55972,7 +56392,7 @@ var init_host = __esm(() => {
55972
56392
  init_errors5();
55973
56393
  });
55974
56394
 
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
56395
+ // ../../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
56396
  var WORKFLOW_ENGINE_SCHEMA_SQL;
55977
56397
  var init_schema_sql = __esm(() => {
55978
56398
  WORKFLOW_ENGINE_SCHEMA_SQL = `
@@ -56045,7 +56465,7 @@ CREATE TABLE IF NOT EXISTS action_runs (
56045
56465
  `.trim();
56046
56466
  });
56047
56467
 
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
56468
+ // ../../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
56469
  async function applyWorkflowEngineSchema(db2) {
56050
56470
  for (const statement of WORKFLOW_ENGINE_SCHEMA_SQL.split(";")) {
56051
56471
  const sql4 = statement.trim();
@@ -56361,7 +56781,7 @@ var init_persistence = __esm(() => {
56361
56781
  init_schema_sql();
56362
56782
  });
56363
56783
 
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
56784
+ // ../../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
56785
  function mergeVars(workflowVars = {}, overrideVars = {}) {
56366
56786
  return { ...workflowVars, ...overrideVars };
56367
56787
  }
@@ -56421,7 +56841,7 @@ var init_variables = __esm(() => {
56421
56841
  TEMPLATE_REF = /\$\{([^}]+)\}/g;
56422
56842
  });
56423
56843
 
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
56844
+ // ../../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
56845
  async function runActionStep(action, vars, deps) {
56426
56846
  const { host, persistence, lifecycle, stateOrNodeId, runId } = deps;
56427
56847
  const resolved = resolveTemplates(action.options ?? {}, {
@@ -56485,7 +56905,7 @@ var init_action_step = __esm(() => {
56485
56905
  init_variables();
56486
56906
  });
56487
56907
 
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
56908
+ // ../../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
56909
  class StateMachineDriver {
56490
56910
  options;
56491
56911
  constructor(options) {
@@ -56621,7 +57041,7 @@ var init_state_machine = __esm(() => {
56621
57041
  EMPTY_OUTCOME = { outcome: "completed", result: undefined, setVars: undefined };
56622
57042
  });
56623
57043
 
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
57044
+ // ../../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
57045
  class TransitionFlowDriver {
56626
57046
  options;
56627
57047
  constructor(options) {
@@ -56740,7 +57160,7 @@ var init_transition_flow = __esm(() => {
56740
57160
  init_variables();
56741
57161
  });
56742
57162
 
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
57163
+ // ../../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
57164
  class WorkflowService {
56745
57165
  host;
56746
57166
  persistence;
@@ -56965,7 +57385,7 @@ var init_service = __esm(() => {
56965
57385
  init_variables();
56966
57386
  });
56967
57387
 
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
57388
+ // ../../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
57389
  var init_dist7 = __esm(() => {
56970
57390
  init_config4();
56971
57391
  init_extensions();
@@ -56975,7 +57395,7 @@ var init_dist7 = __esm(() => {
56975
57395
  init_service();
56976
57396
  });
56977
57397
 
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
57398
+ // ../../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
57399
  import { createHash as createHash2 } from "crypto";
56980
57400
  function stableJson(value) {
56981
57401
  if (Array.isArray(value)) {
@@ -56992,7 +57412,7 @@ function sha256(value) {
56992
57412
  }
56993
57413
  var init_hash = () => {};
56994
57414
 
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
57415
+ // ../../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
57416
  var HistoryImportError;
56997
57417
  var init_errors6 = __esm(() => {
56998
57418
  HistoryImportError = class HistoryImportError extends Error {
@@ -57005,7 +57425,7 @@ var init_errors6 = __esm(() => {
57005
57425
  };
57006
57426
  });
57007
57427
 
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
57428
+ // ../../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
57429
  var HISTORY_IMPORT_SCHEMA_SQL;
57010
57430
  var init_schema_sql2 = __esm(() => {
57011
57431
  HISTORY_IMPORT_SCHEMA_SQL = `
@@ -57089,7 +57509,7 @@ CREATE INDEX IF NOT EXISTS idx_history_tool_call_message_hash
57089
57509
  `.trim();
57090
57510
  });
57091
57511
 
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
57512
+ // ../../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
57513
  function identityFieldMap(keys) {
57094
57514
  const map2 = {};
57095
57515
  for (const key of keys) {
@@ -57467,15 +57887,24 @@ function claudeToolResultTiming(raw) {
57467
57887
  }
57468
57888
  return null;
57469
57889
  }
57470
- function codexSplit(raw) {
57890
+ function codexSplit(raw, context4) {
57471
57891
  const entries = [];
57472
57892
  const payload = raw.payload ?? raw;
57473
- const sessionId = s(raw.session_id, o2(raw.session_meta).id, raw.id) ?? "unknown";
57474
57893
  const seq = typeof raw.seq === "number" ? raw.seq : 0;
57475
57894
  const ts = timestampOf(raw.timestamp, raw.ts, payload.ts);
57476
57895
  const recordType = String(raw.type ?? "");
57477
57896
  const payloadType = String(payload.type ?? "");
57478
- if (recordType === "" && raw.id && raw.timestamp && raw.instructions) {
57897
+ const isShortFormat = recordType === "" && raw.id !== undefined && raw.timestamp !== undefined && raw.instructions !== undefined;
57898
+ let explicitSessionId = s(raw.session_id, o2(raw.session_meta).id);
57899
+ if (explicitSessionId === undefined && recordType === "session_meta") {
57900
+ explicitSessionId = s(payload.id, o2(raw.payload).id);
57901
+ }
57902
+ if (explicitSessionId === undefined && isShortFormat) {
57903
+ explicitSessionId = s(raw.id);
57904
+ }
57905
+ const pathSessionId = context4?.sourceFile ? sessionIdFromSourcePath("codex", context4.sourceFile) : undefined;
57906
+ const sessionId = explicitSessionId ?? pathSessionId ?? "unknown";
57907
+ if (isShortFormat) {
57479
57908
  return [
57480
57909
  {
57481
57910
  targetTable: "history_message",
@@ -57603,10 +58032,12 @@ function codexSplit(raw) {
57603
58032
  }
57604
58033
  return entries;
57605
58034
  }
57606
- function agySplit(raw) {
58035
+ function agySplit(raw, context4) {
57607
58036
  const entries = [];
57608
58037
  const recordType = String(raw.type ?? "");
57609
- const sessionId = s(raw.session_id, raw.conversation_id) ?? "unknown";
58038
+ const explicitSessionId = s(raw.session_id, raw.conversation_id);
58039
+ const pathSessionId = context4?.sourceFile ? sessionIdFromSourcePath("agy", context4.sourceFile) : undefined;
58040
+ const sessionId = explicitSessionId ?? pathSessionId ?? "unknown";
57610
58041
  const seq = typeof raw.seq === "number" ? raw.seq : typeof raw.step_index === "number" ? raw.step_index : 0;
57611
58042
  const ts = timestampOf(raw.created_at, raw.timestamp, raw.ts);
57612
58043
  let role;
@@ -57785,6 +58216,23 @@ function geminiSplit(raw, context4) {
57785
58216
  }
57786
58217
  return entries;
57787
58218
  }
58219
+ function sessionIdFromSourcePath(source, sourceFile) {
58220
+ const normalized = sourceFile.replace(/\\/g, "/");
58221
+ const sLower = source.toLowerCase();
58222
+ if (sLower === "agy" || sLower === "antigravity") {
58223
+ const match = normalized.match(AGY_BRAIN_REGEX);
58224
+ return match?.[1];
58225
+ }
58226
+ if (sLower === "codex") {
58227
+ const basename = normalized.split("/").at(-1) ?? "";
58228
+ if (basename.startsWith("rollout-") && basename.endsWith(".jsonl")) {
58229
+ const stem = basename.slice(0, -6);
58230
+ const match = stem.match(CODEX_ROLLOUT_REGEX);
58231
+ return match?.[1];
58232
+ }
58233
+ }
58234
+ return;
58235
+ }
57788
58236
  function sessionIdFromContext(context4, raw) {
57789
58237
  if (context4 !== undefined) {
57790
58238
  const file2 = context4.sourceFile.split("/").at(-1);
@@ -58218,7 +58666,7 @@ function extractContentText(content) {
58218
58666
  function stableFieldShape(raw) {
58219
58667
  return Object.keys(raw).map((k) => k.toLowerCase()).sort().join("+");
58220
58668
  }
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;
58669
+ 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
58670
  var init_mappers = __esm(() => {
58223
58671
  init_zod();
58224
58672
  init_hash();
@@ -58269,6 +58717,8 @@ var init_mappers = __esm(() => {
58269
58717
  agy: [],
58270
58718
  gemini: []
58271
58719
  };
58720
+ AGY_BRAIN_REGEX = new RegExp(`(?:^|\\/)brain\\/(${UUID_PATTERN})(?:\\/|$)`, "i");
58721
+ CODEX_ROLLOUT_REGEX = new RegExp(`(?:^|-|_)(${UUID_PATTERN})$`, "i");
58272
58722
  GROK_META_TYPES = new Set([
58273
58723
  "phase_changed",
58274
58724
  "permission_requested",
@@ -58316,7 +58766,7 @@ var init_mappers = __esm(() => {
58316
58766
  GEMINI_SCHEMA = passthroughSchema;
58317
58767
  });
58318
58768
 
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
58769
+ // ../../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
58770
  function firstString(...values) {
58321
58771
  for (const value of values) {
58322
58772
  if (typeof value === "string" && value.length > 0)
@@ -58473,7 +58923,7 @@ var init_sources = __esm(() => {
58473
58923
  };
58474
58924
  });
58475
58925
 
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
58926
+ // ../../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
58927
  function targetTableFor(table3) {
58478
58928
  if (!VALID_TABLE_NAME.test(table3)) {
58479
58929
  throw new HistoryImportError(`Invalid history ETL target table: ${table3}`, { table: table3 });
@@ -58788,7 +59238,7 @@ var init_jsonl_importer_dao = __esm(() => {
58788
59238
  TYPED_IGNORED_KEYS = new Set(["_meta", "split_index"]);
58789
59239
  });
58790
59240
 
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
59241
+ // ../../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
59242
  function redactValue(value, rules = DEFAULT_REDACTION_RULES) {
58793
59243
  if (typeof value === "string") {
58794
59244
  return rules.reduce((current, rule) => current.replace(rule.pattern, rule.replacement), value);
@@ -58840,7 +59290,7 @@ var init_redaction = __esm(() => {
58840
59290
  ];
58841
59291
  });
58842
59292
 
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
59293
+ // ../../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
59294
  function toolCallKey(source, sessionId, callId) {
58845
59295
  return `${source}${TOOL_CALL_KEY_SEP}${sessionId}${TOOL_CALL_KEY_SEP}${callId}`;
58846
59296
  }
@@ -59184,7 +59634,7 @@ var init_importer = __esm(() => {
59184
59634
  init_sources();
59185
59635
  });
59186
59636
 
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
59637
+ // ../../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
59638
  async function runOpenCodeImport(options) {
59189
59639
  const paths = options.paths ?? ambientRuntimePaths2();
59190
59640
  const sourceDatabase = options.sourceDatabase ?? joinPath2(paths.home, ".local/share/opencode/opencode.db");
@@ -59439,15 +59889,16 @@ var init_opencode_importer = __esm(() => {
59439
59889
  init_redaction();
59440
59890
  });
59441
59891
 
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
59892
+ // ../../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
59893
  var init_dist8 = __esm(() => {
59444
59894
  init_importer();
59895
+ init_mappers();
59445
59896
  init_opencode_importer();
59446
59897
  init_schema_sql2();
59447
59898
  init_sources();
59448
59899
  });
59449
59900
 
59450
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/config/extensions.js
59901
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/config/extensions.js
59451
59902
  function collectExtensions(sourceName, sourceDir, extensions) {
59452
59903
  if (extensions === undefined)
59453
59904
  return [];
@@ -59461,7 +59912,7 @@ function collectExtensions(sourceName, sourceDir, extensions) {
59461
59912
  }
59462
59913
  var init_extensions2 = () => {};
59463
59914
 
59464
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/types.js
59915
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/types.js
59465
59916
  function createFinding(rule, message, filePath, extras = {}) {
59466
59917
  return {
59467
59918
  ruleId: rule.id,
@@ -59532,7 +59983,7 @@ var init_types3 = __esm(() => {
59532
59983
  });
59533
59984
  });
59534
59985
 
59535
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/config/loader.js
59986
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/config/loader.js
59536
59987
  async function loadPreset(name, options) {
59537
59988
  const merged = await buildMergedRoots(options.roots.map((root) => resolvePath4(root)), options.fileSystem);
59538
59989
  const presetPath = findMergedPreset(merged, name);
@@ -59747,7 +60198,7 @@ var init_loader2 = __esm(() => {
59747
60198
  FIX_MODE_AUTHORITY = { none: 0, suggest: 1, auto: 2 };
59748
60199
  });
59749
60200
 
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
60201
+ // ../../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
60202
  function normalizeFindingPath(filePath) {
59752
60203
  if (!filePath || isAbsolutePath2(filePath))
59753
60204
  return null;
@@ -59812,7 +60263,7 @@ var init_test_stub_fixer = __esm(() => {
59812
60263
  realFileSystem = createNodeFileSystem3();
59813
60264
  });
59814
60265
 
59815
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/fixers/fixers.js
60266
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/fixers/fixers.js
59816
60267
  function registerBuiltinFixers(host, exec) {
59817
60268
  const regexFixer = new RegexFixerProvider;
59818
60269
  const pathFixer = new PathFixerProvider;
@@ -60015,7 +60466,7 @@ var init_fixers = __esm(() => {
60015
60466
  };
60016
60467
  });
60017
60468
 
60018
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/agents/shims.js
60469
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/agents/shims.js
60019
60470
  function getAgentSessionCapability(agent) {
60020
60471
  return AGENT_SESSION_CAPABILITY[agent];
60021
60472
  }
@@ -60307,7 +60758,7 @@ var init_shims = __esm(() => {
60307
60758
  ALIAS_TO_CANONICAL = Object.fromEntries(Object.values(AGENT_SHIMS).flatMap((shim) => (shim.aliases ?? []).map((alias3) => [alias3, shim.name])));
60308
60759
  });
60309
60760
 
60310
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/identity.js
60761
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/identity.js
60311
60762
  function buildIdentityPreamble(ctx) {
60312
60763
  const sections = [
60313
60764
  `You are agent \`${ctx.agentId}\` (${ctx.agentType}) in workspace \`${ctx.workspace}\`.`
@@ -60383,7 +60834,7 @@ var init_identity = __esm(() => {
60383
60834
  init_dist5();
60384
60835
  });
60385
60836
 
60386
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/slash-command.js
60837
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/slash-command.js
60387
60838
  function isClaudeStyleSlashCommand(input) {
60388
60839
  return SLASH_COMMAND_RE.test(input);
60389
60840
  }
@@ -60411,7 +60862,7 @@ var init_slash_command = __esm(() => {
60411
60862
  SLASH_COMMAND_RE = /^\/([a-zA-Z0-9._-]+):([a-zA-Z0-9._-]+)(\s.*)?$/;
60412
60863
  });
60413
60864
 
60414
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/ai-runner.js
60865
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/ai-runner.js
60415
60866
  function buildCorrelationEnv(correlation) {
60416
60867
  return {
60417
60868
  [AGENT_RUN_ID_ENV]: correlation.runId,
@@ -60549,7 +61000,7 @@ var init_ai_runner = __esm(() => {
60549
61000
  init_slash_command();
60550
61001
  });
60551
61002
 
60552
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/agent-detector.js
61003
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/agent-detector.js
60553
61004
  class AgentDetector {
60554
61005
  runner;
60555
61006
  timeout;
@@ -60625,7 +61076,7 @@ var init_agent_detector = __esm(() => {
60625
61076
  VERSION_PATTERN = /(?<version>\d+\.\d+(?:\.\d+)?)/;
60626
61077
  });
60627
61078
 
60628
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/agent-spec.js
61079
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/agent-spec.js
60629
61080
  function validateAgentId(id) {
60630
61081
  if (!/^[a-z][a-z0-9_-]{1,63}$/.test(id)) {
60631
61082
  throw new ValueError(`Invalid agent id "${id}": expected 2-64 chars, lowercase alphanumeric, "_" or "-"`);
@@ -60724,7 +61175,7 @@ var init_agent_spec = __esm(() => {
60724
61175
  };
60725
61176
  });
60726
61177
 
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
61178
+ // ../../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
61179
  function isNonEmpty(value) {
60729
61180
  return value !== undefined && value.trim().length > 0;
60730
61181
  }
@@ -60849,7 +61300,7 @@ var init_auth_shims = __esm(() => {
60849
61300
  };
60850
61301
  });
60851
61302
 
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
61303
+ // ../../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
61304
  class ModelHealthProbeRegistry {
60854
61305
  probes = new Map;
60855
61306
  register(providerPrefix, probe) {
@@ -60957,7 +61408,7 @@ var init_model_health_probe = __esm(() => {
60957
61408
  };
60958
61409
  });
60959
61410
 
60960
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/doctor-runner.js
61411
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/doctor-runner.js
60961
61412
  class DoctorRunner {
60962
61413
  detector;
60963
61414
  runner;
@@ -61094,15 +61545,15 @@ var init_doctor_runner = __esm(() => {
61094
61545
  init_model_health_probe();
61095
61546
  });
61096
61547
 
61097
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/events.js
61548
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/events.js
61098
61549
  var init_events = () => {};
61099
61550
 
61100
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/messages.js
61551
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/messages.js
61101
61552
  function formatMessage(msg) {
61102
61553
  return `[task from=${msg.fromId ?? "operator"} id=${msg.id}] ${msg.body}`;
61103
61554
  }
61104
61555
 
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
61556
+ // ../../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
61557
  import { Buffer as Buffer5 } from "buffer";
61107
61558
 
61108
61559
  class TeamAgentProcess {
@@ -61236,7 +61687,7 @@ var init_team_agent_process = __esm(() => {
61236
61687
  init_dist5();
61237
61688
  });
61238
61689
 
61239
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/team-orchestrator.js
61690
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/team-orchestrator.js
61240
61691
  class TeamOrchestrator {
61241
61692
  configDir;
61242
61693
  inbox;
@@ -61377,7 +61828,7 @@ var init_team_orchestrator = __esm(() => {
61377
61828
  init_team_agent_process();
61378
61829
  });
61379
61830
 
61380
- // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.41+be8563dcb4b93fe8/node_modules/@gobing-ai/ts-ai-runner/dist/index.js
61831
+ // ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.42+2a1a28b8ddd1e341/node_modules/@gobing-ai/ts-ai-runner/dist/index.js
61381
61832
  var exports_dist3 = {};
61382
61833
  __export(exports_dist3, {
61383
61834
  validateAgentId: () => validateAgentId,
@@ -61430,7 +61881,7 @@ var init_dist9 = __esm(() => {
61430
61881
  init_team_orchestrator();
61431
61882
  });
61432
61883
 
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
61884
+ // ../../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
61885
  function stringArray(value) {
61435
61886
  return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : undefined;
61436
61887
  }
@@ -61468,7 +61919,7 @@ function parseInlineFlags(source) {
61468
61919
  return { flags, rest: source.slice(match[0].length) };
61469
61920
  }
61470
61921
 
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
61922
+ // ../../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
61923
  function matchesAny(path9, patterns) {
61473
61924
  if (patterns === undefined || patterns.length === 0)
61474
61925
  return true;
@@ -61516,7 +61967,7 @@ function escapeRegExp(value) {
61516
61967
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
61517
61968
  }
61518
61969
 
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
61970
+ // ../../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
61971
  async function discoverFiles2(options) {
61521
61972
  const fs3 = options.fs ?? createNodeFileSystem3();
61522
61973
  const allFiles = await walkDir2(options.workdir, fs3, DEFAULT_EXCLUDES);
@@ -61547,12 +61998,12 @@ var init_file_discovery = __esm(() => {
61547
61998
  DEFAULT_EXCLUDES = new Set([".git", "node_modules", "dist", ".coverage", ".astro", ".wrangler"]);
61548
61999
  });
61549
62000
 
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
62001
+ // ../../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
62002
  var init_file_utils = __esm(() => {
61552
62003
  init_file_discovery();
61553
62004
  });
61554
62005
 
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
62006
+ // ../../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
62007
  class AgentDetectionEvaluator {
61557
62008
  detector;
61558
62009
  constructor(detector = new AgentDetector) {
@@ -61580,7 +62031,7 @@ var init_agent_detection_evaluator = __esm(() => {
61580
62031
  init_file_utils();
61581
62032
  });
61582
62033
 
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
62034
+ // ../../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
62035
  class CoverageGateEvaluator {
61585
62036
  constructor() {}
61586
62037
  async evaluate(rule, context4) {
@@ -61664,7 +62115,7 @@ var init_coverage_gate_evaluator = __esm(() => {
61664
62115
  init_file_utils();
61665
62116
  });
61666
62117
 
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
62118
+ // ../../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
62119
  class ExitCodeEvaluator {
61669
62120
  executor;
61670
62121
  constructor(executor = nodeBunFactory3.createProcessExecutor()) {
@@ -61700,7 +62151,7 @@ var init_exit_code_evaluator = __esm(() => {
61700
62151
  init_file_utils();
61701
62152
  });
61702
62153
 
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
62154
+ // ../../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
62155
  class ForbiddenImportEvaluator {
61705
62156
  constructor() {}
61706
62157
  async evaluate(rule, context4) {
@@ -61781,7 +62232,7 @@ var init_forbidden_import_evaluator = __esm(() => {
61781
62232
  init_file_utils();
61782
62233
  });
61783
62234
 
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
62235
+ // ../../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
62236
  class ImportBoundaryEvaluator {
61786
62237
  async evaluate(rule, context4) {
61787
62238
  const config4 = rule.evaluator.config ?? {};
@@ -61874,7 +62325,7 @@ var init_import_boundary_evaluator = __esm(() => {
61874
62325
  init_file_utils();
61875
62326
  });
61876
62327
 
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
62328
+ // ../../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
62329
  class PathEvaluator {
61879
62330
  constructor() {}
61880
62331
  async evaluate(rule, context4) {
@@ -61935,7 +62386,7 @@ var init_path_evaluator = __esm(() => {
61935
62386
  init_file_utils();
61936
62387
  });
61937
62388
 
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
62389
+ // ../../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
62390
  class RegexEvaluator {
61940
62391
  constructor() {}
61941
62392
  async evaluate(rule, context4) {
@@ -62013,7 +62464,7 @@ var init_regex_evaluator = __esm(() => {
62013
62464
  init_file_utils();
62014
62465
  });
62015
62466
 
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
62467
+ // ../../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
62468
  class RipgrepEvaluator {
62018
62469
  executor;
62019
62470
  constructor(executor = nodeBunFactory3.createProcessExecutor()) {
@@ -62106,7 +62557,7 @@ var init_ripgrep_evaluator = __esm(() => {
62106
62557
  init_file_utils();
62107
62558
  });
62108
62559
 
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
62560
+ // ../../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
62561
  class SchemaArtifactEvaluator {
62111
62562
  constructor() {}
62112
62563
  async evaluate(rule, context4) {
@@ -62184,7 +62635,7 @@ var init_schema_artifact_evaluator = __esm(() => {
62184
62635
  init_file_utils();
62185
62636
  });
62186
62637
 
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
62638
+ // ../../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
62639
  class SecretsScannerEvaluator {
62189
62640
  constructor() {}
62190
62641
  async evaluate(rule, context4) {
@@ -62252,7 +62703,7 @@ var init_secrets_scanner_evaluator = __esm(() => {
62252
62703
  ALL_CATEGORIES = Object.keys(BUILTIN_PATTERNS);
62253
62704
  });
62254
62705
 
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
62706
+ // ../../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
62707
  class SgEvaluator {
62257
62708
  executor;
62258
62709
  constructor(executor = nodeBunFactory3.createProcessExecutor()) {
@@ -62349,7 +62800,7 @@ var init_sg_evaluator = __esm(() => {
62349
62800
  init_file_utils();
62350
62801
  });
62351
62802
 
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
62803
+ // ../../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
62804
  class TypeScriptTestPathResolver {
62354
62805
  name = "typescript";
62355
62806
  constructor() {}
@@ -62432,7 +62883,7 @@ function testify(rel) {
62432
62883
  return `${dir}test_${base2}`;
62433
62884
  }
62434
62885
 
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
62886
+ // ../../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
62887
  class TestLocationEvaluator {
62437
62888
  resolvers;
62438
62889
  constructor(resolvers) {
@@ -62507,7 +62958,7 @@ var init_test_location_evaluator = __esm(() => {
62507
62958
  TYPESCRIPT_FALLBACK = new TypeScriptTestPathResolver;
62508
62959
  });
62509
62960
 
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
62961
+ // ../../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
62962
  class TsdocExportEvaluator {
62512
62963
  constructor() {}
62513
62964
  async evaluate(rule, context4) {
@@ -62592,7 +63043,7 @@ var init_tsdoc_export_evaluator = __esm(() => {
62592
63043
  };
62593
63044
  });
62594
63045
 
62595
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/json.js
63046
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/json.js
62596
63047
  class JsonFormatter {
62597
63048
  constructor() {}
62598
63049
  format(result) {
@@ -62600,7 +63051,7 @@ class JsonFormatter {
62600
63051
  }
62601
63052
  }
62602
63053
 
62603
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/text.js
63054
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/text.js
62604
63055
  class TextFormatter {
62605
63056
  constructor() {}
62606
63057
  format(result) {
@@ -62614,7 +63065,7 @@ class TextFormatter {
62614
63065
  }
62615
63066
  }
62616
63067
 
62617
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/host/builtins.js
63068
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/host/builtins.js
62618
63069
  function registerBuiltins(host, executor) {
62619
63070
  const path9 = new PathEvaluator;
62620
63071
  host.evaluators.register("regex", new RegexEvaluator, "builtin");
@@ -62654,7 +63105,7 @@ var init_builtins = __esm(() => {
62654
63105
  init_tsdoc_export_evaluator();
62655
63106
  });
62656
63107
 
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
63108
+ // ../../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
63109
  class RuleEngineHost {
62659
63110
  evaluators;
62660
63111
  formatters;
@@ -62671,7 +63122,7 @@ var init_rule_engine_host = __esm(() => {
62671
63122
  init_extension2();
62672
63123
  });
62673
63124
 
62674
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/engine.js
63125
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/engine.js
62675
63126
  class RuleEngine {
62676
63127
  host;
62677
63128
  events;
@@ -62857,7 +63308,7 @@ var init_engine = __esm(() => {
62857
63308
  init_types3();
62858
63309
  });
62859
63310
 
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
63311
+ // ../../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
63312
  async function bundledRulesRoot() {
62862
63313
  if (cachedRoot2 !== undefined)
62863
63314
  return cachedRoot2;
@@ -62908,7 +63359,7 @@ var init_bundled_rules = __esm(() => {
62908
63359
  init_dist5();
62909
63360
  });
62910
63361
 
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
63362
+ // ../../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
63363
  class DbRulePersistenceAdapter {
62913
63364
  db;
62914
63365
  constructor(db2) {
@@ -62942,7 +63393,7 @@ class DbRulePersistenceAdapter {
62942
63393
  }
62943
63394
  }
62944
63395
 
62945
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/schema.js
63396
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/schema.js
62946
63397
  var RULE_ENGINE_SCHEMA_SQL = `
62947
63398
  CREATE TABLE IF NOT EXISTS rule_runs (
62948
63399
  id TEXT PRIMARY KEY,
@@ -62988,10 +63439,10 @@ CREATE TABLE IF NOT EXISTS rule_eval_runs (
62988
63439
  CREATE INDEX IF NOT EXISTS idx_rule_eval_runs_run_id ON rule_eval_runs (run_id);
62989
63440
  `;
62990
63441
 
62991
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/index.js
63442
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/index.js
62992
63443
  var init_persistence2 = () => {};
62993
63444
 
62994
- // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.41+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/index.js
63445
+ // ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.42+df32fe902834add3/node_modules/@gobing-ai/ts-rule-engine/dist/index.js
62995
63446
  var init_dist10 = __esm(() => {
62996
63447
  init_extensions2();
62997
63448
  init_loader2();
@@ -63232,6 +63683,10 @@ ALTER TABLE history_tool_call ADD COLUMN args_raw TEXT;
63232
63683
  ALTER TABLE history_tool_call ADD COLUMN call_id TEXT;
63233
63684
  `, HISTORY_MESSAGE_REQUEST_ID_SCHEMA_SQL = `
63234
63685
  ALTER TABLE history_message ADD COLUMN request_id TEXT;
63686
+ `, HISTORY_MESSAGE_REQUEST_ID_INDEX_SCHEMA_SQL = `
63687
+ CREATE INDEX IF NOT EXISTS idx_history_message_request_id
63688
+ ON history_message (request_id)
63689
+ WHERE request_id IS NOT NULL;
63235
63690
  `, HISTORY_ETL_TABLES_DROP_SCHEMA_SQL = `
63236
63691
  DROP TABLE IF EXISTS history_etl_pi;
63237
63692
  DROP TABLE IF EXISTS history_etl_claude;
@@ -63563,11 +64018,15 @@ ${HISTORY_RUN_SESSION_SCHEMA_SQL}
63563
64018
  {
63564
64019
  id: "0022_spur_cli_history_performance_indexes",
63565
64020
  sql: HISTORY_PERFORMANCE_INDEXES_SCHEMA_SQL
64021
+ },
64022
+ {
64023
+ id: "0023_spur_cli_history_message_request_id_idx",
64024
+ sql: HISTORY_MESSAGE_REQUEST_ID_INDEX_SCHEMA_SQL
63566
64025
  }
63567
64026
  ];
63568
64027
  });
63569
64028
 
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
64029
+ // ../../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
64030
  function queueLogger() {
63572
64031
  if (!_queueLogger)
63573
64032
  _queueLogger = getLogger2("job-queue");
@@ -63870,7 +64329,7 @@ var init_db_job_queue = __esm(() => {
63870
64329
  init_tracing2();
63871
64330
  });
63872
64331
 
63873
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/job-queue-db.js
64332
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/job-queue-db.js
63874
64333
  var exports_job_queue_db = {};
63875
64334
  __export(exports_job_queue_db, {
63876
64335
  DBQueueConsumer: () => DBQueueConsumer,
@@ -66232,6 +66691,7 @@ __export(exports_src, {
66232
66691
  createBoundaryContext: () => createBoundaryContext,
66233
66692
  countToolCallsSince: () => countToolCallsSince,
66234
66693
  countCheckpointsBySource: () => countCheckpointsBySource,
66694
+ consolidatedTimeline: () => consolidatedTimeline,
66235
66695
  computeSnapshotHash: () => computeSnapshotHash,
66236
66696
  computeRecordCost: () => computeRecordCost,
66237
66697
  computeInvalidationFingerprint: () => computeInvalidationFingerprint,
@@ -67238,6 +67698,11 @@ class RunSessionObserver {
67238
67698
  return;
67239
67699
  }
67240
67700
  const sessionId = await this.sessionIdFor(wm.source, candidates[0]);
67701
+ if (sessionId === undefined) {
67702
+ this.warn(`run-session resolve for ${wm.source}: candidate has no canonical session id`);
67703
+ await this.writeUnresolved(wm.source);
67704
+ return;
67705
+ }
67241
67706
  await this.write({
67242
67707
  runId: this.options.runId,
67243
67708
  source: wm.source,
@@ -67275,20 +67740,38 @@ class RunSessionObserver {
67275
67740
  return candidates.sort();
67276
67741
  }
67277
67742
  async sessionIdFor(source, filePath) {
67278
- const stem = basename(filePath).replace(/\.[^.]+$/, "");
67743
+ let firstRecordId;
67279
67744
  try {
67280
67745
  const firstLine = (await createNodeFileSystem3().readFile(filePath)).split(`
67281
67746
  `, 1)[0] ?? "";
67282
67747
  const raw = JSON.parse(firstLine);
67283
67748
  if (source === "claude")
67284
- return firstString2(raw.sessionId, raw.conversation_uuid) ?? stem;
67285
- if (source === "codex") {
67749
+ firstRecordId = firstString2(raw.sessionId, raw.conversation_uuid);
67750
+ else if (source === "codex") {
67286
67751
  const payload = asRecord(raw.payload);
67287
- return firstString2(raw.session_id, payload?.id, raw.id) ?? stem;
67752
+ const recordType = typeof raw.type === "string" ? raw.type : "";
67753
+ const isShortFormat = recordType === "" && raw.id !== undefined && raw.timestamp !== undefined && raw.instructions !== undefined;
67754
+ firstRecordId = firstString2(raw.session_id, asRecord(raw.session_meta)?.id);
67755
+ if (firstRecordId === undefined && recordType === "session_meta") {
67756
+ firstRecordId = firstString2(payload?.id);
67757
+ }
67758
+ if (firstRecordId === undefined && isShortFormat) {
67759
+ firstRecordId = firstString2(raw.id);
67760
+ }
67761
+ } else if (source === "pi") {
67762
+ firstRecordId = firstString2(raw.id, asRecord(raw.session)?.id);
67763
+ } else if (source === "agy" || source === "antigravity") {
67764
+ firstRecordId = firstString2(raw.session_id, raw.conversation_id);
67288
67765
  }
67289
- if (source === "pi")
67290
- return firstString2(raw.id, asRecord(raw.session)?.id) ?? stem;
67291
67766
  } catch {}
67767
+ if (firstRecordId)
67768
+ return firstRecordId;
67769
+ const fromPath = sessionIdFromSourcePath(source, filePath);
67770
+ if (fromPath)
67771
+ return fromPath;
67772
+ if (source === "agy" || source === "antigravity" || source === "codex")
67773
+ return;
67774
+ const stem = basename(filePath).replace(/\.[^.]+$/, "");
67292
67775
  return stem;
67293
67776
  }
67294
67777
  async writeUnresolved(source) {
@@ -74931,125 +75414,180 @@ class MockHistoryBoardService {
74931
75414
  }
74932
75415
  return points;
74933
75416
  }
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
75417
+ async getTimeline(input) {
75418
+ if (input.mode === "session") {
75419
+ const session4 = this.sessions.find((s3) => s3.id === input.sessionId);
75420
+ if (!session4)
75421
+ throw new Error(`History session not found: ${input.sessionId}`);
75422
+ const sessionStart = session4.start;
75423
+ const blocks = [
75424
+ {
75425
+ key: `${session4.source}:::${session4.id}:::0`,
75426
+ sessionId: session4.id,
75427
+ turnIndex: 0,
75428
+ timestamp: new Date(sessionStart).toISOString(),
75429
+ source: session4.source,
75430
+ model: session4.model,
75431
+ correlationExactness: null,
75432
+ totalDurationMs: 4200,
75433
+ totalTokens: 18500,
75434
+ operationCount: 3,
75435
+ events: [
75436
+ {
75437
+ seq: 1,
75438
+ eventType: "message",
75439
+ kind: "user",
75440
+ title: "user turn",
75441
+ toolName: null,
75442
+ durationMs: null,
75443
+ durationSource: "unmeasured",
75444
+ tokens: 450,
75445
+ freshInputTokens: 450,
75446
+ cacheReadTokens: 0,
75447
+ outputTokens: 0,
75448
+ promptTokens: {
75449
+ billedTokens: 18050,
75450
+ cacheSavedTokens: 16300,
75451
+ cacheReadTokens: 16300,
75452
+ freshInputTokens: 800,
75453
+ outputTokens: 950
75454
+ },
75455
+ exitCode: null,
75456
+ payload: "User prompt content",
75457
+ agent: session4.source,
75458
+ model: session4.model
75459
+ },
75460
+ {
75461
+ seq: 2,
75462
+ eventType: "tool",
75463
+ kind: "search",
75464
+ title: "src/**/*.ts",
75465
+ toolName: "Glob",
75466
+ durationMs: 320,
75467
+ durationSource: "measured",
75468
+ tokens: 4200,
75469
+ freshInputTokens: 200,
75470
+ cacheReadTokens: 3800,
75471
+ outputTokens: 200,
75472
+ promptTokens: null,
75473
+ exitCode: 0,
75474
+ payload: "Matched 48 files",
75475
+ agent: session4.source,
75476
+ model: session4.model
75477
+ },
75478
+ {
75479
+ seq: 3,
75480
+ eventType: "tool",
75481
+ kind: "read",
75482
+ title: "docs/03_ARCHITECTURE.md",
75483
+ toolName: "Read",
75484
+ durationMs: 780,
75485
+ durationSource: "measured",
75486
+ tokens: 13850,
75487
+ freshInputTokens: 600,
75488
+ cacheReadTokens: 12500,
75489
+ outputTokens: 750,
75490
+ promptTokens: null,
75491
+ exitCode: 0,
75492
+ payload: `# Architecture
74991
75493
 
74992
75494
  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
- ];
75495
+ agent: session4.source,
75496
+ model: session4.model
75497
+ }
75498
+ ]
75499
+ },
75500
+ {
75501
+ key: `${session4.source}:::${session4.id}:::1`,
75502
+ sessionId: session4.id,
75503
+ turnIndex: 1,
75504
+ timestamp: new Date(sessionStart + 60000).toISOString(),
75505
+ source: session4.source,
75506
+ model: session4.model,
75507
+ correlationExactness: null,
75508
+ totalDurationMs: 8900,
75509
+ totalTokens: 32400,
75510
+ operationCount: 2,
75511
+ events: [
75512
+ {
75513
+ seq: 4,
75514
+ eventType: "tool",
75515
+ kind: "bash",
75516
+ title: "bun run test",
75517
+ toolName: "Bash",
75518
+ durationMs: 6400,
75519
+ durationSource: "measured",
75520
+ tokens: 18200,
75521
+ freshInputTokens: 800,
75522
+ cacheReadTokens: 16500,
75523
+ outputTokens: 900,
75524
+ promptTokens: null,
75525
+ exitCode: 0,
75526
+ payload: "All 64 tests passed",
75527
+ agent: session4.source,
75528
+ model: session4.model
75529
+ },
75530
+ {
75531
+ seq: 5,
75532
+ eventType: "tool",
75533
+ kind: "write",
75534
+ title: "packages/contracts/src/history.ts",
75535
+ toolName: "Edit",
75536
+ durationMs: 2500,
75537
+ durationSource: "measured",
75538
+ tokens: 14200,
75539
+ freshInputTokens: 400,
75540
+ cacheReadTokens: 13000,
75541
+ outputTokens: 800,
75542
+ promptTokens: null,
75543
+ exitCode: 0,
75544
+ payload: "Replaced 42 lines",
75545
+ agent: session4.source,
75546
+ model: session4.model
75547
+ }
75548
+ ]
75549
+ }
75550
+ ];
75551
+ return {
75552
+ mode: "session",
75553
+ scope: {
75554
+ sessionId: session4.id,
75555
+ source: session4.source,
75556
+ model: session4.model,
75557
+ start: new Date(session4.start).toISOString(),
75558
+ end: new Date(session4.start + session4.durationMs).toISOString(),
75559
+ durationMs: session4.durationMs,
75560
+ tokens: session4.tokens,
75561
+ messageCount: session4.messages,
75562
+ toolCallCount: session4.toolCalls,
75563
+ sessionCount: 1
75564
+ },
75565
+ truncated: false,
75566
+ blocks
75567
+ };
75568
+ }
75040
75569
  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
75570
+ mode: "consolidated",
75571
+ scope: {
75572
+ sessionId: null,
75573
+ source: null,
75574
+ model: null,
75575
+ start: this.sessions[0] ? new Date(this.sessions[0].start).toISOString() : null,
75576
+ end: this.sessions.length > 0 && this.sessions[this.sessions.length - 1] ? new Date(this.sessions[this.sessions.length - 1]?.start ?? "").toISOString() : null,
75577
+ durationMs: this.sessions.reduce((s3, x) => s3 + x.durationMs, 0),
75578
+ tokens: {
75579
+ billedTokens: this.sessions.reduce((s3, x) => s3 + x.tokens.billedTokens, 0),
75580
+ cacheSavedTokens: this.sessions.reduce((s3, x) => s3 + x.tokens.cacheSavedTokens, 0),
75581
+ cacheReadTokens: this.sessions.reduce((s3, x) => s3 + x.tokens.cacheReadTokens, 0),
75582
+ freshInputTokens: this.sessions.reduce((s3, x) => s3 + x.tokens.freshInputTokens, 0),
75583
+ outputTokens: this.sessions.reduce((s3, x) => s3 + x.tokens.outputTokens, 0)
75584
+ },
75585
+ messageCount: this.sessions.reduce((s3, x) => s3 + x.messages, 0),
75586
+ toolCallCount: this.sessions.reduce((s3, x) => s3 + x.toolCalls, 0),
75587
+ sessionCount: this.sessions.length
75051
75588
  },
75052
- blocks
75589
+ truncated: false,
75590
+ blocks: []
75053
75591
  };
75054
75592
  }
75055
75593
  async getSessions(input) {
@@ -75492,6 +76030,26 @@ function classifyTimelineKind(toolName, role) {
75492
76030
  }
75493
76031
  return "run";
75494
76032
  }
76033
+ function extractToolTitle(payload) {
76034
+ if (payload == null || payload.trim().length === 0)
76035
+ return "";
76036
+ try {
76037
+ const parsed = JSON.parse(payload);
76038
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
76039
+ return "";
76040
+ const summaryKeys = ["path", "file_path", "target", "cmd", "command", "query", "pattern", "url"];
76041
+ for (const key2 of summaryKeys) {
76042
+ const val = parsed[key2];
76043
+ if (val !== undefined && val !== null) {
76044
+ if (typeof val === "string" && val.length > 0)
76045
+ return val;
76046
+ if (typeof val === "number" || typeof val === "boolean")
76047
+ return String(val);
76048
+ }
76049
+ }
76050
+ } catch {}
76051
+ return "";
76052
+ }
75495
76053
  function projectSummary(rows, extras) {
75496
76054
  const tokenTotal = (row) => row.freshInputTokens + row.outputTokens;
75497
76055
  const totalBilledTokens = rows.models.reduce((sum, row) => sum + tokenTotal(row), 0);
@@ -75814,15 +76372,17 @@ class LiveHistoryBoardService {
75814
76372
  toolErrors: toolStats.reduce((sum, row) => sum + row.errors, 0)
75815
76373
  }, extras);
75816
76374
  }
75817
- async getTimeline(sessionId) {
76375
+ async getTimeline(input) {
75818
76376
  const db2 = await this.resolveDb();
75819
76377
  if (!db2) {
75820
76378
  return {
75821
- session: {
75822
- id: sessionId,
75823
- source: "unknown",
75824
- model: "unknown",
75825
- start: new Date(0).toISOString(),
76379
+ mode: input.mode,
76380
+ scope: {
76381
+ sessionId: input.mode === "session" ? input.sessionId : null,
76382
+ source: input.mode === "session" ? input.source : null,
76383
+ model: null,
76384
+ start: null,
76385
+ end: null,
75826
76386
  durationMs: 0,
75827
76387
  tokens: {
75828
76388
  billedTokens: 0,
@@ -75832,38 +76392,84 @@ class LiveHistoryBoardService {
75832
76392
  outputTokens: 0
75833
76393
  },
75834
76394
  messageCount: 0,
75835
- toolCallCount: 0
76395
+ toolCallCount: 0,
76396
+ sessionCount: 0
75836
76397
  },
76398
+ truncated: false,
75837
76399
  blocks: []
75838
76400
  };
75839
76401
  }
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);
76402
+ let queryResult;
76403
+ if (input.mode === "session") {
76404
+ if (input.sessionId === "" || input.sessionId === "unknown" || input.sessionId === "session") {
76405
+ throw new Error(`History session not found: ${input.sessionId || "(empty)"}`);
76406
+ }
76407
+ if (input.source === "" || input.source === "unknown") {
76408
+ throw new Error(`History source not found: ${input.source || "(empty)"}`);
76409
+ }
76410
+ queryResult = await sessionTimeline(db2, input.source, input.sessionId, 5000);
76411
+ if (queryResult.events.length === 0) {
76412
+ throw new Error(`History session not found: ${input.sessionId}`);
76413
+ }
76414
+ } else {
76415
+ const sel = toArtifactSelector(input.filter);
76416
+ if (input.runId)
76417
+ sel.runId = input.runId;
76418
+ if (input.taskWbs)
76419
+ sel.taskWbs = input.taskWbs;
76420
+ queryResult = await consolidatedTimeline(db2, sel, 5000);
76421
+ }
76422
+ const events2 = queryResult.events;
75844
76423
  if (events2.length === 0) {
75845
- throw new Error(`History session not found: ${sessionId}`);
76424
+ return {
76425
+ mode: input.mode,
76426
+ scope: {
76427
+ sessionId: input.mode === "session" ? input.sessionId : null,
76428
+ source: input.mode === "session" ? input.source : null,
76429
+ model: null,
76430
+ start: null,
76431
+ end: null,
76432
+ durationMs: 0,
76433
+ tokens: {
76434
+ billedTokens: 0,
76435
+ cacheSavedTokens: 0,
76436
+ cacheReadTokens: 0,
76437
+ freshInputTokens: 0,
76438
+ outputTokens: 0
76439
+ },
76440
+ messageCount: 0,
76441
+ toolCallCount: 0,
76442
+ sessionCount: 0
76443
+ },
76444
+ truncated: false,
76445
+ blocks: []
76446
+ };
75846
76447
  }
75847
- let firstTs = null;
75848
- let lastTs = null;
75849
- let source = "unknown";
75850
- let model = "unknown";
76448
+ const projectedEvents = [];
75851
76449
  let totalFresh = 0;
75852
76450
  let totalCache = 0;
75853
76451
  let totalOut = 0;
75854
76452
  let totalDuration = 0;
75855
76453
  let toolCallCount = 0;
75856
76454
  let messageCount = 0;
75857
- const blocksByTurn = new Map;
76455
+ const uniqueSources = new Set;
76456
+ const uniqueModels = new Set;
76457
+ const uniqueSessions = new Set;
76458
+ let firstTs = null;
76459
+ let lastTs = null;
75858
76460
  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;
76461
+ if (ev.ts) {
76462
+ if (firstTs === null || ev.ts < firstTs)
76463
+ firstTs = ev.ts;
76464
+ if (lastTs === null || ev.ts > lastTs)
76465
+ lastTs = ev.ts;
76466
+ }
75863
76467
  if (ev.source)
75864
- source = ev.source;
76468
+ uniqueSources.add(ev.source);
75865
76469
  if (ev.model)
75866
- model = ev.model;
76470
+ uniqueModels.add(ev.model);
76471
+ if (ev.sessionId)
76472
+ uniqueSessions.add(`${ev.source}:::${ev.sessionId}`);
75867
76473
  const fresh = ev.inputTokens ?? 0;
75868
76474
  const cache2 = ev.cacheReadTokens ?? 0;
75869
76475
  const out = ev.outputTokens ?? 0;
@@ -75877,47 +76483,126 @@ class LiveHistoryBoardService {
75877
76483
  toolCallCount += 1;
75878
76484
  else
75879
76485
  messageCount += 1;
75880
- const event = {
76486
+ const title = ev.eventType === "tool" ? extractToolTitle(ev.payload) : ev.role === "user" ? "user turn" : `${ev.role} turn`;
76487
+ projectedEvents.push({
75881
76488
  seq: ev.seq,
75882
76489
  eventType: ev.eventType,
75883
76490
  kind: classifyTimelineKind(ev.toolName, ev.role),
75884
- title: ev.toolName ? `${ev.toolName}` : `${ev.role} turn`,
75885
- durationMs: dur,
76491
+ title,
76492
+ toolName: ev.toolName,
76493
+ durationMs: ev.durationMs,
76494
+ durationSource: ev.durationSource,
75886
76495
  tokens: billed,
75887
76496
  freshInputTokens: fresh,
75888
76497
  cacheReadTokens: cache2,
75889
76498
  outputTokens: out,
76499
+ promptTokens: null,
75890
76500
  exitCode: ev.exitCode,
75891
76501
  payload: ev.payload,
75892
76502
  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
76503
  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);
76504
+ source: ev.source,
76505
+ sessionId: ev.sessionId,
76506
+ turnIndex: ev.turnIndex,
76507
+ ts: ev.ts,
76508
+ correlationExactness: ev.correlationExactness
76509
+ });
76510
+ }
76511
+ const eventsBySession = new Map;
76512
+ for (const ev of projectedEvents) {
76513
+ const sKey = `${ev.source}:::${ev.sessionId}`;
76514
+ let list = eventsBySession.get(sKey);
76515
+ if (list === undefined) {
76516
+ list = [];
76517
+ eventsBySession.set(sKey, list);
76518
+ }
76519
+ list.push(ev);
76520
+ }
76521
+ for (const sessionEvents of eventsBySession.values()) {
76522
+ let activeUserEvent = null;
76523
+ let accFresh = 0;
76524
+ let accCache = 0;
76525
+ let accOut = 0;
76526
+ for (const ev of sessionEvents) {
76527
+ if (ev.kind === "user" || ev.eventType === "message" && ev.title === "user turn") {
76528
+ if (activeUserEvent !== null) {
76529
+ activeUserEvent.promptTokens = {
76530
+ billedTokens: accFresh + accOut,
76531
+ cacheSavedTokens: accCache,
76532
+ cacheReadTokens: accCache,
76533
+ freshInputTokens: accFresh,
76534
+ outputTokens: accOut
76535
+ };
76536
+ }
76537
+ activeUserEvent = ev;
76538
+ accFresh = 0;
76539
+ accCache = 0;
76540
+ accOut = 0;
76541
+ } else {
76542
+ accFresh += ev.freshInputTokens;
76543
+ accCache += ev.cacheReadTokens;
76544
+ accOut += ev.outputTokens;
76545
+ }
76546
+ }
76547
+ if (activeUserEvent !== null) {
76548
+ activeUserEvent.promptTokens = {
76549
+ billedTokens: accFresh + accOut,
76550
+ cacheSavedTokens: accCache,
76551
+ cacheReadTokens: accCache,
76552
+ freshInputTokens: accFresh,
76553
+ outputTokens: accOut
76554
+ };
76555
+ }
75910
76556
  }
76557
+ const blocksByKey = new Map;
76558
+ for (const ev of projectedEvents) {
76559
+ const blockKey = `${ev.source}:::${ev.sessionId}:::${ev.turnIndex}`;
76560
+ let block = blocksByKey.get(blockKey);
76561
+ if (block === undefined) {
76562
+ block = {
76563
+ key: blockKey,
76564
+ sessionId: ev.sessionId,
76565
+ turnIndex: ev.turnIndex,
76566
+ timestamp: ev.ts,
76567
+ source: ev.source,
76568
+ model: ev.model,
76569
+ correlationExactness: ev.correlationExactness ?? null,
76570
+ totalDurationMs: 0,
76571
+ totalTokens: 0,
76572
+ operationCount: 0,
76573
+ events: []
76574
+ };
76575
+ blocksByKey.set(blockKey, block);
76576
+ }
76577
+ block.totalDurationMs += ev.durationMs ?? 0;
76578
+ block.totalTokens += ev.tokens;
76579
+ block.operationCount += 1;
76580
+ if (block.timestamp === null && ev.ts !== null) {
76581
+ block.timestamp = ev.ts;
76582
+ }
76583
+ const { source: _s, sessionId: _sid, turnIndex: _t, ts: _ts, correlationExactness: _ce, ...cleanEv } = ev;
76584
+ block.events.push(cleanEv);
76585
+ }
76586
+ const sortedBlocks = Array.from(blocksByKey.values()).sort((a2, b) => {
76587
+ const aTs = a2.timestamp ? Date.parse(a2.timestamp) : Infinity;
76588
+ const bTs = b.timestamp ? Date.parse(b.timestamp) : Infinity;
76589
+ if (aTs !== bTs)
76590
+ return (Number.isNaN(aTs) ? Infinity : aTs) - (Number.isNaN(bTs) ? Infinity : bTs);
76591
+ return a2.key.localeCompare(b.key);
76592
+ });
75911
76593
  const totalBilled = totalFresh + totalOut;
75912
76594
  const startMs = firstTs ? Date.parse(firstTs) : 0;
75913
76595
  const endMs = lastTs ? Date.parse(lastTs) : startMs;
75914
76596
  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,
76597
+ const firstSource = Array.from(uniqueSources)[0] ?? null;
76598
+ const firstModel = Array.from(uniqueModels)[0] ?? null;
76599
+ const scope = {
76600
+ sessionId: input.mode === "session" ? input.sessionId : null,
76601
+ source: input.mode === "session" ? input.source : uniqueSources.size === 1 ? firstSource : null,
76602
+ model: input.mode === "session" ? uniqueModels.size > 0 ? firstModel : null : uniqueModels.size === 1 ? firstModel : null,
76603
+ start: firstTs,
76604
+ end: lastTs,
76605
+ durationMs: input.mode === "session" && spanMs > 0 ? spanMs : totalDuration,
75921
76606
  tokens: {
75922
76607
  billedTokens: totalBilled,
75923
76608
  cacheSavedTokens: totalCache,
@@ -75926,11 +76611,14 @@ class LiveHistoryBoardService {
75926
76611
  outputTokens: totalOut
75927
76612
  },
75928
76613
  messageCount,
75929
- toolCallCount
76614
+ toolCallCount,
76615
+ sessionCount: input.mode === "session" ? 1 : uniqueSessions.size
75930
76616
  };
75931
76617
  return {
75932
- session: sessionMeta,
75933
- blocks: Array.from(blocksByTurn.values()).sort((a2, b) => a2.turnIndex - b.turnIndex)
76618
+ mode: input.mode,
76619
+ scope,
76620
+ truncated: queryResult.truncated,
76621
+ blocks: sortedBlocks
75934
76622
  };
75935
76623
  }
75936
76624
  async getSessions(input) {
@@ -76240,35 +76928,48 @@ import {
76240
76928
  readdirSync as readdirSync6,
76241
76929
  readFileSync as readFileSync8,
76242
76930
  readlinkSync,
76931
+ realpathSync as realpathSync3,
76243
76932
  rmSync as rmSync4,
76244
76933
  symlinkSync,
76245
76934
  unlinkSync as unlinkSync2,
76246
76935
  writeFileSync as writeFileSync4
76247
76936
  } from "fs";
76248
76937
  import { homedir as homedir5 } from "os";
76249
- import { dirname as dirname11, isAbsolute as isAbsolute3, join as join14, resolve as resolve4 } from "path";
76938
+ import { dirname as dirname11, isAbsolute as isAbsolute3, join as join14, resolve as resolve4, sep } from "path";
76250
76939
  async function buildRefreshCoverage(db2, selector, fanOut) {
76251
76940
  const statusBySource = new Map(fanOut.entries.map((e) => [e.source, e.status]));
76252
76941
  const refreshed = FULL_FIDELITY_SOURCES.filter((s3) => statusBySource.has(s3) && statusBySource.get(s3) !== "failed");
76253
76942
  const { since, until } = await dataWindow(db2, selector);
76254
76943
  return { refreshed, skipped: [...DEFERRED_SOURCES], window: { since, until } };
76255
76944
  }
76256
- function runSessionAugmentedRoots(source, home, cwd) {
76945
+ async function runSessionAugmentedRoots(source, home, cwd, dao2) {
76257
76946
  const roots = getSourceDefinition(source).defaultRoots.map((root) => resolve4(home, root));
76947
+ const runRoots = [];
76258
76948
  const runRoot = join14(cwd, ".spur", "run");
76259
76949
  if (!existsSync5(runRoot))
76260
- return roots;
76950
+ return { roots, runRoots };
76951
+ const sourcesByRun = new Map;
76952
+ for (const row of await dao2.listRunSources()) {
76953
+ const sources = sourcesByRun.get(row.run_id) ?? new Set;
76954
+ sources.add(row.source);
76955
+ sourcesByRun.set(row.run_id, sources);
76956
+ }
76261
76957
  for (const runId of readdirSync6(runRoot)) {
76262
76958
  const sessionsRoot = join14(runRoot, runId, "agent-sessions");
76263
76959
  if (!existsSync5(sessionsRoot))
76264
76960
  continue;
76961
+ const mappedSources = sourcesByRun.get(runId);
76265
76962
  for (const agent of readdirSync6(sessionsRoot)) {
76266
- if (agent === source || agent.startsWith(`${source}-`)) {
76267
- roots.push(join14(sessionsRoot, agent));
76268
- }
76963
+ const directMatch = agent === source || agent.startsWith(`${source}-`);
76964
+ const soleMappedSource = mappedSources?.size === 1 && mappedSources.has(source);
76965
+ if (!directMatch && !soleMappedSource)
76966
+ continue;
76967
+ const root = realpathSync3(join14(sessionsRoot, agent));
76968
+ roots.push(root);
76969
+ runRoots.push({ runId, root });
76269
76970
  }
76270
76971
  }
76271
- return roots;
76972
+ return { roots, runRoots };
76272
76973
  }
76273
76974
 
76274
76975
  class HistoryService {
@@ -76280,21 +76981,31 @@ class HistoryService {
76280
76981
  const parsedSource = parseSource(source);
76281
76982
  const mode = parseMode(opts.mode ?? (opts.file !== undefined ? "force-file" : "incremental"));
76282
76983
  const dryRun = opts.dryRun ?? false;
76984
+ const db2 = await this.ctx.getDb();
76985
+ const dao2 = new RunSessionDao(db2);
76986
+ 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
76987
  const result = parsedSource === "opencode" && opts.file === undefined && opts.root === undefined ? await runOpenCodeImport({
76284
- db: await this.ctx.getDb(),
76988
+ db: db2,
76285
76989
  sourceDatabase: this.ctx.openCodeSourceDatabase,
76286
76990
  mode,
76287
76991
  dryRun
76288
76992
  }) : await runJsonlImport(parsedSource, {
76289
- db: await this.ctx.getDb(),
76993
+ db: db2,
76290
76994
  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
- },
76995
+ ...opts.file !== undefined && opts.file.length > 0 ? { files: [opts.file] } : opts.root !== undefined && opts.root.length > 0 ? { roots: [opts.root] } : { roots: discovery?.roots ?? [] },
76294
76996
  dryRun
76295
76997
  });
76296
76998
  if (!dryRun) {
76297
- await new RunSessionDao(await this.ctx.getDb()).alignMessageProvenance();
76999
+ for (const runRoot of discovery?.runRoots ?? []) {
77000
+ const sourceFilePrefix = runRoot.root.endsWith(sep) ? runRoot.root : `${runRoot.root}${sep}`;
77001
+ await dao2.observeImportedSessions({
77002
+ runId: runRoot.runId,
77003
+ source: parsedSource,
77004
+ sourceFilePrefix,
77005
+ resolvedAt: new Date().toISOString()
77006
+ });
77007
+ }
77008
+ await dao2.alignMessageProvenance();
76298
77009
  }
76299
77010
  return result;
76300
77011
  }
@@ -77649,7 +78360,7 @@ var init_process_inventory_service = __esm(() => {
77649
78360
  });
77650
78361
 
77651
78362
  // ../../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";
78363
+ 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
78364
  import { connect, createServer } from "net";
77654
78365
  import { homedir as homedir6 } from "os";
77655
78366
  import { dirname as dirname12, join as join15, resolve as resolve5 } from "path";
@@ -77665,7 +78376,7 @@ function normalizeProjectPath(pathInput) {
77665
78376
  }
77666
78377
  try {
77667
78378
  if (existsSync6(expanded)) {
77668
- return realpathSync3(expanded);
78379
+ return realpathSync4(expanded);
77669
78380
  }
77670
78381
  } catch {}
77671
78382
  return expanded;
@@ -82758,7 +83469,7 @@ var init_command_gate = __esm(() => {
82758
83469
  });
82759
83470
 
82760
83471
  // ../../packages/app/src/workflow/actions/doctor-probe.ts
82761
- import { normalize as normalize2, resolve as resolve10, sep } from "path";
83472
+ import { normalize as normalize2, resolve as resolve10, sep as sep2 } from "path";
82762
83473
  function splitSpurBin(spurBin) {
82763
83474
  if (SHELL_METACHARACTERS2.test(spurBin)) {
82764
83475
  return { error: `doctor.probe "spurBin" must not contain shell metacharacters (got ${spurBin})` };
@@ -82822,7 +83533,7 @@ class DoctorProbeActionRunner {
82822
83533
  const workdir = context4.workdir ?? process.cwd();
82823
83534
  const allowedDir = resolve10(workdir, ".spur", "run");
82824
83535
  const normalized = normalize2(resolve10(workdir, resultFileRaw));
82825
- const withinAllowed = normalized === allowedDir || normalized.startsWith(allowedDir + sep);
83536
+ const withinAllowed = normalized === allowedDir || normalized.startsWith(allowedDir + sep2);
82826
83537
  if (!withinAllowed) {
82827
83538
  return {
82828
83539
  ok: false,
@@ -86151,19 +86862,19 @@ var {
86151
86862
  init_src();
86152
86863
  init_loader();
86153
86864
 
86154
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/application-node.js
86865
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/application-node.js
86155
86866
  init_dist4();
86156
86867
  init_dist5();
86157
86868
  import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync5 } from "fs";
86158
86869
  import { dirname as dirname5 } from "path";
86159
86870
 
86160
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/application/index.js
86871
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/application/index.js
86161
86872
  init_default_observers();
86162
86873
  init_event_bus();
86163
86874
  init_file_observer();
86164
86875
  init_logger3();
86165
86876
 
86166
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/scheduler/noop.js
86877
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/scheduler/noop.js
86167
86878
  class NoopSchedulerAdapter {
86168
86879
  constructor() {}
86169
86880
  register(_cron, _action) {}
@@ -86171,7 +86882,7 @@ class NoopSchedulerAdapter {
86171
86882
  async stop() {}
86172
86883
  }
86173
86884
 
86174
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/scheduler/factory.js
86885
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/scheduler/factory.js
86175
86886
  function initScheduler(adapter, cronEntries) {
86176
86887
  const resolved = adapter ?? new NoopSchedulerAdapter;
86177
86888
  if (cronEntries) {
@@ -86182,7 +86893,7 @@ function initScheduler(adapter, cronEntries) {
86182
86893
  return resolved;
86183
86894
  }
86184
86895
 
86185
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/application/plugins/builtins.js
86896
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/application/plugins/builtins.js
86186
86897
  init_logger3();
86187
86898
  init_metrics();
86188
86899
  init_sdk();
@@ -86275,7 +86986,7 @@ function dbPlugin(db2) {
86275
86986
  };
86276
86987
  }
86277
86988
 
86278
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/application/plugins/host.js
86989
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/application/plugins/host.js
86279
86990
  init_logger3();
86280
86991
 
86281
86992
  class PluginHost {
@@ -86363,7 +87074,7 @@ class PluginHost {
86363
87074
  }
86364
87075
  }
86365
87076
 
86366
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/application/index.js
87077
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/application/index.js
86367
87078
  async function performShutdown(state, reason) {
86368
87079
  if (state.stopped)
86369
87080
  return;
@@ -86474,10 +87185,10 @@ async function runApplication(options) {
86474
87185
  }
86475
87186
  }
86476
87187
 
86477
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/application-node.js
87188
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/application-node.js
86478
87189
  init_scheduler_node();
86479
87190
 
86480
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
87191
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
86481
87192
  var import_api14 = __toESM(require_src(), 1);
86482
87193
 
86483
87194
  // ../../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 +90204,7 @@ class OTLPTraceExporter extends import_otlp_exporter_base2.OTLPExporterBase {
89493
90204
  }), JsonTraceSerializer));
89494
90205
  }
89495
90206
  }
89496
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
90207
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
89497
90208
  var import_resources2 = __toESM(require_src4(), 1);
89498
90209
  var import_sdk_trace_node = __toESM(require_src8(), 1);
89499
90210
  var import_semantic_conventions = __toESM(require_src2(), 1);
@@ -89544,7 +90255,7 @@ async function shutdownNodeTelemetry() {
89544
90255
  await Promise.all(pending);
89545
90256
  }
89546
90257
 
89547
- // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.41+71f966dea5e7e2de/node_modules/@gobing-ai/ts-infra/dist/application-node.js
90258
+ // ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.42+4012563f10a1cd34/node_modules/@gobing-ai/ts-infra/dist/application-node.js
89548
90259
  class ConfigValidationError extends Error {
89549
90260
  constructor(message) {
89550
90261
  super(message);
@@ -94215,9 +94926,9 @@ Done (local). Review, then push to release:`);
94215
94926
  }
94216
94927
  output2.write(`
94217
94928
  Pushing branch ${branch} (tags excluded)...`);
94218
- await git2(ctx.repoRoot, ["push", "origin", branch]);
94929
+ await git2(ctx.repoRoot, ["push", "--no-follow-tags", "origin", branch]);
94219
94930
  output2.write(`Pushing release trigger tag ${tag}...`);
94220
- await git2(ctx.repoRoot, ["push", "origin", tag]);
94931
+ await git2(ctx.repoRoot, ["push", "--no-follow-tags", "origin", tag]);
94221
94932
  output2.write(`
94222
94933
  Released ${version3}. The publish workflow should now be running:`);
94223
94934
  output2.write(` gh run list --workflow=${config4.publishWorkflow} --limit ${config4.ghRunListLimit}`);
@@ -94298,9 +95009,9 @@ Done (local). Review, then push to release:`);
94298
95009
  }
94299
95010
  output2.write(`
94300
95011
  Pushing branch ${branch} (tags excluded)...`);
94301
- await git2(ctx.repoRoot, ["push", "origin", branch]);
95012
+ await git2(ctx.repoRoot, ["push", "--no-follow-tags", "origin", branch]);
94302
95013
  output2.write(`Pushing release trigger tag ${aggregateTag}...`);
94303
- await git2(ctx.repoRoot, ["push", "origin", aggregateTag]);
95014
+ await git2(ctx.repoRoot, ["push", "--no-follow-tags", "origin", aggregateTag]);
94304
95015
  output2.write(`
94305
95016
  Released ${version3}. The publish workflow should now be running:`);
94306
95017
  output2.write(" gh run list --workflow=publish.yml --limit 3");
@@ -94941,7 +95652,7 @@ import { createRequire } from "module";
94941
95652
  var CLI_CONFIG = {
94942
95653
  binaryName: "spur",
94943
95654
  binaryLabel: "spur",
94944
- binaryVersion: "0.3.58",
95655
+ binaryVersion: "0.3.60",
94945
95656
  configDir: ".spur",
94946
95657
  configFile: ".spur/config.yaml",
94947
95658
  databaseFile: ".spur/spur.db"
@@ -95268,7 +95979,7 @@ var SCAFFOLD_MANIFEST = [
95268
95979
  // src/commands/init.ts
95269
95980
  var GLOBAL_CONFIG_DIR2 = join26(".config", "spur");
95270
95981
  var GLOBAL_RULES_DIR2 = join26(GLOBAL_CONFIG_DIR2, "rules");
95271
- var GLOBAL_CONFIG_EXAMPLE = "config.example.yaml";
95982
+ var GLOBAL_CONFIG_EXAMPLE = BUNDLED_GLOBAL_CONFIG;
95272
95983
  var GLOBAL_CONFIG_FILE2 = "config.yaml";
95273
95984
  var INDEXED_CONTEXT_MARKER = "## Indexed context";
95274
95985
  function substituteAgentsMdTemplate(content, projectName) {
@@ -95369,7 +96080,7 @@ function registerInitCommand(program2, context4, options = {}) {
95369
96080
  `# Generated by \`spur init\``,
95370
96081
  "",
95371
96082
  '$schema: "@gobing-ai/spur/schemas/spur-config.schema.json"',
95372
- `version: "1.1"`,
96083
+ `version: "1.2"`,
95373
96084
  `name: ${projectName}`,
95374
96085
  "",
95375
96086
  "bootstrap:",
@@ -102210,44 +102921,68 @@ var historyTimelineEventKindEnum = exports_external.enum([
102210
102921
  "assistant",
102211
102922
  "unknown"
102212
102923
  ]);
102924
+ var historyDurationSourceEnum = exports_external.enum(["measured", "inferred", "unmeasured"]);
102925
+ var historyCorrelationExactnessEnum = exports_external.enum(["exact", "estimated"]);
102926
+ var historyTimelineInputSchema = exports_external.discriminatedUnion("mode", [
102927
+ exports_external.object({
102928
+ mode: exports_external.literal("session"),
102929
+ source: exports_external.string().min(1),
102930
+ sessionId: exports_external.string().min(1)
102931
+ }),
102932
+ exports_external.object({
102933
+ mode: exports_external.literal("consolidated"),
102934
+ filter: historyFilterSchema.optional(),
102935
+ taskWbs: exports_external.string().optional(),
102936
+ runId: exports_external.string().optional()
102937
+ })
102938
+ ]);
102213
102939
  var historyTimelineEventSchema = exports_external.object({
102214
102940
  seq: exports_external.number(),
102215
102941
  eventType: exports_external.enum(["message", "tool"]),
102216
102942
  kind: historyTimelineEventKindEnum,
102217
102943
  title: exports_external.string(),
102218
- durationMs: exports_external.number(),
102944
+ toolName: exports_external.string().nullable(),
102945
+ durationMs: exports_external.number().nullable(),
102946
+ durationSource: historyDurationSourceEnum,
102219
102947
  tokens: exports_external.number(),
102220
102948
  freshInputTokens: exports_external.number(),
102221
102949
  cacheReadTokens: exports_external.number(),
102222
102950
  outputTokens: exports_external.number(),
102951
+ promptTokens: historyTokensSchema.nullable(),
102223
102952
  exitCode: exports_external.number().nullable(),
102224
102953
  payload: exports_external.string().nullable(),
102225
102954
  agent: exports_external.string(),
102226
102955
  model: exports_external.string()
102227
102956
  });
102228
102957
  var historyTimelineBlockSchema = exports_external.object({
102958
+ key: exports_external.string(),
102959
+ sessionId: exports_external.string(),
102229
102960
  turnIndex: exports_external.number(),
102230
- timestamp: exports_external.string(),
102961
+ timestamp: exports_external.string().nullable(),
102231
102962
  source: exports_external.string(),
102232
102963
  model: exports_external.string(),
102964
+ correlationExactness: historyCorrelationExactnessEnum.nullable(),
102233
102965
  totalDurationMs: exports_external.number(),
102234
102966
  totalTokens: exports_external.number(),
102235
102967
  operationCount: exports_external.number(),
102236
102968
  events: exports_external.array(historyTimelineEventSchema)
102237
102969
  });
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(),
102970
+ var historyTimelineScopeSchema = exports_external.object({
102971
+ sessionId: exports_external.string().nullable(),
102972
+ source: exports_external.string().nullable(),
102973
+ model: exports_external.string().nullable(),
102974
+ start: exports_external.string().nullable(),
102975
+ end: exports_external.string().nullable(),
102244
102976
  durationMs: exports_external.number(),
102245
102977
  tokens: historyTokensSchema,
102246
102978
  messageCount: exports_external.number(),
102247
- toolCallCount: exports_external.number()
102979
+ toolCallCount: exports_external.number(),
102980
+ sessionCount: exports_external.number()
102248
102981
  });
102249
102982
  var historyTimelineResponseDataSchema = exports_external.object({
102250
- session: historyTimelineSessionMetaSchema,
102983
+ mode: exports_external.enum(["session", "consolidated"]),
102984
+ scope: historyTimelineScopeSchema,
102985
+ truncated: exports_external.boolean(),
102251
102986
  blocks: exports_external.array(historyTimelineBlockSchema)
102252
102987
  });
102253
102988
  var historyTimelineResponseSchema = apiSuccessSchema(historyTimelineResponseDataSchema);
@@ -102392,11 +103127,11 @@ var historyContract = {
102392
103127
  tags: ["history"]
102393
103128
  }).input(historyFilterSchema.optional()).output(historySummaryResponseSchema),
102394
103129
  getTimeline: oc.route({
102395
- method: "GET",
102396
- path: "/history/timeline/{sessionId}",
102397
- summary: "Get chronological session execution timeline",
103130
+ method: "POST",
103131
+ path: "/history/timeline",
103132
+ summary: "Get chronological session or consolidated execution timeline",
102398
103133
  tags: ["history"]
102399
- }).input(exports_external.object({ sessionId: exports_external.string() })).output(historyTimelineResponseSchema),
103134
+ }).input(historyTimelineInputSchema).output(historyTimelineResponseSchema),
102400
103135
  getSessions: oc.route({
102401
103136
  method: "POST",
102402
103137
  path: "/history/sessions",
@@ -102806,7 +103541,7 @@ function createHistoryHandlers(ctx) {
102806
103541
  return { ok: true, data };
102807
103542
  }),
102808
103543
  getTimeline: os3.history.getTimeline.handler(async ({ input }) => {
102809
- const data = await ctx.historyBoardService().getTimeline(input.sessionId);
103544
+ const data = await ctx.historyBoardService().getTimeline(input);
102810
103545
  return { ok: true, data };
102811
103546
  }),
102812
103547
  getSessions: os3.history.getSessions.handler(async ({ input }) => {
@@ -106422,7 +107157,6 @@ var spur_config_schema_default = {
106422
107157
  title: "Spur Project Configuration",
106423
107158
  description: "Schema for .spur/config.yaml \u2014 the single project configuration surface consumed by spur and (future) spur-server.",
106424
107159
  type: "object",
106425
- required: ["version", "name"],
106426
107160
  properties: {
106427
107161
  $schema: {
106428
107162
  type: "string",