syntaur 0.62.0 → 0.65.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 (67) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +20 -0
  3. package/dashboard/dist/assets/{_basePickBy-C0DmX-Lf.js → _basePickBy-CrrGp7iQ.js} +1 -1
  4. package/dashboard/dist/assets/{_baseUniq-B656N5Fp.js → _baseUniq-CR-L9Z4l.js} +1 -1
  5. package/dashboard/dist/assets/{arc-DWrED_i3.js → arc-Bplhanol.js} +1 -1
  6. package/dashboard/dist/assets/{architectureDiagram-2XIMDMQ5-B7gQ_B6F.js → architectureDiagram-2XIMDMQ5-hcuAyqPz.js} +1 -1
  7. package/dashboard/dist/assets/{blockDiagram-WCTKOSBZ-CrqgprVY.js → blockDiagram-WCTKOSBZ-BkGOQX1p.js} +1 -1
  8. package/dashboard/dist/assets/{c4Diagram-IC4MRINW-B6JBjUpY.js → c4Diagram-IC4MRINW-CyhVhe9Z.js} +1 -1
  9. package/dashboard/dist/assets/channel-DKDXpYJX.js +1 -0
  10. package/dashboard/dist/assets/{chunk-4BX2VUAB-Co4Kcyxc.js → chunk-4BX2VUAB-DWT4Kb7h.js} +1 -1
  11. package/dashboard/dist/assets/{chunk-55IACEB6-D9r_hMAn.js → chunk-55IACEB6-DabzdGiV.js} +1 -1
  12. package/dashboard/dist/assets/{chunk-FMBD7UC4-Dxxe9AQy.js → chunk-FMBD7UC4-9u9EbTn2.js} +1 -1
  13. package/dashboard/dist/assets/{chunk-JSJVCQXG-CXn2IalW.js → chunk-JSJVCQXG-qNUjUgoq.js} +1 -1
  14. package/dashboard/dist/assets/{chunk-KX2RTZJC-C0lpRUjK.js → chunk-KX2RTZJC-Iw8btz_i.js} +1 -1
  15. package/dashboard/dist/assets/{chunk-NQ4KR5QH-CE2rv8cX.js → chunk-NQ4KR5QH-DuWW63Ax.js} +1 -1
  16. package/dashboard/dist/assets/{chunk-QZHKN3VN-Drs_1Xrc.js → chunk-QZHKN3VN-CquL_I3V.js} +1 -1
  17. package/dashboard/dist/assets/{chunk-WL4C6EOR-IlTQx43D.js → chunk-WL4C6EOR-CmAQtVO_.js} +1 -1
  18. package/dashboard/dist/assets/classDiagram-VBA2DB6C-U7OD7LGq.js +1 -0
  19. package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-U7OD7LGq.js +1 -0
  20. package/dashboard/dist/assets/clone-CZUxWIoY.js +1 -0
  21. package/dashboard/dist/assets/{cose-bilkent-S5V4N54A-C4Xv3sEQ.js → cose-bilkent-S5V4N54A-D_vWs01G.js} +1 -1
  22. package/dashboard/dist/assets/{dagre-KLK3FWXG-BzfEk7Lk.js → dagre-KLK3FWXG-DRSd99h1.js} +1 -1
  23. package/dashboard/dist/assets/{diagram-E7M64L7V-CPwBFGGc.js → diagram-E7M64L7V-CYIlPZb0.js} +1 -1
  24. package/dashboard/dist/assets/{diagram-IFDJBPK2-DSbGA26W.js → diagram-IFDJBPK2-D1Mk78S1.js} +1 -1
  25. package/dashboard/dist/assets/{diagram-P4PSJMXO-XGhn9Qv-.js → diagram-P4PSJMXO-cK1mot2F.js} +1 -1
  26. package/dashboard/dist/assets/{erDiagram-INFDFZHY-XeTWZkc6.js → erDiagram-INFDFZHY-CKAce3P6.js} +1 -1
  27. package/dashboard/dist/assets/{flowDiagram-PKNHOUZH-7vHLCNpk.js → flowDiagram-PKNHOUZH-B8UyrAbG.js} +1 -1
  28. package/dashboard/dist/assets/{ganttDiagram-A5KZAMGK-C9ifnMpV.js → ganttDiagram-A5KZAMGK-DFlWro9k.js} +1 -1
  29. package/dashboard/dist/assets/{gitGraphDiagram-K3NZZRJ6-2o_Myer6.js → gitGraphDiagram-K3NZZRJ6-CfvsGSZk.js} +1 -1
  30. package/dashboard/dist/assets/{graph-D9VPbOXW.js → graph-DTnszQr1.js} +1 -1
  31. package/dashboard/dist/assets/index-BukhcQ51.js +659 -0
  32. package/dashboard/dist/assets/{index-BLRRdPLK.css → index-DlUgV5eO.css} +1 -1
  33. package/dashboard/dist/assets/{infoDiagram-LFFYTUFH-BlCEEtf8.js → infoDiagram-LFFYTUFH-B4CQ1F6_.js} +1 -1
  34. package/dashboard/dist/assets/{ishikawaDiagram-PHBUUO56-BGYOHhaE.js → ishikawaDiagram-PHBUUO56-BJf9J-fu.js} +1 -1
  35. package/dashboard/dist/assets/{journeyDiagram-4ABVD52K-Cn3nH440.js → journeyDiagram-4ABVD52K-CDt3Ieap.js} +1 -1
  36. package/dashboard/dist/assets/{kanban-definition-K7BYSVSG-Beagbum1.js → kanban-definition-K7BYSVSG-DvenMiPw.js} +1 -1
  37. package/dashboard/dist/assets/{layout-DXJOlege.js → layout-B_3cS6Wx.js} +1 -1
  38. package/dashboard/dist/assets/{linear-gb5BSwpC.js → linear-VVB-1jRr.js} +1 -1
  39. package/dashboard/dist/assets/{mermaid.core-leU3TCkv.js → mermaid.core-BR4E6mM3.js} +4 -4
  40. package/dashboard/dist/assets/{mindmap-definition-YRQLILUH-DFGnCvnf.js → mindmap-definition-YRQLILUH-BSMVANTC.js} +1 -1
  41. package/dashboard/dist/assets/{pieDiagram-SKSYHLDU-HmtQWxMR.js → pieDiagram-SKSYHLDU-Bc1KLLbU.js} +1 -1
  42. package/dashboard/dist/assets/{quadrantDiagram-337W2JSQ-BTDN-lUs.js → quadrantDiagram-337W2JSQ-DCxPDJLj.js} +1 -1
  43. package/dashboard/dist/assets/{requirementDiagram-Z7DCOOCP-Da0Yc9Cc.js → requirementDiagram-Z7DCOOCP-CIR7dfaq.js} +1 -1
  44. package/dashboard/dist/assets/{sankeyDiagram-WA2Y5GQK-DgfucBhp.js → sankeyDiagram-WA2Y5GQK-BSmLrby0.js} +1 -1
  45. package/dashboard/dist/assets/{sequenceDiagram-2WXFIKYE-CFIS7rpy.js → sequenceDiagram-2WXFIKYE-D8SKlaHf.js} +1 -1
  46. package/dashboard/dist/assets/{stateDiagram-RAJIS63D-CYPPhI5Y.js → stateDiagram-RAJIS63D-P-weHmzQ.js} +1 -1
  47. package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-DgvK3I0Y.js +1 -0
  48. package/dashboard/dist/assets/{timeline-definition-YZTLITO2-BidLs2_X.js → timeline-definition-YZTLITO2-AWMvjwea.js} +1 -1
  49. package/dashboard/dist/assets/{treemap-KZPCXAKY-cEHQHmiX.js → treemap-KZPCXAKY-ByTswXsP.js} +1 -1
  50. package/dashboard/dist/assets/{vennDiagram-LZ73GAT5-B78ndeUP.js → vennDiagram-LZ73GAT5-FhcL4LCg.js} +1 -1
  51. package/dashboard/dist/assets/{xychartDiagram-JWTSCODW-DhNlfMcT.js → xychartDiagram-JWTSCODW-Aql6py8q.js} +1 -1
  52. package/dashboard/dist/index.html +2 -2
  53. package/dist/dashboard/server.js +441 -100
  54. package/dist/dashboard/server.js.map +1 -1
  55. package/dist/index.js +1011 -561
  56. package/dist/index.js.map +1 -1
  57. package/package.json +1 -1
  58. package/platforms/claude-code/.claude-plugin/plugin.json +1 -1
  59. package/platforms/codex/.codex-plugin/plugin.json +1 -1
  60. package/platforms/hermes/plugins/syntaur/__pycache__/__init__.cpython-312.pyc +0 -0
  61. package/platforms/hermes/plugins/syntaur/__pycache__/boundary.cpython-312.pyc +0 -0
  62. package/dashboard/dist/assets/channel-CDkiQtSs.js +0 -1
  63. package/dashboard/dist/assets/classDiagram-VBA2DB6C-C8nQGnrI.js +0 -1
  64. package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-C8nQGnrI.js +0 -1
  65. package/dashboard/dist/assets/clone-BYliW2bC.js +0 -1
  66. package/dashboard/dist/assets/index-n4_qf3_i.js +0 -644
  67. package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-DC2NHdS4.js +0 -1
package/dist/index.js CHANGED
@@ -7599,7 +7599,7 @@ async function computeFactsDetailed(input4) {
7599
7599
  const ac = countRealAcceptanceCriteria(body);
7600
7600
  const needsPlanDigest = frontmatter.planApproval !== null || declarations.some((d) => d.type === "attestation" && d.binds === "plan");
7601
7601
  const planFile = await latestPlanFile(assignmentDir);
7602
- const [planFileContent, unresolvedQuestions, depsSatisfied] = await Promise.all([
7602
+ const [planFileContent, unresolvedQuestions2, depsSatisfied] = await Promise.all([
7603
7603
  needsPlanDigest && planFile ? readFile10(resolve13(assignmentDir, planFile), "utf-8").catch(() => null) : Promise.resolve(null),
7604
7604
  countUnresolvedQuestions(assignmentDir),
7605
7605
  areDependenciesSatisfied(projectDir, frontmatter.dependsOn, terminalStatuses3)
@@ -7617,7 +7617,7 @@ async function computeFactsDetailed(input4) {
7617
7617
  workspaceSet: frontmatter.workspace.repository !== null && frontmatter.workspace.branch !== null,
7618
7618
  implementationStarted: frontmatter.implementationStarted,
7619
7619
  depsSatisfied,
7620
- unresolvedQuestions,
7620
+ unresolvedQuestions: unresolvedQuestions2,
7621
7621
  blocked: frontmatter.blockedReason !== null,
7622
7622
  parked: frontmatter.parked,
7623
7623
  reviewRequested: frontmatter.reviewRequested,
@@ -8878,8 +8878,8 @@ async function migrateFromMarkdown(projectsDir2) {
8878
8878
  return allSessions.length;
8879
8879
  }
8880
8880
  async function parseMarkdownSessionsIndex(filePath, projectSlug) {
8881
- const { readFile: readFile80 } = await import("fs/promises");
8882
- const raw2 = await readFile80(filePath, "utf-8");
8881
+ const { readFile: readFile81 } = await import("fs/promises");
8882
+ const raw2 = await readFile81(filePath, "utf-8");
8883
8883
  const sessions = [];
8884
8884
  const lines = raw2.split("\n");
8885
8885
  let inTable = false;
@@ -9338,8 +9338,8 @@ function scanKey(serversDir2, projectsDir2, assignmentsDir2) {
9338
9338
  return `${serversDir2}\0${projectsDir2}\0${assignmentsDir2 ?? ""}`;
9339
9339
  }
9340
9340
  function delay(ms) {
9341
- return new Promise((resolve109) => {
9342
- const timer3 = setTimeout(resolve109, ms);
9341
+ return new Promise((resolve110) => {
9342
+ const timer3 = setTimeout(resolve110, ms);
9343
9343
  if (typeof timer3.unref === "function") {
9344
9344
  timer3.unref();
9345
9345
  }
@@ -13083,10 +13083,10 @@ var init_renderers = __esm({
13083
13083
  });
13084
13084
 
13085
13085
  // src/targets/user-descriptors.ts
13086
- import { resolve as resolve44 } from "path";
13087
- import { readFile as readFile30, readdir as readdir19 } from "fs/promises";
13086
+ import { resolve as resolve45 } from "path";
13087
+ import { readFile as readFile31, readdir as readdir19 } from "fs/promises";
13088
13088
  function userTargetsDir() {
13089
- return resolve44(syntaurRoot(), "targets");
13089
+ return resolve45(syntaurRoot(), "targets");
13090
13090
  }
13091
13091
  function msg(err2) {
13092
13092
  return err2 instanceof Error ? err2.message : String(err2);
@@ -13100,7 +13100,7 @@ function expandHomeAndEnv(p) {
13100
13100
  return v ?? "";
13101
13101
  }
13102
13102
  );
13103
- return resolve44(expandHome(envExpanded));
13103
+ return resolve45(expandHome(envExpanded));
13104
13104
  }
13105
13105
  function compileDetect(spec) {
13106
13106
  switch (spec.kind) {
@@ -13252,10 +13252,10 @@ async function loadUserDescriptors(opts = {}) {
13252
13252
  const targets = [];
13253
13253
  const seen = /* @__PURE__ */ new Set();
13254
13254
  for (const file of files) {
13255
- const full = resolve44(dir, file);
13255
+ const full = resolve45(dir, file);
13256
13256
  let raw2;
13257
13257
  try {
13258
- raw2 = await readFile30(full, "utf-8");
13258
+ raw2 = await readFile31(full, "utf-8");
13259
13259
  } catch (err2) {
13260
13260
  warnings.push(`skipped ${file}: ${msg(err2)}`);
13261
13261
  continue;
@@ -13305,23 +13305,23 @@ var init_user_descriptors = __esm({
13305
13305
 
13306
13306
  // src/targets/registry.ts
13307
13307
  import { homedir as homedir7 } from "os";
13308
- import { join as join10, resolve as resolve45 } from "path";
13308
+ import { join as join10, resolve as resolve46 } from "path";
13309
13309
  function home(...segments) {
13310
- return resolve45(homedir7(), ...segments);
13310
+ return resolve46(homedir7(), ...segments);
13311
13311
  }
13312
13312
  function hermesHome() {
13313
13313
  const env = process.env.HERMES_HOME;
13314
- return env && env.length > 0 ? resolve45(env) : home(".hermes");
13314
+ return env && env.length > 0 ? resolve46(env) : home(".hermes");
13315
13315
  }
13316
13316
  function hermesSkillsDir() {
13317
- return resolve45(hermesHome(), "skills");
13317
+ return resolve46(hermesHome(), "skills");
13318
13318
  }
13319
13319
  function isHermesHomeCustom() {
13320
13320
  return hermesHome() !== home(".hermes");
13321
13321
  }
13322
13322
  function codexHome() {
13323
13323
  const env = process.env.CODEX_HOME;
13324
- return env && env.length > 0 ? resolve45(env) : home(".codex");
13324
+ return env && env.length > 0 ? resolve46(env) : home(".codex");
13325
13325
  }
13326
13326
  function toDiscovered(meta) {
13327
13327
  if (!meta) return null;
@@ -13388,7 +13388,7 @@ var init_registry = __esm({
13388
13388
  skillsShAgentId: "codex",
13389
13389
  nativePlugin: "codex",
13390
13390
  detect: detectDir(codexHome()),
13391
- skillsDir: { global: resolve45(codexHome(), "skills") },
13391
+ skillsDir: { global: resolve46(codexHome(), "skills") },
13392
13392
  instructions: { files: [{ path: "AGENTS.md", renderer: "codexAgents" }] },
13393
13393
  sessions: codexSessions
13394
13394
  },
@@ -13456,7 +13456,7 @@ var init_registry = __esm({
13456
13456
  tier3: {
13457
13457
  kind: "hermes-plugin",
13458
13458
  source: "platforms/hermes/plugins/syntaur",
13459
- installDir: () => resolve45(hermesHome(), "plugins", "syntaur"),
13459
+ installDir: () => resolve46(hermesHome(), "plugins", "syntaur"),
13460
13460
  entry: "plugin.yaml"
13461
13461
  }
13462
13462
  }
@@ -13475,8 +13475,8 @@ __export(scanner_exports2, {
13475
13475
  import { execFile as execFile3, execFileSync as execFileSync4 } from "child_process";
13476
13476
  import { promisify as promisify3 } from "util";
13477
13477
  import { statSync as statSync4 } from "fs";
13478
- import { readFile as readFile31 } from "fs/promises";
13479
- import { resolve as resolve46 } from "path";
13478
+ import { readFile as readFile32 } from "fs/promises";
13479
+ import { resolve as resolve47 } from "path";
13480
13480
  function emptySummary() {
13481
13481
  return { discovered: 0, inserted: 0, revived: 0, swept: 0, skipped: 0, changed: false };
13482
13482
  }
@@ -13532,10 +13532,10 @@ async function defaultOpenFiles(files) {
13532
13532
  async function readContextLink(cwd, cache3) {
13533
13533
  if (cache3.has(cwd)) return cache3.get(cwd);
13534
13534
  let link = null;
13535
- const path = resolve46(cwd, ".syntaur", "context.json");
13535
+ const path = resolve47(cwd, ".syntaur", "context.json");
13536
13536
  if (await fileExists(path)) {
13537
13537
  try {
13538
- const parsed = JSON.parse(await readFile31(path, "utf-8"));
13538
+ const parsed = JSON.parse(await readFile32(path, "utf-8"));
13539
13539
  link = {
13540
13540
  projectSlug: typeof parsed.projectSlug === "string" ? parsed.projectSlug : null,
13541
13541
  assignmentSlug: typeof parsed.assignmentSlug === "string" ? parsed.assignmentSlug : null
@@ -13709,7 +13709,7 @@ import {
13709
13709
  unlinkSync
13710
13710
  } from "fs";
13711
13711
  import { fileURLToPath as fileURLToPath9, pathToFileURL } from "url";
13712
- import { dirname as dirname21, resolve as resolve70, join as join16 } from "path";
13712
+ import { dirname as dirname21, resolve as resolve71, join as join16 } from "path";
13713
13713
  import { homedir as homedir13, tmpdir as tmpdir2 } from "os";
13714
13714
  import { spawnSync as spawnSync7 } from "child_process";
13715
13715
  function syntaurRootMjs() {
@@ -13731,7 +13731,7 @@ async function registerMacosUrlHandler(options = { throwOnFailure: false }) {
13731
13731
  }
13732
13732
  const stateRoot = syntaurRootMjs();
13733
13733
  mkdirSync3(stateRoot, { recursive: true });
13734
- const lockPath = resolve70(stateRoot, "install-url-handler.lock");
13734
+ const lockPath = resolve71(stateRoot, "install-url-handler.lock");
13735
13735
  let lockFd;
13736
13736
  try {
13737
13737
  lockFd = openSync(lockPath, "wx");
@@ -13747,8 +13747,8 @@ async function registerMacosUrlHandler(options = { throwOnFailure: false }) {
13747
13747
  throw err2;
13748
13748
  }
13749
13749
  try {
13750
- const pkgRoot = resolve70(dirname21(fileURLToPath9(import.meta.url)), "..");
13751
- const cliBin = realpathSync3(resolve70(pkgRoot, "bin/syntaur.js"));
13750
+ const pkgRoot = resolve71(dirname21(fileURLToPath9(import.meta.url)), "..");
13751
+ const cliBin = realpathSync3(resolve71(pkgRoot, "bin/syntaur.js"));
13752
13752
  const nodeBin = process.execPath;
13753
13753
  const bundleParent = join16(
13754
13754
  homedir13(),
@@ -14598,7 +14598,7 @@ var init_App = __esm({
14598
14598
  });
14599
14599
 
14600
14600
  // src/index.ts
14601
- import { Command as Command23, InvalidArgumentError } from "commander";
14601
+ import { Command as Command24, InvalidArgumentError } from "commander";
14602
14602
 
14603
14603
  // src/commands/init.ts
14604
14604
  init_paths();
@@ -14756,7 +14756,7 @@ init_create_assignment();
14756
14756
  init_config2();
14757
14757
  import { spawn as spawn5 } from "child_process";
14758
14758
  import { createServer as createNetServer } from "net";
14759
- import { resolve as resolve48, dirname as dirname13 } from "path";
14759
+ import { resolve as resolve49, dirname as dirname13 } from "path";
14760
14760
  import { fileURLToPath as fileURLToPath3 } from "url";
14761
14761
 
14762
14762
  // src/dashboard/server.ts
@@ -14766,7 +14766,7 @@ init_assignment_resolver();
14766
14766
  init_agent_sessions();
14767
14767
  import express from "express";
14768
14768
  import { createServer } from "http";
14769
- import { resolve as resolve47 } from "path";
14769
+ import { resolve as resolve48 } from "path";
14770
14770
  import { writeFile as writeFile8, unlink as unlink9 } from "fs/promises";
14771
14771
  import { WebSocketServer, WebSocket } from "ws";
14772
14772
 
@@ -20192,7 +20192,7 @@ async function executeLaunchPlan(plan, spawnFn = realSpawn) {
20192
20192
  `Spawn failed: ${msg2}. Verify the terminal is installed and on PATH.`
20193
20193
  );
20194
20194
  }
20195
- await new Promise((resolve109, reject) => {
20195
+ await new Promise((resolve110, reject) => {
20196
20196
  let settled = false;
20197
20197
  let stderr = "";
20198
20198
  const finishOk = () => {
@@ -20202,7 +20202,7 @@ async function executeLaunchPlan(plan, spawnFn = realSpawn) {
20202
20202
  child.unref();
20203
20203
  } catch {
20204
20204
  }
20205
- resolve109();
20205
+ resolve110();
20206
20206
  };
20207
20207
  const finishErr = (remediation) => {
20208
20208
  if (settled) return;
@@ -20468,7 +20468,7 @@ function normalizeSlashes(p) {
20468
20468
  }
20469
20469
  function detectInstallKind(scriptUrl, opts = {}) {
20470
20470
  const realpath3 = opts.realpath ?? realpathSync.native;
20471
- const readFile80 = opts.readFile ?? ((p) => readFileSync2(p, "utf-8"));
20471
+ const readFile81 = opts.readFile ?? ((p) => readFileSync2(p, "utf-8"));
20472
20472
  const ua = opts.envUserAgent !== void 0 ? opts.envUserAgent : process.env.npm_config_user_agent ?? "";
20473
20473
  const resolved = resolveScriptPath(scriptUrl, realpath3);
20474
20474
  if (resolved === null) {
@@ -20489,7 +20489,7 @@ function detectInstallKind(scriptUrl, opts = {}) {
20489
20489
  const pkgJsonPath = join7(dir, "package.json");
20490
20490
  let raw2;
20491
20491
  try {
20492
- raw2 = readFile80(pkgJsonPath);
20492
+ raw2 = readFile81(pkgJsonPath);
20493
20493
  } catch {
20494
20494
  const parent2 = dirname7(dir);
20495
20495
  if (parent2 === dir) break;
@@ -23877,6 +23877,346 @@ function parseFilters(query) {
23877
23877
  return out;
23878
23878
  }
23879
23879
 
23880
+ // src/dashboard/api-inbox.ts
23881
+ import { Router as Router16 } from "express";
23882
+
23883
+ // src/inbox/index.ts
23884
+ init_fs();
23885
+ init_assignment_walk();
23886
+ init_parser();
23887
+ init_facts();
23888
+ init_state_machine();
23889
+ import { resolve as resolve39 } from "path";
23890
+ import { readFile as readFile26 } from "fs/promises";
23891
+
23892
+ // src/inbox/types.ts
23893
+ var INBOX_CATEGORIES = [
23894
+ "review",
23895
+ "blocked",
23896
+ "question",
23897
+ "plan-approval"
23898
+ ];
23899
+
23900
+ // src/inbox/index.ts
23901
+ function isReview(a) {
23902
+ return a.status === "review";
23903
+ }
23904
+ function isBlocked(a) {
23905
+ return a.status === "blocked";
23906
+ }
23907
+ function isUnresolvedQuestion(c2) {
23908
+ return c2.type === "question" && c2.resolved !== true;
23909
+ }
23910
+ function unresolvedQuestions(comments) {
23911
+ return comments.filter(isUnresolvedQuestion);
23912
+ }
23913
+ async function isPlanAwaitingApproval(a, assignmentDir) {
23914
+ if (a.status !== "ready_for_planning") return false;
23915
+ const latest = await latestPlanFile(assignmentDir);
23916
+ if (latest === null) return false;
23917
+ const approved = await isPlanApproved(assignmentDir, { planApproval: a.planApproval });
23918
+ return !approved;
23919
+ }
23920
+ function canonicalRfc3339(ms) {
23921
+ return new Date(ms).toISOString().replace(/\.\d{3}Z$/, "Z");
23922
+ }
23923
+ function validTimestamp(value) {
23924
+ if (typeof value !== "string") return null;
23925
+ const t = value.trim();
23926
+ if (t.length === 0) return null;
23927
+ const ms = Date.parse(t);
23928
+ return Number.isNaN(ms) ? null : canonicalRfc3339(ms);
23929
+ }
23930
+ function latestStatusHistoryAt(a) {
23931
+ let best = null;
23932
+ for (const e of a.statusHistory) {
23933
+ const at = validTimestamp(e.at);
23934
+ if (at === null) continue;
23935
+ const ms = Date.parse(at);
23936
+ if (best === null || ms >= best.ms) best = { at, ms };
23937
+ }
23938
+ return best?.at ?? null;
23939
+ }
23940
+ function latestStatusHistoryAtWhere(a, pred) {
23941
+ let best = null;
23942
+ for (const e of a.statusHistory) {
23943
+ if (!pred(e)) continue;
23944
+ const at = validTimestamp(e.at);
23945
+ if (at === null) continue;
23946
+ const ms = Date.parse(at);
23947
+ if (best === null || ms >= best.ms) best = { at, ms };
23948
+ }
23949
+ return best?.at ?? null;
23950
+ }
23951
+ function resolveSince(category, a, now, comment) {
23952
+ let primary = null;
23953
+ switch (category) {
23954
+ case "review":
23955
+ primary = latestStatusHistoryAtWhere(a, (e) => e.to === "review");
23956
+ break;
23957
+ case "blocked":
23958
+ primary = latestStatusHistoryAtWhere(a, (e) => e.dispositionTo === "blocked");
23959
+ break;
23960
+ case "question":
23961
+ primary = validTimestamp(comment?.timestamp);
23962
+ break;
23963
+ case "plan-approval":
23964
+ primary = latestStatusHistoryAt(a);
23965
+ break;
23966
+ }
23967
+ return primary ?? latestStatusHistoryAt(a) ?? validTimestamp(a.updated) ?? validTimestamp(a.created) ?? canonicalRfc3339(now);
23968
+ }
23969
+ function computeAgeMs(since, now) {
23970
+ const ms = Date.parse(since);
23971
+ if (Number.isNaN(ms)) return 0;
23972
+ return Math.max(0, now - ms);
23973
+ }
23974
+ var KNOWN_TRANSITION_CLI_VERBS = /* @__PURE__ */ new Set([
23975
+ "start",
23976
+ "complete",
23977
+ "fail",
23978
+ "reopen",
23979
+ "block",
23980
+ "unblock",
23981
+ "review"
23982
+ ]);
23983
+ function deriveReviewVerbs(config) {
23984
+ const candidates = /* @__PURE__ */ new Set();
23985
+ for (const t of config.transitions) {
23986
+ if (t.from === "review") candidates.add(t.command);
23987
+ }
23988
+ for (const key of config.transitionTable.keys()) {
23989
+ if (key.startsWith("review:")) candidates.add(key.slice("review:".length));
23990
+ }
23991
+ const blockedParked = config.blockedParkedStatuses ?? /* @__PURE__ */ new Set();
23992
+ const terminalAccept = [];
23993
+ const activeReopen = [];
23994
+ for (const command of candidates) {
23995
+ const target = getTargetStatus("review", command, config.transitionTable);
23996
+ if (target === null) continue;
23997
+ const isTerminal = config.terminalStatuses.has(target);
23998
+ if (isTerminal && command !== "fail" && KNOWN_TRANSITION_CLI_VERBS.has(command)) {
23999
+ terminalAccept.push(command);
24000
+ }
24001
+ if (!isTerminal && !blockedParked.has(target) && (command === "start" || command === "reopen")) {
24002
+ activeReopen.push(command);
24003
+ }
24004
+ }
24005
+ const accept = terminalAccept.find((c2) => c2 === "complete") ?? terminalAccept[0] ?? null;
24006
+ const reopen = activeReopen.find((c2) => c2 === "start") ?? activeReopen.find((c2) => c2 === "reopen") ?? null;
24007
+ return { accept, reopen };
24008
+ }
24009
+ function targetAndProject(item) {
24010
+ if (item.project === null) {
24011
+ return { target: item.assignmentId, projectFlag: "" };
24012
+ }
24013
+ return { target: item.assignmentSlug, projectFlag: ` --project ${item.project}` };
24014
+ }
24015
+ function buildAction(category, item, ctx) {
24016
+ const { target, projectFlag } = targetAndProject(item);
24017
+ switch (category) {
24018
+ case "review":
24019
+ if (ctx.acceptCommand) {
24020
+ return {
24021
+ verb: "Accept",
24022
+ command: `syntaur ${ctx.acceptCommand} ${target}${projectFlag}`
24023
+ };
24024
+ }
24025
+ if (ctx.reopenCommand) {
24026
+ return {
24027
+ verb: "Reopen",
24028
+ command: `syntaur ${ctx.reopenCommand} ${target}${projectFlag}`
24029
+ };
24030
+ }
24031
+ return {
24032
+ verb: "Review",
24033
+ command: `syntaur timeline ${target}${projectFlag}`
24034
+ };
24035
+ case "blocked":
24036
+ return {
24037
+ verb: "Unblock",
24038
+ command: `syntaur unblock ${target}${projectFlag}`
24039
+ };
24040
+ case "question":
24041
+ return {
24042
+ verb: "Answer",
24043
+ command: `syntaur comment ${target} "<answer>" --reply-to ${ctx.commentId ?? ""}${projectFlag}`
24044
+ };
24045
+ case "plan-approval":
24046
+ return {
24047
+ verb: "Approve plan",
24048
+ command: `syntaur plan approve ${target}${projectFlag}`
24049
+ };
24050
+ }
24051
+ }
24052
+ function orderByUrgency(items) {
24053
+ return [...items].sort((x, y) => y.ageMs - x.ageMs);
24054
+ }
24055
+ function summarizeQuestion(c2) {
24056
+ const body = c2.body.replace(/\s+/g, " ").trim();
24057
+ const clipped = body.length > 140 ? `${body.slice(0, 137)}...` : body;
24058
+ return clipped.length > 0 ? clipped : "(empty question)";
24059
+ }
24060
+ async function computeInbox(opts) {
24061
+ const now = opts.now ?? Date.now();
24062
+ const typeFilter = opts.types && opts.types.length > 0 ? new Set(opts.types) : null;
24063
+ const reviewVerbs = deriveReviewVerbs(opts.statusConfig);
24064
+ const walk = await listAssignmentsByProject(opts.projectsDir, opts.assignmentsDir);
24065
+ const matched = [];
24066
+ for (const entry of walk.withAssignmentMd) {
24067
+ if (opts.project !== void 0 && entry.projectSlug !== opts.project) continue;
24068
+ let parsed;
24069
+ try {
24070
+ const content = await readFile26(resolve39(entry.assignmentDir, "assignment.md"), "utf-8");
24071
+ parsed = parseAssignmentFull(content);
24072
+ } catch {
24073
+ continue;
24074
+ }
24075
+ if (parsed.archived) continue;
24076
+ if (parsed.disposition === "parked" || parsed.disposition === "terminal") continue;
24077
+ if (opts.statusConfig.terminalStatuses.has(parsed.status)) continue;
24078
+ const project = entry.projectSlug;
24079
+ const assignmentSlug = entry.assignmentSlug;
24080
+ const assignmentId = parsed.id;
24081
+ const title = parsed.title;
24082
+ const baseItem = { project, assignmentSlug, assignmentId };
24083
+ if ((!typeFilter || typeFilter.has("review")) && isReview(parsed)) {
24084
+ const since = resolveSince("review", parsed, now);
24085
+ matched.push({
24086
+ ...baseItem,
24087
+ title,
24088
+ category: "review",
24089
+ since,
24090
+ ageMs: computeAgeMs(since, now),
24091
+ summary: parsed.reviewRequested ? "Review requested \u2014 awaiting accept or reopen." : "Awaiting review \u2014 accept or reopen.",
24092
+ acceptCommand: reviewVerbs.accept,
24093
+ reopenCommand: reviewVerbs.reopen,
24094
+ action: buildAction("review", baseItem, {
24095
+ acceptCommand: reviewVerbs.accept,
24096
+ reopenCommand: reviewVerbs.reopen
24097
+ })
24098
+ });
24099
+ }
24100
+ if ((!typeFilter || typeFilter.has("blocked")) && isBlocked(parsed)) {
24101
+ const since = resolveSince("blocked", parsed, now);
24102
+ matched.push({
24103
+ ...baseItem,
24104
+ title,
24105
+ category: "blocked",
24106
+ since,
24107
+ ageMs: computeAgeMs(since, now),
24108
+ summary: parsed.blockedReason ? `Blocked: ${parsed.blockedReason}` : "Blocked \u2014 awaiting unblock.",
24109
+ action: buildAction("blocked", baseItem, {})
24110
+ });
24111
+ }
24112
+ if (!typeFilter || typeFilter.has("question")) {
24113
+ const commentsPath = resolve39(entry.assignmentDir, "comments.md");
24114
+ if (await fileExists(commentsPath)) {
24115
+ try {
24116
+ const content = await readFile26(commentsPath, "utf-8");
24117
+ const parsedComments = parseComments(content);
24118
+ for (const c2 of unresolvedQuestions(parsedComments.entries)) {
24119
+ const since = resolveSince("question", parsed, now, c2);
24120
+ matched.push({
24121
+ ...baseItem,
24122
+ title,
24123
+ category: "question",
24124
+ since,
24125
+ ageMs: computeAgeMs(since, now),
24126
+ summary: summarizeQuestion(c2),
24127
+ commentId: c2.id,
24128
+ action: buildAction("question", baseItem, {
24129
+ commentId: c2.id
24130
+ })
24131
+ });
24132
+ }
24133
+ } catch {
24134
+ }
24135
+ }
24136
+ }
24137
+ if (!typeFilter || typeFilter.has("plan-approval")) {
24138
+ if (await isPlanAwaitingApproval(parsed, entry.assignmentDir)) {
24139
+ const since = resolveSince("plan-approval", parsed, now);
24140
+ matched.push({
24141
+ ...baseItem,
24142
+ title,
24143
+ category: "plan-approval",
24144
+ since,
24145
+ ageMs: computeAgeMs(since, now),
24146
+ summary: "Plan awaiting approval.",
24147
+ action: buildAction("plan-approval", baseItem, {})
24148
+ });
24149
+ }
24150
+ }
24151
+ }
24152
+ const counts = {
24153
+ review: 0,
24154
+ blocked: 0,
24155
+ question: 0,
24156
+ "plan-approval": 0
24157
+ };
24158
+ for (const item of matched) counts[item.category]++;
24159
+ const total = matched.length;
24160
+ const ordered = [];
24161
+ for (const category of INBOX_CATEGORIES) {
24162
+ ordered.push(...orderByUrgency(matched.filter((i) => i.category === category)));
24163
+ }
24164
+ const items = opts.limit !== void 0 && opts.limit >= 0 ? ordered.slice(0, opts.limit) : ordered;
24165
+ return { items, counts, total };
24166
+ }
24167
+
24168
+ // src/dashboard/api-inbox.ts
24169
+ init_api();
24170
+ init_config2();
24171
+ function createInboxRouter(projectsDir2, assignmentsDir2) {
24172
+ const router = Router16();
24173
+ router.get("/inbox", async (req2, res) => {
24174
+ try {
24175
+ const project = typeof req2.query.project === "string" && req2.query.project.length > 0 ? req2.query.project : void 0;
24176
+ let types;
24177
+ if (typeof req2.query.type === "string" && req2.query.type.length > 0) {
24178
+ const raw2 = req2.query.type.split(",").map((t) => t.trim()).filter(Boolean);
24179
+ const unknown = raw2.filter((t) => !INBOX_CATEGORIES.includes(t));
24180
+ if (unknown.length > 0) {
24181
+ res.status(400).json({
24182
+ error: `Unknown inbox type(s): ${unknown.map((u) => JSON.stringify(u)).join(", ")}. Valid types: ${INBOX_CATEGORIES.join(", ")}.`
24183
+ });
24184
+ return;
24185
+ }
24186
+ types = raw2;
24187
+ }
24188
+ let limit;
24189
+ if (typeof req2.query.limit === "string") {
24190
+ const n = Number(req2.query.limit);
24191
+ if (Number.isInteger(n) && n > 0) limit = n;
24192
+ }
24193
+ const resolved = await getStatusConfig();
24194
+ const headline = (resolved.derive ?? DEFAULT_DERIVE_CONFIG).headline;
24195
+ const blockedParkedStatuses = new Set(
24196
+ [headline.blocked, headline.parked].filter(Boolean)
24197
+ );
24198
+ const statusConfig = { ...resolved, blockedParkedStatuses };
24199
+ const result = await computeInbox({
24200
+ projectsDir: projectsDir2,
24201
+ assignmentsDir: assignmentsDir2,
24202
+ project,
24203
+ types,
24204
+ limit,
24205
+ statusConfig
24206
+ });
24207
+ res.json(result);
24208
+ } catch (error) {
24209
+ console.warn("[inbox] failed to compute inbox:", error);
24210
+ res.json({
24211
+ items: [],
24212
+ counts: { review: 0, blocked: 0, question: 0, "plan-approval": 0 },
24213
+ total: 0
24214
+ });
24215
+ }
24216
+ });
24217
+ return router;
24218
+ }
24219
+
23880
24220
  // src/dashboard/api-playbooks.ts
23881
24221
  init_api();
23882
24222
  init_parser();
@@ -23885,9 +24225,9 @@ init_timestamp();
23885
24225
  init_fs();
23886
24226
  init_playbook();
23887
24227
  init_playbooks();
23888
- import { Router as Router16 } from "express";
23889
- import { resolve as resolve39 } from "path";
23890
- import { readFile as readFile26 } from "fs/promises";
24228
+ import { Router as Router17 } from "express";
24229
+ import { resolve as resolve40 } from "path";
24230
+ import { readFile as readFile27 } from "fs/promises";
23891
24231
  function statusForPlaybookError(code) {
23892
24232
  switch (code) {
23893
24233
  case "manifest":
@@ -23901,7 +24241,7 @@ function statusForPlaybookError(code) {
23901
24241
  }
23902
24242
  }
23903
24243
  function createPlaybooksRouter(playbooksDir3) {
23904
- const router = Router16();
24244
+ const router = Router17();
23905
24245
  router.get("/", async (_req, res) => {
23906
24246
  try {
23907
24247
  const playbooks = await listPlaybooks(playbooksDir3);
@@ -23968,8 +24308,8 @@ function createPlaybooksRouter(playbooksDir3) {
23968
24308
  res.status(404).json({ error: `Playbook "${req2.params.slug}" not found` });
23969
24309
  return;
23970
24310
  }
23971
- const filePath = resolve39(playbooksDir3, resolved.filename);
23972
- const content = await readFile26(filePath, "utf-8");
24311
+ const filePath = resolve40(playbooksDir3, resolved.filename);
24312
+ const content = await readFile27(filePath, "utf-8");
23973
24313
  res.json({
23974
24314
  documentType: "playbook",
23975
24315
  title: `Edit Playbook: ${resolved.slug}`,
@@ -23994,7 +24334,7 @@ function createPlaybooksRouter(playbooksDir3) {
23994
24334
  return;
23995
24335
  }
23996
24336
  await ensureDir(playbooksDir3);
23997
- const filePath = resolve39(playbooksDir3, `${slug}.md`);
24337
+ const filePath = resolve40(playbooksDir3, `${slug}.md`);
23998
24338
  if (await fileExists(filePath)) {
23999
24339
  res.status(409).json({ error: `Playbook "${slug}" already exists` });
24000
24340
  return;
@@ -24018,7 +24358,7 @@ function createPlaybooksRouter(playbooksDir3) {
24018
24358
  res.status(404).json({ error: `Playbook "${req2.params.slug}" not found` });
24019
24359
  return;
24020
24360
  }
24021
- const filePath = resolve39(playbooksDir3, resolved.filename);
24361
+ const filePath = resolve40(playbooksDir3, resolved.filename);
24022
24362
  await writeFileForce(filePath, content);
24023
24363
  await rebuildPlaybookManifest(playbooksDir3);
24024
24364
  res.json({ slug: resolved.slug, path: filePath });
@@ -24065,7 +24405,7 @@ init_fs_migration();
24065
24405
  init_parser2();
24066
24406
  init_fs();
24067
24407
  init_paths();
24068
- import { Router as Router18 } from "express";
24408
+ import { Router as Router19 } from "express";
24069
24409
  import { readdir as readdir17 } from "fs/promises";
24070
24410
  import { resolve as resolvePath, dirname as dirname11 } from "path";
24071
24411
  import { rename as rename6, mkdir as mkdir5 } from "fs/promises";
@@ -24078,7 +24418,7 @@ import { raw } from "express";
24078
24418
 
24079
24419
  // src/todos/attachments.ts
24080
24420
  import { mkdir as mkdir4, readdir as readdir16, stat as stat5, rename as rename5, rm as rm4, unlink as unlink7, writeFile as writeFile6, cp } from "fs/promises";
24081
- import { resolve as resolve40, basename as basename5, dirname as dirname10, extname } from "path";
24421
+ import { resolve as resolve41, basename as basename5, dirname as dirname10, extname } from "path";
24082
24422
 
24083
24423
  // src/utils/proof-artifact-id.ts
24084
24424
  import { randomBytes as randomBytes2 } from "crypto";
@@ -24189,12 +24529,12 @@ function sanitizeAttachmentName(name) {
24189
24529
  return n;
24190
24530
  }
24191
24531
  function attachmentsRootDir(todosDir2) {
24192
- return resolve40(todosDir2, "attachments");
24532
+ return resolve41(todosDir2, "attachments");
24193
24533
  }
24194
24534
  function attachmentDirFor(todosDir2, scopeId, todoId) {
24195
24535
  assertScope(scopeId);
24196
24536
  assertTodoId(todoId);
24197
- return resolve40(attachmentsRootDir(todosDir2), scopeId, todoId);
24537
+ return resolve41(attachmentsRootDir(todosDir2), scopeId, todoId);
24198
24538
  }
24199
24539
  async function dirExists(p) {
24200
24540
  try {
@@ -24208,7 +24548,7 @@ async function writeAttachment(todosDir2, scopeId, todoId, originalName, bytes)
24208
24548
  await mkdir4(dir, { recursive: true });
24209
24549
  const id = generateArtifactId();
24210
24550
  const filename = sanitizeAttachmentName(originalName);
24211
- await writeFile6(resolve40(dir, `${id}__${filename}`), bytes);
24551
+ await writeFile6(resolve41(dir, `${id}__${filename}`), bytes);
24212
24552
  return {
24213
24553
  id,
24214
24554
  filename,
@@ -24233,7 +24573,7 @@ async function listAttachments(todosDir2, scopeId, todoId) {
24233
24573
  if (!ATTACHMENT_ID_RE.test(id)) continue;
24234
24574
  const filename = stored.slice(sep2 + 2);
24235
24575
  try {
24236
- const st = await stat5(resolve40(dir, stored));
24576
+ const st = await stat5(resolve41(dir, stored));
24237
24577
  if (!st.isFile()) continue;
24238
24578
  out.push({ id, filename, mime: mimeForName(filename), size: st.size, createdAt: st.mtime.toISOString() });
24239
24579
  } catch {
@@ -24244,7 +24584,7 @@ async function listAttachments(todosDir2, scopeId, todoId) {
24244
24584
  }
24245
24585
  async function readScopeAttachments(todosDir2, scopeId) {
24246
24586
  assertScope(scopeId);
24247
- const scopeDir = resolve40(attachmentsRootDir(todosDir2), scopeId);
24587
+ const scopeDir = resolve41(attachmentsRootDir(todosDir2), scopeId);
24248
24588
  let todoIds;
24249
24589
  try {
24250
24590
  todoIds = await readdir16(scopeDir);
@@ -24272,7 +24612,7 @@ async function resolveAttachmentFile(todosDir2, scopeId, todoId, attachmentId) {
24272
24612
  const stored = names.find((n) => n.startsWith(prefix));
24273
24613
  if (!stored) return null;
24274
24614
  const filename = stored.slice(prefix.length);
24275
- return { path: resolve40(dir, stored), filename, mime: mimeForName(filename) };
24615
+ return { path: resolve41(dir, stored), filename, mime: mimeForName(filename) };
24276
24616
  }
24277
24617
  async function deleteAttachment(todosDir2, scopeId, todoId, attachmentId) {
24278
24618
  const resolved = await resolveAttachmentFile(todosDir2, scopeId, todoId, attachmentId);
@@ -24434,7 +24774,7 @@ function touchItem3(item) {
24434
24774
  item.updatedAt = now;
24435
24775
  }
24436
24776
  function createTodosRouter(todosDir2, broadcast, projectsDir2) {
24437
- const router = Router18();
24777
+ const router = Router19();
24438
24778
  installRecordsInvalidation(router);
24439
24779
  function broadcastUpdate() {
24440
24780
  broadcast({ type: "todos-updated", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
@@ -24684,8 +25024,8 @@ function createTodosRouter(todosDir2, broadcast, projectsDir2) {
24684
25024
  router.post("/:workspace/archive", async (req2, res) => {
24685
25025
  try {
24686
25026
  const { archivePath: archivePath2 } = await Promise.resolve().then(() => (init_parser2(), parser_exports));
24687
- const { resolve: resolve109 } = await import("path");
24688
- const { readFile: readFile80 } = await import("fs/promises");
25027
+ const { resolve: resolve110 } = await import("path");
25028
+ const { readFile: readFile81 } = await import("fs/promises");
24689
25029
  const { writeFileForce: writeFileForce2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
24690
25030
  const workspace = getWorkspaceParam(req2.params.workspace);
24691
25031
  const outcome = await wsLock(workspace, async () => {
@@ -24701,10 +25041,10 @@ function createTodosRouter(todosDir2, broadcast, projectsDir2) {
24701
25041
  (e) => e.itemIds.every((id) => completedIds.has(id))
24702
25042
  );
24703
25043
  const archFile = archivePath2(todosDir2, workspace, checklist.archiveInterval);
24704
- await ensureDir(resolve109(todosDir2, "archive"));
25044
+ await ensureDir(resolve110(todosDir2, "archive"));
24705
25045
  let archContent = "";
24706
25046
  if (await fileExists(archFile)) {
24707
- archContent = await readFile80(archFile, "utf-8");
25047
+ archContent = await readFile81(archFile, "utf-8");
24708
25048
  archContent = archContent.trimEnd() + "\n\n";
24709
25049
  } else {
24710
25050
  archContent = `---
@@ -24996,7 +25336,7 @@ workspace: ${workspace}
24996
25336
  const { readConfig: readConfig3 } = await Promise.resolve().then(() => (init_config2(), config_exports));
24997
25337
  const { assignmentsDir: assignmentsDirFn } = await Promise.resolve().then(() => (init_paths(), paths_exports));
24998
25338
  const { fileExists: fileExists2, writeFileForce: writeFileForce2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
24999
- const { readFile: readFile80 } = await import("fs/promises");
25339
+ const { readFile: readFile81 } = await import("fs/promises");
25000
25340
  const { appendTodosToAssignmentBody: appendTodosToAssignmentBody2, touchAssignmentUpdated: touchAssignmentUpdated2 } = await Promise.resolve().then(() => (init_assignment_todos(), assignment_todos_exports));
25001
25341
  const { nowTimestamp: nowTimestamp3 } = await Promise.resolve().then(() => (init_timestamp(), timestamp_exports));
25002
25342
  let assignmentRef;
@@ -25017,7 +25357,7 @@ workspace: ${workspace}
25017
25357
  }
25018
25358
  const assignmentMdPath2 = resolvePath2(assignmentDir, "assignment.md");
25019
25359
  if (!await fileExists2(assignmentMdPath2)) return { error: `Target assignment not found: ${assignmentMdPath2}` };
25020
- let content = await readFile80(assignmentMdPath2, "utf-8");
25360
+ let content = await readFile81(assignmentMdPath2, "utf-8");
25021
25361
  content = appendTodosToAssignmentBody2(
25022
25362
  content,
25023
25363
  items.map((it) => ({
@@ -25211,9 +25551,9 @@ init_parser2();
25211
25551
  init_fs();
25212
25552
  init_paths();
25213
25553
  init_slug();
25214
- import { Router as Router19 } from "express";
25215
- import { mkdir as mkdir6, readFile as readFile27, rename as rename7 } from "fs/promises";
25216
- import { resolve as resolve41, dirname as dirname12 } from "path";
25554
+ import { Router as Router20 } from "express";
25555
+ import { mkdir as mkdir6, readFile as readFile28, rename as rename7 } from "fs/promises";
25556
+ import { resolve as resolve42, dirname as dirname12 } from "path";
25217
25557
  init_promote_todos();
25218
25558
  init_api();
25219
25559
  var WORKSPACE_REGEX2 = /^[a-z0-9_][a-z0-9-]*$/;
@@ -25230,7 +25570,7 @@ function params(req2) {
25230
25570
  return req2.params;
25231
25571
  }
25232
25572
  async function projectExists(projectsDir2, slug) {
25233
- return fileExists(resolve41(projectsDir2, slug, "project.md"));
25573
+ return fileExists(resolve42(projectsDir2, slug, "project.md"));
25234
25574
  }
25235
25575
  async function ensureProjectTodosDir(projectsDir2, slug) {
25236
25576
  const todosDir2 = projectTodosDir(projectsDir2, slug);
@@ -25247,7 +25587,7 @@ async function ensureProjectTodosDir(projectsDir2, slug) {
25247
25587
  throw err2;
25248
25588
  }
25249
25589
  try {
25250
- await mkdir6(resolve41(todosDir2, "archive"), { recursive: false });
25590
+ await mkdir6(resolve42(todosDir2, "archive"), { recursive: false });
25251
25591
  } catch (err2) {
25252
25592
  const code = err2.code;
25253
25593
  if (code === "EEXIST") return;
@@ -25263,7 +25603,7 @@ function notFound(res, slug) {
25263
25603
  res.status(404).json({ error: `Project "${slug}" not found` });
25264
25604
  }
25265
25605
  function createProjectTodosRouter(projectsDir2, broadcast, workspaceTodosDir) {
25266
- const router = Router19({ mergeParams: true });
25606
+ const router = Router20({ mergeParams: true });
25267
25607
  installRecordsInvalidation(router);
25268
25608
  function broadcastUpdate(projectSlug) {
25269
25609
  broadcast({ type: "todos-updated", projectSlug, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
@@ -25451,7 +25791,7 @@ function createProjectTodosRouter(projectsDir2, broadcast, workspaceTodosDir) {
25451
25791
  const archFile = archivePath(todosDir2, slug, checklist.archiveInterval);
25452
25792
  let archContent = "";
25453
25793
  if (await fileExists(archFile)) {
25454
- archContent = await readFile27(archFile, "utf-8");
25794
+ archContent = await readFile28(archFile, "utf-8");
25455
25795
  archContent = archContent.trimEnd() + "\n\n";
25456
25796
  } else {
25457
25797
  archContent = `---
@@ -25913,17 +26253,17 @@ workspace: ${slug}
25913
26253
  if (tg.includes("/")) {
25914
26254
  const parts = tg.split("/");
25915
26255
  if (parts.length !== 2) return { error: `Invalid target.assignment "${tg}"` };
25916
- assignmentDir = resolve41(projectsDir2, parts[0], "assignments", parts[1]);
26256
+ assignmentDir = resolve42(projectsDir2, parts[0], "assignments", parts[1]);
25917
26257
  assignmentRef = `${parts[0]}/${parts[1]}`;
25918
26258
  } else if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(tg)) {
25919
- assignmentDir = resolve41(assignmentsDirFn(), tg);
26259
+ assignmentDir = resolve42(assignmentsDirFn(), tg);
25920
26260
  assignmentRef = tg;
25921
26261
  } else {
25922
26262
  return { error: `Invalid target.assignment "${tg}"` };
25923
26263
  }
25924
- const assignmentMdPath2 = resolve41(assignmentDir, "assignment.md");
26264
+ const assignmentMdPath2 = resolve42(assignmentDir, "assignment.md");
25925
26265
  if (!await fileExists(assignmentMdPath2)) return { error: `Target assignment not found: ${assignmentMdPath2}` };
25926
- let content = await readFile27(assignmentMdPath2, "utf-8");
26266
+ let content = await readFile28(assignmentMdPath2, "utf-8");
25927
26267
  content = appendTodosToAssignmentBody2(
25928
26268
  content,
25929
26269
  items.map((it) => ({
@@ -26125,7 +26465,7 @@ workspace: ${slug}
26125
26465
  }
26126
26466
 
26127
26467
  // src/dashboard/api-bundles.ts
26128
- import { Router as Router20 } from "express";
26468
+ import { Router as Router21 } from "express";
26129
26469
  import { readdir as readdir18 } from "fs/promises";
26130
26470
 
26131
26471
  // src/todos/bundle-parser.ts
@@ -26134,7 +26474,7 @@ init_fs();
26134
26474
  init_paths();
26135
26475
  init_parser2();
26136
26476
  import { randomBytes as randomBytes3 } from "crypto";
26137
- import { readFile as readFile28 } from "fs/promises";
26477
+ import { readFile as readFile29 } from "fs/promises";
26138
26478
  var BUNDLE_ID_REGEX = /^[a-f0-9]{4}$/;
26139
26479
  var SCOPE_VALUES = /* @__PURE__ */ new Set(["workspace", "project", "global"]);
26140
26480
  var SCOPE_ID_REGEX = /^[a-z0-9_][a-z0-9_-]*$/;
@@ -26237,7 +26577,7 @@ ${lines}
26237
26577
  async function readBundles(todosDir2) {
26238
26578
  const path = bundlesPath(todosDir2);
26239
26579
  if (!await fileExists(path)) return [];
26240
- const content = await readFile28(path, "utf-8");
26580
+ const content = await readFile29(path, "utf-8");
26241
26581
  return parseBundles(content).bundles;
26242
26582
  }
26243
26583
  async function writeBundles(todosDir2, bundles) {
@@ -26276,7 +26616,7 @@ function annotate(bundle, items) {
26276
26616
  }
26277
26617
  function createBundlesRouter(todosDir2, broadcast) {
26278
26618
  void broadcast;
26279
- const router = Router20();
26619
+ const router = Router21();
26280
26620
  function validateWorkspace(req2, res, next) {
26281
26621
  const workspace = getWorkspaceParam2(req2.params.workspace);
26282
26622
  if (workspace && !WORKSPACE_REGEX3.test(workspace)) {
@@ -26342,8 +26682,8 @@ function createBundlesRouter(todosDir2, broadcast) {
26342
26682
  init_fs();
26343
26683
  init_paths();
26344
26684
  init_slug();
26345
- import { Router as Router21 } from "express";
26346
- import { resolve as resolve42 } from "path";
26685
+ import { Router as Router22 } from "express";
26686
+ import { resolve as resolve43 } from "path";
26347
26687
  init_parser2();
26348
26688
  function deriveStatus2(bundle, items) {
26349
26689
  const members = bundle.todoIds.map((id) => items.find((i) => i.id === id)).filter((i) => i !== void 0);
@@ -26372,7 +26712,7 @@ function notFound2(res, slug) {
26372
26712
  }
26373
26713
  function createProjectBundlesRouter(projectsDir2, broadcast) {
26374
26714
  void broadcast;
26375
- const router = Router21({ mergeParams: true });
26715
+ const router = Router22({ mergeParams: true });
26376
26716
  function validateProjectId(req2, res, next) {
26377
26717
  const slug = getProjectIdParam2(req2.params.projectId);
26378
26718
  if (!slug || !isValidSlug(slug)) {
@@ -26385,7 +26725,7 @@ function createProjectBundlesRouter(projectsDir2, broadcast) {
26385
26725
  router.get("/", async (req2, res) => {
26386
26726
  try {
26387
26727
  const slug = getProjectIdParam2(req2.params.projectId);
26388
- const projectMd = resolve42(projectsDir2, slug, "project.md");
26728
+ const projectMd = resolve43(projectsDir2, slug, "project.md");
26389
26729
  if (!await fileExists(projectMd)) {
26390
26730
  notFound2(res, slug);
26391
26731
  return;
@@ -26406,7 +26746,7 @@ function createProjectBundlesRouter(projectsDir2, broadcast) {
26406
26746
  init_config2();
26407
26747
  init_api();
26408
26748
  init_scanner();
26409
- import { Router as Router22 } from "express";
26749
+ import { Router as Router23 } from "express";
26410
26750
 
26411
26751
  // src/utils/github-backup.ts
26412
26752
  init_paths();
@@ -26414,8 +26754,8 @@ init_fs();
26414
26754
  init_config2();
26415
26755
  import { execFile as execFile2 } from "child_process";
26416
26756
  import { promisify as promisify2 } from "util";
26417
- import { cp as cp2, mkdtemp, rm as rm5, readFile as readFile29, writeFile as writeFile7, unlink as unlink8, stat as stat6, open as open5, rename as rename8 } from "fs/promises";
26418
- import { resolve as resolve43, join as join9 } from "path";
26757
+ import { cp as cp2, mkdtemp, rm as rm5, readFile as readFile30, writeFile as writeFile7, unlink as unlink8, stat as stat6, open as open5, rename as rename8 } from "fs/promises";
26758
+ import { resolve as resolve44, join as join9 } from "path";
26419
26759
  import { tmpdir } from "os";
26420
26760
  var exec2 = promisify2(execFile2);
26421
26761
  var VALID_CATEGORIES = ["projects", "playbooks", "todos", "servers", "config"];
@@ -26455,7 +26795,7 @@ async function resolveCategoryPath(category) {
26455
26795
  case "servers":
26456
26796
  return { sourcePath: serversDir(), repoPath: "servers", isFile: false };
26457
26797
  case "config":
26458
- return { sourcePath: resolve43(syntaurRoot(), "config.md"), repoPath: "config.md", isFile: true };
26798
+ return { sourcePath: resolve44(syntaurRoot(), "config.md"), repoPath: "config.md", isFile: true };
26459
26799
  }
26460
26800
  }
26461
26801
  async function checkGitInstalled() {
@@ -26466,7 +26806,7 @@ async function checkGitInstalled() {
26466
26806
  }
26467
26807
  }
26468
26808
  async function acquireLock2() {
26469
- const lockPath = resolve43(syntaurRoot(), LOCK_FILE_NAME);
26809
+ const lockPath = resolve44(syntaurRoot(), LOCK_FILE_NAME);
26470
26810
  await ensureDir(syntaurRoot());
26471
26811
  try {
26472
26812
  const handle = await open5(lockPath, "wx");
@@ -26475,7 +26815,7 @@ async function acquireLock2() {
26475
26815
  return lockPath;
26476
26816
  } catch (err2) {
26477
26817
  if (err2.code === "EEXIST") {
26478
- const pid = await readFile29(lockPath, "utf-8").catch(() => "");
26818
+ const pid = await readFile30(lockPath, "utf-8").catch(() => "");
26479
26819
  throw new Error(
26480
26820
  `Backup operation already in progress (lock file at ${lockPath}, pid ${pid.trim() || "unknown"}). If stale, delete the file and retry.`
26481
26821
  );
@@ -26513,7 +26853,7 @@ async function copyRecursive(src, dest) {
26513
26853
  await ensureDir(dest);
26514
26854
  await cp2(src, dest, { recursive: true, force: true });
26515
26855
  } else {
26516
- await ensureDir(resolve43(dest, ".."));
26856
+ await ensureDir(resolve44(dest, ".."));
26517
26857
  await cp2(src, dest, { force: true });
26518
26858
  }
26519
26859
  }
@@ -26522,7 +26862,7 @@ function resolveCategoriesStrict(csv) {
26522
26862
  return parseCategoriesStrict(parts);
26523
26863
  }
26524
26864
  async function readSanitizedConfig(configPath2) {
26525
- const content = await readFile29(configPath2, "utf-8");
26865
+ const content = await readFile30(configPath2, "utf-8");
26526
26866
  return content.replace(/^(\s*lastBackup:\s*).*$/m, "$1null").replace(/^(\s*lastRestore:\s*).*$/m, "$1null");
26527
26867
  }
26528
26868
  async function backupToGithub(overrides) {
@@ -26561,7 +26901,7 @@ async function backupToGithub(overrides) {
26561
26901
  }
26562
26902
  if (category === "config") {
26563
26903
  const sanitized = await readSanitizedConfig(sourcePath);
26564
- await ensureDir(resolve43(destPath, ".."));
26904
+ await ensureDir(resolve44(destPath, ".."));
26565
26905
  await writeFile7(destPath, sanitized, "utf-8");
26566
26906
  } else {
26567
26907
  await copyRecursive(sourcePath, destPath);
@@ -26615,7 +26955,7 @@ async function backupToGithub(overrides) {
26615
26955
  }
26616
26956
  async function safeRestoreCategory(localPath, repoSrcPath, isFile) {
26617
26957
  if (isFile) {
26618
- await ensureDir(resolve43(localPath, ".."));
26958
+ await ensureDir(resolve44(localPath, ".."));
26619
26959
  await cp2(repoSrcPath, localPath, { force: true });
26620
26960
  return;
26621
26961
  }
@@ -26716,7 +27056,7 @@ async function restoreFromGithub(overrides) {
26716
27056
  }
26717
27057
  async function getBackupStatus() {
26718
27058
  const config = await readConfig();
26719
- const lockPath = resolve43(syntaurRoot(), LOCK_FILE_NAME);
27059
+ const lockPath = resolve44(syntaurRoot(), LOCK_FILE_NAME);
26720
27060
  const locked = await fileExists(lockPath);
26721
27061
  return {
26722
27062
  repo: config.backup?.repo ?? null,
@@ -26729,7 +27069,7 @@ async function getBackupStatus() {
26729
27069
 
26730
27070
  // src/dashboard/api-backup.ts
26731
27071
  function createBackupRouter() {
26732
- const router = Router22();
27072
+ const router = Router23();
26733
27073
  router.get("/", async (_req, res) => {
26734
27074
  try {
26735
27075
  const status = await getBackupStatus();
@@ -27199,7 +27539,7 @@ async function runCcusage(opts = {}) {
27199
27539
  };
27200
27540
  }
27201
27541
  function runOnce(binary, args, env, timeoutMs, maxOutputBytes) {
27202
- return new Promise((resolve109) => {
27542
+ return new Promise((resolve110) => {
27203
27543
  const child = spawn4(binary, args, {
27204
27544
  env: env ?? process.env,
27205
27545
  stdio: ["ignore", "pipe", "pipe"]
@@ -27213,7 +27553,7 @@ function runOnce(binary, args, env, timeoutMs, maxOutputBytes) {
27213
27553
  if (settled) return;
27214
27554
  settled = true;
27215
27555
  clearTimeout(timer3);
27216
- resolve109(result);
27556
+ resolve110(result);
27217
27557
  };
27218
27558
  const timer3 = setTimeout(() => {
27219
27559
  timedOut = true;
@@ -27512,7 +27852,7 @@ function createDashboardServer(options) {
27512
27852
  (async () => {
27513
27853
  try {
27514
27854
  const configResult = await migrateLegacyConfig(
27515
- resolve47(syntaurRoot(), "config.md")
27855
+ resolve48(syntaurRoot(), "config.md")
27516
27856
  );
27517
27857
  const projectResult = await migrateLegacyProjectFiles(projectsDir2);
27518
27858
  const summary = summarizeMigration(projectResult, configResult);
@@ -28002,6 +28342,7 @@ function createDashboardServer(options) {
28002
28342
  app.use("/api/schedules", createSchedulesRouter(broadcast));
28003
28343
  app.use("/api/usage", createUsageRouter(projectsDir2, assignmentsDir2));
28004
28344
  app.use("/api", createEventsRouter(projectsDir2, assignmentsDir2));
28345
+ app.use("/api", createInboxRouter(projectsDir2, assignmentsDir2));
28005
28346
  app.use("/api/agent-sessions", createAgentSessionsRouter(projectsDir2, broadcast, assignmentsDir2));
28006
28347
  app.use("/api/config/agents", createAgentsRouter());
28007
28348
  app.use(
@@ -28034,14 +28375,14 @@ function createDashboardServer(options) {
28034
28375
  app.use("/api/backup", createBackupRouter());
28035
28376
  if (serveStaticUi && dashboardDistPath) {
28036
28377
  const sendOpts = { dotfiles: "allow" };
28037
- app.use("/assets", express.static(resolve47(dashboardDistPath, "assets"), sendOpts));
28378
+ app.use("/assets", express.static(resolve48(dashboardDistPath, "assets"), sendOpts));
28038
28379
  app.use(express.static(dashboardDistPath, { ...sendOpts, index: false, fallthrough: true }));
28039
28380
  app.get("{*path}", async (req2, res) => {
28040
28381
  if (req2.path.startsWith("/api") || req2.path === "/ws" || req2.path.startsWith("/assets")) {
28041
28382
  res.status(404).json({ error: "Not Found" });
28042
28383
  return;
28043
28384
  }
28044
- const indexPath = resolve47(dashboardDistPath, "index.html");
28385
+ const indexPath = resolve48(dashboardDistPath, "index.html");
28045
28386
  if (!await fileExists(indexPath)) {
28046
28387
  res.status(503).send(
28047
28388
  'Dashboard not built. Run "npm run build:dashboard" first.'
@@ -28075,8 +28416,8 @@ function createDashboardServer(options) {
28075
28416
  if (!await migrationGate()) return;
28076
28417
  try {
28077
28418
  const context = await resolveDeriveContext2();
28078
- const projectDir = projectSlug ? resolve47(projectsDir2, projectSlug) : null;
28079
- const path = projectDir ? resolve47(projectDir, "assignments", assignmentSlug, "assignment.md") : resolve47(assignmentsDir2, assignmentSlug, "assignment.md");
28419
+ const projectDir = projectSlug ? resolve48(projectsDir2, projectSlug) : null;
28420
+ const path = projectDir ? resolve48(projectDir, "assignments", assignmentSlug, "assignment.md") : resolve48(assignmentsDir2, assignmentSlug, "assignment.md");
28080
28421
  if (!await fileExists(path)) return;
28081
28422
  const result = await recomputeAndWrite2(path, {
28082
28423
  cause: "derive",
@@ -28129,8 +28470,8 @@ function createDashboardServer(options) {
28129
28470
  serversDir: serversDir2,
28130
28471
  playbooksDir: playbooksDir3,
28131
28472
  todosDir: todosDir2,
28132
- dbPath: resolve47(syntaurRoot(), "syntaur.db"),
28133
- configPath: resolve47(syntaurRoot(), "config.md"),
28473
+ dbPath: resolve48(syntaurRoot(), "syntaur.db"),
28474
+ configPath: resolve48(syntaurRoot(), "config.md"),
28134
28475
  onMessage: broadcast,
28135
28476
  onAssignmentChanged: (projectSlug, assignmentSlug) => {
28136
28477
  void recomputeOne(projectSlug, assignmentSlug);
@@ -28166,7 +28507,7 @@ function createDashboardServer(options) {
28166
28507
  }
28167
28508
  });
28168
28509
  server.listen(port, () => {
28169
- const portFile = resolve47(syntaurRoot(), "dashboard-port");
28510
+ const portFile = resolve48(syntaurRoot(), "dashboard-port");
28170
28511
  writeFile8(portFile, String(port), "utf-8").catch(() => {
28171
28512
  });
28172
28513
  resolvePromise();
@@ -28186,7 +28527,7 @@ function createDashboardServer(options) {
28186
28527
  client.terminate();
28187
28528
  }
28188
28529
  clients.clear();
28189
- const portFile = resolve47(syntaurRoot(), "dashboard-port");
28530
+ const portFile = resolve48(syntaurRoot(), "dashboard-port");
28190
28531
  await unlink9(portFile).catch(() => {
28191
28532
  });
28192
28533
  server.closeAllConnections?.();
@@ -28314,8 +28655,8 @@ async function dashboardCommand(options) {
28314
28655
  port = availablePort;
28315
28656
  }
28316
28657
  const thisFile = fileURLToPath3(import.meta.url);
28317
- const packageRoot = resolve48(dirname13(thisFile), "..");
28318
- const dashboardDist = resolve48(packageRoot, "dashboard", "dist");
28658
+ const packageRoot = resolve49(dirname13(thisFile), "..");
28659
+ const dashboardDist = resolve49(packageRoot, "dashboard", "dist");
28319
28660
  const server = createDashboardServer({
28320
28661
  port,
28321
28662
  projectsDir: projectsDir2,
@@ -28339,8 +28680,8 @@ async function dashboardCommand(options) {
28339
28680
  }
28340
28681
  let viteProcess = null;
28341
28682
  if (mode === "dev") {
28342
- const dashboardDir = resolve48(packageRoot, "dashboard");
28343
- const viteBin = resolve48(dashboardDir, "node_modules", ".bin", "vite");
28683
+ const dashboardDir = resolve49(packageRoot, "dashboard");
28684
+ const viteBin = resolve49(dashboardDir, "node_modules", ".bin", "vite");
28344
28685
  if (!await fileExists(viteBin)) {
28345
28686
  console.error(
28346
28687
  'Vite not found. Run "npm ci --prefix dashboard" first, or use the default bundled dashboard mode.'
@@ -28415,7 +28756,7 @@ init_config2();
28415
28756
  init_slug();
28416
28757
  init_lifecycle();
28417
28758
  init_assignment_resolver();
28418
- import { resolve as resolve49 } from "path";
28759
+ import { resolve as resolve50 } from "path";
28419
28760
  function resolveLinkedTodosLookup(projectsDir2) {
28420
28761
  return { todosDir: todosDir(), projectsDir: projectsDir2 };
28421
28762
  }
@@ -28429,8 +28770,8 @@ async function runTransition(assignment, command, options = {}) {
28429
28770
  if (!isValidSlug(assignment)) {
28430
28771
  throw new Error(`Invalid assignment slug "${assignment}".`);
28431
28772
  }
28432
- const projectDir = resolve49(baseDir, options.project);
28433
- const projectMdPath = resolve49(projectDir, "project.md");
28773
+ const projectDir = resolve50(baseDir, options.project);
28774
+ const projectMdPath = resolve50(projectDir, "project.md");
28434
28775
  if (!await fileExists(projectDir) || !await fileExists(projectMdPath)) {
28435
28776
  throw new Error(`Project "${options.project}" not found at ${projectDir}.`);
28436
28777
  }
@@ -28463,8 +28804,8 @@ async function runAssign(assignment, agent, options = {}) {
28463
28804
  if (!isValidSlug(assignment)) {
28464
28805
  throw new Error(`Invalid assignment slug "${assignment}".`);
28465
28806
  }
28466
- const projectDir = resolve49(baseDir, options.project);
28467
- const projectMdPath = resolve49(projectDir, "project.md");
28807
+ const projectDir = resolve50(baseDir, options.project);
28808
+ const projectMdPath = resolve50(projectDir, "project.md");
28468
28809
  if (!await fileExists(projectDir) || !await fileExists(projectMdPath)) {
28469
28810
  throw new Error(`Project "${options.project}" not found at ${projectDir}.`);
28470
28811
  }
@@ -28488,8 +28829,8 @@ async function runUnassign(assignment, options = {}) {
28488
28829
  if (!isValidSlug(assignment)) {
28489
28830
  throw new Error(`Invalid assignment slug "${assignment}".`);
28490
28831
  }
28491
- const projectDir = resolve49(baseDir, options.project);
28492
- const projectMdPath = resolve49(projectDir, "project.md");
28832
+ const projectDir = resolve50(baseDir, options.project);
28833
+ const projectMdPath = resolve50(projectDir, "project.md");
28493
28834
  if (!await fileExists(projectDir) || !await fileExists(projectMdPath)) {
28494
28835
  throw new Error(`Project "${options.project}" not found at ${projectDir}.`);
28495
28836
  }
@@ -28540,17 +28881,17 @@ init_facts();
28540
28881
  init_git_worktree();
28541
28882
  init_recompute();
28542
28883
  init_event_emit();
28543
- import { readFile as readFile32 } from "fs/promises";
28544
- import { resolve as resolve50, basename as basename6 } from "path";
28884
+ import { readFile as readFile33 } from "fs/promises";
28885
+ import { resolve as resolve51, basename as basename6 } from "path";
28545
28886
  async function resolveTarget(assignment, options) {
28546
28887
  const config = await readConfig();
28547
28888
  const baseDir = options.dir ? expandHome(options.dir) : config.defaultProjectDir;
28548
28889
  if (options.project) {
28549
28890
  if (!isValidSlug(options.project)) throw new Error(`Invalid project slug "${options.project}".`);
28550
28891
  if (!isValidSlug(assignment)) throw new Error(`Invalid assignment slug "${assignment}".`);
28551
- const projectDir = resolve50(baseDir, options.project);
28552
- const assignmentDir = resolve50(projectDir, "assignments", assignment);
28553
- const assignmentPath = resolve50(assignmentDir, "assignment.md");
28892
+ const projectDir = resolve51(baseDir, options.project);
28893
+ const assignmentDir = resolve51(projectDir, "assignments", assignment);
28894
+ const assignmentPath = resolve51(assignmentDir, "assignment.md");
28554
28895
  if (!await fileExists(assignmentPath)) {
28555
28896
  throw new Error(`Assignment "${assignment}" not found at ${assignmentPath}.`);
28556
28897
  }
@@ -28562,14 +28903,14 @@ async function resolveTarget(assignment, options) {
28562
28903
  }
28563
28904
  return {
28564
28905
  assignmentDir: resolved.assignmentDir,
28565
- assignmentPath: resolve50(resolved.assignmentDir, "assignment.md"),
28566
- projectDir: resolved.standalone ? null : resolve50(resolved.assignmentDir, "..", "..")
28906
+ assignmentPath: resolve51(resolved.assignmentDir, "assignment.md"),
28907
+ projectDir: resolved.standalone ? null : resolve51(resolved.assignmentDir, "..", "..")
28567
28908
  };
28568
28909
  }
28569
28910
  async function inferActor(options) {
28570
28911
  if (options.agent) return `agent:${options.agent}`;
28571
28912
  try {
28572
- const raw2 = await readFile32(resolve50(process.cwd(), ".syntaur", "context.json"), "utf-8");
28913
+ const raw2 = await readFile33(resolve51(process.cwd(), ".syntaur", "context.json"), "utf-8");
28573
28914
  const ctx = JSON.parse(raw2);
28574
28915
  if (ctx.sessionId) return `agent:${ctx.sessionId.slice(0, 8)}`;
28575
28916
  } catch {
@@ -28578,7 +28919,7 @@ async function inferActor(options) {
28578
28919
  }
28579
28920
  async function emitDeriveEvent(target, type, actor, details) {
28580
28921
  try {
28581
- const fm = parseAssignmentFrontmatter(await readFile32(target.assignmentPath, "utf-8"));
28922
+ const fm = parseAssignmentFrontmatter(await readFile33(target.assignmentPath, "utf-8"));
28582
28923
  emitEvent({
28583
28924
  assignmentId: fm.id,
28584
28925
  projectSlug: target.projectDir ? basename6(target.projectDir) : null,
@@ -28639,7 +28980,7 @@ async function planApproveCommand(assignment, options) {
28639
28980
  throw new Error("No plan file found (plan.md / plan-v*.md). Write a plan before approving.");
28640
28981
  }
28641
28982
  approvedFile = planFile;
28642
- const planContent = await readFile32(resolve50(target2.assignmentDir, planFile), "utf-8");
28983
+ const planContent = await readFile33(resolve51(target2.assignmentDir, planFile), "utf-8");
28643
28984
  return updatePlanApproval(content, {
28644
28985
  file: planFile,
28645
28986
  digest: planDigest(planContent),
@@ -28712,7 +29053,7 @@ async function attestCommand(assignment, fact, options) {
28712
29053
  "No plan file found (plan.md / plan-v*.md). Write a plan before attesting a binds:plan fact."
28713
29054
  );
28714
29055
  }
28715
- const planContent = await readFile32(resolve50(target2.assignmentDir, planFile), "utf-8");
29056
+ const planContent = await readFile33(resolve51(target2.assignmentDir, planFile), "utf-8");
28716
29057
  record.file = planFile;
28717
29058
  record.digest = planDigest(planContent);
28718
29059
  } else if (binds === "commit") {
@@ -28864,8 +29205,8 @@ init_frontmatter();
28864
29205
  init_timestamp();
28865
29206
  init_assignment_resolver();
28866
29207
  init_event_emit();
28867
- import { resolve as resolve51 } from "path";
28868
- import { readFile as readFile33, writeFile as writeFile9 } from "fs/promises";
29208
+ import { resolve as resolve52 } from "path";
29209
+ import { readFile as readFile34, writeFile as writeFile9 } from "fs/promises";
28869
29210
  async function resolveTarget2(target, options) {
28870
29211
  const config = await readConfig();
28871
29212
  const baseDir = options.dir ? expandHome(options.dir) : config.defaultProjectDir;
@@ -28876,7 +29217,7 @@ async function resolveTarget2(target, options) {
28876
29217
  if (!isValidSlug(target)) {
28877
29218
  throw new Error(`Invalid assignment slug "${target}".`);
28878
29219
  }
28879
- const assignmentMd = resolve51(baseDir, options.project, "assignments", target, "assignment.md");
29220
+ const assignmentMd = resolve52(baseDir, options.project, "assignments", target, "assignment.md");
28880
29221
  if (!await fileExists(assignmentMd)) {
28881
29222
  throw new Error(`Assignment "${target}" not found in project "${options.project}".`);
28882
29223
  }
@@ -28886,18 +29227,18 @@ async function resolveTarget2(target, options) {
28886
29227
  if (resolved) {
28887
29228
  return {
28888
29229
  kind: "assignment",
28889
- filePath: resolve51(resolved.assignmentDir, "assignment.md"),
29230
+ filePath: resolve52(resolved.assignmentDir, "assignment.md"),
28890
29231
  label: resolved.projectSlug ? `assignment "${resolved.projectSlug}/${resolved.assignmentSlug}"` : `assignment "${target}"`
28891
29232
  };
28892
29233
  }
28893
- const projectMd = resolve51(baseDir, target, "project.md");
29234
+ const projectMd = resolve52(baseDir, target, "project.md");
28894
29235
  if (await fileExists(projectMd)) {
28895
29236
  return { kind: "project", filePath: projectMd, label: `project "${target}"` };
28896
29237
  }
28897
29238
  return null;
28898
29239
  }
28899
29240
  async function writeArchiveState(filePath, archived, reason) {
28900
- const content = await readFile33(filePath, "utf-8");
29241
+ const content = await readFile34(filePath, "utf-8");
28901
29242
  const updated = updateAssignmentFile(content, {
28902
29243
  archived,
28903
29244
  archivedAt: archived ? nowTimestamp() : null,
@@ -28909,7 +29250,7 @@ async function writeArchiveState(filePath, archived, reason) {
28909
29250
  async function emitArchiveEvent(resolved, type, reason) {
28910
29251
  if (resolved.kind !== "assignment") return;
28911
29252
  try {
28912
- const fm = parseAssignmentFrontmatter(await readFile33(resolved.filePath, "utf-8"));
29253
+ const fm = parseAssignmentFrontmatter(await readFile34(resolved.filePath, "utf-8"));
28913
29254
  emitEvent({
28914
29255
  assignmentId: fm.id,
28915
29256
  projectSlug: fm.project,
@@ -28979,8 +29320,8 @@ init_config2();
28979
29320
  init_frontmatter();
28980
29321
  init_timestamp();
28981
29322
  init_event_emit();
28982
- import { resolve as resolve52 } from "path";
28983
- import { readdir as readdir20, readFile as readFile34 } from "fs/promises";
29323
+ import { resolve as resolve53 } from "path";
29324
+ import { readdir as readdir20, readFile as readFile35 } from "fs/promises";
28984
29325
  var PROMOTABLE_STATUSES = /* @__PURE__ */ new Set(["pending"]);
28985
29326
  function objectiveIsFleshedOut(content) {
28986
29327
  const match = content.match(/##\s+Objective\s*\n([\s\S]*?)(?=\n##\s+|$)/);
@@ -29002,11 +29343,11 @@ async function collectCandidates(baseDirs) {
29002
29343
  for (const m of projects) {
29003
29344
  if (!m.isDirectory()) continue;
29004
29345
  if (m.name.startsWith(".") || m.name.startsWith("_")) continue;
29005
- const directAssignmentMd = resolve52(baseDir, m.name, "assignment.md");
29346
+ const directAssignmentMd = resolve53(baseDir, m.name, "assignment.md");
29006
29347
  if (await fileExists(directAssignmentMd)) {
29007
29348
  const fm = await parseSafe(directAssignmentMd);
29008
29349
  if (fm && PROMOTABLE_STATUSES.has(fm.status)) {
29009
- const content = await readFile34(directAssignmentMd, "utf-8");
29350
+ const content = await readFile35(directAssignmentMd, "utf-8");
29010
29351
  if (objectiveIsFleshedOut(content) && hasAcceptanceCriteria(content)) {
29011
29352
  candidates.push({
29012
29353
  projectSlug: null,
@@ -29019,17 +29360,17 @@ async function collectCandidates(baseDirs) {
29019
29360
  }
29020
29361
  continue;
29021
29362
  }
29022
- const assignmentsDir2 = resolve52(baseDir, m.name, "assignments");
29363
+ const assignmentsDir2 = resolve53(baseDir, m.name, "assignments");
29023
29364
  if (!await fileExists(assignmentsDir2)) continue;
29024
29365
  const entries = await readdir20(assignmentsDir2, { withFileTypes: true });
29025
29366
  for (const a of entries) {
29026
29367
  if (!a.isDirectory()) continue;
29027
29368
  if (a.name.startsWith(".") || a.name.startsWith("_")) continue;
29028
- const assignmentMd = resolve52(assignmentsDir2, a.name, "assignment.md");
29369
+ const assignmentMd = resolve53(assignmentsDir2, a.name, "assignment.md");
29029
29370
  if (!await fileExists(assignmentMd)) continue;
29030
29371
  const fm = await parseSafe(assignmentMd);
29031
29372
  if (!fm || !PROMOTABLE_STATUSES.has(fm.status)) continue;
29032
- const content = await readFile34(assignmentMd, "utf-8");
29373
+ const content = await readFile35(assignmentMd, "utf-8");
29033
29374
  if (!objectiveIsFleshedOut(content)) continue;
29034
29375
  if (!hasAcceptanceCriteria(content)) continue;
29035
29376
  candidates.push({
@@ -29046,7 +29387,7 @@ async function collectCandidates(baseDirs) {
29046
29387
  }
29047
29388
  async function parseSafe(path) {
29048
29389
  try {
29049
- const content = await readFile34(path, "utf-8");
29390
+ const content = await readFile35(path, "utf-8");
29050
29391
  return parseAssignmentFrontmatter(content);
29051
29392
  } catch {
29052
29393
  return null;
@@ -29076,7 +29417,7 @@ async function migrateStatusesCommand(options) {
29076
29417
  let migrated = 0;
29077
29418
  await withSuppressedEvents(async () => {
29078
29419
  for (const c2 of candidates) {
29079
- const content = await readFile34(c2.assignmentMd, "utf-8");
29420
+ const content = await readFile35(c2.assignmentMd, "utf-8");
29080
29421
  const updated = appendStatusHistoryEntry(
29081
29422
  updateAssignmentFile(content, {
29082
29423
  status: c2.toStatus,
@@ -29098,11 +29439,11 @@ init_config2();
29098
29439
  init_frontmatter();
29099
29440
  init_event_emit();
29100
29441
  init_types();
29101
- import { resolve as resolve53 } from "path";
29102
- import { readdir as readdir21, readFile as readFile35 } from "fs/promises";
29442
+ import { resolve as resolve54 } from "path";
29443
+ import { readdir as readdir21, readFile as readFile36 } from "fs/promises";
29103
29444
  async function parseSafe2(path) {
29104
29445
  try {
29105
- return parseAssignmentFrontmatter(await readFile35(path, "utf-8"));
29446
+ return parseAssignmentFrontmatter(await readFile36(path, "utf-8"));
29106
29447
  } catch {
29107
29448
  return null;
29108
29449
  }
@@ -29129,7 +29470,7 @@ async function collectTargets(baseDirs, terminalStatuses3) {
29129
29470
  for (const m of entries) {
29130
29471
  if (!m.isDirectory()) continue;
29131
29472
  if (m.name.startsWith(".") || m.name.startsWith("_")) continue;
29132
- const directAssignmentMd = resolve53(baseDir, m.name, "assignment.md");
29473
+ const directAssignmentMd = resolve54(baseDir, m.name, "assignment.md");
29133
29474
  if (await fileExists(directAssignmentMd)) {
29134
29475
  if (seen.has(directAssignmentMd)) continue;
29135
29476
  const fm = await parseSafe2(directAssignmentMd);
@@ -29144,13 +29485,13 @@ async function collectTargets(baseDirs, terminalStatuses3) {
29144
29485
  }
29145
29486
  continue;
29146
29487
  }
29147
- const assignmentsBase = resolve53(baseDir, m.name, "assignments");
29488
+ const assignmentsBase = resolve54(baseDir, m.name, "assignments");
29148
29489
  if (!await fileExists(assignmentsBase)) continue;
29149
29490
  const slugs = await readdir21(assignmentsBase, { withFileTypes: true });
29150
29491
  for (const a of slugs) {
29151
29492
  if (!a.isDirectory()) continue;
29152
29493
  if (a.name.startsWith(".") || a.name.startsWith("_")) continue;
29153
- const assignmentMd = resolve53(assignmentsBase, a.name, "assignment.md");
29494
+ const assignmentMd = resolve54(assignmentsBase, a.name, "assignment.md");
29154
29495
  if (!await fileExists(assignmentMd)) continue;
29155
29496
  if (seen.has(assignmentMd)) continue;
29156
29497
  const fm = await parseSafe2(assignmentMd);
@@ -29194,7 +29535,7 @@ async function migrateStatusHistoryCommand(options) {
29194
29535
  await withSuppressedEvents(async () => {
29195
29536
  for (const t of targets) {
29196
29537
  try {
29197
- const content = await readFile35(t.assignmentMd, "utf-8");
29538
+ const content = await readFile36(t.assignmentMd, "utf-8");
29198
29539
  if (parseAssignmentFrontmatter(content).statusHistory.length > 0) continue;
29199
29540
  const seededContent = appendStatusHistoryEntry(content, {
29200
29541
  at: t.seedAt,
@@ -29222,11 +29563,11 @@ init_fs();
29222
29563
  init_config2();
29223
29564
  init_parser();
29224
29565
  init_events_db();
29225
- import { resolve as resolve54 } from "path";
29226
- import { readdir as readdir22, readFile as readFile36 } from "fs/promises";
29566
+ import { resolve as resolve55 } from "path";
29567
+ import { readdir as readdir22, readFile as readFile37 } from "fs/promises";
29227
29568
  async function parseSafe3(path) {
29228
29569
  try {
29229
- return parseAssignmentFull(await readFile36(path, "utf-8"));
29570
+ return parseAssignmentFull(await readFile37(path, "utf-8"));
29230
29571
  } catch {
29231
29572
  return null;
29232
29573
  }
@@ -29263,7 +29604,7 @@ async function collectTargets2(baseDirs) {
29263
29604
  for (const m of entries) {
29264
29605
  if (!m.isDirectory()) continue;
29265
29606
  if (m.name.startsWith(".") || m.name.startsWith("_")) continue;
29266
- const directAssignmentMd = resolve54(baseDir, m.name, "assignment.md");
29607
+ const directAssignmentMd = resolve55(baseDir, m.name, "assignment.md");
29267
29608
  if (await fileExists(directAssignmentMd)) {
29268
29609
  if (seen.has(directAssignmentMd)) continue;
29269
29610
  seen.add(directAssignmentMd);
@@ -29281,13 +29622,13 @@ async function collectTargets2(baseDirs) {
29281
29622
  }
29282
29623
  continue;
29283
29624
  }
29284
- const assignmentsBase = resolve54(baseDir, m.name, "assignments");
29625
+ const assignmentsBase = resolve55(baseDir, m.name, "assignments");
29285
29626
  if (!await fileExists(assignmentsBase)) continue;
29286
29627
  const slugs = await readdir22(assignmentsBase, { withFileTypes: true });
29287
29628
  for (const a of slugs) {
29288
29629
  if (!a.isDirectory()) continue;
29289
29630
  if (a.name.startsWith(".") || a.name.startsWith("_")) continue;
29290
- const assignmentMd = resolve54(assignmentsBase, a.name, "assignment.md");
29631
+ const assignmentMd = resolve55(assignmentsBase, a.name, "assignment.md");
29291
29632
  if (!await fileExists(assignmentMd)) continue;
29292
29633
  if (seen.has(assignmentMd)) continue;
29293
29634
  seen.add(assignmentMd);
@@ -29368,8 +29709,8 @@ init_frontmatter();
29368
29709
  init_facts();
29369
29710
  init_derive();
29370
29711
  init_recompute();
29371
- import { readdir as readdir23, readFile as readFile37 } from "fs/promises";
29372
- import { resolve as resolve55 } from "path";
29712
+ import { readdir as readdir23, readFile as readFile38 } from "fs/promises";
29713
+ import { resolve as resolve56 } from "path";
29373
29714
  var IMPLEMENTATION_STATUSES = /* @__PURE__ */ new Set(["in_progress", "review", "code_review"]);
29374
29715
  var REVIEW_STATUSES = /* @__PURE__ */ new Set(["review", "code_review"]);
29375
29716
  async function listTargets(projectsDir2, standaloneDir) {
@@ -29380,15 +29721,15 @@ async function listTargets(projectsDir2, standaloneDir) {
29380
29721
  } catch {
29381
29722
  }
29382
29723
  for (const project of projects) {
29383
- const projectDir = resolve55(projectsDir2, project);
29724
+ const projectDir = resolve56(projectsDir2, project);
29384
29725
  let slugs = [];
29385
29726
  try {
29386
- slugs = await readdir23(resolve55(projectDir, "assignments"));
29727
+ slugs = await readdir23(resolve56(projectDir, "assignments"));
29387
29728
  } catch {
29388
29729
  continue;
29389
29730
  }
29390
29731
  for (const slug of slugs) {
29391
- const path = resolve55(projectDir, "assignments", slug, "assignment.md");
29732
+ const path = resolve56(projectDir, "assignments", slug, "assignment.md");
29392
29733
  if (await fileExists(path)) targets.push({ path, projectDir, ref: `${project}/${slug}` });
29393
29734
  }
29394
29735
  }
@@ -29398,7 +29739,7 @@ async function listTargets(projectsDir2, standaloneDir) {
29398
29739
  } catch {
29399
29740
  }
29400
29741
  for (const id of ids) {
29401
- const path = resolve55(standaloneDir, id, "assignment.md");
29742
+ const path = resolve56(standaloneDir, id, "assignment.md");
29402
29743
  if (await fileExists(path)) targets.push({ path, projectDir: null, ref: id });
29403
29744
  }
29404
29745
  return targets;
@@ -29453,7 +29794,7 @@ async function migrateDeriveCommand(options) {
29453
29794
  for (const target of targets) {
29454
29795
  let content;
29455
29796
  try {
29456
- content = await readFile37(target.path, "utf-8");
29797
+ content = await readFile38(target.path, "utf-8");
29457
29798
  } catch {
29458
29799
  continue;
29459
29800
  }
@@ -29468,7 +29809,7 @@ async function migrateDeriveCommand(options) {
29468
29809
  const seededFm = parseAssignmentFrontmatter(seededContent);
29469
29810
  const body = seededContent.replace(/^---\n[\s\S]*?\n---/, "");
29470
29811
  const facts = await computeFacts({
29471
- assignmentDir: resolve55(target.path, ".."),
29812
+ assignmentDir: resolve56(target.path, ".."),
29472
29813
  frontmatter: seededFm,
29473
29814
  body,
29474
29815
  projectDir: target.projectDir,
@@ -29528,7 +29869,7 @@ async function migrateDeriveCommand(options) {
29528
29869
  }
29529
29870
 
29530
29871
  // src/commands/complete.ts
29531
- import { resolve as resolve56 } from "path";
29872
+ import { resolve as resolve57 } from "path";
29532
29873
  init_config2();
29533
29874
  init_paths();
29534
29875
  init_assignment_resolver();
@@ -29542,12 +29883,12 @@ async function completeCommand(assignment, options) {
29542
29883
  let projectDir;
29543
29884
  let changedSlug;
29544
29885
  if (options.project) {
29545
- projectDir = resolve56(baseDir, options.project);
29886
+ projectDir = resolve57(baseDir, options.project);
29546
29887
  changedSlug = assignment;
29547
29888
  } else {
29548
29889
  const resolved = await resolveAssignmentById(baseDir, assignmentsDir(), assignment);
29549
29890
  if (!resolved) return;
29550
- projectDir = resolved.standalone ? null : resolve56(resolved.assignmentDir, "..", "..");
29891
+ projectDir = resolved.standalone ? null : resolve57(resolved.assignmentDir, "..", "..");
29551
29892
  changedSlug = resolved.assignmentSlug;
29552
29893
  }
29553
29894
  if (projectDir) {
@@ -29578,7 +29919,7 @@ async function reviewCommand(assignment, options) {
29578
29919
  }
29579
29920
 
29580
29921
  // src/commands/fail.ts
29581
- import { resolve as resolve57 } from "path";
29922
+ import { resolve as resolve58 } from "path";
29582
29923
  init_config2();
29583
29924
  init_paths();
29584
29925
  init_assignment_resolver();
@@ -29592,12 +29933,12 @@ async function failCommand(assignment, options) {
29592
29933
  let projectDir;
29593
29934
  let changedSlug;
29594
29935
  if (options.project) {
29595
- projectDir = resolve57(baseDir, options.project);
29936
+ projectDir = resolve58(baseDir, options.project);
29596
29937
  changedSlug = assignment;
29597
29938
  } else {
29598
29939
  const resolved = await resolveAssignmentById(baseDir, assignmentsDir(), assignment);
29599
29940
  if (!resolved) return;
29600
- projectDir = resolved.standalone ? null : resolve57(resolved.assignmentDir, "..", "..");
29941
+ projectDir = resolved.standalone ? null : resolve58(resolved.assignmentDir, "..", "..");
29601
29942
  changedSlug = resolved.assignmentSlug;
29602
29943
  }
29603
29944
  if (projectDir) {
@@ -29613,7 +29954,7 @@ async function failCommand(assignment, options) {
29613
29954
  }
29614
29955
 
29615
29956
  // src/commands/reopen.ts
29616
- import { resolve as resolve58 } from "path";
29957
+ import { resolve as resolve59 } from "path";
29617
29958
  init_config2();
29618
29959
  init_paths();
29619
29960
  init_assignment_resolver();
@@ -29629,14 +29970,14 @@ async function reopenCommand(assignment, options) {
29629
29970
  let projectDir;
29630
29971
  let changedSlug;
29631
29972
  if (options.project) {
29632
- projectDir = resolve58(baseDir, options.project);
29633
- assignmentPath = resolve58(projectDir, "assignments", assignment, "assignment.md");
29973
+ projectDir = resolve59(baseDir, options.project);
29974
+ assignmentPath = resolve59(projectDir, "assignments", assignment, "assignment.md");
29634
29975
  changedSlug = assignment;
29635
29976
  } else {
29636
29977
  const resolved = await resolveAssignmentById(baseDir, assignmentsDir(), assignment);
29637
29978
  if (!resolved) return;
29638
- assignmentPath = resolve58(resolved.assignmentDir, "assignment.md");
29639
- projectDir = resolved.standalone ? null : resolve58(resolved.assignmentDir, "..", "..");
29979
+ assignmentPath = resolve59(resolved.assignmentDir, "assignment.md");
29980
+ projectDir = resolved.standalone ? null : resolve59(resolved.assignmentDir, "..", "..");
29640
29981
  changedSlug = resolved.assignmentSlug;
29641
29982
  }
29642
29983
  const derived = await recomputeAndWrite(assignmentPath, {
@@ -29670,7 +30011,7 @@ import {
29670
30011
  readdir as readdir24,
29671
30012
  symlink,
29672
30013
  lstat,
29673
- readFile as readFile38,
30014
+ readFile as readFile39,
29674
30015
  readlink,
29675
30016
  rename as rename9,
29676
30017
  rm as rm6,
@@ -29679,20 +30020,20 @@ import {
29679
30020
  } from "fs/promises";
29680
30021
  import { existsSync as existsSync4 } from "fs";
29681
30022
  import { homedir as homedir8 } from "os";
29682
- import { basename as basename7, dirname as dirname15, isAbsolute as isAbsolute7, relative as relative2, resolve as resolve60 } from "path";
30023
+ import { basename as basename7, dirname as dirname15, isAbsolute as isAbsolute7, relative as relative2, resolve as resolve61 } from "path";
29683
30024
 
29684
30025
  // src/utils/package-root.ts
29685
30026
  init_fs();
29686
- import { dirname as dirname14, resolve as resolve59 } from "path";
30027
+ import { dirname as dirname14, resolve as resolve60 } from "path";
29687
30028
  import { fileURLToPath as fileURLToPath4 } from "url";
29688
30029
  async function findPackageRoot(expectedRelativePath) {
29689
30030
  let currentDir = dirname14(fileURLToPath4(import.meta.url));
29690
30031
  while (true) {
29691
- const candidate = resolve59(currentDir, expectedRelativePath);
30032
+ const candidate = resolve60(currentDir, expectedRelativePath);
29692
30033
  if (await fileExists(candidate)) {
29693
30034
  return currentDir;
29694
30035
  }
29695
- const parentDir = resolve59(currentDir, "..");
30036
+ const parentDir = resolve60(currentDir, "..");
29696
30037
  if (parentDir === currentDir) {
29697
30038
  throw new Error(
29698
30039
  `Could not locate package root containing ${expectedRelativePath}.`
@@ -29713,25 +30054,25 @@ function getPluginManifestRelativePath(pluginKind) {
29713
30054
  }
29714
30055
  function getDefaultPluginTargetDir(pluginKind) {
29715
30056
  const home2 = homedir8();
29716
- return pluginKind === "claude" ? resolve60(home2, ".claude", "plugins", "syntaur") : resolve60(home2, "plugins", "syntaur");
30057
+ return pluginKind === "claude" ? resolve61(home2, ".claude", "plugins", "syntaur") : resolve61(home2, "plugins", "syntaur");
29717
30058
  }
29718
30059
  function getDefaultMarketplacePath() {
29719
- return resolve60(homedir8(), ".agents", "plugins", "marketplace.json");
30060
+ return resolve61(homedir8(), ".agents", "plugins", "marketplace.json");
29720
30061
  }
29721
30062
  function getClaudeMarketplacesRoot() {
29722
- return resolve60(homedir8(), ".claude", "plugins", "marketplaces");
30063
+ return resolve61(homedir8(), ".claude", "plugins", "marketplaces");
29723
30064
  }
29724
30065
  function getClaudeKnownMarketplacesPath() {
29725
- return resolve60(homedir8(), ".claude", "plugins", "known_marketplaces.json");
30066
+ return resolve61(homedir8(), ".claude", "plugins", "known_marketplaces.json");
29726
30067
  }
29727
30068
  function getClaudeInstalledPluginsPath() {
29728
- return resolve60(homedir8(), ".claude", "plugins", "installed_plugins.json");
30069
+ return resolve61(homedir8(), ".claude", "plugins", "installed_plugins.json");
29729
30070
  }
29730
30071
  function getInstallMarkerPath(targetDir) {
29731
- return resolve60(targetDir, INSTALL_MARKER_FILENAME);
30072
+ return resolve61(targetDir, INSTALL_MARKER_FILENAME);
29732
30073
  }
29733
30074
  async function readPackageManifest(packageRoot) {
29734
- const raw2 = await readFile38(resolve60(packageRoot, "package.json"), "utf-8");
30075
+ const raw2 = await readFile39(resolve61(packageRoot, "package.json"), "utf-8");
29735
30076
  return JSON.parse(raw2);
29736
30077
  }
29737
30078
  async function readJsonFileIfExists(pathValue) {
@@ -29739,7 +30080,7 @@ async function readJsonFileIfExists(pathValue) {
29739
30080
  return null;
29740
30081
  }
29741
30082
  try {
29742
- const raw2 = await readFile38(pathValue, "utf-8");
30083
+ const raw2 = await readFile39(pathValue, "utf-8");
29743
30084
  return JSON.parse(raw2);
29744
30085
  } catch {
29745
30086
  return null;
@@ -29747,15 +30088,15 @@ async function readJsonFileIfExists(pathValue) {
29747
30088
  }
29748
30089
  async function readClaudePluginManifest(pluginDir) {
29749
30090
  return await readJsonFileIfExists(
29750
- resolve60(pluginDir, ".claude-plugin", "plugin.json")
30091
+ resolve61(pluginDir, ".claude-plugin", "plugin.json")
29751
30092
  ) ?? {};
29752
30093
  }
29753
30094
  async function readPluginManifestName(targetDir, pluginKind) {
29754
- const manifestPath = resolve60(targetDir, getPluginManifestRelativePath(pluginKind));
30095
+ const manifestPath = resolve61(targetDir, getPluginManifestRelativePath(pluginKind));
29755
30096
  if (!await fileExists(manifestPath)) {
29756
30097
  return void 0;
29757
30098
  }
29758
- const raw2 = await readFile38(manifestPath, "utf-8");
30099
+ const raw2 = await readFile39(manifestPath, "utf-8");
29759
30100
  const parsed = JSON.parse(raw2);
29760
30101
  return parsed.name;
29761
30102
  }
@@ -29765,7 +30106,7 @@ async function readInstallMetadata(targetDir) {
29765
30106
  return null;
29766
30107
  }
29767
30108
  try {
29768
- const raw2 = await readFile38(markerPath, "utf-8");
30109
+ const raw2 = await readFile39(markerPath, "utf-8");
29769
30110
  return JSON.parse(raw2);
29770
30111
  } catch {
29771
30112
  return null;
@@ -29778,7 +30119,7 @@ async function getInstallStatus(targetDir, pluginKind) {
29778
30119
  const info = await lstat(targetDir);
29779
30120
  if (info.isSymbolicLink()) {
29780
30121
  const symlinkTarget = await readlink(targetDir);
29781
- const resolvedTarget = resolve60(dirname15(targetDir), symlinkTarget);
30122
+ const resolvedTarget = resolve61(dirname15(targetDir), symlinkTarget);
29782
30123
  const manifestName2 = await readPluginManifestName(resolvedTarget, pluginKind);
29783
30124
  return {
29784
30125
  exists: true,
@@ -29824,7 +30165,7 @@ async function installLink(paths) {
29824
30165
  await ensureDir(dirname15(paths.targetDir));
29825
30166
  await rm6(paths.targetDir, { recursive: true, force: true });
29826
30167
  await ensureDir(dirname15(paths.targetDir));
29827
- await symlink(resolve60(paths.sourceDir), paths.targetDir, "dir");
30168
+ await symlink(resolve61(paths.sourceDir), paths.targetDir, "dir");
29828
30169
  }
29829
30170
  async function removeInstallMarker(targetDir) {
29830
30171
  const markerPath = getInstallMarkerPath(targetDir);
@@ -29838,13 +30179,13 @@ function normalizeAbsoluteInstallPath(pathValue, label) {
29838
30179
  if (!isAbsolute7(expanded)) {
29839
30180
  throw new Error(`${label} must be an absolute path.`);
29840
30181
  }
29841
- return resolve60(expanded);
30182
+ return resolve61(expanded);
29842
30183
  }
29843
30184
  async function resolvePluginPaths(pluginKind, targetDir) {
29844
30185
  const packageRoot = await findPackageRoot(getPluginRelativePath(pluginKind));
29845
30186
  return {
29846
30187
  packageRoot,
29847
- sourceDir: resolve60(packageRoot, getPluginRelativePath(pluginKind)),
30188
+ sourceDir: resolve61(packageRoot, getPluginRelativePath(pluginKind)),
29848
30189
  targetDir: targetDir ?? getDefaultPluginTargetDir(pluginKind)
29849
30190
  };
29850
30191
  }
@@ -29888,7 +30229,7 @@ async function writeClaudeMarketplaceFile(manifestPath, marketplace) {
29888
30229
  }
29889
30230
  if (await fileExists(manifestPath)) {
29890
30231
  try {
29891
- const prev = await readFile38(manifestPath, "utf-8");
30232
+ const prev = await readFile39(manifestPath, "utf-8");
29892
30233
  JSON.parse(prev);
29893
30234
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
29894
30235
  await writeFile10(`${manifestPath}.bak-${stamp}`, prev, "utf-8");
@@ -29969,8 +30310,8 @@ async function listClaudeMarketplaceCandidates() {
29969
30310
  if (!entry.isDirectory()) {
29970
30311
  continue;
29971
30312
  }
29972
- const candidateRoot = resolve60(rootDir, entry.name);
29973
- const manifestPath = resolve60(candidateRoot, ".claude-plugin", "marketplace.json");
30313
+ const candidateRoot = resolve61(rootDir, entry.name);
30314
+ const manifestPath = resolve61(candidateRoot, ".claude-plugin", "marketplace.json");
29974
30315
  if (!await fileExists(manifestPath)) {
29975
30316
  continue;
29976
30317
  }
@@ -29997,11 +30338,11 @@ async function listClaudeMarketplaceCandidates() {
29997
30338
  if (!installLocation) {
29998
30339
  continue;
29999
30340
  }
30000
- const candidateRoot = resolve60(expandHome(installLocation));
30341
+ const candidateRoot = resolve61(expandHome(installLocation));
30001
30342
  if (seen.has(candidateRoot)) {
30002
30343
  continue;
30003
30344
  }
30004
- const manifestPath = resolve60(candidateRoot, ".claude-plugin", "marketplace.json");
30345
+ const manifestPath = resolve61(candidateRoot, ".claude-plugin", "marketplace.json");
30005
30346
  if (!await fileExists(manifestPath)) {
30006
30347
  continue;
30007
30348
  }
@@ -30029,14 +30370,14 @@ async function getPreferredClaudeMarketplace() {
30029
30370
  name: candidate.name,
30030
30371
  rootDir: candidate.rootDir,
30031
30372
  manifestPath: candidate.manifestPath,
30032
- targetDir: resolve60(candidate.rootDir, "plugins", "syntaur")
30373
+ targetDir: resolve61(candidate.rootDir, "plugins", "syntaur")
30033
30374
  };
30034
30375
  }
30035
30376
  async function registerKnownClaudeMarketplace(name, rootDir) {
30036
30377
  const manifestPath = getClaudeKnownMarketplacesPath();
30037
30378
  let existing = {};
30038
30379
  if (await fileExists(manifestPath)) {
30039
- const raw2 = await readFile38(manifestPath, "utf-8");
30380
+ const raw2 = await readFile39(manifestPath, "utf-8");
30040
30381
  try {
30041
30382
  const parsed = JSON.parse(raw2);
30042
30383
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
@@ -30063,7 +30404,7 @@ async function registerKnownClaudeMarketplace(name, rootDir) {
30063
30404
  existing[name].autoUpdate = true;
30064
30405
  await ensureDir(dirname15(manifestPath));
30065
30406
  if (await fileExists(manifestPath)) {
30066
- const prev = await readFile38(manifestPath, "utf-8");
30407
+ const prev = await readFile39(manifestPath, "utf-8");
30067
30408
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
30068
30409
  await writeFile10(`${manifestPath}.bak-${stamp}`, prev, "utf-8");
30069
30410
  }
@@ -30077,11 +30418,11 @@ async function ensureKnownClaudeMarketplaceForRoot(options) {
30077
30418
  return registerKnownClaudeMarketplace(options.name, options.rootDir);
30078
30419
  }
30079
30420
  async function setSyntaurPluginEnabled(options) {
30080
- const settingsPath = resolve60(homedir8(), ".claude", "settings.json");
30421
+ const settingsPath = resolve61(homedir8(), ".claude", "settings.json");
30081
30422
  const key = `syntaur@${options.marketplaceName}`;
30082
30423
  let parsed = {};
30083
30424
  if (await fileExists(settingsPath)) {
30084
- const raw2 = await readFile38(settingsPath, "utf-8");
30425
+ const raw2 = await readFile39(settingsPath, "utf-8");
30085
30426
  try {
30086
30427
  parsed = JSON.parse(raw2);
30087
30428
  } catch {
@@ -30100,7 +30441,7 @@ async function setSyntaurPluginEnabled(options) {
30100
30441
  await ensureDir(dirname15(settingsPath));
30101
30442
  if (await fileExists(settingsPath)) {
30102
30443
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
30103
- const prev = await readFile38(settingsPath, "utf-8");
30444
+ const prev = await readFile39(settingsPath, "utf-8");
30104
30445
  await writeFile10(`${settingsPath}.bak-${stamp}`, prev, "utf-8");
30105
30446
  }
30106
30447
  const tmpPath = `${settingsPath}.tmp`;
@@ -30114,9 +30455,9 @@ async function ensureClaudeUserMarketplace() {
30114
30455
  if (existing) {
30115
30456
  return existing;
30116
30457
  }
30117
- const rootDir = resolve60(getClaudeMarketplacesRoot(), "user-plugins");
30118
- const manifestPath = resolve60(rootDir, ".claude-plugin", "marketplace.json");
30119
- await ensureDir(resolve60(rootDir, "plugins"));
30458
+ const rootDir = resolve61(getClaudeMarketplacesRoot(), "user-plugins");
30459
+ const manifestPath = resolve61(rootDir, ".claude-plugin", "marketplace.json");
30460
+ await ensureDir(resolve61(rootDir, "plugins"));
30120
30461
  if (!await fileExists(manifestPath)) {
30121
30462
  const scaffold = {
30122
30463
  plugins: []
@@ -30135,7 +30476,7 @@ async function ensureClaudeUserMarketplace() {
30135
30476
  name: "user-plugins",
30136
30477
  rootDir,
30137
30478
  manifestPath,
30138
- targetDir: resolve60(rootDir, "plugins", "syntaur")
30479
+ targetDir: resolve61(rootDir, "plugins", "syntaur")
30139
30480
  };
30140
30481
  }
30141
30482
  async function detectClaudeMarketplaceForTarget(targetDir) {
@@ -30145,7 +30486,7 @@ async function detectClaudeMarketplaceForTarget(targetDir) {
30145
30486
  return null;
30146
30487
  }
30147
30488
  const rootDir = dirname15(pluginsDir);
30148
- const manifestPath = resolve60(rootDir, ".claude-plugin", "marketplace.json");
30489
+ const manifestPath = resolve61(rootDir, ".claude-plugin", "marketplace.json");
30149
30490
  if (!await fileExists(manifestPath)) {
30150
30491
  return null;
30151
30492
  }
@@ -30161,7 +30502,7 @@ async function detectClaudeMarketplaceForTarget(targetDir) {
30161
30502
  async function findManagedClaudeMarketplacePluginDir() {
30162
30503
  const marketplaces = await listClaudeMarketplaceCandidates();
30163
30504
  for (const marketplace of marketplaces) {
30164
- const targetDir = resolve60(marketplace.rootDir, "plugins", "syntaur");
30505
+ const targetDir = resolve61(marketplace.rootDir, "plugins", "syntaur");
30165
30506
  const status = await getInstallStatus(targetDir, "claude");
30166
30507
  if (status.exists && status.managed) {
30167
30508
  return targetDir;
@@ -30286,7 +30627,7 @@ async function installManagedPlugin(options) {
30286
30627
  `${paths.targetDir} already exists and is not a Syntaur-managed install. Remove it manually before installing Syntaur there.`
30287
30628
  );
30288
30629
  }
30289
- if (desiredMode === "link" && existing.exists && existing.installMode === "link" && existing.symlinkTarget === resolve60(paths.sourceDir) && !force) {
30630
+ if (desiredMode === "link" && existing.exists && existing.installMode === "link" && existing.symlinkTarget === resolve61(paths.sourceDir) && !force) {
30290
30631
  return {
30291
30632
  targetDir: paths.targetDir,
30292
30633
  sourceDir: paths.sourceDir,
@@ -30338,7 +30679,7 @@ async function readMarketplaceFile(marketplacePath) {
30338
30679
  plugins: []
30339
30680
  };
30340
30681
  }
30341
- const raw2 = await readFile38(marketplacePath, "utf-8");
30682
+ const raw2 = await readFile39(marketplacePath, "utf-8");
30342
30683
  const parsed = JSON.parse(raw2);
30343
30684
  return {
30344
30685
  name: parsed.name ?? "local",
@@ -30505,13 +30846,13 @@ async function recommendMarketplacePath() {
30505
30846
  return configuredOrManaged ?? getDefaultMarketplacePath();
30506
30847
  }
30507
30848
  async function isSyntaurDataInstalled() {
30508
- return fileExists(resolve60(syntaurRoot(), "config.md"));
30849
+ return fileExists(resolve61(syntaurRoot(), "config.md"));
30509
30850
  }
30510
30851
  async function removeSyntaurData() {
30511
30852
  await rm6(syntaurRoot(), { recursive: true, force: true });
30512
30853
  }
30513
30854
  async function getConfiguredProjectDir() {
30514
- if (!await fileExists(resolve60(syntaurRoot(), "config.md"))) {
30855
+ if (!await fileExists(resolve61(syntaurRoot(), "config.md"))) {
30515
30856
  return null;
30516
30857
  }
30517
30858
  return (await readConfig()).defaultProjectDir;
@@ -30580,24 +30921,24 @@ async function textPrompt(question, defaultValue) {
30580
30921
 
30581
30922
  // src/utils/install-skills.ts
30582
30923
  init_fs();
30583
- import { readFile as readFile40, readdir as readdir25, mkdir as mkdir7, copyFile, rm as rm7, lstat as lstat2 } from "fs/promises";
30584
- import { resolve as resolve62, relative as relative3, join as join11 } from "path";
30924
+ import { readFile as readFile41, readdir as readdir25, mkdir as mkdir7, copyFile, rm as rm7, lstat as lstat2 } from "fs/promises";
30925
+ import { resolve as resolve63, relative as relative3, join as join11 } from "path";
30585
30926
  import { homedir as homedir10 } from "os";
30586
30927
 
30587
30928
  // src/utils/plugin-state.ts
30588
30929
  init_fs();
30589
- import { readFile as readFile39 } from "fs/promises";
30590
- import { resolve as resolve61 } from "path";
30930
+ import { readFile as readFile40 } from "fs/promises";
30931
+ import { resolve as resolve62 } from "path";
30591
30932
  import { homedir as homedir9 } from "os";
30592
30933
  function settingsPathFor(agent) {
30593
- if (agent === "claude") return resolve61(homedir9(), ".claude", "settings.json");
30934
+ if (agent === "claude") return resolve62(homedir9(), ".claude", "settings.json");
30594
30935
  return null;
30595
30936
  }
30596
30937
  async function readJsonOrNull(path) {
30597
30938
  if (!path) return null;
30598
30939
  if (!await fileExists(path)) return null;
30599
30940
  try {
30600
- const raw2 = await readFile39(path, "utf-8");
30941
+ const raw2 = await readFile40(path, "utf-8");
30601
30942
  return JSON.parse(raw2);
30602
30943
  } catch {
30603
30944
  return null;
@@ -30647,11 +30988,11 @@ var KNOWN_SKILL_NAMES = [
30647
30988
  var KNOWN_SKILLS = KNOWN_SKILL_NAMES;
30648
30989
  async function getSkillsDir() {
30649
30990
  const packageRoot = await findPackageRoot("skills");
30650
- return resolve62(packageRoot, "skills");
30991
+ return resolve63(packageRoot, "skills");
30651
30992
  }
30652
30993
  function defaultSkillTargetDir(target) {
30653
- if (target === "claude") return resolve62(homedir10(), ".claude", "skills");
30654
- return resolve62(homedir10(), ".codex", "skills");
30994
+ if (target === "claude") return resolve63(homedir10(), ".claude", "skills");
30995
+ return resolve63(homedir10(), ".codex", "skills");
30655
30996
  }
30656
30997
  async function walkFiles(root) {
30657
30998
  const out = [];
@@ -30671,7 +31012,7 @@ async function walkFiles(root) {
30671
31012
  }
30672
31013
  async function filesEqual(a, b) {
30673
31014
  try {
30674
- const [ba, bb] = await Promise.all([readFile40(a), readFile40(b)]);
31015
+ const [ba, bb] = await Promise.all([readFile41(a), readFile41(b)]);
30675
31016
  if (ba.length !== bb.length) return false;
30676
31017
  return ba.equals(bb);
30677
31018
  } catch {
@@ -30811,7 +31152,7 @@ async function uninstallSkills(options) {
30811
31152
  if (await isSymlink(destDir)) continue;
30812
31153
  const skillMd = join11(destDir, "SKILL.md");
30813
31154
  if (!await fileExists(skillMd)) continue;
30814
- const content = await readFile40(skillMd, "utf-8").catch(() => "");
31155
+ const content = await readFile41(skillMd, "utf-8").catch(() => "");
30815
31156
  const match = content.match(/^name:\s*(\S+)\s*$/m);
30816
31157
  if (!match || match[1] !== skill) continue;
30817
31158
  await rm7(destDir, { recursive: true, force: true });
@@ -31006,20 +31347,20 @@ import { realpathSync as realpathSync2 } from "fs";
31006
31347
  init_paths();
31007
31348
  init_fs();
31008
31349
  import { fileURLToPath as fileURLToPath6 } from "url";
31009
- import { readFile as readFile42 } from "fs/promises";
31010
- import { dirname as dirname17, join as join13, resolve as resolve63 } from "path";
31350
+ import { readFile as readFile43 } from "fs/promises";
31351
+ import { dirname as dirname17, join as join13, resolve as resolve64 } from "path";
31011
31352
  import { spawn as spawn6 } from "child_process";
31012
31353
  import { createInterface as createInterface2 } from "readline/promises";
31013
31354
 
31014
31355
  // src/utils/version.ts
31015
31356
  import { fileURLToPath as fileURLToPath5 } from "url";
31016
- import { readFile as readFile41 } from "fs/promises";
31357
+ import { readFile as readFile42 } from "fs/promises";
31017
31358
  import { dirname as dirname16, join as join12 } from "path";
31018
31359
  async function readPackageVersion(scriptUrl) {
31019
31360
  try {
31020
31361
  const scriptPath = fileURLToPath5(scriptUrl);
31021
31362
  const pkgRoot = dirname16(dirname16(scriptPath));
31022
- const raw2 = await readFile41(join12(pkgRoot, "package.json"), "utf-8");
31363
+ const raw2 = await readFile42(join12(pkgRoot, "package.json"), "utf-8");
31023
31364
  const parsed = JSON.parse(raw2);
31024
31365
  return typeof parsed.version === "string" ? parsed.version : null;
31025
31366
  } catch {
@@ -31028,7 +31369,7 @@ async function readPackageVersion(scriptUrl) {
31028
31369
  }
31029
31370
 
31030
31371
  // src/utils/npx-prompt.ts
31031
- var STATE_FILE = resolve63(syntaurRoot(), "npx-install.json");
31372
+ var STATE_FILE = resolve64(syntaurRoot(), "npx-install.json");
31032
31373
  var META_ARGS2 = /* @__PURE__ */ new Set(["-h", "--help", "-V", "--version", "help"]);
31033
31374
  var GLOBAL_VERSION_TIMEOUT_MS = 2e3;
31034
31375
  function isRunningViaNpx(scriptUrl) {
@@ -31049,7 +31390,7 @@ function isRunningViaNpx(scriptUrl) {
31049
31390
  async function readState() {
31050
31391
  if (!await fileExists(STATE_FILE)) return null;
31051
31392
  try {
31052
- const raw2 = await readFile42(STATE_FILE, "utf-8");
31393
+ const raw2 = await readFile43(STATE_FILE, "utf-8");
31053
31394
  return JSON.parse(raw2);
31054
31395
  } catch {
31055
31396
  return null;
@@ -31108,7 +31449,7 @@ async function readGlobalVersion() {
31108
31449
  try {
31109
31450
  const manifestPath = join13(rootPath, "syntaur", "package.json");
31110
31451
  if (!await fileExists(manifestPath)) return null;
31111
- const raw2 = await readFile42(manifestPath, "utf-8");
31452
+ const raw2 = await readFile43(manifestPath, "utf-8");
31112
31453
  const parsed = JSON.parse(raw2);
31113
31454
  return typeof parsed.version === "string" ? parsed.version : null;
31114
31455
  } catch {
@@ -31466,16 +31807,16 @@ async function refreshPluginSkills(options, pm, runner, getManagedDir, resolveFr
31466
31807
  // src/commands/install-statusline.ts
31467
31808
  init_paths();
31468
31809
  init_fs();
31469
- import { readFile as readFile44, writeFile as writeFile12, copyFile as copyFile2, rm as rm8, stat as stat7, symlink as symlink2, unlink as unlink11, lstat as lstat3 } from "fs/promises";
31470
- import { resolve as resolve65, dirname as dirname19 } from "path";
31810
+ import { readFile as readFile45, writeFile as writeFile12, copyFile as copyFile2, rm as rm8, stat as stat7, symlink as symlink2, unlink as unlink11, lstat as lstat3 } from "fs/promises";
31811
+ import { resolve as resolve66, dirname as dirname19 } from "path";
31471
31812
  import { homedir as homedir12 } from "os";
31472
31813
  import { fileURLToPath as fileURLToPath8 } from "url";
31473
31814
 
31474
31815
  // src/commands/configure-statusline.ts
31475
31816
  init_paths();
31476
31817
  init_fs();
31477
- import { readFile as readFile43, writeFile as writeFile11 } from "fs/promises";
31478
- import { resolve as resolve64, dirname as dirname18 } from "path";
31818
+ import { readFile as readFile44, writeFile as writeFile11 } from "fs/promises";
31819
+ import { resolve as resolve65, dirname as dirname18 } from "path";
31479
31820
  import { spawnSync as spawnSync5 } from "child_process";
31480
31821
  import { checkbox, input as input2, confirm } from "@inquirer/prompts";
31481
31822
  var AVAILABLE_SEGMENTS = [
@@ -31496,12 +31837,12 @@ var PRESETS = {
31496
31837
  tracker: { segments: ["git", "assignment", "external", "session"], separator: " \xB7 " }
31497
31838
  };
31498
31839
  function getConfigPath(installRoot) {
31499
- return resolve64(installRoot, "statusline.config.json");
31840
+ return resolve65(installRoot, "statusline.config.json");
31500
31841
  }
31501
31842
  async function readConfig2(path) {
31502
31843
  if (!await fileExists(path)) return null;
31503
31844
  try {
31504
- const raw2 = await readFile43(path, "utf-8");
31845
+ const raw2 = await readFile44(path, "utf-8");
31505
31846
  const parsed = JSON.parse(raw2);
31506
31847
  if (!parsed || typeof parsed !== "object") return null;
31507
31848
  const segments = Array.isArray(parsed.segments) ? parsed.segments.filter(isSegmentName) : [];
@@ -31654,7 +31995,7 @@ async function configureStatuslineCommand(options = {}) {
31654
31995
  console.log(` segments: ${config.segments.join(", ")}`);
31655
31996
  console.log(` separator: ${JSON.stringify(config.separator)}`);
31656
31997
  if (config.wrap) console.log(` wrap: ${config.wrap}`);
31657
- const script = options.statuslineScript ?? resolve64(installRoot, "statusline.sh");
31998
+ const script = options.statuslineScript ?? resolve65(installRoot, "statusline.sh");
31658
31999
  if (await fileExists(script)) {
31659
32000
  console.log("");
31660
32001
  console.log("Live preview:");
@@ -31685,11 +32026,11 @@ async function writeDefaultConfigIfMissing(installRoot) {
31685
32026
  // src/commands/install-statusline.ts
31686
32027
  function getPackageStatuslineSource() {
31687
32028
  const here = dirname19(fileURLToPath8(import.meta.url));
31688
- return resolve65(here, "..", "statusline", "statusline.sh");
32029
+ return resolve66(here, "..", "statusline", "statusline.sh");
31689
32030
  }
31690
32031
  async function readSettingsJson(settingsPath) {
31691
32032
  if (!await fileExists(settingsPath)) return {};
31692
- const raw2 = await readFile44(settingsPath, "utf-8");
32033
+ const raw2 = await readFile45(settingsPath, "utf-8");
31693
32034
  if (raw2.trim() === "") return {};
31694
32035
  try {
31695
32036
  const parsed = JSON.parse(raw2);
@@ -31769,12 +32110,12 @@ async function installScript(sourceScript, destScript, link) {
31769
32110
  }
31770
32111
  async function installStatuslineCommand(options = {}) {
31771
32112
  const mode = options.mode ?? "ask";
31772
- const settingsPath = options.settingsPath ?? resolve65(homedir12(), ".claude", "settings.json");
32113
+ const settingsPath = options.settingsPath ?? resolve66(homedir12(), ".claude", "settings.json");
31773
32114
  const installRoot = options.installRoot ?? syntaurRoot();
31774
32115
  const sourceScript = options.sourceScript ?? getPackageStatuslineSource();
31775
- const destScript = resolve65(installRoot, "statusline.sh");
31776
- const confPath = resolve65(installRoot, "statusline.conf");
31777
- const backupPath = resolve65(installRoot, "statusline.backup.json");
32116
+ const destScript = resolve66(installRoot, "statusline.sh");
32117
+ const confPath = resolve66(installRoot, "statusline.conf");
32118
+ const backupPath = resolve66(installRoot, "statusline.backup.json");
31778
32119
  if (!await fileExists(sourceScript)) {
31779
32120
  throw new Error(
31780
32121
  `Statusline source script not found at ${sourceScript}. Try re-installing syntaur (npm install -g syntaur) or pass --source-script explicitly.`
@@ -31810,7 +32151,7 @@ async function installStatuslineCommand(options = {}) {
31810
32151
  if (parsed) {
31811
32152
  wrapTarget = parsed;
31812
32153
  } else {
31813
- const wrapperPath = resolve65(installRoot, "statusline-wrapped.sh");
32154
+ const wrapperPath = resolve66(installRoot, "statusline-wrapped.sh");
31814
32155
  const wrapperBody = `#!/usr/bin/env bash
31815
32156
  # Auto-generated by syntaur install-statusline.
31816
32157
  # Executes the previously configured statusLine command.
@@ -31865,19 +32206,19 @@ async function chmodExec(path) {
31865
32206
  }
31866
32207
  }
31867
32208
  async function uninstallStatuslineCommand(options = {}) {
31868
- const settingsPath = options.settingsPath ?? resolve65(homedir12(), ".claude", "settings.json");
32209
+ const settingsPath = options.settingsPath ?? resolve66(homedir12(), ".claude", "settings.json");
31869
32210
  const installRoot = options.installRoot ?? syntaurRoot();
31870
- const destScript = resolve65(installRoot, "statusline.sh");
31871
- const confPath = resolve65(installRoot, "statusline.conf");
31872
- const backupPath = resolve65(installRoot, "statusline.backup.json");
31873
- const wrapperPath = resolve65(installRoot, "statusline-wrapped.sh");
32211
+ const destScript = resolve66(installRoot, "statusline.sh");
32212
+ const confPath = resolve66(installRoot, "statusline.conf");
32213
+ const backupPath = resolve66(installRoot, "statusline.backup.json");
32214
+ const wrapperPath = resolve66(installRoot, "statusline-wrapped.sh");
31874
32215
  const settings = await readSettingsJson(settingsPath);
31875
32216
  const existing = extractExistingCommand(settings);
31876
32217
  const ourCommand = `bash ${destScript}`;
31877
32218
  let restored = null;
31878
32219
  if (await fileExists(backupPath)) {
31879
32220
  try {
31880
- const raw2 = await readFile44(backupPath, "utf-8");
32221
+ const raw2 = await readFile45(backupPath, "utf-8");
31881
32222
  const parsed = JSON.parse(raw2);
31882
32223
  const prev = parsed?.previousStatusLine;
31883
32224
  if (prev && typeof prev === "object" && typeof prev.command === "string") {
@@ -31898,7 +32239,7 @@ async function uninstallStatuslineCommand(options = {}) {
31898
32239
  await writeSettingsJson(settingsPath, settings);
31899
32240
  }
31900
32241
  if (!options.keepScript) {
31901
- const configPath2 = resolve65(installRoot, "statusline.config.json");
32242
+ const configPath2 = resolve66(installRoot, "statusline.config.json");
31902
32243
  for (const path of [destScript, confPath, backupPath, wrapperPath, configPath2]) {
31903
32244
  try {
31904
32245
  await rm8(path, { force: true });
@@ -32058,8 +32399,8 @@ init_config2();
32058
32399
  // src/commands/cross-agent-install.ts
32059
32400
  init_fs();
32060
32401
  import { spawnSync as spawnSync6 } from "child_process";
32061
- import { dirname as dirname20, join as join15, resolve as resolve67 } from "path";
32062
- import { cp as cp4, mkdir as mkdir9, readFile as readFile45 } from "fs/promises";
32402
+ import { dirname as dirname20, join as join15, resolve as resolve68 } from "path";
32403
+ import { cp as cp4, mkdir as mkdir9, readFile as readFile46 } from "fs/promises";
32063
32404
 
32064
32405
  // src/commands/setup-adapter.ts
32065
32406
  init_paths();
@@ -32068,7 +32409,7 @@ init_config2();
32068
32409
  init_slug();
32069
32410
  init_registry();
32070
32411
  init_renderers();
32071
- import { resolve as resolve66 } from "path";
32412
+ import { resolve as resolve67 } from "path";
32072
32413
  async function setupAdapterCommand(framework, options) {
32073
32414
  const { targets: known, warnings } = await resolveAgentTargets();
32074
32415
  const target = known.find((t) => t.id === framework);
@@ -32097,13 +32438,13 @@ async function setupAdapterCommand(framework, options) {
32097
32438
  }
32098
32439
  const config = await readConfig();
32099
32440
  const baseDir = options.dir ? expandHome(options.dir) : config.defaultProjectDir;
32100
- const projectDir = resolve66(baseDir, options.project);
32101
- const assignmentDir = resolve66(projectDir, "assignments", options.assignment);
32102
- const projectMdPath = resolve66(projectDir, "project.md");
32441
+ const projectDir = resolve67(baseDir, options.project);
32442
+ const assignmentDir = resolve67(projectDir, "assignments", options.assignment);
32443
+ const projectMdPath = resolve67(projectDir, "project.md");
32103
32444
  if (!await fileExists(projectDir) || !await fileExists(projectMdPath)) {
32104
32445
  throw new Error(`Project "${options.project}" not found at ${projectDir}.`);
32105
32446
  }
32106
- const assignmentMdPath2 = resolve66(assignmentDir, "assignment.md");
32447
+ const assignmentMdPath2 = resolve67(assignmentDir, "assignment.md");
32107
32448
  if (!await fileExists(assignmentDir) || !await fileExists(assignmentMdPath2)) {
32108
32449
  throw new Error(
32109
32450
  `Assignment "${options.assignment}" not found at ${assignmentDir}.`
@@ -32120,7 +32461,7 @@ async function setupAdapterCommand(framework, options) {
32120
32461
  const upToDateFiles = [];
32121
32462
  const skippedFiles = [];
32122
32463
  for (const file of target.instructions.files) {
32123
- const filePath = resolve66(cwd, file.path);
32464
+ const filePath = resolve67(cwd, file.path);
32124
32465
  const content = RENDERERS[file.renderer](rendererParams);
32125
32466
  const status = await writeFileReport(filePath, content, {
32126
32467
  force: options.force
@@ -32176,7 +32517,7 @@ async function installTier3Plugin(t, opts = {}) {
32176
32517
  return "already-present";
32177
32518
  }
32178
32519
  try {
32179
- const sourceDir = resolve67(await findPackageRoot(plugin.source), plugin.source);
32520
+ const sourceDir = resolve68(await findPackageRoot(plugin.source), plugin.source);
32180
32521
  await mkdir9(dirname20(installDir), { recursive: true });
32181
32522
  await cp4(sourceDir, installDir, { recursive: true, force: true });
32182
32523
  console.log(`Tier 3 (${t.id}): installed ${plugin.kind} -> ${installDir}`);
@@ -32201,10 +32542,10 @@ function isNpxAvailable() {
32201
32542
  }
32202
32543
  }
32203
32544
  async function readAssignmentContext() {
32204
- const p = resolve67(process.cwd(), ".syntaur", "context.json");
32545
+ const p = resolve68(process.cwd(), ".syntaur", "context.json");
32205
32546
  if (!await fileExists(p)) return null;
32206
32547
  try {
32207
- return JSON.parse(await readFile45(p, "utf-8"));
32548
+ return JSON.parse(await readFile46(p, "utf-8"));
32208
32549
  } catch {
32209
32550
  return null;
32210
32551
  }
@@ -32284,7 +32625,7 @@ async function crossAgentInstallCommand(options) {
32284
32625
  if (dryRun) {
32285
32626
  for (const f of t.instructions.files) {
32286
32627
  console.log(
32287
- `${prefix}Tier 2 (${t.id}): ${resolve67(process.cwd(), f.path)}`
32628
+ `${prefix}Tier 2 (${t.id}): ${resolve68(process.cwd(), f.path)}`
32288
32629
  );
32289
32630
  }
32290
32631
  continue;
@@ -32441,7 +32782,7 @@ async function setupCommand(options) {
32441
32782
  }
32442
32783
 
32443
32784
  // src/commands/uninstall.ts
32444
- import { resolve as resolve68 } from "path";
32785
+ import { resolve as resolve69 } from "path";
32445
32786
  init_paths();
32446
32787
  function expandTargets(options) {
32447
32788
  if (options.all) {
@@ -32521,7 +32862,7 @@ async function uninstallCommand(options) {
32521
32862
  const configuredProjectDir = await getConfiguredProjectDir();
32522
32863
  await removeSyntaurData();
32523
32864
  console.log(`Removed ${syntaurRoot()}`);
32524
- if (configuredProjectDir && resolve68(configuredProjectDir) !== resolve68(syntaurRoot(), "projects")) {
32865
+ if (configuredProjectDir && resolve69(configuredProjectDir) !== resolve69(syntaurRoot(), "projects")) {
32525
32866
  console.warn(
32526
32867
  `Warning: config.md pointed to an external project directory (${configuredProjectDir}). That directory was not removed automatically.`
32527
32868
  );
@@ -32543,8 +32884,8 @@ init_session_id();
32543
32884
  init_cwd();
32544
32885
  init_session_db();
32545
32886
  init_agent_sessions();
32546
- import { resolve as resolve69 } from "path";
32547
- import { readFile as readFile46 } from "fs/promises";
32887
+ import { resolve as resolve70 } from "path";
32888
+ import { readFile as readFile47 } from "fs/promises";
32548
32889
  async function trackSessionCommand(options, deps = {}) {
32549
32890
  if (!options.agent) {
32550
32891
  throw new Error("--agent <name> is required.");
@@ -32554,7 +32895,7 @@ async function trackSessionCommand(options, deps = {}) {
32554
32895
  const cwd = process.cwd();
32555
32896
  let legacyHint;
32556
32897
  try {
32557
- const raw2 = await readFile46(resolve69(cwd, ".syntaur", "context.json"), "utf-8");
32898
+ const raw2 = await readFile47(resolve70(cwd, ".syntaur", "context.json"), "utf-8");
32558
32899
  const parsed = JSON.parse(raw2);
32559
32900
  if (typeof parsed.sessionId === "string") legacyHint = parsed.sessionId;
32560
32901
  } catch {
@@ -32569,7 +32910,7 @@ async function trackSessionCommand(options, deps = {}) {
32569
32910
  if (options.project) {
32570
32911
  const config = await readConfig();
32571
32912
  const baseDir = options.dir ? expandHome(options.dir) : config.defaultProjectDir;
32572
- const projectDir = resolve69(baseDir, options.project);
32913
+ const projectDir = resolve70(baseDir, options.project);
32573
32914
  if (!await fileExists(projectDir)) {
32574
32915
  throw new Error(
32575
32916
  `Project "${options.project}" not found at ${projectDir}.`
@@ -32702,8 +33043,8 @@ function formatInstallUrlHandlerError(err2) {
32702
33043
  init_config2();
32703
33044
  init_paths();
32704
33045
  init_fs();
32705
- import { resolve as resolve71, isAbsolute as isAbsolute8 } from "path";
32706
- import { readFile as readFile47 } from "fs/promises";
33046
+ import { resolve as resolve72, isAbsolute as isAbsolute8 } from "path";
33047
+ import { readFile as readFile48 } from "fs/promises";
32707
33048
  import { select, confirm as confirm2, input as input3 } from "@inquirer/prompts";
32708
33049
  async function browseCommand(options) {
32709
33050
  const config = await readConfig();
@@ -32772,7 +33113,7 @@ async function pickAgent2(agents) {
32772
33113
  return picked;
32773
33114
  }
32774
33115
  async function ensureWorktree(opts) {
32775
- const assignmentPath = resolve71(
33116
+ const assignmentPath = resolve72(
32776
33117
  opts.projectsDir,
32777
33118
  opts.projectSlug,
32778
33119
  "assignments",
@@ -32782,7 +33123,7 @@ async function ensureWorktree(opts) {
32782
33123
  if (!await fileExists(assignmentPath)) {
32783
33124
  return void 0;
32784
33125
  }
32785
- const content = await readFile47(assignmentPath, "utf-8");
33126
+ const content = await readFile48(assignmentPath, "utf-8");
32786
33127
  const { parseAssignmentFrontmatter: parseAssignmentFrontmatter2 } = await Promise.resolve().then(() => (init_frontmatter(), frontmatter_exports));
32787
33128
  const fm = parseAssignmentFrontmatter2(content);
32788
33129
  const { workspace } = fm;
@@ -32852,7 +33193,7 @@ async function ensureWorktree(opts) {
32852
33193
  async function runCreate(opts) {
32853
33194
  const { createWorktreeAndRecord: createWorktreeAndRecord2, GitWorktreeError: GitWorktreeError2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
32854
33195
  const expandedWorktree = expandHome(opts.worktreePath);
32855
- const absWorktree = isAbsolute8(expandedWorktree) ? expandedWorktree : resolve71(expandedWorktree);
33196
+ const absWorktree = isAbsolute8(expandedWorktree) ? expandedWorktree : resolve72(expandedWorktree);
32856
33197
  try {
32857
33198
  await createWorktreeAndRecord2({
32858
33199
  assignmentPath: opts.assignmentPath,
@@ -32881,7 +33222,7 @@ init_paths();
32881
33222
  init_fs();
32882
33223
  init_playbook();
32883
33224
  init_playbooks();
32884
- import { resolve as resolve72 } from "path";
33225
+ import { resolve as resolve73 } from "path";
32885
33226
  async function createPlaybookCommand(name, options) {
32886
33227
  if (!name.trim()) {
32887
33228
  throw new Error("Playbook name cannot be empty.");
@@ -32894,7 +33235,7 @@ async function createPlaybookCommand(name, options) {
32894
33235
  }
32895
33236
  const dir = playbooksDir();
32896
33237
  await ensureDir(dir);
32897
- const filePath = resolve72(dir, `${slug}.md`);
33238
+ const filePath = resolve73(dir, `${slug}.md`);
32898
33239
  if (await fileExists(filePath)) {
32899
33240
  throw new Error(
32900
33241
  `Playbook "${slug}" already exists at ${filePath}
@@ -32916,8 +33257,8 @@ init_paths();
32916
33257
  init_fs();
32917
33258
  init_parser();
32918
33259
  init_config2();
32919
- import { readdir as readdir26, readFile as readFile48 } from "fs/promises";
32920
- import { resolve as resolve73 } from "path";
33260
+ import { readdir as readdir26, readFile as readFile49 } from "fs/promises";
33261
+ import { resolve as resolve74 } from "path";
32921
33262
  async function listPlaybooksCommand(options = {}) {
32922
33263
  const dir = playbooksDir();
32923
33264
  if (!await fileExists(dir)) {
@@ -32932,8 +33273,8 @@ async function listPlaybooksCommand(options = {}) {
32932
33273
  );
32933
33274
  const rows = [];
32934
33275
  for (const entry of mdFiles) {
32935
- const filePath = resolve73(dir, entry.name);
32936
- const raw2 = await readFile48(filePath, "utf-8");
33276
+ const filePath = resolve74(dir, entry.name);
33277
+ const raw2 = await readFile49(filePath, "utf-8");
32937
33278
  const parsed = parsePlaybook(raw2);
32938
33279
  const slug = parsed.slug || entry.name.replace(/\.md$/, "");
32939
33280
  const disabled = disabledSet.has(slug);
@@ -33056,14 +33397,14 @@ init_fs();
33056
33397
  init_config2();
33057
33398
  init_slug();
33058
33399
  import { Command as Command2 } from "commander";
33059
- import { readFile as readFile50 } from "fs/promises";
33060
- import { resolve as resolve75 } from "path";
33400
+ import { readFile as readFile51 } from "fs/promises";
33401
+ import { resolve as resolve76 } from "path";
33061
33402
 
33062
33403
  // src/commands/bundle.ts
33063
33404
  init_paths();
33064
33405
  import { Command } from "commander";
33065
- import { mkdir as mkdir10, readFile as readFile49, readdir as readdir27, rm as rm9, writeFile as writeFile13 } from "fs/promises";
33066
- import { resolve as resolve74 } from "path";
33406
+ import { mkdir as mkdir10, readFile as readFile50, readdir as readdir27, rm as rm9, writeFile as writeFile13 } from "fs/promises";
33407
+ import { resolve as resolve75 } from "path";
33067
33408
  init_parser2();
33068
33409
  init_fs();
33069
33410
  init_config2();
@@ -33081,7 +33422,7 @@ async function resolveBundleScope(options) {
33081
33422
  throw new Error(`Invalid project slug: "${options.project}".`);
33082
33423
  }
33083
33424
  const config = await readConfig();
33084
- const projectMd = resolve74(config.defaultProjectDir, options.project, "project.md");
33425
+ const projectMd = resolve75(config.defaultProjectDir, options.project, "project.md");
33085
33426
  if (!await fileExists(projectMd)) {
33086
33427
  throw new Error(`Project "${options.project}" not found.`);
33087
33428
  }
@@ -33151,10 +33492,10 @@ function pickNextPlanFile(planDir, existingFiles) {
33151
33492
  const m = f.match(/^plan-v(\d+)\.md$/);
33152
33493
  if (m) versions.add(parseInt(m[1], 10));
33153
33494
  }
33154
- if (versions.size === 0) return { target: resolve74(planDir, "plan.md"), version: 1 };
33495
+ if (versions.size === 0) return { target: resolve75(planDir, "plan.md"), version: 1 };
33155
33496
  let n = 2;
33156
33497
  while (versions.has(n)) n++;
33157
- return { target: resolve74(planDir, `plan-v${n}.md`), version: n };
33498
+ return { target: resolve75(planDir, `plan-v${n}.md`), version: n };
33158
33499
  }
33159
33500
  function dedupePreserveOrder(ids) {
33160
33501
  const out = [];
@@ -33238,7 +33579,7 @@ bundleCommand.command("new").description("Create a new bundle from 2+ existing t
33238
33579
  if (options.plan) {
33239
33580
  const planDir = bundlePlanDir(sc.todosPath, sc.scopeId, id);
33240
33581
  await ensureDir(planDir);
33241
- const target = resolve74(planDir, "plan.md");
33582
+ const target = resolve75(planDir, "plan.md");
33242
33583
  const memberLines = items.map((it) => `- ${it.description} [t:${it.id}]`).join("\n");
33243
33584
  const stub = [
33244
33585
  "---",
@@ -33414,7 +33755,7 @@ bundleCommand.command("worktree").description("Create a git worktree for the bun
33414
33755
  }
33415
33756
  const repository = options.repository ?? process.cwd();
33416
33757
  const parentBranch = options.parentBranch ?? "main";
33417
- const worktreePath = options.worktreePath ?? resolve74(repository, ".worktrees", options.branch);
33758
+ const worktreePath = options.worktreePath ?? resolve75(repository, ".worktrees", options.branch);
33418
33759
  const checklist = await readChecklist(sc.todosPath, sc.checklistKey);
33419
33760
  for (const memberId of bundle.todoIds) {
33420
33761
  const item = checklist.items.find((i) => i.id === memberId);
@@ -33424,8 +33765,8 @@ bundleCommand.command("worktree").description("Create a git worktree for the bun
33424
33765
  }
33425
33766
  const bundlesFilePath = bundlesPath(sc.todosPath);
33426
33767
  const checklistFilePath = checklistPath(sc.todosPath, sc.checklistKey);
33427
- const bundlesSnapshot = await fileExists(bundlesFilePath) ? await readFile49(bundlesFilePath, "utf-8") : null;
33428
- const checklistSnapshot = await fileExists(checklistFilePath) ? await readFile49(checklistFilePath, "utf-8") : null;
33768
+ const bundlesSnapshot = await fileExists(bundlesFilePath) ? await readFile50(bundlesFilePath, "utf-8") : null;
33769
+ const checklistSnapshot = await fileExists(checklistFilePath) ? await readFile50(checklistFilePath, "utf-8") : null;
33429
33770
  const record = async () => {
33430
33771
  bundle.branch = options.branch;
33431
33772
  bundle.worktreePath = worktreePath;
@@ -33441,7 +33782,7 @@ bundleCommand.command("worktree").description("Create a git worktree for the bun
33441
33782
  try {
33442
33783
  await writeBundles(sc.todosPath, bundles);
33443
33784
  await writeChecklist(sc.todosPath, checklist);
33444
- const ctxDir = resolve74(worktreePath, ".syntaur");
33785
+ const ctxDir = resolve75(worktreePath, ".syntaur");
33445
33786
  await mkdir10(ctxDir, { recursive: true });
33446
33787
  const payload = {
33447
33788
  bundleId: bundle.id,
@@ -33455,7 +33796,7 @@ bundleCommand.command("worktree").description("Create a git worktree for the bun
33455
33796
  repository,
33456
33797
  boundAt: nowISO()
33457
33798
  };
33458
- await writeFile13(resolve74(ctxDir, "context.json"), JSON.stringify(payload, null, 2) + "\n");
33799
+ await writeFile13(resolve75(ctxDir, "context.json"), JSON.stringify(payload, null, 2) + "\n");
33459
33800
  } catch (err2) {
33460
33801
  try {
33461
33802
  if (bundlesSnapshot === null) {
@@ -33645,7 +33986,7 @@ async function resolveScope(options) {
33645
33986
  throw new Error(`Invalid project slug: "${options.project}".`);
33646
33987
  }
33647
33988
  const config = await readConfig();
33648
- const projectMd = resolve75(config.defaultProjectDir, options.project, "project.md");
33989
+ const projectMd = resolve76(config.defaultProjectDir, options.project, "project.md");
33649
33990
  if (!await fileExists(projectMd)) {
33650
33991
  throw new Error(`Project "${options.project}" not found.`);
33651
33992
  }
@@ -33968,10 +34309,10 @@ todoCommand.command("archive").description("Archive completed todos and their lo
33968
34309
  (e) => e.itemIds.every((id) => completedIds.has(id))
33969
34310
  );
33970
34311
  const archFile = archivePath(todosPath, workspace, checklist.archiveInterval);
33971
- await ensureDir(resolve75(todosPath, "archive"));
34312
+ await ensureDir(resolve76(todosPath, "archive"));
33972
34313
  let archContent = "";
33973
34314
  if (await fileExists(archFile)) {
33974
- archContent = await readFile50(archFile, "utf-8");
34315
+ archContent = await readFile51(archFile, "utf-8");
33975
34316
  archContent = archContent.trimEnd() + "\n\n";
33976
34317
  } else {
33977
34318
  archContent = `---
@@ -34148,12 +34489,12 @@ function describeScope(scope) {
34148
34489
  }
34149
34490
  async function injectPromotedTodos(assignmentDir, todos, scopeLabel) {
34150
34491
  const { resolve: resolvePath2 } = await import("path");
34151
- const { readFile: readFile80 } = await import("fs/promises");
34492
+ const { readFile: readFile81 } = await import("fs/promises");
34152
34493
  const { writeFileForce: writeFileForce2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
34153
34494
  const { appendTodosToAssignmentBody: appendTodosToAssignmentBody2, touchAssignmentUpdated: touchAssignmentUpdated2 } = await Promise.resolve().then(() => (init_assignment_todos(), assignment_todos_exports));
34154
34495
  const { nowTimestamp: nowTimestamp3 } = await Promise.resolve().then(() => (init_timestamp(), timestamp_exports));
34155
34496
  const assignmentMdPath2 = resolvePath2(assignmentDir, "assignment.md");
34156
- let content = await readFile80(assignmentMdPath2, "utf-8");
34497
+ let content = await readFile81(assignmentMdPath2, "utf-8");
34157
34498
  content = appendTodosToAssignmentBody2(
34158
34499
  content,
34159
34500
  todos.map((t) => ({
@@ -34204,7 +34545,7 @@ todoCommand.command("plan").description("Create or open a plan directory for a t
34204
34545
  );
34205
34546
  let target;
34206
34547
  if (existingFiles.length === 0) {
34207
- target = resolve75(planDir, "plan.md");
34548
+ target = resolve76(planDir, "plan.md");
34208
34549
  } else {
34209
34550
  const versions = /* @__PURE__ */ new Set();
34210
34551
  for (const f of existingFiles) {
@@ -34214,7 +34555,7 @@ todoCommand.command("plan").description("Create or open a plan directory for a t
34214
34555
  }
34215
34556
  let n = 2;
34216
34557
  while (versions.has(n)) n++;
34217
- target = resolve75(planDir, `plan-v${n}.md`);
34558
+ target = resolve76(planDir, `plan-v${n}.md`);
34218
34559
  }
34219
34560
  if (!await fileExists(target)) {
34220
34561
  const stub = `---
@@ -34403,12 +34744,12 @@ backupCommand.command("config").description("Show or update backup configuration
34403
34744
 
34404
34745
  // src/commands/doctor.ts
34405
34746
  import { Command as Command4 } from "commander";
34406
- import { readFile as readFile61 } from "fs/promises";
34407
- import { isAbsolute as isAbsolute11, resolve as resolve88 } from "path";
34747
+ import { readFile as readFile62 } from "fs/promises";
34748
+ import { isAbsolute as isAbsolute11, resolve as resolve89 } from "path";
34408
34749
 
34409
34750
  // src/utils/doctor/index.ts
34410
34751
  import { fileURLToPath as fileURLToPath12 } from "url";
34411
- import { readFile as readFile60 } from "fs/promises";
34752
+ import { readFile as readFile61 } from "fs/promises";
34412
34753
  import { dirname as dirname25, join as join21 } from "path";
34413
34754
 
34414
34755
  // src/utils/doctor/context.ts
@@ -34416,11 +34757,11 @@ init_config2();
34416
34757
  init_paths();
34417
34758
  init_fs();
34418
34759
  import Database5 from "better-sqlite3";
34419
- import { resolve as resolve76 } from "path";
34760
+ import { resolve as resolve77 } from "path";
34420
34761
  async function buildCheckContext(cwd = process.cwd()) {
34421
34762
  const config = await readConfig();
34422
34763
  const root = syntaurRoot();
34423
- const dbPath = resolve76(root, "syntaur.db");
34764
+ const dbPath = resolve77(root, "syntaur.db");
34424
34765
  let db6 = null;
34425
34766
  let dbError = null;
34426
34767
  if (await fileExists(dbPath)) {
@@ -34454,8 +34795,8 @@ function closeCheckContext(ctx) {
34454
34795
  // src/utils/doctor/checks/env.ts
34455
34796
  init_fs();
34456
34797
  init_paths();
34457
- import { resolve as resolve77, isAbsolute as isAbsolute9 } from "path";
34458
- import { readFile as readFile51, stat as stat8 } from "fs/promises";
34798
+ import { resolve as resolve78, isAbsolute as isAbsolute9 } from "path";
34799
+ import { readFile as readFile52, stat as stat8 } from "fs/promises";
34459
34800
  import { fileURLToPath as fileURLToPath10 } from "url";
34460
34801
  import { dirname as dirname22, join as join17 } from "path";
34461
34802
  var CATEGORY = "env";
@@ -34495,7 +34836,7 @@ var configValid = {
34495
34836
  category: CATEGORY,
34496
34837
  title: "~/.syntaur/config.md is valid",
34497
34838
  async run(ctx) {
34498
- const configPath2 = resolve77(ctx.syntaurRoot, "config.md");
34839
+ const configPath2 = resolve78(ctx.syntaurRoot, "config.md");
34499
34840
  if (!await fileExists(configPath2)) {
34500
34841
  return {
34501
34842
  id: this.id,
@@ -34512,7 +34853,7 @@ var configValid = {
34512
34853
  autoFixable: false
34513
34854
  };
34514
34855
  }
34515
- const content = await readFile51(configPath2, "utf-8");
34856
+ const content = await readFile52(configPath2, "utf-8");
34516
34857
  const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
34517
34858
  if (!fmMatch || fmMatch[1].trim() === "") {
34518
34859
  return {
@@ -34792,7 +35133,7 @@ async function readLocalPkg() {
34792
35133
  for (let i = 0; i < 6; i++) {
34793
35134
  const candidate = join17(dir, "package.json");
34794
35135
  try {
34795
- const text = await readFile51(candidate, "utf-8");
35136
+ const text = await readFile52(candidate, "utf-8");
34796
35137
  return JSON.parse(text);
34797
35138
  } catch {
34798
35139
  dir = dirname22(dir);
@@ -34844,7 +35185,7 @@ function versionGte(a, b) {
34844
35185
 
34845
35186
  // src/utils/doctor/checks/structure.ts
34846
35187
  init_fs();
34847
- import { resolve as resolve78 } from "path";
35188
+ import { resolve as resolve79 } from "path";
34848
35189
  import { readdir as readdir28, stat as stat9 } from "fs/promises";
34849
35190
  var CATEGORY2 = "structure";
34850
35191
  var KNOWN_TOP_LEVEL = /* @__PURE__ */ new Set([
@@ -34864,7 +35205,7 @@ var projectsDir = {
34864
35205
  category: CATEGORY2,
34865
35206
  title: "projects/ directory exists",
34866
35207
  async run(ctx) {
34867
- const p = resolve78(ctx.syntaurRoot, "projects");
35208
+ const p = resolve79(ctx.syntaurRoot, "projects");
34868
35209
  if (!await fileExists(p)) {
34869
35210
  return {
34870
35211
  id: this.id,
@@ -34889,7 +35230,7 @@ var playbooksDir2 = {
34889
35230
  category: CATEGORY2,
34890
35231
  title: "playbooks/ directory exists",
34891
35232
  async run(ctx) {
34892
- const p = resolve78(ctx.syntaurRoot, "playbooks");
35233
+ const p = resolve79(ctx.syntaurRoot, "playbooks");
34893
35234
  if (!await fileExists(p)) {
34894
35235
  return {
34895
35236
  id: this.id,
@@ -34914,7 +35255,7 @@ var todosDirValid = {
34914
35255
  category: CATEGORY2,
34915
35256
  title: "todos/ directory is readable (if present)",
34916
35257
  async run(ctx) {
34917
- const p = resolve78(ctx.syntaurRoot, "todos");
35258
+ const p = resolve79(ctx.syntaurRoot, "todos");
34918
35259
  if (!await fileExists(p)) {
34919
35260
  return {
34920
35261
  id: this.id,
@@ -34945,7 +35286,7 @@ var serversDirValid = {
34945
35286
  category: CATEGORY2,
34946
35287
  title: "servers/ directory is readable (if present)",
34947
35288
  async run(ctx) {
34948
- const p = resolve78(ctx.syntaurRoot, "servers");
35289
+ const p = resolve79(ctx.syntaurRoot, "servers");
34949
35290
  if (!await fileExists(p)) {
34950
35291
  return {
34951
35292
  id: this.id,
@@ -34990,7 +35331,7 @@ var knownFilesRecognized = {
34990
35331
  title: this.title,
34991
35332
  status: "warn",
34992
35333
  detail: `unexpected top-level entries: ${unexpected.join(", ")}`,
34993
- affected: unexpected.map((n) => resolve78(ctx.syntaurRoot, n)),
35334
+ affected: unexpected.map((n) => resolve79(ctx.syntaurRoot, n)),
34994
35335
  remediation: {
34995
35336
  kind: "manual",
34996
35337
  suggestion: "Review these entries \u2014 they may be leftover state from older versions",
@@ -35019,7 +35360,7 @@ function pass2(check) {
35019
35360
 
35020
35361
  // src/utils/doctor/checks/project.ts
35021
35362
  init_fs();
35022
- import { resolve as resolve79 } from "path";
35363
+ import { resolve as resolve80 } from "path";
35023
35364
  import { readdir as readdir29, stat as stat10 } from "fs/promises";
35024
35365
  var CATEGORY3 = "project";
35025
35366
  var REQUIRED_PROJECT_FILES = [
@@ -35049,10 +35390,10 @@ async function listProjects2(ctx) {
35049
35390
  for (const e of entries) {
35050
35391
  if (!e.isDirectory()) continue;
35051
35392
  if (e.name.startsWith(".") || e.name.startsWith("_")) continue;
35052
- const projectDir = resolve79(dir, e.name);
35393
+ const projectDir = resolve80(dir, e.name);
35053
35394
  let looksLikeProject = false;
35054
35395
  for (const marker of PROJECT_MARKERS) {
35055
- if (await fileExists(resolve79(projectDir, marker))) {
35396
+ if (await fileExists(resolve80(projectDir, marker))) {
35056
35397
  looksLikeProject = true;
35057
35398
  break;
35058
35399
  }
@@ -35071,7 +35412,7 @@ var requiredFiles = {
35071
35412
  for (const projectDir of projects) {
35072
35413
  const missing = [];
35073
35414
  for (const rel of REQUIRED_PROJECT_FILES) {
35074
- const p = resolve79(projectDir, rel);
35415
+ const p = resolve80(projectDir, rel);
35075
35416
  if (!await fileExists(p)) missing.push(rel);
35076
35417
  }
35077
35418
  if (missing.length === 0) continue;
@@ -35081,7 +35422,7 @@ var requiredFiles = {
35081
35422
  title: this.title,
35082
35423
  status: "error",
35083
35424
  detail: `project at ${projectDir} is missing: ${missing.join(", ")}`,
35084
- affected: missing.map((m) => resolve79(projectDir, m)),
35425
+ affected: missing.map((m) => resolve80(projectDir, m)),
35085
35426
  remediation: {
35086
35427
  kind: "manual",
35087
35428
  suggestion: "Recreate the missing scaffold files from templates",
@@ -35104,7 +35445,7 @@ var manifestStale = {
35104
35445
  const projects = await listProjects2(ctx);
35105
35446
  const results = [];
35106
35447
  for (const projectDir of projects) {
35107
- const manifestPath = resolve79(projectDir, "manifest.md");
35448
+ const manifestPath = resolve80(projectDir, "manifest.md");
35108
35449
  if (!await fileExists(manifestPath)) continue;
35109
35450
  const manifestMtime = (await stat10(manifestPath)).mtimeMs;
35110
35451
  const newestAssignment = await newestAssignmentMtime(projectDir);
@@ -35153,7 +35494,7 @@ var orphanFiles = {
35153
35494
  title: this.title,
35154
35495
  status: "warn",
35155
35496
  detail: `project at ${projectDir} has unexpected entries: ${orphans.join(", ")}`,
35156
- affected: orphans.map((o) => resolve79(projectDir, o)),
35497
+ affected: orphans.map((o) => resolve80(projectDir, o)),
35157
35498
  autoFixable: false
35158
35499
  });
35159
35500
  }
@@ -35163,7 +35504,7 @@ var orphanFiles = {
35163
35504
  };
35164
35505
  var projectChecks = [requiredFiles, manifestStale, orphanFiles];
35165
35506
  async function newestAssignmentMtime(projectDir) {
35166
- const assignmentsRoot = resolve79(projectDir, "assignments");
35507
+ const assignmentsRoot = resolve80(projectDir, "assignments");
35167
35508
  if (!await fileExists(assignmentsRoot)) return 0;
35168
35509
  let newest = 0;
35169
35510
  let entries;
@@ -35174,7 +35515,7 @@ async function newestAssignmentMtime(projectDir) {
35174
35515
  }
35175
35516
  for (const e of entries) {
35176
35517
  if (!e.isDirectory()) continue;
35177
- const assignmentMd = resolve79(assignmentsRoot, e.name, "assignment.md");
35518
+ const assignmentMd = resolve80(assignmentsRoot, e.name, "assignment.md");
35178
35519
  try {
35179
35520
  const s = await stat10(assignmentMd);
35180
35521
  if (s.mtimeMs > newest) newest = s.mtimeMs;
@@ -35199,8 +35540,8 @@ init_parser();
35199
35540
  init_types();
35200
35541
  init_paths();
35201
35542
  init_assignment_walk();
35202
- import { resolve as resolve80 } from "path";
35203
- import { readFile as readFile52, readdir as readdir30 } from "fs/promises";
35543
+ import { resolve as resolve81 } from "path";
35544
+ import { readFile as readFile53, readdir as readdir30 } from "fs/promises";
35204
35545
  var CATEGORY4 = "assignment";
35205
35546
  var STATUSES_REQUIRING_HANDOFF = /* @__PURE__ */ new Set(["review", "completed"]);
35206
35547
  var PRE_WORKSPACE_STATUSES = /* @__PURE__ */ new Set([
@@ -35294,7 +35635,7 @@ var invalidStatus = {
35294
35635
  const allowed = configuredStatuses(ctx);
35295
35636
  const results = [];
35296
35637
  for (const a of withAssignmentMd) {
35297
- const path = resolve80(a.assignmentDir, "assignment.md");
35638
+ const path = resolve81(a.assignmentDir, "assignment.md");
35298
35639
  const parsed = await parseSafe4(path);
35299
35640
  if (!parsed) continue;
35300
35641
  if (!allowed.has(parsed.status)) {
@@ -35327,7 +35668,7 @@ var workspaceMissing = {
35327
35668
  const terminal = terminalStatuses(ctx);
35328
35669
  const results = [];
35329
35670
  for (const a of withAssignmentMd) {
35330
- const path = resolve80(a.assignmentDir, "assignment.md");
35671
+ const path = resolve81(a.assignmentDir, "assignment.md");
35331
35672
  const parsed = await parseSafe4(path);
35332
35673
  if (!parsed) continue;
35333
35674
  if (terminal.has(parsed.status)) continue;
@@ -35374,12 +35715,12 @@ var requiredFilesByStatus = {
35374
35715
  const { withAssignmentMd } = await listAssignments(ctx);
35375
35716
  const results = [];
35376
35717
  for (const a of withAssignmentMd) {
35377
- const assignmentPath = resolve80(a.assignmentDir, "assignment.md");
35718
+ const assignmentPath = resolve81(a.assignmentDir, "assignment.md");
35378
35719
  const parsed = await parseSafe4(assignmentPath);
35379
35720
  if (!parsed) continue;
35380
35721
  const missing = [];
35381
35722
  if (STATUSES_REQUIRING_HANDOFF.has(parsed.status)) {
35382
- const handoffPath = resolve80(a.assignmentDir, "handoff.md");
35723
+ const handoffPath = resolve81(a.assignmentDir, "handoff.md");
35383
35724
  if (!await fileExists(handoffPath)) missing.push("handoff.md");
35384
35725
  }
35385
35726
  if (missing.length === 0) continue;
@@ -35389,7 +35730,7 @@ var requiredFilesByStatus = {
35389
35730
  title: this.title,
35390
35731
  status: "warn",
35391
35732
  detail: `${a.projectSlug}/${a.assignmentSlug} (status: ${parsed.status}) is missing ${missing.join(", ")}`,
35392
- affected: missing.map((m) => resolve80(a.assignmentDir, m)),
35733
+ affected: missing.map((m) => resolve81(a.assignmentDir, m)),
35393
35734
  remediation: {
35394
35735
  kind: "manual",
35395
35736
  suggestion: `Create the missing ${missing.join(" and ")} files for this assignment`,
@@ -35412,7 +35753,7 @@ var companionFilesScaffolded = {
35412
35753
  for (const a of withAssignmentMd) {
35413
35754
  const missing = [];
35414
35755
  for (const filename of ["progress.md", "comments.md"]) {
35415
- if (!await fileExists(resolve80(a.assignmentDir, filename))) {
35756
+ if (!await fileExists(resolve81(a.assignmentDir, filename))) {
35416
35757
  missing.push(filename);
35417
35758
  }
35418
35759
  }
@@ -35424,7 +35765,7 @@ var companionFilesScaffolded = {
35424
35765
  title: this.title,
35425
35766
  status: "warn",
35426
35767
  detail: `${label} is missing ${missing.join(" and ")} (pre-v2.0 assignment \u2014 not required, but scaffolding them keeps the dashboard and CLIs consistent)`,
35427
- affected: missing.map((m) => resolve80(a.assignmentDir, m)),
35768
+ affected: missing.map((m) => resolve81(a.assignmentDir, m)),
35428
35769
  remediation: {
35429
35770
  kind: "manual",
35430
35771
  suggestion: `Create ${missing.join(" and ")} with the renderProgress/renderComments templates, or re-scaffold via the CLI`,
@@ -35457,7 +35798,7 @@ var typeDefinition = {
35457
35798
  const { withAssignmentMd } = await listAssignments(ctx);
35458
35799
  const results = [];
35459
35800
  for (const a of withAssignmentMd) {
35460
- const path = resolve80(a.assignmentDir, "assignment.md");
35801
+ const path = resolve81(a.assignmentDir, "assignment.md");
35461
35802
  const parsed = await parseSafe4(path);
35462
35803
  if (!parsed) continue;
35463
35804
  if (!parsed.type) continue;
@@ -35491,7 +35832,7 @@ var projectFrontmatterMatchesContainer = {
35491
35832
  const { withAssignmentMd } = await listAssignments(ctx);
35492
35833
  const results = [];
35493
35834
  for (const a of withAssignmentMd) {
35494
- const path = resolve80(a.assignmentDir, "assignment.md");
35835
+ const path = resolve81(a.assignmentDir, "assignment.md");
35495
35836
  const parsed = await parseSafe4(path);
35496
35837
  if (!parsed) continue;
35497
35838
  if (a.standalone) {
@@ -35542,13 +35883,13 @@ var draftMissingObjective = {
35542
35883
  const { withAssignmentMd } = await listAssignments(ctx);
35543
35884
  const results = [];
35544
35885
  for (const a of withAssignmentMd) {
35545
- const path = resolve80(a.assignmentDir, "assignment.md");
35886
+ const path = resolve81(a.assignmentDir, "assignment.md");
35546
35887
  const parsed = await parseSafe4(path);
35547
35888
  if (!parsed) continue;
35548
35889
  if (parsed.status !== "draft") continue;
35549
35890
  let raw2;
35550
35891
  try {
35551
- raw2 = await readFile52(path, "utf-8");
35892
+ raw2 = await readFile53(path, "utf-8");
35552
35893
  } catch {
35553
35894
  continue;
35554
35895
  }
@@ -35581,7 +35922,7 @@ var readyToImplementMissingPlan = {
35581
35922
  const { withAssignmentMd } = await listAssignments(ctx);
35582
35923
  const results = [];
35583
35924
  for (const a of withAssignmentMd) {
35584
- const path = resolve80(a.assignmentDir, "assignment.md");
35925
+ const path = resolve81(a.assignmentDir, "assignment.md");
35585
35926
  const parsed = await parseSafe4(path);
35586
35927
  if (!parsed) continue;
35587
35928
  if (parsed.status !== "ready_to_implement") continue;
@@ -35590,7 +35931,7 @@ var readyToImplementMissingPlan = {
35590
35931
  let hasPlanContent = false;
35591
35932
  for (const f of planFiles) {
35592
35933
  try {
35593
- const c2 = await readFile52(resolve80(a.assignmentDir, f), "utf-8");
35934
+ const c2 = await readFile53(resolve81(a.assignmentDir, f), "utf-8");
35594
35935
  if (c2.trim().length > 0) {
35595
35936
  hasPlanContent = true;
35596
35937
  break;
@@ -35606,7 +35947,7 @@ var readyToImplementMissingPlan = {
35606
35947
  title: this.title,
35607
35948
  status: "warn",
35608
35949
  detail: `${label} (status: ready_to_implement) has no plan.md or plan-v<N>.md`,
35609
- affected: [resolve80(a.assignmentDir, "plan.md")],
35950
+ affected: [resolve81(a.assignmentDir, "plan.md")],
35610
35951
  remediation: {
35611
35952
  kind: "manual",
35612
35953
  suggestion: `Write a plan with '/plan-assignment' (or 'syntaur plan'), then re-mark ready_to_implement`,
@@ -35633,7 +35974,7 @@ var assignmentChecks = [
35633
35974
  ];
35634
35975
  async function parseSafe4(path) {
35635
35976
  try {
35636
- const content = await readFile52(path, "utf-8");
35977
+ const content = await readFile53(path, "utf-8");
35637
35978
  return parseAssignmentFull(content);
35638
35979
  } catch {
35639
35980
  return null;
@@ -35652,7 +35993,7 @@ function pass4(check, detail) {
35652
35993
 
35653
35994
  // src/utils/doctor/checks/dashboard.ts
35654
35995
  init_fs();
35655
- import { resolve as resolve81 } from "path";
35996
+ import { resolve as resolve82 } from "path";
35656
35997
  var CATEGORY5 = "dashboard";
35657
35998
  var dbReachable = {
35658
35999
  id: "dashboard.db-reachable",
@@ -35666,7 +36007,7 @@ var dbReachable = {
35666
36007
  title: this.title,
35667
36008
  status: "error",
35668
36009
  detail: `could not open syntaur.db: ${ctx.dbError ?? "unknown error"}`,
35669
- affected: [resolve81(ctx.syntaurRoot, "syntaur.db")],
36010
+ affected: [resolve82(ctx.syntaurRoot, "syntaur.db")],
35670
36011
  remediation: {
35671
36012
  kind: "manual",
35672
36013
  suggestion: "Start the dashboard once (`syntaur dashboard`) to initialize the DB, or restore it from backup",
@@ -35684,7 +36025,7 @@ var dbReachable = {
35684
36025
  title: this.title,
35685
36026
  status: "error",
35686
36027
  detail: 'syntaur.db is missing the expected "sessions" table',
35687
- affected: [resolve81(ctx.syntaurRoot, "syntaur.db")],
36028
+ affected: [resolve82(ctx.syntaurRoot, "syntaur.db")],
35688
36029
  autoFixable: false
35689
36030
  };
35690
36031
  }
@@ -35696,7 +36037,7 @@ var dbReachable = {
35696
36037
  title: this.title,
35697
36038
  status: "error",
35698
36039
  detail: `syntaur.db query failed: ${err2 instanceof Error ? err2.message : String(err2)}`,
35699
- affected: [resolve81(ctx.syntaurRoot, "syntaur.db")],
36040
+ affected: [resolve82(ctx.syntaurRoot, "syntaur.db")],
35700
36041
  autoFixable: false
35701
36042
  };
35702
36043
  }
@@ -35722,7 +36063,7 @@ var ghostSessions = {
35722
36063
  const results = [];
35723
36064
  for (const row of rows) {
35724
36065
  if (!row.project_slug) continue;
35725
- const projectPath = resolve81(projectsDir2, row.project_slug, "project.md");
36066
+ const projectPath = resolve82(projectsDir2, row.project_slug, "project.md");
35726
36067
  if (!await fileExists(projectPath)) {
35727
36068
  results.push({
35728
36069
  id: this.id,
@@ -35741,7 +36082,7 @@ var ghostSessions = {
35741
36082
  continue;
35742
36083
  }
35743
36084
  if (row.assignment_slug) {
35744
- const assignmentPath = resolve81(
36085
+ const assignmentPath = resolve82(
35745
36086
  projectsDir2,
35746
36087
  row.project_slug,
35747
36088
  "assignments",
@@ -35793,8 +36134,8 @@ function skipped(check, reason) {
35793
36134
 
35794
36135
  // src/utils/doctor/checks/integrations.ts
35795
36136
  init_fs();
35796
- import { resolve as resolve82, dirname as dirname23, basename as basename8 } from "path";
35797
- import { readdir as readdir31, readFile as readFile53 } from "fs/promises";
36137
+ import { resolve as resolve83, dirname as dirname23, basename as basename8 } from "path";
36138
+ import { readdir as readdir31, readFile as readFile54 } from "fs/promises";
35798
36139
  import { homedir as homedir14 } from "os";
35799
36140
  var CATEGORY6 = "integrations";
35800
36141
  var claudePluginLinked = {
@@ -35876,10 +36217,10 @@ var backupConfigured = {
35876
36217
  }
35877
36218
  };
35878
36219
  async function readKnownMarketplaces() {
35879
- const path = resolve82(homedir14(), ".claude", "plugins", "known_marketplaces.json");
36220
+ const path = resolve83(homedir14(), ".claude", "plugins", "known_marketplaces.json");
35880
36221
  if (!await fileExists(path)) return {};
35881
36222
  try {
35882
- const raw2 = await readFile53(path, "utf-8");
36223
+ const raw2 = await readFile54(path, "utf-8");
35883
36224
  return JSON.parse(raw2);
35884
36225
  } catch {
35885
36226
  return {};
@@ -35913,7 +36254,7 @@ var claudeMarketplaceRegistered = {
35913
36254
  };
35914
36255
  }
35915
36256
  const marketplaceRoot = dirname23(pluginsParent);
35916
- const marketplaceManifest = resolve82(marketplaceRoot, ".claude-plugin", "marketplace.json");
36257
+ const marketplaceManifest = resolve83(marketplaceRoot, ".claude-plugin", "marketplace.json");
35917
36258
  if (!await fileExists(marketplaceManifest)) {
35918
36259
  return {
35919
36260
  id: this.id,
@@ -35932,7 +36273,7 @@ var claudeMarketplaceRegistered = {
35932
36273
  }
35933
36274
  let parsed = {};
35934
36275
  try {
35935
- parsed = JSON.parse(await readFile53(marketplaceManifest, "utf-8"));
36276
+ parsed = JSON.parse(await readFile54(marketplaceManifest, "utf-8"));
35936
36277
  } catch {
35937
36278
  return {
35938
36279
  id: this.id,
@@ -35964,7 +36305,7 @@ var claudeMarketplaceRegistered = {
35964
36305
  title: this.title,
35965
36306
  status: "error",
35966
36307
  detail: issues.join("; "),
35967
- affected: [marketplaceManifest, resolve82(homedir14(), ".claude", "plugins", "known_marketplaces.json")],
36308
+ affected: [marketplaceManifest, resolve83(homedir14(), ".claude", "plugins", "known_marketplaces.json")],
35968
36309
  remediation: {
35969
36310
  kind: "manual",
35970
36311
  suggestion: "Re-run install-plugin to ensure both files are in sync.",
@@ -36004,8 +36345,8 @@ function skipped2(check, reason) {
36004
36345
  init_fs();
36005
36346
  init_parser();
36006
36347
  init_types();
36007
- import { resolve as resolve83 } from "path";
36008
- import { readFile as readFile54 } from "fs/promises";
36348
+ import { resolve as resolve84 } from "path";
36349
+ import { readFile as readFile55 } from "fs/promises";
36009
36350
  var CATEGORY7 = "workspace";
36010
36351
  var ASSIGNMENT_FIELDS2 = ["projectSlug", "assignmentSlug", "projectDir", "assignmentDir"];
36011
36352
  var BUNDLE_FIELDS = ["bundleId", "bundleScope", "bundleScopeId"];
@@ -36027,12 +36368,12 @@ function isStandaloneSession(ctx) {
36027
36368
  return !hasAnyAssignmentField(ctx) && !hasAnyBundleField(ctx) && hasSessionMeta;
36028
36369
  }
36029
36370
  async function loadContext(ctx) {
36030
- const path = resolve83(ctx.cwd, ".syntaur", "context.json");
36371
+ const path = resolve84(ctx.cwd, ".syntaur", "context.json");
36031
36372
  if (!await fileExists(path)) {
36032
36373
  return { data: null, path, exists: false, parseError: null };
36033
36374
  }
36034
36375
  try {
36035
- const raw2 = await readFile54(path, "utf-8");
36376
+ const raw2 = await readFile55(path, "utf-8");
36036
36377
  return { data: JSON.parse(raw2), path, exists: true, parseError: null };
36037
36378
  } catch (err2) {
36038
36379
  return {
@@ -36126,7 +36467,7 @@ var contextAssignmentResolves = {
36126
36467
  if (isStandaloneSession(data)) return skipped3(this, "standalone session context \u2014 no assignment to resolve");
36127
36468
  if (isBundleContext(data)) return skipped3(this, "bundle context \u2014 no assignment to resolve");
36128
36469
  if (!data?.assignmentDir) return skipped3(this, "context has no assignmentDir");
36129
- const assignmentMd = resolve83(data.assignmentDir, "assignment.md");
36470
+ const assignmentMd = resolve84(data.assignmentDir, "assignment.md");
36130
36471
  if (!await fileExists(assignmentMd)) {
36131
36472
  return {
36132
36473
  id: this.id,
@@ -36156,10 +36497,10 @@ var contextTerminal = {
36156
36497
  if (isStandaloneSession(data)) return skipped3(this, "standalone session context \u2014 no assignment to check");
36157
36498
  if (isBundleContext(data)) return skipped3(this, "bundle context \u2014 no assignment to check");
36158
36499
  if (!data?.assignmentDir) return skipped3(this, "context has no assignmentDir");
36159
- const assignmentMd = resolve83(data.assignmentDir, "assignment.md");
36500
+ const assignmentMd = resolve84(data.assignmentDir, "assignment.md");
36160
36501
  if (!await fileExists(assignmentMd)) return skipped3(this, "assignment file missing");
36161
36502
  try {
36162
- const content = await readFile54(assignmentMd, "utf-8");
36503
+ const content = await readFile55(assignmentMd, "utf-8");
36163
36504
  const parsed = parseAssignmentFull(content);
36164
36505
  const terminal = terminalStatuses2(ctx);
36165
36506
  if (terminal.has(parsed.status)) {
@@ -36305,15 +36646,15 @@ var agentChecks = [agentsResolvable];
36305
36646
  // src/utils/doctor/checks/terminal.ts
36306
36647
  init_config2();
36307
36648
  import { spawnSync as spawnSync9 } from "child_process";
36308
- import { readFile as readFile55 } from "fs/promises";
36309
- import { resolve as resolve84 } from "path";
36649
+ import { readFile as readFile56 } from "fs/promises";
36650
+ import { resolve as resolve85 } from "path";
36310
36651
  init_paths();
36311
36652
  init_fs();
36312
36653
  var CATEGORY9 = "terminal";
36313
36654
  async function readRawTerminalKey() {
36314
- const configPath2 = resolve84(syntaurRoot(), "config.md");
36655
+ const configPath2 = resolve85(syntaurRoot(), "config.md");
36315
36656
  if (!await fileExists(configPath2)) return null;
36316
- const content = await readFile55(configPath2, "utf-8");
36657
+ const content = await readFile56(configPath2, "utf-8");
36317
36658
  const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
36318
36659
  if (!fmMatch) return null;
36319
36660
  const line = fmMatch[1].split("\n").find((l) => /^terminal:\s*/.test(l));
@@ -36463,13 +36804,13 @@ var terminalChecks = [
36463
36804
 
36464
36805
  // src/utils/doctor/checks/skills.ts
36465
36806
  init_fs();
36466
- import { resolve as resolve85, join as join18 } from "path";
36467
- import { readdir as readdir32, readFile as readFile56, lstat as lstat4 } from "fs/promises";
36807
+ import { resolve as resolve86, join as join18 } from "path";
36808
+ import { readdir as readdir32, readFile as readFile57, lstat as lstat4 } from "fs/promises";
36468
36809
  import { homedir as homedir15 } from "os";
36469
36810
  var CATEGORY10 = "skills";
36470
36811
  var skillTargets = [
36471
- { agent: "claude", dir: resolve85(homedir15(), ".claude", "skills"), label: "~/.claude/skills" },
36472
- { agent: "codex", dir: resolve85(homedir15(), ".codex", "skills"), label: "~/.codex/skills" }
36812
+ { agent: "claude", dir: resolve86(homedir15(), ".claude", "skills"), label: "~/.claude/skills" },
36813
+ { agent: "codex", dir: resolve86(homedir15(), ".codex", "skills"), label: "~/.codex/skills" }
36473
36814
  ];
36474
36815
  var skillsDedupCheck = {
36475
36816
  id: "skills.dedup",
@@ -36493,7 +36834,7 @@ var skillsDedupCheck = {
36493
36834
  if (!KNOWN_SKILLS.includes(entry.name)) continue;
36494
36835
  const skillMd = join18(dir, entry.name, "SKILL.md");
36495
36836
  if (!await fileExists(skillMd)) continue;
36496
- const content = await readFile56(skillMd, "utf-8").catch(() => "");
36837
+ const content = await readFile57(skillMd, "utf-8").catch(() => "");
36497
36838
  const match = content.match(/^name:\s*(\S+)\s*$/m);
36498
36839
  if (!match || match[1] !== entry.name) continue;
36499
36840
  let isSymlink2 = false;
@@ -36543,12 +36884,12 @@ var skillsChecks = [skillsDedupCheck];
36543
36884
 
36544
36885
  // src/utils/doctor/checks/cross-agent.ts
36545
36886
  init_fs();
36546
- import { join as join19, resolve as resolve86 } from "path";
36547
- import { readFile as readFile58 } from "fs/promises";
36887
+ import { join as join19, resolve as resolve87 } from "path";
36888
+ import { readFile as readFile59 } from "fs/promises";
36548
36889
 
36549
36890
  // src/utils/skill-frontmatter.ts
36550
36891
  import { createHash as createHash4 } from "crypto";
36551
- import { readFile as readFile57 } from "fs/promises";
36892
+ import { readFile as readFile58 } from "fs/promises";
36552
36893
  function stripQuotes(raw2) {
36553
36894
  const t = raw2.trim();
36554
36895
  if (t.length >= 2 && (t.startsWith('"') && t.endsWith('"') || t.startsWith("'") && t.endsWith("'"))) {
@@ -36592,7 +36933,7 @@ function readSkillIdentity(skillMdText) {
36592
36933
  return { name, hasDescription };
36593
36934
  }
36594
36935
  async function sha256File(path) {
36595
- return createHash4("sha256").update(await readFile57(path)).digest("hex");
36936
+ return createHash4("sha256").update(await readFile58(path)).digest("hex");
36596
36937
  }
36597
36938
 
36598
36939
  // src/utils/doctor/checks/cross-agent.ts
@@ -36609,7 +36950,7 @@ async function checkTargetSkillsIntegrity(installedDir, canonicalSkillsDir, know
36609
36950
  }
36610
36951
  let text;
36611
36952
  try {
36612
- text = await readFile58(installedPath, "utf-8");
36953
+ text = await readFile59(installedPath, "utf-8");
36613
36954
  } catch {
36614
36955
  problems.push({ skill, kind: "invalid-frontmatter" });
36615
36956
  continue;
@@ -36686,7 +37027,7 @@ var crossAgentSkillsCheck = {
36686
37027
  }
36687
37028
  if (recorded && t.instructions) {
36688
37029
  for (const f of t.instructions.files) {
36689
- const p = resolve86(ctx.cwd, f.path);
37030
+ const p = resolve87(ctx.cwd, f.path);
36690
37031
  if (!await fileExists(p)) {
36691
37032
  problems.push(`${t.displayName}: missing protocol file ${f.path} in cwd`);
36692
37033
  affected.push(p);
@@ -36762,7 +37103,7 @@ var crossAgentChecks = [crossAgentSkillsCheck];
36762
37103
  // src/utils/doctor/checks/bundles.ts
36763
37104
  init_fs();
36764
37105
  init_paths();
36765
- import { resolve as resolve87 } from "path";
37106
+ import { resolve as resolve88 } from "path";
36766
37107
  import { readdir as readdir33 } from "fs/promises";
36767
37108
  import { spawnSync as spawnSync10 } from "child_process";
36768
37109
  init_parser2();
@@ -36792,7 +37133,7 @@ async function listScopes(ctx) {
36792
37133
  if (!e.isDirectory()) continue;
36793
37134
  const slug = e.name;
36794
37135
  if (typeof slug !== "string" || slug.startsWith(".")) continue;
36795
- const projectMd = resolve87(ctx.config.defaultProjectDir, slug, "project.md");
37136
+ const projectMd = resolve88(ctx.config.defaultProjectDir, slug, "project.md");
36796
37137
  if (!await fileExists(projectMd)) continue;
36797
37138
  out.push({
36798
37139
  scopeLabel: `project:${slug}`,
@@ -36985,7 +37326,7 @@ var bundleChecks = [
36985
37326
  ];
36986
37327
 
36987
37328
  // src/utils/doctor/checks/plugin.ts
36988
- import { readFile as readFile59 } from "fs/promises";
37329
+ import { readFile as readFile60 } from "fs/promises";
36989
37330
  import { dirname as dirname24, join as join20 } from "path";
36990
37331
  import { fileURLToPath as fileURLToPath11 } from "url";
36991
37332
  var CATEGORY13 = "plugin";
@@ -36995,7 +37336,7 @@ async function readCliVersion() {
36995
37336
  let dir = dirname24(fileURLToPath11(import.meta.url));
36996
37337
  for (let i = 0; i < 8; i += 1) {
36997
37338
  try {
36998
- const parsed = JSON.parse(await readFile59(join20(dir, "package.json"), "utf-8"));
37339
+ const parsed = JSON.parse(await readFile60(join20(dir, "package.json"), "utf-8"));
36999
37340
  if (typeof parsed.version === "string" && parsed.version.length > 0) return parsed.version;
37000
37341
  } catch {
37001
37342
  }
@@ -37205,7 +37546,7 @@ async function readVersion() {
37205
37546
  let dir = dirname25(here);
37206
37547
  for (let i = 0; i < 6; i++) {
37207
37548
  try {
37208
- const raw2 = await readFile60(join21(dir, "package.json"), "utf-8");
37549
+ const raw2 = await readFile61(join21(dir, "package.json"), "utf-8");
37209
37550
  const parsed = JSON.parse(raw2);
37210
37551
  return typeof parsed.version === "string" ? parsed.version : null;
37211
37552
  } catch {
@@ -37302,7 +37643,7 @@ var REQUIRED_WORKSPACE_FIELDS = [
37302
37643
  ];
37303
37644
  var ISO_DATE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/;
37304
37645
  async function validateAssignmentFile(inputPath, cwd = process.cwd()) {
37305
- const absolute = isAbsolute11(inputPath) ? inputPath : resolve88(cwd, inputPath);
37646
+ const absolute = isAbsolute11(inputPath) ? inputPath : resolve89(cwd, inputPath);
37306
37647
  const errors = [];
37307
37648
  const warnings = [];
37308
37649
  if (!await fileExists(absolute)) {
@@ -37315,7 +37656,7 @@ async function validateAssignmentFile(inputPath, cwd = process.cwd()) {
37315
37656
  }
37316
37657
  let content;
37317
37658
  try {
37318
- content = await readFile61(absolute, "utf-8");
37659
+ content = await readFile62(absolute, "utf-8");
37319
37660
  } catch (err2) {
37320
37661
  return {
37321
37662
  ok: false,
@@ -37682,8 +38023,8 @@ init_assignment_resolver();
37682
38023
  init_frontmatter();
37683
38024
  init_event_emit();
37684
38025
  init_templates();
37685
- import { resolve as resolve89 } from "path";
37686
- import { readFile as readFile62 } from "fs/promises";
38026
+ import { resolve as resolve90 } from "path";
38027
+ import { readFile as readFile63 } from "fs/promises";
37687
38028
  function shortId() {
37688
38029
  return generateId().split("-")[0];
37689
38030
  }
@@ -37714,7 +38055,7 @@ async function commentCommand(target, text, options = {}) {
37714
38055
  if (!isValidSlug(target)) {
37715
38056
  throw new Error(`Invalid assignment slug "${target}".`);
37716
38057
  }
37717
- assignmentDir = resolve89(baseDir, options.project, "assignments", target);
38058
+ assignmentDir = resolve90(baseDir, options.project, "assignments", target);
37718
38059
  assignmentRef = target;
37719
38060
  projectSlug = options.project;
37720
38061
  } else {
@@ -37726,13 +38067,13 @@ async function commentCommand(target, text, options = {}) {
37726
38067
  assignmentRef = resolved.standalone ? resolved.id : resolved.assignmentSlug;
37727
38068
  projectSlug = resolved.projectSlug;
37728
38069
  }
37729
- const commentsPath = resolve89(assignmentDir, "comments.md");
38070
+ const commentsPath = resolve90(assignmentDir, "comments.md");
37730
38071
  const timestamp = nowTimestamp();
37731
38072
  const author = options.author ?? process.env.USER ?? "unknown";
37732
38073
  let currentContent;
37733
38074
  let currentCount = 0;
37734
38075
  if (await fileExists(commentsPath)) {
37735
- currentContent = await readFile62(commentsPath, "utf-8");
38076
+ currentContent = await readFile63(commentsPath, "utf-8");
37736
38077
  const countMatch = currentContent.match(/^entryCount:\s*(\d+)/m);
37737
38078
  if (countMatch) currentCount = parseInt(countMatch[1], 10);
37738
38079
  } else {
@@ -37760,9 +38101,9 @@ ${entry}`;
37760
38101
  }
37761
38102
  await writeFileForce(commentsPath, next);
37762
38103
  try {
37763
- const assignmentMd = resolve89(assignmentDir, "assignment.md");
38104
+ const assignmentMd = resolve90(assignmentDir, "assignment.md");
37764
38105
  if (await fileExists(assignmentMd)) {
37765
- const fm = parseAssignmentFrontmatter(await readFile62(assignmentMd, "utf-8"));
38106
+ const fm = parseAssignmentFrontmatter(await readFile63(assignmentMd, "utf-8"));
37766
38107
  emitEvent({
37767
38108
  assignmentId: fm.id,
37768
38109
  projectSlug,
@@ -37786,7 +38127,7 @@ ${entry}`;
37786
38127
  }
37787
38128
 
37788
38129
  // src/commands/capture.ts
37789
- import { resolve as resolve93, relative as relative4, dirname as dirname26 } from "path";
38130
+ import { resolve as resolve94, relative as relative4, dirname as dirname26 } from "path";
37790
38131
  import { copyFile as copyFile3, mkdir as mkdir12, realpath as realpath2, rm as rm14, stat as stat13, writeFile as writeFile15 } from "fs/promises";
37791
38132
  import { existsSync as existsSync7 } from "fs";
37792
38133
 
@@ -37797,8 +38138,8 @@ init_config2();
37797
38138
  init_slug();
37798
38139
  init_assignment_resolver();
37799
38140
  init_parser();
37800
- import { resolve as resolve90 } from "path";
37801
- import { readFile as readFile63 } from "fs/promises";
38141
+ import { resolve as resolve91 } from "path";
38142
+ import { readFile as readFile64 } from "fs/promises";
37802
38143
  var AssignmentTargetError = class extends Error {
37803
38144
  };
37804
38145
  function classifyContext(ctx) {
@@ -37810,10 +38151,10 @@ function classifyContext(ctx) {
37810
38151
  return "empty";
37811
38152
  }
37812
38153
  async function readAssignmentFrontmatterId(assignmentDir) {
37813
- const path = resolve90(assignmentDir, "assignment.md");
38154
+ const path = resolve91(assignmentDir, "assignment.md");
37814
38155
  if (!await fileExists(path)) return null;
37815
38156
  try {
37816
- const content = await readFile63(path, "utf-8");
38157
+ const content = await readFile64(path, "utf-8");
37817
38158
  const [fm] = extractFrontmatter(content);
37818
38159
  return getField(fm, "id");
37819
38160
  } catch {
@@ -37821,10 +38162,10 @@ async function readAssignmentFrontmatterId(assignmentDir) {
37821
38162
  }
37822
38163
  }
37823
38164
  async function readContextJson(cwd) {
37824
- const path = resolve90(cwd, ".syntaur", "context.json");
38165
+ const path = resolve91(cwd, ".syntaur", "context.json");
37825
38166
  if (!await fileExists(path)) return null;
37826
38167
  try {
37827
- const raw2 = await readFile63(path, "utf-8");
38168
+ const raw2 = await readFile64(path, "utf-8");
37828
38169
  return JSON.parse(raw2);
37829
38170
  } catch {
37830
38171
  return null;
@@ -37845,15 +38186,15 @@ async function resolveAssignmentTarget(input4, opts = {}) {
37845
38186
  if (!isValidSlug(input4)) {
37846
38187
  throw new AssignmentTargetError(`Invalid assignment slug "${input4}".`);
37847
38188
  }
37848
- const projectDir = resolve90(baseDir, opts.project);
37849
- const projectMdPath = resolve90(projectDir, "project.md");
38189
+ const projectDir = resolve91(baseDir, opts.project);
38190
+ const projectMdPath = resolve91(projectDir, "project.md");
37850
38191
  if (!await fileExists(projectDir) || !await fileExists(projectMdPath)) {
37851
38192
  throw new AssignmentTargetError(
37852
38193
  `Project "${opts.project}" not found at ${projectDir}.`
37853
38194
  );
37854
38195
  }
37855
- const assignmentDir = resolve90(projectDir, "assignments", input4);
37856
- const assignmentMdPath2 = resolve90(assignmentDir, "assignment.md");
38196
+ const assignmentDir = resolve91(projectDir, "assignments", input4);
38197
+ const assignmentMdPath2 = resolve91(assignmentDir, "assignment.md");
37857
38198
  if (!await fileExists(assignmentMdPath2)) {
37858
38199
  throw new AssignmentTargetError(
37859
38200
  `Assignment "${input4}" not found in project "${opts.project}".`
@@ -37892,7 +38233,7 @@ async function resolveAssignmentTarget(input4, opts = {}) {
37892
38233
  }
37893
38234
  if (ctx.assignmentDir) {
37894
38235
  const dir = expandHome(ctx.assignmentDir);
37895
- const assignmentMdPath2 = resolve90(dir, "assignment.md");
38236
+ const assignmentMdPath2 = resolve91(dir, "assignment.md");
37896
38237
  if (!await fileExists(assignmentMdPath2)) {
37897
38238
  throw new AssignmentTargetError(
37898
38239
  `.syntaur/context.json points to a missing assignment dir: ${dir}.`
@@ -37921,8 +38262,8 @@ async function resolveAssignmentTarget(input4, opts = {}) {
37921
38262
  `.syntaur/context.json contains invalid slugs: project="${ctx.projectSlug}" assignment="${ctx.assignmentSlug}".`
37922
38263
  );
37923
38264
  }
37924
- const assignmentDir = resolve90(baseDir, ctx.projectSlug, "assignments", ctx.assignmentSlug);
37925
- const assignmentMdPath2 = resolve90(assignmentDir, "assignment.md");
38265
+ const assignmentDir = resolve91(baseDir, ctx.projectSlug, "assignments", ctx.assignmentSlug);
38266
+ const assignmentMdPath2 = resolve91(assignmentDir, "assignment.md");
37926
38267
  if (!await fileExists(assignmentMdPath2)) {
37927
38268
  throw new AssignmentTargetError(
37928
38269
  `.syntaur/context.json points to a missing assignment: ${assignmentDir}.`
@@ -38023,7 +38364,7 @@ async function captureScreenshot(mode) {
38023
38364
 
38024
38365
  // src/utils/asciinema.ts
38025
38366
  import { spawn as spawn9 } from "child_process";
38026
- import { mkdtemp as mkdtemp3, readFile as readFile64, rm as rm11 } from "fs/promises";
38367
+ import { mkdtemp as mkdtemp3, readFile as readFile65, rm as rm11 } from "fs/promises";
38027
38368
  import { tmpdir as tmpdir4 } from "os";
38028
38369
  import { join as join23 } from "path";
38029
38370
  var SAFE_RE = /^[A-Za-z0-9_@%+=:,./-]+$/;
@@ -38086,7 +38427,7 @@ async function captureAsciinema(opts) {
38086
38427
  }
38087
38428
  throw err2;
38088
38429
  }
38089
- const text = await readFile64(castPath, "utf8").catch(() => null);
38430
+ const text = await readFile65(castPath, "utf8").catch(() => null);
38090
38431
  if (text === null) {
38091
38432
  throw new Error(
38092
38433
  `asciinema produced no cast file at ${castPath} (exit ${exitCode}). Try running 'asciinema rec ${castPath}' directly to diagnose.`
@@ -38114,9 +38455,9 @@ async function captureAsciinema(opts) {
38114
38455
  // src/utils/recording.ts
38115
38456
  init_paths();
38116
38457
  import { spawn as spawn10 } from "child_process";
38117
- import { mkdir as mkdir11, mkdtemp as mkdtemp4, open as open6, readFile as readFile65, rm as rm12, stat as stat12, unlink as unlink12, writeFile as writeFile14 } from "fs/promises";
38458
+ import { mkdir as mkdir11, mkdtemp as mkdtemp4, open as open6, readFile as readFile66, rm as rm12, stat as stat12, unlink as unlink12, writeFile as writeFile14 } from "fs/promises";
38118
38459
  import { tmpdir as tmpdir5 } from "os";
38119
- import { join as join24, resolve as resolve91 } from "path";
38460
+ import { join as join24, resolve as resolve92 } from "path";
38120
38461
  import { setTimeout as sleep } from "timers/promises";
38121
38462
  function sigintPollIntervalMs() {
38122
38463
  const raw2 = process.env.SYNTAUR_RECORDING_POLL_INTERVAL_MS;
@@ -38137,13 +38478,13 @@ function sigtermWaitMs() {
38137
38478
  return Number.isFinite(parsed) && parsed >= 0 ? parsed : 1e3;
38138
38479
  }
38139
38480
  function pidfilePath() {
38140
- return resolve91(syntaurRoot(), "recording.pid");
38481
+ return resolve92(syntaurRoot(), "recording.pid");
38141
38482
  }
38142
38483
  function logPath2() {
38143
- return resolve91(syntaurRoot(), "recording.log");
38484
+ return resolve92(syntaurRoot(), "recording.log");
38144
38485
  }
38145
38486
  function sidecarPath() {
38146
- return resolve91(syntaurRoot(), "recording.json");
38487
+ return resolve92(syntaurRoot(), "recording.json");
38147
38488
  }
38148
38489
  function ffmpegArgs(device, fps, mp4Path) {
38149
38490
  return [
@@ -38188,7 +38529,7 @@ async function acquirePidfile(pidfile) {
38188
38529
  } catch (err2) {
38189
38530
  if (err2.code !== "EEXIST") throw err2;
38190
38531
  if (attempt === 1) throw err2;
38191
- const existing = (await readFile65(pidfile, "utf-8").catch(() => "")).trim();
38532
+ const existing = (await readFile66(pidfile, "utf-8").catch(() => "")).trim();
38192
38533
  if (existing.startsWith(STARTING_SENTINEL_PREFIX)) {
38193
38534
  const parentPidRaw = existing.slice(STARTING_SENTINEL_PREFIX.length);
38194
38535
  const parentPid = Number.parseInt(parentPidRaw, 10);
@@ -38290,7 +38631,7 @@ async function startRecording(input4) {
38290
38631
  logHandle = null;
38291
38632
  if (warmupMs > 0) await sleep(warmupMs);
38292
38633
  if (!await isProcessAlive(pid)) {
38293
- const tail = await readFile65(log, "utf-8").then((s) => s.split("\n").slice(-20).join("\n")).catch(() => "");
38634
+ const tail = await readFile66(log, "utf-8").then((s) => s.split("\n").slice(-20).join("\n")).catch(() => "");
38294
38635
  acquiredPid = null;
38295
38636
  throw new Error(
38296
38637
  `ffmpeg exited during startup \u2014 likely macOS Screen Recording permission missing. Grant access to your terminal in System Settings \u2192 Privacy & Security \u2192 Screen Recording, then retry. Log: ${log}
@@ -38347,7 +38688,7 @@ ${tail}`
38347
38688
  async function stopRecording() {
38348
38689
  const pidfile = pidfilePath();
38349
38690
  const sidecar = sidecarPath();
38350
- const pidRaw = await readFile65(pidfile, "utf-8").catch(() => null);
38691
+ const pidRaw = await readFile66(pidfile, "utf-8").catch(() => null);
38351
38692
  if (pidRaw === null) {
38352
38693
  throw new Error(
38353
38694
  `No active recording found (no pidfile at ${pidfile}). Did you run --start?`
@@ -38357,7 +38698,7 @@ async function stopRecording() {
38357
38698
  if (!Number.isInteger(pid) || pid <= 0) {
38358
38699
  throw new Error(`Pidfile at ${pidfile} is corrupt (got "${pidRaw}").`);
38359
38700
  }
38360
- const sidecarRaw = await readFile65(sidecar, "utf-8").catch(() => null);
38701
+ const sidecarRaw = await readFile66(sidecar, "utf-8").catch(() => null);
38361
38702
  if (sidecarRaw === null) {
38362
38703
  throw new Error(
38363
38704
  `No recording sidecar at ${sidecar}. The recording state is inconsistent \u2014 delete ${pidfile} and re-run --start.`
@@ -38422,7 +38763,7 @@ async function stopRecording() {
38422
38763
  // src/db/proof-db.ts
38423
38764
  init_paths();
38424
38765
  import Database6 from "better-sqlite3";
38425
- import { resolve as resolve92 } from "path";
38766
+ import { resolve as resolve93 } from "path";
38426
38767
  var db5 = null;
38427
38768
  var PROOF_SCHEMA_VERSION = "1";
38428
38769
  var SCHEMA_SQL5 = `
@@ -38442,7 +38783,7 @@ CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT);
38442
38783
  `;
38443
38784
  function initProofDb(dbPath) {
38444
38785
  if (db5) return db5;
38445
- const finalPath = dbPath ?? resolve92(syntaurRoot(), "syntaur.db");
38786
+ const finalPath = dbPath ?? resolve93(syntaurRoot(), "syntaur.db");
38446
38787
  db5 = new Database6(finalPath);
38447
38788
  db5.pragma("journal_mode = WAL");
38448
38789
  db5.exec(SCHEMA_SQL5);
@@ -38490,7 +38831,7 @@ function listArtifactsByAssignment(assignmentId) {
38490
38831
 
38491
38832
  // src/utils/transcribers/elevenlabs.ts
38492
38833
  import { spawn as spawn11 } from "child_process";
38493
- import { mkdtemp as mkdtemp5, readFile as readFile66, rm as rm13 } from "fs/promises";
38834
+ import { mkdtemp as mkdtemp5, readFile as readFile67, rm as rm13 } from "fs/promises";
38494
38835
  import { tmpdir as tmpdir6 } from "os";
38495
38836
  import { join as join25 } from "path";
38496
38837
  var SCRIBE_URL = "https://api.elevenlabs.io/v1/speech-to-text";
@@ -38554,7 +38895,7 @@ async function extractAudio(videoAbsPath, wavOut) {
38554
38895
  throw new TranscribeFfmpegError(`ffmpeg failed (exit ${result.code}): ${tail}`);
38555
38896
  }
38556
38897
  async function callScribe(wavPath, apiKey, opts) {
38557
- const audio = await readFile66(wavPath);
38898
+ const audio = await readFile67(wavPath);
38558
38899
  const form = new FormData();
38559
38900
  form.set("file", new Blob([new Uint8Array(audio)], { type: "audio/wav" }), "audio.wav");
38560
38901
  form.set("model_id", "scribe_v1");
@@ -38870,7 +39211,7 @@ async function captureCommand(target, options = {}) {
38870
39211
  });
38871
39212
  }
38872
39213
  if (options.file) {
38873
- const expanded = options.file.startsWith("~/") ? resolve93(process.env.HOME ?? "", options.file.slice(2)) : resolve93(options.file);
39214
+ const expanded = options.file.startsWith("~/") ? resolve94(process.env.HOME ?? "", options.file.slice(2)) : resolve94(options.file);
38874
39215
  if (!await fileExists(expanded)) {
38875
39216
  throw new Error(`--file does not exist: ${options.file}`);
38876
39217
  }
@@ -38911,7 +39252,7 @@ async function captureCommand(target, options = {}) {
38911
39252
  }
38912
39253
  initProofDb();
38913
39254
  const subdir = criterionIndex === null ? "untagged" : String(criterionIndex);
38914
- const destDir = resolve93(proofDir(resolved.assignmentDir), subdir);
39255
+ const destDir = resolve94(proofDir(resolved.assignmentDir), subdir);
38915
39256
  if (resolvedSource) await mkdir12(destDir, { recursive: true });
38916
39257
  const ext = resolvedSource ? extensionForKind(kind) : null;
38917
39258
  let id = null;
@@ -38920,7 +39261,7 @@ async function captureCommand(target, options = {}) {
38920
39261
  let lastErr = null;
38921
39262
  for (let attempt = 0; attempt < MAX_ID_RETRIES; attempt += 1) {
38922
39263
  const candidate = generateArtifactId();
38923
- const candidateAbsPath = resolvedSource && ext ? resolve93(destDir, `${candidate}.${ext}`) : null;
39264
+ const candidateAbsPath = resolvedSource && ext ? resolve94(destDir, `${candidate}.${ext}`) : null;
38924
39265
  const candidateRel = candidateAbsPath ? relative4(resolved.assignmentDir, candidateAbsPath) : null;
38925
39266
  try {
38926
39267
  insertArtifact({
@@ -38964,7 +39305,7 @@ async function captureCommand(target, options = {}) {
38964
39305
  }
38965
39306
  }
38966
39307
  if (options.transcribe && kind === "video" && absPath && id) {
38967
- const sidecarPath2 = resolve93(destDir, `${id}.transcript.md`);
39308
+ const sidecarPath2 = resolve94(destDir, `${id}.transcript.md`);
38968
39309
  if (existsSync7(sidecarPath2)) {
38969
39310
  console.warn(
38970
39311
  `transcript: ${sidecarPath2} already exists, skipping (delete to re-transcribe)`
@@ -38996,7 +39337,7 @@ async function captureCommand(target, options = {}) {
38996
39337
  const tagSuffix = criterionIndex === null ? "untagged" : `criterion ${criterionIndex}`;
38997
39338
  console.log(`Captured artifact ${id} (${kind}) for ${ref} \u2014 ${tagSuffix}.`);
38998
39339
  if (relativeFilePath) {
38999
- console.log(` file: ${resolve93(resolved.assignmentDir, relativeFilePath)}`);
39340
+ console.log(` file: ${resolve94(resolved.assignmentDir, relativeFilePath)}`);
39000
39341
  }
39001
39342
  } catch (err2) {
39002
39343
  if (options.stop && kind === "video" && shelloutCleanup && resolvedSource) {
@@ -39019,8 +39360,8 @@ async function captureCommand(target, options = {}) {
39019
39360
 
39020
39361
  // src/commands/proof.ts
39021
39362
  import { Command as Command6 } from "commander";
39022
- import { readFile as readFile67, writeFile as writeFile16, rename as rename10, stat as stat14 } from "fs/promises";
39023
- import { resolve as resolve94, relative as relative5, isAbsolute as isAbsolute12, dirname as dirname27 } from "path";
39363
+ import { readFile as readFile68, writeFile as writeFile16, rename as rename10, stat as stat14 } from "fs/promises";
39364
+ import { resolve as resolve95, relative as relative5, isAbsolute as isAbsolute12, dirname as dirname27 } from "path";
39024
39365
  import { randomBytes as randomBytes4 } from "crypto";
39025
39366
 
39026
39367
  // src/utils/acceptance-criteria-parse.ts
@@ -39260,11 +39601,11 @@ function renderProofHtml(params2, inlineFiles = /* @__PURE__ */ new Map(), trans
39260
39601
 
39261
39602
  // src/commands/proof.ts
39262
39603
  async function readAssignmentMeta(assignmentDir) {
39263
- const path = resolve94(assignmentDir, "assignment.md");
39604
+ const path = resolve95(assignmentDir, "assignment.md");
39264
39605
  if (!await fileExists(path)) {
39265
39606
  return { title: "", body: "" };
39266
39607
  }
39267
- const content = await readFile67(path, "utf-8");
39608
+ const content = await readFile68(path, "utf-8");
39268
39609
  const fmMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);
39269
39610
  let title = "";
39270
39611
  if (fmMatch) {
@@ -39311,7 +39652,7 @@ async function loadInlineFiles(rows, assignmentDir) {
39311
39652
  for (const r of rows) {
39312
39653
  if (!r.file_path) continue;
39313
39654
  if (r.kind !== "http" && r.kind !== "text") continue;
39314
- const abs = resolve94(assignmentDir, r.file_path);
39655
+ const abs = resolve95(assignmentDir, r.file_path);
39315
39656
  if (!isWithin(proofRoot, abs)) {
39316
39657
  out.set(r.file_path, null);
39317
39658
  continue;
@@ -39326,7 +39667,7 @@ async function loadInlineFiles(rows, assignmentDir) {
39326
39667
  continue;
39327
39668
  }
39328
39669
  try {
39329
- out.set(r.file_path, await readFile67(abs, "utf-8"));
39670
+ out.set(r.file_path, await readFile68(abs, "utf-8"));
39330
39671
  } catch {
39331
39672
  out.set(r.file_path, null);
39332
39673
  }
@@ -39338,14 +39679,14 @@ async function loadTranscriptSidecars(rows, assignmentDir) {
39338
39679
  const proofRoot = proofDir(assignmentDir);
39339
39680
  for (const r of rows) {
39340
39681
  if (r.kind !== "video" || !r.file_path) continue;
39341
- const videoAbs = resolve94(assignmentDir, r.file_path);
39342
- const sidecar = resolve94(dirname27(videoAbs), `${r.id}.transcript.md`);
39682
+ const videoAbs = resolve95(assignmentDir, r.file_path);
39683
+ const sidecar = resolve95(dirname27(videoAbs), `${r.id}.transcript.md`);
39343
39684
  if (!isWithin(proofRoot, sidecar)) continue;
39344
39685
  if (!await fileExists(sidecar)) continue;
39345
39686
  const st = await stat14(sidecar);
39346
39687
  if (st.size > INLINE_TEXT_LIMIT_BYTES) continue;
39347
39688
  try {
39348
- out.set(r.id, await readFile67(sidecar, "utf-8"));
39689
+ out.set(r.id, await readFile68(sidecar, "utf-8"));
39349
39690
  } catch {
39350
39691
  }
39351
39692
  }
@@ -39379,8 +39720,8 @@ async function proofBuildCommand(target, options = {}) {
39379
39720
  };
39380
39721
  const md = renderProofMarkdown(renderParams);
39381
39722
  const html = renderProofHtml(renderParams, inlineFiles, transcriptSidecars);
39382
- const mdPath = resolve94(resolved.assignmentDir, "proof.md");
39383
- const htmlPath = resolve94(resolved.assignmentDir, "proof.html");
39723
+ const mdPath = resolve95(resolved.assignmentDir, "proof.md");
39724
+ const htmlPath = resolve95(resolved.assignmentDir, "proof.html");
39384
39725
  await atomicWrite(mdPath, md);
39385
39726
  await atomicWrite(htmlPath, html);
39386
39727
  console.log(`Wrote ${htmlPath}`);
@@ -39910,7 +40251,7 @@ function isScheduledSessionLive(sessionId, launchPid) {
39910
40251
  import { execFileSync as execFileSync5 } from "child_process";
39911
40252
  import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync3, rmSync as rmSync2, realpathSync as realpathSync4, openSync as openSync2, closeSync as closeSync2 } from "fs";
39912
40253
  import { homedir as homedir16, userInfo } from "os";
39913
- import { dirname as dirname28, join as join26, resolve as resolve95 } from "path";
40254
+ import { dirname as dirname28, join as join26, resolve as resolve96 } from "path";
39914
40255
  var LAUNCH_AGENT_LABEL = "com.syntaur.schedule.tick";
39915
40256
  var LaunchAgentRefusalError = class extends Error {
39916
40257
  constructor(message) {
@@ -39964,7 +40305,7 @@ function absolutize(p) {
39964
40305
  try {
39965
40306
  return realpathSync4(p);
39966
40307
  } catch {
39967
- return resolve95(p);
40308
+ return resolve96(p);
39968
40309
  }
39969
40310
  }
39970
40311
  function defaultRun(command, args) {
@@ -40320,8 +40661,8 @@ init_slug();
40320
40661
  init_timestamp();
40321
40662
  init_assignment_resolver();
40322
40663
  init_assignment_todos();
40323
- import { resolve as resolve96 } from "path";
40324
- import { readFile as readFile68 } from "fs/promises";
40664
+ import { resolve as resolve97 } from "path";
40665
+ import { readFile as readFile69 } from "fs/promises";
40325
40666
  async function requestCommand(target, text, options = {}) {
40326
40667
  if (!text || !text.trim()) {
40327
40668
  throw new Error("Request text cannot be empty.");
@@ -40337,7 +40678,7 @@ async function requestCommand(target, text, options = {}) {
40337
40678
  if (!isValidSlug(target)) {
40338
40679
  throw new Error(`Invalid assignment slug "${target}".`);
40339
40680
  }
40340
- assignmentDir = resolve96(baseDir, options.project, "assignments", target);
40681
+ assignmentDir = resolve97(baseDir, options.project, "assignments", target);
40341
40682
  targetRef = target;
40342
40683
  } else {
40343
40684
  const resolved = await resolveAssignmentById(baseDir, assignmentsDir(), target);
@@ -40347,12 +40688,12 @@ async function requestCommand(target, text, options = {}) {
40347
40688
  assignmentDir = resolved.assignmentDir;
40348
40689
  targetRef = resolved.standalone ? resolved.id : resolved.assignmentSlug;
40349
40690
  }
40350
- const assignmentMdPath2 = resolve96(assignmentDir, "assignment.md");
40691
+ const assignmentMdPath2 = resolve97(assignmentDir, "assignment.md");
40351
40692
  if (!await fileExists(assignmentMdPath2)) {
40352
40693
  throw new Error(`assignment.md not found at ${assignmentMdPath2}`);
40353
40694
  }
40354
40695
  const source = options.from ?? process.env.SYNTAUR_ASSIGNMENT ?? "unknown";
40355
- let content = await readFile68(assignmentMdPath2, "utf-8");
40696
+ let content = await readFile69(assignmentMdPath2, "utf-8");
40356
40697
  content = appendTodosToAssignmentBody(content, [
40357
40698
  { description: `${text.trim()} (from: ${source})` }
40358
40699
  ]);
@@ -40366,13 +40707,13 @@ init_fs();
40366
40707
  init_paths();
40367
40708
  init_config2();
40368
40709
  import { Command as Command10 } from "commander";
40369
- import { readFile as readFile69, readdir as readdir34 } from "fs/promises";
40370
- import { resolve as resolve97 } from "path";
40710
+ import { readFile as readFile70, readdir as readdir34 } from "fs/promises";
40711
+ import { resolve as resolve98 } from "path";
40371
40712
  async function readContextAssignmentDir(cwd) {
40372
- const path = resolve97(cwd, ".syntaur", "context.json");
40713
+ const path = resolve98(cwd, ".syntaur", "context.json");
40373
40714
  if (!await fileExists(path)) return null;
40374
40715
  try {
40375
- const raw2 = await readFile69(path, "utf-8");
40716
+ const raw2 = await readFile70(path, "utf-8");
40376
40717
  const ctx = JSON.parse(raw2);
40377
40718
  if (typeof ctx.assignmentDir === "string" && ctx.assignmentDir.length > 0) {
40378
40719
  return ctx.assignmentDir;
@@ -40386,9 +40727,9 @@ async function resolveAssignmentDir(opts) {
40386
40727
  const cwd = opts.cwd ?? process.cwd();
40387
40728
  if (opts.assignment) {
40388
40729
  if (opts.project) {
40389
- return resolve97((await readConfig()).defaultProjectDir, opts.project, "assignments", opts.assignment);
40730
+ return resolve98((await readConfig()).defaultProjectDir, opts.project, "assignments", opts.assignment);
40390
40731
  }
40391
- return resolve97(assignmentsDir(), opts.assignment);
40732
+ return resolve98(assignmentsDir(), opts.assignment);
40392
40733
  }
40393
40734
  const fromCtx = await readContextAssignmentDir(cwd);
40394
40735
  if (fromCtx) return fromCtx;
@@ -40584,17 +40925,17 @@ async function runPlanCreate(options) {
40584
40925
  if (!await fileExists(assignmentDir)) {
40585
40926
  throw new Error(`Assignment directory does not exist: ${assignmentDir}`);
40586
40927
  }
40587
- const assignmentMdPath2 = resolve97(assignmentDir, "assignment.md");
40928
+ const assignmentMdPath2 = resolve98(assignmentDir, "assignment.md");
40588
40929
  if (!await fileExists(assignmentMdPath2)) {
40589
40930
  throw new Error(`Missing assignment.md at: ${assignmentMdPath2}`);
40590
40931
  }
40591
- const planPath = resolve97(assignmentDir, "plan.md");
40932
+ const planPath = resolve98(assignmentDir, "plan.md");
40592
40933
  if (await fileExists(planPath) && !options.force) {
40593
40934
  throw new Error(
40594
40935
  "plan.md already exists. Use --force to overwrite, or `syntaur plan version` to create the next version."
40595
40936
  );
40596
40937
  }
40597
- const assignmentMd = await readFile69(assignmentMdPath2, "utf-8");
40938
+ const assignmentMd = await readFile70(assignmentMdPath2, "utf-8");
40598
40939
  const slugMatch = assignmentMd.match(/^slug:\s*(.+?)\s*$/m);
40599
40940
  const slug = slugMatch ? slugMatch[1].trim() : assignmentDir.split("/").pop() ?? "";
40600
40941
  await writeFileForce(planPath, buildInitialPlanStub(slug));
@@ -40614,7 +40955,7 @@ async function runPlanVersion(options) {
40614
40955
  if (!await fileExists(assignmentDir)) {
40615
40956
  throw new Error(`Assignment directory does not exist: ${assignmentDir}`);
40616
40957
  }
40617
- const assignmentMdPath2 = resolve97(assignmentDir, "assignment.md");
40958
+ const assignmentMdPath2 = resolve98(assignmentDir, "assignment.md");
40618
40959
  if (!await fileExists(assignmentMdPath2)) {
40619
40960
  throw new Error(`Missing assignment.md at: ${assignmentMdPath2}`);
40620
40961
  }
@@ -40626,15 +40967,15 @@ async function runPlanVersion(options) {
40626
40967
  }
40627
40968
  const current = planFiles[planFiles.length - 1];
40628
40969
  const next = nextPlanFileName(current.version);
40629
- const newPath = resolve97(assignmentDir, next.fileName);
40970
+ const newPath = resolve98(assignmentDir, next.fileName);
40630
40971
  if (await fileExists(newPath) && !options.force) {
40631
40972
  throw new Error(`${next.fileName} already exists. Use --force to overwrite.`);
40632
40973
  }
40633
- const assignmentMd = await readFile69(assignmentMdPath2, "utf-8");
40974
+ const assignmentMd = await readFile70(assignmentMdPath2, "utf-8");
40634
40975
  const slugMatch = assignmentMd.match(/^slug:\s*(.+?)\s*$/m);
40635
40976
  const slug = slugMatch ? slugMatch[1].trim() : assignmentDir.split("/").pop() ?? "";
40636
- const oldPlanPath = resolve97(assignmentDir, current.fileName);
40637
- const oldPlanContent = await readFile69(oldPlanPath, "utf-8");
40977
+ const oldPlanPath = resolve98(assignmentDir, current.fileName);
40978
+ const oldPlanContent = await readFile70(oldPlanPath, "utf-8");
40638
40979
  const oldBody = oldPlanContent.replace(/^---[\s\S]*?\n---\n?/, "");
40639
40980
  const carriedTodos = extractUncheckedTodos(oldBody);
40640
40981
  const stub = buildNewPlanStub({
@@ -40704,26 +41045,26 @@ init_cwd();
40704
41045
  init_session_db();
40705
41046
  init_agent_sessions();
40706
41047
  import { Command as Command11 } from "commander";
40707
- import { readFile as readFile70, readdir as readdir35, stat as stat15 } from "fs/promises";
40708
- import { resolve as resolve98 } from "path";
41048
+ import { readFile as readFile71, readdir as readdir35, stat as stat15 } from "fs/promises";
41049
+ import { resolve as resolve99 } from "path";
40709
41050
  async function readContext(cwd) {
40710
- const path = resolve98(cwd, ".syntaur", "context.json");
41051
+ const path = resolve99(cwd, ".syntaur", "context.json");
40711
41052
  if (!await fileExists(path)) return null;
40712
41053
  try {
40713
- const raw2 = await readFile70(path, "utf-8");
41054
+ const raw2 = await readFile71(path, "utf-8");
40714
41055
  return JSON.parse(raw2);
40715
41056
  } catch {
40716
41057
  return null;
40717
41058
  }
40718
41059
  }
40719
41060
  async function findLatestSessionSummary(assignmentDir) {
40720
- const sessionsRoot = resolve98(assignmentDir, "sessions");
41061
+ const sessionsRoot = resolve99(assignmentDir, "sessions");
40721
41062
  if (!await fileExists(sessionsRoot)) return null;
40722
41063
  const entries = await readdir35(sessionsRoot, { withFileTypes: true });
40723
41064
  let best = null;
40724
41065
  for (const entry of entries) {
40725
41066
  if (!entry.isDirectory()) continue;
40726
- const summaryPath = resolve98(sessionsRoot, entry.name, "summary.md");
41067
+ const summaryPath = resolve99(sessionsRoot, entry.name, "summary.md");
40727
41068
  if (!await fileExists(summaryPath)) continue;
40728
41069
  const st = await stat15(summaryPath);
40729
41070
  if (best === null || st.mtime.getTime() > best.mtime.getTime()) {
@@ -40733,9 +41074,9 @@ async function findLatestSessionSummary(assignmentDir) {
40733
41074
  return best;
40734
41075
  }
40735
41076
  async function findOpenHandoff(assignmentDir) {
40736
- const handoffPath = resolve98(assignmentDir, "handoff.md");
41077
+ const handoffPath = resolve99(assignmentDir, "handoff.md");
40737
41078
  if (!await fileExists(handoffPath)) return null;
40738
- const content = await readFile70(handoffPath, "utf-8");
41079
+ const content = await readFile71(handoffPath, "utf-8");
40739
41080
  const body = content.replace(/^---[\s\S]*?\n---\n?/, "").trim();
40740
41081
  if (body.length === 0) return null;
40741
41082
  if (/^<!--[\s\S]*-->$/.test(body)) return null;
@@ -40830,7 +41171,7 @@ async function resolveSaveTarget(options, cwd) {
40830
41171
  let slug;
40831
41172
  const ctx = await readContext(cwd);
40832
41173
  if (options.assignment) {
40833
- assignmentDir = options.project ? resolve98((await readConfig()).defaultProjectDir, options.project, "assignments", options.assignment) : resolve98(assignmentsDir(), options.assignment);
41174
+ assignmentDir = options.project ? resolve99((await readConfig()).defaultProjectDir, options.project, "assignments", options.assignment) : resolve99(assignmentsDir(), options.assignment);
40834
41175
  slug = options.assignment;
40835
41176
  } else {
40836
41177
  if (!ctx?.assignmentDir) {
@@ -40887,21 +41228,21 @@ function extractCreated(content) {
40887
41228
  }
40888
41229
  async function runSessionSave(options, cwd = process.cwd(), body) {
40889
41230
  const { assignmentDir, slug, sessionId } = await resolveSaveTarget(options, cwd);
40890
- if (!await fileExists(resolve98(assignmentDir, "assignment.md"))) {
41231
+ if (!await fileExists(resolve99(assignmentDir, "assignment.md"))) {
40891
41232
  throw new Error(`No assignment found at ${assignmentDir} (missing assignment.md).`);
40892
41233
  }
40893
- const sessionDir = resolve98(assignmentDir, "sessions", sessionId);
40894
- const summaryPath = resolve98(sessionDir, "summary.md");
41234
+ const sessionDir = resolve99(assignmentDir, "sessions", sessionId);
41235
+ const summaryPath = resolve99(sessionDir, "summary.md");
40895
41236
  const now = nowTimestamp();
40896
41237
  let created = now;
40897
41238
  if (await fileExists(summaryPath)) {
40898
- const existing = await readFile70(summaryPath, "utf-8");
41239
+ const existing = await readFile71(summaryPath, "utf-8");
40899
41240
  created = extractCreated(existing) ?? now;
40900
41241
  }
40901
41242
  let sectionBody2 = body;
40902
41243
  if (sectionBody2 === void 0) {
40903
41244
  if (options.fromFile) {
40904
- sectionBody2 = await readFile70(resolve98(cwd, options.fromFile), "utf-8");
41245
+ sectionBody2 = await readFile71(resolve99(cwd, options.fromFile), "utf-8");
40905
41246
  } else {
40906
41247
  sectionBody2 = await readStdin();
40907
41248
  }
@@ -40937,7 +41278,7 @@ async function runSessionRegister(rawStdin, options = {}, deps = {}) {
40937
41278
  if (!isSafeSessionId(sessionId) || !cwd) return result;
40938
41279
  result.sessionId = sessionId;
40939
41280
  const transcriptPath = payload.transcript_path ?? "";
40940
- const contextPath = resolve98(cwd, ".syntaur", "context.json");
41281
+ const contextPath = resolve99(cwd, ".syntaur", "context.json");
40941
41282
  const hasContextFile = await fileExists(contextPath);
40942
41283
  const ctx = hasContextFile ? await readContext(cwd) : null;
40943
41284
  if (ctx) {
@@ -41083,8 +41424,8 @@ sessionCommand.command("resolve-id").description(
41083
41424
  // src/commands/worktree.ts
41084
41425
  init_git_worktree();
41085
41426
  import { Command as Command12 } from "commander";
41086
- import { readFile as readFile71 } from "fs/promises";
41087
- import { resolve as resolve100 } from "path";
41427
+ import { readFile as readFile72 } from "fs/promises";
41428
+ import { resolve as resolve101 } from "path";
41088
41429
  init_fs();
41089
41430
  init_paths();
41090
41431
  init_config2();
@@ -41093,12 +41434,12 @@ init_state_machine();
41093
41434
 
41094
41435
  // src/utils/path-canon.ts
41095
41436
  import { realpathSync as realpathSync5 } from "fs";
41096
- import { resolve as resolve99 } from "path";
41437
+ import { resolve as resolve100 } from "path";
41097
41438
  function canonicalPath(p) {
41098
41439
  try {
41099
- return realpathSync5(resolve99(p));
41440
+ return realpathSync5(resolve100(p));
41100
41441
  } catch {
41101
- return resolve99(p).replace(/\/+$/, "");
41442
+ return resolve100(p).replace(/\/+$/, "");
41102
41443
  }
41103
41444
  }
41104
41445
 
@@ -41126,10 +41467,10 @@ function countSessionsByPath(dbPath, paths) {
41126
41467
  init_timestamp();
41127
41468
  init_frontmatter();
41128
41469
  async function readContext2(cwd) {
41129
- const path = resolve100(cwd, ".syntaur", "context.json");
41470
+ const path = resolve101(cwd, ".syntaur", "context.json");
41130
41471
  if (!await fileExists(path)) return null;
41131
41472
  try {
41132
- return JSON.parse(await readFile71(path, "utf-8"));
41473
+ return JSON.parse(await readFile72(path, "utf-8"));
41133
41474
  } catch {
41134
41475
  return null;
41135
41476
  }
@@ -41138,12 +41479,12 @@ async function resolveAssignmentPath2(opts) {
41138
41479
  if (opts.assignment) {
41139
41480
  if (opts.project) {
41140
41481
  const projectsDir2 = (await readConfig()).defaultProjectDir;
41141
- return resolve100(projectsDir2, opts.project, "assignments", opts.assignment, "assignment.md");
41482
+ return resolve101(projectsDir2, opts.project, "assignments", opts.assignment, "assignment.md");
41142
41483
  }
41143
- return resolve100(assignmentsDir(), opts.assignment, "assignment.md");
41484
+ return resolve101(assignmentsDir(), opts.assignment, "assignment.md");
41144
41485
  }
41145
41486
  const ctx = await readContext2(opts.cwd);
41146
- if (ctx?.assignmentDir) return resolve100(ctx.assignmentDir, "assignment.md");
41487
+ if (ctx?.assignmentDir) return resolve101(ctx.assignmentDir, "assignment.md");
41147
41488
  throw new Error(
41148
41489
  "No active assignment. Pass --assignment <slug> [--project <slug>] or run from a workspace with .syntaur/context.json."
41149
41490
  );
@@ -41154,7 +41495,7 @@ async function runWorktreeCreate(options, cwd = process.cwd()) {
41154
41495
  }
41155
41496
  const repository = options.repository ?? cwd;
41156
41497
  const parentBranch = options.parentBranch ?? "main";
41157
- const worktreePath = options.worktreePath ?? resolve100(repository, ".worktrees", options.branch);
41498
+ const worktreePath = options.worktreePath ?? resolve101(repository, ".worktrees", options.branch);
41158
41499
  const assignmentPath = await resolveAssignmentPath2({
41159
41500
  assignment: options.assignment,
41160
41501
  project: options.project,
@@ -41184,7 +41525,7 @@ async function runWorktreeRemove(options, cwd = process.cwd()) {
41184
41525
  if (!await fileExists(assignmentPath)) {
41185
41526
  throw new Error(`Assignment file not found: ${assignmentPath}`);
41186
41527
  }
41187
- const original = await readFile71(assignmentPath, "utf-8");
41528
+ const original = await readFile72(assignmentPath, "utf-8");
41188
41529
  const fm = parseAssignmentFrontmatter(original);
41189
41530
  const repository = options.repository ?? fm.workspace.repository ?? void 0;
41190
41531
  const worktreePath = fm.workspace.worktreePath ?? void 0;
@@ -41250,7 +41591,7 @@ async function runWorktreeGc(options, cwd = process.cwd()) {
41250
41591
  const owners = /* @__PURE__ */ new Map();
41251
41592
  for (const entry of walk.withAssignmentMd) {
41252
41593
  try {
41253
- const content = await readFile71(resolve100(entry.assignmentDir, "assignment.md"), "utf-8");
41594
+ const content = await readFile72(resolve101(entry.assignmentDir, "assignment.md"), "utf-8");
41254
41595
  const fm = parseAssignmentFrontmatter(content);
41255
41596
  const wp = fm.workspace?.worktreePath;
41256
41597
  if (!wp) continue;
@@ -41272,7 +41613,7 @@ async function runWorktreeGc(options, cwd = process.cwd()) {
41272
41613
  const repoTop = rt ? canonicalPath(rt) : null;
41273
41614
  const cwdTop = ct ? canonicalPath(ct) : null;
41274
41615
  const mainPath = entries.length > 0 ? canonicalPath(entries[0].worktreePath) : null;
41275
- const dbPath = resolve100(syntaurRoot(), "syntaur.db");
41616
+ const dbPath = resolve101(syntaurRoot(), "syntaur.db");
41276
41617
  const candidates = [];
41277
41618
  for (const entry of entries) {
41278
41619
  const canon = canonicalPath(entry.worktreePath);
@@ -41491,8 +41832,8 @@ worktreeCommand.command("gc").description(
41491
41832
  // src/commands/open.ts
41492
41833
  init_fs();
41493
41834
  import { Command as Command13 } from "commander";
41494
- import { readFile as readFile72 } from "fs/promises";
41495
- import { resolve as resolve101 } from "path";
41835
+ import { readFile as readFile73 } from "fs/promises";
41836
+ import { resolve as resolve102 } from "path";
41496
41837
  init_frontmatter();
41497
41838
  init_config2();
41498
41839
  init_paths();
@@ -41546,13 +41887,13 @@ function openInTerminal(path, config) {
41546
41887
  // src/commands/open.ts
41547
41888
  async function runOpen(assignmentArg, options) {
41548
41889
  const resolved = options.id ? await resolveAssignmentTarget(options.id, {}) : await resolveAssignmentTarget(assignmentArg, { project: options.project });
41549
- const assignmentPath = resolve101(resolved.assignmentDir, "assignment.md");
41890
+ const assignmentPath = resolve102(resolved.assignmentDir, "assignment.md");
41550
41891
  if (!await fileExists(assignmentPath)) {
41551
41892
  throw new SyntaurError(`Assignment file not found: ${assignmentPath}`, {
41552
41893
  remediation: "check the assignment slug or --id"
41553
41894
  });
41554
41895
  }
41555
- const fm = parseAssignmentFrontmatter(await readFile72(assignmentPath, "utf-8"));
41896
+ const fm = parseAssignmentFrontmatter(await readFile73(assignmentPath, "utf-8"));
41556
41897
  const worktreePath = fm.workspace?.worktreePath;
41557
41898
  if (!worktreePath) {
41558
41899
  throw new SyntaurError("No worktree recorded for this assignment.", {
@@ -41617,14 +41958,14 @@ init_config2();
41617
41958
  init_fs();
41618
41959
  init_slug();
41619
41960
  import { Command as Command14 } from "commander";
41620
- import { resolve as resolve103 } from "path";
41621
- import { readFile as readFile74, readdir as readdir37, rm as rm15 } from "fs/promises";
41961
+ import { resolve as resolve104 } from "path";
41962
+ import { readFile as readFile75, readdir as readdir37, rm as rm15 } from "fs/promises";
41622
41963
 
41623
41964
  // src/utils/project-indexes.ts
41624
41965
  init_parser();
41625
41966
  init_fs();
41626
- import { readdir as readdir36, readFile as readFile73 } from "fs/promises";
41627
- import { resolve as resolve102 } from "path";
41967
+ import { readdir as readdir36, readFile as readFile74 } from "fs/promises";
41968
+ import { resolve as resolve103 } from "path";
41628
41969
  function nowIso3() {
41629
41970
  return (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
41630
41971
  }
@@ -41643,7 +41984,7 @@ function joinList(items) {
41643
41984
  return items.length === 0 ? "\u2014" : items.map(escapeCell).join(", ");
41644
41985
  }
41645
41986
  async function rebuildResourcesIndex(projectDir) {
41646
- const dir = resolve102(projectDir, "resources");
41987
+ const dir = resolve103(projectDir, "resources");
41647
41988
  await ensureDir(dir);
41648
41989
  const files = await listSlugFiles(dir);
41649
41990
  const slug = readProjectSlug(projectDir);
@@ -41659,7 +42000,7 @@ async function rebuildResourcesIndex(projectDir) {
41659
42000
  lines.push("| Name | Category | Source | Related Assignments | Updated |");
41660
42001
  lines.push("|------|----------|--------|---------------------|---------|");
41661
42002
  for (const fileName of files) {
41662
- const content = await readFile73(resolve102(dir, fileName), "utf-8");
42003
+ const content = await readFile74(resolve103(dir, fileName), "utf-8");
41663
42004
  const parsed = parseResource(content);
41664
42005
  const slugBase = fileName.replace(/\.md$/, "");
41665
42006
  const name = parsed.name || slugBase;
@@ -41669,12 +42010,12 @@ async function rebuildResourcesIndex(projectDir) {
41669
42010
  );
41670
42011
  }
41671
42012
  lines.push("");
41672
- const indexPath = resolve102(dir, "_index.md");
42013
+ const indexPath = resolve103(dir, "_index.md");
41673
42014
  await writeFileForce(indexPath, lines.join("\n"));
41674
42015
  return { total: files.length, path: indexPath };
41675
42016
  }
41676
42017
  async function rebuildMemoriesIndex(projectDir) {
41677
- const dir = resolve102(projectDir, "memories");
42018
+ const dir = resolve103(projectDir, "memories");
41678
42019
  await ensureDir(dir);
41679
42020
  const files = await listSlugFiles(dir);
41680
42021
  const slug = readProjectSlug(projectDir);
@@ -41690,7 +42031,7 @@ async function rebuildMemoriesIndex(projectDir) {
41690
42031
  lines.push("| Name | Source | Scope | Source Assignment | Updated |");
41691
42032
  lines.push("|------|--------|-------|-------------------|---------|");
41692
42033
  for (const fileName of files) {
41693
- const content = await readFile73(resolve102(dir, fileName), "utf-8");
42034
+ const content = await readFile74(resolve103(dir, fileName), "utf-8");
41694
42035
  const parsed = parseMemory(content);
41695
42036
  const slugBase = fileName.replace(/\.md$/, "");
41696
42037
  const name = parsed.name || slugBase;
@@ -41700,7 +42041,7 @@ async function rebuildMemoriesIndex(projectDir) {
41700
42041
  );
41701
42042
  }
41702
42043
  lines.push("");
41703
- const indexPath = resolve102(dir, "_index.md");
42044
+ const indexPath = resolve103(dir, "_index.md");
41704
42045
  await writeFileForce(indexPath, lines.join("\n"));
41705
42046
  return { total: files.length, path: indexPath };
41706
42047
  }
@@ -41764,8 +42105,8 @@ ${opts.body ?? "<!-- Add notes about this resource here. -->"}
41764
42105
  }
41765
42106
  async function resolveProjectDir(project) {
41766
42107
  if (!isValidSlug(project)) throw new Error(`Invalid project slug: "${project}".`);
41767
- const projectDir = resolve103((await readConfig()).defaultProjectDir, project);
41768
- if (!await fileExists(resolve103(projectDir, "project.md"))) {
42108
+ const projectDir = resolve104((await readConfig()).defaultProjectDir, project);
42109
+ if (!await fileExists(resolve104(projectDir, "project.md"))) {
41769
42110
  throw new Error(`Project "${project}" not found at ${projectDir}.`);
41770
42111
  }
41771
42112
  return projectDir;
@@ -41778,7 +42119,7 @@ async function runResourceAdd(options) {
41778
42119
  if (!isValidSlug(slug)) {
41779
42120
  throw new Error(`Invalid resource slug: "${slug}".`);
41780
42121
  }
41781
- const filePath = resolve103(projectDir, "resources", `${slug}.md`);
42122
+ const filePath = resolve104(projectDir, "resources", `${slug}.md`);
41782
42123
  if (await fileExists(filePath) && !options.force) {
41783
42124
  throw new Error(
41784
42125
  `Resource "${slug}" already exists at ${filePath}. Use --force to overwrite.`
@@ -41795,7 +42136,7 @@ async function runResourceAdd(options) {
41795
42136
  return { filePath, indexPath, total };
41796
42137
  }
41797
42138
  async function listResourceSlugs(projectDir) {
41798
- const dir = resolve103(projectDir, "resources");
42139
+ const dir = resolve104(projectDir, "resources");
41799
42140
  if (!await fileExists(dir)) return [];
41800
42141
  const entries = await readdir37(dir, { withFileTypes: true });
41801
42142
  return entries.filter((e) => e.isFile() && e.name.endsWith(".md") && e.name !== "_index.md").map((e) => e.name.slice(0, -3)).sort();
@@ -41805,16 +42146,16 @@ async function runResourceList(project) {
41805
42146
  const slugs = await listResourceSlugs(projectDir);
41806
42147
  const out = [];
41807
42148
  for (const slug of slugs) {
41808
- const parsed = parseResource(await readFile74(resolve103(projectDir, "resources", `${slug}.md`), "utf-8"));
42149
+ const parsed = parseResource(await readFile75(resolve104(projectDir, "resources", `${slug}.md`), "utf-8"));
41809
42150
  out.push({ slug, name: parsed.name, category: parsed.category, source: parsed.source, updated: parsed.updated });
41810
42151
  }
41811
42152
  return out;
41812
42153
  }
41813
42154
  async function runResourceShow(project, slug) {
41814
42155
  const projectDir = await resolveProjectDir(project);
41815
- const filePath = resolve103(projectDir, "resources", `${slug}.md`);
42156
+ const filePath = resolve104(projectDir, "resources", `${slug}.md`);
41816
42157
  if (!await fileExists(filePath)) throw new Error(`Resource "${slug}" not found in project "${project}".`);
41817
- const parsed = parseResource(await readFile74(filePath, "utf-8"));
42158
+ const parsed = parseResource(await readFile75(filePath, "utf-8"));
41818
42159
  return {
41819
42160
  slug,
41820
42161
  name: parsed.name,
@@ -41828,14 +42169,14 @@ async function runResourceShow(project, slug) {
41828
42169
  }
41829
42170
  async function runResourceUpdate(slug, options) {
41830
42171
  const projectDir = await resolveProjectDir(options.project);
41831
- const filePath = resolve103(projectDir, "resources", `${slug}.md`);
42172
+ const filePath = resolve104(projectDir, "resources", `${slug}.md`);
41832
42173
  if (!await fileExists(filePath)) {
41833
42174
  throw new Error(`Resource "${slug}" not found in project "${options.project}".`);
41834
42175
  }
41835
42176
  if (options.name === void 0 && options.source === void 0 && options.category === void 0 && options.relatedAssignments === void 0) {
41836
42177
  throw new Error("Provide at least one of --name, --source, --category, --related-assignments.");
41837
42178
  }
41838
- const original = await readFile74(filePath, "utf-8");
42179
+ const original = await readFile75(filePath, "utf-8");
41839
42180
  const content = editResourceFrontmatter(original, {
41840
42181
  name: options.name,
41841
42182
  category: options.category,
@@ -41848,7 +42189,7 @@ async function runResourceUpdate(slug, options) {
41848
42189
  }
41849
42190
  async function runResourceRemove(slug, options) {
41850
42191
  const projectDir = await resolveProjectDir(options.project);
41851
- const filePath = resolve103(projectDir, "resources", `${slug}.md`);
42192
+ const filePath = resolve104(projectDir, "resources", `${slug}.md`);
41852
42193
  if (!await fileExists(filePath)) {
41853
42194
  throw new Error(`Resource "${slug}" not found in project "${options.project}".`);
41854
42195
  }
@@ -41931,8 +42272,8 @@ init_config2();
41931
42272
  init_fs();
41932
42273
  init_slug();
41933
42274
  import { Command as Command15 } from "commander";
41934
- import { resolve as resolve104 } from "path";
41935
- import { readFile as readFile75, readdir as readdir38, rm as rm16 } from "fs/promises";
42275
+ import { resolve as resolve105 } from "path";
42276
+ import { readFile as readFile76, readdir as readdir38, rm as rm16 } from "fs/promises";
41936
42277
  init_parser();
41937
42278
  function nowIso5() {
41938
42279
  return (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
@@ -41996,8 +42337,8 @@ ${opts.body ?? "<!-- Capture the load-bearing context for this memory here. -->"
41996
42337
  }
41997
42338
  async function resolveProjectDir2(project) {
41998
42339
  if (!isValidSlug(project)) throw new Error(`Invalid project slug: "${project}".`);
41999
- const projectDir = resolve104((await readConfig()).defaultProjectDir, project);
42000
- if (!await fileExists(resolve104(projectDir, "project.md"))) {
42340
+ const projectDir = resolve105((await readConfig()).defaultProjectDir, project);
42341
+ if (!await fileExists(resolve105(projectDir, "project.md"))) {
42001
42342
  throw new Error(`Project "${project}" not found at ${projectDir}.`);
42002
42343
  }
42003
42344
  return projectDir;
@@ -42010,7 +42351,7 @@ async function runMemoryAdd(options) {
42010
42351
  if (!isValidSlug(slug)) {
42011
42352
  throw new Error(`Invalid memory slug: "${slug}".`);
42012
42353
  }
42013
- const filePath = resolve104(projectDir, "memories", `${slug}.md`);
42354
+ const filePath = resolve105(projectDir, "memories", `${slug}.md`);
42014
42355
  if (await fileExists(filePath) && !options.force) {
42015
42356
  throw new Error(
42016
42357
  `Memory "${slug}" already exists at ${filePath}. Use --force to overwrite.`
@@ -42028,7 +42369,7 @@ async function runMemoryAdd(options) {
42028
42369
  return { filePath, indexPath, total };
42029
42370
  }
42030
42371
  async function listMemorySlugs(projectDir) {
42031
- const dir = resolve104(projectDir, "memories");
42372
+ const dir = resolve105(projectDir, "memories");
42032
42373
  if (!await fileExists(dir)) return [];
42033
42374
  const entries = await readdir38(dir, { withFileTypes: true });
42034
42375
  return entries.filter((e) => e.isFile() && e.name.endsWith(".md") && e.name !== "_index.md").map((e) => e.name.slice(0, -3)).sort();
@@ -42038,16 +42379,16 @@ async function runMemoryList(project) {
42038
42379
  const slugs = await listMemorySlugs(projectDir);
42039
42380
  const out = [];
42040
42381
  for (const slug of slugs) {
42041
- const parsed = parseMemory(await readFile75(resolve104(projectDir, "memories", `${slug}.md`), "utf-8"));
42382
+ const parsed = parseMemory(await readFile76(resolve105(projectDir, "memories", `${slug}.md`), "utf-8"));
42042
42383
  out.push({ slug, name: parsed.name, scope: parsed.scope, source: parsed.source, updated: parsed.updated });
42043
42384
  }
42044
42385
  return out;
42045
42386
  }
42046
42387
  async function runMemoryShow(project, slug) {
42047
42388
  const projectDir = await resolveProjectDir2(project);
42048
- const filePath = resolve104(projectDir, "memories", `${slug}.md`);
42389
+ const filePath = resolve105(projectDir, "memories", `${slug}.md`);
42049
42390
  if (!await fileExists(filePath)) throw new Error(`Memory "${slug}" not found in project "${project}".`);
42050
- const parsed = parseMemory(await readFile75(filePath, "utf-8"));
42391
+ const parsed = parseMemory(await readFile76(filePath, "utf-8"));
42051
42392
  return {
42052
42393
  slug,
42053
42394
  name: parsed.name,
@@ -42062,7 +42403,7 @@ async function runMemoryShow(project, slug) {
42062
42403
  }
42063
42404
  async function runMemoryUpdate(slug, options) {
42064
42405
  const projectDir = await resolveProjectDir2(options.project);
42065
- const filePath = resolve104(projectDir, "memories", `${slug}.md`);
42406
+ const filePath = resolve105(projectDir, "memories", `${slug}.md`);
42066
42407
  if (!await fileExists(filePath)) {
42067
42408
  throw new Error(`Memory "${slug}" not found in project "${options.project}".`);
42068
42409
  }
@@ -42071,7 +42412,7 @@ async function runMemoryUpdate(slug, options) {
42071
42412
  "Provide at least one of --name, --source, --scope, --source-assignment, --related-assignments."
42072
42413
  );
42073
42414
  }
42074
- const original = await readFile75(filePath, "utf-8");
42415
+ const original = await readFile76(filePath, "utf-8");
42075
42416
  const content = editMemoryFrontmatter(original, {
42076
42417
  name: options.name,
42077
42418
  source: options.source,
@@ -42085,7 +42426,7 @@ async function runMemoryUpdate(slug, options) {
42085
42426
  }
42086
42427
  async function runMemoryRemove(slug, options) {
42087
42428
  const projectDir = await resolveProjectDir2(options.project);
42088
- const filePath = resolve104(projectDir, "memories", `${slug}.md`);
42429
+ const filePath = resolve105(projectDir, "memories", `${slug}.md`);
42089
42430
  if (!await fileExists(filePath)) {
42090
42431
  throw new Error(`Memory "${slug}" not found in project "${options.project}".`);
42091
42432
  }
@@ -42174,8 +42515,8 @@ init_derive();
42174
42515
  init_recompute();
42175
42516
  init_query();
42176
42517
  import { Command as Command16 } from "commander";
42177
- import { readFile as readFile76 } from "fs/promises";
42178
- import { dirname as dirname29, resolve as resolve105 } from "path";
42518
+ import { readFile as readFile77 } from "fs/promises";
42519
+ import { dirname as dirname29, resolve as resolve106 } from "path";
42179
42520
  var AGE_PATTERN = /^(\d+)([dhwm])$/i;
42180
42521
  function parseAgeToCutoff(age) {
42181
42522
  const match = age.match(AGE_PATTERN);
@@ -42194,7 +42535,7 @@ function parseAgeToCutoff(age) {
42194
42535
  }
42195
42536
  function assignmentMdPath(item) {
42196
42537
  if (item.projectSlug) {
42197
- return resolve105(
42538
+ return resolve106(
42198
42539
  defaultProjectDir(),
42199
42540
  item.projectSlug,
42200
42541
  "assignments",
@@ -42202,13 +42543,13 @@ function assignmentMdPath(item) {
42202
42543
  "assignment.md"
42203
42544
  );
42204
42545
  }
42205
- return resolve105(assignmentsDir(), item.id, "assignment.md");
42546
+ return resolve106(assignmentsDir(), item.id, "assignment.md");
42206
42547
  }
42207
42548
  async function loadTags(item) {
42208
42549
  const path = assignmentMdPath(item);
42209
42550
  if (!await fileExists(path)) return [];
42210
42551
  try {
42211
- const content = await readFile76(path, "utf-8");
42552
+ const content = await readFile77(path, "utf-8");
42212
42553
  return parseAssignmentFrontmatter(content).tags;
42213
42554
  } catch {
42214
42555
  return [];
@@ -42272,11 +42613,11 @@ async function loadQueryItem(item, terminalStatuses3, now, declarations) {
42272
42613
  const path = assignmentMdPath(item);
42273
42614
  if (!await fileExists(path)) return null;
42274
42615
  try {
42275
- const content = await readFile76(path, "utf-8");
42616
+ const content = await readFile77(path, "utf-8");
42276
42617
  const fm = parseAssignmentFrontmatter(content);
42277
42618
  const body = content.replace(/^---\n[\s\S]*?\n---/, "");
42278
42619
  const assignmentDir = dirname29(path);
42279
- const projectDir = item.projectSlug ? resolve105(defaultProjectDir(), item.projectSlug) : null;
42620
+ const projectDir = item.projectSlug ? resolve106(defaultProjectDir(), item.projectSlug) : null;
42280
42621
  const facts = await computeFacts({ assignmentDir, frontmatter: fm, body, projectDir, terminalStatuses: terminalStatuses3, declarations });
42281
42622
  const history = fm.statusHistory;
42282
42623
  const lastHeadlineChange = [...history].reverse().find((e) => e.from !== e.to || e.from === null);
@@ -42556,8 +42897,116 @@ var timelineCommand = new Command18("timeline").description(
42556
42897
  }
42557
42898
  });
42558
42899
 
42559
- // src/commands/views.ts
42900
+ // src/commands/inbox.ts
42901
+ init_config2();
42902
+ init_paths();
42903
+ init_api();
42560
42904
  import { Command as Command19 } from "commander";
42905
+ async function runInbox(options) {
42906
+ const config = await readConfig();
42907
+ const projectsDir2 = config.defaultProjectDir;
42908
+ const assignmentsDir2 = assignmentsDir();
42909
+ const limit = parseLimit3(options.limit);
42910
+ const types = parseTypes(options.type);
42911
+ const resolved = await getStatusConfig();
42912
+ const headline = (resolved.derive ?? DEFAULT_DERIVE_CONFIG).headline;
42913
+ const blockedParkedStatuses = new Set([headline.blocked, headline.parked].filter(Boolean));
42914
+ const statusConfig = { ...resolved, blockedParkedStatuses };
42915
+ return computeInbox({
42916
+ projectsDir: projectsDir2,
42917
+ assignmentsDir: assignmentsDir2,
42918
+ project: options.project,
42919
+ types,
42920
+ limit,
42921
+ statusConfig
42922
+ });
42923
+ }
42924
+ function parseLimit3(raw2) {
42925
+ if (raw2 === void 0) return void 0;
42926
+ const n = parseInt(raw2, 10);
42927
+ if (Number.isNaN(n) || n <= 0) {
42928
+ throw new Error(`Invalid --limit value: "${raw2}". Must be a positive integer.`);
42929
+ }
42930
+ return n;
42931
+ }
42932
+ function parseTypes(raw2) {
42933
+ if (raw2 === void 0) return void 0;
42934
+ const parts = raw2.split(",").map((s) => s.trim()).filter(Boolean);
42935
+ if (parts.length === 0) return void 0;
42936
+ const known = new Set(INBOX_CATEGORIES);
42937
+ const unknown = parts.filter((p) => !known.has(p));
42938
+ if (unknown.length > 0) {
42939
+ throw new Error(
42940
+ `Unknown --type categor${unknown.length > 1 ? "ies" : "y"}: ${unknown.map((u) => `"${u}"`).join(", ")}. Valid: ${INBOX_CATEGORIES.join(", ")}.`
42941
+ );
42942
+ }
42943
+ return parts;
42944
+ }
42945
+ var CATEGORY_LABEL = {
42946
+ review: "review",
42947
+ blocked: "blocked",
42948
+ question: "question",
42949
+ "plan-approval": "plan-approval"
42950
+ };
42951
+ function humanizeAge(ageMs) {
42952
+ const sec = Math.floor(ageMs / 1e3);
42953
+ if (sec < 60) return sec <= 0 ? "just now" : `${sec}s ago`;
42954
+ const min = Math.floor(sec / 60);
42955
+ if (min < 60) return `${min}m ago`;
42956
+ const hr = Math.floor(min / 60);
42957
+ if (hr < 24) return `${hr}h ago`;
42958
+ const day = Math.floor(hr / 24);
42959
+ if (day < 7) return `${day}d ago`;
42960
+ const wk = Math.floor(day / 7);
42961
+ return `${wk}w ago`;
42962
+ }
42963
+ function locator(item) {
42964
+ if (item.project === null) return item.assignmentId;
42965
+ return `${item.project}/${item.assignmentSlug}`;
42966
+ }
42967
+ function renderHeader(result) {
42968
+ if (result.total === 0) return "Nothing needs you.";
42969
+ const noun = result.total === 1 ? "item needs" : "items need";
42970
+ const counts = INBOX_CATEGORIES.filter((c2) => result.counts[c2] > 0).map((c2) => `${CATEGORY_LABEL[c2]} ${result.counts[c2]}`).join(" ");
42971
+ return `${result.total} ${noun} you \xB7 ${counts}`;
42972
+ }
42973
+ function renderHuman2(result) {
42974
+ const lines = [renderHeader(result)];
42975
+ if (result.total === 0) return lines.join("\n");
42976
+ for (const category of INBOX_CATEGORIES) {
42977
+ const items = result.items.filter((i) => i.category === category);
42978
+ if (items.length === 0) continue;
42979
+ lines.push("");
42980
+ lines.push(`${CATEGORY_LABEL[category]} (${result.counts[category]})`);
42981
+ for (const item of items) {
42982
+ lines.push(` ${item.title} [${locator(item)}] ${humanizeAge(item.ageMs)}`);
42983
+ if (item.summary) lines.push(` ${item.summary}`);
42984
+ lines.push(` \u2192 ${item.action.command}`);
42985
+ }
42986
+ }
42987
+ return lines.join("\n");
42988
+ }
42989
+ var inboxCommand = new Command19("inbox").description(
42990
+ "One triage view of everything awaiting a human: assignments in review, blocked, with an unanswered question, or with a plan awaiting approval. Read-only \u2014 prints the exact action command for each item; never mutates."
42991
+ ).option("--project <slug>", "Restrict to one project").option(
42992
+ "--type <list>",
42993
+ `Comma-separated category filter (${INBOX_CATEGORIES.join(", ")})`
42994
+ ).option("--limit <n>", "Maximum number of items to show").option("--json", "Emit the structured InboxResult JSON instead of the grouped view").action(async (options) => {
42995
+ try {
42996
+ const result = await runInbox(options);
42997
+ if (options.json) {
42998
+ console.log(JSON.stringify(result, null, 2));
42999
+ } else {
43000
+ console.log(renderHuman2(result));
43001
+ }
43002
+ } catch (error) {
43003
+ console.error("Error:", error instanceof Error ? error.message : String(error));
43004
+ process.exit(1);
43005
+ }
43006
+ });
43007
+
43008
+ // src/commands/views.ts
43009
+ import { Command as Command20 } from "commander";
42561
43010
 
42562
43011
  // src/utils/saved-view-builder.ts
42563
43012
  var KNOWN_FILTER_KEYS = /* @__PURE__ */ new Set([
@@ -42883,7 +43332,7 @@ async function runViewsDelete(id) {
42883
43332
  function addConfigFlags(cmd) {
42884
43333
  return cmd.option("--workspace <ws>", "Scope the view to a workspace (default: global)").option("--global", "Make the view global (workspace = null)").option("--view-mode <mode>", `View mode (${VIEW_MODES.join("|")})`).option("--sort-field <field>", `Sort field (${SORT_FIELDS.join("|")})`).option("--sort-direction <dir>", `Sort direction (${SORT_DIRECTIONS.join("|")})`).option("--status <vals>", 'Status filter, comma-separated ("all"/"" clears)').option("--type <vals>", 'Type filter, comma-separated ("all"/"" clears)').option("--priority <vals>", 'Priority filter, comma-separated ("all"/"" clears)').option("--assignee <vals>", 'Assignee filter, comma-separated ("all"/"" clears)').option("--project-filter <vals>", 'Project filter, comma-separated ("all"/"" clears)').option("--tags <vals>", 'Tags filter, comma-separated ("all"/"" clears)').option("--activity <val>", `Activity filter (${ACTIVITIES.join("|")}; "all" clears)`).option("--date-range-field <field>", `Date range field (${DATE_RANGE_FIELDS.join("|")})`).option("--date-range-preset <preset>", `Date range preset (${DATE_RANGE_PRESETS.join("|")})`).option("--date-from <YYYY-MM-DD>", "Date range start (exclusive with --date-range-preset)").option("--date-to <YYYY-MM-DD>", "Date range end (exclusive with --date-range-preset)").option("--clear-date-range", "Remove the date-range filter").option("--search <text>", 'Search text filter ("" clears)').option("--query <expr>", 'AQL filter query ("" clears)').option("--collapsed <vals>", "List-view collapsed section ids, comma-separated").option("--kanban-hidden <vals>", "Kanban hidden column ids, comma-separated").option("--table-hidden <vals>", `Table hidden column ids (${TABLE_COLUMN_IDS.join("|")}), comma-separated`).option("--json", "Output the resulting view as JSON");
42885
43334
  }
42886
- var viewsCommand = new Command19("views").description(
43335
+ var viewsCommand = new Command20("views").description(
42887
43336
  "Manage saved views (~/.syntaur/saved-views.json)"
42888
43337
  );
42889
43338
  addConfigFlags(
@@ -42937,9 +43386,9 @@ init_paths();
42937
43386
  init_fs();
42938
43387
  init_timestamp();
42939
43388
  init_frontmatter();
42940
- import { Command as Command20 } from "commander";
42941
- import { readFile as readFile77 } from "fs/promises";
42942
- import { resolve as resolve106 } from "path";
43389
+ import { Command as Command21 } from "commander";
43390
+ import { readFile as readFile78 } from "fs/promises";
43391
+ import { resolve as resolve107 } from "path";
42943
43392
  function renameAssignmentStatusRefs(content, id, newId, now) {
42944
43393
  const fm = parseAssignmentFrontmatter(content);
42945
43394
  const updates = { updated: now };
@@ -42960,12 +43409,12 @@ function fail3(error) {
42960
43409
  process.exit(1);
42961
43410
  }
42962
43411
  function configPath() {
42963
- return resolve106(syntaurRoot(), "config.md");
43412
+ return resolve107(syntaurRoot(), "config.md");
42964
43413
  }
42965
43414
  async function readStatusBlock() {
42966
43415
  const p = configPath();
42967
43416
  if (!await fileExists(p)) return null;
42968
- const content = await readFile77(p, "utf-8");
43417
+ const content = await readFile78(p, "utf-8");
42969
43418
  return parseStatusConfig(content);
42970
43419
  }
42971
43420
  async function requireStatusBlock() {
@@ -43249,7 +43698,7 @@ async function runStatusRename(id, opts) {
43249
43698
  printBlockDiff(before, after);
43250
43699
  const now2 = nowTimestamp();
43251
43700
  for (const a of affected) {
43252
- const original = await readFile77(a.path, "utf-8");
43701
+ const original = await readFile78(a.path, "utf-8");
43253
43702
  const rewritten = renameAssignmentStatusRefs(original, id, newId, now2);
43254
43703
  console.log(`
43255
43704
  --- ${a.display}/assignment.md`);
@@ -43260,9 +43709,9 @@ async function runStatusRename(id, opts) {
43260
43709
  }
43261
43710
  const cfgPath = configPath();
43262
43711
  const buffers = /* @__PURE__ */ new Map();
43263
- buffers.set(cfgPath, await fileExists(cfgPath) ? await readFile77(cfgPath, "utf-8") : "");
43712
+ buffers.set(cfgPath, await fileExists(cfgPath) ? await readFile78(cfgPath, "utf-8") : "");
43264
43713
  for (const a of affected) {
43265
- buffers.set(a.path, await readFile77(a.path, "utf-8"));
43714
+ buffers.set(a.path, await readFile78(a.path, "utf-8"));
43266
43715
  }
43267
43716
  const now = nowTimestamp();
43268
43717
  try {
@@ -43357,7 +43806,7 @@ function printList(result) {
43357
43806
  }
43358
43807
  }
43359
43808
  }
43360
- var statusCommand = new Command20("status").description(
43809
+ var statusCommand = new Command21("status").description(
43361
43810
  "Manage assignment statuses + transitions (the statuses: block in ~/.syntaur/config.md)"
43362
43811
  );
43363
43812
  statusCommand.command("list").description("List the current statuses, order, and transitions").option("--json", "Output as JSON").action(async (opts) => {
@@ -43463,14 +43912,14 @@ init_paths();
43463
43912
  init_config2();
43464
43913
  init_timestamp();
43465
43914
  init_frontmatter();
43466
- import { Command as Command21 } from "commander";
43467
- import { readFile as readFile78 } from "fs/promises";
43468
- import { resolve as resolve107 } from "path";
43915
+ import { Command as Command22 } from "commander";
43916
+ import { readFile as readFile79 } from "fs/promises";
43917
+ import { resolve as resolve108 } from "path";
43469
43918
  async function readContext3(cwd) {
43470
- const path = resolve107(cwd, ".syntaur", "context.json");
43919
+ const path = resolve108(cwd, ".syntaur", "context.json");
43471
43920
  if (!await fileExists(path)) return null;
43472
43921
  try {
43473
- return JSON.parse(await readFile78(path, "utf-8"));
43922
+ return JSON.parse(await readFile79(path, "utf-8"));
43474
43923
  } catch {
43475
43924
  return null;
43476
43925
  }
@@ -43479,12 +43928,12 @@ async function resolveAssignmentPath3(opts) {
43479
43928
  if (opts.assignment) {
43480
43929
  if (opts.project) {
43481
43930
  const projectsDir2 = (await readConfig()).defaultProjectDir;
43482
- return resolve107(projectsDir2, opts.project, "assignments", opts.assignment, "assignment.md");
43931
+ return resolve108(projectsDir2, opts.project, "assignments", opts.assignment, "assignment.md");
43483
43932
  }
43484
- return resolve107(assignmentsDir(), opts.assignment, "assignment.md");
43933
+ return resolve108(assignmentsDir(), opts.assignment, "assignment.md");
43485
43934
  }
43486
43935
  const ctx = await readContext3(opts.cwd);
43487
- if (ctx?.assignmentDir) return resolve107(ctx.assignmentDir, "assignment.md");
43936
+ if (ctx?.assignmentDir) return resolve108(ctx.assignmentDir, "assignment.md");
43488
43937
  throw new Error(
43489
43938
  "No active assignment. Pass --assignment <slug> [--project <slug>] or run from a workspace with .syntaur/context.json."
43490
43939
  );
@@ -43521,7 +43970,7 @@ async function runWorkspaceSet(options, cwd = process.cwd()) {
43521
43970
  ${pre.errors.map((e) => ` - ${e}`).join("\n")}`
43522
43971
  );
43523
43972
  }
43524
- const original = await readFile78(path, "utf-8");
43973
+ const original = await readFile79(path, "utf-8");
43525
43974
  let next = updateAssignmentWorkspace(original, partial);
43526
43975
  next = updateAssignmentFile(next, { updated: nowTimestamp() });
43527
43976
  await writeFileForce(path, next);
@@ -43535,7 +43984,7 @@ ${post.errors.map((e) => ` - ${e}`).join("\n")}`
43535
43984
  }
43536
43985
  return { path, fields };
43537
43986
  }
43538
- var workspaceCommand = new Command21("workspace").description(
43987
+ var workspaceCommand = new Command22("workspace").description(
43539
43988
  "Manage the active assignment workspace binding"
43540
43989
  );
43541
43990
  workspaceCommand.command("set").description("Set the four workspace.* frontmatter fields atomically (validates + bumps updated)").option("--repository <path>", "Repository root").option("--worktree-path <path>", "Worktree path (typically <repo>/.worktrees/<branch>)").option("--branch <name>", "Branch name").option("--parent-branch <name>", "Parent branch (typically main)").option("--assignment <slug>", "Assignment slug (UUID for standalone). Defaults to .syntaur/context.json").option("--project <slug>", "Project slug. Required with --assignment for a project-nested assignment").action(async (options) => {
@@ -43557,14 +44006,14 @@ init_paths();
43557
44006
  init_config2();
43558
44007
  init_timestamp();
43559
44008
  init_templates();
43560
- import { Command as Command22 } from "commander";
43561
- import { readFile as readFile79 } from "fs/promises";
43562
- import { resolve as resolve108 } from "path";
44009
+ import { Command as Command23 } from "commander";
44010
+ import { readFile as readFile80 } from "fs/promises";
44011
+ import { resolve as resolve109 } from "path";
43563
44012
  async function readContext4(cwd) {
43564
- const path = resolve108(cwd, ".syntaur", "context.json");
44013
+ const path = resolve109(cwd, ".syntaur", "context.json");
43565
44014
  if (!await fileExists(path)) return null;
43566
44015
  try {
43567
- return JSON.parse(await readFile79(path, "utf-8"));
44016
+ return JSON.parse(await readFile80(path, "utf-8"));
43568
44017
  } catch {
43569
44018
  return null;
43570
44019
  }
@@ -43574,11 +44023,11 @@ async function resolveAssignmentDir2(opts) {
43574
44023
  if (opts.project) {
43575
44024
  const projectsDir2 = (await readConfig()).defaultProjectDir;
43576
44025
  return {
43577
- dir: resolve108(projectsDir2, opts.project, "assignments", opts.assignment),
44026
+ dir: resolve109(projectsDir2, opts.project, "assignments", opts.assignment),
43578
44027
  slug: opts.assignment
43579
44028
  };
43580
44029
  }
43581
- return { dir: resolve108(assignmentsDir(), opts.assignment), slug: opts.assignment };
44030
+ return { dir: resolve109(assignmentsDir(), opts.assignment), slug: opts.assignment };
43582
44031
  }
43583
44032
  const ctx = await readContext4(opts.cwd);
43584
44033
  if (ctx?.assignmentDir) {
@@ -43640,17 +44089,17 @@ async function runProgressLog(text, options, cwd = process.cwd()) {
43640
44089
  project: options.project,
43641
44090
  cwd
43642
44091
  });
43643
- if (!await fileExists(resolve108(dir, "assignment.md"))) {
44092
+ if (!await fileExists(resolve109(dir, "assignment.md"))) {
43644
44093
  throw new Error(`No assignment found at ${dir} (missing assignment.md).`);
43645
44094
  }
43646
- const path = resolve108(dir, "progress.md");
44095
+ const path = resolve109(dir, "progress.md");
43647
44096
  const now = nowTimestamp();
43648
- const content = await fileExists(path) ? await readFile79(path, "utf-8") : renderProgress({ assignment: slug, timestamp: now });
44097
+ const content = await fileExists(path) ? await readFile80(path, "utf-8") : renderProgress({ assignment: slug, timestamp: now });
43649
44098
  const next = appendProgressEntry(content, text, now);
43650
44099
  await writeFileForce(path, next);
43651
44100
  return path;
43652
44101
  }
43653
- var progressCommand = new Command22("progress").description(
44102
+ var progressCommand = new Command23("progress").description(
43654
44103
  "Record progress on the active assignment"
43655
44104
  );
43656
44105
  progressCommand.command("log").description("Append a timestamped entry to the assignment's progress.md").argument("<text>", "Progress entry text").option("--assignment <slug>", "Assignment slug (UUID for standalone). Defaults to .syntaur/context.json").option("--project <slug>", "Project slug. Required with --assignment for a project-nested assignment").action(async (text, options) => {
@@ -43720,7 +44169,7 @@ function spliceDashDashFromArgv(argv) {
43720
44169
  }
43721
44170
  }
43722
44171
  var captureDashDashArgv = [];
43723
- var program = new Command23();
44172
+ var program = new Command24();
43724
44173
  var version = await readPackageVersion(import.meta.url) ?? "0.0.0";
43725
44174
  program.name("syntaur").description("CLI scaffolding tool for the Syntaur protocol").version(version);
43726
44175
  program.command("init").description("Initialize ~/.syntaur/ directory structure and config").option("--force", "Overwrite existing config file").action(
@@ -44055,6 +44504,7 @@ program.addCommand(memoryCommand);
44055
44504
  program.addCommand(lsCommand);
44056
44505
  program.addCommand(searchCommand);
44057
44506
  program.addCommand(timelineCommand);
44507
+ program.addCommand(inboxCommand);
44058
44508
  program.addCommand(viewsCommand);
44059
44509
  program.addCommand(statusCommand);
44060
44510
  program.addCommand(workspaceCommand);