@staff0rd/assist 0.138.0 → 0.140.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.138.0",
9
+ version: "0.140.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -63,6 +63,7 @@ var package_default = {
63
63
  "@types/react-dom": "^19.2.3",
64
64
  "@types/semver": "^7.7.1",
65
65
  "@types/shell-quote": "^1.7.5",
66
+ "@vitest/coverage-v8": "^4.1.2",
66
67
  esbuild: "^0.27.3",
67
68
  jotai: "^2.18.0",
68
69
  jscpd: "^4.0.5",
@@ -90,10 +91,10 @@ import { stringify as stringifyYaml } from "yaml";
90
91
  // src/shared/loadRawYaml.ts
91
92
  import { existsSync, readFileSync } from "fs";
92
93
  import { parse as parseYaml } from "yaml";
93
- function loadRawYaml(path44) {
94
- if (!existsSync(path44)) return {};
94
+ function loadRawYaml(path49) {
95
+ if (!existsSync(path49)) return {};
95
96
  try {
96
- const content = readFileSync(path44, "utf-8");
97
+ const content = readFileSync(path49, "utf-8");
97
98
  return parseYaml(content) || {};
98
99
  } catch {
99
100
  return {};
@@ -370,9 +371,9 @@ function isTraversable(value) {
370
371
  function stepInto(current, key) {
371
372
  return isTraversable(current) ? current[key] : void 0;
372
373
  }
373
- function getNestedValue(obj, path44) {
374
+ function getNestedValue(obj, path49) {
374
375
  let current = obj;
375
- for (const key of path44.split(".")) current = stepInto(current, key);
376
+ for (const key of path49.split(".")) current = stepInto(current, key);
376
377
  return current;
377
378
  }
378
379
 
@@ -413,8 +414,8 @@ function stepIntoNested(container, key, nextKey) {
413
414
  }
414
415
  return ensureObject(container, resolved);
415
416
  }
416
- function setNestedValue(obj, path44, value) {
417
- const keys = path44.split(".");
417
+ function setNestedValue(obj, path49, value) {
418
+ const keys = path49.split(".");
418
419
  const result = { ...obj };
419
420
  let current = result;
420
421
  for (let i = 0; i < keys.length - 1; i++) {
@@ -3222,12 +3223,12 @@ function getCliReadsPath() {
3222
3223
  var cachedLines;
3223
3224
  function getCliReadsLines() {
3224
3225
  if (cachedLines) return cachedLines;
3225
- const path44 = getCliReadsPath();
3226
- if (!existsSync18(path44)) {
3226
+ const path49 = getCliReadsPath();
3227
+ if (!existsSync18(path49)) {
3227
3228
  cachedLines = [];
3228
3229
  return cachedLines;
3229
3230
  }
3230
- cachedLines = readFileSync13(path44, "utf-8").split("\n").filter((line) => line.trim() !== "");
3231
+ cachedLines = readFileSync13(path49, "utf-8").split("\n").filter((line) => line.trim() !== "");
3231
3232
  return cachedLines;
3232
3233
  }
3233
3234
  function loadCliReads() {
@@ -3582,14 +3583,14 @@ function showProgress(p, label2) {
3582
3583
  const pct = Math.round(p.done / p.total * 100);
3583
3584
  process.stderr.write(`\r\x1B[K[${pct}%] Scanning ${label2}...`);
3584
3585
  }
3585
- async function resolveCommand(cli, path44, description, depth, p) {
3586
- showProgress(p, path44.join(" "));
3587
- const subHelp = await runHelp([cli, ...path44]);
3586
+ async function resolveCommand(cli, path49, description, depth, p) {
3587
+ showProgress(p, path49.join(" "));
3588
+ const subHelp = await runHelp([cli, ...path49]);
3588
3589
  if (!subHelp || !hasSubcommands(subHelp)) {
3589
- return [{ path: path44, description }];
3590
+ return [{ path: path49, description }];
3590
3591
  }
3591
- const children = await discoverAt(cli, path44, depth + 1, p);
3592
- return children.length > 0 ? children : [{ path: path44, description }];
3592
+ const children = await discoverAt(cli, path49, depth + 1, p);
3593
+ return children.length > 0 ? children : [{ path: path49, description }];
3593
3594
  }
3594
3595
  async function discoverAt(cli, parentPath, depth, p) {
3595
3596
  if (depth > SAFETY_DEPTH) return [];
@@ -3737,9 +3738,9 @@ function logPath(cli) {
3737
3738
  return join13(homedir4(), ".assist", `cli-discover-${safeName}.log`);
3738
3739
  }
3739
3740
  function readCache(cli) {
3740
- const path44 = logPath(cli);
3741
- if (!existsSync20(path44)) return void 0;
3742
- return readFileSync15(path44, "utf-8");
3741
+ const path49 = logPath(cli);
3742
+ if (!existsSync20(path49)) return void 0;
3743
+ return readFileSync15(path49, "utf-8");
3743
3744
  }
3744
3745
  function writeCache(cli, output) {
3745
3746
  const dir = join13(homedir4(), ".assist");
@@ -5570,10 +5571,10 @@ function getStorePath(filename) {
5570
5571
  return join19(getStoreDir(), filename);
5571
5572
  }
5572
5573
  function loadJson(filename) {
5573
- const path44 = getStorePath(filename);
5574
- if (existsSync26(path44)) {
5574
+ const path49 = getStorePath(filename);
5575
+ if (existsSync26(path49)) {
5575
5576
  try {
5576
- return JSON.parse(readFileSync21(path44, "utf-8"));
5577
+ return JSON.parse(readFileSync21(path49, "utf-8"));
5577
5578
  } catch {
5578
5579
  return {};
5579
5580
  }
@@ -5966,7 +5967,7 @@ function validateLine(line) {
5966
5967
  process.exit(1);
5967
5968
  }
5968
5969
  }
5969
- function comment(path44, line, body) {
5970
+ function comment(path49, line, body) {
5970
5971
  validateBody(body);
5971
5972
  validateLine(line);
5972
5973
  try {
@@ -5986,7 +5987,7 @@ function comment(path44, line, body) {
5986
5987
  "-f",
5987
5988
  `body=${body}`,
5988
5989
  "-f",
5989
- `path=${path44}`,
5990
+ `path=${path49}`,
5990
5991
  "-F",
5991
5992
  `line=${line}`
5992
5993
  ],
@@ -5995,7 +5996,7 @@ function comment(path44, line, body) {
5995
5996
  if (result.status !== 0) {
5996
5997
  throw new Error(result.stderr || result.stdout);
5997
5998
  }
5998
- console.log(`Added review comment on ${path44}:${line}`);
5999
+ console.log(`Added review comment on ${path49}:${line}`);
5999
6000
  } finally {
6000
6001
  unlinkSync5(queryFile);
6001
6002
  }
@@ -6494,8 +6495,8 @@ function registerPrs(program2) {
6494
6495
  prsCommand.command("wontfix <comment-id> <reason>").description("Reply with reason and resolve thread").action((commentId, reason) => {
6495
6496
  wontfix(Number.parseInt(commentId, 10), reason);
6496
6497
  });
6497
- prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((path44, line, body) => {
6498
- comment(path44, Number.parseInt(line, 10), body);
6498
+ prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((path49, line, body) => {
6499
+ comment(path49, Number.parseInt(line, 10), body);
6499
6500
  });
6500
6501
  }
6501
6502
 
@@ -6747,10 +6748,10 @@ function resolveOpSecret(reference) {
6747
6748
  }
6748
6749
 
6749
6750
  // src/commands/ravendb/ravenFetch.ts
6750
- async function ravenFetch(connection, path44) {
6751
+ async function ravenFetch(connection, path49) {
6751
6752
  const apiKey = resolveOpSecret(connection.apiKeyRef);
6752
6753
  let accessToken = await getAccessToken(apiKey);
6753
- const url = `${connection.url}${path44}`;
6754
+ const url = `${connection.url}${path49}`;
6754
6755
  const headers = {
6755
6756
  Authorization: `Bearer ${accessToken}`,
6756
6757
  "Content-Type": "application/json"
@@ -6840,16 +6841,16 @@ import chalk82 from "chalk";
6840
6841
  // src/commands/ravendb/buildQueryPath.ts
6841
6842
  function buildQueryPath(opts) {
6842
6843
  const db = encodeURIComponent(opts.db);
6843
- let path44;
6844
+ let path49;
6844
6845
  if (opts.collection) {
6845
- path44 = `/databases/${db}/indexes/dynamic/${encodeURIComponent(opts.collection)}?start=${opts.start}&pageSize=${opts.pageSize}&sort=${encodeURIComponent(opts.sort)}`;
6846
+ path49 = `/databases/${db}/indexes/dynamic/${encodeURIComponent(opts.collection)}?start=${opts.start}&pageSize=${opts.pageSize}&sort=${encodeURIComponent(opts.sort)}`;
6846
6847
  } else {
6847
- path44 = `/databases/${db}/queries?start=${opts.start}&pageSize=${opts.pageSize}`;
6848
+ path49 = `/databases/${db}/queries?start=${opts.start}&pageSize=${opts.pageSize}`;
6848
6849
  }
6849
6850
  if (opts.query) {
6850
- path44 += `&query=${encodeURIComponent(opts.query)}`;
6851
+ path49 += `&query=${encodeURIComponent(opts.query)}`;
6851
6852
  }
6852
- return path44;
6853
+ return path49;
6853
6854
  }
6854
6855
 
6855
6856
  // src/commands/ravendb/fetchAllPages.ts
@@ -6858,7 +6859,7 @@ async function fetchAllPages(connection, opts) {
6858
6859
  let start3 = 0;
6859
6860
  while (true) {
6860
6861
  const effectivePageSize = opts.limit !== void 0 ? Math.min(opts.pageSize, opts.limit - allResults.length) : opts.pageSize;
6861
- const path44 = buildQueryPath({
6862
+ const path49 = buildQueryPath({
6862
6863
  db: connection.database,
6863
6864
  collection: opts.collection,
6864
6865
  start: start3,
@@ -6866,7 +6867,7 @@ async function fetchAllPages(connection, opts) {
6866
6867
  sort: opts.sort,
6867
6868
  query: opts.query
6868
6869
  });
6869
- const data = await ravenFetch(connection, path44);
6870
+ const data = await ravenFetch(connection, path49);
6870
6871
  const results = data.Results ?? [];
6871
6872
  const totalResults = data.TotalResults ?? 0;
6872
6873
  if (results.length === 0) break;
@@ -7125,98 +7126,685 @@ async function check(pattern2, options2) {
7125
7126
  }
7126
7127
  }
7127
7128
 
7128
- // src/commands/refactor/ignore.ts
7129
- import fs17 from "fs";
7129
+ // src/commands/refactor/extract/index.ts
7130
+ import path32 from "path";
7131
+ import chalk87 from "chalk";
7132
+
7133
+ // src/commands/refactor/extract/applyExtraction.ts
7134
+ import { SyntaxKind as SyntaxKind3 } from "ts-morph";
7135
+
7136
+ // src/commands/refactor/extract/removeStaleImports.ts
7137
+ import { SyntaxKind as SyntaxKind2 } from "ts-morph";
7138
+ function collectReferencedNames(sourceFile) {
7139
+ const names = /* @__PURE__ */ new Set();
7140
+ for (const id of sourceFile.getDescendantsOfKind(SyntaxKind2.Identifier)) {
7141
+ names.add(id.getText());
7142
+ }
7143
+ return names;
7144
+ }
7145
+ function isImportEmpty(importDecl, usedNames) {
7146
+ if (importDecl.getNamedImports().length > 0) return false;
7147
+ const def = importDecl.getDefaultImport();
7148
+ if (def && usedNames.has(def.getText())) return false;
7149
+ const ns = importDecl.getNamespaceImport();
7150
+ if (ns && usedNames.has(ns.getText())) return false;
7151
+ return true;
7152
+ }
7153
+ function removeStaleImports(sourceFile) {
7154
+ const usedNames = collectReferencedNames(sourceFile);
7155
+ for (const importDecl of sourceFile.getImportDeclarations()) {
7156
+ for (const ni of importDecl.getNamedImports()) {
7157
+ const name = ni.getAliasNode()?.getText() ?? ni.getName();
7158
+ if (!usedNames.has(name)) ni.remove();
7159
+ }
7160
+ if (isImportEmpty(importDecl, usedNames)) {
7161
+ importDecl.remove();
7162
+ }
7163
+ }
7164
+ }
7165
+
7166
+ // src/commands/refactor/extract/updateImporters.ts
7167
+ function updateImporters(functionName, sourceFile, importers) {
7168
+ for (const { file: importerFile, relPath: relPath2 } of importers) {
7169
+ let alias;
7170
+ for (const importDecl of importerFile.getImportDeclarations()) {
7171
+ if (importDecl.getModuleSpecifierSourceFile() !== sourceFile) continue;
7172
+ for (const ni of importDecl.getNamedImports()) {
7173
+ if (ni.getName() === functionName) {
7174
+ alias = ni.getAliasNode()?.getText();
7175
+ ni.remove();
7176
+ break;
7177
+ }
7178
+ }
7179
+ if (importDecl.getNamedImports().length === 0 && !importDecl.getDefaultImport() && !importDecl.getNamespaceImport()) {
7180
+ importDecl.remove();
7181
+ }
7182
+ }
7183
+ importerFile.addImportDeclaration({
7184
+ moduleSpecifier: relPath2,
7185
+ namedImports: [alias ? { name: functionName, alias } : functionName]
7186
+ });
7187
+ }
7188
+ }
7189
+
7190
+ // src/commands/refactor/extract/applyExtraction.ts
7191
+ function isNameReferencedInSource(sourceFile, name) {
7192
+ return sourceFile.getDescendantsOfKind(SyntaxKind3.Identifier).some((id) => id.getText() === name);
7193
+ }
7194
+ async function applyExtraction(functionName, sourceFile, destPath, plan2, project) {
7195
+ project.createSourceFile(destPath, plan2.destContent, { overwrite: false });
7196
+ for (const fn of [plan2.target, ...plan2.dependencies]) {
7197
+ fn.remove();
7198
+ }
7199
+ for (const stmt of plan2.statementsToRemove) {
7200
+ stmt.remove();
7201
+ }
7202
+ removeStaleImports(sourceFile);
7203
+ if (isNameReferencedInSource(sourceFile, functionName)) {
7204
+ sourceFile.addImportDeclaration({
7205
+ moduleSpecifier: plan2.destRelPath,
7206
+ namedImports: [functionName]
7207
+ });
7208
+ }
7209
+ updateImporters(functionName, sourceFile, plan2.importersToUpdate);
7210
+ if (plan2.barrel) {
7211
+ plan2.barrel.addExportDeclaration({
7212
+ moduleSpecifier: plan2.barrelRelPath,
7213
+ namedExports: [functionName]
7214
+ });
7215
+ }
7216
+ await project.save();
7217
+ }
7218
+
7219
+ // src/commands/refactor/extract/buildPlan.ts
7220
+ import path29 from "path";
7221
+
7222
+ // src/commands/refactor/extract/collectDependencies.ts
7223
+ import {
7224
+ SyntaxKind as SyntaxKind5
7225
+ } from "ts-morph";
7226
+
7227
+ // src/commands/refactor/extract/collectPrivateFunctions.ts
7228
+ import { SyntaxKind as SyntaxKind4 } from "ts-morph";
7229
+ function isPrivate(fn) {
7230
+ return !fn.isExported() && !fn.isDefaultExport();
7231
+ }
7232
+ function getCalledFunctionNames(fn) {
7233
+ const names = /* @__PURE__ */ new Set();
7234
+ for (const call of fn.getDescendantsOfKind(SyntaxKind4.CallExpression)) {
7235
+ const expr = call.getExpression();
7236
+ if (expr.getKind() === SyntaxKind4.Identifier) {
7237
+ names.add(expr.getText());
7238
+ }
7239
+ }
7240
+ return names;
7241
+ }
7242
+ function collectPrivateFunctions(target, fnMap) {
7243
+ const collected = /* @__PURE__ */ new Set();
7244
+ const queue = [target];
7245
+ let current = queue.pop();
7246
+ while (current) {
7247
+ for (const name of getCalledFunctionNames(current)) {
7248
+ if (collected.has(name)) continue;
7249
+ const fn = fnMap.get(name);
7250
+ if (fn && isPrivate(fn)) {
7251
+ collected.add(name);
7252
+ queue.push(fn);
7253
+ }
7254
+ }
7255
+ current = queue.pop();
7256
+ }
7257
+ return [...collected].flatMap((name) => {
7258
+ const fn = fnMap.get(name);
7259
+ return fn ? [fn] : [];
7260
+ });
7261
+ }
7262
+
7263
+ // src/commands/refactor/extract/getPrivateStatementMap.ts
7264
+ function getPrivateStatementMap(sourceFile) {
7265
+ const map = /* @__PURE__ */ new Map();
7266
+ for (const stmt of sourceFile.getVariableStatements()) {
7267
+ if (stmt.isExported()) continue;
7268
+ for (const decl of stmt.getDeclarations()) map.set(decl.getName(), stmt);
7269
+ }
7270
+ for (const alias of sourceFile.getTypeAliases()) {
7271
+ if (!alias.isExported()) map.set(alias.getName(), alias);
7272
+ }
7273
+ for (const iface of sourceFile.getInterfaces()) {
7274
+ if (!iface.isExported()) map.set(iface.getName(), iface);
7275
+ }
7276
+ return map;
7277
+ }
7278
+
7279
+ // src/commands/refactor/extract/collectDependencies.ts
7280
+ function getReferencedIdentifiers(fn) {
7281
+ const names = /* @__PURE__ */ new Set();
7282
+ for (const id of fn.getDescendantsOfKind(SyntaxKind5.Identifier)) {
7283
+ names.add(id.getText());
7284
+ }
7285
+ return names;
7286
+ }
7287
+ function getFunctionMap(sourceFile) {
7288
+ const map = /* @__PURE__ */ new Map();
7289
+ for (const fn of sourceFile.getDescendantsOfKind(
7290
+ SyntaxKind5.FunctionDeclaration
7291
+ )) {
7292
+ const name = fn.getName();
7293
+ if (name) map.set(name, fn);
7294
+ }
7295
+ return map;
7296
+ }
7297
+ function collectPrivateStatements(functions, stmtMap) {
7298
+ const seen = /* @__PURE__ */ new Set();
7299
+ for (const fn of functions) {
7300
+ for (const name of getReferencedIdentifiers(fn)) {
7301
+ const stmt = stmtMap.get(name);
7302
+ if (stmt) seen.add(stmt);
7303
+ }
7304
+ }
7305
+ return [...seen];
7306
+ }
7307
+ function getRemainingFunctions(sourceFile, extracted) {
7308
+ return sourceFile.getDescendantsOfKind(SyntaxKind5.FunctionDeclaration).filter((fn) => !extracted.has(fn));
7309
+ }
7310
+ function collectDependencies(target, sourceFile) {
7311
+ const fnMap = getFunctionMap(sourceFile);
7312
+ const depFunctions = collectPrivateFunctions(target, fnMap);
7313
+ const allExtracted = [target, ...depFunctions];
7314
+ const stmtMap = getPrivateStatementMap(sourceFile);
7315
+ const toCopy = collectPrivateStatements(allExtracted, stmtMap);
7316
+ const extractedSet = new Set(allExtracted);
7317
+ const remaining = getRemainingFunctions(sourceFile, extractedSet);
7318
+ const usedByRemaining = new Set(collectPrivateStatements(remaining, stmtMap));
7319
+ const toRemove = toCopy.filter((s) => !usedByRemaining.has(s));
7320
+ return {
7321
+ functions: depFunctions,
7322
+ statements: { toCopy, toRemove }
7323
+ };
7324
+ }
7325
+
7326
+ // src/commands/refactor/extract/findFunction.ts
7327
+ import {
7328
+ SyntaxKind as SyntaxKind6
7329
+ } from "ts-morph";
7330
+ function findFunction(sourceFile, functionName) {
7331
+ return sourceFile.getDescendantsOfKind(SyntaxKind6.FunctionDeclaration).find((fn) => fn.getName() === functionName);
7332
+ }
7333
+
7334
+ // src/commands/refactor/extract/getExportedDependencyNames.ts
7335
+ import { SyntaxKind as SyntaxKind7 } from "ts-morph";
7336
+ function getExportedDependencyNames(target, sourceFile) {
7337
+ const calledNames = /* @__PURE__ */ new Set();
7338
+ for (const call of target.getDescendantsOfKind(SyntaxKind7.CallExpression)) {
7339
+ const expr = call.getExpression();
7340
+ if (expr.getKind() === SyntaxKind7.Identifier) {
7341
+ calledNames.add(expr.getText());
7342
+ }
7343
+ }
7344
+ const exported = [];
7345
+ for (const fn of sourceFile.getDescendantsOfKind(
7346
+ SyntaxKind7.FunctionDeclaration
7347
+ )) {
7348
+ const name = fn.getName();
7349
+ if (name && calledNames.has(name) && fn.isExported()) {
7350
+ exported.push(name);
7351
+ }
7352
+ }
7353
+ return exported;
7354
+ }
7355
+
7356
+ // src/commands/refactor/extract/getStatementNames.ts
7357
+ import { SyntaxKind as SyntaxKind8 } from "ts-morph";
7358
+ function getStatementNames(node) {
7359
+ if (node.getKind() === SyntaxKind8.VariableStatement) {
7360
+ const stmt = node;
7361
+ return stmt.getDeclarations().map((d) => d.getName());
7362
+ }
7363
+ const named = node;
7364
+ return named.getName ? [named.getName()] : [];
7365
+ }
7366
+
7367
+ // src/commands/refactor/extract/resolveImports.ts
7368
+ import {
7369
+ SyntaxKind as SyntaxKind9
7370
+ } from "ts-morph";
7371
+
7372
+ // src/commands/refactor/extract/matchImport.ts
7373
+ function matchNamedImports(importDecl, neededNames) {
7374
+ const matched = [];
7375
+ for (const specifier of importDecl.getNamedImports()) {
7376
+ const name = specifier.getAliasNode()?.getText() ?? specifier.getName();
7377
+ if (!neededNames.has(name)) continue;
7378
+ const original = specifier.getName();
7379
+ const alias = specifier.getAliasNode()?.getText();
7380
+ matched.push(alias ? `${original} as ${alias}` : original);
7381
+ }
7382
+ return matched;
7383
+ }
7384
+ function matchOptionalImport(node, neededNames) {
7385
+ return node && neededNames.has(node.getText()) ? node.getText() : void 0;
7386
+ }
7387
+ function matchImport(importDecl, neededNames) {
7388
+ const namedImports = matchNamedImports(importDecl, neededNames);
7389
+ const defaultImport = matchOptionalImport(
7390
+ importDecl.getDefaultImport(),
7391
+ neededNames
7392
+ );
7393
+ const namespaceImport = matchOptionalImport(
7394
+ importDecl.getNamespaceImport(),
7395
+ neededNames
7396
+ );
7397
+ if (namedImports.length === 0 && !defaultImport && !namespaceImport) {
7398
+ return void 0;
7399
+ }
7400
+ return {
7401
+ moduleSpecifier: importDecl.getModuleSpecifierValue(),
7402
+ namedImports,
7403
+ defaultImport,
7404
+ namespaceImport,
7405
+ isTypeOnly: importDecl.isTypeOnly()
7406
+ };
7407
+ }
7408
+
7409
+ // src/commands/refactor/extract/resolveImports.ts
7410
+ function getReferencedNames(nodes) {
7411
+ const names = /* @__PURE__ */ new Set();
7412
+ for (const node of nodes) {
7413
+ for (const id of node.getDescendantsOfKind(SyntaxKind9.Identifier)) {
7414
+ names.add(id.getText());
7415
+ }
7416
+ }
7417
+ return names;
7418
+ }
7419
+ function getLocallyDeclaredNames(functions) {
7420
+ const names = /* @__PURE__ */ new Set();
7421
+ for (const fn of functions) {
7422
+ const name = fn.getName();
7423
+ if (name) names.add(name);
7424
+ for (const param of fn.getParameters()) {
7425
+ names.add(param.getName());
7426
+ }
7427
+ for (const varDecl of fn.getDescendantsOfKind(
7428
+ SyntaxKind9.VariableDeclaration
7429
+ )) {
7430
+ names.add(varDecl.getName());
7431
+ }
7432
+ }
7433
+ return names;
7434
+ }
7435
+ function resolveImports(target, dependencies, sourceFile, statements = []) {
7436
+ const allFunctions = [target, ...dependencies];
7437
+ const allNodes = [...allFunctions, ...statements];
7438
+ const referencedNames = getReferencedNames(allNodes);
7439
+ const localNames = getLocallyDeclaredNames(allFunctions);
7440
+ const externalNames = /* @__PURE__ */ new Set();
7441
+ for (const name of referencedNames) {
7442
+ if (!localNames.has(name)) externalNames.add(name);
7443
+ }
7444
+ const result = [];
7445
+ for (const importDecl of sourceFile.getImportDeclarations()) {
7446
+ const matched = matchImport(importDecl, externalNames);
7447
+ if (matched) result.push(matched);
7448
+ }
7449
+ return result;
7450
+ }
7451
+
7452
+ // src/commands/refactor/extract/analyseTarget.ts
7453
+ function extractTexts(target, allFunctions, statements) {
7454
+ const stmtTexts = statements.map((v) => v.getFullText().trim());
7455
+ const fnTexts = allFunctions.map((fn) => {
7456
+ const text = fn.getFullText().trim();
7457
+ if (fn === target && !text.startsWith("export ")) return `export ${text}`;
7458
+ return text;
7459
+ });
7460
+ return [...stmtTexts, ...fnTexts];
7461
+ }
7462
+ function analyseTarget(sourceFile, functionName) {
7463
+ const target = findFunction(sourceFile, functionName);
7464
+ if (!target) throw new Error(`Function "${functionName}" not found`);
7465
+ const { functions: dependencies, statements } = collectDependencies(
7466
+ target,
7467
+ sourceFile
7468
+ );
7469
+ const all = [target, ...dependencies];
7470
+ return {
7471
+ target,
7472
+ dependencies,
7473
+ statementsToCopy: statements.toCopy,
7474
+ statementsToRemove: statements.toRemove,
7475
+ imports: resolveImports(
7476
+ target,
7477
+ dependencies,
7478
+ sourceFile,
7479
+ statements.toCopy
7480
+ ),
7481
+ exportedDeps: getExportedDependencyNames(target, sourceFile),
7482
+ extractedNames: [
7483
+ ...statements.toRemove.flatMap(getStatementNames),
7484
+ ...all.map((fn) => fn.getName()).filter(Boolean)
7485
+ ],
7486
+ functionTexts: extractTexts(target, all, statements.toCopy)
7487
+ };
7488
+ }
7489
+
7490
+ // src/commands/refactor/extract/formatImportLine.ts
7491
+ function formatImportLine(imp) {
7492
+ const parts = [];
7493
+ if (imp.isTypeOnly) parts.push("type ");
7494
+ if (imp.defaultImport) parts.push(imp.defaultImport);
7495
+ if (imp.namespaceImport) parts.push(`* as ${imp.namespaceImport}`);
7496
+ if (imp.namedImports.length > 0) {
7497
+ if (imp.defaultImport) parts.push(", ");
7498
+ parts.push(`{ ${imp.namedImports.join(", ")} }`);
7499
+ }
7500
+ return `import ${parts.join("")} from "${imp.moduleSpecifier}";`;
7501
+ }
7502
+
7503
+ // src/commands/refactor/extract/buildDestinationContent.ts
7504
+ function buildDestinationContent(functionTexts, imports, sourceRelativePath, sourceImportNames) {
7505
+ const lines = [];
7506
+ for (const imp of imports) {
7507
+ lines.push(formatImportLine(imp));
7508
+ }
7509
+ if (sourceImportNames.length > 0) {
7510
+ lines.push(
7511
+ `import { ${sourceImportNames.join(", ")} } from "${sourceRelativePath}";`
7512
+ );
7513
+ }
7514
+ if (lines.length > 0) lines.push("");
7515
+ for (let i = 0; i < functionTexts.length; i++) {
7516
+ if (i > 0) lines.push("");
7517
+ lines.push(functionTexts[i]);
7518
+ }
7519
+ lines.push("");
7520
+ return lines.join("\n");
7521
+ }
7522
+
7523
+ // src/commands/refactor/extract/getRelativeImportPath.ts
7524
+ import path28 from "path";
7525
+ function getRelativeImportPath(from, to) {
7526
+ let rel = path28.relative(path28.dirname(from), to).replace(/\.tsx?$/, "").replace(/\\/g, "/");
7527
+ if (!rel.startsWith(".")) rel = `./${rel}`;
7528
+ return rel;
7529
+ }
7530
+
7531
+ // src/commands/refactor/extract/findImporters.ts
7532
+ function findImporters(functionName, sourceFile, destPath, project) {
7533
+ const result = [];
7534
+ for (const sf of project.getSourceFiles()) {
7535
+ if (sf === sourceFile) continue;
7536
+ for (const importDecl of sf.getImportDeclarations()) {
7537
+ if (importDecl.getModuleSpecifierSourceFile() !== sourceFile) continue;
7538
+ if (importDecl.getNamedImports().some((ni) => ni.getName() === functionName)) {
7539
+ result.push({
7540
+ file: sf,
7541
+ relPath: getRelativeImportPath(sf.getFilePath(), destPath)
7542
+ });
7543
+ }
7544
+ }
7545
+ }
7546
+ return result;
7547
+ }
7548
+
7549
+ // src/commands/refactor/extract/sourceReferencesName.ts
7550
+ import { SyntaxKind as SyntaxKind10 } from "ts-morph";
7551
+ var DECLARATION_KINDS = /* @__PURE__ */ new Set([
7552
+ SyntaxKind10.FunctionDeclaration,
7553
+ SyntaxKind10.ImportSpecifier,
7554
+ SyntaxKind10.ExportSpecifier
7555
+ ]);
7556
+ function isInsideExtractedFunction(node, extracted) {
7557
+ let current = node;
7558
+ while (current) {
7559
+ if (current.getKind() !== SyntaxKind10.FunctionDeclaration) {
7560
+ current = current.getParent();
7561
+ continue;
7562
+ }
7563
+ const name = current.getName?.();
7564
+ if (name && extracted.has(name)) return true;
7565
+ current = current.getParent();
7566
+ }
7567
+ return false;
7568
+ }
7569
+ function sourceReferencesName(sourceFile, functionName, extractedNames) {
7570
+ const extracted = new Set(extractedNames);
7571
+ for (const id of sourceFile.getDescendantsOfKind(SyntaxKind10.Identifier)) {
7572
+ if (id.getText() !== functionName) continue;
7573
+ const parent = id.getParent();
7574
+ if (!parent || DECLARATION_KINDS.has(parent.getKind())) continue;
7575
+ if (!isInsideExtractedFunction(parent, extracted)) return true;
7576
+ }
7577
+ return false;
7578
+ }
7579
+
7580
+ // src/commands/refactor/extract/buildPlan.ts
7581
+ function resolveBarrel(destPath, project) {
7582
+ const indexPath = path29.join(path29.dirname(destPath), "index.ts");
7583
+ return {
7584
+ barrel: project.getSourceFile(indexPath),
7585
+ barrelRelPath: getRelativeImportPath(indexPath, destPath)
7586
+ };
7587
+ }
7588
+ function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
7589
+ const analysis = analyseTarget(sourceFile, functionName);
7590
+ const sourceRelPath = getRelativeImportPath(destPath, sourcePath);
7591
+ const { functionTexts: _, ...planFields } = analysis;
7592
+ return {
7593
+ ...planFields,
7594
+ destContent: buildDestinationContent(
7595
+ analysis.functionTexts,
7596
+ analysis.imports,
7597
+ sourceRelPath,
7598
+ analysis.exportedDeps
7599
+ ),
7600
+ destRelPath: getRelativeImportPath(sourcePath, destPath),
7601
+ sourceRelPath,
7602
+ sourceNeedsReimport: sourceReferencesName(
7603
+ sourceFile,
7604
+ functionName,
7605
+ analysis.extractedNames
7606
+ ),
7607
+ importersToUpdate: analysis.target.isExported() ? findImporters(functionName, sourceFile, destPath, project) : [],
7608
+ ...resolveBarrel(destPath, project)
7609
+ };
7610
+ }
7611
+
7612
+ // src/commands/refactor/extract/displayPlan.ts
7613
+ import path30 from "path";
7130
7614
  import chalk85 from "chalk";
7615
+ function section(title) {
7616
+ return `
7617
+ ${chalk85.cyan(title)}`;
7618
+ }
7619
+ function displayImporters(plan2, cwd) {
7620
+ if (plan2.importersToUpdate.length === 0) return;
7621
+ console.log(section("Update importers:"));
7622
+ for (const imp of plan2.importersToUpdate) {
7623
+ const rel = path30.relative(cwd, imp.file.getFilePath());
7624
+ console.log(` ${chalk85.dim(rel)}: \u2192 import from "${imp.relPath}"`);
7625
+ }
7626
+ }
7627
+ function displayPlan(functionName, relDest, plan2, cwd) {
7628
+ console.log(chalk85.bold(`Extract: ${functionName} \u2192 ${relDest}
7629
+ `));
7630
+ console.log(` ${chalk85.cyan("Functions to move:")}`);
7631
+ for (const name of plan2.extractedNames) {
7632
+ console.log(` ${name}`);
7633
+ }
7634
+ if (plan2.imports.length > 0) {
7635
+ console.log(section("Imports to copy:"));
7636
+ for (const imp of plan2.imports) {
7637
+ console.log(` ${formatImportLine(imp)}`);
7638
+ }
7639
+ }
7640
+ if (plan2.exportedDeps.length > 0) {
7641
+ console.log(section("New imports from source:"));
7642
+ console.log(
7643
+ ` import { ${plan2.exportedDeps.join(", ")} } from "${plan2.sourceRelPath}";`
7644
+ );
7645
+ }
7646
+ console.log(section("Source file changes:"));
7647
+ console.log(` Remove: ${plan2.extractedNames.join(", ")}`);
7648
+ if (plan2.sourceNeedsReimport) {
7649
+ console.log(
7650
+ ` Add: import { ${functionName} } from "${plan2.destRelPath}";`
7651
+ );
7652
+ }
7653
+ displayImporters(plan2, cwd);
7654
+ if (plan2.barrel) {
7655
+ console.log(section("Barrel export:"));
7656
+ console.log(
7657
+ ` Add: export { ${functionName} } from "${plan2.barrelRelPath}";`
7658
+ );
7659
+ }
7660
+ }
7661
+
7662
+ // src/commands/refactor/extract/loadProjectFile.ts
7663
+ import fs17 from "fs";
7664
+ import path31 from "path";
7665
+ import chalk86 from "chalk";
7666
+ import { Project as Project2 } from "ts-morph";
7667
+ function findTsConfig(sourcePath) {
7668
+ const rootConfig = path31.resolve("tsconfig.json");
7669
+ if (!fs17.existsSync(rootConfig)) return rootConfig;
7670
+ const raw = fs17.readFileSync(rootConfig, "utf-8");
7671
+ const stripped = raw.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
7672
+ let parsed;
7673
+ try {
7674
+ parsed = JSON.parse(stripped);
7675
+ } catch {
7676
+ return rootConfig;
7677
+ }
7678
+ if (!parsed.references?.length) return rootConfig;
7679
+ for (const ref of parsed.references) {
7680
+ const refPath = path31.resolve(ref.path);
7681
+ const configPath = fs17.statSync(refPath, { throwIfNoEntry: false })?.isDirectory() ? path31.join(refPath, "tsconfig.json") : refPath;
7682
+ if (!fs17.existsSync(configPath)) continue;
7683
+ const project = new Project2({ tsConfigFilePath: configPath });
7684
+ if (project.getSourceFile(sourcePath)) return configPath;
7685
+ }
7686
+ return rootConfig;
7687
+ }
7688
+ function loadProjectFile(file) {
7689
+ const sourcePath = path31.resolve(file);
7690
+ const tsConfigPath = findTsConfig(sourcePath);
7691
+ const project = new Project2({
7692
+ tsConfigFilePath: tsConfigPath
7693
+ });
7694
+ const sourceFile = project.getSourceFile(sourcePath);
7695
+ if (!sourceFile) {
7696
+ console.log(chalk86.red(`File not found in project: ${file}`));
7697
+ process.exit(1);
7698
+ }
7699
+ return { project, sourceFile };
7700
+ }
7701
+
7702
+ // src/commands/refactor/extract/index.ts
7703
+ async function extract(file, functionName, destination, options2 = {}) {
7704
+ const sourcePath = path32.resolve(file);
7705
+ const destPath = path32.resolve(destination);
7706
+ const cwd = process.cwd();
7707
+ const relDest = path32.relative(cwd, destPath);
7708
+ const { project, sourceFile } = loadProjectFile(file);
7709
+ const plan2 = buildPlan(
7710
+ functionName,
7711
+ sourceFile,
7712
+ sourcePath,
7713
+ destPath,
7714
+ project
7715
+ );
7716
+ displayPlan(functionName, relDest, plan2, cwd);
7717
+ if (options2.apply) {
7718
+ await applyExtraction(functionName, sourceFile, destPath, plan2, project);
7719
+ console.log(chalk87.green("\nExtraction complete"));
7720
+ } else {
7721
+ console.log(chalk87.dim("\nDry run. Use --apply to execute."));
7722
+ }
7723
+ }
7724
+
7725
+ // src/commands/refactor/ignore.ts
7726
+ import fs18 from "fs";
7727
+ import chalk88 from "chalk";
7131
7728
  var REFACTOR_YML_PATH2 = "refactor.yml";
7132
7729
  function ignore(file) {
7133
- if (!fs17.existsSync(file)) {
7134
- console.error(chalk85.red(`Error: File does not exist: ${file}`));
7730
+ if (!fs18.existsSync(file)) {
7731
+ console.error(chalk88.red(`Error: File does not exist: ${file}`));
7135
7732
  process.exit(1);
7136
7733
  }
7137
- const content = fs17.readFileSync(file, "utf-8");
7734
+ const content = fs18.readFileSync(file, "utf-8");
7138
7735
  const lineCount = content.split("\n").length;
7139
7736
  const maxLines = lineCount + 10;
7140
7737
  const entry = `- file: ${file}
7141
7738
  maxLines: ${maxLines}
7142
7739
  `;
7143
- if (fs17.existsSync(REFACTOR_YML_PATH2)) {
7144
- const existing = fs17.readFileSync(REFACTOR_YML_PATH2, "utf-8");
7145
- fs17.writeFileSync(REFACTOR_YML_PATH2, existing + entry);
7740
+ if (fs18.existsSync(REFACTOR_YML_PATH2)) {
7741
+ const existing = fs18.readFileSync(REFACTOR_YML_PATH2, "utf-8");
7742
+ fs18.writeFileSync(REFACTOR_YML_PATH2, existing + entry);
7146
7743
  } else {
7147
- fs17.writeFileSync(REFACTOR_YML_PATH2, entry);
7744
+ fs18.writeFileSync(REFACTOR_YML_PATH2, entry);
7148
7745
  }
7149
7746
  console.log(
7150
- chalk85.green(
7747
+ chalk88.green(
7151
7748
  `Added ${file} to refactor ignore list (max ${maxLines} lines)`
7152
7749
  )
7153
7750
  );
7154
7751
  }
7155
7752
 
7156
7753
  // src/commands/refactor/rename/index.ts
7157
- import path28 from "path";
7158
- import chalk86 from "chalk";
7159
- import { Project as Project2 } from "ts-morph";
7754
+ import path33 from "path";
7755
+ import chalk89 from "chalk";
7160
7756
  async function rename(source, destination, options2 = {}) {
7161
- const sourcePath = path28.resolve(source);
7162
- const destPath = path28.resolve(destination);
7757
+ const destPath = path33.resolve(destination);
7163
7758
  const cwd = process.cwd();
7164
- const relSource = path28.relative(cwd, sourcePath);
7165
- const relDest = path28.relative(cwd, destPath);
7166
- const project = new Project2({
7167
- tsConfigFilePath: path28.resolve("tsconfig.json")
7168
- });
7169
- const sourceFile = project.getSourceFile(sourcePath);
7170
- if (!sourceFile) {
7171
- console.log(chalk86.red(`File not found in project: ${source}`));
7172
- process.exit(1);
7173
- }
7174
- console.log(chalk86.bold(`Rename: ${relSource} \u2192 ${relDest}`));
7759
+ const relSource = path33.relative(cwd, path33.resolve(source));
7760
+ const relDest = path33.relative(cwd, destPath);
7761
+ const { project, sourceFile } = loadProjectFile(source);
7762
+ console.log(chalk89.bold(`Rename: ${relSource} \u2192 ${relDest}`));
7175
7763
  if (options2.apply) {
7176
7764
  sourceFile.move(destPath);
7177
7765
  await project.save();
7178
- console.log(chalk86.green("Done"));
7766
+ console.log(chalk89.green("Done"));
7179
7767
  } else {
7180
- console.log(chalk86.dim("Dry run. Use --apply to execute."));
7768
+ console.log(chalk89.dim("Dry run. Use --apply to execute."));
7181
7769
  }
7182
7770
  }
7183
7771
 
7184
7772
  // src/commands/refactor/renameSymbol/index.ts
7185
- import path30 from "path";
7186
- import chalk87 from "chalk";
7773
+ import path35 from "path";
7774
+ import chalk90 from "chalk";
7187
7775
  import { Project as Project3 } from "ts-morph";
7188
7776
 
7189
7777
  // src/commands/refactor/renameSymbol/findSymbol.ts
7190
- import { SyntaxKind as SyntaxKind2 } from "ts-morph";
7778
+ import { SyntaxKind as SyntaxKind11 } from "ts-morph";
7191
7779
  var declarationKinds = [
7192
- SyntaxKind2.VariableDeclaration,
7193
- SyntaxKind2.FunctionDeclaration,
7194
- SyntaxKind2.ClassDeclaration,
7195
- SyntaxKind2.InterfaceDeclaration,
7196
- SyntaxKind2.TypeAliasDeclaration,
7197
- SyntaxKind2.EnumDeclaration,
7198
- SyntaxKind2.PropertyDeclaration,
7199
- SyntaxKind2.MethodDeclaration,
7200
- SyntaxKind2.Parameter
7780
+ SyntaxKind11.VariableDeclaration,
7781
+ SyntaxKind11.FunctionDeclaration,
7782
+ SyntaxKind11.ClassDeclaration,
7783
+ SyntaxKind11.InterfaceDeclaration,
7784
+ SyntaxKind11.TypeAliasDeclaration,
7785
+ SyntaxKind11.EnumDeclaration,
7786
+ SyntaxKind11.PropertyDeclaration,
7787
+ SyntaxKind11.MethodDeclaration,
7788
+ SyntaxKind11.Parameter
7201
7789
  ];
7202
7790
  function isDeclaration(identifier) {
7203
7791
  const parent = identifier.getParent();
7204
7792
  return parent !== void 0 && declarationKinds.includes(parent.getKind());
7205
7793
  }
7206
7794
  function findSymbol(sourceFile, symbolName) {
7207
- for (const id of sourceFile.getDescendantsOfKind(SyntaxKind2.Identifier)) {
7795
+ for (const id of sourceFile.getDescendantsOfKind(SyntaxKind11.Identifier)) {
7208
7796
  if (id.getText() === symbolName && isDeclaration(id)) return id;
7209
7797
  }
7210
7798
  return void 0;
7211
7799
  }
7212
7800
 
7213
7801
  // src/commands/refactor/renameSymbol/groupReferences.ts
7214
- import path29 from "path";
7802
+ import path34 from "path";
7215
7803
  function groupReferences(symbol, cwd) {
7216
7804
  const refs = symbol.findReferencesAsNodes();
7217
7805
  const grouped = /* @__PURE__ */ new Map();
7218
7806
  for (const ref of refs) {
7219
- const refFile = path29.relative(cwd, ref.getSourceFile().getFilePath());
7807
+ const refFile = path34.relative(cwd, ref.getSourceFile().getFilePath());
7220
7808
  const lines = grouped.get(refFile) ?? [];
7221
7809
  if (!grouped.has(refFile)) grouped.set(refFile, lines);
7222
7810
  lines.push(ref.getStartLineNumber());
@@ -7226,47 +7814,47 @@ function groupReferences(symbol, cwd) {
7226
7814
 
7227
7815
  // src/commands/refactor/renameSymbol/index.ts
7228
7816
  async function renameSymbol(file, oldName, newName, options2 = {}) {
7229
- const filePath = path30.resolve(file);
7230
- const tsConfigPath = path30.resolve("tsconfig.json");
7817
+ const filePath = path35.resolve(file);
7818
+ const tsConfigPath = path35.resolve("tsconfig.json");
7231
7819
  const cwd = process.cwd();
7232
7820
  const project = new Project3({ tsConfigFilePath: tsConfigPath });
7233
7821
  const sourceFile = project.getSourceFile(filePath);
7234
7822
  if (!sourceFile) {
7235
- console.log(chalk87.red(`File not found in project: ${file}`));
7823
+ console.log(chalk90.red(`File not found in project: ${file}`));
7236
7824
  process.exit(1);
7237
7825
  }
7238
7826
  const symbol = findSymbol(sourceFile, oldName);
7239
7827
  if (!symbol) {
7240
- console.log(chalk87.red(`Symbol "${oldName}" not found in ${file}`));
7828
+ console.log(chalk90.red(`Symbol "${oldName}" not found in ${file}`));
7241
7829
  process.exit(1);
7242
7830
  }
7243
7831
  const grouped = groupReferences(symbol, cwd);
7244
7832
  const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
7245
7833
  console.log(
7246
- chalk87.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
7834
+ chalk90.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
7247
7835
  `)
7248
7836
  );
7249
7837
  for (const [refFile, lines] of grouped) {
7250
7838
  console.log(
7251
- ` ${chalk87.dim(refFile)}: lines ${chalk87.cyan(lines.join(", "))}`
7839
+ ` ${chalk90.dim(refFile)}: lines ${chalk90.cyan(lines.join(", "))}`
7252
7840
  );
7253
7841
  }
7254
7842
  if (options2.apply) {
7255
7843
  symbol.rename(newName);
7256
7844
  await project.save();
7257
- console.log(chalk87.green(`
7845
+ console.log(chalk90.green(`
7258
7846
  Renamed ${oldName} \u2192 ${newName}`));
7259
7847
  } else {
7260
- console.log(chalk87.dim("\nDry run. Use --apply to execute."));
7848
+ console.log(chalk90.dim("\nDry run. Use --apply to execute."));
7261
7849
  }
7262
7850
  }
7263
7851
 
7264
7852
  // src/commands/refactor/restructure/index.ts
7265
- import path39 from "path";
7266
- import chalk90 from "chalk";
7853
+ import path44 from "path";
7854
+ import chalk93 from "chalk";
7267
7855
 
7268
7856
  // src/commands/refactor/restructure/buildImportGraph/index.ts
7269
- import path31 from "path";
7857
+ import path36 from "path";
7270
7858
  import ts7 from "typescript";
7271
7859
 
7272
7860
  // src/commands/refactor/restructure/buildImportGraph/getImportSpecifiers.ts
@@ -7293,7 +7881,7 @@ function loadParsedConfig(tsConfigPath) {
7293
7881
  return ts7.parseJsonConfigFileContent(
7294
7882
  configFile.config,
7295
7883
  ts7.sys,
7296
- path31.dirname(tsConfigPath)
7884
+ path36.dirname(tsConfigPath)
7297
7885
  );
7298
7886
  }
7299
7887
  function addToSetMap(map, key, value) {
@@ -7309,7 +7897,7 @@ function resolveImport(specifier, filePath, options2) {
7309
7897
  const resolved = ts7.resolveModuleName(specifier, filePath, options2, ts7.sys);
7310
7898
  const resolvedPath = resolved.resolvedModule?.resolvedFileName;
7311
7899
  if (!resolvedPath || resolvedPath.includes("node_modules")) return null;
7312
- return path31.resolve(resolvedPath);
7900
+ return path36.resolve(resolvedPath);
7313
7901
  }
7314
7902
  function buildImportGraph(candidateFiles, tsConfigPath) {
7315
7903
  const parsed = loadParsedConfig(tsConfigPath);
@@ -7318,7 +7906,7 @@ function buildImportGraph(candidateFiles, tsConfigPath) {
7318
7906
  const importedBy = /* @__PURE__ */ new Map();
7319
7907
  const imports = /* @__PURE__ */ new Map();
7320
7908
  for (const sourceFile of program2.getSourceFiles()) {
7321
- const filePath = path31.resolve(sourceFile.fileName);
7909
+ const filePath = path36.resolve(sourceFile.fileName);
7322
7910
  if (filePath.includes("node_modules")) continue;
7323
7911
  for (const specifier of getImportSpecifiers(sourceFile)) {
7324
7912
  const absTarget = resolveImport(specifier, filePath, parsed.options);
@@ -7332,12 +7920,12 @@ function buildImportGraph(candidateFiles, tsConfigPath) {
7332
7920
  }
7333
7921
 
7334
7922
  // src/commands/refactor/restructure/clusterDirectories.ts
7335
- import path32 from "path";
7923
+ import path37 from "path";
7336
7924
  function clusterDirectories(graph) {
7337
7925
  const dirImportedBy = /* @__PURE__ */ new Map();
7338
7926
  for (const edge of graph.edges) {
7339
- const sourceDir = path32.dirname(edge.source);
7340
- const targetDir = path32.dirname(edge.target);
7927
+ const sourceDir = path37.dirname(edge.source);
7928
+ const targetDir = path37.dirname(edge.target);
7341
7929
  if (sourceDir === targetDir) continue;
7342
7930
  if (!graph.files.has(edge.target)) continue;
7343
7931
  const existing = dirImportedBy.get(targetDir) ?? /* @__PURE__ */ new Set();
@@ -7365,20 +7953,20 @@ function clusterDirectories(graph) {
7365
7953
  return clusters;
7366
7954
  }
7367
7955
  function isAncestor(ancestor, descendant) {
7368
- const rel = path32.relative(ancestor, descendant);
7956
+ const rel = path37.relative(ancestor, descendant);
7369
7957
  return !rel.startsWith("..") && rel !== "";
7370
7958
  }
7371
7959
 
7372
7960
  // src/commands/refactor/restructure/clusterFiles.ts
7373
- import path33 from "path";
7961
+ import path38 from "path";
7374
7962
  function findRootParent(file, importedBy, visited) {
7375
7963
  const importers = importedBy.get(file);
7376
7964
  if (!importers || importers.size !== 1) return file;
7377
7965
  const parent = [...importers][0];
7378
- const parentDir = path33.dirname(parent);
7379
- const fileDir = path33.dirname(file);
7966
+ const parentDir = path38.dirname(parent);
7967
+ const fileDir = path38.dirname(file);
7380
7968
  if (parentDir !== fileDir) return file;
7381
- if (path33.basename(parent, path33.extname(parent)) === "index") return file;
7969
+ if (path38.basename(parent, path38.extname(parent)) === "index") return file;
7382
7970
  if (visited.has(parent)) return file;
7383
7971
  visited.add(parent);
7384
7972
  return findRootParent(parent, importedBy, visited);
@@ -7386,16 +7974,16 @@ function findRootParent(file, importedBy, visited) {
7386
7974
  function clusterFiles(graph) {
7387
7975
  const clusters = /* @__PURE__ */ new Map();
7388
7976
  for (const file of graph.files) {
7389
- const basename7 = path33.basename(file, path33.extname(file));
7977
+ const basename7 = path38.basename(file, path38.extname(file));
7390
7978
  if (basename7 === "index") continue;
7391
7979
  const importers = graph.importedBy.get(file);
7392
7980
  if (!importers || importers.size !== 1) continue;
7393
7981
  const parent = [...importers][0];
7394
7982
  if (!graph.files.has(parent)) continue;
7395
- const parentDir = path33.dirname(parent);
7396
- const fileDir = path33.dirname(file);
7983
+ const parentDir = path38.dirname(parent);
7984
+ const fileDir = path38.dirname(file);
7397
7985
  if (parentDir !== fileDir) continue;
7398
- const parentBasename = path33.basename(parent, path33.extname(parent));
7986
+ const parentBasename = path38.basename(parent, path38.extname(parent));
7399
7987
  if (parentBasename === "index") continue;
7400
7988
  const root = findRootParent(parent, graph.importedBy, /* @__PURE__ */ new Set([file]));
7401
7989
  if (!root || root === file) continue;
@@ -7407,10 +7995,10 @@ function clusterFiles(graph) {
7407
7995
  }
7408
7996
 
7409
7997
  // src/commands/refactor/restructure/computeRewrites/index.ts
7410
- import path34 from "path";
7998
+ import path39 from "path";
7411
7999
 
7412
8000
  // src/commands/refactor/restructure/computeRewrites/applyRewrites.ts
7413
- import fs18 from "fs";
8001
+ import fs19 from "fs";
7414
8002
  function getOrCreateList(map, key) {
7415
8003
  const list4 = map.get(key) ?? [];
7416
8004
  if (!map.has(key)) map.set(key, list4);
@@ -7429,7 +8017,7 @@ function rewriteSpecifier(content, oldSpecifier, newSpecifier) {
7429
8017
  return content.replace(pattern2, `$1${newSpecifier}$2`);
7430
8018
  }
7431
8019
  function applyFileRewrites(file, fileRewrites) {
7432
- let content = fs18.readFileSync(file, "utf-8");
8020
+ let content = fs19.readFileSync(file, "utf-8");
7433
8021
  for (const { oldSpecifier, newSpecifier } of fileRewrites) {
7434
8022
  content = rewriteSpecifier(content, oldSpecifier, newSpecifier);
7435
8023
  }
@@ -7461,7 +8049,7 @@ function normalizeSpecifier(rel) {
7461
8049
  );
7462
8050
  }
7463
8051
  function computeSpecifier(fromFile, toFile) {
7464
- return normalizeSpecifier(path34.relative(path34.dirname(fromFile), toFile));
8052
+ return normalizeSpecifier(path39.relative(path39.dirname(fromFile), toFile));
7465
8053
  }
7466
8054
  function isAffected(edge, moveMap) {
7467
8055
  return moveMap.has(edge.target) || moveMap.has(edge.source);
@@ -7505,51 +8093,51 @@ function computeRewrites(moves, edges, allProjectFiles) {
7505
8093
  }
7506
8094
 
7507
8095
  // src/commands/refactor/restructure/displayPlan.ts
7508
- import path35 from "path";
7509
- import chalk88 from "chalk";
8096
+ import path40 from "path";
8097
+ import chalk91 from "chalk";
7510
8098
  function relPath(filePath) {
7511
- return path35.relative(process.cwd(), filePath);
8099
+ return path40.relative(process.cwd(), filePath);
7512
8100
  }
7513
8101
  function displayMoves(plan2) {
7514
8102
  if (plan2.moves.length === 0) return;
7515
- console.log(chalk88.bold("\nFile moves:"));
8103
+ console.log(chalk91.bold("\nFile moves:"));
7516
8104
  for (const move of plan2.moves) {
7517
8105
  console.log(
7518
- ` ${chalk88.red(relPath(move.from))} \u2192 ${chalk88.green(relPath(move.to))}`
8106
+ ` ${chalk91.red(relPath(move.from))} \u2192 ${chalk91.green(relPath(move.to))}`
7519
8107
  );
7520
- console.log(chalk88.dim(` ${move.reason}`));
8108
+ console.log(chalk91.dim(` ${move.reason}`));
7521
8109
  }
7522
8110
  }
7523
8111
  function displayRewrites(rewrites) {
7524
8112
  if (rewrites.length === 0) return;
7525
8113
  const affectedFiles = new Set(rewrites.map((r) => r.file));
7526
- console.log(chalk88.bold(`
8114
+ console.log(chalk91.bold(`
7527
8115
  Import rewrites (${affectedFiles.size} files):`));
7528
8116
  for (const file of affectedFiles) {
7529
- console.log(` ${chalk88.cyan(relPath(file))}:`);
8117
+ console.log(` ${chalk91.cyan(relPath(file))}:`);
7530
8118
  for (const { oldSpecifier, newSpecifier } of rewrites.filter(
7531
8119
  (r) => r.file === file
7532
8120
  )) {
7533
8121
  console.log(
7534
- ` ${chalk88.red(`"${oldSpecifier}"`)} \u2192 ${chalk88.green(`"${newSpecifier}"`)}`
8122
+ ` ${chalk91.red(`"${oldSpecifier}"`)} \u2192 ${chalk91.green(`"${newSpecifier}"`)}`
7535
8123
  );
7536
8124
  }
7537
8125
  }
7538
8126
  }
7539
- function displayPlan(plan2) {
8127
+ function displayPlan2(plan2) {
7540
8128
  if (plan2.warnings.length > 0) {
7541
- console.log(chalk88.yellow("\nWarnings:"));
7542
- for (const w of plan2.warnings) console.log(chalk88.yellow(` ${w}`));
8129
+ console.log(chalk91.yellow("\nWarnings:"));
8130
+ for (const w of plan2.warnings) console.log(chalk91.yellow(` ${w}`));
7543
8131
  }
7544
8132
  if (plan2.newDirectories.length > 0) {
7545
- console.log(chalk88.bold("\nNew directories:"));
8133
+ console.log(chalk91.bold("\nNew directories:"));
7546
8134
  for (const dir of plan2.newDirectories)
7547
- console.log(chalk88.green(` ${dir}/`));
8135
+ console.log(chalk91.green(` ${dir}/`));
7548
8136
  }
7549
8137
  displayMoves(plan2);
7550
8138
  displayRewrites(plan2.rewrites);
7551
8139
  console.log(
7552
- chalk88.dim(
8140
+ chalk91.dim(
7553
8141
  `
7554
8142
  Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
7555
8143
  )
@@ -7557,45 +8145,45 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
7557
8145
  }
7558
8146
 
7559
8147
  // src/commands/refactor/restructure/executePlan.ts
7560
- import fs19 from "fs";
7561
- import path36 from "path";
7562
- import chalk89 from "chalk";
8148
+ import fs20 from "fs";
8149
+ import path41 from "path";
8150
+ import chalk92 from "chalk";
7563
8151
  function executePlan(plan2) {
7564
8152
  const updatedContents = applyRewrites(plan2.rewrites);
7565
8153
  for (const [file, content] of updatedContents) {
7566
- fs19.writeFileSync(file, content, "utf-8");
8154
+ fs20.writeFileSync(file, content, "utf-8");
7567
8155
  console.log(
7568
- chalk89.cyan(` Rewrote imports in ${path36.relative(process.cwd(), file)}`)
8156
+ chalk92.cyan(` Rewrote imports in ${path41.relative(process.cwd(), file)}`)
7569
8157
  );
7570
8158
  }
7571
8159
  for (const dir of plan2.newDirectories) {
7572
- fs19.mkdirSync(dir, { recursive: true });
7573
- console.log(chalk89.green(` Created ${path36.relative(process.cwd(), dir)}/`));
8160
+ fs20.mkdirSync(dir, { recursive: true });
8161
+ console.log(chalk92.green(` Created ${path41.relative(process.cwd(), dir)}/`));
7574
8162
  }
7575
8163
  for (const move of plan2.moves) {
7576
- const targetDir = path36.dirname(move.to);
7577
- if (!fs19.existsSync(targetDir)) {
7578
- fs19.mkdirSync(targetDir, { recursive: true });
8164
+ const targetDir = path41.dirname(move.to);
8165
+ if (!fs20.existsSync(targetDir)) {
8166
+ fs20.mkdirSync(targetDir, { recursive: true });
7579
8167
  }
7580
- fs19.renameSync(move.from, move.to);
8168
+ fs20.renameSync(move.from, move.to);
7581
8169
  console.log(
7582
- chalk89.white(
7583
- ` Moved ${path36.relative(process.cwd(), move.from)} \u2192 ${path36.relative(process.cwd(), move.to)}`
8170
+ chalk92.white(
8171
+ ` Moved ${path41.relative(process.cwd(), move.from)} \u2192 ${path41.relative(process.cwd(), move.to)}`
7584
8172
  )
7585
8173
  );
7586
8174
  }
7587
- removeEmptyDirectories(plan2.moves.map((m) => path36.dirname(m.from)));
8175
+ removeEmptyDirectories(plan2.moves.map((m) => path41.dirname(m.from)));
7588
8176
  }
7589
8177
  function removeEmptyDirectories(dirs) {
7590
8178
  const unique = [...new Set(dirs)];
7591
8179
  for (const dir of unique) {
7592
- if (!fs19.existsSync(dir)) continue;
7593
- const entries = fs19.readdirSync(dir);
8180
+ if (!fs20.existsSync(dir)) continue;
8181
+ const entries = fs20.readdirSync(dir);
7594
8182
  if (entries.length === 0) {
7595
- fs19.rmdirSync(dir);
8183
+ fs20.rmdirSync(dir);
7596
8184
  console.log(
7597
- chalk89.dim(
7598
- ` Removed empty directory ${path36.relative(process.cwd(), dir)}`
8185
+ chalk92.dim(
8186
+ ` Removed empty directory ${path41.relative(process.cwd(), dir)}`
7599
8187
  )
7600
8188
  );
7601
8189
  }
@@ -7603,46 +8191,46 @@ function removeEmptyDirectories(dirs) {
7603
8191
  }
7604
8192
 
7605
8193
  // src/commands/refactor/restructure/planFileMoves/index.ts
7606
- import path38 from "path";
8194
+ import path43 from "path";
7607
8195
 
7608
8196
  // src/commands/refactor/restructure/planFileMoves/shared.ts
7609
- import fs20 from "fs";
8197
+ import fs21 from "fs";
7610
8198
  function emptyResult() {
7611
8199
  return { moves: [], directories: [], warnings: [] };
7612
8200
  }
7613
8201
  function checkDirConflict(result, label2, dir) {
7614
- if (!fs20.existsSync(dir)) return false;
8202
+ if (!fs21.existsSync(dir)) return false;
7615
8203
  result.warnings.push(`Skipping ${label2}: directory ${dir} already exists`);
7616
8204
  return true;
7617
8205
  }
7618
8206
 
7619
8207
  // src/commands/refactor/restructure/planFileMoves/planDirectoryMoves.ts
7620
- import fs21 from "fs";
7621
- import path37 from "path";
8208
+ import fs22 from "fs";
8209
+ import path42 from "path";
7622
8210
  function collectEntry(results, dir, entry) {
7623
- const full = path37.join(dir, entry.name);
8211
+ const full = path42.join(dir, entry.name);
7624
8212
  const items = entry.isDirectory() ? listFilesRecursive(full) : [full];
7625
8213
  results.push(...items);
7626
8214
  }
7627
8215
  function listFilesRecursive(dir) {
7628
- if (!fs21.existsSync(dir)) return [];
8216
+ if (!fs22.existsSync(dir)) return [];
7629
8217
  const results = [];
7630
- for (const entry of fs21.readdirSync(dir, { withFileTypes: true })) {
8218
+ for (const entry of fs22.readdirSync(dir, { withFileTypes: true })) {
7631
8219
  collectEntry(results, dir, entry);
7632
8220
  }
7633
8221
  return results;
7634
8222
  }
7635
8223
  function addDirectoryFileMoves(moves, childDir, newLocation, reason) {
7636
8224
  for (const file of listFilesRecursive(childDir)) {
7637
- const rel = path37.relative(childDir, file);
7638
- moves.push({ from: file, to: path37.join(newLocation, rel), reason });
8225
+ const rel = path42.relative(childDir, file);
8226
+ moves.push({ from: file, to: path42.join(newLocation, rel), reason });
7639
8227
  }
7640
8228
  }
7641
8229
  function resolveChildDest(parentDir, childDir) {
7642
- return path37.join(parentDir, path37.basename(childDir));
8230
+ return path42.join(parentDir, path42.basename(childDir));
7643
8231
  }
7644
8232
  function childMoveReason(parentDir) {
7645
- return `Directory only imported from ${path37.basename(parentDir)}/`;
8233
+ return `Directory only imported from ${path42.basename(parentDir)}/`;
7646
8234
  }
7647
8235
  function registerDirectoryMove(result, childDir, dest, parentDir) {
7648
8236
  result.directories.push(dest);
@@ -7667,7 +8255,7 @@ function planDirectoryMoves(clusters) {
7667
8255
 
7668
8256
  // src/commands/refactor/restructure/planFileMoves/index.ts
7669
8257
  function childMoveData(child, newDir, parentBase) {
7670
- const to = path38.join(newDir, path38.basename(child));
8258
+ const to = path43.join(newDir, path43.basename(child));
7671
8259
  return { from: child, to, reason: `Only imported by ${parentBase}` };
7672
8260
  }
7673
8261
  function addChildMoves(moves, children, newDir, parentBase) {
@@ -7675,15 +8263,15 @@ function addChildMoves(moves, children, newDir, parentBase) {
7675
8263
  moves.push(childMoveData(child, newDir, parentBase));
7676
8264
  }
7677
8265
  function getBaseName(filePath) {
7678
- return path38.basename(filePath, path38.extname(filePath));
8266
+ return path43.basename(filePath, path43.extname(filePath));
7679
8267
  }
7680
8268
  function resolveClusterDir(parent) {
7681
- return path38.join(path38.dirname(parent), getBaseName(parent));
8269
+ return path43.join(path43.dirname(parent), getBaseName(parent));
7682
8270
  }
7683
8271
  function createParentMove(parent, newDir) {
7684
8272
  return {
7685
8273
  from: parent,
7686
- to: path38.join(newDir, `index${path38.extname(parent)}`),
8274
+ to: path43.join(newDir, `index${path43.extname(parent)}`),
7687
8275
  reason: `Main module of new ${getBaseName(parent)}/ directory`
7688
8276
  };
7689
8277
  }
@@ -7706,8 +8294,8 @@ function planFileMoves(clusters) {
7706
8294
  }
7707
8295
 
7708
8296
  // src/commands/refactor/restructure/index.ts
7709
- function buildPlan(candidateFiles, tsConfigPath) {
7710
- const candidates = new Set(candidateFiles.map((f) => path39.resolve(f)));
8297
+ function buildPlan2(candidateFiles, tsConfigPath) {
8298
+ const candidates = new Set(candidateFiles.map((f) => path44.resolve(f)));
7711
8299
  const graph = buildImportGraph(candidates, tsConfigPath);
7712
8300
  const allProjectFiles = /* @__PURE__ */ new Set([
7713
8301
  ...graph.importedBy.keys(),
@@ -7727,40 +8315,42 @@ async function restructure(pattern2, options2 = {}) {
7727
8315
  const targetPattern = pattern2 ?? "src";
7728
8316
  const files = findSourceFiles2(targetPattern);
7729
8317
  if (files.length === 0) {
7730
- console.log(chalk90.yellow("No files found matching pattern"));
8318
+ console.log(chalk93.yellow("No files found matching pattern"));
7731
8319
  return;
7732
8320
  }
7733
- const tsConfigPath = path39.resolve("tsconfig.json");
7734
- const plan2 = buildPlan(files, tsConfigPath);
8321
+ const tsConfigPath = path44.resolve("tsconfig.json");
8322
+ const plan2 = buildPlan2(files, tsConfigPath);
7735
8323
  if (plan2.moves.length === 0) {
7736
- console.log(chalk90.green("No restructuring needed"));
8324
+ console.log(chalk93.green("No restructuring needed"));
7737
8325
  return;
7738
8326
  }
7739
- displayPlan(plan2);
8327
+ displayPlan2(plan2);
7740
8328
  if (options2.apply) {
7741
- console.log(chalk90.bold("\nApplying changes..."));
8329
+ console.log(chalk93.bold("\nApplying changes..."));
7742
8330
  executePlan(plan2);
7743
- console.log(chalk90.green("\nRestructuring complete"));
8331
+ console.log(chalk93.green("\nRestructuring complete"));
7744
8332
  } else {
7745
- console.log(chalk90.dim("\nDry run. Use --apply to execute."));
8333
+ console.log(chalk93.dim("\nDry run. Use --apply to execute."));
7746
8334
  }
7747
8335
  }
7748
8336
 
7749
8337
  // src/commands/registerRefactor.ts
7750
- function registerRefactor(program2) {
7751
- const refactorCommand = program2.command("refactor").description("Run refactoring checks for code quality");
7752
- refactorCommand.command("check [pattern]").description("Check for files that exceed the maximum line count").option("--modified", "Check only staged and unstaged files").option("--staged", "Check only staged files").option("--unstaged", "Check only unstaged files").option(
8338
+ function registerCheck(parent) {
8339
+ parent.command("check [pattern]").description("Check for files that exceed the maximum line count").option("--modified", "Check only staged and unstaged files").option("--staged", "Check only staged files").option("--unstaged", "Check only unstaged files").option(
7753
8340
  "--max-lines <number>",
7754
8341
  "Maximum lines allowed per file (default: 100)",
7755
8342
  Number.parseInt
7756
8343
  ).action(check);
7757
- refactorCommand.command("ignore <file>").description("Add a file to the refactor ignore list").action(ignore);
7758
- const renameCommand = refactorCommand.command("rename").description("Rename files or symbols with automatic import updates");
8344
+ }
8345
+ function registerRename(parent) {
8346
+ const renameCommand = parent.command("rename").description("Rename files or symbols with automatic import updates");
7759
8347
  renameCommand.command("file <source> <destination>").description("Rename/move a TypeScript file and update all imports").option("--apply", "Execute the rename (default: dry-run)").action(rename);
7760
8348
  renameCommand.command("symbol <file> <oldName> <newName>").description(
7761
8349
  "Rename a variable, function, class, or type across the project"
7762
8350
  ).option("--apply", "Execute the rename (default: dry-run)").action(renameSymbol);
7763
- refactorCommand.command("restructure [pattern]").description(
8351
+ }
8352
+ function registerRestructure(parent) {
8353
+ parent.command("restructure [pattern]").description(
7764
8354
  "Analyze import graph and restructure tightly-coupled files into nested directories"
7765
8355
  ).option("--apply", "Execute the restructuring (default: dry-run)").option(
7766
8356
  "--max-depth <number>",
@@ -7768,9 +8358,19 @@ function registerRefactor(program2) {
7768
8358
  Number.parseInt
7769
8359
  ).action(restructure);
7770
8360
  }
8361
+ function registerRefactor(program2) {
8362
+ const refactorCommand = program2.command("refactor").description("Run refactoring checks for code quality");
8363
+ registerCheck(refactorCommand);
8364
+ refactorCommand.command("extract <file> <functionName> <destination>").description(
8365
+ "Extract a function and its private dependencies to a new file"
8366
+ ).option("--apply", "Execute the extraction (default: dry-run)").action(extract);
8367
+ refactorCommand.command("ignore <file>").description("Add a file to the refactor ignore list").action(ignore);
8368
+ registerRename(refactorCommand);
8369
+ registerRestructure(refactorCommand);
8370
+ }
7771
8371
 
7772
8372
  // src/commands/seq/seqAuth.ts
7773
- import chalk92 from "chalk";
8373
+ import chalk95 from "chalk";
7774
8374
 
7775
8375
  // src/commands/seq/loadConnections.ts
7776
8376
  function loadConnections2() {
@@ -7799,11 +8399,11 @@ function setDefaultConnection(name) {
7799
8399
  }
7800
8400
 
7801
8401
  // src/commands/seq/promptConnection.ts
7802
- import chalk91 from "chalk";
8402
+ import chalk94 from "chalk";
7803
8403
  async function promptConnection2(existingNames) {
7804
8404
  const name = await promptInput("name", "Connection name:", "default");
7805
8405
  if (existingNames.includes(name)) {
7806
- console.error(chalk91.red(`Connection "${name}" already exists.`));
8406
+ console.error(chalk94.red(`Connection "${name}" already exists.`));
7807
8407
  process.exit(1);
7808
8408
  }
7809
8409
  const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
@@ -7815,32 +8415,32 @@ async function promptConnection2(existingNames) {
7815
8415
  var seqAuth = createConnectionAuth({
7816
8416
  load: loadConnections2,
7817
8417
  save: saveConnections2,
7818
- format: (c) => `${chalk92.bold(c.name)} ${c.url}`,
8418
+ format: (c) => `${chalk95.bold(c.name)} ${c.url}`,
7819
8419
  promptNew: promptConnection2,
7820
8420
  onFirst: (c) => setDefaultConnection(c.name)
7821
8421
  });
7822
8422
 
7823
8423
  // src/commands/seq/seqQuery.ts
7824
- import chalk95 from "chalk";
8424
+ import chalk98 from "chalk";
7825
8425
 
7826
8426
  // src/commands/seq/formatEvent.ts
7827
- import chalk93 from "chalk";
8427
+ import chalk96 from "chalk";
7828
8428
  function levelColor(level) {
7829
8429
  switch (level) {
7830
8430
  case "Fatal":
7831
- return chalk93.bgRed.white;
8431
+ return chalk96.bgRed.white;
7832
8432
  case "Error":
7833
- return chalk93.red;
8433
+ return chalk96.red;
7834
8434
  case "Warning":
7835
- return chalk93.yellow;
8435
+ return chalk96.yellow;
7836
8436
  case "Information":
7837
- return chalk93.cyan;
8437
+ return chalk96.cyan;
7838
8438
  case "Debug":
7839
- return chalk93.gray;
8439
+ return chalk96.gray;
7840
8440
  case "Verbose":
7841
- return chalk93.dim;
8441
+ return chalk96.dim;
7842
8442
  default:
7843
- return chalk93.white;
8443
+ return chalk96.white;
7844
8444
  }
7845
8445
  }
7846
8446
  function levelAbbrev(level) {
@@ -7881,31 +8481,31 @@ function formatTimestamp(iso) {
7881
8481
  function formatEvent(event) {
7882
8482
  const color = levelColor(event.Level);
7883
8483
  const abbrev = levelAbbrev(event.Level);
7884
- const ts8 = chalk93.dim(formatTimestamp(event.Timestamp));
8484
+ const ts8 = chalk96.dim(formatTimestamp(event.Timestamp));
7885
8485
  const msg = renderMessage(event);
7886
8486
  const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
7887
8487
  if (event.Exception) {
7888
8488
  for (const line of event.Exception.split("\n")) {
7889
- lines.push(chalk93.red(` ${line}`));
8489
+ lines.push(chalk96.red(` ${line}`));
7890
8490
  }
7891
8491
  }
7892
8492
  return lines.join("\n");
7893
8493
  }
7894
8494
 
7895
8495
  // src/commands/seq/resolveConnection.ts
7896
- import chalk94 from "chalk";
8496
+ import chalk97 from "chalk";
7897
8497
  function resolveConnection2(name) {
7898
8498
  const connections = loadConnections2();
7899
8499
  if (connections.length === 0) {
7900
8500
  console.error(
7901
- chalk94.red("No Seq connections configured. Run 'assist seq auth' first.")
8501
+ chalk97.red("No Seq connections configured. Run 'assist seq auth' first.")
7902
8502
  );
7903
8503
  process.exit(1);
7904
8504
  }
7905
8505
  const target = name ?? getDefaultConnection() ?? connections[0].name;
7906
8506
  const connection = connections.find((c) => c.name === target);
7907
8507
  if (!connection) {
7908
- console.error(chalk94.red(`Seq connection "${target}" not found.`));
8508
+ console.error(chalk97.red(`Seq connection "${target}" not found.`));
7909
8509
  process.exit(1);
7910
8510
  }
7911
8511
  return connection;
@@ -7925,12 +8525,12 @@ async function seqQuery(filter, options2) {
7925
8525
  });
7926
8526
  if (!response.ok) {
7927
8527
  const body = await response.text();
7928
- console.error(chalk95.red(`Seq returned ${response.status}: ${body}`));
8528
+ console.error(chalk98.red(`Seq returned ${response.status}: ${body}`));
7929
8529
  process.exit(1);
7930
8530
  }
7931
8531
  const events = await response.json();
7932
8532
  if (events.length === 0) {
7933
- console.log(chalk95.yellow("No events found."));
8533
+ console.log(chalk98.yellow("No events found."));
7934
8534
  return;
7935
8535
  }
7936
8536
  if (options2.json) {
@@ -7941,11 +8541,11 @@ async function seqQuery(filter, options2) {
7941
8541
  for (const event of chronological) {
7942
8542
  console.log(formatEvent(event));
7943
8543
  }
7944
- console.log(chalk95.dim(`
8544
+ console.log(chalk98.dim(`
7945
8545
  ${events.length} events`));
7946
8546
  if (events.length >= count) {
7947
8547
  console.log(
7948
- chalk95.yellow(
8548
+ chalk98.yellow(
7949
8549
  `Results limited to ${count}. Use --count to retrieve more.`
7950
8550
  )
7951
8551
  );
@@ -7953,11 +8553,11 @@ ${events.length} events`));
7953
8553
  }
7954
8554
 
7955
8555
  // src/commands/seq/seqSetConnection.ts
7956
- import chalk96 from "chalk";
8556
+ import chalk99 from "chalk";
7957
8557
  function seqSetConnection(name) {
7958
8558
  const connections = loadConnections2();
7959
8559
  if (!connections.find((c) => c.name === name)) {
7960
- console.error(chalk96.red(`Connection "${name}" not found.`));
8560
+ console.error(chalk99.red(`Connection "${name}" not found.`));
7961
8561
  process.exit(1);
7962
8562
  }
7963
8563
  setDefaultConnection(name);
@@ -8496,14 +9096,14 @@ import {
8496
9096
  import { dirname as dirname20, join as join29 } from "path";
8497
9097
 
8498
9098
  // src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
8499
- import chalk97 from "chalk";
9099
+ import chalk100 from "chalk";
8500
9100
  var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
8501
9101
  function validateStagedContent(filename, content) {
8502
9102
  const firstLine = content.split("\n")[0];
8503
9103
  const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
8504
9104
  if (!match) {
8505
9105
  console.error(
8506
- chalk97.red(
9106
+ chalk100.red(
8507
9107
  `Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
8508
9108
  )
8509
9109
  );
@@ -8512,7 +9112,7 @@ function validateStagedContent(filename, content) {
8512
9112
  const contentAfterLink = content.slice(firstLine.length).trim();
8513
9113
  if (!contentAfterLink) {
8514
9114
  console.error(
8515
- chalk97.red(
9115
+ chalk100.red(
8516
9116
  `Staged file ${filename} has no summary content after the transcript link.`
8517
9117
  )
8518
9118
  );
@@ -8905,7 +9505,7 @@ function registerVoice(program2) {
8905
9505
 
8906
9506
  // src/commands/roam/auth.ts
8907
9507
  import { randomBytes } from "crypto";
8908
- import chalk98 from "chalk";
9508
+ import chalk101 from "chalk";
8909
9509
 
8910
9510
  // src/lib/openBrowser.ts
8911
9511
  import { execSync as execSync36 } from "child_process";
@@ -9080,13 +9680,13 @@ async function auth() {
9080
9680
  saveGlobalConfig(config);
9081
9681
  const state = randomBytes(16).toString("hex");
9082
9682
  console.log(
9083
- chalk98.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
9683
+ chalk101.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
9084
9684
  );
9085
- console.log(chalk98.white("http://localhost:14523/callback\n"));
9086
- console.log(chalk98.blue("Opening browser for authorization..."));
9087
- console.log(chalk98.dim("Waiting for authorization callback..."));
9685
+ console.log(chalk101.white("http://localhost:14523/callback\n"));
9686
+ console.log(chalk101.blue("Opening browser for authorization..."));
9687
+ console.log(chalk101.dim("Waiting for authorization callback..."));
9088
9688
  const { code, redirectUri } = await authorizeInBrowser(clientId, state);
9089
- console.log(chalk98.dim("Exchanging code for tokens..."));
9689
+ console.log(chalk101.dim("Exchanging code for tokens..."));
9090
9690
  const tokens = await exchangeToken({
9091
9691
  code,
9092
9692
  clientId,
@@ -9102,7 +9702,7 @@ async function auth() {
9102
9702
  };
9103
9703
  saveGlobalConfig(config);
9104
9704
  console.log(
9105
- chalk98.green("Roam credentials and tokens saved to ~/.assist.yml")
9705
+ chalk101.green("Roam credentials and tokens saved to ~/.assist.yml")
9106
9706
  );
9107
9707
  }
9108
9708
 
@@ -9323,7 +9923,7 @@ import { execSync as execSync38 } from "child_process";
9323
9923
  import { existsSync as existsSync38, mkdirSync as mkdirSync13, unlinkSync as unlinkSync10, writeFileSync as writeFileSync27 } from "fs";
9324
9924
  import { tmpdir as tmpdir6 } from "os";
9325
9925
  import { join as join38, resolve as resolve5 } from "path";
9326
- import chalk99 from "chalk";
9926
+ import chalk102 from "chalk";
9327
9927
 
9328
9928
  // src/commands/screenshot/captureWindowPs1.ts
9329
9929
  var captureWindowPs1 = `
@@ -9474,22 +10074,22 @@ function screenshot(processName) {
9474
10074
  const config = loadConfig();
9475
10075
  const outputDir = resolve5(config.screenshot.outputDir);
9476
10076
  const outputPath = buildOutputPath(outputDir, processName);
9477
- console.log(chalk99.gray(`Capturing window for process "${processName}" ...`));
10077
+ console.log(chalk102.gray(`Capturing window for process "${processName}" ...`));
9478
10078
  try {
9479
10079
  runPowerShellScript(processName, outputPath);
9480
- console.log(chalk99.green(`Screenshot saved: ${outputPath}`));
10080
+ console.log(chalk102.green(`Screenshot saved: ${outputPath}`));
9481
10081
  } catch (error) {
9482
10082
  const msg = error instanceof Error ? error.message : String(error);
9483
- console.error(chalk99.red(`Failed to capture screenshot: ${msg}`));
10083
+ console.error(chalk102.red(`Failed to capture screenshot: ${msg}`));
9484
10084
  process.exit(1);
9485
10085
  }
9486
10086
  }
9487
10087
 
9488
10088
  // src/commands/statusLine.ts
9489
- import chalk101 from "chalk";
10089
+ import chalk104 from "chalk";
9490
10090
 
9491
10091
  // src/commands/buildLimitsSegment.ts
9492
- import chalk100 from "chalk";
10092
+ import chalk103 from "chalk";
9493
10093
  var FIVE_HOUR_SECONDS = 5 * 3600;
9494
10094
  var SEVEN_DAY_SECONDS = 7 * 86400;
9495
10095
  function formatTimeLeft(resetsAt) {
@@ -9512,10 +10112,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
9512
10112
  function colorizeRateLimit(pct, resetsAt, windowSeconds) {
9513
10113
  const label2 = `${Math.round(pct)}%`;
9514
10114
  const projected = projectUsage(pct, resetsAt, windowSeconds);
9515
- if (projected == null) return chalk100.green(label2);
9516
- if (projected > 100) return chalk100.red(label2);
9517
- if (projected > 75) return chalk100.yellow(label2);
9518
- return chalk100.green(label2);
10115
+ if (projected == null) return chalk103.green(label2);
10116
+ if (projected > 100) return chalk103.red(label2);
10117
+ if (projected > 75) return chalk103.yellow(label2);
10118
+ return chalk103.green(label2);
9519
10119
  }
9520
10120
  function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
9521
10121
  const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
@@ -9541,14 +10141,14 @@ function buildLimitsSegment(rateLimits) {
9541
10141
  }
9542
10142
 
9543
10143
  // src/commands/statusLine.ts
9544
- chalk101.level = 3;
10144
+ chalk104.level = 3;
9545
10145
  function formatNumber(num) {
9546
10146
  return num.toLocaleString("en-US");
9547
10147
  }
9548
10148
  function colorizePercent(pct) {
9549
10149
  const label2 = `${Math.round(pct)}%`;
9550
- if (pct > 80) return chalk101.red(label2);
9551
- if (pct > 40) return chalk101.yellow(label2);
10150
+ if (pct > 80) return chalk104.red(label2);
10151
+ if (pct > 40) return chalk104.yellow(label2);
9552
10152
  return label2;
9553
10153
  }
9554
10154
  async function statusLine() {
@@ -9563,29 +10163,29 @@ async function statusLine() {
9563
10163
  }
9564
10164
 
9565
10165
  // src/commands/sync.ts
9566
- import * as fs24 from "fs";
10166
+ import * as fs25 from "fs";
9567
10167
  import * as os from "os";
9568
- import * as path42 from "path";
10168
+ import * as path47 from "path";
9569
10169
  import { fileURLToPath as fileURLToPath7 } from "url";
9570
10170
 
9571
10171
  // src/commands/sync/syncClaudeMd.ts
9572
- import * as fs22 from "fs";
9573
- import * as path40 from "path";
9574
- import chalk102 from "chalk";
10172
+ import * as fs23 from "fs";
10173
+ import * as path45 from "path";
10174
+ import chalk105 from "chalk";
9575
10175
  async function syncClaudeMd(claudeDir, targetBase) {
9576
- const source = path40.join(claudeDir, "CLAUDE.md");
9577
- const target = path40.join(targetBase, "CLAUDE.md");
9578
- const sourceContent = fs22.readFileSync(source, "utf-8");
9579
- if (fs22.existsSync(target)) {
9580
- const targetContent = fs22.readFileSync(target, "utf-8");
10176
+ const source = path45.join(claudeDir, "CLAUDE.md");
10177
+ const target = path45.join(targetBase, "CLAUDE.md");
10178
+ const sourceContent = fs23.readFileSync(source, "utf-8");
10179
+ if (fs23.existsSync(target)) {
10180
+ const targetContent = fs23.readFileSync(target, "utf-8");
9581
10181
  if (sourceContent !== targetContent) {
9582
10182
  console.log(
9583
- chalk102.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
10183
+ chalk105.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
9584
10184
  );
9585
10185
  console.log();
9586
10186
  printDiff(targetContent, sourceContent);
9587
10187
  const confirm = await promptConfirm(
9588
- chalk102.red("Overwrite existing CLAUDE.md?"),
10188
+ chalk105.red("Overwrite existing CLAUDE.md?"),
9589
10189
  false
9590
10190
  );
9591
10191
  if (!confirm) {
@@ -9594,21 +10194,21 @@ async function syncClaudeMd(claudeDir, targetBase) {
9594
10194
  }
9595
10195
  }
9596
10196
  }
9597
- fs22.copyFileSync(source, target);
10197
+ fs23.copyFileSync(source, target);
9598
10198
  console.log("Copied CLAUDE.md to ~/.claude/CLAUDE.md");
9599
10199
  }
9600
10200
 
9601
10201
  // src/commands/sync/syncSettings.ts
9602
- import * as fs23 from "fs";
9603
- import * as path41 from "path";
9604
- import chalk103 from "chalk";
10202
+ import * as fs24 from "fs";
10203
+ import * as path46 from "path";
10204
+ import chalk106 from "chalk";
9605
10205
  async function syncSettings(claudeDir, targetBase, options2) {
9606
- const source = path41.join(claudeDir, "settings.json");
9607
- const target = path41.join(targetBase, "settings.json");
9608
- const sourceContent = fs23.readFileSync(source, "utf-8");
10206
+ const source = path46.join(claudeDir, "settings.json");
10207
+ const target = path46.join(targetBase, "settings.json");
10208
+ const sourceContent = fs24.readFileSync(source, "utf-8");
9609
10209
  const mergedContent = JSON.stringify(JSON.parse(sourceContent), null, " ");
9610
- if (fs23.existsSync(target)) {
9611
- const targetContent = fs23.readFileSync(target, "utf-8");
10210
+ if (fs24.existsSync(target)) {
10211
+ const targetContent = fs24.readFileSync(target, "utf-8");
9612
10212
  const normalizedTarget = JSON.stringify(
9613
10213
  JSON.parse(targetContent),
9614
10214
  null,
@@ -9617,14 +10217,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
9617
10217
  if (mergedContent !== normalizedTarget) {
9618
10218
  if (!options2?.yes) {
9619
10219
  console.log(
9620
- chalk103.yellow(
10220
+ chalk106.yellow(
9621
10221
  "\n\u26A0\uFE0F Warning: settings.json differs from existing file"
9622
10222
  )
9623
10223
  );
9624
10224
  console.log();
9625
10225
  printDiff(targetContent, mergedContent);
9626
10226
  const confirm = await promptConfirm(
9627
- chalk103.red("Overwrite existing settings.json?"),
10227
+ chalk106.red("Overwrite existing settings.json?"),
9628
10228
  false
9629
10229
  );
9630
10230
  if (!confirm) {
@@ -9634,27 +10234,27 @@ async function syncSettings(claudeDir, targetBase, options2) {
9634
10234
  }
9635
10235
  }
9636
10236
  }
9637
- fs23.writeFileSync(target, mergedContent);
10237
+ fs24.writeFileSync(target, mergedContent);
9638
10238
  console.log("Copied settings.json to ~/.claude/settings.json");
9639
10239
  }
9640
10240
 
9641
10241
  // src/commands/sync.ts
9642
10242
  var __filename4 = fileURLToPath7(import.meta.url);
9643
- var __dirname7 = path42.dirname(__filename4);
10243
+ var __dirname7 = path47.dirname(__filename4);
9644
10244
  async function sync(options2) {
9645
- const claudeDir = path42.join(__dirname7, "..", "claude");
9646
- const targetBase = path42.join(os.homedir(), ".claude");
10245
+ const claudeDir = path47.join(__dirname7, "..", "claude");
10246
+ const targetBase = path47.join(os.homedir(), ".claude");
9647
10247
  syncCommands(claudeDir, targetBase);
9648
10248
  await syncSettings(claudeDir, targetBase, { yes: options2?.yes });
9649
10249
  await syncClaudeMd(claudeDir, targetBase);
9650
10250
  }
9651
10251
  function syncCommands(claudeDir, targetBase) {
9652
- const sourceDir = path42.join(claudeDir, "commands");
9653
- const targetDir = path42.join(targetBase, "commands");
9654
- fs24.mkdirSync(targetDir, { recursive: true });
9655
- const files = fs24.readdirSync(sourceDir);
10252
+ const sourceDir = path47.join(claudeDir, "commands");
10253
+ const targetDir = path47.join(targetBase, "commands");
10254
+ fs25.mkdirSync(targetDir, { recursive: true });
10255
+ const files = fs25.readdirSync(sourceDir);
9656
10256
  for (const file of files) {
9657
- fs24.copyFileSync(path42.join(sourceDir, file), path42.join(targetDir, file));
10257
+ fs25.copyFileSync(path47.join(sourceDir, file), path47.join(targetDir, file));
9658
10258
  console.log(`Copied ${file} to ${targetDir}`);
9659
10259
  }
9660
10260
  console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
@@ -9662,15 +10262,15 @@ function syncCommands(claudeDir, targetBase) {
9662
10262
 
9663
10263
  // src/commands/update.ts
9664
10264
  import { execSync as execSync39 } from "child_process";
9665
- import * as path43 from "path";
10265
+ import * as path48 from "path";
9666
10266
  function isGlobalNpmInstall(dir) {
9667
10267
  try {
9668
- const resolved = path43.resolve(dir);
9669
- if (resolved.split(path43.sep).includes("node_modules")) {
10268
+ const resolved = path48.resolve(dir);
10269
+ if (resolved.split(path48.sep).includes("node_modules")) {
9670
10270
  return true;
9671
10271
  }
9672
10272
  const globalPrefix = execSync39("npm prefix -g", { stdio: "pipe" }).toString().trim();
9673
- return resolved.toLowerCase().startsWith(path43.resolve(globalPrefix).toLowerCase());
10273
+ return resolved.toLowerCase().startsWith(path48.resolve(globalPrefix).toLowerCase());
9674
10274
  } catch {
9675
10275
  return false;
9676
10276
  }