oh-my-opencode 4.18.1 → 4.19.0

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 (217) hide show
  1. package/.agents/skills/codex-qa/scripts/lsp-e2e.sh +39 -16
  2. package/.agents/skills/opencode-qa/scripts/lsp-e2e.sh +111 -28
  3. package/README.ja.md +2 -2
  4. package/README.ko.md +2 -2
  5. package/README.md +4 -4
  6. package/README.ru.md +2 -2
  7. package/README.zh-cn.md +2 -2
  8. package/bin/AGENTS.md +33 -0
  9. package/dist/agents/atlas/agent.d.ts +6 -5
  10. package/dist/agents/sisyphus/index.d.ts +5 -0
  11. package/dist/agents/sisyphus/kimi-k3.d.ts +19 -0
  12. package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
  13. package/dist/agents/sisyphus-junior/agent.d.ts +8 -4
  14. package/dist/agents/sisyphus-junior/index.d.ts +2 -0
  15. package/dist/agents/sisyphus-junior/kimi-k3.d.ts +12 -0
  16. package/dist/agents/types.d.ts +2 -2
  17. package/dist/cli/index.js +690 -139
  18. package/dist/cli-node/index.js +690 -139
  19. package/dist/config/index.d.ts +1 -1
  20. package/dist/config/schema/browser-automation.d.ts +1 -0
  21. package/dist/config/schema/commands.d.ts +1 -3
  22. package/dist/config/schema/default-mode.d.ts +1 -1
  23. package/dist/config/schema/goal.d.ts +7 -0
  24. package/dist/config/schema/hooks.d.ts +1 -1
  25. package/dist/config/schema/oh-my-opencode-config.d.ts +6 -10
  26. package/dist/config/schema/ralph-loop.d.ts +1 -1
  27. package/dist/config/schema.d.ts +1 -1
  28. package/dist/create-hooks.d.ts +1 -1
  29. package/dist/features/builtin-commands/templates/goal.d.ts +1 -0
  30. package/dist/features/builtin-commands/templates/stop-continuation.d.ts +1 -1
  31. package/dist/features/builtin-commands/types.d.ts +1 -1
  32. package/dist/hooks/anthropic-context-window-limit-recovery/empty-content-recovery-sdk.d.ts +6 -0
  33. package/dist/hooks/auto-slash-command/executor.d.ts +1 -0
  34. package/dist/hooks/category-skill-reminder/hook.d.ts +9 -1
  35. package/dist/hooks/comment-checker/hook.d.ts +8 -1
  36. package/dist/hooks/goal/command-arguments.d.ts +13 -0
  37. package/dist/hooks/goal/controller.d.ts +26 -0
  38. package/dist/hooks/goal/index.d.ts +23 -0
  39. package/dist/hooks/goal/prompt.d.ts +3 -0
  40. package/dist/hooks/goal/store.d.ts +8 -0
  41. package/dist/hooks/goal/tools.d.ts +10 -0
  42. package/dist/hooks/goal/types.d.ts +93 -0
  43. package/dist/hooks/goal/validation.d.ts +4 -0
  44. package/dist/hooks/index.d.ts +1 -0
  45. package/dist/hooks/keyword-detector/hook.d.ts +1 -2
  46. package/dist/hooks/ralph-loop/types.d.ts +1 -1
  47. package/dist/hooks/todo-continuation-enforcer/types.d.ts +3 -0
  48. package/dist/index.js +3706 -4329
  49. package/dist/oh-my-opencode.schema.json +23 -19
  50. package/dist/plugin/chat-message/loop-commands.d.ts +1 -1
  51. package/dist/plugin/chat-message/types.d.ts +23 -10
  52. package/dist/plugin/hooks/create-core-hooks.d.ts +1 -1
  53. package/dist/plugin/hooks/create-session-hooks.d.ts +3 -2
  54. package/dist/plugin/hooks/create-transform-hooks.d.ts +0 -2
  55. package/dist/plugin/messages-transform.d.ts +1 -0
  56. package/dist/plugin/stop-continuation.d.ts +2 -2
  57. package/dist/plugin-handlers/prometheus-agent-config-builder.d.ts +2 -0
  58. package/dist/shared/system-directive.d.ts +0 -1
  59. package/dist/skills/ulw-plan/SKILL.md +11 -7
  60. package/dist/skills/ulw-plan/references/full-workflow.md +117 -6
  61. package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  62. package/dist/skills/ulw-research/SKILL.md +3 -3
  63. package/dist/tools/delegate-task/types.d.ts +0 -1
  64. package/dist/tui.js +115 -28
  65. package/package.json +14 -14
  66. package/packages/git-bash-mcp/dist/cli.js +81 -19
  67. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +4 -4
  68. package/packages/lsp-core/src/lsp/directory-diagnostics.test.ts +118 -1
  69. package/packages/lsp-core/src/lsp/directory-diagnostics.ts +1 -1
  70. package/packages/lsp-daemon/dist/cli.js +262 -63
  71. package/packages/lsp-daemon/dist/client.js +194 -50
  72. package/packages/lsp-daemon/dist/daemon-client.d.ts +2 -2
  73. package/packages/lsp-daemon/dist/daemon-client.js +26 -2
  74. package/packages/lsp-daemon/dist/ensure-daemon.d.ts +5 -4
  75. package/packages/lsp-daemon/dist/ensure-daemon.js +79 -18
  76. package/packages/lsp-daemon/dist/index.js +262 -63
  77. package/packages/lsp-daemon/dist/proxy.d.ts +2 -0
  78. package/packages/lsp-daemon/dist/proxy.js +79 -23
  79. package/packages/lsp-tools-mcp/dist/cli.js +82 -20
  80. package/packages/lsp-tools-mcp/dist/mcp.js +82 -20
  81. package/packages/lsp-tools-mcp/dist/tools.js +1 -1
  82. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  83. package/packages/omo-codex/plugin/.mcp.json +2 -1
  84. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +352 -17
  85. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  86. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  87. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +7 -6
  88. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +195 -56
  89. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +100 -28
  90. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  91. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +21 -9
  92. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +1 -1
  93. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +35 -0
  94. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +69 -0
  95. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +57 -1
  96. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  97. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  98. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  99. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  100. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  101. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  102. package/packages/omo-codex/plugin/components/lsp/.mcp.json +2 -1
  103. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +1 -0
  104. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
  105. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +113 -31
  106. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  107. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  108. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +1 -0
  109. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.5.md +1 -1
  110. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.6.md +5 -3
  111. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  112. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  113. package/packages/omo-codex/plugin/components/start-work-continuation/AGENTS.md +8 -0
  114. package/packages/omo-codex/plugin/components/start-work-continuation/README.md +2 -2
  115. package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +3 -3
  116. package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +148 -61
  117. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  118. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  119. package/packages/omo-codex/plugin/components/start-work-continuation/src/boulder-reader.ts +4 -72
  120. package/packages/omo-codex/plugin/components/start-work-continuation/src/codex-hook.ts +1 -1
  121. package/packages/omo-codex/plugin/components/start-work-continuation/src/plan-checklist.ts +171 -0
  122. package/packages/omo-codex/plugin/components/start-work-continuation/test/boulder-reader.test.ts +213 -24
  123. package/packages/omo-codex/plugin/components/start-work-continuation/test/cli.test.ts +4 -3
  124. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +25 -4
  125. package/packages/omo-codex/plugin/components/start-work-continuation/test/fixtures/plan-scaffold.md +15 -0
  126. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  127. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  128. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  129. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  130. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -10
  131. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +3 -3
  132. package/packages/omo-codex/plugin/components/ultrawork/directive.md +50 -33
  133. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  134. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  135. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +50 -33
  136. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +11 -7
  137. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +117 -6
  138. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  139. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +50 -33
  140. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +3 -3
  141. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +5 -6
  142. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  143. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  144. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +1 -1
  145. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +5 -6
  146. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +2 -2
  147. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  148. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  149. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  150. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  151. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  152. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  153. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  154. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  155. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  156. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  157. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  158. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  159. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  160. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  161. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  162. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  163. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  164. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  165. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  166. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  167. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  168. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  169. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  170. package/packages/omo-codex/plugin/package-lock.json +13 -13
  171. package/packages/omo-codex/plugin/package.json +1 -1
  172. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +32 -28
  173. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +17 -45
  174. package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +455 -0
  175. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +13 -20
  176. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +7 -0
  177. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +3 -2
  178. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +50 -33
  179. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +1 -1
  180. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +11 -7
  181. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +117 -6
  182. package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  183. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +2 -2
  184. package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +2 -2
  185. package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -0
  186. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +6 -6
  187. package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +3 -3
  188. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +62 -0
  189. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +271 -14
  190. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +7 -0
  191. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +38 -22
  192. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +0 -5
  193. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +293 -0
  194. package/packages/omo-codex/scripts/install-config.test.mjs +10 -10
  195. package/packages/omo-codex/scripts/install-dist/install-local.mjs +353 -18
  196. package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +39 -2
  197. package/packages/shared-skills/skills/ulw-plan/SKILL.md +11 -7
  198. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +117 -6
  199. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  200. package/packages/shared-skills/skills/ulw-research/SKILL.md +3 -3
  201. package/dist/features/builtin-commands/templates/ralph-loop.d.ts +0 -3
  202. package/dist/skills/ultraresearch/SKILL.md +0 -10
  203. package/packages/shared-skills/skills/lcx-contribute-bug-fix/SKILL.md +0 -273
  204. package/packages/shared-skills/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -12
  205. package/packages/shared-skills/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -107
  206. package/packages/shared-skills/skills/lcx-doctor/SKILL.md +0 -128
  207. package/packages/shared-skills/skills/lcx-doctor/agents/openai.yaml +0 -11
  208. package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +0 -268
  209. package/packages/shared-skills/skills/lcx-report-bug/agents/openai.yaml +0 -11
  210. package/packages/shared-skills/skills/ultraresearch/SKILL.md +0 -10
  211. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/SKILL.md +0 -0
  212. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -0
  213. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -0
  214. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-doctor/SKILL.md +0 -0
  215. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-doctor/agents/openai.yaml +0 -0
  216. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-report-bug/SKILL.md +0 -0
  217. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-report-bug/agents/openai.yaml +0 -0
@@ -2146,7 +2146,7 @@ var package_default;
2146
2146
  var init_package = __esm(() => {
2147
2147
  package_default = {
2148
2148
  name: "oh-my-opencode",
2149
- version: "4.18.1",
2149
+ version: "4.19.0",
2150
2150
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
2151
2151
  main: "./dist/index.js",
2152
2152
  types: "dist/index.d.ts",
@@ -2256,7 +2256,7 @@ var init_package = __esm(() => {
2256
2256
  "install:codex-dev": "bun run script/build-codex-install.ts && bun run script/install-codex-dev.ts",
2257
2257
  "build:codex-plugin": "npm --prefix packages/omo-codex/plugin ci && bun run --cwd packages/omo-codex/plugin build",
2258
2258
  "build:senpi-plugin": "bun run build:lsp-daemon && bun run build:senpi-plugin:stage",
2259
- "build:senpi-plugin:stage": "node packages/omo-senpi/plugin/scripts/stage-lsp-daemon-runtime.mjs && node packages/omo-senpi/plugin/scripts/build-extension.mjs && node packages/omo-senpi/plugin/scripts/sync-skills.mjs && node packages/omo-senpi/plugin/scripts/embed-directive.mjs --check && node packages/omo-senpi/plugin/scripts/build-install.mjs",
2259
+ "build:senpi-plugin:stage": "bun run build:materialize-frontend && node packages/omo-senpi/plugin/scripts/stage-lsp-daemon-runtime.mjs && node packages/omo-senpi/plugin/scripts/build-extension.mjs && node packages/omo-senpi/plugin/scripts/sync-skills.mjs && node packages/omo-senpi/plugin/scripts/embed-directive.mjs --check && node packages/omo-senpi/plugin/scripts/build-install.mjs",
2260
2260
  "build:materialize-frontend": "node packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs --strict",
2261
2261
  "build:shared-skills-assets": "bun run build:materialize-frontend && rm -rf dist/skills && cp -R packages/shared-skills/skills dist/skills",
2262
2262
  "build:lsp-tools-mcp": "npm --prefix packages/lsp-tools-mcp ci && npm --prefix packages/lsp-tools-mcp run build",
@@ -2358,18 +2358,18 @@ var init_package = __esm(() => {
2358
2358
  typescript: "^6.0.3"
2359
2359
  },
2360
2360
  optionalDependencies: {
2361
- "oh-my-opencode-darwin-arm64": "4.18.1",
2362
- "oh-my-opencode-darwin-x64": "4.18.1",
2363
- "oh-my-opencode-darwin-x64-baseline": "4.18.1",
2364
- "oh-my-opencode-linux-arm64": "4.18.1",
2365
- "oh-my-opencode-linux-arm64-musl": "4.18.1",
2366
- "oh-my-opencode-linux-x64": "4.18.1",
2367
- "oh-my-opencode-linux-x64-baseline": "4.18.1",
2368
- "oh-my-opencode-linux-x64-musl": "4.18.1",
2369
- "oh-my-opencode-linux-x64-musl-baseline": "4.18.1",
2370
- "oh-my-opencode-windows-arm64": "4.18.1",
2371
- "oh-my-opencode-windows-x64": "4.18.1",
2372
- "oh-my-opencode-windows-x64-baseline": "4.18.1"
2361
+ "oh-my-opencode-darwin-arm64": "4.19.0",
2362
+ "oh-my-opencode-darwin-x64": "4.19.0",
2363
+ "oh-my-opencode-darwin-x64-baseline": "4.19.0",
2364
+ "oh-my-opencode-linux-arm64": "4.19.0",
2365
+ "oh-my-opencode-linux-arm64-musl": "4.19.0",
2366
+ "oh-my-opencode-linux-x64": "4.19.0",
2367
+ "oh-my-opencode-linux-x64-baseline": "4.19.0",
2368
+ "oh-my-opencode-linux-x64-musl": "4.19.0",
2369
+ "oh-my-opencode-linux-x64-musl-baseline": "4.19.0",
2370
+ "oh-my-opencode-windows-arm64": "4.19.0",
2371
+ "oh-my-opencode-windows-x64": "4.19.0",
2372
+ "oh-my-opencode-windows-x64-baseline": "4.19.0"
2373
2373
  },
2374
2374
  overrides: {
2375
2375
  "@earendil-works/pi-agent-core": "0.80.3",
@@ -9199,6 +9199,7 @@ var init_agent_model_requirements = __esm(() => {
9199
9199
  model: "claude-opus-4-7",
9200
9200
  variant: "max"
9201
9201
  },
9202
+ { providers: ["opencode-go", "kimi-for-coding", "moonshotai", "opencode", "vercel"], model: "kimi-k3" },
9202
9203
  { providers: ["opencode-go", "vercel"], model: "kimi-k2.6" },
9203
9204
  { providers: ["kimi-for-coding"], model: "k2p5" },
9204
9205
  {
@@ -9223,7 +9224,7 @@ var init_agent_model_requirements = __esm(() => {
9223
9224
  hephaestus: {
9224
9225
  fallbackChain: [
9225
9226
  {
9226
- providers: ["openai", "vercel"],
9227
+ providers: ["openai", "github-copilot", "vercel"],
9227
9228
  model: "gpt-5.6-sol",
9228
9229
  variant: "high"
9229
9230
  },
@@ -9331,8 +9332,13 @@ var init_agent_model_requirements = __esm(() => {
9331
9332
  fallbackChain: [
9332
9333
  {
9333
9334
  providers: ["openai", "vercel"],
9334
- model: "gpt-5.6-sol",
9335
- variant: "xhigh"
9335
+ model: "gpt-5.6-terra",
9336
+ variant: "high"
9337
+ },
9338
+ {
9339
+ providers: ["github-copilot"],
9340
+ model: "gpt-5.6-terra",
9341
+ variant: "high"
9336
9342
  },
9337
9343
  {
9338
9344
  providers: ["openai", "github-copilot", "opencode", "vercel"],
@@ -9412,6 +9418,11 @@ var init_category_model_requirements = __esm(() => {
9412
9418
  model: "gpt-5.6-sol",
9413
9419
  variant: "xhigh"
9414
9420
  },
9421
+ {
9422
+ providers: ["github-copilot"],
9423
+ model: "gpt-5.6-sol",
9424
+ variant: "high"
9425
+ },
9415
9426
  {
9416
9427
  providers: ["openai", "opencode", "vercel"],
9417
9428
  model: "gpt-5.5",
@@ -9438,7 +9449,12 @@ var init_category_model_requirements = __esm(() => {
9438
9449
  variant: "xhigh"
9439
9450
  },
9440
9451
  {
9441
- providers: ["openai", "vercel"],
9452
+ providers: ["github-copilot"],
9453
+ model: "gpt-5.6-terra",
9454
+ variant: "high"
9455
+ },
9456
+ {
9457
+ providers: ["openai", "github-copilot", "vercel"],
9442
9458
  model: "gpt-5.6-sol",
9443
9459
  variant: "high"
9444
9460
  },
@@ -9505,6 +9521,11 @@ var init_category_model_requirements = __esm(() => {
9505
9521
  model: "gpt-5.6-luna",
9506
9522
  variant: "xhigh"
9507
9523
  },
9524
+ {
9525
+ providers: ["github-copilot"],
9526
+ model: "gpt-5.6-luna",
9527
+ variant: "high"
9528
+ },
9508
9529
  {
9509
9530
  providers: ["anthropic", "github-copilot", "opencode", "vercel"],
9510
9531
  model: "claude-sonnet-4-6"
@@ -9594,9 +9615,12 @@ function stripProviderPrefixForAliasLookup(normalizedModelID) {
9594
9615
  }
9595
9616
  return normalizedModelID.slice(slashIndex + 1);
9596
9617
  }
9597
- function resolveModelIDAlias(modelID) {
9618
+ function resolveModelIDAlias(modelID, providerID) {
9598
9619
  const requestedModelID = normalizeLookupModelID(modelID);
9599
9620
  const aliasLookupModelID = stripProviderPrefixForAliasLookup(requestedModelID);
9621
+ const normalizedProviderID = providerID ? normalizeLookupModelID(providerID) : undefined;
9622
+ const providerPrefixEnd = requestedModelID.indexOf("/");
9623
+ const embeddedProviderID = providerPrefixEnd > 0 ? requestedModelID.slice(0, providerPrefixEnd) : undefined;
9600
9624
  const exactRule = EXACT_ALIAS_RULES_BY_MODEL.get(aliasLookupModelID);
9601
9625
  if (exactRule) {
9602
9626
  return {
@@ -9607,6 +9631,13 @@ function resolveModelIDAlias(modelID) {
9607
9631
  };
9608
9632
  }
9609
9633
  for (const rule of PATTERN_ALIAS_RULES) {
9634
+ if (rule.providerIDs) {
9635
+ const matchesProviderID = normalizedProviderID !== undefined && rule.providerIDs.includes(normalizedProviderID);
9636
+ const matchesEmbeddedProviderID = normalizedProviderID !== undefined && rule.allowedSubproviderHosts?.includes(normalizedProviderID) === true && embeddedProviderID !== undefined && rule.providerIDs.includes(embeddedProviderID);
9637
+ if (!matchesProviderID && !matchesEmbeddedProviderID) {
9638
+ continue;
9639
+ }
9640
+ }
9610
9641
  if (!rule.match(aliasLookupModelID)) {
9611
9642
  continue;
9612
9643
  }
@@ -9647,6 +9678,14 @@ var init_model_capability_aliases = __esm(() => {
9647
9678
  ];
9648
9679
  EXACT_ALIAS_RULES_BY_MODEL = new Map(EXACT_ALIAS_RULES.map((rule) => [rule.aliasModelID, rule]));
9649
9680
  PATTERN_ALIAS_RULES = [
9681
+ {
9682
+ ruleID: "openai-gpt-5.6-fast-service-tier-alias",
9683
+ description: "Normalizes OpenCode's OpenAI GPT-5.6 fast service-tier IDs to canonical snapshot IDs.",
9684
+ providerIDs: ["openai"],
9685
+ allowedSubproviderHosts: ["vercel"],
9686
+ match: (normalizedModelID) => /^gpt-5\.6-(?:sol|terra|luna)-fast$/.test(normalizedModelID),
9687
+ canonicalize: (normalizedModelID) => normalizedModelID.slice(0, -"-fast".length)
9688
+ },
9650
9689
  {
9651
9690
  ruleID: "claude-thinking-legacy-alias",
9652
9691
  description: "Normalizes the legacy claude-opus-4-7-thinking id to the canonical snapshot ID.",
@@ -10061,6 +10100,21 @@ var init_runtime_fallback_model = () => {};
10061
10100
  var SUPPLEMENTAL_MODEL_CAPABILITIES;
10062
10101
  var init_supplemental_entries = __esm(() => {
10063
10102
  SUPPLEMENTAL_MODEL_CAPABILITIES = {
10103
+ "kimi-k3": {
10104
+ id: "kimi-k3",
10105
+ family: "kimi",
10106
+ reasoning: true,
10107
+ temperature: true,
10108
+ toolCall: true,
10109
+ modalities: {
10110
+ input: ["text", "image", "video"],
10111
+ output: ["text"]
10112
+ },
10113
+ limit: {
10114
+ context: 262144,
10115
+ output: 262144
10116
+ }
10117
+ },
10064
10118
  "kimi-k2.6": {
10065
10119
  id: "kimi-k2.6",
10066
10120
  family: "kimi",
@@ -10314,7 +10368,7 @@ function getProviderOverride(providerID, modelID) {
10314
10368
  return GITHUB_COPILOT_GPT5_MODEL.test(normalizeLookupModelID2(modelID)) ? GITHUB_COPILOT_GPT5_OVERRIDE : undefined;
10315
10369
  }
10316
10370
  function getModelCapabilities(input) {
10317
- const canonicalization = resolveModelIDAlias(input.modelID);
10371
+ const canonicalization = resolveModelIDAlias(input.modelID, input.providerID);
10318
10372
  const override = getOverride(input.modelID);
10319
10373
  const providerOverride = getProviderOverride(input.providerID, canonicalization.canonicalModelID);
10320
10374
  const runtimeModel = readRuntimeModel(input.runtimeModel ?? input.providerCache?.findProviderModelMetadata(input.providerID, input.modelID));
@@ -11419,6 +11473,7 @@ var init_opencode_storage_detection = __esm(() => {
11419
11473
  var opencodePluginsCache;
11420
11474
  var init_load_opencode_plugins = __esm(() => {
11421
11475
  init_jsonc_parser2();
11476
+ init_opencode_config_dir();
11422
11477
  opencodePluginsCache = new Map;
11423
11478
  });
11424
11479
 
@@ -72658,7 +72713,7 @@ var package_default2;
72658
72713
  var init_package2 = __esm(() => {
72659
72714
  package_default2 = {
72660
72715
  name: "@oh-my-opencode/omo-codex",
72661
- version: "4.18.1",
72716
+ version: "4.19.0",
72662
72717
  type: "module",
72663
72718
  private: true,
72664
72719
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -75700,9 +75755,16 @@ function findTomlSection(config, header) {
75700
75755
  const lines = config.match(/[^\n]*\n?|$/g) ?? [];
75701
75756
  let offset = 0;
75702
75757
  let start = -1;
75758
+ let multilineQuote = null;
75703
75759
  for (const line of lines) {
75704
75760
  if (line.length === 0)
75705
75761
  break;
75762
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
75763
+ multilineQuote = multilineScan.nextQuote;
75764
+ if (multilineScan.wasInside) {
75765
+ offset += line.length;
75766
+ continue;
75767
+ }
75706
75768
  const trimmed = line.trim();
75707
75769
  if (start === -1) {
75708
75770
  if (tomlTableHeaderMatches(trimmed, headerLine, targetHeaderPath))
@@ -75717,8 +75779,37 @@ function findTomlSection(config, header) {
75717
75779
  return { start, end: config.length, text: config.slice(start) };
75718
75780
  }
75719
75781
  function replaceOrInsertSetting(config, section, key, value) {
75720
- const linePattern = new RegExp(`^[ \\t]*${escapeRegExp(key)}[ \\t]*=.*$`, "m");
75721
- const replacement = linePattern.test(section.text) ? section.text.replace(linePattern, `${key} = ${value}`) : insertSetting(section.text, key, value);
75782
+ const targetPath = parseTomlDottedKey(key);
75783
+ if (!targetPath)
75784
+ return config;
75785
+ const lines = section.text.match(/[^\n]*\n?|$/g) ?? [];
75786
+ let offset = 0;
75787
+ let multilineQuote = null;
75788
+ for (const line of lines) {
75789
+ if (line.length === 0)
75790
+ break;
75791
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
75792
+ multilineQuote = multilineScan.nextQuote;
75793
+ if (multilineScan.wasInside) {
75794
+ offset += line.length;
75795
+ continue;
75796
+ }
75797
+ const assignmentIndex = findUnquotedAssignment(line);
75798
+ if (assignmentIndex < 0) {
75799
+ offset += line.length;
75800
+ continue;
75801
+ }
75802
+ const settingPath = parseTomlDottedKey(line.slice(0, assignmentIndex).trim());
75803
+ if (!settingPath || !tomlPathMatches(settingPath, targetPath)) {
75804
+ offset += line.length;
75805
+ continue;
75806
+ }
75807
+ const replacement2 = replaceTomlAssignmentValue(line, assignmentIndex, value);
75808
+ const assignmentEnd = multilineScan.nextQuote ? findTomlMultilineValueEnd(section.text, offset + line.length, multilineScan.nextQuote) : offset + line.length;
75809
+ const sectionReplacement = section.text.slice(0, offset) + replacement2 + section.text.slice(assignmentEnd);
75810
+ return config.slice(0, section.start) + sectionReplacement + config.slice(section.end);
75811
+ }
75812
+ const replacement = insertSetting(section.text, key, value);
75722
75813
  return config.slice(0, section.start) + replacement + config.slice(section.end);
75723
75814
  }
75724
75815
  function removeSetting(config, section, key) {
@@ -75738,6 +75829,50 @@ function replaceOrInsertRootSetting(config, key, value) {
75738
75829
  return replacement;
75739
75830
  return `${replacement.trimEnd()}
75740
75831
 
75832
+ ${suffix.trimStart()}`;
75833
+ }
75834
+ function replaceOrInsertRootDottedSetting(config, keyPath, value) {
75835
+ const targetPath = parseTomlDottedKey(keyPath);
75836
+ if (!targetPath)
75837
+ return config;
75838
+ const lines = config.match(/[^\n]*\n?|$/g) ?? [];
75839
+ let offset = 0;
75840
+ let multilineQuote = null;
75841
+ for (const line of lines) {
75842
+ if (line.length === 0)
75843
+ break;
75844
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
75845
+ multilineQuote = multilineScan.nextQuote;
75846
+ if (multilineScan.wasInside) {
75847
+ offset += line.length;
75848
+ continue;
75849
+ }
75850
+ if (isTomlTableHeaderLine(line))
75851
+ break;
75852
+ const assignmentIndex = findUnquotedAssignment(line);
75853
+ if (assignmentIndex < 0) {
75854
+ offset += line.length;
75855
+ continue;
75856
+ }
75857
+ const settingPath = parseTomlDottedKey(line.slice(0, assignmentIndex).trim());
75858
+ if (!settingPath || !tomlPathMatches(settingPath, targetPath)) {
75859
+ offset += line.length;
75860
+ continue;
75861
+ }
75862
+ const replacement2 = replaceTomlAssignmentValue(line, assignmentIndex, value);
75863
+ const assignmentEnd = multilineScan.nextQuote ? findTomlMultilineValueEnd(config, offset + line.length, multilineScan.nextQuote) : offset + line.length;
75864
+ return config.slice(0, offset) + replacement2 + config.slice(assignmentEnd);
75865
+ }
75866
+ const sectionStart = findFirstTableStart(config);
75867
+ const root = config.slice(0, sectionStart).trimEnd();
75868
+ const suffix = config.slice(sectionStart);
75869
+ const replacement = `${root}${root.length > 0 ? `
75870
+ ` : ""}${keyPath} = ${value}
75871
+ `;
75872
+ if (suffix.length === 0)
75873
+ return replacement;
75874
+ return `${replacement.trimEnd()}
75875
+
75741
75876
  ${suffix.trimStart()}`;
75742
75877
  }
75743
75878
  function appendBlock(config, block) {
@@ -75750,9 +75885,16 @@ function appendBlock(config, block) {
75750
75885
  function findFirstTableStart(config) {
75751
75886
  const lines = config.match(/[^\n]*\n?|$/g) ?? [];
75752
75887
  let offset = 0;
75888
+ let multilineQuote = null;
75753
75889
  for (const line of lines) {
75754
75890
  if (line.length === 0)
75755
75891
  break;
75892
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
75893
+ multilineQuote = multilineScan.nextQuote;
75894
+ if (multilineScan.wasInside) {
75895
+ offset += line.length;
75896
+ continue;
75897
+ }
75756
75898
  if (isTomlTableHeaderLine(line))
75757
75899
  return offset;
75758
75900
  offset += line.length;
@@ -75790,6 +75932,131 @@ function isTomlTableHeaderLine(line) {
75790
75932
  const normalizedLine = stripUnquotedInlineComment(line).trim();
75791
75933
  return normalizedLine.startsWith("[") && normalizedLine.endsWith("]");
75792
75934
  }
75935
+ function scanTomlMultilineLine(line, currentQuote) {
75936
+ if (currentQuote) {
75937
+ return {
75938
+ wasInside: true,
75939
+ nextQuote: findTomlMultilineDelimiter(line, currentQuote, 0) === -1 ? currentQuote : null
75940
+ };
75941
+ }
75942
+ let quote = null;
75943
+ let index = 0;
75944
+ while (index < line.length) {
75945
+ const char = line[index];
75946
+ if (quote === '"') {
75947
+ if (char === "\\") {
75948
+ index += 2;
75949
+ continue;
75950
+ }
75951
+ if (char === '"')
75952
+ quote = null;
75953
+ index += 1;
75954
+ continue;
75955
+ }
75956
+ if (quote === "'") {
75957
+ if (char === "'")
75958
+ quote = null;
75959
+ index += 1;
75960
+ continue;
75961
+ }
75962
+ if (char === "#")
75963
+ break;
75964
+ const delimiter2 = line.startsWith('"""', index) ? '"""' : line.startsWith("'''", index) ? "'''" : null;
75965
+ if (delimiter2) {
75966
+ const closingIndex = findTomlMultilineDelimiter(line, delimiter2, index + delimiter2.length);
75967
+ return { wasInside: false, nextQuote: closingIndex === -1 ? delimiter2 : null };
75968
+ }
75969
+ if (char === '"' || char === "'")
75970
+ quote = char;
75971
+ index += 1;
75972
+ }
75973
+ return { wasInside: false, nextQuote: null };
75974
+ }
75975
+ function findTomlMultilineDelimiter(line, delimiter2, startIndex) {
75976
+ let index = line.indexOf(delimiter2, startIndex);
75977
+ while (index !== -1) {
75978
+ if (delimiter2 === "'''" || countPrecedingBackslashes(line, index) % 2 === 0)
75979
+ return index;
75980
+ index = line.indexOf(delimiter2, index + 1);
75981
+ }
75982
+ return -1;
75983
+ }
75984
+ function countPrecedingBackslashes(line, index) {
75985
+ let count = 0;
75986
+ let cursor = index - 1;
75987
+ while (cursor >= 0 && line[cursor] === "\\") {
75988
+ count += 1;
75989
+ cursor -= 1;
75990
+ }
75991
+ return count;
75992
+ }
75993
+ function findUnquotedAssignment(line) {
75994
+ return findUnquotedCharacter(line, "=", 0);
75995
+ }
75996
+ function findUnquotedComment(line, startIndex) {
75997
+ return findUnquotedCharacter(line, "#", startIndex);
75998
+ }
75999
+ function findUnquotedCharacter(line, target, startIndex) {
76000
+ let quote = null;
76001
+ let index = startIndex;
76002
+ while (index < line.length) {
76003
+ const char = line[index];
76004
+ if (quote === '"') {
76005
+ if (char === "\\") {
76006
+ index += 2;
76007
+ continue;
76008
+ }
76009
+ if (char === '"')
76010
+ quote = null;
76011
+ index += 1;
76012
+ continue;
76013
+ }
76014
+ if (quote === "'") {
76015
+ if (char === "'")
76016
+ quote = null;
76017
+ index += 1;
76018
+ continue;
76019
+ }
76020
+ if (char === '"' || char === "'") {
76021
+ quote = char;
76022
+ index += 1;
76023
+ continue;
76024
+ }
76025
+ if (char === target)
76026
+ return index;
76027
+ if (char === "#")
76028
+ return -1;
76029
+ index += 1;
76030
+ }
76031
+ return -1;
76032
+ }
76033
+ function tomlPathMatches(candidate, target) {
76034
+ return candidate.length === target.length && candidate.every((part, index) => part === target[index]);
76035
+ }
76036
+ function replaceTomlAssignmentValue(line, assignmentIndex, value) {
76037
+ const newline = line.endsWith(`
76038
+ `) ? `
76039
+ ` : "";
76040
+ const lineBody = newline ? line.slice(0, -1) : line;
76041
+ const commentIndex = findUnquotedComment(lineBody, assignmentIndex + 1);
76042
+ const comment = commentIndex === -1 ? "" : ` ${lineBody.slice(commentIndex).trimStart()}`;
76043
+ return `${lineBody.slice(0, assignmentIndex + 1)} ${value}${comment}${newline}`;
76044
+ }
76045
+ function findTomlMultilineValueEnd(text, startOffset, quote) {
76046
+ const lines = text.slice(startOffset).match(/[^\n]*\n?|$/g) ?? [];
76047
+ let offset = startOffset;
76048
+ let currentQuote = quote;
76049
+ for (const line of lines) {
76050
+ if (line.length === 0)
76051
+ break;
76052
+ const scan = scanTomlMultilineLine(line, currentQuote);
76053
+ currentQuote = scan.nextQuote;
76054
+ offset += line.length;
76055
+ if (currentQuote === null)
76056
+ return offset;
76057
+ }
76058
+ return text.length;
76059
+ }
75793
76060
  function stripUnquotedInlineComment(line) {
75794
76061
  let quote = null;
75795
76062
  let index = 0;
@@ -76120,13 +76387,137 @@ function delay(milliseconds) {
76120
76387
  return new Promise((resolveDelay) => setTimeout(resolveDelay, milliseconds));
76121
76388
  }
76122
76389
 
76390
+ // packages/omo-codex/src/install/toml-setting-reader.ts
76391
+ function hasTomlSetting(config, keyPath) {
76392
+ const targetPath = parseTomlDottedKey(keyPath);
76393
+ if (!targetPath)
76394
+ return false;
76395
+ return hasTomlAssignment(config, (tablePath, settingPath) => {
76396
+ const fullPath = [...tablePath, ...settingPath];
76397
+ return fullPath.length === targetPath.length && fullPath.every((part, index) => part === targetPath[index]);
76398
+ });
76399
+ }
76400
+ function hasTomlRootDottedKeyPrefix(config, rootKey) {
76401
+ return hasTomlAssignment(config, (tablePath, settingPath) => tablePath.length === 0 && settingPath.length > 1 && settingPath[0] === rootKey);
76402
+ }
76403
+ function hasTomlAssignment(config, predicate) {
76404
+ let tablePath = [];
76405
+ let multilineQuote = null;
76406
+ for (const line of config.split(`
76407
+ `)) {
76408
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
76409
+ multilineQuote = multilineScan.nextQuote;
76410
+ if (multilineScan.wasInside)
76411
+ continue;
76412
+ const normalizedLine = stripUnquotedInlineComment2(line).trim();
76413
+ if (normalizedLine.length === 0)
76414
+ continue;
76415
+ const headerPath = parseTomlTableHeader2(normalizedLine);
76416
+ if (headerPath) {
76417
+ tablePath = headerPath;
76418
+ continue;
76419
+ }
76420
+ if (isTomlTableHeaderLine2(normalizedLine)) {
76421
+ tablePath = null;
76422
+ continue;
76423
+ }
76424
+ if (!tablePath)
76425
+ continue;
76426
+ const assignmentIndex = findUnquotedAssignment2(normalizedLine);
76427
+ if (assignmentIndex < 0)
76428
+ continue;
76429
+ const settingPath = parseTomlDottedKey(normalizedLine.slice(0, assignmentIndex).trim());
76430
+ if (!settingPath)
76431
+ continue;
76432
+ if (predicate(tablePath, settingPath))
76433
+ return true;
76434
+ }
76435
+ return false;
76436
+ }
76437
+ function parseTomlTableHeader2(line) {
76438
+ if (!line.startsWith("[") || !line.endsWith("]") || line.startsWith("[["))
76439
+ return null;
76440
+ return parseTomlDottedKey(line.slice(1, -1).trim());
76441
+ }
76442
+ function isTomlTableHeaderLine2(line) {
76443
+ return line.startsWith("[") && line.endsWith("]");
76444
+ }
76445
+ function stripUnquotedInlineComment2(line) {
76446
+ let quote = null;
76447
+ let index = 0;
76448
+ while (index < line.length) {
76449
+ const char = line[index];
76450
+ if (quote === '"') {
76451
+ if (char === "\\") {
76452
+ index += 2;
76453
+ continue;
76454
+ }
76455
+ if (char === '"')
76456
+ quote = null;
76457
+ index += 1;
76458
+ continue;
76459
+ }
76460
+ if (quote === "'") {
76461
+ if (char === "'")
76462
+ quote = null;
76463
+ index += 1;
76464
+ continue;
76465
+ }
76466
+ if (char === '"' || char === "'") {
76467
+ quote = char;
76468
+ index += 1;
76469
+ continue;
76470
+ }
76471
+ if (char === "#")
76472
+ return line.slice(0, index);
76473
+ index += 1;
76474
+ }
76475
+ return line;
76476
+ }
76477
+ function findUnquotedAssignment2(line) {
76478
+ let quote = null;
76479
+ let index = 0;
76480
+ while (index < line.length) {
76481
+ const char = line[index];
76482
+ if (quote === '"') {
76483
+ if (char === "\\") {
76484
+ index += 2;
76485
+ continue;
76486
+ }
76487
+ if (char === '"')
76488
+ quote = null;
76489
+ index += 1;
76490
+ continue;
76491
+ }
76492
+ if (quote === "'") {
76493
+ if (char === "'")
76494
+ quote = null;
76495
+ index += 1;
76496
+ continue;
76497
+ }
76498
+ if (char === '"' || char === "'") {
76499
+ quote = char;
76500
+ index += 1;
76501
+ continue;
76502
+ }
76503
+ if (char === "=")
76504
+ return index;
76505
+ index += 1;
76506
+ }
76507
+ return -1;
76508
+ }
76509
+
76123
76510
  // packages/omo-codex/src/install/codex-config-features.ts
76124
76511
  function ensureFeatureEnabled(config, featureName) {
76125
76512
  const section = findTomlSection(config, "features");
76126
- if (!section)
76513
+ if (!section) {
76514
+ if (hasTomlRootDottedKeyPrefix(config, "features")) {
76515
+ return replaceOrInsertRootDottedSetting(config, `features.${featureName}`, "true");
76516
+ }
76127
76517
  return appendBlock(config, `[features]
76128
76518
  ${featureName} = true
76129
76519
  `);
76520
+ }
76130
76521
  return replaceOrInsertSetting(config, section, featureName, "true");
76131
76522
  }
76132
76523
 
@@ -76194,7 +76585,7 @@ function ensureAutonomousPermissions(config) {
76194
76585
  next = replaceOrInsertRootSetting(next, "sandbox_mode", JSON.stringify("danger-full-access"));
76195
76586
  next = replaceOrInsertRootSetting(next, "network_access", JSON.stringify("enabled"));
76196
76587
  for (const featureName of AUTONOMOUS_FEATURES) {
76197
- next = ensureFeatureEnabled2(next, featureName);
76588
+ next = ensureFeatureEnabled(next, featureName);
76198
76589
  }
76199
76590
  next = removeWindowsSandboxSetting(next);
76200
76591
  next = ensureNoticeEnabled(next, "hide_full_access_warning");
@@ -76212,14 +76603,6 @@ function ensureNoticeEnabled(config, key) {
76212
76603
  return appendNoticeBlock(config, key);
76213
76604
  return replaceOrInsertSetting(config, section, key, "true");
76214
76605
  }
76215
- function ensureFeatureEnabled2(config, key) {
76216
- const section = findTomlSection(config, "features");
76217
- if (section === null)
76218
- return appendBlock(config, `[features]
76219
- ${key} = true
76220
- `);
76221
- return replaceOrInsertSetting(config, section, key, "true");
76222
- }
76223
76606
  function appendNoticeBlock(config, key) {
76224
76607
  return appendBlock(config, `[notice]
76225
76608
  ${key} = true
@@ -76291,7 +76674,7 @@ function readStringArraySetting(sectionText, key) {
76291
76674
  const assignmentIndex = line.indexOf("=");
76292
76675
  if (assignmentIndex === -1)
76293
76676
  return null;
76294
- return parseTomlStringArray(stripUnquotedInlineComment2(line.slice(assignmentIndex + 1)).trim());
76677
+ return parseTomlStringArray(stripUnquotedInlineComment3(line.slice(assignmentIndex + 1)).trim());
76295
76678
  }
76296
76679
  return null;
76297
76680
  }
@@ -76335,7 +76718,7 @@ function parseTomlString(input, startIndex) {
76335
76718
  }
76336
76719
  return null;
76337
76720
  }
76338
- function stripUnquotedInlineComment2(line) {
76721
+ function stripUnquotedInlineComment3(line) {
76339
76722
  let quote = null;
76340
76723
  let index = 0;
76341
76724
  while (index < line.length) {
@@ -76549,24 +76932,27 @@ import { readFileSync as readFileSync13 } from "node:fs";
76549
76932
  import { dirname as dirname15, isAbsolute as isAbsolute8, join as join39 } from "node:path";
76550
76933
  var CODEX_AGENTS_HEADER = "agents";
76551
76934
  var CODEX_MULTI_AGENT_V2_HEADER = "features.multi_agent_v2";
76935
+ var CODEX_MULTI_AGENT_V2_THREAD_LIMIT_KEY = `${CODEX_MULTI_AGENT_V2_HEADER}.max_concurrent_threads_per_session`;
76552
76936
  var CODEX_SUBAGENT_THREAD_LIMIT = 1000;
76937
+ var CODEX_MULTI_AGENT_V2_THREAD_LIMIT = 16;
76553
76938
  function ensureCodexMultiAgentV2Config(config, options = {}) {
76554
76939
  const featureFlag = removeFeatureFlagSetting(config, "multi_agent_v2");
76555
76940
  const v2Preferred = options.multiAgentVersion === "v2";
76556
76941
  const modelKnown = options.multiAgentVersion != null || readRootModel(featureFlag.config) !== null;
76557
76942
  const agentsConfig = v2Preferred ? removeAgentsMaxThreads(featureFlag.config) : modelKnown ? ensureAgentsMaxThreads(featureFlag.config) : raiseExistingAgentsMaxThreads(featureFlag.config);
76558
- const maxThreadsValue = CODEX_SUBAGENT_THREAD_LIMIT.toString();
76559
76943
  const preserveDisable = featureFlag.value === false && !v2Preferred;
76560
76944
  const featureConfig = preserveDisable ? setMultiAgentV2Disable(agentsConfig) : v2Preferred ? removeMultiAgentV2Disable(agentsConfig) : agentsConfig;
76945
+ if (hasTomlSetting(featureConfig, CODEX_MULTI_AGENT_V2_THREAD_LIMIT_KEY))
76946
+ return featureConfig;
76561
76947
  const section = findTomlSection(featureConfig, CODEX_MULTI_AGENT_V2_HEADER);
76562
76948
  if (!section) {
76563
76949
  const enabledSetting = preserveDisable ? `enabled = false
76564
76950
  ` : "";
76565
76951
  return appendBlock(featureConfig, `[${CODEX_MULTI_AGENT_V2_HEADER}]
76566
- ${enabledSetting}max_concurrent_threads_per_session = ${maxThreadsValue}
76952
+ ${enabledSetting}max_concurrent_threads_per_session = ${CODEX_MULTI_AGENT_V2_THREAD_LIMIT}
76567
76953
  `);
76568
76954
  }
76569
- return replaceOrInsertSetting(featureConfig, section, "max_concurrent_threads_per_session", maxThreadsValue);
76955
+ return replaceOrInsertSetting(featureConfig, section, "max_concurrent_threads_per_session", CODEX_MULTI_AGENT_V2_THREAD_LIMIT.toString());
76570
76956
  }
76571
76957
  function resolveCodexMultiAgentVersion(config, configPath) {
76572
76958
  const model = readRootModel(config);
@@ -76925,6 +77311,10 @@ var MANAGED_REASONING_DEFAULT_UPGRADES = new Map([
76925
77311
  {
76926
77312
  previous: { model: "gpt-5.5", effort: "xhigh" },
76927
77313
  current: { model: "gpt-5.6-sol", effort: "ultra" }
77314
+ },
77315
+ {
77316
+ previous: { model: "gpt-5.6-sol", effort: "ultra" },
77317
+ current: { model: "gpt-5.6-terra", effort: "high" }
76928
77318
  }
76929
77319
  ]
76930
77320
  ],
@@ -78987,8 +79377,24 @@ import { promisify as promisify2 } from "node:util";
78987
79377
  var execFileAsync2 = promisify2(execFile4);
78988
79378
  var REQUIRED_PLUGIN_ARTIFACTS = [
78989
79379
  join58("extensions", "omo.js"),
79380
+ join58("skills", "ast-grep", "SKILL.md"),
79381
+ join58("skills", "coding-agent-sessions", "SKILL.md"),
79382
+ join58("skills", "debugging", "SKILL.md"),
79383
+ join58("skills", "frontend", "SKILL.md"),
79384
+ join58("skills", "git-master", "SKILL.md"),
79385
+ join58("skills", "init-deep", "SKILL.md"),
79386
+ join58("skills", "lsp-setup", "SKILL.md"),
79387
+ join58("skills", "programming", "SKILL.md"),
79388
+ join58("skills", "refactor", "SKILL.md"),
79389
+ join58("skills", "remove-ai-slops", "SKILL.md"),
79390
+ join58("skills", "review-work", "SKILL.md"),
79391
+ join58("skills", "start-work", "SKILL.md"),
79392
+ join58("skills", "ultimate-browsing", "SKILL.md"),
78990
79393
  join58("skills", "ultrawork", "SKILL.md"),
78991
79394
  join58("skills", "ulw-loop", "SKILL.md"),
79395
+ join58("skills", "ulw-plan", "SKILL.md"),
79396
+ join58("skills", "ulw-research", "SKILL.md"),
79397
+ join58("skills", "visual-qa", "SKILL.md"),
78992
79398
  join58("runtime", "lsp-daemon", "dist", "cli.js"),
78993
79399
  join58("runtime", "lsp-daemon", "dist", "index.js"),
78994
79400
  join58("runtime", "lsp-daemon", "dist", "index.d.ts"),
@@ -79042,6 +79448,7 @@ async function ensurePluginArtifacts(context) {
79042
79448
  throw new Error(`Packed omo-senpi plugin is missing required runtime artifacts at ${context.pluginPath}`);
79043
79449
  }
79044
79450
  await context.runCommand("node", [join58(context.pluginPath, "scripts", "build-extension.mjs")], { cwd: context.repoRoot });
79451
+ await context.runCommand("node", [join58("packages", "omo-codex", "plugin", "scripts", "materialize-shared-upstreams.mjs")], { cwd: context.repoRoot });
79045
79452
  await context.runCommand("node", [join58(context.pluginPath, "scripts", "sync-skills.mjs")], { cwd: context.repoRoot });
79046
79453
  await context.runCommand("node", [join58(context.pluginPath, "scripts", "build-install.mjs")], { cwd: context.repoRoot });
79047
79454
  await context.runCommand("node", [join58(context.pluginPath, "scripts", "stage-lsp-daemon-runtime.mjs")], { cwd: context.repoRoot });
@@ -96671,7 +97078,8 @@ var BrowserAutomationProviderSchema = exports_external.enum([
96671
97078
  "playwright-cli"
96672
97079
  ]);
96673
97080
  var BrowserAutomationConfigSchema = exports_external.object({
96674
- provider: BrowserAutomationProviderSchema.default("playwright")
97081
+ provider: BrowserAutomationProviderSchema.default("playwright"),
97082
+ playwright_mcp_args: exports_external.array(exports_external.string()).optional()
96675
97083
  });
96676
97084
  // packages/omo-opencode/src/config/schema/categories.ts
96677
97085
  var CategoryConfigSchema = exports_external.object({
@@ -96733,9 +97141,7 @@ var CommentCheckerConfigSchema = exports_external.object({
96733
97141
  });
96734
97142
  // packages/omo-opencode/src/config/schema/commands.ts
96735
97143
  var BuiltinCommandNameSchema = exports_external.enum([
96736
- "ralph-loop",
96737
- "ulw-loop",
96738
- "cancel-ralph",
97144
+ "goal",
96739
97145
  "refactor",
96740
97146
  "start-work",
96741
97147
  "stop-continuation",
@@ -96745,7 +97151,7 @@ var BuiltinCommandNameSchema = exports_external.enum([
96745
97151
  // packages/omo-opencode/src/config/schema/default-mode.ts
96746
97152
  var DefaultModeConfigSchema = exports_external.object({
96747
97153
  ultrawork: exports_external.boolean().default(false),
96748
- ralph_loop: exports_external.boolean().default(false)
97154
+ goal: exports_external.boolean().default(false)
96749
97155
  });
96750
97156
  // packages/omo-opencode/src/config/schema/dynamic-context-pruning.ts
96751
97157
  var DynamicContextPruningConfigSchema = exports_external.object({
@@ -96793,6 +97199,12 @@ var ExperimentalConfigSchema = exports_external.object({
96793
97199
  max_tools: exports_external.number().int().min(1).optional(),
96794
97200
  disable_live_parent_wake_routing: exports_external.boolean().optional()
96795
97201
  });
97202
+ // packages/omo-opencode/src/config/schema/goal.ts
97203
+ var GoalConfigSchema = exports_external.object({
97204
+ enabled: exports_external.boolean().default(false),
97205
+ auto_start: exports_external.boolean().default(false),
97206
+ default_max_iterations: exports_external.number().min(1).max(1000).default(100)
97207
+ });
96796
97208
  // packages/skills-loader-core/src/config/git-env-prefix.ts
96797
97209
  var GIT_ENV_ASSIGNMENT_PATTERN = /^(?:[A-Za-z_][A-Za-z0-9_]*=[A-Za-z0-9_-]*)(?: [A-Za-z_][A-Za-z0-9_]*=[A-Za-z0-9_-]*)*$/;
96798
97210
  var GIT_ENV_PREFIX_VALIDATION_MESSAGE = 'git_env_prefix must be empty or use shell-safe env assignments like "GIT_MASTER=1"';
@@ -96835,7 +97247,7 @@ var HookNameSchema = exports_external.enum([
96835
97247
  "interactive-bash-session",
96836
97248
  "tool-pair-validator",
96837
97249
  "monitor-status-injector",
96838
- "ralph-loop",
97250
+ "goal",
96839
97251
  "category-skill-reminder",
96840
97252
  "compaction-context-injector",
96841
97253
  "compaction-todo-preserver",
@@ -96945,14 +97357,6 @@ var MonitorConfigSchema = exports_external.object({
96945
97357
  pattern_max_length: exports_external.number().int().min(1).default(512)
96946
97358
  });
96947
97359
 
96948
- // packages/omo-opencode/src/config/schema/ralph-loop.ts
96949
- var RalphLoopConfigSchema = exports_external.object({
96950
- enabled: exports_external.boolean().default(false),
96951
- default_max_iterations: exports_external.number().min(1).max(1000).default(100),
96952
- state_dir: exports_external.string().optional(),
96953
- default_strategy: exports_external.enum(["reset", "continue"]).default("continue")
96954
- });
96955
-
96956
97360
  // packages/omo-opencode/src/config/schema/runtime-fallback.ts
96957
97361
  var RuntimeFallbackConfigSchema = exports_external.object({
96958
97362
  enabled: exports_external.boolean().optional(),
@@ -97088,7 +97492,8 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
97088
97492
  experimental: ExperimentalConfigSchema.optional(),
97089
97493
  auto_update: exports_external.boolean().optional(),
97090
97494
  skills: SkillsConfigSchema.optional(),
97091
- ralph_loop: RalphLoopConfigSchema.optional(),
97495
+ goal: GoalConfigSchema.optional(),
97496
+ ralph_loop: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
97092
97497
  runtime_fallback: exports_external.union([exports_external.boolean(), RuntimeFallbackConfigSchema]).optional(),
97093
97498
  background_task: BackgroundTaskConfigSchema.optional(),
97094
97499
  notification: NotificationConfigSchema.optional(),
@@ -97471,6 +97876,7 @@ function loadPluginConfig(directory, ctx) {
97471
97876
  }
97472
97877
  }
97473
97878
  const userMcpEnvAllowlist = config3.mcp_env_allowlist ?? [];
97879
+ const userPlaywrightMcpArgs = config3.browser_automation_engine?.playwright_mcp_args;
97474
97880
  const canonicalAncestorPathsFarthestFirst = [...canonicalAncestorPathsNearestFirst].reverse();
97475
97881
  const defaultGitMaster = OhMyOpenCodeConfigSchema.parse({}).git_master;
97476
97882
  const ancestorGitMasterOverridesFarthestFirst = [];
@@ -97503,6 +97909,16 @@ function loadPluginConfig(directory, ctx) {
97503
97909
  ...config3,
97504
97910
  mcp_env_allowlist: userMcpEnvAllowlist
97505
97911
  };
97912
+ if (config3.browser_automation_engine) {
97913
+ const {
97914
+ playwright_mcp_args: _ancestorPlaywrightMcpArgs,
97915
+ ...browserAutomationEngine
97916
+ } = config3.browser_automation_engine;
97917
+ config3 = {
97918
+ ...config3,
97919
+ browser_automation_engine: userPlaywrightMcpArgs !== undefined ? { ...browserAutomationEngine, playwright_mcp_args: userPlaywrightMcpArgs } : browserAutomationEngine
97920
+ };
97921
+ }
97506
97922
  applyDisabledProviders(config3);
97507
97923
  log2("Final merged config", {
97508
97924
  agents: config3.agents,
@@ -97974,22 +98390,170 @@ var BOULDER_FILE = "boulder.json";
97974
98390
  var BOULDER_STATE_PATH = `${BOULDER_DIR}/${BOULDER_FILE}`;
97975
98391
  var NOTEPAD_DIR = "notepads";
97976
98392
  var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
97977
- // packages/boulder-state/src/top-level-task.ts
97978
- import { existsSync as existsSync37, readFileSync as readFileSync19 } from "node:fs";
97979
- var TODO_HEADING_PATTERN = /^##\s+TODOs\b/i;
97980
- var FINAL_VERIFICATION_HEADING_PATTERN = /^##\s+Final Verification Wave\b/i;
97981
- var SECOND_LEVEL_HEADING_PATTERN = /^##\s+/;
97982
- var UNCHECKED_CHECKBOX_PATTERN = /^(\s*)[-*]\s*\[\s*\]\s*(.+)$/;
97983
- var TODO_TASK_PATTERN = /^(\d+)\.\s+(.+)$/;
97984
- var FINAL_WAVE_TASK_PATTERN = /^(F\d+)\.\s+(.+)$/i;
97985
- function buildTaskRef(section, taskLabel) {
97986
- const pattern = section === "todo" ? TODO_TASK_PATTERN : FINAL_WAVE_TASK_PATTERN;
97987
- const match = taskLabel.match(pattern);
97988
- if (!match) {
98393
+ // packages/boulder-state/src/plan-checklist.ts
98394
+ var SIMPLE_CHECKBOX_PATTERN = /^[-*][ \t]*\[[ \t]*([xX]?)[ \t]*\][ \t]+(.+)$/;
98395
+ var TODO_HEADING_PATTERN = /^##[ \t]+TODOs(?:[ \t]+#+)?[ \t]*$/i;
98396
+ var FINAL_VERIFICATION_HEADING_PATTERN = /^##[ \t]+Final Verification Wave(?:[ \t]+#+)?[ \t]*$/i;
98397
+ var SECTION_BOUNDARY_HEADING_PATTERN = /^#{1,2}(?:[ \t]+|$)/;
98398
+ var FENCE_PATTERN = /^[ \t]{0,3}(`{3,}|~{3,})(.*)$/;
98399
+ var TODO_CHECKBOX_PATTERN = /^- \[([ xX])\] ([1-9]\d*\. .+)$/;
98400
+ var FINAL_WAVE_CHECKBOX_PATTERN = /^- \[([ xX])\] (F[1-9]\d*\. .+)$/i;
98401
+ function parsePlanChecklist(markdown) {
98402
+ const lines = markdown.split(/\r?\n/);
98403
+ if (!hasStructuredSection(lines)) {
98404
+ return parseSimpleChecklist(lines);
98405
+ }
98406
+ return parseStructuredPlan(lines).checklist;
98407
+ }
98408
+ function parseCurrentTopLevelTask(markdown) {
98409
+ const lines = markdown.split(/\r?\n/);
98410
+ if (!hasStructuredSection(lines)) {
98411
+ return null;
98412
+ }
98413
+ return parseStructuredPlan(lines).nextTask;
98414
+ }
98415
+ function parseStructuredPlan(lines) {
98416
+ let remaining = 0;
98417
+ let total = 0;
98418
+ let nextTaskLabel = null;
98419
+ let nextTask = null;
98420
+ let section = "other";
98421
+ let fence = null;
98422
+ for (const line of lines) {
98423
+ if (fence !== null) {
98424
+ if (isClosingFence(line, fence)) {
98425
+ fence = null;
98426
+ }
98427
+ continue;
98428
+ }
98429
+ const openingFence = parseOpeningFence(line);
98430
+ if (openingFence !== null) {
98431
+ fence = openingFence;
98432
+ continue;
98433
+ }
98434
+ if (SECTION_BOUNDARY_HEADING_PATTERN.test(line)) {
98435
+ section = parseStructuredSectionHeading(line);
98436
+ continue;
98437
+ }
98438
+ if (section === "other") {
98439
+ continue;
98440
+ }
98441
+ const checkbox = parseStructuredTopLevelCheckbox(line, section);
98442
+ if (checkbox === null) {
98443
+ continue;
98444
+ }
98445
+ total += 1;
98446
+ if (checkbox.checked) {
98447
+ continue;
98448
+ }
98449
+ remaining += 1;
98450
+ if (nextTaskLabel === null) {
98451
+ nextTaskLabel = checkbox.label;
98452
+ nextTask = checkbox.task;
98453
+ }
98454
+ }
98455
+ return {
98456
+ checklist: {
98457
+ completed: total - remaining,
98458
+ remaining,
98459
+ total,
98460
+ nextTaskLabel
98461
+ },
98462
+ nextTask
98463
+ };
98464
+ }
98465
+ function parseSimpleChecklist(lines) {
98466
+ let remaining = 0;
98467
+ let total = 0;
98468
+ let nextTaskLabel = null;
98469
+ let fence = null;
98470
+ for (const line of lines) {
98471
+ if (fence !== null) {
98472
+ if (isClosingFence(line, fence)) {
98473
+ fence = null;
98474
+ }
98475
+ continue;
98476
+ }
98477
+ const openingFence = parseOpeningFence(line);
98478
+ if (openingFence !== null) {
98479
+ fence = openingFence;
98480
+ continue;
98481
+ }
98482
+ const checkbox = parseSimpleTopLevelCheckbox(line);
98483
+ if (checkbox === null) {
98484
+ continue;
98485
+ }
98486
+ total += 1;
98487
+ if (checkbox.checked) {
98488
+ continue;
98489
+ }
98490
+ remaining += 1;
98491
+ if (nextTaskLabel === null) {
98492
+ nextTaskLabel = checkbox.label;
98493
+ }
98494
+ }
98495
+ return { completed: total - remaining, remaining, total, nextTaskLabel };
98496
+ }
98497
+ function parseSimpleTopLevelCheckbox(line) {
98498
+ const match = line.match(SIMPLE_CHECKBOX_PATTERN);
98499
+ const marker = match?.[1];
98500
+ const label = match?.[2];
98501
+ if (marker === undefined || label === undefined) {
98502
+ return null;
98503
+ }
98504
+ return { checked: marker.toLowerCase() === "x", label };
98505
+ }
98506
+ function hasStructuredSection(lines) {
98507
+ let fence = null;
98508
+ for (const line of lines) {
98509
+ if (fence !== null) {
98510
+ if (isClosingFence(line, fence)) {
98511
+ fence = null;
98512
+ }
98513
+ continue;
98514
+ }
98515
+ const openingFence = parseOpeningFence(line);
98516
+ if (openingFence !== null) {
98517
+ fence = openingFence;
98518
+ continue;
98519
+ }
98520
+ if (parseStructuredSectionHeading(line) !== "other") {
98521
+ return true;
98522
+ }
98523
+ }
98524
+ return false;
98525
+ }
98526
+ function parseStructuredSectionHeading(line) {
98527
+ if (TODO_HEADING_PATTERN.test(line)) {
98528
+ return "todo";
98529
+ }
98530
+ if (FINAL_VERIFICATION_HEADING_PATTERN.test(line)) {
98531
+ return "final-wave";
98532
+ }
98533
+ return "other";
98534
+ }
98535
+ function parseStructuredTopLevelCheckbox(line, section) {
98536
+ const pattern = section === "todo" ? TODO_CHECKBOX_PATTERN : FINAL_WAVE_CHECKBOX_PATTERN;
98537
+ const match = line.match(pattern);
98538
+ const marker = match?.[1];
98539
+ const label = match?.[2];
98540
+ if (marker === undefined || label === undefined) {
98541
+ return null;
98542
+ }
98543
+ const task = buildTaskRef(section, label);
98544
+ if (task === null) {
98545
+ return null;
98546
+ }
98547
+ return { checked: marker.toLowerCase() === "x", label, task };
98548
+ }
98549
+ function buildTaskRef(section, label) {
98550
+ const pattern = section === "todo" ? /^([1-9]\d*)\. (.+)$/ : /^(F[1-9]\d*)\. (.+)$/i;
98551
+ const match = label.match(pattern);
98552
+ const rawLabel = match?.[1];
98553
+ const title = match?.[2];
98554
+ if (rawLabel === undefined || title === undefined) {
97989
98555
  return null;
97990
98556
  }
97991
- const rawLabel = match[1];
97992
- const title = match[2].trim();
97993
98557
  return {
97994
98558
  key: `${section}:${rawLabel.toLowerCase()}`,
97995
98559
  section,
@@ -97997,31 +98561,29 @@ function buildTaskRef(section, taskLabel) {
97997
98561
  title
97998
98562
  };
97999
98563
  }
98564
+ function parseOpeningFence(line) {
98565
+ const match = line.match(FENCE_PATTERN);
98566
+ const run = match?.[1];
98567
+ const info = match?.[2];
98568
+ const marker = run?.charAt(0);
98569
+ if (run === undefined || info === undefined || marker !== "`" && marker !== "~" || marker === "`" && info.includes("`")) {
98570
+ return null;
98571
+ }
98572
+ return { marker, length: run.length };
98573
+ }
98574
+ function isClosingFence(line, fence) {
98575
+ const run = line.match(/^[ \t]{0,3}(`{3,}|~{3,})[ \t]*$/)?.[1];
98576
+ return run?.charAt(0) === fence.marker && run.length >= fence.length;
98577
+ }
98578
+ // packages/boulder-state/src/top-level-task.ts
98579
+ import { existsSync as existsSync37, readFileSync as readFileSync19 } from "node:fs";
98000
98580
  function readCurrentTopLevelTask(planPath) {
98001
98581
  if (!existsSync37(planPath)) {
98002
98582
  return null;
98003
98583
  }
98004
98584
  try {
98005
98585
  const content = readFileSync19(planPath, "utf-8");
98006
- const lines = content.split(/\r?\n/);
98007
- let section = "other";
98008
- for (const line of lines) {
98009
- if (SECOND_LEVEL_HEADING_PATTERN.test(line)) {
98010
- section = TODO_HEADING_PATTERN.test(line) ? "todo" : FINAL_VERIFICATION_HEADING_PATTERN.test(line) ? "final-wave" : "other";
98011
- }
98012
- const uncheckedTaskMatch = line.match(UNCHECKED_CHECKBOX_PATTERN);
98013
- if (!uncheckedTaskMatch || uncheckedTaskMatch[1].length > 0) {
98014
- continue;
98015
- }
98016
- if (section !== "todo" && section !== "final-wave") {
98017
- continue;
98018
- }
98019
- const taskRef = buildTaskRef(section, uncheckedTaskMatch[2].trim());
98020
- if (taskRef) {
98021
- return taskRef;
98022
- }
98023
- }
98024
- return null;
98586
+ return parseCurrentTopLevelTask(content);
98025
98587
  } catch {
98026
98588
  return null;
98027
98589
  }
@@ -98055,69 +98617,25 @@ function resolveBoulderPlanPathForWork(directory, work) {
98055
98617
  }
98056
98618
  // packages/boulder-state/src/storage/plan-progress.ts
98057
98619
  import { existsSync as existsSync39, readFileSync as readFileSync20, readdirSync as readdirSync5, statSync as statSync5 } from "node:fs";
98058
- var TODO_HEADING_PATTERN2 = /^##\s+TODOs\b/i;
98059
- var FINAL_VERIFICATION_HEADING_PATTERN2 = /^##\s+Final Verification Wave\b/i;
98060
- var SECOND_LEVEL_HEADING_PATTERN2 = /^##\s+/;
98061
- var UNCHECKED_CHECKBOX_PATTERN2 = /^(\s*)[-*]\s*\[\s*\]\s*(.+)$/;
98062
- var CHECKED_CHECKBOX_PATTERN = /^(\s*)[-*]\s*\[[xX]\]\s*(.+)$/;
98063
- var TODO_TASK_PATTERN2 = /^\d+\.\s+/;
98064
- var FINAL_WAVE_TASK_PATTERN2 = /^F\d+\.\s+/i;
98065
98620
  function getPlanProgress(planPath) {
98066
98621
  if (!existsSync39(planPath)) {
98067
98622
  return { total: 0, completed: 0, isComplete: false };
98068
98623
  }
98069
98624
  try {
98070
98625
  const content = readFileSync20(planPath, "utf-8");
98071
- const lines = content.split(/\r?\n/);
98072
- const hasStructuredSections = lines.some((line) => TODO_HEADING_PATTERN2.test(line) || FINAL_VERIFICATION_HEADING_PATTERN2.test(line));
98073
- if (hasStructuredSections) {
98074
- return getStructuredPlanProgress(lines);
98075
- }
98076
- return getSimplePlanProgress(content);
98626
+ const checklist = parsePlanChecklist(content);
98627
+ return {
98628
+ total: checklist.total,
98629
+ completed: checklist.completed,
98630
+ isComplete: checklist.total > 0 && checklist.remaining === 0
98631
+ };
98077
98632
  } catch {
98078
98633
  return { total: 0, completed: 0, isComplete: false };
98079
98634
  }
98080
98635
  }
98081
- function getStructuredPlanProgress(lines) {
98082
- let section = "other";
98083
- let total = 0;
98084
- let completed = 0;
98085
- for (const line of lines) {
98086
- if (SECOND_LEVEL_HEADING_PATTERN2.test(line)) {
98087
- section = TODO_HEADING_PATTERN2.test(line) ? "todo" : FINAL_VERIFICATION_HEADING_PATTERN2.test(line) ? "final-wave" : "other";
98088
- continue;
98089
- }
98090
- if (section !== "todo" && section !== "final-wave") {
98091
- continue;
98092
- }
98093
- const checkedMatch = line.match(CHECKED_CHECKBOX_PATTERN);
98094
- const uncheckedMatch = checkedMatch ? null : line.match(UNCHECKED_CHECKBOX_PATTERN2);
98095
- const match = checkedMatch ?? uncheckedMatch;
98096
- if (!match || match[1].length > 0) {
98097
- continue;
98098
- }
98099
- const taskBody = match[2].trim();
98100
- const labelPattern = section === "todo" ? TODO_TASK_PATTERN2 : FINAL_WAVE_TASK_PATTERN2;
98101
- if (!labelPattern.test(taskBody)) {
98102
- continue;
98103
- }
98104
- total += 1;
98105
- if (checkedMatch) {
98106
- completed += 1;
98107
- }
98108
- }
98109
- return { total, completed, isComplete: total > 0 && completed === total };
98110
- }
98111
- function getSimplePlanProgress(content) {
98112
- const uncheckedMatches = content.match(/^[-*]\s*\[\s*\]/gm) ?? [];
98113
- const checkedMatches = content.match(/^[-*]\s*\[[xX]\]/gm) ?? [];
98114
- const total = uncheckedMatches.length + checkedMatches.length;
98115
- const completed = checkedMatches.length;
98116
- return { total, completed, isComplete: total > 0 && completed === total };
98117
- }
98118
98636
  // packages/boulder-state/src/storage/shared.ts
98119
98637
  var RESERVED_KEYS = new Set(["__proto__", "prototype", "constructor"]);
98120
- var SESSION_ID_PREFIX_PATTERN = /^(codex|opencode):/;
98638
+ var SESSION_ID_PREFIX_PATTERN = /^(codex|opencode|senpi):/;
98121
98639
  function normalizeSessionId(sessionId, platform = "opencode") {
98122
98640
  if (SESSION_ID_PREFIX_PATTERN.test(sessionId)) {
98123
98641
  return sessionId;
@@ -98192,7 +98710,7 @@ function readBoulderState(directory) {
98192
98710
  try {
98193
98711
  const content = readFileSync21(filePath, "utf-8");
98194
98712
  const parsed = JSON.parse(content);
98195
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
98713
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || Object.keys(parsed).length === 0) {
98196
98714
  return null;
98197
98715
  }
98198
98716
  normalizeState(parsed);
@@ -100149,6 +100667,7 @@ import { readFileSync as readFileSync35 } from "node:fs";
100149
100667
  import { homedir as homedir16 } from "node:os";
100150
100668
  import { dirname as dirname29, relative as relative9 } from "node:path";
100151
100669
  init_shared();
100670
+ init_logger2();
100152
100671
  init_plugin_identity();
100153
100672
  function resolveHomeDirectory2() {
100154
100673
  return process.env.HOME ?? process.env.USERPROFILE ?? homedir16();
@@ -100237,13 +100756,45 @@ function mergeLoadedConfig(userLayersNearestFirst, projectLayersNearestFirst) {
100237
100756
  config3 = mergeConfigs2(config3, layer.config);
100238
100757
  }
100239
100758
  const userMcpEnvAllowlist = config3.mcp_env_allowlist ?? [];
100759
+ const userPlaywrightMcpArgs = config3.browser_automation_engine?.playwright_mcp_args;
100240
100760
  for (const layer of [...projectLayersNearestFirst].reverse()) {
100241
100761
  if (layer.config)
100242
100762
  config3 = mergeConfigs2(config3, layer.config);
100243
100763
  }
100244
100764
  config3 = { ...config3, mcp_env_allowlist: userMcpEnvAllowlist };
100765
+ if (config3.browser_automation_engine) {
100766
+ const {
100767
+ playwright_mcp_args: _projectPlaywrightMcpArgs,
100768
+ ...browserAutomationEngine
100769
+ } = config3.browser_automation_engine;
100770
+ config3 = {
100771
+ ...config3,
100772
+ browser_automation_engine: userPlaywrightMcpArgs !== undefined ? { ...browserAutomationEngine, playwright_mcp_args: userPlaywrightMcpArgs } : browserAutomationEngine
100773
+ };
100774
+ }
100245
100775
  return applyDisabledProviders(config3);
100246
100776
  }
100777
+ function migrateRalphLoopConfig(config3) {
100778
+ const legacy = config3.ralph_loop;
100779
+ if (legacy === undefined) {
100780
+ return config3;
100781
+ }
100782
+ const enabled = typeof legacy.enabled === "boolean" ? legacy.enabled : undefined;
100783
+ const defaultMaxIterations = typeof legacy.default_max_iterations === "number" ? legacy.default_max_iterations : undefined;
100784
+ if (enabled === undefined && defaultMaxIterations === undefined) {
100785
+ return config3;
100786
+ }
100787
+ log2("[config] ralph_loop is deprecated and will be removed in a future release. Use goal instead.");
100788
+ const existingGoal = config3.goal;
100789
+ return {
100790
+ ...config3,
100791
+ goal: {
100792
+ enabled: existingGoal?.enabled ?? enabled ?? false,
100793
+ auto_start: existingGoal?.auto_start ?? false,
100794
+ default_max_iterations: existingGoal?.default_max_iterations ?? defaultMaxIterations ?? 100
100795
+ }
100796
+ };
100797
+ }
100247
100798
  function validatePluginConfig(directory) {
100248
100799
  const userLayersNearestFirst = discoverUserLayers().map((layer) => parseLayerConfig(layer.path));
100249
100800
  const projectLayersNearestFirst = discoverProjectLayersNearestFirst(directory).map((layer) => parseLayerConfig(layer.path));
@@ -100253,7 +100804,7 @@ function validatePluginConfig(directory) {
100253
100804
  valid: messages.length === 0,
100254
100805
  messages,
100255
100806
  path: firstFailingPath(layers) ?? firstPath(layers),
100256
- config: mergeLoadedConfig(userLayersNearestFirst, projectLayersNearestFirst)
100807
+ config: migrateRalphLoopConfig(mergeLoadedConfig(userLayersNearestFirst, projectLayersNearestFirst))
100257
100808
  };
100258
100809
  }
100259
100810