@staff0rd/assist 0.288.1 → 0.288.2
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 +526 -458
- package/package.json +1 -1
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.288.
|
|
9
|
+
version: "0.288.2",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -124,10 +124,10 @@ import { stringify as stringifyYaml } from "yaml";
|
|
|
124
124
|
// src/shared/loadRawYaml.ts
|
|
125
125
|
import { existsSync, readFileSync } from "fs";
|
|
126
126
|
import { parse as parseYaml } from "yaml";
|
|
127
|
-
function loadRawYaml(
|
|
128
|
-
if (!existsSync(
|
|
127
|
+
function loadRawYaml(path56) {
|
|
128
|
+
if (!existsSync(path56)) return {};
|
|
129
129
|
try {
|
|
130
|
-
const content = readFileSync(
|
|
130
|
+
const content = readFileSync(path56, "utf-8");
|
|
131
131
|
return parseYaml(content) || {};
|
|
132
132
|
} catch {
|
|
133
133
|
return {};
|
|
@@ -3110,9 +3110,9 @@ var LOCAL_FILES = ["backlog.jsonl", "backlog.db"];
|
|
|
3110
3110
|
function backupLocalBacklogFiles(dir) {
|
|
3111
3111
|
const moved = [];
|
|
3112
3112
|
for (const name of LOCAL_FILES) {
|
|
3113
|
-
const
|
|
3114
|
-
if (existsSync15(
|
|
3115
|
-
renameSync(
|
|
3113
|
+
const path56 = join11(dir, ".assist", name);
|
|
3114
|
+
if (existsSync15(path56)) {
|
|
3115
|
+
renameSync(path56, `${path56}.bak`);
|
|
3116
3116
|
moved.push(`${name} \u2192 ${name}.bak`);
|
|
3117
3117
|
}
|
|
3118
3118
|
}
|
|
@@ -3402,8 +3402,8 @@ var backlogItemSchema = z3.strictObject({
|
|
|
3402
3402
|
var backlogFileSchema = z3.array(backlogItemSchema);
|
|
3403
3403
|
|
|
3404
3404
|
// src/commands/backlog/parseBacklogJsonl.ts
|
|
3405
|
-
function parseBacklogJsonl(
|
|
3406
|
-
const content = readFileSync10(
|
|
3405
|
+
function parseBacklogJsonl(path56) {
|
|
3406
|
+
const content = readFileSync10(path56, "utf-8").trim();
|
|
3407
3407
|
if (content.length === 0) return [];
|
|
3408
3408
|
return content.split("\n").map((line) => line.trim()).filter(Boolean).map((line) => backlogItemSchema.parse(JSON.parse(line)));
|
|
3409
3409
|
}
|
|
@@ -3478,8 +3478,8 @@ function findBacklogUp(startDir) {
|
|
|
3478
3478
|
|
|
3479
3479
|
// src/commands/backlog/getCurrentOrigin.ts
|
|
3480
3480
|
import { execFileSync } from "child_process";
|
|
3481
|
-
function stripLeadingSlashes(
|
|
3482
|
-
return
|
|
3481
|
+
function stripLeadingSlashes(path56) {
|
|
3482
|
+
return path56.replace(/^\/+/, "");
|
|
3483
3483
|
}
|
|
3484
3484
|
function normalizeOrigin(raw) {
|
|
3485
3485
|
const trimmed = raw.trim().replace(/\.git$/i, "").replace(/\/+$/, "");
|
|
@@ -3746,13 +3746,13 @@ function activityPath(sessionId) {
|
|
|
3746
3746
|
function emitActivity(activity2) {
|
|
3747
3747
|
const sessionId = process.env.ASSIST_ACTIVITY_ID;
|
|
3748
3748
|
if (!sessionId) return;
|
|
3749
|
-
const
|
|
3750
|
-
mkdirSync6(dirname14(
|
|
3751
|
-
writeFileSync13(
|
|
3749
|
+
const path56 = activityPath(sessionId);
|
|
3750
|
+
mkdirSync6(dirname14(path56), { recursive: true });
|
|
3751
|
+
writeFileSync13(path56, JSON.stringify({ ...activity2, startedAt: Date.now() }));
|
|
3752
3752
|
}
|
|
3753
|
-
function readActivity(
|
|
3753
|
+
function readActivity(path56) {
|
|
3754
3754
|
try {
|
|
3755
|
-
return JSON.parse(readFileSync11(
|
|
3755
|
+
return JSON.parse(readFileSync11(path56, "utf-8"));
|
|
3756
3756
|
} catch {
|
|
3757
3757
|
return void 0;
|
|
3758
3758
|
}
|
|
@@ -3912,10 +3912,10 @@ function writeSignal(event, data) {
|
|
|
3912
3912
|
|
|
3913
3913
|
// src/commands/backlog/readSignal.ts
|
|
3914
3914
|
function readSignal() {
|
|
3915
|
-
const
|
|
3916
|
-
if (!existsSync19(
|
|
3915
|
+
const path56 = getSignalPath();
|
|
3916
|
+
if (!existsSync19(path56)) return void 0;
|
|
3917
3917
|
try {
|
|
3918
|
-
return JSON.parse(readFileSync12(
|
|
3918
|
+
return JSON.parse(readFileSync12(path56, "utf-8"));
|
|
3919
3919
|
} catch {
|
|
3920
3920
|
return void 0;
|
|
3921
3921
|
}
|
|
@@ -6254,8 +6254,8 @@ import chalk57 from "chalk";
|
|
|
6254
6254
|
// src/commands/backlog/originDisplayName.ts
|
|
6255
6255
|
function originDisplayName(origin) {
|
|
6256
6256
|
if (origin.startsWith("local:")) {
|
|
6257
|
-
const
|
|
6258
|
-
const segments =
|
|
6257
|
+
const path56 = origin.slice("local:".length).replace(/\/+$/, "");
|
|
6258
|
+
const segments = path56.split("/").filter(Boolean);
|
|
6259
6259
|
return segments[segments.length - 1] ?? origin;
|
|
6260
6260
|
}
|
|
6261
6261
|
const firstSlash = origin.indexOf("/");
|
|
@@ -7558,9 +7558,9 @@ var __dirname5 = dirname17(__filename3);
|
|
|
7558
7558
|
function packageRoot() {
|
|
7559
7559
|
return __dirname5;
|
|
7560
7560
|
}
|
|
7561
|
-
function readLines(
|
|
7562
|
-
if (!existsSync22(
|
|
7563
|
-
return readFileSync16(
|
|
7561
|
+
function readLines(path56) {
|
|
7562
|
+
if (!existsSync22(path56)) return [];
|
|
7563
|
+
return readFileSync16(path56, "utf-8").split("\n").filter((line) => line.trim() !== "");
|
|
7564
7564
|
}
|
|
7565
7565
|
var cachedReads;
|
|
7566
7566
|
var cachedWrites;
|
|
@@ -8025,14 +8025,14 @@ function showProgress(p, label2) {
|
|
|
8025
8025
|
const pct = Math.round(p.done / p.total * 100);
|
|
8026
8026
|
process.stderr.write(`\r\x1B[K[${pct}%] Scanning ${label2}...`);
|
|
8027
8027
|
}
|
|
8028
|
-
async function resolveCommand(cli,
|
|
8029
|
-
showProgress(p,
|
|
8030
|
-
const subHelp = await runHelp([cli, ...
|
|
8028
|
+
async function resolveCommand(cli, path56, description, depth, p) {
|
|
8029
|
+
showProgress(p, path56.join(" "));
|
|
8030
|
+
const subHelp = await runHelp([cli, ...path56]);
|
|
8031
8031
|
if (!subHelp || !hasSubcommands(subHelp)) {
|
|
8032
|
-
return [{ path:
|
|
8032
|
+
return [{ path: path56, description }];
|
|
8033
8033
|
}
|
|
8034
|
-
const children = await discoverAt(cli,
|
|
8035
|
-
return children.length > 0 ? children : [{ path:
|
|
8034
|
+
const children = await discoverAt(cli, path56, depth + 1, p);
|
|
8035
|
+
return children.length > 0 ? children : [{ path: path56, description }];
|
|
8036
8036
|
}
|
|
8037
8037
|
async function discoverAt(cli, parentPath, depth, p) {
|
|
8038
8038
|
if (depth > SAFETY_DEPTH) return [];
|
|
@@ -8180,9 +8180,9 @@ function logPath(cli) {
|
|
|
8180
8180
|
return join22(homedir9(), ".assist", `cli-discover-${safeName}.log`);
|
|
8181
8181
|
}
|
|
8182
8182
|
function readCache(cli) {
|
|
8183
|
-
const
|
|
8184
|
-
if (!existsSync24(
|
|
8185
|
-
return readFileSync18(
|
|
8183
|
+
const path56 = logPath(cli);
|
|
8184
|
+
if (!existsSync24(path56)) return void 0;
|
|
8185
|
+
return readFileSync18(path56, "utf-8");
|
|
8186
8186
|
}
|
|
8187
8187
|
function writeCache(cli, output) {
|
|
8188
8188
|
const dir = join22(homedir9(), ".assist");
|
|
@@ -8871,8 +8871,8 @@ function stepIntoNested(container, key, nextKey) {
|
|
|
8871
8871
|
}
|
|
8872
8872
|
return ensureObject(container, resolved);
|
|
8873
8873
|
}
|
|
8874
|
-
function setNestedValue(obj,
|
|
8875
|
-
const keys =
|
|
8874
|
+
function setNestedValue(obj, path56, value) {
|
|
8875
|
+
const keys = path56.split(".");
|
|
8876
8876
|
const result = { ...obj };
|
|
8877
8877
|
let current = result;
|
|
8878
8878
|
for (let i = 0; i < keys.length - 1; i++) {
|
|
@@ -8952,9 +8952,9 @@ function isTraversable(value) {
|
|
|
8952
8952
|
function stepInto(current, key) {
|
|
8953
8953
|
return isTraversable(current) ? current[key] : void 0;
|
|
8954
8954
|
}
|
|
8955
|
-
function getNestedValue(obj,
|
|
8955
|
+
function getNestedValue(obj, path56) {
|
|
8956
8956
|
let current = obj;
|
|
8957
|
-
for (const key of
|
|
8957
|
+
for (const key of path56.split(".")) current = stepInto(current, key);
|
|
8958
8958
|
return current;
|
|
8959
8959
|
}
|
|
8960
8960
|
|
|
@@ -10742,10 +10742,10 @@ function getStorePath(filename) {
|
|
|
10742
10742
|
return join32(getStoreDir(), filename);
|
|
10743
10743
|
}
|
|
10744
10744
|
function loadJson(filename) {
|
|
10745
|
-
const
|
|
10746
|
-
if (existsSync33(
|
|
10745
|
+
const path56 = getStorePath(filename);
|
|
10746
|
+
if (existsSync33(path56)) {
|
|
10747
10747
|
try {
|
|
10748
|
-
return JSON.parse(readFileSync27(
|
|
10748
|
+
return JSON.parse(readFileSync27(path56, "utf-8"));
|
|
10749
10749
|
} catch {
|
|
10750
10750
|
return {};
|
|
10751
10751
|
}
|
|
@@ -11203,15 +11203,15 @@ function postComment(vars) {
|
|
|
11203
11203
|
const stdout = startLine === void 0 ? runGhGraphql(MUTATION_SINGLE, base) : runGhGraphql(MUTATION_MULTI, { ...base, startLine });
|
|
11204
11204
|
assertThreadCreated(stdout);
|
|
11205
11205
|
}
|
|
11206
|
-
function comment2(
|
|
11206
|
+
function comment2(path56, line, body, startLine) {
|
|
11207
11207
|
validateBody(body);
|
|
11208
11208
|
validateLine(line);
|
|
11209
11209
|
if (startLine !== void 0) validateLine(startLine);
|
|
11210
11210
|
try {
|
|
11211
11211
|
const prId = getCurrentPrNodeId();
|
|
11212
|
-
postComment({ prId, body, path:
|
|
11212
|
+
postComment({ prId, body, path: path56, line, startLine });
|
|
11213
11213
|
const range = startLine !== void 0 ? `${startLine}-${line}` : `${line}`;
|
|
11214
|
-
console.log(`Added review comment on ${
|
|
11214
|
+
console.log(`Added review comment on ${path56}:${range}`);
|
|
11215
11215
|
} catch (error) {
|
|
11216
11216
|
if (isGhNotInstalled(error)) {
|
|
11217
11217
|
console.error("Error: GitHub CLI (gh) is not installed.");
|
|
@@ -11953,8 +11953,8 @@ function registerPrs(program2) {
|
|
|
11953
11953
|
prsCommand.command("wontfix <comment-id> <reason>").description("Reply with reason and resolve thread").action((commentId, reason) => {
|
|
11954
11954
|
wontfix(Number.parseInt(commentId, 10), reason);
|
|
11955
11955
|
});
|
|
11956
|
-
prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((
|
|
11957
|
-
comment2(
|
|
11956
|
+
prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((path56, line, body) => {
|
|
11957
|
+
comment2(path56, Number.parseInt(line, 10), body);
|
|
11958
11958
|
});
|
|
11959
11959
|
}
|
|
11960
11960
|
|
|
@@ -12206,10 +12206,10 @@ function resolveOpSecret(reference) {
|
|
|
12206
12206
|
}
|
|
12207
12207
|
|
|
12208
12208
|
// src/commands/ravendb/ravenFetch.ts
|
|
12209
|
-
async function ravenFetch(connection,
|
|
12209
|
+
async function ravenFetch(connection, path56) {
|
|
12210
12210
|
const apiKey = resolveOpSecret(connection.apiKeyRef);
|
|
12211
12211
|
let accessToken = await getAccessToken(apiKey);
|
|
12212
|
-
const url = `${connection.url}${
|
|
12212
|
+
const url = `${connection.url}${path56}`;
|
|
12213
12213
|
const headers = {
|
|
12214
12214
|
Authorization: `Bearer ${accessToken}`,
|
|
12215
12215
|
"Content-Type": "application/json"
|
|
@@ -12299,16 +12299,16 @@ import chalk132 from "chalk";
|
|
|
12299
12299
|
// src/commands/ravendb/buildQueryPath.ts
|
|
12300
12300
|
function buildQueryPath(opts) {
|
|
12301
12301
|
const db = encodeURIComponent(opts.db);
|
|
12302
|
-
let
|
|
12302
|
+
let path56;
|
|
12303
12303
|
if (opts.collection) {
|
|
12304
|
-
|
|
12304
|
+
path56 = `/databases/${db}/indexes/dynamic/${encodeURIComponent(opts.collection)}?start=${opts.start}&pageSize=${opts.pageSize}&sort=${encodeURIComponent(opts.sort)}`;
|
|
12305
12305
|
} else {
|
|
12306
|
-
|
|
12306
|
+
path56 = `/databases/${db}/queries?start=${opts.start}&pageSize=${opts.pageSize}`;
|
|
12307
12307
|
}
|
|
12308
12308
|
if (opts.query) {
|
|
12309
|
-
|
|
12309
|
+
path56 += `&query=${encodeURIComponent(opts.query)}`;
|
|
12310
12310
|
}
|
|
12311
|
-
return
|
|
12311
|
+
return path56;
|
|
12312
12312
|
}
|
|
12313
12313
|
|
|
12314
12314
|
// src/commands/ravendb/fetchAllPages.ts
|
|
@@ -12317,7 +12317,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
12317
12317
|
let start3 = 0;
|
|
12318
12318
|
while (true) {
|
|
12319
12319
|
const effectivePageSize = opts.limit !== void 0 ? Math.min(opts.pageSize, opts.limit - allResults.length) : opts.pageSize;
|
|
12320
|
-
const
|
|
12320
|
+
const path56 = buildQueryPath({
|
|
12321
12321
|
db: connection.database,
|
|
12322
12322
|
collection: opts.collection,
|
|
12323
12323
|
start: start3,
|
|
@@ -12325,7 +12325,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
12325
12325
|
sort: opts.sort,
|
|
12326
12326
|
query: opts.query
|
|
12327
12327
|
});
|
|
12328
|
-
const data = await ravenFetch(connection,
|
|
12328
|
+
const data = await ravenFetch(connection, path56);
|
|
12329
12329
|
const results = data.Results ?? [];
|
|
12330
12330
|
const totalResults = data.TotalResults ?? 0;
|
|
12331
12331
|
if (results.length === 0) break;
|
|
@@ -13329,99 +13329,130 @@ function ignore(file) {
|
|
|
13329
13329
|
}
|
|
13330
13330
|
|
|
13331
13331
|
// src/commands/refactor/rename/index.ts
|
|
13332
|
-
import
|
|
13332
|
+
import fs23 from "fs";
|
|
13333
|
+
import path38 from "path";
|
|
13334
|
+
import chalk141 from "chalk";
|
|
13335
|
+
|
|
13336
|
+
// src/commands/refactor/rename/applyRename.ts
|
|
13337
|
+
import fs22 from "fs";
|
|
13338
|
+
import path35 from "path";
|
|
13333
13339
|
import chalk139 from "chalk";
|
|
13334
|
-
async function rename(source, destination, options2 = {}) {
|
|
13335
|
-
const destPath = path34.resolve(destination);
|
|
13336
|
-
const cwd = process.cwd();
|
|
13337
|
-
const relSource = path34.relative(cwd, path34.resolve(source));
|
|
13338
|
-
const relDest = path34.relative(cwd, destPath);
|
|
13339
|
-
const { project, sourceFile } = loadProjectFile(source);
|
|
13340
|
-
console.log(chalk139.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
13341
|
-
if (options2.apply) {
|
|
13342
|
-
sourceFile.move(destPath);
|
|
13343
|
-
await project.save();
|
|
13344
|
-
console.log(chalk139.green("Done"));
|
|
13345
|
-
} else {
|
|
13346
|
-
console.log(chalk139.dim("Dry run. Use --apply to execute."));
|
|
13347
|
-
}
|
|
13348
|
-
}
|
|
13349
13340
|
|
|
13350
|
-
// src/commands/refactor/
|
|
13351
|
-
import
|
|
13341
|
+
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
13342
|
+
import path34 from "path";
|
|
13352
13343
|
|
|
13353
|
-
// src/commands/refactor/
|
|
13354
|
-
import
|
|
13355
|
-
|
|
13356
|
-
|
|
13357
|
-
|
|
13358
|
-
|
|
13359
|
-
SyntaxKind14.InterfaceDeclaration,
|
|
13360
|
-
SyntaxKind14.TypeAliasDeclaration,
|
|
13361
|
-
SyntaxKind14.EnumDeclaration,
|
|
13362
|
-
SyntaxKind14.PropertyDeclaration,
|
|
13363
|
-
SyntaxKind14.MethodDeclaration,
|
|
13364
|
-
SyntaxKind14.Parameter
|
|
13365
|
-
];
|
|
13366
|
-
function isDeclaration(identifier) {
|
|
13367
|
-
const parent = identifier.getParent();
|
|
13368
|
-
return parent !== void 0 && declarationKinds.includes(parent.getKind());
|
|
13344
|
+
// src/commands/refactor/restructure/computeRewrites/applyRewrites.ts
|
|
13345
|
+
import fs21 from "fs";
|
|
13346
|
+
function getOrCreateList(map, key) {
|
|
13347
|
+
const list4 = map.get(key) ?? [];
|
|
13348
|
+
if (!map.has(key)) map.set(key, list4);
|
|
13349
|
+
return list4;
|
|
13369
13350
|
}
|
|
13370
|
-
function
|
|
13371
|
-
|
|
13372
|
-
|
|
13351
|
+
function groupByFile2(rewrites) {
|
|
13352
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
13353
|
+
for (const rewrite of rewrites) {
|
|
13354
|
+
getOrCreateList(grouped, rewrite.file).push(rewrite);
|
|
13373
13355
|
}
|
|
13374
|
-
return
|
|
13356
|
+
return grouped;
|
|
13357
|
+
}
|
|
13358
|
+
function rewriteSpecifier(content, oldSpecifier, newSpecifier) {
|
|
13359
|
+
const escaped = oldSpecifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
13360
|
+
const pattern2 = new RegExp(`(from\\s+["'])${escaped}(["'])`, "g");
|
|
13361
|
+
return content.replace(pattern2, `$1${newSpecifier}$2`);
|
|
13362
|
+
}
|
|
13363
|
+
function applyFileRewrites(file, fileRewrites) {
|
|
13364
|
+
let content = fs21.readFileSync(file, "utf-8");
|
|
13365
|
+
for (const { oldSpecifier, newSpecifier } of fileRewrites) {
|
|
13366
|
+
content = rewriteSpecifier(content, oldSpecifier, newSpecifier);
|
|
13367
|
+
}
|
|
13368
|
+
return content;
|
|
13369
|
+
}
|
|
13370
|
+
function applyRewrites(rewrites) {
|
|
13371
|
+
const updatedContents = /* @__PURE__ */ new Map();
|
|
13372
|
+
for (const [file, fileRewrites] of groupByFile2(rewrites)) {
|
|
13373
|
+
updatedContents.set(file, applyFileRewrites(file, fileRewrites));
|
|
13374
|
+
}
|
|
13375
|
+
return updatedContents;
|
|
13375
13376
|
}
|
|
13376
13377
|
|
|
13377
|
-
// src/commands/refactor/
|
|
13378
|
-
|
|
13379
|
-
|
|
13380
|
-
const
|
|
13381
|
-
|
|
13382
|
-
|
|
13383
|
-
|
|
13384
|
-
|
|
13385
|
-
|
|
13386
|
-
|
|
13378
|
+
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
13379
|
+
function buildMoveMap(moves) {
|
|
13380
|
+
const map = /* @__PURE__ */ new Map();
|
|
13381
|
+
for (const move of moves) map.set(move.from, move.to);
|
|
13382
|
+
return map;
|
|
13383
|
+
}
|
|
13384
|
+
function stripTrailingIndex(specifier) {
|
|
13385
|
+
return specifier.endsWith("/index") ? specifier.slice(0, -"/index".length) : specifier;
|
|
13386
|
+
}
|
|
13387
|
+
function ensureRelative(specifier) {
|
|
13388
|
+
return specifier.startsWith(".") ? specifier : `./${specifier}`;
|
|
13389
|
+
}
|
|
13390
|
+
function normalizeSpecifier(rel) {
|
|
13391
|
+
return ensureRelative(
|
|
13392
|
+
stripTrailingIndex(rel.replace(/\\/g, "/").replace(/\.tsx?$/, ""))
|
|
13393
|
+
);
|
|
13394
|
+
}
|
|
13395
|
+
function computeSpecifier(fromFile, toFile) {
|
|
13396
|
+
return normalizeSpecifier(path34.relative(path34.dirname(fromFile), toFile));
|
|
13397
|
+
}
|
|
13398
|
+
function isAffected(edge, moveMap) {
|
|
13399
|
+
return moveMap.has(edge.target) || moveMap.has(edge.source);
|
|
13400
|
+
}
|
|
13401
|
+
function resolveTarget(edge, moveMap) {
|
|
13402
|
+
return moveMap.get(edge.target) ?? edge.target;
|
|
13403
|
+
}
|
|
13404
|
+
function createRewrite(edge, newSpecifier) {
|
|
13405
|
+
return { file: edge.source, oldSpecifier: edge.specifier, newSpecifier };
|
|
13406
|
+
}
|
|
13407
|
+
function rewriteIfChanged(edge, newSpecifier) {
|
|
13408
|
+
return newSpecifier === edge.specifier ? null : createRewrite(edge, newSpecifier);
|
|
13409
|
+
}
|
|
13410
|
+
function rewriteEdge(edge, newFile, moveMap) {
|
|
13411
|
+
if (!isAffected(edge, moveMap)) return null;
|
|
13412
|
+
return rewriteIfChanged(
|
|
13413
|
+
edge,
|
|
13414
|
+
computeSpecifier(newFile, resolveTarget(edge, moveMap))
|
|
13415
|
+
);
|
|
13416
|
+
}
|
|
13417
|
+
function fileEdges(edges, file) {
|
|
13418
|
+
return edges.filter((e) => e.source === file);
|
|
13419
|
+
}
|
|
13420
|
+
function collectRewrites(edges, newFile, moveMap) {
|
|
13421
|
+
const rewrites = [];
|
|
13422
|
+
for (const edge of edges) {
|
|
13423
|
+
const rewrite = rewriteEdge(edge, newFile, moveMap);
|
|
13424
|
+
if (rewrite) rewrites.push(rewrite);
|
|
13387
13425
|
}
|
|
13388
|
-
return
|
|
13426
|
+
return rewrites;
|
|
13427
|
+
}
|
|
13428
|
+
function rewriteEdgesForFile(file, edges, moveMap) {
|
|
13429
|
+
const newFile = moveMap.get(file) ?? file;
|
|
13430
|
+
return collectRewrites(fileEdges(edges, file), newFile, moveMap);
|
|
13431
|
+
}
|
|
13432
|
+
function computeRewrites(moves, edges, allProjectFiles) {
|
|
13433
|
+
const moveMap = buildMoveMap(moves);
|
|
13434
|
+
return [...allProjectFiles].flatMap(
|
|
13435
|
+
(file) => rewriteEdgesForFile(file, edges, moveMap)
|
|
13436
|
+
);
|
|
13389
13437
|
}
|
|
13390
13438
|
|
|
13391
|
-
// src/commands/refactor/
|
|
13392
|
-
|
|
13393
|
-
const
|
|
13394
|
-
const
|
|
13395
|
-
|
|
13396
|
-
|
|
13397
|
-
console.log(chalk140.red(`Symbol "${oldName}" not found in ${file}`));
|
|
13398
|
-
process.exit(1);
|
|
13439
|
+
// src/commands/refactor/rename/applyRename.ts
|
|
13440
|
+
function applyRename(rewrites, sourcePath, destPath, cwd) {
|
|
13441
|
+
const updatedContents = applyRewrites(rewrites);
|
|
13442
|
+
for (const [file, content] of updatedContents) {
|
|
13443
|
+
fs22.writeFileSync(file, content, "utf-8");
|
|
13444
|
+
console.log(chalk139.cyan(` Updated imports in ${path35.relative(cwd, file)}`));
|
|
13399
13445
|
}
|
|
13400
|
-
const
|
|
13401
|
-
|
|
13446
|
+
const destDir = path35.dirname(destPath);
|
|
13447
|
+
if (!fs22.existsSync(destDir)) fs22.mkdirSync(destDir, { recursive: true });
|
|
13448
|
+
fs22.renameSync(sourcePath, destPath);
|
|
13402
13449
|
console.log(
|
|
13403
|
-
|
|
13404
|
-
`)
|
|
13450
|
+
chalk139.white(
|
|
13451
|
+
` Moved ${path35.relative(cwd, sourcePath)} \u2192 ${path35.relative(cwd, destPath)}`
|
|
13452
|
+
)
|
|
13405
13453
|
);
|
|
13406
|
-
for (const [refFile, lines] of grouped) {
|
|
13407
|
-
console.log(
|
|
13408
|
-
` ${chalk140.dim(refFile)}: lines ${chalk140.cyan(lines.join(", "))}`
|
|
13409
|
-
);
|
|
13410
|
-
}
|
|
13411
|
-
if (options2.apply) {
|
|
13412
|
-
symbol.rename(newName);
|
|
13413
|
-
await project.save();
|
|
13414
|
-
console.log(chalk140.green(`
|
|
13415
|
-
Renamed ${oldName} \u2192 ${newName}`));
|
|
13416
|
-
} else {
|
|
13417
|
-
console.log(chalk140.dim("\nDry run. Use --apply to execute."));
|
|
13418
|
-
}
|
|
13419
13454
|
}
|
|
13420
13455
|
|
|
13421
|
-
// src/commands/refactor/restructure/index.ts
|
|
13422
|
-
import path44 from "path";
|
|
13423
|
-
import chalk143 from "chalk";
|
|
13424
|
-
|
|
13425
13456
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
13426
13457
|
import path36 from "path";
|
|
13427
13458
|
import ts7 from "typescript";
|
|
@@ -13488,13 +13519,148 @@ function buildImportGraph(candidateFiles, tsConfigPath) {
|
|
|
13488
13519
|
return { files: candidateFiles, edges, importedBy, imports };
|
|
13489
13520
|
}
|
|
13490
13521
|
|
|
13491
|
-
// src/commands/refactor/
|
|
13522
|
+
// src/commands/refactor/rename/computeRenameRewrites.ts
|
|
13523
|
+
function computeRenameRewrites(sourcePath, destPath) {
|
|
13524
|
+
const tsConfigPath = findTsConfig(sourcePath);
|
|
13525
|
+
const graph = buildImportGraph(/* @__PURE__ */ new Set([sourcePath]), tsConfigPath);
|
|
13526
|
+
const allProjectFiles = /* @__PURE__ */ new Set([
|
|
13527
|
+
...graph.importedBy.keys(),
|
|
13528
|
+
...graph.imports.keys(),
|
|
13529
|
+
sourcePath
|
|
13530
|
+
]);
|
|
13531
|
+
const move = { from: sourcePath, to: destPath, reason: "rename" };
|
|
13532
|
+
return computeRewrites([move], graph.edges, allProjectFiles);
|
|
13533
|
+
}
|
|
13534
|
+
|
|
13535
|
+
// src/commands/refactor/rename/printRenamePreview.ts
|
|
13492
13536
|
import path37 from "path";
|
|
13537
|
+
import chalk140 from "chalk";
|
|
13538
|
+
function printRenamePreview(rewrites, cwd) {
|
|
13539
|
+
for (const rewrite of rewrites) {
|
|
13540
|
+
console.log(
|
|
13541
|
+
chalk140.dim(
|
|
13542
|
+
` ${path37.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
|
|
13543
|
+
)
|
|
13544
|
+
);
|
|
13545
|
+
}
|
|
13546
|
+
console.log(chalk140.dim("Dry run. Use --apply to execute."));
|
|
13547
|
+
}
|
|
13548
|
+
|
|
13549
|
+
// src/commands/refactor/rename/index.ts
|
|
13550
|
+
async function rename(source, destination, options2 = {}) {
|
|
13551
|
+
const sourcePath = path38.resolve(source);
|
|
13552
|
+
const destPath = path38.resolve(destination);
|
|
13553
|
+
const cwd = process.cwd();
|
|
13554
|
+
const relSource = path38.relative(cwd, sourcePath);
|
|
13555
|
+
const relDest = path38.relative(cwd, destPath);
|
|
13556
|
+
if (!fs23.existsSync(sourcePath)) {
|
|
13557
|
+
console.log(chalk141.red(`File not found: ${source}`));
|
|
13558
|
+
process.exit(1);
|
|
13559
|
+
}
|
|
13560
|
+
if (destPath !== sourcePath && fs23.existsSync(destPath)) {
|
|
13561
|
+
console.log(chalk141.red(`Destination already exists: ${destination}`));
|
|
13562
|
+
process.exit(1);
|
|
13563
|
+
}
|
|
13564
|
+
console.log(chalk141.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
13565
|
+
console.log(chalk141.dim("Loading project..."));
|
|
13566
|
+
console.log(chalk141.dim("Scanning imports across the project..."));
|
|
13567
|
+
const rewrites = computeRenameRewrites(sourcePath, destPath);
|
|
13568
|
+
const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
|
|
13569
|
+
console.log(
|
|
13570
|
+
chalk141.dim(
|
|
13571
|
+
`${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
|
|
13572
|
+
)
|
|
13573
|
+
);
|
|
13574
|
+
if (!options2.apply) {
|
|
13575
|
+
printRenamePreview(rewrites, cwd);
|
|
13576
|
+
return;
|
|
13577
|
+
}
|
|
13578
|
+
applyRename(rewrites, sourcePath, destPath, cwd);
|
|
13579
|
+
console.log(chalk141.green("Done"));
|
|
13580
|
+
}
|
|
13581
|
+
|
|
13582
|
+
// src/commands/refactor/renameSymbol/index.ts
|
|
13583
|
+
import chalk142 from "chalk";
|
|
13584
|
+
|
|
13585
|
+
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
13586
|
+
import { SyntaxKind as SyntaxKind14 } from "ts-morph";
|
|
13587
|
+
var declarationKinds = [
|
|
13588
|
+
SyntaxKind14.VariableDeclaration,
|
|
13589
|
+
SyntaxKind14.FunctionDeclaration,
|
|
13590
|
+
SyntaxKind14.ClassDeclaration,
|
|
13591
|
+
SyntaxKind14.InterfaceDeclaration,
|
|
13592
|
+
SyntaxKind14.TypeAliasDeclaration,
|
|
13593
|
+
SyntaxKind14.EnumDeclaration,
|
|
13594
|
+
SyntaxKind14.PropertyDeclaration,
|
|
13595
|
+
SyntaxKind14.MethodDeclaration,
|
|
13596
|
+
SyntaxKind14.Parameter
|
|
13597
|
+
];
|
|
13598
|
+
function isDeclaration(identifier) {
|
|
13599
|
+
const parent = identifier.getParent();
|
|
13600
|
+
return parent !== void 0 && declarationKinds.includes(parent.getKind());
|
|
13601
|
+
}
|
|
13602
|
+
function findSymbol(sourceFile, symbolName) {
|
|
13603
|
+
for (const id of sourceFile.getDescendantsOfKind(SyntaxKind14.Identifier)) {
|
|
13604
|
+
if (id.getText() === symbolName && isDeclaration(id)) return id;
|
|
13605
|
+
}
|
|
13606
|
+
return void 0;
|
|
13607
|
+
}
|
|
13608
|
+
|
|
13609
|
+
// src/commands/refactor/renameSymbol/groupReferences.ts
|
|
13610
|
+
import path39 from "path";
|
|
13611
|
+
function groupReferences(symbol, cwd) {
|
|
13612
|
+
const refs = symbol.findReferencesAsNodes();
|
|
13613
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
13614
|
+
for (const ref of refs) {
|
|
13615
|
+
const refFile = path39.relative(cwd, ref.getSourceFile().getFilePath());
|
|
13616
|
+
const lines = grouped.get(refFile) ?? [];
|
|
13617
|
+
if (!grouped.has(refFile)) grouped.set(refFile, lines);
|
|
13618
|
+
lines.push(ref.getStartLineNumber());
|
|
13619
|
+
}
|
|
13620
|
+
return grouped;
|
|
13621
|
+
}
|
|
13622
|
+
|
|
13623
|
+
// src/commands/refactor/renameSymbol/index.ts
|
|
13624
|
+
async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
13625
|
+
const cwd = process.cwd();
|
|
13626
|
+
const { project, sourceFile } = loadProjectFile(file);
|
|
13627
|
+
const symbol = findSymbol(sourceFile, oldName);
|
|
13628
|
+
if (!symbol) {
|
|
13629
|
+
console.log(chalk142.red(`Symbol "${oldName}" not found in ${file}`));
|
|
13630
|
+
process.exit(1);
|
|
13631
|
+
}
|
|
13632
|
+
const grouped = groupReferences(symbol, cwd);
|
|
13633
|
+
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
13634
|
+
console.log(
|
|
13635
|
+
chalk142.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
13636
|
+
`)
|
|
13637
|
+
);
|
|
13638
|
+
for (const [refFile, lines] of grouped) {
|
|
13639
|
+
console.log(
|
|
13640
|
+
` ${chalk142.dim(refFile)}: lines ${chalk142.cyan(lines.join(", "))}`
|
|
13641
|
+
);
|
|
13642
|
+
}
|
|
13643
|
+
if (options2.apply) {
|
|
13644
|
+
symbol.rename(newName);
|
|
13645
|
+
await project.save();
|
|
13646
|
+
console.log(chalk142.green(`
|
|
13647
|
+
Renamed ${oldName} \u2192 ${newName}`));
|
|
13648
|
+
} else {
|
|
13649
|
+
console.log(chalk142.dim("\nDry run. Use --apply to execute."));
|
|
13650
|
+
}
|
|
13651
|
+
}
|
|
13652
|
+
|
|
13653
|
+
// src/commands/refactor/restructure/index.ts
|
|
13654
|
+
import path46 from "path";
|
|
13655
|
+
import chalk145 from "chalk";
|
|
13656
|
+
|
|
13657
|
+
// src/commands/refactor/restructure/clusterDirectories.ts
|
|
13658
|
+
import path40 from "path";
|
|
13493
13659
|
function clusterDirectories(graph) {
|
|
13494
13660
|
const dirImportedBy = /* @__PURE__ */ new Map();
|
|
13495
13661
|
for (const edge of graph.edges) {
|
|
13496
|
-
const sourceDir =
|
|
13497
|
-
const targetDir =
|
|
13662
|
+
const sourceDir = path40.dirname(edge.source);
|
|
13663
|
+
const targetDir = path40.dirname(edge.target);
|
|
13498
13664
|
if (sourceDir === targetDir) continue;
|
|
13499
13665
|
if (!graph.files.has(edge.target)) continue;
|
|
13500
13666
|
const existing = dirImportedBy.get(targetDir) ?? /* @__PURE__ */ new Set();
|
|
@@ -13522,20 +13688,20 @@ function clusterDirectories(graph) {
|
|
|
13522
13688
|
return clusters;
|
|
13523
13689
|
}
|
|
13524
13690
|
function isAncestor(ancestor, descendant) {
|
|
13525
|
-
const rel =
|
|
13691
|
+
const rel = path40.relative(ancestor, descendant);
|
|
13526
13692
|
return !rel.startsWith("..") && rel !== "";
|
|
13527
13693
|
}
|
|
13528
13694
|
|
|
13529
13695
|
// src/commands/refactor/restructure/clusterFiles.ts
|
|
13530
|
-
import
|
|
13696
|
+
import path41 from "path";
|
|
13531
13697
|
function findRootParent(file, importedBy, visited) {
|
|
13532
13698
|
const importers = importedBy.get(file);
|
|
13533
13699
|
if (!importers || importers.size !== 1) return file;
|
|
13534
13700
|
const parent = [...importers][0];
|
|
13535
|
-
const parentDir =
|
|
13536
|
-
const fileDir =
|
|
13701
|
+
const parentDir = path41.dirname(parent);
|
|
13702
|
+
const fileDir = path41.dirname(file);
|
|
13537
13703
|
if (parentDir !== fileDir) return file;
|
|
13538
|
-
if (
|
|
13704
|
+
if (path41.basename(parent, path41.extname(parent)) === "index") return file;
|
|
13539
13705
|
if (visited.has(parent)) return file;
|
|
13540
13706
|
visited.add(parent);
|
|
13541
13707
|
return findRootParent(parent, importedBy, visited);
|
|
@@ -13543,16 +13709,16 @@ function findRootParent(file, importedBy, visited) {
|
|
|
13543
13709
|
function clusterFiles(graph) {
|
|
13544
13710
|
const clusters = /* @__PURE__ */ new Map();
|
|
13545
13711
|
for (const file of graph.files) {
|
|
13546
|
-
const basename12 =
|
|
13712
|
+
const basename12 = path41.basename(file, path41.extname(file));
|
|
13547
13713
|
if (basename12 === "index") continue;
|
|
13548
13714
|
const importers = graph.importedBy.get(file);
|
|
13549
13715
|
if (!importers || importers.size !== 1) continue;
|
|
13550
13716
|
const parent = [...importers][0];
|
|
13551
13717
|
if (!graph.files.has(parent)) continue;
|
|
13552
|
-
const parentDir =
|
|
13553
|
-
const fileDir =
|
|
13718
|
+
const parentDir = path41.dirname(parent);
|
|
13719
|
+
const fileDir = path41.dirname(file);
|
|
13554
13720
|
if (parentDir !== fileDir) continue;
|
|
13555
|
-
const parentBasename =
|
|
13721
|
+
const parentBasename = path41.basename(parent, path41.extname(parent));
|
|
13556
13722
|
if (parentBasename === "index") continue;
|
|
13557
13723
|
const root = findRootParent(parent, graph.importedBy, /* @__PURE__ */ new Set([file]));
|
|
13558
13724
|
if (!root || root === file) continue;
|
|
@@ -13563,150 +13729,52 @@ function clusterFiles(graph) {
|
|
|
13563
13729
|
return clusters;
|
|
13564
13730
|
}
|
|
13565
13731
|
|
|
13566
|
-
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
13567
|
-
import path39 from "path";
|
|
13568
|
-
|
|
13569
|
-
// src/commands/refactor/restructure/computeRewrites/applyRewrites.ts
|
|
13570
|
-
import fs21 from "fs";
|
|
13571
|
-
function getOrCreateList(map, key) {
|
|
13572
|
-
const list4 = map.get(key) ?? [];
|
|
13573
|
-
if (!map.has(key)) map.set(key, list4);
|
|
13574
|
-
return list4;
|
|
13575
|
-
}
|
|
13576
|
-
function groupByFile2(rewrites) {
|
|
13577
|
-
const grouped = /* @__PURE__ */ new Map();
|
|
13578
|
-
for (const rewrite of rewrites) {
|
|
13579
|
-
getOrCreateList(grouped, rewrite.file).push(rewrite);
|
|
13580
|
-
}
|
|
13581
|
-
return grouped;
|
|
13582
|
-
}
|
|
13583
|
-
function rewriteSpecifier(content, oldSpecifier, newSpecifier) {
|
|
13584
|
-
const escaped = oldSpecifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
13585
|
-
const pattern2 = new RegExp(`(from\\s+["'])${escaped}(["'])`, "g");
|
|
13586
|
-
return content.replace(pattern2, `$1${newSpecifier}$2`);
|
|
13587
|
-
}
|
|
13588
|
-
function applyFileRewrites(file, fileRewrites) {
|
|
13589
|
-
let content = fs21.readFileSync(file, "utf-8");
|
|
13590
|
-
for (const { oldSpecifier, newSpecifier } of fileRewrites) {
|
|
13591
|
-
content = rewriteSpecifier(content, oldSpecifier, newSpecifier);
|
|
13592
|
-
}
|
|
13593
|
-
return content;
|
|
13594
|
-
}
|
|
13595
|
-
function applyRewrites(rewrites) {
|
|
13596
|
-
const updatedContents = /* @__PURE__ */ new Map();
|
|
13597
|
-
for (const [file, fileRewrites] of groupByFile2(rewrites)) {
|
|
13598
|
-
updatedContents.set(file, applyFileRewrites(file, fileRewrites));
|
|
13599
|
-
}
|
|
13600
|
-
return updatedContents;
|
|
13601
|
-
}
|
|
13602
|
-
|
|
13603
|
-
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
13604
|
-
function buildMoveMap(moves) {
|
|
13605
|
-
const map = /* @__PURE__ */ new Map();
|
|
13606
|
-
for (const move of moves) map.set(move.from, move.to);
|
|
13607
|
-
return map;
|
|
13608
|
-
}
|
|
13609
|
-
function stripTrailingIndex(specifier) {
|
|
13610
|
-
return specifier.endsWith("/index") ? specifier.slice(0, -"/index".length) : specifier;
|
|
13611
|
-
}
|
|
13612
|
-
function ensureRelative(specifier) {
|
|
13613
|
-
return specifier.startsWith(".") ? specifier : `./${specifier}`;
|
|
13614
|
-
}
|
|
13615
|
-
function normalizeSpecifier(rel) {
|
|
13616
|
-
return ensureRelative(
|
|
13617
|
-
stripTrailingIndex(rel.replace(/\\/g, "/").replace(/\.tsx?$/, ""))
|
|
13618
|
-
);
|
|
13619
|
-
}
|
|
13620
|
-
function computeSpecifier(fromFile, toFile) {
|
|
13621
|
-
return normalizeSpecifier(path39.relative(path39.dirname(fromFile), toFile));
|
|
13622
|
-
}
|
|
13623
|
-
function isAffected(edge, moveMap) {
|
|
13624
|
-
return moveMap.has(edge.target) || moveMap.has(edge.source);
|
|
13625
|
-
}
|
|
13626
|
-
function resolveTarget(edge, moveMap) {
|
|
13627
|
-
return moveMap.get(edge.target) ?? edge.target;
|
|
13628
|
-
}
|
|
13629
|
-
function createRewrite(edge, newSpecifier) {
|
|
13630
|
-
return { file: edge.source, oldSpecifier: edge.specifier, newSpecifier };
|
|
13631
|
-
}
|
|
13632
|
-
function rewriteIfChanged(edge, newSpecifier) {
|
|
13633
|
-
return newSpecifier === edge.specifier ? null : createRewrite(edge, newSpecifier);
|
|
13634
|
-
}
|
|
13635
|
-
function rewriteEdge(edge, newFile, moveMap) {
|
|
13636
|
-
if (!isAffected(edge, moveMap)) return null;
|
|
13637
|
-
return rewriteIfChanged(
|
|
13638
|
-
edge,
|
|
13639
|
-
computeSpecifier(newFile, resolveTarget(edge, moveMap))
|
|
13640
|
-
);
|
|
13641
|
-
}
|
|
13642
|
-
function fileEdges(edges, file) {
|
|
13643
|
-
return edges.filter((e) => e.source === file);
|
|
13644
|
-
}
|
|
13645
|
-
function collectRewrites(edges, newFile, moveMap) {
|
|
13646
|
-
const rewrites = [];
|
|
13647
|
-
for (const edge of edges) {
|
|
13648
|
-
const rewrite = rewriteEdge(edge, newFile, moveMap);
|
|
13649
|
-
if (rewrite) rewrites.push(rewrite);
|
|
13650
|
-
}
|
|
13651
|
-
return rewrites;
|
|
13652
|
-
}
|
|
13653
|
-
function rewriteEdgesForFile(file, edges, moveMap) {
|
|
13654
|
-
const newFile = moveMap.get(file) ?? file;
|
|
13655
|
-
return collectRewrites(fileEdges(edges, file), newFile, moveMap);
|
|
13656
|
-
}
|
|
13657
|
-
function computeRewrites(moves, edges, allProjectFiles) {
|
|
13658
|
-
const moveMap = buildMoveMap(moves);
|
|
13659
|
-
return [...allProjectFiles].flatMap(
|
|
13660
|
-
(file) => rewriteEdgesForFile(file, edges, moveMap)
|
|
13661
|
-
);
|
|
13662
|
-
}
|
|
13663
|
-
|
|
13664
13732
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
13665
|
-
import
|
|
13666
|
-
import
|
|
13733
|
+
import path42 from "path";
|
|
13734
|
+
import chalk143 from "chalk";
|
|
13667
13735
|
function relPath(filePath) {
|
|
13668
|
-
return
|
|
13736
|
+
return path42.relative(process.cwd(), filePath);
|
|
13669
13737
|
}
|
|
13670
13738
|
function displayMoves(plan2) {
|
|
13671
13739
|
if (plan2.moves.length === 0) return;
|
|
13672
|
-
console.log(
|
|
13740
|
+
console.log(chalk143.bold("\nFile moves:"));
|
|
13673
13741
|
for (const move of plan2.moves) {
|
|
13674
13742
|
console.log(
|
|
13675
|
-
` ${
|
|
13743
|
+
` ${chalk143.red(relPath(move.from))} \u2192 ${chalk143.green(relPath(move.to))}`
|
|
13676
13744
|
);
|
|
13677
|
-
console.log(
|
|
13745
|
+
console.log(chalk143.dim(` ${move.reason}`));
|
|
13678
13746
|
}
|
|
13679
13747
|
}
|
|
13680
13748
|
function displayRewrites(rewrites) {
|
|
13681
13749
|
if (rewrites.length === 0) return;
|
|
13682
13750
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
13683
|
-
console.log(
|
|
13751
|
+
console.log(chalk143.bold(`
|
|
13684
13752
|
Import rewrites (${affectedFiles.size} files):`));
|
|
13685
13753
|
for (const file of affectedFiles) {
|
|
13686
|
-
console.log(` ${
|
|
13754
|
+
console.log(` ${chalk143.cyan(relPath(file))}:`);
|
|
13687
13755
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
13688
13756
|
(r) => r.file === file
|
|
13689
13757
|
)) {
|
|
13690
13758
|
console.log(
|
|
13691
|
-
` ${
|
|
13759
|
+
` ${chalk143.red(`"${oldSpecifier}"`)} \u2192 ${chalk143.green(`"${newSpecifier}"`)}`
|
|
13692
13760
|
);
|
|
13693
13761
|
}
|
|
13694
13762
|
}
|
|
13695
13763
|
}
|
|
13696
13764
|
function displayPlan2(plan2) {
|
|
13697
13765
|
if (plan2.warnings.length > 0) {
|
|
13698
|
-
console.log(
|
|
13699
|
-
for (const w of plan2.warnings) console.log(
|
|
13766
|
+
console.log(chalk143.yellow("\nWarnings:"));
|
|
13767
|
+
for (const w of plan2.warnings) console.log(chalk143.yellow(` ${w}`));
|
|
13700
13768
|
}
|
|
13701
13769
|
if (plan2.newDirectories.length > 0) {
|
|
13702
|
-
console.log(
|
|
13770
|
+
console.log(chalk143.bold("\nNew directories:"));
|
|
13703
13771
|
for (const dir of plan2.newDirectories)
|
|
13704
|
-
console.log(
|
|
13772
|
+
console.log(chalk143.green(` ${dir}/`));
|
|
13705
13773
|
}
|
|
13706
13774
|
displayMoves(plan2);
|
|
13707
13775
|
displayRewrites(plan2.rewrites);
|
|
13708
13776
|
console.log(
|
|
13709
|
-
|
|
13777
|
+
chalk143.dim(
|
|
13710
13778
|
`
|
|
13711
13779
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
13712
13780
|
)
|
|
@@ -13714,45 +13782,45 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
13714
13782
|
}
|
|
13715
13783
|
|
|
13716
13784
|
// src/commands/refactor/restructure/executePlan.ts
|
|
13717
|
-
import
|
|
13718
|
-
import
|
|
13719
|
-
import
|
|
13785
|
+
import fs24 from "fs";
|
|
13786
|
+
import path43 from "path";
|
|
13787
|
+
import chalk144 from "chalk";
|
|
13720
13788
|
function executePlan(plan2) {
|
|
13721
13789
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
13722
13790
|
for (const [file, content] of updatedContents) {
|
|
13723
|
-
|
|
13791
|
+
fs24.writeFileSync(file, content, "utf-8");
|
|
13724
13792
|
console.log(
|
|
13725
|
-
|
|
13793
|
+
chalk144.cyan(` Rewrote imports in ${path43.relative(process.cwd(), file)}`)
|
|
13726
13794
|
);
|
|
13727
13795
|
}
|
|
13728
13796
|
for (const dir of plan2.newDirectories) {
|
|
13729
|
-
|
|
13730
|
-
console.log(
|
|
13797
|
+
fs24.mkdirSync(dir, { recursive: true });
|
|
13798
|
+
console.log(chalk144.green(` Created ${path43.relative(process.cwd(), dir)}/`));
|
|
13731
13799
|
}
|
|
13732
13800
|
for (const move of plan2.moves) {
|
|
13733
|
-
const targetDir =
|
|
13734
|
-
if (!
|
|
13735
|
-
|
|
13801
|
+
const targetDir = path43.dirname(move.to);
|
|
13802
|
+
if (!fs24.existsSync(targetDir)) {
|
|
13803
|
+
fs24.mkdirSync(targetDir, { recursive: true });
|
|
13736
13804
|
}
|
|
13737
|
-
|
|
13805
|
+
fs24.renameSync(move.from, move.to);
|
|
13738
13806
|
console.log(
|
|
13739
|
-
|
|
13740
|
-
` Moved ${
|
|
13807
|
+
chalk144.white(
|
|
13808
|
+
` Moved ${path43.relative(process.cwd(), move.from)} \u2192 ${path43.relative(process.cwd(), move.to)}`
|
|
13741
13809
|
)
|
|
13742
13810
|
);
|
|
13743
13811
|
}
|
|
13744
|
-
removeEmptyDirectories(plan2.moves.map((m) =>
|
|
13812
|
+
removeEmptyDirectories(plan2.moves.map((m) => path43.dirname(m.from)));
|
|
13745
13813
|
}
|
|
13746
13814
|
function removeEmptyDirectories(dirs) {
|
|
13747
13815
|
const unique = [...new Set(dirs)];
|
|
13748
13816
|
for (const dir of unique) {
|
|
13749
|
-
if (!
|
|
13750
|
-
const entries =
|
|
13817
|
+
if (!fs24.existsSync(dir)) continue;
|
|
13818
|
+
const entries = fs24.readdirSync(dir);
|
|
13751
13819
|
if (entries.length === 0) {
|
|
13752
|
-
|
|
13820
|
+
fs24.rmdirSync(dir);
|
|
13753
13821
|
console.log(
|
|
13754
|
-
|
|
13755
|
-
` Removed empty directory ${
|
|
13822
|
+
chalk144.dim(
|
|
13823
|
+
` Removed empty directory ${path43.relative(process.cwd(), dir)}`
|
|
13756
13824
|
)
|
|
13757
13825
|
);
|
|
13758
13826
|
}
|
|
@@ -13760,46 +13828,46 @@ function removeEmptyDirectories(dirs) {
|
|
|
13760
13828
|
}
|
|
13761
13829
|
|
|
13762
13830
|
// src/commands/refactor/restructure/planFileMoves/index.ts
|
|
13763
|
-
import
|
|
13831
|
+
import path45 from "path";
|
|
13764
13832
|
|
|
13765
13833
|
// src/commands/refactor/restructure/planFileMoves/shared.ts
|
|
13766
|
-
import
|
|
13834
|
+
import fs25 from "fs";
|
|
13767
13835
|
function emptyResult() {
|
|
13768
13836
|
return { moves: [], directories: [], warnings: [] };
|
|
13769
13837
|
}
|
|
13770
13838
|
function checkDirConflict(result, label2, dir) {
|
|
13771
|
-
if (!
|
|
13839
|
+
if (!fs25.existsSync(dir)) return false;
|
|
13772
13840
|
result.warnings.push(`Skipping ${label2}: directory ${dir} already exists`);
|
|
13773
13841
|
return true;
|
|
13774
13842
|
}
|
|
13775
13843
|
|
|
13776
13844
|
// src/commands/refactor/restructure/planFileMoves/planDirectoryMoves.ts
|
|
13777
|
-
import
|
|
13778
|
-
import
|
|
13845
|
+
import fs26 from "fs";
|
|
13846
|
+
import path44 from "path";
|
|
13779
13847
|
function collectEntry(results, dir, entry) {
|
|
13780
|
-
const full =
|
|
13848
|
+
const full = path44.join(dir, entry.name);
|
|
13781
13849
|
const items2 = entry.isDirectory() ? listFilesRecursive(full) : [full];
|
|
13782
13850
|
results.push(...items2);
|
|
13783
13851
|
}
|
|
13784
13852
|
function listFilesRecursive(dir) {
|
|
13785
|
-
if (!
|
|
13853
|
+
if (!fs26.existsSync(dir)) return [];
|
|
13786
13854
|
const results = [];
|
|
13787
|
-
for (const entry of
|
|
13855
|
+
for (const entry of fs26.readdirSync(dir, { withFileTypes: true })) {
|
|
13788
13856
|
collectEntry(results, dir, entry);
|
|
13789
13857
|
}
|
|
13790
13858
|
return results;
|
|
13791
13859
|
}
|
|
13792
13860
|
function addDirectoryFileMoves(moves, childDir, newLocation, reason) {
|
|
13793
13861
|
for (const file of listFilesRecursive(childDir)) {
|
|
13794
|
-
const rel =
|
|
13795
|
-
moves.push({ from: file, to:
|
|
13862
|
+
const rel = path44.relative(childDir, file);
|
|
13863
|
+
moves.push({ from: file, to: path44.join(newLocation, rel), reason });
|
|
13796
13864
|
}
|
|
13797
13865
|
}
|
|
13798
13866
|
function resolveChildDest(parentDir, childDir) {
|
|
13799
|
-
return
|
|
13867
|
+
return path44.join(parentDir, path44.basename(childDir));
|
|
13800
13868
|
}
|
|
13801
13869
|
function childMoveReason(parentDir) {
|
|
13802
|
-
return `Directory only imported from ${
|
|
13870
|
+
return `Directory only imported from ${path44.basename(parentDir)}/`;
|
|
13803
13871
|
}
|
|
13804
13872
|
function registerDirectoryMove(result, childDir, dest, parentDir) {
|
|
13805
13873
|
result.directories.push(dest);
|
|
@@ -13824,7 +13892,7 @@ function planDirectoryMoves(clusters) {
|
|
|
13824
13892
|
|
|
13825
13893
|
// src/commands/refactor/restructure/planFileMoves/index.ts
|
|
13826
13894
|
function childMoveData(child, newDir, parentBase) {
|
|
13827
|
-
const to =
|
|
13895
|
+
const to = path45.join(newDir, path45.basename(child));
|
|
13828
13896
|
return { from: child, to, reason: `Only imported by ${parentBase}` };
|
|
13829
13897
|
}
|
|
13830
13898
|
function addChildMoves(moves, children, newDir, parentBase) {
|
|
@@ -13832,15 +13900,15 @@ function addChildMoves(moves, children, newDir, parentBase) {
|
|
|
13832
13900
|
moves.push(childMoveData(child, newDir, parentBase));
|
|
13833
13901
|
}
|
|
13834
13902
|
function getBaseName(filePath) {
|
|
13835
|
-
return
|
|
13903
|
+
return path45.basename(filePath, path45.extname(filePath));
|
|
13836
13904
|
}
|
|
13837
13905
|
function resolveClusterDir(parent) {
|
|
13838
|
-
return
|
|
13906
|
+
return path45.join(path45.dirname(parent), getBaseName(parent));
|
|
13839
13907
|
}
|
|
13840
13908
|
function createParentMove(parent, newDir) {
|
|
13841
13909
|
return {
|
|
13842
13910
|
from: parent,
|
|
13843
|
-
to:
|
|
13911
|
+
to: path45.join(newDir, `index${path45.extname(parent)}`),
|
|
13844
13912
|
reason: `Main module of new ${getBaseName(parent)}/ directory`
|
|
13845
13913
|
};
|
|
13846
13914
|
}
|
|
@@ -13864,7 +13932,7 @@ function planFileMoves(clusters) {
|
|
|
13864
13932
|
|
|
13865
13933
|
// src/commands/refactor/restructure/index.ts
|
|
13866
13934
|
function buildPlan3(candidateFiles, tsConfigPath) {
|
|
13867
|
-
const candidates = new Set(candidateFiles.map((f) =>
|
|
13935
|
+
const candidates = new Set(candidateFiles.map((f) => path46.resolve(f)));
|
|
13868
13936
|
const graph = buildImportGraph(candidates, tsConfigPath);
|
|
13869
13937
|
const allProjectFiles = /* @__PURE__ */ new Set([
|
|
13870
13938
|
...graph.importedBy.keys(),
|
|
@@ -13884,22 +13952,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
13884
13952
|
const targetPattern = pattern2 ?? "src";
|
|
13885
13953
|
const files = findSourceFiles2(targetPattern);
|
|
13886
13954
|
if (files.length === 0) {
|
|
13887
|
-
console.log(
|
|
13955
|
+
console.log(chalk145.yellow("No files found matching pattern"));
|
|
13888
13956
|
return;
|
|
13889
13957
|
}
|
|
13890
|
-
const tsConfigPath =
|
|
13958
|
+
const tsConfigPath = path46.resolve("tsconfig.json");
|
|
13891
13959
|
const plan2 = buildPlan3(files, tsConfigPath);
|
|
13892
13960
|
if (plan2.moves.length === 0) {
|
|
13893
|
-
console.log(
|
|
13961
|
+
console.log(chalk145.green("No restructuring needed"));
|
|
13894
13962
|
return;
|
|
13895
13963
|
}
|
|
13896
13964
|
displayPlan2(plan2);
|
|
13897
13965
|
if (options2.apply) {
|
|
13898
|
-
console.log(
|
|
13966
|
+
console.log(chalk145.bold("\nApplying changes..."));
|
|
13899
13967
|
executePlan(plan2);
|
|
13900
|
-
console.log(
|
|
13968
|
+
console.log(chalk145.green("\nRestructuring complete"));
|
|
13901
13969
|
} else {
|
|
13902
|
-
console.log(
|
|
13970
|
+
console.log(chalk145.dim("\nDry run. Use --apply to execute."));
|
|
13903
13971
|
}
|
|
13904
13972
|
}
|
|
13905
13973
|
|
|
@@ -14468,18 +14536,18 @@ function partitionFindingsByDiff(findings, index2) {
|
|
|
14468
14536
|
}
|
|
14469
14537
|
|
|
14470
14538
|
// src/commands/review/warnOutOfDiff.ts
|
|
14471
|
-
import
|
|
14539
|
+
import chalk146 from "chalk";
|
|
14472
14540
|
function warnOutOfDiff(outOfDiff) {
|
|
14473
14541
|
if (outOfDiff.length === 0) return;
|
|
14474
14542
|
console.warn(
|
|
14475
|
-
|
|
14543
|
+
chalk146.yellow(
|
|
14476
14544
|
`Skipped ${outOfDiff.length} finding(s) whose lines fall outside the PR diff (GitHub would silently drop these):`
|
|
14477
14545
|
)
|
|
14478
14546
|
);
|
|
14479
14547
|
for (const finding of outOfDiff) {
|
|
14480
14548
|
const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
|
|
14481
14549
|
console.warn(
|
|
14482
|
-
` ${
|
|
14550
|
+
` ${chalk146.yellow("\xB7")} ${finding.title} ${chalk146.dim(
|
|
14483
14551
|
`(${finding.file}:${range})`
|
|
14484
14552
|
)}`
|
|
14485
14553
|
);
|
|
@@ -14498,18 +14566,18 @@ function selectInDiffFindings(lineBound, prDiff) {
|
|
|
14498
14566
|
}
|
|
14499
14567
|
|
|
14500
14568
|
// src/commands/review/warnUnlocated.ts
|
|
14501
|
-
import
|
|
14569
|
+
import chalk147 from "chalk";
|
|
14502
14570
|
function warnUnlocated(unlocated) {
|
|
14503
14571
|
if (unlocated.length === 0) return;
|
|
14504
14572
|
console.warn(
|
|
14505
|
-
|
|
14573
|
+
chalk147.yellow(
|
|
14506
14574
|
`Skipped ${unlocated.length} finding(s) without a parseable file:line:`
|
|
14507
14575
|
)
|
|
14508
14576
|
);
|
|
14509
14577
|
for (const finding of unlocated) {
|
|
14510
|
-
const where = finding.location ||
|
|
14578
|
+
const where = finding.location || chalk147.dim("missing");
|
|
14511
14579
|
console.warn(
|
|
14512
|
-
` ${
|
|
14580
|
+
` ${chalk147.yellow("\xB7")} ${finding.title} ${chalk147.dim(`(${where})`)}`
|
|
14513
14581
|
);
|
|
14514
14582
|
}
|
|
14515
14583
|
}
|
|
@@ -14606,8 +14674,8 @@ async function handlePostSynthesis(synthesisPath, options2) {
|
|
|
14606
14674
|
// src/commands/review/prepareReviewDir.ts
|
|
14607
14675
|
import { existsSync as existsSync36, mkdirSync as mkdirSync14, unlinkSync as unlinkSync12, writeFileSync as writeFileSync26 } from "fs";
|
|
14608
14676
|
function clearReviewFiles(paths) {
|
|
14609
|
-
for (const
|
|
14610
|
-
if (existsSync36(
|
|
14677
|
+
for (const path56 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
|
|
14678
|
+
if (existsSync36(path56)) unlinkSync12(path56);
|
|
14611
14679
|
}
|
|
14612
14680
|
}
|
|
14613
14681
|
function prepareReviewDir(paths, requestBody, force) {
|
|
@@ -15682,7 +15750,7 @@ function registerReview(program2) {
|
|
|
15682
15750
|
}
|
|
15683
15751
|
|
|
15684
15752
|
// src/commands/seq/seqAuth.ts
|
|
15685
|
-
import
|
|
15753
|
+
import chalk149 from "chalk";
|
|
15686
15754
|
|
|
15687
15755
|
// src/commands/seq/loadConnections.ts
|
|
15688
15756
|
function loadConnections2() {
|
|
@@ -15711,10 +15779,10 @@ function setDefaultConnection(name) {
|
|
|
15711
15779
|
}
|
|
15712
15780
|
|
|
15713
15781
|
// src/shared/assertUniqueName.ts
|
|
15714
|
-
import
|
|
15782
|
+
import chalk148 from "chalk";
|
|
15715
15783
|
function assertUniqueName(existingNames, name) {
|
|
15716
15784
|
if (existingNames.includes(name)) {
|
|
15717
|
-
console.error(
|
|
15785
|
+
console.error(chalk148.red(`Connection "${name}" already exists.`));
|
|
15718
15786
|
process.exit(1);
|
|
15719
15787
|
}
|
|
15720
15788
|
}
|
|
@@ -15732,18 +15800,18 @@ async function promptConnection2(existingNames) {
|
|
|
15732
15800
|
var seqAuth = createConnectionAuth({
|
|
15733
15801
|
load: loadConnections2,
|
|
15734
15802
|
save: saveConnections2,
|
|
15735
|
-
format: (c) => `${
|
|
15803
|
+
format: (c) => `${chalk149.bold(c.name)} ${c.url}`,
|
|
15736
15804
|
promptNew: promptConnection2,
|
|
15737
15805
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
15738
15806
|
});
|
|
15739
15807
|
|
|
15740
15808
|
// src/commands/seq/seqQuery.ts
|
|
15741
|
-
import
|
|
15809
|
+
import chalk153 from "chalk";
|
|
15742
15810
|
|
|
15743
15811
|
// src/commands/seq/fetchSeq.ts
|
|
15744
|
-
import
|
|
15745
|
-
async function fetchSeq(conn,
|
|
15746
|
-
const url = `${conn.url}${
|
|
15812
|
+
import chalk150 from "chalk";
|
|
15813
|
+
async function fetchSeq(conn, path56, params) {
|
|
15814
|
+
const url = `${conn.url}${path56}?${params}`;
|
|
15747
15815
|
const response = await fetch(url, {
|
|
15748
15816
|
headers: {
|
|
15749
15817
|
Accept: "application/json",
|
|
@@ -15752,7 +15820,7 @@ async function fetchSeq(conn, path54, params) {
|
|
|
15752
15820
|
});
|
|
15753
15821
|
if (!response.ok) {
|
|
15754
15822
|
const body = await response.text();
|
|
15755
|
-
console.error(
|
|
15823
|
+
console.error(chalk150.red(`Seq returned ${response.status}: ${body}`));
|
|
15756
15824
|
process.exit(1);
|
|
15757
15825
|
}
|
|
15758
15826
|
return response;
|
|
@@ -15807,23 +15875,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
15807
15875
|
}
|
|
15808
15876
|
|
|
15809
15877
|
// src/commands/seq/formatEvent.ts
|
|
15810
|
-
import
|
|
15878
|
+
import chalk151 from "chalk";
|
|
15811
15879
|
function levelColor(level) {
|
|
15812
15880
|
switch (level) {
|
|
15813
15881
|
case "Fatal":
|
|
15814
|
-
return
|
|
15882
|
+
return chalk151.bgRed.white;
|
|
15815
15883
|
case "Error":
|
|
15816
|
-
return
|
|
15884
|
+
return chalk151.red;
|
|
15817
15885
|
case "Warning":
|
|
15818
|
-
return
|
|
15886
|
+
return chalk151.yellow;
|
|
15819
15887
|
case "Information":
|
|
15820
|
-
return
|
|
15888
|
+
return chalk151.cyan;
|
|
15821
15889
|
case "Debug":
|
|
15822
|
-
return
|
|
15890
|
+
return chalk151.gray;
|
|
15823
15891
|
case "Verbose":
|
|
15824
|
-
return
|
|
15892
|
+
return chalk151.dim;
|
|
15825
15893
|
default:
|
|
15826
|
-
return
|
|
15894
|
+
return chalk151.white;
|
|
15827
15895
|
}
|
|
15828
15896
|
}
|
|
15829
15897
|
function levelAbbrev(level) {
|
|
@@ -15864,12 +15932,12 @@ function formatTimestamp(iso) {
|
|
|
15864
15932
|
function formatEvent(event) {
|
|
15865
15933
|
const color = levelColor(event.Level);
|
|
15866
15934
|
const abbrev = levelAbbrev(event.Level);
|
|
15867
|
-
const ts8 =
|
|
15935
|
+
const ts8 = chalk151.dim(formatTimestamp(event.Timestamp));
|
|
15868
15936
|
const msg = renderMessage(event);
|
|
15869
15937
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
15870
15938
|
if (event.Exception) {
|
|
15871
15939
|
for (const line of event.Exception.split("\n")) {
|
|
15872
|
-
lines.push(
|
|
15940
|
+
lines.push(chalk151.red(` ${line}`));
|
|
15873
15941
|
}
|
|
15874
15942
|
}
|
|
15875
15943
|
return lines.join("\n");
|
|
@@ -15902,11 +15970,11 @@ function rejectTimestampFilter(filter) {
|
|
|
15902
15970
|
}
|
|
15903
15971
|
|
|
15904
15972
|
// src/shared/resolveNamedConnection.ts
|
|
15905
|
-
import
|
|
15973
|
+
import chalk152 from "chalk";
|
|
15906
15974
|
function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
|
|
15907
15975
|
if (connections.length === 0) {
|
|
15908
15976
|
console.error(
|
|
15909
|
-
|
|
15977
|
+
chalk152.red(
|
|
15910
15978
|
`No ${kind} connections configured. Run '${authCommand}' first.`
|
|
15911
15979
|
)
|
|
15912
15980
|
);
|
|
@@ -15915,7 +15983,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
|
|
|
15915
15983
|
const target = requested ?? defaultName ?? connections[0].name;
|
|
15916
15984
|
const connection = connections.find((c) => c.name === target);
|
|
15917
15985
|
if (!connection) {
|
|
15918
|
-
console.error(
|
|
15986
|
+
console.error(chalk152.red(`${kind} connection "${target}" not found.`));
|
|
15919
15987
|
process.exit(1);
|
|
15920
15988
|
}
|
|
15921
15989
|
return connection;
|
|
@@ -15944,7 +16012,7 @@ async function seqQuery(filter, options2) {
|
|
|
15944
16012
|
new URLSearchParams({ filter, count: String(count6) })
|
|
15945
16013
|
);
|
|
15946
16014
|
if (events.length === 0) {
|
|
15947
|
-
console.log(
|
|
16015
|
+
console.log(chalk153.yellow("No events found."));
|
|
15948
16016
|
return;
|
|
15949
16017
|
}
|
|
15950
16018
|
if (options2.json) {
|
|
@@ -15955,11 +16023,11 @@ async function seqQuery(filter, options2) {
|
|
|
15955
16023
|
for (const event of chronological) {
|
|
15956
16024
|
console.log(formatEvent(event));
|
|
15957
16025
|
}
|
|
15958
|
-
console.log(
|
|
16026
|
+
console.log(chalk153.dim(`
|
|
15959
16027
|
${events.length} events`));
|
|
15960
16028
|
if (events.length >= count6) {
|
|
15961
16029
|
console.log(
|
|
15962
|
-
|
|
16030
|
+
chalk153.yellow(
|
|
15963
16031
|
`Results limited to ${count6}. Use --count to retrieve more.`
|
|
15964
16032
|
)
|
|
15965
16033
|
);
|
|
@@ -15967,10 +16035,10 @@ ${events.length} events`));
|
|
|
15967
16035
|
}
|
|
15968
16036
|
|
|
15969
16037
|
// src/shared/setNamedDefaultConnection.ts
|
|
15970
|
-
import
|
|
16038
|
+
import chalk154 from "chalk";
|
|
15971
16039
|
function setNamedDefaultConnection(connections, name, setDefault, kind) {
|
|
15972
16040
|
if (!connections.find((c) => c.name === name)) {
|
|
15973
|
-
console.error(
|
|
16041
|
+
console.error(chalk154.red(`Connection "${name}" not found.`));
|
|
15974
16042
|
process.exit(1);
|
|
15975
16043
|
}
|
|
15976
16044
|
setDefault(name);
|
|
@@ -16018,7 +16086,7 @@ function registerSignal(program2) {
|
|
|
16018
16086
|
}
|
|
16019
16087
|
|
|
16020
16088
|
// src/commands/sql/sqlAuth.ts
|
|
16021
|
-
import
|
|
16089
|
+
import chalk156 from "chalk";
|
|
16022
16090
|
|
|
16023
16091
|
// src/commands/sql/loadConnections.ts
|
|
16024
16092
|
function loadConnections3() {
|
|
@@ -16047,7 +16115,7 @@ function setDefaultConnection2(name) {
|
|
|
16047
16115
|
}
|
|
16048
16116
|
|
|
16049
16117
|
// src/commands/sql/promptConnection.ts
|
|
16050
|
-
import
|
|
16118
|
+
import chalk155 from "chalk";
|
|
16051
16119
|
async function promptConnection3(existingNames) {
|
|
16052
16120
|
const name = await promptInput("name", "Connection name:", "default");
|
|
16053
16121
|
assertUniqueName(existingNames, name);
|
|
@@ -16055,7 +16123,7 @@ async function promptConnection3(existingNames) {
|
|
|
16055
16123
|
const portStr = await promptInput("port", "Port:", "1433");
|
|
16056
16124
|
const port = Number.parseInt(portStr, 10);
|
|
16057
16125
|
if (!Number.isFinite(port)) {
|
|
16058
|
-
console.error(
|
|
16126
|
+
console.error(chalk155.red(`Invalid port "${portStr}".`));
|
|
16059
16127
|
process.exit(1);
|
|
16060
16128
|
}
|
|
16061
16129
|
const user = await promptInput("user", "User:");
|
|
@@ -16068,13 +16136,13 @@ async function promptConnection3(existingNames) {
|
|
|
16068
16136
|
var sqlAuth = createConnectionAuth({
|
|
16069
16137
|
load: loadConnections3,
|
|
16070
16138
|
save: saveConnections3,
|
|
16071
|
-
format: (c) => `${
|
|
16139
|
+
format: (c) => `${chalk156.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
|
|
16072
16140
|
promptNew: promptConnection3,
|
|
16073
16141
|
onFirst: (c) => setDefaultConnection2(c.name)
|
|
16074
16142
|
});
|
|
16075
16143
|
|
|
16076
16144
|
// src/commands/sql/printTable.ts
|
|
16077
|
-
import
|
|
16145
|
+
import chalk157 from "chalk";
|
|
16078
16146
|
function formatCell(value) {
|
|
16079
16147
|
if (value === null || value === void 0) return "";
|
|
16080
16148
|
if (value instanceof Date) return value.toISOString();
|
|
@@ -16083,7 +16151,7 @@ function formatCell(value) {
|
|
|
16083
16151
|
}
|
|
16084
16152
|
function printTable(rows) {
|
|
16085
16153
|
if (rows.length === 0) {
|
|
16086
|
-
console.log(
|
|
16154
|
+
console.log(chalk157.yellow("(no rows)"));
|
|
16087
16155
|
return;
|
|
16088
16156
|
}
|
|
16089
16157
|
const columns = Object.keys(rows[0]);
|
|
@@ -16091,13 +16159,13 @@ function printTable(rows) {
|
|
|
16091
16159
|
(col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
|
|
16092
16160
|
);
|
|
16093
16161
|
const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
16094
|
-
console.log(
|
|
16095
|
-
console.log(
|
|
16162
|
+
console.log(chalk157.dim(header));
|
|
16163
|
+
console.log(chalk157.dim("-".repeat(header.length)));
|
|
16096
16164
|
for (const row of rows) {
|
|
16097
16165
|
const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
|
|
16098
16166
|
console.log(line);
|
|
16099
16167
|
}
|
|
16100
|
-
console.log(
|
|
16168
|
+
console.log(chalk157.dim(`
|
|
16101
16169
|
${rows.length} row${rows.length === 1 ? "" : "s"}`));
|
|
16102
16170
|
}
|
|
16103
16171
|
|
|
@@ -16157,7 +16225,7 @@ async function sqlColumns(table, connectionName) {
|
|
|
16157
16225
|
}
|
|
16158
16226
|
|
|
16159
16227
|
// src/commands/sql/sqlMutate.ts
|
|
16160
|
-
import
|
|
16228
|
+
import chalk158 from "chalk";
|
|
16161
16229
|
|
|
16162
16230
|
// src/commands/sql/isMutation.ts
|
|
16163
16231
|
var MUTATION_KEYWORDS = [
|
|
@@ -16191,7 +16259,7 @@ function isMutation(sql4) {
|
|
|
16191
16259
|
async function sqlMutate(query, connectionName) {
|
|
16192
16260
|
if (!isMutation(query)) {
|
|
16193
16261
|
console.error(
|
|
16194
|
-
|
|
16262
|
+
chalk158.red(
|
|
16195
16263
|
"assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
|
|
16196
16264
|
)
|
|
16197
16265
|
);
|
|
@@ -16201,18 +16269,18 @@ async function sqlMutate(query, connectionName) {
|
|
|
16201
16269
|
const pool = await sqlConnect(conn);
|
|
16202
16270
|
try {
|
|
16203
16271
|
const result = await pool.request().query(query);
|
|
16204
|
-
console.log(
|
|
16272
|
+
console.log(chalk158.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
|
|
16205
16273
|
} finally {
|
|
16206
16274
|
await pool.close();
|
|
16207
16275
|
}
|
|
16208
16276
|
}
|
|
16209
16277
|
|
|
16210
16278
|
// src/commands/sql/sqlQuery.ts
|
|
16211
|
-
import
|
|
16279
|
+
import chalk159 from "chalk";
|
|
16212
16280
|
async function sqlQuery(query, connectionName) {
|
|
16213
16281
|
if (isMutation(query)) {
|
|
16214
16282
|
console.error(
|
|
16215
|
-
|
|
16283
|
+
chalk159.red(
|
|
16216
16284
|
"assist sql query refuses mutating statements. Use `assist sql mutate` instead."
|
|
16217
16285
|
)
|
|
16218
16286
|
);
|
|
@@ -16227,7 +16295,7 @@ async function sqlQuery(query, connectionName) {
|
|
|
16227
16295
|
printTable(rows);
|
|
16228
16296
|
} else {
|
|
16229
16297
|
console.log(
|
|
16230
|
-
|
|
16298
|
+
chalk159.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
|
|
16231
16299
|
);
|
|
16232
16300
|
}
|
|
16233
16301
|
} finally {
|
|
@@ -16807,14 +16875,14 @@ import {
|
|
|
16807
16875
|
import { dirname as dirname22, join as join42 } from "path";
|
|
16808
16876
|
|
|
16809
16877
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
16810
|
-
import
|
|
16878
|
+
import chalk160 from "chalk";
|
|
16811
16879
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
16812
16880
|
function validateStagedContent(filename, content) {
|
|
16813
16881
|
const firstLine = content.split("\n")[0];
|
|
16814
16882
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
16815
16883
|
if (!match) {
|
|
16816
16884
|
console.error(
|
|
16817
|
-
|
|
16885
|
+
chalk160.red(
|
|
16818
16886
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
16819
16887
|
)
|
|
16820
16888
|
);
|
|
@@ -16823,7 +16891,7 @@ function validateStagedContent(filename, content) {
|
|
|
16823
16891
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
16824
16892
|
if (!contentAfterLink) {
|
|
16825
16893
|
console.error(
|
|
16826
|
-
|
|
16894
|
+
chalk160.red(
|
|
16827
16895
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
16828
16896
|
)
|
|
16829
16897
|
);
|
|
@@ -17220,7 +17288,7 @@ function registerVoice(program2) {
|
|
|
17220
17288
|
|
|
17221
17289
|
// src/commands/roam/auth.ts
|
|
17222
17290
|
import { randomBytes } from "crypto";
|
|
17223
|
-
import
|
|
17291
|
+
import chalk161 from "chalk";
|
|
17224
17292
|
|
|
17225
17293
|
// src/commands/roam/waitForCallback.ts
|
|
17226
17294
|
import { createServer as createServer2 } from "http";
|
|
@@ -17351,13 +17419,13 @@ async function auth() {
|
|
|
17351
17419
|
saveGlobalConfig(config);
|
|
17352
17420
|
const state = randomBytes(16).toString("hex");
|
|
17353
17421
|
console.log(
|
|
17354
|
-
|
|
17422
|
+
chalk161.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
17355
17423
|
);
|
|
17356
|
-
console.log(
|
|
17357
|
-
console.log(
|
|
17358
|
-
console.log(
|
|
17424
|
+
console.log(chalk161.white("http://localhost:14523/callback\n"));
|
|
17425
|
+
console.log(chalk161.blue("Opening browser for authorization..."));
|
|
17426
|
+
console.log(chalk161.dim("Waiting for authorization callback..."));
|
|
17359
17427
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
17360
|
-
console.log(
|
|
17428
|
+
console.log(chalk161.dim("Exchanging code for tokens..."));
|
|
17361
17429
|
const tokens = await exchangeToken({
|
|
17362
17430
|
code,
|
|
17363
17431
|
clientId,
|
|
@@ -17373,7 +17441,7 @@ async function auth() {
|
|
|
17373
17441
|
};
|
|
17374
17442
|
saveGlobalConfig(config);
|
|
17375
17443
|
console.log(
|
|
17376
|
-
|
|
17444
|
+
chalk161.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
17377
17445
|
);
|
|
17378
17446
|
}
|
|
17379
17447
|
|
|
@@ -17389,9 +17457,9 @@ function findPortFile(roamDir) {
|
|
|
17389
17457
|
return void 0;
|
|
17390
17458
|
}
|
|
17391
17459
|
const candidates = entries.filter((name) => /^roam-local-api(-[^.]+)?\.port$/.test(name)).map((name) => {
|
|
17392
|
-
const
|
|
17460
|
+
const path56 = join49(roamDir, name);
|
|
17393
17461
|
try {
|
|
17394
|
-
return { path:
|
|
17462
|
+
return { path: path56, mtimeMs: statSync5(path56).mtimeMs };
|
|
17395
17463
|
} catch {
|
|
17396
17464
|
return void 0;
|
|
17397
17465
|
}
|
|
@@ -17734,11 +17802,11 @@ function findLinkIndex() {
|
|
|
17734
17802
|
function parseLinkArgs() {
|
|
17735
17803
|
const idx = findLinkIndex();
|
|
17736
17804
|
if (idx === -1) return null;
|
|
17737
|
-
const
|
|
17805
|
+
const path56 = process.argv[idx + 1];
|
|
17738
17806
|
const rest = process.argv.slice(idx + 2);
|
|
17739
17807
|
const { value: prefix2 } = extractOption(rest, "--prefix");
|
|
17740
17808
|
if (!prefix2) return null;
|
|
17741
|
-
return { path:
|
|
17809
|
+
return { path: path56, prefix: prefix2 };
|
|
17742
17810
|
}
|
|
17743
17811
|
function hasDuplicateLink(runList, linkPath) {
|
|
17744
17812
|
return runList.some(
|
|
@@ -17825,7 +17893,7 @@ import { execSync as execSync48 } from "child_process";
|
|
|
17825
17893
|
import { existsSync as existsSync50, mkdirSync as mkdirSync21, unlinkSync as unlinkSync17, writeFileSync as writeFileSync32 } from "fs";
|
|
17826
17894
|
import { tmpdir as tmpdir7 } from "os";
|
|
17827
17895
|
import { join as join53, resolve as resolve13 } from "path";
|
|
17828
|
-
import
|
|
17896
|
+
import chalk162 from "chalk";
|
|
17829
17897
|
|
|
17830
17898
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
17831
17899
|
var captureWindowPs1 = `
|
|
@@ -17976,13 +18044,13 @@ function screenshot(processName) {
|
|
|
17976
18044
|
const config = loadConfig();
|
|
17977
18045
|
const outputDir = resolve13(config.screenshot.outputDir);
|
|
17978
18046
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
17979
|
-
console.log(
|
|
18047
|
+
console.log(chalk162.gray(`Capturing window for process "${processName}" ...`));
|
|
17980
18048
|
try {
|
|
17981
18049
|
runPowerShellScript(processName, outputPath);
|
|
17982
|
-
console.log(
|
|
18050
|
+
console.log(chalk162.green(`Screenshot saved: ${outputPath}`));
|
|
17983
18051
|
} catch (error) {
|
|
17984
18052
|
const msg = error instanceof Error ? error.message : String(error);
|
|
17985
|
-
console.error(
|
|
18053
|
+
console.error(chalk162.red(`Failed to capture screenshot: ${msg}`));
|
|
17986
18054
|
process.exit(1);
|
|
17987
18055
|
}
|
|
17988
18056
|
}
|
|
@@ -18215,14 +18283,14 @@ import * as pty from "node-pty";
|
|
|
18215
18283
|
// src/commands/sessions/daemon/ensureSpawnHelperExecutable.ts
|
|
18216
18284
|
import { chmodSync, existsSync as existsSync51, statSync as statSync6 } from "fs";
|
|
18217
18285
|
import { createRequire as createRequire3 } from "module";
|
|
18218
|
-
import
|
|
18286
|
+
import path47 from "path";
|
|
18219
18287
|
var require4 = createRequire3(import.meta.url);
|
|
18220
18288
|
var ensured = false;
|
|
18221
18289
|
function ensureSpawnHelperExecutable() {
|
|
18222
18290
|
if (ensured || process.platform !== "darwin") return;
|
|
18223
18291
|
ensured = true;
|
|
18224
|
-
const ptyRoot =
|
|
18225
|
-
const helper =
|
|
18292
|
+
const ptyRoot = path47.join(path47.dirname(require4.resolve("node-pty")), "..");
|
|
18293
|
+
const helper = path47.join(
|
|
18226
18294
|
ptyRoot,
|
|
18227
18295
|
"prebuilds",
|
|
18228
18296
|
`${process.platform}-${process.arch}`,
|
|
@@ -18465,8 +18533,8 @@ import { dirname as dirname26 } from "path";
|
|
|
18465
18533
|
var DEBOUNCE_MS = 50;
|
|
18466
18534
|
function watchActivity(session, notify2) {
|
|
18467
18535
|
if (session.commandType !== "assist" || !session.cwd) return;
|
|
18468
|
-
const
|
|
18469
|
-
const dir = dirname26(
|
|
18536
|
+
const path56 = activityPath(session.id);
|
|
18537
|
+
const dir = dirname26(path56);
|
|
18470
18538
|
try {
|
|
18471
18539
|
mkdirSync22(dir, { recursive: true });
|
|
18472
18540
|
} catch {
|
|
@@ -18475,7 +18543,7 @@ function watchActivity(session, notify2) {
|
|
|
18475
18543
|
let timer = null;
|
|
18476
18544
|
const read = () => {
|
|
18477
18545
|
timer = null;
|
|
18478
|
-
const activity2 = readActivity(
|
|
18546
|
+
const activity2 = readActivity(path56);
|
|
18479
18547
|
if (!activity2) return;
|
|
18480
18548
|
session.activity = activity2;
|
|
18481
18549
|
if (activity2.claudeSessionId)
|
|
@@ -18483,11 +18551,11 @@ function watchActivity(session, notify2) {
|
|
|
18483
18551
|
notify2();
|
|
18484
18552
|
};
|
|
18485
18553
|
session.activityWatcher = watch(dir, (_event, filename) => {
|
|
18486
|
-
if (filename && !
|
|
18554
|
+
if (filename && !path56.endsWith(filename)) return;
|
|
18487
18555
|
if (timer) clearTimeout(timer);
|
|
18488
18556
|
timer = setTimeout(read, DEBOUNCE_MS);
|
|
18489
18557
|
});
|
|
18490
|
-
if (existsSync52(
|
|
18558
|
+
if (existsSync52(path56)) read();
|
|
18491
18559
|
}
|
|
18492
18560
|
function refreshActivity(session) {
|
|
18493
18561
|
if (session.commandType !== "assist" || !session.cwd) return;
|
|
@@ -19007,17 +19075,17 @@ var WindowsProxy = class {
|
|
|
19007
19075
|
};
|
|
19008
19076
|
|
|
19009
19077
|
// src/commands/sessions/daemon/watchClaudeSessionId.ts
|
|
19010
|
-
import * as
|
|
19011
|
-
import * as
|
|
19078
|
+
import * as fs29 from "fs";
|
|
19079
|
+
import * as path50 from "path";
|
|
19012
19080
|
|
|
19013
19081
|
// src/commands/sessions/shared/discoverSessions.ts
|
|
19014
|
-
import * as
|
|
19082
|
+
import * as fs28 from "fs";
|
|
19015
19083
|
import * as os from "os";
|
|
19016
|
-
import * as
|
|
19084
|
+
import * as path49 from "path";
|
|
19017
19085
|
|
|
19018
19086
|
// src/commands/sessions/shared/parseSessionFile.ts
|
|
19019
|
-
import * as
|
|
19020
|
-
import * as
|
|
19087
|
+
import * as fs27 from "fs";
|
|
19088
|
+
import * as path48 from "path";
|
|
19021
19089
|
|
|
19022
19090
|
// src/commands/sessions/shared/deriveHistoryFields.ts
|
|
19023
19091
|
var KNOWN = ["draft", "next", "bug", "refine", "run"];
|
|
@@ -19106,10 +19174,10 @@ function matchMarker(text3, tag) {
|
|
|
19106
19174
|
async function parseSessionFile(filePath, origin = "wsl") {
|
|
19107
19175
|
let handle;
|
|
19108
19176
|
try {
|
|
19109
|
-
handle = await
|
|
19177
|
+
handle = await fs27.promises.open(filePath, "r");
|
|
19110
19178
|
const meta = extractSessionMeta(await readHeadLines(handle));
|
|
19111
19179
|
if (!meta.sessionId) return null;
|
|
19112
|
-
const timestamp = meta.timestamp || (await
|
|
19180
|
+
const timestamp = meta.timestamp || (await fs27.promises.stat(filePath)).mtime.toISOString();
|
|
19113
19181
|
return {
|
|
19114
19182
|
sessionId: meta.sessionId,
|
|
19115
19183
|
name: meta.name || `Session ${meta.sessionId.slice(0, 8)}`,
|
|
@@ -19132,10 +19200,10 @@ async function readHeadLines(handle) {
|
|
|
19132
19200
|
}
|
|
19133
19201
|
function deriveProject(cwd, filePath, origin) {
|
|
19134
19202
|
if (!cwd) return dirNameToProject(filePath);
|
|
19135
|
-
return origin === "windows" ?
|
|
19203
|
+
return origin === "windows" ? path48.win32.basename(cwd) : path48.basename(cwd);
|
|
19136
19204
|
}
|
|
19137
19205
|
function dirNameToProject(filePath) {
|
|
19138
|
-
const dirName =
|
|
19206
|
+
const dirName = path48.basename(path48.dirname(filePath));
|
|
19139
19207
|
const parts = dirName.split("--");
|
|
19140
19208
|
return parts[parts.length - 1].replace(/-/g, "/");
|
|
19141
19209
|
}
|
|
@@ -19143,7 +19211,7 @@ function dirNameToProject(filePath) {
|
|
|
19143
19211
|
// src/commands/sessions/shared/discoverSessions.ts
|
|
19144
19212
|
function sessionRoots() {
|
|
19145
19213
|
const roots = [
|
|
19146
|
-
{ dir:
|
|
19214
|
+
{ dir: path49.join(os.homedir(), ".claude", "projects"), origin: "wsl" }
|
|
19147
19215
|
];
|
|
19148
19216
|
const windowsRoot = loadConfig().sessions?.windowsProjectsRoot;
|
|
19149
19217
|
if (windowsRoot) roots.push({ dir: windowsRoot, origin: "windows" });
|
|
@@ -19155,22 +19223,22 @@ async function discoverSessionJsonlPaths() {
|
|
|
19155
19223
|
sessionRoots().map(async ({ dir, origin }) => {
|
|
19156
19224
|
let projectDirs;
|
|
19157
19225
|
try {
|
|
19158
|
-
projectDirs = await
|
|
19226
|
+
projectDirs = await fs28.promises.readdir(dir);
|
|
19159
19227
|
} catch {
|
|
19160
19228
|
return;
|
|
19161
19229
|
}
|
|
19162
19230
|
await Promise.all(
|
|
19163
19231
|
projectDirs.map(async (dirName) => {
|
|
19164
|
-
const dirPath =
|
|
19232
|
+
const dirPath = path49.join(dir, dirName);
|
|
19165
19233
|
let entries;
|
|
19166
19234
|
try {
|
|
19167
|
-
entries = await
|
|
19235
|
+
entries = await fs28.promises.readdir(dirPath);
|
|
19168
19236
|
} catch {
|
|
19169
19237
|
return;
|
|
19170
19238
|
}
|
|
19171
19239
|
for (const file of entries) {
|
|
19172
19240
|
if (file.endsWith(".jsonl"))
|
|
19173
|
-
results.push({ path:
|
|
19241
|
+
results.push({ path: path49.join(dirPath, file), origin });
|
|
19174
19242
|
}
|
|
19175
19243
|
})
|
|
19176
19244
|
);
|
|
@@ -19217,7 +19285,7 @@ async function findLatestSessionId(options2) {
|
|
|
19217
19285
|
if (createdMs === null) continue;
|
|
19218
19286
|
const meta = await parseSessionFile(filePath, origin);
|
|
19219
19287
|
if (!meta?.cwd || options2.isClaimed(meta.sessionId)) continue;
|
|
19220
|
-
if (
|
|
19288
|
+
if (path50.resolve(meta.cwd) !== path50.resolve(options2.cwd)) continue;
|
|
19221
19289
|
if (!latest || createdMs > latest.createdMs)
|
|
19222
19290
|
latest = { sessionId: meta.sessionId, createdMs };
|
|
19223
19291
|
}
|
|
@@ -19225,7 +19293,7 @@ async function findLatestSessionId(options2) {
|
|
|
19225
19293
|
}
|
|
19226
19294
|
async function createdSince(filePath, sinceMs) {
|
|
19227
19295
|
try {
|
|
19228
|
-
const stat = await
|
|
19296
|
+
const stat = await fs29.promises.stat(filePath);
|
|
19229
19297
|
const createdMs = stat.birthtimeMs || stat.mtimeMs;
|
|
19230
19298
|
return createdMs >= sinceMs ? createdMs : null;
|
|
19231
19299
|
} catch {
|
|
@@ -19403,7 +19471,7 @@ import * as net3 from "net";
|
|
|
19403
19471
|
import { createInterface as createInterface7 } from "readline";
|
|
19404
19472
|
|
|
19405
19473
|
// src/commands/sessions/shared/parseTranscript.ts
|
|
19406
|
-
import * as
|
|
19474
|
+
import * as fs30 from "fs";
|
|
19407
19475
|
|
|
19408
19476
|
// src/commands/sessions/shared/toolTarget.ts
|
|
19409
19477
|
function toolTarget(input) {
|
|
@@ -19451,11 +19519,11 @@ function cleanUserText(value) {
|
|
|
19451
19519
|
}
|
|
19452
19520
|
|
|
19453
19521
|
// src/commands/sessions/shared/findSessionJsonlPath.ts
|
|
19454
|
-
import * as
|
|
19522
|
+
import * as path51 from "path";
|
|
19455
19523
|
async function findSessionJsonlPath(sessionId) {
|
|
19456
19524
|
const paths = await discoverSessionJsonlPaths();
|
|
19457
19525
|
const direct = paths.find(
|
|
19458
|
-
(p) =>
|
|
19526
|
+
(p) => path51.basename(p.path, ".jsonl") === sessionId
|
|
19459
19527
|
);
|
|
19460
19528
|
if (direct) return direct.path;
|
|
19461
19529
|
for (const p of paths) {
|
|
@@ -19470,7 +19538,7 @@ async function parseTranscript(sessionId) {
|
|
|
19470
19538
|
const filePath = await findSessionJsonlPath(sessionId);
|
|
19471
19539
|
if (!filePath) return [];
|
|
19472
19540
|
try {
|
|
19473
|
-
const raw = await
|
|
19541
|
+
const raw = await fs30.promises.readFile(filePath, "utf8");
|
|
19474
19542
|
return parseTranscriptLines(raw.split("\n"));
|
|
19475
19543
|
} catch {
|
|
19476
19544
|
return [];
|
|
@@ -19732,17 +19800,17 @@ function registerDaemon(program2) {
|
|
|
19732
19800
|
}
|
|
19733
19801
|
|
|
19734
19802
|
// src/commands/sessions/summarise/index.ts
|
|
19735
|
-
import * as
|
|
19736
|
-
import
|
|
19803
|
+
import * as fs33 from "fs";
|
|
19804
|
+
import chalk163 from "chalk";
|
|
19737
19805
|
|
|
19738
19806
|
// src/commands/sessions/summarise/shared.ts
|
|
19739
|
-
import * as
|
|
19807
|
+
import * as fs31 from "fs";
|
|
19740
19808
|
function writeSummary(jsonlPath2, summary) {
|
|
19741
|
-
|
|
19809
|
+
fs31.writeFileSync(summaryPathFor(jsonlPath2), `${summary.trim()}
|
|
19742
19810
|
`, "utf8");
|
|
19743
19811
|
}
|
|
19744
19812
|
function hasSummary(jsonlPath2) {
|
|
19745
|
-
return
|
|
19813
|
+
return fs31.existsSync(summaryPathFor(jsonlPath2));
|
|
19746
19814
|
}
|
|
19747
19815
|
function summaryPathFor(jsonlPath2) {
|
|
19748
19816
|
return jsonlPath2.replace(/\.jsonl$/, ".summary");
|
|
@@ -19752,17 +19820,17 @@ function summaryPathFor(jsonlPath2) {
|
|
|
19752
19820
|
import { execFileSync as execFileSync11 } from "child_process";
|
|
19753
19821
|
|
|
19754
19822
|
// src/commands/sessions/summarise/iterateUserMessages.ts
|
|
19755
|
-
import * as
|
|
19823
|
+
import * as fs32 from "fs";
|
|
19756
19824
|
function* iterateUserMessages(filePath, maxBytes = 65536) {
|
|
19757
19825
|
let content;
|
|
19758
19826
|
try {
|
|
19759
|
-
const fd =
|
|
19827
|
+
const fd = fs32.openSync(filePath, "r");
|
|
19760
19828
|
try {
|
|
19761
19829
|
const buf = Buffer.alloc(maxBytes);
|
|
19762
|
-
const bytesRead =
|
|
19830
|
+
const bytesRead = fs32.readSync(fd, buf, 0, buf.length, 0);
|
|
19763
19831
|
content = buf.toString("utf8", 0, bytesRead);
|
|
19764
19832
|
} finally {
|
|
19765
|
-
|
|
19833
|
+
fs32.closeSync(fd);
|
|
19766
19834
|
}
|
|
19767
19835
|
} catch {
|
|
19768
19836
|
return;
|
|
@@ -19860,29 +19928,29 @@ ${firstMessage}`);
|
|
|
19860
19928
|
async function summarise4(options2) {
|
|
19861
19929
|
const files = await discoverSessionFiles();
|
|
19862
19930
|
if (files.length === 0) {
|
|
19863
|
-
console.log(
|
|
19931
|
+
console.log(chalk163.yellow("No sessions found."));
|
|
19864
19932
|
return;
|
|
19865
19933
|
}
|
|
19866
19934
|
const toProcess = selectCandidates(files, options2);
|
|
19867
19935
|
if (toProcess.length === 0) {
|
|
19868
|
-
console.log(
|
|
19936
|
+
console.log(chalk163.green("All sessions already summarised."));
|
|
19869
19937
|
return;
|
|
19870
19938
|
}
|
|
19871
19939
|
console.log(
|
|
19872
|
-
|
|
19940
|
+
chalk163.cyan(
|
|
19873
19941
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
19874
19942
|
)
|
|
19875
19943
|
);
|
|
19876
19944
|
const { succeeded, failed: failed2 } = processSessions(toProcess);
|
|
19877
19945
|
console.log(
|
|
19878
|
-
|
|
19946
|
+
chalk163.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk163.yellow(`, ${failed2} skipped`) : "")
|
|
19879
19947
|
);
|
|
19880
19948
|
}
|
|
19881
19949
|
function selectCandidates(files, options2) {
|
|
19882
19950
|
const candidates = options2.force ? files : files.filter((f) => !hasSummary(f));
|
|
19883
19951
|
candidates.sort((a, b) => {
|
|
19884
19952
|
try {
|
|
19885
|
-
return
|
|
19953
|
+
return fs33.statSync(b).mtimeMs - fs33.statSync(a).mtimeMs;
|
|
19886
19954
|
} catch {
|
|
19887
19955
|
return 0;
|
|
19888
19956
|
}
|
|
@@ -19895,16 +19963,16 @@ function processSessions(files) {
|
|
|
19895
19963
|
let failed2 = 0;
|
|
19896
19964
|
for (let i = 0; i < files.length; i++) {
|
|
19897
19965
|
const file = files[i];
|
|
19898
|
-
process.stdout.write(
|
|
19966
|
+
process.stdout.write(chalk163.dim(` [${i + 1}/${files.length}] `));
|
|
19899
19967
|
const summary = summariseSession(file);
|
|
19900
19968
|
if (summary) {
|
|
19901
19969
|
writeSummary(file, summary);
|
|
19902
19970
|
succeeded++;
|
|
19903
|
-
process.stdout.write(`${
|
|
19971
|
+
process.stdout.write(`${chalk163.green("\u2713")} ${summary}
|
|
19904
19972
|
`);
|
|
19905
19973
|
} else {
|
|
19906
19974
|
failed2++;
|
|
19907
|
-
process.stdout.write(` ${
|
|
19975
|
+
process.stdout.write(` ${chalk163.yellow("skip")}
|
|
19908
19976
|
`);
|
|
19909
19977
|
}
|
|
19910
19978
|
}
|
|
@@ -19919,10 +19987,10 @@ function registerSessions(program2) {
|
|
|
19919
19987
|
}
|
|
19920
19988
|
|
|
19921
19989
|
// src/commands/statusLine.ts
|
|
19922
|
-
import
|
|
19990
|
+
import chalk165 from "chalk";
|
|
19923
19991
|
|
|
19924
19992
|
// src/commands/buildLimitsSegment.ts
|
|
19925
|
-
import
|
|
19993
|
+
import chalk164 from "chalk";
|
|
19926
19994
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
19927
19995
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
19928
19996
|
function formatTimeLeft(resetsAt) {
|
|
@@ -19945,10 +20013,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
19945
20013
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
19946
20014
|
const label2 = `${Math.round(pct)}%`;
|
|
19947
20015
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
19948
|
-
if (projected == null) return
|
|
19949
|
-
if (projected > 100) return
|
|
19950
|
-
if (projected > 75) return
|
|
19951
|
-
return
|
|
20016
|
+
if (projected == null) return chalk164.green(label2);
|
|
20017
|
+
if (projected > 100) return chalk164.red(label2);
|
|
20018
|
+
if (projected > 75) return chalk164.yellow(label2);
|
|
20019
|
+
return chalk164.green(label2);
|
|
19952
20020
|
}
|
|
19953
20021
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
19954
20022
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -19974,14 +20042,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
19974
20042
|
}
|
|
19975
20043
|
|
|
19976
20044
|
// src/commands/statusLine.ts
|
|
19977
|
-
|
|
20045
|
+
chalk165.level = 3;
|
|
19978
20046
|
function formatNumber(num) {
|
|
19979
20047
|
return num.toLocaleString("en-US");
|
|
19980
20048
|
}
|
|
19981
20049
|
function colorizePercent(pct) {
|
|
19982
20050
|
const label2 = `${Math.round(pct)}%`;
|
|
19983
|
-
if (pct > 80) return
|
|
19984
|
-
if (pct > 40) return
|
|
20051
|
+
if (pct > 80) return chalk165.red(label2);
|
|
20052
|
+
if (pct > 40) return chalk165.yellow(label2);
|
|
19985
20053
|
return label2;
|
|
19986
20054
|
}
|
|
19987
20055
|
async function statusLine() {
|
|
@@ -19996,29 +20064,29 @@ async function statusLine() {
|
|
|
19996
20064
|
}
|
|
19997
20065
|
|
|
19998
20066
|
// src/commands/sync.ts
|
|
19999
|
-
import * as
|
|
20067
|
+
import * as fs36 from "fs";
|
|
20000
20068
|
import * as os2 from "os";
|
|
20001
|
-
import * as
|
|
20069
|
+
import * as path54 from "path";
|
|
20002
20070
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
20003
20071
|
|
|
20004
20072
|
// src/commands/sync/syncClaudeMd.ts
|
|
20005
|
-
import * as
|
|
20006
|
-
import * as
|
|
20007
|
-
import
|
|
20073
|
+
import * as fs34 from "fs";
|
|
20074
|
+
import * as path52 from "path";
|
|
20075
|
+
import chalk166 from "chalk";
|
|
20008
20076
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
20009
|
-
const source =
|
|
20010
|
-
const target =
|
|
20011
|
-
const sourceContent =
|
|
20012
|
-
if (
|
|
20013
|
-
const targetContent =
|
|
20077
|
+
const source = path52.join(claudeDir, "CLAUDE.md");
|
|
20078
|
+
const target = path52.join(targetBase, "CLAUDE.md");
|
|
20079
|
+
const sourceContent = fs34.readFileSync(source, "utf-8");
|
|
20080
|
+
if (fs34.existsSync(target)) {
|
|
20081
|
+
const targetContent = fs34.readFileSync(target, "utf-8");
|
|
20014
20082
|
if (sourceContent !== targetContent) {
|
|
20015
20083
|
console.log(
|
|
20016
|
-
|
|
20084
|
+
chalk166.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
20017
20085
|
);
|
|
20018
20086
|
console.log();
|
|
20019
20087
|
printDiff(targetContent, sourceContent);
|
|
20020
20088
|
const confirm = options2?.yes || await promptConfirm(
|
|
20021
|
-
|
|
20089
|
+
chalk166.red("Overwrite existing CLAUDE.md?"),
|
|
20022
20090
|
false
|
|
20023
20091
|
);
|
|
20024
20092
|
if (!confirm) {
|
|
@@ -20027,21 +20095,21 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
20027
20095
|
}
|
|
20028
20096
|
}
|
|
20029
20097
|
}
|
|
20030
|
-
|
|
20098
|
+
fs34.copyFileSync(source, target);
|
|
20031
20099
|
console.log("Copied CLAUDE.md to ~/.claude/CLAUDE.md");
|
|
20032
20100
|
}
|
|
20033
20101
|
|
|
20034
20102
|
// src/commands/sync/syncSettings.ts
|
|
20035
|
-
import * as
|
|
20036
|
-
import * as
|
|
20037
|
-
import
|
|
20103
|
+
import * as fs35 from "fs";
|
|
20104
|
+
import * as path53 from "path";
|
|
20105
|
+
import chalk167 from "chalk";
|
|
20038
20106
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
20039
|
-
const source =
|
|
20040
|
-
const target =
|
|
20041
|
-
const sourceContent =
|
|
20107
|
+
const source = path53.join(claudeDir, "settings.json");
|
|
20108
|
+
const target = path53.join(targetBase, "settings.json");
|
|
20109
|
+
const sourceContent = fs35.readFileSync(source, "utf-8");
|
|
20042
20110
|
const mergedContent = JSON.stringify(JSON.parse(sourceContent), null, " ");
|
|
20043
|
-
if (
|
|
20044
|
-
const targetContent =
|
|
20111
|
+
if (fs35.existsSync(target)) {
|
|
20112
|
+
const targetContent = fs35.readFileSync(target, "utf-8");
|
|
20045
20113
|
const normalizedTarget = JSON.stringify(
|
|
20046
20114
|
JSON.parse(targetContent),
|
|
20047
20115
|
null,
|
|
@@ -20050,14 +20118,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
20050
20118
|
if (mergedContent !== normalizedTarget) {
|
|
20051
20119
|
if (!options2?.yes) {
|
|
20052
20120
|
console.log(
|
|
20053
|
-
|
|
20121
|
+
chalk167.yellow(
|
|
20054
20122
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
20055
20123
|
)
|
|
20056
20124
|
);
|
|
20057
20125
|
console.log();
|
|
20058
20126
|
printDiff(targetContent, mergedContent);
|
|
20059
20127
|
const confirm = await promptConfirm(
|
|
20060
|
-
|
|
20128
|
+
chalk167.red("Overwrite existing settings.json?"),
|
|
20061
20129
|
false
|
|
20062
20130
|
);
|
|
20063
20131
|
if (!confirm) {
|
|
@@ -20067,29 +20135,29 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
20067
20135
|
}
|
|
20068
20136
|
}
|
|
20069
20137
|
}
|
|
20070
|
-
|
|
20138
|
+
fs35.writeFileSync(target, mergedContent);
|
|
20071
20139
|
console.log("Copied settings.json to ~/.claude/settings.json");
|
|
20072
20140
|
}
|
|
20073
20141
|
|
|
20074
20142
|
// src/commands/sync.ts
|
|
20075
20143
|
var __filename4 = fileURLToPath7(import.meta.url);
|
|
20076
|
-
var __dirname7 =
|
|
20144
|
+
var __dirname7 = path54.dirname(__filename4);
|
|
20077
20145
|
async function sync(options2) {
|
|
20078
20146
|
const config = loadConfig();
|
|
20079
20147
|
const yes = options2?.yes ?? config.sync.autoConfirm;
|
|
20080
|
-
const claudeDir =
|
|
20081
|
-
const targetBase =
|
|
20148
|
+
const claudeDir = path54.join(__dirname7, "..", "claude");
|
|
20149
|
+
const targetBase = path54.join(os2.homedir(), ".claude");
|
|
20082
20150
|
syncCommands(claudeDir, targetBase);
|
|
20083
20151
|
await syncSettings(claudeDir, targetBase, { yes });
|
|
20084
20152
|
await syncClaudeMd(claudeDir, targetBase, { yes });
|
|
20085
20153
|
}
|
|
20086
20154
|
function syncCommands(claudeDir, targetBase) {
|
|
20087
|
-
const sourceDir =
|
|
20088
|
-
const targetDir =
|
|
20089
|
-
|
|
20090
|
-
const files =
|
|
20155
|
+
const sourceDir = path54.join(claudeDir, "commands");
|
|
20156
|
+
const targetDir = path54.join(targetBase, "commands");
|
|
20157
|
+
fs36.mkdirSync(targetDir, { recursive: true });
|
|
20158
|
+
const files = fs36.readdirSync(sourceDir);
|
|
20091
20159
|
for (const file of files) {
|
|
20092
|
-
|
|
20160
|
+
fs36.copyFileSync(path54.join(sourceDir, file), path54.join(targetDir, file));
|
|
20093
20161
|
console.log(`Copied ${file} to ${targetDir}`);
|
|
20094
20162
|
}
|
|
20095
20163
|
console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
|
|
@@ -20097,15 +20165,15 @@ function syncCommands(claudeDir, targetBase) {
|
|
|
20097
20165
|
|
|
20098
20166
|
// src/commands/update.ts
|
|
20099
20167
|
import { execSync as execSync49 } from "child_process";
|
|
20100
|
-
import * as
|
|
20168
|
+
import * as path55 from "path";
|
|
20101
20169
|
function isGlobalNpmInstall(dir) {
|
|
20102
20170
|
try {
|
|
20103
|
-
const resolved =
|
|
20104
|
-
if (resolved.split(
|
|
20171
|
+
const resolved = path55.resolve(dir);
|
|
20172
|
+
if (resolved.split(path55.sep).includes("node_modules")) {
|
|
20105
20173
|
return true;
|
|
20106
20174
|
}
|
|
20107
20175
|
const globalPrefix = execSync49("npm prefix -g", { stdio: "pipe" }).toString().trim();
|
|
20108
|
-
return resolved.toLowerCase().startsWith(
|
|
20176
|
+
return resolved.toLowerCase().startsWith(path55.resolve(globalPrefix).toLowerCase());
|
|
20109
20177
|
} catch {
|
|
20110
20178
|
return false;
|
|
20111
20179
|
}
|