oh-my-opencode 4.8.0 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (512) hide show
  1. package/dist/agents/prometheus/system-prompt.d.ts +1 -1
  2. package/dist/agents/sisyphus/claude-fable-5.d.ts +19 -0
  3. package/dist/agents/sisyphus/claude-opus-4-7.d.ts +3 -1
  4. package/dist/agents/sisyphus/claude-opus-4-8.d.ts +19 -0
  5. package/dist/agents/sisyphus/index.d.ts +4 -0
  6. package/dist/agents/types.d.ts +2 -2
  7. package/dist/cli/doctor/checks/codex.d.ts +1 -0
  8. package/dist/cli/doctor/checks/tools-gh.d.ts +8 -1
  9. package/dist/cli/doctor/index.d.ts +1 -0
  10. package/dist/cli/doctor/types.d.ts +2 -0
  11. package/dist/cli/index.js +1922 -785
  12. package/dist/cli/install-codex/codex-config-permissions.d.ts +1 -1
  13. package/dist/cli/install-codex/codex-config-plugins.d.ts +1 -0
  14. package/dist/cli/install-codex/codex-config-toml.d.ts +1 -0
  15. package/dist/cli/install-codex/codex-installer-bin-dir.d.ts +8 -0
  16. package/dist/cli/install-codex/codex-multi-agent-v2-config.d.ts +11 -0
  17. package/dist/cli/install-codex/install-codex.d.ts +1 -8
  18. package/dist/cli/install-codex/lsp-daemon-reaper.d.ts +5 -0
  19. package/dist/cli/run/runnable-agent-resolver.d.ts +11 -0
  20. package/dist/cli/sparkshell-condense.d.ts +10 -0
  21. package/dist/cli/sparkshell-parse.d.ts +3 -0
  22. package/dist/cli/sparkshell-session-context.d.ts +20 -0
  23. package/dist/cli/sparkshell-spark.d.ts +23 -0
  24. package/dist/cli/sparkshell.d.ts +8 -1
  25. package/dist/cli-node/index.js +92552 -0
  26. package/dist/config/schema/agent-names.d.ts +2 -0
  27. package/dist/config/schema/hooks.d.ts +0 -2
  28. package/dist/config/schema/keyword-detector.d.ts +0 -6
  29. package/dist/config/schema/oh-my-opencode-config.d.ts +2 -4
  30. package/dist/create-hooks.d.ts +0 -2
  31. package/dist/features/background-agent/parent-wake-dedupe.d.ts +2 -0
  32. package/dist/features/background-agent/parent-wake-flush-runner.d.ts +2 -0
  33. package/dist/features/background-agent/parent-wake-prompt-dispatch.d.ts +1 -0
  34. package/dist/features/background-agent/parent-wake-session-history.d.ts +4 -0
  35. package/dist/features/background-agent/parent-wake-session-inspector.d.ts +1 -0
  36. package/dist/features/builtin-commands/templates/handoff.d.ts +1 -1
  37. package/dist/features/builtin-skills/index.d.ts +1 -1
  38. package/dist/features/builtin-skills/skills.d.ts +4 -0
  39. package/dist/features/opencode-runtime-skills/source-server.d.ts +16 -1
  40. package/dist/features/opencode-skill-loader/skill-definition-record.d.ts +2 -0
  41. package/dist/features/team-mode/tools/lifecycle-test-fixture.d.ts +2 -0
  42. package/dist/features/team-mode/types.d.ts +1 -0
  43. package/dist/features/tmux-subagent/failed-readiness-cache.d.ts +28 -0
  44. package/dist/features/tmux-subagent/manager.d.ts +1 -9
  45. package/dist/features/tmux-subagent/resolve-server-url.d.ts +3 -0
  46. package/dist/hooks/anthropic-context-window-limit-recovery/executor.d.ts +1 -1
  47. package/dist/hooks/index.d.ts +0 -1
  48. package/dist/hooks/keyword-detector/constants.d.ts +0 -4
  49. package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +1 -1
  50. package/dist/index.js +9001 -1795
  51. package/dist/oh-my-opencode.schema.json +2 -4
  52. package/dist/plugin/chat-params.d.ts +1 -8
  53. package/dist/plugin/hooks/create-core-hooks.d.ts +0 -2
  54. package/dist/plugin/hooks/create-session-hooks.d.ts +0 -2
  55. package/dist/plugin/hooks/create-transform-hooks.d.ts +1 -2
  56. package/dist/plugin/messages-transform.d.ts +0 -1
  57. package/dist/shared/model-availability.d.ts +10 -2
  58. package/package.json +25 -18
  59. package/packages/ast-grep-mcp/dist/cli.js +2 -10
  60. package/packages/git-bash-mcp/dist/cli.js +11 -4
  61. package/packages/lsp-daemon/dist/cli.d.ts +2 -0
  62. package/packages/lsp-daemon/dist/cli.js +3711 -0
  63. package/packages/lsp-daemon/dist/daemon-client.d.ts +19 -0
  64. package/packages/lsp-daemon/dist/daemon-client.js +114 -0
  65. package/packages/lsp-daemon/dist/daemon-server.d.ts +12 -0
  66. package/packages/lsp-daemon/dist/daemon-server.js +106 -0
  67. package/packages/lsp-daemon/dist/ensure-daemon.d.ts +21 -0
  68. package/packages/lsp-daemon/dist/ensure-daemon.js +97 -0
  69. package/packages/lsp-daemon/dist/index.d.ts +5 -0
  70. package/packages/lsp-daemon/dist/index.js +3573 -0
  71. package/packages/lsp-daemon/dist/lock.d.ts +7 -0
  72. package/packages/lsp-daemon/dist/lock.js +61 -0
  73. package/packages/lsp-daemon/dist/package.json +6 -0
  74. package/packages/lsp-daemon/dist/paths.d.ts +11 -0
  75. package/packages/lsp-daemon/dist/paths.js +49 -0
  76. package/packages/lsp-daemon/dist/proxy.d.ts +10 -0
  77. package/packages/lsp-daemon/dist/proxy.js +61 -0
  78. package/packages/lsp-daemon/dist/request-routing.d.ts +9 -0
  79. package/packages/lsp-daemon/dist/request-routing.js +44 -0
  80. package/packages/lsp-daemon/dist/run-daemon.d.ts +1 -0
  81. package/packages/lsp-daemon/dist/run-daemon.js +11 -0
  82. package/packages/lsp-daemon/dist/socket-jsonrpc.d.ts +5 -0
  83. package/packages/lsp-daemon/dist/socket-jsonrpc.js +25 -0
  84. package/packages/lsp-daemon/package.json +38 -0
  85. package/packages/lsp-tools-mcp/dist/cli.js +0 -0
  86. package/packages/lsp-tools-mcp/dist/lsp/client-wrapper.js +40 -17
  87. package/packages/lsp-tools-mcp/dist/lsp/client.js +11 -9
  88. package/packages/lsp-tools-mcp/dist/lsp/config-loader.js +5 -5
  89. package/packages/lsp-tools-mcp/dist/lsp/directory-diagnostics.js +5 -3
  90. package/packages/lsp-tools-mcp/dist/lsp/effective-extension.d.ts +1 -0
  91. package/packages/lsp-tools-mcp/dist/lsp/effective-extension.js +8 -0
  92. package/packages/lsp-tools-mcp/dist/lsp/infer-extension.js +3 -2
  93. package/packages/lsp-tools-mcp/dist/lsp/language-mappings.js +1 -0
  94. package/packages/lsp-tools-mcp/dist/lsp/server-definitions.js +12 -0
  95. package/packages/lsp-tools-mcp/dist/lsp/server-install-state.d.ts +12 -0
  96. package/packages/lsp-tools-mcp/dist/lsp/server-install-state.js +51 -0
  97. package/packages/lsp-tools-mcp/dist/lsp/workspace-edit.js +2 -1
  98. package/packages/lsp-tools-mcp/dist/request-context.d.ts +7 -0
  99. package/packages/lsp-tools-mcp/dist/request-context.js +14 -0
  100. package/packages/lsp-tools-mcp/dist/tools.js +44 -1
  101. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +46 -33
  102. package/packages/omo-codex/plugin/.mcp.json +1 -1
  103. package/packages/omo-codex/plugin/components/comment-checker/dist/apply-patch.d.ts +7 -0
  104. package/packages/omo-codex/plugin/components/comment-checker/dist/apply-patch.js +173 -0
  105. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.d.ts +2 -0
  106. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +10 -0
  107. package/packages/omo-codex/plugin/components/comment-checker/dist/codex-hook.d.ts +22 -0
  108. package/packages/omo-codex/plugin/components/comment-checker/dist/codex-hook.js +165 -0
  109. package/packages/omo-codex/plugin/components/comment-checker/dist/core-values.d.ts +1 -0
  110. package/packages/omo-codex/plugin/components/comment-checker/dist/core-values.js +1 -0
  111. package/packages/omo-codex/plugin/components/comment-checker/dist/core.d.ts +5 -0
  112. package/packages/omo-codex/plugin/components/comment-checker/dist/core.js +4 -0
  113. package/packages/omo-codex/plugin/components/comment-checker/dist/hook-input.d.ts +6 -0
  114. package/packages/omo-codex/plugin/components/comment-checker/dist/hook-input.js +10 -0
  115. package/packages/omo-codex/plugin/components/comment-checker/dist/record.d.ts +2 -0
  116. package/packages/omo-codex/plugin/components/comment-checker/dist/record.js +11 -0
  117. package/packages/omo-codex/plugin/components/comment-checker/dist/request-extractor.d.ts +3 -0
  118. package/packages/omo-codex/plugin/components/comment-checker/dist/request-extractor.js +104 -0
  119. package/packages/omo-codex/plugin/components/comment-checker/dist/runner.d.ts +26 -0
  120. package/packages/omo-codex/plugin/components/comment-checker/dist/runner.js +144 -0
  121. package/packages/omo-codex/plugin/components/comment-checker/dist/types.d.ts +43 -0
  122. package/packages/omo-codex/plugin/components/comment-checker/dist/types.js +1 -0
  123. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  124. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  125. package/packages/omo-codex/plugin/components/git-bash/dist/cli.d.ts +2 -0
  126. package/packages/omo-codex/plugin/components/git-bash/dist/cli.js +29 -0
  127. package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.d.ts +28 -0
  128. package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.js +137 -0
  129. package/packages/omo-codex/plugin/components/git-bash/dist/index.d.ts +1 -0
  130. package/packages/omo-codex/plugin/components/git-bash/dist/index.js +1 -0
  131. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  132. package/packages/omo-codex/plugin/components/git-bash/package.json +5 -2
  133. package/packages/omo-codex/plugin/components/lsp/.mcp.json +1 -1
  134. package/packages/omo-codex/plugin/components/lsp/dist/cli.d.ts +2 -0
  135. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +42 -0
  136. package/packages/omo-codex/plugin/components/lsp/dist/codex-hook-cli.d.ts +2 -0
  137. package/packages/omo-codex/plugin/components/lsp/dist/codex-hook-cli.js +40 -0
  138. package/packages/omo-codex/plugin/components/lsp/dist/codex-hook.d.ts +16 -0
  139. package/packages/omo-codex/plugin/components/lsp/dist/codex-hook.js +180 -0
  140. package/packages/omo-codex/plugin/components/lsp/dist/lsp-session-state.d.ts +12 -0
  141. package/packages/omo-codex/plugin/components/lsp/dist/lsp-session-state.js +95 -0
  142. package/packages/omo-codex/plugin/components/lsp/dist/mutated-file-paths.d.ts +6 -0
  143. package/packages/omo-codex/plugin/components/lsp/dist/mutated-file-paths.js +79 -0
  144. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  145. package/packages/omo-codex/plugin/components/lsp/package.json +7 -7
  146. package/packages/omo-codex/plugin/components/lsp/scripts/build-lsp-daemon.mjs +68 -0
  147. package/packages/omo-codex/plugin/components/lsp/scripts/build-lsp-tools.mjs +45 -22
  148. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  149. package/packages/omo-codex/plugin/components/lsp/src/codex-hook-cli.ts +1 -1
  150. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +6 -2
  151. package/packages/omo-codex/plugin/components/lsp/src/lsp-session-state.ts +4 -0
  152. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +68 -0
  153. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +8 -20
  154. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus.md +69 -96
  155. package/packages/omo-codex/plugin/components/rules/dist/cli.d.ts +2 -0
  156. package/packages/omo-codex/plugin/components/rules/dist/cli.js +118 -0
  157. package/packages/omo-codex/plugin/components/rules/dist/codex-hook-options.d.ts +5 -0
  158. package/packages/omo-codex/plugin/components/rules/dist/codex-hook-options.js +1 -0
  159. package/packages/omo-codex/plugin/components/rules/dist/codex-hook.d.ts +47 -0
  160. package/packages/omo-codex/plugin/components/rules/dist/codex-hook.js +127 -0
  161. package/packages/omo-codex/plugin/components/rules/dist/config.d.ts +2 -0
  162. package/packages/omo-codex/plugin/components/rules/dist/config.js +100 -0
  163. package/packages/omo-codex/plugin/components/rules/dist/context-pressure.d.ts +2 -0
  164. package/packages/omo-codex/plugin/components/rules/dist/context-pressure.js +26 -0
  165. package/packages/omo-codex/plugin/components/rules/dist/debug-log.d.ts +8 -0
  166. package/packages/omo-codex/plugin/components/rules/dist/debug-log.js +36 -0
  167. package/packages/omo-codex/plugin/components/rules/dist/dynamic-target-fingerprints.d.ts +7 -0
  168. package/packages/omo-codex/plugin/components/rules/dist/dynamic-target-fingerprints.js +65 -0
  169. package/packages/omo-codex/plugin/components/rules/dist/event-budget.d.ts +3 -0
  170. package/packages/omo-codex/plugin/components/rules/dist/event-budget.js +14 -0
  171. package/packages/omo-codex/plugin/components/rules/dist/hook-output.d.ts +2 -0
  172. package/packages/omo-codex/plugin/components/rules/dist/hook-output.js +24 -0
  173. package/packages/omo-codex/plugin/components/rules/dist/path-utils.d.ts +4 -0
  174. package/packages/omo-codex/plugin/components/rules/dist/path-utils.js +24 -0
  175. package/packages/omo-codex/plugin/components/rules/dist/persistent-cache.d.ts +13 -0
  176. package/packages/omo-codex/plugin/components/rules/dist/persistent-cache.js +172 -0
  177. package/packages/omo-codex/plugin/components/rules/dist/post-compact-budget.d.ts +6 -0
  178. package/packages/omo-codex/plugin/components/rules/dist/post-compact-budget.js +74 -0
  179. package/packages/omo-codex/plugin/components/rules/dist/post-compact-claim.d.ts +4 -0
  180. package/packages/omo-codex/plugin/components/rules/dist/post-compact-claim.js +6 -0
  181. package/packages/omo-codex/plugin/components/rules/dist/post-compact-directive.d.ts +1 -0
  182. package/packages/omo-codex/plugin/components/rules/dist/post-compact-directive.js +32 -0
  183. package/packages/omo-codex/plugin/components/rules/dist/post-compact-state.d.ts +13 -0
  184. package/packages/omo-codex/plugin/components/rules/dist/post-compact-state.js +29 -0
  185. package/packages/omo-codex/plugin/components/rules/dist/rules/cache.d.ts +9 -0
  186. package/packages/omo-codex/plugin/components/rules/dist/rules/cache.js +51 -0
  187. package/packages/omo-codex/plugin/components/rules/dist/rules/constants.d.ts +70 -0
  188. package/packages/omo-codex/plugin/components/rules/dist/rules/constants.js +101 -0
  189. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-cache.d.ts +5 -0
  190. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-cache.js +60 -0
  191. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-loader.d.ts +6 -0
  192. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-loader.js +61 -0
  193. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-loader.d.ts +7 -0
  194. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-loader.js +60 -0
  195. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-paths.d.ts +11 -0
  196. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-paths.js +75 -0
  197. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-static-loader.d.ts +6 -0
  198. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-static-loader.js +29 -0
  199. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-types.d.ts +44 -0
  200. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-types.js +1 -0
  201. package/packages/omo-codex/plugin/components/rules/dist/rules/engine.d.ts +5 -0
  202. package/packages/omo-codex/plugin/components/rules/dist/rules/engine.js +85 -0
  203. package/packages/omo-codex/plugin/components/rules/dist/rules/errors.d.ts +6 -0
  204. package/packages/omo-codex/plugin/components/rules/dist/rules/errors.js +12 -0
  205. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-cache.d.ts +14 -0
  206. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-cache.js +51 -0
  207. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-paths.d.ts +6 -0
  208. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-paths.js +33 -0
  209. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-sources.d.ts +5 -0
  210. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-sources.js +40 -0
  211. package/packages/omo-codex/plugin/components/rules/dist/rules/finder.d.ts +28 -0
  212. package/packages/omo-codex/plugin/components/rules/dist/rules/finder.js +146 -0
  213. package/packages/omo-codex/plugin/components/rules/dist/rules/formatter.d.ts +7 -0
  214. package/packages/omo-codex/plugin/components/rules/dist/rules/formatter.js +112 -0
  215. package/packages/omo-codex/plugin/components/rules/dist/rules/matcher.d.ts +18 -0
  216. package/packages/omo-codex/plugin/components/rules/dist/rules/matcher.js +93 -0
  217. package/packages/omo-codex/plugin/components/rules/dist/rules/ordering.d.ts +3 -0
  218. package/packages/omo-codex/plugin/components/rules/dist/rules/ordering.js +27 -0
  219. package/packages/omo-codex/plugin/components/rules/dist/rules/parser-frontmatter.d.ts +7 -0
  220. package/packages/omo-codex/plugin/components/rules/dist/rules/parser-frontmatter.js +30 -0
  221. package/packages/omo-codex/plugin/components/rules/dist/rules/parser-yaml.d.ts +2 -0
  222. package/packages/omo-codex/plugin/components/rules/dist/rules/parser-yaml.js +237 -0
  223. package/packages/omo-codex/plugin/components/rules/dist/rules/parser.d.ts +3 -0
  224. package/packages/omo-codex/plugin/components/rules/dist/rules/parser.js +31 -0
  225. package/packages/omo-codex/plugin/components/rules/dist/rules/plugin-root.d.ts +1 -0
  226. package/packages/omo-codex/plugin/components/rules/dist/rules/plugin-root.js +48 -0
  227. package/packages/omo-codex/plugin/components/rules/dist/rules/project-root.d.ts +1 -0
  228. package/packages/omo-codex/plugin/components/rules/dist/rules/project-root.js +23 -0
  229. package/packages/omo-codex/plugin/components/rules/dist/rules/scanner.d.ts +14 -0
  230. package/packages/omo-codex/plugin/components/rules/dist/rules/scanner.js +111 -0
  231. package/packages/omo-codex/plugin/components/rules/dist/rules/sources.d.ts +3 -0
  232. package/packages/omo-codex/plugin/components/rules/dist/rules/sources.js +9 -0
  233. package/packages/omo-codex/plugin/components/rules/dist/rules/truncator.d.ts +18 -0
  234. package/packages/omo-codex/plugin/components/rules/dist/rules/truncator.js +59 -0
  235. package/packages/omo-codex/plugin/components/rules/dist/rules/types.d.ts +126 -0
  236. package/packages/omo-codex/plugin/components/rules/dist/rules/types.js +8 -0
  237. package/packages/omo-codex/plugin/components/rules/dist/rules-engine-factory.d.ts +6 -0
  238. package/packages/omo-codex/plugin/components/rules/dist/rules-engine-factory.js +20 -0
  239. package/packages/omo-codex/plugin/components/rules/dist/session-state-lock.d.ts +3 -0
  240. package/packages/omo-codex/plugin/components/rules/dist/session-state-lock.js +41 -0
  241. package/packages/omo-codex/plugin/components/rules/dist/sparkshell-awareness.d.ts +10 -0
  242. package/packages/omo-codex/plugin/components/rules/dist/sparkshell-awareness.js +90 -0
  243. package/packages/omo-codex/plugin/components/rules/dist/static-injection.d.ts +3 -0
  244. package/packages/omo-codex/plugin/components/rules/dist/static-injection.js +128 -0
  245. package/packages/omo-codex/plugin/components/rules/dist/tool-paths.d.ts +6 -0
  246. package/packages/omo-codex/plugin/components/rules/dist/tool-paths.js +168 -0
  247. package/packages/omo-codex/plugin/components/rules/dist/transcript-rule-filter.d.ts +4 -0
  248. package/packages/omo-codex/plugin/components/rules/dist/transcript-rule-filter.js +49 -0
  249. package/packages/omo-codex/plugin/components/rules/dist/transcript-search.d.ts +4 -0
  250. package/packages/omo-codex/plugin/components/rules/dist/transcript-search.js +91 -0
  251. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  252. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  253. package/packages/omo-codex/plugin/components/rules/src/codex-hook.ts +4 -2
  254. package/packages/omo-codex/plugin/components/rules/src/config.ts +13 -0
  255. package/packages/omo-codex/plugin/components/rules/src/event-budget.ts +17 -0
  256. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +4 -1
  257. package/packages/omo-codex/plugin/components/rules/src/post-compact-directive.ts +39 -0
  258. package/packages/omo-codex/plugin/components/rules/src/rules/constants.ts +16 -0
  259. package/packages/omo-codex/plugin/components/rules/src/rules/engine.ts +8 -0
  260. package/packages/omo-codex/plugin/components/rules/src/rules/formatter.ts +7 -8
  261. package/packages/omo-codex/plugin/components/rules/src/rules/truncator.ts +17 -0
  262. package/packages/omo-codex/plugin/components/rules/src/rules/types.ts +4 -0
  263. package/packages/omo-codex/plugin/components/rules/src/sparkshell-awareness.ts +53 -4
  264. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +127 -7
  265. package/packages/omo-codex/plugin/components/rules/src/transcript-rule-filter.ts +9 -1
  266. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +4 -2
  267. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +7 -2
  268. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +9 -9
  269. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +10 -4
  270. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +241 -0
  271. package/packages/omo-codex/plugin/components/rules/test/event-budget.test.ts +168 -0
  272. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +20 -0
  273. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +4 -0
  274. package/packages/omo-codex/plugin/components/rules/test/sparkshell-awareness.test.ts +86 -3
  275. package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +15 -15
  276. package/packages/omo-codex/plugin/components/start-work-continuation/dist/boulder-reader.d.ts +16 -0
  277. package/packages/omo-codex/plugin/components/start-work-continuation/dist/boulder-reader.js +146 -0
  278. package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.d.ts +2 -0
  279. package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +49 -0
  280. package/packages/omo-codex/plugin/components/start-work-continuation/dist/codex-hook.d.ts +2 -0
  281. package/packages/omo-codex/plugin/components/start-work-continuation/dist/codex-hook.js +80 -0
  282. package/packages/omo-codex/plugin/components/start-work-continuation/dist/directive.d.ts +1 -0
  283. package/packages/omo-codex/plugin/components/start-work-continuation/dist/directive.js +2 -0
  284. package/packages/omo-codex/plugin/components/start-work-continuation/dist/index.d.ts +5 -0
  285. package/packages/omo-codex/plugin/components/start-work-continuation/dist/index.js +3 -0
  286. package/packages/omo-codex/plugin/components/start-work-continuation/dist/types.d.ts +20 -0
  287. package/packages/omo-codex/plugin/components/start-work-continuation/dist/types.js +1 -0
  288. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  289. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  290. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +24 -2
  291. package/packages/omo-codex/plugin/components/telemetry/dist/atomic-write.d.ts +1 -0
  292. package/packages/omo-codex/plugin/components/telemetry/dist/atomic-write.js +18 -0
  293. package/packages/omo-codex/plugin/components/telemetry/dist/cli.d.ts +2 -0
  294. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +62 -0
  295. package/packages/omo-codex/plugin/components/telemetry/dist/codex-hook.d.ts +15 -0
  296. package/packages/omo-codex/plugin/components/telemetry/dist/codex-hook.js +42 -0
  297. package/packages/omo-codex/plugin/components/telemetry/dist/data-path.d.ts +10 -0
  298. package/packages/omo-codex/plugin/components/telemetry/dist/data-path.js +35 -0
  299. package/packages/omo-codex/plugin/components/telemetry/dist/diagnostics.d.ts +12 -0
  300. package/packages/omo-codex/plugin/components/telemetry/dist/diagnostics.js +108 -0
  301. package/packages/omo-codex/plugin/components/telemetry/dist/env-flags.d.ts +4 -0
  302. package/packages/omo-codex/plugin/components/telemetry/dist/env-flags.js +31 -0
  303. package/packages/omo-codex/plugin/components/telemetry/dist/posthog-activity-state.d.ts +8 -0
  304. package/packages/omo-codex/plugin/components/telemetry/dist/posthog-activity-state.js +68 -0
  305. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.d.ts +21 -0
  306. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +133 -0
  307. package/packages/omo-codex/plugin/components/telemetry/dist/product-identity.d.ts +8 -0
  308. package/packages/omo-codex/plugin/components/telemetry/dist/product-identity.js +29 -0
  309. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  310. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  311. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +5 -13
  312. package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +61 -185
  313. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -1
  314. package/packages/omo-codex/plugin/components/ultrawork/directive.md +122 -117
  315. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.d.ts +2 -0
  316. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +48 -0
  317. package/packages/omo-codex/plugin/components/ultrawork/dist/codex-hook.d.ts +7 -0
  318. package/packages/omo-codex/plugin/components/ultrawork/dist/codex-hook.js +122 -0
  319. package/packages/omo-codex/plugin/components/ultrawork/dist/directive.d.ts +1 -0
  320. package/packages/omo-codex/plugin/components/ultrawork/dist/directive.js +2 -0
  321. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  322. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  323. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +20 -11
  324. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +17 -11
  325. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +2 -5
  326. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +0 -71
  327. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.d.ts +16 -0
  328. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +200 -0
  329. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.d.ts +17 -0
  330. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.js +97 -0
  331. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.d.ts +4 -0
  332. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +183 -0
  333. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +6 -0
  334. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +55 -0
  335. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.d.ts +12 -0
  336. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +145 -0
  337. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.d.ts +2 -0
  338. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +39 -0
  339. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +13 -0
  340. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +100 -0
  341. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +26 -0
  342. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +97 -0
  343. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.d.ts +28 -0
  344. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.js +145 -0
  345. package/packages/omo-codex/plugin/components/ulw-loop/dist/command-types.d.ts +34 -0
  346. package/packages/omo-codex/plugin/components/ulw-loop/dist/command-types.js +1 -0
  347. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.d.ts +16 -0
  348. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.js +41 -0
  349. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +95 -0
  350. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.js +1 -0
  351. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.d.ts +31 -0
  352. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.js +119 -0
  353. package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.d.ts +12 -0
  354. package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.js +69 -0
  355. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.d.ts +16 -0
  356. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +59 -0
  357. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.d.ts +48 -0
  358. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +119 -0
  359. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +8 -0
  360. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +89 -0
  361. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +6 -0
  362. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +123 -0
  363. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.d.ts +16 -0
  364. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +70 -0
  365. package/packages/omo-codex/plugin/components/ulw-loop/dist/runtime.d.ts +10 -0
  366. package/packages/omo-codex/plugin/components/ulw-loop/dist/runtime.js +13 -0
  367. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-types.d.ts +63 -0
  368. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-types.js +1 -0
  369. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.d.ts +6 -0
  370. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +292 -0
  371. package/packages/omo-codex/plugin/components/ulw-loop/dist/types.d.ts +5 -0
  372. package/packages/omo-codex/plugin/components/ulw-loop/dist/types.js +5 -0
  373. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +2 -2
  374. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  375. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +14 -14
  376. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +24 -25
  377. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +17 -3
  378. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +2 -1
  379. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +1 -1
  380. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +95 -0
  381. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +0 -96
  382. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +23 -0
  383. package/packages/omo-codex/plugin/components/ulw-loop/test/skill-contract.test.ts +46 -0
  384. package/packages/omo-codex/plugin/hooks/hooks.json +16 -16
  385. package/packages/omo-codex/plugin/package-lock.json +10 -9
  386. package/packages/omo-codex/plugin/package.json +27 -26
  387. package/packages/omo-codex/plugin/scripts/auto-update.mjs +64 -15
  388. package/packages/omo-codex/plugin/scripts/build-bundled-mcp-runtimes.mjs +16 -0
  389. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +104 -0
  390. package/packages/omo-codex/plugin/scripts/migrate-codex-config.mjs +23 -6
  391. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +23 -11
  392. package/packages/omo-codex/plugin/scripts/sync-version.mjs +94 -0
  393. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +9 -9
  394. package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/SKILL.md +16 -1
  395. package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +93 -0
  396. package/packages/omo-codex/plugin/skills/lcx-doctor/agents/openai.yaml +11 -0
  397. package/packages/omo-codex/plugin/skills/lcx-report-bug/SKILL.md +17 -13
  398. package/packages/omo-codex/plugin/skills/lsp-setup/SKILL.md +139 -0
  399. package/packages/omo-codex/plugin/skills/lsp-setup/references/bash/README.md +60 -0
  400. package/packages/omo-codex/plugin/skills/lsp-setup/references/c-cpp/README.md +61 -0
  401. package/packages/omo-codex/plugin/skills/lsp-setup/references/csharp/README.md +71 -0
  402. package/packages/omo-codex/plugin/skills/lsp-setup/references/dart/README.md +48 -0
  403. package/packages/omo-codex/plugin/skills/lsp-setup/references/elixir/README.md +51 -0
  404. package/packages/omo-codex/plugin/skills/lsp-setup/references/go/README.md +57 -0
  405. package/packages/omo-codex/plugin/skills/lsp-setup/references/haskell/README.md +57 -0
  406. package/packages/omo-codex/plugin/skills/lsp-setup/references/java/README.md +57 -0
  407. package/packages/omo-codex/plugin/skills/lsp-setup/references/julia/README.md +60 -0
  408. package/packages/omo-codex/plugin/skills/lsp-setup/references/kotlin/README.md +59 -0
  409. package/packages/omo-codex/plugin/skills/lsp-setup/references/lua/README.md +66 -0
  410. package/packages/omo-codex/plugin/skills/lsp-setup/references/php/README.md +62 -0
  411. package/packages/omo-codex/plugin/skills/lsp-setup/references/python/README.md +71 -0
  412. package/packages/omo-codex/plugin/skills/lsp-setup/references/ruby/README.md +53 -0
  413. package/packages/omo-codex/plugin/skills/lsp-setup/references/rust/README.md +59 -0
  414. package/packages/omo-codex/plugin/skills/lsp-setup/references/swift/README.md +51 -0
  415. package/packages/omo-codex/plugin/skills/lsp-setup/references/terraform/README.md +62 -0
  416. package/packages/omo-codex/plugin/skills/lsp-setup/references/typescript/README.md +77 -0
  417. package/packages/omo-codex/plugin/skills/lsp-setup/references/yaml/README.md +70 -0
  418. package/packages/omo-codex/plugin/skills/lsp-setup/references/zig/README.md +49 -0
  419. package/packages/omo-codex/plugin/skills/lsp-setup/scripts/detect-lsp.ts +210 -0
  420. package/packages/omo-codex/plugin/skills/lsp-setup/scripts/lsp-server-table.ts +177 -0
  421. package/packages/omo-codex/plugin/skills/lsp-setup/scripts/tsconfig.json +17 -0
  422. package/packages/omo-codex/plugin/skills/lsp-setup/scripts/verify-lsp.ts +147 -0
  423. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +9 -9
  424. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +10 -10
  425. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +20 -22
  426. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +38 -61
  427. package/packages/omo-codex/plugin/skills/ultraresearch/SKILL.md +135 -677
  428. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +14 -14
  429. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +24 -25
  430. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +20 -11
  431. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +17 -11
  432. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +9 -9
  433. package/packages/omo-codex/plugin/test/aggregate-build.test.mjs +2 -1
  434. package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +1 -1
  435. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +5 -5
  436. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +6 -6
  437. package/packages/omo-codex/plugin/test/auto-update-restart-notice.test.mjs +194 -0
  438. package/packages/omo-codex/plugin/test/auto-update.test.mjs +17 -0
  439. package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +15 -44
  440. package/packages/omo-codex/plugin/test/lsp-prebuild-layouts.test.mjs +140 -0
  441. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +261 -0
  442. package/packages/omo-codex/plugin/test/start-work-skill.test.mjs +9 -31
  443. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +68 -4
  444. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +119 -0
  445. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +11 -112
  446. package/packages/omo-codex/plugin/test/sync-version.test.mjs +68 -0
  447. package/packages/omo-codex/plugin/test/ultraresearch-skill-contract.test.mjs +126 -0
  448. package/packages/omo-codex/plugin/test/ulw-plan-skill.test.mjs +2 -2
  449. package/packages/omo-codex/scripts/install/bin-dir.mjs +20 -0
  450. package/packages/omo-codex/scripts/install/bin-links.mjs +43 -6
  451. package/packages/omo-codex/scripts/install/cache.mjs +4 -0
  452. package/packages/omo-codex/scripts/install/config.mjs +5 -3
  453. package/packages/omo-codex/scripts/install/delegated-command.mjs +5 -1
  454. package/packages/omo-codex/scripts/install/git-bash-mcp-env.mjs +28 -0
  455. package/packages/omo-codex/scripts/install/git-bash.mjs +12 -4
  456. package/packages/omo-codex/scripts/install/git-bash.test.mjs +39 -4
  457. package/packages/omo-codex/scripts/install/hook-targets.mjs +46 -0
  458. package/packages/omo-codex/scripts/install/multi-agent-v2-config.mjs +22 -10
  459. package/packages/omo-codex/scripts/install/process.mjs +1 -0
  460. package/packages/omo-codex/scripts/install-bin-links.test.mjs +131 -3
  461. package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +91 -0
  462. package/packages/omo-codex/scripts/install-config.test.mjs +50 -44
  463. package/packages/omo-codex/scripts/install-delegated-command.test.mjs +78 -0
  464. package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +93 -0
  465. package/packages/omo-codex/scripts/install-hook-targets.test.mjs +100 -0
  466. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +3 -1
  467. package/packages/omo-codex/scripts/install-local.mjs +7 -18
  468. package/packages/omo-codex/scripts/install-local.test.mjs +34 -1
  469. package/packages/shared-skills/skills/lcx-contribute-bug-fix/SKILL.md +16 -1
  470. package/packages/shared-skills/skills/lcx-doctor/SKILL.md +93 -0
  471. package/packages/shared-skills/skills/lcx-doctor/agents/openai.yaml +11 -0
  472. package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +17 -13
  473. package/packages/shared-skills/skills/lsp-setup/SKILL.md +139 -0
  474. package/packages/shared-skills/skills/lsp-setup/references/bash/README.md +60 -0
  475. package/packages/shared-skills/skills/lsp-setup/references/c-cpp/README.md +61 -0
  476. package/packages/shared-skills/skills/lsp-setup/references/csharp/README.md +71 -0
  477. package/packages/shared-skills/skills/lsp-setup/references/dart/README.md +48 -0
  478. package/packages/shared-skills/skills/lsp-setup/references/elixir/README.md +51 -0
  479. package/packages/shared-skills/skills/lsp-setup/references/go/README.md +57 -0
  480. package/packages/shared-skills/skills/lsp-setup/references/haskell/README.md +57 -0
  481. package/packages/shared-skills/skills/lsp-setup/references/java/README.md +57 -0
  482. package/packages/shared-skills/skills/lsp-setup/references/julia/README.md +60 -0
  483. package/packages/shared-skills/skills/lsp-setup/references/kotlin/README.md +59 -0
  484. package/packages/shared-skills/skills/lsp-setup/references/lua/README.md +66 -0
  485. package/packages/shared-skills/skills/lsp-setup/references/php/README.md +62 -0
  486. package/packages/shared-skills/skills/lsp-setup/references/python/README.md +71 -0
  487. package/packages/shared-skills/skills/lsp-setup/references/ruby/README.md +53 -0
  488. package/packages/shared-skills/skills/lsp-setup/references/rust/README.md +59 -0
  489. package/packages/shared-skills/skills/lsp-setup/references/swift/README.md +51 -0
  490. package/packages/shared-skills/skills/lsp-setup/references/terraform/README.md +62 -0
  491. package/packages/shared-skills/skills/lsp-setup/references/typescript/README.md +77 -0
  492. package/packages/shared-skills/skills/lsp-setup/references/yaml/README.md +70 -0
  493. package/packages/shared-skills/skills/lsp-setup/references/zig/README.md +49 -0
  494. package/packages/shared-skills/skills/lsp-setup/scripts/detect-lsp.ts +210 -0
  495. package/packages/shared-skills/skills/lsp-setup/scripts/lsp-server-table.ts +177 -0
  496. package/packages/shared-skills/skills/lsp-setup/scripts/tsconfig.json +17 -0
  497. package/packages/shared-skills/skills/lsp-setup/scripts/verify-lsp.ts +147 -0
  498. package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +1 -1
  499. package/packages/shared-skills/skills/review-work/SKILL.md +10 -14
  500. package/packages/shared-skills/skills/start-work/SKILL.md +30 -59
  501. package/packages/shared-skills/skills/ultraresearch/SKILL.md +126 -667
  502. package/dist/hooks/anthropic-effort/hook.d.ts +0 -26
  503. package/dist/hooks/anthropic-effort/index.d.ts +0 -1
  504. package/dist/hooks/keyword-detector/analyze/default.d.ts +0 -12
  505. package/dist/hooks/keyword-detector/analyze/index.d.ts +0 -1
  506. package/dist/hooks/keyword-detector/search/default.d.ts +0 -12
  507. package/dist/hooks/keyword-detector/search/index.d.ts +0 -1
  508. package/dist/hooks/thinking-block-validator/hook.d.ts +0 -12
  509. package/dist/hooks/thinking-block-validator/index.d.ts +0 -1
  510. package/packages/omo-codex/plugin/components/ultrawork/test/directive-contract.test.ts +0 -18
  511. package/packages/omo-codex/plugin/test/global-review-debug-gate.test.mjs +0 -29
  512. package/packages/omo-codex/plugin/test/subagent-guidance.test.mjs +0 -151
@@ -0,0 +1,194 @@
1
+ import assert from "node:assert/strict";
2
+ import { spawnSync } from "node:child_process";
3
+ import { mkdtemp, readFile, writeFile } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import test from "node:test";
7
+ import { fileURLToPath } from "node:url";
8
+
9
+ import { resolveAutoUpdatePlan, runAutoUpdateCheck } from "../scripts/auto-update.mjs";
10
+
11
+ const SCRIPT_PATH = fileURLToPath(new URL("../scripts/auto-update.mjs", import.meta.url));
12
+ const STARTED_NOTICE =
13
+ "[LazyCodex] Auto-update started in the background: v1.0.0 -> v1.0.1. Tell the user a new LazyCodex version is installing and that they should start a new Codex session after it completes to apply it.";
14
+ const COMPLETED_NOTICE =
15
+ "[LazyCodex] Auto-update completed: v1.0.0 -> v1.0.1. This session is already running the new version. Tell the user the auto-update was applied.";
16
+
17
+ function autoUpdateEnv(root, extra = {}) {
18
+ return {
19
+ CODEX_HOME: join(root, "codex-home"),
20
+ LAZYCODEX_CURRENT_VERSION: "1.0.0",
21
+ LAZYCODEX_LATEST_VERSION: "1.0.1",
22
+ LAZYCODEX_MODEL_CATALOG_STATE_PATH: join(root, "model-state.json"),
23
+ LAZYCODEX_AUTO_UPDATE_STATE_PATH: join(root, "state.json"),
24
+ LAZYCODEX_AUTO_UPDATE_LOG_PATH: join(root, "auto-update.log"),
25
+ ...extra,
26
+ };
27
+ }
28
+
29
+ test("#given a newer version #when resolving auto update plan #then plan carries current and latest versions", () => {
30
+ const plan = resolveAutoUpdatePlan({
31
+ env: { LAZYCODEX_CURRENT_VERSION: "1.0.0", LAZYCODEX_LATEST_VERSION: "1.0.1" },
32
+ now: 90_000_000,
33
+ lastCheckedAt: 0,
34
+ });
35
+
36
+ assert.equal(plan.shouldRun, true);
37
+ assert.equal(plan.currentVersion, "1.0.0");
38
+ assert.equal(plan.latestVersion, "1.0.1");
39
+ });
40
+
41
+ test("#given a newer version #when waited update succeeds #then returns update-started notice and persists pendingNotice", async () => {
42
+ const root = await mkdtemp(join(tmpdir(), "lazycodex-restart-notice-started-"));
43
+ const env = autoUpdateEnv(root, {
44
+ LAZYCODEX_AUTO_UPDATE_INTERVAL_MS: "0",
45
+ LAZYCODEX_AUTO_UPDATE_COMMAND: process.execPath,
46
+ LAZYCODEX_AUTO_UPDATE_ARGS_JSON: JSON.stringify(["-e", "process.exit(0)"]),
47
+ LAZYCODEX_AUTO_UPDATE_WAIT: "1",
48
+ });
49
+
50
+ const result = await runAutoUpdateCheck({
51
+ env,
52
+ now: 123_456,
53
+ });
54
+
55
+ assert.equal(result.started, true);
56
+ assert.equal(result.status, 0);
57
+ assert.deepEqual(result.notices, [STARTED_NOTICE]);
58
+ const state = JSON.parse(await readFile(env.LAZYCODEX_AUTO_UPDATE_STATE_PATH, "utf8"));
59
+ assert.deepEqual(state.pendingNotice, {
60
+ fromVersion: "1.0.0",
61
+ toVersion: "1.0.1",
62
+ startedAt: 123_456,
63
+ });
64
+ });
65
+
66
+ test("#given completed pending update #when startup check is throttled #then emits completed notice and clears pendingNotice", async () => {
67
+ const root = await mkdtemp(join(tmpdir(), "lazycodex-restart-notice-completed-"));
68
+ const now = 90_000_000;
69
+ const env = autoUpdateEnv(root, {
70
+ LAZYCODEX_CURRENT_VERSION: "1.0.1",
71
+ LAZYCODEX_LATEST_VERSION: "1.0.1",
72
+ });
73
+ await writeFile(env.LAZYCODEX_AUTO_UPDATE_STATE_PATH, JSON.stringify({
74
+ lastCheckedAt: now - 1_000,
75
+ lastStatus: "success",
76
+ pendingNotice: { fromVersion: "1.0.0", toVersion: "1.0.1", startedAt: 1 },
77
+ }));
78
+
79
+ const result = await runAutoUpdateCheck({
80
+ env,
81
+ now,
82
+ });
83
+
84
+ assert.equal(result.started, false);
85
+ assert.equal(result.reason, "throttled");
86
+ assert.deepEqual(result.notices, [COMPLETED_NOTICE]);
87
+ assert.deepEqual(JSON.parse(await readFile(env.LAZYCODEX_AUTO_UPDATE_STATE_PATH, "utf8")), {
88
+ lastCheckedAt: now - 1_000,
89
+ lastStatus: "success",
90
+ });
91
+ });
92
+
93
+ test("#given incomplete pending update #when startup check runs #then no notice and pendingNotice retained", async () => {
94
+ const root = await mkdtemp(join(tmpdir(), "lazycodex-restart-notice-incomplete-"));
95
+ const now = 90_000_000;
96
+ const env = autoUpdateEnv(root);
97
+ await writeFile(env.LAZYCODEX_AUTO_UPDATE_STATE_PATH, JSON.stringify({
98
+ lastAttemptedAt: now - 60_000,
99
+ lastStatus: "started",
100
+ pendingNotice: { fromVersion: "1.0.0", toVersion: "1.0.1", startedAt: 1 },
101
+ }));
102
+
103
+ const result = await runAutoUpdateCheck({
104
+ env,
105
+ now,
106
+ });
107
+
108
+ assert.equal(result.started, false);
109
+ assert.equal(result.reason, "retry-throttled");
110
+ assert.deepEqual(result.notices, []);
111
+ const state = JSON.parse(await readFile(env.LAZYCODEX_AUTO_UPDATE_STATE_PATH, "utf8"));
112
+ assert.deepEqual(state.pendingNotice, {
113
+ fromVersion: "1.0.0",
114
+ toVersion: "1.0.1",
115
+ startedAt: 1,
116
+ });
117
+ });
118
+
119
+ test("#given waited update fails #then no notice and no pendingNotice", async () => {
120
+ const root = await mkdtemp(join(tmpdir(), "lazycodex-restart-notice-failed-"));
121
+ const env = autoUpdateEnv(root, {
122
+ LAZYCODEX_AUTO_UPDATE_INTERVAL_MS: "0",
123
+ LAZYCODEX_AUTO_UPDATE_COMMAND: process.execPath,
124
+ LAZYCODEX_AUTO_UPDATE_ARGS_JSON: JSON.stringify(["-e", "process.exit(1)"]),
125
+ LAZYCODEX_AUTO_UPDATE_WAIT: "1",
126
+ });
127
+
128
+ const result = await runAutoUpdateCheck({
129
+ env,
130
+ now: 123_456,
131
+ });
132
+
133
+ assert.equal(result.started, true);
134
+ assert.equal(result.status, 1);
135
+ assert.deepEqual(result.notices, []);
136
+ assert.deepEqual(JSON.parse(await readFile(env.LAZYCODEX_AUTO_UPDATE_STATE_PATH, "utf8")), {
137
+ lastAttemptedAt: 123_456,
138
+ lastStatus: "failed",
139
+ });
140
+ });
141
+
142
+ test("#given malformed pendingNotice toVersion #when check runs #then pendingNotice dropped silently", async () => {
143
+ const root = await mkdtemp(join(tmpdir(), "lazycodex-restart-notice-malformed-"));
144
+ const env = autoUpdateEnv(root, {
145
+ LAZYCODEX_CURRENT_VERSION: "1.0.1",
146
+ LAZYCODEX_LATEST_VERSION: "1.0.1",
147
+ });
148
+ await writeFile(env.LAZYCODEX_AUTO_UPDATE_STATE_PATH, JSON.stringify({
149
+ pendingNotice: { fromVersion: "1.0.0", toVersion: "not-a-version", startedAt: 1 },
150
+ }));
151
+
152
+ const result = await runAutoUpdateCheck({
153
+ env,
154
+ now: 123_456,
155
+ });
156
+
157
+ assert.deepEqual(result.notices, []);
158
+ const state = JSON.parse(await readFile(env.LAZYCODEX_AUTO_UPDATE_STATE_PATH, "utf8"));
159
+ assert.equal("pendingNotice" in state, false);
160
+ });
161
+
162
+ test("#given completed pending update #when hook session-start runs as CLI #then prints one SessionStart JSON line", async () => {
163
+ const root = await mkdtemp(join(tmpdir(), "lazycodex-restart-notice-cli-"));
164
+ const env = autoUpdateEnv(root, {
165
+ LAZYCODEX_CURRENT_VERSION: "1.0.1",
166
+ LAZYCODEX_LATEST_VERSION: "1.0.1",
167
+ LAZYCODEX_CONFIG_MIGRATION_DISABLED: "1",
168
+ });
169
+ await writeFile(env.LAZYCODEX_AUTO_UPDATE_STATE_PATH, JSON.stringify({
170
+ lastCheckedAt: Date.now() - 1_000,
171
+ lastStatus: "success",
172
+ pendingNotice: { fromVersion: "1.0.0", toVersion: "1.0.1", startedAt: 1 },
173
+ }));
174
+
175
+ const result = spawnSync(process.execPath, [SCRIPT_PATH, "hook", "session-start"], {
176
+ encoding: "utf8",
177
+ env: { ...process.env, ...env },
178
+ });
179
+
180
+ assert.equal(result.status, 0);
181
+ const lines = result.stdout.split("\n").filter((line) => line.length > 0);
182
+ assert.equal(lines.length, 1);
183
+ const parsed = JSON.parse(lines[0]);
184
+ assert.equal(parsed.hookSpecificOutput.hookEventName, "SessionStart");
185
+ assert.match(parsed.hookSpecificOutput.additionalContext, /v1\.0\.0 -> v1\.0\.1/);
186
+
187
+ const repeat = spawnSync(process.execPath, [SCRIPT_PATH, "hook", "session-start"], {
188
+ encoding: "utf8",
189
+ env: { ...process.env, ...env },
190
+ });
191
+
192
+ assert.equal(repeat.status, 0);
193
+ assert.equal(repeat.stdout, "");
194
+ });
@@ -162,6 +162,11 @@ test("#given test command override #when running check #then records state and l
162
162
  lastCheckedAt: 123_456,
163
163
  lastAttemptedAt: 123_456,
164
164
  lastStatus: "success",
165
+ pendingNotice: {
166
+ fromVersion: "1.0.0",
167
+ toVersion: "1.0.1",
168
+ startedAt: 123_456,
169
+ },
165
170
  });
166
171
  assert.equal(await readFile(logPath, "utf8"), "ok");
167
172
  const updateLog = (await readFile(env.LAZYCODEX_AUTO_UPDATE_LOG_PATH, "utf8")).trim().split("\n").map((line) => JSON.parse(line));
@@ -177,6 +182,13 @@ test("#given test command override #when running check #then records state and l
177
182
  event: "finished",
178
183
  status: 0,
179
184
  },
185
+ {
186
+ timestamp: "1970-01-01T00:02:03.456Z",
187
+ event: "notified",
188
+ kind: "update-started",
189
+ fromVersion: "1.0.0",
190
+ toVersion: "1.0.1",
191
+ },
180
192
  ]);
181
193
  assert.match(await readFile(join(env.CODEX_HOME, "config.toml"), "utf8"), /model = "gpt-5\.5"/);
182
194
  });
@@ -262,6 +274,11 @@ test("#given stale lock #when running check #then removes lock and runs update",
262
274
  lastCheckedAt: 1_000_000,
263
275
  lastAttemptedAt: 1_000_000,
264
276
  lastStatus: "success",
277
+ pendingNotice: {
278
+ fromVersion: "1.0.0",
279
+ toVersion: "1.0.1",
280
+ startedAt: 1_000_000,
281
+ },
265
282
  });
266
283
  });
267
284
 
@@ -16,22 +16,6 @@ test("#given synced lcx-report-bug skill #when inspected #then it files LazyCode
16
16
 
17
17
  // then
18
18
  assert.match(skill, /^---\r?\nname: lcx-report-bug\r?\n/m);
19
- assert.match(skill, /code-yeongyu\/lazycodex/);
20
- assert.match(skill, /openai\/codex/);
21
- assert.match(skill, /\/tmp\/openai-codex-source/);
22
- assert.match(skill, /\$omo:debugging/);
23
- assert.match(skill, /Repository Decision/);
24
- assert.match(skill, /TARGET_REPO="code-yeongyu\/lazycodex" # or openai\/codex/);
25
- assert.match(skill, /LABEL_ARGS=\(\)/);
26
- assert.match(skill, /gh label create lazycodex-generated.*--force/);
27
- assert.match(skill, /gh issue create --repo "\$TARGET_REPO".*"\$\{LABEL_ARGS\[@\]\}"/);
28
- assert.match(skill, /gh pr create --repo "\$TARGET_REPO".*"\$\{LABEL_ARGS\[@\]\}"/);
29
- assert.match(skill, /lazycodex-generated/);
30
- assert.match(skill, /This issue or PR was generated by LazyCodex/);
31
- assert.match(skill, /Tag: lazycodex-generated/);
32
- assert.match(skill, /Browser use fallback/);
33
- assert.match(skill, /Computer use fallback/);
34
- assert.match(skill, /## Issue Body Template/);
35
19
  assert.match(interfaceMetadata, /display_name: "lcx-report-bug \(omo\)"/);
36
20
  assert.match(interfaceMetadata, /- "lazycodex bug"/);
37
21
  assert.match(interfaceMetadata, /- "openai codex bug"/);
@@ -44,38 +28,25 @@ test("#given synced lcx-contribute-bug-fix skill #when inspected #then it contri
44
28
  // when
45
29
  const skill = await readFile(join(skillRoot, "SKILL.md"), "utf8");
46
30
  const interfaceMetadata = await readFile(join(skillRoot, "agents", "openai.yaml"), "utf8");
47
- const script = await readFile(join(skillRoot, "scripts", "create-pr-body.mjs"), "utf8");
48
31
 
49
32
  // then
50
33
  assert.match(skill, /^---\r?\nname: lcx-contribute-bug-fix\r?\n/m);
51
- assert.match(skill, /Contribute a verified bug-fix PR/);
52
- assert.match(skill, /fresh `\/tmp` clone\/worktree/);
53
- assert.match(skill, /\/tmp\/lazycodex-fix-/);
54
- assert.match(skill, /git worktree add/);
55
- assert.match(skill, /apply `lazycodex-generated` when label management is available/);
56
- assert.match(skill, /git add -A/);
57
- assert.match(skill, /git commit -m/);
58
- assert.match(skill, /git log --oneline "origin\/\$BASE_BRANCH\.\.HEAD"/);
59
- assert.match(skill, /gh repo fork "\$TARGET_REPO" --remote --remote-name fork/);
60
- assert.match(skill, /PUSH_REMOTE/);
61
- assert.match(skill, /lazycodex-generated/);
62
- assert.match(skill, /LABEL_ARGS=\(\)/);
63
- assert.match(skill, /gh label create lazycodex-generated.*--force/);
64
- assert.match(skill, /gh pr create --repo "\$TARGET_REPO".*"\$\{LABEL_ARGS\[@\]\}"/);
65
- assert.match(skill, /--head "\$PR_HEAD"/);
66
- assert.doesNotMatch(skill, /a PR without the `lazycodex-generated` label/);
67
- assert.match(skill, /scripts\/create-pr-body\.mjs/);
68
- assert.match(skill, /## Problem Situation/);
69
- assert.match(skill, /## Reproduction Logs/);
70
- assert.match(skill, /## Approach/);
71
- assert.match(skill, /## Why I Am Confident/);
72
- assert.match(skill, /## Risks/);
73
- assert.match(skill, /## User-Visible Behavior Changes/);
74
- assert.match(skill, /Clean up/);
75
34
  assert.match(interfaceMetadata, /display_name: "lcx-contribute-bug-fix \(omo\)"/);
76
35
  assert.match(interfaceMetadata, /- "contribute a bug fix"/);
77
36
  assert.match(interfaceMetadata, /- "fix bug pr"/);
78
- assert.match(script, /createLazyCodexBugFixPrBody/);
79
- assert.match(script, /Problem Situation/);
80
- assert.match(script, /Why I Am Confident/);
37
+ });
38
+
39
+ test("#given synced lcx-doctor skill #when inspected #then it diagnoses installs against latest /tmp sources without mutating them", async () => {
40
+ // given
41
+ const skillRoot = join(root, "skills", "lcx-doctor");
42
+
43
+ // when
44
+ const skill = await readFile(join(skillRoot, "SKILL.md"), "utf8");
45
+ const interfaceMetadata = await readFile(join(skillRoot, "agents", "openai.yaml"), "utf8");
46
+
47
+ // then
48
+ assert.match(skill, /^---\r?\nname: lcx-doctor\r?\n/m);
49
+ assert.match(interfaceMetadata, /display_name: "lcx-doctor \(omo\)"/);
50
+ assert.match(interfaceMetadata, /- "lazycodex doctor"/);
51
+ assert.match(interfaceMetadata, /- "lazycodex health check"/);
81
52
  });
@@ -0,0 +1,140 @@
1
+ import assert from "node:assert/strict";
2
+ import { execFileSync } from "node:child_process";
3
+ import { copyFile, mkdir, mkdtemp, rm, utimes, writeFile } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import test from "node:test";
7
+ import { fileURLToPath } from "node:url";
8
+
9
+ const REPO_SCRIPTS = fileURLToPath(new URL("../components/lsp/scripts", import.meta.url));
10
+ const BUILD_LSP_TOOLS = join(REPO_SCRIPTS, "build-lsp-tools.mjs");
11
+ const BUILD_LSP_DAEMON = join(REPO_SCRIPTS, "build-lsp-daemon.mjs");
12
+
13
+ // Run a copied script (built from HEAD sources) and return { status, stdout, stderr }.
14
+ // execFileSync throws on non-zero exit; we capture the SpawnError fields instead.
15
+ function runScript(script, cwd) {
16
+ try {
17
+ const stdout = execFileSync(process.execPath, [script], { cwd, encoding: "utf8" });
18
+ return { status: 0, stdout, stderr: "" };
19
+ } catch (err) {
20
+ return {
21
+ status: typeof err.status === "number" ? err.status : 1,
22
+ stdout: err.stdout ?? "",
23
+ stderr: err.stderr ?? "",
24
+ };
25
+ }
26
+ }
27
+
28
+ // Escape a string for use in a RegExp literal.
29
+ function escapeRegex(str) {
30
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
31
+ }
32
+
33
+ test("#given the installed cache layout #when running build-lsp-tools #then uses the bundled dist and exits 0", async () => {
34
+ // given — mirror the installed plugin cache: scripts 2-up from components/lsp-tools-mcp/dist
35
+ const root = await mkdtemp(join(tmpdir(), "lsp-prebuild-cache-tools-"));
36
+ try {
37
+ const scriptsDir = join(root, "components", "lsp", "scripts");
38
+ await mkdir(scriptsDir, { recursive: true });
39
+ await copyFile(BUILD_LSP_TOOLS, join(scriptsDir, "build-lsp-tools.mjs"));
40
+
41
+ await mkdir(join(root, "components", "lsp-tools-mcp", "dist", "lsp"), { recursive: true });
42
+ await writeFile(join(root, "components", "lsp-tools-mcp", "dist", "cli.js"), "");
43
+ await writeFile(join(root, "components", "lsp-tools-mcp", "dist", "tools.js"), "");
44
+ await writeFile(join(root, "components", "lsp-tools-mcp", "dist", "lsp", "manager.js"), "");
45
+
46
+ // when
47
+ const result = runScript(join(scriptsDir, "build-lsp-tools.mjs"), root);
48
+
49
+ // then
50
+ assert.equal(result.status, 0, `expected exit 0; stderr: ${result.stderr}`);
51
+ assert.match(result.stdout, /Using bundled lsp-tools-mcp dist/);
52
+ } finally {
53
+ await rm(root, { recursive: true, force: true });
54
+ }
55
+ });
56
+
57
+ test("#given the installed cache layout #when running build-lsp-daemon #then uses the bundled dist and exits 0", async () => {
58
+ // given — mirror the installed plugin cache: scripts 2-up from components/lsp-daemon/dist
59
+ const root = await mkdtemp(join(tmpdir(), "lsp-prebuild-cache-daemon-"));
60
+ try {
61
+ const scriptsDir = join(root, "components", "lsp", "scripts");
62
+ await mkdir(scriptsDir, { recursive: true });
63
+ await copyFile(BUILD_LSP_DAEMON, join(scriptsDir, "build-lsp-daemon.mjs"));
64
+
65
+ await mkdir(join(root, "components", "lsp-daemon", "dist"), { recursive: true });
66
+ await writeFile(join(root, "components", "lsp-daemon", "dist", "cli.js"), "");
67
+ await writeFile(join(root, "components", "lsp-daemon", "dist", "index.js"), "");
68
+ await writeFile(join(root, "components", "lsp-daemon", "dist", "index.d.ts"), "");
69
+
70
+ // when
71
+ const result = runScript(join(scriptsDir, "build-lsp-daemon.mjs"), root);
72
+
73
+ // then
74
+ assert.equal(result.status, 0, `expected exit 0; stderr: ${result.stderr}`);
75
+ assert.match(result.stdout, /Using bundled lsp-daemon dist/);
76
+ } finally {
77
+ await rm(root, { recursive: true, force: true });
78
+ }
79
+ });
80
+
81
+ test("#given neither layout #when running build-lsp-tools #then fails listing every probed path", async () => {
82
+ // given — bare layout: only the script, no package.json anywhere, no dist outputs
83
+ const root = await mkdtemp(join(tmpdir(), "lsp-prebuild-none-"));
84
+ try {
85
+ const scriptsDir = join(root, "components", "lsp", "scripts");
86
+ await mkdir(scriptsDir, { recursive: true });
87
+ await copyFile(BUILD_LSP_TOOLS, join(scriptsDir, "build-lsp-tools.mjs"));
88
+
89
+ // when
90
+ const result = runScript(join(scriptsDir, "build-lsp-tools.mjs"), root);
91
+
92
+ // then — exit 1, stderr enumerates BOTH probed package.json paths
93
+ // candidate 1: 5-up repo sibling (resolves outside the temp tree)
94
+ const candidate1PkgJson = join(scriptsDir, "..", "..", "..", "..", "..", "lsp-tools-mcp", "package.json");
95
+ // candidate 2: 2-up components sibling (inside the temp tree)
96
+ const candidate2PkgJson = join(root, "components", "lsp-tools-mcp", "package.json");
97
+
98
+ assert.equal(result.status, 1);
99
+ assert.match(result.stderr, new RegExp(escapeRegex(candidate1PkgJson)));
100
+ assert.match(result.stderr, new RegExp(escapeRegex(candidate2PkgJson)));
101
+ } finally {
102
+ await rm(root, { recursive: true, force: true });
103
+ }
104
+ });
105
+
106
+ test("#given the repo sibling layout with fresh outputs #when running build-lsp-tools #then exits 0 without building", async () => {
107
+ // given — simulate the repo layout: script at d1/d2/d3/components/lsp/scripts/,
108
+ // lsp-tools-mcp at d1/ (5-up from the scripts dir), outputs newer than package.json
109
+ const root = await mkdtemp(join(tmpdir(), "lsp-prebuild-repo-"));
110
+ try {
111
+ const scriptsDir = join(root, "d1", "d2", "d3", "components", "lsp", "scripts");
112
+ await mkdir(scriptsDir, { recursive: true });
113
+ await copyFile(BUILD_LSP_TOOLS, join(scriptsDir, "build-lsp-tools.mjs"));
114
+
115
+ // 5-up from scriptsDir lands on join(root, "d1")
116
+ const lspToolsDir = join(root, "d1", "lsp-tools-mcp");
117
+ await mkdir(join(lspToolsDir, "dist", "lsp"), { recursive: true });
118
+
119
+ // package.json gets an older mtime
120
+ await writeFile(join(lspToolsDir, "package.json"), "{}");
121
+ const older = new Date("2025-01-01T00:00:00.000Z");
122
+ await utimes(join(lspToolsDir, "package.json"), older, older);
123
+
124
+ // outputs get a newer mtime — isBuildFresh returns true
125
+ const newer = new Date("2025-01-02T00:00:00.000Z");
126
+ for (const rel of ["dist/cli.js", "dist/tools.js", "dist/lsp/manager.js"]) {
127
+ await writeFile(join(lspToolsDir, rel), "");
128
+ await utimes(join(lspToolsDir, rel), newer, newer);
129
+ }
130
+
131
+ // when
132
+ const result = runScript(join(scriptsDir, "build-lsp-tools.mjs"), root);
133
+
134
+ // then — exits 0 immediately (fresh build), no npm invocation
135
+ assert.equal(result.status, 0, `expected exit 0; stderr: ${result.stderr}`);
136
+ assert.doesNotMatch(result.stdout, /Installing/);
137
+ } finally {
138
+ await rm(root, { recursive: true, force: true });
139
+ }
140
+ });