chat-recall 0.5.5 → 0.5.6
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/cli.js +1389 -697
- package/dist/cli.js.map +1 -1
- package/dist/mcp-diagnostics.d.ts.map +1 -1
- package/dist/mcp-diagnostics.js +10 -8
- package/dist/mcp-diagnostics.js.map +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +1133 -457
- package/dist/mcp.js.map +1 -1
- package/dist/project-tasks.d.ts.map +1 -1
- package/dist/project-tasks.js +12 -7
- package/dist/project-tasks.js.map +1 -1
- package/dist/service-installer.d.ts +1 -1
- package/dist/service-installer.d.ts.map +1 -1
- package/dist/service-installer.js +20 -6
- package/dist/service-installer.js.map +1 -1
- package/dist/sync-client.d.ts +1 -0
- package/dist/sync-client.d.ts.map +1 -1
- package/dist/sync-client.js +162 -93
- package/dist/sync-client.js.map +1 -1
- package/dist/sync-ledger.d.ts +22 -0
- package/dist/sync-ledger.d.ts.map +1 -1
- package/dist/sync-ledger.js +108 -1
- package/dist/sync-ledger.js.map +1 -1
- package/dist/watch.js +989 -445
- package/hooks/chat_recall_escalate_hook.sh +28 -2
- package/hooks/chat_recall_save_hook.sh +17 -11
- package/hooks/chat_recall_wakeup_hook.sh +27 -1
- package/package.json +7 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-tasks.d.ts","sourceRoot":"","sources":["../src/project-tasks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AASH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAClD,MAAM,WAAW,QAAQ;IAAG,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;CAAE;AAItF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAwC;
|
|
1
|
+
{"version":3,"file":"project-tasks.d.ts","sourceRoot":"","sources":["../src/project-tasks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AASH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAClD,MAAM,WAAW,QAAQ;IAAG,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;CAAE;AAItF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAwC;AAoCxG,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAa7D;AAED,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CAUzD;AAmBD,MAAM,WAAW,UAAU;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;CAAE;AAEnE;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/B,OAAO,CAAC,UAAU,CAAC,CA8CrB;AASD,MAAM,WAAW,YAAY;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAAE;AAE7H,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,MAAM,CAe/D;AAED,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CAE9D"}
|
package/dist/project-tasks.js
CHANGED
|
@@ -23,7 +23,7 @@ import { fetchWithTimeout } from './http.js';
|
|
|
23
23
|
import { isSecretTaskStatus } from '@chat-recall/engine/core/secret-task-status.js';
|
|
24
24
|
import { isCodeTaskStatus } from '@chat-recall/engine/core/code-task-status.js';
|
|
25
25
|
/** Collaborative-task statuses (mirrors the team_tasks CHECK constraint). */
|
|
26
|
-
const TEAM_STATUSES = new Set(['todo', 'in_progress', '
|
|
26
|
+
const TEAM_STATUSES = new Set(['todo', 'in_progress', 'done', 'rejected']);
|
|
27
27
|
export function isTeamTaskStatus(v) { return !!v && TEAM_STATUSES.has(v); }
|
|
28
28
|
// Matches both `cr-secret id=…` (kind implied secret) and `cr-task kind=… id=…`.
|
|
29
29
|
// Status tokens can contain underscores (`in_progress`, `false_positive`), so
|
|
@@ -42,11 +42,15 @@ function reconcile(kind, was, token, checked) {
|
|
|
42
42
|
if (token && token !== was)
|
|
43
43
|
return token; // explicit status edit wins (all kinds)
|
|
44
44
|
if (kind === 'team') {
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
// A TICK CANNOT MEAN DONE ANY MORE. Done is earned by the work: the route
|
|
46
|
+
// refuses it without a linked session, so a tick here would send a 409 the
|
|
47
|
+
// user cannot act on from a markdown file. The honest mapping is to claim
|
|
48
|
+
// the card — that is what a person ticking a box in their repo means, and
|
|
49
|
+
// the agent that finishes it closes it with its session attached.
|
|
50
|
+
//
|
|
51
|
+
// An untick still resets a done card, because undoing a claim is safe.
|
|
52
|
+
if (checked && was === 'todo')
|
|
53
|
+
return 'in_progress';
|
|
50
54
|
if (!checked && was === 'done')
|
|
51
55
|
return 'todo';
|
|
52
56
|
return token ?? was;
|
|
@@ -186,7 +190,8 @@ export function renderTeamTasksMd(tasks) {
|
|
|
186
190
|
'# Team tasks',
|
|
187
191
|
'',
|
|
188
192
|
'<!-- Managed by chat-recall. Tick a box or edit the `status:` token, then run',
|
|
189
|
-
' `chat-recall tasks push`. Statuses: todo · in_progress ·
|
|
193
|
+
' `chat-recall tasks push`. Statuses: todo · in_progress · done · rejected.',
|
|
194
|
+
' A tick claims a task; only the session that does the work can close it. -->',
|
|
190
195
|
'',
|
|
191
196
|
];
|
|
192
197
|
if (tasks.length === 0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-tasks.js","sourceRoot":"","sources":["../src/project-tasks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACvF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AAKhF,6EAA6E;AAC7E,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"project-tasks.js","sourceRoot":"","sources":["../src/project-tasks.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,7 +17,7 @@ export declare function renderSystemdUnit(watchJs: string, node: string, logFile
|
|
|
17
17
|
/** Render the launchd plist body (pure — no FS, no exec). */
|
|
18
18
|
export declare function renderLaunchdPlist(watchJs: string, node: string, logFile: string, label?: string): string;
|
|
19
19
|
/** Render the schtasks /create command (pure — no exec). */
|
|
20
|
-
export declare function renderWindowsTaskCommand(watchJs: string, node: string, taskName?: string): string;
|
|
20
|
+
export declare function renderWindowsTaskCommand(watchJs: string, node: string, taskName?: string, logFile?: string): string;
|
|
21
21
|
/**
|
|
22
22
|
* Stop + remove the per-user background service. Idempotent — no error if
|
|
23
23
|
* the service isn't installed. Returns true if something was removed.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-installer.d.ts","sourceRoot":"","sources":["../src/service-installer.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;CACjB;AAiBD,0EAA0E;AAC1E,wBAAgB,gBAAgB,IAAI,OAAO,CAe1C;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,YAAY,CAiB7C;AAsBD,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"service-installer.d.ts","sourceRoot":"","sources":["../src/service-installer.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;CACjB;AAiBD,0EAA0E;AAC1E,wBAAgB,gBAAgB,IAAI,OAAO,CAe1C;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,YAAY,CAiB7C;AAsBD,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAoBxF;AAmBD,6DAA6D;AAC7D,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,SAA0B,GAAG,MAAM,CAa1H;AAuBD,4DAA4D;AAC5D,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAsB,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAKhI;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAoB1C;AAED,kDAAkD;AAClD,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;gBACF,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;CAI3C"}
|
|
@@ -102,9 +102,13 @@ export function renderSystemdUnit(watchJs, node, logFile) {
|
|
|
102
102
|
// largest transcripts.
|
|
103
103
|
`ExecStart=${node} --max-old-space-size=1536 ${watchJs}`,
|
|
104
104
|
'Restart=on-failure', 'RestartSec=10', 'Nice=10',
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
|
|
105
|
+
// JOURNAL, not append:. The file version had no rotation and nothing to
|
|
106
|
+
// give it any: systemd holds the fd open, so the daemon cannot rename or
|
|
107
|
+
// truncate its own log without leaving systemd writing into a hole. It
|
|
108
|
+
// reached 45 MB on this developer's machine and would have grown forever.
|
|
109
|
+
// journald already rotates and applies disk limits. Read it with
|
|
110
|
+
// journalctl --user -u chat-recall-watch -f
|
|
111
|
+
'StandardOutput=journal', 'StandardError=journal', '',
|
|
108
112
|
'[Install]', 'WantedBy=default.target', '',
|
|
109
113
|
].join('\n');
|
|
110
114
|
}
|
|
@@ -145,7 +149,15 @@ export function renderLaunchdPlist(watchJs, node, logFile, label = 'com.chat-rec
|
|
|
145
149
|
}
|
|
146
150
|
function installWindowsTask(watchJs, node, logFile) {
|
|
147
151
|
const taskName = 'chat-recall-watch';
|
|
148
|
-
|
|
152
|
+
// REDIRECT THE LOG. systemd gets StandardOutput=append: and launchd gets
|
|
153
|
+
// StandardOutPath, but the Scheduled Task had no redirection at all — so
|
|
154
|
+
// every diagnostic the daemon printed was discarded, while the CLI went on
|
|
155
|
+
// telling the user to read ~/.chat-recall/watch.log, a file that was never
|
|
156
|
+
// created. A crash-looping collector with no log is undiagnosable.
|
|
157
|
+
//
|
|
158
|
+
// schtasks /tr cannot express redirection itself, so wrap in cmd /c. The
|
|
159
|
+
// whole thing is one /tr argument, hence the escaped quotes.
|
|
160
|
+
const tr = `cmd /c \\"\\"${node}\\" --max-old-space-size=1536 \\"${watchJs}\\" >> \\"${logFile}\\" 2>&1\\"`;
|
|
149
161
|
try {
|
|
150
162
|
execSync(`schtasks /create /tn "${taskName}" /tr "${tr}" /sc onlogon /rl LIMITED /f`, { stdio: 'inherit' });
|
|
151
163
|
// Start now too (best-effort — starts next logon if /run unsupported).
|
|
@@ -160,8 +172,10 @@ function installWindowsTask(watchJs, node, logFile) {
|
|
|
160
172
|
return { definitionPath: null, logFile };
|
|
161
173
|
}
|
|
162
174
|
/** Render the schtasks /create command (pure — no exec). */
|
|
163
|
-
export function renderWindowsTaskCommand(watchJs, node, taskName = 'chat-recall-watch') {
|
|
164
|
-
const tr =
|
|
175
|
+
export function renderWindowsTaskCommand(watchJs, node, taskName = 'chat-recall-watch', logFile) {
|
|
176
|
+
const tr = logFile
|
|
177
|
+
? `cmd /c \\"\\"${node}\\" --max-old-space-size=1536 \\"${watchJs}\\" >> \\"${logFile}\\" 2>&1\\"`
|
|
178
|
+
: `\\"${node}\\" --max-old-space-size=1536 \\"${watchJs}\\"`;
|
|
165
179
|
return `schtasks /create /tn "${taskName}" /tr "${tr}" /sc onlogon /rl LIMITED /f`;
|
|
166
180
|
}
|
|
167
181
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-installer.js","sourceRoot":"","sources":["../src/service-installer.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"service-installer.js","sourceRoot":"","sources":["../src/service-installer.ts"],"names":[],"mappings":"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"}
|
package/dist/sync-client.d.ts
CHANGED
|
@@ -108,6 +108,7 @@ export declare function batchScanExternal(items: Array<{
|
|
|
108
108
|
slices: number;
|
|
109
109
|
scanMs: number;
|
|
110
110
|
};
|
|
111
|
+
export declare function _resetCapsCacheForTests(): void;
|
|
111
112
|
/**
|
|
112
113
|
* Build the live per-session conversation payload — the THIN-COLLECTOR core.
|
|
113
114
|
* Reads ONLY the raw transcript (via `parseTranscript` + `parseSessionFile`),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-client.d.ts","sourceRoot":"","sources":["../src/sync-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sync-client.d.ts","sourceRoot":"","sources":["../src/sync-client.ts"],"names":[],"mappings":"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"}
|
package/dist/sync-client.js
CHANGED
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
* server owns them.
|
|
32
32
|
*/
|
|
33
33
|
import { join, dirname, basename } from 'node:path';
|
|
34
|
+
import { envCredentials } from '@chat-recall/engine/core/credentials-env.js';
|
|
34
35
|
import { readFileSync, writeFileSync, mkdirSync, mkdtempSync, rmSync, chmodSync, unlinkSync, readdirSync, statSync } from 'node:fs';
|
|
35
36
|
import { tmpdir, hostname } from 'node:os';
|
|
36
37
|
import { createHash } from 'node:crypto';
|
|
@@ -70,11 +71,12 @@ import { parseSessionFile, readCwdFromJsonl } from '@chat-recall/engine/parsers/
|
|
|
70
71
|
import { resolveProjectId } from '@chat-recall/engine/core/project-resolver.js';
|
|
71
72
|
import { extractEntities } from '@chat-recall/engine/core/entity-extractor.js';
|
|
72
73
|
import { buildSourceRegistry } from '@chat-recall/engine/parsers/all-sources.js';
|
|
73
|
-
import { getSyncedRows, markSynced, getLedgerData, persistLedgerData, fieldNeedsScan, markFieldCoverage, fieldNeedsFullPass, markFieldFullPassDone, syncMode, markFullResync, loadItemVersions, saveItemVersions } from './sync-ledger.js';
|
|
74
|
+
import { getSyncedRows, markSynced, getLedgerData, persistLedgerData, fieldNeedsScan, markFieldCoverage, fieldNeedsFullPass, markFieldFullPassDone, syncMode, markFullResync, loadItemVersions, saveItemVersions, flushLedger, pruneLedgerTargets } from './sync-ledger.js';
|
|
74
75
|
import { extractorVersionForTool, extractorVersionForId, toolOfId, EXTRACTOR_VERSION } from '@chat-recall/engine/core/extractor-version.js';
|
|
75
76
|
import { SYNC_FIELDS } from '@chat-recall/engine/core/sync-fields.js';
|
|
76
77
|
import { acquireIndexLock } from '@chat-recall/engine/core/index-lock.js';
|
|
77
78
|
import { fetchWithTimeout } from './http.js';
|
|
79
|
+
import { withSessionReadCache } from '@chat-recall/engine/core/live-session-scan.js';
|
|
78
80
|
import '@chat-recall/engine/core/backends/index.js'; // register the tool backends
|
|
79
81
|
// Lives under the data dir so CHAT_RECALL_DATA_DIR isolates credentials the
|
|
80
82
|
// same way it isolates the index (tests, multi-profile setups).
|
|
@@ -107,6 +109,12 @@ export function saveCredentials(c) {
|
|
|
107
109
|
catch { /* settings unwritable — manual `chat-recall sync` still works */ }
|
|
108
110
|
}
|
|
109
111
|
export function loadAllCredentials() {
|
|
112
|
+
// A container, a CI job or a headless daemon has no credentials.json. When
|
|
113
|
+
// the environment carries an explicit token it IS the login — see
|
|
114
|
+
// credentials-env.ts for why the file is not consulted in that case.
|
|
115
|
+
const fromEnv = envCredentials();
|
|
116
|
+
if (fromEnv)
|
|
117
|
+
return [{ serverUrl: fromEnv.serverUrl, token: fromEnv.token }];
|
|
110
118
|
try {
|
|
111
119
|
const parsed = JSON.parse(readFileSync(credPath(), 'utf-8'));
|
|
112
120
|
// token may be '' for a no-auth local self-host server (AUTH_PROVIDER=none) —
|
|
@@ -340,6 +348,12 @@ export async function syncSessions(opts = {}) {
|
|
|
340
348
|
const targets = loadAllCredentials();
|
|
341
349
|
if (targets.length === 0)
|
|
342
350
|
throw new Error('Not logged in — run `chat-recall login <server-url> --token <token>`');
|
|
351
|
+
// Once per walk: forget servers we no longer sync to, so their rows stop
|
|
352
|
+
// riding along in every write of this single-file ledger.
|
|
353
|
+
try {
|
|
354
|
+
pruneLedgerTargets(targets.map((t) => t.serverUrl));
|
|
355
|
+
}
|
|
356
|
+
catch { /* never block a sync on housekeeping */ }
|
|
343
357
|
let agg = null;
|
|
344
358
|
const errors = [];
|
|
345
359
|
for (const cred of targets) {
|
|
@@ -356,6 +370,11 @@ export async function syncSessions(opts = {}) {
|
|
|
356
370
|
errors.push(`${cred.serverUrl}: ${e instanceof Error ? e.message : e}`);
|
|
357
371
|
}
|
|
358
372
|
}
|
|
373
|
+
// Ledger writes are coalesced during the walk (see persist() in sync-ledger).
|
|
374
|
+
// This is the durability point: everything acked above reaches disk before we
|
|
375
|
+
// report success, so a crash after this cannot re-ship what the server has.
|
|
376
|
+
// In the finally, because a partial walk's acks are still worth keeping.
|
|
377
|
+
flushLedger();
|
|
359
378
|
if (!agg)
|
|
360
379
|
throw new Error(`sync failed for all targets:\n ${errors.join('\n ')}`);
|
|
361
380
|
if (errors.length > 0)
|
|
@@ -582,6 +601,28 @@ export function batchScanExternal(items, opts = {}) {
|
|
|
582
601
|
}
|
|
583
602
|
return { findings, scanned, slices, scanMs };
|
|
584
603
|
}
|
|
604
|
+
/**
|
|
605
|
+
* Server API version check, cached per target for an hour.
|
|
606
|
+
*
|
|
607
|
+
* Only SUCCESS is cached. A server that is down, or too old, is re-checked on
|
|
608
|
+
* the next tick — caching a failure would turn a thirty-second outage into an
|
|
609
|
+
* hour of refusing to sync.
|
|
610
|
+
*/
|
|
611
|
+
const CAPS_TTL_MS = 60 * 60_000;
|
|
612
|
+
const capsOk = new Map(); // serverUrl -> epoch ms verified
|
|
613
|
+
export function _resetCapsCacheForTests() { capsOk.clear(); }
|
|
614
|
+
async function verifyServerApi(serverUrl, minApi) {
|
|
615
|
+
const base = serverUrl.replace(/\/$/, '');
|
|
616
|
+
const seen = capsOk.get(base);
|
|
617
|
+
if (seen !== undefined && Date.now() - seen < CAPS_TTL_MS)
|
|
618
|
+
return true;
|
|
619
|
+
const caps = await fetchWithTimeout(`${base}/api/capabilities`).then((r) => r.json());
|
|
620
|
+
if ((caps.apiVersion ?? 0) < minApi) {
|
|
621
|
+
throw new Error(`server too old: apiVersion ${caps.apiVersion ?? 'none'} < required ${minApi} — update the server image before syncing`);
|
|
622
|
+
}
|
|
623
|
+
capsOk.set(base, Date.now());
|
|
624
|
+
return true;
|
|
625
|
+
}
|
|
585
626
|
async function syncToTarget(cred, opts = {}) {
|
|
586
627
|
const sync = loadSettings().sync;
|
|
587
628
|
// Exclusions = local settings ∪ server-side tenant config (dashboard-edited).
|
|
@@ -618,16 +659,18 @@ async function syncToTarget(cred, opts = {}) {
|
|
|
618
659
|
// server ignores payload fields it doesn't know — which looks like
|
|
619
660
|
// success and produces gutted data (lived experience, June 2026).
|
|
620
661
|
const MIN_SERVER_API = 2;
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
662
|
+
{
|
|
663
|
+
// Cached for an hour per target. This ran on EVERY sync — every file-change
|
|
664
|
+
// debounce, every heartbeat, per target — to re-learn a number that changes
|
|
665
|
+
// only when the server is redeployed. The check itself stays: refusing to
|
|
666
|
+
// sync blind is the point, and an old server silently ignoring payload fields
|
|
667
|
+
// is how gutted data shipped in June 2026. Only the frequency changes.
|
|
668
|
+
//
|
|
669
|
+
// A FAILURE IS NEVER CACHED. An unreachable server must be retried on the
|
|
670
|
+
// next tick, not written off for an hour.
|
|
671
|
+
const ok = await verifyServerApi(cred.serverUrl, MIN_SERVER_API);
|
|
672
|
+
if (!ok)
|
|
673
|
+
throw new Error(`cannot verify server version — refusing to sync blind`);
|
|
631
674
|
}
|
|
632
675
|
// Fetch tenant-specific secret-scan configuration from the server. Rules are
|
|
633
676
|
// configured in the dashboard and must be applied to raw session text on the
|
|
@@ -733,10 +776,14 @@ async function syncToTarget(cred, opts = {}) {
|
|
|
733
776
|
try {
|
|
734
777
|
const body = JSON.parse(text);
|
|
735
778
|
detail = body.error ?? text;
|
|
779
|
+
// `detail` carries the part that stops this reading as breakage —
|
|
780
|
+
// what still works, and the one command that restores the rest.
|
|
781
|
+
if (body.detail)
|
|
782
|
+
detail += `\n ${body.detail}`;
|
|
736
783
|
if (body.resetsAt)
|
|
737
784
|
detail += ` (resets ${new Date(body.resetsAt).toISOString().slice(0, 10)})`;
|
|
738
785
|
if (body.upgradeUrl)
|
|
739
|
-
detail +=
|
|
786
|
+
detail += `\n ${body.upgradeUrl}`;
|
|
740
787
|
}
|
|
741
788
|
catch { /* non-JSON 402 — print as-is */ }
|
|
742
789
|
throw new Error(`sync paused by the server: ${detail}`);
|
|
@@ -954,29 +1001,50 @@ async function syncToTarget(cred, opts = {}) {
|
|
|
954
1001
|
// and redaction of everything shipped is unconditional.
|
|
955
1002
|
const scanSecrets = isSecretScannerAvailable() && upload.findings && process.env.CHAT_RECALL_SCAN_SECRETS !== '0';
|
|
956
1003
|
const verifySecretsScan = verifySecrets;
|
|
957
|
-
|
|
958
|
-
//
|
|
1004
|
+
let skipped = 0, redactions = 0, walked = 0;
|
|
1005
|
+
// ── Live KG accumulator. Triples are extracted on the spot from each item's
|
|
1006
|
+
// redacted text (no local knowledge-graph DB is read). Dedupe by
|
|
959
1007
|
// subject|predicate|object|valid_from; entity types come from `is_a`
|
|
960
1008
|
// triples seen in the same pass, defaulting to 'unknown' otherwise.
|
|
1009
|
+
//
|
|
1010
|
+
// TRIPLES SHIP IMMEDIATELY. They used to pile into an array that was drained
|
|
1011
|
+
// only after the ENTIRE walk — on this developer's box that is 15,700
|
|
1012
|
+
// sessions, so the array grew for the whole run and every row stayed live and
|
|
1013
|
+
// reachable. A full Mark-Compact freed 0 MB at 1602 MB before the daemon
|
|
1014
|
+
// aborted, which is the signature of retention, not of transient copies:
|
|
1015
|
+
// nothing transient survives a mark-compact. Handing each triple to the
|
|
1016
|
+
// batcher as it is produced bounds the resident set to one 4 MB window.
|
|
1017
|
+
//
|
|
1018
|
+
// Two small structures still span the walk, and both are bounded by DISTINCT
|
|
1019
|
+
// entity count rather than by session count:
|
|
1020
|
+
// kgSeen — dedup. Stores a 16-hex digest, because the old key
|
|
1021
|
+
// repeated all three long strings in a fourth string.
|
|
1022
|
+
// kgEntityNames — the names to emit entities for at the end. This is the
|
|
1023
|
+
// only reason the row array was ever kept; a Set of names
|
|
1024
|
+
// it already references costs a pointer, not a row.
|
|
961
1025
|
const kgSeen = new Set();
|
|
962
1026
|
const kgEntityType = new Map();
|
|
963
|
-
const
|
|
964
|
-
const
|
|
1027
|
+
const kgEntityNames = new Set();
|
|
1028
|
+
const kgKey = (subject, predicate, object, validFrom) => createHash('sha1').update(`${subject}|${predicate}|${object}|${validFrom}`).digest('hex').slice(0, 16);
|
|
1029
|
+
const accumulateKg = async (triples, sourceSession) => {
|
|
965
1030
|
for (const t of triples) {
|
|
966
|
-
const key =
|
|
1031
|
+
const key = kgKey(t.subject, t.predicate, t.object, t.validFrom ?? '');
|
|
967
1032
|
if (kgSeen.has(key))
|
|
968
1033
|
continue;
|
|
969
1034
|
kgSeen.add(key);
|
|
970
1035
|
if (t.predicate === 'is_a' && !kgEntityType.has(t.subject))
|
|
971
1036
|
kgEntityType.set(t.subject, t.object);
|
|
972
|
-
|
|
1037
|
+
kgEntityNames.add(t.subject);
|
|
1038
|
+
kgEntityNames.add(t.object);
|
|
1039
|
+
const count = { redactions: 0 };
|
|
1040
|
+
await kgTripleBatch.add(redactDeep({
|
|
973
1041
|
subject: t.subject, predicate: t.predicate, object: t.object,
|
|
974
1042
|
valid_from: t.validFrom ?? null, valid_to: null,
|
|
975
1043
|
confidence: t.confidence ?? 1.0, source_session: sourceSession,
|
|
976
|
-
});
|
|
1044
|
+
}, count));
|
|
1045
|
+
redactions += count.redactions;
|
|
977
1046
|
}
|
|
978
1047
|
};
|
|
979
|
-
let skipped = 0, redactions = 0, walked = 0;
|
|
980
1048
|
let scanMs = 0, scanned = 0; // secret-scan metrics
|
|
981
1049
|
const slice = refs.slice(0, opts.limit ?? refs.length);
|
|
982
1050
|
// CHAT_RECALL_SYNC_TRACE=1: phase + progress markers with heap usage, to
|
|
@@ -1214,7 +1282,7 @@ async function syncToTarget(cred, opts = {}) {
|
|
|
1214
1282
|
// Knowledge graph: extract triples live from the redacted conversation
|
|
1215
1283
|
// text (no local KG DB is read). Accumulated + deduped, flushed at the end.
|
|
1216
1284
|
if (upload.sessionMeta) {
|
|
1217
|
-
accumulateKg(extractEntities(built.kgText, { projectPath: built.projectPath, sourceType: 'session', sessionId: ref.prefixedId, validFrom: ref.mtime ? new Date(ref.mtime).toISOString().slice(0, 10) : undefined }), ref.prefixedId);
|
|
1285
|
+
await accumulateKg(extractEntities(built.kgText, { projectPath: built.projectPath, sourceType: 'session', sessionId: ref.prefixedId, validFrom: ref.mtime ? new Date(ref.mtime).toISOString().slice(0, 10) : undefined }), ref.prefixedId);
|
|
1218
1286
|
}
|
|
1219
1287
|
// Derived data — the CLI has the FS/git/transcript, the server doesn't.
|
|
1220
1288
|
// Always computed live (diff/outcome/commits/markers + badge row); no
|
|
@@ -1326,7 +1394,7 @@ async function syncToTarget(cred, opts = {}) {
|
|
|
1326
1394
|
});
|
|
1327
1395
|
// KG: extract triples live from this item's redacted chunk text.
|
|
1328
1396
|
if (upload.sessionMeta && redactedChunks.length > 0) {
|
|
1329
|
-
accumulateKg(extractEntities(redactedChunks.map((c) => c.text).join('\n'), { projectPath: item.projectPath || '', sourceType: item.sourceType, validFrom: item.mtime ? new Date(Number(item.mtime)).toISOString().slice(0, 10) : undefined }), null);
|
|
1397
|
+
await accumulateKg(extractEntities(redactedChunks.map((c) => c.text).join('\n'), { projectPath: item.projectPath || '', sourceType: item.sourceType, validFrom: item.mtime ? new Date(Number(item.mtime)).toISOString().slice(0, 10) : undefined }), null);
|
|
1330
1398
|
}
|
|
1331
1399
|
try {
|
|
1332
1400
|
for (const l of await source.extractLinks(item)) {
|
|
@@ -1355,16 +1423,12 @@ async function syncToTarget(cred, opts = {}) {
|
|
|
1355
1423
|
// also the incremental-correct set: no manual-fact replay, no local KG
|
|
1356
1424
|
// DB). Entities are derived from the triple subjects/objects, typed from
|
|
1357
1425
|
// any `is_a` triple seen in the same pass.
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
entityNames.add(t.subject);
|
|
1365
|
-
entityNames.add(t.object);
|
|
1366
|
-
}
|
|
1367
|
-
for (const name of entityNames) {
|
|
1426
|
+
// Triples already shipped inside accumulateKg (see above). Entities cannot:
|
|
1427
|
+
// a name's type comes from an `is_a` triple that may appear in any later
|
|
1428
|
+
// session, so the type is only known once the walk is over. The names are
|
|
1429
|
+
// held as a Set, bounded by distinct entities rather than by session count.
|
|
1430
|
+
if (upload.sessionMeta && kgEntityNames.size > 0) {
|
|
1431
|
+
for (const name of kgEntityNames) {
|
|
1368
1432
|
const count = { redactions: 0 };
|
|
1369
1433
|
await kgEntityBatch.add(redactDeep({ name, type: kgEntityType.get(name) ?? 'unknown', properties: {} }, count));
|
|
1370
1434
|
redactions += count.redactions;
|
|
@@ -1880,73 +1944,78 @@ function collectDerived(ref, mtime, count) {
|
|
|
1880
1944
|
const id = ref.prefixedId;
|
|
1881
1945
|
const compute = [];
|
|
1882
1946
|
let fullOutcome = null;
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
else if (kind === 'commits') {
|
|
1897
|
-
// computeOutcome already ran git for the session window — reuse.
|
|
1898
|
-
if (!fullOutcome)
|
|
1947
|
+
// One read of this transcript instead of four. replay, computeOutcome (twice
|
|
1948
|
+
// internally) and extractTurns each re-read the whole file; the scope holds
|
|
1949
|
+
// exactly one session's text and drops it on the way out.
|
|
1950
|
+
return withSessionReadCache(() => {
|
|
1951
|
+
for (const kind of COMPUTE_KINDS) {
|
|
1952
|
+
let data = null;
|
|
1953
|
+
try {
|
|
1954
|
+
if (kind === 'diff') {
|
|
1955
|
+
const replay = replaySessionAny(id);
|
|
1956
|
+
if (replay.found)
|
|
1957
|
+
data = replay;
|
|
1958
|
+
}
|
|
1959
|
+
else if (kind === 'outcome') {
|
|
1899
1960
|
fullOutcome = computeOutcome(id);
|
|
1900
|
-
|
|
1901
|
-
|
|
1961
|
+
if (fullOutcome.found)
|
|
1962
|
+
data = fullOutcome;
|
|
1963
|
+
}
|
|
1964
|
+
else if (kind === 'commits') {
|
|
1965
|
+
// computeOutcome already ran git for the session window — reuse.
|
|
1966
|
+
if (!fullOutcome)
|
|
1967
|
+
fullOutcome = computeOutcome(id);
|
|
1968
|
+
if (fullOutcome.found)
|
|
1969
|
+
data = fullOutcome.commits;
|
|
1970
|
+
}
|
|
1971
|
+
else if (kind === 'markers') {
|
|
1972
|
+
// Analysis-only use of the turns extractor (R4) — markers need
|
|
1973
|
+
// per-prompt line/ts, not render fidelity.
|
|
1974
|
+
const turns = extractTurnsAny(id, { maxTurns: 50_000 });
|
|
1975
|
+
const prompts = turns.turns
|
|
1976
|
+
.filter((t) => t.kind === 'user' && t.text)
|
|
1977
|
+
.map((t) => ({ line: t.line, ts: t.ts, tsIso: t.tsIso, ...markPrompt(t.text) }));
|
|
1978
|
+
data = { sessionId: id, prompts, summary: summarizeMarkers(prompts) };
|
|
1979
|
+
}
|
|
1902
1980
|
}
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
// per-prompt line/ts, not render fidelity.
|
|
1906
|
-
const turns = extractTurnsAny(id, { maxTurns: 50_000 });
|
|
1907
|
-
const prompts = turns.turns
|
|
1908
|
-
.filter((t) => t.kind === 'user' && t.text)
|
|
1909
|
-
.map((t) => ({ line: t.line, ts: t.ts, tsIso: t.tsIso, ...markPrompt(t.text) }));
|
|
1910
|
-
data = { sessionId: id, prompts, summary: summarizeMarkers(prompts) };
|
|
1981
|
+
catch {
|
|
1982
|
+
data = null;
|
|
1911
1983
|
}
|
|
1984
|
+
if (data === null)
|
|
1985
|
+
continue;
|
|
1986
|
+
const redacted = redactDeep(data, count);
|
|
1987
|
+
if (JSON.stringify(redacted).length > MAX_DERIVED_ROW_BYTES)
|
|
1988
|
+
continue;
|
|
1989
|
+
compute.push({ kind, mtime, data: redacted });
|
|
1912
1990
|
}
|
|
1913
|
-
|
|
1914
|
-
|
|
1991
|
+
// Outcome-badge row (session_outcome_cache) — what the list badges read.
|
|
1992
|
+
// Computed live from the outcome we already ran above.
|
|
1993
|
+
let outcomeRow = null;
|
|
1994
|
+
if (fullOutcome?.found) {
|
|
1995
|
+
outcomeRow = {
|
|
1996
|
+
sessionId: id,
|
|
1997
|
+
tool: ref.toolId,
|
|
1998
|
+
status: fullOutcome.status,
|
|
1999
|
+
reason: fullOutcome.reason,
|
|
2000
|
+
fileMtime: mtime,
|
|
2001
|
+
fileSize: 0,
|
|
2002
|
+
contentHash: '',
|
|
2003
|
+
fileCount: fullOutcome.fileCount,
|
|
2004
|
+
linesAdded: fullOutcome.totalLinesAdded,
|
|
2005
|
+
linesRemoved: fullOutcome.totalLinesRemoved,
|
|
2006
|
+
commits: fullOutcome.commits?.totalCommits ?? 0,
|
|
2007
|
+
isFull: true,
|
|
2008
|
+
classifiedAt: Date.now(),
|
|
2009
|
+
lastScannedOffset: 0,
|
|
2010
|
+
};
|
|
1915
2011
|
}
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
compute.push({ kind, mtime, data: redacted });
|
|
1922
|
-
}
|
|
1923
|
-
// Outcome-badge row (session_outcome_cache) — what the list badges read.
|
|
1924
|
-
// Computed live from the outcome we already ran above.
|
|
1925
|
-
let outcomeRow = null;
|
|
1926
|
-
if (fullOutcome?.found) {
|
|
1927
|
-
outcomeRow = {
|
|
1928
|
-
sessionId: id,
|
|
1929
|
-
tool: ref.toolId,
|
|
1930
|
-
status: fullOutcome.status,
|
|
1931
|
-
reason: fullOutcome.reason,
|
|
1932
|
-
fileMtime: mtime,
|
|
1933
|
-
fileSize: 0,
|
|
1934
|
-
contentHash: '',
|
|
1935
|
-
fileCount: fullOutcome.fileCount,
|
|
1936
|
-
linesAdded: fullOutcome.totalLinesAdded,
|
|
1937
|
-
linesRemoved: fullOutcome.totalLinesRemoved,
|
|
1938
|
-
commits: fullOutcome.commits?.totalCommits ?? 0,
|
|
1939
|
-
isFull: true,
|
|
1940
|
-
classifiedAt: Date.now(),
|
|
1941
|
-
lastScannedOffset: 0,
|
|
2012
|
+
return {
|
|
2013
|
+
session_id: id,
|
|
2014
|
+
mtime,
|
|
2015
|
+
compute,
|
|
2016
|
+
outcome_row: outcomeRow ? redactDeep({ ...outcomeRow, sessionId: undefined }, count) : null,
|
|
1942
2017
|
};
|
|
1943
|
-
}
|
|
1944
|
-
return {
|
|
1945
|
-
session_id: id,
|
|
1946
|
-
mtime,
|
|
1947
|
-
compute,
|
|
1948
|
-
outcome_row: outcomeRow ? redactDeep({ ...outcomeRow, sessionId: undefined }, count) : null,
|
|
1949
|
-
};
|
|
2018
|
+
});
|
|
1950
2019
|
}
|
|
1951
2020
|
export function isSyncSkip(r) {
|
|
1952
2021
|
return typeof r.skipped === 'string';
|