syntaur 0.61.0 → 0.64.0

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 (69) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +49 -0
  3. package/dashboard/dist/assets/{_basePickBy-CpFuPIT8.js → _basePickBy-CwwFEBj8.js} +1 -1
  4. package/dashboard/dist/assets/{_baseUniq-DUrsBbod.js → _baseUniq-BoxAvlar.js} +1 -1
  5. package/dashboard/dist/assets/{arc-D432bgcA.js → arc-DohD31yM.js} +1 -1
  6. package/dashboard/dist/assets/{architectureDiagram-2XIMDMQ5--gLudksM.js → architectureDiagram-2XIMDMQ5-J4SdvLJs.js} +1 -1
  7. package/dashboard/dist/assets/{blockDiagram-WCTKOSBZ-MGtlXwaM.js → blockDiagram-WCTKOSBZ-BHuFRK4q.js} +1 -1
  8. package/dashboard/dist/assets/{c4Diagram-IC4MRINW-BYOcEzmn.js → c4Diagram-IC4MRINW-C5jiXpiB.js} +1 -1
  9. package/dashboard/dist/assets/channel-3-4_gf6X.js +1 -0
  10. package/dashboard/dist/assets/{chunk-4BX2VUAB-B8mKqMx3.js → chunk-4BX2VUAB-CcShTIhb.js} +1 -1
  11. package/dashboard/dist/assets/{chunk-55IACEB6-Cx1rZTFA.js → chunk-55IACEB6-BJDZp3Ih.js} +1 -1
  12. package/dashboard/dist/assets/{chunk-FMBD7UC4-Bx55uyLu.js → chunk-FMBD7UC4-DgX8V3qh.js} +1 -1
  13. package/dashboard/dist/assets/{chunk-JSJVCQXG-BRDbVMuU.js → chunk-JSJVCQXG-DnYWrOFd.js} +1 -1
  14. package/dashboard/dist/assets/{chunk-KX2RTZJC-6xpnX7LD.js → chunk-KX2RTZJC-CvsjbfkS.js} +1 -1
  15. package/dashboard/dist/assets/{chunk-NQ4KR5QH-B90im-ae.js → chunk-NQ4KR5QH-DVLwGTNn.js} +1 -1
  16. package/dashboard/dist/assets/{chunk-QZHKN3VN-CIozyGqe.js → chunk-QZHKN3VN-CFNsM5VV.js} +1 -1
  17. package/dashboard/dist/assets/{chunk-WL4C6EOR-DysZoi-Z.js → chunk-WL4C6EOR-BgvnUwmv.js} +1 -1
  18. package/dashboard/dist/assets/classDiagram-VBA2DB6C-CrATshpz.js +1 -0
  19. package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-CrATshpz.js +1 -0
  20. package/dashboard/dist/assets/clone-CfV5MG52.js +1 -0
  21. package/dashboard/dist/assets/{cose-bilkent-S5V4N54A-CxwMsTG4.js → cose-bilkent-S5V4N54A-C4aLmHe0.js} +1 -1
  22. package/dashboard/dist/assets/{dagre-KLK3FWXG-BRZfhvx6.js → dagre-KLK3FWXG-BN-9NtEU.js} +1 -1
  23. package/dashboard/dist/assets/{diagram-E7M64L7V-BKAvlo24.js → diagram-E7M64L7V-CeYAeYg6.js} +1 -1
  24. package/dashboard/dist/assets/{diagram-IFDJBPK2-Colncoj8.js → diagram-IFDJBPK2-DwKlGh9_.js} +1 -1
  25. package/dashboard/dist/assets/{diagram-P4PSJMXO-CtWHVVRh.js → diagram-P4PSJMXO-Brl0MDaZ.js} +1 -1
  26. package/dashboard/dist/assets/{erDiagram-INFDFZHY-DsDvyrXT.js → erDiagram-INFDFZHY-DUyLXkUI.js} +1 -1
  27. package/dashboard/dist/assets/{flowDiagram-PKNHOUZH-DFZFPrVO.js → flowDiagram-PKNHOUZH-DBgZTa3b.js} +1 -1
  28. package/dashboard/dist/assets/{ganttDiagram-A5KZAMGK-DMgPno3v.js → ganttDiagram-A5KZAMGK-CTMXhGer.js} +1 -1
  29. package/dashboard/dist/assets/{gitGraphDiagram-K3NZZRJ6-DL7Z4Kd-.js → gitGraphDiagram-K3NZZRJ6-CMeLom6N.js} +1 -1
  30. package/dashboard/dist/assets/{graph-DjCGNe8r.js → graph-BQZrNogB.js} +1 -1
  31. package/dashboard/dist/assets/{index-CdBsPuM_.css → index-DlUgV5eO.css} +1 -1
  32. package/dashboard/dist/assets/index-tUNHiaW4.js +659 -0
  33. package/dashboard/dist/assets/{infoDiagram-LFFYTUFH-ms6VllLp.js → infoDiagram-LFFYTUFH-CfiYCGUc.js} +1 -1
  34. package/dashboard/dist/assets/{ishikawaDiagram-PHBUUO56-E1P19ow4.js → ishikawaDiagram-PHBUUO56-WSdBFOoI.js} +1 -1
  35. package/dashboard/dist/assets/{journeyDiagram-4ABVD52K-I8hleVZ7.js → journeyDiagram-4ABVD52K-u-S5-YRq.js} +1 -1
  36. package/dashboard/dist/assets/{kanban-definition-K7BYSVSG-CrFYF8VU.js → kanban-definition-K7BYSVSG-B5sU56Sm.js} +1 -1
  37. package/dashboard/dist/assets/{layout-BT_qm2gQ.js → layout-CH9z9Vzx.js} +1 -1
  38. package/dashboard/dist/assets/{linear-D1rmw3D_.js → linear-C-SiDLxL.js} +1 -1
  39. package/dashboard/dist/assets/{mermaid.core-DfYtUVoE.js → mermaid.core-CGgij72_.js} +4 -4
  40. package/dashboard/dist/assets/{mindmap-definition-YRQLILUH-CcN1oeHQ.js → mindmap-definition-YRQLILUH-yu7UCSjb.js} +1 -1
  41. package/dashboard/dist/assets/{pieDiagram-SKSYHLDU-BbZTHYrC.js → pieDiagram-SKSYHLDU-BGSUgFeI.js} +1 -1
  42. package/dashboard/dist/assets/{quadrantDiagram-337W2JSQ-ChjNzTQr.js → quadrantDiagram-337W2JSQ-XnJqntVQ.js} +1 -1
  43. package/dashboard/dist/assets/{requirementDiagram-Z7DCOOCP-DighcHqU.js → requirementDiagram-Z7DCOOCP-CZ5tl3qr.js} +1 -1
  44. package/dashboard/dist/assets/{sankeyDiagram-WA2Y5GQK-Bw4_y6_j.js → sankeyDiagram-WA2Y5GQK-CgcGiKDB.js} +1 -1
  45. package/dashboard/dist/assets/{sequenceDiagram-2WXFIKYE-DHZQ0Yib.js → sequenceDiagram-2WXFIKYE--GDQSqiF.js} +1 -1
  46. package/dashboard/dist/assets/{stateDiagram-RAJIS63D-BawDJGJV.js → stateDiagram-RAJIS63D-sbaNsQ3O.js} +1 -1
  47. package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-Cr-Lm_NG.js +1 -0
  48. package/dashboard/dist/assets/{timeline-definition-YZTLITO2-7GEcb3Ip.js → timeline-definition-YZTLITO2-DieNq8qp.js} +1 -1
  49. package/dashboard/dist/assets/{treemap-KZPCXAKY-BNijr4yg.js → treemap-KZPCXAKY-CND0AGzG.js} +1 -1
  50. package/dashboard/dist/assets/{vennDiagram-LZ73GAT5-OAAr6jJ3.js → vennDiagram-LZ73GAT5-C32CbTtv.js} +1 -1
  51. package/dashboard/dist/assets/{xychartDiagram-JWTSCODW-Bz61FhCg.js → xychartDiagram-JWTSCODW-I-8Tu4ki.js} +1 -1
  52. package/dashboard/dist/index.html +2 -2
  53. package/dist/dashboard/server.js +1415 -579
  54. package/dist/dashboard/server.js.map +1 -1
  55. package/dist/index.js +2505 -1172
  56. package/dist/index.js.map +1 -1
  57. package/dist/launch/index.js +126 -95
  58. package/dist/launch/index.js.map +1 -1
  59. package/package.json +1 -1
  60. package/platforms/claude-code/.claude-plugin/plugin.json +1 -1
  61. package/platforms/codex/.codex-plugin/plugin.json +1 -1
  62. package/platforms/hermes/plugins/syntaur/__pycache__/__init__.cpython-312.pyc +0 -0
  63. package/platforms/hermes/plugins/syntaur/__pycache__/boundary.cpython-312.pyc +0 -0
  64. package/dashboard/dist/assets/channel-HTXYrjhV.js +0 -1
  65. package/dashboard/dist/assets/classDiagram-VBA2DB6C-Ci3W9L6H.js +0 -1
  66. package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-Ci3W9L6H.js +0 -1
  67. package/dashboard/dist/assets/clone-B3CnX-J-.js +0 -1
  68. package/dashboard/dist/assets/index-B_1c_Ctq.js +0 -644
  69. package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO--P1IwIK8.js +0 -1
@@ -365,6 +365,33 @@ var init_frontmatter = __esm({
365
365
  }
366
366
  });
367
367
 
368
+ // src/utils/uuid.ts
369
+ import { randomUUID } from "crypto";
370
+ var init_uuid = __esm({
371
+ "src/utils/uuid.ts"() {
372
+ "use strict";
373
+ }
374
+ });
375
+
376
+ // src/db/events-db.ts
377
+ import Database from "better-sqlite3";
378
+ import { resolve as resolve3 } from "path";
379
+ var init_events_db = __esm({
380
+ "src/db/events-db.ts"() {
381
+ "use strict";
382
+ init_paths();
383
+ init_uuid();
384
+ }
385
+ });
386
+
387
+ // src/lifecycle/event-emit.ts
388
+ var init_event_emit = __esm({
389
+ "src/lifecycle/event-emit.ts"() {
390
+ "use strict";
391
+ init_events_db();
392
+ }
393
+ });
394
+
368
395
  // src/dashboard/parser.ts
369
396
  function extractFrontmatter(fileContent) {
370
397
  const match = fileContent.match(/^---\n([\s\S]*?)\n---/);
@@ -779,7 +806,7 @@ var init_parser = __esm({
779
806
  // src/todos/parser.ts
780
807
  import { randomBytes } from "crypto";
781
808
  import { readFile as readFile3 } from "fs/promises";
782
- import { resolve as resolve3 } from "path";
809
+ import { resolve as resolve4 } from "path";
783
810
  var init_parser2 = __esm({
784
811
  "src/todos/parser.ts"() {
785
812
  "use strict";
@@ -790,7 +817,7 @@ var init_parser2 = __esm({
790
817
 
791
818
  // src/lifecycle/linked-todos.ts
792
819
  import { readdir as readdir2 } from "fs/promises";
793
- import { resolve as resolve4 } from "path";
820
+ import { resolve as resolve5 } from "path";
794
821
  var init_linked_todos = __esm({
795
822
  "src/lifecycle/linked-todos.ts"() {
796
823
  "use strict";
@@ -800,7 +827,7 @@ var init_linked_todos = __esm({
800
827
  });
801
828
 
802
829
  // src/lifecycle/transitions.ts
803
- import { resolve as resolve5 } from "path";
830
+ import { resolve as resolve6 } from "path";
804
831
  import { readFile as readFile4 } from "fs/promises";
805
832
  var init_transitions = __esm({
806
833
  "src/lifecycle/transitions.ts"() {
@@ -809,6 +836,7 @@ var init_transitions = __esm({
809
836
  init_timestamp();
810
837
  init_state_machine();
811
838
  init_frontmatter();
839
+ init_event_emit();
812
840
  init_linked_todos();
813
841
  }
814
842
  });
@@ -1188,11 +1216,14 @@ var init_fields = __esm({
1188
1216
  });
1189
1217
 
1190
1218
  // src/utils/query/evaluate.ts
1191
- function localDayBounds(date) {
1192
- const [y, m, d] = date.split("-").map((n) => parseInt(n, 10));
1193
- const start = new Date(y, m - 1, d).getTime();
1219
+ function localDayBounds(value) {
1220
+ const [y, m, d] = value.raw.split("-").map((n) => parseInt(n, 10));
1221
+ const start = new Date(y, m - 1, d);
1222
+ if (start.getFullYear() !== y || start.getMonth() !== m - 1 || start.getDate() !== d) {
1223
+ throw new CompileError([{ pos: value.pos, message: `Invalid date "${value.raw}"` }]);
1224
+ }
1194
1225
  const end = new Date(y, m - 1, d + 1).getTime();
1195
- return [start, end];
1226
+ return [start.getTime(), end];
1196
1227
  }
1197
1228
  function toEpoch(value) {
1198
1229
  if (typeof value === "number") return Number.isFinite(value) ? value : null;
@@ -1259,7 +1290,7 @@ function compileEquality(def, field, value, atomPos) {
1259
1290
  };
1260
1291
  case "timestamp": {
1261
1292
  if (value.type === "date") {
1262
- const [start, end] = localDayBounds(value.raw);
1293
+ const [start, end] = localDayBounds(value);
1263
1294
  return (item) => {
1264
1295
  const t = toEpoch(readField(def, field, item));
1265
1296
  return t !== null && t >= start && t < end;
@@ -1329,7 +1360,7 @@ function compileComparison(def, field, op, value) {
1329
1360
  };
1330
1361
  }
1331
1362
  if (value.type === "date") {
1332
- const [start, end] = localDayBounds(value.raw);
1363
+ const [start, end] = localDayBounds(value);
1333
1364
  return (item) => {
1334
1365
  const t = toEpoch(readField(def, field, item));
1335
1366
  if (t === null) return false;
@@ -1605,7 +1636,7 @@ var init_lexer = __esm({
1605
1636
  };
1606
1637
  IDENT_START = /[A-Za-z_]/;
1607
1638
  IDENT_CHAR = /[A-Za-z0-9_-]/;
1608
- DATE_RE = /^\d{4}-\d{2}-\d{2}/;
1639
+ DATE_RE = /^\d{4}-\d{2}-\d{2}(?![\d-])/;
1609
1640
  }
1610
1641
  });
1611
1642
 
@@ -2146,7 +2177,7 @@ __export(config_exports, {
2146
2177
  });
2147
2178
  import { readFile as readFile5 } from "fs/promises";
2148
2179
  import { spawnSync } from "child_process";
2149
- import { resolve as resolve6, isAbsolute } from "path";
2180
+ import { resolve as resolve7, isAbsolute } from "path";
2150
2181
  function parseAgentCommand(value, agentId) {
2151
2182
  if (typeof value !== "string" || value.trim() === "") {
2152
2183
  throw new AgentConfigError(
@@ -2155,7 +2186,7 @@ function parseAgentCommand(value, agentId) {
2155
2186
  }
2156
2187
  const expanded = expandHome(value.trim());
2157
2188
  if (isAbsolute(expanded)) {
2158
- return resolve6(expanded);
2189
+ return resolve7(expanded);
2159
2190
  }
2160
2191
  if (expanded.includes("/")) {
2161
2192
  throw new AgentConfigError(
@@ -2618,7 +2649,7 @@ function parsePlaybooksConfig(fmBlock) {
2618
2649
  return { disabled };
2619
2650
  }
2620
2651
  async function updatePlaybooksConfig(playbooks) {
2621
- const configPath = resolve6(syntaurRoot(), "config.md");
2652
+ const configPath = resolve7(syntaurRoot(), "config.md");
2622
2653
  const current = (await readConfig()).playbooks;
2623
2654
  const nextPlaybooks = {
2624
2655
  disabled: Array.from(new Set(playbooks.disabled ?? current.disabled))
@@ -2674,7 +2705,7 @@ function serializeThemeConfig(theme) {
2674
2705
  return ["theme:", ` preset: ${theme.preset}`].join("\n");
2675
2706
  }
2676
2707
  async function writeThemeConfig(theme) {
2677
- const configPath = resolve6(syntaurRoot(), "config.md");
2708
+ const configPath = resolve7(syntaurRoot(), "config.md");
2678
2709
  const themeBlock = serializeThemeConfig(theme);
2679
2710
  const existing = await fileExists(configPath) ? await readFile5(configPath, "utf-8") : renderConfig({ defaultProjectDir: defaultProjectDir() });
2680
2711
  const fmMatch = existing.match(/^(---\n)([\s\S]*?)\n(---)/);
@@ -2700,7 +2731,7 @@ ${normalizedFm}
2700
2731
  await writeFileForce(configPath, newContent);
2701
2732
  }
2702
2733
  async function deleteThemeConfig() {
2703
- const configPath = resolve6(syntaurRoot(), "config.md");
2734
+ const configPath = resolve7(syntaurRoot(), "config.md");
2704
2735
  if (!await fileExists(configPath)) return;
2705
2736
  const existing = await readFile5(configPath, "utf-8");
2706
2737
  const fmMatch = existing.match(/^(---\n)([\s\S]*?)\n(---)/);
@@ -2760,7 +2791,7 @@ function parseWorkspaceVisibilityConfig(fmBlock) {
2760
2791
  return { hidden: normalizeHiddenList(hidden) };
2761
2792
  }
2762
2793
  async function writeWorkspaceVisibilityConfig(cfg) {
2763
- const configPath = resolve6(syntaurRoot(), "config.md");
2794
+ const configPath = resolve7(syntaurRoot(), "config.md");
2764
2795
  const block = serializeWorkspaceVisibilityConfig(cfg);
2765
2796
  const existing = await fileExists(configPath) ? await readFile5(configPath, "utf-8") : renderConfig({ defaultProjectDir: defaultProjectDir() });
2766
2797
  const fmMatch = existing.match(/^(---\n)([\s\S]*?)\n(---)/);
@@ -2787,7 +2818,7 @@ ${normalizedFm}
2787
2818
  await writeFileForce(configPath, newContent);
2788
2819
  }
2789
2820
  async function deleteWorkspaceVisibilityConfig() {
2790
- const configPath = resolve6(syntaurRoot(), "config.md");
2821
+ const configPath = resolve7(syntaurRoot(), "config.md");
2791
2822
  if (!await fileExists(configPath)) return;
2792
2823
  const existing = await readFile5(configPath, "utf-8");
2793
2824
  const fmMatch = existing.match(/^(---\n)([\s\S]*?)\n(---)/);
@@ -2807,7 +2838,7 @@ function stripTopLevelScalar(fmBlock, key) {
2807
2838
  return filtered.join("\n").replace(/\n+$/, "");
2808
2839
  }
2809
2840
  async function writeTerminalConfig(terminal) {
2810
- const configPath = resolve6(syntaurRoot(), "config.md");
2841
+ const configPath = resolve7(syntaurRoot(), "config.md");
2811
2842
  const terminalLine = `terminal: ${terminal}`;
2812
2843
  const existing = await fileExists(configPath) ? await readFile5(configPath, "utf-8") : renderConfig({ defaultProjectDir: defaultProjectDir() });
2813
2844
  const fmMatch = existing.match(/^(---\n)([\s\S]*?)\n(---)/);
@@ -2833,7 +2864,7 @@ ${normalizedFm}
2833
2864
  await writeFileForce(configPath, newContent);
2834
2865
  }
2835
2866
  async function deleteTerminalConfig() {
2836
- const configPath = resolve6(syntaurRoot(), "config.md");
2867
+ const configPath = resolve7(syntaurRoot(), "config.md");
2837
2868
  if (!await fileExists(configPath)) return;
2838
2869
  const existing = await readFile5(configPath, "utf-8");
2839
2870
  const fmMatch = existing.match(/^(---\n)([\s\S]*?)\n(---)/);
@@ -2902,7 +2933,7 @@ async function writeHotkeyBindingsConfig(cfg) {
2902
2933
  await deleteHotkeyBindingsConfig();
2903
2934
  return;
2904
2935
  }
2905
- const configPath = resolve6(syntaurRoot(), "config.md");
2936
+ const configPath = resolve7(syntaurRoot(), "config.md");
2906
2937
  const block = serializeHotkeyBindingsConfig({ bindings: cleaned });
2907
2938
  const existing = await fileExists(configPath) ? await readFile5(configPath, "utf-8") : renderConfig({ defaultProjectDir: defaultProjectDir() });
2908
2939
  const fmMatch = existing.match(/^(---\n)([\s\S]*?)\n(---)/);
@@ -2928,7 +2959,7 @@ ${normalizedFm}
2928
2959
  await writeFileForce(configPath, newContent);
2929
2960
  }
2930
2961
  async function deleteHotkeyBindingsConfig() {
2931
- const configPath = resolve6(syntaurRoot(), "config.md");
2962
+ const configPath = resolve7(syntaurRoot(), "config.md");
2932
2963
  if (!await fileExists(configPath)) return;
2933
2964
  const existing = await readFile5(configPath, "utf-8");
2934
2965
  const fmMatch = existing.match(/^(---\n)([\s\S]*?)\n(---)/);
@@ -2975,7 +3006,7 @@ function parseOptionalAbsolutePath(value, fieldName) {
2975
3006
  );
2976
3007
  return null;
2977
3008
  }
2978
- return resolve6(expanded);
3009
+ return resolve7(expanded);
2979
3010
  }
2980
3011
  function parseAgentsConfig(content) {
2981
3012
  const match = content.match(/^---\n([\s\S]*?)\n---/);
@@ -3266,7 +3297,7 @@ function appendSessionInvocation(lines, key, invocation) {
3266
3297
  }
3267
3298
  async function writeAgentsConfig(agents) {
3268
3299
  validateAgentList(agents);
3269
- const configPath = resolve6(syntaurRoot(), "config.md");
3300
+ const configPath = resolve7(syntaurRoot(), "config.md");
3270
3301
  const agentsBlock = serializeAgentsConfig(agents);
3271
3302
  const existing = await fileExists(configPath) ? await readFile5(configPath, "utf-8") : renderConfig({ defaultProjectDir: defaultProjectDir() });
3272
3303
  const fmMatch = existing.match(/^(---\n)([\s\S]*?)\n(---)/);
@@ -3291,7 +3322,7 @@ ${newFm}
3291
3322
  await writeFileForce(configPath, newContent);
3292
3323
  }
3293
3324
  async function deleteAgentsConfig() {
3294
- const configPath = resolve6(syntaurRoot(), "config.md");
3325
+ const configPath = resolve7(syntaurRoot(), "config.md");
3295
3326
  if (!await fileExists(configPath)) return;
3296
3327
  const existing = await readFile5(configPath, "utf-8");
3297
3328
  const fmMatch = existing.match(/^(---\n)([\s\S]*?)\n(---)/);
@@ -3305,7 +3336,7 @@ ${cleanedFm}
3305
3336
  await writeFileForce(configPath, newContent);
3306
3337
  }
3307
3338
  async function writeStatusConfig(statuses) {
3308
- const configPath = resolve6(syntaurRoot(), "config.md");
3339
+ const configPath = resolve7(syntaurRoot(), "config.md");
3309
3340
  const statusBlock = serializeStatusConfig(statuses);
3310
3341
  if (!await fileExists(configPath)) {
3311
3342
  const content = `---
@@ -3359,7 +3390,7 @@ ${statusBlock}
3359
3390
  await writeFileForce(configPath, newContent);
3360
3391
  }
3361
3392
  async function deleteStatusConfig() {
3362
- const configPath = resolve6(syntaurRoot(), "config.md");
3393
+ const configPath = resolve7(syntaurRoot(), "config.md");
3363
3394
  if (!await fileExists(configPath)) return;
3364
3395
  const existing = await readFile5(configPath, "utf-8");
3365
3396
  const fmMatch = existing.match(/^(---\n)([\s\S]*?)\n(---)/);
@@ -3433,7 +3464,7 @@ function serializeSearchConfig(search) {
3433
3464
  return lines.join("\n");
3434
3465
  }
3435
3466
  async function writeSearchConfig(search) {
3436
- const configPath = resolve6(syntaurRoot(), "config.md");
3467
+ const configPath = resolve7(syntaurRoot(), "config.md");
3437
3468
  const searchBlock = serializeSearchConfig(search);
3438
3469
  if (!await fileExists(configPath)) {
3439
3470
  const content = `---
@@ -3466,7 +3497,7 @@ ${searchBlock}
3466
3497
  await writeFileForce(configPath, newContent);
3467
3498
  }
3468
3499
  async function deleteSearchConfig() {
3469
- const configPath = resolve6(syntaurRoot(), "config.md");
3500
+ const configPath = resolve7(syntaurRoot(), "config.md");
3470
3501
  if (!await fileExists(configPath)) return;
3471
3502
  const existing = await readFile5(configPath, "utf-8");
3472
3503
  const fmMatch = existing.match(/^(---\n)([\s\S]*?)\n(---)/);
@@ -3483,7 +3514,7 @@ function getSearchConfig(config) {
3483
3514
  return config.searchConfig ?? DEFAULT_SEARCH_CONFIG;
3484
3515
  }
3485
3516
  async function updateIntegrationConfig(integrations) {
3486
- const configPath = resolve6(syntaurRoot(), "config.md");
3517
+ const configPath = resolve7(syntaurRoot(), "config.md");
3487
3518
  const nextIntegrations = {
3488
3519
  ...(await readConfig()).integrations,
3489
3520
  ...integrations
@@ -3513,7 +3544,7 @@ ${normalizedFm}
3513
3544
  await writeFileForce(configPath, newContent);
3514
3545
  }
3515
3546
  async function updateOnboardingConfig(onboarding) {
3516
- const configPath = resolve6(syntaurRoot(), "config.md");
3547
+ const configPath = resolve7(syntaurRoot(), "config.md");
3517
3548
  const nextOnboarding = {
3518
3549
  ...(await readConfig()).onboarding,
3519
3550
  ...onboarding
@@ -3543,7 +3574,7 @@ ${normalizedFm}
3543
3574
  await writeFileForce(configPath, newContent);
3544
3575
  }
3545
3576
  async function updateBackupConfig(backup) {
3546
- const configPath = resolve6(syntaurRoot(), "config.md");
3577
+ const configPath = resolve7(syntaurRoot(), "config.md");
3547
3578
  const current = (await readConfig()).backup;
3548
3579
  const nextBackup = {
3549
3580
  repo: current?.repo ?? null,
@@ -3577,7 +3608,7 @@ ${normalizedFm}
3577
3608
  await writeFileForce(configPath, newContent);
3578
3609
  }
3579
3610
  async function readConfig() {
3580
- const configPath = resolve6(syntaurRoot(), "config.md");
3611
+ const configPath = resolve7(syntaurRoot(), "config.md");
3581
3612
  if (!await fileExists(configPath)) {
3582
3613
  return cloneDefaultConfig();
3583
3614
  }
@@ -3808,13 +3839,13 @@ var init_config2 = __esm({
3808
3839
  });
3809
3840
 
3810
3841
  // src/utils/assignment-resolver.ts
3811
- import { resolve as resolve7 } from "path";
3842
+ import { resolve as resolve8 } from "path";
3812
3843
  import { readdir as readdir3, readFile as readFile6 } from "fs/promises";
3813
3844
  async function resolveAssignmentById(projectsDir, assignmentsDir, id) {
3814
3845
  let standaloneMatch = null;
3815
3846
  let projectMatch = null;
3816
- const standaloneDir = resolve7(assignmentsDir, id);
3817
- const standalonePath = resolve7(standaloneDir, "assignment.md");
3847
+ const standaloneDir = resolve8(assignmentsDir, id);
3848
+ const standalonePath = resolve8(standaloneDir, "assignment.md");
3818
3849
  if (await fileExists(standalonePath)) {
3819
3850
  let workspaceGroup = null;
3820
3851
  try {
@@ -3838,12 +3869,12 @@ async function resolveAssignmentById(projectsDir, assignmentsDir, id) {
3838
3869
  for (const p of projects) {
3839
3870
  if (!p.isDirectory()) continue;
3840
3871
  if (p.name.startsWith(".") || p.name.startsWith("_")) continue;
3841
- const assignmentsPath = resolve7(projectsDir, p.name, "assignments");
3872
+ const assignmentsPath = resolve8(projectsDir, p.name, "assignments");
3842
3873
  if (!await fileExists(assignmentsPath)) continue;
3843
3874
  const entries = await readdir3(assignmentsPath, { withFileTypes: true });
3844
3875
  for (const a of entries) {
3845
3876
  if (!a.isDirectory()) continue;
3846
- const aPath = resolve7(assignmentsPath, a.name, "assignment.md");
3877
+ const aPath = resolve8(assignmentsPath, a.name, "assignment.md");
3847
3878
  if (!await fileExists(aPath)) continue;
3848
3879
  try {
3849
3880
  const content = await readFile6(aPath, "utf-8");
@@ -3851,7 +3882,7 @@ async function resolveAssignmentById(projectsDir, assignmentsDir, id) {
3851
3882
  const fileId = getField(fm, "id");
3852
3883
  if (fileId === id) {
3853
3884
  projectMatch = {
3854
- assignmentDir: resolve7(assignmentsPath, a.name),
3885
+ assignmentDir: resolve8(assignmentsPath, a.name),
3855
3886
  projectSlug: p.name,
3856
3887
  assignmentSlug: a.name,
3857
3888
  id,
@@ -3982,7 +4013,7 @@ var init_derive = __esm({
3982
4013
  });
3983
4014
 
3984
4015
  // src/utils/playbooks.ts
3985
- import { resolve as resolve8 } from "path";
4016
+ import { resolve as resolve9 } from "path";
3986
4017
  import { readdir as readdir4, readFile as readFile7, unlink } from "fs/promises";
3987
4018
  function isVisiblePlaybookFile(name, isFile) {
3988
4019
  return isFile && name.endsWith(".md") && !name.startsWith("_") && name !== "manifest.md";
@@ -3993,7 +4024,7 @@ async function listPlaybookSlugs(playbooksDir2) {
3993
4024
  const entries = await readdir4(playbooksDir2, { withFileTypes: true });
3994
4025
  for (const entry of entries) {
3995
4026
  if (!isVisiblePlaybookFile(entry.name, entry.isFile())) continue;
3996
- const filePath = resolve8(playbooksDir2, entry.name);
4027
+ const filePath = resolve9(playbooksDir2, entry.name);
3997
4028
  const raw = await readFile7(filePath, "utf-8");
3998
4029
  const parsed = parsePlaybook(raw);
3999
4030
  slugs.add(parsed.slug || entry.name.replace(/\.md$/, ""));
@@ -4106,7 +4137,7 @@ __export(facts_exports, {
4106
4137
  });
4107
4138
  import { createHash } from "crypto";
4108
4139
  import { readdir as readdir5, readFile as readFile9 } from "fs/promises";
4109
- import { resolve as resolve9 } from "path";
4140
+ import { resolve as resolve10 } from "path";
4110
4141
  function sectionBody(body, heading) {
4111
4142
  const re = new RegExp(`^##\\s+${heading}\\s*$`, "m");
4112
4143
  const m = body.match(re);
@@ -4161,14 +4192,14 @@ async function isPlanApproved(assignmentDir, frontmatter) {
4161
4192
  const latest = await latestPlanFile(assignmentDir);
4162
4193
  if (!latest || latest !== approval.file) return false;
4163
4194
  try {
4164
- const content = await readFile9(resolve9(assignmentDir, latest), "utf-8");
4195
+ const content = await readFile9(resolve10(assignmentDir, latest), "utf-8");
4165
4196
  return planDigest(content) === approval.digest;
4166
4197
  } catch {
4167
4198
  return false;
4168
4199
  }
4169
4200
  }
4170
4201
  async function countUnresolvedQuestions(assignmentDir) {
4171
- const commentsPath = resolve9(assignmentDir, "comments.md");
4202
+ const commentsPath = resolve10(assignmentDir, "comments.md");
4172
4203
  if (!await fileExists(commentsPath)) return 0;
4173
4204
  try {
4174
4205
  const content = await readFile9(commentsPath, "utf-8");
@@ -4186,7 +4217,7 @@ async function countUnresolvedQuestions(assignmentDir) {
4186
4217
  async function areDependenciesSatisfied(projectDir, dependsOn, terminalStatuses) {
4187
4218
  if (dependsOn.length === 0 || projectDir === null) return true;
4188
4219
  for (const depSlug of dependsOn) {
4189
- const depPath = resolve9(projectDir, "assignments", depSlug, "assignment.md");
4220
+ const depPath = resolve10(projectDir, "assignments", depSlug, "assignment.md");
4190
4221
  if (!await fileExists(depPath)) return false;
4191
4222
  try {
4192
4223
  const content = await readFile9(depPath, "utf-8");
@@ -4237,7 +4268,7 @@ async function computeFactsDetailed(input) {
4237
4268
  const needsPlanDigest = frontmatter.planApproval !== null || declarations.some((d) => d.type === "attestation" && d.binds === "plan");
4238
4269
  const planFile = await latestPlanFile(assignmentDir);
4239
4270
  const [planFileContent, unresolvedQuestions, depsSatisfied] = await Promise.all([
4240
- needsPlanDigest && planFile ? readFile9(resolve9(assignmentDir, planFile), "utf-8").catch(() => null) : Promise.resolve(null),
4271
+ needsPlanDigest && planFile ? readFile9(resolve10(assignmentDir, planFile), "utf-8").catch(() => null) : Promise.resolve(null),
4241
4272
  countUnresolvedQuestions(assignmentDir),
4242
4273
  areDependenciesSatisfied(projectDir, frontmatter.dependsOn, terminalStatuses)
4243
4274
  ]);
@@ -4326,7 +4357,7 @@ var init_route = __esm({
4326
4357
  });
4327
4358
 
4328
4359
  // src/utils/assignment-walk.ts
4329
- import { resolve as resolve10 } from "path";
4360
+ import { resolve as resolve11 } from "path";
4330
4361
  import { readdir as readdir6 } from "fs/promises";
4331
4362
  var init_assignment_walk = __esm({
4332
4363
  "src/utils/assignment-walk.ts"() {
@@ -4337,7 +4368,7 @@ var init_assignment_walk = __esm({
4337
4368
 
4338
4369
  // src/search/indexer.ts
4339
4370
  import { readdir as readdir7, readFile as readFile10, stat } from "fs/promises";
4340
- import { resolve as resolve11, join as join2 } from "path";
4371
+ import { resolve as resolve12, join as join2 } from "path";
4341
4372
  var init_indexer = __esm({
4342
4373
  "src/search/indexer.ts"() {
4343
4374
  "use strict";
@@ -4578,13 +4609,13 @@ __export(session_db_exports, {
4578
4609
  migrateFromMarkdown: () => migrateFromMarkdown,
4579
4610
  resetSessionDb: () => resetSessionDb
4580
4611
  });
4581
- import Database from "better-sqlite3";
4582
- import { resolve as resolve12 } from "path";
4612
+ import Database2 from "better-sqlite3";
4613
+ import { resolve as resolve13 } from "path";
4583
4614
  import { readdir as readdir8 } from "fs/promises";
4584
4615
  function initSessionDb(dbPath) {
4585
4616
  if (db) return db;
4586
- const finalPath = dbPath ?? resolve12(syntaurRoot(), "syntaur.db");
4587
- db = new Database(finalPath);
4617
+ const finalPath = dbPath ?? resolve13(syntaurRoot(), "syntaur.db");
4618
+ db = new Database2(finalPath);
4588
4619
  db.pragma("journal_mode = WAL");
4589
4620
  db.exec(SCHEMA_SQL);
4590
4621
  db.prepare("INSERT OR IGNORE INTO meta (key, value) VALUES (?, ?)").run(
@@ -4751,8 +4782,8 @@ async function migrateFromMarkdown(projectsDir) {
4751
4782
  const allSessions = [];
4752
4783
  for (const entry of entries) {
4753
4784
  if (!entry.isDirectory()) continue;
4754
- const projectDir = resolve12(projectsDir, entry.name);
4755
- const indexPath = resolve12(projectDir, "_index-sessions.md");
4785
+ const projectDir = resolve13(projectsDir, entry.name);
4786
+ const indexPath = resolve13(projectDir, "_index-sessions.md");
4756
4787
  if (!await fileExists(indexPath)) continue;
4757
4788
  const sessions = await parseMarkdownSessionsIndex(indexPath, entry.name);
4758
4789
  allSessions.push(...sessions);
@@ -4857,7 +4888,7 @@ __export(agent_sessions_exports, {
4857
4888
  updateSessionStatus: () => updateSessionStatus
4858
4889
  });
4859
4890
  import { readFile as readFile11 } from "fs/promises";
4860
- import { resolve as resolve13 } from "path";
4891
+ import { resolve as resolve14 } from "path";
4861
4892
  function rowToSession(row) {
4862
4893
  return {
4863
4894
  sessionId: row.session_id,
@@ -4964,7 +4995,7 @@ async function readAssignmentStatusFromPath(assignmentMdPath) {
4964
4995
  }
4965
4996
  async function readAssignmentStatus(projectDir, assignmentSlug) {
4966
4997
  return readAssignmentStatusFromPath(
4967
- resolve13(projectDir, "assignments", assignmentSlug, "assignment.md")
4998
+ resolve14(projectDir, "assignments", assignmentSlug, "assignment.md")
4968
4999
  );
4969
5000
  }
4970
5001
  async function reconcileActiveSessions(projectsDir, assignmentsDir) {
@@ -4982,13 +5013,13 @@ async function reconcileActiveSessions(projectsDir, assignmentsDir) {
4982
5013
  seen.add(key);
4983
5014
  if (session.project_slug) {
4984
5015
  const status = await readAssignmentStatus(
4985
- resolve13(projectsDir, session.project_slug),
5016
+ resolve14(projectsDir, session.project_slug),
4986
5017
  aslug
4987
5018
  );
4988
5019
  if (status) assignmentStatuses.set(key, status);
4989
5020
  } else if (assignmentsDir) {
4990
5021
  const status = await readAssignmentStatusFromPath(
4991
- resolve13(assignmentsDir, aslug, "assignment.md")
5022
+ resolve14(assignmentsDir, aslug, "assignment.md")
4992
5023
  );
4993
5024
  if (status) assignmentStatuses.set(key, status);
4994
5025
  }
@@ -5033,7 +5064,7 @@ var init_overviewCopy = __esm({
5033
5064
 
5034
5065
  // src/dashboard/api.ts
5035
5066
  import { readdir as readdir9, readFile as readFile12, writeFile as writeFile3 } from "fs/promises";
5036
- import { resolve as resolve14, dirname as dirname2, basename } from "path";
5067
+ import { resolve as resolve15, dirname as dirname2, basename } from "path";
5037
5068
  function activeAssignments(items) {
5038
5069
  return items.filter((item) => item.archived !== true);
5039
5070
  }
@@ -5057,8 +5088,8 @@ async function computeStandaloneRecords(assignmentsDir) {
5057
5088
  const records = [];
5058
5089
  for (const entry of entries) {
5059
5090
  if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name.startsWith("_")) continue;
5060
- const assignmentDir = resolve14(assignmentsDir, entry.name);
5061
- const assignmentMdPath = resolve14(assignmentDir, "assignment.md");
5091
+ const assignmentDir = resolve15(assignmentsDir, entry.name);
5092
+ const assignmentMdPath = resolve15(assignmentDir, "assignment.md");
5062
5093
  if (!await fileExists(assignmentMdPath)) continue;
5063
5094
  try {
5064
5095
  const content = await readFile12(assignmentMdPath, "utf-8");
@@ -5162,15 +5193,15 @@ async function getStandaloneAvailableTransitions(assignment) {
5162
5193
  return actions;
5163
5194
  }
5164
5195
  async function getAssignmentDetail(projectsDir, projectSlug, assignmentSlug) {
5165
- const assignmentDir = resolve14(projectsDir, projectSlug, "assignments", assignmentSlug);
5166
- const assignmentMdPath = resolve14(assignmentDir, "assignment.md");
5196
+ const assignmentDir = resolve15(projectsDir, projectSlug, "assignments", assignmentSlug);
5197
+ const assignmentMdPath = resolve15(assignmentDir, "assignment.md");
5167
5198
  if (!await fileExists(assignmentMdPath)) {
5168
5199
  return null;
5169
5200
  }
5170
5201
  const assignmentContent = await readFile12(assignmentMdPath, "utf-8");
5171
5202
  const assignment = parseAssignmentFull(assignmentContent);
5172
5203
  let projectWorkspace = null;
5173
- const projectMdPath = resolve14(projectsDir, projectSlug, "project.md");
5204
+ const projectMdPath = resolve15(projectsDir, projectSlug, "project.md");
5174
5205
  if (await fileExists(projectMdPath)) {
5175
5206
  const projectContent = await readFile12(projectMdPath, "utf-8");
5176
5207
  projectWorkspace = parseProject(projectContent).workspace;
@@ -5178,7 +5209,7 @@ async function getAssignmentDetail(projectsDir, projectSlug, assignmentSlug) {
5178
5209
  let plan = null;
5179
5210
  const planFile = await latestPlanFile(assignmentDir);
5180
5211
  if (planFile) {
5181
- const planPath = resolve14(assignmentDir, planFile);
5212
+ const planPath = resolve15(assignmentDir, planFile);
5182
5213
  if (await fileExists(planPath)) {
5183
5214
  const planContent = await readFile12(planPath, "utf-8");
5184
5215
  const parsed = parsePlan(planContent);
@@ -5190,7 +5221,7 @@ async function getAssignmentDetail(projectsDir, projectSlug, assignmentSlug) {
5190
5221
  }
5191
5222
  }
5192
5223
  let scratchpad = null;
5193
- const scratchpadPath = resolve14(assignmentDir, "scratchpad.md");
5224
+ const scratchpadPath = resolve15(assignmentDir, "scratchpad.md");
5194
5225
  if (await fileExists(scratchpadPath)) {
5195
5226
  const scratchpadContent = await readFile12(scratchpadPath, "utf-8");
5196
5227
  const parsed = parseScratchpad(scratchpadContent);
@@ -5200,7 +5231,7 @@ async function getAssignmentDetail(projectsDir, projectSlug, assignmentSlug) {
5200
5231
  };
5201
5232
  }
5202
5233
  let handoff = null;
5203
- const handoffPath = resolve14(assignmentDir, "handoff.md");
5234
+ const handoffPath = resolve15(assignmentDir, "handoff.md");
5204
5235
  if (await fileExists(handoffPath)) {
5205
5236
  const handoffContent = await readFile12(handoffPath, "utf-8");
5206
5237
  const parsed = parseHandoff(handoffContent);
@@ -5211,7 +5242,7 @@ async function getAssignmentDetail(projectsDir, projectSlug, assignmentSlug) {
5211
5242
  };
5212
5243
  }
5213
5244
  let decisionRecord = null;
5214
- const decisionRecordPath = resolve14(assignmentDir, "decision-record.md");
5245
+ const decisionRecordPath = resolve15(assignmentDir, "decision-record.md");
5215
5246
  if (await fileExists(decisionRecordPath)) {
5216
5247
  const decisionRecordContent = await readFile12(decisionRecordPath, "utf-8");
5217
5248
  const parsed = parseDecisionRecord(decisionRecordContent);
@@ -5222,7 +5253,7 @@ async function getAssignmentDetail(projectsDir, projectSlug, assignmentSlug) {
5222
5253
  };
5223
5254
  }
5224
5255
  let progress = null;
5225
- const progressPath = resolve14(assignmentDir, "progress.md");
5256
+ const progressPath = resolve15(assignmentDir, "progress.md");
5226
5257
  if (await fileExists(progressPath)) {
5227
5258
  const progressContent = await readFile12(progressPath, "utf-8");
5228
5259
  const parsed = parseProgress(progressContent);
@@ -5233,7 +5264,7 @@ async function getAssignmentDetail(projectsDir, projectSlug, assignmentSlug) {
5233
5264
  };
5234
5265
  }
5235
5266
  let comments = null;
5236
- const commentsPath = resolve14(assignmentDir, "comments.md");
5267
+ const commentsPath = resolve15(assignmentDir, "comments.md");
5237
5268
  if (await fileExists(commentsPath)) {
5238
5269
  const commentsContent = await readFile12(commentsPath, "utf-8");
5239
5270
  const parsed = parseComments(commentsContent);
@@ -5267,7 +5298,7 @@ async function getAssignmentDetail(projectsDir, projectSlug, assignmentSlug) {
5267
5298
  archivedReason: assignment.archivedReason,
5268
5299
  ...deriveStatusVirtuals(assignment, terminalStatuses),
5269
5300
  override: assignment.override,
5270
- derived: await buildDerivedDetail(assignment, assignmentDir, resolve14(projectsDir, projectSlug)),
5301
+ derived: await buildDerivedDetail(assignment, assignmentDir, resolve15(projectsDir, projectSlug)),
5271
5302
  created: assignment.created,
5272
5303
  updated: assignment.updated,
5273
5304
  body: assignment.body,
@@ -5358,7 +5389,7 @@ async function computeReferencedBy(target, projectsDir, assignmentsDir) {
5358
5389
  slug: a.slug,
5359
5390
  title: a.title,
5360
5391
  projectSlug: rec.summary.slug,
5361
- assignmentDir: resolve14(rec.projectPath, "assignments", a.slug)
5392
+ assignmentDir: resolve15(rec.projectPath, "assignments", a.slug)
5362
5393
  });
5363
5394
  }
5364
5395
  }
@@ -5391,14 +5422,14 @@ async function computeReferencedBy(target, projectsDir, assignmentsDir) {
5391
5422
  }
5392
5423
  async function countMentionsInAssignment(sourceDir, target) {
5393
5424
  const bodies = [];
5394
- const assignmentMd = resolve14(sourceDir, "assignment.md");
5425
+ const assignmentMd = resolve15(sourceDir, "assignment.md");
5395
5426
  if (await fileExists(assignmentMd)) {
5396
5427
  const content = await readFile12(assignmentMd, "utf-8");
5397
5428
  const todosMatch = content.match(/^## Todos\s*$([\s\S]*?)(?=^## |$(?![\r\n]))/m);
5398
5429
  if (todosMatch) bodies.push(todosMatch[1]);
5399
5430
  }
5400
5431
  for (const filename of ["progress.md", "comments.md", "handoff.md"]) {
5401
- const path = resolve14(sourceDir, filename);
5432
+ const path = resolve15(sourceDir, filename);
5402
5433
  if (await fileExists(path)) {
5403
5434
  try {
5404
5435
  bodies.push(await readFile12(path, "utf-8"));
@@ -5459,45 +5490,45 @@ async function getAssignmentDetailById(projectsDir, assignmentsDir, id) {
5459
5490
  }
5460
5491
  async function buildStandaloneAssignmentDetail(resolved) {
5461
5492
  const assignmentDir = resolved.assignmentDir;
5462
- const assignmentMdPath = resolve14(assignmentDir, "assignment.md");
5493
+ const assignmentMdPath = resolve15(assignmentDir, "assignment.md");
5463
5494
  if (!await fileExists(assignmentMdPath)) return null;
5464
5495
  const assignmentContent = await readFile12(assignmentMdPath, "utf-8");
5465
5496
  const assignment = parseAssignmentFull(assignmentContent);
5466
5497
  let plan = null;
5467
5498
  const planFile = await latestPlanFile(assignmentDir);
5468
5499
  if (planFile) {
5469
- const planPath = resolve14(assignmentDir, planFile);
5500
+ const planPath = resolve15(assignmentDir, planFile);
5470
5501
  if (await fileExists(planPath)) {
5471
5502
  const parsed = parsePlan(await readFile12(planPath, "utf-8"));
5472
5503
  plan = { status: parsed.status, updated: parsed.updated, body: parsed.body };
5473
5504
  }
5474
5505
  }
5475
5506
  let scratchpad = null;
5476
- const scratchpadPath = resolve14(assignmentDir, "scratchpad.md");
5507
+ const scratchpadPath = resolve15(assignmentDir, "scratchpad.md");
5477
5508
  if (await fileExists(scratchpadPath)) {
5478
5509
  const parsed = parseScratchpad(await readFile12(scratchpadPath, "utf-8"));
5479
5510
  scratchpad = { updated: parsed.updated, body: parsed.body };
5480
5511
  }
5481
5512
  let handoff = null;
5482
- const handoffPath = resolve14(assignmentDir, "handoff.md");
5513
+ const handoffPath = resolve15(assignmentDir, "handoff.md");
5483
5514
  if (await fileExists(handoffPath)) {
5484
5515
  const parsed = parseHandoff(await readFile12(handoffPath, "utf-8"));
5485
5516
  handoff = { updated: parsed.updated, handoffCount: parsed.handoffCount, body: parsed.body };
5486
5517
  }
5487
5518
  let decisionRecord = null;
5488
- const decisionRecordPath = resolve14(assignmentDir, "decision-record.md");
5519
+ const decisionRecordPath = resolve15(assignmentDir, "decision-record.md");
5489
5520
  if (await fileExists(decisionRecordPath)) {
5490
5521
  const parsed = parseDecisionRecord(await readFile12(decisionRecordPath, "utf-8"));
5491
5522
  decisionRecord = { updated: parsed.updated, decisionCount: parsed.decisionCount, body: parsed.body };
5492
5523
  }
5493
5524
  let progress = null;
5494
- const progressPath = resolve14(assignmentDir, "progress.md");
5525
+ const progressPath = resolve15(assignmentDir, "progress.md");
5495
5526
  if (await fileExists(progressPath)) {
5496
5527
  const parsed = parseProgress(await readFile12(progressPath, "utf-8"));
5497
5528
  progress = { updated: parsed.updated, entryCount: parsed.entryCount, entries: parsed.entries };
5498
5529
  }
5499
5530
  let comments = null;
5500
- const commentsPath = resolve14(assignmentDir, "comments.md");
5531
+ const commentsPath = resolve15(assignmentDir, "comments.md");
5501
5532
  if (await fileExists(commentsPath)) {
5502
5533
  const parsed = parseComments(await readFile12(commentsPath, "utf-8"));
5503
5534
  comments = { updated: parsed.updated, entryCount: parsed.entryCount, entries: parsed.entries };
@@ -5563,8 +5594,8 @@ async function computeProjectRecords(projectsDir, traces) {
5563
5594
  const projectDirs = entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
5564
5595
  const maybeRecords = await Promise.all(
5565
5596
  projectDirs.map(async (entry) => {
5566
- const projectPath = resolve14(projectsDir, entry.name);
5567
- const projectMdPath = resolve14(projectPath, "project.md");
5597
+ const projectPath = resolve15(projectsDir, entry.name);
5598
+ const projectMdPath = resolve15(projectPath, "project.md");
5568
5599
  if (!await fileExists(projectMdPath)) {
5569
5600
  return null;
5570
5601
  }
@@ -5611,7 +5642,7 @@ async function computeProjectRecords(projectsDir, traces) {
5611
5642
  return records;
5612
5643
  }
5613
5644
  async function listAssignmentRecords(projectPath, traces) {
5614
- const assignmentsDir = resolve14(projectPath, "assignments");
5645
+ const assignmentsDir = resolve15(projectPath, "assignments");
5615
5646
  if (!await fileExists(assignmentsDir)) {
5616
5647
  return [];
5617
5648
  }
@@ -5619,7 +5650,7 @@ async function listAssignmentRecords(projectPath, traces) {
5619
5650
  const dirEntries = entries.filter((entry) => entry.isDirectory());
5620
5651
  const maybeRecords = await Promise.all(
5621
5652
  dirEntries.map(async (entry) => {
5622
- const assignmentMd = resolve14(assignmentsDir, entry.name, "assignment.md");
5653
+ const assignmentMd = resolve15(assignmentsDir, entry.name, "assignment.md");
5623
5654
  if (!await fileExists(assignmentMd)) {
5624
5655
  return null;
5625
5656
  }
@@ -5635,7 +5666,7 @@ async function listAssignmentRecords(projectPath, traces) {
5635
5666
  return records;
5636
5667
  }
5637
5668
  async function loadDependencyGraph(projectPath, assignments) {
5638
- const statusPath = resolve14(projectPath, "_status.md");
5669
+ const statusPath = resolve15(projectPath, "_status.md");
5639
5670
  if (await fileExists(statusPath)) {
5640
5671
  const statusContent = await readFile12(statusPath, "utf-8");
5641
5672
  const parsed = parseStatus(statusContent);
@@ -5810,7 +5841,7 @@ async function getAvailableTransitions(projectsDir, projectSlug, assignmentSlug,
5810
5841
  const config = await getStatusConfig();
5811
5842
  const transitionDefs = getTransitionDefinitions(config);
5812
5843
  const actions = [];
5813
- const projectPath = resolve14(projectsDir, projectSlug);
5844
+ const projectPath = resolve15(projectsDir, projectSlug);
5814
5845
  const traces = options?.traces;
5815
5846
  for (const definition of transitionDefs) {
5816
5847
  const target = getTargetStatus(assignment.status, definition.command, config.transitionTable);
@@ -5858,7 +5889,7 @@ async function getUnmetDependencies(projectPath, dependsOn, terminalStatuses, de
5858
5889
  continue;
5859
5890
  }
5860
5891
  }
5861
- const dependencyPath = resolve14(projectPath, "assignments", dependency, "assignment.md");
5892
+ const dependencyPath = resolve15(projectPath, "assignments", dependency, "assignment.md");
5862
5893
  if (!await fileExists(dependencyPath)) {
5863
5894
  unmet.push(`${dependency} (missing)`);
5864
5895
  continue;
@@ -5879,7 +5910,7 @@ function parseTimestamp(timestamp) {
5879
5910
  return Number.isFinite(parsed) ? parsed : 0;
5880
5911
  }
5881
5912
  async function countOpenQuestions(projectPath, assignmentSlug) {
5882
- const commentsPath = resolve14(
5913
+ const commentsPath = resolve15(
5883
5914
  projectPath,
5884
5915
  "assignments",
5885
5916
  assignmentSlug,
@@ -6244,7 +6275,7 @@ init_agents_schema();
6244
6275
  init_cwd();
6245
6276
  import { spawn as spawn2 } from "child_process";
6246
6277
  import { mkdir as mkdir2, writeFile as writeFile4 } from "fs/promises";
6247
- import { isAbsolute as isAbsolute3, resolve as resolve15 } from "path";
6278
+ import { isAbsolute as isAbsolute3, resolve as resolve16 } from "path";
6248
6279
  init_paths();
6249
6280
  init_playbooks();
6250
6281
  init_cwd();
@@ -6471,7 +6502,7 @@ async function resolveSessionPlan(input, terminal) {
6471
6502
  // src/launch/execute.ts
6472
6503
  import { spawn as spawn3 } from "child_process";
6473
6504
  import { homedir as homedir5 } from "os";
6474
- import { basename as basename2, join as join6, resolve as resolve16 } from "path";
6505
+ import { basename as basename2, join as join6, resolve as resolve17 } from "path";
6475
6506
 
6476
6507
  // src/utils/terminal-probe.ts
6477
6508
  import { spawnSync as spawnSync2 } from "child_process";
@@ -6633,7 +6664,7 @@ async function executeLaunchPlan(plan, spawnFn = realSpawn) {
6633
6664
  `Spawn failed: ${msg}. Verify the terminal is installed and on PATH.`
6634
6665
  );
6635
6666
  }
6636
- await new Promise((resolve18, reject) => {
6667
+ await new Promise((resolve19, reject) => {
6637
6668
  let settled = false;
6638
6669
  let stderr = "";
6639
6670
  const finishOk = () => {
@@ -6643,7 +6674,7 @@ async function executeLaunchPlan(plan, spawnFn = realSpawn) {
6643
6674
  child.unref();
6644
6675
  } catch {
6645
6676
  }
6646
- resolve18();
6677
+ resolve19();
6647
6678
  };
6648
6679
  const finishErr = (remediation) => {
6649
6680
  if (settled) return;
@@ -6704,7 +6735,7 @@ async function registerLaunchAtBirth(plan, child) {
6704
6735
  markerDir
6705
6736
  );
6706
6737
  if (!sessionId) return;
6707
- if (autoTrack === "workspaces-only" && !await fileExists(resolve16(plan.cwd, ".syntaur", "context.json"))) {
6738
+ if (autoTrack === "workspaces-only" && !await fileExists(resolve17(plan.cwd, ".syntaur", "context.json"))) {
6708
6739
  return;
6709
6740
  }
6710
6741
  const { initSessionDb: initSessionDb2 } = await Promise.resolve().then(() => (init_session_db(), session_db_exports));
@@ -6880,7 +6911,7 @@ function appleScriptString(value) {
6880
6911
  init_paths();
6881
6912
  init_fs();
6882
6913
  import { fileURLToPath } from "url";
6883
- import { dirname as dirname4, resolve as resolve17, join as join7 } from "path";
6914
+ import { dirname as dirname4, resolve as resolve18, join as join7 } from "path";
6884
6915
  import { realpathSync, readFileSync as readFileSync2, mkdirSync as mkdirSync2 } from "fs";
6885
6916
  var NPX_PATTERNS = [
6886
6917
  { kind: "npm", re: /\/_npx\/([^/]+)\/node_modules(?:\/|$)/ },
@@ -6959,7 +6990,7 @@ function extractNpxHash(scriptUrl, opts = {}) {
6959
6990
  return null;
6960
6991
  }
6961
6992
  function nudgeStampDir() {
6962
- return resolve17(syntaurRoot(), "npx-handler-nudge");
6993
+ return resolve18(syntaurRoot(), "npx-handler-nudge");
6963
6994
  }
6964
6995
  function sanitizeHash(hash) {
6965
6996
  return hash.replace(/[^A-Za-z0-9_-]/g, "_") || "_";