oh-my-opencode 4.8.1 → 4.9.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 (509) hide show
  1. package/dist/agents/prometheus/system-prompt.d.ts +1 -1
  2. package/dist/agents/sisyphus/claude-fable-5.d.ts +19 -0
  3. package/dist/agents/sisyphus/claude-opus-4-7.d.ts +3 -1
  4. package/dist/agents/sisyphus/claude-opus-4-8.d.ts +19 -0
  5. package/dist/agents/sisyphus/index.d.ts +4 -0
  6. package/dist/agents/types.d.ts +2 -2
  7. package/dist/cli/doctor/checks/codex.d.ts +1 -0
  8. package/dist/cli/doctor/checks/dependencies.d.ts +2 -2
  9. package/dist/cli/doctor/checks/tools-gh.d.ts +8 -1
  10. package/dist/cli/doctor/index.d.ts +1 -0
  11. package/dist/cli/doctor/types.d.ts +2 -0
  12. package/dist/cli/index.js +1908 -787
  13. package/dist/cli/install-codex/codex-config-permissions.d.ts +1 -1
  14. package/dist/cli/install-codex/codex-config-plugins.d.ts +1 -0
  15. package/dist/cli/install-codex/codex-config-toml.d.ts +1 -0
  16. package/dist/cli/install-codex/codex-installer-bin-dir.d.ts +8 -0
  17. package/dist/cli/install-codex/install-codex.d.ts +1 -8
  18. package/dist/cli/install-codex/lsp-daemon-reaper.d.ts +5 -0
  19. package/dist/cli/sparkshell-condense.d.ts +10 -0
  20. package/dist/cli/sparkshell-parse.d.ts +3 -0
  21. package/dist/cli/sparkshell-session-context.d.ts +20 -0
  22. package/dist/cli/sparkshell-spark.d.ts +23 -0
  23. package/dist/cli/sparkshell.d.ts +8 -1
  24. package/dist/cli-node/index.js +92564 -0
  25. package/dist/config/schema/agent-names.d.ts +2 -0
  26. package/dist/config/schema/hooks.d.ts +0 -2
  27. package/dist/config/schema/keyword-detector.d.ts +0 -6
  28. package/dist/config/schema/oh-my-opencode-config.d.ts +2 -4
  29. package/dist/create-hooks.d.ts +0 -2
  30. package/dist/features/background-agent/parent-wake-dedupe.d.ts +2 -0
  31. package/dist/features/background-agent/parent-wake-flush-runner.d.ts +2 -0
  32. package/dist/features/background-agent/parent-wake-prompt-dispatch.d.ts +1 -0
  33. package/dist/features/background-agent/parent-wake-session-history.d.ts +4 -0
  34. package/dist/features/background-agent/parent-wake-session-inspector.d.ts +1 -0
  35. package/dist/features/builtin-commands/templates/handoff.d.ts +1 -1
  36. package/dist/features/builtin-skills/index.d.ts +1 -1
  37. package/dist/features/builtin-skills/skills.d.ts +4 -0
  38. package/dist/features/opencode-runtime-skills/source-server.d.ts +16 -1
  39. package/dist/features/opencode-skill-loader/skill-definition-record.d.ts +2 -0
  40. package/dist/features/team-mode/tools/lifecycle-test-fixture.d.ts +2 -0
  41. package/dist/features/team-mode/types.d.ts +1 -0
  42. package/dist/features/tmux-subagent/failed-readiness-cache.d.ts +28 -0
  43. package/dist/features/tmux-subagent/manager.d.ts +1 -9
  44. package/dist/features/tmux-subagent/resolve-server-url.d.ts +3 -0
  45. package/dist/hooks/anthropic-context-window-limit-recovery/executor.d.ts +1 -1
  46. package/dist/hooks/index.d.ts +0 -1
  47. package/dist/hooks/keyword-detector/constants.d.ts +0 -4
  48. package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +1 -1
  49. package/dist/index.js +9001 -1795
  50. package/dist/oh-my-opencode.schema.json +2 -4
  51. package/dist/plugin/chat-params.d.ts +1 -8
  52. package/dist/plugin/hooks/create-core-hooks.d.ts +0 -2
  53. package/dist/plugin/hooks/create-session-hooks.d.ts +0 -2
  54. package/dist/plugin/hooks/create-transform-hooks.d.ts +1 -2
  55. package/dist/plugin/messages-transform.d.ts +0 -1
  56. package/dist/shared/model-availability.d.ts +10 -2
  57. package/dist/shared/module-resolution-failure.d.ts +7 -0
  58. package/package.json +25 -18
  59. package/packages/ast-grep-mcp/dist/cli.js +2 -10
  60. package/packages/git-bash-mcp/dist/cli.js +11 -4
  61. package/packages/lsp-daemon/dist/cli.d.ts +2 -0
  62. package/packages/lsp-daemon/dist/cli.js +3711 -0
  63. package/packages/lsp-daemon/dist/daemon-client.d.ts +19 -0
  64. package/packages/lsp-daemon/dist/daemon-client.js +114 -0
  65. package/packages/lsp-daemon/dist/daemon-server.d.ts +12 -0
  66. package/packages/lsp-daemon/dist/daemon-server.js +106 -0
  67. package/packages/lsp-daemon/dist/ensure-daemon.d.ts +21 -0
  68. package/packages/lsp-daemon/dist/ensure-daemon.js +97 -0
  69. package/packages/lsp-daemon/dist/index.d.ts +5 -0
  70. package/packages/lsp-daemon/dist/index.js +3573 -0
  71. package/packages/lsp-daemon/dist/lock.d.ts +7 -0
  72. package/packages/lsp-daemon/dist/lock.js +61 -0
  73. package/packages/lsp-daemon/dist/package.json +6 -0
  74. package/packages/lsp-daemon/dist/paths.d.ts +11 -0
  75. package/packages/lsp-daemon/dist/paths.js +49 -0
  76. package/packages/lsp-daemon/dist/proxy.d.ts +10 -0
  77. package/packages/lsp-daemon/dist/proxy.js +61 -0
  78. package/packages/lsp-daemon/dist/request-routing.d.ts +9 -0
  79. package/packages/lsp-daemon/dist/request-routing.js +44 -0
  80. package/packages/lsp-daemon/dist/run-daemon.d.ts +1 -0
  81. package/packages/lsp-daemon/dist/run-daemon.js +11 -0
  82. package/packages/lsp-daemon/dist/socket-jsonrpc.d.ts +5 -0
  83. package/packages/lsp-daemon/dist/socket-jsonrpc.js +25 -0
  84. package/packages/lsp-daemon/package.json +38 -0
  85. package/packages/lsp-tools-mcp/dist/cli.js +0 -0
  86. package/packages/lsp-tools-mcp/dist/lsp/client-wrapper.js +40 -17
  87. package/packages/lsp-tools-mcp/dist/lsp/client.js +11 -9
  88. package/packages/lsp-tools-mcp/dist/lsp/config-loader.js +5 -5
  89. package/packages/lsp-tools-mcp/dist/lsp/directory-diagnostics.js +5 -3
  90. package/packages/lsp-tools-mcp/dist/lsp/effective-extension.d.ts +1 -0
  91. package/packages/lsp-tools-mcp/dist/lsp/effective-extension.js +8 -0
  92. package/packages/lsp-tools-mcp/dist/lsp/infer-extension.js +3 -2
  93. package/packages/lsp-tools-mcp/dist/lsp/language-mappings.js +1 -0
  94. package/packages/lsp-tools-mcp/dist/lsp/server-definitions.js +12 -0
  95. package/packages/lsp-tools-mcp/dist/lsp/server-install-state.d.ts +12 -0
  96. package/packages/lsp-tools-mcp/dist/lsp/server-install-state.js +51 -0
  97. package/packages/lsp-tools-mcp/dist/lsp/workspace-edit.js +2 -1
  98. package/packages/lsp-tools-mcp/dist/request-context.d.ts +7 -0
  99. package/packages/lsp-tools-mcp/dist/request-context.js +14 -0
  100. package/packages/lsp-tools-mcp/dist/tools.js +44 -1
  101. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +46 -33
  102. package/packages/omo-codex/plugin/.mcp.json +1 -1
  103. package/packages/omo-codex/plugin/components/comment-checker/dist/apply-patch.d.ts +7 -0
  104. package/packages/omo-codex/plugin/components/comment-checker/dist/apply-patch.js +173 -0
  105. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.d.ts +2 -0
  106. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +10 -0
  107. package/packages/omo-codex/plugin/components/comment-checker/dist/codex-hook.d.ts +22 -0
  108. package/packages/omo-codex/plugin/components/comment-checker/dist/codex-hook.js +165 -0
  109. package/packages/omo-codex/plugin/components/comment-checker/dist/core-values.d.ts +1 -0
  110. package/packages/omo-codex/plugin/components/comment-checker/dist/core-values.js +1 -0
  111. package/packages/omo-codex/plugin/components/comment-checker/dist/core.d.ts +5 -0
  112. package/packages/omo-codex/plugin/components/comment-checker/dist/core.js +4 -0
  113. package/packages/omo-codex/plugin/components/comment-checker/dist/hook-input.d.ts +6 -0
  114. package/packages/omo-codex/plugin/components/comment-checker/dist/hook-input.js +10 -0
  115. package/packages/omo-codex/plugin/components/comment-checker/dist/record.d.ts +2 -0
  116. package/packages/omo-codex/plugin/components/comment-checker/dist/record.js +11 -0
  117. package/packages/omo-codex/plugin/components/comment-checker/dist/request-extractor.d.ts +3 -0
  118. package/packages/omo-codex/plugin/components/comment-checker/dist/request-extractor.js +104 -0
  119. package/packages/omo-codex/plugin/components/comment-checker/dist/runner.d.ts +26 -0
  120. package/packages/omo-codex/plugin/components/comment-checker/dist/runner.js +144 -0
  121. package/packages/omo-codex/plugin/components/comment-checker/dist/types.d.ts +43 -0
  122. package/packages/omo-codex/plugin/components/comment-checker/dist/types.js +1 -0
  123. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  124. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  125. package/packages/omo-codex/plugin/components/git-bash/dist/cli.d.ts +2 -0
  126. package/packages/omo-codex/plugin/components/git-bash/dist/cli.js +29 -0
  127. package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.d.ts +28 -0
  128. package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.js +137 -0
  129. package/packages/omo-codex/plugin/components/git-bash/dist/index.d.ts +1 -0
  130. package/packages/omo-codex/plugin/components/git-bash/dist/index.js +1 -0
  131. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  132. package/packages/omo-codex/plugin/components/git-bash/package.json +5 -2
  133. package/packages/omo-codex/plugin/components/lsp/.mcp.json +1 -1
  134. package/packages/omo-codex/plugin/components/lsp/dist/cli.d.ts +2 -0
  135. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +42 -0
  136. package/packages/omo-codex/plugin/components/lsp/dist/codex-hook-cli.d.ts +2 -0
  137. package/packages/omo-codex/plugin/components/lsp/dist/codex-hook-cli.js +40 -0
  138. package/packages/omo-codex/plugin/components/lsp/dist/codex-hook.d.ts +16 -0
  139. package/packages/omo-codex/plugin/components/lsp/dist/codex-hook.js +180 -0
  140. package/packages/omo-codex/plugin/components/lsp/dist/lsp-session-state.d.ts +12 -0
  141. package/packages/omo-codex/plugin/components/lsp/dist/lsp-session-state.js +95 -0
  142. package/packages/omo-codex/plugin/components/lsp/dist/mutated-file-paths.d.ts +6 -0
  143. package/packages/omo-codex/plugin/components/lsp/dist/mutated-file-paths.js +79 -0
  144. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  145. package/packages/omo-codex/plugin/components/lsp/package.json +7 -7
  146. package/packages/omo-codex/plugin/components/lsp/scripts/build-lsp-daemon.mjs +68 -0
  147. package/packages/omo-codex/plugin/components/lsp/scripts/build-lsp-tools.mjs +45 -22
  148. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  149. package/packages/omo-codex/plugin/components/lsp/src/codex-hook-cli.ts +1 -1
  150. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +6 -2
  151. package/packages/omo-codex/plugin/components/lsp/src/lsp-session-state.ts +4 -0
  152. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +68 -0
  153. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +8 -20
  154. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus.md +69 -96
  155. package/packages/omo-codex/plugin/components/rules/dist/cli.d.ts +2 -0
  156. package/packages/omo-codex/plugin/components/rules/dist/cli.js +118 -0
  157. package/packages/omo-codex/plugin/components/rules/dist/codex-hook-options.d.ts +5 -0
  158. package/packages/omo-codex/plugin/components/rules/dist/codex-hook-options.js +1 -0
  159. package/packages/omo-codex/plugin/components/rules/dist/codex-hook.d.ts +47 -0
  160. package/packages/omo-codex/plugin/components/rules/dist/codex-hook.js +127 -0
  161. package/packages/omo-codex/plugin/components/rules/dist/config.d.ts +2 -0
  162. package/packages/omo-codex/plugin/components/rules/dist/config.js +100 -0
  163. package/packages/omo-codex/plugin/components/rules/dist/context-pressure.d.ts +2 -0
  164. package/packages/omo-codex/plugin/components/rules/dist/context-pressure.js +26 -0
  165. package/packages/omo-codex/plugin/components/rules/dist/debug-log.d.ts +8 -0
  166. package/packages/omo-codex/plugin/components/rules/dist/debug-log.js +36 -0
  167. package/packages/omo-codex/plugin/components/rules/dist/dynamic-target-fingerprints.d.ts +7 -0
  168. package/packages/omo-codex/plugin/components/rules/dist/dynamic-target-fingerprints.js +65 -0
  169. package/packages/omo-codex/plugin/components/rules/dist/event-budget.d.ts +3 -0
  170. package/packages/omo-codex/plugin/components/rules/dist/event-budget.js +14 -0
  171. package/packages/omo-codex/plugin/components/rules/dist/hook-output.d.ts +2 -0
  172. package/packages/omo-codex/plugin/components/rules/dist/hook-output.js +24 -0
  173. package/packages/omo-codex/plugin/components/rules/dist/path-utils.d.ts +4 -0
  174. package/packages/omo-codex/plugin/components/rules/dist/path-utils.js +24 -0
  175. package/packages/omo-codex/plugin/components/rules/dist/persistent-cache.d.ts +13 -0
  176. package/packages/omo-codex/plugin/components/rules/dist/persistent-cache.js +172 -0
  177. package/packages/omo-codex/plugin/components/rules/dist/post-compact-budget.d.ts +6 -0
  178. package/packages/omo-codex/plugin/components/rules/dist/post-compact-budget.js +74 -0
  179. package/packages/omo-codex/plugin/components/rules/dist/post-compact-claim.d.ts +4 -0
  180. package/packages/omo-codex/plugin/components/rules/dist/post-compact-claim.js +6 -0
  181. package/packages/omo-codex/plugin/components/rules/dist/post-compact-directive.d.ts +1 -0
  182. package/packages/omo-codex/plugin/components/rules/dist/post-compact-directive.js +32 -0
  183. package/packages/omo-codex/plugin/components/rules/dist/post-compact-state.d.ts +13 -0
  184. package/packages/omo-codex/plugin/components/rules/dist/post-compact-state.js +29 -0
  185. package/packages/omo-codex/plugin/components/rules/dist/rules/cache.d.ts +9 -0
  186. package/packages/omo-codex/plugin/components/rules/dist/rules/cache.js +51 -0
  187. package/packages/omo-codex/plugin/components/rules/dist/rules/constants.d.ts +70 -0
  188. package/packages/omo-codex/plugin/components/rules/dist/rules/constants.js +101 -0
  189. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-cache.d.ts +5 -0
  190. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-cache.js +60 -0
  191. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-loader.d.ts +6 -0
  192. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-loader.js +61 -0
  193. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-loader.d.ts +7 -0
  194. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-loader.js +60 -0
  195. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-paths.d.ts +11 -0
  196. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-paths.js +75 -0
  197. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-static-loader.d.ts +6 -0
  198. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-static-loader.js +29 -0
  199. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-types.d.ts +44 -0
  200. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-types.js +1 -0
  201. package/packages/omo-codex/plugin/components/rules/dist/rules/engine.d.ts +5 -0
  202. package/packages/omo-codex/plugin/components/rules/dist/rules/engine.js +85 -0
  203. package/packages/omo-codex/plugin/components/rules/dist/rules/errors.d.ts +6 -0
  204. package/packages/omo-codex/plugin/components/rules/dist/rules/errors.js +12 -0
  205. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-cache.d.ts +14 -0
  206. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-cache.js +51 -0
  207. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-paths.d.ts +6 -0
  208. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-paths.js +33 -0
  209. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-sources.d.ts +5 -0
  210. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-sources.js +40 -0
  211. package/packages/omo-codex/plugin/components/rules/dist/rules/finder.d.ts +28 -0
  212. package/packages/omo-codex/plugin/components/rules/dist/rules/finder.js +146 -0
  213. package/packages/omo-codex/plugin/components/rules/dist/rules/formatter.d.ts +7 -0
  214. package/packages/omo-codex/plugin/components/rules/dist/rules/formatter.js +112 -0
  215. package/packages/omo-codex/plugin/components/rules/dist/rules/matcher.d.ts +18 -0
  216. package/packages/omo-codex/plugin/components/rules/dist/rules/matcher.js +93 -0
  217. package/packages/omo-codex/plugin/components/rules/dist/rules/ordering.d.ts +3 -0
  218. package/packages/omo-codex/plugin/components/rules/dist/rules/ordering.js +27 -0
  219. package/packages/omo-codex/plugin/components/rules/dist/rules/parser-frontmatter.d.ts +7 -0
  220. package/packages/omo-codex/plugin/components/rules/dist/rules/parser-frontmatter.js +30 -0
  221. package/packages/omo-codex/plugin/components/rules/dist/rules/parser-yaml.d.ts +2 -0
  222. package/packages/omo-codex/plugin/components/rules/dist/rules/parser-yaml.js +237 -0
  223. package/packages/omo-codex/plugin/components/rules/dist/rules/parser.d.ts +3 -0
  224. package/packages/omo-codex/plugin/components/rules/dist/rules/parser.js +31 -0
  225. package/packages/omo-codex/plugin/components/rules/dist/rules/plugin-root.d.ts +1 -0
  226. package/packages/omo-codex/plugin/components/rules/dist/rules/plugin-root.js +48 -0
  227. package/packages/omo-codex/plugin/components/rules/dist/rules/project-root.d.ts +1 -0
  228. package/packages/omo-codex/plugin/components/rules/dist/rules/project-root.js +23 -0
  229. package/packages/omo-codex/plugin/components/rules/dist/rules/scanner.d.ts +14 -0
  230. package/packages/omo-codex/plugin/components/rules/dist/rules/scanner.js +111 -0
  231. package/packages/omo-codex/plugin/components/rules/dist/rules/sources.d.ts +3 -0
  232. package/packages/omo-codex/plugin/components/rules/dist/rules/sources.js +9 -0
  233. package/packages/omo-codex/plugin/components/rules/dist/rules/truncator.d.ts +18 -0
  234. package/packages/omo-codex/plugin/components/rules/dist/rules/truncator.js +59 -0
  235. package/packages/omo-codex/plugin/components/rules/dist/rules/types.d.ts +126 -0
  236. package/packages/omo-codex/plugin/components/rules/dist/rules/types.js +8 -0
  237. package/packages/omo-codex/plugin/components/rules/dist/rules-engine-factory.d.ts +6 -0
  238. package/packages/omo-codex/plugin/components/rules/dist/rules-engine-factory.js +20 -0
  239. package/packages/omo-codex/plugin/components/rules/dist/session-state-lock.d.ts +3 -0
  240. package/packages/omo-codex/plugin/components/rules/dist/session-state-lock.js +41 -0
  241. package/packages/omo-codex/plugin/components/rules/dist/sparkshell-awareness.d.ts +10 -0
  242. package/packages/omo-codex/plugin/components/rules/dist/sparkshell-awareness.js +90 -0
  243. package/packages/omo-codex/plugin/components/rules/dist/static-injection.d.ts +3 -0
  244. package/packages/omo-codex/plugin/components/rules/dist/static-injection.js +128 -0
  245. package/packages/omo-codex/plugin/components/rules/dist/tool-paths.d.ts +6 -0
  246. package/packages/omo-codex/plugin/components/rules/dist/tool-paths.js +168 -0
  247. package/packages/omo-codex/plugin/components/rules/dist/transcript-rule-filter.d.ts +4 -0
  248. package/packages/omo-codex/plugin/components/rules/dist/transcript-rule-filter.js +49 -0
  249. package/packages/omo-codex/plugin/components/rules/dist/transcript-search.d.ts +4 -0
  250. package/packages/omo-codex/plugin/components/rules/dist/transcript-search.js +91 -0
  251. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  252. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  253. package/packages/omo-codex/plugin/components/rules/src/codex-hook.ts +4 -2
  254. package/packages/omo-codex/plugin/components/rules/src/config.ts +13 -0
  255. package/packages/omo-codex/plugin/components/rules/src/event-budget.ts +17 -0
  256. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +4 -1
  257. package/packages/omo-codex/plugin/components/rules/src/post-compact-directive.ts +39 -0
  258. package/packages/omo-codex/plugin/components/rules/src/rules/constants.ts +16 -0
  259. package/packages/omo-codex/plugin/components/rules/src/rules/engine.ts +8 -0
  260. package/packages/omo-codex/plugin/components/rules/src/rules/types.ts +4 -0
  261. package/packages/omo-codex/plugin/components/rules/src/sparkshell-awareness.ts +53 -4
  262. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +127 -7
  263. package/packages/omo-codex/plugin/components/rules/src/transcript-rule-filter.ts +9 -1
  264. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +4 -2
  265. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +7 -2
  266. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +9 -9
  267. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +10 -4
  268. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +241 -0
  269. package/packages/omo-codex/plugin/components/rules/test/event-budget.test.ts +168 -0
  270. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +4 -0
  271. package/packages/omo-codex/plugin/components/rules/test/sparkshell-awareness.test.ts +86 -3
  272. package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +15 -15
  273. package/packages/omo-codex/plugin/components/start-work-continuation/dist/boulder-reader.d.ts +16 -0
  274. package/packages/omo-codex/plugin/components/start-work-continuation/dist/boulder-reader.js +146 -0
  275. package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.d.ts +2 -0
  276. package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +49 -0
  277. package/packages/omo-codex/plugin/components/start-work-continuation/dist/codex-hook.d.ts +2 -0
  278. package/packages/omo-codex/plugin/components/start-work-continuation/dist/codex-hook.js +80 -0
  279. package/packages/omo-codex/plugin/components/start-work-continuation/dist/directive.d.ts +1 -0
  280. package/packages/omo-codex/plugin/components/start-work-continuation/dist/directive.js +2 -0
  281. package/packages/omo-codex/plugin/components/start-work-continuation/dist/index.d.ts +5 -0
  282. package/packages/omo-codex/plugin/components/start-work-continuation/dist/index.js +3 -0
  283. package/packages/omo-codex/plugin/components/start-work-continuation/dist/types.d.ts +20 -0
  284. package/packages/omo-codex/plugin/components/start-work-continuation/dist/types.js +1 -0
  285. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  286. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  287. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +24 -2
  288. package/packages/omo-codex/plugin/components/telemetry/dist/atomic-write.d.ts +1 -0
  289. package/packages/omo-codex/plugin/components/telemetry/dist/atomic-write.js +18 -0
  290. package/packages/omo-codex/plugin/components/telemetry/dist/cli.d.ts +2 -0
  291. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +62 -0
  292. package/packages/omo-codex/plugin/components/telemetry/dist/codex-hook.d.ts +15 -0
  293. package/packages/omo-codex/plugin/components/telemetry/dist/codex-hook.js +42 -0
  294. package/packages/omo-codex/plugin/components/telemetry/dist/data-path.d.ts +10 -0
  295. package/packages/omo-codex/plugin/components/telemetry/dist/data-path.js +35 -0
  296. package/packages/omo-codex/plugin/components/telemetry/dist/diagnostics.d.ts +12 -0
  297. package/packages/omo-codex/plugin/components/telemetry/dist/diagnostics.js +108 -0
  298. package/packages/omo-codex/plugin/components/telemetry/dist/env-flags.d.ts +4 -0
  299. package/packages/omo-codex/plugin/components/telemetry/dist/env-flags.js +31 -0
  300. package/packages/omo-codex/plugin/components/telemetry/dist/posthog-activity-state.d.ts +8 -0
  301. package/packages/omo-codex/plugin/components/telemetry/dist/posthog-activity-state.js +68 -0
  302. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.d.ts +21 -0
  303. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +133 -0
  304. package/packages/omo-codex/plugin/components/telemetry/dist/product-identity.d.ts +8 -0
  305. package/packages/omo-codex/plugin/components/telemetry/dist/product-identity.js +29 -0
  306. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  307. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  308. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +5 -13
  309. package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +61 -185
  310. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -1
  311. package/packages/omo-codex/plugin/components/ultrawork/directive.md +122 -117
  312. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.d.ts +2 -0
  313. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +48 -0
  314. package/packages/omo-codex/plugin/components/ultrawork/dist/codex-hook.d.ts +7 -0
  315. package/packages/omo-codex/plugin/components/ultrawork/dist/codex-hook.js +122 -0
  316. package/packages/omo-codex/plugin/components/ultrawork/dist/directive.d.ts +1 -0
  317. package/packages/omo-codex/plugin/components/ultrawork/dist/directive.js +2 -0
  318. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  319. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  320. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +20 -11
  321. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +17 -11
  322. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +2 -5
  323. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +0 -71
  324. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.d.ts +16 -0
  325. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +200 -0
  326. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.d.ts +17 -0
  327. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.js +97 -0
  328. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.d.ts +4 -0
  329. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +183 -0
  330. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +6 -0
  331. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +55 -0
  332. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.d.ts +12 -0
  333. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +145 -0
  334. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.d.ts +2 -0
  335. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +39 -0
  336. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +13 -0
  337. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +100 -0
  338. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +26 -0
  339. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +97 -0
  340. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.d.ts +28 -0
  341. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.js +145 -0
  342. package/packages/omo-codex/plugin/components/ulw-loop/dist/command-types.d.ts +34 -0
  343. package/packages/omo-codex/plugin/components/ulw-loop/dist/command-types.js +1 -0
  344. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.d.ts +16 -0
  345. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.js +41 -0
  346. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +95 -0
  347. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.js +1 -0
  348. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.d.ts +31 -0
  349. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.js +119 -0
  350. package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.d.ts +12 -0
  351. package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.js +69 -0
  352. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.d.ts +16 -0
  353. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +59 -0
  354. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.d.ts +48 -0
  355. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +119 -0
  356. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +8 -0
  357. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +89 -0
  358. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +6 -0
  359. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +123 -0
  360. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.d.ts +16 -0
  361. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +70 -0
  362. package/packages/omo-codex/plugin/components/ulw-loop/dist/runtime.d.ts +10 -0
  363. package/packages/omo-codex/plugin/components/ulw-loop/dist/runtime.js +13 -0
  364. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-types.d.ts +63 -0
  365. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-types.js +1 -0
  366. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.d.ts +6 -0
  367. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +292 -0
  368. package/packages/omo-codex/plugin/components/ulw-loop/dist/types.d.ts +5 -0
  369. package/packages/omo-codex/plugin/components/ulw-loop/dist/types.js +5 -0
  370. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +2 -2
  371. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  372. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +14 -14
  373. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +24 -25
  374. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +17 -3
  375. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +2 -1
  376. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +1 -1
  377. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +95 -0
  378. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +0 -96
  379. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +23 -0
  380. package/packages/omo-codex/plugin/components/ulw-loop/test/skill-contract.test.ts +46 -0
  381. package/packages/omo-codex/plugin/hooks/hooks.json +16 -16
  382. package/packages/omo-codex/plugin/package-lock.json +10 -9
  383. package/packages/omo-codex/plugin/package.json +27 -26
  384. package/packages/omo-codex/plugin/scripts/auto-update.mjs +64 -15
  385. package/packages/omo-codex/plugin/scripts/build-bundled-mcp-runtimes.mjs +16 -0
  386. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +82 -18
  387. package/packages/omo-codex/plugin/scripts/migrate-codex-config.mjs +2 -2
  388. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +23 -11
  389. package/packages/omo-codex/plugin/scripts/sync-version.mjs +94 -0
  390. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +9 -9
  391. package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/SKILL.md +16 -1
  392. package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +93 -0
  393. package/packages/omo-codex/plugin/skills/lcx-doctor/agents/openai.yaml +11 -0
  394. package/packages/omo-codex/plugin/skills/lcx-report-bug/SKILL.md +17 -13
  395. package/packages/omo-codex/plugin/skills/lsp-setup/SKILL.md +139 -0
  396. package/packages/omo-codex/plugin/skills/lsp-setup/references/bash/README.md +60 -0
  397. package/packages/omo-codex/plugin/skills/lsp-setup/references/c-cpp/README.md +61 -0
  398. package/packages/omo-codex/plugin/skills/lsp-setup/references/csharp/README.md +71 -0
  399. package/packages/omo-codex/plugin/skills/lsp-setup/references/dart/README.md +48 -0
  400. package/packages/omo-codex/plugin/skills/lsp-setup/references/elixir/README.md +51 -0
  401. package/packages/omo-codex/plugin/skills/lsp-setup/references/go/README.md +57 -0
  402. package/packages/omo-codex/plugin/skills/lsp-setup/references/haskell/README.md +57 -0
  403. package/packages/omo-codex/plugin/skills/lsp-setup/references/java/README.md +57 -0
  404. package/packages/omo-codex/plugin/skills/lsp-setup/references/julia/README.md +60 -0
  405. package/packages/omo-codex/plugin/skills/lsp-setup/references/kotlin/README.md +59 -0
  406. package/packages/omo-codex/plugin/skills/lsp-setup/references/lua/README.md +66 -0
  407. package/packages/omo-codex/plugin/skills/lsp-setup/references/php/README.md +62 -0
  408. package/packages/omo-codex/plugin/skills/lsp-setup/references/python/README.md +71 -0
  409. package/packages/omo-codex/plugin/skills/lsp-setup/references/ruby/README.md +53 -0
  410. package/packages/omo-codex/plugin/skills/lsp-setup/references/rust/README.md +59 -0
  411. package/packages/omo-codex/plugin/skills/lsp-setup/references/swift/README.md +51 -0
  412. package/packages/omo-codex/plugin/skills/lsp-setup/references/terraform/README.md +62 -0
  413. package/packages/omo-codex/plugin/skills/lsp-setup/references/typescript/README.md +77 -0
  414. package/packages/omo-codex/plugin/skills/lsp-setup/references/yaml/README.md +70 -0
  415. package/packages/omo-codex/plugin/skills/lsp-setup/references/zig/README.md +49 -0
  416. package/packages/omo-codex/plugin/skills/lsp-setup/scripts/detect-lsp.ts +210 -0
  417. package/packages/omo-codex/plugin/skills/lsp-setup/scripts/lsp-server-table.ts +177 -0
  418. package/packages/omo-codex/plugin/skills/lsp-setup/scripts/tsconfig.json +17 -0
  419. package/packages/omo-codex/plugin/skills/lsp-setup/scripts/verify-lsp.ts +147 -0
  420. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +9 -9
  421. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +10 -10
  422. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +20 -22
  423. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +38 -61
  424. package/packages/omo-codex/plugin/skills/ultraresearch/SKILL.md +135 -677
  425. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +14 -14
  426. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +24 -25
  427. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +20 -11
  428. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +17 -11
  429. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +9 -9
  430. package/packages/omo-codex/plugin/test/aggregate-build.test.mjs +2 -1
  431. package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +1 -1
  432. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +5 -5
  433. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +6 -6
  434. package/packages/omo-codex/plugin/test/auto-update-restart-notice.test.mjs +194 -0
  435. package/packages/omo-codex/plugin/test/auto-update.test.mjs +17 -0
  436. package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +15 -44
  437. package/packages/omo-codex/plugin/test/lsp-prebuild-layouts.test.mjs +140 -0
  438. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +189 -7
  439. package/packages/omo-codex/plugin/test/start-work-skill.test.mjs +9 -31
  440. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +68 -4
  441. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +119 -0
  442. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +11 -112
  443. package/packages/omo-codex/plugin/test/sync-version.test.mjs +68 -0
  444. package/packages/omo-codex/plugin/test/ultraresearch-skill-contract.test.mjs +126 -0
  445. package/packages/omo-codex/plugin/test/ulw-plan-skill.test.mjs +2 -2
  446. package/packages/omo-codex/scripts/install/bin-dir.mjs +20 -0
  447. package/packages/omo-codex/scripts/install/bin-links.mjs +43 -6
  448. package/packages/omo-codex/scripts/install/cache.mjs +4 -0
  449. package/packages/omo-codex/scripts/install/config.mjs +4 -4
  450. package/packages/omo-codex/scripts/install/delegated-command.mjs +5 -1
  451. package/packages/omo-codex/scripts/install/git-bash-mcp-env.mjs +28 -0
  452. package/packages/omo-codex/scripts/install/git-bash.mjs +12 -4
  453. package/packages/omo-codex/scripts/install/git-bash.test.mjs +39 -4
  454. package/packages/omo-codex/scripts/install/hook-targets.mjs +46 -0
  455. package/packages/omo-codex/scripts/install/multi-agent-v2-config.mjs +12 -2
  456. package/packages/omo-codex/scripts/install/process.mjs +1 -0
  457. package/packages/omo-codex/scripts/install-bin-links.test.mjs +131 -3
  458. package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +91 -0
  459. package/packages/omo-codex/scripts/install-config.test.mjs +50 -44
  460. package/packages/omo-codex/scripts/install-delegated-command.test.mjs +78 -0
  461. package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +93 -0
  462. package/packages/omo-codex/scripts/install-hook-targets.test.mjs +100 -0
  463. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +3 -1
  464. package/packages/omo-codex/scripts/install-local.mjs +7 -18
  465. package/packages/omo-codex/scripts/install-local.test.mjs +34 -1
  466. package/packages/shared-skills/skills/lcx-contribute-bug-fix/SKILL.md +16 -1
  467. package/packages/shared-skills/skills/lcx-doctor/SKILL.md +93 -0
  468. package/packages/shared-skills/skills/lcx-doctor/agents/openai.yaml +11 -0
  469. package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +17 -13
  470. package/packages/shared-skills/skills/lsp-setup/SKILL.md +139 -0
  471. package/packages/shared-skills/skills/lsp-setup/references/bash/README.md +60 -0
  472. package/packages/shared-skills/skills/lsp-setup/references/c-cpp/README.md +61 -0
  473. package/packages/shared-skills/skills/lsp-setup/references/csharp/README.md +71 -0
  474. package/packages/shared-skills/skills/lsp-setup/references/dart/README.md +48 -0
  475. package/packages/shared-skills/skills/lsp-setup/references/elixir/README.md +51 -0
  476. package/packages/shared-skills/skills/lsp-setup/references/go/README.md +57 -0
  477. package/packages/shared-skills/skills/lsp-setup/references/haskell/README.md +57 -0
  478. package/packages/shared-skills/skills/lsp-setup/references/java/README.md +57 -0
  479. package/packages/shared-skills/skills/lsp-setup/references/julia/README.md +60 -0
  480. package/packages/shared-skills/skills/lsp-setup/references/kotlin/README.md +59 -0
  481. package/packages/shared-skills/skills/lsp-setup/references/lua/README.md +66 -0
  482. package/packages/shared-skills/skills/lsp-setup/references/php/README.md +62 -0
  483. package/packages/shared-skills/skills/lsp-setup/references/python/README.md +71 -0
  484. package/packages/shared-skills/skills/lsp-setup/references/ruby/README.md +53 -0
  485. package/packages/shared-skills/skills/lsp-setup/references/rust/README.md +59 -0
  486. package/packages/shared-skills/skills/lsp-setup/references/swift/README.md +51 -0
  487. package/packages/shared-skills/skills/lsp-setup/references/terraform/README.md +62 -0
  488. package/packages/shared-skills/skills/lsp-setup/references/typescript/README.md +77 -0
  489. package/packages/shared-skills/skills/lsp-setup/references/yaml/README.md +70 -0
  490. package/packages/shared-skills/skills/lsp-setup/references/zig/README.md +49 -0
  491. package/packages/shared-skills/skills/lsp-setup/scripts/detect-lsp.ts +210 -0
  492. package/packages/shared-skills/skills/lsp-setup/scripts/lsp-server-table.ts +177 -0
  493. package/packages/shared-skills/skills/lsp-setup/scripts/tsconfig.json +17 -0
  494. package/packages/shared-skills/skills/lsp-setup/scripts/verify-lsp.ts +147 -0
  495. package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +1 -1
  496. package/packages/shared-skills/skills/review-work/SKILL.md +10 -14
  497. package/packages/shared-skills/skills/start-work/SKILL.md +30 -59
  498. package/packages/shared-skills/skills/ultraresearch/SKILL.md +126 -667
  499. package/dist/hooks/anthropic-effort/hook.d.ts +0 -26
  500. package/dist/hooks/anthropic-effort/index.d.ts +0 -1
  501. package/dist/hooks/keyword-detector/analyze/default.d.ts +0 -12
  502. package/dist/hooks/keyword-detector/analyze/index.d.ts +0 -1
  503. package/dist/hooks/keyword-detector/search/default.d.ts +0 -12
  504. package/dist/hooks/keyword-detector/search/index.d.ts +0 -1
  505. package/dist/hooks/thinking-block-validator/hook.d.ts +0 -12
  506. package/dist/hooks/thinking-block-validator/index.d.ts +0 -1
  507. package/packages/omo-codex/plugin/components/ultrawork/test/directive-contract.test.ts +0 -18
  508. package/packages/omo-codex/plugin/test/global-review-debug-gate.test.mjs +0 -29
  509. package/packages/omo-codex/plugin/test/subagent-guidance.test.mjs +0 -151
@@ -0,0 +1,97 @@
1
+ import { existsSync } from "node:fs";
2
+ import { readFile } from "node:fs/promises";
3
+ import { resolve } from "node:path";
4
+ export class CodexGoalSnapshotError extends Error {
5
+ }
6
+ function safeObject(value) {
7
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
8
+ }
9
+ function safeString(value) {
10
+ return typeof value === "string" ? value.trim() : "";
11
+ }
12
+ function normalizeStatus(value) {
13
+ const status = safeString(value).toLowerCase();
14
+ if (status === "complete" || status === "completed" || status === "done")
15
+ return "complete";
16
+ if (status === "cancelled" || status === "canceled")
17
+ return "cancelled";
18
+ if (status === "failed" || status === "failure")
19
+ return "failed";
20
+ if (status === "active" || status === "in_progress" || status === "pending" || status === "running")
21
+ return "active";
22
+ return "unknown";
23
+ }
24
+ function normalizeObjective(value) {
25
+ return value.replace(/\s+/g, " ").trim();
26
+ }
27
+ export function parseCodexGoalSnapshot(value) {
28
+ const root = safeObject(value);
29
+ const goalValue = Object.hasOwn(root, "goal") ? root["goal"] : value;
30
+ if (goalValue === null || goalValue === undefined || goalValue === false) {
31
+ return { available: false, raw: value };
32
+ }
33
+ const goal = safeObject(goalValue);
34
+ const objective = safeString(goal["objective"] ?? goal["goal"] ?? goal["description"] ?? root["objective"]);
35
+ const status = normalizeStatus(goal["status"] ?? root["status"]);
36
+ return {
37
+ available: Boolean(objective || status !== "unknown"),
38
+ ...(objective ? { objective } : {}),
39
+ status,
40
+ raw: value,
41
+ };
42
+ }
43
+ export async function readCodexGoalSnapshotInput(raw, cwd = process.cwd()) {
44
+ if (!raw?.trim())
45
+ return null;
46
+ const trimmed = raw.trim();
47
+ try {
48
+ return parseCodexGoalSnapshot(JSON.parse(trimmed));
49
+ }
50
+ catch {
51
+ const path = resolve(cwd, trimmed);
52
+ if (!existsSync(path)) {
53
+ throw new CodexGoalSnapshotError(`Codex goal snapshot is neither valid JSON nor a readable path: ${trimmed}`);
54
+ }
55
+ try {
56
+ return parseCodexGoalSnapshot(JSON.parse(await readFile(path, "utf-8")));
57
+ }
58
+ catch (error) {
59
+ throw new CodexGoalSnapshotError(`Codex goal snapshot path does not contain valid JSON: ${trimmed}${error instanceof Error ? ` (${error.message})` : ""}`);
60
+ }
61
+ }
62
+ }
63
+ export function reconcileCodexGoalSnapshot(snapshot, options) {
64
+ const effectiveSnapshot = snapshot ?? { available: false, raw: null };
65
+ const errors = [];
66
+ const warnings = [];
67
+ if (!effectiveSnapshot.available) {
68
+ const message = "Codex goal snapshot is absent or reports no active goal; call get_goal and pass its JSON with --codex-goal-json.";
69
+ if (options.requireSnapshot)
70
+ errors.push(message);
71
+ else
72
+ warnings.push(message);
73
+ return { ok: errors.length === 0, snapshot: effectiveSnapshot, warnings, errors };
74
+ }
75
+ const expected = normalizeObjective(options.expectedObjective);
76
+ const accepted = new Set([expected, ...(options.acceptedObjectives ?? []).map((objective) => normalizeObjective(objective))].filter(Boolean));
77
+ const actual = normalizeObjective(effectiveSnapshot.objective ?? "");
78
+ if (!actual) {
79
+ errors.push("Codex goal snapshot is missing objective text.");
80
+ }
81
+ else if (!accepted.has(actual)) {
82
+ errors.push(`Codex goal objective mismatch: expected "${expected}", got "${actual}".`);
83
+ }
84
+ const allowed = options.allowedStatuses ?? (options.requireComplete ? ["complete"] : ["active", "complete"]);
85
+ const actualStatus = effectiveSnapshot.status ?? "unknown";
86
+ if (!allowed.includes(actualStatus)) {
87
+ errors.push(`Codex goal status mismatch: expected ${allowed.join(" or ")}, got ${actualStatus}.`);
88
+ }
89
+ if (options.requireComplete && actualStatus !== "complete") {
90
+ errors.push('Codex goal is not complete; call update_goal({status: "complete"}) only after the objective is actually complete, then pass the fresh get_goal JSON.');
91
+ }
92
+ return { ok: errors.length === 0, snapshot: effectiveSnapshot, warnings, errors };
93
+ }
94
+ export function formatCodexGoalReconciliation(reconciliation) {
95
+ const parts = [...reconciliation.errors, ...reconciliation.warnings];
96
+ return parts.join(" ");
97
+ }
@@ -0,0 +1,28 @@
1
+ export interface UserPromptSubmitPayload {
2
+ readonly cwd: string;
3
+ readonly hook_event_name: "UserPromptSubmit";
4
+ readonly model?: string;
5
+ readonly permission_mode?: string;
6
+ readonly prompt: string;
7
+ readonly session_id: string;
8
+ readonly transcript_path?: string;
9
+ readonly turn_id?: string;
10
+ }
11
+ export interface PreToolUsePayload {
12
+ readonly cwd: string;
13
+ readonly hook_event_name: "PreToolUse";
14
+ readonly model: string;
15
+ readonly permission_mode: string;
16
+ readonly session_id: string;
17
+ readonly tool_input: unknown;
18
+ readonly tool_name: string;
19
+ readonly tool_use_id: string;
20
+ readonly transcript_path: string | null;
21
+ readonly turn_id: string;
22
+ }
23
+ export declare function parseUserPromptSubmitPayload(raw: string): UserPromptSubmitPayload | null;
24
+ export declare function parsePreToolUsePayload(raw: string): PreToolUsePayload | null;
25
+ export declare function applyUserPromptUlwLoopSteering(payload: UserPromptSubmitPayload): Promise<string>;
26
+ export declare function applyPreToolUseGoalBudgetGuard(payload: PreToolUsePayload): string;
27
+ export declare function runUlwLoopHookCli(stdin: NodeJS.ReadableStream, stdout: NodeJS.WritableStream): Promise<void>;
28
+ export declare function runPreToolUseGoalBudgetGuardCli(stdin: NodeJS.ReadableStream, stdout: NodeJS.WritableStream): Promise<void>;
@@ -0,0 +1,145 @@
1
+ import { parseUlwLoopSteeringDirective, steerUlwLoop } from "./steering.js";
2
+ const CREATE_GOAL_TOOL_NAME = "create_goal";
3
+ const CREATE_GOAL_PAYLOAD_WARNING = "Use create_goal with objective only. Omit token_budget so the goal stays unlimited, and put lifecycle status changes on update_goal.";
4
+ export function parseUserPromptSubmitPayload(raw) {
5
+ if (raw.trim().length === 0)
6
+ return null;
7
+ try {
8
+ const parsed = JSON.parse(raw);
9
+ return isUserPromptSubmitPayload(parsed) ? parsed : null;
10
+ }
11
+ catch (error) {
12
+ if (error instanceof SyntaxError)
13
+ return null;
14
+ return null;
15
+ }
16
+ }
17
+ export function parsePreToolUsePayload(raw) {
18
+ if (raw.trim().length === 0)
19
+ return null;
20
+ try {
21
+ const parsed = JSON.parse(raw);
22
+ return isPreToolUsePayload(parsed) ? parsed : null;
23
+ }
24
+ catch (error) {
25
+ if (error instanceof SyntaxError)
26
+ return null;
27
+ return null;
28
+ }
29
+ }
30
+ export async function applyUserPromptUlwLoopSteering(payload) {
31
+ try {
32
+ if (payload.hook_event_name !== "UserPromptSubmit")
33
+ return "";
34
+ const proposal = parseUlwLoopSteeringDirective(payload.prompt);
35
+ if (proposal === null)
36
+ return "";
37
+ const result = await steerUlwLoop(payload.cwd, proposal, payloadScope(payload));
38
+ if (!result.accepted)
39
+ return "";
40
+ return JSON.stringify({
41
+ status: "accepted",
42
+ kind: result.audit.kind,
43
+ source: result.audit.source,
44
+ deduped: result.deduped,
45
+ });
46
+ }
47
+ catch (error) {
48
+ if (error instanceof Error)
49
+ return "";
50
+ return "";
51
+ }
52
+ }
53
+ function payloadScope(payload) {
54
+ return { sessionId: payload.session_id };
55
+ }
56
+ export function applyPreToolUseGoalBudgetGuard(payload) {
57
+ if (payload.hook_event_name !== "PreToolUse")
58
+ return "";
59
+ if (payload.tool_name !== CREATE_GOAL_TOOL_NAME)
60
+ return "";
61
+ if (!hasInvalidCreateGoalInput(payload.tool_input))
62
+ return "";
63
+ const output = {
64
+ hookSpecificOutput: {
65
+ hookEventName: "PreToolUse",
66
+ permissionDecision: "deny",
67
+ permissionDecisionReason: CREATE_GOAL_PAYLOAD_WARNING,
68
+ additionalContext: CREATE_GOAL_PAYLOAD_WARNING,
69
+ },
70
+ };
71
+ return `${JSON.stringify(output)}\n`;
72
+ }
73
+ export async function runUlwLoopHookCli(stdin, stdout) {
74
+ try {
75
+ const payload = parseUserPromptSubmitPayload(await readAll(stdin));
76
+ if (payload === null)
77
+ return;
78
+ const output = await applyUserPromptUlwLoopSteering(payload);
79
+ if (output.length > 0)
80
+ stdout.write(output);
81
+ }
82
+ catch (error) {
83
+ if (error instanceof Error)
84
+ return;
85
+ return;
86
+ }
87
+ }
88
+ export async function runPreToolUseGoalBudgetGuardCli(stdin, stdout) {
89
+ try {
90
+ const payload = parsePreToolUsePayload(await readAll(stdin));
91
+ if (payload === null)
92
+ return;
93
+ const output = applyPreToolUseGoalBudgetGuard(payload);
94
+ if (output.length > 0)
95
+ stdout.write(output);
96
+ }
97
+ catch (error) {
98
+ if (error instanceof Error)
99
+ return;
100
+ return;
101
+ }
102
+ }
103
+ function isUserPromptSubmitPayload(value) {
104
+ if (!isRecord(value))
105
+ return false;
106
+ return (value["hook_event_name"] === "UserPromptSubmit" &&
107
+ typeof value["cwd"] === "string" &&
108
+ typeof value["prompt"] === "string" &&
109
+ typeof value["session_id"] === "string" &&
110
+ ["model", "permission_mode", "transcript_path", "turn_id"].every((key) => optionalString(value[key])));
111
+ }
112
+ function isPreToolUsePayload(value) {
113
+ if (!isRecord(value))
114
+ return false;
115
+ return (value["hook_event_name"] === "PreToolUse" &&
116
+ typeof value["cwd"] === "string" &&
117
+ typeof value["model"] === "string" &&
118
+ typeof value["permission_mode"] === "string" &&
119
+ typeof value["session_id"] === "string" &&
120
+ typeof value["tool_name"] === "string" &&
121
+ typeof value["tool_use_id"] === "string" &&
122
+ (value["transcript_path"] === null || typeof value["transcript_path"] === "string") &&
123
+ typeof value["turn_id"] === "string" &&
124
+ Object.hasOwn(value, "tool_input"));
125
+ }
126
+ function hasInvalidCreateGoalInput(value) {
127
+ return isRecord(value) && Object.keys(value).some((key) => key !== "objective");
128
+ }
129
+ function isRecord(value) {
130
+ return typeof value === "object" && value !== null && !Array.isArray(value);
131
+ }
132
+ function optionalString(value) {
133
+ return value === undefined || typeof value === "string";
134
+ }
135
+ function readAll(stdin) {
136
+ return new Promise((resolve, reject) => {
137
+ let data = "";
138
+ stdin.setEncoding("utf8");
139
+ stdin.on("data", (chunk) => {
140
+ data += chunk instanceof Buffer ? chunk.toString() : String(chunk);
141
+ });
142
+ stdin.once("error", reject);
143
+ stdin.once("end", () => resolve(data));
144
+ });
145
+ }
@@ -0,0 +1,34 @@
1
+ import type { UlwLoopCodexGoalMode, UlwLoopStatus } from "./constants.js";
2
+ export interface CreateUlwLoopOptions {
3
+ brief: string;
4
+ goals?: readonly {
5
+ readonly title?: string;
6
+ readonly objective: string;
7
+ }[];
8
+ codexGoalMode?: UlwLoopCodexGoalMode;
9
+ now?: Date;
10
+ force?: boolean;
11
+ }
12
+ export interface StartNextOptions {
13
+ now?: Date;
14
+ retryFailed?: boolean;
15
+ }
16
+ export interface CheckpointOptions {
17
+ goalId: string;
18
+ status: Extract<UlwLoopStatus, "complete" | "failed"> | "blocked";
19
+ evidence?: string;
20
+ codexGoal?: unknown;
21
+ qualityGate?: unknown;
22
+ allowActiveFinalCodexGoal?: boolean;
23
+ now?: Date;
24
+ }
25
+ export interface AddUlwLoopGoalOptions {
26
+ title: string;
27
+ objective: string;
28
+ evidence?: string;
29
+ now?: Date;
30
+ }
31
+ export interface RecordFinalReviewBlockersOptions extends AddUlwLoopGoalOptions {
32
+ goalId: string;
33
+ codexGoal?: unknown;
34
+ }
@@ -0,0 +1,16 @@
1
+ export declare const ULW_LOOP_DIR = ".omo/ulw-loop";
2
+ export declare const ULW_LOOP_BRIEF = "brief.md";
3
+ export declare const ULW_LOOP_GOALS = "goals.json";
4
+ export declare const ULW_LOOP_LEDGER = "ledger.jsonl";
5
+ export type UlwLoopStatus = "pending" | "in_progress" | "complete" | "failed" | "blocked" | "review_blocked" | "needs_user_decision";
6
+ export type UlwLoopCodexGoalMode = "aggregate" | "per_story";
7
+ export type UlwLoopSteeringStatus = "superseded" | "blocked";
8
+ export declare const ULW_LOOP_STEERING_MUTATION_KINDS: readonly ["add_subgoal", "split_subgoal", "reorder_pending", "revise_pending_wording", "revise_criterion", "annotate_ledger", "mark_blocked_superseded"];
9
+ export type UlwLoopSteeringMutationKind = (typeof ULW_LOOP_STEERING_MUTATION_KINDS)[number];
10
+ export type UlwLoopSteeringSource = "user_prompt_submit" | "finding" | "cli";
11
+ export declare const ULW_LOOP_SUCCESS_CRITERION_USER_MODELS: readonly ["happy", "edge", "regression", "adversarial"];
12
+ export type UlwLoopSuccessCriterionUserModel = (typeof ULW_LOOP_SUCCESS_CRITERION_USER_MODELS)[number];
13
+ export declare const ULW_LOOP_CRITERION_STATUSES: readonly ["pending", "pass", "fail", "blocked"];
14
+ export type UlwLoopCriterionStatus = (typeof ULW_LOOP_CRITERION_STATUSES)[number];
15
+ export declare const ULW_LOOP_LEDGER_EVENT_KINDS: readonly ["plan_created", "goal_started", "goal_resumed", "goal_completed", "goal_blocked", "goal_failed", "goal_needs_user_decision", "goal_retried", "aggregate_completed", "aggregate_objective_migrated", "goal_added", "steering_accepted", "steering_rejected", "final_review_failed", "goal_review_blocked", "evidence_captured", "criterion_failed", "criterion_blocked", "criteria_revised"];
16
+ export type UlwLoopLedgerEventKind = (typeof ULW_LOOP_LEDGER_EVENT_KINDS)[number];
@@ -0,0 +1,41 @@
1
+ export const ULW_LOOP_DIR = ".omo/ulw-loop";
2
+ export const ULW_LOOP_BRIEF = "brief.md";
3
+ export const ULW_LOOP_GOALS = "goals.json";
4
+ export const ULW_LOOP_LEDGER = "ledger.jsonl";
5
+ export const ULW_LOOP_STEERING_MUTATION_KINDS = [
6
+ "add_subgoal",
7
+ "split_subgoal",
8
+ "reorder_pending",
9
+ "revise_pending_wording",
10
+ "revise_criterion",
11
+ "annotate_ledger",
12
+ "mark_blocked_superseded",
13
+ ];
14
+ export const ULW_LOOP_SUCCESS_CRITERION_USER_MODELS = [
15
+ "happy",
16
+ "edge",
17
+ "regression",
18
+ "adversarial",
19
+ ];
20
+ export const ULW_LOOP_CRITERION_STATUSES = ["pending", "pass", "fail", "blocked"];
21
+ export const ULW_LOOP_LEDGER_EVENT_KINDS = [
22
+ "plan_created",
23
+ "goal_started",
24
+ "goal_resumed",
25
+ "goal_completed",
26
+ "goal_blocked",
27
+ "goal_failed",
28
+ "goal_needs_user_decision",
29
+ "goal_retried",
30
+ "aggregate_completed",
31
+ "aggregate_objective_migrated",
32
+ "goal_added",
33
+ "steering_accepted",
34
+ "steering_rejected",
35
+ "final_review_failed",
36
+ "goal_review_blocked",
37
+ "evidence_captured",
38
+ "criterion_failed",
39
+ "criterion_blocked",
40
+ "criteria_revised",
41
+ ];
@@ -0,0 +1,95 @@
1
+ import type { UlwLoopCodexGoalMode, UlwLoopCriterionStatus, UlwLoopLedgerEventKind, UlwLoopStatus, UlwLoopSteeringMutationKind, UlwLoopSteeringStatus, UlwLoopSuccessCriterionUserModel } from "./constants.js";
2
+ import type { UlwLoopSteeringAudit } from "./steering-types.js";
3
+ export interface UlwLoopSuccessCriterion {
4
+ readonly id: string;
5
+ readonly scenario: string;
6
+ readonly userModel: UlwLoopSuccessCriterionUserModel;
7
+ readonly expectedEvidence: string;
8
+ capturedEvidence: string | null;
9
+ status: UlwLoopCriterionStatus;
10
+ capturedAt?: string;
11
+ notes?: string;
12
+ }
13
+ export interface UlwLoopItem {
14
+ id: string;
15
+ title: string;
16
+ objective: string;
17
+ status: UlwLoopStatus;
18
+ successCriteria: UlwLoopSuccessCriterion[];
19
+ attempt: number;
20
+ createdAt: string;
21
+ updatedAt: string;
22
+ startedAt?: string;
23
+ completedAt?: string;
24
+ failedAt?: string;
25
+ reviewBlockedAt?: string;
26
+ evidence?: string;
27
+ failureReason?: string;
28
+ steeringStatus?: UlwLoopSteeringStatus;
29
+ supersededBy?: string[];
30
+ supersedes?: string[];
31
+ blockedReason?: string;
32
+ blockerSignature?: string;
33
+ blockerOccurrenceCount?: number;
34
+ requiredExternalDecision?: string;
35
+ nonRetriable?: boolean;
36
+ steeringEvidence?: string;
37
+ steeringRationale?: string;
38
+ }
39
+ export interface UlwLoopAggregateCompletion {
40
+ status: "complete";
41
+ completedAt: string;
42
+ evidence: string;
43
+ codexGoal?: unknown;
44
+ }
45
+ export interface UlwLoopPlan {
46
+ version: 1;
47
+ createdAt: string;
48
+ updatedAt: string;
49
+ briefPath: string;
50
+ goalsPath: string;
51
+ ledgerPath: string;
52
+ codexGoalMode?: UlwLoopCodexGoalMode;
53
+ codexObjective?: string;
54
+ codexObjectiveAliases?: string[];
55
+ aggregateCompletion?: UlwLoopAggregateCompletion;
56
+ activeGoalId?: string;
57
+ goals: UlwLoopItem[];
58
+ }
59
+ export interface UlwLoopQualityGate {
60
+ aiSlopCleaner: {
61
+ status: "passed";
62
+ evidence: string;
63
+ };
64
+ verification: {
65
+ status: "passed";
66
+ commands: string[];
67
+ evidence: string;
68
+ };
69
+ codeReview: {
70
+ recommendation: "APPROVE";
71
+ architectStatus: "CLEAR";
72
+ evidence: string;
73
+ };
74
+ }
75
+ export interface UlwLoopLedgerEntry {
76
+ at: string;
77
+ kind: UlwLoopLedgerEventKind;
78
+ goalId?: string;
79
+ criterionId?: string;
80
+ status?: UlwLoopStatus;
81
+ criterionStatus?: UlwLoopCriterionStatus;
82
+ message?: string;
83
+ codexGoal?: unknown;
84
+ evidence?: string;
85
+ capturedEvidence?: string;
86
+ qualityGate?: UlwLoopQualityGate;
87
+ steering?: UlwLoopSteeringAudit;
88
+ before?: unknown;
89
+ after?: unknown;
90
+ mutationKind?: UlwLoopSteeringMutationKind;
91
+ idempotencyKey?: string;
92
+ blockerSignature?: string;
93
+ blockerOccurrenceCount?: number;
94
+ requiredExternalDecision?: string;
95
+ }
@@ -0,0 +1,31 @@
1
+ import type { UlwLoopScope } from "./paths.js";
2
+ import type { UlwLoopItem, UlwLoopLedgerEntry, UlwLoopPlan, UlwLoopSuccessCriterion } from "./types.js";
3
+ type EvidenceStatus = "pass" | "fail" | "blocked";
4
+ type RecordEvidenceArgs = {
5
+ readonly goalId: string;
6
+ readonly criterionId: string;
7
+ readonly status: EvidenceStatus;
8
+ readonly evidence: string;
9
+ readonly notes?: string;
10
+ };
11
+ export declare function recordEvidence(repoRoot: string, args: RecordEvidenceArgs, scope?: UlwLoopScope): Promise<{
12
+ plan: UlwLoopPlan;
13
+ goal: UlwLoopItem;
14
+ criterion: UlwLoopSuccessCriterion;
15
+ ledgerEntry: UlwLoopLedgerEntry;
16
+ }>;
17
+ export declare function markCriteriaPendingResetForGoal(repoRoot: string, goalId: string, scope?: UlwLoopScope): Promise<{
18
+ plan: UlwLoopPlan;
19
+ resetCount: number;
20
+ }>;
21
+ export declare function criteriaSummary(plan: UlwLoopPlan): {
22
+ totalCriteria: number;
23
+ passCount: number;
24
+ pendingCount: number;
25
+ failCount: number;
26
+ blockedCount: number;
27
+ goalsWithUnresolvedCriteria: string[];
28
+ };
29
+ export declare function unresolvedCriteriaOf(goal: UlwLoopItem): UlwLoopSuccessCriterion[];
30
+ export declare function requireAllCriteriaPass(goal: UlwLoopItem): void;
31
+ export {};
@@ -0,0 +1,119 @@
1
+ // biome-ignore-all format: keep this module under the mandated pure LOC budget.
2
+ import { hasAllCriteriaPass } from "./goal-status.js";
3
+ import { appendLedger, readUlwLoopPlan, withUlwLoopMutationLock, writePlan } from "./plan-io.js";
4
+ import { iso, UlwLoopError } from "./types.js";
5
+ function ulwLoopFail(message, code, details) { throw new UlwLoopError(message, code, { details }); }
6
+ function ledgerKind(status) {
7
+ switch (status) {
8
+ case "pass":
9
+ return "evidence_captured";
10
+ case "fail":
11
+ return "criterion_failed";
12
+ case "blocked":
13
+ return "criterion_blocked";
14
+ default:
15
+ return ulwLoopFail("Invalid criterion status.", "ULW_LOOP_CRITERION_STATUS_INVALID", { status });
16
+ }
17
+ }
18
+ function findGoal(plan, goalId) {
19
+ const goal = plan.goals.find((candidate) => candidate.id === goalId);
20
+ return goal ?? ulwLoopFail(`UlwLoop goal not found: ${goalId}.`, "ULW_LOOP_GOAL_NOT_FOUND", { goalId });
21
+ }
22
+ function findCriterion(goal, criterionId) {
23
+ const criterion = goal.successCriteria.find((candidate) => candidate.id === criterionId);
24
+ return criterion ?? ulwLoopFail(`Success criterion not found: ${criterionId}.`, "ULW_LOOP_CRITERION_NOT_FOUND", { goalId: goal.id, criterionId });
25
+ }
26
+ function nonEmptyEvidence(evidence) { const trimmed = evidence.trim(); return trimmed || ulwLoopFail("Evidence must be a non-empty string.", "ULW_LOOP_EVIDENCE_REQUIRED", {}); }
27
+ export async function recordEvidence(repoRoot, args, scope) {
28
+ return withUlwLoopMutationLock(repoRoot, scope, async () => {
29
+ const plan = await readUlwLoopPlan(repoRoot, scope);
30
+ const goal = findGoal(plan, args.goalId);
31
+ const criterion = findCriterion(goal, args.criterionId);
32
+ const evidence = nonEmptyEvidence(args.evidence);
33
+ const kind = ledgerKind(args.status);
34
+ const prevStatus = criterion.status;
35
+ const capturedAt = iso();
36
+ criterion.status = args.status;
37
+ criterion.capturedEvidence = evidence;
38
+ criterion.capturedAt = capturedAt;
39
+ if (args.notes !== undefined)
40
+ criterion.notes = args.notes;
41
+ goal.updatedAt = capturedAt;
42
+ plan.updatedAt = capturedAt;
43
+ await writePlan(repoRoot, plan, scope);
44
+ const ledgerEntry = {
45
+ at: capturedAt,
46
+ kind,
47
+ goalId: goal.id,
48
+ criterionId: criterion.id,
49
+ criterionStatus: args.status,
50
+ evidence,
51
+ capturedEvidence: evidence,
52
+ before: { status: prevStatus },
53
+ after: { goalId: goal.id, criterionId: criterion.id, status: args.status, evidence, capturedAt, prevStatus },
54
+ };
55
+ await appendLedger(repoRoot, ledgerEntry, scope);
56
+ return { plan, goal, criterion, ledgerEntry };
57
+ });
58
+ }
59
+ export async function markCriteriaPendingResetForGoal(repoRoot, goalId, scope) {
60
+ return withUlwLoopMutationLock(repoRoot, scope, async () => {
61
+ const plan = await readUlwLoopPlan(repoRoot, scope);
62
+ const goal = findGoal(plan, goalId);
63
+ const now = iso();
64
+ const before = goal.successCriteria.map((criterion) => ({ id: criterion.id, status: criterion.status, capturedEvidence: criterion.capturedEvidence, capturedAt: criterion.capturedAt ?? null }));
65
+ for (const criterion of goal.successCriteria) {
66
+ criterion.status = "pending";
67
+ criterion.capturedEvidence = null;
68
+ delete criterion.capturedAt;
69
+ delete criterion.notes;
70
+ }
71
+ goal.updatedAt = now;
72
+ plan.updatedAt = now;
73
+ await writePlan(repoRoot, plan, scope);
74
+ await appendLedger(repoRoot, { at: now, kind: "criteria_revised", goalId, message: `Reset ${goal.successCriteria.length} criteria to pending.`, before, after: { resetCount: goal.successCriteria.length } }, scope);
75
+ return { plan, resetCount: goal.successCriteria.length };
76
+ });
77
+ }
78
+ export function criteriaSummary(plan) {
79
+ let totalCriteria = 0;
80
+ let passCount = 0;
81
+ let pendingCount = 0;
82
+ let failCount = 0;
83
+ let blockedCount = 0;
84
+ const goalsWithUnresolvedCriteria = [];
85
+ for (const goal of plan.goals) {
86
+ let unresolved = false;
87
+ for (const criterion of goal.successCriteria) {
88
+ totalCriteria += 1;
89
+ if (criterion.status !== "pass")
90
+ unresolved = true;
91
+ switch (criterion.status) {
92
+ case "pass":
93
+ passCount += 1;
94
+ break;
95
+ case "pending":
96
+ pendingCount += 1;
97
+ break;
98
+ case "fail":
99
+ failCount += 1;
100
+ break;
101
+ case "blocked":
102
+ blockedCount += 1;
103
+ break;
104
+ default: ulwLoopFail("Invalid criterion status.", "ULW_LOOP_CRITERION_STATUS_INVALID", { status: criterion.status });
105
+ }
106
+ }
107
+ if (unresolved)
108
+ goalsWithUnresolvedCriteria.push(goal.id);
109
+ }
110
+ return { totalCriteria, passCount, pendingCount, failCount, blockedCount, goalsWithUnresolvedCriteria };
111
+ }
112
+ export function unresolvedCriteriaOf(goal) { return goal.successCriteria.filter((criterion) => criterion.status !== "pass"); }
113
+ export function requireAllCriteriaPass(goal) {
114
+ if (hasAllCriteriaPass(goal))
115
+ return;
116
+ throw new UlwLoopError(`Goal ${goal.id} has unresolved success criteria.`, "ulw_loop_criteria_not_all_pass", {
117
+ details: { goalId: goal.id, unresolved: unresolvedCriteriaOf(goal).map((criterion) => ({ id: criterion.id, status: criterion.status })) },
118
+ });
119
+ }
@@ -0,0 +1,12 @@
1
+ import { type UlwLoopScope } from "./paths.js";
2
+ import type { UlwLoopCodexGoalMode, UlwLoopItem, UlwLoopPlan, UlwLoopSuccessCriterion } from "./types.js";
3
+ export declare const ULW_LOOP_AGGREGATE_CODEX_OBJECTIVE: string;
4
+ export declare function aggregateCodexObjectiveForScope(scope?: UlwLoopScope): string;
5
+ export declare function codexGoalMode(plan: UlwLoopPlan): UlwLoopCodexGoalMode;
6
+ export declare function isUlwLoopDone(plan: UlwLoopPlan): boolean;
7
+ export declare function isFinalRunCompletionCandidate(plan: UlwLoopPlan, goal: UlwLoopItem): boolean;
8
+ export declare function aggregateCodexObjective(plan: UlwLoopPlan): string;
9
+ export declare function expectedCodexObjective(plan: UlwLoopPlan, goal: UlwLoopItem): string;
10
+ export declare function compatibleCodexObjectives(plan: UlwLoopPlan): readonly string[];
11
+ export declare function hasAllCriteriaPass(goal: UlwLoopItem): boolean;
12
+ export declare function firstUnresolvedCriterion(goal: UlwLoopItem): UlwLoopSuccessCriterion | undefined;