@staff0rd/assist 0.288.1 → 0.289.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/commands/sessions/web/bundle.js +66 -66
- package/dist/index.js +626 -535
- 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.
|
|
9
|
+
version: "0.289.0",
|
|
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
|
}
|
|
@@ -5215,6 +5215,101 @@ async function openInCode(req, res) {
|
|
|
5215
5215
|
}
|
|
5216
5216
|
}
|
|
5217
5217
|
|
|
5218
|
+
// src/commands/sessions/daemon/stopDaemon.ts
|
|
5219
|
+
var STOP_TIMEOUT_MS = 5e3;
|
|
5220
|
+
async function stopDaemon() {
|
|
5221
|
+
let socket;
|
|
5222
|
+
try {
|
|
5223
|
+
socket = await connectToDaemon();
|
|
5224
|
+
} catch {
|
|
5225
|
+
console.log("Sessions daemon is not running");
|
|
5226
|
+
return;
|
|
5227
|
+
}
|
|
5228
|
+
socket.write(`${JSON.stringify({ type: "shutdown" })}
|
|
5229
|
+
`);
|
|
5230
|
+
if (await closedBeforeTimeout(socket)) {
|
|
5231
|
+
console.log("Sessions daemon stopped");
|
|
5232
|
+
} else {
|
|
5233
|
+
console.error(
|
|
5234
|
+
`Sessions daemon did not stop within ${STOP_TIMEOUT_MS / 1e3}s`
|
|
5235
|
+
);
|
|
5236
|
+
process.exitCode = 1;
|
|
5237
|
+
}
|
|
5238
|
+
}
|
|
5239
|
+
function closedBeforeTimeout(socket) {
|
|
5240
|
+
return new Promise((resolve16) => {
|
|
5241
|
+
const timer = setTimeout(() => {
|
|
5242
|
+
socket.destroy();
|
|
5243
|
+
resolve16(false);
|
|
5244
|
+
}, STOP_TIMEOUT_MS);
|
|
5245
|
+
socket.resume();
|
|
5246
|
+
socket.on("error", () => {
|
|
5247
|
+
});
|
|
5248
|
+
socket.once("close", () => {
|
|
5249
|
+
clearTimeout(timer);
|
|
5250
|
+
resolve16(true);
|
|
5251
|
+
});
|
|
5252
|
+
});
|
|
5253
|
+
}
|
|
5254
|
+
|
|
5255
|
+
// src/commands/sessions/daemon/restartDaemon.ts
|
|
5256
|
+
async function restartDaemon() {
|
|
5257
|
+
await stopDaemon();
|
|
5258
|
+
await ensureDaemonRunning("daemon restart");
|
|
5259
|
+
console.log(
|
|
5260
|
+
"Sessions daemon restarted; previously running claude sessions will resume"
|
|
5261
|
+
);
|
|
5262
|
+
}
|
|
5263
|
+
|
|
5264
|
+
// src/commands/sessions/web/restartMenu/reExecWebServer.ts
|
|
5265
|
+
import { spawnSync } from "child_process";
|
|
5266
|
+
function resolveExecve() {
|
|
5267
|
+
return typeof process.execve === "function" ? process.execve.bind(process) : null;
|
|
5268
|
+
}
|
|
5269
|
+
function withNoOpen(args) {
|
|
5270
|
+
return args.includes("--no-open") ? args : [...args, "--no-open"];
|
|
5271
|
+
}
|
|
5272
|
+
function reExecWebServer(deps2 = {}) {
|
|
5273
|
+
const {
|
|
5274
|
+
beforeExec,
|
|
5275
|
+
execveFn = resolveExecve(),
|
|
5276
|
+
spawnSyncFn = spawnSync,
|
|
5277
|
+
exit = (code) => process.exit(code)
|
|
5278
|
+
} = deps2;
|
|
5279
|
+
beforeExec?.();
|
|
5280
|
+
if (execveFn) {
|
|
5281
|
+
execveFn(process.execPath, withNoOpen(process.argv), process.env);
|
|
5282
|
+
return;
|
|
5283
|
+
}
|
|
5284
|
+
const [, ...args] = process.argv;
|
|
5285
|
+
const result = spawnSyncFn(process.execPath, withNoOpen(args), {
|
|
5286
|
+
stdio: "inherit"
|
|
5287
|
+
});
|
|
5288
|
+
exit(result.status ?? 0);
|
|
5289
|
+
}
|
|
5290
|
+
|
|
5291
|
+
// src/commands/sessions/web/restartWeb.ts
|
|
5292
|
+
var TARGETS = ["daemon", "webserver", "both"];
|
|
5293
|
+
async function restartWeb(req, res, deps2 = {}) {
|
|
5294
|
+
const { restartDaemonFn = restartDaemon, reExecFn = reExecWebServer } = deps2;
|
|
5295
|
+
const url = new URL(req.url ?? "/", "http://localhost");
|
|
5296
|
+
const target = url.searchParams.get("target");
|
|
5297
|
+
if (!target || !TARGETS.includes(target)) {
|
|
5298
|
+
respondJson(res, 400, { error: "Invalid target" });
|
|
5299
|
+
return;
|
|
5300
|
+
}
|
|
5301
|
+
await new Promise((resolve16) => {
|
|
5302
|
+
res.once("finish", resolve16);
|
|
5303
|
+
respondJson(res, 200, { ok: true });
|
|
5304
|
+
});
|
|
5305
|
+
if (target === "daemon" || target === "both") {
|
|
5306
|
+
await restartDaemonFn();
|
|
5307
|
+
}
|
|
5308
|
+
if (target === "webserver" || target === "both") {
|
|
5309
|
+
reExecFn();
|
|
5310
|
+
}
|
|
5311
|
+
}
|
|
5312
|
+
|
|
5218
5313
|
// src/commands/sessions/web/handleRequest.ts
|
|
5219
5314
|
var require3 = createRequire2(import.meta.url);
|
|
5220
5315
|
function createCssHandler(packageEntry) {
|
|
@@ -5241,6 +5336,7 @@ var routes = {
|
|
|
5241
5336
|
"GET /api/backlog/exists": getBacklogExists,
|
|
5242
5337
|
"POST /api/backlog/init": initBacklog,
|
|
5243
5338
|
"POST /api/open-in-code": openInCode,
|
|
5339
|
+
"POST /api/restart": restartWeb,
|
|
5244
5340
|
"GET /api/github-url": githubUrl,
|
|
5245
5341
|
"GET /api/git-status": gitStatus,
|
|
5246
5342
|
"GET /api/news/items": listNewsItems
|
|
@@ -5560,52 +5656,6 @@ function enableRawMode(stdin, onData) {
|
|
|
5560
5656
|
};
|
|
5561
5657
|
}
|
|
5562
5658
|
|
|
5563
|
-
// src/commands/sessions/daemon/stopDaemon.ts
|
|
5564
|
-
var STOP_TIMEOUT_MS = 5e3;
|
|
5565
|
-
async function stopDaemon() {
|
|
5566
|
-
let socket;
|
|
5567
|
-
try {
|
|
5568
|
-
socket = await connectToDaemon();
|
|
5569
|
-
} catch {
|
|
5570
|
-
console.log("Sessions daemon is not running");
|
|
5571
|
-
return;
|
|
5572
|
-
}
|
|
5573
|
-
socket.write(`${JSON.stringify({ type: "shutdown" })}
|
|
5574
|
-
`);
|
|
5575
|
-
if (await closedBeforeTimeout(socket)) {
|
|
5576
|
-
console.log("Sessions daemon stopped");
|
|
5577
|
-
} else {
|
|
5578
|
-
console.error(
|
|
5579
|
-
`Sessions daemon did not stop within ${STOP_TIMEOUT_MS / 1e3}s`
|
|
5580
|
-
);
|
|
5581
|
-
process.exitCode = 1;
|
|
5582
|
-
}
|
|
5583
|
-
}
|
|
5584
|
-
function closedBeforeTimeout(socket) {
|
|
5585
|
-
return new Promise((resolve16) => {
|
|
5586
|
-
const timer = setTimeout(() => {
|
|
5587
|
-
socket.destroy();
|
|
5588
|
-
resolve16(false);
|
|
5589
|
-
}, STOP_TIMEOUT_MS);
|
|
5590
|
-
socket.resume();
|
|
5591
|
-
socket.on("error", () => {
|
|
5592
|
-
});
|
|
5593
|
-
socket.once("close", () => {
|
|
5594
|
-
clearTimeout(timer);
|
|
5595
|
-
resolve16(true);
|
|
5596
|
-
});
|
|
5597
|
-
});
|
|
5598
|
-
}
|
|
5599
|
-
|
|
5600
|
-
// src/commands/sessions/daemon/restartDaemon.ts
|
|
5601
|
-
async function restartDaemon() {
|
|
5602
|
-
await stopDaemon();
|
|
5603
|
-
await ensureDaemonRunning("daemon restart");
|
|
5604
|
-
console.log(
|
|
5605
|
-
"Sessions daemon restarted; previously running claude sessions will resume"
|
|
5606
|
-
);
|
|
5607
|
-
}
|
|
5608
|
-
|
|
5609
5659
|
// src/commands/sessions/web/restartMenu/menuItems.ts
|
|
5610
5660
|
var menuItems = [
|
|
5611
5661
|
{ label: "Restart daemon", action: "restart-daemon" },
|
|
@@ -5613,33 +5663,6 @@ var menuItems = [
|
|
|
5613
5663
|
{ label: "Restart both", action: "restart-both" }
|
|
5614
5664
|
];
|
|
5615
5665
|
|
|
5616
|
-
// src/commands/sessions/web/restartMenu/reExecWebServer.ts
|
|
5617
|
-
import { spawnSync } from "child_process";
|
|
5618
|
-
function resolveExecve() {
|
|
5619
|
-
return typeof process.execve === "function" ? process.execve.bind(process) : null;
|
|
5620
|
-
}
|
|
5621
|
-
function withNoOpen(args) {
|
|
5622
|
-
return args.includes("--no-open") ? args : [...args, "--no-open"];
|
|
5623
|
-
}
|
|
5624
|
-
function reExecWebServer(deps2 = {}) {
|
|
5625
|
-
const {
|
|
5626
|
-
beforeExec,
|
|
5627
|
-
execveFn = resolveExecve(),
|
|
5628
|
-
spawnSyncFn = spawnSync,
|
|
5629
|
-
exit = (code) => process.exit(code)
|
|
5630
|
-
} = deps2;
|
|
5631
|
-
beforeExec?.();
|
|
5632
|
-
if (execveFn) {
|
|
5633
|
-
execveFn(process.execPath, withNoOpen(process.argv), process.env);
|
|
5634
|
-
return;
|
|
5635
|
-
}
|
|
5636
|
-
const [, ...args] = process.argv;
|
|
5637
|
-
const result = spawnSyncFn(process.execPath, withNoOpen(args), {
|
|
5638
|
-
stdio: "inherit"
|
|
5639
|
-
});
|
|
5640
|
-
exit(result.status ?? 0);
|
|
5641
|
-
}
|
|
5642
|
-
|
|
5643
5666
|
// src/commands/sessions/web/restartMenu/resolveOptions.ts
|
|
5644
5667
|
var CTRL_R = String.fromCharCode(18);
|
|
5645
5668
|
function resolveOptions(options2) {
|
|
@@ -6254,8 +6277,8 @@ import chalk57 from "chalk";
|
|
|
6254
6277
|
// src/commands/backlog/originDisplayName.ts
|
|
6255
6278
|
function originDisplayName(origin) {
|
|
6256
6279
|
if (origin.startsWith("local:")) {
|
|
6257
|
-
const
|
|
6258
|
-
const segments =
|
|
6280
|
+
const path56 = origin.slice("local:".length).replace(/\/+$/, "");
|
|
6281
|
+
const segments = path56.split("/").filter(Boolean);
|
|
6259
6282
|
return segments[segments.length - 1] ?? origin;
|
|
6260
6283
|
}
|
|
6261
6284
|
const firstSlash = origin.indexOf("/");
|
|
@@ -7558,9 +7581,9 @@ var __dirname5 = dirname17(__filename3);
|
|
|
7558
7581
|
function packageRoot() {
|
|
7559
7582
|
return __dirname5;
|
|
7560
7583
|
}
|
|
7561
|
-
function readLines(
|
|
7562
|
-
if (!existsSync22(
|
|
7563
|
-
return readFileSync16(
|
|
7584
|
+
function readLines(path56) {
|
|
7585
|
+
if (!existsSync22(path56)) return [];
|
|
7586
|
+
return readFileSync16(path56, "utf-8").split("\n").filter((line) => line.trim() !== "");
|
|
7564
7587
|
}
|
|
7565
7588
|
var cachedReads;
|
|
7566
7589
|
var cachedWrites;
|
|
@@ -8025,14 +8048,14 @@ function showProgress(p, label2) {
|
|
|
8025
8048
|
const pct = Math.round(p.done / p.total * 100);
|
|
8026
8049
|
process.stderr.write(`\r\x1B[K[${pct}%] Scanning ${label2}...`);
|
|
8027
8050
|
}
|
|
8028
|
-
async function resolveCommand(cli,
|
|
8029
|
-
showProgress(p,
|
|
8030
|
-
const subHelp = await runHelp([cli, ...
|
|
8051
|
+
async function resolveCommand(cli, path56, description, depth, p) {
|
|
8052
|
+
showProgress(p, path56.join(" "));
|
|
8053
|
+
const subHelp = await runHelp([cli, ...path56]);
|
|
8031
8054
|
if (!subHelp || !hasSubcommands(subHelp)) {
|
|
8032
|
-
return [{ path:
|
|
8055
|
+
return [{ path: path56, description }];
|
|
8033
8056
|
}
|
|
8034
|
-
const children = await discoverAt(cli,
|
|
8035
|
-
return children.length > 0 ? children : [{ path:
|
|
8057
|
+
const children = await discoverAt(cli, path56, depth + 1, p);
|
|
8058
|
+
return children.length > 0 ? children : [{ path: path56, description }];
|
|
8036
8059
|
}
|
|
8037
8060
|
async function discoverAt(cli, parentPath, depth, p) {
|
|
8038
8061
|
if (depth > SAFETY_DEPTH) return [];
|
|
@@ -8180,9 +8203,9 @@ function logPath(cli) {
|
|
|
8180
8203
|
return join22(homedir9(), ".assist", `cli-discover-${safeName}.log`);
|
|
8181
8204
|
}
|
|
8182
8205
|
function readCache(cli) {
|
|
8183
|
-
const
|
|
8184
|
-
if (!existsSync24(
|
|
8185
|
-
return readFileSync18(
|
|
8206
|
+
const path56 = logPath(cli);
|
|
8207
|
+
if (!existsSync24(path56)) return void 0;
|
|
8208
|
+
return readFileSync18(path56, "utf-8");
|
|
8186
8209
|
}
|
|
8187
8210
|
function writeCache(cli, output) {
|
|
8188
8211
|
const dir = join22(homedir9(), ".assist");
|
|
@@ -8871,8 +8894,8 @@ function stepIntoNested(container, key, nextKey) {
|
|
|
8871
8894
|
}
|
|
8872
8895
|
return ensureObject(container, resolved);
|
|
8873
8896
|
}
|
|
8874
|
-
function setNestedValue(obj,
|
|
8875
|
-
const keys =
|
|
8897
|
+
function setNestedValue(obj, path56, value) {
|
|
8898
|
+
const keys = path56.split(".");
|
|
8876
8899
|
const result = { ...obj };
|
|
8877
8900
|
let current = result;
|
|
8878
8901
|
for (let i = 0; i < keys.length - 1; i++) {
|
|
@@ -8952,9 +8975,9 @@ function isTraversable(value) {
|
|
|
8952
8975
|
function stepInto(current, key) {
|
|
8953
8976
|
return isTraversable(current) ? current[key] : void 0;
|
|
8954
8977
|
}
|
|
8955
|
-
function getNestedValue(obj,
|
|
8978
|
+
function getNestedValue(obj, path56) {
|
|
8956
8979
|
let current = obj;
|
|
8957
|
-
for (const key of
|
|
8980
|
+
for (const key of path56.split(".")) current = stepInto(current, key);
|
|
8958
8981
|
return current;
|
|
8959
8982
|
}
|
|
8960
8983
|
|
|
@@ -10742,10 +10765,10 @@ function getStorePath(filename) {
|
|
|
10742
10765
|
return join32(getStoreDir(), filename);
|
|
10743
10766
|
}
|
|
10744
10767
|
function loadJson(filename) {
|
|
10745
|
-
const
|
|
10746
|
-
if (existsSync33(
|
|
10768
|
+
const path56 = getStorePath(filename);
|
|
10769
|
+
if (existsSync33(path56)) {
|
|
10747
10770
|
try {
|
|
10748
|
-
return JSON.parse(readFileSync27(
|
|
10771
|
+
return JSON.parse(readFileSync27(path56, "utf-8"));
|
|
10749
10772
|
} catch {
|
|
10750
10773
|
return {};
|
|
10751
10774
|
}
|
|
@@ -11203,15 +11226,15 @@ function postComment(vars) {
|
|
|
11203
11226
|
const stdout = startLine === void 0 ? runGhGraphql(MUTATION_SINGLE, base) : runGhGraphql(MUTATION_MULTI, { ...base, startLine });
|
|
11204
11227
|
assertThreadCreated(stdout);
|
|
11205
11228
|
}
|
|
11206
|
-
function comment2(
|
|
11229
|
+
function comment2(path56, line, body, startLine) {
|
|
11207
11230
|
validateBody(body);
|
|
11208
11231
|
validateLine(line);
|
|
11209
11232
|
if (startLine !== void 0) validateLine(startLine);
|
|
11210
11233
|
try {
|
|
11211
11234
|
const prId = getCurrentPrNodeId();
|
|
11212
|
-
postComment({ prId, body, path:
|
|
11235
|
+
postComment({ prId, body, path: path56, line, startLine });
|
|
11213
11236
|
const range = startLine !== void 0 ? `${startLine}-${line}` : `${line}`;
|
|
11214
|
-
console.log(`Added review comment on ${
|
|
11237
|
+
console.log(`Added review comment on ${path56}:${range}`);
|
|
11215
11238
|
} catch (error) {
|
|
11216
11239
|
if (isGhNotInstalled(error)) {
|
|
11217
11240
|
console.error("Error: GitHub CLI (gh) is not installed.");
|
|
@@ -11953,8 +11976,8 @@ function registerPrs(program2) {
|
|
|
11953
11976
|
prsCommand.command("wontfix <comment-id> <reason>").description("Reply with reason and resolve thread").action((commentId, reason) => {
|
|
11954
11977
|
wontfix(Number.parseInt(commentId, 10), reason);
|
|
11955
11978
|
});
|
|
11956
|
-
prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((
|
|
11957
|
-
comment2(
|
|
11979
|
+
prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((path56, line, body) => {
|
|
11980
|
+
comment2(path56, Number.parseInt(line, 10), body);
|
|
11958
11981
|
});
|
|
11959
11982
|
}
|
|
11960
11983
|
|
|
@@ -12206,10 +12229,10 @@ function resolveOpSecret(reference) {
|
|
|
12206
12229
|
}
|
|
12207
12230
|
|
|
12208
12231
|
// src/commands/ravendb/ravenFetch.ts
|
|
12209
|
-
async function ravenFetch(connection,
|
|
12232
|
+
async function ravenFetch(connection, path56) {
|
|
12210
12233
|
const apiKey = resolveOpSecret(connection.apiKeyRef);
|
|
12211
12234
|
let accessToken = await getAccessToken(apiKey);
|
|
12212
|
-
const url = `${connection.url}${
|
|
12235
|
+
const url = `${connection.url}${path56}`;
|
|
12213
12236
|
const headers = {
|
|
12214
12237
|
Authorization: `Bearer ${accessToken}`,
|
|
12215
12238
|
"Content-Type": "application/json"
|
|
@@ -12299,16 +12322,16 @@ import chalk132 from "chalk";
|
|
|
12299
12322
|
// src/commands/ravendb/buildQueryPath.ts
|
|
12300
12323
|
function buildQueryPath(opts) {
|
|
12301
12324
|
const db = encodeURIComponent(opts.db);
|
|
12302
|
-
let
|
|
12325
|
+
let path56;
|
|
12303
12326
|
if (opts.collection) {
|
|
12304
|
-
|
|
12327
|
+
path56 = `/databases/${db}/indexes/dynamic/${encodeURIComponent(opts.collection)}?start=${opts.start}&pageSize=${opts.pageSize}&sort=${encodeURIComponent(opts.sort)}`;
|
|
12305
12328
|
} else {
|
|
12306
|
-
|
|
12329
|
+
path56 = `/databases/${db}/queries?start=${opts.start}&pageSize=${opts.pageSize}`;
|
|
12307
12330
|
}
|
|
12308
12331
|
if (opts.query) {
|
|
12309
|
-
|
|
12332
|
+
path56 += `&query=${encodeURIComponent(opts.query)}`;
|
|
12310
12333
|
}
|
|
12311
|
-
return
|
|
12334
|
+
return path56;
|
|
12312
12335
|
}
|
|
12313
12336
|
|
|
12314
12337
|
// src/commands/ravendb/fetchAllPages.ts
|
|
@@ -12317,7 +12340,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
12317
12340
|
let start3 = 0;
|
|
12318
12341
|
while (true) {
|
|
12319
12342
|
const effectivePageSize = opts.limit !== void 0 ? Math.min(opts.pageSize, opts.limit - allResults.length) : opts.pageSize;
|
|
12320
|
-
const
|
|
12343
|
+
const path56 = buildQueryPath({
|
|
12321
12344
|
db: connection.database,
|
|
12322
12345
|
collection: opts.collection,
|
|
12323
12346
|
start: start3,
|
|
@@ -12325,7 +12348,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
12325
12348
|
sort: opts.sort,
|
|
12326
12349
|
query: opts.query
|
|
12327
12350
|
});
|
|
12328
|
-
const data = await ravenFetch(connection,
|
|
12351
|
+
const data = await ravenFetch(connection, path56);
|
|
12329
12352
|
const results = data.Results ?? [];
|
|
12330
12353
|
const totalResults = data.TotalResults ?? 0;
|
|
12331
12354
|
if (results.length === 0) break;
|
|
@@ -13329,100 +13352,131 @@ function ignore(file) {
|
|
|
13329
13352
|
}
|
|
13330
13353
|
|
|
13331
13354
|
// src/commands/refactor/rename/index.ts
|
|
13332
|
-
import
|
|
13355
|
+
import fs23 from "fs";
|
|
13356
|
+
import path38 from "path";
|
|
13357
|
+
import chalk141 from "chalk";
|
|
13358
|
+
|
|
13359
|
+
// src/commands/refactor/rename/applyRename.ts
|
|
13360
|
+
import fs22 from "fs";
|
|
13361
|
+
import path35 from "path";
|
|
13333
13362
|
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
13363
|
|
|
13350
|
-
// src/commands/refactor/
|
|
13351
|
-
import
|
|
13364
|
+
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
13365
|
+
import path34 from "path";
|
|
13352
13366
|
|
|
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());
|
|
13369
|
-
}
|
|
13370
|
-
function findSymbol(sourceFile, symbolName) {
|
|
13371
|
-
for (const id of sourceFile.getDescendantsOfKind(SyntaxKind14.Identifier)) {
|
|
13372
|
-
if (id.getText() === symbolName && isDeclaration(id)) return id;
|
|
13373
|
-
}
|
|
13374
|
-
return void 0;
|
|
13367
|
+
// src/commands/refactor/restructure/computeRewrites/applyRewrites.ts
|
|
13368
|
+
import fs21 from "fs";
|
|
13369
|
+
function getOrCreateList(map, key) {
|
|
13370
|
+
const list4 = map.get(key) ?? [];
|
|
13371
|
+
if (!map.has(key)) map.set(key, list4);
|
|
13372
|
+
return list4;
|
|
13375
13373
|
}
|
|
13376
|
-
|
|
13377
|
-
// src/commands/refactor/renameSymbol/groupReferences.ts
|
|
13378
|
-
import path35 from "path";
|
|
13379
|
-
function groupReferences(symbol, cwd) {
|
|
13380
|
-
const refs = symbol.findReferencesAsNodes();
|
|
13374
|
+
function groupByFile2(rewrites) {
|
|
13381
13375
|
const grouped = /* @__PURE__ */ new Map();
|
|
13382
|
-
for (const
|
|
13383
|
-
|
|
13384
|
-
const lines = grouped.get(refFile) ?? [];
|
|
13385
|
-
if (!grouped.has(refFile)) grouped.set(refFile, lines);
|
|
13386
|
-
lines.push(ref.getStartLineNumber());
|
|
13376
|
+
for (const rewrite of rewrites) {
|
|
13377
|
+
getOrCreateList(grouped, rewrite.file).push(rewrite);
|
|
13387
13378
|
}
|
|
13388
13379
|
return grouped;
|
|
13389
13380
|
}
|
|
13390
|
-
|
|
13391
|
-
|
|
13392
|
-
|
|
13393
|
-
|
|
13394
|
-
|
|
13395
|
-
|
|
13396
|
-
|
|
13397
|
-
|
|
13398
|
-
|
|
13399
|
-
}
|
|
13400
|
-
const grouped = groupReferences(symbol, cwd);
|
|
13401
|
-
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
13402
|
-
console.log(
|
|
13403
|
-
chalk140.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
13404
|
-
`)
|
|
13405
|
-
);
|
|
13406
|
-
for (const [refFile, lines] of grouped) {
|
|
13407
|
-
console.log(
|
|
13408
|
-
` ${chalk140.dim(refFile)}: lines ${chalk140.cyan(lines.join(", "))}`
|
|
13409
|
-
);
|
|
13381
|
+
function rewriteSpecifier(content, oldSpecifier, newSpecifier) {
|
|
13382
|
+
const escaped = oldSpecifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
13383
|
+
const pattern2 = new RegExp(`(from\\s+["'])${escaped}(["'])`, "g");
|
|
13384
|
+
return content.replace(pattern2, `$1${newSpecifier}$2`);
|
|
13385
|
+
}
|
|
13386
|
+
function applyFileRewrites(file, fileRewrites) {
|
|
13387
|
+
let content = fs21.readFileSync(file, "utf-8");
|
|
13388
|
+
for (const { oldSpecifier, newSpecifier } of fileRewrites) {
|
|
13389
|
+
content = rewriteSpecifier(content, oldSpecifier, newSpecifier);
|
|
13410
13390
|
}
|
|
13411
|
-
|
|
13412
|
-
|
|
13413
|
-
|
|
13414
|
-
|
|
13415
|
-
|
|
13416
|
-
|
|
13417
|
-
console.log(chalk140.dim("\nDry run. Use --apply to execute."));
|
|
13391
|
+
return content;
|
|
13392
|
+
}
|
|
13393
|
+
function applyRewrites(rewrites) {
|
|
13394
|
+
const updatedContents = /* @__PURE__ */ new Map();
|
|
13395
|
+
for (const [file, fileRewrites] of groupByFile2(rewrites)) {
|
|
13396
|
+
updatedContents.set(file, applyFileRewrites(file, fileRewrites));
|
|
13418
13397
|
}
|
|
13398
|
+
return updatedContents;
|
|
13419
13399
|
}
|
|
13420
13400
|
|
|
13421
|
-
// src/commands/refactor/restructure/index.ts
|
|
13422
|
-
|
|
13423
|
-
|
|
13424
|
-
|
|
13425
|
-
|
|
13401
|
+
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
13402
|
+
function buildMoveMap(moves) {
|
|
13403
|
+
const map = /* @__PURE__ */ new Map();
|
|
13404
|
+
for (const move of moves) map.set(move.from, move.to);
|
|
13405
|
+
return map;
|
|
13406
|
+
}
|
|
13407
|
+
function stripTrailingIndex(specifier) {
|
|
13408
|
+
return specifier.endsWith("/index") ? specifier.slice(0, -"/index".length) : specifier;
|
|
13409
|
+
}
|
|
13410
|
+
function ensureRelative(specifier) {
|
|
13411
|
+
return specifier.startsWith(".") ? specifier : `./${specifier}`;
|
|
13412
|
+
}
|
|
13413
|
+
function normalizeSpecifier(rel) {
|
|
13414
|
+
return ensureRelative(
|
|
13415
|
+
stripTrailingIndex(rel.replace(/\\/g, "/").replace(/\.tsx?$/, ""))
|
|
13416
|
+
);
|
|
13417
|
+
}
|
|
13418
|
+
function computeSpecifier(fromFile, toFile) {
|
|
13419
|
+
return normalizeSpecifier(path34.relative(path34.dirname(fromFile), toFile));
|
|
13420
|
+
}
|
|
13421
|
+
function isAffected(edge, moveMap) {
|
|
13422
|
+
return moveMap.has(edge.target) || moveMap.has(edge.source);
|
|
13423
|
+
}
|
|
13424
|
+
function resolveTarget(edge, moveMap) {
|
|
13425
|
+
return moveMap.get(edge.target) ?? edge.target;
|
|
13426
|
+
}
|
|
13427
|
+
function createRewrite(edge, newSpecifier) {
|
|
13428
|
+
return { file: edge.source, oldSpecifier: edge.specifier, newSpecifier };
|
|
13429
|
+
}
|
|
13430
|
+
function rewriteIfChanged(edge, newSpecifier) {
|
|
13431
|
+
return newSpecifier === edge.specifier ? null : createRewrite(edge, newSpecifier);
|
|
13432
|
+
}
|
|
13433
|
+
function rewriteEdge(edge, newFile, moveMap) {
|
|
13434
|
+
if (!isAffected(edge, moveMap)) return null;
|
|
13435
|
+
return rewriteIfChanged(
|
|
13436
|
+
edge,
|
|
13437
|
+
computeSpecifier(newFile, resolveTarget(edge, moveMap))
|
|
13438
|
+
);
|
|
13439
|
+
}
|
|
13440
|
+
function fileEdges(edges, file) {
|
|
13441
|
+
return edges.filter((e) => e.source === file);
|
|
13442
|
+
}
|
|
13443
|
+
function collectRewrites(edges, newFile, moveMap) {
|
|
13444
|
+
const rewrites = [];
|
|
13445
|
+
for (const edge of edges) {
|
|
13446
|
+
const rewrite = rewriteEdge(edge, newFile, moveMap);
|
|
13447
|
+
if (rewrite) rewrites.push(rewrite);
|
|
13448
|
+
}
|
|
13449
|
+
return rewrites;
|
|
13450
|
+
}
|
|
13451
|
+
function rewriteEdgesForFile(file, edges, moveMap) {
|
|
13452
|
+
const newFile = moveMap.get(file) ?? file;
|
|
13453
|
+
return collectRewrites(fileEdges(edges, file), newFile, moveMap);
|
|
13454
|
+
}
|
|
13455
|
+
function computeRewrites(moves, edges, allProjectFiles) {
|
|
13456
|
+
const moveMap = buildMoveMap(moves);
|
|
13457
|
+
return [...allProjectFiles].flatMap(
|
|
13458
|
+
(file) => rewriteEdgesForFile(file, edges, moveMap)
|
|
13459
|
+
);
|
|
13460
|
+
}
|
|
13461
|
+
|
|
13462
|
+
// src/commands/refactor/rename/applyRename.ts
|
|
13463
|
+
function applyRename(rewrites, sourcePath, destPath, cwd) {
|
|
13464
|
+
const updatedContents = applyRewrites(rewrites);
|
|
13465
|
+
for (const [file, content] of updatedContents) {
|
|
13466
|
+
fs22.writeFileSync(file, content, "utf-8");
|
|
13467
|
+
console.log(chalk139.cyan(` Updated imports in ${path35.relative(cwd, file)}`));
|
|
13468
|
+
}
|
|
13469
|
+
const destDir = path35.dirname(destPath);
|
|
13470
|
+
if (!fs22.existsSync(destDir)) fs22.mkdirSync(destDir, { recursive: true });
|
|
13471
|
+
fs22.renameSync(sourcePath, destPath);
|
|
13472
|
+
console.log(
|
|
13473
|
+
chalk139.white(
|
|
13474
|
+
` Moved ${path35.relative(cwd, sourcePath)} \u2192 ${path35.relative(cwd, destPath)}`
|
|
13475
|
+
)
|
|
13476
|
+
);
|
|
13477
|
+
}
|
|
13478
|
+
|
|
13479
|
+
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
13426
13480
|
import path36 from "path";
|
|
13427
13481
|
import ts7 from "typescript";
|
|
13428
13482
|
|
|
@@ -13488,13 +13542,148 @@ function buildImportGraph(candidateFiles, tsConfigPath) {
|
|
|
13488
13542
|
return { files: candidateFiles, edges, importedBy, imports };
|
|
13489
13543
|
}
|
|
13490
13544
|
|
|
13491
|
-
// src/commands/refactor/
|
|
13545
|
+
// src/commands/refactor/rename/computeRenameRewrites.ts
|
|
13546
|
+
function computeRenameRewrites(sourcePath, destPath) {
|
|
13547
|
+
const tsConfigPath = findTsConfig(sourcePath);
|
|
13548
|
+
const graph = buildImportGraph(/* @__PURE__ */ new Set([sourcePath]), tsConfigPath);
|
|
13549
|
+
const allProjectFiles = /* @__PURE__ */ new Set([
|
|
13550
|
+
...graph.importedBy.keys(),
|
|
13551
|
+
...graph.imports.keys(),
|
|
13552
|
+
sourcePath
|
|
13553
|
+
]);
|
|
13554
|
+
const move = { from: sourcePath, to: destPath, reason: "rename" };
|
|
13555
|
+
return computeRewrites([move], graph.edges, allProjectFiles);
|
|
13556
|
+
}
|
|
13557
|
+
|
|
13558
|
+
// src/commands/refactor/rename/printRenamePreview.ts
|
|
13492
13559
|
import path37 from "path";
|
|
13560
|
+
import chalk140 from "chalk";
|
|
13561
|
+
function printRenamePreview(rewrites, cwd) {
|
|
13562
|
+
for (const rewrite of rewrites) {
|
|
13563
|
+
console.log(
|
|
13564
|
+
chalk140.dim(
|
|
13565
|
+
` ${path37.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
|
|
13566
|
+
)
|
|
13567
|
+
);
|
|
13568
|
+
}
|
|
13569
|
+
console.log(chalk140.dim("Dry run. Use --apply to execute."));
|
|
13570
|
+
}
|
|
13571
|
+
|
|
13572
|
+
// src/commands/refactor/rename/index.ts
|
|
13573
|
+
async function rename(source, destination, options2 = {}) {
|
|
13574
|
+
const sourcePath = path38.resolve(source);
|
|
13575
|
+
const destPath = path38.resolve(destination);
|
|
13576
|
+
const cwd = process.cwd();
|
|
13577
|
+
const relSource = path38.relative(cwd, sourcePath);
|
|
13578
|
+
const relDest = path38.relative(cwd, destPath);
|
|
13579
|
+
if (!fs23.existsSync(sourcePath)) {
|
|
13580
|
+
console.log(chalk141.red(`File not found: ${source}`));
|
|
13581
|
+
process.exit(1);
|
|
13582
|
+
}
|
|
13583
|
+
if (destPath !== sourcePath && fs23.existsSync(destPath)) {
|
|
13584
|
+
console.log(chalk141.red(`Destination already exists: ${destination}`));
|
|
13585
|
+
process.exit(1);
|
|
13586
|
+
}
|
|
13587
|
+
console.log(chalk141.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
13588
|
+
console.log(chalk141.dim("Loading project..."));
|
|
13589
|
+
console.log(chalk141.dim("Scanning imports across the project..."));
|
|
13590
|
+
const rewrites = computeRenameRewrites(sourcePath, destPath);
|
|
13591
|
+
const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
|
|
13592
|
+
console.log(
|
|
13593
|
+
chalk141.dim(
|
|
13594
|
+
`${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
|
|
13595
|
+
)
|
|
13596
|
+
);
|
|
13597
|
+
if (!options2.apply) {
|
|
13598
|
+
printRenamePreview(rewrites, cwd);
|
|
13599
|
+
return;
|
|
13600
|
+
}
|
|
13601
|
+
applyRename(rewrites, sourcePath, destPath, cwd);
|
|
13602
|
+
console.log(chalk141.green("Done"));
|
|
13603
|
+
}
|
|
13604
|
+
|
|
13605
|
+
// src/commands/refactor/renameSymbol/index.ts
|
|
13606
|
+
import chalk142 from "chalk";
|
|
13607
|
+
|
|
13608
|
+
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
13609
|
+
import { SyntaxKind as SyntaxKind14 } from "ts-morph";
|
|
13610
|
+
var declarationKinds = [
|
|
13611
|
+
SyntaxKind14.VariableDeclaration,
|
|
13612
|
+
SyntaxKind14.FunctionDeclaration,
|
|
13613
|
+
SyntaxKind14.ClassDeclaration,
|
|
13614
|
+
SyntaxKind14.InterfaceDeclaration,
|
|
13615
|
+
SyntaxKind14.TypeAliasDeclaration,
|
|
13616
|
+
SyntaxKind14.EnumDeclaration,
|
|
13617
|
+
SyntaxKind14.PropertyDeclaration,
|
|
13618
|
+
SyntaxKind14.MethodDeclaration,
|
|
13619
|
+
SyntaxKind14.Parameter
|
|
13620
|
+
];
|
|
13621
|
+
function isDeclaration(identifier) {
|
|
13622
|
+
const parent = identifier.getParent();
|
|
13623
|
+
return parent !== void 0 && declarationKinds.includes(parent.getKind());
|
|
13624
|
+
}
|
|
13625
|
+
function findSymbol(sourceFile, symbolName) {
|
|
13626
|
+
for (const id of sourceFile.getDescendantsOfKind(SyntaxKind14.Identifier)) {
|
|
13627
|
+
if (id.getText() === symbolName && isDeclaration(id)) return id;
|
|
13628
|
+
}
|
|
13629
|
+
return void 0;
|
|
13630
|
+
}
|
|
13631
|
+
|
|
13632
|
+
// src/commands/refactor/renameSymbol/groupReferences.ts
|
|
13633
|
+
import path39 from "path";
|
|
13634
|
+
function groupReferences(symbol, cwd) {
|
|
13635
|
+
const refs = symbol.findReferencesAsNodes();
|
|
13636
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
13637
|
+
for (const ref of refs) {
|
|
13638
|
+
const refFile = path39.relative(cwd, ref.getSourceFile().getFilePath());
|
|
13639
|
+
const lines = grouped.get(refFile) ?? [];
|
|
13640
|
+
if (!grouped.has(refFile)) grouped.set(refFile, lines);
|
|
13641
|
+
lines.push(ref.getStartLineNumber());
|
|
13642
|
+
}
|
|
13643
|
+
return grouped;
|
|
13644
|
+
}
|
|
13645
|
+
|
|
13646
|
+
// src/commands/refactor/renameSymbol/index.ts
|
|
13647
|
+
async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
13648
|
+
const cwd = process.cwd();
|
|
13649
|
+
const { project, sourceFile } = loadProjectFile(file);
|
|
13650
|
+
const symbol = findSymbol(sourceFile, oldName);
|
|
13651
|
+
if (!symbol) {
|
|
13652
|
+
console.log(chalk142.red(`Symbol "${oldName}" not found in ${file}`));
|
|
13653
|
+
process.exit(1);
|
|
13654
|
+
}
|
|
13655
|
+
const grouped = groupReferences(symbol, cwd);
|
|
13656
|
+
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
13657
|
+
console.log(
|
|
13658
|
+
chalk142.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
13659
|
+
`)
|
|
13660
|
+
);
|
|
13661
|
+
for (const [refFile, lines] of grouped) {
|
|
13662
|
+
console.log(
|
|
13663
|
+
` ${chalk142.dim(refFile)}: lines ${chalk142.cyan(lines.join(", "))}`
|
|
13664
|
+
);
|
|
13665
|
+
}
|
|
13666
|
+
if (options2.apply) {
|
|
13667
|
+
symbol.rename(newName);
|
|
13668
|
+
await project.save();
|
|
13669
|
+
console.log(chalk142.green(`
|
|
13670
|
+
Renamed ${oldName} \u2192 ${newName}`));
|
|
13671
|
+
} else {
|
|
13672
|
+
console.log(chalk142.dim("\nDry run. Use --apply to execute."));
|
|
13673
|
+
}
|
|
13674
|
+
}
|
|
13675
|
+
|
|
13676
|
+
// src/commands/refactor/restructure/index.ts
|
|
13677
|
+
import path46 from "path";
|
|
13678
|
+
import chalk145 from "chalk";
|
|
13679
|
+
|
|
13680
|
+
// src/commands/refactor/restructure/clusterDirectories.ts
|
|
13681
|
+
import path40 from "path";
|
|
13493
13682
|
function clusterDirectories(graph) {
|
|
13494
13683
|
const dirImportedBy = /* @__PURE__ */ new Map();
|
|
13495
13684
|
for (const edge of graph.edges) {
|
|
13496
|
-
const sourceDir =
|
|
13497
|
-
const targetDir =
|
|
13685
|
+
const sourceDir = path40.dirname(edge.source);
|
|
13686
|
+
const targetDir = path40.dirname(edge.target);
|
|
13498
13687
|
if (sourceDir === targetDir) continue;
|
|
13499
13688
|
if (!graph.files.has(edge.target)) continue;
|
|
13500
13689
|
const existing = dirImportedBy.get(targetDir) ?? /* @__PURE__ */ new Set();
|
|
@@ -13522,20 +13711,20 @@ function clusterDirectories(graph) {
|
|
|
13522
13711
|
return clusters;
|
|
13523
13712
|
}
|
|
13524
13713
|
function isAncestor(ancestor, descendant) {
|
|
13525
|
-
const rel =
|
|
13714
|
+
const rel = path40.relative(ancestor, descendant);
|
|
13526
13715
|
return !rel.startsWith("..") && rel !== "";
|
|
13527
13716
|
}
|
|
13528
13717
|
|
|
13529
13718
|
// src/commands/refactor/restructure/clusterFiles.ts
|
|
13530
|
-
import
|
|
13719
|
+
import path41 from "path";
|
|
13531
13720
|
function findRootParent(file, importedBy, visited) {
|
|
13532
13721
|
const importers = importedBy.get(file);
|
|
13533
13722
|
if (!importers || importers.size !== 1) return file;
|
|
13534
13723
|
const parent = [...importers][0];
|
|
13535
|
-
const parentDir =
|
|
13536
|
-
const fileDir =
|
|
13724
|
+
const parentDir = path41.dirname(parent);
|
|
13725
|
+
const fileDir = path41.dirname(file);
|
|
13537
13726
|
if (parentDir !== fileDir) return file;
|
|
13538
|
-
if (
|
|
13727
|
+
if (path41.basename(parent, path41.extname(parent)) === "index") return file;
|
|
13539
13728
|
if (visited.has(parent)) return file;
|
|
13540
13729
|
visited.add(parent);
|
|
13541
13730
|
return findRootParent(parent, importedBy, visited);
|
|
@@ -13543,16 +13732,16 @@ function findRootParent(file, importedBy, visited) {
|
|
|
13543
13732
|
function clusterFiles(graph) {
|
|
13544
13733
|
const clusters = /* @__PURE__ */ new Map();
|
|
13545
13734
|
for (const file of graph.files) {
|
|
13546
|
-
const basename12 =
|
|
13735
|
+
const basename12 = path41.basename(file, path41.extname(file));
|
|
13547
13736
|
if (basename12 === "index") continue;
|
|
13548
13737
|
const importers = graph.importedBy.get(file);
|
|
13549
13738
|
if (!importers || importers.size !== 1) continue;
|
|
13550
13739
|
const parent = [...importers][0];
|
|
13551
13740
|
if (!graph.files.has(parent)) continue;
|
|
13552
|
-
const parentDir =
|
|
13553
|
-
const fileDir =
|
|
13741
|
+
const parentDir = path41.dirname(parent);
|
|
13742
|
+
const fileDir = path41.dirname(file);
|
|
13554
13743
|
if (parentDir !== fileDir) continue;
|
|
13555
|
-
const parentBasename =
|
|
13744
|
+
const parentBasename = path41.basename(parent, path41.extname(parent));
|
|
13556
13745
|
if (parentBasename === "index") continue;
|
|
13557
13746
|
const root = findRootParent(parent, graph.importedBy, /* @__PURE__ */ new Set([file]));
|
|
13558
13747
|
if (!root || root === file) continue;
|
|
@@ -13563,150 +13752,52 @@ function clusterFiles(graph) {
|
|
|
13563
13752
|
return clusters;
|
|
13564
13753
|
}
|
|
13565
13754
|
|
|
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
13755
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
13665
|
-
import
|
|
13666
|
-
import
|
|
13756
|
+
import path42 from "path";
|
|
13757
|
+
import chalk143 from "chalk";
|
|
13667
13758
|
function relPath(filePath) {
|
|
13668
|
-
return
|
|
13759
|
+
return path42.relative(process.cwd(), filePath);
|
|
13669
13760
|
}
|
|
13670
13761
|
function displayMoves(plan2) {
|
|
13671
13762
|
if (plan2.moves.length === 0) return;
|
|
13672
|
-
console.log(
|
|
13763
|
+
console.log(chalk143.bold("\nFile moves:"));
|
|
13673
13764
|
for (const move of plan2.moves) {
|
|
13674
13765
|
console.log(
|
|
13675
|
-
` ${
|
|
13766
|
+
` ${chalk143.red(relPath(move.from))} \u2192 ${chalk143.green(relPath(move.to))}`
|
|
13676
13767
|
);
|
|
13677
|
-
console.log(
|
|
13768
|
+
console.log(chalk143.dim(` ${move.reason}`));
|
|
13678
13769
|
}
|
|
13679
13770
|
}
|
|
13680
13771
|
function displayRewrites(rewrites) {
|
|
13681
13772
|
if (rewrites.length === 0) return;
|
|
13682
13773
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
13683
|
-
console.log(
|
|
13774
|
+
console.log(chalk143.bold(`
|
|
13684
13775
|
Import rewrites (${affectedFiles.size} files):`));
|
|
13685
13776
|
for (const file of affectedFiles) {
|
|
13686
|
-
console.log(` ${
|
|
13777
|
+
console.log(` ${chalk143.cyan(relPath(file))}:`);
|
|
13687
13778
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
13688
13779
|
(r) => r.file === file
|
|
13689
13780
|
)) {
|
|
13690
13781
|
console.log(
|
|
13691
|
-
` ${
|
|
13782
|
+
` ${chalk143.red(`"${oldSpecifier}"`)} \u2192 ${chalk143.green(`"${newSpecifier}"`)}`
|
|
13692
13783
|
);
|
|
13693
13784
|
}
|
|
13694
13785
|
}
|
|
13695
13786
|
}
|
|
13696
13787
|
function displayPlan2(plan2) {
|
|
13697
13788
|
if (plan2.warnings.length > 0) {
|
|
13698
|
-
console.log(
|
|
13699
|
-
for (const w of plan2.warnings) console.log(
|
|
13789
|
+
console.log(chalk143.yellow("\nWarnings:"));
|
|
13790
|
+
for (const w of plan2.warnings) console.log(chalk143.yellow(` ${w}`));
|
|
13700
13791
|
}
|
|
13701
13792
|
if (plan2.newDirectories.length > 0) {
|
|
13702
|
-
console.log(
|
|
13793
|
+
console.log(chalk143.bold("\nNew directories:"));
|
|
13703
13794
|
for (const dir of plan2.newDirectories)
|
|
13704
|
-
console.log(
|
|
13795
|
+
console.log(chalk143.green(` ${dir}/`));
|
|
13705
13796
|
}
|
|
13706
13797
|
displayMoves(plan2);
|
|
13707
13798
|
displayRewrites(plan2.rewrites);
|
|
13708
13799
|
console.log(
|
|
13709
|
-
|
|
13800
|
+
chalk143.dim(
|
|
13710
13801
|
`
|
|
13711
13802
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
13712
13803
|
)
|
|
@@ -13714,45 +13805,45 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
13714
13805
|
}
|
|
13715
13806
|
|
|
13716
13807
|
// src/commands/refactor/restructure/executePlan.ts
|
|
13717
|
-
import
|
|
13718
|
-
import
|
|
13719
|
-
import
|
|
13808
|
+
import fs24 from "fs";
|
|
13809
|
+
import path43 from "path";
|
|
13810
|
+
import chalk144 from "chalk";
|
|
13720
13811
|
function executePlan(plan2) {
|
|
13721
13812
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
13722
13813
|
for (const [file, content] of updatedContents) {
|
|
13723
|
-
|
|
13814
|
+
fs24.writeFileSync(file, content, "utf-8");
|
|
13724
13815
|
console.log(
|
|
13725
|
-
|
|
13816
|
+
chalk144.cyan(` Rewrote imports in ${path43.relative(process.cwd(), file)}`)
|
|
13726
13817
|
);
|
|
13727
13818
|
}
|
|
13728
13819
|
for (const dir of plan2.newDirectories) {
|
|
13729
|
-
|
|
13730
|
-
console.log(
|
|
13820
|
+
fs24.mkdirSync(dir, { recursive: true });
|
|
13821
|
+
console.log(chalk144.green(` Created ${path43.relative(process.cwd(), dir)}/`));
|
|
13731
13822
|
}
|
|
13732
13823
|
for (const move of plan2.moves) {
|
|
13733
|
-
const targetDir =
|
|
13734
|
-
if (!
|
|
13735
|
-
|
|
13824
|
+
const targetDir = path43.dirname(move.to);
|
|
13825
|
+
if (!fs24.existsSync(targetDir)) {
|
|
13826
|
+
fs24.mkdirSync(targetDir, { recursive: true });
|
|
13736
13827
|
}
|
|
13737
|
-
|
|
13828
|
+
fs24.renameSync(move.from, move.to);
|
|
13738
13829
|
console.log(
|
|
13739
|
-
|
|
13740
|
-
` Moved ${
|
|
13830
|
+
chalk144.white(
|
|
13831
|
+
` Moved ${path43.relative(process.cwd(), move.from)} \u2192 ${path43.relative(process.cwd(), move.to)}`
|
|
13741
13832
|
)
|
|
13742
13833
|
);
|
|
13743
13834
|
}
|
|
13744
|
-
removeEmptyDirectories(plan2.moves.map((m) =>
|
|
13835
|
+
removeEmptyDirectories(plan2.moves.map((m) => path43.dirname(m.from)));
|
|
13745
13836
|
}
|
|
13746
13837
|
function removeEmptyDirectories(dirs) {
|
|
13747
13838
|
const unique = [...new Set(dirs)];
|
|
13748
13839
|
for (const dir of unique) {
|
|
13749
|
-
if (!
|
|
13750
|
-
const entries =
|
|
13840
|
+
if (!fs24.existsSync(dir)) continue;
|
|
13841
|
+
const entries = fs24.readdirSync(dir);
|
|
13751
13842
|
if (entries.length === 0) {
|
|
13752
|
-
|
|
13843
|
+
fs24.rmdirSync(dir);
|
|
13753
13844
|
console.log(
|
|
13754
|
-
|
|
13755
|
-
` Removed empty directory ${
|
|
13845
|
+
chalk144.dim(
|
|
13846
|
+
` Removed empty directory ${path43.relative(process.cwd(), dir)}`
|
|
13756
13847
|
)
|
|
13757
13848
|
);
|
|
13758
13849
|
}
|
|
@@ -13760,46 +13851,46 @@ function removeEmptyDirectories(dirs) {
|
|
|
13760
13851
|
}
|
|
13761
13852
|
|
|
13762
13853
|
// src/commands/refactor/restructure/planFileMoves/index.ts
|
|
13763
|
-
import
|
|
13854
|
+
import path45 from "path";
|
|
13764
13855
|
|
|
13765
13856
|
// src/commands/refactor/restructure/planFileMoves/shared.ts
|
|
13766
|
-
import
|
|
13857
|
+
import fs25 from "fs";
|
|
13767
13858
|
function emptyResult() {
|
|
13768
13859
|
return { moves: [], directories: [], warnings: [] };
|
|
13769
13860
|
}
|
|
13770
13861
|
function checkDirConflict(result, label2, dir) {
|
|
13771
|
-
if (!
|
|
13862
|
+
if (!fs25.existsSync(dir)) return false;
|
|
13772
13863
|
result.warnings.push(`Skipping ${label2}: directory ${dir} already exists`);
|
|
13773
13864
|
return true;
|
|
13774
13865
|
}
|
|
13775
13866
|
|
|
13776
13867
|
// src/commands/refactor/restructure/planFileMoves/planDirectoryMoves.ts
|
|
13777
|
-
import
|
|
13778
|
-
import
|
|
13868
|
+
import fs26 from "fs";
|
|
13869
|
+
import path44 from "path";
|
|
13779
13870
|
function collectEntry(results, dir, entry) {
|
|
13780
|
-
const full =
|
|
13871
|
+
const full = path44.join(dir, entry.name);
|
|
13781
13872
|
const items2 = entry.isDirectory() ? listFilesRecursive(full) : [full];
|
|
13782
13873
|
results.push(...items2);
|
|
13783
13874
|
}
|
|
13784
13875
|
function listFilesRecursive(dir) {
|
|
13785
|
-
if (!
|
|
13876
|
+
if (!fs26.existsSync(dir)) return [];
|
|
13786
13877
|
const results = [];
|
|
13787
|
-
for (const entry of
|
|
13878
|
+
for (const entry of fs26.readdirSync(dir, { withFileTypes: true })) {
|
|
13788
13879
|
collectEntry(results, dir, entry);
|
|
13789
13880
|
}
|
|
13790
13881
|
return results;
|
|
13791
13882
|
}
|
|
13792
13883
|
function addDirectoryFileMoves(moves, childDir, newLocation, reason) {
|
|
13793
13884
|
for (const file of listFilesRecursive(childDir)) {
|
|
13794
|
-
const rel =
|
|
13795
|
-
moves.push({ from: file, to:
|
|
13885
|
+
const rel = path44.relative(childDir, file);
|
|
13886
|
+
moves.push({ from: file, to: path44.join(newLocation, rel), reason });
|
|
13796
13887
|
}
|
|
13797
13888
|
}
|
|
13798
13889
|
function resolveChildDest(parentDir, childDir) {
|
|
13799
|
-
return
|
|
13890
|
+
return path44.join(parentDir, path44.basename(childDir));
|
|
13800
13891
|
}
|
|
13801
13892
|
function childMoveReason(parentDir) {
|
|
13802
|
-
return `Directory only imported from ${
|
|
13893
|
+
return `Directory only imported from ${path44.basename(parentDir)}/`;
|
|
13803
13894
|
}
|
|
13804
13895
|
function registerDirectoryMove(result, childDir, dest, parentDir) {
|
|
13805
13896
|
result.directories.push(dest);
|
|
@@ -13824,7 +13915,7 @@ function planDirectoryMoves(clusters) {
|
|
|
13824
13915
|
|
|
13825
13916
|
// src/commands/refactor/restructure/planFileMoves/index.ts
|
|
13826
13917
|
function childMoveData(child, newDir, parentBase) {
|
|
13827
|
-
const to =
|
|
13918
|
+
const to = path45.join(newDir, path45.basename(child));
|
|
13828
13919
|
return { from: child, to, reason: `Only imported by ${parentBase}` };
|
|
13829
13920
|
}
|
|
13830
13921
|
function addChildMoves(moves, children, newDir, parentBase) {
|
|
@@ -13832,15 +13923,15 @@ function addChildMoves(moves, children, newDir, parentBase) {
|
|
|
13832
13923
|
moves.push(childMoveData(child, newDir, parentBase));
|
|
13833
13924
|
}
|
|
13834
13925
|
function getBaseName(filePath) {
|
|
13835
|
-
return
|
|
13926
|
+
return path45.basename(filePath, path45.extname(filePath));
|
|
13836
13927
|
}
|
|
13837
13928
|
function resolveClusterDir(parent) {
|
|
13838
|
-
return
|
|
13929
|
+
return path45.join(path45.dirname(parent), getBaseName(parent));
|
|
13839
13930
|
}
|
|
13840
13931
|
function createParentMove(parent, newDir) {
|
|
13841
13932
|
return {
|
|
13842
13933
|
from: parent,
|
|
13843
|
-
to:
|
|
13934
|
+
to: path45.join(newDir, `index${path45.extname(parent)}`),
|
|
13844
13935
|
reason: `Main module of new ${getBaseName(parent)}/ directory`
|
|
13845
13936
|
};
|
|
13846
13937
|
}
|
|
@@ -13864,7 +13955,7 @@ function planFileMoves(clusters) {
|
|
|
13864
13955
|
|
|
13865
13956
|
// src/commands/refactor/restructure/index.ts
|
|
13866
13957
|
function buildPlan3(candidateFiles, tsConfigPath) {
|
|
13867
|
-
const candidates = new Set(candidateFiles.map((f) =>
|
|
13958
|
+
const candidates = new Set(candidateFiles.map((f) => path46.resolve(f)));
|
|
13868
13959
|
const graph = buildImportGraph(candidates, tsConfigPath);
|
|
13869
13960
|
const allProjectFiles = /* @__PURE__ */ new Set([
|
|
13870
13961
|
...graph.importedBy.keys(),
|
|
@@ -13884,22 +13975,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
13884
13975
|
const targetPattern = pattern2 ?? "src";
|
|
13885
13976
|
const files = findSourceFiles2(targetPattern);
|
|
13886
13977
|
if (files.length === 0) {
|
|
13887
|
-
console.log(
|
|
13978
|
+
console.log(chalk145.yellow("No files found matching pattern"));
|
|
13888
13979
|
return;
|
|
13889
13980
|
}
|
|
13890
|
-
const tsConfigPath =
|
|
13981
|
+
const tsConfigPath = path46.resolve("tsconfig.json");
|
|
13891
13982
|
const plan2 = buildPlan3(files, tsConfigPath);
|
|
13892
13983
|
if (plan2.moves.length === 0) {
|
|
13893
|
-
console.log(
|
|
13984
|
+
console.log(chalk145.green("No restructuring needed"));
|
|
13894
13985
|
return;
|
|
13895
13986
|
}
|
|
13896
13987
|
displayPlan2(plan2);
|
|
13897
13988
|
if (options2.apply) {
|
|
13898
|
-
console.log(
|
|
13989
|
+
console.log(chalk145.bold("\nApplying changes..."));
|
|
13899
13990
|
executePlan(plan2);
|
|
13900
|
-
console.log(
|
|
13991
|
+
console.log(chalk145.green("\nRestructuring complete"));
|
|
13901
13992
|
} else {
|
|
13902
|
-
console.log(
|
|
13993
|
+
console.log(chalk145.dim("\nDry run. Use --apply to execute."));
|
|
13903
13994
|
}
|
|
13904
13995
|
}
|
|
13905
13996
|
|
|
@@ -14468,18 +14559,18 @@ function partitionFindingsByDiff(findings, index2) {
|
|
|
14468
14559
|
}
|
|
14469
14560
|
|
|
14470
14561
|
// src/commands/review/warnOutOfDiff.ts
|
|
14471
|
-
import
|
|
14562
|
+
import chalk146 from "chalk";
|
|
14472
14563
|
function warnOutOfDiff(outOfDiff) {
|
|
14473
14564
|
if (outOfDiff.length === 0) return;
|
|
14474
14565
|
console.warn(
|
|
14475
|
-
|
|
14566
|
+
chalk146.yellow(
|
|
14476
14567
|
`Skipped ${outOfDiff.length} finding(s) whose lines fall outside the PR diff (GitHub would silently drop these):`
|
|
14477
14568
|
)
|
|
14478
14569
|
);
|
|
14479
14570
|
for (const finding of outOfDiff) {
|
|
14480
14571
|
const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
|
|
14481
14572
|
console.warn(
|
|
14482
|
-
` ${
|
|
14573
|
+
` ${chalk146.yellow("\xB7")} ${finding.title} ${chalk146.dim(
|
|
14483
14574
|
`(${finding.file}:${range})`
|
|
14484
14575
|
)}`
|
|
14485
14576
|
);
|
|
@@ -14498,18 +14589,18 @@ function selectInDiffFindings(lineBound, prDiff) {
|
|
|
14498
14589
|
}
|
|
14499
14590
|
|
|
14500
14591
|
// src/commands/review/warnUnlocated.ts
|
|
14501
|
-
import
|
|
14592
|
+
import chalk147 from "chalk";
|
|
14502
14593
|
function warnUnlocated(unlocated) {
|
|
14503
14594
|
if (unlocated.length === 0) return;
|
|
14504
14595
|
console.warn(
|
|
14505
|
-
|
|
14596
|
+
chalk147.yellow(
|
|
14506
14597
|
`Skipped ${unlocated.length} finding(s) without a parseable file:line:`
|
|
14507
14598
|
)
|
|
14508
14599
|
);
|
|
14509
14600
|
for (const finding of unlocated) {
|
|
14510
|
-
const where = finding.location ||
|
|
14601
|
+
const where = finding.location || chalk147.dim("missing");
|
|
14511
14602
|
console.warn(
|
|
14512
|
-
` ${
|
|
14603
|
+
` ${chalk147.yellow("\xB7")} ${finding.title} ${chalk147.dim(`(${where})`)}`
|
|
14513
14604
|
);
|
|
14514
14605
|
}
|
|
14515
14606
|
}
|
|
@@ -14606,8 +14697,8 @@ async function handlePostSynthesis(synthesisPath, options2) {
|
|
|
14606
14697
|
// src/commands/review/prepareReviewDir.ts
|
|
14607
14698
|
import { existsSync as existsSync36, mkdirSync as mkdirSync14, unlinkSync as unlinkSync12, writeFileSync as writeFileSync26 } from "fs";
|
|
14608
14699
|
function clearReviewFiles(paths) {
|
|
14609
|
-
for (const
|
|
14610
|
-
if (existsSync36(
|
|
14700
|
+
for (const path56 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
|
|
14701
|
+
if (existsSync36(path56)) unlinkSync12(path56);
|
|
14611
14702
|
}
|
|
14612
14703
|
}
|
|
14613
14704
|
function prepareReviewDir(paths, requestBody, force) {
|
|
@@ -15682,7 +15773,7 @@ function registerReview(program2) {
|
|
|
15682
15773
|
}
|
|
15683
15774
|
|
|
15684
15775
|
// src/commands/seq/seqAuth.ts
|
|
15685
|
-
import
|
|
15776
|
+
import chalk149 from "chalk";
|
|
15686
15777
|
|
|
15687
15778
|
// src/commands/seq/loadConnections.ts
|
|
15688
15779
|
function loadConnections2() {
|
|
@@ -15711,10 +15802,10 @@ function setDefaultConnection(name) {
|
|
|
15711
15802
|
}
|
|
15712
15803
|
|
|
15713
15804
|
// src/shared/assertUniqueName.ts
|
|
15714
|
-
import
|
|
15805
|
+
import chalk148 from "chalk";
|
|
15715
15806
|
function assertUniqueName(existingNames, name) {
|
|
15716
15807
|
if (existingNames.includes(name)) {
|
|
15717
|
-
console.error(
|
|
15808
|
+
console.error(chalk148.red(`Connection "${name}" already exists.`));
|
|
15718
15809
|
process.exit(1);
|
|
15719
15810
|
}
|
|
15720
15811
|
}
|
|
@@ -15732,18 +15823,18 @@ async function promptConnection2(existingNames) {
|
|
|
15732
15823
|
var seqAuth = createConnectionAuth({
|
|
15733
15824
|
load: loadConnections2,
|
|
15734
15825
|
save: saveConnections2,
|
|
15735
|
-
format: (c) => `${
|
|
15826
|
+
format: (c) => `${chalk149.bold(c.name)} ${c.url}`,
|
|
15736
15827
|
promptNew: promptConnection2,
|
|
15737
15828
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
15738
15829
|
});
|
|
15739
15830
|
|
|
15740
15831
|
// src/commands/seq/seqQuery.ts
|
|
15741
|
-
import
|
|
15832
|
+
import chalk153 from "chalk";
|
|
15742
15833
|
|
|
15743
15834
|
// src/commands/seq/fetchSeq.ts
|
|
15744
|
-
import
|
|
15745
|
-
async function fetchSeq(conn,
|
|
15746
|
-
const url = `${conn.url}${
|
|
15835
|
+
import chalk150 from "chalk";
|
|
15836
|
+
async function fetchSeq(conn, path56, params) {
|
|
15837
|
+
const url = `${conn.url}${path56}?${params}`;
|
|
15747
15838
|
const response = await fetch(url, {
|
|
15748
15839
|
headers: {
|
|
15749
15840
|
Accept: "application/json",
|
|
@@ -15752,7 +15843,7 @@ async function fetchSeq(conn, path54, params) {
|
|
|
15752
15843
|
});
|
|
15753
15844
|
if (!response.ok) {
|
|
15754
15845
|
const body = await response.text();
|
|
15755
|
-
console.error(
|
|
15846
|
+
console.error(chalk150.red(`Seq returned ${response.status}: ${body}`));
|
|
15756
15847
|
process.exit(1);
|
|
15757
15848
|
}
|
|
15758
15849
|
return response;
|
|
@@ -15807,23 +15898,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
15807
15898
|
}
|
|
15808
15899
|
|
|
15809
15900
|
// src/commands/seq/formatEvent.ts
|
|
15810
|
-
import
|
|
15901
|
+
import chalk151 from "chalk";
|
|
15811
15902
|
function levelColor(level) {
|
|
15812
15903
|
switch (level) {
|
|
15813
15904
|
case "Fatal":
|
|
15814
|
-
return
|
|
15905
|
+
return chalk151.bgRed.white;
|
|
15815
15906
|
case "Error":
|
|
15816
|
-
return
|
|
15907
|
+
return chalk151.red;
|
|
15817
15908
|
case "Warning":
|
|
15818
|
-
return
|
|
15909
|
+
return chalk151.yellow;
|
|
15819
15910
|
case "Information":
|
|
15820
|
-
return
|
|
15911
|
+
return chalk151.cyan;
|
|
15821
15912
|
case "Debug":
|
|
15822
|
-
return
|
|
15913
|
+
return chalk151.gray;
|
|
15823
15914
|
case "Verbose":
|
|
15824
|
-
return
|
|
15915
|
+
return chalk151.dim;
|
|
15825
15916
|
default:
|
|
15826
|
-
return
|
|
15917
|
+
return chalk151.white;
|
|
15827
15918
|
}
|
|
15828
15919
|
}
|
|
15829
15920
|
function levelAbbrev(level) {
|
|
@@ -15864,12 +15955,12 @@ function formatTimestamp(iso) {
|
|
|
15864
15955
|
function formatEvent(event) {
|
|
15865
15956
|
const color = levelColor(event.Level);
|
|
15866
15957
|
const abbrev = levelAbbrev(event.Level);
|
|
15867
|
-
const ts8 =
|
|
15958
|
+
const ts8 = chalk151.dim(formatTimestamp(event.Timestamp));
|
|
15868
15959
|
const msg = renderMessage(event);
|
|
15869
15960
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
15870
15961
|
if (event.Exception) {
|
|
15871
15962
|
for (const line of event.Exception.split("\n")) {
|
|
15872
|
-
lines.push(
|
|
15963
|
+
lines.push(chalk151.red(` ${line}`));
|
|
15873
15964
|
}
|
|
15874
15965
|
}
|
|
15875
15966
|
return lines.join("\n");
|
|
@@ -15902,11 +15993,11 @@ function rejectTimestampFilter(filter) {
|
|
|
15902
15993
|
}
|
|
15903
15994
|
|
|
15904
15995
|
// src/shared/resolveNamedConnection.ts
|
|
15905
|
-
import
|
|
15996
|
+
import chalk152 from "chalk";
|
|
15906
15997
|
function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
|
|
15907
15998
|
if (connections.length === 0) {
|
|
15908
15999
|
console.error(
|
|
15909
|
-
|
|
16000
|
+
chalk152.red(
|
|
15910
16001
|
`No ${kind} connections configured. Run '${authCommand}' first.`
|
|
15911
16002
|
)
|
|
15912
16003
|
);
|
|
@@ -15915,7 +16006,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
|
|
|
15915
16006
|
const target = requested ?? defaultName ?? connections[0].name;
|
|
15916
16007
|
const connection = connections.find((c) => c.name === target);
|
|
15917
16008
|
if (!connection) {
|
|
15918
|
-
console.error(
|
|
16009
|
+
console.error(chalk152.red(`${kind} connection "${target}" not found.`));
|
|
15919
16010
|
process.exit(1);
|
|
15920
16011
|
}
|
|
15921
16012
|
return connection;
|
|
@@ -15944,7 +16035,7 @@ async function seqQuery(filter, options2) {
|
|
|
15944
16035
|
new URLSearchParams({ filter, count: String(count6) })
|
|
15945
16036
|
);
|
|
15946
16037
|
if (events.length === 0) {
|
|
15947
|
-
console.log(
|
|
16038
|
+
console.log(chalk153.yellow("No events found."));
|
|
15948
16039
|
return;
|
|
15949
16040
|
}
|
|
15950
16041
|
if (options2.json) {
|
|
@@ -15955,11 +16046,11 @@ async function seqQuery(filter, options2) {
|
|
|
15955
16046
|
for (const event of chronological) {
|
|
15956
16047
|
console.log(formatEvent(event));
|
|
15957
16048
|
}
|
|
15958
|
-
console.log(
|
|
16049
|
+
console.log(chalk153.dim(`
|
|
15959
16050
|
${events.length} events`));
|
|
15960
16051
|
if (events.length >= count6) {
|
|
15961
16052
|
console.log(
|
|
15962
|
-
|
|
16053
|
+
chalk153.yellow(
|
|
15963
16054
|
`Results limited to ${count6}. Use --count to retrieve more.`
|
|
15964
16055
|
)
|
|
15965
16056
|
);
|
|
@@ -15967,10 +16058,10 @@ ${events.length} events`));
|
|
|
15967
16058
|
}
|
|
15968
16059
|
|
|
15969
16060
|
// src/shared/setNamedDefaultConnection.ts
|
|
15970
|
-
import
|
|
16061
|
+
import chalk154 from "chalk";
|
|
15971
16062
|
function setNamedDefaultConnection(connections, name, setDefault, kind) {
|
|
15972
16063
|
if (!connections.find((c) => c.name === name)) {
|
|
15973
|
-
console.error(
|
|
16064
|
+
console.error(chalk154.red(`Connection "${name}" not found.`));
|
|
15974
16065
|
process.exit(1);
|
|
15975
16066
|
}
|
|
15976
16067
|
setDefault(name);
|
|
@@ -16018,7 +16109,7 @@ function registerSignal(program2) {
|
|
|
16018
16109
|
}
|
|
16019
16110
|
|
|
16020
16111
|
// src/commands/sql/sqlAuth.ts
|
|
16021
|
-
import
|
|
16112
|
+
import chalk156 from "chalk";
|
|
16022
16113
|
|
|
16023
16114
|
// src/commands/sql/loadConnections.ts
|
|
16024
16115
|
function loadConnections3() {
|
|
@@ -16047,7 +16138,7 @@ function setDefaultConnection2(name) {
|
|
|
16047
16138
|
}
|
|
16048
16139
|
|
|
16049
16140
|
// src/commands/sql/promptConnection.ts
|
|
16050
|
-
import
|
|
16141
|
+
import chalk155 from "chalk";
|
|
16051
16142
|
async function promptConnection3(existingNames) {
|
|
16052
16143
|
const name = await promptInput("name", "Connection name:", "default");
|
|
16053
16144
|
assertUniqueName(existingNames, name);
|
|
@@ -16055,7 +16146,7 @@ async function promptConnection3(existingNames) {
|
|
|
16055
16146
|
const portStr = await promptInput("port", "Port:", "1433");
|
|
16056
16147
|
const port = Number.parseInt(portStr, 10);
|
|
16057
16148
|
if (!Number.isFinite(port)) {
|
|
16058
|
-
console.error(
|
|
16149
|
+
console.error(chalk155.red(`Invalid port "${portStr}".`));
|
|
16059
16150
|
process.exit(1);
|
|
16060
16151
|
}
|
|
16061
16152
|
const user = await promptInput("user", "User:");
|
|
@@ -16068,13 +16159,13 @@ async function promptConnection3(existingNames) {
|
|
|
16068
16159
|
var sqlAuth = createConnectionAuth({
|
|
16069
16160
|
load: loadConnections3,
|
|
16070
16161
|
save: saveConnections3,
|
|
16071
|
-
format: (c) => `${
|
|
16162
|
+
format: (c) => `${chalk156.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
|
|
16072
16163
|
promptNew: promptConnection3,
|
|
16073
16164
|
onFirst: (c) => setDefaultConnection2(c.name)
|
|
16074
16165
|
});
|
|
16075
16166
|
|
|
16076
16167
|
// src/commands/sql/printTable.ts
|
|
16077
|
-
import
|
|
16168
|
+
import chalk157 from "chalk";
|
|
16078
16169
|
function formatCell(value) {
|
|
16079
16170
|
if (value === null || value === void 0) return "";
|
|
16080
16171
|
if (value instanceof Date) return value.toISOString();
|
|
@@ -16083,7 +16174,7 @@ function formatCell(value) {
|
|
|
16083
16174
|
}
|
|
16084
16175
|
function printTable(rows) {
|
|
16085
16176
|
if (rows.length === 0) {
|
|
16086
|
-
console.log(
|
|
16177
|
+
console.log(chalk157.yellow("(no rows)"));
|
|
16087
16178
|
return;
|
|
16088
16179
|
}
|
|
16089
16180
|
const columns = Object.keys(rows[0]);
|
|
@@ -16091,13 +16182,13 @@ function printTable(rows) {
|
|
|
16091
16182
|
(col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
|
|
16092
16183
|
);
|
|
16093
16184
|
const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
16094
|
-
console.log(
|
|
16095
|
-
console.log(
|
|
16185
|
+
console.log(chalk157.dim(header));
|
|
16186
|
+
console.log(chalk157.dim("-".repeat(header.length)));
|
|
16096
16187
|
for (const row of rows) {
|
|
16097
16188
|
const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
|
|
16098
16189
|
console.log(line);
|
|
16099
16190
|
}
|
|
16100
|
-
console.log(
|
|
16191
|
+
console.log(chalk157.dim(`
|
|
16101
16192
|
${rows.length} row${rows.length === 1 ? "" : "s"}`));
|
|
16102
16193
|
}
|
|
16103
16194
|
|
|
@@ -16157,7 +16248,7 @@ async function sqlColumns(table, connectionName) {
|
|
|
16157
16248
|
}
|
|
16158
16249
|
|
|
16159
16250
|
// src/commands/sql/sqlMutate.ts
|
|
16160
|
-
import
|
|
16251
|
+
import chalk158 from "chalk";
|
|
16161
16252
|
|
|
16162
16253
|
// src/commands/sql/isMutation.ts
|
|
16163
16254
|
var MUTATION_KEYWORDS = [
|
|
@@ -16191,7 +16282,7 @@ function isMutation(sql4) {
|
|
|
16191
16282
|
async function sqlMutate(query, connectionName) {
|
|
16192
16283
|
if (!isMutation(query)) {
|
|
16193
16284
|
console.error(
|
|
16194
|
-
|
|
16285
|
+
chalk158.red(
|
|
16195
16286
|
"assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
|
|
16196
16287
|
)
|
|
16197
16288
|
);
|
|
@@ -16201,18 +16292,18 @@ async function sqlMutate(query, connectionName) {
|
|
|
16201
16292
|
const pool = await sqlConnect(conn);
|
|
16202
16293
|
try {
|
|
16203
16294
|
const result = await pool.request().query(query);
|
|
16204
|
-
console.log(
|
|
16295
|
+
console.log(chalk158.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
|
|
16205
16296
|
} finally {
|
|
16206
16297
|
await pool.close();
|
|
16207
16298
|
}
|
|
16208
16299
|
}
|
|
16209
16300
|
|
|
16210
16301
|
// src/commands/sql/sqlQuery.ts
|
|
16211
|
-
import
|
|
16302
|
+
import chalk159 from "chalk";
|
|
16212
16303
|
async function sqlQuery(query, connectionName) {
|
|
16213
16304
|
if (isMutation(query)) {
|
|
16214
16305
|
console.error(
|
|
16215
|
-
|
|
16306
|
+
chalk159.red(
|
|
16216
16307
|
"assist sql query refuses mutating statements. Use `assist sql mutate` instead."
|
|
16217
16308
|
)
|
|
16218
16309
|
);
|
|
@@ -16227,7 +16318,7 @@ async function sqlQuery(query, connectionName) {
|
|
|
16227
16318
|
printTable(rows);
|
|
16228
16319
|
} else {
|
|
16229
16320
|
console.log(
|
|
16230
|
-
|
|
16321
|
+
chalk159.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
|
|
16231
16322
|
);
|
|
16232
16323
|
}
|
|
16233
16324
|
} finally {
|
|
@@ -16807,14 +16898,14 @@ import {
|
|
|
16807
16898
|
import { dirname as dirname22, join as join42 } from "path";
|
|
16808
16899
|
|
|
16809
16900
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
16810
|
-
import
|
|
16901
|
+
import chalk160 from "chalk";
|
|
16811
16902
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
16812
16903
|
function validateStagedContent(filename, content) {
|
|
16813
16904
|
const firstLine = content.split("\n")[0];
|
|
16814
16905
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
16815
16906
|
if (!match) {
|
|
16816
16907
|
console.error(
|
|
16817
|
-
|
|
16908
|
+
chalk160.red(
|
|
16818
16909
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
16819
16910
|
)
|
|
16820
16911
|
);
|
|
@@ -16823,7 +16914,7 @@ function validateStagedContent(filename, content) {
|
|
|
16823
16914
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
16824
16915
|
if (!contentAfterLink) {
|
|
16825
16916
|
console.error(
|
|
16826
|
-
|
|
16917
|
+
chalk160.red(
|
|
16827
16918
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
16828
16919
|
)
|
|
16829
16920
|
);
|
|
@@ -17220,7 +17311,7 @@ function registerVoice(program2) {
|
|
|
17220
17311
|
|
|
17221
17312
|
// src/commands/roam/auth.ts
|
|
17222
17313
|
import { randomBytes } from "crypto";
|
|
17223
|
-
import
|
|
17314
|
+
import chalk161 from "chalk";
|
|
17224
17315
|
|
|
17225
17316
|
// src/commands/roam/waitForCallback.ts
|
|
17226
17317
|
import { createServer as createServer2 } from "http";
|
|
@@ -17351,13 +17442,13 @@ async function auth() {
|
|
|
17351
17442
|
saveGlobalConfig(config);
|
|
17352
17443
|
const state = randomBytes(16).toString("hex");
|
|
17353
17444
|
console.log(
|
|
17354
|
-
|
|
17445
|
+
chalk161.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
17355
17446
|
);
|
|
17356
|
-
console.log(
|
|
17357
|
-
console.log(
|
|
17358
|
-
console.log(
|
|
17447
|
+
console.log(chalk161.white("http://localhost:14523/callback\n"));
|
|
17448
|
+
console.log(chalk161.blue("Opening browser for authorization..."));
|
|
17449
|
+
console.log(chalk161.dim("Waiting for authorization callback..."));
|
|
17359
17450
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
17360
|
-
console.log(
|
|
17451
|
+
console.log(chalk161.dim("Exchanging code for tokens..."));
|
|
17361
17452
|
const tokens = await exchangeToken({
|
|
17362
17453
|
code,
|
|
17363
17454
|
clientId,
|
|
@@ -17373,7 +17464,7 @@ async function auth() {
|
|
|
17373
17464
|
};
|
|
17374
17465
|
saveGlobalConfig(config);
|
|
17375
17466
|
console.log(
|
|
17376
|
-
|
|
17467
|
+
chalk161.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
17377
17468
|
);
|
|
17378
17469
|
}
|
|
17379
17470
|
|
|
@@ -17389,9 +17480,9 @@ function findPortFile(roamDir) {
|
|
|
17389
17480
|
return void 0;
|
|
17390
17481
|
}
|
|
17391
17482
|
const candidates = entries.filter((name) => /^roam-local-api(-[^.]+)?\.port$/.test(name)).map((name) => {
|
|
17392
|
-
const
|
|
17483
|
+
const path56 = join49(roamDir, name);
|
|
17393
17484
|
try {
|
|
17394
|
-
return { path:
|
|
17485
|
+
return { path: path56, mtimeMs: statSync5(path56).mtimeMs };
|
|
17395
17486
|
} catch {
|
|
17396
17487
|
return void 0;
|
|
17397
17488
|
}
|
|
@@ -17734,11 +17825,11 @@ function findLinkIndex() {
|
|
|
17734
17825
|
function parseLinkArgs() {
|
|
17735
17826
|
const idx = findLinkIndex();
|
|
17736
17827
|
if (idx === -1) return null;
|
|
17737
|
-
const
|
|
17828
|
+
const path56 = process.argv[idx + 1];
|
|
17738
17829
|
const rest = process.argv.slice(idx + 2);
|
|
17739
17830
|
const { value: prefix2 } = extractOption(rest, "--prefix");
|
|
17740
17831
|
if (!prefix2) return null;
|
|
17741
|
-
return { path:
|
|
17832
|
+
return { path: path56, prefix: prefix2 };
|
|
17742
17833
|
}
|
|
17743
17834
|
function hasDuplicateLink(runList, linkPath) {
|
|
17744
17835
|
return runList.some(
|
|
@@ -17825,7 +17916,7 @@ import { execSync as execSync48 } from "child_process";
|
|
|
17825
17916
|
import { existsSync as existsSync50, mkdirSync as mkdirSync21, unlinkSync as unlinkSync17, writeFileSync as writeFileSync32 } from "fs";
|
|
17826
17917
|
import { tmpdir as tmpdir7 } from "os";
|
|
17827
17918
|
import { join as join53, resolve as resolve13 } from "path";
|
|
17828
|
-
import
|
|
17919
|
+
import chalk162 from "chalk";
|
|
17829
17920
|
|
|
17830
17921
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
17831
17922
|
var captureWindowPs1 = `
|
|
@@ -17976,13 +18067,13 @@ function screenshot(processName) {
|
|
|
17976
18067
|
const config = loadConfig();
|
|
17977
18068
|
const outputDir = resolve13(config.screenshot.outputDir);
|
|
17978
18069
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
17979
|
-
console.log(
|
|
18070
|
+
console.log(chalk162.gray(`Capturing window for process "${processName}" ...`));
|
|
17980
18071
|
try {
|
|
17981
18072
|
runPowerShellScript(processName, outputPath);
|
|
17982
|
-
console.log(
|
|
18073
|
+
console.log(chalk162.green(`Screenshot saved: ${outputPath}`));
|
|
17983
18074
|
} catch (error) {
|
|
17984
18075
|
const msg = error instanceof Error ? error.message : String(error);
|
|
17985
|
-
console.error(
|
|
18076
|
+
console.error(chalk162.red(`Failed to capture screenshot: ${msg}`));
|
|
17986
18077
|
process.exit(1);
|
|
17987
18078
|
}
|
|
17988
18079
|
}
|
|
@@ -18215,14 +18306,14 @@ import * as pty from "node-pty";
|
|
|
18215
18306
|
// src/commands/sessions/daemon/ensureSpawnHelperExecutable.ts
|
|
18216
18307
|
import { chmodSync, existsSync as existsSync51, statSync as statSync6 } from "fs";
|
|
18217
18308
|
import { createRequire as createRequire3 } from "module";
|
|
18218
|
-
import
|
|
18309
|
+
import path47 from "path";
|
|
18219
18310
|
var require4 = createRequire3(import.meta.url);
|
|
18220
18311
|
var ensured = false;
|
|
18221
18312
|
function ensureSpawnHelperExecutable() {
|
|
18222
18313
|
if (ensured || process.platform !== "darwin") return;
|
|
18223
18314
|
ensured = true;
|
|
18224
|
-
const ptyRoot =
|
|
18225
|
-
const helper =
|
|
18315
|
+
const ptyRoot = path47.join(path47.dirname(require4.resolve("node-pty")), "..");
|
|
18316
|
+
const helper = path47.join(
|
|
18226
18317
|
ptyRoot,
|
|
18227
18318
|
"prebuilds",
|
|
18228
18319
|
`${process.platform}-${process.arch}`,
|
|
@@ -18465,8 +18556,8 @@ import { dirname as dirname26 } from "path";
|
|
|
18465
18556
|
var DEBOUNCE_MS = 50;
|
|
18466
18557
|
function watchActivity(session, notify2) {
|
|
18467
18558
|
if (session.commandType !== "assist" || !session.cwd) return;
|
|
18468
|
-
const
|
|
18469
|
-
const dir = dirname26(
|
|
18559
|
+
const path56 = activityPath(session.id);
|
|
18560
|
+
const dir = dirname26(path56);
|
|
18470
18561
|
try {
|
|
18471
18562
|
mkdirSync22(dir, { recursive: true });
|
|
18472
18563
|
} catch {
|
|
@@ -18475,7 +18566,7 @@ function watchActivity(session, notify2) {
|
|
|
18475
18566
|
let timer = null;
|
|
18476
18567
|
const read = () => {
|
|
18477
18568
|
timer = null;
|
|
18478
|
-
const activity2 = readActivity(
|
|
18569
|
+
const activity2 = readActivity(path56);
|
|
18479
18570
|
if (!activity2) return;
|
|
18480
18571
|
session.activity = activity2;
|
|
18481
18572
|
if (activity2.claudeSessionId)
|
|
@@ -18483,11 +18574,11 @@ function watchActivity(session, notify2) {
|
|
|
18483
18574
|
notify2();
|
|
18484
18575
|
};
|
|
18485
18576
|
session.activityWatcher = watch(dir, (_event, filename) => {
|
|
18486
|
-
if (filename && !
|
|
18577
|
+
if (filename && !path56.endsWith(filename)) return;
|
|
18487
18578
|
if (timer) clearTimeout(timer);
|
|
18488
18579
|
timer = setTimeout(read, DEBOUNCE_MS);
|
|
18489
18580
|
});
|
|
18490
|
-
if (existsSync52(
|
|
18581
|
+
if (existsSync52(path56)) read();
|
|
18491
18582
|
}
|
|
18492
18583
|
function refreshActivity(session) {
|
|
18493
18584
|
if (session.commandType !== "assist" || !session.cwd) return;
|
|
@@ -19007,17 +19098,17 @@ var WindowsProxy = class {
|
|
|
19007
19098
|
};
|
|
19008
19099
|
|
|
19009
19100
|
// src/commands/sessions/daemon/watchClaudeSessionId.ts
|
|
19010
|
-
import * as
|
|
19011
|
-
import * as
|
|
19101
|
+
import * as fs29 from "fs";
|
|
19102
|
+
import * as path50 from "path";
|
|
19012
19103
|
|
|
19013
19104
|
// src/commands/sessions/shared/discoverSessions.ts
|
|
19014
|
-
import * as
|
|
19105
|
+
import * as fs28 from "fs";
|
|
19015
19106
|
import * as os from "os";
|
|
19016
|
-
import * as
|
|
19107
|
+
import * as path49 from "path";
|
|
19017
19108
|
|
|
19018
19109
|
// src/commands/sessions/shared/parseSessionFile.ts
|
|
19019
|
-
import * as
|
|
19020
|
-
import * as
|
|
19110
|
+
import * as fs27 from "fs";
|
|
19111
|
+
import * as path48 from "path";
|
|
19021
19112
|
|
|
19022
19113
|
// src/commands/sessions/shared/deriveHistoryFields.ts
|
|
19023
19114
|
var KNOWN = ["draft", "next", "bug", "refine", "run"];
|
|
@@ -19106,10 +19197,10 @@ function matchMarker(text3, tag) {
|
|
|
19106
19197
|
async function parseSessionFile(filePath, origin = "wsl") {
|
|
19107
19198
|
let handle;
|
|
19108
19199
|
try {
|
|
19109
|
-
handle = await
|
|
19200
|
+
handle = await fs27.promises.open(filePath, "r");
|
|
19110
19201
|
const meta = extractSessionMeta(await readHeadLines(handle));
|
|
19111
19202
|
if (!meta.sessionId) return null;
|
|
19112
|
-
const timestamp = meta.timestamp || (await
|
|
19203
|
+
const timestamp = meta.timestamp || (await fs27.promises.stat(filePath)).mtime.toISOString();
|
|
19113
19204
|
return {
|
|
19114
19205
|
sessionId: meta.sessionId,
|
|
19115
19206
|
name: meta.name || `Session ${meta.sessionId.slice(0, 8)}`,
|
|
@@ -19132,10 +19223,10 @@ async function readHeadLines(handle) {
|
|
|
19132
19223
|
}
|
|
19133
19224
|
function deriveProject(cwd, filePath, origin) {
|
|
19134
19225
|
if (!cwd) return dirNameToProject(filePath);
|
|
19135
|
-
return origin === "windows" ?
|
|
19226
|
+
return origin === "windows" ? path48.win32.basename(cwd) : path48.basename(cwd);
|
|
19136
19227
|
}
|
|
19137
19228
|
function dirNameToProject(filePath) {
|
|
19138
|
-
const dirName =
|
|
19229
|
+
const dirName = path48.basename(path48.dirname(filePath));
|
|
19139
19230
|
const parts = dirName.split("--");
|
|
19140
19231
|
return parts[parts.length - 1].replace(/-/g, "/");
|
|
19141
19232
|
}
|
|
@@ -19143,7 +19234,7 @@ function dirNameToProject(filePath) {
|
|
|
19143
19234
|
// src/commands/sessions/shared/discoverSessions.ts
|
|
19144
19235
|
function sessionRoots() {
|
|
19145
19236
|
const roots = [
|
|
19146
|
-
{ dir:
|
|
19237
|
+
{ dir: path49.join(os.homedir(), ".claude", "projects"), origin: "wsl" }
|
|
19147
19238
|
];
|
|
19148
19239
|
const windowsRoot = loadConfig().sessions?.windowsProjectsRoot;
|
|
19149
19240
|
if (windowsRoot) roots.push({ dir: windowsRoot, origin: "windows" });
|
|
@@ -19155,22 +19246,22 @@ async function discoverSessionJsonlPaths() {
|
|
|
19155
19246
|
sessionRoots().map(async ({ dir, origin }) => {
|
|
19156
19247
|
let projectDirs;
|
|
19157
19248
|
try {
|
|
19158
|
-
projectDirs = await
|
|
19249
|
+
projectDirs = await fs28.promises.readdir(dir);
|
|
19159
19250
|
} catch {
|
|
19160
19251
|
return;
|
|
19161
19252
|
}
|
|
19162
19253
|
await Promise.all(
|
|
19163
19254
|
projectDirs.map(async (dirName) => {
|
|
19164
|
-
const dirPath =
|
|
19255
|
+
const dirPath = path49.join(dir, dirName);
|
|
19165
19256
|
let entries;
|
|
19166
19257
|
try {
|
|
19167
|
-
entries = await
|
|
19258
|
+
entries = await fs28.promises.readdir(dirPath);
|
|
19168
19259
|
} catch {
|
|
19169
19260
|
return;
|
|
19170
19261
|
}
|
|
19171
19262
|
for (const file of entries) {
|
|
19172
19263
|
if (file.endsWith(".jsonl"))
|
|
19173
|
-
results.push({ path:
|
|
19264
|
+
results.push({ path: path49.join(dirPath, file), origin });
|
|
19174
19265
|
}
|
|
19175
19266
|
})
|
|
19176
19267
|
);
|
|
@@ -19217,7 +19308,7 @@ async function findLatestSessionId(options2) {
|
|
|
19217
19308
|
if (createdMs === null) continue;
|
|
19218
19309
|
const meta = await parseSessionFile(filePath, origin);
|
|
19219
19310
|
if (!meta?.cwd || options2.isClaimed(meta.sessionId)) continue;
|
|
19220
|
-
if (
|
|
19311
|
+
if (path50.resolve(meta.cwd) !== path50.resolve(options2.cwd)) continue;
|
|
19221
19312
|
if (!latest || createdMs > latest.createdMs)
|
|
19222
19313
|
latest = { sessionId: meta.sessionId, createdMs };
|
|
19223
19314
|
}
|
|
@@ -19225,7 +19316,7 @@ async function findLatestSessionId(options2) {
|
|
|
19225
19316
|
}
|
|
19226
19317
|
async function createdSince(filePath, sinceMs) {
|
|
19227
19318
|
try {
|
|
19228
|
-
const stat = await
|
|
19319
|
+
const stat = await fs29.promises.stat(filePath);
|
|
19229
19320
|
const createdMs = stat.birthtimeMs || stat.mtimeMs;
|
|
19230
19321
|
return createdMs >= sinceMs ? createdMs : null;
|
|
19231
19322
|
} catch {
|
|
@@ -19403,7 +19494,7 @@ import * as net3 from "net";
|
|
|
19403
19494
|
import { createInterface as createInterface7 } from "readline";
|
|
19404
19495
|
|
|
19405
19496
|
// src/commands/sessions/shared/parseTranscript.ts
|
|
19406
|
-
import * as
|
|
19497
|
+
import * as fs30 from "fs";
|
|
19407
19498
|
|
|
19408
19499
|
// src/commands/sessions/shared/toolTarget.ts
|
|
19409
19500
|
function toolTarget(input) {
|
|
@@ -19451,11 +19542,11 @@ function cleanUserText(value) {
|
|
|
19451
19542
|
}
|
|
19452
19543
|
|
|
19453
19544
|
// src/commands/sessions/shared/findSessionJsonlPath.ts
|
|
19454
|
-
import * as
|
|
19545
|
+
import * as path51 from "path";
|
|
19455
19546
|
async function findSessionJsonlPath(sessionId) {
|
|
19456
19547
|
const paths = await discoverSessionJsonlPaths();
|
|
19457
19548
|
const direct = paths.find(
|
|
19458
|
-
(p) =>
|
|
19549
|
+
(p) => path51.basename(p.path, ".jsonl") === sessionId
|
|
19459
19550
|
);
|
|
19460
19551
|
if (direct) return direct.path;
|
|
19461
19552
|
for (const p of paths) {
|
|
@@ -19470,7 +19561,7 @@ async function parseTranscript(sessionId) {
|
|
|
19470
19561
|
const filePath = await findSessionJsonlPath(sessionId);
|
|
19471
19562
|
if (!filePath) return [];
|
|
19472
19563
|
try {
|
|
19473
|
-
const raw = await
|
|
19564
|
+
const raw = await fs30.promises.readFile(filePath, "utf8");
|
|
19474
19565
|
return parseTranscriptLines(raw.split("\n"));
|
|
19475
19566
|
} catch {
|
|
19476
19567
|
return [];
|
|
@@ -19732,17 +19823,17 @@ function registerDaemon(program2) {
|
|
|
19732
19823
|
}
|
|
19733
19824
|
|
|
19734
19825
|
// src/commands/sessions/summarise/index.ts
|
|
19735
|
-
import * as
|
|
19736
|
-
import
|
|
19826
|
+
import * as fs33 from "fs";
|
|
19827
|
+
import chalk163 from "chalk";
|
|
19737
19828
|
|
|
19738
19829
|
// src/commands/sessions/summarise/shared.ts
|
|
19739
|
-
import * as
|
|
19830
|
+
import * as fs31 from "fs";
|
|
19740
19831
|
function writeSummary(jsonlPath2, summary) {
|
|
19741
|
-
|
|
19832
|
+
fs31.writeFileSync(summaryPathFor(jsonlPath2), `${summary.trim()}
|
|
19742
19833
|
`, "utf8");
|
|
19743
19834
|
}
|
|
19744
19835
|
function hasSummary(jsonlPath2) {
|
|
19745
|
-
return
|
|
19836
|
+
return fs31.existsSync(summaryPathFor(jsonlPath2));
|
|
19746
19837
|
}
|
|
19747
19838
|
function summaryPathFor(jsonlPath2) {
|
|
19748
19839
|
return jsonlPath2.replace(/\.jsonl$/, ".summary");
|
|
@@ -19752,17 +19843,17 @@ function summaryPathFor(jsonlPath2) {
|
|
|
19752
19843
|
import { execFileSync as execFileSync11 } from "child_process";
|
|
19753
19844
|
|
|
19754
19845
|
// src/commands/sessions/summarise/iterateUserMessages.ts
|
|
19755
|
-
import * as
|
|
19846
|
+
import * as fs32 from "fs";
|
|
19756
19847
|
function* iterateUserMessages(filePath, maxBytes = 65536) {
|
|
19757
19848
|
let content;
|
|
19758
19849
|
try {
|
|
19759
|
-
const fd =
|
|
19850
|
+
const fd = fs32.openSync(filePath, "r");
|
|
19760
19851
|
try {
|
|
19761
19852
|
const buf = Buffer.alloc(maxBytes);
|
|
19762
|
-
const bytesRead =
|
|
19853
|
+
const bytesRead = fs32.readSync(fd, buf, 0, buf.length, 0);
|
|
19763
19854
|
content = buf.toString("utf8", 0, bytesRead);
|
|
19764
19855
|
} finally {
|
|
19765
|
-
|
|
19856
|
+
fs32.closeSync(fd);
|
|
19766
19857
|
}
|
|
19767
19858
|
} catch {
|
|
19768
19859
|
return;
|
|
@@ -19860,29 +19951,29 @@ ${firstMessage}`);
|
|
|
19860
19951
|
async function summarise4(options2) {
|
|
19861
19952
|
const files = await discoverSessionFiles();
|
|
19862
19953
|
if (files.length === 0) {
|
|
19863
|
-
console.log(
|
|
19954
|
+
console.log(chalk163.yellow("No sessions found."));
|
|
19864
19955
|
return;
|
|
19865
19956
|
}
|
|
19866
19957
|
const toProcess = selectCandidates(files, options2);
|
|
19867
19958
|
if (toProcess.length === 0) {
|
|
19868
|
-
console.log(
|
|
19959
|
+
console.log(chalk163.green("All sessions already summarised."));
|
|
19869
19960
|
return;
|
|
19870
19961
|
}
|
|
19871
19962
|
console.log(
|
|
19872
|
-
|
|
19963
|
+
chalk163.cyan(
|
|
19873
19964
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
19874
19965
|
)
|
|
19875
19966
|
);
|
|
19876
19967
|
const { succeeded, failed: failed2 } = processSessions(toProcess);
|
|
19877
19968
|
console.log(
|
|
19878
|
-
|
|
19969
|
+
chalk163.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk163.yellow(`, ${failed2} skipped`) : "")
|
|
19879
19970
|
);
|
|
19880
19971
|
}
|
|
19881
19972
|
function selectCandidates(files, options2) {
|
|
19882
19973
|
const candidates = options2.force ? files : files.filter((f) => !hasSummary(f));
|
|
19883
19974
|
candidates.sort((a, b) => {
|
|
19884
19975
|
try {
|
|
19885
|
-
return
|
|
19976
|
+
return fs33.statSync(b).mtimeMs - fs33.statSync(a).mtimeMs;
|
|
19886
19977
|
} catch {
|
|
19887
19978
|
return 0;
|
|
19888
19979
|
}
|
|
@@ -19895,16 +19986,16 @@ function processSessions(files) {
|
|
|
19895
19986
|
let failed2 = 0;
|
|
19896
19987
|
for (let i = 0; i < files.length; i++) {
|
|
19897
19988
|
const file = files[i];
|
|
19898
|
-
process.stdout.write(
|
|
19989
|
+
process.stdout.write(chalk163.dim(` [${i + 1}/${files.length}] `));
|
|
19899
19990
|
const summary = summariseSession(file);
|
|
19900
19991
|
if (summary) {
|
|
19901
19992
|
writeSummary(file, summary);
|
|
19902
19993
|
succeeded++;
|
|
19903
|
-
process.stdout.write(`${
|
|
19994
|
+
process.stdout.write(`${chalk163.green("\u2713")} ${summary}
|
|
19904
19995
|
`);
|
|
19905
19996
|
} else {
|
|
19906
19997
|
failed2++;
|
|
19907
|
-
process.stdout.write(` ${
|
|
19998
|
+
process.stdout.write(` ${chalk163.yellow("skip")}
|
|
19908
19999
|
`);
|
|
19909
20000
|
}
|
|
19910
20001
|
}
|
|
@@ -19919,10 +20010,10 @@ function registerSessions(program2) {
|
|
|
19919
20010
|
}
|
|
19920
20011
|
|
|
19921
20012
|
// src/commands/statusLine.ts
|
|
19922
|
-
import
|
|
20013
|
+
import chalk165 from "chalk";
|
|
19923
20014
|
|
|
19924
20015
|
// src/commands/buildLimitsSegment.ts
|
|
19925
|
-
import
|
|
20016
|
+
import chalk164 from "chalk";
|
|
19926
20017
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
19927
20018
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
19928
20019
|
function formatTimeLeft(resetsAt) {
|
|
@@ -19945,10 +20036,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
19945
20036
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
19946
20037
|
const label2 = `${Math.round(pct)}%`;
|
|
19947
20038
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
19948
|
-
if (projected == null) return
|
|
19949
|
-
if (projected > 100) return
|
|
19950
|
-
if (projected > 75) return
|
|
19951
|
-
return
|
|
20039
|
+
if (projected == null) return chalk164.green(label2);
|
|
20040
|
+
if (projected > 100) return chalk164.red(label2);
|
|
20041
|
+
if (projected > 75) return chalk164.yellow(label2);
|
|
20042
|
+
return chalk164.green(label2);
|
|
19952
20043
|
}
|
|
19953
20044
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
19954
20045
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -19974,14 +20065,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
19974
20065
|
}
|
|
19975
20066
|
|
|
19976
20067
|
// src/commands/statusLine.ts
|
|
19977
|
-
|
|
20068
|
+
chalk165.level = 3;
|
|
19978
20069
|
function formatNumber(num) {
|
|
19979
20070
|
return num.toLocaleString("en-US");
|
|
19980
20071
|
}
|
|
19981
20072
|
function colorizePercent(pct) {
|
|
19982
20073
|
const label2 = `${Math.round(pct)}%`;
|
|
19983
|
-
if (pct > 80) return
|
|
19984
|
-
if (pct > 40) return
|
|
20074
|
+
if (pct > 80) return chalk165.red(label2);
|
|
20075
|
+
if (pct > 40) return chalk165.yellow(label2);
|
|
19985
20076
|
return label2;
|
|
19986
20077
|
}
|
|
19987
20078
|
async function statusLine() {
|
|
@@ -19996,29 +20087,29 @@ async function statusLine() {
|
|
|
19996
20087
|
}
|
|
19997
20088
|
|
|
19998
20089
|
// src/commands/sync.ts
|
|
19999
|
-
import * as
|
|
20090
|
+
import * as fs36 from "fs";
|
|
20000
20091
|
import * as os2 from "os";
|
|
20001
|
-
import * as
|
|
20092
|
+
import * as path54 from "path";
|
|
20002
20093
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
20003
20094
|
|
|
20004
20095
|
// src/commands/sync/syncClaudeMd.ts
|
|
20005
|
-
import * as
|
|
20006
|
-
import * as
|
|
20007
|
-
import
|
|
20096
|
+
import * as fs34 from "fs";
|
|
20097
|
+
import * as path52 from "path";
|
|
20098
|
+
import chalk166 from "chalk";
|
|
20008
20099
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
20009
|
-
const source =
|
|
20010
|
-
const target =
|
|
20011
|
-
const sourceContent =
|
|
20012
|
-
if (
|
|
20013
|
-
const targetContent =
|
|
20100
|
+
const source = path52.join(claudeDir, "CLAUDE.md");
|
|
20101
|
+
const target = path52.join(targetBase, "CLAUDE.md");
|
|
20102
|
+
const sourceContent = fs34.readFileSync(source, "utf-8");
|
|
20103
|
+
if (fs34.existsSync(target)) {
|
|
20104
|
+
const targetContent = fs34.readFileSync(target, "utf-8");
|
|
20014
20105
|
if (sourceContent !== targetContent) {
|
|
20015
20106
|
console.log(
|
|
20016
|
-
|
|
20107
|
+
chalk166.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
20017
20108
|
);
|
|
20018
20109
|
console.log();
|
|
20019
20110
|
printDiff(targetContent, sourceContent);
|
|
20020
20111
|
const confirm = options2?.yes || await promptConfirm(
|
|
20021
|
-
|
|
20112
|
+
chalk166.red("Overwrite existing CLAUDE.md?"),
|
|
20022
20113
|
false
|
|
20023
20114
|
);
|
|
20024
20115
|
if (!confirm) {
|
|
@@ -20027,21 +20118,21 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
20027
20118
|
}
|
|
20028
20119
|
}
|
|
20029
20120
|
}
|
|
20030
|
-
|
|
20121
|
+
fs34.copyFileSync(source, target);
|
|
20031
20122
|
console.log("Copied CLAUDE.md to ~/.claude/CLAUDE.md");
|
|
20032
20123
|
}
|
|
20033
20124
|
|
|
20034
20125
|
// src/commands/sync/syncSettings.ts
|
|
20035
|
-
import * as
|
|
20036
|
-
import * as
|
|
20037
|
-
import
|
|
20126
|
+
import * as fs35 from "fs";
|
|
20127
|
+
import * as path53 from "path";
|
|
20128
|
+
import chalk167 from "chalk";
|
|
20038
20129
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
20039
|
-
const source =
|
|
20040
|
-
const target =
|
|
20041
|
-
const sourceContent =
|
|
20130
|
+
const source = path53.join(claudeDir, "settings.json");
|
|
20131
|
+
const target = path53.join(targetBase, "settings.json");
|
|
20132
|
+
const sourceContent = fs35.readFileSync(source, "utf-8");
|
|
20042
20133
|
const mergedContent = JSON.stringify(JSON.parse(sourceContent), null, " ");
|
|
20043
|
-
if (
|
|
20044
|
-
const targetContent =
|
|
20134
|
+
if (fs35.existsSync(target)) {
|
|
20135
|
+
const targetContent = fs35.readFileSync(target, "utf-8");
|
|
20045
20136
|
const normalizedTarget = JSON.stringify(
|
|
20046
20137
|
JSON.parse(targetContent),
|
|
20047
20138
|
null,
|
|
@@ -20050,14 +20141,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
20050
20141
|
if (mergedContent !== normalizedTarget) {
|
|
20051
20142
|
if (!options2?.yes) {
|
|
20052
20143
|
console.log(
|
|
20053
|
-
|
|
20144
|
+
chalk167.yellow(
|
|
20054
20145
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
20055
20146
|
)
|
|
20056
20147
|
);
|
|
20057
20148
|
console.log();
|
|
20058
20149
|
printDiff(targetContent, mergedContent);
|
|
20059
20150
|
const confirm = await promptConfirm(
|
|
20060
|
-
|
|
20151
|
+
chalk167.red("Overwrite existing settings.json?"),
|
|
20061
20152
|
false
|
|
20062
20153
|
);
|
|
20063
20154
|
if (!confirm) {
|
|
@@ -20067,29 +20158,29 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
20067
20158
|
}
|
|
20068
20159
|
}
|
|
20069
20160
|
}
|
|
20070
|
-
|
|
20161
|
+
fs35.writeFileSync(target, mergedContent);
|
|
20071
20162
|
console.log("Copied settings.json to ~/.claude/settings.json");
|
|
20072
20163
|
}
|
|
20073
20164
|
|
|
20074
20165
|
// src/commands/sync.ts
|
|
20075
20166
|
var __filename4 = fileURLToPath7(import.meta.url);
|
|
20076
|
-
var __dirname7 =
|
|
20167
|
+
var __dirname7 = path54.dirname(__filename4);
|
|
20077
20168
|
async function sync(options2) {
|
|
20078
20169
|
const config = loadConfig();
|
|
20079
20170
|
const yes = options2?.yes ?? config.sync.autoConfirm;
|
|
20080
|
-
const claudeDir =
|
|
20081
|
-
const targetBase =
|
|
20171
|
+
const claudeDir = path54.join(__dirname7, "..", "claude");
|
|
20172
|
+
const targetBase = path54.join(os2.homedir(), ".claude");
|
|
20082
20173
|
syncCommands(claudeDir, targetBase);
|
|
20083
20174
|
await syncSettings(claudeDir, targetBase, { yes });
|
|
20084
20175
|
await syncClaudeMd(claudeDir, targetBase, { yes });
|
|
20085
20176
|
}
|
|
20086
20177
|
function syncCommands(claudeDir, targetBase) {
|
|
20087
|
-
const sourceDir =
|
|
20088
|
-
const targetDir =
|
|
20089
|
-
|
|
20090
|
-
const files =
|
|
20178
|
+
const sourceDir = path54.join(claudeDir, "commands");
|
|
20179
|
+
const targetDir = path54.join(targetBase, "commands");
|
|
20180
|
+
fs36.mkdirSync(targetDir, { recursive: true });
|
|
20181
|
+
const files = fs36.readdirSync(sourceDir);
|
|
20091
20182
|
for (const file of files) {
|
|
20092
|
-
|
|
20183
|
+
fs36.copyFileSync(path54.join(sourceDir, file), path54.join(targetDir, file));
|
|
20093
20184
|
console.log(`Copied ${file} to ${targetDir}`);
|
|
20094
20185
|
}
|
|
20095
20186
|
console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
|
|
@@ -20097,15 +20188,15 @@ function syncCommands(claudeDir, targetBase) {
|
|
|
20097
20188
|
|
|
20098
20189
|
// src/commands/update.ts
|
|
20099
20190
|
import { execSync as execSync49 } from "child_process";
|
|
20100
|
-
import * as
|
|
20191
|
+
import * as path55 from "path";
|
|
20101
20192
|
function isGlobalNpmInstall(dir) {
|
|
20102
20193
|
try {
|
|
20103
|
-
const resolved =
|
|
20104
|
-
if (resolved.split(
|
|
20194
|
+
const resolved = path55.resolve(dir);
|
|
20195
|
+
if (resolved.split(path55.sep).includes("node_modules")) {
|
|
20105
20196
|
return true;
|
|
20106
20197
|
}
|
|
20107
20198
|
const globalPrefix = execSync49("npm prefix -g", { stdio: "pipe" }).toString().trim();
|
|
20108
|
-
return resolved.toLowerCase().startsWith(
|
|
20199
|
+
return resolved.toLowerCase().startsWith(path55.resolve(globalPrefix).toLowerCase());
|
|
20109
20200
|
} catch {
|
|
20110
20201
|
return false;
|
|
20111
20202
|
}
|