lazycodex-ai 5.0.0-beta.4 → 5.0.0-beta.40

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 (538) hide show
  1. package/README.ja.md +25 -21
  2. package/README.ko.md +25 -21
  3. package/README.md +38 -23
  4. package/README.ru.md +24 -20
  5. package/README.zh-cn.md +25 -21
  6. package/dist/cli/config-manager/parse-opencode-config-file.d.ts +2 -1
  7. package/dist/cli/doctor/checks/system-plugin.d.ts +4 -3
  8. package/dist/cli/fallback-lane-policy.d.ts +1 -0
  9. package/dist/cli/index.js +66932 -64746
  10. package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +1 -1
  11. package/dist/cli/run/on-complete-hook.d.ts +2 -0
  12. package/dist/cli/runtime-commands.d.ts +1 -1
  13. package/dist/cli/worktree-sweep/classify.d.ts +16 -0
  14. package/dist/cli/worktree-sweep/format.d.ts +8 -0
  15. package/dist/cli/worktree-sweep/git.d.ts +19 -0
  16. package/dist/cli/worktree-sweep/index.d.ts +7 -0
  17. package/dist/cli/worktree-sweep/options.d.ts +2 -0
  18. package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
  19. package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
  20. package/dist/cli/worktree-sweep/types.d.ts +65 -0
  21. package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
  22. package/dist/cli-node/index.js +66795 -64586
  23. package/package.json +9 -9
  24. package/packages/git-bash-mcp/dist/cli.js +6 -1
  25. package/packages/lsp-daemon/dist/cli.js +793 -323
  26. package/packages/lsp-daemon/dist/client.d.ts +10 -0
  27. package/packages/lsp-daemon/dist/client.js +753 -280
  28. package/packages/lsp-daemon/dist/daemon-client.d.ts +1 -0
  29. package/packages/lsp-daemon/dist/daemon-client.js +3 -0
  30. package/packages/lsp-daemon/dist/ensure-daemon.js +1 -0
  31. package/packages/lsp-daemon/dist/index.js +757 -289
  32. package/packages/lsp-daemon/dist/proxy.js +3 -0
  33. package/packages/lsp-daemon/dist/version-reap.js +1 -1
  34. package/packages/lsp-daemon/package.json +1 -1
  35. package/packages/lsp-tools-mcp/dist/cli.js +712 -244
  36. package/packages/lsp-tools-mcp/dist/lsp/manager.js +248 -119
  37. package/packages/lsp-tools-mcp/dist/mcp.js +714 -246
  38. package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
  39. package/packages/lsp-tools-mcp/dist/tools.js +718 -254
  40. package/packages/lsp-tools-mcp/package.json +1 -1
  41. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -6
  42. package/packages/omo-codex/plugin/.mcp.json +0 -6
  43. package/packages/omo-codex/plugin/AGENTS.md +47 -0
  44. package/packages/omo-codex/plugin/README.md +2 -2
  45. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +45 -49
  46. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  47. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  48. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -0
  49. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
  50. package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
  51. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
  52. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  53. package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
  54. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
  55. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
  56. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
  57. package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
  58. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
  59. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  60. package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
  61. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
  62. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +1 -5
  63. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +1 -5
  64. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  65. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -5
  66. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +1 -5
  67. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +4 -21
  68. package/packages/omo-codex/plugin/components/lcx/skills/lcx-doctor/SKILL.md +1 -1
  69. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
  70. package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
  71. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
  72. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +741 -294
  73. package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
  74. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  75. package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
  76. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  77. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
  78. package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
  79. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
  80. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
  81. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
  82. package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
  83. package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
  84. package/packages/omo-codex/plugin/components/rules/dist/cli.js +60 -45
  85. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  86. package/packages/omo-codex/plugin/components/rules/package.json +7 -7
  87. package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
  88. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
  89. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +9 -5
  90. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
  91. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
  92. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
  93. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
  94. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
  95. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
  96. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
  97. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
  98. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
  99. package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
  100. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
  101. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
  102. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
  103. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +1 -2
  104. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
  105. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
  106. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
  107. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
  108. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +5 -6
  109. package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
  110. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
  111. package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
  112. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
  113. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  114. package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
  115. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +4 -10
  116. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
  117. package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
  118. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2463 -437
  119. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2467 -441
  120. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  121. package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
  122. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
  123. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
  124. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
  125. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
  126. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -4
  127. package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
  128. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +489 -4
  129. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  130. package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -6
  131. package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +30 -14
  132. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -7
  133. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
  134. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
  135. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
  136. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +4 -0
  137. package/packages/omo-codex/plugin/components/ultrawork/src/directive.ts +5 -2
  138. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
  139. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
  140. package/packages/omo-codex/plugin/components/ultrawork/test/directive-source.test.ts +14 -8
  141. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +12 -1
  142. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
  143. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +2 -2
  144. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
  145. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +5 -5
  146. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
  147. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +6 -6
  148. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +12 -12
  149. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +28 -0
  150. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
  151. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
  152. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
  153. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +3 -3
  154. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
  155. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
  156. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
  157. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +1 -4
  158. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +8 -22
  159. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +19 -0
  160. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -1
  161. package/packages/omo-codex/plugin/components/ulw-loop/README.md +12 -1
  162. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
  163. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +15 -3
  164. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +12 -0
  165. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +45 -0
  166. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +9 -0
  167. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +15 -0
  168. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +15 -1
  169. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.d.ts +8 -0
  170. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +120 -0
  171. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +40 -39
  172. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +7 -2
  173. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +2 -1
  174. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +12 -1
  175. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +2 -0
  176. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +958 -342
  177. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +2 -0
  178. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +27 -6
  179. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +13 -0
  180. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +15 -1
  181. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +17 -9
  182. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +1 -1
  183. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +17 -2
  184. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.d.ts +13 -0
  185. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.js +19 -0
  186. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +7 -0
  187. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +9 -0
  188. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.d.ts +12 -0
  189. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +104 -0
  190. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.d.ts +13 -1
  191. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +65 -9
  192. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +5 -1
  193. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
  194. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +69 -111
  195. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +4 -2
  196. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +185 -14
  197. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.d.ts +6 -0
  198. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.js +33 -0
  199. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +3 -3
  200. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +18 -0
  201. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +65 -0
  202. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  203. package/packages/omo-codex/plugin/components/ulw-loop/package.json +5 -5
  204. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +3 -2
  205. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
  206. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +22 -1
  207. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +81 -0
  208. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +7 -0
  209. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +31 -1
  210. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +134 -0
  211. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +38 -71
  212. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +7 -2
  213. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +14 -1
  214. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +2 -0
  215. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +3 -5
  216. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +34 -5
  217. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +26 -1
  218. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
  219. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +19 -9
  220. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +1 -1
  221. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +18 -3
  222. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-missing-recovery.ts +27 -0
  223. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +11 -0
  224. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +123 -0
  225. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +68 -15
  226. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +6 -1
  227. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +82 -131
  228. package/packages/omo-codex/plugin/components/ulw-loop/src/review-blockers.ts +4 -2
  229. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +187 -12
  230. package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +36 -0
  231. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +3 -3
  232. package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +95 -0
  233. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
  234. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +133 -1
  235. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +137 -0
  236. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +25 -0
  237. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +26 -2
  238. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-status-next-actions.test.ts +183 -0
  239. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +37 -2
  240. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +18 -0
  241. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
  242. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +7 -3
  243. package/packages/omo-codex/plugin/components/ulw-loop/test/guided-recovery.test.ts +105 -0
  244. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
  245. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
  246. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate-basics.test.ts +258 -0
  247. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-cap-and-dedupe.test.ts +22 -0
  248. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-poisoning-cascades.test.ts +97 -0
  249. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +46 -2
  250. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-senpi-surface.test.ts +131 -0
  251. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-single-report.test.ts +241 -0
  252. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +48 -3
  253. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +318 -1
  254. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
  255. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  256. package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -0
  257. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +13 -8
  258. package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
  259. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  260. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  261. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  262. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  263. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  264. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  265. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  266. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  267. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  268. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  269. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  270. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  271. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  272. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  273. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +17 -0
  274. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  275. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +17 -0
  276. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  277. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  278. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  279. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  280. package/packages/omo-codex/plugin/model-catalog.json +3 -3
  281. package/packages/omo-codex/plugin/package-lock.json +676 -524
  282. package/packages/omo-codex/plugin/package.json +2 -3
  283. package/packages/omo-codex/plugin/scripts/AGENTS.md +39 -0
  284. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -2
  285. package/packages/omo-codex/plugin/scripts/auto-update.mjs +0 -9
  286. package/packages/omo-codex/plugin/scripts/canonical-ultrawork-directive.mjs +17 -0
  287. package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +0 -1
  288. package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +3 -3
  289. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +36 -13
  290. package/packages/omo-codex/plugin/shared/package.json +3 -4
  291. package/packages/omo-codex/plugin/shared/src/config-loader.ts +2 -102
  292. package/packages/omo-codex/plugin/shared/src/config-migration.ts +0 -1
  293. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +41 -130
  294. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
  295. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
  296. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +3 -2
  297. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  298. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +4 -4
  299. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  300. package/packages/omo-codex/plugin/skills/data-scientist/SKILL.md +99 -239
  301. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-surfaces.md +91 -0
  302. package/packages/omo-codex/plugin/skills/data-scientist/references/placement.md +74 -0
  303. package/packages/omo-codex/plugin/skills/data-scientist/references/polars-lane.md +95 -0
  304. package/packages/omo-codex/plugin/skills/data-scientist/references/uv-setup.md +1 -1
  305. package/packages/omo-codex/plugin/skills/data-scientist/references/visualization.md +64 -0
  306. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  307. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  308. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +2 -0
  309. package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +12 -0
  310. package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +21 -0
  311. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +15 -1
  312. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +38 -0
  313. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +25 -0
  314. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +13 -0
  315. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +41 -0
  316. package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +267 -0
  317. package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  318. package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +103 -0
  319. package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +193 -0
  320. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +11 -7
  321. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
  322. package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
  323. package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
  324. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
  325. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  326. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  327. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  328. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
  329. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
  330. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +13 -13
  331. package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +1 -1
  332. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +4 -4
  333. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  334. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +2 -0
  335. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  336. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
  337. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  338. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  339. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +15 -3
  340. package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +19 -26
  341. package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
  342. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +3 -2
  343. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
  344. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +22 -1
  345. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -7
  346. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
  347. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
  348. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
  349. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +4 -2
  350. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
  351. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +3 -2
  352. package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
  353. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
  354. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +9 -48
  355. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +2 -3
  356. package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +2 -7
  357. package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +1 -1
  358. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
  359. package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
  360. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
  361. package/packages/omo-codex/plugin/test/auto-update.test.mjs +2 -27
  362. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +0 -31
  363. package/packages/omo-codex/plugin/test/canonical-ultrawork-directive.test.mjs +53 -0
  364. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
  365. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -51
  366. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +2 -2
  367. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +4 -5
  368. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
  369. package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -3
  370. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +8 -8
  371. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
  372. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +101 -0
  373. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +23 -13
  374. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +14 -119
  375. package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
  376. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
  377. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
  378. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
  379. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
  380. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +5 -5
  381. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
  382. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2817 -913
  383. package/packages/{omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md → prompts-core/prompts/ultrawork/codex.md} +15 -10
  384. package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
  385. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
  386. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +3 -2
  387. package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  388. package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +4 -4
  389. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  390. package/packages/shared-skills/skills/data-scientist/SKILL.md +99 -239
  391. package/packages/shared-skills/skills/data-scientist/references/execution-surfaces.md +91 -0
  392. package/packages/shared-skills/skills/data-scientist/references/placement.md +74 -0
  393. package/packages/shared-skills/skills/data-scientist/references/polars-lane.md +95 -0
  394. package/packages/shared-skills/skills/data-scientist/references/uv-setup.md +1 -1
  395. package/packages/shared-skills/skills/data-scientist/references/visualization.md +64 -0
  396. package/packages/shared-skills/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  397. package/packages/shared-skills/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  398. package/packages/shared-skills/skills/debugging/SKILL.md +2 -0
  399. package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +12 -0
  400. package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +21 -0
  401. package/packages/shared-skills/skills/debugging/references/runtimes/go.md +15 -1
  402. package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +38 -0
  403. package/packages/shared-skills/skills/debugging/references/runtimes/node.md +25 -0
  404. package/packages/shared-skills/skills/debugging/references/runtimes/python.md +13 -0
  405. package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +41 -0
  406. package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +267 -0
  407. package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +86 -0
  408. package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  409. package/packages/shared-skills/skills/debugging/references/tools/dap.md +103 -0
  410. package/packages/shared-skills/skills/debugging/references/tools/frida.md +193 -0
  411. package/packages/shared-skills/skills/frontend/SKILL.md +11 -7
  412. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
  413. package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
  414. package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
  415. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
  416. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  417. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  418. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  419. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
  420. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
  421. package/packages/shared-skills/skills/init-deep/SKILL.md +13 -13
  422. package/packages/shared-skills/skills/review-work/SKILL.md +3 -3
  423. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  424. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +2 -0
  425. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  426. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
  427. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  428. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  429. package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +17 -16
  430. package/packages/shared-skills/skills/ulw-plan/SKILL.md +6 -7
  431. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +31 -7
  432. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
  433. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
  434. package/packages/shared-skills/skills/ulw-research/SKILL.md +4 -2
  435. package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
  436. package/packages/shared-skills/skills/visual-qa/SKILL.md +3 -2
  437. package/script/qa/web-terminal-visual-qa.mjs +2 -0
  438. package/script/qa/xterm-live-terminal.mjs +18 -2
  439. package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
  440. package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
  441. package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
  442. package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
  443. package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
  444. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +0 -58
  445. package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +0 -2951
  446. package/packages/omo-codex/plugin/components/codegraph/NOTICE +0 -16
  447. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +0 -12136
  448. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9734
  449. package/packages/omo-codex/plugin/components/codegraph/package.json +0 -33
  450. package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +0 -29
  451. package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +0 -79
  452. package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +0 -33
  453. package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +0 -25
  454. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +0 -131
  455. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +0 -258
  456. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +0 -309
  457. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +0 -80
  458. package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +0 -34
  459. package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +0 -29
  460. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +0 -263
  461. package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +0 -106
  462. package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +0 -145
  463. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +0 -21
  464. package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +0 -139
  465. package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +0 -15
  466. package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +0 -32
  467. package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +0 -109
  468. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +0 -148
  469. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +0 -175
  470. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +0 -81
  471. package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +0 -34
  472. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +0 -112
  473. package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +0 -26
  474. package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +0 -160
  475. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +0 -50
  476. package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +0 -29
  477. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +0 -320
  478. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +0 -172
  479. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +0 -91
  480. package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +0 -100
  481. package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +0 -76
  482. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +0 -133
  483. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +0 -245
  484. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +0 -69
  485. package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +0 -43
  486. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +0 -147
  487. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +0 -175
  488. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +0 -385
  489. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +0 -206
  490. package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +0 -58
  491. package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +0 -104
  492. package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +0 -65
  493. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +0 -106
  494. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +0 -116
  495. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +0 -258
  496. package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +0 -56
  497. package/packages/omo-codex/plugin/components/codegraph/tsconfig.build.json +0 -13
  498. package/packages/omo-codex/plugin/components/codegraph/tsconfig.json +0 -25
  499. package/packages/omo-codex/plugin/components/start-work-continuation/LICENSE +0 -21
  500. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
  501. package/packages/omo-codex/plugin/components/ultrawork/directive.md +0 -471
  502. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +0 -18
  503. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +0 -17
  504. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
  505. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
  506. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/editor.mjs +0 -125
  507. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/jsonc.mjs +0 -43
  508. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/scaffold.mjs +0 -29
  509. package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +0 -121
  510. package/packages/omo-codex/plugin/skills/data-scientist/references/common-scenarios.md +0 -176
  511. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-templates.md +0 -197
  512. package/packages/omo-codex/plugin/skills/data-scientist/references/integration-patterns.md +0 -153
  513. package/packages/omo-codex/plugin/skills/data-scientist/references/performance-benchmarks.md +0 -37
  514. package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
  515. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
  516. package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +0 -76
  517. package/packages/omo-codex/plugin/test/migrate-omo-sot.test.mjs +0 -179
  518. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
  519. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
  520. package/packages/shared-skills/skills/data-scientist/references/common-scenarios.md +0 -176
  521. package/packages/shared-skills/skills/data-scientist/references/execution-templates.md +0 -197
  522. package/packages/shared-skills/skills/data-scientist/references/integration-patterns.md +0 -153
  523. package/packages/shared-skills/skills/data-scientist/references/performance-benchmarks.md +0 -37
  524. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
  525. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
  526. /package/packages/omo-codex/plugin/components/{codegraph → ulw-execute-continuation}/LICENSE +0 -0
  527. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
  528. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +0 -0
  529. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
  530. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
  531. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
  532. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
  533. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
  534. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
  535. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
  536. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
  537. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
  538. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
@@ -1,142 +1,74 @@
1
- import { resolve } from "node:path";
2
- import { isWithinAttemptDir } from "./paths.js";
3
- import { emptyBlockers, invalid, literal, numberField, section, stringArray, textField, } from "./quality-gate-fields.js";
1
+ import { artifactCompatible, artifactMap, checkFile, compatibleKindsFor, parseArtifactRefs, referencedArtifacts, surfaceField, } from "./quality-gate-artifacts.js";
2
+ import { emptyBlockers, invalid, isPoisoned, isPoisonedArtifactKind, literal, numberField, section, stringArray, textField, withQualityGateCollector, } from "./quality-gate-fields.js";
4
3
  import { adversarialVerdict, codeQualityStatusField, passedVerdict } from "./quality-gate-verdicts.js";
5
- const REVIEWER_ROLES = {
6
- codeReview: "lazycodex-code-reviewer",
7
- manualQa: "lazycodex-qa-executor",
8
- gateReview: "lazycodex-gate-reviewer",
9
- };
4
+ import { GATE_SECTION_BY_ACCEPTOR } from "./surface.js";
10
5
  export { classifyExternalAuthorizationBlocker, clearGoalBlockerFields, normalizeBlockerEvidence, sameBlockerOccurrences, } from "./quality-gate-blockers.js";
11
6
  function reviewerRoleField(value, expected, field) {
7
+ if (typeof value !== "string" || value.trim() === "") {
8
+ textField(value, field);
9
+ return expected;
10
+ }
12
11
  const actual = textField(value, field);
13
12
  if (actual !== expected)
14
13
  invalid(`${field} must be ${expected}.`, field);
15
14
  return expected;
16
15
  }
17
- function surfaceField(value, field) {
18
- if (value === "cli" ||
19
- value === "http" ||
20
- value === "tmux" ||
21
- value === "browser" ||
22
- value === "gui" ||
23
- value === "data")
24
- return value;
25
- invalid(`${field} must be a supported manual QA surface.`, field);
26
- }
27
- function kindField(value, field) {
28
- if (value === "cli-transcript" ||
29
- value === "log" ||
30
- value === "screenshot" ||
31
- value === "image" ||
32
- value === "http-dump" ||
33
- value === "data-diff")
34
- return value;
35
- invalid(`${field} must be a supported artifact kind.`, field);
36
- }
37
- function artifactCompatible(surface, kind) {
38
- switch (surface) {
39
- case "cli":
40
- case "tmux":
41
- return kind === "cli-transcript" || kind === "log";
42
- case "http":
43
- return kind === "http-dump";
44
- case "browser":
45
- case "gui":
46
- return kind === "screenshot" || kind === "image";
47
- case "data":
48
- return kind === "data-diff";
49
- default:
50
- invalid("manualQa.surfaceEvidence has an unsupported surface.", "manualQa.surfaceEvidence.surface");
51
- }
52
- }
53
- function checkFile(path, field, opts) {
54
- if (opts === undefined)
55
- return;
56
- const absolute = resolve(opts.repoRoot, path);
57
- if (!opts.fs.existsSync(absolute))
58
- invalid(`${field} must point to an existing artifact.`, field);
59
- if (opts.fs.statSync(absolute).size <= 0)
60
- invalid(`${field} must point to a non-empty artifact.`, field);
61
- if (opts.currentAttemptDir !== undefined) {
62
- const attemptRoot = resolve(opts.repoRoot, opts.currentAttemptDir);
63
- if (!isWithinAttemptDir(absolute, attemptRoot))
64
- invalid(`${field} (${path}) must point to an artifact from the current attempt (${opts.currentAttemptDir}).`, field);
16
+ function reviewerAcceptorField(value, surface, sectionName) {
17
+ const field = `${sectionName}.by`;
18
+ const accepted = GATE_SECTION_BY_ACCEPTOR[surface][sectionName];
19
+ if (typeof value !== "string" || value.trim() === "") {
20
+ textField(value, field);
21
+ return accepted?.[0] ?? "";
65
22
  }
66
- }
67
- function artifactMap(refs) {
68
- const byId = new Map();
69
- for (const ref of refs) {
70
- if (byId.has(ref.id))
71
- invalid(`manualQa.artifactRefs contains duplicate ${ref.id}.`, "manualQa.artifactRefs");
72
- byId.set(ref.id, ref);
73
- }
74
- return byId;
75
- }
76
- function parseArtifactRefs(value, opts) {
77
- if (!Array.isArray(value) || value.length === 0)
78
- invalid("manualQa.artifactRefs must not be empty.", "manualQa.artifactRefs");
79
- return value.map((item, index) => {
80
- const ref = section(item, `manualQa.artifactRefs[${index}]`);
81
- const path = textField(ref["path"], `manualQa.artifactRefs[${index}].path`);
82
- checkFile(path, `manualQa.artifactRefs[${index}].path`, opts);
83
- return {
84
- id: textField(ref["id"], `manualQa.artifactRefs[${index}].id`),
85
- kind: kindField(ref["kind"], `manualQa.artifactRefs[${index}].kind`),
86
- description: textField(ref["description"], `manualQa.artifactRefs[${index}].description`),
87
- path,
88
- };
89
- });
90
- }
91
- function referencedArtifacts(value, field, byId) {
92
- return stringArray(value, field).map((id) => {
93
- const artifact = byId.get(id);
94
- if (artifact === undefined)
95
- invalid(`${field} references unknown artifact ${id}.`, field);
96
- return artifact;
97
- });
23
+ const actual = textField(value, field);
24
+ if (accepted === undefined || !accepted.includes(actual))
25
+ invalid(`${field} must be one of ${accepted?.join(", ") ?? "the configured reviewers"}.`, field);
26
+ return actual;
98
27
  }
99
28
  export function validateQualityGate(input, opts) {
29
+ return withQualityGateCollector(() => validateQualityGateUncollected(input, opts));
30
+ }
31
+ function validateQualityGateUncollected(input, opts) {
32
+ const surface = opts?.reviewerSurface ?? "lazycodex";
100
33
  const gate = section(input, "qualityGate");
101
- const codeReview = section(gate["codeReview"], "codeReview");
34
+ if (surface === "omo-senpi" && gate["codeReview"] !== undefined)
35
+ invalid("omo-senpi gate has no codeReview lane.", "codeReview");
102
36
  const manualQa = section(gate["manualQa"], "manualQa");
103
37
  const gateReview = section(gate["gateReview"], "gateReview");
104
38
  const iteration = section(gate["iteration"], "iteration");
105
39
  const coverage = section(gate["criteriaCoverage"], "criteriaCoverage");
40
+ const codeReview = surface === "lazycodex" ? section(gate["codeReview"], "codeReview") : {};
41
+ const manualQaBy = reviewerAcceptorField(manualQa["by"], surface, "manualQa");
42
+ const gateReviewBy = reviewerAcceptorField(gateReview["by"], surface, "gateReview");
43
+ const manualQaEvidence = textField(manualQa["evidence"], "manualQa.evidence");
44
+ const gateReviewEvidence = textField(gateReview["evidence"], "gateReview.evidence");
45
+ if (surface === "lazycodex")
46
+ reviewerRoleField(codeReview?.["by"], "lazycodex-code-reviewer", "codeReview.by");
106
47
  const totalCriteria = numberField(coverage["totalCriteria"], "criteriaCoverage.totalCriteria");
107
48
  const passCount = numberField(coverage["passCount"], "criteriaCoverage.passCount");
108
- if (passCount < totalCriteria)
49
+ if (!isPoisoned("criteriaCoverage.passCount") && passCount < totalCriteria)
109
50
  invalid("criteriaCoverage.passCount must cover totalCriteria.", "criteriaCoverage.passCount");
110
51
  const artifactRefs = parseArtifactRefs(manualQa["artifactRefs"], opts);
111
52
  const byId = artifactMap(artifactRefs);
112
53
  const surfaceEvidence = parseSurfaceEvidence(manualQa["surfaceEvidence"], byId);
113
54
  const adversarialCases = parseAdversarialCases(manualQa["adversarialCases"], byId);
114
- const codeReportPath = textField(codeReview["reportPath"], "codeReview.reportPath");
115
55
  const gateReportPath = textField(gateReview["reportPath"], "gateReview.reportPath");
116
- checkFile(codeReportPath, "codeReview.reportPath", opts);
117
- checkFile(gateReportPath, "gateReview.reportPath", opts);
118
- return {
119
- codeReview: {
120
- by: reviewerRoleField(codeReview["by"], REVIEWER_ROLES.codeReview, "codeReview.by"),
121
- recommendation: literal(codeReview["recommendation"], "APPROVE", "codeReview.recommendation"),
122
- codeQualityStatus: codeQualityStatusField(codeReview["codeQualityStatus"], "codeReview.codeQualityStatus"),
123
- reportPath: codeReportPath,
124
- evidence: textField(codeReview["evidence"], "codeReview.evidence"),
125
- blockers: emptyBlockers(codeReview["blockers"], "codeReview.blockers"),
126
- },
56
+ if (!isPoisoned("gateReview.reportPath"))
57
+ checkFile(gateReportPath, "gateReview.reportPath", opts);
58
+ const common = {
127
59
  manualQa: {
128
- by: reviewerRoleField(manualQa["by"], REVIEWER_ROLES.manualQa, "manualQa.by"),
60
+ by: manualQaBy,
129
61
  status: literal(manualQa["status"], "passed", "manualQa.status"),
130
- evidence: textField(manualQa["evidence"], "manualQa.evidence"),
62
+ evidence: manualQaEvidence,
131
63
  surfaceEvidence,
132
64
  adversarialCases,
133
65
  artifactRefs,
134
66
  },
135
67
  gateReview: {
136
- by: reviewerRoleField(gateReview["by"], REVIEWER_ROLES.gateReview, "gateReview.by"),
68
+ by: gateReviewBy,
137
69
  recommendation: literal(gateReview["recommendation"], "APPROVE", "gateReview.recommendation"),
138
70
  reportPath: gateReportPath,
139
- evidence: textField(gateReview["evidence"], "gateReview.evidence"),
71
+ evidence: gateReviewEvidence,
140
72
  blockers: emptyBlockers(gateReview["blockers"], "gateReview.blockers"),
141
73
  },
142
74
  iteration: {
@@ -154,17 +86,39 @@ export function validateQualityGate(input, opts) {
154
86
  adversarialClassesCovered: stringArray(coverage["adversarialClassesCovered"], "criteriaCoverage.adversarialClassesCovered"),
155
87
  },
156
88
  };
89
+ if (surface === "omo-senpi")
90
+ return { surface, ...common };
91
+ const codeReportPath = textField(codeReview["reportPath"], "codeReview.reportPath");
92
+ checkFile(codeReportPath, "codeReview.reportPath", opts);
93
+ return {
94
+ surface,
95
+ ...common,
96
+ codeReview: {
97
+ by: "lazycodex-code-reviewer",
98
+ recommendation: literal(codeReview["recommendation"], "APPROVE", "codeReview.recommendation"),
99
+ codeQualityStatus: codeQualityStatusField(codeReview["codeQualityStatus"], "codeReview.codeQualityStatus"),
100
+ reportPath: codeReportPath,
101
+ evidence: textField(codeReview["evidence"], "codeReview.evidence"),
102
+ blockers: emptyBlockers(codeReview["blockers"], "codeReview.blockers"),
103
+ },
104
+ };
157
105
  }
158
106
  function parseSurfaceEvidence(value, byId) {
159
- if (!Array.isArray(value) || value.length === 0)
107
+ if (!Array.isArray(value) || value.length === 0) {
160
108
  invalid("manualQa.surfaceEvidence must not be empty.", "manualQa.surfaceEvidence");
161
- return value.map((item, index) => {
109
+ return [];
110
+ }
111
+ return value.flatMap((item, index) => {
162
112
  const row = section(item, `manualQa.surfaceEvidence[${index}]`);
113
+ if (isPoisoned(`manualQa.surfaceEvidence[${index}]`))
114
+ return [];
163
115
  const surface = surfaceField(row["surface"], `manualQa.surfaceEvidence[${index}].surface`);
164
116
  const artifacts = referencedArtifacts(row["artifactRefs"], `manualQa.surfaceEvidence[${index}].artifactRefs`, byId);
165
117
  for (const artifact of artifacts) {
118
+ if (isPoisoned(`manualQa.surfaceEvidence[${index}].surface`) || isPoisonedArtifactKind(artifact.id))
119
+ continue;
166
120
  if (!artifactCompatible(surface, artifact.kind)) {
167
- invalid(`manualQa.surfaceEvidence ${surface} artifact ${artifact.kind} is incompatible.`, "manualQa.surfaceEvidence");
121
+ invalid(`manualQa.surfaceEvidence ${surface} artifact ${artifact.kind} is incompatible; surface "${surface}" accepts artifact kinds: ${compatibleKindsFor(surface).join(", ")}.`, "manualQa.surfaceEvidence");
168
122
  }
169
123
  }
170
124
  return {
@@ -178,10 +132,14 @@ function parseSurfaceEvidence(value, byId) {
178
132
  });
179
133
  }
180
134
  function parseAdversarialCases(value, byId) {
181
- if (!Array.isArray(value) || value.length === 0)
135
+ if (!Array.isArray(value) || value.length === 0) {
182
136
  invalid("manualQa.adversarialCases must not be empty.", "manualQa.adversarialCases");
183
- return value.map((item, index) => {
137
+ return [];
138
+ }
139
+ return value.flatMap((item, index) => {
184
140
  const row = section(item, `manualQa.adversarialCases[${index}]`);
141
+ if (isPoisoned(`manualQa.adversarialCases[${index}]`))
142
+ return [];
185
143
  const artifacts = referencedArtifacts(row["artifactRefs"], `manualQa.adversarialCases[${index}].artifactRefs`, byId);
186
144
  const verdictInfo = adversarialVerdict(row, `manualQa.adversarialCases[${index}]`);
187
145
  return {
@@ -1,4 +1,5 @@
1
1
  // biome-ignore-all format: compact port must stay within the requested pure LOC budget.
2
+ import { codexSnapshotMismatchError } from "./checkpoint-reconciliation.js";
2
3
  import { readCodexGoalSnapshotInput, reconcileCodexGoalSnapshot } from "./codex-goal-snapshot.js";
3
4
  import { codexGoalMode, compatibleCodexObjectives, expectedCodexObjective, isFinalRunCompletionCandidate } from "./goal-status.js";
4
5
  import { seedDefaultSuccessCriteria } from "./plan-crud.js";
@@ -42,9 +43,10 @@ export async function recordFinalReviewBlockers(repoRoot, args, scope) {
42
43
  ulwLoopError(`${goal.id} is not final.`, "ulw_loop_not_final_story");
43
44
  const snapshot = await readCodexGoalSnapshotInput(args.codexGoalJson, repoRoot);
44
45
  const aggregate = codexGoalMode(plan) === "aggregate";
45
- const reconciliation = reconcileCodexGoalSnapshot(snapshot, { expectedObjective: expectedCodexObjective(plan, goal), ...(aggregate ? { acceptedObjectives: compatibleCodexObjectives(plan) } : {}), allowedStatuses: ["active"], requireSnapshot: true, requireComplete: false });
46
+ const expected = expectedCodexObjective(plan, goal);
47
+ const reconciliation = reconcileCodexGoalSnapshot(snapshot, { expectedObjective: expected, ...(aggregate ? { acceptedObjectives: compatibleCodexObjectives(plan) } : {}), allowedStatuses: ["active"], requireSnapshot: true, requireComplete: false });
46
48
  if (!reconciliation.ok)
47
- ulwLoopError(reconciliation.errors.join(" "), "ulw_loop_codex_snapshot_mismatch");
49
+ throw codexSnapshotMismatchError({ reconciliation, snapshot, expectedObjective: expected });
48
50
  const now = iso();
49
51
  for (const field of BLOCKER_FIELDS)
50
52
  Reflect.deleteProperty(goal, field);
@@ -1,14 +1,23 @@
1
- import { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
2
- import { join } from "node:path";
1
+ import { randomBytes } from "node:crypto";
2
+ import { existsSync, mkdirSync, openSync, readdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
3
+ import { dirname, join } from "node:path";
3
4
  import { parsePreToolUsePayload } from "./codex-hook.js";
4
5
  import { isFinalRunCompletionCandidate } from "./goal-status.js";
5
6
  import { ulwLoopAttemptEvidenceDir, ulwLoopDir } from "./paths.js";
7
+ import { GATE_REVIEWER_AGENT_NAMES, REVIEWER_ROLES_BY_SURFACE, resolveToolkitSurface, reviewerRolesFor, } from "./surface.js";
6
8
  // spawn_agent = v1; collaborationspawn_agent = the delimiter-free flattened v2
7
9
  // hook token from codex-rs hook_names.rs; collaboration.spawn_agent = the
8
10
  // dotted token observed live in the task-1 probe (hook-tool-tokens.txt).
9
11
  const SPAWN_TOOL_TOKENS = new Set(["spawn_agent", "collaborationspawn_agent", "collaboration.spawn_agent"]);
10
12
  const DEFAULT_FANOUT_LIMIT = 60;
11
- const GATE_MESSAGE_PATTERN = /lazycodex-gate-reviewer|final gate review/i;
13
+ const DEFAULT_REVIEW_SPAWN_LIMIT = 3;
14
+ const GATE_MESSAGE_PATTERN = /lazycodex-gate-reviewer|omo-senpi-gate-reviewer|final gate review/i;
15
+ const REVIEW_AGENT_TYPES = [
16
+ ...Object.values(REVIEWER_ROLES_BY_SURFACE).map((roles) => roles.gateReview),
17
+ ...Object.values(REVIEWER_ROLES_BY_SURFACE).map((roles) => roles.codeReview),
18
+ ...Object.values(REVIEWER_ROLES_BY_SURFACE).map((roles) => roles.manualQa),
19
+ ];
20
+ const REVIEW_AGENT_TYPE_SET = new Set(REVIEW_AGENT_TYPES);
12
21
  export function applySpawnGuards(payload) {
13
22
  if (payload.hook_event_name !== "PreToolUse" || !SPAWN_TOOL_TOKENS.has(payload.tool_name))
14
23
  return "";
@@ -16,12 +25,18 @@ export function applySpawnGuards(payload) {
16
25
  const plan = readPlan(join(stateDir, "goals.json"));
17
26
  if (plan === null)
18
27
  return "";
19
- const fanOutDenial = consumeFanOutBudget(stateDir);
20
- if (fanOutDenial !== null)
21
- return deny(fanOutDenial);
28
+ const fanOutPeek = peekFanOutBudget(stateDir);
29
+ if (fanOutPeek !== null)
30
+ return deny(fanOutPeek);
22
31
  const missingArtifact = missingGateArtifact(payload, plan);
23
32
  if (missingArtifact !== null)
24
33
  return deny(`spawn code-review + QA first; gate audits their artifacts: missing ${missingArtifact}`);
34
+ const reviewDenial = consumeReviewSpawnBudget(payload, plan, stateDir);
35
+ if (reviewDenial !== null)
36
+ return deny(reviewDenial);
37
+ const fanOutDenial = consumeFanOutBudget(stateDir);
38
+ if (fanOutDenial !== null)
39
+ return deny(fanOutDenial);
25
40
  return "";
26
41
  }
27
42
  export async function runSpawnGuardCli(stdin, stdout) {
@@ -41,17 +56,51 @@ export async function runSpawnGuardCli(stdin, stdout) {
41
56
  return;
42
57
  }
43
58
  }
59
+ // Read-only fan-out eligibility check. Returns a denial reason when the next
60
+ // spawn would exceed the limit, without incrementing the counter. Call this
61
+ // before charging any per-reviewer quota so a saturated global cap cannot
62
+ // silently consume reviewer allowances for spawns that will never run.
63
+ function peekFanOutBudget(stateDir) {
64
+ const counterPath = join(stateDir, "spawn-count.json");
65
+ const count = readCount(counterPath) + 1;
66
+ const limit = fanOutLimit();
67
+ if (count <= limit)
68
+ return null;
69
+ return `ulw-loop spawn fan-out cap reached (${count}/${limit}). Consolidate work into the agents already running, or raise OMO_SPAWN_FANOUT_LIMIT if this volume is intentional.`;
70
+ }
44
71
  // Per-session spawn counter; depth/lineage tracking is descoped — this is a
45
72
  // total-volume backstop against fan-out explosions, not a recursion tracker.
46
73
  function consumeFanOutBudget(stateDir) {
47
74
  const counterPath = join(stateDir, "spawn-count.json");
48
75
  const count = readCount(counterPath) + 1;
49
- writeFileSync(counterPath, JSON.stringify({ count }));
76
+ atomicWriteJson(counterPath, { count });
50
77
  const limit = fanOutLimit();
51
78
  if (count <= limit)
52
79
  return null;
53
80
  return `ulw-loop spawn fan-out cap reached (${count}/${limit}). Consolidate work into the agents already running, or raise OMO_SPAWN_FANOUT_LIMIT if this volume is intentional.`;
54
81
  }
82
+ function consumeReviewSpawnBudget(payload, plan, stateDir) {
83
+ const agentType = reviewAgentType(payload.tool_input);
84
+ if (agentType === null)
85
+ return null;
86
+ const goal = plan.goals.find((candidate) => candidate.id === plan.activeGoalId) ??
87
+ plan.goals.find((candidate) => isFinalRunCompletionCandidate(plan, candidate));
88
+ if (goal === undefined)
89
+ return null;
90
+ const counterPath = join(stateDir, "review-spawn-counts.json");
91
+ const lockPath = `${counterPath}.lock`;
92
+ const limit = reviewSpawnLimit();
93
+ return withExclusiveLock(lockPath, () => {
94
+ const counts = readCounts(counterPath);
95
+ const key = `${agentType}:${goal.id}:a${goal.attempt}`;
96
+ const count = (counts[key] ?? 0) + 1;
97
+ if (count > limit)
98
+ return `ulw-loop reviewer no-progress cap reached (${agentType} ${count}/${limit}) for ${goal.id} attempt ${goal.attempt}. Consolidate existing review findings, or checkpoint and start a new attempt after concrete progress.`;
99
+ counts[key] = count;
100
+ atomicWriteJson(counterPath, counts);
101
+ return null;
102
+ });
103
+ }
55
104
  function missingGateArtifact(payload, plan) {
56
105
  if (!isGateReviewerSpawn(payload.tool_input))
57
106
  return null;
@@ -61,9 +110,11 @@ function missingGateArtifact(payload, plan) {
61
110
  if (!goal.successCriteria.every((criterion) => criterion.status === "pass"))
62
111
  return null;
63
112
  const scope = { sessionId: payload.session_id };
113
+ const surface = resolveToolkitSurface();
114
+ const requiredArtifacts = surface === "omo-senpi" ? [`${goal.id}-manual-qa.md`] : [`${goal.id}-code-review.md`, `${goal.id}-manual-qa.md`];
64
115
  if (plan.evidenceLayoutVersion === 2) {
65
116
  const attemptDir = ulwLoopAttemptEvidenceDir(goal.id, goal.attempt, scope);
66
- for (const name of [`${goal.id}-code-review.md`, `${goal.id}-manual-qa.md`]) {
117
+ for (const name of requiredArtifacts) {
67
118
  const relative = `${attemptDir}/${name}`;
68
119
  if (!isNonEmptyFile(join(payload.cwd, relative)))
69
120
  return relative;
@@ -71,22 +122,117 @@ function missingGateArtifact(payload, plan) {
71
122
  return null;
72
123
  }
73
124
  const flatReport = `.omo/evidence/${goal.id}-code-review.md`;
74
- if (!isNonEmptyFile(join(payload.cwd, flatReport)))
125
+ if (surface !== "omo-senpi" && !isNonEmptyFile(join(payload.cwd, flatReport)))
75
126
  return flatReport;
127
+ if (surface === "omo-senpi") {
128
+ const manualQa = `.omo/evidence/${goal.id}-manual-qa.md`;
129
+ return isNonEmptyFile(join(payload.cwd, manualQa)) ? null : manualQa;
130
+ }
76
131
  // v1 manual-QA approximation: any other non-empty evidence file counts.
77
132
  if (!hasOtherEvidenceFile(join(payload.cwd, ".omo", "evidence"), `${goal.id}-code-review.md`))
78
- return `.omo/evidence/<any manual-QA artifact besides ${goal.id}-code-review.md>`;
133
+ return `.omo/evidence/${goal.id}-manual-qa.md`;
79
134
  return null;
80
135
  }
81
136
  function isGateReviewerSpawn(toolInput) {
137
+ const agentType = reviewAgentType(toolInput);
138
+ return agentType !== null && GATE_REVIEWER_AGENT_NAMES.has(agentType);
139
+ }
140
+ function reviewAgentType(toolInput) {
82
141
  if (typeof toolInput !== "object" || toolInput === null)
83
- return false;
142
+ return null;
84
143
  const record = toolInput;
85
144
  const agentType = record["agent_type"];
86
- if (typeof agentType === "string")
87
- return agentType === "lazycodex-gate-reviewer";
145
+ if (typeof agentType === "string") {
146
+ // V1: agent_type is present — only reviewer types proceed; any other type is not a review spawn.
147
+ if (!REVIEW_AGENT_TYPE_SET.has(agentType))
148
+ return null;
149
+ return activeSurfaceReviewerAlias(agentType);
150
+ }
88
151
  const message = record["message"];
89
- return typeof message === "string" && GATE_MESSAGE_PATTERN.test(message);
152
+ if (typeof message !== "string")
153
+ return null;
154
+ const normalizedMessage = message.toLowerCase();
155
+ // Explicit "act as <role>" assignment takes priority. If the assigned role is not a reviewer,
156
+ // treat the spawn as non-review so a message that merely mentions a reviewer name does not
157
+ // accidentally charge that reviewer's quota.
158
+ const allRoleNames = [...REVIEW_AGENT_TYPES];
159
+ const explicitAssignment = allRoleNames
160
+ .map((name) => ({
161
+ name,
162
+ index: normalizedMessage.search(new RegExp(`\\bact as (?:an? )?${name}\\b`)),
163
+ }))
164
+ .filter(({ index }) => index >= 0)
165
+ .sort((left, right) => left.index - right.index)[0];
166
+ if (explicitAssignment !== undefined)
167
+ return activeSurfaceReviewerAlias(explicitAssignment.name);
168
+ // Check for an explicit "act as <non-reviewer-role>" assignment. If found, the spawn is not a
169
+ // review spawn even if the message body mentions a reviewer name.
170
+ const nonReviewerActAs = /\bact as (?:an? )?\S+/.test(normalizedMessage);
171
+ if (nonReviewerActAs)
172
+ return null;
173
+ const namedReviewer = REVIEW_AGENT_TYPES.find((name) => normalizedMessage.includes(name));
174
+ if (namedReviewer !== undefined)
175
+ return activeSurfaceReviewerAlias(namedReviewer);
176
+ return GATE_MESSAGE_PATTERN.test(message) ? reviewerRolesFor(resolveToolkitSurface()).gateReview : null;
177
+ }
178
+ function activeSurfaceReviewerAlias(reviewer) {
179
+ const activeRoles = reviewerRolesFor(resolveToolkitSurface());
180
+ for (const roles of Object.values(REVIEWER_ROLES_BY_SURFACE)) {
181
+ if (reviewer === roles.codeReview)
182
+ return activeRoles.codeReview;
183
+ if (reviewer === roles.manualQa)
184
+ return activeRoles.manualQa;
185
+ if (reviewer === roles.gateReview)
186
+ return activeRoles.gateReview;
187
+ }
188
+ return reviewer;
189
+ }
190
+ function withExclusiveLock(lockPath, fn) {
191
+ mkdirSync(dirname(lockPath), { recursive: true });
192
+ const maxAttempts = 10;
193
+ const baseDelayMs = 10;
194
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
195
+ let fd = null;
196
+ try {
197
+ fd = openSync(lockPath, "wx");
198
+ writeFileSync(fd, process.pid.toString());
199
+ try {
200
+ return fn();
201
+ }
202
+ finally {
203
+ try {
204
+ unlinkSync(lockPath);
205
+ }
206
+ catch {
207
+ /* empty */
208
+ }
209
+ }
210
+ }
211
+ catch (error) {
212
+ if (fd !== null) {
213
+ try {
214
+ unlinkSync(lockPath);
215
+ }
216
+ catch {
217
+ /* empty */
218
+ }
219
+ }
220
+ if (error.code !== "EEXIST") {
221
+ return fn();
222
+ }
223
+ const delayMs = baseDelayMs * 2 ** attempt + Math.random() * baseDelayMs;
224
+ const deadline = Date.now() + delayMs;
225
+ while (Date.now() < deadline) {
226
+ /* spin */
227
+ }
228
+ }
229
+ }
230
+ return fn();
231
+ }
232
+ function atomicWriteJson(targetPath, data) {
233
+ const tmp = join(dirname(targetPath), `.tmp-${randomBytes(6).toString("hex")}`);
234
+ writeFileSync(tmp, JSON.stringify(data));
235
+ renameSync(tmp, targetPath);
90
236
  }
91
237
  function deny(reason) {
92
238
  return `${JSON.stringify({
@@ -105,6 +251,13 @@ function fanOutLimit() {
105
251
  const parsed = Number.parseInt(raw, 10);
106
252
  return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_FANOUT_LIMIT;
107
253
  }
254
+ function reviewSpawnLimit() {
255
+ const raw = process.env["OMO_ULW_LOOP_REVIEW_SPAWN_LIMIT"];
256
+ if (raw === undefined)
257
+ return DEFAULT_REVIEW_SPAWN_LIMIT;
258
+ const parsed = Number.parseInt(raw, 10);
259
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_REVIEW_SPAWN_LIMIT;
260
+ }
108
261
  function isNonEmptyFile(path) {
109
262
  try {
110
263
  return existsSync(path) && statSync(path).size > 0;
@@ -136,6 +289,24 @@ function readCount(counterPath) {
136
289
  throw error;
137
290
  }
138
291
  }
292
+ function readCounts(counterPath) {
293
+ try {
294
+ const parsed = JSON.parse(readFileSync(counterPath, "utf8"));
295
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
296
+ return {};
297
+ const counts = {};
298
+ for (const [key, value] of Object.entries(parsed)) {
299
+ if (typeof value === "number" && value >= 0)
300
+ counts[key] = value;
301
+ }
302
+ return counts;
303
+ }
304
+ catch (error) {
305
+ if (error instanceof Error)
306
+ return {};
307
+ throw error;
308
+ }
309
+ }
139
310
  function readPlan(goalsPath) {
140
311
  try {
141
312
  return JSON.parse(readFileSync(goalsPath, "utf8"));
@@ -0,0 +1,6 @@
1
+ import type { UlwLoopPlan } from "./types.js";
2
+ /**
3
+ * `status --json` is the one call every agent already makes between steps, so it is
4
+ * also the cheapest place to answer "what now?" without a second round trip.
5
+ */
6
+ export declare function statusNextActions(plan: UlwLoopPlan): readonly string[];
@@ -0,0 +1,33 @@
1
+ import { hasAllCriteriaPass, isFinalRunCompletionCandidate } from "./goal-status.js";
2
+ import { ULW_LOOP_CREATE_GOALS_COMMAND } from "./plan-missing-recovery.js";
3
+ /**
4
+ * `status --json` is the one call every agent already makes between steps, so it is
5
+ * also the cheapest place to answer "what now?" without a second round trip.
6
+ */
7
+ export function statusNextActions(plan) {
8
+ const actions = [];
9
+ const active = plan.goals.find((goal) => goal.id === plan.activeGoalId);
10
+ if (plan.goals.length === 0)
11
+ actions.push(`No goals yet: bootstrap with \`${ULW_LOOP_CREATE_GOALS_COMMAND}\`.`);
12
+ else if (active !== undefined)
13
+ actions.push(...activeGoalActions(plan, active));
14
+ for (const goal of plan.goals.filter((candidate) => candidate.status === "review_blocked"))
15
+ actions.push(`${goal.id} is review_blocked: capture the reviewer verdict with \`omo-agent-toolkit ulw-loop record-review-blockers --goal-id ${goal.id} --title "<title>" --objective "<objective>" --evidence "<verdict>" --codex-goal-json '<get_goal json>'\`.`);
16
+ if (plan.evidenceLayoutVersion !== 2 || active === undefined)
17
+ actions.push("plan is evidence-layout v1; artifacts go under .omo/evidence/");
18
+ return actions;
19
+ }
20
+ function activeGoalActions(plan, active) {
21
+ const unresolved = active.successCriteria.filter((criterion) => criterion.status !== "pass");
22
+ if (unresolved.length > 0)
23
+ return [
24
+ `${active.id} has ${unresolved.length} unresolved criterion(s) (${unresolved.map((criterion) => criterion.id).join(", ")}): record proof with \`omo-agent-toolkit ulw-loop record-evidence --goal-id ${active.id} --criterion-id <id> --status pass --evidence "<observable proof>"\`.`,
25
+ ];
26
+ if (hasAllCriteriaPass(active) && isFinalRunCompletionCandidate(plan, active))
27
+ return [
28
+ `${active.id} passes every criterion and is the final story: update_goal complete, then checkpoint --print-template to build the final quality gate.`,
29
+ ];
30
+ return [
31
+ `${active.id} passes every criterion: close it with \`omo-agent-toolkit ulw-loop checkpoint --goal-id ${active.id} --status complete --evidence "<proof>" --codex-goal-json '<get_goal json>'\`.`,
32
+ ];
33
+ }
@@ -5,7 +5,7 @@ import { normalizeUlwLoopSessionId, ulwLoopDir } from "./paths.js";
5
5
  // dies mid-turn (crash, kill, context blowup before any Stop) never reaches
6
6
  // this handler. Mid-turn stalls are out of scope by design.
7
7
  const RESUME_CAP = 2;
8
- // Mirrors start-work-continuation's context-pressure bail-out: injecting a
8
+ // Mirrors ulw-execute-continuation's context-pressure bail-out: injecting a
9
9
  // resume directive into an already-overflowing context makes things worse.
10
10
  const CONTEXT_PRESSURE_MARKERS = [
11
11
  "context compacted",
@@ -132,7 +132,7 @@ function readCounter(counterPath) {
132
132
  throw error;
133
133
  }
134
134
  }
135
- // Local ~10-LOC approximation of start-work-continuation's boulder check (no
135
+ // Local ~10-LOC approximation of ulw-execute-continuation's boulder check (no
136
136
  // cross-component import allowed): any continuable work for this session means
137
137
  // that hook owns the Stop event, so this one stays silent.
138
138
  function boulderContinuationWillFire(cwd, sessionId) {
@@ -167,7 +167,7 @@ function transcriptShowsContextPressure(transcriptPath) {
167
167
  throw error;
168
168
  }
169
169
  }
170
- // start-work-continuation owns an active Boulder plan until its final gate marks
170
+ // ulw-execute-continuation owns an active Boulder plan until its final gate marks
171
171
  // the work complete, including the zero-remaining checklist state.
172
172
  function boulderPlanHasChecklist(cwd, entry) {
173
173
  const activePlan = entry["active_plan"];
@@ -0,0 +1,18 @@
1
+ export type UlwLoopToolkitSurface = "lazycodex" | "omo-senpi";
2
+ export interface UlwLoopReviewerRoles {
3
+ readonly codeReview: string;
4
+ readonly manualQa: string;
5
+ readonly gateReview: string;
6
+ }
7
+ export declare const REVIEWER_ROLES_BY_SURFACE: Readonly<Record<UlwLoopToolkitSurface, UlwLoopReviewerRoles>>;
8
+ export declare const GATE_REVIEWER_AGENT_NAMES: ReadonlySet<string>;
9
+ export type UlwLoopGateSection = "codeReview" | "manualQa" | "gateReview" | "iteration" | "criteriaCoverage";
10
+ export declare const REQUIRED_GATE_SECTIONS_BY_SURFACE: Readonly<Record<UlwLoopToolkitSurface, readonly UlwLoopGateSection[]>>;
11
+ export declare const GATE_SECTION_BY_ACCEPTOR: Readonly<Record<UlwLoopToolkitSurface, Readonly<Partial<Record<UlwLoopGateSection, readonly string[]>>>>>;
12
+ export declare function reviewerRolesFor(surface: UlwLoopToolkitSurface): UlwLoopReviewerRoles;
13
+ export declare const SURFACE_MARKER_FILENAME = "surface.json";
14
+ export interface ResolveToolkitSurfaceOptions {
15
+ readonly env?: Readonly<Record<string, string | undefined>>;
16
+ readonly entryDir?: string;
17
+ }
18
+ export declare function resolveToolkitSurface(options?: ResolveToolkitSurfaceOptions): UlwLoopToolkitSurface;