oh-my-opencode 5.0.0-beta.6 → 5.0.0-beta.62

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 (997) hide show
  1. package/.agents/command/publish.md +59 -23
  2. package/.agents/skills/codex-qa/scripts/lsp-e2e.sh +1 -3
  3. package/.agents/skills/opencode-qa/scripts/lsp-e2e.sh +1 -1
  4. package/.agents/skills/pre-publish-review/SKILL.md +9 -12
  5. package/.agents/skills/publish/SKILL.md +59 -23
  6. package/.agents/skills/senpi-qa/SKILL.md +80 -0
  7. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.mjs +65 -0
  8. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs +171 -0
  9. package/.agents/skills/tech-debt-audit/SKILL.md +6 -76
  10. package/.agents/skills/work-with-pr/SKILL.md +37 -23
  11. package/.opencode/command/publish.md +59 -23
  12. package/.opencode/skills/pre-publish-review/SKILL.md +9 -12
  13. package/.opencode/skills/work-with-pr/SKILL.md +37 -23
  14. package/README.ja.md +65 -60
  15. package/README.ko.md +66 -61
  16. package/README.md +65 -72
  17. package/README.ru.md +62 -60
  18. package/README.zh-cn.md +61 -60
  19. package/THIRD-PARTY-NOTICES.md +27 -99
  20. package/dist/agents/atlas/agent.d.ts +0 -1
  21. package/dist/agents/gpt-prompt-identity.d.ts +1 -1
  22. package/dist/agents/sisyphus/grok-4.d.ts +20 -0
  23. package/dist/agents/sisyphus/index.d.ts +2 -0
  24. package/dist/agents/sisyphus-agent-config.d.ts +6 -0
  25. package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
  26. package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +15 -4
  27. package/dist/agents/types.d.ts +4 -2
  28. package/dist/cli/config-manager/parse-opencode-config-file.d.ts +2 -1
  29. package/dist/cli/doctor/checks/index.d.ts +2 -0
  30. package/dist/cli/doctor/checks/latest-version.d.ts +11 -0
  31. package/dist/cli/doctor/checks/system-plugin.d.ts +4 -3
  32. package/dist/cli/doctor/framework/constants.d.ts +5 -0
  33. package/dist/cli/doctor/framework/types.d.ts +2 -0
  34. package/dist/cli/fallback-lane-policy.d.ts +1 -0
  35. package/dist/cli/index.js +52548 -60412
  36. package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +1 -1
  37. package/dist/cli/run/on-complete-hook.d.ts +2 -0
  38. package/dist/cli/runtime-commands.d.ts +1 -1
  39. package/dist/cli/worktree-sweep/classify.d.ts +16 -0
  40. package/dist/cli/worktree-sweep/format.d.ts +8 -0
  41. package/dist/cli/worktree-sweep/git.d.ts +19 -0
  42. package/dist/cli/worktree-sweep/index.d.ts +7 -0
  43. package/dist/cli/worktree-sweep/options.d.ts +2 -0
  44. package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
  45. package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
  46. package/dist/cli/worktree-sweep/types.d.ts +65 -0
  47. package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
  48. package/dist/cli-node/index.js +51202 -59043
  49. package/dist/config/index.d.ts +1 -1
  50. package/dist/config/schema/background-task.d.ts +1 -0
  51. package/dist/config/schema/commands.d.ts +1 -1
  52. package/dist/config/schema/hooks.d.ts +1 -2
  53. package/dist/config/schema/oh-my-opencode-config.d.ts +5 -11
  54. package/dist/config/schema/ulw-execute.d.ts +5 -0
  55. package/dist/config/schema.d.ts +0 -1
  56. package/dist/config/validate.d.ts +2 -0
  57. package/dist/create-hooks.d.ts +3 -2
  58. package/dist/features/background-agent/compaction-aware-message-resolver.d.ts +1 -0
  59. package/dist/features/background-agent/constants.d.ts +0 -7
  60. package/dist/features/background-agent/error-classifier.d.ts +1 -0
  61. package/dist/features/background-agent/manager.d.ts +9 -1
  62. package/dist/features/background-agent/parent-wake-dispatched-tracker.d.ts +0 -1
  63. package/dist/features/background-agent/parent-wake-notifier-types.d.ts +1 -1
  64. package/dist/features/background-agent/parent-wake-prompt-dispatch.d.ts +1 -1
  65. package/dist/features/background-agent/parent-wake-session-inspector.d.ts +1 -1
  66. package/dist/features/background-agent/subagent-spawn-limits.d.ts +8 -0
  67. package/dist/features/background-agent/types.d.ts +4 -0
  68. package/dist/features/btw-side/btw-command-draft.d.ts +7 -0
  69. package/dist/features/btw-side/context-injector.d.ts +15 -0
  70. package/dist/features/btw-side/index.d.ts +8 -0
  71. package/dist/features/btw-side/metadata.d.ts +15 -0
  72. package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
  73. package/dist/features/btw-side/server-session-registry.d.ts +8 -0
  74. package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
  75. package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
  76. package/dist/features/btw-side/tui-controller-types.d.ts +68 -0
  77. package/dist/features/btw-side/tui-controller.d.ts +19 -0
  78. package/dist/features/btw-side/tui-escape-return.d.ts +12 -0
  79. package/dist/features/btw-side/tui-keymap.d.ts +17 -0
  80. package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
  81. package/dist/features/btw-side/tui-picker-options.d.ts +20 -0
  82. package/dist/features/btw-side/tui-picker.d.ts +9 -0
  83. package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
  84. package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
  85. package/dist/features/btw-side/tui-session-catalog.d.ts +35 -0
  86. package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
  87. package/dist/features/btw-side/tui-side-start.d.ts +9 -0
  88. package/dist/features/btw-side/tui-wiring.d.ts +8 -0
  89. package/dist/features/builtin-commands/templates/ulw-execute.d.ts +1 -0
  90. package/dist/features/builtin-commands/types.d.ts +1 -1
  91. package/dist/features/claude-tasks/storage.d.ts +7 -2
  92. package/dist/features/hook-message-injector/index.d.ts +1 -0
  93. package/dist/features/hook-message-injector/sdk-message-lookup.d.ts +1 -0
  94. package/dist/features/monitor/manager-internals.d.ts +1 -1
  95. package/dist/features/monitor/output-injector-types.d.ts +1 -1
  96. package/dist/features/opengateway-provider/index.d.ts +13 -0
  97. package/dist/features/task-toast-manager/manager.d.ts +0 -24
  98. package/dist/features/team-mode/tools/messaging-fallback-wake.d.ts +17 -0
  99. package/dist/features/team-mode/tools/messaging-live-delivery-recipient.d.ts +3 -0
  100. package/dist/features/team-mode/tools/messaging-runtime.d.ts +7 -0
  101. package/dist/hooks/anthropic-context-window-limit-recovery/message-storage-directory.d.ts +0 -3
  102. package/dist/hooks/anthropic-context-window-limit-recovery/state.d.ts +1 -0
  103. package/dist/hooks/anthropic-context-window-limit-recovery/storage/empty-messages.d.ts +0 -1
  104. package/dist/hooks/anthropic-context-window-limit-recovery/tool-result-storage.d.ts +11 -0
  105. package/dist/hooks/atlas/atlas-hook.d.ts +1 -0
  106. package/dist/hooks/atlas/atlas-lifecycle-store.d.ts +50 -0
  107. package/dist/hooks/atlas/event-handler.d.ts +1 -0
  108. package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
  109. package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
  110. package/dist/hooks/atlas/tool-execute-before.d.ts +3 -0
  111. package/dist/hooks/atlas/types.d.ts +1 -0
  112. package/dist/hooks/claude-code-hooks/session-hook-state.d.ts +1 -0
  113. package/dist/hooks/claude-code-hooks/stop.d.ts +2 -0
  114. package/dist/hooks/claude-code-hooks/todo.d.ts +0 -1
  115. package/dist/hooks/claude-code-hooks/transcript.d.ts +2 -0
  116. package/dist/hooks/compaction-context-injector/validated-model.d.ts +2 -0
  117. package/dist/hooks/fsync-skip-warning/index.d.ts +4 -0
  118. package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +1 -0
  119. package/dist/hooks/hashline-edit-diff-enhancer/pending-captures.d.ts +13 -0
  120. package/dist/hooks/index.d.ts +1 -2
  121. package/dist/hooks/keyword-detector/hook.d.ts +9 -0
  122. package/dist/hooks/keyword-detector/ultrawork/index.d.ts +2 -0
  123. package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +0 -1
  124. package/dist/hooks/model-fallback/hook.d.ts +1 -1
  125. package/dist/hooks/prometheus-md-only/agent-resolution.d.ts +2 -2
  126. package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
  127. package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
  128. package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
  129. package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
  130. package/dist/hooks/runtime-fallback/types.d.ts +3 -1
  131. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  132. package/dist/hooks/todo-continuation-enforcer/types.d.ts +1 -0
  133. package/dist/hooks/{start-work → ulw-execute}/context-info-builder.d.ts +1 -1
  134. package/dist/hooks/{start-work → ulw-execute}/index.d.ts +1 -1
  135. package/dist/hooks/ulw-execute/ulw-execute-hook.d.ts +23 -0
  136. package/dist/hooks/unstable-agent-babysitter/task-message-analyzer.d.ts +1 -0
  137. package/dist/index.js +29256 -25391
  138. package/dist/mcp/index.d.ts +0 -4
  139. package/dist/mcp/types.d.ts +0 -1
  140. package/dist/oh-my-opencode.schema.json +21 -47
  141. package/dist/plugin/chat-message/types.d.ts +6 -4
  142. package/dist/plugin/chat-message/ulw-execute-message.d.ts +5 -0
  143. package/dist/plugin/event-session-lifecycle.d.ts +1 -0
  144. package/dist/plugin/hooks/create-core-hooks.d.ts +2 -2
  145. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -3
  146. package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
  147. package/dist/plugin/messages-transform.d.ts +1 -0
  148. package/dist/plugin/stop-continuation.d.ts +3 -0
  149. package/dist/plugin/system-transform.d.ts +5 -1
  150. package/dist/plugin-dispose.d.ts +3 -0
  151. package/dist/shared/agent-tool-restrictions.d.ts +0 -1
  152. package/dist/shared/compaction-agent-config-checkpoint.d.ts +1 -0
  153. package/dist/shared/index.d.ts +2 -0
  154. package/dist/shared/legacy-plugin-warning.d.ts +2 -1
  155. package/dist/shared/normalize-sdk-response.d.ts +1 -0
  156. package/dist/shared/omo-process-sweep.d.ts +2 -4
  157. package/dist/shared/plugin-entry-migrator.d.ts +4 -3
  158. package/dist/shared/plugin-entry-shape.d.ts +6 -0
  159. package/dist/shared/runtime-fallback-retry-marker.d.ts +16 -0
  160. package/dist/shared/shell-env.d.ts +1 -1
  161. package/dist/skills/ast-grep/AGENTS.md +51 -0
  162. package/dist/skills/ast-grep/SKILL.md +1 -1
  163. package/dist/skills/coding-agent-sessions/AGENTS.md +62 -0
  164. package/dist/skills/coding-agent-sessions/SKILL.md +1 -1
  165. package/dist/skills/data-scientist/SKILL.md +99 -239
  166. package/dist/skills/data-scientist/references/execution-surfaces.md +91 -0
  167. package/dist/skills/data-scientist/references/placement.md +74 -0
  168. package/dist/skills/data-scientist/references/polars-lane.md +95 -0
  169. package/dist/skills/data-scientist/references/uv-setup.md +1 -1
  170. package/dist/skills/data-scientist/references/visualization.md +64 -0
  171. package/dist/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  172. package/dist/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  173. package/dist/skills/debugging/SKILL.md +3 -1
  174. package/dist/skills/debugging/references/methodology/00-setup.md +12 -0
  175. package/dist/skills/debugging/references/methodology/02-investigate.md +21 -0
  176. package/dist/skills/debugging/references/runtimes/go.md +15 -1
  177. package/dist/skills/debugging/references/runtimes/native-binary.md +38 -0
  178. package/dist/skills/debugging/references/runtimes/node.md +25 -0
  179. package/dist/skills/debugging/references/runtimes/python.md +13 -0
  180. package/dist/skills/debugging/references/runtimes/rust.md +41 -0
  181. package/dist/skills/debugging/references/scripts/dap.mjs +267 -0
  182. package/dist/skills/debugging/references/scripts/dap.test.ts +86 -0
  183. package/dist/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  184. package/dist/skills/debugging/references/tools/dap.md +103 -0
  185. package/dist/skills/debugging/references/tools/frida.md +193 -0
  186. package/dist/skills/frontend/ATTRIBUTION.md +10 -0
  187. package/dist/skills/frontend/SKILL.md +15 -8
  188. package/dist/skills/frontend/references/design/README.md +10 -2
  189. package/dist/skills/frontend/references/design/_INDEX.md +2 -0
  190. package/dist/skills/frontend/references/design/ambience-skill.md +145 -0
  191. package/dist/skills/frontend/references/design/interaction-skill.md +2 -0
  192. package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
  193. package/dist/skills/frontend/references/design/stylegallery.md +80 -0
  194. package/dist/skills/frontend/references/designpowers/README.md +1 -1
  195. package/dist/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  196. package/dist/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  197. package/dist/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  198. package/dist/skills/frontend/references/designpowers/orchestration.md +1 -1
  199. package/dist/skills/frontend/references/designpowers/routing.md +5 -5
  200. package/dist/skills/git-master/SKILL.md +1 -1
  201. package/dist/skills/init-deep/SKILL.md +14 -14
  202. package/dist/skills/lsp-setup/SKILL.md +1 -1
  203. package/dist/skills/programming/SKILL.md +1 -1
  204. package/dist/skills/refactor/SKILL.md +4 -4
  205. package/dist/skills/remove-ai-slops/SKILL.md +1 -1
  206. package/dist/skills/review-work/SKILL.md +101 -419
  207. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
  208. package/dist/skills/ultimate-browsing/SKILL.md +26 -9
  209. package/dist/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  210. package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
  211. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
  212. package/dist/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  213. package/dist/skills/{start-work → ulw-execute}/SKILL.md +20 -19
  214. package/dist/skills/ulw-plan/SKILL.md +7 -8
  215. package/dist/skills/ulw-plan/references/full-workflow.md +31 -7
  216. package/dist/skills/ulw-plan/references/intent-clear.md +2 -1
  217. package/dist/skills/ulw-plan/references/intent-unclear.md +5 -5
  218. package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
  219. package/dist/skills/ulw-research/SKILL.md +8 -3
  220. package/dist/skills/visual-qa/AGENTS.md +58 -0
  221. package/dist/skills/visual-qa/SKILL.md +4 -3
  222. package/dist/tools/delegate-task/builtin-categories.d.ts +3 -1
  223. package/dist/tools/delegate-task/builtin-category-definition.d.ts +2 -1
  224. package/dist/tools/delegate-task/constants.d.ts +2 -2
  225. package/dist/tools/delegate-task/openai-categories.d.ts +7 -2
  226. package/dist/tools/delegate-task/sync-session-cleanup.d.ts +3 -0
  227. package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -0
  228. package/dist/tools/delegate-task/tool-description.d.ts +3 -1
  229. package/dist/tools/delegate-task/types.d.ts +4 -0
  230. package/dist/tools/session-manager/directory-filter.d.ts +2 -0
  231. package/dist/tui.d.ts +12 -0
  232. package/dist/tui.js +37048 -46599
  233. package/package.json +47 -41
  234. package/packages/git-bash-mcp/dist/cli.js +6 -1
  235. package/packages/git-bash-mcp/package.json +1 -1
  236. package/packages/lsp-core/src/index.ts +1 -0
  237. package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +44 -0
  238. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +57 -48
  239. package/packages/lsp-core/src/lsp/client-diagnostics-pull-timeout.test.ts +64 -0
  240. package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
  241. package/packages/lsp-core/src/lsp/client-wrapper.test.ts +103 -6
  242. package/packages/lsp-core/src/lsp/client-wrapper.ts +50 -16
  243. package/packages/lsp-core/src/lsp/client.ts +32 -3
  244. package/packages/lsp-core/src/lsp/connection.ts +16 -0
  245. package/packages/lsp-core/src/lsp/constants.ts +6 -0
  246. package/packages/lsp-core/src/lsp/controlled-clock-test-support.ts +61 -0
  247. package/packages/lsp-core/src/lsp/errors.ts +15 -0
  248. package/packages/lsp-core/src/lsp/fixtures/workspace-edit-server.mjs +10 -3
  249. package/packages/lsp-core/src/lsp/format-document.test.ts +143 -0
  250. package/packages/lsp-core/src/lsp/format-document.ts +90 -0
  251. package/packages/lsp-core/src/lsp/json-rpc-connection.ts +11 -6
  252. package/packages/lsp-core/src/lsp/manager-lifecycle.test.ts +262 -0
  253. package/packages/lsp-core/src/lsp/manager-max-clients.test.ts +151 -0
  254. package/packages/lsp-core/src/lsp/manager.ts +138 -12
  255. package/packages/lsp-core/src/lsp/outside-context-workspace.ts +33 -0
  256. package/packages/lsp-core/src/lsp/server-definitions.ts +29 -0
  257. package/packages/lsp-core/src/lsp/server-installation.test.ts +376 -0
  258. package/packages/lsp-core/src/lsp/server-installation.ts +200 -27
  259. package/packages/lsp-core/src/lsp/server-resolution-local-binary.test.ts +170 -0
  260. package/packages/lsp-core/src/lsp/server-resolution.ts +18 -5
  261. package/packages/lsp-core/src/lsp/timer-provider.ts +13 -0
  262. package/packages/lsp-core/src/lsp/transport-request-timeout.test.ts +73 -0
  263. package/packages/lsp-core/src/lsp/transport.ts +16 -2
  264. package/packages/lsp-core/src/lsp/types.ts +8 -0
  265. package/packages/lsp-core/src/lsp/workspace-apply-edit-test-support.ts +29 -1
  266. package/packages/lsp-core/src/lsp/workspace-document-state.test.ts +84 -1
  267. package/packages/lsp-core/src/lsp/workspace-document-state.ts +30 -11
  268. package/packages/lsp-core/src/lsp/workspace-markers.ts +18 -0
  269. package/packages/lsp-core/src/mcp.ts +3 -0
  270. package/packages/lsp-core/src/request-context.test.ts +29 -0
  271. package/packages/lsp-core/src/request-context.ts +1 -1
  272. package/packages/lsp-core/src/tool-surface.test.ts +13 -1
  273. package/packages/lsp-core/src/tools/definitions.ts +14 -0
  274. package/packages/lsp-core/src/tools/format.test.ts +56 -0
  275. package/packages/lsp-core/src/tools/format.ts +56 -0
  276. package/packages/lsp-core/src/tools/index.ts +1 -0
  277. package/packages/lsp-core/src/tools/parameters.test.ts +51 -0
  278. package/packages/lsp-core/src/tools/types.ts +10 -0
  279. package/packages/lsp-daemon/dist/cli.js +902 -479
  280. package/packages/lsp-daemon/dist/client.d.ts +10 -0
  281. package/packages/lsp-daemon/dist/client.js +920 -493
  282. package/packages/lsp-daemon/dist/daemon-client.d.ts +1 -0
  283. package/packages/lsp-daemon/dist/daemon-client.js +3 -0
  284. package/packages/lsp-daemon/dist/ensure-daemon.d.ts +6 -1
  285. package/packages/lsp-daemon/dist/ensure-daemon.js +10 -2
  286. package/packages/lsp-daemon/dist/index.js +824 -402
  287. package/packages/lsp-daemon/dist/ownership.js +2 -2
  288. package/packages/lsp-daemon/dist/proxy.js +3 -0
  289. package/packages/lsp-daemon/dist/version-reap.js +1 -1
  290. package/packages/lsp-daemon/package.json +1 -1
  291. package/packages/lsp-tools-mcp/dist/cli.js +762 -341
  292. package/packages/lsp-tools-mcp/dist/lsp/manager.js +272 -138
  293. package/packages/lsp-tools-mcp/dist/mcp.js +787 -368
  294. package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
  295. package/packages/lsp-tools-mcp/dist/tools.js +717 -302
  296. package/packages/lsp-tools-mcp/package.json +1 -1
  297. package/packages/omo-codex/THIRD-PARTY-NOTICES.md +4 -21
  298. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -6
  299. package/packages/omo-codex/plugin/.mcp.json +0 -6
  300. package/packages/omo-codex/plugin/AGENTS.md +47 -0
  301. package/packages/omo-codex/plugin/README.md +6 -2
  302. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +7093 -408
  303. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  304. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  305. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -0
  306. package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +7 -1
  307. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
  308. package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
  309. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
  310. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  311. package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
  312. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
  313. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
  314. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
  315. package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
  316. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
  317. package/packages/omo-codex/plugin/components/git-bash/dist/cli.js +1 -1
  318. package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.js +2 -1
  319. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  320. package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
  321. package/packages/omo-codex/plugin/components/git-bash/src/codex-hook.ts +2 -1
  322. package/packages/omo-codex/plugin/components/git-bash/test/codex-hook.test.ts +6 -7
  323. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/AGENTS.md +2 -2
  324. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
  325. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/directive.md +2 -0
  326. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +36 -29
  327. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +32 -26
  328. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/types.d.ts +3 -0
  329. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  330. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -5
  331. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +32 -28
  332. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/types.ts +3 -0
  333. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/cli.test.ts +1 -1
  334. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +137 -28
  335. package/packages/omo-codex/plugin/components/lcx/skills/lcx-doctor/SKILL.md +4 -2
  336. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
  337. package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
  338. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
  339. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +941 -540
  340. package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
  341. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  342. package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
  343. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  344. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
  345. package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
  346. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
  347. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
  348. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
  349. package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
  350. package/packages/omo-codex/plugin/components/rules/README.md +2 -0
  351. package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
  352. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-6.md +123 -0
  353. package/packages/omo-codex/plugin/components/rules/dist/cli.js +91 -68
  354. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  355. package/packages/omo-codex/plugin/components/rules/package.json +7 -7
  356. package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
  357. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
  358. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +15 -5
  359. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
  360. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
  361. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
  362. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
  363. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
  364. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
  365. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
  366. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
  367. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
  368. package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
  369. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
  370. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
  371. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
  372. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +38 -3
  373. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
  374. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
  375. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
  376. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
  377. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +29 -6
  378. package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
  379. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
  380. package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
  381. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
  382. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  383. package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
  384. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +4 -10
  385. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
  386. package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
  387. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2407 -684
  388. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2411 -689
  389. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  390. package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
  391. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
  392. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
  393. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
  394. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
  395. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -4
  396. package/packages/omo-codex/plugin/components/ultrawork/README.md +2 -0
  397. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -1
  398. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +1 -1
  399. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +1 -1
  400. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
  401. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-qa-executor.toml +1 -1
  402. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +1 -1
  403. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-low.toml +1 -1
  404. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +1 -1
  405. package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +1 -1
  406. package/packages/omo-codex/plugin/components/ultrawork/agents/metis.toml +1 -1
  407. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +1 -1
  408. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -1
  409. package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
  410. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +499 -4
  411. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  412. package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -6
  413. package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +30 -14
  414. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -7
  415. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
  416. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
  417. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
  418. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +4 -0
  419. package/packages/omo-codex/plugin/components/ultrawork/src/directive.ts +5 -2
  420. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
  421. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
  422. package/packages/omo-codex/plugin/components/ultrawork/test/directive-source.test.ts +14 -8
  423. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +12 -1
  424. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
  425. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +4 -4
  426. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
  427. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +6 -6
  428. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
  429. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +10 -10
  430. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +16 -16
  431. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +16 -0
  432. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
  433. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
  434. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
  435. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +4 -4
  436. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
  437. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
  438. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +1 -1
  439. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
  440. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +4 -11
  441. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +24 -22
  442. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +19 -0
  443. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +3 -1
  444. package/packages/omo-codex/plugin/components/ulw-loop/README.md +12 -1
  445. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
  446. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +46 -24
  447. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +16 -0
  448. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +25 -0
  449. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +10 -4
  450. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +2 -5
  451. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +5 -78
  452. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.d.ts +12 -0
  453. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +114 -0
  454. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.d.ts +7 -1
  455. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +50 -42
  456. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.js +2 -2
  457. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +21 -8
  458. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +2 -1
  459. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +12 -1
  460. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.d.ts +1 -1
  461. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +40 -37
  462. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +1468 -535
  463. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +2 -0
  464. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +28 -8
  465. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +2 -5
  466. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +24 -20
  467. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.d.ts +1 -0
  468. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.js +1 -0
  469. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +17 -9
  470. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.d.ts +1 -0
  471. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +13 -4
  472. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +1 -0
  473. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +34 -4
  474. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.d.ts +14 -0
  475. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.js +29 -0
  476. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +7 -0
  477. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +9 -0
  478. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.d.ts +12 -0
  479. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +104 -0
  480. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.d.ts +13 -1
  481. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +65 -9
  482. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +5 -1
  483. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
  484. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +72 -117
  485. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.d.ts +2 -0
  486. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +16 -7
  487. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/factory.d.ts +2 -0
  488. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/factory.js +141 -0
  489. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/manifest.d.ts +46 -0
  490. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/manifest.js +28 -0
  491. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/types.d.ts +127 -0
  492. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/types.js +1 -0
  493. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk.d.ts +3 -0
  494. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk.js +3 -0
  495. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.d.ts +7 -1
  496. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +216 -33
  497. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-role-guard.d.ts +2 -0
  498. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-role-guard.js +22 -0
  499. package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.d.ts +9 -0
  500. package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.js +227 -0
  501. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.d.ts +6 -0
  502. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.js +33 -0
  503. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +20 -6
  504. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +19 -0
  505. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +75 -0
  506. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +18 -5
  507. package/packages/omo-codex/plugin/components/ulw-loop/package.json +6 -6
  508. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +10 -4
  509. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
  510. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +32 -8
  511. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +40 -0
  512. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +8 -6
  513. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +5 -98
  514. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +134 -0
  515. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +52 -73
  516. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-arg-parser.ts +10 -4
  517. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +24 -8
  518. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +14 -1
  519. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +52 -46
  520. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +8 -6
  521. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +35 -7
  522. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +34 -28
  523. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
  524. package/packages/omo-codex/plugin/components/ulw-loop/src/constants.ts +1 -0
  525. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +19 -9
  526. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +25 -4
  527. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +39 -4
  528. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-missing-recovery.ts +38 -0
  529. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +11 -0
  530. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +123 -0
  531. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +71 -15
  532. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +6 -1
  533. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +92 -136
  534. package/packages/omo-codex/plugin/components/ulw-loop/src/review-blockers.ts +29 -8
  535. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/factory.ts +183 -0
  536. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/manifest.ts +42 -0
  537. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/types.ts +140 -0
  538. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk.ts +3 -0
  539. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +226 -31
  540. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-role-guard.ts +22 -0
  541. package/packages/omo-codex/plugin/components/ulw-loop/src/state-lock.ts +239 -0
  542. package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +36 -0
  543. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +19 -6
  544. package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +107 -0
  545. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
  546. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +131 -82
  547. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +147 -0
  548. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint.test.ts +16 -22
  549. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint-continuation.test.ts +4 -2
  550. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint.test.ts +31 -2
  551. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-commands.test.ts +2 -0
  552. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-complete-goals.test.ts +3 -1
  553. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +35 -8
  554. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +38 -4
  555. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-json-errors.test.ts +27 -0
  556. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-scope-required.test.ts +144 -0
  557. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-status-next-actions.test.ts +185 -0
  558. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-batch.test.ts +8 -3
  559. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-validation-batch.test.ts +6 -0
  560. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +37 -2
  561. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +52 -11
  562. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
  563. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/cli-session.ts +4 -0
  564. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +9 -4
  565. package/packages/omo-codex/plugin/components/ulw-loop/test/guided-recovery.test.ts +67 -0
  566. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
  567. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
  568. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io-cross-process.test.ts +106 -0
  569. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io.test.ts +36 -2
  570. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate-basics.test.ts +258 -0
  571. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-cap-and-dedupe.test.ts +22 -0
  572. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-fields-messages.test.ts +98 -0
  573. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-lazycodex-surface.test.ts +93 -0
  574. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-poisoning-cascades.test.ts +97 -0
  575. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +51 -2
  576. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-senpi-surface.test.ts +131 -0
  577. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-single-report.test.ts +241 -0
  578. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +58 -3
  579. package/packages/omo-codex/plugin/components/ulw-loop/test/review-blockers.test.ts +9 -7
  580. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-contract.test.ts +137 -0
  581. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-driver-states.test.ts +145 -0
  582. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-session-context.test.ts +148 -0
  583. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +450 -7
  584. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-role-matrix.test.ts +113 -0
  585. package/packages/omo-codex/plugin/components/ulw-loop/test/state-lock.test.ts +218 -0
  586. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
  587. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  588. package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -0
  589. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +13 -8
  590. package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
  591. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  592. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  593. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  594. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  595. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  596. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  597. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  598. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +18 -0
  599. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  600. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  601. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  602. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  603. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  604. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  605. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  606. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +17 -0
  607. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  608. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  609. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  610. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  611. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  612. package/packages/omo-codex/plugin/model-catalog.json +16 -7
  613. package/packages/omo-codex/plugin/package-lock.json +676 -524
  614. package/packages/omo-codex/plugin/package.json +2 -3
  615. package/packages/omo-codex/plugin/scripts/AGENTS.md +39 -0
  616. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -2
  617. package/packages/omo-codex/plugin/scripts/auto-update.mjs +0 -9
  618. package/packages/omo-codex/plugin/scripts/canonical-ultrawork-directive.mjs +17 -0
  619. package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +0 -1
  620. package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +16 -7
  621. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +8 -4
  622. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +19 -90
  623. package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +1 -1
  624. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +96 -57
  625. package/packages/omo-codex/plugin/shared/package.json +3 -4
  626. package/packages/omo-codex/plugin/shared/src/config-loader.ts +2 -102
  627. package/packages/omo-codex/plugin/shared/src/config-migration.ts +0 -1
  628. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +41 -130
  629. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
  630. package/packages/omo-codex/plugin/skills/ast-grep/SKILL.md +1 -1
  631. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
  632. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +1 -1
  633. package/packages/omo-codex/plugin/skills/data-scientist/SKILL.md +99 -239
  634. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-surfaces.md +91 -0
  635. package/packages/omo-codex/plugin/skills/data-scientist/references/placement.md +74 -0
  636. package/packages/omo-codex/plugin/skills/data-scientist/references/polars-lane.md +95 -0
  637. package/packages/omo-codex/plugin/skills/data-scientist/references/uv-setup.md +1 -1
  638. package/packages/omo-codex/plugin/skills/data-scientist/references/visualization.md +64 -0
  639. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  640. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  641. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +3 -1
  642. package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +12 -0
  643. package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +21 -0
  644. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +15 -1
  645. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +38 -0
  646. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +25 -0
  647. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +13 -0
  648. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +41 -0
  649. package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +267 -0
  650. package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  651. package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +103 -0
  652. package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +193 -0
  653. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +10 -0
  654. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +15 -8
  655. package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +10 -2
  656. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +2 -0
  657. package/packages/omo-codex/plugin/skills/frontend/references/design/ambience-skill.md +145 -0
  658. package/packages/omo-codex/plugin/skills/frontend/references/design/interaction-skill.md +2 -0
  659. package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
  660. package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
  661. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
  662. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  663. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  664. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  665. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
  666. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
  667. package/packages/omo-codex/plugin/skills/git-master/SKILL.md +1 -1
  668. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +20 -18
  669. package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +4 -2
  670. package/packages/omo-codex/plugin/skills/lsp-setup/SKILL.md +1 -1
  671. package/packages/omo-codex/plugin/skills/programming/SKILL.md +1 -1
  672. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +10 -8
  673. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +7 -5
  674. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +116 -424
  675. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
  676. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +26 -9
  677. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  678. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
  679. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
  680. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  681. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +46 -24
  682. package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +31 -33
  683. package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
  684. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +34 -4
  685. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
  686. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +32 -8
  687. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -7
  688. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
  689. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
  690. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
  691. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +14 -7
  692. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
  693. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +10 -7
  694. package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
  695. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
  696. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +16 -51
  697. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +2 -3
  698. package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +2 -7
  699. package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +14 -4
  700. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
  701. package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
  702. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
  703. package/packages/omo-codex/plugin/test/auto-update.test.mjs +4 -29
  704. package/packages/omo-codex/plugin/test/bootstrap-default-role.test.mjs +66 -0
  705. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +0 -31
  706. package/packages/omo-codex/plugin/test/canonical-ultrawork-directive.test.mjs +53 -0
  707. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
  708. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -51
  709. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +100 -2
  710. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +5 -6
  711. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
  712. package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -3
  713. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +35 -35
  714. package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +1 -1
  715. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
  716. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +107 -15
  717. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +168 -0
  718. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +54 -24
  719. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +18 -119
  720. package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
  721. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
  722. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
  723. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
  724. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
  725. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +5 -5
  726. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
  727. package/packages/omo-codex/scripts/AGENTS.md +36 -0
  728. package/packages/omo-codex/scripts/check-model-catalog-parity.mjs +42 -0
  729. package/packages/omo-codex/scripts/install-cache-copy.test.mjs +27 -1
  730. package/packages/omo-codex/scripts/install-config-autonomous-features.test.mjs +1 -1
  731. package/packages/omo-codex/scripts/install-config-autonomous.test.mjs +2 -1
  732. package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +0 -23
  733. package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +5 -5
  734. package/packages/omo-codex/scripts/install-config.test.mjs +15 -17
  735. package/packages/omo-codex/scripts/install-dist/install-local.mjs +9652 -1394
  736. package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +3 -4
  737. package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +1 -25
  738. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
  739. package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +0 -36
  740. package/packages/omo-codex/scripts/install-packaged-local.test.mjs +1 -6
  741. package/packages/{omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md → prompts-core/prompts/ultrawork/codex.md} +46 -31
  742. package/packages/shared-skills/package.json +7 -1
  743. package/packages/shared-skills/skill-source-filter.d.ts +16 -0
  744. package/packages/shared-skills/skill-source-filter.mjs +44 -0
  745. package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
  746. package/packages/shared-skills/skills/ast-grep/SKILL.md +1 -1
  747. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
  748. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +1 -1
  749. package/packages/shared-skills/skills/data-scientist/SKILL.md +99 -239
  750. package/packages/shared-skills/skills/data-scientist/references/execution-surfaces.md +91 -0
  751. package/packages/shared-skills/skills/data-scientist/references/placement.md +74 -0
  752. package/packages/shared-skills/skills/data-scientist/references/polars-lane.md +95 -0
  753. package/packages/shared-skills/skills/data-scientist/references/uv-setup.md +1 -1
  754. package/packages/shared-skills/skills/data-scientist/references/visualization.md +64 -0
  755. package/packages/shared-skills/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  756. package/packages/shared-skills/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  757. package/packages/shared-skills/skills/debugging/SKILL.md +3 -1
  758. package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +12 -0
  759. package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +21 -0
  760. package/packages/shared-skills/skills/debugging/references/runtimes/go.md +15 -1
  761. package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +38 -0
  762. package/packages/shared-skills/skills/debugging/references/runtimes/node.md +25 -0
  763. package/packages/shared-skills/skills/debugging/references/runtimes/python.md +13 -0
  764. package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +41 -0
  765. package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +267 -0
  766. package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +86 -0
  767. package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  768. package/packages/shared-skills/skills/debugging/references/tools/dap.md +103 -0
  769. package/packages/shared-skills/skills/debugging/references/tools/frida.md +193 -0
  770. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +10 -0
  771. package/packages/shared-skills/skills/frontend/SKILL.md +15 -8
  772. package/packages/shared-skills/skills/frontend/references/design/README.md +10 -2
  773. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +2 -0
  774. package/packages/shared-skills/skills/frontend/references/design/ambience-skill.md +145 -0
  775. package/packages/shared-skills/skills/frontend/references/design/interaction-skill.md +2 -0
  776. package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
  777. package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
  778. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
  779. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  780. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  781. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  782. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
  783. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
  784. package/packages/shared-skills/skills/git-master/SKILL.md +1 -1
  785. package/packages/shared-skills/skills/init-deep/SKILL.md +14 -14
  786. package/packages/shared-skills/skills/lsp-setup/SKILL.md +1 -1
  787. package/packages/shared-skills/skills/programming/SKILL.md +1 -1
  788. package/packages/shared-skills/skills/refactor/SKILL.md +4 -4
  789. package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +1 -1
  790. package/packages/shared-skills/skills/review-work/SKILL.md +101 -419
  791. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +38 -11
  792. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +26 -9
  793. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  794. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
  795. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +23 -18
  796. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  797. package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +20 -19
  798. package/packages/shared-skills/skills/ulw-plan/SKILL.md +7 -8
  799. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +31 -7
  800. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
  801. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
  802. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
  803. package/packages/shared-skills/skills/ulw-research/SKILL.md +8 -3
  804. package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
  805. package/packages/shared-skills/skills/visual-qa/SKILL.md +4 -3
  806. package/postinstall.mjs +2 -0
  807. package/script/qa/web-terminal-visual-qa.mjs +2 -0
  808. package/script/qa/xterm-live-terminal.mjs +18 -2
  809. package/dist/config/schema/codegraph.d.ts +0 -12
  810. package/dist/config/schema/start-work.d.ts +0 -5
  811. package/dist/features/builtin-commands/templates/start-work.d.ts +0 -1
  812. package/dist/features/builtin-skills/index.d.ts +0 -1
  813. package/dist/features/builtin-skills/skill-file-loader.d.ts +0 -1
  814. package/dist/features/builtin-skills/skills/agent-browser-skill.d.ts +0 -1
  815. package/dist/features/builtin-skills/skills/agent-browser-template.d.ts +0 -1
  816. package/dist/features/builtin-skills/skills/debugging.d.ts +0 -1
  817. package/dist/features/builtin-skills/skills/dev-browser.d.ts +0 -1
  818. package/dist/features/builtin-skills/skills/frontend.d.ts +0 -1
  819. package/dist/features/builtin-skills/skills/git-master-sections/commit-atomic-planning.d.ts +0 -1
  820. package/dist/features/builtin-skills/skills/git-master-sections/commit-context-analysis.d.ts +0 -1
  821. package/dist/features/builtin-skills/skills/git-master-sections/commit-execution-verification.d.ts +0 -1
  822. package/dist/features/builtin-skills/skills/git-master-sections/commit-workflow.d.ts +0 -1
  823. package/dist/features/builtin-skills/skills/git-master-sections/history-search-workflow.d.ts +0 -1
  824. package/dist/features/builtin-skills/skills/git-master-sections/overview.d.ts +0 -1
  825. package/dist/features/builtin-skills/skills/git-master-sections/quick-reference.d.ts +0 -1
  826. package/dist/features/builtin-skills/skills/git-master-sections/rebase-workflow.d.ts +0 -1
  827. package/dist/features/builtin-skills/skills/git-master-skill-metadata.d.ts +0 -1
  828. package/dist/features/builtin-skills/skills/git-master.d.ts +0 -1
  829. package/dist/features/builtin-skills/skills/index.d.ts +0 -1
  830. package/dist/features/builtin-skills/skills/init-deep.d.ts +0 -1
  831. package/dist/features/builtin-skills/skills/playwright-cli.d.ts +0 -1
  832. package/dist/features/builtin-skills/skills/playwright-mcp-skill.d.ts +0 -1
  833. package/dist/features/builtin-skills/skills/playwright.d.ts +0 -1
  834. package/dist/features/builtin-skills/skills/remove-ai-slops.d.ts +0 -1
  835. package/dist/features/builtin-skills/skills/review-work.d.ts +0 -1
  836. package/dist/features/builtin-skills/skills/security-research.d.ts +0 -1
  837. package/dist/features/builtin-skills/skills/security-review.d.ts +0 -1
  838. package/dist/features/builtin-skills/skills/team-mode.d.ts +0 -1
  839. package/dist/features/builtin-skills/skills/visual-qa.d.ts +0 -1
  840. package/dist/features/builtin-skills/skills.d.ts +0 -1
  841. package/dist/features/builtin-skills/types.d.ts +0 -1
  842. package/dist/features/claude-code-plugin-loader/agent-loader.d.ts +0 -1
  843. package/dist/features/claude-code-plugin-loader/command-loader.d.ts +0 -1
  844. package/dist/features/claude-code-plugin-loader/discovery-core.d.ts +0 -1
  845. package/dist/features/claude-code-plugin-loader/discovery-paths.d.ts +0 -1
  846. package/dist/features/claude-code-plugin-loader/discovery.d.ts +0 -1
  847. package/dist/features/claude-code-plugin-loader/hook-loader.d.ts +0 -1
  848. package/dist/features/claude-code-plugin-loader/index.d.ts +0 -1
  849. package/dist/features/claude-code-plugin-loader/install-path-resolver.d.ts +0 -1
  850. package/dist/features/claude-code-plugin-loader/installed-plugin-database.d.ts +0 -1
  851. package/dist/features/claude-code-plugin-loader/loaded-plugin.d.ts +0 -1
  852. package/dist/features/claude-code-plugin-loader/loader.d.ts +0 -1
  853. package/dist/features/claude-code-plugin-loader/mcp-server-loader.d.ts +0 -1
  854. package/dist/features/claude-code-plugin-loader/plugin-key.d.ts +0 -1
  855. package/dist/features/claude-code-plugin-loader/plugin-manifest.d.ts +0 -1
  856. package/dist/features/claude-code-plugin-loader/plugin-path-resolver.d.ts +0 -1
  857. package/dist/features/claude-code-plugin-loader/plugin-settings.d.ts +0 -1
  858. package/dist/features/claude-code-plugin-loader/scope-filter.d.ts +0 -1
  859. package/dist/features/claude-code-plugin-loader/skill-loader.d.ts +0 -1
  860. package/dist/features/claude-code-plugin-loader/types.d.ts +0 -1
  861. package/dist/hooks/codegraph-bootstrap/command-runner.d.ts +0 -17
  862. package/dist/hooks/codegraph-bootstrap/hook.d.ts +0 -35
  863. package/dist/hooks/codegraph-bootstrap/index.d.ts +0 -1
  864. package/dist/hooks/codegraph-bootstrap/project-root.d.ts +0 -1
  865. package/dist/hooks/codegraph-bootstrap/status.d.ts +0 -11
  866. package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +0 -11
  867. package/dist/hooks/ralph-loop/loop-session-recovery.d.ts +0 -7
  868. package/dist/hooks/start-work/start-work-hook.d.ts +0 -23
  869. package/dist/mcp/codegraph.d.ts +0 -16
  870. package/dist/plugin/chat-message/start-work-message.d.ts +0 -5
  871. package/dist/shared/prompt-async-gate/message-inspection-error.d.ts +0 -1
  872. package/dist/shared/prompt-async-gate/pending-tool-turn.d.ts +0 -1
  873. package/dist/shared/prompt-async-gate/prompt-message-state.d.ts +0 -1
  874. package/dist/shared/prompt-async-gate/queue.d.ts +0 -1
  875. package/dist/shared/prompt-async-gate/recent-dispatches.d.ts +0 -1
  876. package/dist/shared/prompt-async-gate/reservations.d.ts +0 -1
  877. package/dist/shared/prompt-async-gate/semantic-dedupe.d.ts +0 -1
  878. package/dist/shared/prompt-async-gate/session-idle-dispatch.d.ts +0 -1
  879. package/dist/shared/prompt-async-gate/timing.d.ts +0 -1
  880. package/dist/shared/prompt-async-gate/types.d.ts +0 -1
  881. package/dist/skills/data-scientist/references/common-scenarios.md +0 -176
  882. package/dist/skills/data-scientist/references/execution-templates.md +0 -197
  883. package/dist/skills/data-scientist/references/integration-patterns.md +0 -153
  884. package/dist/skills/data-scientist/references/performance-benchmarks.md +0 -37
  885. package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
  886. package/dist/tools/call-omo-agent/message-storage-directory.d.ts +0 -1
  887. package/dist/tools/delegate-task/anthropic-categories.d.ts +0 -2
  888. package/dist/tools/delegate-task/model-string-parser.d.ts +0 -1
  889. package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
  890. package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
  891. package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
  892. package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
  893. package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
  894. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +0 -58
  895. package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +0 -2951
  896. package/packages/omo-codex/plugin/components/codegraph/NOTICE +0 -16
  897. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +0 -12149
  898. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9747
  899. package/packages/omo-codex/plugin/components/codegraph/package.json +0 -33
  900. package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +0 -29
  901. package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +0 -79
  902. package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +0 -33
  903. package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +0 -25
  904. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +0 -131
  905. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +0 -258
  906. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +0 -309
  907. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +0 -80
  908. package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +0 -34
  909. package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +0 -29
  910. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +0 -263
  911. package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +0 -106
  912. package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +0 -145
  913. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +0 -21
  914. package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +0 -139
  915. package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +0 -15
  916. package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +0 -32
  917. package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +0 -109
  918. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +0 -148
  919. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +0 -175
  920. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +0 -81
  921. package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +0 -34
  922. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +0 -112
  923. package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +0 -26
  924. package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +0 -160
  925. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +0 -50
  926. package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +0 -29
  927. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +0 -320
  928. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +0 -172
  929. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +0 -91
  930. package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +0 -100
  931. package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +0 -76
  932. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +0 -133
  933. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +0 -245
  934. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +0 -69
  935. package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +0 -43
  936. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +0 -147
  937. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +0 -175
  938. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +0 -385
  939. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +0 -206
  940. package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +0 -58
  941. package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +0 -104
  942. package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +0 -65
  943. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +0 -106
  944. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +0 -116
  945. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +0 -258
  946. package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +0 -56
  947. package/packages/omo-codex/plugin/components/codegraph/tsconfig.build.json +0 -13
  948. package/packages/omo-codex/plugin/components/codegraph/tsconfig.json +0 -25
  949. package/packages/omo-codex/plugin/components/start-work-continuation/LICENSE +0 -21
  950. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
  951. package/packages/omo-codex/plugin/components/ultrawork/directive.md +0 -471
  952. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +0 -18
  953. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +0 -17
  954. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
  955. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
  956. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/editor.mjs +0 -125
  957. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/jsonc.mjs +0 -43
  958. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/scaffold.mjs +0 -29
  959. package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +0 -121
  960. package/packages/omo-codex/plugin/skills/data-scientist/references/common-scenarios.md +0 -176
  961. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-templates.md +0 -197
  962. package/packages/omo-codex/plugin/skills/data-scientist/references/integration-patterns.md +0 -153
  963. package/packages/omo-codex/plugin/skills/data-scientist/references/performance-benchmarks.md +0 -37
  964. package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
  965. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
  966. package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +0 -76
  967. package/packages/omo-codex/plugin/test/migrate-omo-sot.test.mjs +0 -179
  968. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
  969. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
  970. package/packages/shared-skills/skills/data-scientist/references/common-scenarios.md +0 -176
  971. package/packages/shared-skills/skills/data-scientist/references/execution-templates.md +0 -197
  972. package/packages/shared-skills/skills/data-scientist/references/integration-patterns.md +0 -153
  973. package/packages/shared-skills/skills/data-scientist/references/performance-benchmarks.md +0 -37
  974. /package/dist/hooks/{start-work → ulw-execute}/context-info-formatters.d.ts +0 -0
  975. /package/dist/hooks/{start-work → ulw-execute}/explicit-plan-context.d.ts +0 -0
  976. /package/dist/hooks/{start-work → ulw-execute}/notepad-scaffold.d.ts +0 -0
  977. /package/dist/hooks/{start-work → ulw-execute}/parse-user-request.d.ts +0 -0
  978. /package/dist/hooks/{start-work → ulw-execute}/plan-discovery-context.d.ts +0 -0
  979. /package/dist/hooks/{start-work → ulw-execute}/plan-selection.d.ts +0 -0
  980. /package/dist/hooks/{start-work → ulw-execute}/session-plan-affinity.d.ts +0 -0
  981. /package/dist/hooks/{start-work → ulw-execute}/work-initializer.d.ts +0 -0
  982. /package/dist/hooks/{start-work → ulw-execute}/worktree-block.d.ts +0 -0
  983. /package/dist/hooks/{start-work → ulw-execute}/worktree-detector.d.ts +0 -0
  984. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
  985. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
  986. /package/packages/omo-codex/plugin/components/{codegraph → ulw-execute-continuation}/LICENSE +0 -0
  987. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
  988. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
  989. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
  990. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
  991. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
  992. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
  993. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
  994. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
  995. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
  996. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
  997. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
@@ -1,85 +1,254 @@
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, readFileSync, renameSync, statSync, writeFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
3
4
 
4
5
  import type { PreToolUsePayload } from "./codex-hook.js";
5
6
  import { parsePreToolUsePayload } from "./codex-hook.js";
6
7
  import { isFinalRunCompletionCandidate } from "./goal-status.js";
7
- import { ulwLoopAttemptEvidenceDir, ulwLoopDir } from "./paths.js";
8
+ import { ulwLoopAttemptEvidenceDir, ulwLoopDir, ulwLoopStateLockPath } from "./paths.js";
9
+ import { spawnRoleDenial } from "./spawn-role-guard.js";
10
+ import { isStateLockTimeout, type StateLockOptions, withStateLockSync } from "./state-lock.js";
11
+ import {
12
+ GATE_REVIEWER_AGENT_NAMES,
13
+ REVIEWER_ROLES_BY_SURFACE,
14
+ resolveToolkitSurface,
15
+ reviewerRolesFor,
16
+ } from "./surface.js";
8
17
  import type { UlwLoopPlan } from "./types.js";
9
18
 
10
19
  // spawn_agent = v1; collaborationspawn_agent = the delimiter-free flattened v2
11
20
  // hook token from codex-rs hook_names.rs; collaboration.spawn_agent = the
12
21
  // dotted token observed live in the task-1 probe (hook-tool-tokens.txt).
13
- const SPAWN_TOOL_TOKENS = new Set(["spawn_agent", "collaborationspawn_agent", "collaboration.spawn_agent"]);
14
- const DEFAULT_FANOUT_LIMIT = 60;
15
- const GATE_MESSAGE_PATTERN = /lazycodex-gate-reviewer|final gate review/i;
22
+ const SPAWN_TOOL_TOKENS = new Set([
23
+ "spawn_agent",
24
+ "multi_agent_v1.spawn_agent",
25
+ "collaborationspawn_agent",
26
+ "collaboration.spawn_agent",
27
+ ]);
28
+ export const DEFAULT_FANOUT_LIMIT = 24;
29
+ const DEFAULT_REVIEW_SPAWN_LIMIT = 3;
30
+ const GATE_MESSAGE_PATTERN = /lazycodex-gate-reviewer|omo-senpi-gate-reviewer|final gate review/i;
31
+ const REVIEW_AGENT_TYPES = [
32
+ ...Object.values(REVIEWER_ROLES_BY_SURFACE).map((roles) => roles.gateReview),
33
+ ...Object.values(REVIEWER_ROLES_BY_SURFACE).map((roles) => roles.codeReview),
34
+ ...Object.values(REVIEWER_ROLES_BY_SURFACE).map((roles) => roles.manualQa),
35
+ ] as const;
36
+ const REVIEW_AGENT_TYPE_SET = new Set<string>(REVIEW_AGENT_TYPES);
16
37
 
17
- export function applySpawnGuards(payload: PreToolUsePayload): string {
38
+ export interface SpawnGuardOptions {
39
+ readonly lockTimeoutMs?: number;
40
+ }
41
+
42
+ export function applySpawnGuards(payload: PreToolUsePayload, options: SpawnGuardOptions = {}): string {
43
+ if (payload.hook_event_name !== "PreToolUse" || !SPAWN_TOOL_TOKENS.has(payload.tool_name)) return "";
44
+ if (resolveToolkitSurface() === "lazycodex") {
45
+ const reason = spawnRoleDenial(payload.tool_input);
46
+ if (reason !== null) return deny(reason);
47
+ }
48
+ return applySpawnBudgetGuards(payload, options);
49
+ }
50
+
51
+ export function applySpawnBudgetGuards(payload: PreToolUsePayload, options: SpawnGuardOptions = {}): string {
18
52
  if (payload.hook_event_name !== "PreToolUse" || !SPAWN_TOOL_TOKENS.has(payload.tool_name)) return "";
19
- const stateDir = ulwLoopDir(payload.cwd, { sessionId: payload.session_id });
53
+ const breaker = readAdmissionBreaker(payload.session_id);
54
+ if (breaker !== null)
55
+ return deny(
56
+ `Subagent admission failed earlier in this session (${breaker}). Do not spawn more workers or reviewers; report the capacity block and wait for the user.`,
57
+ );
58
+ const scope = { sessionId: payload.session_id } as const;
59
+ const stateDir = ulwLoopDir(payload.cwd, scope);
20
60
  const plan = readPlan(join(stateDir, "goals.json"));
21
61
  if (plan === null) return "";
22
- const fanOutDenial = consumeFanOutBudget(stateDir);
23
- if (fanOutDenial !== null) return deny(fanOutDenial);
62
+ const lockOptions: StateLockOptions =
63
+ options.lockTimeoutMs === undefined ? {} : { timeoutMs: options.lockTimeoutMs };
64
+ try {
65
+ return withStateLockSync(
66
+ ulwLoopStateLockPath(payload.cwd, scope),
67
+ () => evaluateGuards(payload, plan, stateDir),
68
+ lockOptions,
69
+ );
70
+ } catch (error) {
71
+ if (isStateLockTimeout(error))
72
+ return deny(`ulw-loop spawn guard could not take the session state lock: ${error.message}`);
73
+ throw error;
74
+ }
75
+ }
76
+
77
+ function evaluateGuards(payload: PreToolUsePayload, plan: UlwLoopPlan, stateDir: string): string {
78
+ const fanOutPeek = peekFanOutBudget(stateDir);
79
+ if (fanOutPeek !== null) return deny(fanOutPeek);
24
80
  const missingArtifact = missingGateArtifact(payload, plan);
25
81
  if (missingArtifact !== null)
26
- return deny(`spawn code-review + QA first; gate audits their artifacts: missing ${missingArtifact}`);
82
+ return deny(`record manual QA first; gate audits its artifacts: missing ${missingArtifact}`);
83
+ const reviewDenial = consumeReviewSpawnBudget(payload, plan, stateDir);
84
+ if (reviewDenial !== null) return deny(reviewDenial);
85
+ const fanOutDenial = consumeFanOutBudget(stateDir);
86
+ if (fanOutDenial !== null) return deny(fanOutDenial);
27
87
  return "";
28
88
  }
29
89
 
90
+ export async function runSpawnAdmissionRecorderCli(
91
+ stdin: NodeJS.ReadableStream,
92
+ stdout: NodeJS.WritableStream,
93
+ ): Promise<void> {
94
+ const chunks: Buffer[] = [];
95
+ for await (const chunk of stdin) chunks.push(Buffer.from(chunk));
96
+ try {
97
+ const payload = JSON.parse(Buffer.concat(chunks).toString("utf8")) as Record<string, unknown>;
98
+ const response =
99
+ typeof payload["tool_response"] === "string"
100
+ ? payload["tool_response"]
101
+ : JSON.stringify(payload["tool_response"] ?? "");
102
+ if (!/too many active cells|AgentLimitReached|max_threads|max_concurrent_threads_per_session/i.test(response))
103
+ return;
104
+ const dataDir = process.env["PLUGIN_DATA"];
105
+ if (typeof dataDir !== "string" || typeof payload["session_id"] !== "string") return;
106
+ const markerDir = join(dataDir, "spawn-breaker");
107
+ try {
108
+ mkdirSync(markerDir, { recursive: true });
109
+ atomicWriteJson(join(markerDir, `${payload["session_id"]}.json`), {
110
+ reason: response,
111
+ at: new Date().toISOString(),
112
+ });
113
+ } catch (error) {
114
+ const message = error instanceof Error ? error.message : String(error);
115
+ process.stderr.write(`[ulw-loop] spawn-guard: could not persist admission failure: ${message}\n`);
116
+ }
117
+ } catch {
118
+ /* malformed hook input is ignored */
119
+ }
120
+ void stdout;
121
+ }
122
+
30
123
  export async function runSpawnGuardCli(stdin: NodeJS.ReadableStream, stdout: NodeJS.WritableStream): Promise<void> {
31
124
  try {
32
125
  const chunks: Buffer[] = [];
33
126
  for await (const chunk of stdin) chunks.push(Buffer.from(chunk));
34
127
  const payload = parsePreToolUsePayload(Buffer.concat(chunks).toString("utf8"));
35
- if (payload === null) return;
128
+ if (payload === null) {
129
+ stdout.write(deny("LazyCodex spawn guard received an invalid hook payload; role routing was not verified."));
130
+ return;
131
+ }
36
132
  const output = applySpawnGuards(payload);
37
133
  if (output.length > 0) stdout.write(output);
38
134
  } catch (error) {
39
- if (error instanceof Error) return;
135
+ stdout.write(deny(`LazyCodex spawn guard failed: ${error instanceof Error ? error.message : String(error)}`));
40
136
  }
41
137
  }
42
138
 
139
+ // Read-only fan-out eligibility check. Returns a denial reason when the next
140
+ // spawn would exceed the limit, without incrementing the counter. Call this
141
+ // before charging any per-reviewer quota so a saturated global cap cannot
142
+ // silently consume reviewer allowances for spawns that will never run.
143
+ function peekFanOutBudget(stateDir: string): string | null {
144
+ const counterPath = join(stateDir, "spawn-count.json");
145
+ const count = readCount(counterPath) + 1;
146
+ const limit = fanOutLimit();
147
+ if (count <= limit) return null;
148
+ 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.`;
149
+ }
150
+
43
151
  // Per-session spawn counter; depth/lineage tracking is descoped — this is a
44
152
  // total-volume backstop against fan-out explosions, not a recursion tracker.
45
153
  function consumeFanOutBudget(stateDir: string): string | null {
46
154
  const counterPath = join(stateDir, "spawn-count.json");
47
155
  const count = readCount(counterPath) + 1;
48
- writeFileSync(counterPath, JSON.stringify({ count }));
156
+ atomicWriteJson(counterPath, { count });
49
157
  const limit = fanOutLimit();
50
158
  if (count <= limit) return null;
51
159
  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.`;
52
160
  }
53
161
 
162
+ function consumeReviewSpawnBudget(payload: PreToolUsePayload, plan: UlwLoopPlan, stateDir: string): string | null {
163
+ const agentType = reviewAgentType(payload.tool_input);
164
+ if (agentType === null) return null;
165
+ const goal =
166
+ plan.goals.find((candidate) => candidate.id === plan.activeGoalId) ??
167
+ plan.goals.find((candidate) => isFinalRunCompletionCandidate(plan, candidate));
168
+ if (goal === undefined) return null;
169
+ const counterPath = join(stateDir, "review-spawn-counts.json");
170
+ const limit = reviewSpawnLimit();
171
+ const counts = readCounts(counterPath);
172
+ const key = `${agentType}:${goal.id}:a${goal.attempt}`;
173
+ const count = (counts[key] ?? 0) + 1;
174
+ if (count > limit)
175
+ 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.`;
176
+ counts[key] = count;
177
+ atomicWriteJson(counterPath, counts);
178
+ return null;
179
+ }
180
+
54
181
  function missingGateArtifact(payload: PreToolUsePayload, plan: UlwLoopPlan): string | null {
55
182
  if (!isGateReviewerSpawn(payload.tool_input)) return null;
56
183
  const goal = plan.goals.find((candidate) => isFinalRunCompletionCandidate(plan, candidate));
57
184
  if (goal === undefined || goal.status === "complete") return null;
58
185
  if (!goal.successCriteria.every((criterion) => criterion.status === "pass")) return null;
59
186
  const scope = { sessionId: payload.session_id } as const;
187
+ const requiredArtifacts = [`${goal.id}-manual-qa.md`];
60
188
  if (plan.evidenceLayoutVersion === 2) {
61
189
  const attemptDir = ulwLoopAttemptEvidenceDir(goal.id, goal.attempt, scope);
62
- for (const name of [`${goal.id}-code-review.md`, `${goal.id}-manual-qa.md`]) {
190
+ for (const name of requiredArtifacts) {
63
191
  const relative = `${attemptDir}/${name}`;
64
192
  if (!isNonEmptyFile(join(payload.cwd, relative))) return relative;
65
193
  }
66
194
  return null;
67
195
  }
68
- const flatReport = `.omo/evidence/${goal.id}-code-review.md`;
69
- if (!isNonEmptyFile(join(payload.cwd, flatReport))) return flatReport;
70
- // v1 manual-QA approximation: any other non-empty evidence file counts.
71
- if (!hasOtherEvidenceFile(join(payload.cwd, ".omo", "evidence"), `${goal.id}-code-review.md`))
72
- return `.omo/evidence/<any manual-QA artifact besides ${goal.id}-code-review.md>`;
73
- return null;
196
+ const manualQa = `.omo/evidence/${goal.id}-manual-qa.md`;
197
+ return isNonEmptyFile(join(payload.cwd, manualQa)) ? null : manualQa;
74
198
  }
75
199
 
76
200
  function isGateReviewerSpawn(toolInput: unknown): boolean {
77
- if (typeof toolInput !== "object" || toolInput === null) return false;
201
+ const agentType = reviewAgentType(toolInput);
202
+ return agentType !== null && GATE_REVIEWER_AGENT_NAMES.has(agentType);
203
+ }
204
+
205
+ function reviewAgentType(toolInput: unknown): string | null {
206
+ if (typeof toolInput !== "object" || toolInput === null) return null;
78
207
  const record = toolInput as Record<string, unknown>;
79
208
  const agentType = record["agent_type"];
80
- if (typeof agentType === "string") return agentType === "lazycodex-gate-reviewer";
209
+ if (typeof agentType === "string") {
210
+ // V1: agent_type is present — only reviewer types proceed; any other type is not a review spawn.
211
+ if (!REVIEW_AGENT_TYPE_SET.has(agentType)) return null;
212
+ return activeSurfaceReviewerAlias(agentType);
213
+ }
81
214
  const message = record["message"];
82
- return typeof message === "string" && GATE_MESSAGE_PATTERN.test(message);
215
+ if (typeof message !== "string") return null;
216
+ const normalizedMessage = message.toLowerCase();
217
+ // Explicit "act as <role>" assignment takes priority. If the assigned role is not a reviewer,
218
+ // treat the spawn as non-review so a message that merely mentions a reviewer name does not
219
+ // accidentally charge that reviewer's quota.
220
+ const allRoleNames = [...REVIEW_AGENT_TYPES];
221
+ const explicitAssignment = allRoleNames
222
+ .map((name) => ({
223
+ name,
224
+ index: normalizedMessage.search(new RegExp(`\\bact as (?:an? )?${name}\\b`)),
225
+ }))
226
+ .filter(({ index }) => index >= 0)
227
+ .sort((left, right) => left.index - right.index)[0];
228
+ if (explicitAssignment !== undefined) return activeSurfaceReviewerAlias(explicitAssignment.name);
229
+ // Check for an explicit "act as <non-reviewer-role>" assignment. If found, the spawn is not a
230
+ // review spawn even if the message body mentions a reviewer name.
231
+ const nonReviewerActAs = /\bact as (?:an? )?\S+/.test(normalizedMessage);
232
+ if (nonReviewerActAs) return null;
233
+ const namedReviewer = REVIEW_AGENT_TYPES.find((name) => normalizedMessage.includes(name));
234
+ if (namedReviewer !== undefined) return activeSurfaceReviewerAlias(namedReviewer);
235
+ return GATE_MESSAGE_PATTERN.test(message) ? reviewerRolesFor(resolveToolkitSurface()).gateReview : null;
236
+ }
237
+
238
+ function activeSurfaceReviewerAlias(reviewer: string): string {
239
+ const activeRoles = reviewerRolesFor(resolveToolkitSurface());
240
+ for (const roles of Object.values(REVIEWER_ROLES_BY_SURFACE)) {
241
+ if (reviewer === roles.codeReview) return activeRoles.codeReview;
242
+ if (reviewer === roles.manualQa) return activeRoles.manualQa;
243
+ if (reviewer === roles.gateReview) return activeRoles.gateReview;
244
+ }
245
+ return reviewer;
246
+ }
247
+
248
+ function atomicWriteJson(targetPath: string, data: unknown): void {
249
+ const tmp = join(dirname(targetPath), `.tmp-${randomBytes(6).toString("hex")}`);
250
+ writeFileSync(tmp, JSON.stringify(data));
251
+ renameSync(tmp, targetPath);
83
252
  }
84
253
 
85
254
  function deny(reason: string): string {
@@ -93,6 +262,19 @@ function deny(reason: string): string {
93
262
  })}\n`;
94
263
  }
95
264
 
265
+ function readAdmissionBreaker(sessionId: string): string | null {
266
+ const dataDir = process.env["PLUGIN_DATA"];
267
+ if (typeof dataDir !== "string") return null;
268
+ try {
269
+ const value = JSON.parse(readFileSync(join(dataDir, "spawn-breaker", `${sessionId}.json`), "utf8")) as {
270
+ reason?: unknown;
271
+ };
272
+ return typeof value.reason === "string" ? value.reason : "capacity limit";
273
+ } catch {
274
+ return null;
275
+ }
276
+ }
277
+
96
278
  function fanOutLimit(): number {
97
279
  const raw = process.env["OMO_SPAWN_FANOUT_LIMIT"];
98
280
  if (raw === undefined) return DEFAULT_FANOUT_LIMIT;
@@ -100,6 +282,13 @@ function fanOutLimit(): number {
100
282
  return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_FANOUT_LIMIT;
101
283
  }
102
284
 
285
+ function reviewSpawnLimit(): number {
286
+ const raw = process.env["OMO_ULW_LOOP_REVIEW_SPAWN_LIMIT"];
287
+ if (raw === undefined) return DEFAULT_REVIEW_SPAWN_LIMIT;
288
+ const parsed = Number.parseInt(raw, 10);
289
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_REVIEW_SPAWN_LIMIT;
290
+ }
291
+
103
292
  function isNonEmptyFile(path: string): boolean {
104
293
  try {
105
294
  return existsSync(path) && statSync(path).size > 0;
@@ -109,21 +298,27 @@ function isNonEmptyFile(path: string): boolean {
109
298
  }
110
299
  }
111
300
 
112
- function hasOtherEvidenceFile(evidenceDir: string, excludedName: string): boolean {
301
+ function readCount(counterPath: string): number {
113
302
  try {
114
- return readdirSync(evidenceDir).some((name) => name !== excludedName && isNonEmptyFile(join(evidenceDir, name)));
303
+ const parsed = JSON.parse(readFileSync(counterPath, "utf8")) as Record<string, unknown>;
304
+ return typeof parsed["count"] === "number" && parsed["count"] >= 0 ? parsed["count"] : 0;
115
305
  } catch (error) {
116
- if (error instanceof Error) return false;
306
+ if (error instanceof Error) return 0;
117
307
  throw error;
118
308
  }
119
309
  }
120
310
 
121
- function readCount(counterPath: string): number {
311
+ function readCounts(counterPath: string): Record<string, number> {
122
312
  try {
123
- const parsed = JSON.parse(readFileSync(counterPath, "utf8")) as Record<string, unknown>;
124
- return typeof parsed["count"] === "number" && parsed["count"] >= 0 ? parsed["count"] : 0;
313
+ const parsed: unknown = JSON.parse(readFileSync(counterPath, "utf8"));
314
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return {};
315
+ const counts: Record<string, number> = {};
316
+ for (const [key, value] of Object.entries(parsed)) {
317
+ if (typeof value === "number" && value >= 0) counts[key] = value;
318
+ }
319
+ return counts;
125
320
  } catch (error) {
126
- if (error instanceof Error) return 0;
321
+ if (error instanceof Error) return {};
127
322
  throw error;
128
323
  }
129
324
  }
@@ -0,0 +1,22 @@
1
+ // Explicit selectors, pinned by a test to the bundled role TOMLs. The generated
2
+ // default is a non-fork fallback, not a selector: a user can opt out of owning it.
3
+ export const LAZYCODEX_SPAWN_ROLES: ReadonlySet<string> = new Set([
4
+ "explorer",
5
+ "lazycodex-clone-fidelity-reviewer",
6
+ "lazycodex-code-reviewer",
7
+ "lazycodex-gate-reviewer",
8
+ "lazycodex-qa-executor",
9
+ "lazycodex-worker-high",
10
+ "lazycodex-worker-low",
11
+ "lazycodex-worker-medium",
12
+ "librarian",
13
+ "metis",
14
+ "momus",
15
+ "plan",
16
+ ]);
17
+
18
+ export function spawnRoleDenial(input: unknown): string | null {
19
+ const role = typeof input === "object" && input !== null && "agent_type" in input ? input.agent_type : undefined;
20
+ if (typeof role === "string" && LAZYCODEX_SPAWN_ROLES.has(role)) return null;
21
+ return `LazyCodex requires an explicit registered agent_type: ${[...LAZYCODEX_SPAWN_ROLES].join(", ")}. Received ${JSON.stringify(role) ?? "no agent_type"}. Use the matching role and fork_turns: "none" (V2) or fork_context: false (V1), unless full history is deliberately required. The hook cannot see the tool schema; if agent_type is unavailable, stop and report incompatible role routing rather than spawning a generic agent. Describing a role in message does not select its TOML.`;
22
+ }
@@ -0,0 +1,239 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { closeSync, mkdirSync, openSync, readFileSync, statSync, unlinkSync, writeSync } from "node:fs";
3
+ import { dirname } from "node:path";
4
+ import { setTimeout as sleep } from "node:timers/promises";
5
+
6
+ import { UlwLoopError } from "./types.js";
7
+
8
+ // Cross-process exclusive lock for one ulw-loop state directory. Every CLI
9
+ // invocation is its own process, so the in-process promise chain in plan-io
10
+ // serializes nothing across them; this file-level lock is what makes the
11
+ // read-modify-write of goals.json (and the counters next to it) atomic.
12
+ //
13
+ // Protocol: the lock is a file created with O_EXCL whose body records the
14
+ // owner (pid + a per-acquisition token). A waiter reclaims it only when the
15
+ // owner is provably gone (pid dead) or the body never became a record within
16
+ // `staleMs` (a creator that died mid-write); a live owner is never reclaimed by
17
+ // age alone, because overlapping two bodies is exactly the lost update this lock
18
+ // exists to prevent. Waiters back off and fail closed at `timeoutMs`. Release
19
+ // unlinks only a lock that still carries the releaser's own token.
20
+
21
+ export const ULW_LOOP_LOCK_TIMEOUT_CODE = "ULW_LOOP_LOCK_TIMEOUT";
22
+
23
+ export interface StateLockOptions {
24
+ readonly timeoutMs?: number;
25
+ readonly staleMs?: number;
26
+ }
27
+
28
+ interface LockRecord {
29
+ readonly pid: number;
30
+ readonly createdAt: string;
31
+ readonly token: string;
32
+ }
33
+
34
+ interface LockSnapshot {
35
+ readonly raw: string;
36
+ readonly record: LockRecord | null;
37
+ readonly ageMs: number;
38
+ }
39
+
40
+ type AttemptOutcome = { readonly kind: "acquired"; readonly token: string } | { readonly kind: "retry" | "wait" };
41
+
42
+ const DEFAULT_TIMEOUT_MS = 10_000;
43
+ const DEFAULT_STALE_MS = 60_000;
44
+ const MIN_DELAY_MS = 5;
45
+ const MAX_DELAY_MS = 100;
46
+ const SLEEP_CELL = new Int32Array(new SharedArrayBuffer(4));
47
+
48
+ export async function withStateLock<T>(
49
+ lockPath: string,
50
+ fn: () => Promise<T>,
51
+ options: StateLockOptions = {},
52
+ ): Promise<T> {
53
+ const token = await acquireAsync(lockPath, options);
54
+ try {
55
+ return await fn();
56
+ } finally {
57
+ release(lockPath, token);
58
+ }
59
+ }
60
+
61
+ export function withStateLockSync<T>(lockPath: string, fn: () => T, options: StateLockOptions = {}): T {
62
+ const token = acquireSync(lockPath, options);
63
+ try {
64
+ return fn();
65
+ } finally {
66
+ release(lockPath, token);
67
+ }
68
+ }
69
+
70
+ export function isStateLockTimeout(error: unknown): error is UlwLoopError {
71
+ return error instanceof UlwLoopError && error.code === ULW_LOOP_LOCK_TIMEOUT_CODE;
72
+ }
73
+
74
+ async function acquireAsync(lockPath: string, options: StateLockOptions): Promise<string> {
75
+ const deadline = Date.now() + (options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
76
+ const staleMs = options.staleMs ?? DEFAULT_STALE_MS;
77
+ mkdirSync(dirname(lockPath), { recursive: true });
78
+ for (let attempt = 0; ; ) {
79
+ const outcome = attemptOnce(lockPath, staleMs);
80
+ if (outcome.kind === "acquired") return outcome.token;
81
+ if (outcome.kind === "retry") continue;
82
+ if (Date.now() >= deadline) throw lockTimeout(lockPath, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
83
+ await sleep(backoffMs(attempt));
84
+ attempt += 1;
85
+ }
86
+ }
87
+
88
+ function acquireSync(lockPath: string, options: StateLockOptions): string {
89
+ const deadline = Date.now() + (options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
90
+ const staleMs = options.staleMs ?? DEFAULT_STALE_MS;
91
+ mkdirSync(dirname(lockPath), { recursive: true });
92
+ for (let attempt = 0; ; ) {
93
+ const outcome = attemptOnce(lockPath, staleMs);
94
+ if (outcome.kind === "acquired") return outcome.token;
95
+ if (outcome.kind === "retry") continue;
96
+ if (Date.now() >= deadline) throw lockTimeout(lockPath, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
97
+ Atomics.wait(SLEEP_CELL, 0, 0, backoffMs(attempt));
98
+ attempt += 1;
99
+ }
100
+ }
101
+
102
+ // EINTR surfaces raw from macOS fs syscalls under some runtimes; it is a retry, never a verdict.
103
+ function attemptOnce(lockPath: string, staleMs: number): AttemptOutcome {
104
+ try {
105
+ const token = tryCreate(lockPath);
106
+ if (token !== null) return { kind: "acquired", token };
107
+ const snapshot = readSnapshot(lockPath);
108
+ if (snapshot === null) return { kind: "retry" };
109
+ if (isStale(snapshot, staleMs) && reclaim(lockPath, snapshot.raw)) return { kind: "retry" };
110
+ return { kind: "wait" };
111
+ } catch (error) {
112
+ if (hasCode(error, "EINTR")) return { kind: "wait" };
113
+ throw error;
114
+ }
115
+ }
116
+
117
+ function tryCreate(lockPath: string): string | null {
118
+ let fd: number;
119
+ try {
120
+ fd = openSync(lockPath, "wx");
121
+ } catch (error) {
122
+ if (hasCode(error, "EEXIST")) return null;
123
+ throw error;
124
+ }
125
+ const record: LockRecord = { pid: process.pid, createdAt: new Date().toISOString(), token: randomUUID() };
126
+ try {
127
+ writeSync(fd, JSON.stringify(record));
128
+ } catch (error) {
129
+ closeSync(fd);
130
+ // A failed write (e.g. EINTR) must not leave a partial lock the owner never recorded;
131
+ // otherwise later readers see a young ownerless lock and only age can retire it.
132
+ try {
133
+ unlinkSync(lockPath);
134
+ } catch {
135
+ // another process already reclaimed the partial file; leave it alone
136
+ }
137
+ throw error;
138
+ }
139
+ closeSync(fd);
140
+ return record.token;
141
+ }
142
+
143
+ function readSnapshot(lockPath: string): LockSnapshot | null {
144
+ try {
145
+ const raw = readFileSync(lockPath, "utf8");
146
+ const ageMs = Date.now() - statSync(lockPath).mtimeMs;
147
+ return { raw, record: parseRecord(raw), ageMs };
148
+ } catch (error) {
149
+ if (hasCode(error, "ENOENT")) return null;
150
+ throw error;
151
+ }
152
+ }
153
+
154
+ function parseRecord(raw: string): LockRecord | null {
155
+ try {
156
+ const parsed: unknown = JSON.parse(raw);
157
+ if (typeof parsed !== "object" || parsed === null) return null;
158
+ const record = parsed as Record<string, unknown>;
159
+ const pid = record["pid"];
160
+ const createdAt = record["createdAt"];
161
+ const token = record["token"];
162
+ if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0 || typeof createdAt !== "string") return null;
163
+ if (typeof token !== "string" || token.length === 0) return null;
164
+ return { pid, createdAt, token };
165
+ } catch (error) {
166
+ if (error instanceof SyntaxError) return null;
167
+ throw error;
168
+ }
169
+ }
170
+
171
+ // A body that is not a record is a lock mid-write (or a foreign/legacy file); only
172
+ // age retires it. A parsable record is stale only when its owner is dead: a live
173
+ // owner running past staleMs is slow, not gone, and the waiter fails closed instead.
174
+ function isStale(snapshot: LockSnapshot, staleMs: number): boolean {
175
+ if (snapshot.record === null) return snapshot.ageMs > staleMs;
176
+ return !isProcessAlive(snapshot.record.pid);
177
+ }
178
+
179
+ function isProcessAlive(pid: number): boolean {
180
+ try {
181
+ process.kill(pid, 0);
182
+ return true;
183
+ } catch (error) {
184
+ if (hasCode(error, "ESRCH")) return false;
185
+ if (hasCode(error, "EPERM")) return true;
186
+ throw error;
187
+ }
188
+ }
189
+
190
+ // Re-read right before unlinking so a lock that changed hands since the stale
191
+ // verdict (a sibling waiter reclaimed and re-acquired it) is left alone.
192
+ function reclaim(lockPath: string, expectedRaw: string): boolean {
193
+ const current = readSnapshot(lockPath);
194
+ if (current === null) return true;
195
+ if (current.raw !== expectedRaw) return false;
196
+ try {
197
+ unlinkSync(lockPath);
198
+ } catch (error) {
199
+ if (!hasCode(error, "ENOENT")) throw error;
200
+ }
201
+ return true;
202
+ }
203
+
204
+ // Only the acquisition that wrote this token may unlink: if the file now carries
205
+ // another token, a waiter has legitimately taken over and its lock must stand.
206
+ function release(lockPath: string, token: string): void {
207
+ const current = readSnapshot(lockPath);
208
+ if (current === null || current.record?.token !== token) return;
209
+ try {
210
+ unlinkSync(lockPath);
211
+ } catch (error) {
212
+ if (!hasCode(error, "ENOENT")) throw error;
213
+ }
214
+ }
215
+
216
+ function backoffMs(attempt: number): number {
217
+ const exponential = Math.min(MAX_DELAY_MS, MIN_DELAY_MS * 2 ** attempt);
218
+ return exponential + Math.random() * MIN_DELAY_MS;
219
+ }
220
+
221
+ function lockTimeout(lockPath: string, timeoutMs: number): UlwLoopError {
222
+ const holder = readSnapshot(lockPath)?.record;
223
+ const owner = holder === undefined || holder === null ? "another process" : `pid ${holder.pid}`;
224
+ return new UlwLoopError(
225
+ `ulw-loop state lock ${lockPath} is held by ${owner} for more than ${timeoutMs}ms; retry once that process finishes, or delete the lock file if that process is gone.`,
226
+ ULW_LOOP_LOCK_TIMEOUT_CODE,
227
+ {
228
+ details: {
229
+ lockPath,
230
+ timeoutMs,
231
+ ...(holder === undefined || holder === null ? {} : { holderPid: holder.pid }),
232
+ },
233
+ },
234
+ );
235
+ }
236
+
237
+ function hasCode(error: unknown, code: string): boolean {
238
+ return error instanceof Error && "code" in error && error.code === code;
239
+ }
@@ -0,0 +1,36 @@
1
+ import { hasAllCriteriaPass, isFinalRunCompletionCandidate } from "./goal-status.js";
2
+ import { ULW_LOOP_CREATE_GOALS_COMMAND } from "./plan-missing-recovery.js";
3
+ import type { UlwLoopItem, UlwLoopPlan } from "./types.js";
4
+
5
+ /**
6
+ * `status --json` is the one call every agent already makes between steps, so it is
7
+ * also the cheapest place to answer "what now?" without a second round trip.
8
+ */
9
+ export function statusNextActions(plan: UlwLoopPlan): readonly string[] {
10
+ const actions: string[] = [];
11
+ const active = plan.goals.find((goal) => goal.id === plan.activeGoalId);
12
+ if (plan.goals.length === 0) actions.push(`No goals yet: bootstrap with \`${ULW_LOOP_CREATE_GOALS_COMMAND}\`.`);
13
+ else if (active !== undefined) actions.push(...activeGoalActions(plan, active));
14
+ for (const goal of plan.goals.filter((candidate) => candidate.status === "review_blocked"))
15
+ actions.push(
16
+ `${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>'\`.`,
17
+ );
18
+ if (plan.evidenceLayoutVersion !== 2 || active === undefined)
19
+ actions.push("plan is evidence-layout v1; artifacts go under .omo/evidence/");
20
+ return actions;
21
+ }
22
+
23
+ function activeGoalActions(plan: UlwLoopPlan, active: UlwLoopItem): readonly string[] {
24
+ const unresolved = active.successCriteria.filter((criterion) => criterion.status !== "pass");
25
+ if (unresolved.length > 0)
26
+ return [
27
+ `${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>"\`.`,
28
+ ];
29
+ if (hasAllCriteriaPass(active) && isFinalRunCompletionCandidate(plan, active))
30
+ return [
31
+ `${active.id} passes every criterion and is the final story: update_goal complete, then checkpoint --print-template to build the final quality gate. Use status --json's currentAttemptDir for all quality-gate artifacts.`,
32
+ ];
33
+ return [
34
+ `${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>'\`. Put quality-gate artifacts under the currentAttemptDir shown by status --json.`,
35
+ ];
36
+ }