lazycodex-ai 5.1.48 → 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 (437) 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 -316
  225. package/packages/omo-codex/plugin/skills/ulw-research/references/deliverable-phase.md +23 -21
  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 +12 -5
  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 +13 -4
  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 +11 -1
  240. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-meaning.mjs +13 -9
  241. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-polish.mjs +40 -18
  242. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-verify.mjs +25 -8
  243. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands.mjs +35 -16
  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 +6 -4
  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 +4 -4
  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 +79 -26
  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 -316
  316. package/packages/shared-skills/skills/ulw-research/references/deliverable-phase.md +23 -21
  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 +12 -5
  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 +13 -4
  329. package/packages/shared-skills/skills/ulw-research/scripts/contracts.test.ts +6 -110
  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-polish.test.ts +4 -3
  336. package/packages/shared-skills/skills/ulw-research/scripts/css-hiding.mjs +158 -0
  337. package/packages/shared-skills/skills/ulw-research/scripts/css-lite.mjs +4 -2
  338. package/packages/shared-skills/skills/ulw-research/scripts/delivery-barrier-meaning.test.ts +186 -0
  339. package/packages/shared-skills/skills/ulw-research/scripts/delivery-barrier.test.ts +40 -87
  340. package/packages/shared-skills/skills/ulw-research/scripts/entities.mjs +13 -4
  341. package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-fill.mjs +11 -1
  342. package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-meaning.mjs +13 -9
  343. package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-polish.mjs +40 -18
  344. package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-verify.mjs +25 -8
  345. package/packages/shared-skills/skills/ulw-research/scripts/fact-commands.mjs +35 -16
  346. package/packages/shared-skills/skills/ulw-research/scripts/fact-derive-2.test.ts +149 -0
  347. package/packages/shared-skills/skills/ulw-research/scripts/fact-derive.mjs +7 -2
  348. package/packages/shared-skills/skills/ulw-research/scripts/fact-derive.test.ts +7 -192
  349. package/packages/shared-skills/skills/ulw-research/scripts/fact-fill.mjs +6 -4
  350. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-kinds.mjs +6 -7
  351. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-kinds.test.ts +2 -1
  352. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-legacy.test.ts +2 -1
  353. package/packages/shared-skills/skills/ulw-research/scripts/fact-locate.mjs +15 -9
  354. package/packages/shared-skills/skills/ulw-research/scripts/fact-unit-dimensions-2.test.ts +149 -0
  355. package/packages/shared-skills/skills/ulw-research/scripts/fact-unit-dimensions.test.ts +4 -168
  356. package/packages/shared-skills/skills/ulw-research/scripts/fact-unit-rules.test.ts +3 -229
  357. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-claims.mjs +4 -3
  358. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-csv.mjs +32 -0
  359. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-lexicon.mjs +1 -1
  360. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-originals.mjs +161 -0
  361. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-policy.mjs +4 -4
  362. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-records.mjs +81 -14
  363. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-snapshot-readability.mjs +49 -0
  364. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-sources.mjs +76 -0
  365. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-trace.mjs +25 -11
  366. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-value-unit.mjs +202 -0
  367. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-values.mjs +40 -39
  368. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-values.test.ts +8 -29
  369. package/packages/shared-skills/skills/ulw-research/scripts/gates-fidelity.mjs +8 -6
  370. package/packages/shared-skills/skills/ulw-research/scripts/gates-static-headings.test.ts +17 -0
  371. package/packages/shared-skills/skills/ulw-research/scripts/gates-static.mjs +10 -1
  372. package/packages/shared-skills/skills/ulw-research/scripts/html-lite.mjs +6 -2
  373. package/packages/shared-skills/skills/ulw-research/scripts/html-markup.mjs +2 -2
  374. package/packages/shared-skills/skills/ulw-research/scripts/html-text-map.mjs +140 -0
  375. package/packages/shared-skills/skills/ulw-research/scripts/html-text-map.test.ts +148 -0
  376. package/packages/shared-skills/skills/ulw-research/scripts/markdown-closers.mjs +126 -0
  377. package/packages/shared-skills/skills/ulw-research/scripts/md-lite-boundaries.test.ts +46 -0
  378. package/packages/shared-skills/skills/ulw-research/scripts/md-lite.mjs +1 -1
  379. package/packages/shared-skills/skills/ulw-research/scripts/number-grammar.mjs +33 -0
  380. package/packages/shared-skills/skills/ulw-research/scripts/number-grammar.test.ts +36 -0
  381. package/packages/shared-skills/skills/ulw-research/scripts/numerals.mjs +18 -7
  382. package/packages/shared-skills/skills/ulw-research/scripts/numerals.test.ts +3 -0
  383. package/packages/shared-skills/skills/ulw-research/scripts/outcome-start.mjs +66 -0
  384. package/packages/shared-skills/skills/ulw-research/scripts/outcome-start.test.ts +109 -0
  385. package/packages/shared-skills/skills/ulw-research/scripts/outcome.mjs +11 -22
  386. package/packages/shared-skills/skills/ulw-research/scripts/page-source-locator.test.ts +187 -0
  387. package/packages/shared-skills/skills/ulw-research/scripts/placeholder.mjs +18 -6
  388. package/packages/shared-skills/skills/ulw-research/scripts/polish-apply.mjs +3 -2
  389. package/packages/shared-skills/skills/ulw-research/scripts/polish-markup.test.ts +15 -1
  390. package/packages/shared-skills/skills/ulw-research/scripts/polish-partial.test.ts +42 -0
  391. package/packages/shared-skills/skills/ulw-research/scripts/raw-decode.mjs +110 -0
  392. package/packages/shared-skills/skills/ulw-research/scripts/raw-locator.mjs +47 -0
  393. package/packages/shared-skills/skills/ulw-research/scripts/raw-snapshot.test.ts +139 -0
  394. package/packages/shared-skills/skills/ulw-research/scripts/report-tools-2.test.ts +233 -0
  395. package/packages/shared-skills/skills/ulw-research/scripts/report-tools-3.test.ts +141 -0
  396. package/packages/shared-skills/skills/ulw-research/scripts/report-tools-4.test.ts +135 -0
  397. package/packages/shared-skills/skills/ulw-research/scripts/report-tools-5.test.ts +231 -0
  398. package/packages/shared-skills/skills/ulw-research/scripts/report-tools-commands.mjs +1 -1
  399. package/packages/shared-skills/skills/ulw-research/scripts/report-tools.mjs +7 -1
  400. package/packages/shared-skills/skills/ulw-research/scripts/report-tools.test.ts +5 -800
  401. package/packages/shared-skills/skills/ulw-research/scripts/snapshot-readability.test.ts +116 -0
  402. package/packages/shared-skills/skills/ulw-research/scripts/source-commands.mjs +79 -26
  403. package/packages/shared-skills/skills/ulw-research/scripts/source-integrity.test.ts +243 -0
  404. package/packages/shared-skills/skills/ulw-research/scripts/source-refresh.mjs +82 -0
  405. package/packages/shared-skills/skills/ulw-research/scripts/source-snapshot.mjs +73 -69
  406. package/packages/shared-skills/skills/ulw-research/scripts/source-snapshot.test.ts +7 -4
  407. package/packages/shared-skills/skills/ulw-research/scripts/source-view.mjs +89 -0
  408. package/packages/shared-skills/skills/ulw-research/scripts/sources-citation.mjs +203 -0
  409. package/packages/shared-skills/skills/ulw-research/scripts/sources-citation.test.ts +236 -0
  410. package/packages/shared-skills/skills/ulw-research/scripts/tests/contracts-support.ts +147 -0
  411. package/packages/shared-skills/skills/ulw-research/scripts/tests/delivery-barrier-session.ts +59 -0
  412. package/packages/shared-skills/skills/ulw-research/scripts/tests/derive-clock.ts +4 -0
  413. package/packages/shared-skills/skills/ulw-research/scripts/tests/fact-derive-support.ts +65 -0
  414. package/packages/shared-skills/skills/ulw-research/scripts/tests/fact-unit-dimensions-support.ts +41 -0
  415. package/packages/shared-skills/skills/ulw-research/scripts/tests/fact-unit-rules-support.ts +241 -0
  416. package/packages/shared-skills/skills/ulw-research/scripts/tests/fidelity-values-support.ts +30 -0
  417. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/conversion-probe.html +14 -0
  418. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/sources-shapes.html +20 -0
  419. package/packages/shared-skills/skills/ulw-research/scripts/tests/numeral-classes.ts +196 -0
  420. package/packages/shared-skills/skills/ulw-research/scripts/tests/report-tools-support.ts +182 -0
  421. package/packages/shared-skills/skills/ulw-research/scripts/tests/value-mode-support.ts +48 -0
  422. package/packages/shared-skills/skills/ulw-research/scripts/units.mjs +14 -3
  423. package/packages/shared-skills/skills/ulw-research/scripts/units.test.ts +10 -0
  424. package/packages/shared-skills/skills/ulw-research/scripts/value-mode-unit-classes.test.ts +255 -0
  425. package/packages/shared-skills/skills/ulw-research/scripts/value-mode-unit.test.ts +179 -0
  426. package/packages/shared-skills/skills/ulw-research/scripts/value-rules-cli.test.ts +157 -0
  427. package/packages/shared-skills/skills/ulw-research/scripts/value-rules-followups.test.ts +72 -0
  428. package/packages/shared-skills/skills/ulw-research/scripts/value-rules-priority.test.ts +80 -0
  429. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/amp_redirect_stub.html +0 -7
  430. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/search_interstitial.html +0 -19
  431. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/wayback_available.json +0 -1
  432. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/wayback_snapshot.html +0 -1128
  433. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_fetch_chain.py +0 -77
  434. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_stealth.py +0 -86
  435. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +0 -279
  436. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_surrogate.py +0 -252
  437. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_surrogate_validators.py +0 -78
@@ -0,0 +1,95 @@
1
+ import { pathToFileURL } from "node:url";
2
+
3
+ import { LspClientTransport } from "./transport.js";
4
+
5
+ interface InitializeCapabilities {
6
+ readonly diagnosticProvider?: unknown;
7
+ readonly documentFormattingProvider?: unknown;
8
+ }
9
+
10
+ function supportsDiagnosticPull(capabilities: InitializeCapabilities | undefined): boolean {
11
+ if (capabilities === undefined) return false;
12
+ return Object.hasOwn(capabilities, "diagnosticProvider");
13
+ }
14
+
15
+ /**
16
+ * Reads the whole-document formatting capability the server advertised at initialize time.
17
+ *
18
+ * The provider is either a boolean or an options object, and an explicit `false` means the
19
+ * server refuses the request, so both shapes are checked instead of mere key presence.
20
+ */
21
+ function supportsDocumentFormatting(capabilities: InitializeCapabilities | undefined): boolean {
22
+ if (capabilities === undefined) return false;
23
+ const provider = capabilities.documentFormattingProvider;
24
+ if (provider === undefined || provider === null || provider === false) return false;
25
+ return provider === true || typeof provider === "object";
26
+ }
27
+
28
+ export class LspClientConnection extends LspClientTransport {
29
+ async initialize(): Promise<void> {
30
+ const rootUri = pathToFileURL(this.root).href;
31
+ const result = await this.sendRequest<{ readonly capabilities?: InitializeCapabilities }>(
32
+ "initialize",
33
+ {
34
+ processId: process.pid,
35
+ rootUri,
36
+ rootPath: this.root,
37
+ workspaceFolders: [{ uri: rootUri, name: "workspace" }],
38
+ capabilities: {
39
+ textDocument: {
40
+ hover: { contentFormat: ["markdown", "plaintext"] },
41
+ definition: { linkSupport: true },
42
+ references: {},
43
+ documentSymbol: { hierarchicalDocumentSymbolSupport: true },
44
+ publishDiagnostics: {},
45
+ formatting: { dynamicRegistration: false },
46
+ rename: {
47
+ prepareSupport: true,
48
+ prepareSupportDefaultBehavior: 1,
49
+ },
50
+ codeAction: {
51
+ codeActionLiteralSupport: {
52
+ codeActionKind: {
53
+ valueSet: [
54
+ "quickfix",
55
+ "refactor",
56
+ "refactor.extract",
57
+ "refactor.inline",
58
+ "refactor.rewrite",
59
+ "source",
60
+ "source.organizeImports",
61
+ "source.fixAll",
62
+ ],
63
+ },
64
+ },
65
+ isPreferredSupport: true,
66
+ disabledSupport: true,
67
+ dataSupport: true,
68
+ resolveSupport: {
69
+ properties: ["edit", "command"],
70
+ },
71
+ },
72
+ },
73
+ workspace: {
74
+ symbol: {},
75
+ workspaceFolders: true,
76
+ configuration: true,
77
+ ...(this.hasWorkspaceApplyEditHandler() ? { applyEdit: true } : {}),
78
+ workspaceEdit: {
79
+ documentChanges: true,
80
+ resourceOperations: ["create", "rename", "delete"],
81
+ },
82
+ },
83
+ },
84
+ initializationOptions: this.server.initialization,
85
+ },
86
+ { timeoutMs: this.initializeTimeoutMs },
87
+ );
88
+ this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
89
+ this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
90
+ await this.sendNotification("initialized", {});
91
+ await this.sendNotification("workspace/didChangeConfiguration", {
92
+ settings: { json: { validate: { enable: true } } },
93
+ });
94
+ }
95
+ }
@@ -0,0 +1,17 @@
1
+ export const DEFAULT_MAX_REFERENCES = 200;
2
+ export const DEFAULT_MAX_SYMBOLS = 200;
3
+ export const DEFAULT_MAX_DIAGNOSTICS = 200;
4
+ export const DEFAULT_MAX_DIRECTORY_FILES = 50;
5
+
6
+ export const REQUEST_TIMEOUT_MS = 15_000;
7
+ export const INIT_TIMEOUT_MS = 60_000;
8
+ export const IDLE_TIMEOUT_MS = 5 * 60_000;
9
+ export const MAX_RESIDENT_CLIENTS = 6;
10
+ export const REAPER_INTERVAL_MS = 60_000;
11
+ export const STOP_HARD_KILL_TIMEOUT_MS = 5_000;
12
+ export const STOP_SIGKILL_GRACE_MS = 1_000;
13
+
14
+ /** Max consecutive dead client generations respawned for one key before admission is blocked. */
15
+ export const CLIENT_RESPAWN_RETRY_LIMIT = 2;
16
+ /** How long a spent respawn budget blocks admission before a fresh attempt window opens. */
17
+ export const CLIENT_RESPAWN_COOLDOWN_MS = 60_000;
@@ -0,0 +1,90 @@
1
+ import type { TimerProvider } from "./timer-provider.js";
2
+
3
+ interface ControlledTimer {
4
+ readonly at: number;
5
+ readonly callback: () => void;
6
+ cancelled: boolean;
7
+ }
8
+
9
+ interface TimerWaiter {
10
+ readonly delayMs: number | undefined;
11
+ readonly resolve: () => void;
12
+ }
13
+
14
+ interface ScheduleWaiter {
15
+ readonly count: number;
16
+ readonly resolve: () => void;
17
+ }
18
+
19
+ /**
20
+ * Deterministic TimerProvider for tests: timers fire only through advanceBy(),
21
+ * and waitForTimer(delayMs) resolves once a timer with exactly that delay is
22
+ * scheduled, so tests order themselves behind the timer they intend to fire.
23
+ */
24
+ export class ControlledClock implements TimerProvider {
25
+ private readonly timers: ControlledTimer[] = [];
26
+ private currentTime = 0;
27
+ private readonly timerWaiters = new Set<TimerWaiter>();
28
+ private readonly scheduleWaiters = new Set<ScheduleWaiter>();
29
+ readonly scheduledDelays: number[] = [];
30
+
31
+ readonly now = (): number => this.currentTime;
32
+ readonly setTimeout = (callback: () => void, delayMs: number): ReturnType<typeof setTimeout> => {
33
+ const timer: ControlledTimer = { at: this.currentTime + delayMs, callback, cancelled: false };
34
+ this.scheduledDelays.push(delayMs);
35
+ this.timers.push(timer);
36
+ for (const waiter of this.timerWaiters) {
37
+ if (waiter.delayMs === undefined || waiter.delayMs === delayMs) {
38
+ this.timerWaiters.delete(waiter);
39
+ waiter.resolve();
40
+ }
41
+ }
42
+ for (const waiter of this.scheduleWaiters) {
43
+ if (this.scheduledDelays.length >= waiter.count) {
44
+ this.scheduleWaiters.delete(waiter);
45
+ waiter.resolve();
46
+ }
47
+ }
48
+ return timer as unknown as ReturnType<typeof setTimeout>;
49
+ };
50
+ readonly clearTimeout = (handle: ReturnType<typeof setTimeout>): void => {
51
+ (handle as unknown as { cancelled: boolean }).cancelled = true;
52
+ };
53
+
54
+ waitForTimer(delayMs?: number): Promise<void> {
55
+ const hasTimer = this.timers.some(
56
+ (timer) => !timer.cancelled && (delayMs === undefined || timer.at === this.currentTime + delayMs),
57
+ );
58
+ if (hasTimer) return Promise.resolve();
59
+ return new Promise((resolve) => {
60
+ this.timerWaiters.add({ delayMs, resolve });
61
+ });
62
+ }
63
+
64
+ /**
65
+ * Resolves once this clock has been asked to schedule `count` timers in total.
66
+ *
67
+ * Timer DELAYS are ambiguous whenever the code under test derives several budgets from the same
68
+ * remaining window (an LSP request timeout and the push-fallback wait are both "whatever is left
69
+ * of the freshness window"). The schedule ORDER is not ambiguous: a step that only runs after an
70
+ * earlier request settled can only arm its timer once that request's own timer was cleared. So a
71
+ * test that must fire the LATER timer waits for the later schedule instead of a delay value, and
72
+ * never races the earlier one.
73
+ */
74
+ waitForScheduled(count: number): Promise<void> {
75
+ if (this.scheduledDelays.length >= count) return Promise.resolve();
76
+ return new Promise((resolve) => {
77
+ this.scheduleWaiters.add({ count, resolve });
78
+ });
79
+ }
80
+
81
+ advanceBy(delayMs: number): void {
82
+ this.currentTime += delayMs;
83
+ for (;;) {
84
+ const index = this.timers.findIndex((timer) => timer.at <= this.currentTime);
85
+ if (index < 0) return;
86
+ const timer = this.timers.splice(index, 1)[0];
87
+ if (timer && !timer.cancelled) timer.callback();
88
+ }
89
+ }
90
+ }
@@ -0,0 +1,221 @@
1
+ import { mkdtempSync, rmSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+
5
+ import { describe, expect, it } from "bun:test";
6
+
7
+ import { aggregateDiagnosticsForDirectory } from "./directory-diagnostics.js";
8
+ import { LspClient } from "./client.js";
9
+ import { LspManager } from "./manager.js";
10
+ import type { Diagnostic, ResolvedServer } from "./types.js";
11
+
12
+ describe("directory diagnostics", () => {
13
+ it("#given multiple files and one per-file failure #when directory diagnostics run #then work stays bounded and file failures stay structured", async () => {
14
+ const workspace = mkdtempSync(join(tmpdir(), "lsp-directory-diag-"));
15
+ const active: string[] = [];
16
+ let maxActive = 0;
17
+ const diagnosticsByFile = new Map<string, Diagnostic[] | Error>([
18
+ [join(workspace, "a.ts"), [diagnostic("a")]],
19
+ [join(workspace, "b.ts"), new Error("b failed")],
20
+ [join(workspace, "c.ts"), [diagnostic("c")]],
21
+ [join(workspace, "d.ts"), [diagnostic("d")]],
22
+ [join(workspace, "e.ts"), [diagnostic("e")]],
23
+ ]);
24
+ const client = {
25
+ async diagnostics(filePath: string) {
26
+ active.push(filePath);
27
+ maxActive = Math.max(maxActive, active.length);
28
+ await Promise.resolve();
29
+ active.splice(active.indexOf(filePath), 1);
30
+ const entry = diagnosticsByFile.get(filePath);
31
+ if (entry instanceof Error) throw entry;
32
+ return { items: entry ?? [] };
33
+ },
34
+ } as Pick<LspClient, "diagnostics"> as LspClient;
35
+ const server: ResolvedServer = { id: "typescript", command: ["typescript-language-server"], extensions: [".ts"], priority: 1 };
36
+ const manager = {
37
+ async getClient() {
38
+ return client;
39
+ },
40
+ releaseClient() {},
41
+ };
42
+
43
+ try {
44
+ const result = await aggregateDiagnosticsForDirectory(workspace, ".ts", "all", 4, {
45
+ manager: manager as never,
46
+ listFiles: () => [...diagnosticsByFile.keys()],
47
+ workspaceRoot: workspace,
48
+ server,
49
+ maxConcurrency: 2,
50
+ });
51
+
52
+ expect(maxActive).toBeLessThanOrEqual(2);
53
+ expect(result.fileFailures).toEqual([{ file: join(workspace, "b.ts"), error: "b failed" }]);
54
+ expect(result.totalDiagnostics).toBe(3);
55
+ expect(result.output).toContain("File processing errors:");
56
+ } finally {
57
+ rmSync(workspace, { recursive: true, force: true });
58
+ }
59
+ });
60
+
61
+ it("#given directory diagnostics are aborted after one file #when the worker loops #then no later file is scheduled", async () => {
62
+ const workspace = mkdtempSync(join(tmpdir(), "lsp-directory-diag-cancel-"));
63
+ const controller = new AbortController();
64
+ const visited: string[] = [];
65
+ const firstFile = join(workspace, "a.ts");
66
+ const files = [firstFile, join(workspace, "b.ts"), join(workspace, "c.ts")];
67
+ const client = {
68
+ async diagnostics(filePath: string) {
69
+ visited.push(filePath);
70
+ controller.abort();
71
+ return { items: [] };
72
+ },
73
+ } as Pick<LspClient, "diagnostics"> as LspClient;
74
+ const server: ResolvedServer = { id: "typescript", command: ["typescript-language-server"], extensions: [".ts"], priority: 1 };
75
+ const manager = {
76
+ async getClient() {
77
+ return client;
78
+ },
79
+ releaseClient() {},
80
+ };
81
+
82
+ try {
83
+ const result = await aggregateDiagnosticsForDirectory(workspace, ".ts", "all", 3, {
84
+ manager: manager as never,
85
+ listFiles: () => files,
86
+ workspaceRoot: workspace,
87
+ server,
88
+ maxConcurrency: 1,
89
+ signal: controller.signal,
90
+ });
91
+
92
+ expect(result.totalDiagnostics).toBe(0);
93
+ expect(visited).toEqual([firstFile]);
94
+ } finally {
95
+ rmSync(workspace, { recursive: true, force: true });
96
+ }
97
+ });
98
+
99
+ it("#given cold client acquisition is pending #when directory diagnostics are aborted #then acquisition settles and cleans up before startup releases", async () => {
100
+ const workspace = mkdtempSync(join(tmpdir(), "lsp-directory-diag-cold-cancel-"));
101
+ const controller = new AbortController();
102
+ const startupStarted = deferred();
103
+ const startupRelease = deferred();
104
+ const server: ResolvedServer = {
105
+ id: "typescript",
106
+ command: ["typescript-language-server"],
107
+ extensions: [".ts"],
108
+ priority: 1,
109
+ };
110
+ const client = new PendingStartLspClient({
111
+ root: workspace,
112
+ server,
113
+ startupStarted,
114
+ startupRelease,
115
+ });
116
+ const manager = new LspManager({
117
+ clientFactory: () => client,
118
+ reaperIntervalMs: 60_000,
119
+ });
120
+ const aggregation = aggregateDiagnosticsForDirectory(workspace, ".ts", "all", 1, {
121
+ manager,
122
+ listFiles: () => [join(workspace, "a.ts")],
123
+ workspaceRoot: workspace,
124
+ server,
125
+ signal: controller.signal,
126
+ });
127
+
128
+ try {
129
+ await startupStarted.promise;
130
+ controller.abort();
131
+
132
+ const settledBeforeStartupRelease = await settlesWithin(aggregation, 100);
133
+
134
+ expect(settledBeforeStartupRelease).toBe(true);
135
+ await expect(aggregation).rejects.toHaveProperty("name", "AbortError");
136
+ expect(manager.clientCount()).toBe(0);
137
+ expect(client.stopCallCount).toBe(1);
138
+ } finally {
139
+ startupRelease.resolve();
140
+ await aggregation.catch(() => undefined);
141
+ await manager.stopAll();
142
+ rmSync(workspace, { recursive: true, force: true });
143
+ }
144
+ });
145
+ });
146
+
147
+ class PendingStartLspClient extends LspClient {
148
+ stopCallCount = 0;
149
+ private readonly startupStarted: Deferred;
150
+ private readonly startupRelease: Deferred;
151
+
152
+ constructor(options: PendingStartLspClientOptions) {
153
+ super(options.root, options.server);
154
+ this.startupStarted = options.startupStarted;
155
+ this.startupRelease = options.startupRelease;
156
+ }
157
+
158
+ override async start(): Promise<void> {
159
+ this.startupStarted.resolve();
160
+ await this.startupRelease.promise;
161
+ }
162
+
163
+ override async initialize(): Promise<void> {}
164
+
165
+ override async stop(): Promise<void> {
166
+ this.stopCallCount += 1;
167
+ }
168
+
169
+ override isAlive(): boolean {
170
+ return true;
171
+ }
172
+
173
+ override async diagnostics(): Promise<{ readonly items: Diagnostic[] }> {
174
+ return { items: [] };
175
+ }
176
+ }
177
+
178
+ interface PendingStartLspClientOptions {
179
+ readonly root: string;
180
+ readonly server: ResolvedServer;
181
+ readonly startupStarted: Deferred;
182
+ readonly startupRelease: Deferred;
183
+ }
184
+
185
+ interface Deferred {
186
+ readonly promise: Promise<void>;
187
+ resolve(): void;
188
+ }
189
+
190
+ function deferred(): Deferred {
191
+ let resolvePromise: (() => void) | undefined;
192
+ const promise = new Promise<void>((resolve) => {
193
+ resolvePromise = resolve;
194
+ });
195
+ return { promise, resolve: () => resolvePromise?.() };
196
+ }
197
+
198
+ async function settlesWithin(promise: Promise<unknown>, timeoutMs: number): Promise<boolean> {
199
+ let timer: ReturnType<typeof setTimeout> | undefined;
200
+ try {
201
+ return await Promise.race([
202
+ promise.then(
203
+ () => true,
204
+ () => true,
205
+ ),
206
+ new Promise<boolean>((resolve) => {
207
+ timer = setTimeout(() => resolve(false), timeoutMs);
208
+ timer.unref();
209
+ }),
210
+ ]);
211
+ } finally {
212
+ if (timer !== undefined) clearTimeout(timer);
213
+ }
214
+ }
215
+
216
+ function diagnostic(message: string): Diagnostic {
217
+ return {
218
+ range: { start: { line: 0, character: 0 }, end: { line: 0, character: 1 } },
219
+ message,
220
+ };
221
+ }
@@ -0,0 +1,187 @@
1
+ import { existsSync, lstatSync, readdirSync, type Stats } from "node:fs";
2
+ import { join, resolve } from "node:path";
3
+ import { contextCwd } from "../request-context.js";
4
+ import { findWorkspaceRoot, formatServerLookupError } from "./client-wrapper.js";
5
+ import { DEFAULT_MAX_DIAGNOSTICS, DEFAULT_MAX_DIRECTORY_FILES } from "./constants.js";
6
+ import { effectiveExtension } from "./effective-extension.js";
7
+ import { LspInvalidPathError, LspServerLookupError } from "./errors.js";
8
+ import { filterDiagnosticsBySeverity, formatDiagnostic } from "./formatters.js";
9
+ import { getLspManager, type LspManager } from "./manager.js";
10
+ import { findServerForExtension } from "./server-resolution.js";
11
+ import type { Diagnostic, ResolvedServer, SeverityFilter } from "./types.js";
12
+
13
+ const SKIP_DIRECTORIES = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
14
+ const DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY = 4;
15
+
16
+ interface FileDiagnostic {
17
+ filePath: string;
18
+ diagnostic: Diagnostic;
19
+ }
20
+
21
+ export interface DirectoryDiagnosticsFileFailure {
22
+ readonly file: string;
23
+ readonly error: string;
24
+ }
25
+
26
+ export interface DirectoryDiagnosticsResult {
27
+ readonly output: string;
28
+ readonly totalDiagnostics: number;
29
+ readonly fileFailures: readonly DirectoryDiagnosticsFileFailure[];
30
+ }
31
+
32
+ export interface DirectoryDiagnosticsOptions {
33
+ readonly listFiles?: (directory: string, extension: string, maxFiles: number) => string[];
34
+ readonly manager?: LspManager;
35
+ readonly maxConcurrency?: number;
36
+ readonly workspaceRoot?: string;
37
+ readonly server?: ResolvedServer;
38
+ readonly signal?: AbortSignal;
39
+ }
40
+
41
+ export function collectFilesWithExtension(dir: string, extension: string, maxFiles: number): string[] {
42
+ const files: string[] = [];
43
+
44
+ function walk(currentDir: string): void {
45
+ if (files.length >= maxFiles) return;
46
+
47
+ let entries: string[] = [];
48
+ try {
49
+ entries = readdirSync(currentDir);
50
+ } catch {
51
+ return;
52
+ }
53
+
54
+ for (const entry of entries) {
55
+ if (files.length >= maxFiles) return;
56
+
57
+ const fullPath = join(currentDir, entry);
58
+
59
+ let stat: Stats | undefined;
60
+ try {
61
+ stat = lstatSync(fullPath);
62
+ } catch {
63
+ continue;
64
+ }
65
+
66
+ if (!stat || stat.isSymbolicLink()) continue;
67
+
68
+ if (stat.isDirectory()) {
69
+ if (!SKIP_DIRECTORIES.has(entry)) {
70
+ walk(fullPath);
71
+ }
72
+ } else if (stat.isFile() && effectiveExtension(fullPath) === extension) {
73
+ files.push(fullPath);
74
+ }
75
+ }
76
+ }
77
+
78
+ walk(dir);
79
+ return files;
80
+ }
81
+
82
+ export async function aggregateDiagnosticsForDirectory(
83
+ directory: string,
84
+ extension: string,
85
+ severity?: SeverityFilter,
86
+ maxFiles: number = DEFAULT_MAX_DIRECTORY_FILES,
87
+ options: DirectoryDiagnosticsOptions = {},
88
+ ): Promise<DirectoryDiagnosticsResult> {
89
+ if (!extension.startsWith(".")) {
90
+ throw new LspInvalidPathError(
91
+ `Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`,
92
+ );
93
+ }
94
+
95
+ const absDir = resolve(options.workspaceRoot ?? contextCwd(), directory);
96
+ if (!existsSync(absDir)) {
97
+ throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
98
+ }
99
+
100
+ const serverResult = options.server === undefined ? findServerForExtension(extension) : { status: "found" as const, server: options.server };
101
+ if (serverResult.status !== "found") {
102
+ throw new LspServerLookupError(formatServerLookupError(serverResult));
103
+ }
104
+
105
+ const server = serverResult.server;
106
+ const allFiles = (options.listFiles ?? collectFilesWithExtension)(absDir, extension, maxFiles + 1);
107
+ const wasCapped = allFiles.length > maxFiles;
108
+ const filesToProcess = allFiles.slice(0, maxFiles);
109
+
110
+ if (filesToProcess.length === 0) {
111
+ const output = [
112
+ `Directory: ${absDir}`,
113
+ `Extension: ${extension}`,
114
+ "Files scanned: 0",
115
+ `No files found with extension "${extension}".`,
116
+ ].join("\n");
117
+ return { output, totalDiagnostics: 0, fileFailures: [] };
118
+ }
119
+
120
+ const root = options.workspaceRoot ?? findWorkspaceRoot(absDir);
121
+ const manager = options.manager ?? getLspManager();
122
+ const allDiagnostics: FileDiagnostic[] = [];
123
+ const fileErrors: DirectoryDiagnosticsFileFailure[] = [];
124
+ const maxConcurrency = Math.max(1, options.maxConcurrency ?? DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY);
125
+
126
+ options.signal?.throwIfAborted();
127
+ const client = await manager.getClient(root, server, options.signal);
128
+ try {
129
+ let nextIndex = 0;
130
+ const workers = Array.from({ length: Math.min(maxConcurrency, filesToProcess.length) }, async () => {
131
+ for (;;) {
132
+ if (options.signal?.aborted) return;
133
+ const file = filesToProcess[nextIndex];
134
+ nextIndex += 1;
135
+ if (file === undefined) return;
136
+ try {
137
+ const result = await client.diagnostics(file, options.signal);
138
+ const filtered = filterDiagnosticsBySeverity(result.items, severity);
139
+ allDiagnostics.push(
140
+ ...filtered.map((diagnostic) => ({
141
+ filePath: file,
142
+ diagnostic,
143
+ })),
144
+ );
145
+ } catch (e) {
146
+ fileErrors.push({
147
+ file,
148
+ error: e instanceof Error ? e.message : String(e),
149
+ });
150
+ }
151
+ }
152
+ });
153
+ await Promise.all(workers);
154
+ } finally {
155
+ manager.releaseClient(root, server.id);
156
+ }
157
+
158
+ const displayDiagnostics = allDiagnostics.slice(0, DEFAULT_MAX_DIAGNOSTICS);
159
+ const wasDiagCapped = allDiagnostics.length > DEFAULT_MAX_DIAGNOSTICS;
160
+
161
+ const lines: string[] = [
162
+ `Directory: ${absDir}`,
163
+ `Extension: ${extension}`,
164
+ `Files scanned: ${filesToProcess.length}${wasCapped ? ` (capped at ${maxFiles})` : ""}`,
165
+ `Files with errors: ${fileErrors.length}`,
166
+ `Total diagnostics: ${allDiagnostics.length}`,
167
+ ];
168
+
169
+ if (fileErrors.length > 0) {
170
+ lines.push("", "File processing errors:");
171
+ for (const { file, error } of fileErrors) {
172
+ lines.push(` ${file}: ${error}`);
173
+ }
174
+ }
175
+
176
+ if (displayDiagnostics.length > 0) {
177
+ lines.push("");
178
+ for (const { filePath, diagnostic } of displayDiagnostics) {
179
+ lines.push(`${filePath}: ${formatDiagnostic(diagnostic)}`);
180
+ }
181
+ if (wasDiagCapped) {
182
+ lines.push("", `... (${allDiagnostics.length - DEFAULT_MAX_DIAGNOSTICS} more diagnostics not shown)`);
183
+ }
184
+ }
185
+
186
+ return { output: lines.join("\n"), totalDiagnostics: allDiagnostics.length, fileFailures: fileErrors };
187
+ }
@@ -0,0 +1,10 @@
1
+ import { basename, extname } from "node:path";
2
+
3
+ const BASENAME_EXTENSIONS: Record<string, string> = {
4
+ Dockerfile: ".dockerfile",
5
+ Containerfile: ".dockerfile",
6
+ };
7
+
8
+ export function effectiveExtension(filePath: string): string {
9
+ return BASENAME_EXTENSIONS[basename(filePath)] ?? extname(filePath);
10
+ }