@schoolai/shipyard 3.33.0-rc.20260923.1 → 3.33.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/{auth-VKW72LVH.js → auth-JOCEWSRP.js} +3 -3
  2. package/dist/capability-detector-worker.js +8 -8
  3. package/dist/{chunk-M6XAVFHJ.js → chunk-35QUCNC4.js} +3 -3
  4. package/dist/{chunk-WKJAGQU7.js → chunk-5IDV3G5I.js} +6 -6
  5. package/dist/{chunk-FIE2FRIW.js → chunk-5SURQQLD.js} +2 -2
  6. package/dist/{chunk-ZXYFMJAS.js → chunk-AVOYKLEX.js} +2 -2
  7. package/dist/{chunk-RYZH5KM3.js → chunk-CTVKFKRG.js} +2 -2
  8. package/dist/{chunk-JYAI3JHY.js → chunk-DFIUWLZ2.js} +4 -4
  9. package/dist/{chunk-Y6AAH7LO.js → chunk-EM3SPYXE.js} +2 -2
  10. package/dist/{chunk-3PJULQHI.js → chunk-FHEPAJ33.js} +2 -2
  11. package/dist/{chunk-XPOXRIHH.js → chunk-FTQ7J3XF.js} +7 -7
  12. package/dist/{chunk-FKOUB6H6.js → chunk-HM3SAIPU.js} +29 -2
  13. package/dist/{chunk-FKOUB6H6.js.map → chunk-HM3SAIPU.js.map} +1 -1
  14. package/dist/{chunk-ELZLWLTO.js → chunk-HYK7G5WV.js} +2 -2
  15. package/dist/{chunk-FYT3ETTP.js → chunk-IX4BZWVO.js} +4 -4
  16. package/dist/{chunk-4WJOA7HF.js → chunk-RP7Z3PPQ.js} +4 -4
  17. package/dist/{chunk-XPYW5WQS.js → chunk-T5J6HZOQ.js} +2 -2
  18. package/dist/{chunk-MM3M2KAC.js → chunk-VOS3HC7Y.js} +2 -2
  19. package/dist/cursor-runner.js +3 -3
  20. package/dist/electron-utility.js +6 -6
  21. package/dist/{git-repo-K45YAY55.js → git-repo-2Q3UWJL4.js} +4 -4
  22. package/dist/index.js +10 -10
  23. package/dist/{logger-YFXXQZ5J.js → logger-KG26Y4CL.js} +3 -3
  24. package/dist/{login-SOAGMUHR.js → login-7GIEEET5.js} +6 -6
  25. package/dist/{logout-H4A4CJJN.js → logout-RM3HLME6.js} +5 -5
  26. package/dist/{mcp-servers-GHDSX3UE.js → mcp-servers-T3XIZE7R.js} +4 -4
  27. package/dist/{plan-backfill-W4FLMVC6.js → plan-backfill-NFCVURLA.js} +4 -4
  28. package/dist/{roi-QAZLNMJ3.js → roi-XZXHSXYB.js} +3 -3
  29. package/dist/{serve-SDRQ7JYB.js → serve-BUT2GA6K.js} +1299 -696
  30. package/dist/{serve-SDRQ7JYB.js.map → serve-BUT2GA6K.js.map} +1 -1
  31. package/dist/{skills-RO2BW4XO.js → skills-EGWENCJ4.js} +2 -2
  32. package/dist/{start-DHYV7OQM.js → start-4V5DGDB7.js} +10 -10
  33. package/package.json +1 -1
  34. /package/dist/{auth-VKW72LVH.js.map → auth-JOCEWSRP.js.map} +0 -0
  35. /package/dist/{chunk-M6XAVFHJ.js.map → chunk-35QUCNC4.js.map} +0 -0
  36. /package/dist/{chunk-WKJAGQU7.js.map → chunk-5IDV3G5I.js.map} +0 -0
  37. /package/dist/{chunk-FIE2FRIW.js.map → chunk-5SURQQLD.js.map} +0 -0
  38. /package/dist/{chunk-ZXYFMJAS.js.map → chunk-AVOYKLEX.js.map} +0 -0
  39. /package/dist/{chunk-RYZH5KM3.js.map → chunk-CTVKFKRG.js.map} +0 -0
  40. /package/dist/{chunk-JYAI3JHY.js.map → chunk-DFIUWLZ2.js.map} +0 -0
  41. /package/dist/{chunk-Y6AAH7LO.js.map → chunk-EM3SPYXE.js.map} +0 -0
  42. /package/dist/{chunk-3PJULQHI.js.map → chunk-FHEPAJ33.js.map} +0 -0
  43. /package/dist/{chunk-XPOXRIHH.js.map → chunk-FTQ7J3XF.js.map} +0 -0
  44. /package/dist/{chunk-ELZLWLTO.js.map → chunk-HYK7G5WV.js.map} +0 -0
  45. /package/dist/{chunk-FYT3ETTP.js.map → chunk-IX4BZWVO.js.map} +0 -0
  46. /package/dist/{chunk-4WJOA7HF.js.map → chunk-RP7Z3PPQ.js.map} +0 -0
  47. /package/dist/{chunk-XPYW5WQS.js.map → chunk-T5J6HZOQ.js.map} +0 -0
  48. /package/dist/{chunk-MM3M2KAC.js.map → chunk-VOS3HC7Y.js.map} +0 -0
  49. /package/dist/{git-repo-K45YAY55.js.map → git-repo-2Q3UWJL4.js.map} +0 -0
  50. /package/dist/{logger-YFXXQZ5J.js.map → logger-KG26Y4CL.js.map} +0 -0
  51. /package/dist/{login-SOAGMUHR.js.map → login-7GIEEET5.js.map} +0 -0
  52. /package/dist/{logout-H4A4CJJN.js.map → logout-RM3HLME6.js.map} +0 -0
  53. /package/dist/{mcp-servers-GHDSX3UE.js.map → mcp-servers-T3XIZE7R.js.map} +0 -0
  54. /package/dist/{plan-backfill-W4FLMVC6.js.map → plan-backfill-NFCVURLA.js.map} +0 -0
  55. /package/dist/{roi-QAZLNMJ3.js.map → roi-XZXHSXYB.js.map} +0 -0
  56. /package/dist/{skills-RO2BW4XO.js.map → skills-EGWENCJ4.js.map} +0 -0
  57. /package/dist/{start-DHYV7OQM.js.map → start-4V5DGDB7.js.map} +0 -0
@@ -5,8 +5,8 @@ import {
5
5
  loadAuthToken,
6
6
  readConfig,
7
7
  writeConfig
8
- } from "./chunk-XPYW5WQS.js";
9
- import "./chunk-FKOUB6H6.js";
8
+ } from "./chunk-T5J6HZOQ.js";
9
+ import "./chunk-HM3SAIPU.js";
10
10
  import "./chunk-XVW6VCKW.js";
11
11
  import "./chunk-2H7UOFLK.js";
12
12
  export {
@@ -16,4 +16,4 @@ export {
16
16
  readConfig,
17
17
  writeConfig
18
18
  };
19
- //# sourceMappingURL=auth-VKW72LVH.js.map
19
+ //# sourceMappingURL=auth-JOCEWSRP.js.map
@@ -3,27 +3,27 @@ import {
3
3
  detectCapabilities,
4
4
  refreshMcpServers,
5
5
  registerBuiltInProfiles
6
- } from "./chunk-XPOXRIHH.js";
7
- import "./chunk-ELZLWLTO.js";
8
- import "./chunk-Y6AAH7LO.js";
6
+ } from "./chunk-FTQ7J3XF.js";
7
+ import "./chunk-HYK7G5WV.js";
8
+ import "./chunk-EM3SPYXE.js";
9
9
  import {
10
10
  getRepoMetadata
11
- } from "./chunk-WKJAGQU7.js";
11
+ } from "./chunk-5IDV3G5I.js";
12
12
  import "./chunk-4T2OQAVL.js";
13
13
  import {
14
14
  MCPTokenStore
15
- } from "./chunk-FYT3ETTP.js";
15
+ } from "./chunk-IX4BZWVO.js";
16
16
  import "./chunk-VHPNDDB5.js";
17
17
  import "./chunk-ZFKJAYAN.js";
18
- import "./chunk-3PJULQHI.js";
18
+ import "./chunk-FHEPAJ33.js";
19
19
  import "./chunk-DQQOVPVK.js";
20
20
  import "./chunk-MV7VSD2T.js";
21
21
  import "./chunk-EHQITHQX.js";
22
22
  import {
23
23
  flushLogger,
24
24
  logger
25
- } from "./chunk-FIE2FRIW.js";
26
- import "./chunk-FKOUB6H6.js";
25
+ } from "./chunk-5SURQQLD.js";
26
+ import "./chunk-HM3SAIPU.js";
27
27
  import "./chunk-X3MULCV5.js";
28
28
  import "./chunk-XVW6VCKW.js";
29
29
  import "./chunk-2H7UOFLK.js";
@@ -34,11 +34,11 @@ import {
34
34
  } from "./chunk-DQQOVPVK.js";
35
35
  import {
36
36
  logger
37
- } from "./chunk-FIE2FRIW.js";
37
+ } from "./chunk-5SURQQLD.js";
38
38
  import {
39
39
  getPlanBackfillMode,
40
40
  getShipyardHome
41
- } from "./chunk-FKOUB6H6.js";
41
+ } from "./chunk-HM3SAIPU.js";
42
42
  import {
43
43
  assertNever
44
44
  } from "./chunk-X3MULCV5.js";
@@ -34988,4 +34988,4 @@ export {
34988
34988
  runPlanBackfill,
34989
34989
  buildTaskStateStore
34990
34990
  };
34991
- //# sourceMappingURL=chunk-M6XAVFHJ.js.map
34991
+ //# sourceMappingURL=chunk-35QUCNC4.js.map
@@ -7,10 +7,10 @@ import {
7
7
  } from "./chunk-VHPNDDB5.js";
8
8
  import {
9
9
  logger
10
- } from "./chunk-FIE2FRIW.js";
10
+ } from "./chunk-5SURQQLD.js";
11
11
  import {
12
12
  getShipyardHome
13
- } from "./chunk-FKOUB6H6.js";
13
+ } from "./chunk-HM3SAIPU.js";
14
14
  import {
15
15
  external_exports
16
16
  } from "./chunk-XVW6VCKW.js";
@@ -261,7 +261,7 @@ async function refreshRepoPathsInBackground(log) {
261
261
  const startGen = cacheGeneration;
262
262
  const start = Date.now();
263
263
  try {
264
- const { findGitRepos: findGitRepos2, discoverWorktrees: discoverWorktrees2 } = await import("./git-repo-K45YAY55.js");
264
+ const { findGitRepos: findGitRepos2, discoverWorktrees: discoverWorktrees2 } = await import("./git-repo-2Q3UWJL4.js");
265
265
  const { homedir: homedir2 } = await import("os");
266
266
  const repos = await findGitRepos2(homedir2());
267
267
  const worktrees = await discoverWorktrees2(repos);
@@ -653,7 +653,7 @@ async function runDetectEnvironments(lastKnown) {
653
653
  repoPaths = await findGitRepos(homedir2());
654
654
  } catch (err) {
655
655
  if (lastKnown && lastKnown.length > 0) {
656
- const { logger: logger2 } = await import("./logger-YFXXQZ5J.js");
656
+ const { logger: logger2 } = await import("./logger-KG26Y4CL.js");
657
657
  logger2.warn(
658
658
  { err, lastKnownCount: lastKnown.length },
659
659
  "detectEnvironments findGitRepos threw \u2014 preserving lastKnown"
@@ -663,7 +663,7 @@ async function runDetectEnvironments(lastKnown) {
663
663
  return [];
664
664
  }
665
665
  if (repoPaths.length === 0 && lastKnown && lastKnown.length > 0) {
666
- const { logger: logger2 } = await import("./logger-YFXXQZ5J.js");
666
+ const { logger: logger2 } = await import("./logger-KG26Y4CL.js");
667
667
  logger2.warn(
668
668
  { lastKnownCount: lastKnown.length },
669
669
  "detectEnvironments walk empty but lastKnown non-empty \u2014 preserving lastKnown"
@@ -796,4 +796,4 @@ export {
796
796
  discoverWorktrees,
797
797
  _testing
798
798
  };
799
- //# sourceMappingURL=chunk-WKJAGQU7.js.map
799
+ //# sourceMappingURL=chunk-5IDV3G5I.js.map
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  getShipyardHome,
4
4
  validateEnv
5
- } from "./chunk-FKOUB6H6.js";
5
+ } from "./chunk-HM3SAIPU.js";
6
6
 
7
7
  // src/shared/logger.ts
8
8
  import { mkdirSync } from "fs";
@@ -145,4 +145,4 @@ export {
145
145
  createChildLogger,
146
146
  flushLogger
147
147
  };
148
- //# sourceMappingURL=chunk-FIE2FRIW.js.map
148
+ //# sourceMappingURL=chunk-5SURQQLD.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  validateEnv
4
- } from "./chunk-FKOUB6H6.js";
4
+ } from "./chunk-HM3SAIPU.js";
5
5
  import {
6
6
  external_exports
7
7
  } from "./chunk-XVW6VCKW.js";
@@ -48,4 +48,4 @@ function readDaemonVersion() {
48
48
  export {
49
49
  getDaemonVersion
50
50
  };
51
- //# sourceMappingURL=chunk-ZXYFMJAS.js.map
51
+ //# sourceMappingURL=chunk-AVOYKLEX.js.map
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  getShipyardHome,
7
7
  validateEnv
8
- } from "./chunk-FKOUB6H6.js";
8
+ } from "./chunk-HM3SAIPU.js";
9
9
 
10
10
  // src/services/bootstrap/native-crash-report.ts
11
11
  import { mkdirSync } from "fs";
@@ -59,4 +59,4 @@ function setOptionalFlag(report, flag) {
59
59
  export {
60
60
  enableNativeCrashReports
61
61
  };
62
- //# sourceMappingURL=chunk-RYZH5KM3.js.map
62
+ //# sourceMappingURL=chunk-CTVKFKRG.js.map
@@ -2,13 +2,13 @@
2
2
  import {
3
3
  print,
4
4
  printError
5
- } from "./chunk-MM3M2KAC.js";
5
+ } from "./chunk-VOS3HC7Y.js";
6
6
  import {
7
7
  getConfigPath,
8
8
  loadAuthToken,
9
9
  readConfig,
10
10
  writeConfig
11
- } from "./chunk-XPYW5WQS.js";
11
+ } from "./chunk-T5J6HZOQ.js";
12
12
  import {
13
13
  DeviceExchangeCodeResponseSchema,
14
14
  DevicePollPendingSchema,
@@ -19,7 +19,7 @@ import {
19
19
  import {
20
20
  isDevMode,
21
21
  validateEnv
22
- } from "./chunk-FKOUB6H6.js";
22
+ } from "./chunk-HM3SAIPU.js";
23
23
  import {
24
24
  external_exports
25
25
  } from "./chunk-XVW6VCKW.js";
@@ -223,4 +223,4 @@ export {
223
223
  ensureAuthenticated,
224
224
  loginCommand
225
225
  };
226
- //# sourceMappingURL=chunk-JYAI3JHY.js.map
226
+ //# sourceMappingURL=chunk-DFIUWLZ2.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  resolveNodeExecPath
4
- } from "./chunk-FKOUB6H6.js";
4
+ } from "./chunk-HM3SAIPU.js";
5
5
 
6
6
  // src/shared/spawn-as-node.ts
7
7
  var isElectronOverride = null;
@@ -34,4 +34,4 @@ export {
34
34
  buildNodeSpawnEnv,
35
35
  rewriteElectronNodeScriptSpawn
36
36
  };
37
- //# sourceMappingURL=chunk-Y6AAH7LO.js.map
37
+ //# sourceMappingURL=chunk-EM3SPYXE.js.map
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-DQQOVPVK.js";
6
6
  import {
7
7
  logger
8
- } from "./chunk-FIE2FRIW.js";
8
+ } from "./chunk-5SURQQLD.js";
9
9
  import {
10
10
  assertNever
11
11
  } from "./chunk-X3MULCV5.js";
@@ -588,4 +588,4 @@ export {
588
588
  toRecord,
589
589
  buildCursorUserPrompt
590
590
  };
591
- //# sourceMappingURL=chunk-3PJULQHI.js.map
591
+ //# sourceMappingURL=chunk-FHEPAJ33.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  detectSkills
4
- } from "./chunk-ELZLWLTO.js";
4
+ } from "./chunk-HYK7G5WV.js";
5
5
  import {
6
6
  AUTH_STATUS_TIMEOUT_MS,
7
7
  BUFFER_OVERFLOW_MSG,
@@ -13,7 +13,7 @@ import {
13
13
  run,
14
14
  runWithTimeout,
15
15
  truncateDiff
16
- } from "./chunk-WKJAGQU7.js";
16
+ } from "./chunk-5IDV3G5I.js";
17
17
  import {
18
18
  gitExecSafe
19
19
  } from "./chunk-4T2OQAVL.js";
@@ -23,7 +23,7 @@ import {
23
23
  CURSOR_RUNTIME_ID,
24
24
  DEVIN_RUNTIME_ID,
25
25
  detectMCPServers
26
- } from "./chunk-FYT3ETTP.js";
26
+ } from "./chunk-IX4BZWVO.js";
27
27
  import {
28
28
  isEnoent
29
29
  } from "./chunk-VHPNDDB5.js";
@@ -39,7 +39,7 @@ import {
39
39
  formatTaskFeedback,
40
40
  toRecord,
41
41
  toSdkContent
42
- } from "./chunk-3PJULQHI.js";
42
+ } from "./chunk-FHEPAJ33.js";
43
43
  import {
44
44
  AGENT_IDS,
45
45
  AGENT_SYSTEM_CLAUDE_CODE,
@@ -66,12 +66,12 @@ import {
66
66
  } from "./chunk-MV7VSD2T.js";
67
67
  import {
68
68
  logger
69
- } from "./chunk-FIE2FRIW.js";
69
+ } from "./chunk-5SURQQLD.js";
70
70
  import {
71
71
  getShipyardHome,
72
72
  resolveNodeExecPath,
73
73
  validateEnv
74
- } from "./chunk-FKOUB6H6.js";
74
+ } from "./chunk-HM3SAIPU.js";
75
75
  import {
76
76
  external_exports
77
77
  } from "./chunk-XVW6VCKW.js";
@@ -8895,4 +8895,4 @@ export {
8895
8895
  refreshInstalledAgents,
8896
8896
  refreshCodexAuthSlice
8897
8897
  };
8898
- //# sourceMappingURL=chunk-XPOXRIHH.js.map
8898
+ //# sourceMappingURL=chunk-FTQ7J3XF.js.map
@@ -154,6 +154,18 @@ var EnvSchema = external_exports.object({
154
154
  * heartbeat doesn't trip the wedge detector.
155
155
  */
156
156
  SHIPYARD_HEARTBEAT_INTERVAL_MS: external_exports.coerce.number().int().positive().default(2e3),
157
+ /**
158
+ * Manual-repro hook for wedge supervision: N ms after boot, spin the JS loop
159
+ * forever. Inert unless `{dataDir}/debug-wedge.armed` also exists; the file
160
+ * is consumed on fire so the respawned daemon boots normally.
161
+ */
162
+ SHIPYARD_DEBUG_WEDGE_AFTER_MS: external_exports.coerce.number().int().nonnegative().optional(),
163
+ /**
164
+ * Always-on V8 sampling heap profiler that dumps a `.heapprofile` to
165
+ * `{dataDir}/diagnostics` at 60/75/90% of the heap limit
166
+ * (heap-pressure-profiler.ts). Default ON; set 0 to disable.
167
+ */
168
+ SHIPYARD_HEAP_PROFILER: external_exports.enum(["1", "true", "0", "false", ""]).default("").transform((v) => v !== "0" && v !== "false"),
157
169
  /**
158
170
  * When set to `'electron-safe-storage'`, the vault-key-manager wraps the
159
171
  * master key via Electron's safeStorage API (macOS Keychain on macOS,
@@ -233,7 +245,22 @@ var EnvSchema = external_exports.object({
233
245
  * Electron path also honors a `daemon.maxHeapGb` config.json setting below
234
246
  * this env var in precedence — see daemon-heap-limit-config.ts.
235
247
  */
236
- SHIPYARD_DAEMON_MAX_OLD_SPACE_MB: external_exports.coerce.number().int().positive().optional()
248
+ SHIPYARD_DAEMON_MAX_OLD_SPACE_MB: external_exports.coerce.number().int().positive().optional(),
249
+ /**
250
+ * Auto-continue tasks whose turn was interrupted by an unintended daemon
251
+ * kill (SIGKILL/crash/wedge-kill) rather than leaving them stuck at
252
+ * `input_required` forever. Default OFF — the auto-continue policy is not
253
+ * yet decided; while off, the boot phase still computes and logs what
254
+ * WOULD have resumed (`interrupted_resume_disabled`) so the decision can
255
+ * be made from real data. See `services/bootstrap/interrupted-turn-resume.ts`.
256
+ */
257
+ /**
258
+ * Why this daemon process was started, set by Electron main per spawn
259
+ * (daemon-host.ts). Auto-resume of interrupted turns only acts after a
260
+ * crash/wedge respawn — see interrupted-turn-resume.ts. Unset under the CLI.
261
+ */
262
+ SHIPYARD_DAEMON_START_REASON: external_exports.enum(["launch", "respawn_after_crash", "respawn_after_wedge", "respawn_after_clean", "probe"]).optional(),
263
+ SHIPYARD_AUTO_RESUME_INTERRUPTED: external_exports.enum(["1", "true", "0", "false", ""]).default("").transform((v) => v === "1" || v === "true")
237
264
  });
238
265
  function validateEnv() {
239
266
  return EnvSchema.parse(process.env);
@@ -261,4 +288,4 @@ export {
261
288
  validateEnv,
262
289
  getStallProfilerConfig
263
290
  };
264
- //# sourceMappingURL=chunk-FKOUB6H6.js.map
291
+ //# sourceMappingURL=chunk-HM3SAIPU.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shared/env.ts"],"sourcesContent":["import { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { z } from 'zod';\n\n/**\n * Enable fine-grained tool streaming so MCP tool inputs stream token-by-token\n * via input_json_delta events instead of being buffered as complete JSON.\n * Set early so the subprocess inherits it.\n */\nprocess.env.CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING = '1';\n\n/**\n * Enable the Task system (TaskCreate/TaskGet/TaskList/TaskUpdate) which provides\n * structured task management with dependency tracking (blocks/blockedBy).\n * Replaces TodoWrite — when enabled, CC only has TaskCreate (not TodoWrite).\n */\nprocess.env.CLAUDE_CODE_ENABLE_TASKS = '1';\n\n/**\n * Agent SDK 0.3.233 dropped the Task/Todo tools from the DEFAULT tool surface on\n * Opus 4.8, Sonnet 5, Fable 5, Mythos 5 \"and newer\" — which now includes Fable 5.1.\n * `CLAUDE_CODE_ENABLE_TASKS` alone is no longer sufficient: the 0.3.259 gate is\n * `enableTasks() && (modelNotGated || CLAUDE_CODE_ENABLE_TODO_TOOLS)`, and Shipyard\n * passes no `allowedTools`, so without this the tools silently vanish on exactly our\n * frontier models and `packages/loro-schema/src/todo-helpers.ts` extracts nothing.\n * Failure mode is silent — no type error, no test failure, just an empty todo list.\n */\nprocess.env.CLAUDE_CODE_ENABLE_TODO_TOOLS = '1';\n\n/**\n * Bootstrap exception: reads `process.env` directly because it feeds the\n * `SHIPYARD_DATA_DIR` schema transform (via `shipyardDirName`). Routing it\n * through `validateEnv()` would recurse (validateEnv → parse → transform →\n * shipyardDirName → isDevMode → validateEnv).\n */\nexport function isDevMode(): boolean {\n return process.env.SHIPYARD_DEV === '1' || process.env.SHIPYARD_DEV === 'true';\n}\n\n/**\n * When enabled, the agent runs with only Shipyard builtins (system prompt,\n * comment + visualize MCP servers) and no user/plugin MCP servers.\n * Useful for testing the harness in isolation without external interference.\n *\n * Set `SHIPYARD_VANILLA_AGENT=1` to activate.\n */\nexport function isVanillaAgentMode(): boolean {\n return validateEnv().SHIPYARD_VANILLA_AGENT;\n}\n\n/**\n * Reuse Claude Code's macOS Keychain item (\"Claude Code-credentials\") as a\n * source for MCP connector OAuth clients/tokens.\n *\n * Default OFF. The daemon is a different binary than Claude Code, so reading\n * that Keychain item triggers a macOS password prompt in a GUI session (or a\n * silent denial when headless) — unacceptable in the connector status path,\n * which runs on every capability refresh. Shipyard's own token store is the\n * source of truth, mirroring how local MCPs work (no prompt). Opt back into\n * the legacy import behavior with `SHIPYARD_MCP_REUSE_CC_KEYCHAIN=1`.\n */\nexport function isClaudeCodeKeychainReadEnabled(): boolean {\n return validateEnv().SHIPYARD_MCP_REUSE_CC_KEYCHAIN;\n}\n\n/**\n * Reuse Codex's macOS Keychain item (\"Codex MCP Credentials\") as a source for\n * per-MCP-connector OAuth clients/tokens (Codex DCRs its own atomic\n * client_id+token pairs, useful for borrowing on connectors Claude Code hasn't\n * registered with).\n *\n * Default OFF for the same reason as {@link isClaudeCodeKeychainReadEnabled}:\n * the daemon is a different binary than Codex, so reading that Keychain item\n * triggers a macOS password prompt in a GUI session (or a silent denial when\n * headless) — unacceptable in the connector status path. The\n * `~/.codex/.credentials.json` file fallback is read regardless. Opt in with\n * `SHIPYARD_MCP_REUSE_CODEX_KEYCHAIN=1`.\n */\nexport function isCodexKeychainReadEnabled(): boolean {\n return validateEnv().SHIPYARD_MCP_REUSE_CODEX_KEYCHAIN;\n}\n\nfunction shipyardDirName(): string {\n return isDevMode() ? '.shipyard-dev' : '.shipyard';\n}\n\n/**\n * The signaling worker is a RENDEZVOUS point: a browser and this daemon only\n * meet if they hit the SAME worker. This MUST equal the web build's\n * `VITE_SESSION_SERVER_URL` (.github/workflows/ci.yml + publish-npm.yml) — all\n * live clients (web next+stable, daemons all channels) point here. Do not make\n * this per-channel; a staging worker is a CI/E2E fixture only. See AGENTS.md\n * Invariant #22 (the #4186 \"install daemon\" incident).\n */\nconst DEFAULT_PRODUCTION_SIGNALING_URL = 'https://shipyard-session-server.jacob-191.workers.dev';\nconst DEFAULT_PRODUCTION_WEB_URL = 'https://shipyard.computer';\n\n/**\n * Bootstrap exception: reads `process.env` directly (not `validateEnv()`)\n * because it computes the electron-utility startup-breadcrumb path BEFORE\n * `validateEnv()` runs — the breadcrumb must still resolve when validateEnv\n * itself throws (see apps/daemon/src/electron-utility.ts).\n */\nexport function getShipyardHome(): string {\n if (process.env.SHIPYARD_HOME) return process.env.SHIPYARD_HOME;\n return join(homedir(), shipyardDirName());\n}\n\n/**\n * The executable to fork JS subprocesses with (cursor-runner, the TS language\n * server, the cursor-hook shim).\n *\n * `child_process.fork`/`spawn` default to `process.execPath`. Inside an\n * Electron *utility* process (how the packaged daemon runs) that does NOT point\n * at the main app binary — it resolves to a per-platform helper executable\n * (e.g. `…/Frameworks/Shipyard Helper.app/Contents/MacOS/Shipyard Helper`) that\n * may not exist on disk in the shipped bundle. Forking it ENOENTs, which (with\n * the cursor-runner pre-warm running at boot) crash-looped the daemon on\n * 2026-06-01 (Dylan's log).\n *\n * The Electron *main* process has a guaranteed-valid `process.execPath` (the\n * main app binary, which also honors `ELECTRON_RUN_AS_NODE=1`) and forwards it\n * as `SHIPYARD_NODE_EXEC_PATH` (see apps/electron/src/main/daemon-host.ts). The\n * CLI daemon and dev leave it unset and fall back to `process.execPath`, which\n * is already correct there. Declared in `EnvSchema` so a malformed value fails\n * at boot. Re-exported from `spawn-as-node.ts` for call-site ergonomics.\n */\nexport function resolveNodeExecPath(): string {\n return validateEnv().SHIPYARD_NODE_EXEC_PATH || process.execPath;\n}\n\n/**\n * Resolved one-time plan-backfill mode (boot). Unset/default ⇒ `auto`: the\n * daemon rebuilds missing plan CRDTs write-once on boot, gated only by the\n * marker's `completed` flag (a no-op on every later boot). The env var is an\n * OPTIONAL OVERRIDE, not the gate: `dry-run` forces a read-only fleet-telemetry\n * pass that writes nothing; `off` disables the scan entirely (escape hatch);\n * `write` forces a write pass that bypasses the completion gate (manual re-run /\n * testing).\n */\nexport function getPlanBackfillMode(): 'off' | 'auto' | 'dry-run' | 'write' {\n return validateEnv().SHIPYARD_PLAN_BACKFILL_MODE;\n}\n\nexport const EnvSchema = z.object({\n ANTHROPIC_API_KEY: z.string().min(1).optional(),\n SHIPYARD_DEV: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v === '1' || v === 'true'),\n SHIPYARD_DAEMON_CHILD: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v === '1' || v === 'true'),\n SHIPYARD_DATA_DIR: z\n .string()\n .optional()\n .transform((v) => v ?? `~/${shipyardDirName()}/data`),\n LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),\n SHIPYARD_SIGNALING_URL: z.string().url().optional(),\n SHIPYARD_PRODUCTION_SIGNALING_URL: z.string().url().default(DEFAULT_PRODUCTION_SIGNALING_URL),\n SHIPYARD_METRICS_WORKER_URL: z\n .string()\n .url()\n .default('https://shipyard-metrics.jacob-191.workers.dev'),\n SHIPYARD_TELEMETRY: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v !== '0' && v !== 'false'),\n SHIPYARD_USER_TOKEN: z.string().optional(),\n /**\n * Worker URL for the `shipyard roi` report command (distinct from\n * SHIPYARD_METRICS_WORKER_URL, which is the telemetry ingestion endpoint).\n * Falls back to the `--worker-url` CLI flag when unset.\n */\n SHIPYARD_METRICS_URL: z.string().url().optional(),\n SHIPYARD_USER_ID: z.string().optional(),\n SHIPYARD_MACHINE_ID: z.string().optional(),\n SHIPYARD_MACHINE_NAME: z.string().optional(),\n SHIPYARD_USER_DISPLAY_NAME: z.string().optional(),\n SHIPYARD_HOME: z.string().optional(),\n SHIPYARD_WORKTREE_NAME: z.string().optional(),\n /**\n * Electron utility transport mode. Absent for the CLI daemon; set by\n * apps/electron/src/main/daemon-host.ts when the daemon runs as an Electron\n * utility process.\n */\n SHIPYARD_TRANSPORT: z.enum(['electron-port']).optional(),\n /**\n * Build artifact hosting this daemon. Electron disables the daemon's npm\n * self-updater because electron-updater owns app replacement.\n */\n SHIPYARD_ARTIFACT: z.enum(['electron']).optional(),\n SHIPYARD_VANILLA_AGENT: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v === '1' || v === 'true'),\n /**\n * One-time plan-CRDT backfill mode (auto-on-boot). Empty/absent → `auto`:\n * every daemon rebuilds its missing plan CRDTs write-once on boot, gated ONLY\n * by the `~/.shipyard/data/plan-backfill-v1.json` marker's `completed` flag, so\n * it runs once per machine and is a no-op on every subsequent boot — no manual\n * action required. The env var is an OPTIONAL OVERRIDE, not the gate:\n * - `dry-run` → force a READ-ONLY pass that emits `plan_backfill_dryrun` fleet\n * telemetry and writes nothing (testing / observability).\n * - `off` → disable the scan entirely (escape hatch).\n * - `write` → force a write pass that bypasses the completion gate (manual\n * re-run / testing); still per-task idempotent via the marker.\n */\n SHIPYARD_PLAN_BACKFILL_MODE: z\n .enum(['off', 'auto', 'dry-run', 'write', ''])\n .optional()\n .transform((v) => (v === undefined || v === '' ? 'auto' : v)),\n /**\n * Opt in to reusing Claude Code's macOS Keychain credentials for MCP OAuth.\n * Default OFF — see {@link isClaudeCodeKeychainReadEnabled} for why (prompt\n * avoidance). Validated here so a typo fails at boot.\n */\n SHIPYARD_MCP_REUSE_CC_KEYCHAIN: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v === '1' || v === 'true'),\n /**\n * Opt in to reusing Codex's macOS Keychain credentials (\"Codex MCP\n * Credentials\") for MCP OAuth. Default OFF — see\n * {@link isCodexKeychainReadEnabled} for why (prompt avoidance). Validated\n * here so a typo fails at boot.\n */\n SHIPYARD_MCP_REUSE_CODEX_KEYCHAIN: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v === '1' || v === 'true'),\n SHIPYARD_STALL_PROFILER_ENABLED: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v !== '0' && v !== 'false'),\n /**\n * Master kill-switch for native-crash evidence capture: the supervisor exit\n * record, `process.report` fatal-error diagnostic reports, and the supervisor\n * stderr tail. Default ON. Telemetry of the distilled summary is separately\n * gated by `SHIPYARD_TELEMETRY`; this only controls the local on-disk capture.\n */\n SHIPYARD_CRASH_EVIDENCE: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v !== '0' && v !== 'false'),\n /**\n * Event-loop stall threshold (ms). Once `histogram.max` crosses this,\n * the profiler starts a CPU profile. History: raised 250ms → 5000ms in\n * May 2026 because the capture itself amplified the stalls it measured\n * (V8 inspector `post()` consumed ~493ms of an 800ms capture window);\n * lowered 5000ms → 1000ms in Jun 2026 (#4484) because the dominant fleet\n * stall volume is 1–10s jank that 5s never profiled. Amplification is now\n * bounded by the profiler's own guards instead of the threshold: the 5-min\n * SHIPYARD_STALL_PROFILER_MIN_INTERVAL_MS rate limit between captures, a\n * capture-in-progress flag, and the 250ms sample window — worst case 12\n * captures/hour (~3s of profiling per hour).\n * Override via `SHIPYARD_STALL_PROFILER_THRESHOLD_MS`.\n */\n SHIPYARD_STALL_PROFILER_THRESHOLD_MS: z.coerce.number().int().positive().default(1_000),\n /**\n * How long to sample the V8 CPU profile after a stall is detected.\n * Default 250ms — long enough for the post-stall queue drain and the\n * cascading sibling stall (if any) to land in the same profile, but\n * short enough that the capture window does not itself amplify the\n * stall on the same event loop. Lowered from 1000 → 250 in May 2026\n * after profile evidence showed `#capture` consumed ~1s of inclusive\n * time inside a 3.5s stall window — the profiler was contributing\n * to the stalls it was trying to measure once #3204 dropped the\n * threshold from 500ms to 250ms.\n */\n SHIPYARD_STALL_PROFILER_PROFILE_DURATION_MS: z.coerce.number().int().positive().default(250),\n /**\n * Cascading-stall suppression window. After one capture, subsequent\n * stalls within this window log `stall_profile_suppressed` instead of\n * starting a new profile. Raised from 30s to 300s (5min) in May 2026\n * to prevent capture storms — at 30s a recurring stall every 60s would\n * trigger 2 captures/min, each adding hundreds of ms of inspector overhead.\n */\n SHIPYARD_STALL_PROFILER_MIN_INTERVAL_MS: z.coerce.number().int().nonnegative().default(300_000),\n /**\n * Supervisor wedge detection: if the daemon child sends no IPC heartbeats\n * for this many ms, the supervisor declares the event loop wedged, sends\n * SIGUSR2 to capture a CPU profile (the inspector runs off the JS loop),\n * waits 2s, then SIGKILLs and respawns via the normal abnormal-exit flow.\n * Generous default — 30s tolerates GC pauses and other legitimate sync\n * blocks well outside human-noticeable territory.\n */\n SHIPYARD_WEDGE_TIMEOUT_MS: z.coerce.number().int().positive().default(30_000),\n /**\n * Daemon child IPC heartbeat interval. Must be smaller than\n * SHIPYARD_WEDGE_TIMEOUT_MS by a comfortable margin so a single missed\n * heartbeat doesn't trip the wedge detector.\n */\n SHIPYARD_HEARTBEAT_INTERVAL_MS: z.coerce.number().int().positive().default(2_000),\n /**\n * When set to `'electron-safe-storage'`, the vault-key-manager wraps the\n * master key via Electron's safeStorage API (macOS Keychain on macOS,\n * Secret Service on Linux). Set by daemon-host.ts in the Electron main\n * process. When absent, the daemon falls back to the existing AES-256-GCM\n * file-based path (CLI daemon path — unchanged).\n */\n SHIPYARD_VAULT_BACKEND: z.enum(['electron-safe-storage']).optional(),\n /**\n * Absolute path to a Node-capable executable for forking JS subprocesses\n * (cursor-runner, the TS language server, the cursor-hook shim). Set by\n * apps/electron/src/main/daemon-host.ts to the Electron MAIN process's\n * `process.execPath` (the main app binary), because the daemon utility\n * process's own `process.execPath` resolves to a helper executable that may\n * not exist in the packaged bundle. Absent for the CLI daemon, which falls\n * back to its own `process.execPath`. See `resolveNodeExecPath()`.\n */\n SHIPYARD_NODE_EXEC_PATH: z.string().optional(),\n /**\n * TTL (ms) for the per-repo worktree list cache. Browser polls at 4-7/sec;\n * this collapses redundant git subprocess invocations to 1 per TTL window.\n * Set to 0 to disable caching (useful for tests that need fresh results).\n */\n SHIPYARD_WORKTREE_LIST_TTL_MS: z.coerce.number().int().min(0).default(30_000),\n /**\n * Override for the web app URL the daemon advertises. Absent → derived from\n * the signaling URL (see `getWebAppUrl`). A malformed value fails at boot\n * rather than propagating into URL concatenation.\n */\n SHIPYARD_WEB_URL: z.string().url().optional(),\n SHIPYARD_PRODUCTION_WEB_URL: z.string().url().default(DEFAULT_PRODUCTION_WEB_URL),\n /**\n * Absolute path override for the Claude Code binary. When set and the file\n * exists, the daemon spawns it instead of the SDK-bundled native binary.\n * See `resolveClaudeCodePath` / `resolveClaudeBinaryPath`.\n */\n CLAUDE_CODE_PATH: z.string().optional(),\n /**\n * Suppress auto-opening the verification URL in the browser during the\n * CLI device-login flow. Default OFF (the browser opens).\n */\n SHIPYARD_NO_OPEN: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v === '1' || v === 'true'),\n /**\n * Kill-switch for Loro CRDT recovery on startup. Default OFF (recovery runs).\n */\n SHIPYARD_DISABLE_LORO_RECOVERY: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v === '1' || v === 'true'),\n /**\n * Harness HTTP MCP server (Codex's endpoint). Default ON — Codex ships with\n * every daemon and needs it. `SHIPYARD_HARNESS_HTTP=0` is the kill-switch for\n * Codex-disabled deployments.\n */\n SHIPYARD_HARNESS_HTTP: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v !== '0' && v !== 'false'),\n /**\n * Use the shared `codex app-server` engine (single token owner — fixes the\n * 401-storm). Default ON. Set to `0`/`false` for the legacy per-process path.\n */\n SHIPYARD_CODEX_SHARED_ENGINE: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v !== '0' && v !== 'false'),\n /**\n * Browser-metrics sampling cadence. Kept as a raw string here — clamp /\n * disable (`0`) / invalid-fallback semantics + logging live in\n * `parseBrowserMetricsInterval` (services/metrics/browser-metrics-config.ts),\n * which consumes this validated value.\n */\n SHIPYARD_BROWSER_METRICS_INTERVAL_MS: z.string().optional(),\n /**\n * Max concurrent file watchers before the guard sheds new subscriptions.\n * Absent → default (450). An invalid value fails at boot.\n */\n SHIPYARD_FILE_WATCHER_MAX: z.coerce.number().int().positive().optional(),\n /**\n * Override the daemon's own --max-old-space-size (MB). When absent, the\n * value is auto-derived from os.totalmem() × 25 %, clamped to [2048, 8192].\n * An explicit value is honored as-is (clamped to 65536 to catch typos) and\n * passed to --max-old-space-size at BOTH spawn sites: the outer CLI\n * supervisor (start-supervisor.ts) and the Electron utility-process fork\n * (daemon-host.ts). See apps/daemon/src/shared/daemon-heap-limit.ts. The\n * Electron path also honors a `daemon.maxHeapGb` config.json setting below\n * this env var in precedence — see daemon-heap-limit-config.ts.\n */\n SHIPYARD_DAEMON_MAX_OLD_SPACE_MB: z.coerce.number().int().positive().optional(),\n});\n\nexport type Env = z.infer<typeof EnvSchema>;\n\nexport function validateEnv(): Env {\n return EnvSchema.parse(process.env);\n}\n\n/**\n * Resolved profiler tuning derived from the validated env. Re-parses the\n * schema so a typo in one of the *_MS vars (e.g. `THRESHOLD_MS=abc`) fails\n * here too — boot already failed in `validateEnv()` (start.ts / serve.ts\n * call it), this second parse is cheap and keeps the wiring side free of\n * `process.env.X` reads at the call site.\n */\nexport interface StallProfilerConfig {\n enabled: boolean;\n thresholdMs: number;\n captureMs: number;\n rateLimitMs: number;\n}\n\nexport function getStallProfilerConfig(): StallProfilerConfig {\n const env = validateEnv();\n\n /**\n * Default OFF in packaged Electron when `SHIPYARD_STALL_PROFILER_ENABLED`\n * is unset. Rationale: the V8 inspector `post()` blocks the event loop\n * during capture — in a 2,959ms stall, `node:inspector:117 post` consumed\n * 493.5ms of 800ms captured, i.e. the profiler was profiling itself.\n * Trade: lose production stall visibility in packaged builds in exchange\n * for not amplifying stalls for users. Dev sessions and CLI daemon keep\n * profiling enabled by default. Override with `SHIPYARD_STALL_PROFILER_ENABLED=1`.\n *\n * `env.SHIPYARD_STALL_PROFILER_ENABLED` is `true` when the env var is\n * absent (the Zod transform treats missing/empty as truthy). We detect\n * \"explicitly set\" vs \"defaulted\" by reading `process.env` directly here\n * — the schema transform already validated it, so this read is safe.\n */\n const explicitlySet =\n process.env.SHIPYARD_STALL_PROFILER_ENABLED !== undefined &&\n process.env.SHIPYARD_STALL_PROFILER_ENABLED !== '';\n\n const enabled = explicitlySet\n ? env.SHIPYARD_STALL_PROFILER_ENABLED\n : env.SHIPYARD_ARTIFACT !== 'electron';\n\n return {\n enabled,\n thresholdMs: env.SHIPYARD_STALL_PROFILER_THRESHOLD_MS,\n captureMs: env.SHIPYARD_STALL_PROFILER_PROFILE_DURATION_MS,\n rateLimitMs: env.SHIPYARD_STALL_PROFILER_MIN_INTERVAL_MS,\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/shared/env.ts"],"sourcesContent":["import { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { z } from 'zod';\n\n/**\n * Enable fine-grained tool streaming so MCP tool inputs stream token-by-token\n * via input_json_delta events instead of being buffered as complete JSON.\n * Set early so the subprocess inherits it.\n */\nprocess.env.CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING = '1';\n\n/**\n * Enable the Task system (TaskCreate/TaskGet/TaskList/TaskUpdate) which provides\n * structured task management with dependency tracking (blocks/blockedBy).\n * Replaces TodoWrite — when enabled, CC only has TaskCreate (not TodoWrite).\n */\nprocess.env.CLAUDE_CODE_ENABLE_TASKS = '1';\n\n/**\n * Agent SDK 0.3.233 dropped the Task/Todo tools from the DEFAULT tool surface on\n * Opus 4.8, Sonnet 5, Fable 5, Mythos 5 \"and newer\" — which now includes Fable 5.1.\n * `CLAUDE_CODE_ENABLE_TASKS` alone is no longer sufficient: the 0.3.259 gate is\n * `enableTasks() && (modelNotGated || CLAUDE_CODE_ENABLE_TODO_TOOLS)`, and Shipyard\n * passes no `allowedTools`, so without this the tools silently vanish on exactly our\n * frontier models and `packages/loro-schema/src/todo-helpers.ts` extracts nothing.\n * Failure mode is silent — no type error, no test failure, just an empty todo list.\n */\nprocess.env.CLAUDE_CODE_ENABLE_TODO_TOOLS = '1';\n\n/**\n * Bootstrap exception: reads `process.env` directly because it feeds the\n * `SHIPYARD_DATA_DIR` schema transform (via `shipyardDirName`). Routing it\n * through `validateEnv()` would recurse (validateEnv → parse → transform →\n * shipyardDirName → isDevMode → validateEnv).\n */\nexport function isDevMode(): boolean {\n return process.env.SHIPYARD_DEV === '1' || process.env.SHIPYARD_DEV === 'true';\n}\n\n/**\n * When enabled, the agent runs with only Shipyard builtins (system prompt,\n * comment + visualize MCP servers) and no user/plugin MCP servers.\n * Useful for testing the harness in isolation without external interference.\n *\n * Set `SHIPYARD_VANILLA_AGENT=1` to activate.\n */\nexport function isVanillaAgentMode(): boolean {\n return validateEnv().SHIPYARD_VANILLA_AGENT;\n}\n\n/**\n * Reuse Claude Code's macOS Keychain item (\"Claude Code-credentials\") as a\n * source for MCP connector OAuth clients/tokens.\n *\n * Default OFF. The daemon is a different binary than Claude Code, so reading\n * that Keychain item triggers a macOS password prompt in a GUI session (or a\n * silent denial when headless) — unacceptable in the connector status path,\n * which runs on every capability refresh. Shipyard's own token store is the\n * source of truth, mirroring how local MCPs work (no prompt). Opt back into\n * the legacy import behavior with `SHIPYARD_MCP_REUSE_CC_KEYCHAIN=1`.\n */\nexport function isClaudeCodeKeychainReadEnabled(): boolean {\n return validateEnv().SHIPYARD_MCP_REUSE_CC_KEYCHAIN;\n}\n\n/**\n * Reuse Codex's macOS Keychain item (\"Codex MCP Credentials\") as a source for\n * per-MCP-connector OAuth clients/tokens (Codex DCRs its own atomic\n * client_id+token pairs, useful for borrowing on connectors Claude Code hasn't\n * registered with).\n *\n * Default OFF for the same reason as {@link isClaudeCodeKeychainReadEnabled}:\n * the daemon is a different binary than Codex, so reading that Keychain item\n * triggers a macOS password prompt in a GUI session (or a silent denial when\n * headless) — unacceptable in the connector status path. The\n * `~/.codex/.credentials.json` file fallback is read regardless. Opt in with\n * `SHIPYARD_MCP_REUSE_CODEX_KEYCHAIN=1`.\n */\nexport function isCodexKeychainReadEnabled(): boolean {\n return validateEnv().SHIPYARD_MCP_REUSE_CODEX_KEYCHAIN;\n}\n\nfunction shipyardDirName(): string {\n return isDevMode() ? '.shipyard-dev' : '.shipyard';\n}\n\n/**\n * The signaling worker is a RENDEZVOUS point: a browser and this daemon only\n * meet if they hit the SAME worker. This MUST equal the web build's\n * `VITE_SESSION_SERVER_URL` (.github/workflows/ci.yml + publish-npm.yml) — all\n * live clients (web next+stable, daemons all channels) point here. Do not make\n * this per-channel; a staging worker is a CI/E2E fixture only. See AGENTS.md\n * Invariant #22 (the #4186 \"install daemon\" incident).\n */\nconst DEFAULT_PRODUCTION_SIGNALING_URL = 'https://shipyard-session-server.jacob-191.workers.dev';\nconst DEFAULT_PRODUCTION_WEB_URL = 'https://shipyard.computer';\n\n/**\n * Bootstrap exception: reads `process.env` directly (not `validateEnv()`)\n * because it computes the electron-utility startup-breadcrumb path BEFORE\n * `validateEnv()` runs — the breadcrumb must still resolve when validateEnv\n * itself throws (see apps/daemon/src/electron-utility.ts).\n */\nexport function getShipyardHome(): string {\n if (process.env.SHIPYARD_HOME) return process.env.SHIPYARD_HOME;\n return join(homedir(), shipyardDirName());\n}\n\n/**\n * The executable to fork JS subprocesses with (cursor-runner, the TS language\n * server, the cursor-hook shim).\n *\n * `child_process.fork`/`spawn` default to `process.execPath`. Inside an\n * Electron *utility* process (how the packaged daemon runs) that does NOT point\n * at the main app binary — it resolves to a per-platform helper executable\n * (e.g. `…/Frameworks/Shipyard Helper.app/Contents/MacOS/Shipyard Helper`) that\n * may not exist on disk in the shipped bundle. Forking it ENOENTs, which (with\n * the cursor-runner pre-warm running at boot) crash-looped the daemon on\n * 2026-06-01 (Dylan's log).\n *\n * The Electron *main* process has a guaranteed-valid `process.execPath` (the\n * main app binary, which also honors `ELECTRON_RUN_AS_NODE=1`) and forwards it\n * as `SHIPYARD_NODE_EXEC_PATH` (see apps/electron/src/main/daemon-host.ts). The\n * CLI daemon and dev leave it unset and fall back to `process.execPath`, which\n * is already correct there. Declared in `EnvSchema` so a malformed value fails\n * at boot. Re-exported from `spawn-as-node.ts` for call-site ergonomics.\n */\nexport function resolveNodeExecPath(): string {\n return validateEnv().SHIPYARD_NODE_EXEC_PATH || process.execPath;\n}\n\n/**\n * Resolved one-time plan-backfill mode (boot). Unset/default ⇒ `auto`: the\n * daemon rebuilds missing plan CRDTs write-once on boot, gated only by the\n * marker's `completed` flag (a no-op on every later boot). The env var is an\n * OPTIONAL OVERRIDE, not the gate: `dry-run` forces a read-only fleet-telemetry\n * pass that writes nothing; `off` disables the scan entirely (escape hatch);\n * `write` forces a write pass that bypasses the completion gate (manual re-run /\n * testing).\n */\nexport function getPlanBackfillMode(): 'off' | 'auto' | 'dry-run' | 'write' {\n return validateEnv().SHIPYARD_PLAN_BACKFILL_MODE;\n}\n\nexport const EnvSchema = z.object({\n ANTHROPIC_API_KEY: z.string().min(1).optional(),\n SHIPYARD_DEV: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v === '1' || v === 'true'),\n SHIPYARD_DAEMON_CHILD: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v === '1' || v === 'true'),\n SHIPYARD_DATA_DIR: z\n .string()\n .optional()\n .transform((v) => v ?? `~/${shipyardDirName()}/data`),\n LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),\n SHIPYARD_SIGNALING_URL: z.string().url().optional(),\n SHIPYARD_PRODUCTION_SIGNALING_URL: z.string().url().default(DEFAULT_PRODUCTION_SIGNALING_URL),\n SHIPYARD_METRICS_WORKER_URL: z\n .string()\n .url()\n .default('https://shipyard-metrics.jacob-191.workers.dev'),\n SHIPYARD_TELEMETRY: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v !== '0' && v !== 'false'),\n SHIPYARD_USER_TOKEN: z.string().optional(),\n /**\n * Worker URL for the `shipyard roi` report command (distinct from\n * SHIPYARD_METRICS_WORKER_URL, which is the telemetry ingestion endpoint).\n * Falls back to the `--worker-url` CLI flag when unset.\n */\n SHIPYARD_METRICS_URL: z.string().url().optional(),\n SHIPYARD_USER_ID: z.string().optional(),\n SHIPYARD_MACHINE_ID: z.string().optional(),\n SHIPYARD_MACHINE_NAME: z.string().optional(),\n SHIPYARD_USER_DISPLAY_NAME: z.string().optional(),\n SHIPYARD_HOME: z.string().optional(),\n SHIPYARD_WORKTREE_NAME: z.string().optional(),\n /**\n * Electron utility transport mode. Absent for the CLI daemon; set by\n * apps/electron/src/main/daemon-host.ts when the daemon runs as an Electron\n * utility process.\n */\n SHIPYARD_TRANSPORT: z.enum(['electron-port']).optional(),\n /**\n * Build artifact hosting this daemon. Electron disables the daemon's npm\n * self-updater because electron-updater owns app replacement.\n */\n SHIPYARD_ARTIFACT: z.enum(['electron']).optional(),\n SHIPYARD_VANILLA_AGENT: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v === '1' || v === 'true'),\n /**\n * One-time plan-CRDT backfill mode (auto-on-boot). Empty/absent → `auto`:\n * every daemon rebuilds its missing plan CRDTs write-once on boot, gated ONLY\n * by the `~/.shipyard/data/plan-backfill-v1.json` marker's `completed` flag, so\n * it runs once per machine and is a no-op on every subsequent boot — no manual\n * action required. The env var is an OPTIONAL OVERRIDE, not the gate:\n * - `dry-run` → force a READ-ONLY pass that emits `plan_backfill_dryrun` fleet\n * telemetry and writes nothing (testing / observability).\n * - `off` → disable the scan entirely (escape hatch).\n * - `write` → force a write pass that bypasses the completion gate (manual\n * re-run / testing); still per-task idempotent via the marker.\n */\n SHIPYARD_PLAN_BACKFILL_MODE: z\n .enum(['off', 'auto', 'dry-run', 'write', ''])\n .optional()\n .transform((v) => (v === undefined || v === '' ? 'auto' : v)),\n /**\n * Opt in to reusing Claude Code's macOS Keychain credentials for MCP OAuth.\n * Default OFF — see {@link isClaudeCodeKeychainReadEnabled} for why (prompt\n * avoidance). Validated here so a typo fails at boot.\n */\n SHIPYARD_MCP_REUSE_CC_KEYCHAIN: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v === '1' || v === 'true'),\n /**\n * Opt in to reusing Codex's macOS Keychain credentials (\"Codex MCP\n * Credentials\") for MCP OAuth. Default OFF — see\n * {@link isCodexKeychainReadEnabled} for why (prompt avoidance). Validated\n * here so a typo fails at boot.\n */\n SHIPYARD_MCP_REUSE_CODEX_KEYCHAIN: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v === '1' || v === 'true'),\n SHIPYARD_STALL_PROFILER_ENABLED: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v !== '0' && v !== 'false'),\n /**\n * Master kill-switch for native-crash evidence capture: the supervisor exit\n * record, `process.report` fatal-error diagnostic reports, and the supervisor\n * stderr tail. Default ON. Telemetry of the distilled summary is separately\n * gated by `SHIPYARD_TELEMETRY`; this only controls the local on-disk capture.\n */\n SHIPYARD_CRASH_EVIDENCE: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v !== '0' && v !== 'false'),\n /**\n * Event-loop stall threshold (ms). Once `histogram.max` crosses this,\n * the profiler starts a CPU profile. History: raised 250ms → 5000ms in\n * May 2026 because the capture itself amplified the stalls it measured\n * (V8 inspector `post()` consumed ~493ms of an 800ms capture window);\n * lowered 5000ms → 1000ms in Jun 2026 (#4484) because the dominant fleet\n * stall volume is 1–10s jank that 5s never profiled. Amplification is now\n * bounded by the profiler's own guards instead of the threshold: the 5-min\n * SHIPYARD_STALL_PROFILER_MIN_INTERVAL_MS rate limit between captures, a\n * capture-in-progress flag, and the 250ms sample window — worst case 12\n * captures/hour (~3s of profiling per hour).\n * Override via `SHIPYARD_STALL_PROFILER_THRESHOLD_MS`.\n */\n SHIPYARD_STALL_PROFILER_THRESHOLD_MS: z.coerce.number().int().positive().default(1_000),\n /**\n * How long to sample the V8 CPU profile after a stall is detected.\n * Default 250ms — long enough for the post-stall queue drain and the\n * cascading sibling stall (if any) to land in the same profile, but\n * short enough that the capture window does not itself amplify the\n * stall on the same event loop. Lowered from 1000 → 250 in May 2026\n * after profile evidence showed `#capture` consumed ~1s of inclusive\n * time inside a 3.5s stall window — the profiler was contributing\n * to the stalls it was trying to measure once #3204 dropped the\n * threshold from 500ms to 250ms.\n */\n SHIPYARD_STALL_PROFILER_PROFILE_DURATION_MS: z.coerce.number().int().positive().default(250),\n /**\n * Cascading-stall suppression window. After one capture, subsequent\n * stalls within this window log `stall_profile_suppressed` instead of\n * starting a new profile. Raised from 30s to 300s (5min) in May 2026\n * to prevent capture storms — at 30s a recurring stall every 60s would\n * trigger 2 captures/min, each adding hundreds of ms of inspector overhead.\n */\n SHIPYARD_STALL_PROFILER_MIN_INTERVAL_MS: z.coerce.number().int().nonnegative().default(300_000),\n /**\n * Supervisor wedge detection: if the daemon child sends no IPC heartbeats\n * for this many ms, the supervisor declares the event loop wedged, sends\n * SIGUSR2 to capture a CPU profile (the inspector runs off the JS loop),\n * waits 2s, then SIGKILLs and respawns via the normal abnormal-exit flow.\n * Generous default — 30s tolerates GC pauses and other legitimate sync\n * blocks well outside human-noticeable territory.\n */\n SHIPYARD_WEDGE_TIMEOUT_MS: z.coerce.number().int().positive().default(30_000),\n /**\n * Daemon child IPC heartbeat interval. Must be smaller than\n * SHIPYARD_WEDGE_TIMEOUT_MS by a comfortable margin so a single missed\n * heartbeat doesn't trip the wedge detector.\n */\n SHIPYARD_HEARTBEAT_INTERVAL_MS: z.coerce.number().int().positive().default(2_000),\n /**\n * Manual-repro hook for wedge supervision: N ms after boot, spin the JS loop\n * forever. Inert unless `{dataDir}/debug-wedge.armed` also exists; the file\n * is consumed on fire so the respawned daemon boots normally.\n */\n SHIPYARD_DEBUG_WEDGE_AFTER_MS: z.coerce.number().int().nonnegative().optional(),\n /**\n * Always-on V8 sampling heap profiler that dumps a `.heapprofile` to\n * `{dataDir}/diagnostics` at 60/75/90% of the heap limit\n * (heap-pressure-profiler.ts). Default ON; set 0 to disable.\n */\n SHIPYARD_HEAP_PROFILER: z\n .enum(['1', 'true', '0', 'false', ''])\n .default('')\n .transform((v) => v !== '0' && v !== 'false'),\n /**\n * When set to `'electron-safe-storage'`, the vault-key-manager wraps the\n * master key via Electron's safeStorage API (macOS Keychain on macOS,\n * Secret Service on Linux). Set by daemon-host.ts in the Electron main\n * process. When absent, the daemon falls back to the existing AES-256-GCM\n * file-based path (CLI daemon path — unchanged).\n */\n SHIPYARD_VAULT_BACKEND: z.enum(['electron-safe-storage']).optional(),\n /**\n * Absolute path to a Node-capable executable for forking JS subprocesses\n * (cursor-runner, the TS language server, the cursor-hook shim). Set by\n * apps/electron/src/main/daemon-host.ts to the Electron MAIN process's\n * `process.execPath` (the main app binary), because the daemon utility\n * process's own `process.execPath` resolves to a helper executable that may\n * not exist in the packaged bundle. Absent for the CLI daemon, which falls\n * back to its own `process.execPath`. See `resolveNodeExecPath()`.\n */\n SHIPYARD_NODE_EXEC_PATH: z.string().optional(),\n /**\n * TTL (ms) for the per-repo worktree list cache. Browser polls at 4-7/sec;\n * this collapses redundant git subprocess invocations to 1 per TTL window.\n * Set to 0 to disable caching (useful for tests that need fresh results).\n */\n SHIPYARD_WORKTREE_LIST_TTL_MS: z.coerce.number().int().min(0).default(30_000),\n /**\n * Override for the web app URL the daemon advertises. Absent → derived from\n * the signaling URL (see `getWebAppUrl`). A malformed value fails at boot\n * rather than propagating into URL concatenation.\n */\n SHIPYARD_WEB_URL: z.string().url().optional(),\n SHIPYARD_PRODUCTION_WEB_URL: z.string().url().default(DEFAULT_PRODUCTION_WEB_URL),\n /**\n * Absolute path override for the Claude Code binary. When set and the file\n * exists, the daemon spawns it instead of the SDK-bundled native binary.\n * See `resolveClaudeCodePath` / `resolveClaudeBinaryPath`.\n */\n CLAUDE_CODE_PATH: z.string().optional(),\n /**\n * Suppress auto-opening the verification URL in the browser during the\n * CLI device-login flow. Default OFF (the browser opens).\n */\n SHIPYARD_NO_OPEN: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v === '1' || v === 'true'),\n /**\n * Kill-switch for Loro CRDT recovery on startup. Default OFF (recovery runs).\n */\n SHIPYARD_DISABLE_LORO_RECOVERY: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v === '1' || v === 'true'),\n /**\n * Harness HTTP MCP server (Codex's endpoint). Default ON — Codex ships with\n * every daemon and needs it. `SHIPYARD_HARNESS_HTTP=0` is the kill-switch for\n * Codex-disabled deployments.\n */\n SHIPYARD_HARNESS_HTTP: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v !== '0' && v !== 'false'),\n /**\n * Use the shared `codex app-server` engine (single token owner — fixes the\n * 401-storm). Default ON. Set to `0`/`false` for the legacy per-process path.\n */\n SHIPYARD_CODEX_SHARED_ENGINE: z\n .enum(['1', 'true', '0', 'false', ''])\n .optional()\n .transform((v) => v !== '0' && v !== 'false'),\n /**\n * Browser-metrics sampling cadence. Kept as a raw string here — clamp /\n * disable (`0`) / invalid-fallback semantics + logging live in\n * `parseBrowserMetricsInterval` (services/metrics/browser-metrics-config.ts),\n * which consumes this validated value.\n */\n SHIPYARD_BROWSER_METRICS_INTERVAL_MS: z.string().optional(),\n /**\n * Max concurrent file watchers before the guard sheds new subscriptions.\n * Absent → default (450). An invalid value fails at boot.\n */\n SHIPYARD_FILE_WATCHER_MAX: z.coerce.number().int().positive().optional(),\n /**\n * Override the daemon's own --max-old-space-size (MB). When absent, the\n * value is auto-derived from os.totalmem() × 25 %, clamped to [2048, 8192].\n * An explicit value is honored as-is (clamped to 65536 to catch typos) and\n * passed to --max-old-space-size at BOTH spawn sites: the outer CLI\n * supervisor (start-supervisor.ts) and the Electron utility-process fork\n * (daemon-host.ts). See apps/daemon/src/shared/daemon-heap-limit.ts. The\n * Electron path also honors a `daemon.maxHeapGb` config.json setting below\n * this env var in precedence — see daemon-heap-limit-config.ts.\n */\n SHIPYARD_DAEMON_MAX_OLD_SPACE_MB: z.coerce.number().int().positive().optional(),\n /**\n * Auto-continue tasks whose turn was interrupted by an unintended daemon\n * kill (SIGKILL/crash/wedge-kill) rather than leaving them stuck at\n * `input_required` forever. Default OFF — the auto-continue policy is not\n * yet decided; while off, the boot phase still computes and logs what\n * WOULD have resumed (`interrupted_resume_disabled`) so the decision can\n * be made from real data. See `services/bootstrap/interrupted-turn-resume.ts`.\n */\n /**\n * Why this daemon process was started, set by Electron main per spawn\n * (daemon-host.ts). Auto-resume of interrupted turns only acts after a\n * crash/wedge respawn — see interrupted-turn-resume.ts. Unset under the CLI.\n */\n SHIPYARD_DAEMON_START_REASON: z\n .enum(['launch', 'respawn_after_crash', 'respawn_after_wedge', 'respawn_after_clean', 'probe'])\n .optional(),\n SHIPYARD_AUTO_RESUME_INTERRUPTED: z\n .enum(['1', 'true', '0', 'false', ''])\n .default('')\n .transform((v) => v === '1' || v === 'true'),\n});\n\nexport type Env = z.infer<typeof EnvSchema>;\n\nexport function validateEnv(): Env {\n return EnvSchema.parse(process.env);\n}\n\n/**\n * Resolved profiler tuning derived from the validated env. Re-parses the\n * schema so a typo in one of the *_MS vars (e.g. `THRESHOLD_MS=abc`) fails\n * here too — boot already failed in `validateEnv()` (start.ts / serve.ts\n * call it), this second parse is cheap and keeps the wiring side free of\n * `process.env.X` reads at the call site.\n */\nexport interface StallProfilerConfig {\n enabled: boolean;\n thresholdMs: number;\n captureMs: number;\n rateLimitMs: number;\n}\n\nexport function getStallProfilerConfig(): StallProfilerConfig {\n const env = validateEnv();\n\n /**\n * Default OFF in packaged Electron when `SHIPYARD_STALL_PROFILER_ENABLED`\n * is unset. Rationale: the V8 inspector `post()` blocks the event loop\n * during capture — in a 2,959ms stall, `node:inspector:117 post` consumed\n * 493.5ms of 800ms captured, i.e. the profiler was profiling itself.\n * Trade: lose production stall visibility in packaged builds in exchange\n * for not amplifying stalls for users. Dev sessions and CLI daemon keep\n * profiling enabled by default. Override with `SHIPYARD_STALL_PROFILER_ENABLED=1`.\n *\n * `env.SHIPYARD_STALL_PROFILER_ENABLED` is `true` when the env var is\n * absent (the Zod transform treats missing/empty as truthy). We detect\n * \"explicitly set\" vs \"defaulted\" by reading `process.env` directly here\n * — the schema transform already validated it, so this read is safe.\n */\n const explicitlySet =\n process.env.SHIPYARD_STALL_PROFILER_ENABLED !== undefined &&\n process.env.SHIPYARD_STALL_PROFILER_ENABLED !== '';\n\n const enabled = explicitlySet\n ? env.SHIPYARD_STALL_PROFILER_ENABLED\n : env.SHIPYARD_ARTIFACT !== 'electron';\n\n return {\n enabled,\n thresholdMs: env.SHIPYARD_STALL_PROFILER_THRESHOLD_MS,\n captureMs: env.SHIPYARD_STALL_PROFILER_PROFILE_DURATION_MS,\n rateLimitMs: env.SHIPYARD_STALL_PROFILER_MIN_INTERVAL_MS,\n };\n}\n"],"mappings":"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","names":[]}
@@ -263,7 +263,7 @@ async function detectSkills(environments, lastKnown, options) {
263
263
  try {
264
264
  return await detectSkillsInner(environments, resolvedMirror, options?.activeRepoRoot);
265
265
  } catch (err) {
266
- const { logger } = await import("./logger-YFXXQZ5J.js");
266
+ const { logger } = await import("./logger-KG26Y4CL.js");
267
267
  if (lastKnown && lastKnown.length > 0) {
268
268
  logger.warn(
269
269
  { err, lastKnownCount: lastKnown.length },
@@ -468,4 +468,4 @@ export {
468
468
  scopeEnvironmentsToActiveRepo,
469
469
  _resolveBucketForTesting
470
470
  };
471
- //# sourceMappingURL=chunk-ELZLWLTO.js.map
471
+ //# sourceMappingURL=chunk-HYK7G5WV.js.map
@@ -5,10 +5,10 @@ import {
5
5
  } from "./chunk-VHPNDDB5.js";
6
6
  import {
7
7
  logger
8
- } from "./chunk-FIE2FRIW.js";
8
+ } from "./chunk-5SURQQLD.js";
9
9
  import {
10
10
  isClaudeCodeKeychainReadEnabled
11
- } from "./chunk-FKOUB6H6.js";
11
+ } from "./chunk-HM3SAIPU.js";
12
12
  import {
13
13
  external_exports
14
14
  } from "./chunk-XVW6VCKW.js";
@@ -1578,7 +1578,7 @@ async function detectMCPServers(environments, tokenStore, log, lastKnown, prefer
1578
1578
  lastKnown
1579
1579
  );
1580
1580
  } catch (err) {
1581
- const { logger: logger2 } = await import("./logger-YFXXQZ5J.js");
1581
+ const { logger: logger2 } = await import("./logger-KG26Y4CL.js");
1582
1582
  if (lastKnown && lastKnown.length > 0) {
1583
1583
  logger2.warn(
1584
1584
  { err, lastKnownCount: lastKnown.length },
@@ -1784,4 +1784,4 @@ export {
1784
1784
  resolveAuthStatuses,
1785
1785
  detectMCPServers
1786
1786
  };
1787
- //# sourceMappingURL=chunk-FYT3ETTP.js.map
1787
+ //# sourceMappingURL=chunk-IX4BZWVO.js.map
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getDaemonVersion
4
- } from "./chunk-ZXYFMJAS.js";
4
+ } from "./chunk-AVOYKLEX.js";
5
5
  import {
6
6
  WorkerCommandCodec,
7
7
  WorkerReplyCodec
8
8
  } from "./chunk-EIWGZUA2.js";
9
9
  import {
10
10
  buildNodeSpawnEnv
11
- } from "./chunk-Y6AAH7LO.js";
11
+ } from "./chunk-EM3SPYXE.js";
12
12
  import {
13
13
  createServiceSupervisor
14
14
  } from "./chunk-ZFKJAYAN.js";
@@ -16,7 +16,7 @@ import {
16
16
  getShipyardHome,
17
17
  resolveNodeExecPath,
18
18
  validateEnv
19
- } from "./chunk-FKOUB6H6.js";
19
+ } from "./chunk-HM3SAIPU.js";
20
20
  import {
21
21
  assertNever
22
22
  } from "./chunk-X3MULCV5.js";
@@ -1116,4 +1116,4 @@ export {
1116
1116
  shutdownFileWatcherGuard,
1117
1117
  guardedSubscribe
1118
1118
  };
1119
- //# sourceMappingURL=chunk-4WJOA7HF.js.map
1119
+ //# sourceMappingURL=chunk-RP7Z3PPQ.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getShipyardHome
4
- } from "./chunk-FKOUB6H6.js";
4
+ } from "./chunk-HM3SAIPU.js";
5
5
  import {
6
6
  external_exports
7
7
  } from "./chunk-XVW6VCKW.js";
@@ -90,4 +90,4 @@ export {
90
90
  deleteConfig,
91
91
  loadAuthToken
92
92
  };
93
- //# sourceMappingURL=chunk-XPYW5WQS.js.map
93
+ //# sourceMappingURL=chunk-T5J6HZOQ.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getLogFilePath
4
- } from "./chunk-FIE2FRIW.js";
4
+ } from "./chunk-5SURQQLD.js";
5
5
 
6
6
  // src/shared/commands/output.ts
7
7
  import { appendFileSync } from "fs";
@@ -40,4 +40,4 @@ export {
40
40
  print,
41
41
  printError
42
42
  };
43
- //# sourceMappingURL=chunk-MM3M2KAC.js.map
43
+ //# sourceMappingURL=chunk-VOS3HC7Y.js.map
@@ -7,15 +7,15 @@ import {
7
7
  } from "./chunk-FWL2ZIEL.js";
8
8
  import {
9
9
  buildCursorUserPrompt
10
- } from "./chunk-3PJULQHI.js";
10
+ } from "./chunk-FHEPAJ33.js";
11
11
  import {
12
12
  ContentBlockSchema,
13
13
  HARNESS_SERVER_NAME
14
14
  } from "./chunk-DQQOVPVK.js";
15
15
  import "./chunk-MV7VSD2T.js";
16
16
  import "./chunk-EHQITHQX.js";
17
- import "./chunk-FIE2FRIW.js";
18
- import "./chunk-FKOUB6H6.js";
17
+ import "./chunk-5SURQQLD.js";
18
+ import "./chunk-HM3SAIPU.js";
19
19
  import "./chunk-X3MULCV5.js";
20
20
  import "./chunk-XVW6VCKW.js";
21
21
  import "./chunk-2H7UOFLK.js";
@@ -1,21 +1,21 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getDaemonVersion
4
- } from "./chunk-ZXYFMJAS.js";
4
+ } from "./chunk-AVOYKLEX.js";
5
5
  import {
6
6
  enableNativeCrashReports
7
- } from "./chunk-RYZH5KM3.js";
7
+ } from "./chunk-CTVKFKRG.js";
8
8
  import {
9
9
  installWasmPanicBuffer
10
10
  } from "./chunk-5OTUGRW3.js";
11
11
  import "./chunk-UNGAIUEX.js";
12
12
  import {
13
13
  logger
14
- } from "./chunk-FIE2FRIW.js";
14
+ } from "./chunk-5SURQQLD.js";
15
15
  import {
16
16
  getShipyardHome,
17
17
  validateEnv
18
- } from "./chunk-FKOUB6H6.js";
18
+ } from "./chunk-HM3SAIPU.js";
19
19
  import "./chunk-XVW6VCKW.js";
20
20
  import "./chunk-2H7UOFLK.js";
21
21
 
@@ -40,7 +40,7 @@ function isVersionQuery(data) {
40
40
  }
41
41
  async function loadAuthFromConfig(env) {
42
42
  if (env.SHIPYARD_USER_TOKEN) return;
43
- const { loadAuthToken } = await import("./auth-VKW72LVH.js");
43
+ const { loadAuthToken } = await import("./auth-JOCEWSRP.js");
44
44
  const auth = await loadAuthToken();
45
45
  if (auth.status === "ok") {
46
46
  env.SHIPYARD_USER_TOKEN = auth.token;
@@ -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-SDRQ7JYB.js");
74
+ const { serve } = await import("./serve-BUT2GA6K.js");
75
75
  crumb("post-serve-import");
76
76
  const portQueue = [];
77
77
  let acceptor = null;