@staff0rd/assist 0.192.0 → 0.193.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 +24 -24
- package/dist/index.js +236 -86
- 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.193.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -925,10 +925,10 @@ function writeSignal(event, data) {
|
|
|
925
925
|
|
|
926
926
|
// src/commands/backlog/readSignal.ts
|
|
927
927
|
function readSignal() {
|
|
928
|
-
const
|
|
929
|
-
if (!existsSync5(
|
|
928
|
+
const path52 = getSignalPath();
|
|
929
|
+
if (!existsSync5(path52)) return void 0;
|
|
930
930
|
try {
|
|
931
|
-
return JSON.parse(readFileSync5(
|
|
931
|
+
return JSON.parse(readFileSync5(path52, "utf-8"));
|
|
932
932
|
} catch {
|
|
933
933
|
return void 0;
|
|
934
934
|
}
|
|
@@ -981,10 +981,10 @@ import { stringify as stringifyYaml } from "yaml";
|
|
|
981
981
|
// src/shared/loadRawYaml.ts
|
|
982
982
|
import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
|
|
983
983
|
import { parse as parseYaml2 } from "yaml";
|
|
984
|
-
function loadRawYaml(
|
|
985
|
-
if (!existsSync7(
|
|
984
|
+
function loadRawYaml(path52) {
|
|
985
|
+
if (!existsSync7(path52)) return {};
|
|
986
986
|
try {
|
|
987
|
-
const content = readFileSync6(
|
|
987
|
+
const content = readFileSync6(path52, "utf-8");
|
|
988
988
|
return parseYaml2(content) || {};
|
|
989
989
|
} catch {
|
|
990
990
|
return {};
|
|
@@ -4955,9 +4955,9 @@ var __dirname4 = dirname15(__filename2);
|
|
|
4955
4955
|
function packageRoot() {
|
|
4956
4956
|
return __dirname4;
|
|
4957
4957
|
}
|
|
4958
|
-
function readLines(
|
|
4959
|
-
if (!existsSync20(
|
|
4960
|
-
return readFileSync16(
|
|
4958
|
+
function readLines(path52) {
|
|
4959
|
+
if (!existsSync20(path52)) return [];
|
|
4960
|
+
return readFileSync16(path52, "utf-8").split("\n").filter((line) => line.trim() !== "");
|
|
4961
4961
|
}
|
|
4962
4962
|
var cachedReads;
|
|
4963
4963
|
var cachedWrites;
|
|
@@ -5390,14 +5390,14 @@ function showProgress(p, label2) {
|
|
|
5390
5390
|
const pct = Math.round(p.done / p.total * 100);
|
|
5391
5391
|
process.stderr.write(`\r\x1B[K[${pct}%] Scanning ${label2}...`);
|
|
5392
5392
|
}
|
|
5393
|
-
async function resolveCommand(cli,
|
|
5394
|
-
showProgress(p,
|
|
5395
|
-
const subHelp = await runHelp([cli, ...
|
|
5393
|
+
async function resolveCommand(cli, path52, description, depth, p) {
|
|
5394
|
+
showProgress(p, path52.join(" "));
|
|
5395
|
+
const subHelp = await runHelp([cli, ...path52]);
|
|
5396
5396
|
if (!subHelp || !hasSubcommands(subHelp)) {
|
|
5397
|
-
return [{ path:
|
|
5397
|
+
return [{ path: path52, description }];
|
|
5398
5398
|
}
|
|
5399
|
-
const children = await discoverAt(cli,
|
|
5400
|
-
return children.length > 0 ? children : [{ path:
|
|
5399
|
+
const children = await discoverAt(cli, path52, depth + 1, p);
|
|
5400
|
+
return children.length > 0 ? children : [{ path: path52, description }];
|
|
5401
5401
|
}
|
|
5402
5402
|
async function discoverAt(cli, parentPath, depth, p) {
|
|
5403
5403
|
if (depth > SAFETY_DEPTH) return [];
|
|
@@ -5545,9 +5545,9 @@ function logPath(cli) {
|
|
|
5545
5545
|
return join19(homedir4(), ".assist", `cli-discover-${safeName}.log`);
|
|
5546
5546
|
}
|
|
5547
5547
|
function readCache(cli) {
|
|
5548
|
-
const
|
|
5549
|
-
if (!existsSync22(
|
|
5550
|
-
return readFileSync18(
|
|
5548
|
+
const path52 = logPath(cli);
|
|
5549
|
+
if (!existsSync22(path52)) return void 0;
|
|
5550
|
+
return readFileSync18(path52, "utf-8");
|
|
5551
5551
|
}
|
|
5552
5552
|
function writeCache(cli, output) {
|
|
5553
5553
|
const dir = join19(homedir4(), ".assist");
|
|
@@ -6189,8 +6189,8 @@ function stepIntoNested(container, key, nextKey) {
|
|
|
6189
6189
|
}
|
|
6190
6190
|
return ensureObject(container, resolved);
|
|
6191
6191
|
}
|
|
6192
|
-
function setNestedValue(obj,
|
|
6193
|
-
const keys =
|
|
6192
|
+
function setNestedValue(obj, path52, value) {
|
|
6193
|
+
const keys = path52.split(".");
|
|
6194
6194
|
const result = { ...obj };
|
|
6195
6195
|
let current = result;
|
|
6196
6196
|
for (let i = 0; i < keys.length - 1; i++) {
|
|
@@ -6270,9 +6270,9 @@ function isTraversable(value) {
|
|
|
6270
6270
|
function stepInto(current, key) {
|
|
6271
6271
|
return isTraversable(current) ? current[key] : void 0;
|
|
6272
6272
|
}
|
|
6273
|
-
function getNestedValue(obj,
|
|
6273
|
+
function getNestedValue(obj, path52) {
|
|
6274
6274
|
let current = obj;
|
|
6275
|
-
for (const key of
|
|
6275
|
+
for (const key of path52.split(".")) current = stepInto(current, key);
|
|
6276
6276
|
return current;
|
|
6277
6277
|
}
|
|
6278
6278
|
|
|
@@ -7613,10 +7613,10 @@ function getStorePath(filename) {
|
|
|
7613
7613
|
return join26(getStoreDir(), filename);
|
|
7614
7614
|
}
|
|
7615
7615
|
function loadJson(filename) {
|
|
7616
|
-
const
|
|
7617
|
-
if (existsSync29(
|
|
7616
|
+
const path52 = getStorePath(filename);
|
|
7617
|
+
if (existsSync29(path52)) {
|
|
7618
7618
|
try {
|
|
7619
|
-
return JSON.parse(readFileSync25(
|
|
7619
|
+
return JSON.parse(readFileSync25(path52, "utf-8"));
|
|
7620
7620
|
} catch {
|
|
7621
7621
|
return {};
|
|
7622
7622
|
}
|
|
@@ -8009,7 +8009,7 @@ function validateLine(line) {
|
|
|
8009
8009
|
process.exit(1);
|
|
8010
8010
|
}
|
|
8011
8011
|
}
|
|
8012
|
-
function comment2(
|
|
8012
|
+
function comment2(path52, line, body) {
|
|
8013
8013
|
validateBody(body);
|
|
8014
8014
|
validateLine(line);
|
|
8015
8015
|
try {
|
|
@@ -8029,7 +8029,7 @@ function comment2(path50, line, body) {
|
|
|
8029
8029
|
"-f",
|
|
8030
8030
|
`body=${body}`,
|
|
8031
8031
|
"-f",
|
|
8032
|
-
`path=${
|
|
8032
|
+
`path=${path52}`,
|
|
8033
8033
|
"-F",
|
|
8034
8034
|
`line=${line}`
|
|
8035
8035
|
],
|
|
@@ -8038,7 +8038,7 @@ function comment2(path50, line, body) {
|
|
|
8038
8038
|
if (result.status !== 0) {
|
|
8039
8039
|
throw new Error(result.stderr || result.stdout);
|
|
8040
8040
|
}
|
|
8041
|
-
console.log(`Added review comment on ${
|
|
8041
|
+
console.log(`Added review comment on ${path52}:${line}`);
|
|
8042
8042
|
} finally {
|
|
8043
8043
|
unlinkSync6(queryFile);
|
|
8044
8044
|
}
|
|
@@ -8537,8 +8537,8 @@ function registerPrs(program2) {
|
|
|
8537
8537
|
prsCommand.command("wontfix <comment-id> <reason>").description("Reply with reason and resolve thread").action((commentId, reason) => {
|
|
8538
8538
|
wontfix(Number.parseInt(commentId, 10), reason);
|
|
8539
8539
|
});
|
|
8540
|
-
prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((
|
|
8541
|
-
comment2(
|
|
8540
|
+
prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((path52, line, body) => {
|
|
8541
|
+
comment2(path52, Number.parseInt(line, 10), body);
|
|
8542
8542
|
});
|
|
8543
8543
|
}
|
|
8544
8544
|
|
|
@@ -8790,10 +8790,10 @@ function resolveOpSecret(reference) {
|
|
|
8790
8790
|
}
|
|
8791
8791
|
|
|
8792
8792
|
// src/commands/ravendb/ravenFetch.ts
|
|
8793
|
-
async function ravenFetch(connection,
|
|
8793
|
+
async function ravenFetch(connection, path52) {
|
|
8794
8794
|
const apiKey = resolveOpSecret(connection.apiKeyRef);
|
|
8795
8795
|
let accessToken = await getAccessToken(apiKey);
|
|
8796
|
-
const url = `${connection.url}${
|
|
8796
|
+
const url = `${connection.url}${path52}`;
|
|
8797
8797
|
const headers = {
|
|
8798
8798
|
Authorization: `Bearer ${accessToken}`,
|
|
8799
8799
|
"Content-Type": "application/json"
|
|
@@ -8883,16 +8883,16 @@ import chalk111 from "chalk";
|
|
|
8883
8883
|
// src/commands/ravendb/buildQueryPath.ts
|
|
8884
8884
|
function buildQueryPath(opts) {
|
|
8885
8885
|
const db = encodeURIComponent(opts.db);
|
|
8886
|
-
let
|
|
8886
|
+
let path52;
|
|
8887
8887
|
if (opts.collection) {
|
|
8888
|
-
|
|
8888
|
+
path52 = `/databases/${db}/indexes/dynamic/${encodeURIComponent(opts.collection)}?start=${opts.start}&pageSize=${opts.pageSize}&sort=${encodeURIComponent(opts.sort)}`;
|
|
8889
8889
|
} else {
|
|
8890
|
-
|
|
8890
|
+
path52 = `/databases/${db}/queries?start=${opts.start}&pageSize=${opts.pageSize}`;
|
|
8891
8891
|
}
|
|
8892
8892
|
if (opts.query) {
|
|
8893
|
-
|
|
8893
|
+
path52 += `&query=${encodeURIComponent(opts.query)}`;
|
|
8894
8894
|
}
|
|
8895
|
-
return
|
|
8895
|
+
return path52;
|
|
8896
8896
|
}
|
|
8897
8897
|
|
|
8898
8898
|
// src/commands/ravendb/fetchAllPages.ts
|
|
@@ -8901,7 +8901,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
8901
8901
|
let start3 = 0;
|
|
8902
8902
|
while (true) {
|
|
8903
8903
|
const effectivePageSize = opts.limit !== void 0 ? Math.min(opts.pageSize, opts.limit - allResults.length) : opts.pageSize;
|
|
8904
|
-
const
|
|
8904
|
+
const path52 = buildQueryPath({
|
|
8905
8905
|
db: connection.database,
|
|
8906
8906
|
collection: opts.collection,
|
|
8907
8907
|
start: start3,
|
|
@@ -8909,7 +8909,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
8909
8909
|
sort: opts.sort,
|
|
8910
8910
|
query: opts.query
|
|
8911
8911
|
});
|
|
8912
|
-
const data = await ravenFetch(connection,
|
|
8912
|
+
const data = await ravenFetch(connection, path52);
|
|
8913
8913
|
const results = data.Results ?? [];
|
|
8914
8914
|
const totalResults = data.TotalResults ?? 0;
|
|
8915
8915
|
if (results.length === 0) break;
|
|
@@ -10080,8 +10080,8 @@ function findRootParent(file, importedBy, visited) {
|
|
|
10080
10080
|
function clusterFiles(graph) {
|
|
10081
10081
|
const clusters = /* @__PURE__ */ new Map();
|
|
10082
10082
|
for (const file of graph.files) {
|
|
10083
|
-
const
|
|
10084
|
-
if (
|
|
10083
|
+
const basename8 = path39.basename(file, path39.extname(file));
|
|
10084
|
+
if (basename8 === "index") continue;
|
|
10085
10085
|
const importers = graph.importedBy.get(file);
|
|
10086
10086
|
if (!importers || importers.size !== 1) continue;
|
|
10087
10087
|
const parent = [...importers][0];
|
|
@@ -10531,8 +10531,8 @@ import chalk128 from "chalk";
|
|
|
10531
10531
|
|
|
10532
10532
|
// src/commands/seq/fetchSeq.ts
|
|
10533
10533
|
import chalk125 from "chalk";
|
|
10534
|
-
async function fetchSeq(conn,
|
|
10535
|
-
const url = `${conn.url}${
|
|
10534
|
+
async function fetchSeq(conn, path52, params) {
|
|
10535
|
+
const url = `${conn.url}${path52}?${params}`;
|
|
10536
10536
|
const response = await fetch(url, {
|
|
10537
10537
|
headers: {
|
|
10538
10538
|
Accept: "application/json",
|
|
@@ -12136,11 +12136,11 @@ function findLinkIndex() {
|
|
|
12136
12136
|
function parseLinkArgs() {
|
|
12137
12137
|
const idx = findLinkIndex();
|
|
12138
12138
|
if (idx === -1) return null;
|
|
12139
|
-
const
|
|
12139
|
+
const path52 = process.argv[idx + 1];
|
|
12140
12140
|
const rest = process.argv.slice(idx + 2);
|
|
12141
12141
|
const { value: prefix2 } = extractOption(rest, "--prefix");
|
|
12142
12142
|
if (!prefix2) return null;
|
|
12143
|
-
return { path:
|
|
12143
|
+
return { path: path52, prefix: prefix2 };
|
|
12144
12144
|
}
|
|
12145
12145
|
function hasDuplicateLink(runList, linkPath) {
|
|
12146
12146
|
return runList.some(
|
|
@@ -12468,9 +12468,23 @@ function handleSocket(ws, manager) {
|
|
|
12468
12468
|
data.rows
|
|
12469
12469
|
);
|
|
12470
12470
|
break;
|
|
12471
|
+
case "resume": {
|
|
12472
|
+
const id = manager.resume(
|
|
12473
|
+
data.sessionId,
|
|
12474
|
+
data.cwd,
|
|
12475
|
+
data.name
|
|
12476
|
+
);
|
|
12477
|
+
ws.send(JSON.stringify({ type: "created", sessionId: id }));
|
|
12478
|
+
break;
|
|
12479
|
+
}
|
|
12471
12480
|
case "dismiss":
|
|
12472
12481
|
manager.dismissSession(data.sessionId);
|
|
12473
12482
|
break;
|
|
12483
|
+
case "history":
|
|
12484
|
+
manager.getHistory().then((history) => {
|
|
12485
|
+
ws.send(JSON.stringify({ type: "history", sessions: history }));
|
|
12486
|
+
});
|
|
12487
|
+
break;
|
|
12474
12488
|
}
|
|
12475
12489
|
});
|
|
12476
12490
|
ws.on("close", () => {
|
|
@@ -12480,22 +12494,26 @@ function handleSocket(ws, manager) {
|
|
|
12480
12494
|
|
|
12481
12495
|
// src/commands/sessions/web/spawnClaude.ts
|
|
12482
12496
|
import * as pty from "node-pty";
|
|
12483
|
-
function spawnClaude2(
|
|
12497
|
+
function spawnClaude2(opts = {}) {
|
|
12484
12498
|
const shell = process.platform === "win32" ? "cmd.exe" : process.env.SHELL ?? "bash";
|
|
12485
|
-
const args = buildArgs(
|
|
12499
|
+
const args = buildArgs(opts);
|
|
12486
12500
|
return pty.spawn(shell, args, {
|
|
12487
12501
|
name: "xterm-256color",
|
|
12488
12502
|
cols: 120,
|
|
12489
12503
|
rows: 30,
|
|
12490
|
-
cwd: process.cwd(),
|
|
12504
|
+
cwd: opts.cwd ?? process.cwd(),
|
|
12491
12505
|
env: { ...process.env }
|
|
12492
12506
|
});
|
|
12493
12507
|
}
|
|
12494
|
-
function buildArgs(
|
|
12508
|
+
function buildArgs(opts) {
|
|
12509
|
+
const claudeArgs = opts.resumeSessionId ? ["claude", "--resume", opts.resumeSessionId] : opts.prompt ? ["claude", opts.prompt] : ["claude"];
|
|
12495
12510
|
if (process.platform === "win32") {
|
|
12496
|
-
return
|
|
12511
|
+
return ["/c", ...claudeArgs];
|
|
12497
12512
|
}
|
|
12498
|
-
return
|
|
12513
|
+
return ["-c", `exec ${claudeArgs.map(shellEscape).join(" ")}`];
|
|
12514
|
+
}
|
|
12515
|
+
function shellEscape(s) {
|
|
12516
|
+
return `'${s.replace(/'/g, "'\\''")}'`;
|
|
12499
12517
|
}
|
|
12500
12518
|
|
|
12501
12519
|
// src/commands/sessions/web/createSession.ts
|
|
@@ -12505,13 +12523,133 @@ function createSession(id, prompt) {
|
|
|
12505
12523
|
name: prompt?.slice(0, 40) || `Session ${id}`,
|
|
12506
12524
|
status: "running",
|
|
12507
12525
|
startedAt: Date.now(),
|
|
12508
|
-
pty: spawnClaude2(prompt),
|
|
12526
|
+
pty: spawnClaude2({ prompt }),
|
|
12527
|
+
scrollback: "",
|
|
12528
|
+
idleTimer: null,
|
|
12529
|
+
lastResizeAt: 0
|
|
12530
|
+
};
|
|
12531
|
+
}
|
|
12532
|
+
function resumeSession(id, sessionId, cwd, name) {
|
|
12533
|
+
return {
|
|
12534
|
+
id,
|
|
12535
|
+
name: name ? `${name.slice(0, 36)} (R)` : `Resume ${sessionId.slice(0, 8)}`,
|
|
12536
|
+
status: "running",
|
|
12537
|
+
startedAt: Date.now(),
|
|
12538
|
+
pty: spawnClaude2({ resumeSessionId: sessionId, cwd }),
|
|
12509
12539
|
scrollback: "",
|
|
12510
12540
|
idleTimer: null,
|
|
12511
12541
|
lastResizeAt: 0
|
|
12512
12542
|
};
|
|
12513
12543
|
}
|
|
12514
12544
|
|
|
12545
|
+
// src/commands/sessions/web/discoverSessions.ts
|
|
12546
|
+
import * as fs24 from "fs";
|
|
12547
|
+
import * as os from "os";
|
|
12548
|
+
import * as path47 from "path";
|
|
12549
|
+
|
|
12550
|
+
// src/commands/sessions/web/parseSessionFile.ts
|
|
12551
|
+
import * as fs23 from "fs";
|
|
12552
|
+
import * as path46 from "path";
|
|
12553
|
+
|
|
12554
|
+
// src/commands/sessions/web/extractSessionMeta.ts
|
|
12555
|
+
function extractSessionMeta(lines) {
|
|
12556
|
+
let sessionId = "";
|
|
12557
|
+
let cwd = "";
|
|
12558
|
+
let timestamp = "";
|
|
12559
|
+
let name = "";
|
|
12560
|
+
for (const line of lines) {
|
|
12561
|
+
const entry = safeParse(line);
|
|
12562
|
+
if (!entry) continue;
|
|
12563
|
+
sessionId ||= typeof entry.sessionId === "string" ? entry.sessionId : "";
|
|
12564
|
+
timestamp ||= typeof entry.timestamp === "string" ? entry.timestamp : "";
|
|
12565
|
+
cwd ||= typeof entry.cwd === "string" ? entry.cwd : "";
|
|
12566
|
+
if (entry.type === "user" && !entry.isMeta) {
|
|
12567
|
+
name = extractName(entry);
|
|
12568
|
+
break;
|
|
12569
|
+
}
|
|
12570
|
+
}
|
|
12571
|
+
return { sessionId, cwd, timestamp, name };
|
|
12572
|
+
}
|
|
12573
|
+
function safeParse(line) {
|
|
12574
|
+
try {
|
|
12575
|
+
return JSON.parse(line);
|
|
12576
|
+
} catch {
|
|
12577
|
+
return null;
|
|
12578
|
+
}
|
|
12579
|
+
}
|
|
12580
|
+
function extractName(entry) {
|
|
12581
|
+
const msg = entry.message;
|
|
12582
|
+
const content = msg?.content;
|
|
12583
|
+
const text = typeof content === "string" ? content : Array.isArray(content) ? content.find((c) => c.type === "text")?.text ?? "" : "";
|
|
12584
|
+
return text.replace(/<command-[^>]*>[^<]*<\/command-[^>]*>/g, "").trim().slice(0, 80);
|
|
12585
|
+
}
|
|
12586
|
+
|
|
12587
|
+
// src/commands/sessions/web/parseSessionFile.ts
|
|
12588
|
+
async function parseSessionFile(filePath) {
|
|
12589
|
+
let handle;
|
|
12590
|
+
try {
|
|
12591
|
+
handle = await fs23.promises.open(filePath, "r");
|
|
12592
|
+
const buf = Buffer.alloc(16384);
|
|
12593
|
+
const { bytesRead } = await handle.read(buf, 0, buf.length, 0);
|
|
12594
|
+
const lines = buf.toString("utf8", 0, bytesRead).split("\n").filter(Boolean);
|
|
12595
|
+
const meta = extractSessionMeta(lines);
|
|
12596
|
+
if (!meta.sessionId) return null;
|
|
12597
|
+
const timestamp = meta.timestamp || (await fs23.promises.stat(filePath)).mtime.toISOString();
|
|
12598
|
+
const project = meta.cwd ? path46.basename(meta.cwd) : dirNameToProject(filePath);
|
|
12599
|
+
return {
|
|
12600
|
+
sessionId: meta.sessionId,
|
|
12601
|
+
name: meta.name || `Session ${meta.sessionId.slice(0, 8)}`,
|
|
12602
|
+
project,
|
|
12603
|
+
cwd: meta.cwd,
|
|
12604
|
+
timestamp
|
|
12605
|
+
};
|
|
12606
|
+
} catch {
|
|
12607
|
+
return null;
|
|
12608
|
+
} finally {
|
|
12609
|
+
await handle?.close();
|
|
12610
|
+
}
|
|
12611
|
+
}
|
|
12612
|
+
function dirNameToProject(filePath) {
|
|
12613
|
+
const dirName = path46.basename(path46.dirname(filePath));
|
|
12614
|
+
const parts = dirName.split("--");
|
|
12615
|
+
return parts[parts.length - 1].replace(/-/g, "/");
|
|
12616
|
+
}
|
|
12617
|
+
|
|
12618
|
+
// src/commands/sessions/web/discoverSessions.ts
|
|
12619
|
+
async function discoverSessions() {
|
|
12620
|
+
const projectsDir = path47.join(os.homedir(), ".claude", "projects");
|
|
12621
|
+
let projectDirs;
|
|
12622
|
+
try {
|
|
12623
|
+
projectDirs = await fs24.promises.readdir(projectsDir);
|
|
12624
|
+
} catch {
|
|
12625
|
+
return [];
|
|
12626
|
+
}
|
|
12627
|
+
const sessions = [];
|
|
12628
|
+
await Promise.all(
|
|
12629
|
+
projectDirs.map(async (dirName) => {
|
|
12630
|
+
const dirPath = path47.join(projectsDir, dirName);
|
|
12631
|
+
let entries;
|
|
12632
|
+
try {
|
|
12633
|
+
entries = await fs24.promises.readdir(dirPath);
|
|
12634
|
+
} catch {
|
|
12635
|
+
return;
|
|
12636
|
+
}
|
|
12637
|
+
const jsonlFiles = entries.filter((e) => e.endsWith(".jsonl"));
|
|
12638
|
+
await Promise.all(
|
|
12639
|
+
jsonlFiles.map(async (file) => {
|
|
12640
|
+
const filePath = path47.join(dirPath, file);
|
|
12641
|
+
const session = await parseSessionFile(filePath);
|
|
12642
|
+
if (session) sessions.push(session);
|
|
12643
|
+
})
|
|
12644
|
+
);
|
|
12645
|
+
})
|
|
12646
|
+
);
|
|
12647
|
+
sessions.sort(
|
|
12648
|
+
(a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
|
|
12649
|
+
);
|
|
12650
|
+
return sessions;
|
|
12651
|
+
}
|
|
12652
|
+
|
|
12515
12653
|
// src/commands/sessions/web/scheduleIdle.ts
|
|
12516
12654
|
var IDLE_MS = 3e3;
|
|
12517
12655
|
function scheduleIdle(session, onIdle) {
|
|
@@ -12580,7 +12718,17 @@ var SessionManager = class {
|
|
|
12580
12718
|
spawn(prompt) {
|
|
12581
12719
|
const id = String(this.nextId++);
|
|
12582
12720
|
const session = createSession(id, prompt);
|
|
12583
|
-
this.
|
|
12721
|
+
this.wire(session);
|
|
12722
|
+
return id;
|
|
12723
|
+
}
|
|
12724
|
+
resume(sessionId, cwd, name) {
|
|
12725
|
+
const id = String(this.nextId++);
|
|
12726
|
+
const session = resumeSession(id, sessionId, cwd, name);
|
|
12727
|
+
this.wire(session);
|
|
12728
|
+
return id;
|
|
12729
|
+
}
|
|
12730
|
+
wire(session) {
|
|
12731
|
+
this.sessions.set(session.id, session);
|
|
12584
12732
|
wirePtyEvents(session, this.clients, (s, status2) => {
|
|
12585
12733
|
s.status = status2;
|
|
12586
12734
|
this.notify();
|
|
@@ -12590,7 +12738,6 @@ var SessionManager = class {
|
|
|
12590
12738
|
this.notify();
|
|
12591
12739
|
});
|
|
12592
12740
|
this.notify();
|
|
12593
|
-
return id;
|
|
12594
12741
|
}
|
|
12595
12742
|
writeToSession(id, data) {
|
|
12596
12743
|
const s = this.sessions.get(id);
|
|
@@ -12621,6 +12768,9 @@ var SessionManager = class {
|
|
|
12621
12768
|
})
|
|
12622
12769
|
);
|
|
12623
12770
|
}
|
|
12771
|
+
async getHistory() {
|
|
12772
|
+
return discoverSessions();
|
|
12773
|
+
}
|
|
12624
12774
|
notify() {
|
|
12625
12775
|
wsBroadcast(this.clients, {
|
|
12626
12776
|
type: "sessions",
|
|
@@ -12730,21 +12880,21 @@ async function statusLine() {
|
|
|
12730
12880
|
}
|
|
12731
12881
|
|
|
12732
12882
|
// src/commands/sync.ts
|
|
12733
|
-
import * as
|
|
12734
|
-
import * as
|
|
12735
|
-
import * as
|
|
12883
|
+
import * as fs27 from "fs";
|
|
12884
|
+
import * as os2 from "os";
|
|
12885
|
+
import * as path50 from "path";
|
|
12736
12886
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
12737
12887
|
|
|
12738
12888
|
// src/commands/sync/syncClaudeMd.ts
|
|
12739
|
-
import * as
|
|
12740
|
-
import * as
|
|
12889
|
+
import * as fs25 from "fs";
|
|
12890
|
+
import * as path48 from "path";
|
|
12741
12891
|
import chalk135 from "chalk";
|
|
12742
12892
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
12743
|
-
const source =
|
|
12744
|
-
const target =
|
|
12745
|
-
const sourceContent =
|
|
12746
|
-
if (
|
|
12747
|
-
const targetContent =
|
|
12893
|
+
const source = path48.join(claudeDir, "CLAUDE.md");
|
|
12894
|
+
const target = path48.join(targetBase, "CLAUDE.md");
|
|
12895
|
+
const sourceContent = fs25.readFileSync(source, "utf-8");
|
|
12896
|
+
if (fs25.existsSync(target)) {
|
|
12897
|
+
const targetContent = fs25.readFileSync(target, "utf-8");
|
|
12748
12898
|
if (sourceContent !== targetContent) {
|
|
12749
12899
|
console.log(
|
|
12750
12900
|
chalk135.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
@@ -12761,21 +12911,21 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
12761
12911
|
}
|
|
12762
12912
|
}
|
|
12763
12913
|
}
|
|
12764
|
-
|
|
12914
|
+
fs25.copyFileSync(source, target);
|
|
12765
12915
|
console.log("Copied CLAUDE.md to ~/.claude/CLAUDE.md");
|
|
12766
12916
|
}
|
|
12767
12917
|
|
|
12768
12918
|
// src/commands/sync/syncSettings.ts
|
|
12769
|
-
import * as
|
|
12770
|
-
import * as
|
|
12919
|
+
import * as fs26 from "fs";
|
|
12920
|
+
import * as path49 from "path";
|
|
12771
12921
|
import chalk136 from "chalk";
|
|
12772
12922
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
12773
|
-
const source =
|
|
12774
|
-
const target =
|
|
12775
|
-
const sourceContent =
|
|
12923
|
+
const source = path49.join(claudeDir, "settings.json");
|
|
12924
|
+
const target = path49.join(targetBase, "settings.json");
|
|
12925
|
+
const sourceContent = fs26.readFileSync(source, "utf-8");
|
|
12776
12926
|
const mergedContent = JSON.stringify(JSON.parse(sourceContent), null, " ");
|
|
12777
|
-
if (
|
|
12778
|
-
const targetContent =
|
|
12927
|
+
if (fs26.existsSync(target)) {
|
|
12928
|
+
const targetContent = fs26.readFileSync(target, "utf-8");
|
|
12779
12929
|
const normalizedTarget = JSON.stringify(
|
|
12780
12930
|
JSON.parse(targetContent),
|
|
12781
12931
|
null,
|
|
@@ -12801,29 +12951,29 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
12801
12951
|
}
|
|
12802
12952
|
}
|
|
12803
12953
|
}
|
|
12804
|
-
|
|
12954
|
+
fs26.writeFileSync(target, mergedContent);
|
|
12805
12955
|
console.log("Copied settings.json to ~/.claude/settings.json");
|
|
12806
12956
|
}
|
|
12807
12957
|
|
|
12808
12958
|
// src/commands/sync.ts
|
|
12809
12959
|
var __filename4 = fileURLToPath7(import.meta.url);
|
|
12810
|
-
var __dirname7 =
|
|
12960
|
+
var __dirname7 = path50.dirname(__filename4);
|
|
12811
12961
|
async function sync(options2) {
|
|
12812
12962
|
const config = loadConfig();
|
|
12813
12963
|
const yes = options2?.yes ?? config.sync.autoConfirm;
|
|
12814
|
-
const claudeDir =
|
|
12815
|
-
const targetBase =
|
|
12964
|
+
const claudeDir = path50.join(__dirname7, "..", "claude");
|
|
12965
|
+
const targetBase = path50.join(os2.homedir(), ".claude");
|
|
12816
12966
|
syncCommands(claudeDir, targetBase);
|
|
12817
12967
|
await syncSettings(claudeDir, targetBase, { yes });
|
|
12818
12968
|
await syncClaudeMd(claudeDir, targetBase, { yes });
|
|
12819
12969
|
}
|
|
12820
12970
|
function syncCommands(claudeDir, targetBase) {
|
|
12821
|
-
const sourceDir =
|
|
12822
|
-
const targetDir =
|
|
12823
|
-
|
|
12824
|
-
const files =
|
|
12971
|
+
const sourceDir = path50.join(claudeDir, "commands");
|
|
12972
|
+
const targetDir = path50.join(targetBase, "commands");
|
|
12973
|
+
fs27.mkdirSync(targetDir, { recursive: true });
|
|
12974
|
+
const files = fs27.readdirSync(sourceDir);
|
|
12825
12975
|
for (const file of files) {
|
|
12826
|
-
|
|
12976
|
+
fs27.copyFileSync(path50.join(sourceDir, file), path50.join(targetDir, file));
|
|
12827
12977
|
console.log(`Copied ${file} to ${targetDir}`);
|
|
12828
12978
|
}
|
|
12829
12979
|
console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
|
|
@@ -12831,15 +12981,15 @@ function syncCommands(claudeDir, targetBase) {
|
|
|
12831
12981
|
|
|
12832
12982
|
// src/commands/update.ts
|
|
12833
12983
|
import { execSync as execSync42 } from "child_process";
|
|
12834
|
-
import * as
|
|
12984
|
+
import * as path51 from "path";
|
|
12835
12985
|
function isGlobalNpmInstall(dir) {
|
|
12836
12986
|
try {
|
|
12837
|
-
const resolved =
|
|
12838
|
-
if (resolved.split(
|
|
12987
|
+
const resolved = path51.resolve(dir);
|
|
12988
|
+
if (resolved.split(path51.sep).includes("node_modules")) {
|
|
12839
12989
|
return true;
|
|
12840
12990
|
}
|
|
12841
12991
|
const globalPrefix = execSync42("npm prefix -g", { stdio: "pipe" }).toString().trim();
|
|
12842
|
-
return resolved.toLowerCase().startsWith(
|
|
12992
|
+
return resolved.toLowerCase().startsWith(path51.resolve(globalPrefix).toLowerCase());
|
|
12843
12993
|
} catch {
|
|
12844
12994
|
return false;
|
|
12845
12995
|
}
|