chat-recall 0.7.18 → 0.7.20
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/README.md +2 -2
- package/dist/cli.js +15848 -6647
- package/dist/cli.js.map +1 -1
- package/dist/install-skills.d.ts.map +1 -1
- package/dist/install-skills.js +2 -0
- package/dist/install-skills.js.map +1 -1
- package/dist/intent-drain.d.ts +7 -1
- package/dist/intent-drain.d.ts.map +1 -1
- package/dist/intent-drain.js +19 -3
- package/dist/intent-drain.js.map +1 -1
- package/dist/mcp-relay.js +1 -1
- package/dist/mcp.js +17152 -8293
- package/dist/scan-worker.js +1644 -333
- package/dist/sync-client.d.ts.map +1 -1
- package/dist/sync-client.js +33 -13
- package/dist/sync-client.js.map +1 -1
- package/dist/sync-ledger.d.ts +6 -0
- package/dist/sync-ledger.d.ts.map +1 -1
- package/dist/sync-ledger.js +3 -0
- package/dist/sync-ledger.js.map +1 -1
- package/dist/watch.js +14059 -4933
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-client.d.ts","sourceRoot":"","sources":["../src/sync-client.ts"],"names":[],"mappings":"AA0CA,OAAO,EAAoF,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,4CAA4C,CAAC;
|
|
1
|
+
{"version":3,"file":"sync-client.d.ts","sourceRoot":"","sources":["../src/sync-client.ts"],"names":[],"mappings":"AA0CA,OAAO,EAAoF,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,4CAA4C,CAAC;AAWrL,OAAO,EAA+B,KAAK,UAAU,EAAE,MAAM,0CAA0C,CAAC;AA2ExG,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,UAAU,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,CAI7E;AAgBD,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAGvD;AAED,MAAM,MAAM,YAAY,GACpB,cAAc,GAAG,kBAAkB,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GACpE,KAAK,GAAG,SAAS,GAAG,oBAAoB,GAAG,cAAc,GAAG,OAAO,CAAC;AAExE;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,YAAY,CAqBtE;AAOD,OAAO,EAA2D,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACnH,OAAO,4CAA4C,CAAC;AAMpD,MAAM,WAAW,WAAW;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;CAAE;AAElE;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI,CAoBpD;AAED,wBAAgB,kBAAkB,IAAI,WAAW,EAAE,CAelD;AAwGD,wBAAgB,+BAA+B,IAAI,IAAI,CAEtD;AAuBD,UAAU,gBAAgB;IAAG,YAAY,EAAE,MAAM,EAAE,CAAC;IAAC,eAAe,EAAE,MAAM,EAAE,CAAC;IAAC,cAAc,EAAE,MAAM,EAAE,CAAC;IAAC,cAAc,EAAE,MAAM,EAAE,CAAA;CAAE;AAkCpI,iBAAe,qBAAqB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA2EjF;AAED;;4EAE4E;AAC5E,eAAO,MAAM,8BAA8B,8BAAwB,CAAC;AAuCpE,wBAAgB,2BAA2B,IAAI,IAAI,CAElD;AAED,oDAAoD;AACpD,wEAAwE;AACxE,wBAAgB,eAAe,IAAI,WAAW,GAAG,IAAI,CAEpD;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAM5D;AAMD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CAC3C;AAED,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAUD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAA0C;AAyB/F,wBAAsB,YAAY,CAAC,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CA+GvN;AAED,MAAM,WAAW,eAAe;IAAG,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE;AA+ErK;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CAc9F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAiB,EAAE,QAAQ,SAAe,EAAE,GAAG,SAAa,GAAG,MAAM,CAc3G;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,EACvD,IAAI,GAAE;IACJ,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,cAAc,EAAE,CAAC;CAClE,GACL;IAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAwD3F;AAgBD,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAE7E;AAED,0EAA0E;AAC1E,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAExE;AA8yCD;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB;qGACiG;IACjG,QAAQ,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IACpI,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf;;;qFAGiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;iFAC6E;IAC7E,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9D;AAED;;0EAE0E;AAC1E,MAAM,WAAW,qBAAqB;IAAG,SAAS,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;CAAE;AAE5E;;;;;;;;;6BAS6B;AAC7B,eAAO,MAAM,oBAAoB,QAC2D,CAAC;AAC7F;;gFAEgF;AAChF,eAAO,MAAM,iBAAiB,QAC2D,CAAC;AAC1F;4CAC4C;AAC5C,eAAO,MAAM,gBAAgB,QAAkB,CAAC;AAEhD;;;;;;;GAOG;AACH,wBAAsB,6BAA6B,CACjD,GAAG,EAAE,UAAU,EACf,WAAW,CAAC,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GACnD,OAAO,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAwBxC;AAED;;;;;gEAKgE;AAChE;;wEAEwE;AACxE,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CAA2D,CAAC;AAEpH,eAAO,MAAM,oBAAoB,QAC0D,CAAC;AAE5F,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAIxD;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAIzD;AAED,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzL;;kFAE8E;IAC9E,mBAAmB,CAAC,EAAE,WAAW,EAAE,CAAC;IACpC;;;;0EAIsE;IACtE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAO,GACjC,OAAO,CAAC,iBAAiB,GAAG,qBAAqB,GAAG,IAAI,CAAC,CAsY3D;AAuCD;;;;;;;;;;;GAWG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,UAAU,EACf,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAO,GACnG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAyFlJ;AAED;;;;;;GAMG;AACH;;;;;;;;GAQG;AACH;;;;yCAIyC;AACzC,MAAM,WAAW,QAAQ;IAAG,OAAO,EAAE,gBAAgB,GAAG,QAAQ,GAAG,WAAW,CAAA;CAAE;AAEhF,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,GAAG,QAAQ,GAAG,CAAC,IAAI,QAAQ,CAElE;AAED,wBAAsB,eAAe,CAAC,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAO,GAAG,OAAO,CAAC,UAAU,GAAG,QAAQ,CAAC,CA4C/G"}
|
package/dist/sync-client.js
CHANGED
|
@@ -49,6 +49,7 @@ import { listAvailableBackends } from '@chat-recall/engine/core/tool-backend.js'
|
|
|
49
49
|
import { parseTranscript, trimTranscriptForSync, TRANSCRIPT_VERSION, gzipContainer, redactContainer, buildRawContainer, containerSrcHash, parseTranscriptFromContainer, updateShadow, shadowUncompressedBytes } from '@chat-recall/engine/transcript/index.js';
|
|
50
50
|
import { parseClaudeTranscriptText } from '@chat-recall/engine/transcript/claude.js';
|
|
51
51
|
import { parseCodexTranscriptText } from '@chat-recall/engine/transcript/codex.js';
|
|
52
|
+
import { canonicalEventsToMessages } from '@chat-recall/engine/transcript/index.js';
|
|
52
53
|
import { getBackendForId, getBackend } from '@chat-recall/engine/core/tool-backend.js';
|
|
53
54
|
import { fileURLToPath } from 'node:url';
|
|
54
55
|
let ownVersion = '0.0.0';
|
|
@@ -1331,6 +1332,14 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
1331
1332
|
// that re-classifies the session as FULL on an mtime-only change then matches
|
|
1332
1333
|
// this hash and skips the rebuild entirely.
|
|
1333
1334
|
const shippedHash = new Map();
|
|
1335
|
+
// session_id → the backend's sourceLayout when this run read the session.
|
|
1336
|
+
// Every ack records it with the cursor, so the cursor and the bytes it
|
|
1337
|
+
// addresses come from the same read.
|
|
1338
|
+
const shippedLayout = new Map();
|
|
1339
|
+
const layoutOf = (id) => {
|
|
1340
|
+
const layout = shippedLayout.get(id);
|
|
1341
|
+
return layout ? { layout } : {};
|
|
1342
|
+
};
|
|
1334
1343
|
// `flatten`: each add() is a GROUP of rows that must land in the same
|
|
1335
1344
|
// POST (e.g. one session's findings — the server replaces a session's
|
|
1336
1345
|
// findings wholesale, so splitting a session across two batches would
|
|
@@ -1402,7 +1411,7 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
1402
1411
|
// acked: the server accepted the batch containing this conversation, so
|
|
1403
1412
|
// the cursor is a real delivery receipt.
|
|
1404
1413
|
return off > 0
|
|
1405
|
-
? { id: r.session_id, mtime: r.mtime, offset: off, size: off, hash, acked: true, full: true }
|
|
1414
|
+
? { id: r.session_id, mtime: r.mtime, offset: off, size: off, hash, acked: true, full: true, ...layoutOf(r.session_id) }
|
|
1406
1415
|
: { id: r.session_id, mtime: r.mtime, hash };
|
|
1407
1416
|
}));
|
|
1408
1417
|
}
|
|
@@ -1460,6 +1469,7 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
1460
1469
|
size: c.from_offset, // size = new offset (file grew to here)
|
|
1461
1470
|
acked: true, // server merged this tail
|
|
1462
1471
|
chunkFinal: c.final === true, // completes a chunked full sync
|
|
1472
|
+
...layoutOf(c.session_id),
|
|
1463
1473
|
})));
|
|
1464
1474
|
}
|
|
1465
1475
|
catch { /* ledger — never fail an upload over it */ }
|
|
@@ -1501,10 +1511,10 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
1501
1511
|
const mtime = conv.mtime;
|
|
1502
1512
|
try {
|
|
1503
1513
|
if (staged || !guarded) {
|
|
1504
|
-
markSynced(base, [{ id, mtime, offset: conv.from_offset, size: conv.from_offset, acked: true, chunkedHead: true }]);
|
|
1514
|
+
markSynced(base, [{ id, mtime, offset: conv.from_offset, size: conv.from_offset, acked: true, chunkedHead: true, ...layoutOf(id) }]);
|
|
1505
1515
|
}
|
|
1506
1516
|
else if (typeof guarded.o === 'number' && guarded.o > 0 && guarded.o <= fileSize) {
|
|
1507
|
-
markSynced(base, [{ id, mtime, offset: guarded.o, size: guarded.o, acked: true, chunkedHead: true }]);
|
|
1517
|
+
markSynced(base, [{ id, mtime, offset: guarded.o, size: guarded.o, acked: true, chunkedHead: true, ...layoutOf(id) }]);
|
|
1508
1518
|
}
|
|
1509
1519
|
else {
|
|
1510
1520
|
// The server holds more than this file has: the file was truncated in
|
|
@@ -1666,12 +1676,12 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
1666
1676
|
return ref.mtime >= (opts.sinceMs ?? 0) ? 'full' : 'skip';
|
|
1667
1677
|
const ack = ledger.get(ref.prefixedId);
|
|
1668
1678
|
const backend = backendFor(ref);
|
|
1669
|
-
//
|
|
1670
|
-
//
|
|
1671
|
-
//
|
|
1672
|
-
//
|
|
1673
|
-
const
|
|
1674
|
-
const isAO = !!backend?.isAppendOnly?.() &&
|
|
1679
|
+
// The cursor of a session in more than one home is an offset into its
|
|
1680
|
+
// copies joined end to end. It addresses the same bytes only while the
|
|
1681
|
+
// copies before the last are unchanged; any other change is a FULL sync,
|
|
1682
|
+
// which ships the union and records the new layout.
|
|
1683
|
+
const sameLayout = (ack?.L ?? '') === (backend?.sourceLayout?.(ref.prefixedId) ?? '');
|
|
1684
|
+
const isAO = !!backend?.isAppendOnly?.() && sameLayout;
|
|
1675
1685
|
const size = isAO ? (backend?.fileSize?.(ref.prefixedId) ?? 0) : 0;
|
|
1676
1686
|
return syncMode(ack, ref.mtime, size, extractorVersionForTool(ref.toolId), isAO);
|
|
1677
1687
|
};
|
|
@@ -1792,6 +1802,11 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
1792
1802
|
skipped++;
|
|
1793
1803
|
continue;
|
|
1794
1804
|
}
|
|
1805
|
+
const layout = backendFor(ref)?.sourceLayout?.(ref.prefixedId) ?? '';
|
|
1806
|
+
if (layout)
|
|
1807
|
+
shippedLayout.set(ref.prefixedId, layout);
|
|
1808
|
+
else
|
|
1809
|
+
shippedLayout.delete(ref.prefixedId);
|
|
1795
1810
|
trace?.(`build (${mode}) ${ref.prefixedId} · ${(sessionFileBytes(ref) / 1048576).toFixed(1)}MB`);
|
|
1796
1811
|
// ── APPEND: tail-only ship (no raw_b64, no telemetry, no derived) ──
|
|
1797
1812
|
// `promotedForFindings` flips true when the tail carried a secret finding:
|
|
@@ -1893,7 +1908,7 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
1893
1908
|
const priorCursor = ackRow?.s ?? 0;
|
|
1894
1909
|
const safeToAck = off > 0 && off <= priorCursor;
|
|
1895
1910
|
markSynced(base, [safeToAck
|
|
1896
|
-
? { id: ref.prefixedId, mtime: ref.mtime, offset: off, size: off, hash: built.srcHash, acked: true }
|
|
1911
|
+
? { id: ref.prefixedId, mtime: ref.mtime, offset: off, size: off, hash: built.srcHash, acked: true, ...layoutOf(ref.prefixedId) }
|
|
1897
1912
|
: { id: ref.prefixedId, mtime: ref.mtime, hash: built.srcHash }]);
|
|
1898
1913
|
}
|
|
1899
1914
|
catch { /* ledger is local bookkeeping — never fail a sync over it */ }
|
|
@@ -2390,7 +2405,7 @@ export async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
2390
2405
|
head = await backend.readFromOffset(ref.prefixedId, head.newOffset, SYNC_CHUNK_BYTES);
|
|
2391
2406
|
}
|
|
2392
2407
|
headOffsetEnd = head.newOffset;
|
|
2393
|
-
const messages = parseTailMessages(ref.toolId, head.text);
|
|
2408
|
+
const messages = parseTailMessages(ref.toolId, head.text, backend);
|
|
2394
2409
|
if (messages.length > 0)
|
|
2395
2410
|
transcript = { messages, subagents: [] };
|
|
2396
2411
|
}
|
|
@@ -2798,13 +2813,18 @@ function diskArchiveSource(ref) {
|
|
|
2798
2813
|
* backend's readFromOffset snaps to the last newline). Returns [] when the
|
|
2799
2814
|
* tail has no usable messages (blank, all-summary, internal-tool prompt).
|
|
2800
2815
|
*/
|
|
2801
|
-
function parseTailMessages(tool, text) {
|
|
2816
|
+
function parseTailMessages(tool, text, backend = null) {
|
|
2802
2817
|
if (!text || !text.trim())
|
|
2803
2818
|
return [];
|
|
2804
2819
|
if (tool === 'claude')
|
|
2805
2820
|
return parseClaudeTranscriptText(text);
|
|
2806
2821
|
if (tool === 'codex')
|
|
2807
2822
|
return parseCodexTranscriptText(text);
|
|
2823
|
+
// Pi and Antigravity reuse their canonical-event parser here, so an append
|
|
2824
|
+
// ships the same messages as a full build.
|
|
2825
|
+
if (backend?.readEventsFromText) {
|
|
2826
|
+
return canonicalEventsToMessages(backend.readEventsFromText(text, 0));
|
|
2827
|
+
}
|
|
2808
2828
|
return [];
|
|
2809
2829
|
}
|
|
2810
2830
|
/**
|
|
@@ -2839,7 +2859,7 @@ export async function buildConversationTail(ref, fromOffset, opts = {}) {
|
|
|
2839
2859
|
// than a chunk) still has to move the server's synced-through offset, or the
|
|
2840
2860
|
// cursor reads the same window on every tick and the rest of a chunked
|
|
2841
2861
|
// session never ships. The server merges an empty tail and advances `o`.
|
|
2842
|
-
const messages = skippedBytes ? [] : parseTailMessages(ref.toolId, tailText);
|
|
2862
|
+
const messages = skippedBytes ? [] : parseTailMessages(ref.toolId, tailText, backend);
|
|
2843
2863
|
const textMessages = messages.filter((m) => m.role !== 'summary' && m.content?.trim());
|
|
2844
2864
|
const hasContent = textMessages.length > 0 || messages.some((m) => m.toolCalls?.length);
|
|
2845
2865
|
if (!hasContent) {
|