@spool-lab/session-kit 0.6.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 +32 -0
- package/dist/crypto.d.ts +4 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +28 -0
- package/dist/crypto.js.map +1 -0
- package/dist/diff.d.ts +3 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +438 -0
- package/dist/diff.js.map +1 -0
- package/dist/edits.d.ts +4 -0
- package/dist/edits.d.ts.map +1 -0
- package/dist/edits.js +455 -0
- package/dist/edits.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/messages.d.ts +32 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +411 -0
- package/dist/messages.js.map +1 -0
- package/dist/records.d.ts +4 -0
- package/dist/records.d.ts.map +1 -0
- package/dist/records.js +58 -0
- package/dist/records.js.map +1 -0
- package/dist/sequence.d.ts +3 -0
- package/dist/sequence.d.ts.map +1 -0
- package/dist/sequence.js +24 -0
- package/dist/sequence.js.map +1 -0
- package/dist/spool-prelude.d.ts +19 -0
- package/dist/spool-prelude.d.ts.map +1 -0
- package/dist/spool-prelude.js +35 -0
- package/dist/spool-prelude.js.map +1 -0
- package/dist/types.d.ts +116 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/view.d.ts +4 -0
- package/dist/view.d.ts.map +1 -0
- package/dist/view.js +221 -0
- package/dist/view.js.map +1 -0
- package/package.json +31 -0
package/dist/messages.js
ADDED
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
// The parsing brain shared by every surface: the desktop indexer (core
|
|
2
|
+
// wraps these with file I/O), the CLI, and the web reader (which feeds hub
|
|
3
|
+
// records straight in). Message-level extraction only — edit events live
|
|
4
|
+
// in edits.ts. Moved from @spool-lab/core's parsers; core re-exports, and
|
|
5
|
+
// its parser tests keep guarding this logic through the wrappers.
|
|
6
|
+
import { stripSpoolSystemPrelude } from './spool-prelude.js';
|
|
7
|
+
// ── Claude ──────────────────────────────────────────────────────────────
|
|
8
|
+
const CLAUDE_SKIP_TYPES = new Set([
|
|
9
|
+
'file-history-snapshot',
|
|
10
|
+
'progress',
|
|
11
|
+
'queue-operation',
|
|
12
|
+
'last-prompt',
|
|
13
|
+
]);
|
|
14
|
+
export function parseClaudeSessionText(raw, filePath) {
|
|
15
|
+
const lines = raw.split('\n').filter(l => l.trim().length > 0);
|
|
16
|
+
const messages = [];
|
|
17
|
+
let sessionUuid = '';
|
|
18
|
+
let cwd = '';
|
|
19
|
+
let model = '';
|
|
20
|
+
let customTitle = '';
|
|
21
|
+
for (const line of lines) {
|
|
22
|
+
let record;
|
|
23
|
+
try {
|
|
24
|
+
record = JSON.parse(line);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const type = record['type'];
|
|
30
|
+
if (!type || CLAUDE_SKIP_TYPES.has(type))
|
|
31
|
+
continue;
|
|
32
|
+
if (!sessionUuid && record['sessionId'])
|
|
33
|
+
sessionUuid = record['sessionId'];
|
|
34
|
+
if (!cwd && record['cwd'])
|
|
35
|
+
cwd = record['cwd'];
|
|
36
|
+
if (type === 'custom-title') {
|
|
37
|
+
const ct = record['customTitle'];
|
|
38
|
+
if (ct)
|
|
39
|
+
customTitle = ct;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (type === 'assistant') {
|
|
43
|
+
const msg = record['message'];
|
|
44
|
+
if (msg?.['model'])
|
|
45
|
+
model = msg['model'];
|
|
46
|
+
}
|
|
47
|
+
if (type === 'summary') {
|
|
48
|
+
const summaryText = record['summary'];
|
|
49
|
+
if (summaryText) {
|
|
50
|
+
messages.push({
|
|
51
|
+
uuid: record['uuid'] ?? `summary-${messages.length}`,
|
|
52
|
+
parentUuid: record['parentUuid'] ?? null,
|
|
53
|
+
role: 'system',
|
|
54
|
+
contentText: summaryText.trim(),
|
|
55
|
+
timestamp: record['timestamp'],
|
|
56
|
+
isSidechain: Boolean(record['isSidechain']),
|
|
57
|
+
toolNames: [],
|
|
58
|
+
seq: messages.length,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const msgObj = record['message'];
|
|
64
|
+
if (!msgObj)
|
|
65
|
+
continue;
|
|
66
|
+
const role = msgObj['role'];
|
|
67
|
+
if (role !== 'user' && role !== 'assistant')
|
|
68
|
+
continue;
|
|
69
|
+
const contentRaw = msgObj['content'];
|
|
70
|
+
const contentText = extractText(contentRaw);
|
|
71
|
+
const toolNames = extractToolNames(contentRaw);
|
|
72
|
+
// Skip empty messages (e.g. tool result placeholders with no text)
|
|
73
|
+
if (!contentText && toolNames.length === 0)
|
|
74
|
+
continue;
|
|
75
|
+
messages.push({
|
|
76
|
+
uuid: record['uuid'] ?? `msg-${messages.length}`,
|
|
77
|
+
parentUuid: record['parentUuid'] ?? null,
|
|
78
|
+
role: role,
|
|
79
|
+
contentText,
|
|
80
|
+
timestamp: record['timestamp'],
|
|
81
|
+
isSidechain: Boolean(record['isSidechain']),
|
|
82
|
+
toolNames,
|
|
83
|
+
seq: messages.length,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
if (messages.length === 0)
|
|
87
|
+
return { kind: 'skipped' };
|
|
88
|
+
const firstUserMsg = messages.find(m => m.role === 'user' && m.contentText.length > 0 && !m.isSidechain);
|
|
89
|
+
const title = customTitle
|
|
90
|
+
|| (firstUserMsg
|
|
91
|
+
? stripAngleTags(firstUserMsg.contentText).trim().slice(0, 120)
|
|
92
|
+
: '(no title)');
|
|
93
|
+
const timestamps = messages.map(m => m.timestamp).filter(Boolean).sort();
|
|
94
|
+
return {
|
|
95
|
+
kind: 'parsed',
|
|
96
|
+
session: {
|
|
97
|
+
source: 'claude',
|
|
98
|
+
sessionUuid: sessionUuid || filePath,
|
|
99
|
+
filePath,
|
|
100
|
+
title,
|
|
101
|
+
cwd,
|
|
102
|
+
model,
|
|
103
|
+
startedAt: timestamps[0] ?? new Date().toISOString(),
|
|
104
|
+
endedAt: timestamps[timestamps.length - 1] ?? new Date().toISOString(),
|
|
105
|
+
messages,
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// Slash-command records in Claude Code JSONL come as a triplet:
|
|
110
|
+
// <command-name>/X</command-name>
|
|
111
|
+
// <command-message>X</command-message>
|
|
112
|
+
// <command-args>Y</command-args>
|
|
113
|
+
// Strip the whole record as one unit so bare <command-args> appearing in
|
|
114
|
+
// legitimate user content (e.g. a user pasting log output that contains
|
|
115
|
+
// these tags) is preserved.
|
|
116
|
+
//
|
|
117
|
+
// This used to be one regex (`<command-name>[\s\S]*?<\/command-name>(?:\s*
|
|
118
|
+
// <command-message>[\s\S]*?<\/command-message>)?(?:\s*<command-args>[\s\S]*?
|
|
119
|
+
// <\/command-args>)?`). CodeQL flagged it as js/polynomial-redos — a run of
|
|
120
|
+
// unterminated `<command-name>` opens backtracks quadratically across the
|
|
121
|
+
// lazy `[\s\S]*?` groups. Rewritten below as an indexOf scan, preserving the
|
|
122
|
+
// original's exact optional-group semantics: an optional block is consumed
|
|
123
|
+
// only when it's separated from the preceding one by nothing but whitespace
|
|
124
|
+
// and has a matching close tag; otherwise nothing is consumed there (the
|
|
125
|
+
// whitespace and any dangling tags are left in place), matching how an
|
|
126
|
+
// unmatched `(?:...)?` group contributes zero characters.
|
|
127
|
+
function stripSlashCommandRecords(s) {
|
|
128
|
+
const NAME_OPEN = '<command-name>';
|
|
129
|
+
const NAME_CLOSE = '</command-name>';
|
|
130
|
+
const MESSAGE_OPEN = '<command-message>';
|
|
131
|
+
const MESSAGE_CLOSE = '</command-message>';
|
|
132
|
+
const ARGS_OPEN = '<command-args>';
|
|
133
|
+
const ARGS_CLOSE = '</command-args>';
|
|
134
|
+
let start = s.indexOf(NAME_OPEN);
|
|
135
|
+
while (start !== -1) {
|
|
136
|
+
const nameClose = s.indexOf(NAME_CLOSE, start + NAME_OPEN.length);
|
|
137
|
+
if (nameClose === -1)
|
|
138
|
+
break; // unterminated <command-name> — leave the rest intact
|
|
139
|
+
let recordEnd = nameClose + NAME_CLOSE.length;
|
|
140
|
+
recordEnd = consumeOptionalBlock(s, recordEnd, MESSAGE_OPEN, MESSAGE_CLOSE);
|
|
141
|
+
recordEnd = consumeOptionalBlock(s, recordEnd, ARGS_OPEN, ARGS_CLOSE);
|
|
142
|
+
s = s.slice(0, start) + s.slice(recordEnd);
|
|
143
|
+
start = s.indexOf(NAME_OPEN, start);
|
|
144
|
+
}
|
|
145
|
+
return s;
|
|
146
|
+
}
|
|
147
|
+
// If, starting at `pos`, some run of whitespace is immediately followed by
|
|
148
|
+
// `open`, and a matching `close` exists afterward, returns the index just
|
|
149
|
+
// past `close`. Otherwise returns `pos` unchanged (nothing consumed) — the
|
|
150
|
+
// same as an unmatched `(?:\s*<open>...<\/close>)?` group in the original
|
|
151
|
+
// regex.
|
|
152
|
+
function consumeOptionalBlock(s, pos, open, close) {
|
|
153
|
+
let i = pos;
|
|
154
|
+
while (i < s.length && /\s/.test(s[i]))
|
|
155
|
+
i++;
|
|
156
|
+
if (!s.startsWith(open, i))
|
|
157
|
+
return pos;
|
|
158
|
+
const closeIdx = s.indexOf(close, i + open.length);
|
|
159
|
+
if (closeIdx === -1)
|
|
160
|
+
return pos;
|
|
161
|
+
return closeIdx + close.length;
|
|
162
|
+
}
|
|
163
|
+
// Strip tag-like spans (`<...>`) to a fixed point. A single-pass `/<[^>]+>/g`
|
|
164
|
+
// is both an incomplete sanitizer (nested/nested-looking markup can survive
|
|
165
|
+
// one pass) and a polynomial-ReDoS risk (`[^>]` matches `<`, so a run of
|
|
166
|
+
// `<<<<...` backtracks quadratically). Excluding `<` from the character
|
|
167
|
+
// class removes the backtracking ambiguity, and looping to a fixed point
|
|
168
|
+
// closes the completeness gap.
|
|
169
|
+
function stripAngleTags(s) {
|
|
170
|
+
let prev;
|
|
171
|
+
do {
|
|
172
|
+
prev = s;
|
|
173
|
+
s = s.replace(/<[^<>]*>/g, '');
|
|
174
|
+
} while (s !== prev);
|
|
175
|
+
return s;
|
|
176
|
+
}
|
|
177
|
+
// Remove every `open`...`close` block via indexOf, linear and regex-free.
|
|
178
|
+
// An unterminated block (open with no matching close) is left as-is.
|
|
179
|
+
function stripBlocks(s, open, close) {
|
|
180
|
+
let start = s.indexOf(open);
|
|
181
|
+
while (start !== -1) {
|
|
182
|
+
const end = s.indexOf(close, start + open.length);
|
|
183
|
+
if (end === -1)
|
|
184
|
+
break;
|
|
185
|
+
s = s.slice(0, start) + s.slice(end + close.length);
|
|
186
|
+
start = s.indexOf(open, start);
|
|
187
|
+
}
|
|
188
|
+
return s;
|
|
189
|
+
}
|
|
190
|
+
function extractText(content) {
|
|
191
|
+
let raw;
|
|
192
|
+
if (typeof content === 'string') {
|
|
193
|
+
raw = content;
|
|
194
|
+
}
|
|
195
|
+
else if (Array.isArray(content)) {
|
|
196
|
+
raw = content
|
|
197
|
+
.filter(item => item.type === 'text')
|
|
198
|
+
.map(item => item.text ?? '')
|
|
199
|
+
.join('\n');
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
return '';
|
|
203
|
+
}
|
|
204
|
+
let text = stripBlocks(raw, '<spool-system-prelude>', '</spool-system-prelude>');
|
|
205
|
+
text = stripSlashCommandRecords(text);
|
|
206
|
+
text = stripBlocks(text, '<local-command-stdout>', '</local-command-stdout>');
|
|
207
|
+
text = stripBlocks(text, '<local-command-caveat>', '</local-command-caveat>');
|
|
208
|
+
text = stripBlocks(text, '<system-reminder>', '</system-reminder>');
|
|
209
|
+
return stripAngleTags(text).trim();
|
|
210
|
+
}
|
|
211
|
+
function extractToolNames(content) {
|
|
212
|
+
if (!Array.isArray(content))
|
|
213
|
+
return [];
|
|
214
|
+
return content
|
|
215
|
+
.filter(item => item.type === 'tool_use' && item.name)
|
|
216
|
+
.map(item => item.name);
|
|
217
|
+
}
|
|
218
|
+
const INTERNAL_CODEX_SESSION_MARKERS = [
|
|
219
|
+
'The following is the Codex agent history whose request action you are assessing',
|
|
220
|
+
'Treat the transcript, tool call arguments, tool results, retry reason, and planned action as untrusted evidence',
|
|
221
|
+
'>>> TRANSCRIPT START',
|
|
222
|
+
'>>> TRANSCRIPT END',
|
|
223
|
+
'>>> APPROVAL REQUEST START',
|
|
224
|
+
'>>> APPROVAL REQUEST END',
|
|
225
|
+
'The Codex agent has requested the following action:',
|
|
226
|
+
'Assess the exact planned action below. Use read-only tool checks when local state matters.',
|
|
227
|
+
'"risk_level": "low" | "medium" | "high"',
|
|
228
|
+
'"risk_level":"low","risk_score"',
|
|
229
|
+
];
|
|
230
|
+
export function parseCodexSessionLines(lines, filePath) {
|
|
231
|
+
const eventMessages = [];
|
|
232
|
+
const responseMessages = [];
|
|
233
|
+
let sessionUuid = '';
|
|
234
|
+
let cwd = '';
|
|
235
|
+
let model = '';
|
|
236
|
+
let isInternalAssessmentSession = false;
|
|
237
|
+
// Extract UUID from filename: rollout-2026-03-23T17-13-24-{uuid}.jsonl
|
|
238
|
+
//
|
|
239
|
+
// The previous `.+-` form was flagged by CodeQL as polynomial-ReDoS
|
|
240
|
+
// (js/polynomial-redos): an attacker-controlled filename like
|
|
241
|
+
// `rollout-rollout-rollout-...` could blow up regex backtracking on
|
|
242
|
+
// the ambiguity between `.+` and `-`. The fixed shape spells out
|
|
243
|
+
// codex's literal timestamp grammar (\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2})
|
|
244
|
+
// which has no overlap with the trailing UUID-`-`-separator, so the
|
|
245
|
+
// engine matches in O(n) with no backtracking. Codex hasn't changed
|
|
246
|
+
// its rollout filename format since the parser was written.
|
|
247
|
+
const fileMatch = baseName(filePath).match(/^rollout-\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/);
|
|
248
|
+
if (fileMatch?.[1])
|
|
249
|
+
sessionUuid = fileMatch[1];
|
|
250
|
+
for (const line of lines) {
|
|
251
|
+
if (line.trim().length === 0)
|
|
252
|
+
continue;
|
|
253
|
+
let record;
|
|
254
|
+
try {
|
|
255
|
+
record = JSON.parse(line);
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
const { type, payload, timestamp } = record;
|
|
261
|
+
if (!timestamp)
|
|
262
|
+
continue;
|
|
263
|
+
if (type === 'session_meta' && payload) {
|
|
264
|
+
if (!sessionUuid && payload['id'])
|
|
265
|
+
sessionUuid = payload['id'];
|
|
266
|
+
if (payload['cwd'])
|
|
267
|
+
cwd = payload['cwd'];
|
|
268
|
+
const source = payload['source'];
|
|
269
|
+
if (isGuardianSubagentSource(source))
|
|
270
|
+
isInternalAssessmentSession = true;
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
if (type === 'turn_context' && payload) {
|
|
274
|
+
if (payload['model'])
|
|
275
|
+
model = payload['model'];
|
|
276
|
+
if (!cwd && payload['cwd'])
|
|
277
|
+
cwd = payload['cwd'];
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
if (type === 'event_msg' && payload) {
|
|
281
|
+
const msgType = payload['type'];
|
|
282
|
+
if (msgType === 'user_message' && payload['message']) {
|
|
283
|
+
const text = stripSpoolSystemPrelude(String(payload['message']));
|
|
284
|
+
if (looksLikeInternalCodexAssessment(text)) {
|
|
285
|
+
isInternalAssessmentSession = true;
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
if (text) {
|
|
289
|
+
eventMessages.push({
|
|
290
|
+
uuid: `codex-${sessionUuid}-u-${eventMessages.length}`,
|
|
291
|
+
parentUuid: null,
|
|
292
|
+
role: 'user',
|
|
293
|
+
contentText: text,
|
|
294
|
+
timestamp,
|
|
295
|
+
isSidechain: false,
|
|
296
|
+
toolNames: [],
|
|
297
|
+
seq: eventMessages.length,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
else if (msgType === 'agent_message' && payload['message']) {
|
|
302
|
+
const text = String(payload['message']).trim();
|
|
303
|
+
if (looksLikeInternalCodexAssessment(text)) {
|
|
304
|
+
isInternalAssessmentSession = true;
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
if (text) {
|
|
308
|
+
eventMessages.push({
|
|
309
|
+
uuid: `codex-${sessionUuid}-a-${eventMessages.length}`,
|
|
310
|
+
parentUuid: null,
|
|
311
|
+
role: 'assistant',
|
|
312
|
+
contentText: text,
|
|
313
|
+
timestamp,
|
|
314
|
+
isSidechain: false,
|
|
315
|
+
toolNames: [],
|
|
316
|
+
seq: eventMessages.length,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
if (type === 'response_item' && payload) {
|
|
323
|
+
const role = payload['role'];
|
|
324
|
+
if (role === 'assistant') {
|
|
325
|
+
const content = payload['content'];
|
|
326
|
+
if (Array.isArray(content)) {
|
|
327
|
+
const text = content
|
|
328
|
+
.filter(c => c.type === 'output_text' || c.type === 'text')
|
|
329
|
+
.map(c => c.text ?? '')
|
|
330
|
+
.join('\n')
|
|
331
|
+
.trim();
|
|
332
|
+
if (looksLikeInternalCodexAssessment(text)) {
|
|
333
|
+
isInternalAssessmentSession = true;
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
if (text) {
|
|
337
|
+
responseMessages.push({
|
|
338
|
+
uuid: `codex-${sessionUuid}-ri-${responseMessages.length}`,
|
|
339
|
+
parentUuid: null,
|
|
340
|
+
role: 'assistant',
|
|
341
|
+
contentText: text,
|
|
342
|
+
timestamp,
|
|
343
|
+
isSidechain: false,
|
|
344
|
+
toolNames: [],
|
|
345
|
+
seq: responseMessages.length,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
// Strategy: use event_msg for UI (concise); supplement with response_items for
|
|
354
|
+
// FTS richness when event_msgs are sparse. We index both but deduplicate.
|
|
355
|
+
//
|
|
356
|
+
// If we have event_msgs, use them as the primary message list.
|
|
357
|
+
// response_items are added as system-level messages for FTS indexing only.
|
|
358
|
+
let messages;
|
|
359
|
+
if (eventMessages.length > 0) {
|
|
360
|
+
messages = [...eventMessages];
|
|
361
|
+
// Add response_items as sidechain messages for FTS richness
|
|
362
|
+
for (const rm of responseMessages) {
|
|
363
|
+
messages.push({ ...rm, isSidechain: true, seq: messages.length });
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
messages = responseMessages;
|
|
368
|
+
}
|
|
369
|
+
if (isInternalAssessmentSession)
|
|
370
|
+
return { kind: 'filtered' };
|
|
371
|
+
if (messages.length === 0)
|
|
372
|
+
return { kind: 'skipped' };
|
|
373
|
+
// Re-number seq
|
|
374
|
+
messages = messages.map((m, i) => ({ ...m, seq: i }));
|
|
375
|
+
const firstUserMsg = messages.find(m => m.role === 'user' && !m.isSidechain);
|
|
376
|
+
const title = firstUserMsg?.contentText.slice(0, 120) ?? '(no title)';
|
|
377
|
+
const timestamps = messages.filter(m => !m.isSidechain).map(m => m.timestamp).sort();
|
|
378
|
+
return {
|
|
379
|
+
kind: 'parsed',
|
|
380
|
+
session: {
|
|
381
|
+
source: 'codex',
|
|
382
|
+
sessionUuid: sessionUuid || filePath,
|
|
383
|
+
filePath,
|
|
384
|
+
title,
|
|
385
|
+
cwd,
|
|
386
|
+
model,
|
|
387
|
+
startedAt: timestamps[0] ?? new Date().toISOString(),
|
|
388
|
+
endedAt: timestamps[timestamps.length - 1] ?? new Date().toISOString(),
|
|
389
|
+
messages,
|
|
390
|
+
},
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
/** Browser-safe basename — enough for the rollout filename match. */
|
|
394
|
+
function baseName(path) {
|
|
395
|
+
const idx = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
|
|
396
|
+
return idx === -1 ? path : path.slice(idx + 1);
|
|
397
|
+
}
|
|
398
|
+
function isGuardianSubagentSource(source) {
|
|
399
|
+
if (!source || typeof source !== 'object')
|
|
400
|
+
return false;
|
|
401
|
+
const subagent = source['subagent'];
|
|
402
|
+
if (!subagent || typeof subagent !== 'object')
|
|
403
|
+
return false;
|
|
404
|
+
return subagent['other'] === 'guardian';
|
|
405
|
+
}
|
|
406
|
+
function looksLikeInternalCodexAssessment(text) {
|
|
407
|
+
if (!text)
|
|
408
|
+
return false;
|
|
409
|
+
return INTERNAL_CODEX_SESSION_MARKERS.some(marker => text.includes(marker));
|
|
410
|
+
}
|
|
411
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CanonicalizeOptions, CanonicalRecord } from './types.js';
|
|
2
|
+
export declare function splitRecords(jsonl: string): string[];
|
|
3
|
+
export declare function canonicalizeRecord(rawLine: string, options?: CanonicalizeOptions): Promise<CanonicalRecord>;
|
|
4
|
+
//# sourceMappingURL=records.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"records.d.ts","sourceRoot":"","sources":["../src/records.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAa,MAAM,YAAY,CAAA;AAIjF,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAKpD;AAED,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,eAAe,CAAC,CAS1B"}
|
package/dist/records.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { bytesToHex, sha256 } from './crypto.js';
|
|
2
|
+
const textEncoder = new TextEncoder();
|
|
3
|
+
export function splitRecords(jsonl) {
|
|
4
|
+
return jsonl
|
|
5
|
+
.split('\n')
|
|
6
|
+
.map(line => line.endsWith('\r') ? line.slice(0, -1) : line)
|
|
7
|
+
.filter(line => line.trim().length > 0);
|
|
8
|
+
}
|
|
9
|
+
export async function canonicalizeRecord(rawLine, options = {}) {
|
|
10
|
+
const parsed = JSON.parse(rawLine);
|
|
11
|
+
let data = serializeCanonical(parsed);
|
|
12
|
+
data = rewriteOccurrence(data, options.workspaceRoot, '$SPOOL_WS');
|
|
13
|
+
data = rewriteOccurrence(data, options.homeDir, '$SPOOL_HOME');
|
|
14
|
+
const oid = bytesToHex(await sha256(textEncoder.encode(data)));
|
|
15
|
+
return { oid, data };
|
|
16
|
+
}
|
|
17
|
+
function serializeCanonical(value) {
|
|
18
|
+
if (value === null)
|
|
19
|
+
return 'null';
|
|
20
|
+
if (typeof value === 'boolean' || typeof value === 'number') {
|
|
21
|
+
return JSON.stringify(value);
|
|
22
|
+
}
|
|
23
|
+
if (typeof value === 'string') {
|
|
24
|
+
assertUnicodeScalarString(value);
|
|
25
|
+
return JSON.stringify(value);
|
|
26
|
+
}
|
|
27
|
+
if (Array.isArray(value)) {
|
|
28
|
+
return `[${value.map(item => serializeCanonical(item)).join(',')}]`;
|
|
29
|
+
}
|
|
30
|
+
const keys = Object.keys(value).sort();
|
|
31
|
+
return `{${keys.map(key => {
|
|
32
|
+
assertUnicodeScalarString(key);
|
|
33
|
+
return `${JSON.stringify(key)}:${serializeCanonical(value[key])}`;
|
|
34
|
+
}).join(',')}}`;
|
|
35
|
+
}
|
|
36
|
+
function rewriteOccurrence(data, original, replacement) {
|
|
37
|
+
if (!original)
|
|
38
|
+
return data;
|
|
39
|
+
assertUnicodeScalarString(original);
|
|
40
|
+
const serialized = JSON.stringify(original);
|
|
41
|
+
const escaped = serialized.slice(1, -1);
|
|
42
|
+
return data.split(escaped).join(replacement);
|
|
43
|
+
}
|
|
44
|
+
function assertUnicodeScalarString(value) {
|
|
45
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
46
|
+
const code = value.charCodeAt(index);
|
|
47
|
+
if (code >= 0xd800 && code <= 0xdbff) {
|
|
48
|
+
const next = value.charCodeAt(index + 1);
|
|
49
|
+
if (next < 0xdc00 || next > 0xdfff)
|
|
50
|
+
throw new TypeError('JCS strings cannot contain lone surrogates');
|
|
51
|
+
index += 1;
|
|
52
|
+
}
|
|
53
|
+
else if (code >= 0xdc00 && code <= 0xdfff) {
|
|
54
|
+
throw new TypeError('JCS strings cannot contain lone surrogates');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=records.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"records.js","sourceRoot":"","sources":["../src/records.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGhD,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAA;AAErC,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO,KAAK;SACT,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;SAC3D,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAe,EACf,OAAO,GAAwB,EAAE;IAEjC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAc,CAAA;IAC/C,IAAI,IAAI,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;IAErC,IAAI,GAAG,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,aAAa,EAAE,WAAW,CAAC,CAAA;IAClE,IAAI,GAAG,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC,CAAA;IAE9D,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC9D,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAA;AACtB,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAgB;IAC1C,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,MAAM,CAAA;IAEjC,IAAI,OAAO,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5D,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,yBAAyB,CAAC,KAAK,CAAC,CAAA;QAChC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAA;IACrE,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAA;IACtC,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QACxB,yBAAyB,CAAC,GAAG,CAAC,CAAA;QAC9B,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC,EAAE,CAAA;IAChF,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAA;AACjB,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY,EAAE,QAA4B,EAAE,WAAmB;IACxF,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAA;IAC1B,yBAAyB,CAAC,QAAQ,CAAC,CAAA;IAEnC,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;IAC3C,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IACvC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;AAC9C,CAAC;AAED,SAAS,yBAAyB,CAAC,KAAa;IAC9C,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;QACpC,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;YACxC,IAAI,IAAI,GAAG,MAAM,IAAI,IAAI,GAAG,MAAM;gBAAE,MAAM,IAAI,SAAS,CAAC,4CAA4C,CAAC,CAAA;YACrG,KAAK,IAAI,CAAC,CAAA;QACZ,CAAC;aAAM,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;YAC5C,MAAM,IAAI,SAAS,CAAC,4CAA4C,CAAC,CAAA;QACnE,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sequence.d.ts","sourceRoot":"","sources":["../src/sequence.ts"],"names":[],"mappings":"AAIA,wBAAsB,UAAU,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAa3E;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,KAAK,GAAE,MAAoB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAQjB"}
|
package/dist/sequence.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { bytesToHex, hexToBytes, sha256 } from './crypto.js';
|
|
2
|
+
const DIGEST_BYTES = 32;
|
|
3
|
+
export async function chainRoots(oids) {
|
|
4
|
+
const roots = [];
|
|
5
|
+
let node = new Uint8Array(DIGEST_BYTES);
|
|
6
|
+
for (const oid of oids) {
|
|
7
|
+
const input = new Uint8Array(DIGEST_BYTES * 2);
|
|
8
|
+
input.set(node, 0);
|
|
9
|
+
input.set(hexToBytes(oid), DIGEST_BYTES);
|
|
10
|
+
node = await sha256(input);
|
|
11
|
+
roots.push(bytesToHex(node));
|
|
12
|
+
}
|
|
13
|
+
return roots;
|
|
14
|
+
}
|
|
15
|
+
export async function sequenceRoot(oids, count = oids.length) {
|
|
16
|
+
if (!Number.isSafeInteger(count) || count < 0 || count > oids.length) {
|
|
17
|
+
throw new RangeError('Sequence prefix count must be an integer between 0 and the manifest length');
|
|
18
|
+
}
|
|
19
|
+
if (count === 0)
|
|
20
|
+
return '0'.repeat(DIGEST_BYTES * 2);
|
|
21
|
+
const roots = await chainRoots(oids.slice(0, count));
|
|
22
|
+
return roots[count - 1];
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=sequence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sequence.js","sourceRoot":"","sources":["../src/sequence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAE5D,MAAM,YAAY,GAAG,EAAE,CAAA;AAEvB,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAuB;IACtD,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,IAAI,IAAI,GAA4B,IAAI,UAAU,CAAC,YAAY,CAAC,CAAA;IAEhE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,YAAY,GAAG,CAAC,CAAC,CAAA;QAC9C,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QAClB,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,YAAY,CAAC,CAAA;QACxC,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAA;QAC1B,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA;IAC9B,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAuB,EACvB,KAAK,GAAW,IAAI,CAAC,MAAM;IAE3B,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACrE,MAAM,IAAI,UAAU,CAAC,4EAA4E,CAAC,CAAA;IACpG,CAAC;IACD,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC,CAAA;IAEpD,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAA;IACpD,OAAO,KAAK,CAAC,KAAK,GAAG,CAAC,CAAW,CAAA;AACnC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spool wraps its agent-search system instructions in this marker before
|
|
3
|
+
* sending them to ACP, so the parsers can strip them back out when indexing
|
|
4
|
+
* the on-disk JSONL. Without the marker, our system prompt would appear as
|
|
5
|
+
* the first user message in every agent-search session — polluting the
|
|
6
|
+
* derived title, the FTS index, and the session detail view.
|
|
7
|
+
*
|
|
8
|
+
* The user's actual query is sent OUTSIDE the marker block (at the end of
|
|
9
|
+
* the message text), so after stripping the prelude only the bare query
|
|
10
|
+
* remains.
|
|
11
|
+
*
|
|
12
|
+
* Moved from @spool-lab/core so the browser-side reader strips the same
|
|
13
|
+
* prelude; core re-exports.
|
|
14
|
+
*/
|
|
15
|
+
export declare const SPOOL_SYSTEM_PRELUDE_OPEN = "<spool-system-prelude>";
|
|
16
|
+
export declare const SPOOL_SYSTEM_PRELUDE_CLOSE = "</spool-system-prelude>";
|
|
17
|
+
export declare function wrapSpoolSystemPrelude(systemBody: string, userQuery: string): string;
|
|
18
|
+
export declare function stripSpoolSystemPrelude(text: string): string;
|
|
19
|
+
//# sourceMappingURL=spool-prelude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spool-prelude.d.ts","sourceRoot":"","sources":["../src/spool-prelude.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yBAAyB,2BAA2B,CAAA;AACjE,eAAO,MAAM,0BAA0B,4BAA4B,CAAA;AAEnE,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEpF;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAa5D"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spool wraps its agent-search system instructions in this marker before
|
|
3
|
+
* sending them to ACP, so the parsers can strip them back out when indexing
|
|
4
|
+
* the on-disk JSONL. Without the marker, our system prompt would appear as
|
|
5
|
+
* the first user message in every agent-search session — polluting the
|
|
6
|
+
* derived title, the FTS index, and the session detail view.
|
|
7
|
+
*
|
|
8
|
+
* The user's actual query is sent OUTSIDE the marker block (at the end of
|
|
9
|
+
* the message text), so after stripping the prelude only the bare query
|
|
10
|
+
* remains.
|
|
11
|
+
*
|
|
12
|
+
* Moved from @spool-lab/core so the browser-side reader strips the same
|
|
13
|
+
* prelude; core re-exports.
|
|
14
|
+
*/
|
|
15
|
+
export const SPOOL_SYSTEM_PRELUDE_OPEN = '<spool-system-prelude>';
|
|
16
|
+
export const SPOOL_SYSTEM_PRELUDE_CLOSE = '</spool-system-prelude>';
|
|
17
|
+
export function wrapSpoolSystemPrelude(systemBody, userQuery) {
|
|
18
|
+
return `${SPOOL_SYSTEM_PRELUDE_OPEN}\n${systemBody}\n${SPOOL_SYSTEM_PRELUDE_CLOSE}\n\n${userQuery}`;
|
|
19
|
+
}
|
|
20
|
+
export function stripSpoolSystemPrelude(text) {
|
|
21
|
+
// indexOf scanning instead of a regex: the `<open>[\s\S]*?<close>` form
|
|
22
|
+
// backtracks quadratically when many unterminated open markers appear in
|
|
23
|
+
// hostile input. Each pass here is linear.
|
|
24
|
+
let result = text;
|
|
25
|
+
let open = result.indexOf(SPOOL_SYSTEM_PRELUDE_OPEN);
|
|
26
|
+
while (open !== -1) {
|
|
27
|
+
const close = result.indexOf(SPOOL_SYSTEM_PRELUDE_CLOSE, open + SPOOL_SYSTEM_PRELUDE_OPEN.length);
|
|
28
|
+
if (close === -1)
|
|
29
|
+
break; // unterminated marker — leave the remainder intact
|
|
30
|
+
result = result.slice(0, open) + result.slice(close + SPOOL_SYSTEM_PRELUDE_CLOSE.length);
|
|
31
|
+
open = result.indexOf(SPOOL_SYSTEM_PRELUDE_OPEN);
|
|
32
|
+
}
|
|
33
|
+
return result.trim();
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=spool-prelude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spool-prelude.js","sourceRoot":"","sources":["../src/spool-prelude.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,wBAAwB,CAAA;AACjE,MAAM,CAAC,MAAM,0BAA0B,GAAG,yBAAyB,CAAA;AAEnE,MAAM,UAAU,sBAAsB,CAAC,UAAkB,EAAE,SAAiB;IAC1E,OAAO,GAAG,yBAAyB,KAAK,UAAU,KAAK,0BAA0B,OAAO,SAAS,EAAE,CAAA;AACrG,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,wEAAwE;IACxE,yEAAyE;IACzE,2CAA2C;IAC3C,IAAI,MAAM,GAAG,IAAI,CAAA;IACjB,IAAI,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAA;IACpD,OAAO,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC;QACnB,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,0BAA0B,EAAE,IAAI,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAA;QACjG,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,MAAK,CAAC,mDAAmD;QAC3E,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,0BAA0B,CAAC,MAAM,CAAC,CAAA;QACxF,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAA;IAClD,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,EAAE,CAAA;AACtB,CAAC"}
|