oh-my-opencode 5.0.0-beta.2 → 5.0.0-beta.21

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 (460) hide show
  1. package/.agents/command/publish.md +44 -16
  2. package/.agents/skills/publish/SKILL.md +44 -16
  3. package/.agents/skills/senpi-qa/SKILL.md +80 -0
  4. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.mjs +65 -0
  5. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs +171 -0
  6. package/.agents/skills/work-with-pr/SKILL.md +37 -23
  7. package/.opencode/command/publish.md +44 -16
  8. package/.opencode/skills/work-with-pr/SKILL.md +37 -23
  9. package/README.ja.md +25 -21
  10. package/README.ko.md +25 -21
  11. package/README.md +38 -23
  12. package/README.ru.md +24 -20
  13. package/README.zh-cn.md +25 -21
  14. package/dist/agents/atlas/agent.d.ts +0 -1
  15. package/dist/agents/sisyphus/grok-4.d.ts +20 -0
  16. package/dist/agents/sisyphus/index.d.ts +2 -0
  17. package/dist/agents/sisyphus-agent-config.d.ts +6 -0
  18. package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
  19. package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +15 -4
  20. package/dist/agents/types.d.ts +2 -2
  21. package/dist/cli/fallback-lane-policy.d.ts +1 -0
  22. package/dist/cli/index.js +23057 -20893
  23. package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +1 -1
  24. package/dist/cli/run/on-complete-hook.d.ts +2 -0
  25. package/dist/cli/runtime-commands.d.ts +1 -1
  26. package/dist/cli/worktree-sweep/classify.d.ts +16 -0
  27. package/dist/cli/worktree-sweep/format.d.ts +8 -0
  28. package/dist/cli/worktree-sweep/git.d.ts +19 -0
  29. package/dist/cli/worktree-sweep/index.d.ts +7 -0
  30. package/dist/cli/worktree-sweep/options.d.ts +2 -0
  31. package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
  32. package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
  33. package/dist/cli/worktree-sweep/types.d.ts +65 -0
  34. package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
  35. package/dist/cli-node/index.js +23093 -20929
  36. package/dist/config/schema/commands.d.ts +1 -1
  37. package/dist/config/schema/hooks.d.ts +1 -1
  38. package/dist/config/schema/oh-my-opencode-config.d.ts +4 -1
  39. package/dist/config/schema/ulw-execute.d.ts +5 -0
  40. package/dist/config/validate.d.ts +2 -0
  41. package/dist/create-hooks.d.ts +3 -1
  42. package/dist/features/btw-side/btw-command-draft.d.ts +7 -0
  43. package/dist/features/btw-side/context-injector.d.ts +15 -0
  44. package/dist/features/btw-side/index.d.ts +8 -0
  45. package/dist/features/btw-side/metadata.d.ts +15 -0
  46. package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
  47. package/dist/features/btw-side/server-session-registry.d.ts +8 -0
  48. package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
  49. package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
  50. package/dist/features/btw-side/tui-controller-types.d.ts +68 -0
  51. package/dist/features/btw-side/tui-controller.d.ts +19 -0
  52. package/dist/features/btw-side/tui-escape-return.d.ts +12 -0
  53. package/dist/features/btw-side/tui-keymap.d.ts +17 -0
  54. package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
  55. package/dist/features/btw-side/tui-picker-options.d.ts +20 -0
  56. package/dist/features/btw-side/tui-picker.d.ts +9 -0
  57. package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
  58. package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
  59. package/dist/features/btw-side/tui-session-catalog.d.ts +35 -0
  60. package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
  61. package/dist/features/btw-side/tui-side-start.d.ts +9 -0
  62. package/dist/features/btw-side/tui-wiring.d.ts +8 -0
  63. package/dist/features/builtin-commands/templates/ulw-execute.d.ts +1 -0
  64. package/dist/features/builtin-commands/types.d.ts +1 -1
  65. package/dist/features/opengateway-provider/index.d.ts +13 -0
  66. package/dist/hooks/atlas/atlas-hook.d.ts +1 -0
  67. package/dist/hooks/atlas/atlas-lifecycle-store.d.ts +50 -0
  68. package/dist/hooks/atlas/event-handler.d.ts +1 -0
  69. package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
  70. package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
  71. package/dist/hooks/atlas/tool-execute-before.d.ts +3 -0
  72. package/dist/hooks/atlas/types.d.ts +1 -0
  73. package/dist/hooks/index.d.ts +1 -1
  74. package/dist/hooks/prometheus-md-only/agent-resolution.d.ts +2 -2
  75. package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
  76. package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
  77. package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
  78. package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
  79. package/dist/hooks/runtime-fallback/types.d.ts +3 -1
  80. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  81. package/dist/hooks/{start-work → ulw-execute}/context-info-builder.d.ts +1 -1
  82. package/dist/hooks/{start-work → ulw-execute}/index.d.ts +1 -1
  83. package/dist/hooks/ulw-execute/ulw-execute-hook.d.ts +23 -0
  84. package/dist/index.js +11724 -6355
  85. package/dist/oh-my-opencode.schema.json +15 -2
  86. package/dist/plugin/chat-message/types.d.ts +3 -3
  87. package/dist/plugin/chat-message/ulw-execute-message.d.ts +5 -0
  88. package/dist/plugin/event-session-lifecycle.d.ts +1 -0
  89. package/dist/plugin/hooks/create-core-hooks.d.ts +2 -1
  90. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -2
  91. package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
  92. package/dist/plugin/messages-transform.d.ts +1 -0
  93. package/dist/shared/index.d.ts +1 -0
  94. package/dist/shared/normalize-sdk-response.d.ts +1 -0
  95. package/dist/shared/runtime-fallback-retry-marker.d.ts +16 -0
  96. package/dist/shared/shell-env.d.ts +1 -1
  97. package/dist/skills/ast-grep/AGENTS.md +51 -0
  98. package/dist/skills/coding-agent-sessions/AGENTS.md +62 -0
  99. package/dist/skills/coding-agent-sessions/SKILL.md +3 -2
  100. package/dist/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  101. package/dist/skills/coding-agent-sessions/references/senpi.md +4 -4
  102. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  103. package/dist/skills/frontend/SKILL.md +11 -7
  104. package/dist/skills/frontend/references/design/_INDEX.md +1 -0
  105. package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
  106. package/dist/skills/frontend/references/design/stylegallery.md +80 -0
  107. package/dist/skills/frontend/references/designpowers/README.md +1 -1
  108. package/dist/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  109. package/dist/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  110. package/dist/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  111. package/dist/skills/frontend/references/designpowers/orchestration.md +1 -1
  112. package/dist/skills/frontend/references/designpowers/routing.md +5 -5
  113. package/dist/skills/review-work/SKILL.md +3 -3
  114. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  115. package/dist/skills/ultimate-browsing/SKILL.md +2 -0
  116. package/dist/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  117. package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
  118. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  119. package/dist/skills/{start-work → ulw-execute}/SKILL.md +9 -8
  120. package/dist/skills/ulw-plan/SKILL.md +6 -6
  121. package/dist/skills/ulw-plan/references/full-workflow.md +31 -7
  122. package/dist/skills/ulw-plan/references/intent-clear.md +2 -1
  123. package/dist/skills/ulw-plan/references/intent-unclear.md +5 -5
  124. package/dist/skills/ulw-research/SKILL.md +1 -1
  125. package/dist/skills/visual-qa/AGENTS.md +58 -0
  126. package/dist/skills/visual-qa/SKILL.md +3 -2
  127. package/dist/tools/delegate-task/builtin-categories.d.ts +1 -0
  128. package/dist/tools/delegate-task/builtin-category-definition.d.ts +1 -0
  129. package/dist/tools/delegate-task/tool-description.d.ts +3 -1
  130. package/dist/tui.js +8824 -8906
  131. package/package.json +38 -35
  132. package/packages/git-bash-mcp/dist/cli.js +5 -1
  133. package/packages/git-bash-mcp/package.json +1 -1
  134. package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +44 -0
  135. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +0 -28
  136. package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
  137. package/packages/lsp-core/src/lsp/client-wrapper.test.ts +66 -13
  138. package/packages/lsp-core/src/lsp/client-wrapper.ts +70 -18
  139. package/packages/lsp-core/src/lsp/outside-context-workspace.ts +33 -0
  140. package/packages/lsp-core/src/lsp/workspace-edit-adversarial.test.ts +20 -1
  141. package/packages/lsp-core/src/lsp/workspace-markers.ts +1 -0
  142. package/packages/lsp-core/src/tools/diagnostics.ts +3 -3
  143. package/packages/lsp-core/src/tools/navigation.ts +4 -2
  144. package/packages/lsp-core/src/tools/rename.ts +4 -2
  145. package/packages/lsp-core/src/tools/symbols.ts +1 -1
  146. package/packages/lsp-daemon/dist/cli.js +246 -185
  147. package/packages/lsp-daemon/dist/client.js +222 -164
  148. package/packages/lsp-daemon/dist/ensure-daemon.js +1 -0
  149. package/packages/lsp-daemon/dist/index.js +236 -177
  150. package/packages/lsp-daemon/dist/version-reap.js +1 -1
  151. package/packages/lsp-tools-mcp/dist/cli.js +198 -136
  152. package/packages/lsp-tools-mcp/dist/lsp/manager.js +62 -92
  153. package/packages/lsp-tools-mcp/dist/mcp.js +200 -138
  154. package/packages/lsp-tools-mcp/dist/request-context.js +11 -12
  155. package/packages/lsp-tools-mcp/dist/tools.js +204 -146
  156. package/packages/omo-codex/THIRD-PARTY-NOTICES.md +4 -4
  157. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -4
  158. package/packages/omo-codex/plugin/AGENTS.md +47 -0
  159. package/packages/omo-codex/plugin/README.md +1 -1
  160. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +32 -31
  161. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  162. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  163. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -0
  164. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +224 -81
  165. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +224 -82
  166. package/packages/omo-codex/plugin/components/codegraph/package.json +4 -4
  167. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +1 -0
  168. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +1 -0
  169. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
  170. package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
  171. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
  172. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  173. package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
  174. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
  175. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
  176. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
  177. package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
  178. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
  179. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  180. package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
  181. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
  182. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +1 -5
  183. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +1 -5
  184. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  185. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -5
  186. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +1 -5
  187. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +4 -21
  188. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
  189. package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
  190. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
  191. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +217 -171
  192. package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
  193. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  194. package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
  195. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  196. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
  197. package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
  198. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
  199. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
  200. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
  201. package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
  202. package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
  203. package/packages/omo-codex/plugin/components/rules/dist/cli.js +57 -42
  204. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  205. package/packages/omo-codex/plugin/components/rules/package.json +7 -7
  206. package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
  207. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
  208. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +6 -2
  209. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
  210. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
  211. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
  212. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
  213. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
  214. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
  215. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
  216. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
  217. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
  218. package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
  219. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
  220. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
  221. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
  222. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +1 -2
  223. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
  224. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
  225. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
  226. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
  227. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +1 -2
  228. package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
  229. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
  230. package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
  231. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
  232. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  233. package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
  234. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +3 -9
  235. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
  236. package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
  237. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2433 -422
  238. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2437 -426
  239. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  240. package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
  241. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
  242. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
  243. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
  244. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
  245. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -0
  246. package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
  247. package/packages/omo-codex/plugin/components/ultrawork/directive.md +13 -1
  248. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  249. package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -5
  250. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +13 -1
  251. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -6
  252. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
  253. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
  254. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
  255. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
  256. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
  257. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
  258. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +5 -4
  259. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
  260. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +5 -5
  261. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
  262. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +6 -6
  263. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +12 -12
  264. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +28 -0
  265. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
  266. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
  267. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
  268. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +3 -3
  269. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
  270. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
  271. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
  272. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +1 -4
  273. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +8 -22
  274. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +16 -0
  275. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -1
  276. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
  277. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +13 -1
  278. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +2 -4
  279. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +1 -1
  280. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +1 -1
  281. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +3 -3
  282. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  283. package/packages/omo-codex/plugin/components/ulw-loop/package.json +5 -5
  284. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +3 -2
  285. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
  286. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +1 -0
  287. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +3 -1
  288. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
  289. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +1 -1
  290. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +3 -3
  291. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
  292. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +25 -0
  293. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +2 -2
  294. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +18 -0
  295. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
  296. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
  297. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
  298. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
  299. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  300. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +4 -5
  301. package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
  302. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  303. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  304. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  305. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  306. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  307. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  308. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  309. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  310. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  311. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  312. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  313. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  314. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  315. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  316. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  317. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  318. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +17 -0
  319. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  320. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +17 -0
  321. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  322. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  323. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  324. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  325. package/packages/omo-codex/plugin/package-lock.json +681 -395
  326. package/packages/omo-codex/plugin/package.json +2 -2
  327. package/packages/omo-codex/plugin/scripts/AGENTS.md +40 -0
  328. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -1
  329. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +11 -11
  330. package/packages/omo-codex/plugin/shared/package.json +3 -4
  331. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
  332. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
  333. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +3 -2
  334. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  335. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +4 -4
  336. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  337. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +11 -7
  338. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
  339. package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
  340. package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
  341. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
  342. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  343. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  344. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  345. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
  346. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
  347. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +4 -4
  348. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  349. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +2 -0
  350. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  351. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
  352. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  353. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +13 -1
  354. package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +12 -11
  355. package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
  356. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +3 -2
  357. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
  358. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +1 -0
  359. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -6
  360. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
  361. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
  362. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
  363. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +1 -1
  364. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
  365. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +3 -2
  366. package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
  367. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
  368. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +8 -28
  369. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -1
  370. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
  371. package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
  372. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
  373. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
  374. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -1
  375. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +2 -2
  376. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +4 -4
  377. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
  378. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
  379. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +101 -0
  380. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +12 -12
  381. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +1 -119
  382. package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
  383. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
  384. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
  385. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
  386. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
  387. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +0 -3
  388. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
  389. package/packages/omo-codex/scripts/AGENTS.md +36 -0
  390. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2601 -528
  391. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
  392. package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
  393. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
  394. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +3 -2
  395. package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  396. package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +4 -4
  397. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  398. package/packages/shared-skills/skills/frontend/SKILL.md +11 -7
  399. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
  400. package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
  401. package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
  402. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
  403. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  404. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  405. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  406. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
  407. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
  408. package/packages/shared-skills/skills/review-work/SKILL.md +3 -3
  409. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  410. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +2 -0
  411. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  412. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
  413. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  414. package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +9 -8
  415. package/packages/shared-skills/skills/ulw-plan/SKILL.md +6 -6
  416. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +31 -7
  417. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
  418. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
  419. package/packages/shared-skills/skills/ulw-research/SKILL.md +1 -1
  420. package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
  421. package/packages/shared-skills/skills/visual-qa/SKILL.md +3 -2
  422. package/script/qa/web-terminal-visual-qa.mjs +2 -0
  423. package/script/qa/xterm-live-terminal.mjs +18 -2
  424. package/dist/config/schema/start-work.d.ts +0 -5
  425. package/dist/features/builtin-commands/templates/start-work.d.ts +0 -1
  426. package/dist/hooks/start-work/start-work-hook.d.ts +0 -23
  427. package/dist/plugin/chat-message/start-work-message.d.ts +0 -5
  428. package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
  429. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
  430. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
  431. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
  432. package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
  433. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
  434. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
  435. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
  436. /package/dist/hooks/{start-work → ulw-execute}/context-info-formatters.d.ts +0 -0
  437. /package/dist/hooks/{start-work → ulw-execute}/explicit-plan-context.d.ts +0 -0
  438. /package/dist/hooks/{start-work → ulw-execute}/notepad-scaffold.d.ts +0 -0
  439. /package/dist/hooks/{start-work → ulw-execute}/parse-user-request.d.ts +0 -0
  440. /package/dist/hooks/{start-work → ulw-execute}/plan-discovery-context.d.ts +0 -0
  441. /package/dist/hooks/{start-work → ulw-execute}/plan-selection.d.ts +0 -0
  442. /package/dist/hooks/{start-work → ulw-execute}/session-plan-affinity.d.ts +0 -0
  443. /package/dist/hooks/{start-work → ulw-execute}/work-initializer.d.ts +0 -0
  444. /package/dist/hooks/{start-work → ulw-execute}/worktree-block.d.ts +0 -0
  445. /package/dist/hooks/{start-work → ulw-execute}/worktree-detector.d.ts +0 -0
  446. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
  447. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
  448. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/LICENSE +0 -0
  449. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
  450. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +0 -0
  451. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
  452. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
  453. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
  454. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
  455. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
  456. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
  457. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
  458. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
  459. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
  460. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
@@ -1,8 +1,8 @@
1
1
  import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
+ import { createRuleDiscoveryCache, findRuleCandidates } from "@oh-my-opencode/rules-engine/engine";
4
5
  import { afterEach, beforeEach, describe, expect, it } from "vitest";
5
-
6
6
  import {
7
7
  type CodexPostCompactInput,
8
8
  type CodexSessionStartInput,
@@ -10,7 +10,6 @@ import {
10
10
  runSessionStartHook,
11
11
  runUserPromptSubmitHook,
12
12
  } from "../src/codex-hook.js";
13
- import { createRuleDiscoveryCache, findRuleCandidates } from "@oh-my-opencode/rules-engine/engine";
14
13
 
15
14
  interface FixtureOptions {
16
15
  readonly writeProjectDuplicate?: boolean;
@@ -40,8 +39,12 @@ const DISABLED_BUNDLED_ENV = {
40
39
  CODEX_RULES_DISABLE_BUNDLED: "1",
41
40
  };
42
41
 
43
- const BUNDLED_BODY = "Bundled craftsman baseline.";
44
- const SHARED_BODY = "Always choose the smallest correct change.";
42
+ // Runtime sentinel: the rules hook emits and re-greps this marker when
43
+ // deduplicating injected rules against the transcript (transcript-rule-filter.ts).
44
+ const INSTRUCTIONS_FROM = "Instructions from: ";
45
+
46
+ const BUNDLED_BODY = "BUNDLED_PERSONA_SENTINEL";
47
+ const SHARED_BODY = "SHARED_RULE_SENTINEL";
45
48
 
46
49
  const tempDirectories: string[] = [];
47
50
  let originalPluginRoot: string | undefined;
@@ -130,10 +133,6 @@ function userPromptSubmitInput(root: string): Parameters<typeof runUserPromptSub
130
133
  };
131
134
  }
132
135
 
133
- function occurrenceCount(value: string, search: string): number {
134
- return value.split(search).length - 1;
135
- }
136
-
137
136
  describe("plugin bundled rules", () => {
138
137
  it("#given PLUGIN_ROOT with bundled markdown #when finding candidates #then plugin-bundled source is cached", () => {
139
138
  // given
@@ -162,11 +161,8 @@ describe("plugin bundled rules", () => {
162
161
 
163
162
  // then
164
163
  expect(output).toContain('"hookEventName":"SessionStart"');
165
- expect(output).toContain(`Instructions from: ${bundledRulePath}`);
164
+ expect(output).toContain(`${INSTRUCTIONS_FROM}${bundledRulePath}`);
166
165
  expect(output).toContain(BUNDLED_BODY);
167
- expect(output).toContain("## Project Instructions");
168
- expect(output).not.toContain("must read project rules:");
169
- expect(output).not.toContain(`- [hephaestus.md]{${bundledRulePath}}`);
170
166
  });
171
167
 
172
168
  it("#given same project and bundled body #when SessionStart runs #then project rule file wins", async () => {
@@ -180,8 +176,7 @@ describe("plugin bundled rules", () => {
180
176
  });
181
177
 
182
178
  // then
183
- expect(occurrenceCount(output, "- [hephaestus.md]{")).toBe(0);
184
- expect(output).toContain(`Instructions from: ${projectRulePath}`);
179
+ expect(output).toContain(`${INSTRUCTIONS_FROM}${projectRulePath}`);
185
180
  expect(output).toContain(SHARED_BODY);
186
181
  expect(output).not.toContain(bundledRulePath);
187
182
  });
@@ -207,7 +202,7 @@ describe("plugin bundled rules", () => {
207
202
  pluginDataRoot: pluginData,
208
203
  env: BUNDLED_ONLY_ENV,
209
204
  });
210
- expect(firstOutput).toContain(`Instructions from: ${bundledRulePath}`);
205
+ expect(firstOutput).toContain(`${INSTRUCTIONS_FROM}${bundledRulePath}`);
211
206
  expect(firstOutput).toContain(BUNDLED_BODY);
212
207
 
213
208
  // when
@@ -219,9 +214,8 @@ describe("plugin bundled rules", () => {
219
214
 
220
215
  // then
221
216
  expect(compactOutput).toBe("");
222
- expect(output).toContain(`Instructions from: ${bundledRulePath}`);
217
+ expect(output).toContain(`${INSTRUCTIONS_FROM}${bundledRulePath}`);
223
218
  expect(output).toContain(BUNDLED_BODY);
224
- expect(output).not.toContain("[Truncated. Full:");
225
219
  });
226
220
 
227
221
  it("#given bundled Hephaestus rule body exceeds per-rule cap #when SessionStart runs #then static context expands the body within result budget", async () => {
@@ -232,7 +226,7 @@ describe("plugin bundled rules", () => {
232
226
  tempDirectories.push(root, pluginRoot, pluginData);
233
227
  writeFileSync(join(root, "package.json"), JSON.stringify({ name: "fixture" }));
234
228
  mkdirSync(join(pluginRoot, "bundled-rules"), { recursive: true });
235
- const oversizedBody = "The bundled craftsman discipline is non-negotiable. ".repeat(400);
229
+ const oversizedBody = "BUNDLED_OVERSIZE_SENTINEL_".repeat(500);
236
230
  expect(oversizedBody.length).toBeGreaterThan(12000);
237
231
  const tailMarker = "BUNDLED_TAIL_SENTINEL_LANDS_IN_FULL";
238
232
  const bundledRulePath = join(pluginRoot, "bundled-rules", "hephaestus.md");
@@ -247,10 +241,9 @@ describe("plugin bundled rules", () => {
247
241
  });
248
242
 
249
243
  // then
250
- expect(output).toContain(`Instructions from: ${bundledRulePath}`);
251
- expect(output).toContain("The bundled craftsman discipline is non-negotiable.");
244
+ expect(output).toContain(`${INSTRUCTIONS_FROM}${bundledRulePath}`);
245
+ expect(output).toContain("BUNDLED_OVERSIZE_SENTINEL_");
252
246
  expect(output).toContain(tailMarker);
253
- expect(output).not.toContain("[Truncated. Full:");
254
247
  });
255
248
 
256
249
  it("#given project rule body exceeds per-rule cap #when SessionStart runs #then static context injects a truncated body", async () => {
@@ -262,7 +255,7 @@ describe("plugin bundled rules", () => {
262
255
  writeFileSync(join(root, "package.json"), JSON.stringify({ name: "fixture" }));
263
256
  mkdirSync(join(root, ".omo", "rules"), { recursive: true });
264
257
  mkdirSync(join(pluginRoot, "bundled-rules"), { recursive: true });
265
- const oversizedBody = "The project rule body is intentionally oversized for the cap test. ".repeat(300);
258
+ const oversizedBody = "PROJECT_OVERSIZE_SENTINEL_".repeat(500);
266
259
  expect(oversizedBody.length).toBeGreaterThan(12000);
267
260
  const tailMarker = "PROJECT_TAIL_SENTINEL_SHOULD_NOT_LAND";
268
261
  const projectRulePath = join(root, ".omo", "rules", "oversized.md");
@@ -277,9 +270,8 @@ describe("plugin bundled rules", () => {
277
270
  });
278
271
 
279
272
  // then
280
- expect(output).toContain(`Instructions from: ${projectRulePath}`);
281
- expect(output).toContain("The project rule body is intentionally oversized for the cap test.");
282
- expect(output).toContain("[Truncated. Full:");
273
+ expect(output).toContain(`${INSTRUCTIONS_FROM}${projectRulePath}`);
274
+ expect(output).toContain("PROJECT_OVERSIZE_SENTINEL_");
283
275
  expect(output).not.toContain(tailMarker);
284
276
  });
285
277
  });
@@ -18,6 +18,10 @@ const PROJECT_RULES_ENV = {
18
18
  CODEX_RULES_MAX_RULE_CHARS: "30000",
19
19
  };
20
20
 
21
+ // Runtime sentinel: the rules hook emits and re-greps this marker when
22
+ // deduplicating injected rules against the transcript (transcript-rule-filter.ts).
23
+ const INSTRUCTIONS_FROM = "Instructions from: ";
24
+
21
25
  afterEach(() => {
22
26
  for (const directory of tempDirectories.splice(0)) {
23
27
  rmSync(directory, { recursive: true, force: true });
@@ -46,15 +50,13 @@ describe("codex rules post-compaction context budget", () => {
46
50
  });
47
51
 
48
52
  // then
49
- expect(firstContext).toContain(`Instructions from: ${path.join(root, "CONTEXT.md")}`);
50
- expect(firstContext).toContain("Project rule");
51
- expect(firstContext).toContain("[Truncated. Full:");
53
+ expect(firstContext).toContain(`${INSTRUCTIONS_FROM}${path.join(root, "CONTEXT.md")}`);
54
+ expect(firstContext).toContain("CTX_OVERSIZE_SENTINEL");
55
+ expect(firstContext).not.toContain("CTX_TAIL_SENTINEL");
52
56
  expect(firstContext.length).toBeLessThan(31_000);
53
57
  const recoveryContext = readAdditionalContext(output);
54
- expect(recoveryContext).toContain("MUST READ");
55
- expect(recoveryContext).toContain("NO EXCUSES");
56
58
  expect(recoveryContext).toContain(path.join(root, "CONTEXT.md"));
57
- expect(recoveryContext).not.toContain("Project rule");
59
+ expect(recoveryContext).not.toContain("CTX_OVERSIZE_SENTINEL");
58
60
  expect(recoveryContext.length).toBeLessThan(2_000);
59
61
  });
60
62
  });
@@ -66,7 +68,7 @@ function makeOversizedProject(): { root: string; pluginData: string } {
66
68
  writeFileSync(path.join(root, "package.json"), JSON.stringify({ name: "fixture" }));
67
69
  writeFileSync(path.join(root, "AGENTS.md"), "Project AGENTS.md should stay Codex-native.");
68
70
  writeFileSync(path.join(root, "CLAUDE.md"), "Project CLAUDE.md should stay outside rules hook context.");
69
- writeFileSync(path.join(root, "CONTEXT.md"), `Project rule\n${"A".repeat(30_000)}`);
71
+ writeFileSync(path.join(root, "CONTEXT.md"), `CTX_OVERSIZE_SENTINEL\n${"A".repeat(30_000)}\nCTX_TAIL_SENTINEL`);
70
72
  mkdirSync(path.join(root, ".omo", "rules"), { recursive: true });
71
73
  writeFileSync(
72
74
  path.join(root, ".omo", "rules", "typescript.md"),
@@ -38,7 +38,6 @@ describe("codex rules compacted context recovery", () => {
38
38
  // then
39
39
  const postCompactContext = readAdditionalContext(output);
40
40
  expect(postCompactContext.length).toBeLessThan(2_000);
41
- expect(postCompactContext).toContain("MUST READ");
42
41
  expect(postCompactContext).toContain("CONTEXT.md");
43
42
  expect(postCompactContext).not.toContain("Project rule");
44
43
  });
@@ -65,7 +64,6 @@ describe("codex rules compacted context recovery", () => {
65
64
  // then
66
65
  const firstContext = readOptionalAdditionalContext(firstOutput);
67
66
  expect(firstContext.length).toBeLessThan(1_000);
68
- expect(firstContext).toContain("MUST READ");
69
67
  expect(firstContext).toContain("CONTEXT.md");
70
68
  expect(secondOutput).toBe("");
71
69
  });
@@ -88,7 +86,6 @@ describe("codex rules compacted context recovery", () => {
88
86
  // then
89
87
  const context = readOptionalAdditionalContext(output);
90
88
  expect(context.length).toBeLessThan(1_000);
91
- expect(context).toContain("MUST READ");
92
89
  expect(context).toContain("CONTEXT.md");
93
90
  });
94
91
 
@@ -106,7 +103,6 @@ describe("codex rules compacted context recovery", () => {
106
103
  // then
107
104
  const context = readOptionalAdditionalContext(output);
108
105
  expect(context.length).toBeLessThan(1_000);
109
- expect(context).toContain("MUST READ");
110
106
  expect(context).toContain("CONTEXT.md");
111
107
  });
112
108
 
@@ -128,7 +124,6 @@ describe("codex rules compacted context recovery", () => {
128
124
  // then
129
125
  const context = readOptionalAdditionalContext(output);
130
126
  expect(context.length).toBeLessThan(1_000);
131
- expect(context).toContain("MUST READ");
132
127
  expect(context).toContain("CONTEXT.md");
133
128
  });
134
129
 
@@ -157,7 +152,6 @@ describe("codex rules compacted context recovery", () => {
157
152
  const contexts = outputs.map(readOptionalAdditionalContext);
158
153
  expect(contexts.filter((context) => context.length > 0)).toHaveLength(1);
159
154
  expect(contexts.join("").length).toBeLessThan(1_000);
160
- expect(contexts.join("")).toContain("MUST READ");
161
155
  expect(contexts.join("")).toContain("CONTEXT.md");
162
156
  });
163
157
  });
@@ -18,6 +18,10 @@ const PROJECT_ONLY_ENV = {
18
18
  CODEX_RULES_ENABLED_SOURCES: "CONTEXT.md,.omo/rules",
19
19
  };
20
20
 
21
+ // Runtime sentinel: the rules hook emits and re-greps this marker when
22
+ // deduplicating injected rules against the transcript (transcript-rule-filter.ts).
23
+ const INSTRUCTIONS_FROM = "Instructions from: ";
24
+
21
25
  afterEach(() => {
22
26
  for (const directory of tempDirectories.splice(0)) {
23
27
  rmSync(directory, { recursive: true, force: true });
@@ -114,9 +118,8 @@ describe("codex rules PostCompact deduplication", () => {
114
118
 
115
119
  // then
116
120
  const context = readAdditionalContext(output);
117
- expect(context).toContain("MUST READ");
118
121
  expect(context).toContain("CONTEXT.md");
119
- expect(context).not.toContain("Instructions from:");
122
+ expect(context).not.toContain(INSTRUCTIONS_FROM);
120
123
  });
121
124
 
122
125
  it("#given startup static context dropped by compaction #when compact SessionStart runs after PostCompact #then it emits a mandatory read directive without rule bodies", async () => {
@@ -140,9 +143,8 @@ describe("codex rules PostCompact deduplication", () => {
140
143
 
141
144
  // then
142
145
  const context = readAdditionalContext(output);
143
- expect(context).toContain("MUST READ");
144
146
  expect(context).toContain("CONTEXT.md");
145
- expect(context).not.toContain("Instructions from:");
147
+ expect(context).not.toContain(INSTRUCTIONS_FROM);
146
148
  });
147
149
  });
148
150
 
@@ -1,8 +1,9 @@
1
- import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
1
+ import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2
2
  import { tmpdir } from "node:os";
3
3
  import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { parseRule } from "@oh-my-opencode/rules-engine/engine";
4
6
  import { afterEach, describe, expect, it } from "vitest";
5
-
6
7
  import {
7
8
  type CodexPostCompactInput,
8
9
  type CodexPostToolUseInput,
@@ -20,6 +21,10 @@ const PROJECT_ONLY_ENV = {
20
21
  };
21
22
  const SESSION_ID = "session-post-compact-directive";
22
23
 
24
+ // Runtime sentinel: the rules hook emits and re-greps this marker when
25
+ // deduplicating injected rules against the transcript (transcript-rule-filter.ts).
26
+ const INSTRUCTIONS_FROM = "Instructions from: ";
27
+
23
28
  afterEach(() => {
24
29
  for (const directory of tempDirectories.splice(0)) {
25
30
  rmSync(directory, { recursive: true, force: true });
@@ -48,10 +53,8 @@ describe("codex rules post-compaction read directive", () => {
48
53
  });
49
54
 
50
55
  // then
51
- expect(dynamicOutput).toContain("TypeScript rule");
56
+ expect(dynamicOutput).toContain("TS_RULE_SENTINEL");
52
57
  const context = readAdditionalContext(output);
53
- expect(context).toContain("MUST READ");
54
- expect(context).toContain("NO EXCUSES");
55
58
  expect(context).toContain("CONTEXT.md");
56
59
  expect(context).toContain(".omo/rules/typescript.md");
57
60
  expect(context).not.toContain("A".repeat(50));
@@ -125,9 +128,9 @@ describe("codex rules post-compaction read directive", () => {
125
128
 
126
129
  // then
127
130
  const context = readAdditionalContext(output);
128
- expect(context).toContain("You are Hephaestus");
129
- expect(context).not.toContain("[Truncated. Full:");
130
- expect(context).toContain("MUST READ");
131
+ const bundledRulePath = fileURLToPath(new URL("../bundled-rules/hephaestus/gpt-5.5.md", import.meta.url));
132
+ expect(context).toContain(`${INSTRUCTIONS_FROM}${bundledRulePath}`);
133
+ expect(context).toContain(parseRule(readFileSync(bundledRulePath, "utf8")).body.trim());
131
134
  expect(context).toContain("CONTEXT.md");
132
135
  });
133
136
  });
@@ -141,7 +144,7 @@ function makeProject(): { root: string; pluginData: string } {
141
144
  mkdirSync(path.join(root, ".omo", "rules"), { recursive: true });
142
145
  writeFileSync(
143
146
  path.join(root, ".omo", "rules", "typescript.md"),
144
- ["---", 'globs: "**/*.ts"', "---", "", `TypeScript rule\n${"B".repeat(2_000)}`].join("\n"),
147
+ ["---", 'globs: "**/*.ts"', "---", "", `TS_RULE_SENTINEL\n${"B".repeat(2_000)}`].join("\n"),
145
148
  );
146
149
  mkdirSync(path.join(root, "src"), { recursive: true });
147
150
  writeFileSync(path.join(root, "src", "app.ts"), "export const app = 1;\n");
@@ -77,6 +77,10 @@ const DYNAMIC_BUNDLED_ONLY_ENV = {
77
77
  PLUGIN_ROOT: COMPONENT_ROOT,
78
78
  };
79
79
 
80
+ // Runtime sentinel: the rules hook emits and re-greps this marker when
81
+ // deduplicating injected rules against the transcript (transcript-rule-filter.ts).
82
+ const INSTRUCTIONS_FROM = "Instructions from: ";
83
+
80
84
  afterEach(() => {
81
85
  for (const directory of tempDirectories.splice(0)) {
82
86
  rmSync(directory, { recursive: true, force: true });
@@ -88,20 +92,13 @@ function makeTempProject(): { root: string; pluginData: string } {
88
92
  const pluginData = mkdtempSync(path.join(tmpdir(), "codex-rules-data-"));
89
93
  tempDirectories.push(root, pluginData);
90
94
  writeFileSync(path.join(root, "package.json"), JSON.stringify({ name: "fixture" }));
91
- writeFileSync(path.join(root, "AGENTS.md"), "Project AGENTS.md should stay Codex-native.");
92
- writeFileSync(path.join(root, "CLAUDE.md"), "Project CLAUDE.md should stay outside rules hook context.");
93
- writeFileSync(path.join(root, "CONTEXT.md"), "Always wear safety goggles when refactoring.");
95
+ writeFileSync(path.join(root, "AGENTS.md"), "AGENTS_MD_SENTINEL");
96
+ writeFileSync(path.join(root, "CLAUDE.md"), "CLAUDE_MD_SENTINEL");
97
+ writeFileSync(path.join(root, "CONTEXT.md"), "CTX_RULE_SENTINEL");
94
98
  mkdirSync(path.join(root, ".omo", "rules"), { recursive: true });
95
99
  writeFileSync(
96
100
  path.join(root, ".omo", "rules", "typescript.md"),
97
- [
98
- "---",
99
- "description: TypeScript",
100
- 'globs: ["**/*.ts", "**/*.tsx"]',
101
- "---",
102
- "",
103
- "Prefer strict TypeScript for all source files.",
104
- ].join("\n"),
101
+ ["---", "description: TypeScript", 'globs: ["**/*.ts", "**/*.tsx"]', "---", "", "TS_RULE_SENTINEL"].join("\n"),
105
102
  );
106
103
  mkdirSync(path.join(root, "src"), { recursive: true });
107
104
  writeFileSync(path.join(root, "src", "app.ts"), "export const app = true;\n");
@@ -224,11 +221,10 @@ describe("codex rules hooks", () => {
224
221
  // then
225
222
  const parsed = parseHookOutput(output);
226
223
  expect(parsed.hookSpecificOutput?.hookEventName).toBe("SessionStart");
227
- expect(parsed.hookSpecificOutput?.additionalContext).toContain("## Project Instructions");
228
224
  expect(parsed.hookSpecificOutput?.additionalContext).toContain(
229
- `Instructions from: ${path.join(root, "CONTEXT.md")}`,
225
+ `${INSTRUCTIONS_FROM}${path.join(root, "CONTEXT.md")}`,
230
226
  );
231
- expect(parsed.hookSpecificOutput?.additionalContext).toContain("Always wear safety goggles");
227
+ expect(parsed.hookSpecificOutput?.additionalContext).toContain("CTX_RULE_SENTINEL");
232
228
  });
233
229
 
234
230
  it("#given default auto sources #when SessionStart runs #then native Codex AGENTS.md is not duplicated", async () => {
@@ -242,11 +238,11 @@ describe("codex rules hooks", () => {
242
238
 
243
239
  // then
244
240
  const parsed = parseHookOutput(output);
245
- expect(parsed.hookSpecificOutput?.additionalContext).toContain("## Project Instructions");
246
- expect(parsed.hookSpecificOutput?.additionalContext).not.toContain("Project AGENTS.md should stay Codex-native.");
247
- expect(parsed.hookSpecificOutput?.additionalContext).not.toContain(
248
- "Project CLAUDE.md should stay outside rules hook context.",
241
+ expect(parsed.hookSpecificOutput?.additionalContext).toContain(
242
+ `${INSTRUCTIONS_FROM}${path.join(root, "CONTEXT.md")}`,
249
243
  );
244
+ expect(parsed.hookSpecificOutput?.additionalContext).not.toContain("AGENTS_MD_SENTINEL");
245
+ expect(parsed.hookSpecificOutput?.additionalContext).not.toContain("CLAUDE_MD_SENTINEL");
250
246
  });
251
247
 
252
248
  it("#given project AGENTS.md #when SessionStart runs #then rules hook leaves AGENTS.md to Codex native handling", async () => {
@@ -320,9 +316,8 @@ describe("codex rules hooks", () => {
320
316
  // then
321
317
  expect(resumeOutput).toBe("");
322
318
  const clearContext = parseHookOutput(clearOutput).hookSpecificOutput?.additionalContext ?? "";
323
- expect(clearContext).toContain("## Project Instructions");
324
- expect(clearContext).toContain(`Instructions from: ${path.join(root, "CONTEXT.md")}`);
325
- expect(clearContext).toContain("Always wear safety goggles");
319
+ expect(clearContext).toContain(`${INSTRUCTIONS_FROM}${path.join(root, "CONTEXT.md")}`);
320
+ expect(clearContext).toContain("CTX_RULE_SENTINEL");
326
321
  });
327
322
 
328
323
  it("#given static context remains in transcript but cache is missing #when SessionStart runs #then it emits no duplicate context", async () => {
@@ -363,10 +358,8 @@ describe("codex rules hooks", () => {
363
358
  // regression line: prior versions emitted "src\\app.ts" on Windows.
364
359
  const parsed = parseHookOutput(output);
365
360
  expect(parsed.hookSpecificOutput?.hookEventName).toBe("PostToolUse");
366
- expect(parsed.hookSpecificOutput?.additionalContext).toContain(
367
- "Additional project instructions matched for src/app.ts",
368
- );
369
- expect(parsed.hookSpecificOutput?.additionalContext).toContain("Prefer strict TypeScript");
361
+ expect(parsed.hookSpecificOutput?.additionalContext).toContain("src/app.ts");
362
+ expect(parsed.hookSpecificOutput?.additionalContext).toContain("TS_RULE_SENTINEL");
370
363
  expect(parsed.hookSpecificOutput?.additionalContext ?? "").not.toContain("src\\app.ts");
371
364
  expect(output).not.toContain("updatedMCPToolOutput");
372
365
  expect(output).not.toContain("suppressOutput");
@@ -396,9 +389,9 @@ describe("codex rules hooks", () => {
396
389
  const parsed = parseHookOutput(output);
397
390
  const additionalContext = parsed.hookSpecificOutput?.additionalContext ?? "";
398
391
  expect(parsed.hookSpecificOutput?.hookEventName).toBe("PostToolUse");
399
- expect(additionalContext).toContain("Additional project instructions matched for src/app.ts");
392
+ expect(additionalContext).toContain("src/app.ts");
400
393
  expect(additionalContext).not.toContain("src\\app.ts");
401
- expect(occurrenceCount(additionalContext, "Prefer strict TypeScript")).toBe(1);
394
+ expect(occurrenceCount(additionalContext, "TS_RULE_SENTINEL")).toBe(1);
402
395
  });
403
396
 
404
397
  it("#given dynamic context already injected #when PostToolUse repeats #then emits no duplicate context", async () => {
@@ -437,10 +430,10 @@ describe("codex rules hooks", () => {
437
430
  // then
438
431
  const firstContext = parseHookOutput(firstOutput).hookSpecificOutput?.additionalContext ?? "";
439
432
  const secondContext = parseHookOutput(secondOutput).hookSpecificOutput?.additionalContext ?? "";
440
- expect(firstContext).toContain("based on GPT-5.5");
441
- expect(firstContext).not.toContain("based on GPT-5.6");
442
- expect(secondContext).toContain("based on GPT-5.6");
443
- expect(secondContext).not.toContain("based on GPT-5.5");
433
+ expect(firstContext).toContain("bundled-rules/hephaestus/gpt-5.5.md");
434
+ expect(firstContext).not.toContain("bundled-rules/hephaestus/gpt-5.6.md");
435
+ expect(secondContext).toContain("bundled-rules/hephaestus/gpt-5.6.md");
436
+ expect(secondContext).not.toContain("bundled-rules/hephaestus/gpt-5.5.md");
444
437
  });
445
438
 
446
439
  it("#given default auto sources #when excluded AGENTS.md changes #then PostToolUse fingerprint stays stable", async () => {
@@ -496,7 +489,7 @@ describe("codex rules hooks", () => {
496
489
  );
497
490
 
498
491
  // then
499
- expect(parseHookOutput(output).hookSpecificOutput?.additionalContext).toContain("Prefer strict TypeScript");
492
+ expect(parseHookOutput(output).hookSpecificOutput?.additionalContext).toContain("TS_RULE_SENTINEL");
500
493
  });
501
494
 
502
495
  it("#given cached dynamic target #when rule frontmatter changes #then PostToolUse rechecks the target", async () => {
@@ -505,15 +498,13 @@ describe("codex rules hooks", () => {
505
498
  const filePath = path.join(root, "src", "app.ts");
506
499
  const input = postToolUseInput(root, filePath);
507
500
  await runPostToolUseHook(input, { pluginDataRoot: pluginData, env: RULES_ONLY_ENV });
508
- writeTypeScriptRule(root, '"**/*.ts"', "Prefer readonly TypeScript after rule edits.");
501
+ writeTypeScriptRule(root, '"**/*.ts"', "TS_RULE_V2_SENTINEL");
509
502
 
510
503
  // when
511
504
  const output = await runPostToolUseHook(input, { pluginDataRoot: pluginData, env: RULES_ONLY_ENV });
512
505
 
513
506
  // then
514
- expect(parseHookOutput(output).hookSpecificOutput?.additionalContext).toContain(
515
- "Prefer readonly TypeScript after rule edits.",
516
- );
507
+ expect(parseHookOutput(output).hookSpecificOutput?.additionalContext).toContain("TS_RULE_V2_SENTINEL");
517
508
  });
518
509
 
519
510
  it("#given cached dynamic context #when PostCompact runs #then PostToolUse emits no duplicate dynamic context", async () => {
@@ -633,7 +624,7 @@ describe("codex rules hooks", () => {
633
624
  });
634
625
 
635
626
  // then
636
- expect(parseHookOutput(output).hookSpecificOutput?.additionalContext).toContain("Prefer strict TypeScript");
627
+ expect(parseHookOutput(output).hookSpecificOutput?.additionalContext).toContain("TS_RULE_SENTINEL");
637
628
  });
638
629
 
639
630
  it("#given static-only mode #when PostToolUse runs #then emits no dynamic context", async () => {
@@ -1,10 +1,9 @@
1
1
  import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
2
2
  import { tmpdir } from "node:os";
3
3
  import path from "node:path";
4
+ import { defaultConfig } from "@oh-my-opencode/rules-engine/engine";
4
5
  import { afterEach, describe, expect, it } from "vitest";
5
-
6
6
  import { fingerprintDynamicTargets } from "../src/dynamic-target-fingerprints.js";
7
- import { defaultConfig } from "@oh-my-opencode/rules-engine/engine";
8
7
 
9
8
  const tempDirectories: string[] = [];
10
9
 
@@ -1,10 +1,13 @@
1
1
  import { join } from "node:path";
2
+ import type { RuleCandidate } from "@oh-my-opencode/rules-engine/engine";
3
+ import {
4
+ createEngine,
5
+ defaultConfig,
6
+ matchRule as defaultMatchRule,
7
+ type EngineDeps,
8
+ } from "@oh-my-opencode/rules-engine/engine";
2
9
  import { describe, expect, it } from "vitest";
3
-
4
10
  import { configFromEnvironment } from "../src/config.js";
5
- import { createEngine, defaultConfig, type EngineDeps } from "@oh-my-opencode/rules-engine/engine";
6
- import { matchRule as defaultMatchRule } from "@oh-my-opencode/rules-engine/engine";
7
- import type { RuleCandidate } from "@oh-my-opencode/rules-engine/engine";
8
11
 
9
12
  const projectRoot = "/tmp/codex-rules-engine";
10
13
 
@@ -1,10 +1,9 @@
1
1
  import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
- import { afterEach, describe, expect, it } from "vitest";
5
-
6
- import { findRuleCandidates } from "@oh-my-opencode/rules-engine/engine";
7
4
  import type { RuleCandidate } from "@oh-my-opencode/rules-engine/engine";
5
+ import { findRuleCandidates } from "@oh-my-opencode/rules-engine/engine";
6
+ import { afterEach, describe, expect, it } from "vitest";
8
7
 
9
8
  const tempDirectories: string[] = [];
10
9