autodev-cli 1.4.109 → 1.4.111
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/out/agentBackup/opencodeDb.d.ts +21 -0
- package/out/agentBackup/opencodeDb.js +103 -0
- package/out/agentBackup/opencodeDb.js.map +1 -1
- package/out/commands/sessions.js +56 -1
- package/out/commands/sessions.js.map +1 -1
- package/out/core/settingsLoader.d.ts +7 -0
- package/out/core/settingsLoader.js +20 -0
- package/out/core/settingsLoader.js.map +1 -1
- package/out/providers/claudeCliProvider.d.ts +24 -0
- package/out/providers/claudeCliProvider.js +249 -0
- package/out/providers/claudeCliProvider.js.map +1 -1
- package/out/providers/copilotSessions.d.ts +25 -0
- package/out/providers/copilotSessions.js +214 -0
- package/out/providers/copilotSessions.js.map +1 -0
- package/out/providers/grokSessions.d.ts +21 -0
- package/out/providers/grokSessions.js +150 -0
- package/out/providers/grokSessions.js.map +1 -1
- package/out/sessions.js +7 -0
- package/out/sessions.js.map +1 -1
- package/out/sessionsGlobal.d.ts +32 -0
- package/out/sessionsGlobal.js +81 -0
- package/out/sessionsGlobal.js.map +1 -0
- package/out/taskLoop.js +23 -0
- package/out/taskLoop.js.map +1 -1
- package/package.json +2 -2
|
@@ -17,4 +17,25 @@ export declare function listOpenCodeSessionsDetailed(root: string): Array<{
|
|
|
17
17
|
title: string;
|
|
18
18
|
updated: number;
|
|
19
19
|
}>;
|
|
20
|
+
/** ALL opencode sessions across every workspace (newest first), carrying each
|
|
21
|
+
* row's own `directory` as cwd. Same store as {@link listOpenCodeSessionsDetailed}
|
|
22
|
+
* but unfiltered — for global cross-workspace discovery. `updated` is epoch ms. */
|
|
23
|
+
export declare function listAllOpenCodeSessions(): Array<{
|
|
24
|
+
id: string;
|
|
25
|
+
title: string;
|
|
26
|
+
updated: number;
|
|
27
|
+
cwd: string;
|
|
28
|
+
}>;
|
|
29
|
+
export interface TranscriptMsg {
|
|
30
|
+
role: 'user' | 'assistant' | 'system' | 'tool';
|
|
31
|
+
text: string;
|
|
32
|
+
ts?: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Read an opencode session's messages into a normalized array. A message's
|
|
36
|
+
* role lives in the `message.data` JSON; its rendered text is assembled from
|
|
37
|
+
* the child `part` rows (part.data = {type:'text'|'tool'|…, text?, …}). Ordered
|
|
38
|
+
* by creation time; returns at most `limit` messages (the tail). [] on any miss.
|
|
39
|
+
*/
|
|
40
|
+
export declare function readOpenCodeTranscript(sessionId: string, limit?: number): TranscriptMsg[];
|
|
20
41
|
export {};
|
|
@@ -50,6 +50,8 @@ exports.opencodeDbPath = opencodeDbPath;
|
|
|
50
50
|
exports.dumpOpenCodeSessions = dumpOpenCodeSessions;
|
|
51
51
|
exports.restoreOpenCodeSessions = restoreOpenCodeSessions;
|
|
52
52
|
exports.listOpenCodeSessionsDetailed = listOpenCodeSessionsDetailed;
|
|
53
|
+
exports.listAllOpenCodeSessions = listAllOpenCodeSessions;
|
|
54
|
+
exports.readOpenCodeTranscript = readOpenCodeTranscript;
|
|
53
55
|
const fs = __importStar(require("fs"));
|
|
54
56
|
const os = __importStar(require("os"));
|
|
55
57
|
const path = __importStar(require("path"));
|
|
@@ -210,4 +212,105 @@ function listOpenCodeSessionsDetailed(root) {
|
|
|
210
212
|
catch { /* ignore */ }
|
|
211
213
|
}
|
|
212
214
|
}
|
|
215
|
+
/** ALL opencode sessions across every workspace (newest first), carrying each
|
|
216
|
+
* row's own `directory` as cwd. Same store as {@link listOpenCodeSessionsDetailed}
|
|
217
|
+
* but unfiltered — for global cross-workspace discovery. `updated` is epoch ms. */
|
|
218
|
+
function listAllOpenCodeSessions() {
|
|
219
|
+
const dbFile = opencodeDbPath();
|
|
220
|
+
if (!fs.existsSync(dbFile)) {
|
|
221
|
+
return [];
|
|
222
|
+
}
|
|
223
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
224
|
+
let db;
|
|
225
|
+
try {
|
|
226
|
+
db = openDb(dbFile, true);
|
|
227
|
+
return db.prepare('SELECT id, title, directory, time_updated FROM session').all()
|
|
228
|
+
.map(r => ({
|
|
229
|
+
id: String(r.id),
|
|
230
|
+
title: String(r.title ?? ''),
|
|
231
|
+
updated: Number(r.time_updated ?? 0),
|
|
232
|
+
cwd: String(r.directory ?? ''),
|
|
233
|
+
}))
|
|
234
|
+
.sort((a, b) => b.updated - a.updated);
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
return [];
|
|
238
|
+
}
|
|
239
|
+
finally {
|
|
240
|
+
try {
|
|
241
|
+
db?.close();
|
|
242
|
+
}
|
|
243
|
+
catch { /* ignore */ }
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Read an opencode session's messages into a normalized array. A message's
|
|
248
|
+
* role lives in the `message.data` JSON; its rendered text is assembled from
|
|
249
|
+
* the child `part` rows (part.data = {type:'text'|'tool'|…, text?, …}). Ordered
|
|
250
|
+
* by creation time; returns at most `limit` messages (the tail). [] on any miss.
|
|
251
|
+
*/
|
|
252
|
+
function readOpenCodeTranscript(sessionId, limit = 400) {
|
|
253
|
+
const dbFile = opencodeDbPath();
|
|
254
|
+
if (!fs.existsSync(dbFile)) {
|
|
255
|
+
return [];
|
|
256
|
+
}
|
|
257
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
258
|
+
let db;
|
|
259
|
+
const trunc = (s, max) => (s.length > max ? s.slice(0, max) + '…' : s);
|
|
260
|
+
try {
|
|
261
|
+
db = openDb(dbFile, true);
|
|
262
|
+
const messages = db.prepare('SELECT id, time_created, data FROM message WHERE session_id = ? ORDER BY time_created ASC').all(sessionId);
|
|
263
|
+
const parts = db.prepare('SELECT message_id, time_created, data FROM part WHERE session_id = ? ORDER BY time_created ASC').all(sessionId);
|
|
264
|
+
const partsByMsg = new Map();
|
|
265
|
+
for (const p of parts) {
|
|
266
|
+
const mid = String(p.message_id);
|
|
267
|
+
if (!partsByMsg.has(mid)) {
|
|
268
|
+
partsByMsg.set(mid, []);
|
|
269
|
+
}
|
|
270
|
+
partsByMsg.get(mid).push(p);
|
|
271
|
+
}
|
|
272
|
+
const out = [];
|
|
273
|
+
for (const m of messages) {
|
|
274
|
+
let role = 'assistant';
|
|
275
|
+
try {
|
|
276
|
+
const md = JSON.parse(String(m.data ?? '{}'));
|
|
277
|
+
if (md.role === 'user' || md.role === 'assistant' || md.role === 'system') {
|
|
278
|
+
role = md.role;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
catch { /* default assistant */ }
|
|
282
|
+
const ts = Number(m.time_created ?? 0) || undefined;
|
|
283
|
+
for (const p of partsByMsg.get(String(m.id)) ?? []) {
|
|
284
|
+
let pd;
|
|
285
|
+
try {
|
|
286
|
+
pd = JSON.parse(String(p.data ?? '{}'));
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
if (pd.type === 'text' && pd.text) {
|
|
292
|
+
if (pd.text.trim()) {
|
|
293
|
+
out.push({ role, text: pd.text.trim(), ts });
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
else if (pd.type === 'tool') {
|
|
297
|
+
const name = pd.tool || 'tool';
|
|
298
|
+
const output = pd.state?.output;
|
|
299
|
+
const outTxt = output == null ? '' : (typeof output === 'string' ? output : JSON.stringify(output));
|
|
300
|
+
out.push({ role: 'tool', text: outTxt.trim() ? `🔧 ${name} ↳ ${trunc(outTxt.trim(), 400)}` : `🔧 ${name}`, ts });
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return out.slice(-limit);
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
return [];
|
|
308
|
+
}
|
|
309
|
+
finally {
|
|
310
|
+
try {
|
|
311
|
+
db?.close();
|
|
312
|
+
}
|
|
313
|
+
catch { /* ignore */ }
|
|
314
|
+
}
|
|
315
|
+
}
|
|
213
316
|
//# sourceMappingURL=opencodeDb.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencodeDb.js","sourceRoot":"","sources":["../../src/agentBackup/opencodeDb.ts"],"names":[],"mappings":";AAAA,8EAA8E;AAC9E,8EAA8E;AAC9E,6EAA6E;AAC7E,EAAE;AACF,4EAA4E;AAC5E,2EAA2E;AAC3E,wEAAwE;AACxE,iFAAiF;AACjF,EAAE;AACF,8EAA8E;AAC9E,8EAA8E;AAC9E,0DAA0D;AAC1D,8EAA8E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuB9E,wCAGC;AAWD,oDA0BC;AAGD,0DAgCC;AAaD,oEAaC;
|
|
1
|
+
{"version":3,"file":"opencodeDb.js","sourceRoot":"","sources":["../../src/agentBackup/opencodeDb.ts"],"names":[],"mappings":"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"}
|
package/out/commands/sessions.js
CHANGED
|
@@ -37,13 +37,35 @@ exports.sessionsCommand = sessionsCommand;
|
|
|
37
37
|
const path = __importStar(require("path"));
|
|
38
38
|
const logger_1 = require("../logger");
|
|
39
39
|
const sessions_1 = require("../sessions");
|
|
40
|
+
const sessionsGlobal_1 = require("../sessionsGlobal");
|
|
40
41
|
function sessionsCommand(program) {
|
|
41
42
|
program
|
|
42
43
|
.command('sessions [path]')
|
|
43
44
|
.description('List existing AI sessions for a workspace (id, name, last updated)')
|
|
44
45
|
.option('--json', 'Output JSON')
|
|
45
|
-
.option('
|
|
46
|
+
.option('--all', 'List sessions across ALL workspaces on this machine (ignores [path]); normalized shape with provider + cwd')
|
|
47
|
+
.option('-p, --provider <provider>', 'Only list sessions for this provider family (claude|opencode|grok|copilot); omit to list all inspectable stores')
|
|
46
48
|
.action((workspacePath, opts) => {
|
|
49
|
+
// --- Global mode: every workspace, normalized cross-provider shape ---
|
|
50
|
+
if (opts.all) {
|
|
51
|
+
const fam = (0, sessionsGlobal_1.normalizeSessionProvider)(opts.provider);
|
|
52
|
+
const sessions = (0, sessionsGlobal_1.collectAllSessions)(fam);
|
|
53
|
+
if (opts.json) {
|
|
54
|
+
process.stdout.write(JSON.stringify(sessions, null, 2) + '\n');
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
logger_1.log.section('🗂 Sessions (all workspaces)');
|
|
58
|
+
if (sessions.length === 0) {
|
|
59
|
+
logger_1.log.gray(' (no inspectable sessions found)');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
for (const s of sessions) {
|
|
63
|
+
const when = s.updated ? new Date(s.updated).toISOString().slice(0, 16).replace('T', ' ') : '—';
|
|
64
|
+
logger_1.log.plain(` [${s.provider}] ${s.name} · ${s.id} · ${s.cwd || '?'} · ${when}`);
|
|
65
|
+
}
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
// --- Per-workspace mode (unchanged) ---
|
|
47
69
|
const cwd = workspacePath ? path.resolve(workspacePath) : process.cwd();
|
|
48
70
|
const sessions = (0, sessions_1.collectSessions)(cwd, opts.provider);
|
|
49
71
|
if (opts.json) {
|
|
@@ -61,5 +83,38 @@ function sessionsCommand(program) {
|
|
|
61
83
|
logger_1.log.plain(` [${s.provider}] ${s.name} · ${s.id} · ${when}`);
|
|
62
84
|
}
|
|
63
85
|
});
|
|
86
|
+
program
|
|
87
|
+
.command('session-show <id>')
|
|
88
|
+
.description('Print a session transcript as a normalized message array (--json)')
|
|
89
|
+
.requiredOption('-p, --provider <provider>', 'Provider family the session belongs to (claude|grok|opencode|copilot)')
|
|
90
|
+
.option('--json', 'Output JSON')
|
|
91
|
+
.option('--file <file>', 'Explicit transcript file (claude) — skips the id lookup')
|
|
92
|
+
.option('--cwd <cwd>', 'Workspace path hint (grok) — speeds up transcript resolution')
|
|
93
|
+
.option('--limit <n>', 'Cap the number of messages returned (default 400)', (v) => parseInt(v, 10))
|
|
94
|
+
.action((id, opts) => {
|
|
95
|
+
const fam = (0, sessionsGlobal_1.normalizeSessionProvider)(opts.provider);
|
|
96
|
+
if (!fam) {
|
|
97
|
+
if (opts.json) {
|
|
98
|
+
process.stdout.write('[]\n');
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
logger_1.log.error(`Unknown provider "${opts.provider}" (expected claude|grok|opencode|copilot)`);
|
|
102
|
+
}
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const msgs = (0, sessionsGlobal_1.readSessionTranscript)(fam, id, { file: opts.file, cwd: opts.cwd, limit: opts.limit });
|
|
106
|
+
if (opts.json) {
|
|
107
|
+
process.stdout.write(JSON.stringify(msgs, null, 2) + '\n');
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
logger_1.log.section(`🗂 ${fam} session ${id.slice(0, 8)} (${msgs.length} msgs)`);
|
|
111
|
+
if (msgs.length === 0) {
|
|
112
|
+
logger_1.log.gray(' (no messages / transcript not found)');
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
for (const m of msgs) {
|
|
116
|
+
logger_1.log.plain(` [${m.role}] ${m.text.length > 200 ? m.text.slice(0, 200) + '…' : m.text}`);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
64
119
|
}
|
|
65
120
|
//# sourceMappingURL=sessions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/commands/sessions.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/commands/sessions.ts"],"names":[],"mappings":"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"}
|
|
@@ -251,6 +251,13 @@ export declare const NEW_SETTINGS_REL_PATH = ".autodev/settings.json";
|
|
|
251
251
|
export declare const LEGACY_SETTINGS_REL_PATH = ".vscode/autodev.json";
|
|
252
252
|
/** Path that should be used for writes (always the new canonical location). */
|
|
253
253
|
export declare function settingsWritePath(root: string): string;
|
|
254
|
+
/**
|
|
255
|
+
* True when `key` is EXPLICITLY present in the workspace's raw settings file —
|
|
256
|
+
* i.e. the user (or a spawn flow) actually wrote it, as opposed to it falling
|
|
257
|
+
* back to SETTINGS_DEFAULTS after the `{...defaults, ...raw}` merge. Lets callers
|
|
258
|
+
* tell an explicit `false` apart from a defaulted `false` (e.g. resumeSession).
|
|
259
|
+
*/
|
|
260
|
+
export declare function hasExplicitSetting(root: string, key: keyof AutodevSettings): boolean;
|
|
254
261
|
/** Path that should be used for reads — canonical if present, else legacy. */
|
|
255
262
|
export declare function settingsReadPath(root: string): string;
|
|
256
263
|
/** Load settings, preferring `.autodev/settings.json` and falling back to the legacy `.vscode/autodev.json`. */
|
|
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.LEGACY_SETTINGS_REL_PATH = exports.NEW_SETTINGS_REL_PATH = exports.SETTINGS_DEFAULTS = void 0;
|
|
37
37
|
exports.parseWsUrl = parseWsUrl;
|
|
38
38
|
exports.settingsWritePath = settingsWritePath;
|
|
39
|
+
exports.hasExplicitSetting = hasExplicitSetting;
|
|
39
40
|
exports.settingsReadPath = settingsReadPath;
|
|
40
41
|
exports.loadSettingsForRoot = loadSettingsForRoot;
|
|
41
42
|
const fs = __importStar(require("fs"));
|
|
@@ -142,6 +143,25 @@ exports.LEGACY_SETTINGS_REL_PATH = '.vscode/autodev.json';
|
|
|
142
143
|
function settingsWritePath(root) {
|
|
143
144
|
return path.join(root, '.autodev', 'settings.json');
|
|
144
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* True when `key` is EXPLICITLY present in the workspace's raw settings file —
|
|
148
|
+
* i.e. the user (or a spawn flow) actually wrote it, as opposed to it falling
|
|
149
|
+
* back to SETTINGS_DEFAULTS after the `{...defaults, ...raw}` merge. Lets callers
|
|
150
|
+
* tell an explicit `false` apart from a defaulted `false` (e.g. resumeSession).
|
|
151
|
+
*/
|
|
152
|
+
function hasExplicitSetting(root, key) {
|
|
153
|
+
try {
|
|
154
|
+
const file = settingsReadPath(root);
|
|
155
|
+
if (!fs.existsSync(file)) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
const raw = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
159
|
+
return Object.prototype.hasOwnProperty.call(raw, key);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
145
165
|
/** Path that should be used for reads — canonical if present, else legacy. */
|
|
146
166
|
function settingsReadPath(root) {
|
|
147
167
|
const canonical = path.join(root, '.autodev', 'settings.json');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settingsLoader.js","sourceRoot":"","sources":["../../src/core/settingsLoader.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyTA,gCAWC;AAiBD,8CAEC;AAGD,4CAMC;AA0BD,kDA0BC;
|
|
1
|
+
{"version":3,"file":"settingsLoader.js","sourceRoot":"","sources":["../../src/core/settingsLoader.ts"],"names":[],"mappings":"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"}
|
|
@@ -34,6 +34,30 @@ export declare function findLatestClaudeSession(workspacePath: string): string |
|
|
|
34
34
|
* (latest `display` for this sessionId in ~/.claude/history.jsonl). */
|
|
35
35
|
export declare function getClaudeSessionDisplay(sessionId: string): string | undefined;
|
|
36
36
|
export declare function setClaudeSessionName(sessionId: string, name: string, cwd: string): void;
|
|
37
|
+
export interface ClaudeGlobalSession {
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
cwd: string;
|
|
41
|
+
updated: number;
|
|
42
|
+
file: string;
|
|
43
|
+
msgs: number;
|
|
44
|
+
}
|
|
45
|
+
/** ALL claude sessions across every ~/.claude/projects folder (newest first).
|
|
46
|
+
* Mirrors the app's sessionManager.discover(): skip `agent-` transcripts,
|
|
47
|
+
* derive cwd from the transcript's own `cwd` (folder-name decode fallback). */
|
|
48
|
+
export declare function listAllClaudeSessions(): ClaudeGlobalSession[];
|
|
49
|
+
export interface TranscriptMsg {
|
|
50
|
+
role: 'user' | 'assistant' | 'system' | 'tool';
|
|
51
|
+
text: string;
|
|
52
|
+
ts?: number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Read a claude session transcript (by id, or an explicit `file`) into a
|
|
56
|
+
* normalized message array. Reuses the same parse shape the app uses: type
|
|
57
|
+
* user/assistant/system with tool_use/tool_result rendering. Reads only the
|
|
58
|
+
* tail of huge transcripts. Returns at most `limit` messages. [] on any miss.
|
|
59
|
+
*/
|
|
60
|
+
export declare function readClaudeTranscript(id: string, file?: string, limit?: number): TranscriptMsg[];
|
|
37
61
|
export declare function getClaudeSessionCursor(workspacePath: string): number;
|
|
38
62
|
export interface ClaudeSessionState {
|
|
39
63
|
/** True if a definitive turn-end was detected. */
|
|
@@ -40,6 +40,8 @@ exports.listClaudeSessions = listClaudeSessions;
|
|
|
40
40
|
exports.findLatestClaudeSession = findLatestClaudeSession;
|
|
41
41
|
exports.getClaudeSessionDisplay = getClaudeSessionDisplay;
|
|
42
42
|
exports.setClaudeSessionName = setClaudeSessionName;
|
|
43
|
+
exports.listAllClaudeSessions = listAllClaudeSessions;
|
|
44
|
+
exports.readClaudeTranscript = readClaudeTranscript;
|
|
43
45
|
exports.getClaudeSessionCursor = getClaudeSessionCursor;
|
|
44
46
|
exports.parseClaudeStateSince = parseClaudeStateSince;
|
|
45
47
|
exports.hasClaudeEndTurnSince = hasClaudeEndTurnSince;
|
|
@@ -177,6 +179,253 @@ function setClaudeSessionName(sessionId, name, cwd) {
|
|
|
177
179
|
function resolveClaudeJsonl(workspacePath) {
|
|
178
180
|
return listClaudeSessionFiles(workspacePath)[0]?.full;
|
|
179
181
|
}
|
|
182
|
+
// ---------------------------------------------------------------------------
|
|
183
|
+
// Global (cross-workspace) discovery + transcript reading
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
/** Decode a `~/.claude/projects` folder name back to a plausible cwd. Lossy
|
|
186
|
+
* (dashes in real names collapse), so callers prefer the transcript's own cwd. */
|
|
187
|
+
function decodeClaudeProject(folder) {
|
|
188
|
+
return '/' + folder.replace(/^-+/, '').replace(/-/g, '/');
|
|
189
|
+
}
|
|
190
|
+
/** sessionId → newest display title, from ~/.claude/history.jsonl. */
|
|
191
|
+
function claudeTitleMap() {
|
|
192
|
+
const m = new Map();
|
|
193
|
+
try {
|
|
194
|
+
const claudeDir = process.env['CLAUDE_CONFIG_DIR'] ?? path.join(os.homedir(), '.claude');
|
|
195
|
+
const histFile = path.join(claudeDir, 'history.jsonl');
|
|
196
|
+
if (!fs.existsSync(histFile)) {
|
|
197
|
+
return m;
|
|
198
|
+
}
|
|
199
|
+
for (const line of fs.readFileSync(histFile, 'utf8').split('\n')) {
|
|
200
|
+
if (!line.trim()) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
const e = JSON.parse(line);
|
|
205
|
+
if (e.sessionId && e.display) {
|
|
206
|
+
m.set(e.sessionId, e.display);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
catch { /* skip */ }
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
catch { /* none */ }
|
|
213
|
+
return m;
|
|
214
|
+
}
|
|
215
|
+
/** Peek a transcript head for its real cwd, a first-user title hint, and a
|
|
216
|
+
* message-count floor (bounded read so discovery never loads 100s of MB). */
|
|
217
|
+
function peekClaudeTranscript(file, size) {
|
|
218
|
+
let cwd;
|
|
219
|
+
let firstUser;
|
|
220
|
+
let count = 0;
|
|
221
|
+
const MAX = 256_000;
|
|
222
|
+
try {
|
|
223
|
+
let text;
|
|
224
|
+
if (size > MAX) {
|
|
225
|
+
const fd = fs.openSync(file, 'r');
|
|
226
|
+
try {
|
|
227
|
+
const buf = Buffer.alloc(MAX);
|
|
228
|
+
fs.readSync(fd, buf, 0, MAX, 0);
|
|
229
|
+
text = buf.toString('utf8');
|
|
230
|
+
}
|
|
231
|
+
finally {
|
|
232
|
+
fs.closeSync(fd);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
text = fs.readFileSync(file, 'utf8');
|
|
237
|
+
}
|
|
238
|
+
for (const line of text.split('\n')) {
|
|
239
|
+
if (!line.trim()) {
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
count++;
|
|
243
|
+
try {
|
|
244
|
+
const o = JSON.parse(line);
|
|
245
|
+
if (!cwd && typeof o['cwd'] === 'string') {
|
|
246
|
+
cwd = o['cwd'];
|
|
247
|
+
}
|
|
248
|
+
if (!firstUser && o['type'] === 'user') {
|
|
249
|
+
const t = extractClaudeText(o['message']);
|
|
250
|
+
if (t) {
|
|
251
|
+
firstUser = t.slice(0, 80);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
catch { /* skip */ }
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
catch { /* unreadable */ }
|
|
259
|
+
return { cwd, firstUser, count };
|
|
260
|
+
}
|
|
261
|
+
/** ALL claude sessions across every ~/.claude/projects folder (newest first).
|
|
262
|
+
* Mirrors the app's sessionManager.discover(): skip `agent-` transcripts,
|
|
263
|
+
* derive cwd from the transcript's own `cwd` (folder-name decode fallback). */
|
|
264
|
+
function listAllClaudeSessions() {
|
|
265
|
+
const claudeDir = process.env['CLAUDE_CONFIG_DIR'] ?? path.join(os.homedir(), '.claude');
|
|
266
|
+
const projects = path.join(claudeDir, 'projects');
|
|
267
|
+
if (!fs.existsSync(projects)) {
|
|
268
|
+
return [];
|
|
269
|
+
}
|
|
270
|
+
const titles = claudeTitleMap();
|
|
271
|
+
const out = [];
|
|
272
|
+
let folders = [];
|
|
273
|
+
try {
|
|
274
|
+
folders = fs.readdirSync(projects);
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
return [];
|
|
278
|
+
}
|
|
279
|
+
for (const folder of folders) {
|
|
280
|
+
const dir = path.join(projects, folder);
|
|
281
|
+
let files = [];
|
|
282
|
+
try {
|
|
283
|
+
if (!fs.statSync(dir).isDirectory()) {
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
files = fs.readdirSync(dir).filter(f => f.endsWith('.jsonl') && !f.startsWith('agent-'));
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
for (const f of files) {
|
|
292
|
+
const file = path.join(dir, f);
|
|
293
|
+
const id = f.replace(/\.jsonl$/, '');
|
|
294
|
+
let st;
|
|
295
|
+
try {
|
|
296
|
+
st = fs.statSync(file);
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
const peek = peekClaudeTranscript(file, st.size);
|
|
302
|
+
out.push({
|
|
303
|
+
id,
|
|
304
|
+
name: titles.get(id) || peek.firstUser || '(untitled)',
|
|
305
|
+
cwd: peek.cwd || decodeClaudeProject(folder),
|
|
306
|
+
updated: st.mtimeMs,
|
|
307
|
+
file,
|
|
308
|
+
msgs: peek.count,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return out.sort((a, b) => b.updated - a.updated);
|
|
313
|
+
}
|
|
314
|
+
/** Pull readable text out of a claude transcript entry's `message` (string or
|
|
315
|
+
* array content, rendering tool_use / tool_result blocks compactly). */
|
|
316
|
+
function extractClaudeText(message) {
|
|
317
|
+
if (!message) {
|
|
318
|
+
return '';
|
|
319
|
+
}
|
|
320
|
+
const c = message['content'];
|
|
321
|
+
if (typeof c === 'string') {
|
|
322
|
+
return c;
|
|
323
|
+
}
|
|
324
|
+
if (Array.isArray(c)) {
|
|
325
|
+
const short = (v) => {
|
|
326
|
+
try {
|
|
327
|
+
const s = typeof v === 'string' ? v : JSON.stringify(v);
|
|
328
|
+
return s.length > 200 ? s.slice(0, 200) + '…' : s;
|
|
329
|
+
}
|
|
330
|
+
catch {
|
|
331
|
+
return '';
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
return c.map(b => {
|
|
335
|
+
if (b['type'] === 'text') {
|
|
336
|
+
return String(b['text'] ?? '');
|
|
337
|
+
}
|
|
338
|
+
if (b['type'] === 'tool_use') {
|
|
339
|
+
return `🔧 ${String(b['name'] ?? '')}(${short(b['input'])})`;
|
|
340
|
+
}
|
|
341
|
+
if (b['type'] === 'tool_result') {
|
|
342
|
+
return `↳ ${short(b['content'])}`;
|
|
343
|
+
}
|
|
344
|
+
return '';
|
|
345
|
+
}).filter(Boolean).join('\n');
|
|
346
|
+
}
|
|
347
|
+
return '';
|
|
348
|
+
}
|
|
349
|
+
/** Locate a claude transcript by session id across all project folders. */
|
|
350
|
+
function findClaudeTranscriptById(id) {
|
|
351
|
+
const claudeDir = process.env['CLAUDE_CONFIG_DIR'] ?? path.join(os.homedir(), '.claude');
|
|
352
|
+
const projects = path.join(claudeDir, 'projects');
|
|
353
|
+
try {
|
|
354
|
+
for (const folder of fs.readdirSync(projects)) {
|
|
355
|
+
const file = path.join(projects, folder, `${id}.jsonl`);
|
|
356
|
+
if (fs.existsSync(file)) {
|
|
357
|
+
return file;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
catch { /* none */ }
|
|
362
|
+
return undefined;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Read a claude session transcript (by id, or an explicit `file`) into a
|
|
366
|
+
* normalized message array. Reuses the same parse shape the app uses: type
|
|
367
|
+
* user/assistant/system with tool_use/tool_result rendering. Reads only the
|
|
368
|
+
* tail of huge transcripts. Returns at most `limit` messages. [] on any miss.
|
|
369
|
+
*/
|
|
370
|
+
function readClaudeTranscript(id, file, limit = 400) {
|
|
371
|
+
const p = file && fs.existsSync(file) ? file : findClaudeTranscriptById(id);
|
|
372
|
+
if (!p) {
|
|
373
|
+
return [];
|
|
374
|
+
}
|
|
375
|
+
let text = '';
|
|
376
|
+
try {
|
|
377
|
+
const size = fs.statSync(p).size;
|
|
378
|
+
const MAX = 2_000_000; // last ~2 MB is plenty for `limit` messages
|
|
379
|
+
if (size > MAX) {
|
|
380
|
+
const fd = fs.openSync(p, 'r');
|
|
381
|
+
try {
|
|
382
|
+
const buf = Buffer.alloc(MAX);
|
|
383
|
+
fs.readSync(fd, buf, 0, MAX, size - MAX);
|
|
384
|
+
text = buf.toString('utf8');
|
|
385
|
+
}
|
|
386
|
+
finally {
|
|
387
|
+
fs.closeSync(fd);
|
|
388
|
+
}
|
|
389
|
+
const nl = text.indexOf('\n');
|
|
390
|
+
if (nl >= 0) {
|
|
391
|
+
text = text.slice(nl + 1);
|
|
392
|
+
} // drop the partial first line
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
text = fs.readFileSync(p, 'utf8');
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
catch {
|
|
399
|
+
return [];
|
|
400
|
+
}
|
|
401
|
+
const msgs = [];
|
|
402
|
+
for (const line of text.split('\n')) {
|
|
403
|
+
if (!line.trim()) {
|
|
404
|
+
continue;
|
|
405
|
+
}
|
|
406
|
+
try {
|
|
407
|
+
const o = JSON.parse(line);
|
|
408
|
+
const ts = o['timestamp'] ? Date.parse(String(o['timestamp'])) : undefined;
|
|
409
|
+
if (o['type'] === 'user') {
|
|
410
|
+
const t = extractClaudeText(o['message']);
|
|
411
|
+
if (t) {
|
|
412
|
+
msgs.push({ role: 'user', text: t, ts });
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
else if (o['type'] === 'assistant') {
|
|
416
|
+
const t = extractClaudeText(o['message']);
|
|
417
|
+
if (t) {
|
|
418
|
+
msgs.push({ role: 'assistant', text: t, ts });
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
else if (o['type'] === 'system' && o['content']) {
|
|
422
|
+
msgs.push({ role: 'system', text: String(o['content']).slice(0, 200), ts });
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
catch { /* skip */ }
|
|
426
|
+
}
|
|
427
|
+
return msgs.slice(-limit);
|
|
428
|
+
}
|
|
180
429
|
function getClaudeSessionCursor(workspacePath) {
|
|
181
430
|
const p = resolveClaudeJsonl(workspacePath);
|
|
182
431
|
if (!p) {
|