@staff0rd/assist 0.274.0 → 0.275.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/sessions/web/bundle.js +60 -60
- package/dist/index.js +454 -308
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.275.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -119,10 +119,10 @@ import { stringify as stringifyYaml } from "yaml";
|
|
|
119
119
|
// src/shared/loadRawYaml.ts
|
|
120
120
|
import { existsSync, readFileSync } from "fs";
|
|
121
121
|
import { parse as parseYaml } from "yaml";
|
|
122
|
-
function loadRawYaml(
|
|
123
|
-
if (!existsSync(
|
|
122
|
+
function loadRawYaml(path54) {
|
|
123
|
+
if (!existsSync(path54)) return {};
|
|
124
124
|
try {
|
|
125
|
-
const content = readFileSync(
|
|
125
|
+
const content = readFileSync(path54, "utf-8");
|
|
126
126
|
return parseYaml(content) || {};
|
|
127
127
|
} catch {
|
|
128
128
|
return {};
|
|
@@ -1859,8 +1859,8 @@ var MACHINE_DIRECTIVES = [
|
|
|
1859
1859
|
"v8 ignore",
|
|
1860
1860
|
"c8 ignore"
|
|
1861
1861
|
];
|
|
1862
|
-
function isCommentExempt(
|
|
1863
|
-
const lower =
|
|
1862
|
+
function isCommentExempt(text3, markers) {
|
|
1863
|
+
const lower = text3.toLowerCase();
|
|
1864
1864
|
if (MACHINE_DIRECTIVES.some((d) => lower.includes(d))) return true;
|
|
1865
1865
|
return markers.some((m) => lower.includes(m.toLowerCase()));
|
|
1866
1866
|
}
|
|
@@ -1903,8 +1903,8 @@ function parseDiffAddedLines(diff2) {
|
|
|
1903
1903
|
|
|
1904
1904
|
// src/commands/verify/commentPolicy/findAddedComments.ts
|
|
1905
1905
|
var SOURCE_EXTENSIONS = [".ts", ".tsx", ".cts", ".mts", ".js", ".jsx"];
|
|
1906
|
-
function toSingleLine(
|
|
1907
|
-
return
|
|
1906
|
+
function toSingleLine(text3) {
|
|
1907
|
+
return text3.replace(/\s+/g, " ").trim();
|
|
1908
1908
|
}
|
|
1909
1909
|
function shouldScan(file, ignoreGlobs) {
|
|
1910
1910
|
if (!SOURCE_EXTENSIONS.some((ext) => file.endsWith(ext))) return false;
|
|
@@ -1925,11 +1925,11 @@ function findAddedComments(options2) {
|
|
|
1925
1925
|
for (const [file, lines] of addedLines) {
|
|
1926
1926
|
if (!shouldScan(file, options2.ignoreGlobs)) continue;
|
|
1927
1927
|
const sourceFile = project.addSourceFileAtPath(file);
|
|
1928
|
-
for (const { pos, text:
|
|
1928
|
+
for (const { pos, text: text3 } of collectComments(sourceFile)) {
|
|
1929
1929
|
const { line } = sourceFile.getLineAndColumnAtPos(pos);
|
|
1930
1930
|
if (!lines.has(line)) continue;
|
|
1931
|
-
if (isCommentExempt(
|
|
1932
|
-
findings.push({ file, line, text: toSingleLine(
|
|
1931
|
+
if (isCommentExempt(text3, options2.markers)) continue;
|
|
1932
|
+
findings.push({ file, line, text: toSingleLine(text3) });
|
|
1933
1933
|
}
|
|
1934
1934
|
}
|
|
1935
1935
|
findings.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);
|
|
@@ -1948,8 +1948,8 @@ function commentPolicy() {
|
|
|
1948
1948
|
process.exit(0);
|
|
1949
1949
|
}
|
|
1950
1950
|
console.log("Comments added on changed lines:\n");
|
|
1951
|
-
for (const { file, line, text:
|
|
1952
|
-
console.log(`${file}:${line} \u2192 ${
|
|
1951
|
+
for (const { file, line, text: text3 } of findings) {
|
|
1952
|
+
console.log(`${file}:${line} \u2192 ${text3}`);
|
|
1953
1953
|
}
|
|
1954
1954
|
console.log(`
|
|
1955
1955
|
Total: ${findings.length} comment(s)`);
|
|
@@ -3056,9 +3056,9 @@ var LOCAL_FILES = ["backlog.jsonl", "backlog.db"];
|
|
|
3056
3056
|
function backupLocalBacklogFiles(dir) {
|
|
3057
3057
|
const moved = [];
|
|
3058
3058
|
for (const name of LOCAL_FILES) {
|
|
3059
|
-
const
|
|
3060
|
-
if (existsSync15(
|
|
3061
|
-
renameSync(
|
|
3059
|
+
const path54 = join11(dir, ".assist", name);
|
|
3060
|
+
if (existsSync15(path54)) {
|
|
3061
|
+
renameSync(path54, `${path54}.bak`);
|
|
3062
3062
|
moved.push(`${name} \u2192 ${name}.bak`);
|
|
3063
3063
|
}
|
|
3064
3064
|
}
|
|
@@ -3348,8 +3348,8 @@ var backlogItemSchema = z3.strictObject({
|
|
|
3348
3348
|
var backlogFileSchema = z3.array(backlogItemSchema);
|
|
3349
3349
|
|
|
3350
3350
|
// src/commands/backlog/parseBacklogJsonl.ts
|
|
3351
|
-
function parseBacklogJsonl(
|
|
3352
|
-
const content = readFileSync10(
|
|
3351
|
+
function parseBacklogJsonl(path54) {
|
|
3352
|
+
const content = readFileSync10(path54, "utf-8").trim();
|
|
3353
3353
|
if (content.length === 0) return [];
|
|
3354
3354
|
return content.split("\n").map((line) => line.trim()).filter(Boolean).map((line) => backlogItemSchema.parse(JSON.parse(line)));
|
|
3355
3355
|
}
|
|
@@ -3424,8 +3424,8 @@ function findBacklogUp(startDir) {
|
|
|
3424
3424
|
|
|
3425
3425
|
// src/commands/backlog/getCurrentOrigin.ts
|
|
3426
3426
|
import { execSync as execSync18 } from "child_process";
|
|
3427
|
-
function stripLeadingSlashes(
|
|
3428
|
-
return
|
|
3427
|
+
function stripLeadingSlashes(path54) {
|
|
3428
|
+
return path54.replace(/^\/+/, "");
|
|
3429
3429
|
}
|
|
3430
3430
|
function normalizeOrigin(raw) {
|
|
3431
3431
|
const trimmed = raw.trim().replace(/\.git$/i, "").replace(/\/+$/, "");
|
|
@@ -3689,13 +3689,13 @@ function activityPath(sessionId) {
|
|
|
3689
3689
|
function emitActivity(activity2) {
|
|
3690
3690
|
const sessionId = process.env.ASSIST_ACTIVITY_ID;
|
|
3691
3691
|
if (!sessionId) return;
|
|
3692
|
-
const
|
|
3693
|
-
mkdirSync6(dirname14(
|
|
3694
|
-
writeFileSync13(
|
|
3692
|
+
const path54 = activityPath(sessionId);
|
|
3693
|
+
mkdirSync6(dirname14(path54), { recursive: true });
|
|
3694
|
+
writeFileSync13(path54, JSON.stringify({ ...activity2, startedAt: Date.now() }));
|
|
3695
3695
|
}
|
|
3696
|
-
function readActivity(
|
|
3696
|
+
function readActivity(path54) {
|
|
3697
3697
|
try {
|
|
3698
|
-
return JSON.parse(readFileSync11(
|
|
3698
|
+
return JSON.parse(readFileSync11(path54, "utf-8"));
|
|
3699
3699
|
} catch {
|
|
3700
3700
|
return void 0;
|
|
3701
3701
|
}
|
|
@@ -3855,10 +3855,10 @@ function writeSignal(event, data) {
|
|
|
3855
3855
|
|
|
3856
3856
|
// src/commands/backlog/readSignal.ts
|
|
3857
3857
|
function readSignal() {
|
|
3858
|
-
const
|
|
3859
|
-
if (!existsSync19(
|
|
3858
|
+
const path54 = getSignalPath();
|
|
3859
|
+
if (!existsSync19(path54)) return void 0;
|
|
3860
3860
|
try {
|
|
3861
|
-
return JSON.parse(readFileSync12(
|
|
3861
|
+
return JSON.parse(readFileSync12(path54, "utf-8"));
|
|
3862
3862
|
} catch {
|
|
3863
3863
|
return void 0;
|
|
3864
3864
|
}
|
|
@@ -4114,11 +4114,11 @@ import chalk37 from "chalk";
|
|
|
4114
4114
|
|
|
4115
4115
|
// src/commands/backlog/appendComment.ts
|
|
4116
4116
|
import { sql as sql2 } from "drizzle-orm";
|
|
4117
|
-
async function appendComment(orm, itemId,
|
|
4117
|
+
async function appendComment(orm, itemId, text3, opts = {}) {
|
|
4118
4118
|
await orm.insert(comments).values({
|
|
4119
4119
|
itemId,
|
|
4120
4120
|
idx: sql2`(SELECT COALESCE(MAX(${comments.idx}) + 1, 0) FROM ${comments} WHERE ${comments.itemId} = ${itemId})`,
|
|
4121
|
-
text:
|
|
4121
|
+
text: text3,
|
|
4122
4122
|
phase: opts.phase ?? null,
|
|
4123
4123
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4124
4124
|
type: opts.type ?? "comment"
|
|
@@ -5121,10 +5121,10 @@ async function web2(options2) {
|
|
|
5121
5121
|
|
|
5122
5122
|
// src/commands/backlog/comment/index.ts
|
|
5123
5123
|
import chalk45 from "chalk";
|
|
5124
|
-
async function comment(id,
|
|
5124
|
+
async function comment(id, text3) {
|
|
5125
5125
|
const found = await findOneItem(id);
|
|
5126
5126
|
if (!found) process.exit(1);
|
|
5127
|
-
await appendComment(found.orm, found.item.id,
|
|
5127
|
+
await appendComment(found.orm, found.item.id, text3);
|
|
5128
5128
|
console.log(chalk45.green(`Comment added to item #${id}.`));
|
|
5129
5129
|
}
|
|
5130
5130
|
|
|
@@ -5294,9 +5294,9 @@ function readLine(dump, start3) {
|
|
|
5294
5294
|
return { text: dump.subarray(start3, eol).toString("utf8"), next: eol + 1 };
|
|
5295
5295
|
}
|
|
5296
5296
|
function parseHeader(dump) {
|
|
5297
|
-
const { text:
|
|
5297
|
+
const { text: text3, next: next3 } = readLine(dump, 0);
|
|
5298
5298
|
try {
|
|
5299
|
-
return { header: JSON.parse(
|
|
5299
|
+
return { header: JSON.parse(text3), bodyStart: next3 };
|
|
5300
5300
|
} catch {
|
|
5301
5301
|
return invalid("header is not valid JSON.");
|
|
5302
5302
|
}
|
|
@@ -5305,9 +5305,9 @@ function parseSections(dump, bodyStart) {
|
|
|
5305
5305
|
const sections = /* @__PURE__ */ new Map();
|
|
5306
5306
|
let cursor = bodyStart;
|
|
5307
5307
|
while (cursor < dump.length) {
|
|
5308
|
-
const { text:
|
|
5309
|
-
const match =
|
|
5310
|
-
if (!match) invalid(`malformed table marker "${
|
|
5308
|
+
const { text: text3, next: next3 } = readLine(dump, cursor);
|
|
5309
|
+
const match = text3.match(/^@table (\S+) (\d+)$/);
|
|
5310
|
+
if (!match) invalid(`malformed table marker "${text3}".`);
|
|
5311
5311
|
const [, name, bytes] = match;
|
|
5312
5312
|
const end = next3 + Number(bytes);
|
|
5313
5313
|
if (end > dump.length) invalid(`section "${name}" overruns the dump.`);
|
|
@@ -5645,8 +5645,8 @@ import chalk54 from "chalk";
|
|
|
5645
5645
|
// src/commands/backlog/originDisplayName.ts
|
|
5646
5646
|
function originDisplayName(origin) {
|
|
5647
5647
|
if (origin.startsWith("local:")) {
|
|
5648
|
-
const
|
|
5649
|
-
const segments =
|
|
5648
|
+
const path54 = origin.slice("local:".length).replace(/\/+$/, "");
|
|
5649
|
+
const segments = path54.split("/").filter(Boolean);
|
|
5650
5650
|
return segments[segments.length - 1] ?? origin;
|
|
5651
5651
|
}
|
|
5652
5652
|
const firstSlash = origin.indexOf("/");
|
|
@@ -6904,9 +6904,9 @@ var __dirname5 = dirname17(__filename3);
|
|
|
6904
6904
|
function packageRoot() {
|
|
6905
6905
|
return __dirname5;
|
|
6906
6906
|
}
|
|
6907
|
-
function readLines(
|
|
6908
|
-
if (!existsSync22(
|
|
6909
|
-
return readFileSync16(
|
|
6907
|
+
function readLines(path54) {
|
|
6908
|
+
if (!existsSync22(path54)) return [];
|
|
6909
|
+
return readFileSync16(path54, "utf-8").split("\n").filter((line) => line.trim() !== "");
|
|
6910
6910
|
}
|
|
6911
6911
|
var cachedReads;
|
|
6912
6912
|
var cachedWrites;
|
|
@@ -7389,14 +7389,14 @@ function showProgress(p, label2) {
|
|
|
7389
7389
|
const pct = Math.round(p.done / p.total * 100);
|
|
7390
7390
|
process.stderr.write(`\r\x1B[K[${pct}%] Scanning ${label2}...`);
|
|
7391
7391
|
}
|
|
7392
|
-
async function resolveCommand(cli,
|
|
7393
|
-
showProgress(p,
|
|
7394
|
-
const subHelp = await runHelp([cli, ...
|
|
7392
|
+
async function resolveCommand(cli, path54, description, depth, p) {
|
|
7393
|
+
showProgress(p, path54.join(" "));
|
|
7394
|
+
const subHelp = await runHelp([cli, ...path54]);
|
|
7395
7395
|
if (!subHelp || !hasSubcommands(subHelp)) {
|
|
7396
|
-
return [{ path:
|
|
7396
|
+
return [{ path: path54, description }];
|
|
7397
7397
|
}
|
|
7398
|
-
const children = await discoverAt(cli,
|
|
7399
|
-
return children.length > 0 ? children : [{ path:
|
|
7398
|
+
const children = await discoverAt(cli, path54, depth + 1, p);
|
|
7399
|
+
return children.length > 0 ? children : [{ path: path54, description }];
|
|
7400
7400
|
}
|
|
7401
7401
|
async function discoverAt(cli, parentPath, depth, p) {
|
|
7402
7402
|
if (depth > SAFETY_DEPTH) return [];
|
|
@@ -7506,8 +7506,8 @@ function formatHuman(cli, commands) {
|
|
|
7506
7506
|
`];
|
|
7507
7507
|
for (const cmd of sorted) {
|
|
7508
7508
|
const full = `${cli} ${cmd.path.join(" ")}`;
|
|
7509
|
-
const
|
|
7510
|
-
lines.push(`${prefix(classifyVerb(cmd.path))}${
|
|
7509
|
+
const text3 = cmd.description ? `${full} \u2014 ${cmd.description}` : full;
|
|
7510
|
+
lines.push(`${prefix(classifyVerb(cmd.path))}${text3}`);
|
|
7511
7511
|
}
|
|
7512
7512
|
return lines.join("\n");
|
|
7513
7513
|
}
|
|
@@ -7544,9 +7544,9 @@ function logPath(cli) {
|
|
|
7544
7544
|
return join22(homedir9(), ".assist", `cli-discover-${safeName}.log`);
|
|
7545
7545
|
}
|
|
7546
7546
|
function readCache(cli) {
|
|
7547
|
-
const
|
|
7548
|
-
if (!existsSync24(
|
|
7549
|
-
return readFileSync18(
|
|
7547
|
+
const path54 = logPath(cli);
|
|
7548
|
+
if (!existsSync24(path54)) return void 0;
|
|
7549
|
+
return readFileSync18(path54, "utf-8");
|
|
7550
7550
|
}
|
|
7551
7551
|
function writeCache(cli, output) {
|
|
7552
7552
|
const dir = join22(homedir9(), ".assist");
|
|
@@ -8235,8 +8235,8 @@ function stepIntoNested(container, key, nextKey) {
|
|
|
8235
8235
|
}
|
|
8236
8236
|
return ensureObject(container, resolved);
|
|
8237
8237
|
}
|
|
8238
|
-
function setNestedValue(obj,
|
|
8239
|
-
const keys =
|
|
8238
|
+
function setNestedValue(obj, path54, value) {
|
|
8239
|
+
const keys = path54.split(".");
|
|
8240
8240
|
const result = { ...obj };
|
|
8241
8241
|
let current = result;
|
|
8242
8242
|
for (let i = 0; i < keys.length - 1; i++) {
|
|
@@ -8316,9 +8316,9 @@ function isTraversable(value) {
|
|
|
8316
8316
|
function stepInto(current, key) {
|
|
8317
8317
|
return isTraversable(current) ? current[key] : void 0;
|
|
8318
8318
|
}
|
|
8319
|
-
function getNestedValue(obj,
|
|
8319
|
+
function getNestedValue(obj, path54) {
|
|
8320
8320
|
let current = obj;
|
|
8321
|
-
for (const key of
|
|
8321
|
+
for (const key of path54.split(".")) current = stepInto(current, key);
|
|
8322
8322
|
return current;
|
|
8323
8323
|
}
|
|
8324
8324
|
|
|
@@ -9852,16 +9852,16 @@ function parseUserLine(line) {
|
|
|
9852
9852
|
if (entry.type !== "user") return void 0;
|
|
9853
9853
|
const msg = entry.message;
|
|
9854
9854
|
const c = msg?.content;
|
|
9855
|
-
let
|
|
9855
|
+
let text3;
|
|
9856
9856
|
if (typeof c === "string") {
|
|
9857
|
-
|
|
9857
|
+
text3 = c;
|
|
9858
9858
|
} else if (Array.isArray(c)) {
|
|
9859
9859
|
const collected = c.filter((b) => b.type === "text").map((b) => b.text ?? "").join("\n");
|
|
9860
|
-
|
|
9860
|
+
text3 = collected || void 0;
|
|
9861
9861
|
}
|
|
9862
|
-
if (!
|
|
9862
|
+
if (!text3) return void 0;
|
|
9863
9863
|
return {
|
|
9864
|
-
text:
|
|
9864
|
+
text: text3,
|
|
9865
9865
|
entrypoint: typeof entry.entrypoint === "string" ? entry.entrypoint : void 0
|
|
9866
9866
|
};
|
|
9867
9867
|
}
|
|
@@ -9912,12 +9912,12 @@ ${payload}`;
|
|
|
9912
9912
|
return "";
|
|
9913
9913
|
}
|
|
9914
9914
|
}
|
|
9915
|
-
function stripPreludes(
|
|
9916
|
-
return
|
|
9915
|
+
function stripPreludes(text3) {
|
|
9916
|
+
return text3.replace(/<command-name>[\s\S]*?<\/command-name>/g, "").replace(/<command-message>[\s\S]*?<\/command-message>/g, "").replace(/<command-args>[\s\S]*?<\/command-args>/g, "").replace(/<local-command-stdout>[\s\S]*?<\/local-command-stdout>/g, "").replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, "").trim();
|
|
9917
9917
|
}
|
|
9918
|
-
function capPayload(
|
|
9919
|
-
const buf = Buffer.from(
|
|
9920
|
-
if (buf.length <= maxBytes) return
|
|
9918
|
+
function capPayload(text3, maxBytes) {
|
|
9919
|
+
const buf = Buffer.from(text3, "utf8");
|
|
9920
|
+
if (buf.length <= maxBytes) return text3;
|
|
9921
9921
|
return buf.subarray(buf.length - maxBytes).toString("utf8");
|
|
9922
9922
|
}
|
|
9923
9923
|
function normaliseOutput(raw) {
|
|
@@ -9986,9 +9986,9 @@ import chalk109 from "chalk";
|
|
|
9986
9986
|
|
|
9987
9987
|
// src/commands/jira/adfToText.ts
|
|
9988
9988
|
function renderInline(node) {
|
|
9989
|
-
const
|
|
9990
|
-
if (node.marks?.some((m) => m.type === "code")) return `\`${
|
|
9991
|
-
return
|
|
9989
|
+
const text3 = node.text ?? "";
|
|
9990
|
+
if (node.marks?.some((m) => m.type === "code")) return `\`${text3}\``;
|
|
9991
|
+
return text3;
|
|
9992
9992
|
}
|
|
9993
9993
|
function renderChildren(node, indent2) {
|
|
9994
9994
|
return renderNodes(node.content ?? [], indent2);
|
|
@@ -10030,8 +10030,8 @@ function isListNode(node) {
|
|
|
10030
10030
|
function renderListChild(child, indent2, pad, marker, isFirst) {
|
|
10031
10031
|
if (isListNode(child)) return renderNodes([child], indent2 + 1);
|
|
10032
10032
|
if (child.type !== "paragraph") return renderNode(child, indent2);
|
|
10033
|
-
const
|
|
10034
|
-
return isFirst ? `${pad}${marker} ${
|
|
10033
|
+
const text3 = renderChildren(child, indent2);
|
|
10034
|
+
return isFirst ? `${pad}${marker} ${text3}` : `${pad} ${text3}`;
|
|
10035
10035
|
}
|
|
10036
10036
|
function renderListItem(node, indent2, marker) {
|
|
10037
10037
|
const pad = " ".repeat(indent2);
|
|
@@ -10106,10 +10106,10 @@ function getStorePath(filename) {
|
|
|
10106
10106
|
return join32(getStoreDir(), filename);
|
|
10107
10107
|
}
|
|
10108
10108
|
function loadJson(filename) {
|
|
10109
|
-
const
|
|
10110
|
-
if (existsSync33(
|
|
10109
|
+
const path54 = getStorePath(filename);
|
|
10110
|
+
if (existsSync33(path54)) {
|
|
10111
10111
|
try {
|
|
10112
|
-
return JSON.parse(readFileSync27(
|
|
10112
|
+
return JSON.parse(readFileSync27(path54, "utf-8"));
|
|
10113
10113
|
} catch {
|
|
10114
10114
|
return {};
|
|
10115
10115
|
}
|
|
@@ -10442,9 +10442,9 @@ function excerpt(xml, ...tags) {
|
|
|
10442
10442
|
for (const tag of tags) {
|
|
10443
10443
|
const raw = extractText(xml, tag);
|
|
10444
10444
|
if (!raw) continue;
|
|
10445
|
-
const
|
|
10446
|
-
if (
|
|
10447
|
-
return `${
|
|
10445
|
+
const text3 = stripHtml(raw);
|
|
10446
|
+
if (text3.length <= MAX_EXCERPT) return text3;
|
|
10447
|
+
return `${text3.slice(0, MAX_EXCERPT)}\u2026`;
|
|
10448
10448
|
}
|
|
10449
10449
|
return "";
|
|
10450
10450
|
}
|
|
@@ -10745,15 +10745,15 @@ function postComment(vars) {
|
|
|
10745
10745
|
const stdout = startLine === void 0 ? runGhGraphql(MUTATION_SINGLE, base) : runGhGraphql(MUTATION_MULTI, { ...base, startLine });
|
|
10746
10746
|
assertThreadCreated(stdout);
|
|
10747
10747
|
}
|
|
10748
|
-
function comment2(
|
|
10748
|
+
function comment2(path54, line, body, startLine) {
|
|
10749
10749
|
validateBody(body);
|
|
10750
10750
|
validateLine(line);
|
|
10751
10751
|
if (startLine !== void 0) validateLine(startLine);
|
|
10752
10752
|
try {
|
|
10753
10753
|
const prId = getCurrentPrNodeId();
|
|
10754
|
-
postComment({ prId, body, path:
|
|
10754
|
+
postComment({ prId, body, path: path54, line, startLine });
|
|
10755
10755
|
const range = startLine !== void 0 ? `${startLine}-${line}` : `${line}`;
|
|
10756
|
-
console.log(`Added review comment on ${
|
|
10756
|
+
console.log(`Added review comment on ${path54}:${range}`);
|
|
10757
10757
|
} catch (error) {
|
|
10758
10758
|
if (isGhNotInstalled(error)) {
|
|
10759
10759
|
console.error("Error: GitHub CLI (gh) is not installed.");
|
|
@@ -11333,8 +11333,8 @@ function registerPrs(program2) {
|
|
|
11333
11333
|
prsCommand.command("wontfix <comment-id> <reason>").description("Reply with reason and resolve thread").action((commentId, reason) => {
|
|
11334
11334
|
wontfix(Number.parseInt(commentId, 10), reason);
|
|
11335
11335
|
});
|
|
11336
|
-
prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((
|
|
11337
|
-
comment2(
|
|
11336
|
+
prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((path54, line, body) => {
|
|
11337
|
+
comment2(path54, Number.parseInt(line, 10), body);
|
|
11338
11338
|
});
|
|
11339
11339
|
}
|
|
11340
11340
|
|
|
@@ -11586,10 +11586,10 @@ function resolveOpSecret(reference) {
|
|
|
11586
11586
|
}
|
|
11587
11587
|
|
|
11588
11588
|
// src/commands/ravendb/ravenFetch.ts
|
|
11589
|
-
async function ravenFetch(connection,
|
|
11589
|
+
async function ravenFetch(connection, path54) {
|
|
11590
11590
|
const apiKey = resolveOpSecret(connection.apiKeyRef);
|
|
11591
11591
|
let accessToken = await getAccessToken(apiKey);
|
|
11592
|
-
const url = `${connection.url}${
|
|
11592
|
+
const url = `${connection.url}${path54}`;
|
|
11593
11593
|
const headers = {
|
|
11594
11594
|
Authorization: `Bearer ${accessToken}`,
|
|
11595
11595
|
"Content-Type": "application/json"
|
|
@@ -11679,16 +11679,16 @@ import chalk130 from "chalk";
|
|
|
11679
11679
|
// src/commands/ravendb/buildQueryPath.ts
|
|
11680
11680
|
function buildQueryPath(opts) {
|
|
11681
11681
|
const db = encodeURIComponent(opts.db);
|
|
11682
|
-
let
|
|
11682
|
+
let path54;
|
|
11683
11683
|
if (opts.collection) {
|
|
11684
|
-
|
|
11684
|
+
path54 = `/databases/${db}/indexes/dynamic/${encodeURIComponent(opts.collection)}?start=${opts.start}&pageSize=${opts.pageSize}&sort=${encodeURIComponent(opts.sort)}`;
|
|
11685
11685
|
} else {
|
|
11686
|
-
|
|
11686
|
+
path54 = `/databases/${db}/queries?start=${opts.start}&pageSize=${opts.pageSize}`;
|
|
11687
11687
|
}
|
|
11688
11688
|
if (opts.query) {
|
|
11689
|
-
|
|
11689
|
+
path54 += `&query=${encodeURIComponent(opts.query)}`;
|
|
11690
11690
|
}
|
|
11691
|
-
return
|
|
11691
|
+
return path54;
|
|
11692
11692
|
}
|
|
11693
11693
|
|
|
11694
11694
|
// src/commands/ravendb/fetchAllPages.ts
|
|
@@ -11697,7 +11697,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
11697
11697
|
let start3 = 0;
|
|
11698
11698
|
while (true) {
|
|
11699
11699
|
const effectivePageSize = opts.limit !== void 0 ? Math.min(opts.pageSize, opts.limit - allResults.length) : opts.pageSize;
|
|
11700
|
-
const
|
|
11700
|
+
const path54 = buildQueryPath({
|
|
11701
11701
|
db: connection.database,
|
|
11702
11702
|
collection: opts.collection,
|
|
11703
11703
|
start: start3,
|
|
@@ -11705,7 +11705,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
11705
11705
|
sort: opts.sort,
|
|
11706
11706
|
query: opts.query
|
|
11707
11707
|
});
|
|
11708
|
-
const data = await ravenFetch(connection,
|
|
11708
|
+
const data = await ravenFetch(connection, path54);
|
|
11709
11709
|
const results = data.Results ?? [];
|
|
11710
11710
|
const totalResults = data.TotalResults ?? 0;
|
|
11711
11711
|
if (results.length === 0) break;
|
|
@@ -12352,9 +12352,9 @@ function resolveImports(target, dependencies, sourceFile, statements = []) {
|
|
|
12352
12352
|
function extractTexts(target, allFunctions, statements) {
|
|
12353
12353
|
const stmtTexts = statements.map((v) => v.getFullText().trim());
|
|
12354
12354
|
const fnTexts = allFunctions.map((fn) => {
|
|
12355
|
-
const
|
|
12356
|
-
if (fn === target && !
|
|
12357
|
-
return
|
|
12355
|
+
const text3 = fn.getFullText().trim();
|
|
12356
|
+
if (fn === target && !text3.startsWith("export ")) return `export ${text3}`;
|
|
12357
|
+
return text3;
|
|
12358
12358
|
});
|
|
12359
12359
|
return [...stmtTexts, ...fnTexts];
|
|
12360
12360
|
}
|
|
@@ -12923,8 +12923,8 @@ function findRootParent(file, importedBy, visited) {
|
|
|
12923
12923
|
function clusterFiles(graph) {
|
|
12924
12924
|
const clusters = /* @__PURE__ */ new Map();
|
|
12925
12925
|
for (const file of graph.files) {
|
|
12926
|
-
const
|
|
12927
|
-
if (
|
|
12926
|
+
const basename12 = path38.basename(file, path38.extname(file));
|
|
12927
|
+
if (basename12 === "index") continue;
|
|
12928
12928
|
const importers = graph.importedBy.get(file);
|
|
12929
12929
|
if (!importers || importers.size !== 1) continue;
|
|
12930
12930
|
const parent = [...importers][0];
|
|
@@ -13986,8 +13986,8 @@ async function handlePostSynthesis(synthesisPath, options2) {
|
|
|
13986
13986
|
// src/commands/review/prepareReviewDir.ts
|
|
13987
13987
|
import { existsSync as existsSync36, mkdirSync as mkdirSync14, unlinkSync as unlinkSync12, writeFileSync as writeFileSync26 } from "fs";
|
|
13988
13988
|
function clearReviewFiles(paths) {
|
|
13989
|
-
for (const
|
|
13990
|
-
if (existsSync36(
|
|
13989
|
+
for (const path54 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
|
|
13990
|
+
if (existsSync36(path54)) unlinkSync12(path54);
|
|
13991
13991
|
}
|
|
13992
13992
|
}
|
|
13993
13993
|
function prepareReviewDir(paths, requestBody, force) {
|
|
@@ -14122,9 +14122,9 @@ var MultiSpinner = class {
|
|
|
14122
14122
|
elapsedPrefix: prefix2
|
|
14123
14123
|
});
|
|
14124
14124
|
}
|
|
14125
|
-
failRemaining(
|
|
14125
|
+
failRemaining(text3) {
|
|
14126
14126
|
for (const entry of this.entries) {
|
|
14127
|
-
if (entry.state === "running") this.resolve(entry, "failed",
|
|
14127
|
+
if (entry.state === "running") this.resolve(entry, "failed", text3);
|
|
14128
14128
|
}
|
|
14129
14129
|
}
|
|
14130
14130
|
add(entry) {
|
|
@@ -14137,14 +14137,14 @@ var MultiSpinner = class {
|
|
|
14137
14137
|
set text(value) {
|
|
14138
14138
|
entry.text = value;
|
|
14139
14139
|
},
|
|
14140
|
-
succeed: (
|
|
14141
|
-
fail: (
|
|
14140
|
+
succeed: (text3) => this.resolve(entry, "succeeded", text3),
|
|
14141
|
+
fail: (text3) => this.resolve(entry, "failed", text3)
|
|
14142
14142
|
};
|
|
14143
14143
|
}
|
|
14144
|
-
resolve(entry, state,
|
|
14144
|
+
resolve(entry, state, text3) {
|
|
14145
14145
|
if (entry.state !== "running") return;
|
|
14146
14146
|
entry.state = state;
|
|
14147
|
-
if (
|
|
14147
|
+
if (text3 !== void 0) entry.text = text3;
|
|
14148
14148
|
entry.elapsedStart = void 0;
|
|
14149
14149
|
this.render();
|
|
14150
14150
|
this.maybeFinish();
|
|
@@ -14219,12 +14219,12 @@ function skippedCodexResult(outputPath) {
|
|
|
14219
14219
|
// src/commands/review/formatReviewerFailure.ts
|
|
14220
14220
|
var FAST_FAIL_MS = 1e3;
|
|
14221
14221
|
var STDOUT_TAIL_LINES = 20;
|
|
14222
|
-
function indent(
|
|
14223
|
-
return
|
|
14222
|
+
function indent(text3) {
|
|
14223
|
+
return text3.split(/\r?\n/).map((line) => ` ${line}`);
|
|
14224
14224
|
}
|
|
14225
|
-
function tailLines(
|
|
14226
|
-
const lines =
|
|
14227
|
-
return lines.length <= maxLines ?
|
|
14225
|
+
function tailLines(text3, maxLines) {
|
|
14226
|
+
const lines = text3.split(/\r?\n/);
|
|
14227
|
+
return lines.length <= maxLines ? text3 : lines.slice(-maxLines).join("\n");
|
|
14228
14228
|
}
|
|
14229
14229
|
function isFastFail(input) {
|
|
14230
14230
|
return input.exitCode !== 0 && input.elapsedMs !== void 0 && input.elapsedMs < FAST_FAIL_MS;
|
|
@@ -15122,8 +15122,8 @@ import chalk149 from "chalk";
|
|
|
15122
15122
|
|
|
15123
15123
|
// src/commands/seq/fetchSeq.ts
|
|
15124
15124
|
import chalk146 from "chalk";
|
|
15125
|
-
async function fetchSeq(conn,
|
|
15126
|
-
const url = `${conn.url}${
|
|
15125
|
+
async function fetchSeq(conn, path54, params) {
|
|
15126
|
+
const url = `${conn.url}${path54}?${params}`;
|
|
15127
15127
|
const response = await fetch(url, {
|
|
15128
15128
|
headers: {
|
|
15129
15129
|
Accept: "application/json",
|
|
@@ -15858,8 +15858,8 @@ import { existsSync as existsSync40, mkdirSync as mkdirSync15, readFileSync as r
|
|
|
15858
15858
|
import { basename as basename8, dirname as dirname21, join as join41 } from "path";
|
|
15859
15859
|
|
|
15860
15860
|
// src/commands/transcript/cleanText.ts
|
|
15861
|
-
function cleanText(
|
|
15862
|
-
const words =
|
|
15861
|
+
function cleanText(text3) {
|
|
15862
|
+
const words = text3.split(/\s+/);
|
|
15863
15863
|
const cleaned = [];
|
|
15864
15864
|
for (let i = 0; i < words.length; i++) {
|
|
15865
15865
|
let isRepeat = false;
|
|
@@ -15879,8 +15879,8 @@ function cleanText(text2) {
|
|
|
15879
15879
|
}
|
|
15880
15880
|
|
|
15881
15881
|
// src/commands/transcript/format/processVttFile/parseVtt/deduplicateCues/removeSubstringDuplicates.ts
|
|
15882
|
-
function normalizeText(
|
|
15883
|
-
return
|
|
15882
|
+
function normalizeText(text3) {
|
|
15883
|
+
return text3.toLowerCase().trim();
|
|
15884
15884
|
}
|
|
15885
15885
|
function checkSubstringRelation(textI, textJ) {
|
|
15886
15886
|
if (textI.includes(textJ) && textI.length > textJ.length)
|
|
@@ -16009,13 +16009,13 @@ function parseTimestampLine(line) {
|
|
|
16009
16009
|
return { startMs: parseTimestamp(startStr), endMs: parseTimestamp(endStr) };
|
|
16010
16010
|
}
|
|
16011
16011
|
function buildCue(startMs, endMs, fullText) {
|
|
16012
|
-
const { speaker, text:
|
|
16013
|
-
return
|
|
16012
|
+
const { speaker, text: text3 } = extractSpeaker(fullText);
|
|
16013
|
+
return text3 ? { startMs, endMs, speaker, text: text3 } : null;
|
|
16014
16014
|
}
|
|
16015
16015
|
function parseCueLine(lines, i) {
|
|
16016
16016
|
const { startMs, endMs } = parseTimestampLine(lines[i]);
|
|
16017
|
-
const { text:
|
|
16018
|
-
return { cue: buildCue(startMs, endMs,
|
|
16017
|
+
const { text: text3, nextIndex } = collectTextLines(lines, i + 1);
|
|
16018
|
+
return { cue: buildCue(startMs, endMs, text3), nextIndex };
|
|
16019
16019
|
}
|
|
16020
16020
|
function isCueSeparator(line) {
|
|
16021
16021
|
return line.trim().includes("-->");
|
|
@@ -16728,8 +16728,8 @@ async function exchangeToken(params) {
|
|
|
16728
16728
|
body: body.toString()
|
|
16729
16729
|
});
|
|
16730
16730
|
if (!response.ok) {
|
|
16731
|
-
const
|
|
16732
|
-
throw new Error(`Token exchange failed (${response.status}): ${
|
|
16731
|
+
const text3 = await response.text();
|
|
16732
|
+
throw new Error(`Token exchange failed (${response.status}): ${text3}`);
|
|
16733
16733
|
}
|
|
16734
16734
|
return response.json();
|
|
16735
16735
|
}
|
|
@@ -16813,9 +16813,9 @@ function findPortFile(roamDir) {
|
|
|
16813
16813
|
return void 0;
|
|
16814
16814
|
}
|
|
16815
16815
|
const candidates = entries.filter((name) => /^roam-local-api(-[^.]+)?\.port$/.test(name)).map((name) => {
|
|
16816
|
-
const
|
|
16816
|
+
const path54 = join49(roamDir, name);
|
|
16817
16817
|
try {
|
|
16818
|
-
return { path:
|
|
16818
|
+
return { path: path54, mtimeMs: statSync5(path54).mtimeMs };
|
|
16819
16819
|
} catch {
|
|
16820
16820
|
return void 0;
|
|
16821
16821
|
}
|
|
@@ -17158,11 +17158,11 @@ function findLinkIndex() {
|
|
|
17158
17158
|
function parseLinkArgs() {
|
|
17159
17159
|
const idx = findLinkIndex();
|
|
17160
17160
|
if (idx === -1) return null;
|
|
17161
|
-
const
|
|
17161
|
+
const path54 = process.argv[idx + 1];
|
|
17162
17162
|
const rest = process.argv.slice(idx + 2);
|
|
17163
17163
|
const { value: prefix2 } = extractOption(rest, "--prefix");
|
|
17164
17164
|
if (!prefix2) return null;
|
|
17165
|
-
return { path:
|
|
17165
|
+
return { path: path54, prefix: prefix2 };
|
|
17166
17166
|
}
|
|
17167
17167
|
function hasDuplicateLink(runList, linkPath) {
|
|
17168
17168
|
return runList.some(
|
|
@@ -17582,121 +17582,6 @@ function daemonLog(message) {
|
|
|
17582
17582
|
console.log(`${(/* @__PURE__ */ new Date()).toISOString()} [${process.pid}] ${message}`);
|
|
17583
17583
|
}
|
|
17584
17584
|
|
|
17585
|
-
// src/commands/sessions/shared/discoverSessions.ts
|
|
17586
|
-
import * as fs26 from "fs";
|
|
17587
|
-
import * as os from "os";
|
|
17588
|
-
import * as path46 from "path";
|
|
17589
|
-
|
|
17590
|
-
// src/commands/sessions/shared/parseSessionFile.ts
|
|
17591
|
-
import * as fs25 from "fs";
|
|
17592
|
-
import * as path45 from "path";
|
|
17593
|
-
|
|
17594
|
-
// src/commands/sessions/shared/extractSessionMeta.ts
|
|
17595
|
-
function extractSessionMeta(lines) {
|
|
17596
|
-
let sessionId = "";
|
|
17597
|
-
let cwd = "";
|
|
17598
|
-
let timestamp = "";
|
|
17599
|
-
let name = "";
|
|
17600
|
-
for (const line of lines) {
|
|
17601
|
-
const entry = safeParse(line);
|
|
17602
|
-
if (!entry) continue;
|
|
17603
|
-
sessionId ||= typeof entry.sessionId === "string" ? entry.sessionId : "";
|
|
17604
|
-
timestamp ||= typeof entry.timestamp === "string" ? entry.timestamp : "";
|
|
17605
|
-
cwd ||= typeof entry.cwd === "string" ? entry.cwd : "";
|
|
17606
|
-
if (entry.type === "user" && !entry.isMeta) {
|
|
17607
|
-
name = extractName(entry);
|
|
17608
|
-
break;
|
|
17609
|
-
}
|
|
17610
|
-
}
|
|
17611
|
-
return { sessionId, cwd, timestamp, name };
|
|
17612
|
-
}
|
|
17613
|
-
function safeParse(line) {
|
|
17614
|
-
try {
|
|
17615
|
-
return JSON.parse(line);
|
|
17616
|
-
} catch {
|
|
17617
|
-
return null;
|
|
17618
|
-
}
|
|
17619
|
-
}
|
|
17620
|
-
function extractName(entry) {
|
|
17621
|
-
const msg = entry.message;
|
|
17622
|
-
const content = msg?.content;
|
|
17623
|
-
const text2 = typeof content === "string" ? content : Array.isArray(content) ? content.find((c) => c.type === "text")?.text ?? "" : "";
|
|
17624
|
-
return text2.replace(/<command-[^>]*>[^<]*<\/command-[^>]*>/g, "").trim().slice(0, 80);
|
|
17625
|
-
}
|
|
17626
|
-
|
|
17627
|
-
// src/commands/sessions/shared/parseSessionFile.ts
|
|
17628
|
-
async function parseSessionFile(filePath) {
|
|
17629
|
-
let handle;
|
|
17630
|
-
try {
|
|
17631
|
-
handle = await fs25.promises.open(filePath, "r");
|
|
17632
|
-
const buf = Buffer.alloc(16384);
|
|
17633
|
-
const { bytesRead } = await handle.read(buf, 0, buf.length, 0);
|
|
17634
|
-
const lines = buf.toString("utf8", 0, bytesRead).split("\n").filter(Boolean);
|
|
17635
|
-
const meta = extractSessionMeta(lines);
|
|
17636
|
-
if (!meta.sessionId) return null;
|
|
17637
|
-
const timestamp = meta.timestamp || (await fs25.promises.stat(filePath)).mtime.toISOString();
|
|
17638
|
-
const project = meta.cwd ? path45.basename(meta.cwd) : dirNameToProject(filePath);
|
|
17639
|
-
return {
|
|
17640
|
-
sessionId: meta.sessionId,
|
|
17641
|
-
name: meta.name || `Session ${meta.sessionId.slice(0, 8)}`,
|
|
17642
|
-
project,
|
|
17643
|
-
cwd: meta.cwd,
|
|
17644
|
-
timestamp
|
|
17645
|
-
};
|
|
17646
|
-
} catch {
|
|
17647
|
-
return null;
|
|
17648
|
-
} finally {
|
|
17649
|
-
await handle?.close();
|
|
17650
|
-
}
|
|
17651
|
-
}
|
|
17652
|
-
function dirNameToProject(filePath) {
|
|
17653
|
-
const dirName = path45.basename(path45.dirname(filePath));
|
|
17654
|
-
const parts = dirName.split("--");
|
|
17655
|
-
return parts[parts.length - 1].replace(/-/g, "/");
|
|
17656
|
-
}
|
|
17657
|
-
|
|
17658
|
-
// src/commands/sessions/shared/discoverSessions.ts
|
|
17659
|
-
async function discoverSessionJsonlPaths() {
|
|
17660
|
-
const projectsDir = path46.join(os.homedir(), ".claude", "projects");
|
|
17661
|
-
let projectDirs;
|
|
17662
|
-
try {
|
|
17663
|
-
projectDirs = await fs26.promises.readdir(projectsDir);
|
|
17664
|
-
} catch {
|
|
17665
|
-
return [];
|
|
17666
|
-
}
|
|
17667
|
-
const paths = [];
|
|
17668
|
-
await Promise.all(
|
|
17669
|
-
projectDirs.map(async (dirName) => {
|
|
17670
|
-
const dirPath = path46.join(projectsDir, dirName);
|
|
17671
|
-
let entries;
|
|
17672
|
-
try {
|
|
17673
|
-
entries = await fs26.promises.readdir(dirPath);
|
|
17674
|
-
} catch {
|
|
17675
|
-
return;
|
|
17676
|
-
}
|
|
17677
|
-
const jsonlFiles = entries.filter((e) => e.endsWith(".jsonl"));
|
|
17678
|
-
for (const file of jsonlFiles) {
|
|
17679
|
-
paths.push(path46.join(dirPath, file));
|
|
17680
|
-
}
|
|
17681
|
-
})
|
|
17682
|
-
);
|
|
17683
|
-
return paths;
|
|
17684
|
-
}
|
|
17685
|
-
async function discoverSessions() {
|
|
17686
|
-
const paths = await discoverSessionJsonlPaths();
|
|
17687
|
-
const sessions = [];
|
|
17688
|
-
await Promise.all(
|
|
17689
|
-
paths.map(async (filePath) => {
|
|
17690
|
-
const session = await parseSessionFile(filePath);
|
|
17691
|
-
if (session) sessions.push(session);
|
|
17692
|
-
})
|
|
17693
|
-
);
|
|
17694
|
-
sessions.sort(
|
|
17695
|
-
(a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
|
|
17696
|
-
);
|
|
17697
|
-
return sessions;
|
|
17698
|
-
}
|
|
17699
|
-
|
|
17700
17585
|
// src/commands/sessions/daemon/broadcast.ts
|
|
17701
17586
|
function sendTo(client, msg) {
|
|
17702
17587
|
client.send(JSON.stringify(msg));
|
|
@@ -17800,14 +17685,14 @@ import * as pty from "node-pty";
|
|
|
17800
17685
|
// src/commands/sessions/daemon/ensureSpawnHelperExecutable.ts
|
|
17801
17686
|
import { chmodSync, existsSync as existsSync51, statSync as statSync6 } from "fs";
|
|
17802
17687
|
import { createRequire as createRequire3 } from "module";
|
|
17803
|
-
import
|
|
17688
|
+
import path45 from "path";
|
|
17804
17689
|
var require4 = createRequire3(import.meta.url);
|
|
17805
17690
|
var ensured = false;
|
|
17806
17691
|
function ensureSpawnHelperExecutable() {
|
|
17807
17692
|
if (ensured || process.platform !== "darwin") return;
|
|
17808
17693
|
ensured = true;
|
|
17809
|
-
const ptyRoot =
|
|
17810
|
-
const helper =
|
|
17694
|
+
const ptyRoot = path45.join(path45.dirname(require4.resolve("node-pty")), "..");
|
|
17695
|
+
const helper = path45.join(
|
|
17811
17696
|
ptyRoot,
|
|
17812
17697
|
"prebuilds",
|
|
17813
17698
|
`${process.platform}-${process.arch}`,
|
|
@@ -18044,12 +17929,12 @@ function clearIdle(session) {
|
|
|
18044
17929
|
|
|
18045
17930
|
// src/commands/sessions/daemon/watchActivity.ts
|
|
18046
17931
|
import { existsSync as existsSync52, mkdirSync as mkdirSync22, watch } from "fs";
|
|
18047
|
-
import { dirname as
|
|
17932
|
+
import { dirname as dirname26 } from "path";
|
|
18048
17933
|
var DEBOUNCE_MS = 50;
|
|
18049
17934
|
function watchActivity(session, notify2) {
|
|
18050
17935
|
if (session.commandType !== "assist" || !session.cwd) return;
|
|
18051
|
-
const
|
|
18052
|
-
const dir =
|
|
17936
|
+
const path54 = activityPath(session.id);
|
|
17937
|
+
const dir = dirname26(path54);
|
|
18053
17938
|
try {
|
|
18054
17939
|
mkdirSync22(dir, { recursive: true });
|
|
18055
17940
|
} catch {
|
|
@@ -18058,7 +17943,7 @@ function watchActivity(session, notify2) {
|
|
|
18058
17943
|
let timer = null;
|
|
18059
17944
|
const read = () => {
|
|
18060
17945
|
timer = null;
|
|
18061
|
-
const activity2 = readActivity(
|
|
17946
|
+
const activity2 = readActivity(path54);
|
|
18062
17947
|
if (!activity2) return;
|
|
18063
17948
|
session.activity = activity2;
|
|
18064
17949
|
if (activity2.claudeSessionId)
|
|
@@ -18066,11 +17951,11 @@ function watchActivity(session, notify2) {
|
|
|
18066
17951
|
notify2();
|
|
18067
17952
|
};
|
|
18068
17953
|
session.activityWatcher = watch(dir, (_event, filename) => {
|
|
18069
|
-
if (filename && !
|
|
17954
|
+
if (filename && !path54.endsWith(filename)) return;
|
|
18070
17955
|
if (timer) clearTimeout(timer);
|
|
18071
17956
|
timer = setTimeout(read, DEBOUNCE_MS);
|
|
18072
17957
|
});
|
|
18073
|
-
if (existsSync52(
|
|
17958
|
+
if (existsSync52(path54)) read();
|
|
18074
17959
|
}
|
|
18075
17960
|
function refreshActivity(session) {
|
|
18076
17961
|
if (session.commandType !== "assist" || !session.cwd) return;
|
|
@@ -18159,6 +18044,174 @@ function shutdownSessions(sessions) {
|
|
|
18159
18044
|
// src/commands/sessions/daemon/watchClaudeSessionId.ts
|
|
18160
18045
|
import * as fs27 from "fs";
|
|
18161
18046
|
import * as path48 from "path";
|
|
18047
|
+
|
|
18048
|
+
// src/commands/sessions/shared/discoverSessions.ts
|
|
18049
|
+
import * as fs26 from "fs";
|
|
18050
|
+
import * as os from "os";
|
|
18051
|
+
import * as path47 from "path";
|
|
18052
|
+
|
|
18053
|
+
// src/commands/sessions/shared/parseSessionFile.ts
|
|
18054
|
+
import * as fs25 from "fs";
|
|
18055
|
+
import * as path46 from "path";
|
|
18056
|
+
|
|
18057
|
+
// src/commands/sessions/shared/deriveHistoryFields.ts
|
|
18058
|
+
var KNOWN = ["draft", "next", "bug", "refine", "run"];
|
|
18059
|
+
function deriveHistoryFields(commandName, commandArgs, name) {
|
|
18060
|
+
const fields = {};
|
|
18061
|
+
const sessionType = deriveSessionType(commandName, name);
|
|
18062
|
+
if (sessionType) fields.sessionType = sessionType;
|
|
18063
|
+
const itemMatch = commandArgs.match(/^(\d+)\b\s*/);
|
|
18064
|
+
if (itemMatch) fields.itemId = Number(itemMatch[1]);
|
|
18065
|
+
const prompt = commandArgs.slice(itemMatch?.[0].length ?? 0).trim();
|
|
18066
|
+
if (prompt) fields.prompt = prompt;
|
|
18067
|
+
return fields;
|
|
18068
|
+
}
|
|
18069
|
+
function deriveSessionType(commandName, name) {
|
|
18070
|
+
if (KNOWN.includes(commandName))
|
|
18071
|
+
return commandName;
|
|
18072
|
+
if (commandName || name) return "prompt";
|
|
18073
|
+
return void 0;
|
|
18074
|
+
}
|
|
18075
|
+
|
|
18076
|
+
// src/commands/sessions/shared/backlogRunMarkers.ts
|
|
18077
|
+
function backlogRunMarkers(text3) {
|
|
18078
|
+
const match = text3.match(/backlog item #(\d+):[ \t]*([^\n]*)/);
|
|
18079
|
+
if (!match) return { commandName: "", commandArgs: "" };
|
|
18080
|
+
const title = match[2].trim();
|
|
18081
|
+
return {
|
|
18082
|
+
commandName: "next",
|
|
18083
|
+
commandArgs: title ? `${match[1]} ${title}` : match[1]
|
|
18084
|
+
};
|
|
18085
|
+
}
|
|
18086
|
+
|
|
18087
|
+
// src/commands/sessions/shared/extractSessionMeta.ts
|
|
18088
|
+
function extractSessionMeta(lines) {
|
|
18089
|
+
let sessionId = "";
|
|
18090
|
+
let cwd = "";
|
|
18091
|
+
let timestamp = "";
|
|
18092
|
+
let name = "";
|
|
18093
|
+
let commandName = "";
|
|
18094
|
+
let commandArgs = "";
|
|
18095
|
+
for (const line of lines) {
|
|
18096
|
+
const entry = safeParse(line);
|
|
18097
|
+
if (!entry) continue;
|
|
18098
|
+
sessionId ||= strField(entry, "sessionId");
|
|
18099
|
+
timestamp ||= strField(entry, "timestamp");
|
|
18100
|
+
cwd ||= strField(entry, "cwd");
|
|
18101
|
+
if (entry.type === "user" && !entry.isMeta) {
|
|
18102
|
+
({ name, commandName, commandArgs } = parseFirstUserEntry(entry));
|
|
18103
|
+
break;
|
|
18104
|
+
}
|
|
18105
|
+
}
|
|
18106
|
+
return { sessionId, cwd, timestamp, name, commandName, commandArgs };
|
|
18107
|
+
}
|
|
18108
|
+
function parseFirstUserEntry(entry) {
|
|
18109
|
+
const raw = messageText(entry);
|
|
18110
|
+
const commandName = matchMarker(raw, "command-name").replace(/^\//, "");
|
|
18111
|
+
const commandArgs = matchMarker(raw, "command-args");
|
|
18112
|
+
const name = stripMarkers(raw);
|
|
18113
|
+
if (commandName) return { name, commandName, commandArgs };
|
|
18114
|
+
return { name, ...backlogRunMarkers(raw) };
|
|
18115
|
+
}
|
|
18116
|
+
function strField(entry, key) {
|
|
18117
|
+
const value = entry[key];
|
|
18118
|
+
return typeof value === "string" ? value : "";
|
|
18119
|
+
}
|
|
18120
|
+
function safeParse(line) {
|
|
18121
|
+
try {
|
|
18122
|
+
return JSON.parse(line);
|
|
18123
|
+
} catch {
|
|
18124
|
+
return null;
|
|
18125
|
+
}
|
|
18126
|
+
}
|
|
18127
|
+
function messageText(entry) {
|
|
18128
|
+
const msg = entry.message;
|
|
18129
|
+
const content = msg?.content;
|
|
18130
|
+
return typeof content === "string" ? content : Array.isArray(content) ? content.find((c) => c.type === "text")?.text ?? "" : "";
|
|
18131
|
+
}
|
|
18132
|
+
function stripMarkers(text3) {
|
|
18133
|
+
return text3.replace(/<command-[^>]*>[^<]*<\/command-[^>]*>/g, "").trim().slice(0, 80);
|
|
18134
|
+
}
|
|
18135
|
+
function matchMarker(text3, tag) {
|
|
18136
|
+
const match = text3.match(new RegExp(`<${tag}>([\\s\\S]*?)</${tag}>`));
|
|
18137
|
+
return match ? match[1].trim() : "";
|
|
18138
|
+
}
|
|
18139
|
+
|
|
18140
|
+
// src/commands/sessions/shared/parseSessionFile.ts
|
|
18141
|
+
async function parseSessionFile(filePath) {
|
|
18142
|
+
let handle;
|
|
18143
|
+
try {
|
|
18144
|
+
handle = await fs25.promises.open(filePath, "r");
|
|
18145
|
+
const buf = Buffer.alloc(16384);
|
|
18146
|
+
const { bytesRead } = await handle.read(buf, 0, buf.length, 0);
|
|
18147
|
+
const lines = buf.toString("utf8", 0, bytesRead).split("\n").filter(Boolean);
|
|
18148
|
+
const meta = extractSessionMeta(lines);
|
|
18149
|
+
if (!meta.sessionId) return null;
|
|
18150
|
+
const timestamp = meta.timestamp || (await fs25.promises.stat(filePath)).mtime.toISOString();
|
|
18151
|
+
const project = meta.cwd ? path46.basename(meta.cwd) : dirNameToProject(filePath);
|
|
18152
|
+
return {
|
|
18153
|
+
sessionId: meta.sessionId,
|
|
18154
|
+
name: meta.name || `Session ${meta.sessionId.slice(0, 8)}`,
|
|
18155
|
+
project,
|
|
18156
|
+
cwd: meta.cwd,
|
|
18157
|
+
timestamp,
|
|
18158
|
+
...deriveHistoryFields(meta.commandName, meta.commandArgs, meta.name)
|
|
18159
|
+
};
|
|
18160
|
+
} catch {
|
|
18161
|
+
return null;
|
|
18162
|
+
} finally {
|
|
18163
|
+
await handle?.close();
|
|
18164
|
+
}
|
|
18165
|
+
}
|
|
18166
|
+
function dirNameToProject(filePath) {
|
|
18167
|
+
const dirName = path46.basename(path46.dirname(filePath));
|
|
18168
|
+
const parts = dirName.split("--");
|
|
18169
|
+
return parts[parts.length - 1].replace(/-/g, "/");
|
|
18170
|
+
}
|
|
18171
|
+
|
|
18172
|
+
// src/commands/sessions/shared/discoverSessions.ts
|
|
18173
|
+
async function discoverSessionJsonlPaths() {
|
|
18174
|
+
const projectsDir = path47.join(os.homedir(), ".claude", "projects");
|
|
18175
|
+
let projectDirs;
|
|
18176
|
+
try {
|
|
18177
|
+
projectDirs = await fs26.promises.readdir(projectsDir);
|
|
18178
|
+
} catch {
|
|
18179
|
+
return [];
|
|
18180
|
+
}
|
|
18181
|
+
const paths = [];
|
|
18182
|
+
await Promise.all(
|
|
18183
|
+
projectDirs.map(async (dirName) => {
|
|
18184
|
+
const dirPath = path47.join(projectsDir, dirName);
|
|
18185
|
+
let entries;
|
|
18186
|
+
try {
|
|
18187
|
+
entries = await fs26.promises.readdir(dirPath);
|
|
18188
|
+
} catch {
|
|
18189
|
+
return;
|
|
18190
|
+
}
|
|
18191
|
+
const jsonlFiles = entries.filter((e) => e.endsWith(".jsonl"));
|
|
18192
|
+
for (const file of jsonlFiles) {
|
|
18193
|
+
paths.push(path47.join(dirPath, file));
|
|
18194
|
+
}
|
|
18195
|
+
})
|
|
18196
|
+
);
|
|
18197
|
+
return paths;
|
|
18198
|
+
}
|
|
18199
|
+
async function discoverSessions() {
|
|
18200
|
+
const paths = await discoverSessionJsonlPaths();
|
|
18201
|
+
const sessions = [];
|
|
18202
|
+
await Promise.all(
|
|
18203
|
+
paths.map(async (filePath) => {
|
|
18204
|
+
const session = await parseSessionFile(filePath);
|
|
18205
|
+
if (session) sessions.push(session);
|
|
18206
|
+
})
|
|
18207
|
+
);
|
|
18208
|
+
sessions.sort(
|
|
18209
|
+
(a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
|
|
18210
|
+
);
|
|
18211
|
+
return sessions;
|
|
18212
|
+
}
|
|
18213
|
+
|
|
18214
|
+
// src/commands/sessions/daemon/watchClaudeSessionId.ts
|
|
18162
18215
|
var POLL_MS = 3e3;
|
|
18163
18216
|
async function watchClaudeSessionId(options2) {
|
|
18164
18217
|
let adoptedMs = 0;
|
|
@@ -18346,9 +18399,6 @@ var SessionManager = class {
|
|
|
18346
18399
|
listSessions() {
|
|
18347
18400
|
return [...this.sessions.values()].map(toSessionInfo);
|
|
18348
18401
|
}
|
|
18349
|
-
async getHistory() {
|
|
18350
|
-
return discoverSessions();
|
|
18351
|
-
}
|
|
18352
18402
|
notify = () => {
|
|
18353
18403
|
if (this.shuttingDown) return;
|
|
18354
18404
|
broadcastSessions(this.sessions, this.clients);
|
|
@@ -18363,6 +18413,95 @@ import * as net2 from "net";
|
|
|
18363
18413
|
// src/commands/sessions/daemon/handleConnection.ts
|
|
18364
18414
|
import { createInterface as createInterface5 } from "readline";
|
|
18365
18415
|
|
|
18416
|
+
// src/commands/sessions/shared/parseTranscript.ts
|
|
18417
|
+
import * as fs28 from "fs";
|
|
18418
|
+
|
|
18419
|
+
// src/commands/sessions/shared/toolTarget.ts
|
|
18420
|
+
function toolTarget(input) {
|
|
18421
|
+
if (!input || typeof input !== "object") return "";
|
|
18422
|
+
const i = input;
|
|
18423
|
+
const str = (v) => typeof v === "string" ? v : "";
|
|
18424
|
+
const target = str(i.file_path) || str(i.path) || str(i.notebook_path) || str(i.command) || str(i.pattern) || str(i.url) || str(i.query) || str(i.description) || str(i.prompt);
|
|
18425
|
+
return target.replace(/\s+/g, " ").trim().slice(0, 120);
|
|
18426
|
+
}
|
|
18427
|
+
|
|
18428
|
+
// src/commands/sessions/shared/entryMessages.ts
|
|
18429
|
+
function entryMessages(entry) {
|
|
18430
|
+
const content = entry.message?.content;
|
|
18431
|
+
if (entry.type === "user") return userMessages(content);
|
|
18432
|
+
if (entry.type === "assistant") return assistantMessages(content);
|
|
18433
|
+
return [];
|
|
18434
|
+
}
|
|
18435
|
+
function userMessages(content) {
|
|
18436
|
+
if (typeof content === "string") return text2("user", cleanUserText(content));
|
|
18437
|
+
if (!Array.isArray(content)) return [];
|
|
18438
|
+
return content.filter((c) => c.type === "text").flatMap((c) => text2("user", cleanUserText(c.text ?? "")));
|
|
18439
|
+
}
|
|
18440
|
+
function assistantMessages(content) {
|
|
18441
|
+
if (typeof content === "string") return text2("assistant", content.trim());
|
|
18442
|
+
if (!Array.isArray(content)) return [];
|
|
18443
|
+
return content.flatMap((c) => assistantItem(c));
|
|
18444
|
+
}
|
|
18445
|
+
function assistantItem(c) {
|
|
18446
|
+
if (c.type === "text") return text2("assistant", (c.text ?? "").trim());
|
|
18447
|
+
if (c.type === "tool_use")
|
|
18448
|
+
return [
|
|
18449
|
+
{
|
|
18450
|
+
role: "tool",
|
|
18451
|
+
tool: typeof c.name === "string" ? c.name : "tool",
|
|
18452
|
+
target: toolTarget(c.input)
|
|
18453
|
+
}
|
|
18454
|
+
];
|
|
18455
|
+
return [];
|
|
18456
|
+
}
|
|
18457
|
+
function text2(role, value) {
|
|
18458
|
+
return value ? [{ role, text: value }] : [];
|
|
18459
|
+
}
|
|
18460
|
+
function cleanUserText(value) {
|
|
18461
|
+
return value.replace(/<command-[^>]*>[\s\S]*?<\/command-[^>]*>/g, "").replace(/<local-command-[^>]*>[\s\S]*?<\/local-command-[^>]*>/g, "").trim();
|
|
18462
|
+
}
|
|
18463
|
+
|
|
18464
|
+
// src/commands/sessions/shared/findSessionJsonlPath.ts
|
|
18465
|
+
import * as path49 from "path";
|
|
18466
|
+
async function findSessionJsonlPath(sessionId) {
|
|
18467
|
+
const paths = await discoverSessionJsonlPaths();
|
|
18468
|
+
const direct = paths.find((p) => path49.basename(p, ".jsonl") === sessionId);
|
|
18469
|
+
if (direct) return direct;
|
|
18470
|
+
for (const p of paths) {
|
|
18471
|
+
const meta = await parseSessionFile(p);
|
|
18472
|
+
if (meta?.sessionId === sessionId) return p;
|
|
18473
|
+
}
|
|
18474
|
+
return null;
|
|
18475
|
+
}
|
|
18476
|
+
|
|
18477
|
+
// src/commands/sessions/shared/parseTranscript.ts
|
|
18478
|
+
async function parseTranscript(sessionId) {
|
|
18479
|
+
const filePath = await findSessionJsonlPath(sessionId);
|
|
18480
|
+
if (!filePath) return [];
|
|
18481
|
+
try {
|
|
18482
|
+
const raw = await fs28.promises.readFile(filePath, "utf8");
|
|
18483
|
+
return parseTranscriptLines(raw.split("\n"));
|
|
18484
|
+
} catch {
|
|
18485
|
+
return [];
|
|
18486
|
+
}
|
|
18487
|
+
}
|
|
18488
|
+
function parseTranscriptLines(lines) {
|
|
18489
|
+
const messages = [];
|
|
18490
|
+
for (const line of lines) {
|
|
18491
|
+
const entry = line.trim() ? safeParse2(line) : null;
|
|
18492
|
+
if (!entry || entry.isSidechain || entry.isMeta) continue;
|
|
18493
|
+
messages.push(...entryMessages(entry));
|
|
18494
|
+
}
|
|
18495
|
+
return messages;
|
|
18496
|
+
}
|
|
18497
|
+
function safeParse2(line) {
|
|
18498
|
+
try {
|
|
18499
|
+
return JSON.parse(line);
|
|
18500
|
+
} catch {
|
|
18501
|
+
return null;
|
|
18502
|
+
}
|
|
18503
|
+
}
|
|
18504
|
+
|
|
18366
18505
|
// src/commands/sessions/daemon/dispatchMessage.ts
|
|
18367
18506
|
function sendCreated(client, id) {
|
|
18368
18507
|
sendTo(client, { type: "created", sessionId: id });
|
|
@@ -18405,10 +18544,16 @@ function handleResume(client, manager, data) {
|
|
|
18405
18544
|
)
|
|
18406
18545
|
);
|
|
18407
18546
|
}
|
|
18408
|
-
function handleHistory(client
|
|
18409
|
-
|
|
18410
|
-
sendTo(client, { type: "history", sessions
|
|
18411
|
-
|
|
18547
|
+
function handleHistory(client) {
|
|
18548
|
+
discoverSessions().then(
|
|
18549
|
+
(sessions) => sendTo(client, { type: "history", sessions })
|
|
18550
|
+
);
|
|
18551
|
+
}
|
|
18552
|
+
function handleFetchTranscript(client, _manager, data) {
|
|
18553
|
+
const sessionId = data.sessionId;
|
|
18554
|
+
parseTranscript(sessionId).then(
|
|
18555
|
+
(messages) => sendTo(client, { type: "transcript", sessionId, messages })
|
|
18556
|
+
);
|
|
18412
18557
|
}
|
|
18413
18558
|
function handleShutdown(client, manager) {
|
|
18414
18559
|
manager.shutdown();
|
|
@@ -18422,6 +18567,7 @@ var handlers = {
|
|
|
18422
18567
|
"create-assist": handleCreateAssist,
|
|
18423
18568
|
resume: handleResume,
|
|
18424
18569
|
history: handleHistory,
|
|
18570
|
+
"fetch-transcript": handleFetchTranscript,
|
|
18425
18571
|
shutdown: handleShutdown,
|
|
18426
18572
|
input: (_client, m, d) => m.writeToSession(d.sessionId, d.data),
|
|
18427
18573
|
resize: (_client, m, d) => m.resizeSession(d.sessionId, d.cols, d.rows),
|
|
@@ -18585,17 +18731,17 @@ function registerDaemon(program2) {
|
|
|
18585
18731
|
}
|
|
18586
18732
|
|
|
18587
18733
|
// src/commands/sessions/summarise/index.ts
|
|
18588
|
-
import * as
|
|
18734
|
+
import * as fs31 from "fs";
|
|
18589
18735
|
import chalk159 from "chalk";
|
|
18590
18736
|
|
|
18591
18737
|
// src/commands/sessions/summarise/shared.ts
|
|
18592
|
-
import * as
|
|
18738
|
+
import * as fs29 from "fs";
|
|
18593
18739
|
function writeSummary(jsonlPath2, summary) {
|
|
18594
|
-
|
|
18740
|
+
fs29.writeFileSync(summaryPathFor(jsonlPath2), `${summary.trim()}
|
|
18595
18741
|
`, "utf8");
|
|
18596
18742
|
}
|
|
18597
18743
|
function hasSummary(jsonlPath2) {
|
|
18598
|
-
return
|
|
18744
|
+
return fs29.existsSync(summaryPathFor(jsonlPath2));
|
|
18599
18745
|
}
|
|
18600
18746
|
function summaryPathFor(jsonlPath2) {
|
|
18601
18747
|
return jsonlPath2.replace(/\.jsonl$/, ".summary");
|
|
@@ -18605,17 +18751,17 @@ function summaryPathFor(jsonlPath2) {
|
|
|
18605
18751
|
import { execFileSync as execFileSync10 } from "child_process";
|
|
18606
18752
|
|
|
18607
18753
|
// src/commands/sessions/summarise/iterateUserMessages.ts
|
|
18608
|
-
import * as
|
|
18754
|
+
import * as fs30 from "fs";
|
|
18609
18755
|
function* iterateUserMessages(filePath, maxBytes = 65536) {
|
|
18610
18756
|
let content;
|
|
18611
18757
|
try {
|
|
18612
|
-
const fd =
|
|
18758
|
+
const fd = fs30.openSync(filePath, "r");
|
|
18613
18759
|
try {
|
|
18614
18760
|
const buf = Buffer.alloc(maxBytes);
|
|
18615
|
-
const bytesRead =
|
|
18761
|
+
const bytesRead = fs30.readSync(fd, buf, 0, buf.length, 0);
|
|
18616
18762
|
content = buf.toString("utf8", 0, bytesRead);
|
|
18617
18763
|
} finally {
|
|
18618
|
-
|
|
18764
|
+
fs30.closeSync(fd);
|
|
18619
18765
|
}
|
|
18620
18766
|
} catch {
|
|
18621
18767
|
return;
|
|
@@ -18629,13 +18775,13 @@ function* iterateUserMessages(filePath, maxBytes = 65536) {
|
|
|
18629
18775
|
|
|
18630
18776
|
// src/commands/sessions/summarise/extractFirstUserMessage.ts
|
|
18631
18777
|
function extractFirstUserMessage(filePath) {
|
|
18632
|
-
for (const
|
|
18633
|
-
return truncate3(
|
|
18778
|
+
for (const text3 of iterateUserMessages(filePath)) {
|
|
18779
|
+
return truncate3(text3);
|
|
18634
18780
|
}
|
|
18635
18781
|
return void 0;
|
|
18636
18782
|
}
|
|
18637
|
-
function truncate3(
|
|
18638
|
-
const trimmed =
|
|
18783
|
+
function truncate3(text3, maxChars = 500) {
|
|
18784
|
+
const trimmed = text3.trim();
|
|
18639
18785
|
if (trimmed.length <= maxChars) return trimmed;
|
|
18640
18786
|
return `${trimmed.slice(0, maxChars)}\u2026`;
|
|
18641
18787
|
}
|
|
@@ -18643,28 +18789,28 @@ function truncate3(text2, maxChars = 500) {
|
|
|
18643
18789
|
// src/commands/sessions/summarise/scanSessionBacklogRefs.ts
|
|
18644
18790
|
function scanSessionBacklogRefs(filePath) {
|
|
18645
18791
|
const ids = /* @__PURE__ */ new Set();
|
|
18646
|
-
for (const
|
|
18647
|
-
for (const id of extractBacklogIds(
|
|
18792
|
+
for (const text3 of iterateUserMessages(filePath, Number.MAX_SAFE_INTEGER)) {
|
|
18793
|
+
for (const id of extractBacklogIds(text3)) {
|
|
18648
18794
|
ids.add(id);
|
|
18649
18795
|
}
|
|
18650
18796
|
}
|
|
18651
18797
|
return [...ids].sort((a, b) => a - b);
|
|
18652
18798
|
}
|
|
18653
|
-
function extractBacklogIds(
|
|
18799
|
+
function extractBacklogIds(text3) {
|
|
18654
18800
|
const ids = [];
|
|
18655
|
-
for (const m of
|
|
18801
|
+
for (const m of text3.matchAll(/backlog\s+run\s+(\d+)/gi)) {
|
|
18656
18802
|
ids.push(Number.parseInt(m[1], 10));
|
|
18657
18803
|
}
|
|
18658
|
-
for (const m of
|
|
18804
|
+
for (const m of text3.matchAll(/backlog\s+(?:item\s+)?#(\d+)/gi)) {
|
|
18659
18805
|
ids.push(Number.parseInt(m[1], 10));
|
|
18660
18806
|
}
|
|
18661
|
-
for (const m of
|
|
18807
|
+
for (const m of text3.matchAll(/backlog\s+phase-done\s+(\d+)/gi)) {
|
|
18662
18808
|
ids.push(Number.parseInt(m[1], 10));
|
|
18663
18809
|
}
|
|
18664
|
-
for (const m of
|
|
18810
|
+
for (const m of text3.matchAll(/backlog\s+comment\s+(\d+)/gi)) {
|
|
18665
18811
|
ids.push(Number.parseInt(m[1], 10));
|
|
18666
18812
|
}
|
|
18667
|
-
for (const m of
|
|
18813
|
+
for (const m of text3.matchAll(/(?:^|[\s(])#(\d{1,4})(?=[\s).,;:!?]|$)/gm)) {
|
|
18668
18814
|
ids.push(Number.parseInt(m[1], 10));
|
|
18669
18815
|
}
|
|
18670
18816
|
return ids;
|
|
@@ -18735,7 +18881,7 @@ function selectCandidates(files, options2) {
|
|
|
18735
18881
|
const candidates = options2.force ? files : files.filter((f) => !hasSummary(f));
|
|
18736
18882
|
candidates.sort((a, b) => {
|
|
18737
18883
|
try {
|
|
18738
|
-
return
|
|
18884
|
+
return fs31.statSync(b).mtimeMs - fs31.statSync(a).mtimeMs;
|
|
18739
18885
|
} catch {
|
|
18740
18886
|
return 0;
|
|
18741
18887
|
}
|
|
@@ -18849,21 +18995,21 @@ async function statusLine() {
|
|
|
18849
18995
|
}
|
|
18850
18996
|
|
|
18851
18997
|
// src/commands/sync.ts
|
|
18852
|
-
import * as
|
|
18998
|
+
import * as fs34 from "fs";
|
|
18853
18999
|
import * as os2 from "os";
|
|
18854
|
-
import * as
|
|
19000
|
+
import * as path52 from "path";
|
|
18855
19001
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
18856
19002
|
|
|
18857
19003
|
// src/commands/sync/syncClaudeMd.ts
|
|
18858
|
-
import * as
|
|
18859
|
-
import * as
|
|
19004
|
+
import * as fs32 from "fs";
|
|
19005
|
+
import * as path50 from "path";
|
|
18860
19006
|
import chalk162 from "chalk";
|
|
18861
19007
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
18862
|
-
const source =
|
|
18863
|
-
const target =
|
|
18864
|
-
const sourceContent =
|
|
18865
|
-
if (
|
|
18866
|
-
const targetContent =
|
|
19008
|
+
const source = path50.join(claudeDir, "CLAUDE.md");
|
|
19009
|
+
const target = path50.join(targetBase, "CLAUDE.md");
|
|
19010
|
+
const sourceContent = fs32.readFileSync(source, "utf-8");
|
|
19011
|
+
if (fs32.existsSync(target)) {
|
|
19012
|
+
const targetContent = fs32.readFileSync(target, "utf-8");
|
|
18867
19013
|
if (sourceContent !== targetContent) {
|
|
18868
19014
|
console.log(
|
|
18869
19015
|
chalk162.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
@@ -18880,21 +19026,21 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
18880
19026
|
}
|
|
18881
19027
|
}
|
|
18882
19028
|
}
|
|
18883
|
-
|
|
19029
|
+
fs32.copyFileSync(source, target);
|
|
18884
19030
|
console.log("Copied CLAUDE.md to ~/.claude/CLAUDE.md");
|
|
18885
19031
|
}
|
|
18886
19032
|
|
|
18887
19033
|
// src/commands/sync/syncSettings.ts
|
|
18888
|
-
import * as
|
|
18889
|
-
import * as
|
|
19034
|
+
import * as fs33 from "fs";
|
|
19035
|
+
import * as path51 from "path";
|
|
18890
19036
|
import chalk163 from "chalk";
|
|
18891
19037
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
18892
|
-
const source =
|
|
18893
|
-
const target =
|
|
18894
|
-
const sourceContent =
|
|
19038
|
+
const source = path51.join(claudeDir, "settings.json");
|
|
19039
|
+
const target = path51.join(targetBase, "settings.json");
|
|
19040
|
+
const sourceContent = fs33.readFileSync(source, "utf-8");
|
|
18895
19041
|
const mergedContent = JSON.stringify(JSON.parse(sourceContent), null, " ");
|
|
18896
|
-
if (
|
|
18897
|
-
const targetContent =
|
|
19042
|
+
if (fs33.existsSync(target)) {
|
|
19043
|
+
const targetContent = fs33.readFileSync(target, "utf-8");
|
|
18898
19044
|
const normalizedTarget = JSON.stringify(
|
|
18899
19045
|
JSON.parse(targetContent),
|
|
18900
19046
|
null,
|
|
@@ -18920,29 +19066,29 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
18920
19066
|
}
|
|
18921
19067
|
}
|
|
18922
19068
|
}
|
|
18923
|
-
|
|
19069
|
+
fs33.writeFileSync(target, mergedContent);
|
|
18924
19070
|
console.log("Copied settings.json to ~/.claude/settings.json");
|
|
18925
19071
|
}
|
|
18926
19072
|
|
|
18927
19073
|
// src/commands/sync.ts
|
|
18928
19074
|
var __filename4 = fileURLToPath7(import.meta.url);
|
|
18929
|
-
var __dirname7 =
|
|
19075
|
+
var __dirname7 = path52.dirname(__filename4);
|
|
18930
19076
|
async function sync(options2) {
|
|
18931
19077
|
const config = loadConfig();
|
|
18932
19078
|
const yes = options2?.yes ?? config.sync.autoConfirm;
|
|
18933
|
-
const claudeDir =
|
|
18934
|
-
const targetBase =
|
|
19079
|
+
const claudeDir = path52.join(__dirname7, "..", "claude");
|
|
19080
|
+
const targetBase = path52.join(os2.homedir(), ".claude");
|
|
18935
19081
|
syncCommands(claudeDir, targetBase);
|
|
18936
19082
|
await syncSettings(claudeDir, targetBase, { yes });
|
|
18937
19083
|
await syncClaudeMd(claudeDir, targetBase, { yes });
|
|
18938
19084
|
}
|
|
18939
19085
|
function syncCommands(claudeDir, targetBase) {
|
|
18940
|
-
const sourceDir =
|
|
18941
|
-
const targetDir =
|
|
18942
|
-
|
|
18943
|
-
const files =
|
|
19086
|
+
const sourceDir = path52.join(claudeDir, "commands");
|
|
19087
|
+
const targetDir = path52.join(targetBase, "commands");
|
|
19088
|
+
fs34.mkdirSync(targetDir, { recursive: true });
|
|
19089
|
+
const files = fs34.readdirSync(sourceDir);
|
|
18944
19090
|
for (const file of files) {
|
|
18945
|
-
|
|
19091
|
+
fs34.copyFileSync(path52.join(sourceDir, file), path52.join(targetDir, file));
|
|
18946
19092
|
console.log(`Copied ${file} to ${targetDir}`);
|
|
18947
19093
|
}
|
|
18948
19094
|
console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
|
|
@@ -18950,15 +19096,15 @@ function syncCommands(claudeDir, targetBase) {
|
|
|
18950
19096
|
|
|
18951
19097
|
// src/commands/update.ts
|
|
18952
19098
|
import { execSync as execSync50 } from "child_process";
|
|
18953
|
-
import * as
|
|
19099
|
+
import * as path53 from "path";
|
|
18954
19100
|
function isGlobalNpmInstall(dir) {
|
|
18955
19101
|
try {
|
|
18956
|
-
const resolved =
|
|
18957
|
-
if (resolved.split(
|
|
19102
|
+
const resolved = path53.resolve(dir);
|
|
19103
|
+
if (resolved.split(path53.sep).includes("node_modules")) {
|
|
18958
19104
|
return true;
|
|
18959
19105
|
}
|
|
18960
19106
|
const globalPrefix = execSync50("npm prefix -g", { stdio: "pipe" }).toString().trim();
|
|
18961
|
-
return resolved.toLowerCase().startsWith(
|
|
19107
|
+
return resolved.toLowerCase().startsWith(path53.resolve(globalPrefix).toLowerCase());
|
|
18962
19108
|
} catch {
|
|
18963
19109
|
return false;
|
|
18964
19110
|
}
|