instar 1.3.1349 → 1.3.1351

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 (38) hide show
  1. package/dist/core/ClaudeBinaryRetainer.d.ts +186 -0
  2. package/dist/core/ClaudeBinaryRetainer.d.ts.map +1 -0
  3. package/dist/core/ClaudeBinaryRetainer.js +585 -0
  4. package/dist/core/ClaudeBinaryRetainer.js.map +1 -0
  5. package/dist/core/Config.d.ts.map +1 -1
  6. package/dist/core/Config.js +5 -0
  7. package/dist/core/Config.js.map +1 -1
  8. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  9. package/dist/core/PostUpdateMigrator.js +22 -0
  10. package/dist/core/PostUpdateMigrator.js.map +1 -1
  11. package/dist/core/SessionManager.d.ts +26 -0
  12. package/dist/core/SessionManager.d.ts.map +1 -1
  13. package/dist/core/SessionManager.js +61 -5
  14. package/dist/core/SessionManager.js.map +1 -1
  15. package/dist/core/WriteDomainRegistry.d.ts.map +1 -1
  16. package/dist/core/WriteDomainRegistry.js +20 -0
  17. package/dist/core/WriteDomainRegistry.js.map +1 -1
  18. package/dist/core/types.d.ts +14 -0
  19. package/dist/core/types.d.ts.map +1 -1
  20. package/dist/core/types.js.map +1 -1
  21. package/dist/data/standards-guard-index.json +1 -1
  22. package/dist/data/standards-guard-index.meta.json +2 -2
  23. package/dist/data/standards-registry.meta.json +1 -1
  24. package/dist/scaffold/templates.d.ts.map +1 -1
  25. package/dist/scaffold/templates.js +1 -0
  26. package/dist/scaffold/templates.js.map +1 -1
  27. package/dist/server/routes.d.ts.map +1 -1
  28. package/dist/server/routes.js +33 -0
  29. package/dist/server/routes.js.map +1 -1
  30. package/package.json +1 -1
  31. package/src/data/builtin-manifest.json +64 -64
  32. package/src/data/standards-guard-index.json +1 -1
  33. package/src/data/standards-guard-index.meta.json +2 -2
  34. package/src/data/standards-registry.meta.json +1 -1
  35. package/src/scaffold/templates.ts +1 -0
  36. package/upgrades/1.3.1350.md +21 -0
  37. package/upgrades/1.3.1351.md +28 -0
  38. package/upgrades/side-effects/retained-claude-executable.md +116 -0
@@ -0,0 +1,585 @@
1
+ /**
2
+ * ClaudeBinaryRetainer — launch Claude Code sessions from a per-version
3
+ * RETAINED copy of the claude executable, never from the mutable npm path.
4
+ *
5
+ * Why this exists (Mac Studio, 2026-10-14, lane studio-kmem-leak-1014):
6
+ * Claude Code is a global npm install. Every update replaces
7
+ * `node_modules/@anthropic-ai/claude-code/bin/claude.exe` IN PLACE, so every
8
+ * Claude session that was already running keeps an UNLINKED executable
9
+ * mapped. On macOS, EndpointSecurity path lookups on an unlinked executable
10
+ * fail (`vn_getpath failed: 0x2`) and each failure leaks ~1 KiB in the kernel
11
+ * zone `data.kalloc.1024` (measured 163 MiB/h across seven sessions; the host
12
+ * panicked on 2026-10-06 at 20 GiB in that zone). The leaked kernel memory is
13
+ * NOT reclaimed when the process exits.
14
+ *
15
+ * The fix is structural, not a watchdog: at spawn time, resolve the claude
16
+ * executable's real path + version, copy it ONCE into
17
+ * `<dir>/<version>/claude`, and launch from that copy. A later update replaces
18
+ * the npm file, but the retained copy keeps its directory entry, so the
19
+ * running session's executable stays linked and the kernel path lookup keeps
20
+ * succeeding. New sessions after the update get a NEW version directory. Old
21
+ * directories are pruned only once no live process maps them (and a usage
22
+ * grace window has passed), never while in use.
23
+ *
24
+ * Contract:
25
+ * - `resolve()` is SYNCHRONOUS and used on the spawn path. It copies only on
26
+ * a NEW version (one ~250 MB copy per update), otherwise it is a few stats.
27
+ * - It NEVER replaces an existing retained file in place (that would recreate
28
+ * the exact unlink-under-a-live-process this fixes). A new version always
29
+ * lands in a new directory; a same-version size mismatch lands in a
30
+ * size-suffixed sibling directory.
31
+ * - Every failure falls back to the ORIGINAL path with a named reason and a
32
+ * LOUD log line, so a retainer defect can never stop sessions from
33
+ * spawning — the leak is a slow failure, a spawn refusal is an immediate one.
34
+ * - `prune()` is async, deletes only non-current, unmapped, past-grace
35
+ * directories, and treats "cannot tell whether it is mapped" as KEEP.
36
+ * - Only a genuine Claude Code binary is retained: a wrapper SCRIPT
37
+ * (shebang) is launched as-is because a script is read by its interpreter,
38
+ * never mapped as the process executable, so it cannot trigger the leak —
39
+ * and relocating a wrapper could break its relative references.
40
+ */
41
+ import fs from 'node:fs';
42
+ import os from 'node:os';
43
+ import path from 'node:path';
44
+ import crypto from 'node:crypto';
45
+ import { execFile, execFileSync } from 'node:child_process';
46
+ import { SafeFsExecutor } from './SafeFsExecutor.js';
47
+ import { withSyncOp } from './InFlightSyncOpMarker.js';
48
+ export const DEFAULT_PRUNE_GRACE_MS = 6 * 60 * 60 * 1000;
49
+ export const RETAINED_BINARY_NAME = 'claude';
50
+ export const LAST_USED_MARKER = '.last-used';
51
+ export const SOURCE_MANIFEST = 'source.json';
52
+ const PRUNE_MAX_REMOVALS_PER_PASS = 20;
53
+ const VERSION_PROBE_TIMEOUT_MS = 20_000;
54
+ const LSOF_TIMEOUT_MS = 15_000;
55
+ const SAFE_KEY = /^[A-Za-z0-9][A-Za-z0-9._-]{0,80}$/;
56
+ /**
57
+ * Is the retainer ON for this process? Production default is ON (absent =
58
+ * on — the leak is the default-on failure). Under a test runner (VITEST set)
59
+ * the default is OFF: dozens of SessionManager tests pin the launch argv
60
+ * byte-for-byte against a configured claude path that happens to EXIST on a
61
+ * developer's Mac and not on CI, so a host-dependent default would make the
62
+ * same test pass on one machine and fail on another. An EXPLICIT
63
+ * `enabled: true` always wins (the retainer's own tests set it), and an
64
+ * explicit `false` always wins.
65
+ */
66
+ export function resolveRetainerEnabled(configured, env = process.env) {
67
+ if (configured === true)
68
+ return true;
69
+ if (configured === false)
70
+ return false;
71
+ return !env.VITEST;
72
+ }
73
+ export function sanitizeVersionKey(version) {
74
+ if (!version)
75
+ return null;
76
+ const v = version.trim();
77
+ return SAFE_KEY.test(v) ? v : null;
78
+ }
79
+ /**
80
+ * Read the Claude Code version for a resolved real executable path.
81
+ * 1. `../package.json` of the bin dir (the npm layout:
82
+ * `…/claude-code/bin/claude.exe` → `…/claude-code/package.json`), or a
83
+ * sibling `package.json`.
84
+ * 2. `<bin> --version` (the native installer lays the binary down as
85
+ * `~/.local/share/claude/versions/<ver>` with no package.json).
86
+ */
87
+ export function readClaudeVersion(realPath, versionProbe = defaultVersionProbe) {
88
+ const binDir = path.dirname(realPath);
89
+ for (const candidate of [path.join(binDir, '..', 'package.json'), path.join(binDir, 'package.json')]) {
90
+ try {
91
+ if (!fs.existsSync(candidate))
92
+ continue;
93
+ const pkg = JSON.parse(fs.readFileSync(candidate, 'utf8'));
94
+ const name = typeof pkg.name === 'string' ? pkg.name : '';
95
+ if (name && !/claude/i.test(name))
96
+ continue;
97
+ const version = sanitizeVersionKey(typeof pkg.version === 'string' ? pkg.version : null);
98
+ if (version)
99
+ return { version, via: 'package-json' };
100
+ }
101
+ catch {
102
+ // @silent-fallback-ok — an unreadable package.json just means we try the
103
+ // next source; the fingerprint fallback below is always available.
104
+ }
105
+ }
106
+ try {
107
+ const out = versionProbe(realPath);
108
+ const m = /(\d+\.\d+\.\d+[A-Za-z0-9._-]*)/.exec(out ?? '');
109
+ const version = sanitizeVersionKey(m?.[1] ?? null);
110
+ if (version)
111
+ return { version, via: 'version-flag' };
112
+ }
113
+ catch {
114
+ // @silent-fallback-ok — a failed probe falls through to the fingerprint key.
115
+ }
116
+ return { version: null, via: null };
117
+ }
118
+ function defaultVersionProbe(bin) {
119
+ // Sync by necessity (resolve() sits on the synchronous spawn path) and
120
+ // bounded: once per installed build (cached by the retainer), never per spawn.
121
+ return withSyncOp(() => execFileSync(bin, ['--version'], {
122
+ encoding: 'utf8',
123
+ timeout: VERSION_PROBE_TIMEOUT_MS,
124
+ stdio: ['ignore', 'pipe', 'ignore'],
125
+ env: { ...process.env, CLAUDE_CODE_DISABLE_AUTOUPDATER: '1' },
126
+ }));
127
+ }
128
+ /** Resolve a bare command name through PATH; absolute/relative paths pass through. */
129
+ export function locateExecutable(configured, env = process.env) {
130
+ if (!configured)
131
+ return null;
132
+ if (configured.includes('/'))
133
+ return configured;
134
+ for (const dir of (env.PATH ?? '').split(':').filter(Boolean)) {
135
+ const candidate = path.join(dir, configured);
136
+ try {
137
+ if (fs.statSync(candidate).isFile())
138
+ return candidate;
139
+ }
140
+ catch {
141
+ // @silent-fallback-ok — not in this PATH entry; keep looking.
142
+ }
143
+ }
144
+ return null;
145
+ }
146
+ /**
147
+ * Only a path that is plainly a Claude Code install is retained: the file is
148
+ * named `claude` / `claude.exe`, or a path component is the npm package dir
149
+ * (`claude-code`, `@anthropic-ai`), the native-installer dir (`claude`), or
150
+ * `.claude`. Component-exact so an unrelated directory whose NAME merely
151
+ * contains "claude" (a tmp dir, a project) does not qualify.
152
+ */
153
+ export function looksLikeClaudeInstall(realPath) {
154
+ const parts = realPath.split(path.sep).filter(Boolean);
155
+ const base = parts[parts.length - 1] ?? '';
156
+ if (/^claude(\.exe)?$/i.test(base))
157
+ return true;
158
+ return parts.slice(0, -1).some((c) => /^(claude|claude-code|\.claude|@anthropic-ai)$/i.test(c));
159
+ }
160
+ function startsWithShebang(file) {
161
+ let fd = null;
162
+ try {
163
+ fd = fs.openSync(file, 'r');
164
+ const buf = Buffer.alloc(2);
165
+ const n = fs.readSync(fd, buf, 0, 2, 0);
166
+ return n === 2 && buf[0] === 0x23 && buf[1] === 0x21; // "#!"
167
+ }
168
+ catch {
169
+ // @silent-fallback-ok — unreadable head is treated as "not a script"; the
170
+ // copy step will surface a real read error loudly.
171
+ return false;
172
+ }
173
+ finally {
174
+ if (fd !== null) {
175
+ try {
176
+ fs.closeSync(fd);
177
+ }
178
+ catch { /* @silent-fallback-ok — close of a read-only fd */ }
179
+ }
180
+ }
181
+ }
182
+ /**
183
+ * Count live processes mapping `file`. Linux: scan `/proc/*\/exe` (no
184
+ * subprocess). Elsewhere: `lsof -t -- <file>` (exit 1 + empty output = none).
185
+ * Returns null whenever the answer is not trustworthy — the caller KEEPS.
186
+ */
187
+ export async function defaultLiveMappers(file) {
188
+ if (process.platform === 'linux') {
189
+ try {
190
+ // /proc/<pid>/exe is always canonical; compare canonical to canonical.
191
+ const target = fs.realpathSync(file);
192
+ let count = 0;
193
+ for (const pid of fs.readdirSync('/proc')) {
194
+ if (!/^\d+$/.test(pid))
195
+ continue;
196
+ try {
197
+ if (fs.readlinkSync(`/proc/${pid}/exe`) === target)
198
+ count++;
199
+ }
200
+ catch {
201
+ // @silent-fallback-ok — a process we cannot inspect (not ours) is
202
+ // not evidence either way; the realpath comparison below is the
203
+ // conservative half (a deleted exe reads "<path> (deleted)").
204
+ }
205
+ }
206
+ return count;
207
+ }
208
+ catch {
209
+ // @silent-fallback-ok — /proc unreadable: "cannot tell" → the caller KEEPS.
210
+ return null;
211
+ }
212
+ }
213
+ return await new Promise((resolveP) => {
214
+ execFile('lsof', ['-t', '--', file], { timeout: LSOF_TIMEOUT_MS, encoding: 'utf8' }, (err, stdout) => {
215
+ const pids = String(stdout ?? '').split('\n').map((s) => s.trim()).filter(Boolean);
216
+ if (!err)
217
+ return resolveP(pids.length);
218
+ // lsof exits 1 when no process has the file open — that IS an answer,
219
+ // as long as it was lsof that answered (not ENOENT / a timeout).
220
+ const e = err;
221
+ if (e.code === 1 && !e.killed && !e.signal)
222
+ return resolveP(pids.length);
223
+ return resolveP(null);
224
+ });
225
+ });
226
+ }
227
+ export class ClaudeBinaryRetainer {
228
+ dir;
229
+ enabled;
230
+ pruneGraceMs;
231
+ liveMappers;
232
+ versionProbe;
233
+ copyFile;
234
+ now;
235
+ log;
236
+ currentKey = null;
237
+ currentVersion = null;
238
+ lastResolution = null;
239
+ lastError = null;
240
+ lastPrune = null;
241
+ counters = { resolutions: 0, retained: 0, copies: 0, fallbacks: 0 };
242
+ /** Version-read cache keyed on the source file's identity, so the (slow,
243
+ * synchronous) `--version` fallback for a package.json-less layout runs
244
+ * once per installed build, not once per spawn. */
245
+ versionCache = new Map();
246
+ pruneInFlight = null;
247
+ constructor(opts) {
248
+ this.dir = opts.dir;
249
+ this.enabled = opts.enabled !== false;
250
+ this.pruneGraceMs = opts.pruneGraceMs ?? DEFAULT_PRUNE_GRACE_MS;
251
+ this.liveMappers = opts.liveMappers ?? defaultLiveMappers;
252
+ this.versionProbe = opts.versionProbe ?? defaultVersionProbe;
253
+ // COPYFILE_FICLONE: a reflink/clone where the filesystem supports it (APFS),
254
+ // a plain copy elsewhere — never an error for lack of clone support.
255
+ this.copyFile = opts.copyFile ?? ((src, dst) => fs.copyFileSync(src, dst, fs.constants.COPYFILE_FICLONE));
256
+ this.now = opts.now ?? (() => Date.now());
257
+ this.log = opts.log ?? {
258
+ warn: (m) => console.warn(m),
259
+ error: (m) => console.error(m),
260
+ info: (m) => console.log(m),
261
+ };
262
+ }
263
+ /** The default retain dir for an agent: under its gitignored state dir. */
264
+ static defaultDir(projectDir) {
265
+ return path.join(projectDir, '.instar', 'state', 'claude-bin');
266
+ }
267
+ /**
268
+ * Resolve the path to launch for `configuredPath`. Synchronous; copies only
269
+ * when a new version is seen. Never throws — every failure is a fallback
270
+ * to the original path with a reason.
271
+ */
272
+ resolve(configuredPath) {
273
+ this.counters.resolutions++;
274
+ const at = new Date(this.now()).toISOString();
275
+ const fallback = (reason, detail, realPath = null, loud = false) => {
276
+ this.counters.fallbacks++;
277
+ const res = {
278
+ path: configuredPath, source: 'original', version: null, key: null, sourcePath: configuredPath,
279
+ sourceRealPath: realPath, versionVia: null, copied: false, reason, detail, at,
280
+ };
281
+ this.lastResolution = res;
282
+ if (loud) {
283
+ this.lastError = { at, message: `${reason}: ${detail}` };
284
+ this.log.error(`[ClaudeBinaryRetainer] LAUNCHING FROM THE ORIGINAL PATH (${configuredPath}) — ${reason}: ${detail}. ` +
285
+ 'A Claude Code update will unlink this session\'s executable and leak kernel memory on macOS ' +
286
+ '(data.kalloc.1024). Fix the retain dir or disable sessions.retainedClaudeBinary deliberately.');
287
+ }
288
+ return res;
289
+ };
290
+ if (!this.enabled)
291
+ return fallback('disabled', 'sessions.retainedClaudeBinary.enabled is false');
292
+ const located = locateExecutable(configuredPath);
293
+ if (!located)
294
+ return fallback('source-missing', `"${configuredPath}" is not on PATH`);
295
+ let realPath;
296
+ let srcStat;
297
+ try {
298
+ realPath = fs.realpathSync(located);
299
+ srcStat = fs.statSync(realPath);
300
+ }
301
+ catch (err) {
302
+ // @silent-fallback-ok — NOT silent: the resolution carries a named reason
303
+ // and the status route exposes it; the session still launches.
304
+ return fallback('source-unreadable', `${located}: ${err instanceof Error ? err.message : String(err)}`);
305
+ }
306
+ if (!srcStat.isFile())
307
+ return fallback('not-a-file', realPath, realPath);
308
+ if (!looksLikeClaudeInstall(realPath))
309
+ return fallback('not-claude-binary', `${realPath} does not look like a Claude Code install`, realPath);
310
+ if (startsWithShebang(realPath))
311
+ return fallback('script-not-retained', `${realPath} is a wrapper script (not mapped as an executable; cannot trigger the leak)`, realPath);
312
+ const cacheKey = `${realPath}|${srcStat.size}|${Math.floor(srcStat.mtimeMs)}`;
313
+ let read = this.versionCache.get(cacheKey);
314
+ if (!read) {
315
+ read = readClaudeVersion(realPath, this.versionProbe);
316
+ this.versionCache.set(cacheKey, read);
317
+ }
318
+ const version = read.version;
319
+ const versionVia = read.via ?? 'fingerprint';
320
+ const baseKey = version ?? `fp-${srcStat.size}-${Math.floor(srcStat.mtimeMs)}`;
321
+ // Find or create the directory for THIS source content. A retained file is
322
+ // never replaced: a same-key size mismatch goes to a size-suffixed sibling.
323
+ const candidates = [baseKey, `${baseKey}-${srcStat.size}`];
324
+ for (const key of candidates) {
325
+ const retainedPath = path.join(this.dir, key, RETAINED_BINARY_NAME);
326
+ let existing = null;
327
+ try {
328
+ existing = fs.statSync(retainedPath);
329
+ }
330
+ catch {
331
+ existing = null; /* @silent-fallback-ok — absent → copy */
332
+ }
333
+ if (existing) {
334
+ if (existing.isFile() && existing.size === srcStat.size) {
335
+ this.touchLastUsed(key);
336
+ return this.accept({ key, version, versionVia, retainedPath, realPath, configuredPath, copied: false, at });
337
+ }
338
+ continue; // mismatch → try the sibling key
339
+ }
340
+ const copied = this.copyInto(key, realPath, srcStat, version);
341
+ if (copied.ok) {
342
+ return this.accept({ key, version, versionVia, retainedPath, realPath, configuredPath, copied: true, at });
343
+ }
344
+ return fallback('copy-failed', copied.error, realPath, true);
345
+ }
346
+ return fallback('retained-mismatch', `${this.dir}/${baseKey} and its size-suffixed sibling both exist with a different size than ${realPath}`, realPath, true);
347
+ }
348
+ accept(input) {
349
+ this.currentKey = input.key;
350
+ this.currentVersion = input.version;
351
+ this.counters.retained++;
352
+ if (input.copied)
353
+ this.counters.copies++;
354
+ const res = {
355
+ path: input.retainedPath, source: 'retained', version: input.version, key: input.key,
356
+ sourcePath: input.configuredPath, sourceRealPath: input.realPath, versionVia: input.versionVia,
357
+ copied: input.copied, at: input.at,
358
+ };
359
+ this.lastResolution = res;
360
+ if (input.copied) {
361
+ this.log.info(`[ClaudeBinaryRetainer] retained Claude Code ${input.version ?? input.key} at ${input.retainedPath} (from ${input.realPath})`);
362
+ }
363
+ return res;
364
+ }
365
+ copyInto(key, realPath, srcStat, version) {
366
+ const versionDir = path.join(this.dir, key);
367
+ const finalPath = path.join(versionDir, RETAINED_BINARY_NAME);
368
+ const tmpPath = path.join(versionDir, `.${RETAINED_BINARY_NAME}.tmp-${process.pid}-${crypto.randomBytes(4).toString('hex')}`);
369
+ try {
370
+ fs.mkdirSync(versionDir, { recursive: true, mode: 0o755 });
371
+ this.copyFile(realPath, tmpPath);
372
+ fs.chmodSync(tmpPath, 0o755);
373
+ const copiedStat = fs.statSync(tmpPath);
374
+ if (copiedStat.size !== srcStat.size) {
375
+ throw new Error(`short copy: ${copiedStat.size} of ${srcStat.size} bytes`);
376
+ }
377
+ // Atomic, non-replacing publish: link() fails with EEXIST if another
378
+ // process published the same version first — then theirs wins and ours
379
+ // is discarded. rename() would REPLACE, which is the very unlink this
380
+ // module exists to prevent.
381
+ try {
382
+ fs.linkSync(tmpPath, finalPath);
383
+ }
384
+ catch (err) {
385
+ if (err.code !== 'EEXIST')
386
+ throw err;
387
+ }
388
+ this.removeTmp(tmpPath);
389
+ const manifest = {
390
+ version, key, sourceRealPath: realPath, sizeBytes: srcStat.size,
391
+ sourceMtimeMs: Math.floor(srcStat.mtimeMs), copiedAt: new Date(this.now()).toISOString(),
392
+ hostname: os.hostname(), pid: process.pid,
393
+ };
394
+ try {
395
+ fs.writeFileSync(path.join(versionDir, SOURCE_MANIFEST), JSON.stringify(manifest, null, 2) + '\n');
396
+ }
397
+ catch { /* @silent-fallback-ok — the manifest is observability, the copy is the point */ }
398
+ this.touchLastUsed(key);
399
+ return { ok: true };
400
+ }
401
+ catch (err) {
402
+ this.removeTmp(tmpPath);
403
+ return { ok: false, error: `${finalPath}: ${err instanceof Error ? err.message : String(err)}` };
404
+ }
405
+ }
406
+ removeTmp(tmpPath) {
407
+ try {
408
+ if (fs.existsSync(tmpPath))
409
+ SafeFsExecutor.safeUnlinkSync(tmpPath, { operation: 'ClaudeBinaryRetainer.copy-tmp' });
410
+ }
411
+ catch {
412
+ // @silent-fallback-ok — a leftover tmp file is harmless and visible in status.
413
+ }
414
+ }
415
+ touchLastUsed(key) {
416
+ try {
417
+ fs.writeFileSync(path.join(this.dir, key, LAST_USED_MARKER), new Date(this.now()).toISOString() + '\n');
418
+ }
419
+ catch {
420
+ // @silent-fallback-ok — a missing marker only makes the directory look
421
+ // OLDER to prune, and prune still requires zero live mappers.
422
+ }
423
+ }
424
+ /** The directory this process has most recently launched from (null = never resolved). */
425
+ current() {
426
+ return this.currentKey
427
+ ? { key: this.currentKey, version: this.currentVersion, path: path.join(this.dir, this.currentKey, RETAINED_BINARY_NAME) }
428
+ : null;
429
+ }
430
+ listRetained() {
431
+ let names = [];
432
+ try {
433
+ names = fs.readdirSync(this.dir);
434
+ }
435
+ catch {
436
+ return []; /* @silent-fallback-ok — no dir yet → nothing retained */
437
+ }
438
+ const out = [];
439
+ for (const key of names.sort()) {
440
+ if (key.startsWith('.'))
441
+ continue;
442
+ const versionDir = path.join(this.dir, key);
443
+ const file = path.join(versionDir, RETAINED_BINARY_NAME);
444
+ let sizeBytes = null;
445
+ try {
446
+ const st = fs.statSync(versionDir);
447
+ if (!st.isDirectory())
448
+ continue;
449
+ sizeBytes = fs.statSync(file).size;
450
+ }
451
+ catch {
452
+ // @silent-fallback-ok — a version dir without its binary is listed
453
+ // with sizeBytes null so prune can still reclaim it.
454
+ }
455
+ let version = null;
456
+ let copiedAt = null;
457
+ try {
458
+ const m = JSON.parse(fs.readFileSync(path.join(versionDir, SOURCE_MANIFEST), 'utf8'));
459
+ version = typeof m.version === 'string' ? m.version : null;
460
+ copiedAt = typeof m.copiedAt === 'string' ? m.copiedAt : null;
461
+ }
462
+ catch { /* @silent-fallback-ok — manifest optional */ }
463
+ let lastUsedAt = null;
464
+ try {
465
+ lastUsedAt = fs.statSync(path.join(versionDir, LAST_USED_MARKER)).mtime.toISOString();
466
+ }
467
+ catch { /* @silent-fallback-ok */ }
468
+ out.push({ key, path: file, version, sizeBytes, copiedAt, lastUsedAt, current: key === this.currentKey });
469
+ }
470
+ return out;
471
+ }
472
+ /**
473
+ * Remove retained versions that are not current, have not been used within
474
+ * the grace window, and that NO live process maps. "Cannot tell" keeps.
475
+ */
476
+ async prune() {
477
+ if (this.pruneInFlight)
478
+ return this.pruneInFlight;
479
+ this.pruneInFlight = this.pruneOnce().finally(() => { this.pruneInFlight = null; });
480
+ return this.pruneInFlight;
481
+ }
482
+ async pruneOnce() {
483
+ const result = {
484
+ at: new Date(this.now()).toISOString(), checked: 0, removed: [], keptCurrent: [], keptInUse: [],
485
+ keptRecent: [], keptUnknown: [], errors: [],
486
+ };
487
+ if (!this.enabled) {
488
+ result.skipped = 'disabled';
489
+ this.lastPrune = result;
490
+ return result;
491
+ }
492
+ if (!this.currentKey) {
493
+ result.skipped = 'no-current-key';
494
+ this.lastPrune = result;
495
+ return result;
496
+ }
497
+ if (!fs.existsSync(this.dir)) {
498
+ result.skipped = 'dir-missing';
499
+ this.lastPrune = result;
500
+ return result;
501
+ }
502
+ const now = this.now();
503
+ for (const entry of this.listRetained()) {
504
+ result.checked++;
505
+ if (entry.current) {
506
+ result.keptCurrent.push(entry.key);
507
+ continue;
508
+ }
509
+ const versionDir = path.join(this.dir, entry.key);
510
+ let lastUsedMs;
511
+ try {
512
+ lastUsedMs = fs.statSync(path.join(versionDir, LAST_USED_MARKER)).mtimeMs;
513
+ }
514
+ catch {
515
+ // @silent-fallback-ok — no marker: fall back to the directory's own mtime.
516
+ try {
517
+ lastUsedMs = fs.statSync(versionDir).mtimeMs;
518
+ }
519
+ catch {
520
+ lastUsedMs = 0; /* @silent-fallback-ok — unstat-able dir reads as old; the mapper gate still protects it */
521
+ }
522
+ }
523
+ if (now - lastUsedMs < this.pruneGraceMs) {
524
+ result.keptRecent.push(entry.key);
525
+ continue;
526
+ }
527
+ if (result.removed.length >= PRUNE_MAX_REMOVALS_PER_PASS)
528
+ break;
529
+ let mappers = null;
530
+ if (entry.sizeBytes !== null) {
531
+ try {
532
+ mappers = await this.liveMappers(entry.path);
533
+ }
534
+ catch {
535
+ mappers = null; /* @silent-fallback-ok — unknown → keep */
536
+ }
537
+ if (mappers === null) {
538
+ result.keptUnknown.push(entry.key);
539
+ continue;
540
+ }
541
+ if (mappers > 0) {
542
+ result.keptInUse.push(entry.key);
543
+ continue;
544
+ }
545
+ }
546
+ // Re-read the marker AFTER the probe: a resolve() in another process may
547
+ // have picked this version during the lsof wait (shared-dir case).
548
+ try {
549
+ if (this.now() - fs.statSync(path.join(versionDir, LAST_USED_MARKER)).mtimeMs < this.pruneGraceMs) {
550
+ result.keptRecent.push(entry.key);
551
+ continue;
552
+ }
553
+ }
554
+ catch {
555
+ // @silent-fallback-ok — no marker: the pre-probe age check already passed.
556
+ }
557
+ try {
558
+ SafeFsExecutor.safeRmSync(versionDir, { recursive: true, force: true, operation: 'ClaudeBinaryRetainer.prune' });
559
+ result.removed.push(entry.key);
560
+ }
561
+ catch (err) {
562
+ result.errors.push(`${entry.key}: ${err instanceof Error ? err.message : String(err)}`);
563
+ }
564
+ }
565
+ this.lastPrune = result;
566
+ if (result.removed.length > 0) {
567
+ this.log.info(`[ClaudeBinaryRetainer] pruned ${result.removed.length} unused retained Claude Code version(s): ${result.removed.join(', ')}`);
568
+ }
569
+ return result;
570
+ }
571
+ status() {
572
+ return {
573
+ enabled: this.enabled,
574
+ dir: this.dir,
575
+ pruneGraceMs: this.pruneGraceMs,
576
+ current: this.current(),
577
+ lastResolution: this.lastResolution,
578
+ lastError: this.lastError,
579
+ counters: { ...this.counters },
580
+ retained: this.listRetained(),
581
+ lastPrune: this.lastPrune,
582
+ };
583
+ }
584
+ }
585
+ //# sourceMappingURL=ClaudeBinaryRetainer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClaudeBinaryRetainer.js","sourceRoot":"","sources":["../../src/core/ClaudeBinaryRetainer.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../src/core/Config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../src/core/Config.ts"],"names":[],"mappings":"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"}
@@ -940,6 +940,11 @@ export function loadConfig(projectDir) {
940
940
  typeof fileConfig.sessions.resumeFollowsAccount === 'object'
941
941
  ? { resumeFollowsAccount: fileConfig.sessions.resumeFollowsAccount }
942
942
  : {}),
943
+ // CMT-798: retained per-version Claude executable (off switch + dir + grace).
944
+ ...(fileConfig.sessions?.retainedClaudeBinary &&
945
+ typeof fileConfig.sessions.retainedClaudeBinary === 'object'
946
+ ? { retainedClaudeBinary: fileConfig.sessions.retainedClaudeBinary }
947
+ : {}),
943
948
  credentials: buildCredentialsMap(fileConfig.sessions),
944
949
  // Per-component framework routing (docs/specs/per-component-framework-routing.md).
945
950
  // LOAD-PATH FIX (2026-06-06): this field was documented + consumed