oh-my-opencode 4.19.1 → 4.19.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/README.ja.md +2 -2
  2. package/README.ko.md +2 -2
  3. package/README.md +2 -2
  4. package/README.ru.md +2 -2
  5. package/README.zh-cn.md +2 -2
  6. package/dist/agents/atlas/agent.d.ts +4 -2
  7. package/dist/agents/explore.d.ts +4 -2
  8. package/dist/agents/hephaestus/agent.d.ts +4 -2
  9. package/dist/agents/librarian.d.ts +4 -2
  10. package/dist/agents/metis.d.ts +4 -2
  11. package/dist/agents/momus.d.ts +3 -2
  12. package/dist/agents/multimodal-looker.d.ts +4 -2
  13. package/dist/agents/oracle.d.ts +4 -2
  14. package/dist/agents/sisyphus/claude-opus-5.d.ts +33 -0
  15. package/dist/agents/sisyphus/index.d.ts +2 -0
  16. package/dist/agents/sisyphus-agent-factory.d.ts +5 -2
  17. package/dist/agents/sisyphus-junior/agent.d.ts +4 -1
  18. package/dist/agents/types.d.ts +2 -2
  19. package/dist/cli/index.js +23454 -19200
  20. package/dist/cli-node/index.js +23454 -19200
  21. package/dist/config/schema/agent-names.d.ts +26 -26
  22. package/dist/config/schema/agent-overrides.d.ts +400 -400
  23. package/dist/config/schema/browser-automation.d.ts +2 -2
  24. package/dist/config/schema/categories.d.ts +36 -36
  25. package/dist/config/schema/commands.d.ts +2 -2
  26. package/dist/config/schema/dynamic-context-pruning.d.ts +1 -1
  27. package/dist/config/schema/experimental.d.ts +1 -1
  28. package/dist/config/schema/fallback-models.d.ts +25 -25
  29. package/dist/config/schema/hooks.d.ts +43 -43
  30. package/dist/config/schema/internal/permission.d.ts +9 -9
  31. package/dist/config/schema/keyword-detector.d.ts +6 -6
  32. package/dist/config/schema/oh-my-opencode-config.d.ts +402 -402
  33. package/dist/config/schema/tmux.d.ts +6 -6
  34. package/dist/create-hooks.d.ts +35 -35
  35. package/dist/features/background-agent/spawner/tmux-callback-invoker.d.ts +11 -0
  36. package/dist/features/builtin-commands/templates/start-work.d.ts +1 -1
  37. package/dist/features/claude-tasks/types.d.ts +4 -4
  38. package/dist/features/team-mode/team-runtime/shutdown-helpers.d.ts +1 -1
  39. package/dist/features/team-mode/team-runtime/shutdown-test-fixtures.d.ts +4 -4
  40. package/dist/features/team-mode/tools/lifecycle-test-fixture.d.ts +42 -42
  41. package/dist/features/tmux-subagent/environment-eligibility.d.ts +2 -0
  42. package/dist/features/tmux-subagent/index.d.ts +1 -0
  43. package/dist/features/tmux-subagent/tracked-session-state.d.ts +1 -0
  44. package/dist/features/tui-sidebar/snapshot-schema.d.ts +6 -6
  45. package/dist/help/schema/acp.d.ts +3 -3
  46. package/dist/help/schema/doctor.d.ts +4 -4
  47. package/dist/help/schema/status.d.ts +3 -3
  48. package/dist/hooks/goal/types.d.ts +5 -5
  49. package/dist/hooks/non-interactive-env/constants.d.ts +4 -1
  50. package/dist/hooks/start-work/parse-user-request.d.ts +2 -0
  51. package/dist/hooks/start-work/worktree-block.d.ts +5 -0
  52. package/dist/index.js +25231 -20301
  53. package/dist/mcp/types.d.ts +3 -3
  54. package/dist/oh-my-opencode.schema.json +1 -1
  55. package/dist/plugin/chat-message/loop-commands.d.ts +1 -0
  56. package/dist/plugin/command-execute-before.d.ts +3 -3
  57. package/dist/plugin/hooks/create-core-hooks.d.ts +25 -25
  58. package/dist/shared/tmux/tmux-utils/environment.d.ts +1 -1
  59. package/dist/shared/tmux/tmux-utils.d.ts +1 -1
  60. package/dist/shared/typescript-native-source-parser.d.ts +7 -0
  61. package/dist/skills/coding-agent-sessions/SKILL.md +5 -2
  62. package/dist/skills/coding-agent-sessions/references/all-platforms.md +3 -1
  63. package/dist/skills/coding-agent-sessions/references/senpi.md +15 -5
  64. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +46 -0
  65. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +19 -10
  66. package/dist/skills/debugging/SKILL.md +2 -1
  67. package/dist/skills/debugging/references/methodology/03-flaky-triage.md +47 -0
  68. package/dist/skills/programming/SKILL.md +11 -1
  69. package/dist/skills/programming/references/logging.md +6 -1
  70. package/dist/skills/programming/scripts/typescript/check-no-excuse-rules.ts +51 -17
  71. package/dist/skills/start-work/SKILL.md +12 -2
  72. package/dist/skills/ulw-plan/SKILL.md +1 -1
  73. package/dist/skills/ulw-plan/references/full-workflow.md +12 -1
  74. package/dist/skills/ulw-plan/references/intent-clear.md +1 -1
  75. package/dist/tools/task/types.d.ts +10 -10
  76. package/dist/tui.js +23468 -19218
  77. package/package.json +14 -14
  78. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +2 -2
  79. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  80. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +8 -4
  81. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  82. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  83. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +296 -206
  84. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +126 -86
  85. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  86. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +21 -42
  87. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +3 -4
  88. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +12 -23
  89. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +5 -0
  90. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +33 -5
  91. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +6 -1
  92. package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +6 -0
  93. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +1 -0
  94. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +5 -5
  95. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +1 -0
  96. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +24 -13
  97. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +58 -64
  98. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  99. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  100. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  101. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  102. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  103. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  104. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  105. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  106. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  107. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  108. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  109. package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +1 -1
  110. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  111. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  112. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  113. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  114. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  115. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  116. package/packages/omo-codex/plugin/components/ultrawork/directive.md +12 -7
  117. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  118. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  119. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +12 -7
  120. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +1 -1
  121. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +12 -1
  122. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +1 -1
  123. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +12 -7
  124. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  125. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  126. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +2 -1
  127. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  128. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  129. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  130. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  131. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  132. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  133. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  134. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  135. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  136. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  137. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  138. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  139. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  140. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  141. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  142. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  143. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  144. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  145. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  146. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  147. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  148. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  149. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  150. package/packages/omo-codex/plugin/package-lock.json +13 -13
  151. package/packages/omo-codex/plugin/package.json +1 -1
  152. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +10 -9
  153. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +5 -2
  154. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +3 -1
  155. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +15 -5
  156. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +46 -0
  157. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +19 -10
  158. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +2 -1
  159. package/packages/omo-codex/plugin/skills/debugging/references/methodology/03-flaky-triage.md +47 -0
  160. package/packages/omo-codex/plugin/skills/programming/SKILL.md +11 -1
  161. package/packages/omo-codex/plugin/skills/programming/references/logging.md +6 -1
  162. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-no-excuse-rules.ts +51 -17
  163. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +12 -2
  164. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +12 -7
  165. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +2 -1
  166. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +1 -1
  167. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +12 -1
  168. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +1 -1
  169. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +22 -0
  170. package/packages/omo-codex/scripts/install-dist/install-local.mjs +1 -1
  171. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +5 -2
  172. package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +3 -1
  173. package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +15 -5
  174. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +46 -0
  175. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +19 -10
  176. package/packages/shared-skills/skills/debugging/SKILL.md +2 -1
  177. package/packages/shared-skills/skills/debugging/references/methodology/03-flaky-triage.md +47 -0
  178. package/packages/shared-skills/skills/programming/SKILL.md +11 -1
  179. package/packages/shared-skills/skills/programming/references/logging.md +6 -1
  180. package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.ts +51 -17
  181. package/packages/shared-skills/skills/start-work/SKILL.md +12 -2
  182. package/packages/shared-skills/skills/ulw-plan/SKILL.md +1 -1
  183. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +12 -1
  184. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +1 -1
@@ -2,14 +2,13 @@
2
2
 
3
3
  // components/codegraph/src/cli.ts
4
4
  import { realpathSync as realpathSync7 } from "node:fs";
5
- import { basename as basename5, resolve as resolve8 } from "node:path";
5
+ import { basename as basename5, resolve as resolve9 } from "node:path";
6
6
  import { stderr as processStderr4 } from "node:process";
7
7
  import { fileURLToPath as fileURLToPath4 } from "node:url";
8
8
 
9
9
  // components/codegraph/src/hook.ts
10
- import { execFile as execFile4, spawn } from "node:child_process";
10
+ import { spawn as spawn2 } from "node:child_process";
11
11
  import { homedir as homedir13 } from "node:os";
12
- import { join as join14 } from "node:path";
13
12
  import {
14
13
  cwd as processCwd2,
15
14
  env as processEnv2,
@@ -68,7 +67,7 @@ function buildCodegraphEnv(options = {}) {
68
67
  const homeDir = options.homeDir ?? homedir();
69
68
  return {
70
69
  [CODEGRAPH_INSTALL_DIR_ENV]: join(homeDir, ".omo", "codegraph"),
71
- ...options.daemon === true ? {} : { [CODEGRAPH_NO_DAEMON_ENV]: "1" },
70
+ ...options.daemon === false ? { [CODEGRAPH_NO_DAEMON_ENV]: "1" } : {},
72
71
  [CODEGRAPH_NO_DOWNLOAD_ENV]: "1",
73
72
  [CODEGRAPH_TELEMETRY_ENV]: "0",
74
73
  [DO_NOT_TRACK_ENV]: "1"
@@ -493,16 +492,101 @@ function isRecord(value) {
493
492
  return typeof value === "object" && value !== null && !Array.isArray(value);
494
493
  }
495
494
 
495
+ // ../../utils/src/codegraph/managed-runtime.ts
496
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
497
+ import { join as join6, resolve as resolve4 } from "node:path";
498
+
499
+ // ../../utils/src/record-type-guard.ts
500
+ function isPlainRecord(value) {
501
+ return typeof value === "object" && value !== null && !Array.isArray(value);
502
+ }
503
+
504
+ // ../../utils/src/codegraph/manifest.ts
505
+ var CODEGRAPH_PINNED_VERSION = "1.4.1";
506
+ var CODEGRAPH_PROVISION_MANIFEST = {
507
+ assets: {
508
+ "darwin-arm64": {
509
+ executableName: "codegraph",
510
+ sha256: "4a679ae5a5cb9fff900dd59bb786da6a581b7f68f4cf713bdedd137e347d34dc",
511
+ url: "https://github.com/colbymchenry/codegraph/releases/download/v1.4.1/codegraph-darwin-arm64.tar.gz"
512
+ },
513
+ "darwin-x64": {
514
+ executableName: "codegraph",
515
+ sha256: "436f96943cfd926ea6d0a8454f18833d21254d5fd9b3d224317b1426132def95",
516
+ url: "https://github.com/colbymchenry/codegraph/releases/download/v1.4.1/codegraph-darwin-x64.tar.gz"
517
+ },
518
+ "linux-arm64": {
519
+ executableName: "codegraph",
520
+ sha256: "0d62c5eb2722f8d19d20f7a1bd974445e18d5294cb59be116a0c3d55ce87591f",
521
+ url: "https://github.com/colbymchenry/codegraph/releases/download/v1.4.1/codegraph-linux-arm64.tar.gz"
522
+ },
523
+ "linux-x64": {
524
+ executableName: "codegraph",
525
+ sha256: "fb585ff5018d6faaa46d282b61f4f689bc7967ed8a1b467a5c556dd7ced9b542",
526
+ url: "https://github.com/colbymchenry/codegraph/releases/download/v1.4.1/codegraph-linux-x64.tar.gz"
527
+ },
528
+ "win32-arm64": {
529
+ executableName: "codegraph.cmd",
530
+ sha256: "e2a2a28c802a79804c7df203afa50bd461309c6c180ce3f76079fdc7cddc7697",
531
+ url: "https://registry.npmjs.org/@colbymchenry/codegraph-win32-arm64/-/codegraph-win32-arm64-1.4.1.tgz"
532
+ },
533
+ "win32-x64": {
534
+ executableName: "codegraph.cmd",
535
+ sha256: "4f08700fda5f4a03ad5b2956135c5788d739a351b3433db2b5820e5d5224c30d",
536
+ url: "https://registry.npmjs.org/@colbymchenry/codegraph-win32-x64/-/codegraph-win32-x64-1.4.1.tgz"
537
+ }
538
+ },
539
+ version: CODEGRAPH_PINNED_VERSION
540
+ };
541
+
542
+ // ../../utils/src/codegraph/managed-runtime.ts
543
+ function resolvePinnedCodegraphBin(installDir, options = {}) {
544
+ if (installDir === undefined)
545
+ return null;
546
+ const fileExists = options.fileExists ?? existsSync3;
547
+ const readText = options.readText ?? ((filePath) => readFileSync3(filePath, "utf8"));
548
+ const expectedBin = join6(installDir, "bin", (options.platform ?? process.platform) === "win32" ? "codegraph.cmd" : "codegraph");
549
+ const markerPath = join6(installDir, ".provisioned", `codegraph-${CODEGRAPH_PINNED_VERSION}.json`);
550
+ if (!fileExists(expectedBin) || !fileExists(markerPath))
551
+ return null;
552
+ let markerText;
553
+ try {
554
+ markerText = readText(markerPath);
555
+ } catch {
556
+ return null;
557
+ }
558
+ const marker = parseProvisionMarker(markerText);
559
+ if (marker === null || marker.version !== CODEGRAPH_PINNED_VERSION)
560
+ return null;
561
+ return resolve4(marker.binPath) === resolve4(expectedBin) ? expectedBin : null;
562
+ }
563
+ function parseProvisionMarker(text) {
564
+ try {
565
+ const value = JSON.parse(text);
566
+ if (!isPlainRecord(value))
567
+ return null;
568
+ const binPath = value["binPath"];
569
+ const version = value["version"];
570
+ if (typeof binPath !== "string" || typeof version !== "string")
571
+ return null;
572
+ return { binPath, version };
573
+ } catch (error) {
574
+ if (error instanceof SyntaxError)
575
+ return null;
576
+ throw error;
577
+ }
578
+ }
579
+
496
580
  // ../../utils/src/codegraph/resolve.ts
497
- import { existsSync as existsSync3 } from "node:fs";
581
+ import { existsSync as existsSync4 } from "node:fs";
498
582
  import { homedir as homedir6 } from "node:os";
499
583
  import { spawnSync } from "node:child_process";
500
- import { basename as basename2, dirname as dirname2, join as join7 } from "node:path";
584
+ import { basename as basename2, dirname as dirname2, join as join8 } from "node:path";
501
585
  import { createRequire } from "node:module";
502
586
 
503
587
  // ../../utils/src/runtime/which.ts
504
588
  import { accessSync, constants } from "node:fs";
505
- import { delimiter, join as join6 } from "node:path";
589
+ import { delimiter, join as join7 } from "node:path";
506
590
  var runtime = globalThis;
507
591
  function isUnsafeCommandName(commandName) {
508
592
  if (commandName.includes("/") || commandName.includes("\\"))
@@ -557,7 +641,7 @@ function bunWhich(commandName) {
557
641
  return null;
558
642
  for (const pathEntry of pathEntries) {
559
643
  for (const candidateName of candidateNames) {
560
- const candidatePath = join6(pathEntry, candidateName);
644
+ const candidatePath = join7(pathEntry, candidateName);
561
645
  if (isExecutable(candidatePath))
562
646
  return candidatePath;
563
647
  }
@@ -674,18 +758,13 @@ function defaultNodeRuntime(env, fileExists, which, nodeVersion) {
674
758
  return null;
675
759
  }
676
760
  function defaultProvisionedBin(homeDir, fileExists) {
677
- const binaryName = process.platform === "win32" ? "codegraph.cmd" : "codegraph";
678
- const candidates = [
679
- join7(homeDir, ".omo", "codegraph", "bin", binaryName),
680
- join7(homeDir, ".omo", "codegraph", "node-servers", "node_modules", ".bin", binaryName)
681
- ];
682
- return candidates.find((candidate) => fileExists(candidate)) ?? null;
761
+ return resolvePinnedCodegraphBin(join8(homeDir, ".omo", "codegraph"), { fileExists });
683
762
  }
684
763
  function resolveBundledShim(requireResolve, fileExists) {
685
764
  try {
686
765
  const packageJson = requireResolve(`${CODEGRAPH_PACKAGE}/package.json`);
687
766
  const packageRoot = dirname2(packageJson);
688
- const candidates = [join7(packageRoot, "bin", "codegraph.js"), join7(packageRoot, "npm-shim.js")];
767
+ const candidates = [join8(packageRoot, "bin", "codegraph.js"), join8(packageRoot, "npm-shim.js")];
689
768
  return candidates.find((candidate) => fileExists(candidate)) ?? null;
690
769
  } catch (error) {
691
770
  if (error instanceof Error)
@@ -701,7 +780,7 @@ function resolveBundledShim(requireResolve, fileExists) {
701
780
  }
702
781
  function resolveCodegraphCommand(options = {}) {
703
782
  const env = options.env ?? process.env;
704
- const fileExists = options.fileExists ?? existsSync3;
783
+ const fileExists = options.fileExists ?? existsSync4;
705
784
  const configuredBin = env[CODEGRAPH_ENV_BIN]?.trim() || env[CODEGRAPH_LEGACY_ENV_BIN]?.trim();
706
785
  if (configuredBin !== undefined && configuredBin.length > 0) {
707
786
  return { argsPrefix: [], command: configuredBin, exists: fileExists(configuredBin), source: "env" };
@@ -726,15 +805,97 @@ function resolveCodegraphCommand(options = {}) {
726
805
  };
727
806
  }
728
807
 
808
+ // ../../utils/src/process-tree.ts
809
+ import { execFile, spawn } from "node:child_process";
810
+ import { StringDecoder } from "node:string_decoder";
811
+ function runProcessWithTreeTimeout(options) {
812
+ return new Promise((resolvePromise) => {
813
+ const child = spawn(options.command, [...options.args], {
814
+ cwd: options.cwd,
815
+ detached: process.platform !== "win32",
816
+ env: options.env,
817
+ stdio: ["ignore", "pipe", "pipe"],
818
+ windowsHide: true
819
+ });
820
+ let stderr = "";
821
+ let stderrBytes = 0;
822
+ let stdout = "";
823
+ let stdoutBytes = 0;
824
+ let timedOut = false;
825
+ let overflowed = false;
826
+ let settled = false;
827
+ let treeTermination;
828
+ const stderrDecoder = new StringDecoder("utf8");
829
+ const stdoutDecoder = new StringDecoder("utf8");
830
+ const capture = (target, chunk) => {
831
+ if (overflowed)
832
+ return;
833
+ const currentBytes = target === "stdout" ? stdoutBytes : stderrBytes;
834
+ if (currentBytes + chunk.length > options.maxBuffer) {
835
+ overflowed = true;
836
+ treeTermination ??= terminateProcessTree(child.pid);
837
+ return;
838
+ }
839
+ if (target === "stdout") {
840
+ stdoutBytes += chunk.length;
841
+ stdout += stdoutDecoder.write(chunk);
842
+ } else {
843
+ stderrBytes += chunk.length;
844
+ stderr += stderrDecoder.write(chunk);
845
+ }
846
+ };
847
+ child.stdout.on("data", (chunk) => capture("stdout", chunk));
848
+ child.stderr.on("data", (chunk) => capture("stderr", chunk));
849
+ const timeout = setTimeout(() => {
850
+ timedOut = true;
851
+ treeTermination ??= terminateProcessTree(child.pid);
852
+ }, options.timeoutMs);
853
+ timeout.unref();
854
+ const settle = async (exitCode, signal) => {
855
+ if (settled)
856
+ return;
857
+ settled = true;
858
+ clearTimeout(timeout);
859
+ await treeTermination;
860
+ stderr += stderrDecoder.end();
861
+ stdout += stdoutDecoder.end();
862
+ resolvePromise({ exitCode, signal, stderr, stdout, timedOut });
863
+ };
864
+ child.once("error", () => void settle(1, null));
865
+ child.once("close", (code, signal) => void settle(overflowed ? 1 : code ?? 1, signal));
866
+ });
867
+ }
868
+ function terminateProcessTree(pid) {
869
+ if (pid === undefined)
870
+ return Promise.resolve();
871
+ if (process.platform === "win32")
872
+ return taskkillProcessTree(pid);
873
+ try {
874
+ process.kill(-pid, "SIGKILL");
875
+ } catch (error) {
876
+ if (!isIgnorableKillError(error))
877
+ throw error;
878
+ }
879
+ return Promise.resolve();
880
+ }
881
+ function taskkillProcessTree(pid) {
882
+ return new Promise((resolvePromise) => {
883
+ execFile("taskkill.exe", ["/PID", String(pid), "/T", "/F"], { timeout: 5000, windowsHide: true }, () => resolvePromise());
884
+ });
885
+ }
886
+ function isIgnorableKillError(error) {
887
+ return error instanceof Error && "code" in error && (error.code === "EPERM" || error.code === "ESRCH");
888
+ }
889
+
729
890
  // shared/src/config-loader.ts
730
891
  import { homedir as homedir8 } from "node:os";
731
892
 
732
893
  // ../../utils/src/omo-config/loader.ts
733
- import { existsSync as existsSync5 } from "node:fs";
894
+ import { existsSync as existsSync6 } from "node:fs";
734
895
  import { homedir as homedir7 } from "node:os";
735
896
 
736
897
  // ../../utils/src/omo-config/body.ts
737
- import { readFileSync as readFileSync3 } from "node:fs";
898
+ import { readFileSync as readFileSync4 } from "node:fs";
738
899
 
739
900
  // ../../utils/src/deep-merge.ts
740
901
  var DANGEROUS_KEYS = new Set(["__proto__", "constructor", "prototype"]);
@@ -1623,6 +1784,7 @@ var SETTING_HARNESS_SUPPORT = {
1623
1784
  var BUILT_IN_DEFAULTS = {
1624
1785
  codegraph: {
1625
1786
  auto_provision: true,
1787
+ daemon: true,
1626
1788
  enabled: true,
1627
1789
  telemetry: false
1628
1790
  }
@@ -1782,7 +1944,7 @@ function normalizeActiveHarnessBlock(value, harness, pathPrefix, warnings) {
1782
1944
  }
1783
1945
  function loadConfigFile(path, harness) {
1784
1946
  try {
1785
- const content = readFileSync3(path, "utf-8");
1947
+ const content = readFileSync4(path, "utf-8");
1786
1948
  const parsed = parseJsoncSafe(content);
1787
1949
  if (parsed.errors.length > 0) {
1788
1950
  return {
@@ -1905,22 +2067,22 @@ function buildEnvOverrides(harness, env, warnings, merge) {
1905
2067
  }
1906
2068
 
1907
2069
  // ../../utils/src/omo-config/resolve.ts
1908
- import { existsSync as existsSync4 } from "node:fs";
1909
- import { dirname as dirname3, isAbsolute as isAbsolute2, join as join8, relative, resolve as resolve4 } from "node:path";
2070
+ import { existsSync as existsSync5 } from "node:fs";
2071
+ import { dirname as dirname3, isAbsolute as isAbsolute2, join as join9, relative, resolve as resolve5 } from "node:path";
1910
2072
  function containsPath(parent, child) {
1911
2073
  const pathToChild = relative(parent, child);
1912
2074
  return pathToChild === "" || !pathToChild.startsWith("..") && !isAbsolute2(pathToChild);
1913
2075
  }
1914
2076
  function findProjectConfigPathsNearestFirst(cwd, homeDir) {
1915
- const startDir = resolve4(cwd);
1916
- const stopBeforeDir = containsPath(resolve4(homeDir), startDir) ? resolve4(homeDir) : null;
2077
+ const startDir = resolve5(cwd);
2078
+ const stopBeforeDir = containsPath(resolve5(homeDir), startDir) ? resolve5(homeDir) : null;
1917
2079
  const paths = [];
1918
2080
  let currentDir = startDir;
1919
2081
  while (true) {
1920
2082
  if (stopBeforeDir !== null && currentDir === stopBeforeDir)
1921
2083
  break;
1922
- const configPath = join8(currentDir, ".omo", "config.jsonc");
1923
- if (existsSync4(configPath)) {
2084
+ const configPath = join9(currentDir, ".omo", "config.jsonc");
2085
+ if (existsSync5(configPath)) {
1924
2086
  paths.push(configPath);
1925
2087
  }
1926
2088
  const parentDir = dirname3(currentDir);
@@ -1931,7 +2093,7 @@ function findProjectConfigPathsNearestFirst(cwd, homeDir) {
1931
2093
  return paths;
1932
2094
  }
1933
2095
  function resolveOmoConfigPaths(options) {
1934
- const globalPath = join8(resolve4(options.homeDir), ".omo", "config.jsonc");
2096
+ const globalPath = join9(resolve5(options.homeDir), ".omo", "config.jsonc");
1935
2097
  const projectPathsFarthestFirst = findProjectConfigPathsNearestFirst(options.cwd, options.homeDir).reverse();
1936
2098
  return [
1937
2099
  { path: globalPath, scope: "global" },
@@ -1956,7 +2118,7 @@ function loadOmoConfig(options) {
1956
2118
  const sources = [];
1957
2119
  const warnings = [];
1958
2120
  for (const candidate of resolveOmoConfigPaths({ cwd, homeDir })) {
1959
- if (!existsSync5(candidate.path)) {
2121
+ if (!existsSync6(candidate.path)) {
1960
2122
  if (candidate.scope === "global") {
1961
2123
  sources.push(toMissingSource(candidate));
1962
2124
  }
@@ -2028,13 +2190,13 @@ function isNonFatalCodegraphGcError(error) {
2028
2190
  // components/codegraph/src/hook-sweep.ts
2029
2191
  import { fileURLToPath } from "node:url";
2030
2192
  // ../../utils/src/process-sweep/sweeper.ts
2031
- import { existsSync as existsSync7, mkdirSync as mkdirSync2, statSync as statSync2, utimesSync, writeFileSync as writeFileSync2 } from "node:fs";
2193
+ import { existsSync as existsSync8, mkdirSync as mkdirSync2, statSync as statSync2, utimesSync, writeFileSync as writeFileSync2 } from "node:fs";
2032
2194
  import { homedir as homedir10 } from "node:os";
2033
- import { dirname as dirname5, join as join11 } from "node:path";
2195
+ import { dirname as dirname5, join as join12 } from "node:path";
2034
2196
 
2035
2197
  // ../../utils/src/codegraph/daemon-lock.ts
2036
- import { readFileSync as readFileSync4, realpathSync as realpathSync4 } from "node:fs";
2037
- import { dirname as dirname4, join as join9, resolve as resolve5 } from "node:path";
2198
+ import { readFileSync as readFileSync5, realpathSync as realpathSync4 } from "node:fs";
2199
+ import { dirname as dirname4, join as join10, resolve as resolve6 } from "node:path";
2038
2200
  function parseDaemonLock(raw) {
2039
2201
  const trimmed = raw.trim();
2040
2202
  if (trimmed.length === 0)
@@ -2065,10 +2227,10 @@ function parseDaemonLock(raw) {
2065
2227
  }
2066
2228
  function daemonLockCandidates(projectRoot) {
2067
2229
  const dirs = new Set;
2068
- const resolved = resolve5(projectRoot);
2230
+ const resolved = resolve6(projectRoot);
2069
2231
  collectAncestors(resolved, dirs);
2070
2232
  collectAncestors(realpathIfPossible2(resolved), dirs);
2071
- return [...dirs].map((dir) => join9(dir, ".codegraph", "daemon.pid"));
2233
+ return [...dirs].map((dir) => join10(dir, ".codegraph", "daemon.pid"));
2072
2234
  }
2073
2235
  function evaluateDaemonStaleness(pid, projectRoot) {
2074
2236
  let sawLock = false;
@@ -2089,7 +2251,7 @@ function evaluateDaemonStaleness(pid, projectRoot) {
2089
2251
  }
2090
2252
  function readLockIfPresent(lockPath) {
2091
2253
  try {
2092
- return readFileSync4(lockPath, "utf8");
2254
+ return readFileSync5(lockPath, "utf8");
2093
2255
  } catch (error) {
2094
2256
  if (error instanceof Error && "code" in error && error.code === "ENOENT")
2095
2257
  return;
@@ -2363,7 +2525,7 @@ function upstreamPackagePathIsUnderRoot(command, root) {
2363
2525
  }
2364
2526
 
2365
2527
  // ../../utils/src/process-sweep/exec.ts
2366
- import { execFile } from "node:child_process";
2528
+ import { execFile as execFile2 } from "node:child_process";
2367
2529
  function enumerateProcesses(platform = process.platform) {
2368
2530
  return platform === "win32" ? enumerateWindowsProcesses() : enumeratePosixProcesses();
2369
2531
  }
@@ -2413,7 +2575,7 @@ function createWindowsKiller() {
2413
2575
  }
2414
2576
  function execFileText(command, args) {
2415
2577
  return new Promise((resolvePromise, reject) => {
2416
- execFile(command, [...args], { encoding: "utf8", maxBuffer: 16 * 1024 * 1024, windowsHide: true }, (error, stdout) => {
2578
+ execFile2(command, [...args], { encoding: "utf8", maxBuffer: 16 * 1024 * 1024, windowsHide: true }, (error, stdout) => {
2417
2579
  if (error !== null) {
2418
2580
  reject(error);
2419
2581
  return;
@@ -2437,9 +2599,9 @@ function processKillErrorMeansAlive(error) {
2437
2599
  }
2438
2600
 
2439
2601
  // ../../utils/src/process-sweep/roots.ts
2440
- import { existsSync as existsSync6, readdirSync as readdirSync2, realpathSync as realpathSync5 } from "node:fs";
2602
+ import { existsSync as existsSync7, readdirSync as readdirSync2, realpathSync as realpathSync5 } from "node:fs";
2441
2603
  import { homedir as homedir9 } from "node:os";
2442
- import { join as join10, resolve as resolve6 } from "node:path";
2604
+ import { join as join11, resolve as resolve7 } from "node:path";
2443
2605
  function discoverCodegraphOwnedRoots(options = {}) {
2444
2606
  const env = options.env ?? process.env;
2445
2607
  const homeDir = options.homeDir ?? env["HOME"] ?? env["USERPROFILE"] ?? homedir9();
@@ -2449,31 +2611,31 @@ function discoverCodegraphOwnedRoots(options = {}) {
2449
2611
  addRoot(roots, options.pluginRoot);
2450
2612
  for (const root of options.extraRoots ?? [])
2451
2613
  addRoot(roots, root);
2452
- for (const root of readCodexPluginCacheRoots(options.codexHome ?? env["CODEX_HOME"] ?? join10(homeDir, ".codex"))) {
2614
+ for (const root of readCodexPluginCacheRoots(options.codexHome ?? env["CODEX_HOME"] ?? join11(homeDir, ".codex"))) {
2453
2615
  addRoot(roots, root);
2454
2616
  }
2455
2617
  return [...roots];
2456
2618
  }
2457
2619
  function readCodexPluginCacheRoots(codexHome) {
2458
- const cacheRoot = join10(codexHome, "plugins", "cache");
2459
- if (!existsSync6(cacheRoot))
2620
+ const cacheRoot = join11(codexHome, "plugins", "cache");
2621
+ if (!existsSync7(cacheRoot))
2460
2622
  return [];
2461
2623
  const roots = [];
2462
2624
  for (const publisher of safeReadDir(cacheRoot)) {
2463
2625
  if (!OMO_CODEX_PLUGIN_CACHE_PUBLISHERS.has(publisher))
2464
2626
  continue;
2465
- const omoRoot = join10(cacheRoot, publisher, "omo");
2466
- if (!existsSync6(omoRoot))
2627
+ const omoRoot = join11(cacheRoot, publisher, "omo");
2628
+ if (!existsSync7(omoRoot))
2467
2629
  continue;
2468
2630
  for (const version of safeReadDir(omoRoot))
2469
- roots.push(join10(omoRoot, version));
2631
+ roots.push(join11(omoRoot, version));
2470
2632
  }
2471
2633
  return roots;
2472
2634
  }
2473
2635
  function addRoot(roots, root) {
2474
2636
  if (root === undefined || root.trim().length === 0)
2475
2637
  return;
2476
- const resolved = resolve6(root);
2638
+ const resolved = resolve7(root);
2477
2639
  roots.add(resolved);
2478
2640
  roots.add(realpathIfPossible3(resolved));
2479
2641
  }
@@ -2491,7 +2653,7 @@ function realpathIfPossible3(path) {
2491
2653
  return realpathSync5(path);
2492
2654
  } catch (error) {
2493
2655
  if (error instanceof Error)
2494
- return resolve6(path);
2656
+ return resolve7(path);
2495
2657
  throw error;
2496
2658
  }
2497
2659
  }
@@ -2534,7 +2696,7 @@ async function runProcessFamilySweep(config, options) {
2534
2696
  var CODEGRAPH_SWEEP_STAMP_FILE = "zombie-sweep.stamp";
2535
2697
  async function sweepCodegraphZombies(options = {}) {
2536
2698
  const homeDir = options.homeDir ?? options.env?.["HOME"] ?? options.env?.["USERPROFILE"] ?? homedir10();
2537
- const stampFile = join11(codegraphDataRoot(homeDir), CODEGRAPH_SWEEP_STAMP_FILE);
2699
+ const stampFile = join12(codegraphDataRoot(homeDir), CODEGRAPH_SWEEP_STAMP_FILE);
2538
2700
  const ownedRoots = options.ownedRoots ?? discoverCodegraphOwnedRoots(options);
2539
2701
  const result = await runProcessFamilySweep({
2540
2702
  familyLabel: "CodeGraph zombie sweep",
@@ -2610,7 +2772,7 @@ async function safelyKill(pid, killer, failed, log, familyLabel) {
2610
2772
  }
2611
2773
  }
2612
2774
  function isSweepThrottled(stampFile, nowMs, throttleMs) {
2613
- if (!existsSync7(stampFile))
2775
+ if (!existsSync8(stampFile))
2614
2776
  return false;
2615
2777
  return nowMs - statSync2(stampFile).mtimeMs < throttleMs;
2616
2778
  }
@@ -2645,70 +2807,31 @@ function defaultPluginRoot() {
2645
2807
  }
2646
2808
 
2647
2809
  // components/codegraph/src/session-start-worker.ts
2648
- import { execFile as execFile3 } from "node:child_process";
2649
- import { appendFileSync as appendFileSync2, existsSync as existsSync9, mkdirSync as mkdirSync3 } from "node:fs";
2810
+ import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync3 } from "node:fs";
2650
2811
  import { homedir as homedir12 } from "node:os";
2651
- import { extname, join as join13 } from "node:path";
2812
+ import { extname, join as join14 } from "node:path";
2652
2813
  import { cwd as processCwd, env as processEnv, execPath as processExecPath, stderr as processStderr } from "node:process";
2653
2814
 
2654
- // ../../utils/src/codegraph/manifest.ts
2655
- var CODEGRAPH_PINNED_VERSION = "1.4.1";
2656
- var CODEGRAPH_PROVISION_MANIFEST = {
2657
- assets: {
2658
- "darwin-arm64": {
2659
- executableName: "codegraph",
2660
- sha256: "4a679ae5a5cb9fff900dd59bb786da6a581b7f68f4cf713bdedd137e347d34dc",
2661
- url: "https://github.com/colbymchenry/codegraph/releases/download/v1.4.1/codegraph-darwin-arm64.tar.gz"
2662
- },
2663
- "darwin-x64": {
2664
- executableName: "codegraph",
2665
- sha256: "436f96943cfd926ea6d0a8454f18833d21254d5fd9b3d224317b1426132def95",
2666
- url: "https://github.com/colbymchenry/codegraph/releases/download/v1.4.1/codegraph-darwin-x64.tar.gz"
2667
- },
2668
- "linux-arm64": {
2669
- executableName: "codegraph",
2670
- sha256: "0d62c5eb2722f8d19d20f7a1bd974445e18d5294cb59be116a0c3d55ce87591f",
2671
- url: "https://github.com/colbymchenry/codegraph/releases/download/v1.4.1/codegraph-linux-arm64.tar.gz"
2672
- },
2673
- "linux-x64": {
2674
- executableName: "codegraph",
2675
- sha256: "fb585ff5018d6faaa46d282b61f4f689bc7967ed8a1b467a5c556dd7ced9b542",
2676
- url: "https://github.com/colbymchenry/codegraph/releases/download/v1.4.1/codegraph-linux-x64.tar.gz"
2677
- },
2678
- "win32-arm64": {
2679
- executableName: "codegraph.cmd",
2680
- sha256: "e2a2a28c802a79804c7df203afa50bd461309c6c180ce3f76079fdc7cddc7697",
2681
- url: "https://registry.npmjs.org/@colbymchenry/codegraph-win32-arm64/-/codegraph-win32-arm64-1.4.1.tgz"
2682
- },
2683
- "win32-x64": {
2684
- executableName: "codegraph.cmd",
2685
- sha256: "4f08700fda5f4a03ad5b2956135c5788d739a351b3433db2b5820e5d5224c30d",
2686
- url: "https://registry.npmjs.org/@colbymchenry/codegraph-win32-x64/-/codegraph-win32-x64-1.4.1.tgz"
2687
- }
2688
- },
2689
- version: CODEGRAPH_PINNED_VERSION
2690
- };
2691
-
2692
2815
  // ../../utils/src/codegraph/provision.ts
2693
2816
  import { createHash as createHash2, randomUUID } from "node:crypto";
2694
- import { execFile as execFile2 } from "node:child_process";
2817
+ import { execFile as execFile3 } from "node:child_process";
2695
2818
  import { chmod, mkdir, readdir, readFile, rename, rm, rmdir, stat, writeFile } from "node:fs/promises";
2696
- import { existsSync as existsSync8 } from "node:fs";
2819
+ import { existsSync as existsSync9 } from "node:fs";
2697
2820
  import { homedir as homedir11, hostname } from "node:os";
2698
- import { basename as basename3, join as join12 } from "node:path";
2821
+ import { basename as basename3, join as join13 } from "node:path";
2699
2822
  import { promisify } from "node:util";
2700
2823
  var DEFAULT_LOCK_WAIT_MS = 5000;
2701
2824
  var DEFAULT_LOCK_STALE_MS = 120000;
2702
2825
  var DEFAULT_DOWNLOAD_TIMEOUT_MS = 60000;
2703
- var execFileAsync = promisify(execFile2);
2826
+ var execFileAsync = promisify(execFile3);
2704
2827
  function platformKey() {
2705
2828
  return `${process.platform}-${process.arch}`;
2706
2829
  }
2707
2830
  function markerPath(installDir, version) {
2708
- return join12(installDir, ".provisioned", `codegraph-${version}.json`);
2831
+ return join13(installDir, ".provisioned", `codegraph-${version}.json`);
2709
2832
  }
2710
2833
  function defaultInstallDir() {
2711
- return join12(homedir11(), ".omo", "codegraph");
2834
+ return join13(homedir11(), ".omo", "codegraph");
2712
2835
  }
2713
2836
  function sha256(bytes) {
2714
2837
  return createHash2("sha256").update(bytes).digest("hex");
@@ -2728,7 +2851,7 @@ async function removeEmptyDirectory(path) {
2728
2851
  }
2729
2852
  }
2730
2853
  function sleep(ms) {
2731
- return new Promise((resolve7) => setTimeout(resolve7, ms));
2854
+ return new Promise((resolve8) => setTimeout(resolve8, ms));
2732
2855
  }
2733
2856
  async function defaultDownloader(asset, timeoutMs = DEFAULT_DOWNLOAD_TIMEOUT_MS) {
2734
2857
  const response = await fetch(asset.url, { signal: AbortSignal.timeout(timeoutMs) });
@@ -2742,7 +2865,7 @@ function forcedBadChecksumOptions(options) {
2742
2865
  const key = options.platformKey ?? platformKey();
2743
2866
  return {
2744
2867
  downloader: async () => new TextEncoder().encode("checksum mismatch"),
2745
- installDir: options.installDir ?? join12(options.lockDir, "codegraph-force-bad-checksum"),
2868
+ installDir: options.installDir ?? join13(options.lockDir, "codegraph-force-bad-checksum"),
2746
2869
  manifest: {
2747
2870
  assets: {
2748
2871
  [key]: { executableName: process.platform === "win32" ? "codegraph.cmd" : "codegraph", sha256: "0000", url: "memory://bad" }
@@ -2753,13 +2876,13 @@ function forcedBadChecksumOptions(options) {
2753
2876
  };
2754
2877
  }
2755
2878
  async function readMarker(path) {
2756
- if (!existsSync8(path))
2879
+ if (!existsSync9(path))
2757
2880
  return null;
2758
2881
  try {
2759
2882
  const raw = JSON.parse(await readFile(path, "utf8"));
2760
2883
  if (typeof raw === "object" && raw !== null && "binPath" in raw) {
2761
2884
  const value = raw.binPath;
2762
- return typeof value === "string" && existsSync8(value) ? value : null;
2885
+ return typeof value === "string" && existsSync9(value) ? value : null;
2763
2886
  }
2764
2887
  return null;
2765
2888
  } catch (error) {
@@ -2770,7 +2893,7 @@ async function readMarker(path) {
2770
2893
  }
2771
2894
  async function acquireLock(lockPath, waitMs, staleMs) {
2772
2895
  const startedAt = Date.now();
2773
- await mkdir(join12(lockPath, ".."), { recursive: true });
2896
+ await mkdir(join13(lockPath, ".."), { recursive: true });
2774
2897
  while (Date.now() - startedAt <= waitMs) {
2775
2898
  try {
2776
2899
  await mkdir(lockPath);
@@ -2795,24 +2918,24 @@ async function installExtractedBundle(extractDir, installDir, executableName) {
2795
2918
  const roots = await readdir(extractDir);
2796
2919
  if (roots.length !== 1)
2797
2920
  throw new Error(`CodeGraph archive should contain one root directory, found ${roots.length}`);
2798
- const bundleDir = join12(extractDir, roots[0] ?? "");
2921
+ const bundleDir = join13(extractDir, roots[0] ?? "");
2799
2922
  const bundleEntries = await readdir(bundleDir);
2800
2923
  await mkdir(installDir, { recursive: true });
2801
2924
  for (const entry of bundleEntries) {
2802
- await rm(join12(installDir, entry), { force: true, recursive: true });
2803
- await rename(join12(bundleDir, entry), join12(installDir, entry));
2925
+ await rm(join13(installDir, entry), { force: true, recursive: true });
2926
+ await rename(join13(bundleDir, entry), join13(installDir, entry));
2804
2927
  }
2805
- const destination = join12(installDir, "bin", executableName);
2806
- if (!existsSync8(destination))
2928
+ const destination = join13(installDir, "bin", executableName);
2929
+ if (!existsSync9(destination))
2807
2930
  throw new Error(`CodeGraph archive did not contain bin/${executableName}`);
2808
2931
  await chmod(destination, 493);
2809
2932
  return destination;
2810
2933
  }
2811
2934
  async function installAsset(layout) {
2812
2935
  const { asset, downloader, installDir, version } = layout;
2813
- const stagingDir = join12(installDir, ".staging", randomUUID());
2814
- const archivePath = join12(stagingDir, basename3(asset.url));
2815
- const extractDir = join12(stagingDir, "extract");
2936
+ const stagingDir = join13(installDir, ".staging", randomUUID());
2937
+ const archivePath = join13(stagingDir, basename3(asset.url));
2938
+ const extractDir = join13(stagingDir, "extract");
2816
2939
  try {
2817
2940
  await mkdir(extractDir, { recursive: true });
2818
2941
  const bytes = await downloader(asset);
@@ -2826,13 +2949,13 @@ async function installAsset(layout) {
2826
2949
  await writeFile(archivePath, bytes);
2827
2950
  await extractTarGz(archivePath, extractDir);
2828
2951
  const destination = await installExtractedBundle(extractDir, installDir, asset.executableName);
2829
- await mkdir(join12(installDir, ".provisioned"), { recursive: true });
2952
+ await mkdir(join13(installDir, ".provisioned"), { recursive: true });
2830
2953
  await writeFile(markerPath(installDir, version), `${JSON.stringify({ binPath: destination, version })}
2831
2954
  `);
2832
2955
  return destination;
2833
2956
  } finally {
2834
2957
  await rm(stagingDir, { force: true, recursive: true });
2835
- await removeEmptyDirectory(join12(installDir, ".staging"));
2958
+ await removeEmptyDirectory(join13(installDir, ".staging"));
2836
2959
  }
2837
2960
  }
2838
2961
  async function ensureCodegraphProvisioned(options) {
@@ -2845,7 +2968,7 @@ async function ensureCodegraphProvisioned(options) {
2845
2968
  const existing = await readMarker(marker);
2846
2969
  if (existing !== null)
2847
2970
  return { binPath: existing, provisioned: true };
2848
- const lockPath = join12(options.lockDir, `codegraph-${hostname()}.lock`);
2971
+ const lockPath = join13(options.lockDir, `codegraph-${hostname()}.lock`);
2849
2972
  const release = await acquireLock(lockPath, options.lockWaitMs ?? DEFAULT_LOCK_WAIT_MS, options.lockStaleMs ?? DEFAULT_LOCK_STALE_MS);
2850
2973
  if (release === null)
2851
2974
  return { error: "timed out waiting for codegraph provisioning lock", provisioned: false };
@@ -2935,8 +3058,8 @@ async function resolveOrProvisionCommand(deps, config, env, homeDir, nodeSupport
2935
3058
  return { kind: "unsupported-node" };
2936
3059
  if (config.auto_provision === false)
2937
3060
  return { error: "codegraph binary unavailable and auto_provision is disabled", kind: "unavailable", source: resolved.source };
2938
- const installDir = trustedInstallDir ?? join13(homeDir, ".omo", "codegraph");
2939
- const provisioned = await deps.ensureProvisioned({ installDir, lockDir: join13(installDir, ".locks"), version: CODEGRAPH_VERSION });
3061
+ const installDir = trustedInstallDir ?? join14(homeDir, ".omo", "codegraph");
3062
+ const provisioned = await deps.ensureProvisioned({ installDir, lockDir: join14(installDir, ".locks"), version: CODEGRAPH_VERSION });
2940
3063
  if (!provisioned.provisioned || provisioned.binPath === undefined) {
2941
3064
  return { error: provisioned.error ?? "provisioning did not produce a binary", kind: "unavailable", source: resolved.source };
2942
3065
  }
@@ -2983,15 +3106,14 @@ function jsonSaysInitialized(value) {
2983
3106
  }
2984
3107
  async function runCodegraphCommand(projectRoot, command, args, options) {
2985
3108
  const invocation = resolveCodegraphCommandInvocation(command, args);
2986
- return new Promise((resolvePromise) => {
2987
- execFile3(invocation.command, [...invocation.args], { cwd: projectRoot, encoding: "utf8", env: buildCodegraphChildEnv({ ambientEnv: processEnv, codegraphEnv: options.env }), maxBuffer: 1024 * 1024, timeout: options.timeoutMs, windowsHide: true }, (error, stdout, stderr) => {
2988
- if (error === null) {
2989
- resolvePromise({ exitCode: 0, stderr: toOutputText(stderr), stdout: toOutputText(stdout), timedOut: false });
2990
- return;
2991
- }
2992
- resolvePromise({ exitCode: resolveExitCode(error), stderr: toOutputText(stderr), stdout: toOutputText(stdout), timedOut: error.killed === true });
2993
- });
2994
- });
3109
+ return runProcessWithTreeTimeout({
3110
+ args: invocation.args,
3111
+ command: invocation.command,
3112
+ cwd: projectRoot,
3113
+ env: buildCodegraphChildEnv({ ambientEnv: processEnv, codegraphEnv: options.env }),
3114
+ maxBuffer: 1024 * 1024,
3115
+ timeoutMs: options.timeoutMs
3116
+ }).then(({ exitCode, stderr, stdout, timedOut }) => ({ exitCode, stderr, stdout, timedOut }));
2995
3117
  }
2996
3118
  function resolveCodegraphCommandInvocation(command, args, platform = process.platform) {
2997
3119
  if (platform !== "win32")
@@ -3004,9 +3126,9 @@ function resolveCodegraphCommandInvocation(command, args, platform = process.pla
3004
3126
  return { args: ["/d", "/s", "/c", command, ...args], command: "cmd.exe" };
3005
3127
  }
3006
3128
  function appendOutcome(homeDir, outcome) {
3007
- const logDir = join13(homeDir, ".omo", "codegraph");
3129
+ const logDir = join14(homeDir, ".omo", "codegraph");
3008
3130
  mkdirSync3(logDir, { recursive: true });
3009
- appendFileSync2(join13(logDir, "session-start.jsonl"), `${JSON.stringify({ ...outcome, timestamp: new Date().toISOString() })}
3131
+ appendFileSync2(join14(logDir, "session-start.jsonl"), `${JSON.stringify({ ...outcome, timestamp: new Date().toISOString() })}
3010
3132
  `);
3011
3133
  }
3012
3134
  function safeLogOutcome(logOutcome, outcome) {
@@ -3021,18 +3143,7 @@ function safeLogOutcome(logOutcome, outcome) {
3021
3143
  }
3022
3144
  }
3023
3145
  function provisionedBinFromInstallDir(installDir) {
3024
- if (installDir === undefined)
3025
- return null;
3026
- const candidate = join13(installDir, "bin", process.platform === "win32" ? "codegraph.cmd" : "codegraph");
3027
- return existsSync9(candidate) ? candidate : null;
3028
- }
3029
- function resolveExitCode(error) {
3030
- if ("code" in error && typeof error.code === "number")
3031
- return error.code;
3032
- return 1;
3033
- }
3034
- function toOutputText(value) {
3035
- return Buffer.isBuffer(value) ? value.toString("utf8") : value;
3146
+ return resolvePinnedCodegraphBin(installDir);
3036
3147
  }
3037
3148
  function resolveHomeDir2(env) {
3038
3149
  return env["HOME"] ?? env["USERPROFILE"] ?? homedir12();
@@ -3065,13 +3176,6 @@ async function executeCodegraphSessionStartHook(options = {}) {
3065
3176
  const projectRoot = resolveProjectRoot(input, options.cwd ?? processCwd2());
3066
3177
  const homeDir = resolveHomeDir3(env);
3067
3178
  const config = options.config ?? getCodexOmoConfig({ cwd: projectRoot, env, homeDir });
3068
- pruneCodegraphProjectStoresBestEffort(homeDir, { debugLog: writeDebugLog });
3069
- await sweepCodegraphZombiesBestEffort({
3070
- env,
3071
- homeDir,
3072
- ...config.trustedCodegraphInstallDir === undefined ? {} : { trustedCodegraphInstallDir: config.trustedCodegraphInstallDir },
3073
- log: writeDebugLog
3074
- }, options.sweepZombies);
3075
3179
  if (config.codegraph?.enabled === false) {
3076
3180
  return { action: "skipped-disabled", exitCode: 0 };
3077
3181
  }
@@ -3083,8 +3187,15 @@ async function executeCodegraphSessionStartHook(options = {}) {
3083
3187
  if (exclusion.excluded) {
3084
3188
  return { action: "skipped-excluded", exitCode: 0 };
3085
3189
  }
3190
+ pruneCodegraphProjectStoresBestEffort(homeDir, { debugLog: writeDebugLog });
3191
+ await sweepCodegraphZombiesBestEffort({
3192
+ env,
3193
+ homeDir,
3194
+ ...config.trustedCodegraphInstallDir === undefined ? {} : { trustedCodegraphInstallDir: config.trustedCodegraphInstallDir },
3195
+ log: writeDebugLog
3196
+ }, options.sweepZombies);
3086
3197
  const isInitialized = await (options.statusProbe ?? isCodegraphProjectInitialized)({
3087
- daemon: config.codegraph?.daemon === true,
3198
+ daemon: config.codegraph?.daemon !== false,
3088
3199
  env,
3089
3200
  homeDir,
3090
3201
  projectRoot,
@@ -3124,22 +3235,14 @@ async function isCodegraphProjectInitialized(options) {
3124
3235
  return codegraphStatusSaysInitialized(status.stdout);
3125
3236
  }
3126
3237
  function runStatusProbe(projectRoot, command, args, env) {
3127
- return new Promise((resolveProbe) => {
3128
- execFile4(command, [...args], {
3129
- cwd: projectRoot,
3130
- encoding: "utf8",
3131
- env,
3132
- maxBuffer: 1024 * 1024,
3133
- timeout: STATUS_PROBE_TIMEOUT_MS,
3134
- windowsHide: true
3135
- }, (error, stdout) => {
3136
- if (error === null) {
3137
- resolveProbe({ exitCode: 0, stdout: toOutputText2(stdout), timedOut: false });
3138
- return;
3139
- }
3140
- resolveProbe({ exitCode: resolveExitCode2(error), stdout: toOutputText2(stdout), timedOut: error.killed === true });
3141
- });
3142
- });
3238
+ return runProcessWithTreeTimeout({
3239
+ args,
3240
+ command,
3241
+ cwd: projectRoot,
3242
+ env,
3243
+ maxBuffer: 1024 * 1024,
3244
+ timeoutMs: STATUS_PROBE_TIMEOUT_MS
3245
+ }).then(({ exitCode, stdout, timedOut }) => ({ exitCode, stdout, timedOut }));
3143
3246
  }
3144
3247
  function codegraphStatusSaysInitialized(stdout) {
3145
3248
  const parsed = parseJson3(stdout);
@@ -3155,9 +3258,7 @@ function codegraphStatusSaysInitialized(stdout) {
3155
3258
  return (normalized.includes("initialized") || normalized.includes("ready")) && !normalized.includes("not initialized") && !normalized.includes("uninitialized");
3156
3259
  }
3157
3260
  function provisionedBinFromInstallDir2(installDir) {
3158
- if (installDir === undefined)
3159
- return null;
3160
- return join14(installDir, "bin", process.platform === "win32" ? "codegraph.cmd" : "codegraph");
3261
+ return resolvePinnedCodegraphBin(installDir);
3161
3262
  }
3162
3263
  async function executeCodegraphPostToolUseHook(options = {}) {
3163
3264
  const env = options.env ?? processEnv2;
@@ -3200,20 +3301,12 @@ function writeDebugLog(message) {
3200
3301
  `);
3201
3302
  }
3202
3303
  function spawnDetachedWorker(invocation) {
3203
- const child = spawn(invocation.command, [...invocation.args], { detached: true, env: invocation.env, stdio: "ignore" });
3304
+ const child = spawn2(invocation.command, [...invocation.args], { detached: true, env: invocation.env, stdio: "ignore" });
3204
3305
  child.unref();
3205
3306
  }
3206
3307
  function resolveHomeDir3(env) {
3207
3308
  return env["HOME"] ?? env["USERPROFILE"] ?? homedir13();
3208
3309
  }
3209
- function resolveExitCode2(error) {
3210
- if ("code" in error && typeof error.code === "number")
3211
- return error.code;
3212
- return 1;
3213
- }
3214
- function toOutputText2(value) {
3215
- return Buffer.isBuffer(value) ? value.toString("utf8") : value;
3216
- }
3217
3310
  function resolveProjectRoot(input, fallback) {
3218
3311
  if (!isRecord5(input))
3219
3312
  return fallback;
@@ -3249,7 +3342,7 @@ function defaultWorkerCliPath() {
3249
3342
  // components/codegraph/src/serve.ts
3250
3343
  import { existsSync as existsSync10, realpathSync as realpathSync6 } from "node:fs";
3251
3344
  import { homedir as homedir14 } from "node:os";
3252
- import { basename as basename4, join as join15, resolve as resolve7 } from "node:path";
3345
+ import { basename as basename4, join as join15, resolve as resolve8 } from "node:path";
3253
3346
  import {
3254
3347
  cwd as processCwd3,
3255
3348
  env as processEnv3,
@@ -3260,10 +3353,10 @@ import {
3260
3353
  import { fileURLToPath as fileURLToPath3 } from "node:url";
3261
3354
 
3262
3355
  // components/codegraph/src/mcp-bridge.ts
3263
- import { spawn as spawn2 } from "node:child_process";
3356
+ import { spawn as spawn3 } from "node:child_process";
3264
3357
 
3265
3358
  // ../../mcp-stdio-core/src/record.ts
3266
- function isPlainRecord(value) {
3359
+ function isPlainRecord2(value) {
3267
3360
  return typeof value === "object" && value !== null && !Array.isArray(value);
3268
3361
  }
3269
3362
  // ../../mcp-stdio-core/src/responses.ts
@@ -3310,7 +3403,7 @@ ${body}` : `${body}
3310
3403
  await writeChunk(output, payload);
3311
3404
  }
3312
3405
  function writeChunk(output, chunk) {
3313
- return new Promise((resolve7, reject) => {
3406
+ return new Promise((resolve8, reject) => {
3314
3407
  let settled = false;
3315
3408
  const onError = (error) => {
3316
3409
  if (settled)
@@ -3330,7 +3423,7 @@ function writeChunk(output, chunk) {
3330
3423
  return;
3331
3424
  }
3332
3425
  output.removeListener("error", onError);
3333
- resolve7();
3426
+ resolve8();
3334
3427
  });
3335
3428
  } catch (error) {
3336
3429
  output.removeListener("error", onError);
@@ -3483,8 +3576,8 @@ async function handleParseError(message, config, log) {
3483
3576
  }
3484
3577
  async function handleRequest(message, config, log) {
3485
3578
  const parsed = message.payload;
3486
- const id = isPlainRecord(parsed) ? jsonRpcId(parsed["id"]) : null;
3487
- const method = isPlainRecord(parsed) && typeof parsed["method"] === "string" ? parsed["method"] : null;
3579
+ const id = isPlainRecord2(parsed) ? jsonRpcId(parsed["id"]) : null;
3580
+ const method = isPlainRecord2(parsed) && typeof parsed["method"] === "string" ? parsed["method"] : null;
3488
3581
  log("request", { id: id === null ? null : String(id), method });
3489
3582
  let response;
3490
3583
  try {
@@ -3602,7 +3695,7 @@ var CODEGRAPH_CONTAINER_OUTLINE_GUIDANCE = "Container symbols intentionally retu
3602
3695
  var SIGKILL_ESCALATION_MS = 2000;
3603
3696
  async function runBridgedCodegraphProcess(command, args, options) {
3604
3697
  const invocation = resolveServeProcessInvocation(command, args);
3605
- const child = spawn2(invocation.command, invocation.args, {
3698
+ const child = spawn3(invocation.command, invocation.args, {
3606
3699
  cwd: options.cwd,
3607
3700
  env: options.env,
3608
3701
  stdio: ["pipe", "pipe", "inherit"]
@@ -3716,22 +3809,22 @@ async function forwardCodegraphToClient(childOutput, output, pendingResponses, d
3716
3809
  }
3717
3810
  }
3718
3811
  function responseModeKey(payload) {
3719
- if (!isPlainRecord(payload) || !("id" in payload))
3812
+ if (!isPlainRecord2(payload) || !("id" in payload))
3720
3813
  return null;
3721
3814
  const id = jsonRpcId(payload["id"]);
3722
3815
  return `${typeof id}:${String(id)}`;
3723
3816
  }
3724
3817
  function jsonRpcMethod(payload) {
3725
- if (!isPlainRecord(payload))
3818
+ if (!isPlainRecord2(payload))
3726
3819
  return null;
3727
3820
  const method = payload["method"];
3728
3821
  return typeof method === "string" ? method : null;
3729
3822
  }
3730
3823
  function jsonRpcToolName(payload) {
3731
- if (jsonRpcMethod(payload) !== "tools/call" || !isPlainRecord(payload))
3824
+ if (jsonRpcMethod(payload) !== "tools/call" || !isPlainRecord2(payload))
3732
3825
  return null;
3733
3826
  const params = payload["params"];
3734
- if (!isPlainRecord(params))
3827
+ if (!isPlainRecord2(params))
3735
3828
  return null;
3736
3829
  const name = params["name"];
3737
3830
  return typeof name === "string" ? name : null;
@@ -3745,14 +3838,14 @@ function clarifyCodegraphResponse(payload, pendingResponse) {
3745
3838
  return payload;
3746
3839
  }
3747
3840
  function clarifyCodegraphToolsList(payload) {
3748
- if (!isPlainRecord(payload))
3841
+ if (!isPlainRecord2(payload))
3749
3842
  return payload;
3750
3843
  const result = payload["result"];
3751
- if (!isPlainRecord(result) || !Array.isArray(result["tools"]))
3844
+ if (!isPlainRecord2(result) || !Array.isArray(result["tools"]))
3752
3845
  return payload;
3753
3846
  let changed = false;
3754
3847
  const tools = result["tools"].map((tool) => {
3755
- if (!isPlainRecord(tool) || tool["name"] !== "codegraph_node")
3848
+ if (!isPlainRecord2(tool) || tool["name"] !== "codegraph_node")
3756
3849
  return tool;
3757
3850
  if (!hasCodegraphNodeContractMetadata(tool))
3758
3851
  return tool;
@@ -3769,7 +3862,7 @@ function clarifyCodegraphNodeTool(tool) {
3769
3862
  description: CODEGRAPH_NODE_DESCRIPTION
3770
3863
  };
3771
3864
  const inputSchema = tool["inputSchema"];
3772
- if (isPlainRecord(inputSchema))
3865
+ if (isPlainRecord2(inputSchema))
3773
3866
  clarified["inputSchema"] = clarifyCodegraphNodeInputSchema(inputSchema);
3774
3867
  return clarified;
3775
3868
  }
@@ -3777,17 +3870,17 @@ function hasCodegraphNodeContractMetadata(tool) {
3777
3870
  if (typeof tool["description"] === "string")
3778
3871
  return true;
3779
3872
  const inputSchema = tool["inputSchema"];
3780
- if (!isPlainRecord(inputSchema))
3873
+ if (!isPlainRecord2(inputSchema))
3781
3874
  return false;
3782
3875
  const properties = inputSchema["properties"];
3783
- return isPlainRecord(properties) && isPlainRecord(properties["includeCode"]);
3876
+ return isPlainRecord2(properties) && isPlainRecord2(properties["includeCode"]);
3784
3877
  }
3785
3878
  function clarifyCodegraphNodeInputSchema(inputSchema) {
3786
3879
  const properties = inputSchema["properties"];
3787
- if (!isPlainRecord(properties))
3880
+ if (!isPlainRecord2(properties))
3788
3881
  return inputSchema;
3789
3882
  const includeCode = properties["includeCode"];
3790
- if (!isPlainRecord(includeCode))
3883
+ if (!isPlainRecord2(includeCode))
3791
3884
  return inputSchema;
3792
3885
  return {
3793
3886
  ...inputSchema,
@@ -3801,14 +3894,14 @@ function clarifyCodegraphNodeInputSchema(inputSchema) {
3801
3894
  };
3802
3895
  }
3803
3896
  function clarifyCodegraphNodeCallResult(payload) {
3804
- if (!isPlainRecord(payload))
3897
+ if (!isPlainRecord2(payload))
3805
3898
  return payload;
3806
3899
  const result = payload["result"];
3807
- if (!isPlainRecord(result) || !Array.isArray(result["content"]))
3900
+ if (!isPlainRecord2(result) || !Array.isArray(result["content"]))
3808
3901
  return payload;
3809
3902
  let changed = false;
3810
3903
  const content = result["content"].map((item) => {
3811
- if (!isPlainRecord(item) || item["type"] !== "text" || typeof item["text"] !== "string")
3904
+ if (!isPlainRecord2(item) || item["type"] !== "text" || typeof item["text"] !== "string")
3812
3905
  return item;
3813
3906
  const text = clarifyContainerOutlineGuidance(item["text"]);
3814
3907
  if (text === item["text"])
@@ -3849,7 +3942,7 @@ async function runUnavailableCodegraphMcpServer(options) {
3849
3942
  });
3850
3943
  }
3851
3944
  async function handleUnavailableCodegraphMcpRequest(input, options) {
3852
- if (!isPlainRecord(input)) {
3945
+ if (!isPlainRecord2(input)) {
3853
3946
  return errorResponse(null, -32600, "Invalid Request");
3854
3947
  }
3855
3948
  const id = jsonRpcId(input["id"]);
@@ -3877,7 +3970,7 @@ async function handleUnavailableCodegraphMcpRequest(input, options) {
3877
3970
  return errorResponse(id, -32601, `Method not found: ${String(method)}`);
3878
3971
  }
3879
3972
  function requestedProtocolVersion(params) {
3880
- if (!isPlainRecord(params) || typeof params["protocolVersion"] !== "string")
3973
+ if (!isPlainRecord2(params) || typeof params["protocolVersion"] !== "string")
3881
3974
  return "2024-11-05";
3882
3975
  return params["protocolVersion"];
3883
3976
  }
@@ -3937,7 +4030,7 @@ async function runCodegraphServe(options = {}) {
3937
4030
  return runUnavailableMcp(buildCodegraphNodeSkipHint(nodeSupport), options);
3938
4031
  }
3939
4032
  const runProcess = options.runProcess ?? runBridgedCodegraphProcess;
3940
- const codegraphEnv = codegraphEnvForConfig2(trustedInstallDir, homeDir, codegraphConfig.daemon === true, options.buildEnv);
4033
+ const codegraphEnv = codegraphEnvForConfig2(trustedInstallDir, homeDir, codegraphConfig.daemon !== false, options.buildEnv);
3941
4034
  const mergedEnv = buildCodegraphChildEnv({ ambientEnv: env, codegraphEnv, runtimeEnv: env });
3942
4035
  return runProcess(resolution.command, [...resolution.argsPrefix, "serve", "--mcp"], {
3943
4036
  cwd: projectCwd,
@@ -3994,17 +4087,14 @@ function resolveProjectCwd(env, fallback) {
3994
4087
  const candidate = env[key]?.trim();
3995
4088
  if (candidate === undefined || candidate.length === 0)
3996
4089
  continue;
3997
- const resolved = resolve7(candidate);
4090
+ const resolved = resolve8(candidate);
3998
4091
  if (existsSync10(resolved))
3999
4092
  return resolved;
4000
4093
  }
4001
- return resolve7(fallback);
4094
+ return resolve8(fallback);
4002
4095
  }
4003
4096
  function provisionedBinFromInstallDir3(installDir) {
4004
- if (installDir === undefined)
4005
- return null;
4006
- const candidate = join15(installDir, "bin", process.platform === "win32" ? "codegraph.cmd" : "codegraph");
4007
- return existsSync10(candidate) ? candidate : null;
4097
+ return resolvePinnedCodegraphBin(installDir);
4008
4098
  }
4009
4099
  async function runCodegraphServeCli() {
4010
4100
  process.exitCode = await runCodegraphServe();
@@ -4023,7 +4113,7 @@ function isDirectInvocation(argvPath) {
4023
4113
  const moduleName = basename4(modulePath);
4024
4114
  if (moduleName !== "serve.js" && moduleName !== "serve.ts")
4025
4115
  return false;
4026
- return realpathSync6(resolve7(argvPath)) === realpathSync6(modulePath);
4116
+ return realpathSync6(resolve8(argvPath)) === realpathSync6(modulePath);
4027
4117
  }
4028
4118
 
4029
4119
  // components/codegraph/src/sweep-cli.ts
@@ -4134,7 +4224,7 @@ function isDirectInvocation2(argvPath) {
4134
4224
  const moduleName = basename5(modulePath);
4135
4225
  if (moduleName !== "cli.js" && moduleName !== "cli.ts")
4136
4226
  return false;
4137
- return realpathSync7(resolve8(argvPath)) === realpathSync7(modulePath);
4227
+ return realpathSync7(resolve9(argvPath)) === realpathSync7(modulePath);
4138
4228
  }
4139
4229
  export {
4140
4230
  runCodegraphCli