ccompactor 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE +37 -0
- package/README.md +101 -0
- package/dist/adapters/claude.d.ts +36 -0
- package/dist/adapters/claude.js +361 -0
- package/dist/adapters/claude.js.map +1 -0
- package/dist/adapters/codex.d.ts +11 -0
- package/dist/adapters/codex.js +218 -0
- package/dist/adapters/codex.js.map +1 -0
- package/dist/adapters/index.d.ts +17 -0
- package/dist/adapters/index.js +19 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/pi.d.ts +16 -0
- package/dist/adapters/pi.js +213 -0
- package/dist/adapters/pi.js.map +1 -0
- package/dist/adapters/types.d.ts +31 -0
- package/dist/adapters/types.js +7 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/artifact/expand.d.ts +23 -0
- package/dist/artifact/expand.js +71 -0
- package/dist/artifact/expand.js.map +1 -0
- package/dist/artifact/render.d.ts +59 -0
- package/dist/artifact/render.js +357 -0
- package/dist/artifact/render.js.map +1 -0
- package/dist/artifact/verify.d.ts +12 -0
- package/dist/artifact/verify.js +48 -0
- package/dist/artifact/verify.js.map +1 -0
- package/dist/bench/index.d.ts +71 -0
- package/dist/bench/index.js +186 -0
- package/dist/bench/index.js.map +1 -0
- package/dist/bench/run.d.ts +17 -0
- package/dist/bench/run.js +187 -0
- package/dist/bench/run.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +322 -0
- package/dist/cli.js.map +1 -0
- package/dist/compact/engine.d.ts +69 -0
- package/dist/compact/engine.js +164 -0
- package/dist/compact/engine.js.map +1 -0
- package/dist/compact/shims.d.ts +24 -0
- package/dist/compact/shims.js +14 -0
- package/dist/compact/shims.js.map +1 -0
- package/dist/discover/index.d.ts +40 -0
- package/dist/discover/index.js +164 -0
- package/dist/discover/index.js.map +1 -0
- package/dist/discover/reference.d.ts +21 -0
- package/dist/discover/reference.js +44 -0
- package/dist/discover/reference.js.map +1 -0
- package/dist/extract.d.ts +26 -0
- package/dist/extract.js +103 -0
- package/dist/extract.js.map +1 -0
- package/dist/handoff/index.d.ts +12 -0
- package/dist/handoff/index.js +67 -0
- package/dist/handoff/index.js.map +1 -0
- package/dist/ir/tokens.d.ts +14 -0
- package/dist/ir/tokens.js +36 -0
- package/dist/ir/tokens.js.map +1 -0
- package/dist/ir/types.d.ts +82 -0
- package/dist/ir/types.js +36 -0
- package/dist/ir/types.js.map +1 -0
- package/dist/ledgers/index.d.ts +66 -0
- package/dist/ledgers/index.js +185 -0
- package/dist/ledgers/index.js.map +1 -0
- package/dist/llm/index.d.ts +43 -0
- package/dist/llm/index.js +143 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/redact.d.ts +39 -0
- package/dist/redact.js +104 -0
- package/dist/redact.js.map +1 -0
- package/dist/skill/index.d.ts +9 -0
- package/dist/skill/index.js +48 -0
- package/dist/skill/index.js.map +1 -0
- package/dist/triage.d.ts +25 -0
- package/dist/triage.js +160 -0
- package/dist/triage.js.map +1 -0
- package/dist/tui/index.d.ts +4 -0
- package/dist/tui/index.js +147 -0
- package/dist/tui/index.js.map +1 -0
- package/package.json +71 -0
- package/skill/SKILL.md +54 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex CLI session adapter.
|
|
3
|
+
*
|
|
4
|
+
* The store is `~/.codex/sessions/YYYY/MM/DD/rollout-<ts>-<uuid>.jsonl`, one
|
|
5
|
+
* JSON object per line, each `{timestamp, type, payload}`.
|
|
6
|
+
*
|
|
7
|
+
* Two properties differ from Claude's format and both matter:
|
|
8
|
+
*
|
|
9
|
+
* 1. **The line order is the order.** Codex records a rollout, and a rollback
|
|
10
|
+
* rewrites history by appending rather than by branching, so there is no
|
|
11
|
+
* `parentUuid` to walk. Rollbacks are handled by the `compacted` and
|
|
12
|
+
* `turn_aborted` markers instead.
|
|
13
|
+
*
|
|
14
|
+
* 2. **The user's words live in two places.** `event_msg` carries the human's
|
|
15
|
+
* message; `response_item` carries the same turn as a model-input item. Only
|
|
16
|
+
* the first is intent — reading both double-counts every request.
|
|
17
|
+
*/
|
|
18
|
+
import { homedir } from 'node:os';
|
|
19
|
+
import { basename, join } from 'node:path';
|
|
20
|
+
import { existsSync } from 'node:fs';
|
|
21
|
+
import { readdir, stat } from 'node:fs/promises';
|
|
22
|
+
import { readLines } from './types.js';
|
|
23
|
+
export function codexStore() {
|
|
24
|
+
return process.env['CODEX_HOME'] ? join(process.env['CODEX_HOME'], 'sessions') : join(homedir(), '.codex', 'sessions');
|
|
25
|
+
}
|
|
26
|
+
export class CodexAdapter {
|
|
27
|
+
kind = 'codex';
|
|
28
|
+
label = 'Codex CLI';
|
|
29
|
+
store() {
|
|
30
|
+
return codexStore();
|
|
31
|
+
}
|
|
32
|
+
available() {
|
|
33
|
+
return existsSync(this.store());
|
|
34
|
+
}
|
|
35
|
+
async list(options) {
|
|
36
|
+
const root = this.store();
|
|
37
|
+
const files = await walkJsonl(root, options.maxBytes);
|
|
38
|
+
const refs = [];
|
|
39
|
+
for (const { path, mtime, bytes } of files) {
|
|
40
|
+
const name = basename(path).replace(/\.jsonl(\.zst)?$/, '');
|
|
41
|
+
// `rollout-2026-01-01T00-00-00-<uuid>`: the uuid is the id, the rest is
|
|
42
|
+
// the timestamp the provider already encodes in the filename.
|
|
43
|
+
const id = name.replace(/^rollout-/, '');
|
|
44
|
+
refs.push({ agent: 'codex', id, path, mtime, bytes });
|
|
45
|
+
}
|
|
46
|
+
return refs.sort((a, b) => b.mtime - a.mtime);
|
|
47
|
+
}
|
|
48
|
+
async read(ref, _options = {}) {
|
|
49
|
+
const lines = await readLines(ref.path);
|
|
50
|
+
const diagnostics = [];
|
|
51
|
+
const messages = [];
|
|
52
|
+
const compactBoundaries = [];
|
|
53
|
+
const metadata = {};
|
|
54
|
+
const seenUserText = new Set();
|
|
55
|
+
for (const [index, line] of lines.entries()) {
|
|
56
|
+
let raw;
|
|
57
|
+
try {
|
|
58
|
+
raw = JSON.parse(line);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
diagnostics.push({ line: index + 1, message: `unparseable: ${error.message}` });
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const payload = raw.payload ?? {};
|
|
65
|
+
if (raw.type === 'session_meta') {
|
|
66
|
+
for (const key of ['cwd', 'id', 'cli_version', 'originator']) {
|
|
67
|
+
if (payload[key] !== undefined)
|
|
68
|
+
metadata[key] = payload[key];
|
|
69
|
+
}
|
|
70
|
+
const git = payload['git'];
|
|
71
|
+
if (typeof git === 'object' && git !== null) {
|
|
72
|
+
const branch = git['branch'];
|
|
73
|
+
if (typeof branch === 'string')
|
|
74
|
+
metadata['branch'] = branch;
|
|
75
|
+
}
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (raw.type === 'compacted') {
|
|
79
|
+
compactBoundaries.push(index);
|
|
80
|
+
messages.push({
|
|
81
|
+
uuid: `evt-${index}`,
|
|
82
|
+
role: 'attachment',
|
|
83
|
+
text: typeof payload['message'] === 'string' ? payload['message'] : 'compacted',
|
|
84
|
+
eventIndex: index,
|
|
85
|
+
raw,
|
|
86
|
+
});
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (raw.type === 'event_msg') {
|
|
90
|
+
const kind = payload['type'];
|
|
91
|
+
if (kind === 'user_message') {
|
|
92
|
+
const text = typeof payload['message'] === 'string' ? payload['message'] : '';
|
|
93
|
+
if (text.trim().length === 0)
|
|
94
|
+
continue;
|
|
95
|
+
// The same turn reappears as a `response_item` message below; the
|
|
96
|
+
// human said it once.
|
|
97
|
+
seenUserText.add(text.trim());
|
|
98
|
+
messages.push({
|
|
99
|
+
uuid: `evt-${index}`,
|
|
100
|
+
role: 'user',
|
|
101
|
+
text,
|
|
102
|
+
isHumanTurn: true,
|
|
103
|
+
eventIndex: index,
|
|
104
|
+
raw,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (raw.type === 'turn_context') {
|
|
110
|
+
const cwd = payload['cwd'];
|
|
111
|
+
if (typeof cwd === 'string' && metadata['cwd'] === undefined)
|
|
112
|
+
metadata['cwd'] = cwd;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (raw.type !== 'response_item')
|
|
116
|
+
continue;
|
|
117
|
+
const kind = payload['type'];
|
|
118
|
+
if (kind === 'message') {
|
|
119
|
+
const role = typeof payload['role'] === 'string' ? payload['role'] : 'assistant';
|
|
120
|
+
const text = contentText(payload['content']);
|
|
121
|
+
if (text.trim().length === 0)
|
|
122
|
+
continue;
|
|
123
|
+
if (role === 'user') {
|
|
124
|
+
if (seenUserText.has(text.trim()))
|
|
125
|
+
continue;
|
|
126
|
+
seenUserText.add(text.trim());
|
|
127
|
+
messages.push({
|
|
128
|
+
uuid: `evt-${index}`,
|
|
129
|
+
role: 'user',
|
|
130
|
+
text,
|
|
131
|
+
isHumanTurn: true,
|
|
132
|
+
eventIndex: index,
|
|
133
|
+
raw,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
messages.push({ uuid: `evt-${index}`, role: 'assistant', text, eventIndex: index, raw });
|
|
138
|
+
}
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (kind === 'function_call') {
|
|
142
|
+
messages.push({
|
|
143
|
+
uuid: `evt-${index}`,
|
|
144
|
+
role: 'assistant',
|
|
145
|
+
toolName: typeof payload['name'] === 'string' ? payload['name'] : undefined,
|
|
146
|
+
toolUseId: typeof payload['call_id'] === 'string' ? payload['call_id'] : undefined,
|
|
147
|
+
toolInput: parseArguments(payload['arguments']),
|
|
148
|
+
eventIndex: index,
|
|
149
|
+
raw,
|
|
150
|
+
});
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (kind === 'function_call_output') {
|
|
154
|
+
messages.push({
|
|
155
|
+
uuid: `evt-${index}`,
|
|
156
|
+
role: 'tool',
|
|
157
|
+
toolUseId: typeof payload['call_id'] === 'string' ? payload['call_id'] : undefined,
|
|
158
|
+
toolResult: payload['output'],
|
|
159
|
+
text: typeof payload['output'] === 'string' ? payload['output'] : undefined,
|
|
160
|
+
eventIndex: index,
|
|
161
|
+
raw,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return { ref, messages, compactBoundaries, metadata, diagnostics };
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function contentText(content) {
|
|
169
|
+
if (typeof content === 'string')
|
|
170
|
+
return content;
|
|
171
|
+
if (!Array.isArray(content))
|
|
172
|
+
return '';
|
|
173
|
+
const parts = [];
|
|
174
|
+
for (const block of content) {
|
|
175
|
+
if (typeof block !== 'object' || block === null)
|
|
176
|
+
continue;
|
|
177
|
+
const b = block;
|
|
178
|
+
for (const key of ['text', 'input_text', 'output_text']) {
|
|
179
|
+
if (typeof b[key] === 'string')
|
|
180
|
+
parts.push(b[key]);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return parts.join('\n\n');
|
|
184
|
+
}
|
|
185
|
+
function parseArguments(value) {
|
|
186
|
+
if (typeof value !== 'string')
|
|
187
|
+
return value;
|
|
188
|
+
try {
|
|
189
|
+
return JSON.parse(value);
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
return value;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
async function walkJsonl(root, maxBytes) {
|
|
196
|
+
const out = [];
|
|
197
|
+
const stack = [root];
|
|
198
|
+
while (stack.length > 0) {
|
|
199
|
+
const dir = stack.pop();
|
|
200
|
+
for (const entry of await readdir(dir, { withFileTypes: true }).catch(() => [])) {
|
|
201
|
+
const path = join(dir, entry.name);
|
|
202
|
+
if (entry.isDirectory()) {
|
|
203
|
+
stack.push(path);
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
if (!entry.name.endsWith('.jsonl'))
|
|
207
|
+
continue;
|
|
208
|
+
const info = await stat(path).catch(() => null);
|
|
209
|
+
if (!info?.isFile())
|
|
210
|
+
continue;
|
|
211
|
+
if (maxBytes !== undefined && info.size > maxBytes)
|
|
212
|
+
continue;
|
|
213
|
+
out.push({ path, mtime: info.mtimeMs, bytes: info.size });
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return out;
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=codex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/adapters/codex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AgentKind } from '../ir/types.js';
|
|
2
|
+
import type { Adapter } from './types.js';
|
|
3
|
+
import { ClaudeAdapter } from './claude.js';
|
|
4
|
+
import { CodexAdapter } from './codex.js';
|
|
5
|
+
import { PiAdapter } from './pi.js';
|
|
6
|
+
/**
|
|
7
|
+
* The adapter registry.
|
|
8
|
+
*
|
|
9
|
+
* Adding an agent means adding one file here and nothing else — every later
|
|
10
|
+
* stage reads the canonical IR, not a provider format. Adapters whose store is
|
|
11
|
+
* absent are still listed, so `doctor` can say what it looked for and did not
|
|
12
|
+
* find rather than silently omitting a provider.
|
|
13
|
+
*/
|
|
14
|
+
export declare function adapters(): Adapter[];
|
|
15
|
+
export declare function adapterFor(kind: AgentKind): Adapter | undefined;
|
|
16
|
+
export { ClaudeAdapter, CodexAdapter, PiAdapter };
|
|
17
|
+
export type { Adapter, ListOptions, ReadOptions } from './types.js';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ClaudeAdapter } from './claude.js';
|
|
2
|
+
import { CodexAdapter } from './codex.js';
|
|
3
|
+
import { PiAdapter } from './pi.js';
|
|
4
|
+
/**
|
|
5
|
+
* The adapter registry.
|
|
6
|
+
*
|
|
7
|
+
* Adding an agent means adding one file here and nothing else — every later
|
|
8
|
+
* stage reads the canonical IR, not a provider format. Adapters whose store is
|
|
9
|
+
* absent are still listed, so `doctor` can say what it looked for and did not
|
|
10
|
+
* find rather than silently omitting a provider.
|
|
11
|
+
*/
|
|
12
|
+
export function adapters() {
|
|
13
|
+
return [new ClaudeAdapter(), new CodexAdapter(), new PiAdapter()];
|
|
14
|
+
}
|
|
15
|
+
export function adapterFor(kind) {
|
|
16
|
+
return adapters().find((a) => a.kind === kind);
|
|
17
|
+
}
|
|
18
|
+
export { ClaudeAdapter, CodexAdapter, PiAdapter };
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAEnC;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,CAAC,IAAI,aAAa,EAAE,EAAE,IAAI,YAAY,EAAE,EAAE,IAAI,SAAS,EAAE,CAAC,CAAA;AACnE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAe;IACxC,OAAO,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;AAChD,CAAC;AAED,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AgentKind, SessionIR, SessionRef } from '../ir/types.js';
|
|
2
|
+
import type { Adapter, ListOptions, ReadOptions } from './types.js';
|
|
3
|
+
export declare function piStore(): string;
|
|
4
|
+
/** How well a session was understood, so the artifact can say so. */
|
|
5
|
+
export interface PiCoverage {
|
|
6
|
+
recognised: number;
|
|
7
|
+
unknown: number;
|
|
8
|
+
}
|
|
9
|
+
export declare class PiAdapter implements Adapter {
|
|
10
|
+
kind: AgentKind;
|
|
11
|
+
label: string;
|
|
12
|
+
store(): string;
|
|
13
|
+
available(): boolean;
|
|
14
|
+
list(options: ListOptions): Promise<SessionRef[]>;
|
|
15
|
+
read(ref: SessionRef, _options?: ReadOptions): Promise<SessionIR>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pi session adapter.
|
|
3
|
+
*
|
|
4
|
+
* The store is `~/.pi/agent/sessions/<slugified-project>/<timestamp>_<id>.jsonl`.
|
|
5
|
+
* Files are v1-v3 and the record types seen in the wild are `session`,
|
|
6
|
+
* `model_change`, `thinking_level_change`, `custom_message` and `message`, with
|
|
7
|
+
* message roles `user`, `assistant` and `toolResult`.
|
|
8
|
+
*
|
|
9
|
+
* `custom_message` is harness-injected context — a plugin feeding the session a
|
|
10
|
+
* block of text — and is recorded as an attachment rather than as a user turn.
|
|
11
|
+
* Treating it as intent would put a news feed into the handoff as something the
|
|
12
|
+
* human asked for.
|
|
13
|
+
*
|
|
14
|
+
* Unknown record types are counted and reported rather than skipped in silence,
|
|
15
|
+
* because a handoff that is quietly missing half a session is worse than one
|
|
16
|
+
* that says which half.
|
|
17
|
+
*/
|
|
18
|
+
import { homedir } from 'node:os';
|
|
19
|
+
import { join } from 'node:path';
|
|
20
|
+
import { existsSync } from 'node:fs';
|
|
21
|
+
import { readdir, stat } from 'node:fs/promises';
|
|
22
|
+
import { readLines } from './types.js';
|
|
23
|
+
export function piStore() {
|
|
24
|
+
return process.env['PI_HOME']
|
|
25
|
+
? join(process.env['PI_HOME'], 'agent', 'sessions')
|
|
26
|
+
: join(homedir(), '.pi', 'agent', 'sessions');
|
|
27
|
+
}
|
|
28
|
+
export class PiAdapter {
|
|
29
|
+
kind = 'pi';
|
|
30
|
+
label = 'Pi';
|
|
31
|
+
store() {
|
|
32
|
+
return piStore();
|
|
33
|
+
}
|
|
34
|
+
available() {
|
|
35
|
+
return existsSync(this.store());
|
|
36
|
+
}
|
|
37
|
+
async list(options) {
|
|
38
|
+
const refs = [];
|
|
39
|
+
const root = this.store();
|
|
40
|
+
const stack = [root];
|
|
41
|
+
while (stack.length > 0) {
|
|
42
|
+
const dir = stack.pop();
|
|
43
|
+
for (const entry of await readdir(dir, { withFileTypes: true }).catch(() => [])) {
|
|
44
|
+
const path = join(dir, entry.name);
|
|
45
|
+
if (entry.isDirectory()) {
|
|
46
|
+
stack.push(path);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (!entry.name.endsWith('.jsonl'))
|
|
50
|
+
continue;
|
|
51
|
+
const info = await stat(path).catch(() => null);
|
|
52
|
+
if (!info?.isFile())
|
|
53
|
+
continue;
|
|
54
|
+
if (options.maxBytes !== undefined && info.size > options.maxBytes)
|
|
55
|
+
continue;
|
|
56
|
+
refs.push({
|
|
57
|
+
agent: 'pi',
|
|
58
|
+
id: entry.name.replace(/\.jsonl$/, ''),
|
|
59
|
+
path,
|
|
60
|
+
projectPath: dir,
|
|
61
|
+
mtime: info.mtimeMs,
|
|
62
|
+
bytes: info.size,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return refs.sort((a, b) => b.mtime - a.mtime);
|
|
67
|
+
}
|
|
68
|
+
async read(ref, _options = {}) {
|
|
69
|
+
const lines = await readLines(ref.path);
|
|
70
|
+
const diagnostics = [];
|
|
71
|
+
const messages = [];
|
|
72
|
+
const compactBoundaries = [];
|
|
73
|
+
const metadata = {};
|
|
74
|
+
let unknown = 0;
|
|
75
|
+
for (const [index, line] of lines.entries()) {
|
|
76
|
+
let raw;
|
|
77
|
+
try {
|
|
78
|
+
raw = JSON.parse(line);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
diagnostics.push({ line: index + 1, message: `unparseable: ${error.message}` });
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const type = typeof raw['type'] === 'string' ? raw['type'] : '';
|
|
85
|
+
const id = typeof raw['id'] === 'string' ? raw['id'] : `evt-${index}`;
|
|
86
|
+
const parentId = typeof raw['parentId'] === 'string' ? raw['parentId'] : undefined;
|
|
87
|
+
if (type === 'session') {
|
|
88
|
+
for (const key of ['cwd', 'id', 'version']) {
|
|
89
|
+
if (raw[key] !== undefined)
|
|
90
|
+
metadata[key] = raw[key];
|
|
91
|
+
}
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (type === 'model_change') {
|
|
95
|
+
if (typeof raw['modelId'] === 'string')
|
|
96
|
+
metadata['model'] = raw['modelId'];
|
|
97
|
+
if (typeof raw['provider'] === 'string')
|
|
98
|
+
metadata['provider'] = raw['provider'];
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (type === 'custom_message') {
|
|
102
|
+
// Harness-injected, never typed by the human.
|
|
103
|
+
messages.push({
|
|
104
|
+
uuid: id,
|
|
105
|
+
...(parentId ? { parentUuid: parentId } : {}),
|
|
106
|
+
role: 'attachment',
|
|
107
|
+
text: typeof raw['content'] === 'string' ? raw['content'] : '',
|
|
108
|
+
isMeta: true,
|
|
109
|
+
eventIndex: index,
|
|
110
|
+
raw,
|
|
111
|
+
});
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (type === 'compaction' || type === 'summary') {
|
|
115
|
+
compactBoundaries.push(index);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (type !== 'message') {
|
|
119
|
+
unknown += 1;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
const message = (raw['message'] ?? {});
|
|
123
|
+
const role = typeof message['role'] === 'string' ? message['role'] : '';
|
|
124
|
+
const text = contentText(message['content']);
|
|
125
|
+
const base = {
|
|
126
|
+
uuid: id,
|
|
127
|
+
...(parentId ? { parentUuid: parentId } : {}),
|
|
128
|
+
...(typeof raw['timestamp'] === 'string' ? { timestamp: raw['timestamp'] } : {}),
|
|
129
|
+
eventIndex: index,
|
|
130
|
+
raw,
|
|
131
|
+
};
|
|
132
|
+
if (role === 'user') {
|
|
133
|
+
if (text.trim().length === 0)
|
|
134
|
+
continue;
|
|
135
|
+
messages.push({ ...base, role: 'user', text, isHumanTurn: true });
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (role === 'assistant') {
|
|
139
|
+
const toolCall = firstToolCall(message['content']);
|
|
140
|
+
messages.push({
|
|
141
|
+
...base,
|
|
142
|
+
role: 'assistant',
|
|
143
|
+
text: text || undefined,
|
|
144
|
+
...(toolCall?.name ? { toolName: toolCall.name } : {}),
|
|
145
|
+
...(toolCall?.id ? { toolUseId: toolCall.id } : {}),
|
|
146
|
+
...(toolCall?.args !== undefined ? { toolInput: toolCall.args } : {}),
|
|
147
|
+
});
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (role === 'toolResult' || role === 'tool') {
|
|
151
|
+
messages.push({
|
|
152
|
+
...base,
|
|
153
|
+
role: 'tool',
|
|
154
|
+
...(typeof message['toolCallId'] === 'string' ? { toolUseId: message['toolCallId'] } : {}),
|
|
155
|
+
...(typeof message['toolName'] === 'string' ? { toolName: message['toolName'] } : {}),
|
|
156
|
+
text,
|
|
157
|
+
toolResult: message['content'],
|
|
158
|
+
isError: message['isError'] === true,
|
|
159
|
+
});
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
unknown += 1;
|
|
163
|
+
}
|
|
164
|
+
metadata['piUnknownRecords'] = unknown;
|
|
165
|
+
if (unknown > 0) {
|
|
166
|
+
diagnostics.push({
|
|
167
|
+
line: 0,
|
|
168
|
+
message: `${unknown} record(s) matched no known Pi shape and were skipped`,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
return { ref, messages, compactBoundaries, metadata, diagnostics };
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function contentText(content) {
|
|
175
|
+
if (typeof content === 'string')
|
|
176
|
+
return content;
|
|
177
|
+
if (!Array.isArray(content))
|
|
178
|
+
return '';
|
|
179
|
+
const parts = [];
|
|
180
|
+
for (const block of content) {
|
|
181
|
+
if (typeof block === 'string') {
|
|
182
|
+
parts.push(block);
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (typeof block !== 'object' || block === null)
|
|
186
|
+
continue;
|
|
187
|
+
const b = block;
|
|
188
|
+
if (typeof b['text'] === 'string')
|
|
189
|
+
parts.push(b['text']);
|
|
190
|
+
if (b['type'] === 'toolCall' && typeof b['name'] === 'string')
|
|
191
|
+
parts.push('');
|
|
192
|
+
}
|
|
193
|
+
return parts.join('\n\n');
|
|
194
|
+
}
|
|
195
|
+
function firstToolCall(content) {
|
|
196
|
+
if (!Array.isArray(content))
|
|
197
|
+
return undefined;
|
|
198
|
+
for (const block of content) {
|
|
199
|
+
if (typeof block !== 'object' || block === null)
|
|
200
|
+
continue;
|
|
201
|
+
const b = block;
|
|
202
|
+
if (b['type'] === 'toolCall' || b['type'] === 'tool_use') {
|
|
203
|
+
return {
|
|
204
|
+
...(typeof b['name'] === 'string' ? { name: b['name'] } : {}),
|
|
205
|
+
...(typeof b['id'] === 'string' ? { id: b['id'] } : {}),
|
|
206
|
+
...(b['arguments'] !== undefined ? { args: b['arguments'] } : {}),
|
|
207
|
+
...(b['input'] !== undefined ? { args: b['input'] } : {}),
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return undefined;
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=pi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi.js","sourceRoot":"","sources":["../../src/adapters/pi.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { AgentKind, SessionIR, SessionRef } from '../ir/types.js';
|
|
2
|
+
export interface ListOptions {
|
|
3
|
+
/** Restrict to sessions belonging to this project directory. */
|
|
4
|
+
project?: string;
|
|
5
|
+
/** Ignore the project filter and search every store. */
|
|
6
|
+
anyProject?: boolean;
|
|
7
|
+
/** Skip sessions whose transcript is larger than this, in bytes. */
|
|
8
|
+
maxBytes?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface Adapter {
|
|
11
|
+
kind: AgentKind;
|
|
12
|
+
label: string;
|
|
13
|
+
/** Where this adapter looks. Shown by `doctor`. */
|
|
14
|
+
store(): string;
|
|
15
|
+
/** True when the store exists on this machine. */
|
|
16
|
+
available(): boolean;
|
|
17
|
+
list(options: ListOptions): Promise<SessionRef[]>;
|
|
18
|
+
read(ref: SessionRef, options?: ReadOptions): Promise<SessionIR>;
|
|
19
|
+
}
|
|
20
|
+
export interface ReadOptions {
|
|
21
|
+
/** Include subagent transcripts. Off by default: they are not this session. */
|
|
22
|
+
includeSidechains?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Start after the provider's last compaction boundary. Off by default: the
|
|
25
|
+
* turns before a boundary are the record of what the human asked for, and the
|
|
26
|
+
* boundary is where the provider stopped *reading*, not where the work began.
|
|
27
|
+
*/
|
|
28
|
+
sinceCompact?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** Shared by adapters: read a file, tolerate a bad line, count the bad ones. */
|
|
31
|
+
export declare function readLines(path: string): Promise<string[]>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Shared by adapters: read a file, tolerate a bad line, count the bad ones. */
|
|
2
|
+
export async function readLines(path) {
|
|
3
|
+
const { readFile } = await import('node:fs/promises');
|
|
4
|
+
const text = await readFile(path, 'utf8');
|
|
5
|
+
return text.split('\n').filter((line) => line.trim().length > 0);
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAiCA,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY;IAC1C,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAA;IACrD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IACzC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AAClE,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `[evt a–b]` → the events behind it.
|
|
3
|
+
*
|
|
4
|
+
* The pointer is the artifact's only claim-checking mechanism, so this has to
|
|
5
|
+
* mean exactly one thing: the events in that inclusive range, in source order.
|
|
6
|
+
* A range is delivered in exact, non-overlapping pages rather than one
|
|
7
|
+
* unbounded dump, and every page says how to reach the next one — a window that
|
|
8
|
+
* has already shown you events 1–200 owes you a way to reach 201.
|
|
9
|
+
*/
|
|
10
|
+
import type { SessionIR } from '../ir/types.js';
|
|
11
|
+
export interface Page {
|
|
12
|
+
index: number;
|
|
13
|
+
tokens: number;
|
|
14
|
+
}
|
|
15
|
+
export interface ExpandOptions {
|
|
16
|
+
context?: number;
|
|
17
|
+
page?: Page;
|
|
18
|
+
}
|
|
19
|
+
export declare function expand(ir: SessionIR, ranges: Array<[number, number]>, options?: ExpandOptions): string;
|
|
20
|
+
/** Consecutive, non-overlapping pages. A single oversized event is its own page. */
|
|
21
|
+
export declare function paginate(messages: SessionIR['messages'], tokens: number): Array<SessionIR['messages']>;
|
|
22
|
+
/** Parse the `4122..4381`, `4122..=4381` and `4122` forms an artifact prints. */
|
|
23
|
+
export declare function parseRange(text: string): [number, number];
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export function expand(ir, ranges, options = {}) {
|
|
2
|
+
const out = [];
|
|
3
|
+
const context = options.context ?? 0;
|
|
4
|
+
for (const [from, to] of ranges) {
|
|
5
|
+
const start = Math.max(0, from - context);
|
|
6
|
+
const end = to + context;
|
|
7
|
+
const selected = ir.messages.filter((m) => m.eventIndex >= start && m.eventIndex <= end);
|
|
8
|
+
if (selected.length === 0) {
|
|
9
|
+
out.push(`=== evt ${start}–${end} ===\n(no events in this range)\n`);
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
if (!options.page) {
|
|
13
|
+
out.push(`=== evt ${start}–${end} ===\n${selected.map(renderEvent).join('\n')}\n`);
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
const pages = paginate(selected, options.page.tokens);
|
|
17
|
+
const index = Math.min(Math.max(1, options.page.index), pages.length);
|
|
18
|
+
const slice = pages[index - 1];
|
|
19
|
+
out.push(`=== evt ${start}–${end} · page ${index}/${pages.length} · evt ${slice[0].eventIndex}–${slice.at(-1).eventIndex} · ${slice.reduce((n, m) => n + Math.ceil((m.text?.length ?? 0) / 4), 0)} token(s) ===`);
|
|
20
|
+
out.push(slice.map(renderEvent).join('\n'));
|
|
21
|
+
if (pages.length > 1) {
|
|
22
|
+
const next = index === pages.length ? 1 : index + 1;
|
|
23
|
+
out.push(`\n--- page ${index} of ${pages.length}; page ${next} is \`ccompactor expand <ref> ${from}..${to} --page ${next}\` ---`);
|
|
24
|
+
}
|
|
25
|
+
out.push('');
|
|
26
|
+
}
|
|
27
|
+
return out.join('\n');
|
|
28
|
+
}
|
|
29
|
+
/** Consecutive, non-overlapping pages. A single oversized event is its own page. */
|
|
30
|
+
export function paginate(messages, tokens) {
|
|
31
|
+
const pages = [];
|
|
32
|
+
let current = [];
|
|
33
|
+
let used = 0;
|
|
34
|
+
for (const message of messages) {
|
|
35
|
+
const cost = Math.ceil((message.text?.length ?? 0) / 4);
|
|
36
|
+
if (current.length > 0 && used + cost > tokens) {
|
|
37
|
+
pages.push(current);
|
|
38
|
+
current = [];
|
|
39
|
+
used = 0;
|
|
40
|
+
}
|
|
41
|
+
current.push(message);
|
|
42
|
+
used += cost;
|
|
43
|
+
}
|
|
44
|
+
if (current.length > 0)
|
|
45
|
+
pages.push(current);
|
|
46
|
+
return pages.length > 0 ? pages : [[]];
|
|
47
|
+
}
|
|
48
|
+
function renderEvent(message) {
|
|
49
|
+
const role = message.isHumanTurn ? 'user' : message.role;
|
|
50
|
+
const tag = message.toolName ? `${role}·${message.toolName}` : role;
|
|
51
|
+
const body = message.text ?? (message.toolInput ? JSON.stringify(message.toolInput) : '');
|
|
52
|
+
return `evt ${message.eventIndex} [${tag}] ${body.replace(/\s+/g, ' ').slice(0, 2_000)}`;
|
|
53
|
+
}
|
|
54
|
+
/** Parse the `4122..4381`, `4122..=4381` and `4122` forms an artifact prints. */
|
|
55
|
+
export function parseRange(text) {
|
|
56
|
+
const trimmed = text.trim();
|
|
57
|
+
const match = /^(\d+)\s*\.\.\s*=?\s*(\d+)$/.exec(trimmed);
|
|
58
|
+
if (match) {
|
|
59
|
+
const from = Number.parseInt(match[1], 10);
|
|
60
|
+
const to = Number.parseInt(match[2], 10);
|
|
61
|
+
if (to < from)
|
|
62
|
+
throw new Error(`range \`${text}\` runs backwards`);
|
|
63
|
+
return [from, to];
|
|
64
|
+
}
|
|
65
|
+
if (/^\d+$/.test(trimmed)) {
|
|
66
|
+
const value = Number.parseInt(trimmed, 10);
|
|
67
|
+
return [value, value];
|
|
68
|
+
}
|
|
69
|
+
throw new Error(`\`${text}\` is not a range (expected \`4122..4381\` or \`4122\`)`);
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=expand.js.map
|