oh-my-opencode 4.18.2 → 4.19.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 (307) hide show
  1. package/.agents/command/omomomo.md +1 -1
  2. package/.agents/skills/omomomo/SKILL.md +1 -1
  3. package/.opencode/command/omomomo.md +1 -1
  4. package/README.ja.md +6 -6
  5. package/README.ko.md +6 -6
  6. package/README.md +8 -8
  7. package/README.ru.md +6 -6
  8. package/README.zh-cn.md +6 -6
  9. package/dist/agents/atlas/agent.d.ts +7 -6
  10. package/dist/agents/gpt-prompt-identity.d.ts +3 -0
  11. package/dist/agents/sisyphus/gpt-5-5.d.ts +1 -1
  12. package/dist/agents/sisyphus/gpt-task-system-guide.d.ts +1 -0
  13. package/dist/agents/sisyphus/index.d.ts +5 -0
  14. package/dist/agents/sisyphus/kimi-k3.d.ts +19 -0
  15. package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
  16. package/dist/agents/sisyphus-junior/agent.d.ts +8 -4
  17. package/dist/agents/sisyphus-junior/gpt-5-5.d.ts +2 -2
  18. package/dist/agents/sisyphus-junior/index.d.ts +2 -0
  19. package/dist/agents/sisyphus-junior/kimi-k3.d.ts +12 -0
  20. package/dist/agents/types.d.ts +2 -2
  21. package/dist/cli/index.js +781 -215
  22. package/dist/cli-node/index.js +781 -215
  23. package/dist/config/index.d.ts +1 -1
  24. package/dist/config/schema/agent-overrides.d.ts +48 -48
  25. package/dist/config/schema/browser-automation.d.ts +1 -0
  26. package/dist/config/schema/categories.d.ts +6 -6
  27. package/dist/config/schema/codegraph.d.ts +2 -0
  28. package/dist/config/schema/commands.d.ts +1 -3
  29. package/dist/config/schema/default-mode.d.ts +1 -1
  30. package/dist/config/schema/fallback-models.d.ts +5 -5
  31. package/dist/config/schema/goal.d.ts +7 -0
  32. package/dist/config/schema/hooks.d.ts +1 -1
  33. package/dist/config/schema/oh-my-opencode-config.d.ts +56 -58
  34. package/dist/config/schema/ralph-loop.d.ts +1 -1
  35. package/dist/config/schema.d.ts +1 -1
  36. package/dist/create-hooks.d.ts +1 -1
  37. package/dist/features/builtin-commands/templates/goal.d.ts +1 -0
  38. package/dist/features/builtin-commands/templates/stop-continuation.d.ts +1 -1
  39. package/dist/features/builtin-commands/types.d.ts +1 -1
  40. package/dist/hooks/auto-slash-command/executor.d.ts +1 -0
  41. package/dist/hooks/codegraph-bootstrap/hook.d.ts +3 -2
  42. package/dist/hooks/goal/command-arguments.d.ts +13 -0
  43. package/dist/hooks/goal/controller.d.ts +26 -0
  44. package/dist/hooks/goal/index.d.ts +23 -0
  45. package/dist/hooks/goal/prompt.d.ts +3 -0
  46. package/dist/hooks/goal/store.d.ts +8 -0
  47. package/dist/hooks/goal/tools.d.ts +10 -0
  48. package/dist/hooks/goal/types.d.ts +93 -0
  49. package/dist/hooks/goal/validation.d.ts +4 -0
  50. package/dist/hooks/index.d.ts +1 -0
  51. package/dist/hooks/keyword-detector/hook.d.ts +1 -2
  52. package/dist/hooks/ralph-loop/types.d.ts +1 -1
  53. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  54. package/dist/hooks/start-work/notepad-scaffold.d.ts +10 -0
  55. package/dist/index.js +5398 -5109
  56. package/dist/oh-my-opencode.schema.json +34 -19
  57. package/dist/plugin/chat-message/loop-commands.d.ts +1 -1
  58. package/dist/plugin/chat-message/types.d.ts +23 -10
  59. package/dist/plugin/hooks/create-core-hooks.d.ts +1 -1
  60. package/dist/plugin/hooks/create-session-hooks.d.ts +3 -2
  61. package/dist/plugin/hooks/create-transform-hooks.d.ts +0 -2
  62. package/dist/plugin/stop-continuation.d.ts +2 -2
  63. package/dist/shared/omo-process-sweep.d.ts +18 -0
  64. package/dist/shared/system-directive.d.ts +0 -1
  65. package/dist/skills/programming/scripts/typescript/check-no-excuse-rules.test.ts +87 -0
  66. package/dist/skills/programming/scripts/typescript/check-no-excuse-rules.ts +35 -5
  67. package/dist/skills/ulw-plan/SKILL.md +31 -8
  68. package/dist/skills/ulw-plan/references/full-workflow.md +117 -6
  69. package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  70. package/dist/skills/ulw-research/SKILL.md +3 -3
  71. package/dist/testing/create-plugin-module.d.ts +1 -0
  72. package/dist/tools/delegate-task/types.d.ts +0 -1
  73. package/dist/tui.js +138 -80
  74. package/package.json +14 -14
  75. package/packages/git-bash-mcp/dist/cli.js +54 -8
  76. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +60 -0
  77. package/packages/lsp-core/src/lsp/client.ts +14 -1
  78. package/packages/lsp-core/src/lsp/fixtures/diagnostics-freshness-contract-probe.ts +2 -2
  79. package/packages/lsp-core/src/mcp.ts +9 -0
  80. package/packages/lsp-daemon/dist/cli.js +319 -51
  81. package/packages/lsp-daemon/dist/client.js +136 -48
  82. package/packages/lsp-daemon/dist/daemon-client.d.ts +0 -10
  83. package/packages/lsp-daemon/dist/daemon-client.js +4 -34
  84. package/packages/lsp-daemon/dist/daemon-failure-result.d.ts +3 -0
  85. package/packages/lsp-daemon/dist/daemon-failure-result.js +38 -0
  86. package/packages/lsp-daemon/dist/daemon-request-error.d.ts +14 -0
  87. package/packages/lsp-daemon/dist/daemon-request-error.js +26 -0
  88. package/packages/lsp-daemon/dist/daemon-server.js +5 -1
  89. package/packages/lsp-daemon/dist/index.js +137 -48
  90. package/packages/lsp-daemon/dist/proxy.d.ts +2 -0
  91. package/packages/lsp-daemon/dist/proxy.js +1 -0
  92. package/packages/lsp-daemon/dist/version-reap.d.ts +26 -0
  93. package/packages/lsp-daemon/dist/version-reap.js +182 -0
  94. package/packages/lsp-tools-mcp/dist/cli.js +61 -10
  95. package/packages/lsp-tools-mcp/dist/lsp/manager.js +6 -1
  96. package/packages/lsp-tools-mcp/dist/mcp.js +61 -10
  97. package/packages/lsp-tools-mcp/dist/tools.js +6 -1
  98. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  99. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +416 -25
  100. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  101. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  102. package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +22 -2
  103. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +7 -6
  104. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +638 -267
  105. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +178 -89
  106. package/packages/omo-codex/plugin/components/codegraph/package.json +2 -2
  107. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +3 -1
  108. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +3 -1
  109. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +98 -32
  110. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +5 -0
  111. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +15 -6
  112. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +6 -2
  113. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +1 -0
  114. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +1 -1
  115. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +148 -0
  116. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +31 -2
  117. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +1 -1
  118. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +65 -1
  119. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +3 -7
  120. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +1 -1
  121. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +57 -3
  122. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +41 -0
  123. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +109 -8
  124. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +2 -2
  125. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +43 -0
  126. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  127. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  128. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  129. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  130. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  131. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  132. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +1 -0
  133. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
  134. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +80 -40
  135. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  136. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  137. package/packages/omo-codex/plugin/components/rules/dist/cli.js +11 -0
  138. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  139. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  140. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +11 -0
  141. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +60 -0
  142. package/packages/omo-codex/plugin/components/start-work-continuation/AGENTS.md +8 -0
  143. package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +147 -60
  144. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  145. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  146. package/packages/omo-codex/plugin/components/start-work-continuation/src/boulder-reader.ts +3 -71
  147. package/packages/omo-codex/plugin/components/start-work-continuation/src/plan-checklist.ts +171 -0
  148. package/packages/omo-codex/plugin/components/start-work-continuation/test/boulder-reader.test.ts +198 -23
  149. package/packages/omo-codex/plugin/components/start-work-continuation/test/cli.test.ts +4 -3
  150. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +6 -5
  151. package/packages/omo-codex/plugin/components/start-work-continuation/test/fixtures/plan-scaffold.md +15 -0
  152. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  153. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  154. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  155. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  156. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -10
  157. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +2 -2
  158. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +2 -2
  159. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
  160. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +1 -1
  161. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +2 -2
  162. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +3 -3
  163. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -1
  164. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +1 -1
  165. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  166. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  167. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +31 -8
  168. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +117 -6
  169. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  170. package/packages/omo-codex/plugin/components/ultrawork/src/codex-hook.ts +1 -1
  171. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +42 -0
  172. package/packages/omo-codex/plugin/components/ulw-loop/README.md +6 -4
  173. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.d.ts +21 -0
  174. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +64 -0
  175. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +15 -2
  176. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.js +1 -1
  177. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +2 -1
  178. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +1 -1
  179. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +3 -3
  180. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.d.ts +3 -0
  181. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +85 -0
  182. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.d.ts +0 -1
  183. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +13 -33
  184. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +998 -593
  185. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +1 -0
  186. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.d.ts +1 -1
  187. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.js +2 -0
  188. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +6 -0
  189. package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.d.ts +1 -0
  190. package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.js +3 -0
  191. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.d.ts +1 -0
  192. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +4 -0
  193. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +1 -0
  194. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +10 -2
  195. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +1 -1
  196. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-batch.d.ts +15 -0
  197. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-batch.js +84 -0
  198. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.d.ts +5 -0
  199. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.js +81 -0
  200. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +7 -59
  201. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +12 -4
  202. package/packages/omo-codex/plugin/components/ulw-loop/dist/validation-batch.d.ts +9 -0
  203. package/packages/omo-codex/plugin/components/ulw-loop/dist/validation-batch.js +122 -0
  204. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  205. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  206. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +8 -6
  207. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +84 -0
  208. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +13 -2
  209. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-arg-parser.ts +1 -1
  210. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +1 -1
  211. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +3 -3
  212. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-steering.ts +49 -0
  213. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +13 -45
  214. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +1 -0
  215. package/packages/omo-codex/plugin/components/ulw-loop/src/constants.ts +2 -0
  216. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +7 -0
  217. package/packages/omo-codex/plugin/components/ulw-loop/src/goal-status.ts +4 -0
  218. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +4 -1
  219. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +20 -2
  220. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +1 -1
  221. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-batch.ts +125 -0
  222. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-mutations.ts +59 -0
  223. package/packages/omo-codex/plugin/components/ulw-loop/src/steering.ts +6 -58
  224. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +12 -4
  225. package/packages/omo-codex/plugin/components/ulw-loop/src/validation-batch.ts +122 -0
  226. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +76 -0
  227. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint-continuation.test.ts +111 -0
  228. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-batch.test.ts +67 -0
  229. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-validation-batch.test.ts +57 -0
  230. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +1 -0
  231. package/packages/omo-codex/plugin/components/ulw-loop/test/steering-batch.test.ts +152 -0
  232. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +29 -0
  233. package/packages/omo-codex/plugin/components/ulw-loop/test/validation-batch-checkpoint.test.ts +147 -0
  234. package/packages/omo-codex/plugin/components/ulw-loop/test/validation-batch.test.ts +73 -0
  235. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  236. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  237. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  238. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  239. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  240. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  241. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  242. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  243. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  244. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  245. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  246. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +2 -2
  247. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  248. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +2 -2
  249. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  250. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +2 -2
  251. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  252. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  253. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  254. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  255. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  256. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  257. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  258. package/packages/omo-codex/plugin/package-lock.json +41 -41
  259. package/packages/omo-codex/plugin/package.json +1 -1
  260. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +32 -28
  261. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +17 -45
  262. package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +455 -0
  263. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +3 -18
  264. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +43 -0
  265. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-no-excuse-rules.ts +35 -5
  266. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +8 -6
  267. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +31 -8
  268. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +117 -6
  269. package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  270. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +11 -11
  271. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +26 -0
  272. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +41 -0
  273. package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +2 -2
  274. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +6 -6
  275. package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +3 -3
  276. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +62 -0
  277. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +271 -14
  278. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +3 -18
  279. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +0 -5
  280. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +293 -0
  281. package/packages/omo-codex/scripts/install-config.test.mjs +10 -10
  282. package/packages/omo-codex/scripts/install-dist/install-local.mjs +401 -22
  283. package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +39 -2
  284. package/packages/omo-codex/scripts/install-marketplace-cache.test.mjs +4 -1
  285. package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.test.ts +87 -0
  286. package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.ts +35 -5
  287. package/packages/shared-skills/skills/ulw-plan/SKILL.md +31 -8
  288. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +117 -6
  289. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  290. package/packages/shared-skills/skills/ulw-research/SKILL.md +3 -3
  291. package/dist/features/builtin-commands/templates/ralph-loop.d.ts +0 -3
  292. package/dist/skills/ultraresearch/SKILL.md +0 -10
  293. package/packages/shared-skills/skills/lcx-contribute-bug-fix/SKILL.md +0 -273
  294. package/packages/shared-skills/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -12
  295. package/packages/shared-skills/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -107
  296. package/packages/shared-skills/skills/lcx-doctor/SKILL.md +0 -128
  297. package/packages/shared-skills/skills/lcx-doctor/agents/openai.yaml +0 -11
  298. package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +0 -268
  299. package/packages/shared-skills/skills/lcx-report-bug/agents/openai.yaml +0 -11
  300. package/packages/shared-skills/skills/ultraresearch/SKILL.md +0 -10
  301. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/SKILL.md +0 -0
  302. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -0
  303. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -0
  304. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-doctor/SKILL.md +0 -0
  305. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-doctor/agents/openai.yaml +0 -0
  306. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-report-bug/SKILL.md +0 -0
  307. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-report-bug/agents/openai.yaml +0 -0
@@ -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.18.2) Loading Project Rules"
10
+ "statusMessage": "(OmO 4.19.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.18.2) Loading Project Rules"
22
+ "statusMessage": "(OmO 4.19.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.18.2) Matching Project Rules"
35
+ "statusMessage": "(OmO 4.19.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.18.2) Resetting Project Rule Cache"
48
+ "statusMessage": "(OmO 4.19.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.18.2",
3
+ "version": "4.19.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",
@@ -21,6 +21,17 @@ const POST_COMPACT_MIN_RESERVED_TOKENS = 8_000;
21
21
  const POST_COMPACT_MIN_GUIDE_CHARS = 500;
22
22
  const FALLBACK_CONTEXT_WINDOW_TOKENS = 200_000;
23
23
  const MODEL_CONTEXT_BUDGETS: readonly ModelContextBudget[] = [
24
+ { slug: "gpt-5.6-sol", contextWindowTokens: 372_000, effectivePercent: DEFAULT_EFFECTIVE_CONTEXT_WINDOW_PERCENT },
25
+ {
26
+ slug: "gpt-5.6-terra",
27
+ contextWindowTokens: 372_000,
28
+ effectivePercent: DEFAULT_EFFECTIVE_CONTEXT_WINDOW_PERCENT,
29
+ },
30
+ {
31
+ slug: "gpt-5.6-luna",
32
+ contextWindowTokens: 372_000,
33
+ effectivePercent: DEFAULT_EFFECTIVE_CONTEXT_WINDOW_PERCENT,
34
+ },
24
35
  { slug: "gpt-5.5", contextWindowTokens: 272_000, effectivePercent: DEFAULT_EFFECTIVE_CONTEXT_WINDOW_PERCENT },
25
36
  { slug: "gpt-5.4-mini", contextWindowTokens: 272_000, effectivePercent: DEFAULT_EFFECTIVE_CONTEXT_WINDOW_PERCENT },
26
37
  {
@@ -76,6 +76,66 @@ describe("post-compact context budget", () => {
76
76
  expect(budget.maxRuleChars).toBeLessThanOrEqual(budget.maxResultChars);
77
77
  });
78
78
 
79
+ it("#given gpt-5.6-sol within its 372k window #when resolving post-compact budget #then keeps configured post-compact cap", () => {
80
+ // given
81
+ const transcriptPath = writeCompactedTranscript("A".repeat(541_500));
82
+
83
+ // when
84
+ const budget = withPostCompactBudget(CONFIG, { model: "gpt-5.6-sol", transcriptPath });
85
+
86
+ // then
87
+ expect(budget.maxRuleChars).toBe(CONFIG.postCompactMaxRuleChars);
88
+ expect(budget.maxResultChars).toBe(CONFIG.postCompactMaxResultChars);
89
+ });
90
+
91
+ it("#given gpt-5.6-terra within its 372k window #when resolving post-compact budget #then keeps configured post-compact cap", () => {
92
+ // given
93
+ const transcriptPath = writeCompactedTranscript("A".repeat(541_500));
94
+
95
+ // when
96
+ const budget = withPostCompactBudget(CONFIG, { model: "gpt-5.6-terra", transcriptPath });
97
+
98
+ // then
99
+ expect(budget.maxRuleChars).toBe(CONFIG.postCompactMaxRuleChars);
100
+ expect(budget.maxResultChars).toBe(CONFIG.postCompactMaxResultChars);
101
+ });
102
+
103
+ it("#given gpt-5.6-luna within its 372k window #when resolving post-compact budget #then keeps configured post-compact cap", () => {
104
+ // given
105
+ const transcriptPath = writeCompactedTranscript("A".repeat(541_500));
106
+
107
+ // when
108
+ const budget = withPostCompactBudget(CONFIG, { model: "gpt-5.6-luna", transcriptPath });
109
+
110
+ // then
111
+ expect(budget.maxRuleChars).toBe(CONFIG.postCompactMaxRuleChars);
112
+ expect(budget.maxResultChars).toBe(CONFIG.postCompactMaxResultChars);
113
+ });
114
+
115
+ it("#given provider-prefixed gpt-5.6 variant within its 372k window #when resolving post-compact budget #then keeps configured post-compact cap", () => {
116
+ // given
117
+ const transcriptPath = writeCompactedTranscript("A".repeat(541_500));
118
+
119
+ // when
120
+ const budget = withPostCompactBudget(CONFIG, { model: "openai/gpt-5.6-sol", transcriptPath });
121
+
122
+ // then
123
+ expect(budget.maxRuleChars).toBe(CONFIG.postCompactMaxRuleChars);
124
+ expect(budget.maxResultChars).toBe(CONFIG.postCompactMaxResultChars);
125
+ });
126
+
127
+ it("#given unknown model with the same transcript #when resolving post-compact budget #then keeps the 200k fallback floor", () => {
128
+ // given
129
+ const transcriptPath = writeCompactedTranscript("A".repeat(541_500));
130
+
131
+ // when
132
+ const budget = withPostCompactBudget(CONFIG, { model: "unknown-model", transcriptPath });
133
+
134
+ // then
135
+ expect(budget.maxResultChars).toBe(500);
136
+ expect(budget.maxRuleChars).toBe(500);
137
+ });
138
+
79
139
  it("#given context pressure marker after compaction #when resolving post-compact budget #then shrinks projected rule injection", () => {
80
140
  // given
81
141
  const transcriptPath = writeCompactedPressureTranscript("small compacted summary");
@@ -29,6 +29,13 @@ Conventions for human contributors and AI agents working on this repository.
29
29
  - Never use Arrange-Act-Assert comments.
30
30
  - Keep fixtures in `test/fixtures/`.
31
31
 
32
+ ## Layout
33
+
34
+ - `src/boulder-reader.ts`: reads `.omo/boulder.json`, resolves the active work for the session, re-exports `getPlanChecklist`/`PlanChecklist` from `plan-checklist.ts`. `readContinuationState` returns null only when the plan has no readable top-level checklist (`total === 0`).
35
+ - `src/plan-checklist.ts`: `PlanChecklist` (`completed`/`remaining`/`total`/`nextTaskLabel`) and `getPlanChecklist`/`parsePlanChecklist`. Counts structured `## TODOs` rows (`N. <title>`) and `## Final Verification Wave` rows (`F<number>. <title>`); falls back to simple top-level `- [ ]`/`- [x]` checkboxes. Skips fenced blocks and respects `#`/`##` section boundaries.
36
+ - `src/codex-hook.ts`: Stop/SubagentStop hook; fills `REMAINING_COUNT`/`TOTAL_COUNT`/`NEXT_TASK_LABEL` from the checklist into `directive.md`.
37
+ - `directive.md`: directive template with placeholders, applied per invocation.
38
+
32
39
  ## Build and Hooks
33
40
 
34
41
  - Build output goes to `dist/`.
@@ -41,3 +48,4 @@ Conventions for human contributors and AI agents working on this repository.
41
48
  - Never make a network call from the hook.
42
49
  - Keep the directive in `directive.md`. Do not inline it into TypeScript files.
43
50
  - The hook only continues sessions listed in `.omo/boulder.json` as `codex:<session_id>`.
51
+ - The hook continues while the plan has a readable top-level checklist (`total > 0`). A fully-checked plan still blocks Stop until the final gate runs and the Boulder work is marked completed; an unreadable or empty checklist yields no output.
@@ -1,37 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // components/start-work-continuation/src/cli.ts
4
- import { readFileSync as readFileSync3 } from "node:fs";
4
+ import { readFileSync as readFileSync4 } from "node:fs";
5
5
  import { stdin as processStdin, stdout as processStdout } from "node:process";
6
6
 
7
7
  // components/start-work-continuation/src/boulder-reader.ts
8
- import { existsSync, readFileSync } from "node:fs";
8
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
9
9
  import { isAbsolute, join, relative, resolve } from "node:path";
10
- var TODO_HEADING = "TODOs";
11
- var FINAL_VERIFICATION_HEADING = "Final Verification Wave";
12
- var CHECKBOX_PREFIX_LENGTH = "- [ ] ".length;
13
- var SESSION_ID_PREFIX_PATTERN = /^(codex|opencode):/;
14
- function readContinuationState(cwd, sessionId) {
15
- const boulderPath = getBoulderFilePath(cwd);
16
- const boulderState = readBoulderState(boulderPath);
17
- if (boulderState === null)
18
- return null;
19
- const work = getWorkForSession(boulderState, normalizeSessionId(sessionId, "codex"));
20
- if (work === null || !isContinuableStatus(work.status))
21
- return null;
22
- const planPath = resolveBoulderPlanPathForWork(cwd, work);
23
- const checklist = getPlanChecklist(planPath);
24
- if (checklist.total === 0)
25
- return null;
26
- return {
27
- planName: work.planName,
28
- planPath,
29
- boulderPath,
30
- ledgerPath: join(cwd, ".omo", "start-work", "ledger.jsonl"),
31
- worktreePath: work.worktreePath ?? null,
32
- checklist
33
- };
34
- }
10
+
11
+ // components/start-work-continuation/src/plan-checklist.ts
12
+ import { existsSync, readFileSync } from "node:fs";
13
+ var TODO_HEADING_PATTERN = /^##[ \t]+TODOs(?:[ \t]+#+)?[ \t]*$/i;
14
+ var FINAL_VERIFICATION_HEADING_PATTERN = /^##[ \t]+Final Verification Wave(?:[ \t]+#+)?[ \t]*$/i;
15
+ var SECTION_BOUNDARY_HEADING_PATTERN = /^#{1,2}(?:[ \t]+|$)/;
16
+ var FENCE_PATTERN = /^[ \t]{0,3}(`{3,}|~{3,})(.*)$/;
17
+ var SIMPLE_CHECKBOX_PATTERN = /^[-*][ \t]*\[[ \t]*([xX]?)[ \t]*\][ \t]+(.+)$/;
18
+ var TODO_CHECKBOX_PATTERN = /^- \[([ xX])\] ([1-9]\d*\. .+)$/;
19
+ var FINAL_WAVE_CHECKBOX_PATTERN = /^- \[([ xX])\] (F[1-9]\d*\. .+)$/i;
35
20
  function getPlanChecklist(planPath) {
36
21
  if (!existsSync(planPath))
37
22
  return emptyChecklist();
@@ -45,34 +30,155 @@ function getPlanChecklist(planPath) {
45
30
  }
46
31
  function parsePlanChecklist(markdown) {
47
32
  const lines = markdown.split(/\r?\n/);
48
- const hasCountedSections = lines.some((line) => isCountedHeading(parseLevelTwoHeading(line)));
33
+ if (!hasStructuredSection(lines))
34
+ return parseSimpleChecklist(lines);
49
35
  let completed = 0;
50
36
  let remaining = 0;
51
37
  let nextTaskLabel = null;
52
- let isCountedSection = !hasCountedSections;
38
+ let section = "other";
39
+ let fence = null;
53
40
  for (const line of lines) {
54
- const heading = parseLevelTwoHeading(line);
55
- if (heading !== null) {
56
- isCountedSection = isCountedHeading(heading);
41
+ if (fence !== null) {
42
+ if (isClosingFence(line, fence))
43
+ fence = null;
44
+ continue;
45
+ }
46
+ const openingFence = parseOpeningFence(line);
47
+ if (openingFence !== null) {
48
+ fence = openingFence;
57
49
  continue;
58
50
  }
59
- if (!isCountedSection)
51
+ if (SECTION_BOUNDARY_HEADING_PATTERN.test(line)) {
52
+ section = parseStructuredSectionHeading(line);
60
53
  continue;
61
- const checkbox = parseTopLevelCheckbox(line);
54
+ }
55
+ if (section === "other")
56
+ continue;
57
+ const checkbox = parseStructuredCheckbox(line, section);
62
58
  if (checkbox === null)
63
59
  continue;
64
- if (checkbox.checked) {
60
+ if (checkbox.checked)
65
61
  completed += 1;
66
- } else {
62
+ else {
67
63
  remaining += 1;
68
64
  nextTaskLabel = nextTaskLabel ?? checkbox.label;
69
65
  }
70
66
  }
71
67
  return { completed, remaining, total: completed + remaining, nextTaskLabel };
72
68
  }
69
+ function hasStructuredSection(lines) {
70
+ let fence = null;
71
+ for (const line of lines) {
72
+ if (fence !== null) {
73
+ if (isClosingFence(line, fence))
74
+ fence = null;
75
+ continue;
76
+ }
77
+ const openingFence = parseOpeningFence(line);
78
+ if (openingFence !== null) {
79
+ fence = openingFence;
80
+ continue;
81
+ }
82
+ if (parseStructuredSectionHeading(line) !== "other")
83
+ return true;
84
+ }
85
+ return false;
86
+ }
87
+ function parseSimpleChecklist(lines) {
88
+ let completed = 0;
89
+ let remaining = 0;
90
+ let nextTaskLabel = null;
91
+ let fence = null;
92
+ for (const line of lines) {
93
+ if (fence !== null) {
94
+ if (isClosingFence(line, fence))
95
+ fence = null;
96
+ continue;
97
+ }
98
+ const openingFence = parseOpeningFence(line);
99
+ if (openingFence !== null) {
100
+ fence = openingFence;
101
+ continue;
102
+ }
103
+ const checkbox = parseSimpleTopLevelCheckbox(line);
104
+ if (checkbox === null)
105
+ continue;
106
+ if (checkbox.checked)
107
+ completed += 1;
108
+ else {
109
+ remaining += 1;
110
+ nextTaskLabel = nextTaskLabel ?? checkbox.label;
111
+ }
112
+ }
113
+ return { completed, remaining, total: completed + remaining, nextTaskLabel };
114
+ }
115
+ function parseStructuredSectionHeading(line) {
116
+ if (TODO_HEADING_PATTERN.test(line))
117
+ return "todo";
118
+ if (FINAL_VERIFICATION_HEADING_PATTERN.test(line))
119
+ return "final-wave";
120
+ return "other";
121
+ }
122
+ function parseStructuredCheckbox(line, section) {
123
+ const pattern = section === "todo" ? TODO_CHECKBOX_PATTERN : FINAL_WAVE_CHECKBOX_PATTERN;
124
+ const match = line.match(pattern);
125
+ const marker = match?.[1];
126
+ const label = match?.[2];
127
+ if (marker === undefined || label === undefined)
128
+ return null;
129
+ return { checked: marker.toLowerCase() === "x", label };
130
+ }
131
+ function parseSimpleTopLevelCheckbox(line) {
132
+ const match = line.match(SIMPLE_CHECKBOX_PATTERN);
133
+ const marker = match?.[1];
134
+ const label = match?.[2];
135
+ if (marker === undefined || label === undefined)
136
+ return null;
137
+ return { checked: marker.toLowerCase() === "x", label };
138
+ }
139
+ function parseOpeningFence(line) {
140
+ const match = line.match(FENCE_PATTERN);
141
+ const run = match?.[1];
142
+ const info = match?.[2];
143
+ const marker = run?.charAt(0);
144
+ if (run === undefined || info === undefined || marker !== "`" && marker !== "~" || marker === "`" && info.includes("`"))
145
+ return null;
146
+ return { marker, length: run.length };
147
+ }
148
+ function isClosingFence(line, fence) {
149
+ const run = line.match(/^[ \t]{0,3}(`{3,}|~{3,})[ \t]*$/)?.[1];
150
+ return run?.charAt(0) === fence.marker && run.length >= fence.length;
151
+ }
152
+ function emptyChecklist() {
153
+ return { completed: 0, remaining: 0, total: 0, nextTaskLabel: null };
154
+ }
155
+
156
+ // components/start-work-continuation/src/boulder-reader.ts
157
+ var SESSION_ID_PREFIX_PATTERN = /^(codex|opencode):/;
158
+ function readContinuationState(cwd, sessionId) {
159
+ const boulderPath = getBoulderFilePath(cwd);
160
+ const boulderState = readBoulderState(boulderPath);
161
+ if (boulderState === null)
162
+ return null;
163
+ const work = getWorkForSession(boulderState, normalizeSessionId(sessionId, "codex"));
164
+ if (work === null || !isContinuableStatus(work.status))
165
+ return null;
166
+ const planPath = resolveBoulderPlanPathForWork(cwd, work);
167
+ const checklist = getPlanChecklist(planPath);
168
+ if (checklist.total === 0)
169
+ return null;
170
+ return {
171
+ planName: work.planName,
172
+ planPath,
173
+ boulderPath,
174
+ ledgerPath: join(cwd, ".omo", "start-work", "ledger.jsonl"),
175
+ worktreePath: work.worktreePath ?? null,
176
+ checklist
177
+ };
178
+ }
73
179
  function readBoulderState(path) {
74
180
  try {
75
- const parsed = JSON.parse(readFileSync(path, "utf8"));
181
+ const parsed = JSON.parse(readFileSync2(path, "utf8"));
76
182
  return parseBoulderState(parsed);
77
183
  } catch (error) {
78
184
  if (error instanceof Error)
@@ -150,27 +256,11 @@ function resolveBoulderPlanPathForWork(cwd, work) {
150
256
  return absolutePlanPath;
151
257
  }
152
258
  const worktreePlanPath = resolve(resolveTrackedPath(cwd, worktreePath), relativePlanPath);
153
- return existsSync(worktreePlanPath) ? worktreePlanPath : absolutePlanPath;
259
+ return existsSync2(worktreePlanPath) ? worktreePlanPath : absolutePlanPath;
154
260
  }
155
261
  function resolveTrackedPath(baseDirectory, trackedPath) {
156
262
  return isAbsolute(trackedPath) ? resolve(trackedPath) : resolve(baseDirectory, trackedPath);
157
263
  }
158
- function parseTopLevelCheckbox(line) {
159
- if (line.startsWith("- [ ] "))
160
- return { checked: false, label: line.slice(CHECKBOX_PREFIX_LENGTH) };
161
- if (line.startsWith("- [x] ") || line.startsWith("- [X] ")) {
162
- return { checked: true, label: line.slice(CHECKBOX_PREFIX_LENGTH) };
163
- }
164
- return null;
165
- }
166
- function parseLevelTwoHeading(line) {
167
- if (!line.startsWith("## "))
168
- return null;
169
- return line.slice("## ".length).trim();
170
- }
171
- function isCountedHeading(heading) {
172
- return heading === TODO_HEADING || heading === FINAL_VERIFICATION_HEADING;
173
- }
174
264
  function parseBoulderWorkStatus(value) {
175
265
  if (value === "active" || value === "paused" || value === "completed" || value === "abandoned")
176
266
  return value;
@@ -203,16 +293,13 @@ function isContinuableStatus(status) {
203
293
  function getBoulderFilePath(cwd) {
204
294
  return join(cwd, ".omo", "boulder.json");
205
295
  }
206
- function emptyChecklist() {
207
- return { completed: 0, remaining: 0, total: 0, nextTaskLabel: null };
208
- }
209
296
  function isRecord(value) {
210
297
  return typeof value === "object" && value !== null && !Array.isArray(value);
211
298
  }
212
299
 
213
300
  // components/start-work-continuation/src/directive.ts
214
- import { readFileSync as readFileSync2 } from "node:fs";
215
- var START_WORK_CONTINUATION_DIRECTIVE = readFileSync2(new URL("../directive.md", import.meta.url), "utf8");
301
+ import { readFileSync as readFileSync3 } from "node:fs";
302
+ var START_WORK_CONTINUATION_DIRECTIVE = readFileSync3(new URL("../directive.md", import.meta.url), "utf8");
216
303
 
217
304
  // components/start-work-continuation/src/codex-hook.ts
218
305
  function runStopHook(input, fs) {
@@ -285,7 +372,7 @@ function isRecord2(value) {
285
372
  // components/start-work-continuation/src/cli.ts
286
373
  var nodeFileSystem = {
287
374
  readFileSync(path, encoding) {
288
- return readFileSync3(path, encoding);
375
+ return readFileSync4(path, encoding);
289
376
  }
290
377
  };
291
378
  var command = process.argv[2];
@@ -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.18.2) Checking Start-Work Continuation"
10
+ "statusMessage": "(OmO 4.19.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.18.2) Checking Start-Work Continuation"
22
+ "statusMessage": "(OmO 4.19.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.18.2",
3
+ "version": "4.19.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,12 +1,9 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { isAbsolute, join, relative, resolve } from "node:path";
3
+ import { getPlanChecklist, type PlanChecklist } from "./plan-checklist.js";
3
4
 
4
- export type PlanChecklist = {
5
- readonly completed: number;
6
- readonly remaining: number;
7
- readonly total: number;
8
- readonly nextTaskLabel: string | null;
9
- };
5
+ export type { PlanChecklist } from "./plan-checklist.js";
6
+ export { getPlanChecklist } from "./plan-checklist.js";
10
7
 
11
8
  type BoulderWorkStatus = "active" | "paused" | "completed" | "abandoned";
12
9
 
@@ -35,9 +32,6 @@ export type ContinuationState = {
35
32
  readonly checklist: PlanChecklist;
36
33
  };
37
34
 
38
- const TODO_HEADING = "TODOs";
39
- const FINAL_VERIFICATION_HEADING = "Final Verification Wave";
40
- const CHECKBOX_PREFIX_LENGTH = "- [ ] ".length;
41
35
  const SESSION_ID_PREFIX_PATTERN = /^(codex|opencode):/;
42
36
 
43
37
  export function readContinuationState(cwd: string, sessionId: string): ContinuationState | null {
@@ -62,47 +56,6 @@ export function readContinuationState(cwd: string, sessionId: string): Continuat
62
56
  };
63
57
  }
64
58
 
65
- export function getPlanChecklist(planPath: string): PlanChecklist {
66
- if (!existsSync(planPath)) return emptyChecklist();
67
-
68
- try {
69
- return parsePlanChecklist(readFileSync(planPath, "utf8"));
70
- } catch (error) {
71
- if (error instanceof Error) return emptyChecklist();
72
- throw error;
73
- }
74
- }
75
-
76
- function parsePlanChecklist(markdown: string): PlanChecklist {
77
- const lines = markdown.split(/\r?\n/);
78
- const hasCountedSections = lines.some((line) => isCountedHeading(parseLevelTwoHeading(line)));
79
- let completed = 0;
80
- let remaining = 0;
81
- let nextTaskLabel: string | null = null;
82
- let isCountedSection = !hasCountedSections;
83
-
84
- for (const line of lines) {
85
- const heading = parseLevelTwoHeading(line);
86
- if (heading !== null) {
87
- isCountedSection = isCountedHeading(heading);
88
- continue;
89
- }
90
- if (!isCountedSection) continue;
91
-
92
- const checkbox = parseTopLevelCheckbox(line);
93
- if (checkbox === null) continue;
94
-
95
- if (checkbox.checked) {
96
- completed += 1;
97
- } else {
98
- remaining += 1;
99
- nextTaskLabel = nextTaskLabel ?? checkbox.label;
100
- }
101
- }
102
-
103
- return { completed, remaining, total: completed + remaining, nextTaskLabel };
104
- }
105
-
106
59
  function readBoulderState(path: string): BoulderState | null {
107
60
  try {
108
61
  const parsed: unknown = JSON.parse(readFileSync(path, "utf8"));
@@ -193,23 +146,6 @@ function resolveTrackedPath(baseDirectory: string, trackedPath: string): string
193
146
  return isAbsolute(trackedPath) ? resolve(trackedPath) : resolve(baseDirectory, trackedPath);
194
147
  }
195
148
 
196
- function parseTopLevelCheckbox(line: string): { readonly checked: boolean; readonly label: string } | null {
197
- if (line.startsWith("- [ ] ")) return { checked: false, label: line.slice(CHECKBOX_PREFIX_LENGTH) };
198
- if (line.startsWith("- [x] ") || line.startsWith("- [X] ")) {
199
- return { checked: true, label: line.slice(CHECKBOX_PREFIX_LENGTH) };
200
- }
201
- return null;
202
- }
203
-
204
- function parseLevelTwoHeading(line: string): string | null {
205
- if (!line.startsWith("## ")) return null;
206
- return line.slice("## ".length).trim();
207
- }
208
-
209
- function isCountedHeading(heading: string | null): boolean {
210
- return heading === TODO_HEADING || heading === FINAL_VERIFICATION_HEADING;
211
- }
212
-
213
149
  function parseBoulderWorkStatus(value: unknown): BoulderWorkStatus | undefined {
214
150
  if (value === "active" || value === "paused" || value === "completed" || value === "abandoned") return value;
215
151
  return undefined;
@@ -243,10 +179,6 @@ function getBoulderFilePath(cwd: string): string {
243
179
  return join(cwd, ".omo", "boulder.json");
244
180
  }
245
181
 
246
- function emptyChecklist(): PlanChecklist {
247
- return { completed: 0, remaining: 0, total: 0, nextTaskLabel: null };
248
- }
249
-
250
182
  function isRecord(value: unknown): value is Record<string, unknown> {
251
183
  return typeof value === "object" && value !== null && !Array.isArray(value);
252
184
  }