@staff0rd/assist 0.306.0 → 0.307.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.307.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -2178,7 +2178,7 @@ function flushIfFailed(exitCode, chunks) {
|
|
|
2178
2178
|
|
|
2179
2179
|
// src/commands/verify/run/runAllEntries.ts
|
|
2180
2180
|
function runEntry(entry, onComplete) {
|
|
2181
|
-
return new Promise((
|
|
2181
|
+
return new Promise((resolve17) => {
|
|
2182
2182
|
const child = spawnCommand(
|
|
2183
2183
|
entry.fullCommand,
|
|
2184
2184
|
entry.cwd,
|
|
@@ -2190,7 +2190,7 @@ function runEntry(entry, onComplete) {
|
|
|
2190
2190
|
const exitCode = code ?? 1;
|
|
2191
2191
|
flushIfFailed(exitCode, chunks);
|
|
2192
2192
|
onComplete?.(exitCode);
|
|
2193
|
-
|
|
2193
|
+
resolve17({ script: entry.name, code: exitCode });
|
|
2194
2194
|
});
|
|
2195
2195
|
});
|
|
2196
2196
|
}
|
|
@@ -2943,8 +2943,8 @@ function spawnClaude(prompt, options2 = {}) {
|
|
|
2943
2943
|
stdio: "inherit",
|
|
2944
2944
|
env
|
|
2945
2945
|
});
|
|
2946
|
-
const done2 = new Promise((
|
|
2947
|
-
child.on("close", (code) =>
|
|
2946
|
+
const done2 = new Promise((resolve17, reject) => {
|
|
2947
|
+
child.on("close", (code) => resolve17(code ?? 0));
|
|
2948
2948
|
child.on("error", reject);
|
|
2949
2949
|
});
|
|
2950
2950
|
return { child, done: done2 };
|
|
@@ -4752,9 +4752,9 @@ import {
|
|
|
4752
4752
|
// src/commands/sessions/daemon/connectToDaemon.ts
|
|
4753
4753
|
import * as net from "net";
|
|
4754
4754
|
function connectToDaemon() {
|
|
4755
|
-
return new Promise((
|
|
4755
|
+
return new Promise((resolve17, reject) => {
|
|
4756
4756
|
const socket = net.connect(daemonPaths.socket);
|
|
4757
|
-
socket.once("connect", () =>
|
|
4757
|
+
socket.once("connect", () => resolve17(socket));
|
|
4758
4758
|
socket.once("error", reject);
|
|
4759
4759
|
});
|
|
4760
4760
|
}
|
|
@@ -4834,7 +4834,7 @@ function spawnDaemon(reason) {
|
|
|
4834
4834
|
child.unref();
|
|
4835
4835
|
}
|
|
4836
4836
|
function delay(ms) {
|
|
4837
|
-
return new Promise((
|
|
4837
|
+
return new Promise((resolve17) => setTimeout(resolve17, ms));
|
|
4838
4838
|
}
|
|
4839
4839
|
|
|
4840
4840
|
// src/commands/sessions/web/handleRequest.ts
|
|
@@ -4974,12 +4974,12 @@ async function loadVisibleItems(req) {
|
|
|
4974
4974
|
|
|
4975
4975
|
// src/commands/backlog/web/parseStatusBody.ts
|
|
4976
4976
|
function readBody(req) {
|
|
4977
|
-
return new Promise((
|
|
4977
|
+
return new Promise((resolve17, reject) => {
|
|
4978
4978
|
let body = "";
|
|
4979
4979
|
req.on("data", (chunk) => {
|
|
4980
4980
|
body += chunk.toString();
|
|
4981
4981
|
});
|
|
4982
|
-
req.on("end", () =>
|
|
4982
|
+
req.on("end", () => resolve17(body));
|
|
4983
4983
|
req.on("error", reject);
|
|
4984
4984
|
});
|
|
4985
4985
|
}
|
|
@@ -5503,17 +5503,17 @@ async function stopDaemon() {
|
|
|
5503
5503
|
}
|
|
5504
5504
|
}
|
|
5505
5505
|
function closedBeforeTimeout(socket) {
|
|
5506
|
-
return new Promise((
|
|
5506
|
+
return new Promise((resolve17) => {
|
|
5507
5507
|
const timer = setTimeout(() => {
|
|
5508
5508
|
socket.destroy();
|
|
5509
|
-
|
|
5509
|
+
resolve17(false);
|
|
5510
5510
|
}, STOP_TIMEOUT_MS);
|
|
5511
5511
|
socket.resume();
|
|
5512
5512
|
socket.on("error", () => {
|
|
5513
5513
|
});
|
|
5514
5514
|
socket.once("close", () => {
|
|
5515
5515
|
clearTimeout(timer);
|
|
5516
|
-
|
|
5516
|
+
resolve17(true);
|
|
5517
5517
|
});
|
|
5518
5518
|
});
|
|
5519
5519
|
}
|
|
@@ -5564,8 +5564,8 @@ async function restartWeb(req, res, deps2 = {}) {
|
|
|
5564
5564
|
respondJson(res, 400, { error: "Invalid target" });
|
|
5565
5565
|
return;
|
|
5566
5566
|
}
|
|
5567
|
-
await new Promise((
|
|
5568
|
-
res.once("finish",
|
|
5567
|
+
await new Promise((resolve17) => {
|
|
5568
|
+
res.once("finish", resolve17);
|
|
5569
5569
|
respondJson(res, 200, { ok: true });
|
|
5570
5570
|
});
|
|
5571
5571
|
if (target === "daemon" || target === "both") {
|
|
@@ -8339,12 +8339,12 @@ function hasSubcommands(helpText) {
|
|
|
8339
8339
|
// src/commands/permitCliReads/runHelp.ts
|
|
8340
8340
|
import { exec as exec2 } from "child_process";
|
|
8341
8341
|
function runHelp(args) {
|
|
8342
|
-
return new Promise((
|
|
8342
|
+
return new Promise((resolve17) => {
|
|
8343
8343
|
exec2(
|
|
8344
8344
|
`${args.join(" ")} --help`,
|
|
8345
8345
|
{ encoding: "utf8", timeout: 3e4 },
|
|
8346
8346
|
(_err, stdout, stderr) => {
|
|
8347
|
-
|
|
8347
|
+
resolve17(stdout || stderr || "");
|
|
8348
8348
|
}
|
|
8349
8349
|
);
|
|
8350
8350
|
});
|
|
@@ -11411,25 +11411,18 @@ function createNetcapHandler(options2) {
|
|
|
11411
11411
|
};
|
|
11412
11412
|
}
|
|
11413
11413
|
|
|
11414
|
-
// src/commands/netcap/defaultCapturePath.ts
|
|
11415
|
-
import { homedir as homedir12 } from "os";
|
|
11416
|
-
import { join as join34 } from "path";
|
|
11417
|
-
function defaultCapturePath() {
|
|
11418
|
-
return join34(homedir12(), ".assist", "netcap", "capture.jsonl");
|
|
11419
|
-
}
|
|
11420
|
-
|
|
11421
11414
|
// src/commands/netcap/prepareExtensionForLoad.ts
|
|
11422
11415
|
import { cp, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
11423
11416
|
import { networkInterfaces } from "os";
|
|
11424
|
-
import { join as
|
|
11417
|
+
import { join as join35 } from "path";
|
|
11425
11418
|
import chalk123 from "chalk";
|
|
11426
11419
|
|
|
11427
11420
|
// src/commands/netcap/netcapExtensionDir.ts
|
|
11428
|
-
import { dirname as dirname19, join as
|
|
11421
|
+
import { dirname as dirname19, join as join34 } from "path";
|
|
11429
11422
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
11430
11423
|
var moduleDir = dirname19(fileURLToPath5(import.meta.url));
|
|
11431
11424
|
function netcapExtensionDir() {
|
|
11432
|
-
return
|
|
11425
|
+
return join34(moduleDir, "commands", "netcap", "netcap-extension");
|
|
11433
11426
|
}
|
|
11434
11427
|
|
|
11435
11428
|
// src/commands/netcap/prepareExtensionForLoad.ts
|
|
@@ -11443,21 +11436,24 @@ function lanIPv4() {
|
|
|
11443
11436
|
}
|
|
11444
11437
|
return void 0;
|
|
11445
11438
|
}
|
|
11446
|
-
async function
|
|
11447
|
-
const file =
|
|
11439
|
+
async function configureBackground(dir, host, port, filter) {
|
|
11440
|
+
const file = join35(dir, "background.js");
|
|
11448
11441
|
const source = await readFile2(file, "utf8");
|
|
11449
11442
|
await writeFile2(
|
|
11450
11443
|
file,
|
|
11451
11444
|
source.replace(
|
|
11452
11445
|
/const RECEIVER = "[^"]*";/,
|
|
11453
11446
|
`const RECEIVER = "http://${host}:${port}/";`
|
|
11447
|
+
).replace(
|
|
11448
|
+
/const FILTER = "[^"]*";/,
|
|
11449
|
+
`const FILTER = ${JSON.stringify(filter)};`
|
|
11454
11450
|
)
|
|
11455
11451
|
);
|
|
11456
11452
|
}
|
|
11457
|
-
async function prepareExtensionForLoad(port) {
|
|
11453
|
+
async function prepareExtensionForLoad(port, filter = "") {
|
|
11458
11454
|
const source = netcapExtensionDir();
|
|
11459
11455
|
if (detectPlatform() !== "wsl") {
|
|
11460
|
-
await
|
|
11456
|
+
await configureBackground(source, "127.0.0.1", port, filter);
|
|
11461
11457
|
return source;
|
|
11462
11458
|
}
|
|
11463
11459
|
const host = lanIPv4();
|
|
@@ -11465,12 +11461,12 @@ async function prepareExtensionForLoad(port) {
|
|
|
11465
11461
|
console.log(
|
|
11466
11462
|
chalk123.yellow("could not determine the WSL IP for the extension")
|
|
11467
11463
|
);
|
|
11468
|
-
await
|
|
11464
|
+
await configureBackground(source, "127.0.0.1", port, filter);
|
|
11469
11465
|
return source;
|
|
11470
11466
|
}
|
|
11471
11467
|
try {
|
|
11472
11468
|
await cp(source, WSL_WINDOWS_DIR, { recursive: true });
|
|
11473
|
-
await
|
|
11469
|
+
await configureBackground(WSL_WINDOWS_DIR, host, port, filter);
|
|
11474
11470
|
return WSL_WINDOWS_PATH;
|
|
11475
11471
|
} catch {
|
|
11476
11472
|
console.log(
|
|
@@ -11480,12 +11476,30 @@ async function prepareExtensionForLoad(port) {
|
|
|
11480
11476
|
}
|
|
11481
11477
|
}
|
|
11482
11478
|
|
|
11479
|
+
// src/commands/netcap/resolveNetcapOutPath.ts
|
|
11480
|
+
import { isAbsolute, join as join37, resolve as resolve11 } from "path";
|
|
11481
|
+
|
|
11482
|
+
// src/commands/netcap/defaultCapturePath.ts
|
|
11483
|
+
import { homedir as homedir12 } from "os";
|
|
11484
|
+
import { join as join36 } from "path";
|
|
11485
|
+
function defaultCapturePath() {
|
|
11486
|
+
return join36(homedir12(), ".assist", "netcap", "capture.jsonl");
|
|
11487
|
+
}
|
|
11488
|
+
|
|
11489
|
+
// src/commands/netcap/resolveNetcapOutPath.ts
|
|
11490
|
+
function resolveNetcapOutPath(out) {
|
|
11491
|
+
if (!out) return defaultCapturePath();
|
|
11492
|
+
const dir = isAbsolute(out) ? out : resolve11(process.cwd(), out);
|
|
11493
|
+
return join37(dir, "capture.jsonl");
|
|
11494
|
+
}
|
|
11495
|
+
|
|
11483
11496
|
// src/commands/netcap/netcap.ts
|
|
11484
11497
|
async function netcap(options2) {
|
|
11485
11498
|
const port = Number(options2.port);
|
|
11486
|
-
const outPath =
|
|
11499
|
+
const outPath = resolveNetcapOutPath(options2.out);
|
|
11500
|
+
const filter = options2.filter ?? "";
|
|
11487
11501
|
await mkdir(dirname20(outPath), { recursive: true });
|
|
11488
|
-
const extensionPath = await prepareExtensionForLoad(port);
|
|
11502
|
+
const extensionPath = await prepareExtensionForLoad(port, filter);
|
|
11489
11503
|
let count6 = 0;
|
|
11490
11504
|
const handler = createNetcapHandler({
|
|
11491
11505
|
outPath,
|
|
@@ -11504,24 +11518,480 @@ async function netcap(options2) {
|
|
|
11504
11518
|
chalk124.bold(`netcap receiver listening on http://127.0.0.1:${port}`)
|
|
11505
11519
|
);
|
|
11506
11520
|
console.log(chalk124.dim(`appending captures to ${outPath}`));
|
|
11521
|
+
if (filter)
|
|
11522
|
+
console.log(chalk124.dim(`forwarding only URLs matching "${filter}"`));
|
|
11507
11523
|
console.log(chalk124.dim(`load the unpacked extension from ${extensionPath}`));
|
|
11508
11524
|
console.log(chalk124.dim("press Ctrl-C to stop"));
|
|
11509
11525
|
});
|
|
11510
11526
|
process.on("SIGINT", () => {
|
|
11511
11527
|
server.close();
|
|
11528
|
+
console.log(
|
|
11529
|
+
chalk124.bold(
|
|
11530
|
+
`
|
|
11531
|
+
netcap stopped \u2014 captured ${count6} ${count6 === 1 ? "entry" : "entries"} to ${outPath}`
|
|
11532
|
+
)
|
|
11533
|
+
);
|
|
11512
11534
|
process.exit(0);
|
|
11513
11535
|
});
|
|
11514
11536
|
}
|
|
11515
11537
|
|
|
11538
|
+
// src/commands/netcap/netcapExtract.ts
|
|
11539
|
+
import { writeFileSync as writeFileSync26 } from "fs";
|
|
11540
|
+
import { join as join38 } from "path";
|
|
11541
|
+
import chalk125 from "chalk";
|
|
11542
|
+
|
|
11543
|
+
// src/commands/netcap/extractPostsFromCapture.ts
|
|
11544
|
+
import { readFileSync as readFileSync30 } from "fs";
|
|
11545
|
+
|
|
11546
|
+
// src/commands/netcap/parseRscRows.ts
|
|
11547
|
+
var isRscRef = (v) => typeof v === "string" && /^\$[0-9a-fL@]/.test(v);
|
|
11548
|
+
function parseRscRows(flight) {
|
|
11549
|
+
const rows = {};
|
|
11550
|
+
for (const line of flight.split("\n")) {
|
|
11551
|
+
const m = line.match(/^([0-9a-f]+):(.*)$/s);
|
|
11552
|
+
if (!m) continue;
|
|
11553
|
+
let payload = m[2];
|
|
11554
|
+
if (payload && !/^[[{"\d\-tfn]/.test(payload[0]))
|
|
11555
|
+
payload = payload.slice(1);
|
|
11556
|
+
try {
|
|
11557
|
+
rows[m[1]] = JSON.parse(payload);
|
|
11558
|
+
} catch {
|
|
11559
|
+
rows[m[1]] = m[2];
|
|
11560
|
+
}
|
|
11561
|
+
}
|
|
11562
|
+
return rows;
|
|
11563
|
+
}
|
|
11564
|
+
function makeRscResolver(rows) {
|
|
11565
|
+
return (ref) => {
|
|
11566
|
+
const [id2, ...path58] = ref.slice(1).replace(/^[L@]/, "").split(":");
|
|
11567
|
+
let v = rows[id2];
|
|
11568
|
+
for (const key of path58) {
|
|
11569
|
+
if (v == null || typeof v !== "object") return void 0;
|
|
11570
|
+
v = v[key];
|
|
11571
|
+
}
|
|
11572
|
+
return v;
|
|
11573
|
+
};
|
|
11574
|
+
}
|
|
11575
|
+
|
|
11576
|
+
// src/commands/netcap/collectRscText.ts
|
|
11577
|
+
function isVisibleText(t) {
|
|
11578
|
+
if (/^(proto\.|com\.linkedin|react\.)/.test(t)) return false;
|
|
11579
|
+
if (!/\s/.test(t.trim())) return false;
|
|
11580
|
+
return /[a-zA-Z]{3,}/.test(t);
|
|
11581
|
+
}
|
|
11582
|
+
var isHashtag = (t) => /^#[A-Za-z0-9_]+$/.test(t);
|
|
11583
|
+
function collectRscText(v, resolve17, sink, seen) {
|
|
11584
|
+
if (v == null) return;
|
|
11585
|
+
if (typeof v === "string") {
|
|
11586
|
+
if (isRscRef(v)) {
|
|
11587
|
+
if (!seen.has(v)) {
|
|
11588
|
+
seen.add(v);
|
|
11589
|
+
collectRscText(resolve17(v), resolve17, sink, seen);
|
|
11590
|
+
}
|
|
11591
|
+
} else if (isHashtag(v)) sink.hashtags.push(v);
|
|
11592
|
+
else if (isVisibleText(v)) sink.text.push(v);
|
|
11593
|
+
return;
|
|
11594
|
+
}
|
|
11595
|
+
if (Array.isArray(v)) {
|
|
11596
|
+
for (const x of v) collectRscText(x, resolve17, sink, seen);
|
|
11597
|
+
return;
|
|
11598
|
+
}
|
|
11599
|
+
if (typeof v === "object") {
|
|
11600
|
+
for (const val of Object.values(v)) {
|
|
11601
|
+
collectRscText(val, resolve17, sink, seen);
|
|
11602
|
+
}
|
|
11603
|
+
}
|
|
11604
|
+
}
|
|
11605
|
+
|
|
11606
|
+
// src/commands/netcap/buildMentionMap.ts
|
|
11607
|
+
function asObject(v) {
|
|
11608
|
+
return v != null && typeof v === "object" && !Array.isArray(v) ? v : void 0;
|
|
11609
|
+
}
|
|
11610
|
+
function profileActionUrl(o) {
|
|
11611
|
+
const actions = asObject(o.action)?.actions;
|
|
11612
|
+
if (!Array.isArray(actions)) return void 0;
|
|
11613
|
+
for (const a of actions) {
|
|
11614
|
+
const url = asObject(asObject(asObject(a)?.value)?.content)?.url;
|
|
11615
|
+
const target = asObject(url)?.url;
|
|
11616
|
+
if (typeof target === "string" && /\/in\//.test(target)) return target;
|
|
11617
|
+
}
|
|
11618
|
+
return void 0;
|
|
11619
|
+
}
|
|
11620
|
+
var slugFromProfileUrl = (url) => url.match(/\/in\/([^/?]+)/)?.[1];
|
|
11621
|
+
function visitObjects(root, fn) {
|
|
11622
|
+
const stack = [root];
|
|
11623
|
+
while (stack.length) {
|
|
11624
|
+
const v = stack.pop();
|
|
11625
|
+
if (v == null || typeof v !== "object") continue;
|
|
11626
|
+
const o = asObject(v);
|
|
11627
|
+
if (o) fn(o);
|
|
11628
|
+
for (const child of Array.isArray(v) ? v : Object.values(v)) {
|
|
11629
|
+
if (child && typeof child === "object") stack.push(child);
|
|
11630
|
+
}
|
|
11631
|
+
}
|
|
11632
|
+
}
|
|
11633
|
+
function buildMentionMap(rows, resolve17) {
|
|
11634
|
+
const map = /* @__PURE__ */ new Map();
|
|
11635
|
+
visitObjects(rows, (o) => {
|
|
11636
|
+
const url = profileActionUrl(o);
|
|
11637
|
+
if (!url || o.children == null) return;
|
|
11638
|
+
const slug = slugFromProfileUrl(url);
|
|
11639
|
+
if (!slug || map.has(slug)) return;
|
|
11640
|
+
const sink = { text: [], hashtags: [] };
|
|
11641
|
+
collectRscText(o.children, resolve17, sink, /* @__PURE__ */ new Set());
|
|
11642
|
+
const name = sink.text.join(" ").replace(/\s+/g, " ").trim();
|
|
11643
|
+
map.set(slug, name ? { slug, name, url } : { slug, url });
|
|
11644
|
+
});
|
|
11645
|
+
return map;
|
|
11646
|
+
}
|
|
11647
|
+
|
|
11648
|
+
// src/commands/netcap/activityUrnDate.ts
|
|
11649
|
+
function activityUrnDate(urn) {
|
|
11650
|
+
if (!urn) return void 0;
|
|
11651
|
+
const id2 = urn.split(":").pop();
|
|
11652
|
+
if (!id2 || !/^\d+$/.test(id2)) return void 0;
|
|
11653
|
+
return new Date(Number(BigInt(id2) >> 22n)).toISOString();
|
|
11654
|
+
}
|
|
11655
|
+
|
|
11656
|
+
// src/commands/netcap/dedupeLinks.ts
|
|
11657
|
+
function decodeSafetyLink(url) {
|
|
11658
|
+
try {
|
|
11659
|
+
const wrapped = new URL(url).searchParams.get("url");
|
|
11660
|
+
return wrapped ? decodeURIComponent(wrapped) : url;
|
|
11661
|
+
} catch {
|
|
11662
|
+
return url;
|
|
11663
|
+
}
|
|
11664
|
+
}
|
|
11665
|
+
function dedupeLinks(links2) {
|
|
11666
|
+
return [
|
|
11667
|
+
...new Set(
|
|
11668
|
+
links2.map((l) => /\/safety\/go\//.test(l) ? decodeSafetyLink(l) : l)
|
|
11669
|
+
)
|
|
11670
|
+
];
|
|
11671
|
+
}
|
|
11672
|
+
|
|
11673
|
+
// src/commands/netcap/linkifyMentions.ts
|
|
11674
|
+
function linkifyMentions(text5, mentions) {
|
|
11675
|
+
let out = text5;
|
|
11676
|
+
for (const m of mentions) {
|
|
11677
|
+
if (m.name && out.includes(m.name)) {
|
|
11678
|
+
out = out.replace(m.name, `[${m.name}](${m.url})`);
|
|
11679
|
+
}
|
|
11680
|
+
}
|
|
11681
|
+
return out;
|
|
11682
|
+
}
|
|
11683
|
+
|
|
11684
|
+
// src/commands/netcap/buildPost.ts
|
|
11685
|
+
var profileUrl = (slug) => `https://www.linkedin.com/in/${slug}/`;
|
|
11686
|
+
var joinText = (parts) => parts.join(" ").replace(/\s+/g, " ").replace(/\s+([.,!?])/g, "$1").trim();
|
|
11687
|
+
function resolveMentions(raw, mentionMap, author) {
|
|
11688
|
+
const slugs = /* @__PURE__ */ new Set();
|
|
11689
|
+
for (const url of raw.profileUrls) {
|
|
11690
|
+
const slug = slugFromProfileUrl(url);
|
|
11691
|
+
if (slug && slug !== author) slugs.add(slug);
|
|
11692
|
+
}
|
|
11693
|
+
return [...slugs].map(
|
|
11694
|
+
(slug) => mentionMap.get(slug) ?? { slug, url: profileUrl(slug) }
|
|
11695
|
+
);
|
|
11696
|
+
}
|
|
11697
|
+
function resolveAuthor(mentionMap, author) {
|
|
11698
|
+
if (!author) return void 0;
|
|
11699
|
+
return mentionMap.get(author) ?? { slug: author, url: profileUrl(author) };
|
|
11700
|
+
}
|
|
11701
|
+
function buildPost(raw, mentionMap, author) {
|
|
11702
|
+
const text5 = joinText(raw.text);
|
|
11703
|
+
if (!text5) return void 0;
|
|
11704
|
+
const mentions = resolveMentions(raw, mentionMap, author);
|
|
11705
|
+
const relatedPosts = [...new Set(raw.related)];
|
|
11706
|
+
return {
|
|
11707
|
+
text: text5,
|
|
11708
|
+
markdown: linkifyMentions(text5, mentions),
|
|
11709
|
+
mentions,
|
|
11710
|
+
hashtags: [...new Set(raw.hashtags)],
|
|
11711
|
+
links: dedupeLinks(raw.links),
|
|
11712
|
+
relatedPosts,
|
|
11713
|
+
activityUrn: relatedPosts[0],
|
|
11714
|
+
postedAt: activityUrnDate(relatedPosts[0]),
|
|
11715
|
+
author: resolveAuthor(mentionMap, author)
|
|
11716
|
+
};
|
|
11717
|
+
}
|
|
11718
|
+
|
|
11719
|
+
// src/commands/netcap/walkPostRow.ts
|
|
11720
|
+
var isCommentary = (o) => asObject(o.viewTrackingSpecs)?.viewName === "feed-commentary";
|
|
11721
|
+
function walkPostRow(v, resolve17, raw) {
|
|
11722
|
+
if (v == null || typeof v !== "object") return;
|
|
11723
|
+
if (Array.isArray(v)) {
|
|
11724
|
+
for (const x of v) walkPostRow(x, resolve17, raw);
|
|
11725
|
+
return;
|
|
11726
|
+
}
|
|
11727
|
+
const o = v;
|
|
11728
|
+
if (o.$type === "proto.sdui.actions.core.NavigateToUrl" && typeof o.url === "string") {
|
|
11729
|
+
if (/\/in\//.test(o.url)) raw.profileUrls.push(o.url);
|
|
11730
|
+
else raw.links.push(o.url);
|
|
11731
|
+
}
|
|
11732
|
+
if (o.$type === "proto.sdui.actions.requests.RequestedArguments") {
|
|
11733
|
+
const a = JSON.stringify(o).match(/urn:li:activity:\d+/);
|
|
11734
|
+
if (a) raw.related.push(a[0]);
|
|
11735
|
+
}
|
|
11736
|
+
if (isCommentary(o)) {
|
|
11737
|
+
const sink = { text: raw.text, hashtags: raw.hashtags };
|
|
11738
|
+
collectRscText(o.children, resolve17, sink, /* @__PURE__ */ new Set());
|
|
11739
|
+
}
|
|
11740
|
+
for (const val of Object.values(o)) walkPostRow(val, resolve17, raw);
|
|
11741
|
+
}
|
|
11742
|
+
|
|
11743
|
+
// src/commands/netcap/extractLinkedInPosts.ts
|
|
11744
|
+
function findAuthorSlug(flight) {
|
|
11745
|
+
return flight.match(/profile-activity-load-([A-Za-z0-9-]+)/)?.[1];
|
|
11746
|
+
}
|
|
11747
|
+
function findCommentaryRows(rows) {
|
|
11748
|
+
return Object.keys(rows).filter(
|
|
11749
|
+
(id2) => /"componentkey":"feed-commentary_/.test(JSON.stringify(rows[id2]))
|
|
11750
|
+
);
|
|
11751
|
+
}
|
|
11752
|
+
function extractLinkedInPosts(flight, author = findAuthorSlug(flight)) {
|
|
11753
|
+
const rows = parseRscRows(flight);
|
|
11754
|
+
const resolve17 = makeRscResolver(rows);
|
|
11755
|
+
const mentionMap = buildMentionMap(rows, resolve17);
|
|
11756
|
+
const posts = [];
|
|
11757
|
+
for (const id2 of findCommentaryRows(rows)) {
|
|
11758
|
+
const raw = {
|
|
11759
|
+
text: [],
|
|
11760
|
+
hashtags: [],
|
|
11761
|
+
profileUrls: [],
|
|
11762
|
+
links: [],
|
|
11763
|
+
related: []
|
|
11764
|
+
};
|
|
11765
|
+
walkPostRow(rows[id2], resolve17, raw);
|
|
11766
|
+
const post = buildPost(raw, mentionMap, author);
|
|
11767
|
+
if (post) posts.push(post);
|
|
11768
|
+
}
|
|
11769
|
+
return posts;
|
|
11770
|
+
}
|
|
11771
|
+
|
|
11772
|
+
// src/commands/netcap/collectVoyagerAttributes.ts
|
|
11773
|
+
function attributeDetails(update3) {
|
|
11774
|
+
const attrs = asObject(asObject(update3.commentary)?.text)?.attributesV2;
|
|
11775
|
+
if (!Array.isArray(attrs)) return [];
|
|
11776
|
+
return attrs.map((a) => asObject(asObject(a)?.detailData)).filter((d) => d !== void 0);
|
|
11777
|
+
}
|
|
11778
|
+
function mentionsFrom(details, profiles, authorSlug) {
|
|
11779
|
+
const bySlug = /* @__PURE__ */ new Map();
|
|
11780
|
+
for (const detail of details) {
|
|
11781
|
+
const urn = detail["*profileMention"];
|
|
11782
|
+
if (typeof urn !== "string") continue;
|
|
11783
|
+
const mention = profiles.get(urn);
|
|
11784
|
+
if (mention && mention.slug !== authorSlug)
|
|
11785
|
+
bySlug.set(mention.slug, mention);
|
|
11786
|
+
}
|
|
11787
|
+
return [...bySlug.values()];
|
|
11788
|
+
}
|
|
11789
|
+
function hashtagsFrom(details) {
|
|
11790
|
+
const tags = [];
|
|
11791
|
+
for (const detail of details) {
|
|
11792
|
+
const urn = detail["*hashtag"];
|
|
11793
|
+
const tag = typeof urn === "string" ? urn.match(/\(([^,]+),/)?.[1] : void 0;
|
|
11794
|
+
if (tag) tags.push(`#${tag}`);
|
|
11795
|
+
}
|
|
11796
|
+
return [...new Set(tags)];
|
|
11797
|
+
}
|
|
11798
|
+
function linksFrom(details) {
|
|
11799
|
+
const links2 = details.map((detail) => asObject(detail.textLink)?.url).filter((url) => typeof url === "string");
|
|
11800
|
+
return dedupeLinks(links2);
|
|
11801
|
+
}
|
|
11802
|
+
function collectVoyagerAttributes(update3, profiles, authorSlug) {
|
|
11803
|
+
const details = attributeDetails(update3);
|
|
11804
|
+
return {
|
|
11805
|
+
mentions: mentionsFrom(details, profiles, authorSlug),
|
|
11806
|
+
hashtags: hashtagsFrom(details),
|
|
11807
|
+
links: linksFrom(details)
|
|
11808
|
+
};
|
|
11809
|
+
}
|
|
11810
|
+
|
|
11811
|
+
// src/commands/netcap/resolveVoyagerAuthor.ts
|
|
11812
|
+
var profileUrl2 = (slug) => `https://www.linkedin.com/in/${slug}/`;
|
|
11813
|
+
function profileSlug(actor) {
|
|
11814
|
+
const target = asObject(actor?.navigationContext)?.actionTarget;
|
|
11815
|
+
if (typeof target !== "string") return void 0;
|
|
11816
|
+
return target.match(/\/in\/([^/?]+)/)?.[1];
|
|
11817
|
+
}
|
|
11818
|
+
function resolveVoyagerAuthor(update3) {
|
|
11819
|
+
const actor = asObject(update3.actor);
|
|
11820
|
+
const slug = profileSlug(actor);
|
|
11821
|
+
if (!slug) return void 0;
|
|
11822
|
+
const name = asObject(actor?.name)?.text;
|
|
11823
|
+
const mention = { slug, url: profileUrl2(slug) };
|
|
11824
|
+
if (typeof name === "string" && name.trim()) mention.name = name.trim();
|
|
11825
|
+
return mention;
|
|
11826
|
+
}
|
|
11827
|
+
|
|
11828
|
+
// src/commands/netcap/buildVoyagerPost.ts
|
|
11829
|
+
function commentaryText(update3) {
|
|
11830
|
+
const body = asObject(asObject(update3.commentary)?.text)?.text;
|
|
11831
|
+
return typeof body === "string" && body.trim() ? body.trim() : void 0;
|
|
11832
|
+
}
|
|
11833
|
+
function activityUrnOf(update3) {
|
|
11834
|
+
const urn = asObject(update3.metadata)?.backendUrn;
|
|
11835
|
+
return typeof urn === "string" ? urn : void 0;
|
|
11836
|
+
}
|
|
11837
|
+
function buildVoyagerPost(update3, profiles) {
|
|
11838
|
+
const text5 = commentaryText(update3);
|
|
11839
|
+
if (!text5) return void 0;
|
|
11840
|
+
const author = resolveVoyagerAuthor(update3);
|
|
11841
|
+
const { mentions, hashtags, links: links2 } = collectVoyagerAttributes(
|
|
11842
|
+
update3,
|
|
11843
|
+
profiles,
|
|
11844
|
+
author?.slug
|
|
11845
|
+
);
|
|
11846
|
+
const activityUrn = activityUrnOf(update3);
|
|
11847
|
+
return {
|
|
11848
|
+
text: text5,
|
|
11849
|
+
markdown: linkifyMentions(text5, mentions),
|
|
11850
|
+
mentions,
|
|
11851
|
+
hashtags,
|
|
11852
|
+
links: links2,
|
|
11853
|
+
relatedPosts: activityUrn ? [activityUrn] : [],
|
|
11854
|
+
activityUrn,
|
|
11855
|
+
postedAt: activityUrnDate(activityUrn),
|
|
11856
|
+
author
|
|
11857
|
+
};
|
|
11858
|
+
}
|
|
11859
|
+
|
|
11860
|
+
// src/commands/netcap/voyagerProfileMentions.ts
|
|
11861
|
+
var PROFILE_TYPE = "com.linkedin.voyager.dash.identity.profile.Profile";
|
|
11862
|
+
var profileUrl3 = (slug) => `https://www.linkedin.com/in/${slug}/`;
|
|
11863
|
+
function profileName(o) {
|
|
11864
|
+
return [o.firstName, o.lastName].filter((s) => typeof s === "string" && s.length > 0).join(" ");
|
|
11865
|
+
}
|
|
11866
|
+
function voyagerProfileMentions(included) {
|
|
11867
|
+
const map = /* @__PURE__ */ new Map();
|
|
11868
|
+
for (const o of included) {
|
|
11869
|
+
const urn = o.entityUrn;
|
|
11870
|
+
const slug = o.publicIdentifier;
|
|
11871
|
+
if (o.$type !== PROFILE_TYPE) continue;
|
|
11872
|
+
if (typeof urn !== "string" || typeof slug !== "string") continue;
|
|
11873
|
+
const name = profileName(o);
|
|
11874
|
+
const url = profileUrl3(slug);
|
|
11875
|
+
map.set(urn, name ? { slug, name, url } : { slug, url });
|
|
11876
|
+
}
|
|
11877
|
+
return map;
|
|
11878
|
+
}
|
|
11879
|
+
|
|
11880
|
+
// src/commands/netcap/extractVoyagerPosts.ts
|
|
11881
|
+
function includedObjects(root) {
|
|
11882
|
+
const included = root.included;
|
|
11883
|
+
if (!Array.isArray(included)) return [];
|
|
11884
|
+
return included.map((item) => asObject(item)).filter((o) => o !== void 0);
|
|
11885
|
+
}
|
|
11886
|
+
function elementUrns(root) {
|
|
11887
|
+
const data = asObject(asObject(root.data)?.data);
|
|
11888
|
+
if (!data) return [];
|
|
11889
|
+
for (const value of Object.values(data)) {
|
|
11890
|
+
const elements = asObject(value)?.["*elements"];
|
|
11891
|
+
if (Array.isArray(elements))
|
|
11892
|
+
return elements.filter((e) => typeof e === "string");
|
|
11893
|
+
}
|
|
11894
|
+
return [];
|
|
11895
|
+
}
|
|
11896
|
+
function extractVoyagerPosts(body) {
|
|
11897
|
+
let root;
|
|
11898
|
+
try {
|
|
11899
|
+
root = JSON.parse(body);
|
|
11900
|
+
} catch {
|
|
11901
|
+
return [];
|
|
11902
|
+
}
|
|
11903
|
+
const rootObj = asObject(root);
|
|
11904
|
+
if (!rootObj) return [];
|
|
11905
|
+
const included = includedObjects(rootObj);
|
|
11906
|
+
const byUrn = /* @__PURE__ */ new Map();
|
|
11907
|
+
for (const o of included) {
|
|
11908
|
+
if (typeof o.entityUrn === "string") byUrn.set(o.entityUrn, o);
|
|
11909
|
+
}
|
|
11910
|
+
const profiles = voyagerProfileMentions(included);
|
|
11911
|
+
const posts = [];
|
|
11912
|
+
for (const ref of elementUrns(rootObj)) {
|
|
11913
|
+
const update3 = byUrn.get(ref);
|
|
11914
|
+
if (!update3) continue;
|
|
11915
|
+
const post = buildVoyagerPost(update3, profiles);
|
|
11916
|
+
if (post) posts.push(post);
|
|
11917
|
+
}
|
|
11918
|
+
return posts;
|
|
11919
|
+
}
|
|
11920
|
+
|
|
11921
|
+
// src/commands/netcap/extractPostsFromCapture.ts
|
|
11922
|
+
function captureEntries(captureFile) {
|
|
11923
|
+
const lines = readFileSync30(captureFile, "utf8").split("\n").filter(Boolean);
|
|
11924
|
+
const entries = [];
|
|
11925
|
+
for (const line of lines) {
|
|
11926
|
+
let entry;
|
|
11927
|
+
try {
|
|
11928
|
+
entry = JSON.parse(line);
|
|
11929
|
+
} catch {
|
|
11930
|
+
continue;
|
|
11931
|
+
}
|
|
11932
|
+
if (typeof entry.url !== "string" || typeof entry.responseBody !== "string")
|
|
11933
|
+
continue;
|
|
11934
|
+
entries.push({ url: entry.url, responseBody: entry.responseBody });
|
|
11935
|
+
}
|
|
11936
|
+
return entries;
|
|
11937
|
+
}
|
|
11938
|
+
function dedupeByActivity(posts) {
|
|
11939
|
+
const byUrn = /* @__PURE__ */ new Map();
|
|
11940
|
+
const noUrn = [];
|
|
11941
|
+
for (const post of posts) {
|
|
11942
|
+
if (!post.activityUrn) {
|
|
11943
|
+
noUrn.push(post);
|
|
11944
|
+
continue;
|
|
11945
|
+
}
|
|
11946
|
+
const existing = byUrn.get(post.activityUrn);
|
|
11947
|
+
if (!existing || post.text.length > existing.text.length)
|
|
11948
|
+
byUrn.set(post.activityUrn, post);
|
|
11949
|
+
}
|
|
11950
|
+
return [...byUrn.values(), ...noUrn];
|
|
11951
|
+
}
|
|
11952
|
+
function extractPostsFromCapture(captureFile) {
|
|
11953
|
+
const entries = captureEntries(captureFile);
|
|
11954
|
+
const rscBodies = entries.filter((e) => /rsc-action/.test(e.url)).map((e) => e.responseBody);
|
|
11955
|
+
const voyagerBodies = entries.filter((e) => /voyagerFeedDashProfileUpdates/.test(e.url)).map((e) => e.responseBody);
|
|
11956
|
+
const author = rscBodies.map(findAuthorSlug).find(Boolean);
|
|
11957
|
+
const all = [
|
|
11958
|
+
...rscBodies.flatMap((body) => extractLinkedInPosts(body, author)),
|
|
11959
|
+
...voyagerBodies.flatMap(extractVoyagerPosts)
|
|
11960
|
+
];
|
|
11961
|
+
return dedupeByActivity(all);
|
|
11962
|
+
}
|
|
11963
|
+
|
|
11964
|
+
// src/commands/netcap/netcapExtract.ts
|
|
11965
|
+
function netcapExtract(file) {
|
|
11966
|
+
const captureFile = file ?? defaultCapturePath();
|
|
11967
|
+
const posts = extractPostsFromCapture(captureFile);
|
|
11968
|
+
const outFile = join38(captureFile, "..", "posts.json");
|
|
11969
|
+
writeFileSync26(outFile, `${JSON.stringify(posts, null, 2)}
|
|
11970
|
+
`);
|
|
11971
|
+
console.log(
|
|
11972
|
+
chalk125.green(`extracted ${posts.length} posts`),
|
|
11973
|
+
chalk125.dim(`-> ${outFile}`)
|
|
11974
|
+
);
|
|
11975
|
+
}
|
|
11976
|
+
|
|
11516
11977
|
// src/commands/registerNetcap.ts
|
|
11517
11978
|
function registerNetcap(program2) {
|
|
11518
|
-
program2.command("netcap").description(
|
|
11979
|
+
const command = program2.command("netcap").description(
|
|
11519
11980
|
"Start a local receiver that captures browser network traffic (fetch/XHR) to a JSONL file via the netcap browser extension"
|
|
11520
|
-
).option("-p, --port <port>", "Port to listen on", "8723").
|
|
11981
|
+
).option("-p, --port <port>", "Port to listen on", "8723").option(
|
|
11982
|
+
"-o, --out <dir>",
|
|
11983
|
+
"Directory to write the capture file into (default ~/.assist/netcap)"
|
|
11984
|
+
).option(
|
|
11985
|
+
"-f, --filter <pattern>",
|
|
11986
|
+
"Only forward requests whose URL contains this substring"
|
|
11987
|
+
).action((options2) => netcap(options2));
|
|
11988
|
+
command.command("extract [file]").description(
|
|
11989
|
+
"Extract LinkedIn posts (text, author, mentions, links) from a netcap capture file to posts.json"
|
|
11990
|
+
).action((file) => netcapExtract(file));
|
|
11521
11991
|
}
|
|
11522
11992
|
|
|
11523
11993
|
// src/commands/news/add/index.ts
|
|
11524
|
-
import
|
|
11994
|
+
import chalk126 from "chalk";
|
|
11525
11995
|
import enquirer8 from "enquirer";
|
|
11526
11996
|
async function add2(url) {
|
|
11527
11997
|
if (!url) {
|
|
@@ -11543,10 +12013,10 @@ async function add2(url) {
|
|
|
11543
12013
|
const { orm } = await getReady();
|
|
11544
12014
|
const added = await addFeed(orm, url);
|
|
11545
12015
|
if (!added) {
|
|
11546
|
-
console.log(
|
|
12016
|
+
console.log(chalk126.yellow("Feed already exists"));
|
|
11547
12017
|
return;
|
|
11548
12018
|
}
|
|
11549
|
-
console.log(
|
|
12019
|
+
console.log(chalk126.green(`Added feed: ${url}`));
|
|
11550
12020
|
}
|
|
11551
12021
|
|
|
11552
12022
|
// src/commands/registerNews.ts
|
|
@@ -11556,7 +12026,7 @@ function registerNews(program2) {
|
|
|
11556
12026
|
}
|
|
11557
12027
|
|
|
11558
12028
|
// src/commands/prompts/printPromptsTable.ts
|
|
11559
|
-
import
|
|
12029
|
+
import chalk127 from "chalk";
|
|
11560
12030
|
function truncate(str, max) {
|
|
11561
12031
|
if (str.length <= max) return str;
|
|
11562
12032
|
return `${str.slice(0, max - 1)}\u2026`;
|
|
@@ -11574,14 +12044,14 @@ function printPromptsTable(rows) {
|
|
|
11574
12044
|
"Command".padEnd(commandWidth),
|
|
11575
12045
|
"Repos"
|
|
11576
12046
|
].join(" ");
|
|
11577
|
-
console.log(
|
|
11578
|
-
console.log(
|
|
12047
|
+
console.log(chalk127.dim(header));
|
|
12048
|
+
console.log(chalk127.dim("-".repeat(header.length)));
|
|
11579
12049
|
for (const row of rows) {
|
|
11580
12050
|
const count6 = String(row.count).padStart(countWidth);
|
|
11581
12051
|
const tool = row.tool.padEnd(toolWidth);
|
|
11582
12052
|
const command = truncate(row.command, 60).padEnd(commandWidth);
|
|
11583
12053
|
console.log(
|
|
11584
|
-
`${
|
|
12054
|
+
`${chalk127.yellow(count6)} ${tool} ${command} ${chalk127.dim(row.repos)}`
|
|
11585
12055
|
);
|
|
11586
12056
|
}
|
|
11587
12057
|
}
|
|
@@ -11929,23 +12399,23 @@ import { execSync as execSync33 } from "child_process";
|
|
|
11929
12399
|
|
|
11930
12400
|
// src/commands/prs/resolveCommentWithReply.ts
|
|
11931
12401
|
import { execSync as execSync32 } from "child_process";
|
|
11932
|
-
import { unlinkSync as unlinkSync10, writeFileSync as
|
|
12402
|
+
import { unlinkSync as unlinkSync10, writeFileSync as writeFileSync27 } from "fs";
|
|
11933
12403
|
import { tmpdir as tmpdir5 } from "os";
|
|
11934
|
-
import { join as
|
|
12404
|
+
import { join as join40 } from "path";
|
|
11935
12405
|
|
|
11936
12406
|
// src/commands/prs/loadCommentsCache.ts
|
|
11937
|
-
import { existsSync as existsSync33, readFileSync as
|
|
11938
|
-
import { join as
|
|
12407
|
+
import { existsSync as existsSync33, readFileSync as readFileSync31, unlinkSync as unlinkSync9 } from "fs";
|
|
12408
|
+
import { join as join39 } from "path";
|
|
11939
12409
|
import { parse as parse2 } from "yaml";
|
|
11940
12410
|
function getCachePath(prNumber) {
|
|
11941
|
-
return
|
|
12411
|
+
return join39(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`);
|
|
11942
12412
|
}
|
|
11943
12413
|
function loadCommentsCache(prNumber) {
|
|
11944
12414
|
const cachePath = getCachePath(prNumber);
|
|
11945
12415
|
if (!existsSync33(cachePath)) {
|
|
11946
12416
|
return null;
|
|
11947
12417
|
}
|
|
11948
|
-
const content =
|
|
12418
|
+
const content = readFileSync31(cachePath, "utf8");
|
|
11949
12419
|
return parse2(content);
|
|
11950
12420
|
}
|
|
11951
12421
|
function deleteCommentsCache(prNumber) {
|
|
@@ -11965,8 +12435,8 @@ function replyToComment(org, repo, prNumber, commentId, message) {
|
|
|
11965
12435
|
}
|
|
11966
12436
|
function resolveThread(threadId) {
|
|
11967
12437
|
const mutation = `mutation($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } }`;
|
|
11968
|
-
const queryFile =
|
|
11969
|
-
|
|
12438
|
+
const queryFile = join40(tmpdir5(), `gh-mutation-${Date.now()}.graphql`);
|
|
12439
|
+
writeFileSync27(queryFile, mutation);
|
|
11970
12440
|
try {
|
|
11971
12441
|
execSync32(
|
|
11972
12442
|
`gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
|
|
@@ -12047,19 +12517,19 @@ function fixed(commentId, sha) {
|
|
|
12047
12517
|
}
|
|
12048
12518
|
|
|
12049
12519
|
// src/commands/prs/listComments/index.ts
|
|
12050
|
-
import { existsSync as existsSync34, mkdirSync as mkdirSync13, writeFileSync as
|
|
12051
|
-
import { join as
|
|
12520
|
+
import { existsSync as existsSync34, mkdirSync as mkdirSync13, writeFileSync as writeFileSync29 } from "fs";
|
|
12521
|
+
import { join as join42 } from "path";
|
|
12052
12522
|
import { stringify } from "yaml";
|
|
12053
12523
|
|
|
12054
12524
|
// src/commands/prs/fetchThreadIds.ts
|
|
12055
12525
|
import { execSync as execSync34 } from "child_process";
|
|
12056
|
-
import { unlinkSync as unlinkSync11, writeFileSync as
|
|
12526
|
+
import { unlinkSync as unlinkSync11, writeFileSync as writeFileSync28 } from "fs";
|
|
12057
12527
|
import { tmpdir as tmpdir6 } from "os";
|
|
12058
|
-
import { join as
|
|
12528
|
+
import { join as join41 } from "path";
|
|
12059
12529
|
var THREAD_QUERY = `query($owner: String!, $repo: String!, $prNumber: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $prNumber) { reviewThreads(first: 100) { nodes { id isResolved comments(first: 100) { nodes { databaseId } } } } } } }`;
|
|
12060
12530
|
function fetchThreadIds(org, repo, prNumber) {
|
|
12061
|
-
const queryFile =
|
|
12062
|
-
|
|
12531
|
+
const queryFile = join41(tmpdir6(), `gh-query-${Date.now()}.graphql`);
|
|
12532
|
+
writeFileSync28(queryFile, THREAD_QUERY);
|
|
12063
12533
|
try {
|
|
12064
12534
|
const result = execSync34(
|
|
12065
12535
|
`gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
|
|
@@ -12127,20 +12597,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
12127
12597
|
}
|
|
12128
12598
|
|
|
12129
12599
|
// src/commands/prs/listComments/printComments.ts
|
|
12130
|
-
import
|
|
12600
|
+
import chalk128 from "chalk";
|
|
12131
12601
|
function formatForHuman(comment3) {
|
|
12132
12602
|
if (comment3.type === "review") {
|
|
12133
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
12603
|
+
const stateColor = comment3.state === "APPROVED" ? chalk128.green : comment3.state === "CHANGES_REQUESTED" ? chalk128.red : chalk128.yellow;
|
|
12134
12604
|
return [
|
|
12135
|
-
`${
|
|
12605
|
+
`${chalk128.cyan("Review")} by ${chalk128.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
12136
12606
|
comment3.body,
|
|
12137
12607
|
""
|
|
12138
12608
|
].join("\n");
|
|
12139
12609
|
}
|
|
12140
12610
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
12141
12611
|
return [
|
|
12142
|
-
`${
|
|
12143
|
-
|
|
12612
|
+
`${chalk128.cyan("Line comment")} by ${chalk128.bold(comment3.user)} on ${chalk128.dim(`${comment3.path}${location}`)}`,
|
|
12613
|
+
chalk128.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
12144
12614
|
comment3.body,
|
|
12145
12615
|
""
|
|
12146
12616
|
].join("\n");
|
|
@@ -12172,7 +12642,7 @@ function printComments2(result) {
|
|
|
12172
12642
|
|
|
12173
12643
|
// src/commands/prs/listComments/index.ts
|
|
12174
12644
|
function writeCommentsCache(prNumber, comments3) {
|
|
12175
|
-
const assistDir =
|
|
12645
|
+
const assistDir = join42(process.cwd(), ".assist");
|
|
12176
12646
|
if (!existsSync34(assistDir)) {
|
|
12177
12647
|
mkdirSync13(assistDir, { recursive: true });
|
|
12178
12648
|
}
|
|
@@ -12181,8 +12651,8 @@ function writeCommentsCache(prNumber, comments3) {
|
|
|
12181
12651
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12182
12652
|
comments: comments3
|
|
12183
12653
|
};
|
|
12184
|
-
const cachePath =
|
|
12185
|
-
|
|
12654
|
+
const cachePath = join42(assistDir, `pr-${prNumber}-comments.yaml`);
|
|
12655
|
+
writeFileSync29(cachePath, stringify(cacheData));
|
|
12186
12656
|
}
|
|
12187
12657
|
function handleKnownErrors(error) {
|
|
12188
12658
|
if (isGhNotInstalled(error)) {
|
|
@@ -12214,7 +12684,7 @@ async function listComments() {
|
|
|
12214
12684
|
];
|
|
12215
12685
|
updateCache(prNumber, allComments);
|
|
12216
12686
|
const hasLineComments = allComments.some((c) => c.type === "line");
|
|
12217
|
-
const cachePath = hasLineComments ?
|
|
12687
|
+
const cachePath = hasLineComments ? join42(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`) : null;
|
|
12218
12688
|
return { comments: allComments, cachePath };
|
|
12219
12689
|
} catch (error) {
|
|
12220
12690
|
const handled = handleKnownErrors(error);
|
|
@@ -12230,13 +12700,13 @@ import { execSync as execSync36 } from "child_process";
|
|
|
12230
12700
|
import enquirer9 from "enquirer";
|
|
12231
12701
|
|
|
12232
12702
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
12233
|
-
import
|
|
12703
|
+
import chalk129 from "chalk";
|
|
12234
12704
|
var STATUS_MAP = {
|
|
12235
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
12236
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
12705
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk129.magenta("merged"), date: pr.mergedAt } : null,
|
|
12706
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk129.red("closed"), date: pr.closedAt } : null
|
|
12237
12707
|
};
|
|
12238
12708
|
function defaultStatus(pr) {
|
|
12239
|
-
return { label:
|
|
12709
|
+
return { label: chalk129.green("opened"), date: pr.createdAt };
|
|
12240
12710
|
}
|
|
12241
12711
|
function getStatus2(pr) {
|
|
12242
12712
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -12245,11 +12715,11 @@ function formatDate(dateStr) {
|
|
|
12245
12715
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
12246
12716
|
}
|
|
12247
12717
|
function formatPrHeader(pr, status2) {
|
|
12248
|
-
return `${
|
|
12718
|
+
return `${chalk129.cyan(`#${pr.number}`)} ${pr.title} ${chalk129.dim(`(${pr.author.login},`)} ${status2.label} ${chalk129.dim(`${formatDate(status2.date)})`)}`;
|
|
12249
12719
|
}
|
|
12250
12720
|
function logPrDetails(pr) {
|
|
12251
12721
|
console.log(
|
|
12252
|
-
|
|
12722
|
+
chalk129.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
12253
12723
|
);
|
|
12254
12724
|
console.log();
|
|
12255
12725
|
}
|
|
@@ -12528,10 +12998,10 @@ function registerPrs(program2) {
|
|
|
12528
12998
|
}
|
|
12529
12999
|
|
|
12530
13000
|
// src/commands/ravendb/ravendbAuth.ts
|
|
12531
|
-
import
|
|
13001
|
+
import chalk135 from "chalk";
|
|
12532
13002
|
|
|
12533
13003
|
// src/shared/createConnectionAuth.ts
|
|
12534
|
-
import
|
|
13004
|
+
import chalk130 from "chalk";
|
|
12535
13005
|
function listConnections(connections, format2) {
|
|
12536
13006
|
if (connections.length === 0) {
|
|
12537
13007
|
console.log("No connections configured.");
|
|
@@ -12544,7 +13014,7 @@ function listConnections(connections, format2) {
|
|
|
12544
13014
|
function removeConnection(connections, name, save) {
|
|
12545
13015
|
const filtered = connections.filter((c) => c.name !== name);
|
|
12546
13016
|
if (filtered.length === connections.length) {
|
|
12547
|
-
console.error(
|
|
13017
|
+
console.error(chalk130.red(`Connection "${name}" not found.`));
|
|
12548
13018
|
process.exit(1);
|
|
12549
13019
|
}
|
|
12550
13020
|
save(filtered);
|
|
@@ -12590,15 +13060,15 @@ function saveConnections(connections) {
|
|
|
12590
13060
|
}
|
|
12591
13061
|
|
|
12592
13062
|
// src/commands/ravendb/promptConnection.ts
|
|
12593
|
-
import
|
|
13063
|
+
import chalk133 from "chalk";
|
|
12594
13064
|
|
|
12595
13065
|
// src/commands/ravendb/selectOpSecret.ts
|
|
12596
|
-
import
|
|
13066
|
+
import chalk132 from "chalk";
|
|
12597
13067
|
import Enquirer2 from "enquirer";
|
|
12598
13068
|
|
|
12599
13069
|
// src/commands/ravendb/searchItems.ts
|
|
12600
13070
|
import { execSync as execSync39 } from "child_process";
|
|
12601
|
-
import
|
|
13071
|
+
import chalk131 from "chalk";
|
|
12602
13072
|
function opExec(args) {
|
|
12603
13073
|
return execSync39(`op ${args}`, {
|
|
12604
13074
|
encoding: "utf8",
|
|
@@ -12611,7 +13081,7 @@ function searchItems(search2) {
|
|
|
12611
13081
|
items2 = JSON.parse(opExec("item list --format=json"));
|
|
12612
13082
|
} catch {
|
|
12613
13083
|
console.error(
|
|
12614
|
-
|
|
13084
|
+
chalk131.red(
|
|
12615
13085
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
12616
13086
|
)
|
|
12617
13087
|
);
|
|
@@ -12625,7 +13095,7 @@ function getItemFields(itemId) {
|
|
|
12625
13095
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
12626
13096
|
return item.fields.filter((f) => f.reference && f.label);
|
|
12627
13097
|
} catch {
|
|
12628
|
-
console.error(
|
|
13098
|
+
console.error(chalk131.red("Failed to get item details from 1Password."));
|
|
12629
13099
|
process.exit(1);
|
|
12630
13100
|
}
|
|
12631
13101
|
}
|
|
@@ -12644,7 +13114,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
12644
13114
|
}).run();
|
|
12645
13115
|
const items2 = searchItems(search2);
|
|
12646
13116
|
if (items2.length === 0) {
|
|
12647
|
-
console.error(
|
|
13117
|
+
console.error(chalk132.red(`No items found matching "${search2}".`));
|
|
12648
13118
|
process.exit(1);
|
|
12649
13119
|
}
|
|
12650
13120
|
const itemId = await selectOne(
|
|
@@ -12653,7 +13123,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
12653
13123
|
);
|
|
12654
13124
|
const fields = getItemFields(itemId);
|
|
12655
13125
|
if (fields.length === 0) {
|
|
12656
|
-
console.error(
|
|
13126
|
+
console.error(chalk132.red("No fields with references found on this item."));
|
|
12657
13127
|
process.exit(1);
|
|
12658
13128
|
}
|
|
12659
13129
|
const ref = await selectOne(
|
|
@@ -12667,7 +13137,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
12667
13137
|
async function promptConnection(existingNames) {
|
|
12668
13138
|
const name = await promptInput("name", "Connection name:");
|
|
12669
13139
|
if (existingNames.includes(name)) {
|
|
12670
|
-
console.error(
|
|
13140
|
+
console.error(chalk133.red(`Connection "${name}" already exists.`));
|
|
12671
13141
|
process.exit(1);
|
|
12672
13142
|
}
|
|
12673
13143
|
const url = await promptInput(
|
|
@@ -12676,22 +13146,22 @@ async function promptConnection(existingNames) {
|
|
|
12676
13146
|
);
|
|
12677
13147
|
const database = await promptInput("database", "Database name:");
|
|
12678
13148
|
if (!name || !url || !database) {
|
|
12679
|
-
console.error(
|
|
13149
|
+
console.error(chalk133.red("All fields are required."));
|
|
12680
13150
|
process.exit(1);
|
|
12681
13151
|
}
|
|
12682
13152
|
const apiKeyRef = await selectOpSecret();
|
|
12683
|
-
console.log(
|
|
13153
|
+
console.log(chalk133.dim(`Using: ${apiKeyRef}`));
|
|
12684
13154
|
return { name, url, database, apiKeyRef };
|
|
12685
13155
|
}
|
|
12686
13156
|
|
|
12687
13157
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
12688
|
-
import
|
|
13158
|
+
import chalk134 from "chalk";
|
|
12689
13159
|
function ravendbSetConnection(name) {
|
|
12690
13160
|
const raw = loadGlobalConfigRaw();
|
|
12691
13161
|
const ravendb = raw.ravendb ?? {};
|
|
12692
13162
|
const connections = ravendb.connections ?? [];
|
|
12693
13163
|
if (!connections.some((c) => c.name === name)) {
|
|
12694
|
-
console.error(
|
|
13164
|
+
console.error(chalk134.red(`Connection "${name}" not found.`));
|
|
12695
13165
|
console.error(
|
|
12696
13166
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
12697
13167
|
);
|
|
@@ -12707,16 +13177,16 @@ function ravendbSetConnection(name) {
|
|
|
12707
13177
|
var ravendbAuth = createConnectionAuth({
|
|
12708
13178
|
load: loadConnections,
|
|
12709
13179
|
save: saveConnections,
|
|
12710
|
-
format: (c) => `${
|
|
13180
|
+
format: (c) => `${chalk135.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
12711
13181
|
promptNew: promptConnection,
|
|
12712
13182
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
12713
13183
|
});
|
|
12714
13184
|
|
|
12715
13185
|
// src/commands/ravendb/ravendbCollections.ts
|
|
12716
|
-
import
|
|
13186
|
+
import chalk139 from "chalk";
|
|
12717
13187
|
|
|
12718
13188
|
// src/commands/ravendb/ravenFetch.ts
|
|
12719
|
-
import
|
|
13189
|
+
import chalk137 from "chalk";
|
|
12720
13190
|
|
|
12721
13191
|
// src/commands/ravendb/getAccessToken.ts
|
|
12722
13192
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -12753,10 +13223,10 @@ ${errorText}`
|
|
|
12753
13223
|
|
|
12754
13224
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
12755
13225
|
import { execSync as execSync40 } from "child_process";
|
|
12756
|
-
import
|
|
13226
|
+
import chalk136 from "chalk";
|
|
12757
13227
|
function resolveOpSecret(reference) {
|
|
12758
13228
|
if (!reference.startsWith("op://")) {
|
|
12759
|
-
console.error(
|
|
13229
|
+
console.error(chalk136.red(`Invalid secret reference: must start with op://`));
|
|
12760
13230
|
process.exit(1);
|
|
12761
13231
|
}
|
|
12762
13232
|
try {
|
|
@@ -12766,7 +13236,7 @@ function resolveOpSecret(reference) {
|
|
|
12766
13236
|
}).trim();
|
|
12767
13237
|
} catch {
|
|
12768
13238
|
console.error(
|
|
12769
|
-
|
|
13239
|
+
chalk136.red(
|
|
12770
13240
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
12771
13241
|
)
|
|
12772
13242
|
);
|
|
@@ -12793,7 +13263,7 @@ async function ravenFetch(connection, path58) {
|
|
|
12793
13263
|
if (!response.ok) {
|
|
12794
13264
|
const body = await response.text();
|
|
12795
13265
|
console.error(
|
|
12796
|
-
|
|
13266
|
+
chalk137.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
12797
13267
|
);
|
|
12798
13268
|
console.error(body.substring(0, 500));
|
|
12799
13269
|
process.exit(1);
|
|
@@ -12802,7 +13272,7 @@ async function ravenFetch(connection, path58) {
|
|
|
12802
13272
|
}
|
|
12803
13273
|
|
|
12804
13274
|
// src/commands/ravendb/resolveConnection.ts
|
|
12805
|
-
import
|
|
13275
|
+
import chalk138 from "chalk";
|
|
12806
13276
|
function loadRavendb() {
|
|
12807
13277
|
const raw = loadGlobalConfigRaw();
|
|
12808
13278
|
const ravendb = raw.ravendb;
|
|
@@ -12816,7 +13286,7 @@ function resolveConnection(name) {
|
|
|
12816
13286
|
const connectionName = name ?? defaultConnection;
|
|
12817
13287
|
if (!connectionName) {
|
|
12818
13288
|
console.error(
|
|
12819
|
-
|
|
13289
|
+
chalk138.red(
|
|
12820
13290
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
12821
13291
|
)
|
|
12822
13292
|
);
|
|
@@ -12824,7 +13294,7 @@ function resolveConnection(name) {
|
|
|
12824
13294
|
}
|
|
12825
13295
|
const connection = connections.find((c) => c.name === connectionName);
|
|
12826
13296
|
if (!connection) {
|
|
12827
|
-
console.error(
|
|
13297
|
+
console.error(chalk138.red(`Connection "${connectionName}" not found.`));
|
|
12828
13298
|
console.error(
|
|
12829
13299
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
12830
13300
|
);
|
|
@@ -12855,15 +13325,15 @@ async function ravendbCollections(connectionName) {
|
|
|
12855
13325
|
return;
|
|
12856
13326
|
}
|
|
12857
13327
|
for (const c of collections) {
|
|
12858
|
-
console.log(`${
|
|
13328
|
+
console.log(`${chalk139.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
12859
13329
|
}
|
|
12860
13330
|
}
|
|
12861
13331
|
|
|
12862
13332
|
// src/commands/ravendb/ravendbQuery.ts
|
|
12863
|
-
import
|
|
13333
|
+
import chalk141 from "chalk";
|
|
12864
13334
|
|
|
12865
13335
|
// src/commands/ravendb/fetchAllPages.ts
|
|
12866
|
-
import
|
|
13336
|
+
import chalk140 from "chalk";
|
|
12867
13337
|
|
|
12868
13338
|
// src/commands/ravendb/buildQueryPath.ts
|
|
12869
13339
|
function buildQueryPath(opts) {
|
|
@@ -12901,7 +13371,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
12901
13371
|
allResults.push(...results);
|
|
12902
13372
|
start3 += results.length;
|
|
12903
13373
|
process.stderr.write(
|
|
12904
|
-
`\r${
|
|
13374
|
+
`\r${chalk140.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
12905
13375
|
);
|
|
12906
13376
|
if (start3 >= totalResults) break;
|
|
12907
13377
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -12916,7 +13386,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
12916
13386
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
12917
13387
|
const resolved = resolveArgs(connectionName, collection);
|
|
12918
13388
|
if (!resolved.collection && !options2.query) {
|
|
12919
|
-
console.error(
|
|
13389
|
+
console.error(chalk141.red("Provide a collection name or --query filter."));
|
|
12920
13390
|
process.exit(1);
|
|
12921
13391
|
}
|
|
12922
13392
|
const { collection: col } = resolved;
|
|
@@ -12954,7 +13424,7 @@ import { spawn as spawn5 } from "child_process";
|
|
|
12954
13424
|
import * as path28 from "path";
|
|
12955
13425
|
|
|
12956
13426
|
// src/commands/refactor/logViolations.ts
|
|
12957
|
-
import
|
|
13427
|
+
import chalk142 from "chalk";
|
|
12958
13428
|
var DEFAULT_MAX_LINES = 100;
|
|
12959
13429
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
12960
13430
|
if (violations.length === 0) {
|
|
@@ -12963,43 +13433,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
12963
13433
|
}
|
|
12964
13434
|
return;
|
|
12965
13435
|
}
|
|
12966
|
-
console.error(
|
|
13436
|
+
console.error(chalk142.red(`
|
|
12967
13437
|
Refactor check failed:
|
|
12968
13438
|
`));
|
|
12969
|
-
console.error(
|
|
13439
|
+
console.error(chalk142.red(` The following files exceed ${maxLines} lines:
|
|
12970
13440
|
`));
|
|
12971
13441
|
for (const violation of violations) {
|
|
12972
|
-
console.error(
|
|
13442
|
+
console.error(chalk142.red(` ${violation.file} (${violation.lines} lines)`));
|
|
12973
13443
|
}
|
|
12974
13444
|
console.error(
|
|
12975
|
-
|
|
13445
|
+
chalk142.yellow(
|
|
12976
13446
|
`
|
|
12977
13447
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
12978
13448
|
way to refactor it, ignore it with:
|
|
12979
13449
|
`
|
|
12980
13450
|
)
|
|
12981
13451
|
);
|
|
12982
|
-
console.error(
|
|
13452
|
+
console.error(chalk142.gray(` assist refactor ignore <file>
|
|
12983
13453
|
`));
|
|
12984
13454
|
if (process.env.CLAUDECODE) {
|
|
12985
|
-
console.error(
|
|
13455
|
+
console.error(chalk142.cyan(`
|
|
12986
13456
|
## Extracting Code to New Files
|
|
12987
13457
|
`));
|
|
12988
13458
|
console.error(
|
|
12989
|
-
|
|
13459
|
+
chalk142.cyan(
|
|
12990
13460
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
12991
13461
|
`
|
|
12992
13462
|
)
|
|
12993
13463
|
);
|
|
12994
13464
|
console.error(
|
|
12995
|
-
|
|
13465
|
+
chalk142.cyan(
|
|
12996
13466
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
12997
13467
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
12998
13468
|
`
|
|
12999
13469
|
)
|
|
13000
13470
|
);
|
|
13001
13471
|
console.error(
|
|
13002
|
-
|
|
13472
|
+
chalk142.cyan(
|
|
13003
13473
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
13004
13474
|
domains, move it to a common/shared folder.
|
|
13005
13475
|
`
|
|
@@ -13097,7 +13567,7 @@ function getViolations(pattern2, options2 = {}, maxLines = DEFAULT_MAX_LINES) {
|
|
|
13097
13567
|
|
|
13098
13568
|
// src/commands/refactor/check/index.ts
|
|
13099
13569
|
function runScript(script, cwd) {
|
|
13100
|
-
return new Promise((
|
|
13570
|
+
return new Promise((resolve17) => {
|
|
13101
13571
|
const child = spawn5("npm", ["run", script], {
|
|
13102
13572
|
stdio: "pipe",
|
|
13103
13573
|
shell: true,
|
|
@@ -13111,7 +13581,7 @@ function runScript(script, cwd) {
|
|
|
13111
13581
|
output += data.toString();
|
|
13112
13582
|
});
|
|
13113
13583
|
child.on("close", (code) => {
|
|
13114
|
-
|
|
13584
|
+
resolve17({ script, code: code ?? 1, output });
|
|
13115
13585
|
});
|
|
13116
13586
|
});
|
|
13117
13587
|
}
|
|
@@ -13155,7 +13625,7 @@ async function check(pattern2, options2) {
|
|
|
13155
13625
|
|
|
13156
13626
|
// src/commands/refactor/extract/index.ts
|
|
13157
13627
|
import path35 from "path";
|
|
13158
|
-
import
|
|
13628
|
+
import chalk145 from "chalk";
|
|
13159
13629
|
|
|
13160
13630
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
13161
13631
|
import { SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
@@ -13730,23 +14200,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
13730
14200
|
|
|
13731
14201
|
// src/commands/refactor/extract/displayPlan.ts
|
|
13732
14202
|
import path32 from "path";
|
|
13733
|
-
import
|
|
14203
|
+
import chalk143 from "chalk";
|
|
13734
14204
|
function section(title) {
|
|
13735
14205
|
return `
|
|
13736
|
-
${
|
|
14206
|
+
${chalk143.cyan(title)}`;
|
|
13737
14207
|
}
|
|
13738
14208
|
function displayImporters(plan2, cwd) {
|
|
13739
14209
|
if (plan2.importersToUpdate.length === 0) return;
|
|
13740
14210
|
console.log(section("Update importers:"));
|
|
13741
14211
|
for (const imp of plan2.importersToUpdate) {
|
|
13742
14212
|
const rel = path32.relative(cwd, imp.file.getFilePath());
|
|
13743
|
-
console.log(` ${
|
|
14213
|
+
console.log(` ${chalk143.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
13744
14214
|
}
|
|
13745
14215
|
}
|
|
13746
14216
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
13747
|
-
console.log(
|
|
14217
|
+
console.log(chalk143.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
13748
14218
|
`));
|
|
13749
|
-
console.log(` ${
|
|
14219
|
+
console.log(` ${chalk143.cyan("Functions to move:")}`);
|
|
13750
14220
|
for (const name of plan2.extractedNames) {
|
|
13751
14221
|
console.log(` ${name}`);
|
|
13752
14222
|
}
|
|
@@ -13780,7 +14250,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
13780
14250
|
|
|
13781
14251
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
13782
14252
|
import path34 from "path";
|
|
13783
|
-
import
|
|
14253
|
+
import chalk144 from "chalk";
|
|
13784
14254
|
import { Project as Project4 } from "ts-morph";
|
|
13785
14255
|
|
|
13786
14256
|
// src/commands/refactor/extract/findTsConfig.ts
|
|
@@ -13840,7 +14310,7 @@ function loadProjectFile(file) {
|
|
|
13840
14310
|
});
|
|
13841
14311
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
13842
14312
|
if (!sourceFile) {
|
|
13843
|
-
console.log(
|
|
14313
|
+
console.log(chalk144.red(`File not found in project: ${file}`));
|
|
13844
14314
|
process.exit(1);
|
|
13845
14315
|
}
|
|
13846
14316
|
return { project, sourceFile };
|
|
@@ -13863,19 +14333,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
13863
14333
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
13864
14334
|
if (options2.apply) {
|
|
13865
14335
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
13866
|
-
console.log(
|
|
14336
|
+
console.log(chalk145.green("\nExtraction complete"));
|
|
13867
14337
|
} else {
|
|
13868
|
-
console.log(
|
|
14338
|
+
console.log(chalk145.dim("\nDry run. Use --apply to execute."));
|
|
13869
14339
|
}
|
|
13870
14340
|
}
|
|
13871
14341
|
|
|
13872
14342
|
// src/commands/refactor/ignore.ts
|
|
13873
14343
|
import fs22 from "fs";
|
|
13874
|
-
import
|
|
14344
|
+
import chalk146 from "chalk";
|
|
13875
14345
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
13876
14346
|
function ignore(file) {
|
|
13877
14347
|
if (!fs22.existsSync(file)) {
|
|
13878
|
-
console.error(
|
|
14348
|
+
console.error(chalk146.red(`Error: File does not exist: ${file}`));
|
|
13879
14349
|
process.exit(1);
|
|
13880
14350
|
}
|
|
13881
14351
|
const content = fs22.readFileSync(file, "utf8");
|
|
@@ -13891,7 +14361,7 @@ function ignore(file) {
|
|
|
13891
14361
|
fs22.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
13892
14362
|
}
|
|
13893
14363
|
console.log(
|
|
13894
|
-
|
|
14364
|
+
chalk146.green(
|
|
13895
14365
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
13896
14366
|
)
|
|
13897
14367
|
);
|
|
@@ -13900,12 +14370,12 @@ function ignore(file) {
|
|
|
13900
14370
|
// src/commands/refactor/rename/index.ts
|
|
13901
14371
|
import fs25 from "fs";
|
|
13902
14372
|
import path40 from "path";
|
|
13903
|
-
import
|
|
14373
|
+
import chalk149 from "chalk";
|
|
13904
14374
|
|
|
13905
14375
|
// src/commands/refactor/rename/applyRename.ts
|
|
13906
14376
|
import fs24 from "fs";
|
|
13907
14377
|
import path37 from "path";
|
|
13908
|
-
import
|
|
14378
|
+
import chalk147 from "chalk";
|
|
13909
14379
|
|
|
13910
14380
|
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
13911
14381
|
import path36 from "path";
|
|
@@ -14010,13 +14480,13 @@ function applyRename(rewrites, sourcePath, destPath, cwd) {
|
|
|
14010
14480
|
const updatedContents = applyRewrites(rewrites);
|
|
14011
14481
|
for (const [file, content] of updatedContents) {
|
|
14012
14482
|
fs24.writeFileSync(file, content, "utf8");
|
|
14013
|
-
console.log(
|
|
14483
|
+
console.log(chalk147.cyan(` Updated imports in ${path37.relative(cwd, file)}`));
|
|
14014
14484
|
}
|
|
14015
14485
|
const destDir = path37.dirname(destPath);
|
|
14016
14486
|
if (!fs24.existsSync(destDir)) fs24.mkdirSync(destDir, { recursive: true });
|
|
14017
14487
|
fs24.renameSync(sourcePath, destPath);
|
|
14018
14488
|
console.log(
|
|
14019
|
-
|
|
14489
|
+
chalk147.white(
|
|
14020
14490
|
` Moved ${path37.relative(cwd, sourcePath)} \u2192 ${path37.relative(cwd, destPath)}`
|
|
14021
14491
|
)
|
|
14022
14492
|
);
|
|
@@ -14103,16 +14573,16 @@ function computeRenameRewrites(sourcePath, destPath) {
|
|
|
14103
14573
|
|
|
14104
14574
|
// src/commands/refactor/rename/printRenamePreview.ts
|
|
14105
14575
|
import path39 from "path";
|
|
14106
|
-
import
|
|
14576
|
+
import chalk148 from "chalk";
|
|
14107
14577
|
function printRenamePreview(rewrites, cwd) {
|
|
14108
14578
|
for (const rewrite of rewrites) {
|
|
14109
14579
|
console.log(
|
|
14110
|
-
|
|
14580
|
+
chalk148.dim(
|
|
14111
14581
|
` ${path39.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
|
|
14112
14582
|
)
|
|
14113
14583
|
);
|
|
14114
14584
|
}
|
|
14115
|
-
console.log(
|
|
14585
|
+
console.log(chalk148.dim("Dry run. Use --apply to execute."));
|
|
14116
14586
|
}
|
|
14117
14587
|
|
|
14118
14588
|
// src/commands/refactor/rename/index.ts
|
|
@@ -14123,20 +14593,20 @@ async function rename(source, destination, options2 = {}) {
|
|
|
14123
14593
|
const relSource = path40.relative(cwd, sourcePath);
|
|
14124
14594
|
const relDest = path40.relative(cwd, destPath);
|
|
14125
14595
|
if (!fs25.existsSync(sourcePath)) {
|
|
14126
|
-
console.log(
|
|
14596
|
+
console.log(chalk149.red(`File not found: ${source}`));
|
|
14127
14597
|
process.exit(1);
|
|
14128
14598
|
}
|
|
14129
14599
|
if (destPath !== sourcePath && fs25.existsSync(destPath)) {
|
|
14130
|
-
console.log(
|
|
14600
|
+
console.log(chalk149.red(`Destination already exists: ${destination}`));
|
|
14131
14601
|
process.exit(1);
|
|
14132
14602
|
}
|
|
14133
|
-
console.log(
|
|
14134
|
-
console.log(
|
|
14135
|
-
console.log(
|
|
14603
|
+
console.log(chalk149.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
14604
|
+
console.log(chalk149.dim("Loading project..."));
|
|
14605
|
+
console.log(chalk149.dim("Scanning imports across the project..."));
|
|
14136
14606
|
const rewrites = computeRenameRewrites(sourcePath, destPath);
|
|
14137
14607
|
const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
|
|
14138
14608
|
console.log(
|
|
14139
|
-
|
|
14609
|
+
chalk149.dim(
|
|
14140
14610
|
`${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
|
|
14141
14611
|
)
|
|
14142
14612
|
);
|
|
@@ -14145,11 +14615,11 @@ async function rename(source, destination, options2 = {}) {
|
|
|
14145
14615
|
return;
|
|
14146
14616
|
}
|
|
14147
14617
|
applyRename(rewrites, sourcePath, destPath, cwd);
|
|
14148
|
-
console.log(
|
|
14618
|
+
console.log(chalk149.green("Done"));
|
|
14149
14619
|
}
|
|
14150
14620
|
|
|
14151
14621
|
// src/commands/refactor/renameSymbol/index.ts
|
|
14152
|
-
import
|
|
14622
|
+
import chalk150 from "chalk";
|
|
14153
14623
|
|
|
14154
14624
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
14155
14625
|
import { SyntaxKind as SyntaxKind14 } from "ts-morph";
|
|
@@ -14195,33 +14665,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
14195
14665
|
const { project, sourceFile } = loadProjectFile(file);
|
|
14196
14666
|
const symbol = findSymbol(sourceFile, oldName);
|
|
14197
14667
|
if (!symbol) {
|
|
14198
|
-
console.log(
|
|
14668
|
+
console.log(chalk150.red(`Symbol "${oldName}" not found in ${file}`));
|
|
14199
14669
|
process.exit(1);
|
|
14200
14670
|
}
|
|
14201
14671
|
const grouped = groupReferences(symbol, cwd);
|
|
14202
14672
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
14203
14673
|
console.log(
|
|
14204
|
-
|
|
14674
|
+
chalk150.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
14205
14675
|
`)
|
|
14206
14676
|
);
|
|
14207
14677
|
for (const [refFile, lines] of grouped) {
|
|
14208
14678
|
console.log(
|
|
14209
|
-
` ${
|
|
14679
|
+
` ${chalk150.dim(refFile)}: lines ${chalk150.cyan(lines.join(", "))}`
|
|
14210
14680
|
);
|
|
14211
14681
|
}
|
|
14212
14682
|
if (options2.apply) {
|
|
14213
14683
|
symbol.rename(newName);
|
|
14214
14684
|
await project.save();
|
|
14215
|
-
console.log(
|
|
14685
|
+
console.log(chalk150.green(`
|
|
14216
14686
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
14217
14687
|
} else {
|
|
14218
|
-
console.log(
|
|
14688
|
+
console.log(chalk150.dim("\nDry run. Use --apply to execute."));
|
|
14219
14689
|
}
|
|
14220
14690
|
}
|
|
14221
14691
|
|
|
14222
14692
|
// src/commands/refactor/restructure/index.ts
|
|
14223
14693
|
import path48 from "path";
|
|
14224
|
-
import
|
|
14694
|
+
import chalk153 from "chalk";
|
|
14225
14695
|
|
|
14226
14696
|
// src/commands/refactor/restructure/clusterDirectories.ts
|
|
14227
14697
|
import path42 from "path";
|
|
@@ -14300,50 +14770,50 @@ function clusterFiles(graph) {
|
|
|
14300
14770
|
|
|
14301
14771
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
14302
14772
|
import path44 from "path";
|
|
14303
|
-
import
|
|
14773
|
+
import chalk151 from "chalk";
|
|
14304
14774
|
function relPath(filePath) {
|
|
14305
14775
|
return path44.relative(process.cwd(), filePath);
|
|
14306
14776
|
}
|
|
14307
14777
|
function displayMoves(plan2) {
|
|
14308
14778
|
if (plan2.moves.length === 0) return;
|
|
14309
|
-
console.log(
|
|
14779
|
+
console.log(chalk151.bold("\nFile moves:"));
|
|
14310
14780
|
for (const move of plan2.moves) {
|
|
14311
14781
|
console.log(
|
|
14312
|
-
` ${
|
|
14782
|
+
` ${chalk151.red(relPath(move.from))} \u2192 ${chalk151.green(relPath(move.to))}`
|
|
14313
14783
|
);
|
|
14314
|
-
console.log(
|
|
14784
|
+
console.log(chalk151.dim(` ${move.reason}`));
|
|
14315
14785
|
}
|
|
14316
14786
|
}
|
|
14317
14787
|
function displayRewrites(rewrites) {
|
|
14318
14788
|
if (rewrites.length === 0) return;
|
|
14319
14789
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
14320
|
-
console.log(
|
|
14790
|
+
console.log(chalk151.bold(`
|
|
14321
14791
|
Import rewrites (${affectedFiles.size} files):`));
|
|
14322
14792
|
for (const file of affectedFiles) {
|
|
14323
|
-
console.log(` ${
|
|
14793
|
+
console.log(` ${chalk151.cyan(relPath(file))}:`);
|
|
14324
14794
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
14325
14795
|
(r) => r.file === file
|
|
14326
14796
|
)) {
|
|
14327
14797
|
console.log(
|
|
14328
|
-
` ${
|
|
14798
|
+
` ${chalk151.red(`"${oldSpecifier}"`)} \u2192 ${chalk151.green(`"${newSpecifier}"`)}`
|
|
14329
14799
|
);
|
|
14330
14800
|
}
|
|
14331
14801
|
}
|
|
14332
14802
|
}
|
|
14333
14803
|
function displayPlan2(plan2) {
|
|
14334
14804
|
if (plan2.warnings.length > 0) {
|
|
14335
|
-
console.log(
|
|
14336
|
-
for (const w of plan2.warnings) console.log(
|
|
14805
|
+
console.log(chalk151.yellow("\nWarnings:"));
|
|
14806
|
+
for (const w of plan2.warnings) console.log(chalk151.yellow(` ${w}`));
|
|
14337
14807
|
}
|
|
14338
14808
|
if (plan2.newDirectories.length > 0) {
|
|
14339
|
-
console.log(
|
|
14809
|
+
console.log(chalk151.bold("\nNew directories:"));
|
|
14340
14810
|
for (const dir of plan2.newDirectories)
|
|
14341
|
-
console.log(
|
|
14811
|
+
console.log(chalk151.green(` ${dir}/`));
|
|
14342
14812
|
}
|
|
14343
14813
|
displayMoves(plan2);
|
|
14344
14814
|
displayRewrites(plan2.rewrites);
|
|
14345
14815
|
console.log(
|
|
14346
|
-
|
|
14816
|
+
chalk151.dim(
|
|
14347
14817
|
`
|
|
14348
14818
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
14349
14819
|
)
|
|
@@ -14353,18 +14823,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
14353
14823
|
// src/commands/refactor/restructure/executePlan.ts
|
|
14354
14824
|
import fs26 from "fs";
|
|
14355
14825
|
import path45 from "path";
|
|
14356
|
-
import
|
|
14826
|
+
import chalk152 from "chalk";
|
|
14357
14827
|
function executePlan(plan2) {
|
|
14358
14828
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
14359
14829
|
for (const [file, content] of updatedContents) {
|
|
14360
14830
|
fs26.writeFileSync(file, content, "utf8");
|
|
14361
14831
|
console.log(
|
|
14362
|
-
|
|
14832
|
+
chalk152.cyan(` Rewrote imports in ${path45.relative(process.cwd(), file)}`)
|
|
14363
14833
|
);
|
|
14364
14834
|
}
|
|
14365
14835
|
for (const dir of plan2.newDirectories) {
|
|
14366
14836
|
fs26.mkdirSync(dir, { recursive: true });
|
|
14367
|
-
console.log(
|
|
14837
|
+
console.log(chalk152.green(` Created ${path45.relative(process.cwd(), dir)}/`));
|
|
14368
14838
|
}
|
|
14369
14839
|
for (const move of plan2.moves) {
|
|
14370
14840
|
const targetDir = path45.dirname(move.to);
|
|
@@ -14373,7 +14843,7 @@ function executePlan(plan2) {
|
|
|
14373
14843
|
}
|
|
14374
14844
|
fs26.renameSync(move.from, move.to);
|
|
14375
14845
|
console.log(
|
|
14376
|
-
|
|
14846
|
+
chalk152.white(
|
|
14377
14847
|
` Moved ${path45.relative(process.cwd(), move.from)} \u2192 ${path45.relative(process.cwd(), move.to)}`
|
|
14378
14848
|
)
|
|
14379
14849
|
);
|
|
@@ -14388,7 +14858,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
14388
14858
|
if (entries.length === 0) {
|
|
14389
14859
|
fs26.rmdirSync(dir);
|
|
14390
14860
|
console.log(
|
|
14391
|
-
|
|
14861
|
+
chalk152.dim(
|
|
14392
14862
|
` Removed empty directory ${path45.relative(process.cwd(), dir)}`
|
|
14393
14863
|
)
|
|
14394
14864
|
);
|
|
@@ -14521,22 +14991,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
14521
14991
|
const targetPattern = pattern2 ?? "src";
|
|
14522
14992
|
const files = findSourceFiles2(targetPattern);
|
|
14523
14993
|
if (files.length === 0) {
|
|
14524
|
-
console.log(
|
|
14994
|
+
console.log(chalk153.yellow("No files found matching pattern"));
|
|
14525
14995
|
return;
|
|
14526
14996
|
}
|
|
14527
14997
|
const tsConfigPath = path48.resolve("tsconfig.json");
|
|
14528
14998
|
const plan2 = buildPlan3(files, tsConfigPath);
|
|
14529
14999
|
if (plan2.moves.length === 0) {
|
|
14530
|
-
console.log(
|
|
15000
|
+
console.log(chalk153.green("No restructuring needed"));
|
|
14531
15001
|
return;
|
|
14532
15002
|
}
|
|
14533
15003
|
displayPlan2(plan2);
|
|
14534
15004
|
if (options2.apply) {
|
|
14535
|
-
console.log(
|
|
15005
|
+
console.log(chalk153.bold("\nApplying changes..."));
|
|
14536
15006
|
executePlan(plan2);
|
|
14537
|
-
console.log(
|
|
15007
|
+
console.log(chalk153.green("\nRestructuring complete"));
|
|
14538
15008
|
} else {
|
|
14539
|
-
console.log(
|
|
15009
|
+
console.log(chalk153.dim("\nDry run. Use --apply to execute."));
|
|
14540
15010
|
}
|
|
14541
15011
|
}
|
|
14542
15012
|
|
|
@@ -14692,9 +15162,9 @@ ${annotateDiffWithLineNumbers(context.diff.trimEnd())}
|
|
|
14692
15162
|
|
|
14693
15163
|
// src/commands/review/buildReviewPaths.ts
|
|
14694
15164
|
import { homedir as homedir13 } from "os";
|
|
14695
|
-
import { basename as basename7, join as
|
|
15165
|
+
import { basename as basename7, join as join43 } from "path";
|
|
14696
15166
|
function buildReviewPaths(repoRoot, key) {
|
|
14697
|
-
const reviewDir =
|
|
15167
|
+
const reviewDir = join43(
|
|
14698
15168
|
homedir13(),
|
|
14699
15169
|
".assist",
|
|
14700
15170
|
"reviews",
|
|
@@ -14703,10 +15173,10 @@ function buildReviewPaths(repoRoot, key) {
|
|
|
14703
15173
|
);
|
|
14704
15174
|
return {
|
|
14705
15175
|
reviewDir,
|
|
14706
|
-
requestPath:
|
|
14707
|
-
claudePath:
|
|
14708
|
-
codexPath:
|
|
14709
|
-
synthesisPath:
|
|
15176
|
+
requestPath: join43(reviewDir, "request.md"),
|
|
15177
|
+
claudePath: join43(reviewDir, "claude.md"),
|
|
15178
|
+
codexPath: join43(reviewDir, "codex.md"),
|
|
15179
|
+
synthesisPath: join43(reviewDir, "synthesis.md")
|
|
14710
15180
|
};
|
|
14711
15181
|
}
|
|
14712
15182
|
|
|
@@ -14849,7 +15319,7 @@ function gatherContext() {
|
|
|
14849
15319
|
}
|
|
14850
15320
|
|
|
14851
15321
|
// src/commands/review/postReviewToPr.ts
|
|
14852
|
-
import { readFileSync as
|
|
15322
|
+
import { readFileSync as readFileSync32 } from "fs";
|
|
14853
15323
|
|
|
14854
15324
|
// src/commands/review/parseFindings.ts
|
|
14855
15325
|
var SEVERITIES = ["blocker", "major", "minor", "nit"];
|
|
@@ -15105,18 +15575,18 @@ function partitionFindingsByDiff(findings, index3) {
|
|
|
15105
15575
|
}
|
|
15106
15576
|
|
|
15107
15577
|
// src/commands/review/warnOutOfDiff.ts
|
|
15108
|
-
import
|
|
15578
|
+
import chalk154 from "chalk";
|
|
15109
15579
|
function warnOutOfDiff(outOfDiff) {
|
|
15110
15580
|
if (outOfDiff.length === 0) return;
|
|
15111
15581
|
console.warn(
|
|
15112
|
-
|
|
15582
|
+
chalk154.yellow(
|
|
15113
15583
|
`Skipped ${outOfDiff.length} finding(s) whose lines fall outside the PR diff (GitHub would silently drop these):`
|
|
15114
15584
|
)
|
|
15115
15585
|
);
|
|
15116
15586
|
for (const finding of outOfDiff) {
|
|
15117
15587
|
const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
|
|
15118
15588
|
console.warn(
|
|
15119
|
-
` ${
|
|
15589
|
+
` ${chalk154.yellow("\xB7")} ${finding.title} ${chalk154.dim(
|
|
15120
15590
|
`(${finding.file}:${range})`
|
|
15121
15591
|
)}`
|
|
15122
15592
|
);
|
|
@@ -15135,18 +15605,18 @@ function selectInDiffFindings(lineBound, prDiff) {
|
|
|
15135
15605
|
}
|
|
15136
15606
|
|
|
15137
15607
|
// src/commands/review/warnUnlocated.ts
|
|
15138
|
-
import
|
|
15608
|
+
import chalk155 from "chalk";
|
|
15139
15609
|
function warnUnlocated(unlocated) {
|
|
15140
15610
|
if (unlocated.length === 0) return;
|
|
15141
15611
|
console.warn(
|
|
15142
|
-
|
|
15612
|
+
chalk155.yellow(
|
|
15143
15613
|
`Skipped ${unlocated.length} finding(s) without a parseable file:line:`
|
|
15144
15614
|
)
|
|
15145
15615
|
);
|
|
15146
15616
|
for (const finding of unlocated) {
|
|
15147
|
-
const where = finding.location ||
|
|
15617
|
+
const where = finding.location || chalk155.dim("missing");
|
|
15148
15618
|
console.warn(
|
|
15149
|
-
` ${
|
|
15619
|
+
` ${chalk155.yellow("\xB7")} ${finding.title} ${chalk155.dim(`(${where})`)}`
|
|
15150
15620
|
);
|
|
15151
15621
|
}
|
|
15152
15622
|
}
|
|
@@ -15159,7 +15629,7 @@ async function confirmPost(prNumber, count6, options2) {
|
|
|
15159
15629
|
async function postReviewToPr(synthesisPath, options2) {
|
|
15160
15630
|
const prInfo = fetchPrDiffInfo();
|
|
15161
15631
|
const prNumber = prInfo.prNumber;
|
|
15162
|
-
const markdown =
|
|
15632
|
+
const markdown = readFileSync32(synthesisPath, "utf8");
|
|
15163
15633
|
const findings = parseFindings(markdown);
|
|
15164
15634
|
if (findings.length === 0) {
|
|
15165
15635
|
console.log("Synthesis contains no findings; nothing to post.");
|
|
@@ -15241,7 +15711,7 @@ async function handlePostSynthesis(synthesisPath, options2) {
|
|
|
15241
15711
|
}
|
|
15242
15712
|
|
|
15243
15713
|
// src/commands/review/prepareReviewDir.ts
|
|
15244
|
-
import { existsSync as existsSync35, mkdirSync as mkdirSync14, unlinkSync as unlinkSync12, writeFileSync as
|
|
15714
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync14, unlinkSync as unlinkSync12, writeFileSync as writeFileSync30 } from "fs";
|
|
15245
15715
|
function clearReviewFiles(paths) {
|
|
15246
15716
|
for (const path58 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
|
|
15247
15717
|
if (existsSync35(path58)) unlinkSync12(path58);
|
|
@@ -15250,7 +15720,7 @@ function clearReviewFiles(paths) {
|
|
|
15250
15720
|
function prepareReviewDir(paths, requestBody, force) {
|
|
15251
15721
|
mkdirSync14(paths.reviewDir, { recursive: true });
|
|
15252
15722
|
if (force) clearReviewFiles(paths);
|
|
15253
|
-
|
|
15723
|
+
writeFileSync30(paths.requestPath, requestBody);
|
|
15254
15724
|
}
|
|
15255
15725
|
|
|
15256
15726
|
// src/commands/review/runApplySession.ts
|
|
@@ -15595,7 +16065,7 @@ The review request is at: ${requestPath}
|
|
|
15595
16065
|
}
|
|
15596
16066
|
|
|
15597
16067
|
// src/commands/review/runClaudeReviewer.ts
|
|
15598
|
-
import { writeFileSync as
|
|
16068
|
+
import { writeFileSync as writeFileSync31 } from "fs";
|
|
15599
16069
|
|
|
15600
16070
|
// src/commands/review/finaliseReviewerSpinner.ts
|
|
15601
16071
|
var SUMMARY_MAX_LEN = 80;
|
|
@@ -15853,12 +16323,12 @@ function onCloseResult(ctx, code) {
|
|
|
15853
16323
|
return { ...closed, stderr: ctx.stderr.value, stdout: ctx.stdout.value };
|
|
15854
16324
|
}
|
|
15855
16325
|
function waitForChildExit(ctx) {
|
|
15856
|
-
return new Promise((
|
|
16326
|
+
return new Promise((resolve17) => {
|
|
15857
16327
|
let settled = false;
|
|
15858
16328
|
const settle = (result) => {
|
|
15859
16329
|
if (settled) return;
|
|
15860
16330
|
settled = true;
|
|
15861
|
-
|
|
16331
|
+
resolve17(result);
|
|
15862
16332
|
};
|
|
15863
16333
|
ctx.child.on("error", (err) => settle(onErrorResult(ctx, err)));
|
|
15864
16334
|
ctx.child.on("close", (code) => settle(onCloseResult(ctx, code)));
|
|
@@ -15931,7 +16401,7 @@ async function runClaudeReviewer(spec) {
|
|
|
15931
16401
|
}
|
|
15932
16402
|
});
|
|
15933
16403
|
if (result.exitCode === 0 && finalText)
|
|
15934
|
-
|
|
16404
|
+
writeFileSync31(spec.outputPath, finalText);
|
|
15935
16405
|
return finaliseReviewerRun({ ...spec, command }, spinner, result);
|
|
15936
16406
|
}
|
|
15937
16407
|
|
|
@@ -16043,7 +16513,7 @@ async function runReviewers(reviewDir, claudePath, codexPath, stdinPrompt, optio
|
|
|
16043
16513
|
}
|
|
16044
16514
|
|
|
16045
16515
|
// src/commands/review/synthesise.ts
|
|
16046
|
-
import { readFileSync as
|
|
16516
|
+
import { readFileSync as readFileSync33 } from "fs";
|
|
16047
16517
|
|
|
16048
16518
|
// src/commands/review/buildSynthesisStdin.ts
|
|
16049
16519
|
var SYNTHESIS_PROMPT = `You are consolidating two independent code reviews of the same change. The original review request is in request.md. The two reviews are in claude.md and codex.md in the current working directory.
|
|
@@ -16099,7 +16569,7 @@ Files:
|
|
|
16099
16569
|
|
|
16100
16570
|
// src/commands/review/synthesise.ts
|
|
16101
16571
|
function printSummary2(synthesisPath) {
|
|
16102
|
-
const markdown =
|
|
16572
|
+
const markdown = readFileSync33(synthesisPath, "utf8");
|
|
16103
16573
|
console.log("");
|
|
16104
16574
|
console.log(buildReviewSummary(markdown));
|
|
16105
16575
|
console.log("");
|
|
@@ -16317,7 +16787,7 @@ function registerReview(program2) {
|
|
|
16317
16787
|
}
|
|
16318
16788
|
|
|
16319
16789
|
// src/commands/seq/seqAuth.ts
|
|
16320
|
-
import
|
|
16790
|
+
import chalk157 from "chalk";
|
|
16321
16791
|
|
|
16322
16792
|
// src/commands/seq/loadConnections.ts
|
|
16323
16793
|
function loadConnections2() {
|
|
@@ -16346,10 +16816,10 @@ function setDefaultConnection(name) {
|
|
|
16346
16816
|
}
|
|
16347
16817
|
|
|
16348
16818
|
// src/shared/assertUniqueName.ts
|
|
16349
|
-
import
|
|
16819
|
+
import chalk156 from "chalk";
|
|
16350
16820
|
function assertUniqueName(existingNames, name) {
|
|
16351
16821
|
if (existingNames.includes(name)) {
|
|
16352
|
-
console.error(
|
|
16822
|
+
console.error(chalk156.red(`Connection "${name}" already exists.`));
|
|
16353
16823
|
process.exit(1);
|
|
16354
16824
|
}
|
|
16355
16825
|
}
|
|
@@ -16367,16 +16837,16 @@ async function promptConnection2(existingNames) {
|
|
|
16367
16837
|
var seqAuth = createConnectionAuth({
|
|
16368
16838
|
load: loadConnections2,
|
|
16369
16839
|
save: saveConnections2,
|
|
16370
|
-
format: (c) => `${
|
|
16840
|
+
format: (c) => `${chalk157.bold(c.name)} ${c.url}`,
|
|
16371
16841
|
promptNew: promptConnection2,
|
|
16372
16842
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
16373
16843
|
});
|
|
16374
16844
|
|
|
16375
16845
|
// src/commands/seq/seqQuery.ts
|
|
16376
|
-
import
|
|
16846
|
+
import chalk161 from "chalk";
|
|
16377
16847
|
|
|
16378
16848
|
// src/commands/seq/fetchSeq.ts
|
|
16379
|
-
import
|
|
16849
|
+
import chalk158 from "chalk";
|
|
16380
16850
|
async function fetchSeq(conn, path58, params) {
|
|
16381
16851
|
const url = `${conn.url}${path58}?${params}`;
|
|
16382
16852
|
const response = await fetch(url, {
|
|
@@ -16387,7 +16857,7 @@ async function fetchSeq(conn, path58, params) {
|
|
|
16387
16857
|
});
|
|
16388
16858
|
if (!response.ok) {
|
|
16389
16859
|
const body = await response.text();
|
|
16390
|
-
console.error(
|
|
16860
|
+
console.error(chalk158.red(`Seq returned ${response.status}: ${body}`));
|
|
16391
16861
|
process.exit(1);
|
|
16392
16862
|
}
|
|
16393
16863
|
return response;
|
|
@@ -16446,23 +16916,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
16446
16916
|
}
|
|
16447
16917
|
|
|
16448
16918
|
// src/commands/seq/formatEvent.ts
|
|
16449
|
-
import
|
|
16919
|
+
import chalk159 from "chalk";
|
|
16450
16920
|
function levelColor(level) {
|
|
16451
16921
|
switch (level) {
|
|
16452
16922
|
case "Fatal":
|
|
16453
|
-
return
|
|
16923
|
+
return chalk159.bgRed.white;
|
|
16454
16924
|
case "Error":
|
|
16455
|
-
return
|
|
16925
|
+
return chalk159.red;
|
|
16456
16926
|
case "Warning":
|
|
16457
|
-
return
|
|
16927
|
+
return chalk159.yellow;
|
|
16458
16928
|
case "Information":
|
|
16459
|
-
return
|
|
16929
|
+
return chalk159.cyan;
|
|
16460
16930
|
case "Debug":
|
|
16461
|
-
return
|
|
16931
|
+
return chalk159.gray;
|
|
16462
16932
|
case "Verbose":
|
|
16463
|
-
return
|
|
16933
|
+
return chalk159.dim;
|
|
16464
16934
|
default:
|
|
16465
|
-
return
|
|
16935
|
+
return chalk159.white;
|
|
16466
16936
|
}
|
|
16467
16937
|
}
|
|
16468
16938
|
function levelAbbrev(level) {
|
|
@@ -16503,12 +16973,12 @@ function formatTimestamp(iso) {
|
|
|
16503
16973
|
function formatEvent(event) {
|
|
16504
16974
|
const color = levelColor(event.Level);
|
|
16505
16975
|
const abbrev = levelAbbrev(event.Level);
|
|
16506
|
-
const ts8 =
|
|
16976
|
+
const ts8 = chalk159.dim(formatTimestamp(event.Timestamp));
|
|
16507
16977
|
const msg = renderMessage(event);
|
|
16508
16978
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
16509
16979
|
if (event.Exception) {
|
|
16510
16980
|
for (const line of event.Exception.split("\n")) {
|
|
16511
|
-
lines.push(
|
|
16981
|
+
lines.push(chalk159.red(` ${line}`));
|
|
16512
16982
|
}
|
|
16513
16983
|
}
|
|
16514
16984
|
return lines.join("\n");
|
|
@@ -16541,11 +17011,11 @@ function rejectTimestampFilter(filter) {
|
|
|
16541
17011
|
}
|
|
16542
17012
|
|
|
16543
17013
|
// src/shared/resolveNamedConnection.ts
|
|
16544
|
-
import
|
|
17014
|
+
import chalk160 from "chalk";
|
|
16545
17015
|
function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
|
|
16546
17016
|
if (connections.length === 0) {
|
|
16547
17017
|
console.error(
|
|
16548
|
-
|
|
17018
|
+
chalk160.red(
|
|
16549
17019
|
`No ${kind} connections configured. Run '${authCommand}' first.`
|
|
16550
17020
|
)
|
|
16551
17021
|
);
|
|
@@ -16554,7 +17024,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
|
|
|
16554
17024
|
const target = requested ?? defaultName ?? connections[0].name;
|
|
16555
17025
|
const connection = connections.find((c) => c.name === target);
|
|
16556
17026
|
if (!connection) {
|
|
16557
|
-
console.error(
|
|
17027
|
+
console.error(chalk160.red(`${kind} connection "${target}" not found.`));
|
|
16558
17028
|
process.exit(1);
|
|
16559
17029
|
}
|
|
16560
17030
|
return connection;
|
|
@@ -16583,7 +17053,7 @@ async function seqQuery(filter, options2) {
|
|
|
16583
17053
|
new URLSearchParams({ filter, count: String(count6) })
|
|
16584
17054
|
);
|
|
16585
17055
|
if (events.length === 0) {
|
|
16586
|
-
console.log(
|
|
17056
|
+
console.log(chalk161.yellow("No events found."));
|
|
16587
17057
|
return;
|
|
16588
17058
|
}
|
|
16589
17059
|
if (options2.json) {
|
|
@@ -16594,11 +17064,11 @@ async function seqQuery(filter, options2) {
|
|
|
16594
17064
|
for (const event of chronological) {
|
|
16595
17065
|
console.log(formatEvent(event));
|
|
16596
17066
|
}
|
|
16597
|
-
console.log(
|
|
17067
|
+
console.log(chalk161.dim(`
|
|
16598
17068
|
${events.length} events`));
|
|
16599
17069
|
if (events.length >= count6) {
|
|
16600
17070
|
console.log(
|
|
16601
|
-
|
|
17071
|
+
chalk161.yellow(
|
|
16602
17072
|
`Results limited to ${count6}. Use --count to retrieve more.`
|
|
16603
17073
|
)
|
|
16604
17074
|
);
|
|
@@ -16606,10 +17076,10 @@ ${events.length} events`));
|
|
|
16606
17076
|
}
|
|
16607
17077
|
|
|
16608
17078
|
// src/shared/setNamedDefaultConnection.ts
|
|
16609
|
-
import
|
|
17079
|
+
import chalk162 from "chalk";
|
|
16610
17080
|
function setNamedDefaultConnection(connections, name, setDefault, kind) {
|
|
16611
17081
|
if (!connections.find((c) => c.name === name)) {
|
|
16612
|
-
console.error(
|
|
17082
|
+
console.error(chalk162.red(`Connection "${name}" not found.`));
|
|
16613
17083
|
process.exit(1);
|
|
16614
17084
|
}
|
|
16615
17085
|
setDefault(name);
|
|
@@ -16657,7 +17127,7 @@ function registerSignal(program2) {
|
|
|
16657
17127
|
}
|
|
16658
17128
|
|
|
16659
17129
|
// src/commands/sql/sqlAuth.ts
|
|
16660
|
-
import
|
|
17130
|
+
import chalk164 from "chalk";
|
|
16661
17131
|
|
|
16662
17132
|
// src/commands/sql/loadConnections.ts
|
|
16663
17133
|
function loadConnections3() {
|
|
@@ -16686,7 +17156,7 @@ function setDefaultConnection2(name) {
|
|
|
16686
17156
|
}
|
|
16687
17157
|
|
|
16688
17158
|
// src/commands/sql/promptConnection.ts
|
|
16689
|
-
import
|
|
17159
|
+
import chalk163 from "chalk";
|
|
16690
17160
|
async function promptConnection3(existingNames) {
|
|
16691
17161
|
const name = await promptInput("name", "Connection name:", "default");
|
|
16692
17162
|
assertUniqueName(existingNames, name);
|
|
@@ -16694,7 +17164,7 @@ async function promptConnection3(existingNames) {
|
|
|
16694
17164
|
const portStr = await promptInput("port", "Port:", "1433");
|
|
16695
17165
|
const port = Number.parseInt(portStr, 10);
|
|
16696
17166
|
if (!Number.isFinite(port)) {
|
|
16697
|
-
console.error(
|
|
17167
|
+
console.error(chalk163.red(`Invalid port "${portStr}".`));
|
|
16698
17168
|
process.exit(1);
|
|
16699
17169
|
}
|
|
16700
17170
|
const user = await promptInput("user", "User:");
|
|
@@ -16707,13 +17177,13 @@ async function promptConnection3(existingNames) {
|
|
|
16707
17177
|
var sqlAuth = createConnectionAuth({
|
|
16708
17178
|
load: loadConnections3,
|
|
16709
17179
|
save: saveConnections3,
|
|
16710
|
-
format: (c) => `${
|
|
17180
|
+
format: (c) => `${chalk164.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
|
|
16711
17181
|
promptNew: promptConnection3,
|
|
16712
17182
|
onFirst: (c) => setDefaultConnection2(c.name)
|
|
16713
17183
|
});
|
|
16714
17184
|
|
|
16715
17185
|
// src/commands/sql/printTable.ts
|
|
16716
|
-
import
|
|
17186
|
+
import chalk165 from "chalk";
|
|
16717
17187
|
function formatCell(value) {
|
|
16718
17188
|
if (value === null || value === void 0) return "";
|
|
16719
17189
|
if (value instanceof Date) return value.toISOString();
|
|
@@ -16722,7 +17192,7 @@ function formatCell(value) {
|
|
|
16722
17192
|
}
|
|
16723
17193
|
function printTable(rows) {
|
|
16724
17194
|
if (rows.length === 0) {
|
|
16725
|
-
console.log(
|
|
17195
|
+
console.log(chalk165.yellow("(no rows)"));
|
|
16726
17196
|
return;
|
|
16727
17197
|
}
|
|
16728
17198
|
const columns = Object.keys(rows[0]);
|
|
@@ -16730,13 +17200,13 @@ function printTable(rows) {
|
|
|
16730
17200
|
(col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
|
|
16731
17201
|
);
|
|
16732
17202
|
const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
16733
|
-
console.log(
|
|
16734
|
-
console.log(
|
|
17203
|
+
console.log(chalk165.dim(header));
|
|
17204
|
+
console.log(chalk165.dim("-".repeat(header.length)));
|
|
16735
17205
|
for (const row of rows) {
|
|
16736
17206
|
const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
|
|
16737
17207
|
console.log(line);
|
|
16738
17208
|
}
|
|
16739
|
-
console.log(
|
|
17209
|
+
console.log(chalk165.dim(`
|
|
16740
17210
|
${rows.length} row${rows.length === 1 ? "" : "s"}`));
|
|
16741
17211
|
}
|
|
16742
17212
|
|
|
@@ -16796,7 +17266,7 @@ async function sqlColumns(table, connectionName) {
|
|
|
16796
17266
|
}
|
|
16797
17267
|
|
|
16798
17268
|
// src/commands/sql/sqlMutate.ts
|
|
16799
|
-
import
|
|
17269
|
+
import chalk166 from "chalk";
|
|
16800
17270
|
|
|
16801
17271
|
// src/commands/sql/isMutation.ts
|
|
16802
17272
|
var MUTATION_KEYWORDS = [
|
|
@@ -16830,7 +17300,7 @@ function isMutation(sql6) {
|
|
|
16830
17300
|
async function sqlMutate(query, connectionName) {
|
|
16831
17301
|
if (!isMutation(query)) {
|
|
16832
17302
|
console.error(
|
|
16833
|
-
|
|
17303
|
+
chalk166.red(
|
|
16834
17304
|
"assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
|
|
16835
17305
|
)
|
|
16836
17306
|
);
|
|
@@ -16840,18 +17310,18 @@ async function sqlMutate(query, connectionName) {
|
|
|
16840
17310
|
const pool = await sqlConnect(conn);
|
|
16841
17311
|
try {
|
|
16842
17312
|
const result = await pool.request().query(query);
|
|
16843
|
-
console.log(
|
|
17313
|
+
console.log(chalk166.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
|
|
16844
17314
|
} finally {
|
|
16845
17315
|
await pool.close();
|
|
16846
17316
|
}
|
|
16847
17317
|
}
|
|
16848
17318
|
|
|
16849
17319
|
// src/commands/sql/sqlQuery.ts
|
|
16850
|
-
import
|
|
17320
|
+
import chalk167 from "chalk";
|
|
16851
17321
|
async function sqlQuery(query, connectionName) {
|
|
16852
17322
|
if (isMutation(query)) {
|
|
16853
17323
|
console.error(
|
|
16854
|
-
|
|
17324
|
+
chalk167.red(
|
|
16855
17325
|
"assist sql query refuses mutating statements. Use `assist sql mutate` instead."
|
|
16856
17326
|
)
|
|
16857
17327
|
);
|
|
@@ -16866,7 +17336,7 @@ async function sqlQuery(query, connectionName) {
|
|
|
16866
17336
|
printTable(rows);
|
|
16867
17337
|
} else {
|
|
16868
17338
|
console.log(
|
|
16869
|
-
|
|
17339
|
+
chalk167.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
|
|
16870
17340
|
);
|
|
16871
17341
|
}
|
|
16872
17342
|
} finally {
|
|
@@ -16927,7 +17397,7 @@ function registerSql(program2) {
|
|
|
16927
17397
|
|
|
16928
17398
|
// src/commands/transcript/shared.ts
|
|
16929
17399
|
import { existsSync as existsSync38, readdirSync as readdirSync7, statSync as statSync5 } from "fs";
|
|
16930
|
-
import { basename as basename8, join as
|
|
17400
|
+
import { basename as basename8, join as join44, relative as relative2 } from "path";
|
|
16931
17401
|
import * as readline2 from "readline";
|
|
16932
17402
|
var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
|
|
16933
17403
|
function getDatePrefix(daysOffset = 0) {
|
|
@@ -16945,7 +17415,7 @@ function collectFiles(dir, extension) {
|
|
|
16945
17415
|
if (!existsSync38(dir)) return [];
|
|
16946
17416
|
const results = [];
|
|
16947
17417
|
for (const entry of readdirSync7(dir)) {
|
|
16948
|
-
const fullPath =
|
|
17418
|
+
const fullPath = join44(dir, entry);
|
|
16949
17419
|
if (statSync5(fullPath).isDirectory()) {
|
|
16950
17420
|
results.push(...collectFiles(fullPath, extension));
|
|
16951
17421
|
} else if (entry.endsWith(extension)) {
|
|
@@ -16977,9 +17447,9 @@ function createReadlineInterface() {
|
|
|
16977
17447
|
});
|
|
16978
17448
|
}
|
|
16979
17449
|
function askQuestion(rl, question) {
|
|
16980
|
-
return new Promise((
|
|
17450
|
+
return new Promise((resolve17) => {
|
|
16981
17451
|
rl.question(question, (answer) => {
|
|
16982
|
-
|
|
17452
|
+
resolve17(answer.trim());
|
|
16983
17453
|
});
|
|
16984
17454
|
});
|
|
16985
17455
|
}
|
|
@@ -17042,11 +17512,11 @@ async function configure() {
|
|
|
17042
17512
|
import { existsSync as existsSync40 } from "fs";
|
|
17043
17513
|
|
|
17044
17514
|
// src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
|
|
17045
|
-
import { dirname as dirname22, join as
|
|
17515
|
+
import { dirname as dirname22, join as join46 } from "path";
|
|
17046
17516
|
|
|
17047
17517
|
// src/commands/transcript/format/fixInvalidDatePrefixes/promptForDateFix.ts
|
|
17048
17518
|
import { renameSync as renameSync2 } from "fs";
|
|
17049
|
-
import { join as
|
|
17519
|
+
import { join as join45 } from "path";
|
|
17050
17520
|
async function resolveDate(rl, choice) {
|
|
17051
17521
|
if (choice === "1") return getDatePrefix(0);
|
|
17052
17522
|
if (choice === "2") return getDatePrefix(-1);
|
|
@@ -17061,7 +17531,7 @@ async function resolveDate(rl, choice) {
|
|
|
17061
17531
|
}
|
|
17062
17532
|
function renameWithPrefix(vttDir, vttFile, prefix2) {
|
|
17063
17533
|
const newFilename = `${prefix2}.${vttFile}`;
|
|
17064
|
-
renameSync2(
|
|
17534
|
+
renameSync2(join45(vttDir, vttFile), join45(vttDir, newFilename));
|
|
17065
17535
|
console.log(`Renamed to: ${newFilename}`);
|
|
17066
17536
|
return newFilename;
|
|
17067
17537
|
}
|
|
@@ -17095,12 +17565,12 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
17095
17565
|
const vttFileDir = dirname22(vttFile.absolutePath);
|
|
17096
17566
|
const newFilename = await promptForDateFix(vttFile.filename, vttFileDir);
|
|
17097
17567
|
if (newFilename) {
|
|
17098
|
-
const newRelativePath =
|
|
17568
|
+
const newRelativePath = join46(
|
|
17099
17569
|
dirname22(vttFile.relativePath),
|
|
17100
17570
|
newFilename
|
|
17101
17571
|
);
|
|
17102
17572
|
vttFiles[i] = {
|
|
17103
|
-
absolutePath:
|
|
17573
|
+
absolutePath: join46(vttFileDir, newFilename),
|
|
17104
17574
|
relativePath: newRelativePath,
|
|
17105
17575
|
filename: newFilename
|
|
17106
17576
|
};
|
|
@@ -17113,8 +17583,8 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
17113
17583
|
}
|
|
17114
17584
|
|
|
17115
17585
|
// src/commands/transcript/format/processVttFile/index.ts
|
|
17116
|
-
import { existsSync as existsSync39, mkdirSync as mkdirSync15, readFileSync as
|
|
17117
|
-
import { basename as basename9, dirname as dirname23, join as
|
|
17586
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync15, readFileSync as readFileSync34, writeFileSync as writeFileSync32 } from "fs";
|
|
17587
|
+
import { basename as basename9, dirname as dirname23, join as join47 } from "path";
|
|
17118
17588
|
|
|
17119
17589
|
// src/commands/transcript/cleanText.ts
|
|
17120
17590
|
function cleanText(text5) {
|
|
@@ -17324,17 +17794,17 @@ function toMdFilename(vttFilename) {
|
|
|
17324
17794
|
return `${basename9(vttFilename, ".vtt").replace(/\s*Transcription\s*/g, " ").trim()}.md`;
|
|
17325
17795
|
}
|
|
17326
17796
|
function resolveOutputDir(relativeDir, transcriptsDir) {
|
|
17327
|
-
return relativeDir === "." ? transcriptsDir :
|
|
17797
|
+
return relativeDir === "." ? transcriptsDir : join47(transcriptsDir, relativeDir);
|
|
17328
17798
|
}
|
|
17329
17799
|
function buildOutputPaths(vttFile, transcriptsDir) {
|
|
17330
17800
|
const mdFile = toMdFilename(vttFile.filename);
|
|
17331
17801
|
const relativeDir = dirname23(vttFile.relativePath);
|
|
17332
17802
|
const outputDir = resolveOutputDir(relativeDir, transcriptsDir);
|
|
17333
|
-
const outputPath =
|
|
17803
|
+
const outputPath = join47(outputDir, mdFile);
|
|
17334
17804
|
return { outputDir, outputPath, mdFile, relativeDir };
|
|
17335
17805
|
}
|
|
17336
17806
|
function logSkipped(relativeDir, mdFile) {
|
|
17337
|
-
console.log(`Skipping (already exists): ${
|
|
17807
|
+
console.log(`Skipping (already exists): ${join47(relativeDir, mdFile)}`);
|
|
17338
17808
|
return "skipped";
|
|
17339
17809
|
}
|
|
17340
17810
|
function ensureDirectory(dir, label2) {
|
|
@@ -17361,10 +17831,10 @@ function logReduction(cueCount, messageCount) {
|
|
|
17361
17831
|
}
|
|
17362
17832
|
function readAndParseCues(inputPath) {
|
|
17363
17833
|
console.log(`Reading: ${inputPath}`);
|
|
17364
|
-
return processCues(
|
|
17834
|
+
return processCues(readFileSync34(inputPath, "utf8"));
|
|
17365
17835
|
}
|
|
17366
17836
|
function writeFormatted(outputPath, content) {
|
|
17367
|
-
|
|
17837
|
+
writeFileSync32(outputPath, content, "utf8");
|
|
17368
17838
|
console.log(`Written: ${outputPath}`);
|
|
17369
17839
|
}
|
|
17370
17840
|
function convertVttToMarkdown(inputPath, outputPath) {
|
|
@@ -17433,27 +17903,27 @@ async function format() {
|
|
|
17433
17903
|
|
|
17434
17904
|
// src/commands/transcript/summarise/index.ts
|
|
17435
17905
|
import { existsSync as existsSync42 } from "fs";
|
|
17436
|
-
import { basename as basename10, dirname as dirname25, join as
|
|
17906
|
+
import { basename as basename10, dirname as dirname25, join as join49, relative as relative3 } from "path";
|
|
17437
17907
|
|
|
17438
17908
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
17439
17909
|
import {
|
|
17440
17910
|
existsSync as existsSync41,
|
|
17441
17911
|
mkdirSync as mkdirSync16,
|
|
17442
|
-
readFileSync as
|
|
17912
|
+
readFileSync as readFileSync35,
|
|
17443
17913
|
renameSync as renameSync3,
|
|
17444
17914
|
rmSync as rmSync4
|
|
17445
17915
|
} from "fs";
|
|
17446
|
-
import { dirname as dirname24, join as
|
|
17916
|
+
import { dirname as dirname24, join as join48 } from "path";
|
|
17447
17917
|
|
|
17448
17918
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
17449
|
-
import
|
|
17919
|
+
import chalk168 from "chalk";
|
|
17450
17920
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
17451
17921
|
function validateStagedContent(filename, content) {
|
|
17452
17922
|
const firstLine = content.split("\n")[0];
|
|
17453
17923
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
17454
17924
|
if (!match) {
|
|
17455
17925
|
console.error(
|
|
17456
|
-
|
|
17926
|
+
chalk168.red(
|
|
17457
17927
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
17458
17928
|
)
|
|
17459
17929
|
);
|
|
@@ -17462,7 +17932,7 @@ function validateStagedContent(filename, content) {
|
|
|
17462
17932
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
17463
17933
|
if (!contentAfterLink) {
|
|
17464
17934
|
console.error(
|
|
17465
|
-
|
|
17935
|
+
chalk168.red(
|
|
17466
17936
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
17467
17937
|
)
|
|
17468
17938
|
);
|
|
@@ -17472,7 +17942,7 @@ function validateStagedContent(filename, content) {
|
|
|
17472
17942
|
}
|
|
17473
17943
|
|
|
17474
17944
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
17475
|
-
var STAGING_DIR =
|
|
17945
|
+
var STAGING_DIR = join48(process.cwd(), ".assist", "transcript");
|
|
17476
17946
|
function processStagedFile() {
|
|
17477
17947
|
if (!existsSync41(STAGING_DIR)) {
|
|
17478
17948
|
return false;
|
|
@@ -17483,7 +17953,7 @@ function processStagedFile() {
|
|
|
17483
17953
|
}
|
|
17484
17954
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
17485
17955
|
const stagedFile = stagedFiles[0];
|
|
17486
|
-
const content =
|
|
17956
|
+
const content = readFileSync35(stagedFile.absolutePath, "utf8");
|
|
17487
17957
|
validateStagedContent(stagedFile.filename, content);
|
|
17488
17958
|
const stagedBaseName = getTranscriptBaseName(stagedFile.filename);
|
|
17489
17959
|
const transcriptFiles = findMdFilesRecursive(transcriptsDir);
|
|
@@ -17496,7 +17966,7 @@ function processStagedFile() {
|
|
|
17496
17966
|
);
|
|
17497
17967
|
process.exit(1);
|
|
17498
17968
|
}
|
|
17499
|
-
const destPath =
|
|
17969
|
+
const destPath = join48(summaryDir, matchingTranscript.relativePath);
|
|
17500
17970
|
const destDir = dirname24(destPath);
|
|
17501
17971
|
if (!existsSync41(destDir)) {
|
|
17502
17972
|
mkdirSync16(destDir, { recursive: true });
|
|
@@ -17512,7 +17982,7 @@ function processStagedFile() {
|
|
|
17512
17982
|
// src/commands/transcript/summarise/index.ts
|
|
17513
17983
|
function buildRelativeKey(relativePath, baseName) {
|
|
17514
17984
|
const relDir = dirname25(relativePath);
|
|
17515
|
-
return relDir === "." ? baseName :
|
|
17985
|
+
return relDir === "." ? baseName : join49(relDir, baseName);
|
|
17516
17986
|
}
|
|
17517
17987
|
function buildSummaryIndex(summaryDir) {
|
|
17518
17988
|
const summaryFiles = findMdFilesRecursive(summaryDir);
|
|
@@ -17546,8 +18016,8 @@ function summarise2() {
|
|
|
17546
18016
|
}
|
|
17547
18017
|
const next3 = missing[0];
|
|
17548
18018
|
const outputFilename = `${getTranscriptBaseName(next3.filename)}.md`;
|
|
17549
|
-
const outputPath =
|
|
17550
|
-
const summaryFileDir =
|
|
18019
|
+
const outputPath = join49(STAGING_DIR, outputFilename);
|
|
18020
|
+
const summaryFileDir = join49(summaryDir, dirname25(next3.relativePath));
|
|
17551
18021
|
const relativeTranscriptPath = encodeURI(
|
|
17552
18022
|
relative3(summaryFileDir, next3.absolutePath).replace(/\\/g, "/")
|
|
17553
18023
|
);
|
|
@@ -17597,50 +18067,50 @@ function registerVerify(program2) {
|
|
|
17597
18067
|
|
|
17598
18068
|
// src/commands/voice/devices.ts
|
|
17599
18069
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
17600
|
-
import { join as
|
|
18070
|
+
import { join as join51 } from "path";
|
|
17601
18071
|
|
|
17602
18072
|
// src/commands/voice/shared.ts
|
|
17603
18073
|
import { homedir as homedir14 } from "os";
|
|
17604
|
-
import { dirname as dirname26, join as
|
|
18074
|
+
import { dirname as dirname26, join as join50 } from "path";
|
|
17605
18075
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
17606
18076
|
var __dirname5 = dirname26(fileURLToPath6(import.meta.url));
|
|
17607
|
-
var VOICE_DIR =
|
|
18077
|
+
var VOICE_DIR = join50(homedir14(), ".assist", "voice");
|
|
17608
18078
|
var voicePaths = {
|
|
17609
18079
|
dir: VOICE_DIR,
|
|
17610
|
-
pid:
|
|
17611
|
-
log:
|
|
17612
|
-
venv:
|
|
17613
|
-
lock:
|
|
18080
|
+
pid: join50(VOICE_DIR, "voice.pid"),
|
|
18081
|
+
log: join50(VOICE_DIR, "voice.log"),
|
|
18082
|
+
venv: join50(VOICE_DIR, ".venv"),
|
|
18083
|
+
lock: join50(VOICE_DIR, "voice.lock")
|
|
17614
18084
|
};
|
|
17615
18085
|
function getPythonDir() {
|
|
17616
|
-
return
|
|
18086
|
+
return join50(__dirname5, "commands", "voice", "python");
|
|
17617
18087
|
}
|
|
17618
18088
|
function getVenvPython() {
|
|
17619
|
-
return process.platform === "win32" ?
|
|
18089
|
+
return process.platform === "win32" ? join50(voicePaths.venv, "Scripts", "python.exe") : join50(voicePaths.venv, "bin", "python");
|
|
17620
18090
|
}
|
|
17621
18091
|
function getLockDir() {
|
|
17622
18092
|
const config = loadConfig();
|
|
17623
18093
|
return config.voice?.lockDir ?? VOICE_DIR;
|
|
17624
18094
|
}
|
|
17625
18095
|
function getLockFile() {
|
|
17626
|
-
return
|
|
18096
|
+
return join50(getLockDir(), "voice.lock");
|
|
17627
18097
|
}
|
|
17628
18098
|
|
|
17629
18099
|
// src/commands/voice/devices.ts
|
|
17630
18100
|
function devices() {
|
|
17631
|
-
const script =
|
|
18101
|
+
const script = join51(getPythonDir(), "list_devices.py");
|
|
17632
18102
|
spawnSync5(getVenvPython(), [script], { stdio: "inherit" });
|
|
17633
18103
|
}
|
|
17634
18104
|
|
|
17635
18105
|
// src/commands/voice/logs.ts
|
|
17636
|
-
import { existsSync as existsSync43, readFileSync as
|
|
18106
|
+
import { existsSync as existsSync43, readFileSync as readFileSync36 } from "fs";
|
|
17637
18107
|
function logs(options2) {
|
|
17638
18108
|
if (!existsSync43(voicePaths.log)) {
|
|
17639
18109
|
console.log("No voice log file found");
|
|
17640
18110
|
return;
|
|
17641
18111
|
}
|
|
17642
18112
|
const count6 = Number.parseInt(options2.lines ?? "150", 10);
|
|
17643
|
-
const content =
|
|
18113
|
+
const content = readFileSync36(voicePaths.log, "utf8").trim();
|
|
17644
18114
|
if (!content) {
|
|
17645
18115
|
console.log("Voice log is empty");
|
|
17646
18116
|
return;
|
|
@@ -17663,12 +18133,12 @@ function logs(options2) {
|
|
|
17663
18133
|
// src/commands/voice/setup.ts
|
|
17664
18134
|
import { spawnSync as spawnSync6 } from "child_process";
|
|
17665
18135
|
import { mkdirSync as mkdirSync18 } from "fs";
|
|
17666
|
-
import { join as
|
|
18136
|
+
import { join as join53 } from "path";
|
|
17667
18137
|
|
|
17668
18138
|
// src/commands/voice/checkLockFile.ts
|
|
17669
18139
|
import { execSync as execSync46 } from "child_process";
|
|
17670
|
-
import { existsSync as existsSync44, mkdirSync as mkdirSync17, readFileSync as
|
|
17671
|
-
import { join as
|
|
18140
|
+
import { existsSync as existsSync44, mkdirSync as mkdirSync17, readFileSync as readFileSync37, writeFileSync as writeFileSync33 } from "fs";
|
|
18141
|
+
import { join as join52 } from "path";
|
|
17672
18142
|
function isProcessAlive2(pid) {
|
|
17673
18143
|
try {
|
|
17674
18144
|
process.kill(pid, 0);
|
|
@@ -17681,7 +18151,7 @@ function checkLockFile() {
|
|
|
17681
18151
|
const lockFile = getLockFile();
|
|
17682
18152
|
if (!existsSync44(lockFile)) return;
|
|
17683
18153
|
try {
|
|
17684
|
-
const lock = JSON.parse(
|
|
18154
|
+
const lock = JSON.parse(readFileSync37(lockFile, "utf8"));
|
|
17685
18155
|
if (lock.pid && isProcessAlive2(lock.pid)) {
|
|
17686
18156
|
console.error(
|
|
17687
18157
|
`Voice daemon already running (PID ${lock.pid}, env: ${lock.env}). Stop it first with: assist voice stop`
|
|
@@ -17705,8 +18175,8 @@ function bootstrapVenv() {
|
|
|
17705
18175
|
}
|
|
17706
18176
|
function writeLockFile(pid) {
|
|
17707
18177
|
const lockFile = getLockFile();
|
|
17708
|
-
mkdirSync17(
|
|
17709
|
-
|
|
18178
|
+
mkdirSync17(join52(lockFile, ".."), { recursive: true });
|
|
18179
|
+
writeFileSync33(
|
|
17710
18180
|
lockFile,
|
|
17711
18181
|
JSON.stringify({
|
|
17712
18182
|
pid,
|
|
@@ -17721,7 +18191,7 @@ function setup() {
|
|
|
17721
18191
|
mkdirSync18(voicePaths.dir, { recursive: true });
|
|
17722
18192
|
bootstrapVenv();
|
|
17723
18193
|
console.log("\nDownloading models...\n");
|
|
17724
|
-
const script =
|
|
18194
|
+
const script = join53(getPythonDir(), "setup_models.py");
|
|
17725
18195
|
const result = spawnSync6(getVenvPython(), [script], {
|
|
17726
18196
|
stdio: "inherit",
|
|
17727
18197
|
env: { ...process.env, VOICE_LOG_FILE: voicePaths.log }
|
|
@@ -17734,8 +18204,8 @@ function setup() {
|
|
|
17734
18204
|
|
|
17735
18205
|
// src/commands/voice/start.ts
|
|
17736
18206
|
import { spawn as spawn7 } from "child_process";
|
|
17737
|
-
import { mkdirSync as mkdirSync19, writeFileSync as
|
|
17738
|
-
import { join as
|
|
18207
|
+
import { mkdirSync as mkdirSync19, writeFileSync as writeFileSync34 } from "fs";
|
|
18208
|
+
import { join as join54 } from "path";
|
|
17739
18209
|
|
|
17740
18210
|
// src/commands/voice/buildDaemonEnv.ts
|
|
17741
18211
|
function buildDaemonEnv(options2) {
|
|
@@ -17763,7 +18233,7 @@ function spawnBackground(python, script, env) {
|
|
|
17763
18233
|
console.error("Failed to start voice daemon");
|
|
17764
18234
|
process.exit(1);
|
|
17765
18235
|
}
|
|
17766
|
-
|
|
18236
|
+
writeFileSync34(voicePaths.pid, String(pid));
|
|
17767
18237
|
writeLockFile(pid);
|
|
17768
18238
|
console.log(`Voice daemon started (PID ${pid})`);
|
|
17769
18239
|
}
|
|
@@ -17773,7 +18243,7 @@ function start2(options2) {
|
|
|
17773
18243
|
bootstrapVenv();
|
|
17774
18244
|
const debug = options2.debug || options2.foreground || process.platform === "win32";
|
|
17775
18245
|
const env = buildDaemonEnv({ debug });
|
|
17776
|
-
const script =
|
|
18246
|
+
const script = join54(getPythonDir(), "voice_daemon.py");
|
|
17777
18247
|
const python = getVenvPython();
|
|
17778
18248
|
if (options2.foreground) {
|
|
17779
18249
|
spawnForeground(python, script, env);
|
|
@@ -17783,7 +18253,7 @@ function start2(options2) {
|
|
|
17783
18253
|
}
|
|
17784
18254
|
|
|
17785
18255
|
// src/commands/voice/status.ts
|
|
17786
|
-
import { existsSync as existsSync45, readFileSync as
|
|
18256
|
+
import { existsSync as existsSync45, readFileSync as readFileSync38 } from "fs";
|
|
17787
18257
|
function isProcessAlive3(pid) {
|
|
17788
18258
|
try {
|
|
17789
18259
|
process.kill(pid, 0);
|
|
@@ -17794,7 +18264,7 @@ function isProcessAlive3(pid) {
|
|
|
17794
18264
|
}
|
|
17795
18265
|
function readRecentLogs(count6) {
|
|
17796
18266
|
if (!existsSync45(voicePaths.log)) return [];
|
|
17797
|
-
const lines =
|
|
18267
|
+
const lines = readFileSync38(voicePaths.log, "utf8").trim().split("\n");
|
|
17798
18268
|
return lines.slice(-count6);
|
|
17799
18269
|
}
|
|
17800
18270
|
function status() {
|
|
@@ -17802,7 +18272,7 @@ function status() {
|
|
|
17802
18272
|
console.log("Voice daemon: not running (no PID file)");
|
|
17803
18273
|
return;
|
|
17804
18274
|
}
|
|
17805
|
-
const pid = Number.parseInt(
|
|
18275
|
+
const pid = Number.parseInt(readFileSync38(voicePaths.pid, "utf8").trim(), 10);
|
|
17806
18276
|
const alive = isProcessAlive3(pid);
|
|
17807
18277
|
console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
|
|
17808
18278
|
const recent = readRecentLogs(5);
|
|
@@ -17821,13 +18291,13 @@ function status() {
|
|
|
17821
18291
|
}
|
|
17822
18292
|
|
|
17823
18293
|
// src/commands/voice/stop.ts
|
|
17824
|
-
import { existsSync as existsSync46, readFileSync as
|
|
18294
|
+
import { existsSync as existsSync46, readFileSync as readFileSync39, unlinkSync as unlinkSync15 } from "fs";
|
|
17825
18295
|
function stop2() {
|
|
17826
18296
|
if (!existsSync46(voicePaths.pid)) {
|
|
17827
18297
|
console.log("Voice daemon is not running (no PID file)");
|
|
17828
18298
|
return;
|
|
17829
18299
|
}
|
|
17830
|
-
const pid = Number.parseInt(
|
|
18300
|
+
const pid = Number.parseInt(readFileSync39(voicePaths.pid, "utf8").trim(), 10);
|
|
17831
18301
|
try {
|
|
17832
18302
|
process.kill(pid, "SIGTERM");
|
|
17833
18303
|
console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
|
|
@@ -17859,7 +18329,7 @@ function registerVoice(program2) {
|
|
|
17859
18329
|
|
|
17860
18330
|
// src/commands/roam/auth.ts
|
|
17861
18331
|
import { randomBytes } from "crypto";
|
|
17862
|
-
import
|
|
18332
|
+
import chalk169 from "chalk";
|
|
17863
18333
|
|
|
17864
18334
|
// src/commands/roam/waitForCallback.ts
|
|
17865
18335
|
import { createServer as createServer3 } from "http";
|
|
@@ -17880,7 +18350,7 @@ function extractCode(url, expectedState) {
|
|
|
17880
18350
|
return code;
|
|
17881
18351
|
}
|
|
17882
18352
|
function waitForCallback(port, expectedState) {
|
|
17883
|
-
return new Promise((
|
|
18353
|
+
return new Promise((resolve17, reject) => {
|
|
17884
18354
|
const timeout = setTimeout(() => {
|
|
17885
18355
|
server.close();
|
|
17886
18356
|
reject(new Error("Authorization timed out after 120 seconds"));
|
|
@@ -17897,7 +18367,7 @@ function waitForCallback(port, expectedState) {
|
|
|
17897
18367
|
const code = extractCode(url, expectedState);
|
|
17898
18368
|
respondHtml(res, 200, "Authorization successful!");
|
|
17899
18369
|
server.close();
|
|
17900
|
-
|
|
18370
|
+
resolve17(code);
|
|
17901
18371
|
} catch (error) {
|
|
17902
18372
|
respondHtml(res, 400, error.message);
|
|
17903
18373
|
server.close();
|
|
@@ -17990,13 +18460,13 @@ async function auth() {
|
|
|
17990
18460
|
saveGlobalConfig(config);
|
|
17991
18461
|
const state = randomBytes(16).toString("hex");
|
|
17992
18462
|
console.log(
|
|
17993
|
-
|
|
18463
|
+
chalk169.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
17994
18464
|
);
|
|
17995
|
-
console.log(
|
|
17996
|
-
console.log(
|
|
17997
|
-
console.log(
|
|
18465
|
+
console.log(chalk169.white("http://localhost:14523/callback\n"));
|
|
18466
|
+
console.log(chalk169.blue("Opening browser for authorization..."));
|
|
18467
|
+
console.log(chalk169.dim("Waiting for authorization callback..."));
|
|
17998
18468
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
17999
|
-
console.log(
|
|
18469
|
+
console.log(chalk169.dim("Exchanging code for tokens..."));
|
|
18000
18470
|
const tokens = await exchangeToken({
|
|
18001
18471
|
code,
|
|
18002
18472
|
clientId,
|
|
@@ -18012,14 +18482,14 @@ async function auth() {
|
|
|
18012
18482
|
};
|
|
18013
18483
|
saveGlobalConfig(config);
|
|
18014
18484
|
console.log(
|
|
18015
|
-
|
|
18485
|
+
chalk169.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
18016
18486
|
);
|
|
18017
18487
|
}
|
|
18018
18488
|
|
|
18019
18489
|
// src/commands/roam/postRoamActivity.ts
|
|
18020
18490
|
import { execFileSync as execFileSync7 } from "child_process";
|
|
18021
|
-
import { readdirSync as readdirSync8, readFileSync as
|
|
18022
|
-
import { join as
|
|
18491
|
+
import { readdirSync as readdirSync8, readFileSync as readFileSync40, statSync as statSync6 } from "fs";
|
|
18492
|
+
import { join as join55 } from "path";
|
|
18023
18493
|
function findPortFile(roamDir) {
|
|
18024
18494
|
let entries;
|
|
18025
18495
|
try {
|
|
@@ -18028,7 +18498,7 @@ function findPortFile(roamDir) {
|
|
|
18028
18498
|
return void 0;
|
|
18029
18499
|
}
|
|
18030
18500
|
const candidates = entries.filter((name) => /^roam-local-api(-[^.]+)?\.port$/.test(name)).map((name) => {
|
|
18031
|
-
const path58 =
|
|
18501
|
+
const path58 = join55(roamDir, name);
|
|
18032
18502
|
try {
|
|
18033
18503
|
return { path: path58, mtimeMs: statSync6(path58).mtimeMs };
|
|
18034
18504
|
} catch {
|
|
@@ -18040,11 +18510,11 @@ function findPortFile(roamDir) {
|
|
|
18040
18510
|
function postRoamActivity(app, event) {
|
|
18041
18511
|
const appData = process.env.APPDATA;
|
|
18042
18512
|
if (!appData) return;
|
|
18043
|
-
const portFile = findPortFile(
|
|
18513
|
+
const portFile = findPortFile(join55(appData, "Roam"));
|
|
18044
18514
|
if (!portFile) return;
|
|
18045
18515
|
let port;
|
|
18046
18516
|
try {
|
|
18047
|
-
port =
|
|
18517
|
+
port = readFileSync40(portFile, "utf8").trim();
|
|
18048
18518
|
} catch {
|
|
18049
18519
|
return;
|
|
18050
18520
|
}
|
|
@@ -18088,7 +18558,7 @@ function registerRoam(program2) {
|
|
|
18088
18558
|
}
|
|
18089
18559
|
|
|
18090
18560
|
// src/commands/run/index.ts
|
|
18091
|
-
import { resolve as
|
|
18561
|
+
import { resolve as resolve13 } from "path";
|
|
18092
18562
|
|
|
18093
18563
|
// src/commands/run/findRunConfig.ts
|
|
18094
18564
|
function exitNoRunConfigs() {
|
|
@@ -18187,13 +18657,13 @@ function runPreCommands(pre, cwd) {
|
|
|
18187
18657
|
// src/commands/run/spawnRunCommand.ts
|
|
18188
18658
|
import { execFileSync as execFileSync8, spawn as spawn8 } from "child_process";
|
|
18189
18659
|
import { existsSync as existsSync47 } from "fs";
|
|
18190
|
-
import { dirname as dirname27, join as
|
|
18660
|
+
import { dirname as dirname27, join as join56, resolve as resolve12 } from "path";
|
|
18191
18661
|
function resolveCommand2(command) {
|
|
18192
18662
|
if (process.platform !== "win32" || command !== "bash") return command;
|
|
18193
18663
|
try {
|
|
18194
18664
|
const gitPath = execFileSync8("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
|
|
18195
|
-
const gitRoot =
|
|
18196
|
-
const gitBash =
|
|
18665
|
+
const gitRoot = resolve12(dirname27(gitPath), "..");
|
|
18666
|
+
const gitBash = join56(gitRoot, "bin", "bash.exe");
|
|
18197
18667
|
if (existsSync47(gitBash)) return gitBash;
|
|
18198
18668
|
} catch {
|
|
18199
18669
|
}
|
|
@@ -18240,7 +18710,7 @@ function listRunConfigs(verbose) {
|
|
|
18240
18710
|
}
|
|
18241
18711
|
}
|
|
18242
18712
|
function execRunConfig(config, args) {
|
|
18243
|
-
const cwd = config.cwd ?
|
|
18713
|
+
const cwd = config.cwd ? resolve13(getConfigDir(), config.cwd) : void 0;
|
|
18244
18714
|
if (config.pre) runPreCommands(config.pre, cwd);
|
|
18245
18715
|
const resolved = resolveParams(config.params, args);
|
|
18246
18716
|
spawnRunCommand(
|
|
@@ -18279,8 +18749,8 @@ async function run3(name, args) {
|
|
|
18279
18749
|
}
|
|
18280
18750
|
|
|
18281
18751
|
// src/commands/run/add.ts
|
|
18282
|
-
import { mkdirSync as mkdirSync20, writeFileSync as
|
|
18283
|
-
import { join as
|
|
18752
|
+
import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync35 } from "fs";
|
|
18753
|
+
import { join as join57 } from "path";
|
|
18284
18754
|
|
|
18285
18755
|
// src/commands/run/extractOption.ts
|
|
18286
18756
|
function extractOption(args, flag) {
|
|
@@ -18341,7 +18811,7 @@ function saveNewRunConfig(name, command, args, cwd) {
|
|
|
18341
18811
|
saveConfig(config);
|
|
18342
18812
|
}
|
|
18343
18813
|
function createCommandFile(name) {
|
|
18344
|
-
const dir =
|
|
18814
|
+
const dir = join57(".claude", "commands");
|
|
18345
18815
|
mkdirSync20(dir, { recursive: true });
|
|
18346
18816
|
const content = `---
|
|
18347
18817
|
description: Run ${name}
|
|
@@ -18349,8 +18819,8 @@ description: Run ${name}
|
|
|
18349
18819
|
|
|
18350
18820
|
Run \`assist run ${name} $ARGUMENTS 2>&1\`.
|
|
18351
18821
|
`;
|
|
18352
|
-
const filePath =
|
|
18353
|
-
|
|
18822
|
+
const filePath = join57(dir, `${name}.md`);
|
|
18823
|
+
writeFileSync35(filePath, content);
|
|
18354
18824
|
console.log(`Created command file: ${filePath}`);
|
|
18355
18825
|
}
|
|
18356
18826
|
function add3() {
|
|
@@ -18406,7 +18876,7 @@ function link2() {
|
|
|
18406
18876
|
|
|
18407
18877
|
// src/commands/run/remove.ts
|
|
18408
18878
|
import { existsSync as existsSync48, unlinkSync as unlinkSync16 } from "fs";
|
|
18409
|
-
import { join as
|
|
18879
|
+
import { join as join58 } from "path";
|
|
18410
18880
|
function findRemoveIndex() {
|
|
18411
18881
|
const idx = process.argv.indexOf("remove");
|
|
18412
18882
|
if (idx === -1 || idx + 1 >= process.argv.length) return -1;
|
|
@@ -18421,7 +18891,7 @@ function parseRemoveName() {
|
|
|
18421
18891
|
return process.argv[idx + 1];
|
|
18422
18892
|
}
|
|
18423
18893
|
function deleteCommandFile(name) {
|
|
18424
|
-
const filePath =
|
|
18894
|
+
const filePath = join58(".claude", "commands", `${name}.md`);
|
|
18425
18895
|
if (existsSync48(filePath)) {
|
|
18426
18896
|
unlinkSync16(filePath);
|
|
18427
18897
|
console.log(`Deleted command file: ${filePath}`);
|
|
@@ -18461,10 +18931,10 @@ function registerRun(program2) {
|
|
|
18461
18931
|
|
|
18462
18932
|
// src/commands/screenshot/index.ts
|
|
18463
18933
|
import { execSync as execSync48 } from "child_process";
|
|
18464
|
-
import { existsSync as existsSync49, mkdirSync as mkdirSync21, unlinkSync as unlinkSync17, writeFileSync as
|
|
18934
|
+
import { existsSync as existsSync49, mkdirSync as mkdirSync21, unlinkSync as unlinkSync17, writeFileSync as writeFileSync36 } from "fs";
|
|
18465
18935
|
import { tmpdir as tmpdir7 } from "os";
|
|
18466
|
-
import { join as
|
|
18467
|
-
import
|
|
18936
|
+
import { join as join59, resolve as resolve14 } from "path";
|
|
18937
|
+
import chalk170 from "chalk";
|
|
18468
18938
|
|
|
18469
18939
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
18470
18940
|
var captureWindowPs1 = `
|
|
@@ -18597,11 +19067,11 @@ function buildOutputPath(outputDir, processName) {
|
|
|
18597
19067
|
mkdirSync21(outputDir, { recursive: true });
|
|
18598
19068
|
}
|
|
18599
19069
|
const timestamp2 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
18600
|
-
return
|
|
19070
|
+
return resolve14(outputDir, `${processName}-${timestamp2}.png`);
|
|
18601
19071
|
}
|
|
18602
19072
|
function runPowerShellScript(processName, outputPath) {
|
|
18603
|
-
const scriptPath =
|
|
18604
|
-
|
|
19073
|
+
const scriptPath = join59(tmpdir7(), `assist-screenshot-${Date.now()}.ps1`);
|
|
19074
|
+
writeFileSync36(scriptPath, captureWindowPs1, "utf8");
|
|
18605
19075
|
try {
|
|
18606
19076
|
execSync48(
|
|
18607
19077
|
`powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
|
|
@@ -18613,15 +19083,15 @@ function runPowerShellScript(processName, outputPath) {
|
|
|
18613
19083
|
}
|
|
18614
19084
|
function screenshot(processName) {
|
|
18615
19085
|
const config = loadConfig();
|
|
18616
|
-
const outputDir =
|
|
19086
|
+
const outputDir = resolve14(config.screenshot.outputDir);
|
|
18617
19087
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
18618
|
-
console.log(
|
|
19088
|
+
console.log(chalk170.gray(`Capturing window for process "${processName}" ...`));
|
|
18619
19089
|
try {
|
|
18620
19090
|
runPowerShellScript(processName, outputPath);
|
|
18621
|
-
console.log(
|
|
19091
|
+
console.log(chalk170.green(`Screenshot saved: ${outputPath}`));
|
|
18622
19092
|
} catch (error) {
|
|
18623
19093
|
const msg = error instanceof Error ? error.message : String(error);
|
|
18624
|
-
console.error(
|
|
19094
|
+
console.error(chalk170.red(`Failed to capture screenshot: ${msg}`));
|
|
18625
19095
|
process.exit(1);
|
|
18626
19096
|
}
|
|
18627
19097
|
}
|
|
@@ -18646,10 +19116,10 @@ var STATUS_TIMEOUT_MS = 5e3;
|
|
|
18646
19116
|
function queryDaemon(socket) {
|
|
18647
19117
|
socket.write(`${JSON.stringify({ type: "ping" })}
|
|
18648
19118
|
`);
|
|
18649
|
-
return new Promise((
|
|
19119
|
+
return new Promise((resolve17) => {
|
|
18650
19120
|
const result = { sessions: [] };
|
|
18651
19121
|
const pending = /* @__PURE__ */ new Set(["sessions", "pong"]);
|
|
18652
|
-
const timer = setTimeout(() =>
|
|
19122
|
+
const timer = setTimeout(() => resolve17(result), STATUS_TIMEOUT_MS);
|
|
18653
19123
|
const lines = createInterface4({ input: socket });
|
|
18654
19124
|
lines.on("error", () => {
|
|
18655
19125
|
});
|
|
@@ -18657,7 +19127,7 @@ function queryDaemon(socket) {
|
|
|
18657
19127
|
applyLine(result, pending, line);
|
|
18658
19128
|
if (pending.size === 0) {
|
|
18659
19129
|
clearTimeout(timer);
|
|
18660
|
-
|
|
19130
|
+
resolve17(result);
|
|
18661
19131
|
}
|
|
18662
19132
|
});
|
|
18663
19133
|
});
|
|
@@ -18677,7 +19147,7 @@ function applyLine(result, pending, line) {
|
|
|
18677
19147
|
}
|
|
18678
19148
|
|
|
18679
19149
|
// src/commands/sessions/daemon/reportStolenSocket.ts
|
|
18680
|
-
import { readFileSync as
|
|
19150
|
+
import { readFileSync as readFileSync41 } from "fs";
|
|
18681
19151
|
function reportStolenSocket(socketPid) {
|
|
18682
19152
|
if (!socketPid) return;
|
|
18683
19153
|
const filePid = readPidFile();
|
|
@@ -18689,7 +19159,7 @@ function reportStolenSocket(socketPid) {
|
|
|
18689
19159
|
function readPidFile() {
|
|
18690
19160
|
try {
|
|
18691
19161
|
const pid = Number.parseInt(
|
|
18692
|
-
|
|
19162
|
+
readFileSync41(daemonPaths.pid, "utf8").trim(),
|
|
18693
19163
|
10
|
|
18694
19164
|
);
|
|
18695
19165
|
return Number.isInteger(pid) ? pid : void 0;
|
|
@@ -19431,10 +19901,10 @@ function windowsDaemonHost() {
|
|
|
19431
19901
|
|
|
19432
19902
|
// src/commands/sessions/daemon/connectToWindowsDaemon.ts
|
|
19433
19903
|
function connectToWindowsDaemon() {
|
|
19434
|
-
return new Promise((
|
|
19904
|
+
return new Promise((resolve17, reject) => {
|
|
19435
19905
|
const socket = net2.connect(windowsDaemonPort(), windowsDaemonHost());
|
|
19436
19906
|
socket.setKeepAlive(true, 1e4);
|
|
19437
|
-
socket.once("connect", () =>
|
|
19907
|
+
socket.once("connect", () => resolve17(socket));
|
|
19438
19908
|
socket.once("error", reject);
|
|
19439
19909
|
});
|
|
19440
19910
|
}
|
|
@@ -19511,7 +19981,7 @@ async function waitForWindowsDaemon() {
|
|
|
19511
19981
|
);
|
|
19512
19982
|
}
|
|
19513
19983
|
function delay2(ms) {
|
|
19514
|
-
return new Promise((
|
|
19984
|
+
return new Promise((resolve17) => setTimeout(resolve17, ms));
|
|
19515
19985
|
}
|
|
19516
19986
|
|
|
19517
19987
|
// src/commands/sessions/daemon/defaultConnect.ts
|
|
@@ -19678,7 +20148,7 @@ async function healWindowsDaemon() {
|
|
|
19678
20148
|
daemonLog("windows daemon: auto-heal: stale daemon stopped");
|
|
19679
20149
|
}
|
|
19680
20150
|
function runOnWindowsHost(command, timeoutMs) {
|
|
19681
|
-
return new Promise((
|
|
20151
|
+
return new Promise((resolve17, reject) => {
|
|
19682
20152
|
const child = spawn11("pwsh.exe", ["-Command", command], {
|
|
19683
20153
|
stdio: ["ignore", "pipe", "pipe"]
|
|
19684
20154
|
});
|
|
@@ -19698,7 +20168,7 @@ function runOnWindowsHost(command, timeoutMs) {
|
|
|
19698
20168
|
});
|
|
19699
20169
|
child.on("exit", (code) => {
|
|
19700
20170
|
clearTimeout(timer);
|
|
19701
|
-
if (code === 0)
|
|
20171
|
+
if (code === 0) resolve17();
|
|
19702
20172
|
else
|
|
19703
20173
|
reject(
|
|
19704
20174
|
new Error(
|
|
@@ -20173,7 +20643,7 @@ async function createdSince(filePath, sinceMs) {
|
|
|
20173
20643
|
}
|
|
20174
20644
|
}
|
|
20175
20645
|
function sleep(ms) {
|
|
20176
|
-
return new Promise((
|
|
20646
|
+
return new Promise((resolve17) => setTimeout(resolve17, ms));
|
|
20177
20647
|
}
|
|
20178
20648
|
|
|
20179
20649
|
// src/commands/sessions/daemon/watchForClaudeSessionId.ts
|
|
@@ -20552,10 +21022,10 @@ function handleConnection(socket, manager) {
|
|
|
20552
21022
|
}
|
|
20553
21023
|
|
|
20554
21024
|
// src/commands/sessions/daemon/onListening.ts
|
|
20555
|
-
import { unlinkSync as unlinkSync18, writeFileSync as
|
|
21025
|
+
import { unlinkSync as unlinkSync18, writeFileSync as writeFileSync37 } from "fs";
|
|
20556
21026
|
|
|
20557
21027
|
// src/commands/sessions/daemon/startPidFileWatchdog.ts
|
|
20558
|
-
import { readFileSync as
|
|
21028
|
+
import { readFileSync as readFileSync42 } from "fs";
|
|
20559
21029
|
var WATCHDOG_INTERVAL_MS = 5e3;
|
|
20560
21030
|
function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
|
|
20561
21031
|
const timer = setInterval(() => {
|
|
@@ -20566,7 +21036,7 @@ function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
|
|
|
20566
21036
|
}
|
|
20567
21037
|
function ownsPidFile() {
|
|
20568
21038
|
try {
|
|
20569
|
-
return
|
|
21039
|
+
return readFileSync42(daemonPaths.pid, "utf8").trim() === String(process.pid);
|
|
20570
21040
|
} catch {
|
|
20571
21041
|
return false;
|
|
20572
21042
|
}
|
|
@@ -20574,7 +21044,7 @@ function ownsPidFile() {
|
|
|
20574
21044
|
|
|
20575
21045
|
// src/commands/sessions/daemon/onListening.ts
|
|
20576
21046
|
function onListening(manager, checkAutoExit) {
|
|
20577
|
-
|
|
21047
|
+
writeFileSync37(daemonPaths.pid, String(process.pid));
|
|
20578
21048
|
startPidFileWatchdog(() => {
|
|
20579
21049
|
daemonLog("lost daemon.pid ownership; shutting down sessions and exiting");
|
|
20580
21050
|
manager.shutdown();
|
|
@@ -20708,7 +21178,7 @@ async function setSessionStatus(status2) {
|
|
|
20708
21178
|
|
|
20709
21179
|
// src/commands/sessions/summarise/index.ts
|
|
20710
21180
|
import * as fs35 from "fs";
|
|
20711
|
-
import
|
|
21181
|
+
import chalk171 from "chalk";
|
|
20712
21182
|
|
|
20713
21183
|
// src/commands/sessions/summarise/shared.ts
|
|
20714
21184
|
import * as fs33 from "fs";
|
|
@@ -20862,22 +21332,22 @@ ${firstMessage}`);
|
|
|
20862
21332
|
async function summarise3(options2) {
|
|
20863
21333
|
const files = await discoverSessionFiles();
|
|
20864
21334
|
if (files.length === 0) {
|
|
20865
|
-
console.log(
|
|
21335
|
+
console.log(chalk171.yellow("No sessions found."));
|
|
20866
21336
|
return;
|
|
20867
21337
|
}
|
|
20868
21338
|
const toProcess = selectCandidates(files, options2);
|
|
20869
21339
|
if (toProcess.length === 0) {
|
|
20870
|
-
console.log(
|
|
21340
|
+
console.log(chalk171.green("All sessions already summarised."));
|
|
20871
21341
|
return;
|
|
20872
21342
|
}
|
|
20873
21343
|
console.log(
|
|
20874
|
-
|
|
21344
|
+
chalk171.cyan(
|
|
20875
21345
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
20876
21346
|
)
|
|
20877
21347
|
);
|
|
20878
21348
|
const { succeeded, failed: failed2 } = processSessions(toProcess);
|
|
20879
21349
|
console.log(
|
|
20880
|
-
|
|
21350
|
+
chalk171.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk171.yellow(`, ${failed2} skipped`) : "")
|
|
20881
21351
|
);
|
|
20882
21352
|
}
|
|
20883
21353
|
function selectCandidates(files, options2) {
|
|
@@ -20897,16 +21367,16 @@ function processSessions(files) {
|
|
|
20897
21367
|
let failed2 = 0;
|
|
20898
21368
|
for (let i = 0; i < files.length; i++) {
|
|
20899
21369
|
const file = files[i];
|
|
20900
|
-
process.stdout.write(
|
|
21370
|
+
process.stdout.write(chalk171.dim(` [${i + 1}/${files.length}] `));
|
|
20901
21371
|
const summary = summariseSession(file);
|
|
20902
21372
|
if (summary) {
|
|
20903
21373
|
writeSummary(file, summary);
|
|
20904
21374
|
succeeded++;
|
|
20905
|
-
process.stdout.write(`${
|
|
21375
|
+
process.stdout.write(`${chalk171.green("\u2713")} ${summary}
|
|
20906
21376
|
`);
|
|
20907
21377
|
} else {
|
|
20908
21378
|
failed2++;
|
|
20909
|
-
process.stdout.write(` ${
|
|
21379
|
+
process.stdout.write(` ${chalk171.yellow("skip")}
|
|
20910
21380
|
`);
|
|
20911
21381
|
}
|
|
20912
21382
|
}
|
|
@@ -20924,10 +21394,10 @@ function registerSessions(program2) {
|
|
|
20924
21394
|
}
|
|
20925
21395
|
|
|
20926
21396
|
// src/commands/statusLine.ts
|
|
20927
|
-
import
|
|
21397
|
+
import chalk173 from "chalk";
|
|
20928
21398
|
|
|
20929
21399
|
// src/commands/buildLimitsSegment.ts
|
|
20930
|
-
import
|
|
21400
|
+
import chalk172 from "chalk";
|
|
20931
21401
|
|
|
20932
21402
|
// src/shared/rateLimitLevel.ts
|
|
20933
21403
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
@@ -20958,9 +21428,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
|
|
|
20958
21428
|
|
|
20959
21429
|
// src/commands/buildLimitsSegment.ts
|
|
20960
21430
|
var LEVEL_COLOR = {
|
|
20961
|
-
ok:
|
|
20962
|
-
warn:
|
|
20963
|
-
over:
|
|
21431
|
+
ok: chalk172.green,
|
|
21432
|
+
warn: chalk172.yellow,
|
|
21433
|
+
over: chalk172.red
|
|
20964
21434
|
};
|
|
20965
21435
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
|
|
20966
21436
|
const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
|
|
@@ -21000,14 +21470,14 @@ async function relayRateLimits(rateLimits) {
|
|
|
21000
21470
|
}
|
|
21001
21471
|
|
|
21002
21472
|
// src/commands/statusLine.ts
|
|
21003
|
-
|
|
21473
|
+
chalk173.level = 3;
|
|
21004
21474
|
function formatNumber(num) {
|
|
21005
21475
|
return num.toLocaleString("en-US");
|
|
21006
21476
|
}
|
|
21007
21477
|
function colorizePercent(pct) {
|
|
21008
21478
|
const label2 = `${Math.round(pct)}%`;
|
|
21009
|
-
if (pct > 80) return
|
|
21010
|
-
if (pct > 40) return
|
|
21479
|
+
if (pct > 80) return chalk173.red(label2);
|
|
21480
|
+
if (pct > 40) return chalk173.yellow(label2);
|
|
21011
21481
|
return label2;
|
|
21012
21482
|
}
|
|
21013
21483
|
async function statusLine() {
|
|
@@ -21031,7 +21501,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
21031
21501
|
// src/commands/sync/syncClaudeMd.ts
|
|
21032
21502
|
import * as fs36 from "fs";
|
|
21033
21503
|
import * as path54 from "path";
|
|
21034
|
-
import
|
|
21504
|
+
import chalk174 from "chalk";
|
|
21035
21505
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
21036
21506
|
const source = path54.join(claudeDir, "CLAUDE.md");
|
|
21037
21507
|
const target = path54.join(targetBase, "CLAUDE.md");
|
|
@@ -21040,12 +21510,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
21040
21510
|
const targetContent = fs36.readFileSync(target, "utf8");
|
|
21041
21511
|
if (sourceContent !== targetContent) {
|
|
21042
21512
|
console.log(
|
|
21043
|
-
|
|
21513
|
+
chalk174.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
21044
21514
|
);
|
|
21045
21515
|
console.log();
|
|
21046
21516
|
printDiff(targetContent, sourceContent);
|
|
21047
21517
|
const confirm = options2?.yes || await promptConfirm(
|
|
21048
|
-
|
|
21518
|
+
chalk174.red("Overwrite existing CLAUDE.md?"),
|
|
21049
21519
|
false
|
|
21050
21520
|
);
|
|
21051
21521
|
if (!confirm) {
|
|
@@ -21061,7 +21531,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
21061
21531
|
// src/commands/sync/syncSettings.ts
|
|
21062
21532
|
import * as fs37 from "fs";
|
|
21063
21533
|
import * as path55 from "path";
|
|
21064
|
-
import
|
|
21534
|
+
import chalk175 from "chalk";
|
|
21065
21535
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
21066
21536
|
const source = path55.join(claudeDir, "settings.json");
|
|
21067
21537
|
const target = path55.join(targetBase, "settings.json");
|
|
@@ -21077,14 +21547,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
21077
21547
|
if (mergedContent !== normalizedTarget) {
|
|
21078
21548
|
if (!options2?.yes) {
|
|
21079
21549
|
console.log(
|
|
21080
|
-
|
|
21550
|
+
chalk175.yellow(
|
|
21081
21551
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
21082
21552
|
)
|
|
21083
21553
|
);
|
|
21084
21554
|
console.log();
|
|
21085
21555
|
printDiff(targetContent, mergedContent);
|
|
21086
21556
|
const confirm = await promptConfirm(
|
|
21087
|
-
|
|
21557
|
+
chalk175.red("Overwrite existing settings.json?"),
|
|
21088
21558
|
false
|
|
21089
21559
|
);
|
|
21090
21560
|
if (!confirm) {
|