lazycodex-ai 5.1.47 → 5.1.51

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 (438) hide show
  1. package/dist/cli/index.js +1194 -752
  2. package/dist/cli/service-auth/accounts-gate.d.ts +11 -0
  3. package/dist/cli/service-auth/commands.d.ts +2 -4
  4. package/dist/cli/service-auth/index.d.ts +1 -1
  5. package/dist/cli/service-auth/keystore.d.ts +26 -2
  6. package/dist/cli/service-auth/protocol.d.ts +7 -1
  7. package/dist/cli/service-auth/session.d.ts +6 -0
  8. package/dist/cli/service-auth/signed-out-marker.d.ts +11 -0
  9. package/dist/cli-node/index.js +1194 -752
  10. package/package.json +3 -1
  11. package/packages/lsp-core/package.json +45 -0
  12. package/packages/lsp-core/src/index.ts +30 -0
  13. package/packages/lsp-core/src/lsp/bun-command-output.ts +82 -0
  14. package/packages/lsp-core/src/lsp/bun-project-checks.test.ts +170 -0
  15. package/packages/lsp-core/src/lsp/bun-project-checks.ts +223 -0
  16. package/packages/lsp-core/src/lsp/cleanup-errors.test.ts +18 -0
  17. package/packages/lsp-core/src/lsp/cleanup-errors.ts +14 -0
  18. package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +52 -0
  19. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +471 -0
  20. package/packages/lsp-core/src/lsp/client-diagnostics-pull-timeout.test.ts +64 -0
  21. package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
  22. package/packages/lsp-core/src/lsp/client-wrapper.test.ts +213 -0
  23. package/packages/lsp-core/src/lsp/client-wrapper.ts +290 -0
  24. package/packages/lsp-core/src/lsp/client.ts +398 -0
  25. package/packages/lsp-core/src/lsp/config-loader.ts +254 -0
  26. package/packages/lsp-core/src/lsp/connection.ts +95 -0
  27. package/packages/lsp-core/src/lsp/constants.ts +17 -0
  28. package/packages/lsp-core/src/lsp/controlled-clock-test-support.ts +90 -0
  29. package/packages/lsp-core/src/lsp/directory-diagnostics.test.ts +221 -0
  30. package/packages/lsp-core/src/lsp/directory-diagnostics.ts +187 -0
  31. package/packages/lsp-core/src/lsp/effective-extension.ts +10 -0
  32. package/packages/lsp-core/src/lsp/errors.ts +89 -0
  33. package/packages/lsp-core/src/lsp/fake-bun-test-support.ts +102 -0
  34. package/packages/lsp-core/src/lsp/fixtures/diagnostics-freshness-contract-probe.ts +283 -0
  35. package/packages/lsp-core/src/lsp/fixtures/disposed-stdin-epipe-probe.ts +28 -0
  36. package/packages/lsp-core/src/lsp/fixtures/workspace-edit-contract-probe.ts +196 -0
  37. package/packages/lsp-core/src/lsp/fixtures/workspace-edit-server.mjs +234 -0
  38. package/packages/lsp-core/src/lsp/format-document.test.ts +143 -0
  39. package/packages/lsp-core/src/lsp/format-document.ts +90 -0
  40. package/packages/lsp-core/src/lsp/formatters.ts +144 -0
  41. package/packages/lsp-core/src/lsp/infer-extension.ts +66 -0
  42. package/packages/lsp-core/src/lsp/json-rpc-connection-cancellation.test.ts +97 -0
  43. package/packages/lsp-core/src/lsp/json-rpc-connection.ts +369 -0
  44. package/packages/lsp-core/src/lsp/language-mappings.ts +173 -0
  45. package/packages/lsp-core/src/lsp/manager-lifecycle.test.ts +262 -0
  46. package/packages/lsp-core/src/lsp/manager-max-clients.test.ts +151 -0
  47. package/packages/lsp-core/src/lsp/manager.ts +495 -0
  48. package/packages/lsp-core/src/lsp/outside-context-workspace.ts +33 -0
  49. package/packages/lsp-core/src/lsp/process-pipe-errors.test.ts +21 -0
  50. package/packages/lsp-core/src/lsp/process-signal-cleanup.ts +21 -0
  51. package/packages/lsp-core/src/lsp/process.ts +221 -0
  52. package/packages/lsp-core/src/lsp/server-definitions.ts +205 -0
  53. package/packages/lsp-core/src/lsp/server-install-state.ts +67 -0
  54. package/packages/lsp-core/src/lsp/server-installation.test.ts +376 -0
  55. package/packages/lsp-core/src/lsp/server-installation.ts +218 -0
  56. package/packages/lsp-core/src/lsp/server-resolution-local-binary.test.ts +170 -0
  57. package/packages/lsp-core/src/lsp/server-resolution.ts +117 -0
  58. package/packages/lsp-core/src/lsp/startup-failure.ts +1 -0
  59. package/packages/lsp-core/src/lsp/timer-provider.ts +13 -0
  60. package/packages/lsp-core/src/lsp/transport-protocol.ts +52 -0
  61. package/packages/lsp-core/src/lsp/transport-request-timeout.test.ts +73 -0
  62. package/packages/lsp-core/src/lsp/transport.ts +339 -0
  63. package/packages/lsp-core/src/lsp/types.ts +134 -0
  64. package/packages/lsp-core/src/lsp/utils.test.ts +72 -0
  65. package/packages/lsp-core/src/lsp/utils.ts +40 -0
  66. package/packages/lsp-core/src/lsp/workspace-apply-edit-failure.ts +19 -0
  67. package/packages/lsp-core/src/lsp/workspace-apply-edit-lease.integration.test.ts +218 -0
  68. package/packages/lsp-core/src/lsp/workspace-apply-edit-sync.integration.test.ts +113 -0
  69. package/packages/lsp-core/src/lsp/workspace-apply-edit-test-support.ts +194 -0
  70. package/packages/lsp-core/src/lsp/workspace-apply-edit.integration.test.ts +163 -0
  71. package/packages/lsp-core/src/lsp/workspace-document-state.test.ts +150 -0
  72. package/packages/lsp-core/src/lsp/workspace-document-state.ts +392 -0
  73. package/packages/lsp-core/src/lsp/workspace-edit-adversarial.test.ts +132 -0
  74. package/packages/lsp-core/src/lsp/workspace-edit-commit.test.ts +140 -0
  75. package/packages/lsp-core/src/lsp/workspace-edit-commit.ts +220 -0
  76. package/packages/lsp-core/src/lsp/workspace-edit-contract-evidence.test.ts +56 -0
  77. package/packages/lsp-core/src/lsp/workspace-edit-contract-evidence.ts +30 -0
  78. package/packages/lsp-core/src/lsp/workspace-edit-fingerprint.ts +44 -0
  79. package/packages/lsp-core/src/lsp/workspace-edit-options.test.ts +147 -0
  80. package/packages/lsp-core/src/lsp/workspace-edit-parse-helpers.ts +59 -0
  81. package/packages/lsp-core/src/lsp/workspace-edit-parser.ts +130 -0
  82. package/packages/lsp-core/src/lsp/workspace-edit-path.ts +98 -0
  83. package/packages/lsp-core/src/lsp/workspace-edit-plan-types.ts +60 -0
  84. package/packages/lsp-core/src/lsp/workspace-edit-plan.ts +73 -0
  85. package/packages/lsp-core/src/lsp/workspace-edit-prevalidation.test.ts +174 -0
  86. package/packages/lsp-core/src/lsp/workspace-edit-resource-parser.ts +89 -0
  87. package/packages/lsp-core/src/lsp/workspace-edit-simulation.ts +183 -0
  88. package/packages/lsp-core/src/lsp/workspace-edit-snapshot.ts +53 -0
  89. package/packages/lsp-core/src/lsp/workspace-edit-text.ts +125 -0
  90. package/packages/lsp-core/src/lsp/workspace-edit-types.ts +121 -0
  91. package/packages/lsp-core/src/lsp/workspace-edit.characterization.test.ts +95 -0
  92. package/packages/lsp-core/src/lsp/workspace-edit.ts +55 -0
  93. package/packages/lsp-core/src/lsp/workspace-markers.ts +18 -0
  94. package/packages/lsp-core/src/lsp/workspace-mutation-controller.ts +182 -0
  95. package/packages/lsp-core/src/mcp-protocol-pin.test.ts +97 -0
  96. package/packages/lsp-core/src/mcp.ts +122 -0
  97. package/packages/lsp-core/src/missing-dependency-result.test.ts +135 -0
  98. package/packages/lsp-core/src/missing-dependency-result.ts +79 -0
  99. package/packages/lsp-core/src/post-edit/file-location.ts +55 -0
  100. package/packages/lsp-core/src/post-edit/index.ts +3 -0
  101. package/packages/lsp-core/src/post-edit/not-installed-guidance.ts +36 -0
  102. package/packages/lsp-core/src/post-edit/not-installed.test.ts +224 -0
  103. package/packages/lsp-core/src/post-edit/orchestration.test.ts +157 -0
  104. package/packages/lsp-core/src/post-edit/orchestration.ts +205 -0
  105. package/packages/lsp-core/src/request-context.test.ts +200 -0
  106. package/packages/lsp-core/src/request-context.ts +235 -0
  107. package/packages/lsp-core/src/tool-surface.test.ts +173 -0
  108. package/packages/lsp-core/src/tools/bun-directory-diagnostics.test.ts +113 -0
  109. package/packages/lsp-core/src/tools/bun-directory-diagnostics.ts +75 -0
  110. package/packages/lsp-core/src/tools/definitions.ts +156 -0
  111. package/packages/lsp-core/src/tools/diagnostics.ts +133 -0
  112. package/packages/lsp-core/src/tools/format.test.ts +56 -0
  113. package/packages/lsp-core/src/tools/format.ts +56 -0
  114. package/packages/lsp-core/src/tools/index.ts +11 -0
  115. package/packages/lsp-core/src/tools/install-decision.ts +39 -0
  116. package/packages/lsp-core/src/tools/navigation.ts +88 -0
  117. package/packages/lsp-core/src/tools/parameters.test.ts +51 -0
  118. package/packages/lsp-core/src/tools/parameters.ts +49 -0
  119. package/packages/lsp-core/src/tools/rename.ts +69 -0
  120. package/packages/lsp-core/src/tools/result.ts +5 -0
  121. package/packages/lsp-core/src/tools/runtime.ts +21 -0
  122. package/packages/lsp-core/src/tools/schema.ts +9 -0
  123. package/packages/lsp-core/src/tools/status.ts +28 -0
  124. package/packages/lsp-core/src/tools/symbols.ts +99 -0
  125. package/packages/lsp-core/src/tools/types.ts +116 -0
  126. package/packages/lsp-core/src/tools.ts +1 -0
  127. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  128. package/packages/omo-codex/plugin/README.md +1 -1
  129. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  130. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  131. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  132. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  133. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  134. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  135. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  136. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  137. package/packages/omo-codex/plugin/components/lcx/skills/lcx-contribute-bug-fix/SKILL.md +51 -55
  138. package/packages/omo-codex/plugin/components/lcx/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
  139. package/packages/omo-codex/plugin/components/lcx/skills/lcx-report-bug/SKILL.md +7 -7
  140. package/packages/omo-codex/plugin/components/lcx/skills/lcx-report-bug/agents/openai.yaml +1 -1
  141. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  142. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  143. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  144. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  145. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  146. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  147. package/packages/omo-codex/plugin/components/teammode/package.json +2 -2
  148. package/packages/omo-codex/plugin/components/telemetry/README.md +2 -2
  149. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +52 -15
  150. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +52 -19
  151. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  152. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  153. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +2 -9
  154. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -13
  155. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +0 -2
  156. package/packages/omo-codex/plugin/components/telemetry/test/codex-hook-diagnostics.test.ts +0 -3
  157. package/packages/omo-codex/plugin/components/telemetry/test/codex-hook.test.ts +3 -8
  158. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +3 -0
  159. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  160. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  161. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +1 -1
  162. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  163. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  164. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +3 -0
  165. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  166. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  167. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  168. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  169. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  170. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  171. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  172. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  173. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  174. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  175. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  176. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  177. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  178. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  179. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  180. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  181. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  182. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  183. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  184. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  185. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  186. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  187. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  188. package/packages/omo-codex/plugin/package-lock.json +16 -16
  189. package/packages/omo-codex/plugin/package.json +1 -1
  190. package/packages/omo-codex/plugin/shared/package.json +1 -1
  191. package/packages/omo-codex/plugin/skills/ast-grep/README.md +1 -1
  192. package/packages/omo-codex/plugin/skills/ast-grep/install.ps1 +5 -3
  193. package/packages/omo-codex/plugin/skills/ast-grep/install.sh +4 -5
  194. package/packages/omo-codex/plugin/skills/ast-grep/references/install.md +2 -2
  195. package/packages/omo-codex/plugin/skills/ast-grep/scripts/ast_grep_helper.py +13 -3
  196. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +1 -1
  197. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +5 -4
  198. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +11 -11
  199. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +2 -2
  200. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/codex.md +4 -4
  201. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +1 -1
  202. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/find-agent-sessions.py +6 -3
  203. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +1 -1
  204. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +34 -12
  205. package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +2 -2
  206. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +2 -1
  207. package/packages/omo-codex/plugin/skills/frontend/references/design/component-catalogs.md +14 -10
  208. package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +19 -6
  209. package/packages/omo-codex/plugin/skills/frontend/references/design/grounding.md +29 -0
  210. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/design_system.py +2 -0
  211. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/search.py +2 -0
  212. package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/SKILL.md +51 -55
  213. package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
  214. package/packages/omo-codex/plugin/skills/lcx-report-bug/SKILL.md +7 -7
  215. package/packages/omo-codex/plugin/skills/lcx-report-bug/agents/openai.yaml +1 -1
  216. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +5 -4
  217. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +2 -2
  218. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/__main__.py +9 -6
  219. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/summary.py +1 -1
  220. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +4 -4
  221. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/extract_cookies.py +4 -2
  222. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +3 -0
  223. package/packages/omo-codex/plugin/skills/ulw-research/AGENTS.md +8 -4
  224. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +7 -259
  225. package/packages/omo-codex/plugin/skills/ulw-research/references/deliverable-phase.md +68 -24
  226. package/packages/omo-codex/plugin/skills/ulw-research/references/fact-ledger-grammar.md +7 -3
  227. package/packages/omo-codex/plugin/skills/ulw-research/references/fact-ledger.md +42 -8
  228. package/packages/omo-codex/plugin/skills/ulw-research/references/fidelity-claim-kinds.md +1 -1
  229. package/packages/omo-codex/plugin/skills/ulw-research/references/markdown-blocks.md +12 -0
  230. package/packages/omo-codex/plugin/skills/ulw-research/references/report-gates.md +14 -6
  231. package/packages/omo-codex/plugin/skills/ulw-research/references/research-collection.md +195 -0
  232. package/packages/omo-codex/plugin/skills/ulw-research/references/research-delivery.md +123 -0
  233. package/packages/omo-codex/plugin/skills/ulw-research/scripts/claim-kinds.mjs +33 -5
  234. package/packages/omo-codex/plugin/skills/ulw-research/scripts/contracts.mjs +16 -15
  235. package/packages/omo-codex/plugin/skills/ulw-research/scripts/conversion-probe.mjs +229 -0
  236. package/packages/omo-codex/plugin/skills/ulw-research/scripts/css-hiding.mjs +158 -0
  237. package/packages/omo-codex/plugin/skills/ulw-research/scripts/css-lite.mjs +4 -2
  238. package/packages/omo-codex/plugin/skills/ulw-research/scripts/entities.mjs +13 -4
  239. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-fill.mjs +96 -0
  240. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-meaning.mjs +26 -30
  241. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-polish.mjs +46 -19
  242. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-verify.mjs +37 -6
  243. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands.mjs +40 -62
  244. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-derive.mjs +7 -2
  245. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-fill.mjs +9 -6
  246. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-ledger-kinds.mjs +6 -7
  247. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-locate.mjs +15 -9
  248. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-claims.mjs +4 -3
  249. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-csv.mjs +32 -0
  250. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-lexicon.mjs +1 -1
  251. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-originals.mjs +161 -0
  252. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-policy.mjs +183 -0
  253. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-records.mjs +81 -14
  254. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-snapshot-readability.mjs +49 -0
  255. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-sources.mjs +76 -0
  256. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-trace.mjs +25 -11
  257. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-value-unit.mjs +202 -0
  258. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-values.mjs +40 -39
  259. package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-fidelity.mjs +8 -6
  260. package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-static.mjs +10 -1
  261. package/packages/omo-codex/plugin/skills/ulw-research/scripts/html-lite.mjs +6 -2
  262. package/packages/omo-codex/plugin/skills/ulw-research/scripts/html-markup.mjs +2 -2
  263. package/packages/omo-codex/plugin/skills/ulw-research/scripts/html-text-map.mjs +140 -0
  264. package/packages/omo-codex/plugin/skills/ulw-research/scripts/markdown-closers.mjs +126 -0
  265. package/packages/omo-codex/plugin/skills/ulw-research/scripts/md-lite.mjs +1 -1
  266. package/packages/omo-codex/plugin/skills/ulw-research/scripts/number-grammar.mjs +33 -0
  267. package/packages/omo-codex/plugin/skills/ulw-research/scripts/numerals.mjs +18 -7
  268. package/packages/omo-codex/plugin/skills/ulw-research/scripts/outcome-start.mjs +66 -0
  269. package/packages/omo-codex/plugin/skills/ulw-research/scripts/outcome.mjs +11 -22
  270. package/packages/omo-codex/plugin/skills/ulw-research/scripts/placeholder.mjs +18 -6
  271. package/packages/omo-codex/plugin/skills/ulw-research/scripts/polish-apply.mjs +3 -2
  272. package/packages/omo-codex/plugin/skills/ulw-research/scripts/raw-decode.mjs +110 -0
  273. package/packages/omo-codex/plugin/skills/ulw-research/scripts/raw-locator.mjs +47 -0
  274. package/packages/omo-codex/plugin/skills/ulw-research/scripts/report-tools-commands.mjs +1 -1
  275. package/packages/omo-codex/plugin/skills/ulw-research/scripts/report-tools.mjs +7 -1
  276. package/packages/omo-codex/plugin/skills/ulw-research/scripts/source-commands.mjs +87 -29
  277. package/packages/omo-codex/plugin/skills/ulw-research/scripts/source-refresh.mjs +82 -0
  278. package/packages/omo-codex/plugin/skills/ulw-research/scripts/source-snapshot.mjs +73 -69
  279. package/packages/omo-codex/plugin/skills/ulw-research/scripts/source-view.mjs +89 -0
  280. package/packages/omo-codex/plugin/skills/ulw-research/scripts/sources-citation.mjs +203 -0
  281. package/packages/omo-codex/plugin/skills/ulw-research/scripts/units.mjs +14 -3
  282. package/packages/omo-codex/plugin/test/payload-equivalence.test.mjs +6 -4
  283. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +4 -3
  284. package/packages/omo-codex/scripts/install-dist/install-local.mjs +338 -237
  285. package/packages/prompts-core/prompts/ultrawork/codex.md +3 -0
  286. package/packages/shared-skills/skill-source-filter.mjs +6 -2
  287. package/packages/shared-skills/skills/ast-grep/README.md +1 -1
  288. package/packages/shared-skills/skills/ast-grep/install.ps1 +5 -3
  289. package/packages/shared-skills/skills/ast-grep/install.sh +4 -5
  290. package/packages/shared-skills/skills/ast-grep/references/install.md +2 -2
  291. package/packages/shared-skills/skills/ast-grep/scripts/ast_grep_helper.py +13 -3
  292. package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +1 -1
  293. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +5 -4
  294. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +11 -11
  295. package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +2 -2
  296. package/packages/shared-skills/skills/coding-agent-sessions/references/codex.md +4 -4
  297. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +1 -1
  298. package/packages/shared-skills/skills/coding-agent-sessions/scripts/find-agent-sessions.py +6 -3
  299. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +1 -1
  300. package/packages/shared-skills/skills/frontend/SKILL.md +34 -12
  301. package/packages/shared-skills/skills/frontend/references/design/README.md +2 -2
  302. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +2 -1
  303. package/packages/shared-skills/skills/frontend/references/design/component-catalogs.md +14 -10
  304. package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +19 -6
  305. package/packages/shared-skills/skills/frontend/references/design/grounding.md +29 -0
  306. package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/design_system.py +2 -0
  307. package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/search.py +2 -0
  308. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +5 -4
  309. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +2 -2
  310. package/packages/shared-skills/skills/ultimate-browsing/engine/__main__.py +9 -6
  311. package/packages/shared-skills/skills/ultimate-browsing/engine/summary.py +1 -1
  312. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +4 -4
  313. package/packages/shared-skills/skills/ultimate-browsing/scripts/extract_cookies.py +4 -2
  314. package/packages/shared-skills/skills/ulw-research/AGENTS.md +8 -4
  315. package/packages/shared-skills/skills/ulw-research/SKILL.md +7 -259
  316. package/packages/shared-skills/skills/ulw-research/references/deliverable-phase.md +68 -24
  317. package/packages/shared-skills/skills/ulw-research/references/fact-ledger-grammar.md +7 -3
  318. package/packages/shared-skills/skills/ulw-research/references/fact-ledger.md +42 -8
  319. package/packages/shared-skills/skills/ulw-research/references/fidelity-claim-kinds.md +1 -1
  320. package/packages/shared-skills/skills/ulw-research/references/markdown-blocks.md +12 -0
  321. package/packages/shared-skills/skills/ulw-research/references/report-gates.md +14 -6
  322. package/packages/shared-skills/skills/ulw-research/references/research-collection.md +195 -0
  323. package/packages/shared-skills/skills/ulw-research/references/research-delivery.md +123 -0
  324. package/packages/shared-skills/skills/ulw-research/scripts/claim-kinds.mjs +33 -5
  325. package/packages/shared-skills/skills/ulw-research/scripts/claim-kinds.test.ts +37 -2
  326. package/packages/shared-skills/skills/ulw-research/scripts/claim-prefix.test.ts +76 -0
  327. package/packages/shared-skills/skills/ulw-research/scripts/contracts-validation.test.ts +83 -0
  328. package/packages/shared-skills/skills/ulw-research/scripts/contracts.mjs +16 -15
  329. package/packages/shared-skills/skills/ulw-research/scripts/contracts.test.ts +6 -109
  330. package/packages/shared-skills/skills/ulw-research/scripts/conversion-altered.test.ts +154 -0
  331. package/packages/shared-skills/skills/ulw-research/scripts/conversion-originals.test.ts +297 -0
  332. package/packages/shared-skills/skills/ulw-research/scripts/conversion-probe-classes.test.ts +361 -0
  333. package/packages/shared-skills/skills/ulw-research/scripts/conversion-probe.mjs +229 -0
  334. package/packages/shared-skills/skills/ulw-research/scripts/conversion-probe.test.ts +218 -0
  335. package/packages/shared-skills/skills/ulw-research/scripts/copy-returns-fidelity-policy.test.ts +156 -0
  336. package/packages/shared-skills/skills/ulw-research/scripts/copy-returns-polish.test.ts +10 -9
  337. package/packages/shared-skills/skills/ulw-research/scripts/css-hiding.mjs +158 -0
  338. package/packages/shared-skills/skills/ulw-research/scripts/css-lite.mjs +4 -2
  339. package/packages/shared-skills/skills/ulw-research/scripts/delivery-barrier-meaning.test.ts +186 -0
  340. package/packages/shared-skills/skills/ulw-research/scripts/delivery-barrier.test.ts +40 -87
  341. package/packages/shared-skills/skills/ulw-research/scripts/entities.mjs +13 -4
  342. package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-fill.mjs +96 -0
  343. package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-meaning.mjs +26 -30
  344. package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-polish.mjs +46 -19
  345. package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-verify.mjs +37 -6
  346. package/packages/shared-skills/skills/ulw-research/scripts/fact-commands.mjs +40 -62
  347. package/packages/shared-skills/skills/ulw-research/scripts/fact-derive-2.test.ts +149 -0
  348. package/packages/shared-skills/skills/ulw-research/scripts/fact-derive.mjs +7 -2
  349. package/packages/shared-skills/skills/ulw-research/scripts/fact-derive.test.ts +7 -192
  350. package/packages/shared-skills/skills/ulw-research/scripts/fact-fill.mjs +9 -6
  351. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-kinds.mjs +6 -7
  352. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-kinds.test.ts +2 -1
  353. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-legacy.test.ts +2 -1
  354. package/packages/shared-skills/skills/ulw-research/scripts/fact-locate.mjs +15 -9
  355. package/packages/shared-skills/skills/ulw-research/scripts/fact-unit-dimensions-2.test.ts +149 -0
  356. package/packages/shared-skills/skills/ulw-research/scripts/fact-unit-dimensions.test.ts +4 -168
  357. package/packages/shared-skills/skills/ulw-research/scripts/fact-unit-rules.test.ts +3 -229
  358. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-claims.mjs +4 -3
  359. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-csv.mjs +32 -0
  360. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-lexicon.mjs +1 -1
  361. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-originals.mjs +161 -0
  362. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-policy.mjs +183 -0
  363. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-records.mjs +81 -14
  364. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-snapshot-readability.mjs +49 -0
  365. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-sources.mjs +76 -0
  366. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-trace.mjs +25 -11
  367. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-value-unit.mjs +202 -0
  368. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-values.mjs +40 -39
  369. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-values.test.ts +8 -29
  370. package/packages/shared-skills/skills/ulw-research/scripts/gates-fidelity.mjs +8 -6
  371. package/packages/shared-skills/skills/ulw-research/scripts/gates-static-headings.test.ts +17 -0
  372. package/packages/shared-skills/skills/ulw-research/scripts/gates-static.mjs +10 -1
  373. package/packages/shared-skills/skills/ulw-research/scripts/html-lite.mjs +6 -2
  374. package/packages/shared-skills/skills/ulw-research/scripts/html-markup.mjs +2 -2
  375. package/packages/shared-skills/skills/ulw-research/scripts/html-text-map.mjs +140 -0
  376. package/packages/shared-skills/skills/ulw-research/scripts/html-text-map.test.ts +148 -0
  377. package/packages/shared-skills/skills/ulw-research/scripts/markdown-closers.mjs +126 -0
  378. package/packages/shared-skills/skills/ulw-research/scripts/md-lite-boundaries.test.ts +46 -0
  379. package/packages/shared-skills/skills/ulw-research/scripts/md-lite.mjs +1 -1
  380. package/packages/shared-skills/skills/ulw-research/scripts/number-grammar.mjs +33 -0
  381. package/packages/shared-skills/skills/ulw-research/scripts/number-grammar.test.ts +36 -0
  382. package/packages/shared-skills/skills/ulw-research/scripts/numerals.mjs +18 -7
  383. package/packages/shared-skills/skills/ulw-research/scripts/numerals.test.ts +3 -0
  384. package/packages/shared-skills/skills/ulw-research/scripts/outcome-start.mjs +66 -0
  385. package/packages/shared-skills/skills/ulw-research/scripts/outcome-start.test.ts +109 -0
  386. package/packages/shared-skills/skills/ulw-research/scripts/outcome.mjs +11 -22
  387. package/packages/shared-skills/skills/ulw-research/scripts/page-source-locator.test.ts +187 -0
  388. package/packages/shared-skills/skills/ulw-research/scripts/placeholder.mjs +18 -6
  389. package/packages/shared-skills/skills/ulw-research/scripts/polish-apply.mjs +3 -2
  390. package/packages/shared-skills/skills/ulw-research/scripts/polish-markup.test.ts +15 -1
  391. package/packages/shared-skills/skills/ulw-research/scripts/polish-partial.test.ts +42 -0
  392. package/packages/shared-skills/skills/ulw-research/scripts/raw-decode.mjs +110 -0
  393. package/packages/shared-skills/skills/ulw-research/scripts/raw-locator.mjs +47 -0
  394. package/packages/shared-skills/skills/ulw-research/scripts/raw-snapshot.test.ts +139 -0
  395. package/packages/shared-skills/skills/ulw-research/scripts/report-tools-2.test.ts +233 -0
  396. package/packages/shared-skills/skills/ulw-research/scripts/report-tools-3.test.ts +141 -0
  397. package/packages/shared-skills/skills/ulw-research/scripts/report-tools-4.test.ts +135 -0
  398. package/packages/shared-skills/skills/ulw-research/scripts/report-tools-5.test.ts +231 -0
  399. package/packages/shared-skills/skills/ulw-research/scripts/report-tools-commands.mjs +1 -1
  400. package/packages/shared-skills/skills/ulw-research/scripts/report-tools.mjs +7 -1
  401. package/packages/shared-skills/skills/ulw-research/scripts/report-tools.test.ts +6 -560
  402. package/packages/shared-skills/skills/ulw-research/scripts/snapshot-readability.test.ts +116 -0
  403. package/packages/shared-skills/skills/ulw-research/scripts/source-commands.mjs +87 -29
  404. package/packages/shared-skills/skills/ulw-research/scripts/source-integrity.test.ts +243 -0
  405. package/packages/shared-skills/skills/ulw-research/scripts/source-refresh.mjs +82 -0
  406. package/packages/shared-skills/skills/ulw-research/scripts/source-snapshot.mjs +73 -69
  407. package/packages/shared-skills/skills/ulw-research/scripts/source-snapshot.test.ts +7 -4
  408. package/packages/shared-skills/skills/ulw-research/scripts/source-view.mjs +89 -0
  409. package/packages/shared-skills/skills/ulw-research/scripts/sources-citation.mjs +203 -0
  410. package/packages/shared-skills/skills/ulw-research/scripts/sources-citation.test.ts +236 -0
  411. package/packages/shared-skills/skills/ulw-research/scripts/tests/contracts-support.ts +147 -0
  412. package/packages/shared-skills/skills/ulw-research/scripts/tests/delivery-barrier-session.ts +59 -0
  413. package/packages/shared-skills/skills/ulw-research/scripts/tests/derive-clock.ts +4 -0
  414. package/packages/shared-skills/skills/ulw-research/scripts/tests/fact-derive-support.ts +65 -0
  415. package/packages/shared-skills/skills/ulw-research/scripts/tests/fact-unit-dimensions-support.ts +41 -0
  416. package/packages/shared-skills/skills/ulw-research/scripts/tests/fact-unit-rules-support.ts +241 -0
  417. package/packages/shared-skills/skills/ulw-research/scripts/tests/fidelity-values-support.ts +30 -0
  418. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/conversion-probe.html +14 -0
  419. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/sources-shapes.html +20 -0
  420. package/packages/shared-skills/skills/ulw-research/scripts/tests/numeral-classes.ts +196 -0
  421. package/packages/shared-skills/skills/ulw-research/scripts/tests/report-tools-support.ts +182 -0
  422. package/packages/shared-skills/skills/ulw-research/scripts/tests/value-mode-support.ts +48 -0
  423. package/packages/shared-skills/skills/ulw-research/scripts/units.mjs +14 -3
  424. package/packages/shared-skills/skills/ulw-research/scripts/units.test.ts +10 -0
  425. package/packages/shared-skills/skills/ulw-research/scripts/value-mode-unit-classes.test.ts +255 -0
  426. package/packages/shared-skills/skills/ulw-research/scripts/value-mode-unit.test.ts +179 -0
  427. package/packages/shared-skills/skills/ulw-research/scripts/value-rules-cli.test.ts +157 -0
  428. package/packages/shared-skills/skills/ulw-research/scripts/value-rules-followups.test.ts +72 -0
  429. package/packages/shared-skills/skills/ulw-research/scripts/value-rules-priority.test.ts +80 -0
  430. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/amp_redirect_stub.html +0 -7
  431. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/search_interstitial.html +0 -19
  432. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/wayback_available.json +0 -1
  433. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/wayback_snapshot.html +0 -1128
  434. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_fetch_chain.py +0 -77
  435. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_stealth.py +0 -86
  436. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +0 -279
  437. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_surrogate.py +0 -252
  438. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_surrogate_validators.py +0 -78
@@ -0,0 +1,200 @@
1
+ import { mkdirSync, mkdtempSync, realpathSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
2
+ import { homedir, tmpdir } from "node:os";
3
+ import { delimiter, join } from "node:path";
4
+ import { afterEach, describe, expect, it } from "bun:test";
5
+
6
+ import {
7
+ createStandaloneMcpRequestContext,
8
+ LspRequestContextUnavailableError,
9
+ LspRequestContextParseError,
10
+ parseLspRequestContext,
11
+ runWithRequestContext,
12
+ lspRequestContext,
13
+ } from "./request-context.js";
14
+
15
+ const tempDirectories: string[] = [];
16
+
17
+ afterEach(() => {
18
+ for (const directory of tempDirectories.splice(0)) {
19
+ rmSync(directory, { recursive: true, force: true });
20
+ }
21
+ });
22
+
23
+ function tempRoot(prefix: string): string {
24
+ const root = mkdtempSync(join(homedir(), prefix));
25
+ tempDirectories.push(root);
26
+ return root;
27
+ }
28
+
29
+ function tempSystemRoot(prefix: string): string {
30
+ const root = mkdtempSync(join(tmpdir(), prefix));
31
+ tempDirectories.push(root);
32
+ return root;
33
+ }
34
+
35
+ describe("LspRequestContext", () => {
36
+ it("#given exact typed context #when parsed #then canonicalizes cwd and preserves typed paths", () => {
37
+ const root = tempRoot("lsp-context-root-");
38
+ const projectPath = join(root, ".codex", "lsp-client.json");
39
+ const userPath = join(homedir(), ".codex", "lsp-client.json");
40
+ const decisionsPath = join(homedir(), ".codex", "lsp-install-decisions.json");
41
+ mkdirSync(join(root, ".codex"), { recursive: true });
42
+
43
+ const context = parseLspRequestContext({
44
+ cwd: join(root, "."),
45
+ projectConfigPaths: [projectPath],
46
+ userConfigPath: userPath,
47
+ installDecisionsPath: decisionsPath,
48
+ capabilities: { installDecisionTool: false },
49
+ });
50
+
51
+ expect(context).toEqual({
52
+ cwd: root,
53
+ projectConfigPaths: [projectPath],
54
+ userConfigPath: userPath,
55
+ installDecisionsPath: decisionsPath,
56
+ capabilities: { installDecisionTool: false },
57
+ });
58
+ expect(runWithRequestContext(context, () => lspRequestContext())).toEqual(context);
59
+ });
60
+
61
+ it("#given no active context #when requested #then throws an actionable typed error", () => {
62
+ expect(() => lspRequestContext()).toThrow(LspRequestContextUnavailableError);
63
+ });
64
+
65
+ it("#given unknown field #when parsed #then rejects before lookup", () => {
66
+ const root = tempRoot("lsp-context-unknown-");
67
+ const projectPath = join(root, ".codex", "lsp-client.json");
68
+
69
+ expect(() =>
70
+ parseLspRequestContext({
71
+ cwd: root,
72
+ projectConfigPaths: [projectPath],
73
+ userConfigPath: join(homedir(), ".codex", "lsp-client.json"),
74
+ installDecisionsPath: join(homedir(), ".codex", "lsp-install-decisions.json"),
75
+ capabilities: { installDecisionTool: true },
76
+ env: {},
77
+ }),
78
+ ).toThrow(LspRequestContextParseError);
79
+ });
80
+
81
+ it("#given project path outside cwd #when parsed #then rejects before config loading", () => {
82
+ const root = tempRoot("lsp-context-confined-");
83
+ const outside = tempRoot("lsp-context-outside-");
84
+
85
+ expect(() =>
86
+ parseLspRequestContext({
87
+ cwd: root,
88
+ projectConfigPaths: [join(outside, "lsp-client.json")],
89
+ userConfigPath: join(homedir(), ".codex", "lsp-client.json"),
90
+ installDecisionsPath: join(homedir(), ".codex", "lsp-install-decisions.json"),
91
+ capabilities: { installDecisionTool: true },
92
+ }),
93
+ ).toThrow(LspRequestContextParseError);
94
+ });
95
+
96
+ it("#given equivalent macOS var spelling #when parsed #then canonicalizes to one identity", () => {
97
+ const systemRoot = tempSystemRoot("lsp-context-private-var-");
98
+ const canonicalRoot = realpathSync(systemRoot);
99
+ const aliasRoot = canonicalRoot.startsWith("/private/var/") ? canonicalRoot.replace("/private/var/", "/var/") : systemRoot;
100
+ mkdirSync(join(canonicalRoot, ".codex"), { recursive: true });
101
+
102
+ const context = parseLspRequestContext({
103
+ cwd: aliasRoot,
104
+ projectConfigPaths: [join(aliasRoot, ".codex", "lsp-client.json")],
105
+ userConfigPath: join(homedir(), ".codex", "lsp-client.json"),
106
+ installDecisionsPath: join(homedir(), ".codex", "lsp-install-decisions.json"),
107
+ capabilities: { installDecisionTool: true },
108
+ });
109
+
110
+ expect(context.cwd).toBe(canonicalRoot);
111
+ expect(context.projectConfigPaths).toEqual([join(canonicalRoot, ".codex", "lsp-client.json")]);
112
+ });
113
+
114
+ it("#given missing standard project config inside cwd #when parsed #then accepts and preserves the intended suffix", () => {
115
+ const root = tempRoot("lsp-context-missing-config-");
116
+ mkdirSync(join(root, ".codex"), { recursive: true });
117
+
118
+ const context = parseLspRequestContext({
119
+ cwd: root,
120
+ projectConfigPaths: [join(root, ".codex", "missing-lsp-client.json")],
121
+ userConfigPath: join(homedir(), ".codex", "lsp-client.json"),
122
+ installDecisionsPath: join(homedir(), ".codex", "lsp-install-decisions.json"),
123
+ capabilities: { installDecisionTool: true },
124
+ });
125
+
126
+ expect(context.projectConfigPaths).toEqual([join(root, ".codex", "missing-lsp-client.json")]);
127
+ });
128
+
129
+ it("#given symlink project config escaping cwd #when parsed #then rejects the escape", () => {
130
+ const root = tempRoot("lsp-context-symlink-root-");
131
+ const outside = tempRoot("lsp-context-symlink-outside-");
132
+ const outsideConfig = join(outside, "lsp-client.json");
133
+ writeFileSync(outsideConfig, "{}");
134
+ const linkedConfig = join(root, "linked-lsp-client.json");
135
+ symlinkSync(outsideConfig, linkedConfig);
136
+
137
+ expect(() =>
138
+ parseLspRequestContext({
139
+ cwd: root,
140
+ projectConfigPaths: [linkedConfig],
141
+ userConfigPath: join(homedir(), ".codex", "lsp-client.json"),
142
+ installDecisionsPath: join(homedir(), ".codex", "lsp-install-decisions.json"),
143
+ capabilities: { installDecisionTool: true },
144
+ }),
145
+ ).toThrow(LspRequestContextParseError);
146
+ });
147
+
148
+ it("#given standalone MCP env #when translated #then resolves exact defaults and relative paths", () => {
149
+ const root = tempRoot("lsp-context-standalone-");
150
+ const home = tempRoot("lsp-context-home-");
151
+ const absoluteProjectPath = join(root, ".omo", "lsp-client.json");
152
+
153
+ const context = createStandaloneMcpRequestContext({
154
+ cwd: root,
155
+ homeDir: home,
156
+ env: {
157
+ LSP_TOOLS_MCP_PROJECT_CONFIG: ["relative.json", "", absoluteProjectPath].join(delimiter),
158
+ LSP_TOOLS_MCP_USER_CONFIG: "user-lsp.json",
159
+ LSP_TOOLS_MCP_INSTALL_DECISIONS: "decisions.json",
160
+ },
161
+ });
162
+
163
+ expect(context).toEqual({
164
+ cwd: root,
165
+ projectConfigPaths: [join(root, "relative.json"), absoluteProjectPath],
166
+ userConfigPath: join(home, "user-lsp.json"),
167
+ installDecisionsPath: join(home, "decisions.json"),
168
+ capabilities: { installDecisionTool: true },
169
+ });
170
+ });
171
+
172
+ it("#given an injected LSP cwd #when standalone context is created #then it wins over process cwd without reading global env", () => {
173
+ const sessionRoot = tempRoot("lsp-context-session-");
174
+ const processRoot = tempRoot("lsp-context-process-");
175
+ const home = tempRoot("lsp-context-env-home-");
176
+
177
+ const context = createStandaloneMcpRequestContext({
178
+ env: {
179
+ LSP_TOOLS_MCP_CWD: sessionRoot,
180
+ },
181
+ homeDir: home,
182
+ });
183
+
184
+ expect(context.cwd).toBe(sessionRoot);
185
+ expect(context.projectConfigPaths).toEqual([join(sessionRoot, ".codex", "lsp-client.json")]);
186
+ expect(processRoot).not.toBe(context.cwd);
187
+ });
188
+
189
+ it("#given explicit cwd and an injected LSP cwd #when standalone context is created #then explicit cwd wins", () => {
190
+ const explicitRoot = tempRoot("lsp-context-explicit-");
191
+ const injectedRoot = tempRoot("lsp-context-injected-");
192
+
193
+ const context = createStandaloneMcpRequestContext({
194
+ cwd: explicitRoot,
195
+ env: { LSP_TOOLS_MCP_CWD: injectedRoot },
196
+ });
197
+
198
+ expect(context.cwd).toBe(explicitRoot);
199
+ });
200
+ });
@@ -0,0 +1,235 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import { existsSync, realpathSync, statSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { basename, delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
5
+
6
+ export interface LspRequestContext {
7
+ readonly cwd: string;
8
+ readonly projectConfigPaths: readonly string[];
9
+ readonly userConfigPath: string;
10
+ readonly installDecisionsPath: string;
11
+ readonly capabilities: {
12
+ readonly installDecisionTool: boolean;
13
+ };
14
+ }
15
+
16
+ export type RequestContext = LspRequestContext;
17
+
18
+ export interface StandaloneMcpRequestContextInput {
19
+ readonly cwd?: string;
20
+ readonly env?: Record<string, string | undefined>;
21
+ readonly homeDir?: string;
22
+ }
23
+
24
+ export class LspRequestContextParseError extends Error {
25
+ override readonly name = "LspRequestContextParseError";
26
+
27
+ constructor(
28
+ readonly code: string,
29
+ message: string,
30
+ ) {
31
+ super(message);
32
+ }
33
+ }
34
+
35
+ export class LspRequestContextUnavailableError extends Error {
36
+ override readonly name = "LspRequestContextUnavailableError";
37
+
38
+ constructor() {
39
+ super(
40
+ "LSP request context is required. Standalone MCP startup must install one with runWithRequestContext(createStandaloneMcpRequestContext()).",
41
+ );
42
+ }
43
+ }
44
+
45
+ const storage = new AsyncLocalStorage<LspRequestContext>();
46
+ const CONTEXT_FIELDS = new Set(["cwd", "projectConfigPaths", "userConfigPath", "installDecisionsPath", "capabilities"]);
47
+ const CAPABILITY_FIELDS = new Set(["installDecisionTool"]);
48
+
49
+ export function runWithRequestContext<T>(context: LspRequestContext, fn: () => T): T {
50
+ return storage.run(context, fn);
51
+ }
52
+
53
+ export function lspRequestContext(): LspRequestContext {
54
+ const context = storage.getStore();
55
+ if (!context) throw new LspRequestContextUnavailableError();
56
+ return context;
57
+ }
58
+
59
+ export function contextCwd(): string {
60
+ return lspRequestContext().cwd;
61
+ }
62
+
63
+ export function contextEnv(key: string): string | undefined {
64
+ const context = lspRequestContext();
65
+ if (key === "LSP_TOOLS_MCP_PROJECT_CONFIG") return context.projectConfigPaths.join(delimiter);
66
+ if (key === "LSP_TOOLS_MCP_USER_CONFIG") return context.userConfigPath;
67
+ if (key === "LSP_TOOLS_MCP_INSTALL_DECISIONS") return context.installDecisionsPath;
68
+ return undefined;
69
+ }
70
+
71
+ export function createStandaloneMcpRequestContext(
72
+ input: StandaloneMcpRequestContextInput = {},
73
+ ): LspRequestContext {
74
+ const env = input.env ?? process.env;
75
+ const cwd = canonicalCwd(input.cwd ?? env["LSP_TOOLS_MCP_CWD"] ?? process.cwd());
76
+ const home = input.homeDir ?? homedir();
77
+ const projectConfigPaths = translateProjectConfigEnv(env["LSP_TOOLS_MCP_PROJECT_CONFIG"], cwd);
78
+ const userConfigPath = translateHomeConfigEnv(env["LSP_TOOLS_MCP_USER_CONFIG"], home, ".codex/lsp-client.json");
79
+ const installDecisionsPath = translateHomeConfigEnv(
80
+ env["LSP_TOOLS_MCP_INSTALL_DECISIONS"],
81
+ home,
82
+ ".codex/lsp-install-decisions.json",
83
+ );
84
+ return parseLspRequestContext({
85
+ cwd,
86
+ projectConfigPaths,
87
+ userConfigPath,
88
+ installDecisionsPath,
89
+ capabilities: { installDecisionTool: true },
90
+ });
91
+ }
92
+
93
+ export function parseLspRequestContext(value: unknown): LspRequestContext {
94
+ if (!isRecord(value)) {
95
+ throw new LspRequestContextParseError("invalid_context", "LSP request context must be an object.");
96
+ }
97
+ rejectUnknownFields(value, CONTEXT_FIELDS, "context");
98
+
99
+ const cwd = stringField(value, "cwd");
100
+ const projectConfigPaths = stringArrayField(value, "projectConfigPaths");
101
+ const userConfigPath = stringField(value, "userConfigPath");
102
+ const installDecisionsPath = stringField(value, "installDecisionsPath");
103
+ const capabilities = capabilitiesField(value["capabilities"]);
104
+ const canonical = canonicalCwd(cwd);
105
+
106
+ for (const path of projectConfigPaths) {
107
+ requireAbsolutePath(path, "projectConfigPaths");
108
+ const projectPath = canonicalizeExistingOrNearestAncestor(path);
109
+ if (!isPathInside(canonical, projectPath)) {
110
+ throw new LspRequestContextParseError(
111
+ "project_config_outside_cwd",
112
+ `Project LSP config path must be inside cwd: ${path}`,
113
+ );
114
+ }
115
+ }
116
+ requireAbsolutePath(userConfigPath, "userConfigPath");
117
+ requireAbsolutePath(installDecisionsPath, "installDecisionsPath");
118
+
119
+ return {
120
+ cwd: canonical,
121
+ projectConfigPaths: projectConfigPaths.map((path) => canonicalizeExistingOrNearestAncestor(path)),
122
+ userConfigPath,
123
+ installDecisionsPath,
124
+ capabilities,
125
+ };
126
+ }
127
+
128
+ function translateProjectConfigEnv(value: string | undefined, cwd: string): readonly string[] {
129
+ if (value === undefined || value.length === 0) return [join(cwd, ".codex", "lsp-client.json")];
130
+ return value
131
+ .split(delimiter)
132
+ .filter((entry) => entry.length > 0)
133
+ .map((entry) => (isAbsolute(entry) ? entry : join(cwd, entry)));
134
+ }
135
+
136
+ function translateHomeConfigEnv(value: string | undefined, home: string, fallback: string): string {
137
+ if (value === undefined || value.length === 0) return join(home, fallback);
138
+ return isAbsolute(value) ? value : join(home, value);
139
+ }
140
+
141
+ function canonicalCwd(cwd: string): string {
142
+ const resolved = resolve(cwd);
143
+ if (!existsSync(resolved) || !statSync(resolved).isDirectory()) {
144
+ throw new LspRequestContextParseError("invalid_cwd", `LSP request cwd must be an existing directory: ${cwd}`);
145
+ }
146
+ return realpathSync(resolved);
147
+ }
148
+
149
+ export function canonicalizeExistingOrNearestAncestor(path: string): string {
150
+ let current = resolve(path);
151
+ const suffix: string[] = [];
152
+ while (true) {
153
+ try {
154
+ const existing = realpathSync(current);
155
+ return suffix.length === 0 ? existing : join(existing, ...suffix);
156
+ } catch (error) {
157
+ if (!isMissingPathError(error)) throw error;
158
+ const parent = dirname(current);
159
+ if (parent === current) throw error;
160
+ suffix.unshift(basename(current));
161
+ current = parent;
162
+ }
163
+ }
164
+ }
165
+
166
+ function capabilitiesField(value: unknown): LspRequestContext["capabilities"] {
167
+ if (!isRecord(value)) {
168
+ throw new LspRequestContextParseError("invalid_capabilities", "LSP request capabilities must be an object.");
169
+ }
170
+ rejectUnknownFields(value, CAPABILITY_FIELDS, "capabilities");
171
+ const installDecisionTool = value["installDecisionTool"];
172
+ if (typeof installDecisionTool !== "boolean") {
173
+ throw new LspRequestContextParseError(
174
+ "invalid_install_decision_capability",
175
+ "LSP request capabilities.installDecisionTool must be a boolean.",
176
+ );
177
+ }
178
+ return { installDecisionTool };
179
+ }
180
+
181
+ function stringField(value: Record<string, unknown>, field: string): string {
182
+ const fieldValue = value[field];
183
+ if (typeof fieldValue !== "string" || fieldValue.length === 0) {
184
+ throw new LspRequestContextParseError("invalid_field", `LSP request context.${field} must be a non-empty string.`);
185
+ }
186
+ return fieldValue;
187
+ }
188
+
189
+ function stringArrayField(value: Record<string, unknown>, field: string): readonly string[] {
190
+ const fieldValue = value[field];
191
+ if (!Array.isArray(fieldValue) || !fieldValue.every((item) => typeof item === "string" && item.length > 0)) {
192
+ throw new LspRequestContextParseError(
193
+ "invalid_field",
194
+ `LSP request context.${field} must be a non-empty string array.`,
195
+ );
196
+ }
197
+ return fieldValue;
198
+ }
199
+
200
+ function requireAbsolutePath(path: string, field: string): void {
201
+ if (!isAbsolute(path)) {
202
+ throw new LspRequestContextParseError("relative_path", `LSP request context.${field} must be absolute: ${path}`);
203
+ }
204
+ }
205
+
206
+ export function isPathInside(parent: string, child: string): boolean {
207
+ const childPath = resolve(child);
208
+ const relativePath = relative(parent, childPath);
209
+ return relativePath === "" || (!relativePath.startsWith("..") && !isAbsolute(relativePath));
210
+ }
211
+
212
+ function isMissingPathError(error: unknown): boolean {
213
+ const code = errorCode(error);
214
+ return code === "ENOENT" || code === "ENOTDIR";
215
+ }
216
+
217
+ function rejectUnknownFields(value: Record<string, unknown>, allowed: ReadonlySet<string>, scope: string): void {
218
+ const unknown = Object.keys(value).filter((key) => !allowed.has(key));
219
+ if (unknown.length > 0) {
220
+ throw new LspRequestContextParseError(
221
+ "unknown_field",
222
+ `Unknown LSP request ${scope} field: ${unknown.join(", ")}`,
223
+ );
224
+ }
225
+ }
226
+
227
+ function isRecord(value: unknown): value is Record<string, unknown> {
228
+ return typeof value === "object" && value !== null && !Array.isArray(value);
229
+ }
230
+
231
+ function errorCode(error: unknown): string | undefined {
232
+ if (!error || typeof error !== "object" || !("code" in error)) return undefined;
233
+ const code = Reflect.get(error, "code");
234
+ return typeof code === "string" ? code : undefined;
235
+ }
@@ -0,0 +1,173 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import { handleLspMcpRequest } from "./mcp.js";
4
+ import { createStandaloneMcpRequestContext, runWithRequestContext } from "./request-context.js";
5
+ import { coerceToolArguments, executeLspTool } from "./tools.js";
6
+
7
+ const expectedToolSurface = [
8
+ {
9
+ name: "status",
10
+ title: "LSP Status",
11
+ description: "List configured and active LSP servers without starting a new language server.",
12
+ inputSchema: { type: "object", properties: {}, required: [] },
13
+ },
14
+ {
15
+ name: "diagnostics",
16
+ title: "LSP Diagnostics",
17
+ description:
18
+ "Get errors, warnings, and hints for a source file or directory. In a Bun project, a TypeScript directory is typechecked with `bun check`, plus `bun lint` when the installed Bun has it.",
19
+ inputSchema: {
20
+ type: "object",
21
+ properties: {
22
+ filePath: { type: "string", description: "File or directory path to check." },
23
+ severity: {
24
+ type: "string",
25
+ enum: ["error", "warning", "information", "hint", "all"],
26
+ description: "Severity filter. Defaults to all.",
27
+ },
28
+ },
29
+ required: ["filePath"],
30
+ },
31
+ },
32
+ {
33
+ name: "goto_definition",
34
+ title: "LSP Goto Definition",
35
+ description: "Find where a symbol is defined.",
36
+ inputSchema: {
37
+ type: "object",
38
+ properties: {
39
+ filePath: { type: "string", description: "Source file containing the symbol." },
40
+ line: { type: "number", description: "1-based line number." },
41
+ character: { type: "number", description: "0-based column." },
42
+ },
43
+ required: ["filePath", "line", "character"],
44
+ },
45
+ },
46
+ {
47
+ name: "find_references",
48
+ title: "LSP Find References",
49
+ description: "Find references of a symbol across the workspace.",
50
+ inputSchema: {
51
+ type: "object",
52
+ properties: {
53
+ filePath: { type: "string", description: "Source file containing the symbol." },
54
+ line: { type: "number", description: "1-based line number." },
55
+ character: { type: "number", description: "0-based column." },
56
+ includeDeclaration: { type: "boolean", description: "Include the declaration. Defaults to true." },
57
+ },
58
+ required: ["filePath", "line", "character"],
59
+ },
60
+ },
61
+ {
62
+ name: "symbols",
63
+ title: "LSP Symbols",
64
+ description: "List document symbols or search workspace symbols.",
65
+ inputSchema: {
66
+ type: "object",
67
+ properties: {
68
+ filePath: { type: "string", description: "File path used as LSP context." },
69
+ scope: {
70
+ type: "string",
71
+ enum: ["document", "workspace"],
72
+ description: "Use document for file outline or workspace for project-wide search.",
73
+ },
74
+ query: { type: "string", description: "Workspace symbol query." },
75
+ limit: { type: "number", description: "Maximum number of symbols to return." },
76
+ },
77
+ required: ["filePath", "scope"],
78
+ },
79
+ },
80
+ {
81
+ name: "prepare_rename",
82
+ title: "LSP Prepare Rename",
83
+ description: "Check whether a symbol can be renamed at a position.",
84
+ inputSchema: {
85
+ type: "object",
86
+ properties: {
87
+ filePath: { type: "string", description: "Source file path." },
88
+ line: { type: "number", description: "1-based line number." },
89
+ character: { type: "number", description: "0-based column." },
90
+ },
91
+ required: ["filePath", "line", "character"],
92
+ },
93
+ },
94
+ {
95
+ name: "rename",
96
+ title: "LSP Rename",
97
+ description: "Rename a symbol across the workspace and apply the returned workspace edit.",
98
+ inputSchema: {
99
+ type: "object",
100
+ properties: {
101
+ filePath: { type: "string", description: "Source file path." },
102
+ line: { type: "number", description: "1-based line number." },
103
+ character: { type: "number", description: "0-based column." },
104
+ newName: { type: "string", description: "New symbol name." },
105
+ },
106
+ required: ["filePath", "line", "character", "newName"],
107
+ },
108
+ },
109
+ {
110
+ name: "format",
111
+ title: "LSP Format",
112
+ description: "Format a source file with its language server and write the returned edits to disk.",
113
+ inputSchema: {
114
+ type: "object",
115
+ properties: {
116
+ filePath: { type: "string", description: "Source file path to format." },
117
+ },
118
+ required: ["filePath"],
119
+ },
120
+ },
121
+ {
122
+ name: "install_decision",
123
+ title: "LSP Install Decision",
124
+ description:
125
+ "Record whether the user allowed or declined installing a missing LSP server. Record 'declined' when the user declines, or has not explicitly asked for LSP installation, to silence future prompts.",
126
+ inputSchema: {
127
+ type: "object",
128
+ properties: {
129
+ server_id: {
130
+ type: "string",
131
+ description: "The LSP server id from the not-installed message (e.g. 'rust').",
132
+ },
133
+ decision: {
134
+ type: "string",
135
+ enum: ["declined", "allowed"],
136
+ description: "'declined' silences future prompts; 'allowed' pre-authorizes installation.",
137
+ },
138
+ },
139
+ required: ["server_id", "decision"],
140
+ },
141
+ },
142
+ ];
143
+
144
+ describe("LSP core tool surface", () => {
145
+ test("#given a JSON-RPC tools/list request #when descriptors are returned #then the public nine-tool schemas are pinned", async () => {
146
+ // given
147
+ const request = { jsonrpc: "2.0", id: 21, method: "tools/list" };
148
+
149
+ // when
150
+ const response = await handleLspMcpRequest(request);
151
+
152
+ // then
153
+ expect(response?.result?.tools).toEqual(expectedToolSurface);
154
+ });
155
+
156
+ test("#given legacy tool aliases #when executed #then aliases are callable but not listed", async () => {
157
+ // given / when
158
+ const result = await runWithRequestContext(createStandaloneMcpRequestContext(), () =>
159
+ executeLspTool("lsp_diagnostics", { filePath: "module.wat" }),
160
+ );
161
+
162
+ // then
163
+ expect(result.content[0]?.text).toContain("No LSP server configured for extension: .wat");
164
+ const listResponse = await handleLspMcpRequest({ jsonrpc: "2.0", id: 23, method: "tools/list" });
165
+ expect(listResponse?.result?.tools?.map((tool: { name: string }) => tool.name)).not.toContain("lsp_diagnostics");
166
+ });
167
+
168
+ test("#given non-object tool arguments #when coerced #then they produce an empty argument record", () => {
169
+ // given / when / then
170
+ expect(coerceToolArguments(null)).toEqual({});
171
+ expect(coerceToolArguments(["filePath"])).toEqual({});
172
+ });
173
+ });