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
package/dist/cli/index.js CHANGED
@@ -2145,7 +2145,7 @@ var package_default;
2145
2145
  var init_package = __esm(() => {
2146
2146
  package_default = {
2147
2147
  name: "oh-my-opencode",
2148
- version: "4.18.1",
2148
+ version: "4.19.0",
2149
2149
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
2150
2150
  main: "./dist/index.js",
2151
2151
  types: "dist/index.d.ts",
@@ -2255,7 +2255,7 @@ var init_package = __esm(() => {
2255
2255
  "install:codex-dev": "bun run script/build-codex-install.ts && bun run script/install-codex-dev.ts",
2256
2256
  "build:codex-plugin": "npm --prefix packages/omo-codex/plugin ci && bun run --cwd packages/omo-codex/plugin build",
2257
2257
  "build:senpi-plugin": "bun run build:lsp-daemon && bun run build:senpi-plugin:stage",
2258
- "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",
2258
+ "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",
2259
2259
  "build:materialize-frontend": "node packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs --strict",
2260
2260
  "build:shared-skills-assets": "bun run build:materialize-frontend && rm -rf dist/skills && cp -R packages/shared-skills/skills dist/skills",
2261
2261
  "build:lsp-tools-mcp": "npm --prefix packages/lsp-tools-mcp ci && npm --prefix packages/lsp-tools-mcp run build",
@@ -2357,18 +2357,18 @@ var init_package = __esm(() => {
2357
2357
  typescript: "^6.0.3"
2358
2358
  },
2359
2359
  optionalDependencies: {
2360
- "oh-my-opencode-darwin-arm64": "4.18.1",
2361
- "oh-my-opencode-darwin-x64": "4.18.1",
2362
- "oh-my-opencode-darwin-x64-baseline": "4.18.1",
2363
- "oh-my-opencode-linux-arm64": "4.18.1",
2364
- "oh-my-opencode-linux-arm64-musl": "4.18.1",
2365
- "oh-my-opencode-linux-x64": "4.18.1",
2366
- "oh-my-opencode-linux-x64-baseline": "4.18.1",
2367
- "oh-my-opencode-linux-x64-musl": "4.18.1",
2368
- "oh-my-opencode-linux-x64-musl-baseline": "4.18.1",
2369
- "oh-my-opencode-windows-arm64": "4.18.1",
2370
- "oh-my-opencode-windows-x64": "4.18.1",
2371
- "oh-my-opencode-windows-x64-baseline": "4.18.1"
2360
+ "oh-my-opencode-darwin-arm64": "4.19.0",
2361
+ "oh-my-opencode-darwin-x64": "4.19.0",
2362
+ "oh-my-opencode-darwin-x64-baseline": "4.19.0",
2363
+ "oh-my-opencode-linux-arm64": "4.19.0",
2364
+ "oh-my-opencode-linux-arm64-musl": "4.19.0",
2365
+ "oh-my-opencode-linux-x64": "4.19.0",
2366
+ "oh-my-opencode-linux-x64-baseline": "4.19.0",
2367
+ "oh-my-opencode-linux-x64-musl": "4.19.0",
2368
+ "oh-my-opencode-linux-x64-musl-baseline": "4.19.0",
2369
+ "oh-my-opencode-windows-arm64": "4.19.0",
2370
+ "oh-my-opencode-windows-x64": "4.19.0",
2371
+ "oh-my-opencode-windows-x64-baseline": "4.19.0"
2372
2372
  },
2373
2373
  overrides: {
2374
2374
  "@earendil-works/pi-agent-core": "0.80.3",
@@ -9198,6 +9198,7 @@ var init_agent_model_requirements = __esm(() => {
9198
9198
  model: "claude-opus-4-7",
9199
9199
  variant: "max"
9200
9200
  },
9201
+ { providers: ["opencode-go", "kimi-for-coding", "moonshotai", "opencode", "vercel"], model: "kimi-k3" },
9201
9202
  { providers: ["opencode-go", "vercel"], model: "kimi-k2.6" },
9202
9203
  { providers: ["kimi-for-coding"], model: "k2p5" },
9203
9204
  {
@@ -9222,7 +9223,7 @@ var init_agent_model_requirements = __esm(() => {
9222
9223
  hephaestus: {
9223
9224
  fallbackChain: [
9224
9225
  {
9225
- providers: ["openai", "vercel"],
9226
+ providers: ["openai", "github-copilot", "vercel"],
9226
9227
  model: "gpt-5.6-sol",
9227
9228
  variant: "high"
9228
9229
  },
@@ -9330,8 +9331,13 @@ var init_agent_model_requirements = __esm(() => {
9330
9331
  fallbackChain: [
9331
9332
  {
9332
9333
  providers: ["openai", "vercel"],
9333
- model: "gpt-5.6-sol",
9334
- variant: "xhigh"
9334
+ model: "gpt-5.6-terra",
9335
+ variant: "high"
9336
+ },
9337
+ {
9338
+ providers: ["github-copilot"],
9339
+ model: "gpt-5.6-terra",
9340
+ variant: "high"
9335
9341
  },
9336
9342
  {
9337
9343
  providers: ["openai", "github-copilot", "opencode", "vercel"],
@@ -9411,6 +9417,11 @@ var init_category_model_requirements = __esm(() => {
9411
9417
  model: "gpt-5.6-sol",
9412
9418
  variant: "xhigh"
9413
9419
  },
9420
+ {
9421
+ providers: ["github-copilot"],
9422
+ model: "gpt-5.6-sol",
9423
+ variant: "high"
9424
+ },
9414
9425
  {
9415
9426
  providers: ["openai", "opencode", "vercel"],
9416
9427
  model: "gpt-5.5",
@@ -9437,7 +9448,12 @@ var init_category_model_requirements = __esm(() => {
9437
9448
  variant: "xhigh"
9438
9449
  },
9439
9450
  {
9440
- providers: ["openai", "vercel"],
9451
+ providers: ["github-copilot"],
9452
+ model: "gpt-5.6-terra",
9453
+ variant: "high"
9454
+ },
9455
+ {
9456
+ providers: ["openai", "github-copilot", "vercel"],
9441
9457
  model: "gpt-5.6-sol",
9442
9458
  variant: "high"
9443
9459
  },
@@ -9504,6 +9520,11 @@ var init_category_model_requirements = __esm(() => {
9504
9520
  model: "gpt-5.6-luna",
9505
9521
  variant: "xhigh"
9506
9522
  },
9523
+ {
9524
+ providers: ["github-copilot"],
9525
+ model: "gpt-5.6-luna",
9526
+ variant: "high"
9527
+ },
9507
9528
  {
9508
9529
  providers: ["anthropic", "github-copilot", "opencode", "vercel"],
9509
9530
  model: "claude-sonnet-4-6"
@@ -9593,9 +9614,12 @@ function stripProviderPrefixForAliasLookup(normalizedModelID) {
9593
9614
  }
9594
9615
  return normalizedModelID.slice(slashIndex + 1);
9595
9616
  }
9596
- function resolveModelIDAlias(modelID) {
9617
+ function resolveModelIDAlias(modelID, providerID) {
9597
9618
  const requestedModelID = normalizeLookupModelID(modelID);
9598
9619
  const aliasLookupModelID = stripProviderPrefixForAliasLookup(requestedModelID);
9620
+ const normalizedProviderID = providerID ? normalizeLookupModelID(providerID) : undefined;
9621
+ const providerPrefixEnd = requestedModelID.indexOf("/");
9622
+ const embeddedProviderID = providerPrefixEnd > 0 ? requestedModelID.slice(0, providerPrefixEnd) : undefined;
9599
9623
  const exactRule = EXACT_ALIAS_RULES_BY_MODEL.get(aliasLookupModelID);
9600
9624
  if (exactRule) {
9601
9625
  return {
@@ -9606,6 +9630,13 @@ function resolveModelIDAlias(modelID) {
9606
9630
  };
9607
9631
  }
9608
9632
  for (const rule of PATTERN_ALIAS_RULES) {
9633
+ if (rule.providerIDs) {
9634
+ const matchesProviderID = normalizedProviderID !== undefined && rule.providerIDs.includes(normalizedProviderID);
9635
+ const matchesEmbeddedProviderID = normalizedProviderID !== undefined && rule.allowedSubproviderHosts?.includes(normalizedProviderID) === true && embeddedProviderID !== undefined && rule.providerIDs.includes(embeddedProviderID);
9636
+ if (!matchesProviderID && !matchesEmbeddedProviderID) {
9637
+ continue;
9638
+ }
9639
+ }
9609
9640
  if (!rule.match(aliasLookupModelID)) {
9610
9641
  continue;
9611
9642
  }
@@ -9646,6 +9677,14 @@ var init_model_capability_aliases = __esm(() => {
9646
9677
  ];
9647
9678
  EXACT_ALIAS_RULES_BY_MODEL = new Map(EXACT_ALIAS_RULES.map((rule) => [rule.aliasModelID, rule]));
9648
9679
  PATTERN_ALIAS_RULES = [
9680
+ {
9681
+ ruleID: "openai-gpt-5.6-fast-service-tier-alias",
9682
+ description: "Normalizes OpenCode's OpenAI GPT-5.6 fast service-tier IDs to canonical snapshot IDs.",
9683
+ providerIDs: ["openai"],
9684
+ allowedSubproviderHosts: ["vercel"],
9685
+ match: (normalizedModelID) => /^gpt-5\.6-(?:sol|terra|luna)-fast$/.test(normalizedModelID),
9686
+ canonicalize: (normalizedModelID) => normalizedModelID.slice(0, -"-fast".length)
9687
+ },
9649
9688
  {
9650
9689
  ruleID: "claude-thinking-legacy-alias",
9651
9690
  description: "Normalizes the legacy claude-opus-4-7-thinking id to the canonical snapshot ID.",
@@ -10060,6 +10099,21 @@ var init_runtime_fallback_model = () => {};
10060
10099
  var SUPPLEMENTAL_MODEL_CAPABILITIES;
10061
10100
  var init_supplemental_entries = __esm(() => {
10062
10101
  SUPPLEMENTAL_MODEL_CAPABILITIES = {
10102
+ "kimi-k3": {
10103
+ id: "kimi-k3",
10104
+ family: "kimi",
10105
+ reasoning: true,
10106
+ temperature: true,
10107
+ toolCall: true,
10108
+ modalities: {
10109
+ input: ["text", "image", "video"],
10110
+ output: ["text"]
10111
+ },
10112
+ limit: {
10113
+ context: 262144,
10114
+ output: 262144
10115
+ }
10116
+ },
10063
10117
  "kimi-k2.6": {
10064
10118
  id: "kimi-k2.6",
10065
10119
  family: "kimi",
@@ -10313,7 +10367,7 @@ function getProviderOverride(providerID, modelID) {
10313
10367
  return GITHUB_COPILOT_GPT5_MODEL.test(normalizeLookupModelID2(modelID)) ? GITHUB_COPILOT_GPT5_OVERRIDE : undefined;
10314
10368
  }
10315
10369
  function getModelCapabilities(input) {
10316
- const canonicalization = resolveModelIDAlias(input.modelID);
10370
+ const canonicalization = resolveModelIDAlias(input.modelID, input.providerID);
10317
10371
  const override = getOverride(input.modelID);
10318
10372
  const providerOverride = getProviderOverride(input.providerID, canonicalization.canonicalModelID);
10319
10373
  const runtimeModel = readRuntimeModel(input.runtimeModel ?? input.providerCache?.findProviderModelMetadata(input.providerID, input.modelID));
@@ -11418,6 +11472,7 @@ var init_opencode_storage_detection = __esm(() => {
11418
11472
  var opencodePluginsCache;
11419
11473
  var init_load_opencode_plugins = __esm(() => {
11420
11474
  init_jsonc_parser2();
11475
+ init_opencode_config_dir();
11421
11476
  opencodePluginsCache = new Map;
11422
11477
  });
11423
11478
 
@@ -72602,7 +72657,7 @@ var package_default2;
72602
72657
  var init_package2 = __esm(() => {
72603
72658
  package_default2 = {
72604
72659
  name: "@oh-my-opencode/omo-codex",
72605
- version: "4.18.1",
72660
+ version: "4.19.0",
72606
72661
  type: "module",
72607
72662
  private: true,
72608
72663
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -75644,9 +75699,16 @@ function findTomlSection(config, header) {
75644
75699
  const lines = config.match(/[^\n]*\n?|$/g) ?? [];
75645
75700
  let offset = 0;
75646
75701
  let start = -1;
75702
+ let multilineQuote = null;
75647
75703
  for (const line of lines) {
75648
75704
  if (line.length === 0)
75649
75705
  break;
75706
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
75707
+ multilineQuote = multilineScan.nextQuote;
75708
+ if (multilineScan.wasInside) {
75709
+ offset += line.length;
75710
+ continue;
75711
+ }
75650
75712
  const trimmed = line.trim();
75651
75713
  if (start === -1) {
75652
75714
  if (tomlTableHeaderMatches(trimmed, headerLine, targetHeaderPath))
@@ -75661,8 +75723,37 @@ function findTomlSection(config, header) {
75661
75723
  return { start, end: config.length, text: config.slice(start) };
75662
75724
  }
75663
75725
  function replaceOrInsertSetting(config, section, key, value) {
75664
- const linePattern = new RegExp(`^[ \\t]*${escapeRegExp(key)}[ \\t]*=.*$`, "m");
75665
- const replacement = linePattern.test(section.text) ? section.text.replace(linePattern, `${key} = ${value}`) : insertSetting(section.text, key, value);
75726
+ const targetPath = parseTomlDottedKey(key);
75727
+ if (!targetPath)
75728
+ return config;
75729
+ const lines = section.text.match(/[^\n]*\n?|$/g) ?? [];
75730
+ let offset = 0;
75731
+ let multilineQuote = null;
75732
+ for (const line of lines) {
75733
+ if (line.length === 0)
75734
+ break;
75735
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
75736
+ multilineQuote = multilineScan.nextQuote;
75737
+ if (multilineScan.wasInside) {
75738
+ offset += line.length;
75739
+ continue;
75740
+ }
75741
+ const assignmentIndex = findUnquotedAssignment(line);
75742
+ if (assignmentIndex < 0) {
75743
+ offset += line.length;
75744
+ continue;
75745
+ }
75746
+ const settingPath = parseTomlDottedKey(line.slice(0, assignmentIndex).trim());
75747
+ if (!settingPath || !tomlPathMatches(settingPath, targetPath)) {
75748
+ offset += line.length;
75749
+ continue;
75750
+ }
75751
+ const replacement2 = replaceTomlAssignmentValue(line, assignmentIndex, value);
75752
+ const assignmentEnd = multilineScan.nextQuote ? findTomlMultilineValueEnd(section.text, offset + line.length, multilineScan.nextQuote) : offset + line.length;
75753
+ const sectionReplacement = section.text.slice(0, offset) + replacement2 + section.text.slice(assignmentEnd);
75754
+ return config.slice(0, section.start) + sectionReplacement + config.slice(section.end);
75755
+ }
75756
+ const replacement = insertSetting(section.text, key, value);
75666
75757
  return config.slice(0, section.start) + replacement + config.slice(section.end);
75667
75758
  }
75668
75759
  function removeSetting(config, section, key) {
@@ -75682,6 +75773,50 @@ function replaceOrInsertRootSetting(config, key, value) {
75682
75773
  return replacement;
75683
75774
  return `${replacement.trimEnd()}
75684
75775
 
75776
+ ${suffix.trimStart()}`;
75777
+ }
75778
+ function replaceOrInsertRootDottedSetting(config, keyPath, value) {
75779
+ const targetPath = parseTomlDottedKey(keyPath);
75780
+ if (!targetPath)
75781
+ return config;
75782
+ const lines = config.match(/[^\n]*\n?|$/g) ?? [];
75783
+ let offset = 0;
75784
+ let multilineQuote = null;
75785
+ for (const line of lines) {
75786
+ if (line.length === 0)
75787
+ break;
75788
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
75789
+ multilineQuote = multilineScan.nextQuote;
75790
+ if (multilineScan.wasInside) {
75791
+ offset += line.length;
75792
+ continue;
75793
+ }
75794
+ if (isTomlTableHeaderLine(line))
75795
+ break;
75796
+ const assignmentIndex = findUnquotedAssignment(line);
75797
+ if (assignmentIndex < 0) {
75798
+ offset += line.length;
75799
+ continue;
75800
+ }
75801
+ const settingPath = parseTomlDottedKey(line.slice(0, assignmentIndex).trim());
75802
+ if (!settingPath || !tomlPathMatches(settingPath, targetPath)) {
75803
+ offset += line.length;
75804
+ continue;
75805
+ }
75806
+ const replacement2 = replaceTomlAssignmentValue(line, assignmentIndex, value);
75807
+ const assignmentEnd = multilineScan.nextQuote ? findTomlMultilineValueEnd(config, offset + line.length, multilineScan.nextQuote) : offset + line.length;
75808
+ return config.slice(0, offset) + replacement2 + config.slice(assignmentEnd);
75809
+ }
75810
+ const sectionStart = findFirstTableStart(config);
75811
+ const root = config.slice(0, sectionStart).trimEnd();
75812
+ const suffix = config.slice(sectionStart);
75813
+ const replacement = `${root}${root.length > 0 ? `
75814
+ ` : ""}${keyPath} = ${value}
75815
+ `;
75816
+ if (suffix.length === 0)
75817
+ return replacement;
75818
+ return `${replacement.trimEnd()}
75819
+
75685
75820
  ${suffix.trimStart()}`;
75686
75821
  }
75687
75822
  function appendBlock(config, block) {
@@ -75694,9 +75829,16 @@ function appendBlock(config, block) {
75694
75829
  function findFirstTableStart(config) {
75695
75830
  const lines = config.match(/[^\n]*\n?|$/g) ?? [];
75696
75831
  let offset = 0;
75832
+ let multilineQuote = null;
75697
75833
  for (const line of lines) {
75698
75834
  if (line.length === 0)
75699
75835
  break;
75836
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
75837
+ multilineQuote = multilineScan.nextQuote;
75838
+ if (multilineScan.wasInside) {
75839
+ offset += line.length;
75840
+ continue;
75841
+ }
75700
75842
  if (isTomlTableHeaderLine(line))
75701
75843
  return offset;
75702
75844
  offset += line.length;
@@ -75734,6 +75876,131 @@ function isTomlTableHeaderLine(line) {
75734
75876
  const normalizedLine = stripUnquotedInlineComment(line).trim();
75735
75877
  return normalizedLine.startsWith("[") && normalizedLine.endsWith("]");
75736
75878
  }
75879
+ function scanTomlMultilineLine(line, currentQuote) {
75880
+ if (currentQuote) {
75881
+ return {
75882
+ wasInside: true,
75883
+ nextQuote: findTomlMultilineDelimiter(line, currentQuote, 0) === -1 ? currentQuote : null
75884
+ };
75885
+ }
75886
+ let quote = null;
75887
+ let index = 0;
75888
+ while (index < line.length) {
75889
+ const char = line[index];
75890
+ if (quote === '"') {
75891
+ if (char === "\\") {
75892
+ index += 2;
75893
+ continue;
75894
+ }
75895
+ if (char === '"')
75896
+ quote = null;
75897
+ index += 1;
75898
+ continue;
75899
+ }
75900
+ if (quote === "'") {
75901
+ if (char === "'")
75902
+ quote = null;
75903
+ index += 1;
75904
+ continue;
75905
+ }
75906
+ if (char === "#")
75907
+ break;
75908
+ const delimiter2 = line.startsWith('"""', index) ? '"""' : line.startsWith("'''", index) ? "'''" : null;
75909
+ if (delimiter2) {
75910
+ const closingIndex = findTomlMultilineDelimiter(line, delimiter2, index + delimiter2.length);
75911
+ return { wasInside: false, nextQuote: closingIndex === -1 ? delimiter2 : null };
75912
+ }
75913
+ if (char === '"' || char === "'")
75914
+ quote = char;
75915
+ index += 1;
75916
+ }
75917
+ return { wasInside: false, nextQuote: null };
75918
+ }
75919
+ function findTomlMultilineDelimiter(line, delimiter2, startIndex) {
75920
+ let index = line.indexOf(delimiter2, startIndex);
75921
+ while (index !== -1) {
75922
+ if (delimiter2 === "'''" || countPrecedingBackslashes(line, index) % 2 === 0)
75923
+ return index;
75924
+ index = line.indexOf(delimiter2, index + 1);
75925
+ }
75926
+ return -1;
75927
+ }
75928
+ function countPrecedingBackslashes(line, index) {
75929
+ let count = 0;
75930
+ let cursor = index - 1;
75931
+ while (cursor >= 0 && line[cursor] === "\\") {
75932
+ count += 1;
75933
+ cursor -= 1;
75934
+ }
75935
+ return count;
75936
+ }
75937
+ function findUnquotedAssignment(line) {
75938
+ return findUnquotedCharacter(line, "=", 0);
75939
+ }
75940
+ function findUnquotedComment(line, startIndex) {
75941
+ return findUnquotedCharacter(line, "#", startIndex);
75942
+ }
75943
+ function findUnquotedCharacter(line, target, startIndex) {
75944
+ let quote = null;
75945
+ let index = startIndex;
75946
+ while (index < line.length) {
75947
+ const char = line[index];
75948
+ if (quote === '"') {
75949
+ if (char === "\\") {
75950
+ index += 2;
75951
+ continue;
75952
+ }
75953
+ if (char === '"')
75954
+ quote = null;
75955
+ index += 1;
75956
+ continue;
75957
+ }
75958
+ if (quote === "'") {
75959
+ if (char === "'")
75960
+ quote = null;
75961
+ index += 1;
75962
+ continue;
75963
+ }
75964
+ if (char === '"' || char === "'") {
75965
+ quote = char;
75966
+ index += 1;
75967
+ continue;
75968
+ }
75969
+ if (char === target)
75970
+ return index;
75971
+ if (char === "#")
75972
+ return -1;
75973
+ index += 1;
75974
+ }
75975
+ return -1;
75976
+ }
75977
+ function tomlPathMatches(candidate, target) {
75978
+ return candidate.length === target.length && candidate.every((part, index) => part === target[index]);
75979
+ }
75980
+ function replaceTomlAssignmentValue(line, assignmentIndex, value) {
75981
+ const newline = line.endsWith(`
75982
+ `) ? `
75983
+ ` : "";
75984
+ const lineBody = newline ? line.slice(0, -1) : line;
75985
+ const commentIndex = findUnquotedComment(lineBody, assignmentIndex + 1);
75986
+ const comment = commentIndex === -1 ? "" : ` ${lineBody.slice(commentIndex).trimStart()}`;
75987
+ return `${lineBody.slice(0, assignmentIndex + 1)} ${value}${comment}${newline}`;
75988
+ }
75989
+ function findTomlMultilineValueEnd(text, startOffset, quote) {
75990
+ const lines = text.slice(startOffset).match(/[^\n]*\n?|$/g) ?? [];
75991
+ let offset = startOffset;
75992
+ let currentQuote = quote;
75993
+ for (const line of lines) {
75994
+ if (line.length === 0)
75995
+ break;
75996
+ const scan = scanTomlMultilineLine(line, currentQuote);
75997
+ currentQuote = scan.nextQuote;
75998
+ offset += line.length;
75999
+ if (currentQuote === null)
76000
+ return offset;
76001
+ }
76002
+ return text.length;
76003
+ }
75737
76004
  function stripUnquotedInlineComment(line) {
75738
76005
  let quote = null;
75739
76006
  let index = 0;
@@ -76064,13 +76331,137 @@ function delay(milliseconds) {
76064
76331
  return new Promise((resolveDelay) => setTimeout(resolveDelay, milliseconds));
76065
76332
  }
76066
76333
 
76334
+ // packages/omo-codex/src/install/toml-setting-reader.ts
76335
+ function hasTomlSetting(config, keyPath) {
76336
+ const targetPath = parseTomlDottedKey(keyPath);
76337
+ if (!targetPath)
76338
+ return false;
76339
+ return hasTomlAssignment(config, (tablePath, settingPath) => {
76340
+ const fullPath = [...tablePath, ...settingPath];
76341
+ return fullPath.length === targetPath.length && fullPath.every((part, index) => part === targetPath[index]);
76342
+ });
76343
+ }
76344
+ function hasTomlRootDottedKeyPrefix(config, rootKey) {
76345
+ return hasTomlAssignment(config, (tablePath, settingPath) => tablePath.length === 0 && settingPath.length > 1 && settingPath[0] === rootKey);
76346
+ }
76347
+ function hasTomlAssignment(config, predicate) {
76348
+ let tablePath = [];
76349
+ let multilineQuote = null;
76350
+ for (const line of config.split(`
76351
+ `)) {
76352
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
76353
+ multilineQuote = multilineScan.nextQuote;
76354
+ if (multilineScan.wasInside)
76355
+ continue;
76356
+ const normalizedLine = stripUnquotedInlineComment2(line).trim();
76357
+ if (normalizedLine.length === 0)
76358
+ continue;
76359
+ const headerPath = parseTomlTableHeader2(normalizedLine);
76360
+ if (headerPath) {
76361
+ tablePath = headerPath;
76362
+ continue;
76363
+ }
76364
+ if (isTomlTableHeaderLine2(normalizedLine)) {
76365
+ tablePath = null;
76366
+ continue;
76367
+ }
76368
+ if (!tablePath)
76369
+ continue;
76370
+ const assignmentIndex = findUnquotedAssignment2(normalizedLine);
76371
+ if (assignmentIndex < 0)
76372
+ continue;
76373
+ const settingPath = parseTomlDottedKey(normalizedLine.slice(0, assignmentIndex).trim());
76374
+ if (!settingPath)
76375
+ continue;
76376
+ if (predicate(tablePath, settingPath))
76377
+ return true;
76378
+ }
76379
+ return false;
76380
+ }
76381
+ function parseTomlTableHeader2(line) {
76382
+ if (!line.startsWith("[") || !line.endsWith("]") || line.startsWith("[["))
76383
+ return null;
76384
+ return parseTomlDottedKey(line.slice(1, -1).trim());
76385
+ }
76386
+ function isTomlTableHeaderLine2(line) {
76387
+ return line.startsWith("[") && line.endsWith("]");
76388
+ }
76389
+ function stripUnquotedInlineComment2(line) {
76390
+ let quote = null;
76391
+ let index = 0;
76392
+ while (index < line.length) {
76393
+ const char = line[index];
76394
+ if (quote === '"') {
76395
+ if (char === "\\") {
76396
+ index += 2;
76397
+ continue;
76398
+ }
76399
+ if (char === '"')
76400
+ quote = null;
76401
+ index += 1;
76402
+ continue;
76403
+ }
76404
+ if (quote === "'") {
76405
+ if (char === "'")
76406
+ quote = null;
76407
+ index += 1;
76408
+ continue;
76409
+ }
76410
+ if (char === '"' || char === "'") {
76411
+ quote = char;
76412
+ index += 1;
76413
+ continue;
76414
+ }
76415
+ if (char === "#")
76416
+ return line.slice(0, index);
76417
+ index += 1;
76418
+ }
76419
+ return line;
76420
+ }
76421
+ function findUnquotedAssignment2(line) {
76422
+ let quote = null;
76423
+ let index = 0;
76424
+ while (index < line.length) {
76425
+ const char = line[index];
76426
+ if (quote === '"') {
76427
+ if (char === "\\") {
76428
+ index += 2;
76429
+ continue;
76430
+ }
76431
+ if (char === '"')
76432
+ quote = null;
76433
+ index += 1;
76434
+ continue;
76435
+ }
76436
+ if (quote === "'") {
76437
+ if (char === "'")
76438
+ quote = null;
76439
+ index += 1;
76440
+ continue;
76441
+ }
76442
+ if (char === '"' || char === "'") {
76443
+ quote = char;
76444
+ index += 1;
76445
+ continue;
76446
+ }
76447
+ if (char === "=")
76448
+ return index;
76449
+ index += 1;
76450
+ }
76451
+ return -1;
76452
+ }
76453
+
76067
76454
  // packages/omo-codex/src/install/codex-config-features.ts
76068
76455
  function ensureFeatureEnabled(config, featureName) {
76069
76456
  const section = findTomlSection(config, "features");
76070
- if (!section)
76457
+ if (!section) {
76458
+ if (hasTomlRootDottedKeyPrefix(config, "features")) {
76459
+ return replaceOrInsertRootDottedSetting(config, `features.${featureName}`, "true");
76460
+ }
76071
76461
  return appendBlock(config, `[features]
76072
76462
  ${featureName} = true
76073
76463
  `);
76464
+ }
76074
76465
  return replaceOrInsertSetting(config, section, featureName, "true");
76075
76466
  }
76076
76467
 
@@ -76138,7 +76529,7 @@ function ensureAutonomousPermissions(config) {
76138
76529
  next = replaceOrInsertRootSetting(next, "sandbox_mode", JSON.stringify("danger-full-access"));
76139
76530
  next = replaceOrInsertRootSetting(next, "network_access", JSON.stringify("enabled"));
76140
76531
  for (const featureName of AUTONOMOUS_FEATURES) {
76141
- next = ensureFeatureEnabled2(next, featureName);
76532
+ next = ensureFeatureEnabled(next, featureName);
76142
76533
  }
76143
76534
  next = removeWindowsSandboxSetting(next);
76144
76535
  next = ensureNoticeEnabled(next, "hide_full_access_warning");
@@ -76156,14 +76547,6 @@ function ensureNoticeEnabled(config, key) {
76156
76547
  return appendNoticeBlock(config, key);
76157
76548
  return replaceOrInsertSetting(config, section, key, "true");
76158
76549
  }
76159
- function ensureFeatureEnabled2(config, key) {
76160
- const section = findTomlSection(config, "features");
76161
- if (section === null)
76162
- return appendBlock(config, `[features]
76163
- ${key} = true
76164
- `);
76165
- return replaceOrInsertSetting(config, section, key, "true");
76166
- }
76167
76550
  function appendNoticeBlock(config, key) {
76168
76551
  return appendBlock(config, `[notice]
76169
76552
  ${key} = true
@@ -76235,7 +76618,7 @@ function readStringArraySetting(sectionText, key) {
76235
76618
  const assignmentIndex = line.indexOf("=");
76236
76619
  if (assignmentIndex === -1)
76237
76620
  return null;
76238
- return parseTomlStringArray(stripUnquotedInlineComment2(line.slice(assignmentIndex + 1)).trim());
76621
+ return parseTomlStringArray(stripUnquotedInlineComment3(line.slice(assignmentIndex + 1)).trim());
76239
76622
  }
76240
76623
  return null;
76241
76624
  }
@@ -76279,7 +76662,7 @@ function parseTomlString(input, startIndex) {
76279
76662
  }
76280
76663
  return null;
76281
76664
  }
76282
- function stripUnquotedInlineComment2(line) {
76665
+ function stripUnquotedInlineComment3(line) {
76283
76666
  let quote = null;
76284
76667
  let index = 0;
76285
76668
  while (index < line.length) {
@@ -76493,24 +76876,27 @@ import { readFileSync as readFileSync13 } from "fs";
76493
76876
  import { dirname as dirname15, isAbsolute as isAbsolute8, join as join39 } from "path";
76494
76877
  var CODEX_AGENTS_HEADER = "agents";
76495
76878
  var CODEX_MULTI_AGENT_V2_HEADER = "features.multi_agent_v2";
76879
+ var CODEX_MULTI_AGENT_V2_THREAD_LIMIT_KEY = `${CODEX_MULTI_AGENT_V2_HEADER}.max_concurrent_threads_per_session`;
76496
76880
  var CODEX_SUBAGENT_THREAD_LIMIT = 1000;
76881
+ var CODEX_MULTI_AGENT_V2_THREAD_LIMIT = 16;
76497
76882
  function ensureCodexMultiAgentV2Config(config, options = {}) {
76498
76883
  const featureFlag = removeFeatureFlagSetting(config, "multi_agent_v2");
76499
76884
  const v2Preferred = options.multiAgentVersion === "v2";
76500
76885
  const modelKnown = options.multiAgentVersion != null || readRootModel(featureFlag.config) !== null;
76501
76886
  const agentsConfig = v2Preferred ? removeAgentsMaxThreads(featureFlag.config) : modelKnown ? ensureAgentsMaxThreads(featureFlag.config) : raiseExistingAgentsMaxThreads(featureFlag.config);
76502
- const maxThreadsValue = CODEX_SUBAGENT_THREAD_LIMIT.toString();
76503
76887
  const preserveDisable = featureFlag.value === false && !v2Preferred;
76504
76888
  const featureConfig = preserveDisable ? setMultiAgentV2Disable(agentsConfig) : v2Preferred ? removeMultiAgentV2Disable(agentsConfig) : agentsConfig;
76889
+ if (hasTomlSetting(featureConfig, CODEX_MULTI_AGENT_V2_THREAD_LIMIT_KEY))
76890
+ return featureConfig;
76505
76891
  const section = findTomlSection(featureConfig, CODEX_MULTI_AGENT_V2_HEADER);
76506
76892
  if (!section) {
76507
76893
  const enabledSetting = preserveDisable ? `enabled = false
76508
76894
  ` : "";
76509
76895
  return appendBlock(featureConfig, `[${CODEX_MULTI_AGENT_V2_HEADER}]
76510
- ${enabledSetting}max_concurrent_threads_per_session = ${maxThreadsValue}
76896
+ ${enabledSetting}max_concurrent_threads_per_session = ${CODEX_MULTI_AGENT_V2_THREAD_LIMIT}
76511
76897
  `);
76512
76898
  }
76513
- return replaceOrInsertSetting(featureConfig, section, "max_concurrent_threads_per_session", maxThreadsValue);
76899
+ return replaceOrInsertSetting(featureConfig, section, "max_concurrent_threads_per_session", CODEX_MULTI_AGENT_V2_THREAD_LIMIT.toString());
76514
76900
  }
76515
76901
  function resolveCodexMultiAgentVersion(config, configPath) {
76516
76902
  const model = readRootModel(config);
@@ -76869,6 +77255,10 @@ var MANAGED_REASONING_DEFAULT_UPGRADES = new Map([
76869
77255
  {
76870
77256
  previous: { model: "gpt-5.5", effort: "xhigh" },
76871
77257
  current: { model: "gpt-5.6-sol", effort: "ultra" }
77258
+ },
77259
+ {
77260
+ previous: { model: "gpt-5.6-sol", effort: "ultra" },
77261
+ current: { model: "gpt-5.6-terra", effort: "high" }
76872
77262
  }
76873
77263
  ]
76874
77264
  ],
@@ -78931,8 +79321,24 @@ import { promisify as promisify2 } from "util";
78931
79321
  var execFileAsync2 = promisify2(execFile4);
78932
79322
  var REQUIRED_PLUGIN_ARTIFACTS = [
78933
79323
  join58("extensions", "omo.js"),
79324
+ join58("skills", "ast-grep", "SKILL.md"),
79325
+ join58("skills", "coding-agent-sessions", "SKILL.md"),
79326
+ join58("skills", "debugging", "SKILL.md"),
79327
+ join58("skills", "frontend", "SKILL.md"),
79328
+ join58("skills", "git-master", "SKILL.md"),
79329
+ join58("skills", "init-deep", "SKILL.md"),
79330
+ join58("skills", "lsp-setup", "SKILL.md"),
79331
+ join58("skills", "programming", "SKILL.md"),
79332
+ join58("skills", "refactor", "SKILL.md"),
79333
+ join58("skills", "remove-ai-slops", "SKILL.md"),
79334
+ join58("skills", "review-work", "SKILL.md"),
79335
+ join58("skills", "start-work", "SKILL.md"),
79336
+ join58("skills", "ultimate-browsing", "SKILL.md"),
78934
79337
  join58("skills", "ultrawork", "SKILL.md"),
78935
79338
  join58("skills", "ulw-loop", "SKILL.md"),
79339
+ join58("skills", "ulw-plan", "SKILL.md"),
79340
+ join58("skills", "ulw-research", "SKILL.md"),
79341
+ join58("skills", "visual-qa", "SKILL.md"),
78936
79342
  join58("runtime", "lsp-daemon", "dist", "cli.js"),
78937
79343
  join58("runtime", "lsp-daemon", "dist", "index.js"),
78938
79344
  join58("runtime", "lsp-daemon", "dist", "index.d.ts"),
@@ -78986,6 +79392,7 @@ async function ensurePluginArtifacts(context) {
78986
79392
  throw new Error(`Packed omo-senpi plugin is missing required runtime artifacts at ${context.pluginPath}`);
78987
79393
  }
78988
79394
  await context.runCommand("node", [join58(context.pluginPath, "scripts", "build-extension.mjs")], { cwd: context.repoRoot });
79395
+ await context.runCommand("node", [join58("packages", "omo-codex", "plugin", "scripts", "materialize-shared-upstreams.mjs")], { cwd: context.repoRoot });
78989
79396
  await context.runCommand("node", [join58(context.pluginPath, "scripts", "sync-skills.mjs")], { cwd: context.repoRoot });
78990
79397
  await context.runCommand("node", [join58(context.pluginPath, "scripts", "build-install.mjs")], { cwd: context.repoRoot });
78991
79398
  await context.runCommand("node", [join58(context.pluginPath, "scripts", "stage-lsp-daemon-runtime.mjs")], { cwd: context.repoRoot });
@@ -96615,7 +97022,8 @@ var BrowserAutomationProviderSchema = exports_external.enum([
96615
97022
  "playwright-cli"
96616
97023
  ]);
96617
97024
  var BrowserAutomationConfigSchema = exports_external.object({
96618
- provider: BrowserAutomationProviderSchema.default("playwright")
97025
+ provider: BrowserAutomationProviderSchema.default("playwright"),
97026
+ playwright_mcp_args: exports_external.array(exports_external.string()).optional()
96619
97027
  });
96620
97028
  // packages/omo-opencode/src/config/schema/categories.ts
96621
97029
  var CategoryConfigSchema = exports_external.object({
@@ -96677,9 +97085,7 @@ var CommentCheckerConfigSchema = exports_external.object({
96677
97085
  });
96678
97086
  // packages/omo-opencode/src/config/schema/commands.ts
96679
97087
  var BuiltinCommandNameSchema = exports_external.enum([
96680
- "ralph-loop",
96681
- "ulw-loop",
96682
- "cancel-ralph",
97088
+ "goal",
96683
97089
  "refactor",
96684
97090
  "start-work",
96685
97091
  "stop-continuation",
@@ -96689,7 +97095,7 @@ var BuiltinCommandNameSchema = exports_external.enum([
96689
97095
  // packages/omo-opencode/src/config/schema/default-mode.ts
96690
97096
  var DefaultModeConfigSchema = exports_external.object({
96691
97097
  ultrawork: exports_external.boolean().default(false),
96692
- ralph_loop: exports_external.boolean().default(false)
97098
+ goal: exports_external.boolean().default(false)
96693
97099
  });
96694
97100
  // packages/omo-opencode/src/config/schema/dynamic-context-pruning.ts
96695
97101
  var DynamicContextPruningConfigSchema = exports_external.object({
@@ -96737,6 +97143,12 @@ var ExperimentalConfigSchema = exports_external.object({
96737
97143
  max_tools: exports_external.number().int().min(1).optional(),
96738
97144
  disable_live_parent_wake_routing: exports_external.boolean().optional()
96739
97145
  });
97146
+ // packages/omo-opencode/src/config/schema/goal.ts
97147
+ var GoalConfigSchema = exports_external.object({
97148
+ enabled: exports_external.boolean().default(false),
97149
+ auto_start: exports_external.boolean().default(false),
97150
+ default_max_iterations: exports_external.number().min(1).max(1000).default(100)
97151
+ });
96740
97152
  // packages/skills-loader-core/src/config/git-env-prefix.ts
96741
97153
  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_-]*)*$/;
96742
97154
  var GIT_ENV_PREFIX_VALIDATION_MESSAGE = 'git_env_prefix must be empty or use shell-safe env assignments like "GIT_MASTER=1"';
@@ -96779,7 +97191,7 @@ var HookNameSchema = exports_external.enum([
96779
97191
  "interactive-bash-session",
96780
97192
  "tool-pair-validator",
96781
97193
  "monitor-status-injector",
96782
- "ralph-loop",
97194
+ "goal",
96783
97195
  "category-skill-reminder",
96784
97196
  "compaction-context-injector",
96785
97197
  "compaction-todo-preserver",
@@ -96889,14 +97301,6 @@ var MonitorConfigSchema = exports_external.object({
96889
97301
  pattern_max_length: exports_external.number().int().min(1).default(512)
96890
97302
  });
96891
97303
 
96892
- // packages/omo-opencode/src/config/schema/ralph-loop.ts
96893
- var RalphLoopConfigSchema = exports_external.object({
96894
- enabled: exports_external.boolean().default(false),
96895
- default_max_iterations: exports_external.number().min(1).max(1000).default(100),
96896
- state_dir: exports_external.string().optional(),
96897
- default_strategy: exports_external.enum(["reset", "continue"]).default("continue")
96898
- });
96899
-
96900
97304
  // packages/omo-opencode/src/config/schema/runtime-fallback.ts
96901
97305
  var RuntimeFallbackConfigSchema = exports_external.object({
96902
97306
  enabled: exports_external.boolean().optional(),
@@ -97032,7 +97436,8 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
97032
97436
  experimental: ExperimentalConfigSchema.optional(),
97033
97437
  auto_update: exports_external.boolean().optional(),
97034
97438
  skills: SkillsConfigSchema.optional(),
97035
- ralph_loop: RalphLoopConfigSchema.optional(),
97439
+ goal: GoalConfigSchema.optional(),
97440
+ ralph_loop: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
97036
97441
  runtime_fallback: exports_external.union([exports_external.boolean(), RuntimeFallbackConfigSchema]).optional(),
97037
97442
  background_task: BackgroundTaskConfigSchema.optional(),
97038
97443
  notification: NotificationConfigSchema.optional(),
@@ -97415,6 +97820,7 @@ function loadPluginConfig(directory, ctx) {
97415
97820
  }
97416
97821
  }
97417
97822
  const userMcpEnvAllowlist = config3.mcp_env_allowlist ?? [];
97823
+ const userPlaywrightMcpArgs = config3.browser_automation_engine?.playwright_mcp_args;
97418
97824
  const canonicalAncestorPathsFarthestFirst = [...canonicalAncestorPathsNearestFirst].reverse();
97419
97825
  const defaultGitMaster = OhMyOpenCodeConfigSchema.parse({}).git_master;
97420
97826
  const ancestorGitMasterOverridesFarthestFirst = [];
@@ -97447,6 +97853,16 @@ function loadPluginConfig(directory, ctx) {
97447
97853
  ...config3,
97448
97854
  mcp_env_allowlist: userMcpEnvAllowlist
97449
97855
  };
97856
+ if (config3.browser_automation_engine) {
97857
+ const {
97858
+ playwright_mcp_args: _ancestorPlaywrightMcpArgs,
97859
+ ...browserAutomationEngine
97860
+ } = config3.browser_automation_engine;
97861
+ config3 = {
97862
+ ...config3,
97863
+ browser_automation_engine: userPlaywrightMcpArgs !== undefined ? { ...browserAutomationEngine, playwright_mcp_args: userPlaywrightMcpArgs } : browserAutomationEngine
97864
+ };
97865
+ }
97450
97866
  applyDisabledProviders(config3);
97451
97867
  log2("Final merged config", {
97452
97868
  agents: config3.agents,
@@ -97918,22 +98334,170 @@ var BOULDER_FILE = "boulder.json";
97918
98334
  var BOULDER_STATE_PATH = `${BOULDER_DIR}/${BOULDER_FILE}`;
97919
98335
  var NOTEPAD_DIR = "notepads";
97920
98336
  var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
97921
- // packages/boulder-state/src/top-level-task.ts
97922
- import { existsSync as existsSync37, readFileSync as readFileSync19 } from "fs";
97923
- var TODO_HEADING_PATTERN = /^##\s+TODOs\b/i;
97924
- var FINAL_VERIFICATION_HEADING_PATTERN = /^##\s+Final Verification Wave\b/i;
97925
- var SECOND_LEVEL_HEADING_PATTERN = /^##\s+/;
97926
- var UNCHECKED_CHECKBOX_PATTERN = /^(\s*)[-*]\s*\[\s*\]\s*(.+)$/;
97927
- var TODO_TASK_PATTERN = /^(\d+)\.\s+(.+)$/;
97928
- var FINAL_WAVE_TASK_PATTERN = /^(F\d+)\.\s+(.+)$/i;
97929
- function buildTaskRef(section, taskLabel) {
97930
- const pattern = section === "todo" ? TODO_TASK_PATTERN : FINAL_WAVE_TASK_PATTERN;
97931
- const match = taskLabel.match(pattern);
97932
- if (!match) {
98337
+ // packages/boulder-state/src/plan-checklist.ts
98338
+ var SIMPLE_CHECKBOX_PATTERN = /^[-*][ \t]*\[[ \t]*([xX]?)[ \t]*\][ \t]+(.+)$/;
98339
+ var TODO_HEADING_PATTERN = /^##[ \t]+TODOs(?:[ \t]+#+)?[ \t]*$/i;
98340
+ var FINAL_VERIFICATION_HEADING_PATTERN = /^##[ \t]+Final Verification Wave(?:[ \t]+#+)?[ \t]*$/i;
98341
+ var SECTION_BOUNDARY_HEADING_PATTERN = /^#{1,2}(?:[ \t]+|$)/;
98342
+ var FENCE_PATTERN = /^[ \t]{0,3}(`{3,}|~{3,})(.*)$/;
98343
+ var TODO_CHECKBOX_PATTERN = /^- \[([ xX])\] ([1-9]\d*\. .+)$/;
98344
+ var FINAL_WAVE_CHECKBOX_PATTERN = /^- \[([ xX])\] (F[1-9]\d*\. .+)$/i;
98345
+ function parsePlanChecklist(markdown) {
98346
+ const lines = markdown.split(/\r?\n/);
98347
+ if (!hasStructuredSection(lines)) {
98348
+ return parseSimpleChecklist(lines);
98349
+ }
98350
+ return parseStructuredPlan(lines).checklist;
98351
+ }
98352
+ function parseCurrentTopLevelTask(markdown) {
98353
+ const lines = markdown.split(/\r?\n/);
98354
+ if (!hasStructuredSection(lines)) {
98355
+ return null;
98356
+ }
98357
+ return parseStructuredPlan(lines).nextTask;
98358
+ }
98359
+ function parseStructuredPlan(lines) {
98360
+ let remaining = 0;
98361
+ let total = 0;
98362
+ let nextTaskLabel = null;
98363
+ let nextTask = null;
98364
+ let section = "other";
98365
+ let fence = null;
98366
+ for (const line of lines) {
98367
+ if (fence !== null) {
98368
+ if (isClosingFence(line, fence)) {
98369
+ fence = null;
98370
+ }
98371
+ continue;
98372
+ }
98373
+ const openingFence = parseOpeningFence(line);
98374
+ if (openingFence !== null) {
98375
+ fence = openingFence;
98376
+ continue;
98377
+ }
98378
+ if (SECTION_BOUNDARY_HEADING_PATTERN.test(line)) {
98379
+ section = parseStructuredSectionHeading(line);
98380
+ continue;
98381
+ }
98382
+ if (section === "other") {
98383
+ continue;
98384
+ }
98385
+ const checkbox = parseStructuredTopLevelCheckbox(line, section);
98386
+ if (checkbox === null) {
98387
+ continue;
98388
+ }
98389
+ total += 1;
98390
+ if (checkbox.checked) {
98391
+ continue;
98392
+ }
98393
+ remaining += 1;
98394
+ if (nextTaskLabel === null) {
98395
+ nextTaskLabel = checkbox.label;
98396
+ nextTask = checkbox.task;
98397
+ }
98398
+ }
98399
+ return {
98400
+ checklist: {
98401
+ completed: total - remaining,
98402
+ remaining,
98403
+ total,
98404
+ nextTaskLabel
98405
+ },
98406
+ nextTask
98407
+ };
98408
+ }
98409
+ function parseSimpleChecklist(lines) {
98410
+ let remaining = 0;
98411
+ let total = 0;
98412
+ let nextTaskLabel = null;
98413
+ let fence = null;
98414
+ for (const line of lines) {
98415
+ if (fence !== null) {
98416
+ if (isClosingFence(line, fence)) {
98417
+ fence = null;
98418
+ }
98419
+ continue;
98420
+ }
98421
+ const openingFence = parseOpeningFence(line);
98422
+ if (openingFence !== null) {
98423
+ fence = openingFence;
98424
+ continue;
98425
+ }
98426
+ const checkbox = parseSimpleTopLevelCheckbox(line);
98427
+ if (checkbox === null) {
98428
+ continue;
98429
+ }
98430
+ total += 1;
98431
+ if (checkbox.checked) {
98432
+ continue;
98433
+ }
98434
+ remaining += 1;
98435
+ if (nextTaskLabel === null) {
98436
+ nextTaskLabel = checkbox.label;
98437
+ }
98438
+ }
98439
+ return { completed: total - remaining, remaining, total, nextTaskLabel };
98440
+ }
98441
+ function parseSimpleTopLevelCheckbox(line) {
98442
+ const match = line.match(SIMPLE_CHECKBOX_PATTERN);
98443
+ const marker = match?.[1];
98444
+ const label = match?.[2];
98445
+ if (marker === undefined || label === undefined) {
98446
+ return null;
98447
+ }
98448
+ return { checked: marker.toLowerCase() === "x", label };
98449
+ }
98450
+ function hasStructuredSection(lines) {
98451
+ let fence = null;
98452
+ for (const line of lines) {
98453
+ if (fence !== null) {
98454
+ if (isClosingFence(line, fence)) {
98455
+ fence = null;
98456
+ }
98457
+ continue;
98458
+ }
98459
+ const openingFence = parseOpeningFence(line);
98460
+ if (openingFence !== null) {
98461
+ fence = openingFence;
98462
+ continue;
98463
+ }
98464
+ if (parseStructuredSectionHeading(line) !== "other") {
98465
+ return true;
98466
+ }
98467
+ }
98468
+ return false;
98469
+ }
98470
+ function parseStructuredSectionHeading(line) {
98471
+ if (TODO_HEADING_PATTERN.test(line)) {
98472
+ return "todo";
98473
+ }
98474
+ if (FINAL_VERIFICATION_HEADING_PATTERN.test(line)) {
98475
+ return "final-wave";
98476
+ }
98477
+ return "other";
98478
+ }
98479
+ function parseStructuredTopLevelCheckbox(line, section) {
98480
+ const pattern = section === "todo" ? TODO_CHECKBOX_PATTERN : FINAL_WAVE_CHECKBOX_PATTERN;
98481
+ const match = line.match(pattern);
98482
+ const marker = match?.[1];
98483
+ const label = match?.[2];
98484
+ if (marker === undefined || label === undefined) {
98485
+ return null;
98486
+ }
98487
+ const task = buildTaskRef(section, label);
98488
+ if (task === null) {
98489
+ return null;
98490
+ }
98491
+ return { checked: marker.toLowerCase() === "x", label, task };
98492
+ }
98493
+ function buildTaskRef(section, label) {
98494
+ const pattern = section === "todo" ? /^([1-9]\d*)\. (.+)$/ : /^(F[1-9]\d*)\. (.+)$/i;
98495
+ const match = label.match(pattern);
98496
+ const rawLabel = match?.[1];
98497
+ const title = match?.[2];
98498
+ if (rawLabel === undefined || title === undefined) {
97933
98499
  return null;
97934
98500
  }
97935
- const rawLabel = match[1];
97936
- const title = match[2].trim();
97937
98501
  return {
97938
98502
  key: `${section}:${rawLabel.toLowerCase()}`,
97939
98503
  section,
@@ -97941,31 +98505,29 @@ function buildTaskRef(section, taskLabel) {
97941
98505
  title
97942
98506
  };
97943
98507
  }
98508
+ function parseOpeningFence(line) {
98509
+ const match = line.match(FENCE_PATTERN);
98510
+ const run = match?.[1];
98511
+ const info = match?.[2];
98512
+ const marker = run?.charAt(0);
98513
+ if (run === undefined || info === undefined || marker !== "`" && marker !== "~" || marker === "`" && info.includes("`")) {
98514
+ return null;
98515
+ }
98516
+ return { marker, length: run.length };
98517
+ }
98518
+ function isClosingFence(line, fence) {
98519
+ const run = line.match(/^[ \t]{0,3}(`{3,}|~{3,})[ \t]*$/)?.[1];
98520
+ return run?.charAt(0) === fence.marker && run.length >= fence.length;
98521
+ }
98522
+ // packages/boulder-state/src/top-level-task.ts
98523
+ import { existsSync as existsSync37, readFileSync as readFileSync19 } from "fs";
97944
98524
  function readCurrentTopLevelTask(planPath) {
97945
98525
  if (!existsSync37(planPath)) {
97946
98526
  return null;
97947
98527
  }
97948
98528
  try {
97949
98529
  const content = readFileSync19(planPath, "utf-8");
97950
- const lines = content.split(/\r?\n/);
97951
- let section = "other";
97952
- for (const line of lines) {
97953
- if (SECOND_LEVEL_HEADING_PATTERN.test(line)) {
97954
- section = TODO_HEADING_PATTERN.test(line) ? "todo" : FINAL_VERIFICATION_HEADING_PATTERN.test(line) ? "final-wave" : "other";
97955
- }
97956
- const uncheckedTaskMatch = line.match(UNCHECKED_CHECKBOX_PATTERN);
97957
- if (!uncheckedTaskMatch || uncheckedTaskMatch[1].length > 0) {
97958
- continue;
97959
- }
97960
- if (section !== "todo" && section !== "final-wave") {
97961
- continue;
97962
- }
97963
- const taskRef = buildTaskRef(section, uncheckedTaskMatch[2].trim());
97964
- if (taskRef) {
97965
- return taskRef;
97966
- }
97967
- }
97968
- return null;
98530
+ return parseCurrentTopLevelTask(content);
97969
98531
  } catch {
97970
98532
  return null;
97971
98533
  }
@@ -97999,69 +98561,25 @@ function resolveBoulderPlanPathForWork(directory, work) {
97999
98561
  }
98000
98562
  // packages/boulder-state/src/storage/plan-progress.ts
98001
98563
  import { existsSync as existsSync39, readFileSync as readFileSync20, readdirSync as readdirSync5, statSync as statSync5 } from "fs";
98002
- var TODO_HEADING_PATTERN2 = /^##\s+TODOs\b/i;
98003
- var FINAL_VERIFICATION_HEADING_PATTERN2 = /^##\s+Final Verification Wave\b/i;
98004
- var SECOND_LEVEL_HEADING_PATTERN2 = /^##\s+/;
98005
- var UNCHECKED_CHECKBOX_PATTERN2 = /^(\s*)[-*]\s*\[\s*\]\s*(.+)$/;
98006
- var CHECKED_CHECKBOX_PATTERN = /^(\s*)[-*]\s*\[[xX]\]\s*(.+)$/;
98007
- var TODO_TASK_PATTERN2 = /^\d+\.\s+/;
98008
- var FINAL_WAVE_TASK_PATTERN2 = /^F\d+\.\s+/i;
98009
98564
  function getPlanProgress(planPath) {
98010
98565
  if (!existsSync39(planPath)) {
98011
98566
  return { total: 0, completed: 0, isComplete: false };
98012
98567
  }
98013
98568
  try {
98014
98569
  const content = readFileSync20(planPath, "utf-8");
98015
- const lines = content.split(/\r?\n/);
98016
- const hasStructuredSections = lines.some((line) => TODO_HEADING_PATTERN2.test(line) || FINAL_VERIFICATION_HEADING_PATTERN2.test(line));
98017
- if (hasStructuredSections) {
98018
- return getStructuredPlanProgress(lines);
98019
- }
98020
- return getSimplePlanProgress(content);
98570
+ const checklist = parsePlanChecklist(content);
98571
+ return {
98572
+ total: checklist.total,
98573
+ completed: checklist.completed,
98574
+ isComplete: checklist.total > 0 && checklist.remaining === 0
98575
+ };
98021
98576
  } catch {
98022
98577
  return { total: 0, completed: 0, isComplete: false };
98023
98578
  }
98024
98579
  }
98025
- function getStructuredPlanProgress(lines) {
98026
- let section = "other";
98027
- let total = 0;
98028
- let completed = 0;
98029
- for (const line of lines) {
98030
- if (SECOND_LEVEL_HEADING_PATTERN2.test(line)) {
98031
- section = TODO_HEADING_PATTERN2.test(line) ? "todo" : FINAL_VERIFICATION_HEADING_PATTERN2.test(line) ? "final-wave" : "other";
98032
- continue;
98033
- }
98034
- if (section !== "todo" && section !== "final-wave") {
98035
- continue;
98036
- }
98037
- const checkedMatch = line.match(CHECKED_CHECKBOX_PATTERN);
98038
- const uncheckedMatch = checkedMatch ? null : line.match(UNCHECKED_CHECKBOX_PATTERN2);
98039
- const match = checkedMatch ?? uncheckedMatch;
98040
- if (!match || match[1].length > 0) {
98041
- continue;
98042
- }
98043
- const taskBody = match[2].trim();
98044
- const labelPattern = section === "todo" ? TODO_TASK_PATTERN2 : FINAL_WAVE_TASK_PATTERN2;
98045
- if (!labelPattern.test(taskBody)) {
98046
- continue;
98047
- }
98048
- total += 1;
98049
- if (checkedMatch) {
98050
- completed += 1;
98051
- }
98052
- }
98053
- return { total, completed, isComplete: total > 0 && completed === total };
98054
- }
98055
- function getSimplePlanProgress(content) {
98056
- const uncheckedMatches = content.match(/^[-*]\s*\[\s*\]/gm) ?? [];
98057
- const checkedMatches = content.match(/^[-*]\s*\[[xX]\]/gm) ?? [];
98058
- const total = uncheckedMatches.length + checkedMatches.length;
98059
- const completed = checkedMatches.length;
98060
- return { total, completed, isComplete: total > 0 && completed === total };
98061
- }
98062
98580
  // packages/boulder-state/src/storage/shared.ts
98063
98581
  var RESERVED_KEYS = new Set(["__proto__", "prototype", "constructor"]);
98064
- var SESSION_ID_PREFIX_PATTERN = /^(codex|opencode):/;
98582
+ var SESSION_ID_PREFIX_PATTERN = /^(codex|opencode|senpi):/;
98065
98583
  function normalizeSessionId(sessionId, platform = "opencode") {
98066
98584
  if (SESSION_ID_PREFIX_PATTERN.test(sessionId)) {
98067
98585
  return sessionId;
@@ -98136,7 +98654,7 @@ function readBoulderState(directory) {
98136
98654
  try {
98137
98655
  const content = readFileSync21(filePath, "utf-8");
98138
98656
  const parsed = JSON.parse(content);
98139
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
98657
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || Object.keys(parsed).length === 0) {
98140
98658
  return null;
98141
98659
  }
98142
98660
  normalizeState(parsed);
@@ -100093,6 +100611,7 @@ import { readFileSync as readFileSync35 } from "fs";
100093
100611
  import { homedir as homedir16 } from "os";
100094
100612
  import { dirname as dirname29, relative as relative9 } from "path";
100095
100613
  init_shared();
100614
+ init_logger2();
100096
100615
  init_plugin_identity();
100097
100616
  function resolveHomeDirectory2() {
100098
100617
  return process.env.HOME ?? process.env.USERPROFILE ?? homedir16();
@@ -100181,13 +100700,45 @@ function mergeLoadedConfig(userLayersNearestFirst, projectLayersNearestFirst) {
100181
100700
  config3 = mergeConfigs2(config3, layer.config);
100182
100701
  }
100183
100702
  const userMcpEnvAllowlist = config3.mcp_env_allowlist ?? [];
100703
+ const userPlaywrightMcpArgs = config3.browser_automation_engine?.playwright_mcp_args;
100184
100704
  for (const layer of [...projectLayersNearestFirst].reverse()) {
100185
100705
  if (layer.config)
100186
100706
  config3 = mergeConfigs2(config3, layer.config);
100187
100707
  }
100188
100708
  config3 = { ...config3, mcp_env_allowlist: userMcpEnvAllowlist };
100709
+ if (config3.browser_automation_engine) {
100710
+ const {
100711
+ playwright_mcp_args: _projectPlaywrightMcpArgs,
100712
+ ...browserAutomationEngine
100713
+ } = config3.browser_automation_engine;
100714
+ config3 = {
100715
+ ...config3,
100716
+ browser_automation_engine: userPlaywrightMcpArgs !== undefined ? { ...browserAutomationEngine, playwright_mcp_args: userPlaywrightMcpArgs } : browserAutomationEngine
100717
+ };
100718
+ }
100189
100719
  return applyDisabledProviders(config3);
100190
100720
  }
100721
+ function migrateRalphLoopConfig(config3) {
100722
+ const legacy = config3.ralph_loop;
100723
+ if (legacy === undefined) {
100724
+ return config3;
100725
+ }
100726
+ const enabled = typeof legacy.enabled === "boolean" ? legacy.enabled : undefined;
100727
+ const defaultMaxIterations = typeof legacy.default_max_iterations === "number" ? legacy.default_max_iterations : undefined;
100728
+ if (enabled === undefined && defaultMaxIterations === undefined) {
100729
+ return config3;
100730
+ }
100731
+ log2("[config] ralph_loop is deprecated and will be removed in a future release. Use goal instead.");
100732
+ const existingGoal = config3.goal;
100733
+ return {
100734
+ ...config3,
100735
+ goal: {
100736
+ enabled: existingGoal?.enabled ?? enabled ?? false,
100737
+ auto_start: existingGoal?.auto_start ?? false,
100738
+ default_max_iterations: existingGoal?.default_max_iterations ?? defaultMaxIterations ?? 100
100739
+ }
100740
+ };
100741
+ }
100191
100742
  function validatePluginConfig(directory) {
100192
100743
  const userLayersNearestFirst = discoverUserLayers().map((layer) => parseLayerConfig(layer.path));
100193
100744
  const projectLayersNearestFirst = discoverProjectLayersNearestFirst(directory).map((layer) => parseLayerConfig(layer.path));
@@ -100197,7 +100748,7 @@ function validatePluginConfig(directory) {
100197
100748
  valid: messages.length === 0,
100198
100749
  messages,
100199
100750
  path: firstFailingPath(layers) ?? firstPath(layers),
100200
- config: mergeLoadedConfig(userLayersNearestFirst, projectLayersNearestFirst)
100751
+ config: migrateRalphLoopConfig(mergeLoadedConfig(userLayersNearestFirst, projectLayersNearestFirst))
100201
100752
  };
100202
100753
  }
100203
100754