@spool-lab/core 0.5.1 → 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/dist/db/db.d.ts +1 -1
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/db.js +159 -2
- package/dist/db/db.js.map +1 -1
- package/dist/db/published-shares-cache.d.ts +39 -0
- package/dist/db/published-shares-cache.d.ts.map +1 -0
- package/dist/db/published-shares-cache.js +60 -0
- package/dist/db/published-shares-cache.js.map +1 -0
- package/dist/db/queries.d.ts +58 -2
- package/dist/db/queries.d.ts.map +1 -1
- package/dist/db/queries.js +210 -26
- package/dist/db/queries.js.map +1 -1
- package/dist/db/search-query.d.ts +7 -0
- package/dist/db/search-query.d.ts.map +1 -1
- package/dist/db/search-query.js +26 -0
- package/dist/db/search-query.js.map +1 -1
- package/dist/db/share-drafts.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/migrations/worktree-identity-upgrade.d.ts +5 -3
- package/dist/migrations/worktree-identity-upgrade.d.ts.map +1 -1
- package/dist/migrations/worktree-identity-upgrade.js +23 -2
- package/dist/migrations/worktree-identity-upgrade.js.map +1 -1
- package/dist/observability/exporter-file.d.ts.map +1 -1
- package/dist/observability/exporter-pretty.d.ts.map +1 -1
- package/dist/observability/exporter-pretty.js.map +1 -1
- package/dist/parsers/claude.d.ts.map +1 -1
- package/dist/parsers/claude.js +4 -144
- package/dist/parsers/claude.js.map +1 -1
- package/dist/parsers/codex.d.ts +7 -1
- package/dist/parsers/codex.d.ts.map +1 -1
- package/dist/parsers/codex.js +47 -177
- package/dist/parsers/codex.js.map +1 -1
- package/dist/parsers/gemini.d.ts.map +1 -1
- package/dist/parsers/gemini.js +102 -2
- package/dist/parsers/gemini.js.map +1 -1
- package/dist/parsers/pi.d.ts +18 -0
- package/dist/parsers/pi.d.ts.map +1 -0
- package/dist/parsers/pi.js +154 -0
- package/dist/parsers/pi.js.map +1 -0
- package/dist/parsers/spool-prelude.d.ts +1 -15
- package/dist/parsers/spool-prelude.d.ts.map +1 -1
- package/dist/parsers/spool-prelude.js +3 -20
- package/dist/parsers/spool-prelude.js.map +1 -1
- package/dist/projects/groups.d.ts +4 -1
- package/dist/projects/groups.d.ts.map +1 -1
- package/dist/projects/groups.js +26 -9
- package/dist/projects/groups.js.map +1 -1
- package/dist/projects/identity.d.ts +1 -1
- package/dist/projects/identity.d.ts.map +1 -1
- package/dist/projects/identity.js +12 -1
- package/dist/projects/identity.js.map +1 -1
- package/dist/projects/sessions.js.map +1 -1
- package/dist/projects/worktree-resolvers.d.ts +3 -0
- package/dist/projects/worktree-resolvers.d.ts.map +1 -1
- package/dist/projects/worktree-resolvers.js +130 -2
- package/dist/projects/worktree-resolvers.js.map +1 -1
- package/dist/security/profile.d.ts.map +1 -1
- package/dist/security/profile.js +2 -3
- package/dist/security/profile.js.map +1 -1
- package/dist/security/purge.d.ts +16 -11
- package/dist/security/purge.d.ts.map +1 -1
- package/dist/security/purge.js +165 -24
- package/dist/security/purge.js.map +1 -1
- package/dist/security/types.d.ts +1 -1
- package/dist/security/types.d.ts.map +1 -1
- package/dist/security/worker.d.ts.map +1 -1
- package/dist/security/worker.js +44 -8
- package/dist/security/worker.js.map +1 -1
- package/dist/sync/source-paths.d.ts.map +1 -1
- package/dist/sync/source-paths.js +47 -11
- package/dist/sync/source-paths.js.map +1 -1
- package/dist/sync/syncer.d.ts +59 -1
- package/dist/sync/syncer.d.ts.map +1 -1
- package/dist/sync/syncer.js +172 -36
- package/dist/sync/syncer.js.map +1 -1
- package/dist/sync/watcher.d.ts.map +1 -1
- package/dist/sync/watcher.js +3 -1
- package/dist/sync/watcher.js.map +1 -1
- package/dist/types.d.ts +8 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/util/resolve-bin.js.map +1 -1
- package/package.json +7 -4
|
@@ -1,14 +1,35 @@
|
|
|
1
|
+
import { loadCodexSessionGitRemote } from '../parsers/codex.js';
|
|
1
2
|
import { computeIdentity } from '../projects/identity.js';
|
|
2
|
-
export function upgradeWorktreeIdentities(db, fs) {
|
|
3
|
+
export function upgradeWorktreeIdentities(db, fs, readCodexGitRemote = loadCodexSessionGitRemote) {
|
|
3
4
|
const rows = db.prepare(`SELECT id, identity_key FROM projects WHERE identity_kind = 'path'`).all();
|
|
4
5
|
if (rows.length === 0)
|
|
5
6
|
return { examined: 0, upgraded: 0 };
|
|
6
7
|
const update = db.prepare(`UPDATE projects
|
|
7
8
|
SET identity_kind = ?, identity_key = ?, display_name = ?
|
|
8
9
|
WHERE id = ?`);
|
|
10
|
+
const codexFiles = db.prepare(`
|
|
11
|
+
SELECT s.file_path
|
|
12
|
+
FROM sessions s
|
|
13
|
+
JOIN sources src ON src.id = s.source_id
|
|
14
|
+
WHERE s.project_id = ? AND src.name = 'codex'
|
|
15
|
+
ORDER BY s.started_at DESC
|
|
16
|
+
`);
|
|
9
17
|
let upgraded = 0;
|
|
10
18
|
for (const row of rows) {
|
|
11
|
-
|
|
19
|
+
let id = computeIdentity(row.identity_key, fs);
|
|
20
|
+
// Codex persists the remote in session_meta. This is the only durable
|
|
21
|
+
// identity signal for historical rows whose checkout and worktree-tool
|
|
22
|
+
// metadata are both gone, so consult it before accepting the path fallback.
|
|
23
|
+
if (id.kind === 'path') {
|
|
24
|
+
const files = codexFiles.all(row.id);
|
|
25
|
+
for (const file of files) {
|
|
26
|
+
const remote = readCodexGitRemote(file.file_path);
|
|
27
|
+
if (!remote)
|
|
28
|
+
continue;
|
|
29
|
+
id = computeIdentity(row.identity_key, fs, [], [], remote);
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
12
33
|
// Only upgrade when the resolver produced something stronger than path.
|
|
13
34
|
// (`loose` shouldn't happen here since we feed it a real cwd, but skip
|
|
14
35
|
// defensively to avoid demoting rows.)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktree-identity-upgrade.js","sourceRoot":"","sources":["../../src/migrations/worktree-identity-upgrade.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAmB,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"worktree-identity-upgrade.js","sourceRoot":"","sources":["../../src/migrations/worktree-identity-upgrade.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,EAAE,eAAe,EAAmB,MAAM,yBAAyB,CAAA;AAiC1E,MAAM,UAAU,yBAAyB,CACvC,EAAqB,EACrB,EAAc,EACd,kBAAkB,GAAwC,yBAAyB;IAEnF,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CACrB,oEAAoE,CACrE,CAAC,GAAG,EAAiD,CAAA;IAEtD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAA;IAE1D,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CACvB;;kBAEc,CACf,CAAA;IACD,MAAM,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;GAM7B,CAAC,CAAA;IAEF,IAAI,QAAQ,GAAG,CAAC,CAAA;IAChB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,EAAE,GAAG,eAAe,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;QAC9C,sEAAsE;QACtE,uEAAuE;QACvE,4EAA4E;QAC5E,IAAI,EAAE,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAiC,CAAA;YACpE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;gBACjD,IAAI,CAAC,MAAM;oBAAE,SAAQ;gBACrB,EAAE,GAAG,eAAe,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,CAAA;gBAC1D,MAAK;YACP,CAAC;QACH,CAAC;QACD,wEAAwE;QACxE,uEAAuE;QACvE,uCAAuC;QACvC,IAAI,EAAE,CAAC,IAAI,KAAK,MAAM,IAAI,EAAE,CAAC,IAAI,KAAK,OAAO;YAAE,SAAQ;QACvD,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,WAAW,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;QACnD,QAAQ,IAAI,CAAC,CAAA;IACf,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAA;AAC5C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exporter-file.d.ts","sourceRoot":"","sources":["../../src/observability/exporter-file.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAI/E,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAED,MAAM,WAAW,+BAA+B;IAC9C,2DAA2D;IAC3D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,kEAAkE;IAClE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,kCAAkC;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;CAC1B;AAMD,qBAAa,wBAAyB,YAAW,YAAY;IAC3D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAY;IAMhC,OAAO,CAAC,UAAU,CAAsB;
|
|
1
|
+
{"version":3,"file":"exporter-file.d.ts","sourceRoot":"","sources":["../../src/observability/exporter-file.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAI/E,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAED,MAAM,WAAW,+BAA+B;IAC9C,2DAA2D;IAC3D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,kEAAkE;IAClE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,kCAAkC;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;CAC1B;AAMD,qBAAa,wBAAyB,YAAW,YAAY;IAC3D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAY;IAMhC,OAAO,CAAC,UAAU,CAAsB;IAExC,YAAY,IAAI,EAAE,+BAA+B,EAKhD;IAED,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI,CAYlF;IAED,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAA6B;IACtD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAA6B;IAExD,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,cAAc;CAevB;AA8DD;qDACqD;AACrD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAElD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exporter-pretty.d.ts","sourceRoot":"","sources":["../../src/observability/exporter-pretty.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAM/E,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAcD,MAAM,WAAW,gCAAgC;IAC/C,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,uDAAuD;IACvD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAC3B;AAED;;;yBAGyB;AACzB,qBAAa,yBAA0B,YAAW,YAAY;IAC5D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAwB;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;
|
|
1
|
+
{"version":3,"file":"exporter-pretty.d.ts","sourceRoot":"","sources":["../../src/observability/exporter-pretty.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAM/E,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAcD,MAAM,WAAW,gCAAgC;IAC/C,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,uDAAuD;IACvD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAC3B;AAED;;;yBAGyB;AACzB,qBAAa,yBAA0B,YAAW,YAAY;IAC5D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAwB;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B,YAAY,IAAI,GAAE,gCAAqC,EAGtD;IAED,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI,CAGlF;IAED,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAA6B;IACtD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAA6B;IAExD,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,IAAI;CAGb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exporter-pretty.js","sourceRoot":"","sources":["../../src/observability/exporter-pretty.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAUnD,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,SAAS;IAChB,GAAG,EAAE,SAAS;IACd,GAAG,EAAE,UAAU;IACf,KAAK,EAAE,UAAU;IACjB,MAAM,EAAE,UAAU;IAClB,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,UAAU;IACnB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,UAAU;CACR,CAAA;AASV;;;yBAGyB;AACzB,MAAM,OAAO,yBAAyB;IACnB,IAAI,CAAwB;IAC5B,KAAK,CAAS;IAE/B,YAAY,
|
|
1
|
+
{"version":3,"file":"exporter-pretty.js","sourceRoot":"","sources":["../../src/observability/exporter-pretty.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/parsers/claude.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/parsers/claude.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAKpE,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CAEtE;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAOzE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGtD"}
|
package/dist/parsers/claude.js
CHANGED
|
@@ -1,111 +1,9 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { parseClaudeSessionText } from '@spool-lab/session-kit';
|
|
3
|
+
// The parsing brain lives in @spool-lab/session-kit (browser-safe, shared
|
|
4
|
+
// with the web reader); this wrapper owns only the file I/O.
|
|
2
5
|
export function loadClaudeSession(filePath) {
|
|
3
|
-
|
|
4
|
-
const lines = raw.split('\n').filter(l => l.trim().length > 0);
|
|
5
|
-
const messages = [];
|
|
6
|
-
let sessionUuid = '';
|
|
7
|
-
let cwd = '';
|
|
8
|
-
let model = '';
|
|
9
|
-
let customTitle = '';
|
|
10
|
-
const SKIP_TYPES = new Set([
|
|
11
|
-
'file-history-snapshot',
|
|
12
|
-
'progress',
|
|
13
|
-
'queue-operation',
|
|
14
|
-
'last-prompt',
|
|
15
|
-
]);
|
|
16
|
-
for (const line of lines) {
|
|
17
|
-
let record;
|
|
18
|
-
try {
|
|
19
|
-
record = JSON.parse(line);
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
continue;
|
|
23
|
-
}
|
|
24
|
-
const type = record['type'];
|
|
25
|
-
if (!type || SKIP_TYPES.has(type))
|
|
26
|
-
continue;
|
|
27
|
-
if (!sessionUuid && record['sessionId'])
|
|
28
|
-
sessionUuid = record['sessionId'];
|
|
29
|
-
if (!cwd && record['cwd'])
|
|
30
|
-
cwd = record['cwd'];
|
|
31
|
-
if (type === 'custom-title') {
|
|
32
|
-
const ct = record['customTitle'];
|
|
33
|
-
if (ct)
|
|
34
|
-
customTitle = ct;
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
if (type === 'assistant') {
|
|
38
|
-
const msg = record['message'];
|
|
39
|
-
if (msg?.['model'])
|
|
40
|
-
model = msg['model'];
|
|
41
|
-
}
|
|
42
|
-
if (type === 'summary') {
|
|
43
|
-
const summaryText = record['summary'];
|
|
44
|
-
if (summaryText) {
|
|
45
|
-
messages.push({
|
|
46
|
-
uuid: record['uuid'] ?? `summary-${messages.length}`,
|
|
47
|
-
parentUuid: record['parentUuid'] ?? null,
|
|
48
|
-
role: 'system',
|
|
49
|
-
contentText: summaryText.trim(),
|
|
50
|
-
timestamp: record['timestamp'],
|
|
51
|
-
isSidechain: Boolean(record['isSidechain']),
|
|
52
|
-
toolNames: [],
|
|
53
|
-
seq: messages.length,
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
const msgObj = record['message'];
|
|
59
|
-
if (!msgObj)
|
|
60
|
-
continue;
|
|
61
|
-
const role = msgObj['role'];
|
|
62
|
-
if (role !== 'user' && role !== 'assistant')
|
|
63
|
-
continue;
|
|
64
|
-
const contentRaw = msgObj['content'];
|
|
65
|
-
const contentText = extractText(contentRaw);
|
|
66
|
-
const toolNames = extractToolNames(contentRaw);
|
|
67
|
-
// Skip empty messages (e.g. tool result placeholders with no text)
|
|
68
|
-
if (!contentText && toolNames.length === 0)
|
|
69
|
-
continue;
|
|
70
|
-
messages.push({
|
|
71
|
-
uuid: record['uuid'] ?? `msg-${messages.length}`,
|
|
72
|
-
parentUuid: record['parentUuid'] ?? null,
|
|
73
|
-
role: role,
|
|
74
|
-
contentText,
|
|
75
|
-
timestamp: record['timestamp'],
|
|
76
|
-
isSidechain: Boolean(record['isSidechain']),
|
|
77
|
-
toolNames,
|
|
78
|
-
seq: messages.length,
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
if (messages.length === 0)
|
|
82
|
-
return { kind: 'skipped' };
|
|
83
|
-
// Use cwd from messages if not in top-level fields
|
|
84
|
-
if (!cwd) {
|
|
85
|
-
for (const m of messages) {
|
|
86
|
-
// cwd is on the record level, not message level — already captured above
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
const firstUserMsg = messages.find(m => m.role === 'user' && m.contentText.length > 0 && !m.isSidechain);
|
|
90
|
-
const title = customTitle
|
|
91
|
-
|| (firstUserMsg
|
|
92
|
-
? firstUserMsg.contentText.replace(/<[^>]+>/g, '').trim().slice(0, 120)
|
|
93
|
-
: '(no title)');
|
|
94
|
-
const timestamps = messages.map(m => m.timestamp).filter(Boolean).sort();
|
|
95
|
-
return {
|
|
96
|
-
kind: 'parsed',
|
|
97
|
-
session: {
|
|
98
|
-
source: 'claude',
|
|
99
|
-
sessionUuid: sessionUuid || filePath,
|
|
100
|
-
filePath,
|
|
101
|
-
title,
|
|
102
|
-
cwd,
|
|
103
|
-
model,
|
|
104
|
-
startedAt: timestamps[0] ?? new Date().toISOString(),
|
|
105
|
-
endedAt: timestamps[timestamps.length - 1] ?? new Date().toISOString(),
|
|
106
|
-
messages,
|
|
107
|
-
},
|
|
108
|
-
};
|
|
6
|
+
return parseClaudeSessionText(readFileSync(filePath, 'utf8'), filePath);
|
|
109
7
|
}
|
|
110
8
|
export function parseClaudeSession(filePath) {
|
|
111
9
|
try {
|
|
@@ -116,44 +14,6 @@ export function parseClaudeSession(filePath) {
|
|
|
116
14
|
return null;
|
|
117
15
|
}
|
|
118
16
|
}
|
|
119
|
-
// Slash-command records in Claude Code JSONL come as a triplet:
|
|
120
|
-
// <command-name>/X</command-name>
|
|
121
|
-
// <command-message>X</command-message>
|
|
122
|
-
// <command-args>Y</command-args>
|
|
123
|
-
// Strip the whole record as one unit so bare <command-args> appearing in
|
|
124
|
-
// legitimate user content (e.g. a user pasting log output that contains
|
|
125
|
-
// these tags) is preserved.
|
|
126
|
-
const SLASH_COMMAND_RECORD = /<command-name>[\s\S]*?<\/command-name>(?:\s*<command-message>[\s\S]*?<\/command-message>)?(?:\s*<command-args>[\s\S]*?<\/command-args>)?/g;
|
|
127
|
-
function extractText(content) {
|
|
128
|
-
let raw;
|
|
129
|
-
if (typeof content === 'string') {
|
|
130
|
-
raw = content;
|
|
131
|
-
}
|
|
132
|
-
else if (Array.isArray(content)) {
|
|
133
|
-
raw = content
|
|
134
|
-
.filter(item => item.type === 'text')
|
|
135
|
-
.map(item => item.text ?? '')
|
|
136
|
-
.join('\n');
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
return '';
|
|
140
|
-
}
|
|
141
|
-
return raw
|
|
142
|
-
.replace(/<spool-system-prelude>[\s\S]*?<\/spool-system-prelude>/g, '')
|
|
143
|
-
.replace(SLASH_COMMAND_RECORD, '')
|
|
144
|
-
.replace(/<local-command-stdout>[\s\S]*?<\/local-command-stdout>/g, '')
|
|
145
|
-
.replace(/<local-command-caveat>[\s\S]*?<\/local-command-caveat>/g, '')
|
|
146
|
-
.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, '')
|
|
147
|
-
.replace(/<[^>]+>/g, '')
|
|
148
|
-
.trim();
|
|
149
|
-
}
|
|
150
|
-
function extractToolNames(content) {
|
|
151
|
-
if (!Array.isArray(content))
|
|
152
|
-
return [];
|
|
153
|
-
return content
|
|
154
|
-
.filter(item => item.type === 'tool_use' && item.name)
|
|
155
|
-
.map(item => item.name);
|
|
156
|
-
}
|
|
157
17
|
/** Decode a Claude project slug to a display path.
|
|
158
18
|
* e.g. '-Users-claw-code-spool' → '/Users/claw/code/spool'
|
|
159
19
|
* Note: lossy for paths containing hyphens — prefer cwd from session records.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/parsers/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/parsers/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AAG/D,0EAA0E;AAC1E,6DAA6D;AAE7D,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,OAAO,sBAAsB,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAA;AACzE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAA;QAC1C,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IACtC,OAAO,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;AAC/C,CAAC"}
|
package/dist/parsers/codex.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { ParseSessionResult, ParsedSession } from '../types.js';
|
|
2
|
-
export declare const CODEX_INDEX_VERSION = "codex-
|
|
2
|
+
export declare const CODEX_INDEX_VERSION = "codex-v6-project-identity-from-session-git-remote";
|
|
3
3
|
export declare function loadCodexSession(filePath: string): ParseSessionResult;
|
|
4
4
|
export declare function parseCodexSession(filePath: string): ParsedSession | null;
|
|
5
|
+
/**
|
|
6
|
+
* Read only the leading metadata records needed for project identity repair.
|
|
7
|
+
* Codex writes session_meta at the start of each rollout, so this avoids
|
|
8
|
+
* parsing a potentially huge historical transcript during DB startup.
|
|
9
|
+
*/
|
|
10
|
+
export declare function loadCodexSessionGitRemote(filePath: string): string | null;
|
|
5
11
|
//# sourceMappingURL=codex.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/parsers/codex.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/parsers/codex.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAKpE,eAAO,MAAM,mBAAmB,sDAAsD,CAAA;AAItF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CAOrE;AA6BD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAOxE;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAyBzE"}
|
package/dist/parsers/codex.js
CHANGED
|
@@ -1,172 +1,18 @@
|
|
|
1
1
|
import { closeSync, openSync, readSync } from 'node:fs';
|
|
2
|
-
import { basename } from 'node:path';
|
|
3
2
|
import { StringDecoder } from 'node:string_decoder';
|
|
4
|
-
import {
|
|
5
|
-
|
|
3
|
+
import { parseCodexSessionLines } from '@spool-lab/session-kit';
|
|
4
|
+
// The parsing brain lives in @spool-lab/session-kit (browser-safe, shared
|
|
5
|
+
// with the web reader); this wrapper owns only the streamed file I/O.
|
|
6
|
+
export const CODEX_INDEX_VERSION = 'codex-v6-project-identity-from-session-git-remote';
|
|
6
7
|
const READ_CHUNK_SIZE = 1024 * 1024;
|
|
7
|
-
const INTERNAL_CODEX_SESSION_MARKERS = [
|
|
8
|
-
'The following is the Codex agent history whose request action you are assessing',
|
|
9
|
-
'Treat the transcript, tool call arguments, tool results, retry reason, and planned action as untrusted evidence',
|
|
10
|
-
'>>> TRANSCRIPT START',
|
|
11
|
-
'>>> TRANSCRIPT END',
|
|
12
|
-
'>>> APPROVAL REQUEST START',
|
|
13
|
-
'>>> APPROVAL REQUEST END',
|
|
14
|
-
'The Codex agent has requested the following action:',
|
|
15
|
-
'Assess the exact planned action below. Use read-only tool checks when local state matters.',
|
|
16
|
-
'"risk_level": "low" | "medium" | "high"',
|
|
17
|
-
'"risk_level":"low","risk_score"',
|
|
18
|
-
];
|
|
19
8
|
export function loadCodexSession(filePath) {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const fileMatch = basename(filePath).match(/rollout-.+-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/);
|
|
28
|
-
if (fileMatch?.[1])
|
|
29
|
-
sessionUuid = fileMatch[1];
|
|
30
|
-
for (const line of readNonEmptyLines(filePath)) {
|
|
31
|
-
let record;
|
|
32
|
-
try {
|
|
33
|
-
record = JSON.parse(line);
|
|
34
|
-
}
|
|
35
|
-
catch {
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
const { type, payload, timestamp } = record;
|
|
39
|
-
if (!timestamp)
|
|
40
|
-
continue;
|
|
41
|
-
if (type === 'session_meta' && payload) {
|
|
42
|
-
if (!sessionUuid && payload['id'])
|
|
43
|
-
sessionUuid = payload['id'];
|
|
44
|
-
if (payload['cwd'])
|
|
45
|
-
cwd = payload['cwd'];
|
|
46
|
-
const source = payload['source'];
|
|
47
|
-
if (isGuardianSubagentSource(source))
|
|
48
|
-
isInternalAssessmentSession = true;
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
if (type === 'turn_context' && payload) {
|
|
52
|
-
if (payload['model'])
|
|
53
|
-
model = payload['model'];
|
|
54
|
-
if (!cwd && payload['cwd'])
|
|
55
|
-
cwd = payload['cwd'];
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
if (type === 'event_msg' && payload) {
|
|
59
|
-
const msgType = payload['type'];
|
|
60
|
-
if (msgType === 'user_message' && payload['message']) {
|
|
61
|
-
const text = stripSpoolSystemPrelude(String(payload['message']));
|
|
62
|
-
if (looksLikeInternalCodexAssessment(text)) {
|
|
63
|
-
isInternalAssessmentSession = true;
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
if (text) {
|
|
67
|
-
eventMessages.push({
|
|
68
|
-
uuid: `codex-${sessionUuid}-u-${eventMessages.length}`,
|
|
69
|
-
parentUuid: null,
|
|
70
|
-
role: 'user',
|
|
71
|
-
contentText: text,
|
|
72
|
-
timestamp,
|
|
73
|
-
isSidechain: false,
|
|
74
|
-
toolNames: [],
|
|
75
|
-
seq: eventMessages.length,
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
else if (msgType === 'agent_message' && payload['message']) {
|
|
80
|
-
const text = String(payload['message']).trim();
|
|
81
|
-
if (looksLikeInternalCodexAssessment(text)) {
|
|
82
|
-
isInternalAssessmentSession = true;
|
|
83
|
-
continue;
|
|
84
|
-
}
|
|
85
|
-
if (text) {
|
|
86
|
-
eventMessages.push({
|
|
87
|
-
uuid: `codex-${sessionUuid}-a-${eventMessages.length}`,
|
|
88
|
-
parentUuid: null,
|
|
89
|
-
role: 'assistant',
|
|
90
|
-
contentText: text,
|
|
91
|
-
timestamp,
|
|
92
|
-
isSidechain: false,
|
|
93
|
-
toolNames: [],
|
|
94
|
-
seq: eventMessages.length,
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
if (type === 'response_item' && payload) {
|
|
101
|
-
const role = payload['role'];
|
|
102
|
-
if (role === 'assistant') {
|
|
103
|
-
const content = payload['content'];
|
|
104
|
-
if (Array.isArray(content)) {
|
|
105
|
-
const text = content
|
|
106
|
-
.filter(c => c.type === 'output_text' || c.type === 'text')
|
|
107
|
-
.map(c => c.text ?? '')
|
|
108
|
-
.join('\n')
|
|
109
|
-
.trim();
|
|
110
|
-
if (looksLikeInternalCodexAssessment(text)) {
|
|
111
|
-
isInternalAssessmentSession = true;
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
if (text) {
|
|
115
|
-
responseMessages.push({
|
|
116
|
-
uuid: `codex-${sessionUuid}-ri-${responseMessages.length}`,
|
|
117
|
-
parentUuid: null,
|
|
118
|
-
role: 'assistant',
|
|
119
|
-
contentText: text,
|
|
120
|
-
timestamp,
|
|
121
|
-
isSidechain: false,
|
|
122
|
-
toolNames: [],
|
|
123
|
-
seq: responseMessages.length,
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
// Strategy: use event_msg for UI (concise); supplement with response_items for
|
|
132
|
-
// FTS richness when event_msgs are sparse. We index both but deduplicate.
|
|
133
|
-
//
|
|
134
|
-
// If we have event_msgs, use them as the primary message list.
|
|
135
|
-
// response_items are added as system-level messages for FTS indexing only.
|
|
136
|
-
let messages;
|
|
137
|
-
if (eventMessages.length > 0) {
|
|
138
|
-
messages = [...eventMessages];
|
|
139
|
-
// Add response_items as sidechain messages for FTS richness
|
|
140
|
-
for (const rm of responseMessages) {
|
|
141
|
-
messages.push({ ...rm, isSidechain: true, seq: messages.length });
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
messages = responseMessages;
|
|
146
|
-
}
|
|
147
|
-
if (isInternalAssessmentSession)
|
|
148
|
-
return { kind: 'filtered' };
|
|
149
|
-
if (messages.length === 0)
|
|
150
|
-
return { kind: 'skipped' };
|
|
151
|
-
// Re-number seq
|
|
152
|
-
messages = messages.map((m, i) => ({ ...m, seq: i }));
|
|
153
|
-
const firstUserMsg = messages.find(m => m.role === 'user' && !m.isSidechain);
|
|
154
|
-
const title = firstUserMsg?.contentText.slice(0, 120) ?? '(no title)';
|
|
155
|
-
const timestamps = messages.filter(m => !m.isSidechain).map(m => m.timestamp).sort();
|
|
156
|
-
return {
|
|
157
|
-
kind: 'parsed',
|
|
158
|
-
session: {
|
|
159
|
-
source: 'codex',
|
|
160
|
-
sessionUuid: sessionUuid || filePath,
|
|
161
|
-
filePath,
|
|
162
|
-
title,
|
|
163
|
-
cwd,
|
|
164
|
-
model,
|
|
165
|
-
startedAt: timestamps[0] ?? new Date().toISOString(),
|
|
166
|
-
endedAt: timestamps[timestamps.length - 1] ?? new Date().toISOString(),
|
|
167
|
-
messages,
|
|
168
|
-
},
|
|
169
|
-
};
|
|
9
|
+
const result = parseCodexSessionLines(readNonEmptyLines(filePath), filePath);
|
|
10
|
+
if (result.kind !== 'parsed')
|
|
11
|
+
return result;
|
|
12
|
+
const gitRemote = loadCodexSessionGitRemote(filePath);
|
|
13
|
+
return gitRemote
|
|
14
|
+
? { kind: 'parsed', session: { ...result.session, gitRemote } }
|
|
15
|
+
: result;
|
|
170
16
|
}
|
|
171
17
|
function* readNonEmptyLines(filePath) {
|
|
172
18
|
const fd = openSync(filePath, 'r');
|
|
@@ -203,17 +49,41 @@ export function parseCodexSession(filePath) {
|
|
|
203
49
|
return null;
|
|
204
50
|
}
|
|
205
51
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Read only the leading metadata records needed for project identity repair.
|
|
54
|
+
* Codex writes session_meta at the start of each rollout, so this avoids
|
|
55
|
+
* parsing a potentially huge historical transcript during DB startup.
|
|
56
|
+
*/
|
|
57
|
+
export function loadCodexSessionGitRemote(filePath) {
|
|
58
|
+
try {
|
|
59
|
+
let scanned = 0;
|
|
60
|
+
for (const line of readNonEmptyLines(filePath)) {
|
|
61
|
+
if (scanned++ >= 100)
|
|
62
|
+
break;
|
|
63
|
+
let record;
|
|
64
|
+
try {
|
|
65
|
+
record = JSON.parse(line);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (record['type'] !== 'session_meta')
|
|
71
|
+
continue;
|
|
72
|
+
const payload = record['payload'];
|
|
73
|
+
if (!payload || typeof payload !== 'object')
|
|
74
|
+
return null;
|
|
75
|
+
const git = payload['git'];
|
|
76
|
+
if (!git || typeof git !== 'object')
|
|
77
|
+
return null;
|
|
78
|
+
const repositoryUrl = git['repository_url'];
|
|
79
|
+
return typeof repositoryUrl === 'string' && repositoryUrl.trim()
|
|
80
|
+
? repositoryUrl
|
|
81
|
+
: null;
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
218
88
|
}
|
|
219
89
|
//# sourceMappingURL=codex.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/parsers/codex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACvD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/parsers/codex.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/parsers/gemini.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAiB,aAAa,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/parsers/gemini.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAiB,aAAa,EAAE,MAAM,aAAa,CAAA;AAyGnF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CA+DtE;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAOzE"}
|