@staff0rd/assist 0.158.1 → 0.159.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.158.1",
9
+ version: "0.159.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -256,6 +256,45 @@ async function exitOnCancel(promise) {
256
256
  }
257
257
  }
258
258
 
259
+ // src/commands/backlog/acquireLock.ts
260
+ import { existsSync as existsSync2, readFileSync as readFileSync2, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
261
+ import { join as join2 } from "path";
262
+ function getLockPath(itemId) {
263
+ return join2(process.cwd(), `.assist-lock-${itemId}.json`);
264
+ }
265
+ function isProcessAlive(pid) {
266
+ try {
267
+ process.kill(pid, 0);
268
+ return true;
269
+ } catch {
270
+ return false;
271
+ }
272
+ }
273
+ function isLockedByOther(itemId) {
274
+ const lockPath = getLockPath(itemId);
275
+ if (!existsSync2(lockPath)) return false;
276
+ try {
277
+ const lock = JSON.parse(readFileSync2(lockPath, "utf-8"));
278
+ if (lock.pid === process.pid) return false;
279
+ return isProcessAlive(lock.pid);
280
+ } catch {
281
+ return false;
282
+ }
283
+ }
284
+ function acquireLock(itemId) {
285
+ writeFileSync2(
286
+ getLockPath(itemId),
287
+ JSON.stringify({ pid: process.pid, timestamp: (/* @__PURE__ */ new Date()).toISOString() })
288
+ );
289
+ }
290
+ function releaseLock(itemId) {
291
+ const lockPath = getLockPath(itemId);
292
+ try {
293
+ unlinkSync(lockPath);
294
+ } catch {
295
+ }
296
+ }
297
+
259
298
  // src/commands/backlog/list/shared.ts
260
299
  import chalk4 from "chalk";
261
300
  function statusIcon(status2) {
@@ -406,7 +445,7 @@ function buildReviewPhase() {
406
445
  import chalk6 from "chalk";
407
446
 
408
447
  // src/commands/backlog/resolvePhaseResult.ts
409
- import { existsSync as existsSync2, unlinkSync } from "fs";
448
+ import { existsSync as existsSync3, unlinkSync as unlinkSync2 } from "fs";
410
449
  import chalk5 from "chalk";
411
450
 
412
451
  // src/commands/backlog/handleIncompletePhase.ts
@@ -426,27 +465,27 @@ async function handleIncompletePhase() {
426
465
  }
427
466
 
428
467
  // src/commands/backlog/writeSignal.ts
429
- import { writeFileSync as writeFileSync2 } from "fs";
430
- import { join as join2 } from "path";
468
+ import { writeFileSync as writeFileSync3 } from "fs";
469
+ import { join as join3 } from "path";
431
470
  var SIGNAL_FILE = ".assist-signal.json";
432
471
  function getSignalPath() {
433
- return join2(process.cwd(), SIGNAL_FILE);
472
+ return join3(process.cwd(), SIGNAL_FILE);
434
473
  }
435
474
  function writeSignal(event, data) {
436
475
  const sessionId = process.env.ASSIST_SESSION_ID;
437
476
  const signal = { event, ...sessionId && { sessionId }, ...data };
438
- writeFileSync2(getSignalPath(), JSON.stringify(signal));
477
+ writeFileSync3(getSignalPath(), JSON.stringify(signal));
439
478
  }
440
479
 
441
480
  // src/commands/backlog/resolvePhaseResult.ts
442
481
  function cleanupSignal() {
443
482
  const statusPath = getSignalPath();
444
- if (existsSync2(statusPath)) {
445
- unlinkSync(statusPath);
483
+ if (existsSync3(statusPath)) {
484
+ unlinkSync2(statusPath);
446
485
  }
447
486
  }
448
487
  async function resolvePhaseResult(phaseIndex) {
449
- if (!existsSync2(getSignalPath())) {
488
+ if (!existsSync3(getSignalPath())) {
450
489
  const action = await handleIncompletePhase();
451
490
  if (action === "abort") return -1;
452
491
  return action === "skip" ? 1 : 0;
@@ -475,15 +514,15 @@ function spawnClaude(prompt, options2 = {}) {
475
514
  }
476
515
 
477
516
  // src/commands/backlog/watchForMarker.ts
478
- import { existsSync as existsSync4, unwatchFile, watchFile } from "fs";
517
+ import { existsSync as existsSync5, unwatchFile, watchFile } from "fs";
479
518
 
480
519
  // src/commands/backlog/readSignal.ts
481
- import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
520
+ import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
482
521
  function readSignal() {
483
522
  const path50 = getSignalPath();
484
- if (!existsSync3(path50)) return void 0;
523
+ if (!existsSync4(path50)) return void 0;
485
524
  try {
486
- return JSON.parse(readFileSync2(path50, "utf-8"));
525
+ return JSON.parse(readFileSync3(path50, "utf-8"));
487
526
  } catch {
488
527
  return void 0;
489
528
  }
@@ -494,7 +533,7 @@ function watchForMarker(child) {
494
533
  const statusPath = getSignalPath();
495
534
  const sessionId = process.env.ASSIST_SESSION_ID;
496
535
  watchFile(statusPath, { interval: 1e3 }, () => {
497
- if (!existsSync4(statusPath)) return;
536
+ if (!existsSync5(statusPath)) return;
498
537
  const signal = readSignal();
499
538
  if (signal && (!signal.sessionId || signal.sessionId === sessionId)) {
500
539
  unwatchFile(statusPath);
@@ -571,13 +610,16 @@ async function run(id, spawnOptions) {
571
610
  if (!prepared) return false;
572
611
  const { item, plan: plan2, startPhase } = prepared;
573
612
  setStatus(id, "in-progress");
613
+ acquireLock(item.id);
574
614
  logProgress(id, item.name, startPhase, plan2.length);
575
- if (!await runPhases(item, startPhase, plan2, spawnOptions)) return false;
576
- if (!await runReview(item, plan2, spawnOptions)) return false;
577
- ensureDone(id);
578
- console.log(chalk8.green(`
579
- All phases complete for #${id}: ${item.name}`));
580
- return true;
615
+ try {
616
+ if (!await runPhases(item, startPhase, plan2, spawnOptions)) return false;
617
+ if (!await runReview(item, plan2, spawnOptions)) return false;
618
+ ensureDone(id);
619
+ return true;
620
+ } finally {
621
+ releaseLock(item.id);
622
+ }
581
623
  }
582
624
  function logProgress(id, name, startPhase, total) {
583
625
  console.log(chalk8.bold(`Running plan for #${id}: ${name}`));
@@ -616,6 +658,11 @@ async function runReview(item, plan2, spawnOptions) {
616
658
  }
617
659
 
618
660
  // src/commands/backlog/next.ts
661
+ function findResumable(items) {
662
+ return items.find(
663
+ (i) => i.status === "in-progress" && i.plan && !isLockedByOther(i.id)
664
+ );
665
+ }
619
666
  async function selectItem(todo) {
620
667
  const choices = todo.map((i) => `${typeLabel(i.type)} #${i.id}: ${i.name}`);
621
668
  const { selected } = await exitOnCancel(
@@ -631,7 +678,7 @@ async function selectItem(todo) {
631
678
  async function next(options2) {
632
679
  while (true) {
633
680
  const items = loadBacklog();
634
- const inProgress = items.find((i) => i.status === "in-progress" && i.plan);
681
+ const inProgress = findResumable(items);
635
682
  if (inProgress) {
636
683
  console.log(
637
684
  chalk9.bold(
@@ -802,11 +849,11 @@ async function start(id) {
802
849
 
803
850
  // src/shared/web.ts
804
851
  import { exec } from "child_process";
805
- import { readFileSync as readFileSync3 } from "fs";
852
+ import { readFileSync as readFileSync4 } from "fs";
806
853
  import {
807
854
  createServer
808
855
  } from "http";
809
- import { dirname, join as join3 } from "path";
856
+ import { dirname, join as join4 } from "path";
810
857
  import { fileURLToPath } from "url";
811
858
  import chalk15 from "chalk";
812
859
  function respondJson(res, status2, data) {
@@ -818,7 +865,7 @@ function createBundleHandler(importMetaUrl, bundlePath) {
818
865
  let cache;
819
866
  return (_req, res) => {
820
867
  if (!cache) {
821
- cache = readFileSync3(join3(dir, bundlePath), "utf-8");
868
+ cache = readFileSync4(join4(dir, bundlePath), "utf-8");
822
869
  }
823
870
  res.writeHead(200, { "Content-Type": "application/javascript" });
824
871
  res.end(cache);
@@ -1020,19 +1067,19 @@ async function launchMode(slashCommand) {
1020
1067
  import { execSync } from "child_process";
1021
1068
 
1022
1069
  // src/shared/loadConfig.ts
1023
- import { existsSync as existsSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
1070
+ import { existsSync as existsSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
1024
1071
  import { homedir } from "os";
1025
- import { basename, dirname as dirname2, join as join4 } from "path";
1072
+ import { basename, dirname as dirname2, join as join5 } from "path";
1026
1073
  import chalk17 from "chalk";
1027
1074
  import { stringify as stringifyYaml2 } from "yaml";
1028
1075
 
1029
1076
  // src/shared/loadRawYaml.ts
1030
- import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
1077
+ import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
1031
1078
  import { parse as parseYaml2 } from "yaml";
1032
1079
  function loadRawYaml(path50) {
1033
- if (!existsSync5(path50)) return {};
1080
+ if (!existsSync6(path50)) return {};
1034
1081
  try {
1035
- const content = readFileSync4(path50, "utf-8");
1082
+ const content = readFileSync5(path50, "utf-8");
1036
1083
  return parseYaml2(content) || {};
1037
1084
  } catch {
1038
1085
  return {};
@@ -1153,10 +1200,10 @@ var assistConfigSchema = z2.strictObject({
1153
1200
  function findConfigUp(startDir) {
1154
1201
  let current = startDir;
1155
1202
  while (current !== dirname2(current)) {
1156
- const claudePath = join4(current, ".claude", "assist.yml");
1157
- if (existsSync6(claudePath)) return claudePath;
1158
- const rootPath = join4(current, "assist.yml");
1159
- if (existsSync6(rootPath)) return rootPath;
1203
+ const claudePath = join5(current, ".claude", "assist.yml");
1204
+ if (existsSync7(claudePath)) return claudePath;
1205
+ const rootPath = join5(current, "assist.yml");
1206
+ if (existsSync7(rootPath)) return rootPath;
1160
1207
  current = dirname2(current);
1161
1208
  }
1162
1209
  return null;
@@ -1164,10 +1211,10 @@ function findConfigUp(startDir) {
1164
1211
  function getConfigPath() {
1165
1212
  const found = findConfigUp(process.cwd());
1166
1213
  if (found) return found;
1167
- return join4(process.cwd(), "assist.yml");
1214
+ return join5(process.cwd(), "assist.yml");
1168
1215
  }
1169
1216
  function getGlobalConfigPath() {
1170
- return join4(homedir(), ".assist.yml");
1217
+ return join5(homedir(), ".assist.yml");
1171
1218
  }
1172
1219
  function loadConfig() {
1173
1220
  const globalRaw = loadRawYaml(getGlobalConfigPath());
@@ -1182,21 +1229,21 @@ function loadGlobalConfigRaw() {
1182
1229
  return loadRawYaml(getGlobalConfigPath());
1183
1230
  }
1184
1231
  function saveGlobalConfig(config) {
1185
- writeFileSync3(getGlobalConfigPath(), stringifyYaml2(config, { lineWidth: 0 }));
1232
+ writeFileSync4(getGlobalConfigPath(), stringifyYaml2(config, { lineWidth: 0 }));
1186
1233
  }
1187
1234
  function saveConfig(config) {
1188
1235
  const configPath = getConfigPath();
1189
- writeFileSync3(configPath, stringifyYaml2(config, { lineWidth: 0 }));
1236
+ writeFileSync4(configPath, stringifyYaml2(config, { lineWidth: 0 }));
1190
1237
  }
1191
1238
  function getRepoName() {
1192
1239
  const config = loadConfig();
1193
1240
  if (config.devlog?.name) {
1194
1241
  return config.devlog.name;
1195
1242
  }
1196
- const packageJsonPath = join4(process.cwd(), "package.json");
1197
- if (existsSync6(packageJsonPath)) {
1243
+ const packageJsonPath = join5(process.cwd(), "package.json");
1244
+ if (existsSync7(packageJsonPath)) {
1198
1245
  try {
1199
- const content = readFileSync5(packageJsonPath, "utf-8");
1246
+ const content = readFileSync6(packageJsonPath, "utf-8");
1200
1247
  const pkg = JSON.parse(content);
1201
1248
  if (pkg.name) {
1202
1249
  return pkg.name;
@@ -1511,10 +1558,10 @@ function findPackageJsonWithVerifyScripts(startDir) {
1511
1558
 
1512
1559
  // src/commands/verify/installPackage.ts
1513
1560
  import { execSync as execSync3 } from "child_process";
1514
- import { writeFileSync as writeFileSync4 } from "fs";
1561
+ import { writeFileSync as writeFileSync5 } from "fs";
1515
1562
  import chalk21 from "chalk";
1516
1563
  function writePackageJson(filePath, pkg) {
1517
- writeFileSync4(filePath, `${JSON.stringify(pkg, null, 2)}
1564
+ writeFileSync5(filePath, `${JSON.stringify(pkg, null, 2)}
1518
1565
  `);
1519
1566
  }
1520
1567
  function addScript(pkg, name, command) {
@@ -1619,23 +1666,23 @@ import * as path3 from "path";
1619
1666
  import chalk25 from "chalk";
1620
1667
 
1621
1668
  // src/commands/verify/addToKnipIgnoreBinaries.ts
1622
- import { existsSync as existsSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "fs";
1623
- import { join as join6 } from "path";
1669
+ import { existsSync as existsSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "fs";
1670
+ import { join as join7 } from "path";
1624
1671
  import chalk24 from "chalk";
1625
1672
  function loadKnipConfig(knipJsonPath) {
1626
- if (existsSync8(knipJsonPath)) {
1627
- return JSON.parse(readFileSync7(knipJsonPath, "utf-8"));
1673
+ if (existsSync9(knipJsonPath)) {
1674
+ return JSON.parse(readFileSync8(knipJsonPath, "utf-8"));
1628
1675
  }
1629
1676
  return { $schema: "https://unpkg.com/knip@5/schema.json" };
1630
1677
  }
1631
1678
  function addToKnipIgnoreBinaries(cwd, binary) {
1632
- const knipJsonPath = join6(cwd, "knip.json");
1679
+ const knipJsonPath = join7(cwd, "knip.json");
1633
1680
  try {
1634
1681
  const knipConfig = loadKnipConfig(knipJsonPath);
1635
1682
  const ignoreBinaries = knipConfig.ignoreBinaries ?? [];
1636
1683
  if (!ignoreBinaries.includes(binary)) {
1637
1684
  knipConfig.ignoreBinaries = [...ignoreBinaries, binary];
1638
- writeFileSync5(
1685
+ writeFileSync6(
1639
1686
  knipJsonPath,
1640
1687
  `${JSON.stringify(knipConfig, null, " ")}
1641
1688
  `
@@ -1677,8 +1724,8 @@ import chalk29 from "chalk";
1677
1724
 
1678
1725
  // src/commands/lint/init.ts
1679
1726
  import { execSync as execSync5 } from "child_process";
1680
- import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "fs";
1681
- import { dirname as dirname7, join as join7 } from "path";
1727
+ import { existsSync as existsSync12, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "fs";
1728
+ import { dirname as dirname7, join as join8 } from "path";
1682
1729
  import { fileURLToPath as fileURLToPath2 } from "url";
1683
1730
  import chalk28 from "chalk";
1684
1731
 
@@ -1703,10 +1750,10 @@ async function promptConfirm(message, initial = true) {
1703
1750
 
1704
1751
  // src/shared/removeEslint/index.ts
1705
1752
  import { execSync as execSync4 } from "child_process";
1706
- import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "fs";
1753
+ import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "fs";
1707
1754
 
1708
1755
  // src/shared/removeEslint/removeEslintConfigFiles.ts
1709
- import { existsSync as existsSync9, unlinkSync as unlinkSync2 } from "fs";
1756
+ import { existsSync as existsSync10, unlinkSync as unlinkSync3 } from "fs";
1710
1757
  var ESLINT_CONFIG_FILES = [
1711
1758
  "eslint.config.js",
1712
1759
  "eslint.config.mjs",
@@ -1722,8 +1769,8 @@ var ESLINT_CONFIG_FILES = [
1722
1769
  function removeEslintConfigFiles() {
1723
1770
  let removed = false;
1724
1771
  for (const configFile of ESLINT_CONFIG_FILES) {
1725
- if (existsSync9(configFile)) {
1726
- unlinkSync2(configFile);
1772
+ if (existsSync10(configFile)) {
1773
+ unlinkSync3(configFile);
1727
1774
  console.log(`Removed ${configFile}`);
1728
1775
  removed = true;
1729
1776
  }
@@ -1744,16 +1791,16 @@ function removeEslint(options2 = {}) {
1744
1791
  }
1745
1792
  function removeEslintFromPackageJson(options2) {
1746
1793
  const packageJsonPath = "package.json";
1747
- if (!existsSync10(packageJsonPath)) {
1794
+ if (!existsSync11(packageJsonPath)) {
1748
1795
  return false;
1749
1796
  }
1750
- const packageJson = JSON.parse(readFileSync8(packageJsonPath, "utf-8"));
1797
+ const packageJson = JSON.parse(readFileSync9(packageJsonPath, "utf-8"));
1751
1798
  let modified = false;
1752
1799
  modified = removeEslintDeps(packageJson.dependencies) || modified;
1753
1800
  modified = removeEslintDeps(packageJson.devDependencies) || modified;
1754
1801
  modified = removeEslintScripts(packageJson.scripts, options2) || modified;
1755
1802
  if (modified) {
1756
- writeFileSync6(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
1803
+ writeFileSync7(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
1757
1804
  `);
1758
1805
  console.log("Removed eslint references from package.json");
1759
1806
  }
@@ -1817,17 +1864,17 @@ var __dirname2 = dirname7(fileURLToPath2(import.meta.url));
1817
1864
  async function init() {
1818
1865
  removeEslint();
1819
1866
  const biomeConfigPath = "biome.json";
1820
- if (!existsSync11(biomeConfigPath)) {
1867
+ if (!existsSync12(biomeConfigPath)) {
1821
1868
  console.log("Initializing Biome...");
1822
1869
  execSync5("npx @biomejs/biome init", { stdio: "inherit" });
1823
1870
  }
1824
- if (!existsSync11(biomeConfigPath)) {
1871
+ if (!existsSync12(biomeConfigPath)) {
1825
1872
  console.log("No biome.json found, skipping linter config");
1826
1873
  return;
1827
1874
  }
1828
- const linterConfigPath = join7(__dirname2, "commands/lint/biome.linter.json");
1829
- const linterConfig = JSON.parse(readFileSync9(linterConfigPath, "utf-8"));
1830
- const biomeConfig = JSON.parse(readFileSync9(biomeConfigPath, "utf-8"));
1875
+ const linterConfigPath = join8(__dirname2, "commands/lint/biome.linter.json");
1876
+ const linterConfig = JSON.parse(readFileSync10(linterConfigPath, "utf-8"));
1877
+ const biomeConfig = JSON.parse(readFileSync10(biomeConfigPath, "utf-8"));
1831
1878
  const oldContent = `${JSON.stringify(biomeConfig, null, 2)}
1832
1879
  `;
1833
1880
  biomeConfig.linter = linterConfig.linter;
@@ -1848,7 +1895,7 @@ async function init() {
1848
1895
  console.log("Skipped biome.json update");
1849
1896
  return;
1850
1897
  }
1851
- writeFileSync7(biomeConfigPath, newContent);
1898
+ writeFileSync8(biomeConfigPath, newContent);
1852
1899
  console.log("Updated biome.json with linter config");
1853
1900
  }
1854
1901
 
@@ -2862,11 +2909,11 @@ async function run2(options2 = {}) {
2862
2909
 
2863
2910
  // src/commands/new/registerNew/initGit.ts
2864
2911
  import { execSync as execSync9 } from "child_process";
2865
- import { writeFileSync as writeFileSync9 } from "fs";
2912
+ import { writeFileSync as writeFileSync10 } from "fs";
2866
2913
  function initGit() {
2867
2914
  console.log("Initializing git repository...");
2868
2915
  execSync9("git init", { stdio: "inherit" });
2869
- writeFileSync9(".gitignore", "dist\nnode_modules\n");
2916
+ writeFileSync10(".gitignore", "dist\nnode_modules\n");
2870
2917
  }
2871
2918
 
2872
2919
  // src/commands/new/registerNew/newCli/initPackageJson.ts
@@ -2885,10 +2932,10 @@ function initPackageJson(name) {
2885
2932
  }
2886
2933
 
2887
2934
  // src/commands/new/registerNew/newCli/writeCliTemplate.ts
2888
- import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync10 } from "fs";
2935
+ import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync11 } from "fs";
2889
2936
  function writeCliTemplate(name) {
2890
2937
  console.log("Writing tsconfig.json...");
2891
- writeFileSync10(
2938
+ writeFileSync11(
2892
2939
  "tsconfig.json",
2893
2940
  JSON.stringify(
2894
2941
  {
@@ -2912,7 +2959,7 @@ function writeCliTemplate(name) {
2912
2959
  )
2913
2960
  );
2914
2961
  console.log("Writing tsup.config.ts...");
2915
- writeFileSync10(
2962
+ writeFileSync11(
2916
2963
  "tsup.config.ts",
2917
2964
  `import { defineConfig } from "tsup";
2918
2965
  export default defineConfig({
@@ -2927,7 +2974,7 @@ export default defineConfig({
2927
2974
  );
2928
2975
  console.log("Writing src/index.ts...");
2929
2976
  mkdirSync2("src", { recursive: true });
2930
- writeFileSync10(
2977
+ writeFileSync11(
2931
2978
  "src/index.ts",
2932
2979
  `#!/usr/bin/env node
2933
2980
  import { Command } from "commander";
@@ -2955,7 +3002,7 @@ async function newCli() {
2955
3002
 
2956
3003
  // src/commands/new/registerNew/newProject.ts
2957
3004
  import { execSync as execSync13 } from "child_process";
2958
- import { existsSync as existsSync15, readFileSync as readFileSync12, writeFileSync as writeFileSync12 } from "fs";
3005
+ import { existsSync as existsSync16, readFileSync as readFileSync13, writeFileSync as writeFileSync13 } from "fs";
2959
3006
 
2960
3007
  // src/commands/deploy/init/index.ts
2961
3008
  import { execSync as execSync12 } from "child_process";
@@ -2963,33 +3010,33 @@ import chalk40 from "chalk";
2963
3010
  import enquirer5 from "enquirer";
2964
3011
 
2965
3012
  // src/commands/deploy/init/updateWorkflow.ts
2966
- import { existsSync as existsSync14, mkdirSync as mkdirSync3, readFileSync as readFileSync11, writeFileSync as writeFileSync11 } from "fs";
2967
- import { dirname as dirname13, join as join10 } from "path";
3013
+ import { existsSync as existsSync15, mkdirSync as mkdirSync3, readFileSync as readFileSync12, writeFileSync as writeFileSync12 } from "fs";
3014
+ import { dirname as dirname13, join as join11 } from "path";
2968
3015
  import { fileURLToPath as fileURLToPath3 } from "url";
2969
3016
  import chalk39 from "chalk";
2970
3017
  var WORKFLOW_PATH = ".github/workflows/build.yml";
2971
3018
  var __dirname3 = dirname13(fileURLToPath3(import.meta.url));
2972
3019
  function getExistingSiteId() {
2973
- if (!existsSync14(WORKFLOW_PATH)) {
3020
+ if (!existsSync15(WORKFLOW_PATH)) {
2974
3021
  return null;
2975
3022
  }
2976
- const content = readFileSync11(WORKFLOW_PATH, "utf-8");
3023
+ const content = readFileSync12(WORKFLOW_PATH, "utf-8");
2977
3024
  const match = content.match(/-s\s+([a-f0-9-]{36})/);
2978
3025
  return match ? match[1] : null;
2979
3026
  }
2980
3027
  function getTemplateContent(siteId) {
2981
- const templatePath = join10(__dirname3, "commands/deploy/build.yml");
2982
- const template = readFileSync11(templatePath, "utf-8");
3028
+ const templatePath = join11(__dirname3, "commands/deploy/build.yml");
3029
+ const template = readFileSync12(templatePath, "utf-8");
2983
3030
  return template.replace("{{NETLIFY_SITE_ID}}", siteId);
2984
3031
  }
2985
3032
  async function updateWorkflow(siteId) {
2986
3033
  const newContent = getTemplateContent(siteId);
2987
3034
  const workflowDir = ".github/workflows";
2988
- if (!existsSync14(workflowDir)) {
3035
+ if (!existsSync15(workflowDir)) {
2989
3036
  mkdirSync3(workflowDir, { recursive: true });
2990
3037
  }
2991
- if (existsSync14(WORKFLOW_PATH)) {
2992
- const oldContent = readFileSync11(WORKFLOW_PATH, "utf-8");
3038
+ if (existsSync15(WORKFLOW_PATH)) {
3039
+ const oldContent = readFileSync12(WORKFLOW_PATH, "utf-8");
2993
3040
  if (oldContent === newContent) {
2994
3041
  console.log(chalk39.green("build.yml is already up to date"));
2995
3042
  return;
@@ -3003,7 +3050,7 @@ async function updateWorkflow(siteId) {
3003
3050
  return;
3004
3051
  }
3005
3052
  }
3006
- writeFileSync11(WORKFLOW_PATH, newContent);
3053
+ writeFileSync12(WORKFLOW_PATH, newContent);
3007
3054
  console.log(chalk39.green(`
3008
3055
  Created ${WORKFLOW_PATH}`));
3009
3056
  }
@@ -3083,11 +3130,11 @@ async function newProject() {
3083
3130
  }
3084
3131
  function addViteBaseConfig() {
3085
3132
  const viteConfigPath = "vite.config.ts";
3086
- if (!existsSync15(viteConfigPath)) {
3133
+ if (!existsSync16(viteConfigPath)) {
3087
3134
  console.log("No vite.config.ts found, skipping base config");
3088
3135
  return;
3089
3136
  }
3090
- const content = readFileSync12(viteConfigPath, "utf-8");
3137
+ const content = readFileSync13(viteConfigPath, "utf-8");
3091
3138
  if (content.includes("base:")) {
3092
3139
  console.log("vite.config.ts already has base config");
3093
3140
  return;
@@ -3097,7 +3144,7 @@ function addViteBaseConfig() {
3097
3144
  'defineConfig({\n base: "./",'
3098
3145
  );
3099
3146
  if (updated !== content) {
3100
- writeFileSync12(viteConfigPath, updated);
3147
+ writeFileSync13(viteConfigPath, updated);
3101
3148
  console.log('Added base: "./" to vite.config.ts');
3102
3149
  }
3103
3150
  }
@@ -3265,7 +3312,7 @@ function registerCommentCommands(cmd) {
3265
3312
  }
3266
3313
 
3267
3314
  // src/commands/backlog/add/index.ts
3268
- import { existsSync as existsSync16 } from "fs";
3315
+ import { existsSync as existsSync17 } from "fs";
3269
3316
  import chalk44 from "chalk";
3270
3317
 
3271
3318
  // src/commands/backlog/commitBacklog.ts
@@ -3284,9 +3331,9 @@ function commitBacklog(id, name) {
3284
3331
 
3285
3332
  // src/commands/backlog/add/shared.ts
3286
3333
  import { spawnSync } from "child_process";
3287
- import { mkdtempSync, readFileSync as readFileSync13, unlinkSync as unlinkSync3, writeFileSync as writeFileSync13 } from "fs";
3334
+ import { mkdtempSync, readFileSync as readFileSync14, unlinkSync as unlinkSync4, writeFileSync as writeFileSync14 } from "fs";
3288
3335
  import { tmpdir } from "os";
3289
- import { join as join11 } from "path";
3336
+ import { join as join12 } from "path";
3290
3337
  import enquirer6 from "enquirer";
3291
3338
  async function promptType() {
3292
3339
  const { type } = await enquirer6.prompt({
@@ -3326,16 +3373,16 @@ async function promptDescription() {
3326
3373
  }
3327
3374
  function openEditor() {
3328
3375
  const editor = process.env.EDITOR || process.env.VISUAL || "vi";
3329
- const dir = mkdtempSync(join11(tmpdir(), "assist-"));
3330
- const filePath = join11(dir, "description.md");
3331
- writeFileSync13(filePath, "");
3376
+ const dir = mkdtempSync(join12(tmpdir(), "assist-"));
3377
+ const filePath = join12(dir, "description.md");
3378
+ writeFileSync14(filePath, "");
3332
3379
  const result = spawnSync(editor, [filePath], { stdio: "inherit" });
3333
3380
  if (result.status !== 0) {
3334
- unlinkSync3(filePath);
3381
+ unlinkSync4(filePath);
3335
3382
  return void 0;
3336
3383
  }
3337
- const content = readFileSync13(filePath, "utf-8").trim();
3338
- unlinkSync3(filePath);
3384
+ const content = readFileSync14(filePath, "utf-8").trim();
3385
+ unlinkSync4(filePath);
3339
3386
  return content || void 0;
3340
3387
  }
3341
3388
  async function promptAcceptanceCriteria() {
@@ -3392,7 +3439,7 @@ async function addInteractive() {
3392
3439
  console.log(chalk44.green(`Added item #${id}: ${name}`));
3393
3440
  }
3394
3441
  async function add(options2) {
3395
- if (!existsSync16(getBacklogPath())) {
3442
+ if (!existsSync17(getBacklogPath())) {
3396
3443
  console.log(
3397
3444
  chalk44.yellow(
3398
3445
  "No backlog found. Run 'assist backlog init' to create one."
@@ -3408,11 +3455,11 @@ async function add(options2) {
3408
3455
  }
3409
3456
 
3410
3457
  // src/commands/backlog/init/index.ts
3411
- import { existsSync as existsSync17 } from "fs";
3458
+ import { existsSync as existsSync18 } from "fs";
3412
3459
  import chalk45 from "chalk";
3413
3460
  async function init6() {
3414
3461
  const backlogPath = getBacklogPath();
3415
- if (existsSync17(backlogPath)) {
3462
+ if (existsSync18(backlogPath)) {
3416
3463
  console.log(chalk45.yellow("assist.backlog.yml already exists."));
3417
3464
  return;
3418
3465
  }
@@ -3421,7 +3468,7 @@ async function init6() {
3421
3468
  }
3422
3469
 
3423
3470
  // src/commands/backlog/list/index.ts
3424
- import { existsSync as existsSync18 } from "fs";
3471
+ import { existsSync as existsSync19 } from "fs";
3425
3472
  import chalk46 from "chalk";
3426
3473
  function filterItems(items, options2) {
3427
3474
  if (options2.status) return items.filter((i) => i.status === options2.status);
@@ -3429,7 +3476,7 @@ function filterItems(items, options2) {
3429
3476
  return items;
3430
3477
  }
3431
3478
  async function list2(options2) {
3432
- if (!existsSync18(getBacklogPath())) {
3479
+ if (!existsSync19(getBacklogPath())) {
3433
3480
  console.log(
3434
3481
  chalk46.yellow(
3435
3482
  "No backlog found. Run 'assist backlog init' to create one."
@@ -3579,7 +3626,7 @@ function extractGraphqlQuery(args) {
3579
3626
  }
3580
3627
 
3581
3628
  // src/shared/loadCliReads.ts
3582
- import { existsSync as existsSync19, readFileSync as readFileSync14, writeFileSync as writeFileSync14 } from "fs";
3629
+ import { existsSync as existsSync20, readFileSync as readFileSync15, writeFileSync as writeFileSync15 } from "fs";
3583
3630
  import { dirname as dirname14, resolve as resolve2 } from "path";
3584
3631
  import { fileURLToPath as fileURLToPath4 } from "url";
3585
3632
  var __filename2 = fileURLToPath4(import.meta.url);
@@ -3591,18 +3638,18 @@ var cachedLines;
3591
3638
  function getCliReadsLines() {
3592
3639
  if (cachedLines) return cachedLines;
3593
3640
  const path50 = getCliReadsPath();
3594
- if (!existsSync19(path50)) {
3641
+ if (!existsSync20(path50)) {
3595
3642
  cachedLines = [];
3596
3643
  return cachedLines;
3597
3644
  }
3598
- cachedLines = readFileSync14(path50, "utf-8").split("\n").filter((line) => line.trim() !== "");
3645
+ cachedLines = readFileSync15(path50, "utf-8").split("\n").filter((line) => line.trim() !== "");
3599
3646
  return cachedLines;
3600
3647
  }
3601
3648
  function loadCliReads() {
3602
3649
  return getCliReadsLines();
3603
3650
  }
3604
3651
  function saveCliReads(commands) {
3605
- writeFileSync14(getCliReadsPath(), `${commands.join("\n")}
3652
+ writeFileSync15(getCliReadsPath(), `${commands.join("\n")}
3606
3653
  `);
3607
3654
  cachedLines = void 0;
3608
3655
  }
@@ -3619,61 +3666,82 @@ function findCliRead(command) {
3619
3666
  return candidates.sort((a, b) => b.length - a.length).find((rc) => command === rc || command.startsWith(`${rc} `));
3620
3667
  }
3621
3668
 
3622
- // src/shared/matchesBashAllow.ts
3623
- import { existsSync as existsSync20, readFileSync as readFileSync15 } from "fs";
3669
+ // src/shared/matchesAllow.ts
3670
+ import { existsSync as existsSync21, readFileSync as readFileSync16 } from "fs";
3624
3671
  import { homedir as homedir3 } from "os";
3625
- import { join as join12 } from "path";
3626
- var cached;
3627
- function loadBashAllowPrefixes() {
3628
- if (cached) return cached;
3629
- cached = parsePrefixes(collectAllowEntries());
3630
- return cached;
3631
- }
3632
- function matchesBashAllow(command) {
3633
- const prefixes = loadBashAllowPrefixes();
3672
+ import { join as join13 } from "path";
3673
+ var allowCache;
3674
+ var denyCache;
3675
+ var TOOL_RE = /^(Bash|PowerShell)\((.+?)(?::.*)\)$/;
3676
+ function loadPrefixes(key) {
3677
+ const entries = collectEntries(key);
3678
+ return parsePrefixes(entries);
3679
+ }
3680
+ var SHELL_TOOLS = ["Bash", "PowerShell"];
3681
+ function shellPrefixes(map, toolName) {
3682
+ if (SHELL_TOOLS.includes(toolName)) {
3683
+ return SHELL_TOOLS.flatMap((t) => map.get(t) ?? []);
3684
+ }
3685
+ return map.get(toolName) ?? [];
3686
+ }
3687
+ function matchesAllow(toolName, command) {
3688
+ if (!allowCache) allowCache = loadPrefixes("allow");
3689
+ const prefixes = shellPrefixes(allowCache, toolName);
3690
+ return prefixes.find(
3691
+ (pfx) => command === pfx || command.startsWith(`${pfx} `)
3692
+ );
3693
+ }
3694
+ function matchesDeny(toolName, command) {
3695
+ if (!denyCache) denyCache = loadPrefixes("deny");
3696
+ const prefixes = shellPrefixes(denyCache, toolName);
3634
3697
  return prefixes.find(
3635
3698
  (pfx) => command === pfx || command.startsWith(`${pfx} `)
3636
3699
  );
3637
3700
  }
3638
- function collectAllowEntries() {
3701
+ function collectEntries(key) {
3639
3702
  const paths = [
3640
- join12(homedir3(), ".claude", "settings.json"),
3641
- join12(process.cwd(), ".claude", "settings.json"),
3642
- join12(process.cwd(), ".claude", "settings.local.json")
3703
+ join13(homedir3(), ".claude", "settings.json"),
3704
+ join13(process.cwd(), ".claude", "settings.json"),
3705
+ join13(process.cwd(), ".claude", "settings.local.json")
3643
3706
  ];
3644
3707
  const entries = [];
3645
3708
  for (const p of paths) {
3646
- entries.push(...readAllowArray(p));
3709
+ entries.push(...readPermissionArray(p, key));
3647
3710
  }
3648
3711
  return entries;
3649
3712
  }
3650
- function readAllowArray(filePath) {
3651
- if (!existsSync20(filePath)) return [];
3713
+ function readPermissionArray(filePath, key) {
3714
+ if (!existsSync21(filePath)) return [];
3652
3715
  try {
3653
- const data = JSON.parse(readFileSync15(filePath, "utf-8"));
3654
- const allow = data?.permissions?.allow;
3655
- return Array.isArray(allow) ? allow.filter((e) => typeof e === "string") : [];
3716
+ const data = JSON.parse(readFileSync16(filePath, "utf-8"));
3717
+ const arr = data?.permissions?.[key];
3718
+ return Array.isArray(arr) ? arr.filter((e) => typeof e === "string") : [];
3656
3719
  } catch {
3657
3720
  return [];
3658
3721
  }
3659
3722
  }
3660
3723
  function parsePrefixes(entries) {
3661
- const re = /^Bash\((.+?)(?::.*)\)$/;
3662
- const prefixes = [];
3724
+ const map = /* @__PURE__ */ new Map();
3663
3725
  for (const entry of entries) {
3664
- const m = entry.match(re);
3665
- if (m) prefixes.push(m[1]);
3726
+ const m = entry.match(TOOL_RE);
3727
+ if (m) {
3728
+ const tool = m[1];
3729
+ const prefix2 = m[2];
3730
+ const list4 = map.get(tool) ?? [];
3731
+ list4.push(prefix2);
3732
+ map.set(tool, list4);
3733
+ }
3666
3734
  }
3667
- return prefixes;
3735
+ return map;
3668
3736
  }
3669
3737
 
3670
3738
  // src/shared/isApprovedRead.ts
3671
- function isApprovedRead(command) {
3739
+ function isApprovedRead(command, toolName = "Bash") {
3672
3740
  if (isCdToCwd(command)) return "cd to current directory";
3673
3741
  const matched = findCliRead(command);
3674
3742
  if (matched) return `Read-only CLI command: ${matched}`;
3675
3743
  if (isGhApiRead(command)) return "Read-only gh api command";
3676
- const allowMatch = matchesBashAllow(command);
3744
+ const allowMatch = matchesAllow(toolName, command);
3677
3745
  if (allowMatch) return `Allowed by settings: ${allowMatch}`;
3678
3746
  return void 0;
3679
3747
  }
@@ -3745,6 +3813,28 @@ function stripEnvPrefix(parts) {
3745
3813
  }
3746
3814
 
3747
3815
  // src/commands/cliHook/index.ts
3816
+ var SUPPORTED_TOOLS = /* @__PURE__ */ new Set(["Bash", "PowerShell"]);
3817
+ function resolvePermission(toolName, parts) {
3818
+ for (const part of parts) {
3819
+ const denied = matchesDeny(toolName, part);
3820
+ if (denied) {
3821
+ return {
3822
+ permissionDecision: "deny",
3823
+ permissionDecisionReason: `Denied by settings: ${denied}`
3824
+ };
3825
+ }
3826
+ }
3827
+ const reasons = [];
3828
+ for (const part of parts) {
3829
+ const reason = isApprovedRead(part, toolName);
3830
+ if (!reason) return void 0;
3831
+ reasons.push(reason);
3832
+ }
3833
+ return {
3834
+ permissionDecision: "allow",
3835
+ permissionDecisionReason: reasons.join("; ")
3836
+ };
3837
+ }
3748
3838
  async function cliHook() {
3749
3839
  const inputData = await readStdin2();
3750
3840
  let data;
@@ -3753,24 +3843,18 @@ async function cliHook() {
3753
3843
  } catch {
3754
3844
  return;
3755
3845
  }
3756
- if (data.tool_name !== "Bash" || !data.tool_input?.command) {
3846
+ if (!SUPPORTED_TOOLS.has(data.tool_name) || !data.tool_input?.command) {
3757
3847
  return;
3758
3848
  }
3759
- const command = data.tool_input.command.trim();
3760
- const parts = splitCompound(command);
3849
+ const parts = splitCompound(data.tool_input.command.trim());
3761
3850
  if (!parts) return;
3762
- const reasons = [];
3763
- for (const part of parts) {
3764
- const reason = isApprovedRead(part);
3765
- if (!reason) return;
3766
- reasons.push(reason);
3767
- }
3851
+ const decision = resolvePermission(data.tool_name, parts);
3852
+ if (!decision) return;
3768
3853
  console.log(
3769
3854
  JSON.stringify({
3770
3855
  hookSpecificOutput: {
3771
3856
  hookEventName: "PreToolUse",
3772
- permissionDecision: "allow",
3773
- permissionDecisionReason: reasons.join("; ")
3857
+ ...decision
3774
3858
  }
3775
3859
  })
3776
3860
  );
@@ -3800,9 +3884,9 @@ ${reasons.join("\n")}`);
3800
3884
  }
3801
3885
 
3802
3886
  // src/commands/permitCliReads/index.ts
3803
- import { existsSync as existsSync21, mkdirSync as mkdirSync4, readFileSync as readFileSync16, writeFileSync as writeFileSync15 } from "fs";
3887
+ import { existsSync as existsSync22, mkdirSync as mkdirSync4, readFileSync as readFileSync17, writeFileSync as writeFileSync16 } from "fs";
3804
3888
  import { homedir as homedir4 } from "os";
3805
- import { join as join13 } from "path";
3889
+ import { join as join14 } from "path";
3806
3890
 
3807
3891
  // src/shared/getInstallDir.ts
3808
3892
  import { execSync as execSync15 } from "child_process";
@@ -4076,10 +4160,10 @@ function formatHuman(cli, commands) {
4076
4160
  }
4077
4161
 
4078
4162
  // src/commands/permitCliReads/parseCached.ts
4079
- function parseCached(cli, cached2) {
4163
+ function parseCached(cli, cached) {
4080
4164
  const prefix2 = `${cli} `;
4081
4165
  const commands = [];
4082
- for (const line of cached2.split("\n")) {
4166
+ for (const line of cached.split("\n")) {
4083
4167
  const trimmed = line.replace(/^ [RW?] {2}/, "").trim();
4084
4168
  if (!trimmed.startsWith(prefix2)) continue;
4085
4169
  const rest = trimmed.slice(prefix2.length);
@@ -4104,17 +4188,17 @@ function updateSettings(cli, commands) {
4104
4188
  // src/commands/permitCliReads/index.ts
4105
4189
  function logPath(cli) {
4106
4190
  const safeName = cli.replace(/\s+/g, "-");
4107
- return join13(homedir4(), ".assist", `cli-discover-${safeName}.log`);
4191
+ return join14(homedir4(), ".assist", `cli-discover-${safeName}.log`);
4108
4192
  }
4109
4193
  function readCache(cli) {
4110
4194
  const path50 = logPath(cli);
4111
- if (!existsSync21(path50)) return void 0;
4112
- return readFileSync16(path50, "utf-8");
4195
+ if (!existsSync22(path50)) return void 0;
4196
+ return readFileSync17(path50, "utf-8");
4113
4197
  }
4114
4198
  function writeCache(cli, output) {
4115
- const dir = join13(homedir4(), ".assist");
4199
+ const dir = join14(homedir4(), ".assist");
4116
4200
  mkdirSync4(dir, { recursive: true });
4117
- writeFileSync15(logPath(cli), output);
4201
+ writeFileSync16(logPath(cli), output);
4118
4202
  }
4119
4203
  async function permitCliReads(cli, options2 = { noCache: false }) {
4120
4204
  if (!cli) {
@@ -4132,10 +4216,10 @@ async function permitCliReads(cli, options2 = { noCache: false }) {
4132
4216
  const binary = parts[0];
4133
4217
  const prefixPath = parts.slice(1);
4134
4218
  if (!options2.noCache) {
4135
- const cached2 = readCache(cli);
4136
- if (cached2) {
4137
- console.log(colorize(cached2));
4138
- updateSettings(binary, parseCached(binary, cached2));
4219
+ const cached = readCache(cli);
4220
+ if (cached) {
4221
+ console.log(colorize(cached));
4222
+ updateSettings(binary, parseCached(binary, cached));
4139
4223
  return;
4140
4224
  }
4141
4225
  }
@@ -4657,7 +4741,7 @@ function registerComplexity(program2) {
4657
4741
  }
4658
4742
 
4659
4743
  // src/commands/deploy/redirect.ts
4660
- import { existsSync as existsSync22, readFileSync as readFileSync17, writeFileSync as writeFileSync16 } from "fs";
4744
+ import { existsSync as existsSync23, readFileSync as readFileSync18, writeFileSync as writeFileSync17 } from "fs";
4661
4745
  import chalk54 from "chalk";
4662
4746
  var TRAILING_SLASH_SCRIPT = ` <script>
4663
4747
  if (!window.location.pathname.endsWith('/')) {
@@ -4666,11 +4750,11 @@ var TRAILING_SLASH_SCRIPT = ` <script>
4666
4750
  </script>`;
4667
4751
  function redirect() {
4668
4752
  const indexPath = "index.html";
4669
- if (!existsSync22(indexPath)) {
4753
+ if (!existsSync23(indexPath)) {
4670
4754
  console.log(chalk54.yellow("No index.html found"));
4671
4755
  return;
4672
4756
  }
4673
- const content = readFileSync17(indexPath, "utf-8");
4757
+ const content = readFileSync18(indexPath, "utf-8");
4674
4758
  if (content.includes("window.location.pathname.endsWith('/')")) {
4675
4759
  console.log(chalk54.dim("Trailing slash script already present"));
4676
4760
  return;
@@ -4681,7 +4765,7 @@ function redirect() {
4681
4765
  return;
4682
4766
  }
4683
4767
  const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
4684
- writeFileSync16(indexPath, newContent);
4768
+ writeFileSync17(indexPath, newContent);
4685
4769
  console.log(chalk54.green("Added trailing slash redirect to index.html"));
4686
4770
  }
4687
4771
 
@@ -4698,10 +4782,10 @@ import { basename as basename3 } from "path";
4698
4782
 
4699
4783
  // src/commands/devlog/loadBlogSkipDays.ts
4700
4784
  import { homedir as homedir5 } from "os";
4701
- import { join as join14 } from "path";
4702
- var BLOG_REPO_ROOT = join14(homedir5(), "git/blog");
4785
+ import { join as join15 } from "path";
4786
+ var BLOG_REPO_ROOT = join15(homedir5(), "git/blog");
4703
4787
  function loadBlogSkipDays(repoName) {
4704
- const config = loadRawYaml(join14(BLOG_REPO_ROOT, "assist.yml"));
4788
+ const config = loadRawYaml(join15(BLOG_REPO_ROOT, "assist.yml"));
4705
4789
  const devlog = config.devlog;
4706
4790
  const skip2 = devlog?.skip;
4707
4791
  return new Set(skip2?.[repoName] ?? []);
@@ -4712,9 +4796,9 @@ import { execSync as execSync17 } from "child_process";
4712
4796
  import chalk55 from "chalk";
4713
4797
 
4714
4798
  // src/commands/devlog/loadDevlogEntries.ts
4715
- import { readdirSync, readFileSync as readFileSync18 } from "fs";
4716
- import { join as join15 } from "path";
4717
- var DEVLOG_DIR = join15(BLOG_REPO_ROOT, "src/content/devlog");
4799
+ import { readdirSync, readFileSync as readFileSync19 } from "fs";
4800
+ import { join as join16 } from "path";
4801
+ var DEVLOG_DIR = join16(BLOG_REPO_ROOT, "src/content/devlog");
4718
4802
  function extractFrontmatter(content) {
4719
4803
  const fm = content.match(/^---\n([\s\S]*?)\n---/);
4720
4804
  return fm?.[1] ?? null;
@@ -4742,7 +4826,7 @@ function readDevlogFiles(callback) {
4742
4826
  try {
4743
4827
  const files = readdirSync(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
4744
4828
  for (const file of files) {
4745
- const content = readFileSync18(join15(DEVLOG_DIR, file), "utf-8");
4829
+ const content = readFileSync19(join16(DEVLOG_DIR, file), "utf-8");
4746
4830
  const parsed = parseFrontmatter(content, file);
4747
4831
  if (parsed) callback(parsed);
4748
4832
  }
@@ -5127,12 +5211,12 @@ function repos(options2) {
5127
5211
  }
5128
5212
 
5129
5213
  // src/commands/devlog/skip.ts
5130
- import { writeFileSync as writeFileSync17 } from "fs";
5131
- import { join as join16 } from "path";
5214
+ import { writeFileSync as writeFileSync18 } from "fs";
5215
+ import { join as join17 } from "path";
5132
5216
  import chalk60 from "chalk";
5133
5217
  import { stringify as stringifyYaml4 } from "yaml";
5134
5218
  function getBlogConfigPath() {
5135
- return join16(BLOG_REPO_ROOT, "assist.yml");
5219
+ return join17(BLOG_REPO_ROOT, "assist.yml");
5136
5220
  }
5137
5221
  function skip(date) {
5138
5222
  if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
@@ -5156,7 +5240,7 @@ function skip(date) {
5156
5240
  skip2[repoName] = skipDays;
5157
5241
  devlog.skip = skip2;
5158
5242
  config.devlog = devlog;
5159
- writeFileSync17(configPath, stringifyYaml4(config, { lineWidth: 0 }));
5243
+ writeFileSync18(configPath, stringifyYaml4(config, { lineWidth: 0 }));
5160
5244
  console.log(chalk60.green(`Added ${date} to skip list for ${repoName}`));
5161
5245
  }
5162
5246
 
@@ -5193,16 +5277,16 @@ function registerDevlog(program2) {
5193
5277
 
5194
5278
  // src/commands/dotnet/checkBuildLocks.ts
5195
5279
  import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
5196
- import { join as join17 } from "path";
5280
+ import { join as join18 } from "path";
5197
5281
  import chalk62 from "chalk";
5198
5282
 
5199
5283
  // src/shared/findRepoRoot.ts
5200
- import { existsSync as existsSync23 } from "fs";
5284
+ import { existsSync as existsSync24 } from "fs";
5201
5285
  import path21 from "path";
5202
5286
  function findRepoRoot(dir) {
5203
5287
  let current = dir;
5204
5288
  while (current !== path21.dirname(current)) {
5205
- if (existsSync23(path21.join(current, ".git"))) {
5289
+ if (existsSync24(path21.join(current, ".git"))) {
5206
5290
  return current;
5207
5291
  }
5208
5292
  current = path21.dirname(current);
@@ -5221,7 +5305,7 @@ function isLockedDll(debugDir) {
5221
5305
  }
5222
5306
  for (const file of files) {
5223
5307
  if (!file.toLowerCase().endsWith(".dll")) continue;
5224
- const dllPath = join17(debugDir, file);
5308
+ const dllPath = join18(debugDir, file);
5225
5309
  try {
5226
5310
  const fd = openSync(dllPath, "r+");
5227
5311
  closeSync(fd);
@@ -5239,13 +5323,13 @@ function findFirstLockedDll(dir) {
5239
5323
  return null;
5240
5324
  }
5241
5325
  if (entries.includes("bin")) {
5242
- const locked = isLockedDll(join17(dir, "bin", "Debug"));
5326
+ const locked = isLockedDll(join18(dir, "bin", "Debug"));
5243
5327
  if (locked) return locked;
5244
5328
  }
5245
5329
  for (const entry of entries) {
5246
5330
  if (SKIP_DIRS.has(entry) || entry === "bin" || entry.startsWith("."))
5247
5331
  continue;
5248
- const found = findFirstLockedDll(join17(dir, entry));
5332
+ const found = findFirstLockedDll(join18(dir, entry));
5249
5333
  if (found) return found;
5250
5334
  }
5251
5335
  return null;
@@ -5268,11 +5352,11 @@ async function checkBuildLocksCommand() {
5268
5352
  }
5269
5353
 
5270
5354
  // src/commands/dotnet/buildTree.ts
5271
- import { readFileSync as readFileSync19 } from "fs";
5355
+ import { readFileSync as readFileSync20 } from "fs";
5272
5356
  import path22 from "path";
5273
5357
  var PROJECT_REF_RE = /<ProjectReference\s+Include="([^"]+)"/g;
5274
5358
  function getProjectRefs(csprojPath) {
5275
- const content = readFileSync19(csprojPath, "utf-8");
5359
+ const content = readFileSync20(csprojPath, "utf-8");
5276
5360
  const refs = [];
5277
5361
  for (const match of content.matchAll(PROJECT_REF_RE)) {
5278
5362
  refs.push(match[1].replace(/\\/g, "/"));
@@ -5289,7 +5373,7 @@ function buildTree(csprojPath, repoRoot, visited = /* @__PURE__ */ new Set()) {
5289
5373
  for (const ref of getProjectRefs(abs)) {
5290
5374
  const childAbs = path22.resolve(dir, ref);
5291
5375
  try {
5292
- readFileSync19(childAbs);
5376
+ readFileSync20(childAbs);
5293
5377
  node.children.push(buildTree(childAbs, repoRoot, visited));
5294
5378
  } catch {
5295
5379
  node.children.push({
@@ -5314,7 +5398,7 @@ function collectAllDeps(node) {
5314
5398
  }
5315
5399
 
5316
5400
  // src/commands/dotnet/findContainingSolutions.ts
5317
- import { readdirSync as readdirSync3, readFileSync as readFileSync20, statSync } from "fs";
5401
+ import { readdirSync as readdirSync3, readFileSync as readFileSync21, statSync } from "fs";
5318
5402
  import path23 from "path";
5319
5403
  function findSlnFiles(dir, maxDepth, depth = 0) {
5320
5404
  if (depth > maxDepth) return [];
@@ -5349,7 +5433,7 @@ function findContainingSolutions(csprojPath, repoRoot) {
5349
5433
  const pattern2 = new RegExp(`[\\\\"/]${escapeRegex(csprojBasename)}"`);
5350
5434
  for (const sln of slnFiles) {
5351
5435
  try {
5352
- const content = readFileSync20(sln, "utf-8");
5436
+ const content = readFileSync21(sln, "utf-8");
5353
5437
  if (pattern2.test(content)) {
5354
5438
  matches.push(path23.relative(repoRoot, sln));
5355
5439
  }
@@ -5413,12 +5497,12 @@ function printJson(tree, totalCount, solutions) {
5413
5497
  }
5414
5498
 
5415
5499
  // src/commands/dotnet/resolveCsproj.ts
5416
- import { existsSync as existsSync24 } from "fs";
5500
+ import { existsSync as existsSync25 } from "fs";
5417
5501
  import path24 from "path";
5418
5502
  import chalk64 from "chalk";
5419
5503
  function resolveCsproj(csprojPath) {
5420
5504
  const resolved = path24.resolve(csprojPath);
5421
- if (!existsSync24(resolved)) {
5505
+ if (!existsSync25(resolved)) {
5422
5506
  console.error(chalk64.red(`File not found: ${resolved}`));
5423
5507
  process.exit(1);
5424
5508
  }
@@ -5586,17 +5670,17 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
5586
5670
  }
5587
5671
 
5588
5672
  // src/commands/dotnet/resolveSolution.ts
5589
- import { existsSync as existsSync25 } from "fs";
5673
+ import { existsSync as existsSync26 } from "fs";
5590
5674
  import path25 from "path";
5591
5675
  import chalk68 from "chalk";
5592
5676
 
5593
5677
  // src/commands/dotnet/findSolution.ts
5594
5678
  import { readdirSync as readdirSync4 } from "fs";
5595
- import { dirname as dirname16, join as join18 } from "path";
5679
+ import { dirname as dirname16, join as join19 } from "path";
5596
5680
  import chalk67 from "chalk";
5597
5681
  function findSlnInDir(dir) {
5598
5682
  try {
5599
- return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join18(dir, f));
5683
+ return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join19(dir, f));
5600
5684
  } catch {
5601
5685
  return [];
5602
5686
  }
@@ -5627,7 +5711,7 @@ function findSolution() {
5627
5711
  function resolveSolution(sln) {
5628
5712
  if (sln) {
5629
5713
  const resolved = path25.resolve(sln);
5630
- if (!existsSync25(resolved)) {
5714
+ if (!existsSync26(resolved)) {
5631
5715
  console.error(chalk68.red(`Solution file not found: ${resolved}`));
5632
5716
  process.exit(1);
5633
5717
  }
@@ -5667,7 +5751,7 @@ function parseInspectReport(json) {
5667
5751
 
5668
5752
  // src/commands/dotnet/runInspectCode.ts
5669
5753
  import { execSync as execSync23 } from "child_process";
5670
- import { existsSync as existsSync26, readFileSync as readFileSync21, unlinkSync as unlinkSync4 } from "fs";
5754
+ import { existsSync as existsSync27, readFileSync as readFileSync22, unlinkSync as unlinkSync5 } from "fs";
5671
5755
  import { tmpdir as tmpdir2 } from "os";
5672
5756
  import path26 from "path";
5673
5757
  import chalk69 from "chalk";
@@ -5698,12 +5782,12 @@ function runInspectCode(slnPath, include, swea) {
5698
5782
  console.error(chalk69.red("jb inspectcode failed"));
5699
5783
  process.exit(1);
5700
5784
  }
5701
- if (!existsSync26(reportPath)) {
5785
+ if (!existsSync27(reportPath)) {
5702
5786
  console.error(chalk69.red("Report file not generated"));
5703
5787
  process.exit(1);
5704
5788
  }
5705
- const xml = readFileSync21(reportPath, "utf-8");
5706
- unlinkSync4(reportPath);
5789
+ const xml = readFileSync22(reportPath, "utf-8");
5790
+ unlinkSync5(reportPath);
5707
5791
  return xml;
5708
5792
  }
5709
5793
 
@@ -5930,20 +6014,20 @@ function acceptanceCriteria(issueKey) {
5930
6014
  import { execSync as execSync26 } from "child_process";
5931
6015
 
5932
6016
  // src/shared/loadJson.ts
5933
- import { existsSync as existsSync27, mkdirSync as mkdirSync5, readFileSync as readFileSync22, writeFileSync as writeFileSync18 } from "fs";
6017
+ import { existsSync as existsSync28, mkdirSync as mkdirSync5, readFileSync as readFileSync23, writeFileSync as writeFileSync19 } from "fs";
5934
6018
  import { homedir as homedir6 } from "os";
5935
- import { join as join19 } from "path";
6019
+ import { join as join20 } from "path";
5936
6020
  function getStoreDir() {
5937
- return join19(homedir6(), ".assist");
6021
+ return join20(homedir6(), ".assist");
5938
6022
  }
5939
6023
  function getStorePath(filename) {
5940
- return join19(getStoreDir(), filename);
6024
+ return join20(getStoreDir(), filename);
5941
6025
  }
5942
6026
  function loadJson(filename) {
5943
6027
  const path50 = getStorePath(filename);
5944
- if (existsSync27(path50)) {
6028
+ if (existsSync28(path50)) {
5945
6029
  try {
5946
- return JSON.parse(readFileSync22(path50, "utf-8"));
6030
+ return JSON.parse(readFileSync23(path50, "utf-8"));
5947
6031
  } catch {
5948
6032
  return {};
5949
6033
  }
@@ -5952,10 +6036,10 @@ function loadJson(filename) {
5952
6036
  }
5953
6037
  function saveJson(filename, data) {
5954
6038
  const dir = getStoreDir();
5955
- if (!existsSync27(dir)) {
6039
+ if (!existsSync28(dir)) {
5956
6040
  mkdirSync5(dir, { recursive: true });
5957
6041
  }
5958
- writeFileSync18(getStorePath(filename), JSON.stringify(data, null, 2));
6042
+ writeFileSync19(getStorePath(filename), JSON.stringify(data, null, 2));
5959
6043
  }
5960
6044
 
5961
6045
  // src/shared/promptInput.ts
@@ -6267,9 +6351,9 @@ function registerNews(program2) {
6267
6351
 
6268
6352
  // src/commands/prs/comment.ts
6269
6353
  import { spawnSync as spawnSync2 } from "child_process";
6270
- import { unlinkSync as unlinkSync5, writeFileSync as writeFileSync19 } from "fs";
6354
+ import { unlinkSync as unlinkSync6, writeFileSync as writeFileSync20 } from "fs";
6271
6355
  import { tmpdir as tmpdir3 } from "os";
6272
- import { join as join20 } from "path";
6356
+ import { join as join21 } from "path";
6273
6357
 
6274
6358
  // src/commands/prs/shared.ts
6275
6359
  import { execSync as execSync27 } from "child_process";
@@ -6341,8 +6425,8 @@ function comment2(path50, line, body) {
6341
6425
  validateLine(line);
6342
6426
  try {
6343
6427
  const prId = getCurrentPrNodeId();
6344
- const queryFile = join20(tmpdir3(), `gh-query-${Date.now()}.graphql`);
6345
- writeFileSync19(queryFile, MUTATION);
6428
+ const queryFile = join21(tmpdir3(), `gh-query-${Date.now()}.graphql`);
6429
+ writeFileSync20(queryFile, MUTATION);
6346
6430
  try {
6347
6431
  const result = spawnSync2(
6348
6432
  "gh",
@@ -6367,7 +6451,7 @@ function comment2(path50, line, body) {
6367
6451
  }
6368
6452
  console.log(`Added review comment on ${path50}:${line}`);
6369
6453
  } finally {
6370
- unlinkSync5(queryFile);
6454
+ unlinkSync6(queryFile);
6371
6455
  }
6372
6456
  } catch (error) {
6373
6457
  if (isGhNotInstalled(error)) {
@@ -6384,29 +6468,29 @@ import { execSync as execSync29 } from "child_process";
6384
6468
 
6385
6469
  // src/commands/prs/resolveCommentWithReply.ts
6386
6470
  import { execSync as execSync28 } from "child_process";
6387
- import { unlinkSync as unlinkSync7, writeFileSync as writeFileSync20 } from "fs";
6471
+ import { unlinkSync as unlinkSync8, writeFileSync as writeFileSync21 } from "fs";
6388
6472
  import { tmpdir as tmpdir4 } from "os";
6389
- import { join as join22 } from "path";
6473
+ import { join as join23 } from "path";
6390
6474
 
6391
6475
  // src/commands/prs/loadCommentsCache.ts
6392
- import { existsSync as existsSync28, readFileSync as readFileSync23, unlinkSync as unlinkSync6 } from "fs";
6393
- import { join as join21 } from "path";
6476
+ import { existsSync as existsSync29, readFileSync as readFileSync24, unlinkSync as unlinkSync7 } from "fs";
6477
+ import { join as join22 } from "path";
6394
6478
  import { parse as parse2 } from "yaml";
6395
6479
  function getCachePath(prNumber) {
6396
- return join21(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`);
6480
+ return join22(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`);
6397
6481
  }
6398
6482
  function loadCommentsCache(prNumber) {
6399
6483
  const cachePath = getCachePath(prNumber);
6400
- if (!existsSync28(cachePath)) {
6484
+ if (!existsSync29(cachePath)) {
6401
6485
  return null;
6402
6486
  }
6403
- const content = readFileSync23(cachePath, "utf-8");
6487
+ const content = readFileSync24(cachePath, "utf-8");
6404
6488
  return parse2(content);
6405
6489
  }
6406
6490
  function deleteCommentsCache(prNumber) {
6407
6491
  const cachePath = getCachePath(prNumber);
6408
- if (existsSync28(cachePath)) {
6409
- unlinkSync6(cachePath);
6492
+ if (existsSync29(cachePath)) {
6493
+ unlinkSync7(cachePath);
6410
6494
  console.log("No more unresolved line comments. Cache dropped.");
6411
6495
  }
6412
6496
  }
@@ -6420,15 +6504,15 @@ function replyToComment(org, repo, prNumber, commentId, message) {
6420
6504
  }
6421
6505
  function resolveThread(threadId) {
6422
6506
  const mutation = `mutation($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } }`;
6423
- const queryFile = join22(tmpdir4(), `gh-mutation-${Date.now()}.graphql`);
6424
- writeFileSync20(queryFile, mutation);
6507
+ const queryFile = join23(tmpdir4(), `gh-mutation-${Date.now()}.graphql`);
6508
+ writeFileSync21(queryFile, mutation);
6425
6509
  try {
6426
6510
  execSync28(
6427
6511
  `gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
6428
6512
  { stdio: ["inherit", "pipe", "inherit"] }
6429
6513
  );
6430
6514
  } finally {
6431
- unlinkSync7(queryFile);
6515
+ unlinkSync8(queryFile);
6432
6516
  }
6433
6517
  }
6434
6518
  function requireCache(prNumber) {
@@ -6502,19 +6586,19 @@ function fixed(commentId, sha) {
6502
6586
  }
6503
6587
 
6504
6588
  // src/commands/prs/listComments/index.ts
6505
- import { existsSync as existsSync29, mkdirSync as mkdirSync6, writeFileSync as writeFileSync22 } from "fs";
6506
- import { join as join24 } from "path";
6589
+ import { existsSync as existsSync30, mkdirSync as mkdirSync6, writeFileSync as writeFileSync23 } from "fs";
6590
+ import { join as join25 } from "path";
6507
6591
  import { stringify } from "yaml";
6508
6592
 
6509
6593
  // src/commands/prs/fetchThreadIds.ts
6510
6594
  import { execSync as execSync30 } from "child_process";
6511
- import { unlinkSync as unlinkSync8, writeFileSync as writeFileSync21 } from "fs";
6595
+ import { unlinkSync as unlinkSync9, writeFileSync as writeFileSync22 } from "fs";
6512
6596
  import { tmpdir as tmpdir5 } from "os";
6513
- import { join as join23 } from "path";
6597
+ import { join as join24 } from "path";
6514
6598
  var THREAD_QUERY = `query($owner: String!, $repo: String!, $prNumber: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $prNumber) { reviewThreads(first: 100) { nodes { id isResolved comments(first: 100) { nodes { databaseId } } } } } } }`;
6515
6599
  function fetchThreadIds(org, repo, prNumber) {
6516
- const queryFile = join23(tmpdir5(), `gh-query-${Date.now()}.graphql`);
6517
- writeFileSync21(queryFile, THREAD_QUERY);
6600
+ const queryFile = join24(tmpdir5(), `gh-query-${Date.now()}.graphql`);
6601
+ writeFileSync22(queryFile, THREAD_QUERY);
6518
6602
  try {
6519
6603
  const result = execSync30(
6520
6604
  `gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
@@ -6533,7 +6617,7 @@ function fetchThreadIds(org, repo, prNumber) {
6533
6617
  }
6534
6618
  return { threadMap, resolvedThreadIds };
6535
6619
  } finally {
6536
- unlinkSync8(queryFile);
6620
+ unlinkSync9(queryFile);
6537
6621
  }
6538
6622
  }
6539
6623
 
@@ -6627,8 +6711,8 @@ function printComments2(result) {
6627
6711
 
6628
6712
  // src/commands/prs/listComments/index.ts
6629
6713
  function writeCommentsCache(prNumber, comments2) {
6630
- const assistDir = join24(process.cwd(), ".assist");
6631
- if (!existsSync29(assistDir)) {
6714
+ const assistDir = join25(process.cwd(), ".assist");
6715
+ if (!existsSync30(assistDir)) {
6632
6716
  mkdirSync6(assistDir, { recursive: true });
6633
6717
  }
6634
6718
  const cacheData = {
@@ -6636,8 +6720,8 @@ function writeCommentsCache(prNumber, comments2) {
6636
6720
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
6637
6721
  comments: comments2
6638
6722
  };
6639
- const cachePath = join24(assistDir, `pr-${prNumber}-comments.yaml`);
6640
- writeFileSync22(cachePath, stringify(cacheData));
6723
+ const cachePath = join25(assistDir, `pr-${prNumber}-comments.yaml`);
6724
+ writeFileSync23(cachePath, stringify(cacheData));
6641
6725
  }
6642
6726
  function handleKnownErrors(error) {
6643
6727
  if (isGhNotInstalled(error)) {
@@ -6669,7 +6753,7 @@ async function listComments() {
6669
6753
  ];
6670
6754
  updateCache(prNumber, allComments);
6671
6755
  const hasLineComments = allComments.some((c) => c.type === "line");
6672
- const cachePath = hasLineComments ? join24(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`) : null;
6756
+ const cachePath = hasLineComments ? join25(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`) : null;
6673
6757
  return { comments: allComments, cachePath };
6674
6758
  } catch (error) {
6675
6759
  const handled = handleKnownErrors(error);
@@ -7069,9 +7153,9 @@ function clearCachedToken(apiKey) {
7069
7153
  }
7070
7154
  async function getAccessToken(apiKey) {
7071
7155
  const now = Date.now();
7072
- const cached2 = tokenCache.get(apiKey);
7073
- if (cached2 && now < cached2.expiry) {
7074
- return cached2.token;
7156
+ const cached = tokenCache.get(apiKey);
7157
+ if (cached && now < cached.expiry) {
7158
+ return cached.token;
7075
7159
  }
7076
7160
  const response = await fetch(OAUTH_URL, {
7077
7161
  method: "GET",
@@ -8988,8 +9072,8 @@ function registerSeq(program2) {
8988
9072
  }
8989
9073
 
8990
9074
  // src/commands/transcript/shared.ts
8991
- import { existsSync as existsSync30, readdirSync as readdirSync5, statSync as statSync2 } from "fs";
8992
- import { basename as basename4, join as join25, relative } from "path";
9075
+ import { existsSync as existsSync31, readdirSync as readdirSync5, statSync as statSync2 } from "fs";
9076
+ import { basename as basename4, join as join26, relative } from "path";
8993
9077
  import * as readline2 from "readline";
8994
9078
  var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
8995
9079
  function getDatePrefix(daysOffset = 0) {
@@ -9004,10 +9088,10 @@ function isValidDatePrefix(filename) {
9004
9088
  return DATE_PREFIX_REGEX.test(filename);
9005
9089
  }
9006
9090
  function collectFiles(dir, extension) {
9007
- if (!existsSync30(dir)) return [];
9091
+ if (!existsSync31(dir)) return [];
9008
9092
  const results = [];
9009
9093
  for (const entry of readdirSync5(dir)) {
9010
- const fullPath = join25(dir, entry);
9094
+ const fullPath = join26(dir, entry);
9011
9095
  if (statSync2(fullPath).isDirectory()) {
9012
9096
  results.push(...collectFiles(fullPath, extension));
9013
9097
  } else if (entry.endsWith(extension)) {
@@ -9101,14 +9185,14 @@ async function configure() {
9101
9185
  }
9102
9186
 
9103
9187
  // src/commands/transcript/format/index.ts
9104
- import { existsSync as existsSync32 } from "fs";
9188
+ import { existsSync as existsSync33 } from "fs";
9105
9189
 
9106
9190
  // src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
9107
- import { dirname as dirname18, join as join27 } from "path";
9191
+ import { dirname as dirname18, join as join28 } from "path";
9108
9192
 
9109
9193
  // src/commands/transcript/format/fixInvalidDatePrefixes/promptForDateFix.ts
9110
9194
  import { renameSync } from "fs";
9111
- import { join as join26 } from "path";
9195
+ import { join as join27 } from "path";
9112
9196
  async function resolveDate(rl, choice) {
9113
9197
  if (choice === "1") return getDatePrefix(0);
9114
9198
  if (choice === "2") return getDatePrefix(-1);
@@ -9123,7 +9207,7 @@ async function resolveDate(rl, choice) {
9123
9207
  }
9124
9208
  function renameWithPrefix(vttDir, vttFile, prefix2) {
9125
9209
  const newFilename = `${prefix2}.${vttFile}`;
9126
- renameSync(join26(vttDir, vttFile), join26(vttDir, newFilename));
9210
+ renameSync(join27(vttDir, vttFile), join27(vttDir, newFilename));
9127
9211
  console.log(`Renamed to: ${newFilename}`);
9128
9212
  return newFilename;
9129
9213
  }
@@ -9157,12 +9241,12 @@ async function fixInvalidDatePrefixes(vttFiles) {
9157
9241
  const vttFileDir = dirname18(vttFile.absolutePath);
9158
9242
  const newFilename = await promptForDateFix(vttFile.filename, vttFileDir);
9159
9243
  if (newFilename) {
9160
- const newRelativePath = join27(
9244
+ const newRelativePath = join28(
9161
9245
  dirname18(vttFile.relativePath),
9162
9246
  newFilename
9163
9247
  );
9164
9248
  vttFiles[i] = {
9165
- absolutePath: join27(vttFileDir, newFilename),
9249
+ absolutePath: join28(vttFileDir, newFilename),
9166
9250
  relativePath: newRelativePath,
9167
9251
  filename: newFilename
9168
9252
  };
@@ -9175,8 +9259,8 @@ async function fixInvalidDatePrefixes(vttFiles) {
9175
9259
  }
9176
9260
 
9177
9261
  // src/commands/transcript/format/processVttFile/index.ts
9178
- import { existsSync as existsSync31, mkdirSync as mkdirSync7, readFileSync as readFileSync24, writeFileSync as writeFileSync23 } from "fs";
9179
- import { basename as basename5, dirname as dirname19, join as join28 } from "path";
9262
+ import { existsSync as existsSync32, mkdirSync as mkdirSync7, readFileSync as readFileSync25, writeFileSync as writeFileSync24 } from "fs";
9263
+ import { basename as basename5, dirname as dirname19, join as join29 } from "path";
9180
9264
 
9181
9265
  // src/commands/transcript/cleanText.ts
9182
9266
  function cleanText(text) {
@@ -9386,21 +9470,21 @@ function toMdFilename(vttFilename) {
9386
9470
  return `${basename5(vttFilename, ".vtt").replace(/\s*Transcription\s*/g, " ").trim()}.md`;
9387
9471
  }
9388
9472
  function resolveOutputDir(relativeDir, transcriptsDir) {
9389
- return relativeDir === "." ? transcriptsDir : join28(transcriptsDir, relativeDir);
9473
+ return relativeDir === "." ? transcriptsDir : join29(transcriptsDir, relativeDir);
9390
9474
  }
9391
9475
  function buildOutputPaths(vttFile, transcriptsDir) {
9392
9476
  const mdFile = toMdFilename(vttFile.filename);
9393
9477
  const relativeDir = dirname19(vttFile.relativePath);
9394
9478
  const outputDir = resolveOutputDir(relativeDir, transcriptsDir);
9395
- const outputPath = join28(outputDir, mdFile);
9479
+ const outputPath = join29(outputDir, mdFile);
9396
9480
  return { outputDir, outputPath, mdFile, relativeDir };
9397
9481
  }
9398
9482
  function logSkipped(relativeDir, mdFile) {
9399
- console.log(`Skipping (already exists): ${join28(relativeDir, mdFile)}`);
9483
+ console.log(`Skipping (already exists): ${join29(relativeDir, mdFile)}`);
9400
9484
  return "skipped";
9401
9485
  }
9402
9486
  function ensureDirectory(dir, label2) {
9403
- if (!existsSync31(dir)) {
9487
+ if (!existsSync32(dir)) {
9404
9488
  mkdirSync7(dir, { recursive: true });
9405
9489
  console.log(`Created ${label2}: ${dir}`);
9406
9490
  }
@@ -9423,10 +9507,10 @@ function logReduction(cueCount, messageCount) {
9423
9507
  }
9424
9508
  function readAndParseCues(inputPath) {
9425
9509
  console.log(`Reading: ${inputPath}`);
9426
- return processCues(readFileSync24(inputPath, "utf-8"));
9510
+ return processCues(readFileSync25(inputPath, "utf-8"));
9427
9511
  }
9428
9512
  function writeFormatted(outputPath, content) {
9429
- writeFileSync23(outputPath, content, "utf-8");
9513
+ writeFileSync24(outputPath, content, "utf-8");
9430
9514
  console.log(`Written: ${outputPath}`);
9431
9515
  }
9432
9516
  function convertVttToMarkdown(inputPath, outputPath) {
@@ -9436,7 +9520,7 @@ function convertVttToMarkdown(inputPath, outputPath) {
9436
9520
  logReduction(cues.length, chatMessages.length);
9437
9521
  }
9438
9522
  function tryProcessVtt(vttFile, paths) {
9439
- if (existsSync31(paths.outputPath))
9523
+ if (existsSync32(paths.outputPath))
9440
9524
  return logSkipped(paths.relativeDir, paths.mdFile);
9441
9525
  convertVttToMarkdown(vttFile.absolutePath, paths.outputPath);
9442
9526
  return "processed";
@@ -9462,7 +9546,7 @@ function processAllFiles(vttFiles, transcriptsDir) {
9462
9546
  logSummary(counts);
9463
9547
  }
9464
9548
  function requireVttDir(vttDir) {
9465
- if (!existsSync32(vttDir)) {
9549
+ if (!existsSync33(vttDir)) {
9466
9550
  console.error(`VTT directory not found: ${vttDir}`);
9467
9551
  process.exit(1);
9468
9552
  }
@@ -9494,18 +9578,18 @@ async function format() {
9494
9578
  }
9495
9579
 
9496
9580
  // src/commands/transcript/summarise/index.ts
9497
- import { existsSync as existsSync34 } from "fs";
9498
- import { basename as basename6, dirname as dirname21, join as join30, relative as relative2 } from "path";
9581
+ import { existsSync as existsSync35 } from "fs";
9582
+ import { basename as basename6, dirname as dirname21, join as join31, relative as relative2 } from "path";
9499
9583
 
9500
9584
  // src/commands/transcript/summarise/processStagedFile/index.ts
9501
9585
  import {
9502
- existsSync as existsSync33,
9586
+ existsSync as existsSync34,
9503
9587
  mkdirSync as mkdirSync8,
9504
- readFileSync as readFileSync25,
9588
+ readFileSync as readFileSync26,
9505
9589
  renameSync as renameSync2,
9506
9590
  rmSync
9507
9591
  } from "fs";
9508
- import { dirname as dirname20, join as join29 } from "path";
9592
+ import { dirname as dirname20, join as join30 } from "path";
9509
9593
 
9510
9594
  // src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
9511
9595
  import chalk107 from "chalk";
@@ -9534,9 +9618,9 @@ function validateStagedContent(filename, content) {
9534
9618
  }
9535
9619
 
9536
9620
  // src/commands/transcript/summarise/processStagedFile/index.ts
9537
- var STAGING_DIR = join29(process.cwd(), ".assist", "transcript");
9621
+ var STAGING_DIR = join30(process.cwd(), ".assist", "transcript");
9538
9622
  function processStagedFile() {
9539
- if (!existsSync33(STAGING_DIR)) {
9623
+ if (!existsSync34(STAGING_DIR)) {
9540
9624
  return false;
9541
9625
  }
9542
9626
  const stagedFiles = findMdFilesRecursive(STAGING_DIR);
@@ -9545,7 +9629,7 @@ function processStagedFile() {
9545
9629
  }
9546
9630
  const { transcriptsDir, summaryDir } = getTranscriptConfig();
9547
9631
  const stagedFile = stagedFiles[0];
9548
- const content = readFileSync25(stagedFile.absolutePath, "utf-8");
9632
+ const content = readFileSync26(stagedFile.absolutePath, "utf-8");
9549
9633
  validateStagedContent(stagedFile.filename, content);
9550
9634
  const stagedBaseName = getTranscriptBaseName(stagedFile.filename);
9551
9635
  const transcriptFiles = findMdFilesRecursive(transcriptsDir);
@@ -9558,9 +9642,9 @@ function processStagedFile() {
9558
9642
  );
9559
9643
  process.exit(1);
9560
9644
  }
9561
- const destPath = join29(summaryDir, matchingTranscript.relativePath);
9645
+ const destPath = join30(summaryDir, matchingTranscript.relativePath);
9562
9646
  const destDir = dirname20(destPath);
9563
- if (!existsSync33(destDir)) {
9647
+ if (!existsSync34(destDir)) {
9564
9648
  mkdirSync8(destDir, { recursive: true });
9565
9649
  }
9566
9650
  renameSync2(stagedFile.absolutePath, destPath);
@@ -9574,7 +9658,7 @@ function processStagedFile() {
9574
9658
  // src/commands/transcript/summarise/index.ts
9575
9659
  function buildRelativeKey(relativePath, baseName) {
9576
9660
  const relDir = dirname21(relativePath);
9577
- return relDir === "." ? baseName : join30(relDir, baseName);
9661
+ return relDir === "." ? baseName : join31(relDir, baseName);
9578
9662
  }
9579
9663
  function buildSummaryIndex(summaryDir) {
9580
9664
  const summaryFiles = findMdFilesRecursive(summaryDir);
@@ -9587,7 +9671,7 @@ function buildSummaryIndex(summaryDir) {
9587
9671
  function summarise2() {
9588
9672
  processStagedFile();
9589
9673
  const { transcriptsDir, summaryDir } = getTranscriptConfig();
9590
- if (!existsSync34(transcriptsDir)) {
9674
+ if (!existsSync35(transcriptsDir)) {
9591
9675
  console.log("No transcripts directory found.");
9592
9676
  return;
9593
9677
  }
@@ -9608,8 +9692,8 @@ function summarise2() {
9608
9692
  }
9609
9693
  const next3 = missing[0];
9610
9694
  const outputFilename = `${getTranscriptBaseName(next3.filename)}.md`;
9611
- const outputPath = join30(STAGING_DIR, outputFilename);
9612
- const summaryFileDir = join30(summaryDir, dirname21(next3.relativePath));
9695
+ const outputPath = join31(STAGING_DIR, outputFilename);
9696
+ const summaryFileDir = join31(summaryDir, dirname21(next3.relativePath));
9613
9697
  const relativeTranscriptPath = encodeURI(
9614
9698
  relative2(summaryFileDir, next3.absolutePath).replace(/\\/g, "/")
9615
9699
  );
@@ -9655,50 +9739,50 @@ function registerVerify(program2) {
9655
9739
 
9656
9740
  // src/commands/voice/devices.ts
9657
9741
  import { spawnSync as spawnSync3 } from "child_process";
9658
- import { join as join32 } from "path";
9742
+ import { join as join33 } from "path";
9659
9743
 
9660
9744
  // src/commands/voice/shared.ts
9661
9745
  import { homedir as homedir7 } from "os";
9662
- import { dirname as dirname22, join as join31 } from "path";
9746
+ import { dirname as dirname22, join as join32 } from "path";
9663
9747
  import { fileURLToPath as fileURLToPath6 } from "url";
9664
9748
  var __dirname6 = dirname22(fileURLToPath6(import.meta.url));
9665
- var VOICE_DIR = join31(homedir7(), ".assist", "voice");
9749
+ var VOICE_DIR = join32(homedir7(), ".assist", "voice");
9666
9750
  var voicePaths = {
9667
9751
  dir: VOICE_DIR,
9668
- pid: join31(VOICE_DIR, "voice.pid"),
9669
- log: join31(VOICE_DIR, "voice.log"),
9670
- venv: join31(VOICE_DIR, ".venv"),
9671
- lock: join31(VOICE_DIR, "voice.lock")
9752
+ pid: join32(VOICE_DIR, "voice.pid"),
9753
+ log: join32(VOICE_DIR, "voice.log"),
9754
+ venv: join32(VOICE_DIR, ".venv"),
9755
+ lock: join32(VOICE_DIR, "voice.lock")
9672
9756
  };
9673
9757
  function getPythonDir() {
9674
- return join31(__dirname6, "commands", "voice", "python");
9758
+ return join32(__dirname6, "commands", "voice", "python");
9675
9759
  }
9676
9760
  function getVenvPython() {
9677
- return process.platform === "win32" ? join31(voicePaths.venv, "Scripts", "python.exe") : join31(voicePaths.venv, "bin", "python");
9761
+ return process.platform === "win32" ? join32(voicePaths.venv, "Scripts", "python.exe") : join32(voicePaths.venv, "bin", "python");
9678
9762
  }
9679
9763
  function getLockDir() {
9680
9764
  const config = loadConfig();
9681
9765
  return config.voice?.lockDir ?? VOICE_DIR;
9682
9766
  }
9683
9767
  function getLockFile() {
9684
- return join31(getLockDir(), "voice.lock");
9768
+ return join32(getLockDir(), "voice.lock");
9685
9769
  }
9686
9770
 
9687
9771
  // src/commands/voice/devices.ts
9688
9772
  function devices() {
9689
- const script = join32(getPythonDir(), "list_devices.py");
9773
+ const script = join33(getPythonDir(), "list_devices.py");
9690
9774
  spawnSync3(getVenvPython(), [script], { stdio: "inherit" });
9691
9775
  }
9692
9776
 
9693
9777
  // src/commands/voice/logs.ts
9694
- import { existsSync as existsSync35, readFileSync as readFileSync26 } from "fs";
9778
+ import { existsSync as existsSync36, readFileSync as readFileSync27 } from "fs";
9695
9779
  function logs(options2) {
9696
- if (!existsSync35(voicePaths.log)) {
9780
+ if (!existsSync36(voicePaths.log)) {
9697
9781
  console.log("No voice log file found");
9698
9782
  return;
9699
9783
  }
9700
9784
  const count = Number.parseInt(options2.lines ?? "150", 10);
9701
- const content = readFileSync26(voicePaths.log, "utf-8").trim();
9785
+ const content = readFileSync27(voicePaths.log, "utf-8").trim();
9702
9786
  if (!content) {
9703
9787
  console.log("Voice log is empty");
9704
9788
  return;
@@ -9721,13 +9805,13 @@ function logs(options2) {
9721
9805
  // src/commands/voice/setup.ts
9722
9806
  import { spawnSync as spawnSync4 } from "child_process";
9723
9807
  import { mkdirSync as mkdirSync10 } from "fs";
9724
- import { join as join34 } from "path";
9808
+ import { join as join35 } from "path";
9725
9809
 
9726
9810
  // src/commands/voice/checkLockFile.ts
9727
9811
  import { execSync as execSync37 } from "child_process";
9728
- import { existsSync as existsSync36, mkdirSync as mkdirSync9, readFileSync as readFileSync27, writeFileSync as writeFileSync24 } from "fs";
9729
- import { join as join33 } from "path";
9730
- function isProcessAlive(pid) {
9812
+ import { existsSync as existsSync37, mkdirSync as mkdirSync9, readFileSync as readFileSync28, writeFileSync as writeFileSync25 } from "fs";
9813
+ import { join as join34 } from "path";
9814
+ function isProcessAlive2(pid) {
9731
9815
  try {
9732
9816
  process.kill(pid, 0);
9733
9817
  return true;
@@ -9737,10 +9821,10 @@ function isProcessAlive(pid) {
9737
9821
  }
9738
9822
  function checkLockFile() {
9739
9823
  const lockFile = getLockFile();
9740
- if (!existsSync36(lockFile)) return;
9824
+ if (!existsSync37(lockFile)) return;
9741
9825
  try {
9742
- const lock = JSON.parse(readFileSync27(lockFile, "utf-8"));
9743
- if (lock.pid && isProcessAlive(lock.pid)) {
9826
+ const lock = JSON.parse(readFileSync28(lockFile, "utf-8"));
9827
+ if (lock.pid && isProcessAlive2(lock.pid)) {
9744
9828
  console.error(
9745
9829
  `Voice daemon already running (PID ${lock.pid}, env: ${lock.env}). Stop it first with: assist voice stop`
9746
9830
  );
@@ -9750,7 +9834,7 @@ function checkLockFile() {
9750
9834
  }
9751
9835
  }
9752
9836
  function bootstrapVenv() {
9753
- if (existsSync36(getVenvPython())) return;
9837
+ if (existsSync37(getVenvPython())) return;
9754
9838
  console.log("Setting up Python environment...");
9755
9839
  const pythonDir = getPythonDir();
9756
9840
  execSync37(
@@ -9763,8 +9847,8 @@ function bootstrapVenv() {
9763
9847
  }
9764
9848
  function writeLockFile(pid) {
9765
9849
  const lockFile = getLockFile();
9766
- mkdirSync9(join33(lockFile, ".."), { recursive: true });
9767
- writeFileSync24(
9850
+ mkdirSync9(join34(lockFile, ".."), { recursive: true });
9851
+ writeFileSync25(
9768
9852
  lockFile,
9769
9853
  JSON.stringify({
9770
9854
  pid,
@@ -9779,7 +9863,7 @@ function setup() {
9779
9863
  mkdirSync10(voicePaths.dir, { recursive: true });
9780
9864
  bootstrapVenv();
9781
9865
  console.log("\nDownloading models...\n");
9782
- const script = join34(getPythonDir(), "setup_models.py");
9866
+ const script = join35(getPythonDir(), "setup_models.py");
9783
9867
  const result = spawnSync4(getVenvPython(), [script], {
9784
9868
  stdio: "inherit",
9785
9869
  env: { ...process.env, VOICE_LOG_FILE: voicePaths.log }
@@ -9792,8 +9876,8 @@ function setup() {
9792
9876
 
9793
9877
  // src/commands/voice/start.ts
9794
9878
  import { spawn as spawn5 } from "child_process";
9795
- import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync25 } from "fs";
9796
- import { join as join35 } from "path";
9879
+ import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync26 } from "fs";
9880
+ import { join as join36 } from "path";
9797
9881
 
9798
9882
  // src/commands/voice/buildDaemonEnv.ts
9799
9883
  function buildDaemonEnv(options2) {
@@ -9821,7 +9905,7 @@ function spawnBackground(python, script, env) {
9821
9905
  console.error("Failed to start voice daemon");
9822
9906
  process.exit(1);
9823
9907
  }
9824
- writeFileSync25(voicePaths.pid, String(pid));
9908
+ writeFileSync26(voicePaths.pid, String(pid));
9825
9909
  writeLockFile(pid);
9826
9910
  console.log(`Voice daemon started (PID ${pid})`);
9827
9911
  }
@@ -9831,7 +9915,7 @@ function start2(options2) {
9831
9915
  bootstrapVenv();
9832
9916
  const debug = options2.debug || options2.foreground || process.platform === "win32";
9833
9917
  const env = buildDaemonEnv({ debug });
9834
- const script = join35(getPythonDir(), "voice_daemon.py");
9918
+ const script = join36(getPythonDir(), "voice_daemon.py");
9835
9919
  const python = getVenvPython();
9836
9920
  if (options2.foreground) {
9837
9921
  spawnForeground(python, script, env);
@@ -9841,8 +9925,8 @@ function start2(options2) {
9841
9925
  }
9842
9926
 
9843
9927
  // src/commands/voice/status.ts
9844
- import { existsSync as existsSync37, readFileSync as readFileSync28 } from "fs";
9845
- function isProcessAlive2(pid) {
9928
+ import { existsSync as existsSync38, readFileSync as readFileSync29 } from "fs";
9929
+ function isProcessAlive3(pid) {
9846
9930
  try {
9847
9931
  process.kill(pid, 0);
9848
9932
  return true;
@@ -9851,17 +9935,17 @@ function isProcessAlive2(pid) {
9851
9935
  }
9852
9936
  }
9853
9937
  function readRecentLogs(count) {
9854
- if (!existsSync37(voicePaths.log)) return [];
9855
- const lines = readFileSync28(voicePaths.log, "utf-8").trim().split("\n");
9938
+ if (!existsSync38(voicePaths.log)) return [];
9939
+ const lines = readFileSync29(voicePaths.log, "utf-8").trim().split("\n");
9856
9940
  return lines.slice(-count);
9857
9941
  }
9858
9942
  function status() {
9859
- if (!existsSync37(voicePaths.pid)) {
9943
+ if (!existsSync38(voicePaths.pid)) {
9860
9944
  console.log("Voice daemon: not running (no PID file)");
9861
9945
  return;
9862
9946
  }
9863
- const pid = Number.parseInt(readFileSync28(voicePaths.pid, "utf-8").trim(), 10);
9864
- const alive = isProcessAlive2(pid);
9947
+ const pid = Number.parseInt(readFileSync29(voicePaths.pid, "utf-8").trim(), 10);
9948
+ const alive = isProcessAlive3(pid);
9865
9949
  console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
9866
9950
  const recent = readRecentLogs(5);
9867
9951
  if (recent.length > 0) {
@@ -9879,13 +9963,13 @@ function status() {
9879
9963
  }
9880
9964
 
9881
9965
  // src/commands/voice/stop.ts
9882
- import { existsSync as existsSync38, readFileSync as readFileSync29, unlinkSync as unlinkSync9 } from "fs";
9966
+ import { existsSync as existsSync39, readFileSync as readFileSync30, unlinkSync as unlinkSync10 } from "fs";
9883
9967
  function stop() {
9884
- if (!existsSync38(voicePaths.pid)) {
9968
+ if (!existsSync39(voicePaths.pid)) {
9885
9969
  console.log("Voice daemon is not running (no PID file)");
9886
9970
  return;
9887
9971
  }
9888
- const pid = Number.parseInt(readFileSync29(voicePaths.pid, "utf-8").trim(), 10);
9972
+ const pid = Number.parseInt(readFileSync30(voicePaths.pid, "utf-8").trim(), 10);
9889
9973
  try {
9890
9974
  process.kill(pid, "SIGTERM");
9891
9975
  console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
@@ -9893,12 +9977,12 @@ function stop() {
9893
9977
  console.log(`Voice daemon (PID ${pid}) is not running`);
9894
9978
  }
9895
9979
  try {
9896
- unlinkSync9(voicePaths.pid);
9980
+ unlinkSync10(voicePaths.pid);
9897
9981
  } catch {
9898
9982
  }
9899
9983
  try {
9900
9984
  const lockFile = getLockFile();
9901
- if (existsSync38(lockFile)) unlinkSync9(lockFile);
9985
+ if (existsSync39(lockFile)) unlinkSync10(lockFile);
9902
9986
  } catch {
9903
9987
  }
9904
9988
  console.log("Voice daemon stopped");
@@ -10119,15 +10203,15 @@ async function auth() {
10119
10203
  }
10120
10204
 
10121
10205
  // src/commands/roam/showClaudeCodeIcon.ts
10122
- import { readFileSync as readFileSync30 } from "fs";
10123
- import { join as join36 } from "path";
10206
+ import { readFileSync as readFileSync31 } from "fs";
10207
+ import { join as join37 } from "path";
10124
10208
  async function showClaudeCodeIcon() {
10125
10209
  const appData = process.env.APPDATA;
10126
10210
  if (!appData) return;
10127
- const portFile = join36(appData, "Roam", "roam-local-api.port");
10211
+ const portFile = join37(appData, "Roam", "roam-local-api.port");
10128
10212
  let port;
10129
10213
  try {
10130
- port = readFileSync30(portFile, "utf-8").trim();
10214
+ port = readFileSync31(portFile, "utf-8").trim();
10131
10215
  } catch {
10132
10216
  return;
10133
10217
  }
@@ -10198,8 +10282,8 @@ Done in ${elapsed}`);
10198
10282
  }
10199
10283
 
10200
10284
  // src/commands/run/add.ts
10201
- import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync26 } from "fs";
10202
- import { join as join37 } from "path";
10285
+ import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync27 } from "fs";
10286
+ import { join as join38 } from "path";
10203
10287
  function findAddIndex() {
10204
10288
  const addIndex = process.argv.indexOf("add");
10205
10289
  if (addIndex === -1 || addIndex + 2 >= process.argv.length) return -1;
@@ -10245,7 +10329,7 @@ function saveNewRunConfig(name, command, args) {
10245
10329
  saveConfig(config);
10246
10330
  }
10247
10331
  function createCommandFile(name) {
10248
- const dir = join37(".claude", "commands");
10332
+ const dir = join38(".claude", "commands");
10249
10333
  mkdirSync12(dir, { recursive: true });
10250
10334
  const content = `---
10251
10335
  description: Run ${name}
@@ -10253,8 +10337,8 @@ description: Run ${name}
10253
10337
 
10254
10338
  Run \`assist run ${name} $ARGUMENTS 2>&1\`.
10255
10339
  `;
10256
- const filePath = join37(dir, `${name}.md`);
10257
- writeFileSync26(filePath, content);
10340
+ const filePath = join38(dir, `${name}.md`);
10341
+ writeFileSync27(filePath, content);
10258
10342
  console.log(`Created command file: ${filePath}`);
10259
10343
  }
10260
10344
  function add3() {
@@ -10324,9 +10408,9 @@ function run3(name, args) {
10324
10408
 
10325
10409
  // src/commands/screenshot/index.ts
10326
10410
  import { execSync as execSync40 } from "child_process";
10327
- import { existsSync as existsSync39, mkdirSync as mkdirSync13, unlinkSync as unlinkSync10, writeFileSync as writeFileSync27 } from "fs";
10411
+ import { existsSync as existsSync40, mkdirSync as mkdirSync13, unlinkSync as unlinkSync11, writeFileSync as writeFileSync28 } from "fs";
10328
10412
  import { tmpdir as tmpdir6 } from "os";
10329
- import { join as join38, resolve as resolve5 } from "path";
10413
+ import { join as join39, resolve as resolve5 } from "path";
10330
10414
  import chalk109 from "chalk";
10331
10415
 
10332
10416
  // src/commands/screenshot/captureWindowPs1.ts
@@ -10456,22 +10540,22 @@ Write-Output $OutputPath
10456
10540
 
10457
10541
  // src/commands/screenshot/index.ts
10458
10542
  function buildOutputPath(outputDir, processName) {
10459
- if (!existsSync39(outputDir)) {
10543
+ if (!existsSync40(outputDir)) {
10460
10544
  mkdirSync13(outputDir, { recursive: true });
10461
10545
  }
10462
10546
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
10463
10547
  return resolve5(outputDir, `${processName}-${timestamp}.png`);
10464
10548
  }
10465
10549
  function runPowerShellScript(processName, outputPath) {
10466
- const scriptPath = join38(tmpdir6(), `assist-screenshot-${Date.now()}.ps1`);
10467
- writeFileSync27(scriptPath, captureWindowPs1, "utf-8");
10550
+ const scriptPath = join39(tmpdir6(), `assist-screenshot-${Date.now()}.ps1`);
10551
+ writeFileSync28(scriptPath, captureWindowPs1, "utf-8");
10468
10552
  try {
10469
10553
  execSync40(
10470
10554
  `powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
10471
10555
  { stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }
10472
10556
  );
10473
10557
  } finally {
10474
- unlinkSync10(scriptPath);
10558
+ unlinkSync11(scriptPath);
10475
10559
  }
10476
10560
  }
10477
10561
  function screenshot(processName) {