oh-my-opencode 4.12.0 → 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 (560) 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 +916 -670
  6. package/dist/cli-node/index.js +916 -670
  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 +1042 -640
  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 +34 -6
  169. package/dist/skills/ulw-plan/SKILL.md +4 -1
  170. package/dist/tools/background-task/constants.d.ts +1 -1
  171. package/dist/tools/delegate-task/sync-task-deps.d.ts +8 -6
  172. package/dist/tools/skill-mcp/tools.d.ts +1 -1
  173. package/dist/tui.js +18 -4
  174. package/package.json +16 -14
  175. package/packages/omo-codex/THIRD-PARTY-NOTICES.md +27 -4
  176. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +3 -1
  177. package/packages/omo-codex/plugin/README.md +1 -1
  178. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +134 -42
  179. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  180. package/packages/omo-codex/plugin/components/codegraph/LICENSE +21 -0
  181. package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +2951 -0
  182. package/packages/omo-codex/plugin/components/codegraph/NOTICE +16 -0
  183. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +633 -193
  184. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +561 -44
  185. package/packages/omo-codex/plugin/components/codegraph/package.json +9 -3
  186. package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +11 -0
  187. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +12 -0
  188. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +34 -0
  189. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +75 -0
  190. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +66 -13
  191. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +26 -12
  192. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +50 -330
  193. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +91 -0
  194. package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +2 -2
  195. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +68 -0
  196. package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +11 -1
  197. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +48 -0
  198. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +133 -0
  199. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +1 -112
  200. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +149 -0
  201. package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +63 -0
  202. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +106 -0
  203. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +150 -0
  204. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  205. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  206. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  207. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  208. package/packages/omo-codex/plugin/components/rules/dist/cli.js +3 -3
  209. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  210. package/packages/omo-codex/plugin/components/rules/src/sparkshell-awareness.ts +3 -3
  211. package/packages/omo-codex/plugin/components/rules/test/sparkshell-awareness.test.ts +33 -9
  212. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  213. package/packages/omo-codex/plugin/components/teammode/dist/cli.js +94 -0
  214. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +17 -0
  215. package/packages/omo-codex/plugin/components/teammode/package.json +26 -0
  216. package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +59 -32
  217. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-guide.mjs +17 -16
  218. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-state.mjs +70 -3
  219. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-worktree.mjs +113 -0
  220. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +63 -4
  221. package/packages/omo-codex/plugin/components/teammode/src/cli.ts +12 -0
  222. package/packages/omo-codex/plugin/components/teammode/src/codex-hook.ts +125 -0
  223. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +116 -0
  224. package/packages/omo-codex/plugin/components/teammode/tsconfig.json +25 -0
  225. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  226. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -1
  227. package/packages/omo-codex/plugin/components/ultrawork/directive.md +5 -4
  228. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  229. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +24 -3
  230. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  231. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +8 -7
  232. package/packages/omo-codex/plugin/components/ulw-loop/test/skill-contract.test.ts +1 -1
  233. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +17 -0
  234. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +17 -0
  235. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  236. package/packages/omo-codex/plugin/package-lock.json +129 -12
  237. package/packages/omo-codex/plugin/package.json +3 -2
  238. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +133 -0
  239. package/packages/omo-codex/plugin/scripts/auto-update-release-notes.mjs +135 -0
  240. package/packages/omo-codex/plugin/scripts/auto-update.mjs +33 -133
  241. package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +1 -0
  242. package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +41 -0
  243. package/packages/omo-codex/plugin/shared/src/config-loader.ts +20 -2
  244. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +16 -0
  245. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +32 -8
  246. package/packages/omo-codex/plugin/skills/frontend/references/design/airbnb.md +3 -0
  247. package/packages/omo-codex/plugin/skills/frontend/references/design/airtable.md +3 -0
  248. package/packages/omo-codex/plugin/skills/frontend/references/design/apple.md +3 -0
  249. package/packages/omo-codex/plugin/skills/frontend/references/design/binance.md +3 -0
  250. package/packages/omo-codex/plugin/skills/frontend/references/design/bmw.md +3 -0
  251. package/packages/omo-codex/plugin/skills/frontend/references/design/bugatti.md +3 -0
  252. package/packages/omo-codex/plugin/skills/frontend/references/design/cal.md +3 -0
  253. package/packages/omo-codex/plugin/skills/frontend/references/design/claude.md +3 -0
  254. package/packages/omo-codex/plugin/skills/frontend/references/design/clay.md +3 -0
  255. package/packages/omo-codex/plugin/skills/frontend/references/design/clickhouse.md +3 -0
  256. package/packages/omo-codex/plugin/skills/frontend/references/design/cohere.md +3 -0
  257. package/packages/omo-codex/plugin/skills/frontend/references/design/coinbase.md +3 -0
  258. package/packages/omo-codex/plugin/skills/frontend/references/design/composio.md +3 -0
  259. package/packages/omo-codex/plugin/skills/frontend/references/design/cursor.md +3 -0
  260. package/packages/omo-codex/plugin/skills/frontend/references/design/elevenlabs.md +3 -0
  261. package/packages/omo-codex/plugin/skills/frontend/references/design/expo.md +3 -0
  262. package/packages/omo-codex/plugin/skills/frontend/references/design/ferrari.md +3 -0
  263. package/packages/omo-codex/plugin/skills/frontend/references/design/figma.md +3 -0
  264. package/packages/omo-codex/plugin/skills/frontend/references/design/framer.md +3 -0
  265. package/packages/omo-codex/plugin/skills/frontend/references/design/hashicorp.md +3 -0
  266. package/packages/omo-codex/plugin/skills/frontend/references/design/ibm.md +3 -0
  267. package/packages/omo-codex/plugin/skills/frontend/references/design/imagegen-frontend-web.md +380 -79
  268. package/packages/omo-codex/plugin/skills/frontend/references/design/intercom.md +3 -0
  269. package/packages/omo-codex/plugin/skills/frontend/references/design/kraken.md +3 -0
  270. package/packages/omo-codex/plugin/skills/frontend/references/design/lamborghini.md +3 -0
  271. package/packages/omo-codex/plugin/skills/frontend/references/design/linear.app.md +3 -0
  272. package/packages/omo-codex/plugin/skills/frontend/references/design/lovable.md +3 -0
  273. package/packages/omo-codex/plugin/skills/frontend/references/design/mastercard.md +3 -0
  274. package/packages/omo-codex/plugin/skills/frontend/references/design/meta.md +3 -0
  275. package/packages/omo-codex/plugin/skills/frontend/references/design/minimax.md +3 -0
  276. package/packages/omo-codex/plugin/skills/frontend/references/design/mintlify.md +3 -0
  277. package/packages/omo-codex/plugin/skills/frontend/references/design/miro.md +3 -0
  278. package/packages/omo-codex/plugin/skills/frontend/references/design/mistral.ai.md +3 -0
  279. package/packages/omo-codex/plugin/skills/frontend/references/design/mongodb.md +3 -0
  280. package/packages/omo-codex/plugin/skills/frontend/references/design/nike.md +3 -0
  281. package/packages/omo-codex/plugin/skills/frontend/references/design/notion.md +3 -0
  282. package/packages/omo-codex/plugin/skills/frontend/references/design/nvidia.md +3 -0
  283. package/packages/omo-codex/plugin/skills/frontend/references/design/ollama.md +3 -0
  284. package/packages/omo-codex/plugin/skills/frontend/references/design/opencode.ai.md +3 -0
  285. package/packages/omo-codex/plugin/skills/frontend/references/design/pinterest.md +3 -0
  286. package/packages/omo-codex/plugin/skills/frontend/references/design/playstation.md +3 -0
  287. package/packages/omo-codex/plugin/skills/frontend/references/design/posthog.md +3 -0
  288. package/packages/omo-codex/plugin/skills/frontend/references/design/raycast.md +3 -0
  289. package/packages/omo-codex/plugin/skills/frontend/references/design/renault.md +3 -0
  290. package/packages/omo-codex/plugin/skills/frontend/references/design/replicate.md +3 -0
  291. package/packages/omo-codex/plugin/skills/frontend/references/design/resend.md +3 -0
  292. package/packages/omo-codex/plugin/skills/frontend/references/design/revolut.md +3 -0
  293. package/packages/omo-codex/plugin/skills/frontend/references/design/runwayml.md +3 -0
  294. package/packages/omo-codex/plugin/skills/frontend/references/design/sanity.md +3 -0
  295. package/packages/omo-codex/plugin/skills/frontend/references/design/sentry.md +3 -0
  296. package/packages/omo-codex/plugin/skills/frontend/references/design/shopify.md +3 -0
  297. package/packages/omo-codex/plugin/skills/frontend/references/design/spacex.md +3 -0
  298. package/packages/omo-codex/plugin/skills/frontend/references/design/spotify.md +3 -0
  299. package/packages/omo-codex/plugin/skills/frontend/references/design/starbucks.md +3 -0
  300. package/packages/omo-codex/plugin/skills/frontend/references/design/stitch-skill.md +1 -1
  301. package/packages/omo-codex/plugin/skills/frontend/references/design/stripe.md +3 -0
  302. package/packages/omo-codex/plugin/skills/frontend/references/design/supabase.md +3 -0
  303. package/packages/omo-codex/plugin/skills/frontend/references/design/superhuman.md +3 -0
  304. package/packages/omo-codex/plugin/skills/frontend/references/design/taste-skill.md +1188 -208
  305. package/packages/omo-codex/plugin/skills/frontend/references/design/tesla.md +3 -0
  306. package/packages/omo-codex/plugin/skills/frontend/references/design/theverge.md +3 -0
  307. package/packages/omo-codex/plugin/skills/frontend/references/design/together.ai.md +3 -0
  308. package/packages/omo-codex/plugin/skills/frontend/references/design/uber.md +3 -0
  309. package/packages/omo-codex/plugin/skills/frontend/references/design/vercel.md +3 -0
  310. package/packages/omo-codex/plugin/skills/frontend/references/design/vodafone.md +3 -0
  311. package/packages/omo-codex/plugin/skills/frontend/references/design/voltagent.md +3 -0
  312. package/packages/omo-codex/plugin/skills/frontend/references/design/warp.md +3 -0
  313. package/packages/omo-codex/plugin/skills/frontend/references/design/webflow.md +3 -0
  314. package/packages/omo-codex/plugin/skills/frontend/references/design/wired.md +3 -0
  315. package/packages/omo-codex/plugin/skills/frontend/references/design/wise.md +3 -0
  316. package/packages/omo-codex/plugin/skills/frontend/references/design/x.ai.md +3 -0
  317. package/packages/omo-codex/plugin/skills/frontend/references/design/zapier.md +3 -0
  318. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/README.md +501 -115
  319. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/charts.csv +26 -26
  320. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/colors.csv +162 -97
  321. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/icons.csv +105 -100
  322. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/landing.csv +22 -18
  323. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/products.csv +162 -97
  324. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/flutter.csv +53 -53
  325. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/html-tailwind.csv +56 -56
  326. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/nextjs.csv +53 -53
  327. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/react.csv +54 -54
  328. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/svelte.csv +54 -54
  329. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/swiftui.csv +51 -51
  330. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/vue.csv +50 -50
  331. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/styles.csv +17 -0
  332. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/typography.csv +17 -1
  333. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/ui-reasoning.csv +162 -101
  334. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/web-interface.csv +30 -30
  335. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/core.py +31 -22
  336. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/design_system.py +150 -69
  337. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/search.py +3 -3
  338. package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +1 -1
  339. package/packages/omo-codex/plugin/skills/teammode/SKILL.md +59 -32
  340. package/packages/omo-codex/plugin/skills/teammode/scripts/team-guide.mjs +17 -16
  341. package/packages/omo-codex/plugin/skills/teammode/scripts/team-state.mjs +70 -3
  342. package/packages/omo-codex/plugin/skills/teammode/scripts/team-worktree.mjs +113 -0
  343. package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +63 -4
  344. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +105 -0
  345. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +140 -0
  346. package/packages/omo-codex/plugin/skills/ultimate-browsing/agents/openai.yaml +2 -0
  347. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/__init__.py +24 -0
  348. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/__main__.py +106 -0
  349. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/bias_check.py +174 -0
  350. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/curl_probe.py +91 -0
  351. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/executor.py +192 -0
  352. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/fetch_chain.py +268 -0
  353. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/referers.py +15 -0
  354. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/result_schema.py +45 -0
  355. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/summary.py +37 -0
  356. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +11 -0
  357. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +129 -0
  358. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +167 -0
  359. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_fetch_chain.py +77 -0
  360. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +282 -0
  361. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/url_transforms.py +98 -0
  362. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/validators.py +216 -0
  363. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/waf_detector.py +214 -0
  364. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/waf_profiles.yaml +162 -0
  365. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/README.md +79 -0
  366. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/career.md +29 -0
  367. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/dev.md +62 -0
  368. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/search.md +33 -0
  369. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/social.md +207 -0
  370. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/video.md +115 -0
  371. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/web.md +76 -0
  372. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +120 -0
  373. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +319 -0
  374. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/cache-archive.md +83 -0
  375. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/fallback.md +159 -0
  376. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/jina.md +130 -0
  377. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/json-api.md +133 -0
  378. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/media.md +123 -0
  379. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/metadata.md +116 -0
  380. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/naver.md +107 -0
  381. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/playwright.md +142 -0
  382. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/public-api.md +119 -0
  383. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/rss.md +123 -0
  384. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/tls-impersonate.md +186 -0
  385. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/twitter.md +104 -0
  386. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/cookie_crypto.py +75 -0
  387. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/cookie_domains.py +38 -0
  388. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/cookie_paths.py +112 -0
  389. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/extract_cookies.py +280 -0
  390. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/tests/test_cookie_domain_filter.py +110 -0
  391. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/tests/test_extract_cookies.py +245 -0
  392. package/packages/omo-codex/plugin/skills/ultraresearch/ATTRIBUTION.md +49 -0
  393. package/packages/omo-codex/plugin/skills/ultraresearch/SKILL.md +34 -6
  394. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +8 -7
  395. package/packages/omo-codex/plugin/test/aggregate-build.test.mjs +2 -1
  396. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +36 -0
  397. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +2 -1
  398. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +1 -1
  399. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +95 -0
  400. package/packages/omo-codex/plugin/test/auto-update-restart-notice.test.mjs +12 -3
  401. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -0
  402. package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +76 -0
  403. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +24 -0
  404. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +1 -0
  405. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +1 -0
  406. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +87 -0
  407. package/packages/omo-codex/plugin/test/teammode-thread-title.test.mjs +169 -0
  408. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +246 -0
  409. package/packages/omo-codex/plugin/test/ultraresearch-skill-contract.test.mjs +78 -0
  410. package/packages/omo-codex/scripts/install-cli-args.test.mjs +1 -1
  411. package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +23 -0
  412. package/packages/omo-codex/scripts/install-delegated-command.test.mjs +76 -4
  413. package/packages/omo-codex/scripts/install-dist/install-local.mjs +531 -214
  414. package/packages/omo-codex/scripts/install-local-entrypoint.test.mjs +40 -3
  415. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +32 -8
  416. package/packages/shared-skills/skills/frontend/references/design/airbnb.md +3 -0
  417. package/packages/shared-skills/skills/frontend/references/design/airtable.md +3 -0
  418. package/packages/shared-skills/skills/frontend/references/design/apple.md +3 -0
  419. package/packages/shared-skills/skills/frontend/references/design/binance.md +3 -0
  420. package/packages/shared-skills/skills/frontend/references/design/bmw.md +3 -0
  421. package/packages/shared-skills/skills/frontend/references/design/bugatti.md +3 -0
  422. package/packages/shared-skills/skills/frontend/references/design/cal.md +3 -0
  423. package/packages/shared-skills/skills/frontend/references/design/claude.md +3 -0
  424. package/packages/shared-skills/skills/frontend/references/design/clay.md +3 -0
  425. package/packages/shared-skills/skills/frontend/references/design/clickhouse.md +3 -0
  426. package/packages/shared-skills/skills/frontend/references/design/cohere.md +3 -0
  427. package/packages/shared-skills/skills/frontend/references/design/coinbase.md +3 -0
  428. package/packages/shared-skills/skills/frontend/references/design/composio.md +3 -0
  429. package/packages/shared-skills/skills/frontend/references/design/cursor.md +3 -0
  430. package/packages/shared-skills/skills/frontend/references/design/elevenlabs.md +3 -0
  431. package/packages/shared-skills/skills/frontend/references/design/expo.md +3 -0
  432. package/packages/shared-skills/skills/frontend/references/design/ferrari.md +3 -0
  433. package/packages/shared-skills/skills/frontend/references/design/figma.md +3 -0
  434. package/packages/shared-skills/skills/frontend/references/design/framer.md +3 -0
  435. package/packages/shared-skills/skills/frontend/references/design/hashicorp.md +3 -0
  436. package/packages/shared-skills/skills/frontend/references/design/ibm.md +3 -0
  437. package/packages/shared-skills/skills/frontend/references/design/imagegen-frontend-web.md +380 -79
  438. package/packages/shared-skills/skills/frontend/references/design/intercom.md +3 -0
  439. package/packages/shared-skills/skills/frontend/references/design/kraken.md +3 -0
  440. package/packages/shared-skills/skills/frontend/references/design/lamborghini.md +3 -0
  441. package/packages/shared-skills/skills/frontend/references/design/linear.app.md +3 -0
  442. package/packages/shared-skills/skills/frontend/references/design/lovable.md +3 -0
  443. package/packages/shared-skills/skills/frontend/references/design/mastercard.md +3 -0
  444. package/packages/shared-skills/skills/frontend/references/design/meta.md +3 -0
  445. package/packages/shared-skills/skills/frontend/references/design/minimax.md +3 -0
  446. package/packages/shared-skills/skills/frontend/references/design/mintlify.md +3 -0
  447. package/packages/shared-skills/skills/frontend/references/design/miro.md +3 -0
  448. package/packages/shared-skills/skills/frontend/references/design/mistral.ai.md +3 -0
  449. package/packages/shared-skills/skills/frontend/references/design/mongodb.md +3 -0
  450. package/packages/shared-skills/skills/frontend/references/design/nike.md +3 -0
  451. package/packages/shared-skills/skills/frontend/references/design/notion.md +3 -0
  452. package/packages/shared-skills/skills/frontend/references/design/nvidia.md +3 -0
  453. package/packages/shared-skills/skills/frontend/references/design/ollama.md +3 -0
  454. package/packages/shared-skills/skills/frontend/references/design/opencode.ai.md +3 -0
  455. package/packages/shared-skills/skills/frontend/references/design/pinterest.md +3 -0
  456. package/packages/shared-skills/skills/frontend/references/design/playstation.md +3 -0
  457. package/packages/shared-skills/skills/frontend/references/design/posthog.md +3 -0
  458. package/packages/shared-skills/skills/frontend/references/design/raycast.md +3 -0
  459. package/packages/shared-skills/skills/frontend/references/design/renault.md +3 -0
  460. package/packages/shared-skills/skills/frontend/references/design/replicate.md +3 -0
  461. package/packages/shared-skills/skills/frontend/references/design/resend.md +3 -0
  462. package/packages/shared-skills/skills/frontend/references/design/revolut.md +3 -0
  463. package/packages/shared-skills/skills/frontend/references/design/runwayml.md +3 -0
  464. package/packages/shared-skills/skills/frontend/references/design/sanity.md +3 -0
  465. package/packages/shared-skills/skills/frontend/references/design/sentry.md +3 -0
  466. package/packages/shared-skills/skills/frontend/references/design/shopify.md +3 -0
  467. package/packages/shared-skills/skills/frontend/references/design/spacex.md +3 -0
  468. package/packages/shared-skills/skills/frontend/references/design/spotify.md +3 -0
  469. package/packages/shared-skills/skills/frontend/references/design/starbucks.md +3 -0
  470. package/packages/shared-skills/skills/frontend/references/design/stitch-skill.md +1 -1
  471. package/packages/shared-skills/skills/frontend/references/design/stripe.md +3 -0
  472. package/packages/shared-skills/skills/frontend/references/design/supabase.md +3 -0
  473. package/packages/shared-skills/skills/frontend/references/design/superhuman.md +3 -0
  474. package/packages/shared-skills/skills/frontend/references/design/taste-skill.md +1188 -208
  475. package/packages/shared-skills/skills/frontend/references/design/tesla.md +3 -0
  476. package/packages/shared-skills/skills/frontend/references/design/theverge.md +3 -0
  477. package/packages/shared-skills/skills/frontend/references/design/together.ai.md +3 -0
  478. package/packages/shared-skills/skills/frontend/references/design/uber.md +3 -0
  479. package/packages/shared-skills/skills/frontend/references/design/vercel.md +3 -0
  480. package/packages/shared-skills/skills/frontend/references/design/vodafone.md +3 -0
  481. package/packages/shared-skills/skills/frontend/references/design/voltagent.md +3 -0
  482. package/packages/shared-skills/skills/frontend/references/design/warp.md +3 -0
  483. package/packages/shared-skills/skills/frontend/references/design/webflow.md +3 -0
  484. package/packages/shared-skills/skills/frontend/references/design/wired.md +3 -0
  485. package/packages/shared-skills/skills/frontend/references/design/wise.md +3 -0
  486. package/packages/shared-skills/skills/frontend/references/design/x.ai.md +3 -0
  487. package/packages/shared-skills/skills/frontend/references/design/zapier.md +3 -0
  488. package/packages/shared-skills/skills/frontend/references/ui-ux-db/README.md +501 -115
  489. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/charts.csv +26 -26
  490. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/colors.csv +162 -97
  491. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/icons.csv +105 -100
  492. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/landing.csv +22 -18
  493. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/products.csv +162 -97
  494. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/flutter.csv +53 -53
  495. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/html-tailwind.csv +56 -56
  496. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/nextjs.csv +53 -53
  497. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/react.csv +54 -54
  498. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/svelte.csv +54 -54
  499. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/swiftui.csv +51 -51
  500. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/vue.csv +50 -50
  501. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/styles.csv +17 -0
  502. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/typography.csv +17 -1
  503. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/ui-reasoning.csv +162 -101
  504. package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/web-interface.csv +30 -30
  505. package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/core.py +31 -22
  506. package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/design_system.py +150 -69
  507. package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/search.py +3 -3
  508. package/packages/shared-skills/skills/lcx-doctor/SKILL.md +1 -1
  509. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +105 -0
  510. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +140 -0
  511. package/packages/shared-skills/skills/ultimate-browsing/engine/__init__.py +24 -0
  512. package/packages/shared-skills/skills/ultimate-browsing/engine/__main__.py +106 -0
  513. package/packages/shared-skills/skills/ultimate-browsing/engine/bias_check.py +174 -0
  514. package/packages/shared-skills/skills/ultimate-browsing/engine/curl_probe.py +91 -0
  515. package/packages/shared-skills/skills/ultimate-browsing/engine/executor.py +192 -0
  516. package/packages/shared-skills/skills/ultimate-browsing/engine/fetch_chain.py +268 -0
  517. package/packages/shared-skills/skills/ultimate-browsing/engine/referers.py +15 -0
  518. package/packages/shared-skills/skills/ultimate-browsing/engine/result_schema.py +45 -0
  519. package/packages/shared-skills/skills/ultimate-browsing/engine/summary.py +37 -0
  520. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +11 -0
  521. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +129 -0
  522. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +167 -0
  523. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_fetch_chain.py +77 -0
  524. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +282 -0
  525. package/packages/shared-skills/skills/ultimate-browsing/engine/url_transforms.py +98 -0
  526. package/packages/shared-skills/skills/ultimate-browsing/engine/validators.py +216 -0
  527. package/packages/shared-skills/skills/ultimate-browsing/engine/waf_detector.py +214 -0
  528. package/packages/shared-skills/skills/ultimate-browsing/engine/waf_profiles.yaml +162 -0
  529. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/README.md +79 -0
  530. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/career.md +29 -0
  531. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/dev.md +62 -0
  532. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/search.md +33 -0
  533. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/social.md +207 -0
  534. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/video.md +115 -0
  535. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/web.md +76 -0
  536. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +120 -0
  537. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +319 -0
  538. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/cache-archive.md +83 -0
  539. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/fallback.md +159 -0
  540. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/jina.md +130 -0
  541. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/json-api.md +133 -0
  542. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/media.md +123 -0
  543. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/metadata.md +116 -0
  544. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/naver.md +107 -0
  545. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/playwright.md +142 -0
  546. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/public-api.md +119 -0
  547. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/rss.md +123 -0
  548. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/tls-impersonate.md +186 -0
  549. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/twitter.md +104 -0
  550. package/packages/shared-skills/skills/ultimate-browsing/scripts/cookie_crypto.py +75 -0
  551. package/packages/shared-skills/skills/ultimate-browsing/scripts/cookie_domains.py +38 -0
  552. package/packages/shared-skills/skills/ultimate-browsing/scripts/cookie_paths.py +112 -0
  553. package/packages/shared-skills/skills/ultimate-browsing/scripts/extract_cookies.py +280 -0
  554. package/packages/shared-skills/skills/ultimate-browsing/scripts/tests/test_cookie_domain_filter.py +110 -0
  555. package/packages/shared-skills/skills/ultimate-browsing/scripts/tests/test_extract_cookies.py +245 -0
  556. package/packages/shared-skills/skills/ultraresearch/ATTRIBUTION.md +49 -0
  557. package/packages/shared-skills/skills/ultraresearch/SKILL.md +34 -6
  558. package/packages/shared-skills/skills/ulw-plan/SKILL.md +4 -1
  559. package/packages/omo-codex/plugin/components/codegraph/dist/cli.d.ts +0 -2
  560. package/packages/omo-codex/plugin/components/codegraph/dist/serve.d.ts +0 -32
package/dist/index.js CHANGED
@@ -5798,6 +5798,201 @@ function buildCodegraphEnv(options = {}) {
5798
5798
  var CODEGRAPH_INSTALL_DIR_ENV = "CODEGRAPH_INSTALL_DIR", CODEGRAPH_NO_DOWNLOAD_ENV = "CODEGRAPH_NO_DOWNLOAD", CODEGRAPH_TELEMETRY_ENV = "CODEGRAPH_TELEMETRY", DO_NOT_TRACK_ENV = "DO_NOT_TRACK";
5799
5799
  var init_env = () => {};
5800
5800
 
5801
+ // packages/utils/src/codegraph/workspace.ts
5802
+ import { createHash as createHash2 } from "crypto";
5803
+ import {
5804
+ appendFileSync as appendFileSync2,
5805
+ existsSync as existsSync5,
5806
+ lstatSync as lstatSync2,
5807
+ mkdirSync as mkdirSync2,
5808
+ readFileSync as readFileSync2,
5809
+ readdirSync,
5810
+ realpathSync as realpathSync3,
5811
+ rmSync,
5812
+ statSync as statSync3,
5813
+ symlinkSync
5814
+ } from "fs";
5815
+ import { homedir as homedir3 } from "os";
5816
+ import { basename as basename3, join as join9, resolve as resolve4 } from "path";
5817
+ function sanitizeBase(value) {
5818
+ const sanitized = value.replace(/[^A-Za-z0-9._-]/g, "-").replace(/-+/g, "-");
5819
+ return sanitized.length > 0 ? sanitized : "workspace";
5820
+ }
5821
+ function codegraphDataRoot(homeDir) {
5822
+ return join9(homeDir, ".omo", "codegraph");
5823
+ }
5824
+ function workspaceStorageName(workspace) {
5825
+ const resolved = resolve4(workspace);
5826
+ const hash = createHash2("sha256").update(resolved).digest("hex").slice(0, 16);
5827
+ return `${sanitizeBase(basename3(resolved))}-${hash}`;
5828
+ }
5829
+ function resolveCodegraphWorkspacePaths(workspace, options = {}) {
5830
+ const resolvedWorkspace = resolve4(workspace);
5831
+ const dataRoot = codegraphDataRoot(options.homeDir ?? homedir3());
5832
+ return {
5833
+ dataDir: join9(dataRoot, "projects", workspaceStorageName(resolvedWorkspace)),
5834
+ dataRoot,
5835
+ projectLink: join9(resolvedWorkspace, ".codegraph")
5836
+ };
5837
+ }
5838
+ function fallbackResult(dataRoot, projectLink, reason) {
5839
+ return { dataDir: projectLink, dataRoot, linked: false, mode: "in-place-fallback", projectLink, reason };
5840
+ }
5841
+ function isSameFilesystem(workspace, dataRoot, override) {
5842
+ if (override !== undefined)
5843
+ return override;
5844
+ return statSync3(workspace).dev === statSync3(dataRoot).dev;
5845
+ }
5846
+ function ensureInPlaceFallback(projectLink) {
5847
+ if (!existsSync5(projectLink))
5848
+ mkdirSync2(projectLink, { recursive: true });
5849
+ }
5850
+ function prepareCodegraphWorkspace(workspace, options = {}) {
5851
+ const resolvedWorkspace = resolve4(workspace);
5852
+ const { dataDir, dataRoot, projectLink } = resolveCodegraphWorkspacePaths(resolvedWorkspace, options);
5853
+ try {
5854
+ mkdirSync2(dataDir, { recursive: true });
5855
+ if (existsSync5(projectLink)) {
5856
+ const linkStat = lstatSync2(projectLink);
5857
+ if (!linkStat.isSymbolicLink()) {
5858
+ return { dataDir: projectLink, dataRoot, linked: false, mode: "in-project", projectLink };
5859
+ }
5860
+ if (realpathSync3(projectLink) === realpathSync3(dataDir)) {
5861
+ return { dataDir, dataRoot, linked: true, mode: "global-linked", projectLink };
5862
+ }
5863
+ return fallbackResult(dataRoot, projectLink, "existing .codegraph symlink points outside OMO store");
5864
+ }
5865
+ if (!isSameFilesystem(resolvedWorkspace, dataRoot, options.sameFilesystem)) {
5866
+ ensureInPlaceFallback(projectLink);
5867
+ return fallbackResult(dataRoot, projectLink, "workspace and OMO store are on different filesystems");
5868
+ }
5869
+ const symlink = options.symlink ?? symlinkSync;
5870
+ symlink(dataDir, projectLink, (options.platform ?? process.platform) === "win32" ? "junction" : "dir");
5871
+ return { dataDir, dataRoot, linked: true, mode: "global-linked", projectLink };
5872
+ } catch (error) {
5873
+ const reason = error instanceof Error ? error.message : String(error);
5874
+ try {
5875
+ ensureInPlaceFallback(projectLink);
5876
+ } catch (fallbackError) {
5877
+ return fallbackResult(dataRoot, projectLink, `${reason}; fallback failed: ${String(fallbackError)}`);
5878
+ }
5879
+ return fallbackResult(dataRoot, projectLink, reason);
5880
+ }
5881
+ }
5882
+ function ensureCodegraphGitignored(workspace) {
5883
+ const gitDir = join9(workspace, ".git");
5884
+ if (!existsSync5(gitDir))
5885
+ return false;
5886
+ const excludePath = join9(gitDir, "info", "exclude");
5887
+ try {
5888
+ mkdirSync2(join9(gitDir, "info"), { recursive: true });
5889
+ const existing = existsSync5(excludePath) ? readFileSync2(excludePath, "utf8") : "";
5890
+ if (existing.split(/\r?\n/).includes(".codegraph"))
5891
+ return true;
5892
+ appendFileSync2(excludePath, `${existing.endsWith(`
5893
+ `) || existing.length === 0 ? "" : `
5894
+ `}.codegraph
5895
+ `);
5896
+ return true;
5897
+ } catch (error) {
5898
+ if (error instanceof Error)
5899
+ return false;
5900
+ throw error;
5901
+ }
5902
+ }
5903
+ var init_workspace = () => {};
5904
+
5905
+ // packages/utils/src/codegraph/guidance.ts
5906
+ import { homedir as homedir4 } from "os";
5907
+ function getCodegraphUninitializedProject(input) {
5908
+ const output = textFromUnknown(input.toolOutput);
5909
+ if (!isCodegraphTool(input.toolName))
5910
+ return null;
5911
+ const projectPath = extractProjectPath(output);
5912
+ if (projectPath !== null)
5913
+ return projectPath;
5914
+ if (!looksLikeCodegraphUninitializedOutput(output))
5915
+ return null;
5916
+ return typeof input.cwd === "string" && input.cwd.trim().length > 0 ? input.cwd.trim() : null;
5917
+ }
5918
+ function buildCodegraphInitGuidance(projectPath, options = {}) {
5919
+ const { dataDir, dataRoot, projectLink } = resolveCodegraphWorkspacePaths(projectPath, {
5920
+ homeDir: options.homeDir ?? homedir4()
5921
+ });
5922
+ const displayProjectPath = formatDisplayPath(projectPath);
5923
+ const displayProjectLink = formatDisplayPath(projectLink);
5924
+ const displayDataDir = formatDisplayPath(dataDir);
5925
+ const displayDataRoot = formatDisplayPath(dataRoot);
5926
+ return [
5927
+ "OMO CodeGraph initialization guidance:",
5928
+ "",
5929
+ `CodeGraph is not initialized for ${displayProjectPath}. Initialize it through OMO's global local store instead of leaving a standalone project-local index.`,
5930
+ "",
5931
+ `- Link or create ${displayProjectLink} so it points at ${displayDataDir} under the OMO store ${displayDataRoot}.`,
5932
+ `- Then run \`codegraph init\` from ${displayProjectPath} and retry the CodeGraph tool.`,
5933
+ "- OMO's CodeGraph bootstrap does this automatically on session start; if bootstrap just ran, wait for it to finish and retry."
5934
+ ].join(`
5935
+ `);
5936
+ }
5937
+ function buildCodegraphInitGuidanceForToolResult(input, options = {}) {
5938
+ const projectPath = getCodegraphUninitializedProject(input);
5939
+ return projectPath === null ? null : buildCodegraphInitGuidance(projectPath, options);
5940
+ }
5941
+ function extractProjectPath(output) {
5942
+ const normalizedOutput = normalizeCodegraphOutput(output);
5943
+ const uninitializedMatch = normalizedOutput.match(CODEGRAPH_UNINITIALIZED_PATTERN);
5944
+ const uninitializedProject = uninitializedMatch?.[1]?.trim();
5945
+ if (uninitializedProject && uninitializedProject.length > 0)
5946
+ return uninitializedProject;
5947
+ if (!looksLikeCodegraphUninitializedOutput(normalizedOutput))
5948
+ return null;
5949
+ const statusMatch = normalizedOutput.match(CODEGRAPH_STATUS_PROJECT_PATTERN);
5950
+ const statusProject = statusMatch?.[1]?.trim();
5951
+ return statusProject && statusProject.length > 0 ? statusProject : null;
5952
+ }
5953
+ function looksLikeCodegraphUninitializedOutput(output) {
5954
+ const normalizedOutput = normalizeCodegraphOutput(output);
5955
+ if (normalizedOutput.match(CODEGRAPH_UNINITIALIZED_PATTERN) !== null)
5956
+ return true;
5957
+ return CODEGRAPH_STATUS_UNINITIALIZED_PATTERN.test(normalizedOutput) && CODEGRAPH_INIT_HINT_PATTERN.test(normalizedOutput);
5958
+ }
5959
+ function normalizeCodegraphOutput(output) {
5960
+ return output.replace(ANSI_ESCAPE_PATTERN, "");
5961
+ }
5962
+ function isCodegraphTool(toolName) {
5963
+ if (typeof toolName !== "string")
5964
+ return false;
5965
+ return toolName.startsWith("codegraph.") || toolName.startsWith("codegraph_") || toolName.startsWith("mcp__codegraph__");
5966
+ }
5967
+ function formatDisplayPath(value) {
5968
+ return JSON.stringify(value);
5969
+ }
5970
+ function textFromUnknown(value) {
5971
+ if (typeof value === "string")
5972
+ return value;
5973
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint")
5974
+ return String(value);
5975
+ if (Array.isArray(value))
5976
+ return value.map(textFromUnknown).filter(Boolean).join(`
5977
+ `);
5978
+ if (!isRecord2(value))
5979
+ return "";
5980
+ return Object.entries(value).map(([key, nested]) => `${key}: ${textFromUnknown(nested)}`).filter((line) => line.trim().length > 0).join(`
5981
+ `);
5982
+ }
5983
+ function isRecord2(value) {
5984
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5985
+ }
5986
+ var CODEGRAPH_UNINITIALIZED_PATTERN, ANSI_ESCAPE_PATTERN, CODEGRAPH_STATUS_PROJECT_PATTERN, CODEGRAPH_STATUS_UNINITIALIZED_PATTERN, CODEGRAPH_INIT_HINT_PATTERN;
5987
+ var init_guidance = __esm(() => {
5988
+ init_workspace();
5989
+ CODEGRAPH_UNINITIALIZED_PATTERN = /CodeGraph not initialized in ([\s\S]*?)\.\s*Run ['`]codegraph init['`] in that project first\./i;
5990
+ ANSI_ESCAPE_PATTERN = /\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g;
5991
+ CODEGRAPH_STATUS_PROJECT_PATTERN = /^.*?\bProject:\s*(.+?)\s*$/im;
5992
+ CODEGRAPH_STATUS_UNINITIALIZED_PATTERN = /^.*?\bNot initialized\s*$/im;
5993
+ CODEGRAPH_INIT_HINT_PATTERN = /Run\s+["'`]codegraph init["'`]\s+(?:in that project first|to initialize)\.?/i;
5994
+ });
5995
+
5801
5996
  // packages/utils/src/codegraph/node-support.ts
5802
5997
  function evaluateCodegraphNodeSupport(options = {}) {
5803
5998
  const nodeVersion = options.nodeVersion ?? process.versions.node;
@@ -5860,24 +6055,24 @@ var init_manifest = __esm(() => {
5860
6055
  });
5861
6056
 
5862
6057
  // packages/utils/src/codegraph/provision.ts
5863
- import { createHash as createHash2, randomUUID as randomUUID2 } from "crypto";
6058
+ import { createHash as createHash3, randomUUID as randomUUID2 } from "crypto";
5864
6059
  import { execFile } from "child_process";
5865
6060
  import { chmod as chmod2, mkdir as mkdir2, readdir, readFile as readFile2, rename as rename2, rm as rm2, rmdir, stat, writeFile as writeFile3 } from "fs/promises";
5866
- import { existsSync as existsSync5 } from "fs";
5867
- import { homedir as homedir3, hostname } from "os";
5868
- import { basename as basename3, join as join9 } from "path";
6061
+ import { existsSync as existsSync6 } from "fs";
6062
+ import { homedir as homedir5, hostname } from "os";
6063
+ import { basename as basename4, join as join10 } from "path";
5869
6064
  import { promisify } from "util";
5870
6065
  function platformKey() {
5871
6066
  return `${process.platform}-${process.arch}`;
5872
6067
  }
5873
6068
  function markerPath(installDir, version) {
5874
- return join9(installDir, ".provisioned", `codegraph-${version}.json`);
6069
+ return join10(installDir, ".provisioned", `codegraph-${version}.json`);
5875
6070
  }
5876
6071
  function defaultInstallDir() {
5877
- return join9(homedir3(), ".omo", "codegraph");
6072
+ return join10(homedir5(), ".omo", "codegraph");
5878
6073
  }
5879
6074
  function sha2562(bytes) {
5880
- return createHash2("sha256").update(bytes).digest("hex");
6075
+ return createHash3("sha256").update(bytes).digest("hex");
5881
6076
  }
5882
6077
  function isErrnoException(error) {
5883
6078
  return error instanceof Error && "code" in error;
@@ -5894,7 +6089,7 @@ async function removeEmptyDirectory(path4) {
5894
6089
  }
5895
6090
  }
5896
6091
  function sleep(ms) {
5897
- return new Promise((resolve4) => setTimeout(resolve4, ms));
6092
+ return new Promise((resolve5) => setTimeout(resolve5, ms));
5898
6093
  }
5899
6094
  async function defaultDownloader(asset, timeoutMs = DEFAULT_DOWNLOAD_TIMEOUT_MS2) {
5900
6095
  const response = await fetch(asset.url, { signal: AbortSignal.timeout(timeoutMs) });
@@ -5908,7 +6103,7 @@ function forcedBadChecksumOptions(options) {
5908
6103
  const key = options.platformKey ?? platformKey();
5909
6104
  return {
5910
6105
  downloader: async () => new TextEncoder().encode("checksum mismatch"),
5911
- installDir: options.installDir ?? join9(options.lockDir, "codegraph-force-bad-checksum"),
6106
+ installDir: options.installDir ?? join10(options.lockDir, "codegraph-force-bad-checksum"),
5912
6107
  manifest: {
5913
6108
  assets: {
5914
6109
  [key]: { executableName: process.platform === "win32" ? "codegraph.cmd" : "codegraph", sha256: "0000", url: "memory://bad" }
@@ -5919,13 +6114,13 @@ function forcedBadChecksumOptions(options) {
5919
6114
  };
5920
6115
  }
5921
6116
  async function readMarker(path4) {
5922
- if (!existsSync5(path4))
6117
+ if (!existsSync6(path4))
5923
6118
  return null;
5924
6119
  try {
5925
6120
  const raw = JSON.parse(await readFile2(path4, "utf8"));
5926
6121
  if (typeof raw === "object" && raw !== null && "binPath" in raw) {
5927
6122
  const value = raw.binPath;
5928
- return typeof value === "string" && existsSync5(value) ? value : null;
6123
+ return typeof value === "string" && existsSync6(value) ? value : null;
5929
6124
  }
5930
6125
  return null;
5931
6126
  } catch (error) {
@@ -5936,7 +6131,7 @@ async function readMarker(path4) {
5936
6131
  }
5937
6132
  async function acquireLock(lockPath, waitMs, staleMs) {
5938
6133
  const startedAt = Date.now();
5939
- await mkdir2(join9(lockPath, ".."), { recursive: true });
6134
+ await mkdir2(join10(lockPath, ".."), { recursive: true });
5940
6135
  while (Date.now() - startedAt <= waitMs) {
5941
6136
  try {
5942
6137
  await mkdir2(lockPath);
@@ -5961,44 +6156,44 @@ async function installExtractedBundle(extractDir, installDir, executableName) {
5961
6156
  const roots = await readdir(extractDir);
5962
6157
  if (roots.length !== 1)
5963
6158
  throw new Error(`CodeGraph archive should contain one root directory, found ${roots.length}`);
5964
- const bundleDir = join9(extractDir, roots[0] ?? "");
6159
+ const bundleDir = join10(extractDir, roots[0] ?? "");
5965
6160
  const bundleEntries = await readdir(bundleDir);
5966
6161
  await mkdir2(installDir, { recursive: true });
5967
6162
  for (const entry of bundleEntries) {
5968
- await rm2(join9(installDir, entry), { force: true, recursive: true });
5969
- await rename2(join9(bundleDir, entry), join9(installDir, entry));
6163
+ await rm2(join10(installDir, entry), { force: true, recursive: true });
6164
+ await rename2(join10(bundleDir, entry), join10(installDir, entry));
5970
6165
  }
5971
- const destination = join9(installDir, "bin", executableName);
5972
- if (!existsSync5(destination))
6166
+ const destination = join10(installDir, "bin", executableName);
6167
+ if (!existsSync6(destination))
5973
6168
  throw new Error(`CodeGraph archive did not contain bin/${executableName}`);
5974
6169
  await chmod2(destination, 493);
5975
6170
  return destination;
5976
6171
  }
5977
6172
  async function installAsset(layout) {
5978
6173
  const { asset, downloader, installDir, version } = layout;
5979
- const stagingDir = join9(installDir, ".staging", randomUUID2());
5980
- const archivePath = join9(stagingDir, basename3(asset.url));
5981
- const extractDir = join9(stagingDir, "extract");
6174
+ const stagingDir = join10(installDir, ".staging", randomUUID2());
6175
+ const archivePath = join10(stagingDir, basename4(asset.url));
6176
+ const extractDir = join10(stagingDir, "extract");
5982
6177
  try {
5983
6178
  await mkdir2(extractDir, { recursive: true });
5984
6179
  const bytes = await downloader(asset);
5985
6180
  const actualChecksum = sha2562(bytes);
5986
6181
  if (actualChecksum !== asset.sha256) {
5987
- throw new Error(`checksum mismatch for ${basename3(asset.url)}: expected ${asset.sha256}, got ${actualChecksum}`);
6182
+ throw new Error(`checksum mismatch for ${basename4(asset.url)}: expected ${asset.sha256}, got ${actualChecksum}`);
5988
6183
  }
5989
6184
  if (!asset.url.endsWith(".tar.gz") && !asset.url.endsWith(".tgz")) {
5990
- throw new Error(`unsupported CodeGraph archive type for ${basename3(asset.url)}`);
6185
+ throw new Error(`unsupported CodeGraph archive type for ${basename4(asset.url)}`);
5991
6186
  }
5992
6187
  await writeFile3(archivePath, bytes);
5993
6188
  await extractTarGz(archivePath, extractDir);
5994
6189
  const destination = await installExtractedBundle(extractDir, installDir, asset.executableName);
5995
- await mkdir2(join9(installDir, ".provisioned"), { recursive: true });
6190
+ await mkdir2(join10(installDir, ".provisioned"), { recursive: true });
5996
6191
  await writeFile3(markerPath(installDir, version), `${JSON.stringify({ binPath: destination, version })}
5997
6192
  `);
5998
6193
  return destination;
5999
6194
  } finally {
6000
6195
  await rm2(stagingDir, { force: true, recursive: true });
6001
- await removeEmptyDirectory(join9(installDir, ".staging"));
6196
+ await removeEmptyDirectory(join10(installDir, ".staging"));
6002
6197
  }
6003
6198
  }
6004
6199
  async function ensureCodegraphProvisioned(options) {
@@ -6011,7 +6206,7 @@ async function ensureCodegraphProvisioned(options) {
6011
6206
  const existing = await readMarker(marker);
6012
6207
  if (existing !== null)
6013
6208
  return { binPath: existing, provisioned: true };
6014
- const lockPath = join9(options.lockDir, `codegraph-${hostname()}.lock`);
6209
+ const lockPath = join10(options.lockDir, `codegraph-${hostname()}.lock`);
6015
6210
  const release = await acquireLock(lockPath, options.lockWaitMs ?? DEFAULT_LOCK_WAIT_MS, options.lockStaleMs ?? DEFAULT_LOCK_STALE_MS);
6016
6211
  if (release === null)
6017
6212
  return { error: "timed out waiting for codegraph provisioning lock", provisioned: false };
@@ -6041,10 +6236,10 @@ var init_provision = __esm(() => {
6041
6236
  });
6042
6237
 
6043
6238
  // packages/utils/src/codegraph/resolve.ts
6044
- import { existsSync as existsSync6 } from "fs";
6045
- import { homedir as homedir4 } from "os";
6239
+ import { existsSync as existsSync7 } from "fs";
6240
+ import { homedir as homedir6 } from "os";
6046
6241
  import { spawnSync as spawnSync2 } from "child_process";
6047
- import { basename as basename4, dirname as dirname3, join as join10 } from "path";
6242
+ import { basename as basename5, dirname as dirname3, join as join11 } from "path";
6048
6243
  import { createRequire } from "module";
6049
6244
  function defaultRequireResolve(specifier) {
6050
6245
  return requireFromHere.resolve(specifier);
@@ -6070,7 +6265,7 @@ ${result.stderr}`.trim().split(/\s+/)[0];
6070
6265
  }
6071
6266
  }
6072
6267
  function isNodeExecutableName(filePath) {
6073
- const executable = basename4(filePath).toLowerCase();
6268
+ const executable = basename5(filePath).toLowerCase();
6074
6269
  return executable === "node" || executable === "node.exe" || /^node\d+(\.exe)?$/.test(executable);
6075
6270
  }
6076
6271
  function looksLikePath(command) {
@@ -6109,7 +6304,7 @@ function defaultNodeRuntime(env, fileExists, which2, nodeVersion) {
6109
6304
  }
6110
6305
  function resolveCodegraphNodeRuntime(options = {}) {
6111
6306
  const env = options.env ?? process.env;
6112
- return defaultNodeRuntime(env, options.fileExists ?? existsSync6, options.which ?? bunWhich, options.nodeVersion ?? defaultNodeVersion);
6307
+ return defaultNodeRuntime(env, options.fileExists ?? existsSync7, options.which ?? bunWhich, options.nodeVersion ?? defaultNodeVersion);
6113
6308
  }
6114
6309
  function resolveCodegraphNodeSupport(options = {}) {
6115
6310
  const env = options.env ?? process.env;
@@ -6123,8 +6318,8 @@ function resolveCodegraphNodeSupport(options = {}) {
6123
6318
  function defaultProvisionedBin(homeDir, fileExists) {
6124
6319
  const binaryName = process.platform === "win32" ? "codegraph.cmd" : "codegraph";
6125
6320
  const candidates = [
6126
- join10(homeDir, ".omo", "codegraph", "bin", binaryName),
6127
- join10(homeDir, ".omo", "codegraph", "node-servers", "node_modules", ".bin", binaryName)
6321
+ join11(homeDir, ".omo", "codegraph", "bin", binaryName),
6322
+ join11(homeDir, ".omo", "codegraph", "node-servers", "node_modules", ".bin", binaryName)
6128
6323
  ];
6129
6324
  return candidates.find((candidate) => fileExists(candidate)) ?? null;
6130
6325
  }
@@ -6132,7 +6327,7 @@ function resolveBundledShim(requireResolve, fileExists) {
6132
6327
  try {
6133
6328
  const packageJson = requireResolve(`${CODEGRAPH_PACKAGE}/package.json`);
6134
6329
  const packageRoot = dirname3(packageJson);
6135
- const candidates = [join10(packageRoot, "bin", "codegraph.js"), join10(packageRoot, "npm-shim.js")];
6330
+ const candidates = [join11(packageRoot, "bin", "codegraph.js"), join11(packageRoot, "npm-shim.js")];
6136
6331
  return candidates.find((candidate) => fileExists(candidate)) ?? null;
6137
6332
  } catch (error) {
6138
6333
  if (error instanceof Error)
@@ -6148,7 +6343,7 @@ function resolveBundledShim(requireResolve, fileExists) {
6148
6343
  }
6149
6344
  function resolveCodegraphCommand(options = {}) {
6150
6345
  const env = options.env ?? process.env;
6151
- const fileExists = options.fileExists ?? existsSync6;
6346
+ const fileExists = options.fileExists ?? existsSync7;
6152
6347
  const configuredBin = env[CODEGRAPH_ENV_BIN]?.trim() || env[CODEGRAPH_LEGACY_ENV_BIN]?.trim();
6153
6348
  if (configuredBin !== undefined && configuredBin.length > 0) {
6154
6349
  return { argsPrefix: [], command: configuredBin, exists: fileExists(configuredBin), source: "env" };
@@ -6160,7 +6355,7 @@ function resolveCodegraphCommand(options = {}) {
6160
6355
  if (bundled !== null && runtime4 !== null) {
6161
6356
  return { argsPrefix: [bundled], command: runtime4, exists: true, source: "bundled" };
6162
6357
  }
6163
- const provisioned = options.provisioned?.() ?? defaultProvisionedBin(options.homeDir ?? homedir4(), fileExists);
6358
+ const provisioned = options.provisioned?.() ?? defaultProvisionedBin(options.homeDir ?? homedir6(), fileExists);
6164
6359
  if (provisioned !== null && fileExists(provisioned)) {
6165
6360
  return { argsPrefix: [], command: provisioned, exists: true, source: "provisioned" };
6166
6361
  }
@@ -6179,115 +6374,19 @@ var init_resolve2 = __esm(() => {
6179
6374
  requireFromHere = createRequire(import.meta.url);
6180
6375
  });
6181
6376
 
6182
- // packages/utils/src/codegraph/workspace.ts
6183
- import { createHash as createHash3 } from "crypto";
6184
- import {
6185
- appendFileSync as appendFileSync2,
6186
- existsSync as existsSync7,
6187
- lstatSync as lstatSync2,
6188
- mkdirSync as mkdirSync2,
6189
- readFileSync as readFileSync2,
6190
- readdirSync,
6191
- realpathSync as realpathSync3,
6192
- rmSync,
6193
- statSync as statSync3,
6194
- symlinkSync
6195
- } from "fs";
6196
- import { homedir as homedir5 } from "os";
6197
- import { basename as basename5, join as join11, resolve as resolve4 } from "path";
6198
- function sanitizeBase(value) {
6199
- const sanitized = value.replace(/[^A-Za-z0-9._-]/g, "-").replace(/-+/g, "-");
6200
- return sanitized.length > 0 ? sanitized : "workspace";
6201
- }
6202
- function codegraphDataRoot(homeDir) {
6203
- return join11(homeDir, ".omo", "codegraph");
6204
- }
6205
- function workspaceStorageName(workspace) {
6206
- const resolved = resolve4(workspace);
6207
- const hash = createHash3("sha256").update(resolved).digest("hex").slice(0, 16);
6208
- return `${sanitizeBase(basename5(resolved))}-${hash}`;
6209
- }
6210
- function fallbackResult(dataRoot, projectLink, reason) {
6211
- return { dataDir: projectLink, dataRoot, linked: false, mode: "in-place-fallback", projectLink, reason };
6212
- }
6213
- function isSameFilesystem(workspace, dataRoot, override) {
6214
- if (override !== undefined)
6215
- return override;
6216
- return statSync3(workspace).dev === statSync3(dataRoot).dev;
6217
- }
6218
- function ensureInPlaceFallback(projectLink) {
6219
- if (!existsSync7(projectLink))
6220
- mkdirSync2(projectLink, { recursive: true });
6221
- }
6222
- function prepareCodegraphWorkspace(workspace, options = {}) {
6223
- const resolvedWorkspace = resolve4(workspace);
6224
- const dataRoot = codegraphDataRoot(options.homeDir ?? homedir5());
6225
- const dataDir = join11(dataRoot, "projects", workspaceStorageName(resolvedWorkspace));
6226
- const projectLink = join11(resolvedWorkspace, ".codegraph");
6227
- try {
6228
- mkdirSync2(dataDir, { recursive: true });
6229
- if (existsSync7(projectLink)) {
6230
- const linkStat = lstatSync2(projectLink);
6231
- if (!linkStat.isSymbolicLink()) {
6232
- return { dataDir: projectLink, dataRoot, linked: false, mode: "in-project", projectLink };
6233
- }
6234
- if (realpathSync3(projectLink) === realpathSync3(dataDir)) {
6235
- return { dataDir, dataRoot, linked: true, mode: "global-linked", projectLink };
6236
- }
6237
- return fallbackResult(dataRoot, projectLink, "existing .codegraph symlink points outside OMO store");
6238
- }
6239
- if (!isSameFilesystem(resolvedWorkspace, dataRoot, options.sameFilesystem)) {
6240
- ensureInPlaceFallback(projectLink);
6241
- return fallbackResult(dataRoot, projectLink, "workspace and OMO store are on different filesystems");
6242
- }
6243
- const symlink = options.symlink ?? symlinkSync;
6244
- symlink(dataDir, projectLink, (options.platform ?? process.platform) === "win32" ? "junction" : "dir");
6245
- return { dataDir, dataRoot, linked: true, mode: "global-linked", projectLink };
6246
- } catch (error) {
6247
- const reason = error instanceof Error ? error.message : String(error);
6248
- try {
6249
- ensureInPlaceFallback(projectLink);
6250
- } catch (fallbackError) {
6251
- return fallbackResult(dataRoot, projectLink, `${reason}; fallback failed: ${String(fallbackError)}`);
6252
- }
6253
- return fallbackResult(dataRoot, projectLink, reason);
6254
- }
6255
- }
6256
- function ensureCodegraphGitignored(workspace) {
6257
- const gitDir = join11(workspace, ".git");
6258
- if (!existsSync7(gitDir))
6259
- return false;
6260
- const excludePath = join11(gitDir, "info", "exclude");
6261
- try {
6262
- mkdirSync2(join11(gitDir, "info"), { recursive: true });
6263
- const existing = existsSync7(excludePath) ? readFileSync2(excludePath, "utf8") : "";
6264
- if (existing.split(/\r?\n/).includes(".codegraph"))
6265
- return true;
6266
- appendFileSync2(excludePath, `${existing.endsWith(`
6267
- `) || existing.length === 0 ? "" : `
6268
- `}.codegraph
6269
- `);
6270
- return true;
6271
- } catch (error) {
6272
- if (error instanceof Error)
6273
- return false;
6274
- throw error;
6275
- }
6276
- }
6277
- var init_workspace = () => {};
6278
-
6279
6377
  // packages/utils/src/codegraph/index.ts
6280
6378
  var init_codegraph = __esm(() => {
6281
6379
  init_env();
6380
+ init_guidance();
6282
6381
  init_provision();
6283
6382
  init_resolve2();
6284
6383
  init_workspace();
6285
6384
  });
6286
6385
 
6287
6386
  // packages/utils/src/command-executor/home-directory.ts
6288
- import { homedir as homedir6 } from "os";
6387
+ import { homedir as homedir7 } from "os";
6289
6388
  function getHomeDirectory() {
6290
- return process.env.HOME || process.env.USERPROFILE || homedir6();
6389
+ return process.env.HOME || process.env.USERPROFILE || homedir7();
6291
6390
  }
6292
6391
  var init_home_directory = () => {};
6293
6392
 
@@ -12779,7 +12878,7 @@ var init_types2 = __esm(() => {
12779
12878
 
12780
12879
  // packages/team-core/src/team-registry/paths.ts
12781
12880
  import { mkdir as mkdir3, readdir as readdir2, stat as stat2, chmod as chmod3 } from "fs/promises";
12782
- import { homedir as homedir22 } from "os";
12881
+ import { homedir as homedir23 } from "os";
12783
12882
  import path14 from "path";
12784
12883
  function getTeamDirectory(baseDir, teamName, scope, projectRoot) {
12785
12884
  if (scope === "project") {
@@ -12802,7 +12901,16 @@ function resolveContainedPath2(baseDir, pathSegments) {
12802
12901
  return resolvedPath;
12803
12902
  }
12804
12903
  function resolveBaseDir(config) {
12805
- return config.base_dir ?? path14.join(homedir22(), ".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;
12806
12914
  }
12807
12915
  function getTeamSpecPath(baseDir, teamName, scope, projectRoot) {
12808
12916
  return path14.join(getTeamDirectory(baseDir, teamName, scope, projectRoot), "config.json");
@@ -20369,20 +20477,38 @@ function ignoreStaleTeamSessionSweepFailure(error) {
20369
20477
  if (error instanceof Error)
20370
20478
  return;
20371
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
+ }
20372
20486
  async function deleteTeam(teamRunId, config, tmuxMgr, bgMgr, options, deps = defaultDeleteTeamDeps) {
20373
20487
  const runtimeState = await loadRuntimeState(teamRunId, config);
20374
20488
  const nonLeadMembers = runtimeState.members.filter((member) => member.agentType !== "leader");
20375
20489
  if (options?.force !== true && nonLeadMembers.some((member) => !DELETABLE_MEMBER_STATUSES.has(member.status))) {
20376
20490
  throw new Error("members still active");
20377
20491
  }
20378
- if (bgMgr && runtimeState.leadSessionId) {
20379
- const teamMessageMarkerPrefix = `team-create:${teamRunId}:`;
20380
- 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
+ }
20381
20504
  await Promise.all(teamTasks.map((task) => bgMgr.cancelTask(task.id, {
20382
20505
  source: "team-mode-delete",
20383
20506
  reason: `delete team ${teamRunId}`
20384
20507
  })));
20385
20508
  }
20509
+ return await deleteTeamResources(teamRunId, config, runtimeState, tmuxMgr, options, deps);
20510
+ }
20511
+ async function deleteTeamResources(teamRunId, config, runtimeState, tmuxMgr, options, deps = defaultDeleteTeamDeps) {
20386
20512
  if (options?.force === true) {
20387
20513
  await transitionRuntimeState(teamRunId, (currentRuntimeState) => ({
20388
20514
  ...currentRuntimeState,
@@ -20434,7 +20560,7 @@ async function deleteTeam(teamRunId, config, tmuxMgr, bgMgr, options, deps = def
20434
20560
  sweepStaleTeamSessions(new Set(activeTeams.map((team) => team.teamRunId))).catch(ignoreStaleTeamSessionSweepFailure);
20435
20561
  return { removedWorktrees, removedLayout };
20436
20562
  }
20437
- 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;
20438
20564
  var init_delete_team = __esm(() => {
20439
20565
  init_logger2();
20440
20566
  init_layout4();
@@ -20466,6 +20592,7 @@ var init_delete_team = __esm(() => {
20466
20592
  "idle"
20467
20593
  ]);
20468
20594
  FORCE_BYPASS_DELETING_STATUSES = new Set(["creating", "orphaned"]);
20595
+ ACTIVE_BACKGROUND_TASK_STATUSES3 = new Set(["pending", "running"]);
20469
20596
  });
20470
20597
 
20471
20598
  // packages/omo-opencode/src/features/team-mode/deps.ts
@@ -20506,7 +20633,7 @@ init_command_executor();
20506
20633
  init_src();
20507
20634
  // packages/omo-opencode/src/shared/file-reference-resolver.ts
20508
20635
  import { existsSync as existsSync10, readFileSync as readFileSync6, statSync as statSync4 } from "fs";
20509
- import { homedir as homedir7 } from "os";
20636
+ import { homedir as homedir8 } from "os";
20510
20637
  import { isAbsolute as isAbsolute4, posix, resolve as resolve7, win32 } from "path";
20511
20638
  init_logger2();
20512
20639
  var FILE_REFERENCE_PATTERN = /@([^\s@]+)/g;
@@ -20525,7 +20652,7 @@ function expandEnvironmentVariable(match, variableName) {
20525
20652
  return value;
20526
20653
  }
20527
20654
  if (variableName === "HOME") {
20528
- return homedir7();
20655
+ return homedir8();
20529
20656
  }
20530
20657
  return match;
20531
20658
  }
@@ -22025,7 +22152,7 @@ function extractRuntimeFallbackAutoRetrySignal(info) {
22025
22152
  }
22026
22153
  // packages/model-core/src/runtime-fallback-error-shape.ts
22027
22154
  var DEFAULT_RETRY_ON_ERRORS = [429, 500, 502, 503, 504];
22028
- function isRecord2(value) {
22155
+ function isRecord3(value) {
22029
22156
  return typeof value === "object" && value !== null;
22030
22157
  }
22031
22158
  function getRecordValue(record, key) {
@@ -22033,14 +22160,14 @@ function getRecordValue(record, key) {
22033
22160
  }
22034
22161
  function getNestedRecord(record, key) {
22035
22162
  const value = getRecordValue(record, key);
22036
- return isRecord2(value) ? value : undefined;
22163
+ return isRecord3(value) ? value : undefined;
22037
22164
  }
22038
22165
  function getRuntimeFallbackErrorMessage(error) {
22039
22166
  if (!error)
22040
22167
  return "";
22041
22168
  if (typeof error === "string")
22042
22169
  return error.toLowerCase();
22043
- if (!isRecord2(error)) {
22170
+ if (!isRecord3(error)) {
22044
22171
  try {
22045
22172
  return JSON.stringify(error).toLowerCase();
22046
22173
  } catch (error2) {
@@ -22076,7 +22203,7 @@ function getRuntimeFallbackErrorMessage(error) {
22076
22203
  }
22077
22204
  }
22078
22205
  function getRuntimeFallbackStatusCode(error, retryOnErrors) {
22079
- if (isRecord2(error)) {
22206
+ if (isRecord3(error)) {
22080
22207
  const topLevelStatusCode = getRecordValue(error, "statusCode");
22081
22208
  if (typeof topLevelStatusCode === "number")
22082
22209
  return topLevelStatusCode;
@@ -22084,7 +22211,7 @@ function getRuntimeFallbackStatusCode(error, retryOnErrors) {
22084
22211
  if (typeof topLevelStatus === "number")
22085
22212
  return topLevelStatus;
22086
22213
  }
22087
- const root = isRecord2(error) ? error : undefined;
22214
+ const root = isRecord3(error) ? error : undefined;
22088
22215
  const data = getNestedRecord(root, "data");
22089
22216
  const nestedError = getNestedRecord(root, "error");
22090
22217
  const cause = getNestedRecord(root, "cause");
@@ -22103,7 +22230,7 @@ function getRuntimeFallbackStatusCode(error, retryOnErrors) {
22103
22230
  return;
22104
22231
  }
22105
22232
  function getRuntimeFallbackErrorName(error) {
22106
- if (!isRecord2(error))
22233
+ if (!isRecord3(error))
22107
22234
  return;
22108
22235
  const data = getNestedRecord(error, "data");
22109
22236
  const nestedError = getNestedRecord(error, "error");
@@ -22118,7 +22245,7 @@ function getRuntimeFallbackErrorName(error) {
22118
22245
  return;
22119
22246
  }
22120
22247
  function getRuntimeFallbackRetryableSignal(error) {
22121
- if (!isRecord2(error))
22248
+ if (!isRecord3(error))
22122
22249
  return;
22123
22250
  const data = getNestedRecord(error, "data");
22124
22251
  const nestedError = getNestedRecord(error, "error");
@@ -22181,7 +22308,7 @@ function classifyRuntimeFallbackError(error) {
22181
22308
  if (errorName?.includes("providermodelnotfounderror") || errorName?.includes("modelnotfounderror") || errorName?.includes("unknownerror") && /model\s+not\s+found/i.test(message)) {
22182
22309
  return "model_not_found";
22183
22310
  }
22184
- 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)) {
22185
22312
  return "quota_exceeded";
22186
22313
  }
22187
22314
  return;
@@ -22207,6 +22334,14 @@ function isRuntimeFallbackRetryableError(error, retryOnErrors, options = {}) {
22207
22334
  }
22208
22335
  return RUNTIME_FALLBACK_RETRYABLE_ERROR_PATTERNS.some((pattern) => pattern.test(message));
22209
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
+ }
22210
22345
  // packages/model-core/src/runtime-fallback-model.ts
22211
22346
  function isRuntimeFallbackModelRecord(model) {
22212
22347
  if (typeof model !== "object" || model === null)
@@ -22324,7 +22459,7 @@ function getBundledModelCapabilitiesSnapshot(snapshotJson) {
22324
22459
  };
22325
22460
  }
22326
22461
  // packages/model-core/src/model-capabilities/runtime-model-readers.ts
22327
- function isRecord3(value) {
22462
+ function isRecord4(value) {
22328
22463
  return typeof value === "object" && value !== null && !Array.isArray(value);
22329
22464
  }
22330
22465
  function readNumber(value) {
@@ -22342,7 +22477,7 @@ function normalizeVariantKeys(value) {
22342
22477
  if (arrayVariants) {
22343
22478
  return arrayVariants.filter((v) => typeof v === "string").map((variant) => variant.toLowerCase());
22344
22479
  }
22345
- if (!isRecord3(value)) {
22480
+ if (!isRecord4(value)) {
22346
22481
  return;
22347
22482
  }
22348
22483
  const variants = Object.keys(value).map((variant) => variant.toLowerCase());
@@ -22353,7 +22488,7 @@ function readModalityKeys(value) {
22353
22488
  if (stringArray) {
22354
22489
  return stringArray.filter((entry) => typeof entry === "string").map((entry) => entry.toLowerCase());
22355
22490
  }
22356
- if (!isRecord3(value)) {
22491
+ if (!isRecord4(value)) {
22357
22492
  return;
22358
22493
  }
22359
22494
  const fromNested = Object.values(value).filter((v) => Array.isArray(v)).flat().filter((item) => typeof item === "string");
@@ -22364,7 +22499,7 @@ function readModalityKeys(value) {
22364
22499
  return enabled.length > 0 ? enabled : undefined;
22365
22500
  }
22366
22501
  function normalizeModalities(value) {
22367
- if (!isRecord3(value)) {
22502
+ if (!isRecord4(value)) {
22368
22503
  return;
22369
22504
  }
22370
22505
  const input = readModalityKeys(value.input);
@@ -22378,7 +22513,7 @@ function normalizeModalities(value) {
22378
22513
  };
22379
22514
  }
22380
22515
  function readRuntimeModelCapabilities(runtimeModel) {
22381
- return isRecord3(runtimeModel?.capabilities) ? runtimeModel.capabilities : undefined;
22516
+ return isRecord4(runtimeModel?.capabilities) ? runtimeModel.capabilities : undefined;
22382
22517
  }
22383
22518
  function readRuntimeModelBoolean(runtimeModel, keys) {
22384
22519
  const runtimeCapabilities = readRuntimeModelCapabilities(runtimeModel);
@@ -22395,7 +22530,7 @@ function readRuntimeModelBoolean(runtimeModel, keys) {
22395
22530
  return;
22396
22531
  }
22397
22532
  function readRuntimeModel(runtimeModel) {
22398
- return isRecord3(runtimeModel) ? runtimeModel : undefined;
22533
+ return isRecord4(runtimeModel) ? runtimeModel : undefined;
22399
22534
  }
22400
22535
  function readRuntimeModelVariants(runtimeModel) {
22401
22536
  const rootVariants = normalizeVariantKeys(runtimeModel?.variants);
@@ -22443,8 +22578,8 @@ function readRuntimeModelToolCallSupport(runtimeModel) {
22443
22578
  return readRuntimeModelBoolean(runtimeModel, ["toolCall", "tool_call", "toolcall"]);
22444
22579
  }
22445
22580
  function readRuntimeModelLimitOutput(runtimeModel) {
22446
- const limit = isRecord3(runtimeModel?.limit) ? runtimeModel.limit : readRuntimeModelCapabilities(runtimeModel)?.limit;
22447
- if (!isRecord3(limit)) {
22581
+ const limit = isRecord4(runtimeModel?.limit) ? runtimeModel.limit : readRuntimeModelCapabilities(runtimeModel)?.limit;
22582
+ if (!isRecord4(limit)) {
22448
22583
  return;
22449
22584
  }
22450
22585
  const output = readNumber(limit.output);
@@ -22561,7 +22696,7 @@ function resolveActualContextLimit(providerID, modelID, modelCacheState) {
22561
22696
  }
22562
22697
  // packages/model-core/src/model-capabilities-snapshot.ts
22563
22698
  var MODELS_DEV_SOURCE_URL = "https://models.dev/api.json";
22564
- function isRecord4(value) {
22699
+ function isRecord5(value) {
22565
22700
  return typeof value === "object" && value !== null && !Array.isArray(value);
22566
22701
  }
22567
22702
  function readBoolean(value) {
@@ -22581,7 +22716,7 @@ function readStringArray2(value) {
22581
22716
  return result.length > 0 ? result : undefined;
22582
22717
  }
22583
22718
  function normalizeSnapshotEntry(rawModelID, rawModel) {
22584
- if (!isRecord4(rawModel)) {
22719
+ if (!isRecord5(rawModel)) {
22585
22720
  return;
22586
22721
  }
22587
22722
  const id = readString(rawModel.id) ?? rawModelID;
@@ -22589,14 +22724,14 @@ function normalizeSnapshotEntry(rawModelID, rawModel) {
22589
22724
  const reasoning = readBoolean(rawModel.reasoning);
22590
22725
  const temperature = readBoolean(rawModel.temperature);
22591
22726
  const toolCall = readBoolean(rawModel.tool_call);
22592
- const rawModalities = isRecord4(rawModel.modalities) ? rawModel.modalities : undefined;
22727
+ const rawModalities = isRecord5(rawModel.modalities) ? rawModel.modalities : undefined;
22593
22728
  const modalitiesInput = readStringArray2(rawModalities?.input);
22594
22729
  const modalitiesOutput = readStringArray2(rawModalities?.output);
22595
22730
  const modalities = modalitiesInput || modalitiesOutput ? {
22596
22731
  ...modalitiesInput ? { input: modalitiesInput } : {},
22597
22732
  ...modalitiesOutput ? { output: modalitiesOutput } : {}
22598
22733
  } : undefined;
22599
- const rawLimit = isRecord4(rawModel.limit) ? rawModel.limit : undefined;
22734
+ const rawLimit = isRecord5(rawModel.limit) ? rawModel.limit : undefined;
22600
22735
  const limitContext = readNumber2(rawLimit?.context);
22601
22736
  const limitInput = readNumber2(rawLimit?.input);
22602
22737
  const limitOutput = readNumber2(rawLimit?.output);
@@ -22636,13 +22771,13 @@ function mergeSnapshotEntries(existing, incoming) {
22636
22771
  }
22637
22772
  function buildModelCapabilitiesSnapshotFromModelsDev(raw) {
22638
22773
  const models = {};
22639
- const providers = isRecord4(raw) ? raw : {};
22774
+ const providers = isRecord5(raw) ? raw : {};
22640
22775
  for (const providerValue of Object.values(providers)) {
22641
- if (!isRecord4(providerValue)) {
22776
+ if (!isRecord5(providerValue)) {
22642
22777
  continue;
22643
22778
  }
22644
22779
  const providerModels = providerValue.models;
22645
- if (!isRecord4(providerModels)) {
22780
+ if (!isRecord5(providerModels)) {
22646
22781
  continue;
22647
22782
  }
22648
22783
  for (const [rawModelID, rawModel] of Object.entries(providerModels)) {
@@ -23059,14 +23194,14 @@ function addConfigLoadError(error) {
23059
23194
  configLoadErrors.push(error);
23060
23195
  }
23061
23196
  // packages/omo-opencode/src/shared/claude-config-dir.ts
23062
- import { homedir as homedir9 } from "os";
23197
+ import { homedir as homedir10 } from "os";
23063
23198
  import { join as join14 } from "path";
23064
23199
  function getClaudeConfigDir() {
23065
23200
  const envConfigDir = process.env.CLAUDE_CONFIG_DIR;
23066
23201
  if (envConfigDir) {
23067
23202
  return envConfigDir;
23068
23203
  }
23069
- return join14(homedir9(), ".claude");
23204
+ return join14(homedir10(), ".claude");
23070
23205
  }
23071
23206
  // packages/omo-opencode/src/shared/jsonc-parser.ts
23072
23207
  init_src();
@@ -23911,7 +24046,7 @@ configureMigrationCategoryDefaults(DEFAULT_CATEGORIES);
23911
24046
  // packages/omo-opencode/src/shared/opencode-config-dir.ts
23912
24047
  init_plugin_identity();
23913
24048
  import { existsSync as existsSync11, realpathSync as realpathSync4 } from "fs";
23914
- import { homedir as homedir10 } from "os";
24049
+ import { homedir as homedir11 } from "os";
23915
24050
  import { join as join15, posix as posix2, resolve as resolve8, win32 as win322 } from "path";
23916
24051
  var TAURI_APP_IDENTIFIER = "ai.opencode.desktop";
23917
24052
  var TAURI_APP_IDENTIFIER_DEV = "ai.opencode.desktop.dev";
@@ -23924,14 +24059,14 @@ function getTauriConfigDir(identifier) {
23924
24059
  const platform = process.platform;
23925
24060
  switch (platform) {
23926
24061
  case "darwin":
23927
- return join15(homedir10(), "Library", "Application Support", identifier);
24062
+ return join15(homedir11(), "Library", "Application Support", identifier);
23928
24063
  case "win32": {
23929
- const appData = process.env.APPDATA || join15(homedir10(), "AppData", "Roaming");
24064
+ const appData = process.env.APPDATA || join15(homedir11(), "AppData", "Roaming");
23930
24065
  return win322.join(appData, identifier);
23931
24066
  }
23932
24067
  case "linux":
23933
24068
  default: {
23934
- const xdgConfig = process.env.XDG_CONFIG_HOME || join15(homedir10(), ".config");
24069
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join15(homedir11(), ".config");
23935
24070
  return join15(xdgConfig, identifier);
23936
24071
  }
23937
24072
  }
@@ -23975,7 +24110,7 @@ function getWslLinuxHomeDir(windowsConfigRoot) {
23975
24110
  function getCliDefaultConfigDir() {
23976
24111
  const envXdgConfig = process.env.XDG_CONFIG_HOME?.trim();
23977
24112
  const shouldIgnoreWindowsXdg = envXdgConfig !== undefined && envXdgConfig.length > 0 && isWslEnvironment() && isWindowsUserConfigRoot(envXdgConfig);
23978
- const xdgConfig = shouldIgnoreWindowsXdg ? posix2.join(getWslLinuxHomeDir(envXdgConfig) ?? "/home", ".config") : envXdgConfig || join15(homedir10(), ".config");
24113
+ const xdgConfig = shouldIgnoreWindowsXdg ? posix2.join(getWslLinuxHomeDir(envXdgConfig) ?? "/home", ".config") : envXdgConfig || join15(homedir11(), ".config");
23979
24114
  const configDir = isWslEnvironment() ? posix2.join(xdgConfig, "opencode") : join15(xdgConfig, "opencode");
23980
24115
  return resolveConfigPath(configDir);
23981
24116
  }
@@ -24028,12 +24163,12 @@ function getOpenCodeConfigPaths(options) {
24028
24163
  };
24029
24164
  }
24030
24165
  // packages/omo-opencode/src/shared/resolve-agent-definition-paths.ts
24031
- import { homedir as homedir11 } from "os";
24166
+ import { homedir as homedir12 } from "os";
24032
24167
  import { isAbsolute as isAbsolute5, join as join16, resolve as resolve9 } from "path";
24033
24168
  init_logger2();
24034
24169
  function resolveAgentDefinitionPaths(paths, baseDir, containmentDir) {
24035
24170
  return paths.flatMap((p) => {
24036
- const expanded = p.startsWith("~/") ? join16(homedir11(), p.slice(2)) : p;
24171
+ const expanded = p.startsWith("~/") ? join16(homedir12(), p.slice(2)) : p;
24037
24172
  const resolved = isAbsolute5(expanded) ? expanded : resolve9(baseDir, expanded);
24038
24173
  if (containmentDir !== null && !isWithinProject(resolved, containmentDir)) {
24039
24174
  log2(`agent_definitions path rejected (outside project boundary): ${p} -> ${resolved}`);
@@ -70666,7 +70801,7 @@ var log4 = logger4.log;
70666
70801
  var getLogFilePath2 = logger4.getLogFilePath;
70667
70802
 
70668
70803
  // packages/claude-code-compat-core/src/features/claude-code-plugin-loader/scope-filter.ts
70669
- import { homedir as homedir13 } from "os";
70804
+ import { homedir as homedir14 } from "os";
70670
70805
  import { join as join29 } from "path";
70671
70806
 
70672
70807
  // packages/claude-code-compat-core/src/shared/contains-path.ts
@@ -70675,10 +70810,10 @@ init_src();
70675
70810
  // packages/claude-code-compat-core/src/features/claude-code-plugin-loader/scope-filter.ts
70676
70811
  function expandTilde(inputPath) {
70677
70812
  if (inputPath === "~") {
70678
- return homedir13();
70813
+ return homedir14();
70679
70814
  }
70680
70815
  if (inputPath.startsWith("~/") || inputPath.startsWith("~\\")) {
70681
- return join29(homedir13(), inputPath.slice(2));
70816
+ return join29(homedir14(), inputPath.slice(2));
70682
70817
  }
70683
70818
  return inputPath;
70684
70819
  }
@@ -70693,13 +70828,13 @@ function shouldLoadPluginForCwd(installation, cwd = process.cwd()) {
70693
70828
  }
70694
70829
 
70695
70830
  // packages/claude-code-compat-core/src/features/claude-code-plugin-loader/discovery-paths.ts
70696
- import { homedir as homedir14 } from "os";
70831
+ import { homedir as homedir15 } from "os";
70697
70832
  import { join as join30 } from "path";
70698
70833
  function getPluginsBaseDir() {
70699
70834
  if (process.env.CLAUDE_PLUGINS_HOME) {
70700
70835
  return process.env.CLAUDE_PLUGINS_HOME;
70701
70836
  }
70702
- return join30(homedir14(), ".claude", "plugins");
70837
+ return join30(homedir15(), ".claude", "plugins");
70703
70838
  }
70704
70839
  function getInstalledPluginsPath(pluginsBaseDir) {
70705
70840
  return join30(pluginsBaseDir ?? getPluginsBaseDir(), "installed_plugins.json");
@@ -70708,7 +70843,7 @@ function getClaudeSettingsPath() {
70708
70843
  if (process.env.CLAUDE_SETTINGS_PATH) {
70709
70844
  return process.env.CLAUDE_SETTINGS_PATH;
70710
70845
  }
70711
- return join30(homedir14(), ".claude", "settings.json");
70846
+ return join30(homedir15(), ".claude", "settings.json");
70712
70847
  }
70713
70848
 
70714
70849
  // packages/claude-code-compat-core/src/features/claude-code-plugin-loader/installed-plugin-database.ts
@@ -74183,7 +74318,7 @@ async function runCommentChecker(input, options) {
74183
74318
  // packages/omo-opencode/src/hooks/comment-checker/downloader.ts
74184
74319
  import { existsSync as existsSync37, appendFileSync as appendFileSync3 } from "fs";
74185
74320
  import { join as join43 } from "path";
74186
- import { homedir as homedir15, tmpdir as tmpdir3 } from "os";
74321
+ import { homedir as homedir16, tmpdir as tmpdir3 } from "os";
74187
74322
  import { createRequire as createRequire3 } from "module";
74188
74323
  init_logger2();
74189
74324
  init_plugin_identity();
@@ -74207,11 +74342,11 @@ var PLATFORM_MAP = {
74207
74342
  function getCacheDir2() {
74208
74343
  if (process.platform === "win32") {
74209
74344
  const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
74210
- const base2 = localAppData || join43(homedir15(), "AppData", "Local");
74345
+ const base2 = localAppData || join43(homedir16(), "AppData", "Local");
74211
74346
  return join43(base2, CACHE_DIR_NAME, "bin");
74212
74347
  }
74213
74348
  const xdgCache = process.env.XDG_CACHE_HOME;
74214
- const base = xdgCache || join43(homedir15(), ".cache");
74349
+ const base = xdgCache || join43(homedir16(), ".cache");
74215
74350
  return join43(base, CACHE_DIR_NAME, "bin");
74216
74351
  }
74217
74352
  function getBinaryName() {
@@ -74823,7 +74958,7 @@ function isSameOrChildPath(childPath, parentPath) {
74823
74958
  }
74824
74959
  // packages/rules-engine/src/finder.ts
74825
74960
  import { existsSync as existsSync42, statSync as statSync6 } from "fs";
74826
- import { homedir as homedir16 } from "os";
74961
+ import { homedir as homedir17 } from "os";
74827
74962
  import { dirname as dirname13, isAbsolute as isAbsolute9, join as join48, relative as relative8, resolve as resolve14 } from "path";
74828
74963
 
74829
74964
  // packages/rules-engine/src/ordering.ts
@@ -74922,7 +75057,7 @@ function findRuleFiles(projectRoot, homeDir, currentFile, options, cache) {
74922
75057
  const seenRealPaths = new Set;
74923
75058
  addProjectRuleCandidates(effectiveProjectRoot, startDir, candidates, seenRealPaths, cache);
74924
75059
  addProjectSingleFileCandidates(effectiveProjectRoot, candidates, seenRealPaths);
74925
- addUserRuleCandidates(homeDir || homedir16(), skipClaudeUserRules, candidates, seenRealPaths, cache);
75060
+ addUserRuleCandidates(homeDir || homedir17(), skipClaudeUserRules, candidates, seenRealPaths, cache);
74926
75061
  const sorted = sortCandidates(candidates);
74927
75062
  cache?.set(cacheKey, sorted);
74928
75063
  return sorted;
@@ -80011,7 +80146,7 @@ function createSessionRuleScanCacheStore() {
80011
80146
  }
80012
80147
 
80013
80148
  // packages/omo-opencode/src/hooks/rules-injector/injection-processor.ts
80014
- import { homedir as homedir17 } from "os";
80149
+ import { homedir as homedir18 } from "os";
80015
80150
  // packages/omo-opencode/src/hooks/rules-injector/rule-file-finder.ts
80016
80151
  init_logger2();
80017
80152
  setSisyphusRuleDeprecationLogger(log2);
@@ -80157,7 +80292,7 @@ function createRuleInjectionProcessor(deps) {
80157
80292
  getSessionCache: getSessionCache3,
80158
80293
  getSessionRuleScanCache,
80159
80294
  ruleFinderOptions,
80160
- homedir: getHomeDir = homedir17,
80295
+ homedir: getHomeDir = homedir18,
80161
80296
  shouldApplyRule: shouldApplyRuleImpl = shouldApplyRule,
80162
80297
  isDuplicateByRealPath: isDuplicateByRealPathImpl = isDuplicateByRealPath,
80163
80298
  createContentHash: createContentHashImpl = createContentHash,
@@ -80683,7 +80818,7 @@ function getCachedVersion(options = {}) {
80683
80818
  // package.json
80684
80819
  var package_default = {
80685
80820
  name: "oh-my-opencode",
80686
- version: "4.12.0",
80821
+ version: "4.13.0",
80687
80822
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
80688
80823
  main: "./dist/index.js",
80689
80824
  types: "dist/index.d.ts",
@@ -80764,7 +80899,8 @@ var package_default = {
80764
80899
  "build:cli-node": "bun run script/build-cli-node.ts",
80765
80900
  "build:codex-install": "bun run script/build-codex-install.ts",
80766
80901
  "build:codex-plugin": "npm --prefix packages/omo-codex/plugin ci && bun run --cwd packages/omo-codex/plugin build",
80767
- "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",
80768
80904
  "build:lsp-tools-mcp": "npm --prefix packages/lsp-tools-mcp ci && npm --prefix packages/lsp-tools-mcp run build",
80769
80905
  "build:lsp-daemon": "npm --prefix packages/lsp-daemon ci && npm --prefix packages/lsp-daemon run build",
80770
80906
  "build:node-require-shim": "bun run script/patch-node-require-shim.ts",
@@ -80773,6 +80909,7 @@ var package_default = {
80773
80909
  "build:schema": "bun run script/build-schema.ts",
80774
80910
  "build:model-capabilities": "bun run script/build-model-capabilities.ts",
80775
80911
  clean: "rm -rf dist",
80912
+ prepack: "bun run build:materialize-frontend",
80776
80913
  prepare: "bun run build",
80777
80914
  postinstall: "node postinstall.mjs",
80778
80915
  prepublishOnly: "bun run clean && bun run build:lsp-tools-mcp && bun run build:lsp-daemon && bun run build",
@@ -80853,18 +80990,18 @@ var package_default = {
80853
80990
  typescript: "^6.0.3"
80854
80991
  },
80855
80992
  optionalDependencies: {
80856
- "oh-my-opencode-darwin-arm64": "4.12.0",
80857
- "oh-my-opencode-darwin-x64": "4.12.0",
80858
- "oh-my-opencode-darwin-x64-baseline": "4.12.0",
80859
- "oh-my-opencode-linux-arm64": "4.12.0",
80860
- "oh-my-opencode-linux-arm64-musl": "4.12.0",
80861
- "oh-my-opencode-linux-x64": "4.12.0",
80862
- "oh-my-opencode-linux-x64-baseline": "4.12.0",
80863
- "oh-my-opencode-linux-x64-musl": "4.12.0",
80864
- "oh-my-opencode-linux-x64-musl-baseline": "4.12.0",
80865
- "oh-my-opencode-windows-arm64": "4.12.0",
80866
- "oh-my-opencode-windows-x64": "4.12.0",
80867
- "oh-my-opencode-windows-x64-baseline": "4.12.0"
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"
80868
81005
  },
80869
81006
  overrides: {
80870
81007
  hono: "^4.12.18",
@@ -81855,7 +81992,7 @@ v${latestVersion} available. Restart OpenCode to apply.` : "OpenCode is now on S
81855
81992
  // packages/omo-opencode/src/hooks/codegraph-bootstrap/hook.ts
81856
81993
  init_src();
81857
81994
  import { existsSync as existsSync65 } from "fs";
81858
- import { homedir as homedir20 } from "os";
81995
+ import { homedir as homedir21 } from "os";
81859
81996
  import { join as join75 } from "path";
81860
81997
 
81861
81998
  // packages/omo-opencode/src/hooks/codegraph-bootstrap/command-runner.ts
@@ -82003,7 +82140,7 @@ function defaultSchedule(task) {
82003
82140
  timer.unref?.();
82004
82141
  }
82005
82142
  function defaultInstallDir2() {
82006
- return join75(homedir20(), ".omo", "codegraph");
82143
+ return join75(homedir21(), ".omo", "codegraph");
82007
82144
  }
82008
82145
  function provisionedBinFromInstallDir(installDir) {
82009
82146
  if (installDir === undefined)
@@ -82053,6 +82190,14 @@ async function resolveOrProvisionCommand(deps, config) {
82053
82190
  }
82054
82191
  async function runBootstrap(projectRoot, config, deps) {
82055
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
+ }
82056
82201
  const command = await resolveOrProvisionCommand(deps, config);
82057
82202
  if (command === null) {
82058
82203
  deps.log("[codegraph-bootstrap] CodeGraph unavailable; skipping bootstrap", { projectRoot });
@@ -82134,7 +82279,7 @@ function createCodegraphBootstrapHook(ctx, config, depsOverride = {}) {
82134
82279
  }
82135
82280
  // packages/omo-opencode/src/hooks/ast-grep-sg-provision/hook.ts
82136
82281
  init_src();
82137
- import { homedir as homedir21 } from "os";
82282
+ import { homedir as homedir22 } from "os";
82138
82283
  import { join as join76 } from "path";
82139
82284
  var provisionedTargets = new Set;
82140
82285
  function defaultSchedule2(task) {
@@ -82154,7 +82299,7 @@ async function runProvision(targetDir, deps) {
82154
82299
  }
82155
82300
  var defaultDeps5 = {
82156
82301
  findSgBinary: findSgBinarySync,
82157
- homeDir: homedir21,
82302
+ homeDir: homedir22,
82158
82303
  log: log2,
82159
82304
  provisionSgBinary,
82160
82305
  schedule: defaultSchedule2
@@ -90350,13 +90495,13 @@ function findSlashCommandPartIndex(parts) {
90350
90495
  return -1;
90351
90496
  }
90352
90497
  // packages/omo-opencode/src/hooks/auto-slash-command/executor.ts
90353
- import { dirname as dirname28 } from "path";
90498
+ import { dirname as dirname29 } from "path";
90354
90499
 
90355
90500
  // packages/omo-opencode/src/shared/command-executor/resolve-commands-in-text.ts
90356
90501
  init_resolve_commands_in_text();
90357
90502
  // packages/skills-loader-core/src/features/opencode-skill-loader/loader.ts
90358
90503
  import { join as join88 } from "path";
90359
- import { homedir as homedir25 } from "os";
90504
+ import { homedir as homedir26 } from "os";
90360
90505
 
90361
90506
  // packages/shared-skills/index.mjs
90362
90507
  import { fileURLToPath as fileURLToPath5 } from "url";
@@ -90365,21 +90510,21 @@ function sharedSkillsRootPath() {
90365
90510
  }
90366
90511
 
90367
90512
  // packages/skills-loader-core/src/shared/claude-config-dir.ts
90368
- import { homedir as homedir23 } from "os";
90513
+ import { homedir as homedir24 } from "os";
90369
90514
  import { join as join82 } from "path";
90370
90515
  function getClaudeConfigDir2() {
90371
90516
  const envConfigDir = process.env.CLAUDE_CONFIG_DIR;
90372
90517
  if (envConfigDir) {
90373
90518
  return envConfigDir;
90374
90519
  }
90375
- return join82(homedir23(), ".claude");
90520
+ return join82(homedir24(), ".claude");
90376
90521
  }
90377
90522
  // packages/skills-loader-core/src/shared/opencode-command-dirs.ts
90378
90523
  import { basename as basename13, dirname as dirname24, join as join84 } from "path";
90379
90524
 
90380
90525
  // packages/skills-loader-core/src/shared/opencode-config-dir.ts
90381
90526
  import { existsSync as existsSync70, realpathSync as realpathSync11 } from "fs";
90382
- import { homedir as homedir24 } from "os";
90527
+ import { homedir as homedir25 } from "os";
90383
90528
  import { join as join83, posix as posix4, resolve as resolve19, win32 as win325 } from "path";
90384
90529
 
90385
90530
  // packages/skills-loader-core/src/shared/plugin-identity.ts
@@ -90413,14 +90558,14 @@ function getTauriConfigDir2(identifier) {
90413
90558
  const platform2 = process.platform;
90414
90559
  switch (platform2) {
90415
90560
  case "darwin":
90416
- return join83(homedir24(), "Library", "Application Support", identifier);
90561
+ return join83(homedir25(), "Library", "Application Support", identifier);
90417
90562
  case "win32": {
90418
- const appData = process.env.APPDATA || join83(homedir24(), "AppData", "Roaming");
90563
+ const appData = process.env.APPDATA || join83(homedir25(), "AppData", "Roaming");
90419
90564
  return win325.join(appData, identifier);
90420
90565
  }
90421
90566
  case "linux":
90422
90567
  default: {
90423
- const xdgConfig = process.env.XDG_CONFIG_HOME || join83(homedir24(), ".config");
90568
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join83(homedir25(), ".config");
90424
90569
  return join83(xdgConfig, identifier);
90425
90570
  }
90426
90571
  }
@@ -90464,7 +90609,7 @@ function getWslLinuxHomeDir2(windowsConfigRoot) {
90464
90609
  function getCliDefaultConfigDir2() {
90465
90610
  const envXdgConfig = process.env.XDG_CONFIG_HOME?.trim();
90466
90611
  const shouldIgnoreWindowsXdg = envXdgConfig !== undefined && envXdgConfig.length > 0 && isWslEnvironment2() && isWindowsUserConfigRoot2(envXdgConfig);
90467
- const xdgConfig = shouldIgnoreWindowsXdg ? posix4.join(getWslLinuxHomeDir2(envXdgConfig) ?? "/home", ".config") : envXdgConfig || join83(homedir24(), ".config");
90612
+ const xdgConfig = shouldIgnoreWindowsXdg ? posix4.join(getWslLinuxHomeDir2(envXdgConfig) ?? "/home", ".config") : envXdgConfig || join83(homedir25(), ".config");
90468
90613
  const configDir = isWslEnvironment2() ? posix4.join(xdgConfig, "opencode") : join83(xdgConfig, "opencode");
90469
90614
  return resolveConfigPath2(configDir);
90470
90615
  }
@@ -91039,7 +91184,7 @@ async function loadProjectAgentsSkills(directory) {
91039
91184
  const allSkills = await Promise.all(agentsProjectSkillDirs.map((skillsDir) => loadSkillsFromDir({ skillsDir, scope: "project" })));
91040
91185
  return skillsToCommandDefinitionRecord(deduplicateSkillsByName(allSkills.flat()));
91041
91186
  }
91042
- async function loadGlobalAgentsSkills(homeDirectory = homedir25()) {
91187
+ async function loadGlobalAgentsSkills(homeDirectory = homedir26()) {
91043
91188
  const agentsGlobalDir = join88(homeDirectory, ".agents", "skills");
91044
91189
  const skills = await loadSkillsFromDir({ skillsDir: agentsGlobalDir, scope: "user" });
91045
91190
  return skillsToCommandDefinitionRecord(skills);
@@ -91137,11 +91282,19 @@ async function discoverProjectAgentsSkills(directory) {
91137
91282
  const allSkills = await Promise.all(agentsProjectSkillDirs.map((skillsDir) => loadSkillsFromDir({ skillsDir, scope: "project" })));
91138
91283
  return deduplicateSkillsByName(allSkills.flat());
91139
91284
  }
91140
- async function discoverGlobalAgentsSkills(homeDirectory = homedir25()) {
91285
+ async function discoverGlobalAgentsSkills(homeDirectory = homedir26()) {
91141
91286
  const agentsGlobalDir = join88(homeDirectory, ".agents", "skills");
91142
91287
  return loadSkillsFromDir({ skillsDir: agentsGlobalDir, scope: "user" });
91143
91288
  }
91144
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
+ }
91145
91298
  function builtinToLoadedSkill(builtin) {
91146
91299
  const definition = {
91147
91300
  name: builtin.name,
@@ -91160,22 +91313,23 @@ function builtinToLoadedSkill(builtin) {
91160
91313
  compatibility: builtin.compatibility,
91161
91314
  metadata: builtin.metadata,
91162
91315
  allowedTools: builtin.allowedTools,
91163
- mcpConfig: builtin.mcpConfig
91316
+ mcpConfig: builtin.mcpConfig,
91317
+ resolvedPath: resolveBuiltinSkillPath(builtin)
91164
91318
  };
91165
91319
  }
91166
91320
 
91167
91321
  // packages/skills-loader-core/src/features/opencode-skill-loader/merger/config-skill-entry-loader.ts
91168
91322
  init_src();
91169
- import { existsSync as existsSync72, readFileSync as readFileSync46 } from "fs";
91323
+ import { existsSync as existsSync73, readFileSync as readFileSync46 } from "fs";
91170
91324
  import { dirname as dirname26, isAbsolute as isAbsolute13, resolve as resolve22 } from "path";
91171
- import { homedir as homedir26 } from "os";
91325
+ import { homedir as homedir27 } from "os";
91172
91326
  function resolveFilePath5(from, configDir) {
91173
91327
  let filePath = from;
91174
91328
  if (filePath.startsWith("{file:") && filePath.endsWith("}")) {
91175
91329
  filePath = filePath.slice(6, -1);
91176
91330
  }
91177
91331
  if (filePath.startsWith("~/")) {
91178
- return resolve22(homedir26(), filePath.slice(2));
91332
+ return resolve22(homedir27(), filePath.slice(2));
91179
91333
  }
91180
91334
  if (isAbsolute13(filePath)) {
91181
91335
  return filePath;
@@ -91185,7 +91339,7 @@ function resolveFilePath5(from, configDir) {
91185
91339
  }
91186
91340
  function loadSkillFromFile(filePath) {
91187
91341
  try {
91188
- if (!existsSync72(filePath))
91342
+ if (!existsSync73(filePath))
91189
91343
  return null;
91190
91344
  const content = readFileSync46(filePath, "utf-8");
91191
91345
  const { data, body } = parseFrontmatter(content);
@@ -92054,7 +92208,7 @@ playwright-cli close
92054
92208
  };
92055
92209
  // packages/skills-loader-core/src/features/builtin-skills/skill-file-loader.ts
92056
92210
  import { readFileSync as readFileSync47 } from "fs";
92057
- import { join as join89 } from "path";
92211
+ import { join as join90 } from "path";
92058
92212
  init_src();
92059
92213
  function createSharedSkillTemplateLoader(readFile9 = readFileSync47, skillsRootPath = sharedSkillsRootPath()) {
92060
92214
  const cache2 = new Map;
@@ -92063,7 +92217,7 @@ function createSharedSkillTemplateLoader(readFile9 = readFileSync47, skillsRootP
92063
92217
  if (cached !== undefined)
92064
92218
  return cached;
92065
92219
  try {
92066
- const { body } = parseFrontmatter(readFile9(join89(skillsRootPath, skillName, "SKILL.md"), "utf8"));
92220
+ const { body } = parseFrontmatter(readFile9(join90(skillsRootPath, skillName, "SKILL.md"), "utf8"));
92067
92221
  cache2.set(skillName, body);
92068
92222
  return body;
92069
92223
  } catch (error) {
@@ -93200,6 +93354,9 @@ var gitMasterSkill = {
93200
93354
  template: GIT_MASTER_TEMPLATE
93201
93355
  };
93202
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));
93203
93360
  var devBrowserSkill = {
93204
93361
  name: "dev-browser",
93205
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.",
@@ -93416,7 +93573,8 @@ console.log({
93416
93573
 
93417
93574
  await client.disconnect();
93418
93575
  EOF
93419
- \`\`\``
93576
+ \`\`\``,
93577
+ resolvedPath: join91(CURRENT_DIR, "..", "dev-browser")
93420
93578
  };
93421
93579
  // packages/skills-loader-core/src/features/builtin-skills/skills/review-work.ts
93422
93580
  var reviewWorkSkill = {
@@ -94416,23 +94574,23 @@ function isDisabledSkillName(name, disabledSkills) {
94416
94574
  init_src();
94417
94575
  var import_picomatch2 = __toESM(require_picomatch2(), 1);
94418
94576
  import * as fs20 from "fs/promises";
94419
- import { homedir as homedir27 } from "os";
94420
- import { dirname as dirname27, extname as extname2, isAbsolute as isAbsolute14, join as join90, relative as relative12 } from "path";
94577
+ import { homedir as homedir28 } from "os";
94578
+ import { dirname as dirname28, extname as extname2, isAbsolute as isAbsolute14, join as join92, relative as relative12 } from "path";
94421
94579
  var MAX_RECURSIVE_DEPTH = 10;
94422
94580
  function isHttpUrl(path17) {
94423
94581
  return path17.startsWith("http://") || path17.startsWith("https://");
94424
94582
  }
94425
94583
  function toAbsolutePath(path17, configDir) {
94426
94584
  if (path17 === "~") {
94427
- return homedir27();
94585
+ return homedir28();
94428
94586
  }
94429
94587
  if (path17.startsWith("~/")) {
94430
- return join90(homedir27(), path17.slice(2));
94588
+ return join92(homedir28(), path17.slice(2));
94431
94589
  }
94432
94590
  if (isAbsolute14(path17)) {
94433
94591
  return path17;
94434
94592
  }
94435
- return join90(configDir, path17);
94593
+ return join92(configDir, path17);
94436
94594
  }
94437
94595
  function isMarkdownPath(path17) {
94438
94596
  return extname2(path17).toLowerCase() === ".md";
@@ -94472,13 +94630,13 @@ async function loadSourcePath(options) {
94472
94630
  return [];
94473
94631
  const loaded = await loadSkillFromPath({
94474
94632
  skillPath: realSourcePath,
94475
- resolvedPath: dirname27(realSourcePath),
94633
+ resolvedPath: dirname28(realSourcePath),
94476
94634
  defaultName: inferSkillNameFromFileName(realSourcePath),
94477
94635
  scope: "config"
94478
94636
  });
94479
94637
  if (!loaded)
94480
94638
  return [];
94481
- return filterByGlob([loaded], dirname27(realSourcePath), options.globPattern);
94639
+ return filterByGlob([loaded], dirname28(realSourcePath), options.globPattern);
94482
94640
  }
94483
94641
  if (!stat5.isDirectory())
94484
94642
  return [];
@@ -94559,8 +94717,8 @@ function readOpencodeConfigSkills(directory) {
94559
94717
  return { paths, urls };
94560
94718
  }
94561
94719
  // packages/omo-opencode/src/tools/slashcommand/command-discovery.ts
94562
- import { existsSync as existsSync74, readdirSync as readdirSync19, readFileSync as readFileSync50, statSync as statSync10 } from "fs";
94563
- 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";
94564
94722
 
94565
94723
  // packages/omo-opencode/src/tools/slashcommand/command-discovery-deps.ts
94566
94724
  init_frontmatter2();
@@ -96120,7 +96278,7 @@ function loadBuiltinCommands(disabledCommands, options) {
96120
96278
  // packages/omo-opencode/src/tools/slashcommand/command-discovery.ts
96121
96279
  var NESTED_COMMAND_SEPARATOR = "/";
96122
96280
  function discoverCommandsFromDir(commandsDir, scope, prefix = "") {
96123
- if (!existsSync74(commandsDir))
96281
+ if (!existsSync75(commandsDir))
96124
96282
  return [];
96125
96283
  if (!statSync10(commandsDir).isDirectory()) {
96126
96284
  log2(`[command-discovery] Skipping non-directory path: ${commandsDir}`);
@@ -96135,12 +96293,12 @@ function discoverCommandsFromDir(commandsDir, scope, prefix = "") {
96135
96293
  if (entry.name.startsWith("."))
96136
96294
  continue;
96137
96295
  const nestedPrefix = prefix ? `${prefix}${NESTED_COMMAND_SEPARATOR}${entry.name}` : entry.name;
96138
- commands.push(...discoverCommandsFromDir(join92(commandsDir, entry.name), scope, nestedPrefix));
96296
+ commands.push(...discoverCommandsFromDir(join94(commandsDir, entry.name), scope, nestedPrefix));
96139
96297
  continue;
96140
96298
  }
96141
96299
  if (!isMarkdownFile(entry))
96142
96300
  continue;
96143
- const commandPath = join92(commandsDir, entry.name);
96301
+ const commandPath = join94(commandsDir, entry.name);
96144
96302
  const baseCommandName = basename15(entry.name, ".md");
96145
96303
  const commandName = prefix ? `${prefix}${NESTED_COMMAND_SEPARATOR}${baseCommandName}` : baseCommandName;
96146
96304
  try {
@@ -96199,8 +96357,8 @@ function deduplicateCommandInfosByName(commands) {
96199
96357
  return deduplicatedCommands;
96200
96358
  }
96201
96359
  function discoverCommandsSync(directory, options) {
96202
- const userCommandsDir = join92(getClaudeConfigDir(), "commands");
96203
- const projectCommandsDir = join92(directory ?? process.cwd(), ".claude", "commands");
96360
+ const userCommandsDir = join94(getClaudeConfigDir(), "commands");
96361
+ const projectCommandsDir = join94(directory ?? process.cwd(), ".claude", "commands");
96204
96362
  const opencodeGlobalDirs = getOpenCodeCommandDirs({ binary: "opencode" });
96205
96363
  const opencodeProjectDirs = findProjectOpencodeCommandDirs(directory ?? process.cwd());
96206
96364
  const userCommands = discoverCommandsFromDir(userCommandsDir, "user");
@@ -96304,7 +96462,7 @@ async function formatCommandTemplate(cmd, args) {
96304
96462
  if (!content && cmd.lazyContentLoader) {
96305
96463
  content = await cmd.lazyContentLoader.load();
96306
96464
  }
96307
- const commandDir = cmd.path ? dirname28(cmd.path) : process.cwd();
96465
+ const commandDir = cmd.path ? dirname29(cmd.path) : process.cwd();
96308
96466
  const withFileRefs = await resolveFileReferencesInText(content, commandDir);
96309
96467
  const resolvedContent = await resolveCommandsInText(withFileRefs);
96310
96468
  const resolvedArguments = args;
@@ -96688,7 +96846,7 @@ var NOTEPAD_DIR = "notepads";
96688
96846
  var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
96689
96847
  var PROMETHEUS_PLANS_DIR = ".omo/plans";
96690
96848
  // packages/boulder-state/src/top-level-task.ts
96691
- import { existsSync as existsSync75, readFileSync as readFileSync51 } from "fs";
96849
+ import { existsSync as existsSync76, readFileSync as readFileSync51 } from "fs";
96692
96850
  var TODO_HEADING_PATTERN = /^##\s+TODOs\b/i;
96693
96851
  var FINAL_VERIFICATION_HEADING_PATTERN = /^##\s+Final Verification Wave\b/i;
96694
96852
  var SECOND_LEVEL_HEADING_PATTERN = /^##\s+/;
@@ -96711,7 +96869,7 @@ function buildTaskRef(section, taskLabel) {
96711
96869
  };
96712
96870
  }
96713
96871
  function readCurrentTopLevelTask(planPath) {
96714
- if (!existsSync75(planPath)) {
96872
+ if (!existsSync76(planPath)) {
96715
96873
  return null;
96716
96874
  }
96717
96875
  try {
@@ -96740,10 +96898,10 @@ function readCurrentTopLevelTask(planPath) {
96740
96898
  }
96741
96899
  }
96742
96900
  // packages/boulder-state/src/storage/path.ts
96743
- import { existsSync as existsSync76 } from "fs";
96744
- 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";
96745
96903
  function getBoulderFilePath(directory) {
96746
- return join93(directory, BOULDER_DIR, BOULDER_FILE);
96904
+ return join95(directory, BOULDER_DIR, BOULDER_FILE);
96747
96905
  }
96748
96906
  function resolveTrackedPath(baseDirectory, trackedPath) {
96749
96907
  return isAbsolute15(trackedPath) ? resolve23(trackedPath) : resolve23(baseDirectory, trackedPath);
@@ -96761,14 +96919,14 @@ function resolveBoulderPlanPath(directory, state3) {
96761
96919
  }
96762
96920
  const absoluteWorktreePath = resolveTrackedPath(directory, worktreePath);
96763
96921
  const worktreePlanPath = resolve23(absoluteWorktreePath, relativePlanPath);
96764
- return existsSync76(worktreePlanPath) ? worktreePlanPath : absolutePlanPath;
96922
+ return existsSync77(worktreePlanPath) ? worktreePlanPath : absolutePlanPath;
96765
96923
  }
96766
96924
  function resolveBoulderPlanPathForWork(directory, work) {
96767
96925
  return resolveBoulderPlanPath(directory, work);
96768
96926
  }
96769
96927
  // packages/boulder-state/src/storage/plan-progress.ts
96770
- import { existsSync as existsSync77, readFileSync as readFileSync52, readdirSync as readdirSync20, statSync as statSync11 } from "fs";
96771
- 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";
96772
96930
  var TODO_HEADING_PATTERN2 = /^##\s+TODOs\b/i;
96773
96931
  var FINAL_VERIFICATION_HEADING_PATTERN2 = /^##\s+Final Verification Wave\b/i;
96774
96932
  var SECOND_LEVEL_HEADING_PATTERN2 = /^##\s+/;
@@ -96781,11 +96939,11 @@ var PROMETHEUS_PLAN_DIRS = [PROMETHEUS_PLANS_DIR, LEGACY_PROMETHEUS_PLANS_DIR];
96781
96939
  function findPrometheusPlans(directory) {
96782
96940
  try {
96783
96941
  return PROMETHEUS_PLAN_DIRS.flatMap((planDir) => {
96784
- const plansDir = join94(directory, planDir);
96785
- if (!existsSync77(plansDir)) {
96942
+ const plansDir = join96(directory, planDir);
96943
+ if (!existsSync78(plansDir)) {
96786
96944
  return [];
96787
96945
  }
96788
- 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));
96789
96947
  }).sort((left, right) => statSync11(right).mtimeMs - statSync11(left).mtimeMs);
96790
96948
  } catch {
96791
96949
  return [];
@@ -96795,7 +96953,7 @@ function getPlanName(planPath) {
96795
96953
  return basename16(planPath, ".md");
96796
96954
  }
96797
96955
  function getPlanProgress(planPath) {
96798
- if (!existsSync77(planPath)) {
96956
+ if (!existsSync78(planPath)) {
96799
96957
  return { total: 0, completed: 0, isComplete: false };
96800
96958
  }
96801
96959
  try {
@@ -96929,10 +97087,10 @@ function selectMirrorWork(state3) {
96929
97087
  return sorted[0] ?? null;
96930
97088
  }
96931
97089
  // packages/boulder-state/src/storage/read-state.ts
96932
- import { existsSync as existsSync78, readFileSync as readFileSync53 } from "fs";
97090
+ import { existsSync as existsSync79, readFileSync as readFileSync53 } from "fs";
96933
97091
  function readBoulderState(directory) {
96934
97092
  const filePath = getBoulderFilePath(directory);
96935
- if (!existsSync78(filePath)) {
97093
+ if (!existsSync79(filePath)) {
96936
97094
  return null;
96937
97095
  }
96938
97096
  try {
@@ -97085,15 +97243,15 @@ function getTaskSessionState(directory, taskKey) {
97085
97243
  return state3.task_sessions[taskKey] ?? null;
97086
97244
  }
97087
97245
  // packages/boulder-state/src/storage/write-state.ts
97088
- import { existsSync as existsSync79, mkdirSync as mkdirSync18, unlinkSync as unlinkSync13, writeFileSync as writeFileSync17 } from "fs";
97089
- 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";
97090
97248
  function writeBoulderState(directory, state3) {
97091
97249
  const filePath = getBoulderFilePath(directory);
97092
97250
  try {
97093
- const dir = dirname29(filePath);
97094
- if (!existsSync79(dir)) {
97251
+ const dir = dirname30(filePath);
97252
+ if (!existsSync80(dir)) {
97095
97253
  mkdirSync18(dir, { recursive: true });
97096
- writeFileSync17(join95(dir, ".gitignore"), ["*", "!/rules/", "!/rules/**", ""].join(`
97254
+ writeFileSync17(join97(dir, ".gitignore"), ["*", "!/rules/", "!/rules/**", ""].join(`
97097
97255
  `), "utf-8");
97098
97256
  }
97099
97257
  const stateToWrite = { ...state3 };
@@ -97129,7 +97287,7 @@ function writeBoulderState(directory, state3) {
97129
97287
  function clearBoulderState(directory) {
97130
97288
  const filePath = getBoulderFilePath(directory);
97131
97289
  try {
97132
- if (existsSync79(filePath)) {
97290
+ if (existsSync80(filePath)) {
97133
97291
  unlinkSync13(filePath);
97134
97292
  }
97135
97293
  return true;
@@ -97625,11 +97783,11 @@ init_logger2();
97625
97783
 
97626
97784
  // packages/omo-opencode/src/hooks/start-work/worktree-detector.ts
97627
97785
  import { execFileSync as execFileSync5 } from "child_process";
97628
- import { existsSync as existsSync80, realpathSync as realpathSync13 } from "fs";
97786
+ import { existsSync as existsSync81, realpathSync as realpathSync13 } from "fs";
97629
97787
  import { resolve as resolve25, win32 as win328 } from "path";
97630
97788
  function normalizePath5(path18) {
97631
97789
  const resolvedPath = process.platform !== "win32" && win328.isAbsolute(path18) ? path18 : resolve25(path18);
97632
- if (!existsSync80(resolvedPath)) {
97790
+ if (!existsSync81(resolvedPath)) {
97633
97791
  return resolvedPath;
97634
97792
  }
97635
97793
  try {
@@ -98925,7 +99083,7 @@ async function isSessionInBoulderLineage(input) {
98925
99083
 
98926
99084
  // packages/omo-opencode/src/hooks/atlas/session-last-agent.ts
98927
99085
  import { readFileSync as readFileSync54, readdirSync as readdirSync21 } from "fs";
98928
- import { join as join96 } from "path";
99086
+ import { join as join98 } from "path";
98929
99087
  var defaultSessionLastAgentDeps = {
98930
99088
  getMessageDir,
98931
99089
  isSqliteBackend,
@@ -98985,7 +99143,7 @@ async function getLastAgentFromSession(sessionID, client3, deps = {}) {
98985
99143
  try {
98986
99144
  const messages = readdirSync21(messageDir).filter((fileName) => fileName.endsWith(".json")).map((fileName) => {
98987
99145
  try {
98988
- const content = readFileSync54(join96(messageDir, fileName), "utf-8");
99146
+ const content = readFileSync54(join98(messageDir, fileName), "utf-8");
98989
99147
  const parsed = JSON.parse(content);
98990
99148
  return {
98991
99149
  fileName,
@@ -99528,7 +99686,7 @@ function isOmoPath(filePath) {
99528
99686
  }
99529
99687
 
99530
99688
  // packages/omo-opencode/src/hooks/atlas/tool-execute-after-plan-tasks.ts
99531
- import { existsSync as existsSync81, readFileSync as readFileSync55 } from "fs";
99689
+ import { existsSync as existsSync82, readFileSync as readFileSync55 } from "fs";
99532
99690
  var TODO_HEADING_PATTERN3 = /^##\s+TODOs\b/i;
99533
99691
  var FINAL_VERIFICATION_HEADING_PATTERN3 = /^##\s+Final Verification Wave\b/i;
99534
99692
  var SECOND_LEVEL_HEADING_PATTERN3 = /^##\s+/;
@@ -99536,7 +99694,7 @@ var CHECKED_CHECKBOX_PATTERN2 = /^(\s*)[-*]\s*\[[xX]\]\s*(.+)$/;
99536
99694
  var TODO_TASK_PATTERN3 = /^(\d+)\.\s+(.+)$/;
99537
99695
  var FINAL_WAVE_TASK_PATTERN3 = /^(F\d+)\.\s+(.+)$/i;
99538
99696
  function isTrackedTaskChecked(planPath, taskKey) {
99539
- if (!existsSync81(planPath)) {
99697
+ if (!existsSync82(planPath)) {
99540
99698
  return false;
99541
99699
  }
99542
99700
  const [section, label] = taskKey.split(":");
@@ -99590,7 +99748,7 @@ function parseCheckedTopLevelTaskKeys(planContent) {
99590
99748
  return checkedKeys;
99591
99749
  }
99592
99750
  function readCheckedTaskKeysFromPlan(planPath) {
99593
- if (!existsSync81(planPath)) {
99751
+ if (!existsSync82(planPath)) {
99594
99752
  return new Set;
99595
99753
  }
99596
99754
  try {
@@ -99769,7 +99927,7 @@ async function resolveFallbackTrackedSessionId(input) {
99769
99927
  }
99770
99928
 
99771
99929
  // packages/omo-opencode/src/hooks/atlas/final-wave-plan-state.ts
99772
- import { existsSync as existsSync82, readFileSync as readFileSync56 } from "fs";
99930
+ import { existsSync as existsSync83, readFileSync as readFileSync56 } from "fs";
99773
99931
  var TODO_HEADING_PATTERN4 = /^##\s+TODOs\b/i;
99774
99932
  var FINAL_VERIFICATION_HEADING_PATTERN4 = /^##\s+Final Verification Wave\b/i;
99775
99933
  var SECOND_LEVEL_HEADING_PATTERN4 = /^##\s+/;
@@ -99777,7 +99935,7 @@ var UNCHECKED_CHECKBOX_PATTERN3 = /^\s*[-*]\s*\[\s*\]\s*(.+)$/;
99777
99935
  var TODO_TASK_PATTERN4 = /^\d+\./;
99778
99936
  var FINAL_WAVE_TASK_PATTERN4 = /^F\d+\./i;
99779
99937
  function readFinalWavePlanState(planPath) {
99780
- if (!existsSync82(planPath)) {
99938
+ if (!existsSync83(planPath)) {
99781
99939
  return null;
99782
99940
  }
99783
99941
  try {
@@ -100224,7 +100382,7 @@ function createToolExecuteAfterHandler2(input) {
100224
100382
 
100225
100383
  // packages/omo-opencode/src/hooks/atlas/tool-execute-before.ts
100226
100384
  init_logger2();
100227
- import { existsSync as existsSync83, readFileSync as readFileSync57 } from "fs";
100385
+ import { existsSync as existsSync84, readFileSync as readFileSync57 } from "fs";
100228
100386
  import { resolve as resolve27 } from "path";
100229
100387
  var TASK_SECTION_HEADER_PATTERN = /^##\s*1\.\s*TASK\s*$/i;
100230
100388
  var TODO_TASK_LINE_PATTERN = /^(?:[-*]\s*\[\s*\]\s*)?(\d+)\.\s+(.+)$/;
@@ -100285,7 +100443,7 @@ function createToolExecuteBeforeHandler2(input) {
100285
100443
  const planPath = sessionWork ? resolveBoulderPlanPathForWork(ctx.directory, sessionWork) : state3 ? resolveBoulderPlanPath(ctx.directory, state3) : null;
100286
100444
  if (planPath && resolve27(filePath) === resolve27(planPath) && pendingPlanSnapshots) {
100287
100445
  try {
100288
- if (existsSync83(planPath)) {
100446
+ if (existsSync84(planPath)) {
100289
100447
  pendingPlanSnapshots.set(toolInput.callID, readFileSync57(planPath, "utf-8"));
100290
100448
  }
100291
100449
  } catch (error) {
@@ -100754,7 +100912,7 @@ function buildRetryGuidance(errorInfo) {
100754
100912
  if (!pattern) {
100755
100913
  return `[task ERROR] Fix the error and retry with correct parameters.`;
100756
100914
  }
100757
- let guidance = `
100915
+ let guidance2 = `
100758
100916
  [task CALL FAILED - IMMEDIATE RETRY REQUIRED]
100759
100917
 
100760
100918
  **Error Type**: ${errorInfo.errorType}
@@ -100762,11 +100920,11 @@ function buildRetryGuidance(errorInfo) {
100762
100920
  `;
100763
100921
  const availableList = extractAvailableList(errorInfo.originalOutput);
100764
100922
  if (availableList) {
100765
- guidance += `
100923
+ guidance2 += `
100766
100924
  **Available Options**: ${availableList}
100767
100925
  `;
100768
100926
  }
100769
- guidance += `
100927
+ guidance2 += `
100770
100928
  **Action**: Retry task NOW with corrected parameters.
100771
100929
 
100772
100930
  Example of CORRECT call:
@@ -100780,7 +100938,7 @@ function buildRetryGuidance(errorInfo) {
100780
100938
  )
100781
100939
  \`\`\`
100782
100940
  `;
100783
- return guidance;
100941
+ return guidance2;
100784
100942
  }
100785
100943
  // packages/omo-opencode/src/hooks/delegate-task-retry/hook.ts
100786
100944
  function createDelegateTaskRetryHook(_ctx) {
@@ -100792,9 +100950,9 @@ function createDelegateTaskRetryHook(_ctx) {
100792
100950
  return;
100793
100951
  const errorInfo = detectDelegateTaskError(output.output);
100794
100952
  if (errorInfo) {
100795
- const guidance = buildRetryGuidance(errorInfo);
100953
+ const guidance2 = buildRetryGuidance(errorInfo);
100796
100954
  output.output += `
100797
- ${guidance}`;
100955
+ ${guidance2}`;
100798
100956
  }
100799
100957
  }
100800
100958
  };
@@ -102358,7 +102516,8 @@ var DEFAULT_CONFIG2 = {
102358
102516
  max_fallback_attempts: 3,
102359
102517
  cooldown_seconds: 60,
102360
102518
  timeout_seconds: 30,
102361
- notify_on_fallback: true
102519
+ notify_on_fallback: true,
102520
+ restore_primary_after_cooldown: false
102362
102521
  };
102363
102522
  var RETRYABLE_ERROR_PATTERNS = [
102364
102523
  /rate.?limit/i,
@@ -102395,7 +102554,7 @@ init_logger2();
102395
102554
  function createAbortSessionRequest(deps) {
102396
102555
  const { ctx } = deps;
102397
102556
  return async (sessionID, source) => {
102398
- 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") {
102399
102558
  deps.internallyAbortedSessions.add(sessionID);
102400
102559
  deps.sessionLastAccess.set(sessionID, Date.now());
102401
102560
  }
@@ -102654,7 +102813,7 @@ function createAutoRetryDispatcher(deps, scheduleSessionFallbackTimeout, clearSe
102654
102813
  return async (sessionID, newModel, resolvedAgent, source) => {
102655
102814
  if (sessionRetryInFlight.has(sessionID)) {
102656
102815
  log2(`[${HOOK_NAME11}] Retry already in flight, skipping (${source})`, { sessionID });
102657
- return;
102816
+ return { accepted: false, status: "blocked", reason: "retry already in flight" };
102658
102817
  }
102659
102818
  const agentSettings = resolvedAgent ? pluginConfig?.agents?.[resolvedAgent] : undefined;
102660
102819
  const retryModelPayload = buildRetryModelPayload(newModel, agentSettings ? {
@@ -102670,7 +102829,7 @@ function createAutoRetryDispatcher(deps, scheduleSessionFallbackTimeout, clearSe
102670
102829
  if (state3) {
102671
102830
  state3.pendingFallbackPromptMayHaveBeenAccepted = false;
102672
102831
  }
102673
- return;
102832
+ return { accepted: false, status: "invalid-model", reason: "missing provider prefix" };
102674
102833
  }
102675
102834
  const hadAwaitingFallbackResult = sessionAwaitingFallbackResult.has(sessionID);
102676
102835
  const previousPendingFallbackModel = sessionStates.get(sessionID)?.pendingFallbackModel;
@@ -102678,6 +102837,7 @@ function createAutoRetryDispatcher(deps, scheduleSessionFallbackTimeout, clearSe
102678
102837
  sessionRetryInFlight.add(sessionID);
102679
102838
  let retryDispatched = false;
102680
102839
  let retryMayHaveBeenAccepted = false;
102840
+ let acceptedStatus = "dispatched";
102681
102841
  try {
102682
102842
  const messagesResp = await ctx.client.session.messages({
102683
102843
  path: { id: sessionID },
@@ -102732,6 +102892,7 @@ function createAutoRetryDispatcher(deps, scheduleSessionFallbackTimeout, clearSe
102732
102892
  sessionID
102733
102893
  });
102734
102894
  promptResult = await dispatchRetryPrompt(`runtime-fallback:${source}:active-queue`);
102895
+ acceptedStatus = "queued";
102735
102896
  }
102736
102897
  if (promptResult.status === "failed") {
102737
102898
  if (isAmbiguousPostDispatchPromptFailure(promptResult)) {
@@ -102740,6 +102901,7 @@ function createAutoRetryDispatcher(deps, scheduleSessionFallbackTimeout, clearSe
102740
102901
  sessionID,
102741
102902
  error: String(promptResult.error)
102742
102903
  });
102904
+ return { accepted: true, status: "possibly-accepted" };
102743
102905
  }
102744
102906
  throw promptResult.error;
102745
102907
  }
@@ -102766,6 +102928,7 @@ function createAutoRetryDispatcher(deps, scheduleSessionFallbackTimeout, clearSe
102766
102928
  sessionID,
102767
102929
  error: String(reservedResult.error)
102768
102930
  });
102931
+ return { accepted: true, status: "possibly-accepted" };
102769
102932
  }
102770
102933
  throw reservedResult.error;
102771
102934
  }
@@ -102774,14 +102937,15 @@ function createAutoRetryDispatcher(deps, scheduleSessionFallbackTimeout, clearSe
102774
102937
  sessionID,
102775
102938
  status: reservedResult.status
102776
102939
  });
102777
- return;
102940
+ return { accepted: false, status: "blocked", reason: `prompt gate returned ${reservedResult.status}` };
102778
102941
  }
102942
+ acceptedStatus = "queued";
102779
102943
  } else if (!isInternalPromptDispatchAccepted(promptResult)) {
102780
102944
  log2(`[${HOOK_NAME11}] Auto-retry skipped by promptAsync gate (${source})`, {
102781
102945
  sessionID,
102782
102946
  status: promptResult.status
102783
102947
  });
102784
- return;
102948
+ return { accepted: false, status: "blocked", reason: `prompt gate returned ${promptResult.status}` };
102785
102949
  }
102786
102950
  sessionAwaitingFallbackResult.add(sessionID);
102787
102951
  if (hadAwaitingFallbackResult) {
@@ -102792,12 +102956,14 @@ function createAutoRetryDispatcher(deps, scheduleSessionFallbackTimeout, clearSe
102792
102956
  state3.pendingFallbackPromptMayHaveBeenAccepted = false;
102793
102957
  }
102794
102958
  retryDispatched = true;
102959
+ return { accepted: true, status: acceptedStatus };
102795
102960
  } catch (retryError) {
102796
102961
  if (!(retryError instanceof Error)) {
102797
102962
  log2(`[${HOOK_NAME11}] Auto-retry failed (${source})`, { sessionID, error: String(retryError) });
102798
- return;
102963
+ return { accepted: false, status: "failed", reason: String(retryError) };
102799
102964
  }
102800
102965
  log2(`[${HOOK_NAME11}] Auto-retry failed (${source})`, { sessionID, error: String(retryError) });
102966
+ return { accepted: false, status: "failed", reason: retryError.message };
102801
102967
  } finally {
102802
102968
  sessionRetryInFlight.delete(sessionID);
102803
102969
  if (retryMayHaveBeenAccepted) {
@@ -102949,6 +103115,28 @@ function prepareFallback(sessionID, state3, fallbackModels, config) {
102949
103115
  return { success: true, newModel: nextModel };
102950
103116
  }
102951
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
+
102952
103140
  // packages/omo-opencode/src/hooks/runtime-fallback/auto-retry-timeout.ts
102953
103141
  function createFallbackTimeoutHelpers(deps, abortSessionRequest, autoRetryWithFallback) {
102954
103142
  const {
@@ -102990,6 +103178,7 @@ function createFallbackTimeoutHelpers(deps, abortSessionRequest, autoRetryWithFa
102990
103178
  state3.pendingFallbackModel = undefined;
102991
103179
  }
102992
103180
  state3.pendingFallbackPromptMayHaveBeenAccepted = false;
103181
+ const stateSnapshot = snapshotFallbackState(state3);
102993
103182
  const fallbackModels = getFallbackModelsForSession(sessionID, resolvedAgent, pluginConfig);
102994
103183
  if (fallbackModels.length === 0)
102995
103184
  return;
@@ -103000,7 +103189,18 @@ function createFallbackTimeoutHelpers(deps, abortSessionRequest, autoRetryWithFa
103000
103189
  });
103001
103190
  const result = prepareFallback(sessionID, state3, fallbackModels, config);
103002
103191
  if (result.success && result.newModel) {
103003
- 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
+ }
103004
103204
  }
103005
103205
  }, timeoutMs);
103006
103206
  sessionFallbackTimeouts.set(sessionID, timer);
@@ -103090,7 +103290,7 @@ function createChatMessageHandler2(deps) {
103090
103290
  sessionStates.set(sessionID, state3);
103091
103291
  return;
103092
103292
  }
103093
- 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)) {
103094
103294
  const activeModel2 = state3.originalModel;
103095
103295
  log2(`[${HOOK_NAME11}] Restoring preferred primary model`, {
103096
103296
  sessionID,
@@ -103207,20 +103407,49 @@ function resolveFallbackBootstrapModel(options) {
103207
103407
 
103208
103408
  // packages/omo-opencode/src/hooks/runtime-fallback/fallback-retry-dispatcher.ts
103209
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
+ }
103210
103418
  async function dispatchFallbackRetry(deps, helpers, options) {
103419
+ const snapshot = snapshotFallbackState(options.state);
103211
103420
  const result = prepareFallback(options.sessionID, options.state, options.fallbackModels, deps.config);
103212
- if (result.success && deps.config.notify_on_fallback) {
103213
- await deps.ctx.client.tui.showToast({
103214
- body: {
103215
- title: "Model Fallback",
103216
- message: `Switching to ${result.newModel?.split("/").pop() || result.newModel} for next request`,
103217
- variant: "warning",
103218
- duration: 5000
103219
- }
103220
- }).catch(() => {});
103221
- }
103222
103421
  if (result.success && result.newModel) {
103223
- 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
+ }
103224
103453
  return;
103225
103454
  }
103226
103455
  log2(`[${HOOK_NAME11}] Fallback preparation failed`, {
@@ -104002,6 +104231,10 @@ function createMessageUpdateHandler(deps, helpers) {
104002
104231
  }
104003
104232
  }
104004
104233
  }
104234
+ if (classifyErrorType(error) === "quota_exceeded") {
104235
+ await helpers.abortSessionRequest(sessionID, "message.updated.quota-fallback");
104236
+ sessionRetryInFlight.delete(sessionID);
104237
+ }
104005
104238
  await dispatchFallbackRetry(deps, helpers, {
104006
104239
  sessionID,
104007
104240
  state: state3,
@@ -104032,7 +104265,8 @@ function createRuntimeFallbackHook(ctx, options, factoryOverrides = {}) {
104032
104265
  max_fallback_attempts: options?.config?.max_fallback_attempts ?? DEFAULT_CONFIG2.max_fallback_attempts,
104033
104266
  cooldown_seconds: options?.config?.cooldown_seconds ?? DEFAULT_CONFIG2.cooldown_seconds,
104034
104267
  timeout_seconds: options?.config?.timeout_seconds ?? DEFAULT_CONFIG2.timeout_seconds,
104035
- 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
104036
104270
  };
104037
104271
  const deps = {
104038
104272
  ctx,
@@ -104100,11 +104334,11 @@ function createRuntimeFallbackHook(ctx, options, factoryOverrides = {}) {
104100
104334
  };
104101
104335
  }
104102
104336
  // packages/omo-opencode/src/hooks/write-existing-file-guard/hook.ts
104103
- import { existsSync as existsSync85, realpathSync as realpathSync14 } from "fs";
104104
- 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";
104105
104339
 
104106
104340
  // packages/omo-opencode/src/hooks/write-existing-file-guard/tool-execute-before-handler.ts
104107
- import { existsSync as existsSync84 } from "fs";
104341
+ import { existsSync as existsSync85 } from "fs";
104108
104342
 
104109
104343
  // packages/omo-opencode/src/hooks/write-existing-file-guard/session-read-permissions.ts
104110
104344
  function touchSession(sessionLastAccess, sessionID) {
@@ -104205,7 +104439,7 @@ async function handleWriteExistingFileGuardToolExecuteBefore(params) {
104205
104439
  return;
104206
104440
  }
104207
104441
  if (toolName === "read") {
104208
- if (!existsSync84(resolvedPath) || !input.sessionID) {
104442
+ if (!existsSync85(resolvedPath) || !input.sessionID) {
104209
104443
  return;
104210
104444
  }
104211
104445
  registerReadPermission({
@@ -104223,7 +104457,7 @@ async function handleWriteExistingFileGuardToolExecuteBefore(params) {
104223
104457
  const { overwrite: _, ...rest } = argsRecord;
104224
104458
  output.args = rest;
104225
104459
  }
104226
- if (!existsSync84(resolvedPath)) {
104460
+ if (!existsSync85(resolvedPath)) {
104227
104461
  return;
104228
104462
  }
104229
104463
  if (isOmoWorkspacePath(canonicalPath)) {
@@ -104281,7 +104515,7 @@ function isPathInsideDirectory(pathToCheck, directory) {
104281
104515
  }
104282
104516
  function toCanonicalPath2(absolutePath) {
104283
104517
  let canonicalPath = absolutePath;
104284
- if (existsSync85(absolutePath)) {
104518
+ if (existsSync86(absolutePath)) {
104285
104519
  try {
104286
104520
  canonicalPath = realpathSync14.native(absolutePath);
104287
104521
  } catch (canonicalPathError) {
@@ -104289,9 +104523,9 @@ function toCanonicalPath2(absolutePath) {
104289
104523
  canonicalPath = absolutePath;
104290
104524
  }
104291
104525
  } else {
104292
- const absoluteDir = dirname30(absolutePath);
104293
- const resolvedDir = existsSync85(absoluteDir) ? realpathSync14.native(absoluteDir) : absoluteDir;
104294
- 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));
104295
104529
  }
104296
104530
  return normalize2(canonicalPath);
104297
104531
  }
@@ -107052,23 +107286,23 @@ init_logger2();
107052
107286
  init_plugin_identity();
107053
107287
 
107054
107288
  // packages/omo-opencode/src/hooks/legacy-plugin-toast/auto-migrate.ts
107055
- import { existsSync as existsSync86, readFileSync as readFileSync58 } from "fs";
107056
- import { join as join98 } from "path";
107289
+ import { existsSync as existsSync87, readFileSync as readFileSync58 } from "fs";
107290
+ import { join as join100 } from "path";
107057
107291
  init_plugin_identity();
107058
107292
  function detectOpenCodeConfigPath(overrideConfigDir) {
107059
107293
  if (overrideConfigDir) {
107060
- const jsoncPath = join98(overrideConfigDir, "opencode.jsonc");
107061
- const jsonPath = join98(overrideConfigDir, "opencode.json");
107062
- if (existsSync86(jsoncPath))
107294
+ const jsoncPath = join100(overrideConfigDir, "opencode.jsonc");
107295
+ const jsonPath = join100(overrideConfigDir, "opencode.json");
107296
+ if (existsSync87(jsoncPath))
107063
107297
  return jsoncPath;
107064
- if (existsSync86(jsonPath))
107298
+ if (existsSync87(jsonPath))
107065
107299
  return jsonPath;
107066
107300
  return null;
107067
107301
  }
107068
107302
  const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
107069
- if (existsSync86(paths.configJsonc))
107303
+ if (existsSync87(paths.configJsonc))
107070
107304
  return paths.configJsonc;
107071
- if (existsSync86(paths.configJson))
107305
+ if (existsSync87(paths.configJson))
107072
107306
  return paths.configJson;
107073
107307
  return null;
107074
107308
  }
@@ -107260,7 +107494,7 @@ function createNotepadWriteGuardHook() {
107260
107494
  };
107261
107495
  }
107262
107496
  // packages/omo-opencode/src/hooks/plan-format-validator/hook.ts
107263
- import { existsSync as existsSync87, readFileSync as readFileSync59 } from "fs";
107497
+ import { existsSync as existsSync88, readFileSync as readFileSync59 } from "fs";
107264
107498
  import { resolve as resolve29 } from "path";
107265
107499
  init_logger2();
107266
107500
  var WRITE_TOOLS = new Set(["Write", "Edit", "write", "edit"]);
@@ -107344,7 +107578,7 @@ function createPlanFormatValidatorHook(_ctx) {
107344
107578
  if (!isPlanFilePath(filePath))
107345
107579
  return;
107346
107580
  const resolvedPath = resolve29(_ctx.directory, filePath);
107347
- if (!existsSync87(resolvedPath))
107581
+ if (!existsSync88(resolvedPath))
107348
107582
  return;
107349
107583
  const content = readFileSync59(resolvedPath, "utf-8");
107350
107584
  if (!CHECKBOX_PATTERN.test(content))
@@ -107456,19 +107690,19 @@ tool.schema = z3;
107456
107690
 
107457
107691
  // packages/omo-opencode/src/shared/ripgrep-cli.ts
107458
107692
  import { spawnSync as spawnSync3 } from "child_process";
107459
- import { existsSync as existsSync89 } from "fs";
107460
- 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";
107461
107695
 
107462
107696
  // packages/omo-opencode/src/tools/grep/downloader.ts
107463
- import { existsSync as existsSync88, readdirSync as readdirSync22 } from "fs";
107464
- import { join as join99 } from "path";
107697
+ import { existsSync as existsSync89, readdirSync as readdirSync22 } from "fs";
107698
+ import { join as join101 } from "path";
107465
107699
  init_plugin_identity();
107466
107700
  function findFileRecursive(dir, filename) {
107467
107701
  try {
107468
107702
  const entries = readdirSync22(dir, { withFileTypes: true, recursive: true });
107469
107703
  for (const entry of entries) {
107470
107704
  if (entry.isFile() && entry.name === filename) {
107471
- return join99(entry.parentPath ?? dir, entry.name);
107705
+ return join101(entry.parentPath ?? dir, entry.name);
107472
107706
  }
107473
107707
  }
107474
107708
  } catch (error) {
@@ -107492,11 +107726,11 @@ function getPlatformKey() {
107492
107726
  }
107493
107727
  function getInstallDir() {
107494
107728
  const homeDir = process.env.HOME || process.env.USERPROFILE || ".";
107495
- return join99(homeDir, ".cache", CACHE_DIR_NAME, "bin");
107729
+ return join101(homeDir, ".cache", CACHE_DIR_NAME, "bin");
107496
107730
  }
107497
107731
  function getRgPath() {
107498
107732
  const isWindows2 = process.platform === "win32";
107499
- return join99(getInstallDir(), isWindows2 ? "rg.exe" : "rg");
107733
+ return join101(getInstallDir(), isWindows2 ? "rg.exe" : "rg");
107500
107734
  }
107501
107735
  async function extractTarGz3(archivePath, destDir) {
107502
107736
  const platformKey2 = getPlatformKey();
@@ -107513,7 +107747,7 @@ async function extractZip2(archivePath, destDir) {
107513
107747
  const binaryName = process.platform === "win32" ? "rg.exe" : "rg";
107514
107748
  const foundPath = findFileRecursive(destDir, binaryName);
107515
107749
  if (foundPath) {
107516
- const destPath = join99(destDir, binaryName);
107750
+ const destPath = join101(destDir, binaryName);
107517
107751
  if (foundPath !== destPath) {
107518
107752
  const { renameSync: renameSync7 } = await import("fs");
107519
107753
  renameSync7(foundPath, destPath);
@@ -107528,13 +107762,13 @@ async function downloadAndInstallRipgrep() {
107528
107762
  }
107529
107763
  const installDir = getInstallDir();
107530
107764
  const rgPath = getRgPath();
107531
- if (existsSync88(rgPath)) {
107765
+ if (existsSync89(rgPath)) {
107532
107766
  return rgPath;
107533
107767
  }
107534
107768
  ensureCacheDir(installDir);
107535
107769
  const filename = `ripgrep-${RG_VERSION}-${config.platform}.${config.extension}`;
107536
107770
  const url = `https://github.com/BurntSushi/ripgrep/releases/download/${RG_VERSION}/${filename}`;
107537
- const archivePath = join99(installDir, filename);
107771
+ const archivePath = join101(installDir, filename);
107538
107772
  try {
107539
107773
  await downloadArchive(url, archivePath);
107540
107774
  if (config.extension === "tar.gz") {
@@ -107543,7 +107777,7 @@ async function downloadAndInstallRipgrep() {
107543
107777
  await extractZip2(archivePath, installDir);
107544
107778
  }
107545
107779
  ensureExecutable(rgPath);
107546
- if (!existsSync88(rgPath)) {
107780
+ if (!existsSync89(rgPath)) {
107547
107781
  throw new Error("ripgrep binary not found after extraction");
107548
107782
  }
107549
107783
  return rgPath;
@@ -107559,7 +107793,7 @@ async function downloadAndInstallRipgrep() {
107559
107793
  }
107560
107794
  function getInstalledRipgrepPath() {
107561
107795
  const rgPath = getRgPath();
107562
- return existsSync88(rgPath) ? rgPath : null;
107796
+ return existsSync89(rgPath) ? rgPath : null;
107563
107797
  }
107564
107798
 
107565
107799
  // packages/omo-opencode/src/shared/ripgrep-cli.ts
@@ -107595,19 +107829,19 @@ function findExecutable(name) {
107595
107829
  }
107596
107830
  function getOpenCodeBundledRg() {
107597
107831
  const execPath = process.execPath;
107598
- const execDir = dirname31(execPath);
107832
+ const execDir = dirname32(execPath);
107599
107833
  const isWindows2 = process.platform === "win32";
107600
107834
  const rgName = isWindows2 ? "rg.exe" : "rg";
107601
107835
  const candidates = [
107602
- join100(getOpenCodeCacheDir(), "bin", rgName),
107603
- join100(getDataDir(), "opencode", "bin", rgName),
107604
- join100(execDir, rgName),
107605
- join100(execDir, "bin", rgName),
107606
- join100(execDir, "..", "bin", rgName),
107607
- 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)
107608
107842
  ];
107609
107843
  for (const candidate of candidates) {
107610
- if (existsSync89(candidate)) {
107844
+ if (existsSync90(candidate)) {
107611
107845
  return candidate;
107612
107846
  }
107613
107847
  }
@@ -108259,7 +108493,7 @@ Use this when a task matches an available skill's or command's description.
108259
108493
  - The tool will return detailed instructions with your context applied.
108260
108494
  `;
108261
108495
  // packages/omo-opencode/src/tools/skill/tools.ts
108262
- import { dirname as dirname33 } from "path";
108496
+ import { dirname as dirname34 } from "path";
108263
108497
  // packages/omo-opencode/src/tools/skill/session-skill-cache.ts
108264
108498
  var seenSessionIDs = new Set;
108265
108499
  function shouldInvalidateSkillCacheForSession(sessionID) {
@@ -108270,7 +108504,7 @@ function shouldInvalidateSkillCacheForSession(sessionID) {
108270
108504
  return true;
108271
108505
  }
108272
108506
  // packages/omo-opencode/src/tools/slashcommand/command-output-formatter.ts
108273
- import { dirname as dirname32 } from "path";
108507
+ import { dirname as dirname33 } from "path";
108274
108508
  async function formatLoadedCommand(command, userMessage) {
108275
108509
  const sections = [];
108276
108510
  sections.push(`# /${command.name} Command
@@ -108309,7 +108543,7 @@ async function formatLoadedCommand(command, userMessage) {
108309
108543
  if (!content && command.lazyContentLoader) {
108310
108544
  content = await command.lazyContentLoader.load();
108311
108545
  }
108312
- const commandDir = command.path ? dirname32(command.path) : process.cwd();
108546
+ const commandDir = command.path ? dirname33(command.path) : process.cwd();
108313
108547
  const withFileReferences = await resolveFileReferencesInText(content, commandDir);
108314
108548
  const resolvedContent = await resolveCommandsInText(withFileReferences);
108315
108549
  let finalContent = resolvedContent.trim();
@@ -108711,7 +108945,7 @@ function createSkillTool(options) {
108711
108945
  if (matchedSkill.name === "git-master") {
108712
108946
  body = injectGitMasterConfig(body, options.gitMasterConfig);
108713
108947
  }
108714
- const dir = matchedSkill.path ? dirname33(matchedSkill.path) : matchedSkill.resolvedPath || process.cwd();
108948
+ const dir = matchedSkill.path ? dirname34(matchedSkill.path) : matchedSkill.resolvedPath || process.cwd();
108715
108949
  const output = [
108716
108950
  `## Skill: ${matchedSkill.name}`,
108717
108951
  "",
@@ -108751,9 +108985,9 @@ function createSkillTool(options) {
108751
108985
  }
108752
108986
  var skill = createSkillTool({ directory: process.cwd() });
108753
108987
  // packages/omo-opencode/src/tools/session-manager/constants.ts
108754
- import { join as join101 } from "path";
108755
- var TODO_DIR2 = join101(getClaudeConfigDir(), "todos");
108756
- 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");
108757
108991
  var SESSION_LIST_DESCRIPTION = `List all OpenCode sessions with optional filtering.
108758
108992
 
108759
108993
  Returns a list of available session IDs with metadata including message count, date range, and agents used.
@@ -108826,16 +109060,16 @@ Has Todos: Yes (12 items, 8 completed)
108826
109060
  Has Transcript: Yes (234 entries)`;
108827
109061
 
108828
109062
  // packages/omo-opencode/src/tools/session-manager/file-storage.ts
108829
- import { existsSync as existsSync90 } from "fs";
109063
+ import { existsSync as existsSync91 } from "fs";
108830
109064
  import { readdir as readdir6, readFile as readFile9 } from "fs/promises";
108831
- import { join as join102 } from "path";
109065
+ import { join as join104 } from "path";
108832
109066
  function ignoreFileStorageError(error) {
108833
109067
  if (error instanceof Error)
108834
109068
  return;
108835
109069
  throw error;
108836
109070
  }
108837
109071
  async function getFileMainSessions(directory) {
108838
- if (!existsSync90(SESSION_STORAGE))
109072
+ if (!existsSync91(SESSION_STORAGE))
108839
109073
  return [];
108840
109074
  const sessions = [];
108841
109075
  try {
@@ -108843,13 +109077,13 @@ async function getFileMainSessions(directory) {
108843
109077
  for (const projectDir of projectDirs) {
108844
109078
  if (!projectDir.isDirectory())
108845
109079
  continue;
108846
- const projectPath = join102(SESSION_STORAGE, projectDir.name);
109080
+ const projectPath = join104(SESSION_STORAGE, projectDir.name);
108847
109081
  const sessionFiles = await readdir6(projectPath);
108848
109082
  for (const file2 of sessionFiles) {
108849
109083
  if (!file2.endsWith(".json"))
108850
109084
  continue;
108851
109085
  try {
108852
- const content = await readFile9(join102(projectPath, file2), "utf-8");
109086
+ const content = await readFile9(join104(projectPath, file2), "utf-8");
108853
109087
  const meta = JSON.parse(content);
108854
109088
  if (meta.parentID)
108855
109089
  continue;
@@ -108869,7 +109103,7 @@ async function getFileMainSessions(directory) {
108869
109103
  return sessions.sort((a, b) => b.time.updated - a.time.updated);
108870
109104
  }
108871
109105
  async function getFileAllSessions() {
108872
- if (!existsSync90(MESSAGE_STORAGE))
109106
+ if (!existsSync91(MESSAGE_STORAGE))
108873
109107
  return [];
108874
109108
  const sessions = [];
108875
109109
  async function scanDirectory(dir) {
@@ -108878,7 +109112,7 @@ async function getFileAllSessions() {
108878
109112
  for (const entry of entries) {
108879
109113
  if (!entry.isDirectory())
108880
109114
  continue;
108881
- const sessionPath = join102(dir, entry.name);
109115
+ const sessionPath = join104(dir, entry.name);
108882
109116
  const files = await readdir6(sessionPath);
108883
109117
  if (files.some((file2) => file2.endsWith(".json"))) {
108884
109118
  sessions.push(entry.name);
@@ -108899,7 +109133,7 @@ async function fileSessionExists(sessionID) {
108899
109133
  }
108900
109134
  async function getFileSessionMessages(sessionID) {
108901
109135
  const messageDir = getMessageDir(sessionID);
108902
- if (!messageDir || !existsSync90(messageDir))
109136
+ if (!messageDir || !existsSync91(messageDir))
108903
109137
  return [];
108904
109138
  const messages = [];
108905
109139
  try {
@@ -108908,7 +109142,7 @@ async function getFileSessionMessages(sessionID) {
108908
109142
  if (!file2.endsWith(".json"))
108909
109143
  continue;
108910
109144
  try {
108911
- const content = await readFile9(join102(messageDir, file2), "utf-8");
109145
+ const content = await readFile9(join104(messageDir, file2), "utf-8");
108912
109146
  const meta = JSON.parse(content);
108913
109147
  const parts = await readParts2(meta.id);
108914
109148
  messages.push({
@@ -108936,8 +109170,8 @@ async function getFileSessionMessages(sessionID) {
108936
109170
  });
108937
109171
  }
108938
109172
  async function readParts2(messageID) {
108939
- const partDir = join102(PART_STORAGE, messageID);
108940
- if (!existsSync90(partDir))
109173
+ const partDir = join104(PART_STORAGE, messageID);
109174
+ if (!existsSync91(partDir))
108941
109175
  return [];
108942
109176
  const parts = [];
108943
109177
  try {
@@ -108946,7 +109180,7 @@ async function readParts2(messageID) {
108946
109180
  if (!file2.endsWith(".json"))
108947
109181
  continue;
108948
109182
  try {
108949
- const content = await readFile9(join102(partDir, file2), "utf-8");
109183
+ const content = await readFile9(join104(partDir, file2), "utf-8");
108950
109184
  parts.push(JSON.parse(content));
108951
109185
  } catch (error) {
108952
109186
  ignoreFileStorageError(error);
@@ -108960,14 +109194,14 @@ async function readParts2(messageID) {
108960
109194
  return parts.sort((a, b) => a.id.localeCompare(b.id));
108961
109195
  }
108962
109196
  async function getFileSessionTodos(sessionID) {
108963
- if (!existsSync90(TODO_DIR2))
109197
+ if (!existsSync91(TODO_DIR2))
108964
109198
  return [];
108965
109199
  try {
108966
109200
  const allFiles = await readdir6(TODO_DIR2);
108967
109201
  const todoFiles = allFiles.filter((file2) => file2 === `${sessionID}.json`);
108968
109202
  for (const file2 of todoFiles) {
108969
109203
  try {
108970
- const content = await readFile9(join102(TODO_DIR2, file2), "utf-8");
109204
+ const content = await readFile9(join104(TODO_DIR2, file2), "utf-8");
108971
109205
  const data = JSON.parse(content);
108972
109206
  if (!Array.isArray(data))
108973
109207
  continue;
@@ -108989,10 +109223,10 @@ async function getFileSessionTodos(sessionID) {
108989
109223
  return [];
108990
109224
  }
108991
109225
  async function getFileSessionTranscript(sessionID) {
108992
- if (!existsSync90(TRANSCRIPT_DIR2))
109226
+ if (!existsSync91(TRANSCRIPT_DIR2))
108993
109227
  return 0;
108994
- const transcriptFile = join102(TRANSCRIPT_DIR2, `${sessionID}.jsonl`);
108995
- if (!existsSync90(transcriptFile))
109228
+ const transcriptFile = join104(TRANSCRIPT_DIR2, `${sessionID}.jsonl`);
109229
+ if (!existsSync91(transcriptFile))
108996
109230
  return 0;
108997
109231
  try {
108998
109232
  const content = await readFile9(transcriptFile, "utf-8");
@@ -109925,7 +110159,7 @@ function createSkillMcpTool(options) {
109925
110159
  },
109926
110160
  async execute(args, toolContext) {
109927
110161
  const operation = validateOperationParams(args);
109928
- const skills = getLoadedSkills();
110162
+ const skills = await getLoadedSkills();
109929
110163
  const found = findMcpServer(args.mcp_name, skills);
109930
110164
  if (!found) {
109931
110165
  const builtinHint = formatBuiltinMcpHint(args.mcp_name);
@@ -110811,23 +111045,23 @@ Pass \`session_id=<id>\` to continue previous agent with full context. Nested su
110811
111045
  // packages/omo-opencode/src/tools/call-omo-agent/tools.ts
110812
111046
  init_plugin_identity();
110813
111047
  // packages/claude-code-compat-core/src/features/claude-code-agent-loader/loader.ts
110814
- import { existsSync as existsSync95, readdirSync as readdirSync23 } from "fs";
110815
- import { join as join108 } from "path";
111048
+ import { existsSync as existsSync96, readdirSync as readdirSync23 } from "fs";
111049
+ import { join as join110 } from "path";
110816
111050
 
110817
111051
  // packages/claude-code-compat-core/src/shared/claude-config-dir.ts
110818
- import { homedir as homedir28 } from "os";
110819
- import { join as join103 } from "path";
111052
+ import { homedir as homedir29 } from "os";
111053
+ import { join as join105 } from "path";
110820
111054
  function getClaudeConfigDir3() {
110821
111055
  const envConfigDir = process.env.CLAUDE_CONFIG_DIR;
110822
111056
  if (envConfigDir) {
110823
111057
  return envConfigDir;
110824
111058
  }
110825
- return join103(process.env.HOME || process.env.USERPROFILE || homedir28(), ".claude");
111059
+ return join105(process.env.HOME || process.env.USERPROFILE || homedir29(), ".claude");
110826
111060
  }
110827
111061
  // packages/claude-code-compat-core/src/shared/opencode-config-dir.ts
110828
- import { existsSync as existsSync91, realpathSync as realpathSync15 } from "fs";
110829
- import { homedir as homedir29 } from "os";
110830
- import { join as join104, posix as posix7, resolve as resolve33, win32 as win3210 } from "path";
111062
+ import { existsSync as existsSync92, realpathSync as realpathSync15 } from "fs";
111063
+ import { homedir as homedir30 } from "os";
111064
+ import { join as join106, posix as posix7, resolve as resolve33, win32 as win3210 } from "path";
110831
111065
  var TAURI_APP_IDENTIFIER3 = "ai.opencode.desktop";
110832
111066
  var TAURI_APP_IDENTIFIER_DEV3 = "ai.opencode.desktop.dev";
110833
111067
  function isDevBuild3(version) {
@@ -110839,15 +111073,15 @@ function getTauriConfigDir3(identifier) {
110839
111073
  const platform2 = process.platform;
110840
111074
  switch (platform2) {
110841
111075
  case "darwin":
110842
- return join104(homedir29(), "Library", "Application Support", identifier);
111076
+ return join106(homedir30(), "Library", "Application Support", identifier);
110843
111077
  case "win32": {
110844
- const appData = process.env.APPDATA || join104(homedir29(), "AppData", "Roaming");
111078
+ const appData = process.env.APPDATA || join106(homedir30(), "AppData", "Roaming");
110845
111079
  return win3210.join(appData, identifier);
110846
111080
  }
110847
111081
  case "linux":
110848
111082
  default: {
110849
- const xdgConfig = process.env.XDG_CONFIG_HOME || join104(homedir29(), ".config");
110850
- return join104(xdgConfig, identifier);
111083
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join106(homedir30(), ".config");
111084
+ return join106(xdgConfig, identifier);
110851
111085
  }
110852
111086
  }
110853
111087
  }
@@ -110856,7 +111090,7 @@ function resolveConfigPath3(pathValue) {
110856
111090
  return posix7.normalize(pathValue);
110857
111091
  }
110858
111092
  const resolvedPath = resolve33(pathValue);
110859
- if (!existsSync91(resolvedPath))
111093
+ if (!existsSync92(resolvedPath))
110860
111094
  return resolvedPath;
110861
111095
  try {
110862
111096
  return realpathSync15(resolvedPath);
@@ -110890,8 +111124,8 @@ function getWslLinuxHomeDir3(windowsConfigRoot) {
110890
111124
  function getCliDefaultConfigDir3() {
110891
111125
  const envXdgConfig = process.env.XDG_CONFIG_HOME?.trim();
110892
111126
  const shouldIgnoreWindowsXdg = envXdgConfig !== undefined && envXdgConfig.length > 0 && isWslEnvironment3() && isWindowsUserConfigRoot3(envXdgConfig);
110893
- const xdgConfig = shouldIgnoreWindowsXdg ? posix7.join(getWslLinuxHomeDir3(envXdgConfig) ?? "/home", ".config") : envXdgConfig || join104(homedir29(), ".config");
110894
- 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");
110895
111129
  return resolveConfigPath3(configDir);
110896
111130
  }
110897
111131
  function getCliCustomConfigDir3() {
@@ -110924,9 +111158,9 @@ function getOpenCodeConfigDir3(options) {
110924
111158
  const tauriDir = process.platform === "win32" ? win3210.isAbsolute(tauriDirBase) ? win3210.normalize(tauriDirBase) : win3210.resolve(tauriDirBase) : resolveConfigPath3(tauriDirBase);
110925
111159
  if (checkExisting) {
110926
111160
  const legacyDir = getCliConfigDir3();
110927
- const legacyConfig = join104(legacyDir, "opencode.json");
110928
- const legacyConfigC = join104(legacyDir, "opencode.jsonc");
110929
- 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)) {
110930
111164
  return legacyDir;
110931
111165
  }
110932
111166
  }
@@ -110935,11 +111169,11 @@ function getOpenCodeConfigDir3(options) {
110935
111169
  // packages/claude-code-compat-core/src/shared/jsonc-parser.ts
110936
111170
  init_src();
110937
111171
  // packages/claude-code-compat-core/src/shared/resolve-agent-definition-paths.ts
110938
- import { homedir as homedir30 } from "os";
110939
- import { isAbsolute as isAbsolute18, join as join105, resolve as resolve34 } from "path";
111172
+ import { homedir as homedir31 } from "os";
111173
+ import { isAbsolute as isAbsolute18, join as join107, resolve as resolve34 } from "path";
110940
111174
  function resolveAgentDefinitionPaths2(paths, baseDir, containmentDir) {
110941
111175
  return paths.flatMap((p) => {
110942
- const expanded = p.startsWith("~/") ? join105(homedir30(), p.slice(2)) : p;
111176
+ const expanded = p.startsWith("~/") ? join107(homedir31(), p.slice(2)) : p;
110943
111177
  const resolved = isAbsolute18(expanded) ? expanded : resolve34(baseDir, expanded);
110944
111178
  if (containmentDir !== null && !isWithinProject(resolved, containmentDir)) {
110945
111179
  log4(`agent_definitions path rejected (outside project boundary): ${p} -> ${resolved}`);
@@ -110967,13 +111201,13 @@ var EXCLUDED_DIR_NAMES2 = [
110967
111201
  ];
110968
111202
  var EXCLUDED_DIRS3 = Object.freeze(new Set(EXCLUDED_DIR_NAMES2));
110969
111203
  // packages/claude-code-compat-core/src/shared/opencode-command-dirs.ts
110970
- 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";
110971
111205
  function getParentOpencodeConfigDir3(configDir) {
110972
- const parentDir = dirname34(configDir);
111206
+ const parentDir = dirname35(configDir);
110973
111207
  if (basename18(parentDir) !== "profiles") {
110974
111208
  return null;
110975
111209
  }
110976
- return dirname34(parentDir);
111210
+ return dirname35(parentDir);
110977
111211
  }
110978
111212
  function getOpenCodeCommandDirs2(options) {
110979
111213
  const configDirs = getOpenCodeConfigDirs3(options);
@@ -110981,21 +111215,21 @@ function getOpenCodeCommandDirs2(options) {
110981
111215
  ...configDirs.flatMap((configDir) => {
110982
111216
  const parentConfigDir = getParentOpencodeConfigDir3(configDir);
110983
111217
  return [
110984
- join106(configDir, "commands"),
110985
- join106(configDir, "command"),
110986
- ...parentConfigDir ? [join106(parentConfigDir, "commands"), join106(parentConfigDir, "command")] : []
111218
+ join108(configDir, "commands"),
111219
+ join108(configDir, "command"),
111220
+ ...parentConfigDir ? [join108(parentConfigDir, "commands"), join108(parentConfigDir, "command")] : []
110987
111221
  ];
110988
111222
  })
110989
111223
  ]));
110990
111224
  }
110991
111225
  // packages/claude-code-compat-core/src/shared/project-discovery-dirs.ts
110992
111226
  import { execFileSync as execFileSync6 } from "child_process";
110993
- import { existsSync as existsSync92, realpathSync as realpathSync16 } from "fs";
110994
- 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";
110995
111229
  var worktreePathCache3 = new Map;
110996
111230
  function normalizePath6(path18) {
110997
111231
  const resolvedPath = process.platform !== "win32" && win3211.isAbsolute(path18) ? path18 : resolve35(path18);
110998
- if (!existsSync92(resolvedPath)) {
111232
+ if (!existsSync93(resolvedPath)) {
110999
111233
  return resolvedPath;
111000
111234
  }
111001
111235
  try {
@@ -111050,10 +111284,10 @@ function detectWorktreePath4(directory) {
111050
111284
  function findGitMarkerAncestor(directory) {
111051
111285
  let currentDirectory = normalizePath6(directory);
111052
111286
  while (true) {
111053
- if (existsSync92(join107(currentDirectory, ".git"))) {
111287
+ if (existsSync93(join109(currentDirectory, ".git"))) {
111054
111288
  return currentDirectory;
111055
111289
  }
111056
- const parentDirectory = dirname35(currentDirectory);
111290
+ const parentDirectory = dirname36(currentDirectory);
111057
111291
  if (parentDirectory === currentDirectory) {
111058
111292
  return;
111059
111293
  }
@@ -111068,8 +111302,8 @@ function findAncestorDirectories3(startDirectory, targetPaths, stopDirectory) {
111068
111302
  const stopDirectoryKey = resolvedStopDirectory ? pathKey3(resolvedStopDirectory) : undefined;
111069
111303
  while (true) {
111070
111304
  for (const targetPath of targetPaths) {
111071
- const candidateDirectory = join107(currentDirectory, ...targetPath);
111072
- if (!existsSync92(candidateDirectory)) {
111305
+ const candidateDirectory = join109(currentDirectory, ...targetPath);
111306
+ if (!existsSync93(candidateDirectory)) {
111073
111307
  continue;
111074
111308
  }
111075
111309
  const normalizedCandidateDirectory = normalizePath6(candidateDirectory);
@@ -111083,7 +111317,7 @@ function findAncestorDirectories3(startDirectory, targetPaths, stopDirectory) {
111083
111317
  if (stopDirectoryKey === pathKey3(currentDirectory)) {
111084
111318
  return directories;
111085
111319
  }
111086
- const parentDirectory = dirname35(currentDirectory);
111320
+ const parentDirectory = dirname36(currentDirectory);
111087
111321
  if (parentDirectory === currentDirectory) {
111088
111322
  return directories;
111089
111323
  }
@@ -111098,14 +111332,14 @@ function findProjectOpencodeCommandDirs2(startDirectory, stopDirectory) {
111098
111332
  ], detectedStopDirectory);
111099
111333
  }
111100
111334
  // packages/claude-code-compat-core/src/features/claude-code-agent-loader/agent-definitions-loader.ts
111101
- import { existsSync as existsSync94, readFileSync as readFileSync61 } from "fs";
111335
+ import { existsSync as existsSync95, readFileSync as readFileSync61 } from "fs";
111102
111336
  import { basename as basename19, extname as extname4 } from "path";
111103
111337
 
111104
111338
  // packages/claude-code-compat-core/src/features/claude-code-agent-loader/json-agent-loader.ts
111105
- import { existsSync as existsSync93, readFileSync as readFileSync60 } from "fs";
111339
+ import { existsSync as existsSync94, readFileSync as readFileSync60 } from "fs";
111106
111340
  function parseJsonAgentFile(filePath, scope) {
111107
111341
  try {
111108
- if (!existsSync93(filePath)) {
111342
+ if (!existsSync94(filePath)) {
111109
111343
  return null;
111110
111344
  }
111111
111345
  const content = readFileSync60(filePath, "utf-8");
@@ -111146,7 +111380,7 @@ function parseJsonAgentFile(filePath, scope) {
111146
111380
  // packages/claude-code-compat-core/src/features/claude-code-agent-loader/agent-definitions-loader.ts
111147
111381
  function parseMarkdownAgentFile(filePath, scope, anthropicProvider) {
111148
111382
  try {
111149
- if (!existsSync94(filePath)) {
111383
+ if (!existsSync95(filePath)) {
111150
111384
  return null;
111151
111385
  }
111152
111386
  const content = readFileSync61(filePath, "utf-8");
@@ -111183,7 +111417,7 @@ function parseMarkdownAgentFile(filePath, scope, anthropicProvider) {
111183
111417
  function loadAgentDefinitions(paths, scope, anthropicProvider) {
111184
111418
  const result = Object.create(null);
111185
111419
  for (const filePath of paths) {
111186
- if (!existsSync94(filePath)) {
111420
+ if (!existsSync95(filePath)) {
111187
111421
  log4(`[agent-definitions-loader] File not found, skipping: ${filePath}`);
111188
111422
  continue;
111189
111423
  }
@@ -111208,7 +111442,7 @@ function loadAgentDefinitions(paths, scope, anthropicProvider) {
111208
111442
 
111209
111443
  // packages/claude-code-compat-core/src/features/claude-code-agent-loader/loader.ts
111210
111444
  function loadAgentsFromDir(agentsDir, scope, anthropicProvider) {
111211
- if (!existsSync95(agentsDir)) {
111445
+ if (!existsSync96(agentsDir)) {
111212
111446
  return [];
111213
111447
  }
111214
111448
  const entries = readdirSync23(agentsDir, { withFileTypes: true });
@@ -111216,7 +111450,7 @@ function loadAgentsFromDir(agentsDir, scope, anthropicProvider) {
111216
111450
  for (const entry of entries) {
111217
111451
  if (!isMarkdownFile(entry))
111218
111452
  continue;
111219
- const agentPath = join108(agentsDir, entry.name);
111453
+ const agentPath = join110(agentsDir, entry.name);
111220
111454
  const agent = parseMarkdownAgentFile(agentPath, scope, anthropicProvider);
111221
111455
  if (agent) {
111222
111456
  agents.push(agent);
@@ -111225,7 +111459,7 @@ function loadAgentsFromDir(agentsDir, scope, anthropicProvider) {
111225
111459
  return agents;
111226
111460
  }
111227
111461
  function loadUserAgents(anthropicProvider) {
111228
- const userAgentsDir = join108(getClaudeConfigDir3(), "agents");
111462
+ const userAgentsDir = join110(getClaudeConfigDir3(), "agents");
111229
111463
  const agents = loadAgentsFromDir(userAgentsDir, "user", anthropicProvider);
111230
111464
  const result = Object.create(null);
111231
111465
  for (const agent of agents) {
@@ -111234,7 +111468,7 @@ function loadUserAgents(anthropicProvider) {
111234
111468
  return result;
111235
111469
  }
111236
111470
  function loadProjectAgents(directory, anthropicProvider) {
111237
- const projectAgentsDir = join108(directory ?? process.cwd(), ".claude", "agents");
111471
+ const projectAgentsDir = join110(directory ?? process.cwd(), ".claude", "agents");
111238
111472
  const agents = loadAgentsFromDir(projectAgentsDir, "project", anthropicProvider);
111239
111473
  const result = Object.create(null);
111240
111474
  for (const agent of agents) {
@@ -111246,7 +111480,7 @@ function loadOpencodeGlobalAgents() {
111246
111480
  const result = Object.create(null);
111247
111481
  const configDirs = getOpenCodeConfigDirs3({ binary: "opencode" });
111248
111482
  for (const configDir of configDirs) {
111249
- const opencodeAgentsDir = join108(configDir, "agents");
111483
+ const opencodeAgentsDir = join110(configDir, "agents");
111250
111484
  const agents = loadAgentsFromDir(opencodeAgentsDir, "opencode");
111251
111485
  for (const agent of agents) {
111252
111486
  if (!(agent.name in result)) {
@@ -111257,7 +111491,7 @@ function loadOpencodeGlobalAgents() {
111257
111491
  return result;
111258
111492
  }
111259
111493
  function loadOpencodeProjectAgents(directory) {
111260
- const opencodeProjectDir = join108(directory ?? process.cwd(), ".opencode", "agents");
111494
+ const opencodeProjectDir = join110(directory ?? process.cwd(), ".opencode", "agents");
111261
111495
  const agents = loadAgentsFromDir(opencodeProjectDir, "opencode-project");
111262
111496
  const result = Object.create(null);
111263
111497
  for (const agent of agents) {
@@ -111470,9 +111704,7 @@ Description: ${task.description}
111470
111704
  Agent: ${task.agent} (subagent)
111471
111705
  Status: ${task.status}
111472
111706
 
111473
- System notifies on completion. Use \`background_output\` with task_id="${task.id}" to check.
111474
-
111475
- Do NOT call background_output now. Wait for <system-reminder> notification first.`;
111707
+ Do NOT call background_output now. Wait for <system-reminder> notification first. The system will deliver the result when the task completes; you do not need to poll for it.`;
111476
111708
  } catch (error) {
111477
111709
  const message = error instanceof Error ? error.message : String(error);
111478
111710
  return `Failed to launch background agent task: ${message}`;
@@ -111854,6 +112086,28 @@ async function resolveCallableAgents(_client, _sessionId) {
111854
112086
  return [...ALLOWED_AGENTS];
111855
112087
  }
111856
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
+
111857
112111
  // packages/omo-opencode/src/tools/call-omo-agent/tools.ts
111858
112112
  function createSyncExecutorDeps(modelFallbackControllerAccessor) {
111859
112113
  return {
@@ -111898,6 +112152,19 @@ function resolveModelAndFallbackChain(args) {
111898
112152
  variant: variantToUse
111899
112153
  });
111900
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
+ }
111901
112168
  }
111902
112169
  const normalizedFallbackModels = normalizeFallbackModels(agentOverride?.fallback_models ?? (agentOverride?.category ? userCategories?.[agentOverride.category]?.fallback_models : undefined));
111903
112170
  const defaultProviderID = model?.providerID ?? agentRequirement?.fallbackChain?.[0]?.providers?.[0] ?? "opencode";
@@ -111994,9 +112261,9 @@ function validateArgs(args) {
111994
112261
  const normalizedArgs = args;
111995
112262
  const filePath = args.file_path;
111996
112263
  const hasFilePath = hasNonEmptyString(args.file_path);
111997
- const hasFilePaths = Array.isArray(args.file_paths);
112264
+ const hasFilePaths = hasValues(args.file_paths);
111998
112265
  const hasImageData = hasNonEmptyString(args.image_data);
111999
- const hasImageDataList = Array.isArray(args.image_data_list);
112266
+ const hasImageDataList = hasValues(args.image_data_list);
112000
112267
  const filePathsFromSingular = normalizedArgs._normalized_file_paths_from_singular === true;
112001
112268
  const imageDataListFromSingular = normalizedArgs._normalized_image_data_list_from_singular === true;
112002
112269
  if (hasFilePath && hasFilePaths && !filePathsFromSingular) {
@@ -112005,12 +112272,6 @@ function validateArgs(args) {
112005
112272
  if (hasImageData && hasImageDataList && !imageDataListFromSingular) {
112006
112273
  return "Error: Provide either 'image_data' or 'image_data_list', not both.";
112007
112274
  }
112008
- if (hasFilePaths && !hasValues(args.file_paths)) {
112009
- return "Error: 'file_paths' must contain at least one local file path.";
112010
- }
112011
- if (hasImageDataList && !hasValues(args.image_data_list)) {
112012
- return "Error: 'image_data_list' must contain at least one Base64 image string.";
112013
- }
112014
112275
  if (hasValues(args.file_paths)) {
112015
112276
  for (const filePath2 of args.file_paths) {
112016
112277
  if (!hasNonEmptyString(filePath2)) {
@@ -112031,7 +112292,7 @@ function validateArgs(args) {
112031
112292
  if (hasNonEmptyString(filePath) && isRemoteUrl(filePath)) {
112032
112293
  return "Error: Remote URLs are not supported for file_path. Download the file first or use a local path.";
112033
112294
  }
112034
- if (!hasFilePath && !hasValues(args.file_paths) && !hasImageData && !hasValues(args.image_data_list)) {
112295
+ if (!hasFilePath && !hasFilePaths && !hasImageData && !hasImageDataList) {
112035
112296
  return `Error: Must provide at least one of 'file_path', 'file_paths', 'image_data', or 'image_data_list'. Usage:
112036
112297
  - look_at(file_path="/path/to/file", goal="what to extract")
112037
112298
  - look_at(file_paths=["/path/to/file-1", "/path/to/file-2"], goal="what to extract")
@@ -112050,9 +112311,9 @@ import { pathToFileURL } from "url";
112050
112311
 
112051
112312
  // packages/omo-opencode/src/tools/look-at/image-converter.ts
112052
112313
  import * as childProcess2 from "child_process";
112053
- 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";
112054
112315
  import { tmpdir as tmpdir7 } from "os";
112055
- import { dirname as dirname37, join as join110 } from "path";
112316
+ import { dirname as dirname38, join as join112 } from "path";
112056
112317
  var SUPPORTED_FORMATS = new Set([
112057
112318
  "image/jpeg",
112058
112319
  "image/png",
@@ -112082,7 +112343,7 @@ var UNSUPPORTED_FORMATS = new Set([
112082
112343
  var CONVERSION_TIMEOUT_MS = 30000;
112083
112344
  function cleanupTemporaryFileAfterFailure(filePath) {
112084
112345
  try {
112085
- if (existsSync97(filePath)) {
112346
+ if (existsSync98(filePath)) {
112086
112347
  unlinkSync14(filePath);
112087
112348
  }
112088
112349
  } catch (cleanupError) {
@@ -112100,11 +112361,11 @@ function needsConversion(mimeType) {
112100
112361
  return mimeType.startsWith("image/");
112101
112362
  }
112102
112363
  function convertImageToJpeg(inputPath, mimeType) {
112103
- if (!existsSync97(inputPath)) {
112364
+ if (!existsSync98(inputPath)) {
112104
112365
  throw new Error(`File not found: ${inputPath}`);
112105
112366
  }
112106
- const tempDir = mkdtempSync(join110(tmpdir7(), "opencode-img-"));
112107
- const outputPath = join110(tempDir, "converted.jpg");
112367
+ const tempDir = mkdtempSync(join112(tmpdir7(), "opencode-img-"));
112368
+ const outputPath = join112(tempDir, "converted.jpg");
112108
112369
  log2(`[image-converter] Converting ${mimeType} to JPEG: ${inputPath}`);
112109
112370
  try {
112110
112371
  if (process.platform === "darwin") {
@@ -112114,7 +112375,7 @@ function convertImageToJpeg(inputPath, mimeType) {
112114
112375
  encoding: "utf-8",
112115
112376
  timeout: CONVERSION_TIMEOUT_MS
112116
112377
  });
112117
- if (existsSync97(outputPath)) {
112378
+ if (existsSync98(outputPath)) {
112118
112379
  log2(`[image-converter] Converted using sips: ${outputPath}`);
112119
112380
  return outputPath;
112120
112381
  }
@@ -112130,7 +112391,7 @@ function convertImageToJpeg(inputPath, mimeType) {
112130
112391
  encoding: "utf-8",
112131
112392
  timeout: CONVERSION_TIMEOUT_MS
112132
112393
  });
112133
- if (existsSync97(outputPath)) {
112394
+ if (existsSync98(outputPath)) {
112134
112395
  log2(`[image-converter] Converted using ImageMagick: ${outputPath}`);
112135
112396
  return outputPath;
112136
112397
  }
@@ -112153,12 +112414,12 @@ function convertImageToJpeg(inputPath, mimeType) {
112153
112414
  }
112154
112415
  function cleanupConvertedImage(filePath) {
112155
112416
  try {
112156
- const tempDirectory = dirname37(filePath);
112157
- if (existsSync97(filePath)) {
112417
+ const tempDirectory = dirname38(filePath);
112418
+ if (existsSync98(filePath)) {
112158
112419
  unlinkSync14(filePath);
112159
112420
  log2(`[image-converter] Cleaned up temporary file: ${filePath}`);
112160
112421
  }
112161
- if (existsSync97(tempDirectory)) {
112422
+ if (existsSync98(tempDirectory)) {
112162
112423
  rmSync5(tempDirectory, { recursive: true, force: true });
112163
112424
  log2(`[image-converter] Cleaned up temporary directory: ${tempDirectory}`);
112164
112425
  }
@@ -112168,9 +112429,9 @@ function cleanupConvertedImage(filePath) {
112168
112429
  }
112169
112430
  }
112170
112431
  function convertBase64ImageToJpeg(base64Data, mimeType) {
112171
- const tempDir = mkdtempSync(join110(tmpdir7(), "opencode-b64-"));
112432
+ const tempDir = mkdtempSync(join112(tmpdir7(), "opencode-b64-"));
112172
112433
  const inputExt = mimeType.split("/")[1] || "bin";
112173
- const inputPath = join110(tempDir, `input.${inputExt}`);
112434
+ const inputPath = join112(tempDir, `input.${inputExt}`);
112174
112435
  const tempFiles = [inputPath];
112175
112436
  try {
112176
112437
  const cleanBase64 = base64Data.replace(/^data:[^;]+;base64,/, "");
@@ -113722,9 +113983,7 @@ Agent: ${task.agent}
113722
113983
  Status: ${task.status}
113723
113984
 
113724
113985
  Agent continues with full previous context preserved.
113725
- System notifies on completion. Use \`background_output\` with task_id="${backgroundTaskId}" to check.
113726
-
113727
- Do NOT call background_output now. Wait for <system-reminder> notification first.
113986
+ Do NOT call background_output now. Wait for <system-reminder> notification first. The system will deliver the result when the task completes; you do not need to poll for it.
113728
113987
 
113729
113988
  ${buildTaskMetadataBlock({
113730
113989
  sessionId,
@@ -114738,9 +114997,7 @@ Description: ${task.description}
114738
114997
  Agent: ${task.agent}${args.category ? ` (category: ${args.category})` : ""}
114739
114998
  Status: ${task.status}
114740
114999
 
114741
- System notifies on completion. Use \`background_output\` with task_id="${task.id}" to check.
114742
-
114743
- Do NOT call background_output now. Wait for <system-reminder> notification first.${taskMetadataBlock}`;
115000
+ Do NOT call background_output now. Wait for <system-reminder> notification first. The system will deliver the result when the task completes; you do not need to poll for it.${taskMetadataBlock}`;
114744
115001
  } catch (error) {
114745
115002
  return formatDetailedError(error, {
114746
115003
  operation: "Launch background task",
@@ -114917,7 +115174,8 @@ var syncTaskDeps = {
114917
115174
  createSyncSession,
114918
115175
  sendSyncPrompt,
114919
115176
  pollSyncSession,
114920
- fetchSyncResult
115177
+ fetchSyncResult,
115178
+ isProviderExhaustionFallbackEligible
114921
115179
  };
114922
115180
 
114923
115181
  // packages/omo-opencode/src/tools/delegate-task/sync-task-metadata.ts
@@ -115103,6 +115361,10 @@ function addRetryTaskToast(input) {
115103
115361
  modelInfo: input.modelInfo
115104
115362
  });
115105
115363
  }
115364
+ function shouldRetryPollErrorWithFallback(pollError, deps) {
115365
+ const errorInfo = { message: pollError };
115366
+ return shouldRetryError(errorInfo) || (deps.isProviderExhaustionFallbackEligible?.(errorInfo) ?? false);
115367
+ }
115106
115368
  async function runSyncTaskLoop(input) {
115107
115369
  const {
115108
115370
  args,
@@ -115202,7 +115464,7 @@ async function runSyncTaskLoop(input) {
115202
115464
  });
115203
115465
  }
115204
115466
  }
115205
- const nextFallbackModel = shouldRetryError({ message: pollError }) ? getNextSyncFallbackModel(activeSessionID, fallbackState) : null;
115467
+ const nextFallbackModel = shouldRetryPollErrorWithFallback(pollError, deps) ? getNextSyncFallbackModel(activeSessionID, fallbackState) : null;
115206
115468
  if (!nextFallbackModel) {
115207
115469
  return pollError;
115208
115470
  }
@@ -116291,7 +116553,7 @@ function isExplicitSyncRun(runInBackground) {
116291
116553
  return runInBackground === false || runInBackground === "false";
116292
116554
  }
116293
116555
  // packages/omo-opencode/src/tools/task/task-create.ts
116294
- import { join as join112 } from "path";
116556
+ import { join as join114 } from "path";
116295
116557
 
116296
116558
  // packages/omo-opencode/src/tools/task/types.ts
116297
116559
  import { z as z4 } from "zod";
@@ -116346,8 +116608,8 @@ var TaskDeleteInputSchema = z4.object({
116346
116608
  });
116347
116609
 
116348
116610
  // packages/omo-opencode/src/features/claude-tasks/storage.ts
116349
- import { join as join111, dirname as dirname38, basename as basename21, isAbsolute as isAbsolute19 } from "path";
116350
- 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";
116351
116613
  import { randomUUID as randomUUID7 } from "crypto";
116352
116614
  function ignoreClaudeTaskStorageError(error) {
116353
116615
  if (error instanceof Error)
@@ -116358,11 +116620,11 @@ function getTaskDir(config = {}) {
116358
116620
  const tasksConfig = config.sisyphus?.tasks;
116359
116621
  const storagePath = tasksConfig?.storage_path;
116360
116622
  if (storagePath) {
116361
- return isAbsolute19(storagePath) ? storagePath : join111(process.cwd(), storagePath);
116623
+ return isAbsolute19(storagePath) ? storagePath : join113(process.cwd(), storagePath);
116362
116624
  }
116363
116625
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
116364
116626
  const listId = resolveTaskListId(config);
116365
- return join111(configDir, "tasks", listId);
116627
+ return join113(configDir, "tasks", listId);
116366
116628
  }
116367
116629
  function sanitizePathSegment(value) {
116368
116630
  return value.replace(/[^a-zA-Z0-9_-]/g, "-") || "default";
@@ -116380,13 +116642,13 @@ function resolveTaskListId(config = {}) {
116380
116642
  return sanitizePathSegment(basename21(process.cwd()));
116381
116643
  }
116382
116644
  function ensureDir(dirPath) {
116383
- if (!existsSync98(dirPath)) {
116645
+ if (!existsSync99(dirPath)) {
116384
116646
  mkdirSync19(dirPath, { recursive: true });
116385
116647
  }
116386
116648
  }
116387
116649
  function readJsonSafe(filePath, schema) {
116388
116650
  try {
116389
- if (!existsSync98(filePath)) {
116651
+ if (!existsSync99(filePath)) {
116390
116652
  return null;
116391
116653
  }
116392
116654
  const content = readFileSync65(filePath, "utf-8");
@@ -116402,7 +116664,7 @@ function readJsonSafe(filePath, schema) {
116402
116664
  }
116403
116665
  }
116404
116666
  function writeJsonAtomic(filePath, data) {
116405
- const dir = dirname38(filePath);
116667
+ const dir = dirname39(filePath);
116406
116668
  ensureDir(dir);
116407
116669
  const tempPath = `${filePath}.tmp.${Date.now()}`;
116408
116670
  try {
@@ -116410,7 +116672,7 @@ function writeJsonAtomic(filePath, data) {
116410
116672
  renameSync7(tempPath, filePath);
116411
116673
  } catch (error) {
116412
116674
  try {
116413
- if (existsSync98(tempPath)) {
116675
+ if (existsSync99(tempPath)) {
116414
116676
  unlinkSync15(tempPath);
116415
116677
  }
116416
116678
  } catch (cleanupError) {
@@ -116424,7 +116686,7 @@ function generateTaskId() {
116424
116686
  return `T-${randomUUID7()}`;
116425
116687
  }
116426
116688
  function acquireLock3(dirPath) {
116427
- const lockPath = join111(dirPath, ".lock");
116689
+ const lockPath = join113(dirPath, ".lock");
116428
116690
  const lockId = randomUUID7();
116429
116691
  const createLock = (timestamp) => {
116430
116692
  writeFileSync19(lockPath, JSON.stringify({ id: lockId, timestamp }), {
@@ -116475,7 +116737,7 @@ function acquireLock3(dirPath) {
116475
116737
  acquired: true,
116476
116738
  release: () => {
116477
116739
  try {
116478
- if (!existsSync98(lockPath))
116740
+ if (!existsSync99(lockPath))
116479
116741
  return;
116480
116742
  const lockContent = readFileSync65(lockPath, "utf-8");
116481
116743
  const lockData = JSON.parse(lockContent);
@@ -116642,7 +116904,7 @@ async function handleCreate(args, config, ctx, context) {
116642
116904
  threadID: context.sessionID
116643
116905
  };
116644
116906
  const validatedTask = TaskObjectSchema.parse(task);
116645
- writeJsonAtomic(join112(taskDir, `${taskId}.json`), validatedTask);
116907
+ writeJsonAtomic(join114(taskDir, `${taskId}.json`), validatedTask);
116646
116908
  await syncTaskTodoUpdate(ctx, validatedTask, context.sessionID);
116647
116909
  return JSON.stringify({
116648
116910
  task: {
@@ -116664,7 +116926,7 @@ async function handleCreate(args, config, ctx, context) {
116664
116926
  }
116665
116927
  }
116666
116928
  // packages/omo-opencode/src/tools/task/task-get.ts
116667
- import { join as join113 } from "path";
116929
+ import { join as join115 } from "path";
116668
116930
  var TASK_ID_PATTERN = /^T-[A-Za-z0-9-]+$/;
116669
116931
  function parseTaskId(id) {
116670
116932
  if (!TASK_ID_PATTERN.test(id))
@@ -116689,7 +116951,7 @@ Returns null if the task does not exist or the file is invalid.`,
116689
116951
  return JSON.stringify({ error: "invalid_task_id" });
116690
116952
  }
116691
116953
  const taskDir = getTaskDir(config);
116692
- const taskPath = join113(taskDir, `${taskId}.json`);
116954
+ const taskPath = join115(taskDir, `${taskId}.json`);
116693
116955
  const task = readJsonSafe(taskPath, TaskObjectSchema);
116694
116956
  return JSON.stringify({ task: task ?? null });
116695
116957
  } catch (error) {
@@ -116702,8 +116964,8 @@ Returns null if the task does not exist or the file is invalid.`,
116702
116964
  });
116703
116965
  }
116704
116966
  // packages/omo-opencode/src/tools/task/task-list.ts
116705
- import { join as join114 } from "path";
116706
- 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";
116707
116969
  function createTaskList(config) {
116708
116970
  return tool({
116709
116971
  description: `List all active tasks with summary information.
@@ -116714,7 +116976,7 @@ Returns summary format: id, subject, status, owner, blockedBy (not full descript
116714
116976
  args: {},
116715
116977
  execute: async () => {
116716
116978
  const taskDir = getTaskDir(config);
116717
- if (!existsSync99(taskDir)) {
116979
+ if (!existsSync100(taskDir)) {
116718
116980
  return JSON.stringify({ tasks: [] });
116719
116981
  }
116720
116982
  const files = readdirSync25(taskDir).filter((f) => f.endsWith(".json") && f.startsWith("T-")).map((f) => f.replace(".json", ""));
@@ -116723,7 +116985,7 @@ Returns summary format: id, subject, status, owner, blockedBy (not full descript
116723
116985
  }
116724
116986
  const allTasks = [];
116725
116987
  for (const fileId of files) {
116726
- const task = readJsonSafe(join114(taskDir, `${fileId}.json`), TaskObjectSchema);
116988
+ const task = readJsonSafe(join116(taskDir, `${fileId}.json`), TaskObjectSchema);
116727
116989
  if (task) {
116728
116990
  allTasks.push(task);
116729
116991
  }
@@ -116751,7 +117013,7 @@ Returns summary format: id, subject, status, owner, blockedBy (not full descript
116751
117013
  });
116752
117014
  }
116753
117015
  // packages/omo-opencode/src/tools/task/task-update.ts
116754
- import { join as join115 } from "path";
117016
+ import { join as join117 } from "path";
116755
117017
  var TASK_ID_PATTERN2 = /^T-[A-Za-z0-9-]+$/;
116756
117018
  function parseTaskId2(id) {
116757
117019
  if (!TASK_ID_PATTERN2.test(id))
@@ -116799,7 +117061,7 @@ async function handleUpdate(args, config, ctx, context) {
116799
117061
  return JSON.stringify({ error: "task_lock_unavailable" });
116800
117062
  }
116801
117063
  try {
116802
- const taskPath = join115(taskDir, `${taskId}.json`);
117064
+ const taskPath = join117(taskDir, `${taskId}.json`);
116803
117065
  const task = readJsonSafe(taskPath, TaskObjectSchema);
116804
117066
  if (!task) {
116805
117067
  return JSON.stringify({ error: "task_not_found" });
@@ -118372,7 +118634,7 @@ function createHooks(args) {
118372
118634
  };
118373
118635
  }
118374
118636
  // packages/omo-opencode/src/features/background-agent/manager.ts
118375
- import { join as join117 } from "path";
118637
+ import { join as join119 } from "path";
118376
118638
  init_tmux();
118377
118639
 
118378
118640
  // packages/omo-opencode/src/features/background-agent/abort-with-timeout.ts
@@ -118644,9 +118906,23 @@ Use \`background_output(task_id="${task.id}")\` to retrieve this result when rea
118644
118906
  </system-reminder>`;
118645
118907
  }
118646
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
+
118647
118923
  // packages/omo-opencode/src/features/background-agent/compaction-aware-message-resolver.ts
118648
118924
  import { readdirSync as readdirSync26, readFileSync as readFileSync66 } from "fs";
118649
- import { join as join116 } from "path";
118925
+ import { join as join118 } from "path";
118650
118926
  function hasFullAgentAndModel(message) {
118651
118927
  return !!message.agent && !isCompactionAgent(message.agent) && !!message.model?.providerID && !!message.model?.modelID;
118652
118928
  }
@@ -118725,7 +119001,7 @@ function findNearestMessageExcludingCompaction(messageDir, sessionID) {
118725
119001
  const messages = [];
118726
119002
  for (const file2 of files) {
118727
119003
  try {
118728
- const content = readFileSync66(join116(messageDir, file2), "utf-8");
119004
+ const content = readFileSync66(join118(messageDir, file2), "utf-8");
118729
119005
  const parsed = JSON.parse(content);
118730
119006
  if (hasCompactionPartInStorage(parsed.id) || isCompactionAgent(parsed.agent)) {
118731
119007
  continue;
@@ -118956,13 +119232,15 @@ var defaultFallbackRetryHandlerDeps = {
118956
119232
  getNextFallback,
118957
119233
  hasMoreFallbacks,
118958
119234
  selectFallbackProvider,
118959
- transformModelForProvider
119235
+ transformModelForProvider,
119236
+ isProviderExhaustionFallbackEligible
118960
119237
  };
118961
119238
  async function tryFallbackRetry(args) {
118962
119239
  const { task, errorInfo, source, concurrencyManager, client: client3, idleDeferralTimers, queuesByKey, processKey, onRetrying } = args;
118963
119240
  const deps = { ...defaultFallbackRetryHandlerDeps, ...args.deps };
118964
119241
  const fallbackChain = task.fallbackChain;
118965
- 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);
118966
119244
  if (!canRetry)
118967
119245
  return false;
118968
119246
  const attemptCount = task.attemptCount ?? 0;
@@ -119190,7 +119468,8 @@ function cloneParentWake(wake) {
119190
119468
  ...wake.dispatchedAt !== undefined ? { dispatchedAt: wake.dispatchedAt } : {},
119191
119469
  ...wake.noReplyAdmittedAt !== undefined ? { noReplyAdmittedAt: wake.noReplyAdmittedAt } : {},
119192
119470
  ...wake.toolCallDeferralStartedAt !== undefined ? { toolCallDeferralStartedAt: wake.toolCallDeferralStartedAt } : {},
119193
- ...wake.allowEmptyAssistantTurnRetry !== undefined ? { allowEmptyAssistantTurnRetry: wake.allowEmptyAssistantTurnRetry } : {}
119471
+ ...wake.allowEmptyAssistantTurnRetry !== undefined ? { allowEmptyAssistantTurnRetry: wake.allowEmptyAssistantTurnRetry } : {},
119472
+ ...wake.noAssistantOutputRetryCount !== undefined ? { noAssistantOutputRetryCount: wake.noAssistantOutputRetryCount } : {}
119194
119473
  };
119195
119474
  }
119196
119475
  function isRedundantParentWake(latestWake, dispatchedWake) {
@@ -119722,7 +120001,13 @@ class ParentWakeFlushRunner {
119722
120001
  });
119723
120002
  }
119724
120003
  schedulePendingParentWakeFlush(sessionID, delayMs) {
119725
- 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);
119726
120011
  }
119727
120012
  deferReplyWakeWhileUnsafe(sessionID, latestWake) {
119728
120013
  if (isFailureParentWake(latestWake)) {
@@ -119834,6 +120119,7 @@ class ParentWakePendingQueue {
119834
120119
  pendingWake.shouldReply = pendingWake.shouldReply || shouldReply;
119835
120120
  if (notificationsChanged) {
119836
120121
  delete pendingWake.noReplyAdmittedAt;
120122
+ delete pendingWake.noAssistantOutputRetryCount;
119837
120123
  }
119838
120124
  return;
119839
120125
  }
@@ -119852,6 +120138,10 @@ class ParentWakePendingQueue {
119852
120138
  pendingWake.noReplyAdmittedAt ??= latestWake.noReplyAdmittedAt;
119853
120139
  pendingWake.toolCallDeferralStartedAt ??= latestWake.toolCallDeferralStartedAt;
119854
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
+ }
119855
120145
  return;
119856
120146
  }
119857
120147
  this.pendingParentWakes.set(sessionID, cloneParentWake(latestWake));
@@ -120142,6 +120432,7 @@ class ParentWakeSessionInspector {
120142
120432
  }
120143
120433
 
120144
120434
  // packages/omo-opencode/src/features/background-agent/parent-wake-window-recovery.ts
120435
+ var MAX_NO_ASSISTANT_OUTPUT_RETRIES = 1;
120145
120436
  async function handleDispatchedParentWakeWindowElapsed(input) {
120146
120437
  const currentWake = input.dispatchedTracker.getWake(input.sessionID);
120147
120438
  if (!currentWake || currentWake.dispatchedAt !== input.wake.dispatchedAt) {
@@ -120154,9 +120445,22 @@ async function handleDispatchedParentWakeWindowElapsed(input) {
120154
120445
  });
120155
120446
  return;
120156
120447
  }
120157
- input.dispatchedTracker.refreshWakeTimer(input.sessionID);
120158
- log2("[background-agent] Kept dispatched parent wake awaiting late failure or assistant output:", {
120159
- 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
120160
120464
  });
120161
120465
  }
120162
120466
  function logParentWakeWindowRecoveryError(sessionID, error) {
@@ -120180,7 +120484,9 @@ class ParentWakeNotifier {
120180
120484
  dispatchedTracker;
120181
120485
  sessionInspector;
120182
120486
  flushRunner;
120487
+ onPendingWakeRequeued;
120183
120488
  constructor(deps, options) {
120489
+ this.onPendingWakeRequeued = deps.onPendingWakeRequeued;
120184
120490
  this.pendingQueue = new ParentWakePendingQueue({
120185
120491
  pendingRetryMs: options.pendingRetryMs,
120186
120492
  enqueueNotificationForParent: deps.enqueueNotificationForParent
@@ -120192,7 +120498,9 @@ class ParentWakeNotifier {
120192
120498
  sessionID,
120193
120499
  wake,
120194
120500
  dispatchedTracker: this.dispatchedTracker,
120195
- sessionInspector: this.sessionInspector
120501
+ sessionInspector: this.sessionInspector,
120502
+ requeueWake: (latestWake) => this.requeueWake(sessionID, latestWake),
120503
+ scheduleFlush: () => this.schedulePendingParentWakeFlush(sessionID)
120196
120504
  }).catch((error) => {
120197
120505
  logParentWakeWindowRecoveryError(sessionID, error);
120198
120506
  rescheduleParentWakeWindowRecoveryAfterError(sessionID, wake, this.dispatchedTracker);
@@ -120298,6 +120606,7 @@ class ParentWakeNotifier {
120298
120606
  }
120299
120607
  requeueWake(sessionID, latestWake) {
120300
120608
  this.pendingQueue.requeueWake(sessionID, latestWake);
120609
+ this.onPendingWakeRequeued?.(sessionID);
120301
120610
  }
120302
120611
  async shouldDeferParentWakeForSessionHistory(sessionID, wake) {
120303
120612
  return this.sessionInspector.shouldDeferForHistory(sessionID, wake);
@@ -121496,7 +121805,9 @@ class BackgroundManager {
121496
121805
  this.parentWakeNotifier = new ParentWakeNotifier({
121497
121806
  client: this.client,
121498
121807
  directory: this.directory,
121499
- enqueueNotificationForParent: this.enqueueNotificationForParent.bind(this)
121808
+ enqueueNotificationForParent: this.enqueueNotificationForParent.bind(this),
121809
+ onPendingWakeRequeued: (sessionID) => this.updateBackgroundTaskMarker(sessionID),
121810
+ onScheduledFlushSettled: (sessionID) => this.updateBackgroundTaskMarker(sessionID)
121500
121811
  }, {
121501
121812
  pendingRetryMs: PENDING_PARENT_WAKE_RETRY_MS,
121502
121813
  acceptedMessageSkewMs: PARENT_WAKE_ACCEPTED_MESSAGE_SKEW_MS,
@@ -122138,16 +122449,20 @@ The fallback retry session is now created and can be inspected directly.
122138
122449
  return this.getTasksByParentSession(sessionID).some((t2) => t2.status === "running" || t2.status === "pending");
122139
122450
  }
122140
122451
  hasPendingParentWake(sessionID) {
122141
- 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);
122142
122456
  }
122143
122457
  updateBackgroundTaskMarker(parentSessionID) {
122144
122458
  const tasks = this.getTasksByParentSession(parentSessionID);
122145
122459
  const activeTasks = tasks.filter((t2) => t2.status === "running" || t2.status === "pending");
122146
- if (activeTasks.length > 0) {
122147
- setContinuationMarkerSource(this.directory, parentSessionID, "background-task", "active", `${activeTasks.length} background task(s) active`);
122148
- } else {
122149
- setContinuationMarkerSource(this.directory, parentSessionID, "background-task", "idle");
122150
- }
122460
+ writeBackgroundTaskMarker({
122461
+ directory: this.directory,
122462
+ parentSessionID,
122463
+ activeTaskCount: activeTasks.length,
122464
+ hasUndeliveredParentWake: this.hasUndeliveredParentWake(parentSessionID)
122465
+ });
122151
122466
  }
122152
122467
  getAllDescendantTasks(sessionID) {
122153
122468
  const result = [];
@@ -122824,6 +123139,7 @@ The fallback retry session is now created and can be inspected directly.
122824
123139
  const releaseNotificationPreparation = () => {
122825
123140
  if (notificationParentSessionID) {
122826
123141
  this.parentWakeNotifier.releaseNotificationPreparation(notificationParentSessionID);
123142
+ this.updateBackgroundTaskMarker(notificationParentSessionID);
122827
123143
  }
122828
123144
  };
122829
123145
  if (task.currentAttemptID) {
@@ -123295,6 +123611,7 @@ The task was re-queued on a fallback model after a retryable failure.
123295
123611
  } finally {
123296
123612
  if (notificationParentSessionID) {
123297
123613
  this.parentWakeNotifier.releaseNotificationPreparation(notificationParentSessionID);
123614
+ this.updateBackgroundTaskMarker(notificationParentSessionID);
123298
123615
  }
123299
123616
  }
123300
123617
  }
@@ -123408,7 +123725,7 @@ The task was re-queued on a fallback model after a retryable failure.
123408
123725
  parentSessionID: task.parentSessionId
123409
123726
  });
123410
123727
  }
123411
- const messageDir = join117(MESSAGE_STORAGE, task.parentSessionId);
123728
+ const messageDir = join119(MESSAGE_STORAGE, task.parentSessionId);
123412
123729
  const currentMessage = messageDir ? findNearestMessageExcludingCompaction(messageDir, task.parentSessionId) : null;
123413
123730
  agent = currentMessage?.agent ?? task.parentAgent;
123414
123731
  model = currentMessage?.model?.providerID && currentMessage?.model?.modelID ? { providerID: currentMessage.model.providerID, modelID: currentMessage.model.modelID } : undefined;
@@ -123429,9 +123746,14 @@ The task was re-queued on a fallback model after a retryable failure.
123429
123746
  }
123430
123747
  queuePendingParentWake(sessionID, notification, promptContext, shouldReply, delayMs) {
123431
123748
  this.parentWakeNotifier.queuePendingParentWake(sessionID, notification, promptContext, shouldReply, delayMs);
123749
+ this.updateBackgroundTaskMarker(sessionID);
123432
123750
  }
123433
123751
  async flushPendingParentWake(sessionID) {
123434
- await this.parentWakeNotifier.flushPendingParentWake(sessionID);
123752
+ try {
123753
+ await this.parentWakeNotifier.flushPendingParentWake(sessionID);
123754
+ } finally {
123755
+ this.updateBackgroundTaskMarker(sessionID);
123756
+ }
123435
123757
  }
123436
123758
  hasRunningTasks() {
123437
123759
  for (const task of this.tasks.values()) {
@@ -124992,7 +125314,7 @@ function createMonitorManager(options) {
124992
125314
  import { createHash as createHash6 } from "crypto";
124993
125315
  import {
124994
125316
  chmodSync as chmodSync4,
124995
- existsSync as existsSync102,
125317
+ existsSync as existsSync103,
124996
125318
  mkdirSync as mkdirSync20,
124997
125319
  readdirSync as readdirSync27,
124998
125320
  readFileSync as readFileSync68,
@@ -125000,15 +125322,15 @@ import {
125000
125322
  unlinkSync as unlinkSync16,
125001
125323
  writeFileSync as writeFileSync21
125002
125324
  } from "fs";
125003
- 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";
125004
125326
 
125005
125327
  // packages/mcp-client-core/src/config-dir.ts
125006
- import { existsSync as existsSync100, realpathSync as realpathSync17 } from "fs";
125007
- import { homedir as homedir31 } from "os";
125008
- import { join as join118, resolve as resolve36 } from "path";
125328
+ import { existsSync as existsSync101, realpathSync as realpathSync17 } from "fs";
125329
+ import { homedir as homedir32 } from "os";
125330
+ import { join as join120, resolve as resolve36 } from "path";
125009
125331
  function resolveConfigPath4(pathValue) {
125010
125332
  const resolvedPath = resolve36(pathValue);
125011
- if (!existsSync100(resolvedPath))
125333
+ if (!existsSync101(resolvedPath))
125012
125334
  return resolvedPath;
125013
125335
  try {
125014
125336
  return realpathSync17(resolvedPath);
@@ -125023,13 +125345,13 @@ function getOpenCodeCliConfigDir(env2 = process.env) {
125023
125345
  if (customConfigDir) {
125024
125346
  return resolveConfigPath4(customConfigDir);
125025
125347
  }
125026
- const xdgConfigDir = env2["XDG_CONFIG_HOME"]?.trim() || join118(homedir31(), ".config");
125027
- return resolveConfigPath4(join118(xdgConfigDir, "opencode"));
125348
+ const xdgConfigDir = env2["XDG_CONFIG_HOME"]?.trim() || join120(homedir32(), ".config");
125349
+ return resolveConfigPath4(join120(xdgConfigDir, "opencode"));
125028
125350
  }
125029
125351
 
125030
125352
  // packages/mcp-client-core/src/mcp-oauth/storage-index.ts
125031
- import { chmodSync as chmodSync3, existsSync as existsSync101, readFileSync as readFileSync67, renameSync as renameSync8, writeFileSync as writeFileSync20 } from "fs";
125032
- 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";
125033
125355
  var INDEX_FILE_NAME = "index.json";
125034
125356
  function isTokenIndex(value) {
125035
125357
  if (typeof value !== "object" || value === null || Array.isArray(value))
@@ -125037,11 +125359,11 @@ function isTokenIndex(value) {
125037
125359
  return Object.values(value).every((entry) => typeof entry === "string");
125038
125360
  }
125039
125361
  function getIndexPath(storageDir) {
125040
- return join119(storageDir, INDEX_FILE_NAME);
125362
+ return join121(storageDir, INDEX_FILE_NAME);
125041
125363
  }
125042
125364
  function readTokenIndex(storageDir) {
125043
125365
  const indexPath = getIndexPath(storageDir);
125044
- if (!existsSync101(indexPath))
125366
+ if (!existsSync102(indexPath))
125045
125367
  return {};
125046
125368
  try {
125047
125369
  const parsed = JSON.parse(readFileSync67(indexPath, "utf-8"));
@@ -125074,16 +125396,16 @@ function saveTokenIndexEntry(storageDir, hash, key) {
125074
125396
  var STORAGE_DIR_NAME = "mcp-oauth";
125075
125397
  var LEGACY_STORAGE_FILE_NAME = "mcp-oauth.json";
125076
125398
  function getMcpOauthStorageDir() {
125077
- return join120(getOpenCodeCliConfigDir(), STORAGE_DIR_NAME);
125399
+ return join122(getOpenCodeCliConfigDir(), STORAGE_DIR_NAME);
125078
125400
  }
125079
125401
  function getMcpOauthServerHash(serverHost, resource) {
125080
125402
  return createHash6("sha256").update(buildKey(serverHost, resource)).digest("hex").slice(0, 32);
125081
125403
  }
125082
125404
  function getMcpOauthStoragePath(serverHost, resource) {
125083
- return join120(getMcpOauthStorageDir(), `${getMcpOauthServerHash(serverHost, resource)}.json`);
125405
+ return join122(getMcpOauthStorageDir(), `${getMcpOauthServerHash(serverHost, resource)}.json`);
125084
125406
  }
125085
125407
  function getLegacyStoragePath() {
125086
- return join120(getOpenCodeCliConfigDir(), LEGACY_STORAGE_FILE_NAME);
125408
+ return join122(getOpenCodeCliConfigDir(), LEGACY_STORAGE_FILE_NAME);
125087
125409
  }
125088
125410
  function normalizeHost(serverHost) {
125089
125411
  let host = serverHost.trim();
@@ -125144,7 +125466,7 @@ function isOAuthTokenData(value) {
125144
125466
  return clientSecret === undefined || typeof clientSecret === "string";
125145
125467
  }
125146
125468
  function readTokenFile(filePath) {
125147
- if (!existsSync102(filePath))
125469
+ if (!existsSync103(filePath))
125148
125470
  return null;
125149
125471
  try {
125150
125472
  const parsed = JSON.parse(readFileSync68(filePath, "utf-8"));
@@ -125157,7 +125479,7 @@ function readTokenFile(filePath) {
125157
125479
  }
125158
125480
  function readLegacyStore() {
125159
125481
  const filePath = getLegacyStoragePath();
125160
- if (!existsSync102(filePath))
125482
+ if (!existsSync103(filePath))
125161
125483
  return null;
125162
125484
  try {
125163
125485
  const parsed = JSON.parse(readFileSync68(filePath, "utf-8"));
@@ -125177,8 +125499,8 @@ function readLegacyStore() {
125177
125499
  }
125178
125500
  function writeTokenFile(filePath, token) {
125179
125501
  try {
125180
- const dir = dirname39(filePath);
125181
- if (!existsSync102(dir)) {
125502
+ const dir = dirname40(filePath);
125503
+ if (!existsSync103(dir)) {
125182
125504
  mkdirSync20(dir, { recursive: true });
125183
125505
  }
125184
125506
  const tempPath = `${filePath}.tmp.${Date.now()}`;
@@ -130571,15 +130893,15 @@ init_logger2();
130571
130893
 
130572
130894
  // packages/omo-opencode/src/features/tui-sidebar/mirror-io.ts
130573
130895
  import { mkdirSync as mkdirSync21, readFileSync as readFileSync69 } from "fs";
130574
- import { dirname as dirname40 } from "path";
130896
+ import { dirname as dirname41 } from "path";
130575
130897
 
130576
130898
  // packages/omo-opencode/src/features/tui-sidebar/mirror-path.ts
130577
130899
  import { createHash as createHash8 } from "crypto";
130578
130900
  import { realpathSync as realpathSync18 } from "fs";
130579
- import { homedir as homedir32 } from "os";
130580
- import { join as join121, resolve as resolve37 } from "path";
130901
+ import { homedir as homedir33 } from "os";
130902
+ import { join as join123, resolve as resolve37 } from "path";
130581
130903
  function mirrorStorageDir() {
130582
- return join121(process.env.XDG_DATA_HOME ?? join121(homedir32(), ".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);
130583
130905
  }
130584
130906
  function canonicalProjectDir(projectDir) {
130585
130907
  try {
@@ -130593,7 +130915,7 @@ function canonicalProjectDir(projectDir) {
130593
130915
  }
130594
130916
  function mirrorFilePath(projectDir) {
130595
130917
  const projectHash = createHash8("sha1").update(canonicalProjectDir(projectDir)).digest("hex").slice(0, 16);
130596
- return join121(mirrorStorageDir(), `${projectHash}.json`);
130918
+ return join123(mirrorStorageDir(), `${projectHash}.json`);
130597
130919
  }
130598
130920
 
130599
130921
  // packages/omo-opencode/src/features/tui-sidebar/snapshot-schema.ts
@@ -130646,13 +130968,13 @@ var TuiRuntimeSnapshotSchema = z9.object({
130646
130968
  function writeMirror(projectDir, snapshot) {
130647
130969
  const filePath = mirrorFilePath(projectDir);
130648
130970
  const content = JSON.stringify(snapshot);
130649
- mkdirSync21(dirname40(filePath), { recursive: true });
130971
+ mkdirSync21(dirname41(filePath), { recursive: true });
130650
130972
  writeFileAtomically2(filePath, content, { mode: 384 });
130651
130973
  }
130652
130974
 
130653
130975
  // packages/omo-opencode/src/features/tui-sidebar/loop-reader.ts
130654
130976
  import { readdirSync as readdirSync28, readFileSync as readFileSync70, statSync as statSync13 } from "fs";
130655
- import { join as join122 } from "path";
130977
+ import { join as join124 } from "path";
130656
130978
  import { z as z10 } from "zod";
130657
130979
  var CriterionSchema = z10.object({
130658
130980
  status: z10.string()
@@ -130682,7 +131004,7 @@ function enumerateCandidates(projectDir) {
130682
131004
  return [...currentLoopCandidates(projectDir), legacyLoopCandidate(projectDir)].filter((candidate) => candidate !== null);
130683
131005
  }
130684
131006
  function currentLoopCandidates(projectDir) {
130685
- const loopRoot = join122(projectDir, ".omo", "ulw-loop");
131007
+ const loopRoot = join124(projectDir, ".omo", "ulw-loop");
130686
131008
  let entries;
130687
131009
  try {
130688
131010
  entries = readdirSync28(loopRoot, { withFileTypes: true });
@@ -130692,10 +131014,10 @@ function currentLoopCandidates(projectDir) {
130692
131014
  }
130693
131015
  throw error;
130694
131016
  }
130695
- 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);
130696
131018
  }
130697
131019
  function legacyLoopCandidate(projectDir) {
130698
- return statCandidate(join122(projectDir, ".omo", "loop", "goals.json"));
131020
+ return statCandidate(join124(projectDir, ".omo", "loop", "goals.json"));
130699
131021
  }
130700
131022
  function statCandidate(path22) {
130701
131023
  try {
@@ -133445,7 +133767,7 @@ async function isTmuxAvailableWithDeps(deps) {
133445
133767
  import {
133446
133768
  appendFileSync as appendFileSync7,
133447
133769
  chmodSync as chmodSync5,
133448
- existsSync as existsSync104,
133770
+ existsSync as existsSync105,
133449
133771
  renameSync as renameSync10,
133450
133772
  statSync as statSync14,
133451
133773
  unlinkSync as unlinkSync17,
@@ -133453,31 +133775,31 @@ import {
133453
133775
  } from "fs";
133454
133776
 
133455
133777
  // packages/openclaw-core/src/reply-listener-paths.ts
133456
- import { existsSync as existsSync103, mkdirSync as mkdirSync22 } from "fs";
133457
- import { homedir as homedir33 } from "os";
133458
- import { join as join123 } from "path";
133778
+ import { existsSync as existsSync104, mkdirSync as mkdirSync22 } from "fs";
133779
+ import { homedir as homedir34 } from "os";
133780
+ import { join as join125 } from "path";
133459
133781
  var REPLY_LISTENER_SECURE_FILE_MODE = 384;
133460
133782
  function resolveReplyListenerHomeDir() {
133461
- return process.env.HOME ?? process.env.USERPROFILE ?? homedir33();
133783
+ return process.env.HOME ?? process.env.USERPROFILE ?? homedir34();
133462
133784
  }
133463
133785
  function getReplyListenerStateDir() {
133464
- return join123(resolveReplyListenerHomeDir(), ".omo", "openclaw", "state");
133786
+ return join125(resolveReplyListenerHomeDir(), ".omo", "openclaw", "state");
133465
133787
  }
133466
133788
  function getReplyListenerPidFilePath() {
133467
- return join123(getReplyListenerStateDir(), "reply-listener.pid");
133789
+ return join125(getReplyListenerStateDir(), "reply-listener.pid");
133468
133790
  }
133469
133791
  function getReplyListenerStateFilePath() {
133470
- return join123(getReplyListenerStateDir(), "reply-listener-state.json");
133792
+ return join125(getReplyListenerStateDir(), "reply-listener-state.json");
133471
133793
  }
133472
133794
  function getReplyListenerConfigFilePath() {
133473
- return join123(getReplyListenerStateDir(), "reply-listener-config.json");
133795
+ return join125(getReplyListenerStateDir(), "reply-listener-config.json");
133474
133796
  }
133475
133797
  function getReplyListenerLogFilePath() {
133476
- return join123(getReplyListenerStateDir(), "reply-listener.log");
133798
+ return join125(getReplyListenerStateDir(), "reply-listener.log");
133477
133799
  }
133478
133800
  function ensureReplyListenerStateDir() {
133479
133801
  const stateDir = getReplyListenerStateDir();
133480
- if (!existsSync103(stateDir)) {
133802
+ if (!existsSync104(stateDir)) {
133481
133803
  mkdirSync22(stateDir, { recursive: true, mode: 448 });
133482
133804
  }
133483
133805
  }
@@ -133500,13 +133822,13 @@ function writeSecureReplyListenerFile(filePath, content) {
133500
133822
  }
133501
133823
  function rotateReplyListenerLogIfNeeded(logPath) {
133502
133824
  try {
133503
- if (!existsSync104(logPath))
133825
+ if (!existsSync105(logPath))
133504
133826
  return;
133505
133827
  const stats = statSync14(logPath);
133506
133828
  if (stats.size <= MAX_REPLY_LISTENER_LOG_SIZE_BYTES)
133507
133829
  return;
133508
133830
  const backupPath = `${logPath}.old`;
133509
- if (existsSync104(backupPath)) {
133831
+ if (existsSync105(backupPath)) {
133510
133832
  unlinkSync17(backupPath);
133511
133833
  }
133512
133834
  renameSync10(logPath, backupPath);
@@ -133533,7 +133855,7 @@ import { constants as constants24, closeSync as closeSync5, openSync as openSync
133533
133855
 
133534
133856
  // packages/openclaw-core/src/session-registry-paths.ts
133535
133857
  init_src();
133536
- import { join as join124 } from "path";
133858
+ import { join as join126 } from "path";
133537
133859
  var SECURE_FILE_MODE = 384;
133538
133860
  var MAX_AGE_MS = 24 * 60 * 60 * 1000;
133539
133861
  var LOCK_TIMEOUT_MS = 2000;
@@ -133544,16 +133866,16 @@ var cachedRegistryPaths = null;
133544
133866
  function resolveRegistryPaths() {
133545
133867
  if (cachedRegistryPaths !== null)
133546
133868
  return cachedRegistryPaths;
133547
- const openClawStorageDir = join124(getOpenCodeStorageDir2(), "openclaw");
133869
+ const openClawStorageDir = join126(getOpenCodeStorageDir2(), "openclaw");
133548
133870
  cachedRegistryPaths = {
133549
133871
  openClawStorageDir,
133550
- registryPath: join124(openClawStorageDir, "reply-session-registry.jsonl"),
133551
- registryLockPath: join124(openClawStorageDir, "reply-session-registry.lock")
133872
+ registryPath: join126(openClawStorageDir, "reply-session-registry.jsonl"),
133873
+ registryLockPath: join126(openClawStorageDir, "reply-session-registry.lock")
133552
133874
  };
133553
133875
  return cachedRegistryPaths;
133554
133876
  }
133555
133877
  function getOpenCodeStorageDir2() {
133556
- return join124(resolveXdgDataDir("opencode"), "opencode", "storage");
133878
+ return join126(resolveXdgDataDir("opencode"), "opencode", "storage");
133557
133879
  }
133558
133880
  function getRegistryPath() {
133559
133881
  return resolveRegistryPaths().registryPath;
@@ -133563,12 +133885,12 @@ function getRegistryLockPath() {
133563
133885
  }
133564
133886
 
133565
133887
  // packages/openclaw-core/src/session-registry-lock.ts
133566
- 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";
133567
133889
  import { randomUUID as randomUUID10 } from "crypto";
133568
133890
 
133569
133891
  // packages/openclaw-core/src/session-registry-storage.ts
133570
- import { existsSync as existsSync105, mkdirSync as mkdirSync23, readFileSync as readFileSync71, writeFileSync as writeFileSync23 } from "fs";
133571
- 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";
133572
133894
  function isSessionMapping(value) {
133573
133895
  if (typeof value !== "object" || value === null)
133574
133896
  return false;
@@ -133589,14 +133911,14 @@ function isSessionMapping(value) {
133589
133911
  return true;
133590
133912
  }
133591
133913
  function ensureRegistryDir() {
133592
- const registryDir = dirname41(getRegistryPath());
133593
- if (!existsSync105(registryDir)) {
133914
+ const registryDir = dirname42(getRegistryPath());
133915
+ if (!existsSync106(registryDir)) {
133594
133916
  mkdirSync23(registryDir, { recursive: true, mode: 448 });
133595
133917
  }
133596
133918
  }
133597
133919
  function readAllMappingsUnsafe() {
133598
133920
  const registryPath = getRegistryPath();
133599
- if (!existsSync105(registryPath))
133921
+ if (!existsSync106(registryPath))
133600
133922
  return [];
133601
133923
  try {
133602
133924
  const content = readFileSync71(registryPath, "utf-8");
@@ -133650,7 +133972,7 @@ function isPidAlive2(pid) {
133650
133972
  function readLockSnapshot() {
133651
133973
  try {
133652
133974
  const registryLockPath = getRegistryLockPath();
133653
- if (!existsSync106(registryLockPath))
133975
+ if (!existsSync107(registryLockPath))
133654
133976
  return null;
133655
133977
  const raw = readFileSync72(registryLockPath, "utf-8");
133656
133978
  const trimmed = raw.trim();
@@ -133681,7 +134003,7 @@ function readLockSnapshot() {
133681
134003
  function removeLockIfUnchanged(snapshot) {
133682
134004
  try {
133683
134005
  const registryLockPath = getRegistryLockPath();
133684
- if (!existsSync106(registryLockPath))
134006
+ if (!existsSync107(registryLockPath))
133685
134007
  return false;
133686
134008
  const currentRaw = readFileSync72(registryLockPath, "utf-8");
133687
134009
  if (currentRaw !== snapshot.raw)
@@ -133853,7 +134175,7 @@ class ReplyListenerRateLimiter {
133853
134175
  }
133854
134176
 
133855
134177
  // packages/openclaw-core/src/reply-listener-state.ts
133856
- 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";
133857
134179
  var REPLY_LISTENER_STARTUP_TOKEN_ENV = "OMO_OPENCLAW_REPLY_LISTENER_STARTUP_TOKEN";
133858
134180
  function ignoreReplyListenerStateReadError(error) {
133859
134181
  if (error instanceof Error)
@@ -133920,7 +134242,7 @@ function createPendingReplyListenerState(startupToken) {
133920
134242
  function readReplyListenerDaemonState() {
133921
134243
  try {
133922
134244
  const stateFilePath = getReplyListenerStateFilePath();
133923
- if (!existsSync107(stateFilePath))
134245
+ if (!existsSync108(stateFilePath))
133924
134246
  return null;
133925
134247
  return normalizeReplyListenerState(JSON.parse(readFileSync73(stateFilePath, "utf-8")));
133926
134248
  } catch (error) {
@@ -133938,7 +134260,7 @@ function writeReplyListenerDaemonState(state3) {
133938
134260
  function readReplyListenerDaemonConfig() {
133939
134261
  try {
133940
134262
  const configFilePath = getReplyListenerConfigFilePath();
133941
- if (!existsSync107(configFilePath))
134263
+ if (!existsSync108(configFilePath))
133942
134264
  return null;
133943
134265
  return JSON.parse(readFileSync73(configFilePath, "utf-8"));
133944
134266
  } catch (error) {
@@ -133952,7 +134274,7 @@ function writeReplyListenerDaemonConfig(config) {
133952
134274
  function readReplyListenerPid() {
133953
134275
  try {
133954
134276
  const pidFilePath = getReplyListenerPidFilePath();
133955
- if (!existsSync107(pidFilePath))
134277
+ if (!existsSync108(pidFilePath))
133956
134278
  return null;
133957
134279
  const pid = Number.parseInt(readFileSync73(pidFilePath, "utf-8").trim(), 10);
133958
134280
  return Number.isNaN(pid) ? null : pid;
@@ -133966,7 +134288,7 @@ function writeReplyListenerPid(pid) {
133966
134288
  }
133967
134289
  function removeReplyListenerPid() {
133968
134290
  const pidFilePath = getReplyListenerPidFilePath();
133969
- if (existsSync107(pidFilePath)) {
134291
+ if (existsSync108(pidFilePath)) {
133970
134292
  unlinkSync19(pidFilePath);
133971
134293
  }
133972
134294
  }
@@ -133994,8 +134316,8 @@ function getReplyListenerRuntimeSignature(config) {
133994
134316
  // packages/openclaw-core/src/reply-listener-poll-loop.ts
133995
134317
  var PRUNE_INTERVAL_MS = 60 * 60 * 1000;
133996
134318
  // packages/openclaw-core/src/reply-listener-start.ts
133997
- import { dirname as dirname42, join as join125 } from "path";
133998
- import { fileURLToPath as fileURLToPath6 } from "url";
134319
+ import { dirname as dirname43, join as join127 } from "path";
134320
+ import { fileURLToPath as fileURLToPath7 } from "url";
133999
134321
 
134000
134322
  // packages/openclaw-core/src/reply-listener-spawn.ts
134001
134323
  init_runtime();
@@ -134235,8 +134557,8 @@ function createStartFailureResult(message, state3) {
134235
134557
  };
134236
134558
  }
134237
134559
  function resolveReplyListenerDaemonScript(currentFileUrl) {
134238
- const currentFilePath = fileURLToPath6(currentFileUrl);
134239
- 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");
134240
134562
  }
134241
134563
  async function startReplyListener(config) {
134242
134564
  const normalizedConfig = getNormalizedReplyListenerConfig(config);
@@ -134659,25 +134981,25 @@ async function createRuntimeSkillSourceServer(options, runtimeEnv = runtime6) {
134659
134981
  };
134660
134982
  }
134661
134983
  // packages/claude-code-compat-core/src/features/claude-code-mcp-loader/loader.ts
134662
- import { existsSync as existsSync108, readFileSync as readFileSync75 } from "fs";
134663
- import { join as join126 } from "path";
134664
- import { homedir as homedir34 } from "os";
134984
+ import { existsSync as existsSync109, readFileSync as readFileSync75 } from "fs";
134985
+ import { join as join128 } from "path";
134986
+ import { homedir as homedir35 } from "os";
134665
134987
  function getMcpConfigPaths() {
134666
134988
  const claudeConfigDir = getClaudeConfigDir3();
134667
134989
  const homeDir = getHomeDir();
134668
134990
  const cwd = process.cwd();
134669
134991
  return [
134670
- { path: join126(homeDir, ".claude.json"), scope: "user" },
134671
- { path: join126(claudeConfigDir, ".mcp.json"), scope: "user" },
134672
- { path: join126(cwd, ".mcp.json"), scope: "project" },
134673
- { 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" }
134674
134996
  ];
134675
134997
  }
134676
134998
  function getHomeDir() {
134677
- return process.env.HOME || process.env.USERPROFILE || homedir34();
134999
+ return process.env.HOME || process.env.USERPROFILE || homedir35();
134678
135000
  }
134679
135001
  async function loadMcpConfigFile(filePath) {
134680
- if (!existsSync108(filePath)) {
135002
+ if (!existsSync109(filePath)) {
134681
135003
  return null;
134682
135004
  }
134683
135005
  try {
@@ -134697,7 +135019,7 @@ function getSystemMcpServerNames() {
134697
135019
  const paths2 = getMcpConfigPaths();
134698
135020
  const cwd = process.cwd();
134699
135021
  for (const { path: path22 } of paths2) {
134700
- if (!existsSync108(path22))
135022
+ if (!existsSync109(path22))
134701
135023
  continue;
134702
135024
  try {
134703
135025
  const content = readFileSync75(path22, "utf-8");
@@ -138843,40 +139165,52 @@ ${styleBlock}`;
138843
139165
 
138844
139166
  // packages/omo-opencode/src/agents/sisyphus-agent-factory.ts
138845
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
+ }
138846
139187
  function createSisyphusAgent(model, availableAgents, availableToolNames, availableSkills, availableCategories, useTaskSystem = false) {
138847
139188
  const tools = availableToolNames ? categorizeTools(availableToolNames) : [];
138848
139189
  const skills = availableSkills ?? [];
138849
139190
  const categories = availableCategories ?? [];
138850
139191
  const agents = availableAgents ?? [];
138851
- if (isKimiK27Model(model)) {
138852
- return buildGptSisyphusAgentConfig(MODE, model, buildKimiK27SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
138853
- }
138854
- if (isKimiK2Model(model)) {
138855
- return buildGptSisyphusAgentConfig(MODE, model, buildKimiK26SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
138856
- }
138857
- if (isGpt5_5Model(model)) {
138858
- return buildGptSisyphusAgentConfig(MODE, model, buildGpt55SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
138859
- }
138860
- if (isGptNativeSisyphusModel(model)) {
138861
- return buildGptSisyphusAgentConfig(MODE, model, buildGpt54SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
138862
- }
138863
- if (isClaudeFable5Model(model)) {
138864
- return buildClaudeSisyphusAgentConfig(MODE, model, buildClaudeFable5SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
138865
- }
138866
- if (isClaudeOpus48Model(model)) {
138867
- return buildClaudeSisyphusAgentConfig(MODE, model, buildClaudeOpus48SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
138868
- }
138869
- if (isClaudeOpus47Model(model)) {
138870
- return buildClaudeSisyphusAgentConfig(MODE, model, buildClaudeOpus47SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
138871
- }
138872
- if (isGlmModel(model)) {
138873
- return buildGlmSisyphusAgentConfig(MODE, model, buildGlm52SisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem));
138874
- }
138875
- const prompt = buildFallbackSisyphusPrompt(model, agents, tools, skills, categories, useTaskSystem);
138876
- if (isGptModel(model)) {
138877
- 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
+ }
138878
139213
  }
138879
- return buildClaudeSisyphusAgentConfig(MODE, model, prompt);
138880
139214
  }
138881
139215
  createSisyphusAgent.mode = MODE;
138882
139216
  // packages/omo-opencode/src/agents/oracle.ts
@@ -141602,15 +141936,15 @@ function createHephaestusAgent(model, availableAgents, availableToolNames, avail
141602
141936
  }
141603
141937
  createHephaestusAgent.mode = MODE9;
141604
141938
  // packages/omo-opencode/src/agents/builtin-agents/resolve-file-uri.ts
141605
- import { existsSync as existsSync109, readFileSync as readFileSync76 } from "fs";
141606
- import { homedir as homedir35 } from "os";
141607
- import { isAbsolute as isAbsolute20, join as join127, resolve as resolve38 } from "path";
141939
+ import { existsSync as existsSync110, readFileSync as readFileSync76 } from "fs";
141940
+ import { homedir as homedir36 } from "os";
141941
+ import { isAbsolute as isAbsolute20, join as join129, resolve as resolve38 } from "path";
141608
141942
  init_logger2();
141609
141943
  var ALLOWED_HOME_SUBDIRS = [
141610
- join127(homedir35(), ".config", "opencode"),
141611
- join127(homedir35(), ".config", "oh-my-openagent"),
141612
- join127(homedir35(), ".omo"),
141613
- join127(homedir35(), ".opencode")
141944
+ join129(homedir36(), ".config", "opencode"),
141945
+ join129(homedir36(), ".config", "oh-my-openagent"),
141946
+ join129(homedir36(), ".omo"),
141947
+ join129(homedir36(), ".opencode")
141614
141948
  ];
141615
141949
  function isWithinAllowedPaths(filePath, projectRoot) {
141616
141950
  if (isWithinProject(filePath, projectRoot))
@@ -141628,7 +141962,7 @@ function resolvePromptAppend(promptAppend, configDir) {
141628
141962
  let filePath;
141629
141963
  try {
141630
141964
  const decoded = decodeURIComponent(encoded);
141631
- const expanded = decoded.startsWith("~/") ? decoded.replace(/^~\//, `${homedir35()}/`) : decoded;
141965
+ const expanded = decoded.startsWith("~/") ? decoded.replace(/^~\//, `${homedir36()}/`) : decoded;
141632
141966
  filePath = isAbsolute20(expanded) ? expanded : resolve38(configDir ?? process.cwd(), expanded);
141633
141967
  } catch (error) {
141634
141968
  if (!(error instanceof Error)) {
@@ -141646,7 +141980,7 @@ function resolvePromptAppend(promptAppend, configDir) {
141646
141980
  });
141647
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/)]`;
141648
141982
  }
141649
- if (!existsSync109(filePath)) {
141983
+ if (!existsSync110(filePath)) {
141650
141984
  return `[WARNING: Could not resolve file URI: ${promptAppend}]`;
141651
141985
  }
141652
141986
  try {
@@ -143138,28 +143472,6 @@ function applyEnvironmentContext(config, directory, options = {}) {
143138
143472
  return { ...config, prompt: config.prompt + envContext };
143139
143473
  }
143140
143474
 
143141
- // packages/omo-opencode/src/agents/builtin-agents/model-resolution.ts
143142
- function applyModelResolution(input) {
143143
- const { uiSelectedModel, userModel, requirement, availableModels, systemDefaultModel } = input;
143144
- return resolveModelPipeline2({
143145
- intent: { uiSelectedModel, userModel },
143146
- constraints: { availableModels },
143147
- policy: { fallbackChain: requirement?.fallbackChain, systemDefaultModel }
143148
- });
143149
- }
143150
- function getFirstFallbackModel(requirement) {
143151
- const entry = requirement?.fallbackChain?.[0];
143152
- if (!entry || entry.providers.length === 0)
143153
- return;
143154
- const provider = entry.providers[0];
143155
- const transformedModel = transformModelForProvider(provider, entry.model);
143156
- return {
143157
- model: `${provider}/${transformedModel}`,
143158
- provenance: "provider-fallback",
143159
- variant: entry.variant
143160
- };
143161
- }
143162
-
143163
143475
  // packages/omo-opencode/src/agents/builtin-agents/general-agents.ts
143164
143476
  init_logger2();
143165
143477
  function collectPendingBuiltinAgents(input) {
@@ -143256,6 +143568,33 @@ function collectPendingBuiltinAgents(input) {
143256
143568
 
143257
143569
  // packages/omo-opencode/src/agents/builtin-agents/sisyphus-agent.ts
143258
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
143259
143598
  function maybeCreateSisyphusConfig(input) {
143260
143599
  const {
143261
143600
  disabledAgents,
@@ -143311,6 +143650,16 @@ function maybeCreateSisyphusConfig(input) {
143311
143650
  sisyphusConfig = applyEnvironmentContext(sisyphusConfig, directory, {
143312
143651
  disableOmoEnv
143313
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
+ });
143314
143663
  return sisyphusConfig;
143315
143664
  }
143316
143665
 
@@ -143607,7 +143956,7 @@ function isDisabledConfigSkillEntryName(name, disabledSkills) {
143607
143956
  return disabledSkills.has(normalizeSkillAliasName2(name));
143608
143957
  }
143609
143958
  async function createSkillContext(args) {
143610
- const { directory, pluginConfig } = args;
143959
+ const { directory, pluginConfig, hostSkills } = args;
143611
143960
  const browserProvider = pluginConfig.browser_automation_engine?.provider ?? "playwright";
143612
143961
  const disabledSkills = collectDisabledSkillAliases(pluginConfig);
143613
143962
  const builtinSkills = resolveActiveBuiltinSkills({
@@ -143617,7 +143966,7 @@ async function createSkillContext(args) {
143617
143966
  systemMcpNames: getSystemMcpServerNames()
143618
143967
  });
143619
143968
  const includeClaudeSkills = pluginConfig.claude_code?.skills !== false;
143620
- const hostSkillConfig = adaptHostSkillConfig(readOpencodeConfigSkills(directory));
143969
+ const hostSkillConfig = adaptHostSkillConfig(hostSkills ?? readOpencodeConfigSkills(directory));
143621
143970
  const [
143622
143971
  configSourceSkills,
143623
143972
  hostConfigSkills,
@@ -144301,7 +144650,7 @@ async function applyAgentConfig(params) {
144301
144650
  }
144302
144651
  // packages/claude-code-compat-core/src/features/claude-code-command-loader/loader.ts
144303
144652
  import { promises as fs23 } from "fs";
144304
- import { join as join128, basename as basename24 } from "path";
144653
+ import { join as join130, basename as basename24 } from "path";
144305
144654
 
144306
144655
  // packages/claude-code-compat-core/src/features/claude-code-command-loader/loader-cache.ts
144307
144656
  var commandLoaderCache = new Map;
@@ -144349,7 +144698,7 @@ async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix
144349
144698
  continue;
144350
144699
  if (entry.name.startsWith("."))
144351
144700
  continue;
144352
- const subDirPath = join128(commandsDir, entry.name);
144701
+ const subDirPath = join130(commandsDir, entry.name);
144353
144702
  const subPrefix = prefix ? `${prefix}/${entry.name}` : entry.name;
144354
144703
  const subCommands = await loadCommandsFromDir(subDirPath, scope, visited, subPrefix);
144355
144704
  commands.push(...subCommands);
@@ -144357,7 +144706,7 @@ async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix
144357
144706
  }
144358
144707
  if (!isMarkdownFile(entry))
144359
144708
  continue;
144360
- const commandPath = join128(commandsDir, entry.name);
144709
+ const commandPath = join130(commandsDir, entry.name);
144361
144710
  const baseCommandName = basename24(entry.name, ".md");
144362
144711
  const commandName = prefix ? `${prefix}/${baseCommandName}` : baseCommandName;
144363
144712
  try {
@@ -144420,12 +144769,12 @@ function commandsToRecord(commands) {
144420
144769
  return result;
144421
144770
  }
144422
144771
  async function loadUserCommands() {
144423
- const userCommandsDir = join128(getClaudeConfigDir3(), "commands");
144772
+ const userCommandsDir = join130(getClaudeConfigDir3(), "commands");
144424
144773
  const commands = await loadCommandsFromDir(userCommandsDir, "user");
144425
144774
  return commandsToRecord(commands);
144426
144775
  }
144427
144776
  async function loadProjectCommands(directory) {
144428
- const projectCommandsDir = join128(directory ?? process.cwd(), ".claude", "commands");
144777
+ const projectCommandsDir = join130(directory ?? process.cwd(), ".claude", "commands");
144429
144778
  const commands = await loadCommandsFromDir(projectCommandsDir, "project");
144430
144779
  return commandsToRecord(commands);
144431
144780
  }
@@ -144602,8 +144951,8 @@ var grep_app = {
144602
144951
 
144603
144952
  // packages/omo-opencode/src/mcp/codegraph.ts
144604
144953
  init_src();
144605
- import { existsSync as existsSync110 } from "fs";
144606
- import { join as join129 } from "path";
144954
+ import { existsSync as existsSync111 } from "fs";
144955
+ import { join as join131 } from "path";
144607
144956
 
144608
144957
  // packages/omo-opencode/src/mcp/runtime-executable.ts
144609
144958
  init_bun_which_shim();
@@ -144650,7 +144999,7 @@ function createWhichResolver(resolveExecutable) {
144650
144999
  function provisionedBinFromInstallDir2(installDir, fileExists2) {
144651
145000
  if (installDir === undefined)
144652
145001
  return null;
144653
- const candidate = join129(installDir, "bin", process.platform === "win32" ? "codegraph.cmd" : "codegraph");
145002
+ const candidate = join131(installDir, "bin", process.platform === "win32" ? "codegraph.cmd" : "codegraph");
144654
145003
  return fileExists2(candidate) ? candidate : null;
144655
145004
  }
144656
145005
  function codegraphEnvForConfig(config, homeDir) {
@@ -144661,7 +145010,7 @@ function createCodegraphMcpConfig(options = {}) {
144661
145010
  const env2 = options.env ?? process.env;
144662
145011
  const resolveExecutable = options.resolveExecutable ?? resolveRuntimeExecutable;
144663
145012
  const which2 = createWhichResolver(resolveExecutable);
144664
- const fileExists2 = options.fileExists ?? existsSync110;
145013
+ const fileExists2 = options.fileExists ?? existsSync111;
144665
145014
  const resolvedCommand = resolveCodegraphCommand({
144666
145015
  env: env2,
144667
145016
  fileExists: fileExists2,
@@ -144687,9 +145036,9 @@ function createCodegraphMcpConfig(options = {}) {
144687
145036
  }
144688
145037
 
144689
145038
  // packages/omo-opencode/src/mcp/lsp.ts
144690
- import { existsSync as existsSync111 } from "fs";
144691
- import { delimiter as delimiter2, dirname as dirname43, resolve as resolve40 } from "path";
144692
- 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";
144693
145042
 
144694
145043
  // packages/omo-opencode/src/mcp/cli-suffix.ts
144695
145044
  function normalizeCliPath(path22) {
@@ -144775,7 +145124,7 @@ var LSP_BOOTSTRAP_SCRIPT = [
144775
145124
  ].join(";");
144776
145125
  function getModuleDirectory(moduleUrl) {
144777
145126
  try {
144778
- return dirname43(fileURLToPath7(moduleUrl));
145127
+ return dirname44(fileURLToPath8(moduleUrl));
144779
145128
  } catch (error) {
144780
145129
  if (!(error instanceof Error))
144781
145130
  throw error;
@@ -144799,7 +145148,7 @@ function createBootstrapCandidate(root, pathExists, resolveExecutable) {
144799
145148
  };
144800
145149
  }
144801
145150
  function resolveLspCommand(options = {}) {
144802
- const pathExists = options.exists ?? existsSync111;
145151
+ const pathExists = options.exists ?? existsSync112;
144803
145152
  const resolveExecutable = options.resolveExecutable ?? resolveRuntimeExecutable;
144804
145153
  const moduleDirectory = getModuleDirectory(options.moduleUrl ?? import.meta.url);
144805
145154
  const candidates = moduleDirectory ? createAncestorCliCandidates({
@@ -145435,6 +145784,37 @@ function createTeamModeToolsRecord(args) {
145435
145784
  };
145436
145785
  }
145437
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
+
145438
145818
  // packages/omo-opencode/src/plugin/tool-registry-core-tools.ts
145439
145819
  function createCoreTools(args) {
145440
145820
  const { ctx, pluginConfig, managers, skillContext, availableCategories, factories } = args;
@@ -145488,9 +145868,14 @@ function createCoreTools(args) {
145488
145868
  }
145489
145869
  });
145490
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
+ });
145491
145876
  const skillMcpTool = factories.createSkillMcpTool({
145492
145877
  manager: managers.skillMcpManager,
145493
- getLoadedSkills: () => skillContext.mergedSkills,
145878
+ getLoadedSkills: getLoadedSkillsForMcp,
145494
145879
  getSessionID: getSessionIDForMcp
145495
145880
  });
145496
145881
  const commands2 = factories.discoverCommandsSync(ctx.directory, {
@@ -147728,8 +148113,8 @@ function createChatHeadersHandler(args) {
147728
148113
  }
147729
148114
 
147730
148115
  // packages/omo-opencode/src/plugin/ultrawork-db-model-override.ts
147731
- import { join as join130 } from "path";
147732
- import { existsSync as existsSync112 } from "fs";
148116
+ import { join as join132 } from "path";
148117
+ import { existsSync as existsSync113 } from "fs";
147733
148118
  async function importBunSqlite() {
147734
148119
  if (typeof globalThis.Bun === "undefined") {
147735
148120
  return null;
@@ -147745,7 +148130,7 @@ async function importBunSqlite() {
147745
148130
  }
147746
148131
  }
147747
148132
  function getDbPath() {
147748
- return join130(getDataDir(), "opencode", "opencode.db");
148133
+ return join132(getDataDir(), "opencode", "opencode.db");
147749
148134
  }
147750
148135
  var MAX_MICROTASK_RETRIES = 10;
147751
148136
  function logCaughtDbError(message, metadata, error) {
@@ -147848,7 +148233,7 @@ async function scheduleDeferredModelOverride(messageId, targetModel, variant) {
147848
148233
  return;
147849
148234
  }
147850
148235
  const dbPath = getDbPath();
147851
- if (!existsSync112(dbPath)) {
148236
+ if (!existsSync113(dbPath)) {
147852
148237
  log2("[ultrawork-db-override] DB not found, skipping deferred override");
147853
148238
  return;
147854
148239
  }
@@ -148549,6 +148934,7 @@ function isFalsy(value) {
148549
148934
  var ULTRAWORK_MODE_TAG = "<ultrawork-mode>";
148550
148935
  function createSystemTransformHandler(defaultMode, getUltraworkMessage2, env2 = process.env) {
148551
148936
  return async (input, output) => {
148937
+ reconcileSisyphusRuntimePrompt(output.system, input.model?.id);
148552
148938
  const sparkshellAwareness = getSparkShellRuntimeAwareness(env2);
148553
148939
  if (sparkshellAwareness.length > 0 && !output.system.some(hasSparkShellRuntimeAwareness)) {
148554
148940
  output.system.push(sparkshellAwareness);
@@ -149953,6 +150339,7 @@ function createToolDefinitionHandler(args) {
149953
150339
  }
149954
150340
 
149955
150341
  // packages/omo-opencode/src/plugin/tool-execute-after.ts
150342
+ init_src();
149956
150343
  init_logger2();
149957
150344
  var VERIFICATION_ATTEMPT_PATTERN = /<ulw_verification_attempt_id>(.*?)<\/ulw_verification_attempt_id>/i;
149958
150345
  var METADATA_LINKED_TOOLS = new Set([
@@ -149978,12 +150365,25 @@ function getPluginDirectory(ctx) {
149978
150365
  function expectsRecoverableMetadata(tool3) {
149979
150366
  return METADATA_LINKED_TOOLS.has(tool3);
149980
150367
  }
150368
+ function appendCodegraphInitGuidance(input, output, cwd) {
150369
+ const guidance2 = buildCodegraphInitGuidanceForToolResult({
150370
+ cwd: cwd ?? undefined,
150371
+ toolName: input.tool,
150372
+ toolOutput: output.output
150373
+ });
150374
+ if (guidance2 === null || output.output.includes(guidance2))
150375
+ return;
150376
+ output.output = `${output.output}
150377
+
150378
+ ${guidance2}`;
150379
+ }
149981
150380
  function createToolExecuteAfterHandler3(args) {
149982
150381
  const { ctx, hooks } = args;
149983
150382
  const log8 = args.log ?? log2;
149984
150383
  return async (input, output) => {
149985
150384
  if (!output)
149986
150385
  return;
150386
+ appendCodegraphInitGuidance(input, output, getPluginDirectory(ctx));
149987
150387
  const hookInput = {
149988
150388
  tool: input.tool,
149989
150389
  sessionID: input.sessionID,
@@ -150379,7 +150779,7 @@ function createPluginInterface(args) {
150379
150779
 
150380
150780
  // packages/omo-opencode/src/plugin-config/layered-config-loader.ts
150381
150781
  import * as fs25 from "fs";
150382
- import { homedir as homedir36 } from "os";
150782
+ import { homedir as homedir37 } from "os";
150383
150783
  import * as path27 from "path";
150384
150784
 
150385
150785
  // packages/omo-opencode/src/config/schema/agent-names.ts
@@ -150611,6 +151011,7 @@ var ClaudeCodeConfigSchema = z22.object({
150611
151011
  // packages/omo-opencode/src/config/schema/codegraph.ts
150612
151012
  import { z as z23 } from "zod";
150613
151013
  var CodegraphConfigSchema = z23.object({
151014
+ auto_init: z23.boolean().default(true),
150614
151015
  auto_provision: z23.boolean().default(true),
150615
151016
  enabled: z23.boolean().default(true),
150616
151017
  install_dir: z23.string().optional(),
@@ -150855,7 +151256,8 @@ var RuntimeFallbackConfigSchema = z39.object({
150855
151256
  max_fallback_attempts: z39.number().min(1).max(20).optional(),
150856
151257
  cooldown_seconds: z39.number().min(0).optional(),
150857
151258
  timeout_seconds: z39.number().min(0).optional(),
150858
- notify_on_fallback: z39.boolean().optional()
151259
+ notify_on_fallback: z39.boolean().optional(),
151260
+ restore_primary_after_cooldown: z39.boolean().optional()
150859
151261
  });
150860
151262
 
150861
151263
  // packages/team-core/src/config.ts
@@ -151221,7 +151623,7 @@ function loadConfigFromPath2(configPath, _ctx) {
151221
151623
 
151222
151624
  // packages/omo-opencode/src/plugin-config/layered-config-loader.ts
151223
151625
  function resolveHomeDirectory() {
151224
- return process.env.HOME ?? process.env.USERPROFILE ?? homedir36();
151626
+ return process.env.HOME ?? process.env.USERPROFILE ?? homedir37();
151225
151627
  }
151226
151628
  function resolveConfigPathAfterLegacyMigration(detectedPath) {
151227
151629
  if (!path27.basename(detectedPath).startsWith(LEGACY_CONFIG_BASENAME)) {
@@ -151421,9 +151823,9 @@ function createSessionCompactingHandler(hooks2) {
151421
151823
  });
151422
151824
  await runCompactionStep("compactionContextInjector.inject", input.sessionID, () => {
151423
151825
  const inject = hooks2.compactionContextInjector?.inject;
151424
- const context = inject ? inject(input.sessionID) : undefined;
151425
- if (context) {
151426
- output.context.push(context);
151826
+ const context2 = inject ? inject(input.sessionID) : undefined;
151827
+ if (context2) {
151828
+ output.context.push(context2);
151427
151829
  }
151428
151830
  });
151429
151831
  };