@agent-relay/sdk 3.2.8 → 3.2.10

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.
Files changed (70) hide show
  1. package/bin/agent-relay-broker-darwin-arm64 +0 -0
  2. package/bin/agent-relay-broker-darwin-x64 +0 -0
  3. package/bin/agent-relay-broker-linux-arm64 +0 -0
  4. package/bin/agent-relay-broker-linux-x64 +0 -0
  5. package/dist/workflows/__tests__/cli-session-collector.test.d.ts +2 -0
  6. package/dist/workflows/__tests__/cli-session-collector.test.d.ts.map +1 -0
  7. package/dist/workflows/__tests__/cli-session-collector.test.js +54 -0
  8. package/dist/workflows/__tests__/cli-session-collector.test.js.map +1 -0
  9. package/dist/workflows/__tests__/collectors/claude.test.d.ts +2 -0
  10. package/dist/workflows/__tests__/collectors/claude.test.d.ts.map +1 -0
  11. package/dist/workflows/__tests__/collectors/claude.test.js +85 -0
  12. package/dist/workflows/__tests__/collectors/claude.test.js.map +1 -0
  13. package/dist/workflows/__tests__/collectors/codex.test.d.ts +2 -0
  14. package/dist/workflows/__tests__/collectors/codex.test.d.ts.map +1 -0
  15. package/dist/workflows/__tests__/collectors/codex.test.js +67 -0
  16. package/dist/workflows/__tests__/collectors/codex.test.js.map +1 -0
  17. package/dist/workflows/__tests__/collectors/opencode.test.d.ts +2 -0
  18. package/dist/workflows/__tests__/collectors/opencode.test.d.ts.map +1 -0
  19. package/dist/workflows/__tests__/collectors/opencode.test.js +119 -0
  20. package/dist/workflows/__tests__/collectors/opencode.test.js.map +1 -0
  21. package/dist/workflows/__tests__/run-summary-table.test.d.ts +2 -0
  22. package/dist/workflows/__tests__/run-summary-table.test.d.ts.map +1 -0
  23. package/dist/workflows/__tests__/run-summary-table.test.js +130 -0
  24. package/dist/workflows/__tests__/run-summary-table.test.js.map +1 -0
  25. package/dist/workflows/__tests__/step-cwd.test.d.ts +2 -0
  26. package/dist/workflows/__tests__/step-cwd.test.d.ts.map +1 -0
  27. package/dist/workflows/__tests__/step-cwd.test.js +42 -0
  28. package/dist/workflows/__tests__/step-cwd.test.js.map +1 -0
  29. package/dist/workflows/builder.d.ts +2 -0
  30. package/dist/workflows/builder.d.ts.map +1 -1
  31. package/dist/workflows/builder.js +4 -0
  32. package/dist/workflows/builder.js.map +1 -1
  33. package/dist/workflows/cli-session-collector.d.ts +39 -0
  34. package/dist/workflows/cli-session-collector.d.ts.map +1 -0
  35. package/dist/workflows/cli-session-collector.js +23 -0
  36. package/dist/workflows/cli-session-collector.js.map +1 -0
  37. package/dist/workflows/cli.js +228 -48
  38. package/dist/workflows/cli.js.map +1 -1
  39. package/dist/workflows/collectors/claude.d.ts +6 -0
  40. package/dist/workflows/collectors/claude.d.ts.map +1 -0
  41. package/dist/workflows/collectors/claude.js +330 -0
  42. package/dist/workflows/collectors/claude.js.map +1 -0
  43. package/dist/workflows/collectors/codex.d.ts +18 -0
  44. package/dist/workflows/collectors/codex.d.ts.map +1 -0
  45. package/dist/workflows/collectors/codex.js +265 -0
  46. package/dist/workflows/collectors/codex.js.map +1 -0
  47. package/dist/workflows/collectors/opencode.d.ts +6 -0
  48. package/dist/workflows/collectors/opencode.d.ts.map +1 -0
  49. package/dist/workflows/collectors/opencode.js +178 -0
  50. package/dist/workflows/collectors/opencode.js.map +1 -0
  51. package/dist/workflows/index.d.ts +3 -0
  52. package/dist/workflows/index.d.ts.map +1 -1
  53. package/dist/workflows/index.js +3 -0
  54. package/dist/workflows/index.js.map +1 -1
  55. package/dist/workflows/listr-renderer.d.ts +26 -0
  56. package/dist/workflows/listr-renderer.d.ts.map +1 -0
  57. package/dist/workflows/listr-renderer.js +232 -0
  58. package/dist/workflows/listr-renderer.js.map +1 -0
  59. package/dist/workflows/run-summary-table.d.ts +4 -0
  60. package/dist/workflows/run-summary-table.d.ts.map +1 -0
  61. package/dist/workflows/run-summary-table.js +98 -0
  62. package/dist/workflows/run-summary-table.js.map +1 -0
  63. package/dist/workflows/runner.d.ts +11 -0
  64. package/dist/workflows/runner.d.ts.map +1 -1
  65. package/dist/workflows/runner.js +91 -26
  66. package/dist/workflows/runner.js.map +1 -1
  67. package/dist/workflows/types.d.ts +2 -0
  68. package/dist/workflows/types.d.ts.map +1 -1
  69. package/dist/workflows/types.js.map +1 -1
  70. package/package.json +5 -3
@@ -0,0 +1,330 @@
1
+ import { createReadStream, existsSync, statSync } from 'node:fs';
2
+ import { access } from 'node:fs/promises';
3
+ import { homedir } from 'node:os';
4
+ import path from 'node:path';
5
+ import { createInterface } from 'node:readline';
6
+ const CLAUDE_HOME = path.join(homedir(), '.claude');
7
+ const HISTORY_PATH = path.join(CLAUDE_HOME, 'history.jsonl');
8
+ const PROJECTS_PATH = path.join(CLAUDE_HOME, 'projects');
9
+ const HISTORY_LOOKBACK_MS = 5_000;
10
+ export class ClaudeCodeCollector {
11
+ canCollect() {
12
+ return isReadableFile(HISTORY_PATH) && isReadableDirectory(PROJECTS_PATH);
13
+ }
14
+ async collect(query) {
15
+ const historyEntry = await findMatchingHistoryEntry(query);
16
+ if (!historyEntry) {
17
+ return null;
18
+ }
19
+ const sessionPath = path.join(PROJECTS_PATH, encodeProjectPath(historyEntry.project), `${historyEntry.sessionId}.jsonl`);
20
+ if (!(await isReadableFileAsync(sessionPath))) {
21
+ return null;
22
+ }
23
+ return parseSessionLog(sessionPath, query, historyEntry.sessionId);
24
+ }
25
+ }
26
+ async function findMatchingHistoryEntry(query) {
27
+ const history = createInterface({
28
+ input: createReadStream(HISTORY_PATH, { encoding: 'utf8' }),
29
+ crlfDelay: Infinity,
30
+ });
31
+ let match = null;
32
+ try {
33
+ for await (const line of history) {
34
+ const parsed = safeParseRecord(line);
35
+ if (!parsed) {
36
+ continue;
37
+ }
38
+ const entry = toHistoryEntry(parsed);
39
+ if (!entry) {
40
+ continue;
41
+ }
42
+ if (entry.project !== query.cwd) {
43
+ continue;
44
+ }
45
+ if (entry.timestamp < query.startedAt - HISTORY_LOOKBACK_MS || entry.timestamp > query.completedAt) {
46
+ continue;
47
+ }
48
+ match = entry;
49
+ }
50
+ }
51
+ finally {
52
+ history.close();
53
+ }
54
+ return match;
55
+ }
56
+ async function parseSessionLog(sessionPath, query, sessionId) {
57
+ const session = createInterface({
58
+ input: createReadStream(sessionPath, { encoding: 'utf8' }),
59
+ crlfDelay: Infinity,
60
+ });
61
+ const rawLines = [];
62
+ const toolCalls = new Map();
63
+ const errors = [];
64
+ const tokens = { input: 0, output: 0, cacheRead: 0 };
65
+ let turns = 0;
66
+ let summary = null;
67
+ let model = null;
68
+ let provider = null;
69
+ let finalStatus = 'unknown';
70
+ try {
71
+ for await (const line of session) {
72
+ const parsed = safeParseRecord(line);
73
+ if (!parsed) {
74
+ continue;
75
+ }
76
+ rawLines.push(parsed);
77
+ const entryType = getString(parsed.type);
78
+ if (entryType === 'user') {
79
+ turns += 1;
80
+ continue;
81
+ }
82
+ if (entryType === 'assistant') {
83
+ const usage = extractUsage(parsed);
84
+ if (usage) {
85
+ tokens.input += usage.input;
86
+ tokens.output += usage.output;
87
+ tokens.cacheRead += usage.cacheRead;
88
+ }
89
+ model ??= extractModel(parsed);
90
+ provider ??= extractProvider(parsed);
91
+ const assistantText = extractText(parsed);
92
+ if (assistantText) {
93
+ summary = assistantText;
94
+ if (finalStatus !== 'failed') {
95
+ finalStatus = 'completed';
96
+ }
97
+ }
98
+ continue;
99
+ }
100
+ if (entryType === 'tool_use') {
101
+ const toolName = extractToolName(parsed);
102
+ if (toolName) {
103
+ toolCalls.set(toolName, (toolCalls.get(toolName) ?? 0) + 1);
104
+ }
105
+ continue;
106
+ }
107
+ if (entryType === 'tool_result') {
108
+ const errorText = extractErrorText(parsed);
109
+ if (errorText) {
110
+ errors.push({ turn: Math.max(turns, 1), text: errorText });
111
+ finalStatus = 'failed';
112
+ }
113
+ }
114
+ }
115
+ }
116
+ finally {
117
+ session.close();
118
+ }
119
+ if (rawLines.length === 0) {
120
+ return null;
121
+ }
122
+ return {
123
+ cli: 'claude',
124
+ sessionId,
125
+ model,
126
+ provider,
127
+ durationMs: Math.max(query.completedAt - query.startedAt, 0),
128
+ cost: null,
129
+ tokens: tokens.input || tokens.output || tokens.cacheRead ? tokens : null,
130
+ turns,
131
+ toolCalls: Array.from(toolCalls, ([name, count]) => ({ name, count })),
132
+ errors,
133
+ finalStatus,
134
+ summary,
135
+ raw: {
136
+ historyPath: HISTORY_PATH,
137
+ sessionPath,
138
+ lines: rawLines,
139
+ },
140
+ };
141
+ }
142
+ function toHistoryEntry(record) {
143
+ const timestamp = getNumber(record.timestamp);
144
+ const project = getString(record.project);
145
+ const sessionId = getString(record.sessionId);
146
+ if (timestamp === null || !project || !sessionId) {
147
+ return null;
148
+ }
149
+ return {
150
+ display: getString(record.display) ?? undefined,
151
+ timestamp,
152
+ project,
153
+ sessionId,
154
+ };
155
+ }
156
+ function encodeProjectPath(projectPath) {
157
+ return projectPath.replace(/\//g, '--').replace(/^-+/, '');
158
+ }
159
+ function extractUsage(record) {
160
+ const usage = findNestedRecord(record, [
161
+ 'usage',
162
+ 'message.usage',
163
+ 'metadata.usage',
164
+ 'message.metadata.usage',
165
+ ]);
166
+ if (!usage) {
167
+ return null;
168
+ }
169
+ return {
170
+ input: firstNumber(usage, ['input_tokens', 'inputTokens']) ?? 0,
171
+ output: firstNumber(usage, ['output_tokens', 'outputTokens']) ?? 0,
172
+ cacheRead: firstNumber(usage, ['cache_read_input_tokens', 'cacheReadInputTokens', 'cache_read_tokens']) ?? 0,
173
+ };
174
+ }
175
+ function extractModel(record) {
176
+ return (getString(record.model)
177
+ ?? getString(record.modelId)
178
+ ?? getString(findNestedValue(record, ['message.model', 'message.modelId', 'metadata.model'])));
179
+ }
180
+ function extractProvider(record) {
181
+ return (getString(record.provider)
182
+ ?? getString(record.providerId)
183
+ ?? getString(findNestedValue(record, ['message.provider', 'message.providerId', 'metadata.provider']))
184
+ ?? 'anthropic');
185
+ }
186
+ function extractToolName(record) {
187
+ return (getString(record.name)
188
+ ?? getString(record.tool_name)
189
+ ?? getString(findNestedValue(record, ['tool.name', 'content.name'])));
190
+ }
191
+ function extractErrorText(record) {
192
+ const candidates = [
193
+ getString(record.error),
194
+ getString(findNestedValue(record, ['content.error', 'result.error', 'data.error', 'payload.error'])),
195
+ extractText(record),
196
+ ];
197
+ for (const candidate of candidates) {
198
+ const normalized = normalizeError(candidate);
199
+ if (normalized) {
200
+ return normalized;
201
+ }
202
+ }
203
+ return null;
204
+ }
205
+ function extractText(value) {
206
+ if (typeof value === 'string') {
207
+ return value.trim() || null;
208
+ }
209
+ if (!value || typeof value !== 'object') {
210
+ return null;
211
+ }
212
+ if (Array.isArray(value)) {
213
+ const texts = value
214
+ .map((entry) => extractText(entry))
215
+ .filter((entry) => Boolean(entry));
216
+ return texts.length > 0 ? texts.join('\n').trim() : null;
217
+ }
218
+ const record = value;
219
+ if (typeof record.text === 'string' && record.text.trim()) {
220
+ return record.text.trim();
221
+ }
222
+ if (typeof record.content === 'string' && record.content.trim()) {
223
+ return record.content.trim();
224
+ }
225
+ if (Array.isArray(record.content)) {
226
+ const texts = record.content
227
+ .map((entry) => extractText(entry))
228
+ .filter((entry) => Boolean(entry));
229
+ if (texts.length > 0) {
230
+ return texts.join('\n').trim();
231
+ }
232
+ }
233
+ if (record.message && typeof record.message === 'object') {
234
+ return extractText(record.message);
235
+ }
236
+ return null;
237
+ }
238
+ function normalizeError(text) {
239
+ if (!text) {
240
+ return null;
241
+ }
242
+ const line = text
243
+ .split('\n')
244
+ .map((entry) => entry.trim())
245
+ .find((entry) => /(?:^error\b|^error:|^command failed\b|^fail\b|exception|traceback)/i.test(entry));
246
+ return line ?? null;
247
+ }
248
+ function safeParseRecord(line) {
249
+ const trimmed = line.trim();
250
+ if (!trimmed) {
251
+ return null;
252
+ }
253
+ try {
254
+ const parsed = JSON.parse(trimmed);
255
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
256
+ return null;
257
+ }
258
+ return parsed;
259
+ }
260
+ catch {
261
+ return null;
262
+ }
263
+ }
264
+ function findNestedRecord(root, paths) {
265
+ for (const candidate of paths) {
266
+ const value = findNestedValue(root, [candidate]);
267
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
268
+ return value;
269
+ }
270
+ }
271
+ return null;
272
+ }
273
+ function findNestedValue(root, paths) {
274
+ for (const candidate of paths) {
275
+ let current = root;
276
+ let found = true;
277
+ for (const segment of candidate.split('.')) {
278
+ if (!current || typeof current !== 'object' || Array.isArray(current) || !(segment in current)) {
279
+ found = false;
280
+ break;
281
+ }
282
+ current = current[segment];
283
+ }
284
+ if (found) {
285
+ return current;
286
+ }
287
+ }
288
+ return undefined;
289
+ }
290
+ function firstNumber(record, keys) {
291
+ for (const key of keys) {
292
+ const value = record[key];
293
+ if (typeof value === 'number' && Number.isFinite(value)) {
294
+ return value;
295
+ }
296
+ }
297
+ return null;
298
+ }
299
+ function getString(value) {
300
+ return typeof value === 'string' && value.trim() ? value.trim() : null;
301
+ }
302
+ function getNumber(value) {
303
+ return typeof value === 'number' && Number.isFinite(value) ? value : null;
304
+ }
305
+ function isReadableFile(filePath) {
306
+ try {
307
+ return existsSync(filePath) && statSync(filePath).isFile();
308
+ }
309
+ catch {
310
+ return false;
311
+ }
312
+ }
313
+ function isReadableDirectory(dirPath) {
314
+ try {
315
+ return existsSync(dirPath) && statSync(dirPath).isDirectory();
316
+ }
317
+ catch {
318
+ return false;
319
+ }
320
+ }
321
+ async function isReadableFileAsync(filePath) {
322
+ try {
323
+ await access(filePath);
324
+ return true;
325
+ }
326
+ catch {
327
+ return false;
328
+ }
329
+ }
330
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../../src/workflows/collectors/claude.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { CliSessionCollector, CliSessionQuery, CliSessionReport } from '../cli-session-collector.js';
2
+ interface CodexCollectorOptions {
3
+ historyPath?: string;
4
+ statePath?: string;
5
+ }
6
+ export declare class CodexCollector implements CliSessionCollector {
7
+ private readonly historyPath;
8
+ private readonly statePath;
9
+ constructor(options?: CodexCollectorOptions);
10
+ canCollect(): boolean;
11
+ collect(query: CliSessionQuery): Promise<CliSessionReport | null>;
12
+ private readHistoryEntries;
13
+ private findMatchingHistoryEntry;
14
+ private findMatchingThread;
15
+ private readThreadErrors;
16
+ }
17
+ export {};
18
+ //# sourceMappingURL=codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../../src/workflows/collectors/codex.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EACjB,MAAM,6BAA6B,CAAC;AA0BrC,UAAU,qBAAqB;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAoID,qBAAa,cAAe,YAAW,mBAAmB;IACxD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,OAAO,GAAE,qBAA0B;IAK/C,UAAU,IAAI,OAAO;IAIf,OAAO,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IA4DvE,OAAO,CAAC,kBAAkB;IAmB1B,OAAO,CAAC,wBAAwB;YAgBlB,kBAAkB;YAgClB,gBAAgB;CAwC/B"}
@@ -0,0 +1,265 @@
1
+ import fs from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import { createRequire } from 'node:module';
5
+ const require = createRequire(import.meta.url);
6
+ const CODEX_HOME = path.join(os.homedir(), '.codex');
7
+ const DEFAULT_HISTORY_PATH = path.join(CODEX_HOME, 'history.jsonl');
8
+ const DEFAULT_STATE_PATH = path.join(CODEX_HOME, 'state_5.sqlite');
9
+ function loadBetterSqlite3() {
10
+ try {
11
+ return require('better-sqlite3');
12
+ }
13
+ catch {
14
+ return null;
15
+ }
16
+ }
17
+ async function openDatabase(dbPath) {
18
+ const BetterSqlite = loadBetterSqlite3();
19
+ if (BetterSqlite) {
20
+ try {
21
+ return new BetterSqlite(dbPath, { readonly: true, fileMustExist: true });
22
+ }
23
+ catch {
24
+ // Fall through to node:sqlite.
25
+ }
26
+ }
27
+ try {
28
+ const sqlite = (await import('node:sqlite'));
29
+ return new sqlite.DatabaseSync(dbPath, { readOnly: true, open: true });
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ function normalizeTimestamp(value) {
36
+ const numeric = typeof value === 'number' && Number.isFinite(value)
37
+ ? value
38
+ : typeof value === 'string' && value.trim()
39
+ ? Number(value)
40
+ : null;
41
+ if (numeric === null || !Number.isFinite(numeric)) {
42
+ return null;
43
+ }
44
+ return numeric < 10_000_000_000 ? numeric * 1000 : numeric;
45
+ }
46
+ function parseJsonLine(line) {
47
+ try {
48
+ return JSON.parse(line);
49
+ }
50
+ catch {
51
+ return null;
52
+ }
53
+ }
54
+ function parseModelProvider(value) {
55
+ if (!value) {
56
+ return { provider: null, model: null };
57
+ }
58
+ if (value.includes('/')) {
59
+ const [provider, ...rest] = value.split('/');
60
+ return {
61
+ provider: provider || null,
62
+ model: rest.join('/') || null,
63
+ };
64
+ }
65
+ if (value.includes(':')) {
66
+ const [provider, ...rest] = value.split(':');
67
+ return {
68
+ provider: provider || null,
69
+ model: rest.join(':') || null,
70
+ };
71
+ }
72
+ return {
73
+ provider: value,
74
+ model: null,
75
+ };
76
+ }
77
+ function getNumericField(row, fieldNames) {
78
+ for (const fieldName of fieldNames) {
79
+ const value = row[fieldName];
80
+ if (typeof value === 'number' && Number.isFinite(value)) {
81
+ return value;
82
+ }
83
+ }
84
+ return null;
85
+ }
86
+ function extractTokens(row) {
87
+ const input = getNumericField(row, ['input_tokens', 'prompt_tokens', 'tokens_input']);
88
+ const output = getNumericField(row, ['output_tokens', 'completion_tokens', 'tokens_output']);
89
+ const cacheRead = getNumericField(row, ['cache_read_tokens', 'tokens_cache_read', 'cached_input_tokens']);
90
+ if (input !== null || output !== null || cacheRead !== null) {
91
+ return {
92
+ input: input ?? 0,
93
+ output: output ?? 0,
94
+ cacheRead: cacheRead ?? 0,
95
+ };
96
+ }
97
+ return typeof row.tokens_used === 'number'
98
+ ? {
99
+ input: row.tokens_used,
100
+ output: 0,
101
+ cacheRead: 0,
102
+ }
103
+ : null;
104
+ }
105
+ export class CodexCollector {
106
+ historyPath;
107
+ statePath;
108
+ constructor(options = {}) {
109
+ this.historyPath = options.historyPath ?? DEFAULT_HISTORY_PATH;
110
+ this.statePath = options.statePath ?? DEFAULT_STATE_PATH;
111
+ }
112
+ canCollect() {
113
+ return fs.existsSync(this.statePath) || fs.existsSync(this.historyPath);
114
+ }
115
+ async collect(query) {
116
+ const historyEntries = this.readHistoryEntries();
117
+ const matchedThread = await this.findMatchingThread(query);
118
+ if (matchedThread) {
119
+ const errors = await this.readThreadErrors(matchedThread.id);
120
+ const { provider, model } = parseModelProvider(matchedThread.model_provider);
121
+ const createdAtMs = normalizeTimestamp(matchedThread.created_at);
122
+ const updatedAtMs = normalizeTimestamp(matchedThread.updated_at);
123
+ return {
124
+ cli: 'codex',
125
+ sessionId: matchedThread.id,
126
+ model,
127
+ provider,
128
+ durationMs: createdAtMs !== null && updatedAtMs !== null && updatedAtMs >= createdAtMs
129
+ ? updatedAtMs - createdAtMs
130
+ : Math.max(query.completedAt - query.startedAt, 0),
131
+ cost: null,
132
+ tokens: extractTokens(matchedThread),
133
+ turns: historyEntries.filter((entry) => entry.session_id === matchedThread.id).length,
134
+ toolCalls: [],
135
+ errors,
136
+ finalStatus: errors.length > 0 ? 'failed' : 'unknown',
137
+ summary: null,
138
+ raw: {
139
+ matchedVia: 'threads',
140
+ thread: matchedThread,
141
+ },
142
+ };
143
+ }
144
+ const historyMatch = this.findMatchingHistoryEntry(query, historyEntries);
145
+ if (!historyMatch) {
146
+ return null;
147
+ }
148
+ return {
149
+ cli: 'codex',
150
+ sessionId: historyMatch.session_id ?? null,
151
+ model: null,
152
+ provider: null,
153
+ durationMs: Math.max(query.completedAt - query.startedAt, 0),
154
+ cost: null,
155
+ tokens: null,
156
+ turns: historyMatch.session_id
157
+ ? historyEntries.filter((entry) => entry.session_id === historyMatch.session_id).length
158
+ : 0,
159
+ toolCalls: [],
160
+ errors: [],
161
+ finalStatus: 'unknown',
162
+ summary: null,
163
+ raw: {
164
+ matchedVia: 'history',
165
+ entry: historyMatch,
166
+ },
167
+ };
168
+ }
169
+ readHistoryEntries() {
170
+ if (!fs.existsSync(this.historyPath)) {
171
+ return [];
172
+ }
173
+ try {
174
+ return fs.readFileSync(this.historyPath, 'utf8')
175
+ .split(/\r?\n/)
176
+ .map((line) => line.trim())
177
+ .filter(Boolean)
178
+ .flatMap((line) => {
179
+ const parsed = parseJsonLine(line);
180
+ return parsed ? [parsed] : [];
181
+ });
182
+ }
183
+ catch {
184
+ return [];
185
+ }
186
+ }
187
+ findMatchingHistoryEntry(query, entries) {
188
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
189
+ const entry = entries[index];
190
+ const timestamp = normalizeTimestamp(entry.ts);
191
+ if (timestamp === null) {
192
+ continue;
193
+ }
194
+ if (timestamp >= query.startedAt && timestamp <= query.completedAt) {
195
+ return entry;
196
+ }
197
+ }
198
+ return null;
199
+ }
200
+ async findMatchingThread(query) {
201
+ if (!fs.existsSync(this.statePath)) {
202
+ return null;
203
+ }
204
+ const db = await openDatabase(this.statePath);
205
+ if (!db) {
206
+ return null;
207
+ }
208
+ try {
209
+ const threads = db.prepare(`
210
+ SELECT *
211
+ FROM threads
212
+ WHERE cwd = ?
213
+ ORDER BY created_at DESC
214
+ LIMIT 100
215
+ `).all(query.cwd);
216
+ return threads.find((thread) => {
217
+ const createdAt = normalizeTimestamp(thread.created_at);
218
+ return createdAt !== null && createdAt >= query.startedAt && createdAt <= query.completedAt;
219
+ }) ?? null;
220
+ }
221
+ catch {
222
+ return null;
223
+ }
224
+ finally {
225
+ db.close?.();
226
+ }
227
+ }
228
+ async readThreadErrors(threadId) {
229
+ if (!fs.existsSync(this.statePath)) {
230
+ return [];
231
+ }
232
+ const db = await openDatabase(this.statePath);
233
+ if (!db) {
234
+ return [];
235
+ }
236
+ try {
237
+ const rows = db.prepare(`
238
+ SELECT ts, level, message, line
239
+ FROM logs
240
+ WHERE thread_id = ?
241
+ AND lower(level) = 'error'
242
+ ORDER BY ts ASC
243
+ `).all(threadId);
244
+ return rows
245
+ .map((row, index) => {
246
+ const message = typeof row.message === 'string' ? row.message.trim() : '';
247
+ if (!message) {
248
+ return null;
249
+ }
250
+ return {
251
+ turn: index + 1,
252
+ text: message,
253
+ };
254
+ })
255
+ .filter((row) => row !== null);
256
+ }
257
+ catch {
258
+ return [];
259
+ }
260
+ finally {
261
+ db.close?.();
262
+ }
263
+ }
264
+ }
265
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../src/workflows/collectors/codex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { CliSessionCollector, CliSessionQuery, CliSessionReport } from '../cli-session-collector.js';
2
+ export declare class OpenCodeCollector implements CliSessionCollector {
3
+ canCollect(): boolean;
4
+ collect(query: CliSessionQuery): Promise<CliSessionReport | null>;
5
+ }
6
+ //# sourceMappingURL=opencode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../../src/workflows/collectors/opencode.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EACjB,MAAM,6BAA6B,CAAC;AAmGrC,qBAAa,iBAAkB,YAAW,mBAAmB;IAC3D,UAAU,IAAI,OAAO;IAwBf,OAAO,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;CAiJxE"}