@staff0rd/assist 0.111.0 → 0.113.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.111.0",
9
+ version: "0.113.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -67,6 +67,7 @@ var package_default = {
67
67
  jotai: "^2.18.0",
68
68
  jscpd: "^4.0.5",
69
69
  knip: "^5.71.0",
70
+ madge: "^8.0.0",
70
71
  marked: "^15.0.12",
71
72
  react: "^19.2.4",
72
73
  "react-dom": "^19.2.4",
@@ -89,10 +90,10 @@ import { stringify as stringifyYaml } from "yaml";
89
90
  // src/shared/loadRawYaml.ts
90
91
  import { existsSync, readFileSync } from "fs";
91
92
  import { parse as parseYaml } from "yaml";
92
- function loadRawYaml(path43) {
93
- if (!existsSync(path43)) return {};
93
+ function loadRawYaml(path42) {
94
+ if (!existsSync(path42)) return {};
94
95
  try {
95
- const content = readFileSync(path43, "utf-8");
96
+ const content = readFileSync(path42, "utf-8");
96
97
  return parseYaml(content) || {};
97
98
  } catch {
98
99
  return {};
@@ -161,6 +162,17 @@ var assistConfigSchema = z.strictObject({
161
162
  news: z.strictObject({
162
163
  feeds: z.array(z.string()).default([])
163
164
  }).default({ feeds: [] }),
165
+ ravendb: z.strictObject({
166
+ connections: z.array(
167
+ z.strictObject({
168
+ name: z.string(),
169
+ url: z.string(),
170
+ database: z.string(),
171
+ apiKeyRef: z.string()
172
+ })
173
+ ).default([]),
174
+ defaultConnection: z.string().optional()
175
+ }).optional(),
164
176
  voice: z.strictObject({
165
177
  wakeWords: z.array(z.string()).default(DEFAULT_WAKE_WORDS),
166
178
  mic: z.string().optional(),
@@ -330,9 +342,9 @@ function isTraversable(value) {
330
342
  function stepInto(current, key) {
331
343
  return isTraversable(current) ? current[key] : void 0;
332
344
  }
333
- function getNestedValue(obj, path43) {
345
+ function getNestedValue(obj, path42) {
334
346
  let current = obj;
335
- for (const key of path43.split(".")) current = stepInto(current, key);
347
+ for (const key of path42.split(".")) current = stepInto(current, key);
336
348
  return current;
337
349
  }
338
350
 
@@ -373,8 +385,8 @@ function stepIntoNested(container, key, nextKey) {
373
385
  }
374
386
  return ensureObject(container, resolved);
375
387
  }
376
- function setNestedValue(obj, path43, value) {
377
- const keys = path43.split(".");
388
+ function setNestedValue(obj, path42, value) {
389
+ const keys = path42.split(".");
378
390
  const result = { ...obj };
379
391
  let current = result;
380
392
  for (let i = 0; i < keys.length - 1; i++) {
@@ -443,7 +455,7 @@ function configList() {
443
455
  }
444
456
 
445
457
  // src/commands/verify/init/index.ts
446
- import chalk16 from "chalk";
458
+ import chalk17 from "chalk";
447
459
 
448
460
  // src/shared/promptMultiselect.ts
449
461
  import chalk3 from "chalk";
@@ -513,28 +525,12 @@ function findPackageJsonWithVerifyScripts(startDir) {
513
525
  }
514
526
  }
515
527
 
516
- // src/commands/verify/setup/expectedScripts.ts
517
- var expectedScripts = {
518
- "verify:knip": "knip --no-progress --treat-config-hints-as-errors",
519
- "verify:lint": "biome check --write --error-on-warnings .",
520
- "verify:duplicate-code": "jscpd --format 'typescript,tsx' --exitCode 1 --ignore '**/*.test.*' -r consoleFull src",
521
- "verify:test": "vitest run --reporter=dot --silent",
522
- "verify:hardcoded-colors": "assist verify hardcoded-colors",
523
- "verify:no-venv": "assist verify no-venv",
524
- "verify:maintainability": "assist complexity maintainability ./src --threshold 60",
525
- "verify:madge": "madge --circular --ts-config ./tsconfig.json --extensions ts,tsx src/"
526
- };
527
-
528
- // src/commands/verify/setup/setupBuild.ts
529
- import chalk6 from "chalk";
530
-
531
528
  // src/commands/verify/installPackage.ts
532
529
  import { execSync as execSync2 } from "child_process";
533
- import * as fs2 from "fs";
534
- import * as path2 from "path";
530
+ import { writeFileSync as writeFileSync2 } from "fs";
535
531
  import chalk5 from "chalk";
536
532
  function writePackageJson(filePath, pkg) {
537
- fs2.writeFileSync(filePath, `${JSON.stringify(pkg, null, 2)}
533
+ writeFileSync2(filePath, `${JSON.stringify(pkg, null, 2)}
538
534
  `);
539
535
  }
540
536
  function addScript(pkg, name, command) {
@@ -556,29 +552,6 @@ function installPackage(name, cwd) {
556
552
  return false;
557
553
  }
558
554
  }
559
- function addToKnipIgnoreBinaries(cwd, binary) {
560
- const knipJsonPath = path2.join(cwd, "knip.json");
561
- try {
562
- let knipConfig;
563
- if (fs2.existsSync(knipJsonPath)) {
564
- knipConfig = JSON.parse(fs2.readFileSync(knipJsonPath, "utf-8"));
565
- } else {
566
- knipConfig = { $schema: "https://unpkg.com/knip@5/schema.json" };
567
- }
568
- const ignoreBinaries = knipConfig.ignoreBinaries ?? [];
569
- if (!ignoreBinaries.includes(binary)) {
570
- knipConfig.ignoreBinaries = [...ignoreBinaries, binary];
571
- fs2.writeFileSync(
572
- knipJsonPath,
573
- `${JSON.stringify(knipConfig, null, " ")}
574
- `
575
- );
576
- console.log(chalk5.dim(`Added '${binary}' to knip.json ignoreBinaries`));
577
- }
578
- } catch {
579
- console.log(chalk5.yellow("Warning: Could not update knip.json"));
580
- }
581
- }
582
555
  function setupVerifyScript(packageJsonPath, scriptName, command) {
583
556
  writePackageJson(
584
557
  packageJsonPath,
@@ -586,8 +559,43 @@ function setupVerifyScript(packageJsonPath, scriptName, command) {
586
559
  );
587
560
  }
588
561
 
562
+ // src/commands/verify/setupVerifyRunEntry.ts
563
+ var GLOBAL_COMMANDS = /* @__PURE__ */ new Set(["assist", "npm", "npx", "node"]);
564
+ function buildRunEntry(scriptName, command) {
565
+ const parts = command.split(/\s+/);
566
+ const needsNpx = !GLOBAL_COMMANDS.has(parts[0]);
567
+ const entry = {
568
+ name: scriptName,
569
+ command: needsNpx ? "npx" : parts[0]
570
+ };
571
+ const args = needsNpx ? parts : parts.slice(1);
572
+ if (args.length > 0) entry.args = args;
573
+ return entry;
574
+ }
575
+ function setupVerifyRunEntry(scriptName, command) {
576
+ const config = loadProjectConfig();
577
+ if (!config.run) config.run = [];
578
+ const runList = config.run;
579
+ if (runList.find((r) => r.name === scriptName)) return;
580
+ runList.push(buildRunEntry(scriptName, command));
581
+ saveConfig(config);
582
+ }
583
+
584
+ // src/commands/verify/setup/expectedScripts.ts
585
+ var expectedScripts = {
586
+ "verify:knip": "knip --no-progress --treat-config-hints-as-errors",
587
+ "verify:lint": "biome check --write --error-on-warnings .",
588
+ "verify:duplicate-code": "jscpd --format 'typescript,tsx' --exitCode 1 --ignore '**/*.test.*' -r consoleFull src",
589
+ "verify:test": "vitest run --reporter=dot --silent",
590
+ "verify:hardcoded-colors": "assist verify hardcoded-colors",
591
+ "verify:no-venv": "assist verify no-venv",
592
+ "verify:maintainability": "assist complexity maintainability ./src --threshold 60",
593
+ "verify:madge": "madge --circular --ts-config ./tsconfig.json --extensions ts,tsx src/"
594
+ };
595
+
589
596
  // src/commands/verify/setup/setupBuild.ts
590
- async function setupBuild(packageJsonPath, hasVite, hasTypescript) {
597
+ import chalk6 from "chalk";
598
+ async function setupBuild(_packageJsonPath, writer, hasVite, hasTypescript) {
591
599
  console.log(chalk6.blue("\nSetting up build verification..."));
592
600
  let command;
593
601
  if (hasVite && hasTypescript) {
@@ -598,82 +606,96 @@ async function setupBuild(packageJsonPath, hasVite, hasTypescript) {
598
606
  command = "npm run build";
599
607
  }
600
608
  console.log(chalk6.dim(`Using: ${command}`));
601
- const pkg = readPackageJson(packageJsonPath);
602
- writePackageJson(packageJsonPath, addScript(pkg, "verify:build", command));
609
+ writer("verify:build", command);
603
610
  }
604
- async function setupTypecheck(packageJsonPath) {
611
+ async function setupTypecheck(_packageJsonPath, writer) {
605
612
  console.log(chalk6.blue("\nSetting up typecheck verification..."));
606
613
  const command = "tsc --noEmit";
607
614
  console.log(chalk6.dim(`Using: ${command}`));
608
- const pkg = readPackageJson(packageJsonPath);
609
- writePackageJson(
610
- packageJsonPath,
611
- addScript(pkg, "verify:typecheck", command)
612
- );
615
+ writer("verify:typecheck", command);
613
616
  }
614
617
 
615
618
  // src/commands/verify/setup/setupDuplicateCode.ts
616
- import * as path3 from "path";
619
+ import * as path2 from "path";
617
620
  import chalk7 from "chalk";
618
- async function setupDuplicateCode(packageJsonPath) {
621
+ async function setupDuplicateCode(packageJsonPath, writer) {
619
622
  console.log(chalk7.blue("\nSetting up jscpd..."));
620
- const cwd = path3.dirname(packageJsonPath);
623
+ const cwd = path2.dirname(packageJsonPath);
621
624
  const pkg = readPackageJson(packageJsonPath);
622
625
  const hasJscpd = !!pkg.dependencies?.jscpd || !!pkg.devDependencies?.jscpd;
623
626
  if (!hasJscpd && !installPackage("jscpd", cwd)) {
624
627
  return;
625
628
  }
626
- setupVerifyScript(
627
- packageJsonPath,
628
- "verify:duplicate-code",
629
- expectedScripts["verify:duplicate-code"]
630
- );
629
+ writer("verify:duplicate-code", expectedScripts["verify:duplicate-code"]);
631
630
  }
632
631
 
633
632
  // src/commands/verify/setup/setupHardcodedColors.ts
634
- import * as path4 from "path";
633
+ import * as path3 from "path";
634
+ import chalk9 from "chalk";
635
+
636
+ // src/commands/verify/addToKnipIgnoreBinaries.ts
637
+ import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
638
+ import { join as join3 } from "path";
635
639
  import chalk8 from "chalk";
636
- async function setupHardcodedColors(packageJsonPath, hasOpenColor) {
637
- console.log(chalk8.blue("\nSetting up hardcoded colors check..."));
638
- const cwd = path4.dirname(packageJsonPath);
640
+ function loadKnipConfig(knipJsonPath) {
641
+ if (existsSync4(knipJsonPath)) {
642
+ return JSON.parse(readFileSync4(knipJsonPath, "utf-8"));
643
+ }
644
+ return { $schema: "https://unpkg.com/knip@5/schema.json" };
645
+ }
646
+ function addToKnipIgnoreBinaries(cwd, binary) {
647
+ const knipJsonPath = join3(cwd, "knip.json");
648
+ try {
649
+ const knipConfig = loadKnipConfig(knipJsonPath);
650
+ const ignoreBinaries = knipConfig.ignoreBinaries ?? [];
651
+ if (!ignoreBinaries.includes(binary)) {
652
+ knipConfig.ignoreBinaries = [...ignoreBinaries, binary];
653
+ writeFileSync3(
654
+ knipJsonPath,
655
+ `${JSON.stringify(knipConfig, null, " ")}
656
+ `
657
+ );
658
+ console.log(chalk8.dim(`Added '${binary}' to knip.json ignoreBinaries`));
659
+ }
660
+ } catch {
661
+ console.log(chalk8.yellow("Warning: Could not update knip.json"));
662
+ }
663
+ }
664
+
665
+ // src/commands/verify/setup/setupHardcodedColors.ts
666
+ async function setupHardcodedColors(packageJsonPath, writer, hasOpenColor) {
667
+ console.log(chalk9.blue("\nSetting up hardcoded colors check..."));
668
+ const cwd = path3.dirname(packageJsonPath);
639
669
  if (!hasOpenColor) {
640
670
  installPackage("open-color", cwd);
641
671
  }
642
672
  addToKnipIgnoreBinaries(cwd, "assist");
643
- setupVerifyScript(
644
- packageJsonPath,
645
- "verify:hardcoded-colors",
646
- expectedScripts["verify:hardcoded-colors"]
647
- );
673
+ writer("verify:hardcoded-colors", expectedScripts["verify:hardcoded-colors"]);
648
674
  }
649
675
 
650
676
  // src/commands/verify/setup/setupKnip.ts
651
- import * as path5 from "path";
652
- import chalk9 from "chalk";
653
- async function setupKnip(packageJsonPath) {
654
- console.log(chalk9.blue("\nSetting up knip..."));
655
- const cwd = path5.dirname(packageJsonPath);
677
+ import * as path4 from "path";
678
+ import chalk10 from "chalk";
679
+ async function setupKnip(packageJsonPath, writer) {
680
+ console.log(chalk10.blue("\nSetting up knip..."));
681
+ const cwd = path4.dirname(packageJsonPath);
656
682
  const pkg = readPackageJson(packageJsonPath);
657
683
  if (!pkg.devDependencies?.knip && !installPackage("knip", cwd)) {
658
684
  return;
659
685
  }
660
- setupVerifyScript(
661
- packageJsonPath,
662
- "verify:knip",
663
- expectedScripts["verify:knip"]
664
- );
686
+ writer("verify:knip", expectedScripts["verify:knip"]);
665
687
  }
666
688
 
667
689
  // src/commands/verify/setup/setupLint.ts
668
- import * as path6 from "path";
669
- import chalk12 from "chalk";
690
+ import * as path5 from "path";
691
+ import chalk13 from "chalk";
670
692
 
671
693
  // src/commands/lint/init.ts
672
694
  import { execSync as execSync4 } from "child_process";
673
- import { existsSync as existsSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
695
+ import { existsSync as existsSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
674
696
  import { dirname as dirname5, join as join4 } from "path";
675
697
  import { fileURLToPath } from "url";
676
- import chalk11 from "chalk";
698
+ import chalk12 from "chalk";
677
699
 
678
700
  // src/shared/promptConfirm.ts
679
701
  import enquirer2 from "enquirer";
@@ -694,7 +716,7 @@ async function promptConfirm(message, initial = true) {
694
716
 
695
717
  // src/shared/removeEslint/index.ts
696
718
  import { execSync as execSync3 } from "child_process";
697
- import { existsSync as existsSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
719
+ import { existsSync as existsSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
698
720
 
699
721
  // src/shared/removeEslint/removeEslintConfigFiles.ts
700
722
  import { existsSync as existsSync5, unlinkSync } from "fs";
@@ -744,7 +766,7 @@ function removeEslintFromPackageJson(options2) {
744
766
  modified = removeEslintDeps(packageJson.devDependencies) || modified;
745
767
  modified = removeEslintScripts(packageJson.scripts, options2) || modified;
746
768
  if (modified) {
747
- writeFileSync3(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
769
+ writeFileSync4(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
748
770
  `);
749
771
  console.log("Removed eslint references from package.json");
750
772
  }
@@ -775,7 +797,7 @@ function removeEslintScripts(scripts, options2) {
775
797
  }
776
798
 
777
799
  // src/utils/printDiff.ts
778
- import chalk10 from "chalk";
800
+ import chalk11 from "chalk";
779
801
  import * as diff from "diff";
780
802
  function normalizeJson(content) {
781
803
  try {
@@ -793,11 +815,11 @@ function printDiff(oldContent, newContent) {
793
815
  const lines = change.value.replace(/\n$/, "").split("\n");
794
816
  for (const line of lines) {
795
817
  if (change.added) {
796
- console.log(chalk10.green(`+ ${line}`));
818
+ console.log(chalk11.green(`+ ${line}`));
797
819
  } else if (change.removed) {
798
- console.log(chalk10.red(`- ${line}`));
820
+ console.log(chalk11.red(`- ${line}`));
799
821
  } else {
800
- console.log(chalk10.dim(` ${line}`));
822
+ console.log(chalk11.dim(` ${line}`));
801
823
  }
802
824
  }
803
825
  }
@@ -831,22 +853,22 @@ async function init() {
831
853
  console.log("biome.json already has the correct linter config");
832
854
  return;
833
855
  }
834
- console.log(chalk11.yellow("\n\u26A0\uFE0F biome.json will be updated:"));
856
+ console.log(chalk12.yellow("\n\u26A0\uFE0F biome.json will be updated:"));
835
857
  console.log();
836
858
  printDiff(oldContent, newContent);
837
- const confirm = await promptConfirm(chalk11.red("Update biome.json?"));
859
+ const confirm = await promptConfirm(chalk12.red("Update biome.json?"));
838
860
  if (!confirm) {
839
861
  console.log("Skipped biome.json update");
840
862
  return;
841
863
  }
842
- writeFileSync4(biomeConfigPath, newContent);
864
+ writeFileSync5(biomeConfigPath, newContent);
843
865
  console.log("Updated biome.json with linter config");
844
866
  }
845
867
 
846
868
  // src/commands/verify/setup/setupLint.ts
847
- async function setupLint(packageJsonPath) {
848
- console.log(chalk12.blue("\nSetting up biome..."));
849
- const cwd = path6.dirname(packageJsonPath);
869
+ async function setupLint(packageJsonPath, writer) {
870
+ console.log(chalk13.blue("\nSetting up biome..."));
871
+ const cwd = path5.dirname(packageJsonPath);
850
872
  const pkg = readPackageJson(packageJsonPath);
851
873
  if (!pkg.devDependencies?.["@biomejs/biome"]) {
852
874
  if (!installPackage("@biomejs/biome", cwd)) {
@@ -854,59 +876,43 @@ async function setupLint(packageJsonPath) {
854
876
  }
855
877
  }
856
878
  await init();
857
- setupVerifyScript(
858
- packageJsonPath,
859
- "verify:lint",
860
- expectedScripts["verify:lint"]
861
- );
879
+ writer("verify:lint", expectedScripts["verify:lint"]);
862
880
  }
863
881
 
864
882
  // src/commands/verify/setup/setupMadge.ts
865
- import * as path7 from "path";
866
- import chalk13 from "chalk";
867
- async function setupMadge(packageJsonPath) {
868
- console.log(chalk13.blue("\nSetting up madge..."));
869
- const cwd = path7.dirname(packageJsonPath);
883
+ import * as path6 from "path";
884
+ import chalk14 from "chalk";
885
+ async function setupMadge(packageJsonPath, writer) {
886
+ console.log(chalk14.blue("\nSetting up madge..."));
887
+ const cwd = path6.dirname(packageJsonPath);
870
888
  const pkg = readPackageJson(packageJsonPath);
871
889
  const hasMadge = !!pkg.dependencies?.madge || !!pkg.devDependencies?.madge;
872
890
  if (!hasMadge && !installPackage("madge", cwd)) {
873
891
  return;
874
892
  }
875
- setupVerifyScript(
876
- packageJsonPath,
877
- "verify:madge",
878
- expectedScripts["verify:madge"]
879
- );
893
+ writer("verify:madge", expectedScripts["verify:madge"]);
880
894
  }
881
895
 
882
896
  // src/commands/verify/setup/setupMaintainability.ts
883
- import * as path8 from "path";
884
- import chalk14 from "chalk";
885
- async function setupMaintainability(packageJsonPath) {
886
- console.log(chalk14.blue("\nSetting up maintainability check..."));
887
- addToKnipIgnoreBinaries(path8.dirname(packageJsonPath), "assist");
888
- setupVerifyScript(
889
- packageJsonPath,
890
- "verify:maintainability",
891
- expectedScripts["verify:maintainability"]
892
- );
897
+ import * as path7 from "path";
898
+ import chalk15 from "chalk";
899
+ async function setupMaintainability(packageJsonPath, writer) {
900
+ console.log(chalk15.blue("\nSetting up maintainability check..."));
901
+ addToKnipIgnoreBinaries(path7.dirname(packageJsonPath), "assist");
902
+ writer("verify:maintainability", expectedScripts["verify:maintainability"]);
893
903
  }
894
904
 
895
905
  // src/commands/verify/setup/setupTest.ts
896
- import * as path9 from "path";
897
- import chalk15 from "chalk";
898
- async function setupTest(packageJsonPath) {
899
- console.log(chalk15.blue("\nSetting up vitest..."));
900
- const cwd = path9.dirname(packageJsonPath);
906
+ import * as path8 from "path";
907
+ import chalk16 from "chalk";
908
+ async function setupTest(packageJsonPath, writer) {
909
+ console.log(chalk16.blue("\nSetting up vitest..."));
910
+ const cwd = path8.dirname(packageJsonPath);
901
911
  const pkg = readPackageJson(packageJsonPath);
902
912
  if (!pkg.devDependencies?.vitest && !installPackage("vitest", cwd)) {
903
913
  return;
904
914
  }
905
- setupVerifyScript(
906
- packageJsonPath,
907
- "verify:test",
908
- expectedScripts["verify:test"]
909
- );
915
+ writer("verify:test", expectedScripts["verify:test"]);
910
916
  }
911
917
 
912
918
  // src/commands/verify/init/detectExistingSetup/needsSetup.ts
@@ -924,30 +930,44 @@ function getStatusLabel(status2) {
924
930
  function hasDep(pkg, name) {
925
931
  return !!pkg.dependencies?.[name] || !!pkg.devDependencies?.[name];
926
932
  }
927
- function toolStatus(pkg, scriptName, hasPackage) {
933
+ function toolStatus(pkg, scriptName, hasPackage, configScriptNames) {
928
934
  const currentScript = pkg.scripts?.[scriptName];
935
+ const hasConfigEntry = configScriptNames.has(scriptName) || [...configScriptNames].some((n) => n.startsWith(`${scriptName}-`));
929
936
  const expectedCommand = expectedScripts[scriptName];
930
937
  return {
931
938
  hasPackage,
932
- hasScript: !!currentScript,
939
+ hasScript: !!currentScript || hasConfigEntry,
933
940
  isOutdated: !!currentScript && !!expectedCommand && currentScript !== expectedCommand
934
941
  };
935
942
  }
936
- function detectExistingSetup(pkg) {
937
- const status2 = (script, has) => toolStatus(pkg, script, has);
943
+ function loadConfigScriptNames() {
944
+ const config = loadConfig();
945
+ return new Set((config.run ?? []).map((r) => r.name));
946
+ }
947
+ function buildToolStatuses(pkg, configScriptNames) {
948
+ const status2 = (script, has) => toolStatus(pkg, script, has, configScriptNames);
938
949
  return {
939
950
  knip: status2("verify:knip", hasDep(pkg, "knip")),
940
951
  biome: status2("verify:lint", hasDep(pkg, "@biomejs/biome")),
941
952
  jscpd: status2("verify:duplicate-code", hasDep(pkg, "jscpd")),
942
953
  test: status2("verify:test", hasDep(pkg, "vitest")),
943
- hasVite: hasDep(pkg, "vite"),
944
- hasTypescript: !!pkg.devDependencies?.typescript,
945
954
  build: status2("verify:build", true),
946
955
  typecheck: status2("verify:typecheck", true),
947
956
  hardcodedColors: status2("verify:hardcoded-colors", true),
948
957
  madge: status2("verify:madge", hasDep(pkg, "madge")),
949
- maintainability: status2("verify:maintainability", true),
950
- hasOpenColor: hasDep(pkg, "open-color")
958
+ maintainability: status2("verify:maintainability", true)
959
+ };
960
+ }
961
+ function detectExistingSetup(pkg) {
962
+ const configScriptNames = loadConfigScriptNames();
963
+ return {
964
+ ...buildToolStatuses(pkg, configScriptNames),
965
+ hasVite: hasDep(pkg, "vite"),
966
+ hasTypescript: !!pkg.devDependencies?.typescript,
967
+ hasOpenColor: hasDep(pkg, "open-color"),
968
+ hasConfigScripts: [...configScriptNames].some(
969
+ (n) => n.startsWith("verify:")
970
+ )
951
971
  };
952
972
  }
953
973
 
@@ -1035,43 +1055,45 @@ function getAvailableOptions(setup2) {
1035
1055
  ).map((def) => toVerifyOption(def, setup2));
1036
1056
  }
1037
1057
 
1038
- // src/commands/verify/init/index.ts
1058
+ // src/commands/verify/init/getSetupHandlers.ts
1039
1059
  function getSetupHandlers(hasVite, hasTypescript, hasOpenColor) {
1040
1060
  return {
1041
- knip: (p) => setupKnip(p),
1042
- lint: (p) => setupLint(p),
1043
- "duplicate-code": (p) => setupDuplicateCode(p),
1044
- test: (p) => setupTest(p),
1045
- build: (p) => setupBuild(p, hasVite, hasTypescript),
1046
- typecheck: (p) => setupTypecheck(p),
1047
- "hardcoded-colors": (p) => setupHardcodedColors(p, hasOpenColor),
1048
- madge: (p) => setupMadge(p),
1049
- maintainability: (p) => setupMaintainability(p)
1061
+ knip: (p, w) => setupKnip(p, w),
1062
+ lint: (p, w) => setupLint(p, w),
1063
+ "duplicate-code": (p, w) => setupDuplicateCode(p, w),
1064
+ test: (p, w) => setupTest(p, w),
1065
+ build: (p, w) => setupBuild(p, w, hasVite, hasTypescript),
1066
+ typecheck: (p, w) => setupTypecheck(p, w),
1067
+ "hardcoded-colors": (p, w) => setupHardcodedColors(p, w, hasOpenColor),
1068
+ madge: (p, w) => setupMadge(p, w),
1069
+ maintainability: (p, w) => setupMaintainability(p, w)
1050
1070
  };
1051
1071
  }
1052
- async function runSelectedSetups(selected, packageJsonPath, handlers) {
1072
+
1073
+ // src/commands/verify/init/index.ts
1074
+ async function runSelectedSetups(selected, packageJsonPath, writer, handlers) {
1053
1075
  for (const choice of selected) {
1054
- await handlers[choice]?.(packageJsonPath);
1076
+ await handlers[choice]?.(packageJsonPath, writer);
1055
1077
  }
1056
- console.log(chalk16.green(`
1078
+ console.log(chalk17.green(`
1057
1079
  Added ${selected.length} verify script(s):`));
1058
1080
  for (const choice of selected) {
1059
- console.log(chalk16.green(` - verify:${choice}`));
1081
+ console.log(chalk17.green(` - verify:${choice}`));
1060
1082
  }
1061
- console.log(chalk16.dim("\nRun 'assist verify' to run all verify scripts"));
1083
+ console.log(chalk17.dim("\nRun 'assist verify' to run all verify scripts"));
1062
1084
  }
1063
1085
  async function promptForScripts(availableOptions) {
1064
1086
  if (availableOptions.length === 0) {
1065
- console.log(chalk16.green("All verify scripts are already configured!"));
1087
+ console.log(chalk17.green("All verify scripts are already configured!"));
1066
1088
  return null;
1067
1089
  }
1068
- console.log(chalk16.bold("Available verify scripts to add:\n"));
1090
+ console.log(chalk17.bold("Available verify scripts to add:\n"));
1069
1091
  const selected = await promptMultiselect(
1070
1092
  "Select verify scripts to add:",
1071
1093
  availableOptions
1072
1094
  );
1073
1095
  if (selected.length === 0) {
1074
- console.log(chalk16.yellow("No scripts selected"));
1096
+ console.log(chalk17.yellow("No scripts selected"));
1075
1097
  return null;
1076
1098
  }
1077
1099
  return selected;
@@ -1081,41 +1103,42 @@ async function init2() {
1081
1103
  const setup2 = detectExistingSetup(pkg);
1082
1104
  const selected = await promptForScripts(getAvailableOptions(setup2));
1083
1105
  if (!selected) return;
1106
+ const writer = setup2.hasConfigScripts ? setupVerifyRunEntry : (name, cmd) => setupVerifyScript(packageJsonPath, name, cmd);
1084
1107
  const handlers = getSetupHandlers(
1085
1108
  setup2.hasVite,
1086
1109
  setup2.hasTypescript,
1087
1110
  setup2.hasOpenColor
1088
1111
  );
1089
- await runSelectedSetups(selected, packageJsonPath, handlers);
1112
+ await runSelectedSetups(selected, packageJsonPath, writer, handlers);
1090
1113
  }
1091
1114
 
1092
1115
  // src/commands/vscode/init/index.ts
1093
- import chalk18 from "chalk";
1116
+ import chalk19 from "chalk";
1094
1117
 
1095
1118
  // src/commands/vscode/init/createLaunchJson.ts
1096
- import * as fs3 from "fs";
1097
- import * as path10 from "path";
1098
- import chalk17 from "chalk";
1119
+ import * as fs2 from "fs";
1120
+ import * as path9 from "path";
1121
+ import chalk18 from "chalk";
1099
1122
  function ensureVscodeFolder() {
1100
- const vscodeDir = path10.join(process.cwd(), ".vscode");
1101
- if (!fs3.existsSync(vscodeDir)) {
1102
- fs3.mkdirSync(vscodeDir);
1103
- console.log(chalk17.dim("Created .vscode folder"));
1123
+ const vscodeDir = path9.join(process.cwd(), ".vscode");
1124
+ if (!fs2.existsSync(vscodeDir)) {
1125
+ fs2.mkdirSync(vscodeDir);
1126
+ console.log(chalk18.dim("Created .vscode folder"));
1104
1127
  }
1105
1128
  }
1106
1129
  function removeVscodeFromGitignore() {
1107
- const gitignorePath = path10.join(process.cwd(), ".gitignore");
1108
- if (!fs3.existsSync(gitignorePath)) {
1130
+ const gitignorePath = path9.join(process.cwd(), ".gitignore");
1131
+ if (!fs2.existsSync(gitignorePath)) {
1109
1132
  return;
1110
1133
  }
1111
- const content = fs3.readFileSync(gitignorePath, "utf-8");
1134
+ const content = fs2.readFileSync(gitignorePath, "utf-8");
1112
1135
  const lines = content.split("\n");
1113
1136
  const filteredLines = lines.filter(
1114
1137
  (line) => !line.trim().toLowerCase().includes(".vscode")
1115
1138
  );
1116
1139
  if (filteredLines.length !== lines.length) {
1117
- fs3.writeFileSync(gitignorePath, filteredLines.join("\n"));
1118
- console.log(chalk17.dim("Removed .vscode references from .gitignore"));
1140
+ fs2.writeFileSync(gitignorePath, filteredLines.join("\n"));
1141
+ console.log(chalk18.dim("Removed .vscode references from .gitignore"));
1119
1142
  }
1120
1143
  }
1121
1144
  function createLaunchJson(type) {
@@ -1131,10 +1154,10 @@ function createLaunchJson(type) {
1131
1154
  }
1132
1155
  ]
1133
1156
  };
1134
- const launchPath = path10.join(process.cwd(), ".vscode", "launch.json");
1135
- fs3.writeFileSync(launchPath, `${JSON.stringify(launchConfig, null, " ")}
1157
+ const launchPath = path9.join(process.cwd(), ".vscode", "launch.json");
1158
+ fs2.writeFileSync(launchPath, `${JSON.stringify(launchConfig, null, " ")}
1136
1159
  `);
1137
- console.log(chalk17.green("Created .vscode/launch.json"));
1160
+ console.log(chalk18.green("Created .vscode/launch.json"));
1138
1161
  }
1139
1162
  function createSettingsJson() {
1140
1163
  const settings = {
@@ -1144,33 +1167,33 @@ function createSettingsJson() {
1144
1167
  "source.organizeImports.biome": "explicit"
1145
1168
  }
1146
1169
  };
1147
- const settingsPath = path10.join(process.cwd(), ".vscode", "settings.json");
1148
- fs3.writeFileSync(settingsPath, `${JSON.stringify(settings, null, " ")}
1170
+ const settingsPath = path9.join(process.cwd(), ".vscode", "settings.json");
1171
+ fs2.writeFileSync(settingsPath, `${JSON.stringify(settings, null, " ")}
1149
1172
  `);
1150
- console.log(chalk17.green("Created .vscode/settings.json"));
1173
+ console.log(chalk18.green("Created .vscode/settings.json"));
1151
1174
  }
1152
1175
  function createExtensionsJson() {
1153
1176
  const extensions = {
1154
1177
  recommendations: ["biomejs.biome"]
1155
1178
  };
1156
- const extensionsPath = path10.join(process.cwd(), ".vscode", "extensions.json");
1157
- fs3.writeFileSync(
1179
+ const extensionsPath = path9.join(process.cwd(), ".vscode", "extensions.json");
1180
+ fs2.writeFileSync(
1158
1181
  extensionsPath,
1159
1182
  `${JSON.stringify(extensions, null, " ")}
1160
1183
  `
1161
1184
  );
1162
- console.log(chalk17.green("Created .vscode/extensions.json"));
1185
+ console.log(chalk18.green("Created .vscode/extensions.json"));
1163
1186
  }
1164
1187
 
1165
1188
  // src/commands/vscode/init/detectVscodeSetup.ts
1166
- import * as fs4 from "fs";
1167
- import * as path11 from "path";
1189
+ import * as fs3 from "fs";
1190
+ import * as path10 from "path";
1168
1191
  function detectVscodeSetup(pkg) {
1169
- const vscodeDir = path11.join(process.cwd(), ".vscode");
1192
+ const vscodeDir = path10.join(process.cwd(), ".vscode");
1170
1193
  return {
1171
- hasVscodeFolder: fs4.existsSync(vscodeDir),
1172
- hasLaunchJson: fs4.existsSync(path11.join(vscodeDir, "launch.json")),
1173
- hasSettingsJson: fs4.existsSync(path11.join(vscodeDir, "settings.json")),
1194
+ hasVscodeFolder: fs3.existsSync(vscodeDir),
1195
+ hasLaunchJson: fs3.existsSync(path10.join(vscodeDir, "launch.json")),
1196
+ hasSettingsJson: fs3.existsSync(path10.join(vscodeDir, "settings.json")),
1174
1197
  hasVite: !!pkg.devDependencies?.vite || !!pkg.dependencies?.vite,
1175
1198
  hasTsup: !!pkg.devDependencies?.tsup || !!pkg.dependencies?.tsup
1176
1199
  };
@@ -1216,7 +1239,7 @@ function applySelections(selected, setup2) {
1216
1239
  for (const choice of selected) handlers[choice]?.();
1217
1240
  }
1218
1241
  async function promptForOptions(options2) {
1219
- console.log(chalk18.bold("Available VS Code configurations to add:\n"));
1242
+ console.log(chalk19.bold("Available VS Code configurations to add:\n"));
1220
1243
  return promptMultiselect("Select configurations to add:", options2);
1221
1244
  }
1222
1245
  async function init3({ all = false } = {}) {
@@ -1224,17 +1247,17 @@ async function init3({ all = false } = {}) {
1224
1247
  const setup2 = detectVscodeSetup(pkg);
1225
1248
  const options2 = getAvailableOptions2(setup2);
1226
1249
  if (options2.length === 0) {
1227
- console.log(chalk18.green("VS Code configuration already exists!"));
1250
+ console.log(chalk19.green("VS Code configuration already exists!"));
1228
1251
  return;
1229
1252
  }
1230
1253
  const selected = all ? options2.map((o) => o.value) : await promptForOptions(options2);
1231
1254
  if (selected.length === 0) {
1232
- console.log(chalk18.yellow("No configurations selected"));
1255
+ console.log(chalk19.yellow("No configurations selected"));
1233
1256
  return;
1234
1257
  }
1235
1258
  applySelections(selected, setup2);
1236
1259
  console.log(
1237
- chalk18.green(`
1260
+ chalk19.green(`
1238
1261
  Added ${selected.length} VS Code configuration(s)`)
1239
1262
  );
1240
1263
  }
@@ -1246,26 +1269,26 @@ async function init4() {
1246
1269
  }
1247
1270
 
1248
1271
  // src/commands/lint/lint/runFileNameCheck.ts
1249
- import path17 from "path";
1250
- import chalk20 from "chalk";
1272
+ import path16 from "path";
1273
+ import chalk21 from "chalk";
1251
1274
 
1252
1275
  // src/commands/lint/lint/checkFileNames.ts
1253
- import fs6 from "fs";
1254
- import path13 from "path";
1255
-
1256
- // src/shared/findSourceFiles.ts
1257
1276
  import fs5 from "fs";
1258
1277
  import path12 from "path";
1278
+
1279
+ // src/shared/findSourceFiles.ts
1280
+ import fs4 from "fs";
1281
+ import path11 from "path";
1259
1282
  var EXTENSIONS = [".ts", ".tsx"];
1260
1283
  function findSourceFiles(dir, options2 = {}) {
1261
1284
  const { includeTests = true } = options2;
1262
1285
  const results = [];
1263
- if (!fs5.existsSync(dir)) {
1286
+ if (!fs4.existsSync(dir)) {
1264
1287
  return results;
1265
1288
  }
1266
- const entries = fs5.readdirSync(dir, { withFileTypes: true });
1289
+ const entries = fs4.readdirSync(dir, { withFileTypes: true });
1267
1290
  for (const entry of entries) {
1268
- const fullPath = path12.join(dir, entry.name);
1291
+ const fullPath = path11.join(dir, entry.name);
1269
1292
  if (entry.isDirectory() && entry.name !== "node_modules") {
1270
1293
  results.push(...findSourceFiles(fullPath, options2));
1271
1294
  } else if (entry.isFile() && EXTENSIONS.some((ext) => entry.name.endsWith(ext))) {
@@ -1309,11 +1332,11 @@ function checkFileNames() {
1309
1332
  const sourceFiles = findSourceFiles("src");
1310
1333
  const violations = [];
1311
1334
  for (const filePath of sourceFiles) {
1312
- const fileName = path13.basename(filePath);
1335
+ const fileName = path12.basename(filePath);
1313
1336
  const nameWithoutExt = fileName.replace(/\.(ts|tsx)$/, "");
1314
1337
  if (/\.(stories|test)\.(ts|tsx)$/.test(fileName)) continue;
1315
1338
  if (/^[A-Z]/.test(nameWithoutExt)) {
1316
- const content = fs6.readFileSync(filePath, "utf-8");
1339
+ const content = fs5.readFileSync(filePath, "utf-8");
1317
1340
  if (!hasClassOrComponent(content) && !hasMatchingTypeExport(content, nameWithoutExt)) {
1318
1341
  violations.push({
1319
1342
  filePath,
@@ -1327,17 +1350,17 @@ function checkFileNames() {
1327
1350
  }
1328
1351
 
1329
1352
  // src/commands/lint/lint/fixFileNameViolations.ts
1330
- import chalk19 from "chalk";
1353
+ import chalk20 from "chalk";
1331
1354
 
1332
1355
  // src/commands/lint/lint/applyMoves.ts
1333
- import fs7 from "fs";
1334
- import path15 from "path";
1356
+ import fs6 from "fs";
1357
+ import path14 from "path";
1335
1358
 
1336
1359
  // src/commands/lint/lint/renameExports.ts
1337
- import path14 from "path";
1360
+ import path13 from "path";
1338
1361
  import { SyntaxKind } from "ts-morph";
1339
1362
  function nameWithoutExtension(filePath) {
1340
- return path14.basename(filePath).replace(/\.(ts|tsx)$/, "");
1363
+ return path13.basename(filePath).replace(/\.(ts|tsx)$/, "");
1341
1364
  }
1342
1365
  function renameExports(project, absSource, absDest) {
1343
1366
  const oldName = nameWithoutExtension(absSource);
@@ -1366,40 +1389,40 @@ function isCaseOnly(a, b) {
1366
1389
  }
1367
1390
  function moveCaseInsensitive(absSource, absDest) {
1368
1391
  const tmp = `${absSource}.tmp`;
1369
- fs7.renameSync(absSource, tmp);
1370
- fs7.renameSync(tmp, absDest);
1392
+ fs6.renameSync(absSource, tmp);
1393
+ fs6.renameSync(tmp, absDest);
1371
1394
  }
1372
1395
  function applyMoves(project, moves, cwd, emit) {
1373
1396
  for (const { sourcePath, destPath } of moves) {
1374
1397
  const start3 = performance.now();
1375
- const absSource = path15.resolve(sourcePath);
1376
- const absDest = path15.resolve(destPath);
1398
+ const absSource = path14.resolve(sourcePath);
1399
+ const absDest = path14.resolve(destPath);
1377
1400
  for (const r of renameExports(project, absSource, absDest)) {
1378
1401
  emit(` Renamed export ${r} in ${sourcePath}`);
1379
1402
  }
1380
1403
  const sourceFile = project.getSourceFile(absSource);
1381
1404
  if (sourceFile) sourceFile.move(absDest);
1382
1405
  const ms = (performance.now() - start3).toFixed(0);
1383
- const rel = `${path15.relative(cwd, absSource)} \u2192 ${path15.relative(cwd, absDest)}`;
1406
+ const rel = `${path14.relative(cwd, absSource)} \u2192 ${path14.relative(cwd, absDest)}`;
1384
1407
  emit(` Renamed ${rel} (${ms}ms)`);
1385
1408
  }
1386
1409
  project.saveSync();
1387
1410
  for (const { sourcePath, destPath } of moves) {
1388
- const absSource = path15.resolve(sourcePath);
1389
- const absDest = path15.resolve(destPath);
1390
- if (isCaseOnly(absSource, absDest) && fs7.existsSync(absSource)) {
1411
+ const absSource = path14.resolve(sourcePath);
1412
+ const absDest = path14.resolve(destPath);
1413
+ if (isCaseOnly(absSource, absDest) && fs6.existsSync(absSource)) {
1391
1414
  moveCaseInsensitive(absSource, absDest);
1392
1415
  }
1393
1416
  }
1394
1417
  }
1395
1418
 
1396
1419
  // src/commands/lint/lint/createLintProject.ts
1397
- import fs8 from "fs";
1398
- import path16 from "path";
1420
+ import fs7 from "fs";
1421
+ import path15 from "path";
1399
1422
  import { Project } from "ts-morph";
1400
1423
  function createLintProject() {
1401
- const tsConfigPath = path16.resolve("tsconfig.json");
1402
- const project = fs8.existsSync(tsConfigPath) ? new Project({
1424
+ const tsConfigPath = path15.resolve("tsconfig.json");
1425
+ const project = fs7.existsSync(tsConfigPath) ? new Project({
1403
1426
  tsConfigFilePath: tsConfigPath,
1404
1427
  skipAddingFilesFromTsConfig: true
1405
1428
  }) : new Project();
@@ -1412,25 +1435,25 @@ function fixFileNameViolations(moves) {
1412
1435
  const start3 = performance.now();
1413
1436
  const project = createLintProject();
1414
1437
  const cwd = process.cwd();
1415
- applyMoves(project, moves, cwd, (line) => console.log(chalk19.green(line)));
1438
+ applyMoves(project, moves, cwd, (line) => console.log(chalk20.green(line)));
1416
1439
  const ms = (performance.now() - start3).toFixed(0);
1417
- console.log(chalk19.dim(` Done in ${ms}ms`));
1440
+ console.log(chalk20.dim(` Done in ${ms}ms`));
1418
1441
  }
1419
1442
 
1420
1443
  // src/commands/lint/lint/runFileNameCheck.ts
1421
1444
  function reportViolations(violations) {
1422
- console.error(chalk20.red("\nFile name check failed:\n"));
1445
+ console.error(chalk21.red("\nFile name check failed:\n"));
1423
1446
  console.error(
1424
- chalk20.red(
1447
+ chalk21.red(
1425
1448
  " Files without classes or React components should not start with a capital letter.\n"
1426
1449
  )
1427
1450
  );
1428
1451
  for (const violation of violations) {
1429
- console.error(chalk20.red(` ${violation.filePath}`));
1430
- console.error(chalk20.gray(` Rename to: ${violation.suggestedName}
1452
+ console.error(chalk21.red(` ${violation.filePath}`));
1453
+ console.error(chalk21.gray(` Rename to: ${violation.suggestedName}
1431
1454
  `));
1432
1455
  }
1433
- console.error(chalk20.dim(" Run with -f to auto-fix.\n"));
1456
+ console.error(chalk21.dim(" Run with -f to auto-fix.\n"));
1434
1457
  }
1435
1458
  function runFileNameCheck(fix = false) {
1436
1459
  const violations = checkFileNames();
@@ -1449,27 +1472,27 @@ function runFileNameCheck(fix = false) {
1449
1472
  fixFileNameViolations(
1450
1473
  violations.map((v) => ({
1451
1474
  sourcePath: v.filePath,
1452
- destPath: path17.join(path17.dirname(v.filePath), v.suggestedName)
1475
+ destPath: path16.join(path16.dirname(v.filePath), v.suggestedName)
1453
1476
  }))
1454
1477
  );
1455
1478
  return true;
1456
1479
  }
1457
1480
 
1458
1481
  // src/commands/lint/lint/runImportExtensionCheck.ts
1459
- import fs9 from "fs";
1482
+ import fs8 from "fs";
1460
1483
 
1461
1484
  // src/commands/lint/shared.ts
1462
- import chalk21 from "chalk";
1485
+ import chalk22 from "chalk";
1463
1486
  function reportViolations2(violations, checkName, errorMessage, successMessage) {
1464
1487
  if (violations.length > 0) {
1465
- console.error(chalk21.red(`
1488
+ console.error(chalk22.red(`
1466
1489
  ${checkName} failed:
1467
1490
  `));
1468
- console.error(chalk21.red(` ${errorMessage}
1491
+ console.error(chalk22.red(` ${errorMessage}
1469
1492
  `));
1470
1493
  for (const violation of violations) {
1471
- console.error(chalk21.red(` ${violation.filePath}:${violation.line}`));
1472
- console.error(chalk21.gray(` ${violation.content}
1494
+ console.error(chalk22.red(` ${violation.filePath}:${violation.line}`));
1495
+ console.error(chalk22.gray(` ${violation.content}
1473
1496
  `));
1474
1497
  }
1475
1498
  return false;
@@ -1482,7 +1505,7 @@ ${checkName} failed:
1482
1505
 
1483
1506
  // src/commands/lint/lint/runImportExtensionCheck.ts
1484
1507
  function checkForImportExtensions(filePath) {
1485
- const content = fs9.readFileSync(filePath, "utf-8");
1508
+ const content = fs8.readFileSync(filePath, "utf-8");
1486
1509
  const lines = content.split("\n");
1487
1510
  const violations = [];
1488
1511
  const importExtensionPattern = /from\s+["']\..*\.(js|ts)["']/;
@@ -1516,9 +1539,9 @@ function runImportExtensionCheck() {
1516
1539
  }
1517
1540
 
1518
1541
  // src/commands/lint/lint/runStaticImportCheck.ts
1519
- import fs10 from "fs";
1542
+ import fs9 from "fs";
1520
1543
  function checkForDynamicImports(filePath) {
1521
- const content = fs10.readFileSync(filePath, "utf-8");
1544
+ const content = fs9.readFileSync(filePath, "utf-8");
1522
1545
  const lines = content.split("\n");
1523
1546
  const violations = [];
1524
1547
  const requirePattern = /\brequire\s*\(/;
@@ -1611,7 +1634,7 @@ Total: ${lines.length} hardcoded color(s)`);
1611
1634
  }
1612
1635
 
1613
1636
  // src/commands/verify/run/resolveEntries.ts
1614
- import * as path18 from "path";
1637
+ import * as path17 from "path";
1615
1638
  function buildFullCommand(command, args) {
1616
1639
  return [shellQuote(command), ...(args ?? []).map(shellQuote)].join(" ");
1617
1640
  }
@@ -1628,7 +1651,7 @@ function getRunEntries() {
1628
1651
  function getPackageJsonEntries() {
1629
1652
  const result = findPackageJsonWithVerifyScripts(process.cwd());
1630
1653
  if (!result) return [];
1631
- const cwd = path18.dirname(result.packageJsonPath);
1654
+ const cwd = path17.dirname(result.packageJsonPath);
1632
1655
  return result.verifyScripts.map((script) => ({
1633
1656
  name: script,
1634
1657
  fullCommand: `npm run ${script}`,
@@ -1852,11 +1875,11 @@ async function run(options2 = {}) {
1852
1875
 
1853
1876
  // src/commands/new/registerNew/initGit.ts
1854
1877
  import { execSync as execSync8 } from "child_process";
1855
- import { writeFileSync as writeFileSync6 } from "fs";
1878
+ import { writeFileSync as writeFileSync7 } from "fs";
1856
1879
  function initGit() {
1857
1880
  console.log("Initializing git repository...");
1858
1881
  execSync8("git init", { stdio: "inherit" });
1859
- writeFileSync6(".gitignore", "dist\nnode_modules\n");
1882
+ writeFileSync7(".gitignore", "dist\nnode_modules\n");
1860
1883
  }
1861
1884
 
1862
1885
  // src/commands/new/registerNew/newCli/initPackageJson.ts
@@ -1875,10 +1898,10 @@ function initPackageJson(name) {
1875
1898
  }
1876
1899
 
1877
1900
  // src/commands/new/registerNew/newCli/writeCliTemplate.ts
1878
- import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync7 } from "fs";
1901
+ import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync8 } from "fs";
1879
1902
  function writeCliTemplate(name) {
1880
1903
  console.log("Writing tsconfig.json...");
1881
- writeFileSync7(
1904
+ writeFileSync8(
1882
1905
  "tsconfig.json",
1883
1906
  JSON.stringify(
1884
1907
  {
@@ -1902,7 +1925,7 @@ function writeCliTemplate(name) {
1902
1925
  )
1903
1926
  );
1904
1927
  console.log("Writing tsup.config.ts...");
1905
- writeFileSync7(
1928
+ writeFileSync8(
1906
1929
  "tsup.config.ts",
1907
1930
  `import { defineConfig } from "tsup";
1908
1931
  export default defineConfig({
@@ -1917,7 +1940,7 @@ export default defineConfig({
1917
1940
  );
1918
1941
  console.log("Writing src/index.ts...");
1919
1942
  mkdirSync2("src", { recursive: true });
1920
- writeFileSync7(
1943
+ writeFileSync8(
1921
1944
  "src/index.ts",
1922
1945
  `#!/usr/bin/env node
1923
1946
  import { Command } from "commander";
@@ -1945,18 +1968,18 @@ async function newCli() {
1945
1968
 
1946
1969
  // src/commands/new/registerNew/newProject.ts
1947
1970
  import { execSync as execSync12 } from "child_process";
1948
- import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync9 } from "fs";
1971
+ import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync10 } from "fs";
1949
1972
 
1950
1973
  // src/commands/deploy/init/index.ts
1951
1974
  import { execSync as execSync11 } from "child_process";
1952
- import chalk23 from "chalk";
1975
+ import chalk24 from "chalk";
1953
1976
  import enquirer3 from "enquirer";
1954
1977
 
1955
1978
  // src/commands/deploy/init/updateWorkflow.ts
1956
- import { existsSync as existsSync10, mkdirSync as mkdirSync3, readFileSync as readFileSync8, writeFileSync as writeFileSync8 } from "fs";
1979
+ import { existsSync as existsSync10, mkdirSync as mkdirSync3, readFileSync as readFileSync8, writeFileSync as writeFileSync9 } from "fs";
1957
1980
  import { dirname as dirname11, join as join7 } from "path";
1958
1981
  import { fileURLToPath as fileURLToPath2 } from "url";
1959
- import chalk22 from "chalk";
1982
+ import chalk23 from "chalk";
1960
1983
  var WORKFLOW_PATH = ".github/workflows/build.yml";
1961
1984
  var __dirname3 = dirname11(fileURLToPath2(import.meta.url));
1962
1985
  function getExistingSiteId() {
@@ -1981,20 +2004,20 @@ async function updateWorkflow(siteId) {
1981
2004
  if (existsSync10(WORKFLOW_PATH)) {
1982
2005
  const oldContent = readFileSync8(WORKFLOW_PATH, "utf-8");
1983
2006
  if (oldContent === newContent) {
1984
- console.log(chalk22.green("build.yml is already up to date"));
2007
+ console.log(chalk23.green("build.yml is already up to date"));
1985
2008
  return;
1986
2009
  }
1987
- console.log(chalk22.yellow("\nbuild.yml will be updated:"));
2010
+ console.log(chalk23.yellow("\nbuild.yml will be updated:"));
1988
2011
  console.log();
1989
2012
  printDiff(oldContent, newContent);
1990
- const confirm = await promptConfirm(chalk22.red("Update build.yml?"));
2013
+ const confirm = await promptConfirm(chalk23.red("Update build.yml?"));
1991
2014
  if (!confirm) {
1992
2015
  console.log("Skipped build.yml update");
1993
2016
  return;
1994
2017
  }
1995
2018
  }
1996
- writeFileSync8(WORKFLOW_PATH, newContent);
1997
- console.log(chalk22.green(`
2019
+ writeFileSync9(WORKFLOW_PATH, newContent);
2020
+ console.log(chalk23.green(`
1998
2021
  Created ${WORKFLOW_PATH}`));
1999
2022
  }
2000
2023
 
@@ -2005,43 +2028,43 @@ async function ensureNetlifyCli() {
2005
2028
  } catch (error) {
2006
2029
  if (!(error instanceof Error) || !error.message.includes("command not found"))
2007
2030
  throw error;
2008
- console.error(chalk23.red("\nNetlify CLI is not installed.\n"));
2031
+ console.error(chalk24.red("\nNetlify CLI is not installed.\n"));
2009
2032
  const install = await promptConfirm("Would you like to install it now?");
2010
2033
  if (!install) {
2011
2034
  console.log(
2012
- chalk23.yellow(
2035
+ chalk24.yellow(
2013
2036
  "\nInstall it manually with: npm install -g netlify-cli\n"
2014
2037
  )
2015
2038
  );
2016
2039
  process.exit(1);
2017
2040
  }
2018
- console.log(chalk23.dim("\nInstalling netlify-cli...\n"));
2041
+ console.log(chalk24.dim("\nInstalling netlify-cli...\n"));
2019
2042
  execSync11("npm install -g netlify-cli", { stdio: "inherit" });
2020
2043
  console.log();
2021
2044
  execSync11("netlify sites:create --disable-linking", { stdio: "inherit" });
2022
2045
  }
2023
2046
  }
2024
2047
  function printSetupInstructions() {
2025
- console.log(chalk23.bold("\nDeployment initialized successfully!"));
2048
+ console.log(chalk24.bold("\nDeployment initialized successfully!"));
2026
2049
  console.log(
2027
- chalk23.yellow("\nTo complete setup, create a personal access token at:")
2050
+ chalk24.yellow("\nTo complete setup, create a personal access token at:")
2028
2051
  );
2029
2052
  console.log(
2030
- chalk23.cyan(
2053
+ chalk24.cyan(
2031
2054
  "https://app.netlify.com/user/applications#personal-access-tokens"
2032
2055
  )
2033
2056
  );
2034
2057
  console.log(
2035
- chalk23.yellow(
2058
+ chalk24.yellow(
2036
2059
  "\nThen add it as NETLIFY_AUTH_TOKEN in your GitHub repository secrets."
2037
2060
  )
2038
2061
  );
2039
2062
  }
2040
2063
  async function init5() {
2041
- console.log(chalk23.bold("Initializing Netlify deployment...\n"));
2064
+ console.log(chalk24.bold("Initializing Netlify deployment...\n"));
2042
2065
  const existingSiteId = getExistingSiteId();
2043
2066
  if (existingSiteId) {
2044
- console.log(chalk23.dim(`Using existing site ID: ${existingSiteId}
2067
+ console.log(chalk24.dim(`Using existing site ID: ${existingSiteId}
2045
2068
  `));
2046
2069
  await updateWorkflow(existingSiteId);
2047
2070
  return;
@@ -2087,7 +2110,7 @@ function addViteBaseConfig() {
2087
2110
  'defineConfig({\n base: "./",'
2088
2111
  );
2089
2112
  if (updated !== content) {
2090
- writeFileSync9(viteConfigPath, updated);
2113
+ writeFileSync10(viteConfigPath, updated);
2091
2114
  console.log('Added base: "./" to vite.config.ts');
2092
2115
  }
2093
2116
  }
@@ -2135,19 +2158,19 @@ function detectPlatform() {
2135
2158
 
2136
2159
  // src/commands/notify/showNotification/showWindowsNotificationFromWsl.ts
2137
2160
  import { spawn as spawn2 } from "child_process";
2138
- import fs11 from "fs";
2161
+ import fs10 from "fs";
2139
2162
  import { createRequire } from "module";
2140
- import path19 from "path";
2163
+ import path18 from "path";
2141
2164
  var require2 = createRequire(import.meta.url);
2142
2165
  function getSnoreToastPath() {
2143
- const notifierPath = path19.dirname(require2.resolve("node-notifier"));
2144
- return path19.join(notifierPath, "vendor", "snoreToast", "snoretoast-x64.exe");
2166
+ const notifierPath = path18.dirname(require2.resolve("node-notifier"));
2167
+ return path18.join(notifierPath, "vendor", "snoreToast", "snoretoast-x64.exe");
2145
2168
  }
2146
2169
  function showWindowsNotificationFromWsl(options2) {
2147
2170
  const { title, message, sound } = options2;
2148
2171
  const snoreToastPath = getSnoreToastPath();
2149
2172
  try {
2150
- fs11.chmodSync(snoreToastPath, 493);
2173
+ fs10.chmodSync(snoreToastPath, 493);
2151
2174
  } catch {
2152
2175
  }
2153
2176
  const args = ["-t", title, "-m", message];
@@ -2221,12 +2244,12 @@ async function notify() {
2221
2244
 
2222
2245
  // src/commands/backlog/add/index.ts
2223
2246
  import { existsSync as existsSync13 } from "fs";
2224
- import chalk25 from "chalk";
2247
+ import chalk26 from "chalk";
2225
2248
 
2226
2249
  // src/commands/backlog/shared.ts
2227
- import { existsSync as existsSync12, readFileSync as readFileSync10, writeFileSync as writeFileSync10 } from "fs";
2250
+ import { existsSync as existsSync12, readFileSync as readFileSync10, writeFileSync as writeFileSync11 } from "fs";
2228
2251
  import { join as join8 } from "path";
2229
- import chalk24 from "chalk";
2252
+ import chalk25 from "chalk";
2230
2253
  import { parse as parseYaml2, stringify as stringifyYaml3 } from "yaml";
2231
2254
 
2232
2255
  // src/commands/backlog/types.ts
@@ -2262,7 +2285,7 @@ function loadBacklog() {
2262
2285
  }
2263
2286
  function saveBacklog(items) {
2264
2287
  const backlogPath = getBacklogPath();
2265
- writeFileSync10(backlogPath, stringifyYaml3(items, { lineWidth: 0 }));
2288
+ writeFileSync11(backlogPath, stringifyYaml3(items, { lineWidth: 0 }));
2266
2289
  }
2267
2290
  function findItem(items, id) {
2268
2291
  return items.find((item) => item.id === id);
@@ -2270,7 +2293,7 @@ function findItem(items, id) {
2270
2293
  function loadAndFindItem(id) {
2271
2294
  if (!existsSync12(getBacklogPath())) {
2272
2295
  console.log(
2273
- chalk24.yellow(
2296
+ chalk25.yellow(
2274
2297
  "No backlog found. Run 'assist backlog init' to create one."
2275
2298
  )
2276
2299
  );
@@ -2279,7 +2302,7 @@ function loadAndFindItem(id) {
2279
2302
  const items = loadBacklog();
2280
2303
  const item = findItem(items, Number.parseInt(id, 10));
2281
2304
  if (!item) {
2282
- console.log(chalk24.red(`Item #${id} not found.`));
2305
+ console.log(chalk25.red(`Item #${id} not found.`));
2283
2306
  return void 0;
2284
2307
  }
2285
2308
  return { items, item };
@@ -2304,7 +2327,7 @@ function getNextId(items) {
2304
2327
 
2305
2328
  // src/commands/backlog/add/shared.ts
2306
2329
  import { spawnSync } from "child_process";
2307
- import { mkdtempSync, readFileSync as readFileSync11, unlinkSync as unlinkSync2, writeFileSync as writeFileSync11 } from "fs";
2330
+ import { mkdtempSync, readFileSync as readFileSync11, unlinkSync as unlinkSync2, writeFileSync as writeFileSync12 } from "fs";
2308
2331
  import { tmpdir } from "os";
2309
2332
  import { join as join9 } from "path";
2310
2333
  import enquirer4 from "enquirer";
@@ -2348,7 +2371,7 @@ function openEditor() {
2348
2371
  const editor = process.env.EDITOR || process.env.VISUAL || "vi";
2349
2372
  const dir = mkdtempSync(join9(tmpdir(), "assist-"));
2350
2373
  const filePath = join9(dir, "description.md");
2351
- writeFileSync11(filePath, "");
2374
+ writeFileSync12(filePath, "");
2352
2375
  const result = spawnSync(editor, [filePath], { stdio: "inherit" });
2353
2376
  if (result.status !== 0) {
2354
2377
  unlinkSync2(filePath);
@@ -2377,7 +2400,7 @@ async function add() {
2377
2400
  const backlogPath = getBacklogPath();
2378
2401
  if (!existsSync13(backlogPath)) {
2379
2402
  console.log(
2380
- chalk25.yellow(
2403
+ chalk26.yellow(
2381
2404
  "No backlog found. Run 'assist backlog init' to create one."
2382
2405
  )
2383
2406
  );
@@ -2398,67 +2421,67 @@ async function add() {
2398
2421
  status: "todo"
2399
2422
  });
2400
2423
  saveBacklog(items);
2401
- console.log(chalk25.green(`Added item #${id}: ${name}`));
2424
+ console.log(chalk26.green(`Added item #${id}: ${name}`));
2402
2425
  }
2403
2426
 
2404
2427
  // src/commands/backlog/delete/index.ts
2405
- import chalk26 from "chalk";
2428
+ import chalk27 from "chalk";
2406
2429
  async function del(id) {
2407
2430
  const name = removeItem(id);
2408
2431
  if (name) {
2409
- console.log(chalk26.green(`Deleted item #${id}: ${name}`));
2432
+ console.log(chalk27.green(`Deleted item #${id}: ${name}`));
2410
2433
  }
2411
2434
  }
2412
2435
 
2413
2436
  // src/commands/backlog/done/index.ts
2414
- import chalk27 from "chalk";
2437
+ import chalk28 from "chalk";
2415
2438
  async function done(id) {
2416
2439
  const name = setStatus(id, "done");
2417
2440
  if (name) {
2418
- console.log(chalk27.green(`Completed item #${id}: ${name}`));
2441
+ console.log(chalk28.green(`Completed item #${id}: ${name}`));
2419
2442
  }
2420
2443
  }
2421
2444
 
2422
2445
  // src/commands/backlog/init/index.ts
2423
2446
  import { existsSync as existsSync14 } from "fs";
2424
- import chalk28 from "chalk";
2447
+ import chalk29 from "chalk";
2425
2448
  async function init6() {
2426
2449
  const backlogPath = getBacklogPath();
2427
2450
  if (existsSync14(backlogPath)) {
2428
- console.log(chalk28.yellow("assist.backlog.yml already exists."));
2451
+ console.log(chalk29.yellow("assist.backlog.yml already exists."));
2429
2452
  return;
2430
2453
  }
2431
2454
  saveBacklog([]);
2432
- console.log(chalk28.green("Created assist.backlog.yml"));
2455
+ console.log(chalk29.green("Created assist.backlog.yml"));
2433
2456
  }
2434
2457
 
2435
2458
  // src/commands/backlog/list/index.ts
2436
2459
  import { existsSync as existsSync15 } from "fs";
2437
- import chalk29 from "chalk";
2460
+ import chalk30 from "chalk";
2438
2461
  function statusIcon(status2) {
2439
2462
  switch (status2) {
2440
2463
  case "todo":
2441
- return chalk29.dim("[ ]");
2464
+ return chalk30.dim("[ ]");
2442
2465
  case "in-progress":
2443
- return chalk29.yellow("[~]");
2466
+ return chalk30.yellow("[~]");
2444
2467
  case "done":
2445
- return chalk29.green("[x]");
2468
+ return chalk30.green("[x]");
2446
2469
  }
2447
2470
  }
2448
2471
  function typeLabel(type) {
2449
2472
  switch (type) {
2450
2473
  case "bug":
2451
- return chalk29.magenta("Bug");
2474
+ return chalk30.magenta("Bug");
2452
2475
  case "story":
2453
- return chalk29.cyan("Story");
2476
+ return chalk30.cyan("Story");
2454
2477
  }
2455
2478
  }
2456
2479
  function printVerboseDetails(item) {
2457
2480
  if (item.description) {
2458
- console.log(` ${chalk29.dim("Description:")} ${item.description}`);
2481
+ console.log(` ${chalk30.dim("Description:")} ${item.description}`);
2459
2482
  }
2460
2483
  if (item.acceptanceCriteria.length > 0) {
2461
- console.log(` ${chalk29.dim("Acceptance criteria:")}`);
2484
+ console.log(` ${chalk30.dim("Acceptance criteria:")}`);
2462
2485
  for (const criterion of item.acceptanceCriteria) {
2463
2486
  console.log(` - ${criterion}`);
2464
2487
  }
@@ -2474,7 +2497,7 @@ async function list2(options2) {
2474
2497
  const backlogPath = getBacklogPath();
2475
2498
  if (!existsSync15(backlogPath)) {
2476
2499
  console.log(
2477
- chalk29.yellow(
2500
+ chalk30.yellow(
2478
2501
  "No backlog found. Run 'assist backlog init' to create one."
2479
2502
  )
2480
2503
  );
@@ -2482,12 +2505,12 @@ async function list2(options2) {
2482
2505
  }
2483
2506
  const items = filterItems(loadBacklog(), options2);
2484
2507
  if (items.length === 0) {
2485
- console.log(chalk29.dim("Backlog is empty."));
2508
+ console.log(chalk30.dim("Backlog is empty."));
2486
2509
  return;
2487
2510
  }
2488
2511
  for (const item of items) {
2489
2512
  console.log(
2490
- `${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk29.dim(`#${item.id}`)} ${item.name}`
2513
+ `${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk30.dim(`#${item.id}`)} ${item.name}`
2491
2514
  );
2492
2515
  if (options2.verbose) {
2493
2516
  printVerboseDetails(item);
@@ -2496,11 +2519,11 @@ async function list2(options2) {
2496
2519
  }
2497
2520
 
2498
2521
  // src/commands/backlog/start/index.ts
2499
- import chalk30 from "chalk";
2522
+ import chalk31 from "chalk";
2500
2523
  async function start(id) {
2501
2524
  const name = setStatus(id, "in-progress");
2502
2525
  if (name) {
2503
- console.log(chalk30.green(`Started item #${id}: ${name}`));
2526
+ console.log(chalk31.green(`Started item #${id}: ${name}`));
2504
2527
  }
2505
2528
  }
2506
2529
 
@@ -2512,7 +2535,7 @@ import {
2512
2535
  } from "http";
2513
2536
  import { dirname as dirname12, join as join10 } from "path";
2514
2537
  import { fileURLToPath as fileURLToPath3 } from "url";
2515
- import chalk31 from "chalk";
2538
+ import chalk32 from "chalk";
2516
2539
  function respondJson(res, status2, data) {
2517
2540
  res.writeHead(status2, { "Content-Type": "application/json" });
2518
2541
  res.end(JSON.stringify(data));
@@ -2556,8 +2579,8 @@ function startWebServer(label2, port, handler) {
2556
2579
  handler(req, res, port);
2557
2580
  });
2558
2581
  server.listen(port, () => {
2559
- console.log(chalk31.green(`${label2}: ${url}`));
2560
- console.log(chalk31.dim("Press Ctrl+C to stop"));
2582
+ console.log(chalk32.green(`${label2}: ${url}`));
2583
+ console.log(chalk32.dim("Press Ctrl+C to stop"));
2561
2584
  exec(`open ${url}`);
2562
2585
  });
2563
2586
  }
@@ -2786,7 +2809,7 @@ function extractGraphqlQuery(args) {
2786
2809
  }
2787
2810
 
2788
2811
  // src/shared/loadCliReads.ts
2789
- import { existsSync as existsSync16, readFileSync as readFileSync13, writeFileSync as writeFileSync12 } from "fs";
2812
+ import { existsSync as existsSync16, readFileSync as readFileSync13, writeFileSync as writeFileSync13 } from "fs";
2790
2813
  import { dirname as dirname13, resolve as resolve2 } from "path";
2791
2814
  import { fileURLToPath as fileURLToPath4 } from "url";
2792
2815
  var __filename2 = fileURLToPath4(import.meta.url);
@@ -2797,19 +2820,19 @@ function getCliReadsPath() {
2797
2820
  var cachedLines;
2798
2821
  function getCliReadsLines() {
2799
2822
  if (cachedLines) return cachedLines;
2800
- const path43 = getCliReadsPath();
2801
- if (!existsSync16(path43)) {
2823
+ const path42 = getCliReadsPath();
2824
+ if (!existsSync16(path42)) {
2802
2825
  cachedLines = [];
2803
2826
  return cachedLines;
2804
2827
  }
2805
- cachedLines = readFileSync13(path43, "utf-8").split("\n").filter((line) => line.trim() !== "");
2828
+ cachedLines = readFileSync13(path42, "utf-8").split("\n").filter((line) => line.trim() !== "");
2806
2829
  return cachedLines;
2807
2830
  }
2808
2831
  function loadCliReads() {
2809
2832
  return getCliReadsLines();
2810
2833
  }
2811
2834
  function saveCliReads(commands) {
2812
- writeFileSync12(getCliReadsPath(), `${commands.join("\n")}
2835
+ writeFileSync13(getCliReadsPath(), `${commands.join("\n")}
2813
2836
  `);
2814
2837
  cachedLines = void 0;
2815
2838
  }
@@ -3002,7 +3025,7 @@ ${reasons.join("\n")}`);
3002
3025
  }
3003
3026
 
3004
3027
  // src/commands/permitCliReads/index.ts
3005
- import { existsSync as existsSync18, mkdirSync as mkdirSync4, readFileSync as readFileSync15, writeFileSync as writeFileSync13 } from "fs";
3028
+ import { existsSync as existsSync18, mkdirSync as mkdirSync4, readFileSync as readFileSync15, writeFileSync as writeFileSync14 } from "fs";
3006
3029
  import { homedir as homedir4 } from "os";
3007
3030
  import { join as join12 } from "path";
3008
3031
 
@@ -3048,11 +3071,11 @@ function assertCliExists(cli) {
3048
3071
  }
3049
3072
 
3050
3073
  // src/commands/permitCliReads/colorize.ts
3051
- import chalk32 from "chalk";
3074
+ import chalk33 from "chalk";
3052
3075
  function colorize(plainOutput) {
3053
3076
  return plainOutput.split("\n").map((line) => {
3054
- if (line.startsWith(" R ")) return chalk32.green(line);
3055
- if (line.startsWith(" W ")) return chalk32.red(line);
3077
+ if (line.startsWith(" R ")) return chalk33.green(line);
3078
+ if (line.startsWith(" W ")) return chalk33.red(line);
3056
3079
  return line;
3057
3080
  }).join("\n");
3058
3081
  }
@@ -3154,14 +3177,14 @@ function showProgress(p, label2) {
3154
3177
  const pct = Math.round(p.done / p.total * 100);
3155
3178
  process.stderr.write(`\r\x1B[K[${pct}%] Scanning ${label2}...`);
3156
3179
  }
3157
- async function resolveCommand(cli, path43, description, depth, p) {
3158
- showProgress(p, path43.join(" "));
3159
- const subHelp = await runHelp([cli, ...path43]);
3180
+ async function resolveCommand(cli, path42, description, depth, p) {
3181
+ showProgress(p, path42.join(" "));
3182
+ const subHelp = await runHelp([cli, ...path42]);
3160
3183
  if (!subHelp || !hasSubcommands(subHelp)) {
3161
- return [{ path: path43, description }];
3184
+ return [{ path: path42, description }];
3162
3185
  }
3163
- const children = await discoverAt(cli, path43, depth + 1, p);
3164
- return children.length > 0 ? children : [{ path: path43, description }];
3186
+ const children = await discoverAt(cli, path42, depth + 1, p);
3187
+ return children.length > 0 ? children : [{ path: path42, description }];
3165
3188
  }
3166
3189
  async function discoverAt(cli, parentPath, depth, p) {
3167
3190
  if (depth > SAFETY_DEPTH) return [];
@@ -3309,14 +3332,14 @@ function logPath(cli) {
3309
3332
  return join12(homedir4(), ".assist", `cli-discover-${safeName}.log`);
3310
3333
  }
3311
3334
  function readCache(cli) {
3312
- const path43 = logPath(cli);
3313
- if (!existsSync18(path43)) return void 0;
3314
- return readFileSync15(path43, "utf-8");
3335
+ const path42 = logPath(cli);
3336
+ if (!existsSync18(path42)) return void 0;
3337
+ return readFileSync15(path42, "utf-8");
3315
3338
  }
3316
3339
  function writeCache(cli, output) {
3317
3340
  const dir = join12(homedir4(), ".assist");
3318
3341
  mkdirSync4(dir, { recursive: true });
3319
- writeFileSync13(logPath(cli), output);
3342
+ writeFileSync14(logPath(cli), output);
3320
3343
  }
3321
3344
  async function permitCliReads(cli, options2 = { noCache: false }) {
3322
3345
  if (!cli) {
@@ -3363,20 +3386,20 @@ function registerCliHook(program2) {
3363
3386
  }
3364
3387
 
3365
3388
  // src/commands/complexity/analyze.ts
3366
- import chalk38 from "chalk";
3389
+ import chalk39 from "chalk";
3367
3390
 
3368
3391
  // src/commands/complexity/cyclomatic.ts
3369
- import chalk34 from "chalk";
3392
+ import chalk35 from "chalk";
3370
3393
 
3371
3394
  // src/commands/complexity/shared/index.ts
3372
- import fs13 from "fs";
3373
- import path21 from "path";
3374
- import chalk33 from "chalk";
3395
+ import fs12 from "fs";
3396
+ import path20 from "path";
3397
+ import chalk34 from "chalk";
3375
3398
  import ts5 from "typescript";
3376
3399
 
3377
3400
  // src/commands/complexity/findSourceFiles.ts
3378
- import fs12 from "fs";
3379
- import path20 from "path";
3401
+ import fs11 from "fs";
3402
+ import path19 from "path";
3380
3403
  import { minimatch as minimatch3 } from "minimatch";
3381
3404
  function applyIgnoreGlobs(files) {
3382
3405
  const { complexity } = loadConfig();
@@ -3385,13 +3408,13 @@ function applyIgnoreGlobs(files) {
3385
3408
  );
3386
3409
  }
3387
3410
  function walk(dir, results) {
3388
- if (!fs12.existsSync(dir)) {
3411
+ if (!fs11.existsSync(dir)) {
3389
3412
  return;
3390
3413
  }
3391
3414
  const extensions = [".ts", ".tsx"];
3392
- const entries = fs12.readdirSync(dir, { withFileTypes: true });
3415
+ const entries = fs11.readdirSync(dir, { withFileTypes: true });
3393
3416
  for (const entry of entries) {
3394
- const fullPath = path20.join(dir, entry.name);
3417
+ const fullPath = path19.join(dir, entry.name);
3395
3418
  if (entry.isDirectory()) {
3396
3419
  if (entry.name !== "node_modules" && entry.name !== ".git") {
3397
3420
  walk(fullPath, results);
@@ -3407,10 +3430,10 @@ function findSourceFiles2(pattern2, baseDir = ".") {
3407
3430
  walk(baseDir, results);
3408
3431
  return applyIgnoreGlobs(results.filter((f) => minimatch3(f, pattern2)));
3409
3432
  }
3410
- if (fs12.existsSync(pattern2) && fs12.statSync(pattern2).isFile()) {
3433
+ if (fs11.existsSync(pattern2) && fs11.statSync(pattern2).isFile()) {
3411
3434
  return [pattern2];
3412
3435
  }
3413
- if (fs12.existsSync(pattern2) && fs12.statSync(pattern2).isDirectory()) {
3436
+ if (fs11.existsSync(pattern2) && fs11.statSync(pattern2).isDirectory()) {
3414
3437
  walk(pattern2, results);
3415
3438
  return applyIgnoreGlobs(results);
3416
3439
  }
@@ -3605,9 +3628,9 @@ function countSloc(content) {
3605
3628
 
3606
3629
  // src/commands/complexity/shared/index.ts
3607
3630
  function createSourceFromFile(filePath) {
3608
- const content = fs13.readFileSync(filePath, "utf-8");
3631
+ const content = fs12.readFileSync(filePath, "utf-8");
3609
3632
  return ts5.createSourceFile(
3610
- path21.basename(filePath),
3633
+ path20.basename(filePath),
3611
3634
  content,
3612
3635
  ts5.ScriptTarget.Latest,
3613
3636
  true,
@@ -3617,7 +3640,7 @@ function createSourceFromFile(filePath) {
3617
3640
  function withSourceFiles(pattern2, callback) {
3618
3641
  const files = findSourceFiles2(pattern2);
3619
3642
  if (files.length === 0) {
3620
- console.log(chalk33.yellow("No files found matching pattern"));
3643
+ console.log(chalk34.yellow("No files found matching pattern"));
3621
3644
  return void 0;
3622
3645
  }
3623
3646
  return callback(files);
@@ -3650,11 +3673,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
3650
3673
  results.sort((a, b) => b.complexity - a.complexity);
3651
3674
  for (const { file, name, complexity } of results) {
3652
3675
  const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
3653
- const color = exceedsThreshold ? chalk34.red : chalk34.white;
3654
- console.log(`${color(`${file}:${name}`)} \u2192 ${chalk34.cyan(complexity)}`);
3676
+ const color = exceedsThreshold ? chalk35.red : chalk35.white;
3677
+ console.log(`${color(`${file}:${name}`)} \u2192 ${chalk35.cyan(complexity)}`);
3655
3678
  }
3656
3679
  console.log(
3657
- chalk34.dim(
3680
+ chalk35.dim(
3658
3681
  `
3659
3682
  Analyzed ${results.length} functions across ${files.length} files`
3660
3683
  )
@@ -3666,7 +3689,7 @@ Analyzed ${results.length} functions across ${files.length} files`
3666
3689
  }
3667
3690
 
3668
3691
  // src/commands/complexity/halstead.ts
3669
- import chalk35 from "chalk";
3692
+ import chalk36 from "chalk";
3670
3693
  async function halstead(pattern2 = "**/*.ts", options2 = {}) {
3671
3694
  withSourceFiles(pattern2, (files) => {
3672
3695
  const results = [];
@@ -3681,13 +3704,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
3681
3704
  results.sort((a, b) => b.metrics.effort - a.metrics.effort);
3682
3705
  for (const { file, name, metrics } of results) {
3683
3706
  const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
3684
- const color = exceedsThreshold ? chalk35.red : chalk35.white;
3707
+ const color = exceedsThreshold ? chalk36.red : chalk36.white;
3685
3708
  console.log(
3686
- `${color(`${file}:${name}`)} \u2192 volume: ${chalk35.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk35.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk35.magenta(metrics.effort.toFixed(1))}`
3709
+ `${color(`${file}:${name}`)} \u2192 volume: ${chalk36.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk36.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk36.magenta(metrics.effort.toFixed(1))}`
3687
3710
  );
3688
3711
  }
3689
3712
  console.log(
3690
- chalk35.dim(
3713
+ chalk36.dim(
3691
3714
  `
3692
3715
  Analyzed ${results.length} functions across ${files.length} files`
3693
3716
  )
@@ -3699,31 +3722,31 @@ Analyzed ${results.length} functions across ${files.length} files`
3699
3722
  }
3700
3723
 
3701
3724
  // src/commands/complexity/maintainability/index.ts
3702
- import fs14 from "fs";
3725
+ import fs13 from "fs";
3703
3726
 
3704
3727
  // src/commands/complexity/maintainability/displayMaintainabilityResults.ts
3705
- import chalk36 from "chalk";
3728
+ import chalk37 from "chalk";
3706
3729
  function displayMaintainabilityResults(results, threshold) {
3707
3730
  const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
3708
3731
  if (threshold !== void 0 && filtered.length === 0) {
3709
- console.log(chalk36.green("All files pass maintainability threshold"));
3732
+ console.log(chalk37.green("All files pass maintainability threshold"));
3710
3733
  } else {
3711
3734
  for (const { file, avgMaintainability, minMaintainability } of filtered) {
3712
- const color = threshold !== void 0 ? chalk36.red : chalk36.white;
3735
+ const color = threshold !== void 0 ? chalk37.red : chalk37.white;
3713
3736
  console.log(
3714
- `${color(file)} \u2192 avg: ${chalk36.cyan(avgMaintainability.toFixed(1))}, min: ${chalk36.yellow(minMaintainability.toFixed(1))}`
3737
+ `${color(file)} \u2192 avg: ${chalk37.cyan(avgMaintainability.toFixed(1))}, min: ${chalk37.yellow(minMaintainability.toFixed(1))}`
3715
3738
  );
3716
3739
  }
3717
3740
  }
3718
- console.log(chalk36.dim(`
3741
+ console.log(chalk37.dim(`
3719
3742
  Analyzed ${results.length} files`));
3720
3743
  if (filtered.length > 0 && threshold !== void 0) {
3721
3744
  console.error(
3722
- chalk36.red(
3745
+ chalk37.red(
3723
3746
  `
3724
3747
  Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
3725
3748
 
3726
- \u26A0\uFE0F ${chalk36.bold("Diagnose and fix one file at a time")} \u2014 do not investigate or fix multiple files in parallel. Run 'assist complexity <file>' to see all metrics. For larger files, start by extracting responsibilities into smaller files.`
3749
+ \u26A0\uFE0F ${chalk37.bold("Diagnose and fix one file at a time")} \u2014 do not investigate or fix multiple files in parallel. Run 'assist complexity <file>' to see all metrics. For larger files, start by extracting responsibilities into smaller files.`
3727
3750
  )
3728
3751
  );
3729
3752
  process.exit(1);
@@ -3741,7 +3764,7 @@ function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, slo
3741
3764
  function collectFileMetrics(files) {
3742
3765
  const fileMetrics = /* @__PURE__ */ new Map();
3743
3766
  for (const file of files) {
3744
- const content = fs14.readFileSync(file, "utf-8");
3767
+ const content = fs13.readFileSync(file, "utf-8");
3745
3768
  fileMetrics.set(file, { sloc: countSloc(content), functions: [] });
3746
3769
  }
3747
3770
  forEachFunction(files, (file, _name, node) => {
@@ -3779,14 +3802,14 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
3779
3802
  }
3780
3803
 
3781
3804
  // src/commands/complexity/sloc.ts
3782
- import fs15 from "fs";
3783
- import chalk37 from "chalk";
3805
+ import fs14 from "fs";
3806
+ import chalk38 from "chalk";
3784
3807
  async function sloc(pattern2 = "**/*.ts", options2 = {}) {
3785
3808
  withSourceFiles(pattern2, (files) => {
3786
3809
  const results = [];
3787
3810
  let hasViolation = false;
3788
3811
  for (const file of files) {
3789
- const content = fs15.readFileSync(file, "utf-8");
3812
+ const content = fs14.readFileSync(file, "utf-8");
3790
3813
  const lines = countSloc(content);
3791
3814
  results.push({ file, lines });
3792
3815
  if (options2.threshold !== void 0 && lines > options2.threshold) {
@@ -3796,12 +3819,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
3796
3819
  results.sort((a, b) => b.lines - a.lines);
3797
3820
  for (const { file, lines } of results) {
3798
3821
  const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
3799
- const color = exceedsThreshold ? chalk37.red : chalk37.white;
3800
- console.log(`${color(file)} \u2192 ${chalk37.cyan(lines)} lines`);
3822
+ const color = exceedsThreshold ? chalk38.red : chalk38.white;
3823
+ console.log(`${color(file)} \u2192 ${chalk38.cyan(lines)} lines`);
3801
3824
  }
3802
3825
  const total = results.reduce((sum, r) => sum + r.lines, 0);
3803
3826
  console.log(
3804
- chalk37.dim(`
3827
+ chalk38.dim(`
3805
3828
  Total: ${total} lines across ${files.length} files`)
3806
3829
  );
3807
3830
  if (hasViolation) {
@@ -3815,21 +3838,21 @@ async function analyze(pattern2) {
3815
3838
  const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
3816
3839
  const files = findSourceFiles2(searchPattern);
3817
3840
  if (files.length === 0) {
3818
- console.log(chalk38.yellow("No files found matching pattern"));
3841
+ console.log(chalk39.yellow("No files found matching pattern"));
3819
3842
  return;
3820
3843
  }
3821
3844
  if (files.length === 1) {
3822
3845
  const file = files[0];
3823
- console.log(chalk38.bold.underline("SLOC"));
3846
+ console.log(chalk39.bold.underline("SLOC"));
3824
3847
  await sloc(file);
3825
3848
  console.log();
3826
- console.log(chalk38.bold.underline("Cyclomatic Complexity"));
3849
+ console.log(chalk39.bold.underline("Cyclomatic Complexity"));
3827
3850
  await cyclomatic(file);
3828
3851
  console.log();
3829
- console.log(chalk38.bold.underline("Halstead Metrics"));
3852
+ console.log(chalk39.bold.underline("Halstead Metrics"));
3830
3853
  await halstead(file);
3831
3854
  console.log();
3832
- console.log(chalk38.bold.underline("Maintainability Index"));
3855
+ console.log(chalk39.bold.underline("Maintainability Index"));
3833
3856
  await maintainability(file);
3834
3857
  return;
3835
3858
  }
@@ -3856,8 +3879,8 @@ function registerComplexity(program2) {
3856
3879
  }
3857
3880
 
3858
3881
  // src/commands/deploy/redirect.ts
3859
- import { existsSync as existsSync19, readFileSync as readFileSync16, writeFileSync as writeFileSync14 } from "fs";
3860
- import chalk39 from "chalk";
3882
+ import { existsSync as existsSync19, readFileSync as readFileSync16, writeFileSync as writeFileSync15 } from "fs";
3883
+ import chalk40 from "chalk";
3861
3884
  var TRAILING_SLASH_SCRIPT = ` <script>
3862
3885
  if (!window.location.pathname.endsWith('/')) {
3863
3886
  window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
@@ -3866,22 +3889,22 @@ var TRAILING_SLASH_SCRIPT = ` <script>
3866
3889
  function redirect() {
3867
3890
  const indexPath = "index.html";
3868
3891
  if (!existsSync19(indexPath)) {
3869
- console.log(chalk39.yellow("No index.html found"));
3892
+ console.log(chalk40.yellow("No index.html found"));
3870
3893
  return;
3871
3894
  }
3872
3895
  const content = readFileSync16(indexPath, "utf-8");
3873
3896
  if (content.includes("window.location.pathname.endsWith('/')")) {
3874
- console.log(chalk39.dim("Trailing slash script already present"));
3897
+ console.log(chalk40.dim("Trailing slash script already present"));
3875
3898
  return;
3876
3899
  }
3877
3900
  const headCloseIndex = content.indexOf("</head>");
3878
3901
  if (headCloseIndex === -1) {
3879
- console.log(chalk39.red("Could not find </head> tag in index.html"));
3902
+ console.log(chalk40.red("Could not find </head> tag in index.html"));
3880
3903
  return;
3881
3904
  }
3882
3905
  const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
3883
- writeFileSync14(indexPath, newContent);
3884
- console.log(chalk39.green("Added trailing slash redirect to index.html"));
3906
+ writeFileSync15(indexPath, newContent);
3907
+ console.log(chalk40.green("Added trailing slash redirect to index.html"));
3885
3908
  }
3886
3909
 
3887
3910
  // src/commands/registerDeploy.ts
@@ -3908,7 +3931,7 @@ function loadBlogSkipDays(repoName) {
3908
3931
 
3909
3932
  // src/commands/devlog/shared.ts
3910
3933
  import { execSync as execSync15 } from "child_process";
3911
- import chalk40 from "chalk";
3934
+ import chalk41 from "chalk";
3912
3935
 
3913
3936
  // src/commands/devlog/loadDevlogEntries.ts
3914
3937
  import { readdirSync, readFileSync as readFileSync17 } from "fs";
@@ -3995,13 +4018,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
3995
4018
  }
3996
4019
  function printCommitsWithFiles(commits, ignore2, verbose) {
3997
4020
  for (const commit2 of commits) {
3998
- console.log(` ${chalk40.yellow(commit2.hash)} ${commit2.message}`);
4021
+ console.log(` ${chalk41.yellow(commit2.hash)} ${commit2.message}`);
3999
4022
  if (verbose) {
4000
4023
  const visibleFiles = commit2.files.filter(
4001
4024
  (file) => !ignore2.some((p) => file.startsWith(p))
4002
4025
  );
4003
4026
  for (const file of visibleFiles) {
4004
- console.log(` ${chalk40.dim(file)}`);
4027
+ console.log(` ${chalk41.dim(file)}`);
4005
4028
  }
4006
4029
  }
4007
4030
  }
@@ -4026,15 +4049,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
4026
4049
  }
4027
4050
 
4028
4051
  // src/commands/devlog/list/printDateHeader.ts
4029
- import chalk41 from "chalk";
4052
+ import chalk42 from "chalk";
4030
4053
  function printDateHeader(date, isSkipped, entries) {
4031
4054
  if (isSkipped) {
4032
- console.log(`${chalk41.bold.blue(date)} ${chalk41.dim("skipped")}`);
4055
+ console.log(`${chalk42.bold.blue(date)} ${chalk42.dim("skipped")}`);
4033
4056
  } else if (entries && entries.length > 0) {
4034
- const entryInfo = entries.map((e) => `${chalk41.green(e.version)} ${e.title}`).join(" | ");
4035
- console.log(`${chalk41.bold.blue(date)} ${entryInfo}`);
4057
+ const entryInfo = entries.map((e) => `${chalk42.green(e.version)} ${e.title}`).join(" | ");
4058
+ console.log(`${chalk42.bold.blue(date)} ${entryInfo}`);
4036
4059
  } else {
4037
- console.log(`${chalk41.bold.blue(date)} ${chalk41.red("\u26A0 devlog missing")}`);
4060
+ console.log(`${chalk42.bold.blue(date)} ${chalk42.red("\u26A0 devlog missing")}`);
4038
4061
  }
4039
4062
  }
4040
4063
 
@@ -4137,24 +4160,24 @@ function bumpVersion(version2, type) {
4137
4160
 
4138
4161
  // src/commands/devlog/next/displayNextEntry/index.ts
4139
4162
  import { execSync as execSync18 } from "child_process";
4140
- import chalk43 from "chalk";
4163
+ import chalk44 from "chalk";
4141
4164
 
4142
4165
  // src/commands/devlog/next/displayNextEntry/displayVersion.ts
4143
- import chalk42 from "chalk";
4166
+ import chalk43 from "chalk";
4144
4167
  function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
4145
4168
  if (conventional && firstHash) {
4146
4169
  const version2 = getVersionAtCommit(firstHash);
4147
4170
  if (version2) {
4148
- console.log(`${chalk42.bold("version:")} ${stripToMinor(version2)}`);
4171
+ console.log(`${chalk43.bold("version:")} ${stripToMinor(version2)}`);
4149
4172
  } else {
4150
- console.log(`${chalk42.bold("version:")} ${chalk42.red("unknown")}`);
4173
+ console.log(`${chalk43.bold("version:")} ${chalk43.red("unknown")}`);
4151
4174
  }
4152
4175
  } else if (patchVersion && minorVersion) {
4153
4176
  console.log(
4154
- `${chalk42.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
4177
+ `${chalk43.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
4155
4178
  );
4156
4179
  } else {
4157
- console.log(`${chalk42.bold("version:")} v0.1 (initial)`);
4180
+ console.log(`${chalk43.bold("version:")} v0.1 (initial)`);
4158
4181
  }
4159
4182
  }
4160
4183
 
@@ -4201,16 +4224,16 @@ function noCommitsMessage(hasLastInfo) {
4201
4224
  return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
4202
4225
  }
4203
4226
  function logName(repoName) {
4204
- console.log(`${chalk43.bold("name:")} ${repoName}`);
4227
+ console.log(`${chalk44.bold("name:")} ${repoName}`);
4205
4228
  }
4206
4229
  function displayNextEntry(ctx, targetDate, commits) {
4207
4230
  logName(ctx.repoName);
4208
4231
  printVersionInfo(ctx.config, ctx.lastInfo, commits[0]?.hash);
4209
- console.log(chalk43.bold.blue(targetDate));
4232
+ console.log(chalk44.bold.blue(targetDate));
4210
4233
  printCommitsWithFiles(commits, ctx.ignore, ctx.verbose);
4211
4234
  }
4212
4235
  function logNoCommits(lastInfo) {
4213
- console.log(chalk43.dim(noCommitsMessage(!!lastInfo)));
4236
+ console.log(chalk44.dim(noCommitsMessage(!!lastInfo)));
4214
4237
  }
4215
4238
 
4216
4239
  // src/commands/devlog/next/index.ts
@@ -4251,11 +4274,11 @@ function next(options2) {
4251
4274
  import { execSync as execSync19 } from "child_process";
4252
4275
 
4253
4276
  // src/commands/devlog/repos/printReposTable.ts
4254
- import chalk44 from "chalk";
4277
+ import chalk45 from "chalk";
4255
4278
  function colorStatus(status2) {
4256
- if (status2 === "missing") return chalk44.red(status2);
4257
- if (status2 === "outdated") return chalk44.yellow(status2);
4258
- return chalk44.green(status2);
4279
+ if (status2 === "missing") return chalk45.red(status2);
4280
+ if (status2 === "outdated") return chalk45.yellow(status2);
4281
+ return chalk45.green(status2);
4259
4282
  }
4260
4283
  function formatRow(row, nameWidth) {
4261
4284
  const devlog = (row.lastDevlog ?? "-").padEnd(11);
@@ -4269,8 +4292,8 @@ function printReposTable(rows) {
4269
4292
  "Last Devlog".padEnd(11),
4270
4293
  "Status"
4271
4294
  ].join(" ");
4272
- console.log(chalk44.dim(header));
4273
- console.log(chalk44.dim("-".repeat(header.length)));
4295
+ console.log(chalk45.dim(header));
4296
+ console.log(chalk45.dim("-".repeat(header.length)));
4274
4297
  for (const row of rows) {
4275
4298
  console.log(formatRow(row, nameWidth));
4276
4299
  }
@@ -4326,16 +4349,16 @@ function repos(options2) {
4326
4349
  }
4327
4350
 
4328
4351
  // src/commands/devlog/skip.ts
4329
- import { writeFileSync as writeFileSync15 } from "fs";
4352
+ import { writeFileSync as writeFileSync16 } from "fs";
4330
4353
  import { join as join15 } from "path";
4331
- import chalk45 from "chalk";
4354
+ import chalk46 from "chalk";
4332
4355
  import { stringify as stringifyYaml4 } from "yaml";
4333
4356
  function getBlogConfigPath() {
4334
4357
  return join15(BLOG_REPO_ROOT, "assist.yml");
4335
4358
  }
4336
4359
  function skip(date) {
4337
4360
  if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
4338
- console.log(chalk45.red("Invalid date format. Use YYYY-MM-DD"));
4361
+ console.log(chalk46.red("Invalid date format. Use YYYY-MM-DD"));
4339
4362
  process.exit(1);
4340
4363
  }
4341
4364
  const repoName = getRepoName();
@@ -4346,7 +4369,7 @@ function skip(date) {
4346
4369
  const skipDays = skip2[repoName] ?? [];
4347
4370
  if (skipDays.includes(date)) {
4348
4371
  console.log(
4349
- chalk45.yellow(`${date} is already in skip list for ${repoName}`)
4372
+ chalk46.yellow(`${date} is already in skip list for ${repoName}`)
4350
4373
  );
4351
4374
  return;
4352
4375
  }
@@ -4355,21 +4378,21 @@ function skip(date) {
4355
4378
  skip2[repoName] = skipDays;
4356
4379
  devlog.skip = skip2;
4357
4380
  config.devlog = devlog;
4358
- writeFileSync15(configPath, stringifyYaml4(config, { lineWidth: 0 }));
4359
- console.log(chalk45.green(`Added ${date} to skip list for ${repoName}`));
4381
+ writeFileSync16(configPath, stringifyYaml4(config, { lineWidth: 0 }));
4382
+ console.log(chalk46.green(`Added ${date} to skip list for ${repoName}`));
4360
4383
  }
4361
4384
 
4362
4385
  // src/commands/devlog/version.ts
4363
- import chalk46 from "chalk";
4386
+ import chalk47 from "chalk";
4364
4387
  function version() {
4365
4388
  const config = loadConfig();
4366
4389
  const name = getRepoName();
4367
4390
  const lastInfo = getLastVersionInfo(name, config);
4368
4391
  const lastVersion = lastInfo?.version ?? null;
4369
4392
  const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
4370
- console.log(`${chalk46.bold("name:")} ${name}`);
4371
- console.log(`${chalk46.bold("last:")} ${lastVersion ?? chalk46.dim("none")}`);
4372
- console.log(`${chalk46.bold("next:")} ${nextVersion ?? chalk46.dim("none")}`);
4393
+ console.log(`${chalk47.bold("name:")} ${name}`);
4394
+ console.log(`${chalk47.bold("last:")} ${lastVersion ?? chalk47.dim("none")}`);
4395
+ console.log(`${chalk47.bold("next:")} ${nextVersion ?? chalk47.dim("none")}`);
4373
4396
  }
4374
4397
 
4375
4398
  // src/commands/registerDevlog.ts
@@ -4392,7 +4415,7 @@ function registerDevlog(program2) {
4392
4415
 
4393
4416
  // src/commands/jira/acceptanceCriteria.ts
4394
4417
  import { execSync as execSync20 } from "child_process";
4395
- import chalk47 from "chalk";
4418
+ import chalk48 from "chalk";
4396
4419
 
4397
4420
  // src/commands/jira/adfToText.ts
4398
4421
  function renderInline(node) {
@@ -4467,21 +4490,21 @@ function acceptanceCriteria(issueKey) {
4467
4490
  const stderr = error.stderr;
4468
4491
  if (stderr.includes("unauthorized")) {
4469
4492
  console.error(
4470
- chalk47.red("Jira authentication expired."),
4493
+ chalk48.red("Jira authentication expired."),
4471
4494
  "Run",
4472
- chalk47.cyan("assist jira auth"),
4495
+ chalk48.cyan("assist jira auth"),
4473
4496
  "to re-authenticate."
4474
4497
  );
4475
4498
  process.exit(1);
4476
4499
  }
4477
4500
  }
4478
- console.error(chalk47.red(`Failed to fetch ${issueKey}.`));
4501
+ console.error(chalk48.red(`Failed to fetch ${issueKey}.`));
4479
4502
  process.exit(1);
4480
4503
  }
4481
4504
  const parsed = JSON.parse(result);
4482
4505
  const acValue = parsed?.fields?.[field];
4483
4506
  if (!acValue) {
4484
- console.log(chalk47.yellow(`No acceptance criteria found on ${issueKey}.`));
4507
+ console.log(chalk48.yellow(`No acceptance criteria found on ${issueKey}.`));
4485
4508
  return;
4486
4509
  }
4487
4510
  if (typeof acValue === "string") {
@@ -4500,7 +4523,7 @@ import { execSync as execSync21 } from "child_process";
4500
4523
  import Enquirer from "enquirer";
4501
4524
 
4502
4525
  // src/shared/loadJson.ts
4503
- import { existsSync as existsSync20, mkdirSync as mkdirSync5, readFileSync as readFileSync18, writeFileSync as writeFileSync16 } from "fs";
4526
+ import { existsSync as existsSync20, mkdirSync as mkdirSync5, readFileSync as readFileSync18, writeFileSync as writeFileSync17 } from "fs";
4504
4527
  import { homedir as homedir6 } from "os";
4505
4528
  import { join as join16 } from "path";
4506
4529
  function getStoreDir() {
@@ -4510,10 +4533,10 @@ function getStorePath(filename) {
4510
4533
  return join16(getStoreDir(), filename);
4511
4534
  }
4512
4535
  function loadJson(filename) {
4513
- const path43 = getStorePath(filename);
4514
- if (existsSync20(path43)) {
4536
+ const path42 = getStorePath(filename);
4537
+ if (existsSync20(path42)) {
4515
4538
  try {
4516
- return JSON.parse(readFileSync18(path43, "utf-8"));
4539
+ return JSON.parse(readFileSync18(path42, "utf-8"));
4517
4540
  } catch {
4518
4541
  return {};
4519
4542
  }
@@ -4525,19 +4548,19 @@ function saveJson(filename, data) {
4525
4548
  if (!existsSync20(dir)) {
4526
4549
  mkdirSync5(dir, { recursive: true });
4527
4550
  }
4528
- writeFileSync16(getStorePath(filename), JSON.stringify(data, null, 2));
4551
+ writeFileSync17(getStorePath(filename), JSON.stringify(data, null, 2));
4529
4552
  }
4530
4553
 
4531
4554
  // src/commands/jira/jiraAuth.ts
4532
4555
  var CONFIG_FILE = "jira.json";
4533
4556
  async function promptCredentials(config) {
4534
- const { Input, Password } = Enquirer;
4535
- const site = await new Input({
4557
+ const { Input: Input2, Password } = Enquirer;
4558
+ const site = await new Input2({
4536
4559
  name: "site",
4537
4560
  message: "Jira site (e.g., mycompany.atlassian.net):",
4538
4561
  initial: config.site
4539
4562
  }).run();
4540
- const email = await new Input({
4563
+ const email = await new Input2({
4541
4564
  name: "email",
4542
4565
  message: "Email:",
4543
4566
  initial: config.email
@@ -4580,7 +4603,7 @@ function registerJira(program2) {
4580
4603
 
4581
4604
  // src/commands/netframework/buildTree.ts
4582
4605
  import { readFileSync as readFileSync19 } from "fs";
4583
- import path22 from "path";
4606
+ import path21 from "path";
4584
4607
  var PROJECT_REF_RE = /<ProjectReference\s+Include="([^"]+)"/g;
4585
4608
  function getProjectRefs(csprojPath) {
4586
4609
  const content = readFileSync19(csprojPath, "utf-8");
@@ -4591,14 +4614,14 @@ function getProjectRefs(csprojPath) {
4591
4614
  return refs;
4592
4615
  }
4593
4616
  function buildTree(csprojPath, repoRoot, visited = /* @__PURE__ */ new Set()) {
4594
- const abs = path22.resolve(csprojPath);
4595
- const rel = path22.relative(repoRoot, abs);
4617
+ const abs = path21.resolve(csprojPath);
4618
+ const rel = path21.relative(repoRoot, abs);
4596
4619
  const node = { path: abs, relativePath: rel, children: [] };
4597
4620
  if (visited.has(abs)) return node;
4598
4621
  visited.add(abs);
4599
- const dir = path22.dirname(abs);
4622
+ const dir = path21.dirname(abs);
4600
4623
  for (const ref of getProjectRefs(abs)) {
4601
- const childAbs = path22.resolve(dir, ref);
4624
+ const childAbs = path21.resolve(dir, ref);
4602
4625
  try {
4603
4626
  readFileSync19(childAbs);
4604
4627
  node.children.push(buildTree(childAbs, repoRoot, visited));
@@ -4626,7 +4649,7 @@ function collectAllDeps(node) {
4626
4649
 
4627
4650
  // src/commands/netframework/findContainingSolutions.ts
4628
4651
  import { readdirSync as readdirSync2, readFileSync as readFileSync20, statSync } from "fs";
4629
- import path23 from "path";
4652
+ import path22 from "path";
4630
4653
  function findSlnFiles(dir, maxDepth, depth = 0) {
4631
4654
  if (depth > maxDepth) return [];
4632
4655
  const results = [];
@@ -4639,7 +4662,7 @@ function findSlnFiles(dir, maxDepth, depth = 0) {
4639
4662
  for (const entry of entries) {
4640
4663
  if (entry.startsWith(".") || entry === "node_modules" || entry === "packages")
4641
4664
  continue;
4642
- const full = path23.join(dir, entry);
4665
+ const full = path22.join(dir, entry);
4643
4666
  try {
4644
4667
  const stat = statSync(full);
4645
4668
  if (stat.isFile() && entry.endsWith(".sln")) {
@@ -4653,8 +4676,8 @@ function findSlnFiles(dir, maxDepth, depth = 0) {
4653
4676
  return results;
4654
4677
  }
4655
4678
  function findContainingSolutions(csprojPath, repoRoot) {
4656
- const csprojAbs = path23.resolve(csprojPath);
4657
- const csprojBasename = path23.basename(csprojAbs);
4679
+ const csprojAbs = path22.resolve(csprojPath);
4680
+ const csprojBasename = path22.basename(csprojAbs);
4658
4681
  const slnFiles = findSlnFiles(repoRoot, 3);
4659
4682
  const matches = [];
4660
4683
  const pattern2 = new RegExp(`[\\\\"/]${escapeRegex(csprojBasename)}"`);
@@ -4662,7 +4685,7 @@ function findContainingSolutions(csprojPath, repoRoot) {
4662
4685
  try {
4663
4686
  const content = readFileSync20(sln, "utf-8");
4664
4687
  if (pattern2.test(content)) {
4665
- matches.push(path23.relative(repoRoot, sln));
4688
+ matches.push(path22.relative(repoRoot, sln));
4666
4689
  }
4667
4690
  } catch {
4668
4691
  }
@@ -4674,30 +4697,30 @@ function escapeRegex(s) {
4674
4697
  }
4675
4698
 
4676
4699
  // src/commands/netframework/printTree.ts
4677
- import chalk48 from "chalk";
4700
+ import chalk49 from "chalk";
4678
4701
  function printNodes(nodes, prefix2) {
4679
4702
  for (let i = 0; i < nodes.length; i++) {
4680
4703
  const isLast = i === nodes.length - 1;
4681
4704
  const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
4682
4705
  const childPrefix = isLast ? " " : "\u2502 ";
4683
4706
  const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
4684
- const label2 = isMissing ? chalk48.red(nodes[i].relativePath) : nodes[i].relativePath;
4707
+ const label2 = isMissing ? chalk49.red(nodes[i].relativePath) : nodes[i].relativePath;
4685
4708
  console.log(`${prefix2}${connector}${label2}`);
4686
4709
  printNodes(nodes[i].children, prefix2 + childPrefix);
4687
4710
  }
4688
4711
  }
4689
4712
  function printTree(tree, totalCount, solutions) {
4690
- console.log(chalk48.bold("\nProject Dependency Tree"));
4691
- console.log(chalk48.cyan(tree.relativePath));
4713
+ console.log(chalk49.bold("\nProject Dependency Tree"));
4714
+ console.log(chalk49.cyan(tree.relativePath));
4692
4715
  printNodes(tree.children, "");
4693
- console.log(chalk48.dim(`
4716
+ console.log(chalk49.dim(`
4694
4717
  ${totalCount} projects total (including root)`));
4695
- console.log(chalk48.bold("\nSolution Membership"));
4718
+ console.log(chalk49.bold("\nSolution Membership"));
4696
4719
  if (solutions.length === 0) {
4697
- console.log(chalk48.yellow(" Not found in any .sln"));
4720
+ console.log(chalk49.yellow(" Not found in any .sln"));
4698
4721
  } else {
4699
4722
  for (const sln of solutions) {
4700
- console.log(` ${chalk48.green(sln)}`);
4723
+ console.log(` ${chalk49.green(sln)}`);
4701
4724
  }
4702
4725
  }
4703
4726
  console.log();
@@ -4725,33 +4748,33 @@ function printJson(tree, totalCount, solutions) {
4725
4748
 
4726
4749
  // src/commands/netframework/resolveCsproj.ts
4727
4750
  import { existsSync as existsSync22 } from "fs";
4728
- import path25 from "path";
4729
- import chalk49 from "chalk";
4751
+ import path24 from "path";
4752
+ import chalk50 from "chalk";
4730
4753
 
4731
4754
  // src/commands/netframework/findRepoRoot.ts
4732
4755
  import { existsSync as existsSync21 } from "fs";
4733
- import path24 from "path";
4756
+ import path23 from "path";
4734
4757
  function findRepoRoot(dir) {
4735
4758
  let current = dir;
4736
- while (current !== path24.dirname(current)) {
4737
- if (existsSync21(path24.join(current, ".git"))) {
4759
+ while (current !== path23.dirname(current)) {
4760
+ if (existsSync21(path23.join(current, ".git"))) {
4738
4761
  return current;
4739
4762
  }
4740
- current = path24.dirname(current);
4763
+ current = path23.dirname(current);
4741
4764
  }
4742
4765
  return null;
4743
4766
  }
4744
4767
 
4745
4768
  // src/commands/netframework/resolveCsproj.ts
4746
4769
  function resolveCsproj(csprojPath) {
4747
- const resolved = path25.resolve(csprojPath);
4770
+ const resolved = path24.resolve(csprojPath);
4748
4771
  if (!existsSync22(resolved)) {
4749
- console.error(chalk49.red(`File not found: ${resolved}`));
4772
+ console.error(chalk50.red(`File not found: ${resolved}`));
4750
4773
  process.exit(1);
4751
4774
  }
4752
- const repoRoot = findRepoRoot(path25.dirname(resolved));
4775
+ const repoRoot = findRepoRoot(path24.dirname(resolved));
4753
4776
  if (!repoRoot) {
4754
- console.error(chalk49.red("Could not find git repository root"));
4777
+ console.error(chalk50.red("Could not find git repository root"));
4755
4778
  process.exit(1);
4756
4779
  }
4757
4780
  return { resolved, repoRoot };
@@ -4771,12 +4794,12 @@ async function deps(csprojPath, options2) {
4771
4794
  }
4772
4795
 
4773
4796
  // src/commands/netframework/inSln.ts
4774
- import chalk50 from "chalk";
4797
+ import chalk51 from "chalk";
4775
4798
  async function inSln(csprojPath) {
4776
4799
  const { resolved, repoRoot } = resolveCsproj(csprojPath);
4777
4800
  const solutions = findContainingSolutions(resolved, repoRoot);
4778
4801
  if (solutions.length === 0) {
4779
- console.log(chalk50.yellow("Not found in any .sln file"));
4802
+ console.log(chalk51.yellow("Not found in any .sln file"));
4780
4803
  process.exit(1);
4781
4804
  }
4782
4805
  for (const sln of solutions) {
@@ -4792,7 +4815,7 @@ function registerNetframework(program2) {
4792
4815
  }
4793
4816
 
4794
4817
  // src/commands/news/add/index.ts
4795
- import chalk51 from "chalk";
4818
+ import chalk52 from "chalk";
4796
4819
  import enquirer5 from "enquirer";
4797
4820
  async function add2(url) {
4798
4821
  if (!url) {
@@ -4815,17 +4838,17 @@ async function add2(url) {
4815
4838
  const news = config.news ?? {};
4816
4839
  const feeds = news.feeds ?? [];
4817
4840
  if (feeds.includes(url)) {
4818
- console.log(chalk51.yellow("Feed already exists in config"));
4841
+ console.log(chalk52.yellow("Feed already exists in config"));
4819
4842
  return;
4820
4843
  }
4821
4844
  feeds.push(url);
4822
4845
  config.news = { ...news, feeds };
4823
4846
  saveGlobalConfig(config);
4824
- console.log(chalk51.green(`Added feed: ${url}`));
4847
+ console.log(chalk52.green(`Added feed: ${url}`));
4825
4848
  }
4826
4849
 
4827
4850
  // src/commands/news/web/handleRequest.ts
4828
- import chalk52 from "chalk";
4851
+ import chalk53 from "chalk";
4829
4852
 
4830
4853
  // src/commands/news/web/shared.ts
4831
4854
  import { decodeHTML } from "entities";
@@ -4961,17 +4984,17 @@ function prefetch() {
4961
4984
  const config = loadConfig();
4962
4985
  const total = config.news.feeds.length;
4963
4986
  if (total === 0) return;
4964
- process.stdout.write(chalk52.dim(`Fetching ${total} feed(s)\u2026 `));
4987
+ process.stdout.write(chalk53.dim(`Fetching ${total} feed(s)\u2026 `));
4965
4988
  prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
4966
4989
  const width = 20;
4967
4990
  const filled = Math.round(done2 / t * width);
4968
4991
  const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
4969
4992
  process.stdout.write(
4970
- `\r${chalk52.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
4993
+ `\r${chalk53.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
4971
4994
  );
4972
4995
  }).then((items) => {
4973
4996
  process.stdout.write(
4974
- `\r${chalk52.green(`Fetched ${items.length} items from ${total} feed(s)`)}
4997
+ `\r${chalk53.green(`Fetched ${items.length} items from ${total} feed(s)`)}
4975
4998
  `
4976
4999
  );
4977
5000
  cachedItems = items;
@@ -5017,7 +5040,7 @@ function registerNews(program2) {
5017
5040
 
5018
5041
  // src/commands/prs/comment.ts
5019
5042
  import { spawnSync as spawnSync2 } from "child_process";
5020
- import { unlinkSync as unlinkSync3, writeFileSync as writeFileSync17 } from "fs";
5043
+ import { unlinkSync as unlinkSync3, writeFileSync as writeFileSync18 } from "fs";
5021
5044
  import { tmpdir as tmpdir2 } from "os";
5022
5045
  import { join as join17 } from "path";
5023
5046
 
@@ -5086,13 +5109,13 @@ function validateLine(line) {
5086
5109
  process.exit(1);
5087
5110
  }
5088
5111
  }
5089
- function comment(path43, line, body) {
5112
+ function comment(path42, line, body) {
5090
5113
  validateBody(body);
5091
5114
  validateLine(line);
5092
5115
  try {
5093
5116
  const prId = getCurrentPrNodeId();
5094
5117
  const queryFile = join17(tmpdir2(), `gh-query-${Date.now()}.graphql`);
5095
- writeFileSync17(queryFile, MUTATION);
5118
+ writeFileSync18(queryFile, MUTATION);
5096
5119
  try {
5097
5120
  const result = spawnSync2(
5098
5121
  "gh",
@@ -5106,7 +5129,7 @@ function comment(path43, line, body) {
5106
5129
  "-f",
5107
5130
  `body=${body}`,
5108
5131
  "-f",
5109
- `path=${path43}`,
5132
+ `path=${path42}`,
5110
5133
  "-F",
5111
5134
  `line=${line}`
5112
5135
  ],
@@ -5115,7 +5138,7 @@ function comment(path43, line, body) {
5115
5138
  if (result.status !== 0) {
5116
5139
  throw new Error(result.stderr || result.stdout);
5117
5140
  }
5118
- console.log(`Added review comment on ${path43}:${line}`);
5141
+ console.log(`Added review comment on ${path42}:${line}`);
5119
5142
  } finally {
5120
5143
  unlinkSync3(queryFile);
5121
5144
  }
@@ -5134,7 +5157,7 @@ import { execSync as execSync24 } from "child_process";
5134
5157
 
5135
5158
  // src/commands/prs/resolveCommentWithReply.ts
5136
5159
  import { execSync as execSync23 } from "child_process";
5137
- import { unlinkSync as unlinkSync5, writeFileSync as writeFileSync18 } from "fs";
5160
+ import { unlinkSync as unlinkSync5, writeFileSync as writeFileSync19 } from "fs";
5138
5161
  import { tmpdir as tmpdir3 } from "os";
5139
5162
  import { join as join19 } from "path";
5140
5163
 
@@ -5171,7 +5194,7 @@ function replyToComment(org, repo, prNumber, commentId, message) {
5171
5194
  function resolveThread(threadId) {
5172
5195
  const mutation = `mutation($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } }`;
5173
5196
  const queryFile = join19(tmpdir3(), `gh-mutation-${Date.now()}.graphql`);
5174
- writeFileSync18(queryFile, mutation);
5197
+ writeFileSync19(queryFile, mutation);
5175
5198
  try {
5176
5199
  execSync23(
5177
5200
  `gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
@@ -5252,19 +5275,19 @@ function fixed(commentId, sha) {
5252
5275
  }
5253
5276
 
5254
5277
  // src/commands/prs/listComments/index.ts
5255
- import { existsSync as existsSync24, mkdirSync as mkdirSync6, writeFileSync as writeFileSync20 } from "fs";
5278
+ import { existsSync as existsSync24, mkdirSync as mkdirSync6, writeFileSync as writeFileSync21 } from "fs";
5256
5279
  import { join as join21 } from "path";
5257
5280
  import { stringify } from "yaml";
5258
5281
 
5259
5282
  // src/commands/prs/fetchThreadIds.ts
5260
5283
  import { execSync as execSync25 } from "child_process";
5261
- import { unlinkSync as unlinkSync6, writeFileSync as writeFileSync19 } from "fs";
5284
+ import { unlinkSync as unlinkSync6, writeFileSync as writeFileSync20 } from "fs";
5262
5285
  import { tmpdir as tmpdir4 } from "os";
5263
5286
  import { join as join20 } from "path";
5264
5287
  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 } } } } } } }`;
5265
5288
  function fetchThreadIds(org, repo, prNumber) {
5266
5289
  const queryFile = join20(tmpdir4(), `gh-query-${Date.now()}.graphql`);
5267
- writeFileSync19(queryFile, THREAD_QUERY);
5290
+ writeFileSync20(queryFile, THREAD_QUERY);
5268
5291
  try {
5269
5292
  const result = execSync25(
5270
5293
  `gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
@@ -5332,20 +5355,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
5332
5355
  }
5333
5356
 
5334
5357
  // src/commands/prs/listComments/printComments.ts
5335
- import chalk53 from "chalk";
5358
+ import chalk54 from "chalk";
5336
5359
  function formatForHuman(comment2) {
5337
5360
  if (comment2.type === "review") {
5338
- const stateColor = comment2.state === "APPROVED" ? chalk53.green : comment2.state === "CHANGES_REQUESTED" ? chalk53.red : chalk53.yellow;
5361
+ const stateColor = comment2.state === "APPROVED" ? chalk54.green : comment2.state === "CHANGES_REQUESTED" ? chalk54.red : chalk54.yellow;
5339
5362
  return [
5340
- `${chalk53.cyan("Review")} by ${chalk53.bold(comment2.user)} ${stateColor(`[${comment2.state}]`)}`,
5363
+ `${chalk54.cyan("Review")} by ${chalk54.bold(comment2.user)} ${stateColor(`[${comment2.state}]`)}`,
5341
5364
  comment2.body,
5342
5365
  ""
5343
5366
  ].join("\n");
5344
5367
  }
5345
5368
  const location = comment2.line ? `:${comment2.line}` : "";
5346
5369
  return [
5347
- `${chalk53.cyan("Line comment")} by ${chalk53.bold(comment2.user)} on ${chalk53.dim(`${comment2.path}${location}`)}`,
5348
- chalk53.dim(comment2.diff_hunk.split("\n").slice(-3).join("\n")),
5370
+ `${chalk54.cyan("Line comment")} by ${chalk54.bold(comment2.user)} on ${chalk54.dim(`${comment2.path}${location}`)}`,
5371
+ chalk54.dim(comment2.diff_hunk.split("\n").slice(-3).join("\n")),
5349
5372
  comment2.body,
5350
5373
  ""
5351
5374
  ].join("\n");
@@ -5387,7 +5410,7 @@ function writeCommentsCache(prNumber, comments) {
5387
5410
  comments
5388
5411
  };
5389
5412
  const cachePath = join21(assistDir, `pr-${prNumber}-comments.yaml`);
5390
- writeFileSync20(cachePath, stringify(cacheData));
5413
+ writeFileSync21(cachePath, stringify(cacheData));
5391
5414
  }
5392
5415
  function handleKnownErrors(error) {
5393
5416
  if (isGhNotInstalled(error)) {
@@ -5435,13 +5458,13 @@ import { execSync as execSync27 } from "child_process";
5435
5458
  import enquirer6 from "enquirer";
5436
5459
 
5437
5460
  // src/commands/prs/prs/displayPaginated/printPr.ts
5438
- import chalk54 from "chalk";
5461
+ import chalk55 from "chalk";
5439
5462
  var STATUS_MAP = {
5440
- MERGED: (pr) => pr.mergedAt ? { label: chalk54.magenta("merged"), date: pr.mergedAt } : null,
5441
- CLOSED: (pr) => pr.closedAt ? { label: chalk54.red("closed"), date: pr.closedAt } : null
5463
+ MERGED: (pr) => pr.mergedAt ? { label: chalk55.magenta("merged"), date: pr.mergedAt } : null,
5464
+ CLOSED: (pr) => pr.closedAt ? { label: chalk55.red("closed"), date: pr.closedAt } : null
5442
5465
  };
5443
5466
  function defaultStatus(pr) {
5444
- return { label: chalk54.green("opened"), date: pr.createdAt };
5467
+ return { label: chalk55.green("opened"), date: pr.createdAt };
5445
5468
  }
5446
5469
  function getStatus2(pr) {
5447
5470
  return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
@@ -5450,11 +5473,11 @@ function formatDate(dateStr) {
5450
5473
  return new Date(dateStr).toISOString().split("T")[0];
5451
5474
  }
5452
5475
  function formatPrHeader(pr, status2) {
5453
- return `${chalk54.cyan(`#${pr.number}`)} ${pr.title} ${chalk54.dim(`(${pr.author.login},`)} ${status2.label} ${chalk54.dim(`${formatDate(status2.date)})`)}`;
5476
+ return `${chalk55.cyan(`#${pr.number}`)} ${pr.title} ${chalk55.dim(`(${pr.author.login},`)} ${status2.label} ${chalk55.dim(`${formatDate(status2.date)})`)}`;
5454
5477
  }
5455
5478
  function logPrDetails(pr) {
5456
5479
  console.log(
5457
- chalk54.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
5480
+ chalk55.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
5458
5481
  );
5459
5482
  console.log();
5460
5483
  }
@@ -5614,17 +5637,425 @@ function registerPrs(program2) {
5614
5637
  prsCommand.command("wontfix <comment-id> <reason>").description("Reply with reason and resolve thread").action((commentId, reason) => {
5615
5638
  wontfix(Number.parseInt(commentId, 10), reason);
5616
5639
  });
5617
- prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((path43, line, body) => {
5618
- comment(path43, Number.parseInt(line, 10), body);
5640
+ prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((path42, line, body) => {
5641
+ comment(path42, Number.parseInt(line, 10), body);
5642
+ });
5643
+ }
5644
+
5645
+ // src/commands/ravendb/ravendbAuth.ts
5646
+ import chalk60 from "chalk";
5647
+
5648
+ // src/commands/ravendb/loadConnections.ts
5649
+ function loadConnections() {
5650
+ const raw = loadGlobalConfigRaw();
5651
+ const ravendb = raw.ravendb;
5652
+ return ravendb?.connections ?? [];
5653
+ }
5654
+ function saveConnections(connections) {
5655
+ const raw = loadGlobalConfigRaw();
5656
+ const ravendb = raw.ravendb ?? {};
5657
+ ravendb.connections = connections;
5658
+ raw.ravendb = ravendb;
5659
+ saveGlobalConfig(raw);
5660
+ }
5661
+
5662
+ // src/commands/ravendb/promptConnection.ts
5663
+ import chalk58 from "chalk";
5664
+ import Enquirer3 from "enquirer";
5665
+
5666
+ // src/commands/ravendb/selectOpSecret.ts
5667
+ import chalk57 from "chalk";
5668
+ import Enquirer2 from "enquirer";
5669
+
5670
+ // src/commands/ravendb/searchItems.ts
5671
+ import { execSync as execSync29 } from "child_process";
5672
+ import chalk56 from "chalk";
5673
+ function opExec(args) {
5674
+ return execSync29(`op ${args}`, {
5675
+ encoding: "utf-8",
5676
+ stdio: ["pipe", "pipe", "pipe"]
5677
+ }).trim();
5678
+ }
5679
+ function searchItems(search) {
5680
+ let items;
5681
+ try {
5682
+ items = JSON.parse(opExec("item list --format=json"));
5683
+ } catch {
5684
+ console.error(
5685
+ chalk56.red(
5686
+ "Failed to search 1Password. Ensure the CLI is installed and you are signed in."
5687
+ )
5688
+ );
5689
+ process.exit(1);
5690
+ }
5691
+ const lower = search.toLowerCase();
5692
+ return items.filter((i) => i.title.toLowerCase().includes(lower));
5693
+ }
5694
+ function getItemFields(itemId) {
5695
+ try {
5696
+ const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
5697
+ return item.fields.filter((f) => f.reference && f.label);
5698
+ } catch {
5699
+ console.error(chalk56.red("Failed to get item details from 1Password."));
5700
+ process.exit(1);
5701
+ }
5702
+ }
5703
+
5704
+ // src/commands/ravendb/selectOpSecret.ts
5705
+ var { Input, Select } = Enquirer2;
5706
+ async function selectOne(message, choices) {
5707
+ if (choices.length === 1) return choices[0].value;
5708
+ const selected = await new Select({ name: "choice", message, choices }).run();
5709
+ return choices.find((c) => c.name === selected)?.value ?? selected;
5710
+ }
5711
+ async function selectOpSecret(searchTerm) {
5712
+ const search = searchTerm ?? await new Input({
5713
+ name: "search",
5714
+ message: "Search 1Password for API key item:"
5715
+ }).run();
5716
+ const items = searchItems(search);
5717
+ if (items.length === 0) {
5718
+ console.error(chalk57.red(`No items found matching "${search}".`));
5719
+ process.exit(1);
5720
+ }
5721
+ const itemId = await selectOne(
5722
+ "Select item:",
5723
+ items.map((i) => ({ name: `${i.title} (${i.vault.name})`, value: i.id }))
5724
+ );
5725
+ const fields = getItemFields(itemId);
5726
+ if (fields.length === 0) {
5727
+ console.error(chalk57.red("No fields with references found on this item."));
5728
+ process.exit(1);
5729
+ }
5730
+ const ref = await selectOne(
5731
+ "Select field:",
5732
+ fields.map((f) => ({ name: f.label, value: f.reference }))
5733
+ );
5734
+ return ref;
5735
+ }
5736
+
5737
+ // src/commands/ravendb/promptConnection.ts
5738
+ async function promptConnection(existingNames) {
5739
+ const { Input: Input2 } = Enquirer3;
5740
+ const name = await new Input2({
5741
+ name: "name",
5742
+ message: "Connection name:"
5743
+ }).run();
5744
+ if (existingNames.includes(name)) {
5745
+ console.error(chalk58.red(`Connection "${name}" already exists.`));
5746
+ process.exit(1);
5747
+ }
5748
+ const url = await new Input2({
5749
+ name: "url",
5750
+ message: "RavenDB base URL (e.g. https://host.ravenhq.com):"
5751
+ }).run();
5752
+ const database = await new Input2({
5753
+ name: "database",
5754
+ message: "Database name:"
5755
+ }).run();
5756
+ if (!name || !url || !database) {
5757
+ console.error(chalk58.red("All fields are required."));
5758
+ process.exit(1);
5759
+ }
5760
+ const apiKeyRef = await selectOpSecret();
5761
+ console.log(chalk58.dim(`Using: ${apiKeyRef}`));
5762
+ return { name, url, database, apiKeyRef };
5763
+ }
5764
+
5765
+ // src/commands/ravendb/ravendbSetConnection.ts
5766
+ import chalk59 from "chalk";
5767
+ function ravendbSetConnection(name) {
5768
+ const raw = loadGlobalConfigRaw();
5769
+ const ravendb = raw.ravendb ?? {};
5770
+ const connections = ravendb.connections ?? [];
5771
+ if (!connections.some((c) => c.name === name)) {
5772
+ console.error(chalk59.red(`Connection "${name}" not found.`));
5773
+ console.error(
5774
+ `Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
5775
+ );
5776
+ process.exit(1);
5777
+ }
5778
+ ravendb.defaultConnection = name;
5779
+ raw.ravendb = ravendb;
5780
+ saveGlobalConfig(raw);
5781
+ console.log(`Default connection set to "${name}".`);
5782
+ }
5783
+
5784
+ // src/commands/ravendb/ravendbAuth.ts
5785
+ async function ravendbAuth(options2) {
5786
+ const connections = loadConnections();
5787
+ if (options2.list) {
5788
+ if (connections.length === 0) {
5789
+ console.log("No RavenDB connections configured.");
5790
+ return;
5791
+ }
5792
+ for (const c of connections) {
5793
+ console.log(
5794
+ `${chalk60.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`
5795
+ );
5796
+ }
5797
+ return;
5798
+ }
5799
+ if (options2.remove) {
5800
+ const filtered = connections.filter((c) => c.name !== options2.remove);
5801
+ if (filtered.length === connections.length) {
5802
+ console.error(chalk60.red(`Connection "${options2.remove}" not found.`));
5803
+ process.exit(1);
5804
+ }
5805
+ saveConnections(filtered);
5806
+ console.log(`Removed connection "${options2.remove}".`);
5807
+ return;
5808
+ }
5809
+ const isFirst = connections.length === 0;
5810
+ const newConnection = await promptConnection(connections.map((c) => c.name));
5811
+ connections.push(newConnection);
5812
+ saveConnections(connections);
5813
+ if (isFirst) {
5814
+ ravendbSetConnection(newConnection.name);
5815
+ }
5816
+ console.log(`Connection "${newConnection.name}" saved.`);
5817
+ }
5818
+
5819
+ // src/commands/ravendb/ravendbCollections.ts
5820
+ import chalk64 from "chalk";
5821
+
5822
+ // src/commands/ravendb/ravenFetch.ts
5823
+ import chalk62 from "chalk";
5824
+
5825
+ // src/commands/ravendb/getAccessToken.ts
5826
+ var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
5827
+ var TOKEN_CACHE_MS = 50 * 60 * 1e3;
5828
+ var tokenCache = /* @__PURE__ */ new Map();
5829
+ function clearCachedToken(apiKey) {
5830
+ tokenCache.delete(apiKey);
5831
+ }
5832
+ async function getAccessToken(apiKey) {
5833
+ const now = Date.now();
5834
+ const cached2 = tokenCache.get(apiKey);
5835
+ if (cached2 && now < cached2.expiry) {
5836
+ return cached2.token;
5837
+ }
5838
+ const response = await fetch(OAUTH_URL, {
5839
+ method: "GET",
5840
+ headers: {
5841
+ "Api-Key": apiKey,
5842
+ grant_type: "client_credentials"
5843
+ }
5844
+ });
5845
+ if (!response.ok) {
5846
+ const errorText = await response.text();
5847
+ throw new Error(
5848
+ `Failed to get access token: ${response.status} ${response.statusText}
5849
+ ${errorText}`
5850
+ );
5851
+ }
5852
+ const tokenData = await response.json();
5853
+ const token = JSON.stringify(tokenData);
5854
+ tokenCache.set(apiKey, { token, expiry: now + TOKEN_CACHE_MS });
5855
+ return token;
5856
+ }
5857
+
5858
+ // src/commands/ravendb/resolveOpSecret.ts
5859
+ import { execSync as execSync30 } from "child_process";
5860
+ import chalk61 from "chalk";
5861
+ function resolveOpSecret(reference) {
5862
+ if (!reference.startsWith("op://")) {
5863
+ console.error(chalk61.red(`Invalid secret reference: must start with op://`));
5864
+ process.exit(1);
5865
+ }
5866
+ try {
5867
+ return execSync30(`op read "${reference}"`, {
5868
+ encoding: "utf-8",
5869
+ stdio: ["pipe", "pipe", "pipe"]
5870
+ }).trim();
5871
+ } catch {
5872
+ console.error(
5873
+ chalk61.red(
5874
+ "Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
5875
+ )
5876
+ );
5877
+ process.exit(1);
5878
+ }
5879
+ }
5880
+
5881
+ // src/commands/ravendb/ravenFetch.ts
5882
+ async function ravenFetch(connection, path42) {
5883
+ const apiKey = resolveOpSecret(connection.apiKeyRef);
5884
+ let accessToken = await getAccessToken(apiKey);
5885
+ const url = `${connection.url}${path42}`;
5886
+ const headers = {
5887
+ Authorization: `Bearer ${accessToken}`,
5888
+ "Content-Type": "application/json"
5889
+ };
5890
+ let response = await fetch(url, { headers });
5891
+ if (response.status === 401) {
5892
+ clearCachedToken(apiKey);
5893
+ accessToken = await getAccessToken(apiKey);
5894
+ headers.Authorization = `Bearer ${accessToken}`;
5895
+ response = await fetch(url, { headers });
5896
+ }
5897
+ if (!response.ok) {
5898
+ const body = await response.text();
5899
+ console.error(
5900
+ chalk62.red(`RavenDB error: ${response.status} ${response.statusText}`)
5901
+ );
5902
+ console.error(body.substring(0, 500));
5903
+ process.exit(1);
5904
+ }
5905
+ return response.json();
5906
+ }
5907
+
5908
+ // src/commands/ravendb/resolveConnection.ts
5909
+ import chalk63 from "chalk";
5910
+ function loadRavendb() {
5911
+ const raw = loadGlobalConfigRaw();
5912
+ const ravendb = raw.ravendb;
5913
+ return {
5914
+ connections: ravendb?.connections ?? [],
5915
+ defaultConnection: ravendb?.defaultConnection
5916
+ };
5917
+ }
5918
+ function resolveConnection(name) {
5919
+ const { connections, defaultConnection } = loadRavendb();
5920
+ const connectionName = name ?? defaultConnection;
5921
+ if (!connectionName) {
5922
+ console.error(
5923
+ chalk63.red(
5924
+ "No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
5925
+ )
5926
+ );
5927
+ process.exit(1);
5928
+ }
5929
+ const connection = connections.find((c) => c.name === connectionName);
5930
+ if (!connection) {
5931
+ console.error(chalk63.red(`Connection "${connectionName}" not found.`));
5932
+ console.error(
5933
+ `Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
5934
+ );
5935
+ console.error("Run assist ravendb auth to add a connection.");
5936
+ process.exit(1);
5937
+ }
5938
+ return connection;
5939
+ }
5940
+ function resolveArgs(first, second) {
5941
+ const { connections } = loadRavendb();
5942
+ const isConnection = first && connections.some((c) => c.name === first);
5943
+ if (isConnection) {
5944
+ return { connection: resolveConnection(first), collection: second };
5945
+ }
5946
+ return { connection: resolveConnection(void 0), collection: first };
5947
+ }
5948
+
5949
+ // src/commands/ravendb/ravendbCollections.ts
5950
+ async function ravendbCollections(connectionName) {
5951
+ const connection = resolveConnection(connectionName);
5952
+ const data = await ravenFetch(
5953
+ connection,
5954
+ `/databases/${encodeURIComponent(connection.database)}/collections/stats`
5955
+ );
5956
+ const collections = data.Collections ?? [];
5957
+ if (collections.length === 0) {
5958
+ console.log("No collections found.");
5959
+ return;
5960
+ }
5961
+ for (const c of collections) {
5962
+ console.log(`${chalk64.bold(c.Name)} ${c.CountOfDocuments} docs`);
5963
+ }
5964
+ }
5965
+
5966
+ // src/commands/ravendb/ravendbQuery.ts
5967
+ import chalk66 from "chalk";
5968
+
5969
+ // src/commands/ravendb/fetchAllPages.ts
5970
+ import chalk65 from "chalk";
5971
+
5972
+ // src/commands/ravendb/buildQueryPath.ts
5973
+ function buildQueryPath(opts) {
5974
+ const db = encodeURIComponent(opts.db);
5975
+ let path42;
5976
+ if (opts.collection) {
5977
+ path42 = `/databases/${db}/indexes/dynamic/${encodeURIComponent(opts.collection)}?start=${opts.start}&pageSize=${opts.pageSize}&sort=${encodeURIComponent(opts.sort)}`;
5978
+ } else {
5979
+ path42 = `/databases/${db}/queries?start=${opts.start}&pageSize=${opts.pageSize}`;
5980
+ }
5981
+ if (opts.query) {
5982
+ path42 += `&query=${encodeURIComponent(opts.query)}`;
5983
+ }
5984
+ return path42;
5985
+ }
5986
+
5987
+ // src/commands/ravendb/fetchAllPages.ts
5988
+ async function fetchAllPages(connection, opts) {
5989
+ const allResults = [];
5990
+ let start3 = 0;
5991
+ while (true) {
5992
+ const effectivePageSize = opts.limit !== void 0 ? Math.min(opts.pageSize, opts.limit - allResults.length) : opts.pageSize;
5993
+ const path42 = buildQueryPath({
5994
+ db: connection.database,
5995
+ collection: opts.collection,
5996
+ start: start3,
5997
+ pageSize: effectivePageSize,
5998
+ sort: opts.sort,
5999
+ query: opts.query
6000
+ });
6001
+ const data = await ravenFetch(connection, path42);
6002
+ const results = data.Results ?? [];
6003
+ const totalResults = data.TotalResults ?? 0;
6004
+ if (results.length === 0) break;
6005
+ allResults.push(...results);
6006
+ start3 += results.length;
6007
+ process.stderr.write(
6008
+ `\r${chalk65.dim(`Fetched ${allResults.length}/${totalResults}`)}`
6009
+ );
6010
+ if (start3 >= totalResults) break;
6011
+ if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
6012
+ }
6013
+ if (allResults.length > 0) {
6014
+ process.stderr.write("\n");
6015
+ }
6016
+ return allResults;
6017
+ }
6018
+
6019
+ // src/commands/ravendb/ravendbQuery.ts
6020
+ async function ravendbQuery(connectionName, collection, options2) {
6021
+ const resolved = resolveArgs(connectionName, collection);
6022
+ if (!resolved.collection && !options2.query) {
6023
+ console.error(chalk66.red("Provide a collection name or --query filter."));
6024
+ process.exit(1);
6025
+ }
6026
+ const { collection: col } = resolved;
6027
+ const connection = resolved.connection;
6028
+ const allResults = await fetchAllPages(connection, {
6029
+ collection: col,
6030
+ pageSize: Number.parseInt(options2.pageSize ?? "25", 10),
6031
+ sort: options2.sort ?? "-@metadata.Last-Modified",
6032
+ query: options2.query,
6033
+ limit: options2.limit ? Number.parseInt(options2.limit, 10) : void 0
5619
6034
  });
6035
+ console.log(JSON.stringify(allResults, null, 2));
6036
+ }
6037
+
6038
+ // src/commands/registerRavendb.ts
6039
+ function registerRavendb(program2) {
6040
+ const cmd = program2.command("ravendb").description("RavenDB query utilities");
6041
+ cmd.command("auth").description("Configure a named RavenDB connection").option("--list", "List configured connections").option("--remove <name>", "Remove a configured connection").action((options2) => ravendbAuth(options2));
6042
+ cmd.command("set-connection <name>").description("Set the default connection").action((name) => ravendbSetConnection(name));
6043
+ cmd.command("query [connection] [collection]").description("Query a RavenDB collection").option("--page-size <n>", "Documents per page", "25").option(
6044
+ "--sort <field>",
6045
+ "Sort field (prefix - for descending)",
6046
+ "-@metadata.Last-Modified"
6047
+ ).option("--query <lucene>", "Lucene filter query").option("--limit <n>", "Max total documents to fetch").action(
6048
+ (connection, collection, options2) => ravendbQuery(connection, collection, options2)
6049
+ );
6050
+ cmd.command("collections [connection]").description("List collections in a RavenDB database").action((connection) => ravendbCollections(connection));
5620
6051
  }
5621
6052
 
5622
6053
  // src/commands/refactor/check/index.ts
5623
6054
  import { spawn as spawn3 } from "child_process";
5624
- import * as path26 from "path";
6055
+ import * as path25 from "path";
5625
6056
 
5626
6057
  // src/commands/refactor/logViolations.ts
5627
- import chalk55 from "chalk";
6058
+ import chalk67 from "chalk";
5628
6059
  var DEFAULT_MAX_LINES = 100;
5629
6060
  function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
5630
6061
  if (violations.length === 0) {
@@ -5633,43 +6064,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
5633
6064
  }
5634
6065
  return;
5635
6066
  }
5636
- console.error(chalk55.red(`
6067
+ console.error(chalk67.red(`
5637
6068
  Refactor check failed:
5638
6069
  `));
5639
- console.error(chalk55.red(` The following files exceed ${maxLines} lines:
6070
+ console.error(chalk67.red(` The following files exceed ${maxLines} lines:
5640
6071
  `));
5641
6072
  for (const violation of violations) {
5642
- console.error(chalk55.red(` ${violation.file} (${violation.lines} lines)`));
6073
+ console.error(chalk67.red(` ${violation.file} (${violation.lines} lines)`));
5643
6074
  }
5644
6075
  console.error(
5645
- chalk55.yellow(
6076
+ chalk67.yellow(
5646
6077
  `
5647
6078
  Each file needs to be sensibly refactored, or if there is no sensible
5648
6079
  way to refactor it, ignore it with:
5649
6080
  `
5650
6081
  )
5651
6082
  );
5652
- console.error(chalk55.gray(` assist refactor ignore <file>
6083
+ console.error(chalk67.gray(` assist refactor ignore <file>
5653
6084
  `));
5654
6085
  if (process.env.CLAUDECODE) {
5655
- console.error(chalk55.cyan(`
6086
+ console.error(chalk67.cyan(`
5656
6087
  ## Extracting Code to New Files
5657
6088
  `));
5658
6089
  console.error(
5659
- chalk55.cyan(
6090
+ chalk67.cyan(
5660
6091
  ` When extracting logic from one file to another, consider where the extracted code belongs:
5661
6092
  `
5662
6093
  )
5663
6094
  );
5664
6095
  console.error(
5665
- chalk55.cyan(
6096
+ chalk67.cyan(
5666
6097
  ` 1. Keep related logic together: If the extracted code is tightly coupled to the
5667
6098
  original file's domain, create a new folder containing both the original and extracted files.
5668
6099
  `
5669
6100
  )
5670
6101
  );
5671
6102
  console.error(
5672
- chalk55.cyan(
6103
+ chalk67.cyan(
5673
6104
  ` 2. Share common utilities: If the extracted code can be reused across multiple
5674
6105
  domains, move it to a common/shared folder.
5675
6106
  `
@@ -5679,18 +6110,18 @@ Refactor check failed:
5679
6110
  }
5680
6111
 
5681
6112
  // src/commands/refactor/check/getViolations/index.ts
5682
- import { execSync as execSync29 } from "child_process";
5683
- import fs17 from "fs";
6113
+ import { execSync as execSync31 } from "child_process";
6114
+ import fs16 from "fs";
5684
6115
  import { minimatch as minimatch4 } from "minimatch";
5685
6116
 
5686
6117
  // src/commands/refactor/check/getViolations/getIgnoredFiles.ts
5687
- import fs16 from "fs";
6118
+ import fs15 from "fs";
5688
6119
  var REFACTOR_YML_PATH = "refactor.yml";
5689
6120
  function parseRefactorYml() {
5690
- if (!fs16.existsSync(REFACTOR_YML_PATH)) {
6121
+ if (!fs15.existsSync(REFACTOR_YML_PATH)) {
5691
6122
  return [];
5692
6123
  }
5693
- const content = fs16.readFileSync(REFACTOR_YML_PATH, "utf-8");
6124
+ const content = fs15.readFileSync(REFACTOR_YML_PATH, "utf-8");
5694
6125
  const entries = [];
5695
6126
  const lines = content.split("\n");
5696
6127
  let currentEntry = {};
@@ -5720,7 +6151,7 @@ function getIgnoredFiles() {
5720
6151
 
5721
6152
  // src/commands/refactor/check/getViolations/index.ts
5722
6153
  function countLines(filePath) {
5723
- const content = fs17.readFileSync(filePath, "utf-8");
6154
+ const content = fs16.readFileSync(filePath, "utf-8");
5724
6155
  return content.split("\n").length;
5725
6156
  }
5726
6157
  function getGitFiles(options2) {
@@ -5729,7 +6160,7 @@ function getGitFiles(options2) {
5729
6160
  }
5730
6161
  const files = /* @__PURE__ */ new Set();
5731
6162
  if (options2.staged || options2.modified) {
5732
- const staged = execSync29("git diff --cached --name-only", {
6163
+ const staged = execSync31("git diff --cached --name-only", {
5733
6164
  encoding: "utf-8"
5734
6165
  });
5735
6166
  for (const file of staged.trim().split("\n").filter(Boolean)) {
@@ -5737,7 +6168,7 @@ function getGitFiles(options2) {
5737
6168
  }
5738
6169
  }
5739
6170
  if (options2.unstaged || options2.modified) {
5740
- const unstaged = execSync29("git diff --name-only", { encoding: "utf-8" });
6171
+ const unstaged = execSync31("git diff --name-only", { encoding: "utf-8" });
5741
6172
  for (const file of unstaged.trim().split("\n").filter(Boolean)) {
5742
6173
  files.add(file);
5743
6174
  }
@@ -5798,7 +6229,7 @@ ${failed.length} verify script(s) failed:`);
5798
6229
  async function runVerifyQuietly() {
5799
6230
  const result = findPackageJsonWithVerifyScripts(process.cwd());
5800
6231
  if (!result) return true;
5801
- const packageDir = path26.dirname(result.packageJsonPath);
6232
+ const packageDir = path25.dirname(result.packageJsonPath);
5802
6233
  const results = await Promise.all(
5803
6234
  result.verifyScripts.map((script) => runScript(script, packageDir))
5804
6235
  );
@@ -5824,64 +6255,64 @@ async function check(pattern2, options2) {
5824
6255
  }
5825
6256
 
5826
6257
  // src/commands/refactor/ignore.ts
5827
- import fs18 from "fs";
5828
- import chalk56 from "chalk";
6258
+ import fs17 from "fs";
6259
+ import chalk68 from "chalk";
5829
6260
  var REFACTOR_YML_PATH2 = "refactor.yml";
5830
6261
  function ignore(file) {
5831
- if (!fs18.existsSync(file)) {
5832
- console.error(chalk56.red(`Error: File does not exist: ${file}`));
6262
+ if (!fs17.existsSync(file)) {
6263
+ console.error(chalk68.red(`Error: File does not exist: ${file}`));
5833
6264
  process.exit(1);
5834
6265
  }
5835
- const content = fs18.readFileSync(file, "utf-8");
6266
+ const content = fs17.readFileSync(file, "utf-8");
5836
6267
  const lineCount = content.split("\n").length;
5837
6268
  const maxLines = lineCount + 10;
5838
6269
  const entry = `- file: ${file}
5839
6270
  maxLines: ${maxLines}
5840
6271
  `;
5841
- if (fs18.existsSync(REFACTOR_YML_PATH2)) {
5842
- const existing = fs18.readFileSync(REFACTOR_YML_PATH2, "utf-8");
5843
- fs18.writeFileSync(REFACTOR_YML_PATH2, existing + entry);
6272
+ if (fs17.existsSync(REFACTOR_YML_PATH2)) {
6273
+ const existing = fs17.readFileSync(REFACTOR_YML_PATH2, "utf-8");
6274
+ fs17.writeFileSync(REFACTOR_YML_PATH2, existing + entry);
5844
6275
  } else {
5845
- fs18.writeFileSync(REFACTOR_YML_PATH2, entry);
6276
+ fs17.writeFileSync(REFACTOR_YML_PATH2, entry);
5846
6277
  }
5847
6278
  console.log(
5848
- chalk56.green(
6279
+ chalk68.green(
5849
6280
  `Added ${file} to refactor ignore list (max ${maxLines} lines)`
5850
6281
  )
5851
6282
  );
5852
6283
  }
5853
6284
 
5854
6285
  // src/commands/refactor/rename/index.ts
5855
- import path27 from "path";
5856
- import chalk57 from "chalk";
6286
+ import path26 from "path";
6287
+ import chalk69 from "chalk";
5857
6288
  import { Project as Project2 } from "ts-morph";
5858
6289
  async function rename(source, destination, options2 = {}) {
5859
- const sourcePath = path27.resolve(source);
5860
- const destPath = path27.resolve(destination);
6290
+ const sourcePath = path26.resolve(source);
6291
+ const destPath = path26.resolve(destination);
5861
6292
  const cwd = process.cwd();
5862
- const relSource = path27.relative(cwd, sourcePath);
5863
- const relDest = path27.relative(cwd, destPath);
6293
+ const relSource = path26.relative(cwd, sourcePath);
6294
+ const relDest = path26.relative(cwd, destPath);
5864
6295
  const project = new Project2({
5865
- tsConfigFilePath: path27.resolve("tsconfig.json")
6296
+ tsConfigFilePath: path26.resolve("tsconfig.json")
5866
6297
  });
5867
6298
  const sourceFile = project.getSourceFile(sourcePath);
5868
6299
  if (!sourceFile) {
5869
- console.log(chalk57.red(`File not found in project: ${source}`));
6300
+ console.log(chalk69.red(`File not found in project: ${source}`));
5870
6301
  process.exit(1);
5871
6302
  }
5872
- console.log(chalk57.bold(`Rename: ${relSource} \u2192 ${relDest}`));
6303
+ console.log(chalk69.bold(`Rename: ${relSource} \u2192 ${relDest}`));
5873
6304
  if (options2.apply) {
5874
6305
  sourceFile.move(destPath);
5875
6306
  await project.save();
5876
- console.log(chalk57.green("Done"));
6307
+ console.log(chalk69.green("Done"));
5877
6308
  } else {
5878
- console.log(chalk57.dim("Dry run. Use --apply to execute."));
6309
+ console.log(chalk69.dim("Dry run. Use --apply to execute."));
5879
6310
  }
5880
6311
  }
5881
6312
 
5882
6313
  // src/commands/refactor/renameSymbol/index.ts
5883
- import path29 from "path";
5884
- import chalk58 from "chalk";
6314
+ import path28 from "path";
6315
+ import chalk70 from "chalk";
5885
6316
  import { Project as Project3 } from "ts-morph";
5886
6317
 
5887
6318
  // src/commands/refactor/renameSymbol/findSymbol.ts
@@ -5909,12 +6340,12 @@ function findSymbol(sourceFile, symbolName) {
5909
6340
  }
5910
6341
 
5911
6342
  // src/commands/refactor/renameSymbol/groupReferences.ts
5912
- import path28 from "path";
6343
+ import path27 from "path";
5913
6344
  function groupReferences(symbol, cwd) {
5914
6345
  const refs = symbol.findReferencesAsNodes();
5915
6346
  const grouped = /* @__PURE__ */ new Map();
5916
6347
  for (const ref of refs) {
5917
- const refFile = path28.relative(cwd, ref.getSourceFile().getFilePath());
6348
+ const refFile = path27.relative(cwd, ref.getSourceFile().getFilePath());
5918
6349
  const lines = grouped.get(refFile) ?? [];
5919
6350
  if (!grouped.has(refFile)) grouped.set(refFile, lines);
5920
6351
  lines.push(ref.getStartLineNumber());
@@ -5924,47 +6355,47 @@ function groupReferences(symbol, cwd) {
5924
6355
 
5925
6356
  // src/commands/refactor/renameSymbol/index.ts
5926
6357
  async function renameSymbol(file, oldName, newName, options2 = {}) {
5927
- const filePath = path29.resolve(file);
5928
- const tsConfigPath = path29.resolve("tsconfig.json");
6358
+ const filePath = path28.resolve(file);
6359
+ const tsConfigPath = path28.resolve("tsconfig.json");
5929
6360
  const cwd = process.cwd();
5930
6361
  const project = new Project3({ tsConfigFilePath: tsConfigPath });
5931
6362
  const sourceFile = project.getSourceFile(filePath);
5932
6363
  if (!sourceFile) {
5933
- console.log(chalk58.red(`File not found in project: ${file}`));
6364
+ console.log(chalk70.red(`File not found in project: ${file}`));
5934
6365
  process.exit(1);
5935
6366
  }
5936
6367
  const symbol = findSymbol(sourceFile, oldName);
5937
6368
  if (!symbol) {
5938
- console.log(chalk58.red(`Symbol "${oldName}" not found in ${file}`));
6369
+ console.log(chalk70.red(`Symbol "${oldName}" not found in ${file}`));
5939
6370
  process.exit(1);
5940
6371
  }
5941
6372
  const grouped = groupReferences(symbol, cwd);
5942
6373
  const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
5943
6374
  console.log(
5944
- chalk58.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
6375
+ chalk70.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
5945
6376
  `)
5946
6377
  );
5947
6378
  for (const [refFile, lines] of grouped) {
5948
6379
  console.log(
5949
- ` ${chalk58.dim(refFile)}: lines ${chalk58.cyan(lines.join(", "))}`
6380
+ ` ${chalk70.dim(refFile)}: lines ${chalk70.cyan(lines.join(", "))}`
5950
6381
  );
5951
6382
  }
5952
6383
  if (options2.apply) {
5953
6384
  symbol.rename(newName);
5954
6385
  await project.save();
5955
- console.log(chalk58.green(`
6386
+ console.log(chalk70.green(`
5956
6387
  Renamed ${oldName} \u2192 ${newName}`));
5957
6388
  } else {
5958
- console.log(chalk58.dim("\nDry run. Use --apply to execute."));
6389
+ console.log(chalk70.dim("\nDry run. Use --apply to execute."));
5959
6390
  }
5960
6391
  }
5961
6392
 
5962
6393
  // src/commands/refactor/restructure/index.ts
5963
- import path38 from "path";
5964
- import chalk61 from "chalk";
6394
+ import path37 from "path";
6395
+ import chalk73 from "chalk";
5965
6396
 
5966
6397
  // src/commands/refactor/restructure/buildImportGraph/index.ts
5967
- import path30 from "path";
6398
+ import path29 from "path";
5968
6399
  import ts7 from "typescript";
5969
6400
 
5970
6401
  // src/commands/refactor/restructure/buildImportGraph/getImportSpecifiers.ts
@@ -5991,7 +6422,7 @@ function loadParsedConfig(tsConfigPath) {
5991
6422
  return ts7.parseJsonConfigFileContent(
5992
6423
  configFile.config,
5993
6424
  ts7.sys,
5994
- path30.dirname(tsConfigPath)
6425
+ path29.dirname(tsConfigPath)
5995
6426
  );
5996
6427
  }
5997
6428
  function addToSetMap(map, key, value) {
@@ -6007,7 +6438,7 @@ function resolveImport(specifier, filePath, options2) {
6007
6438
  const resolved = ts7.resolveModuleName(specifier, filePath, options2, ts7.sys);
6008
6439
  const resolvedPath = resolved.resolvedModule?.resolvedFileName;
6009
6440
  if (!resolvedPath || resolvedPath.includes("node_modules")) return null;
6010
- return path30.resolve(resolvedPath);
6441
+ return path29.resolve(resolvedPath);
6011
6442
  }
6012
6443
  function buildImportGraph(candidateFiles, tsConfigPath) {
6013
6444
  const parsed = loadParsedConfig(tsConfigPath);
@@ -6016,7 +6447,7 @@ function buildImportGraph(candidateFiles, tsConfigPath) {
6016
6447
  const importedBy = /* @__PURE__ */ new Map();
6017
6448
  const imports = /* @__PURE__ */ new Map();
6018
6449
  for (const sourceFile of program2.getSourceFiles()) {
6019
- const filePath = path30.resolve(sourceFile.fileName);
6450
+ const filePath = path29.resolve(sourceFile.fileName);
6020
6451
  if (filePath.includes("node_modules")) continue;
6021
6452
  for (const specifier of getImportSpecifiers(sourceFile)) {
6022
6453
  const absTarget = resolveImport(specifier, filePath, parsed.options);
@@ -6030,12 +6461,12 @@ function buildImportGraph(candidateFiles, tsConfigPath) {
6030
6461
  }
6031
6462
 
6032
6463
  // src/commands/refactor/restructure/clusterDirectories.ts
6033
- import path31 from "path";
6464
+ import path30 from "path";
6034
6465
  function clusterDirectories(graph) {
6035
6466
  const dirImportedBy = /* @__PURE__ */ new Map();
6036
6467
  for (const edge of graph.edges) {
6037
- const sourceDir = path31.dirname(edge.source);
6038
- const targetDir = path31.dirname(edge.target);
6468
+ const sourceDir = path30.dirname(edge.source);
6469
+ const targetDir = path30.dirname(edge.target);
6039
6470
  if (sourceDir === targetDir) continue;
6040
6471
  if (!graph.files.has(edge.target)) continue;
6041
6472
  const existing = dirImportedBy.get(targetDir) ?? /* @__PURE__ */ new Set();
@@ -6063,20 +6494,20 @@ function clusterDirectories(graph) {
6063
6494
  return clusters;
6064
6495
  }
6065
6496
  function isAncestor(ancestor, descendant) {
6066
- const rel = path31.relative(ancestor, descendant);
6497
+ const rel = path30.relative(ancestor, descendant);
6067
6498
  return !rel.startsWith("..") && rel !== "";
6068
6499
  }
6069
6500
 
6070
6501
  // src/commands/refactor/restructure/clusterFiles.ts
6071
- import path32 from "path";
6502
+ import path31 from "path";
6072
6503
  function findRootParent(file, importedBy, visited) {
6073
6504
  const importers = importedBy.get(file);
6074
6505
  if (!importers || importers.size !== 1) return file;
6075
6506
  const parent = [...importers][0];
6076
- const parentDir = path32.dirname(parent);
6077
- const fileDir = path32.dirname(file);
6507
+ const parentDir = path31.dirname(parent);
6508
+ const fileDir = path31.dirname(file);
6078
6509
  if (parentDir !== fileDir) return file;
6079
- if (path32.basename(parent, path32.extname(parent)) === "index") return file;
6510
+ if (path31.basename(parent, path31.extname(parent)) === "index") return file;
6080
6511
  if (visited.has(parent)) return file;
6081
6512
  visited.add(parent);
6082
6513
  return findRootParent(parent, importedBy, visited);
@@ -6084,16 +6515,16 @@ function findRootParent(file, importedBy, visited) {
6084
6515
  function clusterFiles(graph) {
6085
6516
  const clusters = /* @__PURE__ */ new Map();
6086
6517
  for (const file of graph.files) {
6087
- const basename7 = path32.basename(file, path32.extname(file));
6518
+ const basename7 = path31.basename(file, path31.extname(file));
6088
6519
  if (basename7 === "index") continue;
6089
6520
  const importers = graph.importedBy.get(file);
6090
6521
  if (!importers || importers.size !== 1) continue;
6091
6522
  const parent = [...importers][0];
6092
6523
  if (!graph.files.has(parent)) continue;
6093
- const parentDir = path32.dirname(parent);
6094
- const fileDir = path32.dirname(file);
6524
+ const parentDir = path31.dirname(parent);
6525
+ const fileDir = path31.dirname(file);
6095
6526
  if (parentDir !== fileDir) continue;
6096
- const parentBasename = path32.basename(parent, path32.extname(parent));
6527
+ const parentBasename = path31.basename(parent, path31.extname(parent));
6097
6528
  if (parentBasename === "index") continue;
6098
6529
  const root = findRootParent(parent, graph.importedBy, /* @__PURE__ */ new Set([file]));
6099
6530
  if (!root || root === file) continue;
@@ -6105,10 +6536,10 @@ function clusterFiles(graph) {
6105
6536
  }
6106
6537
 
6107
6538
  // src/commands/refactor/restructure/computeRewrites/index.ts
6108
- import path33 from "path";
6539
+ import path32 from "path";
6109
6540
 
6110
6541
  // src/commands/refactor/restructure/computeRewrites/applyRewrites.ts
6111
- import fs19 from "fs";
6542
+ import fs18 from "fs";
6112
6543
  function getOrCreateList(map, key) {
6113
6544
  const list4 = map.get(key) ?? [];
6114
6545
  if (!map.has(key)) map.set(key, list4);
@@ -6127,7 +6558,7 @@ function rewriteSpecifier(content, oldSpecifier, newSpecifier) {
6127
6558
  return content.replace(pattern2, `$1${newSpecifier}$2`);
6128
6559
  }
6129
6560
  function applyFileRewrites(file, fileRewrites) {
6130
- let content = fs19.readFileSync(file, "utf-8");
6561
+ let content = fs18.readFileSync(file, "utf-8");
6131
6562
  for (const { oldSpecifier, newSpecifier } of fileRewrites) {
6132
6563
  content = rewriteSpecifier(content, oldSpecifier, newSpecifier);
6133
6564
  }
@@ -6159,7 +6590,7 @@ function normalizeSpecifier(rel) {
6159
6590
  );
6160
6591
  }
6161
6592
  function computeSpecifier(fromFile, toFile) {
6162
- return normalizeSpecifier(path33.relative(path33.dirname(fromFile), toFile));
6593
+ return normalizeSpecifier(path32.relative(path32.dirname(fromFile), toFile));
6163
6594
  }
6164
6595
  function isAffected(edge, moveMap) {
6165
6596
  return moveMap.has(edge.target) || moveMap.has(edge.source);
@@ -6203,51 +6634,51 @@ function computeRewrites(moves, edges, allProjectFiles) {
6203
6634
  }
6204
6635
 
6205
6636
  // src/commands/refactor/restructure/displayPlan.ts
6206
- import path34 from "path";
6207
- import chalk59 from "chalk";
6637
+ import path33 from "path";
6638
+ import chalk71 from "chalk";
6208
6639
  function relPath(filePath) {
6209
- return path34.relative(process.cwd(), filePath);
6640
+ return path33.relative(process.cwd(), filePath);
6210
6641
  }
6211
6642
  function displayMoves(plan) {
6212
6643
  if (plan.moves.length === 0) return;
6213
- console.log(chalk59.bold("\nFile moves:"));
6644
+ console.log(chalk71.bold("\nFile moves:"));
6214
6645
  for (const move of plan.moves) {
6215
6646
  console.log(
6216
- ` ${chalk59.red(relPath(move.from))} \u2192 ${chalk59.green(relPath(move.to))}`
6647
+ ` ${chalk71.red(relPath(move.from))} \u2192 ${chalk71.green(relPath(move.to))}`
6217
6648
  );
6218
- console.log(chalk59.dim(` ${move.reason}`));
6649
+ console.log(chalk71.dim(` ${move.reason}`));
6219
6650
  }
6220
6651
  }
6221
6652
  function displayRewrites(rewrites) {
6222
6653
  if (rewrites.length === 0) return;
6223
6654
  const affectedFiles = new Set(rewrites.map((r) => r.file));
6224
- console.log(chalk59.bold(`
6655
+ console.log(chalk71.bold(`
6225
6656
  Import rewrites (${affectedFiles.size} files):`));
6226
6657
  for (const file of affectedFiles) {
6227
- console.log(` ${chalk59.cyan(relPath(file))}:`);
6658
+ console.log(` ${chalk71.cyan(relPath(file))}:`);
6228
6659
  for (const { oldSpecifier, newSpecifier } of rewrites.filter(
6229
6660
  (r) => r.file === file
6230
6661
  )) {
6231
6662
  console.log(
6232
- ` ${chalk59.red(`"${oldSpecifier}"`)} \u2192 ${chalk59.green(`"${newSpecifier}"`)}`
6663
+ ` ${chalk71.red(`"${oldSpecifier}"`)} \u2192 ${chalk71.green(`"${newSpecifier}"`)}`
6233
6664
  );
6234
6665
  }
6235
6666
  }
6236
6667
  }
6237
6668
  function displayPlan(plan) {
6238
6669
  if (plan.warnings.length > 0) {
6239
- console.log(chalk59.yellow("\nWarnings:"));
6240
- for (const w of plan.warnings) console.log(chalk59.yellow(` ${w}`));
6670
+ console.log(chalk71.yellow("\nWarnings:"));
6671
+ for (const w of plan.warnings) console.log(chalk71.yellow(` ${w}`));
6241
6672
  }
6242
6673
  if (plan.newDirectories.length > 0) {
6243
- console.log(chalk59.bold("\nNew directories:"));
6674
+ console.log(chalk71.bold("\nNew directories:"));
6244
6675
  for (const dir of plan.newDirectories)
6245
- console.log(chalk59.green(` ${dir}/`));
6676
+ console.log(chalk71.green(` ${dir}/`));
6246
6677
  }
6247
6678
  displayMoves(plan);
6248
6679
  displayRewrites(plan.rewrites);
6249
6680
  console.log(
6250
- chalk59.dim(
6681
+ chalk71.dim(
6251
6682
  `
6252
6683
  Summary: ${plan.moves.length} file(s) moved, ${plan.rewrites.length} imports rewritten`
6253
6684
  )
@@ -6255,45 +6686,45 @@ Summary: ${plan.moves.length} file(s) moved, ${plan.rewrites.length} imports rew
6255
6686
  }
6256
6687
 
6257
6688
  // src/commands/refactor/restructure/executePlan.ts
6258
- import fs20 from "fs";
6259
- import path35 from "path";
6260
- import chalk60 from "chalk";
6689
+ import fs19 from "fs";
6690
+ import path34 from "path";
6691
+ import chalk72 from "chalk";
6261
6692
  function executePlan(plan) {
6262
6693
  const updatedContents = applyRewrites(plan.rewrites);
6263
6694
  for (const [file, content] of updatedContents) {
6264
- fs20.writeFileSync(file, content, "utf-8");
6695
+ fs19.writeFileSync(file, content, "utf-8");
6265
6696
  console.log(
6266
- chalk60.cyan(` Rewrote imports in ${path35.relative(process.cwd(), file)}`)
6697
+ chalk72.cyan(` Rewrote imports in ${path34.relative(process.cwd(), file)}`)
6267
6698
  );
6268
6699
  }
6269
6700
  for (const dir of plan.newDirectories) {
6270
- fs20.mkdirSync(dir, { recursive: true });
6271
- console.log(chalk60.green(` Created ${path35.relative(process.cwd(), dir)}/`));
6701
+ fs19.mkdirSync(dir, { recursive: true });
6702
+ console.log(chalk72.green(` Created ${path34.relative(process.cwd(), dir)}/`));
6272
6703
  }
6273
6704
  for (const move of plan.moves) {
6274
- const targetDir = path35.dirname(move.to);
6275
- if (!fs20.existsSync(targetDir)) {
6276
- fs20.mkdirSync(targetDir, { recursive: true });
6705
+ const targetDir = path34.dirname(move.to);
6706
+ if (!fs19.existsSync(targetDir)) {
6707
+ fs19.mkdirSync(targetDir, { recursive: true });
6277
6708
  }
6278
- fs20.renameSync(move.from, move.to);
6709
+ fs19.renameSync(move.from, move.to);
6279
6710
  console.log(
6280
- chalk60.white(
6281
- ` Moved ${path35.relative(process.cwd(), move.from)} \u2192 ${path35.relative(process.cwd(), move.to)}`
6711
+ chalk72.white(
6712
+ ` Moved ${path34.relative(process.cwd(), move.from)} \u2192 ${path34.relative(process.cwd(), move.to)}`
6282
6713
  )
6283
6714
  );
6284
6715
  }
6285
- removeEmptyDirectories(plan.moves.map((m) => path35.dirname(m.from)));
6716
+ removeEmptyDirectories(plan.moves.map((m) => path34.dirname(m.from)));
6286
6717
  }
6287
6718
  function removeEmptyDirectories(dirs) {
6288
6719
  const unique = [...new Set(dirs)];
6289
6720
  for (const dir of unique) {
6290
- if (!fs20.existsSync(dir)) continue;
6291
- const entries = fs20.readdirSync(dir);
6721
+ if (!fs19.existsSync(dir)) continue;
6722
+ const entries = fs19.readdirSync(dir);
6292
6723
  if (entries.length === 0) {
6293
- fs20.rmdirSync(dir);
6724
+ fs19.rmdirSync(dir);
6294
6725
  console.log(
6295
- chalk60.dim(
6296
- ` Removed empty directory ${path35.relative(process.cwd(), dir)}`
6726
+ chalk72.dim(
6727
+ ` Removed empty directory ${path34.relative(process.cwd(), dir)}`
6297
6728
  )
6298
6729
  );
6299
6730
  }
@@ -6301,14 +6732,24 @@ function removeEmptyDirectories(dirs) {
6301
6732
  }
6302
6733
 
6303
6734
  // src/commands/refactor/restructure/planFileMoves/index.ts
6304
- import fs22 from "fs";
6305
- import path37 from "path";
6735
+ import path36 from "path";
6736
+
6737
+ // src/commands/refactor/restructure/planFileMoves/shared.ts
6738
+ import fs20 from "fs";
6739
+ function emptyResult() {
6740
+ return { moves: [], directories: [], warnings: [] };
6741
+ }
6742
+ function checkDirConflict(result, label2, dir) {
6743
+ if (!fs20.existsSync(dir)) return false;
6744
+ result.warnings.push(`Skipping ${label2}: directory ${dir} already exists`);
6745
+ return true;
6746
+ }
6306
6747
 
6307
6748
  // src/commands/refactor/restructure/planFileMoves/planDirectoryMoves.ts
6308
6749
  import fs21 from "fs";
6309
- import path36 from "path";
6750
+ import path35 from "path";
6310
6751
  function collectEntry(results, dir, entry) {
6311
- const full = path36.join(dir, entry.name);
6752
+ const full = path35.join(dir, entry.name);
6312
6753
  const items = entry.isDirectory() ? listFilesRecursive(full) : [full];
6313
6754
  results.push(...items);
6314
6755
  }
@@ -6322,15 +6763,15 @@ function listFilesRecursive(dir) {
6322
6763
  }
6323
6764
  function addDirectoryFileMoves(moves, childDir, newLocation, reason) {
6324
6765
  for (const file of listFilesRecursive(childDir)) {
6325
- const rel = path36.relative(childDir, file);
6326
- moves.push({ from: file, to: path36.join(newLocation, rel), reason });
6766
+ const rel = path35.relative(childDir, file);
6767
+ moves.push({ from: file, to: path35.join(newLocation, rel), reason });
6327
6768
  }
6328
6769
  }
6329
6770
  function resolveChildDest(parentDir, childDir) {
6330
- return path36.join(parentDir, path36.basename(childDir));
6771
+ return path35.join(parentDir, path35.basename(childDir));
6331
6772
  }
6332
6773
  function childMoveReason(parentDir) {
6333
- return `Directory only imported from ${path36.basename(parentDir)}/`;
6774
+ return `Directory only imported from ${path35.basename(parentDir)}/`;
6334
6775
  }
6335
6776
  function registerDirectoryMove(result, childDir, dest, parentDir) {
6336
6777
  result.directories.push(dest);
@@ -6354,32 +6795,24 @@ function planDirectoryMoves(clusters) {
6354
6795
  }
6355
6796
 
6356
6797
  // src/commands/refactor/restructure/planFileMoves/index.ts
6357
- function emptyResult() {
6358
- return { moves: [], directories: [], warnings: [] };
6359
- }
6360
6798
  function childMoveData(child, newDir, parentBase) {
6361
- const to = path37.join(newDir, path37.basename(child));
6799
+ const to = path36.join(newDir, path36.basename(child));
6362
6800
  return { from: child, to, reason: `Only imported by ${parentBase}` };
6363
6801
  }
6364
6802
  function addChildMoves(moves, children, newDir, parentBase) {
6365
6803
  for (const child of children)
6366
6804
  moves.push(childMoveData(child, newDir, parentBase));
6367
6805
  }
6368
- function checkDirConflict(result, label2, dir) {
6369
- if (!fs22.existsSync(dir)) return false;
6370
- result.warnings.push(`Skipping ${label2}: directory ${dir} already exists`);
6371
- return true;
6372
- }
6373
6806
  function getBaseName(filePath) {
6374
- return path37.basename(filePath, path37.extname(filePath));
6807
+ return path36.basename(filePath, path36.extname(filePath));
6375
6808
  }
6376
6809
  function resolveClusterDir(parent) {
6377
- return path37.join(path37.dirname(parent), getBaseName(parent));
6810
+ return path36.join(path36.dirname(parent), getBaseName(parent));
6378
6811
  }
6379
6812
  function createParentMove(parent, newDir) {
6380
6813
  return {
6381
6814
  from: parent,
6382
- to: path37.join(newDir, `index${path37.extname(parent)}`),
6815
+ to: path36.join(newDir, `index${path36.extname(parent)}`),
6383
6816
  reason: `Main module of new ${getBaseName(parent)}/ directory`
6384
6817
  };
6385
6818
  }
@@ -6403,7 +6836,7 @@ function planFileMoves(clusters) {
6403
6836
 
6404
6837
  // src/commands/refactor/restructure/index.ts
6405
6838
  function buildPlan(candidateFiles, tsConfigPath) {
6406
- const candidates = new Set(candidateFiles.map((f) => path38.resolve(f)));
6839
+ const candidates = new Set(candidateFiles.map((f) => path37.resolve(f)));
6407
6840
  const graph = buildImportGraph(candidates, tsConfigPath);
6408
6841
  const allProjectFiles = /* @__PURE__ */ new Set([
6409
6842
  ...graph.importedBy.keys(),
@@ -6423,22 +6856,22 @@ async function restructure(pattern2, options2 = {}) {
6423
6856
  const targetPattern = pattern2 ?? "src";
6424
6857
  const files = findSourceFiles2(targetPattern);
6425
6858
  if (files.length === 0) {
6426
- console.log(chalk61.yellow("No files found matching pattern"));
6859
+ console.log(chalk73.yellow("No files found matching pattern"));
6427
6860
  return;
6428
6861
  }
6429
- const tsConfigPath = path38.resolve("tsconfig.json");
6862
+ const tsConfigPath = path37.resolve("tsconfig.json");
6430
6863
  const plan = buildPlan(files, tsConfigPath);
6431
6864
  if (plan.moves.length === 0) {
6432
- console.log(chalk61.green("No restructuring needed"));
6865
+ console.log(chalk73.green("No restructuring needed"));
6433
6866
  return;
6434
6867
  }
6435
6868
  displayPlan(plan);
6436
6869
  if (options2.apply) {
6437
- console.log(chalk61.bold("\nApplying changes..."));
6870
+ console.log(chalk73.bold("\nApplying changes..."));
6438
6871
  executePlan(plan);
6439
- console.log(chalk61.green("\nRestructuring complete"));
6872
+ console.log(chalk73.green("\nRestructuring complete"));
6440
6873
  } else {
6441
- console.log(chalk61.dim("\nDry run. Use --apply to execute."));
6874
+ console.log(chalk73.dim("\nDry run. Use --apply to execute."));
6442
6875
  }
6443
6876
  }
6444
6877
 
@@ -6653,7 +7086,7 @@ async function fixInvalidDatePrefixes(vttFiles) {
6653
7086
  }
6654
7087
 
6655
7088
  // src/commands/transcript/format/processVttFile/index.ts
6656
- import { existsSync as existsSync26, mkdirSync as mkdirSync7, readFileSync as readFileSync22, writeFileSync as writeFileSync21 } from "fs";
7089
+ import { existsSync as existsSync26, mkdirSync as mkdirSync7, readFileSync as readFileSync22, writeFileSync as writeFileSync22 } from "fs";
6657
7090
  import { basename as basename5, dirname as dirname17, join as join25 } from "path";
6658
7091
 
6659
7092
  // src/commands/transcript/cleanText.ts
@@ -6904,7 +7337,7 @@ function readAndParseCues(inputPath) {
6904
7337
  return processCues(readFileSync22(inputPath, "utf-8"));
6905
7338
  }
6906
7339
  function writeFormatted(outputPath, content) {
6907
- writeFileSync21(outputPath, content, "utf-8");
7340
+ writeFileSync22(outputPath, content, "utf-8");
6908
7341
  console.log(`Written: ${outputPath}`);
6909
7342
  }
6910
7343
  function convertVttToMarkdown(inputPath, outputPath) {
@@ -6986,14 +7419,14 @@ import {
6986
7419
  import { dirname as dirname18, join as join26 } from "path";
6987
7420
 
6988
7421
  // src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
6989
- import chalk62 from "chalk";
7422
+ import chalk74 from "chalk";
6990
7423
  var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
6991
7424
  function validateStagedContent(filename, content) {
6992
7425
  const firstLine = content.split("\n")[0];
6993
7426
  const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
6994
7427
  if (!match) {
6995
7428
  console.error(
6996
- chalk62.red(
7429
+ chalk74.red(
6997
7430
  `Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
6998
7431
  )
6999
7432
  );
@@ -7002,7 +7435,7 @@ function validateStagedContent(filename, content) {
7002
7435
  const contentAfterLink = content.slice(firstLine.length).trim();
7003
7436
  if (!contentAfterLink) {
7004
7437
  console.error(
7005
- chalk62.red(
7438
+ chalk74.red(
7006
7439
  `Staged file ${filename} has no summary content after the transcript link.`
7007
7440
  )
7008
7441
  );
@@ -7202,8 +7635,8 @@ import { mkdirSync as mkdirSync10 } from "fs";
7202
7635
  import { join as join31 } from "path";
7203
7636
 
7204
7637
  // src/commands/voice/checkLockFile.ts
7205
- import { execSync as execSync30 } from "child_process";
7206
- import { existsSync as existsSync31, mkdirSync as mkdirSync9, readFileSync as readFileSync25, writeFileSync as writeFileSync22 } from "fs";
7638
+ import { execSync as execSync32 } from "child_process";
7639
+ import { existsSync as existsSync31, mkdirSync as mkdirSync9, readFileSync as readFileSync25, writeFileSync as writeFileSync23 } from "fs";
7207
7640
  import { join as join30 } from "path";
7208
7641
  function isProcessAlive(pid) {
7209
7642
  try {
@@ -7231,7 +7664,7 @@ function bootstrapVenv() {
7231
7664
  if (existsSync31(getVenvPython())) return;
7232
7665
  console.log("Setting up Python environment...");
7233
7666
  const pythonDir = getPythonDir();
7234
- execSync30(
7667
+ execSync32(
7235
7668
  `uv sync --project "${pythonDir}" --extra runtime --no-install-project`,
7236
7669
  {
7237
7670
  stdio: "inherit",
@@ -7242,7 +7675,7 @@ function bootstrapVenv() {
7242
7675
  function writeLockFile(pid) {
7243
7676
  const lockFile = getLockFile();
7244
7677
  mkdirSync9(join30(lockFile, ".."), { recursive: true });
7245
- writeFileSync22(
7678
+ writeFileSync23(
7246
7679
  lockFile,
7247
7680
  JSON.stringify({
7248
7681
  pid,
@@ -7270,7 +7703,7 @@ function setup() {
7270
7703
 
7271
7704
  // src/commands/voice/start.ts
7272
7705
  import { spawn as spawn4 } from "child_process";
7273
- import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync23 } from "fs";
7706
+ import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync24 } from "fs";
7274
7707
  import { join as join32 } from "path";
7275
7708
 
7276
7709
  // src/commands/voice/buildDaemonEnv.ts
@@ -7299,7 +7732,7 @@ function spawnBackground(python, script, env) {
7299
7732
  console.error("Failed to start voice daemon");
7300
7733
  process.exit(1);
7301
7734
  }
7302
- writeFileSync23(voicePaths.pid, String(pid));
7735
+ writeFileSync24(voicePaths.pid, String(pid));
7303
7736
  writeLockFile(pid);
7304
7737
  console.log(`Voice daemon started (PID ${pid})`);
7305
7738
  }
@@ -7395,14 +7828,14 @@ function registerVoice(program2) {
7395
7828
 
7396
7829
  // src/commands/roam/auth.ts
7397
7830
  import { randomBytes } from "crypto";
7398
- import chalk63 from "chalk";
7831
+ import chalk75 from "chalk";
7399
7832
 
7400
7833
  // src/lib/openBrowser.ts
7401
- import { execSync as execSync31 } from "child_process";
7834
+ import { execSync as execSync33 } from "child_process";
7402
7835
  function tryExec(commands) {
7403
7836
  for (const cmd of commands) {
7404
7837
  try {
7405
- execSync31(cmd);
7838
+ execSync33(cmd);
7406
7839
  return true;
7407
7840
  } catch {
7408
7841
  }
@@ -7570,13 +8003,13 @@ async function auth() {
7570
8003
  saveGlobalConfig(config);
7571
8004
  const state = randomBytes(16).toString("hex");
7572
8005
  console.log(
7573
- chalk63.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
8006
+ chalk75.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
7574
8007
  );
7575
- console.log(chalk63.white("http://localhost:14523/callback\n"));
7576
- console.log(chalk63.blue("Opening browser for authorization..."));
7577
- console.log(chalk63.dim("Waiting for authorization callback..."));
8008
+ console.log(chalk75.white("http://localhost:14523/callback\n"));
8009
+ console.log(chalk75.blue("Opening browser for authorization..."));
8010
+ console.log(chalk75.dim("Waiting for authorization callback..."));
7578
8011
  const { code, redirectUri } = await authorizeInBrowser(clientId, state);
7579
- console.log(chalk63.dim("Exchanging code for tokens..."));
8012
+ console.log(chalk75.dim("Exchanging code for tokens..."));
7580
8013
  const tokens = await exchangeToken({
7581
8014
  code,
7582
8015
  clientId,
@@ -7592,7 +8025,7 @@ async function auth() {
7592
8025
  };
7593
8026
  saveGlobalConfig(config);
7594
8027
  console.log(
7595
- chalk63.green("Roam credentials and tokens saved to ~/.assist.yml")
8028
+ chalk75.green("Roam credentials and tokens saved to ~/.assist.yml")
7596
8029
  );
7597
8030
  }
7598
8031
 
@@ -7639,7 +8072,7 @@ function resolveParams(params, cliArgs) {
7639
8072
  }
7640
8073
 
7641
8074
  // src/commands/run/add.ts
7642
- import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync24 } from "fs";
8075
+ import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync25 } from "fs";
7643
8076
  import { join as join33 } from "path";
7644
8077
  function findAddIndex() {
7645
8078
  const addIndex = process.argv.indexOf("add");
@@ -7657,7 +8090,7 @@ function parseAddArguments() {
7657
8090
  const addIndex = findAddIndex();
7658
8091
  return addIndex === -1 ? null : extractAddArgs(addIndex);
7659
8092
  }
7660
- function buildRunEntry(name, command, args) {
8093
+ function buildRunEntry2(name, command, args) {
7661
8094
  const entry = {
7662
8095
  name,
7663
8096
  command
@@ -7690,7 +8123,7 @@ function getOrInitRunList() {
7690
8123
  function saveNewRunConfig(name, command, args) {
7691
8124
  const { config, runList } = getOrInitRunList();
7692
8125
  ensureNoDuplicate(runList, name);
7693
- runList.push(buildRunEntry(name, command, args));
8126
+ runList.push(buildRunEntry2(name, command, args));
7694
8127
  saveConfig(config);
7695
8128
  }
7696
8129
  function createCommandFile(name) {
@@ -7703,7 +8136,7 @@ description: Run ${name}
7703
8136
  Run \`assist run ${name} $ARGUMENTS 2>&1\`.
7704
8137
  `;
7705
8138
  const filePath = join33(dir, `${name}.md`);
7706
- writeFileSync24(filePath, content);
8139
+ writeFileSync25(filePath, content);
7707
8140
  console.log(`Created command file: ${filePath}`);
7708
8141
  }
7709
8142
  function add3() {
@@ -7780,14 +8213,14 @@ function run2(name, args) {
7780
8213
  }
7781
8214
 
7782
8215
  // src/commands/statusLine.ts
7783
- import chalk64 from "chalk";
8216
+ import chalk76 from "chalk";
7784
8217
  function formatNumber(num) {
7785
8218
  return num.toLocaleString("en-US");
7786
8219
  }
7787
8220
  function colorizePercent(pct) {
7788
8221
  const label2 = `${pct}%`;
7789
- if (pct > 80) return chalk64.red(label2);
7790
- if (pct > 40) return chalk64.yellow(label2);
8222
+ if (pct > 80) return chalk76.red(label2);
8223
+ if (pct > 40) return chalk76.yellow(label2);
7791
8224
  return label2;
7792
8225
  }
7793
8226
  async function statusLine() {
@@ -7805,29 +8238,29 @@ async function statusLine() {
7805
8238
  }
7806
8239
 
7807
8240
  // src/commands/sync.ts
7808
- import * as fs25 from "fs";
8241
+ import * as fs24 from "fs";
7809
8242
  import * as os from "os";
7810
- import * as path41 from "path";
8243
+ import * as path40 from "path";
7811
8244
  import { fileURLToPath as fileURLToPath7 } from "url";
7812
8245
 
7813
8246
  // src/commands/sync/syncClaudeMd.ts
7814
- import * as fs23 from "fs";
7815
- import * as path39 from "path";
7816
- import chalk65 from "chalk";
8247
+ import * as fs22 from "fs";
8248
+ import * as path38 from "path";
8249
+ import chalk77 from "chalk";
7817
8250
  async function syncClaudeMd(claudeDir, targetBase) {
7818
- const source = path39.join(claudeDir, "CLAUDE.md");
7819
- const target = path39.join(targetBase, "CLAUDE.md");
7820
- const sourceContent = fs23.readFileSync(source, "utf-8");
7821
- if (fs23.existsSync(target)) {
7822
- const targetContent = fs23.readFileSync(target, "utf-8");
8251
+ const source = path38.join(claudeDir, "CLAUDE.md");
8252
+ const target = path38.join(targetBase, "CLAUDE.md");
8253
+ const sourceContent = fs22.readFileSync(source, "utf-8");
8254
+ if (fs22.existsSync(target)) {
8255
+ const targetContent = fs22.readFileSync(target, "utf-8");
7823
8256
  if (sourceContent !== targetContent) {
7824
8257
  console.log(
7825
- chalk65.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
8258
+ chalk77.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
7826
8259
  );
7827
8260
  console.log();
7828
8261
  printDiff(targetContent, sourceContent);
7829
8262
  const confirm = await promptConfirm(
7830
- chalk65.red("Overwrite existing CLAUDE.md?"),
8263
+ chalk77.red("Overwrite existing CLAUDE.md?"),
7831
8264
  false
7832
8265
  );
7833
8266
  if (!confirm) {
@@ -7836,21 +8269,21 @@ async function syncClaudeMd(claudeDir, targetBase) {
7836
8269
  }
7837
8270
  }
7838
8271
  }
7839
- fs23.copyFileSync(source, target);
8272
+ fs22.copyFileSync(source, target);
7840
8273
  console.log("Copied CLAUDE.md to ~/.claude/CLAUDE.md");
7841
8274
  }
7842
8275
 
7843
8276
  // src/commands/sync/syncSettings.ts
7844
- import * as fs24 from "fs";
7845
- import * as path40 from "path";
7846
- import chalk66 from "chalk";
8277
+ import * as fs23 from "fs";
8278
+ import * as path39 from "path";
8279
+ import chalk78 from "chalk";
7847
8280
  async function syncSettings(claudeDir, targetBase, options2) {
7848
- const source = path40.join(claudeDir, "settings.json");
7849
- const target = path40.join(targetBase, "settings.json");
7850
- const sourceContent = fs24.readFileSync(source, "utf-8");
8281
+ const source = path39.join(claudeDir, "settings.json");
8282
+ const target = path39.join(targetBase, "settings.json");
8283
+ const sourceContent = fs23.readFileSync(source, "utf-8");
7851
8284
  const mergedContent = JSON.stringify(JSON.parse(sourceContent), null, " ");
7852
- if (fs24.existsSync(target)) {
7853
- const targetContent = fs24.readFileSync(target, "utf-8");
8285
+ if (fs23.existsSync(target)) {
8286
+ const targetContent = fs23.readFileSync(target, "utf-8");
7854
8287
  const normalizedTarget = JSON.stringify(
7855
8288
  JSON.parse(targetContent),
7856
8289
  null,
@@ -7859,14 +8292,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
7859
8292
  if (mergedContent !== normalizedTarget) {
7860
8293
  if (!options2?.yes) {
7861
8294
  console.log(
7862
- chalk66.yellow(
8295
+ chalk78.yellow(
7863
8296
  "\n\u26A0\uFE0F Warning: settings.json differs from existing file"
7864
8297
  )
7865
8298
  );
7866
8299
  console.log();
7867
8300
  printDiff(targetContent, mergedContent);
7868
8301
  const confirm = await promptConfirm(
7869
- chalk66.red("Overwrite existing settings.json?"),
8302
+ chalk78.red("Overwrite existing settings.json?"),
7870
8303
  false
7871
8304
  );
7872
8305
  if (!confirm) {
@@ -7876,43 +8309,43 @@ async function syncSettings(claudeDir, targetBase, options2) {
7876
8309
  }
7877
8310
  }
7878
8311
  }
7879
- fs24.writeFileSync(target, mergedContent);
8312
+ fs23.writeFileSync(target, mergedContent);
7880
8313
  console.log("Copied settings.json to ~/.claude/settings.json");
7881
8314
  }
7882
8315
 
7883
8316
  // src/commands/sync.ts
7884
8317
  var __filename4 = fileURLToPath7(import.meta.url);
7885
- var __dirname7 = path41.dirname(__filename4);
8318
+ var __dirname7 = path40.dirname(__filename4);
7886
8319
  async function sync(options2) {
7887
- const claudeDir = path41.join(__dirname7, "..", "claude");
7888
- const targetBase = path41.join(os.homedir(), ".claude");
8320
+ const claudeDir = path40.join(__dirname7, "..", "claude");
8321
+ const targetBase = path40.join(os.homedir(), ".claude");
7889
8322
  syncCommands(claudeDir, targetBase);
7890
8323
  await syncSettings(claudeDir, targetBase, { yes: options2?.yes });
7891
8324
  await syncClaudeMd(claudeDir, targetBase);
7892
8325
  }
7893
8326
  function syncCommands(claudeDir, targetBase) {
7894
- const sourceDir = path41.join(claudeDir, "commands");
7895
- const targetDir = path41.join(targetBase, "commands");
7896
- fs25.mkdirSync(targetDir, { recursive: true });
7897
- const files = fs25.readdirSync(sourceDir);
8327
+ const sourceDir = path40.join(claudeDir, "commands");
8328
+ const targetDir = path40.join(targetBase, "commands");
8329
+ fs24.mkdirSync(targetDir, { recursive: true });
8330
+ const files = fs24.readdirSync(sourceDir);
7898
8331
  for (const file of files) {
7899
- fs25.copyFileSync(path41.join(sourceDir, file), path41.join(targetDir, file));
8332
+ fs24.copyFileSync(path40.join(sourceDir, file), path40.join(targetDir, file));
7900
8333
  console.log(`Copied ${file} to ${targetDir}`);
7901
8334
  }
7902
8335
  console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
7903
8336
  }
7904
8337
 
7905
8338
  // src/commands/update.ts
7906
- import { execSync as execSync32 } from "child_process";
7907
- import * as path42 from "path";
8339
+ import { execSync as execSync34 } from "child_process";
8340
+ import * as path41 from "path";
7908
8341
  function isGlobalNpmInstall(dir) {
7909
8342
  try {
7910
- const resolved = path42.resolve(dir);
7911
- if (resolved.split(path42.sep).includes("node_modules")) {
8343
+ const resolved = path41.resolve(dir);
8344
+ if (resolved.split(path41.sep).includes("node_modules")) {
7912
8345
  return true;
7913
8346
  }
7914
- const globalPrefix = execSync32("npm prefix -g", { stdio: "pipe" }).toString().trim();
7915
- return resolved.toLowerCase().startsWith(path42.resolve(globalPrefix).toLowerCase());
8347
+ const globalPrefix = execSync34("npm prefix -g", { stdio: "pipe" }).toString().trim();
8348
+ return resolved.toLowerCase().startsWith(path41.resolve(globalPrefix).toLowerCase());
7916
8349
  } catch {
7917
8350
  return false;
7918
8351
  }
@@ -7922,18 +8355,18 @@ async function update() {
7922
8355
  console.log(`Assist is installed at: ${installDir}`);
7923
8356
  if (isGitRepo(installDir)) {
7924
8357
  console.log("Detected git repo installation, pulling latest...");
7925
- execSync32("git pull", { cwd: installDir, stdio: "inherit" });
8358
+ execSync34("git pull", { cwd: installDir, stdio: "inherit" });
7926
8359
  console.log("Installing dependencies...");
7927
- execSync32("npm i", { cwd: installDir, stdio: "inherit" });
8360
+ execSync34("npm i", { cwd: installDir, stdio: "inherit" });
7928
8361
  console.log("Building...");
7929
- execSync32("npm run build", { cwd: installDir, stdio: "inherit" });
8362
+ execSync34("npm run build", { cwd: installDir, stdio: "inherit" });
7930
8363
  console.log("Syncing commands...");
7931
- execSync32("assist sync", { stdio: "inherit" });
8364
+ execSync34("assist sync", { stdio: "inherit" });
7932
8365
  } else if (isGlobalNpmInstall(installDir)) {
7933
8366
  console.log("Detected global npm installation, updating...");
7934
- execSync32("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
8367
+ execSync34("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
7935
8368
  console.log("Syncing commands...");
7936
- execSync32("assist sync", { stdio: "inherit" });
8369
+ execSync34("assist sync", { stdio: "inherit" });
7937
8370
  } else {
7938
8371
  console.error(
7939
8372
  "Could not determine installation method. Expected a git repo or global npm install."
@@ -7982,6 +8415,7 @@ registerDeploy(program);
7982
8415
  registerComplexity(program);
7983
8416
  registerNetframework(program);
7984
8417
  registerNews(program);
8418
+ registerRavendb(program);
7985
8419
  registerTranscript(program);
7986
8420
  registerVoice(program);
7987
8421
  program.parse();