chat-recall 0.7.0 → 0.7.2

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.
@@ -1,8 +1,25 @@
1
- /** workspace path → epoch ms of the last COMPLETED index. */
2
- export type CodeIndexCursor = Record<string, number>;
1
+ /** One completed index: when, and the workspace fingerprint it saw. */
2
+ export interface CursorEntry {
3
+ at: number;
4
+ fp?: string;
5
+ }
6
+ /** workspace path → the last COMPLETED index. */
7
+ export type CodeIndexCursor = Record<string, CursorEntry>;
3
8
  export declare function readCursor(): CodeIndexCursor;
4
9
  /** Record a COMPLETED index. Never called for a failure — see the header. */
5
- export declare function noteIndexed(workspace: string, now?: number): void;
10
+ export declare function noteIndexed(workspace: string, now?: number, fp?: string | null): void;
11
+ /**
12
+ * What the code in a git workspace is right now: HEAD, plus each changed or
13
+ * untracked file with its size and mtime, plus the collector's own version so
14
+ * a new result format rescans everything. Null when the workspace is not a git
15
+ * repository or git does not answer; such a workspace is scanned every pass.
16
+ */
17
+ export declare function workspaceFingerprint(workspace: string, collectorVersion: number): string | null;
18
+ /** An unchanged workspace is still sent again after this long. The collector
19
+ * cannot see the server's copy, and a server that lost it gets it back. */
20
+ export declare const UNCHANGED_RESEND_MS: number;
21
+ /** True when the last completed index saw this same fingerprint recently. */
22
+ export declare function isUnchangedSinceIndexed(workspace: string, fp: string | null, cursor: CodeIndexCursor, now?: number): boolean;
6
23
  /**
7
24
  * Order workspaces least-recently-indexed first, so a sweep that keeps getting
8
25
  * interrupted still eventually covers everything.
@@ -1 +1 @@
1
- {"version":3,"file":"code-index-cursor.d.ts","sourceRoot":"","sources":["../src/code-index-cursor.ts"],"names":[],"mappings":"AA8BA,6DAA6D;AAC7D,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAErD,wBAAgB,UAAU,IAAI,eAAe,CAY5C;AAUD,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,IAAI,CAMrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,MAAM,kBAAe,GAAG,MAAM,EAAE,CAKtF;AAED,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAQjD"}
1
+ {"version":3,"file":"code-index-cursor.d.ts","sourceRoot":"","sources":["../src/code-index-cursor.ts"],"names":[],"mappings":"AAkCA,uEAAuE;AACvE,MAAM,WAAW,WAAW;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE;AAExD,iDAAiD;AACjD,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAE1D,wBAAgB,UAAU,IAAI,eAAe,CAiB5C;AAUD,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,SAAa,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAIzF;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkB/F;AAED;4EAC4E;AAC5E,eAAO,MAAM,mBAAmB,QAAuB,CAAC;AAExD,6EAA6E;AAC7E,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,SAAa,GAAG,OAAO,CAGhI;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,MAAM,kBAAe,GAAG,MAAM,EAAE,CAKtF;AAED,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAQjD"}
@@ -16,13 +16,17 @@
16
16
  * which is what this cursor provides.
17
17
  *
18
18
  * ── Shape ────────────────────────────────────────────────────────────────
19
- * A tiny JSON map of workspace path → last successful index. Best-effort in both
19
+ * A tiny JSON map of workspace path → last successful index (its time and the
20
+ * workspace fingerprint it saw, so a pass skips code that did not change).
21
+ * Best-effort in both
20
22
  * directions: a missing or corrupt file just means "nothing indexed yet", and a
21
23
  * write that fails is ignored. It records COMPLETIONS only, so a workspace that
22
24
  * crashes the indexer is retried rather than being marked done — the opposite
23
25
  * choice would silently drop a repo forever.
24
26
  */
25
- import { readFileSync, writeFileSync, mkdirSync } from 'fs';
27
+ import { readFileSync, writeFileSync, mkdirSync, statSync } from 'fs';
28
+ import { execFileSync } from 'child_process';
29
+ import { createHash } from 'crypto';
26
30
  import { join, dirname } from 'path';
27
31
  import { getDataDir } from '@chat-recall/engine/core/paths.js';
28
32
  const cursorPath = () => join(getDataDir(), 'code-index-cursor.json');
@@ -32,8 +36,13 @@ export function readCursor() {
32
36
  if (raw && typeof raw === 'object' && !Array.isArray(raw)) {
33
37
  const out = {};
34
38
  for (const [k, v] of Object.entries(raw)) {
39
+ // A bare number is the file an earlier version wrote: a time, no fingerprint.
35
40
  if (typeof v === 'number' && Number.isFinite(v))
36
- out[k] = v;
41
+ out[k] = { at: v };
42
+ else if (v && typeof v === 'object' && typeof v.at === 'number' && Number.isFinite(v.at)) {
43
+ const fp = v.fp;
44
+ out[k] = typeof fp === 'string' ? { at: v.at, fp } : { at: v.at };
45
+ }
37
46
  }
38
47
  return out;
39
48
  }
@@ -50,13 +59,49 @@ function writeCursor(c) {
50
59
  catch { /* housekeeping must never fail a sweep */ }
51
60
  }
52
61
  /** Record a COMPLETED index. Never called for a failure — see the header. */
53
- export function noteIndexed(workspace, now = Date.now()) {
62
+ export function noteIndexed(workspace, now = Date.now(), fp) {
54
63
  const c = readCursor();
55
- c[workspace] = now;
56
- // Forget paths that are no longer candidates, so a machine that has moved on
57
- // does not carry a growing map of dead repos forever.
64
+ c[workspace] = fp ? { at: now, fp } : { at: now };
58
65
  writeCursor(c);
59
66
  }
67
+ /**
68
+ * What the code in a git workspace is right now: HEAD, plus each changed or
69
+ * untracked file with its size and mtime, plus the collector's own version so
70
+ * a new result format rescans everything. Null when the workspace is not a git
71
+ * repository or git does not answer; such a workspace is scanned every pass.
72
+ */
73
+ export function workspaceFingerprint(workspace, collectorVersion) {
74
+ try {
75
+ const git = (args) => execFileSync('git', ['-C', workspace, ...args], { encoding: 'utf-8', timeout: 10_000, maxBuffer: 16 * 1024 * 1024, stdio: ['ignore', 'pipe', 'ignore'] });
76
+ const head = git(['rev-parse', 'HEAD']).trim();
77
+ const status = git(['status', '--porcelain=v1', '-z', '--untracked-files=all']);
78
+ const h = createHash('sha256').update(`v${collectorVersion}\0${head}\0`);
79
+ for (const entry of status.split('\0')) {
80
+ if (entry.length < 4)
81
+ continue;
82
+ const rel = entry.slice(3);
83
+ let stamp = 'gone';
84
+ try {
85
+ const s = statSync(join(workspace, rel));
86
+ stamp = `${s.size}:${Math.floor(s.mtimeMs)}`;
87
+ }
88
+ catch { /* deleted */ }
89
+ h.update(`${entry.slice(0, 2)}\0${rel}\0${stamp}\0`);
90
+ }
91
+ return h.digest('hex');
92
+ }
93
+ catch {
94
+ return null;
95
+ }
96
+ }
97
+ /** An unchanged workspace is still sent again after this long. The collector
98
+ * cannot see the server's copy, and a server that lost it gets it back. */
99
+ export const UNCHANGED_RESEND_MS = 7 * 24 * 3600 * 1000;
100
+ /** True when the last completed index saw this same fingerprint recently. */
101
+ export function isUnchangedSinceIndexed(workspace, fp, cursor, now = Date.now()) {
102
+ const e = cursor[workspace];
103
+ return !!fp && !!e && e.fp === fp && now - e.at < UNCHANGED_RESEND_MS;
104
+ }
60
105
  /**
61
106
  * Order workspaces least-recently-indexed first, so a sweep that keeps getting
62
107
  * interrupted still eventually covers everything.
@@ -68,7 +113,7 @@ export function noteIndexed(workspace, now = Date.now()) {
68
113
  */
69
114
  export function orderByStaleness(workspaces, cursor = readCursor()) {
70
115
  return workspaces
71
- .map((w, i) => ({ w, i, at: cursor[w] ?? -1 }))
116
+ .map((w, i) => ({ w, i, at: cursor[w]?.at ?? -1 }))
72
117
  .sort((a, b) => (a.at - b.at) || (a.i - b.i))
73
118
  .map((e) => e.w);
74
119
  }
@@ -1 +1 @@
1
- {"version":3,"file":"code-index-cursor.js","sourceRoot":"","sources":["../src/code-index-cursor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"code-index-cursor.js","sourceRoot":"","sources":["../src/code-index-cursor.ts"],"names":[],"mappings":"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"}
package/dist/mcp-relay.js CHANGED
@@ -117,8 +117,82 @@ function daemonEnabled() {
117
117
  return t === "" || t === "0" || t === "false";
118
118
  }
119
119
 
120
+ // src/relay-lifecycle.ts
121
+ var PARENT_POLL_MS = 5e3;
122
+ function pidAlive(pid) {
123
+ try {
124
+ process.kill(pid, 0);
125
+ return true;
126
+ } catch (err) {
127
+ return err.code === "EPERM";
128
+ }
129
+ }
130
+ var processProbe = {
131
+ ppid: () => process.ppid,
132
+ alive: pidAlive
133
+ };
134
+ function parentGone(originalPpid, probe) {
135
+ if (probe.ppid() !== originalPpid) return true;
136
+ return !probe.alive(originalPpid);
137
+ }
138
+ function watchParent(onGone, opts = {}) {
139
+ const probe = opts.probe ?? processProbe;
140
+ const original = probe.ppid();
141
+ if (original <= 1) return () => {
142
+ };
143
+ const timer = setInterval(() => {
144
+ if (!parentGone(original, probe)) return;
145
+ clearInterval(timer);
146
+ onGone();
147
+ }, opts.intervalMs ?? PARENT_POLL_MS);
148
+ timer.unref?.();
149
+ return () => clearInterval(timer);
150
+ }
151
+ function onInputFinished(input, onEnd) {
152
+ let fired = false;
153
+ const fire = () => {
154
+ if (fired) return;
155
+ fired = true;
156
+ onEnd();
157
+ };
158
+ input.once("end", fire);
159
+ input.once("close", fire);
160
+ input.once("error", fire);
161
+ }
162
+ function bridge(input, output, sock, exit, opts = {}) {
163
+ let done = false;
164
+ let stopParentWatch = () => {
165
+ };
166
+ const finish = () => {
167
+ if (done) return;
168
+ done = true;
169
+ stopParentWatch();
170
+ try {
171
+ sock.destroy();
172
+ } catch {
173
+ }
174
+ exit(0);
175
+ };
176
+ input.pipe(sock);
177
+ sock.pipe(output);
178
+ sock.on("close", finish);
179
+ sock.on("error", finish);
180
+ output.on("error", finish);
181
+ onInputFinished(input, () => {
182
+ try {
183
+ sock.end();
184
+ } catch {
185
+ finish();
186
+ return;
187
+ }
188
+ const t = setTimeout(finish, opts.drainMs ?? 2e3);
189
+ t.unref?.();
190
+ });
191
+ stopParentWatch = watchParent(finish, { probe: opts.probe, intervalMs: opts.parentPollMs });
192
+ }
193
+
120
194
  // src/mcp-relay.ts
121
- var VERSION = true ? "0.7.0" : "0.0.0";
195
+ var VERSION = true ? "0.7.2" : "0.0.0";
122
196
  var SERVER_URL = new URL("./mcp.js", import.meta.url);
123
197
  var SERVER_PATH = fileURLToPath(SERVER_URL);
124
198
  var START_TIMEOUT_MS = 15e3;
@@ -160,18 +234,7 @@ function startDaemon(dir, sock) {
160
234
  }
161
235
  }
162
236
  function relay(sock) {
163
- process.stdin.pipe(sock);
164
- sock.pipe(process.stdout);
165
- const done = (code) => {
166
- try {
167
- sock.destroy();
168
- } catch {
169
- }
170
- process.exit(code);
171
- };
172
- process.stdin.on("end", () => sock.end());
173
- sock.on("close", () => done(0));
174
- sock.on("error", () => done(0));
237
+ bridge(process.stdin, process.stdout, sock, (code) => process.exit(code));
175
238
  }
176
239
  var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
177
240
  async function main() {
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-relay.js","sourceRoot":"","sources":["../src/mcp-relay.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp-relay.js","sourceRoot":"","sources":["../src/mcp-relay.ts"],"names":[],"mappings":"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"}