@staff0rd/assist 0.172.3 → 0.173.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.
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { Command } from "commander";
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "@staff0rd/assist",
9
- version: "0.172.3",
9
+ version: "0.173.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -76,6 +76,7 @@ var package_default = {
76
76
  marked: "^15.0.12",
77
77
  react: "^19.2.4",
78
78
  "react-dom": "^19.2.4",
79
+ "react-router": "^7.14.0",
79
80
  "semantic-release": "^25.0.2",
80
81
  tsup: "^8.5.1",
81
82
  vitest: "^4.0.18"
@@ -148,14 +149,11 @@ function loadComments(db, itemId) {
148
149
  // src/commands/backlog/loadPlan.ts
149
150
  function toPhase(db, itemId, p) {
150
151
  const tasks = db.prepare(
151
- "SELECT task, verify FROM plan_tasks WHERE item_id = ? AND phase_idx = ? ORDER BY idx"
152
+ "SELECT task FROM plan_tasks WHERE item_id = ? AND phase_idx = ? ORDER BY idx"
152
153
  ).all(itemId, p.idx);
153
154
  const phase = {
154
155
  name: p.name,
155
- tasks: tasks.map((t) => ({
156
- task: t.task,
157
- ...t.verify != null ? { verify: t.verify } : {}
158
- }))
156
+ tasks: tasks.map((t) => ({ task: t.task }))
159
157
  };
160
158
  if (p.manual_checks) {
161
159
  phase.manualChecks = JSON.parse(p.manual_checks);
@@ -242,7 +240,7 @@ function insertPlan(db, item) {
242
240
  "INSERT INTO plan_phases (item_id, idx, name, manual_checks) VALUES (?, ?, ?, ?)"
243
241
  );
244
242
  const taskStmt = db.prepare(
245
- "INSERT INTO plan_tasks (item_id, phase_idx, idx, task, verify) VALUES (?, ?, ?, ?, ?)"
243
+ "INSERT INTO plan_tasks (item_id, phase_idx, idx, task) VALUES (?, ?, ?, ?)"
246
244
  );
247
245
  for (let pi = 0; pi < item.plan.length; pi++) {
248
246
  const phase = item.plan[pi];
@@ -254,7 +252,7 @@ function insertPlan(db, item) {
254
252
  );
255
253
  for (let ti = 0; ti < phase.tasks.length; ti++) {
256
254
  const task = phase.tasks[ti];
257
- taskStmt.run(item.id, pi, ti, task.task, task.verify ?? null);
255
+ taskStmt.run(item.id, pi, ti, task.task);
258
256
  }
259
257
  }
260
258
  }
@@ -310,8 +308,7 @@ import { z } from "zod";
310
308
  var backlogStatusSchema = z.enum(["todo", "in-progress", "done", "wontdo"]);
311
309
  var backlogTypeSchema = z.enum(["story", "bug"]);
312
310
  var planTaskSchema = z.strictObject({
313
- task: z.string(),
314
- verify: z.string().optional()
311
+ task: z.string()
315
312
  });
316
313
  var planPhaseSchema = z.strictObject({
317
314
  name: z.string(),
@@ -446,7 +443,6 @@ function initSchema(db) {
446
443
  phase_idx INTEGER NOT NULL,
447
444
  idx INTEGER NOT NULL,
448
445
  task TEXT NOT NULL,
449
- verify TEXT,
450
446
  PRIMARY KEY (item_id, phase_idx, idx),
451
447
  FOREIGN KEY (item_id, phase_idx) REFERENCES plan_phases(item_id, idx) ON DELETE CASCADE
452
448
  );
@@ -618,9 +614,17 @@ function phaseLabel(item) {
618
614
  ` (phase ${(item.currentPhase ?? 0) + 1}/${item.plan.length})`
619
615
  );
620
616
  }
621
- function dependencyLabel(item) {
617
+ function isBlocked(item, items) {
618
+ const deps2 = (item.links ?? []).filter((l) => l.type === "depends-on");
619
+ return deps2.some((dep) => {
620
+ const target = items.find((i) => i.id === dep.targetId);
621
+ return target !== void 0 && target.status !== "done";
622
+ });
623
+ }
624
+ function dependencyLabel(item, items) {
622
625
  const deps2 = (item.links ?? []).filter((l) => l.type === "depends-on");
623
626
  if (deps2.length === 0) return "";
627
+ if (isBlocked(item, items)) return chalk2.red(" [blocked]");
624
628
  return chalk2.dim(` [${deps2.length} dep${deps2.length > 1 ? "s" : ""}]`);
625
629
  }
626
630
  function printVerboseDetails(item) {
@@ -698,11 +702,7 @@ function buildManualCheckLines(manualChecks) {
698
702
  return [];
699
703
  }
700
704
  function formatTasks(phase) {
701
- return phase.tasks.map((t) => {
702
- let line = `- ${t.task}`;
703
- if (t.verify) line += ` (verify: ${t.verify})`;
704
- return line;
705
- }).join("\n");
705
+ return phase.tasks.map((t) => `- ${t.task}`).join("\n");
706
706
  }
707
707
 
708
708
  // src/commands/backlog/buildReviewPrompt.ts
@@ -980,41 +980,51 @@ async function runReview(item, plan2, spawnOptions) {
980
980
  // src/commands/backlog/next.ts
981
981
  function findResumable(items) {
982
982
  return items.find(
983
- (i) => i.status === "in-progress" && i.plan && !isLockedByOther(i.id)
983
+ (i) => i.status === "in-progress" && i.plan && !isLockedByOther(i.id) && !isBlocked(i, items)
984
984
  );
985
985
  }
986
- async function selectItem(todo) {
987
- const choices = todo.map((i) => `${typeLabel(i.type)} #${i.id}: ${i.name}`);
986
+ function toChoice(item, items) {
987
+ const name = `${typeLabel(item.type)} #${item.id}: ${item.name}`;
988
+ return isBlocked(item, items) ? { name, disabled: chalk7.red("[blocked]") } : { name };
989
+ }
990
+ async function selectItem(todo, items) {
988
991
  const { selected } = await exitOnCancel(
989
992
  enquirer2.prompt({
990
993
  type: "select",
991
994
  name: "selected",
992
995
  message: "Choose a backlog item to start:",
993
- choices
996
+ choices: todo.map((i) => toChoice(i, items))
994
997
  })
995
998
  );
996
999
  return selected.match(/#(\d+)/)?.[1] ?? "";
997
1000
  }
1001
+ async function pickItem(items) {
1002
+ const resumable = findResumable(items);
1003
+ if (resumable) {
1004
+ console.log(
1005
+ chalk7.bold(
1006
+ `Resuming in-progress item #${resumable.id}: ${resumable.name}`
1007
+ )
1008
+ );
1009
+ return String(resumable.id);
1010
+ }
1011
+ const todo = items.filter((i) => i.status === "todo");
1012
+ if (todo.length === 0) {
1013
+ console.log(chalk7.green("All backlog items complete."));
1014
+ return void 0;
1015
+ }
1016
+ if (todo.every((i) => isBlocked(i, items))) {
1017
+ console.log(
1018
+ chalk7.yellow("All remaining todo items are blocked by dependencies.")
1019
+ );
1020
+ return void 0;
1021
+ }
1022
+ return selectItem(todo, items);
1023
+ }
998
1024
  async function next(options2) {
999
1025
  while (true) {
1000
- const items = loadBacklog();
1001
- const inProgress = findResumable(items);
1002
- if (inProgress) {
1003
- console.log(
1004
- chalk7.bold(
1005
- `Resuming in-progress item #${inProgress.id}: ${inProgress.name}`
1006
- )
1007
- );
1008
- const completed2 = await run(String(inProgress.id), options2);
1009
- if (!completed2) return;
1010
- continue;
1011
- }
1012
- const todo = items.filter((i) => i.status === "todo");
1013
- if (todo.length === 0) {
1014
- console.log(chalk7.green("All backlog items complete."));
1015
- return;
1016
- }
1017
- const id = await selectItem(todo);
1026
+ const id = await pickItem(loadBacklog());
1027
+ if (id === void 0) return;
1018
1028
  const completed = await run(id, options2);
1019
1029
  if (!completed) return;
1020
1030
  }
@@ -1082,9 +1092,6 @@ function plan(id) {
1082
1092
  console.log(`${chalk9.bold(`Phase ${i + 1}:`)} ${phase.name}`);
1083
1093
  for (const task of phase.tasks) {
1084
1094
  console.log(` - ${task.task}`);
1085
- if (task.verify) {
1086
- console.log(` ${chalk9.dim(`verify: ${task.verify}`)}`);
1087
- }
1088
1095
  }
1089
1096
  console.log();
1090
1097
  }
@@ -1130,9 +1137,6 @@ import chalk12 from "chalk";
1130
1137
  function printPhaseTasks(phase) {
1131
1138
  for (const task of phase.tasks) {
1132
1139
  console.log(` - ${task.task}`);
1133
- if (task.verify) {
1134
- console.log(` ${chalk12.dim(`verify: ${task.verify}`)}`);
1135
- }
1136
1140
  }
1137
1141
  if (phase.manualChecks && phase.manualChecks.length > 0) {
1138
1142
  console.log(` ${chalk12.dim("Manual checks:")}`);
@@ -1376,18 +1380,28 @@ var itemRoutes = {
1376
1380
  PATCH: (req, res, id) => patchItemStatus(req, res, id),
1377
1381
  DELETE: (_req, res, id) => deleteItem2(res, id)
1378
1382
  };
1383
+ var serveHtml = createHtmlHandler(getHtml);
1379
1384
  var baseHandler = createRouteHandler(routes);
1385
+ async function handleItemRoute(req, res, pathname) {
1386
+ const match = pathname.match(/^\/api\/items\/(\d+)$/);
1387
+ if (!match) return false;
1388
+ const handler = itemRoutes[req.method ?? "GET"];
1389
+ if (!handler) return false;
1390
+ await handler(req, res, Number.parseInt(match[1], 10));
1391
+ return true;
1392
+ }
1380
1393
  async function handleRequest(req, res, port) {
1381
1394
  const url = new URL(req.url ?? "/", `http://localhost:${port}`);
1382
1395
  const method = req.method ?? "GET";
1383
1396
  const pathname = url.pathname;
1384
- const itemMatch = pathname.match(/^\/api\/items\/(\d+)$/);
1385
- if (itemMatch) {
1386
- const itemHandler = itemRoutes[method];
1387
- if (itemHandler) {
1388
- await itemHandler(req, res, Number.parseInt(itemMatch[1], 10));
1389
- return;
1390
- }
1397
+ if (await handleItemRoute(req, res, pathname)) return;
1398
+ if (routes[`${method} ${pathname}`]) {
1399
+ await baseHandler(req, res, port);
1400
+ return;
1401
+ }
1402
+ if (method === "GET" && !pathname.startsWith("/api/")) {
1403
+ await serveHtml(req, res);
1404
+ return;
1391
1405
  }
1392
1406
  await baseHandler(req, res, port);
1393
1407
  }
@@ -3701,7 +3715,7 @@ function registerCommentCommands(cmd) {
3701
3715
  }
3702
3716
 
3703
3717
  // src/commands/backlog/add/index.ts
3704
- import chalk45 from "chalk";
3718
+ import chalk44 from "chalk";
3705
3719
 
3706
3720
  // src/commands/backlog/commitBacklog.ts
3707
3721
  import { execSync as execSync14 } from "child_process";
@@ -3718,58 +3732,9 @@ function commitBacklog(id, name) {
3718
3732
  }
3719
3733
  }
3720
3734
 
3721
- // src/commands/backlog/add/parseItemFile.ts
3722
- import { existsSync as existsSync18, readFileSync as readFileSync15 } from "fs";
3723
- import chalk44 from "chalk";
3724
- import { ZodError } from "zod";
3725
- var addItemSchema = backlogItemSchema.omit({ id: true, status: true });
3726
- function readJsonFile(filePath) {
3727
- if (!existsSync18(filePath)) {
3728
- console.log(chalk44.red(`File not found: ${filePath}`));
3729
- process.exitCode = 1;
3730
- return void 0;
3731
- }
3732
- let raw;
3733
- try {
3734
- raw = readFileSync15(filePath, "utf-8");
3735
- } catch {
3736
- console.log(chalk44.red(`Failed to read file: ${filePath}`));
3737
- process.exitCode = 1;
3738
- return void 0;
3739
- }
3740
- try {
3741
- return JSON.parse(raw);
3742
- } catch {
3743
- console.log(chalk44.red(`Invalid JSON in file: ${filePath}`));
3744
- process.exitCode = 1;
3745
- return void 0;
3746
- }
3747
- }
3748
- function formatZodError(err) {
3749
- if (err instanceof ZodError) {
3750
- console.log(chalk44.red("Invalid backlog item schema:"));
3751
- for (const issue of err.issues) {
3752
- console.log(chalk44.red(` - ${issue.path.join(".")}: ${issue.message}`));
3753
- }
3754
- } else {
3755
- console.log(chalk44.red("Invalid backlog item schema."));
3756
- }
3757
- }
3758
- function parseItemFile(filePath) {
3759
- const parsed = readJsonFile(filePath);
3760
- if (parsed === void 0) return void 0;
3761
- try {
3762
- return addItemSchema.parse(parsed);
3763
- } catch (err) {
3764
- formatZodError(err);
3765
- process.exitCode = 1;
3766
- return void 0;
3767
- }
3768
- }
3769
-
3770
3735
  // src/commands/backlog/add/shared.ts
3771
3736
  import { spawnSync } from "child_process";
3772
- import { mkdtempSync, readFileSync as readFileSync16, unlinkSync as unlinkSync4, writeFileSync as writeFileSync14 } from "fs";
3737
+ import { mkdtempSync, readFileSync as readFileSync15, unlinkSync as unlinkSync4, writeFileSync as writeFileSync14 } from "fs";
3773
3738
  import { tmpdir } from "os";
3774
3739
  import { join as join15 } from "path";
3775
3740
  import enquirer6 from "enquirer";
@@ -3819,7 +3784,7 @@ function openEditor() {
3819
3784
  unlinkSync4(filePath);
3820
3785
  return void 0;
3821
3786
  }
3822
- const content = readFileSync16(filePath, "utf-8").trim();
3787
+ const content = readFileSync15(filePath, "utf-8").trim();
3823
3788
  unlinkSync4(filePath);
3824
3789
  return content || void 0;
3825
3790
  }
@@ -3838,49 +3803,70 @@ async function promptAcceptanceCriteria() {
3838
3803
  }
3839
3804
 
3840
3805
  // src/commands/backlog/add/index.ts
3841
- function addFromFile(filePath) {
3842
- const data = parseItemFile(filePath);
3843
- if (!data) return;
3844
- const items = loadBacklog();
3845
- const id = getNextId(items);
3846
- items.push({ ...data, id, status: "todo" });
3847
- saveBacklog(items);
3848
- commitBacklog(id, data.name);
3849
- console.log(chalk45.green(`Added item #${id}: ${data.name}`));
3850
- }
3851
- async function addInteractive() {
3852
- const type = await promptType();
3853
- const name = await promptName();
3854
- const description = await promptDescription();
3855
- const acceptanceCriteria2 = await promptAcceptanceCriteria();
3806
+ async function addFromOptions(options2) {
3807
+ const type = options2.type ?? await promptType();
3808
+ const name = options2.name ?? await promptName();
3809
+ const description = options2.desc ?? await promptDescription();
3810
+ const acceptanceCriteria2 = options2.ac ?? await promptAcceptanceCriteria();
3856
3811
  const items = loadBacklog();
3857
3812
  const id = getNextId(items);
3858
3813
  items.push({
3859
3814
  id,
3860
3815
  type,
3861
3816
  name,
3862
- description,
3817
+ description: description || void 0,
3863
3818
  acceptanceCriteria: acceptanceCriteria2,
3864
3819
  status: "todo"
3865
3820
  });
3866
3821
  saveBacklog(items);
3867
3822
  commitBacklog(id, name);
3868
- console.log(chalk45.green(`Added item #${id}: ${name}`));
3823
+ console.log(chalk44.green(`Added item #${id}: ${name}`));
3869
3824
  }
3870
3825
  async function add(options2) {
3871
3826
  if (!backlogExists()) {
3872
3827
  console.log(
3873
- chalk45.yellow(
3828
+ chalk44.yellow(
3874
3829
  "No backlog found. Run 'assist backlog init' to create one."
3875
3830
  )
3876
3831
  );
3877
3832
  return;
3878
3833
  }
3879
- if (options2.file) {
3880
- addFromFile(options2.file);
3881
- } else {
3882
- await addInteractive();
3834
+ await addFromOptions(options2);
3835
+ }
3836
+
3837
+ // src/commands/backlog/addPhase.ts
3838
+ import chalk45 from "chalk";
3839
+ function addPhase(id, name, options2) {
3840
+ const result = loadAndFindItem(id);
3841
+ if (!result) return;
3842
+ const tasks = options2.task ?? [];
3843
+ if (tasks.length === 0) {
3844
+ console.log(chalk45.red("At least one --task is required."));
3845
+ process.exitCode = 1;
3846
+ return;
3883
3847
  }
3848
+ const dir = getBacklogDir();
3849
+ const db = openDb(dir);
3850
+ const itemId = result.item.id;
3851
+ const existing = db.prepare("SELECT COUNT(*) as cnt FROM plan_phases WHERE item_id = ?").get(itemId);
3852
+ const phaseIdx = existing.cnt;
3853
+ const manualChecks = options2.manualCheck && options2.manualCheck.length > 0 ? JSON.stringify(options2.manualCheck) : null;
3854
+ db.prepare(
3855
+ "INSERT INTO plan_phases (item_id, idx, name, manual_checks) VALUES (?, ?, ?, ?)"
3856
+ ).run(itemId, phaseIdx, name, manualChecks);
3857
+ const taskStmt = db.prepare(
3858
+ "INSERT INTO plan_tasks (item_id, phase_idx, idx, task) VALUES (?, ?, ?, ?)"
3859
+ );
3860
+ for (let i = 0; i < tasks.length; i++) {
3861
+ taskStmt.run(itemId, phaseIdx, i, tasks[i]);
3862
+ }
3863
+ exportToJsonl(db, dir);
3864
+ commitBacklog(itemId, result.item.name);
3865
+ console.log(
3866
+ chalk45.green(
3867
+ `Added phase ${phaseIdx + 1} "${name}" to item #${itemId} with ${tasks.length} task(s).`
3868
+ )
3869
+ );
3884
3870
  }
3885
3871
 
3886
3872
  // src/commands/backlog/init/index.ts
@@ -3911,14 +3897,15 @@ async function list2(options2) {
3911
3897
  );
3912
3898
  return;
3913
3899
  }
3914
- const items = filterItems(loadBacklog(), options2);
3900
+ const allItems = loadBacklog();
3901
+ const items = filterItems(allItems, options2);
3915
3902
  if (items.length === 0) {
3916
3903
  console.log(chalk47.dim("Backlog is empty."));
3917
3904
  return;
3918
3905
  }
3919
3906
  for (const item of items) {
3920
3907
  console.log(
3921
- `${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk47.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}${dependencyLabel(item)}`
3908
+ `${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk47.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}${dependencyLabel(item, allItems)}`
3922
3909
  );
3923
3910
  if (options2.verbose) {
3924
3911
  printVerboseDetails(item);
@@ -3933,7 +3920,11 @@ function registerItemCommands(cmd) {
3933
3920
  "--status <type>",
3934
3921
  "Filter by status (todo, in-progress, done, wontdo)"
3935
3922
  ).option("-a, --all", "Include done/wontdo items").option("-v, --verbose", "Show all item details").action(list2);
3936
- cmd.command("add").description("Add a new backlog item").option("--file <path>", "Read item as JSON from a file").action(add);
3923
+ cmd.command("add").description("Add a new backlog item").option("--name <name>", "Item name").option("--type <type>", "Item type (story or bug)").option("--desc <description>", "Item description").option("--ac <criterion...>", "Acceptance criteria (repeatable)").action(add);
3924
+ cmd.command("add-phase <id> <name>").description("Add a phase to an existing backlog item").option("--task <task...>", "Task description (repeatable)").option(
3925
+ "--manual-check <check...>",
3926
+ "Manual check description (repeatable)"
3927
+ ).action(addPhase);
3937
3928
  }
3938
3929
 
3939
3930
  // src/commands/backlog/link.ts
@@ -4227,7 +4218,7 @@ function extractGraphqlQuery(args) {
4227
4218
  }
4228
4219
 
4229
4220
  // src/shared/loadCliReads.ts
4230
- import { existsSync as existsSync19, readFileSync as readFileSync17, writeFileSync as writeFileSync15 } from "fs";
4221
+ import { existsSync as existsSync18, readFileSync as readFileSync16, writeFileSync as writeFileSync15 } from "fs";
4231
4222
  import { dirname as dirname14, resolve as resolve2 } from "path";
4232
4223
  import { fileURLToPath as fileURLToPath4 } from "url";
4233
4224
  var __filename2 = fileURLToPath4(import.meta.url);
@@ -4236,8 +4227,8 @@ function packageRoot() {
4236
4227
  return __dirname4;
4237
4228
  }
4238
4229
  function readLines(path50) {
4239
- if (!existsSync19(path50)) return [];
4240
- return readFileSync17(path50, "utf-8").split("\n").filter((line) => line.trim() !== "");
4230
+ if (!existsSync18(path50)) return [];
4231
+ return readFileSync16(path50, "utf-8").split("\n").filter((line) => line.trim() !== "");
4241
4232
  }
4242
4233
  var cachedReads;
4243
4234
  var cachedWrites;
@@ -4283,7 +4274,7 @@ function findCliWrite(command) {
4283
4274
  }
4284
4275
 
4285
4276
  // src/shared/readSettingsPerms.ts
4286
- import { existsSync as existsSync20, readFileSync as readFileSync18 } from "fs";
4277
+ import { existsSync as existsSync19, readFileSync as readFileSync17 } from "fs";
4287
4278
  import { homedir as homedir3 } from "os";
4288
4279
  import { join as join16 } from "path";
4289
4280
  function readSettingsPerms(key) {
@@ -4299,9 +4290,9 @@ function readSettingsPerms(key) {
4299
4290
  return entries;
4300
4291
  }
4301
4292
  function readPermissionArray(filePath, key) {
4302
- if (!existsSync20(filePath)) return [];
4293
+ if (!existsSync19(filePath)) return [];
4303
4294
  try {
4304
- const data = JSON.parse(readFileSync18(filePath, "utf-8"));
4295
+ const data = JSON.parse(readFileSync17(filePath, "utf-8"));
4305
4296
  const arr = data?.permissions?.[key];
4306
4297
  return Array.isArray(arr) ? arr.filter((e) => typeof e === "string") : [];
4307
4298
  } catch {
@@ -4392,6 +4383,18 @@ function matchesConfigDeny(command) {
4392
4383
 
4393
4384
  // src/shared/splitCompound.ts
4394
4385
  import { parse } from "shell-quote";
4386
+
4387
+ // src/shared/hasUnquotedBackticks.ts
4388
+ var QUOTED_OR_BACKTICK_RE = /\\.|'[^']*'|"[^"]*"|(`)/g;
4389
+ function hasUnquotedBackticks(command) {
4390
+ QUOTED_OR_BACKTICK_RE.lastIndex = 0;
4391
+ for (let m = QUOTED_OR_BACKTICK_RE.exec(command); m !== null; m = QUOTED_OR_BACKTICK_RE.exec(command)) {
4392
+ if (m[1] !== void 0) return true;
4393
+ }
4394
+ return false;
4395
+ }
4396
+
4397
+ // src/shared/splitCompound.ts
4395
4398
  var SEPARATOR_OPS = /* @__PURE__ */ new Set(["|", "&&", "||", ";"]);
4396
4399
  var UNSAFE_OPS = /* @__PURE__ */ new Set(["(", ")", ">", ">>", "<", "<&", "|&", ">&"]);
4397
4400
  var FD_REDIRECT_RE = /\d+>&\d+/g;
@@ -4407,12 +4410,9 @@ function splitCompound(command) {
4407
4410
  function tokenizeCommand(command) {
4408
4411
  const trimmed = command.trim().replace(FD_DEVNULL_RE, "").replace(FD_REDIRECT_RE, "");
4409
4412
  if (!trimmed) return void 0;
4413
+ if (hasUnquotedBackticks(trimmed)) return void 0;
4410
4414
  try {
4411
- const tokens = parse(trimmed);
4412
- const hasBacktick = tokens.some(
4413
- (t) => typeof t === "string" && /`.+`/.test(t)
4414
- );
4415
- return hasBacktick ? void 0 : tokens;
4415
+ return parse(trimmed);
4416
4416
  } catch {
4417
4417
  return void 0;
4418
4418
  }
@@ -4586,7 +4586,7 @@ function denyRemove(pattern2) {
4586
4586
  }
4587
4587
 
4588
4588
  // src/commands/permitCliReads/index.ts
4589
- import { existsSync as existsSync21, mkdirSync as mkdirSync5, readFileSync as readFileSync19, writeFileSync as writeFileSync16 } from "fs";
4589
+ import { existsSync as existsSync20, mkdirSync as mkdirSync5, readFileSync as readFileSync18, writeFileSync as writeFileSync16 } from "fs";
4590
4590
  import { homedir as homedir4 } from "os";
4591
4591
  import { join as join17 } from "path";
4592
4592
 
@@ -4894,8 +4894,8 @@ function logPath(cli) {
4894
4894
  }
4895
4895
  function readCache(cli) {
4896
4896
  const path50 = logPath(cli);
4897
- if (!existsSync21(path50)) return void 0;
4898
- return readFileSync19(path50, "utf-8");
4897
+ if (!existsSync20(path50)) return void 0;
4898
+ return readFileSync18(path50, "utf-8");
4899
4899
  }
4900
4900
  function writeCache(cli, output) {
4901
4901
  const dir = join17(homedir4(), ".assist");
@@ -5447,7 +5447,7 @@ function registerComplexity(program2) {
5447
5447
  }
5448
5448
 
5449
5449
  // src/commands/deploy/redirect.ts
5450
- import { existsSync as existsSync22, readFileSync as readFileSync20, writeFileSync as writeFileSync17 } from "fs";
5450
+ import { existsSync as existsSync21, readFileSync as readFileSync19, writeFileSync as writeFileSync17 } from "fs";
5451
5451
  import chalk65 from "chalk";
5452
5452
  var TRAILING_SLASH_SCRIPT = ` <script>
5453
5453
  if (!window.location.pathname.endsWith('/')) {
@@ -5456,11 +5456,11 @@ var TRAILING_SLASH_SCRIPT = ` <script>
5456
5456
  </script>`;
5457
5457
  function redirect() {
5458
5458
  const indexPath = "index.html";
5459
- if (!existsSync22(indexPath)) {
5459
+ if (!existsSync21(indexPath)) {
5460
5460
  console.log(chalk65.yellow("No index.html found"));
5461
5461
  return;
5462
5462
  }
5463
- const content = readFileSync20(indexPath, "utf-8");
5463
+ const content = readFileSync19(indexPath, "utf-8");
5464
5464
  if (content.includes("window.location.pathname.endsWith('/')")) {
5465
5465
  console.log(chalk65.dim("Trailing slash script already present"));
5466
5466
  return;
@@ -5502,7 +5502,7 @@ import { execSync as execSync17 } from "child_process";
5502
5502
  import chalk66 from "chalk";
5503
5503
 
5504
5504
  // src/commands/devlog/loadDevlogEntries.ts
5505
- import { readdirSync, readFileSync as readFileSync21 } from "fs";
5505
+ import { readdirSync, readFileSync as readFileSync20 } from "fs";
5506
5506
  import { join as join19 } from "path";
5507
5507
  var DEVLOG_DIR = join19(BLOG_REPO_ROOT, "src/content/devlog");
5508
5508
  function extractFrontmatter(content) {
@@ -5532,7 +5532,7 @@ function readDevlogFiles(callback) {
5532
5532
  try {
5533
5533
  const files = readdirSync(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
5534
5534
  for (const file of files) {
5535
- const content = readFileSync21(join19(DEVLOG_DIR, file), "utf-8");
5535
+ const content = readFileSync20(join19(DEVLOG_DIR, file), "utf-8");
5536
5536
  const parsed = parseFrontmatter(content, file);
5537
5537
  if (parsed) callback(parsed);
5538
5538
  }
@@ -5988,12 +5988,12 @@ import { join as join21 } from "path";
5988
5988
  import chalk73 from "chalk";
5989
5989
 
5990
5990
  // src/shared/findRepoRoot.ts
5991
- import { existsSync as existsSync23 } from "fs";
5991
+ import { existsSync as existsSync22 } from "fs";
5992
5992
  import path21 from "path";
5993
5993
  function findRepoRoot(dir) {
5994
5994
  let current = dir;
5995
5995
  while (current !== path21.dirname(current)) {
5996
- if (existsSync23(path21.join(current, ".git"))) {
5996
+ if (existsSync22(path21.join(current, ".git"))) {
5997
5997
  return current;
5998
5998
  }
5999
5999
  current = path21.dirname(current);
@@ -6059,11 +6059,11 @@ async function checkBuildLocksCommand() {
6059
6059
  }
6060
6060
 
6061
6061
  // src/commands/dotnet/buildTree.ts
6062
- import { readFileSync as readFileSync22 } from "fs";
6062
+ import { readFileSync as readFileSync21 } from "fs";
6063
6063
  import path22 from "path";
6064
6064
  var PROJECT_REF_RE = /<ProjectReference\s+Include="([^"]+)"/g;
6065
6065
  function getProjectRefs(csprojPath) {
6066
- const content = readFileSync22(csprojPath, "utf-8");
6066
+ const content = readFileSync21(csprojPath, "utf-8");
6067
6067
  const refs = [];
6068
6068
  for (const match of content.matchAll(PROJECT_REF_RE)) {
6069
6069
  refs.push(match[1].replace(/\\/g, "/"));
@@ -6080,7 +6080,7 @@ function buildTree(csprojPath, repoRoot, visited = /* @__PURE__ */ new Set()) {
6080
6080
  for (const ref of getProjectRefs(abs)) {
6081
6081
  const childAbs = path22.resolve(dir, ref);
6082
6082
  try {
6083
- readFileSync22(childAbs);
6083
+ readFileSync21(childAbs);
6084
6084
  node.children.push(buildTree(childAbs, repoRoot, visited));
6085
6085
  } catch {
6086
6086
  node.children.push({
@@ -6105,7 +6105,7 @@ function collectAllDeps(node) {
6105
6105
  }
6106
6106
 
6107
6107
  // src/commands/dotnet/findContainingSolutions.ts
6108
- import { readdirSync as readdirSync3, readFileSync as readFileSync23, statSync as statSync3 } from "fs";
6108
+ import { readdirSync as readdirSync3, readFileSync as readFileSync22, statSync as statSync3 } from "fs";
6109
6109
  import path23 from "path";
6110
6110
  function findSlnFiles(dir, maxDepth, depth = 0) {
6111
6111
  if (depth > maxDepth) return [];
@@ -6140,7 +6140,7 @@ function findContainingSolutions(csprojPath, repoRoot) {
6140
6140
  const pattern2 = new RegExp(`[\\\\"/]${escapeRegex(csprojBasename)}"`);
6141
6141
  for (const sln of slnFiles) {
6142
6142
  try {
6143
- const content = readFileSync23(sln, "utf-8");
6143
+ const content = readFileSync22(sln, "utf-8");
6144
6144
  if (pattern2.test(content)) {
6145
6145
  matches.push(path23.relative(repoRoot, sln));
6146
6146
  }
@@ -6204,12 +6204,12 @@ function printJson(tree, totalCount, solutions) {
6204
6204
  }
6205
6205
 
6206
6206
  // src/commands/dotnet/resolveCsproj.ts
6207
- import { existsSync as existsSync24 } from "fs";
6207
+ import { existsSync as existsSync23 } from "fs";
6208
6208
  import path24 from "path";
6209
6209
  import chalk75 from "chalk";
6210
6210
  function resolveCsproj(csprojPath) {
6211
6211
  const resolved = path24.resolve(csprojPath);
6212
- if (!existsSync24(resolved)) {
6212
+ if (!existsSync23(resolved)) {
6213
6213
  console.error(chalk75.red(`File not found: ${resolved}`));
6214
6214
  process.exit(1);
6215
6215
  }
@@ -6377,7 +6377,7 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
6377
6377
  }
6378
6378
 
6379
6379
  // src/commands/dotnet/resolveSolution.ts
6380
- import { existsSync as existsSync25 } from "fs";
6380
+ import { existsSync as existsSync24 } from "fs";
6381
6381
  import path25 from "path";
6382
6382
  import chalk79 from "chalk";
6383
6383
 
@@ -6418,7 +6418,7 @@ function findSolution() {
6418
6418
  function resolveSolution(sln) {
6419
6419
  if (sln) {
6420
6420
  const resolved = path25.resolve(sln);
6421
- if (!existsSync25(resolved)) {
6421
+ if (!existsSync24(resolved)) {
6422
6422
  console.error(chalk79.red(`Solution file not found: ${resolved}`));
6423
6423
  process.exit(1);
6424
6424
  }
@@ -6458,7 +6458,7 @@ function parseInspectReport(json) {
6458
6458
 
6459
6459
  // src/commands/dotnet/runInspectCode.ts
6460
6460
  import { execSync as execSync23 } from "child_process";
6461
- import { existsSync as existsSync26, readFileSync as readFileSync24, unlinkSync as unlinkSync5 } from "fs";
6461
+ import { existsSync as existsSync25, readFileSync as readFileSync23, unlinkSync as unlinkSync5 } from "fs";
6462
6462
  import { tmpdir as tmpdir2 } from "os";
6463
6463
  import path26 from "path";
6464
6464
  import chalk80 from "chalk";
@@ -6489,11 +6489,11 @@ function runInspectCode(slnPath, include, swea) {
6489
6489
  console.error(chalk80.red("jb inspectcode failed"));
6490
6490
  process.exit(1);
6491
6491
  }
6492
- if (!existsSync26(reportPath)) {
6492
+ if (!existsSync25(reportPath)) {
6493
6493
  console.error(chalk80.red("Report file not generated"));
6494
6494
  process.exit(1);
6495
6495
  }
6496
- const xml = readFileSync24(reportPath, "utf-8");
6496
+ const xml = readFileSync23(reportPath, "utf-8");
6497
6497
  unlinkSync5(reportPath);
6498
6498
  return xml;
6499
6499
  }
@@ -6721,7 +6721,7 @@ function acceptanceCriteria(issueKey) {
6721
6721
  import { execSync as execSync26 } from "child_process";
6722
6722
 
6723
6723
  // src/shared/loadJson.ts
6724
- import { existsSync as existsSync27, mkdirSync as mkdirSync6, readFileSync as readFileSync25, writeFileSync as writeFileSync19 } from "fs";
6724
+ import { existsSync as existsSync26, mkdirSync as mkdirSync6, readFileSync as readFileSync24, writeFileSync as writeFileSync19 } from "fs";
6725
6725
  import { homedir as homedir6 } from "os";
6726
6726
  import { join as join23 } from "path";
6727
6727
  function getStoreDir() {
@@ -6732,9 +6732,9 @@ function getStorePath(filename) {
6732
6732
  }
6733
6733
  function loadJson(filename) {
6734
6734
  const path50 = getStorePath(filename);
6735
- if (existsSync27(path50)) {
6735
+ if (existsSync26(path50)) {
6736
6736
  try {
6737
- return JSON.parse(readFileSync25(path50, "utf-8"));
6737
+ return JSON.parse(readFileSync24(path50, "utf-8"));
6738
6738
  } catch {
6739
6739
  return {};
6740
6740
  }
@@ -6743,7 +6743,7 @@ function loadJson(filename) {
6743
6743
  }
6744
6744
  function saveJson(filename, data) {
6745
6745
  const dir = getStoreDir();
6746
- if (!existsSync27(dir)) {
6746
+ if (!existsSync26(dir)) {
6747
6747
  mkdirSync6(dir, { recursive: true });
6748
6748
  }
6749
6749
  writeFileSync19(getStorePath(filename), JSON.stringify(data, null, 2));
@@ -7180,7 +7180,7 @@ import { tmpdir as tmpdir4 } from "os";
7180
7180
  import { join as join26 } from "path";
7181
7181
 
7182
7182
  // src/commands/prs/loadCommentsCache.ts
7183
- import { existsSync as existsSync28, readFileSync as readFileSync26, unlinkSync as unlinkSync7 } from "fs";
7183
+ import { existsSync as existsSync27, readFileSync as readFileSync25, unlinkSync as unlinkSync7 } from "fs";
7184
7184
  import { join as join25 } from "path";
7185
7185
  import { parse as parse2 } from "yaml";
7186
7186
  function getCachePath(prNumber) {
@@ -7188,15 +7188,15 @@ function getCachePath(prNumber) {
7188
7188
  }
7189
7189
  function loadCommentsCache(prNumber) {
7190
7190
  const cachePath = getCachePath(prNumber);
7191
- if (!existsSync28(cachePath)) {
7191
+ if (!existsSync27(cachePath)) {
7192
7192
  return null;
7193
7193
  }
7194
- const content = readFileSync26(cachePath, "utf-8");
7194
+ const content = readFileSync25(cachePath, "utf-8");
7195
7195
  return parse2(content);
7196
7196
  }
7197
7197
  function deleteCommentsCache(prNumber) {
7198
7198
  const cachePath = getCachePath(prNumber);
7199
- if (existsSync28(cachePath)) {
7199
+ if (existsSync27(cachePath)) {
7200
7200
  unlinkSync7(cachePath);
7201
7201
  console.log("No more unresolved line comments. Cache dropped.");
7202
7202
  }
@@ -7293,7 +7293,7 @@ function fixed(commentId, sha) {
7293
7293
  }
7294
7294
 
7295
7295
  // src/commands/prs/listComments/index.ts
7296
- import { existsSync as existsSync29, mkdirSync as mkdirSync7, writeFileSync as writeFileSync23 } from "fs";
7296
+ import { existsSync as existsSync28, mkdirSync as mkdirSync7, writeFileSync as writeFileSync23 } from "fs";
7297
7297
  import { join as join28 } from "path";
7298
7298
  import { stringify } from "yaml";
7299
7299
 
@@ -7419,7 +7419,7 @@ function printComments2(result) {
7419
7419
  // src/commands/prs/listComments/index.ts
7420
7420
  function writeCommentsCache(prNumber, comments2) {
7421
7421
  const assistDir = join28(process.cwd(), ".assist");
7422
- if (!existsSync29(assistDir)) {
7422
+ if (!existsSync28(assistDir)) {
7423
7423
  mkdirSync7(assistDir, { recursive: true });
7424
7424
  }
7425
7425
  const cacheData = {
@@ -9854,7 +9854,7 @@ function registerSeq(program2) {
9854
9854
  }
9855
9855
 
9856
9856
  // src/commands/transcript/shared.ts
9857
- import { existsSync as existsSync30, readdirSync as readdirSync5, statSync as statSync4 } from "fs";
9857
+ import { existsSync as existsSync29, readdirSync as readdirSync5, statSync as statSync4 } from "fs";
9858
9858
  import { basename as basename4, join as join29, relative } from "path";
9859
9859
  import * as readline2 from "readline";
9860
9860
  var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
@@ -9870,7 +9870,7 @@ function isValidDatePrefix(filename) {
9870
9870
  return DATE_PREFIX_REGEX.test(filename);
9871
9871
  }
9872
9872
  function collectFiles(dir, extension) {
9873
- if (!existsSync30(dir)) return [];
9873
+ if (!existsSync29(dir)) return [];
9874
9874
  const results = [];
9875
9875
  for (const entry of readdirSync5(dir)) {
9876
9876
  const fullPath = join29(dir, entry);
@@ -9967,7 +9967,7 @@ async function configure() {
9967
9967
  }
9968
9968
 
9969
9969
  // src/commands/transcript/format/index.ts
9970
- import { existsSync as existsSync32 } from "fs";
9970
+ import { existsSync as existsSync31 } from "fs";
9971
9971
 
9972
9972
  // src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
9973
9973
  import { dirname as dirname18, join as join31 } from "path";
@@ -10041,7 +10041,7 @@ async function fixInvalidDatePrefixes(vttFiles) {
10041
10041
  }
10042
10042
 
10043
10043
  // src/commands/transcript/format/processVttFile/index.ts
10044
- import { existsSync as existsSync31, mkdirSync as mkdirSync8, readFileSync as readFileSync27, writeFileSync as writeFileSync24 } from "fs";
10044
+ import { existsSync as existsSync30, mkdirSync as mkdirSync8, readFileSync as readFileSync26, writeFileSync as writeFileSync24 } from "fs";
10045
10045
  import { basename as basename5, dirname as dirname19, join as join32 } from "path";
10046
10046
 
10047
10047
  // src/commands/transcript/cleanText.ts
@@ -10266,7 +10266,7 @@ function logSkipped(relativeDir, mdFile) {
10266
10266
  return "skipped";
10267
10267
  }
10268
10268
  function ensureDirectory(dir, label2) {
10269
- if (!existsSync31(dir)) {
10269
+ if (!existsSync30(dir)) {
10270
10270
  mkdirSync8(dir, { recursive: true });
10271
10271
  console.log(`Created ${label2}: ${dir}`);
10272
10272
  }
@@ -10289,7 +10289,7 @@ function logReduction(cueCount, messageCount) {
10289
10289
  }
10290
10290
  function readAndParseCues(inputPath) {
10291
10291
  console.log(`Reading: ${inputPath}`);
10292
- return processCues(readFileSync27(inputPath, "utf-8"));
10292
+ return processCues(readFileSync26(inputPath, "utf-8"));
10293
10293
  }
10294
10294
  function writeFormatted(outputPath, content) {
10295
10295
  writeFileSync24(outputPath, content, "utf-8");
@@ -10302,7 +10302,7 @@ function convertVttToMarkdown(inputPath, outputPath) {
10302
10302
  logReduction(cues.length, chatMessages.length);
10303
10303
  }
10304
10304
  function tryProcessVtt(vttFile, paths) {
10305
- if (existsSync31(paths.outputPath))
10305
+ if (existsSync30(paths.outputPath))
10306
10306
  return logSkipped(paths.relativeDir, paths.mdFile);
10307
10307
  convertVttToMarkdown(vttFile.absolutePath, paths.outputPath);
10308
10308
  return "processed";
@@ -10328,7 +10328,7 @@ function processAllFiles(vttFiles, transcriptsDir) {
10328
10328
  logSummary(counts);
10329
10329
  }
10330
10330
  function requireVttDir(vttDir) {
10331
- if (!existsSync32(vttDir)) {
10331
+ if (!existsSync31(vttDir)) {
10332
10332
  console.error(`VTT directory not found: ${vttDir}`);
10333
10333
  process.exit(1);
10334
10334
  }
@@ -10360,14 +10360,14 @@ async function format() {
10360
10360
  }
10361
10361
 
10362
10362
  // src/commands/transcript/summarise/index.ts
10363
- import { existsSync as existsSync34 } from "fs";
10363
+ import { existsSync as existsSync33 } from "fs";
10364
10364
  import { basename as basename6, dirname as dirname21, join as join34, relative as relative2 } from "path";
10365
10365
 
10366
10366
  // src/commands/transcript/summarise/processStagedFile/index.ts
10367
10367
  import {
10368
- existsSync as existsSync33,
10368
+ existsSync as existsSync32,
10369
10369
  mkdirSync as mkdirSync9,
10370
- readFileSync as readFileSync28,
10370
+ readFileSync as readFileSync27,
10371
10371
  renameSync as renameSync3,
10372
10372
  rmSync
10373
10373
  } from "fs";
@@ -10402,7 +10402,7 @@ function validateStagedContent(filename, content) {
10402
10402
  // src/commands/transcript/summarise/processStagedFile/index.ts
10403
10403
  var STAGING_DIR = join33(process.cwd(), ".assist", "transcript");
10404
10404
  function processStagedFile() {
10405
- if (!existsSync33(STAGING_DIR)) {
10405
+ if (!existsSync32(STAGING_DIR)) {
10406
10406
  return false;
10407
10407
  }
10408
10408
  const stagedFiles = findMdFilesRecursive(STAGING_DIR);
@@ -10411,7 +10411,7 @@ function processStagedFile() {
10411
10411
  }
10412
10412
  const { transcriptsDir, summaryDir } = getTranscriptConfig();
10413
10413
  const stagedFile = stagedFiles[0];
10414
- const content = readFileSync28(stagedFile.absolutePath, "utf-8");
10414
+ const content = readFileSync27(stagedFile.absolutePath, "utf-8");
10415
10415
  validateStagedContent(stagedFile.filename, content);
10416
10416
  const stagedBaseName = getTranscriptBaseName(stagedFile.filename);
10417
10417
  const transcriptFiles = findMdFilesRecursive(transcriptsDir);
@@ -10426,7 +10426,7 @@ function processStagedFile() {
10426
10426
  }
10427
10427
  const destPath = join33(summaryDir, matchingTranscript.relativePath);
10428
10428
  const destDir = dirname20(destPath);
10429
- if (!existsSync33(destDir)) {
10429
+ if (!existsSync32(destDir)) {
10430
10430
  mkdirSync9(destDir, { recursive: true });
10431
10431
  }
10432
10432
  renameSync3(stagedFile.absolutePath, destPath);
@@ -10453,7 +10453,7 @@ function buildSummaryIndex(summaryDir) {
10453
10453
  function summarise2() {
10454
10454
  processStagedFile();
10455
10455
  const { transcriptsDir, summaryDir } = getTranscriptConfig();
10456
- if (!existsSync34(transcriptsDir)) {
10456
+ if (!existsSync33(transcriptsDir)) {
10457
10457
  console.log("No transcripts directory found.");
10458
10458
  return;
10459
10459
  }
@@ -10557,14 +10557,14 @@ function devices() {
10557
10557
  }
10558
10558
 
10559
10559
  // src/commands/voice/logs.ts
10560
- import { existsSync as existsSync35, readFileSync as readFileSync29 } from "fs";
10560
+ import { existsSync as existsSync34, readFileSync as readFileSync28 } from "fs";
10561
10561
  function logs(options2) {
10562
- if (!existsSync35(voicePaths.log)) {
10562
+ if (!existsSync34(voicePaths.log)) {
10563
10563
  console.log("No voice log file found");
10564
10564
  return;
10565
10565
  }
10566
10566
  const count = Number.parseInt(options2.lines ?? "150", 10);
10567
- const content = readFileSync29(voicePaths.log, "utf-8").trim();
10567
+ const content = readFileSync28(voicePaths.log, "utf-8").trim();
10568
10568
  if (!content) {
10569
10569
  console.log("Voice log is empty");
10570
10570
  return;
@@ -10591,7 +10591,7 @@ import { join as join38 } from "path";
10591
10591
 
10592
10592
  // src/commands/voice/checkLockFile.ts
10593
10593
  import { execSync as execSync37 } from "child_process";
10594
- import { existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as readFileSync30, writeFileSync as writeFileSync25 } from "fs";
10594
+ import { existsSync as existsSync35, mkdirSync as mkdirSync10, readFileSync as readFileSync29, writeFileSync as writeFileSync25 } from "fs";
10595
10595
  import { join as join37 } from "path";
10596
10596
  function isProcessAlive2(pid) {
10597
10597
  try {
@@ -10603,9 +10603,9 @@ function isProcessAlive2(pid) {
10603
10603
  }
10604
10604
  function checkLockFile() {
10605
10605
  const lockFile = getLockFile();
10606
- if (!existsSync36(lockFile)) return;
10606
+ if (!existsSync35(lockFile)) return;
10607
10607
  try {
10608
- const lock = JSON.parse(readFileSync30(lockFile, "utf-8"));
10608
+ const lock = JSON.parse(readFileSync29(lockFile, "utf-8"));
10609
10609
  if (lock.pid && isProcessAlive2(lock.pid)) {
10610
10610
  console.error(
10611
10611
  `Voice daemon already running (PID ${lock.pid}, env: ${lock.env}). Stop it first with: assist voice stop`
@@ -10616,7 +10616,7 @@ function checkLockFile() {
10616
10616
  }
10617
10617
  }
10618
10618
  function bootstrapVenv() {
10619
- if (existsSync36(getVenvPython())) return;
10619
+ if (existsSync35(getVenvPython())) return;
10620
10620
  console.log("Setting up Python environment...");
10621
10621
  const pythonDir = getPythonDir();
10622
10622
  execSync37(
@@ -10707,7 +10707,7 @@ function start2(options2) {
10707
10707
  }
10708
10708
 
10709
10709
  // src/commands/voice/status.ts
10710
- import { existsSync as existsSync37, readFileSync as readFileSync31 } from "fs";
10710
+ import { existsSync as existsSync36, readFileSync as readFileSync30 } from "fs";
10711
10711
  function isProcessAlive3(pid) {
10712
10712
  try {
10713
10713
  process.kill(pid, 0);
@@ -10717,16 +10717,16 @@ function isProcessAlive3(pid) {
10717
10717
  }
10718
10718
  }
10719
10719
  function readRecentLogs(count) {
10720
- if (!existsSync37(voicePaths.log)) return [];
10721
- const lines = readFileSync31(voicePaths.log, "utf-8").trim().split("\n");
10720
+ if (!existsSync36(voicePaths.log)) return [];
10721
+ const lines = readFileSync30(voicePaths.log, "utf-8").trim().split("\n");
10722
10722
  return lines.slice(-count);
10723
10723
  }
10724
10724
  function status() {
10725
- if (!existsSync37(voicePaths.pid)) {
10725
+ if (!existsSync36(voicePaths.pid)) {
10726
10726
  console.log("Voice daemon: not running (no PID file)");
10727
10727
  return;
10728
10728
  }
10729
- const pid = Number.parseInt(readFileSync31(voicePaths.pid, "utf-8").trim(), 10);
10729
+ const pid = Number.parseInt(readFileSync30(voicePaths.pid, "utf-8").trim(), 10);
10730
10730
  const alive = isProcessAlive3(pid);
10731
10731
  console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
10732
10732
  const recent = readRecentLogs(5);
@@ -10745,13 +10745,13 @@ function status() {
10745
10745
  }
10746
10746
 
10747
10747
  // src/commands/voice/stop.ts
10748
- import { existsSync as existsSync38, readFileSync as readFileSync32, unlinkSync as unlinkSync10 } from "fs";
10748
+ import { existsSync as existsSync37, readFileSync as readFileSync31, unlinkSync as unlinkSync10 } from "fs";
10749
10749
  function stop() {
10750
- if (!existsSync38(voicePaths.pid)) {
10750
+ if (!existsSync37(voicePaths.pid)) {
10751
10751
  console.log("Voice daemon is not running (no PID file)");
10752
10752
  return;
10753
10753
  }
10754
- const pid = Number.parseInt(readFileSync32(voicePaths.pid, "utf-8").trim(), 10);
10754
+ const pid = Number.parseInt(readFileSync31(voicePaths.pid, "utf-8").trim(), 10);
10755
10755
  try {
10756
10756
  process.kill(pid, "SIGTERM");
10757
10757
  console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
@@ -10764,7 +10764,7 @@ function stop() {
10764
10764
  }
10765
10765
  try {
10766
10766
  const lockFile = getLockFile();
10767
- if (existsSync38(lockFile)) unlinkSync10(lockFile);
10767
+ if (existsSync37(lockFile)) unlinkSync10(lockFile);
10768
10768
  } catch {
10769
10769
  }
10770
10770
  console.log("Voice daemon stopped");
@@ -10985,7 +10985,7 @@ async function auth() {
10985
10985
  }
10986
10986
 
10987
10987
  // src/commands/roam/showClaudeCodeIcon.ts
10988
- import { readFileSync as readFileSync33 } from "fs";
10988
+ import { readFileSync as readFileSync32 } from "fs";
10989
10989
  import { join as join40 } from "path";
10990
10990
  async function showClaudeCodeIcon() {
10991
10991
  const appData = process.env.APPDATA;
@@ -10993,7 +10993,7 @@ async function showClaudeCodeIcon() {
10993
10993
  const portFile = join40(appData, "Roam", "roam-local-api.port");
10994
10994
  let port;
10995
10995
  try {
10996
- port = readFileSync33(portFile, "utf-8").trim();
10996
+ port = readFileSync32(portFile, "utf-8").trim();
10997
10997
  } catch {
10998
10998
  return;
10999
10999
  }
@@ -11190,7 +11190,7 @@ function run3(name, args) {
11190
11190
 
11191
11191
  // src/commands/screenshot/index.ts
11192
11192
  import { execSync as execSync40 } from "child_process";
11193
- import { existsSync as existsSync39, mkdirSync as mkdirSync14, unlinkSync as unlinkSync11, writeFileSync as writeFileSync28 } from "fs";
11193
+ import { existsSync as existsSync38, mkdirSync as mkdirSync14, unlinkSync as unlinkSync11, writeFileSync as writeFileSync28 } from "fs";
11194
11194
  import { tmpdir as tmpdir6 } from "os";
11195
11195
  import { join as join42, resolve as resolve5 } from "path";
11196
11196
  import chalk121 from "chalk";
@@ -11322,7 +11322,7 @@ Write-Output $OutputPath
11322
11322
 
11323
11323
  // src/commands/screenshot/index.ts
11324
11324
  function buildOutputPath(outputDir, processName) {
11325
- if (!existsSync39(outputDir)) {
11325
+ if (!existsSync38(outputDir)) {
11326
11326
  mkdirSync14(outputDir, { recursive: true });
11327
11327
  }
11328
11328
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");