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