@schoolai/shipyard 3.20.0 → 3.21.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 (30) hide show
  1. package/dist/capability-detector-worker.js +4 -4
  2. package/dist/{chunk-QNEFPC4Y.js → chunk-4WCHE6BN.js} +2 -2
  3. package/dist/{chunk-SECZGRK2.js → chunk-55ODHVH2.js} +2 -2
  4. package/dist/{chunk-OBYRPZRA.js → chunk-COFAFGTA.js} +28 -46
  5. package/dist/chunk-COFAFGTA.js.map +1 -0
  6. package/dist/{chunk-FMHVDAJK.js → chunk-DDWNDIZI.js} +3 -3
  7. package/dist/{chunk-TJ4TMMMB.js → chunk-GWG6Q7LG.js} +2 -2
  8. package/dist/{chunk-TJ4TMMMB.js.map → chunk-GWG6Q7LG.js.map} +1 -1
  9. package/dist/{chunk-LYUR7G6B.js → chunk-JJ6TS3FZ.js} +2 -2
  10. package/dist/{chunk-MD32Y6U4.js → chunk-UTVOF3I4.js} +2 -2
  11. package/dist/{chunk-OC75AUKJ.js → chunk-XXTFMFS5.js} +2 -2
  12. package/dist/cursor-runner.js +3 -3
  13. package/dist/electron-utility.js +2 -2
  14. package/dist/index.js +4 -4
  15. package/dist/{login-VNZ6AQDV.js → login-FLLL5EZF.js} +3 -3
  16. package/dist/{plan-backfill-ZNL2YQP6.js → plan-backfill-STEWGDCN.js} +4 -4
  17. package/dist/{serve-WG7HQAYG.js → serve-7XWAHTBU.js} +111 -86
  18. package/dist/{serve-WG7HQAYG.js.map → serve-7XWAHTBU.js.map} +1 -1
  19. package/dist/{start-5VG7QWUR.js → start-Y4FEOM4Y.js} +6 -6
  20. package/package.json +2 -2
  21. package/dist/chunk-OBYRPZRA.js.map +0 -1
  22. /package/dist/{chunk-QNEFPC4Y.js.map → chunk-4WCHE6BN.js.map} +0 -0
  23. /package/dist/{chunk-SECZGRK2.js.map → chunk-55ODHVH2.js.map} +0 -0
  24. /package/dist/{chunk-FMHVDAJK.js.map → chunk-DDWNDIZI.js.map} +0 -0
  25. /package/dist/{chunk-LYUR7G6B.js.map → chunk-JJ6TS3FZ.js.map} +0 -0
  26. /package/dist/{chunk-MD32Y6U4.js.map → chunk-UTVOF3I4.js.map} +0 -0
  27. /package/dist/{chunk-OC75AUKJ.js.map → chunk-XXTFMFS5.js.map} +0 -0
  28. /package/dist/{login-VNZ6AQDV.js.map → login-FLLL5EZF.js.map} +0 -0
  29. /package/dist/{plan-backfill-ZNL2YQP6.js.map → plan-backfill-STEWGDCN.js.map} +0 -0
  30. /package/dist/{start-5VG7QWUR.js.map → start-Y4FEOM4Y.js.map} +0 -0
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  isImageMimeType,
4
4
  parseAssetUri
5
- } from "./chunk-OC75AUKJ.js";
5
+ } from "./chunk-XXTFMFS5.js";
6
6
  import {
7
7
  assertNever
8
8
  } from "./chunk-X3MULCV5.js";
@@ -588,4 +588,4 @@ export {
588
588
  toRecord,
589
589
  buildCursorUserPrompt
590
590
  };
591
- //# sourceMappingURL=chunk-LYUR7G6B.js.map
591
+ //# sourceMappingURL=chunk-JJ6TS3FZ.js.map
@@ -15,7 +15,7 @@ import {
15
15
  DevicePollResponseSchema,
16
16
  DeviceStartResponseSchema,
17
17
  ROUTES
18
- } from "./chunk-TJ4TMMMB.js";
18
+ } from "./chunk-GWG6Q7LG.js";
19
19
  import {
20
20
  isDevMode,
21
21
  validateEnv
@@ -223,4 +223,4 @@ export {
223
223
  ensureAuthenticated,
224
224
  loginCommand
225
225
  };
226
- //# sourceMappingURL=chunk-MD32Y6U4.js.map
226
+ //# sourceMappingURL=chunk-UTVOF3I4.js.map
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  PUBLISHED_PREVIEW_KINDS,
4
4
  PUBLISH_TTL_CHOICES
5
- } from "./chunk-TJ4TMMMB.js";
5
+ } from "./chunk-GWG6Q7LG.js";
6
6
  import {
7
7
  external_exports
8
8
  } from "./chunk-JCEWPG3R.js";
@@ -29230,4 +29230,4 @@ export {
29230
29230
  encodeDrain,
29231
29231
  decodeFrame
29232
29232
  };
29233
- //# sourceMappingURL=chunk-OC75AUKJ.js.map
29233
+ //# sourceMappingURL=chunk-XXTFMFS5.js.map
@@ -4,12 +4,12 @@ import {
4
4
  } from "./chunk-CKQL7TWQ.js";
5
5
  import {
6
6
  buildCursorUserPrompt
7
- } from "./chunk-LYUR7G6B.js";
7
+ } from "./chunk-JJ6TS3FZ.js";
8
8
  import {
9
9
  ContentBlockSchema,
10
10
  HARNESS_SERVER_NAME
11
- } from "./chunk-OC75AUKJ.js";
12
- import "./chunk-TJ4TMMMB.js";
11
+ } from "./chunk-XXTFMFS5.js";
12
+ import "./chunk-GWG6Q7LG.js";
13
13
  import "./chunk-EHQITHQX.js";
14
14
  import "./chunk-X3MULCV5.js";
15
15
  import "./chunk-X53VIV2J.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getDaemonVersion
4
- } from "./chunk-FMHVDAJK.js";
4
+ } from "./chunk-DDWNDIZI.js";
5
5
  import {
6
6
  enableNativeCrashReports
7
7
  } from "./chunk-TSJOSKN3.js";
@@ -71,7 +71,7 @@ async function main() {
71
71
  await loadAuthFromConfig(env);
72
72
  crumb("post-auth-load");
73
73
  crumb("pre-serve-import");
74
- const { serve } = await import("./serve-WG7HQAYG.js");
74
+ const { serve } = await import("./serve-7XWAHTBU.js");
75
75
  crumb("post-serve-import");
76
76
  const portQueue = [];
77
77
  let acceptor = null;
package/dist/index.js CHANGED
@@ -118,7 +118,7 @@ async function loadAuthFromConfig(env) {
118
118
  async function handleSubcommand() {
119
119
  const subcommand = process.argv[2];
120
120
  if (subcommand === "login") {
121
- const { loginCommand } = await import("./login-VNZ6AQDV.js");
121
+ const { loginCommand } = await import("./login-FLLL5EZF.js");
122
122
  const hasCheck = process.argv.includes("--check");
123
123
  await loginCommand({ check: hasCheck });
124
124
  return true;
@@ -129,7 +129,7 @@ async function handleSubcommand() {
129
129
  return true;
130
130
  }
131
131
  if (subcommand === "start") {
132
- const { startCommand } = await import("./start-5VG7QWUR.js");
132
+ const { startCommand } = await import("./start-Y4FEOM4Y.js");
133
133
  await startCommand();
134
134
  return true;
135
135
  }
@@ -139,7 +139,7 @@ async function handleSubcommand() {
139
139
  return true;
140
140
  }
141
141
  if (subcommand === "plan-backfill") {
142
- const { planBackfillCommand } = await import("./plan-backfill-ZNL2YQP6.js");
142
+ const { planBackfillCommand } = await import("./plan-backfill-STEWGDCN.js");
143
143
  await planBackfillCommand();
144
144
  return true;
145
145
  }
@@ -151,7 +151,7 @@ async function main() {
151
151
  const args = parseCliArgs();
152
152
  if (args.serve) {
153
153
  await loadAuthFromConfig(env);
154
- const { serve } = await import("./serve-WG7HQAYG.js");
154
+ const { serve } = await import("./serve-7XWAHTBU.js");
155
155
  return serve({ isDev: env.SHIPYARD_DEV });
156
156
  }
157
157
  logger.error("Use `shipyard start` to run the daemon. Use --help for usage.");
@@ -3,10 +3,10 @@ import {
3
3
  ensureAuthenticated,
4
4
  getSignalingUrl,
5
5
  loginCommand
6
- } from "./chunk-MD32Y6U4.js";
6
+ } from "./chunk-UTVOF3I4.js";
7
7
  import "./chunk-ZHLJRR5O.js";
8
8
  import "./chunk-TFWDJCUJ.js";
9
- import "./chunk-TJ4TMMMB.js";
9
+ import "./chunk-GWG6Q7LG.js";
10
10
  import "./chunk-EHQITHQX.js";
11
11
  import "./chunk-X53VIV2J.js";
12
12
  import "./chunk-UTL5PF43.js";
@@ -17,4 +17,4 @@ export {
17
17
  getSignalingUrl,
18
18
  loginCommand
19
19
  };
20
- //# sourceMappingURL=login-VNZ6AQDV.js.map
20
+ //# sourceMappingURL=login-FLLL5EZF.js.map
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  buildTaskStateStore,
4
4
  runPlanBackfill
5
- } from "./chunk-SECZGRK2.js";
5
+ } from "./chunk-55ODHVH2.js";
6
6
  import "./chunk-RR6V6SNM.js";
7
- import "./chunk-OC75AUKJ.js";
8
- import "./chunk-TJ4TMMMB.js";
7
+ import "./chunk-XXTFMFS5.js";
8
+ import "./chunk-GWG6Q7LG.js";
9
9
  import "./chunk-EHQITHQX.js";
10
10
  import "./chunk-X3MULCV5.js";
11
11
  import {
@@ -65,4 +65,4 @@ async function planBackfillCommand(argv = process.argv.slice(3)) {
65
65
  export {
66
66
  planBackfillCommand
67
67
  };
68
- //# sourceMappingURL=plan-backfill-ZNL2YQP6.js.map
68
+ //# sourceMappingURL=plan-backfill-STEWGDCN.js.map
@@ -12,7 +12,7 @@ import {
12
12
  guardedSubscribe,
13
13
  makeInitialAttemptState,
14
14
  shutdownFileWatcherGuard
15
- } from "./chunk-QNEFPC4Y.js";
15
+ } from "./chunk-4WCHE6BN.js";
16
16
  import {
17
17
  TRAILER_SCHEMA_VERSION,
18
18
  appendTrailerToMessage,
@@ -39,13 +39,13 @@ import {
39
39
  startPlanBackfillForDaemon,
40
40
  sync,
41
41
  validatePeerId
42
- } from "./chunk-SECZGRK2.js";
42
+ } from "./chunk-55ODHVH2.js";
43
43
  import {
44
44
  loadAuthToken
45
45
  } from "./chunk-TFWDJCUJ.js";
46
46
  import {
47
47
  getDaemonVersion
48
- } from "./chunk-FMHVDAJK.js";
48
+ } from "./chunk-DDWNDIZI.js";
49
49
  import {
50
50
  collectPriorCrashDetail,
51
51
  getRecentWasmPanicMessages
@@ -174,7 +174,7 @@ import {
174
174
  unresolveReviewThread,
175
175
  withLabelAsync,
176
176
  writeCursorApiKeyToVault
177
- } from "./chunk-OBYRPZRA.js";
177
+ } from "./chunk-COFAFGTA.js";
178
178
  import {
179
179
  buildNodeSpawnEnv,
180
180
  nodeSpawnEnvOverlay,
@@ -235,7 +235,7 @@ import {
235
235
  createAssetResolver,
236
236
  toSdkContent,
237
237
  toSdkPermissionMode
238
- } from "./chunk-LYUR7G6B.js";
238
+ } from "./chunk-JJ6TS3FZ.js";
239
239
  import {
240
240
  AGENT_IDS,
241
241
  AGENT_SYSTEM_CLAUDE_CODE,
@@ -421,7 +421,7 @@ import {
421
421
  unsafeAssertSourceId,
422
422
  vizFileExtension,
423
423
  withPreferredRuntimeAuthMethod
424
- } from "./chunk-OC75AUKJ.js";
424
+ } from "./chunk-XXTFMFS5.js";
425
425
  import {
426
426
  AuthGitHubCallbackRequestSchema,
427
427
  AuthGitHubCallbackResponseSchema,
@@ -469,7 +469,7 @@ import {
469
469
  VaultKeyPutResponseSchema,
470
470
  classifyClaudeCodeCompatibility,
471
471
  classifyCodexCompatibility
472
- } from "./chunk-TJ4TMMMB.js";
472
+ } from "./chunk-GWG6Q7LG.js";
473
473
  import {
474
474
  external_exports as external_exports2
475
475
  } from "./chunk-EHQITHQX.js";
@@ -485,6 +485,7 @@ import {
485
485
  getShipyardHome,
486
486
  getStallProfilerConfig,
487
487
  isCodexKeychainReadEnabled,
488
+ isDevMode,
488
489
  isVanillaAgentMode,
489
490
  resolveNodeExecPath,
490
491
  validateEnv
@@ -3376,32 +3377,6 @@ function getHandlerTimingTracker(channel) {
3376
3377
 
3377
3378
  // src/shared/keep-awake.ts
3378
3379
  import { spawn } from "child_process";
3379
-
3380
- // src/shared/electron-ipc.ts
3381
- function getParentPort() {
3382
- const pp = Reflect.get(process, "parentPort");
3383
- return isElectronParentPort(pp) ? pp : null;
3384
- }
3385
- function isElectronParentPort(value) {
3386
- return value !== null && typeof value === "object" && typeof Reflect.get(value, "postMessage") === "function";
3387
- }
3388
- var _cachedPort;
3389
- function parentPort() {
3390
- if (_cachedPort === void 0) {
3391
- _cachedPort = getParentPort();
3392
- }
3393
- return _cachedPort;
3394
- }
3395
- function sendToElectronHost(msg) {
3396
- const port = parentPort();
3397
- if (!port) return;
3398
- port.postMessage(msg);
3399
- }
3400
- function isElectronUtility() {
3401
- return parentPort() !== null;
3402
- }
3403
-
3404
- // src/shared/keep-awake.ts
3405
3380
  var KEEP_AWAKE_GRACE_PERIOD_MS = 15 * 60 * 1e3;
3406
3381
  var darwinStrategy = {
3407
3382
  spawn: () => spawn("caffeinate", ["-dis"], { stdio: ["ignore", "ignore", "ignore"] })
@@ -3460,24 +3435,34 @@ var KeepAwakeManager = class {
3460
3435
  #log;
3461
3436
  #graceTimer = null;
3462
3437
  #gracePeriodMs;
3463
- /** When true, delegate power management to Electron main via IPC. */
3464
- #isElectron;
3465
- /** Last active-task count forwarded to Electron to avoid redundant messages. */
3466
- #lastElectronCount = -1;
3467
- constructor(log, gracePeriodMs = KEEP_AWAKE_GRACE_PERIOD_MS) {
3468
- this.#isElectron = isElectronUtility();
3438
+ #pidTracker;
3439
+ /**
3440
+ * `pidTracker` is optional (not a required dep) because the CLI/test callers
3441
+ * legitimately run without the daemon's orphan-sweep store; when absent, the
3442
+ * helper still works, it just isn't reaped after an abrupt exit.
3443
+ */
3444
+ constructor(log, gracePeriodMs = KEEP_AWAKE_GRACE_PERIOD_MS, pidTracker = null) {
3469
3445
  this.#log = log;
3470
3446
  this.#gracePeriodMs = gracePeriodMs;
3471
- if (this.#isElectron) {
3472
- this.#strategy = null;
3473
- log.info("Keep-awake delegated to Electron powerSaveBlocker");
3474
- return;
3475
- }
3447
+ this.#pidTracker = pidTracker;
3476
3448
  this.#strategy = createKeepAwakeStrategy();
3477
3449
  if (!this.#strategy) {
3478
3450
  log.info({ platform: process.platform }, "Keep-awake not supported on this platform");
3479
3451
  }
3480
3452
  }
3453
+ #trackChild(pid) {
3454
+ if (pid === void 0 || !this.#pidTracker) return;
3455
+ this.#pidTracker.add(pid).catch((err3) => {
3456
+ this.#log.debug({ err: err3, pid }, "Keep-awake pid track failed");
3457
+ });
3458
+ }
3459
+ /** Returns the deregistration promise so `shutdown()` can await the flush. */
3460
+ #untrackChild(pid) {
3461
+ if (pid === void 0 || !this.#pidTracker) return Promise.resolve();
3462
+ return this.#pidTracker.remove(pid).catch((err3) => {
3463
+ this.#log.debug({ err: err3, pid }, "Keep-awake pid untrack failed");
3464
+ });
3465
+ }
3481
3466
  get running() {
3482
3467
  return this.#child !== null;
3483
3468
  }
@@ -3490,22 +3475,10 @@ var KeepAwakeManager = class {
3490
3475
  * task → idle → task flicker shouldn't churn the subprocess. `off` stops
3491
3476
  * immediately (the user explicitly disabled it). `always` ignores
3492
3477
  * `hasActiveTasks` entirely.
3493
- *
3494
- * When running inside Electron, delegates to the main process via IPC
3495
- * instead of spawning a platform helper subprocess.
3496
3478
  */
3497
3479
  update(mode, hasActiveTasks) {
3498
3480
  this.#restartAttempts = 0;
3499
3481
  const wantRunning = wantsRunning(mode, hasActiveTasks);
3500
- if (this.#isElectron) {
3501
- const count = wantRunning ? 1 : 0;
3502
- if (count !== this.#lastElectronCount) {
3503
- this.#lastElectronCount = count;
3504
- sendToElectronHost({ type: "power:tasks-running", count });
3505
- this.#log.info({ count }, "Keep-awake IPC sent to Electron host");
3506
- }
3507
- return;
3508
- }
3509
3482
  if (wantRunning) {
3510
3483
  this.#cancelGrace();
3511
3484
  this.#shouldBeRunning = true;
@@ -3515,7 +3488,7 @@ var KeepAwakeManager = class {
3515
3488
  if (mode === "off") {
3516
3489
  this.#shouldBeRunning = false;
3517
3490
  this.#cancelGrace();
3518
- this.#stop();
3491
+ void this.#stop();
3519
3492
  return;
3520
3493
  }
3521
3494
  if (this.#graceTimer) return;
@@ -3525,17 +3498,15 @@ var KeepAwakeManager = class {
3525
3498
  return;
3526
3499
  }
3527
3500
  }
3528
- shutdown() {
3501
+ /**
3502
+ * Awaits the pid deregistration so the tracker file is flushed before the
3503
+ * daemon exits — otherwise a fire-and-forget remove can lose the race with
3504
+ * `process.exit`, stranding a dead pid the next boot's orphan sweep signals.
3505
+ */
3506
+ async shutdown() {
3529
3507
  this.#shouldBeRunning = false;
3530
3508
  this.#cancelGrace();
3531
- if (this.#isElectron) {
3532
- if (this.#lastElectronCount !== 0) {
3533
- this.#lastElectronCount = 0;
3534
- sendToElectronHost({ type: "power:tasks-running", count: 0 });
3535
- }
3536
- return;
3537
- }
3538
- this.#stop();
3509
+ await this.#stop();
3539
3510
  }
3540
3511
  #startGrace() {
3541
3512
  if (this.#graceTimer) return;
@@ -3543,7 +3514,7 @@ var KeepAwakeManager = class {
3543
3514
  this.#graceTimer = setTimeout(() => {
3544
3515
  this.#graceTimer = null;
3545
3516
  this.#log.info("Keep-awake grace period expired");
3546
- this.#stop();
3517
+ void this.#stop();
3547
3518
  }, this.#gracePeriodMs);
3548
3519
  this.#graceTimer.unref();
3549
3520
  }
@@ -3559,14 +3530,17 @@ var KeepAwakeManager = class {
3559
3530
  const child = this.#strategy.spawn();
3560
3531
  this.#child = child;
3561
3532
  child.unref();
3533
+ this.#trackChild(child.pid);
3562
3534
  child.on("exit", (code, signal) => {
3563
3535
  if (this.#child !== child) return;
3536
+ void this.#untrackChild(child.pid);
3564
3537
  this.#log.info({ code, signal }, "Keep-awake process exited");
3565
3538
  this.#child = null;
3566
3539
  this.#scheduleRestart();
3567
3540
  });
3568
3541
  child.on("error", (err3) => {
3569
3542
  if (this.#child !== child) return;
3543
+ void this.#untrackChild(child.pid);
3570
3544
  this.#log.warn({ err: err3.message }, "Keep-awake process error");
3571
3545
  this.#child = null;
3572
3546
  this.#scheduleRestart();
@@ -3601,7 +3575,7 @@ var KeepAwakeManager = class {
3601
3575
  timer.unref();
3602
3576
  }
3603
3577
  #stop() {
3604
- if (!this.#child) return;
3578
+ if (!this.#child) return Promise.resolve();
3605
3579
  const pid = this.#child.pid;
3606
3580
  try {
3607
3581
  this.#child.kill("SIGTERM");
@@ -3610,6 +3584,7 @@ var KeepAwakeManager = class {
3610
3584
  }
3611
3585
  this.#child = null;
3612
3586
  this.#log.info({ pid }, "Keep-awake stopped");
3587
+ return this.#untrackChild(pid);
3613
3588
  }
3614
3589
  };
3615
3590
 
@@ -6021,7 +5996,7 @@ function nanoid(size = 21) {
6021
5996
  }
6022
5997
 
6023
5998
  // src/services/bootstrap/signaling.ts
6024
- var DAEMON_NPM_VERSION = true ? "3.20.0" : "unknown";
5999
+ var DAEMON_NPM_VERSION = true ? "3.21.0" : "unknown";
6025
6000
  function createDaemonSignaling(config) {
6026
6001
  const agentId = config.agentId ?? nanoid();
6027
6002
  function send(msg) {
@@ -19843,7 +19818,7 @@ async function safeStorageEncrypt(plaintext) {
19843
19818
  async function safeStorageDecrypt(b64Ciphertext) {
19844
19819
  return sendSafeStorageRequest({ type: "safe-storage:decrypt", ciphertext: b64Ciphertext });
19845
19820
  }
19846
- function getParentPort2() {
19821
+ function getParentPort() {
19847
19822
  const pp = Reflect.get(process, "parentPort");
19848
19823
  return isParentPort(pp) ? pp : null;
19849
19824
  }
@@ -19851,7 +19826,7 @@ function isParentPort(value) {
19851
19826
  return value !== null && typeof value === "object" && typeof Reflect.get(value, "postMessage") === "function" && typeof Reflect.get(value, "on") === "function" && typeof Reflect.get(value, "off") === "function";
19852
19827
  }
19853
19828
  async function sendSafeStorageRequest(request) {
19854
- const port = getParentPort2();
19829
+ const port = getParentPort();
19855
19830
  if (!port) return null;
19856
19831
  const requestId = globalThis.crypto.randomUUID();
19857
19832
  const livePort = port;
@@ -21112,6 +21087,7 @@ function prefsToFraction(prefs, maxTokens) {
21112
21087
  return prefs.thresholdTokens / maxTokens;
21113
21088
  }
21114
21089
  var ONE_M_SPAWN_PREFIXES = [
21090
+ "claude-opus-5",
21115
21091
  "claude-opus-4-8",
21116
21092
  "claude-opus-4-7",
21117
21093
  "claude-opus-4-6",
@@ -24161,6 +24137,29 @@ function buildRateLimitWiring(daemon) {
24161
24137
 
24162
24138
  // src/services/notifications/notifications-handler.ts
24163
24139
  import { randomUUID as randomUUID9 } from "crypto";
24140
+
24141
+ // src/shared/electron-ipc.ts
24142
+ function getParentPort2() {
24143
+ const pp = Reflect.get(process, "parentPort");
24144
+ return isElectronParentPort(pp) ? pp : null;
24145
+ }
24146
+ function isElectronParentPort(value) {
24147
+ return value !== null && typeof value === "object" && typeof Reflect.get(value, "postMessage") === "function";
24148
+ }
24149
+ var _cachedPort;
24150
+ function parentPort() {
24151
+ if (_cachedPort === void 0) {
24152
+ _cachedPort = getParentPort2();
24153
+ }
24154
+ return _cachedPort;
24155
+ }
24156
+ function sendToElectronHost(msg) {
24157
+ const port = parentPort();
24158
+ if (!port) return;
24159
+ port.postMessage(msg);
24160
+ }
24161
+
24162
+ // src/services/notifications/notifications-handler.ts
24164
24163
  var NOTIFICATIONS_PER_TASK_CAP = 50;
24165
24164
  var CREATE_THEN_RESOLVE_WINDOW_MS = 500;
24166
24165
  var DEFAULT_GC_HORIZON_MS = 24 * 60 * 60 * 1e3;
@@ -78949,11 +78948,23 @@ var SessionRecoveryController = class {
78949
78948
  return { kind: "fresh" };
78950
78949
  }
78951
78950
  /**
78952
- * Returns true and clears stale session pointers when the persisted
78953
- * session belongs to a different auth identity than the one we're
78954
- * about to spawn under. Both sides must be non-null to fire — a
78951
+ * Decide whether an auth-identity change (account / org / provider switch)
78952
+ * should force a fresh session. Both sides must be non-null to fire — a
78955
78953
  * missing identity on either side falls through to the existing
78956
78954
  * #sawResumeFailure safety net.
78955
+ *
78956
+ * Claude Code: `claude --resume` is a pure local JSONL replay keyed by
78957
+ * cwd-slug + sessionId, with NO account check (verified against the
78958
+ * SDK-bundled native binary). A different-account session on the same
78959
+ * machine/cwd resumes losslessly, so we let it resume — no force-fresh, no
78960
+ * summary — and return false so `resolveSpawnSystemPrompt` does not inject a
78961
+ * session-loss digest over a healthy resume. A genuinely-missing session
78962
+ * (created on another machine / a changed worktree) still fails at spawn and
78963
+ * is caught by the reactive #tryStaleResumeRetry net.
78964
+ *
78965
+ * Other runtimes (Codex, etc.): keep the conservative force-fresh. Codex's
78966
+ * shared app-server caches `expected_account_id` and refuses cross-account
78967
+ * auth reload, so resuming across accounts is unsafe there.
78957
78968
  */
78958
78969
  async #detectAndClearIdentityMismatch() {
78959
78970
  const persisted = await this.#deps.loadPersistedSession(this.#deps.channelId).catch(() => null);
@@ -78963,9 +78974,13 @@ var SessionRecoveryController = class {
78963
78974
  this.#deps.log({
78964
78975
  event: "thread_identity_mismatch_detected",
78965
78976
  threadId: this.#deps.threadId,
78977
+ agentSystem: this.#deps.getAgentSystem(),
78966
78978
  persistedIdentity: persisted?.authIdentity,
78967
78979
  currentAuthIdentity
78968
78980
  });
78981
+ if (this.#deps.getAgentSystem() === AGENT_SYSTEM_CLAUDE_CODE) {
78982
+ return false;
78983
+ }
78969
78984
  this.#ownSessionId = null;
78970
78985
  this.#effectiveSpawnMode = { kind: "fresh" };
78971
78986
  this.#hasForked = false;
@@ -79224,8 +79239,19 @@ var SessionRecoveryController = class {
79224
79239
  }
79225
79240
  };
79226
79241
 
79242
+ // src/services/storage/channel-transcript-path.ts
79243
+ import { join as pathJoin } from "path";
79244
+ function resolveChannelTranscriptPath(dataDir, channelId) {
79245
+ return pathJoin(dataDir, "channels", `${channelId}.jsonl`);
79246
+ }
79247
+ function resolveDefaultChannelTranscriptPath(channelId) {
79248
+ return resolveChannelTranscriptPath(
79249
+ pathJoin(getShipyardHome(), isDevMode() ? "data-dev" : "data"),
79250
+ channelId
79251
+ );
79252
+ }
79253
+
79227
79254
  // src/services/conversation/conversation-replay.ts
79228
- var SESSION_LOSS_SUMMARY_CAP_CHARS = 2e4;
79229
79255
  async function buildSessionLossSummary(params) {
79230
79256
  const { store, channelId, log, threadId } = params;
79231
79257
  try {
@@ -79243,12 +79269,10 @@ async function buildSessionLossSummary(params) {
79243
79269
  (m2) => m2.senderKind === "human" || m2.senderKind === "agent"
79244
79270
  );
79245
79271
  if (relevant.length === 0) return void 0;
79246
- const result = serializeCompactionContext(relevant, null);
79272
+ const transcriptPath = resolveDefaultChannelTranscriptPath(channelId);
79273
+ const result = serializeCompactionContext(relevant, { absolutePath: transcriptPath });
79247
79274
  if (result.charsSerialized === 0) return void 0;
79248
- const text = result.text;
79249
- if (text.length <= SESSION_LOSS_SUMMARY_CAP_CHARS) return text;
79250
- return `${text.slice(0, SESSION_LOSS_SUMMARY_CAP_CHARS)}
79251
- [...session-loss summary truncated at ${SESSION_LOSS_SUMMARY_CAP_CHARS} chars]`;
79275
+ return result.text;
79252
79276
  } catch (err3) {
79253
79277
  const errMsg = err3 instanceof Error ? err3.message : String(err3);
79254
79278
  log({
@@ -79534,7 +79558,8 @@ var Thread = class {
79534
79558
  sendMessage: (content) => this.#manager.sendMessage(content),
79535
79559
  persistError: (msg) => this.#persistErrorAsAssistantMessage(msg),
79536
79560
  loadPersistedSession: (channelId) => this.#config.sessionPersistence.load(channelId),
79537
- getCurrentAuthIdentity: () => this.#config.getCurrentAuthIdentity()
79561
+ getCurrentAuthIdentity: () => this.#config.getCurrentAuthIdentity(),
79562
+ getAgentSystem: () => this.#agentSystem
79538
79563
  },
79539
79564
  {
79540
79565
  initialSpawnMode: config.spawnMode,
@@ -85609,7 +85634,7 @@ function mapSmStatusToWire(status) {
85609
85634
 
85610
85635
  // src/services/task/orchestrator/task-compaction.ts
85611
85636
  import { randomUUID as randomUUID22 } from "crypto";
85612
- import { join as pathJoin } from "path";
85637
+ import { join as pathJoin2 } from "path";
85613
85638
  async function buildCompactionSnapshot(deps, instructions) {
85614
85639
  const messages = await deps.store.getMessages(deps.channelId);
85615
85640
  const threadId = randomUUID22();
@@ -85632,7 +85657,7 @@ async function buildCompactionSnapshot(deps, instructions) {
85632
85657
  readOnly: true,
85633
85658
  isCompaction: true
85634
85659
  };
85635
- const archiveAbsolutePath = pathJoin(
85660
+ const archiveAbsolutePath = pathJoin2(
85636
85661
  getShipyardHome(),
85637
85662
  "data",
85638
85663
  "channels",
@@ -98283,7 +98308,7 @@ async function createDaemon(deps) {
98283
98308
  taskStoreBroadcast.dispose();
98284
98309
  userSettingsUnsub();
98285
98310
  daemonBroadcasts.dispose();
98286
- keepAwakeManager.shutdown();
98311
+ await keepAwakeManager.shutdown();
98287
98312
  healthMetrics.stop();
98288
98313
  planDocGapReporter.stop();
98289
98314
  gcObserver.stop();
@@ -100936,7 +100961,7 @@ async function runServeBody(options, captureRefs) {
100936
100961
  const tokenStore = new MCPTokenStore(shipyardHome, logAdapter);
100937
100962
  tokenStoreRef.current = tokenStore;
100938
100963
  const settingsStore = buildDaemonSettingsStore(dataDir);
100939
- const keepAwakeManager = new KeepAwakeManager(log);
100964
+ const keepAwakeManager = new KeepAwakeManager(log, void 0, pidTracker);
100940
100965
  if (!resolvedSignalingUrl) {
100941
100966
  log.error("Missing signalingUrl in auth config \u2014 cannot start daemon without signaling server");
100942
100967
  process.exit(1);
@@ -101645,4 +101670,4 @@ export {
101645
101670
  decideWorkspaceScope,
101646
101671
  serve
101647
101672
  };
101648
- //# sourceMappingURL=serve-WG7HQAYG.js.map
101673
+ //# sourceMappingURL=serve-7XWAHTBU.js.map