oh-my-opencode 4.12.1 → 4.13.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 (539) hide show
  1. package/README.md +1 -1
  2. package/THIRD-PARTY-NOTICES.md +1 -1
  3. package/dist/agents/sisyphus-agent-factory.d.ts +9 -0
  4. package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +31 -0
  5. package/dist/cli/index.js +896 -669
  6. package/dist/cli-node/index.js +896 -669
  7. package/dist/config/schema/codegraph.d.ts +1 -0
  8. package/dist/config/schema/oh-my-opencode-config.d.ts +2 -0
  9. package/dist/config/schema/runtime-fallback.d.ts +1 -0
  10. package/dist/features/background-agent/background-task-marker.d.ts +8 -0
  11. package/dist/features/background-agent/fallback-retry-handler.d.ts +1 -0
  12. package/dist/features/background-agent/manager.d.ts +1 -0
  13. package/dist/features/background-agent/parent-wake-dedupe.d.ts +1 -0
  14. package/dist/features/background-agent/parent-wake-notifier-types.d.ts +2 -0
  15. package/dist/features/background-agent/parent-wake-notifier.d.ts +1 -0
  16. package/dist/features/background-agent/parent-wake-window-recovery.d.ts +2 -0
  17. package/dist/hooks/runtime-fallback/auto-retry-dispatch.d.ts +2 -2
  18. package/dist/hooks/runtime-fallback/auto-retry-timeout.d.ts +2 -2
  19. package/dist/hooks/runtime-fallback/auto-retry.d.ts +1 -1
  20. package/dist/hooks/runtime-fallback/fallback-state-snapshot.d.ts +13 -0
  21. package/dist/hooks/runtime-fallback/types.d.ts +8 -0
  22. package/dist/index.js +708 -413
  23. package/dist/oh-my-opencode.schema.json +8 -0
  24. package/dist/plugin/runtime-skill-resolver.d.ts +35 -0
  25. package/dist/plugin/skill-context.d.ts +9 -0
  26. package/dist/skills/frontend/ATTRIBUTION.md +32 -8
  27. package/dist/skills/frontend/references/design/airbnb.md +3 -0
  28. package/dist/skills/frontend/references/design/airtable.md +3 -0
  29. package/dist/skills/frontend/references/design/apple.md +3 -0
  30. package/dist/skills/frontend/references/design/binance.md +3 -0
  31. package/dist/skills/frontend/references/design/bmw.md +3 -0
  32. package/dist/skills/frontend/references/design/bugatti.md +3 -0
  33. package/dist/skills/frontend/references/design/cal.md +3 -0
  34. package/dist/skills/frontend/references/design/claude.md +3 -0
  35. package/dist/skills/frontend/references/design/clay.md +3 -0
  36. package/dist/skills/frontend/references/design/clickhouse.md +3 -0
  37. package/dist/skills/frontend/references/design/cohere.md +3 -0
  38. package/dist/skills/frontend/references/design/coinbase.md +3 -0
  39. package/dist/skills/frontend/references/design/composio.md +3 -0
  40. package/dist/skills/frontend/references/design/cursor.md +3 -0
  41. package/dist/skills/frontend/references/design/elevenlabs.md +3 -0
  42. package/dist/skills/frontend/references/design/expo.md +3 -0
  43. package/dist/skills/frontend/references/design/ferrari.md +3 -0
  44. package/dist/skills/frontend/references/design/figma.md +3 -0
  45. package/dist/skills/frontend/references/design/framer.md +3 -0
  46. package/dist/skills/frontend/references/design/hashicorp.md +3 -0
  47. package/dist/skills/frontend/references/design/ibm.md +3 -0
  48. package/dist/skills/frontend/references/design/imagegen-frontend-web.md +380 -79
  49. package/dist/skills/frontend/references/design/intercom.md +3 -0
  50. package/dist/skills/frontend/references/design/kraken.md +3 -0
  51. package/dist/skills/frontend/references/design/lamborghini.md +3 -0
  52. package/dist/skills/frontend/references/design/linear.app.md +3 -0
  53. package/dist/skills/frontend/references/design/lovable.md +3 -0
  54. package/dist/skills/frontend/references/design/mastercard.md +3 -0
  55. package/dist/skills/frontend/references/design/meta.md +3 -0
  56. package/dist/skills/frontend/references/design/minimax.md +3 -0
  57. package/dist/skills/frontend/references/design/mintlify.md +3 -0
  58. package/dist/skills/frontend/references/design/miro.md +3 -0
  59. package/dist/skills/frontend/references/design/mistral.ai.md +3 -0
  60. package/dist/skills/frontend/references/design/mongodb.md +3 -0
  61. package/dist/skills/frontend/references/design/nike.md +3 -0
  62. package/dist/skills/frontend/references/design/notion.md +3 -0
  63. package/dist/skills/frontend/references/design/nvidia.md +3 -0
  64. package/dist/skills/frontend/references/design/ollama.md +3 -0
  65. package/dist/skills/frontend/references/design/opencode.ai.md +3 -0
  66. package/dist/skills/frontend/references/design/pinterest.md +3 -0
  67. package/dist/skills/frontend/references/design/playstation.md +3 -0
  68. package/dist/skills/frontend/references/design/posthog.md +3 -0
  69. package/dist/skills/frontend/references/design/raycast.md +3 -0
  70. package/dist/skills/frontend/references/design/renault.md +3 -0
  71. package/dist/skills/frontend/references/design/replicate.md +3 -0
  72. package/dist/skills/frontend/references/design/resend.md +3 -0
  73. package/dist/skills/frontend/references/design/revolut.md +3 -0
  74. package/dist/skills/frontend/references/design/runwayml.md +3 -0
  75. package/dist/skills/frontend/references/design/sanity.md +3 -0
  76. package/dist/skills/frontend/references/design/sentry.md +3 -0
  77. package/dist/skills/frontend/references/design/shopify.md +3 -0
  78. package/dist/skills/frontend/references/design/spacex.md +3 -0
  79. package/dist/skills/frontend/references/design/spotify.md +3 -0
  80. package/dist/skills/frontend/references/design/starbucks.md +3 -0
  81. package/dist/skills/frontend/references/design/stitch-skill.md +1 -1
  82. package/dist/skills/frontend/references/design/stripe.md +3 -0
  83. package/dist/skills/frontend/references/design/supabase.md +3 -0
  84. package/dist/skills/frontend/references/design/superhuman.md +3 -0
  85. package/dist/skills/frontend/references/design/taste-skill.md +1188 -208
  86. package/dist/skills/frontend/references/design/tesla.md +3 -0
  87. package/dist/skills/frontend/references/design/theverge.md +3 -0
  88. package/dist/skills/frontend/references/design/together.ai.md +3 -0
  89. package/dist/skills/frontend/references/design/uber.md +3 -0
  90. package/dist/skills/frontend/references/design/vercel.md +3 -0
  91. package/dist/skills/frontend/references/design/vodafone.md +3 -0
  92. package/dist/skills/frontend/references/design/voltagent.md +3 -0
  93. package/dist/skills/frontend/references/design/warp.md +3 -0
  94. package/dist/skills/frontend/references/design/webflow.md +3 -0
  95. package/dist/skills/frontend/references/design/wired.md +3 -0
  96. package/dist/skills/frontend/references/design/wise.md +3 -0
  97. package/dist/skills/frontend/references/design/x.ai.md +3 -0
  98. package/dist/skills/frontend/references/design/zapier.md +3 -0
  99. package/dist/skills/frontend/references/ui-ux-db/README.md +501 -115
  100. package/dist/skills/frontend/references/ui-ux-db/data/charts.csv +26 -26
  101. package/dist/skills/frontend/references/ui-ux-db/data/colors.csv +162 -97
  102. package/dist/skills/frontend/references/ui-ux-db/data/icons.csv +105 -100
  103. package/dist/skills/frontend/references/ui-ux-db/data/landing.csv +22 -18
  104. package/dist/skills/frontend/references/ui-ux-db/data/products.csv +162 -97
  105. package/dist/skills/frontend/references/ui-ux-db/data/stacks/flutter.csv +53 -53
  106. package/dist/skills/frontend/references/ui-ux-db/data/stacks/html-tailwind.csv +56 -56
  107. package/dist/skills/frontend/references/ui-ux-db/data/stacks/nextjs.csv +53 -53
  108. package/dist/skills/frontend/references/ui-ux-db/data/stacks/react.csv +54 -54
  109. package/dist/skills/frontend/references/ui-ux-db/data/stacks/svelte.csv +54 -54
  110. package/dist/skills/frontend/references/ui-ux-db/data/stacks/swiftui.csv +51 -51
  111. package/dist/skills/frontend/references/ui-ux-db/data/stacks/vue.csv +50 -50
  112. package/dist/skills/frontend/references/ui-ux-db/data/styles.csv +17 -0
  113. package/dist/skills/frontend/references/ui-ux-db/data/typography.csv +17 -1
  114. package/dist/skills/frontend/references/ui-ux-db/data/ui-reasoning.csv +162 -101
  115. package/dist/skills/frontend/references/ui-ux-db/data/web-interface.csv +30 -30
  116. package/dist/skills/frontend/references/ui-ux-db/scripts/core.py +31 -22
  117. package/dist/skills/frontend/references/ui-ux-db/scripts/design_system.py +150 -69
  118. package/dist/skills/frontend/references/ui-ux-db/scripts/search.py +3 -3
  119. package/dist/skills/lcx-doctor/SKILL.md +1 -1
  120. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +105 -0
  121. package/dist/skills/ultimate-browsing/SKILL.md +140 -0
  122. package/dist/skills/ultimate-browsing/engine/__init__.py +24 -0
  123. package/dist/skills/ultimate-browsing/engine/__main__.py +106 -0
  124. package/dist/skills/ultimate-browsing/engine/bias_check.py +174 -0
  125. package/dist/skills/ultimate-browsing/engine/curl_probe.py +91 -0
  126. package/dist/skills/ultimate-browsing/engine/executor.py +192 -0
  127. package/dist/skills/ultimate-browsing/engine/fetch_chain.py +268 -0
  128. package/dist/skills/ultimate-browsing/engine/referers.py +15 -0
  129. package/dist/skills/ultimate-browsing/engine/result_schema.py +45 -0
  130. package/dist/skills/ultimate-browsing/engine/summary.py +37 -0
  131. package/dist/skills/ultimate-browsing/engine/templates/package.json +11 -0
  132. package/dist/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +129 -0
  133. package/dist/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +167 -0
  134. package/dist/skills/ultimate-browsing/engine/tests/test_fetch_chain.py +77 -0
  135. package/dist/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +282 -0
  136. package/dist/skills/ultimate-browsing/engine/url_transforms.py +98 -0
  137. package/dist/skills/ultimate-browsing/engine/validators.py +216 -0
  138. package/dist/skills/ultimate-browsing/engine/waf_detector.py +214 -0
  139. package/dist/skills/ultimate-browsing/engine/waf_profiles.yaml +162 -0
  140. package/dist/skills/ultimate-browsing/references/agent-reach/README.md +79 -0
  141. package/dist/skills/ultimate-browsing/references/agent-reach/career.md +29 -0
  142. package/dist/skills/ultimate-browsing/references/agent-reach/dev.md +62 -0
  143. package/dist/skills/ultimate-browsing/references/agent-reach/search.md +33 -0
  144. package/dist/skills/ultimate-browsing/references/agent-reach/social.md +207 -0
  145. package/dist/skills/ultimate-browsing/references/agent-reach/video.md +115 -0
  146. package/dist/skills/ultimate-browsing/references/agent-reach/web.md +76 -0
  147. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +120 -0
  148. package/dist/skills/ultimate-browsing/references/insane-search/README.md +319 -0
  149. package/dist/skills/ultimate-browsing/references/insane-search/cache-archive.md +83 -0
  150. package/dist/skills/ultimate-browsing/references/insane-search/fallback.md +159 -0
  151. package/dist/skills/ultimate-browsing/references/insane-search/jina.md +130 -0
  152. package/dist/skills/ultimate-browsing/references/insane-search/json-api.md +133 -0
  153. package/dist/skills/ultimate-browsing/references/insane-search/media.md +123 -0
  154. package/dist/skills/ultimate-browsing/references/insane-search/metadata.md +116 -0
  155. package/dist/skills/ultimate-browsing/references/insane-search/naver.md +107 -0
  156. package/dist/skills/ultimate-browsing/references/insane-search/playwright.md +142 -0
  157. package/dist/skills/ultimate-browsing/references/insane-search/public-api.md +119 -0
  158. package/dist/skills/ultimate-browsing/references/insane-search/rss.md +123 -0
  159. package/dist/skills/ultimate-browsing/references/insane-search/tls-impersonate.md +186 -0
  160. package/dist/skills/ultimate-browsing/references/insane-search/twitter.md +104 -0
  161. package/dist/skills/ultimate-browsing/scripts/cookie_crypto.py +75 -0
  162. package/dist/skills/ultimate-browsing/scripts/cookie_domains.py +38 -0
  163. package/dist/skills/ultimate-browsing/scripts/cookie_paths.py +112 -0
  164. package/dist/skills/ultimate-browsing/scripts/extract_cookies.py +280 -0
  165. package/dist/skills/ultimate-browsing/scripts/tests/test_cookie_domain_filter.py +110 -0
  166. package/dist/skills/ultimate-browsing/scripts/tests/test_extract_cookies.py +245 -0
  167. package/dist/skills/ultraresearch/ATTRIBUTION.md +49 -0
  168. package/dist/skills/ultraresearch/SKILL.md +23 -4
  169. package/dist/skills/ulw-plan/SKILL.md +4 -1
  170. package/dist/tools/delegate-task/sync-task-deps.d.ts +8 -6
  171. package/dist/tools/skill-mcp/tools.d.ts +1 -1
  172. package/dist/tui.js +9 -1
  173. package/package.json +16 -14
  174. package/packages/omo-codex/THIRD-PARTY-NOTICES.md +27 -4
  175. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  176. package/packages/omo-codex/plugin/README.md +1 -1
  177. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +134 -42
  178. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  179. package/packages/omo-codex/plugin/components/codegraph/LICENSE +21 -0
  180. package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +2951 -0
  181. package/packages/omo-codex/plugin/components/codegraph/NOTICE +16 -0
  182. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +323 -39
  183. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +292 -19
  184. package/packages/omo-codex/plugin/components/codegraph/package.json +9 -3
  185. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +75 -0
  186. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +29 -13
  187. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +20 -7
  188. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +1 -243
  189. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +91 -0
  190. package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +1 -1
  191. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +68 -0
  192. package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +11 -1
  193. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +133 -0
  194. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +1 -113
  195. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +8 -1
  196. package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +63 -0
  197. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +106 -0
  198. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +150 -0
  199. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  200. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  201. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  202. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  203. package/packages/omo-codex/plugin/components/rules/dist/cli.js +3 -3
  204. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  205. package/packages/omo-codex/plugin/components/rules/src/sparkshell-awareness.ts +3 -3
  206. package/packages/omo-codex/plugin/components/rules/test/sparkshell-awareness.test.ts +33 -9
  207. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  208. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  209. package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +59 -32
  210. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-guide.mjs +17 -16
  211. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-state.mjs +70 -3
  212. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-worktree.mjs +113 -0
  213. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +63 -4
  214. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  215. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -1
  216. package/packages/omo-codex/plugin/components/ultrawork/directive.md +5 -4
  217. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  218. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +24 -3
  219. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  220. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +8 -7
  221. package/packages/omo-codex/plugin/components/ulw-loop/test/skill-contract.test.ts +1 -1
  222. package/packages/omo-codex/plugin/package-lock.json +112 -13
  223. package/packages/omo-codex/plugin/package.json +2 -2
  224. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +133 -0
  225. package/packages/omo-codex/plugin/scripts/auto-update-release-notes.mjs +135 -0
  226. package/packages/omo-codex/plugin/scripts/auto-update.mjs +33 -133
  227. package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +41 -0
  228. package/packages/omo-codex/plugin/shared/src/config-loader.ts +20 -2
  229. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +16 -0
  230. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +32 -8
  231. package/packages/omo-codex/plugin/skills/frontend/references/design/airbnb.md +3 -0
  232. package/packages/omo-codex/plugin/skills/frontend/references/design/airtable.md +3 -0
  233. package/packages/omo-codex/plugin/skills/frontend/references/design/apple.md +3 -0
  234. package/packages/omo-codex/plugin/skills/frontend/references/design/binance.md +3 -0
  235. package/packages/omo-codex/plugin/skills/frontend/references/design/bmw.md +3 -0
  236. package/packages/omo-codex/plugin/skills/frontend/references/design/bugatti.md +3 -0
  237. package/packages/omo-codex/plugin/skills/frontend/references/design/cal.md +3 -0
  238. package/packages/omo-codex/plugin/skills/frontend/references/design/claude.md +3 -0
  239. package/packages/omo-codex/plugin/skills/frontend/references/design/clay.md +3 -0
  240. package/packages/omo-codex/plugin/skills/frontend/references/design/clickhouse.md +3 -0
  241. package/packages/omo-codex/plugin/skills/frontend/references/design/cohere.md +3 -0
  242. package/packages/omo-codex/plugin/skills/frontend/references/design/coinbase.md +3 -0
  243. package/packages/omo-codex/plugin/skills/frontend/references/design/composio.md +3 -0
  244. package/packages/omo-codex/plugin/skills/frontend/references/design/cursor.md +3 -0
  245. package/packages/omo-codex/plugin/skills/frontend/references/design/elevenlabs.md +3 -0
  246. package/packages/omo-codex/plugin/skills/frontend/references/design/expo.md +3 -0
  247. package/packages/omo-codex/plugin/skills/frontend/references/design/ferrari.md +3 -0
  248. package/packages/omo-codex/plugin/skills/frontend/references/design/figma.md +3 -0
  249. package/packages/omo-codex/plugin/skills/frontend/references/design/framer.md +3 -0
  250. package/packages/omo-codex/plugin/skills/frontend/references/design/hashicorp.md +3 -0
  251. package/packages/omo-codex/plugin/skills/frontend/references/design/ibm.md +3 -0
  252. package/packages/omo-codex/plugin/skills/frontend/references/design/imagegen-frontend-web.md +380 -79
  253. package/packages/omo-codex/plugin/skills/frontend/references/design/intercom.md +3 -0
  254. package/packages/omo-codex/plugin/skills/frontend/references/design/kraken.md +3 -0
  255. package/packages/omo-codex/plugin/skills/frontend/references/design/lamborghini.md +3 -0
  256. package/packages/omo-codex/plugin/skills/frontend/references/design/linear.app.md +3 -0
  257. package/packages/omo-codex/plugin/skills/frontend/references/design/lovable.md +3 -0
  258. package/packages/omo-codex/plugin/skills/frontend/references/design/mastercard.md +3 -0
  259. package/packages/omo-codex/plugin/skills/frontend/references/design/meta.md +3 -0
  260. package/packages/omo-codex/plugin/skills/frontend/references/design/minimax.md +3 -0
  261. package/packages/omo-codex/plugin/skills/frontend/references/design/mintlify.md +3 -0
  262. package/packages/omo-codex/plugin/skills/frontend/references/design/miro.md +3 -0
  263. package/packages/omo-codex/plugin/skills/frontend/references/design/mistral.ai.md +3 -0
  264. package/packages/omo-codex/plugin/skills/frontend/references/design/mongodb.md +3 -0
  265. package/packages/omo-codex/plugin/skills/frontend/references/design/nike.md +3 -0
  266. package/packages/omo-codex/plugin/skills/frontend/references/design/notion.md +3 -0
  267. package/packages/omo-codex/plugin/skills/frontend/references/design/nvidia.md +3 -0
  268. package/packages/omo-codex/plugin/skills/frontend/references/design/ollama.md +3 -0
  269. package/packages/omo-codex/plugin/skills/frontend/references/design/opencode.ai.md +3 -0
  270. package/packages/omo-codex/plugin/skills/frontend/references/design/pinterest.md +3 -0
  271. package/packages/omo-codex/plugin/skills/frontend/references/design/playstation.md +3 -0
  272. package/packages/omo-codex/plugin/skills/frontend/references/design/posthog.md +3 -0
  273. package/packages/omo-codex/plugin/skills/frontend/references/design/raycast.md +3 -0
  274. package/packages/omo-codex/plugin/skills/frontend/references/design/renault.md +3 -0
  275. package/packages/omo-codex/plugin/skills/frontend/references/design/replicate.md +3 -0
  276. package/packages/omo-codex/plugin/skills/frontend/references/design/resend.md +3 -0
  277. package/packages/omo-codex/plugin/skills/frontend/references/design/revolut.md +3 -0
  278. package/packages/omo-codex/plugin/skills/frontend/references/design/runwayml.md +3 -0
  279. package/packages/omo-codex/plugin/skills/frontend/references/design/sanity.md +3 -0
  280. package/packages/omo-codex/plugin/skills/frontend/references/design/sentry.md +3 -0
  281. package/packages/omo-codex/plugin/skills/frontend/references/design/shopify.md +3 -0
  282. package/packages/omo-codex/plugin/skills/frontend/references/design/spacex.md +3 -0
  283. package/packages/omo-codex/plugin/skills/frontend/references/design/spotify.md +3 -0
  284. package/packages/omo-codex/plugin/skills/frontend/references/design/starbucks.md +3 -0
  285. package/packages/omo-codex/plugin/skills/frontend/references/design/stitch-skill.md +1 -1
  286. package/packages/omo-codex/plugin/skills/frontend/references/design/stripe.md +3 -0
  287. package/packages/omo-codex/plugin/skills/frontend/references/design/supabase.md +3 -0
  288. package/packages/omo-codex/plugin/skills/frontend/references/design/superhuman.md +3 -0
  289. package/packages/omo-codex/plugin/skills/frontend/references/design/taste-skill.md +1188 -208
  290. package/packages/omo-codex/plugin/skills/frontend/references/design/tesla.md +3 -0
  291. package/packages/omo-codex/plugin/skills/frontend/references/design/theverge.md +3 -0
  292. package/packages/omo-codex/plugin/skills/frontend/references/design/together.ai.md +3 -0
  293. package/packages/omo-codex/plugin/skills/frontend/references/design/uber.md +3 -0
  294. package/packages/omo-codex/plugin/skills/frontend/references/design/vercel.md +3 -0
  295. package/packages/omo-codex/plugin/skills/frontend/references/design/vodafone.md +3 -0
  296. package/packages/omo-codex/plugin/skills/frontend/references/design/voltagent.md +3 -0
  297. package/packages/omo-codex/plugin/skills/frontend/references/design/warp.md +3 -0
  298. package/packages/omo-codex/plugin/skills/frontend/references/design/webflow.md +3 -0
  299. package/packages/omo-codex/plugin/skills/frontend/references/design/wired.md +3 -0
  300. package/packages/omo-codex/plugin/skills/frontend/references/design/wise.md +3 -0
  301. package/packages/omo-codex/plugin/skills/frontend/references/design/x.ai.md +3 -0
  302. package/packages/omo-codex/plugin/skills/frontend/references/design/zapier.md +3 -0
  303. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/README.md +501 -115
  304. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/charts.csv +26 -26
  305. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/colors.csv +162 -97
  306. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/icons.csv +105 -100
  307. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/landing.csv +22 -18
  308. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/products.csv +162 -97
  309. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/flutter.csv +53 -53
  310. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/html-tailwind.csv +56 -56
  311. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/nextjs.csv +53 -53
  312. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/react.csv +54 -54
  313. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/svelte.csv +54 -54
  314. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/swiftui.csv +51 -51
  315. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/vue.csv +50 -50
  316. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/styles.csv +17 -0
  317. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/typography.csv +17 -1
  318. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/ui-reasoning.csv +162 -101
  319. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/web-interface.csv +30 -30
  320. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/core.py +31 -22
  321. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/design_system.py +150 -69
  322. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/search.py +3 -3
  323. package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +1 -1
  324. package/packages/omo-codex/plugin/skills/teammode/SKILL.md +59 -32
  325. package/packages/omo-codex/plugin/skills/teammode/scripts/team-guide.mjs +17 -16
  326. package/packages/omo-codex/plugin/skills/teammode/scripts/team-state.mjs +70 -3
  327. package/packages/omo-codex/plugin/skills/teammode/scripts/team-worktree.mjs +113 -0
  328. package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +63 -4
  329. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +105 -0
  330. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +140 -0
  331. package/packages/omo-codex/plugin/skills/ultimate-browsing/agents/openai.yaml +2 -0
  332. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/__init__.py +24 -0
  333. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/__main__.py +106 -0
  334. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/bias_check.py +174 -0
  335. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/curl_probe.py +91 -0
  336. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/executor.py +192 -0
  337. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/fetch_chain.py +268 -0
  338. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/referers.py +15 -0
  339. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/result_schema.py +45 -0
  340. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/summary.py +37 -0
  341. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +11 -0
  342. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +129 -0
  343. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +167 -0
  344. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_fetch_chain.py +77 -0
  345. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +282 -0
  346. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/url_transforms.py +98 -0
  347. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/validators.py +216 -0
  348. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/waf_detector.py +214 -0
  349. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/waf_profiles.yaml +162 -0
  350. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/README.md +79 -0
  351. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/career.md +29 -0
  352. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/dev.md +62 -0
  353. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/search.md +33 -0
  354. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/social.md +207 -0
  355. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/video.md +115 -0
  356. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/web.md +76 -0
  357. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +120 -0
  358. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +319 -0
  359. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/cache-archive.md +83 -0
  360. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/fallback.md +159 -0
  361. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/jina.md +130 -0
  362. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/json-api.md +133 -0
  363. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/media.md +123 -0
  364. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/metadata.md +116 -0
  365. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/naver.md +107 -0
  366. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/playwright.md +142 -0
  367. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/public-api.md +119 -0
  368. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/rss.md +123 -0
  369. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/tls-impersonate.md +186 -0
  370. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/twitter.md +104 -0
  371. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/cookie_crypto.py +75 -0
  372. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/cookie_domains.py +38 -0
  373. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/cookie_paths.py +112 -0
  374. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/extract_cookies.py +280 -0
  375. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/tests/test_cookie_domain_filter.py +110 -0
  376. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/tests/test_extract_cookies.py +245 -0
  377. package/packages/omo-codex/plugin/skills/ultraresearch/ATTRIBUTION.md +49 -0
  378. package/packages/omo-codex/plugin/skills/ultraresearch/SKILL.md +23 -4
  379. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +8 -7
  380. package/packages/omo-codex/plugin/test/aggregate-build.test.mjs +2 -1
  381. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +95 -0
  382. package/packages/omo-codex/plugin/test/auto-update-restart-notice.test.mjs +12 -3
  383. package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +76 -0
  384. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +1 -0
  385. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +87 -0
  386. package/packages/omo-codex/plugin/test/teammode-thread-title.test.mjs +169 -0
  387. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +246 -0
  388. package/packages/omo-codex/plugin/test/ultraresearch-skill-contract.test.mjs +30 -0
  389. package/packages/omo-codex/scripts/install-cli-args.test.mjs +1 -1
  390. package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +23 -0
  391. package/packages/omo-codex/scripts/install-delegated-command.test.mjs +76 -4
  392. package/packages/omo-codex/scripts/install-dist/install-local.mjs +520 -216
  393. package/packages/omo-codex/scripts/install-local-entrypoint.test.mjs +40 -3
  394. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +32 -8
  395. package/packages/shared-skills/skills/frontend/references/design/airbnb.md +3 -0
  396. package/packages/shared-skills/skills/frontend/references/design/airtable.md +3 -0
  397. package/packages/shared-skills/skills/frontend/references/design/apple.md +3 -0
  398. package/packages/shared-skills/skills/frontend/references/design/binance.md +3 -0
  399. package/packages/shared-skills/skills/frontend/references/design/bmw.md +3 -0
  400. package/packages/shared-skills/skills/frontend/references/design/bugatti.md +3 -0
  401. package/packages/shared-skills/skills/frontend/references/design/cal.md +3 -0
  402. package/packages/shared-skills/skills/frontend/references/design/claude.md +3 -0
  403. package/packages/shared-skills/skills/frontend/references/design/clay.md +3 -0
  404. package/packages/shared-skills/skills/frontend/references/design/clickhouse.md +3 -0
  405. package/packages/shared-skills/skills/frontend/references/design/cohere.md +3 -0
  406. package/packages/shared-skills/skills/frontend/references/design/coinbase.md +3 -0
  407. package/packages/shared-skills/skills/frontend/references/design/composio.md +3 -0
  408. package/packages/shared-skills/skills/frontend/references/design/cursor.md +3 -0
  409. package/packages/shared-skills/skills/frontend/references/design/elevenlabs.md +3 -0
  410. package/packages/shared-skills/skills/frontend/references/design/expo.md +3 -0
  411. package/packages/shared-skills/skills/frontend/references/design/ferrari.md +3 -0
  412. package/packages/shared-skills/skills/frontend/references/design/figma.md +3 -0
  413. package/packages/shared-skills/skills/frontend/references/design/framer.md +3 -0
  414. package/packages/shared-skills/skills/frontend/references/design/hashicorp.md +3 -0
  415. package/packages/shared-skills/skills/frontend/references/design/ibm.md +3 -0
  416. package/packages/shared-skills/skills/frontend/references/design/imagegen-frontend-web.md +380 -79
  417. package/packages/shared-skills/skills/frontend/references/design/intercom.md +3 -0
  418. package/packages/shared-skills/skills/frontend/references/design/kraken.md +3 -0
  419. package/packages/shared-skills/skills/frontend/references/design/lamborghini.md +3 -0
  420. package/packages/shared-skills/skills/frontend/references/design/linear.app.md +3 -0
  421. package/packages/shared-skills/skills/frontend/references/design/lovable.md +3 -0
  422. package/packages/shared-skills/skills/frontend/references/design/mastercard.md +3 -0
  423. package/packages/shared-skills/skills/frontend/references/design/meta.md +3 -0
  424. package/packages/shared-skills/skills/frontend/references/design/minimax.md +3 -0
  425. package/packages/shared-skills/skills/frontend/references/design/mintlify.md +3 -0
  426. package/packages/shared-skills/skills/frontend/references/design/miro.md +3 -0
  427. package/packages/shared-skills/skills/frontend/references/design/mistral.ai.md +3 -0
  428. package/packages/shared-skills/skills/frontend/references/design/mongodb.md +3 -0
  429. package/packages/shared-skills/skills/frontend/references/design/nike.md +3 -0
  430. package/packages/shared-skills/skills/frontend/references/design/notion.md +3 -0
  431. package/packages/shared-skills/skills/frontend/references/design/nvidia.md +3 -0
  432. package/packages/shared-skills/skills/frontend/references/design/ollama.md +3 -0
  433. package/packages/shared-skills/skills/frontend/references/design/opencode.ai.md +3 -0
  434. package/packages/shared-skills/skills/frontend/references/design/pinterest.md +3 -0
  435. package/packages/shared-skills/skills/frontend/references/design/playstation.md +3 -0
  436. package/packages/shared-skills/skills/frontend/references/design/posthog.md +3 -0
  437. package/packages/shared-skills/skills/frontend/references/design/raycast.md +3 -0
  438. package/packages/shared-skills/skills/frontend/references/design/renault.md +3 -0
  439. package/packages/shared-skills/skills/frontend/references/design/replicate.md +3 -0
  440. package/packages/shared-skills/skills/frontend/references/design/resend.md +3 -0
  441. package/packages/shared-skills/skills/frontend/references/design/revolut.md +3 -0
  442. package/packages/shared-skills/skills/frontend/references/design/runwayml.md +3 -0
  443. package/packages/shared-skills/skills/frontend/references/design/sanity.md +3 -0
  444. package/packages/shared-skills/skills/frontend/references/design/sentry.md +3 -0
  445. package/packages/shared-skills/skills/frontend/references/design/shopify.md +3 -0
  446. package/packages/shared-skills/skills/frontend/references/design/spacex.md +3 -0
  447. package/packages/shared-skills/skills/frontend/references/design/spotify.md +3 -0
  448. package/packages/shared-skills/skills/frontend/references/design/starbucks.md +3 -0
  449. package/packages/shared-skills/skills/frontend/references/design/stitch-skill.md +1 -1
  450. package/packages/shared-skills/skills/frontend/references/design/stripe.md +3 -0
  451. package/packages/shared-skills/skills/frontend/references/design/supabase.md +3 -0
  452. package/packages/shared-skills/skills/frontend/references/design/superhuman.md +3 -0
  453. package/packages/shared-skills/skills/frontend/references/design/taste-skill.md +1188 -208
  454. package/packages/shared-skills/skills/frontend/references/design/tesla.md +3 -0
  455. package/packages/shared-skills/skills/frontend/references/design/theverge.md +3 -0
  456. package/packages/shared-skills/skills/frontend/references/design/together.ai.md +3 -0
  457. package/packages/shared-skills/skills/frontend/references/design/uber.md +3 -0
  458. package/packages/shared-skills/skills/frontend/references/design/vercel.md +3 -0
  459. package/packages/shared-skills/skills/frontend/references/design/vodafone.md +3 -0
  460. package/packages/shared-skills/skills/frontend/references/design/voltagent.md +3 -0
  461. package/packages/shared-skills/skills/frontend/references/design/warp.md +3 -0
  462. package/packages/shared-skills/skills/frontend/references/design/webflow.md +3 -0
  463. package/packages/shared-skills/skills/frontend/references/design/wired.md +3 -0
  464. package/packages/shared-skills/skills/frontend/references/design/wise.md +3 -0
  465. package/packages/shared-skills/skills/frontend/references/design/x.ai.md +3 -0
  466. package/packages/shared-skills/skills/frontend/references/design/zapier.md +3 -0
  467. package/packages/shared-skills/skills/frontend/references/ui-ux-db/README.md +501 -115
  468. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/charts.csv +26 -26
  469. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/colors.csv +162 -97
  470. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/icons.csv +105 -100
  471. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/landing.csv +22 -18
  472. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/products.csv +162 -97
  473. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/flutter.csv +53 -53
  474. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/html-tailwind.csv +56 -56
  475. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/nextjs.csv +53 -53
  476. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/react.csv +54 -54
  477. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/svelte.csv +54 -54
  478. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/swiftui.csv +51 -51
  479. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/vue.csv +50 -50
  480. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/styles.csv +17 -0
  481. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/typography.csv +17 -1
  482. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/ui-reasoning.csv +162 -101
  483. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/web-interface.csv +30 -30
  484. package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/core.py +31 -22
  485. package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/design_system.py +150 -69
  486. package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/search.py +3 -3
  487. package/packages/shared-skills/skills/lcx-doctor/SKILL.md +1 -1
  488. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +105 -0
  489. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +140 -0
  490. package/packages/shared-skills/skills/ultimate-browsing/engine/__init__.py +24 -0
  491. package/packages/shared-skills/skills/ultimate-browsing/engine/__main__.py +106 -0
  492. package/packages/shared-skills/skills/ultimate-browsing/engine/bias_check.py +174 -0
  493. package/packages/shared-skills/skills/ultimate-browsing/engine/curl_probe.py +91 -0
  494. package/packages/shared-skills/skills/ultimate-browsing/engine/executor.py +192 -0
  495. package/packages/shared-skills/skills/ultimate-browsing/engine/fetch_chain.py +268 -0
  496. package/packages/shared-skills/skills/ultimate-browsing/engine/referers.py +15 -0
  497. package/packages/shared-skills/skills/ultimate-browsing/engine/result_schema.py +45 -0
  498. package/packages/shared-skills/skills/ultimate-browsing/engine/summary.py +37 -0
  499. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +11 -0
  500. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +129 -0
  501. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +167 -0
  502. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_fetch_chain.py +77 -0
  503. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +282 -0
  504. package/packages/shared-skills/skills/ultimate-browsing/engine/url_transforms.py +98 -0
  505. package/packages/shared-skills/skills/ultimate-browsing/engine/validators.py +216 -0
  506. package/packages/shared-skills/skills/ultimate-browsing/engine/waf_detector.py +214 -0
  507. package/packages/shared-skills/skills/ultimate-browsing/engine/waf_profiles.yaml +162 -0
  508. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/README.md +79 -0
  509. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/career.md +29 -0
  510. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/dev.md +62 -0
  511. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/search.md +33 -0
  512. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/social.md +207 -0
  513. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/video.md +115 -0
  514. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/web.md +76 -0
  515. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +120 -0
  516. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +319 -0
  517. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/cache-archive.md +83 -0
  518. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/fallback.md +159 -0
  519. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/jina.md +130 -0
  520. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/json-api.md +133 -0
  521. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/media.md +123 -0
  522. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/metadata.md +116 -0
  523. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/naver.md +107 -0
  524. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/playwright.md +142 -0
  525. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/public-api.md +119 -0
  526. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/rss.md +123 -0
  527. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/tls-impersonate.md +186 -0
  528. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/twitter.md +104 -0
  529. package/packages/shared-skills/skills/ultimate-browsing/scripts/cookie_crypto.py +75 -0
  530. package/packages/shared-skills/skills/ultimate-browsing/scripts/cookie_domains.py +38 -0
  531. package/packages/shared-skills/skills/ultimate-browsing/scripts/cookie_paths.py +112 -0
  532. package/packages/shared-skills/skills/ultimate-browsing/scripts/extract_cookies.py +280 -0
  533. package/packages/shared-skills/skills/ultimate-browsing/scripts/tests/test_cookie_domain_filter.py +110 -0
  534. package/packages/shared-skills/skills/ultimate-browsing/scripts/tests/test_extract_cookies.py +245 -0
  535. package/packages/shared-skills/skills/ultraresearch/ATTRIBUTION.md +49 -0
  536. package/packages/shared-skills/skills/ultraresearch/SKILL.md +23 -4
  537. package/packages/shared-skills/skills/ulw-plan/SKILL.md +4 -1
  538. package/packages/omo-codex/plugin/components/codegraph/dist/cli.d.ts +0 -2
  539. package/packages/omo-codex/plugin/components/codegraph/dist/serve.d.ts +0 -32
package/dist/index.js CHANGED
@@ -12901,7 +12901,16 @@ function resolveContainedPath2(baseDir, pathSegments) {
12901
12901
  return resolvedPath;
12902
12902
  }
12903
12903
  function resolveBaseDir(config) {
12904
- return config.base_dir ?? path14.join(homedir23(), ".omo");
12904
+ return expandHomeDirectory(config.base_dir ?? path14.join(homedir23(), ".omo"));
12905
+ }
12906
+ function expandHomeDirectory(directoryPath) {
12907
+ if (directoryPath === "~") {
12908
+ return homedir23();
12909
+ }
12910
+ if (directoryPath.startsWith("~/") || directoryPath.startsWith("~\\")) {
12911
+ return path14.join(homedir23(), directoryPath.slice(2));
12912
+ }
12913
+ return directoryPath;
12905
12914
  }
12906
12915
  function getTeamSpecPath(baseDir, teamName, scope, projectRoot) {
12907
12916
  return path14.join(getTeamDirectory(baseDir, teamName, scope, projectRoot), "config.json");
@@ -20468,20 +20477,38 @@ function ignoreStaleTeamSessionSweepFailure(error) {
20468
20477
  if (error instanceof Error)
20469
20478
  return;
20470
20479
  }
20480
+ function getTeamBackgroundTasks(bgMgr, runtimeState) {
20481
+ if (!runtimeState.leadSessionId)
20482
+ return [];
20483
+ const teamMessageMarkerPrefix = `team-create:${runtimeState.teamRunId}:`;
20484
+ return bgMgr.getTasksByParentSession(runtimeState.leadSessionId).filter((task) => task.teamRunId === runtimeState.teamRunId || task.parentMessageId?.startsWith(teamMessageMarkerPrefix));
20485
+ }
20471
20486
  async function deleteTeam(teamRunId, config, tmuxMgr, bgMgr, options, deps = defaultDeleteTeamDeps) {
20472
20487
  const runtimeState = await loadRuntimeState(teamRunId, config);
20473
20488
  const nonLeadMembers = runtimeState.members.filter((member) => member.agentType !== "leader");
20474
20489
  if (options?.force !== true && nonLeadMembers.some((member) => !DELETABLE_MEMBER_STATUSES.has(member.status))) {
20475
20490
  throw new Error("members still active");
20476
20491
  }
20477
- if (bgMgr && runtimeState.leadSessionId) {
20478
- const teamMessageMarkerPrefix = `team-create:${teamRunId}:`;
20479
- const teamTasks = bgMgr.getTasksByParentSession(runtimeState.leadSessionId).filter((task) => task.teamRunId === teamRunId || task.parentMessageId?.startsWith(teamMessageMarkerPrefix));
20492
+ const deletableTeamStatuses = options?.force === true ? FORCE_DELETABLE_TEAM_STATUSES : DELETABLE_TEAM_STATUSES;
20493
+ if (!deletableTeamStatuses.has(runtimeState.status)) {
20494
+ throw new Error(`team cannot be deleted from '${runtimeState.status}'`);
20495
+ }
20496
+ if (bgMgr) {
20497
+ const teamTasks = getTeamBackgroundTasks(bgMgr, runtimeState);
20498
+ if (options?.force !== true && teamTasks.some((task) => task.status !== undefined && ACTIVE_BACKGROUND_TASK_STATUSES3.has(task.status))) {
20499
+ throw new Error("members still active");
20500
+ }
20501
+ if (options?.force !== true) {
20502
+ return await deleteTeamResources(teamRunId, config, runtimeState, tmuxMgr, options, deps);
20503
+ }
20480
20504
  await Promise.all(teamTasks.map((task) => bgMgr.cancelTask(task.id, {
20481
20505
  source: "team-mode-delete",
20482
20506
  reason: `delete team ${teamRunId}`
20483
20507
  })));
20484
20508
  }
20509
+ return await deleteTeamResources(teamRunId, config, runtimeState, tmuxMgr, options, deps);
20510
+ }
20511
+ async function deleteTeamResources(teamRunId, config, runtimeState, tmuxMgr, options, deps = defaultDeleteTeamDeps) {
20485
20512
  if (options?.force === true) {
20486
20513
  await transitionRuntimeState(teamRunId, (currentRuntimeState) => ({
20487
20514
  ...currentRuntimeState,
@@ -20533,7 +20560,7 @@ async function deleteTeam(teamRunId, config, tmuxMgr, bgMgr, options, deps = def
20533
20560
  sweepStaleTeamSessions(new Set(activeTeams.map((team) => team.teamRunId))).catch(ignoreStaleTeamSessionSweepFailure);
20534
20561
  return { removedWorktrees, removedLayout };
20535
20562
  }
20536
- var defaultDeleteTeamDeps, DELETABLE_TEAM_STATUSES, FORCE_DELETABLE_TEAM_STATUSES, FORCE_COMPLETABLE_MEMBER_STATUSES, FORCE_BYPASS_DELETING_STATUSES;
20563
+ var defaultDeleteTeamDeps, DELETABLE_TEAM_STATUSES, FORCE_DELETABLE_TEAM_STATUSES, FORCE_COMPLETABLE_MEMBER_STATUSES, FORCE_BYPASS_DELETING_STATUSES, ACTIVE_BACKGROUND_TASK_STATUSES3;
20537
20564
  var init_delete_team = __esm(() => {
20538
20565
  init_logger2();
20539
20566
  init_layout4();
@@ -20565,6 +20592,7 @@ var init_delete_team = __esm(() => {
20565
20592
  "idle"
20566
20593
  ]);
20567
20594
  FORCE_BYPASS_DELETING_STATUSES = new Set(["creating", "orphaned"]);
20595
+ ACTIVE_BACKGROUND_TASK_STATUSES3 = new Set(["pending", "running"]);
20568
20596
  });
20569
20597
 
20570
20598
  // packages/omo-opencode/src/features/team-mode/deps.ts
@@ -22280,7 +22308,7 @@ function classifyRuntimeFallbackError(error) {
22280
22308
  if (errorName?.includes("providermodelnotfounderror") || errorName?.includes("modelnotfounderror") || errorName?.includes("unknownerror") && /model\s+not\s+found/i.test(message)) {
22281
22309
  return "model_not_found";
22282
22310
  }
22283
- if (errorName?.includes("quotaexceeded") || errorName?.includes("insufficientquota") || errorName?.includes("billingerror") || errorName?.includes("resourceexhausted") || /quota.?exceeded/i.test(message) || /exceeded.*quota/i.test(message) || /usage\s*quota/i.test(message) || /subscription.*quota/i.test(message) || /insufficient.?(?:quota|balance|funds?)/i.test(message) || /billing.?(?:hard.?)?limit/i.test(message) || /exhausted\s+your\s+capacity/i.test(message) || /resource.?exhausted/i.test(message) || /out\s+of\s+credits?/i.test(message) || /payment.?required/i.test(message) || /usage\s+limit/i.test(message) || /credit\s+balance.*too\s+low/i.test(message) || /limit\s+exhausted/i.test(message) || /\u4F7F\u7528\u4E0A\u9650/.test(message) || /\u8FBE\u5230.*\u9650\u5236/.test(message) || /\u989D\u5EA6.*\u4E0D\u8DB3/.test(message) || /\u4F59\u989D.*\u4E0D\u8DB3/.test(message) || /\u5DF2\u8017\u5C3D/.test(message) || isLocalizedQuotaExhaustionMessage(message)) {
22311
+ if (errorName?.includes("quotaexceeded") || errorName?.includes("insufficientquota") || errorName?.includes("billingerror") || errorName?.includes("resourceexhausted") || /quota.?exceeded/i.test(message) || /exceeded.*quota/i.test(message) || /usage\s*quota/i.test(message) || /subscription.?(?:quota|limit)/i.test(message) || /insufficient.?(?:quota|balance|funds?)/i.test(message) || /billing.?(?:hard.?)?limit/i.test(message) || /exhausted\s+your\s+capacity/i.test(message) || /resource.?exhausted/i.test(message) || /out\s+of\s+credits?/i.test(message) || /payment.?required/i.test(message) || /usage\s+limit/i.test(message) || /credit\s+balance.*too\s+low/i.test(message) || /limit\s+exhausted/i.test(message) || /\u4F7F\u7528\u4E0A\u9650/.test(message) || /\u8FBE\u5230.*\u9650\u5236/.test(message) || /\u989D\u5EA6.*\u4E0D\u8DB3/.test(message) || /\u4F59\u989D.*\u4E0D\u8DB3/.test(message) || /\u5DF2\u8017\u5C3D/.test(message) || isLocalizedQuotaExhaustionMessage(message)) {
22284
22312
  return "quota_exceeded";
22285
22313
  }
22286
22314
  return;
@@ -22306,6 +22334,14 @@ function isRuntimeFallbackRetryableError(error, retryOnErrors, options = {}) {
22306
22334
  }
22307
22335
  return RUNTIME_FALLBACK_RETRYABLE_ERROR_PATTERNS.some((pattern) => pattern.test(message));
22308
22336
  }
22337
+ // packages/model-core/src/provider-exhaustion-fallback-policy.ts
22338
+ function classifyProviderExhaustionFallbackSignal(error) {
22339
+ const runtimeFallbackErrorType = classifyRuntimeFallbackError(error);
22340
+ return runtimeFallbackErrorType === "quota_exceeded" ? runtimeFallbackErrorType : undefined;
22341
+ }
22342
+ function isProviderExhaustionFallbackEligible(error) {
22343
+ return classifyProviderExhaustionFallbackSignal(error) !== undefined;
22344
+ }
22309
22345
  // packages/model-core/src/runtime-fallback-model.ts
22310
22346
  function isRuntimeFallbackModelRecord(model) {
22311
22347
  if (typeof model !== "object" || model === null)
@@ -80782,7 +80818,7 @@ function getCachedVersion(options = {}) {
80782
80818
  // package.json
80783
80819
  var package_default = {
80784
80820
  name: "oh-my-opencode",
80785
- version: "4.12.1",
80821
+ version: "4.13.0",
80786
80822
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
80787
80823
  main: "./dist/index.js",
80788
80824
  types: "dist/index.d.ts",
@@ -80863,7 +80899,8 @@ var package_default = {
80863
80899
  "build:cli-node": "bun run script/build-cli-node.ts",
80864
80900
  "build:codex-install": "bun run script/build-codex-install.ts",
80865
80901
  "build:codex-plugin": "npm --prefix packages/omo-codex/plugin ci && bun run --cwd packages/omo-codex/plugin build",
80866
- "build:shared-skills-assets": "rm -rf dist/skills && cp -R packages/shared-skills/skills dist/skills",
80902
+ "build:materialize-frontend": "node packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs --strict",
80903
+ "build:shared-skills-assets": "bun run build:materialize-frontend && rm -rf dist/skills && cp -R packages/shared-skills/skills dist/skills",
80867
80904
  "build:lsp-tools-mcp": "npm --prefix packages/lsp-tools-mcp ci && npm --prefix packages/lsp-tools-mcp run build",
80868
80905
  "build:lsp-daemon": "npm --prefix packages/lsp-daemon ci && npm --prefix packages/lsp-daemon run build",
80869
80906
  "build:node-require-shim": "bun run script/patch-node-require-shim.ts",
@@ -80872,6 +80909,7 @@ var package_default = {
80872
80909
  "build:schema": "bun run script/build-schema.ts",
80873
80910
  "build:model-capabilities": "bun run script/build-model-capabilities.ts",
80874
80911
  clean: "rm -rf dist",
80912
+ prepack: "bun run build:materialize-frontend",
80875
80913
  prepare: "bun run build",
80876
80914
  postinstall: "node postinstall.mjs",
80877
80915
  prepublishOnly: "bun run clean && bun run build:lsp-tools-mcp && bun run build:lsp-daemon && bun run build",
@@ -80952,18 +80990,18 @@ var package_default = {
80952
80990
  typescript: "^6.0.3"
80953
80991
  },
80954
80992
  optionalDependencies: {
80955
- "oh-my-opencode-darwin-arm64": "4.12.1",
80956
- "oh-my-opencode-darwin-x64": "4.12.1",
80957
- "oh-my-opencode-darwin-x64-baseline": "4.12.1",
80958
- "oh-my-opencode-linux-arm64": "4.12.1",
80959
- "oh-my-opencode-linux-arm64-musl": "4.12.1",
80960
- "oh-my-opencode-linux-x64": "4.12.1",
80961
- "oh-my-opencode-linux-x64-baseline": "4.12.1",
80962
- "oh-my-opencode-linux-x64-musl": "4.12.1",
80963
- "oh-my-opencode-linux-x64-musl-baseline": "4.12.1",
80964
- "oh-my-opencode-windows-arm64": "4.12.1",
80965
- "oh-my-opencode-windows-x64": "4.12.1",
80966
- "oh-my-opencode-windows-x64-baseline": "4.12.1"
80993
+ "oh-my-opencode-darwin-arm64": "4.13.0",
80994
+ "oh-my-opencode-darwin-x64": "4.13.0",
80995
+ "oh-my-opencode-darwin-x64-baseline": "4.13.0",
80996
+ "oh-my-opencode-linux-arm64": "4.13.0",
80997
+ "oh-my-opencode-linux-arm64-musl": "4.13.0",
80998
+ "oh-my-opencode-linux-x64": "4.13.0",
80999
+ "oh-my-opencode-linux-x64-baseline": "4.13.0",
81000
+ "oh-my-opencode-linux-x64-musl": "4.13.0",
81001
+ "oh-my-opencode-linux-x64-musl-baseline": "4.13.0",
81002
+ "oh-my-opencode-windows-arm64": "4.13.0",
81003
+ "oh-my-opencode-windows-x64": "4.13.0",
81004
+ "oh-my-opencode-windows-x64-baseline": "4.13.0"
80967
81005
  },
80968
81006
  overrides: {
80969
81007
  hono: "^4.12.18",
@@ -82152,6 +82190,14 @@ async function resolveOrProvisionCommand(deps, config) {
82152
82190
  }
82153
82191
  async function runBootstrap(projectRoot, config, deps) {
82154
82192
  try {
82193
+ const autoInit = config.auto_init !== false;
82194
+ const codegraphPath = join75(projectRoot, ".codegraph");
82195
+ if (!autoInit && !existsSync65(codegraphPath)) {
82196
+ deps.log("[codegraph-bootstrap] CodeGraph auto_init disabled and .codegraph not present; skipping bootstrap", {
82197
+ projectRoot
82198
+ });
82199
+ return;
82200
+ }
82155
82201
  const command = await resolveOrProvisionCommand(deps, config);
82156
82202
  if (command === null) {
82157
82203
  deps.log("[codegraph-bootstrap] CodeGraph unavailable; skipping bootstrap", { projectRoot });
@@ -90449,7 +90495,7 @@ function findSlashCommandPartIndex(parts) {
90449
90495
  return -1;
90450
90496
  }
90451
90497
  // packages/omo-opencode/src/hooks/auto-slash-command/executor.ts
90452
- import { dirname as dirname28 } from "path";
90498
+ import { dirname as dirname29 } from "path";
90453
90499
 
90454
90500
  // packages/omo-opencode/src/shared/command-executor/resolve-commands-in-text.ts
90455
90501
  init_resolve_commands_in_text();
@@ -91241,6 +91287,14 @@ async function discoverGlobalAgentsSkills(homeDirectory = homedir26()) {
91241
91287
  return loadSkillsFromDir({ skillsDir: agentsGlobalDir, scope: "user" });
91242
91288
  }
91243
91289
  // packages/skills-loader-core/src/features/opencode-skill-loader/merger/builtin-skill-converter.ts
91290
+ import { existsSync as existsSync72 } from "fs";
91291
+ import { join as join89 } from "path";
91292
+ function resolveBuiltinSkillPath(builtin) {
91293
+ if (builtin.resolvedPath !== undefined)
91294
+ return builtin.resolvedPath;
91295
+ const sharedSkillPath = join89(sharedSkillsRootPath(), builtin.name);
91296
+ return existsSync72(sharedSkillPath) ? sharedSkillPath : undefined;
91297
+ }
91244
91298
  function builtinToLoadedSkill(builtin) {
91245
91299
  const definition = {
91246
91300
  name: builtin.name,
@@ -91259,13 +91313,14 @@ function builtinToLoadedSkill(builtin) {
91259
91313
  compatibility: builtin.compatibility,
91260
91314
  metadata: builtin.metadata,
91261
91315
  allowedTools: builtin.allowedTools,
91262
- mcpConfig: builtin.mcpConfig
91316
+ mcpConfig: builtin.mcpConfig,
91317
+ resolvedPath: resolveBuiltinSkillPath(builtin)
91263
91318
  };
91264
91319
  }
91265
91320
 
91266
91321
  // packages/skills-loader-core/src/features/opencode-skill-loader/merger/config-skill-entry-loader.ts
91267
91322
  init_src();
91268
- import { existsSync as existsSync72, readFileSync as readFileSync46 } from "fs";
91323
+ import { existsSync as existsSync73, readFileSync as readFileSync46 } from "fs";
91269
91324
  import { dirname as dirname26, isAbsolute as isAbsolute13, resolve as resolve22 } from "path";
91270
91325
  import { homedir as homedir27 } from "os";
91271
91326
  function resolveFilePath5(from, configDir) {
@@ -91284,7 +91339,7 @@ function resolveFilePath5(from, configDir) {
91284
91339
  }
91285
91340
  function loadSkillFromFile(filePath) {
91286
91341
  try {
91287
- if (!existsSync72(filePath))
91342
+ if (!existsSync73(filePath))
91288
91343
  return null;
91289
91344
  const content = readFileSync46(filePath, "utf-8");
91290
91345
  const { data, body } = parseFrontmatter(content);
@@ -92153,7 +92208,7 @@ playwright-cli close
92153
92208
  };
92154
92209
  // packages/skills-loader-core/src/features/builtin-skills/skill-file-loader.ts
92155
92210
  import { readFileSync as readFileSync47 } from "fs";
92156
- import { join as join89 } from "path";
92211
+ import { join as join90 } from "path";
92157
92212
  init_src();
92158
92213
  function createSharedSkillTemplateLoader(readFile9 = readFileSync47, skillsRootPath = sharedSkillsRootPath()) {
92159
92214
  const cache2 = new Map;
@@ -92162,7 +92217,7 @@ function createSharedSkillTemplateLoader(readFile9 = readFileSync47, skillsRootP
92162
92217
  if (cached !== undefined)
92163
92218
  return cached;
92164
92219
  try {
92165
- const { body } = parseFrontmatter(readFile9(join89(skillsRootPath, skillName, "SKILL.md"), "utf8"));
92220
+ const { body } = parseFrontmatter(readFile9(join90(skillsRootPath, skillName, "SKILL.md"), "utf8"));
92166
92221
  cache2.set(skillName, body);
92167
92222
  return body;
92168
92223
  } catch (error) {
@@ -93299,6 +93354,9 @@ var gitMasterSkill = {
93299
93354
  template: GIT_MASTER_TEMPLATE
93300
93355
  };
93301
93356
  // packages/skills-loader-core/src/features/builtin-skills/skills/dev-browser.ts
93357
+ import { dirname as dirname27, join as join91 } from "path";
93358
+ import { fileURLToPath as fileURLToPath6 } from "url";
93359
+ var CURRENT_DIR = dirname27(fileURLToPath6(import.meta.url));
93302
93360
  var devBrowserSkill = {
93303
93361
  name: "dev-browser",
93304
93362
  description: "Browser automation with persistent page state. Use when users ask to navigate websites, fill forms, take screenshots, extract web data, test web apps, or automate browser workflows. Trigger phrases include 'go to [url]', 'click on', 'fill out the form', 'take a screenshot', 'scrape', 'automate', 'test the website', 'log into', or any browser interaction request.",
@@ -93515,7 +93573,8 @@ console.log({
93515
93573
 
93516
93574
  await client.disconnect();
93517
93575
  EOF
93518
- \`\`\``
93576
+ \`\`\``,
93577
+ resolvedPath: join91(CURRENT_DIR, "..", "dev-browser")
93519
93578
  };
93520
93579
  // packages/skills-loader-core/src/features/builtin-skills/skills/review-work.ts
93521
93580
  var reviewWorkSkill = {
@@ -94516,7 +94575,7 @@ init_src();
94516
94575
  var import_picomatch2 = __toESM(require_picomatch2(), 1);
94517
94576
  import * as fs20 from "fs/promises";
94518
94577
  import { homedir as homedir28 } from "os";
94519
- import { dirname as dirname27, extname as extname2, isAbsolute as isAbsolute14, join as join90, relative as relative12 } from "path";
94578
+ import { dirname as dirname28, extname as extname2, isAbsolute as isAbsolute14, join as join92, relative as relative12 } from "path";
94520
94579
  var MAX_RECURSIVE_DEPTH = 10;
94521
94580
  function isHttpUrl(path17) {
94522
94581
  return path17.startsWith("http://") || path17.startsWith("https://");
@@ -94526,12 +94585,12 @@ function toAbsolutePath(path17, configDir) {
94526
94585
  return homedir28();
94527
94586
  }
94528
94587
  if (path17.startsWith("~/")) {
94529
- return join90(homedir28(), path17.slice(2));
94588
+ return join92(homedir28(), path17.slice(2));
94530
94589
  }
94531
94590
  if (isAbsolute14(path17)) {
94532
94591
  return path17;
94533
94592
  }
94534
- return join90(configDir, path17);
94593
+ return join92(configDir, path17);
94535
94594
  }
94536
94595
  function isMarkdownPath(path17) {
94537
94596
  return extname2(path17).toLowerCase() === ".md";
@@ -94571,13 +94630,13 @@ async function loadSourcePath(options) {
94571
94630
  return [];
94572
94631
  const loaded = await loadSkillFromPath({
94573
94632
  skillPath: realSourcePath,
94574
- resolvedPath: dirname27(realSourcePath),
94633
+ resolvedPath: dirname28(realSourcePath),
94575
94634
  defaultName: inferSkillNameFromFileName(realSourcePath),
94576
94635
  scope: "config"
94577
94636
  });
94578
94637
  if (!loaded)
94579
94638
  return [];
94580
- return filterByGlob([loaded], dirname27(realSourcePath), options.globPattern);
94639
+ return filterByGlob([loaded], dirname28(realSourcePath), options.globPattern);
94581
94640
  }
94582
94641
  if (!stat5.isDirectory())
94583
94642
  return [];
@@ -94658,8 +94717,8 @@ function readOpencodeConfigSkills(directory) {
94658
94717
  return { paths, urls };
94659
94718
  }
94660
94719
  // packages/omo-opencode/src/tools/slashcommand/command-discovery.ts
94661
- import { existsSync as existsSync74, readdirSync as readdirSync19, readFileSync as readFileSync50, statSync as statSync10 } from "fs";
94662
- import { basename as basename15, join as join92 } from "path";
94720
+ import { existsSync as existsSync75, readdirSync as readdirSync19, readFileSync as readFileSync50, statSync as statSync10 } from "fs";
94721
+ import { basename as basename15, join as join94 } from "path";
94663
94722
 
94664
94723
  // packages/omo-opencode/src/tools/slashcommand/command-discovery-deps.ts
94665
94724
  init_frontmatter2();
@@ -96219,7 +96278,7 @@ function loadBuiltinCommands(disabledCommands, options) {
96219
96278
  // packages/omo-opencode/src/tools/slashcommand/command-discovery.ts
96220
96279
  var NESTED_COMMAND_SEPARATOR = "/";
96221
96280
  function discoverCommandsFromDir(commandsDir, scope, prefix = "") {
96222
- if (!existsSync74(commandsDir))
96281
+ if (!existsSync75(commandsDir))
96223
96282
  return [];
96224
96283
  if (!statSync10(commandsDir).isDirectory()) {
96225
96284
  log2(`[command-discovery] Skipping non-directory path: ${commandsDir}`);
@@ -96234,12 +96293,12 @@ function discoverCommandsFromDir(commandsDir, scope, prefix = "") {
96234
96293
  if (entry.name.startsWith("."))
96235
96294
  continue;
96236
96295
  const nestedPrefix = prefix ? `${prefix}${NESTED_COMMAND_SEPARATOR}${entry.name}` : entry.name;
96237
- commands.push(...discoverCommandsFromDir(join92(commandsDir, entry.name), scope, nestedPrefix));
96296
+ commands.push(...discoverCommandsFromDir(join94(commandsDir, entry.name), scope, nestedPrefix));
96238
96297
  continue;
96239
96298
  }
96240
96299
  if (!isMarkdownFile(entry))
96241
96300
  continue;
96242
- const commandPath = join92(commandsDir, entry.name);
96301
+ const commandPath = join94(commandsDir, entry.name);
96243
96302
  const baseCommandName = basename15(entry.name, ".md");
96244
96303
  const commandName = prefix ? `${prefix}${NESTED_COMMAND_SEPARATOR}${baseCommandName}` : baseCommandName;
96245
96304
  try {
@@ -96298,8 +96357,8 @@ function deduplicateCommandInfosByName(commands) {
96298
96357
  return deduplicatedCommands;
96299
96358
  }
96300
96359
  function discoverCommandsSync(directory, options) {
96301
- const userCommandsDir = join92(getClaudeConfigDir(), "commands");
96302
- const projectCommandsDir = join92(directory ?? process.cwd(), ".claude", "commands");
96360
+ const userCommandsDir = join94(getClaudeConfigDir(), "commands");
96361
+ const projectCommandsDir = join94(directory ?? process.cwd(), ".claude", "commands");
96303
96362
  const opencodeGlobalDirs = getOpenCodeCommandDirs({ binary: "opencode" });
96304
96363
  const opencodeProjectDirs = findProjectOpencodeCommandDirs(directory ?? process.cwd());
96305
96364
  const userCommands = discoverCommandsFromDir(userCommandsDir, "user");
@@ -96403,7 +96462,7 @@ async function formatCommandTemplate(cmd, args) {
96403
96462
  if (!content && cmd.lazyContentLoader) {
96404
96463
  content = await cmd.lazyContentLoader.load();
96405
96464
  }
96406
- const commandDir = cmd.path ? dirname28(cmd.path) : process.cwd();
96465
+ const commandDir = cmd.path ? dirname29(cmd.path) : process.cwd();
96407
96466
  const withFileRefs = await resolveFileReferencesInText(content, commandDir);
96408
96467
  const resolvedContent = await resolveCommandsInText(withFileRefs);
96409
96468
  const resolvedArguments = args;
@@ -96787,7 +96846,7 @@ var NOTEPAD_DIR = "notepads";
96787
96846
  var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
96788
96847
  var PROMETHEUS_PLANS_DIR = ".omo/plans";
96789
96848
  // packages/boulder-state/src/top-level-task.ts
96790
- import { existsSync as existsSync75, readFileSync as readFileSync51 } from "fs";
96849
+ import { existsSync as existsSync76, readFileSync as readFileSync51 } from "fs";
96791
96850
  var TODO_HEADING_PATTERN = /^##\s+TODOs\b/i;
96792
96851
  var FINAL_VERIFICATION_HEADING_PATTERN = /^##\s+Final Verification Wave\b/i;
96793
96852
  var SECOND_LEVEL_HEADING_PATTERN = /^##\s+/;
@@ -96810,7 +96869,7 @@ function buildTaskRef(section, taskLabel) {
96810
96869
  };
96811
96870
  }
96812
96871
  function readCurrentTopLevelTask(planPath) {
96813
- if (!existsSync75(planPath)) {
96872
+ if (!existsSync76(planPath)) {
96814
96873
  return null;
96815
96874
  }
96816
96875
  try {
@@ -96839,10 +96898,10 @@ function readCurrentTopLevelTask(planPath) {
96839
96898
  }
96840
96899
  }
96841
96900
  // packages/boulder-state/src/storage/path.ts
96842
- import { existsSync as existsSync76 } from "fs";
96843
- import { isAbsolute as isAbsolute15, join as join93, relative as relative13, resolve as resolve23 } from "path";
96901
+ import { existsSync as existsSync77 } from "fs";
96902
+ import { isAbsolute as isAbsolute15, join as join95, relative as relative13, resolve as resolve23 } from "path";
96844
96903
  function getBoulderFilePath(directory) {
96845
- return join93(directory, BOULDER_DIR, BOULDER_FILE);
96904
+ return join95(directory, BOULDER_DIR, BOULDER_FILE);
96846
96905
  }
96847
96906
  function resolveTrackedPath(baseDirectory, trackedPath) {
96848
96907
  return isAbsolute15(trackedPath) ? resolve23(trackedPath) : resolve23(baseDirectory, trackedPath);
@@ -96860,14 +96919,14 @@ function resolveBoulderPlanPath(directory, state3) {
96860
96919
  }
96861
96920
  const absoluteWorktreePath = resolveTrackedPath(directory, worktreePath);
96862
96921
  const worktreePlanPath = resolve23(absoluteWorktreePath, relativePlanPath);
96863
- return existsSync76(worktreePlanPath) ? worktreePlanPath : absolutePlanPath;
96922
+ return existsSync77(worktreePlanPath) ? worktreePlanPath : absolutePlanPath;
96864
96923
  }
96865
96924
  function resolveBoulderPlanPathForWork(directory, work) {
96866
96925
  return resolveBoulderPlanPath(directory, work);
96867
96926
  }
96868
96927
  // packages/boulder-state/src/storage/plan-progress.ts
96869
- import { existsSync as existsSync77, readFileSync as readFileSync52, readdirSync as readdirSync20, statSync as statSync11 } from "fs";
96870
- import { basename as basename16, join as join94 } from "path";
96928
+ import { existsSync as existsSync78, readFileSync as readFileSync52, readdirSync as readdirSync20, statSync as statSync11 } from "fs";
96929
+ import { basename as basename16, join as join96 } from "path";
96871
96930
  var TODO_HEADING_PATTERN2 = /^##\s+TODOs\b/i;
96872
96931
  var FINAL_VERIFICATION_HEADING_PATTERN2 = /^##\s+Final Verification Wave\b/i;
96873
96932
  var SECOND_LEVEL_HEADING_PATTERN2 = /^##\s+/;
@@ -96880,11 +96939,11 @@ var PROMETHEUS_PLAN_DIRS = [PROMETHEUS_PLANS_DIR, LEGACY_PROMETHEUS_PLANS_DIR];
96880
96939
  function findPrometheusPlans(directory) {
96881
96940
  try {
96882
96941
  return PROMETHEUS_PLAN_DIRS.flatMap((planDir) => {
96883
- const plansDir = join94(directory, planDir);
96884
- if (!existsSync77(plansDir)) {
96942
+ const plansDir = join96(directory, planDir);
96943
+ if (!existsSync78(plansDir)) {
96885
96944
  return [];
96886
96945
  }
96887
- return readdirSync20(plansDir).filter((file2) => file2.endsWith(".md")).map((file2) => join94(plansDir, file2));
96946
+ return readdirSync20(plansDir).filter((file2) => file2.endsWith(".md")).map((file2) => join96(plansDir, file2));
96888
96947
  }).sort((left, right) => statSync11(right).mtimeMs - statSync11(left).mtimeMs);
96889
96948
  } catch {
96890
96949
  return [];
@@ -96894,7 +96953,7 @@ function getPlanName(planPath) {
96894
96953
  return basename16(planPath, ".md");
96895
96954
  }
96896
96955
  function getPlanProgress(planPath) {
96897
- if (!existsSync77(planPath)) {
96956
+ if (!existsSync78(planPath)) {
96898
96957
  return { total: 0, completed: 0, isComplete: false };
96899
96958
  }
96900
96959
  try {
@@ -97028,10 +97087,10 @@ function selectMirrorWork(state3) {
97028
97087
  return sorted[0] ?? null;
97029
97088
  }
97030
97089
  // packages/boulder-state/src/storage/read-state.ts
97031
- import { existsSync as existsSync78, readFileSync as readFileSync53 } from "fs";
97090
+ import { existsSync as existsSync79, readFileSync as readFileSync53 } from "fs";
97032
97091
  function readBoulderState(directory) {
97033
97092
  const filePath = getBoulderFilePath(directory);
97034
- if (!existsSync78(filePath)) {
97093
+ if (!existsSync79(filePath)) {
97035
97094
  return null;
97036
97095
  }
97037
97096
  try {
@@ -97184,15 +97243,15 @@ function getTaskSessionState(directory, taskKey) {
97184
97243
  return state3.task_sessions[taskKey] ?? null;
97185
97244
  }
97186
97245
  // packages/boulder-state/src/storage/write-state.ts
97187
- import { existsSync as existsSync79, mkdirSync as mkdirSync18, unlinkSync as unlinkSync13, writeFileSync as writeFileSync17 } from "fs";
97188
- import { dirname as dirname29, join as join95 } from "path";
97246
+ import { existsSync as existsSync80, mkdirSync as mkdirSync18, unlinkSync as unlinkSync13, writeFileSync as writeFileSync17 } from "fs";
97247
+ import { dirname as dirname30, join as join97 } from "path";
97189
97248
  function writeBoulderState(directory, state3) {
97190
97249
  const filePath = getBoulderFilePath(directory);
97191
97250
  try {
97192
- const dir = dirname29(filePath);
97193
- if (!existsSync79(dir)) {
97251
+ const dir = dirname30(filePath);
97252
+ if (!existsSync80(dir)) {
97194
97253
  mkdirSync18(dir, { recursive: true });
97195
- writeFileSync17(join95(dir, ".gitignore"), ["*", "!/rules/", "!/rules/**", ""].join(`
97254
+ writeFileSync17(join97(dir, ".gitignore"), ["*", "!/rules/", "!/rules/**", ""].join(`
97196
97255
  `), "utf-8");
97197
97256
  }
97198
97257
  const stateToWrite = { ...state3 };
@@ -97228,7 +97287,7 @@ function writeBoulderState(directory, state3) {
97228
97287
  function clearBoulderState(directory) {
97229
97288
  const filePath = getBoulderFilePath(directory);
97230
97289
  try {
97231
- if (existsSync79(filePath)) {
97290
+ if (existsSync80(filePath)) {
97232
97291
  unlinkSync13(filePath);
97233
97292
  }
97234
97293
  return true;
@@ -97724,11 +97783,11 @@ init_logger2();
97724
97783
 
97725
97784
  // packages/omo-opencode/src/hooks/start-work/worktree-detector.ts
97726
97785
  import { execFileSync as execFileSync5 } from "child_process";
97727
- import { existsSync as existsSync80, realpathSync as realpathSync13 } from "fs";
97786
+ import { existsSync as existsSync81, realpathSync as realpathSync13 } from "fs";
97728
97787
  import { resolve as resolve25, win32 as win328 } from "path";
97729
97788
  function normalizePath5(path18) {
97730
97789
  const resolvedPath = process.platform !== "win32" && win328.isAbsolute(path18) ? path18 : resolve25(path18);
97731
- if (!existsSync80(resolvedPath)) {
97790
+ if (!existsSync81(resolvedPath)) {
97732
97791
  return resolvedPath;
97733
97792
  }
97734
97793
  try {
@@ -99024,7 +99083,7 @@ async function isSessionInBoulderLineage(input) {
99024
99083
 
99025
99084
  // packages/omo-opencode/src/hooks/atlas/session-last-agent.ts
99026
99085
  import { readFileSync as readFileSync54, readdirSync as readdirSync21 } from "fs";
99027
- import { join as join96 } from "path";
99086
+ import { join as join98 } from "path";
99028
99087
  var defaultSessionLastAgentDeps = {
99029
99088
  getMessageDir,
99030
99089
  isSqliteBackend,
@@ -99084,7 +99143,7 @@ async function getLastAgentFromSession(sessionID, client3, deps = {}) {
99084
99143
  try {
99085
99144
  const messages = readdirSync21(messageDir).filter((fileName) => fileName.endsWith(".json")).map((fileName) => {
99086
99145
  try {
99087
- const content = readFileSync54(join96(messageDir, fileName), "utf-8");
99146
+ const content = readFileSync54(join98(messageDir, fileName), "utf-8");
99088
99147
  const parsed = JSON.parse(content);
99089
99148
  return {
99090
99149
  fileName,
@@ -99627,7 +99686,7 @@ function isOmoPath(filePath) {
99627
99686
  }
99628
99687
 
99629
99688
  // packages/omo-opencode/src/hooks/atlas/tool-execute-after-plan-tasks.ts
99630
- import { existsSync as existsSync81, readFileSync as readFileSync55 } from "fs";
99689
+ import { existsSync as existsSync82, readFileSync as readFileSync55 } from "fs";
99631
99690
  var TODO_HEADING_PATTERN3 = /^##\s+TODOs\b/i;
99632
99691
  var FINAL_VERIFICATION_HEADING_PATTERN3 = /^##\s+Final Verification Wave\b/i;
99633
99692
  var SECOND_LEVEL_HEADING_PATTERN3 = /^##\s+/;
@@ -99635,7 +99694,7 @@ var CHECKED_CHECKBOX_PATTERN2 = /^(\s*)[-*]\s*\[[xX]\]\s*(.+)$/;
99635
99694
  var TODO_TASK_PATTERN3 = /^(\d+)\.\s+(.+)$/;
99636
99695
  var FINAL_WAVE_TASK_PATTERN3 = /^(F\d+)\.\s+(.+)$/i;
99637
99696
  function isTrackedTaskChecked(planPath, taskKey) {
99638
- if (!existsSync81(planPath)) {
99697
+ if (!existsSync82(planPath)) {
99639
99698
  return false;
99640
99699
  }
99641
99700
  const [section, label] = taskKey.split(":");
@@ -99689,7 +99748,7 @@ function parseCheckedTopLevelTaskKeys(planContent) {
99689
99748
  return checkedKeys;
99690
99749
  }
99691
99750
  function readCheckedTaskKeysFromPlan(planPath) {
99692
- if (!existsSync81(planPath)) {
99751
+ if (!existsSync82(planPath)) {
99693
99752
  return new Set;
99694
99753
  }
99695
99754
  try {
@@ -99868,7 +99927,7 @@ async function resolveFallbackTrackedSessionId(input) {
99868
99927
  }
99869
99928
 
99870
99929
  // packages/omo-opencode/src/hooks/atlas/final-wave-plan-state.ts
99871
- import { existsSync as existsSync82, readFileSync as readFileSync56 } from "fs";
99930
+ import { existsSync as existsSync83, readFileSync as readFileSync56 } from "fs";
99872
99931
  var TODO_HEADING_PATTERN4 = /^##\s+TODOs\b/i;
99873
99932
  var FINAL_VERIFICATION_HEADING_PATTERN4 = /^##\s+Final Verification Wave\b/i;
99874
99933
  var SECOND_LEVEL_HEADING_PATTERN4 = /^##\s+/;
@@ -99876,7 +99935,7 @@ var UNCHECKED_CHECKBOX_PATTERN3 = /^\s*[-*]\s*\[\s*\]\s*(.+)$/;
99876
99935
  var TODO_TASK_PATTERN4 = /^\d+\./;
99877
99936
  var FINAL_WAVE_TASK_PATTERN4 = /^F\d+\./i;
99878
99937
  function readFinalWavePlanState(planPath) {
99879
- if (!existsSync82(planPath)) {
99938
+ if (!existsSync83(planPath)) {
99880
99939
  return null;
99881
99940
  }
99882
99941
  try {
@@ -100323,7 +100382,7 @@ function createToolExecuteAfterHandler2(input) {
100323
100382
 
100324
100383
  // packages/omo-opencode/src/hooks/atlas/tool-execute-before.ts
100325
100384
  init_logger2();
100326
- import { existsSync as existsSync83, readFileSync as readFileSync57 } from "fs";
100385
+ import { existsSync as existsSync84, readFileSync as readFileSync57 } from "fs";
100327
100386
  import { resolve as resolve27 } from "path";
100328
100387
  var TASK_SECTION_HEADER_PATTERN = /^##\s*1\.\s*TASK\s*$/i;
100329
100388
  var TODO_TASK_LINE_PATTERN = /^(?:[-*]\s*\[\s*\]\s*)?(\d+)\.\s+(.+)$/;
@@ -100384,7 +100443,7 @@ function createToolExecuteBeforeHandler2(input) {
100384
100443
  const planPath = sessionWork ? resolveBoulderPlanPathForWork(ctx.directory, sessionWork) : state3 ? resolveBoulderPlanPath(ctx.directory, state3) : null;
100385
100444
  if (planPath && resolve27(filePath) === resolve27(planPath) && pendingPlanSnapshots) {
100386
100445
  try {
100387
- if (existsSync83(planPath)) {
100446
+ if (existsSync84(planPath)) {
100388
100447
  pendingPlanSnapshots.set(toolInput.callID, readFileSync57(planPath, "utf-8"));
100389
100448
  }
100390
100449
  } catch (error) {
@@ -102457,7 +102516,8 @@ var DEFAULT_CONFIG2 = {
102457
102516
  max_fallback_attempts: 3,
102458
102517
  cooldown_seconds: 60,
102459
102518
  timeout_seconds: 30,
102460
- notify_on_fallback: true
102519
+ notify_on_fallback: true,
102520
+ restore_primary_after_cooldown: false
102461
102521
  };
102462
102522
  var RETRYABLE_ERROR_PATTERNS = [
102463
102523
  /rate.?limit/i,
@@ -102494,7 +102554,7 @@ init_logger2();
102494
102554
  function createAbortSessionRequest(deps) {
102495
102555
  const { ctx } = deps;
102496
102556
  return async (sessionID, source) => {
102497
- if (source === "session.status.retry-signal" || source === "message.updated.retry-signal" || source === "session.timeout") {
102557
+ if (source === "session.status.retry-signal" || source === "message.updated.retry-signal" || source === "message.updated.quota-fallback" || source === "session.timeout") {
102498
102558
  deps.internallyAbortedSessions.add(sessionID);
102499
102559
  deps.sessionLastAccess.set(sessionID, Date.now());
102500
102560
  }
@@ -102753,7 +102813,7 @@ function createAutoRetryDispatcher(deps, scheduleSessionFallbackTimeout, clearSe
102753
102813
  return async (sessionID, newModel, resolvedAgent, source) => {
102754
102814
  if (sessionRetryInFlight.has(sessionID)) {
102755
102815
  log2(`[${HOOK_NAME11}] Retry already in flight, skipping (${source})`, { sessionID });
102756
- return;
102816
+ return { accepted: false, status: "blocked", reason: "retry already in flight" };
102757
102817
  }
102758
102818
  const agentSettings = resolvedAgent ? pluginConfig?.agents?.[resolvedAgent] : undefined;
102759
102819
  const retryModelPayload = buildRetryModelPayload(newModel, agentSettings ? {
@@ -102769,7 +102829,7 @@ function createAutoRetryDispatcher(deps, scheduleSessionFallbackTimeout, clearSe
102769
102829
  if (state3) {
102770
102830
  state3.pendingFallbackPromptMayHaveBeenAccepted = false;
102771
102831
  }
102772
- return;
102832
+ return { accepted: false, status: "invalid-model", reason: "missing provider prefix" };
102773
102833
  }
102774
102834
  const hadAwaitingFallbackResult = sessionAwaitingFallbackResult.has(sessionID);
102775
102835
  const previousPendingFallbackModel = sessionStates.get(sessionID)?.pendingFallbackModel;
@@ -102777,6 +102837,7 @@ function createAutoRetryDispatcher(deps, scheduleSessionFallbackTimeout, clearSe
102777
102837
  sessionRetryInFlight.add(sessionID);
102778
102838
  let retryDispatched = false;
102779
102839
  let retryMayHaveBeenAccepted = false;
102840
+ let acceptedStatus = "dispatched";
102780
102841
  try {
102781
102842
  const messagesResp = await ctx.client.session.messages({
102782
102843
  path: { id: sessionID },
@@ -102831,6 +102892,7 @@ function createAutoRetryDispatcher(deps, scheduleSessionFallbackTimeout, clearSe
102831
102892
  sessionID
102832
102893
  });
102833
102894
  promptResult = await dispatchRetryPrompt(`runtime-fallback:${source}:active-queue`);
102895
+ acceptedStatus = "queued";
102834
102896
  }
102835
102897
  if (promptResult.status === "failed") {
102836
102898
  if (isAmbiguousPostDispatchPromptFailure(promptResult)) {
@@ -102839,6 +102901,7 @@ function createAutoRetryDispatcher(deps, scheduleSessionFallbackTimeout, clearSe
102839
102901
  sessionID,
102840
102902
  error: String(promptResult.error)
102841
102903
  });
102904
+ return { accepted: true, status: "possibly-accepted" };
102842
102905
  }
102843
102906
  throw promptResult.error;
102844
102907
  }
@@ -102865,6 +102928,7 @@ function createAutoRetryDispatcher(deps, scheduleSessionFallbackTimeout, clearSe
102865
102928
  sessionID,
102866
102929
  error: String(reservedResult.error)
102867
102930
  });
102931
+ return { accepted: true, status: "possibly-accepted" };
102868
102932
  }
102869
102933
  throw reservedResult.error;
102870
102934
  }
@@ -102873,14 +102937,15 @@ function createAutoRetryDispatcher(deps, scheduleSessionFallbackTimeout, clearSe
102873
102937
  sessionID,
102874
102938
  status: reservedResult.status
102875
102939
  });
102876
- return;
102940
+ return { accepted: false, status: "blocked", reason: `prompt gate returned ${reservedResult.status}` };
102877
102941
  }
102942
+ acceptedStatus = "queued";
102878
102943
  } else if (!isInternalPromptDispatchAccepted(promptResult)) {
102879
102944
  log2(`[${HOOK_NAME11}] Auto-retry skipped by promptAsync gate (${source})`, {
102880
102945
  sessionID,
102881
102946
  status: promptResult.status
102882
102947
  });
102883
- return;
102948
+ return { accepted: false, status: "blocked", reason: `prompt gate returned ${promptResult.status}` };
102884
102949
  }
102885
102950
  sessionAwaitingFallbackResult.add(sessionID);
102886
102951
  if (hadAwaitingFallbackResult) {
@@ -102891,12 +102956,14 @@ function createAutoRetryDispatcher(deps, scheduleSessionFallbackTimeout, clearSe
102891
102956
  state3.pendingFallbackPromptMayHaveBeenAccepted = false;
102892
102957
  }
102893
102958
  retryDispatched = true;
102959
+ return { accepted: true, status: acceptedStatus };
102894
102960
  } catch (retryError) {
102895
102961
  if (!(retryError instanceof Error)) {
102896
102962
  log2(`[${HOOK_NAME11}] Auto-retry failed (${source})`, { sessionID, error: String(retryError) });
102897
- return;
102963
+ return { accepted: false, status: "failed", reason: String(retryError) };
102898
102964
  }
102899
102965
  log2(`[${HOOK_NAME11}] Auto-retry failed (${source})`, { sessionID, error: String(retryError) });
102966
+ return { accepted: false, status: "failed", reason: retryError.message };
102900
102967
  } finally {
102901
102968
  sessionRetryInFlight.delete(sessionID);
102902
102969
  if (retryMayHaveBeenAccepted) {
@@ -103048,6 +103115,28 @@ function prepareFallback(sessionID, state3, fallbackModels, config) {
103048
103115
  return { success: true, newModel: nextModel };
103049
103116
  }
103050
103117
 
103118
+ // packages/omo-opencode/src/hooks/runtime-fallback/fallback-state-snapshot.ts
103119
+ function snapshotFallbackState(state3) {
103120
+ return {
103121
+ originalModel: state3.originalModel,
103122
+ currentModel: state3.currentModel,
103123
+ fallbackIndex: state3.fallbackIndex,
103124
+ failedModels: new Map(state3.failedModels),
103125
+ attemptCount: state3.attemptCount,
103126
+ pendingFallbackModel: state3.pendingFallbackModel,
103127
+ pendingFallbackPromptMayHaveBeenAccepted: state3.pendingFallbackPromptMayHaveBeenAccepted
103128
+ };
103129
+ }
103130
+ function restoreFallbackState(state3, snapshot) {
103131
+ state3.originalModel = snapshot.originalModel;
103132
+ state3.currentModel = snapshot.currentModel;
103133
+ state3.fallbackIndex = snapshot.fallbackIndex;
103134
+ state3.failedModels = new Map(snapshot.failedModels);
103135
+ state3.attemptCount = snapshot.attemptCount;
103136
+ state3.pendingFallbackModel = snapshot.pendingFallbackModel;
103137
+ state3.pendingFallbackPromptMayHaveBeenAccepted = snapshot.pendingFallbackPromptMayHaveBeenAccepted;
103138
+ }
103139
+
103051
103140
  // packages/omo-opencode/src/hooks/runtime-fallback/auto-retry-timeout.ts
103052
103141
  function createFallbackTimeoutHelpers(deps, abortSessionRequest, autoRetryWithFallback) {
103053
103142
  const {
@@ -103089,6 +103178,7 @@ function createFallbackTimeoutHelpers(deps, abortSessionRequest, autoRetryWithFa
103089
103178
  state3.pendingFallbackModel = undefined;
103090
103179
  }
103091
103180
  state3.pendingFallbackPromptMayHaveBeenAccepted = false;
103181
+ const stateSnapshot = snapshotFallbackState(state3);
103092
103182
  const fallbackModels = getFallbackModelsForSession(sessionID, resolvedAgent, pluginConfig);
103093
103183
  if (fallbackModels.length === 0)
103094
103184
  return;
@@ -103099,7 +103189,18 @@ function createFallbackTimeoutHelpers(deps, abortSessionRequest, autoRetryWithFa
103099
103189
  });
103100
103190
  const result = prepareFallback(sessionID, state3, fallbackModels, config);
103101
103191
  if (result.success && result.newModel) {
103102
- await autoRetryWithFallback(sessionID, result.newModel, resolvedAgent, "session.timeout");
103192
+ const dispatchOutcome = await autoRetryWithFallback(sessionID, result.newModel, resolvedAgent, "session.timeout");
103193
+ if (!dispatchOutcome.accepted) {
103194
+ restoreFallbackState(state3, stateSnapshot);
103195
+ if (deps.sessionAwaitingFallbackResult.has(sessionID)) {
103196
+ scheduleSessionFallbackTimeout(sessionID, resolvedAgent);
103197
+ }
103198
+ log2(`[${HOOK_NAME11}] Session timeout fallback dispatch was not accepted`, {
103199
+ sessionID,
103200
+ status: dispatchOutcome.status,
103201
+ reason: dispatchOutcome.reason
103202
+ });
103203
+ }
103103
103204
  }
103104
103205
  }, timeoutMs);
103105
103206
  sessionFallbackTimeouts.set(sessionID, timer);
@@ -103189,7 +103290,7 @@ function createChatMessageHandler2(deps) {
103189
103290
  sessionStates.set(sessionID, state3);
103190
103291
  return;
103191
103292
  }
103192
- if (state3.currentModel !== state3.originalModel && !state3.pendingFallbackModel && !isModelInCooldown(state3.originalModel, state3, config.cooldown_seconds)) {
103293
+ if (config.restore_primary_after_cooldown && state3.currentModel !== state3.originalModel && !state3.pendingFallbackModel && !isModelInCooldown(state3.originalModel, state3, config.cooldown_seconds)) {
103193
103294
  const activeModel2 = state3.originalModel;
103194
103295
  log2(`[${HOOK_NAME11}] Restoring preferred primary model`, {
103195
103296
  sessionID,
@@ -103306,20 +103407,49 @@ function resolveFallbackBootstrapModel(options) {
103306
103407
 
103307
103408
  // packages/omo-opencode/src/hooks/runtime-fallback/fallback-retry-dispatcher.ts
103308
103409
  init_logger2();
103410
+ function resolveDispatchMessage(result, newModel) {
103411
+ const modelName = newModel.split("/").pop() || newModel;
103412
+ if (result.status === "queued")
103413
+ return `Fallback queued for ${modelName}`;
103414
+ if (result.status === "possibly-accepted")
103415
+ return `Fallback dispatch may have been accepted for ${modelName}`;
103416
+ return `Switched to ${modelName} for next request`;
103417
+ }
103309
103418
  async function dispatchFallbackRetry(deps, helpers, options) {
103419
+ const snapshot = snapshotFallbackState(options.state);
103310
103420
  const result = prepareFallback(options.sessionID, options.state, options.fallbackModels, deps.config);
103311
- if (result.success && deps.config.notify_on_fallback) {
103312
- await deps.ctx.client.tui.showToast({
103313
- body: {
103314
- title: "Model Fallback",
103315
- message: `Switching to ${result.newModel?.split("/").pop() || result.newModel} for next request`,
103316
- variant: "warning",
103317
- duration: 5000
103318
- }
103319
- }).catch(() => {});
103320
- }
103321
103421
  if (result.success && result.newModel) {
103322
- await helpers.autoRetryWithFallback(options.sessionID, result.newModel, options.resolvedAgent, options.source);
103422
+ const rawDispatchOutcome = await helpers.autoRetryWithFallback(options.sessionID, result.newModel, options.resolvedAgent, options.source);
103423
+ const dispatchOutcome = rawDispatchOutcome ?? {
103424
+ accepted: true,
103425
+ status: "dispatched"
103426
+ };
103427
+ if (rawDispatchOutcome === undefined) {
103428
+ log2(`[${HOOK_NAME11}] Fallback dispatch returned no outcome; treating as accepted for compatibility`, {
103429
+ sessionID: options.sessionID,
103430
+ source: options.source
103431
+ });
103432
+ }
103433
+ if (!dispatchOutcome.accepted) {
103434
+ restoreFallbackState(options.state, snapshot);
103435
+ log2(`[${HOOK_NAME11}] Fallback dispatch was not accepted`, {
103436
+ sessionID: options.sessionID,
103437
+ source: options.source,
103438
+ status: dispatchOutcome.status,
103439
+ reason: dispatchOutcome.reason
103440
+ });
103441
+ return;
103442
+ }
103443
+ if (deps.config.notify_on_fallback) {
103444
+ await deps.ctx.client.tui.showToast({
103445
+ body: {
103446
+ title: "Model Fallback",
103447
+ message: resolveDispatchMessage(dispatchOutcome, result.newModel),
103448
+ variant: "warning",
103449
+ duration: 5000
103450
+ }
103451
+ }).catch(() => {});
103452
+ }
103323
103453
  return;
103324
103454
  }
103325
103455
  log2(`[${HOOK_NAME11}] Fallback preparation failed`, {
@@ -104101,6 +104231,10 @@ function createMessageUpdateHandler(deps, helpers) {
104101
104231
  }
104102
104232
  }
104103
104233
  }
104234
+ if (classifyErrorType(error) === "quota_exceeded") {
104235
+ await helpers.abortSessionRequest(sessionID, "message.updated.quota-fallback");
104236
+ sessionRetryInFlight.delete(sessionID);
104237
+ }
104104
104238
  await dispatchFallbackRetry(deps, helpers, {
104105
104239
  sessionID,
104106
104240
  state: state3,
@@ -104131,7 +104265,8 @@ function createRuntimeFallbackHook(ctx, options, factoryOverrides = {}) {
104131
104265
  max_fallback_attempts: options?.config?.max_fallback_attempts ?? DEFAULT_CONFIG2.max_fallback_attempts,
104132
104266
  cooldown_seconds: options?.config?.cooldown_seconds ?? DEFAULT_CONFIG2.cooldown_seconds,
104133
104267
  timeout_seconds: options?.config?.timeout_seconds ?? DEFAULT_CONFIG2.timeout_seconds,
104134
- notify_on_fallback: options?.config?.notify_on_fallback ?? DEFAULT_CONFIG2.notify_on_fallback
104268
+ notify_on_fallback: options?.config?.notify_on_fallback ?? DEFAULT_CONFIG2.notify_on_fallback,
104269
+ restore_primary_after_cooldown: options?.config?.restore_primary_after_cooldown ?? DEFAULT_CONFIG2.restore_primary_after_cooldown
104135
104270
  };
104136
104271
  const deps = {
104137
104272
  ctx,
@@ -104199,11 +104334,11 @@ function createRuntimeFallbackHook(ctx, options, factoryOverrides = {}) {
104199
104334
  };
104200
104335
  }
104201
104336
  // packages/omo-opencode/src/hooks/write-existing-file-guard/hook.ts
104202
- import { existsSync as existsSync85, realpathSync as realpathSync14 } from "fs";
104203
- import { basename as basename17, dirname as dirname30, isAbsolute as isAbsolute17, join as join97, normalize as normalize2, relative as relative15, resolve as resolve28 } from "path";
104337
+ import { existsSync as existsSync86, realpathSync as realpathSync14 } from "fs";
104338
+ import { basename as basename17, dirname as dirname31, isAbsolute as isAbsolute17, join as join99, normalize as normalize2, relative as relative15, resolve as resolve28 } from "path";
104204
104339
 
104205
104340
  // packages/omo-opencode/src/hooks/write-existing-file-guard/tool-execute-before-handler.ts
104206
- import { existsSync as existsSync84 } from "fs";
104341
+ import { existsSync as existsSync85 } from "fs";
104207
104342
 
104208
104343
  // packages/omo-opencode/src/hooks/write-existing-file-guard/session-read-permissions.ts
104209
104344
  function touchSession(sessionLastAccess, sessionID) {
@@ -104304,7 +104439,7 @@ async function handleWriteExistingFileGuardToolExecuteBefore(params) {
104304
104439
  return;
104305
104440
  }
104306
104441
  if (toolName === "read") {
104307
- if (!existsSync84(resolvedPath) || !input.sessionID) {
104442
+ if (!existsSync85(resolvedPath) || !input.sessionID) {
104308
104443
  return;
104309
104444
  }
104310
104445
  registerReadPermission({
@@ -104322,7 +104457,7 @@ async function handleWriteExistingFileGuardToolExecuteBefore(params) {
104322
104457
  const { overwrite: _, ...rest } = argsRecord;
104323
104458
  output.args = rest;
104324
104459
  }
104325
- if (!existsSync84(resolvedPath)) {
104460
+ if (!existsSync85(resolvedPath)) {
104326
104461
  return;
104327
104462
  }
104328
104463
  if (isOmoWorkspacePath(canonicalPath)) {
@@ -104380,7 +104515,7 @@ function isPathInsideDirectory(pathToCheck, directory) {
104380
104515
  }
104381
104516
  function toCanonicalPath2(absolutePath) {
104382
104517
  let canonicalPath = absolutePath;
104383
- if (existsSync85(absolutePath)) {
104518
+ if (existsSync86(absolutePath)) {
104384
104519
  try {
104385
104520
  canonicalPath = realpathSync14.native(absolutePath);
104386
104521
  } catch (canonicalPathError) {
@@ -104388,9 +104523,9 @@ function toCanonicalPath2(absolutePath) {
104388
104523
  canonicalPath = absolutePath;
104389
104524
  }
104390
104525
  } else {
104391
- const absoluteDir = dirname30(absolutePath);
104392
- const resolvedDir = existsSync85(absoluteDir) ? realpathSync14.native(absoluteDir) : absoluteDir;
104393
- canonicalPath = join97(resolvedDir, basename17(absolutePath));
104526
+ const absoluteDir = dirname31(absolutePath);
104527
+ const resolvedDir = existsSync86(absoluteDir) ? realpathSync14.native(absoluteDir) : absoluteDir;
104528
+ canonicalPath = join99(resolvedDir, basename17(absolutePath));
104394
104529
  }
104395
104530
  return normalize2(canonicalPath);
104396
104531
  }
@@ -107151,23 +107286,23 @@ init_logger2();
107151
107286
  init_plugin_identity();
107152
107287
 
107153
107288
  // packages/omo-opencode/src/hooks/legacy-plugin-toast/auto-migrate.ts
107154
- import { existsSync as existsSync86, readFileSync as readFileSync58 } from "fs";
107155
- import { join as join98 } from "path";
107289
+ import { existsSync as existsSync87, readFileSync as readFileSync58 } from "fs";
107290
+ import { join as join100 } from "path";
107156
107291
  init_plugin_identity();
107157
107292
  function detectOpenCodeConfigPath(overrideConfigDir) {
107158
107293
  if (overrideConfigDir) {
107159
- const jsoncPath = join98(overrideConfigDir, "opencode.jsonc");
107160
- const jsonPath = join98(overrideConfigDir, "opencode.json");
107161
- if (existsSync86(jsoncPath))
107294
+ const jsoncPath = join100(overrideConfigDir, "opencode.jsonc");
107295
+ const jsonPath = join100(overrideConfigDir, "opencode.json");
107296
+ if (existsSync87(jsoncPath))
107162
107297
  return jsoncPath;
107163
- if (existsSync86(jsonPath))
107298
+ if (existsSync87(jsonPath))
107164
107299
  return jsonPath;
107165
107300
  return null;
107166
107301
  }
107167
107302
  const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
107168
- if (existsSync86(paths.configJsonc))
107303
+ if (existsSync87(paths.configJsonc))
107169
107304
  return paths.configJsonc;
107170
- if (existsSync86(paths.configJson))
107305
+ if (existsSync87(paths.configJson))
107171
107306
  return paths.configJson;
107172
107307
  return null;
107173
107308
  }
@@ -107359,7 +107494,7 @@ function createNotepadWriteGuardHook() {
107359
107494
  };
107360
107495
  }
107361
107496
  // packages/omo-opencode/src/hooks/plan-format-validator/hook.ts
107362
- import { existsSync as existsSync87, readFileSync as readFileSync59 } from "fs";
107497
+ import { existsSync as existsSync88, readFileSync as readFileSync59 } from "fs";
107363
107498
  import { resolve as resolve29 } from "path";
107364
107499
  init_logger2();
107365
107500
  var WRITE_TOOLS = new Set(["Write", "Edit", "write", "edit"]);
@@ -107443,7 +107578,7 @@ function createPlanFormatValidatorHook(_ctx) {
107443
107578
  if (!isPlanFilePath(filePath))
107444
107579
  return;
107445
107580
  const resolvedPath = resolve29(_ctx.directory, filePath);
107446
- if (!existsSync87(resolvedPath))
107581
+ if (!existsSync88(resolvedPath))
107447
107582
  return;
107448
107583
  const content = readFileSync59(resolvedPath, "utf-8");
107449
107584
  if (!CHECKBOX_PATTERN.test(content))
@@ -107555,19 +107690,19 @@ tool.schema = z3;
107555
107690
 
107556
107691
  // packages/omo-opencode/src/shared/ripgrep-cli.ts
107557
107692
  import { spawnSync as spawnSync3 } from "child_process";
107558
- import { existsSync as existsSync89 } from "fs";
107559
- import { dirname as dirname31, join as join100 } from "path";
107693
+ import { existsSync as existsSync90 } from "fs";
107694
+ import { dirname as dirname32, join as join102 } from "path";
107560
107695
 
107561
107696
  // packages/omo-opencode/src/tools/grep/downloader.ts
107562
- import { existsSync as existsSync88, readdirSync as readdirSync22 } from "fs";
107563
- import { join as join99 } from "path";
107697
+ import { existsSync as existsSync89, readdirSync as readdirSync22 } from "fs";
107698
+ import { join as join101 } from "path";
107564
107699
  init_plugin_identity();
107565
107700
  function findFileRecursive(dir, filename) {
107566
107701
  try {
107567
107702
  const entries = readdirSync22(dir, { withFileTypes: true, recursive: true });
107568
107703
  for (const entry of entries) {
107569
107704
  if (entry.isFile() && entry.name === filename) {
107570
- return join99(entry.parentPath ?? dir, entry.name);
107705
+ return join101(entry.parentPath ?? dir, entry.name);
107571
107706
  }
107572
107707
  }
107573
107708
  } catch (error) {
@@ -107591,11 +107726,11 @@ function getPlatformKey() {
107591
107726
  }
107592
107727
  function getInstallDir() {
107593
107728
  const homeDir = process.env.HOME || process.env.USERPROFILE || ".";
107594
- return join99(homeDir, ".cache", CACHE_DIR_NAME, "bin");
107729
+ return join101(homeDir, ".cache", CACHE_DIR_NAME, "bin");
107595
107730
  }
107596
107731
  function getRgPath() {
107597
107732
  const isWindows2 = process.platform === "win32";
107598
- return join99(getInstallDir(), isWindows2 ? "rg.exe" : "rg");
107733
+ return join101(getInstallDir(), isWindows2 ? "rg.exe" : "rg");
107599
107734
  }
107600
107735
  async function extractTarGz3(archivePath, destDir) {
107601
107736
  const platformKey2 = getPlatformKey();
@@ -107612,7 +107747,7 @@ async function extractZip2(archivePath, destDir) {
107612
107747
  const binaryName = process.platform === "win32" ? "rg.exe" : "rg";
107613
107748
  const foundPath = findFileRecursive(destDir, binaryName);
107614
107749
  if (foundPath) {
107615
- const destPath = join99(destDir, binaryName);
107750
+ const destPath = join101(destDir, binaryName);
107616
107751
  if (foundPath !== destPath) {
107617
107752
  const { renameSync: renameSync7 } = await import("fs");
107618
107753
  renameSync7(foundPath, destPath);
@@ -107627,13 +107762,13 @@ async function downloadAndInstallRipgrep() {
107627
107762
  }
107628
107763
  const installDir = getInstallDir();
107629
107764
  const rgPath = getRgPath();
107630
- if (existsSync88(rgPath)) {
107765
+ if (existsSync89(rgPath)) {
107631
107766
  return rgPath;
107632
107767
  }
107633
107768
  ensureCacheDir(installDir);
107634
107769
  const filename = `ripgrep-${RG_VERSION}-${config.platform}.${config.extension}`;
107635
107770
  const url = `https://github.com/BurntSushi/ripgrep/releases/download/${RG_VERSION}/${filename}`;
107636
- const archivePath = join99(installDir, filename);
107771
+ const archivePath = join101(installDir, filename);
107637
107772
  try {
107638
107773
  await downloadArchive(url, archivePath);
107639
107774
  if (config.extension === "tar.gz") {
@@ -107642,7 +107777,7 @@ async function downloadAndInstallRipgrep() {
107642
107777
  await extractZip2(archivePath, installDir);
107643
107778
  }
107644
107779
  ensureExecutable(rgPath);
107645
- if (!existsSync88(rgPath)) {
107780
+ if (!existsSync89(rgPath)) {
107646
107781
  throw new Error("ripgrep binary not found after extraction");
107647
107782
  }
107648
107783
  return rgPath;
@@ -107658,7 +107793,7 @@ async function downloadAndInstallRipgrep() {
107658
107793
  }
107659
107794
  function getInstalledRipgrepPath() {
107660
107795
  const rgPath = getRgPath();
107661
- return existsSync88(rgPath) ? rgPath : null;
107796
+ return existsSync89(rgPath) ? rgPath : null;
107662
107797
  }
107663
107798
 
107664
107799
  // packages/omo-opencode/src/shared/ripgrep-cli.ts
@@ -107694,19 +107829,19 @@ function findExecutable(name) {
107694
107829
  }
107695
107830
  function getOpenCodeBundledRg() {
107696
107831
  const execPath = process.execPath;
107697
- const execDir = dirname31(execPath);
107832
+ const execDir = dirname32(execPath);
107698
107833
  const isWindows2 = process.platform === "win32";
107699
107834
  const rgName = isWindows2 ? "rg.exe" : "rg";
107700
107835
  const candidates = [
107701
- join100(getOpenCodeCacheDir(), "bin", rgName),
107702
- join100(getDataDir(), "opencode", "bin", rgName),
107703
- join100(execDir, rgName),
107704
- join100(execDir, "bin", rgName),
107705
- join100(execDir, "..", "bin", rgName),
107706
- join100(execDir, "..", "libexec", rgName)
107836
+ join102(getOpenCodeCacheDir(), "bin", rgName),
107837
+ join102(getDataDir(), "opencode", "bin", rgName),
107838
+ join102(execDir, rgName),
107839
+ join102(execDir, "bin", rgName),
107840
+ join102(execDir, "..", "bin", rgName),
107841
+ join102(execDir, "..", "libexec", rgName)
107707
107842
  ];
107708
107843
  for (const candidate of candidates) {
107709
- if (existsSync89(candidate)) {
107844
+ if (existsSync90(candidate)) {
107710
107845
  return candidate;
107711
107846
  }
107712
107847
  }
@@ -108358,7 +108493,7 @@ Use this when a task matches an available skill's or command's description.
108358
108493
  - The tool will return detailed instructions with your context applied.
108359
108494
  `;
108360
108495
  // packages/omo-opencode/src/tools/skill/tools.ts
108361
- import { dirname as dirname33 } from "path";
108496
+ import { dirname as dirname34 } from "path";
108362
108497
  // packages/omo-opencode/src/tools/skill/session-skill-cache.ts
108363
108498
  var seenSessionIDs = new Set;
108364
108499
  function shouldInvalidateSkillCacheForSession(sessionID) {
@@ -108369,7 +108504,7 @@ function shouldInvalidateSkillCacheForSession(sessionID) {
108369
108504
  return true;
108370
108505
  }
108371
108506
  // packages/omo-opencode/src/tools/slashcommand/command-output-formatter.ts
108372
- import { dirname as dirname32 } from "path";
108507
+ import { dirname as dirname33 } from "path";
108373
108508
  async function formatLoadedCommand(command, userMessage) {
108374
108509
  const sections = [];
108375
108510
  sections.push(`# /${command.name} Command
@@ -108408,7 +108543,7 @@ async function formatLoadedCommand(command, userMessage) {
108408
108543
  if (!content && command.lazyContentLoader) {
108409
108544
  content = await command.lazyContentLoader.load();
108410
108545
  }
108411
- const commandDir = command.path ? dirname32(command.path) : process.cwd();
108546
+ const commandDir = command.path ? dirname33(command.path) : process.cwd();
108412
108547
  const withFileReferences = await resolveFileReferencesInText(content, commandDir);
108413
108548
  const resolvedContent = await resolveCommandsInText(withFileReferences);
108414
108549
  let finalContent = resolvedContent.trim();
@@ -108810,7 +108945,7 @@ function createSkillTool(options) {
108810
108945
  if (matchedSkill.name === "git-master") {
108811
108946
  body = injectGitMasterConfig(body, options.gitMasterConfig);
108812
108947
  }
108813
- const dir = matchedSkill.path ? dirname33(matchedSkill.path) : matchedSkill.resolvedPath || process.cwd();
108948
+ const dir = matchedSkill.path ? dirname34(matchedSkill.path) : matchedSkill.resolvedPath || process.cwd();
108814
108949
  const output = [
108815
108950
  `## Skill: ${matchedSkill.name}`,
108816
108951
  "",
@@ -108850,9 +108985,9 @@ function createSkillTool(options) {
108850
108985
  }
108851
108986
  var skill = createSkillTool({ directory: process.cwd() });
108852
108987
  // packages/omo-opencode/src/tools/session-manager/constants.ts
108853
- import { join as join101 } from "path";
108854
- var TODO_DIR2 = join101(getClaudeConfigDir(), "todos");
108855
- var TRANSCRIPT_DIR2 = join101(getClaudeConfigDir(), "transcripts");
108988
+ import { join as join103 } from "path";
108989
+ var TODO_DIR2 = join103(getClaudeConfigDir(), "todos");
108990
+ var TRANSCRIPT_DIR2 = join103(getClaudeConfigDir(), "transcripts");
108856
108991
  var SESSION_LIST_DESCRIPTION = `List all OpenCode sessions with optional filtering.
108857
108992
 
108858
108993
  Returns a list of available session IDs with metadata including message count, date range, and agents used.
@@ -108925,16 +109060,16 @@ Has Todos: Yes (12 items, 8 completed)
108925
109060
  Has Transcript: Yes (234 entries)`;
108926
109061
 
108927
109062
  // packages/omo-opencode/src/tools/session-manager/file-storage.ts
108928
- import { existsSync as existsSync90 } from "fs";
109063
+ import { existsSync as existsSync91 } from "fs";
108929
109064
  import { readdir as readdir6, readFile as readFile9 } from "fs/promises";
108930
- import { join as join102 } from "path";
109065
+ import { join as join104 } from "path";
108931
109066
  function ignoreFileStorageError(error) {
108932
109067
  if (error instanceof Error)
108933
109068
  return;
108934
109069
  throw error;
108935
109070
  }
108936
109071
  async function getFileMainSessions(directory) {
108937
- if (!existsSync90(SESSION_STORAGE))
109072
+ if (!existsSync91(SESSION_STORAGE))
108938
109073
  return [];
108939
109074
  const sessions = [];
108940
109075
  try {
@@ -108942,13 +109077,13 @@ async function getFileMainSessions(directory) {
108942
109077
  for (const projectDir of projectDirs) {
108943
109078
  if (!projectDir.isDirectory())
108944
109079
  continue;
108945
- const projectPath = join102(SESSION_STORAGE, projectDir.name);
109080
+ const projectPath = join104(SESSION_STORAGE, projectDir.name);
108946
109081
  const sessionFiles = await readdir6(projectPath);
108947
109082
  for (const file2 of sessionFiles) {
108948
109083
  if (!file2.endsWith(".json"))
108949
109084
  continue;
108950
109085
  try {
108951
- const content = await readFile9(join102(projectPath, file2), "utf-8");
109086
+ const content = await readFile9(join104(projectPath, file2), "utf-8");
108952
109087
  const meta = JSON.parse(content);
108953
109088
  if (meta.parentID)
108954
109089
  continue;
@@ -108968,7 +109103,7 @@ async function getFileMainSessions(directory) {
108968
109103
  return sessions.sort((a, b) => b.time.updated - a.time.updated);
108969
109104
  }
108970
109105
  async function getFileAllSessions() {
108971
- if (!existsSync90(MESSAGE_STORAGE))
109106
+ if (!existsSync91(MESSAGE_STORAGE))
108972
109107
  return [];
108973
109108
  const sessions = [];
108974
109109
  async function scanDirectory(dir) {
@@ -108977,7 +109112,7 @@ async function getFileAllSessions() {
108977
109112
  for (const entry of entries) {
108978
109113
  if (!entry.isDirectory())
108979
109114
  continue;
108980
- const sessionPath = join102(dir, entry.name);
109115
+ const sessionPath = join104(dir, entry.name);
108981
109116
  const files = await readdir6(sessionPath);
108982
109117
  if (files.some((file2) => file2.endsWith(".json"))) {
108983
109118
  sessions.push(entry.name);
@@ -108998,7 +109133,7 @@ async function fileSessionExists(sessionID) {
108998
109133
  }
108999
109134
  async function getFileSessionMessages(sessionID) {
109000
109135
  const messageDir = getMessageDir(sessionID);
109001
- if (!messageDir || !existsSync90(messageDir))
109136
+ if (!messageDir || !existsSync91(messageDir))
109002
109137
  return [];
109003
109138
  const messages = [];
109004
109139
  try {
@@ -109007,7 +109142,7 @@ async function getFileSessionMessages(sessionID) {
109007
109142
  if (!file2.endsWith(".json"))
109008
109143
  continue;
109009
109144
  try {
109010
- const content = await readFile9(join102(messageDir, file2), "utf-8");
109145
+ const content = await readFile9(join104(messageDir, file2), "utf-8");
109011
109146
  const meta = JSON.parse(content);
109012
109147
  const parts = await readParts2(meta.id);
109013
109148
  messages.push({
@@ -109035,8 +109170,8 @@ async function getFileSessionMessages(sessionID) {
109035
109170
  });
109036
109171
  }
109037
109172
  async function readParts2(messageID) {
109038
- const partDir = join102(PART_STORAGE, messageID);
109039
- if (!existsSync90(partDir))
109173
+ const partDir = join104(PART_STORAGE, messageID);
109174
+ if (!existsSync91(partDir))
109040
109175
  return [];
109041
109176
  const parts = [];
109042
109177
  try {
@@ -109045,7 +109180,7 @@ async function readParts2(messageID) {
109045
109180
  if (!file2.endsWith(".json"))
109046
109181
  continue;
109047
109182
  try {
109048
- const content = await readFile9(join102(partDir, file2), "utf-8");
109183
+ const content = await readFile9(join104(partDir, file2), "utf-8");
109049
109184
  parts.push(JSON.parse(content));
109050
109185
  } catch (error) {
109051
109186
  ignoreFileStorageError(error);
@@ -109059,14 +109194,14 @@ async function readParts2(messageID) {
109059
109194
  return parts.sort((a, b) => a.id.localeCompare(b.id));
109060
109195
  }
109061
109196
  async function getFileSessionTodos(sessionID) {
109062
- if (!existsSync90(TODO_DIR2))
109197
+ if (!existsSync91(TODO_DIR2))
109063
109198
  return [];
109064
109199
  try {
109065
109200
  const allFiles = await readdir6(TODO_DIR2);
109066
109201
  const todoFiles = allFiles.filter((file2) => file2 === `${sessionID}.json`);
109067
109202
  for (const file2 of todoFiles) {
109068
109203
  try {
109069
- const content = await readFile9(join102(TODO_DIR2, file2), "utf-8");
109204
+ const content = await readFile9(join104(TODO_DIR2, file2), "utf-8");
109070
109205
  const data = JSON.parse(content);
109071
109206
  if (!Array.isArray(data))
109072
109207
  continue;
@@ -109088,10 +109223,10 @@ async function getFileSessionTodos(sessionID) {
109088
109223
  return [];
109089
109224
  }
109090
109225
  async function getFileSessionTranscript(sessionID) {
109091
- if (!existsSync90(TRANSCRIPT_DIR2))
109226
+ if (!existsSync91(TRANSCRIPT_DIR2))
109092
109227
  return 0;
109093
- const transcriptFile = join102(TRANSCRIPT_DIR2, `${sessionID}.jsonl`);
109094
- if (!existsSync90(transcriptFile))
109228
+ const transcriptFile = join104(TRANSCRIPT_DIR2, `${sessionID}.jsonl`);
109229
+ if (!existsSync91(transcriptFile))
109095
109230
  return 0;
109096
109231
  try {
109097
109232
  const content = await readFile9(transcriptFile, "utf-8");
@@ -110024,7 +110159,7 @@ function createSkillMcpTool(options) {
110024
110159
  },
110025
110160
  async execute(args, toolContext) {
110026
110161
  const operation = validateOperationParams(args);
110027
- const skills = getLoadedSkills();
110162
+ const skills = await getLoadedSkills();
110028
110163
  const found = findMcpServer(args.mcp_name, skills);
110029
110164
  if (!found) {
110030
110165
  const builtinHint = formatBuiltinMcpHint(args.mcp_name);
@@ -110910,23 +111045,23 @@ Pass \`session_id=<id>\` to continue previous agent with full context. Nested su
110910
111045
  // packages/omo-opencode/src/tools/call-omo-agent/tools.ts
110911
111046
  init_plugin_identity();
110912
111047
  // packages/claude-code-compat-core/src/features/claude-code-agent-loader/loader.ts
110913
- import { existsSync as existsSync95, readdirSync as readdirSync23 } from "fs";
110914
- import { join as join108 } from "path";
111048
+ import { existsSync as existsSync96, readdirSync as readdirSync23 } from "fs";
111049
+ import { join as join110 } from "path";
110915
111050
 
110916
111051
  // packages/claude-code-compat-core/src/shared/claude-config-dir.ts
110917
111052
  import { homedir as homedir29 } from "os";
110918
- import { join as join103 } from "path";
111053
+ import { join as join105 } from "path";
110919
111054
  function getClaudeConfigDir3() {
110920
111055
  const envConfigDir = process.env.CLAUDE_CONFIG_DIR;
110921
111056
  if (envConfigDir) {
110922
111057
  return envConfigDir;
110923
111058
  }
110924
- return join103(process.env.HOME || process.env.USERPROFILE || homedir29(), ".claude");
111059
+ return join105(process.env.HOME || process.env.USERPROFILE || homedir29(), ".claude");
110925
111060
  }
110926
111061
  // packages/claude-code-compat-core/src/shared/opencode-config-dir.ts
110927
- import { existsSync as existsSync91, realpathSync as realpathSync15 } from "fs";
111062
+ import { existsSync as existsSync92, realpathSync as realpathSync15 } from "fs";
110928
111063
  import { homedir as homedir30 } from "os";
110929
- import { join as join104, posix as posix7, resolve as resolve33, win32 as win3210 } from "path";
111064
+ import { join as join106, posix as posix7, resolve as resolve33, win32 as win3210 } from "path";
110930
111065
  var TAURI_APP_IDENTIFIER3 = "ai.opencode.desktop";
110931
111066
  var TAURI_APP_IDENTIFIER_DEV3 = "ai.opencode.desktop.dev";
110932
111067
  function isDevBuild3(version) {
@@ -110938,15 +111073,15 @@ function getTauriConfigDir3(identifier) {
110938
111073
  const platform2 = process.platform;
110939
111074
  switch (platform2) {
110940
111075
  case "darwin":
110941
- return join104(homedir30(), "Library", "Application Support", identifier);
111076
+ return join106(homedir30(), "Library", "Application Support", identifier);
110942
111077
  case "win32": {
110943
- const appData = process.env.APPDATA || join104(homedir30(), "AppData", "Roaming");
111078
+ const appData = process.env.APPDATA || join106(homedir30(), "AppData", "Roaming");
110944
111079
  return win3210.join(appData, identifier);
110945
111080
  }
110946
111081
  case "linux":
110947
111082
  default: {
110948
- const xdgConfig = process.env.XDG_CONFIG_HOME || join104(homedir30(), ".config");
110949
- return join104(xdgConfig, identifier);
111083
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join106(homedir30(), ".config");
111084
+ return join106(xdgConfig, identifier);
110950
111085
  }
110951
111086
  }
110952
111087
  }
@@ -110955,7 +111090,7 @@ function resolveConfigPath3(pathValue) {
110955
111090
  return posix7.normalize(pathValue);
110956
111091
  }
110957
111092
  const resolvedPath = resolve33(pathValue);
110958
- if (!existsSync91(resolvedPath))
111093
+ if (!existsSync92(resolvedPath))
110959
111094
  return resolvedPath;
110960
111095
  try {
110961
111096
  return realpathSync15(resolvedPath);
@@ -110989,8 +111124,8 @@ function getWslLinuxHomeDir3(windowsConfigRoot) {
110989
111124
  function getCliDefaultConfigDir3() {
110990
111125
  const envXdgConfig = process.env.XDG_CONFIG_HOME?.trim();
110991
111126
  const shouldIgnoreWindowsXdg = envXdgConfig !== undefined && envXdgConfig.length > 0 && isWslEnvironment3() && isWindowsUserConfigRoot3(envXdgConfig);
110992
- const xdgConfig = shouldIgnoreWindowsXdg ? posix7.join(getWslLinuxHomeDir3(envXdgConfig) ?? "/home", ".config") : envXdgConfig || join104(homedir30(), ".config");
110993
- const configDir = isWslEnvironment3() ? posix7.join(xdgConfig, "opencode") : join104(xdgConfig, "opencode");
111127
+ const xdgConfig = shouldIgnoreWindowsXdg ? posix7.join(getWslLinuxHomeDir3(envXdgConfig) ?? "/home", ".config") : envXdgConfig || join106(homedir30(), ".config");
111128
+ const configDir = isWslEnvironment3() ? posix7.join(xdgConfig, "opencode") : join106(xdgConfig, "opencode");
110994
111129
  return resolveConfigPath3(configDir);
110995
111130
  }
110996
111131
  function getCliCustomConfigDir3() {
@@ -111023,9 +111158,9 @@ function getOpenCodeConfigDir3(options) {
111023
111158
  const tauriDir = process.platform === "win32" ? win3210.isAbsolute(tauriDirBase) ? win3210.normalize(tauriDirBase) : win3210.resolve(tauriDirBase) : resolveConfigPath3(tauriDirBase);
111024
111159
  if (checkExisting) {
111025
111160
  const legacyDir = getCliConfigDir3();
111026
- const legacyConfig = join104(legacyDir, "opencode.json");
111027
- const legacyConfigC = join104(legacyDir, "opencode.jsonc");
111028
- if (existsSync91(legacyConfig) || existsSync91(legacyConfigC)) {
111161
+ const legacyConfig = join106(legacyDir, "opencode.json");
111162
+ const legacyConfigC = join106(legacyDir, "opencode.jsonc");
111163
+ if (existsSync92(legacyConfig) || existsSync92(legacyConfigC)) {
111029
111164
  return legacyDir;
111030
111165
  }
111031
111166
  }
@@ -111035,10 +111170,10 @@ function getOpenCodeConfigDir3(options) {
111035
111170
  init_src();
111036
111171
  // packages/claude-code-compat-core/src/shared/resolve-agent-definition-paths.ts
111037
111172
  import { homedir as homedir31 } from "os";
111038
- import { isAbsolute as isAbsolute18, join as join105, resolve as resolve34 } from "path";
111173
+ import { isAbsolute as isAbsolute18, join as join107, resolve as resolve34 } from "path";
111039
111174
  function resolveAgentDefinitionPaths2(paths, baseDir, containmentDir) {
111040
111175
  return paths.flatMap((p) => {
111041
- const expanded = p.startsWith("~/") ? join105(homedir31(), p.slice(2)) : p;
111176
+ const expanded = p.startsWith("~/") ? join107(homedir31(), p.slice(2)) : p;
111042
111177
  const resolved = isAbsolute18(expanded) ? expanded : resolve34(baseDir, expanded);
111043
111178
  if (containmentDir !== null && !isWithinProject(resolved, containmentDir)) {
111044
111179
  log4(`agent_definitions path rejected (outside project boundary): ${p} -> ${resolved}`);
@@ -111066,13 +111201,13 @@ var EXCLUDED_DIR_NAMES2 = [
111066
111201
  ];
111067
111202
  var EXCLUDED_DIRS3 = Object.freeze(new Set(EXCLUDED_DIR_NAMES2));
111068
111203
  // packages/claude-code-compat-core/src/shared/opencode-command-dirs.ts
111069
- import { basename as basename18, dirname as dirname34, join as join106 } from "path";
111204
+ import { basename as basename18, dirname as dirname35, join as join108 } from "path";
111070
111205
  function getParentOpencodeConfigDir3(configDir) {
111071
- const parentDir = dirname34(configDir);
111206
+ const parentDir = dirname35(configDir);
111072
111207
  if (basename18(parentDir) !== "profiles") {
111073
111208
  return null;
111074
111209
  }
111075
- return dirname34(parentDir);
111210
+ return dirname35(parentDir);
111076
111211
  }
111077
111212
  function getOpenCodeCommandDirs2(options) {
111078
111213
  const configDirs = getOpenCodeConfigDirs3(options);
@@ -111080,21 +111215,21 @@ function getOpenCodeCommandDirs2(options) {
111080
111215
  ...configDirs.flatMap((configDir) => {
111081
111216
  const parentConfigDir = getParentOpencodeConfigDir3(configDir);
111082
111217
  return [
111083
- join106(configDir, "commands"),
111084
- join106(configDir, "command"),
111085
- ...parentConfigDir ? [join106(parentConfigDir, "commands"), join106(parentConfigDir, "command")] : []
111218
+ join108(configDir, "commands"),
111219
+ join108(configDir, "command"),
111220
+ ...parentConfigDir ? [join108(parentConfigDir, "commands"), join108(parentConfigDir, "command")] : []
111086
111221
  ];
111087
111222
  })
111088
111223
  ]));
111089
111224
  }
111090
111225
  // packages/claude-code-compat-core/src/shared/project-discovery-dirs.ts
111091
111226
  import { execFileSync as execFileSync6 } from "child_process";
111092
- import { existsSync as existsSync92, realpathSync as realpathSync16 } from "fs";
111093
- import { dirname as dirname35, join as join107, resolve as resolve35, win32 as win3211 } from "path";
111227
+ import { existsSync as existsSync93, realpathSync as realpathSync16 } from "fs";
111228
+ import { dirname as dirname36, join as join109, resolve as resolve35, win32 as win3211 } from "path";
111094
111229
  var worktreePathCache3 = new Map;
111095
111230
  function normalizePath6(path18) {
111096
111231
  const resolvedPath = process.platform !== "win32" && win3211.isAbsolute(path18) ? path18 : resolve35(path18);
111097
- if (!existsSync92(resolvedPath)) {
111232
+ if (!existsSync93(resolvedPath)) {
111098
111233
  return resolvedPath;
111099
111234
  }
111100
111235
  try {
@@ -111149,10 +111284,10 @@ function detectWorktreePath4(directory) {
111149
111284
  function findGitMarkerAncestor(directory) {
111150
111285
  let currentDirectory = normalizePath6(directory);
111151
111286
  while (true) {
111152
- if (existsSync92(join107(currentDirectory, ".git"))) {
111287
+ if (existsSync93(join109(currentDirectory, ".git"))) {
111153
111288
  return currentDirectory;
111154
111289
  }
111155
- const parentDirectory = dirname35(currentDirectory);
111290
+ const parentDirectory = dirname36(currentDirectory);
111156
111291
  if (parentDirectory === currentDirectory) {
111157
111292
  return;
111158
111293
  }
@@ -111167,8 +111302,8 @@ function findAncestorDirectories3(startDirectory, targetPaths, stopDirectory) {
111167
111302
  const stopDirectoryKey = resolvedStopDirectory ? pathKey3(resolvedStopDirectory) : undefined;
111168
111303
  while (true) {
111169
111304
  for (const targetPath of targetPaths) {
111170
- const candidateDirectory = join107(currentDirectory, ...targetPath);
111171
- if (!existsSync92(candidateDirectory)) {
111305
+ const candidateDirectory = join109(currentDirectory, ...targetPath);
111306
+ if (!existsSync93(candidateDirectory)) {
111172
111307
  continue;
111173
111308
  }
111174
111309
  const normalizedCandidateDirectory = normalizePath6(candidateDirectory);
@@ -111182,7 +111317,7 @@ function findAncestorDirectories3(startDirectory, targetPaths, stopDirectory) {
111182
111317
  if (stopDirectoryKey === pathKey3(currentDirectory)) {
111183
111318
  return directories;
111184
111319
  }
111185
- const parentDirectory = dirname35(currentDirectory);
111320
+ const parentDirectory = dirname36(currentDirectory);
111186
111321
  if (parentDirectory === currentDirectory) {
111187
111322
  return directories;
111188
111323
  }
@@ -111197,14 +111332,14 @@ function findProjectOpencodeCommandDirs2(startDirectory, stopDirectory) {
111197
111332
  ], detectedStopDirectory);
111198
111333
  }
111199
111334
  // packages/claude-code-compat-core/src/features/claude-code-agent-loader/agent-definitions-loader.ts
111200
- import { existsSync as existsSync94, readFileSync as readFileSync61 } from "fs";
111335
+ import { existsSync as existsSync95, readFileSync as readFileSync61 } from "fs";
111201
111336
  import { basename as basename19, extname as extname4 } from "path";
111202
111337
 
111203
111338
  // packages/claude-code-compat-core/src/features/claude-code-agent-loader/json-agent-loader.ts
111204
- import { existsSync as existsSync93, readFileSync as readFileSync60 } from "fs";
111339
+ import { existsSync as existsSync94, readFileSync as readFileSync60 } from "fs";
111205
111340
  function parseJsonAgentFile(filePath, scope) {
111206
111341
  try {
111207
- if (!existsSync93(filePath)) {
111342
+ if (!existsSync94(filePath)) {
111208
111343
  return null;
111209
111344
  }
111210
111345
  const content = readFileSync60(filePath, "utf-8");
@@ -111245,7 +111380,7 @@ function parseJsonAgentFile(filePath, scope) {
111245
111380
  // packages/claude-code-compat-core/src/features/claude-code-agent-loader/agent-definitions-loader.ts
111246
111381
  function parseMarkdownAgentFile(filePath, scope, anthropicProvider) {
111247
111382
  try {
111248
- if (!existsSync94(filePath)) {
111383
+ if (!existsSync95(filePath)) {
111249
111384
  return null;
111250
111385
  }
111251
111386
  const content = readFileSync61(filePath, "utf-8");
@@ -111282,7 +111417,7 @@ function parseMarkdownAgentFile(filePath, scope, anthropicProvider) {
111282
111417
  function loadAgentDefinitions(paths, scope, anthropicProvider) {
111283
111418
  const result = Object.create(null);
111284
111419
  for (const filePath of paths) {
111285
- if (!existsSync94(filePath)) {
111420
+ if (!existsSync95(filePath)) {
111286
111421
  log4(`[agent-definitions-loader] File not found, skipping: ${filePath}`);
111287
111422
  continue;
111288
111423
  }
@@ -111307,7 +111442,7 @@ function loadAgentDefinitions(paths, scope, anthropicProvider) {
111307
111442
 
111308
111443
  // packages/claude-code-compat-core/src/features/claude-code-agent-loader/loader.ts
111309
111444
  function loadAgentsFromDir(agentsDir, scope, anthropicProvider) {
111310
- if (!existsSync95(agentsDir)) {
111445
+ if (!existsSync96(agentsDir)) {
111311
111446
  return [];
111312
111447
  }
111313
111448
  const entries = readdirSync23(agentsDir, { withFileTypes: true });
@@ -111315,7 +111450,7 @@ function loadAgentsFromDir(agentsDir, scope, anthropicProvider) {
111315
111450
  for (const entry of entries) {
111316
111451
  if (!isMarkdownFile(entry))
111317
111452
  continue;
111318
- const agentPath = join108(agentsDir, entry.name);
111453
+ const agentPath = join110(agentsDir, entry.name);
111319
111454
  const agent = parseMarkdownAgentFile(agentPath, scope, anthropicProvider);
111320
111455
  if (agent) {
111321
111456
  agents.push(agent);
@@ -111324,7 +111459,7 @@ function loadAgentsFromDir(agentsDir, scope, anthropicProvider) {
111324
111459
  return agents;
111325
111460
  }
111326
111461
  function loadUserAgents(anthropicProvider) {
111327
- const userAgentsDir = join108(getClaudeConfigDir3(), "agents");
111462
+ const userAgentsDir = join110(getClaudeConfigDir3(), "agents");
111328
111463
  const agents = loadAgentsFromDir(userAgentsDir, "user", anthropicProvider);
111329
111464
  const result = Object.create(null);
111330
111465
  for (const agent of agents) {
@@ -111333,7 +111468,7 @@ function loadUserAgents(anthropicProvider) {
111333
111468
  return result;
111334
111469
  }
111335
111470
  function loadProjectAgents(directory, anthropicProvider) {
111336
- const projectAgentsDir = join108(directory ?? process.cwd(), ".claude", "agents");
111471
+ const projectAgentsDir = join110(directory ?? process.cwd(), ".claude", "agents");
111337
111472
  const agents = loadAgentsFromDir(projectAgentsDir, "project", anthropicProvider);
111338
111473
  const result = Object.create(null);
111339
111474
  for (const agent of agents) {
@@ -111345,7 +111480,7 @@ function loadOpencodeGlobalAgents() {
111345
111480
  const result = Object.create(null);
111346
111481
  const configDirs = getOpenCodeConfigDirs3({ binary: "opencode" });
111347
111482
  for (const configDir of configDirs) {
111348
- const opencodeAgentsDir = join108(configDir, "agents");
111483
+ const opencodeAgentsDir = join110(configDir, "agents");
111349
111484
  const agents = loadAgentsFromDir(opencodeAgentsDir, "opencode");
111350
111485
  for (const agent of agents) {
111351
111486
  if (!(agent.name in result)) {
@@ -111356,7 +111491,7 @@ function loadOpencodeGlobalAgents() {
111356
111491
  return result;
111357
111492
  }
111358
111493
  function loadOpencodeProjectAgents(directory) {
111359
- const opencodeProjectDir = join108(directory ?? process.cwd(), ".opencode", "agents");
111494
+ const opencodeProjectDir = join110(directory ?? process.cwd(), ".opencode", "agents");
111360
111495
  const agents = loadAgentsFromDir(opencodeProjectDir, "opencode-project");
111361
111496
  const result = Object.create(null);
111362
111497
  for (const agent of agents) {
@@ -111951,6 +112086,28 @@ async function resolveCallableAgents(_client, _sessionId) {
111951
112086
  return [...ALLOWED_AGENTS];
111952
112087
  }
111953
112088
 
112089
+ // packages/omo-opencode/src/agents/builtin-agents/model-resolution.ts
112090
+ function applyModelResolution(input) {
112091
+ const { uiSelectedModel, userModel, requirement, availableModels, systemDefaultModel } = input;
112092
+ return resolveModelPipeline2({
112093
+ intent: { uiSelectedModel, userModel },
112094
+ constraints: { availableModels },
112095
+ policy: { fallbackChain: requirement?.fallbackChain, systemDefaultModel }
112096
+ });
112097
+ }
112098
+ function getFirstFallbackModel(requirement) {
112099
+ const entry = requirement?.fallbackChain?.[0];
112100
+ if (!entry || entry.providers.length === 0)
112101
+ return;
112102
+ const provider = entry.providers[0];
112103
+ const transformedModel = transformModelForProvider(provider, entry.model);
112104
+ return {
112105
+ model: `${provider}/${transformedModel}`,
112106
+ provenance: "provider-fallback",
112107
+ variant: entry.variant
112108
+ };
112109
+ }
112110
+
111954
112111
  // packages/omo-opencode/src/tools/call-omo-agent/tools.ts
111955
112112
  function createSyncExecutorDeps(modelFallbackControllerAccessor) {
111956
112113
  return {
@@ -111995,6 +112152,19 @@ function resolveModelAndFallbackChain(args) {
111995
112152
  variant: variantToUse
111996
112153
  });
111997
112154
  }
112155
+ } else {
112156
+ const firstFallback = getFirstFallbackModel(agentRequirement);
112157
+ if (firstFallback) {
112158
+ const normalized = parseModelString(firstFallback.model);
112159
+ if (normalized) {
112160
+ model = firstFallback.variant ? { ...normalized, variant: firstFallback.variant } : normalized;
112161
+ log2("[call_omo_agent] Resolved model from first fallbackChain entry", {
112162
+ agent: subagentType,
112163
+ model: firstFallback.model,
112164
+ variant: firstFallback.variant
112165
+ });
112166
+ }
112167
+ }
111998
112168
  }
111999
112169
  const normalizedFallbackModels = normalizeFallbackModels(agentOverride?.fallback_models ?? (agentOverride?.category ? userCategories?.[agentOverride.category]?.fallback_models : undefined));
112000
112170
  const defaultProviderID = model?.providerID ?? agentRequirement?.fallbackChain?.[0]?.providers?.[0] ?? "opencode";
@@ -112091,9 +112261,9 @@ function validateArgs(args) {
112091
112261
  const normalizedArgs = args;
112092
112262
  const filePath = args.file_path;
112093
112263
  const hasFilePath = hasNonEmptyString(args.file_path);
112094
- const hasFilePaths = Array.isArray(args.file_paths);
112264
+ const hasFilePaths = hasValues(args.file_paths);
112095
112265
  const hasImageData = hasNonEmptyString(args.image_data);
112096
- const hasImageDataList = Array.isArray(args.image_data_list);
112266
+ const hasImageDataList = hasValues(args.image_data_list);
112097
112267
  const filePathsFromSingular = normalizedArgs._normalized_file_paths_from_singular === true;
112098
112268
  const imageDataListFromSingular = normalizedArgs._normalized_image_data_list_from_singular === true;
112099
112269
  if (hasFilePath && hasFilePaths && !filePathsFromSingular) {
@@ -112102,12 +112272,6 @@ function validateArgs(args) {
112102
112272
  if (hasImageData && hasImageDataList && !imageDataListFromSingular) {
112103
112273
  return "Error: Provide either 'image_data' or 'image_data_list', not both.";
112104
112274
  }
112105
- if (hasFilePaths && !hasValues(args.file_paths)) {
112106
- return "Error: 'file_paths' must contain at least one local file path.";
112107
- }
112108
- if (hasImageDataList && !hasValues(args.image_data_list)) {
112109
- return "Error: 'image_data_list' must contain at least one Base64 image string.";
112110
- }
112111
112275
  if (hasValues(args.file_paths)) {
112112
112276
  for (const filePath2 of args.file_paths) {
112113
112277
  if (!hasNonEmptyString(filePath2)) {
@@ -112128,7 +112292,7 @@ function validateArgs(args) {
112128
112292
  if (hasNonEmptyString(filePath) && isRemoteUrl(filePath)) {
112129
112293
  return "Error: Remote URLs are not supported for file_path. Download the file first or use a local path.";
112130
112294
  }
112131
- if (!hasFilePath && !hasValues(args.file_paths) && !hasImageData && !hasValues(args.image_data_list)) {
112295
+ if (!hasFilePath && !hasFilePaths && !hasImageData && !hasImageDataList) {
112132
112296
  return `Error: Must provide at least one of 'file_path', 'file_paths', 'image_data', or 'image_data_list'. Usage:
112133
112297
  - look_at(file_path="/path/to/file", goal="what to extract")
112134
112298
  - look_at(file_paths=["/path/to/file-1", "/path/to/file-2"], goal="what to extract")
@@ -112147,9 +112311,9 @@ import { pathToFileURL } from "url";
112147
112311
 
112148
112312
  // packages/omo-opencode/src/tools/look-at/image-converter.ts
112149
112313
  import * as childProcess2 from "child_process";
112150
- import { existsSync as existsSync97, mkdtempSync, readFileSync as readFileSync63, rmSync as rmSync5, unlinkSync as unlinkSync14, writeFileSync as writeFileSync18 } from "fs";
112314
+ import { existsSync as existsSync98, mkdtempSync, readFileSync as readFileSync63, rmSync as rmSync5, unlinkSync as unlinkSync14, writeFileSync as writeFileSync18 } from "fs";
112151
112315
  import { tmpdir as tmpdir7 } from "os";
112152
- import { dirname as dirname37, join as join110 } from "path";
112316
+ import { dirname as dirname38, join as join112 } from "path";
112153
112317
  var SUPPORTED_FORMATS = new Set([
112154
112318
  "image/jpeg",
112155
112319
  "image/png",
@@ -112179,7 +112343,7 @@ var UNSUPPORTED_FORMATS = new Set([
112179
112343
  var CONVERSION_TIMEOUT_MS = 30000;
112180
112344
  function cleanupTemporaryFileAfterFailure(filePath) {
112181
112345
  try {
112182
- if (existsSync97(filePath)) {
112346
+ if (existsSync98(filePath)) {
112183
112347
  unlinkSync14(filePath);
112184
112348
  }
112185
112349
  } catch (cleanupError) {
@@ -112197,11 +112361,11 @@ function needsConversion(mimeType) {
112197
112361
  return mimeType.startsWith("image/");
112198
112362
  }
112199
112363
  function convertImageToJpeg(inputPath, mimeType) {
112200
- if (!existsSync97(inputPath)) {
112364
+ if (!existsSync98(inputPath)) {
112201
112365
  throw new Error(`File not found: ${inputPath}`);
112202
112366
  }
112203
- const tempDir = mkdtempSync(join110(tmpdir7(), "opencode-img-"));
112204
- const outputPath = join110(tempDir, "converted.jpg");
112367
+ const tempDir = mkdtempSync(join112(tmpdir7(), "opencode-img-"));
112368
+ const outputPath = join112(tempDir, "converted.jpg");
112205
112369
  log2(`[image-converter] Converting ${mimeType} to JPEG: ${inputPath}`);
112206
112370
  try {
112207
112371
  if (process.platform === "darwin") {
@@ -112211,7 +112375,7 @@ function convertImageToJpeg(inputPath, mimeType) {
112211
112375
  encoding: "utf-8",
112212
112376
  timeout: CONVERSION_TIMEOUT_MS
112213
112377
  });
112214
- if (existsSync97(outputPath)) {
112378
+ if (existsSync98(outputPath)) {
112215
112379
  log2(`[image-converter] Converted using sips: ${outputPath}`);
112216
112380
  return outputPath;
112217
112381
  }
@@ -112227,7 +112391,7 @@ function convertImageToJpeg(inputPath, mimeType) {
112227
112391
  encoding: "utf-8",
112228
112392
  timeout: CONVERSION_TIMEOUT_MS
112229
112393
  });
112230
- if (existsSync97(outputPath)) {
112394
+ if (existsSync98(outputPath)) {
112231
112395
  log2(`[image-converter] Converted using ImageMagick: ${outputPath}`);
112232
112396
  return outputPath;
112233
112397
  }
@@ -112250,12 +112414,12 @@ function convertImageToJpeg(inputPath, mimeType) {
112250
112414
  }
112251
112415
  function cleanupConvertedImage(filePath) {
112252
112416
  try {
112253
- const tempDirectory = dirname37(filePath);
112254
- if (existsSync97(filePath)) {
112417
+ const tempDirectory = dirname38(filePath);
112418
+ if (existsSync98(filePath)) {
112255
112419
  unlinkSync14(filePath);
112256
112420
  log2(`[image-converter] Cleaned up temporary file: ${filePath}`);
112257
112421
  }
112258
- if (existsSync97(tempDirectory)) {
112422
+ if (existsSync98(tempDirectory)) {
112259
112423
  rmSync5(tempDirectory, { recursive: true, force: true });
112260
112424
  log2(`[image-converter] Cleaned up temporary directory: ${tempDirectory}`);
112261
112425
  }
@@ -112265,9 +112429,9 @@ function cleanupConvertedImage(filePath) {
112265
112429
  }
112266
112430
  }
112267
112431
  function convertBase64ImageToJpeg(base64Data, mimeType) {
112268
- const tempDir = mkdtempSync(join110(tmpdir7(), "opencode-b64-"));
112432
+ const tempDir = mkdtempSync(join112(tmpdir7(), "opencode-b64-"));
112269
112433
  const inputExt = mimeType.split("/")[1] || "bin";
112270
- const inputPath = join110(tempDir, `input.${inputExt}`);
112434
+ const inputPath = join112(tempDir, `input.${inputExt}`);
112271
112435
  const tempFiles = [inputPath];
112272
112436
  try {
112273
112437
  const cleanBase64 = base64Data.replace(/^data:[^;]+;base64,/, "");
@@ -115010,7 +115174,8 @@ var syncTaskDeps = {
115010
115174
  createSyncSession,
115011
115175
  sendSyncPrompt,
115012
115176
  pollSyncSession,
115013
- fetchSyncResult
115177
+ fetchSyncResult,
115178
+ isProviderExhaustionFallbackEligible
115014
115179
  };
115015
115180
 
115016
115181
  // packages/omo-opencode/src/tools/delegate-task/sync-task-metadata.ts
@@ -115196,6 +115361,10 @@ function addRetryTaskToast(input) {
115196
115361
  modelInfo: input.modelInfo
115197
115362
  });
115198
115363
  }
115364
+ function shouldRetryPollErrorWithFallback(pollError, deps) {
115365
+ const errorInfo = { message: pollError };
115366
+ return shouldRetryError(errorInfo) || (deps.isProviderExhaustionFallbackEligible?.(errorInfo) ?? false);
115367
+ }
115199
115368
  async function runSyncTaskLoop(input) {
115200
115369
  const {
115201
115370
  args,
@@ -115295,7 +115464,7 @@ async function runSyncTaskLoop(input) {
115295
115464
  });
115296
115465
  }
115297
115466
  }
115298
- const nextFallbackModel = shouldRetryError({ message: pollError }) ? getNextSyncFallbackModel(activeSessionID, fallbackState) : null;
115467
+ const nextFallbackModel = shouldRetryPollErrorWithFallback(pollError, deps) ? getNextSyncFallbackModel(activeSessionID, fallbackState) : null;
115299
115468
  if (!nextFallbackModel) {
115300
115469
  return pollError;
115301
115470
  }
@@ -116384,7 +116553,7 @@ function isExplicitSyncRun(runInBackground) {
116384
116553
  return runInBackground === false || runInBackground === "false";
116385
116554
  }
116386
116555
  // packages/omo-opencode/src/tools/task/task-create.ts
116387
- import { join as join112 } from "path";
116556
+ import { join as join114 } from "path";
116388
116557
 
116389
116558
  // packages/omo-opencode/src/tools/task/types.ts
116390
116559
  import { z as z4 } from "zod";
@@ -116439,8 +116608,8 @@ var TaskDeleteInputSchema = z4.object({
116439
116608
  });
116440
116609
 
116441
116610
  // packages/omo-opencode/src/features/claude-tasks/storage.ts
116442
- import { join as join111, dirname as dirname38, basename as basename21, isAbsolute as isAbsolute19 } from "path";
116443
- import { existsSync as existsSync98, mkdirSync as mkdirSync19, readFileSync as readFileSync65, writeFileSync as writeFileSync19, renameSync as renameSync7, unlinkSync as unlinkSync15, readdirSync as readdirSync24 } from "fs";
116611
+ import { join as join113, dirname as dirname39, basename as basename21, isAbsolute as isAbsolute19 } from "path";
116612
+ import { existsSync as existsSync99, mkdirSync as mkdirSync19, readFileSync as readFileSync65, writeFileSync as writeFileSync19, renameSync as renameSync7, unlinkSync as unlinkSync15, readdirSync as readdirSync24 } from "fs";
116444
116613
  import { randomUUID as randomUUID7 } from "crypto";
116445
116614
  function ignoreClaudeTaskStorageError(error) {
116446
116615
  if (error instanceof Error)
@@ -116451,11 +116620,11 @@ function getTaskDir(config = {}) {
116451
116620
  const tasksConfig = config.sisyphus?.tasks;
116452
116621
  const storagePath = tasksConfig?.storage_path;
116453
116622
  if (storagePath) {
116454
- return isAbsolute19(storagePath) ? storagePath : join111(process.cwd(), storagePath);
116623
+ return isAbsolute19(storagePath) ? storagePath : join113(process.cwd(), storagePath);
116455
116624
  }
116456
116625
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
116457
116626
  const listId = resolveTaskListId(config);
116458
- return join111(configDir, "tasks", listId);
116627
+ return join113(configDir, "tasks", listId);
116459
116628
  }
116460
116629
  function sanitizePathSegment(value) {
116461
116630
  return value.replace(/[^a-zA-Z0-9_-]/g, "-") || "default";
@@ -116473,13 +116642,13 @@ function resolveTaskListId(config = {}) {
116473
116642
  return sanitizePathSegment(basename21(process.cwd()));
116474
116643
  }
116475
116644
  function ensureDir(dirPath) {
116476
- if (!existsSync98(dirPath)) {
116645
+ if (!existsSync99(dirPath)) {
116477
116646
  mkdirSync19(dirPath, { recursive: true });
116478
116647
  }
116479
116648
  }
116480
116649
  function readJsonSafe(filePath, schema) {
116481
116650
  try {
116482
- if (!existsSync98(filePath)) {
116651
+ if (!existsSync99(filePath)) {
116483
116652
  return null;
116484
116653
  }
116485
116654
  const content = readFileSync65(filePath, "utf-8");
@@ -116495,7 +116664,7 @@ function readJsonSafe(filePath, schema) {
116495
116664
  }
116496
116665
  }
116497
116666
  function writeJsonAtomic(filePath, data) {
116498
- const dir = dirname38(filePath);
116667
+ const dir = dirname39(filePath);
116499
116668
  ensureDir(dir);
116500
116669
  const tempPath = `${filePath}.tmp.${Date.now()}`;
116501
116670
  try {
@@ -116503,7 +116672,7 @@ function writeJsonAtomic(filePath, data) {
116503
116672
  renameSync7(tempPath, filePath);
116504
116673
  } catch (error) {
116505
116674
  try {
116506
- if (existsSync98(tempPath)) {
116675
+ if (existsSync99(tempPath)) {
116507
116676
  unlinkSync15(tempPath);
116508
116677
  }
116509
116678
  } catch (cleanupError) {
@@ -116517,7 +116686,7 @@ function generateTaskId() {
116517
116686
  return `T-${randomUUID7()}`;
116518
116687
  }
116519
116688
  function acquireLock3(dirPath) {
116520
- const lockPath = join111(dirPath, ".lock");
116689
+ const lockPath = join113(dirPath, ".lock");
116521
116690
  const lockId = randomUUID7();
116522
116691
  const createLock = (timestamp) => {
116523
116692
  writeFileSync19(lockPath, JSON.stringify({ id: lockId, timestamp }), {
@@ -116568,7 +116737,7 @@ function acquireLock3(dirPath) {
116568
116737
  acquired: true,
116569
116738
  release: () => {
116570
116739
  try {
116571
- if (!existsSync98(lockPath))
116740
+ if (!existsSync99(lockPath))
116572
116741
  return;
116573
116742
  const lockContent = readFileSync65(lockPath, "utf-8");
116574
116743
  const lockData = JSON.parse(lockContent);
@@ -116735,7 +116904,7 @@ async function handleCreate(args, config, ctx, context) {
116735
116904
  threadID: context.sessionID
116736
116905
  };
116737
116906
  const validatedTask = TaskObjectSchema.parse(task);
116738
- writeJsonAtomic(join112(taskDir, `${taskId}.json`), validatedTask);
116907
+ writeJsonAtomic(join114(taskDir, `${taskId}.json`), validatedTask);
116739
116908
  await syncTaskTodoUpdate(ctx, validatedTask, context.sessionID);
116740
116909
  return JSON.stringify({
116741
116910
  task: {
@@ -116757,7 +116926,7 @@ async function handleCreate(args, config, ctx, context) {
116757
116926
  }
116758
116927
  }
116759
116928
  // packages/omo-opencode/src/tools/task/task-get.ts
116760
- import { join as join113 } from "path";
116929
+ import { join as join115 } from "path";
116761
116930
  var TASK_ID_PATTERN = /^T-[A-Za-z0-9-]+$/;
116762
116931
  function parseTaskId(id) {
116763
116932
  if (!TASK_ID_PATTERN.test(id))
@@ -116782,7 +116951,7 @@ Returns null if the task does not exist or the file is invalid.`,
116782
116951
  return JSON.stringify({ error: "invalid_task_id" });
116783
116952
  }
116784
116953
  const taskDir = getTaskDir(config);
116785
- const taskPath = join113(taskDir, `${taskId}.json`);
116954
+ const taskPath = join115(taskDir, `${taskId}.json`);
116786
116955
  const task = readJsonSafe(taskPath, TaskObjectSchema);
116787
116956
  return JSON.stringify({ task: task ?? null });
116788
116957
  } catch (error) {
@@ -116795,8 +116964,8 @@ Returns null if the task does not exist or the file is invalid.`,
116795
116964
  });
116796
116965
  }
116797
116966
  // packages/omo-opencode/src/tools/task/task-list.ts
116798
- import { join as join114 } from "path";
116799
- import { existsSync as existsSync99, readdirSync as readdirSync25 } from "fs";
116967
+ import { join as join116 } from "path";
116968
+ import { existsSync as existsSync100, readdirSync as readdirSync25 } from "fs";
116800
116969
  function createTaskList(config) {
116801
116970
  return tool({
116802
116971
  description: `List all active tasks with summary information.
@@ -116807,7 +116976,7 @@ Returns summary format: id, subject, status, owner, blockedBy (not full descript
116807
116976
  args: {},
116808
116977
  execute: async () => {
116809
116978
  const taskDir = getTaskDir(config);
116810
- if (!existsSync99(taskDir)) {
116979
+ if (!existsSync100(taskDir)) {
116811
116980
  return JSON.stringify({ tasks: [] });
116812
116981
  }
116813
116982
  const files = readdirSync25(taskDir).filter((f) => f.endsWith(".json") && f.startsWith("T-")).map((f) => f.replace(".json", ""));
@@ -116816,7 +116985,7 @@ Returns summary format: id, subject, status, owner, blockedBy (not full descript
116816
116985
  }
116817
116986
  const allTasks = [];
116818
116987
  for (const fileId of files) {
116819
- const task = readJsonSafe(join114(taskDir, `${fileId}.json`), TaskObjectSchema);
116988
+ const task = readJsonSafe(join116(taskDir, `${fileId}.json`), TaskObjectSchema);
116820
116989
  if (task) {
116821
116990
  allTasks.push(task);
116822
116991
  }
@@ -116844,7 +117013,7 @@ Returns summary format: id, subject, status, owner, blockedBy (not full descript
116844
117013
  });
116845
117014
  }
116846
117015
  // packages/omo-opencode/src/tools/task/task-update.ts
116847
- import { join as join115 } from "path";
117016
+ import { join as join117 } from "path";
116848
117017
  var TASK_ID_PATTERN2 = /^T-[A-Za-z0-9-]+$/;
116849
117018
  function parseTaskId2(id) {
116850
117019
  if (!TASK_ID_PATTERN2.test(id))
@@ -116892,7 +117061,7 @@ async function handleUpdate(args, config, ctx, context) {
116892
117061
  return JSON.stringify({ error: "task_lock_unavailable" });
116893
117062
  }
116894
117063
  try {
116895
- const taskPath = join115(taskDir, `${taskId}.json`);
117064
+ const taskPath = join117(taskDir, `${taskId}.json`);
116896
117065
  const task = readJsonSafe(taskPath, TaskObjectSchema);
116897
117066
  if (!task) {
116898
117067
  return JSON.stringify({ error: "task_not_found" });
@@ -118465,7 +118634,7 @@ function createHooks(args) {
118465
118634
  };
118466
118635
  }
118467
118636
  // packages/omo-opencode/src/features/background-agent/manager.ts
118468
- import { join as join117 } from "path";
118637
+ import { join as join119 } from "path";
118469
118638
  init_tmux();
118470
118639
 
118471
118640
  // packages/omo-opencode/src/features/background-agent/abort-with-timeout.ts
@@ -118737,9 +118906,23 @@ Use \`background_output(task_id="${task.id}")\` to retrieve this result when rea
118737
118906
  </system-reminder>`;
118738
118907
  }
118739
118908
 
118909
+ // packages/omo-opencode/src/features/background-agent/background-task-marker.ts
118910
+ var BACKGROUND_COMPLETION_WAKE_PENDING_REASON = "background completion wake pending";
118911
+ function writeBackgroundTaskMarker(input) {
118912
+ if (input.activeTaskCount > 0) {
118913
+ setContinuationMarkerSource(input.directory, input.parentSessionID, "background-task", "active", `${input.activeTaskCount} background task(s) active`);
118914
+ return;
118915
+ }
118916
+ if (input.hasUndeliveredParentWake) {
118917
+ setContinuationMarkerSource(input.directory, input.parentSessionID, "background-task", "active", BACKGROUND_COMPLETION_WAKE_PENDING_REASON);
118918
+ return;
118919
+ }
118920
+ setContinuationMarkerSource(input.directory, input.parentSessionID, "background-task", "idle");
118921
+ }
118922
+
118740
118923
  // packages/omo-opencode/src/features/background-agent/compaction-aware-message-resolver.ts
118741
118924
  import { readdirSync as readdirSync26, readFileSync as readFileSync66 } from "fs";
118742
- import { join as join116 } from "path";
118925
+ import { join as join118 } from "path";
118743
118926
  function hasFullAgentAndModel(message) {
118744
118927
  return !!message.agent && !isCompactionAgent(message.agent) && !!message.model?.providerID && !!message.model?.modelID;
118745
118928
  }
@@ -118818,7 +119001,7 @@ function findNearestMessageExcludingCompaction(messageDir, sessionID) {
118818
119001
  const messages = [];
118819
119002
  for (const file2 of files) {
118820
119003
  try {
118821
- const content = readFileSync66(join116(messageDir, file2), "utf-8");
119004
+ const content = readFileSync66(join118(messageDir, file2), "utf-8");
118822
119005
  const parsed = JSON.parse(content);
118823
119006
  if (hasCompactionPartInStorage(parsed.id) || isCompactionAgent(parsed.agent)) {
118824
119007
  continue;
@@ -119049,13 +119232,15 @@ var defaultFallbackRetryHandlerDeps = {
119049
119232
  getNextFallback,
119050
119233
  hasMoreFallbacks,
119051
119234
  selectFallbackProvider,
119052
- transformModelForProvider
119235
+ transformModelForProvider,
119236
+ isProviderExhaustionFallbackEligible
119053
119237
  };
119054
119238
  async function tryFallbackRetry(args) {
119055
119239
  const { task, errorInfo, source, concurrencyManager, client: client3, idleDeferralTimers, queuesByKey, processKey, onRetrying } = args;
119056
119240
  const deps = { ...defaultFallbackRetryHandlerDeps, ...args.deps };
119057
119241
  const fallbackChain = task.fallbackChain;
119058
- const canRetry = deps.shouldRetryError(errorInfo) && fallbackChain && fallbackChain.length > 0 && deps.hasMoreFallbacks(fallbackChain, task.attemptCount ?? 0);
119242
+ const canUseProviderExhaustionFallback = deps.isProviderExhaustionFallbackEligible(errorInfo);
119243
+ const canRetry = (deps.shouldRetryError(errorInfo) || canUseProviderExhaustionFallback) && fallbackChain && fallbackChain.length > 0 && deps.hasMoreFallbacks(fallbackChain, task.attemptCount ?? 0);
119059
119244
  if (!canRetry)
119060
119245
  return false;
119061
119246
  const attemptCount = task.attemptCount ?? 0;
@@ -119283,7 +119468,8 @@ function cloneParentWake(wake) {
119283
119468
  ...wake.dispatchedAt !== undefined ? { dispatchedAt: wake.dispatchedAt } : {},
119284
119469
  ...wake.noReplyAdmittedAt !== undefined ? { noReplyAdmittedAt: wake.noReplyAdmittedAt } : {},
119285
119470
  ...wake.toolCallDeferralStartedAt !== undefined ? { toolCallDeferralStartedAt: wake.toolCallDeferralStartedAt } : {},
119286
- ...wake.allowEmptyAssistantTurnRetry !== undefined ? { allowEmptyAssistantTurnRetry: wake.allowEmptyAssistantTurnRetry } : {}
119471
+ ...wake.allowEmptyAssistantTurnRetry !== undefined ? { allowEmptyAssistantTurnRetry: wake.allowEmptyAssistantTurnRetry } : {},
119472
+ ...wake.noAssistantOutputRetryCount !== undefined ? { noAssistantOutputRetryCount: wake.noAssistantOutputRetryCount } : {}
119287
119473
  };
119288
119474
  }
119289
119475
  function isRedundantParentWake(latestWake, dispatchedWake) {
@@ -119815,7 +120001,13 @@ class ParentWakeFlushRunner {
119815
120001
  });
119816
120002
  }
119817
120003
  schedulePendingParentWakeFlush(sessionID, delayMs) {
119818
- this.deps.pendingQueue.scheduleFlush(sessionID, () => this.flushPendingParentWake(sessionID), delayMs);
120004
+ this.deps.pendingQueue.scheduleFlush(sessionID, async () => {
120005
+ try {
120006
+ await this.flushPendingParentWake(sessionID);
120007
+ } finally {
120008
+ this.deps.notifierDeps.onScheduledFlushSettled?.(sessionID);
120009
+ }
120010
+ }, delayMs);
119819
120011
  }
119820
120012
  deferReplyWakeWhileUnsafe(sessionID, latestWake) {
119821
120013
  if (isFailureParentWake(latestWake)) {
@@ -119927,6 +120119,7 @@ class ParentWakePendingQueue {
119927
120119
  pendingWake.shouldReply = pendingWake.shouldReply || shouldReply;
119928
120120
  if (notificationsChanged) {
119929
120121
  delete pendingWake.noReplyAdmittedAt;
120122
+ delete pendingWake.noAssistantOutputRetryCount;
119930
120123
  }
119931
120124
  return;
119932
120125
  }
@@ -119945,6 +120138,10 @@ class ParentWakePendingQueue {
119945
120138
  pendingWake.noReplyAdmittedAt ??= latestWake.noReplyAdmittedAt;
119946
120139
  pendingWake.toolCallDeferralStartedAt ??= latestWake.toolCallDeferralStartedAt;
119947
120140
  pendingWake.allowEmptyAssistantTurnRetry ||= latestWake.allowEmptyAssistantTurnRetry;
120141
+ const noAssistantOutputRetryCount = Math.max(pendingWake.noAssistantOutputRetryCount ?? 0, latestWake.noAssistantOutputRetryCount ?? 0);
120142
+ if (noAssistantOutputRetryCount > 0) {
120143
+ pendingWake.noAssistantOutputRetryCount = noAssistantOutputRetryCount;
120144
+ }
119948
120145
  return;
119949
120146
  }
119950
120147
  this.pendingParentWakes.set(sessionID, cloneParentWake(latestWake));
@@ -120235,6 +120432,7 @@ class ParentWakeSessionInspector {
120235
120432
  }
120236
120433
 
120237
120434
  // packages/omo-opencode/src/features/background-agent/parent-wake-window-recovery.ts
120435
+ var MAX_NO_ASSISTANT_OUTPUT_RETRIES = 1;
120238
120436
  async function handleDispatchedParentWakeWindowElapsed(input) {
120239
120437
  const currentWake = input.dispatchedTracker.getWake(input.sessionID);
120240
120438
  if (!currentWake || currentWake.dispatchedAt !== input.wake.dispatchedAt) {
@@ -120247,9 +120445,22 @@ async function handleDispatchedParentWakeWindowElapsed(input) {
120247
120445
  });
120248
120446
  return;
120249
120447
  }
120250
- input.dispatchedTracker.refreshWakeTimer(input.sessionID);
120251
- log2("[background-agent] Kept dispatched parent wake awaiting late failure or assistant output:", {
120252
- sessionID: input.sessionID
120448
+ const retryCount = input.wake.noAssistantOutputRetryCount ?? 0;
120449
+ if (retryCount >= MAX_NO_ASSISTANT_OUTPUT_RETRIES) {
120450
+ input.dispatchedTracker.clearWake(input.sessionID);
120451
+ log2("[background-agent] Stopped retrying parent wake after repeated no-output dispatch:", {
120452
+ sessionID: input.sessionID,
120453
+ retryCount
120454
+ });
120455
+ return;
120456
+ }
120457
+ input.dispatchedTracker.clearWake(input.sessionID);
120458
+ input.wake.noAssistantOutputRetryCount = retryCount + 1;
120459
+ input.requeueWake(input.wake);
120460
+ input.scheduleFlush();
120461
+ log2("[background-agent] Requeued dispatched parent wake after no assistant output:", {
120462
+ sessionID: input.sessionID,
120463
+ retryCount: input.wake.noAssistantOutputRetryCount
120253
120464
  });
120254
120465
  }
120255
120466
  function logParentWakeWindowRecoveryError(sessionID, error) {
@@ -120273,7 +120484,9 @@ class ParentWakeNotifier {
120273
120484
  dispatchedTracker;
120274
120485
  sessionInspector;
120275
120486
  flushRunner;
120487
+ onPendingWakeRequeued;
120276
120488
  constructor(deps, options) {
120489
+ this.onPendingWakeRequeued = deps.onPendingWakeRequeued;
120277
120490
  this.pendingQueue = new ParentWakePendingQueue({
120278
120491
  pendingRetryMs: options.pendingRetryMs,
120279
120492
  enqueueNotificationForParent: deps.enqueueNotificationForParent
@@ -120285,7 +120498,9 @@ class ParentWakeNotifier {
120285
120498
  sessionID,
120286
120499
  wake,
120287
120500
  dispatchedTracker: this.dispatchedTracker,
120288
- sessionInspector: this.sessionInspector
120501
+ sessionInspector: this.sessionInspector,
120502
+ requeueWake: (latestWake) => this.requeueWake(sessionID, latestWake),
120503
+ scheduleFlush: () => this.schedulePendingParentWakeFlush(sessionID)
120289
120504
  }).catch((error) => {
120290
120505
  logParentWakeWindowRecoveryError(sessionID, error);
120291
120506
  rescheduleParentWakeWindowRecoveryAfterError(sessionID, wake, this.dispatchedTracker);
@@ -120391,6 +120606,7 @@ class ParentWakeNotifier {
120391
120606
  }
120392
120607
  requeueWake(sessionID, latestWake) {
120393
120608
  this.pendingQueue.requeueWake(sessionID, latestWake);
120609
+ this.onPendingWakeRequeued?.(sessionID);
120394
120610
  }
120395
120611
  async shouldDeferParentWakeForSessionHistory(sessionID, wake) {
120396
120612
  return this.sessionInspector.shouldDeferForHistory(sessionID, wake);
@@ -121589,7 +121805,9 @@ class BackgroundManager {
121589
121805
  this.parentWakeNotifier = new ParentWakeNotifier({
121590
121806
  client: this.client,
121591
121807
  directory: this.directory,
121592
- enqueueNotificationForParent: this.enqueueNotificationForParent.bind(this)
121808
+ enqueueNotificationForParent: this.enqueueNotificationForParent.bind(this),
121809
+ onPendingWakeRequeued: (sessionID) => this.updateBackgroundTaskMarker(sessionID),
121810
+ onScheduledFlushSettled: (sessionID) => this.updateBackgroundTaskMarker(sessionID)
121593
121811
  }, {
121594
121812
  pendingRetryMs: PENDING_PARENT_WAKE_RETRY_MS,
121595
121813
  acceptedMessageSkewMs: PARENT_WAKE_ACCEPTED_MESSAGE_SKEW_MS,
@@ -122231,16 +122449,20 @@ The fallback retry session is now created and can be inspected directly.
122231
122449
  return this.getTasksByParentSession(sessionID).some((t2) => t2.status === "running" || t2.status === "pending");
122232
122450
  }
122233
122451
  hasPendingParentWake(sessionID) {
122234
- return this.parentWakeNotifier.hasNotificationPreparation(sessionID) || this.parentWakeNotifier.getPendingParentWakes().has(sessionID) || this.parentWakeNotifier.getPendingParentWakeTimers().has(sessionID) || this.parentWakeNotifier.hasInFlightParentWakeDispatch(sessionID) || this.parentWakeNotifier.getDispatchedParentWakes().has(sessionID);
122452
+ return this.hasUndeliveredParentWake(sessionID) || this.parentWakeNotifier.getDispatchedParentWakes().has(sessionID);
122453
+ }
122454
+ hasUndeliveredParentWake(sessionID) {
122455
+ return this.parentWakeNotifier.hasNotificationPreparation(sessionID) || this.parentWakeNotifier.getPendingParentWakes().has(sessionID) || this.parentWakeNotifier.getPendingParentWakeTimers().has(sessionID) || this.parentWakeNotifier.hasInFlightParentWakeDispatch(sessionID);
122235
122456
  }
122236
122457
  updateBackgroundTaskMarker(parentSessionID) {
122237
122458
  const tasks = this.getTasksByParentSession(parentSessionID);
122238
122459
  const activeTasks = tasks.filter((t2) => t2.status === "running" || t2.status === "pending");
122239
- if (activeTasks.length > 0) {
122240
- setContinuationMarkerSource(this.directory, parentSessionID, "background-task", "active", `${activeTasks.length} background task(s) active`);
122241
- } else {
122242
- setContinuationMarkerSource(this.directory, parentSessionID, "background-task", "idle");
122243
- }
122460
+ writeBackgroundTaskMarker({
122461
+ directory: this.directory,
122462
+ parentSessionID,
122463
+ activeTaskCount: activeTasks.length,
122464
+ hasUndeliveredParentWake: this.hasUndeliveredParentWake(parentSessionID)
122465
+ });
122244
122466
  }
122245
122467
  getAllDescendantTasks(sessionID) {
122246
122468
  const result = [];
@@ -122917,6 +123139,7 @@ The fallback retry session is now created and can be inspected directly.
122917
123139
  const releaseNotificationPreparation = () => {
122918
123140
  if (notificationParentSessionID) {
122919
123141
  this.parentWakeNotifier.releaseNotificationPreparation(notificationParentSessionID);
123142
+ this.updateBackgroundTaskMarker(notificationParentSessionID);
122920
123143
  }
122921
123144
  };
122922
123145
  if (task.currentAttemptID) {
@@ -123388,6 +123611,7 @@ The task was re-queued on a fallback model after a retryable failure.
123388
123611
  } finally {
123389
123612
  if (notificationParentSessionID) {
123390
123613
  this.parentWakeNotifier.releaseNotificationPreparation(notificationParentSessionID);
123614
+ this.updateBackgroundTaskMarker(notificationParentSessionID);
123391
123615
  }
123392
123616
  }
123393
123617
  }
@@ -123501,7 +123725,7 @@ The task was re-queued on a fallback model after a retryable failure.
123501
123725
  parentSessionID: task.parentSessionId
123502
123726
  });
123503
123727
  }
123504
- const messageDir = join117(MESSAGE_STORAGE, task.parentSessionId);
123728
+ const messageDir = join119(MESSAGE_STORAGE, task.parentSessionId);
123505
123729
  const currentMessage = messageDir ? findNearestMessageExcludingCompaction(messageDir, task.parentSessionId) : null;
123506
123730
  agent = currentMessage?.agent ?? task.parentAgent;
123507
123731
  model = currentMessage?.model?.providerID && currentMessage?.model?.modelID ? { providerID: currentMessage.model.providerID, modelID: currentMessage.model.modelID } : undefined;
@@ -123522,9 +123746,14 @@ The task was re-queued on a fallback model after a retryable failure.
123522
123746
  }
123523
123747
  queuePendingParentWake(sessionID, notification, promptContext, shouldReply, delayMs) {
123524
123748
  this.parentWakeNotifier.queuePendingParentWake(sessionID, notification, promptContext, shouldReply, delayMs);
123749
+ this.updateBackgroundTaskMarker(sessionID);
123525
123750
  }
123526
123751
  async flushPendingParentWake(sessionID) {
123527
- await this.parentWakeNotifier.flushPendingParentWake(sessionID);
123752
+ try {
123753
+ await this.parentWakeNotifier.flushPendingParentWake(sessionID);
123754
+ } finally {
123755
+ this.updateBackgroundTaskMarker(sessionID);
123756
+ }
123528
123757
  }
123529
123758
  hasRunningTasks() {
123530
123759
  for (const task of this.tasks.values()) {
@@ -125085,7 +125314,7 @@ function createMonitorManager(options) {
125085
125314
  import { createHash as createHash6 } from "crypto";
125086
125315
  import {
125087
125316
  chmodSync as chmodSync4,
125088
- existsSync as existsSync102,
125317
+ existsSync as existsSync103,
125089
125318
  mkdirSync as mkdirSync20,
125090
125319
  readdirSync as readdirSync27,
125091
125320
  readFileSync as readFileSync68,
@@ -125093,15 +125322,15 @@ import {
125093
125322
  unlinkSync as unlinkSync16,
125094
125323
  writeFileSync as writeFileSync21
125095
125324
  } from "fs";
125096
- import { basename as basename22, dirname as dirname39, join as join120 } from "path";
125325
+ import { basename as basename22, dirname as dirname40, join as join122 } from "path";
125097
125326
 
125098
125327
  // packages/mcp-client-core/src/config-dir.ts
125099
- import { existsSync as existsSync100, realpathSync as realpathSync17 } from "fs";
125328
+ import { existsSync as existsSync101, realpathSync as realpathSync17 } from "fs";
125100
125329
  import { homedir as homedir32 } from "os";
125101
- import { join as join118, resolve as resolve36 } from "path";
125330
+ import { join as join120, resolve as resolve36 } from "path";
125102
125331
  function resolveConfigPath4(pathValue) {
125103
125332
  const resolvedPath = resolve36(pathValue);
125104
- if (!existsSync100(resolvedPath))
125333
+ if (!existsSync101(resolvedPath))
125105
125334
  return resolvedPath;
125106
125335
  try {
125107
125336
  return realpathSync17(resolvedPath);
@@ -125116,13 +125345,13 @@ function getOpenCodeCliConfigDir(env2 = process.env) {
125116
125345
  if (customConfigDir) {
125117
125346
  return resolveConfigPath4(customConfigDir);
125118
125347
  }
125119
- const xdgConfigDir = env2["XDG_CONFIG_HOME"]?.trim() || join118(homedir32(), ".config");
125120
- return resolveConfigPath4(join118(xdgConfigDir, "opencode"));
125348
+ const xdgConfigDir = env2["XDG_CONFIG_HOME"]?.trim() || join120(homedir32(), ".config");
125349
+ return resolveConfigPath4(join120(xdgConfigDir, "opencode"));
125121
125350
  }
125122
125351
 
125123
125352
  // packages/mcp-client-core/src/mcp-oauth/storage-index.ts
125124
- import { chmodSync as chmodSync3, existsSync as existsSync101, readFileSync as readFileSync67, renameSync as renameSync8, writeFileSync as writeFileSync20 } from "fs";
125125
- import { join as join119 } from "path";
125353
+ import { chmodSync as chmodSync3, existsSync as existsSync102, readFileSync as readFileSync67, renameSync as renameSync8, writeFileSync as writeFileSync20 } from "fs";
125354
+ import { join as join121 } from "path";
125126
125355
  var INDEX_FILE_NAME = "index.json";
125127
125356
  function isTokenIndex(value) {
125128
125357
  if (typeof value !== "object" || value === null || Array.isArray(value))
@@ -125130,11 +125359,11 @@ function isTokenIndex(value) {
125130
125359
  return Object.values(value).every((entry) => typeof entry === "string");
125131
125360
  }
125132
125361
  function getIndexPath(storageDir) {
125133
- return join119(storageDir, INDEX_FILE_NAME);
125362
+ return join121(storageDir, INDEX_FILE_NAME);
125134
125363
  }
125135
125364
  function readTokenIndex(storageDir) {
125136
125365
  const indexPath = getIndexPath(storageDir);
125137
- if (!existsSync101(indexPath))
125366
+ if (!existsSync102(indexPath))
125138
125367
  return {};
125139
125368
  try {
125140
125369
  const parsed = JSON.parse(readFileSync67(indexPath, "utf-8"));
@@ -125167,16 +125396,16 @@ function saveTokenIndexEntry(storageDir, hash, key) {
125167
125396
  var STORAGE_DIR_NAME = "mcp-oauth";
125168
125397
  var LEGACY_STORAGE_FILE_NAME = "mcp-oauth.json";
125169
125398
  function getMcpOauthStorageDir() {
125170
- return join120(getOpenCodeCliConfigDir(), STORAGE_DIR_NAME);
125399
+ return join122(getOpenCodeCliConfigDir(), STORAGE_DIR_NAME);
125171
125400
  }
125172
125401
  function getMcpOauthServerHash(serverHost, resource) {
125173
125402
  return createHash6("sha256").update(buildKey(serverHost, resource)).digest("hex").slice(0, 32);
125174
125403
  }
125175
125404
  function getMcpOauthStoragePath(serverHost, resource) {
125176
- return join120(getMcpOauthStorageDir(), `${getMcpOauthServerHash(serverHost, resource)}.json`);
125405
+ return join122(getMcpOauthStorageDir(), `${getMcpOauthServerHash(serverHost, resource)}.json`);
125177
125406
  }
125178
125407
  function getLegacyStoragePath() {
125179
- return join120(getOpenCodeCliConfigDir(), LEGACY_STORAGE_FILE_NAME);
125408
+ return join122(getOpenCodeCliConfigDir(), LEGACY_STORAGE_FILE_NAME);
125180
125409
  }
125181
125410
  function normalizeHost(serverHost) {
125182
125411
  let host = serverHost.trim();
@@ -125237,7 +125466,7 @@ function isOAuthTokenData(value) {
125237
125466
  return clientSecret === undefined || typeof clientSecret === "string";
125238
125467
  }
125239
125468
  function readTokenFile(filePath) {
125240
- if (!existsSync102(filePath))
125469
+ if (!existsSync103(filePath))
125241
125470
  return null;
125242
125471
  try {
125243
125472
  const parsed = JSON.parse(readFileSync68(filePath, "utf-8"));
@@ -125250,7 +125479,7 @@ function readTokenFile(filePath) {
125250
125479
  }
125251
125480
  function readLegacyStore() {
125252
125481
  const filePath = getLegacyStoragePath();
125253
- if (!existsSync102(filePath))
125482
+ if (!existsSync103(filePath))
125254
125483
  return null;
125255
125484
  try {
125256
125485
  const parsed = JSON.parse(readFileSync68(filePath, "utf-8"));
@@ -125270,8 +125499,8 @@ function readLegacyStore() {
125270
125499
  }
125271
125500
  function writeTokenFile(filePath, token) {
125272
125501
  try {
125273
- const dir = dirname39(filePath);
125274
- if (!existsSync102(dir)) {
125502
+ const dir = dirname40(filePath);
125503
+ if (!existsSync103(dir)) {
125275
125504
  mkdirSync20(dir, { recursive: true });
125276
125505
  }
125277
125506
  const tempPath = `${filePath}.tmp.${Date.now()}`;
@@ -130664,15 +130893,15 @@ init_logger2();
130664
130893
 
130665
130894
  // packages/omo-opencode/src/features/tui-sidebar/mirror-io.ts
130666
130895
  import { mkdirSync as mkdirSync21, readFileSync as readFileSync69 } from "fs";
130667
- import { dirname as dirname40 } from "path";
130896
+ import { dirname as dirname41 } from "path";
130668
130897
 
130669
130898
  // packages/omo-opencode/src/features/tui-sidebar/mirror-path.ts
130670
130899
  import { createHash as createHash8 } from "crypto";
130671
130900
  import { realpathSync as realpathSync18 } from "fs";
130672
130901
  import { homedir as homedir33 } from "os";
130673
- import { join as join121, resolve as resolve37 } from "path";
130902
+ import { join as join123, resolve as resolve37 } from "path";
130674
130903
  function mirrorStorageDir() {
130675
- return join121(process.env.XDG_DATA_HOME ?? join121(homedir33(), ".local", "share"), "opencode", "storage", "oh-my-openagent", MIRROR_DIR_NAME);
130904
+ return join123(process.env.XDG_DATA_HOME ?? join123(homedir33(), ".local", "share"), "opencode", "storage", "oh-my-openagent", MIRROR_DIR_NAME);
130676
130905
  }
130677
130906
  function canonicalProjectDir(projectDir) {
130678
130907
  try {
@@ -130686,7 +130915,7 @@ function canonicalProjectDir(projectDir) {
130686
130915
  }
130687
130916
  function mirrorFilePath(projectDir) {
130688
130917
  const projectHash = createHash8("sha1").update(canonicalProjectDir(projectDir)).digest("hex").slice(0, 16);
130689
- return join121(mirrorStorageDir(), `${projectHash}.json`);
130918
+ return join123(mirrorStorageDir(), `${projectHash}.json`);
130690
130919
  }
130691
130920
 
130692
130921
  // packages/omo-opencode/src/features/tui-sidebar/snapshot-schema.ts
@@ -130739,13 +130968,13 @@ var TuiRuntimeSnapshotSchema = z9.object({
130739
130968
  function writeMirror(projectDir, snapshot) {
130740
130969
  const filePath = mirrorFilePath(projectDir);
130741
130970
  const content = JSON.stringify(snapshot);
130742
- mkdirSync21(dirname40(filePath), { recursive: true });
130971
+ mkdirSync21(dirname41(filePath), { recursive: true });
130743
130972
  writeFileAtomically2(filePath, content, { mode: 384 });
130744
130973
  }
130745
130974
 
130746
130975
  // packages/omo-opencode/src/features/tui-sidebar/loop-reader.ts
130747
130976
  import { readdirSync as readdirSync28, readFileSync as readFileSync70, statSync as statSync13 } from "fs";
130748
- import { join as join122 } from "path";
130977
+ import { join as join124 } from "path";
130749
130978
  import { z as z10 } from "zod";
130750
130979
  var CriterionSchema = z10.object({
130751
130980
  status: z10.string()
@@ -130775,7 +131004,7 @@ function enumerateCandidates(projectDir) {
130775
131004
  return [...currentLoopCandidates(projectDir), legacyLoopCandidate(projectDir)].filter((candidate) => candidate !== null);
130776
131005
  }
130777
131006
  function currentLoopCandidates(projectDir) {
130778
- const loopRoot = join122(projectDir, ".omo", "ulw-loop");
131007
+ const loopRoot = join124(projectDir, ".omo", "ulw-loop");
130779
131008
  let entries;
130780
131009
  try {
130781
131010
  entries = readdirSync28(loopRoot, { withFileTypes: true });
@@ -130785,10 +131014,10 @@ function currentLoopCandidates(projectDir) {
130785
131014
  }
130786
131015
  throw error;
130787
131016
  }
130788
- return entries.filter((entry) => entry.isDirectory()).map((entry) => statCandidate(join122(loopRoot, entry.name, "goals.json"))).filter((candidate) => candidate !== null);
131017
+ return entries.filter((entry) => entry.isDirectory()).map((entry) => statCandidate(join124(loopRoot, entry.name, "goals.json"))).filter((candidate) => candidate !== null);
130789
131018
  }
130790
131019
  function legacyLoopCandidate(projectDir) {
130791
- return statCandidate(join122(projectDir, ".omo", "loop", "goals.json"));
131020
+ return statCandidate(join124(projectDir, ".omo", "loop", "goals.json"));
130792
131021
  }
130793
131022
  function statCandidate(path22) {
130794
131023
  try {
@@ -133538,7 +133767,7 @@ async function isTmuxAvailableWithDeps(deps) {
133538
133767
  import {
133539
133768
  appendFileSync as appendFileSync7,
133540
133769
  chmodSync as chmodSync5,
133541
- existsSync as existsSync104,
133770
+ existsSync as existsSync105,
133542
133771
  renameSync as renameSync10,
133543
133772
  statSync as statSync14,
133544
133773
  unlinkSync as unlinkSync17,
@@ -133546,31 +133775,31 @@ import {
133546
133775
  } from "fs";
133547
133776
 
133548
133777
  // packages/openclaw-core/src/reply-listener-paths.ts
133549
- import { existsSync as existsSync103, mkdirSync as mkdirSync22 } from "fs";
133778
+ import { existsSync as existsSync104, mkdirSync as mkdirSync22 } from "fs";
133550
133779
  import { homedir as homedir34 } from "os";
133551
- import { join as join123 } from "path";
133780
+ import { join as join125 } from "path";
133552
133781
  var REPLY_LISTENER_SECURE_FILE_MODE = 384;
133553
133782
  function resolveReplyListenerHomeDir() {
133554
133783
  return process.env.HOME ?? process.env.USERPROFILE ?? homedir34();
133555
133784
  }
133556
133785
  function getReplyListenerStateDir() {
133557
- return join123(resolveReplyListenerHomeDir(), ".omo", "openclaw", "state");
133786
+ return join125(resolveReplyListenerHomeDir(), ".omo", "openclaw", "state");
133558
133787
  }
133559
133788
  function getReplyListenerPidFilePath() {
133560
- return join123(getReplyListenerStateDir(), "reply-listener.pid");
133789
+ return join125(getReplyListenerStateDir(), "reply-listener.pid");
133561
133790
  }
133562
133791
  function getReplyListenerStateFilePath() {
133563
- return join123(getReplyListenerStateDir(), "reply-listener-state.json");
133792
+ return join125(getReplyListenerStateDir(), "reply-listener-state.json");
133564
133793
  }
133565
133794
  function getReplyListenerConfigFilePath() {
133566
- return join123(getReplyListenerStateDir(), "reply-listener-config.json");
133795
+ return join125(getReplyListenerStateDir(), "reply-listener-config.json");
133567
133796
  }
133568
133797
  function getReplyListenerLogFilePath() {
133569
- return join123(getReplyListenerStateDir(), "reply-listener.log");
133798
+ return join125(getReplyListenerStateDir(), "reply-listener.log");
133570
133799
  }
133571
133800
  function ensureReplyListenerStateDir() {
133572
133801
  const stateDir = getReplyListenerStateDir();
133573
- if (!existsSync103(stateDir)) {
133802
+ if (!existsSync104(stateDir)) {
133574
133803
  mkdirSync22(stateDir, { recursive: true, mode: 448 });
133575
133804
  }
133576
133805
  }
@@ -133593,13 +133822,13 @@ function writeSecureReplyListenerFile(filePath, content) {
133593
133822
  }
133594
133823
  function rotateReplyListenerLogIfNeeded(logPath) {
133595
133824
  try {
133596
- if (!existsSync104(logPath))
133825
+ if (!existsSync105(logPath))
133597
133826
  return;
133598
133827
  const stats = statSync14(logPath);
133599
133828
  if (stats.size <= MAX_REPLY_LISTENER_LOG_SIZE_BYTES)
133600
133829
  return;
133601
133830
  const backupPath = `${logPath}.old`;
133602
- if (existsSync104(backupPath)) {
133831
+ if (existsSync105(backupPath)) {
133603
133832
  unlinkSync17(backupPath);
133604
133833
  }
133605
133834
  renameSync10(logPath, backupPath);
@@ -133626,7 +133855,7 @@ import { constants as constants24, closeSync as closeSync5, openSync as openSync
133626
133855
 
133627
133856
  // packages/openclaw-core/src/session-registry-paths.ts
133628
133857
  init_src();
133629
- import { join as join124 } from "path";
133858
+ import { join as join126 } from "path";
133630
133859
  var SECURE_FILE_MODE = 384;
133631
133860
  var MAX_AGE_MS = 24 * 60 * 60 * 1000;
133632
133861
  var LOCK_TIMEOUT_MS = 2000;
@@ -133637,16 +133866,16 @@ var cachedRegistryPaths = null;
133637
133866
  function resolveRegistryPaths() {
133638
133867
  if (cachedRegistryPaths !== null)
133639
133868
  return cachedRegistryPaths;
133640
- const openClawStorageDir = join124(getOpenCodeStorageDir2(), "openclaw");
133869
+ const openClawStorageDir = join126(getOpenCodeStorageDir2(), "openclaw");
133641
133870
  cachedRegistryPaths = {
133642
133871
  openClawStorageDir,
133643
- registryPath: join124(openClawStorageDir, "reply-session-registry.jsonl"),
133644
- registryLockPath: join124(openClawStorageDir, "reply-session-registry.lock")
133872
+ registryPath: join126(openClawStorageDir, "reply-session-registry.jsonl"),
133873
+ registryLockPath: join126(openClawStorageDir, "reply-session-registry.lock")
133645
133874
  };
133646
133875
  return cachedRegistryPaths;
133647
133876
  }
133648
133877
  function getOpenCodeStorageDir2() {
133649
- return join124(resolveXdgDataDir("opencode"), "opencode", "storage");
133878
+ return join126(resolveXdgDataDir("opencode"), "opencode", "storage");
133650
133879
  }
133651
133880
  function getRegistryPath() {
133652
133881
  return resolveRegistryPaths().registryPath;
@@ -133656,12 +133885,12 @@ function getRegistryLockPath() {
133656
133885
  }
133657
133886
 
133658
133887
  // packages/openclaw-core/src/session-registry-lock.ts
133659
- import { constants as constants23, closeSync as closeSync4, existsSync as existsSync106, openSync as openSync4, readFileSync as readFileSync72, statSync as statSync15, unlinkSync as unlinkSync18, writeSync } from "fs";
133888
+ import { constants as constants23, closeSync as closeSync4, existsSync as existsSync107, openSync as openSync4, readFileSync as readFileSync72, statSync as statSync15, unlinkSync as unlinkSync18, writeSync } from "fs";
133660
133889
  import { randomUUID as randomUUID10 } from "crypto";
133661
133890
 
133662
133891
  // packages/openclaw-core/src/session-registry-storage.ts
133663
- import { existsSync as existsSync105, mkdirSync as mkdirSync23, readFileSync as readFileSync71, writeFileSync as writeFileSync23 } from "fs";
133664
- import { dirname as dirname41 } from "path";
133892
+ import { existsSync as existsSync106, mkdirSync as mkdirSync23, readFileSync as readFileSync71, writeFileSync as writeFileSync23 } from "fs";
133893
+ import { dirname as dirname42 } from "path";
133665
133894
  function isSessionMapping(value) {
133666
133895
  if (typeof value !== "object" || value === null)
133667
133896
  return false;
@@ -133682,14 +133911,14 @@ function isSessionMapping(value) {
133682
133911
  return true;
133683
133912
  }
133684
133913
  function ensureRegistryDir() {
133685
- const registryDir = dirname41(getRegistryPath());
133686
- if (!existsSync105(registryDir)) {
133914
+ const registryDir = dirname42(getRegistryPath());
133915
+ if (!existsSync106(registryDir)) {
133687
133916
  mkdirSync23(registryDir, { recursive: true, mode: 448 });
133688
133917
  }
133689
133918
  }
133690
133919
  function readAllMappingsUnsafe() {
133691
133920
  const registryPath = getRegistryPath();
133692
- if (!existsSync105(registryPath))
133921
+ if (!existsSync106(registryPath))
133693
133922
  return [];
133694
133923
  try {
133695
133924
  const content = readFileSync71(registryPath, "utf-8");
@@ -133743,7 +133972,7 @@ function isPidAlive2(pid) {
133743
133972
  function readLockSnapshot() {
133744
133973
  try {
133745
133974
  const registryLockPath = getRegistryLockPath();
133746
- if (!existsSync106(registryLockPath))
133975
+ if (!existsSync107(registryLockPath))
133747
133976
  return null;
133748
133977
  const raw = readFileSync72(registryLockPath, "utf-8");
133749
133978
  const trimmed = raw.trim();
@@ -133774,7 +134003,7 @@ function readLockSnapshot() {
133774
134003
  function removeLockIfUnchanged(snapshot) {
133775
134004
  try {
133776
134005
  const registryLockPath = getRegistryLockPath();
133777
- if (!existsSync106(registryLockPath))
134006
+ if (!existsSync107(registryLockPath))
133778
134007
  return false;
133779
134008
  const currentRaw = readFileSync72(registryLockPath, "utf-8");
133780
134009
  if (currentRaw !== snapshot.raw)
@@ -133946,7 +134175,7 @@ class ReplyListenerRateLimiter {
133946
134175
  }
133947
134176
 
133948
134177
  // packages/openclaw-core/src/reply-listener-state.ts
133949
- import { existsSync as existsSync107, readFileSync as readFileSync73, unlinkSync as unlinkSync19 } from "fs";
134178
+ import { existsSync as existsSync108, readFileSync as readFileSync73, unlinkSync as unlinkSync19 } from "fs";
133950
134179
  var REPLY_LISTENER_STARTUP_TOKEN_ENV = "OMO_OPENCLAW_REPLY_LISTENER_STARTUP_TOKEN";
133951
134180
  function ignoreReplyListenerStateReadError(error) {
133952
134181
  if (error instanceof Error)
@@ -134013,7 +134242,7 @@ function createPendingReplyListenerState(startupToken) {
134013
134242
  function readReplyListenerDaemonState() {
134014
134243
  try {
134015
134244
  const stateFilePath = getReplyListenerStateFilePath();
134016
- if (!existsSync107(stateFilePath))
134245
+ if (!existsSync108(stateFilePath))
134017
134246
  return null;
134018
134247
  return normalizeReplyListenerState(JSON.parse(readFileSync73(stateFilePath, "utf-8")));
134019
134248
  } catch (error) {
@@ -134031,7 +134260,7 @@ function writeReplyListenerDaemonState(state3) {
134031
134260
  function readReplyListenerDaemonConfig() {
134032
134261
  try {
134033
134262
  const configFilePath = getReplyListenerConfigFilePath();
134034
- if (!existsSync107(configFilePath))
134263
+ if (!existsSync108(configFilePath))
134035
134264
  return null;
134036
134265
  return JSON.parse(readFileSync73(configFilePath, "utf-8"));
134037
134266
  } catch (error) {
@@ -134045,7 +134274,7 @@ function writeReplyListenerDaemonConfig(config) {
134045
134274
  function readReplyListenerPid() {
134046
134275
  try {
134047
134276
  const pidFilePath = getReplyListenerPidFilePath();
134048
- if (!existsSync107(pidFilePath))
134277
+ if (!existsSync108(pidFilePath))
134049
134278
  return null;
134050
134279
  const pid = Number.parseInt(readFileSync73(pidFilePath, "utf-8").trim(), 10);
134051
134280
  return Number.isNaN(pid) ? null : pid;
@@ -134059,7 +134288,7 @@ function writeReplyListenerPid(pid) {
134059
134288
  }
134060
134289
  function removeReplyListenerPid() {
134061
134290
  const pidFilePath = getReplyListenerPidFilePath();
134062
- if (existsSync107(pidFilePath)) {
134291
+ if (existsSync108(pidFilePath)) {
134063
134292
  unlinkSync19(pidFilePath);
134064
134293
  }
134065
134294
  }
@@ -134087,8 +134316,8 @@ function getReplyListenerRuntimeSignature(config) {
134087
134316
  // packages/openclaw-core/src/reply-listener-poll-loop.ts
134088
134317
  var PRUNE_INTERVAL_MS = 60 * 60 * 1000;
134089
134318
  // packages/openclaw-core/src/reply-listener-start.ts
134090
- import { dirname as dirname42, join as join125 } from "path";
134091
- import { fileURLToPath as fileURLToPath6 } from "url";
134319
+ import { dirname as dirname43, join as join127 } from "path";
134320
+ import { fileURLToPath as fileURLToPath7 } from "url";
134092
134321
 
134093
134322
  // packages/openclaw-core/src/reply-listener-spawn.ts
134094
134323
  init_runtime();
@@ -134328,8 +134557,8 @@ function createStartFailureResult(message, state3) {
134328
134557
  };
134329
134558
  }
134330
134559
  function resolveReplyListenerDaemonScript(currentFileUrl) {
134331
- const currentFilePath = fileURLToPath6(currentFileUrl);
134332
- return currentFilePath.endsWith(".ts") ? join125(dirname42(currentFilePath), "daemon.ts") : join125(dirname42(currentFilePath), "daemon.js");
134560
+ const currentFilePath = fileURLToPath7(currentFileUrl);
134561
+ return currentFilePath.endsWith(".ts") ? join127(dirname43(currentFilePath), "daemon.ts") : join127(dirname43(currentFilePath), "daemon.js");
134333
134562
  }
134334
134563
  async function startReplyListener(config) {
134335
134564
  const normalizedConfig = getNormalizedReplyListenerConfig(config);
@@ -134752,25 +134981,25 @@ async function createRuntimeSkillSourceServer(options, runtimeEnv = runtime6) {
134752
134981
  };
134753
134982
  }
134754
134983
  // packages/claude-code-compat-core/src/features/claude-code-mcp-loader/loader.ts
134755
- import { existsSync as existsSync108, readFileSync as readFileSync75 } from "fs";
134756
- import { join as join126 } from "path";
134984
+ import { existsSync as existsSync109, readFileSync as readFileSync75 } from "fs";
134985
+ import { join as join128 } from "path";
134757
134986
  import { homedir as homedir35 } from "os";
134758
134987
  function getMcpConfigPaths() {
134759
134988
  const claudeConfigDir = getClaudeConfigDir3();
134760
134989
  const homeDir = getHomeDir();
134761
134990
  const cwd = process.cwd();
134762
134991
  return [
134763
- { path: join126(homeDir, ".claude.json"), scope: "user" },
134764
- { path: join126(claudeConfigDir, ".mcp.json"), scope: "user" },
134765
- { path: join126(cwd, ".mcp.json"), scope: "project" },
134766
- { path: join126(cwd, ".claude", ".mcp.json"), scope: "local" }
134992
+ { path: join128(homeDir, ".claude.json"), scope: "user" },
134993
+ { path: join128(claudeConfigDir, ".mcp.json"), scope: "user" },
134994
+ { path: join128(cwd, ".mcp.json"), scope: "project" },
134995
+ { path: join128(cwd, ".claude", ".mcp.json"), scope: "local" }
134767
134996
  ];
134768
134997
  }
134769
134998
  function getHomeDir() {
134770
134999
  return process.env.HOME || process.env.USERPROFILE || homedir35();
134771
135000
  }
134772
135001
  async function loadMcpConfigFile(filePath) {
134773
- if (!existsSync108(filePath)) {
135002
+ if (!existsSync109(filePath)) {
134774
135003
  return null;
134775
135004
  }
134776
135005
  try {
@@ -134790,7 +135019,7 @@ function getSystemMcpServerNames() {
134790
135019
  const paths2 = getMcpConfigPaths();
134791
135020
  const cwd = process.cwd();
134792
135021
  for (const { path: path22 } of paths2) {
134793
- if (!existsSync108(path22))
135022
+ if (!existsSync109(path22))
134794
135023
  continue;
134795
135024
  try {
134796
135025
  const content = readFileSync75(path22, "utf-8");
@@ -138936,40 +139165,52 @@ ${styleBlock}`;
138936
139165
 
138937
139166
  // packages/omo-opencode/src/agents/sisyphus-agent-factory.ts
138938
139167
  var MODE = "primary";
139168
+ function resolveSisyphusPromptFamily(model) {
139169
+ if (isKimiK27Model(model))
139170
+ return "kimi-k2-7";
139171
+ if (isKimiK2Model(model))
139172
+ return "kimi-k2-6";
139173
+ if (isGpt5_5Model(model))
139174
+ return "gpt-5-5";
139175
+ if (isGptNativeSisyphusModel(model))
139176
+ return "gpt-5-4";
139177
+ if (isClaudeFable5Model(model))
139178
+ return "claude-fable-5";
139179
+ if (isClaudeOpus48Model(model))
139180
+ return "claude-opus-4-8";
139181
+ if (isClaudeOpus47Model(model))
139182
+ return "claude-opus-4-7";
139183
+ if (isGlmModel(model))
139184
+ return "glm-5-2";
139185
+ return "fallback";
139186
+ }
138939
139187
  function createSisyphusAgent(model, availableAgents, availableToolNames, availableSkills, availableCategories, useTaskSystem = false) {
138940
139188
  const tools = availableToolNames ? categorizeTools(availableToolNames) : [];
138941
139189
  const skills = availableSkills ?? [];
138942
139190
  const categories = availableCategories ?? [];
138943
139191
  const agents = availableAgents ?? [];
138944
- if (isKimiK27Model(model)) {
138945
- return buildGptSisyphusAgentConfig(MODE, model, buildKimiK27SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
138946
- }
138947
- if (isKimiK2Model(model)) {
138948
- return buildGptSisyphusAgentConfig(MODE, model, buildKimiK26SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
138949
- }
138950
- if (isGpt5_5Model(model)) {
138951
- return buildGptSisyphusAgentConfig(MODE, model, buildGpt55SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
138952
- }
138953
- if (isGptNativeSisyphusModel(model)) {
138954
- return buildGptSisyphusAgentConfig(MODE, model, buildGpt54SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
138955
- }
138956
- if (isClaudeFable5Model(model)) {
138957
- return buildClaudeSisyphusAgentConfig(MODE, model, buildClaudeFable5SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
138958
- }
138959
- if (isClaudeOpus48Model(model)) {
138960
- return buildClaudeSisyphusAgentConfig(MODE, model, buildClaudeOpus48SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
138961
- }
138962
- if (isClaudeOpus47Model(model)) {
138963
- return buildClaudeSisyphusAgentConfig(MODE, model, buildClaudeOpus47SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
138964
- }
138965
- if (isGlmModel(model)) {
138966
- return buildGlmSisyphusAgentConfig(MODE, model, buildGlm52SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
138967
- }
138968
- const prompt = buildFallbackSisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem);
138969
- if (isGptModel(model)) {
138970
- return buildGptSisyphusAgentConfig(MODE, model, prompt);
139192
+ switch (resolveSisyphusPromptFamily(model)) {
139193
+ case "kimi-k2-7":
139194
+ return buildGptSisyphusAgentConfig(MODE, model, buildKimiK27SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
139195
+ case "kimi-k2-6":
139196
+ return buildGptSisyphusAgentConfig(MODE, model, buildKimiK26SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
139197
+ case "gpt-5-5":
139198
+ return buildGptSisyphusAgentConfig(MODE, model, buildGpt55SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
139199
+ case "gpt-5-4":
139200
+ return buildGptSisyphusAgentConfig(MODE, model, buildGpt54SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
139201
+ case "claude-fable-5":
139202
+ return buildClaudeSisyphusAgentConfig(MODE, model, buildClaudeFable5SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
139203
+ case "claude-opus-4-8":
139204
+ return buildClaudeSisyphusAgentConfig(MODE, model, buildClaudeOpus48SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
139205
+ case "claude-opus-4-7":
139206
+ return buildClaudeSisyphusAgentConfig(MODE, model, buildClaudeOpus47SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
139207
+ case "glm-5-2":
139208
+ return buildGlmSisyphusAgentConfig(MODE, model, buildGlm52SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
139209
+ case "fallback": {
139210
+ const prompt = buildFallbackSisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem);
139211
+ return isGptModel(model) ? buildGptSisyphusAgentConfig(MODE, model, prompt) : buildClaudeSisyphusAgentConfig(MODE, model, prompt);
139212
+ }
138971
139213
  }
138972
- return buildClaudeSisyphusAgentConfig(MODE, model, prompt);
138973
139214
  }
138974
139215
  createSisyphusAgent.mode = MODE;
138975
139216
  // packages/omo-opencode/src/agents/oracle.ts
@@ -141695,15 +141936,15 @@ function createHephaestusAgent(model, availableAgents, availableToolNames, avail
141695
141936
  }
141696
141937
  createHephaestusAgent.mode = MODE9;
141697
141938
  // packages/omo-opencode/src/agents/builtin-agents/resolve-file-uri.ts
141698
- import { existsSync as existsSync109, readFileSync as readFileSync76 } from "fs";
141939
+ import { existsSync as existsSync110, readFileSync as readFileSync76 } from "fs";
141699
141940
  import { homedir as homedir36 } from "os";
141700
- import { isAbsolute as isAbsolute20, join as join127, resolve as resolve38 } from "path";
141941
+ import { isAbsolute as isAbsolute20, join as join129, resolve as resolve38 } from "path";
141701
141942
  init_logger2();
141702
141943
  var ALLOWED_HOME_SUBDIRS = [
141703
- join127(homedir36(), ".config", "opencode"),
141704
- join127(homedir36(), ".config", "oh-my-openagent"),
141705
- join127(homedir36(), ".omo"),
141706
- join127(homedir36(), ".opencode")
141944
+ join129(homedir36(), ".config", "opencode"),
141945
+ join129(homedir36(), ".config", "oh-my-openagent"),
141946
+ join129(homedir36(), ".omo"),
141947
+ join129(homedir36(), ".opencode")
141707
141948
  ];
141708
141949
  function isWithinAllowedPaths(filePath, projectRoot) {
141709
141950
  if (isWithinProject(filePath, projectRoot))
@@ -141739,7 +141980,7 @@ function resolvePromptAppend(promptAppend, configDir) {
141739
141980
  });
141740
141981
  return `[WARNING: Path rejected: ${promptAppend} (resolved outside project root ${projectRoot} and allowed home directories; file:// prompts must reside within the project directory, ~/.config/opencode/, ~/.config/oh-my-openagent/, ~/.omo/, or ~/.opencode/)]`;
141741
141982
  }
141742
- if (!existsSync109(filePath)) {
141983
+ if (!existsSync110(filePath)) {
141743
141984
  return `[WARNING: Could not resolve file URI: ${promptAppend}]`;
141744
141985
  }
141745
141986
  try {
@@ -143231,28 +143472,6 @@ function applyEnvironmentContext(config, directory, options = {}) {
143231
143472
  return { ...config, prompt: config.prompt + envContext };
143232
143473
  }
143233
143474
 
143234
- // packages/omo-opencode/src/agents/builtin-agents/model-resolution.ts
143235
- function applyModelResolution(input) {
143236
- const { uiSelectedModel, userModel, requirement, availableModels, systemDefaultModel } = input;
143237
- return resolveModelPipeline2({
143238
- intent: { uiSelectedModel, userModel },
143239
- constraints: { availableModels },
143240
- policy: { fallbackChain: requirement?.fallbackChain, systemDefaultModel }
143241
- });
143242
- }
143243
- function getFirstFallbackModel(requirement) {
143244
- const entry = requirement?.fallbackChain?.[0];
143245
- if (!entry || entry.providers.length === 0)
143246
- return;
143247
- const provider = entry.providers[0];
143248
- const transformedModel = transformModelForProvider(provider, entry.model);
143249
- return {
143250
- model: `${provider}/${transformedModel}`,
143251
- provenance: "provider-fallback",
143252
- variant: entry.variant
143253
- };
143254
- }
143255
-
143256
143475
  // packages/omo-opencode/src/agents/builtin-agents/general-agents.ts
143257
143476
  init_logger2();
143258
143477
  function collectPendingBuiltinAgents(input) {
@@ -143349,6 +143568,33 @@ function collectPendingBuiltinAgents(input) {
143349
143568
 
143350
143569
  // packages/omo-opencode/src/agents/builtin-agents/sisyphus-agent.ts
143351
143570
  init_logger2();
143571
+
143572
+ // packages/omo-opencode/src/agents/sisyphus-runtime-prompt-reconciler.ts
143573
+ var context;
143574
+ function setSisyphusRuntimePromptContext(ctx) {
143575
+ context = ctx;
143576
+ }
143577
+ function reconcileSisyphusRuntimePrompt(system, runtimeModel) {
143578
+ if (!runtimeModel || !context)
143579
+ return false;
143580
+ if (resolveSisyphusPromptFamily(runtimeModel) === resolveSisyphusPromptFamily(context.configuredModel)) {
143581
+ return false;
143582
+ }
143583
+ const rebuilt = context.rebuildPromptForModel(runtimeModel);
143584
+ if (rebuilt === context.bakedPrompt)
143585
+ return false;
143586
+ let swapped = false;
143587
+ for (let i = 0;i < system.length; i++) {
143588
+ const part = system[i];
143589
+ if (part.includes(context.bakedPrompt)) {
143590
+ system[i] = part.split(context.bakedPrompt).join(rebuilt);
143591
+ swapped = true;
143592
+ }
143593
+ }
143594
+ return swapped;
143595
+ }
143596
+
143597
+ // packages/omo-opencode/src/agents/builtin-agents/sisyphus-agent.ts
143352
143598
  function maybeCreateSisyphusConfig(input) {
143353
143599
  const {
143354
143600
  disabledAgents,
@@ -143404,6 +143650,16 @@ function maybeCreateSisyphusConfig(input) {
143404
143650
  sisyphusConfig = applyEnvironmentContext(sisyphusConfig, directory, {
143405
143651
  disableOmoEnv
143406
143652
  });
143653
+ setSisyphusRuntimePromptContext({
143654
+ configuredModel: sisyphusModel,
143655
+ bakedPrompt: sisyphusConfig.prompt ?? "",
143656
+ rebuildPromptForModel: (runtimeModel) => {
143657
+ let rebuilt = createSisyphusAgent(runtimeModel, availableAgents, undefined, availableSkills, availableCategories, useTaskSystem);
143658
+ rebuilt = applyOverrides(rebuilt, sisyphusOverride, mergedCategories, directory);
143659
+ rebuilt = applyEnvironmentContext(rebuilt, directory, { disableOmoEnv });
143660
+ return rebuilt.prompt ?? "";
143661
+ }
143662
+ });
143407
143663
  return sisyphusConfig;
143408
143664
  }
143409
143665
 
@@ -143700,7 +143956,7 @@ function isDisabledConfigSkillEntryName(name, disabledSkills) {
143700
143956
  return disabledSkills.has(normalizeSkillAliasName2(name));
143701
143957
  }
143702
143958
  async function createSkillContext(args) {
143703
- const { directory, pluginConfig } = args;
143959
+ const { directory, pluginConfig, hostSkills } = args;
143704
143960
  const browserProvider = pluginConfig.browser_automation_engine?.provider ?? "playwright";
143705
143961
  const disabledSkills = collectDisabledSkillAliases(pluginConfig);
143706
143962
  const builtinSkills = resolveActiveBuiltinSkills({
@@ -143710,7 +143966,7 @@ async function createSkillContext(args) {
143710
143966
  systemMcpNames: getSystemMcpServerNames()
143711
143967
  });
143712
143968
  const includeClaudeSkills = pluginConfig.claude_code?.skills !== false;
143713
- const hostSkillConfig = adaptHostSkillConfig(readOpencodeConfigSkills(directory));
143969
+ const hostSkillConfig = adaptHostSkillConfig(hostSkills ?? readOpencodeConfigSkills(directory));
143714
143970
  const [
143715
143971
  configSourceSkills,
143716
143972
  hostConfigSkills,
@@ -144394,7 +144650,7 @@ async function applyAgentConfig(params) {
144394
144650
  }
144395
144651
  // packages/claude-code-compat-core/src/features/claude-code-command-loader/loader.ts
144396
144652
  import { promises as fs23 } from "fs";
144397
- import { join as join128, basename as basename24 } from "path";
144653
+ import { join as join130, basename as basename24 } from "path";
144398
144654
 
144399
144655
  // packages/claude-code-compat-core/src/features/claude-code-command-loader/loader-cache.ts
144400
144656
  var commandLoaderCache = new Map;
@@ -144442,7 +144698,7 @@ async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix
144442
144698
  continue;
144443
144699
  if (entry.name.startsWith("."))
144444
144700
  continue;
144445
- const subDirPath = join128(commandsDir, entry.name);
144701
+ const subDirPath = join130(commandsDir, entry.name);
144446
144702
  const subPrefix = prefix ? `${prefix}/${entry.name}` : entry.name;
144447
144703
  const subCommands = await loadCommandsFromDir(subDirPath, scope, visited, subPrefix);
144448
144704
  commands.push(...subCommands);
@@ -144450,7 +144706,7 @@ async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix
144450
144706
  }
144451
144707
  if (!isMarkdownFile(entry))
144452
144708
  continue;
144453
- const commandPath = join128(commandsDir, entry.name);
144709
+ const commandPath = join130(commandsDir, entry.name);
144454
144710
  const baseCommandName = basename24(entry.name, ".md");
144455
144711
  const commandName = prefix ? `${prefix}/${baseCommandName}` : baseCommandName;
144456
144712
  try {
@@ -144513,12 +144769,12 @@ function commandsToRecord(commands) {
144513
144769
  return result;
144514
144770
  }
144515
144771
  async function loadUserCommands() {
144516
- const userCommandsDir = join128(getClaudeConfigDir3(), "commands");
144772
+ const userCommandsDir = join130(getClaudeConfigDir3(), "commands");
144517
144773
  const commands = await loadCommandsFromDir(userCommandsDir, "user");
144518
144774
  return commandsToRecord(commands);
144519
144775
  }
144520
144776
  async function loadProjectCommands(directory) {
144521
- const projectCommandsDir = join128(directory ?? process.cwd(), ".claude", "commands");
144777
+ const projectCommandsDir = join130(directory ?? process.cwd(), ".claude", "commands");
144522
144778
  const commands = await loadCommandsFromDir(projectCommandsDir, "project");
144523
144779
  return commandsToRecord(commands);
144524
144780
  }
@@ -144695,8 +144951,8 @@ var grep_app = {
144695
144951
 
144696
144952
  // packages/omo-opencode/src/mcp/codegraph.ts
144697
144953
  init_src();
144698
- import { existsSync as existsSync110 } from "fs";
144699
- import { join as join129 } from "path";
144954
+ import { existsSync as existsSync111 } from "fs";
144955
+ import { join as join131 } from "path";
144700
144956
 
144701
144957
  // packages/omo-opencode/src/mcp/runtime-executable.ts
144702
144958
  init_bun_which_shim();
@@ -144743,7 +144999,7 @@ function createWhichResolver(resolveExecutable) {
144743
144999
  function provisionedBinFromInstallDir2(installDir, fileExists2) {
144744
145000
  if (installDir === undefined)
144745
145001
  return null;
144746
- const candidate = join129(installDir, "bin", process.platform === "win32" ? "codegraph.cmd" : "codegraph");
145002
+ const candidate = join131(installDir, "bin", process.platform === "win32" ? "codegraph.cmd" : "codegraph");
144747
145003
  return fileExists2(candidate) ? candidate : null;
144748
145004
  }
144749
145005
  function codegraphEnvForConfig(config, homeDir) {
@@ -144754,7 +145010,7 @@ function createCodegraphMcpConfig(options = {}) {
144754
145010
  const env2 = options.env ?? process.env;
144755
145011
  const resolveExecutable = options.resolveExecutable ?? resolveRuntimeExecutable;
144756
145012
  const which2 = createWhichResolver(resolveExecutable);
144757
- const fileExists2 = options.fileExists ?? existsSync110;
145013
+ const fileExists2 = options.fileExists ?? existsSync111;
144758
145014
  const resolvedCommand = resolveCodegraphCommand({
144759
145015
  env: env2,
144760
145016
  fileExists: fileExists2,
@@ -144780,9 +145036,9 @@ function createCodegraphMcpConfig(options = {}) {
144780
145036
  }
144781
145037
 
144782
145038
  // packages/omo-opencode/src/mcp/lsp.ts
144783
- import { existsSync as existsSync111 } from "fs";
144784
- import { delimiter as delimiter2, dirname as dirname43, resolve as resolve40 } from "path";
144785
- import { fileURLToPath as fileURLToPath7 } from "url";
145039
+ import { existsSync as existsSync112 } from "fs";
145040
+ import { delimiter as delimiter2, dirname as dirname44, resolve as resolve40 } from "path";
145041
+ import { fileURLToPath as fileURLToPath8 } from "url";
144786
145042
 
144787
145043
  // packages/omo-opencode/src/mcp/cli-suffix.ts
144788
145044
  function normalizeCliPath(path22) {
@@ -144868,7 +145124,7 @@ var LSP_BOOTSTRAP_SCRIPT = [
144868
145124
  ].join(";");
144869
145125
  function getModuleDirectory(moduleUrl) {
144870
145126
  try {
144871
- return dirname43(fileURLToPath7(moduleUrl));
145127
+ return dirname44(fileURLToPath8(moduleUrl));
144872
145128
  } catch (error) {
144873
145129
  if (!(error instanceof Error))
144874
145130
  throw error;
@@ -144892,7 +145148,7 @@ function createBootstrapCandidate(root, pathExists, resolveExecutable) {
144892
145148
  };
144893
145149
  }
144894
145150
  function resolveLspCommand(options = {}) {
144895
- const pathExists = options.exists ?? existsSync111;
145151
+ const pathExists = options.exists ?? existsSync112;
144896
145152
  const resolveExecutable = options.resolveExecutable ?? resolveRuntimeExecutable;
144897
145153
  const moduleDirectory = getModuleDirectory(options.moduleUrl ?? import.meta.url);
144898
145154
  const candidates = moduleDirectory ? createAncestorCliCandidates({
@@ -145528,6 +145784,37 @@ function createTeamModeToolsRecord(args) {
145528
145784
  };
145529
145785
  }
145530
145786
 
145787
+ // packages/omo-opencode/src/plugin/runtime-skill-resolver.ts
145788
+ async function readRuntimeHostSkills(client3) {
145789
+ try {
145790
+ const result = await client3.config.get();
145791
+ const skills = result.data?.skills;
145792
+ if (skills && typeof skills === "object") {
145793
+ return skills;
145794
+ }
145795
+ } catch {}
145796
+ return;
145797
+ }
145798
+ function createRuntimeSkillsResolver(args) {
145799
+ const { baseSkills, readRuntimeHostSkills: readHostSkills, buildMergedSkills } = args;
145800
+ let inflight;
145801
+ const resolve41 = async () => {
145802
+ const hostSkills = await readHostSkills();
145803
+ if (!hostSkills)
145804
+ return baseSkills;
145805
+ try {
145806
+ return await buildMergedSkills(hostSkills);
145807
+ } catch {
145808
+ return baseSkills;
145809
+ }
145810
+ };
145811
+ return () => {
145812
+ if (!inflight)
145813
+ inflight = resolve41();
145814
+ return inflight;
145815
+ };
145816
+ }
145817
+
145531
145818
  // packages/omo-opencode/src/plugin/tool-registry-core-tools.ts
145532
145819
  function createCoreTools(args) {
145533
145820
  const { ctx, pluginConfig, managers, skillContext, availableCategories, factories } = args;
@@ -145581,9 +145868,14 @@ function createCoreTools(args) {
145581
145868
  }
145582
145869
  });
145583
145870
  const getSessionIDForMcp = () => getMainSessionID();
145871
+ const getLoadedSkillsForMcp = createRuntimeSkillsResolver({
145872
+ baseSkills: skillContext.mergedSkills,
145873
+ readRuntimeHostSkills: () => readRuntimeHostSkills(ctx.client),
145874
+ buildMergedSkills: async (hostSkills) => (await createSkillContext({ directory: ctx.directory, pluginConfig, hostSkills })).mergedSkills
145875
+ });
145584
145876
  const skillMcpTool = factories.createSkillMcpTool({
145585
145877
  manager: managers.skillMcpManager,
145586
- getLoadedSkills: () => skillContext.mergedSkills,
145878
+ getLoadedSkills: getLoadedSkillsForMcp,
145587
145879
  getSessionID: getSessionIDForMcp
145588
145880
  });
145589
145881
  const commands2 = factories.discoverCommandsSync(ctx.directory, {
@@ -147821,8 +148113,8 @@ function createChatHeadersHandler(args) {
147821
148113
  }
147822
148114
 
147823
148115
  // packages/omo-opencode/src/plugin/ultrawork-db-model-override.ts
147824
- import { join as join130 } from "path";
147825
- import { existsSync as existsSync112 } from "fs";
148116
+ import { join as join132 } from "path";
148117
+ import { existsSync as existsSync113 } from "fs";
147826
148118
  async function importBunSqlite() {
147827
148119
  if (typeof globalThis.Bun === "undefined") {
147828
148120
  return null;
@@ -147838,7 +148130,7 @@ async function importBunSqlite() {
147838
148130
  }
147839
148131
  }
147840
148132
  function getDbPath() {
147841
- return join130(getDataDir(), "opencode", "opencode.db");
148133
+ return join132(getDataDir(), "opencode", "opencode.db");
147842
148134
  }
147843
148135
  var MAX_MICROTASK_RETRIES = 10;
147844
148136
  function logCaughtDbError(message, metadata, error) {
@@ -147941,7 +148233,7 @@ async function scheduleDeferredModelOverride(messageId, targetModel, variant) {
147941
148233
  return;
147942
148234
  }
147943
148235
  const dbPath = getDbPath();
147944
- if (!existsSync112(dbPath)) {
148236
+ if (!existsSync113(dbPath)) {
147945
148237
  log2("[ultrawork-db-override] DB not found, skipping deferred override");
147946
148238
  return;
147947
148239
  }
@@ -148642,6 +148934,7 @@ function isFalsy(value) {
148642
148934
  var ULTRAWORK_MODE_TAG = "<ultrawork-mode>";
148643
148935
  function createSystemTransformHandler(defaultMode, getUltraworkMessage2, env2 = process.env) {
148644
148936
  return async (input, output) => {
148937
+ reconcileSisyphusRuntimePrompt(output.system, input.model?.id);
148645
148938
  const sparkshellAwareness = getSparkShellRuntimeAwareness(env2);
148646
148939
  if (sparkshellAwareness.length > 0 && !output.system.some(hasSparkShellRuntimeAwareness)) {
148647
148940
  output.system.push(sparkshellAwareness);
@@ -150718,6 +151011,7 @@ var ClaudeCodeConfigSchema = z22.object({
150718
151011
  // packages/omo-opencode/src/config/schema/codegraph.ts
150719
151012
  import { z as z23 } from "zod";
150720
151013
  var CodegraphConfigSchema = z23.object({
151014
+ auto_init: z23.boolean().default(true),
150721
151015
  auto_provision: z23.boolean().default(true),
150722
151016
  enabled: z23.boolean().default(true),
150723
151017
  install_dir: z23.string().optional(),
@@ -150962,7 +151256,8 @@ var RuntimeFallbackConfigSchema = z39.object({
150962
151256
  max_fallback_attempts: z39.number().min(1).max(20).optional(),
150963
151257
  cooldown_seconds: z39.number().min(0).optional(),
150964
151258
  timeout_seconds: z39.number().min(0).optional(),
150965
- notify_on_fallback: z39.boolean().optional()
151259
+ notify_on_fallback: z39.boolean().optional(),
151260
+ restore_primary_after_cooldown: z39.boolean().optional()
150966
151261
  });
150967
151262
 
150968
151263
  // packages/team-core/src/config.ts
@@ -151528,9 +151823,9 @@ function createSessionCompactingHandler(hooks2) {
151528
151823
  });
151529
151824
  await runCompactionStep("compactionContextInjector.inject", input.sessionID, () => {
151530
151825
  const inject = hooks2.compactionContextInjector?.inject;
151531
- const context = inject ? inject(input.sessionID) : undefined;
151532
- if (context) {
151533
- output.context.push(context);
151826
+ const context2 = inject ? inject(input.sessionID) : undefined;
151827
+ if (context2) {
151828
+ output.context.push(context2);
151534
151829
  }
151535
151830
  });
151536
151831
  };