oh-my-opencode 4.9.2 → 4.10.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 (211) hide show
  1. package/.agents/skills/opencode-qa/scripts/lib/common.sh +39 -1
  2. package/.agents/skills/tech-debt-audit/SKILL.md +277 -0
  3. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/execution-plan.md +1 -1
  4. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/execution-plan.md +1 -1
  5. package/bin/platform.js +5 -0
  6. package/bin/platform.test.ts +56 -0
  7. package/dist/agents/atlas/agent.d.ts +4 -3
  8. package/dist/agents/gpt-apply-patch-guard.d.ts +2 -2
  9. package/dist/agents/hephaestus/agent.d.ts +5 -0
  10. package/dist/agents/hephaestus/index.d.ts +1 -1
  11. package/dist/agents/metis.d.ts +1 -0
  12. package/dist/agents/prometheus/system-prompt.d.ts +1 -1
  13. package/dist/agents/sisyphus/kimi-k2-7.d.ts +17 -0
  14. package/dist/agents/sisyphus-junior/agent.d.ts +1 -1
  15. package/dist/agents/sisyphus-junior/kimi-k2-7.d.ts +11 -0
  16. package/dist/agents/types.d.ts +2 -2
  17. package/dist/cli/doctor/checks/codex-components.d.ts +13 -0
  18. package/dist/cli/doctor/checks/tui-plugin-config.d.ts +1 -0
  19. package/dist/cli/doctor/constants.d.ts +1 -1
  20. package/dist/cli/index.js +929 -291
  21. package/dist/cli/install-codex/codex-cleanup.d.ts +4 -0
  22. package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +34 -0
  23. package/dist/cli/install-codex/link-cached-plugin-agents.d.ts +4 -0
  24. package/dist/cli/model-fallback.d.ts +1 -0
  25. package/dist/cli/provider-availability.d.ts +2 -0
  26. package/dist/cli-node/index.js +929 -291
  27. package/dist/config/schema/agent-overrides.d.ts +80 -16
  28. package/dist/config/schema/experimental.d.ts +0 -1
  29. package/dist/config/schema/hooks.d.ts +0 -1
  30. package/dist/config/schema/internal/permission.d.ts +5 -1
  31. package/dist/config/schema/oh-my-opencode-config.d.ts +75 -16
  32. package/dist/create-hooks.d.ts +0 -1
  33. package/dist/features/background-agent/index.d.ts +1 -1
  34. package/dist/features/background-agent/manager.d.ts +6 -0
  35. package/dist/features/background-agent/types.d.ts +2 -0
  36. package/dist/features/claude-code-plugin-loader/types.d.ts +3 -0
  37. package/dist/features/claude-code-session-state/state.d.ts +1 -0
  38. package/dist/features/skill-mcp-manager/manager.d.ts +11 -7
  39. package/dist/features/team-mode/team-mailbox/pending-delivery-recovery.d.ts +31 -0
  40. package/dist/features/team-mode/team-runtime/delete-team.d.ts +2 -1
  41. package/dist/features/team-mode/tools/lifecycle-inline-spec.d.ts +2 -2
  42. package/dist/features/tmux-subagent/stale-tmux-resource-sweeper.d.ts +12 -0
  43. package/dist/features/tool-metadata-store/store.d.ts +5 -0
  44. package/dist/hooks/anthropic-context-window-limit-recovery/storage/constants.d.ts +3 -0
  45. package/dist/hooks/{session-recovery → anthropic-context-window-limit-recovery}/storage/messages-reader.d.ts +1 -1
  46. package/dist/hooks/{session-recovery → anthropic-context-window-limit-recovery}/storage/part-content.d.ts +1 -1
  47. package/dist/hooks/{session-recovery → anthropic-context-window-limit-recovery}/storage/parts-reader.d.ts +1 -1
  48. package/dist/hooks/{session-recovery → anthropic-context-window-limit-recovery/storage}/types.d.ts +0 -13
  49. package/dist/hooks/auto-update-checker/checker/bundled-version.d.ts +1 -0
  50. package/dist/hooks/auto-update-checker/checker.d.ts +1 -0
  51. package/dist/hooks/auto-update-checker/constants.d.ts +3 -3
  52. package/dist/hooks/auto-update-checker/hook.d.ts +2 -1
  53. package/dist/hooks/claude-code-hooks/types.d.ts +4 -0
  54. package/dist/hooks/index.d.ts +0 -1
  55. package/dist/hooks/team-session-events/team-idle-wake-hint.d.ts +5 -0
  56. package/dist/index.js +2991 -2367
  57. package/dist/oh-my-opencode.schema.json +120 -18
  58. package/dist/plugin/build-team-idle-wake-hint-client.d.ts +2 -0
  59. package/dist/plugin/event-session-lifecycle.d.ts +0 -3
  60. package/dist/plugin/hooks/create-continuation-hooks.d.ts +0 -6
  61. package/dist/plugin/hooks/create-core-hooks.d.ts +0 -1
  62. package/dist/plugin/hooks/create-session-hooks.d.ts +1 -2
  63. package/dist/shared/command-executor/execute-hook-command.d.ts +7 -0
  64. package/dist/shared/plugin-identity.d.ts +2 -2
  65. package/dist/shared/tmux/tmux-utils/server-health.d.ts +2 -1
  66. package/dist/shared/tmux/tmux-utils/stale-attach-pane-sweep.d.ts +16 -0
  67. package/dist/shared/tmux/tmux-utils.d.ts +1 -0
  68. package/dist/tools/background-task/clients.d.ts +2 -0
  69. package/dist/tools/background-task/full-session-format.d.ts +1 -0
  70. package/dist/tools/background-task/types.d.ts +1 -0
  71. package/dist/tools/delegate-task/sync-prompt-sender.d.ts +1 -1
  72. package/dist/tools/delegate-task/sync-session-lifecycle.d.ts +2 -1
  73. package/dist/tools/look-at/look-at-input-preparer.d.ts +6 -2
  74. package/dist/tools/look-at/look-at-prompt.d.ts +2 -1
  75. package/dist/tools/look-at/look-at-session-runner.d.ts +3 -4
  76. package/dist/tools/look-at/types.d.ts +2 -0
  77. package/dist/tools/session-manager/types.d.ts +1 -0
  78. package/dist/tools/skill-mcp/types.d.ts +1 -0
  79. package/package.json +14 -13
  80. package/packages/ast-grep-mcp/dist/cli.js +50 -17
  81. package/packages/lsp-daemon/dist/cli.js +8 -5
  82. package/packages/lsp-daemon/dist/index.js +8 -5
  83. package/packages/lsp-tools-mcp/dist/lsp/connection.js +1 -1
  84. package/packages/lsp-tools-mcp/dist/lsp/server-definitions.js +2 -2
  85. package/packages/lsp-tools-mcp/dist/lsp/transport.d.ts +10 -1
  86. package/packages/lsp-tools-mcp/dist/lsp/transport.js +6 -3
  87. package/packages/omo-codex/lazycodex-repository/.github/workflows/pr-source-guidance.yml +11 -12
  88. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  89. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +2583 -0
  90. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +17 -0
  91. package/packages/omo-codex/plugin/components/bootstrap/manifests/ast-grep.json +22 -0
  92. package/packages/omo-codex/plugin/components/bootstrap/manifests/node.json +10 -0
  93. package/packages/omo-codex/plugin/components/bootstrap/package.json +20 -0
  94. package/packages/omo-codex/plugin/components/bootstrap/scripts/bootstrap.ps1 +310 -0
  95. package/packages/omo-codex/plugin/components/bootstrap/scripts/build.mjs +35 -0
  96. package/packages/omo-codex/plugin/components/bootstrap/scripts/generate-manifests.mjs +115 -0
  97. package/packages/omo-codex/plugin/components/bootstrap/src/cli.ts +153 -0
  98. package/packages/omo-codex/plugin/components/bootstrap/src/download.ts +212 -0
  99. package/packages/omo-codex/plugin/components/bootstrap/src/environment.ts +286 -0
  100. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +108 -0
  101. package/packages/omo-codex/plugin/components/bootstrap/src/provision.ts +243 -0
  102. package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +294 -0
  103. package/packages/omo-codex/plugin/components/bootstrap/src/worker.ts +279 -0
  104. package/packages/omo-codex/plugin/components/bootstrap/test/download.test.ts +295 -0
  105. package/packages/omo-codex/plugin/components/bootstrap/test/environment.test.ts +375 -0
  106. package/packages/omo-codex/plugin/components/bootstrap/test/provision.test.ts +464 -0
  107. package/packages/omo-codex/plugin/components/bootstrap/tsconfig.json +25 -0
  108. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  109. package/packages/omo-codex/plugin/components/comment-checker/package.json +4 -4
  110. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  111. package/packages/omo-codex/plugin/components/git-bash/package.json +2 -2
  112. package/packages/omo-codex/plugin/components/lsp/dist/codex-hook-cli.js +6 -10
  113. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  114. package/packages/omo-codex/plugin/components/lsp/package.json +4 -4
  115. package/packages/omo-codex/plugin/components/lsp/scripts/build-lsp-tools.test.mjs +8 -3
  116. package/packages/omo-codex/plugin/components/lsp/src/codex-hook-cli.ts +5 -8
  117. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-cli.test.ts +24 -1
  118. package/packages/omo-codex/plugin/components/rules/bundled-rules/windows-git-bash.md +3 -1
  119. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  120. package/packages/omo-codex/plugin/components/rules/package.json +4 -4
  121. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +35 -1
  122. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  123. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +4 -4
  124. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  125. package/packages/omo-codex/plugin/components/telemetry/package.json +4 -4
  126. package/packages/omo-codex/plugin/components/ultrawork/biome.json +1 -1
  127. package/packages/omo-codex/plugin/components/ultrawork/directive.md +155 -99
  128. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  129. package/packages/omo-codex/plugin/components/ultrawork/package.json +4 -4
  130. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +19 -51
  131. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +46 -51
  132. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +19 -0
  133. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +0 -1
  134. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +9 -1
  135. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +1 -0
  136. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +18 -0
  137. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +1 -3
  138. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +2 -2
  139. package/packages/omo-codex/plugin/components/ulw-loop/package.json +4 -4
  140. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +6 -2
  141. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +19 -0
  142. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +1 -1
  143. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-commands.test.ts +6 -0
  144. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-complete-goals.test.ts +26 -1
  145. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-json-errors.test.ts +89 -0
  146. package/packages/omo-codex/plugin/hooks/hooks.json +27 -16
  147. package/packages/omo-codex/plugin/package-lock.json +193 -193
  148. package/packages/omo-codex/plugin/package.json +1 -1
  149. package/packages/omo-codex/plugin/scripts/auto-update-state.d.mts +20 -0
  150. package/packages/omo-codex/plugin/scripts/auto-update.mjs +28 -8
  151. package/packages/omo-codex/plugin/scripts/build-components.mjs +36 -5
  152. package/packages/omo-codex/plugin/scripts/install-flow.mjs +43 -0
  153. package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/SKILL.md +79 -28
  154. package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/agents/openai.yaml +2 -2
  155. package/packages/omo-codex/plugin/skills/lcx-report-bug/SKILL.md +7 -6
  156. package/packages/omo-codex/plugin/skills/lcx-report-bug/agents/openai.yaml +1 -1
  157. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +19 -51
  158. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +46 -51
  159. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -0
  160. package/packages/omo-codex/plugin/test/auto-update.test.mjs +145 -0
  161. package/packages/omo-codex/plugin/test/bootstrap-binlinks.test.mjs +250 -0
  162. package/packages/omo-codex/plugin/test/bootstrap-hooks.test.mjs +166 -0
  163. package/packages/omo-codex/plugin/test/bootstrap-orchestration.test.mjs +371 -0
  164. package/packages/omo-codex/plugin/test/bootstrap-ps-guard.test.mjs +134 -0
  165. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +249 -0
  166. package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +10 -1
  167. package/packages/omo-codex/plugin/test/ulw-plan-skill.test.mjs +46 -0
  168. package/packages/omo-codex/scripts/atomic-write.test.mjs +82 -0
  169. package/packages/omo-codex/scripts/install/agents.d.mts +18 -0
  170. package/packages/omo-codex/scripts/install/agents.mjs +78 -5
  171. package/packages/omo-codex/scripts/install/atomic-write.mjs +59 -0
  172. package/packages/omo-codex/scripts/install/bin-dir.d.mts +7 -0
  173. package/packages/omo-codex/scripts/install/bin-links.d.mts +18 -0
  174. package/packages/omo-codex/scripts/install/config.d.mts +35 -0
  175. package/packages/omo-codex/scripts/install/config.mjs +13 -3
  176. package/packages/omo-codex/scripts/install/git-bash-mcp-env.d.mts +5 -0
  177. package/packages/omo-codex/scripts/install/git-bash.d.mts +23 -0
  178. package/packages/omo-codex/scripts/install/hook-trust.d.mts +10 -0
  179. package/packages/omo-codex/scripts/install-agent-links.test.mjs +41 -0
  180. package/packages/omo-codex/scripts/install-local.mjs +3 -2
  181. package/packages/shared-skills/skills/lcx-contribute-bug-fix/SKILL.md +79 -28
  182. package/packages/shared-skills/skills/lcx-contribute-bug-fix/agents/openai.yaml +2 -2
  183. package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +7 -6
  184. package/packages/shared-skills/skills/lcx-report-bug/agents/openai.yaml +1 -1
  185. package/dist/hooks/session-recovery/constants.d.ts +0 -4
  186. package/dist/hooks/session-recovery/detect-error-type.d.ts +0 -4
  187. package/dist/hooks/session-recovery/error-recovery.d.ts +0 -4
  188. package/dist/hooks/session-recovery/hook-types.d.ts +0 -22
  189. package/dist/hooks/session-recovery/hook.d.ts +0 -4
  190. package/dist/hooks/session-recovery/index.d.ts +0 -5
  191. package/dist/hooks/session-recovery/interrupted-idle-message-fetch-timeout.d.ts +0 -7
  192. package/dist/hooks/session-recovery/interrupted-tool-results.d.ts +0 -3
  193. package/dist/hooks/session-recovery/message-state.d.ts +0 -4
  194. package/dist/hooks/session-recovery/recover-thinking-block-order.d.ts +0 -5
  195. package/dist/hooks/session-recovery/recover-thinking-disabled-violation.d.ts +0 -5
  196. package/dist/hooks/session-recovery/recover-tool-result-missing.d.ts +0 -10
  197. package/dist/hooks/session-recovery/recover-unavailable-tool.d.ts +0 -5
  198. package/dist/hooks/session-recovery/resume.d.ts +0 -7
  199. package/dist/hooks/session-recovery/storage/latest-assistant-message.d.ts +0 -5
  200. package/dist/hooks/session-recovery/storage/orphan-thinking-search.d.ts +0 -2
  201. package/dist/hooks/session-recovery/storage/thinking-block-search.d.ts +0 -2
  202. package/dist/hooks/session-recovery/storage/thinking-prepend.d.ts +0 -33
  203. package/dist/hooks/session-recovery/storage/thinking-strip.d.ts +0 -11
  204. package/dist/hooks/session-recovery/storage.d.ts +0 -20
  205. package/dist/plugin/event-session-recovery.d.ts +0 -9
  206. package/dist/plugin/user-abort-interrupted-recovery-guard.d.ts +0 -6
  207. /package/dist/hooks/{session-recovery → anthropic-context-window-limit-recovery}/storage/empty-messages.d.ts +0 -0
  208. /package/dist/hooks/{session-recovery → anthropic-context-window-limit-recovery}/storage/empty-text.d.ts +0 -0
  209. /package/dist/hooks/{session-recovery → anthropic-context-window-limit-recovery}/storage/message-dir.d.ts +0 -0
  210. /package/dist/hooks/{session-recovery → anthropic-context-window-limit-recovery}/storage/part-id.d.ts +0 -0
  211. /package/dist/hooks/{session-recovery → anthropic-context-window-limit-recovery}/storage/text-part-injector.d.ts +0 -0
package/dist/cli/index.js CHANGED
@@ -2140,6 +2140,186 @@ var require_commander = __commonJS((exports) => {
2140
2140
  exports.InvalidOptionArgumentError = InvalidArgumentError;
2141
2141
  });
2142
2142
 
2143
+ // package.json
2144
+ var package_default;
2145
+ var init_package = __esm(() => {
2146
+ package_default = {
2147
+ name: "oh-my-opencode",
2148
+ version: "4.10.0",
2149
+ description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
2150
+ main: "./dist/index.js",
2151
+ types: "dist/index.d.ts",
2152
+ type: "module",
2153
+ workspaces: [
2154
+ "packages/rules-engine",
2155
+ "packages/ast-grep-core",
2156
+ "packages/ast-grep-mcp",
2157
+ "packages/git-bash-mcp",
2158
+ "packages/utils",
2159
+ "packages/model-core",
2160
+ "packages/prompts-core",
2161
+ "packages/comment-checker-core",
2162
+ "packages/hashline-core",
2163
+ "packages/boulder-state",
2164
+ "packages/agents-md-core",
2165
+ "packages/shared-skills",
2166
+ "packages/omo-codex",
2167
+ "packages/omo-opencode"
2168
+ ],
2169
+ bin: {
2170
+ "oh-my-opencode": "bin/oh-my-opencode.js",
2171
+ "oh-my-openagent": "bin/oh-my-opencode.js",
2172
+ omo: "bin/oh-my-opencode.js",
2173
+ lazycodex: "bin/oh-my-opencode.js",
2174
+ "lazycodex-ai": "bin/oh-my-opencode.js"
2175
+ },
2176
+ files: [
2177
+ "dist",
2178
+ "bin",
2179
+ "postinstall.mjs",
2180
+ ".opencode/command",
2181
+ ".opencode/skills",
2182
+ ".agents/command",
2183
+ ".agents/skills",
2184
+ "packages/lsp-tools-mcp/package.json",
2185
+ "packages/lsp-tools-mcp/dist",
2186
+ "packages/lsp-daemon/package.json",
2187
+ "packages/lsp-daemon/dist",
2188
+ "packages/ast-grep-mcp/dist",
2189
+ "packages/git-bash-mcp/dist",
2190
+ "packages/shared-skills/package.json",
2191
+ "packages/shared-skills/index.mjs",
2192
+ "packages/shared-skills/skills",
2193
+ "packages/omo-codex/marketplace.json",
2194
+ "packages/omo-codex/lazycodex-repository",
2195
+ "packages/omo-codex/plugin",
2196
+ "packages/omo-codex/plugin/.codex-plugin",
2197
+ "!packages/omo-codex/plugin/node_modules",
2198
+ "!packages/omo-codex/plugin/**/node_modules",
2199
+ "packages/omo-codex/scripts"
2200
+ ],
2201
+ exports: {
2202
+ ".": {
2203
+ types: "./dist/index.d.ts",
2204
+ import: "./dist/index.js"
2205
+ },
2206
+ "./server": "./dist/index.js",
2207
+ "./schema.json": "./dist/oh-my-opencode.schema.json"
2208
+ },
2209
+ scripts: {
2210
+ build: "bun run build:ast-grep-mcp && bun run build:git-bash-mcp && bun build packages/omo-opencode/src/index.ts --outdir dist --target bun --format esm --external @ast-grep/napi --external zod && bun run build:node-require-shim && tsc --emitDeclarationOnly && bun build packages/omo-opencode/src/cli/index.ts --outdir dist/cli --target bun --format esm --external @ast-grep/napi && bun run build:cli-node && bun run build:schema",
2211
+ "build:cli-node": "bun run script/build-cli-node.ts",
2212
+ "build:lsp-tools-mcp": "npm --prefix packages/lsp-tools-mcp ci && npm --prefix packages/lsp-tools-mcp run build",
2213
+ "build:lsp-daemon": "npm --prefix packages/lsp-daemon ci && npm --prefix packages/lsp-daemon run build",
2214
+ "build:node-require-shim": "bun run script/patch-node-require-shim.ts",
2215
+ "build:all": "bun run build && bun run build:binaries",
2216
+ "build:binaries": "bun run script/build-binaries.ts",
2217
+ "build:schema": "bun run script/build-schema.ts",
2218
+ "build:model-capabilities": "bun run script/build-model-capabilities.ts",
2219
+ clean: "rm -rf dist",
2220
+ prepare: "bun run build",
2221
+ postinstall: "node postinstall.mjs",
2222
+ prepublishOnly: "bun run clean && bun run build:lsp-tools-mcp && bun run build:lsp-daemon && bun run build",
2223
+ "test:model-capabilities": "bun test packages/model-core/src/model-capability-aliases.test.ts packages/model-core/src/model-capability-guardrails.test.ts packages/model-core/src/model-capabilities.test.ts packages/omo-opencode/src/cli/doctor/checks/model-resolution.test.ts --bail",
2224
+ typecheck: "tsgo --noEmit && bun run typecheck:script && bun run typecheck:packages",
2225
+ "typecheck:packages": "tsgo --noEmit -p packages/rules-engine/tsconfig.json && tsgo --noEmit -p packages/ast-grep-core/tsconfig.json && tsgo --noEmit -p packages/ast-grep-mcp/tsconfig.json && tsgo --noEmit -p packages/git-bash-mcp/tsconfig.json && tsgo --noEmit -p packages/utils/tsconfig.json && tsgo --noEmit -p packages/model-core/tsconfig.json && tsgo --noEmit -p packages/prompts-core/tsconfig.json && tsgo --noEmit -p packages/comment-checker-core/tsconfig.json && tsgo --noEmit -p packages/hashline-core/tsconfig.json && tsgo --noEmit -p packages/boulder-state/tsconfig.json && tsgo --noEmit -p packages/agents-md-core/tsconfig.json && tsgo --noEmit -p packages/omo-codex/tsconfig.json && tsgo --noEmit -p packages/omo-opencode/tsconfig.json",
2226
+ "typecheck:script": "tsgo --noEmit -p script/tsconfig.json",
2227
+ test: "bun test",
2228
+ "test:codex": "bun run build:ast-grep-mcp && bun run build:git-bash-mcp && bun run build:lsp-tools-mcp && npm --prefix packages/lsp-tools-mcp test && npm --prefix packages/omo-codex/plugin ci && bun run --cwd packages/omo-codex/plugin build && bun test packages/omo-opencode/src/cli/cli-installer.platform.test.ts packages/omo-opencode/src/cli/install-codex/codex-cache.test.ts packages/omo-opencode/src/cli/install-codex/codex-cleanup.test.ts packages/omo-opencode/src/cli/install-codex/codex-config-agent-cleanup.test.ts packages/omo-opencode/src/cli/install-codex/codex-config-autonomous-features.test.ts packages/omo-opencode/src/cli/install-codex/codex-config-reasoning.test.ts packages/omo-opencode/src/cli/install-codex/codex-config-toml.test.ts packages/omo-opencode/src/cli/install-codex/codex-project-local-cleanup.test.ts packages/omo-opencode/src/cli/install-codex/install-codex-project-local-cleanup.test.ts packages/omo-opencode/src/cli/install-codex/install-codex.test.ts packages/omo-opencode/src/cli/install-codex/install-codex-packaged.test.ts packages/omo-opencode/src/cli/install-codex/link-cached-plugin-agents.test.ts packages/omo-codex/src/**/*.test.ts packages/utils/src/jsonc-parser.test.ts packages/utils/src/frontmatter.test.ts packages/hashline-core/src/hash-computation.test.ts packages/hashline-core/src/smoke-untested-modules.test.ts packages/rules-engine/src/index.test.ts packages/rules-engine/src/security-boundary.test.ts packages/agents-md-core/src/injector.test.ts packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts && node --test packages/omo-codex/plugin/test/*.test.mjs packages/omo-codex/scripts/install-cache-copy.test.mjs packages/omo-codex/scripts/install-cli-args.test.mjs packages/omo-codex/scripts/install-delegated-command.test.mjs packages/omo-codex/scripts/install-config-autonomous-features.test.mjs packages/omo-codex/scripts/install-config-autonomous.test.mjs packages/omo-codex/scripts/install-config-reasoning.test.mjs packages/omo-codex/scripts/install-config.test.mjs packages/omo-codex/scripts/install-hook-targets.test.mjs packages/omo-codex/scripts/install-project-local-cleanup.test.mjs packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs packages/omo-codex/scripts/install-local-entrypoint.test.mjs packages/omo-codex/scripts/install-local-git-bash-preflight.test.mjs packages/omo-codex/scripts/install-local.test.mjs packages/omo-codex/scripts/install-marketplace-cache.test.mjs packages/omo-codex/scripts/install-mcp-runtime.test.mjs packages/omo-codex/scripts/install-packaged-local.test.mjs packages/omo-codex/scripts/install/git-bash.test.mjs packages/omo-codex/scripts/install-agent-links.test.mjs packages/omo-codex/scripts/install-bin-links.test.mjs packages/omo-codex/scripts/sync-telemetry-component.test.mjs",
2229
+ "test:windows-codex": "bun run test:codex",
2230
+ "build:ast-grep-mcp": "bun run --cwd packages/ast-grep-mcp build",
2231
+ "build:git-bash-mcp": "bun run --cwd packages/git-bash-mcp build"
2232
+ },
2233
+ keywords: [
2234
+ "opencode",
2235
+ "plugin",
2236
+ "oracle",
2237
+ "librarian",
2238
+ "agents",
2239
+ "ai",
2240
+ "llm"
2241
+ ],
2242
+ author: "YeonGyu-Kim",
2243
+ license: "SUL-1.0",
2244
+ repository: {
2245
+ type: "git",
2246
+ url: "git+https://github.com/code-yeongyu/oh-my-openagent.git"
2247
+ },
2248
+ bugs: {
2249
+ url: "https://github.com/code-yeongyu/oh-my-openagent/issues"
2250
+ },
2251
+ homepage: "https://github.com/code-yeongyu/oh-my-openagent#readme",
2252
+ dependencies: {
2253
+ "@ast-grep/cli": "^0.42.2",
2254
+ "@ast-grep/napi": "^0.42.2",
2255
+ "@clack/prompts": "^1.4.0",
2256
+ "@code-yeongyu/comment-checker": "^0.8.0",
2257
+ "@modelcontextprotocol/sdk": "^1.29.0",
2258
+ "@opencode-ai/plugin": "^1.15.4",
2259
+ "@opencode-ai/sdk": "^1.15.4",
2260
+ commander: "^14.0.3",
2261
+ "detect-libc": "^2.1.2",
2262
+ diff: "^9.0.0",
2263
+ "js-yaml": "^4.1.1",
2264
+ "jsonc-parser": "^3.3.1",
2265
+ picocolors: "^1.1.1",
2266
+ picomatch: "^4.0.4",
2267
+ "posthog-node": "^5.34.3",
2268
+ "vscode-jsonrpc": "^8.2.1"
2269
+ },
2270
+ devDependencies: {
2271
+ "@oh-my-opencode/ast-grep-core": "workspace:*",
2272
+ "@oh-my-opencode/ast-grep-mcp": "workspace:*",
2273
+ "@oh-my-opencode/git-bash-mcp": "workspace:*",
2274
+ "@oh-my-opencode/agents-md-core": "workspace:*",
2275
+ "@oh-my-opencode/boulder-state": "workspace:*",
2276
+ "@oh-my-opencode/comment-checker-core": "workspace:*",
2277
+ "@oh-my-opencode/hashline-core": "workspace:*",
2278
+ "@oh-my-opencode/model-core": "workspace:*",
2279
+ "@oh-my-opencode/omo-codex": "workspace:*",
2280
+ "@oh-my-opencode/prompts-core": "workspace:*",
2281
+ "@oh-my-opencode/rules-engine": "workspace:*",
2282
+ "@oh-my-opencode/shared-skills": "workspace:*",
2283
+ "@oh-my-opencode/utils": "workspace:*",
2284
+ "@typescript/native-preview": "7.0.0-dev.20260518.1",
2285
+ "@types/js-yaml": "^4.0.9",
2286
+ "@types/picomatch": "^4.0.3",
2287
+ "bun-types": "1.3.14",
2288
+ typescript: "^6.0.3",
2289
+ zod: "^4.4.3"
2290
+ },
2291
+ optionalDependencies: {
2292
+ "oh-my-opencode-darwin-arm64": "4.10.0",
2293
+ "oh-my-opencode-darwin-x64": "4.10.0",
2294
+ "oh-my-opencode-darwin-x64-baseline": "4.10.0",
2295
+ "oh-my-opencode-linux-arm64": "4.10.0",
2296
+ "oh-my-opencode-linux-arm64-musl": "4.10.0",
2297
+ "oh-my-opencode-linux-x64": "4.10.0",
2298
+ "oh-my-opencode-linux-x64-baseline": "4.10.0",
2299
+ "oh-my-opencode-linux-x64-musl": "4.10.0",
2300
+ "oh-my-opencode-linux-x64-musl-baseline": "4.10.0",
2301
+ "oh-my-opencode-windows-arm64": "4.10.0",
2302
+ "oh-my-opencode-windows-x64": "4.10.0",
2303
+ "oh-my-opencode-windows-x64-baseline": "4.10.0"
2304
+ },
2305
+ overrides: {
2306
+ hono: "^4.12.18",
2307
+ "@hono/node-server": "^1.19.13",
2308
+ "express-rate-limit": "^8.5.1",
2309
+ "fast-uri": "^3.1.2",
2310
+ "path-to-regexp": "^8.4.2"
2311
+ },
2312
+ trustedDependencies: [
2313
+ "@ast-grep/cli",
2314
+ "@ast-grep/napi",
2315
+ "@code-yeongyu/comment-checker"
2316
+ ],
2317
+ peerDependencies: {
2318
+ zod: "^4.0.0"
2319
+ }
2320
+ };
2321
+ });
2322
+
2143
2323
  // node_modules/.bun/picocolors@1.1.1/node_modules/picocolors/picocolors.js
2144
2324
  var require_picocolors = __commonJS((exports, module) => {
2145
2325
  var p = process || {};
@@ -6143,10 +6323,10 @@ var init_contains_path2 = __esm(() => {
6143
6323
  });
6144
6324
 
6145
6325
  // packages/omo-opencode/src/shared/plugin-identity.ts
6146
- var PLUGIN_NAME = "oh-my-openagent", LEGACY_PLUGIN_NAME = "oh-my-opencode", PUBLISHED_PACKAGE_NAME, ACCEPTED_PACKAGE_NAMES, CONFIG_BASENAME = "oh-my-openagent", LEGACY_CONFIG_BASENAME = "oh-my-opencode", LOG_FILENAME = "oh-my-opencode.log", CACHE_DIR_NAME = "oh-my-opencode";
6326
+ var PLUGIN_NAME = "oh-my-openagent", LEGACY_PLUGIN_NAME = "oh-my-opencode", ACCEPTED_PACKAGE_NAMES, PUBLISHED_PACKAGE_NAME, CONFIG_BASENAME = "oh-my-openagent", LEGACY_CONFIG_BASENAME = "oh-my-opencode", LOG_FILENAME = "oh-my-opencode.log", CACHE_DIR_NAME = "oh-my-opencode";
6147
6327
  var init_plugin_identity = __esm(() => {
6148
- PUBLISHED_PACKAGE_NAME = LEGACY_PLUGIN_NAME;
6149
- ACCEPTED_PACKAGE_NAMES = [PUBLISHED_PACKAGE_NAME, PLUGIN_NAME];
6328
+ ACCEPTED_PACKAGE_NAMES = [PLUGIN_NAME, LEGACY_PLUGIN_NAME];
6329
+ PUBLISHED_PACKAGE_NAME = PLUGIN_NAME;
6150
6330
  });
6151
6331
 
6152
6332
  // packages/omo-opencode/src/shared/logger.ts
@@ -6270,7 +6450,8 @@ var init_agent_model_requirements = __esm(() => {
6270
6450
  variant: "medium"
6271
6451
  }
6272
6452
  ],
6273
- requiresProvider: ["openai", "github-copilot", "venice", "opencode", "vercel"]
6453
+ requiresProvider: ["openai", "github-copilot", "venice", "opencode", "vercel"],
6454
+ requiresAnyModel: true
6274
6455
  },
6275
6456
  oracle: {
6276
6457
  fallbackChain: [
@@ -6300,7 +6481,7 @@ var init_agent_model_requirements = __esm(() => {
6300
6481
  { providers: ["opencode-go", "vercel"], model: "minimax-m3" },
6301
6482
  { providers: ["minimax-coding-plan", "minimax-cn-coding-plan"], model: "MiniMax-M3" },
6302
6483
  { providers: ["opencode-go", "vercel"], model: "minimax-m2.7" },
6303
- { providers: ["anthropic", "vercel"], model: "claude-haiku-4-5" },
6484
+ { providers: ["anthropic", "github-copilot", "vercel"], model: "claude-haiku-4-5" },
6304
6485
  { providers: ["openai", "vercel"], model: "gpt-5.4-nano" }
6305
6486
  ]
6306
6487
  },
@@ -6312,7 +6493,7 @@ var init_agent_model_requirements = __esm(() => {
6312
6493
  { providers: ["opencode-go", "vercel"], model: "minimax-m3" },
6313
6494
  { providers: ["minimax-coding-plan", "minimax-cn-coding-plan"], model: "MiniMax-M3" },
6314
6495
  { providers: ["opencode-go", "vercel"], model: "minimax-m2.7" },
6315
- { providers: ["anthropic", "vercel"], model: "claude-haiku-4-5" },
6496
+ { providers: ["anthropic", "github-copilot", "vercel"], model: "claude-haiku-4-5" },
6316
6497
  { providers: ["openai", "vercel"], model: "gpt-5.4-nano" }
6317
6498
  ]
6318
6499
  },
@@ -6767,7 +6948,7 @@ var init_model_capability_heuristics = __esm(() => {
6767
6948
  {
6768
6949
  family: "deepseek",
6769
6950
  includes: ["deepseek"],
6770
- variants: ["low", "medium", "high"],
6951
+ variants: ["low", "medium", "high", "max"],
6771
6952
  reasoningEfforts: ["high", "max"],
6772
6953
  reasoningEffortAliases: {
6773
6954
  low: "high",
@@ -7719,7 +7900,8 @@ var init_hook_names = __esm(() => {
7719
7900
  "empty-message-sanitizer": null,
7720
7901
  "delegate-task-english-directive": null,
7721
7902
  "gpt-permission-continuation": null,
7722
- "thinking-block-validator": null
7903
+ "thinking-block-validator": null,
7904
+ "session-recovery": null
7723
7905
  };
7724
7906
  });
7725
7907
 
@@ -51776,6 +51958,9 @@ var init_session_spawn = __esm(() => {
51776
51958
  // packages/omo-opencode/src/shared/tmux/tmux-utils/stale-session-sweep.ts
51777
51959
  var init_stale_session_sweep = () => {};
51778
51960
 
51961
+ // packages/omo-opencode/src/shared/tmux/tmux-utils/stale-attach-pane-sweep.ts
51962
+ var init_stale_attach_pane_sweep = () => {};
51963
+
51779
51964
  // packages/omo-opencode/src/shared/tmux/tmux-utils/layout.ts
51780
51965
  var init_layout = __esm(() => {
51781
51966
  init_tmux_path_resolver();
@@ -51791,6 +51976,7 @@ var init_tmux_utils = __esm(() => {
51791
51976
  init_window_spawn();
51792
51977
  init_session_spawn();
51793
51978
  init_stale_session_sweep();
51979
+ init_stale_attach_pane_sweep();
51794
51980
  init_pane_command();
51795
51981
  init_layout();
51796
51982
  });
@@ -53815,11 +54001,12 @@ var init_dist = __esm(() => {
53815
54001
  function getSessionAgent(sessionID) {
53816
54002
  return sessionAgentMap.get(sessionID);
53817
54003
  }
53818
- var subagentSessions, syncSubagentSessions, registeredAgentNames, registeredAgentAliases, sessionAgentMap;
54004
+ var subagentSessions, syncSubagentSessions, handedBackSyncSessions, registeredAgentNames, registeredAgentAliases, sessionAgentMap;
53819
54005
  var init_state = __esm(() => {
53820
54006
  init_agent_display_names();
53821
54007
  subagentSessions = new Set;
53822
54008
  syncSubagentSessions = new Set;
54009
+ handedBackSyncSessions = new Set;
53823
54010
  registeredAgentNames = new Set;
53824
54011
  registeredAgentAliases = new Map;
53825
54012
  sessionAgentMap = new Map;
@@ -56187,6 +56374,16 @@ function isProviderAvailable(provider, availability) {
56187
56374
  };
56188
56375
  return mapping[provider] ?? false;
56189
56376
  }
56377
+ function hasAnyConfiguredProvider(config) {
56378
+ const availability = toProviderAvailability(config);
56379
+ return availability.native.claude || availability.native.openai || availability.native.gemini || availability.copilot || availability.opencodeZen || availability.zai || availability.kimiForCoding || availability.opencodeGo || availability.bailianCodingPlan || availability.minimaxCnCodingPlan || availability.minimaxCodingPlan || availability.vercelAiGateway;
56380
+ }
56381
+ function getNoModelProvidersWarning() {
56382
+ return `No model providers configured. Using ${ULTIMATE_FALLBACK} as fallback.`;
56383
+ }
56384
+ var init_provider_availability = __esm(() => {
56385
+ init_model_fallback();
56386
+ });
56190
56387
 
56191
56388
  // packages/omo-opencode/src/cli/provider-model-id-transform.ts
56192
56389
  var init_provider_model_id_transform2 = __esm(() => {
@@ -56225,6 +56422,7 @@ function isRequiredProviderAvailable(requiredProviders, availability) {
56225
56422
  }
56226
56423
  var init_fallback_chain_resolution = __esm(() => {
56227
56424
  init_model_fallback_requirements();
56425
+ init_provider_availability();
56228
56426
  init_provider_model_id_transform2();
56229
56427
  });
56230
56428
 
@@ -56409,6 +56607,7 @@ var init_model_fallback = __esm(() => {
56409
56607
  init_model_fallback_requirements();
56410
56608
  init_src2();
56411
56609
  init_openai_only_model_catalog();
56610
+ init_provider_availability();
56412
56611
  init_fallback_chain_resolution();
56413
56612
  init_provider_model_id_transform2();
56414
56613
  });
@@ -62410,10 +62609,10 @@ var init_index_node = __esm(() => {
62410
62609
 
62411
62610
  // packages/omo-codex/package.json
62412
62611
  var package_default2;
62413
- var init_package = __esm(() => {
62612
+ var init_package2 = __esm(() => {
62414
62613
  package_default2 = {
62415
62614
  name: "@oh-my-opencode/omo-codex",
62416
- version: "4.9.2",
62615
+ version: "4.10.0",
62417
62616
  type: "module",
62418
62617
  private: true,
62419
62618
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -62467,7 +62666,7 @@ var init_atomic_write = () => {};
62467
62666
  // packages/omo-codex/src/telemetry/product-identity.ts
62468
62667
  var PRODUCT_NAME = "omo-codex", PACKAGE_NAME2 = "@oh-my-opencode/omo-codex", CACHE_DIR_NAME2 = "omo-codex", EVENT_NAME = "omo_codex_daily_active", DEFAULT_POSTHOG_HOST = "https://us.i.posthog.com", DEFAULT_POSTHOG_API_KEY = "phc_CFJhj5HyvA62QPhvyaUCtaq23aUfznnijg5VaaGkNk74";
62469
62668
  var init_product_identity = __esm(() => {
62470
- init_package();
62669
+ init_package2();
62471
62670
  });
62472
62671
 
62473
62672
  // packages/omo-codex/src/telemetry/data-path.ts
@@ -62861,7 +63060,7 @@ function __resetActivityStateProviderForTesting() {
62861
63060
  var osProviderOverride2 = null, activityStateProviderOverride = null, NO_OP_POSTHOG;
62862
63061
  var init_posthog = __esm(() => {
62863
63062
  init_index_node();
62864
- init_package();
63063
+ init_package2();
62865
63064
  init_diagnostics();
62866
63065
  init_env_flags();
62867
63066
  init_posthog_activity_state();
@@ -63223,6 +63422,14 @@ var init_cached_version = __esm(() => {
63223
63422
  init_package_json_locator();
63224
63423
  });
63225
63424
 
63425
+ // packages/omo-opencode/src/hooks/auto-update-checker/checker/bundled-version.ts
63426
+ function getBundledVersion() {
63427
+ return package_default.version;
63428
+ }
63429
+ var init_bundled_version = __esm(() => {
63430
+ init_package();
63431
+ });
63432
+
63226
63433
  // packages/omo-opencode/src/hooks/auto-update-checker/checker/pinned-version-updater.ts
63227
63434
  var init_pinned_version_updater = __esm(() => {
63228
63435
  init_logger();
@@ -63370,6 +63577,9 @@ function getIntentVersion(pluginInfo) {
63370
63577
  }
63371
63578
  return pluginInfo.pinnedVersion;
63372
63579
  }
63580
+ function getPackageNameFromIntent(pluginInfo) {
63581
+ return ACCEPTED_PACKAGE_NAMES2.find((packageName) => pluginInfo.entry === packageName || pluginInfo.entry.startsWith(`${packageName}@`)) ?? PACKAGE_NAME3;
63582
+ }
63373
63583
  function writeCachePackageJson(cachePackageJsonPath, pkgJson) {
63374
63584
  const tmpPath = `${cachePackageJsonPath}.${crypto.randomUUID()}`;
63375
63585
  try {
@@ -63390,10 +63600,11 @@ function writeCachePackageJson(cachePackageJsonPath, pkgJson) {
63390
63600
  function syncCachePackageJsonToIntent(pluginInfo) {
63391
63601
  const cachePackageJsonPath = path12.join(CACHE_DIR, "package.json");
63392
63602
  const intentVersion = getIntentVersion(pluginInfo);
63603
+ const packageName = getPackageNameFromIntent(pluginInfo);
63393
63604
  if (!fs11.existsSync(cachePackageJsonPath)) {
63394
63605
  log("[auto-update-checker] Cache package.json missing, creating workspace package.json", { intentVersion });
63395
63606
  return {
63396
- ...writeCachePackageJson(cachePackageJsonPath, { dependencies: { [PACKAGE_NAME3]: intentVersion } }),
63607
+ ...writeCachePackageJson(cachePackageJsonPath, { dependencies: { [packageName]: intentVersion } }),
63397
63608
  message: `Created cache package.json with: ${intentVersion}`
63398
63609
  };
63399
63610
  }
@@ -63419,21 +63630,21 @@ function syncCachePackageJsonToIntent(pluginInfo) {
63419
63630
  }
63420
63631
  return { synced: false, error: "parse_error", message: "Failed to parse cache package.json (malformed JSON)" };
63421
63632
  }
63422
- if (!pkgJson || !pkgJson.dependencies?.[PACKAGE_NAME3]) {
63633
+ if (!pkgJson || !pkgJson.dependencies?.[packageName]) {
63423
63634
  log("[auto-update-checker] Plugin missing from cache package.json dependencies, adding dependency", { intentVersion });
63424
63635
  const nextPkgJson = {
63425
63636
  ...pkgJson ?? {},
63426
63637
  dependencies: {
63427
63638
  ...pkgJson?.dependencies ?? {},
63428
- [PACKAGE_NAME3]: intentVersion
63639
+ [packageName]: intentVersion
63429
63640
  }
63430
63641
  };
63431
63642
  return {
63432
63643
  ...writeCachePackageJson(cachePackageJsonPath, nextPkgJson),
63433
- message: `Added ${PACKAGE_NAME3}: ${intentVersion}`
63644
+ message: `Added ${packageName}: ${intentVersion}`
63434
63645
  };
63435
63646
  }
63436
- const currentVersion = pkgJson.dependencies[PACKAGE_NAME3];
63647
+ const currentVersion = pkgJson.dependencies[packageName];
63437
63648
  if (currentVersion === intentVersion) {
63438
63649
  log("[auto-update-checker] Cache package.json already matches intent:", intentVersion);
63439
63650
  return { synced: false, error: null, message: `Already matches intent: ${intentVersion}` };
@@ -63445,7 +63656,7 @@ function syncCachePackageJsonToIntent(pluginInfo) {
63445
63656
  } else {
63446
63657
  log(`[auto-update-checker] Updating cache package.json: "${currentVersion}" \u2192 "${intentVersion}"`);
63447
63658
  }
63448
- pkgJson.dependencies[PACKAGE_NAME3] = intentVersion;
63659
+ pkgJson.dependencies[packageName] = intentVersion;
63449
63660
  return {
63450
63661
  ...writeCachePackageJson(cachePackageJsonPath, pkgJson),
63451
63662
  message: `Updated: "${currentVersion}" \u2192 "${intentVersion}"`
@@ -63464,6 +63675,7 @@ var init_checker = __esm(() => {
63464
63675
  init_local_dev_version();
63465
63676
  init_plugin_entry();
63466
63677
  init_cached_version();
63678
+ init_bundled_version();
63467
63679
  init_pinned_version_updater();
63468
63680
  init_latest_version();
63469
63681
  init_check_for_update();
@@ -63548,13 +63760,14 @@ function removeSpecifierRootDirs(cacheDir, packageNames) {
63548
63760
  }
63549
63761
  return removed;
63550
63762
  }
63551
- function invalidatePackage(packageName = PACKAGE_NAME3, options = {}) {
63763
+ function invalidatePackage(packageName, options = {}) {
63552
63764
  try {
63553
63765
  const acceptedPackageNames = options.acceptedPackageNames ?? ACCEPTED_PACKAGE_NAMES2;
63554
63766
  const cacheDir = options.cacheDir ?? CACHE_DIR;
63555
63767
  const defaultPackageName = options.defaultPackageName ?? PACKAGE_NAME3;
63556
63768
  const userConfigDir = options.userConfigDir ?? getUserConfigDir();
63557
- const packageNames = getInvalidationPackageNames(packageName, defaultPackageName, acceptedPackageNames);
63769
+ const targetPackageName = packageName ?? defaultPackageName;
63770
+ const packageNames = getInvalidationPackageNames(targetPackageName, defaultPackageName, acceptedPackageNames);
63558
63771
  const pkgDirs = packageNames.flatMap((name) => [
63559
63772
  path13.join(userConfigDir, "node_modules", name),
63560
63773
  path13.join(cacheDir, "node_modules", name)
@@ -63572,7 +63785,7 @@ function invalidatePackage(packageName = PACKAGE_NAME3, options = {}) {
63572
63785
  specifierRemoved = removeSpecifierRootDirs(cacheDir, packageNames);
63573
63786
  lockRemoved = removeFromBunLock(cacheDir, packageNames);
63574
63787
  if (!packageRemoved && !specifierRemoved && !lockRemoved) {
63575
- log(`[auto-update-checker] Package not found, nothing to invalidate: ${packageName}`);
63788
+ log(`[auto-update-checker] Package not found, nothing to invalidate: ${targetPackageName}`);
63576
63789
  return false;
63577
63790
  }
63578
63791
  return true;
@@ -64005,9 +64218,9 @@ v${latestVersion} available. Restart OpenCode to apply.` : "OpenCode is now on S
64005
64218
  scheduleDeferredStartupCheck(() => {
64006
64219
  hasChecked = true;
64007
64220
  (async () => {
64008
- const cachedVersion2 = deps.getCachedVersion();
64221
+ const bundledVersion = deps.getBundledVersion?.();
64009
64222
  const localDevVersion = deps.getLocalDevVersion(ctx.directory);
64010
- const displayVersion = localDevVersion ?? cachedVersion2;
64223
+ const displayVersion = localDevVersion ?? bundledVersion ?? deps.getCachedVersion();
64011
64224
  await deps.showConfigErrorsIfAny(ctx);
64012
64225
  await deps.updateAndShowConnectedProvidersCacheStatus(ctx);
64013
64226
  await deps.refreshModelCapabilitiesOnStartup(modelCapabilities);
@@ -64051,6 +64264,7 @@ var init_hook = __esm(() => {
64051
64264
  init_model_cache_warning();
64052
64265
  init_startup_toasts();
64053
64266
  defaultDeps5 = {
64267
+ getBundledVersion,
64054
64268
  getCachedVersion,
64055
64269
  getLocalDevVersion,
64056
64270
  showConfigErrorsIfAny,
@@ -64097,181 +64311,9 @@ var {
64097
64311
  Option,
64098
64312
  Help
64099
64313
  } = import__.default;
64100
- // package.json
64101
- var package_default = {
64102
- name: "oh-my-opencode",
64103
- version: "4.9.2",
64104
- description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
64105
- main: "./dist/index.js",
64106
- types: "dist/index.d.ts",
64107
- type: "module",
64108
- workspaces: [
64109
- "packages/rules-engine",
64110
- "packages/ast-grep-core",
64111
- "packages/ast-grep-mcp",
64112
- "packages/git-bash-mcp",
64113
- "packages/utils",
64114
- "packages/model-core",
64115
- "packages/prompts-core",
64116
- "packages/comment-checker-core",
64117
- "packages/hashline-core",
64118
- "packages/boulder-state",
64119
- "packages/agents-md-core",
64120
- "packages/shared-skills",
64121
- "packages/omo-codex",
64122
- "packages/omo-opencode"
64123
- ],
64124
- bin: {
64125
- "oh-my-opencode": "bin/oh-my-opencode.js",
64126
- "oh-my-openagent": "bin/oh-my-opencode.js",
64127
- omo: "bin/oh-my-opencode.js",
64128
- lazycodex: "bin/oh-my-opencode.js",
64129
- "lazycodex-ai": "bin/oh-my-opencode.js"
64130
- },
64131
- files: [
64132
- "dist",
64133
- "bin",
64134
- "postinstall.mjs",
64135
- ".opencode/command",
64136
- ".opencode/skills",
64137
- ".agents/command",
64138
- ".agents/skills",
64139
- "packages/lsp-tools-mcp/package.json",
64140
- "packages/lsp-tools-mcp/dist",
64141
- "packages/lsp-daemon/package.json",
64142
- "packages/lsp-daemon/dist",
64143
- "packages/ast-grep-mcp/dist",
64144
- "packages/git-bash-mcp/dist",
64145
- "packages/shared-skills/package.json",
64146
- "packages/shared-skills/index.mjs",
64147
- "packages/shared-skills/skills",
64148
- "packages/omo-codex/marketplace.json",
64149
- "packages/omo-codex/lazycodex-repository",
64150
- "packages/omo-codex/plugin",
64151
- "packages/omo-codex/plugin/.codex-plugin",
64152
- "!packages/omo-codex/plugin/node_modules",
64153
- "!packages/omo-codex/plugin/**/node_modules",
64154
- "packages/omo-codex/scripts"
64155
- ],
64156
- exports: {
64157
- ".": {
64158
- types: "./dist/index.d.ts",
64159
- import: "./dist/index.js"
64160
- },
64161
- "./server": "./dist/index.js",
64162
- "./schema.json": "./dist/oh-my-opencode.schema.json"
64163
- },
64164
- scripts: {
64165
- build: "bun run build:ast-grep-mcp && bun run build:git-bash-mcp && bun build packages/omo-opencode/src/index.ts --outdir dist --target bun --format esm --external @ast-grep/napi --external zod && bun run build:node-require-shim && tsc --emitDeclarationOnly && bun build packages/omo-opencode/src/cli/index.ts --outdir dist/cli --target bun --format esm --external @ast-grep/napi && bun run build:cli-node && bun run build:schema",
64166
- "build:cli-node": "bun run script/build-cli-node.ts",
64167
- "build:lsp-tools-mcp": "npm --prefix packages/lsp-tools-mcp ci && npm --prefix packages/lsp-tools-mcp run build",
64168
- "build:lsp-daemon": "npm --prefix packages/lsp-daemon ci && npm --prefix packages/lsp-daemon run build",
64169
- "build:node-require-shim": "bun run script/patch-node-require-shim.ts",
64170
- "build:all": "bun run build && bun run build:binaries",
64171
- "build:binaries": "bun run script/build-binaries.ts",
64172
- "build:schema": "bun run script/build-schema.ts",
64173
- "build:model-capabilities": "bun run script/build-model-capabilities.ts",
64174
- clean: "rm -rf dist",
64175
- prepare: "bun run build",
64176
- postinstall: "node postinstall.mjs",
64177
- prepublishOnly: "bun run clean && bun run build:lsp-tools-mcp && bun run build:lsp-daemon && bun run build",
64178
- "test:model-capabilities": "bun test packages/omo-opencode/src/shared/model-capability-aliases.test.ts packages/omo-opencode/src/shared/model-capability-guardrails.test.ts packages/omo-opencode/src/shared/model-capabilities.test.ts packages/omo-opencode/src/cli/doctor/checks/model-resolution.test.ts --bail",
64179
- typecheck: "tsgo --noEmit && bun run typecheck:script && bun run typecheck:packages",
64180
- "typecheck:packages": "tsgo --noEmit -p packages/rules-engine/tsconfig.json && tsgo --noEmit -p packages/ast-grep-core/tsconfig.json && tsgo --noEmit -p packages/ast-grep-mcp/tsconfig.json && tsgo --noEmit -p packages/git-bash-mcp/tsconfig.json && tsgo --noEmit -p packages/utils/tsconfig.json && tsgo --noEmit -p packages/model-core/tsconfig.json && tsgo --noEmit -p packages/prompts-core/tsconfig.json && tsgo --noEmit -p packages/comment-checker-core/tsconfig.json && tsgo --noEmit -p packages/hashline-core/tsconfig.json && tsgo --noEmit -p packages/boulder-state/tsconfig.json && tsgo --noEmit -p packages/agents-md-core/tsconfig.json && tsgo --noEmit -p packages/omo-codex/tsconfig.json && tsgo --noEmit -p packages/omo-opencode/tsconfig.json",
64181
- "typecheck:script": "tsgo --noEmit -p script/tsconfig.json",
64182
- test: "bun test",
64183
- "test:codex": "bun run build:ast-grep-mcp && bun run build:git-bash-mcp && bun run build:lsp-tools-mcp && npm --prefix packages/lsp-tools-mcp test && npm --prefix packages/omo-codex/plugin ci && bun run --cwd packages/omo-codex/plugin build && bun test packages/omo-opencode/src/cli/cli-installer.platform.test.ts packages/omo-opencode/src/cli/install-codex/codex-cache.test.ts packages/omo-opencode/src/cli/install-codex/codex-cleanup.test.ts packages/omo-opencode/src/cli/install-codex/codex-config-agent-cleanup.test.ts packages/omo-opencode/src/cli/install-codex/codex-config-autonomous-features.test.ts packages/omo-opencode/src/cli/install-codex/codex-config-reasoning.test.ts packages/omo-opencode/src/cli/install-codex/codex-config-toml.test.ts packages/omo-opencode/src/cli/install-codex/codex-project-local-cleanup.test.ts packages/omo-opencode/src/cli/install-codex/install-codex-project-local-cleanup.test.ts packages/omo-opencode/src/cli/install-codex/install-codex.test.ts packages/omo-opencode/src/cli/install-codex/install-codex-packaged.test.ts packages/omo-opencode/src/cli/install-codex/link-cached-plugin-agents.test.ts packages/omo-codex/src/**/*.test.ts packages/utils/src/jsonc-parser.test.ts packages/utils/src/frontmatter.test.ts packages/hashline-core/src/hash-computation.test.ts packages/hashline-core/src/smoke-untested-modules.test.ts packages/rules-engine/src/index.test.ts packages/rules-engine/src/security-boundary.test.ts packages/agents-md-core/src/injector.test.ts packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts && node --test packages/omo-codex/plugin/test/*.test.mjs packages/omo-codex/scripts/install-cache-copy.test.mjs packages/omo-codex/scripts/install-cli-args.test.mjs packages/omo-codex/scripts/install-delegated-command.test.mjs packages/omo-codex/scripts/install-config-autonomous-features.test.mjs packages/omo-codex/scripts/install-config-autonomous.test.mjs packages/omo-codex/scripts/install-config-reasoning.test.mjs packages/omo-codex/scripts/install-config.test.mjs packages/omo-codex/scripts/install-hook-targets.test.mjs packages/omo-codex/scripts/install-project-local-cleanup.test.mjs packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs packages/omo-codex/scripts/install-local-entrypoint.test.mjs packages/omo-codex/scripts/install-local-git-bash-preflight.test.mjs packages/omo-codex/scripts/install-local.test.mjs packages/omo-codex/scripts/install-marketplace-cache.test.mjs packages/omo-codex/scripts/install-mcp-runtime.test.mjs packages/omo-codex/scripts/install-packaged-local.test.mjs packages/omo-codex/scripts/install/git-bash.test.mjs packages/omo-codex/scripts/install-agent-links.test.mjs packages/omo-codex/scripts/install-bin-links.test.mjs packages/omo-codex/scripts/sync-telemetry-component.test.mjs",
64184
- "test:windows-codex": "bun run test:codex",
64185
- "build:ast-grep-mcp": "bun run --cwd packages/ast-grep-mcp build",
64186
- "build:git-bash-mcp": "bun run --cwd packages/git-bash-mcp build"
64187
- },
64188
- keywords: [
64189
- "opencode",
64190
- "plugin",
64191
- "oracle",
64192
- "librarian",
64193
- "agents",
64194
- "ai",
64195
- "llm"
64196
- ],
64197
- author: "YeonGyu-Kim",
64198
- license: "SUL-1.0",
64199
- repository: {
64200
- type: "git",
64201
- url: "git+https://github.com/code-yeongyu/oh-my-openagent.git"
64202
- },
64203
- bugs: {
64204
- url: "https://github.com/code-yeongyu/oh-my-openagent/issues"
64205
- },
64206
- homepage: "https://github.com/code-yeongyu/oh-my-openagent#readme",
64207
- dependencies: {
64208
- "@ast-grep/cli": "^0.42.2",
64209
- "@ast-grep/napi": "^0.42.2",
64210
- "@clack/prompts": "^1.4.0",
64211
- "@code-yeongyu/comment-checker": "^0.8.0",
64212
- "@modelcontextprotocol/sdk": "^1.29.0",
64213
- "@opencode-ai/plugin": "^1.15.4",
64214
- "@opencode-ai/sdk": "^1.15.4",
64215
- commander: "^14.0.3",
64216
- "detect-libc": "^2.1.2",
64217
- diff: "^9.0.0",
64218
- "js-yaml": "^4.1.1",
64219
- "jsonc-parser": "^3.3.1",
64220
- picocolors: "^1.1.1",
64221
- picomatch: "^4.0.4",
64222
- "posthog-node": "^5.34.3",
64223
- "vscode-jsonrpc": "^8.2.1"
64224
- },
64225
- devDependencies: {
64226
- "@oh-my-opencode/ast-grep-core": "workspace:*",
64227
- "@oh-my-opencode/ast-grep-mcp": "workspace:*",
64228
- "@oh-my-opencode/git-bash-mcp": "workspace:*",
64229
- "@oh-my-opencode/agents-md-core": "workspace:*",
64230
- "@oh-my-opencode/boulder-state": "workspace:*",
64231
- "@oh-my-opencode/comment-checker-core": "workspace:*",
64232
- "@oh-my-opencode/hashline-core": "workspace:*",
64233
- "@oh-my-opencode/model-core": "workspace:*",
64234
- "@oh-my-opencode/omo-codex": "workspace:*",
64235
- "@oh-my-opencode/prompts-core": "workspace:*",
64236
- "@oh-my-opencode/rules-engine": "workspace:*",
64237
- "@oh-my-opencode/shared-skills": "workspace:*",
64238
- "@oh-my-opencode/utils": "workspace:*",
64239
- "@typescript/native-preview": "7.0.0-dev.20260518.1",
64240
- "@types/js-yaml": "^4.0.9",
64241
- "@types/picomatch": "^4.0.3",
64242
- "bun-types": "1.3.14",
64243
- typescript: "^6.0.3",
64244
- zod: "^4.4.3"
64245
- },
64246
- optionalDependencies: {
64247
- "oh-my-opencode-darwin-arm64": "4.9.2",
64248
- "oh-my-opencode-darwin-x64": "4.9.2",
64249
- "oh-my-opencode-darwin-x64-baseline": "4.9.2",
64250
- "oh-my-opencode-linux-arm64": "4.9.2",
64251
- "oh-my-opencode-linux-arm64-musl": "4.9.2",
64252
- "oh-my-opencode-linux-x64": "4.9.2",
64253
- "oh-my-opencode-linux-x64-baseline": "4.9.2",
64254
- "oh-my-opencode-linux-x64-musl": "4.9.2",
64255
- "oh-my-opencode-linux-x64-musl-baseline": "4.9.2",
64256
- "oh-my-opencode-windows-x64": "4.9.2",
64257
- "oh-my-opencode-windows-x64-baseline": "4.9.2"
64258
- },
64259
- overrides: {
64260
- hono: "^4.12.18",
64261
- "@hono/node-server": "^1.19.13",
64262
- "express-rate-limit": "^8.5.1",
64263
- "fast-uri": "^3.1.2",
64264
- "path-to-regexp": "^8.4.2"
64265
- },
64266
- trustedDependencies: [
64267
- "@ast-grep/cli",
64268
- "@ast-grep/napi",
64269
- "@code-yeongyu/comment-checker"
64270
- ],
64271
- peerDependencies: {
64272
- zod: "^4.0.0"
64273
- }
64274
- };
64314
+
64315
+ // packages/omo-opencode/src/cli/install.ts
64316
+ init_package();
64275
64317
 
64276
64318
  // packages/omo-opencode/src/cli/cli-installer.ts
64277
64319
  init_shared();
@@ -64804,16 +64846,19 @@ async function existingNonRuntimeWrapper(path6) {
64804
64846
  }
64805
64847
  }
64806
64848
  function posixRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
64807
- const ulwLoopBin = join22(binDir, "omo-ulw-loop");
64808
- const nodeCli = escapePosixDoubleQuoted(nodeCliPath);
64849
+ const ulwLoopBin = toPosixPath(join22(binDir, "omo-ulw-loop"));
64850
+ const nodeCli = escapePosixDoubleQuoted(toPosixPath(nodeCliPath));
64851
+ const escapedCliPath = escapePosixDoubleQuoted(toPosixPath(cliPath));
64852
+ const escapedCodexHome = escapePosixDoubleQuoted(toPosixPath(codexHome));
64853
+ const escapedUlwLoopBin = escapePosixDoubleQuoted(ulwLoopBin);
64809
64854
  return [
64810
64855
  "#!/bin/sh",
64811
64856
  `# ${RUNTIME_WRAPPER_MARKER}`,
64812
- `export CODEX_HOME="\${CODEX_HOME:-${escapePosixDoubleQuoted(codexHome)}}"`,
64857
+ `export CODEX_HOME="\${CODEX_HOME:-${escapedCodexHome}}"`,
64813
64858
  'export OMO_SPARKSHELL_APP_SERVER_SOCKET="${OMO_SPARKSHELL_APP_SERVER_SOCKET:-$CODEX_HOME/app-server-control/app-server-control.sock}"',
64814
- 'if [ "$1" = "ulw-loop" ] && [ -x "' + escapePosixDoubleQuoted(ulwLoopBin) + '" ]; then',
64859
+ 'if [ "$1" = "ulw-loop" ] && [ -x "' + escapedUlwLoopBin + '" ]; then',
64815
64860
  " shift",
64816
- ' exec "' + escapePosixDoubleQuoted(ulwLoopBin) + '" "$@"',
64861
+ ' exec "' + escapedUlwLoopBin + '" "$@"',
64817
64862
  "fi",
64818
64863
  `if [ "\${OMO_RUNTIME:-}" = "node" ] && [ -f "${nodeCli}" ]; then`,
64819
64864
  ` exec node "${nodeCli}" "$@"`,
@@ -64837,7 +64882,7 @@ function posixRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
64837
64882
  ` echo "omo: bun runtime not found (checked PATH, ~/.bun/bin, /opt/homebrew/bin, /usr/local/bin) and the node fallback CLI is missing at ${nodeCli}; install bun from https://bun.sh, or reinstall omo and force the fallback with OMO_RUNTIME=node" >&2`,
64838
64883
  " exit 127",
64839
64884
  "fi",
64840
- `exec "$BUN_BINARY" "${escapePosixDoubleQuoted(cliPath)}" "$@"`,
64885
+ `exec "$BUN_BINARY" "${escapedCliPath}" "$@"`,
64841
64886
  ""
64842
64887
  ].join(`
64843
64888
  `);
@@ -64873,6 +64918,9 @@ function windowsRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
64873
64918
  ].join(`\r
64874
64919
  `);
64875
64920
  }
64921
+ function toPosixPath(p) {
64922
+ return p.replaceAll("\\", "/");
64923
+ }
64876
64924
  function escapePosixDoubleQuoted(value) {
64877
64925
  return value.replaceAll("\\", "\\\\").replaceAll('"', "\\\"").replaceAll("$", "\\$").replaceAll("`", "\\`");
64878
64926
  }
@@ -66147,6 +66195,8 @@ function resolveGitBash(input) {
66147
66195
  if (candidate.length === 0)
66148
66196
  continue;
66149
66197
  checkedPaths.push(candidate);
66198
+ if (isKnownNonGitBashLauncher(candidate))
66199
+ continue;
66150
66200
  if (isBashExePath(candidate) && input.exists(candidate))
66151
66201
  return { found: true, path: candidate, source: "path" };
66152
66202
  }
@@ -66199,6 +66249,11 @@ function nonEmptyEnvValue(env, key) {
66199
66249
  function isBashExePath(path6) {
66200
66250
  return path6.toLowerCase().endsWith("bash.exe");
66201
66251
  }
66252
+ var NON_GIT_BASH_LAUNCHER_DIR_SEGMENTS = ["\\windows\\system32\\", "\\microsoft\\windowsapps\\"];
66253
+ function isKnownNonGitBashLauncher(path6) {
66254
+ const normalized = path6.replaceAll("/", "\\").toLowerCase();
66255
+ return NON_GIT_BASH_LAUNCHER_DIR_SEGMENTS.some((segment) => normalized.includes(segment));
66256
+ }
66202
66257
  function whereCommand(command) {
66203
66258
  try {
66204
66259
  return execFileSync("where", [command], { encoding: "utf8" }).split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
@@ -66231,6 +66286,22 @@ async function capturePreservedAgentReasoning(input) {
66231
66286
  }
66232
66287
  return preserved;
66233
66288
  }
66289
+ async function capturePreservedAgentServiceTier(input) {
66290
+ const agentsDir = join32(input.codexHome, "agents");
66291
+ if (!await exists4(agentsDir))
66292
+ return new Map;
66293
+ const preserved = new Map;
66294
+ const agentEntries = await readdir4(agentsDir, { withFileTypes: true });
66295
+ for (const entry of agentEntries) {
66296
+ if (!entry.name.endsWith(".toml"))
66297
+ continue;
66298
+ const content = await readTextIfExists(join32(agentsDir, entry.name));
66299
+ if (content === null)
66300
+ continue;
66301
+ preserved.set(agentNameFromToml(entry.name), extractServiceTier(content));
66302
+ }
66303
+ return preserved;
66304
+ }
66234
66305
  async function linkCachedPluginAgents(input) {
66235
66306
  const bundledAgents = await discoverBundledAgents(input.pluginRoot);
66236
66307
  if (bundledAgents.length === 0) {
@@ -66251,11 +66322,27 @@ async function linkCachedPluginAgents(input) {
66251
66322
  target: agentPath,
66252
66323
  value: input.preservedReasoning?.get(agentName)
66253
66324
  });
66325
+ await restorePreservedServiceTier({
66326
+ linkPath,
66327
+ preserved: input.preservedServiceTier?.has(agentName) ?? false,
66328
+ value: input.preservedServiceTier?.get(agentName) ?? null
66329
+ });
66254
66330
  linked.push({ name: agentFileName, path: linkPath, target: agentPath });
66255
66331
  }
66256
66332
  await writeManifest(input.pluginRoot, linked.map((entry) => entry.path));
66257
66333
  return linked;
66258
66334
  }
66335
+ async function restorePreservedServiceTier(input) {
66336
+ if (!input.preserved)
66337
+ return;
66338
+ const content = await readFile11(input.linkPath, "utf8");
66339
+ if (extractServiceTier(content) === input.value)
66340
+ return;
66341
+ const replacement = replaceServiceTier(content, input.value);
66342
+ if (!replacement.replaced)
66343
+ return;
66344
+ await writeFile6(input.linkPath, replacement.content);
66345
+ }
66259
66346
  async function discoverBundledAgents(pluginRoot) {
66260
66347
  const componentsRoot = join32(pluginRoot, "components");
66261
66348
  if (!await exists4(componentsRoot))
@@ -66324,11 +66411,16 @@ async function readTextIfExists(path6) {
66324
66411
  }
66325
66412
  }
66326
66413
  function extractReasoningEffort(content) {
66414
+ return extractTopLevelStringSetting(content, "model_reasoning_effort");
66415
+ }
66416
+ function extractServiceTier(content) {
66417
+ return extractTopLevelStringSetting(content, "service_tier");
66418
+ }
66419
+ function extractTopLevelStringSetting(content, key) {
66327
66420
  for (const line of content.split(/\n/)) {
66328
66421
  if (isSectionHeader2(line))
66329
66422
  return null;
66330
- const match = line.match(/^\s*model_reasoning_effort\s*=\s*("(?:[^"\\]|\\.)*")/);
66331
- const rawValue = match?.[1];
66423
+ const rawValue = topLevelStringSettingRawValue(line, key);
66332
66424
  if (rawValue === undefined)
66333
66425
  continue;
66334
66426
  const parsed = parseJsonString2(rawValue);
@@ -66338,18 +66430,52 @@ function extractReasoningEffort(content) {
66338
66430
  return null;
66339
66431
  }
66340
66432
  function replaceReasoningEffort(content, value) {
66433
+ return replaceTopLevelStringSetting(content, "model_reasoning_effort", value, { insertIfMissing: false });
66434
+ }
66435
+ function replaceServiceTier(content, value) {
66436
+ return replaceTopLevelStringSetting(content, "service_tier", value, { insertIfMissing: true });
66437
+ }
66438
+ function replaceTopLevelStringSetting(content, key, value, options) {
66341
66439
  const lines = content.split(/\n/);
66342
66440
  for (let index = 0;index < lines.length; index += 1) {
66343
66441
  const line = lines[index];
66344
66442
  if (line === undefined || isSectionHeader2(line))
66345
66443
  break;
66346
- if (!/^\s*model_reasoning_effort\s*=/.test(line))
66444
+ if (topLevelStringSettingRawValue(line, key) === undefined)
66347
66445
  continue;
66446
+ if (value === null) {
66447
+ lines.splice(index, 1);
66448
+ return { content: lines.join(`
66449
+ `), replaced: true };
66450
+ }
66348
66451
  lines[index] = line.replace(/=\s*"(?:[^"\\]|\\.)*"/, `= ${JSON.stringify(value)}`);
66349
66452
  return { content: lines.join(`
66350
66453
  `), replaced: true };
66351
66454
  }
66352
- return { content, replaced: false };
66455
+ if (value === null || !options.insertIfMissing)
66456
+ return { content, replaced: false };
66457
+ lines.splice(topLevelInsertionIndex(lines), 0, `${key} = ${JSON.stringify(value)}`);
66458
+ return { content: lines.join(`
66459
+ `), replaced: true };
66460
+ }
66461
+ function topLevelStringSettingRawValue(line, key) {
66462
+ const match = line.match(/^\s*([A-Za-z0-9_]+)\s*=\s*("(?:[^"\\]|\\.)*")/);
66463
+ if (match === null)
66464
+ return;
66465
+ const settingKey = match[1];
66466
+ const rawValue = match[2];
66467
+ if (settingKey !== key || rawValue === undefined)
66468
+ return;
66469
+ return rawValue;
66470
+ }
66471
+ function topLevelInsertionIndex(lines) {
66472
+ const sectionIndex = lines.findIndex((line) => isSectionHeader2(line));
66473
+ const topLevelEnd = sectionIndex === -1 ? lines.length : sectionIndex;
66474
+ let insertionIndex = topLevelEnd;
66475
+ while (insertionIndex > 0 && lines[insertionIndex - 1] === "") {
66476
+ insertionIndex -= 1;
66477
+ }
66478
+ return insertionIndex;
66353
66479
  }
66354
66480
  function isSectionHeader2(line) {
66355
66481
  const trimmed = line.trim();
@@ -67049,6 +67175,7 @@ async function runCodexInstaller(options = {}) {
67049
67175
  installed.push(plugin);
67050
67176
  }
67051
67177
  const preservedReasoning = await capturePreservedAgentReasoning({ codexHome });
67178
+ const preservedServiceTier = await capturePreservedAgentServiceTier({ codexHome });
67052
67179
  const agentSourceRoots = await agentSourceRootsForInstall({
67053
67180
  codexHome,
67054
67181
  marketplace,
@@ -67057,7 +67184,13 @@ async function runCodexInstaller(options = {}) {
67057
67184
  });
67058
67185
  for (const plugin of installed) {
67059
67186
  const pluginRoot = agentSourceRoots.get(plugin.name) ?? plugin.path;
67060
- const agentLinks = await linkCachedPluginAgents({ codexHome, pluginRoot, platform, preservedReasoning });
67187
+ const agentLinks = await linkCachedPluginAgents({
67188
+ codexHome,
67189
+ pluginRoot,
67190
+ platform,
67191
+ preservedReasoning,
67192
+ preservedServiceTier
67193
+ });
67061
67194
  for (const link of agentLinks) {
67062
67195
  log2(`Linked agent ${link.name} -> ${link.target}`);
67063
67196
  const agentName = agentNameFromToml2(link.name);
@@ -67309,7 +67442,7 @@ function defaultRunCommand2(command, args) {
67309
67442
  });
67310
67443
  }
67311
67444
  // packages/omo-opencode/src/cli/install-codex/codex-cleanup.ts
67312
- import { lstat as lstat8, readFile as readFile17, readdir as readdir7, rm as rm8 } from "fs/promises";
67445
+ import { lstat as lstat8, readFile as readFile17, readdir as readdir7, rm as rm8, rmdir } from "fs/promises";
67313
67446
  import { homedir as homedir8 } from "os";
67314
67447
  import { isAbsolute as isAbsolute7, join as join42, relative as relative6, resolve as resolve12 } from "path";
67315
67448
 
@@ -67478,10 +67611,15 @@ async function cleanupCodexLight(input = {}) {
67478
67611
  const configCleanup = await cleanupCodexConfig(configPath, input.now);
67479
67612
  const agentCleanup = await removeManifestListedAgentLinks(codexHome, agentPaths);
67480
67613
  const removedPaths = [];
67481
- for (const path7 of managedGlobalStatePaths(codexHome)) {
67482
- if (await removePathIfExists(path7))
67614
+ const managedStatePaths = new Set([
67615
+ ...managedGlobalStatePaths(codexHome),
67616
+ ...await collectBootstrapDataDirsByGlob(codexHome)
67617
+ ]);
67618
+ for (const path7 of managedStatePaths) {
67619
+ if (await removeManagedPathBestEffort(path7))
67483
67620
  removedPaths.push(path7);
67484
67621
  }
67622
+ await pruneEmptyRuntimeDirBestEffort(codexHome);
67485
67623
  const projectDirectory = input.projectDirectory ?? env.OMO_CODEX_PROJECT ?? process.cwd();
67486
67624
  const projectCleanup = await repairProjectLocalCodexArtifactsBestEffort({
67487
67625
  startDirectory: projectDirectory,
@@ -67505,9 +67643,61 @@ async function cleanupCodexLight(input = {}) {
67505
67643
  function managedGlobalStatePaths(codexHome) {
67506
67644
  return [
67507
67645
  join42(codexHome, "plugins", "cache", "sisyphuslabs"),
67508
- join42(codexHome, ".tmp", "marketplaces", "sisyphuslabs")
67646
+ join42(codexHome, ".tmp", "marketplaces", "sisyphuslabs"),
67647
+ join42(codexHome, "runtime", "ast-grep"),
67648
+ join42(codexHome, "runtime", "node"),
67649
+ join42(codexHome, "plugins", "data", "omo-sisyphuslabs", "bootstrap")
67509
67650
  ];
67510
67651
  }
67652
+ var BOOTSTRAP_DATA_GLOB_MAX_DEPTH = 5;
67653
+ async function collectBootstrapDataDirsByGlob(codexHome) {
67654
+ const results = [];
67655
+ await walkForManagedBootstrapDirs(join42(codexHome, "plugins"), 0, results);
67656
+ return results;
67657
+ }
67658
+ async function walkForManagedBootstrapDirs(directory, depth, results) {
67659
+ if (depth > BOOTSTRAP_DATA_GLOB_MAX_DEPTH)
67660
+ return;
67661
+ const entries = await readdir7(directory, { withFileTypes: true }).catch(() => null);
67662
+ if (entries === null)
67663
+ return;
67664
+ for (const entry of entries) {
67665
+ if (!entry.isDirectory())
67666
+ continue;
67667
+ const childPath = join42(directory, entry.name);
67668
+ if (isManagedBootstrapOwnerName(entry.name)) {
67669
+ const bootstrapDir = join42(childPath, "bootstrap");
67670
+ if (await exists6(bootstrapDir))
67671
+ results.push(bootstrapDir);
67672
+ continue;
67673
+ }
67674
+ await walkForManagedBootstrapDirs(childPath, depth + 1, results);
67675
+ }
67676
+ }
67677
+ function isManagedBootstrapOwnerName(name) {
67678
+ return name.startsWith("omo") && name.slice("omo".length).includes("sisyphuslabs");
67679
+ }
67680
+ async function removeManagedPathBestEffort(path7, seams = {}) {
67681
+ const removedOnFirstAttempt = await attemptRemove(path7);
67682
+ await seams.afterFirstAttempt?.();
67683
+ const removedOnRetry = await attemptRemove(path7);
67684
+ return removedOnFirstAttempt || removedOnRetry;
67685
+ }
67686
+ async function attemptRemove(path7) {
67687
+ try {
67688
+ if (await lstat8(path7).catch(() => null) === null)
67689
+ return false;
67690
+ await rm8(path7, { recursive: true, force: true });
67691
+ return true;
67692
+ } catch {
67693
+ return false;
67694
+ }
67695
+ }
67696
+ async function pruneEmptyRuntimeDirBestEffort(codexHome) {
67697
+ try {
67698
+ await rmdir(join42(codexHome, "runtime"));
67699
+ } catch {}
67700
+ }
67511
67701
  async function collectInstalledAgentPaths(codexHome, configPath) {
67512
67702
  const manifestPaths = [
67513
67703
  join42(codexHome, ".tmp", "marketplaces", "sisyphuslabs", "plugins", "omo", INSTALLED_AGENTS_MANIFEST)
@@ -67577,12 +67767,6 @@ function isSafeManagedAgentPath(agentsDir, path7) {
67577
67767
  return false;
67578
67768
  return MANAGED_CODEX_AGENT_NAMES2.some((agentName) => fileName === `${agentName}.toml`);
67579
67769
  }
67580
- async function removePathIfExists(path7) {
67581
- if (!await exists6(path7))
67582
- return false;
67583
- await rm8(path7, { recursive: true, force: true });
67584
- return true;
67585
- }
67586
67770
  async function exists6(path7) {
67587
67771
  return await maybeLstat2(path7) !== null;
67588
67772
  }
@@ -67633,6 +67817,7 @@ async function starGitHubRepositories(platform = "both", runCommand = runGitHubS
67633
67817
  }
67634
67818
 
67635
67819
  // packages/omo-opencode/src/cli/cli-installer.ts
67820
+ init_provider_availability();
67636
67821
  async function runCliInstaller(args, version2) {
67637
67822
  const validation = validateNonTuiArgs(args);
67638
67823
  if (!validation.valid) {
@@ -67710,8 +67895,8 @@ async function runCliInstaller(args, version2) {
67710
67895
  if (config.hasOpenCode && !config.hasClaude) {
67711
67896
  printInfo("Note: Sisyphus agent performs best with Claude Opus 4.5+. " + "Other models work but may have reduced orchestration quality.");
67712
67897
  }
67713
- if (config.hasOpenCode && !config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen && !config.hasZaiCodingPlan && !config.hasKimiForCoding && !config.hasOpencodeGo && !config.hasMinimaxCnCodingPlan && !config.hasMinimaxCodingPlan && !config.hasVercelAiGateway) {
67714
- printWarning("No model providers configured. Using opencode/big-pickle as fallback.");
67898
+ if (config.hasOpenCode && !hasAnyConfiguredProvider(config)) {
67899
+ printWarning(getNoModelProvidersWarning());
67715
67900
  }
67716
67901
  console.log(`${SYMBOLS.star} ${import_picocolors3.default.bold(import_picocolors3.default.green(isUpdate ? "Configuration updated!" : "Installation complete!"))}`);
67717
67902
  if (hasOpenCode) {
@@ -69097,6 +69282,7 @@ init_config_manager();
69097
69282
  var import_picocolors4 = __toESM(require_picocolors(), 1);
69098
69283
 
69099
69284
  // packages/omo-opencode/src/cli/tui-install-prompts.ts
69285
+ init_model_fallback();
69100
69286
  async function selectOrCancel(params) {
69101
69287
  if (!process.stdin.isTTY || !process.stdout.isTTY)
69102
69288
  return null;
@@ -69154,7 +69340,7 @@ async function promptInstallConfig(detected, platform, codexAutonomousOverride)
69154
69340
  const claude = await selectOrCancel({
69155
69341
  message: "Do you have a Claude Pro/Max subscription?",
69156
69342
  options: [
69157
- { value: "no", label: "No", hint: "Will use opencode/big-pickle as fallback" },
69343
+ { value: "no", label: "No", hint: `Will use ${ULTIMATE_FALLBACK} as fallback` },
69158
69344
  { value: "yes", label: "Yes (standard)", hint: "Claude Opus 4.5 for orchestration" },
69159
69345
  { value: "max20", label: "Yes (max20 mode)", hint: "Full power with Claude Sonnet 4.6 for Librarian" }
69160
69346
  ],
@@ -69301,6 +69487,7 @@ async function resolveCodexAutonomous(hasCodex, override) {
69301
69487
  }
69302
69488
 
69303
69489
  // packages/omo-opencode/src/cli/tui-installer.ts
69490
+ init_provider_availability();
69304
69491
  async function runTuiInstaller(args, version2) {
69305
69492
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
69306
69493
  console.error("Error: Interactive installer requires a TTY. Use --non-interactive or set environment variables directly.");
@@ -69378,8 +69565,8 @@ async function runTuiInstaller(args, version2) {
69378
69565
  R2.info(`${import_picocolors4.default.bold("Note:")} Sisyphus agent performs best with Claude Opus 4.5+.
69379
69566
  ` + `Other models work but may have reduced orchestration quality.`);
69380
69567
  }
69381
- if (config.hasOpenCode && !config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen && !config.hasZaiCodingPlan && !config.hasKimiForCoding && !config.hasOpencodeGo && !config.hasMinimaxCnCodingPlan && !config.hasMinimaxCodingPlan && !config.hasVercelAiGateway) {
69382
- R2.warn("No model providers configured. Using opencode/big-pickle as fallback.");
69568
+ if (config.hasOpenCode && !hasAnyConfiguredProvider(config)) {
69569
+ R2.warn(getNoModelProvidersWarning());
69383
69570
  }
69384
69571
  Ce(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
69385
69572
  if (config.hasCodex) {
@@ -84610,7 +84797,7 @@ var AgentPermissionSchema = exports_external.object({
84610
84797
  task: PermissionValueSchema.optional(),
84611
84798
  doom_loop: PermissionValueSchema.optional(),
84612
84799
  external_directory: PermissionValueSchema.optional()
84613
- });
84800
+ }).catchall(PermissionValueSchema.optional());
84614
84801
 
84615
84802
  // packages/omo-opencode/src/config/schema/agent-overrides.ts
84616
84803
  var AgentOverrideConfigSchema = exports_external.object({
@@ -84798,7 +84985,6 @@ var DynamicContextPruningConfigSchema = exports_external.object({
84798
84985
  // packages/omo-opencode/src/config/schema/experimental.ts
84799
84986
  var ExperimentalConfigSchema = exports_external.object({
84800
84987
  aggressive_truncation: exports_external.boolean().optional(),
84801
- auto_resume: exports_external.boolean().optional(),
84802
84988
  preemptive_compaction: exports_external.boolean().optional(),
84803
84989
  truncate_all_tool_outputs: exports_external.boolean().optional(),
84804
84990
  dynamic_context_pruning: DynamicContextPruningConfigSchema.optional(),
@@ -84830,7 +85016,6 @@ var GitMasterConfigSchema = exports_external.object({
84830
85016
  // packages/omo-opencode/src/config/schema/hooks.ts
84831
85017
  var HookNameSchema = exports_external.enum([
84832
85018
  "todo-continuation-enforcer",
84833
- "session-recovery",
84834
85019
  "session-notification",
84835
85020
  "comment-checker",
84836
85021
  "tool-output-truncator",
@@ -86752,6 +86937,13 @@ async function pollForCompletion(ctx, eventState, abortController, options = {})
86752
86937
  return 130;
86753
86938
  }
86754
86939
  if (eventState.mainSessionError) {
86940
+ const statusDuringError = await getMainSessionStatus(ctx);
86941
+ if (statusDuringError === "busy" || statusDuringError === "retry") {
86942
+ eventState.mainSessionError = false;
86943
+ eventState.mainSessionIdle = false;
86944
+ errorCycleCount = 0;
86945
+ continue;
86946
+ }
86755
86947
  errorCycleCount++;
86756
86948
  if (errorCycleCount >= ERROR_GRACE_CYCLES) {
86757
86949
  console.error(import_picocolors15.default.red(`
@@ -87081,9 +87273,10 @@ function createTimestampedStdoutController(stdout = process.stdout) {
87081
87273
 
87082
87274
  // packages/omo-opencode/src/shared/posthog.ts
87083
87275
  init_index_node();
87276
+ init_package();
87277
+ init_plugin_identity();
87084
87278
  import os5 from "os";
87085
87279
  import { createHash as createHash4 } from "crypto";
87086
- init_plugin_identity();
87087
87280
 
87088
87281
  // packages/omo-opencode/src/shared/posthog-activity-state.ts
87089
87282
  init_data_path();
@@ -87912,7 +88105,7 @@ init_file_utils2();
87912
88105
  init_checker();
87913
88106
  init_auto_update_checker();
87914
88107
  init_package_json_locator();
87915
- import { existsSync as existsSync46, readFileSync as readFileSync31 } from "fs";
88108
+ import { existsSync as existsSync46, readFileSync as readFileSync31, readdirSync as readdirSync7 } from "fs";
87916
88109
  import { createRequire } from "module";
87917
88110
  import { homedir as homedir13 } from "os";
87918
88111
  import { join as join56 } from "path";
@@ -87965,6 +88158,29 @@ function createPackageCandidates(rootDir) {
87965
88158
  installedPackagePath: join56(rootDir, "node_modules", packageName, "package.json")
87966
88159
  }));
87967
88160
  }
88161
+ function createTaggedInstallCandidates(rootDir) {
88162
+ const packagesDir = join56(rootDir, "packages");
88163
+ if (!existsSync46(packagesDir))
88164
+ return [];
88165
+ const candidates = [];
88166
+ for (const entryName of readdirSync7(packagesDir).sort()) {
88167
+ const packageName = ACCEPTED_PACKAGE_NAMES.find((name) => entryName.startsWith(`${name}@`));
88168
+ if (packageName === undefined)
88169
+ continue;
88170
+ const installDir = join56(packagesDir, entryName);
88171
+ candidates.push({
88172
+ cacheDir: installDir,
88173
+ cachePackagePath: join56(installDir, "package.json"),
88174
+ packageCandidates: [
88175
+ {
88176
+ packageName,
88177
+ installedPackagePath: join56(installDir, "node_modules", packageName, "package.json")
88178
+ }
88179
+ ]
88180
+ });
88181
+ }
88182
+ return candidates;
88183
+ }
87968
88184
  function selectInstalledPackage(candidate) {
87969
88185
  return candidate.packageCandidates.find((packageCandidate) => existsSync46(packageCandidate.installedPackagePath)) ?? candidate.packageCandidates[0];
87970
88186
  }
@@ -88006,11 +88222,13 @@ function getLoadedPluginVersion() {
88006
88222
  cachePackagePath: join56(configDir, "package.json"),
88007
88223
  packageCandidates: createPackageCandidates(configDir)
88008
88224
  },
88225
+ ...createTaggedInstallCandidates(configDir),
88009
88226
  {
88010
88227
  cacheDir,
88011
88228
  cachePackagePath: join56(cacheDir, "package.json"),
88012
88229
  packageCandidates: createPackageCandidates(cacheDir)
88013
- }
88230
+ },
88231
+ ...createTaggedInstallCandidates(cacheDir)
88014
88232
  ];
88015
88233
  const selectedCandidate = candidates.find((candidate) => candidate.packageCandidates.some((packageCandidate) => existsSync46(packageCandidate.installedPackagePath))) ?? candidates[0];
88016
88234
  const { cacheDir: selectedDir, cachePackagePath } = selectedCandidate;
@@ -88085,6 +88303,12 @@ function buildMessage(status, issues) {
88085
88303
  return `${issues.length} system issue(s) detected`;
88086
88304
  return `${issues.length} system warning(s) detected`;
88087
88305
  }
88306
+ function getLoadedPackageName(installedPackagePath) {
88307
+ const parts = installedPackagePath.split(/[\\/]/);
88308
+ const nodeModulesIndex = parts.lastIndexOf("node_modules");
88309
+ const packageName = nodeModulesIndex >= 0 ? parts[nodeModulesIndex + 1] : undefined;
88310
+ return packageName !== undefined && ACCEPTED_PACKAGE_NAMES.some((acceptedName) => acceptedName === packageName) ? packageName : PUBLISHED_PACKAGE_NAME;
88311
+ }
88088
88312
  async function gatherSystemInfo(deps = defaultDeps6) {
88089
88313
  const [binaryInfo, pluginInfo] = await Promise.all([
88090
88314
  deps.findOpenCodeBinary(),
@@ -88166,7 +88390,7 @@ async function checkSystem(deps = defaultDeps6) {
88166
88390
  issues.push({
88167
88391
  title: "Loaded plugin is outdated",
88168
88392
  description: `Loaded ${systemInfo.loadedVersion}, latest ${latestVersion}.`,
88169
- fix: `Update: cd "${loadedInfo.cacheDir}" && bun add ${PUBLISHED_PACKAGE_NAME}@${installTag}`,
88393
+ fix: `Update: cd "${loadedInfo.cacheDir}" && bun add ${getLoadedPackageName(loadedInfo.installedPackagePath)}@${installTag}`,
88170
88394
  severity: "warning",
88171
88395
  affects: ["plugin features"]
88172
88396
  });
@@ -89464,6 +89688,10 @@ function isNamedTuiPluginEntry(entry) {
89464
89688
  return true;
89465
89689
  return false;
89466
89690
  }
89691
+ function isCanonicalNamedTuiPluginEntry(entry) {
89692
+ const canonicalPrefix = `${PLUGIN_NAME}/${TUI_SUBPATH}`;
89693
+ return entry === canonicalPrefix || entry.startsWith(`${canonicalPrefix}@`);
89694
+ }
89467
89695
  function detectServerPluginRegistration() {
89468
89696
  const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
89469
89697
  const configPath = existsSync52(paths.configJsonc) ? paths.configJsonc : existsSync52(paths.configJson) ? paths.configJson : null;
@@ -89486,7 +89714,7 @@ function detectServerPluginRegistration() {
89486
89714
  function detectTuiPluginRegistration() {
89487
89715
  const tuiJsonPath = join65(getOpenCodeConfigDir({ binary: "opencode" }), "tui.json");
89488
89716
  if (!existsSync52(tuiJsonPath)) {
89489
- return { registered: false, configPath: tuiJsonPath, exists: false, hasNamedTuiEntry: false };
89717
+ return { registered: false, configPath: tuiJsonPath, exists: false, hasNamedTuiEntry: false, hasCanonicalNamedTuiEntry: false };
89490
89718
  }
89491
89719
  try {
89492
89720
  const parsed = parseJsonc(readFileSync39(tuiJsonPath, "utf-8"));
@@ -89495,10 +89723,11 @@ function detectTuiPluginRegistration() {
89495
89723
  registered: plugins.some(isTuiPluginEntry),
89496
89724
  configPath: tuiJsonPath,
89497
89725
  exists: true,
89498
- hasNamedTuiEntry: plugins.some(isNamedTuiPluginEntry)
89726
+ hasNamedTuiEntry: plugins.some(isNamedTuiPluginEntry),
89727
+ hasCanonicalNamedTuiEntry: plugins.some(isCanonicalNamedTuiPluginEntry)
89499
89728
  };
89500
89729
  } catch (error51) {
89501
- return { registered: false, configPath: tuiJsonPath, exists: true, hasNamedTuiEntry: false };
89730
+ return { registered: false, configPath: tuiJsonPath, exists: true, hasNamedTuiEntry: false, hasCanonicalNamedTuiEntry: false };
89502
89731
  }
89503
89732
  }
89504
89733
  async function checkTuiPluginConfig() {
@@ -89520,10 +89749,13 @@ async function checkTuiPluginConfig() {
89520
89749
  issues
89521
89750
  };
89522
89751
  }
89523
- if (server2.registered && server2.packageExportsTui === false && tui.hasNamedTuiEntry) {
89752
+ const hasKnownBrokenNamedTuiEntry = server2.packageExportsTui === false && tui.hasNamedTuiEntry;
89753
+ const hasUninspectableCanonicalTuiEntry = server2.packageExportsTui === null && tui.hasCanonicalNamedTuiEntry;
89754
+ if (server2.registered && (hasKnownBrokenNamedTuiEntry || hasUninspectableCanonicalTuiEntry)) {
89755
+ const exportStatus = server2.packageExportsTui === null ? `could not be inspected for a "${TUI_EXPORT_SUBPATH}" export` : `does not export "${TUI_EXPORT_SUBPATH}"`;
89524
89756
  issues.push({
89525
89757
  title: "TUI plugin entry in tui.json is unresolvable",
89526
- description: `The installed ${PLUGIN_NAME} package registered in opencode.json does not export ` + `"${TUI_EXPORT_SUBPATH}", but tui.json contains "${PLUGIN_NAME}/${TUI_SUBPATH}". ` + "OpenCode TUI may try to resolve that package subpath as a GitHub repository and fail.",
89758
+ description: `The installed ${PLUGIN_NAME} package registered in opencode.json ${exportStatus}, ` + `but tui.json contains "${PLUGIN_NAME}/${TUI_SUBPATH}". ` + "OpenCode TUI may try to resolve that package subpath as a GitHub repository and fail.",
89527
89759
  fix: `Remove "${PLUGIN_NAME}/${TUI_SUBPATH}" or "${LEGACY_PLUGIN_NAME}/${TUI_SUBPATH}" from the "plugin" array in ${tui.configPath}.`,
89528
89760
  affects: ["TUI startup", "plugin loading"],
89529
89761
  severity: "warning"
@@ -89841,6 +90073,390 @@ async function pathExists2(path16) {
89841
90073
  throw error51;
89842
90074
  }
89843
90075
  }
90076
+
90077
+ // packages/omo-opencode/src/cli/doctor/checks/codex-components.ts
90078
+ import { statSync as statSync6 } from "fs";
90079
+ import { readdir as readdir9, readFile as readFile19, stat as stat4 } from "fs/promises";
90080
+ import { homedir as homedir19 } from "os";
90081
+ import { dirname as dirname25, join as join67, relative as relative8, resolve as resolve16, sep as sep8 } from "path";
90082
+ var CODEX_COMPONENTS_CHECK_ID = "codex-components";
90083
+ var CODEX_COMPONENTS_CHECK_NAME = "codex-components";
90084
+ var SG_PATH_ENV_KEY = "OMO_AST_GREP_SG_PATH";
90085
+ var PLUGIN_DATA_DIR_NAME = "omo-sisyphuslabs";
90086
+ var BOOTSTRAP_PENDING_MESSAGE = "bootstrap pending \u2014 start a Codex session";
90087
+ var HOMEBREW_SG_PATHS = ["/opt/homebrew/bin/sg", "/usr/local/bin/sg"];
90088
+ var WINDOWS_EXECUTABLE_EXTENSIONS = [".exe", ".cmd", ".bat"];
90089
+ var MIN_BINARY_SIZE_BYTES = 1e4;
90090
+ var REINSTALL_FIX = "Reinstall: npx lazycodex-ai install (or upgrade: codex plugin marketplace upgrade sisyphuslabs)";
90091
+ async function checkCodexComponents(deps = {}) {
90092
+ const env = deps.env ?? process.env;
90093
+ const platform = deps.platform ?? process.platform;
90094
+ const arch = deps.arch ?? process.arch;
90095
+ const codexHome = resolve16(deps.codexHome ?? env["CODEX_HOME"] ?? join67(homedir19(), ".codex"));
90096
+ const summary = await gatherCodexSummary({ ...deps, codexHome });
90097
+ if (summary.pluginRoot === null) {
90098
+ return {
90099
+ name: CODEX_COMPONENTS_CHECK_NAME,
90100
+ status: "skip",
90101
+ message: "OMO Codex plugin is not installed \u2014 skipping component checks",
90102
+ details: [`plugin root: not installed under ${codexHome}`],
90103
+ issues: []
90104
+ };
90105
+ }
90106
+ const issues = [];
90107
+ const details = [`plugin root: ${summary.pluginRoot}`];
90108
+ const { referencedCount, broken } = await auditBundleTargets(summary.pluginRoot);
90109
+ details.push(broken.length === 0 ? `dist targets: ok (${referencedCount} referenced)` : `dist targets: ${broken.length} of ${referencedCount} referenced target(s) broken`);
90110
+ for (const target of broken) {
90111
+ issues.push({
90112
+ title: `Missing plugin dist target: ${target.relativePath}`,
90113
+ description: `Referenced by ${target.referencedBy} but ${target.reason === "missing" ? "missing from" : "zero bytes in"} the installed plugin bundle.`,
90114
+ fix: REINSTALL_FIX,
90115
+ severity: "error",
90116
+ affects: [target.referencedBy.endsWith(".mcp.json") ? "MCP servers" : "plugin hooks"]
90117
+ });
90118
+ }
90119
+ const runtimeSgPath = runtimeDirSgPath(codexHome, platform, arch);
90120
+ const sg = resolveSgBinary({
90121
+ env,
90122
+ platform,
90123
+ runtimeSgPath,
90124
+ pluginRoot: summary.pluginRoot,
90125
+ arch,
90126
+ resolveModulePath: deps.resolveModulePath ?? defaultResolveModulePath
90127
+ });
90128
+ if (sg === null) {
90129
+ details.push("ast_grep: missing");
90130
+ issues.push({
90131
+ title: "ast_grep (sg) binary is missing",
90132
+ description: `sg was not found via the ${SG_PATH_ENV_KEY} override, the Codex runtime dir (${runtimeSgPath}), the bundled @ast-grep/cli packages, or Homebrew. The ast_grep MCP server runs degraded until it is provisioned.`,
90133
+ fix: "Start a Codex session so the LazyCodex bootstrap can provision sg, then rerun: npx lazycodex-ai doctor",
90134
+ severity: "warning",
90135
+ affects: ["ast_grep MCP"]
90136
+ });
90137
+ } else {
90138
+ details.push(`ast_grep: ok (${sg.source}: ${sg.path})`);
90139
+ }
90140
+ const state2 = await readBootstrapStateSummary(codexHome);
90141
+ details.push(...bootstrapDetails(state2, summary.pluginVersion));
90142
+ const status = issues.some((issue2) => issue2.severity === "error") ? "fail" : issues.length > 0 ? "warn" : "pass";
90143
+ return {
90144
+ name: CODEX_COMPONENTS_CHECK_NAME,
90145
+ status,
90146
+ message: status === "pass" ? "Codex component checks passed" : `${issues.length} Codex component issue(s) detected`,
90147
+ details,
90148
+ issues
90149
+ };
90150
+ }
90151
+ async function auditBundleTargets(pluginRoot) {
90152
+ const broken = [];
90153
+ let referencedCount = 0;
90154
+ for (const manifestPath of await findManifestPaths(pluginRoot, ".mcp.json")) {
90155
+ const manifest = await readJson2(manifestPath);
90156
+ if (manifest === null || !isRecord21(manifest["mcpServers"]))
90157
+ continue;
90158
+ const manifestRoot = dirname25(manifestPath);
90159
+ const isRootManifest = resolve16(manifestRoot) === resolve16(pluginRoot);
90160
+ for (const server2 of Object.values(manifest["mcpServers"])) {
90161
+ if (!isRecord21(server2) || !Array.isArray(server2["args"]))
90162
+ continue;
90163
+ for (const arg of server2["args"]) {
90164
+ if (typeof arg !== "string" || !isPluginRuntimePathArg(arg))
90165
+ continue;
90166
+ referencedCount += 1;
90167
+ recordBrokenTarget(broken, await classifyBundleTarget(pluginRoot, manifestRoot, arg, !isRootManifest), {
90168
+ referencedBy: normalizeRelative(pluginRoot, manifestPath)
90169
+ });
90170
+ }
90171
+ }
90172
+ }
90173
+ for (const hookManifestPath of await findHookManifestPaths(pluginRoot)) {
90174
+ const manifest = await readJson2(hookManifestPath);
90175
+ if (manifest === null)
90176
+ continue;
90177
+ const commands2 = [];
90178
+ collectHookCommands(manifest, commands2);
90179
+ const hookPluginRoot = dirname25(dirname25(hookManifestPath));
90180
+ for (const command of commands2) {
90181
+ for (const relativePath of extractPluginRootPaths(command)) {
90182
+ referencedCount += 1;
90183
+ const baseRoot = relativePath.startsWith("components/") ? pluginRoot : hookPluginRoot;
90184
+ recordBrokenTarget(broken, await classifyBundleTarget(pluginRoot, baseRoot, relativePath, false), {
90185
+ referencedBy: normalizeRelative(pluginRoot, hookManifestPath)
90186
+ });
90187
+ }
90188
+ }
90189
+ }
90190
+ return { referencedCount, broken };
90191
+ }
90192
+ function recordBrokenTarget(broken, classified, origin) {
90193
+ if (classified === null)
90194
+ return;
90195
+ const entry = { ...classified, referencedBy: origin.referencedBy };
90196
+ if (broken.some((existing) => existing.relativePath === entry.relativePath && existing.reason === entry.reason))
90197
+ return;
90198
+ broken.push(entry);
90199
+ }
90200
+ async function classifyBundleTarget(bundleRoot, baseRoot, relativePath, allowEscape) {
90201
+ const targetPath = resolve16(baseRoot, relativePath);
90202
+ const bundleRootPath = resolve16(bundleRoot);
90203
+ const bundleRootPrefix = bundleRootPath.endsWith(sep8) ? bundleRootPath : `${bundleRootPath}${sep8}`;
90204
+ if (targetPath !== bundleRootPath && !targetPath.startsWith(bundleRootPrefix)) {
90205
+ if (allowEscape)
90206
+ return null;
90207
+ return { relativePath: normalizePathSeparators(relativePath), reason: "missing" };
90208
+ }
90209
+ const size = await fileSize(targetPath);
90210
+ if (size === undefined)
90211
+ return { relativePath: normalizeRelative(bundleRoot, targetPath), reason: "missing" };
90212
+ if (size === 0)
90213
+ return { relativePath: normalizeRelative(bundleRoot, targetPath), reason: "zero bytes" };
90214
+ return null;
90215
+ }
90216
+ async function findHookManifestPaths(root) {
90217
+ const paths = await findManifestPaths(root, "hooks.json");
90218
+ return paths.filter((path16) => dirname25(path16).endsWith(`${sep8}hooks`));
90219
+ }
90220
+ async function findManifestPaths(root, manifestName) {
90221
+ let entries;
90222
+ try {
90223
+ entries = await readdir9(root, { withFileTypes: true });
90224
+ } catch {
90225
+ return [];
90226
+ }
90227
+ const paths = [];
90228
+ for (const entry of entries) {
90229
+ if (entry.name === "node_modules" || entry.name === ".git")
90230
+ continue;
90231
+ const entryPath = join67(root, entry.name);
90232
+ if (entry.isDirectory()) {
90233
+ paths.push(...await findManifestPaths(entryPath, manifestName));
90234
+ continue;
90235
+ }
90236
+ if (entry.isFile() && entry.name === manifestName)
90237
+ paths.push(entryPath);
90238
+ }
90239
+ return paths;
90240
+ }
90241
+ function collectHookCommands(value, commands2) {
90242
+ if (Array.isArray(value)) {
90243
+ for (const item of value)
90244
+ collectHookCommands(item, commands2);
90245
+ return;
90246
+ }
90247
+ if (!isRecord21(value))
90248
+ return;
90249
+ if (value["type"] === "command") {
90250
+ if (typeof value["command"] === "string")
90251
+ commands2.push(value["command"]);
90252
+ if (typeof value["commandWindows"] === "string")
90253
+ commands2.push(value["commandWindows"]);
90254
+ }
90255
+ for (const child of Object.values(value))
90256
+ collectHookCommands(child, commands2);
90257
+ }
90258
+ function extractPluginRootPaths(command) {
90259
+ const paths = [];
90260
+ const pluginRootPathPattern = /\$\{PLUGIN_ROOT\}([\\/][^"'\s]+)/g;
90261
+ let match = pluginRootPathPattern.exec(command);
90262
+ while (match) {
90263
+ const rawPath = match[1];
90264
+ if (rawPath)
90265
+ paths.push(normalizePathSeparators(rawPath).replace(/^\//, ""));
90266
+ match = pluginRootPathPattern.exec(command);
90267
+ }
90268
+ return paths;
90269
+ }
90270
+ function isPluginRuntimePathArg(arg) {
90271
+ return (arg.startsWith("./") || arg.startsWith("../")) && arg.endsWith("/dist/cli.js");
90272
+ }
90273
+ function resolveSgBinary(options) {
90274
+ const override = nonEmptyValue2(options.env[SG_PATH_ENV_KEY]);
90275
+ if (override !== undefined) {
90276
+ const overridePath = findValidExecutable(override, options.platform);
90277
+ if (overridePath !== null)
90278
+ return { path: overridePath, source: `env override ${SG_PATH_ENV_KEY}` };
90279
+ }
90280
+ const runtimePath = findValidExecutable(options.runtimeSgPath, options.platform);
90281
+ if (runtimePath !== null)
90282
+ return { path: runtimePath, source: "runtime dir" };
90283
+ const moduleContext = join67(options.pluginRoot, "components", "ast-grep-mcp", "dist", "cli.js");
90284
+ const cliPackagePath = tryResolveModulePath(options.resolveModulePath, "@ast-grep/cli/package.json", moduleContext);
90285
+ if (cliPackagePath !== null) {
90286
+ const sgPath = findValidExecutable(join67(dirname25(cliPackagePath), "sg"), options.platform);
90287
+ if (sgPath !== null)
90288
+ return { path: sgPath, source: "@ast-grep/cli package" };
90289
+ }
90290
+ const platformPackage = platformPackageName(options.platform, options.arch);
90291
+ if (platformPackage !== null) {
90292
+ const packageJsonPath = tryResolveModulePath(options.resolveModulePath, `${platformPackage}/package.json`, moduleContext);
90293
+ if (packageJsonPath !== null) {
90294
+ const binaryPath = findValidExecutable(join67(dirname25(packageJsonPath), "ast-grep"), options.platform);
90295
+ if (binaryPath !== null)
90296
+ return { path: binaryPath, source: `${platformPackage} package` };
90297
+ }
90298
+ }
90299
+ if (options.platform === "darwin") {
90300
+ for (const homebrewPath of HOMEBREW_SG_PATHS) {
90301
+ if (isValidBinary(homebrewPath))
90302
+ return { path: homebrewPath, source: "Homebrew" };
90303
+ }
90304
+ }
90305
+ return null;
90306
+ }
90307
+ function runtimeDirSgPath(codexHome, platform, arch) {
90308
+ return join67(codexHome, "runtime", "ast-grep", `${platform}-${arch}`, platform === "win32" ? "sg.exe" : "sg");
90309
+ }
90310
+ function platformPackageName(platform, arch) {
90311
+ const platformMap = {
90312
+ "darwin-arm64": "@ast-grep/cli-darwin-arm64",
90313
+ "darwin-x64": "@ast-grep/cli-darwin-x64",
90314
+ "linux-arm64": "@ast-grep/cli-linux-arm64-gnu",
90315
+ "linux-x64": "@ast-grep/cli-linux-x64-gnu",
90316
+ "win32-x64": "@ast-grep/cli-win32-x64-msvc",
90317
+ "win32-arm64": "@ast-grep/cli-win32-arm64-msvc",
90318
+ "win32-ia32": "@ast-grep/cli-win32-ia32-msvc"
90319
+ };
90320
+ return platformMap[`${platform}-${arch}`] ?? null;
90321
+ }
90322
+ function defaultResolveModulePath(specifier, fromPath) {
90323
+ let current = dirname25(fromPath);
90324
+ for (;; ) {
90325
+ const candidate = join67(current, "node_modules", specifier);
90326
+ if (isExistingFile(candidate))
90327
+ return candidate;
90328
+ const parent = dirname25(current);
90329
+ if (parent === current)
90330
+ throw new Error(`Cannot find module '${specifier}'`);
90331
+ current = parent;
90332
+ }
90333
+ }
90334
+ function isExistingFile(path16) {
90335
+ try {
90336
+ return statSync6(path16).isFile();
90337
+ } catch {
90338
+ return false;
90339
+ }
90340
+ }
90341
+ function tryResolveModulePath(resolveModulePath, specifier, fromPath) {
90342
+ try {
90343
+ return resolveModulePath(specifier, fromPath);
90344
+ } catch {
90345
+ return null;
90346
+ }
90347
+ }
90348
+ function findValidExecutable(filePath, platform) {
90349
+ for (const candidate of executableCandidates(filePath, platform)) {
90350
+ if (isValidBinary(candidate))
90351
+ return candidate;
90352
+ }
90353
+ return null;
90354
+ }
90355
+ function executableCandidates(filePath, platform) {
90356
+ if (platform !== "win32")
90357
+ return [filePath];
90358
+ const candidates = [filePath];
90359
+ const lowerPath = filePath.toLowerCase();
90360
+ if (WINDOWS_EXECUTABLE_EXTENSIONS.some((extension) => lowerPath.endsWith(extension)))
90361
+ return candidates;
90362
+ for (const extension of WINDOWS_EXECUTABLE_EXTENSIONS)
90363
+ candidates.push(`${filePath}${extension}`);
90364
+ return candidates;
90365
+ }
90366
+ function nonEmptyValue2(value) {
90367
+ if (value === undefined)
90368
+ return;
90369
+ const trimmed = value.trim();
90370
+ return trimmed.length === 0 ? undefined : trimmed;
90371
+ }
90372
+ function isValidBinary(filePath) {
90373
+ try {
90374
+ const stats = statSync6(filePath);
90375
+ if (!stats.isFile())
90376
+ return false;
90377
+ const lowerPath = filePath.toLowerCase();
90378
+ if (lowerPath.endsWith(".cmd") || lowerPath.endsWith(".bat"))
90379
+ return stats.size > 0;
90380
+ return stats.size > MIN_BINARY_SIZE_BYTES;
90381
+ } catch {
90382
+ return false;
90383
+ }
90384
+ }
90385
+ async function readBootstrapStateSummary(codexHome) {
90386
+ const statePath = join67(codexHome, "plugins", "data", PLUGIN_DATA_DIR_NAME, "bootstrap", "state.json");
90387
+ const raw = await readJson2(statePath);
90388
+ if (raw === null)
90389
+ return null;
90390
+ const lastStatus = raw["lastStatus"] === "success" || raw["lastStatus"] === "degraded" ? raw["lastStatus"] : null;
90391
+ return {
90392
+ completedForVersion: typeof raw["completedForVersion"] === "string" ? raw["completedForVersion"] : null,
90393
+ lastStatus,
90394
+ degraded: parseDegradedEntries(raw["degraded"])
90395
+ };
90396
+ }
90397
+ function parseDegradedEntries(value) {
90398
+ if (!Array.isArray(value))
90399
+ return [];
90400
+ const entries = [];
90401
+ for (const item of value) {
90402
+ if (!isRecord21(item))
90403
+ continue;
90404
+ if (typeof item["component"] !== "string" || typeof item["reason"] !== "string")
90405
+ continue;
90406
+ entries.push({
90407
+ component: item["component"],
90408
+ reason: item["reason"],
90409
+ ...typeof item["hint"] === "string" ? { hint: item["hint"] } : {}
90410
+ });
90411
+ }
90412
+ return entries;
90413
+ }
90414
+ function bootstrapDetails(state2, installedVersion) {
90415
+ const installedLabel = installedVersion ?? "unknown";
90416
+ if (state2 === null || state2.lastStatus === null) {
90417
+ return [`${BOOTSTRAP_PENDING_MESSAGE} (installed ${installedLabel}, state none)`];
90418
+ }
90419
+ const completed = state2.completedForVersion;
90420
+ if (completed === null || completed !== installedVersion) {
90421
+ const lines2 = [`${BOOTSTRAP_PENDING_MESSAGE} (installed ${installedLabel}, state ${completed ?? "none"}, lastStatus=${state2.lastStatus})`];
90422
+ lines2.push(...degradedDetailLines(state2.degraded));
90423
+ return lines2;
90424
+ }
90425
+ const statusLabel = state2.lastStatus === "success" ? "completed" : "degraded";
90426
+ const lines = [`bootstrap: ${statusLabel}@${completed} (lastStatus=${state2.lastStatus})`];
90427
+ lines.push(...degradedDetailLines(state2.degraded));
90428
+ return lines;
90429
+ }
90430
+ function degradedDetailLines(entries) {
90431
+ return entries.map((entry) => `degraded component=${entry.component} reason=${entry.reason}${entry.hint === undefined ? "" : ` hint=${entry.hint}`}`);
90432
+ }
90433
+ async function readJson2(path16) {
90434
+ try {
90435
+ const parsed = JSON.parse(await readFile19(path16, "utf8"));
90436
+ return isRecord21(parsed) ? parsed : null;
90437
+ } catch (error51) {
90438
+ if (error51 instanceof Error)
90439
+ return null;
90440
+ throw error51;
90441
+ }
90442
+ }
90443
+ async function fileSize(path16) {
90444
+ try {
90445
+ const stats = await stat4(path16);
90446
+ return stats.isFile() ? stats.size : undefined;
90447
+ } catch {
90448
+ return;
90449
+ }
90450
+ }
90451
+ function normalizeRelative(root, target) {
90452
+ return normalizePathSeparators(relative8(root, target));
90453
+ }
90454
+ function normalizePathSeparators(path16) {
90455
+ return path16.split("\\").join("/");
90456
+ }
90457
+ function isRecord21(value) {
90458
+ return typeof value === "object" && value !== null && !Array.isArray(value);
90459
+ }
89844
90460
  // packages/omo-opencode/src/cli/doctor/checks/index.ts
89845
90461
  function getAllCheckDefinitions() {
89846
90462
  return [
@@ -89884,6 +90500,11 @@ function getCodexCheckDefinitions() {
89884
90500
  name: CHECK_NAMES[CHECK_IDS.CODEX],
89885
90501
  check: checkCodex,
89886
90502
  critical: true
90503
+ },
90504
+ {
90505
+ id: CODEX_COMPONENTS_CHECK_ID,
90506
+ name: CODEX_COMPONENTS_CHECK_NAME,
90507
+ check: checkCodexComponents
89887
90508
  }
89888
90509
  ];
89889
90510
  }
@@ -90254,6 +90875,10 @@ async function runDoctor(options) {
90254
90875
  }
90255
90876
  return doctorResult;
90256
90877
  }
90878
+
90879
+ // packages/omo-opencode/src/cli/doctor/index.ts
90880
+ init_shared();
90881
+
90257
90882
  // packages/omo-opencode/src/cli/doctor/doctor-target.ts
90258
90883
  function resolveDoctorTarget(invocationName) {
90259
90884
  return invocationName === "lazycodex" || invocationName === "lazycodex-ai" ? "codex" : "opencode";
@@ -90278,7 +90903,7 @@ Doctor failed unexpectedly: ${message}`];
90278
90903
  if (error51 instanceof Error && error51.stack) {
90279
90904
  lines.push(error51.stack);
90280
90905
  }
90281
- lines.push(`Try: OMO_DISABLE_POSTHOG=1 bunx oh-my-opencode doctor --verbose
90906
+ lines.push(`Try: OMO_DISABLE_POSTHOG=1 bunx ${PUBLISHED_PACKAGE_NAME} doctor --verbose
90282
90907
  `);
90283
90908
  return lines;
90284
90909
  }
@@ -90286,10 +90911,10 @@ Doctor failed unexpectedly: ${message}`];
90286
90911
  // packages/omo-opencode/src/features/mcp-oauth/storage.ts
90287
90912
  init_shared();
90288
90913
  import { chmodSync as chmodSync2, existsSync as existsSync54, mkdirSync as mkdirSync14, readFileSync as readFileSync40, renameSync as renameSync6, unlinkSync as unlinkSync8, writeFileSync as writeFileSync10 } from "fs";
90289
- import { dirname as dirname25, join as join67 } from "path";
90914
+ import { dirname as dirname26, join as join68 } from "path";
90290
90915
  var STORAGE_FILE_NAME = "mcp-oauth.json";
90291
90916
  function getMcpOauthStoragePath() {
90292
- return join67(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
90917
+ return join68(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
90293
90918
  }
90294
90919
  function normalizeHost2(serverHost) {
90295
90920
  let host = serverHost.trim();
@@ -90343,7 +90968,7 @@ function readStore() {
90343
90968
  function writeStore(store2) {
90344
90969
  const filePath = getMcpOauthStoragePath();
90345
90970
  try {
90346
- const dir = dirname25(filePath);
90971
+ const dir = dirname26(filePath);
90347
90972
  if (!existsSync54(dir)) {
90348
90973
  mkdirSync14(dir, { recursive: true });
90349
90974
  }
@@ -90556,7 +91181,7 @@ async function getOrRegisterClient(options) {
90556
91181
  }
90557
91182
  }
90558
91183
  function parseRegistrationResponse(data) {
90559
- if (!isRecord21(data))
91184
+ if (!isRecord22(data))
90560
91185
  return null;
90561
91186
  const clientId = data.client_id;
90562
91187
  if (typeof clientId !== "string" || clientId.length === 0)
@@ -90567,7 +91192,7 @@ function parseRegistrationResponse(data) {
90567
91192
  }
90568
91193
  return { clientId };
90569
91194
  }
90570
- function isRecord21(value) {
91195
+ function isRecord22(value) {
90571
91196
  return typeof value === "object" && value !== null;
90572
91197
  }
90573
91198
 
@@ -90608,7 +91233,7 @@ function buildAuthorizationUrl(authorizationEndpoint, options) {
90608
91233
  }
90609
91234
  var CALLBACK_TIMEOUT_MS = 5 * 60 * 1000;
90610
91235
  function startCallbackServer(port) {
90611
- return new Promise((resolve16, reject) => {
91236
+ return new Promise((resolve17, reject) => {
90612
91237
  let timeoutId;
90613
91238
  const server2 = createServer2((request, response) => {
90614
91239
  clearTimeout(timeoutId);
@@ -90634,7 +91259,7 @@ function startCallbackServer(port) {
90634
91259
  response.writeHead(200, { "content-type": "text/html" });
90635
91260
  response.end("<html><body><h1>Authorization successful. You can close this tab.</h1></body></html>");
90636
91261
  server2.close();
90637
- resolve16({ code, state: state2 });
91262
+ resolve17({ code, state: state2 });
90638
91263
  });
90639
91264
  timeoutId = setTimeout(() => {
90640
91265
  server2.close();
@@ -91132,16 +91757,16 @@ async function boulder(options) {
91132
91757
  }
91133
91758
  // packages/omo-opencode/src/cli/codex-ulw-loop.ts
91134
91759
  import { spawn as spawn3 } from "child_process";
91135
- import { existsSync as existsSync56, readdirSync as readdirSync7, realpathSync as realpathSync8 } from "fs";
91136
- import { homedir as homedir19 } from "os";
91137
- import { join as join68 } from "path";
91760
+ import { existsSync as existsSync56, readdirSync as readdirSync8, realpathSync as realpathSync8 } from "fs";
91761
+ import { homedir as homedir20 } from "os";
91762
+ import { join as join69 } from "path";
91138
91763
  function resolveCodexUlwLoopCommand(input = {}) {
91139
91764
  const env = input.env ?? process.env;
91140
- const homeDir = input.homeDir ?? homedir19();
91765
+ const homeDir = input.homeDir ?? homedir20();
91141
91766
  const localComponentBin = resolveLocalUlwLoopBin(env, homeDir);
91142
91767
  if (localComponentBin !== null)
91143
91768
  return { executable: localComponentBin, argsPrefix: [] };
91144
- const componentCli = resolveNewestCachedUlwLoopCli(env.CODEX_HOME ?? join68(homeDir, ".codex"));
91769
+ const componentCli = resolveNewestCachedUlwLoopCli(env.CODEX_HOME ?? join69(homeDir, ".codex"));
91145
91770
  if (componentCli !== null)
91146
91771
  return { executable: process.execPath, argsPrefix: [componentCli] };
91147
91772
  const legacyLocalBin = resolveLegacyLocalOmoBin(env, homeDir, input.currentExecutablePaths ?? [process.argv[1]].filter((value) => typeof value === "string"));
@@ -91155,28 +91780,28 @@ async function codexUlwLoop(args) {
91155
91780
  console.error("Codex ulw-loop is not installed. Run: npx lazycodex-ai@latest install --no-tui");
91156
91781
  return 1;
91157
91782
  }
91158
- return new Promise((resolve16) => {
91783
+ return new Promise((resolve17) => {
91159
91784
  const child = spawn3(command.executable, [...command.argsPrefix, ...args], { stdio: "inherit" });
91160
91785
  child.on("error", (error51) => {
91161
91786
  console.error(error51.message);
91162
- resolve16(1);
91787
+ resolve17(1);
91163
91788
  });
91164
- child.on("close", (code) => resolve16(code ?? 1));
91789
+ child.on("close", (code) => resolve17(code ?? 1));
91165
91790
  });
91166
91791
  }
91167
91792
  function resolveLocalUlwLoopBin(env, homeDir) {
91168
91793
  const candidates = [
91169
- env.CODEX_LOCAL_BIN_DIR ? join68(env.CODEX_LOCAL_BIN_DIR, "omo-ulw-loop") : undefined,
91170
- join68(homeDir, ".local", "bin", "omo-ulw-loop"),
91171
- join68(homeDir, ".codex", "bin", "omo-ulw-loop")
91794
+ env.CODEX_LOCAL_BIN_DIR ? join69(env.CODEX_LOCAL_BIN_DIR, "omo-ulw-loop") : undefined,
91795
+ join69(homeDir, ".local", "bin", "omo-ulw-loop"),
91796
+ join69(homeDir, ".codex", "bin", "omo-ulw-loop")
91172
91797
  ].filter((value) => typeof value === "string");
91173
91798
  return candidates.find((candidate) => existsSync56(candidate)) ?? null;
91174
91799
  }
91175
91800
  function resolveLegacyLocalOmoBin(env, homeDir, currentExecutablePaths) {
91176
91801
  const candidates = [
91177
- env.CODEX_LOCAL_BIN_DIR ? join68(env.CODEX_LOCAL_BIN_DIR, "omo") : undefined,
91178
- join68(homeDir, ".local", "bin", "omo"),
91179
- join68(homeDir, ".codex", "bin", "omo")
91802
+ env.CODEX_LOCAL_BIN_DIR ? join69(env.CODEX_LOCAL_BIN_DIR, "omo") : undefined,
91803
+ join69(homeDir, ".local", "bin", "omo"),
91804
+ join69(homeDir, ".codex", "bin", "omo")
91180
91805
  ].filter((value) => typeof value === "string");
91181
91806
  return candidates.find((candidate) => existsSync56(candidate) && !isCurrentExecutable(candidate, currentExecutablePaths)) ?? null;
91182
91807
  }
@@ -91194,12 +91819,12 @@ function realpathOrSelf(path16) {
91194
91819
  }
91195
91820
  }
91196
91821
  function resolveNewestCachedUlwLoopCli(codexHome) {
91197
- const versionsRoot = join68(codexHome, "plugins", "cache", "sisyphuslabs", "omo");
91822
+ const versionsRoot = join69(codexHome, "plugins", "cache", "sisyphuslabs", "omo");
91198
91823
  if (!existsSync56(versionsRoot))
91199
91824
  return null;
91200
- const versions2 = readdirSync7(versionsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareVersionNames).reverse();
91825
+ const versions2 = readdirSync8(versionsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareVersionNames).reverse();
91201
91826
  for (const version3 of versions2) {
91202
- const candidate = join68(versionsRoot, version3, "components", "ulw-loop", "dist", "cli.js");
91827
+ const candidate = join69(versionsRoot, version3, "components", "ulw-loop", "dist", "cli.js");
91203
91828
  if (existsSync56(candidate))
91204
91829
  return candidate;
91205
91830
  }
@@ -91253,12 +91878,12 @@ async function refreshModelCapabilities(options, deps = {}) {
91253
91878
  // packages/omo-opencode/src/cli/sparkshell.ts
91254
91879
  import { spawnSync as spawnSync4 } from "child_process";
91255
91880
  import { constants as osConstants } from "os";
91256
- import { isAbsolute as isAbsolute9, resolve as resolve16 } from "path";
91881
+ import { isAbsolute as isAbsolute9, resolve as resolve17 } from "path";
91257
91882
 
91258
91883
  // packages/omo-opencode/src/cli/sparkshell-appserver.ts
91259
91884
  import { existsSync as existsSync57 } from "fs";
91260
- import { homedir as homedir20 } from "os";
91261
- import { join as join69 } from "path";
91885
+ import { homedir as homedir21 } from "os";
91886
+ import { join as join70 } from "path";
91262
91887
 
91263
91888
  // packages/omo-opencode/src/cli/sparkshell-appserver-websocket.ts
91264
91889
  import { randomBytes as randomBytes3 } from "crypto";
@@ -91419,8 +92044,8 @@ function resolveAppServerSocketPath(env) {
91419
92044
  if (explicit) {
91420
92045
  return explicit;
91421
92046
  }
91422
- const codexHome = env["CODEX_HOME"]?.trim() || join69(homedir20(), ".codex");
91423
- return join69(codexHome, "app-server-control", "app-server-control.sock");
92047
+ const codexHome = env["CODEX_HOME"]?.trim() || join70(homedir21(), ".codex");
92048
+ return join70(codexHome, "app-server-control", "app-server-control.sock");
91424
92049
  }
91425
92050
  function resolveAppServerTimeoutMs(env) {
91426
92051
  const parsed = Number.parseInt(env["OMO_SPARKSHELL_APP_SERVER_TIMEOUT_MS"]?.trim() ?? "", 10);
@@ -91520,7 +92145,7 @@ async function withTimeout(promise2, timeoutMs, label) {
91520
92145
  }
91521
92146
  function parseJsonRpcResponse(text) {
91522
92147
  const parsed = JSON.parse(text);
91523
- if (!isRecord22(parsed)) {
92148
+ if (!isRecord23(parsed)) {
91524
92149
  return { kind: "other" };
91525
92150
  }
91526
92151
  return {
@@ -91536,17 +92161,17 @@ function parseResponseId(value) {
91536
92161
  return typeof value === "string" || typeof value === "number" ? value : undefined;
91537
92162
  }
91538
92163
  function parseResponseError(value) {
91539
- if (!isRecord22(value)) {
92164
+ if (!isRecord23(value)) {
91540
92165
  return;
91541
92166
  }
91542
92167
  const message = value["message"];
91543
92168
  return { message: typeof message === "string" ? message : undefined };
91544
92169
  }
91545
- function isRecord22(value) {
92170
+ function isRecord23(value) {
91546
92171
  return typeof value === "object" && value !== null;
91547
92172
  }
91548
92173
  function parseInitializeResult(value) {
91549
- if (!isRecord22(value)) {
92174
+ if (!isRecord23(value)) {
91550
92175
  return {};
91551
92176
  }
91552
92177
  return {
@@ -91555,7 +92180,7 @@ function parseInitializeResult(value) {
91555
92180
  };
91556
92181
  }
91557
92182
  function parseCommandExecResult(value) {
91558
- if (!isRecord22(value)) {
92183
+ if (!isRecord23(value)) {
91559
92184
  return {};
91560
92185
  }
91561
92186
  return {
@@ -91991,9 +92616,9 @@ function isLowSurrogate(codeUnit) {
91991
92616
  }
91992
92617
 
91993
92618
  // packages/omo-opencode/src/cli/sparkshell-session-context.ts
91994
- import { existsSync as existsSync58, readdirSync as readdirSync8, readFileSync as readFileSync41 } from "fs";
91995
- import { homedir as homedir21 } from "os";
91996
- import { join as join70 } from "path";
92619
+ import { existsSync as existsSync58, readdirSync as readdirSync9, readFileSync as readFileSync41 } from "fs";
92620
+ import { homedir as homedir22 } from "os";
92621
+ import { join as join71 } from "path";
91997
92622
  var SPARKSHELL_SESSION_CONTEXT_ENV = "OMO_SPARKSHELL_SESSION_CONTEXT";
91998
92623
  var SPARKSHELL_SESSION_ID_ENV = "OMO_SPARKSHELL_SESSION_ID";
91999
92624
  var CODEX_THREAD_ID_ENV = "CODEX_THREAD_ID";
@@ -92007,10 +92632,10 @@ function resolveCodexSessionId(env) {
92007
92632
  }
92008
92633
  function findRolloutPath(sessionId, env, deps = {}) {
92009
92634
  const fileExists = deps.fileExists ?? existsSync58;
92010
- const listDirectory = deps.listDirectory ?? ((path16) => readdirSync8(path16));
92011
- const homeDirectory = deps.homeDirectory ?? homedir21;
92012
- const codexHome = env["CODEX_HOME"]?.trim() || join70(homeDirectory(), ".codex");
92013
- const roots = [join70(codexHome, "sessions"), join70(codexHome, "archived_sessions")];
92635
+ const listDirectory = deps.listDirectory ?? ((path16) => readdirSync9(path16));
92636
+ const homeDirectory = deps.homeDirectory ?? homedir22;
92637
+ const codexHome = env["CODEX_HOME"]?.trim() || join71(homeDirectory(), ".codex");
92638
+ const roots = [join71(codexHome, "sessions"), join71(codexHome, "archived_sessions")];
92014
92639
  const fileSuffix = `-${sessionId}.jsonl`;
92015
92640
  const scanDay = (dayDir) => {
92016
92641
  if (!fileExists(dayDir)) {
@@ -92018,14 +92643,14 @@ function findRolloutPath(sessionId, env, deps = {}) {
92018
92643
  }
92019
92644
  for (const name of listSafely(listDirectory, dayDir)) {
92020
92645
  if (name.startsWith("rollout-") && name.endsWith(fileSuffix)) {
92021
- return join70(dayDir, name);
92646
+ return join71(dayDir, name);
92022
92647
  }
92023
92648
  }
92024
92649
  return null;
92025
92650
  };
92026
92651
  for (const dayDir of uuidV7DayDirCandidates(sessionId)) {
92027
92652
  for (const root of roots) {
92028
- const found = scanDay(join70(root, dayDir));
92653
+ const found = scanDay(join71(root, dayDir));
92029
92654
  if (found) {
92030
92655
  return found;
92031
92656
  }
@@ -92036,9 +92661,9 @@ function findRolloutPath(sessionId, env, deps = {}) {
92036
92661
  continue;
92037
92662
  }
92038
92663
  for (const year of numericNamesDescending(listSafely(listDirectory, root))) {
92039
- for (const month of numericNamesDescending(listSafely(listDirectory, join70(root, year)))) {
92040
- for (const day of numericNamesDescending(listSafely(listDirectory, join70(root, year, month)))) {
92041
- const found = scanDay(join70(root, year, month, day));
92664
+ for (const month of numericNamesDescending(listSafely(listDirectory, join71(root, year)))) {
92665
+ for (const day of numericNamesDescending(listSafely(listDirectory, join71(root, year, month)))) {
92666
+ const found = scanDay(join71(root, year, month, day));
92042
92667
  if (found) {
92043
92668
  return found;
92044
92669
  }
@@ -92100,7 +92725,7 @@ function extractSessionContext(rolloutText) {
92100
92725
  } catch {
92101
92726
  continue;
92102
92727
  }
92103
- if (!isRecord23(parsed) || !isRecord23(parsed["payload"])) {
92728
+ if (!isRecord24(parsed) || !isRecord24(parsed["payload"])) {
92104
92729
  continue;
92105
92730
  }
92106
92731
  const payload = parsed["payload"];
@@ -92198,7 +92823,7 @@ function uuidV7DayDirCandidates(sessionId) {
92198
92823
  const candidates = [];
92199
92824
  for (const offsetDays of [0, 1, -1]) {
92200
92825
  const date5 = new Date(ms + offsetDays * DAY_MS);
92201
- candidates.push(join70(String(date5.getFullYear()), pad2(date5.getMonth() + 1), pad2(date5.getDate())));
92826
+ candidates.push(join71(String(date5.getFullYear()), pad2(date5.getMonth() + 1), pad2(date5.getDate())));
92202
92827
  }
92203
92828
  return candidates;
92204
92829
  }
@@ -92228,7 +92853,7 @@ ${text.slice(text.length - tailLength)}`;
92228
92853
  function readString2(value) {
92229
92854
  return typeof value === "string" ? value : "";
92230
92855
  }
92231
- function isRecord23(value) {
92856
+ function isRecord24(value) {
92232
92857
  return typeof value === "object" && value !== null;
92233
92858
  }
92234
92859
  function isFalsy2(value) {
@@ -92242,7 +92867,7 @@ function isFalsy2(value) {
92242
92867
  import { spawnSync as spawnSync3 } from "child_process";
92243
92868
  import { mkdtempSync, readFileSync as readFileSync42, rmSync as rmSync4 } from "fs";
92244
92869
  import { tmpdir as tmpdir4 } from "os";
92245
- import { join as join71 } from "path";
92870
+ import { join as join72 } from "path";
92246
92871
  var SPARKSHELL_SPARK_ENV = "OMO_SPARKSHELL_SPARK";
92247
92872
  var SPARKSHELL_SPARK_MODEL_ENV = "OMO_SPARKSHELL_SPARK_MODEL";
92248
92873
  var SPARKSHELL_SPARK_TIMEOUT_ENV = "OMO_SPARKSHELL_SPARK_TIMEOUT_MS";
@@ -92315,8 +92940,8 @@ function buildSparkExecArgs(env, lastMessagePath) {
92315
92940
  function createDefaultSparkSummarizer(env, cwd) {
92316
92941
  return (request) => {
92317
92942
  const binary = env[SPARKSHELL_SPARK_BIN_ENV]?.trim() || "codex";
92318
- const tempDir = mkdtempSync(join71(tmpdir4(), "omo-sparkshell-spark-"));
92319
- const lastMessagePath = join71(tempDir, "last-message.txt");
92943
+ const tempDir = mkdtempSync(join72(tmpdir4(), "omo-sparkshell-spark-"));
92944
+ const lastMessagePath = join72(tempDir, "last-message.txt");
92320
92945
  try {
92321
92946
  const result = spawnSync3(binary, [...buildSparkExecArgs(env, lastMessagePath)], {
92322
92947
  cwd,
@@ -92519,7 +93144,7 @@ function resolveNativeBinaryOverride(env, cwd) {
92519
93144
  if (override.length === 0) {
92520
93145
  return "";
92521
93146
  }
92522
- return isAbsolute9(override) || /^[A-Za-z]:[\\/]/.test(override) ? override : resolve16(cwd, override);
93147
+ return isAbsolute9(override) || /^[A-Za-z]:[\\/]/.test(override) ? override : resolve17(cwd, override);
92523
93148
  }
92524
93149
  async function runAppServerCommand(args, appServerClient, options) {
92525
93150
  let invocation;
@@ -92602,6 +93227,10 @@ function runSpawnedCommand(spawn4, command, args, options, writeStdout, writeStd
92602
93227
  }
92603
93228
  writeStderr(`[sparkshell] failed to launch ${command}: ${result.error.message}
92604
93229
  `);
93230
+ if (isSpawnNotFoundError(result.error) && hasShellMetacharacters(command)) {
93231
+ writeStderr(`[sparkshell] '${command}' looks like a shell command; re-run with: omo sparkshell --shell '${command}'
93232
+ `);
93233
+ }
92605
93234
  return 1;
92606
93235
  }
92607
93236
  if (typeof result.status === "number") {
@@ -92612,6 +93241,13 @@ function runSpawnedCommand(spawn4, command, args, options, writeStdout, writeStd
92612
93241
  function isCaptureOverflowError(error51) {
92613
93242
  return error51.code === "ENOBUFS";
92614
93243
  }
93244
+ function isSpawnNotFoundError(error51) {
93245
+ return error51.code === "ENOENT";
93246
+ }
93247
+ var SHELL_METACHARACTER_PATTERN = /(\s&&\s|\s\|\|\s|[|;<>]|\$\(|`)/;
93248
+ function hasShellMetacharacters(command) {
93249
+ return SHELL_METACHARACTER_PATTERN.test(command);
93250
+ }
92615
93251
  function signalExitCode(signal) {
92616
93252
  if (!signal) {
92617
93253
  return 1;
@@ -92644,6 +93280,7 @@ function defaultSpawn(command, args, options) {
92644
93280
 
92645
93281
  // packages/omo-opencode/src/cli/runtime-commands.ts
92646
93282
  init_shared();
93283
+ init_package();
92647
93284
  var VERSION2 = package_default.version;
92648
93285
  function configureRuntimeCommands(program2) {
92649
93286
  program2.command("refresh-model-capabilities").description("Refresh the cached models.dev-based model capabilities snapshot").option("-d, --directory <path>", "Working directory to read oh-my-opencode config from").option("--source-url <url>", "Override the models.dev source URL").option("--json", "Output refresh summary as JSON").action(async (options) => {
@@ -92676,6 +93313,7 @@ function configureRuntimeCommands(program2) {
92676
93313
  }
92677
93314
 
92678
93315
  // packages/omo-opencode/src/cli/cli-program.ts
93316
+ init_package();
92679
93317
  var VERSION3 = package_default.version;
92680
93318
  var program2 = new Command;
92681
93319
  function resolveInstallArgs(options, invocationName = process.env.OMO_INVOCATION_NAME) {