@redplanethq/corebrain 2.6.3 → 2.6.5
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/coding/agents.d.ts +8 -0
- package/dist/commands/coding/agents.d.ts.map +1 -0
- package/dist/commands/coding/agents.js +34 -0
- package/dist/commands/coding/agents.js.map +1 -0
- package/dist/commands/coding/close.d.ts.map +1 -1
- package/dist/commands/coding/close.js +13 -25
- package/dist/commands/coding/close.js.map +1 -1
- package/dist/commands/coding/list.d.ts +4 -0
- package/dist/commands/coding/list.d.ts.map +1 -1
- package/dist/commands/coding/list.js +18 -38
- package/dist/commands/coding/list.js.map +1 -1
- package/dist/commands/coding/read.d.ts +1 -0
- package/dist/commands/coding/read.d.ts.map +1 -1
- package/dist/commands/coding/read.js +36 -35
- package/dist/commands/coding/read.js.map +1 -1
- package/dist/commands/coding/resume.d.ts +1 -0
- package/dist/commands/coding/resume.d.ts.map +1 -1
- package/dist/commands/coding/resume.js +37 -31
- package/dist/commands/coding/resume.js.map +1 -1
- package/dist/commands/coding/setup.d.ts.map +1 -1
- package/dist/commands/coding/setup.js +34 -5
- package/dist/commands/coding/setup.js.map +1 -1
- package/dist/commands/coding/start.d.ts.map +1 -1
- package/dist/commands/coding/start.js +7 -32
- package/dist/commands/coding/start.js.map +1 -1
- package/dist/server/gateway-client.d.ts.map +1 -1
- package/dist/server/gateway-client.js +4 -0
- package/dist/server/gateway-client.js.map +1 -1
- package/dist/server/tools/coding-tools.d.ts +0 -22
- package/dist/server/tools/coding-tools.d.ts.map +1 -1
- package/dist/server/tools/coding-tools.js +255 -230
- package/dist/server/tools/coding-tools.js.map +1 -1
- package/dist/tui/chat.d.ts.map +1 -1
- package/dist/tui/chat.js +41 -0
- package/dist/tui/chat.js.map +1 -1
- package/dist/tui/hooks/use-conversation.d.ts +2 -0
- package/dist/tui/hooks/use-conversation.d.ts.map +1 -1
- package/dist/tui/hooks/use-conversation.js +8 -1
- package/dist/tui/hooks/use-conversation.js.map +1 -1
- package/dist/tui/utils/stream.d.ts +1 -1
- package/dist/tui/utils/stream.d.ts.map +1 -1
- package/dist/tui/utils/stream.js +2 -2
- package/dist/tui/utils/stream.js.map +1 -1
- package/dist/types/config.d.ts +2 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/utils/coding-agents/claude-code.d.ts +8 -6
- package/dist/utils/coding-agents/claude-code.d.ts.map +1 -1
- package/dist/utils/coding-agents/claude-code.js +77 -111
- package/dist/utils/coding-agents/claude-code.js.map +1 -1
- package/dist/utils/coding-agents/codex.d.ts +23 -0
- package/dist/utils/coding-agents/codex.d.ts.map +1 -0
- package/dist/utils/coding-agents/codex.js +243 -0
- package/dist/utils/coding-agents/codex.js.map +1 -0
- package/dist/utils/coding-agents/index.d.ts +12 -10
- package/dist/utils/coding-agents/index.d.ts.map +1 -1
- package/dist/utils/coding-agents/index.js +30 -23
- package/dist/utils/coding-agents/index.js.map +1 -1
- package/dist/utils/coding-agents/types.d.ts +37 -21
- package/dist/utils/coding-agents/types.d.ts.map +1 -1
- package/dist/utils/coding-agents/types.js +98 -1
- package/dist/utils/coding-agents/types.js.map +1 -1
- package/dist/utils/coding-runner.d.ts +1 -28
- package/dist/utils/coding-runner.d.ts.map +1 -1
- package/dist/utils/coding-runner.js +10 -85
- package/dist/utils/coding-runner.js.map +1 -1
- package/dist/utils/coding-sessions.d.ts +4 -57
- package/dist/utils/coding-sessions.d.ts.map +1 -1
- package/dist/utils/coding-sessions.js +9 -75
- package/dist/utils/coding-sessions.js.map +1 -1
- package/package.json +2 -2
- package/dist/assets/assets/AppIcon.icns +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/utils/coding-agents/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/utils/coding-agents/claude-code.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { BaseCodingAgentReader, type AgentReadResult, type AgentReadOptions, type ScannedSession, type ScanOptions } from './types.js';
|
|
2
|
+
export declare class CodexReader extends BaseCodingAgentReader {
|
|
3
|
+
readonly agentName = "codex-cli";
|
|
4
|
+
/**
|
|
5
|
+
* For startup polling: check if codex has written anything to the captured stdout log.
|
|
6
|
+
* We use our internal UUID (not codex's UUID) as sessionId during a live session.
|
|
7
|
+
*/
|
|
8
|
+
sessionExists(_dir: string, sessionId: string): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Read session output.
|
|
11
|
+
* - For live sessions (our UUID): read from captured stdout log.
|
|
12
|
+
* - For historical sessions (codex UUID from list/search): find in date dirs.
|
|
13
|
+
*/
|
|
14
|
+
readSessionOutput(_dir: string, sessionId: string, options?: AgentReadOptions): Promise<AgentReadResult>;
|
|
15
|
+
/**
|
|
16
|
+
* Extract title from codex JSONL format.
|
|
17
|
+
* Codex has no `summary` type — find the first user message that isn't the environment_context.
|
|
18
|
+
*/
|
|
19
|
+
protected extractTitle(filePath: string): Promise<string | null>;
|
|
20
|
+
scanSessions(options?: ScanOptions): Promise<ScannedSession[]>;
|
|
21
|
+
}
|
|
22
|
+
export declare const codexReader: CodexReader;
|
|
23
|
+
//# sourceMappingURL=codex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../../src/utils/coding-agents/codex.ts"],"names":[],"mappings":"AAKA,OAAO,EACN,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,WAAW,EAEhB,MAAM,SAAS,CAAC;AA2GjB,qBAAa,WAAY,SAAQ,qBAAqB;IACrD,QAAQ,CAAC,SAAS,eAAe;IAEjC;;;OAGG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAUvD;;;;OAIG;IACG,iBAAiB,CACtB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,gBAAqB,GAC5B,OAAO,CAAC,eAAe,CAAC;IAiC3B;;;OAGG;cACa,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAwChE,YAAY,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;CA4CxE;AAED,eAAO,MAAM,WAAW,aAAoB,CAAC"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { existsSync, statSync, readdirSync, createReadStream } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { createInterface } from 'node:readline';
|
|
5
|
+
import { getSessionLogPath } from '../../utils/coding-runner.js';
|
|
6
|
+
import { BaseCodingAgentReader, } from './types.js';
|
|
7
|
+
// ~/.codex/sessions/YYYY/MM/DD/rollout-<datetime>-<uuid>.jsonl
|
|
8
|
+
const CODEX_SESSIONS_DIR = join(homedir(), '.codex', 'sessions');
|
|
9
|
+
const MAX_FILE_SIZE_BYTES = 5 * 1024 * 1024;
|
|
10
|
+
const DEFAULT_LARGE_FILE_LINES = 100;
|
|
11
|
+
/**
|
|
12
|
+
* Extract the session UUID from a codex rollout filename.
|
|
13
|
+
* rollout-2025-11-03T22-52-20-019a4abd-bd5b-7ab0-aee6-f2fbdcab989c.jsonl
|
|
14
|
+
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
15
|
+
*/
|
|
16
|
+
function extractSessionId(filename) {
|
|
17
|
+
const match = filename.match(/^rollout-.*?T\d{2}-\d{2}-\d{2}-(.+)\.jsonl$/);
|
|
18
|
+
return match?.[1] ?? null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Read the first JSONL line from a file and parse it.
|
|
22
|
+
*/
|
|
23
|
+
async function readFirstLine(filePath) {
|
|
24
|
+
return new Promise((resolve) => {
|
|
25
|
+
const rl = createInterface({ input: createReadStream(filePath), crlfDelay: Infinity });
|
|
26
|
+
let done = false;
|
|
27
|
+
rl.on('line', (line) => {
|
|
28
|
+
if (done || !line.trim())
|
|
29
|
+
return;
|
|
30
|
+
done = true;
|
|
31
|
+
rl.close();
|
|
32
|
+
try {
|
|
33
|
+
resolve(JSON.parse(line));
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
resolve(null);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
rl.on('close', () => { if (!done)
|
|
40
|
+
resolve(null); });
|
|
41
|
+
rl.on('error', () => resolve(null));
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Walk ~/.codex/sessions/YYYY/MM/DD/ and yield rollout JSONL files (newest first).
|
|
46
|
+
*/
|
|
47
|
+
function* walkCodexSessions(since) {
|
|
48
|
+
if (!existsSync(CODEX_SESSIONS_DIR))
|
|
49
|
+
return;
|
|
50
|
+
let years;
|
|
51
|
+
try {
|
|
52
|
+
years = readdirSync(CODEX_SESSIONS_DIR).filter((y) => /^\d{4}$/.test(y));
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
for (const year of years.sort().reverse()) {
|
|
58
|
+
const yearPath = join(CODEX_SESSIONS_DIR, year);
|
|
59
|
+
let months;
|
|
60
|
+
try {
|
|
61
|
+
months = readdirSync(yearPath).filter((m) => /^\d{2}$/.test(m));
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
for (const month of months.sort().reverse()) {
|
|
67
|
+
const monthPath = join(yearPath, month);
|
|
68
|
+
let days;
|
|
69
|
+
try {
|
|
70
|
+
days = readdirSync(monthPath).filter((d) => /^\d{2}$/.test(d));
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
for (const day of days.sort().reverse()) {
|
|
76
|
+
if (since) {
|
|
77
|
+
const dateMs = new Date(`${year}-${month}-${day}`).getTime();
|
|
78
|
+
if (dateMs < since - 86_400_000)
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const dayPath = join(monthPath, day);
|
|
82
|
+
let files;
|
|
83
|
+
try {
|
|
84
|
+
files = readdirSync(dayPath)
|
|
85
|
+
.filter((f) => f.startsWith('rollout-') && f.endsWith('.jsonl'));
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
for (const file of files.sort().reverse()) {
|
|
91
|
+
const sessionId = extractSessionId(file);
|
|
92
|
+
if (!sessionId)
|
|
93
|
+
continue;
|
|
94
|
+
yield { filePath: join(dayPath, file), sessionId };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Find the JSONL file path for a codex session UUID.
|
|
102
|
+
*/
|
|
103
|
+
function findSessionPath(sessionId) {
|
|
104
|
+
for (const { filePath, sessionId: id } of walkCodexSessions()) {
|
|
105
|
+
if (id === sessionId)
|
|
106
|
+
return filePath;
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
export class CodexReader extends BaseCodingAgentReader {
|
|
111
|
+
agentName = 'codex-cli';
|
|
112
|
+
/**
|
|
113
|
+
* For startup polling: check if codex has written anything to the captured stdout log.
|
|
114
|
+
* We use our internal UUID (not codex's UUID) as sessionId during a live session.
|
|
115
|
+
*/
|
|
116
|
+
sessionExists(_dir, sessionId) {
|
|
117
|
+
const logPath = getSessionLogPath(sessionId, 'stdout');
|
|
118
|
+
if (!existsSync(logPath))
|
|
119
|
+
return false;
|
|
120
|
+
try {
|
|
121
|
+
return statSync(logPath).size > 0;
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Read session output.
|
|
129
|
+
* - For live sessions (our UUID): read from captured stdout log.
|
|
130
|
+
* - For historical sessions (codex UUID from list/search): find in date dirs.
|
|
131
|
+
*/
|
|
132
|
+
async readSessionOutput(_dir, sessionId, options = {}) {
|
|
133
|
+
// Check stdout log first (live/recent session tracked by our UUID)
|
|
134
|
+
const logPath = getSessionLogPath(sessionId, 'stdout');
|
|
135
|
+
const sessionPath = existsSync(logPath) && statSync(logPath).size > 0
|
|
136
|
+
? logPath
|
|
137
|
+
: findSessionPath(sessionId);
|
|
138
|
+
if (!sessionPath) {
|
|
139
|
+
return { entries: [], totalLines: 0, returnedLines: 0, fileExists: false, fileSizeBytes: 0, fileSizeHuman: '0 B' };
|
|
140
|
+
}
|
|
141
|
+
let fileSizeBytes = 0;
|
|
142
|
+
try {
|
|
143
|
+
fileSizeBytes = statSync(sessionPath).size;
|
|
144
|
+
}
|
|
145
|
+
catch { /* ignore */ }
|
|
146
|
+
const fileSizeHuman = this.formatBytes(fileSizeBytes);
|
|
147
|
+
let readOptions = { ...options };
|
|
148
|
+
if (fileSizeBytes > MAX_FILE_SIZE_BYTES && !options.lines) {
|
|
149
|
+
readOptions = { ...options, lines: DEFAULT_LARGE_FILE_LINES, tail: true };
|
|
150
|
+
}
|
|
151
|
+
try {
|
|
152
|
+
const { entries, totalLines } = await this.readJsonlLines(sessionPath, readOptions);
|
|
153
|
+
return { entries, totalLines, returnedLines: entries.length, fileExists: true, fileSizeBytes, fileSizeHuman };
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
return {
|
|
157
|
+
entries: [], totalLines: 0, returnedLines: 0, fileExists: true, fileSizeBytes, fileSizeHuman,
|
|
158
|
+
error: err instanceof Error ? err.message : 'Failed to read session file',
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Extract title from codex JSONL format.
|
|
164
|
+
* Codex has no `summary` type — find the first user message that isn't the environment_context.
|
|
165
|
+
*/
|
|
166
|
+
async extractTitle(filePath) {
|
|
167
|
+
return new Promise((resolve) => {
|
|
168
|
+
let firstUserMessage = null;
|
|
169
|
+
let resolved = false;
|
|
170
|
+
const rl = createInterface({ input: createReadStream(filePath), crlfDelay: Infinity });
|
|
171
|
+
rl.on('line', (line) => {
|
|
172
|
+
if (resolved || !line.trim())
|
|
173
|
+
return;
|
|
174
|
+
try {
|
|
175
|
+
const entry = JSON.parse(line);
|
|
176
|
+
if (entry.type === 'response_item' &&
|
|
177
|
+
entry.payload?.type === 'message' &&
|
|
178
|
+
entry.payload?.role === 'user') {
|
|
179
|
+
const content = entry.payload?.content;
|
|
180
|
+
if (Array.isArray(content)) {
|
|
181
|
+
for (const part of content) {
|
|
182
|
+
if (part.type === 'input_text' && typeof part.text === 'string') {
|
|
183
|
+
const text = part.text.trim();
|
|
184
|
+
// Skip environment context injected by codex
|
|
185
|
+
if (!text.startsWith('<environment_context>')) {
|
|
186
|
+
firstUserMessage = text.slice(0, 120);
|
|
187
|
+
resolved = true;
|
|
188
|
+
rl.close();
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
catch { /* skip */ }
|
|
197
|
+
});
|
|
198
|
+
rl.on('close', () => resolve(firstUserMessage));
|
|
199
|
+
rl.on('error', () => resolve(null));
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
async scanSessions(options = {}) {
|
|
203
|
+
const results = [];
|
|
204
|
+
for (const { filePath, sessionId } of walkCodexSessions(options.since)) {
|
|
205
|
+
let stats;
|
|
206
|
+
try {
|
|
207
|
+
stats = statSync(filePath);
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
if (options.since && stats.mtimeMs < options.since)
|
|
213
|
+
continue;
|
|
214
|
+
results.push({
|
|
215
|
+
sessionId,
|
|
216
|
+
agent: this.agentName,
|
|
217
|
+
dir: '', // populated below from session_meta
|
|
218
|
+
title: null,
|
|
219
|
+
filePath,
|
|
220
|
+
fileSizeBytes: stats.size,
|
|
221
|
+
createdAt: stats.birthtimeMs || stats.mtimeMs,
|
|
222
|
+
updatedAt: stats.mtimeMs,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
results.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
226
|
+
// Populate title + dir from session_meta (first line) in parallel
|
|
227
|
+
await Promise.all(results.map(async (s) => {
|
|
228
|
+
const first = await readFirstLine(s.filePath);
|
|
229
|
+
if (first?.type === 'session_meta') {
|
|
230
|
+
const payload = first.payload;
|
|
231
|
+
s.dir = payload?.cwd ?? '';
|
|
232
|
+
}
|
|
233
|
+
s.title = await this.extractTitle(s.filePath);
|
|
234
|
+
}));
|
|
235
|
+
// Apply dir filter after reading cwd from session_meta
|
|
236
|
+
if (options.dir) {
|
|
237
|
+
return results.filter((s) => s.dir === options.dir);
|
|
238
|
+
}
|
|
239
|
+
return results;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
export const codexReader = new CodexReader();
|
|
243
|
+
//# sourceMappingURL=codex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../src/utils/coding-agents/codex.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
export type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export declare function
|
|
1
|
+
import { BaseCodingAgentReader, type AgentReadResult, type AgentReadOptions, type ScannedSession, type ScanOptions, type ScanResult } from './types.js';
|
|
2
|
+
export type { AgentReadResult, AgentReadOptions, ScannedSession, ScanOptions, ScanResult };
|
|
3
|
+
export { BaseCodingAgentReader };
|
|
4
|
+
export declare function getAgentReader(agentName: string): BaseCodingAgentReader | null;
|
|
5
|
+
export declare function readAgentSessionOutput(agentName: string, dir: string, sessionId: string, options?: AgentReadOptions): Promise<AgentReadResult>;
|
|
6
|
+
export declare function agentSessionExists(agentName: string, dir: string, sessionId: string): boolean;
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Scan sessions across all registered agents, merge, sort by recency, and paginate.
|
|
9
9
|
*/
|
|
10
|
-
export declare function
|
|
10
|
+
export declare function scanAllSessions(options?: ScanOptions): Promise<ScanResult>;
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Search sessions by title across all agents.
|
|
13
13
|
*/
|
|
14
|
-
export declare function
|
|
14
|
+
export declare function searchSessions(query: string, options?: Omit<ScanOptions, 'offset'> & {
|
|
15
|
+
limit?: number;
|
|
16
|
+
}): Promise<ScannedSession[]>;
|
|
15
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/coding-agents/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/coding-agents/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,qBAAqB,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAC,MAAM,SAAS,CAAC;AAInJ,YAAY,EAAC,eAAe,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAC,CAAC;AACzF,OAAO,EAAC,qBAAqB,EAAC,CAAC;AAO/B,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAE9E;AAED,wBAAsB,sBAAsB,CAC3C,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CAS1B;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAE7F;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAepF;AAED;;GAEG;AACH,wBAAsB,cAAc,CACnC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,GAAG;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAM,GAC1D,OAAO,CAAC,cAAc,EAAE,CAAC,CAK3B"}
|
|
@@ -1,42 +1,49 @@
|
|
|
1
|
+
import { BaseCodingAgentReader } from './types.js';
|
|
1
2
|
import { claudeCodeReader } from './claude-code.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*/
|
|
3
|
+
import { codexReader } from './codex.js';
|
|
4
|
+
export { BaseCodingAgentReader };
|
|
5
5
|
const agentReaders = {
|
|
6
6
|
'claude-code': claudeCodeReader,
|
|
7
|
+
'codex-cli': codexReader,
|
|
7
8
|
};
|
|
8
|
-
/**
|
|
9
|
-
* Get the reader for a specific agent
|
|
10
|
-
*/
|
|
11
9
|
export function getAgentReader(agentName) {
|
|
12
10
|
return agentReaders[agentName] || null;
|
|
13
11
|
}
|
|
14
|
-
/**
|
|
15
|
-
* Read session output using the appropriate agent reader
|
|
16
|
-
*/
|
|
17
12
|
export async function readAgentSessionOutput(agentName, dir, sessionId, options) {
|
|
18
13
|
const reader = getAgentReader(agentName);
|
|
19
14
|
if (!reader) {
|
|
20
15
|
return {
|
|
21
|
-
entries: [],
|
|
22
|
-
|
|
23
|
-
returnedLines: 0,
|
|
24
|
-
fileExists: false,
|
|
25
|
-
fileSizeBytes: 0,
|
|
26
|
-
fileSizeHuman: '0 B',
|
|
27
|
-
error: `No reader available for agent: ${agentName}`,
|
|
16
|
+
entries: [], totalLines: 0, returnedLines: 0, fileExists: false, fileSizeBytes: 0,
|
|
17
|
+
fileSizeHuman: '0 B', error: `No reader for agent: ${agentName}`,
|
|
28
18
|
};
|
|
29
19
|
}
|
|
30
20
|
return reader.readSessionOutput(dir, sessionId, options);
|
|
31
21
|
}
|
|
22
|
+
export function agentSessionExists(agentName, dir, sessionId) {
|
|
23
|
+
return getAgentReader(agentName)?.sessionExists(dir, sessionId) ?? false;
|
|
24
|
+
}
|
|
32
25
|
/**
|
|
33
|
-
*
|
|
26
|
+
* Scan sessions across all registered agents, merge, sort by recency, and paginate.
|
|
34
27
|
*/
|
|
35
|
-
export function
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
28
|
+
export async function scanAllSessions(options = {}) {
|
|
29
|
+
const readers = options.agent
|
|
30
|
+
? Object.values(agentReaders).filter((r) => r.agentName === options.agent)
|
|
31
|
+
: Object.values(agentReaders);
|
|
32
|
+
const allResults = await Promise.all(readers.map((r) => r.scanSessions(options)));
|
|
33
|
+
const merged = allResults.flat().sort((a, b) => b.updatedAt - a.updatedAt);
|
|
34
|
+
const total = merged.length;
|
|
35
|
+
const offset = options.offset ?? 0;
|
|
36
|
+
const limit = options.limit ?? 20;
|
|
37
|
+
const sessions = merged.slice(offset, offset + limit);
|
|
38
|
+
return { sessions, total, hasMore: offset + limit < total };
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Search sessions by title across all agents.
|
|
42
|
+
*/
|
|
43
|
+
export async function searchSessions(query, options = {}) {
|
|
44
|
+
const { sessions: all } = await scanAllSessions({ ...options, limit: undefined });
|
|
45
|
+
const q = query.toLowerCase();
|
|
46
|
+
const matched = all.filter((s) => s.title?.toLowerCase().includes(q));
|
|
47
|
+
return options.limit ? matched.slice(0, options.limit) : matched;
|
|
41
48
|
}
|
|
42
49
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/coding-agents/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/coding-agents/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A single JSONL entry from a session
|
|
3
|
-
*/
|
|
4
1
|
export interface SessionEntry {
|
|
5
2
|
type: string;
|
|
6
3
|
message?: {
|
|
@@ -13,9 +10,6 @@ export interface SessionEntry {
|
|
|
13
10
|
timestamp?: string;
|
|
14
11
|
[key: string]: unknown;
|
|
15
12
|
}
|
|
16
|
-
/**
|
|
17
|
-
* Result from reading agent session output
|
|
18
|
-
*/
|
|
19
13
|
export interface AgentReadResult {
|
|
20
14
|
entries: SessionEntry[];
|
|
21
15
|
totalLines: number;
|
|
@@ -25,25 +19,47 @@ export interface AgentReadResult {
|
|
|
25
19
|
fileSizeHuman: string;
|
|
26
20
|
error?: string;
|
|
27
21
|
}
|
|
28
|
-
/**
|
|
29
|
-
* Options for reading session output
|
|
30
|
-
*/
|
|
31
22
|
export interface AgentReadOptions {
|
|
32
23
|
lines?: number;
|
|
33
24
|
offset?: number;
|
|
34
25
|
tail?: boolean;
|
|
35
26
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
27
|
+
export interface ScannedSession {
|
|
28
|
+
sessionId: string;
|
|
29
|
+
agent: string;
|
|
30
|
+
dir: string;
|
|
31
|
+
title: string | null;
|
|
32
|
+
filePath: string;
|
|
33
|
+
fileSizeBytes: number;
|
|
34
|
+
createdAt: number;
|
|
35
|
+
updatedAt: number;
|
|
36
|
+
}
|
|
37
|
+
export interface ScanOptions {
|
|
38
|
+
agent?: string;
|
|
39
|
+
dir?: string;
|
|
40
|
+
since?: number;
|
|
41
|
+
limit?: number;
|
|
42
|
+
offset?: number;
|
|
43
|
+
}
|
|
44
|
+
export interface ScanResult {
|
|
45
|
+
sessions: ScannedSession[];
|
|
46
|
+
total: number;
|
|
47
|
+
hasMore: boolean;
|
|
48
|
+
}
|
|
49
|
+
export declare abstract class BaseCodingAgentReader {
|
|
50
|
+
abstract readonly agentName: string;
|
|
51
|
+
abstract sessionExists(dir: string, sessionId: string): boolean;
|
|
52
|
+
abstract readSessionOutput(dir: string, sessionId: string, options?: AgentReadOptions): Promise<AgentReadResult>;
|
|
53
|
+
abstract scanSessions(options?: ScanOptions): Promise<ScannedSession[]>;
|
|
54
|
+
protected formatBytes(bytes: number): string;
|
|
55
|
+
protected readJsonlLines(filePath: string, options?: {
|
|
56
|
+
lines?: number;
|
|
57
|
+
offset?: number;
|
|
58
|
+
tail?: boolean;
|
|
59
|
+
}): Promise<{
|
|
60
|
+
entries: SessionEntry[];
|
|
61
|
+
totalLines: number;
|
|
62
|
+
}>;
|
|
63
|
+
protected extractTitle(filePath: string): Promise<string | null>;
|
|
48
64
|
}
|
|
49
65
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/coding-agents/types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/coding-agents/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE;QACT,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAC,CAAC,CAAC;KACvD,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IAC1B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,8BAAsB,qBAAqB;IAC1C,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAEpC,QAAQ,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAE/D,QAAQ,CAAC,iBAAiB,CACzB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC;IAE3B,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAIvE,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;cAQ5B,cAAc,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAM,GAC7D,OAAO,CAAC;QAAC,OAAO,EAAE,YAAY,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAC,CAAC;cA0CzC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAmDtE"}
|
|
@@ -1,2 +1,99 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export class BaseCodingAgentReader {
|
|
2
|
+
// ── Shared utilities ──────────────────────────────────────────────────────
|
|
3
|
+
formatBytes(bytes) {
|
|
4
|
+
if (bytes === 0)
|
|
5
|
+
return '0 B';
|
|
6
|
+
const k = 1024;
|
|
7
|
+
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
8
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
9
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
|
|
10
|
+
}
|
|
11
|
+
async readJsonlLines(filePath, options = {}) {
|
|
12
|
+
const { createReadStream } = await import('node:fs');
|
|
13
|
+
const { createInterface } = await import('node:readline');
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
const entries = [];
|
|
16
|
+
const rl = createInterface({
|
|
17
|
+
input: createReadStream(filePath),
|
|
18
|
+
crlfDelay: Infinity,
|
|
19
|
+
});
|
|
20
|
+
rl.on('line', (line) => {
|
|
21
|
+
if (!line.trim())
|
|
22
|
+
return;
|
|
23
|
+
try {
|
|
24
|
+
entries.push(JSON.parse(line));
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// Skip malformed
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
rl.on('close', () => {
|
|
31
|
+
const totalLines = entries.length;
|
|
32
|
+
let result;
|
|
33
|
+
if (options.tail && options.lines) {
|
|
34
|
+
result = entries.slice(Math.max(0, totalLines - options.lines));
|
|
35
|
+
}
|
|
36
|
+
else if (options.lines || options.offset) {
|
|
37
|
+
const offset = options.offset || 0;
|
|
38
|
+
const limit = options.lines || totalLines;
|
|
39
|
+
result = entries.slice(offset, offset + limit);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
result = entries;
|
|
43
|
+
}
|
|
44
|
+
resolve({ entries: result, totalLines });
|
|
45
|
+
});
|
|
46
|
+
rl.on('error', reject);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
async extractTitle(filePath) {
|
|
50
|
+
const { createReadStream } = await import('node:fs');
|
|
51
|
+
const { createInterface } = await import('node:readline');
|
|
52
|
+
return new Promise((resolve) => {
|
|
53
|
+
let title = null;
|
|
54
|
+
let firstUserMessage = null;
|
|
55
|
+
let resolved = false;
|
|
56
|
+
const rl = createInterface({
|
|
57
|
+
input: createReadStream(filePath),
|
|
58
|
+
crlfDelay: Infinity,
|
|
59
|
+
});
|
|
60
|
+
rl.on('line', (line) => {
|
|
61
|
+
if (resolved || !line.trim())
|
|
62
|
+
return;
|
|
63
|
+
try {
|
|
64
|
+
const entry = JSON.parse(line);
|
|
65
|
+
if (entry.type === 'summary' && entry.summary) {
|
|
66
|
+
title = entry.summary;
|
|
67
|
+
resolved = true;
|
|
68
|
+
rl.close();
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (!firstUserMessage && entry.message?.role === 'user') {
|
|
72
|
+
const content = entry.message.content;
|
|
73
|
+
let raw = '';
|
|
74
|
+
if (typeof content === 'string') {
|
|
75
|
+
raw = content;
|
|
76
|
+
}
|
|
77
|
+
else if (Array.isArray(content)) {
|
|
78
|
+
const part = content.find((p) => p.type === 'text' && p.text);
|
|
79
|
+
raw = part?.text ?? '';
|
|
80
|
+
}
|
|
81
|
+
// Strip system-injected XML tags e.g. <local-command-caveat>...</local-command-caveat>
|
|
82
|
+
const clean = raw
|
|
83
|
+
.replace(/<[^>]+>[\s\S]*?<\/[^>]+>/g, '')
|
|
84
|
+
.replace(/<[^>]+>/g, '')
|
|
85
|
+
.trim();
|
|
86
|
+
if (clean)
|
|
87
|
+
firstUserMessage = clean.slice(0, 120);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// Skip malformed
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
rl.on('close', () => resolve(title ?? firstUserMessage ?? null));
|
|
95
|
+
rl.on('error', () => resolve(null));
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
2
99
|
//# sourceMappingURL=types.js.map
|