oh-my-opencode 4.5.1 → 4.5.12

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 (584) hide show
  1. package/README.ja.md +33 -18
  2. package/README.ko.md +33 -18
  3. package/README.md +82 -24
  4. package/README.ru.md +33 -18
  5. package/README.zh-cn.md +45 -24
  6. package/bin/oh-my-opencode.js +47 -2
  7. package/bin/oh-my-opencode.test.ts +174 -0
  8. package/bin/platform.d.ts +6 -0
  9. package/bin/platform.js +19 -0
  10. package/bin/platform.test.ts +66 -1
  11. package/dist/cli/cli-program.d.ts +18 -0
  12. package/dist/cli/index.js +28472 -26159
  13. package/dist/cli/install-codex/codex-cache-bundled-mcps.d.ts +5 -0
  14. package/dist/cli/install-codex/codex-cache-command-shim.d.ts +1 -0
  15. package/dist/cli/install-codex/codex-cache-legacy-bins.d.ts +3 -0
  16. package/dist/cli/install-codex/codex-cache-local-dependencies.d.ts +1 -0
  17. package/dist/cli/install-codex/codex-cache-paths.d.ts +2 -0
  18. package/dist/cli/install-codex/codex-cache.d.ts +31 -0
  19. package/dist/cli/install-codex/codex-config-toml.d.ts +11 -0
  20. package/dist/cli/install-codex/codex-hook-trust.d.ts +6 -0
  21. package/dist/cli/install-codex/codex-marketplace-snapshot.d.ts +15 -0
  22. package/dist/cli/install-codex/codex-marketplace.d.ts +9 -0
  23. package/dist/cli/install-codex/codex-multi-agent-v2-config.d.ts +1 -0
  24. package/dist/cli/install-codex/codex-process.d.ts +2 -0
  25. package/dist/cli/install-codex/index.d.ts +7 -0
  26. package/dist/cli/install-codex/install-codex.d.ts +17 -0
  27. package/dist/cli/install-codex/link-cached-plugin-agents.d.ts +12 -0
  28. package/dist/cli/install-codex/toml-section-editor.d.ts +9 -0
  29. package/dist/cli/install-codex/types.d.ts +56 -0
  30. package/dist/cli/star-request.d.ts +2 -0
  31. package/dist/cli/tui-install-prompts.d.ts +3 -2
  32. package/dist/cli/types.d.ts +8 -0
  33. package/dist/config/schema/agent-names.d.ts +4 -1
  34. package/dist/config/schema/commands.d.ts +1 -2
  35. package/dist/config/schema/oh-my-opencode-config.d.ts +5 -3
  36. package/dist/create-managers.d.ts +1 -0
  37. package/dist/features/background-agent/parent-wake-message-activity.d.ts +23 -0
  38. package/dist/features/background-agent/parent-wake-notifier.d.ts +0 -1
  39. package/dist/features/boulder-state/storage.d.ts +1 -1
  40. package/dist/features/builtin-commands/templates/refactor.d.ts +1 -1
  41. package/dist/features/builtin-commands/templates/remove-ai-slops.d.ts +2 -2
  42. package/dist/features/builtin-commands/types.d.ts +1 -1
  43. package/dist/features/builtin-skills/skill-file-loader.d.ts +4 -0
  44. package/dist/features/builtin-skills/skills/index.d.ts +4 -1
  45. package/dist/features/builtin-skills/skills/init-deep.d.ts +2 -0
  46. package/dist/features/builtin-skills/skills/remove-ai-slops.d.ts +2 -0
  47. package/dist/features/builtin-skills/skills/security-research.d.ts +2 -0
  48. package/dist/features/builtin-skills/skills/security-review.d.ts +2 -0
  49. package/dist/features/opencode-runtime-skills/index.d.ts +2 -0
  50. package/dist/features/opencode-runtime-skills/runtime-skill-config.d.ts +17 -0
  51. package/dist/features/opencode-runtime-skills/skill-markdown.d.ts +7 -0
  52. package/dist/features/opencode-runtime-skills/source-server.d.ts +8 -0
  53. package/dist/hooks/claude-code-hooks/hook-text.d.ts +2 -0
  54. package/dist/hooks/session-recovery/storage/latest-assistant-message.d.ts +5 -0
  55. package/dist/hooks/session-recovery/storage/thinking-prepend.d.ts +3 -0
  56. package/dist/hooks/thinking-block-validator/hook.d.ts +0 -18
  57. package/dist/hooks/todo-continuation-enforcer/pending-question-detection.d.ts +4 -0
  58. package/dist/index.js +1684 -1801
  59. package/dist/oh-my-opencode.schema.json +4 -2
  60. package/dist/plugin-handlers/config-handler.d.ts +2 -1
  61. package/dist/shared/external-plugin-detector.d.ts +8 -0
  62. package/dist/shared/prompt-async-gate/message-inspection-error.d.ts +1 -0
  63. package/dist/shared/prompt-async-gate/pending-tool-turn.d.ts +1 -0
  64. package/dist/shared/prompt-async-gate/prompt-message-state.d.ts +8 -0
  65. package/dist/shared/prompt-timeout-context.d.ts +2 -0
  66. package/dist/testing/create-plugin-module.d.ts +5 -1
  67. package/dist/tools/delegate-task/sync-prompt-sender.d.ts +2 -2
  68. package/package.json +31 -16
  69. package/packages/ast-grep-mcp/dist/cli.js +245 -40
  70. package/packages/lsp-tools-mcp/dist/cli.js +1 -1
  71. package/packages/omo-codex/marketplace.json +17 -0
  72. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +35 -0
  73. package/packages/omo-codex/plugin/.mcp.json +14 -0
  74. package/packages/omo-codex/plugin/README.md +13 -0
  75. package/packages/omo-codex/plugin/components/comment-checker/.gitattributes +13 -0
  76. package/packages/omo-codex/plugin/components/comment-checker/.github/CODEOWNERS +12 -0
  77. package/packages/omo-codex/plugin/components/comment-checker/.github/ISSUE_TEMPLATE/bug.yml +40 -0
  78. package/packages/omo-codex/plugin/components/comment-checker/.github/ISSUE_TEMPLATE/feature.yml +27 -0
  79. package/packages/omo-codex/plugin/components/comment-checker/.github/branch-ruleset.json +45 -0
  80. package/packages/omo-codex/plugin/components/comment-checker/.github/dependabot.yml +16 -0
  81. package/packages/omo-codex/plugin/components/comment-checker/.github/pull_request_template.md +19 -0
  82. package/packages/omo-codex/plugin/components/comment-checker/.github/workflows/ci.yml +47 -0
  83. package/packages/omo-codex/plugin/components/comment-checker/.github/workflows/publish.yml +51 -0
  84. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +35 -0
  85. package/packages/omo-codex/plugin/components/comment-checker/CHANGELOG.md +33 -0
  86. package/packages/omo-codex/plugin/components/comment-checker/LICENSE +21 -0
  87. package/packages/omo-codex/plugin/components/comment-checker/NOTICE +6 -0
  88. package/packages/omo-codex/plugin/components/comment-checker/README.md +87 -0
  89. package/packages/omo-codex/plugin/components/comment-checker/biome.json +48 -0
  90. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +17 -0
  91. package/packages/omo-codex/plugin/components/comment-checker/package.json +57 -0
  92. package/packages/omo-codex/plugin/components/comment-checker/skills/comment-checker/SKILL.md +16 -0
  93. package/packages/omo-codex/plugin/components/comment-checker/src/cli.ts +12 -0
  94. package/packages/omo-codex/plugin/components/comment-checker/src/codex-hook.ts +205 -0
  95. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +361 -0
  96. package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +195 -0
  97. package/packages/omo-codex/plugin/components/comment-checker/test/codex-hook-newline.test.ts +52 -0
  98. package/packages/omo-codex/plugin/components/comment-checker/test/codex-hook.test.ts +368 -0
  99. package/packages/omo-codex/plugin/components/comment-checker/test/fixtures/post-tool-use.json +15 -0
  100. package/packages/omo-codex/plugin/components/comment-checker/test/package-smoke.test.ts +93 -0
  101. package/packages/omo-codex/plugin/components/comment-checker/test/runner.test.ts +66 -0
  102. package/packages/omo-codex/plugin/components/comment-checker/tsconfig.build.json +12 -0
  103. package/packages/omo-codex/plugin/components/comment-checker/tsconfig.json +27 -0
  104. package/packages/omo-codex/plugin/components/comment-checker/vitest.config.ts +9 -0
  105. package/packages/omo-codex/plugin/components/lsp/.gitattributes +13 -0
  106. package/packages/omo-codex/plugin/components/lsp/.github/CODEOWNERS +1 -0
  107. package/packages/omo-codex/plugin/components/lsp/.github/ISSUE_TEMPLATE/bug.yml +26 -0
  108. package/packages/omo-codex/plugin/components/lsp/.github/ISSUE_TEMPLATE/feature.yml +19 -0
  109. package/packages/omo-codex/plugin/components/lsp/.github/branch-ruleset.json +45 -0
  110. package/packages/omo-codex/plugin/components/lsp/.github/dependabot.yml +11 -0
  111. package/packages/omo-codex/plugin/components/lsp/.github/pull_request_template.md +11 -0
  112. package/packages/omo-codex/plugin/components/lsp/.github/workflows/ci.yml +56 -0
  113. package/packages/omo-codex/plugin/components/lsp/.github/workflows/publish.yml +60 -0
  114. package/packages/omo-codex/plugin/components/lsp/.mcp.json +9 -0
  115. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +25 -0
  116. package/packages/omo-codex/plugin/components/lsp/CHANGELOG.md +25 -0
  117. package/packages/omo-codex/plugin/components/lsp/LICENSE +21 -0
  118. package/packages/omo-codex/plugin/components/lsp/NOTICE +3 -0
  119. package/packages/omo-codex/plugin/components/lsp/README.md +148 -0
  120. package/packages/omo-codex/plugin/components/lsp/biome.json +48 -0
  121. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +17 -0
  122. package/packages/omo-codex/plugin/components/lsp/package.json +64 -0
  123. package/packages/omo-codex/plugin/components/lsp/scripts/build-lsp-tools.mjs +46 -0
  124. package/packages/omo-codex/plugin/components/lsp/scripts/build-lsp-tools.test.mjs +104 -0
  125. package/packages/omo-codex/plugin/components/lsp/scripts/clean-dist.mjs +5 -0
  126. package/packages/omo-codex/plugin/components/lsp/scripts/test.mjs +8 -0
  127. package/packages/omo-codex/plugin/components/lsp/skills/lsp/SKILL.md +35 -0
  128. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +44 -0
  129. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +285 -0
  130. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +358 -0
  131. package/packages/omo-codex/plugin/components/lsp/test/fixtures/broken.py +1 -0
  132. package/packages/omo-codex/plugin/components/lsp/test/fixtures/post-tool-use.json +15 -0
  133. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +153 -0
  134. package/packages/omo-codex/plugin/components/lsp/tsconfig.build.json +12 -0
  135. package/packages/omo-codex/plugin/components/lsp/tsconfig.json +27 -0
  136. package/packages/omo-codex/plugin/components/lsp/vitest.config.ts +9 -0
  137. package/packages/omo-codex/plugin/components/rules/.codex-plugin/plugin.json +3 -0
  138. package/packages/omo-codex/plugin/components/rules/.gitattributes +13 -0
  139. package/packages/omo-codex/plugin/components/rules/.github/CODEOWNERS +12 -0
  140. package/packages/omo-codex/plugin/components/rules/.github/ISSUE_TEMPLATE/bug.yml +49 -0
  141. package/packages/omo-codex/plugin/components/rules/.github/ISSUE_TEMPLATE/feature.yml +27 -0
  142. package/packages/omo-codex/plugin/components/rules/.github/branch-ruleset.json +45 -0
  143. package/packages/omo-codex/plugin/components/rules/.github/dependabot.yml +16 -0
  144. package/packages/omo-codex/plugin/components/rules/.github/pull_request_template.md +20 -0
  145. package/packages/omo-codex/plugin/components/rules/.github/workflows/ci.yml +47 -0
  146. package/packages/omo-codex/plugin/components/rules/.github/workflows/publish.yml +51 -0
  147. package/packages/omo-codex/plugin/components/rules/AGENTS.md +34 -0
  148. package/packages/omo-codex/plugin/components/rules/CHANGELOG.md +19 -0
  149. package/packages/omo-codex/plugin/components/rules/LICENSE +21 -0
  150. package/packages/omo-codex/plugin/components/rules/NOTICE +15 -0
  151. package/packages/omo-codex/plugin/components/rules/README.md +124 -0
  152. package/packages/omo-codex/plugin/components/rules/biome.json +48 -0
  153. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus.md +209 -0
  154. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +54 -0
  155. package/packages/omo-codex/plugin/components/rules/package.json +62 -0
  156. package/packages/omo-codex/plugin/components/rules/scripts/bench-codex-rules.mjs +268 -0
  157. package/packages/omo-codex/plugin/components/rules/skills/rules/SKILL.md +34 -0
  158. package/packages/omo-codex/plugin/components/rules/src/cli.ts +143 -0
  159. package/packages/omo-codex/plugin/components/rules/src/codex-hook-options.ts +4 -0
  160. package/packages/omo-codex/plugin/components/rules/src/codex-hook.ts +238 -0
  161. package/packages/omo-codex/plugin/components/rules/src/config.ts +107 -0
  162. package/packages/omo-codex/plugin/components/rules/src/context-pressure.ts +26 -0
  163. package/packages/omo-codex/plugin/components/rules/src/debug-log.ts +65 -0
  164. package/packages/omo-codex/plugin/components/rules/src/dynamic-target-fingerprints.ts +98 -0
  165. package/packages/omo-codex/plugin/components/rules/src/hook-output.ts +19 -0
  166. package/packages/omo-codex/plugin/components/rules/src/path-utils.ts +29 -0
  167. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +234 -0
  168. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +104 -0
  169. package/packages/omo-codex/plugin/components/rules/src/post-compact-claim.ts +13 -0
  170. package/packages/omo-codex/plugin/components/rules/src/post-compact-state.ts +45 -0
  171. package/packages/omo-codex/plugin/components/rules/src/rules/cache.ts +64 -0
  172. package/packages/omo-codex/plugin/components/rules/src/rules/constants.ts +115 -0
  173. package/packages/omo-codex/plugin/components/rules/src/rules/engine.ts +535 -0
  174. package/packages/omo-codex/plugin/components/rules/src/rules/errors.ts +13 -0
  175. package/packages/omo-codex/plugin/components/rules/src/rules/finder-cache.ts +73 -0
  176. package/packages/omo-codex/plugin/components/rules/src/rules/finder-paths.ts +47 -0
  177. package/packages/omo-codex/plugin/components/rules/src/rules/finder-sources.ts +50 -0
  178. package/packages/omo-codex/plugin/components/rules/src/rules/finder.ts +207 -0
  179. package/packages/omo-codex/plugin/components/rules/src/rules/formatter.ts +123 -0
  180. package/packages/omo-codex/plugin/components/rules/src/rules/matcher.ts +142 -0
  181. package/packages/omo-codex/plugin/components/rules/src/rules/ordering.ts +33 -0
  182. package/packages/omo-codex/plugin/components/rules/src/rules/parser.ts +326 -0
  183. package/packages/omo-codex/plugin/components/rules/src/rules/plugin-root.ts +55 -0
  184. package/packages/omo-codex/plugin/components/rules/src/rules/project-root.ts +30 -0
  185. package/packages/omo-codex/plugin/components/rules/src/rules/scanner.ts +162 -0
  186. package/packages/omo-codex/plugin/components/rules/src/rules/truncator.ts +67 -0
  187. package/packages/omo-codex/plugin/components/rules/src/rules/types.ts +141 -0
  188. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +24 -0
  189. package/packages/omo-codex/plugin/components/rules/src/session-state-lock.ts +47 -0
  190. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +56 -0
  191. package/packages/omo-codex/plugin/components/rules/src/tool-paths.ts +192 -0
  192. package/packages/omo-codex/plugin/components/rules/src/transcript-rule-filter.ts +44 -0
  193. package/packages/omo-codex/plugin/components/rules/src/transcript-search.ts +108 -0
  194. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +107 -0
  195. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +268 -0
  196. package/packages/omo-codex/plugin/components/rules/test/codex-hook-context-pressure.test.ts +243 -0
  197. package/packages/omo-codex/plugin/components/rules/test/codex-hook-performance.test.ts +99 -0
  198. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +132 -0
  199. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +156 -0
  200. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +299 -0
  201. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-lock.test.ts +46 -0
  202. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-process.test.ts +83 -0
  203. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +667 -0
  204. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +192 -0
  205. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +102 -0
  206. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +168 -0
  207. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +42 -0
  208. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +206 -0
  209. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +151 -0
  210. package/packages/omo-codex/plugin/components/rules/test/persistent-cache.test.ts +63 -0
  211. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +172 -0
  212. package/packages/omo-codex/plugin/components/rules/test/post-compact-test-fixture.ts +196 -0
  213. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +63 -0
  214. package/packages/omo-codex/plugin/components/rules/test/tool-paths.test.ts +198 -0
  215. package/packages/omo-codex/plugin/components/rules/tsconfig.build.json +12 -0
  216. package/packages/omo-codex/plugin/components/rules/tsconfig.json +27 -0
  217. package/packages/omo-codex/plugin/components/rules/vitest.config.ts +8 -0
  218. package/packages/omo-codex/plugin/components/start-work-continuation/.gitattributes +13 -0
  219. package/packages/omo-codex/plugin/components/start-work-continuation/AGENTS.md +43 -0
  220. package/packages/omo-codex/plugin/components/start-work-continuation/CHANGELOG.md +5 -0
  221. package/packages/omo-codex/plugin/components/start-work-continuation/LICENSE +21 -0
  222. package/packages/omo-codex/plugin/components/start-work-continuation/NOTICE +5 -0
  223. package/packages/omo-codex/plugin/components/start-work-continuation/README.md +55 -0
  224. package/packages/omo-codex/plugin/components/start-work-continuation/biome.json +48 -0
  225. package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +51 -0
  226. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +28 -0
  227. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +53 -0
  228. package/packages/omo-codex/plugin/components/start-work-continuation/src/boulder-reader.ts +167 -0
  229. package/packages/omo-codex/plugin/components/start-work-continuation/src/cli.ts +52 -0
  230. package/packages/omo-codex/plugin/components/start-work-continuation/src/codex-hook.ts +66 -0
  231. package/packages/omo-codex/plugin/components/start-work-continuation/src/directive.ts +6 -0
  232. package/packages/omo-codex/plugin/components/start-work-continuation/src/index.ts +5 -0
  233. package/packages/omo-codex/plugin/components/start-work-continuation/src/types.ts +23 -0
  234. package/packages/omo-codex/plugin/components/start-work-continuation/test/boulder-reader.test.ts +63 -0
  235. package/packages/omo-codex/plugin/components/start-work-continuation/test/cli.test.ts +124 -0
  236. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +160 -0
  237. package/packages/omo-codex/plugin/components/start-work-continuation/test/fixtures/boulder-completed.json +19 -0
  238. package/packages/omo-codex/plugin/components/start-work-continuation/test/fixtures/boulder-mixed-platforms.json +27 -0
  239. package/packages/omo-codex/plugin/components/start-work-continuation/test/fixtures/boulder-single-codex-work.json +19 -0
  240. package/packages/omo-codex/plugin/components/start-work-continuation/test/fixtures/plan-all-done.md +5 -0
  241. package/packages/omo-codex/plugin/components/start-work-continuation/test/fixtures/plan-with-nested-checkboxes.md +11 -0
  242. package/packages/omo-codex/plugin/components/start-work-continuation/test/fixtures/plan-with-unchecked.md +6 -0
  243. package/packages/omo-codex/plugin/components/start-work-continuation/tsconfig.build.json +12 -0
  244. package/packages/omo-codex/plugin/components/start-work-continuation/tsconfig.json +27 -0
  245. package/packages/omo-codex/plugin/components/start-work-continuation/vitest.config.ts +10 -0
  246. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +37 -0
  247. package/packages/omo-codex/plugin/components/telemetry/README.md +102 -0
  248. package/packages/omo-codex/plugin/components/telemetry/biome.json +48 -0
  249. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +16 -0
  250. package/packages/omo-codex/plugin/components/telemetry/package.json +56 -0
  251. package/packages/omo-codex/plugin/components/telemetry/src/atomic-write.ts +22 -0
  252. package/packages/omo-codex/plugin/components/telemetry/src/cli.ts +69 -0
  253. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +49 -0
  254. package/packages/omo-codex/plugin/components/telemetry/src/data-path.ts +45 -0
  255. package/packages/omo-codex/plugin/components/telemetry/src/env-flags.ts +43 -0
  256. package/packages/omo-codex/plugin/components/telemetry/src/posthog-activity-state.ts +81 -0
  257. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +165 -0
  258. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +35 -0
  259. package/packages/omo-codex/plugin/components/telemetry/test/codex-hook.test.ts +270 -0
  260. package/packages/omo-codex/plugin/components/telemetry/tsconfig.build.json +12 -0
  261. package/packages/omo-codex/plugin/components/telemetry/tsconfig.json +27 -0
  262. package/packages/omo-codex/plugin/components/telemetry/vitest.config.ts +8 -0
  263. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +41 -0
  264. package/packages/omo-codex/plugin/components/ultrawork/CHANGELOG.md +25 -0
  265. package/packages/omo-codex/plugin/components/ultrawork/LICENSE +21 -0
  266. package/packages/omo-codex/plugin/components/ultrawork/NOTICE +5 -0
  267. package/packages/omo-codex/plugin/components/ultrawork/README.md +60 -0
  268. package/packages/omo-codex/plugin/components/ultrawork/agents/codex-ultrawork-reviewer.toml +17 -0
  269. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +82 -0
  270. package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +221 -0
  271. package/packages/omo-codex/plugin/components/ultrawork/agents/metis.toml +65 -0
  272. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +69 -0
  273. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +163 -0
  274. package/packages/omo-codex/plugin/components/ultrawork/biome.json +48 -0
  275. package/packages/omo-codex/plugin/components/ultrawork/directive.md +264 -0
  276. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +16 -0
  277. package/packages/omo-codex/plugin/components/ultrawork/package.json +54 -0
  278. package/packages/omo-codex/plugin/components/ultrawork/src/cli.ts +50 -0
  279. package/packages/omo-codex/plugin/components/ultrawork/src/codex-hook.ts +84 -0
  280. package/packages/omo-codex/plugin/components/ultrawork/src/directive.ts +3 -0
  281. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +252 -0
  282. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +78 -0
  283. package/packages/omo-codex/plugin/components/ultrawork/tsconfig.build.json +12 -0
  284. package/packages/omo-codex/plugin/components/ultrawork/tsconfig.json +27 -0
  285. package/packages/omo-codex/plugin/components/ulw-loop/.gitattributes +13 -0
  286. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +48 -0
  287. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +7 -0
  288. package/packages/omo-codex/plugin/components/ulw-loop/LICENSE +21 -0
  289. package/packages/omo-codex/plugin/components/ulw-loop/NOTICE +6 -0
  290. package/packages/omo-codex/plugin/components/ulw-loop/README.md +74 -0
  291. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +48 -0
  292. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +29 -0
  293. package/packages/omo-codex/plugin/components/ulw-loop/package.json +55 -0
  294. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/.gitkeep +0 -0
  295. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +222 -0
  296. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/agents/openai.yaml +6 -0
  297. package/packages/omo-codex/plugin/components/ulw-loop/src/.gitkeep +0 -0
  298. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +155 -0
  299. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-arg-parser.ts +95 -0
  300. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +156 -0
  301. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +63 -0
  302. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-steering.ts +94 -0
  303. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +40 -0
  304. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +129 -0
  305. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +139 -0
  306. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +177 -0
  307. package/packages/omo-codex/plugin/components/ulw-loop/src/evidence.ts +122 -0
  308. package/packages/omo-codex/plugin/components/ulw-loop/src/goal-status.ts +88 -0
  309. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +73 -0
  310. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +113 -0
  311. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +124 -0
  312. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +102 -0
  313. package/packages/omo-codex/plugin/components/ulw-loop/src/review-blockers.ts +81 -0
  314. package/packages/omo-codex/plugin/components/ulw-loop/src/steering.ts +270 -0
  315. package/packages/omo-codex/plugin/components/ulw-loop/src/types.ts +277 -0
  316. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint.test.ts +213 -0
  317. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-commands.test.ts +375 -0
  318. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-helpers.test.ts +250 -0
  319. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering.test.ts +407 -0
  320. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +169 -0
  321. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +156 -0
  322. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +275 -0
  323. package/packages/omo-codex/plugin/components/ulw-loop/test/evidence-criteria-gate.test.ts +100 -0
  324. package/packages/omo-codex/plugin/components/ulw-loop/test/evidence.test.ts +263 -0
  325. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/.gitkeep +0 -0
  326. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/codex-goal-snapshot.json +1 -0
  327. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/sample-brief.md +5 -0
  328. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/sample-plan.json +108 -0
  329. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/sample-quality-gate.json +18 -0
  330. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/steering-proposal.json +8 -0
  331. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/user-prompt-submit.json +10 -0
  332. package/packages/omo-codex/plugin/components/ulw-loop/test/goal-status.test.ts +327 -0
  333. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +164 -0
  334. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +62 -0
  335. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-crud.test.ts +256 -0
  336. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io.test.ts +239 -0
  337. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +203 -0
  338. package/packages/omo-codex/plugin/components/ulw-loop/test/review-blockers.test.ts +180 -0
  339. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +353 -0
  340. package/packages/omo-codex/plugin/components/ulw-loop/test/types.test.ts +79 -0
  341. package/packages/omo-codex/plugin/components/ulw-loop/tsconfig.build.json +12 -0
  342. package/packages/omo-codex/plugin/components/ulw-loop/tsconfig.json +27 -0
  343. package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +10 -0
  344. package/packages/omo-codex/plugin/hooks/hooks.json +138 -0
  345. package/packages/omo-codex/plugin/package-lock.json +1750 -0
  346. package/packages/omo-codex/plugin/package.json +26 -0
  347. package/packages/omo-codex/plugin/scripts/build-bundled-mcp-runtimes.mjs +50 -0
  348. package/packages/omo-codex/plugin/scripts/build-components.mjs +23 -0
  349. package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +46 -0
  350. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +75 -0
  351. package/packages/omo-codex/plugin/skills/comment-checker/SKILL.md +16 -0
  352. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +116 -0
  353. package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +108 -0
  354. package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +130 -0
  355. package/packages/omo-codex/plugin/skills/debugging/references/methodology/04-oracle-triple.md +136 -0
  356. package/packages/omo-codex/plugin/skills/debugging/references/methodology/05-escalate.md +69 -0
  357. package/packages/omo-codex/plugin/skills/debugging/references/methodology/06-fix.md +116 -0
  358. package/packages/omo-codex/plugin/skills/debugging/references/methodology/08-qa.md +94 -0
  359. package/packages/omo-codex/plugin/skills/debugging/references/methodology/09-cleanup.md +164 -0
  360. package/packages/omo-codex/plugin/skills/debugging/references/methodology/partial-runtime-evidence.md +229 -0
  361. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/bundled-js-binary.md +415 -0
  362. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +252 -0
  363. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +484 -0
  364. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +260 -0
  365. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +248 -0
  366. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +234 -0
  367. package/packages/omo-codex/plugin/skills/debugging/references/tools/ghidra.md +212 -0
  368. package/packages/omo-codex/plugin/skills/debugging/references/tools/playwright-cli.md +194 -0
  369. package/packages/omo-codex/plugin/skills/debugging/references/tools/pwndbg.md +263 -0
  370. package/packages/omo-codex/plugin/skills/debugging/references/tools/pwntools.md +265 -0
  371. package/packages/omo-codex/plugin/skills/frontend-ui-ux/SKILL.md +77 -0
  372. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +325 -0
  373. package/packages/omo-codex/plugin/skills/lsp/SKILL.md +35 -0
  374. package/packages/omo-codex/plugin/skills/programming/SKILL.md +463 -0
  375. package/packages/omo-codex/plugin/skills/programming/references/go/README.md +90 -0
  376. package/packages/omo-codex/plugin/skills/programming/references/go/backend-stack.md +641 -0
  377. package/packages/omo-codex/plugin/skills/programming/references/go/bootstrap.md +328 -0
  378. package/packages/omo-codex/plugin/skills/programming/references/go/bubbletea-v2.md +360 -0
  379. package/packages/omo-codex/plugin/skills/programming/references/go/cobra-stack.md +468 -0
  380. package/packages/omo-codex/plugin/skills/programming/references/go/concurrency.md +362 -0
  381. package/packages/omo-codex/plugin/skills/programming/references/go/data-modeling.md +329 -0
  382. package/packages/omo-codex/plugin/skills/programming/references/go/error-handling.md +359 -0
  383. package/packages/omo-codex/plugin/skills/programming/references/go/golangci-strict.md +236 -0
  384. package/packages/omo-codex/plugin/skills/programming/references/go/grpc-connect.md +375 -0
  385. package/packages/omo-codex/plugin/skills/programming/references/go/libraries.md +337 -0
  386. package/packages/omo-codex/plugin/skills/programming/references/go/one-liners.md +202 -0
  387. package/packages/omo-codex/plugin/skills/programming/references/go/sqlc-pgx.md +471 -0
  388. package/packages/omo-codex/plugin/skills/programming/references/go/testing.md +467 -0
  389. package/packages/omo-codex/plugin/skills/programming/references/go/type-patterns.md +298 -0
  390. package/packages/omo-codex/plugin/skills/programming/references/python/README.md +314 -0
  391. package/packages/omo-codex/plugin/skills/programming/references/python/async-anyio.md +442 -0
  392. package/packages/omo-codex/plugin/skills/programming/references/python/data-modeling.md +233 -0
  393. package/packages/omo-codex/plugin/skills/programming/references/python/data-processing.md +133 -0
  394. package/packages/omo-codex/plugin/skills/programming/references/python/error-handling.md +218 -0
  395. package/packages/omo-codex/plugin/skills/programming/references/python/fastapi-stack.md +316 -0
  396. package/packages/omo-codex/plugin/skills/programming/references/python/httpx2-optimization.md +360 -0
  397. package/packages/omo-codex/plugin/skills/programming/references/python/libraries.md +307 -0
  398. package/packages/omo-codex/plugin/skills/programming/references/python/one-liners.md +268 -0
  399. package/packages/omo-codex/plugin/skills/programming/references/python/orjson-stack.md +378 -0
  400. package/packages/omo-codex/plugin/skills/programming/references/python/pydantic-ai.md +285 -0
  401. package/packages/omo-codex/plugin/skills/programming/references/python/pyproject-strict.md +232 -0
  402. package/packages/omo-codex/plugin/skills/programming/references/python/textual-tui.md +201 -0
  403. package/packages/omo-codex/plugin/skills/programming/references/python/type-patterns.md +176 -0
  404. package/packages/omo-codex/plugin/skills/programming/references/rust/README.md +317 -0
  405. package/packages/omo-codex/plugin/skills/programming/references/rust/async-tokio.md +299 -0
  406. package/packages/omo-codex/plugin/skills/programming/references/rust/axum-stack.md +467 -0
  407. package/packages/omo-codex/plugin/skills/programming/references/rust/cargo-strict.md +317 -0
  408. package/packages/omo-codex/plugin/skills/programming/references/rust/clap-stack.md +409 -0
  409. package/packages/omo-codex/plugin/skills/programming/references/rust/concurrency.md +375 -0
  410. package/packages/omo-codex/plugin/skills/programming/references/rust/libraries.md +439 -0
  411. package/packages/omo-codex/plugin/skills/programming/references/rust/one-liners.md +291 -0
  412. package/packages/omo-codex/plugin/skills/programming/references/rust/proptest-insta.md +429 -0
  413. package/packages/omo-codex/plugin/skills/programming/references/rust/type-state.md +354 -0
  414. package/packages/omo-codex/plugin/skills/programming/references/rust/unsafe-discipline.md +250 -0
  415. package/packages/omo-codex/plugin/skills/programming/references/rust/zero-cost-safety.md +527 -0
  416. package/packages/omo-codex/plugin/skills/programming/references/rust-ub/README.md +289 -0
  417. package/packages/omo-codex/plugin/skills/programming/references/rust-ub/miri-sanitizers-loom.md +411 -0
  418. package/packages/omo-codex/plugin/skills/programming/references/rust-ub/ub-taxonomy.md +269 -0
  419. package/packages/omo-codex/plugin/skills/programming/references/typescript/README.md +195 -0
  420. package/packages/omo-codex/plugin/skills/programming/references/typescript/backend-hono.md +672 -0
  421. package/packages/omo-codex/plugin/skills/programming/references/typescript/bootstrap.md +199 -0
  422. package/packages/omo-codex/plugin/skills/programming/references/typescript/data-modeling.md +202 -0
  423. package/packages/omo-codex/plugin/skills/programming/references/typescript/error-handling.md +169 -0
  424. package/packages/omo-codex/plugin/skills/programming/references/typescript/tsconfig-strict.md +152 -0
  425. package/packages/omo-codex/plugin/skills/programming/references/typescript/type-patterns.md +196 -0
  426. package/packages/omo-codex/plugin/skills/programming/scripts/go/check-no-excuse-rules.sh +173 -0
  427. package/packages/omo-codex/plugin/skills/programming/scripts/go/new-project.py +138 -0
  428. package/packages/omo-codex/plugin/skills/programming/scripts/go/templates/.editorconfig +13 -0
  429. package/packages/omo-codex/plugin/skills/programming/scripts/go/templates/.golangci.yml +95 -0
  430. package/packages/omo-codex/plugin/skills/programming/scripts/go/templates/AGENTS.md.tmpl +24 -0
  431. package/packages/omo-codex/plugin/skills/programming/scripts/go/templates/README.md.tmpl +12 -0
  432. package/packages/omo-codex/plugin/skills/programming/scripts/go/templates/Taskfile.yml +40 -0
  433. package/packages/omo-codex/plugin/skills/programming/scripts/go/templates/ci.yml +37 -0
  434. package/packages/omo-codex/plugin/skills/programming/scripts/go/templates/config.go +24 -0
  435. package/packages/omo-codex/plugin/skills/programming/scripts/go/templates/gitignore +15 -0
  436. package/packages/omo-codex/plugin/skills/programming/scripts/go/templates/main.go.tmpl +22 -0
  437. package/packages/omo-codex/plugin/skills/programming/scripts/go/templates/run.go +15 -0
  438. package/packages/omo-codex/plugin/skills/programming/scripts/python/check-no-excuse-rules.py +687 -0
  439. package/packages/omo-codex/plugin/skills/programming/scripts/python/new-project.py +172 -0
  440. package/packages/omo-codex/plugin/skills/programming/scripts/python/new-script.py +116 -0
  441. package/packages/omo-codex/plugin/skills/programming/scripts/rust/check-no-excuse-rules.py +296 -0
  442. package/packages/omo-codex/plugin/skills/programming/scripts/rust/check-no-excuse-rules.sh +158 -0
  443. package/packages/omo-codex/plugin/skills/programming/scripts/rust/new-project.py +175 -0
  444. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-no-excuse-rules.ts +282 -0
  445. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/new-project.ts +177 -0
  446. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +779 -0
  447. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +333 -0
  448. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +549 -0
  449. package/packages/omo-codex/plugin/skills/rules/SKILL.md +34 -0
  450. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +129 -0
  451. package/packages/omo-codex/plugin/skills/ulw-loop/.gitkeep +0 -0
  452. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +222 -0
  453. package/packages/omo-codex/plugin/skills/ulw-loop/agents/openai.yaml +6 -0
  454. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +399 -0
  455. package/packages/omo-codex/plugin/test/aggregate.test.mjs +330 -0
  456. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +66 -0
  457. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +150 -0
  458. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +199 -0
  459. package/packages/omo-codex/scripts/install/agents.mjs +84 -0
  460. package/packages/omo-codex/scripts/install/cache.mjs +245 -0
  461. package/packages/omo-codex/scripts/install/command-shim.mjs +1 -0
  462. package/packages/omo-codex/scripts/install/config.mjs +229 -0
  463. package/packages/omo-codex/scripts/install/hook-trust.mjs +84 -0
  464. package/packages/omo-codex/scripts/install/legacy-bins.mjs +57 -0
  465. package/packages/omo-codex/scripts/install/marketplace.mjs +104 -0
  466. package/packages/omo-codex/scripts/install/mcp-runtime-cache.mjs +77 -0
  467. package/packages/omo-codex/scripts/install/multi-agent-v2-config.mjs +32 -0
  468. package/packages/omo-codex/scripts/install/process.mjs +19 -0
  469. package/packages/omo-codex/scripts/install/snapshot.mjs +54 -0
  470. package/packages/omo-codex/scripts/install/toml-editor.mjs +47 -0
  471. package/packages/omo-codex/scripts/install/utils.mjs +15 -0
  472. package/packages/omo-codex/scripts/install-agent-links.test.mjs +104 -0
  473. package/packages/omo-codex/scripts/install-bin-links.test.mjs +123 -0
  474. package/packages/omo-codex/scripts/install-cache-copy.test.mjs +30 -0
  475. package/packages/omo-codex/scripts/install-config.test.mjs +118 -0
  476. package/packages/omo-codex/scripts/install-local.mjs +192 -0
  477. package/packages/omo-codex/scripts/install-local.test.mjs +379 -0
  478. package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +173 -0
  479. package/packages/omo-codex/scripts/install-test-fixtures.mjs +58 -0
  480. package/packages/omo-codex/scripts/sync-telemetry-component.mjs +115 -0
  481. package/packages/omo-codex/scripts/sync-telemetry-component.test.mjs +94 -0
  482. package/packages/shared-skills/index.mjs +5 -0
  483. package/packages/shared-skills/package.json +14 -0
  484. package/packages/shared-skills/skills/debugging/SKILL.md +116 -0
  485. package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +108 -0
  486. package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +130 -0
  487. package/packages/shared-skills/skills/debugging/references/methodology/04-oracle-triple.md +136 -0
  488. package/packages/shared-skills/skills/debugging/references/methodology/05-escalate.md +69 -0
  489. package/packages/shared-skills/skills/debugging/references/methodology/06-fix.md +116 -0
  490. package/packages/shared-skills/skills/debugging/references/methodology/08-qa.md +94 -0
  491. package/packages/shared-skills/skills/debugging/references/methodology/09-cleanup.md +164 -0
  492. package/packages/shared-skills/skills/debugging/references/methodology/partial-runtime-evidence.md +229 -0
  493. package/packages/shared-skills/skills/debugging/references/runtimes/bundled-js-binary.md +415 -0
  494. package/packages/shared-skills/skills/debugging/references/runtimes/go.md +252 -0
  495. package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +484 -0
  496. package/packages/shared-skills/skills/debugging/references/runtimes/node.md +260 -0
  497. package/packages/shared-skills/skills/debugging/references/runtimes/python.md +248 -0
  498. package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +234 -0
  499. package/packages/shared-skills/skills/debugging/references/tools/ghidra.md +212 -0
  500. package/packages/shared-skills/skills/debugging/references/tools/playwright-cli.md +194 -0
  501. package/packages/shared-skills/skills/debugging/references/tools/pwndbg.md +263 -0
  502. package/packages/shared-skills/skills/debugging/references/tools/pwntools.md +265 -0
  503. package/packages/shared-skills/skills/frontend-ui-ux/SKILL.md +77 -0
  504. package/packages/shared-skills/skills/init-deep/SKILL.md +309 -0
  505. package/packages/shared-skills/skills/programming/SKILL.md +463 -0
  506. package/packages/shared-skills/skills/programming/references/go/README.md +90 -0
  507. package/packages/shared-skills/skills/programming/references/go/backend-stack.md +641 -0
  508. package/packages/shared-skills/skills/programming/references/go/bootstrap.md +328 -0
  509. package/packages/shared-skills/skills/programming/references/go/bubbletea-v2.md +360 -0
  510. package/packages/shared-skills/skills/programming/references/go/cobra-stack.md +468 -0
  511. package/packages/shared-skills/skills/programming/references/go/concurrency.md +362 -0
  512. package/packages/shared-skills/skills/programming/references/go/data-modeling.md +329 -0
  513. package/packages/shared-skills/skills/programming/references/go/error-handling.md +359 -0
  514. package/packages/shared-skills/skills/programming/references/go/golangci-strict.md +236 -0
  515. package/packages/shared-skills/skills/programming/references/go/grpc-connect.md +375 -0
  516. package/packages/shared-skills/skills/programming/references/go/libraries.md +337 -0
  517. package/packages/shared-skills/skills/programming/references/go/one-liners.md +202 -0
  518. package/packages/shared-skills/skills/programming/references/go/sqlc-pgx.md +471 -0
  519. package/packages/shared-skills/skills/programming/references/go/testing.md +467 -0
  520. package/packages/shared-skills/skills/programming/references/go/type-patterns.md +298 -0
  521. package/packages/shared-skills/skills/programming/references/python/README.md +314 -0
  522. package/packages/shared-skills/skills/programming/references/python/async-anyio.md +442 -0
  523. package/packages/shared-skills/skills/programming/references/python/data-modeling.md +233 -0
  524. package/packages/shared-skills/skills/programming/references/python/data-processing.md +133 -0
  525. package/packages/shared-skills/skills/programming/references/python/error-handling.md +218 -0
  526. package/packages/shared-skills/skills/programming/references/python/fastapi-stack.md +316 -0
  527. package/packages/shared-skills/skills/programming/references/python/httpx2-optimization.md +360 -0
  528. package/packages/shared-skills/skills/programming/references/python/libraries.md +307 -0
  529. package/packages/shared-skills/skills/programming/references/python/one-liners.md +268 -0
  530. package/packages/shared-skills/skills/programming/references/python/orjson-stack.md +378 -0
  531. package/packages/shared-skills/skills/programming/references/python/pydantic-ai.md +285 -0
  532. package/packages/shared-skills/skills/programming/references/python/pyproject-strict.md +232 -0
  533. package/packages/shared-skills/skills/programming/references/python/textual-tui.md +201 -0
  534. package/packages/shared-skills/skills/programming/references/python/type-patterns.md +176 -0
  535. package/packages/shared-skills/skills/programming/references/rust/README.md +317 -0
  536. package/packages/shared-skills/skills/programming/references/rust/async-tokio.md +299 -0
  537. package/packages/shared-skills/skills/programming/references/rust/axum-stack.md +467 -0
  538. package/packages/shared-skills/skills/programming/references/rust/cargo-strict.md +317 -0
  539. package/packages/shared-skills/skills/programming/references/rust/clap-stack.md +409 -0
  540. package/packages/shared-skills/skills/programming/references/rust/concurrency.md +375 -0
  541. package/packages/shared-skills/skills/programming/references/rust/libraries.md +439 -0
  542. package/packages/shared-skills/skills/programming/references/rust/one-liners.md +291 -0
  543. package/packages/shared-skills/skills/programming/references/rust/proptest-insta.md +429 -0
  544. package/packages/shared-skills/skills/programming/references/rust/type-state.md +354 -0
  545. package/packages/shared-skills/skills/programming/references/rust/unsafe-discipline.md +250 -0
  546. package/packages/shared-skills/skills/programming/references/rust/zero-cost-safety.md +527 -0
  547. package/packages/shared-skills/skills/programming/references/rust-ub/README.md +289 -0
  548. package/packages/shared-skills/skills/programming/references/rust-ub/miri-sanitizers-loom.md +411 -0
  549. package/packages/shared-skills/skills/programming/references/rust-ub/ub-taxonomy.md +269 -0
  550. package/packages/shared-skills/skills/programming/references/typescript/README.md +195 -0
  551. package/packages/shared-skills/skills/programming/references/typescript/backend-hono.md +672 -0
  552. package/packages/shared-skills/skills/programming/references/typescript/bootstrap.md +199 -0
  553. package/packages/shared-skills/skills/programming/references/typescript/data-modeling.md +202 -0
  554. package/packages/shared-skills/skills/programming/references/typescript/error-handling.md +169 -0
  555. package/packages/shared-skills/skills/programming/references/typescript/tsconfig-strict.md +152 -0
  556. package/packages/shared-skills/skills/programming/references/typescript/type-patterns.md +196 -0
  557. package/packages/shared-skills/skills/programming/scripts/go/check-no-excuse-rules.sh +173 -0
  558. package/packages/shared-skills/skills/programming/scripts/go/new-project.py +138 -0
  559. package/packages/shared-skills/skills/programming/scripts/go/templates/.editorconfig +13 -0
  560. package/packages/shared-skills/skills/programming/scripts/go/templates/.golangci.yml +95 -0
  561. package/packages/shared-skills/skills/programming/scripts/go/templates/AGENTS.md.tmpl +24 -0
  562. package/packages/shared-skills/skills/programming/scripts/go/templates/README.md.tmpl +12 -0
  563. package/packages/shared-skills/skills/programming/scripts/go/templates/Taskfile.yml +40 -0
  564. package/packages/shared-skills/skills/programming/scripts/go/templates/ci.yml +37 -0
  565. package/packages/shared-skills/skills/programming/scripts/go/templates/config.go +24 -0
  566. package/packages/shared-skills/skills/programming/scripts/go/templates/gitignore +15 -0
  567. package/packages/shared-skills/skills/programming/scripts/go/templates/main.go.tmpl +22 -0
  568. package/packages/shared-skills/skills/programming/scripts/go/templates/run.go +15 -0
  569. package/packages/shared-skills/skills/programming/scripts/python/check-no-excuse-rules.py +687 -0
  570. package/packages/shared-skills/skills/programming/scripts/python/new-project.py +172 -0
  571. package/packages/shared-skills/skills/programming/scripts/python/new-script.py +116 -0
  572. package/packages/shared-skills/skills/programming/scripts/rust/check-no-excuse-rules.py +296 -0
  573. package/packages/shared-skills/skills/programming/scripts/rust/check-no-excuse-rules.sh +158 -0
  574. package/packages/shared-skills/skills/programming/scripts/rust/new-project.py +175 -0
  575. package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.ts +282 -0
  576. package/packages/shared-skills/skills/programming/scripts/typescript/new-project.ts +177 -0
  577. package/packages/shared-skills/skills/refactor/SKILL.md +763 -0
  578. package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +317 -0
  579. package/packages/shared-skills/skills/review-work/SKILL.md +549 -0
  580. package/packages/shared-skills/skills/start-work/SKILL.md +129 -0
  581. package/packages/shared-skills/skills/ulw-plan/SKILL.md +383 -0
  582. package/postinstall.mjs +6 -2
  583. package/dist/features/builtin-commands/templates/init-deep.d.ts +0 -1
  584. package/dist/features/builtin-skills/skills/ai-slop-remover.d.ts +0 -2
@@ -0,0 +1,156 @@
1
+ // biome-ignore-all format: keep cli-commands dispatcher under the 200 pure LOC budget.
2
+ import { readFile } from "node:fs/promises";
3
+ import { type CheckpointUlwLoopArgs, checkpointUlwLoop } from "./checkpoint.js";
4
+ import { hasFlag, parseCodexGoalJson, parseRecordEvidenceArgs, positionalText, readStdin, readValue } from "./cli-arg-parser.js";
5
+ import { blockedDecisionHandoff, normalizeCodexGoalMode, printJson, printStatus, ULW_LOOP_HELP } from "./cli-output.js";
6
+ import { parseSteeringProposal, printSteerResult } from "./cli-steering.js";
7
+ import { buildCodexGoalInstruction } from "./codex-goal-instruction.js";
8
+ import { recordEvidence } from "./evidence.js";
9
+ import { resolveUlwLoopSessionIdFromEnv, type UlwLoopScope } from "./paths.js";
10
+ import { addUlwLoopGoal, createUlwLoopPlan, startNextUlwLoop, summarizeUlwLoopPlan } from "./plan-crud.js";
11
+ import { readUlwLoopPlan } from "./plan-io.js";
12
+ import { recordFinalReviewBlockers } from "./review-blockers.js";
13
+ import { steerUlwLoop } from "./steering.js";
14
+ import type { UlwLoopItem } from "./types.js";
15
+ import { UlwLoopError } from "./types.js";
16
+
17
+ type CheckpointStatus = "complete" | "failed" | "blocked";
18
+
19
+ export async function ulwLoopCommand(argv: readonly string[]): Promise<number> {
20
+ const command = argv[0] ?? "help";
21
+ const rest = argv.slice(1);
22
+ const repoRoot = process.cwd();
23
+ const json = hasFlag(rest, "--json");
24
+ const scope = commandScope(rest);
25
+ try {
26
+ switch (command) {
27
+ case "help": case "--help": case "-h": process.stdout.write(`${ULW_LOOP_HELP}\n`); return 0;
28
+ case "create-goals": return await createGoals(repoRoot, rest, json, scope);
29
+ case "status": return await status(repoRoot, json, scope);
30
+ case "complete-goals": return await completeGoals(repoRoot, rest, json, scope);
31
+ case "checkpoint": return await checkpoint(repoRoot, rest, json, scope);
32
+ case "steer": return await steer(repoRoot, rest, json, scope);
33
+ case "add-goal": return await addGoal(repoRoot, rest, json, scope);
34
+ case "criteria": return await criteria(repoRoot, rest, json, scope);
35
+ case "record-evidence": return await captureEvidence(repoRoot, rest, json, scope);
36
+ case "record-review-blockers": return await reviewBlockers(repoRoot, rest, json, scope);
37
+ default: process.stdout.write(`${ULW_LOOP_HELP}\n`); return 1;
38
+ }
39
+ } catch (error) {
40
+ if (error instanceof UlwLoopError) process.stderr.write(`[ulw-loop] ${error.message}\n`);
41
+ else if (error instanceof Error) process.stderr.write(`[ulw-loop] unexpected: ${error.message}\n`);
42
+ else process.stderr.write("[ulw-loop] unknown error\n");
43
+ return 1;
44
+ }
45
+ }
46
+
47
+ function commandScope(argv: readonly string[]): UlwLoopScope | undefined {
48
+ const sessionId = readValue(argv, "--session-id") ?? resolveUlwLoopSessionIdFromEnv();
49
+ return sessionId === null ? undefined : { sessionId };
50
+ }
51
+
52
+ async function createGoals(repoRoot: string, argv: readonly string[], json: boolean, scope?: UlwLoopScope): Promise<number> {
53
+ const briefFile = readValue(argv, "--brief-file");
54
+ const brief = readValue(argv, "--brief") ?? (briefFile === undefined ? undefined : await readFile(briefFile, "utf8")) ?? (hasFlag(argv, "--from-stdin") ? await readStdin() : undefined) ?? positionalText(argv);
55
+ if (!brief.trim()) throw new UlwLoopError("Missing brief text. Pass --brief, --brief-file, --from-stdin, or positional text.", "ULW_LOOP_BRIEF_REQUIRED");
56
+ const plan = await createUlwLoopPlan(repoRoot, { brief, codexGoalMode: normalizeCodexGoalMode(readValue(argv, "--codex-goal-mode")), force: hasFlag(argv, "--force") }, scope);
57
+ if (json) printJson({ ok: true, plan, summary: summarizeUlwLoopPlan(plan) });
58
+ else process.stdout.write(`ulw-loop plan created: ${plan.goals.length} goal(s)\nbrief: ${plan.briefPath}\ngoals: ${plan.goalsPath}\nledger: ${plan.ledgerPath}\n`);
59
+ return 0;
60
+ }
61
+
62
+ async function status(repoRoot: string, json: boolean, scope?: UlwLoopScope): Promise<number> {
63
+ const plan = await readUlwLoopPlan(repoRoot, scope);
64
+ if (json) printJson({ ok: true, plan, summary: summarizeUlwLoopPlan(plan) });
65
+ else printStatus(plan);
66
+ return 0;
67
+ }
68
+
69
+ async function completeGoals(repoRoot: string, argv: readonly string[], json: boolean, scope?: UlwLoopScope): Promise<number> {
70
+ const result = await startNextUlwLoop(repoRoot, { retryFailed: hasFlag(argv, "--retry-failed") }, scope);
71
+ if ("done" in result) {
72
+ const handoff = blockedDecisionHandoff(result.plan);
73
+ if (json) printJson({ ok: true, done: true, blocked: handoff.length > 0, handoff, summary: summarizeUlwLoopPlan(result.plan), plan: result.plan });
74
+ else process.stdout.write(`${handoff || "ulw-loop: all goals complete"}\n`);
75
+ return 0;
76
+ }
77
+ const instruction = buildCodexGoalInstruction({ plan: result.plan, goal: result.goal });
78
+ if (json) printJson({ ok: true, resumed: result.resumed, goal: result.goal, instruction, plan: result.plan });
79
+ else process.stdout.write(`${instruction.text}\n`);
80
+ return 0;
81
+ }
82
+
83
+ async function checkpoint(repoRoot: string, argv: readonly string[], json: boolean, scope?: UlwLoopScope): Promise<number> {
84
+ const goalId = required(argv, "--goal-id");
85
+ const statusValue = checkpointStatus(required(argv, "--status"));
86
+ const evidence = required(argv, "--evidence");
87
+ const codexGoalJson = await parseCodexGoalJson(statusValue === "complete" ? required(argv, "--codex-goal-json") : readValue(argv, "--codex-goal-json"));
88
+ if (statusValue === "complete" && codexGoalJson === undefined) throw new UlwLoopError("Missing --codex-goal-json.", "ULW_LOOP_CODEX_GOAL_JSON_REQUIRED");
89
+ const qualityGateJson = readValue(argv, "--quality-gate-json");
90
+ const args: CheckpointUlwLoopArgs = {
91
+ goalId,
92
+ status: statusValue,
93
+ evidence,
94
+ ...(codexGoalJson === undefined ? {} : { codexGoalJson }),
95
+ ...(qualityGateJson === undefined ? {} : { qualityGateJson }),
96
+ };
97
+ const result = await checkpointUlwLoop(repoRoot, args, scope);
98
+ if (json) printJson({ ok: true, ...result, summary: summarizeUlwLoopPlan(result.plan) });
99
+ else process.stdout.write(`ulw-loop checkpoint: ${result.goal.id} -> ${result.goal.status}\n`);
100
+ return 0;
101
+ }
102
+
103
+ async function steer(repoRoot: string, argv: readonly string[], json: boolean, scope?: UlwLoopScope): Promise<number> {
104
+ const proposal = await parseSteeringProposal(argv);
105
+ const result = await steerUlwLoop(repoRoot, proposal, scope);
106
+ printSteerResult(result, json);
107
+ return result.accepted ? 0 : 1;
108
+ }
109
+
110
+ async function addGoal(repoRoot: string, argv: readonly string[], json: boolean, scope?: UlwLoopScope): Promise<number> {
111
+ const result = await addUlwLoopGoal(repoRoot, { title: required(argv, "--title"), objective: required(argv, "--objective") }, scope);
112
+ if (json) printJson({ ok: true, plan: result.plan, goal: result.goal, summary: summarizeUlwLoopPlan(result.plan) });
113
+ else { process.stdout.write(`ulw-loop added goal: ${result.goal.id}\n`); printStatus(result.plan); }
114
+ return 0;
115
+ }
116
+
117
+ async function criteria(repoRoot: string, argv: readonly string[], json: boolean, scope?: UlwLoopScope): Promise<number> {
118
+ const goalId = required(argv, "--goal-id");
119
+ const goal = findGoal(await readUlwLoopPlan(repoRoot, scope), goalId);
120
+ if (json) printJson({ ok: true, goalId: goal.id, criteria: goal.successCriteria });
121
+ else process.stdout.write(`criteria for ${goal.id}:\n${goal.successCriteria.map((c) => `- ${c.id} [${c.status}] (${c.userModel}) ${c.scenario} evidence: ${c.capturedEvidence ?? "pending"}`).join("\n")}\n`);
122
+ return 0;
123
+ }
124
+
125
+ async function captureEvidence(repoRoot: string, argv: readonly string[], json: boolean, scope?: UlwLoopScope): Promise<number> {
126
+ const result = await recordEvidence(repoRoot, parseRecordEvidenceArgs(argv), scope);
127
+ if (json) printJson({ ok: true, ...result, summary: summarizeUlwLoopPlan(result.plan) });
128
+ else process.stdout.write(`ulw-loop evidence recorded: ${result.goal.id}/${result.criterion.id} -> ${result.criterion.status}\n`);
129
+ return 0;
130
+ }
131
+
132
+ async function reviewBlockers(repoRoot: string, argv: readonly string[], json: boolean, scope?: UlwLoopScope): Promise<number> {
133
+ const codexGoalJson = await parseCodexGoalJson(required(argv, "--codex-goal-json"));
134
+ if (codexGoalJson === undefined) throw new UlwLoopError("Missing --codex-goal-json.", "ULW_LOOP_CODEX_GOAL_JSON_REQUIRED");
135
+ const result = await recordFinalReviewBlockers(repoRoot, { goalId: required(argv, "--goal-id"), title: required(argv, "--title"), objective: required(argv, "--objective"), evidence: required(argv, "--evidence"), codexGoalJson }, scope);
136
+ if (json) printJson({ ok: true, plan: result.plan, blockedGoal: result.blockedGoal, goal: result.newGoal, ledgerEntries: result.ledgerEntries, summary: summarizeUlwLoopPlan(result.plan) });
137
+ else process.stdout.write(`ulw-loop final review blockers recorded: ${result.blockedGoal.id} -> review_blocked; added ${result.newGoal.id}\n`);
138
+ return 0;
139
+ }
140
+
141
+ function required(argv: readonly string[], flag: string): string {
142
+ const value = readValue(argv, flag)?.trim();
143
+ if (value) return value;
144
+ throw new UlwLoopError(`Missing ${flag}.`, "ULW_LOOP_ARGUMENT_MISSING", { details: { flag } });
145
+ }
146
+
147
+ function checkpointStatus(value: string): CheckpointStatus {
148
+ if (value === "complete" || value === "failed" || value === "blocked") return value;
149
+ throw new UlwLoopError("Missing or invalid --status; expected complete, failed, or blocked.", "ULW_LOOP_STATUS_INVALID", { details: { status: value } });
150
+ }
151
+
152
+ function findGoal(plan: { readonly goals: readonly UlwLoopItem[] }, goalId: string): UlwLoopItem {
153
+ const goal = plan.goals.find((candidate) => candidate.id === goalId);
154
+ if (goal !== undefined) return goal;
155
+ throw new UlwLoopError(`Unknown ulw-loop id: ${goalId}.`, "ULW_LOOP_GOAL_NOT_FOUND", { details: { goalId } });
156
+ }
@@ -0,0 +1,63 @@
1
+ import type { UlwLoopCodexGoalMode, UlwLoopItem, UlwLoopPlan } from "./types.js";
2
+ import { UlwLoopError } from "./types.js";
3
+
4
+ export const ULW_LOOP_HELP = `Usage:
5
+ omo ulw-loop create-goals --brief "..." [--brief-file <path>] [--from-stdin] [--codex-goal-mode aggregate|per_story] [--force] [--json]
6
+ omo ulw-loop status [--json]
7
+ omo ulw-loop complete-goals [--retry-failed] [--json]
8
+ omo ulw-loop criteria --goal-id <id> [--json]
9
+ omo ulw-loop record-evidence --goal-id <id> --criterion-id <id> --status pass|fail|blocked --evidence "..." [--notes "..."] [--json]
10
+ omo ulw-loop checkpoint --goal-id <id> --status complete|failed|blocked --evidence "..." --codex-goal-json <...> [--quality-gate-json <...>] [--json]
11
+ omo ulw-loop steer --kind <kind> ... --evidence "..." --rationale "..." [--json]
12
+ omo ulw-loop add-goal --title "..." --objective "..." [--json]
13
+ omo ulw-loop record-review-blockers --goal-id <id> --title "..." --objective "..." --evidence "..." --codex-goal-json <...> [--json]
14
+
15
+ All subcommands accept [--session-id <id>] to isolate state under .omo/ulw-loop/<id>/; without it, Codex session env is used when present.`;
16
+
17
+ type CriteriaCounts = { readonly pass: number; readonly total: number };
18
+
19
+ export function printJson(value: unknown): void {
20
+ process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
21
+ }
22
+
23
+ function criteriaCounts(goal: UlwLoopItem): CriteriaCounts {
24
+ let pass = 0;
25
+ for (const criterion of goal.successCriteria) if (criterion.status === "pass") pass += 1;
26
+ return { pass, total: goal.successCriteria.length };
27
+ }
28
+
29
+ export function printStatus(plan: UlwLoopPlan): void {
30
+ let totalCriteria = 0;
31
+ let passCriteria = 0;
32
+ const lines = ["ulw-loop status", "", "goals:"];
33
+ for (const goal of plan.goals) {
34
+ const counts = criteriaCounts(goal);
35
+ totalCriteria += counts.total;
36
+ passCriteria += counts.pass;
37
+ const marker = goal.id === plan.activeGoalId ? "*" : "-";
38
+ lines.push(`${marker} ${goal.id} [${goal.status}] ${goal.title} (criteria: ${counts.pass}/${counts.total})`);
39
+ }
40
+ lines.push("", "summary:", `total goals: ${plan.goals.length}`, `criteria: ${passCriteria}/${totalCriteria} pass`);
41
+ process.stdout.write(`${lines.join("\n")}\n`);
42
+ }
43
+
44
+ export function blockedDecisionHandoff(plan: UlwLoopPlan): string {
45
+ const blocked = plan.goals.find((goal) => goal.status === "needs_user_decision" && goal.nonRetriable);
46
+ if (blocked === undefined) return "";
47
+ return [
48
+ "ulw-loop: blocked on repeated external authorization; no retryable failed goals remain.",
49
+ `Goal: ${blocked.id} - ${blocked.title}`,
50
+ `Required external decision: ${blocked.requiredExternalDecision ?? "provide the missing authorization or choose a different unblock path"}.`,
51
+ "Do not run complete-goals --retry-failed again until external state changes or the user authorizes an unblock path.",
52
+ ].join("\n");
53
+ }
54
+
55
+ export function normalizeCodexGoalMode(value: string | undefined): UlwLoopCodexGoalMode {
56
+ if (value === undefined) return "aggregate";
57
+ if (value === "aggregate" || value === "per_story") return value;
58
+ throw new UlwLoopError(
59
+ "Invalid --codex-goal-mode; expected aggregate or per_story.",
60
+ "ULW_LOOP_CODEX_GOAL_MODE_INVALID",
61
+ { details: { value } },
62
+ );
63
+ }
@@ -0,0 +1,94 @@
1
+ // biome-ignore-all format: keep this module under the mandated pure LOC budget.
2
+ import { parseGoalArg, readJsonInput, readValue } from "./cli-arg-parser.js";
3
+ import { printJson, printStatus } from "./cli-output.js";
4
+ import type { SteerUlwLoopResult, UlwLoopSteeringChildGoal, UlwLoopSteeringMutationKind, UlwLoopSteeringProposal, UlwLoopSteeringSource, UlwLoopSuccessCriterionUserModel } from "./types.js";
5
+ import { ULW_LOOP_STEERING_MUTATION_KINDS, ULW_LOOP_SUCCESS_CRITERION_USER_MODELS, UlwLoopError } from "./types.js";
6
+
7
+ const SOURCES = ["user_prompt_submit", "finding", "cli"] as const satisfies readonly UlwLoopSteeringSource[];
8
+
9
+ export type CliSteeringProposal = UlwLoopSteeringProposal & { readonly goalId?: string; readonly scenario?: string; readonly expectedEvidence?: string; readonly userModel?: UlwLoopSuccessCriterionUserModel };
10
+
11
+ function isKind(value: string | undefined): value is UlwLoopSteeringMutationKind { return value !== undefined && ULW_LOOP_STEERING_MUTATION_KINDS.some((kind) => kind === value); }
12
+ function isSource(value: string | undefined): value is UlwLoopSteeringSource { return value !== undefined && SOURCES.some((source) => source === value); }
13
+ function isModel(value: string): value is UlwLoopSuccessCriterionUserModel { return ULW_LOOP_SUCCESS_CRITERION_USER_MODELS.some((model) => model === value); }
14
+ function fail(message: string, code: string, details: Record<string, unknown>): never { throw new UlwLoopError(message, code, { details }); }
15
+ function text(value: string | undefined, field: string): string | undefined { if (value === undefined) return undefined; const trimmed = value.trim(); if (trimmed.length > 0) return trimmed; return fail(`Empty ${field}.`, "ULW_LOOP_STEERING_FIELD_EMPTY", { field }); }
16
+ function required(argv: readonly string[], flag: string): string { const value = text(readValue(argv, flag), flag); return value ?? fail(`Missing ${flag}.`, "ULW_LOOP_STEERING_FIELD_REQUIRED", { flag }); }
17
+ function requiredGoal(argv: readonly string[]): string { const value = text(parseGoalArg(argv), "--goal-id"); return value ?? fail("Missing --goal-id.", "ULW_LOOP_GOAL_ID_REQUIRED", { flag: "--goal-id" }); }
18
+ function readObject(value: object, key: string): unknown { return Object.entries(value).find(([name]) => name === key)?.[1]; }
19
+ function isPlain(value: unknown): value is object { return typeof value === "object" && value !== null && !Array.isArray(value); }
20
+ function objectText(value: object, key: string): string | undefined { const candidate = readObject(value, key); return typeof candidate === "string" ? candidate : undefined; }
21
+
22
+ export function parseSteeringKind(argv: readonly string[]): UlwLoopSteeringMutationKind {
23
+ const value = readValue(argv, "--kind");
24
+ if (isKind(value)) return value;
25
+ return value === undefined ? fail("Missing --kind.", "ULW_LOOP_STEERING_KIND_REQUIRED", { flag: "--kind" }) : fail(`Invalid --kind: ${value}.`, "ULW_LOOP_STEERING_KIND_INVALID", { value, expected: ULW_LOOP_STEERING_MUTATION_KINDS });
26
+ }
27
+
28
+ export function parseSteeringSource(argv: readonly string[]): UlwLoopSteeringSource {
29
+ const value = readValue(argv, "--source");
30
+ if (value === undefined) return "cli";
31
+ return isSource(value) ? value : fail(`Invalid --source: ${value}.`, "ULW_LOOP_STEERING_SOURCE_INVALID", { value, expected: SOURCES });
32
+ }
33
+
34
+ function child(value: unknown): UlwLoopSteeringChildGoal | null {
35
+ if (!isPlain(value)) return null;
36
+ const title = text(objectText(value, "title"), "title"); const objective = text(objectText(value, "objective"), "objective");
37
+ if (title === undefined || objective === undefined) return null;
38
+ return { title, objective };
39
+ }
40
+
41
+ async function children(argv: readonly string[], flag: string, needed: boolean): Promise<UlwLoopSteeringChildGoal[]> {
42
+ const input = needed ? required(argv, flag) : text(readValue(argv, flag), flag);
43
+ if (input === undefined) return [];
44
+ const raw = await readJsonInput(input);
45
+ if (!Array.isArray(raw)) return fail(`${flag} must be a JSON array.`, "ULW_LOOP_STEERING_JSON_ARRAY_REQUIRED", { flag });
46
+ const parsed: UlwLoopSteeringChildGoal[] = [];
47
+ for (const item of raw) { const next = child(item); if (next === null) return fail(`${flag} entries require title/objective.`, "ULW_LOOP_STEERING_CHILD_INVALID", { flag }); parsed.push(next); }
48
+ return parsed;
49
+ }
50
+
51
+ async function stringArray(argv: readonly string[], flag: string): Promise<string[]> {
52
+ const raw = await readJsonInput(required(argv, flag));
53
+ if (!Array.isArray(raw)) return fail(`${flag} must be a JSON array.`, "ULW_LOOP_STEERING_JSON_ARRAY_REQUIRED", { flag });
54
+ const values: string[] = [];
55
+ for (const item of raw) { if (typeof item !== "string") return fail(`${flag} entries must be strings.`, "ULW_LOOP_STEERING_STRING_ARRAY_REQUIRED", { flag }); values.push(text(item, flag) ?? ""); }
56
+ return values;
57
+ }
58
+
59
+ function model(value: string | undefined): UlwLoopSuccessCriterionUserModel | undefined { const trimmed = text(value, "--user-model"); if (trimmed === undefined) return undefined; return isModel(trimmed) ? trimmed : fail(`Invalid --user-model: ${trimmed}.`, "ULW_LOOP_STEERING_USER_MODEL_INVALID", { value: trimmed, expected: ULW_LOOP_SUCCESS_CRITERION_USER_MODELS }); }
60
+ function neverKind(kind: never): never { return fail(`Unsupported steering kind: ${String(kind)}.`, "ULW_LOOP_STEERING_KIND_UNSUPPORTED", { kind }); }
61
+
62
+ export async function parseSteeringProposal(argv: readonly string[]): Promise<CliSteeringProposal> {
63
+ const kind = parseSteeringKind(argv); const source = parseSteeringSource(argv); const base = { kind, source, evidence: required(argv, "--evidence"), rationale: required(argv, "--rationale") };
64
+ switch (kind) {
65
+ case "add_subgoal": return normalizeSteeringProposal({ ...base, title: required(argv, "--title"), objective: required(argv, "--objective") });
66
+ case "split_subgoal": { const goalId = requiredGoal(argv); return normalizeSteeringProposal({ ...base, goalId, targetGoalId: goalId, childGoals: await children(argv, "--children", true) }); }
67
+ case "reorder_pending": return normalizeSteeringProposal({ ...base, pendingOrder: await stringArray(argv, "--order") });
68
+ case "revise_pending_wording": { const goalId = requiredGoal(argv); const revisedTitle = readValue(argv, "--title"); const revisedObjective = readValue(argv, "--objective"); if (revisedTitle === undefined && revisedObjective === undefined) return fail("revise_pending_wording requires --title or --objective.", "ULW_LOOP_STEERING_UPDATE_REQUIRED", { kind }); return normalizeSteeringProposal({ ...base, goalId, targetGoalId: goalId, ...(revisedTitle === undefined ? {} : { revisedTitle }), ...(revisedObjective === undefined ? {} : { revisedObjective }) }); }
69
+ case "revise_criterion": { const goalId = requiredGoal(argv); const criterionId = required(argv, "--criterion-id"); const scenario = readValue(argv, "--scenario"); const expectedEvidence = readValue(argv, "--expected-evidence"); const userModel = model(readValue(argv, "--user-model")); if (scenario === undefined && expectedEvidence === undefined && userModel === undefined) return fail("revise_criterion requires scenario, expected-evidence, or user-model.", "ULW_LOOP_STEERING_UPDATE_REQUIRED", { kind }); return normalizeSteeringProposal({ ...base, goalId, targetGoalId: goalId, criterionId, ...(scenario === undefined ? {} : { scenario }), ...(expectedEvidence === undefined ? {} : { expectedEvidence }), ...(userModel === undefined ? {} : { userModel }) }); }
70
+ case "annotate_ledger": return normalizeSteeringProposal(base);
71
+ case "mark_blocked_superseded": { const goalId = requiredGoal(argv); const childGoals = await children(argv, "--replacements", false); return normalizeSteeringProposal({ ...base, goalId, targetGoalId: goalId, ...(childGoals.length === 0 ? {} : { childGoals }) }); }
72
+ default: return neverKind(kind);
73
+ }
74
+ }
75
+
76
+ function normalizedChildren(values: readonly UlwLoopSteeringChildGoal[] | undefined): UlwLoopSteeringChildGoal[] | undefined { if (values === undefined) return undefined; return values.map((item) => ({ title: text(item.title, "child.title") ?? "", objective: text(item.objective, "child.objective") ?? "" })); }
77
+ function normalizedStrings(values: readonly string[] | undefined, field: string): string[] | undefined { if (values === undefined) return undefined; return values.map((value) => text(value, field) ?? ""); }
78
+
79
+ export function normalizeSteeringProposal(proposal: CliSteeringProposal): CliSteeringProposal {
80
+ const evidence = text(proposal.evidence, "evidence") ?? ""; const rationale = text(proposal.rationale, "rationale") ?? ""; const goalId = text(proposal.goalId, "goalId"); const targetGoalId = text(proposal.targetGoalId, "targetGoalId"); const targetGoalIds = normalizedStrings(proposal.targetGoalIds, "targetGoalIds");
81
+ const criterionId = text(proposal.criterionId, "criterionId"); const title = text(proposal.title, "title"); const objective = text(proposal.objective, "objective"); const revisedTitle = text(proposal.revisedTitle, "revisedTitle"); const revisedObjective = text(proposal.revisedObjective, "revisedObjective");
82
+ const blockedReason = text(proposal.blockedReason, "blockedReason"); const directiveText = text(proposal.directiveText, "directiveText"); const promptSignature = text(proposal.promptSignature, "promptSignature"); const idempotencyKey = text(proposal.idempotencyKey, "idempotencyKey");
83
+ const scenario = text(proposal.scenario, "scenario"); const expectedEvidence = text(proposal.expectedEvidence, "expectedEvidence"); const childGoals = normalizedChildren(proposal.childGoals); const pendingOrder = normalizedStrings(proposal.pendingOrder, "pendingOrder");
84
+ return { kind: proposal.kind, source: proposal.source, evidence, rationale, ...(goalId === undefined ? {} : { goalId }), ...(targetGoalId === undefined ? {} : { targetGoalId }), ...(targetGoalIds === undefined ? {} : { targetGoalIds }), ...(criterionId === undefined ? {} : { criterionId }), ...(title === undefined ? {} : { title }), ...(objective === undefined ? {} : { objective }), ...(childGoals === undefined ? {} : { childGoals }), ...(revisedTitle === undefined ? {} : { revisedTitle }), ...(revisedObjective === undefined ? {} : { revisedObjective }), ...(pendingOrder === undefined ? {} : { pendingOrder }), ...(blockedReason === undefined ? {} : { blockedReason }), ...(proposal.after === undefined ? {} : { after: proposal.after }), ...(directiveText === undefined ? {} : { directiveText }), ...(promptSignature === undefined ? {} : { promptSignature }), ...(idempotencyKey === undefined ? {} : { idempotencyKey }), ...(proposal.now === undefined ? {} : { now: proposal.now }), ...(scenario === undefined ? {} : { scenario }), ...(expectedEvidence === undefined ? {} : { expectedEvidence }), ...(proposal.userModel === undefined ? {} : { userModel: proposal.userModel }) };
85
+ }
86
+
87
+ export function printSteerResult(result: SteerUlwLoopResult, json: boolean): void {
88
+ if (json) { printJson({ ok: result.accepted, accepted: result.accepted, rejectedReasons: result.rejectedReasons, deduped: result.deduped, audit: result.audit, plan: result.plan }); return; }
89
+ const outcome = result.deduped ? "deduped" : result.accepted ? "accepted" : "rejected";
90
+ process.stdout.write(`ulw-loop steer: ${outcome} ${result.audit.kind}\n`);
91
+ if (result.rejectedReasons.length > 0) process.stdout.write(`rejected: ${result.rejectedReasons.join("; ")}\n`);
92
+ if (result.audit.idempotencyKey !== undefined) process.stdout.write(`idempotency-key: ${result.audit.idempotencyKey}\n`);
93
+ printStatus(result.plan);
94
+ }
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ import { ulwLoopCommand } from "./cli-commands.js";
3
+ import { runPreToolUseGoalBudgetGuardCli, runUlwLoopHookCli } from "./codex-hook.js";
4
+
5
+ const TOP_LEVEL_HELP =
6
+ "Usage:\n omo ulw-loop <subcommand> [args]\n omo hook user-prompt-submit (Codex UserPromptSubmit hook)\n omo help | --help | -h (this message)\n\nRun `omo ulw-loop help` for ulw-loop subcommands.\n";
7
+
8
+ async function main(): Promise<number> {
9
+ const argv = process.argv.slice(2);
10
+ const command = argv[0];
11
+ if (command === undefined || command === "help" || command === "--help" || command === "-h") {
12
+ process.stdout.write(TOP_LEVEL_HELP);
13
+ return 0;
14
+ }
15
+ if (command === "ulw-loop") return ulwLoopCommand(argv.slice(1));
16
+ if (command === "hook") {
17
+ const sub = argv[1];
18
+ if (sub === "user-prompt-submit") {
19
+ await runUlwLoopHookCli(process.stdin, process.stdout);
20
+ return 0;
21
+ }
22
+ if (sub === "pre-tool-use") {
23
+ await runPreToolUseGoalBudgetGuardCli(process.stdin, process.stdout);
24
+ return 0;
25
+ }
26
+ process.stderr.write(`[omo] unknown hook subcommand: ${sub ?? "(none)"}\n`);
27
+ return 1;
28
+ }
29
+ process.stderr.write(`[omo] unknown command: ${command}\n${TOP_LEVEL_HELP}`);
30
+ return 1;
31
+ }
32
+
33
+ main()
34
+ .then((code) => {
35
+ process.exit(code);
36
+ })
37
+ .catch((error: unknown) => {
38
+ process.stderr.write(`[omo] ${error instanceof Error ? error.message : String(error)}\n`);
39
+ process.exit(1);
40
+ });
@@ -0,0 +1,129 @@
1
+ import { codexGoalMode, expectedCodexObjective, isFinalRunCompletionCandidate } from "./goal-status.js";
2
+ import type { UlwLoopCodexGoalMode, UlwLoopItem, UlwLoopPlan, UlwLoopSuccessCriterion } from "./types.js";
3
+
4
+ export interface CodexCreateGoalPayload {
5
+ readonly objective: string;
6
+ readonly status: "active";
7
+ }
8
+
9
+ export interface UlwLoopGoalInstruction {
10
+ readonly text: string;
11
+ readonly json: CodexCreateGoalPayload;
12
+ }
13
+
14
+ export function buildCodexGoalInstruction(args: {
15
+ readonly plan: UlwLoopPlan;
16
+ readonly goal: UlwLoopItem;
17
+ readonly isFinal?: boolean;
18
+ }): UlwLoopGoalInstruction {
19
+ const mode = codexGoalMode(args.plan);
20
+ const createGoal = buildCreateGoalPayload(args.plan, args.goal);
21
+ const isFinal = args.isFinal ?? isFinalRunCompletionCandidate(args.plan, args.goal);
22
+ return { text: buildText(mode, args.plan, args.goal, createGoal, isFinal), json: createGoal };
23
+ }
24
+
25
+ function buildCreateGoalPayload(plan: UlwLoopPlan, goal: UlwLoopItem): CodexCreateGoalPayload {
26
+ return { objective: expectedCodexObjective(plan, goal), status: "active" };
27
+ }
28
+
29
+ function buildText(
30
+ mode: UlwLoopCodexGoalMode,
31
+ plan: UlwLoopPlan,
32
+ goal: UlwLoopItem,
33
+ createGoal: CodexCreateGoalPayload,
34
+ isFinal: boolean,
35
+ ): string {
36
+ return joinLines([
37
+ mode === "aggregate" ? "UlwLoop aggregate-goal handoff" : "UlwLoop active-goal handoff",
38
+ `Mode: ${mode}`,
39
+ `Plan: ${plan.goalsPath}`,
40
+ `Ledger: ${plan.ledgerPath}`,
41
+ `Goal: ${goal.id} — ${goal.title}`,
42
+ "",
43
+ ...activeGoalLines(goal),
44
+ "",
45
+ ...successCriteriaLines(goal.successCriteria),
46
+ "",
47
+ "Codex goal integration constraints:",
48
+ "- Use the create_goal payload exactly as rendered: objective and status only.",
49
+ "- Goals are unlimited. Do not add numeric limits.",
50
+ ...modeConstraintLines(mode, isFinal),
51
+ finalSection(plan, goal, isFinal, mode === "aggregate"),
52
+ ...checkpointLines(plan, mode),
53
+ "",
54
+ "create_goal payload:",
55
+ JSON.stringify(createGoal, null, 2),
56
+ ]);
57
+ }
58
+
59
+ function modeConstraintLines(mode: UlwLoopCodexGoalMode, isFinal: boolean): readonly string[] {
60
+ if (mode === "per_story") {
61
+ return [
62
+ "- First call get_goal. If no active goal exists, call create_goal with the payload below.",
63
+ "- If a different active Codex goal exists, finish/checkpoint that goal before starting this ulw-loop.",
64
+ "- Work only this goal until its completion audit passes.",
65
+ ];
66
+ }
67
+ return [
68
+ "- Codex goal = the whole omo ulw-loop run; OMO G001/G002/etc. = ledger stories.",
69
+ "- First call get_goal. If no active goal exists, call create_goal with the aggregate payload below.",
70
+ "- If get_goal reports the same aggregate objective as active, continue this OMO story without creating a new Codex goal.",
71
+ "- If a different active or incomplete Codex goal exists, finish/checkpoint that goal before starting this ulw-loop.",
72
+ isFinal
73
+ ? "- This is the final story; update_goal is allowed only after the mandatory quality gate passes."
74
+ : "- This is not the final story: do not call update_goal yet; the aggregate Codex goal must remain active while later OMO stories remain.",
75
+ ];
76
+ }
77
+
78
+ function checkpointLines(plan: UlwLoopPlan, mode: UlwLoopCodexGoalMode): readonly string[] {
79
+ const failureLine = `- If blocked or failed, checkpoint with --status failed and the failure evidence; rerun complete-goals${sessionOption(plan)} --retry-failed to resume.`;
80
+ if (mode === "per_story") return [failureLine];
81
+ return [
82
+ "- Checkpoint this OMO story with a fresh get_goal snapshot whose objective matches the aggregate payload.",
83
+ failureLine,
84
+ ];
85
+ }
86
+
87
+ function activeGoalLines(goal: UlwLoopItem): readonly string[] {
88
+ return ["Active goal:", `- id: ${goal.id}`, `- title: ${goal.title}`, `- objective: ${goal.objective}`];
89
+ }
90
+
91
+ function successCriteriaLines(criteria: readonly UlwLoopSuccessCriterion[]): readonly string[] {
92
+ if (criteria.length === 0) return ["Success criteria:", "- No success criteria recorded for this goal."];
93
+ return ["Success criteria:", ...criteria.map(formatCriterionLine)];
94
+ }
95
+
96
+ function formatCriterionLine(criterion: UlwLoopSuccessCriterion): string {
97
+ const remainingWork = criterion.status === "pending" ? " remaining work:" : "";
98
+ return `-${remainingWork} [${criterion.id}] (${criterion.userModel}) ${criterion.scenario} — expect: ${criterion.expectedEvidence} — status: ${criterion.status}`;
99
+ }
100
+
101
+ function finalSection(plan: UlwLoopPlan, goal: UlwLoopItem, isFinal: boolean, aggregate: boolean): string {
102
+ if (!isFinal)
103
+ return "- This is not the final ulw-loop story; do not run the final ai-slop-cleaner/$code-review gate yet.";
104
+ const option = sessionOption(plan);
105
+ const blockerCommand = `omo ulw-loop record-review-blockers${option} --goal-id ${goal.id} --title "Resolve final code-review blockers" --objective "<blocker-resolution objective>" --evidence "<review findings>" --codex-goal-json "<active get_goal JSON or path>"`;
106
+ const checkpointCommand = `omo ulw-loop checkpoint${option} --goal-id ${goal.id} --status complete --evidence "<tests/files/PR evidence>" --codex-goal-json "<fresh complete get_goal JSON or path>" --quality-gate-json "<quality gate JSON or path>"`;
107
+ return joinLines([
108
+ "Final story — run mandatory quality gate before update_goal:",
109
+ "- Run ai-slop-cleaner on changed files even when it is a no-op, rerun verification, then run $code-review.",
110
+ "- If final $code-review is not APPROVE with architect status CLEAR, do not call update_goal. Record blocker work first:",
111
+ ` ${blockerCommand}`,
112
+ aggregate
113
+ ? '- If final $code-review is clean, call update_goal({status: "complete"}), call get_goal again, then checkpoint the aggregate story:'
114
+ : '- If final $code-review is clean, call update_goal({status: "complete"}), call get_goal again, then checkpoint:',
115
+ ` ${checkpointCommand}`,
116
+ ]);
117
+ }
118
+
119
+ function sessionOption(plan: UlwLoopPlan): string {
120
+ const prefix = ".omo/ulw-loop/";
121
+ const suffix = "/goals.json";
122
+ if (!plan.goalsPath.startsWith(prefix) || !plan.goalsPath.endsWith(suffix)) return "";
123
+ const sessionId = plan.goalsPath.slice(prefix.length, -suffix.length);
124
+ return sessionId.length === 0 ? "" : ` --session-id ${sessionId}`;
125
+ }
126
+
127
+ function joinLines(lines: readonly string[]): string {
128
+ return lines.join("\n");
129
+ }
@@ -0,0 +1,139 @@
1
+ import { existsSync } from "node:fs";
2
+ import { readFile } from "node:fs/promises";
3
+ import { resolve } from "node:path";
4
+
5
+ export type CodexGoalSnapshotStatus = "active" | "complete" | "cancelled" | "failed" | "unknown";
6
+
7
+ export interface CodexGoalSnapshot {
8
+ available: boolean;
9
+ objective?: string;
10
+ status?: CodexGoalSnapshotStatus;
11
+ raw: unknown;
12
+ }
13
+
14
+ export interface CodexGoalReconciliation {
15
+ ok: boolean;
16
+ snapshot: CodexGoalSnapshot;
17
+ warnings: string[];
18
+ errors: string[];
19
+ }
20
+
21
+ export interface ReconcileCodexGoalOptions {
22
+ expectedObjective: string;
23
+ acceptedObjectives?: readonly string[];
24
+ allowedStatuses?: readonly CodexGoalSnapshotStatus[];
25
+ requireSnapshot?: boolean;
26
+ requireComplete?: boolean;
27
+ }
28
+
29
+ export class CodexGoalSnapshotError extends Error {}
30
+ function safeObject(value: unknown): Record<string, unknown> {
31
+ return value && typeof value === "object" && !Array.isArray(value) ? (value as Record<string, unknown>) : {};
32
+ }
33
+
34
+ function safeString(value: unknown): string {
35
+ return typeof value === "string" ? value.trim() : "";
36
+ }
37
+
38
+ function normalizeStatus(value: unknown): CodexGoalSnapshotStatus {
39
+ const status = safeString(value).toLowerCase();
40
+ if (status === "complete" || status === "completed" || status === "done") return "complete";
41
+ if (status === "cancelled" || status === "canceled") return "cancelled";
42
+ if (status === "failed" || status === "failure") return "failed";
43
+ if (status === "active" || status === "in_progress" || status === "pending" || status === "running") return "active";
44
+ return "unknown";
45
+ }
46
+
47
+ function normalizeObjective(value: string): string {
48
+ return value.replace(/\s+/g, " ").trim();
49
+ }
50
+
51
+ export function parseCodexGoalSnapshot(value: unknown): CodexGoalSnapshot {
52
+ const root = safeObject(value);
53
+ const goalValue = Object.hasOwn(root, "goal") ? root["goal"] : value;
54
+ if (goalValue === null || goalValue === undefined || goalValue === false) {
55
+ return { available: false, raw: value };
56
+ }
57
+
58
+ const goal = safeObject(goalValue);
59
+ const objective = safeString(goal["objective"] ?? goal["goal"] ?? goal["description"] ?? root["objective"]);
60
+ const status = normalizeStatus(goal["status"] ?? root["status"]);
61
+
62
+ return {
63
+ available: Boolean(objective || status !== "unknown"),
64
+ ...(objective ? { objective } : {}),
65
+ status,
66
+ raw: value,
67
+ };
68
+ }
69
+
70
+ export async function readCodexGoalSnapshotInput(
71
+ raw: string | undefined,
72
+ cwd = process.cwd(),
73
+ ): Promise<CodexGoalSnapshot | null> {
74
+ if (!raw?.trim()) return null;
75
+ const trimmed = raw.trim();
76
+ try {
77
+ return parseCodexGoalSnapshot(JSON.parse(trimmed));
78
+ } catch {
79
+ const path = resolve(cwd, trimmed);
80
+ if (!existsSync(path)) {
81
+ throw new CodexGoalSnapshotError(`Codex goal snapshot is neither valid JSON nor a readable path: ${trimmed}`);
82
+ }
83
+ try {
84
+ return parseCodexGoalSnapshot(JSON.parse(await readFile(path, "utf-8")));
85
+ } catch (error) {
86
+ throw new CodexGoalSnapshotError(
87
+ `Codex goal snapshot path does not contain valid JSON: ${trimmed}${error instanceof Error ? ` (${error.message})` : ""}`,
88
+ );
89
+ }
90
+ }
91
+ }
92
+
93
+ export function reconcileCodexGoalSnapshot(
94
+ snapshot: CodexGoalSnapshot | null | undefined,
95
+ options: ReconcileCodexGoalOptions,
96
+ ): CodexGoalReconciliation {
97
+ const effectiveSnapshot = snapshot ?? { available: false, raw: null };
98
+ const errors: string[] = [];
99
+ const warnings: string[] = [];
100
+
101
+ if (!effectiveSnapshot.available) {
102
+ const message =
103
+ "Codex goal snapshot is absent or reports no active goal; call get_goal and pass its JSON with --codex-goal-json.";
104
+ if (options.requireSnapshot) errors.push(message);
105
+ else warnings.push(message);
106
+ return { ok: errors.length === 0, snapshot: effectiveSnapshot, warnings, errors };
107
+ }
108
+
109
+ const expected = normalizeObjective(options.expectedObjective);
110
+ const accepted = new Set(
111
+ [expected, ...(options.acceptedObjectives ?? []).map((objective) => normalizeObjective(objective))].filter(
112
+ Boolean,
113
+ ),
114
+ );
115
+ const actual = normalizeObjective(effectiveSnapshot.objective ?? "");
116
+ if (!actual) {
117
+ errors.push("Codex goal snapshot is missing objective text.");
118
+ } else if (!accepted.has(actual)) {
119
+ errors.push(`Codex goal objective mismatch: expected "${expected}", got "${actual}".`);
120
+ }
121
+
122
+ const allowed = options.allowedStatuses ?? (options.requireComplete ? ["complete"] : ["active", "complete"]);
123
+ const actualStatus = effectiveSnapshot.status ?? "unknown";
124
+ if (!allowed.includes(actualStatus)) {
125
+ errors.push(`Codex goal status mismatch: expected ${allowed.join(" or ")}, got ${actualStatus}.`);
126
+ }
127
+ if (options.requireComplete && actualStatus !== "complete") {
128
+ errors.push(
129
+ 'Codex goal is not complete; call update_goal({status: "complete"}) only after the objective is actually complete, then pass the fresh get_goal JSON.',
130
+ );
131
+ }
132
+
133
+ return { ok: errors.length === 0, snapshot: effectiveSnapshot, warnings, errors };
134
+ }
135
+
136
+ export function formatCodexGoalReconciliation(reconciliation: CodexGoalReconciliation): string {
137
+ const parts = [...reconciliation.errors, ...reconciliation.warnings];
138
+ return parts.join(" ");
139
+ }