oh-my-opencode 4.16.3 → 4.17.1

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 (220) hide show
  1. package/.agents/command/omomomo.md +1 -1
  2. package/.agents/command/publish.md +31 -58
  3. package/.agents/skills/hyperplan/SKILL.md +3 -3
  4. package/.agents/skills/omomomo/SKILL.md +1 -1
  5. package/.agents/skills/pre-publish-review/SKILL.md +1 -1
  6. package/.agents/skills/publish/SKILL.md +32 -59
  7. package/.opencode/command/omomomo.md +1 -1
  8. package/.opencode/command/publish.md +31 -58
  9. package/.opencode/skills/hyperplan/SKILL.md +3 -3
  10. package/.opencode/skills/pre-publish-review/SKILL.md +4 -1
  11. package/README.ja.md +4 -4
  12. package/README.ko.md +4 -4
  13. package/README.md +2 -2
  14. package/README.ru.md +4 -4
  15. package/README.zh-cn.md +4 -4
  16. package/dist/cli/index.js +195 -76
  17. package/dist/cli-node/index.js +195 -76
  18. package/dist/features/team-mode/test-support/async-test-helpers.d.ts +2 -2
  19. package/dist/index.js +310 -299
  20. package/dist/plugin/chat-message/types.d.ts +4 -0
  21. package/dist/plugin/command-execute-before.d.ts +1 -0
  22. package/dist/plugin/stop-continuation.d.ts +17 -0
  23. package/dist/skills/remove-ai-slops/SKILL.md +2 -2
  24. package/dist/skills/review-work/SKILL.md +10 -2
  25. package/dist/skills/start-work/SKILL.md +6 -3
  26. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +2 -2
  27. package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
  28. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +11 -11
  29. package/dist/skills/ulw-plan/SKILL.md +2 -1
  30. package/dist/skills/ulw-plan/references/full-workflow.md +1 -1
  31. package/dist/skills/ulw-plan/references/intent-unclear.md +4 -4
  32. package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +2 -2
  33. package/dist/skills/visual-qa/SKILL.md +9 -5
  34. package/dist/tui.js +79 -32
  35. package/package.json +15 -14
  36. package/packages/git-bash-mcp/package.json +27 -0
  37. package/packages/lsp-daemon/dist/cli.js +7 -13
  38. package/packages/lsp-daemon/dist/daemon-client.js +3 -5
  39. package/packages/lsp-daemon/dist/index.js +12 -18
  40. package/packages/lsp-daemon/dist/request-routing.js +6 -8
  41. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +3 -1
  42. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +1080 -1017
  43. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  44. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  45. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  46. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  47. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  48. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  49. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  50. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/AGENTS.md +2 -2
  51. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +6 -2
  52. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +6 -2
  53. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +2 -2
  54. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  55. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +6 -2
  56. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/cli.test.ts +1 -1
  57. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +67 -2
  58. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +14 -14
  59. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  60. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  61. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +0 -13
  62. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.5.md +2 -2
  63. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.6.md +3 -3
  64. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  65. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  66. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  67. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  68. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +1 -79
  69. package/packages/omo-codex/plugin/components/teammode/AGENTS.md +2 -2
  70. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  71. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  72. package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +33 -16
  73. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +2 -1
  74. package/packages/omo-codex/plugin/components/teammode/test/v2-spawn-schema.test.ts +69 -0
  75. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  76. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  77. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +2 -2
  78. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +2 -2
  79. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +6 -6
  80. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-qa-executor.toml +5 -5
  81. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +26 -0
  82. package/packages/omo-codex/plugin/components/ultrawork/agents/{lazycodex-executor.toml → lazycodex-worker-low.toml} +6 -4
  83. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +26 -0
  84. package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +2 -2
  85. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +7 -7
  86. package/packages/omo-codex/plugin/components/ultrawork/directive.md +76 -37
  87. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  88. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  89. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +76 -37
  90. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +2 -1
  91. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +1 -1
  92. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +4 -4
  93. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +2 -2
  94. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +25 -0
  95. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +0 -68
  96. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +1 -1
  97. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +2 -0
  98. package/packages/omo-codex/plugin/components/ulw-loop/README.md +3 -1
  99. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +76 -37
  100. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +6 -1
  101. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.d.ts +1 -1
  102. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +13 -2
  103. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +405 -25
  104. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +12 -1
  105. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +4 -2
  106. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.d.ts +7 -0
  107. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +16 -1
  108. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +1 -0
  109. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.d.ts +6 -0
  110. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +20 -0
  111. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +1 -0
  112. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +12 -9
  113. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.d.ts +3 -0
  114. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +148 -0
  115. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.d.ts +2 -0
  116. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +209 -0
  117. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +25 -2
  118. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  119. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +14 -15
  120. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +30 -28
  121. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +6 -1
  122. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +14 -3
  123. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +10 -0
  124. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +12 -1
  125. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +4 -2
  126. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +27 -1
  127. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +1 -0
  128. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +23 -0
  129. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +16 -9
  130. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +138 -0
  131. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +208 -0
  132. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +12 -0
  133. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +4 -1
  134. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +8 -35
  135. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +24 -13
  136. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -2
  137. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +43 -8
  138. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +55 -2
  139. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +228 -0
  140. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +193 -0
  141. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  142. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  143. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  144. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  145. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  146. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  147. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  148. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  149. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  150. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +18 -0
  151. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  152. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  153. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  154. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  155. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  156. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  157. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  158. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +17 -0
  159. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  160. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +2 -2
  161. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  162. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  163. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  164. package/packages/omo-codex/plugin/model-catalog.json +16 -7
  165. package/packages/omo-codex/plugin/package-lock.json +13 -13
  166. package/packages/omo-codex/plugin/package.json +1 -1
  167. package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +16 -7
  168. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +8 -2
  169. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +2 -2
  170. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +2 -2
  171. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +4 -4
  172. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +18 -4
  173. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +6 -3
  174. package/packages/omo-codex/plugin/skills/teammode/SKILL.md +33 -16
  175. package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +2 -1
  176. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +2 -2
  177. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
  178. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +11 -11
  179. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +76 -37
  180. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +14 -15
  181. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +30 -28
  182. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +2 -1
  183. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +1 -1
  184. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +4 -4
  185. package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +2 -2
  186. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +2 -2
  187. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +11 -7
  188. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +76 -16
  189. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +23 -2
  190. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -1
  191. package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +4 -4
  192. package/packages/omo-codex/plugin/test/auto-update.test.mjs +4 -4
  193. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +2 -2
  194. package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +4 -101
  195. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +14 -14
  196. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +11 -0
  197. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +1 -1
  198. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +5 -3
  199. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +25 -0
  200. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +24 -0
  201. package/packages/omo-codex/plugin/test/ulw-plan-skill-contract.test.mjs +9 -40
  202. package/packages/omo-codex/plugin/test/ulw-research-skill-contract.test.mjs +4 -277
  203. package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +5 -5
  204. package/packages/omo-codex/scripts/install-config.test.mjs +22 -3
  205. package/packages/omo-codex/scripts/install-dist/install-local.mjs +98 -30
  206. package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +2 -2
  207. package/packages/shared-skills/skills/review-work/SKILL.md +10 -2
  208. package/packages/shared-skills/skills/start-work/SKILL.md +6 -3
  209. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +2 -2
  210. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
  211. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +11 -11
  212. package/packages/shared-skills/skills/ulw-plan/SKILL.md +2 -1
  213. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +1 -1
  214. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +4 -4
  215. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +2 -2
  216. package/packages/shared-skills/skills/visual-qa/SKILL.md +9 -5
  217. package/dist/skills/visual-qa/scripts/skill-prompt-contract.test.ts +0 -296
  218. package/packages/omo-codex/plugin/components/ulw-loop/test/skill-contract.test.ts +0 -70
  219. package/packages/omo-codex/plugin/test/ulw-research-epistemic-contract.test.mjs +0 -98
  220. package/packages/shared-skills/skills/visual-qa/scripts/skill-prompt-contract.test.ts +0 -296
@@ -8,7 +8,7 @@
8
8
  "command": "node \"${PLUGIN_ROOT}/components/bootstrap/dist/cli.js\" hook session-start",
9
9
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\bootstrap.ps1\"",
10
10
  "timeout": 30,
11
- "statusMessage": "(OmO 4.16.3) Checking Bootstrap Provisioning"
11
+ "statusMessage": "(OmO 4.17.1) Checking Bootstrap Provisioning"
12
12
  }
13
13
  ]
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sisyphuslabs/codex-bootstrap",
3
- "version": "4.16.3",
3
+ "version": "4.17.1",
4
4
  "description": "Codex SessionStart bootstrap component that provisions LazyCodex runtime dependencies from a detached worker.",
5
5
  "type": "module",
6
6
  "private": true,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sisyphuslabs/codex-codegraph",
3
- "version": "4.16.3",
3
+ "version": "4.17.1",
4
4
  "description": "Codex plugin MCP wrapper for CodeGraph.",
5
5
  "type": "module",
6
6
  "private": true,
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
10
10
  "timeout": 30,
11
- "statusMessage": "(OmO 4.16.3) Checking Comments"
11
+ "statusMessage": "(OmO 4.17.1) Checking Comments"
12
12
  }
13
13
  ]
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-comment-checker",
3
- "version": "4.16.3",
3
+ "version": "4.17.1",
4
4
  "description": "Codex plugin that runs comment-checker after edit-like PostToolUse hooks.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook pre-tool-use",
10
10
  "timeout": 5,
11
- "statusMessage": "(OmO 4.16.3) Recommending Git Bash MCP"
11
+ "statusMessage": "(OmO 4.17.1) Recommending Git Bash MCP"
12
12
  }
13
13
  ]
14
14
  }
@@ -20,7 +20,7 @@
20
20
  "type": "command",
21
21
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
22
22
  "timeout": 5,
23
- "statusMessage": "(OmO 4.16.3) Resetting Git Bash MCP Reminder"
23
+ "statusMessage": "(OmO 4.17.1) Resetting Git Bash MCP Reminder"
24
24
  }
25
25
  ]
26
26
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sisyphuslabs/codex-git-bash-hook",
3
- "version": "4.16.3",
3
+ "version": "4.17.1",
4
4
  "description": "Codex hook component that reminds Windows sessions to prefer the OMO git_bash MCP.",
5
5
  "type": "module",
6
6
  "private": true,
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## OVERVIEW
6
6
 
7
- Codex `SubagentStop` hook component: the evidence gate for the `lazycodex-executor` subagent (ultrawork implementation executor). When the executor stops without a valid evidence receipt, the hook emits `{"decision": "block", "reason": <directive>}` and Codex sends it back to work. Matcher is `^lazycodex-executor$` only; `lazycodex-qa-executor` and `lazycodex-gate-reviewer` (same `ultrawork/agents/` family) are NOT gated by this hook.
7
+ Codex `SubagentStop` hook component: the evidence gate for the ultrawork implementation workers (`lazycodex-worker-low|medium|high`). When a worker stops without a valid evidence receipt, the hook emits `{"decision": "block", "reason": <directive>}` and Codex sends it back to work. Matcher is `^lazycodex-worker-(low|medium|high)$`; read-only roles like `lazycodex-qa-executor` and `lazycodex-gate-reviewer` (same `ultrawork/agents/` family) are NOT gated by this hook. (The historical `lazycodex-executor` agent was removed; this component keeps its name.)
8
8
 
9
9
  Valid receipt: `last_assistant_message` contains `EVIDENCE_RECORDED: <path>` where `<path>` resolves to a non-empty regular file strictly inside `<cwd>/.omo/evidence/`. Symlinks and directories rejected; containment checked on realpaths (file inside evidence root inside cwd, traversal-safe). A valid receipt clears attempt state and exits silently.
10
10
 
@@ -30,7 +30,7 @@ Escape hatches: after 3 blocked attempts (`MAX_ATTEMPTS`) the stop passes and st
30
30
  | Change the block message | `directive.md`; keep both `{{...}}` placeholders and the literal `EVIDENCE_RECORDED: <path>` final-line contract |
31
31
  | Change receipt validation | `src/codex-hook.ts` (`hasValidEvidenceReceipt`, `extractEvidencePath`, `isNonEmptyFileInsideEvidenceRoot`) |
32
32
  | Change the retry budget | `src/state.ts` `MAX_ATTEMPTS` |
33
- | Executor-side contract | `../ultrawork/agents/lazycodex-executor.toml` instructs the final `EVIDENCE_RECORDED: <path>` line this hook parses |
33
+ | Worker-side contract | `../ultrawork/agents/lazycodex-worker-{low,medium,high}.toml` instruct the final `EVIDENCE_RECORDED: <path>` line this hook parses |
34
34
  | Plugin-level wiring | `../../hooks/subagent-stop-verifying-lazycodex-executor-evidence.json` (adds `commandWindows` via `../bootstrap/scripts/node-dispatch.ps1`) |
35
35
  | Wiring + contract tests | `../../test/aggregate-hooks.test.mjs`, `../../test/component-hook-contract-cases.mjs`, `../../test/hook-status-message.test.mjs`, `../../test/component-bundled-cli.test.mjs` |
36
36
 
@@ -66,11 +66,15 @@ function isRecord(value) {
66
66
  var SUBAGENT_STOP_EVENT = "SubagentStop";
67
67
 
68
68
  // components/lazycodex-executor-verify/src/codex-hook.ts
69
- var LAZYCODEX_EXECUTOR_AGENT = "lazycodex-executor";
69
+ var RECEIPT_ENFORCED_AGENTS = new Set([
70
+ "lazycodex-worker-low",
71
+ "lazycodex-worker-medium",
72
+ "lazycodex-worker-high"
73
+ ]);
70
74
  function runSubagentStopHook(input, fs) {
71
75
  if (!isSubagentStopInput(input))
72
76
  return "";
73
- if (input.agent_type !== LAZYCODEX_EXECUTOR_AGENT)
77
+ if (!RECEIPT_ENFORCED_AGENTS.has(input.agent_type))
74
78
  return "";
75
79
  if (transcriptHasContextPressureMarker(input.transcript_path, fs))
76
80
  return "";
@@ -3,11 +3,15 @@ import { isAbsolute, relative, resolve } from "node:path";
3
3
  import { renderDirective } from "./directive.js";
4
4
  import { clearAttemptState, MAX_ATTEMPTS, readAttemptState, writeAttemptState } from "./state.js";
5
5
  import { SUBAGENT_STOP_EVENT } from "./types.js";
6
- const LAZYCODEX_EXECUTOR_AGENT = "lazycodex-executor";
6
+ const RECEIPT_ENFORCED_AGENTS = new Set([
7
+ "lazycodex-worker-low",
8
+ "lazycodex-worker-medium",
9
+ "lazycodex-worker-high",
10
+ ]);
7
11
  export function runSubagentStopHook(input, fs) {
8
12
  if (!isSubagentStopInput(input))
9
13
  return "";
10
- if (input.agent_type !== LAZYCODEX_EXECUTOR_AGENT)
14
+ if (!RECEIPT_ENFORCED_AGENTS.has(input.agent_type))
11
15
  return "";
12
16
  if (transcriptHasContextPressureMarker(input.transcript_path, fs))
13
17
  return "";
@@ -2,13 +2,13 @@
2
2
  "hooks": {
3
3
  "SubagentStop": [
4
4
  {
5
- "matcher": "^lazycodex-executor$",
5
+ "matcher": "^lazycodex-worker-(low|medium|high)$",
6
6
  "hooks": [
7
7
  {
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/components/lazycodex-executor-verify/dist/cli.js\" hook subagent-stop",
10
10
  "timeout": 10,
11
- "statusMessage": "(OmO 4.16.3) Verifying LazyCodex Executor Evidence"
11
+ "statusMessage": "(OmO 4.17.1) Verifying LazyCodex Executor Evidence"
12
12
  }
13
13
  ]
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-lazycodex-executor-verify",
3
- "version": "4.16.3",
3
+ "version": "4.17.1",
4
4
  "description": "Codex SubagentStop evidence verifier for LazyCodex executor completions.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -6,11 +6,15 @@ import { clearAttemptState, MAX_ATTEMPTS, readAttemptState, writeAttemptState }
6
6
  import type { HookFileSystem, StopHookOutput, SubagentStopInput } from "./types.js";
7
7
  import { SUBAGENT_STOP_EVENT } from "./types.js";
8
8
 
9
- const LAZYCODEX_EXECUTOR_AGENT = "lazycodex-executor";
9
+ const RECEIPT_ENFORCED_AGENTS = new Set([
10
+ "lazycodex-worker-low",
11
+ "lazycodex-worker-medium",
12
+ "lazycodex-worker-high",
13
+ ]);
10
14
 
11
15
  export function runSubagentStopHook(input: unknown, fs: HookFileSystem): string {
12
16
  if (!isSubagentStopInput(input)) return "";
13
- if (input.agent_type !== LAZYCODEX_EXECUTOR_AGENT) return "";
17
+ if (!RECEIPT_ENFORCED_AGENTS.has(input.agent_type)) return "";
14
18
  if (transcriptHasContextPressureMarker(input.transcript_path, fs)) return "";
15
19
  if (hasValidEvidenceReceipt(input, fs)) {
16
20
  clearAttemptState(input.cwd, input.session_id, input.agent_id, fs);
@@ -110,7 +110,7 @@ function createPayload(
110
110
  ): Record<string, string | boolean> {
111
111
  return {
112
112
  hook_event_name: "SubagentStop",
113
- agent_type: "lazycodex-executor",
113
+ agent_type: "lazycodex-worker-medium",
114
114
  agent_id: "agent_1",
115
115
  session_id: "sess.1",
116
116
  cwd,
@@ -299,7 +299,7 @@ function existingReceiptTargetOutsideEvidenceRoot(): string {
299
299
  function createInput(cwd: string, overrides: Partial<SubagentStopInput> = {}): SubagentStopInput {
300
300
  return {
301
301
  hook_event_name: "SubagentStop",
302
- agent_type: "lazycodex-executor",
302
+ agent_type: "lazycodex-worker-medium",
303
303
  agent_id: "agent_1",
304
304
  session_id: "sess.1",
305
305
  cwd,
@@ -315,7 +315,7 @@ function createInput(cwd: string, overrides: Partial<SubagentStopInput> = {}): S
315
315
  function createUnknownEventInput(cwd: string): Record<string, string | boolean> {
316
316
  return {
317
317
  hook_event_name: "Stop",
318
- agent_type: "lazycodex-executor",
318
+ agent_type: "lazycodex-worker-medium",
319
319
  agent_id: "agent_1",
320
320
  session_id: "sess.1",
321
321
  cwd,
@@ -344,3 +344,68 @@ function isBlockOutput(value: unknown): value is BlockOutput {
344
344
  typeof value.reason === "string"
345
345
  );
346
346
  }
347
+
348
+ describe("tier worker receipt enforcement", () => {
349
+ // given the matcher set now covers the difficulty-tier workers
350
+ const workerTypes = ["lazycodex-worker-low", "lazycodex-worker-medium", "lazycodex-worker-high"] as const;
351
+
352
+ for (const agentType of workerTypes) {
353
+ it(`#given no evidence receipt #when a ${agentType} child stops #then blocks`, () => {
354
+ // given
355
+ const cwd = createWorkspace();
356
+
357
+ // when
358
+ const output = runSubagentStopHook(createInput(cwd, { agent_type: agentType }), nodeFileSystem);
359
+
360
+ // then
361
+ expect(parseBlockOutput(output).decision).toBe("block");
362
+ });
363
+ }
364
+
365
+ it("#given no evidence receipt #when an explorer child stops #then no-ops", () => {
366
+ // given
367
+ const cwd = createWorkspace();
368
+
369
+ // when
370
+ const output = runSubagentStopHook(createInput(cwd, { agent_type: "explorer" }), nodeFileSystem);
371
+
372
+ // then
373
+ expect(output).toBe("");
374
+ });
375
+
376
+ it("#given both hook manifests #when their matchers are applied #then enforced agents match and read-only roles do not", () => {
377
+ // given
378
+ const componentManifest = JSON.parse(
379
+ readFileSync(new URL("../hooks/hooks.json", import.meta.url), "utf8"),
380
+ );
381
+ const rootManifest = JSON.parse(
382
+ readFileSync(
383
+ new URL("../../../hooks/subagent-stop-verifying-lazycodex-executor-evidence.json", import.meta.url),
384
+ "utf8",
385
+ ),
386
+ );
387
+ for (const manifest of [componentManifest, rootManifest]) {
388
+ const matcher = new RegExp(manifest.hooks.SubagentStop[0].matcher);
389
+
390
+ // then
391
+ for (const name of workerTypes) expect(matcher.test(name)).toBe(true);
392
+ expect(matcher.test("lazycodex-executor")).toBe(false);
393
+ expect(matcher.test("explorer")).toBe(false);
394
+ expect(matcher.test("lazycodex-gate-reviewer")).toBe(false);
395
+ }
396
+ });
397
+
398
+ it("#given the tier worker TOMLs #when inspected #then each instructs the EVIDENCE_RECORDED receipt line", () => {
399
+ for (const tier of ["low", "medium", "high"]) {
400
+ // when
401
+ const toml = readFileSync(
402
+ new URL(`../../ultrawork/agents/lazycodex-worker-${tier}.toml`, import.meta.url),
403
+ "utf8",
404
+ );
405
+
406
+ // then
407
+ expect(toml).toContain("EVIDENCE_RECORDED: <path>");
408
+ }
409
+ });
410
+ });
411
+
@@ -1423,6 +1423,9 @@ async function disposeDefaultLspManager() {
1423
1423
  await m.stopAll();
1424
1424
  }
1425
1425
  }
1426
+ function isPlainRecord(value) {
1427
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1428
+ }
1426
1429
  function isProcessAlive(pid) {
1427
1430
  if (!Number.isInteger(pid) || pid <= 0)
1428
1431
  return false;
@@ -3313,10 +3316,10 @@ function sendToolCall(socketPath, name, args, timeoutMs) {
3313
3316
  });
3314
3317
  }
3315
3318
  function toToolResult(message) {
3316
- if (!isRecord6(message) || message["id"] !== REQUEST_ID)
3319
+ if (!isPlainRecord(message) || message["id"] !== REQUEST_ID)
3317
3320
  return null;
3318
3321
  const result = message["result"];
3319
- if (!isRecord6(result) || !Array.isArray(result["content"]))
3322
+ if (!isPlainRecord(result) || !Array.isArray(result["content"]))
3320
3323
  return null;
3321
3324
  return {
3322
3325
  content: result["content"],
@@ -3324,9 +3327,6 @@ function toToolResult(message) {
3324
3327
  details: result["details"]
3325
3328
  };
3326
3329
  }
3327
- function isRecord6(value) {
3328
- return typeof value === "object" && value !== null && !Array.isArray(value);
3329
- }
3330
3330
  function errorText(error) {
3331
3331
  return error instanceof Error ? error.message : String(error);
3332
3332
  }
@@ -3450,7 +3450,7 @@ function readSessionState(path) {
3450
3450
  return parsed;
3451
3451
  return emptyState();
3452
3452
  } catch (error) {
3453
- if (error instanceof SyntaxError || isRecord7(error) && error["code"] === "ENOENT")
3453
+ if (error instanceof SyntaxError || isRecord6(error) && error["code"] === "ENOENT")
3454
3454
  return emptyState();
3455
3455
  throw error;
3456
3456
  }
@@ -3471,12 +3471,12 @@ function safePathSegment(value) {
3471
3471
  return value.replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 120) || "unknown-session";
3472
3472
  }
3473
3473
  function isLspSessionState(value) {
3474
- if (!isRecord7(value) || !Array.isArray(value["unavailableExtensions"]))
3474
+ if (!isRecord6(value) || !Array.isArray(value["unavailableExtensions"]))
3475
3475
  return false;
3476
3476
  const postCompactProbePending = value["postCompactProbePending"];
3477
3477
  return value["unavailableExtensions"].every((item) => typeof item === "string") && (postCompactProbePending === undefined || typeof postCompactProbePending === "boolean");
3478
3478
  }
3479
- function isRecord7(value) {
3479
+ function isRecord6(value) {
3480
3480
  return typeof value === "object" && value !== null && !Array.isArray(value);
3481
3481
  }
3482
3482
 
@@ -3487,7 +3487,7 @@ function extractMutatedFilePaths(input) {
3487
3487
  return [];
3488
3488
  if (isFailedToolResponse(input.tool_response))
3489
3489
  return [];
3490
- const toolInput = isRecord9(input.tool_input) ? input.tool_input : {};
3490
+ const toolInput = isRecord7(input.tool_input) ? input.tool_input : {};
3491
3491
  const paths = new Set;
3492
3492
  addStringValue(paths, toolInput["path"]);
3493
3493
  addStringValue(paths, toolInput["filePath"]);
@@ -3506,7 +3506,7 @@ function isMutationTool(value) {
3506
3506
  return MUTATION_TOOL_NAMES.has(value.toLowerCase());
3507
3507
  }
3508
3508
  function isFailedToolResponse(value) {
3509
- if (!isRecord9(value))
3509
+ if (!isRecord7(value))
3510
3510
  return false;
3511
3511
  return value["isError"] === true || value["is_error"] === true || value["error"] === true || value["status"] === "error";
3512
3512
  }
@@ -3549,7 +3549,7 @@ function addPatchFiles(paths, value) {
3549
3549
  if (!Array.isArray(value))
3550
3550
  return;
3551
3551
  for (const item of value) {
3552
- if (!isRecord9(item))
3552
+ if (!isRecord7(item))
3553
3553
  continue;
3554
3554
  addStringValue(paths, item["path"]);
3555
3555
  addStringValue(paths, item["filePath"]);
@@ -3558,7 +3558,7 @@ function addPatchFiles(paths, value) {
3558
3558
  addStringValue(paths, item["move_path"]);
3559
3559
  }
3560
3560
  }
3561
- function isRecord9(value) {
3561
+ function isRecord7(value) {
3562
3562
  return typeof value === "object" && value !== null && !Array.isArray(value);
3563
3563
  }
3564
3564
 
@@ -3742,7 +3742,7 @@ function limitHookText(text2, maxChars) {
3742
3742
  function isCleanDiagnostics(diagnostics) {
3743
3743
  return diagnostics.length === 0 || diagnostics === CLEAN_DIAGNOSTICS_TEXT || diagnostics.startsWith(UNSUPPORTED_EXTENSION_TEXT);
3744
3744
  }
3745
- function isRecord10(value) {
3745
+ function isRecord8(value) {
3746
3746
  return typeof value === "object" && value !== null && !Array.isArray(value);
3747
3747
  }
3748
3748
 
@@ -3759,7 +3759,7 @@ async function runHookCli(runHook, stdin) {
3759
3759
  if (!raw.trim())
3760
3760
  return;
3761
3761
  const parsed = JSON.parse(raw);
3762
- const input = isRecord10(parsed) ? parsed : {};
3762
+ const input = isRecord8(parsed) ? parsed : {};
3763
3763
  const output = await runHook(input);
3764
3764
  if (output)
3765
3765
  process.stdout.write(output);
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
10
10
  "timeout": 60,
11
- "statusMessage": "(OmO 4.16.3) Checking LSP Diagnostics"
11
+ "statusMessage": "(OmO 4.17.1) Checking LSP Diagnostics"
12
12
  }
13
13
  ]
14
14
  }
@@ -21,7 +21,7 @@
21
21
  "type": "command",
22
22
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
23
23
  "timeout": 5,
24
- "statusMessage": "(OmO 4.16.3) Resetting LSP Diagnostics Cache"
24
+ "statusMessage": "(OmO 4.17.1) Resetting LSP Diagnostics Cache"
25
25
  }
26
26
  ]
27
27
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-lsp",
3
- "version": "4.16.3",
3
+ "version": "4.17.1",
4
4
  "description": "Codex plugin that exposes Language Server Protocol tools and post-edit diagnostics.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -56,17 +56,4 @@ describe("plugin package metadata", () => {
56
56
  expect(codexHookSource).not.toContain("../../../../../lsp-daemon");
57
57
  expect(sourceFiles.filter((name) => name.startsWith("lazy-mcp") || name === "lazy-lsp-mcp.ts")).toEqual([]);
58
58
  });
59
-
60
- it("#given LSP skill guidance #when validating MCP tool instructions #then tool names are not framed as shell commands", () => {
61
- // given
62
- const skill = readTextFile("skills/lsp/SKILL.md");
63
-
64
- // when
65
- const mentionsToolInterface = skill.includes("through the tool interface");
66
- const rejectsShellExecution = skill.includes("not shell commands");
67
-
68
- // then
69
- expect(mentionsToolInterface).toBe(true);
70
- expect(rejectsShellExecution).toBe(true);
71
- });
72
59
  });
@@ -45,7 +45,7 @@ Read-only Codex subagent roles live in `CODEX_HOME/agents/`. Spawn: `multi_agent
45
45
 
46
46
  - `explorer` - codebase search
47
47
  - `librarian` - external docs, OSS code, API contracts
48
- - `plan` - planning for ambiguous, multi-module work
48
+ - `plan` - planning when design is still open after discovery; never for a known checklist or for work being delegated onward
49
49
  - `lazycodex-gate-reviewer` - final verification of a finished change
50
50
 
51
51
  Spawn subagents in parallel for independent investigations; do non-overlapping prep while they run, integrate on return. Never duplicate a running search or poll without a completion signal. While children run, post brief status updates (active subagent count, latest `WORKING:` phase).
@@ -74,7 +74,7 @@ Diagnostics catch type errors, not logic bugs; tests cover only what their autho
74
74
 
75
75
  # Global Review and Debugging Gate
76
76
 
77
- Before declaring significant work or a PR handoff complete, run `review-work` plus a `debugging` runtime audit; record three debugging hypotheses with runtime evidence each. Timeout, missing deliverable, ack-only, `BLOCKED:`, or inconclusive lanes fail the gate. Redact secrets, tokens, and PII from ledgers, PR bodies, and handoffs.
77
+ Run `review-work` plus a `debugging` runtime audit only before a PR handoff or when the user asks for a review; lane pass/fail semantics live in those skills. For everything else, the gate above is the whole gate: once you have personally observed the artifact working, report your evidence. Redact secrets, tokens, and PII from ledgers, PR bodies, and handoffs.
78
78
 
79
79
  # Failure Recovery
80
80
 
@@ -19,7 +19,7 @@ Status requests are not stop signals: give the update, keep working. Honor every
19
19
 
20
20
  # Discovery
21
21
 
22
- Never speculate about code you have not read: verify with tools and re-read on every hand-off. Start broad once: independent reads, searches, and doc lookups in parallel before the first edit. Retrieve again only when the core question is open, a needed fact is missing, or a second-order question (callers, error paths, ownership) changes the design. Stop when you can act. Prefer the root fix over the symptom fix.
22
+ Never speculate about code you have not read: verify with tools and re-read on every hand-off. Start broad once - and WIDE: tool calls run as JavaScript through `exec`, so write programs, not single calls. Batch EVERY independent read, search, and doc lookup into ONE `exec` script via `Promise.all` over the `tools` object before the first edit; filter and reduce results in-script so only what you need returns to context. NEVER await independent calls one at a time - sequence only when one result feeds the next. Retrieve again only when the core question is open, a needed fact is missing, or a second-order question (callers, error paths, ownership) changes the design. Stop when you can act. Prefer the root fix over the symptom fix.
23
23
 
24
24
  # Operating Loop
25
25
 
@@ -33,7 +33,7 @@ Read-only Codex subagent roles live in `CODEX_HOME/agents/`. Spawn: `multi_agent
33
33
 
34
34
  - `explorer` - codebase search
35
35
  - `librarian` - external docs, OSS code, API contracts
36
- - `plan` - planning for ambiguous, multi-module work
36
+ - `plan` - planning when design is still open after discovery; never for a known checklist or for work being delegated onward
37
37
  - `lazycodex-gate-reviewer` - final verification of a finished change
38
38
 
39
39
  Spawn in parallel for independent investigations; do non-overlapping prep while they run, integrate on return. Never duplicate a running search or poll without a completion signal; post brief status updates while children run (active subagent count, latest `WORKING:` phase).
@@ -50,7 +50,7 @@ Diagnostics catch type errors, not logic bugs; tests cover only what their autho
50
50
 
51
51
  "This should work" from reading source does not pass. A defect found in usage is yours to fix this turn.
52
52
 
53
- Before declaring significant work or a PR handoff complete, run `review-work` plus a `debugging` runtime audit; record three debugging hypotheses with runtime evidence each. Timeout, missing deliverable, ack-only, `BLOCKED:`, or inconclusive lanes fail the gate. Redact secrets, tokens, and PII from ledgers, PR bodies, and handoffs.
53
+ Run `review-work` plus a `debugging` runtime audit only before a PR handoff or when the user asks for a review; lane pass/fail semantics live in those skills. For everything else, the gate above is the whole gate: once you have personally observed the artifact working, report your evidence. Redact secrets, tokens, and PII from ledgers, PR bodies, and handoffs.
54
54
 
55
55
  # Failure Recovery
56
56
 
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook session-start",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO 4.16.3) Loading Project Rules"
10
+ "statusMessage": "(OmO 4.17.1) Loading Project Rules"
11
11
  }
12
12
  ]
13
13
  }
@@ -19,7 +19,7 @@
19
19
  "type": "command",
20
20
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook user-prompt-submit",
21
21
  "timeout": 10,
22
- "statusMessage": "(OmO 4.16.3) Loading Project Rules"
22
+ "statusMessage": "(OmO 4.17.1) Loading Project Rules"
23
23
  }
24
24
  ]
25
25
  }
@@ -32,7 +32,7 @@
32
32
  "type": "command",
33
33
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
34
34
  "timeout": 10,
35
- "statusMessage": "(OmO 4.16.3) Matching Project Rules"
35
+ "statusMessage": "(OmO 4.17.1) Matching Project Rules"
36
36
  }
37
37
  ]
38
38
  }
@@ -45,7 +45,7 @@
45
45
  "type": "command",
46
46
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
47
47
  "timeout": 10,
48
- "statusMessage": "(OmO 4.16.3) Resetting Project Rule Cache"
48
+ "statusMessage": "(OmO 4.17.1) Resetting Project Rule Cache"
49
49
  }
50
50
  ]
51
51
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-rules",
3
- "version": "4.16.3",
3
+ "version": "4.17.1",
4
4
  "description": "Codex plugin that injects project rule files into model context through lifecycle hooks.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/start-work-continuation/dist/cli.js\" hook stop",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO 4.16.3) Checking Start-Work Continuation"
10
+ "statusMessage": "(OmO 4.17.1) Checking Start-Work Continuation"
11
11
  }
12
12
  ]
13
13
  }
@@ -19,7 +19,7 @@
19
19
  "type": "command",
20
20
  "command": "node \"${PLUGIN_ROOT}/components/start-work-continuation/dist/cli.js\" hook subagent-stop",
21
21
  "timeout": 10,
22
- "statusMessage": "(OmO 4.16.3) Checking Start-Work Continuation"
22
+ "statusMessage": "(OmO 4.17.1) Checking Start-Work Continuation"
23
23
  }
24
24
  ]
25
25
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-start-work-continuation",
3
- "version": "4.16.3",
3
+ "version": "4.17.1",
4
4
  "description": "Codex Stop hook continuation injector for omo-codex start-work plans.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -1,4 +1,4 @@
1
- import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
1
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { afterEach, describe, expect, it } from "vitest";
@@ -96,84 +96,6 @@ describe("start-work Stop hook", () => {
96
96
  expect(output).toBe("");
97
97
  });
98
98
 
99
- it("#given active codex work #when continuation directive is emitted #then subagent guidance is reliable", () => {
100
- // given
101
- const workspace = createWorkspace({
102
- boulderJson: createBoulderJson({ sessionIds: ["codex:sess_abc"], status: "active" }),
103
- planMarkdown: ["# Plan", "", "## TODOs", "- [ ] First"].join("\n"),
104
- });
105
- const fs = createMemoryFs();
106
-
107
- // when
108
- const output = runStopHook(createStopInput(workspace), fs);
109
-
110
- // then
111
- const parsed = parseBlockOutput(output);
112
- expect(parsed.reason).toMatch(/TASK:/);
113
- expect(parsed.reason).toMatch(/fork_context:\s*false/);
114
- expect(parsed.reason).toMatch(/wait_agent.*mailbox signals/);
115
- expect(parsed.reason).toMatch(/TASK STILL ACTIVE/);
116
- expect(parsed.reason).toMatch(/respawn.*smaller/);
117
- expect(parsed.reason).toMatch(/WORKING:/);
118
- });
119
-
120
- it("#given active codex work #when continuation directive is emitted #then QA weight is tier-scoped without echo bloat", () => {
121
- // given
122
- const workspace = createWorkspace({
123
- boulderJson: createBoulderJson({ sessionIds: ["codex:sess_abc"], status: "active" }),
124
- planMarkdown: ["# Plan", "", "## TODOs", "- [ ] First"].join("\n"),
125
- });
126
- const fs = createMemoryFs();
127
-
128
- // when
129
- const output = runStopHook(createStopInput(workspace), fs);
130
-
131
- // then
132
- const parsed = parseBlockOutput(output);
133
- expect(parsed.reason).toMatch(/LIGHT/);
134
- expect(parsed.reason).toMatch(/HEAVY/);
135
- expect(parsed.reason).toMatch(/When unsure[^.]{0,30}HEAVY/);
136
- expect(parsed.reason).toMatch(/mirrors its implementation/);
137
- expect((parsed.reason.match(/malformed input, prompt injection/g) ?? []).length).toBe(1);
138
- expect(parsed.reason.split(/\s+/).filter(Boolean).length).toBeLessThanOrEqual(1135);
139
- });
140
-
141
- it("#given active codex work #when continuation directive is emitted #then PR lifecycle stays worktree-bound", () => {
142
- // given
143
- const workspace = createWorkspace({
144
- boulderJson: createBoulderJson({
145
- sessionIds: ["codex:sess_abc"],
146
- status: "active",
147
- worktreePath: "/tmp/worktree",
148
- }),
149
- planMarkdown: ["# Plan", "", "## TODOs", "- [ ] First"].join("\n"),
150
- });
151
- const fs = createMemoryFs();
152
-
153
- // when
154
- const output = runStopHook(createStopInput(workspace), fs);
155
-
156
- // then
157
- const parsed = parseBlockOutput(output);
158
- expect(parsed.reason).toContain("PR or branch implementation/review/merge work requires a task-owned git worktree");
159
- expect(parsed.reason).toContain("Treat the main worktree as read-only context");
160
- expect(parsed.reason).toContain("create/update the PR, wait for CI/review/Cubic gates, merge by default");
161
- expect(parsed.reason).toContain("Do not create a PR, PR handoff, branch handoff, merge");
162
- });
163
-
164
- it("#given stop hook source #when inspected #then it remains Boulder-only without planning bootstrap logic", () => {
165
- // given
166
- const hook = readFileSync(new URL("../src/codex-hook.ts", import.meta.url), "utf8");
167
-
168
- // then
169
- expect(hook).toMatch(/readContinuationState/);
170
- expect(hook).toMatch(/START_WORK_CONTINUATION_DIRECTIVE/);
171
- expect(hook).toMatch(/decision:\s*"block"/);
172
- expect(hook).not.toMatch(
173
- /\bulw-plan\b|\bspawn_agent\b|\brequest_user_input\b|bootstrap|selectable plan|Phase 1|Create or update Boulder state/i,
174
- );
175
- });
176
-
177
99
  it("#given active work belongs to another harness #when hook runs #then returns empty output", () => {
178
100
  // given
179
101
  const workspace = createWorkspace({