lazycodex-ai 4.19.4 → 5.0.0-beta.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 (209) hide show
  1. package/README.ja.md +1 -1
  2. package/README.ko.md +1 -1
  3. package/README.md +6 -5
  4. package/README.ru.md +1 -1
  5. package/README.zh-cn.md +1 -1
  6. package/dist/cli/index.js +1452 -703
  7. package/dist/cli-node/index.js +1452 -703
  8. package/docs/reference/web-terminal-visual-qa.md +1 -1
  9. package/package.json +5 -2
  10. package/packages/lsp-daemon/dist/cli.js +27 -13
  11. package/packages/lsp-daemon/dist/client.js +49 -35
  12. package/packages/lsp-daemon/dist/ensure-daemon.d.ts +1 -0
  13. package/packages/lsp-daemon/dist/ensure-daemon.js +18 -5
  14. package/packages/lsp-daemon/dist/index.js +34 -20
  15. package/packages/lsp-tools-mcp/dist/cli.js +1 -1
  16. package/packages/lsp-tools-mcp/dist/lsp/manager.js +1 -1
  17. package/packages/lsp-tools-mcp/dist/mcp.js +1 -1
  18. package/packages/lsp-tools-mcp/dist/tools.js +1 -1
  19. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  20. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +268 -92
  21. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  22. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  23. package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +7 -7
  24. package/packages/omo-codex/plugin/components/bootstrap/src/worker.ts +3 -0
  25. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +106 -6
  26. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +106 -6
  27. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  28. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  29. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  30. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  31. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  32. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  33. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  34. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
  35. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +56 -42
  36. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  37. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  38. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  39. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  40. package/packages/omo-codex/plugin/components/start-work-continuation/AGENTS.md +1 -0
  41. package/packages/omo-codex/plugin/components/start-work-continuation/README.md +5 -1
  42. package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +2 -1
  43. package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +18 -0
  44. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  45. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  46. package/packages/omo-codex/plugin/components/start-work-continuation/src/codex-hook.ts +21 -0
  47. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +105 -0
  48. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  49. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  50. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  51. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  52. package/packages/omo-codex/plugin/components/ultrawork/CHANGELOG.md +2 -0
  53. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +1 -1
  54. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
  55. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-qa-executor.toml +1 -1
  56. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +1 -1
  57. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-low.toml +1 -1
  58. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +1 -1
  59. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +2 -2
  60. package/packages/omo-codex/plugin/components/ultrawork/directive.md +3 -2
  61. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  62. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  63. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +3 -2
  64. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +1 -1
  65. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +3 -3
  66. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
  67. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +1 -1
  68. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +2 -0
  69. package/packages/omo-codex/plugin/components/ulw-loop/README.md +11 -11
  70. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +3 -2
  71. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +1 -1
  72. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +1 -1
  73. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +9 -9
  74. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +1 -1
  75. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +66 -66
  76. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +4 -4
  77. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.js +1 -1
  78. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +1 -1
  79. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +1 -1
  80. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +1 -1
  81. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +2 -2
  82. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  83. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  84. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +3 -3
  85. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +22 -25
  86. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +1 -1
  87. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +9 -9
  88. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-steering.ts +1 -1
  89. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +1 -1
  90. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +4 -4
  91. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +1 -1
  92. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +1 -1
  93. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +1 -1
  94. package/packages/omo-codex/plugin/components/ulw-loop/src/steering.ts +1 -1
  95. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +2 -2
  96. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-commands.test.ts +2 -2
  97. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +1 -1
  98. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-helpers.test.ts +2 -2
  99. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-kind-guidance.test.ts +1 -1
  100. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +2 -2
  101. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +1 -1
  102. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -5
  103. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io.test.ts +1 -1
  104. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +1 -1
  105. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +1 -1
  106. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  107. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  108. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  109. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  110. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  111. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  112. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  113. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  114. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  115. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  116. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  117. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  118. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  119. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  120. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  121. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  122. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  123. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  124. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  125. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  126. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  127. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  128. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  129. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  130. package/packages/omo-codex/plugin/package-lock.json +13 -13
  131. package/packages/omo-codex/plugin/package.json +1 -1
  132. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +4 -4
  133. package/packages/omo-codex/plugin/skills/ast-grep/SOURCE +1 -1
  134. package/packages/omo-codex/plugin/skills/ast-grep/install.ps1 +2 -2
  135. package/packages/omo-codex/plugin/skills/ast-grep/install.sh +1 -1
  136. package/packages/omo-codex/plugin/skills/ast-grep/references/install.md +2 -2
  137. package/packages/omo-codex/plugin/skills/ast-grep/tests/smoke.sh +1 -1
  138. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +54 -9
  139. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +2 -2
  140. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/__main__.py +8 -1
  141. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/bias_check.py +11 -0
  142. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/fetch_chain.py +90 -52
  143. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/result_schema.py +10 -1
  144. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/surrogate.py +214 -0
  145. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/surrogates.yaml +60 -0
  146. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/amp_redirect_stub.html +7 -0
  147. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/search_interstitial.html +19 -0
  148. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/wayback_available.json +1 -0
  149. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/wayback_snapshot.html +1128 -0
  150. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_surrogate.py +252 -0
  151. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_surrogate_validators.py +78 -0
  152. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/validators.py +46 -0
  153. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/waf_detector.py +1 -1
  154. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/waf_profiles.yaml +10 -5
  155. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/social.md +1 -1
  156. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  157. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +4 -4
  158. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/cache-archive.md +51 -50
  159. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/fallback.md +1 -1
  160. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/jina.md +8 -2
  161. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/naver.md +1 -1
  162. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/twitter.md +3 -3
  163. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +3 -2
  164. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +3 -3
  165. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +22 -25
  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 +3 -3
  168. package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
  169. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +15 -10
  170. package/packages/omo-codex/plugin/test/bootstrap-binlinks.test.mjs +12 -12
  171. package/packages/omo-codex/plugin/test/bootstrap-orchestration.test.mjs +36 -4
  172. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +1 -1
  173. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +4 -4
  174. package/packages/omo-codex/scripts/install-dist/install-local.mjs +115 -61
  175. package/packages/shared-skills/index.mjs +19 -1
  176. package/packages/shared-skills/skills/ast-grep/SOURCE +1 -1
  177. package/packages/shared-skills/skills/ast-grep/install.ps1 +2 -2
  178. package/packages/shared-skills/skills/ast-grep/install.sh +1 -1
  179. package/packages/shared-skills/skills/ast-grep/references/install.md +2 -2
  180. package/packages/shared-skills/skills/ast-grep/tests/smoke.sh +1 -1
  181. package/packages/shared-skills/skills/start-work/SKILL.md +54 -9
  182. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +2 -2
  183. package/packages/shared-skills/skills/ultimate-browsing/engine/__main__.py +8 -1
  184. package/packages/shared-skills/skills/ultimate-browsing/engine/bias_check.py +11 -0
  185. package/packages/shared-skills/skills/ultimate-browsing/engine/fetch_chain.py +90 -52
  186. package/packages/shared-skills/skills/ultimate-browsing/engine/result_schema.py +10 -1
  187. package/packages/shared-skills/skills/ultimate-browsing/engine/surrogate.py +214 -0
  188. package/packages/shared-skills/skills/ultimate-browsing/engine/surrogates.yaml +60 -0
  189. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/fixtures/amp_redirect_stub.html +7 -0
  190. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/fixtures/search_interstitial.html +19 -0
  191. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/fixtures/wayback_available.json +1 -0
  192. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/fixtures/wayback_snapshot.html +1128 -0
  193. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_surrogate.py +252 -0
  194. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_surrogate_validators.py +78 -0
  195. package/packages/shared-skills/skills/ultimate-browsing/engine/validators.py +46 -0
  196. package/packages/shared-skills/skills/ultimate-browsing/engine/waf_detector.py +1 -1
  197. package/packages/shared-skills/skills/ultimate-browsing/engine/waf_profiles.yaml +10 -5
  198. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/social.md +1 -1
  199. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  200. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +4 -4
  201. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/cache-archive.md +51 -50
  202. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/fallback.md +1 -1
  203. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/jina.md +8 -2
  204. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/naver.md +1 -1
  205. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/twitter.md +3 -3
  206. package/packages/shared-skills/skills/ulw-plan/SKILL.md +1 -1
  207. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +3 -3
  208. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
  209. package/packages/shared-skills/skills/ulw-research/SKILL.md +15 -10
@@ -70,6 +70,6 @@ node script/qa/web-terminal-visual-qa.mjs --title "Replay" \
70
70
  2. Store the output under `.omo/evidence/<YYYYMMDD>-<slug>/`.
71
71
  3. Review `terminal.txt` and `terminal-ansi.txt` for accidental secrets before citing them.
72
72
  4. Include `terminal.png`, `terminal.txt`, and `metadata.json` in the evidence summary.
73
- 5. Verify the cleanup receipt in `metadata.json`: no leftover pty, Chrome, PIDs, ports, or temp state.
73
+ 5. Review the cleanup receipt in `metadata.json`. It records the pty cleanup action and browser closure attempt; it does not audit ports, temporary state, or all leftover processes.
74
74
 
75
75
  Tests alone are not TUI visual QA. The passing artifact is the xterm.js-rendered `terminal.png` plus a binary observation - expected text present, colors correct, no overflow, no border or CJK-width misalignment.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lazycodex-ai",
3
- "version": "4.19.4",
3
+ "version": "5.0.0-beta.2",
4
4
  "description": "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
5
5
  "main": "./dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -8,6 +8,7 @@
8
8
  "workspaces": [
9
9
  "packages/rules-engine",
10
10
  "packages/delegate-core",
11
+ "packages/ast-grep-mcp",
11
12
  "packages/git-bash-mcp",
12
13
  "packages/mcp-stdio-core",
13
14
  "packages/mcp-client-core",
@@ -22,6 +23,7 @@
22
23
  "packages/team-core",
23
24
  "packages/openclaw-core",
24
25
  "packages/boulder-state",
26
+ "packages/memory-core",
25
27
  "packages/telemetry-core",
26
28
  "packages/claude-code-compat-core",
27
29
  "packages/skills-loader-core",
@@ -32,7 +34,8 @@
32
34
  "packages/senpi-task",
33
35
  "packages/pi-goal",
34
36
  "packages/pi-webfetch",
35
- "packages/omo-opencode"
37
+ "packages/omo-opencode",
38
+ "packages/omo-native"
36
39
  ],
37
40
  "bin": {
38
41
  "lazycodex-ai": "packages/omo-codex/scripts/install-local.mjs",
@@ -4,8 +4,8 @@
4
4
  import { argv, stderr } from "node:process";
5
5
 
6
6
  // src/proxy.ts
7
- import { existsSync as existsSync11, realpathSync as realpathSync4 } from "node:fs";
8
- import { basename as basename3, delimiter as delimiter4, dirname as dirname9, isAbsolute as isAbsolute4 } from "node:path";
7
+ import { existsSync as existsSync12, realpathSync as realpathSync4 } from "node:fs";
8
+ import { basename as basename3, delimiter as delimiter4, dirname as dirname9, isAbsolute as isAbsolute5 } from "node:path";
9
9
 
10
10
  // ../mcp-stdio-core/src/record.ts
11
11
  function isPlainRecord(value) {
@@ -1417,7 +1417,7 @@ class LspClientConnection extends LspClientTransport {
1417
1417
  initializationOptions: this.server.initialization
1418
1418
  }, { timeoutMs: this.initializeTimeoutMs });
1419
1419
  this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
1420
- await this.sendNotification("initialized");
1420
+ await this.sendNotification("initialized", {});
1421
1421
  await this.sendNotification("workspace/didChangeConfiguration", {
1422
1422
  settings: { json: { validate: { enable: true } } }
1423
1423
  });
@@ -5192,10 +5192,10 @@ function errorText(error) {
5192
5192
 
5193
5193
  // src/ensure-daemon.ts
5194
5194
  import { spawn as spawn2 } from "node:child_process";
5195
- import { closeSync as closeSync2, mkdirSync as mkdirSync3, openSync as openSync2 } from "node:fs";
5195
+ import { closeSync as closeSync2, existsSync as existsSync11, mkdirSync as mkdirSync3, openSync as openSync2, writeSync as writeSync2 } from "node:fs";
5196
5196
  import { Socket } from "node:net";
5197
- import { dirname as dirname8 } from "node:path";
5198
- import { execPath } from "node:process";
5197
+ import { dirname as dirname8, isAbsolute as isAbsolute4 } from "node:path";
5198
+ import { argv0, execPath } from "node:process";
5199
5199
 
5200
5200
  // src/ipc-protocol.ts
5201
5201
  import { randomBytes, timingSafeEqual } from "node:crypto";
@@ -5665,15 +5665,29 @@ function spawnDaemonProcess(paths) {
5665
5665
  mkdirSync3(dirname8(paths.log), { recursive: true });
5666
5666
  const logFd = openSync2(paths.log, "a");
5667
5667
  try {
5668
- const child = spawn2(execPath, [paths.cliPath, "daemon"], {
5668
+ const child = spawn2(resolveDaemonNodeExecutable(), [paths.cliPath, "daemon"], {
5669
5669
  detached: true,
5670
5670
  stdio: ["ignore", logFd, logFd]
5671
5671
  });
5672
+ child.once("spawn", () => closeSync2(logFd));
5673
+ child.once("error", (error) => {
5674
+ writeSync2(logFd, `[lsp-daemon] failed to spawn daemon: ${error.message}
5675
+ `);
5676
+ closeSync2(logFd);
5677
+ });
5672
5678
  child.unref();
5673
- } finally {
5679
+ } catch (error) {
5674
5680
  closeSync2(logFd);
5681
+ throw error;
5675
5682
  }
5676
5683
  }
5684
+ function resolveDaemonNodeExecutable(cachedExecPath = execPath, originalArgv0 = argv0, pathExists = existsSync11) {
5685
+ if (pathExists(cachedExecPath))
5686
+ return cachedExecPath;
5687
+ if (isAbsolute4(originalArgv0) && pathExists(originalArgv0))
5688
+ return originalArgv0;
5689
+ return "node";
5690
+ }
5677
5691
  function defaultEnsureDaemonDeps() {
5678
5692
  return {
5679
5693
  probe: (paths, signal) => probeDaemon(paths, PROBE_TIMEOUT_MS, signal),
@@ -6144,7 +6158,7 @@ function canonicalizePathList(value) {
6144
6158
  return value.split(delimiter4).map((entry) => canonicalizePath(entry) ?? entry).join(delimiter4);
6145
6159
  }
6146
6160
  function canonicalizePath(value) {
6147
- if (value === undefined || !isAbsolute4(value) || !existsSync11(value))
6161
+ if (value === undefined || !isAbsolute5(value) || !existsSync12(value))
6148
6162
  return value;
6149
6163
  return realpathSync4(value);
6150
6164
  }
@@ -6164,11 +6178,11 @@ import { createServer as createServer2 } from "node:net";
6164
6178
 
6165
6179
  // src/ownership.ts
6166
6180
  import { randomUUID } from "node:crypto";
6167
- import { existsSync as existsSync12, lstatSync as lstatSync7, readFileSync as readFileSync7, statSync as statSync5, unlinkSync as unlinkSync3 } from "node:fs";
6181
+ import { existsSync as existsSync13, lstatSync as lstatSync7, readFileSync as readFileSync7, statSync as statSync5, unlinkSync as unlinkSync3 } from "node:fs";
6168
6182
  import { dirname as dirname11 } from "node:path";
6169
6183
 
6170
6184
  // src/lock.ts
6171
- import { closeSync as closeSync3, mkdirSync as mkdirSync4, openSync as openSync3, readFileSync as readFileSync6, unlinkSync as unlinkSync2, writeSync as writeSync2 } from "node:fs";
6185
+ import { closeSync as closeSync3, mkdirSync as mkdirSync4, openSync as openSync3, readFileSync as readFileSync6, unlinkSync as unlinkSync2, writeSync as writeSync3 } from "node:fs";
6172
6186
  import { dirname as dirname10 } from "node:path";
6173
6187
  function isProcessAlive2(pid) {
6174
6188
  if (!Number.isInteger(pid) || pid <= 0)
@@ -6204,7 +6218,7 @@ function tryAcquireLock(lockPath, ownerPid = process.pid) {
6204
6218
  function writeLockFile(lockPath, ownerPid) {
6205
6219
  try {
6206
6220
  const fd = openSync3(lockPath, "wx", 384);
6207
- writeSync2(fd, `${ownerPid}
6221
+ writeSync3(fd, `${ownerPid}
6208
6222
  `);
6209
6223
  closeSync3(fd);
6210
6224
  return { release: () => unlinkQuietly(lockPath) };
@@ -6352,7 +6366,7 @@ async function validateExistingOwner(paths, pingOwner) {
6352
6366
  throw new DaemonStartupDeferredError("reachable_owner_mismatch");
6353
6367
  }
6354
6368
  function cleanupDeadOwner(paths, owner) {
6355
- if (process.platform !== "win32" && existsSync12(owner.endpoint.path)) {
6369
+ if (process.platform !== "win32" && existsSync13(owner.endpoint.path)) {
6356
6370
  const stat = lstatSync7(owner.endpoint.path);
6357
6371
  if (stat.isSocket())
6358
6372
  unlinkSync3(owner.endpoint.path);
@@ -254,10 +254,10 @@ function errorText(error) {
254
254
 
255
255
  // src/ensure-daemon.ts
256
256
  import { spawn } from "node:child_process";
257
- import { closeSync as closeSync2, mkdirSync as mkdirSync2, openSync as openSync2 } from "node:fs";
257
+ import { closeSync as closeSync2, existsSync as existsSync2, mkdirSync as mkdirSync2, openSync as openSync2, writeSync as writeSync2 } from "node:fs";
258
258
  import { Socket } from "node:net";
259
- import { dirname as dirname3 } from "node:path";
260
- import { execPath } from "node:process";
259
+ import { dirname as dirname3, isAbsolute as isAbsolute3 } from "node:path";
260
+ import { argv0, execPath } from "node:process";
261
261
 
262
262
  // src/ipc-protocol.ts
263
263
  import { randomBytes, timingSafeEqual } from "node:crypto";
@@ -727,15 +727,29 @@ function spawnDaemonProcess(paths) {
727
727
  mkdirSync2(dirname3(paths.log), { recursive: true });
728
728
  const logFd = openSync2(paths.log, "a");
729
729
  try {
730
- const child = spawn(execPath, [paths.cliPath, "daemon"], {
730
+ const child = spawn(resolveDaemonNodeExecutable(), [paths.cliPath, "daemon"], {
731
731
  detached: true,
732
732
  stdio: ["ignore", logFd, logFd]
733
733
  });
734
+ child.once("spawn", () => closeSync2(logFd));
735
+ child.once("error", (error) => {
736
+ writeSync2(logFd, `[lsp-daemon] failed to spawn daemon: ${error.message}
737
+ `);
738
+ closeSync2(logFd);
739
+ });
734
740
  child.unref();
735
- } finally {
741
+ } catch (error) {
736
742
  closeSync2(logFd);
743
+ throw error;
737
744
  }
738
745
  }
746
+ function resolveDaemonNodeExecutable(cachedExecPath = execPath, originalArgv0 = argv0, pathExists = existsSync2) {
747
+ if (pathExists(cachedExecPath))
748
+ return cachedExecPath;
749
+ if (isAbsolute3(originalArgv0) && pathExists(originalArgv0))
750
+ return originalArgv0;
751
+ return "node";
752
+ }
739
753
  function defaultEnsureDaemonDeps() {
740
754
  return {
741
755
  probe: (paths, signal) => probeDaemon(paths, PROBE_TIMEOUT_MS, signal),
@@ -1127,7 +1141,7 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
1127
1141
  };
1128
1142
  }
1129
1143
  // ../lsp-core/src/lsp/client-wrapper.ts
1130
- import { existsSync as existsSync9, statSync as statSync4 } from "node:fs";
1144
+ import { existsSync as existsSync10, statSync as statSync4 } from "node:fs";
1131
1145
  import { dirname as dirname8, join as join4, resolve as resolve7 } from "node:path";
1132
1146
 
1133
1147
  // ../lsp-core/src/lsp/effective-extension.ts
@@ -1559,7 +1573,7 @@ function toError(error) {
1559
1573
 
1560
1574
  // ../lsp-core/src/lsp/process.ts
1561
1575
  import { spawn as spawn2, spawnSync } from "node:child_process";
1562
- import { existsSync as existsSync2, statSync as statSync3 } from "node:fs";
1576
+ import { existsSync as existsSync3, statSync as statSync3 } from "node:fs";
1563
1577
  import { delimiter as delimiter2, join as join2 } from "node:path";
1564
1578
  function isMissingProcessError(error) {
1565
1579
  if (!(error instanceof Error) || !("code" in error))
@@ -1573,7 +1587,7 @@ function reportKillError(context, error) {
1573
1587
  }
1574
1588
  function validateCwd(cwd) {
1575
1589
  try {
1576
- if (!existsSync2(cwd)) {
1590
+ if (!existsSync3(cwd)) {
1577
1591
  return { valid: false, error: `Working directory does not exist: ${cwd}` };
1578
1592
  }
1579
1593
  const stats = statSync3(cwd);
@@ -1661,7 +1675,7 @@ function resolveWindowsCommand(command, env) {
1661
1675
  for (const baseDirectory of baseDirectories) {
1662
1676
  for (const extension of extensions) {
1663
1677
  const candidate = baseDirectory ? join2(baseDirectory, `${command}${extension}`) : `${command}${extension}`;
1664
- if (existsSync2(candidate))
1678
+ if (existsSync3(candidate))
1665
1679
  return candidate;
1666
1680
  }
1667
1681
  }
@@ -2060,7 +2074,7 @@ class LspClientConnection extends LspClientTransport {
2060
2074
  initializationOptions: this.server.initialization
2061
2075
  }, { timeoutMs: this.initializeTimeoutMs });
2062
2076
  this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
2063
- await this.sendNotification("initialized");
2077
+ await this.sendNotification("initialized", {});
2064
2078
  await this.sendNotification("workspace/didChangeConfiguration", {
2065
2079
  settings: { json: { validate: { enable: true } } }
2066
2080
  });
@@ -2530,11 +2544,11 @@ function workspaceApplyEditConcurrentFailureReason(phase) {
2530
2544
  }
2531
2545
 
2532
2546
  // ../lsp-core/src/lsp/workspace-edit-commit.ts
2533
- import { existsSync as existsSync4, lstatSync as lstatSync3, renameSync, rmSync, writeFileSync } from "node:fs";
2547
+ import { existsSync as existsSync5, lstatSync as lstatSync3, renameSync, rmSync, writeFileSync } from "node:fs";
2534
2548
 
2535
2549
  // ../lsp-core/src/lsp/workspace-edit-path.ts
2536
- import { existsSync as existsSync3, lstatSync as lstatSync2, readFileSync as readFileSync3, readdirSync, realpathSync as realpathSync3 } from "node:fs";
2537
- import { dirname as dirname4, isAbsolute as isAbsolute3, relative as relative3, resolve as resolve3 } from "node:path";
2550
+ import { existsSync as existsSync4, lstatSync as lstatSync2, readFileSync as readFileSync3, readdirSync, realpathSync as realpathSync3 } from "node:fs";
2551
+ import { dirname as dirname4, isAbsolute as isAbsolute4, relative as relative3, resolve as resolve3 } from "node:path";
2538
2552
  import { fileURLToPath as fileURLToPath2 } from "node:url";
2539
2553
 
2540
2554
  class WorkspaceEditPathError extends Error {
@@ -2549,11 +2563,11 @@ class WorkspaceEditPathError extends Error {
2549
2563
  }
2550
2564
  function isPathInsideWorkspace(filePath, workspaceRoot) {
2551
2565
  const relativePath = relative3(workspaceRoot, filePath);
2552
- return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute3(relativePath);
2566
+ return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute4(relativePath);
2553
2567
  }
2554
2568
  function canonicalizeMissingPath(filePath) {
2555
2569
  let ancestor = filePath;
2556
- while (!existsSync3(ancestor)) {
2570
+ while (!existsSync4(ancestor)) {
2557
2571
  const parent = dirname4(ancestor);
2558
2572
  if (parent === ancestor)
2559
2573
  throw new WorkspaceEditPathError(filePath, "no existing ancestor");
@@ -2571,7 +2585,7 @@ function canonicalWorkspaceRoot(workspaceRoot) {
2571
2585
  success: true,
2572
2586
  path: canonical,
2573
2587
  requestedPath: resolve3(workspaceRoot),
2574
- followedSymbolicLink: existsSync3(resolve3(workspaceRoot)) && lstatSync2(resolve3(workspaceRoot)).isSymbolicLink()
2588
+ followedSymbolicLink: existsSync4(resolve3(workspaceRoot)) && lstatSync2(resolve3(workspaceRoot)).isSymbolicLink()
2575
2589
  };
2576
2590
  } catch (error) {
2577
2591
  const detail = error instanceof Error ? error.message : String(error);
@@ -2591,7 +2605,7 @@ function uriToCanonicalWorkspacePath(uri, workspaceRoot) {
2591
2605
  return { success: false, error: `non-file URI ${uri}: ${detail}` };
2592
2606
  }
2593
2607
  try {
2594
- const canonical = existsSync3(requestedPath) ? realpathSync3(requestedPath) : canonicalizeMissingPath(requestedPath);
2608
+ const canonical = existsSync4(requestedPath) ? realpathSync3(requestedPath) : canonicalizeMissingPath(requestedPath);
2595
2609
  if (!isPathInsideWorkspace(canonical, workspaceRoot)) {
2596
2610
  return { success: false, error: `${requestedPath}: outside workspace ${workspaceRoot}` };
2597
2611
  }
@@ -2599,7 +2613,7 @@ function uriToCanonicalWorkspacePath(uri, workspaceRoot) {
2599
2613
  success: true,
2600
2614
  path: canonical,
2601
2615
  requestedPath,
2602
- followedSymbolicLink: existsSync3(requestedPath) && lstatSync2(requestedPath).isSymbolicLink()
2616
+ followedSymbolicLink: existsSync4(requestedPath) && lstatSync2(requestedPath).isSymbolicLink()
2603
2617
  };
2604
2618
  } catch (error) {
2605
2619
  const detail = error instanceof Error ? error.message : String(error);
@@ -2607,7 +2621,7 @@ function uriToCanonicalWorkspacePath(uri, workspaceRoot) {
2607
2621
  }
2608
2622
  }
2609
2623
  function snapshotPath(path2, includeChildren) {
2610
- if (!existsSync3(path2))
2624
+ if (!existsSync4(path2))
2611
2625
  return { kind: "missing" };
2612
2626
  const stats = lstatSync2(path2);
2613
2627
  if (stats.isFile())
@@ -2727,7 +2741,7 @@ function commitOperation(context, operation) {
2727
2741
  }
2728
2742
  if (operation.kind === "rename") {
2729
2743
  if (operation.replaceDestination) {
2730
- const targetKind = existsSync4(operation.newPath) && lstatSync3(operation.newPath).isDirectory() ? "directory" : "file";
2744
+ const targetKind = existsSync5(operation.newPath) && lstatSync3(operation.newPath).isDirectory() ? "directory" : "file";
2731
2745
  io.remove(operation.newPath, targetKind === "directory");
2732
2746
  accumulator.mutations.push({ kind: "delete", path: operation.newPath, targetKind });
2733
2747
  addModifiedPath(accumulator.filesModified, reportedPath(plan, operation.newPath));
@@ -3337,7 +3351,7 @@ function simulateDelete(operation, virtual) {
3337
3351
  }
3338
3352
 
3339
3353
  // ../lsp-core/src/lsp/workspace-edit-snapshot.ts
3340
- import { existsSync as existsSync5, lstatSync as lstatSync4, readdirSync as readdirSync2 } from "node:fs";
3354
+ import { existsSync as existsSync6, lstatSync as lstatSync4, readdirSync as readdirSync2 } from "node:fs";
3341
3355
  import { dirname as dirname6, resolve as resolve5 } from "node:path";
3342
3356
  class WorkspaceSnapshotBuilder {
3343
3357
  workspaceRoot;
@@ -3375,7 +3389,7 @@ class WorkspaceSnapshotBuilder {
3375
3389
  break;
3376
3390
  candidate = dirname6(candidate);
3377
3391
  }
3378
- if (!includeChildren || !existsSync5(path2) || !lstatSync4(path2).isDirectory())
3392
+ if (!includeChildren || !existsSync6(path2) || !lstatSync4(path2).isDirectory())
3379
3393
  return;
3380
3394
  for (const child of readdirSync2(path2))
3381
3395
  this.add(resolve5(path2, child), true);
@@ -4144,14 +4158,14 @@ async function disposeDefaultLspManager() {
4144
4158
  }
4145
4159
 
4146
4160
  // ../lsp-core/src/lsp/server-install-state.ts
4147
- import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
4161
+ import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
4148
4162
  import { dirname as dirname7 } from "node:path";
4149
4163
  function getInstallDecisionsPath() {
4150
4164
  return lspRequestContext().installDecisionsPath;
4151
4165
  }
4152
4166
  function loadInstallDecisions() {
4153
4167
  const path2 = getInstallDecisionsPath();
4154
- if (!existsSync6(path2))
4168
+ if (!existsSync7(path2))
4155
4169
  return {};
4156
4170
  try {
4157
4171
  const parsed = JSON.parse(readFileSync4(path2, "utf8"));
@@ -4192,7 +4206,7 @@ function isRecord5(value) {
4192
4206
  }
4193
4207
 
4194
4208
  // ../lsp-core/src/lsp/config-loader.ts
4195
- import { existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
4209
+ import { existsSync as existsSync8, readFileSync as readFileSync5 } from "node:fs";
4196
4210
 
4197
4211
  // ../lsp-core/src/lsp/server-definitions.ts
4198
4212
  var LSP_INSTALL_HINTS = {
@@ -4349,7 +4363,7 @@ function getUserConfigPath() {
4349
4363
  return lspRequestContext().userConfigPath;
4350
4364
  }
4351
4365
  function loadJsonFile(path2) {
4352
- if (!existsSync7(path2))
4366
+ if (!existsSync8(path2))
4353
4367
  return null;
4354
4368
  try {
4355
4369
  const parsed = JSON.parse(readFileSync5(path2, "utf-8"));
@@ -4537,7 +4551,7 @@ function getDisabledServerIds() {
4537
4551
  }
4538
4552
 
4539
4553
  // ../lsp-core/src/lsp/server-installation.ts
4540
- import { existsSync as existsSync8 } from "node:fs";
4554
+ import { existsSync as existsSync9 } from "node:fs";
4541
4555
  import { delimiter as delimiter3, join as join3 } from "node:path";
4542
4556
  function isServerInstalled(command, _workingDirectory) {
4543
4557
  if (command.length === 0)
@@ -4546,7 +4560,7 @@ function isServerInstalled(command, _workingDirectory) {
4546
4560
  if (!cmd)
4547
4561
  return false;
4548
4562
  if (cmd.includes("/") || cmd.includes("\\")) {
4549
- if (existsSync8(cmd))
4563
+ if (existsSync9(cmd))
4550
4564
  return true;
4551
4565
  }
4552
4566
  const isWindows = process.platform === "win32";
@@ -4567,7 +4581,7 @@ function isServerInstalled(command, _workingDirectory) {
4567
4581
  const paths = pathEnv.split(delimiter3);
4568
4582
  for (const p of paths) {
4569
4583
  for (const suffix of exts) {
4570
- if (existsSync8(join3(p, cmd + suffix))) {
4584
+ if (existsSync9(join3(p, cmd + suffix))) {
4571
4585
  return true;
4572
4586
  }
4573
4587
  }
@@ -4680,7 +4694,7 @@ function findWorkspaceRoot(filePath) {
4680
4694
  let prevDir = "";
4681
4695
  while (dir !== prevDir) {
4682
4696
  for (const marker of WORKSPACE_MARKERS) {
4683
- if (existsSync9(join4(dir, marker))) {
4697
+ if (existsSync10(join4(dir, marker))) {
4684
4698
  return dir;
4685
4699
  }
4686
4700
  }
@@ -4812,7 +4826,7 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4812
4826
  }
4813
4827
 
4814
4828
  // ../lsp-core/src/lsp/directory-diagnostics.ts
4815
- import { existsSync as existsSync10, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
4829
+ import { existsSync as existsSync11, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
4816
4830
  import { join as join5, resolve as resolve8 } from "node:path";
4817
4831
 
4818
4832
  // ../lsp-core/src/lsp/formatters.ts
@@ -4969,7 +4983,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4969
4983
  throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
4970
4984
  }
4971
4985
  const absDir = resolve8(options.workspaceRoot ?? contextCwd(), directory);
4972
- if (!existsSync10(absDir)) {
4986
+ if (!existsSync11(absDir)) {
4973
4987
  throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
4974
4988
  }
4975
4989
  const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
@@ -6014,7 +6028,7 @@ function isRetryableTool(name) {
6014
6028
 
6015
6029
  // src/client.ts
6016
6030
  import { statSync as statSync5 } from "node:fs";
6017
- import { isAbsolute as isAbsolute4 } from "node:path";
6031
+ import { isAbsolute as isAbsolute5 } from "node:path";
6018
6032
  var OMO_LSP_DAEMON_DIR2 = "OMO_LSP_DAEMON_DIR";
6019
6033
  var OMO_LSP_DAEMON_CLI2 = "OMO_LSP_DAEMON_CLI";
6020
6034
  var OMO_LSP_DAEMON_VERSION2 = "OMO_LSP_DAEMON_VERSION";
@@ -6044,12 +6058,12 @@ function resolveDaemonRuntime2(env, defaults) {
6044
6058
  throw new InvalidRuntimeOverrideError2("paired_values_required", `${OMO_LSP_DAEMON_CLI2} and ${OMO_LSP_DAEMON_VERSION2} must be set together`);
6045
6059
  }
6046
6060
  if (!hasCliOverride || !hasVersionOverride) {
6047
- if (!isAbsolute4(defaults.cliPath)) {
6061
+ if (!isAbsolute5(defaults.cliPath)) {
6048
6062
  throw new InvalidRuntimeOverrideError2("packaged_cli_must_be_absolute", "Packaged LSP daemon CLI path must be absolute");
6049
6063
  }
6050
6064
  return { cliPath: defaults.cliPath, version: validateDaemonVersion2(defaults.version) };
6051
6065
  }
6052
- if (!isAbsolute4(cliOverride)) {
6066
+ if (!isAbsolute5(cliOverride)) {
6053
6067
  throw new InvalidRuntimeOverrideError2("cli_must_be_absolute", `${OMO_LSP_DAEMON_CLI2} must be an absolute path to an existing regular file`);
6054
6068
  }
6055
6069
  const stat = statSync5(cliOverride, { throwIfNoEntry: false });
@@ -20,5 +20,6 @@ export declare function ensureDaemonRunning(paths: DaemonPaths, deps?: EnsureDae
20
20
  export declare function probeDaemon(paths: DaemonPaths, timeoutMs?: number, signal?: AbortSignal): Promise<boolean>;
21
21
  export declare function pingDaemon(paths: DaemonPaths, token: string, timeoutMs?: number, signal?: AbortSignal): Promise<OwnerPing | null>;
22
22
  export declare function spawnDaemonProcess(paths: DaemonPaths): void;
23
+ export declare function resolveDaemonNodeExecutable(cachedExecPath?: string, originalArgv0?: string, pathExists?: (path: string) => boolean): string;
23
24
  export declare function resolveDaemonCliPath(env?: NodeJS.ProcessEnv, defaults?: DaemonRuntimeDefaults): string;
24
25
  export declare function defaultEnsureDaemonDeps(): EnsureDaemonDeps;
@@ -1,8 +1,8 @@
1
1
  import { spawn } from "node:child_process";
2
- import { closeSync, mkdirSync, openSync } from "node:fs";
2
+ import { closeSync, existsSync, mkdirSync, openSync, writeSync } from "node:fs";
3
3
  import { Socket } from "node:net";
4
- import { dirname } from "node:path";
5
- import { execPath } from "node:process";
4
+ import { dirname, isAbsolute } from "node:path";
5
+ import { argv0, execPath } from "node:process";
6
6
  import { authEnvelope, readAuthToken } from "./ipc-protocol.js";
7
7
  import { packagedRuntimeDefaults } from "./paths.js";
8
8
  import { resolveDaemonRuntime } from "./runtime-contract.js";
@@ -85,16 +85,29 @@ export function spawnDaemonProcess(paths) {
85
85
  mkdirSync(dirname(paths.log), { recursive: true });
86
86
  const logFd = openSync(paths.log, "a");
87
87
  try {
88
- const child = spawn(execPath, [paths.cliPath, "daemon"], {
88
+ const child = spawn(resolveDaemonNodeExecutable(), [paths.cliPath, "daemon"], {
89
89
  detached: true,
90
90
  stdio: ["ignore", logFd, logFd],
91
91
  });
92
+ child.once("spawn", () => closeSync(logFd));
93
+ child.once("error", (error) => {
94
+ writeSync(logFd, `[lsp-daemon] failed to spawn daemon: ${error.message}\n`);
95
+ closeSync(logFd);
96
+ });
92
97
  child.unref();
93
98
  }
94
- finally {
99
+ catch (error) {
95
100
  closeSync(logFd);
101
+ throw error;
96
102
  }
97
103
  }
104
+ export function resolveDaemonNodeExecutable(cachedExecPath = execPath, originalArgv0 = argv0, pathExists = existsSync) {
105
+ if (pathExists(cachedExecPath))
106
+ return cachedExecPath;
107
+ if (isAbsolute(originalArgv0) && pathExists(originalArgv0))
108
+ return originalArgv0;
109
+ return "node";
110
+ }
98
111
  export function resolveDaemonCliPath(env = process.env, defaults = packagedRuntimeDefaults()) {
99
112
  return resolveDaemonRuntime(env, defaults).cliPath;
100
113
  }
@@ -918,7 +918,7 @@ class LspClientConnection extends LspClientTransport {
918
918
  initializationOptions: this.server.initialization
919
919
  }, { timeoutMs: this.initializeTimeoutMs });
920
920
  this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
921
- await this.sendNotification("initialized");
921
+ await this.sendNotification("initialized", {});
922
922
  await this.sendNotification("workspace/didChangeConfiguration", {
923
923
  settings: { json: { validate: { enable: true } } }
924
924
  });
@@ -3266,10 +3266,10 @@ function errorText(error) {
3266
3266
 
3267
3267
  // src/ensure-daemon.ts
3268
3268
  import { spawn as spawn2 } from "node:child_process";
3269
- import { closeSync as closeSync2, mkdirSync as mkdirSync2, openSync as openSync2 } from "node:fs";
3269
+ import { closeSync as closeSync2, existsSync as existsSync6, mkdirSync as mkdirSync2, openSync as openSync2, writeSync as writeSync2 } from "node:fs";
3270
3270
  import { Socket } from "node:net";
3271
- import { dirname as dirname6 } from "node:path";
3272
- import { execPath } from "node:process";
3271
+ import { dirname as dirname6, isAbsolute as isAbsolute4 } from "node:path";
3272
+ import { argv0, execPath } from "node:process";
3273
3273
 
3274
3274
  // src/ipc-protocol.ts
3275
3275
  import { randomBytes, timingSafeEqual } from "node:crypto";
@@ -3739,15 +3739,29 @@ function spawnDaemonProcess(paths) {
3739
3739
  mkdirSync2(dirname6(paths.log), { recursive: true });
3740
3740
  const logFd = openSync2(paths.log, "a");
3741
3741
  try {
3742
- const child = spawn2(execPath, [paths.cliPath, "daemon"], {
3742
+ const child = spawn2(resolveDaemonNodeExecutable(), [paths.cliPath, "daemon"], {
3743
3743
  detached: true,
3744
3744
  stdio: ["ignore", logFd, logFd]
3745
3745
  });
3746
+ child.once("spawn", () => closeSync2(logFd));
3747
+ child.once("error", (error) => {
3748
+ writeSync2(logFd, `[lsp-daemon] failed to spawn daemon: ${error.message}
3749
+ `);
3750
+ closeSync2(logFd);
3751
+ });
3746
3752
  child.unref();
3747
- } finally {
3753
+ } catch (error) {
3748
3754
  closeSync2(logFd);
3755
+ throw error;
3749
3756
  }
3750
3757
  }
3758
+ function resolveDaemonNodeExecutable(cachedExecPath = execPath, originalArgv0 = argv0, pathExists = existsSync6) {
3759
+ if (pathExists(cachedExecPath))
3760
+ return cachedExecPath;
3761
+ if (isAbsolute4(originalArgv0) && pathExists(originalArgv0))
3762
+ return originalArgv0;
3763
+ return "node";
3764
+ }
3751
3765
  function defaultEnsureDaemonDeps() {
3752
3766
  return {
3753
3767
  probe: (paths, signal) => probeDaemon(paths, PROBE_TIMEOUT_MS, signal),
@@ -4139,18 +4153,18 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
4139
4153
  };
4140
4154
  }
4141
4155
  // ../lsp-core/src/lsp/client-wrapper.ts
4142
- import { existsSync as existsSync9, statSync as statSync4 } from "node:fs";
4156
+ import { existsSync as existsSync10, statSync as statSync4 } from "node:fs";
4143
4157
  import { dirname as dirname8, join as join4, resolve as resolve7 } from "node:path";
4144
4158
 
4145
4159
  // ../lsp-core/src/lsp/server-install-state.ts
4146
- import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
4160
+ import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
4147
4161
  import { dirname as dirname7 } from "node:path";
4148
4162
  function getInstallDecisionsPath() {
4149
4163
  return lspRequestContext().installDecisionsPath;
4150
4164
  }
4151
4165
  function loadInstallDecisions() {
4152
4166
  const path2 = getInstallDecisionsPath();
4153
- if (!existsSync6(path2))
4167
+ if (!existsSync7(path2))
4154
4168
  return {};
4155
4169
  try {
4156
4170
  const parsed = JSON.parse(readFileSync4(path2, "utf8"));
@@ -4191,7 +4205,7 @@ function isRecord5(value) {
4191
4205
  }
4192
4206
 
4193
4207
  // ../lsp-core/src/lsp/config-loader.ts
4194
- import { existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
4208
+ import { existsSync as existsSync8, readFileSync as readFileSync5 } from "node:fs";
4195
4209
 
4196
4210
  // ../lsp-core/src/lsp/server-definitions.ts
4197
4211
  var LSP_INSTALL_HINTS = {
@@ -4348,7 +4362,7 @@ function getUserConfigPath() {
4348
4362
  return lspRequestContext().userConfigPath;
4349
4363
  }
4350
4364
  function loadJsonFile(path2) {
4351
- if (!existsSync7(path2))
4365
+ if (!existsSync8(path2))
4352
4366
  return null;
4353
4367
  try {
4354
4368
  const parsed = JSON.parse(readFileSync5(path2, "utf-8"));
@@ -4536,7 +4550,7 @@ function getDisabledServerIds() {
4536
4550
  }
4537
4551
 
4538
4552
  // ../lsp-core/src/lsp/server-installation.ts
4539
- import { existsSync as existsSync8 } from "node:fs";
4553
+ import { existsSync as existsSync9 } from "node:fs";
4540
4554
  import { delimiter as delimiter3, join as join3 } from "node:path";
4541
4555
  function isServerInstalled(command, _workingDirectory) {
4542
4556
  if (command.length === 0)
@@ -4545,7 +4559,7 @@ function isServerInstalled(command, _workingDirectory) {
4545
4559
  if (!cmd)
4546
4560
  return false;
4547
4561
  if (cmd.includes("/") || cmd.includes("\\")) {
4548
- if (existsSync8(cmd))
4562
+ if (existsSync9(cmd))
4549
4563
  return true;
4550
4564
  }
4551
4565
  const isWindows = process.platform === "win32";
@@ -4566,7 +4580,7 @@ function isServerInstalled(command, _workingDirectory) {
4566
4580
  const paths = pathEnv.split(delimiter3);
4567
4581
  for (const p of paths) {
4568
4582
  for (const suffix of exts) {
4569
- if (existsSync8(join3(p, cmd + suffix))) {
4583
+ if (existsSync9(join3(p, cmd + suffix))) {
4570
4584
  return true;
4571
4585
  }
4572
4586
  }
@@ -4679,7 +4693,7 @@ function findWorkspaceRoot(filePath) {
4679
4693
  let prevDir = "";
4680
4694
  while (dir !== prevDir) {
4681
4695
  for (const marker of WORKSPACE_MARKERS) {
4682
- if (existsSync9(join4(dir, marker))) {
4696
+ if (existsSync10(join4(dir, marker))) {
4683
4697
  return dir;
4684
4698
  }
4685
4699
  }
@@ -4811,7 +4825,7 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4811
4825
  }
4812
4826
 
4813
4827
  // ../lsp-core/src/lsp/directory-diagnostics.ts
4814
- import { existsSync as existsSync10, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
4828
+ import { existsSync as existsSync11, lstatSync as lstatSync5, readdirSync as readdirSync3 } from "node:fs";
4815
4829
  import { join as join5, resolve as resolve8 } from "node:path";
4816
4830
 
4817
4831
  // ../lsp-core/src/lsp/formatters.ts
@@ -4968,7 +4982,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4968
4982
  throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
4969
4983
  }
4970
4984
  const absDir = resolve8(options.workspaceRoot ?? contextCwd(), directory);
4971
- if (!existsSync10(absDir)) {
4985
+ if (!existsSync11(absDir)) {
4972
4986
  throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
4973
4987
  }
4974
4988
  const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found", server: options.server };
@@ -6011,8 +6025,8 @@ function isRetryableTool(name) {
6011
6025
  return name !== "rename" && name !== "lsp_rename";
6012
6026
  }
6013
6027
  // src/proxy.ts
6014
- import { existsSync as existsSync11, realpathSync as realpathSync4 } from "node:fs";
6015
- import { basename as basename3, delimiter as delimiter4, dirname as dirname9, isAbsolute as isAbsolute4 } from "node:path";
6028
+ import { existsSync as existsSync12, realpathSync as realpathSync4 } from "node:fs";
6029
+ import { basename as basename3, delimiter as delimiter4, dirname as dirname9, isAbsolute as isAbsolute5 } from "node:path";
6016
6030
  var DEFAULT_STARTUP_TIMEOUT_MS = 1e4;
6017
6031
  async function runMcpStdioProxy(options = {}) {
6018
6032
  const input = options.input ?? process.stdin;
@@ -6135,7 +6149,7 @@ function canonicalizePathList(value) {
6135
6149
  return value.split(delimiter4).map((entry) => canonicalizePath(entry) ?? entry).join(delimiter4);
6136
6150
  }
6137
6151
  function canonicalizePath(value) {
6138
- if (value === undefined || !isAbsolute4(value) || !existsSync11(value))
6152
+ if (value === undefined || !isAbsolute5(value) || !existsSync12(value))
6139
6153
  return value;
6140
6154
  return realpathSync4(value);
6141
6155
  }