@dsiloed/silo-link 1.12.7 → 1.13.0

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 (57) hide show
  1. package/dist/api/dsiloed-client.d.ts +16 -0
  2. package/dist/api/dsiloed-client.d.ts.map +1 -1
  3. package/dist/api/dsiloed-client.js +22 -0
  4. package/dist/api/dsiloed-client.js.map +1 -1
  5. package/dist/cli/commands.d.ts.map +1 -1
  6. package/dist/cli/commands.js +8 -0
  7. package/dist/cli/commands.js.map +1 -1
  8. package/dist/config/config-manager.d.ts +10 -0
  9. package/dist/config/config-manager.d.ts.map +1 -1
  10. package/dist/config/config-manager.js +36 -0
  11. package/dist/config/config-manager.js.map +1 -1
  12. package/dist/core/auto-updater.d.ts +94 -0
  13. package/dist/core/auto-updater.d.ts.map +1 -0
  14. package/dist/core/auto-updater.js +411 -0
  15. package/dist/core/auto-updater.js.map +1 -0
  16. package/dist/core/base-tmux-launcher.d.ts +26 -0
  17. package/dist/core/base-tmux-launcher.d.ts.map +1 -1
  18. package/dist/core/base-tmux-launcher.js +87 -0
  19. package/dist/core/base-tmux-launcher.js.map +1 -1
  20. package/dist/core/baseline-verify.d.ts +54 -0
  21. package/dist/core/baseline-verify.d.ts.map +1 -0
  22. package/dist/core/baseline-verify.js +164 -0
  23. package/dist/core/baseline-verify.js.map +1 -0
  24. package/dist/core/bridge.d.ts +3 -0
  25. package/dist/core/bridge.d.ts.map +1 -1
  26. package/dist/core/bridge.js +52 -5
  27. package/dist/core/bridge.js.map +1 -1
  28. package/dist/core/claude-launcher.d.ts +9 -4
  29. package/dist/core/claude-launcher.d.ts.map +1 -1
  30. package/dist/core/claude-launcher.js +21 -21
  31. package/dist/core/claude-launcher.js.map +1 -1
  32. package/dist/core/codex-launcher.d.ts +13 -0
  33. package/dist/core/codex-launcher.d.ts.map +1 -1
  34. package/dist/core/codex-launcher.js +38 -3
  35. package/dist/core/codex-launcher.js.map +1 -1
  36. package/dist/core/gemini-launcher.d.ts +12 -0
  37. package/dist/core/gemini-launcher.d.ts.map +1 -1
  38. package/dist/core/gemini-launcher.js +24 -0
  39. package/dist/core/gemini-launcher.js.map +1 -1
  40. package/dist/core/semver-lite.d.ts +25 -0
  41. package/dist/core/semver-lite.d.ts.map +1 -0
  42. package/dist/core/semver-lite.js +101 -0
  43. package/dist/core/semver-lite.js.map +1 -0
  44. package/dist/core/version.d.ts +3 -0
  45. package/dist/core/version.d.ts.map +1 -0
  46. package/dist/core/version.js +14 -0
  47. package/dist/core/version.js.map +1 -0
  48. package/dist/core/workspace-manager.d.ts +8 -0
  49. package/dist/core/workspace-manager.d.ts.map +1 -1
  50. package/dist/core/workspace-manager.js +31 -0
  51. package/dist/core/workspace-manager.js.map +1 -1
  52. package/dist/mcp/tools/register-tools.d.ts.map +1 -1
  53. package/dist/mcp/tools/register-tools.js +4 -2
  54. package/dist/mcp/tools/register-tools.js.map +1 -1
  55. package/dist/types/index.d.ts +5 -0
  56. package/dist/types/index.d.ts.map +1 -1
  57. package/package.json +1 -1
@@ -0,0 +1,411 @@
1
+ import { execFile, execFileSync, spawn } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import { PACKAGE_NAME, PACKAGE_VERSION } from './version.js';
4
+ import * as semver from './semver-lite.js';
5
+ const execFileAsync = promisify(execFile);
6
+ /**
7
+ * Self-update orchestrator. Periodically reconciles the installed version
8
+ * against (a) the npm registry — "what's published" — and (b) the hub's policy
9
+ * — "what's allowed / required / held back". Applies the patch-auto /
10
+ * minor-notify / major-manual policy, gates every actual update on the daemon
11
+ * being idle (no live coding session), and on a qualifying update runs
12
+ * `npm i -g <pkg>@<target>` then restarts onto the new version.
13
+ *
14
+ * Failure-safe by construction: any network/registry/install error logs and
15
+ * leaves the running daemon untouched. It never crosses a major boundary
16
+ * automatically, and it never updates mid-session.
17
+ */
18
+ export class AutoUpdater {
19
+ config;
20
+ client;
21
+ env;
22
+ isIdle;
23
+ gracefulStop;
24
+ timer = null;
25
+ checking = false;
26
+ updating = false;
27
+ // The version we last emitted a "notify" banner for, so we don't spam the log
28
+ // every interval for a minor/major the operator has chosen not to apply.
29
+ lastNotifiedVersion = null;
30
+ // The version we're deferring because the daemon is busy — logged once so the
31
+ // log shows "waiting for idle" without repeating every interval.
32
+ lastDeferredVersion = null;
33
+ constructor(deps) {
34
+ this.config = deps.config;
35
+ this.client = deps.client;
36
+ this.env = deps.env;
37
+ this.isIdle = deps.isIdle;
38
+ this.gracefulStop = deps.gracefulStop;
39
+ }
40
+ get enabled() {
41
+ // Default ON unless explicitly disabled.
42
+ return this.config.auto_update_enabled !== false;
43
+ }
44
+ get intervalMs() {
45
+ return this.config.update_check_interval_ms ?? 3_600_000;
46
+ }
47
+ start() {
48
+ // A short initial delay lets the daemon finish connecting/registering before
49
+ // the first check, and avoids racing startup work.
50
+ setTimeout(() => { void this.checkOnce(); }, 60_000);
51
+ this.timer = setInterval(() => { void this.checkOnce(); }, this.intervalMs);
52
+ // Don't let the interval keep the event loop alive on its own.
53
+ if (this.timer.unref)
54
+ this.timer.unref();
55
+ console.log(` Auto-update: ${this.enabled ? 'enabled' : 'report-only'} (check every ${Math.round(this.intervalMs / 60000)}m), current v${PACKAGE_VERSION}`);
56
+ }
57
+ stop() {
58
+ if (this.timer) {
59
+ clearInterval(this.timer);
60
+ this.timer = null;
61
+ }
62
+ }
63
+ /** One reconcile pass. Public so it can be triggered/tested directly. */
64
+ async checkOnce() {
65
+ if (this.checking || this.updating)
66
+ return;
67
+ this.checking = true;
68
+ try {
69
+ const current = PACKAGE_VERSION;
70
+ const policy = await this.client.getVersionPolicy();
71
+ const npmLatest = await this.fetchNpmLatest();
72
+ const target = this.resolveTarget(current, npmLatest, policy);
73
+ if (!target)
74
+ return; // already current / nothing actionable
75
+ const bump = semver.diffType(current, target.version);
76
+ const decision = this.decide(current, target.version, bump, target.belowMin, policy);
77
+ // Apply the hub's supply-chain pin only when it names the exact version
78
+ // we resolved to (operators pin target_version + expected_integrity as a
79
+ // pair). Following npm `latest` without a pin stays unpinned.
80
+ const expectedIntegrity = (policy?.target_version && target.version === policy.target_version)
81
+ ? (policy.expected_integrity ?? null)
82
+ : null;
83
+ if (decision === 'auto') {
84
+ if (this.isIdle()) {
85
+ await this.performUpdate(target.version, expectedIntegrity);
86
+ }
87
+ else {
88
+ if (this.lastDeferredVersion !== target.version) {
89
+ console.log(` Auto-update: v${target.version} ready — deferring until idle (a coding session is active)`);
90
+ this.lastDeferredVersion = target.version;
91
+ }
92
+ }
93
+ }
94
+ else if (decision === 'notify') {
95
+ this.notify(current, target.version, bump, target.belowMin);
96
+ }
97
+ }
98
+ catch (err) {
99
+ console.warn(` Auto-update check failed (non-fatal): ${err.message}`);
100
+ }
101
+ finally {
102
+ this.checking = false;
103
+ }
104
+ }
105
+ /**
106
+ * Decide what version, if any, we should move toward. Returns the resolved
107
+ * target and whether the move is forced by the support floor, or null if the
108
+ * daemon is already at/above the best allowed version.
109
+ */
110
+ resolveTarget(current, npmLatest, policy) {
111
+ // Available = newest published, capped by an optional hub pin (ceiling).
112
+ let available = npmLatest;
113
+ const ceiling = policy?.target_version;
114
+ if (available && ceiling && semver.isValid(ceiling) && semver.lt(ceiling, available)) {
115
+ available = ceiling; // hub is holding the fleet back below the latest publish
116
+ }
117
+ const min = policy?.min_supported_version;
118
+ const belowMin = !!(min && semver.isValid(min) && semver.lt(current, min));
119
+ // Forced-update path: below the support floor. Aim at the floor, or higher
120
+ // if something newer is available (and not pinned below the floor).
121
+ if (belowMin && min) {
122
+ let forcedTarget = min;
123
+ if (available && semver.gt(available, forcedTarget))
124
+ forcedTarget = available;
125
+ if (semver.gt(forcedTarget, current))
126
+ return { version: forcedTarget, belowMin: true };
127
+ // Floor is above anything installable (misconfig / not yet published) —
128
+ // can't act; surface it as a notify below via belowMin with no newer.
129
+ }
130
+ if (available && semver.gt(available, current)) {
131
+ return { version: available, belowMin };
132
+ }
133
+ return null;
134
+ }
135
+ decide(_current, _target, bump, belowMin, policy) {
136
+ if (bump === null || bump === 'same')
137
+ return 'none';
138
+ // Never cross a major automatically — even a forced (below-min) update stops
139
+ // at notify for a major, because majors imply breaking config/protocol
140
+ // changes that need a human.
141
+ if (bump === 'major')
142
+ return 'notify';
143
+ if (!this.enabled)
144
+ return 'notify'; // local opt-out: still surface a banner
145
+ // Below the support floor: force patch/minor regardless of the per-bump
146
+ // switches — staying on an unsupported version is worse than the bump.
147
+ if (belowMin)
148
+ return 'auto';
149
+ // Policy: auto-patch / notify-minor by default. The hub can escalate minor
150
+ // to auto via auto_update_minor; patch defaults to auto unless the hub
151
+ // explicitly disables it.
152
+ if (bump === 'patch' || bump === 'prerelease') {
153
+ return policy?.auto_update_patch === false ? 'notify' : 'auto';
154
+ }
155
+ if (bump === 'minor') {
156
+ return policy?.auto_update_minor === true ? 'auto' : 'notify';
157
+ }
158
+ return 'notify';
159
+ }
160
+ notify(current, target, bump, belowMin) {
161
+ if (this.lastNotifiedVersion === target)
162
+ return; // already told them about this one
163
+ this.lastNotifiedVersion = target;
164
+ const kind = belowMin ? 'REQUIRED (below minimum supported)' : `${bump} update`;
165
+ const cmd = `npm i -g ${PACKAGE_NAME}@${target}`;
166
+ console.log('');
167
+ console.log(` ╭─ SiloLink ${kind} available ─────────────────────────────`);
168
+ console.log(` │ ${current} → ${target}`);
169
+ console.log(` │ Update with: ${cmd}`);
170
+ console.log(` │ then restart the daemon (or it will be applied on next restart).`);
171
+ console.log(' ╰──────────────────────────────────────────────────────────');
172
+ console.log('');
173
+ }
174
+ /** Query the npm registry for the package's published `latest` dist-tag. */
175
+ fetchNpmLatest() {
176
+ return fetchNpmLatestVersion(this.registryUrl());
177
+ }
178
+ /**
179
+ * Validated registry base URL. Only an https URL is honored; anything else
180
+ * (including a config override that isn't https) falls back to the public
181
+ * npm registry, so a tampered config can't silently redirect installs to a
182
+ * plaintext or attacker-chosen host. (The integrity pin is the primary
183
+ * defense; this is belt-and-suspenders.)
184
+ */
185
+ registryUrl() {
186
+ const def = 'https://registry.npmjs.org';
187
+ const configured = this.config.npm_registry_url;
188
+ if (!configured)
189
+ return def;
190
+ try {
191
+ const u = new URL(configured);
192
+ if (u.protocol !== 'https:') {
193
+ console.warn(` Auto-update: ignoring non-https npm_registry_url (${configured}); using ${def}.`);
194
+ return def;
195
+ }
196
+ return configured;
197
+ }
198
+ catch {
199
+ console.warn(` Auto-update: ignoring malformed npm_registry_url (${configured}); using ${def}.`);
200
+ return def;
201
+ }
202
+ }
203
+ /** The registry's stated `dist.integrity` (sha512-…) for an exact version. */
204
+ async fetchRegistryIntegrity(version) {
205
+ const registry = this.registryUrl().replace(/\/$/, '');
206
+ const url = `${registry}/${PACKAGE_NAME.replace('/', '%2F')}/${encodeURIComponent(version)}`;
207
+ const controller = new AbortController();
208
+ const timeout = setTimeout(() => controller.abort(), 15_000);
209
+ try {
210
+ const res = await fetch(url, {
211
+ headers: { Accept: 'application/vnd.npm.install-v1+json' },
212
+ signal: controller.signal,
213
+ });
214
+ if (!res.ok)
215
+ return null;
216
+ const json = (await res.json());
217
+ return json.dist?.integrity ?? null;
218
+ }
219
+ catch {
220
+ return null;
221
+ }
222
+ finally {
223
+ clearTimeout(timeout);
224
+ }
225
+ }
226
+ /**
227
+ * Install the target version globally, then restart onto it. Guarded so a
228
+ * second check can't kick off a parallel install. The npm install completes
229
+ * BEFORE we exit, so a managed supervisor that restarts on exit comes back on
230
+ * the new version with no race.
231
+ */
232
+ async performUpdate(target, expectedIntegrity) {
233
+ if (this.updating)
234
+ return;
235
+ // Re-check idle right before we commit — a session may have launched between
236
+ // the decision and here.
237
+ if (!this.isIdle()) {
238
+ console.log(` Auto-update: v${target} install aborted — daemon became busy`);
239
+ return;
240
+ }
241
+ // Supply-chain gate: if the hub pinned an integrity for this exact version,
242
+ // verify the registry's tarball integrity matches BEFORE installing. A
243
+ // malicious npm republish would change the integrity and be rejected here,
244
+ // unless the hub policy was also compromised.
245
+ if (expectedIntegrity) {
246
+ const actual = await this.fetchRegistryIntegrity(target);
247
+ if (actual == null) {
248
+ console.error(` Auto-update: could not verify integrity for v${target} (registry lookup failed) — refusing pinned install.`);
249
+ return;
250
+ }
251
+ if (actual !== expectedIntegrity) {
252
+ console.error(` Auto-update: INTEGRITY MISMATCH for v${target} — refusing install. expected ${expectedIntegrity}, registry has ${actual}. (Possible npm tampering, or a stale pin in the hub policy.)`);
253
+ return;
254
+ }
255
+ console.log(` Auto-update: integrity pin verified for v${target}.`);
256
+ }
257
+ else {
258
+ console.log(` Auto-update: v${target} is unpinned (no expected_integrity in policy) — installing with --ignore-scripts.`);
259
+ }
260
+ this.updating = true;
261
+ this.stop(); // no more checks while we update/restart
262
+ const spec = `${PACKAGE_NAME}@${target}`;
263
+ console.log(` Auto-update: installing ${spec} ...`);
264
+ try {
265
+ // --ignore-scripts: do NOT run the fetched package's lifecycle scripts
266
+ // (pre/postinstall) — silo-link needs none at install time, and this
267
+ // removes the install-script RCE vector if a published version is ever
268
+ // malicious. Bin-linking still happens (it's core npm, not a script).
269
+ const { stdout } = await execFileAsync('npm', ['install', '-g', spec, '--ignore-scripts', '--no-fund', '--no-audit'], { timeout: 300_000, maxBuffer: 16 * 1024 * 1024 });
270
+ const tail = stdout.trim().split('\n').slice(-1)[0] ?? '';
271
+ console.log(` Auto-update: install complete (${tail || 'ok'}). Restarting onto v${target}.`);
272
+ }
273
+ catch (err) {
274
+ // Most common real-world failure: global prefix needs sudo. Don't crash —
275
+ // log a clear, actionable banner and resume report-only behavior.
276
+ this.updating = false;
277
+ console.error(` Auto-update: install FAILED — ${err.message}`);
278
+ console.error(` Auto-update: leaving daemon on v${PACKAGE_VERSION}. Run "npm i -g ${spec}" manually (with sudo if your global npm prefix needs it), or set auto_update_enabled:false to silence this.`);
279
+ // Restart the check timer so we retry later (e.g. once perms are fixed).
280
+ this.timer = setInterval(() => { void this.checkOnce(); }, this.intervalMs);
281
+ if (this.timer.unref)
282
+ this.timer.unref();
283
+ return;
284
+ }
285
+ this.scheduleRestart();
286
+ // Drain and exit. In managed mode the supervisor brings us back; otherwise
287
+ // the detached waiter scheduled above does.
288
+ await this.gracefulStop();
289
+ }
290
+ /**
291
+ * Arrange for the daemon to come back on the freshly-installed version.
292
+ *
293
+ * Managed mode (config flag or SILOLINK_MANAGED=1): do nothing — an external
294
+ * supervisor restarts the process on exit, and since the install already
295
+ * completed it will pick up the new version.
296
+ *
297
+ * Unmanaged mode: spawn a detached shell that waits for THIS process to fully
298
+ * exit (PID gone, ports freed) and then re-launches the daemon via the global
299
+ * `silolink` bin (now pointing at the new version).
300
+ */
301
+ scheduleRestart() {
302
+ const managed = this.config.auto_update_managed_restart === true || process.env.SILOLINK_MANAGED === '1';
303
+ if (managed) {
304
+ console.log(' Auto-update: managed mode — exiting for supervisor to restart on new version.');
305
+ return;
306
+ }
307
+ // `env` is interpolated into the /bin/sh -c relaunch below. It comes from
308
+ // local config (operator-set), but validate the charset anyway so a stray
309
+ // or hostile value can't inject shell syntax. Reject anything outside a
310
+ // conservative identifier set and restart without the env flag (the daemon
311
+ // still comes back; the operator can re-point it).
312
+ let envFlag = '';
313
+ if (this.env) {
314
+ if (/^[\w.-]+$/.test(this.env)) {
315
+ envFlag = ` --env ${this.env}`;
316
+ }
317
+ else {
318
+ console.warn(` Auto-update: env "${this.env}" has unexpected characters — relaunching without --env.`);
319
+ }
320
+ }
321
+ // Resolve the global bin path so we don't depend on the daemon's PATH
322
+ // including the npm global bin (systemd units often have a minimal PATH).
323
+ const bin = this.resolveGlobalBin();
324
+ const launch = bin ? `"${bin}" start --daemon${envFlag}` : `silolink start --daemon${envFlag}`;
325
+ const script = `i=0; while kill -0 ${process.pid} 2>/dev/null && [ $i -lt 120 ]; do sleep 0.5; i=$((i+1)); done; exec ${launch}`;
326
+ try {
327
+ const child = spawn('/bin/sh', ['-c', script], { detached: true, stdio: 'ignore' });
328
+ child.unref();
329
+ console.log(' Auto-update: detached restarter scheduled.');
330
+ }
331
+ catch (err) {
332
+ console.error(` Auto-update: could not schedule restart (${err.message}). Restart the daemon manually to pick up the new version.`);
333
+ }
334
+ }
335
+ /** Best-effort absolute path to the freshly-installed global `silolink` bin. */
336
+ resolveGlobalBin() {
337
+ try {
338
+ const prefix = execFileSync('npm', ['prefix', '-g'], { encoding: 'utf-8', timeout: 15_000 }).trim();
339
+ if (!prefix)
340
+ return null;
341
+ // npm global bins live in <prefix>/bin on POSIX, <prefix>\silolink.cmd on Windows.
342
+ return process.platform === 'win32' ? `${prefix}\\silolink.cmd` : `${prefix}/bin/silolink`;
343
+ }
344
+ catch {
345
+ return null;
346
+ }
347
+ }
348
+ }
349
+ /** Query the npm registry for the package's published `latest` version. */
350
+ export async function fetchNpmLatestVersion(registryUrl = 'https://registry.npmjs.org') {
351
+ const registry = registryUrl.replace(/\/$/, '');
352
+ const url = `${registry}/${PACKAGE_NAME.replace('/', '%2F')}/latest`;
353
+ const controller = new AbortController();
354
+ const timeout = setTimeout(() => controller.abort(), 15_000);
355
+ try {
356
+ const res = await fetch(url, {
357
+ headers: { Accept: 'application/vnd.npm.install-v1+json' },
358
+ signal: controller.signal,
359
+ });
360
+ if (!res.ok)
361
+ return null;
362
+ const json = (await res.json());
363
+ return json.version && semver.isValid(json.version) ? json.version : null;
364
+ }
365
+ catch {
366
+ return null;
367
+ }
368
+ finally {
369
+ clearTimeout(timeout);
370
+ }
371
+ }
372
+ /**
373
+ * One-shot manual update used by the `silolink update` CLI command. Decoupled
374
+ * from a running daemon: compares the installed version to the npm `latest`,
375
+ * and (unless checkOnly) installs it. Does NOT restart anything — the operator
376
+ * restarts the daemon to pick up the new version. Returns true if an update is
377
+ * available (and, when not checkOnly, was installed).
378
+ */
379
+ export async function checkAndInstallNow(opts = {}) {
380
+ const latest = await fetchNpmLatestVersion();
381
+ if (!latest) {
382
+ console.error('Could not reach the npm registry to check for updates.');
383
+ return false;
384
+ }
385
+ if (!semver.gt(latest, PACKAGE_VERSION)) {
386
+ console.log(`SiloLink is up to date (v${PACKAGE_VERSION}).`);
387
+ return false;
388
+ }
389
+ const bump = semver.diffType(PACKAGE_VERSION, latest);
390
+ console.log(`Update available: v${PACKAGE_VERSION} → v${latest} (${bump}).`);
391
+ if (opts.checkOnly) {
392
+ console.log(`Run "silolink update" to install, or "npm i -g ${PACKAGE_NAME}@${latest}".`);
393
+ return true;
394
+ }
395
+ const spec = `${PACKAGE_NAME}@${latest}`;
396
+ console.log(`Installing ${spec} ...`);
397
+ try {
398
+ await execFileAsync('npm', ['install', '-g', spec, '--ignore-scripts', '--no-fund', '--no-audit'], {
399
+ timeout: 300_000,
400
+ maxBuffer: 16 * 1024 * 1024,
401
+ });
402
+ console.log(`Installed v${latest}. Restart the daemon (silolink stop && silolink start) to use it.`);
403
+ return true;
404
+ }
405
+ catch (err) {
406
+ console.error(`Install failed: ${err.message}`);
407
+ console.error(`Try manually: npm i -g ${spec} (with sudo if your global npm prefix needs it).`);
408
+ return false;
409
+ }
410
+ }
411
+ //# sourceMappingURL=auto-updater.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-updater.js","sourceRoot":"","sources":["../../src/core/auto-updater.ts"],"names":[],"mappings":"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"}
@@ -210,6 +210,32 @@ export declare abstract class BaseTmuxLauncher implements AgentLauncher {
210
210
  cost_basis: 'real' | 'imputed';
211
211
  usage: UsageEntry[];
212
212
  } | null;
213
+ /**
214
+ * Detect the coding agent's CLI session/resume id for a worker running in
215
+ * `cwd`, by inspecting the CLI's on-disk transcript (claude `<id>.jsonl`,
216
+ * gemini chat header `sessionId`, codex rollout uuid). Agent-agnostic seam:
217
+ * the base flow (captureResumeId) calls this; each launcher overrides it.
218
+ * Default is null (no resume support — falls back to a fresh launch).
219
+ *
220
+ * Best-effort: returns null on any failure. NEVER throws into the launch path.
221
+ */
222
+ protected detectResumeId(_cwd: string): string | null;
223
+ /**
224
+ * Capture the running worker's CLI session id and remember it so the next
225
+ * respawn relaunches the SAME session (`--resume`). Stores on three places:
226
+ * 1. `this.lastSessionId` — what buildLaunchPrompt reads to add resume args.
227
+ * 2. the SessionInfo (`resumeId`) — survives in-memory so finishPaneTeardown
228
+ * can restore it just before relaunch (keyed off the SESSION, not a stale
229
+ * global).
230
+ * 3. the rails AgentSession metadata (`cli_resume_id` + legacy
231
+ * `claude_resume_id`) — survives a daemon restart so bridge startup /
232
+ * remote_load_context can restore it.
233
+ *
234
+ * Idempotent + throttled by the caller (runs on the live-usage tick and once
235
+ * shortly after launch). Best-effort — a capture failure leaves prior state
236
+ * intact and never blocks anything.
237
+ */
238
+ protected captureResumeId(conversationId: number): void;
213
239
  protected captureUsageFromTranscript(conversationId: number): boolean;
214
240
  protected maybeReportLiveUsage(conversationId: number): void;
215
241
  protected checkIdle(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"base-tmux-launcher.d.ts","sourceRoot":"","sources":["../../src/core/base-tmux-launcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base-tmux-launcher.d.ts","sourceRoot":"","sources":["../../src/core/base-tmux-launcher.ts"],"names":[],"mappings":"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"}
@@ -865,6 +865,10 @@ export class BaseTmuxLauncher {
865
865
  // Live session: periodically report cumulative usage (throttled) so cost
866
866
  // is captured even if the daemon dies before the teardown report fires.
867
867
  this.maybeReportLiveUsage(info.conversationId);
868
+ // Also (cheap, idempotent) keep the worker's CLI resume id captured so a
869
+ // mid-task death/respawn can continue the SAME session instead of starting
870
+ // fresh. The transcript exists by the time the CLI has done any work.
871
+ this.captureResumeId(info.conversationId);
868
872
  return;
869
873
  }
870
874
  this.lastUsageReportAt.delete(info.conversationId);
@@ -894,6 +898,16 @@ export class BaseTmuxLauncher {
894
898
  const stillRegistered = this.sessionManager.getByConversationId(conversationId);
895
899
  if (!stillRegistered)
896
900
  return;
901
+ // RESTORE resume id from the dying SESSION's stored value (not a stale
902
+ // global) BEFORE we unregister it — this is what lets the auto-respawn relaunch
903
+ // the SAME CLI session (`--resume <id>`) and continue an in-progress task
904
+ // instead of starting fresh. Best-effort: if the worker never captured an id
905
+ // (capture failed / CLI has no resume), lastSessionId stays null and the
906
+ // relaunch falls back to a fresh session — current behavior, never blocked.
907
+ const resumeId = stillRegistered.resumeId || stillRegistered.claudeResumeId;
908
+ if (resumeId) {
909
+ this.setLastResumeId(resumeId);
910
+ }
897
911
  // Unregister the stale MCP session either way — the tmux is gone.
898
912
  this.messageQueue?.clearSession(stillRegistered.sessionId);
899
913
  this.sessionManager.unregister(stillRegistered.sessionId);
@@ -957,6 +971,79 @@ export class BaseTmuxLauncher {
957
971
  extractTranscriptUsage(_cwd) {
958
972
  return null;
959
973
  }
974
+ /**
975
+ * Detect the coding agent's CLI session/resume id for a worker running in
976
+ * `cwd`, by inspecting the CLI's on-disk transcript (claude `<id>.jsonl`,
977
+ * gemini chat header `sessionId`, codex rollout uuid). Agent-agnostic seam:
978
+ * the base flow (captureResumeId) calls this; each launcher overrides it.
979
+ * Default is null (no resume support — falls back to a fresh launch).
980
+ *
981
+ * Best-effort: returns null on any failure. NEVER throws into the launch path.
982
+ */
983
+ detectResumeId(_cwd) {
984
+ return null;
985
+ }
986
+ /**
987
+ * Capture the running worker's CLI session id and remember it so the next
988
+ * respawn relaunches the SAME session (`--resume`). Stores on three places:
989
+ * 1. `this.lastSessionId` — what buildLaunchPrompt reads to add resume args.
990
+ * 2. the SessionInfo (`resumeId`) — survives in-memory so finishPaneTeardown
991
+ * can restore it just before relaunch (keyed off the SESSION, not a stale
992
+ * global).
993
+ * 3. the rails AgentSession metadata (`cli_resume_id` + legacy
994
+ * `claude_resume_id`) — survives a daemon restart so bridge startup /
995
+ * remote_load_context can restore it.
996
+ *
997
+ * Idempotent + throttled by the caller (runs on the live-usage tick and once
998
+ * shortly after launch). Best-effort — a capture failure leaves prior state
999
+ * intact and never blocks anything.
1000
+ */
1001
+ captureResumeId(conversationId) {
1002
+ const session = conversationId
1003
+ ? this.sessionManager.getByConversationId(conversationId)
1004
+ : this.sessionManager.getAll()[0];
1005
+ if (!session)
1006
+ return;
1007
+ // Locate by the ACTUAL launch cwd (same resolution extractTranscriptUsage uses).
1008
+ let cwd;
1009
+ for (const info of this.tmuxSessions.values()) {
1010
+ if (info.conversationId === conversationId) {
1011
+ cwd = info.cwd;
1012
+ break;
1013
+ }
1014
+ }
1015
+ cwd ||= this.getWorkingDirectory();
1016
+ let resumeId = null;
1017
+ try {
1018
+ resumeId = this.detectResumeId(cwd);
1019
+ }
1020
+ catch (err) {
1021
+ console.warn(`${this.getLogTag()} detectResumeId failed for conv=${conversationId}: ${err}`);
1022
+ return;
1023
+ }
1024
+ if (!resumeId)
1025
+ return;
1026
+ // No change — already captured this id.
1027
+ if (this.lastSessionId === resumeId && session.resumeId === resumeId)
1028
+ return;
1029
+ this.lastSessionId = resumeId;
1030
+ session.resumeId = resumeId;
1031
+ session.claudeResumeId = resumeId; // keep legacy alias in sync
1032
+ if (this.dsiloedClient && session.agentSessionId) {
1033
+ // MERGE — only the resume keys; a full replace would wipe workspace_* and
1034
+ // server-set keys. Persist BOTH a generic key and the legacy claude key the
1035
+ // bridge startup / remote_load_context already read.
1036
+ this.dsiloedClient.mergeAgentSessionMetadata(session.agentSessionId, {
1037
+ cli_resume_id: resumeId,
1038
+ claude_resume_id: resumeId,
1039
+ }).then(() => {
1040
+ console.log(`${this.getLogTag()} Captured resume id ${resumeId} for conv=${conversationId} (agent session ${session.agentSessionId})`);
1041
+ }).catch(err => console.error(`${this.getLogTag()} Failed to persist resume id:`, err));
1042
+ }
1043
+ else {
1044
+ console.log(`${this.getLogTag()} Captured resume id ${resumeId} for conv=${conversationId} (in-memory only)`);
1045
+ }
1046
+ }
960
1047
  // Returns true if usage was found and a report was initiated (used by the
961
1048
  // periodic reporter to only advance its throttle once there's something to send).
962
1049
  captureUsageFromTranscript(conversationId) {