@staff0rd/assist 0.147.4 → 0.149.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.147.4",
9
+ version: "0.149.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -483,6 +483,21 @@ function configList() {
483
483
  console.log(stringifyYaml2(config, { lineWidth: 0 }).trimEnd());
484
484
  }
485
485
 
486
+ // src/commands/coverage.ts
487
+ import { execSync as execSync2 } from "child_process";
488
+ function coverage() {
489
+ const output = execSync2(
490
+ "npx vitest run --coverage --coverage.include='src/**/*.ts' --coverage.all --coverage.reporter=text 2>&1",
491
+ { encoding: "utf-8", timeout: 12e4 }
492
+ );
493
+ const match = output.match(/All files\s*\|\s*([\d.]+)/);
494
+ if (!match) {
495
+ console.error("Could not determine coverage from vitest output.");
496
+ process.exit(1);
497
+ }
498
+ console.log(`${match[1]}%`);
499
+ }
500
+
486
501
  // src/commands/verify/init/index.ts
487
502
  import chalk17 from "chalk";
488
503
 
@@ -555,7 +570,7 @@ function findPackageJsonWithVerifyScripts(startDir) {
555
570
  }
556
571
 
557
572
  // src/commands/verify/installPackage.ts
558
- import { execSync as execSync2 } from "child_process";
573
+ import { execSync as execSync3 } from "child_process";
559
574
  import { writeFileSync as writeFileSync2 } from "fs";
560
575
  import chalk5 from "chalk";
561
576
  function writePackageJson(filePath, pkg) {
@@ -574,7 +589,7 @@ function addScript(pkg, name, command) {
574
589
  function installPackage(name, cwd) {
575
590
  console.log(chalk5.dim(`Installing ${name}...`));
576
591
  try {
577
- execSync2(`npm install -D ${name}`, { stdio: "inherit", cwd });
592
+ execSync3(`npm install -D ${name}`, { stdio: "inherit", cwd });
578
593
  return true;
579
594
  } catch {
580
595
  console.error(chalk5.red(`Failed to install ${name}`));
@@ -720,7 +735,7 @@ import * as path5 from "path";
720
735
  import chalk13 from "chalk";
721
736
 
722
737
  // src/commands/lint/init.ts
723
- import { execSync as execSync4 } from "child_process";
738
+ import { execSync as execSync5 } from "child_process";
724
739
  import { existsSync as existsSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
725
740
  import { dirname as dirname6, join as join4 } from "path";
726
741
  import { fileURLToPath } from "url";
@@ -744,7 +759,7 @@ async function promptConfirm(message, initial = true) {
744
759
  }
745
760
 
746
761
  // src/shared/removeEslint/index.ts
747
- import { execSync as execSync3 } from "child_process";
762
+ import { execSync as execSync4 } from "child_process";
748
763
  import { existsSync as existsSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
749
764
 
750
765
  // src/shared/removeEslint/removeEslintConfigFiles.ts
@@ -779,7 +794,7 @@ function removeEslint(options2 = {}) {
779
794
  const removedConfigFiles = removeEslintConfigFiles();
780
795
  if (removedFromPackageJson || removedConfigFiles) {
781
796
  console.log("Running npm install...");
782
- execSync3("npm install", { stdio: "inherit" });
797
+ execSync4("npm install", { stdio: "inherit" });
783
798
  return true;
784
799
  }
785
800
  return false;
@@ -861,7 +876,7 @@ async function init() {
861
876
  const biomeConfigPath = "biome.json";
862
877
  if (!existsSync7(biomeConfigPath)) {
863
878
  console.log("Initializing Biome...");
864
- execSync4("npx @biomejs/biome init", { stdio: "inherit" });
879
+ execSync5("npx @biomejs/biome init", { stdio: "inherit" });
865
880
  }
866
881
  if (!existsSync7(biomeConfigPath)) {
867
882
  console.log("No biome.json found, skipping linter config");
@@ -1615,17 +1630,17 @@ function lint(options2 = {}) {
1615
1630
  }
1616
1631
 
1617
1632
  // src/commands/new/registerNew/newCli/index.ts
1618
- import { execSync as execSync10 } from "child_process";
1633
+ import { execSync as execSync11 } from "child_process";
1619
1634
  import { basename as basename2, resolve } from "path";
1620
1635
 
1621
1636
  // src/commands/verify/hardcodedColors.ts
1622
- import { execSync as execSync5 } from "child_process";
1637
+ import { execSync as execSync6 } from "child_process";
1623
1638
  import { minimatch } from "minimatch";
1624
1639
  var pattern = "0x[0-9a-fA-F]{6}|#[0-9a-fA-F]{3,6}";
1625
1640
  function hardcodedColors() {
1626
1641
  const ignoreGlobs = loadConfig().hardcodedColors?.ignore ?? [];
1627
1642
  try {
1628
- const output = execSync5(`grep -rEnH '${pattern}' src/`, {
1643
+ const output = execSync6(`grep -rEnH '${pattern}' src/`, {
1629
1644
  encoding: "utf-8"
1630
1645
  });
1631
1646
  const lines = output.trim().split("\n").filter((line) => {
@@ -1704,10 +1719,10 @@ function list() {
1704
1719
  }
1705
1720
 
1706
1721
  // src/commands/verify/noVenv.ts
1707
- import { execSync as execSync6 } from "child_process";
1722
+ import { execSync as execSync7 } from "child_process";
1708
1723
  function noVenv() {
1709
1724
  try {
1710
- const output = execSync6(
1725
+ const output = execSync7(
1711
1726
  "find . -type d -name venv -not -path '*/node_modules/*'",
1712
1727
  {
1713
1728
  encoding: "utf-8"
@@ -1739,9 +1754,9 @@ Total: ${folders.length} venv folder(s)`);
1739
1754
  import { minimatch as minimatch2 } from "minimatch";
1740
1755
 
1741
1756
  // src/commands/verify/run/getChangedFiles.ts
1742
- import { execSync as execSync7 } from "child_process";
1757
+ import { execSync as execSync8 } from "child_process";
1743
1758
  function getChangedFiles() {
1744
- const output = execSync7("git diff --name-only HEAD", {
1759
+ const output = execSync8("git diff --name-only HEAD", {
1745
1760
  encoding: "utf-8"
1746
1761
  }).trim();
1747
1762
  if (output === "") return [];
@@ -1903,25 +1918,25 @@ async function run(options2 = {}) {
1903
1918
  }
1904
1919
 
1905
1920
  // src/commands/new/registerNew/initGit.ts
1906
- import { execSync as execSync8 } from "child_process";
1921
+ import { execSync as execSync9 } from "child_process";
1907
1922
  import { writeFileSync as writeFileSync7 } from "fs";
1908
1923
  function initGit() {
1909
1924
  console.log("Initializing git repository...");
1910
- execSync8("git init", { stdio: "inherit" });
1925
+ execSync9("git init", { stdio: "inherit" });
1911
1926
  writeFileSync7(".gitignore", "dist\nnode_modules\n");
1912
1927
  }
1913
1928
 
1914
1929
  // src/commands/new/registerNew/newCli/initPackageJson.ts
1915
- import { execSync as execSync9 } from "child_process";
1930
+ import { execSync as execSync10 } from "child_process";
1916
1931
  function initPackageJson(name) {
1917
1932
  console.log("Initializing package.json...");
1918
- execSync9("npm init -y", { stdio: "inherit" });
1933
+ execSync10("npm init -y", { stdio: "inherit" });
1919
1934
  console.log("Configuring package.json...");
1920
- execSync9("npm pkg delete main", { stdio: "inherit" });
1921
- execSync9("npm pkg set type=module", { stdio: "inherit" });
1922
- execSync9(`npm pkg set bin.${name}=./dist/index.js`, { stdio: "inherit" });
1923
- execSync9("npm pkg set scripts.build=tsup", { stdio: "inherit" });
1924
- execSync9('npm pkg set scripts.start="node dist/index.js"', {
1935
+ execSync10("npm pkg delete main", { stdio: "inherit" });
1936
+ execSync10("npm pkg set type=module", { stdio: "inherit" });
1937
+ execSync10(`npm pkg set bin.${name}=./dist/index.js`, { stdio: "inherit" });
1938
+ execSync10("npm pkg set scripts.build=tsup", { stdio: "inherit" });
1939
+ execSync10('npm pkg set scripts.start="node dist/index.js"', {
1925
1940
  stdio: "inherit"
1926
1941
  });
1927
1942
  }
@@ -1986,8 +2001,8 @@ async function newCli() {
1986
2001
  initGit();
1987
2002
  initPackageJson(name);
1988
2003
  console.log("Installing dependencies...");
1989
- execSync10("npm install commander", { stdio: "inherit" });
1990
- execSync10("npm install -D tsup typescript @types/node", {
2004
+ execSync11("npm install commander", { stdio: "inherit" });
2005
+ execSync11("npm install -D tsup typescript @types/node", {
1991
2006
  stdio: "inherit"
1992
2007
  });
1993
2008
  writeCliTemplate(name);
@@ -1996,11 +2011,11 @@ async function newCli() {
1996
2011
  }
1997
2012
 
1998
2013
  // src/commands/new/registerNew/newProject.ts
1999
- import { execSync as execSync12 } from "child_process";
2014
+ import { execSync as execSync13 } from "child_process";
2000
2015
  import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync10 } from "fs";
2001
2016
 
2002
2017
  // src/commands/deploy/init/index.ts
2003
- import { execSync as execSync11 } from "child_process";
2018
+ import { execSync as execSync12 } from "child_process";
2004
2019
  import chalk24 from "chalk";
2005
2020
  import enquirer3 from "enquirer";
2006
2021
 
@@ -2053,7 +2068,7 @@ Created ${WORKFLOW_PATH}`));
2053
2068
  // src/commands/deploy/init/index.ts
2054
2069
  async function ensureNetlifyCli() {
2055
2070
  try {
2056
- execSync11("netlify sites:create --disable-linking", { stdio: "inherit" });
2071
+ execSync12("netlify sites:create --disable-linking", { stdio: "inherit" });
2057
2072
  } catch (error) {
2058
2073
  if (!(error instanceof Error) || !error.message.includes("command not found"))
2059
2074
  throw error;
@@ -2068,9 +2083,9 @@ async function ensureNetlifyCli() {
2068
2083
  process.exit(1);
2069
2084
  }
2070
2085
  console.log(chalk24.dim("\nInstalling netlify-cli...\n"));
2071
- execSync11("npm install -g netlify-cli", { stdio: "inherit" });
2086
+ execSync12("npm install -g netlify-cli", { stdio: "inherit" });
2072
2087
  console.log();
2073
- execSync11("netlify sites:create --disable-linking", { stdio: "inherit" });
2088
+ execSync12("netlify sites:create --disable-linking", { stdio: "inherit" });
2074
2089
  }
2075
2090
  }
2076
2091
  function printSetupInstructions() {
@@ -2113,7 +2128,7 @@ async function init5() {
2113
2128
  // src/commands/new/registerNew/newProject.ts
2114
2129
  async function newProject() {
2115
2130
  console.log("Initializing Vite with react-ts template...");
2116
- execSync12("npm create vite@latest . -- --template react-ts", {
2131
+ execSync13("npm create vite@latest . -- --template react-ts", {
2117
2132
  stdio: "inherit"
2118
2133
  });
2119
2134
  initGit();
@@ -2271,8 +2286,7 @@ async function notify() {
2271
2286
  console.log(`Notification sent: ${notification_type} for ${projectName}`);
2272
2287
  }
2273
2288
 
2274
- // src/commands/backlog/add/index.ts
2275
- import { existsSync as existsSync13 } from "fs";
2289
+ // src/commands/backlog/delete/index.ts
2276
2290
  import chalk26 from "chalk";
2277
2291
 
2278
2292
  // src/commands/backlog/shared.ts
@@ -2379,196 +2393,59 @@ function readStdin2() {
2379
2393
  });
2380
2394
  }
2381
2395
 
2382
- // src/commands/backlog/add/shared.ts
2383
- import { spawnSync } from "child_process";
2384
- import { mkdtempSync, readFileSync as readFileSync11, unlinkSync as unlinkSync2, writeFileSync as writeFileSync12 } from "fs";
2385
- import { tmpdir } from "os";
2386
- import { join as join9 } from "path";
2387
- import enquirer4 from "enquirer";
2388
- async function promptType() {
2389
- const { type } = await enquirer4.prompt({
2390
- type: "select",
2391
- name: "type",
2392
- message: "Type:",
2393
- choices: ["story", "bug"],
2394
- initial: 0
2395
- });
2396
- return type;
2397
- }
2398
- async function promptName() {
2399
- const { name } = await enquirer4.prompt({
2400
- type: "input",
2401
- name: "name",
2402
- message: "Name:",
2403
- validate: (value) => value.trim().length > 0 || "Name is required"
2404
- });
2405
- return name.trim();
2406
- }
2407
- async function promptDescription() {
2408
- const { useEditor } = await enquirer4.prompt({
2409
- type: "confirm",
2410
- name: "useEditor",
2411
- message: "Open editor for description?",
2412
- initial: false
2413
- });
2414
- if (!useEditor) {
2415
- const { description } = await enquirer4.prompt({
2416
- type: "input",
2417
- name: "description",
2418
- message: "Description (optional):"
2419
- });
2420
- return description.trim() || void 0;
2421
- }
2422
- return openEditor();
2423
- }
2424
- function openEditor() {
2425
- const editor = process.env.EDITOR || process.env.VISUAL || "vi";
2426
- const dir = mkdtempSync(join9(tmpdir(), "assist-"));
2427
- const filePath = join9(dir, "description.md");
2428
- writeFileSync12(filePath, "");
2429
- const result = spawnSync(editor, [filePath], { stdio: "inherit" });
2430
- if (result.status !== 0) {
2431
- unlinkSync2(filePath);
2432
- return void 0;
2433
- }
2434
- const content = readFileSync11(filePath, "utf-8").trim();
2435
- unlinkSync2(filePath);
2436
- return content || void 0;
2437
- }
2438
- async function promptAcceptanceCriteria() {
2439
- const criteria = [];
2440
- for (; ; ) {
2441
- const { criterion } = await enquirer4.prompt({
2442
- type: "input",
2443
- name: "criterion",
2444
- message: "Acceptance criterion (empty to finish):"
2445
- });
2446
- if (criterion.trim() === "") break;
2447
- criteria.push(criterion.trim());
2448
- }
2449
- return criteria;
2450
- }
2451
-
2452
- // src/commands/backlog/add/index.ts
2453
- var addItemSchema = backlogItemSchema.omit({ id: true, status: true });
2454
- async function addFromJson() {
2455
- if (process.stdin.isTTY) {
2456
- console.log(chalk26.red("--json requires piped input on stdin."));
2457
- return;
2458
- }
2459
- const input = await readStdin2();
2460
- const sanitised = input.replace(
2461
- /"(?:[^"\\]|\\.)*"/g,
2462
- (match) => match.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t")
2463
- );
2464
- const data = addItemSchema.parse(JSON.parse(sanitised));
2465
- const items = loadBacklog();
2466
- const id = getNextId(items);
2467
- items.push({ ...data, id, status: "todo" });
2468
- saveBacklog(items);
2469
- console.log(chalk26.green(`Added item #${id}: ${data.name}`));
2470
- }
2471
- async function addInteractive() {
2472
- const type = await promptType();
2473
- const name = await promptName();
2474
- const description = await promptDescription();
2475
- const acceptanceCriteria2 = await promptAcceptanceCriteria();
2476
- const items = loadBacklog();
2477
- const id = getNextId(items);
2478
- items.push({
2479
- id,
2480
- type,
2481
- name,
2482
- description,
2483
- acceptanceCriteria: acceptanceCriteria2,
2484
- status: "todo"
2485
- });
2486
- saveBacklog(items);
2487
- console.log(chalk26.green(`Added item #${id}: ${name}`));
2488
- }
2489
- async function add(options2) {
2490
- if (!existsSync13(getBacklogPath())) {
2491
- console.log(
2492
- chalk26.yellow(
2493
- "No backlog found. Run 'assist backlog init' to create one."
2494
- )
2495
- );
2496
- return;
2497
- }
2498
- if (options2.json) {
2499
- await addFromJson();
2500
- } else {
2501
- await addInteractive();
2502
- }
2503
- }
2504
-
2505
2396
  // src/commands/backlog/delete/index.ts
2506
- import chalk27 from "chalk";
2507
2397
  async function del(id) {
2508
2398
  const name = removeItem(id);
2509
2399
  if (name) {
2510
- console.log(chalk27.green(`Deleted item #${id}: ${name}`));
2400
+ console.log(chalk26.green(`Deleted item #${id}: ${name}`));
2511
2401
  }
2512
2402
  }
2513
2403
 
2514
2404
  // src/commands/backlog/done/index.ts
2515
- import chalk28 from "chalk";
2405
+ import chalk27 from "chalk";
2516
2406
  async function done(id) {
2517
2407
  const name = setStatus(id, "done");
2518
2408
  if (name) {
2519
- console.log(chalk28.green(`Completed item #${id}: ${name}`));
2520
- }
2521
- }
2522
-
2523
- // src/commands/backlog/init/index.ts
2524
- import { existsSync as existsSync14 } from "fs";
2525
- import chalk29 from "chalk";
2526
- async function init6() {
2527
- const backlogPath = getBacklogPath();
2528
- if (existsSync14(backlogPath)) {
2529
- console.log(chalk29.yellow("assist.backlog.yml already exists."));
2530
- return;
2409
+ console.log(chalk27.green(`Completed item #${id}: ${name}`));
2531
2410
  }
2532
- saveBacklog([]);
2533
- console.log(chalk29.green("Created assist.backlog.yml"));
2534
2411
  }
2535
2412
 
2536
- // src/commands/backlog/list/index.ts
2537
- import { existsSync as existsSync15 } from "fs";
2538
- import chalk31 from "chalk";
2413
+ // src/commands/backlog/next.ts
2414
+ import chalk33 from "chalk";
2415
+ import enquirer5 from "enquirer";
2539
2416
 
2540
2417
  // src/commands/backlog/list/shared.ts
2541
- import chalk30 from "chalk";
2418
+ import chalk28 from "chalk";
2542
2419
  function statusIcon(status2) {
2543
2420
  switch (status2) {
2544
2421
  case "todo":
2545
- return chalk30.dim("[ ]");
2422
+ return chalk28.dim("[ ]");
2546
2423
  case "in-progress":
2547
- return chalk30.yellow("[~]");
2424
+ return chalk28.yellow("[~]");
2548
2425
  case "done":
2549
- return chalk30.green("[x]");
2426
+ return chalk28.green("[x]");
2550
2427
  }
2551
2428
  }
2552
2429
  function typeLabel(type) {
2553
2430
  switch (type) {
2554
2431
  case "bug":
2555
- return chalk30.magenta("Bug");
2432
+ return chalk28.magenta("Bug");
2556
2433
  case "story":
2557
- return chalk30.cyan("Story");
2434
+ return chalk28.cyan("Story");
2558
2435
  }
2559
2436
  }
2560
2437
  function phaseLabel(item) {
2561
2438
  if (!item.plan) return "";
2562
- return chalk30.dim(
2439
+ return chalk28.dim(
2563
2440
  ` (phase ${(item.currentPhase ?? 0) + 1}/${item.plan.length})`
2564
2441
  );
2565
2442
  }
2566
2443
  function printVerboseDetails(item) {
2567
2444
  if (item.description) {
2568
- console.log(` ${chalk30.dim("Description:")} ${item.description}`);
2445
+ console.log(` ${chalk28.dim("Description:")} ${item.description}`);
2569
2446
  }
2570
2447
  if (item.acceptanceCriteria.length > 0) {
2571
- console.log(` ${chalk30.dim("Acceptance criteria:")}`);
2448
+ console.log(` ${chalk28.dim("Acceptance criteria:")}`);
2572
2449
  for (const [i, criterion] of item.acceptanceCriteria.entries()) {
2573
2450
  console.log(` ${i + 1}. ${criterion}`);
2574
2451
  }
@@ -2576,42 +2453,8 @@ function printVerboseDetails(item) {
2576
2453
  console.log();
2577
2454
  }
2578
2455
 
2579
- // src/commands/backlog/list/index.ts
2580
- function filterItems(items, options2) {
2581
- if (options2.status) return items.filter((i) => i.status === options2.status);
2582
- if (!options2.all) return items.filter((i) => i.status !== "done");
2583
- return items;
2584
- }
2585
- async function list2(options2) {
2586
- if (!existsSync15(getBacklogPath())) {
2587
- console.log(
2588
- chalk31.yellow(
2589
- "No backlog found. Run 'assist backlog init' to create one."
2590
- )
2591
- );
2592
- return;
2593
- }
2594
- const items = filterItems(loadBacklog(), options2);
2595
- if (items.length === 0) {
2596
- console.log(chalk31.dim("Backlog is empty."));
2597
- return;
2598
- }
2599
- for (const item of items) {
2600
- console.log(
2601
- `${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk31.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}`
2602
- );
2603
- if (options2.verbose) {
2604
- printVerboseDetails(item);
2605
- }
2606
- }
2607
- }
2608
-
2609
- // src/commands/backlog/next.ts
2610
- import chalk36 from "chalk";
2611
- import enquirer6 from "enquirer";
2612
-
2613
2456
  // src/commands/backlog/run.ts
2614
- import chalk35 from "chalk";
2457
+ import chalk32 from "chalk";
2615
2458
 
2616
2459
  // src/commands/backlog/buildAuthoredPhasePrompt.ts
2617
2460
  function buildAuthoredPhasePrompt(item, phaseIndex, phase) {
@@ -2711,16 +2554,16 @@ function buildReviewPhase() {
2711
2554
  }
2712
2555
 
2713
2556
  // src/commands/backlog/executePhase.ts
2714
- import chalk34 from "chalk";
2557
+ import chalk31 from "chalk";
2715
2558
 
2716
2559
  // src/commands/backlog/resolvePhaseResult.ts
2717
- import { existsSync as existsSync16, unlinkSync as unlinkSync3 } from "fs";
2718
- import chalk33 from "chalk";
2560
+ import { existsSync as existsSync13, unlinkSync as unlinkSync2 } from "fs";
2561
+ import chalk30 from "chalk";
2719
2562
 
2720
2563
  // src/commands/backlog/handleIncompletePhase.ts
2721
- import enquirer5 from "enquirer";
2564
+ import enquirer4 from "enquirer";
2722
2565
  async function handleIncompletePhase() {
2723
- const { action } = await enquirer5.prompt({
2566
+ const { action } = await enquirer4.prompt({
2724
2567
  type: "select",
2725
2568
  name: "action",
2726
2569
  message: "Phase was not marked complete. What would you like to do?",
@@ -2732,17 +2575,17 @@ async function handleIncompletePhase() {
2732
2575
  }
2733
2576
 
2734
2577
  // src/commands/backlog/phaseDone.ts
2735
- import { writeFileSync as writeFileSync13 } from "fs";
2736
- import { join as join10 } from "path";
2737
- import chalk32 from "chalk";
2578
+ import { writeFileSync as writeFileSync12 } from "fs";
2579
+ import { join as join9 } from "path";
2580
+ import chalk29 from "chalk";
2738
2581
  var PHASE_STATUS_FILE = ".assist-phase-status.json";
2739
2582
  function getPhaseStatusPath() {
2740
- return join10(process.cwd(), PHASE_STATUS_FILE);
2583
+ return join9(process.cwd(), PHASE_STATUS_FILE);
2741
2584
  }
2742
2585
  function phaseDone(id, phase) {
2743
2586
  const phaseIndex = Number.parseInt(phase, 10);
2744
2587
  const statusPath = getPhaseStatusPath();
2745
- writeFileSync13(
2588
+ writeFileSync12(
2746
2589
  statusPath,
2747
2590
  JSON.stringify({
2748
2591
  itemId: Number.parseInt(id, 10),
@@ -2751,32 +2594,36 @@ function phaseDone(id, phase) {
2751
2594
  })
2752
2595
  );
2753
2596
  setCurrentPhase(id, phaseIndex + 1);
2754
- console.log(chalk32.green(`Phase ${phase} of item #${id} marked as complete.`));
2597
+ console.log(chalk29.green(`Phase ${phase} of item #${id} marked as complete.`));
2755
2598
  }
2756
2599
 
2757
2600
  // src/commands/backlog/resolvePhaseResult.ts
2758
2601
  function cleanupMarker() {
2759
2602
  const statusPath = getPhaseStatusPath();
2760
- if (existsSync16(statusPath)) {
2761
- unlinkSync3(statusPath);
2603
+ if (existsSync13(statusPath)) {
2604
+ unlinkSync2(statusPath);
2762
2605
  }
2763
2606
  }
2764
2607
  async function resolvePhaseResult(phaseIndex) {
2765
- if (!existsSync16(getPhaseStatusPath())) {
2608
+ if (!existsSync13(getPhaseStatusPath())) {
2766
2609
  const action = await handleIncompletePhase();
2767
2610
  if (action === "abort") return -1;
2768
2611
  return action === "skip" ? 1 : 0;
2769
2612
  }
2770
2613
  cleanupMarker();
2771
- console.log(chalk33.green(`
2614
+ console.log(chalk30.green(`
2772
2615
  Phase ${phaseIndex + 1} completed.`));
2773
2616
  return 1;
2774
2617
  }
2775
2618
 
2776
2619
  // src/commands/backlog/spawnClaude.ts
2777
2620
  import { spawn as spawn3 } from "child_process";
2778
- function spawnClaude(prompt) {
2779
- const child = spawn3("claude", [prompt], {
2621
+ function spawnClaude(prompt, options2 = {}) {
2622
+ const args = [prompt];
2623
+ if (options2.allowEdits) {
2624
+ args.push("--permission-mode", "acceptEdits");
2625
+ }
2626
+ const child = spawn3("claude", args, {
2780
2627
  stdio: "inherit"
2781
2628
  });
2782
2629
  const done2 = new Promise((resolve7, reject) => {
@@ -2787,11 +2634,11 @@ function spawnClaude(prompt) {
2787
2634
  }
2788
2635
 
2789
2636
  // src/commands/backlog/watchForMarker.ts
2790
- import { existsSync as existsSync17, unwatchFile, watchFile } from "fs";
2637
+ import { existsSync as existsSync14, unwatchFile, watchFile } from "fs";
2791
2638
  function watchForMarker(child) {
2792
2639
  const statusPath = getPhaseStatusPath();
2793
2640
  watchFile(statusPath, { interval: 1e3 }, () => {
2794
- if (existsSync17(statusPath)) {
2641
+ if (existsSync14(statusPath)) {
2795
2642
  unwatchFile(statusPath);
2796
2643
  child.kill("SIGTERM");
2797
2644
  }
@@ -2802,17 +2649,18 @@ function stopWatching() {
2802
2649
  }
2803
2650
 
2804
2651
  // src/commands/backlog/executePhase.ts
2805
- async function executePhase(item, phaseIndex, phases) {
2652
+ async function executePhase(item, phaseIndex, phases, spawnOptions) {
2806
2653
  const phase = phases[phaseIndex];
2807
2654
  console.log(
2808
- chalk34.bold(
2655
+ chalk31.bold(
2809
2656
  `
2810
2657
  --- Phase ${phaseIndex + 1}/${phases.length}: ${phase.name} ---
2811
2658
  `
2812
2659
  )
2813
2660
  );
2814
2661
  const { child, done: done2 } = spawnClaude(
2815
- buildPhasePrompt(item, phaseIndex, phase)
2662
+ buildPhasePrompt(item, phaseIndex, phase),
2663
+ spawnOptions
2816
2664
  );
2817
2665
  watchForMarker(child);
2818
2666
  await done2;
@@ -2835,7 +2683,7 @@ function resolvePlan(item) {
2835
2683
  }
2836
2684
 
2837
2685
  // src/commands/backlog/run.ts
2838
- async function run2(id) {
2686
+ async function run2(id, spawnOptions) {
2839
2687
  const result = loadAndFindItem(id);
2840
2688
  if (!result) return;
2841
2689
  const { item } = result;
@@ -2844,93 +2692,98 @@ async function run2(id) {
2844
2692
  if (startPhase > plan2.length) {
2845
2693
  if (item.status !== "done") setStatus(id, "done");
2846
2694
  console.log(
2847
- chalk35.green(`All phases already complete for #${id}: ${item.name}`)
2695
+ chalk32.green(`All phases already complete for #${id}: ${item.name}`)
2848
2696
  );
2849
2697
  return;
2850
2698
  }
2851
2699
  setStatus(id, "in-progress");
2852
- console.log(chalk35.bold(`Running plan for #${id}: ${item.name}`));
2700
+ console.log(chalk32.bold(`Running plan for #${id}: ${item.name}`));
2853
2701
  if (startPhase > 0) {
2854
2702
  console.log(
2855
- chalk35.dim(`Resuming from phase ${startPhase + 1}/${plan2.length}
2703
+ chalk32.dim(`Resuming from phase ${startPhase + 1}/${plan2.length}
2856
2704
  `)
2857
2705
  );
2858
2706
  } else {
2859
- console.log(chalk35.dim(`${plan2.length} phase(s)
2707
+ console.log(chalk32.dim(`${plan2.length} phase(s)
2860
2708
  `));
2861
2709
  }
2862
2710
  let phaseIndex = startPhase;
2863
2711
  while (phaseIndex < plan2.length) {
2864
- phaseIndex = await executePhase(item, phaseIndex, plan2);
2712
+ phaseIndex = await executePhase(item, phaseIndex, plan2, spawnOptions);
2865
2713
  if (phaseIndex < 0) return;
2866
2714
  }
2867
2715
  const reviewPhase = buildReviewPhase();
2868
2716
  const allPhases = [...plan2, reviewPhase];
2869
2717
  const reviewIndex = plan2.length;
2870
- const reviewResult = await executePhase(item, reviewIndex, allPhases);
2718
+ const reviewResult = await executePhase(
2719
+ item,
2720
+ reviewIndex,
2721
+ allPhases,
2722
+ spawnOptions
2723
+ );
2871
2724
  if (reviewResult < 0) return;
2872
2725
  if (item.status !== "done") setStatus(id, "done");
2873
- console.log(chalk35.green(`
2726
+ console.log(chalk32.green(`
2874
2727
  All phases complete for #${id}: ${item.name}`));
2875
2728
  }
2876
2729
 
2877
2730
  // src/commands/backlog/next.ts
2878
- async function next() {
2731
+ async function next(options2) {
2879
2732
  const items = loadBacklog();
2880
2733
  const inProgress = items.find((i) => i.status === "in-progress" && i.plan);
2881
2734
  if (inProgress) {
2882
2735
  console.log(
2883
- chalk36.bold(
2736
+ chalk33.bold(
2884
2737
  `Resuming in-progress item #${inProgress.id}: ${inProgress.name}`
2885
2738
  )
2886
2739
  );
2887
- await run2(String(inProgress.id));
2740
+ await run2(String(inProgress.id), options2);
2888
2741
  return;
2889
2742
  }
2890
2743
  const todo = items.filter((i) => i.status === "todo");
2891
2744
  if (todo.length === 0) {
2892
- console.log(chalk36.dim("No incomplete backlog items. Opening /draft..."));
2893
- await spawnClaude("/draft");
2745
+ console.log(chalk33.dim("No incomplete backlog items. Opening /draft..."));
2746
+ await spawnClaude("/draft", options2);
2894
2747
  return;
2895
2748
  }
2896
2749
  if (todo.length === 1) {
2897
2750
  const only = todo[0];
2898
- console.log(chalk36.bold(`Starting #${only.id}: ${only.name}`));
2899
- await run2(String(only.id));
2751
+ console.log(chalk33.bold(`Starting #${only.id}: ${only.name}`));
2752
+ await run2(String(only.id), options2);
2900
2753
  return;
2901
2754
  }
2902
2755
  const choices = todo.map((i) => ({
2903
2756
  name: `${typeLabel(i.type)} #${i.id}: ${i.name}`,
2904
2757
  value: String(i.id)
2905
2758
  }));
2906
- const { selected } = await enquirer6.prompt({
2759
+ const { selected } = await enquirer5.prompt({
2907
2760
  type: "select",
2908
2761
  name: "selected",
2909
2762
  message: "Choose a backlog item to start:",
2910
2763
  choices: choices.map((c) => c.name)
2911
2764
  });
2912
2765
  const id = selected.match(/#(\d+)/)?.[1] ?? "";
2913
- await run2(id);
2766
+ await run2(id, options2);
2914
2767
  }
2915
2768
 
2916
2769
  // src/commands/backlog/plan.ts
2917
- import chalk37 from "chalk";
2770
+ import chalk34 from "chalk";
2918
2771
  function plan(id) {
2919
2772
  const result = loadAndFindItem(id);
2920
2773
  if (!result) return;
2921
2774
  const { item } = result;
2922
2775
  if (!item.plan || item.plan.length === 0) {
2923
- console.log(chalk37.dim("No plan defined for this item."));
2776
+ console.log(chalk34.dim("No plan defined for this item."));
2924
2777
  return;
2925
2778
  }
2926
- console.log(chalk37.bold(item.name));
2779
+ console.log(chalk34.bold(item.name));
2927
2780
  console.log();
2928
2781
  for (const [i, phase] of item.plan.entries()) {
2929
- console.log(`${chalk37.bold(`Phase ${i + 1}:`)} ${phase.name}`);
2782
+ console.log(`${chalk34.bold(`Phase ${i + 1}:`)} ${phase.name}`);
2930
2783
  for (const task of phase.tasks) {
2931
2784
  console.log(` - ${task.task}`);
2932
2785
  if (task.verify) {
2933
- console.log(` ${chalk37.dim(`verify: ${task.verify}`)}`);
2786
+ console.log(` ${chalk34.dim(`verify: ${task.verify}`)}`);
2934
2787
  }
2935
2788
  }
2936
2789
  console.log();
@@ -2938,23 +2791,23 @@ function plan(id) {
2938
2791
  }
2939
2792
 
2940
2793
  // src/commands/backlog/start/index.ts
2941
- import chalk38 from "chalk";
2794
+ import chalk35 from "chalk";
2942
2795
  async function start(id) {
2943
2796
  const name = setStatus(id, "in-progress");
2944
2797
  if (name) {
2945
- console.log(chalk38.green(`Started item #${id}: ${name}`));
2798
+ console.log(chalk35.green(`Started item #${id}: ${name}`));
2946
2799
  }
2947
2800
  }
2948
2801
 
2949
2802
  // src/shared/web.ts
2950
2803
  import { exec } from "child_process";
2951
- import { readFileSync as readFileSync12 } from "fs";
2804
+ import { readFileSync as readFileSync11 } from "fs";
2952
2805
  import {
2953
2806
  createServer
2954
2807
  } from "http";
2955
- import { dirname as dirname13, join as join11 } from "path";
2808
+ import { dirname as dirname13, join as join10 } from "path";
2956
2809
  import { fileURLToPath as fileURLToPath3 } from "url";
2957
- import chalk39 from "chalk";
2810
+ import chalk36 from "chalk";
2958
2811
  function respondJson(res, status2, data) {
2959
2812
  res.writeHead(status2, { "Content-Type": "application/json" });
2960
2813
  res.end(JSON.stringify(data));
@@ -2964,7 +2817,7 @@ function createBundleHandler(importMetaUrl, bundlePath) {
2964
2817
  let cache;
2965
2818
  return (_req, res) => {
2966
2819
  if (!cache) {
2967
- cache = readFileSync12(join11(dir, bundlePath), "utf-8");
2820
+ cache = readFileSync11(join10(dir, bundlePath), "utf-8");
2968
2821
  }
2969
2822
  res.writeHead(200, { "Content-Type": "application/javascript" });
2970
2823
  res.end(cache);
@@ -2998,8 +2851,8 @@ function startWebServer(label2, port, handler) {
2998
2851
  handler(req, res, port);
2999
2852
  });
3000
2853
  server.listen(port, () => {
3001
- console.log(chalk39.green(`${label2}: ${url}`));
3002
- console.log(chalk39.dim("Press Ctrl+C to stop"));
2854
+ console.log(chalk36.green(`${label2}: ${url}`));
2855
+ console.log(chalk36.dim("Press Ctrl+C to stop"));
3003
2856
  exec(`open ${url}`);
3004
2857
  });
3005
2858
  }
@@ -3146,29 +2999,210 @@ async function web(options2) {
3146
2999
  );
3147
3000
  }
3148
3001
 
3149
- // src/commands/registerBacklog.ts
3002
+ // src/commands/backlog/add/index.ts
3003
+ import { existsSync as existsSync15 } from "fs";
3004
+ import chalk37 from "chalk";
3005
+
3006
+ // src/commands/backlog/add/shared.ts
3007
+ import { spawnSync } from "child_process";
3008
+ import { mkdtempSync, readFileSync as readFileSync12, unlinkSync as unlinkSync3, writeFileSync as writeFileSync13 } from "fs";
3009
+ import { tmpdir } from "os";
3010
+ import { join as join11 } from "path";
3011
+ import enquirer6 from "enquirer";
3012
+ async function promptType() {
3013
+ const { type } = await enquirer6.prompt({
3014
+ type: "select",
3015
+ name: "type",
3016
+ message: "Type:",
3017
+ choices: ["story", "bug"],
3018
+ initial: 0
3019
+ });
3020
+ return type;
3021
+ }
3022
+ async function promptName() {
3023
+ const { name } = await enquirer6.prompt({
3024
+ type: "input",
3025
+ name: "name",
3026
+ message: "Name:",
3027
+ validate: (value) => value.trim().length > 0 || "Name is required"
3028
+ });
3029
+ return name.trim();
3030
+ }
3031
+ async function promptDescription() {
3032
+ const { useEditor } = await enquirer6.prompt({
3033
+ type: "confirm",
3034
+ name: "useEditor",
3035
+ message: "Open editor for description?",
3036
+ initial: false
3037
+ });
3038
+ if (!useEditor) {
3039
+ const { description } = await enquirer6.prompt({
3040
+ type: "input",
3041
+ name: "description",
3042
+ message: "Description (optional):"
3043
+ });
3044
+ return description.trim() || void 0;
3045
+ }
3046
+ return openEditor();
3047
+ }
3048
+ function openEditor() {
3049
+ const editor = process.env.EDITOR || process.env.VISUAL || "vi";
3050
+ const dir = mkdtempSync(join11(tmpdir(), "assist-"));
3051
+ const filePath = join11(dir, "description.md");
3052
+ writeFileSync13(filePath, "");
3053
+ const result = spawnSync(editor, [filePath], { stdio: "inherit" });
3054
+ if (result.status !== 0) {
3055
+ unlinkSync3(filePath);
3056
+ return void 0;
3057
+ }
3058
+ const content = readFileSync12(filePath, "utf-8").trim();
3059
+ unlinkSync3(filePath);
3060
+ return content || void 0;
3061
+ }
3062
+ async function promptAcceptanceCriteria() {
3063
+ const criteria = [];
3064
+ for (; ; ) {
3065
+ const { criterion } = await enquirer6.prompt({
3066
+ type: "input",
3067
+ name: "criterion",
3068
+ message: "Acceptance criterion (empty to finish):"
3069
+ });
3070
+ if (criterion.trim() === "") break;
3071
+ criteria.push(criterion.trim());
3072
+ }
3073
+ return criteria;
3074
+ }
3075
+
3076
+ // src/commands/backlog/add/index.ts
3077
+ var addItemSchema = backlogItemSchema.omit({ id: true, status: true });
3078
+ async function addFromJson() {
3079
+ if (process.stdin.isTTY) {
3080
+ console.log(chalk37.red("--json requires piped input on stdin."));
3081
+ return;
3082
+ }
3083
+ const input = await readStdin2();
3084
+ const sanitised = input.replace(
3085
+ /"(?:[^"\\]|\\.)*"/g,
3086
+ (match) => match.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t")
3087
+ );
3088
+ const data = addItemSchema.parse(JSON.parse(sanitised));
3089
+ const items = loadBacklog();
3090
+ const id = getNextId(items);
3091
+ items.push({ ...data, id, status: "todo" });
3092
+ saveBacklog(items);
3093
+ console.log(chalk37.green(`Added item #${id}: ${data.name}`));
3094
+ }
3095
+ async function addInteractive() {
3096
+ const type = await promptType();
3097
+ const name = await promptName();
3098
+ const description = await promptDescription();
3099
+ const acceptanceCriteria2 = await promptAcceptanceCriteria();
3100
+ const items = loadBacklog();
3101
+ const id = getNextId(items);
3102
+ items.push({
3103
+ id,
3104
+ type,
3105
+ name,
3106
+ description,
3107
+ acceptanceCriteria: acceptanceCriteria2,
3108
+ status: "todo"
3109
+ });
3110
+ saveBacklog(items);
3111
+ console.log(chalk37.green(`Added item #${id}: ${name}`));
3112
+ }
3113
+ async function add(options2) {
3114
+ if (!existsSync15(getBacklogPath())) {
3115
+ console.log(
3116
+ chalk37.yellow(
3117
+ "No backlog found. Run 'assist backlog init' to create one."
3118
+ )
3119
+ );
3120
+ return;
3121
+ }
3122
+ if (options2.json) {
3123
+ await addFromJson();
3124
+ } else {
3125
+ await addInteractive();
3126
+ }
3127
+ }
3128
+
3129
+ // src/commands/backlog/init/index.ts
3130
+ import { existsSync as existsSync16 } from "fs";
3131
+ import chalk38 from "chalk";
3132
+ async function init6() {
3133
+ const backlogPath = getBacklogPath();
3134
+ if (existsSync16(backlogPath)) {
3135
+ console.log(chalk38.yellow("assist.backlog.yml already exists."));
3136
+ return;
3137
+ }
3138
+ saveBacklog([]);
3139
+ console.log(chalk38.green("Created assist.backlog.yml"));
3140
+ }
3141
+
3142
+ // src/commands/backlog/list/index.ts
3143
+ import { existsSync as existsSync17 } from "fs";
3144
+ import chalk39 from "chalk";
3145
+ function filterItems(items, options2) {
3146
+ if (options2.status) return items.filter((i) => i.status === options2.status);
3147
+ if (!options2.all) return items.filter((i) => i.status !== "done");
3148
+ return items;
3149
+ }
3150
+ async function list2(options2) {
3151
+ if (!existsSync17(getBacklogPath())) {
3152
+ console.log(
3153
+ chalk39.yellow(
3154
+ "No backlog found. Run 'assist backlog init' to create one."
3155
+ )
3156
+ );
3157
+ return;
3158
+ }
3159
+ const items = filterItems(loadBacklog(), options2);
3160
+ if (items.length === 0) {
3161
+ console.log(chalk39.dim("Backlog is empty."));
3162
+ return;
3163
+ }
3164
+ for (const item of items) {
3165
+ console.log(
3166
+ `${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk39.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}`
3167
+ );
3168
+ if (options2.verbose) {
3169
+ printVerboseDetails(item);
3170
+ }
3171
+ }
3172
+ }
3173
+
3174
+ // src/commands/backlog/registerItemCommands.ts
3150
3175
  function registerItemCommands(cmd) {
3151
3176
  cmd.command("init").description("Create an empty assist.backlog.yml").action(init6);
3152
3177
  cmd.command("list").description("List all backlog items").option("--status <type>", "Filter by status (todo, in-progress, done)").option("-a, --all", "Include done items").option("-v, --verbose", "Show all item details").action(list2);
3153
3178
  cmd.command("add").description("Add a new backlog item").option("--json", "Read item as JSON from stdin").action(add);
3154
3179
  }
3180
+
3181
+ // src/commands/registerBacklog.ts
3155
3182
  function registerStatusCommands(cmd) {
3156
3183
  cmd.command("start <id>").description("Set a backlog item to in-progress").action(start);
3157
3184
  cmd.command("done <id>").description("Set a backlog item to done").action(done);
3158
3185
  cmd.command("delete <id>").alias("remove").description("Delete a backlog item").action(del);
3159
3186
  cmd.command("web").description("Start a web view of the backlog").option("-p, --port <number>", "Port to listen on", "3000").action(web);
3160
3187
  }
3161
- function registerOrchestrationCommands(cmd) {
3162
- cmd.command("next").description("Pick and run the next backlog item, or open /draft if none").action(next);
3188
+ function registerPlanCommands(cmd) {
3163
3189
  cmd.command("plan <id>").description("Display the plan for a backlog item").action(plan);
3164
3190
  cmd.command("phase-done <id> <phase>").description("Signal that a plan phase is complete").action(phaseDone);
3165
- cmd.command("run <id>").description("Run a backlog item's plan phase-by-phase with Claude").action(run2);
3191
+ }
3192
+ function registerRunCommands(cmd) {
3193
+ cmd.command("next").description("Pick and run the next backlog item, or open /draft if none").option("--allow-edits", "Run Claude with acceptEdits permission mode").action(
3194
+ (opts) => next({ allowEdits: opts.allowEdits })
3195
+ );
3196
+ cmd.command("run <id>").description("Run a backlog item's plan phase-by-phase with Claude").option("--allow-edits", "Run Claude with acceptEdits permission mode").action(
3197
+ (id, opts) => run2(id, { allowEdits: opts.allowEdits })
3198
+ );
3166
3199
  }
3167
3200
  function registerBacklog(program2) {
3168
3201
  const cmd = program2.command("backlog").description("Manage a backlog of work items").action(() => web({ port: "3000" }));
3169
3202
  registerItemCommands(cmd);
3170
3203
  registerStatusCommands(cmd);
3171
- registerOrchestrationCommands(cmd);
3204
+ registerPlanCommands(cmd);
3205
+ registerRunCommands(cmd);
3172
3206
  }
3173
3207
 
3174
3208
  // src/shared/isApprovedRead.ts
@@ -3477,7 +3511,7 @@ import { homedir as homedir4 } from "os";
3477
3511
  import { join as join13 } from "path";
3478
3512
 
3479
3513
  // src/shared/getInstallDir.ts
3480
- import { execSync as execSync13 } from "child_process";
3514
+ import { execSync as execSync14 } from "child_process";
3481
3515
  import { dirname as dirname15, resolve as resolve4 } from "path";
3482
3516
  import { fileURLToPath as fileURLToPath5 } from "url";
3483
3517
  var __filename3 = fileURLToPath5(import.meta.url);
@@ -3487,7 +3521,7 @@ function getInstallDir() {
3487
3521
  }
3488
3522
  function isGitRepo(dir) {
3489
3523
  try {
3490
- const result = execSync13("git rev-parse --show-toplevel", {
3524
+ const result = execSync14("git rev-parse --show-toplevel", {
3491
3525
  cwd: dir,
3492
3526
  stdio: "pipe"
3493
3527
  }).toString().trim();
@@ -3498,7 +3532,7 @@ function isGitRepo(dir) {
3498
3532
  }
3499
3533
 
3500
3534
  // src/commands/permitCliReads/assertCliExists.ts
3501
- import { execSync as execSync14 } from "child_process";
3535
+ import { execSync as execSync15 } from "child_process";
3502
3536
  function assertCliExists(cli) {
3503
3537
  const binary = cli.split(/\s+/)[0];
3504
3538
  const opts = {
@@ -3506,10 +3540,10 @@ function assertCliExists(cli) {
3506
3540
  stdio: ["ignore", "pipe", "pipe"]
3507
3541
  };
3508
3542
  try {
3509
- execSync14(`command -v ${binary}`, opts);
3543
+ execSync15(`command -v ${binary}`, opts);
3510
3544
  } catch {
3511
3545
  try {
3512
- execSync14(`where ${binary}`, opts);
3546
+ execSync15(`where ${binary}`, opts);
3513
3547
  } catch {
3514
3548
  console.error(`CLI "${cli}" not found in PATH`);
3515
3549
  process.exit(1);
@@ -4365,7 +4399,7 @@ function registerDeploy(program2) {
4365
4399
  }
4366
4400
 
4367
4401
  // src/commands/devlog/list/index.ts
4368
- import { execSync as execSync16 } from "child_process";
4402
+ import { execSync as execSync17 } from "child_process";
4369
4403
  import { basename as basename3 } from "path";
4370
4404
 
4371
4405
  // src/commands/devlog/loadBlogSkipDays.ts
@@ -4380,7 +4414,7 @@ function loadBlogSkipDays(repoName) {
4380
4414
  }
4381
4415
 
4382
4416
  // src/commands/devlog/shared.ts
4383
- import { execSync as execSync15 } from "child_process";
4417
+ import { execSync as execSync16 } from "child_process";
4384
4418
  import chalk48 from "chalk";
4385
4419
 
4386
4420
  // src/commands/devlog/loadDevlogEntries.ts
@@ -4450,7 +4484,7 @@ function loadAllDevlogLatestDates() {
4450
4484
  // src/commands/devlog/shared.ts
4451
4485
  function getCommitFiles(hash) {
4452
4486
  try {
4453
- const output = execSync15(`git show --name-only --format="" ${hash}`, {
4487
+ const output = execSync16(`git show --name-only --format="" ${hash}`, {
4454
4488
  encoding: "utf-8"
4455
4489
  });
4456
4490
  return output.trim().split("\n").filter(Boolean);
@@ -4521,7 +4555,7 @@ function list3(options2) {
4521
4555
  const devlogEntries = loadDevlogEntries(repoName);
4522
4556
  const reverseFlag = options2.reverse ? "--reverse " : "";
4523
4557
  const limitFlag = options2.reverse ? "" : "-n 500 ";
4524
- const output = execSync16(
4558
+ const output = execSync17(
4525
4559
  `git log ${reverseFlag}${limitFlag}--pretty=format:'%ad|%h|%s' --date=short`,
4526
4560
  { encoding: "utf-8" }
4527
4561
  );
@@ -4547,11 +4581,11 @@ function list3(options2) {
4547
4581
  }
4548
4582
 
4549
4583
  // src/commands/devlog/getLastVersionInfo.ts
4550
- import { execSync as execSync17 } from "child_process";
4584
+ import { execSync as execSync18 } from "child_process";
4551
4585
  import semver from "semver";
4552
4586
  function getVersionAtCommit(hash) {
4553
4587
  try {
4554
- const content = execSync17(`git show ${hash}:package.json`, {
4588
+ const content = execSync18(`git show ${hash}:package.json`, {
4555
4589
  encoding: "utf-8"
4556
4590
  });
4557
4591
  const pkg = JSON.parse(content);
@@ -4566,7 +4600,7 @@ function stripToMinor(version2) {
4566
4600
  }
4567
4601
  function getLastVersionInfoFromGit() {
4568
4602
  try {
4569
- const output = execSync17(
4603
+ const output = execSync18(
4570
4604
  "git log -1 --pretty=format:'%ad|%h' --date=short",
4571
4605
  {
4572
4606
  encoding: "utf-8"
@@ -4609,7 +4643,7 @@ function bumpVersion(version2, type) {
4609
4643
  }
4610
4644
 
4611
4645
  // src/commands/devlog/next/displayNextEntry/index.ts
4612
- import { execSync as execSync18 } from "child_process";
4646
+ import { execSync as execSync19 } from "child_process";
4613
4647
  import chalk51 from "chalk";
4614
4648
 
4615
4649
  // src/commands/devlog/next/displayNextEntry/displayVersion.ts
@@ -4643,7 +4677,7 @@ function findTargetDate(commitsByDate, skipDays) {
4643
4677
  return Array.from(commitsByDate.keys()).filter((d) => !skipDays.has(d)).sort()[0];
4644
4678
  }
4645
4679
  function fetchCommitsByDate(ignore2, lastDate) {
4646
- const output = execSync18(
4680
+ const output = execSync19(
4647
4681
  "git log --pretty=format:'%ad|%h|%s' --date=short -n 500",
4648
4682
  { encoding: "utf-8" }
4649
4683
  );
@@ -4721,7 +4755,7 @@ function next2(options2) {
4721
4755
  }
4722
4756
 
4723
4757
  // src/commands/devlog/repos/index.ts
4724
- import { execSync as execSync19 } from "child_process";
4758
+ import { execSync as execSync20 } from "child_process";
4725
4759
 
4726
4760
  // src/commands/devlog/repos/printReposTable.ts
4727
4761
  import chalk52 from "chalk";
@@ -4756,7 +4790,7 @@ function getStatus(lastPush, lastDevlog) {
4756
4790
  return lastDevlog < lastPush ? "outdated" : "ok";
4757
4791
  }
4758
4792
  function fetchRepos(days, all) {
4759
- const json = execSync19(
4793
+ const json = execSync20(
4760
4794
  "gh repo list staff0rd --json name,pushedAt,isArchived --limit 200",
4761
4795
  { encoding: "utf-8" }
4762
4796
  );
@@ -5116,7 +5150,7 @@ async function deps(csprojPath, options2) {
5116
5150
  }
5117
5151
 
5118
5152
  // src/commands/dotnet/getChangedCsFiles.ts
5119
- import { execSync as execSync20 } from "child_process";
5153
+ import { execSync as execSync21 } from "child_process";
5120
5154
  var SCOPE_ALL = "all";
5121
5155
  var SCOPE_BASE = "base:";
5122
5156
  var SCOPE_COMMIT = "commit:";
@@ -5140,7 +5174,7 @@ function getChangedCsFiles(scope) {
5140
5174
  } else {
5141
5175
  cmd = "git diff --name-only HEAD";
5142
5176
  }
5143
- const output = execSync20(cmd, { encoding: "utf-8" }).trim();
5177
+ const output = execSync21(cmd, { encoding: "utf-8" }).trim();
5144
5178
  if (output === "") return [];
5145
5179
  return output.split("\n").filter((f) => f.toLowerCase().endsWith(".cs"));
5146
5180
  }
@@ -5338,14 +5372,14 @@ function parseInspectReport(json) {
5338
5372
  }
5339
5373
 
5340
5374
  // src/commands/dotnet/runInspectCode.ts
5341
- import { execSync as execSync21 } from "child_process";
5375
+ import { execSync as execSync22 } from "child_process";
5342
5376
  import { existsSync as existsSync25, readFileSync as readFileSync20, unlinkSync as unlinkSync4 } from "fs";
5343
5377
  import { tmpdir as tmpdir2 } from "os";
5344
5378
  import path26 from "path";
5345
5379
  import chalk62 from "chalk";
5346
5380
  function assertJbInstalled() {
5347
5381
  try {
5348
- execSync21("jb inspectcode --version", { stdio: "pipe" });
5382
+ execSync22("jb inspectcode --version", { stdio: "pipe" });
5349
5383
  } catch {
5350
5384
  console.error(chalk62.red("jb is not installed. Install with:"));
5351
5385
  console.error(
@@ -5359,7 +5393,7 @@ function runInspectCode(slnPath, include, swea) {
5359
5393
  const includeFlag = include ? ` --include="${include}"` : "";
5360
5394
  const sweaFlag = swea ? " --swea" : "";
5361
5395
  try {
5362
- execSync21(
5396
+ execSync22(
5363
5397
  `jb inspectcode "${slnPath}" -o="${reportPath}"${includeFlag}${sweaFlag} --verbosity=OFF`,
5364
5398
  { stdio: "pipe" }
5365
5399
  );
@@ -5380,7 +5414,7 @@ function runInspectCode(slnPath, include, swea) {
5380
5414
  }
5381
5415
 
5382
5416
  // src/commands/dotnet/runRoslynInspect.ts
5383
- import { execSync as execSync22 } from "child_process";
5417
+ import { execSync as execSync23 } from "child_process";
5384
5418
  import chalk63 from "chalk";
5385
5419
  function resolveMsbuildPath() {
5386
5420
  const config = loadConfig();
@@ -5390,7 +5424,7 @@ function resolveMsbuildPath() {
5390
5424
  function assertMsbuildInstalled() {
5391
5425
  const msbuild = resolveMsbuildPath();
5392
5426
  try {
5393
- execSync22(`"${msbuild}" -version`, { stdio: "pipe" });
5427
+ execSync23(`"${msbuild}" -version`, { stdio: "pipe" });
5394
5428
  } catch {
5395
5429
  console.error(chalk63.red(`msbuild not found at: ${msbuild}`));
5396
5430
  console.error(
@@ -5416,7 +5450,7 @@ function runRoslynInspect(slnPath) {
5416
5450
  const msbuild = resolveMsbuildPath();
5417
5451
  let output;
5418
5452
  try {
5419
- output = execSync22(
5453
+ output = execSync23(
5420
5454
  `"${msbuild}" "${slnPath}" -t:Build -v:minimal -maxcpucount -p:EnforceCodeStyleInBuild=true -p:RunAnalyzersDuringBuild=true 2>&1`,
5421
5455
  { encoding: "utf-8", stdio: "pipe", maxBuffer: 50 * 1024 * 1024 }
5422
5456
  );
@@ -5548,12 +5582,12 @@ function adfToText(doc) {
5548
5582
  }
5549
5583
 
5550
5584
  // src/commands/jira/fetchIssue.ts
5551
- import { execSync as execSync23 } from "child_process";
5585
+ import { execSync as execSync24 } from "child_process";
5552
5586
  import chalk65 from "chalk";
5553
5587
  function fetchIssue(issueKey, fields) {
5554
5588
  let result;
5555
5589
  try {
5556
- result = execSync23(
5590
+ result = execSync24(
5557
5591
  `acli jira workitem view ${issueKey} -f ${fields} --json`,
5558
5592
  { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
5559
5593
  );
@@ -5599,7 +5633,7 @@ function acceptanceCriteria(issueKey) {
5599
5633
  }
5600
5634
 
5601
5635
  // src/commands/jira/jiraAuth.ts
5602
- import { execSync as execSync24 } from "child_process";
5636
+ import { execSync as execSync25 } from "child_process";
5603
5637
 
5604
5638
  // src/shared/loadJson.ts
5605
5639
  import { existsSync as existsSync26, mkdirSync as mkdirSync5, readFileSync as readFileSync21, writeFileSync as writeFileSync18 } from "fs";
@@ -5663,7 +5697,7 @@ async function jiraAuth() {
5663
5697
  console.error("All fields are required.");
5664
5698
  process.exit(1);
5665
5699
  }
5666
- execSync24(`acli jira auth login --site ${site} --email "${email}" --token`, {
5700
+ execSync25(`acli jira auth login --site ${site} --email "${email}" --token`, {
5667
5701
  encoding: "utf-8",
5668
5702
  input: token,
5669
5703
  stdio: ["pipe", "inherit", "inherit"]
@@ -5944,7 +5978,7 @@ import { tmpdir as tmpdir3 } from "os";
5944
5978
  import { join as join20 } from "path";
5945
5979
 
5946
5980
  // src/commands/prs/shared.ts
5947
- import { execSync as execSync25 } from "child_process";
5981
+ import { execSync as execSync26 } from "child_process";
5948
5982
  function isGhNotInstalled(error) {
5949
5983
  if (error instanceof Error) {
5950
5984
  const msg = error.message.toLowerCase();
@@ -5960,14 +5994,14 @@ function isNotFound(error) {
5960
5994
  }
5961
5995
  function getRepoInfo() {
5962
5996
  const repoInfo = JSON.parse(
5963
- execSync25("gh repo view --json owner,name", { encoding: "utf-8" })
5997
+ execSync26("gh repo view --json owner,name", { encoding: "utf-8" })
5964
5998
  );
5965
5999
  return { org: repoInfo.owner.login, repo: repoInfo.name };
5966
6000
  }
5967
6001
  function getCurrentPrNumber() {
5968
6002
  try {
5969
6003
  const prInfo = JSON.parse(
5970
- execSync25("gh pr view --json number", { encoding: "utf-8" })
6004
+ execSync26("gh pr view --json number", { encoding: "utf-8" })
5971
6005
  );
5972
6006
  return prInfo.number;
5973
6007
  } catch (error) {
@@ -5981,7 +6015,7 @@ function getCurrentPrNumber() {
5981
6015
  function getCurrentPrNodeId() {
5982
6016
  try {
5983
6017
  const prInfo = JSON.parse(
5984
- execSync25("gh pr view --json id", { encoding: "utf-8" })
6018
+ execSync26("gh pr view --json id", { encoding: "utf-8" })
5985
6019
  );
5986
6020
  return prInfo.id;
5987
6021
  } catch (error) {
@@ -6052,10 +6086,10 @@ function comment(path49, line, body) {
6052
6086
  }
6053
6087
 
6054
6088
  // src/commands/prs/fixed.ts
6055
- import { execSync as execSync27 } from "child_process";
6089
+ import { execSync as execSync28 } from "child_process";
6056
6090
 
6057
6091
  // src/commands/prs/resolveCommentWithReply.ts
6058
- import { execSync as execSync26 } from "child_process";
6092
+ import { execSync as execSync27 } from "child_process";
6059
6093
  import { unlinkSync as unlinkSync7, writeFileSync as writeFileSync20 } from "fs";
6060
6094
  import { tmpdir as tmpdir4 } from "os";
6061
6095
  import { join as join22 } from "path";
@@ -6085,7 +6119,7 @@ function deleteCommentsCache(prNumber) {
6085
6119
 
6086
6120
  // src/commands/prs/resolveCommentWithReply.ts
6087
6121
  function replyToComment(org, repo, prNumber, commentId, message) {
6088
- execSync26(
6122
+ execSync27(
6089
6123
  `gh api repos/${org}/${repo}/pulls/${prNumber}/comments -f body="${message.replace(/"/g, '\\"')}" -F in_reply_to=${commentId}`,
6090
6124
  { stdio: ["inherit", "pipe", "inherit"] }
6091
6125
  );
@@ -6095,7 +6129,7 @@ function resolveThread(threadId) {
6095
6129
  const queryFile = join22(tmpdir4(), `gh-mutation-${Date.now()}.graphql`);
6096
6130
  writeFileSync20(queryFile, mutation);
6097
6131
  try {
6098
- execSync26(
6132
+ execSync27(
6099
6133
  `gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
6100
6134
  { stdio: ["inherit", "pipe", "inherit"] }
6101
6135
  );
@@ -6147,7 +6181,7 @@ function resolveCommentWithReply(commentId, message) {
6147
6181
  // src/commands/prs/fixed.ts
6148
6182
  function verifySha(sha) {
6149
6183
  try {
6150
- return execSync27(`git rev-parse --verify ${sha}`, {
6184
+ return execSync28(`git rev-parse --verify ${sha}`, {
6151
6185
  encoding: "utf-8"
6152
6186
  }).trim();
6153
6187
  } catch {
@@ -6161,7 +6195,7 @@ function fixed(commentId, sha) {
6161
6195
  const { org, repo } = getRepoInfo();
6162
6196
  const repoUrl = `https://github.com/${org}/${repo}`;
6163
6197
  const message = `Fixed in [${fullSha}](${repoUrl}/commit/${fullSha})`;
6164
- execSync27("git push", { stdio: "inherit" });
6198
+ execSync28("git push", { stdio: "inherit" });
6165
6199
  resolveCommentWithReply(commentId, message);
6166
6200
  } catch (error) {
6167
6201
  if (isGhNotInstalled(error)) {
@@ -6179,7 +6213,7 @@ import { join as join24 } from "path";
6179
6213
  import { stringify } from "yaml";
6180
6214
 
6181
6215
  // src/commands/prs/fetchThreadIds.ts
6182
- import { execSync as execSync28 } from "child_process";
6216
+ import { execSync as execSync29 } from "child_process";
6183
6217
  import { unlinkSync as unlinkSync8, writeFileSync as writeFileSync21 } from "fs";
6184
6218
  import { tmpdir as tmpdir5 } from "os";
6185
6219
  import { join as join23 } from "path";
@@ -6188,7 +6222,7 @@ function fetchThreadIds(org, repo, prNumber) {
6188
6222
  const queryFile = join23(tmpdir5(), `gh-query-${Date.now()}.graphql`);
6189
6223
  writeFileSync21(queryFile, THREAD_QUERY);
6190
6224
  try {
6191
- const result = execSync28(
6225
+ const result = execSync29(
6192
6226
  `gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
6193
6227
  { encoding: "utf-8" }
6194
6228
  );
@@ -6210,9 +6244,9 @@ function fetchThreadIds(org, repo, prNumber) {
6210
6244
  }
6211
6245
 
6212
6246
  // src/commands/prs/listComments/fetchReviewComments.ts
6213
- import { execSync as execSync29 } from "child_process";
6247
+ import { execSync as execSync30 } from "child_process";
6214
6248
  function fetchJson(endpoint) {
6215
- const result = execSync29(`gh api --paginate ${endpoint}`, {
6249
+ const result = execSync30(`gh api --paginate ${endpoint}`, {
6216
6250
  encoding: "utf-8"
6217
6251
  });
6218
6252
  if (!result.trim()) return [];
@@ -6351,7 +6385,7 @@ async function listComments() {
6351
6385
  }
6352
6386
 
6353
6387
  // src/commands/prs/prs/index.ts
6354
- import { execSync as execSync30 } from "child_process";
6388
+ import { execSync as execSync31 } from "child_process";
6355
6389
 
6356
6390
  // src/commands/prs/prs/displayPaginated/index.ts
6357
6391
  import enquirer8 from "enquirer";
@@ -6457,7 +6491,7 @@ async function displayPaginated(pullRequests) {
6457
6491
  async function prs(options2) {
6458
6492
  const state = options2.open ? "open" : options2.closed ? "closed" : "all";
6459
6493
  try {
6460
- const result = execSync30(
6494
+ const result = execSync31(
6461
6495
  `gh pr list --state ${state} --json number,title,url,author,createdAt,mergedAt,closedAt,state,changedFiles --limit 100`,
6462
6496
  { encoding: "utf-8" }
6463
6497
  );
@@ -6480,7 +6514,7 @@ async function prs(options2) {
6480
6514
  }
6481
6515
 
6482
6516
  // src/commands/prs/wontfix.ts
6483
- import { execSync as execSync31 } from "child_process";
6517
+ import { execSync as execSync32 } from "child_process";
6484
6518
  function validateReason(reason) {
6485
6519
  const lowerReason = reason.toLowerCase();
6486
6520
  if (lowerReason.includes("claude") || lowerReason.includes("opus")) {
@@ -6497,7 +6531,7 @@ function validateShaReferences(reason) {
6497
6531
  const invalidShas = [];
6498
6532
  for (const sha of shas) {
6499
6533
  try {
6500
- execSync31(`git cat-file -t ${sha}`, { stdio: "pipe" });
6534
+ execSync32(`git cat-file -t ${sha}`, { stdio: "pipe" });
6501
6535
  } catch {
6502
6536
  invalidShas.push(sha);
6503
6537
  }
@@ -6611,10 +6645,10 @@ import chalk74 from "chalk";
6611
6645
  import Enquirer2 from "enquirer";
6612
6646
 
6613
6647
  // src/commands/ravendb/searchItems.ts
6614
- import { execSync as execSync32 } from "child_process";
6648
+ import { execSync as execSync33 } from "child_process";
6615
6649
  import chalk73 from "chalk";
6616
6650
  function opExec(args) {
6617
- return execSync32(`op ${args}`, {
6651
+ return execSync33(`op ${args}`, {
6618
6652
  encoding: "utf-8",
6619
6653
  stdio: ["pipe", "pipe", "pipe"]
6620
6654
  }).trim();
@@ -6766,7 +6800,7 @@ ${errorText}`
6766
6800
  }
6767
6801
 
6768
6802
  // src/commands/ravendb/resolveOpSecret.ts
6769
- import { execSync as execSync33 } from "child_process";
6803
+ import { execSync as execSync34 } from "child_process";
6770
6804
  import chalk78 from "chalk";
6771
6805
  function resolveOpSecret(reference) {
6772
6806
  if (!reference.startsWith("op://")) {
@@ -6774,7 +6808,7 @@ function resolveOpSecret(reference) {
6774
6808
  process.exit(1);
6775
6809
  }
6776
6810
  try {
6777
- return execSync33(`op read "${reference}"`, {
6811
+ return execSync34(`op read "${reference}"`, {
6778
6812
  encoding: "utf-8",
6779
6813
  stdio: ["pipe", "pipe", "pipe"]
6780
6814
  }).trim();
@@ -7023,7 +7057,7 @@ Refactor check failed:
7023
7057
  }
7024
7058
 
7025
7059
  // src/commands/refactor/check/getViolations/index.ts
7026
- import { execSync as execSync34 } from "child_process";
7060
+ import { execSync as execSync35 } from "child_process";
7027
7061
  import fs16 from "fs";
7028
7062
  import { minimatch as minimatch4 } from "minimatch";
7029
7063
 
@@ -7073,7 +7107,7 @@ function getGitFiles(options2) {
7073
7107
  }
7074
7108
  const files = /* @__PURE__ */ new Set();
7075
7109
  if (options2.staged || options2.modified) {
7076
- const staged = execSync34("git diff --cached --name-only", {
7110
+ const staged = execSync35("git diff --cached --name-only", {
7077
7111
  encoding: "utf-8"
7078
7112
  });
7079
7113
  for (const file of staged.trim().split("\n").filter(Boolean)) {
@@ -7081,7 +7115,7 @@ function getGitFiles(options2) {
7081
7115
  }
7082
7116
  }
7083
7117
  if (options2.unstaged || options2.modified) {
7084
- const unstaged = execSync34("git diff --name-only", { encoding: "utf-8" });
7118
+ const unstaged = execSync35("git diff --name-only", { encoding: "utf-8" });
7085
7119
  for (const file of unstaged.trim().split("\n").filter(Boolean)) {
7086
7120
  files.add(file);
7087
7121
  }
@@ -9376,7 +9410,7 @@ import { mkdirSync as mkdirSync10 } from "fs";
9376
9410
  import { join as join34 } from "path";
9377
9411
 
9378
9412
  // src/commands/voice/checkLockFile.ts
9379
- import { execSync as execSync35 } from "child_process";
9413
+ import { execSync as execSync36 } from "child_process";
9380
9414
  import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync26, writeFileSync as writeFileSync24 } from "fs";
9381
9415
  import { join as join33 } from "path";
9382
9416
  function isProcessAlive(pid) {
@@ -9405,7 +9439,7 @@ function bootstrapVenv() {
9405
9439
  if (existsSync35(getVenvPython())) return;
9406
9440
  console.log("Setting up Python environment...");
9407
9441
  const pythonDir = getPythonDir();
9408
- execSync35(
9442
+ execSync36(
9409
9443
  `uv sync --project "${pythonDir}" --extra runtime --no-install-project`,
9410
9444
  {
9411
9445
  stdio: "inherit",
@@ -9572,11 +9606,11 @@ import { randomBytes } from "crypto";
9572
9606
  import chalk101 from "chalk";
9573
9607
 
9574
9608
  // src/lib/openBrowser.ts
9575
- import { execSync as execSync36 } from "child_process";
9609
+ import { execSync as execSync37 } from "child_process";
9576
9610
  function tryExec(commands) {
9577
9611
  for (const cmd of commands) {
9578
9612
  try {
9579
- execSync36(cmd);
9613
+ execSync37(cmd);
9580
9614
  return true;
9581
9615
  } catch {
9582
9616
  }
@@ -9802,7 +9836,7 @@ function registerRoam(program2) {
9802
9836
  }
9803
9837
 
9804
9838
  // src/commands/run/index.ts
9805
- import { execSync as execSync37 } from "child_process";
9839
+ import { execSync as execSync38 } from "child_process";
9806
9840
 
9807
9841
  // src/commands/run/resolveParams.ts
9808
9842
  function resolveParams(params, cliArgs) {
@@ -9965,7 +9999,7 @@ function listRunConfigs() {
9965
9999
  function runPreCommands(pre) {
9966
10000
  for (const cmd of pre) {
9967
10001
  try {
9968
- execSync37(cmd, { stdio: "inherit" });
10002
+ execSync38(cmd, { stdio: "inherit" });
9969
10003
  } catch (err) {
9970
10004
  const code = err && typeof err === "object" && "status" in err ? err.status : 1;
9971
10005
  process.exit(code);
@@ -9983,7 +10017,7 @@ function run3(name, args) {
9983
10017
  }
9984
10018
 
9985
10019
  // src/commands/screenshot/index.ts
9986
- import { execSync as execSync38 } from "child_process";
10020
+ import { execSync as execSync39 } from "child_process";
9987
10021
  import { existsSync as existsSync38, mkdirSync as mkdirSync13, unlinkSync as unlinkSync10, writeFileSync as writeFileSync27 } from "fs";
9988
10022
  import { tmpdir as tmpdir6 } from "os";
9989
10023
  import { join as join38, resolve as resolve5 } from "path";
@@ -10126,7 +10160,7 @@ function runPowerShellScript(processName, outputPath) {
10126
10160
  const scriptPath = join38(tmpdir6(), `assist-screenshot-${Date.now()}.ps1`);
10127
10161
  writeFileSync27(scriptPath, captureWindowPs1, "utf-8");
10128
10162
  try {
10129
- execSync38(
10163
+ execSync39(
10130
10164
  `powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
10131
10165
  { stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }
10132
10166
  );
@@ -10325,7 +10359,7 @@ function syncCommands(claudeDir, targetBase) {
10325
10359
  }
10326
10360
 
10327
10361
  // src/commands/update.ts
10328
- import { execSync as execSync39 } from "child_process";
10362
+ import { execSync as execSync40 } from "child_process";
10329
10363
  import * as path48 from "path";
10330
10364
  function isGlobalNpmInstall(dir) {
10331
10365
  try {
@@ -10333,7 +10367,7 @@ function isGlobalNpmInstall(dir) {
10333
10367
  if (resolved.split(path48.sep).includes("node_modules")) {
10334
10368
  return true;
10335
10369
  }
10336
- const globalPrefix = execSync39("npm prefix -g", { stdio: "pipe" }).toString().trim();
10370
+ const globalPrefix = execSync40("npm prefix -g", { stdio: "pipe" }).toString().trim();
10337
10371
  return resolved.toLowerCase().startsWith(path48.resolve(globalPrefix).toLowerCase());
10338
10372
  } catch {
10339
10373
  return false;
@@ -10344,18 +10378,18 @@ async function update() {
10344
10378
  console.log(`Assist is installed at: ${installDir}`);
10345
10379
  if (isGitRepo(installDir)) {
10346
10380
  console.log("Detected git repo installation, pulling latest...");
10347
- execSync39("git pull", { cwd: installDir, stdio: "inherit" });
10381
+ execSync40("git pull", { cwd: installDir, stdio: "inherit" });
10348
10382
  console.log("Installing dependencies...");
10349
- execSync39("npm i", { cwd: installDir, stdio: "inherit" });
10383
+ execSync40("npm i", { cwd: installDir, stdio: "inherit" });
10350
10384
  console.log("Building...");
10351
- execSync39("npm run build", { cwd: installDir, stdio: "inherit" });
10385
+ execSync40("npm run build", { cwd: installDir, stdio: "inherit" });
10352
10386
  console.log("Syncing commands...");
10353
- execSync39("assist sync", { stdio: "inherit" });
10387
+ execSync40("assist sync", { stdio: "inherit" });
10354
10388
  } else if (isGlobalNpmInstall(installDir)) {
10355
10389
  console.log("Detected global npm installation, updating...");
10356
- execSync39("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
10390
+ execSync40("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
10357
10391
  console.log("Syncing commands...");
10358
- execSync39("assist sync", { stdio: "inherit" });
10392
+ execSync40("assist sync", { stdio: "inherit" });
10359
10393
  } else {
10360
10394
  console.error(
10361
10395
  "Could not determine installation method. Expected a git repo or global npm install."
@@ -10392,6 +10426,7 @@ program.command("notify").description(
10392
10426
  "Show notification from Claude Code hook (reads JSON from stdin)"
10393
10427
  ).action(notify);
10394
10428
  program.command("update").description("Update assist to the latest version and sync commands").action(update);
10429
+ program.command("coverage").description("Print global statement coverage percentage").action(coverage);
10395
10430
  program.command("screenshot").description("Capture a screenshot of a running application window").argument("<process>", "Name of the running process (e.g. notepad, code)").action(screenshot);
10396
10431
  registerCliHook(program);
10397
10432
  registerJira(program);