chat-recall 0.0.1 → 0.4.8

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.
Files changed (94) hide show
  1. package/LICENSE +93 -0
  2. package/dist/auto-update.d.ts +52 -0
  3. package/dist/auto-update.d.ts.map +1 -0
  4. package/dist/auto-update.js +157 -0
  5. package/dist/auto-update.js.map +1 -0
  6. package/dist/cli.d.ts +6 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +26102 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/client-events.d.ts +11 -0
  11. package/dist/client-events.d.ts.map +1 -0
  12. package/dist/client-events.js +77 -0
  13. package/dist/client-events.js.map +1 -0
  14. package/dist/collector-migrate.d.ts +27 -0
  15. package/dist/collector-migrate.d.ts.map +1 -0
  16. package/dist/collector-migrate.js +60 -0
  17. package/dist/collector-migrate.js.map +1 -0
  18. package/dist/device-auth.d.ts +37 -0
  19. package/dist/device-auth.d.ts.map +1 -0
  20. package/dist/device-auth.js +161 -0
  21. package/dist/device-auth.js.map +1 -0
  22. package/dist/escalate.d.ts +99 -0
  23. package/dist/escalate.d.ts.map +1 -0
  24. package/dist/escalate.js +219 -0
  25. package/dist/escalate.js.map +1 -0
  26. package/dist/http.d.ts +14 -0
  27. package/dist/http.d.ts.map +1 -0
  28. package/dist/http.js +49 -0
  29. package/dist/http.js.map +1 -0
  30. package/dist/install-skills.d.ts +51 -0
  31. package/dist/install-skills.d.ts.map +1 -0
  32. package/dist/install-skills.js +223 -0
  33. package/dist/install-skills.js.map +1 -0
  34. package/dist/intent-drain.d.ts +25 -0
  35. package/dist/intent-drain.d.ts.map +1 -0
  36. package/dist/intent-drain.js +189 -0
  37. package/dist/intent-drain.js.map +1 -0
  38. package/dist/keyring.d.ts +28 -0
  39. package/dist/keyring.d.ts.map +1 -0
  40. package/dist/keyring.js +163 -0
  41. package/dist/keyring.js.map +1 -0
  42. package/dist/mcp.d.ts +8 -0
  43. package/dist/mcp.d.ts.map +1 -0
  44. package/dist/mcp.js +23665 -0
  45. package/dist/mcp.js.map +1 -0
  46. package/dist/project-tasks.d.ts +54 -0
  47. package/dist/project-tasks.d.ts.map +1 -0
  48. package/dist/project-tasks.js +204 -0
  49. package/dist/project-tasks.js.map +1 -0
  50. package/dist/repair.d.ts +73 -0
  51. package/dist/repair.d.ts.map +1 -0
  52. package/dist/repair.js +267 -0
  53. package/dist/repair.js.map +1 -0
  54. package/dist/self-restart.d.ts +91 -0
  55. package/dist/self-restart.d.ts.map +1 -0
  56. package/dist/self-restart.js +137 -0
  57. package/dist/self-restart.js.map +1 -0
  58. package/dist/service-installer.d.ts +32 -0
  59. package/dist/service-installer.d.ts.map +1 -0
  60. package/dist/service-installer.js +231 -0
  61. package/dist/service-installer.js.map +1 -0
  62. package/dist/sync-client.d.ts +234 -0
  63. package/dist/sync-client.d.ts.map +1 -0
  64. package/dist/sync-client.js +1985 -0
  65. package/dist/sync-client.js.map +1 -0
  66. package/dist/sync-ledger.d.ts +131 -0
  67. package/dist/sync-ledger.d.ts.map +1 -0
  68. package/dist/sync-ledger.js +366 -0
  69. package/dist/sync-ledger.js.map +1 -0
  70. package/dist/update-notice.d.ts +16 -0
  71. package/dist/update-notice.d.ts.map +1 -0
  72. package/dist/update-notice.js +107 -0
  73. package/dist/update-notice.js.map +1 -0
  74. package/dist/verify-deep.d.ts +79 -0
  75. package/dist/verify-deep.d.ts.map +1 -0
  76. package/dist/verify-deep.js +97 -0
  77. package/dist/verify-deep.js.map +1 -0
  78. package/dist/verify-repair.d.ts +21 -0
  79. package/dist/verify-repair.d.ts.map +1 -0
  80. package/dist/verify-repair.js +58 -0
  81. package/dist/verify-repair.js.map +1 -0
  82. package/dist/watch.js +21550 -0
  83. package/hooks/chat_recall_escalate_hook.sh +51 -0
  84. package/hooks/chat_recall_resume_hook.sh +69 -0
  85. package/hooks/chat_recall_save_hook.sh +254 -0
  86. package/hooks/chat_recall_wakeup_hook.sh +39 -0
  87. package/package.json +38 -4
  88. package/skills/chat-recall/SKILL.md +76 -0
  89. package/skills/chat-recall-changes/SKILL.md +50 -0
  90. package/skills/chat-recall-find/SKILL.md +64 -0
  91. package/skills/chat-recall-memory/SKILL.md +55 -0
  92. package/skills/chat-recall-project/SKILL.md +75 -0
  93. package/skills/chat-recall-resume/SKILL.md +62 -0
  94. package/README.md +0 -7
@@ -0,0 +1,97 @@
1
+ /**
2
+ * `chat-recall verify --deep` — does the server actually hold what this machine
3
+ * has, per session?
4
+ *
5
+ * Every silent-loss incident in this codebase was found by a human asking about
6
+ * one specific session. Nothing reported them, because every symptom looks like
7
+ * healthy operation: `15604 skipped` is what a fully-synced corpus prints too.
8
+ * This is the check that turns "did session X make it?" from an investigation
9
+ * into a command.
10
+ *
11
+ * It compares in the unit the server's shrink guard uses — `gzipContainer().size`
12
+ * of the local union versus the archive's stored `size` — so a difference means
13
+ * the server is genuinely missing records, not that two measurements disagree.
14
+ * Sub-unit noise is ignored via a tolerance.
15
+ *
16
+ * Both sides must be the REDACTED container (see Deps.localContainerSize): the
17
+ * archive stores what was shipped, and what was shipped had its secrets
18
+ * replaced by sentinels.
19
+ *
20
+ * Deliberately NOT an mtime comparison: the server stores the client-sent mtime,
21
+ * which drifts sub-second against the file for essentially every session. An
22
+ * mtime-based version of this check reported 9,975 of 10,032 sessions suspect
23
+ * when the true number was 13.
24
+ *
25
+ * Classification matters as much as detection:
26
+ * pending — the ledger knows there is more to send; it will go on its own
27
+ * STRANDED — the ledger claims complete while the server holds less, so
28
+ * nothing will ever re-ship it. This is the actionable class.
29
+ */
30
+ import { loadAllCredentials } from './sync-client.js';
31
+ import { getSyncedRows } from './sync-ledger.js';
32
+ /** Below this, a size difference is container-encoding noise rather than
33
+ * missing records. */
34
+ const TOLERANCE_BYTES = 512;
35
+ /**
36
+ * A session written within this window is being TYPED INTO. Its bytes grow
37
+ * between the cursor read and the container build, so `cursor >= fileSize`
38
+ * momentarily holds for a session that is simply mid-flight — and it gets
39
+ * reported as stranded on every run.
40
+ *
41
+ * This is not theoretical: the first real run flagged the live session it was
42
+ * being run from, short by 902 bytes. A checker that always cries wolf about the
43
+ * session you are in is a checker people learn to ignore, so recent writes are
44
+ * classified `pending` regardless of what the cursor says.
45
+ */
46
+ const LIVE_GRACE_MS = 10 * 60_000;
47
+ /**
48
+ * Pure comparison, injectable so it can be tested without a server or a real
49
+ * transcript corpus.
50
+ */
51
+ export async function verifyAgainstServer(server, token, sinceMs, deps, now = Date.now()) {
52
+ const serverSize = await deps.serverSizes(server, token);
53
+ const ledger = getSyncedRows(server);
54
+ const report = {
55
+ server, checked: 0, complete: 0, missingArchive: 0, pending: [], stranded: [],
56
+ };
57
+ for (const s of deps.listSessions(sinceMs)) {
58
+ const srv = serverSize.get(s.rawId);
59
+ if (srv === undefined) {
60
+ report.missingArchive++;
61
+ continue;
62
+ }
63
+ const local = deps.localContainerSize(s.rawId);
64
+ if (local === null)
65
+ continue; // unreadable/unparseable — not a finding
66
+ report.checked++;
67
+ const deficit = local - srv;
68
+ if (deficit <= TOLERANCE_BYTES) {
69
+ report.complete++;
70
+ continue;
71
+ }
72
+ // The ledger's `s` is the server's confirmed byte cursor. If it is at or
73
+ // past the local file size, the client believes there is nothing left to
74
+ // send — so this session will never re-ship on its own.
75
+ const row = ledger.get(s.prefixedId) ?? ledger.get(s.rawId);
76
+ const cursor = row?.s ?? 0;
77
+ const live = s.mtime >= now - LIVE_GRACE_MS;
78
+ const stranded = !live && !!row && cursor >= deps.fileSize(s.rawId);
79
+ const finding = {
80
+ sessionId: s.rawId,
81
+ projectPath: s.projectPath || '',
82
+ localSize: local,
83
+ serverSize: srv,
84
+ deficit,
85
+ stranded,
86
+ };
87
+ (stranded ? report.stranded : report.pending).push(finding);
88
+ }
89
+ report.stranded.sort((a, b) => b.deficit - a.deficit);
90
+ report.pending.sort((a, b) => b.deficit - a.deficit);
91
+ return report;
92
+ }
93
+ /** Every configured target, so a multi-server setup is verified as a whole. */
94
+ export function verifyTargets() {
95
+ return loadAllCredentials().map((c) => ({ serverUrl: c.serverUrl.replace(/\/+$/, ''), token: c.token }));
96
+ }
97
+ //# sourceMappingURL=verify-deep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-deep.js","sourceRoot":"","sources":["../src/verify-deep.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Un-strand sessions found by `chat-recall verify --deep`.
3
+ *
4
+ * A stranded session is one whose ledger cursor says "the server has all of
5
+ * this" while the server demonstrably has less. Nothing re-ships it, because
6
+ * `syncMode` reads that cursor and returns SKIP. Clearing the cursor is what
7
+ * puts it back in the queue — the next sync then re-derives and re-ships from
8
+ * scratch.
9
+ *
10
+ * Only the CURSOR is cleared, not the whole row: per-field coverage (`f`) is
11
+ * owned by field reconciliation and dropping it would make every field re-scan
12
+ * from zero. The mtime is cleared too, since leaving it would let the
13
+ * mtime-unchanged branch SKIP the session straight back out again.
14
+ *
15
+ * Writes a timestamped backup first. This edits the file that decides what gets
16
+ * uploaded, and a bad edit here re-ships a 10k-session corpus.
17
+ */
18
+ /** Clear the sync cursor for `sessionIds` on `server`. Returns how many rows
19
+ * were actually cleared (ids with no ledger entry need no work). */
20
+ export declare function forceFullResync(server: string, sessionIds: string[]): number;
21
+ //# sourceMappingURL=verify-repair.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-repair.d.ts","sourceRoot":"","sources":["../src/verify-repair.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH;qEACqE;AACrE,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,CA6B5E"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Un-strand sessions found by `chat-recall verify --deep`.
3
+ *
4
+ * A stranded session is one whose ledger cursor says "the server has all of
5
+ * this" while the server demonstrably has less. Nothing re-ships it, because
6
+ * `syncMode` reads that cursor and returns SKIP. Clearing the cursor is what
7
+ * puts it back in the queue — the next sync then re-derives and re-ships from
8
+ * scratch.
9
+ *
10
+ * Only the CURSOR is cleared, not the whole row: per-field coverage (`f`) is
11
+ * owned by field reconciliation and dropping it would make every field re-scan
12
+ * from zero. The mtime is cleared too, since leaving it would let the
13
+ * mtime-unchanged branch SKIP the session straight back out again.
14
+ *
15
+ * Writes a timestamped backup first. This edits the file that decides what gets
16
+ * uploaded, and a bad edit here re-ships a 10k-session corpus.
17
+ */
18
+ import { copyFileSync, existsSync } from 'fs';
19
+ import { getLedgerData, persistLedgerData, ledgerFilePath } from './sync-ledger.js';
20
+ /** Clear the sync cursor for `sessionIds` on `server`. Returns how many rows
21
+ * were actually cleared (ids with no ledger entry need no work). */
22
+ export function forceFullResync(server, sessionIds) {
23
+ if (sessionIds.length === 0)
24
+ return 0;
25
+ const path = ledgerFilePath();
26
+ if (existsSync(path)) {
27
+ const stamp = new Date().toISOString().replace(/[:.]/g, '').replace(/-/g, '');
28
+ try {
29
+ copyFileSync(path, `${path}.bak-${stamp}`);
30
+ }
31
+ catch { /* backup best-effort */ }
32
+ }
33
+ const data = getLedgerData(server);
34
+ const wanted = new Set(sessionIds);
35
+ let cleared = 0;
36
+ for (const key of Object.keys(data)) {
37
+ // Ledger keys are prefixed ids for non-Claude tools; match either form.
38
+ const bare = key.replace(/^(opencode_|gemini_|codex_|agy_)/, '');
39
+ if (!wanted.has(key) && !wanted.has(bare))
40
+ continue;
41
+ const row = data[key];
42
+ if (typeof row !== 'object' || row === null) {
43
+ delete data[key];
44
+ cleared++;
45
+ continue;
46
+ }
47
+ const r = row;
48
+ delete r.o; // byte cursor
49
+ delete r.s; // synced-through size
50
+ delete r.h; // content hash — else the "unchanged" fast path skips again
51
+ delete r.m; // mtime — else the mtime-unchanged branch skips again
52
+ cleared++;
53
+ }
54
+ if (cleared > 0)
55
+ persistLedgerData(server, data);
56
+ return cleared;
57
+ }
58
+ //# sourceMappingURL=verify-repair.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-repair.js","sourceRoot":"","sources":["../src/verify-repair.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEpF;qEACqE;AACrE,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,UAAoB;IAClE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAEtC,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;IAC9B,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC9E,IAAI,CAAC;YAAC,YAAY,CAAC,IAAI,EAAE,GAAG,IAAI,QAAQ,KAAK,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,wBAAwB,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IACnC,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,wEAAwE;QACxE,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,kCAAkC,EAAE,EAAE,CAAC,CAAC;QACjE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACtB,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;YAAC,OAAO,EAAE,CAAC;YAAC,SAAS;QAAC,CAAC;QACvF,MAAM,CAAC,GAAG,GAAyC,CAAC;QACpD,OAAO,CAAC,CAAC,CAAC,CAAC,CAAM,cAAc;QAC/B,OAAO,CAAC,CAAC,CAAC,CAAC,CAAM,sBAAsB;QACvC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAM,4DAA4D;QAC7E,OAAO,CAAC,CAAC,CAAC,CAAC,CAAM,sDAAsD;QACvE,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,OAAO,GAAG,CAAC;QAAE,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACjD,OAAO,OAAO,CAAC;AACjB,CAAC"}