@redplanethq/corebrain 2.6.2 → 2.6.4
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/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 +237 -233
- package/dist/server/tools/coding-tools.js.map +1 -1
- package/dist/tui/chat.d.ts.map +1 -1
- package/dist/tui/chat.js +57 -1
- package/dist/tui/chat.js.map +1 -1
- package/dist/tui/components/tool-call-item.d.ts.map +1 -1
- package/dist/tui/components/tool-call-item.js +16 -8
- package/dist/tui/components/tool-call-item.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
|
@@ -1,143 +1,109 @@
|
|
|
1
|
-
import { existsSync, statSync,
|
|
2
|
-
import { join } from 'node:path';
|
|
1
|
+
import { existsSync, statSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { join, basename } from 'node:path';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
|
-
import {
|
|
5
|
-
// Claude Code projects directory
|
|
4
|
+
import { BaseCodingAgentReader } from './types.js';
|
|
6
5
|
const CLAUDE_PROJECTS_DIR = join(homedir(), '.claude', 'projects');
|
|
7
|
-
// Max file size before limiting lines (5MB)
|
|
8
6
|
const MAX_FILE_SIZE_BYTES = 5 * 1024 * 1024;
|
|
9
|
-
// Default lines to read when file is too large
|
|
10
7
|
const DEFAULT_LARGE_FILE_LINES = 100;
|
|
11
8
|
/**
|
|
12
|
-
*
|
|
13
|
-
* /Users/harshithmullapudi/Documents/core -> -Users-harshithmullapudi-Documents-core
|
|
9
|
+
* /Users/foo/bar → -Users-foo-bar
|
|
14
10
|
*/
|
|
15
11
|
function dirToProjectFolder(dir) {
|
|
16
12
|
return dir.replace(/\//g, '-');
|
|
17
13
|
}
|
|
18
14
|
/**
|
|
19
|
-
*
|
|
15
|
+
* -Users-foo-bar → /Users/foo/bar
|
|
20
16
|
*/
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
return join(CLAUDE_PROJECTS_DIR, projectFolder, `${sessionId}.jsonl`);
|
|
17
|
+
function projectFolderToDir(folder) {
|
|
18
|
+
return folder.replace(/^-/, '/').replace(/-/g, '/');
|
|
24
19
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
*/
|
|
28
|
-
function formatBytes(bytes) {
|
|
29
|
-
if (bytes === 0)
|
|
30
|
-
return '0 B';
|
|
31
|
-
const k = 1024;
|
|
32
|
-
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
33
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
34
|
-
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Read JSONL file line by line (streaming)
|
|
38
|
-
*/
|
|
39
|
-
async function readJsonlLines(filePath, options = {}) {
|
|
40
|
-
return new Promise((resolve, reject) => {
|
|
41
|
-
const entries = [];
|
|
42
|
-
let lineCount = 0;
|
|
43
|
-
const rl = createInterface({
|
|
44
|
-
input: createReadStream(filePath),
|
|
45
|
-
crlfDelay: Infinity,
|
|
46
|
-
});
|
|
47
|
-
rl.on('line', (line) => {
|
|
48
|
-
if (!line.trim())
|
|
49
|
-
return;
|
|
50
|
-
lineCount++;
|
|
51
|
-
try {
|
|
52
|
-
const entry = JSON.parse(line);
|
|
53
|
-
entries.push(entry);
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
// Skip malformed lines
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
rl.on('close', () => {
|
|
60
|
-
let resultEntries;
|
|
61
|
-
const totalLines = entries.length;
|
|
62
|
-
if (options.tail && options.lines) {
|
|
63
|
-
const start = Math.max(0, totalLines - options.lines);
|
|
64
|
-
resultEntries = entries.slice(start);
|
|
65
|
-
}
|
|
66
|
-
else if (options.lines || options.offset) {
|
|
67
|
-
const offset = options.offset || 0;
|
|
68
|
-
const limit = options.lines || totalLines;
|
|
69
|
-
resultEntries = entries.slice(offset, offset + limit);
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
resultEntries = entries;
|
|
73
|
-
}
|
|
74
|
-
resolve({ entries: resultEntries, totalLines });
|
|
75
|
-
});
|
|
76
|
-
rl.on('error', reject);
|
|
77
|
-
});
|
|
20
|
+
function getSessionPath(dir, sessionId) {
|
|
21
|
+
return join(CLAUDE_PROJECTS_DIR, dirToProjectFolder(dir), `${sessionId}.jsonl`);
|
|
78
22
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
* Reads from ~/.claude/projects/<path>/<session-id>.jsonl
|
|
82
|
-
*/
|
|
83
|
-
export const claudeCodeReader = {
|
|
23
|
+
export class ClaudeCodeReader extends BaseCodingAgentReader {
|
|
24
|
+
agentName = 'claude-code';
|
|
84
25
|
sessionExists(dir, sessionId) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
},
|
|
26
|
+
return existsSync(getSessionPath(dir, sessionId));
|
|
27
|
+
}
|
|
88
28
|
async readSessionOutput(dir, sessionId, options = {}) {
|
|
89
29
|
const sessionPath = getSessionPath(dir, sessionId);
|
|
90
30
|
if (!existsSync(sessionPath)) {
|
|
91
|
-
return {
|
|
92
|
-
entries: [],
|
|
93
|
-
totalLines: 0,
|
|
94
|
-
returnedLines: 0,
|
|
95
|
-
fileExists: false,
|
|
96
|
-
fileSizeBytes: 0,
|
|
97
|
-
fileSizeHuman: '0 B',
|
|
98
|
-
};
|
|
31
|
+
return { entries: [], totalLines: 0, returnedLines: 0, fileExists: false, fileSizeBytes: 0, fileSizeHuman: '0 B' };
|
|
99
32
|
}
|
|
100
|
-
// Get file size
|
|
101
33
|
let fileSizeBytes = 0;
|
|
102
34
|
try {
|
|
103
|
-
|
|
104
|
-
fileSizeBytes = stats.size;
|
|
105
|
-
}
|
|
106
|
-
catch {
|
|
107
|
-
// Ignore stat errors
|
|
35
|
+
fileSizeBytes = statSync(sessionPath).size;
|
|
108
36
|
}
|
|
109
|
-
|
|
110
|
-
|
|
37
|
+
catch { /* ignore */ }
|
|
38
|
+
const fileSizeHuman = this.formatBytes(fileSizeBytes);
|
|
111
39
|
let readOptions = { ...options };
|
|
112
40
|
if (fileSizeBytes > MAX_FILE_SIZE_BYTES && !options.lines) {
|
|
113
|
-
readOptions = {
|
|
114
|
-
...options,
|
|
115
|
-
lines: DEFAULT_LARGE_FILE_LINES,
|
|
116
|
-
tail: true, // Get most recent entries
|
|
117
|
-
};
|
|
41
|
+
readOptions = { ...options, lines: DEFAULT_LARGE_FILE_LINES, tail: true };
|
|
118
42
|
}
|
|
119
43
|
try {
|
|
120
|
-
const { entries, totalLines } = await readJsonlLines(sessionPath, readOptions);
|
|
121
|
-
return {
|
|
122
|
-
entries,
|
|
123
|
-
totalLines,
|
|
124
|
-
returnedLines: entries.length,
|
|
125
|
-
fileExists: true,
|
|
126
|
-
fileSizeBytes,
|
|
127
|
-
fileSizeHuman,
|
|
128
|
-
};
|
|
44
|
+
const { entries, totalLines } = await this.readJsonlLines(sessionPath, readOptions);
|
|
45
|
+
return { entries, totalLines, returnedLines: entries.length, fileExists: true, fileSizeBytes, fileSizeHuman };
|
|
129
46
|
}
|
|
130
47
|
catch (err) {
|
|
131
48
|
return {
|
|
132
|
-
entries: [],
|
|
133
|
-
totalLines: 0,
|
|
134
|
-
returnedLines: 0,
|
|
135
|
-
fileExists: true,
|
|
136
|
-
fileSizeBytes,
|
|
137
|
-
fileSizeHuman,
|
|
49
|
+
entries: [], totalLines: 0, returnedLines: 0, fileExists: true, fileSizeBytes, fileSizeHuman,
|
|
138
50
|
error: err instanceof Error ? err.message : 'Failed to read session file',
|
|
139
51
|
};
|
|
140
52
|
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
53
|
+
}
|
|
54
|
+
async scanSessions(options = {}) {
|
|
55
|
+
if (!existsSync(CLAUDE_PROJECTS_DIR))
|
|
56
|
+
return [];
|
|
57
|
+
let projectFolders;
|
|
58
|
+
try {
|
|
59
|
+
projectFolders = readdirSync(CLAUDE_PROJECTS_DIR);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
64
|
+
const results = [];
|
|
65
|
+
for (const folder of projectFolders) {
|
|
66
|
+
const dir = projectFolderToDir(folder);
|
|
67
|
+
if (options.dir && dir !== options.dir)
|
|
68
|
+
continue;
|
|
69
|
+
const projectPath = join(CLAUDE_PROJECTS_DIR, folder);
|
|
70
|
+
let files;
|
|
71
|
+
try {
|
|
72
|
+
files = readdirSync(projectPath).filter((f) => f.endsWith('.jsonl'));
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
for (const file of files) {
|
|
78
|
+
const filePath = join(projectPath, file);
|
|
79
|
+
let stats;
|
|
80
|
+
try {
|
|
81
|
+
stats = statSync(filePath);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (options.since && stats.mtimeMs < options.since)
|
|
87
|
+
continue;
|
|
88
|
+
results.push({
|
|
89
|
+
sessionId: basename(file, '.jsonl'),
|
|
90
|
+
agent: this.agentName,
|
|
91
|
+
dir,
|
|
92
|
+
title: null,
|
|
93
|
+
filePath,
|
|
94
|
+
fileSizeBytes: stats.size,
|
|
95
|
+
createdAt: stats.birthtimeMs || stats.mtimeMs,
|
|
96
|
+
updatedAt: stats.mtimeMs,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
results.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
101
|
+
// Populate titles in parallel (before slicing — titles are cheap to read)
|
|
102
|
+
await Promise.all(results.map(async (s) => {
|
|
103
|
+
s.title = await this.extractTitle(s.filePath);
|
|
104
|
+
}));
|
|
105
|
+
return results;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
export const claudeCodeReader = new ClaudeCodeReader();
|
|
143
109
|
//# sourceMappingURL=claude-code.js.map
|
|
@@ -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
|