@volter/supercode-interchange 0.1.9 → 0.1.11
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/jsonl.mjs +6 -2
- package/metadata.mjs +1 -1
- package/openclaw.mjs +2 -2
- package/package.json +1 -1
- package/source-files.mjs +1 -1
- package/source-layout.mjs +7 -1
package/jsonl.mjs
CHANGED
|
@@ -30,13 +30,17 @@ async function readHeader(reader, harness) {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
async function descriptor(path, harness, reader, header, facts, nativeTopic) {
|
|
33
|
-
|
|
33
|
+
// A Claude subagent's transcript (`<session>/subagents/agent-<id>.jsonl`) carries its parent's sessionId in every
|
|
34
|
+
// record: named by that id it would share its parent's index key, replace the parent's row and, as a child, drop
|
|
35
|
+
// the parent from discovery. It is named by its own file, under its parent.
|
|
36
|
+
const subagentOf = harness === 'claude-code' && basename(dirname(path)) === 'subagents' ? basename(dirname(dirname(path))) : null;
|
|
37
|
+
const sessionId = subagentOf ? basename(path, extname(path)) : header.session_id ?? basename(path, extname(path));
|
|
34
38
|
let title = header.title ?? header.topic;
|
|
35
39
|
if (title == null && harness === 'codex') {
|
|
36
40
|
if (typeof nativeTopic !== 'function') throw new Error('Codex metadata requires its native thread-name source');
|
|
37
41
|
title = await nativeTopic(path, sessionId);
|
|
38
42
|
}
|
|
39
|
-
const parent = header.parent_session_id ??
|
|
43
|
+
const parent = header.parent_session_id ?? subagentOf;
|
|
40
44
|
return finalizeNouns({
|
|
41
45
|
locator: { harness, session_id: sessionId, storage: { kind: 'file', path } },
|
|
42
46
|
cwd: header.cwd, title, updated_at_ms: facts.last_turn_ms ?? reader.modified_ms,
|
package/metadata.mjs
CHANGED
|
@@ -119,7 +119,7 @@ export function headerFacts(records, harness) {
|
|
|
119
119
|
applyHeaderRecord(result, value, harness);
|
|
120
120
|
if (headerComplete(result, harness)) break;
|
|
121
121
|
}
|
|
122
|
-
if (result.session_id == null && result.cwd == null) throw new Error(`no recognizable ${harness} session header`);
|
|
122
|
+
if (result.session_id == null && result.cwd == null) throw Object.assign(new Error(`no recognizable ${harness} session header`), { code: 'not_a_session' });
|
|
123
123
|
return result;
|
|
124
124
|
}
|
|
125
125
|
|
package/openclaw.mjs
CHANGED
|
@@ -44,7 +44,7 @@ async function scanCounts(reader, previous) {
|
|
|
44
44
|
headerPieces = []; headerSize = 0;
|
|
45
45
|
if (!nativeTrim(text)) return;
|
|
46
46
|
const value = parseJsonLine(bytes, { strictUtf8: true });
|
|
47
|
-
if (value?.type !== 'session') throw new Error(`${reader.path} has no OpenClaw session header`);
|
|
47
|
+
if (value?.type !== 'session') throw Object.assign(new Error(`${reader.path} has no OpenClaw session header`), { code: 'not_a_session' });
|
|
48
48
|
header = value; headerTerminated = terminated;
|
|
49
49
|
};
|
|
50
50
|
while (offset < reader.size) {
|
|
@@ -72,7 +72,7 @@ async function scanCounts(reader, previous) {
|
|
|
72
72
|
}
|
|
73
73
|
utf8.decode(); // A truncated multibyte sequence is a failed part, not none.
|
|
74
74
|
if (header == null && headerSize) acceptHeader(false);
|
|
75
|
-
if (header == null) throw new Error(`${reader.path} has no OpenClaw session header`);
|
|
75
|
+
if (header == null) throw Object.assign(new Error(`${reader.path} has no OpenClaw session header`), { code: 'not_a_session' });
|
|
76
76
|
count.match_tail = overlap.toString('base64');
|
|
77
77
|
return { count, header, header_terminated: headerTerminated };
|
|
78
78
|
}
|
package/package.json
CHANGED
package/source-files.mjs
CHANGED
|
@@ -46,7 +46,7 @@ async function geminiHeader(reader) {
|
|
|
46
46
|
const bytes = await reader.read(0, Math.min(64 * 1024, reader.size));
|
|
47
47
|
const newline = bytes.indexOf(10), end = newline < 0 ? bytes.length : newline;
|
|
48
48
|
const header = parseJsonLine(bytes.subarray(0, end), { strictUtf8: true });
|
|
49
|
-
if (typeof header?.sessionId !== 'string') throw new Error(`${reader.path} has no Gemini sessionId header`);
|
|
49
|
+
if (typeof header?.sessionId !== 'string') throw Object.assign(new Error(`${reader.path} has no Gemini sessionId header`), { code: 'not_a_session' });
|
|
50
50
|
const after = newline < 0 ? bytes.length : newline + 1;
|
|
51
51
|
const decoration = bytes.subarray(after, Math.min(bytes.length, after + 4 * 1024));
|
|
52
52
|
let model = null, modelTerminated = false;
|
package/source-layout.mjs
CHANGED
|
@@ -37,7 +37,13 @@ export async function sessionPartFor(harness, root, path) {
|
|
|
37
37
|
const name = basename(path);
|
|
38
38
|
if (harness === 'claude-code' || harness === 'pi') return name.endsWith('.jsonl') ? path : null;
|
|
39
39
|
if (harness === 'codex') return name.endsWith('.jsonl') || name.endsWith('.jsonl.zst') ? path : null;
|
|
40
|
-
|
|
40
|
+
// OpenClaw keeps its sessions in `agents/<id>/sessions/` only (native discover_openclaw); the rest of its state
|
|
41
|
+
// folder (logs, cron, workspace) holds JSONL that is not a session.
|
|
42
|
+
if (harness === 'openclaw') {
|
|
43
|
+
const part = relative(root, path).split(sep);
|
|
44
|
+
return part.length === 4 && part[0] === 'agents' && part[2] === 'sessions'
|
|
45
|
+
&& name.endsWith('.jsonl') && !name.endsWith('.trajectory.jsonl') ? path : null;
|
|
46
|
+
}
|
|
41
47
|
if (harness === 'gemini') return name.endsWith('.jsonl') && pathUnder(join(root, 'tmp'), path) ? path : null;
|
|
42
48
|
if (harness === 'grok') {
|
|
43
49
|
const part = relative(root, path).split(sep);
|