oh-my-opencode 5.0.0-beta.2 → 5.0.0-beta.21

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 (460) hide show
  1. package/.agents/command/publish.md +44 -16
  2. package/.agents/skills/publish/SKILL.md +44 -16
  3. package/.agents/skills/senpi-qa/SKILL.md +80 -0
  4. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.mjs +65 -0
  5. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs +171 -0
  6. package/.agents/skills/work-with-pr/SKILL.md +37 -23
  7. package/.opencode/command/publish.md +44 -16
  8. package/.opencode/skills/work-with-pr/SKILL.md +37 -23
  9. package/README.ja.md +25 -21
  10. package/README.ko.md +25 -21
  11. package/README.md +38 -23
  12. package/README.ru.md +24 -20
  13. package/README.zh-cn.md +25 -21
  14. package/dist/agents/atlas/agent.d.ts +0 -1
  15. package/dist/agents/sisyphus/grok-4.d.ts +20 -0
  16. package/dist/agents/sisyphus/index.d.ts +2 -0
  17. package/dist/agents/sisyphus-agent-config.d.ts +6 -0
  18. package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
  19. package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +15 -4
  20. package/dist/agents/types.d.ts +2 -2
  21. package/dist/cli/fallback-lane-policy.d.ts +1 -0
  22. package/dist/cli/index.js +23057 -20893
  23. package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +1 -1
  24. package/dist/cli/run/on-complete-hook.d.ts +2 -0
  25. package/dist/cli/runtime-commands.d.ts +1 -1
  26. package/dist/cli/worktree-sweep/classify.d.ts +16 -0
  27. package/dist/cli/worktree-sweep/format.d.ts +8 -0
  28. package/dist/cli/worktree-sweep/git.d.ts +19 -0
  29. package/dist/cli/worktree-sweep/index.d.ts +7 -0
  30. package/dist/cli/worktree-sweep/options.d.ts +2 -0
  31. package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
  32. package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
  33. package/dist/cli/worktree-sweep/types.d.ts +65 -0
  34. package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
  35. package/dist/cli-node/index.js +23093 -20929
  36. package/dist/config/schema/commands.d.ts +1 -1
  37. package/dist/config/schema/hooks.d.ts +1 -1
  38. package/dist/config/schema/oh-my-opencode-config.d.ts +4 -1
  39. package/dist/config/schema/ulw-execute.d.ts +5 -0
  40. package/dist/config/validate.d.ts +2 -0
  41. package/dist/create-hooks.d.ts +3 -1
  42. package/dist/features/btw-side/btw-command-draft.d.ts +7 -0
  43. package/dist/features/btw-side/context-injector.d.ts +15 -0
  44. package/dist/features/btw-side/index.d.ts +8 -0
  45. package/dist/features/btw-side/metadata.d.ts +15 -0
  46. package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
  47. package/dist/features/btw-side/server-session-registry.d.ts +8 -0
  48. package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
  49. package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
  50. package/dist/features/btw-side/tui-controller-types.d.ts +68 -0
  51. package/dist/features/btw-side/tui-controller.d.ts +19 -0
  52. package/dist/features/btw-side/tui-escape-return.d.ts +12 -0
  53. package/dist/features/btw-side/tui-keymap.d.ts +17 -0
  54. package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
  55. package/dist/features/btw-side/tui-picker-options.d.ts +20 -0
  56. package/dist/features/btw-side/tui-picker.d.ts +9 -0
  57. package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
  58. package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
  59. package/dist/features/btw-side/tui-session-catalog.d.ts +35 -0
  60. package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
  61. package/dist/features/btw-side/tui-side-start.d.ts +9 -0
  62. package/dist/features/btw-side/tui-wiring.d.ts +8 -0
  63. package/dist/features/builtin-commands/templates/ulw-execute.d.ts +1 -0
  64. package/dist/features/builtin-commands/types.d.ts +1 -1
  65. package/dist/features/opengateway-provider/index.d.ts +13 -0
  66. package/dist/hooks/atlas/atlas-hook.d.ts +1 -0
  67. package/dist/hooks/atlas/atlas-lifecycle-store.d.ts +50 -0
  68. package/dist/hooks/atlas/event-handler.d.ts +1 -0
  69. package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
  70. package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
  71. package/dist/hooks/atlas/tool-execute-before.d.ts +3 -0
  72. package/dist/hooks/atlas/types.d.ts +1 -0
  73. package/dist/hooks/index.d.ts +1 -1
  74. package/dist/hooks/prometheus-md-only/agent-resolution.d.ts +2 -2
  75. package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
  76. package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
  77. package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
  78. package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
  79. package/dist/hooks/runtime-fallback/types.d.ts +3 -1
  80. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  81. package/dist/hooks/{start-work → ulw-execute}/context-info-builder.d.ts +1 -1
  82. package/dist/hooks/{start-work → ulw-execute}/index.d.ts +1 -1
  83. package/dist/hooks/ulw-execute/ulw-execute-hook.d.ts +23 -0
  84. package/dist/index.js +11724 -6355
  85. package/dist/oh-my-opencode.schema.json +15 -2
  86. package/dist/plugin/chat-message/types.d.ts +3 -3
  87. package/dist/plugin/chat-message/ulw-execute-message.d.ts +5 -0
  88. package/dist/plugin/event-session-lifecycle.d.ts +1 -0
  89. package/dist/plugin/hooks/create-core-hooks.d.ts +2 -1
  90. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -2
  91. package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
  92. package/dist/plugin/messages-transform.d.ts +1 -0
  93. package/dist/shared/index.d.ts +1 -0
  94. package/dist/shared/normalize-sdk-response.d.ts +1 -0
  95. package/dist/shared/runtime-fallback-retry-marker.d.ts +16 -0
  96. package/dist/shared/shell-env.d.ts +1 -1
  97. package/dist/skills/ast-grep/AGENTS.md +51 -0
  98. package/dist/skills/coding-agent-sessions/AGENTS.md +62 -0
  99. package/dist/skills/coding-agent-sessions/SKILL.md +3 -2
  100. package/dist/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  101. package/dist/skills/coding-agent-sessions/references/senpi.md +4 -4
  102. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  103. package/dist/skills/frontend/SKILL.md +11 -7
  104. package/dist/skills/frontend/references/design/_INDEX.md +1 -0
  105. package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
  106. package/dist/skills/frontend/references/design/stylegallery.md +80 -0
  107. package/dist/skills/frontend/references/designpowers/README.md +1 -1
  108. package/dist/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  109. package/dist/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  110. package/dist/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  111. package/dist/skills/frontend/references/designpowers/orchestration.md +1 -1
  112. package/dist/skills/frontend/references/designpowers/routing.md +5 -5
  113. package/dist/skills/review-work/SKILL.md +3 -3
  114. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  115. package/dist/skills/ultimate-browsing/SKILL.md +2 -0
  116. package/dist/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  117. package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
  118. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  119. package/dist/skills/{start-work → ulw-execute}/SKILL.md +9 -8
  120. package/dist/skills/ulw-plan/SKILL.md +6 -6
  121. package/dist/skills/ulw-plan/references/full-workflow.md +31 -7
  122. package/dist/skills/ulw-plan/references/intent-clear.md +2 -1
  123. package/dist/skills/ulw-plan/references/intent-unclear.md +5 -5
  124. package/dist/skills/ulw-research/SKILL.md +1 -1
  125. package/dist/skills/visual-qa/AGENTS.md +58 -0
  126. package/dist/skills/visual-qa/SKILL.md +3 -2
  127. package/dist/tools/delegate-task/builtin-categories.d.ts +1 -0
  128. package/dist/tools/delegate-task/builtin-category-definition.d.ts +1 -0
  129. package/dist/tools/delegate-task/tool-description.d.ts +3 -1
  130. package/dist/tui.js +8824 -8906
  131. package/package.json +38 -35
  132. package/packages/git-bash-mcp/dist/cli.js +5 -1
  133. package/packages/git-bash-mcp/package.json +1 -1
  134. package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +44 -0
  135. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +0 -28
  136. package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
  137. package/packages/lsp-core/src/lsp/client-wrapper.test.ts +66 -13
  138. package/packages/lsp-core/src/lsp/client-wrapper.ts +70 -18
  139. package/packages/lsp-core/src/lsp/outside-context-workspace.ts +33 -0
  140. package/packages/lsp-core/src/lsp/workspace-edit-adversarial.test.ts +20 -1
  141. package/packages/lsp-core/src/lsp/workspace-markers.ts +1 -0
  142. package/packages/lsp-core/src/tools/diagnostics.ts +3 -3
  143. package/packages/lsp-core/src/tools/navigation.ts +4 -2
  144. package/packages/lsp-core/src/tools/rename.ts +4 -2
  145. package/packages/lsp-core/src/tools/symbols.ts +1 -1
  146. package/packages/lsp-daemon/dist/cli.js +246 -185
  147. package/packages/lsp-daemon/dist/client.js +222 -164
  148. package/packages/lsp-daemon/dist/ensure-daemon.js +1 -0
  149. package/packages/lsp-daemon/dist/index.js +236 -177
  150. package/packages/lsp-daemon/dist/version-reap.js +1 -1
  151. package/packages/lsp-tools-mcp/dist/cli.js +198 -136
  152. package/packages/lsp-tools-mcp/dist/lsp/manager.js +62 -92
  153. package/packages/lsp-tools-mcp/dist/mcp.js +200 -138
  154. package/packages/lsp-tools-mcp/dist/request-context.js +11 -12
  155. package/packages/lsp-tools-mcp/dist/tools.js +204 -146
  156. package/packages/omo-codex/THIRD-PARTY-NOTICES.md +4 -4
  157. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -4
  158. package/packages/omo-codex/plugin/AGENTS.md +47 -0
  159. package/packages/omo-codex/plugin/README.md +1 -1
  160. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +32 -31
  161. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  162. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  163. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -0
  164. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +224 -81
  165. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +224 -82
  166. package/packages/omo-codex/plugin/components/codegraph/package.json +4 -4
  167. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +1 -0
  168. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +1 -0
  169. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
  170. package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
  171. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
  172. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  173. package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
  174. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
  175. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
  176. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
  177. package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
  178. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
  179. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  180. package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
  181. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
  182. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +1 -5
  183. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +1 -5
  184. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  185. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -5
  186. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +1 -5
  187. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +4 -21
  188. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
  189. package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
  190. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
  191. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +217 -171
  192. package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
  193. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  194. package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
  195. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  196. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
  197. package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
  198. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
  199. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
  200. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
  201. package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
  202. package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
  203. package/packages/omo-codex/plugin/components/rules/dist/cli.js +57 -42
  204. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  205. package/packages/omo-codex/plugin/components/rules/package.json +7 -7
  206. package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
  207. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
  208. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +6 -2
  209. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
  210. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
  211. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
  212. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
  213. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
  214. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
  215. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
  216. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
  217. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
  218. package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
  219. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
  220. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
  221. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
  222. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +1 -2
  223. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
  224. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
  225. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
  226. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
  227. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +1 -2
  228. package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
  229. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
  230. package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
  231. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
  232. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  233. package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
  234. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +3 -9
  235. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
  236. package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
  237. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2433 -422
  238. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2437 -426
  239. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  240. package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
  241. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
  242. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
  243. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
  244. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
  245. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -0
  246. package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
  247. package/packages/omo-codex/plugin/components/ultrawork/directive.md +13 -1
  248. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  249. package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -5
  250. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +13 -1
  251. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -6
  252. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
  253. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
  254. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
  255. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
  256. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
  257. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
  258. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +5 -4
  259. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
  260. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +5 -5
  261. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
  262. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +6 -6
  263. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +12 -12
  264. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +28 -0
  265. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
  266. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
  267. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
  268. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +3 -3
  269. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
  270. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
  271. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
  272. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +1 -4
  273. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +8 -22
  274. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +16 -0
  275. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -1
  276. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
  277. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +13 -1
  278. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +2 -4
  279. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +1 -1
  280. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +1 -1
  281. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +3 -3
  282. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  283. package/packages/omo-codex/plugin/components/ulw-loop/package.json +5 -5
  284. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +3 -2
  285. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
  286. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +1 -0
  287. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +3 -1
  288. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
  289. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +1 -1
  290. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +3 -3
  291. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
  292. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +25 -0
  293. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +2 -2
  294. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +18 -0
  295. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
  296. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
  297. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
  298. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
  299. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  300. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +4 -5
  301. package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
  302. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  303. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  304. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  305. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  306. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  307. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  308. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  309. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  310. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  311. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  312. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  313. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  314. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  315. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  316. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  317. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  318. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +17 -0
  319. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  320. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +17 -0
  321. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  322. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  323. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  324. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  325. package/packages/omo-codex/plugin/package-lock.json +681 -395
  326. package/packages/omo-codex/plugin/package.json +2 -2
  327. package/packages/omo-codex/plugin/scripts/AGENTS.md +40 -0
  328. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -1
  329. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +11 -11
  330. package/packages/omo-codex/plugin/shared/package.json +3 -4
  331. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
  332. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
  333. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +3 -2
  334. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  335. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +4 -4
  336. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  337. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +11 -7
  338. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
  339. package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
  340. package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
  341. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
  342. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  343. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  344. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  345. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
  346. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
  347. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +4 -4
  348. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  349. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +2 -0
  350. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  351. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
  352. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  353. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +13 -1
  354. package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +12 -11
  355. package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
  356. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +3 -2
  357. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
  358. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +1 -0
  359. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -6
  360. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
  361. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
  362. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
  363. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +1 -1
  364. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
  365. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +3 -2
  366. package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
  367. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
  368. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +8 -28
  369. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -1
  370. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
  371. package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
  372. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
  373. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
  374. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -1
  375. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +2 -2
  376. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +4 -4
  377. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
  378. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
  379. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +101 -0
  380. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +12 -12
  381. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +1 -119
  382. package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
  383. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
  384. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
  385. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
  386. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
  387. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +0 -3
  388. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
  389. package/packages/omo-codex/scripts/AGENTS.md +36 -0
  390. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2601 -528
  391. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
  392. package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
  393. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
  394. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +3 -2
  395. package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  396. package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +4 -4
  397. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  398. package/packages/shared-skills/skills/frontend/SKILL.md +11 -7
  399. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
  400. package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
  401. package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
  402. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
  403. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  404. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  405. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  406. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
  407. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
  408. package/packages/shared-skills/skills/review-work/SKILL.md +3 -3
  409. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  410. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +2 -0
  411. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  412. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
  413. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  414. package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +9 -8
  415. package/packages/shared-skills/skills/ulw-plan/SKILL.md +6 -6
  416. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +31 -7
  417. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
  418. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
  419. package/packages/shared-skills/skills/ulw-research/SKILL.md +1 -1
  420. package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
  421. package/packages/shared-skills/skills/visual-qa/SKILL.md +3 -2
  422. package/script/qa/web-terminal-visual-qa.mjs +2 -0
  423. package/script/qa/xterm-live-terminal.mjs +18 -2
  424. package/dist/config/schema/start-work.d.ts +0 -5
  425. package/dist/features/builtin-commands/templates/start-work.d.ts +0 -1
  426. package/dist/hooks/start-work/start-work-hook.d.ts +0 -23
  427. package/dist/plugin/chat-message/start-work-message.d.ts +0 -5
  428. package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
  429. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
  430. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
  431. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
  432. package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
  433. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
  434. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
  435. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
  436. /package/dist/hooks/{start-work → ulw-execute}/context-info-formatters.d.ts +0 -0
  437. /package/dist/hooks/{start-work → ulw-execute}/explicit-plan-context.d.ts +0 -0
  438. /package/dist/hooks/{start-work → ulw-execute}/notepad-scaffold.d.ts +0 -0
  439. /package/dist/hooks/{start-work → ulw-execute}/parse-user-request.d.ts +0 -0
  440. /package/dist/hooks/{start-work → ulw-execute}/plan-discovery-context.d.ts +0 -0
  441. /package/dist/hooks/{start-work → ulw-execute}/plan-selection.d.ts +0 -0
  442. /package/dist/hooks/{start-work → ulw-execute}/session-plan-affinity.d.ts +0 -0
  443. /package/dist/hooks/{start-work → ulw-execute}/work-initializer.d.ts +0 -0
  444. /package/dist/hooks/{start-work → ulw-execute}/worktree-block.d.ts +0 -0
  445. /package/dist/hooks/{start-work → ulw-execute}/worktree-detector.d.ts +0 -0
  446. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
  447. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
  448. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/LICENSE +0 -0
  449. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
  450. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +0 -0
  451. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
  452. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
  453. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
  454. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
  455. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
  456. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
  457. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
  458. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
  459. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
  460. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
@@ -15,103 +15,25 @@ const agentSchemaKeys = new Set([
15
15
  "developer_instructions",
16
16
  ]);
17
17
 
18
+ // `includes` entries below are machine-consumed tokens only: EVIDENCE_RECORDED is the sentinel the
19
+ // lazycodex-executor-verify SubagentStop hook greps from worker messages; recommendation, blockers,
20
+ // codeQualityStatus, not_applicable, surfaceEvidence, and adversarialCases are fields the ulw-loop
21
+ // quality gate parses out of reviewer/QA reports; <attemptDir>/<goalId>-code-review.md and
22
+ // -manual-qa.md are the artifact names the ulw-loop spawn guard requires before a gate-reviewer
23
+ // spawn; currentAttemptDir is a field of `ulw-loop status --json`.
18
24
  const lazycodexAgentInvariants = new Map([
19
- [
20
- "explorer.toml",
21
- {
22
- model: "gpt-5.6-luna",
23
- effort: "low",
24
- includes: [/Read-only/, /working tree/, /rg/],
25
- },
26
- ],
27
- [
28
- "librarian.toml",
29
- {
30
- model: "gpt-5.6-luna",
31
- effort: "low",
32
- includes: [/Read-only/, /SHA-pinned GitHub permalink/, /external/],
33
- },
34
- ],
35
- [
36
- "metis.toml",
37
- {
38
- model: "gpt-5.6-sol",
39
- effort: "high",
40
- includes: [/pre-planning analyst/i, /contradictions/, /Read-only/],
41
- },
42
- ],
43
- [
44
- "momus.toml",
45
- {
46
- model: "gpt-5.6-terra",
47
- effort: "high",
48
- includes: [/plan reviewer/i, /OKAY, ITERATE, or REJECT/, /Read-only/],
49
- },
50
- ],
51
- [
52
- "plan.toml",
53
- {
54
- model: "gpt-5.6-sol",
55
- effort: "high",
56
- includes: [/strategic planning consultant/i, /\.omo\/plans\/<slug>\.md/, /never implements/i],
57
- },
58
- ],
59
- [
60
- "lazycodex-worker-low.toml",
61
- {
62
- model: "gpt-5.6-luna",
63
- effort: "high",
64
- includes: [/EVIDENCE_RECORDED: <path>/, /low-difficulty/i, /smallest correct change/i],
65
- },
66
- ],
67
- [
68
- "lazycodex-worker-medium.toml",
69
- {
70
- model: "gpt-5.6-terra",
71
- effort: "high",
72
- includes: [/EVIDENCE_RECORDED: <path>/, /medium-difficulty/i, /smallest correct change/i],
73
- },
74
- ],
75
- [
76
- "lazycodex-worker-high.toml",
77
- {
78
- model: "gpt-5.6-sol",
79
- effort: "medium",
80
- includes: [/EVIDENCE_RECORDED: <path>/, /high-difficulty/i, /smallest correct change/i],
81
- },
82
- ],
83
- [
84
- "lazycodex-clone-fidelity-reviewer.toml",
85
- {
86
- model: "gpt-5.6-terra",
87
- effort: "high",
88
- includes: [/recommendation/, /blockers/, /\.omo\/evidence\/<goal>-clone-fidelity\.md/],
89
- },
90
- ],
91
- [
92
- "lazycodex-code-reviewer.toml",
93
- {
94
- model: "gpt-5.6-terra",
95
- effort: "medium",
96
- includes: [/codeQualityStatus/, /recommendation/, /<attemptDir>\/<goalId>-code-review\.md/, /currentAttemptDir/],
97
- },
98
- ],
99
- [
100
- "lazycodex-qa-executor.toml",
101
- {
102
- model: "gpt-5.6-luna",
103
- effort: "high",
104
- includes: [/not_applicable/, /surfaceEvidence/, /adversarialCases/, /<attemptDir>\/<goalId>-manual-qa\.md/],
105
- },
106
- ],
107
- [
108
- "lazycodex-gate-reviewer.toml",
109
- {
110
- model: "gpt-5.6-sol",
111
- effort: "low",
112
- includes: [/APPROVE\/REJECT/, /blockers/, /<attemptDir>\/<goalId>-gate-review\.md/, /currentAttemptDir/],
113
- },
114
- ],
25
+ ["explorer.toml", { model: "gpt-5.6-luna", effort: "low" }],
26
+ ["librarian.toml", { model: "gpt-5.6-luna", effort: "low" }],
27
+ ["metis.toml", { model: "gpt-5.6-sol", effort: "high" }],
28
+ ["momus.toml", { model: "gpt-5.6-terra", effort: "high" }],
29
+ ["plan.toml", { model: "gpt-5.6-sol", effort: "high" }],
30
+ ["lazycodex-worker-low.toml", { model: "gpt-5.6-luna", effort: "high", includes: [/EVIDENCE_RECORDED: <path>/] }],
31
+ ["lazycodex-worker-medium.toml", { model: "gpt-5.6-terra", effort: "high", includes: [/EVIDENCE_RECORDED: <path>/] }],
32
+ ["lazycodex-worker-high.toml", { model: "gpt-5.6-sol", effort: "medium", includes: [/EVIDENCE_RECORDED: <path>/] }],
33
+ ["lazycodex-clone-fidelity-reviewer.toml", { model: "gpt-5.6-terra", effort: "high", includes: [/recommendation/, /blockers/] }],
34
+ ["lazycodex-code-reviewer.toml", { model: "gpt-5.6-terra", effort: "medium", includes: [/codeQualityStatus/, /recommendation/, /<attemptDir>\/<goalId>-code-review\.md/, /currentAttemptDir/] }],
35
+ ["lazycodex-qa-executor.toml", { model: "gpt-5.6-luna", effort: "high", includes: [/not_applicable/, /surfaceEvidence/, /adversarialCases/, /<attemptDir>\/<goalId>-manual-qa\.md/] }],
36
+ ["lazycodex-gate-reviewer.toml", { model: "gpt-5.6-sol", effort: "low", includes: [/blockers/, /currentAttemptDir/] }],
115
37
  ]);
116
38
 
117
39
  const externalSourceTokenPattern = new RegExp(
@@ -156,7 +78,6 @@ test("#given bundled Codex agents #when components/ultrawork/agents directory is
156
78
  }
157
79
  }
158
80
  });
159
-
160
81
  test("#given bundled agent TOMLs #when nickname_candidates are inspected #then they use only the codex-accepted charset", async () => {
161
82
  // given: codex_app_server ignores a role whose nickname has characters outside
162
83
  // ASCII letters, digits, spaces, hyphens, underscores (observed live in task-15 QA)
@@ -174,16 +95,6 @@ test("#given bundled agent TOMLs #when nickname_candidates are inspected #then t
174
95
  }
175
96
  });
176
97
 
177
- test("#given planner agent prompt #when inspected #then generated artifacts stay under .omo", async () => {
178
- const prompt = await readFile(join(root, "components", "ultrawork", "agents", "plan.toml"), "utf8");
179
-
180
- assert.match(prompt, /\.omo\/plans\/<slug>\.md/);
181
- assert.match(prompt, /<attemptDir>\/task-<N>-<slug>\.<ext>/);
182
- assert.match(prompt, /\.omo\/evidence\/ulw\/<session>\/<goalId>\/a<attempt>/);
183
- assert.doesNotMatch(prompt, /(?<!\.omo\/)plans\/<slug>\.md/);
184
- assert.doesNotMatch(prompt, /(?<!\.omo\/)evidence\/task-/);
185
- });
186
-
187
98
  test("#given lazycodex agent prompts #when inspected #then each role pins model effort and evidence discipline", async () => {
188
99
  const agentsDir = join(root, "components", "ultrawork", "agents");
189
100
 
@@ -197,73 +108,8 @@ test("#given lazycodex agent prompts #when inspected #then each role pins model
197
108
  assert.doesNotMatch(prompt, /^blocking\s*=/m);
198
109
  assert.doesNotMatch(prompt, externalSourceTokenPattern);
199
110
 
200
- for (const pattern of invariant.includes) {
111
+ for (const pattern of invariant.includes ?? []) {
201
112
  assert.match(prompt, pattern, `${fileName} must include ${pattern}`);
202
113
  }
203
114
  }
204
115
  });
205
-
206
- test("#given LazyCodex reviewer prompts #when inspected #then anti-slop review coverage is required", async () => {
207
- const agentsDir = join(root, "components", "ultrawork", "agents");
208
- const codeReviewer = await readFile(join(agentsDir, "lazycodex-code-reviewer.toml"), "utf8");
209
- const gateReviewer = await readFile(join(agentsDir, "lazycodex-gate-reviewer.toml"), "utf8");
210
-
211
- assert.match(codeReviewer, /remove-ai-slops/);
212
- assert.match(codeReviewer, /programming/);
213
- assert.match(codeReviewer, /load or consult/);
214
- assert.match(codeReviewer, /documented criteria/);
215
- assert.match(codeReviewer, /violates either skill perspective/);
216
- assert.match(codeReviewer, /overfit\/slop review pass/);
217
- assert.match(codeReviewer, /deletion-only tests/);
218
- assert.match(codeReviewer, /tests that merely verify a requested removal/);
219
- assert.match(codeReviewer, /tautological tests/);
220
- assert.match(codeReviewer, /mirror implementation constants/);
221
- assert.match(codeReviewer, /unnecessary production data extraction, parsing, or normalization/);
222
- assert.match(codeReviewer, /false confidence/);
223
-
224
- assert.match(gateReviewer, /remove-ai-slops/);
225
- assert.match(gateReviewer, /programming/);
226
- assert.match(gateReviewer, /load or consult/);
227
- assert.match(gateReviewer, /documented criteria/);
228
- assert.match(gateReviewer, /Run the `remove-ai-slops`/);
229
- assert.match(gateReviewer, /Apply the `programming`/);
230
- assert.match(gateReviewer, /overfit\/slop pass yourself/);
231
- assert.match(gateReviewer, /tests that merely verify a requested removal/);
232
- assert.match(gateReviewer, /deletion-only/);
233
- assert.match(gateReviewer, /tautological/);
234
- assert.match(gateReviewer, /implementation-mirroring tests/);
235
- assert.match(gateReviewer, /unnecessary production extraction, parsing, or normalization/);
236
-
237
- const directPassIndex = gateReviewer.indexOf("overfit/slop pass yourself");
238
- const reportCoverageIndex = gateReviewer.indexOf("Then confirm the code review report");
239
- assert.notEqual(directPassIndex, -1);
240
- assert.notEqual(reportCoverageIndex, -1);
241
- assert.ok(
242
- directPassIndex < reportCoverageIndex,
243
- "gate reviewer must perform the overfit/slop pass directly before checking report coverage",
244
- );
245
- });
246
-
247
- test("#given done-gate reviewer prompts #when inspected #then burden of proof is approve-unless-cited and reject priors are gone", async () => {
248
- const agentsDir = join(root, "components", "ultrawork", "agents");
249
- const gateReviewer = await readFile(join(agentsDir, "lazycodex-gate-reviewer.toml"), "utf8");
250
- const qaExecutor = await readFile(join(agentsDir, "lazycodex-qa-executor.toml"), "utf8");
251
- const codeReviewer = await readFile(join(agentsDir, "lazycodex-code-reviewer.toml"), "utf8");
252
-
253
- assert.match(gateReviewer, /APPROVE unless you can cite/);
254
- assert.match(gateReviewer, /violatedCriterion/);
255
- assert.match(gateReviewer, /evidencePointer/);
256
- assert.match(gateReviewer, /top blockers inline/);
257
- assert.match(gateReviewer, /is a NOTE, not a blocker/);
258
- assert.match(gateReviewer, /You do NOT check/);
259
- assert.doesNotMatch(gateReviewer, /Assume the work has already failed/);
260
- assert.doesNotMatch(gateReviewer, /Return exactly one recommendation: APPROVE\/REJECT\./);
261
-
262
- assert.match(qaExecutor, /one-line reason/);
263
- assert.match(qaExecutor, /rejecting a legitimately untriggered class is itself an error/);
264
- assert.doesNotMatch(qaExecutor, /Trust nothing\./);
265
-
266
- assert.match(codeReviewer, /MEDIUM by default/);
267
- assert.doesNotMatch(codeReviewer, /Treat useless tests or needless production complexity as CRITICAL\/HIGH/);
268
- });
269
-
@@ -32,7 +32,7 @@ test("#given isolated components #when hooks are inspected #then commands stay i
32
32
  "components/lsp/dist/cli.js",
33
33
  "components/codegraph/dist/cli.js",
34
34
  "components/rules/dist/cli.js",
35
- "components/start-work-continuation/dist/cli.js",
35
+ "components/ulw-execute-continuation/dist/cli.js",
36
36
  "components/telemetry/dist/cli.js",
37
37
  "components/teammode/dist/cli.js",
38
38
  "components/ulw-loop/dist/cli.js",
@@ -48,7 +48,7 @@ test("#given isolated components #when hooks are inspected #then commands stay i
48
48
  assert.equal(await exists("scripts/migrate-codex-config.mjs"), true);
49
49
  });
50
50
 
51
- test("#given aggregate Stop hooks #when inspected #then start-work continuation and ulw-loop resume are separate groups", async () => {
51
+ test("#given aggregate Stop hooks #when inspected #then ulw-execute continuation and ulw-loop resume are separate groups", async () => {
52
52
  // given
53
53
  const manifests = await readAggregateHookManifests();
54
54
 
@@ -60,11 +60,11 @@ test("#given aggregate Stop hooks #when inspected #then start-work continuation
60
60
 
61
61
  // then
62
62
  assert.equal(stopCommands.length, 2);
63
- assert.ok(stopCommands.some((command) => command.includes("start-work-continuation/dist/cli.js")));
63
+ assert.ok(stopCommands.some((command) => command.includes("ulw-execute-continuation/dist/cli.js")));
64
64
  assert.ok(stopCommands.some((command) => command.includes("ulw-loop/dist/cli.js\" hook stop")));
65
65
  });
66
66
 
67
- test("#given aggregate SubagentStop hooks #when inspected #then start-work and LazyCodex executor verifier are separate groups", async () => {
67
+ test("#given aggregate SubagentStop hooks #when inspected #then ulw-execute and LazyCodex executor verifier are separate groups", async () => {
68
68
  // given
69
69
  const manifests = await readAggregateHookManifests();
70
70
 
@@ -84,7 +84,7 @@ test("#given aggregate SubagentStop hooks #when inspected #then start-work and L
84
84
  assert.equal(verifierGroups.length, 1);
85
85
  assert.equal(verifierGroups[0]?.groupIndex, 0);
86
86
  assert.equal(verifierGroups[0]?.handler.timeout, 10);
87
- assert.match(verifierGroups[0]?.handler.statusMessage ?? "", /^\(OmO [^)]+\) Verifying LazyCodex Executor Evidence$/);
87
+ assert.match(verifierGroups[0]?.handler.statusMessage ?? "", /\S/);
88
88
  });
89
89
 
90
90
  test("#given aggregate PostCompact hooks #when hooks are inspected #then LSP diagnostics cache reset is registered", async () => {
@@ -100,7 +100,7 @@ test("#given aggregate PostCompact hooks #when hooks are inspected #then LSP dia
100
100
 
101
101
  // then
102
102
  assert.equal(lspPostCompactHooks.length, 1);
103
- assert.match(lspPostCompactHooks[0]?.handler.statusMessage ?? "", /^\(OmO [^)]+\) Resetting LSP Diagnostics Cache$/);
103
+ assert.match(lspPostCompactHooks[0]?.handler.statusMessage ?? "", /\S/);
104
104
  });
105
105
 
106
106
  test("#given aggregate hook commands #when inspected #then every command exposes a Codex status message", async () => {
@@ -142,23 +142,6 @@ test("#given component hook commands #when inspected #then standalone packages e
142
142
  assert.deepEqual(missingStatusMessages, []);
143
143
  });
144
144
 
145
- test("#given hook status messages #when inspected #then labels describe OMO responsibilities instead of the hook runner", async () => {
146
- // given
147
- const componentHooks = await readComponentHookManifests();
148
-
149
- // when
150
- const commandHooks = [
151
- ...(await readAggregateCommandHooks()),
152
- ...componentHooks.flatMap(({ source, hooks }) => collectCommandHooks(hooks, source)),
153
- ];
154
- const genericStatusMessages = commandHooks
155
- .filter(({ handler }) => typeof handler.statusMessage !== "string" || /\bhook\b/i.test(handler.statusMessage))
156
- .map(hookLocation);
157
-
158
- // then
159
- assert.deepEqual(genericStatusMessages, []);
160
- });
161
-
162
145
  test("#given aggregate OMO plugin is enabled #when hooks are inspected #then shell guidance and ulw-loop guard are registered", async () => {
163
146
  // given
164
147
  const manifests = await readAggregateHookManifests();
@@ -169,9 +152,7 @@ test("#given aggregate OMO plugin is enabled #when hooks are inspected #then she
169
152
 
170
153
  // then
171
154
  assert.match(text, /components\/git-bash\/dist\/cli\.js/);
172
- assert.match(text, /Recommending Git Bash MCP/);
173
155
  assert.match(text, /hook post-compact/);
174
- assert.match(text, /Resetting Git Bash MCP Reminder/);
175
156
  assert.match(text, /components\/ulw-loop\/dist\/cli\.js/);
176
157
  assert.match(text, /hook pre-tool-use/);
177
158
  assert.deepEqual(preToolUseGroups.map((group) => group.matcher), [
@@ -221,7 +202,6 @@ test("#given aggregate SessionStart hooks #when inspected #then LazyCodex auto-u
221
202
  // then
222
203
  assert.equal(autoUpdateGroup?.matcher, "^startup$");
223
204
  assert.match(text, /scripts\/auto-update\.mjs/);
224
- assert.match(text, /Checking Auto Update/);
225
205
  assert(sessionStartCommands.some((command) => command.includes("scripts/auto-update.mjs")));
226
206
  });
227
207
 
@@ -265,7 +245,7 @@ test("#given aggregate PostToolUse hooks #when inspected #then CodeGraph init gu
265
245
  // then
266
246
  assert.equal(codegraphPostToolUseHooks.length, 1);
267
247
  assert.equal(codegraphPostToolUseHooks[0]?.matcher, "^(codegraph[._].*|mcp__codegraph__.*)$");
268
- assert.match(codegraphPostToolUseHooks[0]?.handler.statusMessage ?? "", /^\(OmO [^)]+\) Checking CodeGraph Init Guidance$/);
248
+ assert.match(codegraphPostToolUseHooks[0]?.handler.statusMessage ?? "", /\S/);
269
249
  });
270
250
 
271
251
  test("#given aggregate PostToolUse hooks #when inspected #then thread title hygiene is registered for created Codex threads", async () => {
@@ -282,7 +262,7 @@ test("#given aggregate PostToolUse hooks #when inspected #then thread title hygi
282
262
  // then
283
263
  assert.equal(threadTitleHooks.length, 1);
284
264
  assert.equal(threadTitleHooks[0]?.matcher, "^(create_thread|codex_app\\.create_thread)$");
285
- assert.match(threadTitleHooks[0]?.handler.statusMessage ?? "", /^\(OmO [^)]+\) Checking Thread Title Hygiene$/);
265
+ assert.match(threadTitleHooks[0]?.handler.statusMessage ?? "", /\S/);
286
266
  });
287
267
 
288
268
  test("#given aggregate plugin packaging #when inspected #then hooks and compatibility sentinels stay Python-free", async () => {
@@ -60,10 +60,10 @@ test("#given component directories #when scanned #then only intentional resource
60
60
  "lazycodex-executor-verify",
61
61
  "lsp",
62
62
  "rules",
63
- "start-work-continuation",
64
63
  "teammode",
65
64
  "telemetry",
66
65
  "ultrawork",
66
+ "ulw-execute-continuation",
67
67
  "ulw-loop",
68
68
  ]);
69
69
  for (const name of componentNames) {
@@ -1,10 +1,8 @@
1
1
  import { readdir, readFile, stat } from "node:fs/promises";
2
- import { dirname, join } from "node:path";
2
+ import { basename, dirname, join, sep } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
-
5
4
  export const root = dirname(dirname(fileURLToPath(import.meta.url)));
6
5
  export const repoRoot = join(root, "..", "..", "..");
7
-
8
6
  export async function readJson(relativePath) {
9
7
  return JSON.parse(await readFile(join(root, relativePath), "utf8"));
10
8
  }
@@ -79,18 +77,182 @@ export function hookLocation({ source, eventName, groupIndex, handlerIndex, hand
79
77
  return `${source}:${eventName}:${groupIndex}:${handlerIndex}:${handler.command}`;
80
78
  }
81
79
 
82
- export function findInvalidSpawnAgentRoleParameters(content) {
83
- return [...content.matchAll(/spawn_agent\([^)\n]*(?:agent_type|model|reasoning_effort)\s*=/g)].map((match) => match[0]);
80
+ const SPAWN_AGENT_START = /(?:(?<receiver>\b[A-Za-z_]\w*)\s*\.\s*)?(?<callee>\bspawn_agent)\s*\(/g;
81
+
82
+ async function collectFiles(directory, predicate) {
83
+ let entries;
84
+ try {
85
+ entries = await readdir(directory, { withFileTypes: true });
86
+ } catch (error) {
87
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") return [];
88
+ throw error;
89
+ }
90
+
91
+ const files = [];
92
+ for (const entry of entries) {
93
+ const path = join(directory, entry.name);
94
+ if (entry.isDirectory()) files.push(...(await collectFiles(path, predicate)));
95
+ else if (entry.isFile() && predicate(path)) files.push(path);
96
+ }
97
+ return files;
84
98
  }
85
99
 
86
- export function findSpawnAgentCallsWithoutForkContextFalse(content) {
87
- const missingForkContext = [];
88
- const regex = /spawn_agent\(([^)]*)\)/g;
89
- for (const match of content.matchAll(regex)) {
90
- const call = match[0];
91
- if (!/"fork_context"\s*:\s*false|fork_context:\s*false|fork_context=false|"fork_turns"\s*:\s*"none"|fork_turns:\s*"none"|fork_turns="none"/.test(call)) {
92
- missingForkContext.push(call);
100
+ export async function listShippedSpawnPromptFiles() {
101
+ const skillFiles = [
102
+ ...(await collectFiles(join(root, "skills"), (path) => basename(path) === "SKILL.md")),
103
+ ...(await collectFiles(
104
+ join(root, "components"),
105
+ (path) => path.includes(`${sep}skills${sep}`) && basename(path) === "SKILL.md",
106
+ )),
107
+ ];
108
+ const hephaestusRules = await collectFiles(
109
+ join(root, "components", "rules", "bundled-rules", "hephaestus"),
110
+ (path) => path.endsWith(".md"),
111
+ );
112
+ return [...skillFiles, ...hephaestusRules].sort();
113
+ }
114
+
115
+ export function findSpawnAgentCalls(content) {
116
+ const calls = [];
117
+ for (const match of content.matchAll(SPAWN_AGENT_START)) {
118
+ const openingParenthesis = match.index + match[0].lastIndexOf("(");
119
+ let depth = 1;
120
+ let quote = null;
121
+ let escaped = false;
122
+
123
+ for (let index = openingParenthesis + 1; index < content.length; index += 1) {
124
+ const character = content[index];
125
+ if (quote !== null) {
126
+ if (escaped) escaped = false;
127
+ else if (character === "\\") escaped = true;
128
+ else if (character === quote) quote = null;
129
+ continue;
130
+ }
131
+ if (character === '"' || character === "'" || character === "`") {
132
+ quote = character;
133
+ continue;
134
+ }
135
+ if (character === "(") depth += 1;
136
+ else if (character === ")") depth -= 1;
137
+ if (depth !== 0) continue;
138
+
139
+ const { receiver = null, callee } = match.groups;
140
+ calls.push({ call: content.slice(match.index, index + 1), index: match.index, receiver, callee });
141
+ break;
93
142
  }
94
143
  }
95
- return missingForkContext;
144
+ return calls;
96
145
  }
146
+
147
+ function tokensForSpawnCall(call) {
148
+ const tokens = [];
149
+ let braceDepth = 0;
150
+ let bracketDepth = 0;
151
+ let parenthesisDepth = 0;
152
+
153
+ for (let index = call.indexOf("(") + 1; index < call.length - 1; ) {
154
+ const character = call[index];
155
+ if (/\s/.test(character)) {
156
+ index += 1;
157
+ continue;
158
+ }
159
+ if (character === '"' || character === "'" || character === "`") {
160
+ const start = index;
161
+ const quote = character;
162
+ let value = "";
163
+ index += 1;
164
+ while (index < call.length - 1) {
165
+ const current = call[index];
166
+ if (current === "\\" && index + 1 < call.length - 1) {
167
+ value += call[index + 1];
168
+ index += 2;
169
+ continue;
170
+ }
171
+ index += 1;
172
+ if (current === quote) break;
173
+ value += current;
174
+ }
175
+ tokens.push({ type: "string", value, start, end: index, braceDepth, bracketDepth, parenthesisDepth });
176
+ continue;
177
+ }
178
+ if (/[A-Za-z_]/.test(character)) {
179
+ const start = index;
180
+ while (/[A-Za-z0-9_]/.test(call[index] ?? "")) index += 1;
181
+ tokens.push({ type: "identifier", value: call.slice(start, index), start, end: index,
182
+ braceDepth, bracketDepth, parenthesisDepth });
183
+ continue;
184
+ }
185
+
186
+ if (character === "{") braceDepth += 1;
187
+ else if (character === "}") braceDepth -= 1;
188
+ else if (character === "[") bracketDepth += 1;
189
+ else if (character === "]") bracketDepth -= 1;
190
+ else if (character === "(") parenthesisDepth += 1;
191
+ else if (character === ")") parenthesisDepth -= 1;
192
+ else if (character === ":" || character === "=") {
193
+ tokens.push({ type: "separator", value: character, start: index, end: index + 1,
194
+ braceDepth, bracketDepth, parenthesisDepth });
195
+ }
196
+ index += 1;
197
+ }
198
+ return tokens;
199
+ }
200
+
201
+ function spawnParameters(call) {
202
+ const tokens = tokensForSpawnCall(call);
203
+ const parameters = [];
204
+ for (let index = 0; index < tokens.length - 2; index += 1) {
205
+ const key = tokens[index];
206
+ const separator = tokens[index + 1];
207
+ const value = tokens[index + 2];
208
+ const isArgumentScope = key.parenthesisDepth === 0 && key.bracketDepth === 0 && key.braceDepth <= 1;
209
+ const isSameScope =
210
+ separator.braceDepth === key.braceDepth && separator.bracketDepth === key.bracketDepth &&
211
+ separator.parenthesisDepth === key.parenthesisDepth && value.braceDepth === key.braceDepth &&
212
+ value.bracketDepth === key.bracketDepth &&
213
+ value.parenthesisDepth === key.parenthesisDepth;
214
+ const isAdjacent = /^\s*$/.test(call.slice(key.end, separator.start)) &&
215
+ /^\s*$/.test(call.slice(separator.end, value.start));
216
+ if (!isArgumentScope || !isSameScope || !isAdjacent || separator.type !== "separator") continue;
217
+ parameters.push({ name: key.value, value, direct: key.braceDepth === 0 });
218
+ }
219
+ return parameters;
220
+ }
221
+
222
+ export function hasSpawnIsolationArgument(call) {
223
+ return spawnParameters(call).some(
224
+ ({ name, value }) => (name === "fork_context" && value.type === "identifier" && value.value === "false") ||
225
+ (name === "fork_turns" && value.type === "string" && value.value === "none"),
226
+ );
227
+ }
228
+
229
+ export function findSpawnAgentCallsWithoutIsolation(content) {
230
+ return findSpawnAgentCalls(content).filter(({ call }) => !hasSpawnIsolationArgument(call));
231
+ }
232
+
233
+ export function findSpawnAgentCallsWithUnsupportedParameters(content) {
234
+ return findSpawnAgentCalls(content).flatMap((entry) => {
235
+ const allowsObjectAgentType = entry.receiver === "multi_agent_v1";
236
+ const parameters = spawnParameters(entry.call)
237
+ .filter(({ name, direct }) => name === "model" || name === "reasoning_effort" ||
238
+ (name === "agent_type" && (direct || !allowsObjectAgentType)))
239
+ .map(({ name }) => name);
240
+ return parameters.length === 0 ? [] : [{ ...entry, parameters }];
241
+ });
242
+ }
243
+
244
+ async function findShippedSpawnViolations(findViolations) {
245
+ const violations = [];
246
+ for (const path of await listShippedSpawnPromptFiles()) {
247
+ const content = await readFile(path, "utf8");
248
+ for (const violation of findViolations(content)) {
249
+ const line = content.slice(0, violation.index).split("\n").length;
250
+ violations.push({ path, line, ...violation });
251
+ }
252
+ }
253
+ return violations;
254
+ }
255
+
256
+ export const findShippedSpawnIsolationViolations = () => findShippedSpawnViolations(findSpawnAgentCallsWithoutIsolation);
257
+ export const findShippedUnsupportedSpawnParameterViolations = () =>
258
+ findShippedSpawnViolations(findSpawnAgentCallsWithUnsupportedParameters);
@@ -1,2 +1,78 @@
1
- // Compatibility sentinel for packaging regressions that inspect this path.
2
- // Focused aggregate coverage lives in aggregate-*.test.mjs.
1
+ import assert from "node:assert/strict";
2
+ import { relative, sep } from "node:path";
3
+ import test from "node:test";
4
+
5
+ import {
6
+ findShippedSpawnIsolationViolations,
7
+ findShippedUnsupportedSpawnParameterViolations,
8
+ findSpawnAgentCalls,
9
+ findSpawnAgentCallsWithoutIsolation,
10
+ findSpawnAgentCallsWithUnsupportedParameters,
11
+ listShippedSpawnPromptFiles,
12
+ root,
13
+ } from "./aggregate-plugin-fixture.mjs";
14
+
15
+ test("#given suffixed spawn-like identifiers #when parsed #then they are not spawn calls", () => {
16
+ const content = 'auto_respawn_agent({agent_type: "explorer"})\nrespawn_agent(message="x")';
17
+
18
+ assert.equal(findSpawnAgentCalls(content).length, 0);
19
+ assert.deepEqual(findSpawnAgentCallsWithUnsupportedParameters(content), []);
20
+ });
21
+
22
+ test("#given nested spawn calls and isolation-like message text #when parsed #then only structural isolation arguments count", () => {
23
+ const content = [
24
+ 'spawn_agent({message: "fork_context:false and a closing ) are prose", task: nested(call())})',
25
+ 'spawn_agent(task_name="v1", message="nested (message)", fork_context=false)',
26
+ 'spawn_agent({"task_name":"v2","fork_turns":"none"})',
27
+ ].join("\n");
28
+
29
+ assert.equal(findSpawnAgentCalls(content).length, 3);
30
+ assert.deepEqual(
31
+ findSpawnAgentCallsWithoutIsolation(content).map(({ call }) => call),
32
+ ['spawn_agent({message: "fork_context:false and a closing ) are prose", task: nested(call())})'],
33
+ );
34
+ });
35
+
36
+ test("#given spawn parameter mutations and role-like prose #when parsed #then only unsupported machine arguments are rejected", () => {
37
+ const content = [
38
+ 'multi_agent_v1.spawn_agent({"message":"model and reasoning_effort are prose","agent_type":"explorer","fork_context":false})',
39
+ 'multi_agent_v1.spawn_agent(agent_type="explorer", message="invalid keyword role", fork_context=false)',
40
+ 'spawn_agent({"message":"invalid flat role","agent_type":"explorer","fork_turns":"none"})',
41
+ 'spawn_agent(agent_type="explorer", message="invalid direct role", fork_turns="none")',
42
+ 'spawn_agent({"message":"model and agent_type are prose","metadata":{"model":"nested","agent_type":"nested"},"fork_turns":"none"})',
43
+ 'spawn_agent({"message":"placeholder prose","agent_type":...,"fork_turns":"none"})',
44
+ 'multi_agent_v1.spawn_agent({"message":"invalid model","model":"gpt-5","fork_context":false})',
45
+ 'spawn_agent(message="invalid effort", reasoning_effort="high", fork_context=false)',
46
+ ].join("\n");
47
+
48
+ assert.deepEqual(
49
+ findSpawnAgentCallsWithUnsupportedParameters(content).map(({ parameters }) => parameters),
50
+ [["agent_type"], ["agent_type"], ["agent_type"], ["model"], ["reasoning_effort"]],
51
+ );
52
+ });
53
+
54
+ test("#given shipped generated skills and Hephaestus rules #when spawn calls are scanned #then every call disables parent context", async () => {
55
+ const promptFiles = await listShippedSpawnPromptFiles();
56
+ const relativePaths = promptFiles.map((path) => relative(root, path).split(sep).join("/"));
57
+
58
+ assert(relativePaths.some((path) => path.startsWith("skills/") && path.endsWith("/SKILL.md")));
59
+ assert(relativePaths.some((path) => path.startsWith("components/") && path.includes("/skills/") && path.endsWith("/SKILL.md")));
60
+ assert(relativePaths.some((path) => path.startsWith("components/rules/bundled-rules/hephaestus/") && path.endsWith(".md")));
61
+
62
+ const violations = (await findShippedSpawnIsolationViolations()).map(({ path, line, call }) => ({
63
+ path: relative(root, path).split(sep).join("/"),
64
+ line,
65
+ call,
66
+ }));
67
+ assert.deepEqual(violations, []);
68
+ });
69
+
70
+ test("#given shipped generated skills and Hephaestus rules #when spawn parameters are scanned #then unsupported role and model arguments are absent", async () => {
71
+ const violations = (await findShippedUnsupportedSpawnParameterViolations()).map(({ path, line, call, parameters }) => ({
72
+ path: relative(root, path).split(sep).join("/"),
73
+ line,
74
+ call,
75
+ parameters,
76
+ }));
77
+ assert.deepEqual(violations, []);
78
+ });