@staff0rd/assist 0.49.0 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +286 -260
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import { Command } from "commander";
7
7
  // package.json
8
8
  var package_default = {
9
9
  name: "@staff0rd/assist",
10
- version: "0.49.0",
10
+ version: "0.50.0",
11
11
  type: "module",
12
12
  main: "dist/index.js",
13
13
  bin: {
@@ -222,9 +222,9 @@ function isTraversable(value) {
222
222
  function stepInto(current, key) {
223
223
  return isTraversable(current) ? current[key] : void 0;
224
224
  }
225
- function getNestedValue(obj, path29) {
225
+ function getNestedValue(obj, path30) {
226
226
  let current = obj;
227
- for (const key of path29.split(".")) current = stepInto(current, key);
227
+ for (const key of path30.split(".")) current = stepInto(current, key);
228
228
  return current;
229
229
  }
230
230
  function isPlainObject(val) {
@@ -241,8 +241,8 @@ function buildNestedPath(root, keys) {
241
241
  }
242
242
  return current;
243
243
  }
244
- function setNestedValue(obj, path29, value) {
245
- const keys = path29.split(".");
244
+ function setNestedValue(obj, path30, value) {
245
+ const keys = path30.split(".");
246
246
  const result = { ...obj };
247
247
  buildNestedPath(result, keys)[keys[keys.length - 1]] = value;
248
248
  return result;
@@ -311,7 +311,7 @@ function configList() {
311
311
  }
312
312
 
313
313
  // src/commands/verify/init/index.ts
314
- import chalk14 from "chalk";
314
+ import chalk15 from "chalk";
315
315
 
316
316
  // src/shared/promptMultiselect.ts
317
317
  import chalk3 from "chalk";
@@ -387,7 +387,8 @@ var expectedScripts = {
387
387
  "verify:lint": "biome check --write .",
388
388
  "verify:duplicate-code": "jscpd --format 'typescript,tsx' --exitCode 1 --ignore '**/*.test.*' -r consoleFull src",
389
389
  "verify:test": "vitest run --reporter=dot --silent",
390
- "verify:hardcoded-colors": "assist verify hardcoded-colors"
390
+ "verify:hardcoded-colors": "assist verify hardcoded-colors",
391
+ "verify:maintainability": "assist complexity maintainability ./src --threshold 60"
391
392
  };
392
393
 
393
394
  // src/commands/verify/setup/setupBuild.ts
@@ -726,12 +727,25 @@ async function setupLint(packageJsonPath) {
726
727
  );
727
728
  }
728
729
 
729
- // src/commands/verify/setup/setupTest.ts
730
+ // src/commands/verify/setup/setupMaintainability.ts
730
731
  import * as path7 from "path";
731
732
  import chalk13 from "chalk";
733
+ async function setupMaintainability(packageJsonPath) {
734
+ console.log(chalk13.blue("\nSetting up maintainability check..."));
735
+ addToKnipIgnoreBinaries(path7.dirname(packageJsonPath), "assist");
736
+ setupVerifyScript(
737
+ packageJsonPath,
738
+ "verify:maintainability",
739
+ expectedScripts["verify:maintainability"]
740
+ );
741
+ }
742
+
743
+ // src/commands/verify/setup/setupTest.ts
744
+ import * as path8 from "path";
745
+ import chalk14 from "chalk";
732
746
  async function setupTest(packageJsonPath) {
733
- console.log(chalk13.blue("\nSetting up vitest..."));
734
- const cwd = path7.dirname(packageJsonPath);
747
+ console.log(chalk14.blue("\nSetting up vitest..."));
748
+ const cwd = path8.dirname(packageJsonPath);
735
749
  const pkg = readPackageJson(packageJsonPath);
736
750
  if (!pkg.devDependencies?.vitest && !installPackage("vitest", cwd)) {
737
751
  return;
@@ -783,6 +797,7 @@ function detectExistingSetup(pkg) {
783
797
  build: toolStatus(pkg, "verify:build", true),
784
798
  typecheck: toolStatus(pkg, "verify:typecheck", true),
785
799
  hardcodedColors: toolStatus(pkg, "verify:hardcoded-colors", true),
800
+ maintainability: toolStatus(pkg, "verify:maintainability", true),
786
801
  hasOpenColor: !!pkg.dependencies?.["open-color"] || !!pkg.devDependencies?.["open-color"]
787
802
  };
788
803
  }
@@ -839,6 +854,12 @@ var options = [
839
854
  label: "typecheck",
840
855
  description: "TypeScript type checking",
841
856
  extraCondition: (s) => s.hasTypescript && !s.hasVite
857
+ },
858
+ {
859
+ toolKey: "maintainability",
860
+ value: "maintainability",
861
+ label: "maintainability",
862
+ description: "Maintainability index threshold check"
842
863
  }
843
864
  ];
844
865
 
@@ -868,37 +889,42 @@ function getSetupHandlers(hasVite, hasTypescript, hasOpenColor) {
868
889
  test: (p) => setupTest(p),
869
890
  build: (p) => setupBuild(p, hasVite, hasTypescript),
870
891
  typecheck: (p) => setupTypecheck(p),
871
- "hardcoded-colors": (p) => setupHardcodedColors(p, hasOpenColor)
892
+ "hardcoded-colors": (p) => setupHardcodedColors(p, hasOpenColor),
893
+ maintainability: (p) => setupMaintainability(p)
872
894
  };
873
895
  }
874
896
  async function runSelectedSetups(selected, packageJsonPath, handlers) {
875
897
  for (const choice of selected) {
876
898
  await handlers[choice]?.(packageJsonPath);
877
899
  }
878
- console.log(chalk14.green(`
900
+ console.log(chalk15.green(`
879
901
  Added ${selected.length} verify script(s):`));
880
902
  for (const choice of selected) {
881
- console.log(chalk14.green(` - verify:${choice}`));
903
+ console.log(chalk15.green(` - verify:${choice}`));
882
904
  }
883
- console.log(chalk14.dim("\nRun 'assist verify' to run all verify scripts"));
905
+ console.log(chalk15.dim("\nRun 'assist verify' to run all verify scripts"));
884
906
  }
885
- async function init2() {
886
- const { packageJsonPath, pkg } = requirePackageJson();
887
- const setup = detectExistingSetup(pkg);
888
- const availableOptions = getAvailableOptions(setup);
907
+ async function promptForScripts(availableOptions) {
889
908
  if (availableOptions.length === 0) {
890
- console.log(chalk14.green("All verify scripts are already configured!"));
891
- return;
909
+ console.log(chalk15.green("All verify scripts are already configured!"));
910
+ return null;
892
911
  }
893
- console.log(chalk14.bold("Available verify scripts to add:\n"));
912
+ console.log(chalk15.bold("Available verify scripts to add:\n"));
894
913
  const selected = await promptMultiselect(
895
914
  "Select verify scripts to add:",
896
915
  availableOptions
897
916
  );
898
917
  if (selected.length === 0) {
899
- console.log(chalk14.yellow("No scripts selected"));
900
- return;
918
+ console.log(chalk15.yellow("No scripts selected"));
919
+ return null;
901
920
  }
921
+ return selected;
922
+ }
923
+ async function init2() {
924
+ const { packageJsonPath, pkg } = requirePackageJson();
925
+ const setup = detectExistingSetup(pkg);
926
+ const selected = await promptForScripts(getAvailableOptions(setup));
927
+ if (!selected) return;
902
928
  const handlers = getSetupHandlers(
903
929
  setup.hasVite,
904
930
  setup.hasTypescript,
@@ -908,21 +934,21 @@ async function init2() {
908
934
  }
909
935
 
910
936
  // src/commands/vscode/init/index.ts
911
- import chalk16 from "chalk";
937
+ import chalk17 from "chalk";
912
938
 
913
939
  // src/commands/vscode/init/createLaunchJson.ts
914
940
  import * as fs3 from "fs";
915
- import * as path8 from "path";
916
- import chalk15 from "chalk";
941
+ import * as path9 from "path";
942
+ import chalk16 from "chalk";
917
943
  function ensureVscodeFolder() {
918
- const vscodeDir = path8.join(process.cwd(), ".vscode");
944
+ const vscodeDir = path9.join(process.cwd(), ".vscode");
919
945
  if (!fs3.existsSync(vscodeDir)) {
920
946
  fs3.mkdirSync(vscodeDir);
921
- console.log(chalk15.dim("Created .vscode folder"));
947
+ console.log(chalk16.dim("Created .vscode folder"));
922
948
  }
923
949
  }
924
950
  function removeVscodeFromGitignore() {
925
- const gitignorePath = path8.join(process.cwd(), ".gitignore");
951
+ const gitignorePath = path9.join(process.cwd(), ".gitignore");
926
952
  if (!fs3.existsSync(gitignorePath)) {
927
953
  return;
928
954
  }
@@ -933,7 +959,7 @@ function removeVscodeFromGitignore() {
933
959
  );
934
960
  if (filteredLines.length !== lines.length) {
935
961
  fs3.writeFileSync(gitignorePath, filteredLines.join("\n"));
936
- console.log(chalk15.dim("Removed .vscode references from .gitignore"));
962
+ console.log(chalk16.dim("Removed .vscode references from .gitignore"));
937
963
  }
938
964
  }
939
965
  function createLaunchJson() {
@@ -948,10 +974,10 @@ function createLaunchJson() {
948
974
  }
949
975
  ]
950
976
  };
951
- const launchPath = path8.join(process.cwd(), ".vscode", "launch.json");
977
+ const launchPath = path9.join(process.cwd(), ".vscode", "launch.json");
952
978
  fs3.writeFileSync(launchPath, `${JSON.stringify(launchConfig, null, " ")}
953
979
  `);
954
- console.log(chalk15.green("Created .vscode/launch.json"));
980
+ console.log(chalk16.green("Created .vscode/launch.json"));
955
981
  }
956
982
  function createSettingsJson() {
957
983
  const settings = {
@@ -961,33 +987,33 @@ function createSettingsJson() {
961
987
  "source.organizeImports.biome": "explicit"
962
988
  }
963
989
  };
964
- const settingsPath = path8.join(process.cwd(), ".vscode", "settings.json");
990
+ const settingsPath = path9.join(process.cwd(), ".vscode", "settings.json");
965
991
  fs3.writeFileSync(settingsPath, `${JSON.stringify(settings, null, " ")}
966
992
  `);
967
- console.log(chalk15.green("Created .vscode/settings.json"));
993
+ console.log(chalk16.green("Created .vscode/settings.json"));
968
994
  }
969
995
  function createExtensionsJson() {
970
996
  const extensions = {
971
997
  recommendations: ["biomejs.biome"]
972
998
  };
973
- const extensionsPath = path8.join(process.cwd(), ".vscode", "extensions.json");
999
+ const extensionsPath = path9.join(process.cwd(), ".vscode", "extensions.json");
974
1000
  fs3.writeFileSync(
975
1001
  extensionsPath,
976
1002
  `${JSON.stringify(extensions, null, " ")}
977
1003
  `
978
1004
  );
979
- console.log(chalk15.green("Created .vscode/extensions.json"));
1005
+ console.log(chalk16.green("Created .vscode/extensions.json"));
980
1006
  }
981
1007
 
982
1008
  // src/commands/vscode/init/detectVscodeSetup.ts
983
1009
  import * as fs4 from "fs";
984
- import * as path9 from "path";
1010
+ import * as path10 from "path";
985
1011
  function detectVscodeSetup(pkg) {
986
- const vscodeDir = path9.join(process.cwd(), ".vscode");
1012
+ const vscodeDir = path10.join(process.cwd(), ".vscode");
987
1013
  return {
988
1014
  hasVscodeFolder: fs4.existsSync(vscodeDir),
989
- hasLaunchJson: fs4.existsSync(path9.join(vscodeDir, "launch.json")),
990
- hasSettingsJson: fs4.existsSync(path9.join(vscodeDir, "settings.json")),
1015
+ hasLaunchJson: fs4.existsSync(path10.join(vscodeDir, "launch.json")),
1016
+ hasSettingsJson: fs4.existsSync(path10.join(vscodeDir, "settings.json")),
991
1017
  hasVite: !!pkg.devDependencies?.vite || !!pkg.dependencies?.vite
992
1018
  };
993
1019
  }
@@ -1021,23 +1047,23 @@ async function init3() {
1021
1047
  const setup = detectVscodeSetup(pkg);
1022
1048
  const availableOptions = getAvailableOptions2(setup);
1023
1049
  if (availableOptions.length === 0) {
1024
- console.log(chalk16.green("VS Code configuration already exists!"));
1050
+ console.log(chalk17.green("VS Code configuration already exists!"));
1025
1051
  return;
1026
1052
  }
1027
- console.log(chalk16.bold("Available VS Code configurations to add:\n"));
1053
+ console.log(chalk17.bold("Available VS Code configurations to add:\n"));
1028
1054
  const selected = await promptMultiselect(
1029
1055
  "Select configurations to add:",
1030
1056
  availableOptions
1031
1057
  );
1032
1058
  if (selected.length === 0) {
1033
- console.log(chalk16.yellow("No configurations selected"));
1059
+ console.log(chalk17.yellow("No configurations selected"));
1034
1060
  return;
1035
1061
  }
1036
1062
  removeVscodeFromGitignore();
1037
1063
  ensureVscodeFolder();
1038
1064
  for (const choice of selected) SETUP_HANDLERS[choice]?.();
1039
1065
  console.log(
1040
- chalk16.green(`
1066
+ chalk17.green(`
1041
1067
  Added ${selected.length} VS Code configuration(s)`)
1042
1068
  );
1043
1069
  }
@@ -1050,12 +1076,12 @@ async function init4() {
1050
1076
 
1051
1077
  // src/commands/lint/lint/runFileNameCheck.ts
1052
1078
  import fs6 from "fs";
1053
- import path11 from "path";
1054
- import chalk17 from "chalk";
1079
+ import path12 from "path";
1080
+ import chalk18 from "chalk";
1055
1081
 
1056
1082
  // src/shared/findSourceFiles.ts
1057
1083
  import fs5 from "fs";
1058
- import path10 from "path";
1084
+ import path11 from "path";
1059
1085
  var EXTENSIONS = [".ts", ".tsx"];
1060
1086
  function findSourceFiles(dir, options2 = {}) {
1061
1087
  const { includeTests = true } = options2;
@@ -1065,7 +1091,7 @@ function findSourceFiles(dir, options2 = {}) {
1065
1091
  }
1066
1092
  const entries = fs5.readdirSync(dir, { withFileTypes: true });
1067
1093
  for (const entry of entries) {
1068
- const fullPath = path10.join(dir, entry.name);
1094
+ const fullPath = path11.join(dir, entry.name);
1069
1095
  if (entry.isDirectory() && entry.name !== "node_modules") {
1070
1096
  results.push(...findSourceFiles(fullPath, options2));
1071
1097
  } else if (entry.isFile() && EXTENSIONS.some((ext) => entry.name.endsWith(ext))) {
@@ -1089,7 +1115,7 @@ function checkFileNames() {
1089
1115
  const sourceFiles = findSourceFiles("src");
1090
1116
  const violations = [];
1091
1117
  for (const filePath of sourceFiles) {
1092
- const fileName = path11.basename(filePath);
1118
+ const fileName = path12.basename(filePath);
1093
1119
  const nameWithoutExt = fileName.replace(/\.(ts|tsx)$/, "");
1094
1120
  if (/^[A-Z]/.test(nameWithoutExt)) {
1095
1121
  const content = fs6.readFileSync(filePath, "utf-8");
@@ -1103,16 +1129,16 @@ function checkFileNames() {
1103
1129
  function runFileNameCheck() {
1104
1130
  const violations = checkFileNames();
1105
1131
  if (violations.length > 0) {
1106
- console.error(chalk17.red("\nFile name check failed:\n"));
1132
+ console.error(chalk18.red("\nFile name check failed:\n"));
1107
1133
  console.error(
1108
- chalk17.red(
1134
+ chalk18.red(
1109
1135
  " Files without classes or React components should not start with a capital letter.\n"
1110
1136
  )
1111
1137
  );
1112
1138
  for (const violation of violations) {
1113
- console.error(chalk17.red(` ${violation.filePath}`));
1139
+ console.error(chalk18.red(` ${violation.filePath}`));
1114
1140
  console.error(
1115
- chalk17.gray(
1141
+ chalk18.gray(
1116
1142
  ` Rename to: ${violation.fileName.charAt(0).toLowerCase()}${violation.fileName.slice(1)}
1117
1143
  `
1118
1144
  )
@@ -1132,17 +1158,17 @@ function runFileNameCheck() {
1132
1158
  import fs7 from "fs";
1133
1159
 
1134
1160
  // src/commands/lint/shared.ts
1135
- import chalk18 from "chalk";
1161
+ import chalk19 from "chalk";
1136
1162
  function reportViolations(violations, checkName, errorMessage, successMessage) {
1137
1163
  if (violations.length > 0) {
1138
- console.error(chalk18.red(`
1164
+ console.error(chalk19.red(`
1139
1165
  ${checkName} failed:
1140
1166
  `));
1141
- console.error(chalk18.red(` ${errorMessage}
1167
+ console.error(chalk19.red(` ${errorMessage}
1142
1168
  `));
1143
1169
  for (const violation of violations) {
1144
- console.error(chalk18.red(` ${violation.filePath}:${violation.line}`));
1145
- console.error(chalk18.gray(` ${violation.content}
1170
+ console.error(chalk19.red(` ${violation.filePath}:${violation.line}`));
1171
+ console.error(chalk19.gray(` ${violation.content}
1146
1172
  `));
1147
1173
  }
1148
1174
  return false;
@@ -1274,7 +1300,7 @@ Total: ${lines.length} hardcoded color(s)`);
1274
1300
 
1275
1301
  // src/commands/verify/run/index.ts
1276
1302
  import { spawn } from "child_process";
1277
- import * as path12 from "path";
1303
+ import * as path13 from "path";
1278
1304
 
1279
1305
  // src/commands/verify/run/createTimerCallback/printTaskStatuses.ts
1280
1306
  function formatDuration(ms) {
@@ -1374,7 +1400,7 @@ function resolveVerifyScripts() {
1374
1400
  return result;
1375
1401
  }
1376
1402
  function getPackageDir(found) {
1377
- return path12.dirname(found.packageJsonPath);
1403
+ return path13.dirname(found.packageJsonPath);
1378
1404
  }
1379
1405
  async function executeVerifyScripts(found, timer) {
1380
1406
  printScriptList(found.verifyScripts);
@@ -1480,16 +1506,16 @@ import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSyn
1480
1506
 
1481
1507
  // src/commands/deploy/init/index.ts
1482
1508
  import { execSync as execSync8 } from "child_process";
1483
- import chalk20 from "chalk";
1509
+ import chalk21 from "chalk";
1484
1510
  import enquirer3 from "enquirer";
1485
1511
 
1486
1512
  // src/commands/deploy/init/updateWorkflow.ts
1487
1513
  import { existsSync as existsSync9, mkdirSync as mkdirSync3, readFileSync as readFileSync7, writeFileSync as writeFileSync7 } from "fs";
1488
- import { dirname as dirname9, join as join7 } from "path";
1514
+ import { dirname as dirname10, join as join7 } from "path";
1489
1515
  import { fileURLToPath as fileURLToPath2 } from "url";
1490
- import chalk19 from "chalk";
1516
+ import chalk20 from "chalk";
1491
1517
  var WORKFLOW_PATH = ".github/workflows/build.yml";
1492
- var __dirname3 = dirname9(fileURLToPath2(import.meta.url));
1518
+ var __dirname3 = dirname10(fileURLToPath2(import.meta.url));
1493
1519
  function getExistingSiteId() {
1494
1520
  if (!existsSync9(WORKFLOW_PATH)) {
1495
1521
  return null;
@@ -1512,20 +1538,20 @@ async function updateWorkflow(siteId) {
1512
1538
  if (existsSync9(WORKFLOW_PATH)) {
1513
1539
  const oldContent = readFileSync7(WORKFLOW_PATH, "utf-8");
1514
1540
  if (oldContent === newContent) {
1515
- console.log(chalk19.green("build.yml is already up to date"));
1541
+ console.log(chalk20.green("build.yml is already up to date"));
1516
1542
  return;
1517
1543
  }
1518
- console.log(chalk19.yellow("\nbuild.yml will be updated:"));
1544
+ console.log(chalk20.yellow("\nbuild.yml will be updated:"));
1519
1545
  console.log();
1520
1546
  printDiff(oldContent, newContent);
1521
- const confirm = await promptConfirm(chalk19.red("Update build.yml?"));
1547
+ const confirm = await promptConfirm(chalk20.red("Update build.yml?"));
1522
1548
  if (!confirm) {
1523
1549
  console.log("Skipped build.yml update");
1524
1550
  return;
1525
1551
  }
1526
1552
  }
1527
1553
  writeFileSync7(WORKFLOW_PATH, newContent);
1528
- console.log(chalk19.green(`
1554
+ console.log(chalk20.green(`
1529
1555
  Created ${WORKFLOW_PATH}`));
1530
1556
  }
1531
1557
 
@@ -1536,43 +1562,43 @@ async function ensureNetlifyCli() {
1536
1562
  } catch (error) {
1537
1563
  if (!(error instanceof Error) || !error.message.includes("command not found"))
1538
1564
  throw error;
1539
- console.error(chalk20.red("\nNetlify CLI is not installed.\n"));
1565
+ console.error(chalk21.red("\nNetlify CLI is not installed.\n"));
1540
1566
  const install = await promptConfirm("Would you like to install it now?");
1541
1567
  if (!install) {
1542
1568
  console.log(
1543
- chalk20.yellow(
1569
+ chalk21.yellow(
1544
1570
  "\nInstall it manually with: npm install -g netlify-cli\n"
1545
1571
  )
1546
1572
  );
1547
1573
  process.exit(1);
1548
1574
  }
1549
- console.log(chalk20.dim("\nInstalling netlify-cli...\n"));
1575
+ console.log(chalk21.dim("\nInstalling netlify-cli...\n"));
1550
1576
  execSync8("npm install -g netlify-cli", { stdio: "inherit" });
1551
1577
  console.log();
1552
1578
  execSync8("netlify sites:create --disable-linking", { stdio: "inherit" });
1553
1579
  }
1554
1580
  }
1555
1581
  function printSetupInstructions() {
1556
- console.log(chalk20.bold("\nDeployment initialized successfully!"));
1582
+ console.log(chalk21.bold("\nDeployment initialized successfully!"));
1557
1583
  console.log(
1558
- chalk20.yellow("\nTo complete setup, create a personal access token at:")
1584
+ chalk21.yellow("\nTo complete setup, create a personal access token at:")
1559
1585
  );
1560
1586
  console.log(
1561
- chalk20.cyan(
1587
+ chalk21.cyan(
1562
1588
  "https://app.netlify.com/user/applications#personal-access-tokens"
1563
1589
  )
1564
1590
  );
1565
1591
  console.log(
1566
- chalk20.yellow(
1592
+ chalk21.yellow(
1567
1593
  "\nThen add it as NETLIFY_AUTH_TOKEN in your GitHub repository secrets."
1568
1594
  )
1569
1595
  );
1570
1596
  }
1571
1597
  async function init5() {
1572
- console.log(chalk20.bold("Initializing Netlify deployment...\n"));
1598
+ console.log(chalk21.bold("Initializing Netlify deployment...\n"));
1573
1599
  const existingSiteId = getExistingSiteId();
1574
1600
  if (existingSiteId) {
1575
- console.log(chalk20.dim(`Using existing site ID: ${existingSiteId}
1601
+ console.log(chalk21.dim(`Using existing site ID: ${existingSiteId}
1576
1602
  `));
1577
1603
  await updateWorkflow(existingSiteId);
1578
1604
  return;
@@ -1666,11 +1692,11 @@ function detectPlatform() {
1666
1692
  import { spawn as spawn2 } from "child_process";
1667
1693
  import fs9 from "fs";
1668
1694
  import { createRequire } from "module";
1669
- import path13 from "path";
1695
+ import path14 from "path";
1670
1696
  var require2 = createRequire(import.meta.url);
1671
1697
  function getSnoreToastPath() {
1672
- const notifierPath = path13.dirname(require2.resolve("node-notifier"));
1673
- return path13.join(notifierPath, "vendor", "snoreToast", "snoretoast-x64.exe");
1698
+ const notifierPath = path14.dirname(require2.resolve("node-notifier"));
1699
+ return path14.join(notifierPath, "vendor", "snoreToast", "snoretoast-x64.exe");
1674
1700
  }
1675
1701
  function showWindowsNotificationFromWsl(options2) {
1676
1702
  const { title, message, sound } = options2;
@@ -1751,20 +1777,20 @@ async function notify() {
1751
1777
  }
1752
1778
 
1753
1779
  // src/commands/complexity/analyze.ts
1754
- import chalk26 from "chalk";
1780
+ import chalk27 from "chalk";
1755
1781
 
1756
1782
  // src/commands/complexity/cyclomatic.ts
1757
- import chalk22 from "chalk";
1783
+ import chalk23 from "chalk";
1758
1784
 
1759
1785
  // src/commands/complexity/shared/index.ts
1760
1786
  import fs11 from "fs";
1761
- import path15 from "path";
1762
- import chalk21 from "chalk";
1787
+ import path16 from "path";
1788
+ import chalk22 from "chalk";
1763
1789
  import ts5 from "typescript";
1764
1790
 
1765
1791
  // src/commands/complexity/findSourceFiles.ts
1766
1792
  import fs10 from "fs";
1767
- import path14 from "path";
1793
+ import path15 from "path";
1768
1794
  import { minimatch } from "minimatch";
1769
1795
  function applyIgnoreGlobs(files) {
1770
1796
  const { complexity } = loadConfig();
@@ -1779,7 +1805,7 @@ function walk(dir, results) {
1779
1805
  const extensions = [".ts", ".tsx"];
1780
1806
  const entries = fs10.readdirSync(dir, { withFileTypes: true });
1781
1807
  for (const entry of entries) {
1782
- const fullPath = path14.join(dir, entry.name);
1808
+ const fullPath = path15.join(dir, entry.name);
1783
1809
  if (entry.isDirectory()) {
1784
1810
  if (entry.name !== "node_modules" && entry.name !== ".git") {
1785
1811
  walk(fullPath, results);
@@ -1995,7 +2021,7 @@ function countSloc(content) {
1995
2021
  function createSourceFromFile(filePath) {
1996
2022
  const content = fs11.readFileSync(filePath, "utf-8");
1997
2023
  return ts5.createSourceFile(
1998
- path15.basename(filePath),
2024
+ path16.basename(filePath),
1999
2025
  content,
2000
2026
  ts5.ScriptTarget.Latest,
2001
2027
  true,
@@ -2005,7 +2031,7 @@ function createSourceFromFile(filePath) {
2005
2031
  function withSourceFiles(pattern2, callback) {
2006
2032
  const files = findSourceFiles2(pattern2);
2007
2033
  if (files.length === 0) {
2008
- console.log(chalk21.yellow("No files found matching pattern"));
2034
+ console.log(chalk22.yellow("No files found matching pattern"));
2009
2035
  return void 0;
2010
2036
  }
2011
2037
  return callback(files);
@@ -2038,11 +2064,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
2038
2064
  results.sort((a, b) => b.complexity - a.complexity);
2039
2065
  for (const { file, name, complexity } of results) {
2040
2066
  const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
2041
- const color = exceedsThreshold ? chalk22.red : chalk22.white;
2042
- console.log(`${color(`${file}:${name}`)} \u2192 ${chalk22.cyan(complexity)}`);
2067
+ const color = exceedsThreshold ? chalk23.red : chalk23.white;
2068
+ console.log(`${color(`${file}:${name}`)} \u2192 ${chalk23.cyan(complexity)}`);
2043
2069
  }
2044
2070
  console.log(
2045
- chalk22.dim(
2071
+ chalk23.dim(
2046
2072
  `
2047
2073
  Analyzed ${results.length} functions across ${files.length} files`
2048
2074
  )
@@ -2054,7 +2080,7 @@ Analyzed ${results.length} functions across ${files.length} files`
2054
2080
  }
2055
2081
 
2056
2082
  // src/commands/complexity/halstead.ts
2057
- import chalk23 from "chalk";
2083
+ import chalk24 from "chalk";
2058
2084
  async function halstead(pattern2 = "**/*.ts", options2 = {}) {
2059
2085
  withSourceFiles(pattern2, (files) => {
2060
2086
  const results = [];
@@ -2069,13 +2095,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
2069
2095
  results.sort((a, b) => b.metrics.effort - a.metrics.effort);
2070
2096
  for (const { file, name, metrics } of results) {
2071
2097
  const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
2072
- const color = exceedsThreshold ? chalk23.red : chalk23.white;
2098
+ const color = exceedsThreshold ? chalk24.red : chalk24.white;
2073
2099
  console.log(
2074
- `${color(`${file}:${name}`)} \u2192 volume: ${chalk23.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk23.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk23.magenta(metrics.effort.toFixed(1))}`
2100
+ `${color(`${file}:${name}`)} \u2192 volume: ${chalk24.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk24.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk24.magenta(metrics.effort.toFixed(1))}`
2075
2101
  );
2076
2102
  }
2077
2103
  console.log(
2078
- chalk23.dim(
2104
+ chalk24.dim(
2079
2105
  `
2080
2106
  Analyzed ${results.length} functions across ${files.length} files`
2081
2107
  )
@@ -2090,24 +2116,24 @@ Analyzed ${results.length} functions across ${files.length} files`
2090
2116
  import fs12 from "fs";
2091
2117
 
2092
2118
  // src/commands/complexity/maintainability/displayMaintainabilityResults.ts
2093
- import chalk24 from "chalk";
2119
+ import chalk25 from "chalk";
2094
2120
  function displayMaintainabilityResults(results, threshold) {
2095
2121
  const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
2096
2122
  if (threshold !== void 0 && filtered.length === 0) {
2097
- console.log(chalk24.green("All files pass maintainability threshold"));
2123
+ console.log(chalk25.green("All files pass maintainability threshold"));
2098
2124
  } else {
2099
2125
  for (const { file, avgMaintainability, minMaintainability } of filtered) {
2100
- const color = threshold !== void 0 ? chalk24.red : chalk24.white;
2126
+ const color = threshold !== void 0 ? chalk25.red : chalk25.white;
2101
2127
  console.log(
2102
- `${color(file)} \u2192 avg: ${chalk24.cyan(avgMaintainability.toFixed(1))}, min: ${chalk24.yellow(minMaintainability.toFixed(1))}`
2128
+ `${color(file)} \u2192 avg: ${chalk25.cyan(avgMaintainability.toFixed(1))}, min: ${chalk25.yellow(minMaintainability.toFixed(1))}`
2103
2129
  );
2104
2130
  }
2105
2131
  }
2106
- console.log(chalk24.dim(`
2132
+ console.log(chalk25.dim(`
2107
2133
  Analyzed ${results.length} files`));
2108
2134
  if (filtered.length > 0 && threshold !== void 0) {
2109
2135
  console.error(
2110
- chalk24.red(
2136
+ chalk25.red(
2111
2137
  `
2112
2138
  Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code. Focus on one file at a time \u2014 run 'assist complexity <file>' to see all metrics. For larger files, start by extracting responsibilities into smaller files.`
2113
2139
  )
@@ -2166,7 +2192,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
2166
2192
 
2167
2193
  // src/commands/complexity/sloc.ts
2168
2194
  import fs13 from "fs";
2169
- import chalk25 from "chalk";
2195
+ import chalk26 from "chalk";
2170
2196
  async function sloc(pattern2 = "**/*.ts", options2 = {}) {
2171
2197
  withSourceFiles(pattern2, (files) => {
2172
2198
  const results = [];
@@ -2182,12 +2208,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
2182
2208
  results.sort((a, b) => b.lines - a.lines);
2183
2209
  for (const { file, lines } of results) {
2184
2210
  const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
2185
- const color = exceedsThreshold ? chalk25.red : chalk25.white;
2186
- console.log(`${color(file)} \u2192 ${chalk25.cyan(lines)} lines`);
2211
+ const color = exceedsThreshold ? chalk26.red : chalk26.white;
2212
+ console.log(`${color(file)} \u2192 ${chalk26.cyan(lines)} lines`);
2187
2213
  }
2188
2214
  const total = results.reduce((sum, r) => sum + r.lines, 0);
2189
2215
  console.log(
2190
- chalk25.dim(`
2216
+ chalk26.dim(`
2191
2217
  Total: ${total} lines across ${files.length} files`)
2192
2218
  );
2193
2219
  if (hasViolation) {
@@ -2201,21 +2227,21 @@ async function analyze(pattern2) {
2201
2227
  const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
2202
2228
  const files = findSourceFiles2(searchPattern);
2203
2229
  if (files.length === 0) {
2204
- console.log(chalk26.yellow("No files found matching pattern"));
2230
+ console.log(chalk27.yellow("No files found matching pattern"));
2205
2231
  return;
2206
2232
  }
2207
2233
  if (files.length === 1) {
2208
2234
  const file = files[0];
2209
- console.log(chalk26.bold.underline("SLOC"));
2235
+ console.log(chalk27.bold.underline("SLOC"));
2210
2236
  await sloc(file);
2211
2237
  console.log();
2212
- console.log(chalk26.bold.underline("Cyclomatic Complexity"));
2238
+ console.log(chalk27.bold.underline("Cyclomatic Complexity"));
2213
2239
  await cyclomatic(file);
2214
2240
  console.log();
2215
- console.log(chalk26.bold.underline("Halstead Metrics"));
2241
+ console.log(chalk27.bold.underline("Halstead Metrics"));
2216
2242
  await halstead(file);
2217
2243
  console.log();
2218
- console.log(chalk26.bold.underline("Maintainability Index"));
2244
+ console.log(chalk27.bold.underline("Maintainability Index"));
2219
2245
  await maintainability(file);
2220
2246
  return;
2221
2247
  }
@@ -2243,7 +2269,7 @@ function registerComplexity(program2) {
2243
2269
 
2244
2270
  // src/commands/deploy/redirect.ts
2245
2271
  import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync9 } from "fs";
2246
- import chalk27 from "chalk";
2272
+ import chalk28 from "chalk";
2247
2273
  var TRAILING_SLASH_SCRIPT = ` <script>
2248
2274
  if (!window.location.pathname.endsWith('/')) {
2249
2275
  window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
@@ -2252,22 +2278,22 @@ var TRAILING_SLASH_SCRIPT = ` <script>
2252
2278
  function redirect() {
2253
2279
  const indexPath = "index.html";
2254
2280
  if (!existsSync11(indexPath)) {
2255
- console.log(chalk27.yellow("No index.html found"));
2281
+ console.log(chalk28.yellow("No index.html found"));
2256
2282
  return;
2257
2283
  }
2258
2284
  const content = readFileSync9(indexPath, "utf-8");
2259
2285
  if (content.includes("window.location.pathname.endsWith('/')")) {
2260
- console.log(chalk27.dim("Trailing slash script already present"));
2286
+ console.log(chalk28.dim("Trailing slash script already present"));
2261
2287
  return;
2262
2288
  }
2263
2289
  const headCloseIndex = content.indexOf("</head>");
2264
2290
  if (headCloseIndex === -1) {
2265
- console.log(chalk27.red("Could not find </head> tag in index.html"));
2291
+ console.log(chalk28.red("Could not find </head> tag in index.html"));
2266
2292
  return;
2267
2293
  }
2268
2294
  const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
2269
2295
  writeFileSync9(indexPath, newContent);
2270
- console.log(chalk27.green("Added trailing slash redirect to index.html"));
2296
+ console.log(chalk28.green("Added trailing slash redirect to index.html"));
2271
2297
  }
2272
2298
 
2273
2299
  // src/commands/registerDeploy.ts
@@ -2283,7 +2309,7 @@ import { basename as basename3 } from "path";
2283
2309
 
2284
2310
  // src/commands/devlog/shared.ts
2285
2311
  import { execSync as execSync10 } from "child_process";
2286
- import chalk28 from "chalk";
2312
+ import chalk29 from "chalk";
2287
2313
 
2288
2314
  // src/commands/devlog/loadDevlogEntries.ts
2289
2315
  import { readdirSync, readFileSync as readFileSync10 } from "fs";
@@ -2344,13 +2370,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
2344
2370
  }
2345
2371
  function printCommitsWithFiles(commits, ignore2, verbose) {
2346
2372
  for (const commit2 of commits) {
2347
- console.log(` ${chalk28.yellow(commit2.hash)} ${commit2.message}`);
2373
+ console.log(` ${chalk29.yellow(commit2.hash)} ${commit2.message}`);
2348
2374
  if (verbose) {
2349
2375
  const visibleFiles = commit2.files.filter(
2350
2376
  (file) => !ignore2.some((p) => file.startsWith(p))
2351
2377
  );
2352
2378
  for (const file of visibleFiles) {
2353
- console.log(` ${chalk28.dim(file)}`);
2379
+ console.log(` ${chalk29.dim(file)}`);
2354
2380
  }
2355
2381
  }
2356
2382
  }
@@ -2375,15 +2401,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
2375
2401
  }
2376
2402
 
2377
2403
  // src/commands/devlog/list/printDateHeader.ts
2378
- import chalk29 from "chalk";
2404
+ import chalk30 from "chalk";
2379
2405
  function printDateHeader(date, isSkipped, entries) {
2380
2406
  if (isSkipped) {
2381
- console.log(`${chalk29.bold.blue(date)} ${chalk29.dim("skipped")}`);
2407
+ console.log(`${chalk30.bold.blue(date)} ${chalk30.dim("skipped")}`);
2382
2408
  } else if (entries && entries.length > 0) {
2383
- const entryInfo = entries.map((e) => `${chalk29.green(e.version)} ${e.title}`).join(" | ");
2384
- console.log(`${chalk29.bold.blue(date)} ${entryInfo}`);
2409
+ const entryInfo = entries.map((e) => `${chalk30.green(e.version)} ${e.title}`).join(" | ");
2410
+ console.log(`${chalk30.bold.blue(date)} ${entryInfo}`);
2385
2411
  } else {
2386
- console.log(`${chalk29.bold.blue(date)} ${chalk29.red("\u26A0 devlog missing")}`);
2412
+ console.log(`${chalk30.bold.blue(date)} ${chalk30.red("\u26A0 devlog missing")}`);
2387
2413
  }
2388
2414
  }
2389
2415
 
@@ -2486,24 +2512,24 @@ function bumpVersion(version2, type) {
2486
2512
 
2487
2513
  // src/commands/devlog/next/displayNextEntry/index.ts
2488
2514
  import { execSync as execSync13 } from "child_process";
2489
- import chalk31 from "chalk";
2515
+ import chalk32 from "chalk";
2490
2516
 
2491
2517
  // src/commands/devlog/next/displayNextEntry/displayVersion.ts
2492
- import chalk30 from "chalk";
2518
+ import chalk31 from "chalk";
2493
2519
  function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
2494
2520
  if (conventional && firstHash) {
2495
2521
  const version2 = getVersionAtCommit(firstHash);
2496
2522
  if (version2) {
2497
- console.log(`${chalk30.bold("version:")} ${stripToMinor(version2)}`);
2523
+ console.log(`${chalk31.bold("version:")} ${stripToMinor(version2)}`);
2498
2524
  } else {
2499
- console.log(`${chalk30.bold("version:")} ${chalk30.red("unknown")}`);
2525
+ console.log(`${chalk31.bold("version:")} ${chalk31.red("unknown")}`);
2500
2526
  }
2501
2527
  } else if (patchVersion && minorVersion) {
2502
2528
  console.log(
2503
- `${chalk30.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
2529
+ `${chalk31.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
2504
2530
  );
2505
2531
  } else {
2506
- console.log(`${chalk30.bold("version:")} v0.1 (initial)`);
2532
+ console.log(`${chalk31.bold("version:")} v0.1 (initial)`);
2507
2533
  }
2508
2534
  }
2509
2535
 
@@ -2550,16 +2576,16 @@ function noCommitsMessage(hasLastInfo) {
2550
2576
  return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
2551
2577
  }
2552
2578
  function logName(repoName) {
2553
- console.log(`${chalk31.bold("name:")} ${repoName}`);
2579
+ console.log(`${chalk32.bold("name:")} ${repoName}`);
2554
2580
  }
2555
2581
  function displayNextEntry(ctx, targetDate, commits) {
2556
2582
  logName(ctx.repoName);
2557
2583
  printVersionInfo(ctx.config, ctx.lastInfo, commits[0]?.hash);
2558
- console.log(chalk31.bold.blue(targetDate));
2584
+ console.log(chalk32.bold.blue(targetDate));
2559
2585
  printCommitsWithFiles(commits, ctx.ignore, ctx.verbose);
2560
2586
  }
2561
2587
  function logNoCommits(lastInfo) {
2562
- console.log(chalk31.dim(noCommitsMessage(!!lastInfo)));
2588
+ console.log(chalk32.dim(noCommitsMessage(!!lastInfo)));
2563
2589
  }
2564
2590
 
2565
2591
  // src/commands/devlog/next/index.ts
@@ -2594,16 +2620,16 @@ function next(options2) {
2594
2620
  }
2595
2621
 
2596
2622
  // src/commands/devlog/skip.ts
2597
- import chalk32 from "chalk";
2623
+ import chalk33 from "chalk";
2598
2624
  function skip(date) {
2599
2625
  if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
2600
- console.log(chalk32.red("Invalid date format. Use YYYY-MM-DD"));
2626
+ console.log(chalk33.red("Invalid date format. Use YYYY-MM-DD"));
2601
2627
  process.exit(1);
2602
2628
  }
2603
2629
  const config = loadConfig();
2604
2630
  const skipDays = config.devlog?.skip?.days ?? [];
2605
2631
  if (skipDays.includes(date)) {
2606
- console.log(chalk32.yellow(`${date} is already in skip list`));
2632
+ console.log(chalk33.yellow(`${date} is already in skip list`));
2607
2633
  return;
2608
2634
  }
2609
2635
  skipDays.push(date);
@@ -2616,20 +2642,20 @@ function skip(date) {
2616
2642
  }
2617
2643
  };
2618
2644
  saveConfig(config);
2619
- console.log(chalk32.green(`Added ${date} to skip list`));
2645
+ console.log(chalk33.green(`Added ${date} to skip list`));
2620
2646
  }
2621
2647
 
2622
2648
  // src/commands/devlog/version.ts
2623
- import chalk33 from "chalk";
2649
+ import chalk34 from "chalk";
2624
2650
  function version() {
2625
2651
  const config = loadConfig();
2626
2652
  const name = getRepoName();
2627
2653
  const lastInfo = getLastVersionInfo(name, config);
2628
2654
  const lastVersion = lastInfo?.version ?? null;
2629
2655
  const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
2630
- console.log(`${chalk33.bold("name:")} ${name}`);
2631
- console.log(`${chalk33.bold("last:")} ${lastVersion ?? chalk33.dim("none")}`);
2632
- console.log(`${chalk33.bold("next:")} ${nextVersion ?? chalk33.dim("none")}`);
2656
+ console.log(`${chalk34.bold("name:")} ${name}`);
2657
+ console.log(`${chalk34.bold("last:")} ${lastVersion ?? chalk34.dim("none")}`);
2658
+ console.log(`${chalk34.bold("next:")} ${nextVersion ?? chalk34.dim("none")}`);
2633
2659
  }
2634
2660
 
2635
2661
  // src/commands/registerDevlog.ts
@@ -2886,20 +2912,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
2886
2912
  }
2887
2913
 
2888
2914
  // src/commands/prs/listComments/formatForHuman.ts
2889
- import chalk34 from "chalk";
2915
+ import chalk35 from "chalk";
2890
2916
  function formatForHuman(comment) {
2891
2917
  if (comment.type === "review") {
2892
- const stateColor = comment.state === "APPROVED" ? chalk34.green : comment.state === "CHANGES_REQUESTED" ? chalk34.red : chalk34.yellow;
2918
+ const stateColor = comment.state === "APPROVED" ? chalk35.green : comment.state === "CHANGES_REQUESTED" ? chalk35.red : chalk35.yellow;
2893
2919
  return [
2894
- `${chalk34.cyan("Review")} by ${chalk34.bold(comment.user)} ${stateColor(`[${comment.state}]`)}`,
2920
+ `${chalk35.cyan("Review")} by ${chalk35.bold(comment.user)} ${stateColor(`[${comment.state}]`)}`,
2895
2921
  comment.body,
2896
2922
  ""
2897
2923
  ].join("\n");
2898
2924
  }
2899
2925
  const location = comment.line ? `:${comment.line}` : "";
2900
2926
  return [
2901
- `${chalk34.cyan("Line comment")} by ${chalk34.bold(comment.user)} on ${chalk34.dim(`${comment.path}${location}`)}`,
2902
- chalk34.dim(comment.diff_hunk.split("\n").slice(-3).join("\n")),
2927
+ `${chalk35.cyan("Line comment")} by ${chalk35.bold(comment.user)} on ${chalk35.dim(`${comment.path}${location}`)}`,
2928
+ chalk35.dim(comment.diff_hunk.split("\n").slice(-3).join("\n")),
2903
2929
  comment.body,
2904
2930
  ""
2905
2931
  ].join("\n");
@@ -2978,13 +3004,13 @@ import { execSync as execSync19 } from "child_process";
2978
3004
  import enquirer4 from "enquirer";
2979
3005
 
2980
3006
  // src/commands/prs/prs/displayPaginated/printPr.ts
2981
- import chalk35 from "chalk";
3007
+ import chalk36 from "chalk";
2982
3008
  var STATUS_MAP = {
2983
- MERGED: (pr) => pr.mergedAt ? { label: chalk35.magenta("merged"), date: pr.mergedAt } : null,
2984
- CLOSED: (pr) => pr.closedAt ? { label: chalk35.red("closed"), date: pr.closedAt } : null
3009
+ MERGED: (pr) => pr.mergedAt ? { label: chalk36.magenta("merged"), date: pr.mergedAt } : null,
3010
+ CLOSED: (pr) => pr.closedAt ? { label: chalk36.red("closed"), date: pr.closedAt } : null
2985
3011
  };
2986
3012
  function defaultStatus(pr) {
2987
- return { label: chalk35.green("opened"), date: pr.createdAt };
3013
+ return { label: chalk36.green("opened"), date: pr.createdAt };
2988
3014
  }
2989
3015
  function getStatus(pr) {
2990
3016
  return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
@@ -2993,11 +3019,11 @@ function formatDate(dateStr) {
2993
3019
  return new Date(dateStr).toISOString().split("T")[0];
2994
3020
  }
2995
3021
  function formatPrHeader(pr, status) {
2996
- return `${chalk35.cyan(`#${pr.number}`)} ${pr.title} ${chalk35.dim(`(${pr.author.login},`)} ${status.label} ${chalk35.dim(`${formatDate(status.date)})`)}`;
3022
+ return `${chalk36.cyan(`#${pr.number}`)} ${pr.title} ${chalk36.dim(`(${pr.author.login},`)} ${status.label} ${chalk36.dim(`${formatDate(status.date)})`)}`;
2997
3023
  }
2998
3024
  function logPrDetails(pr) {
2999
3025
  console.log(
3000
- chalk35.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
3026
+ chalk36.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
3001
3027
  );
3002
3028
  console.log();
3003
3029
  }
@@ -3161,10 +3187,10 @@ function registerPrs(program2) {
3161
3187
 
3162
3188
  // src/commands/refactor/check/index.ts
3163
3189
  import { spawn as spawn3 } from "child_process";
3164
- import * as path16 from "path";
3190
+ import * as path17 from "path";
3165
3191
 
3166
3192
  // src/commands/refactor/logViolations.ts
3167
- import chalk36 from "chalk";
3193
+ import chalk37 from "chalk";
3168
3194
  var DEFAULT_MAX_LINES = 100;
3169
3195
  function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
3170
3196
  if (violations.length === 0) {
@@ -3173,43 +3199,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
3173
3199
  }
3174
3200
  return;
3175
3201
  }
3176
- console.error(chalk36.red(`
3202
+ console.error(chalk37.red(`
3177
3203
  Refactor check failed:
3178
3204
  `));
3179
- console.error(chalk36.red(` The following files exceed ${maxLines} lines:
3205
+ console.error(chalk37.red(` The following files exceed ${maxLines} lines:
3180
3206
  `));
3181
3207
  for (const violation of violations) {
3182
- console.error(chalk36.red(` ${violation.file} (${violation.lines} lines)`));
3208
+ console.error(chalk37.red(` ${violation.file} (${violation.lines} lines)`));
3183
3209
  }
3184
3210
  console.error(
3185
- chalk36.yellow(
3211
+ chalk37.yellow(
3186
3212
  `
3187
3213
  Each file needs to be sensibly refactored, or if there is no sensible
3188
3214
  way to refactor it, ignore it with:
3189
3215
  `
3190
3216
  )
3191
3217
  );
3192
- console.error(chalk36.gray(` assist refactor ignore <file>
3218
+ console.error(chalk37.gray(` assist refactor ignore <file>
3193
3219
  `));
3194
3220
  if (process.env.CLAUDECODE) {
3195
- console.error(chalk36.cyan(`
3221
+ console.error(chalk37.cyan(`
3196
3222
  ## Extracting Code to New Files
3197
3223
  `));
3198
3224
  console.error(
3199
- chalk36.cyan(
3225
+ chalk37.cyan(
3200
3226
  ` When extracting logic from one file to another, consider where the extracted code belongs:
3201
3227
  `
3202
3228
  )
3203
3229
  );
3204
3230
  console.error(
3205
- chalk36.cyan(
3231
+ chalk37.cyan(
3206
3232
  ` 1. Keep related logic together: If the extracted code is tightly coupled to the
3207
3233
  original file's domain, create a new folder containing both the original and extracted files.
3208
3234
  `
3209
3235
  )
3210
3236
  );
3211
3237
  console.error(
3212
- chalk36.cyan(
3238
+ chalk37.cyan(
3213
3239
  ` 2. Share common utilities: If the extracted code can be reused across multiple
3214
3240
  domains, move it to a common/shared folder.
3215
3241
  `
@@ -3338,7 +3364,7 @@ ${failed.length} verify script(s) failed:`);
3338
3364
  async function runVerifyQuietly() {
3339
3365
  const result = findPackageJsonWithVerifyScripts(process.cwd());
3340
3366
  if (!result) return true;
3341
- const packageDir = path16.dirname(result.packageJsonPath);
3367
+ const packageDir = path17.dirname(result.packageJsonPath);
3342
3368
  const results = await Promise.all(
3343
3369
  result.verifyScripts.map((script) => runScript2(script, packageDir))
3344
3370
  );
@@ -3365,11 +3391,11 @@ async function check(pattern2, options2) {
3365
3391
 
3366
3392
  // src/commands/refactor/ignore.ts
3367
3393
  import fs16 from "fs";
3368
- import chalk37 from "chalk";
3394
+ import chalk38 from "chalk";
3369
3395
  var REFACTOR_YML_PATH2 = "refactor.yml";
3370
3396
  function ignore(file) {
3371
3397
  if (!fs16.existsSync(file)) {
3372
- console.error(chalk37.red(`Error: File does not exist: ${file}`));
3398
+ console.error(chalk38.red(`Error: File does not exist: ${file}`));
3373
3399
  process.exit(1);
3374
3400
  }
3375
3401
  const content = fs16.readFileSync(file, "utf-8");
@@ -3385,18 +3411,18 @@ function ignore(file) {
3385
3411
  fs16.writeFileSync(REFACTOR_YML_PATH2, entry);
3386
3412
  }
3387
3413
  console.log(
3388
- chalk37.green(
3414
+ chalk38.green(
3389
3415
  `Added ${file} to refactor ignore list (max ${maxLines} lines)`
3390
3416
  )
3391
3417
  );
3392
3418
  }
3393
3419
 
3394
3420
  // src/commands/refactor/restructure/index.ts
3395
- import path25 from "path";
3396
- import chalk40 from "chalk";
3421
+ import path26 from "path";
3422
+ import chalk41 from "chalk";
3397
3423
 
3398
3424
  // src/commands/refactor/restructure/buildImportGraph/index.ts
3399
- import path17 from "path";
3425
+ import path18 from "path";
3400
3426
  import ts7 from "typescript";
3401
3427
 
3402
3428
  // src/commands/refactor/restructure/buildImportGraph/getImportSpecifiers.ts
@@ -3423,7 +3449,7 @@ function loadParsedConfig(tsConfigPath) {
3423
3449
  return ts7.parseJsonConfigFileContent(
3424
3450
  configFile.config,
3425
3451
  ts7.sys,
3426
- path17.dirname(tsConfigPath)
3452
+ path18.dirname(tsConfigPath)
3427
3453
  );
3428
3454
  }
3429
3455
  function addToSetMap(map, key, value) {
@@ -3439,7 +3465,7 @@ function resolveImport(specifier, filePath, options2) {
3439
3465
  const resolved = ts7.resolveModuleName(specifier, filePath, options2, ts7.sys);
3440
3466
  const resolvedPath = resolved.resolvedModule?.resolvedFileName;
3441
3467
  if (!resolvedPath || resolvedPath.includes("node_modules")) return null;
3442
- return path17.resolve(resolvedPath);
3468
+ return path18.resolve(resolvedPath);
3443
3469
  }
3444
3470
  function buildImportGraph(candidateFiles, tsConfigPath) {
3445
3471
  const parsed = loadParsedConfig(tsConfigPath);
@@ -3448,7 +3474,7 @@ function buildImportGraph(candidateFiles, tsConfigPath) {
3448
3474
  const importedBy = /* @__PURE__ */ new Map();
3449
3475
  const imports = /* @__PURE__ */ new Map();
3450
3476
  for (const sourceFile of program2.getSourceFiles()) {
3451
- const filePath = path17.resolve(sourceFile.fileName);
3477
+ const filePath = path18.resolve(sourceFile.fileName);
3452
3478
  if (filePath.includes("node_modules")) continue;
3453
3479
  for (const specifier of getImportSpecifiers(sourceFile)) {
3454
3480
  const absTarget = resolveImport(specifier, filePath, parsed.options);
@@ -3462,12 +3488,12 @@ function buildImportGraph(candidateFiles, tsConfigPath) {
3462
3488
  }
3463
3489
 
3464
3490
  // src/commands/refactor/restructure/clusterDirectories.ts
3465
- import path18 from "path";
3491
+ import path19 from "path";
3466
3492
  function clusterDirectories(graph) {
3467
3493
  const dirImportedBy = /* @__PURE__ */ new Map();
3468
3494
  for (const edge of graph.edges) {
3469
- const sourceDir = path18.dirname(edge.source);
3470
- const targetDir = path18.dirname(edge.target);
3495
+ const sourceDir = path19.dirname(edge.source);
3496
+ const targetDir = path19.dirname(edge.target);
3471
3497
  if (sourceDir === targetDir) continue;
3472
3498
  if (!graph.files.has(edge.target)) continue;
3473
3499
  const existing = dirImportedBy.get(targetDir) ?? /* @__PURE__ */ new Set();
@@ -3495,20 +3521,20 @@ function clusterDirectories(graph) {
3495
3521
  return clusters;
3496
3522
  }
3497
3523
  function isAncestor(ancestor, descendant) {
3498
- const rel = path18.relative(ancestor, descendant);
3524
+ const rel = path19.relative(ancestor, descendant);
3499
3525
  return !rel.startsWith("..") && rel !== "";
3500
3526
  }
3501
3527
 
3502
3528
  // src/commands/refactor/restructure/clusterFiles.ts
3503
- import path19 from "path";
3529
+ import path20 from "path";
3504
3530
  function findRootParent(file, importedBy, visited) {
3505
3531
  const importers = importedBy.get(file);
3506
3532
  if (!importers || importers.size !== 1) return file;
3507
3533
  const parent = [...importers][0];
3508
- const parentDir = path19.dirname(parent);
3509
- const fileDir = path19.dirname(file);
3534
+ const parentDir = path20.dirname(parent);
3535
+ const fileDir = path20.dirname(file);
3510
3536
  if (parentDir !== fileDir) return file;
3511
- if (path19.basename(parent, path19.extname(parent)) === "index") return file;
3537
+ if (path20.basename(parent, path20.extname(parent)) === "index") return file;
3512
3538
  if (visited.has(parent)) return file;
3513
3539
  visited.add(parent);
3514
3540
  return findRootParent(parent, importedBy, visited);
@@ -3516,16 +3542,16 @@ function findRootParent(file, importedBy, visited) {
3516
3542
  function clusterFiles(graph) {
3517
3543
  const clusters = /* @__PURE__ */ new Map();
3518
3544
  for (const file of graph.files) {
3519
- const basename7 = path19.basename(file, path19.extname(file));
3545
+ const basename7 = path20.basename(file, path20.extname(file));
3520
3546
  if (basename7 === "index") continue;
3521
3547
  const importers = graph.importedBy.get(file);
3522
3548
  if (!importers || importers.size !== 1) continue;
3523
3549
  const parent = [...importers][0];
3524
3550
  if (!graph.files.has(parent)) continue;
3525
- const parentDir = path19.dirname(parent);
3526
- const fileDir = path19.dirname(file);
3551
+ const parentDir = path20.dirname(parent);
3552
+ const fileDir = path20.dirname(file);
3527
3553
  if (parentDir !== fileDir) continue;
3528
- const parentBasename = path19.basename(parent, path19.extname(parent));
3554
+ const parentBasename = path20.basename(parent, path20.extname(parent));
3529
3555
  if (parentBasename === "index") continue;
3530
3556
  const root = findRootParent(parent, graph.importedBy, /* @__PURE__ */ new Set([file]));
3531
3557
  if (!root || root === file) continue;
@@ -3537,7 +3563,7 @@ function clusterFiles(graph) {
3537
3563
  }
3538
3564
 
3539
3565
  // src/commands/refactor/restructure/computeRewrites/index.ts
3540
- import path20 from "path";
3566
+ import path21 from "path";
3541
3567
 
3542
3568
  // src/commands/refactor/restructure/computeRewrites/applyRewrites.ts
3543
3569
  import fs17 from "fs";
@@ -3591,7 +3617,7 @@ function normalizeSpecifier(rel) {
3591
3617
  );
3592
3618
  }
3593
3619
  function computeSpecifier(fromFile, toFile) {
3594
- return normalizeSpecifier(path20.relative(path20.dirname(fromFile), toFile));
3620
+ return normalizeSpecifier(path21.relative(path21.dirname(fromFile), toFile));
3595
3621
  }
3596
3622
  function isAffected(edge, moveMap) {
3597
3623
  return moveMap.has(edge.target) || moveMap.has(edge.source);
@@ -3635,51 +3661,51 @@ function computeRewrites(moves, edges, allProjectFiles) {
3635
3661
  }
3636
3662
 
3637
3663
  // src/commands/refactor/restructure/displayPlan.ts
3638
- import path21 from "path";
3639
- import chalk38 from "chalk";
3664
+ import path22 from "path";
3665
+ import chalk39 from "chalk";
3640
3666
  function relPath(filePath) {
3641
- return path21.relative(process.cwd(), filePath);
3667
+ return path22.relative(process.cwd(), filePath);
3642
3668
  }
3643
3669
  function displayMoves(plan) {
3644
3670
  if (plan.moves.length === 0) return;
3645
- console.log(chalk38.bold("\nFile moves:"));
3671
+ console.log(chalk39.bold("\nFile moves:"));
3646
3672
  for (const move of plan.moves) {
3647
3673
  console.log(
3648
- ` ${chalk38.red(relPath(move.from))} \u2192 ${chalk38.green(relPath(move.to))}`
3674
+ ` ${chalk39.red(relPath(move.from))} \u2192 ${chalk39.green(relPath(move.to))}`
3649
3675
  );
3650
- console.log(chalk38.dim(` ${move.reason}`));
3676
+ console.log(chalk39.dim(` ${move.reason}`));
3651
3677
  }
3652
3678
  }
3653
3679
  function displayRewrites(rewrites) {
3654
3680
  if (rewrites.length === 0) return;
3655
3681
  const affectedFiles = new Set(rewrites.map((r) => r.file));
3656
- console.log(chalk38.bold(`
3682
+ console.log(chalk39.bold(`
3657
3683
  Import rewrites (${affectedFiles.size} files):`));
3658
3684
  for (const file of affectedFiles) {
3659
- console.log(` ${chalk38.cyan(relPath(file))}:`);
3685
+ console.log(` ${chalk39.cyan(relPath(file))}:`);
3660
3686
  for (const { oldSpecifier, newSpecifier } of rewrites.filter(
3661
3687
  (r) => r.file === file
3662
3688
  )) {
3663
3689
  console.log(
3664
- ` ${chalk38.red(`"${oldSpecifier}"`)} \u2192 ${chalk38.green(`"${newSpecifier}"`)}`
3690
+ ` ${chalk39.red(`"${oldSpecifier}"`)} \u2192 ${chalk39.green(`"${newSpecifier}"`)}`
3665
3691
  );
3666
3692
  }
3667
3693
  }
3668
3694
  }
3669
3695
  function displayPlan(plan) {
3670
3696
  if (plan.warnings.length > 0) {
3671
- console.log(chalk38.yellow("\nWarnings:"));
3672
- for (const w of plan.warnings) console.log(chalk38.yellow(` ${w}`));
3697
+ console.log(chalk39.yellow("\nWarnings:"));
3698
+ for (const w of plan.warnings) console.log(chalk39.yellow(` ${w}`));
3673
3699
  }
3674
3700
  if (plan.newDirectories.length > 0) {
3675
- console.log(chalk38.bold("\nNew directories:"));
3701
+ console.log(chalk39.bold("\nNew directories:"));
3676
3702
  for (const dir of plan.newDirectories)
3677
- console.log(chalk38.green(` ${dir}/`));
3703
+ console.log(chalk39.green(` ${dir}/`));
3678
3704
  }
3679
3705
  displayMoves(plan);
3680
3706
  displayRewrites(plan.rewrites);
3681
3707
  console.log(
3682
- chalk38.dim(
3708
+ chalk39.dim(
3683
3709
  `
3684
3710
  Summary: ${plan.moves.length} file(s) moved, ${plan.rewrites.length} imports rewritten`
3685
3711
  )
@@ -3688,33 +3714,33 @@ Summary: ${plan.moves.length} file(s) moved, ${plan.rewrites.length} imports rew
3688
3714
 
3689
3715
  // src/commands/refactor/restructure/executePlan.ts
3690
3716
  import fs18 from "fs";
3691
- import path22 from "path";
3692
- import chalk39 from "chalk";
3717
+ import path23 from "path";
3718
+ import chalk40 from "chalk";
3693
3719
  function executePlan(plan) {
3694
3720
  const updatedContents = applyRewrites(plan.rewrites);
3695
3721
  for (const [file, content] of updatedContents) {
3696
3722
  fs18.writeFileSync(file, content, "utf-8");
3697
3723
  console.log(
3698
- chalk39.cyan(` Rewrote imports in ${path22.relative(process.cwd(), file)}`)
3724
+ chalk40.cyan(` Rewrote imports in ${path23.relative(process.cwd(), file)}`)
3699
3725
  );
3700
3726
  }
3701
3727
  for (const dir of plan.newDirectories) {
3702
3728
  fs18.mkdirSync(dir, { recursive: true });
3703
- console.log(chalk39.green(` Created ${path22.relative(process.cwd(), dir)}/`));
3729
+ console.log(chalk40.green(` Created ${path23.relative(process.cwd(), dir)}/`));
3704
3730
  }
3705
3731
  for (const move of plan.moves) {
3706
- const targetDir = path22.dirname(move.to);
3732
+ const targetDir = path23.dirname(move.to);
3707
3733
  if (!fs18.existsSync(targetDir)) {
3708
3734
  fs18.mkdirSync(targetDir, { recursive: true });
3709
3735
  }
3710
3736
  fs18.renameSync(move.from, move.to);
3711
3737
  console.log(
3712
- chalk39.white(
3713
- ` Moved ${path22.relative(process.cwd(), move.from)} \u2192 ${path22.relative(process.cwd(), move.to)}`
3738
+ chalk40.white(
3739
+ ` Moved ${path23.relative(process.cwd(), move.from)} \u2192 ${path23.relative(process.cwd(), move.to)}`
3714
3740
  )
3715
3741
  );
3716
3742
  }
3717
- removeEmptyDirectories(plan.moves.map((m) => path22.dirname(m.from)));
3743
+ removeEmptyDirectories(plan.moves.map((m) => path23.dirname(m.from)));
3718
3744
  }
3719
3745
  function removeEmptyDirectories(dirs) {
3720
3746
  const unique = [...new Set(dirs)];
@@ -3724,8 +3750,8 @@ function removeEmptyDirectories(dirs) {
3724
3750
  if (entries.length === 0) {
3725
3751
  fs18.rmdirSync(dir);
3726
3752
  console.log(
3727
- chalk39.dim(
3728
- ` Removed empty directory ${path22.relative(process.cwd(), dir)}`
3753
+ chalk40.dim(
3754
+ ` Removed empty directory ${path23.relative(process.cwd(), dir)}`
3729
3755
  )
3730
3756
  );
3731
3757
  }
@@ -3734,13 +3760,13 @@ function removeEmptyDirectories(dirs) {
3734
3760
 
3735
3761
  // src/commands/refactor/restructure/planFileMoves/index.ts
3736
3762
  import fs20 from "fs";
3737
- import path24 from "path";
3763
+ import path25 from "path";
3738
3764
 
3739
3765
  // src/commands/refactor/restructure/planFileMoves/planDirectoryMoves.ts
3740
3766
  import fs19 from "fs";
3741
- import path23 from "path";
3767
+ import path24 from "path";
3742
3768
  function collectEntry(results, dir, entry) {
3743
- const full = path23.join(dir, entry.name);
3769
+ const full = path24.join(dir, entry.name);
3744
3770
  const items = entry.isDirectory() ? listFilesRecursive(full) : [full];
3745
3771
  results.push(...items);
3746
3772
  }
@@ -3754,15 +3780,15 @@ function listFilesRecursive(dir) {
3754
3780
  }
3755
3781
  function addDirectoryFileMoves(moves, childDir, newLocation, reason) {
3756
3782
  for (const file of listFilesRecursive(childDir)) {
3757
- const rel = path23.relative(childDir, file);
3758
- moves.push({ from: file, to: path23.join(newLocation, rel), reason });
3783
+ const rel = path24.relative(childDir, file);
3784
+ moves.push({ from: file, to: path24.join(newLocation, rel), reason });
3759
3785
  }
3760
3786
  }
3761
3787
  function resolveChildDest(parentDir, childDir) {
3762
- return path23.join(parentDir, path23.basename(childDir));
3788
+ return path24.join(parentDir, path24.basename(childDir));
3763
3789
  }
3764
3790
  function childMoveReason(parentDir) {
3765
- return `Directory only imported from ${path23.basename(parentDir)}/`;
3791
+ return `Directory only imported from ${path24.basename(parentDir)}/`;
3766
3792
  }
3767
3793
  function registerDirectoryMove(result, childDir, dest, parentDir) {
3768
3794
  result.directories.push(dest);
@@ -3790,7 +3816,7 @@ function emptyResult() {
3790
3816
  return { moves: [], directories: [], warnings: [] };
3791
3817
  }
3792
3818
  function childMoveData(child, newDir, parentBase) {
3793
- const to = path24.join(newDir, path24.basename(child));
3819
+ const to = path25.join(newDir, path25.basename(child));
3794
3820
  return { from: child, to, reason: `Only imported by ${parentBase}` };
3795
3821
  }
3796
3822
  function addChildMoves(moves, children, newDir, parentBase) {
@@ -3803,15 +3829,15 @@ function checkDirConflict(result, label, dir) {
3803
3829
  return true;
3804
3830
  }
3805
3831
  function getBaseName(filePath) {
3806
- return path24.basename(filePath, path24.extname(filePath));
3832
+ return path25.basename(filePath, path25.extname(filePath));
3807
3833
  }
3808
3834
  function resolveClusterDir(parent) {
3809
- return path24.join(path24.dirname(parent), getBaseName(parent));
3835
+ return path25.join(path25.dirname(parent), getBaseName(parent));
3810
3836
  }
3811
3837
  function createParentMove(parent, newDir) {
3812
3838
  return {
3813
3839
  from: parent,
3814
- to: path24.join(newDir, `index${path24.extname(parent)}`),
3840
+ to: path25.join(newDir, `index${path25.extname(parent)}`),
3815
3841
  reason: `Main module of new ${getBaseName(parent)}/ directory`
3816
3842
  };
3817
3843
  }
@@ -3835,7 +3861,7 @@ function planFileMoves(clusters) {
3835
3861
 
3836
3862
  // src/commands/refactor/restructure/index.ts
3837
3863
  function buildPlan(candidateFiles, tsConfigPath) {
3838
- const candidates = new Set(candidateFiles.map((f) => path25.resolve(f)));
3864
+ const candidates = new Set(candidateFiles.map((f) => path26.resolve(f)));
3839
3865
  const graph = buildImportGraph(candidates, tsConfigPath);
3840
3866
  const allProjectFiles = /* @__PURE__ */ new Set([
3841
3867
  ...graph.importedBy.keys(),
@@ -3855,22 +3881,22 @@ async function restructure(pattern2, options2 = {}) {
3855
3881
  const targetPattern = pattern2 ?? "src";
3856
3882
  const files = findSourceFiles2(targetPattern);
3857
3883
  if (files.length === 0) {
3858
- console.log(chalk40.yellow("No files found matching pattern"));
3884
+ console.log(chalk41.yellow("No files found matching pattern"));
3859
3885
  return;
3860
3886
  }
3861
- const tsConfigPath = path25.resolve("tsconfig.json");
3887
+ const tsConfigPath = path26.resolve("tsconfig.json");
3862
3888
  const plan = buildPlan(files, tsConfigPath);
3863
3889
  if (plan.moves.length === 0) {
3864
- console.log(chalk40.green("No restructuring needed"));
3890
+ console.log(chalk41.green("No restructuring needed"));
3865
3891
  return;
3866
3892
  }
3867
3893
  displayPlan(plan);
3868
3894
  if (options2.apply) {
3869
- console.log(chalk40.bold("\nApplying changes..."));
3895
+ console.log(chalk41.bold("\nApplying changes..."));
3870
3896
  executePlan(plan);
3871
- console.log(chalk40.green("\nRestructuring complete"));
3897
+ console.log(chalk41.green("\nRestructuring complete"));
3872
3898
  } else {
3873
- console.log(chalk40.dim("\nDry run. Use --apply to execute."));
3899
+ console.log(chalk41.dim("\nDry run. Use --apply to execute."));
3874
3900
  }
3875
3901
  }
3876
3902
 
@@ -4009,7 +4035,7 @@ async function configure() {
4009
4035
  import { existsSync as existsSync16 } from "fs";
4010
4036
 
4011
4037
  // src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
4012
- import { dirname as dirname11, join as join15 } from "path";
4038
+ import { dirname as dirname12, join as join15 } from "path";
4013
4039
 
4014
4040
  // src/commands/transcript/format/fixInvalidDatePrefixes/promptForDateFix.ts
4015
4041
  import { renameSync } from "fs";
@@ -4059,11 +4085,11 @@ async function fixInvalidDatePrefixes(vttFiles) {
4059
4085
  for (let i = 0; i < vttFiles.length; i++) {
4060
4086
  const vttFile = vttFiles[i];
4061
4087
  if (!isValidDatePrefix(vttFile.filename)) {
4062
- const vttFileDir = dirname11(vttFile.absolutePath);
4088
+ const vttFileDir = dirname12(vttFile.absolutePath);
4063
4089
  const newFilename = await promptForDateFix(vttFile.filename, vttFileDir);
4064
4090
  if (newFilename) {
4065
4091
  const newRelativePath = join15(
4066
- dirname11(vttFile.relativePath),
4092
+ dirname12(vttFile.relativePath),
4067
4093
  newFilename
4068
4094
  );
4069
4095
  vttFiles[i] = {
@@ -4081,7 +4107,7 @@ async function fixInvalidDatePrefixes(vttFiles) {
4081
4107
 
4082
4108
  // src/commands/transcript/format/processVttFile/index.ts
4083
4109
  import { existsSync as existsSync15, mkdirSync as mkdirSync5, readFileSync as readFileSync12, writeFileSync as writeFileSync13 } from "fs";
4084
- import { basename as basename5, dirname as dirname12, join as join16 } from "path";
4110
+ import { basename as basename5, dirname as dirname13, join as join16 } from "path";
4085
4111
 
4086
4112
  // src/commands/transcript/cleanText.ts
4087
4113
  function cleanText(text) {
@@ -4295,7 +4321,7 @@ function resolveOutputDir(relativeDir, transcriptsDir) {
4295
4321
  }
4296
4322
  function buildOutputPaths(vttFile, transcriptsDir) {
4297
4323
  const mdFile = toMdFilename(vttFile.filename);
4298
- const relativeDir = dirname12(vttFile.relativePath);
4324
+ const relativeDir = dirname13(vttFile.relativePath);
4299
4325
  const outputDir = resolveOutputDir(relativeDir, transcriptsDir);
4300
4326
  const outputPath = join16(outputDir, mdFile);
4301
4327
  return { outputDir, outputPath, mdFile, relativeDir };
@@ -4400,7 +4426,7 @@ async function format() {
4400
4426
 
4401
4427
  // src/commands/transcript/summarise/index.ts
4402
4428
  import { existsSync as existsSync18 } from "fs";
4403
- import { basename as basename6, dirname as dirname14, join as join18, relative as relative2 } from "path";
4429
+ import { basename as basename6, dirname as dirname15, join as join18, relative as relative2 } from "path";
4404
4430
 
4405
4431
  // src/commands/transcript/summarise/processStagedFile/index.ts
4406
4432
  import {
@@ -4410,17 +4436,17 @@ import {
4410
4436
  renameSync as renameSync2,
4411
4437
  rmSync
4412
4438
  } from "fs";
4413
- import { dirname as dirname13, join as join17 } from "path";
4439
+ import { dirname as dirname14, join as join17 } from "path";
4414
4440
 
4415
4441
  // src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
4416
- import chalk41 from "chalk";
4442
+ import chalk42 from "chalk";
4417
4443
  var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
4418
4444
  function validateStagedContent(filename, content) {
4419
4445
  const firstLine = content.split("\n")[0];
4420
4446
  const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
4421
4447
  if (!match) {
4422
4448
  console.error(
4423
- chalk41.red(
4449
+ chalk42.red(
4424
4450
  `Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
4425
4451
  )
4426
4452
  );
@@ -4429,7 +4455,7 @@ function validateStagedContent(filename, content) {
4429
4455
  const contentAfterLink = content.slice(firstLine.length).trim();
4430
4456
  if (!contentAfterLink) {
4431
4457
  console.error(
4432
- chalk41.red(
4458
+ chalk42.red(
4433
4459
  `Staged file ${filename} has no summary content after the transcript link.`
4434
4460
  )
4435
4461
  );
@@ -4464,7 +4490,7 @@ function processStagedFile() {
4464
4490
  process.exit(1);
4465
4491
  }
4466
4492
  const destPath = join17(summaryDir, matchingTranscript.relativePath);
4467
- const destDir = dirname13(destPath);
4493
+ const destDir = dirname14(destPath);
4468
4494
  if (!existsSync17(destDir)) {
4469
4495
  mkdirSync6(destDir, { recursive: true });
4470
4496
  }
@@ -4478,7 +4504,7 @@ function processStagedFile() {
4478
4504
 
4479
4505
  // src/commands/transcript/summarise/index.ts
4480
4506
  function buildRelativeKey(relativePath, baseName) {
4481
- const relDir = dirname14(relativePath);
4507
+ const relDir = dirname15(relativePath);
4482
4508
  return relDir === "." ? baseName : join18(relDir, baseName);
4483
4509
  }
4484
4510
  function buildSummaryIndex(summaryDir) {
@@ -4514,7 +4540,7 @@ function summarise() {
4514
4540
  const next2 = missing[0];
4515
4541
  const outputFilename = `${getTranscriptBaseName(next2.filename)}.md`;
4516
4542
  const outputPath = join18(STAGING_DIR, outputFilename);
4517
- const summaryFileDir = join18(summaryDir, dirname14(next2.relativePath));
4543
+ const summaryFileDir = join18(summaryDir, dirname15(next2.relativePath));
4518
4544
  const relativeTranscriptPath = encodeURI(
4519
4545
  relative2(summaryFileDir, next2.absolutePath).replace(/\\/g, "/")
4520
4546
  );
@@ -4676,27 +4702,27 @@ async function statusLine() {
4676
4702
  // src/commands/sync.ts
4677
4703
  import * as fs23 from "fs";
4678
4704
  import * as os from "os";
4679
- import * as path28 from "path";
4705
+ import * as path29 from "path";
4680
4706
  import { fileURLToPath as fileURLToPath3 } from "url";
4681
4707
 
4682
4708
  // src/commands/sync/syncClaudeMd.ts
4683
4709
  import * as fs21 from "fs";
4684
- import * as path26 from "path";
4685
- import chalk42 from "chalk";
4710
+ import * as path27 from "path";
4711
+ import chalk43 from "chalk";
4686
4712
  async function syncClaudeMd(claudeDir, targetBase) {
4687
- const source = path26.join(claudeDir, "CLAUDE.md");
4688
- const target = path26.join(targetBase, "CLAUDE.md");
4713
+ const source = path27.join(claudeDir, "CLAUDE.md");
4714
+ const target = path27.join(targetBase, "CLAUDE.md");
4689
4715
  const sourceContent = fs21.readFileSync(source, "utf-8");
4690
4716
  if (fs21.existsSync(target)) {
4691
4717
  const targetContent = fs21.readFileSync(target, "utf-8");
4692
4718
  if (sourceContent !== targetContent) {
4693
4719
  console.log(
4694
- chalk42.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
4720
+ chalk43.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
4695
4721
  );
4696
4722
  console.log();
4697
4723
  printDiff(targetContent, sourceContent);
4698
4724
  const confirm = await promptConfirm(
4699
- chalk42.red("Overwrite existing CLAUDE.md?"),
4725
+ chalk43.red("Overwrite existing CLAUDE.md?"),
4700
4726
  false
4701
4727
  );
4702
4728
  if (!confirm) {
@@ -4711,11 +4737,11 @@ async function syncClaudeMd(claudeDir, targetBase) {
4711
4737
 
4712
4738
  // src/commands/sync/syncSettings.ts
4713
4739
  import * as fs22 from "fs";
4714
- import * as path27 from "path";
4715
- import chalk43 from "chalk";
4740
+ import * as path28 from "path";
4741
+ import chalk44 from "chalk";
4716
4742
  async function syncSettings(claudeDir, targetBase) {
4717
- const source = path27.join(claudeDir, "settings.json");
4718
- const target = path27.join(targetBase, "settings.json");
4743
+ const source = path28.join(claudeDir, "settings.json");
4744
+ const target = path28.join(targetBase, "settings.json");
4719
4745
  const sourceContent = fs22.readFileSync(source, "utf-8");
4720
4746
  const normalizedSource = JSON.stringify(JSON.parse(sourceContent), null, 2);
4721
4747
  if (fs22.existsSync(target)) {
@@ -4723,12 +4749,12 @@ async function syncSettings(claudeDir, targetBase) {
4723
4749
  const normalizedTarget = JSON.stringify(JSON.parse(targetContent), null, 2);
4724
4750
  if (normalizedSource !== normalizedTarget) {
4725
4751
  console.log(
4726
- chalk43.yellow("\n\u26A0\uFE0F Warning: settings.json differs from existing file")
4752
+ chalk44.yellow("\n\u26A0\uFE0F Warning: settings.json differs from existing file")
4727
4753
  );
4728
4754
  console.log();
4729
4755
  printDiff(targetContent, sourceContent);
4730
4756
  const confirm = await promptConfirm(
4731
- chalk43.red("Overwrite existing settings.json?"),
4757
+ chalk44.red("Overwrite existing settings.json?"),
4732
4758
  false
4733
4759
  );
4734
4760
  if (!confirm) {
@@ -4743,21 +4769,21 @@ async function syncSettings(claudeDir, targetBase) {
4743
4769
 
4744
4770
  // src/commands/sync.ts
4745
4771
  var __filename2 = fileURLToPath3(import.meta.url);
4746
- var __dirname4 = path28.dirname(__filename2);
4772
+ var __dirname4 = path29.dirname(__filename2);
4747
4773
  async function sync() {
4748
- const claudeDir = path28.join(__dirname4, "..", "claude");
4749
- const targetBase = path28.join(os.homedir(), ".claude");
4774
+ const claudeDir = path29.join(__dirname4, "..", "claude");
4775
+ const targetBase = path29.join(os.homedir(), ".claude");
4750
4776
  syncCommands(claudeDir, targetBase);
4751
4777
  await syncSettings(claudeDir, targetBase);
4752
4778
  await syncClaudeMd(claudeDir, targetBase);
4753
4779
  }
4754
4780
  function syncCommands(claudeDir, targetBase) {
4755
- const sourceDir = path28.join(claudeDir, "commands");
4756
- const targetDir = path28.join(targetBase, "commands");
4781
+ const sourceDir = path29.join(claudeDir, "commands");
4782
+ const targetDir = path29.join(targetBase, "commands");
4757
4783
  fs23.mkdirSync(targetDir, { recursive: true });
4758
4784
  const files = fs23.readdirSync(sourceDir);
4759
4785
  for (const file of files) {
4760
- fs23.copyFileSync(path28.join(sourceDir, file), path28.join(targetDir, file));
4786
+ fs23.copyFileSync(path29.join(sourceDir, file), path29.join(targetDir, file));
4761
4787
  console.log(`Copied ${file} to ${targetDir}`);
4762
4788
  }
4763
4789
  console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);