oh-my-opencode 5.0.0-beta.30 → 5.0.0-beta.32

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 (278) hide show
  1. package/dist/cli/index.js +178 -37
  2. package/dist/cli-node/index.js +178 -37
  3. package/dist/config/schema/background-task.d.ts +1 -0
  4. package/dist/config/schema/oh-my-opencode-config.d.ts +1 -0
  5. package/dist/features/background-agent/constants.d.ts +0 -7
  6. package/dist/features/background-agent/manager.d.ts +2 -1
  7. package/dist/features/background-agent/parent-wake-dispatched-tracker.d.ts +0 -1
  8. package/dist/features/background-agent/parent-wake-notifier-types.d.ts +1 -1
  9. package/dist/features/background-agent/parent-wake-prompt-dispatch.d.ts +1 -1
  10. package/dist/features/background-agent/parent-wake-session-inspector.d.ts +1 -1
  11. package/dist/features/background-agent/subagent-spawn-limits.d.ts +8 -0
  12. package/dist/features/monitor/manager-internals.d.ts +1 -1
  13. package/dist/features/monitor/output-injector-types.d.ts +1 -1
  14. package/dist/features/task-toast-manager/manager.d.ts +0 -24
  15. package/dist/features/team-mode/tools/messaging-live-delivery-recipient.d.ts +1 -0
  16. package/dist/features/team-mode/tools/messaging-runtime.d.ts +1 -0
  17. package/dist/hooks/anthropic-context-window-limit-recovery/message-storage-directory.d.ts +0 -3
  18. package/dist/hooks/anthropic-context-window-limit-recovery/state.d.ts +1 -0
  19. package/dist/hooks/anthropic-context-window-limit-recovery/storage/empty-messages.d.ts +0 -1
  20. package/dist/hooks/anthropic-context-window-limit-recovery/tool-result-storage.d.ts +11 -0
  21. package/dist/hooks/claude-code-hooks/session-hook-state.d.ts +1 -0
  22. package/dist/hooks/claude-code-hooks/stop.d.ts +2 -0
  23. package/dist/hooks/claude-code-hooks/todo.d.ts +0 -1
  24. package/dist/hooks/claude-code-hooks/transcript.d.ts +2 -0
  25. package/dist/hooks/fsync-skip-warning/index.d.ts +4 -0
  26. package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +1 -0
  27. package/dist/hooks/hashline-edit-diff-enhancer/pending-captures.d.ts +13 -0
  28. package/dist/hooks/keyword-detector/hook.d.ts +7 -0
  29. package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +0 -1
  30. package/dist/hooks/model-fallback/hook.d.ts +1 -1
  31. package/dist/index.js +681 -273
  32. package/dist/oh-my-opencode.schema.json +5 -0
  33. package/dist/plugin-dispose.d.ts +3 -0
  34. package/dist/shared/agent-tool-restrictions.d.ts +0 -1
  35. package/dist/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  36. package/dist/tools/delegate-task/sync-session-cleanup.d.ts +3 -0
  37. package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -0
  38. package/dist/tools/delegate-task/types.d.ts +1 -0
  39. package/dist/tools/session-manager/directory-filter.d.ts +2 -0
  40. package/dist/tui.js +148 -9
  41. package/package.json +16 -15
  42. package/packages/git-bash-mcp/dist/cli.js +1 -0
  43. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +47 -19
  44. package/packages/lsp-core/src/lsp/client-diagnostics-pull-timeout.test.ts +64 -0
  45. package/packages/lsp-core/src/lsp/client-wrapper.test.ts +97 -0
  46. package/packages/lsp-core/src/lsp/client-wrapper.ts +21 -6
  47. package/packages/lsp-core/src/lsp/client.ts +6 -3
  48. package/packages/lsp-core/src/lsp/constants.ts +5 -0
  49. package/packages/lsp-core/src/lsp/controlled-clock-test-support.ts +61 -0
  50. package/packages/lsp-core/src/lsp/errors.ts +15 -0
  51. package/packages/lsp-core/src/lsp/fixtures/workspace-edit-server.mjs +10 -3
  52. package/packages/lsp-core/src/lsp/manager-lifecycle.test.ts +262 -0
  53. package/packages/lsp-core/src/lsp/manager.ts +106 -13
  54. package/packages/lsp-core/src/lsp/timer-provider.ts +13 -0
  55. package/packages/lsp-core/src/lsp/transport-request-timeout.test.ts +73 -0
  56. package/packages/lsp-core/src/lsp/transport.ts +7 -2
  57. package/packages/lsp-core/src/lsp/workspace-document-state.test.ts +84 -1
  58. package/packages/lsp-core/src/lsp/workspace-document-state.ts +30 -11
  59. package/packages/lsp-core/src/lsp/workspace-markers.ts +18 -1
  60. package/packages/lsp-core/src/mcp.ts +3 -0
  61. package/packages/lsp-core/src/tools/parameters.test.ts +51 -0
  62. package/packages/lsp-daemon/dist/cli.js +155 -34
  63. package/packages/lsp-daemon/dist/client.js +155 -34
  64. package/packages/lsp-daemon/dist/index.js +155 -34
  65. package/packages/lsp-daemon/dist/proxy.js +3 -0
  66. package/packages/lsp-tools-mcp/dist/cli.js +155 -34
  67. package/packages/lsp-tools-mcp/dist/lsp/manager.js +134 -28
  68. package/packages/lsp-tools-mcp/dist/mcp.js +155 -34
  69. package/packages/lsp-tools-mcp/dist/tools.js +154 -34
  70. package/packages/lsp-tools-mcp/package.json +1 -1
  71. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  72. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  73. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  74. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +17 -2
  75. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +17 -2
  76. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  77. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +12 -0
  78. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable-idle.test.ts +47 -0
  79. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  80. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  81. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  82. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  83. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  84. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  85. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
  86. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +152 -34
  87. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  88. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  89. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  90. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  91. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  92. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  93. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  94. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  95. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -4
  96. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +489 -4
  97. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  98. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -2
  99. package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +30 -14
  100. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +4 -0
  101. package/packages/omo-codex/plugin/components/ultrawork/src/directive.ts +5 -2
  102. package/packages/omo-codex/plugin/components/ultrawork/test/directive-source.test.ts +14 -8
  103. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +12 -1
  104. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +2 -2
  105. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  106. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +5 -2
  107. package/packages/omo-codex/plugin/components/ulw-loop/README.md +1 -0
  108. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +9 -0
  109. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +14 -0
  110. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +10 -1
  111. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.d.ts +8 -0
  112. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +113 -0
  113. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +9 -5
  114. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +2 -1
  115. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +1 -1
  116. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +1 -0
  117. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +2 -0
  118. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +856 -347
  119. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +2 -0
  120. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +27 -6
  121. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +13 -0
  122. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +14 -0
  123. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +17 -9
  124. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +17 -2
  125. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.d.ts +13 -0
  126. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.js +19 -0
  127. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +2 -0
  128. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +53 -0
  129. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.d.ts +9 -0
  130. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +85 -0
  131. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +1 -1
  132. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
  133. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +41 -102
  134. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +4 -2
  135. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +185 -14
  136. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.d.ts +6 -0
  137. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.js +33 -0
  138. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +18 -0
  139. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +65 -0
  140. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  141. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  142. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +17 -0
  143. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +7 -0
  144. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +25 -1
  145. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +127 -0
  146. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +10 -12
  147. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +2 -1
  148. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +1 -0
  149. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +2 -0
  150. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +34 -5
  151. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +23 -0
  152. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +19 -9
  153. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +18 -3
  154. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-missing-recovery.ts +27 -0
  155. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +57 -0
  156. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +103 -0
  157. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +1 -1
  158. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +54 -123
  159. package/packages/omo-codex/plugin/components/ulw-loop/src/review-blockers.ts +4 -2
  160. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +187 -12
  161. package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +36 -0
  162. package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +95 -0
  163. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +107 -1
  164. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +92 -0
  165. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-status-next-actions.test.ts +183 -0
  166. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +35 -0
  167. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +7 -3
  168. package/packages/omo-codex/plugin/components/ulw-loop/test/guided-recovery.test.ts +105 -0
  169. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate.test.ts +101 -0
  170. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +46 -2
  171. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-senpi-surface.test.ts +131 -0
  172. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +5 -0
  173. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +318 -1
  174. package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -0
  175. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +9 -3
  176. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  177. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  178. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  179. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  180. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  181. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  182. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  183. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  184. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  185. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  186. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  187. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  188. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  189. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  190. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  191. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  192. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  193. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  194. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +1 -1
  195. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  196. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  197. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  198. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  199. package/packages/omo-codex/plugin/package-lock.json +13 -13
  200. package/packages/omo-codex/plugin/package.json +1 -1
  201. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +31 -2
  202. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  203. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +17 -0
  204. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +11 -1
  205. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +13 -0
  206. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +5 -2
  207. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2 -2
  208. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  209. package/dist/features/builtin-skills/index.d.ts +0 -1
  210. package/dist/features/builtin-skills/skill-file-loader.d.ts +0 -1
  211. package/dist/features/builtin-skills/skills/agent-browser-skill.d.ts +0 -1
  212. package/dist/features/builtin-skills/skills/agent-browser-template.d.ts +0 -1
  213. package/dist/features/builtin-skills/skills/debugging.d.ts +0 -1
  214. package/dist/features/builtin-skills/skills/dev-browser.d.ts +0 -1
  215. package/dist/features/builtin-skills/skills/frontend.d.ts +0 -1
  216. package/dist/features/builtin-skills/skills/git-master-sections/commit-atomic-planning.d.ts +0 -1
  217. package/dist/features/builtin-skills/skills/git-master-sections/commit-context-analysis.d.ts +0 -1
  218. package/dist/features/builtin-skills/skills/git-master-sections/commit-execution-verification.d.ts +0 -1
  219. package/dist/features/builtin-skills/skills/git-master-sections/commit-workflow.d.ts +0 -1
  220. package/dist/features/builtin-skills/skills/git-master-sections/history-search-workflow.d.ts +0 -1
  221. package/dist/features/builtin-skills/skills/git-master-sections/overview.d.ts +0 -1
  222. package/dist/features/builtin-skills/skills/git-master-sections/quick-reference.d.ts +0 -1
  223. package/dist/features/builtin-skills/skills/git-master-sections/rebase-workflow.d.ts +0 -1
  224. package/dist/features/builtin-skills/skills/git-master-skill-metadata.d.ts +0 -1
  225. package/dist/features/builtin-skills/skills/git-master.d.ts +0 -1
  226. package/dist/features/builtin-skills/skills/index.d.ts +0 -1
  227. package/dist/features/builtin-skills/skills/init-deep.d.ts +0 -1
  228. package/dist/features/builtin-skills/skills/playwright-cli.d.ts +0 -1
  229. package/dist/features/builtin-skills/skills/playwright-mcp-skill.d.ts +0 -1
  230. package/dist/features/builtin-skills/skills/playwright.d.ts +0 -1
  231. package/dist/features/builtin-skills/skills/remove-ai-slops.d.ts +0 -1
  232. package/dist/features/builtin-skills/skills/review-work.d.ts +0 -1
  233. package/dist/features/builtin-skills/skills/security-research.d.ts +0 -1
  234. package/dist/features/builtin-skills/skills/security-review.d.ts +0 -1
  235. package/dist/features/builtin-skills/skills/team-mode.d.ts +0 -1
  236. package/dist/features/builtin-skills/skills/visual-qa.d.ts +0 -1
  237. package/dist/features/builtin-skills/skills.d.ts +0 -1
  238. package/dist/features/builtin-skills/types.d.ts +0 -1
  239. package/dist/features/claude-code-plugin-loader/agent-loader.d.ts +0 -1
  240. package/dist/features/claude-code-plugin-loader/command-loader.d.ts +0 -1
  241. package/dist/features/claude-code-plugin-loader/discovery-core.d.ts +0 -1
  242. package/dist/features/claude-code-plugin-loader/discovery-paths.d.ts +0 -1
  243. package/dist/features/claude-code-plugin-loader/discovery.d.ts +0 -1
  244. package/dist/features/claude-code-plugin-loader/hook-loader.d.ts +0 -1
  245. package/dist/features/claude-code-plugin-loader/index.d.ts +0 -1
  246. package/dist/features/claude-code-plugin-loader/install-path-resolver.d.ts +0 -1
  247. package/dist/features/claude-code-plugin-loader/installed-plugin-database.d.ts +0 -1
  248. package/dist/features/claude-code-plugin-loader/loaded-plugin.d.ts +0 -1
  249. package/dist/features/claude-code-plugin-loader/loader.d.ts +0 -1
  250. package/dist/features/claude-code-plugin-loader/mcp-server-loader.d.ts +0 -1
  251. package/dist/features/claude-code-plugin-loader/plugin-key.d.ts +0 -1
  252. package/dist/features/claude-code-plugin-loader/plugin-manifest.d.ts +0 -1
  253. package/dist/features/claude-code-plugin-loader/plugin-path-resolver.d.ts +0 -1
  254. package/dist/features/claude-code-plugin-loader/plugin-settings.d.ts +0 -1
  255. package/dist/features/claude-code-plugin-loader/scope-filter.d.ts +0 -1
  256. package/dist/features/claude-code-plugin-loader/skill-loader.d.ts +0 -1
  257. package/dist/features/claude-code-plugin-loader/types.d.ts +0 -1
  258. package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +0 -11
  259. package/dist/hooks/ralph-loop/loop-session-recovery.d.ts +0 -7
  260. package/dist/shared/prompt-async-gate/message-inspection-error.d.ts +0 -1
  261. package/dist/shared/prompt-async-gate/pending-tool-turn.d.ts +0 -1
  262. package/dist/shared/prompt-async-gate/prompt-message-state.d.ts +0 -1
  263. package/dist/shared/prompt-async-gate/queue.d.ts +0 -1
  264. package/dist/shared/prompt-async-gate/recent-dispatches.d.ts +0 -1
  265. package/dist/shared/prompt-async-gate/reservations.d.ts +0 -1
  266. package/dist/shared/prompt-async-gate/semantic-dedupe.d.ts +0 -1
  267. package/dist/shared/prompt-async-gate/session-idle-dispatch.d.ts +0 -1
  268. package/dist/shared/prompt-async-gate/timing.d.ts +0 -1
  269. package/dist/shared/prompt-async-gate/types.d.ts +0 -1
  270. package/dist/tools/call-omo-agent/message-storage-directory.d.ts +0 -1
  271. package/dist/tools/delegate-task/model-string-parser.d.ts +0 -1
  272. package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
  273. package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
  274. package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
  275. package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
  276. package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
  277. package/packages/omo-codex/plugin/components/ultrawork/directive.md +0 -483
  278. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +0 -490
package/dist/index.js CHANGED
@@ -2816,10 +2816,11 @@ var init_js_yaml = __esm(() => {
2816
2816
  function parseFrontmatter(content, options = {}) {
2817
2817
  if (options.mode === "rule")
2818
2818
  return parseRuleFrontmatter(content);
2819
+ const normalized = stripBom(content);
2819
2820
  const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n?---\r?\n([\s\S]*)$/;
2820
- const match = content.match(frontmatterRegex);
2821
+ const match = normalized.match(frontmatterRegex);
2821
2822
  if (!match) {
2822
- return { data: {}, body: content, hadFrontmatter: false, parseError: false };
2823
+ return { data: {}, body: normalized, hadFrontmatter: false, parseError: false };
2823
2824
  }
2824
2825
  const yamlContent = match[1];
2825
2826
  const body = match[2];
@@ -3064,17 +3065,20 @@ function findNearestExistingAncestor(resolvedPath) {
3064
3065
  }
3065
3066
  return candidatePath;
3066
3067
  }
3068
+ function realpathNativeOrFallback(pathToNormalize) {
3069
+ try {
3070
+ return realpathSync2.native(pathToNormalize);
3071
+ } catch {
3072
+ return pathToNormalize;
3073
+ }
3074
+ }
3067
3075
  function toCanonicalPath(pathToNormalize) {
3068
3076
  const resolvedPath = resolve(pathToNormalize);
3069
3077
  if (existsSync(resolvedPath)) {
3070
- try {
3071
- return normalize(realpathSync2.native(resolvedPath));
3072
- } catch {
3073
- return normalize(resolvedPath);
3074
- }
3078
+ return normalize(realpathNativeOrFallback(resolvedPath));
3075
3079
  }
3076
3080
  const nearestExistingAncestor = findNearestExistingAncestor(resolvedPath);
3077
- const canonicalAncestor = existsSync(nearestExistingAncestor) ? realpathSync2.native(nearestExistingAncestor) : nearestExistingAncestor;
3081
+ const canonicalAncestor = existsSync(nearestExistingAncestor) ? realpathNativeOrFallback(nearestExistingAncestor) : nearestExistingAncestor;
3078
3082
  const relativePathFromAncestor = relative(nearestExistingAncestor, resolvedPath);
3079
3083
  return normalize(join(canonicalAncestor, relativePathFromAncestor || basename(resolvedPath)));
3080
3084
  }
@@ -3153,7 +3157,7 @@ function transformToolName(toolName) {
3153
3157
  if (lower in SPECIAL_TOOL_MAPPINGS) {
3154
3158
  return SPECIAL_TOOL_MAPPINGS[lower];
3155
3159
  }
3156
- if (trimmed.includes("-") || trimmed.includes("_")) {
3160
+ if (/[-_\s]/.test(trimmed)) {
3157
3161
  return toPascalCase(trimmed);
3158
3162
  }
3159
3163
  return trimmed.charAt(0).toUpperCase() + trimmed.slice(1);
@@ -5449,7 +5453,7 @@ var init_git_master = __esm(() => {
5449
5453
 
5450
5454
  // packages/omo-config-core/src/schema/memory.ts
5451
5455
  import * as z8 from "zod";
5452
- var OmoMemoryReflectionTriggerSchema, OmoMemoryReflectionSchema, OmoMemorySyncSchema, OmoMemorySearchSchema, OmoMemoryNudgeSchema, OmoMemoryFactsSchema, OmoMemoryDreamSchema, OmoMemoryPeopleSchema, OmoMemorySoulSchema, OmoMemoryWriteNoticeSchema, OmoMemoryReflectionTriggerLayerSchema, OmoMemoryReflectionLayerSchema, OmoMemorySyncLayerSchema, OmoMemorySearchLayerSchema, OmoMemoryNudgeLayerSchema, OmoMemoryFactsLayerSchema, OmoMemoryDreamLayerSchema, OmoMemoryPeopleLayerSchema, OmoMemorySoulLayerSchema, OmoMemoryWriteNoticeLayerSchema, OmoMemoryAgentOverridesSchema, OmoMemorySettingsSchema, OmoMemorySettingsLayerSchema;
5456
+ var OmoMemoryReflectionTriggerSchema, OmoMemoryReflectionSchema, OmoMemorySyncSchema, OmoMemorySearchSchema, OmoMemoryRecallSchema, OmoMemoryNudgeSchema, OmoMemoryFactsSchema, OmoMemoryDreamSchema, OmoMemoryPeopleSchema, OmoMemorySoulSchema, OmoMemoryWriteNoticeSchema, OmoMemoryReflectionTriggerLayerSchema, OmoMemoryReflectionLayerSchema, OmoMemorySyncLayerSchema, OmoMemorySearchLayerSchema, OmoMemoryRecallLayerSchema, OmoMemoryNudgeLayerSchema, OmoMemoryFactsLayerSchema, OmoMemoryDreamLayerSchema, OmoMemoryPeopleLayerSchema, OmoMemorySoulLayerSchema, OmoMemoryWriteNoticeLayerSchema, OmoMemoryAgentOverridesSchema, OmoMemorySettingsSchema, OmoMemorySettingsLayerSchema;
5453
5457
  var init_memory = __esm(() => {
5454
5458
  OmoMemoryReflectionTriggerSchema = z8.object({
5455
5459
  step_count: z8.number().int().nonnegative().default(25),
@@ -5470,6 +5474,10 @@ var init_memory = __esm(() => {
5470
5474
  OmoMemorySearchSchema = z8.object({
5471
5475
  enabled: z8.boolean().default(true)
5472
5476
  }).strict();
5477
+ OmoMemoryRecallSchema = z8.object({
5478
+ enabled: z8.boolean().default(true),
5479
+ max_items: z8.number().int().min(1).max(5).default(2)
5480
+ }).strict();
5473
5481
  OmoMemoryNudgeSchema = z8.object({
5474
5482
  enabled: z8.boolean().default(true),
5475
5483
  every_user_turns: z8.number().int().min(1).default(10)
@@ -5516,6 +5524,10 @@ var init_memory = __esm(() => {
5516
5524
  OmoMemorySearchLayerSchema = z8.object({
5517
5525
  enabled: z8.boolean().optional()
5518
5526
  }).strict();
5527
+ OmoMemoryRecallLayerSchema = z8.object({
5528
+ enabled: z8.boolean().optional(),
5529
+ max_items: z8.number().int().min(1).max(5).optional()
5530
+ }).strict();
5519
5531
  OmoMemoryNudgeLayerSchema = z8.object({
5520
5532
  enabled: z8.boolean().optional(),
5521
5533
  every_user_turns: z8.number().int().min(1).optional()
@@ -5555,6 +5567,7 @@ var init_memory = __esm(() => {
5555
5567
  write_notice: OmoMemoryWriteNoticeLayerSchema.optional(),
5556
5568
  sync: OmoMemorySyncLayerSchema.optional(),
5557
5569
  search: OmoMemorySearchLayerSchema.optional(),
5570
+ recall: OmoMemoryRecallLayerSchema.optional(),
5558
5571
  compile_warn_tokens: z8.number().int().positive().optional()
5559
5572
  }).strict();
5560
5573
  OmoMemorySettingsSchema = z8.object({
@@ -5584,6 +5597,7 @@ var init_memory = __esm(() => {
5584
5597
  write_notice: OmoMemoryWriteNoticeSchema.default({ enabled: true }),
5585
5598
  sync: OmoMemorySyncSchema.default({ enabled: true }),
5586
5599
  search: OmoMemorySearchSchema.default({ enabled: true }),
5600
+ recall: OmoMemoryRecallSchema.default({ enabled: true, max_items: 2 }),
5587
5601
  compile_warn_tokens: z8.number().int().positive().default(30000),
5588
5602
  agents: z8.record(z8.string(), OmoMemoryAgentOverridesSchema).default({})
5589
5603
  }).strict();
@@ -5600,6 +5614,7 @@ var init_memory = __esm(() => {
5600
5614
  write_notice: OmoMemoryWriteNoticeLayerSchema.optional(),
5601
5615
  sync: OmoMemorySyncLayerSchema.optional(),
5602
5616
  search: OmoMemorySearchLayerSchema.optional(),
5617
+ recall: OmoMemoryRecallLayerSchema.optional(),
5603
5618
  compile_warn_tokens: z8.number().int().positive().optional(),
5604
5619
  agents: z8.record(z8.string(), OmoMemoryAgentOverridesSchema).optional()
5605
5620
  }).strict();
@@ -5634,11 +5649,11 @@ function resolveOmoTaskSettings(input, resolveParallelism = availableParallelism
5634
5649
  const record8 = z10.record(z10.string(), z10.unknown()).parse(input);
5635
5650
  return OmoTaskSettingsSchema.parse({
5636
5651
  ...record8,
5637
- residency_max_children: record8["residency_max_children"] ?? Math.max(8, resolveParallelism() * 3),
5652
+ residency_max_children: record8["residency_max_children"] ?? Math.min(DEFAULT_RESIDENCY_MAX_CHILDREN, Math.max(8, resolveParallelism() * 2)),
5638
5653
  global_concurrency: record8["global_concurrency"] ?? Math.max(8, resolveParallelism() * 2)
5639
5654
  });
5640
5655
  }
5641
- var ResidencyMaxChildrenInputSchema, OmoTaskWaitSchema, OmoTaskTeamSettingsSchema, OmoTaskWarningsSchema, OmoTaskDagSettingsSchema, OmoTaskSettingsSchema, OmoTaskDagSettingsLayerSchema, OmoTaskWaitLayerSchema, OmoTaskTeamSettingsLayerSchema, OmoTaskWarningsLayerSchema, OmoTaskSettingsLayerSchema;
5656
+ var DEFAULT_RESIDENCY_MAX_CHILDREN = 16, ResidencyMaxChildrenInputSchema, OmoTaskWaitSchema, OmoTaskTeamSettingsSchema, OmoTaskWarningsSchema, OmoTaskDagSettingsSchema, OmoTaskSettingsSchema, OmoTaskDagSettingsLayerSchema, OmoTaskWaitLayerSchema, OmoTaskTeamSettingsLayerSchema, OmoTaskWarningsLayerSchema, OmoTaskSettingsLayerSchema;
5642
5657
  var init_task = __esm(() => {
5643
5658
  ResidencyMaxChildrenInputSchema = z10.union([z10.number().int().nonnegative(), z10.literal("unlimited")]);
5644
5659
  OmoTaskWaitSchema = z10.object({
@@ -7888,12 +7903,15 @@ function normalizeInputPath(absolutePath) {
7888
7903
  function isUnderPath(normalizedPath, normalizedParentPath) {
7889
7904
  return normalizedPath === normalizedParentPath || normalizedPath.startsWith(`${normalizedParentPath}/`);
7890
7905
  }
7906
+ function isOneDriveSegment(segment) {
7907
+ const lowercaseSegment = segment.toLowerCase();
7908
+ return lowercaseSegment === "onedrive" || lowercaseSegment.startsWith("onedrive - ");
7909
+ }
7891
7910
  function classifyPathEnvironment(absolutePath) {
7892
7911
  if (absolutePath.length === 0)
7893
7912
  return "unknown";
7894
7913
  const normalizedPath = normalizeInputPath(absolutePath);
7895
- const lowercasePath = normalizedPath.toLowerCase();
7896
- if (lowercasePath.includes("/onedrive") || lowercasePath.includes("/onedrive/")) {
7914
+ if (normalizedPath.split("/").some(isOneDriveSegment)) {
7897
7915
  return "onedrive";
7898
7916
  }
7899
7917
  if (normalizedPath.includes("/Library/Mobile Documents/")) {
@@ -11999,7 +12017,6 @@ function extractPromptFailureMessage(error) {
11999
12017
  try {
12000
12018
  return JSON.stringify(error);
12001
12019
  } catch (stringifyError) {
12002
- stringifyError instanceof Error;
12003
12020
  return "";
12004
12021
  }
12005
12022
  }
@@ -12160,7 +12177,7 @@ function validateParsedTarListing(totalLineCount, unparsedLines) {
12160
12177
  throw new Error(`zip entry listing failed: ${unparsedLines.length}/${totalLineCount} tar listing lines could not be parsed (fail-closed)`);
12161
12178
  }
12162
12179
  function parseTarListingOutput(stdout) {
12163
- const listingLines = stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
12180
+ const listingLines = stdout.split(/\r?\n/).filter((line) => line.trim().length > 0);
12164
12181
  if (listingLines.length === 0) {
12165
12182
  return [];
12166
12183
  }
@@ -19166,8 +19183,8 @@ var require_resolve = __commonJS(function(exports) {
19166
19183
  }
19167
19184
  return count;
19168
19185
  }
19169
- function getFullPath(resolver, id = "", normalize4) {
19170
- if (normalize4 !== false)
19186
+ function getFullPath(resolver, id = "", normalize5) {
19187
+ if (normalize5 !== false)
19171
19188
  id = normalizeId(id);
19172
19189
  const p = resolver.parse(id);
19173
19190
  return _getFullPath(resolver, p);
@@ -20510,25 +20527,25 @@ var require_schemes = __commonJS(function(exports, module) {
20510
20527
  var require_fast_uri = __commonJS(function(exports, module) {
20511
20528
  var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils2();
20512
20529
  var { SCHEMES, getSchemeHandler } = require_schemes();
20513
- function normalize4(uri, options) {
20530
+ function normalize5(uri, options) {
20514
20531
  if (typeof uri === "string") {
20515
20532
  uri = normalizeString(uri, options);
20516
20533
  } else if (typeof uri === "object") {
20517
- uri = parse3(serialize(uri, options), options);
20534
+ uri = parse4(serialize(uri, options), options);
20518
20535
  }
20519
20536
  return uri;
20520
20537
  }
20521
20538
  function resolve41(baseURI, relativeURI, options) {
20522
20539
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
20523
- const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
20540
+ const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
20524
20541
  schemelessOptions.skipEscape = true;
20525
20542
  return serialize(resolved, schemelessOptions);
20526
20543
  }
20527
20544
  function resolveComponent(base, relative16, options, skipNormalization) {
20528
20545
  const target = {};
20529
20546
  if (!skipNormalization) {
20530
- base = parse3(serialize(base, options), options);
20531
- relative16 = parse3(serialize(relative16, options), options);
20547
+ base = parse4(serialize(base, options), options);
20548
+ relative16 = parse4(serialize(relative16, options), options);
20532
20549
  }
20533
20550
  options = options || {};
20534
20551
  if (!options.tolerant && relative16.scheme) {
@@ -20752,7 +20769,7 @@ var require_fast_uri = __commonJS(function(exports, module) {
20752
20769
  }
20753
20770
  return { parsed, malformedAuthorityOrPort };
20754
20771
  }
20755
- function parse3(uri, opts) {
20772
+ function parse4(uri, opts) {
20756
20773
  return parseWithStatus(uri, opts).parsed;
20757
20774
  }
20758
20775
  function normalizeString(uri, opts) {
@@ -20776,12 +20793,12 @@ var require_fast_uri = __commonJS(function(exports, module) {
20776
20793
  }
20777
20794
  var fastUri = {
20778
20795
  SCHEMES,
20779
- normalize: normalize4,
20796
+ normalize: normalize5,
20780
20797
  resolve: resolve41,
20781
20798
  resolveComponent,
20782
20799
  equal,
20783
20800
  serialize,
20784
- parse: parse3
20801
+ parse: parse4
20785
20802
  };
20786
20803
  module.exports = fastUri;
20787
20804
  module.exports.default = fastUri;
@@ -23592,7 +23609,7 @@ var require_content_type = __commonJS(function(exports) {
23592
23609
  var QUOTE_REGEXP = /([\\"])/g;
23593
23610
  var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
23594
23611
  exports.format = format2;
23595
- exports.parse = parse3;
23612
+ exports.parse = parse4;
23596
23613
  function format2(obj) {
23597
23614
  if (!obj || typeof obj !== "object") {
23598
23615
  throw new TypeError("argument obj is required");
@@ -23616,7 +23633,7 @@ var require_content_type = __commonJS(function(exports) {
23616
23633
  }
23617
23634
  return string17;
23618
23635
  }
23619
- function parse3(string17) {
23636
+ function parse4(string17) {
23620
23637
  if (!string17) {
23621
23638
  throw new TypeError("argument string is required");
23622
23639
  }
@@ -24366,6 +24383,33 @@ var AGENT_MODEL_REQUIREMENTS = {
24366
24383
  { providers: ["opencode-go"], model: "glm-5.2" }
24367
24384
  ]
24368
24385
  },
24386
+ "omo-senpi-code-reviewer": {
24387
+ fallbackChain: [
24388
+ { providers: ["openai", "openai-codex"], model: "gpt-5.6-terra", variant: "medium" },
24389
+ { providers: ["github-copilot"], model: "gpt-5.6-terra", variant: "medium" },
24390
+ { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-6" },
24391
+ { providers: ["opencode-go"], model: "glm-5.2" },
24392
+ { providers: ["kimi-for-coding"], model: "kimi-k3" }
24393
+ ]
24394
+ },
24395
+ "omo-senpi-qa-executor": {
24396
+ fallbackChain: [
24397
+ { providers: ["openai", "openai-codex"], model: "gpt-5.6-luna", variant: "high" },
24398
+ { providers: ["github-copilot"], model: "gpt-5.6-luna", variant: "high" },
24399
+ { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-6" },
24400
+ { providers: ["opencode-go"], model: "glm-5.2" },
24401
+ { providers: ["kimi-for-coding"], model: "kimi-k3" }
24402
+ ]
24403
+ },
24404
+ "omo-senpi-gate-reviewer": {
24405
+ fallbackChain: [
24406
+ { providers: ["openai", "openai-codex"], model: "gpt-5.6-sol", variant: "low" },
24407
+ { providers: ["github-copilot"], model: "gpt-5.6-sol", variant: "low" },
24408
+ { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-5", variant: "max" },
24409
+ { providers: ["opencode-go"], model: "glm-5.2" },
24410
+ { providers: ["kimi-for-coding"], model: "kimi-k3" }
24411
+ ]
24412
+ },
24369
24413
  atlas: {
24370
24414
  fallbackChain: [
24371
24415
  { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-5" },
@@ -24955,7 +24999,7 @@ function normalizeCapabilitiesReasoningEfforts(capabilities) {
24955
24999
  }
24956
25000
  return capabilities.reasoningEfforts.map((value) => value.toLowerCase());
24957
25001
  }
24958
- function resolveField(normalized, familyCaps, ladder, familyKnown, metadataOverride, familyAliases) {
25002
+ function resolveField(normalized, familyCaps, familyKnown, metadataOverride, familyAliases) {
24959
25003
  const aliased = familyAliases?.[normalized];
24960
25004
  if (aliased && (metadataOverride?.includes(aliased) || familyCaps?.includes(aliased))) {
24961
25005
  return { value: aliased, reason: "unsupported-by-model-family" };
@@ -24990,7 +25034,7 @@ function resolveCompatibleModelSettings(input) {
24990
25034
  let variant = input.desired.variant;
24991
25035
  if (variant !== undefined) {
24992
25036
  const normalized = variant.toLowerCase();
24993
- const resolved = resolveField(normalized, family?.variants, REASONING_LEVELS2, familyKnown, metadataVariants);
25037
+ const resolved = resolveField(normalized, family?.variants, familyKnown, metadataVariants);
24994
25038
  if (resolved.value !== normalized && resolved.reason) {
24995
25039
  changes.push({ field: "variant", from: variant, to: resolved.value, reason: resolved.reason });
24996
25040
  }
@@ -24999,7 +25043,7 @@ function resolveCompatibleModelSettings(input) {
24999
25043
  let reasoningEffort = input.desired.reasoningEffort;
25000
25044
  if (reasoningEffort !== undefined) {
25001
25045
  const normalized = reasoningEffort.toLowerCase();
25002
- const resolved = resolveField(normalized, family?.reasoningEfforts, REASONING_LEVELS2, familyKnown, metadataReasoningEfforts, family?.reasoningEffortAliases);
25046
+ const resolved = resolveField(normalized, family?.reasoningEfforts, familyKnown, metadataReasoningEfforts, family?.reasoningEffortAliases);
25003
25047
  if (resolved.value !== normalized && resolved.reason) {
25004
25048
  changes.push({ field: "reasoningEffort", from: reasoningEffort, to: resolved.value, reason: resolved.reason });
25005
25049
  }
@@ -25393,7 +25437,11 @@ function normalizeModelFormat(model) {
25393
25437
  if (typeof model === "string") {
25394
25438
  const parts = model.split("/");
25395
25439
  if (parts.length >= 2) {
25396
- return { providerID: parts[0], modelID: parts.slice(1).join("/") };
25440
+ const providerID = parts[0];
25441
+ const modelID = parts.slice(1).join("/");
25442
+ if (providerID.trim() && modelID.trim()) {
25443
+ return { providerID, modelID };
25444
+ }
25397
25445
  }
25398
25446
  }
25399
25447
  return;
@@ -25724,7 +25772,12 @@ function isRecord9(value) {
25724
25772
  return typeof value === "object" && value !== null;
25725
25773
  }
25726
25774
  function getRecordValue(record11, key) {
25727
- return record11?.[key];
25775
+ try {
25776
+ return record11?.[key];
25777
+ } catch (cause) {
25778
+ if (!(cause instanceof Error)) {}
25779
+ return;
25780
+ }
25728
25781
  }
25729
25782
  function getNestedRecord(record11, key) {
25730
25783
  const value = getRecordValue(record11, key);
@@ -25834,8 +25887,41 @@ function isStatusCodeRetrySafe(code, retryOnErrors) {
25834
25887
  function isLocalizedQuotaExhaustionMessage(message) {
25835
25888
  return /\u9884\u6263\u8D39\u989D\u5EA6\u5931\u8D25/i.test(message) && /\u7528\u6237\u5269\u4F59\u989D\u5EA6/i.test(message) || /\u7528\u6237\u5269\u4F59\u989D\u5EA6/i.test(message) && /\u9700\u8981\u9884\u6263\u8D39\u989D\u5EA6/i.test(message);
25836
25889
  }
25890
+ function isUnknownRecord(value) {
25891
+ return typeof value === "object" && value !== null;
25892
+ }
25893
+ function getUnknownProperty(value, key) {
25894
+ if (!isUnknownRecord(value))
25895
+ return;
25896
+ try {
25897
+ return value[key];
25898
+ } catch (cause) {
25899
+ if (!(cause instanceof Error)) {}
25900
+ return;
25901
+ }
25902
+ }
25903
+ function getDetailErrorType(error) {
25904
+ const data = getUnknownProperty(error, "data");
25905
+ const detail = getUnknownProperty(error, "detail") ?? getUnknownProperty(data, "detail") ?? error;
25906
+ const detailError = getUnknownProperty(detail, "error") ?? detail;
25907
+ const type = getUnknownProperty(detailError, "type") ?? getUnknownProperty(detail, "type");
25908
+ return typeof type === "string" ? type.toLowerCase() : undefined;
25909
+ }
25910
+ function isTerminalQuotaMessage(message) {
25911
+ if (/\bnon[-\s]+terminal\s+quota\b/i.test(message) || /\bnon[-\s]+terminal\s+billing\s+limit\b/i.test(message)) {
25912
+ return false;
25913
+ }
25914
+ return /\bterminal\s+quota\b/i.test(message) || /\bterminal\s+billing\s+limit\b/i.test(message) || /\bhard\s+billing\s+limit\b/i.test(message);
25915
+ }
25837
25916
  function classifyRuntimeFallbackError(error) {
25917
+ const detailType = getDetailErrorType(error);
25918
+ if (detailType === "terminal_quota_exhausted") {
25919
+ return "abort";
25920
+ }
25838
25921
  const message = getRuntimeFallbackErrorMessage(error);
25922
+ if (isTerminalQuotaMessage(message)) {
25923
+ return "abort";
25924
+ }
25839
25925
  const errorName = getRuntimeFallbackErrorName(error)?.toLowerCase().replace(/[_-]/g, "");
25840
25926
  if (errorName?.includes("messageabortederror") || errorName?.includes("aborterror")) {
25841
25927
  return "abort";
@@ -26062,6 +26148,111 @@ var SUPPLEMENTAL_MODEL_CAPABILITIES = {
26062
26148
  input: 272000,
26063
26149
  output: 128000
26064
26150
  }
26151
+ },
26152
+ "grok-4.5": {
26153
+ id: "grok-4.5",
26154
+ family: "grok",
26155
+ reasoning: false,
26156
+ temperature: true,
26157
+ toolCall: true,
26158
+ modalities: {
26159
+ input: ["text", "image"],
26160
+ output: ["text"]
26161
+ },
26162
+ limit: {
26163
+ context: 500000,
26164
+ output: 32768
26165
+ }
26166
+ },
26167
+ "xai/grok-4.5": {
26168
+ id: "xai/grok-4.5",
26169
+ family: "grok",
26170
+ reasoning: false,
26171
+ temperature: true,
26172
+ toolCall: true,
26173
+ modalities: {
26174
+ input: ["text", "image"],
26175
+ output: ["text"]
26176
+ },
26177
+ limit: {
26178
+ context: 500000,
26179
+ output: 32768
26180
+ }
26181
+ },
26182
+ "x-ai/grok-4.5": {
26183
+ id: "x-ai/grok-4.5",
26184
+ family: "grok",
26185
+ reasoning: false,
26186
+ temperature: true,
26187
+ toolCall: true,
26188
+ modalities: {
26189
+ input: ["text", "image"],
26190
+ output: ["text"]
26191
+ },
26192
+ limit: {
26193
+ context: 500000,
26194
+ output: 32768
26195
+ }
26196
+ },
26197
+ "grok-4.6": {
26198
+ id: "grok-4.6",
26199
+ family: "grok",
26200
+ reasoning: false,
26201
+ temperature: true,
26202
+ toolCall: true,
26203
+ modalities: {
26204
+ input: ["text", "image"],
26205
+ output: ["text"]
26206
+ },
26207
+ limit: {
26208
+ context: 500000,
26209
+ output: 32768
26210
+ }
26211
+ },
26212
+ "xai/grok-4.6": {
26213
+ id: "xai/grok-4.6",
26214
+ family: "grok",
26215
+ reasoning: false,
26216
+ temperature: true,
26217
+ toolCall: true,
26218
+ modalities: {
26219
+ input: ["text", "image"],
26220
+ output: ["text"]
26221
+ },
26222
+ limit: {
26223
+ context: 500000,
26224
+ output: 32768
26225
+ }
26226
+ },
26227
+ "xai/grok-build-0.1": {
26228
+ id: "xai/grok-build-0.1",
26229
+ family: "grok",
26230
+ reasoning: false,
26231
+ temperature: true,
26232
+ toolCall: true,
26233
+ modalities: {
26234
+ input: ["text", "image"],
26235
+ output: ["text"]
26236
+ },
26237
+ limit: {
26238
+ context: 256000,
26239
+ output: 32768
26240
+ }
26241
+ },
26242
+ "x-ai/grok-build-0.1": {
26243
+ id: "x-ai/grok-build-0.1",
26244
+ family: "grok",
26245
+ reasoning: false,
26246
+ temperature: true,
26247
+ toolCall: true,
26248
+ modalities: {
26249
+ input: ["text", "image"],
26250
+ output: ["text"]
26251
+ },
26252
+ limit: {
26253
+ context: 256000,
26254
+ output: 32768
26255
+ }
26065
26256
  }
26066
26257
  };
26067
26258
 
@@ -27343,6 +27534,7 @@ var BackgroundTaskConfigSchema = z20.object({
27343
27534
  providerConcurrency: z20.record(z20.string(), z20.number().min(0)).optional(),
27344
27535
  modelConcurrency: z20.record(z20.string(), z20.number().min(0)).optional(),
27345
27536
  maxDepth: z20.number().int().min(1).optional(),
27537
+ maxLiveDescendantsPerRoot: z20.number().int().min(0).optional(),
27346
27538
  staleTimeoutMs: z20.number().min(60000).optional(),
27347
27539
  messageStalenessTimeoutMs: z20.number().min(60000).optional(),
27348
27540
  taskTtlMs: z20.number().min(300000).optional(),
@@ -87109,7 +87301,6 @@ function extractMessage2(error) {
87109
87301
  try {
87110
87302
  return JSON.stringify(error);
87111
87303
  } catch (stringifyError) {
87112
- stringifyError instanceof Error;
87113
87304
  return "";
87114
87305
  }
87115
87306
  }
@@ -89150,8 +89341,6 @@ function isCompactionGuardActive(state2, now) {
89150
89341
 
89151
89342
  // packages/omo-opencode/src/hooks/todo-continuation-enforcer/idle-event.ts
89152
89343
  init_logger2();
89153
-
89154
- // packages/omo-opencode/src/shared/prompt-async-gate/pending-tool-turn.ts
89155
89344
  init_pending_tool_turn();
89156
89345
 
89157
89346
  // packages/omo-opencode/src/hooks/todo-continuation-enforcer/abort-detection.ts
@@ -90765,7 +90954,6 @@ async function hasIncompleteTodos(ctx, sessionID) {
90765
90954
  return false;
90766
90955
  return todos.some((todo) => todo.status !== "completed" && todo.status !== "cancelled");
90767
90956
  } catch (todoError) {
90768
- todoError instanceof Error;
90769
90957
  return false;
90770
90958
  }
90771
90959
  }
@@ -92550,9 +92738,7 @@ async function findReadmeMdUp(input) {
92550
92738
  try {
92551
92739
  await access2(readmePath);
92552
92740
  found.push(readmePath);
92553
- } catch (error) {
92554
- error instanceof Error;
92555
- }
92741
+ } catch (error) {}
92556
92742
  if (current === input.rootDir)
92557
92743
  break;
92558
92744
  const parent = dirname23(current);
@@ -92934,6 +93120,21 @@ var TRUNCATE_CONFIG = {
92934
93120
  charsPerToken: 4
92935
93121
  };
92936
93122
 
93123
+ // packages/omo-opencode/src/hooks/anthropic-context-window-limit-recovery/session-timeout-map.ts
93124
+ function clearSessionTimeout(timeoutBySession, sessionID) {
93125
+ const timeoutID = timeoutBySession.get(sessionID);
93126
+ if (timeoutID !== undefined) {
93127
+ clearTimeout(timeoutID);
93128
+ timeoutBySession.delete(sessionID);
93129
+ }
93130
+ }
93131
+ function clearAllSessionTimeouts(timeoutBySession) {
93132
+ for (const timeoutID of timeoutBySession.values()) {
93133
+ clearTimeout(timeoutID);
93134
+ }
93135
+ timeoutBySession.clear();
93136
+ }
93137
+
92937
93138
  // packages/omo-opencode/src/hooks/anthropic-context-window-limit-recovery/state.ts
92938
93139
  function getOrCreateRetryState(autoCompactState, sessionID) {
92939
93140
  let state2 = autoCompactState.retryStateBySession.get(sessionID);
@@ -92964,6 +93165,15 @@ function clearSessionState(autoCompactState, sessionID) {
92964
93165
  autoCompactState.emptyContentAttemptBySession.delete(sessionID);
92965
93166
  autoCompactState.compactionInProgress.delete(sessionID);
92966
93167
  }
93168
+ function clearAllSessionState(autoCompactState) {
93169
+ clearAllSessionTimeouts(autoCompactState.retryTimerBySession);
93170
+ autoCompactState.pendingCompact.clear();
93171
+ autoCompactState.errorDataBySession.clear();
93172
+ autoCompactState.retryStateBySession.clear();
93173
+ autoCompactState.truncateStateBySession.clear();
93174
+ autoCompactState.emptyContentAttemptBySession.clear();
93175
+ autoCompactState.compactionInProgress.clear();
93176
+ }
92967
93177
  function setRetryTimer(autoCompactState, sessionID, timeout) {
92968
93178
  const existingTimer = autoCompactState.retryTimerBySession.get(sessionID);
92969
93179
  if (existingTimer !== undefined) {
@@ -92988,7 +93198,7 @@ function incrementEmptyContentAttempt(autoCompactState, sessionID) {
92988
93198
  }
92989
93199
 
92990
93200
  // packages/omo-opencode/src/hooks/anthropic-context-window-limit-recovery/tool-result-storage.ts
92991
- import { existsSync as existsSync50, readdirSync as readdirSync15, readFileSync as readFileSync30, writeFileSync as writeFileSync10 } from "fs";
93201
+ import { existsSync as existsSync50, readdirSync as readdirSync15, readFileSync as readFileSync30, rmSync as rmSync4, writeFileSync as writeFileSync10 } from "fs";
92992
93202
  import { join as join67 } from "path";
92993
93203
 
92994
93204
  // packages/omo-opencode/src/hooks/anthropic-context-window-limit-recovery/message-storage-directory.ts
@@ -93062,6 +93272,10 @@ function truncateToolResult(partPath) {
93062
93272
  }
93063
93273
  const originalSize = part.state.output.length;
93064
93274
  const toolName = part.tool;
93275
+ const backupPath = `${partPath}.original`;
93276
+ try {
93277
+ writeFileSync10(backupPath, part.state.output);
93278
+ } catch {}
93065
93279
  part.truncated = true;
93066
93280
  part.originalSize = originalSize;
93067
93281
  part.state.output = TRUNCATION_MESSAGE;
@@ -93798,7 +94012,7 @@ function getSdkMessages(response) {
93798
94012
  const data = record11["data"];
93799
94013
  if (Array.isArray(data))
93800
94014
  return data;
93801
- return Array.isArray(record11) ? record11 : [];
94015
+ return [];
93802
94016
  }
93803
94017
  async function findEmptyMessagesFromSDK(client3, sessionID) {
93804
94018
  try {
@@ -94515,21 +94729,6 @@ async function attemptDeduplicationRecovery(sessionID, parsed, experimental2, cl
94515
94729
  }
94516
94730
  }
94517
94731
 
94518
- // packages/omo-opencode/src/hooks/anthropic-context-window-limit-recovery/session-timeout-map.ts
94519
- function clearSessionTimeout(timeoutBySession, sessionID) {
94520
- const timeoutID = timeoutBySession.get(sessionID);
94521
- if (timeoutID !== undefined) {
94522
- clearTimeout(timeoutID);
94523
- timeoutBySession.delete(sessionID);
94524
- }
94525
- }
94526
- function clearAllSessionTimeouts(timeoutBySession) {
94527
- for (const timeoutID of timeoutBySession.values()) {
94528
- clearTimeout(timeoutID);
94529
- }
94530
- timeoutBySession.clear();
94531
- }
94532
-
94533
94732
  // packages/omo-opencode/src/hooks/anthropic-context-window-limit-recovery/recovery-hook.ts
94534
94733
  init_logger2();
94535
94734
  function createRecoveryState() {
@@ -94655,7 +94854,7 @@ function createAnthropicContextWindowLimitRecoveryHook(ctx, options) {
94655
94854
  event: eventHandler,
94656
94855
  dispose: () => {
94657
94856
  clearAllSessionTimeouts(pendingCompactionTimeoutBySession);
94658
- clearAllSessionTimeouts(autoCompactState.retryTimerBySession);
94857
+ clearAllSessionState(autoCompactState);
94659
94858
  }
94660
94859
  };
94661
94860
  }
@@ -95922,7 +96121,9 @@ function appendTranscriptEntry(sessionId, entry) {
95922
96121
  appendFileSync6(path8, line);
95923
96122
  }
95924
96123
  var TRANSCRIPT_CACHE_TTL_MS = 5 * 60 * 1000;
96124
+ var TRANSCRIPT_CACHE_PRUNE_INTERVAL_MS = TRANSCRIPT_CACHE_TTL_MS;
95925
96125
  var transcriptCache = new Map;
96126
+ var cleanupInterval2 = null;
95926
96127
  function logTranscriptError(message, error) {
95927
96128
  log2(message, { error });
95928
96129
  }
@@ -95958,6 +96159,30 @@ function clearTranscriptCache(sessionId) {
95958
96159
  transcriptCache.clear();
95959
96160
  }
95960
96161
  }
96162
+ function pruneExpiredTranscriptCache() {
96163
+ const now = Date.now();
96164
+ for (const sessionId of [...transcriptCache.keys()]) {
96165
+ const entry = transcriptCache.get(sessionId);
96166
+ if (!entry || now - entry.createdAt >= TRANSCRIPT_CACHE_TTL_MS) {
96167
+ clearTranscriptCache(sessionId);
96168
+ }
96169
+ }
96170
+ }
96171
+ function ensureTranscriptCacheCleanup() {
96172
+ if (cleanupInterval2)
96173
+ return;
96174
+ cleanupInterval2 = setInterval(pruneExpiredTranscriptCache, TRANSCRIPT_CACHE_PRUNE_INTERVAL_MS);
96175
+ if (typeof cleanupInterval2 === "object" && "unref" in cleanupInterval2) {
96176
+ cleanupInterval2.unref();
96177
+ }
96178
+ }
96179
+ function stopTranscriptCacheCleanup() {
96180
+ clearTranscriptCache();
96181
+ if (!cleanupInterval2)
96182
+ return;
96183
+ clearInterval(cleanupInterval2);
96184
+ cleanupInterval2 = null;
96185
+ }
95961
96186
  function isCacheValid(entry) {
95962
96187
  return Date.now() - entry.createdAt < TRANSCRIPT_CACHE_TTL_MS;
95963
96188
  }
@@ -96034,6 +96259,7 @@ async function buildTranscriptFromSession(client3, sessionId, directory, current
96034
96259
  tempPath: null,
96035
96260
  createdAt: Date.now()
96036
96261
  });
96262
+ ensureTranscriptCacheCleanup();
96037
96263
  }
96038
96264
  const allEntries = [...baseEntries, buildCurrentEntry(currentToolName, currentToolInput)];
96039
96265
  if (previousTempPath) {
@@ -96091,6 +96317,91 @@ function deleteTempTranscript(path8) {
96091
96317
  }
96092
96318
  }
96093
96319
 
96320
+ // packages/omo-opencode/src/hooks/claude-code-hooks/todo.ts
96321
+ import { join as join77 } from "path";
96322
+ var TODO_DIR = join77(getClaudeConfigDir(), "todos");
96323
+ function getTodoPath(sessionId) {
96324
+ return join77(TODO_DIR, `${sessionId}-agent-${sessionId}.json`);
96325
+ }
96326
+
96327
+ // packages/omo-opencode/src/hooks/claude-code-hooks/stop.ts
96328
+ var stopHookActiveState = new Map;
96329
+ function clearStopHookActive(sessionId) {
96330
+ stopHookActiveState.delete(sessionId);
96331
+ }
96332
+ function clearAllStopHookActive() {
96333
+ stopHookActiveState.clear();
96334
+ }
96335
+ async function executeStopHooks(ctx, config3, extendedConfig) {
96336
+ if (ctx.parentSessionId) {
96337
+ return { block: false };
96338
+ }
96339
+ if (!config3) {
96340
+ return { block: false };
96341
+ }
96342
+ const matchers = findMatchingHooks(config3, "Stop");
96343
+ if (matchers.length === 0) {
96344
+ return { block: false };
96345
+ }
96346
+ const stdinData = {
96347
+ session_id: ctx.sessionId,
96348
+ transcript_path: ctx.transcriptPath,
96349
+ cwd: ctx.cwd,
96350
+ permission_mode: ctx.permissionMode ?? "bypassPermissions",
96351
+ hook_event_name: "Stop",
96352
+ stop_hook_active: stopHookActiveState.get(ctx.sessionId) ?? false,
96353
+ todo_path: getTodoPath(ctx.sessionId),
96354
+ hook_source: "opencode-plugin"
96355
+ };
96356
+ for (const matcher of matchers) {
96357
+ if (!matcher.hooks || matcher.hooks.length === 0)
96358
+ continue;
96359
+ for (const hook of matcher.hooks) {
96360
+ if (hook.type !== "command" && hook.type !== "http")
96361
+ continue;
96362
+ const hookName = getHookIdentifier(hook);
96363
+ if (isHookCommandDisabled("Stop", hookName, extendedConfig ?? null)) {
96364
+ log2("Stop hook command skipped (disabled by config)", { command: hookName });
96365
+ continue;
96366
+ }
96367
+ const result = await dispatchHook(hook, JSON.stringify(stdinData), ctx.cwd);
96368
+ if (result.exitCode === 2) {
96369
+ const reason = normalizeHookText(result.stderr) ?? normalizeHookText(result.stdout) ?? "Blocked by stop hook";
96370
+ return {
96371
+ block: true,
96372
+ reason,
96373
+ injectPrompt: reason
96374
+ };
96375
+ }
96376
+ if (result.stdout) {
96377
+ try {
96378
+ const output = JSON.parse(result.stdout || "{}");
96379
+ if (output.stop_hook_active !== undefined) {
96380
+ stopHookActiveState.set(ctx.sessionId, output.stop_hook_active);
96381
+ }
96382
+ const isBlock = output.decision === "block";
96383
+ if (isBlock) {
96384
+ const reason = normalizeHookText(output.reason);
96385
+ const injectPrompt = normalizeHookText(output.inject_prompt) ?? reason;
96386
+ return {
96387
+ block: true,
96388
+ reason,
96389
+ stopHookActive: output.stop_hook_active,
96390
+ permissionMode: output.permission_mode,
96391
+ injectPrompt
96392
+ };
96393
+ }
96394
+ } catch (error) {
96395
+ if (!(error instanceof SyntaxError)) {
96396
+ throw error;
96397
+ }
96398
+ }
96399
+ }
96400
+ }
96401
+ }
96402
+ return { block: false };
96403
+ }
96404
+
96094
96405
  // packages/omo-opencode/src/hooks/claude-code-hooks/session-hook-state.ts
96095
96406
  var sessionFirstMessageProcessed = new Set;
96096
96407
  var sessionErrorState = new Map;
@@ -96099,10 +96410,16 @@ function clearSessionHookState(sessionID) {
96099
96410
  sessionErrorState.delete(sessionID);
96100
96411
  sessionInterruptState.delete(sessionID);
96101
96412
  }
96413
+ function clearSessionEndHookState(sessionID) {
96414
+ clearSessionHookState(sessionID);
96415
+ sessionFirstMessageProcessed.delete(sessionID);
96416
+ clearStopHookActive(sessionID);
96417
+ }
96102
96418
  function clearAllSessionHookState() {
96103
96419
  sessionErrorState.clear();
96104
96420
  sessionInterruptState.clear();
96105
96421
  sessionFirstMessageProcessed.clear();
96422
+ clearAllStopHookActive();
96106
96423
  }
96107
96424
 
96108
96425
  // packages/omo-opencode/src/hooks/claude-code-hooks/handlers/chat-message-handler.ts
@@ -96313,89 +96630,10 @@ function createPreCompactHandler(ctx, config3) {
96313
96630
  };
96314
96631
  }
96315
96632
 
96316
- // packages/omo-opencode/src/hooks/claude-code-hooks/todo.ts
96317
- import { join as join77 } from "path";
96318
- var TODO_DIR = join77(getClaudeConfigDir(), "todos");
96319
- function getTodoPath(sessionId) {
96320
- return join77(TODO_DIR, `${sessionId}-agent-${sessionId}.json`);
96321
- }
96322
-
96323
- // packages/omo-opencode/src/hooks/claude-code-hooks/stop.ts
96324
- var stopHookActiveState = new Map;
96325
- async function executeStopHooks(ctx, config3, extendedConfig) {
96326
- if (ctx.parentSessionId) {
96327
- return { block: false };
96328
- }
96329
- if (!config3) {
96330
- return { block: false };
96331
- }
96332
- const matchers = findMatchingHooks(config3, "Stop");
96333
- if (matchers.length === 0) {
96334
- return { block: false };
96335
- }
96336
- const stdinData = {
96337
- session_id: ctx.sessionId,
96338
- transcript_path: ctx.transcriptPath,
96339
- cwd: ctx.cwd,
96340
- permission_mode: ctx.permissionMode ?? "bypassPermissions",
96341
- hook_event_name: "Stop",
96342
- stop_hook_active: stopHookActiveState.get(ctx.sessionId) ?? false,
96343
- todo_path: getTodoPath(ctx.sessionId),
96344
- hook_source: "opencode-plugin"
96345
- };
96346
- for (const matcher of matchers) {
96347
- if (!matcher.hooks || matcher.hooks.length === 0)
96348
- continue;
96349
- for (const hook of matcher.hooks) {
96350
- if (hook.type !== "command" && hook.type !== "http")
96351
- continue;
96352
- const hookName = getHookIdentifier(hook);
96353
- if (isHookCommandDisabled("Stop", hookName, extendedConfig ?? null)) {
96354
- log2("Stop hook command skipped (disabled by config)", { command: hookName });
96355
- continue;
96356
- }
96357
- const result = await dispatchHook(hook, JSON.stringify(stdinData), ctx.cwd);
96358
- if (result.exitCode === 2) {
96359
- const reason = normalizeHookText(result.stderr) ?? normalizeHookText(result.stdout) ?? "Blocked by stop hook";
96360
- return {
96361
- block: true,
96362
- reason,
96363
- injectPrompt: reason
96364
- };
96365
- }
96366
- if (result.stdout) {
96367
- try {
96368
- const output = JSON.parse(result.stdout || "{}");
96369
- if (output.stop_hook_active !== undefined) {
96370
- stopHookActiveState.set(ctx.sessionId, output.stop_hook_active);
96371
- }
96372
- const isBlock = output.decision === "block";
96373
- if (isBlock) {
96374
- const reason = normalizeHookText(output.reason);
96375
- const injectPrompt = normalizeHookText(output.inject_prompt) ?? reason;
96376
- return {
96377
- block: true,
96378
- reason,
96379
- stopHookActive: output.stop_hook_active,
96380
- permissionMode: output.permission_mode,
96381
- injectPrompt
96382
- };
96383
- }
96384
- } catch (error) {
96385
- if (!(error instanceof SyntaxError)) {
96386
- throw error;
96387
- }
96388
- }
96389
- }
96390
- }
96391
- }
96392
- return { block: false };
96393
- }
96394
-
96395
96633
  // packages/omo-opencode/src/hooks/claude-code-hooks/tool-input-cache.ts
96396
96634
  var cache = new Map;
96397
96635
  var CACHE_TTL = 60000;
96398
- var cleanupInterval2 = null;
96636
+ var cleanupInterval3 = null;
96399
96637
  function pruneExpiredToolInputs() {
96400
96638
  const now = Date.now();
96401
96639
  for (const [key, entry] of cache.entries()) {
@@ -96405,13 +96643,13 @@ function pruneExpiredToolInputs() {
96405
96643
  }
96406
96644
  }
96407
96645
  function ensureCleanupInterval() {
96408
- if (cleanupInterval2)
96646
+ if (cleanupInterval3)
96409
96647
  return;
96410
- cleanupInterval2 = setInterval(() => {
96648
+ cleanupInterval3 = setInterval(() => {
96411
96649
  pruneExpiredToolInputs();
96412
96650
  }, CACHE_TTL);
96413
- if (typeof cleanupInterval2 === "object" && "unref" in cleanupInterval2) {
96414
- cleanupInterval2.unref();
96651
+ if (typeof cleanupInterval3 === "object" && "unref" in cleanupInterval3) {
96652
+ cleanupInterval3.unref();
96415
96653
  }
96416
96654
  }
96417
96655
  function cacheToolInput(sessionId, toolName, invocationId, toolInput) {
@@ -96443,10 +96681,10 @@ function clearToolInputCache(sessionId) {
96443
96681
  }
96444
96682
  function stopToolInputCacheCleanup() {
96445
96683
  clearToolInputCache();
96446
- if (!cleanupInterval2)
96684
+ if (!cleanupInterval3)
96447
96685
  return;
96448
- clearInterval(cleanupInterval2);
96449
- cleanupInterval2 = null;
96686
+ clearInterval(cleanupInterval3);
96687
+ cleanupInterval3 = null;
96450
96688
  }
96451
96689
 
96452
96690
  // packages/omo-opencode/src/hooks/claude-code-hooks/handlers/session-event-handler.ts
@@ -96473,7 +96711,7 @@ function createSessionEventHandler(ctx, config3, contextCollector) {
96473
96711
  clearTranscriptCache(sessionID2);
96474
96712
  clearToolInputCache(sessionID2);
96475
96713
  contextCollector?.clear(sessionID2);
96476
- clearSessionHookState(sessionID2);
96714
+ clearSessionEndHookState(sessionID2);
96477
96715
  }
96478
96716
  return;
96479
96717
  }
@@ -96563,7 +96801,7 @@ function createSessionEventHandler(ctx, config3, contextCollector) {
96563
96801
  };
96564
96802
  }
96565
96803
  function disposeSessionEventHandler(contextCollector) {
96566
- clearTranscriptCache();
96804
+ stopTranscriptCacheCleanup();
96567
96805
  clearClaudeHooksConfigCache();
96568
96806
  clearPluginExtendedConfigCache();
96569
96807
  stopToolInputCacheCleanup();
@@ -98631,7 +98869,6 @@ function getLocalDevVersion(directory) {
98631
98869
  const pkg = JSON.parse(content);
98632
98870
  return pkg.version ?? null;
98633
98871
  } catch (error) {
98634
- error instanceof Error;
98635
98872
  return null;
98636
98873
  }
98637
98874
  }
@@ -98661,7 +98898,6 @@ function findPluginEntry(directory) {
98661
98898
  }
98662
98899
  }
98663
98900
  } catch (error) {
98664
- error instanceof Error;
98665
98901
  continue;
98666
98902
  }
98667
98903
  }
@@ -98727,7 +98963,7 @@ function getCachedVersion(options = {}) {
98727
98963
  // package.json
98728
98964
  var package_default = {
98729
98965
  name: "oh-my-opencode",
98730
- version: "5.0.0-beta.30",
98966
+ version: "5.0.0-beta.32",
98731
98967
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
98732
98968
  main: "./dist/index.js",
98733
98969
  types: "dist/index.d.ts",
@@ -98840,6 +99076,7 @@ var package_default = {
98840
99076
  "install:codex-dev": "bun run script/build-codex-install.ts && bun run script/install-codex-dev.ts",
98841
99077
  "build:codex-plugin": "npm --prefix packages/omo-codex/plugin ci && bun run --cwd packages/omo-codex/plugin build",
98842
99078
  "build:senpi-plugin": "bun run build:lsp-daemon && bun run build:ast-grep-mcp && bun run build:senpi-plugin:stage",
99079
+ "build:senpi-plugin:native": "node packages/omo-senpi/plugin/scripts/stage-lsp-daemon-runtime.mjs && node packages/omo-senpi/plugin/scripts/stage-ast-grep-mcp-runtime.mjs && node packages/omo-senpi/plugin/scripts/stage-agent-toolkit.mjs && node packages/omo-senpi/plugin/scripts/build-extension.mjs && node packages/omo-senpi/plugin/scripts/sync-skills.mjs && node packages/omo-senpi/plugin/scripts/embed-directive.mjs --check && node packages/omo-senpi/plugin/scripts/build-install.mjs",
98843
99080
  "build:senpi-plugin:stage": "bun run build:materialize-frontend && node packages/omo-senpi/plugin/scripts/stage-lsp-daemon-runtime.mjs && node packages/omo-senpi/plugin/scripts/stage-ast-grep-mcp-runtime.mjs && node packages/omo-senpi/plugin/scripts/stage-agent-toolkit.mjs && node packages/omo-senpi/plugin/scripts/build-extension.mjs && node packages/omo-senpi/plugin/scripts/sync-skills.mjs && node packages/omo-senpi/plugin/scripts/embed-directive.mjs --check && node packages/omo-senpi/plugin/scripts/build-install.mjs",
98844
99081
  "build:materialize-frontend": "node packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs --strict",
98845
99082
  "build:shared-skills-assets": "bun run build:materialize-frontend && rm -rf dist/skills && cp -R packages/shared-skills/skills dist/skills",
@@ -98908,7 +99145,7 @@ var package_default = {
98908
99145
  zod: "^4.4.3"
98909
99146
  },
98910
99147
  devDependencies: {
98911
- "@code-yeongyu/senpi": "2026.8.30-3",
99148
+ "@code-yeongyu/senpi": "2026.9.2",
98912
99149
  "@oh-my-opencode/agents-md-core": "workspace:*",
98913
99150
  "@oh-my-opencode/ast-grep-mcp": "workspace:*",
98914
99151
  "@oh-my-opencode/boulder-state": "workspace:*",
@@ -98949,18 +99186,18 @@ var package_default = {
98949
99186
  typescript: "^7.0.2"
98950
99187
  },
98951
99188
  optionalDependencies: {
98952
- "oh-my-opencode-darwin-arm64": "5.0.0-beta.30",
98953
- "oh-my-opencode-darwin-x64": "5.0.0-beta.30",
98954
- "oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.30",
98955
- "oh-my-opencode-linux-arm64": "5.0.0-beta.30",
98956
- "oh-my-opencode-linux-arm64-musl": "5.0.0-beta.30",
98957
- "oh-my-opencode-linux-x64": "5.0.0-beta.30",
98958
- "oh-my-opencode-linux-x64-baseline": "5.0.0-beta.30",
98959
- "oh-my-opencode-linux-x64-musl": "5.0.0-beta.30",
98960
- "oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.30",
98961
- "oh-my-opencode-windows-arm64": "5.0.0-beta.30",
98962
- "oh-my-opencode-windows-x64": "5.0.0-beta.30",
98963
- "oh-my-opencode-windows-x64-baseline": "5.0.0-beta.30"
99189
+ "oh-my-opencode-darwin-arm64": "5.0.0-beta.32",
99190
+ "oh-my-opencode-darwin-x64": "5.0.0-beta.32",
99191
+ "oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.32",
99192
+ "oh-my-opencode-linux-arm64": "5.0.0-beta.32",
99193
+ "oh-my-opencode-linux-arm64-musl": "5.0.0-beta.32",
99194
+ "oh-my-opencode-linux-x64": "5.0.0-beta.32",
99195
+ "oh-my-opencode-linux-x64-baseline": "5.0.0-beta.32",
99196
+ "oh-my-opencode-linux-x64-musl": "5.0.0-beta.32",
99197
+ "oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.32",
99198
+ "oh-my-opencode-windows-arm64": "5.0.0-beta.32",
99199
+ "oh-my-opencode-windows-x64": "5.0.0-beta.32",
99200
+ "oh-my-opencode-windows-x64-baseline": "5.0.0-beta.32"
98964
99201
  },
98965
99202
  overrides: {
98966
99203
  "@earendil-works/pi-agent-core": "0.84.2",
@@ -98978,7 +99215,7 @@ var package_default = {
98978
99215
  "@code-yeongyu/comment-checker"
98979
99216
  ],
98980
99217
  patchedDependencies: {
98981
- "@code-yeongyu/senpi@2026.8.30-3": "patches/@code-yeongyu%2Fsenpi@2026.8.30-3.patch"
99218
+ "@code-yeongyu/senpi@2026.9.2": "patches/@code-yeongyu%2Fsenpi@2026.9.2.patch"
98982
99219
  }
98983
99220
  };
98984
99221
 
@@ -99002,7 +99239,6 @@ async function getLatestVersion(channel = "latest") {
99002
99239
  const data = await response.json();
99003
99240
  return data[channel] ?? data.latest ?? null;
99004
99241
  } catch (error) {
99005
- error instanceof Error;
99006
99242
  return null;
99007
99243
  } finally {
99008
99244
  clearTimeout(timeoutId);
@@ -101041,8 +101277,7 @@ var TARGET_TOOLS = new Set([
101041
101277
  ]);
101042
101278
  var AGENT_TOOLS = new Set([
101043
101279
  "task",
101044
- "call_omo_agent",
101045
- "task"
101280
+ "call_omo_agent"
101046
101281
  ]);
101047
101282
  var REMINDER_MESSAGE = `
101048
101283
  [Agent Usage Reminder]
@@ -101082,7 +101317,6 @@ function loadAgentUsageState(sessionID) {
101082
101317
  const content = readFileSync48(filePath, "utf-8");
101083
101318
  return JSON.parse(content);
101084
101319
  } catch (error) {
101085
- error instanceof Error;
101086
101320
  return null;
101087
101321
  }
101088
101322
  }
@@ -106136,6 +106370,23 @@ function extractPromptText2(parts) {
106136
106370
  }
106137
106371
  // packages/omo-opencode/src/hooks/keyword-detector/hook.ts
106138
106372
  var defaultModeUltraworkInjectedSessions = new Set;
106373
+ var DEFAULT_MODE_ULTRAWORK_SESSION_CAP = 256;
106374
+ function rememberDefaultModeUltraworkInjectedSession(sessionID) {
106375
+ if (defaultModeUltraworkInjectedSessions.has(sessionID))
106376
+ return;
106377
+ if (defaultModeUltraworkInjectedSessions.size >= DEFAULT_MODE_ULTRAWORK_SESSION_CAP) {
106378
+ const oldest = defaultModeUltraworkInjectedSessions.values().next().value;
106379
+ if (oldest !== undefined)
106380
+ defaultModeUltraworkInjectedSessions.delete(oldest);
106381
+ }
106382
+ defaultModeUltraworkInjectedSessions.add(sessionID);
106383
+ }
106384
+ function clearDefaultModeUltraworkInjectedSession(sessionID) {
106385
+ defaultModeUltraworkInjectedSessions.delete(sessionID);
106386
+ }
106387
+ function clearAllDefaultModeUltraworkInjectedSessions() {
106388
+ defaultModeUltraworkInjectedSessions.clear();
106389
+ }
106139
106390
  function suppressComboStandalones(detected) {
106140
106391
  const hasCombo = detected.some((k) => k.type === "hyperplan-ultrawork");
106141
106392
  if (!hasCombo)
@@ -106196,7 +106447,7 @@ function createKeywordDetectorHook(ctx, _collector, _ralphLoop, config3, default
106196
106447
  const isNonMainSession = mainSessionID && input.sessionID !== mainSessionID;
106197
106448
  if (detectedKeywords.length === 0) {
106198
106449
  if (defaultMode?.ultrawork && !isNonMainSession && !defaultModeUltraworkInjectedSessions.has(input.sessionID)) {
106199
- defaultModeUltraworkInjectedSessions.add(input.sessionID);
106450
+ rememberDefaultModeUltraworkInjectedSession(input.sessionID);
106200
106451
  log2(`[keyword-detector] Default ultrawork mode auto-activated (injected via system prompt)`, { sessionID: input.sessionID });
106201
106452
  ctx.client.tui.showToast({
106202
106453
  body: {
@@ -106294,6 +106545,16 @@ ${allMessages}`;
106294
106545
  sessionID: input.sessionID,
106295
106546
  types: detectedKeywords.map((k) => k.type)
106296
106547
  });
106548
+ },
106549
+ event: ({ event }) => {
106550
+ if (event.type !== "session.deleted")
106551
+ return;
106552
+ const sessionID = resolveSessionEventID(event.properties);
106553
+ if (sessionID)
106554
+ clearDefaultModeUltraworkInjectedSession(sessionID);
106555
+ },
106556
+ dispose: () => {
106557
+ clearAllDefaultModeUltraworkInjectedSessions();
106297
106558
  }
106298
106559
  };
106299
106560
  }
@@ -107603,6 +107864,9 @@ function recoverToolMetadata(sessionID, source) {
107603
107864
  }
107604
107865
  return consumeToolMetadata(sessionID, callID);
107605
107866
  }
107867
+ // packages/omo-opencode/src/hooks/ralph-loop/oracle-verification-detector.ts
107868
+ var VERIFICATION_AGENTS = new Set(["oracle", "gate-verifier"]);
107869
+
107606
107870
  // packages/omo-opencode/src/hooks/ralph-loop/verification-failure-handler.ts
107607
107871
  init_logger2();
107608
107872
 
@@ -107619,6 +107883,7 @@ REQUIRED NOW:
107619
107883
  - Ask Oracle to verify whether the original task is actually complete
107620
107884
  - Include the original task in the Oracle request
107621
107885
  - Explicitly tell Oracle to review skeptically and critically, and to look for reasons the task may still be incomplete or wrong
107886
+ - If the Oracle spawn fails because its model/agent is unavailable, spawn a verifier with the identical verification instructions using task(category: "deep", load_skills=[], run_in_background=false, ...), then retry with category: "unspecified-high", then category: "unspecified-low" on the same failure; require its reply to end with the literal line \`Agent: gate-verifier\` immediately above the promise tag
107622
107887
  - The system will inspect the Oracle session directly for the verification result
107623
107888
  - If Oracle does not verify, continue fixing the task and do not consider it complete
107624
107889
 
@@ -107634,6 +107899,7 @@ REQUIRED NOW:
107634
107899
  - Do not claim completion early or argue with the failed verification
107635
107900
  - After fixing the remaining issues, request Oracle review again using task(subagent_type="oracle", load_skills=[], run_in_background=false, ...)
107636
107901
  - Include the original task in the Oracle request and tell Oracle to review skeptically and critically
107902
+ - If the Oracle spawn fails because its model/agent is unavailable, spawn a verifier with the identical verification instructions using task(category: "deep", load_skills=[], run_in_background=false, ...), then retry with category: "unspecified-high", then category: "unspecified-low" on the same failure; require its reply to end with the literal line \`Agent: gate-verifier\` immediately above the promise tag
107637
107903
  - Only when the work is ready for review again, output: <promise>{{PROMISE}}</promise>
107638
107904
 
107639
107905
  Original task:
@@ -109077,7 +109343,7 @@ $ARGUMENTS
109077
109343
  subtask: entry.subtask ?? fileMetadata.subtask,
109078
109344
  argumentHint: entry["argument-hint"] || fileMetadata["argument-hint"]
109079
109345
  };
109080
- const allowedTools = entry["allowed-tools"] || parseAllowedTools(fileMetadata["allowed-tools"]);
109346
+ const allowedTools = parseAllowedTools(entry["allowed-tools"]) || parseAllowedTools(fileMetadata["allowed-tools"]);
109081
109347
  return {
109082
109348
  name,
109083
109349
  path: sourcePath,
@@ -109095,7 +109361,8 @@ $ARGUMENTS
109095
109361
  init_src2();
109096
109362
  function mergeSkillDefinitions(base, patch) {
109097
109363
  const mergedMetadata = base.metadata || patch.metadata ? deepMerge(base.metadata || {}, patch.metadata || {}) : undefined;
109098
- const mergedTools = base.allowedTools || patch["allowed-tools"] ? [...base.allowedTools || [], ...patch["allowed-tools"] || []] : undefined;
109364
+ const patchAllowedTools = parseAllowedTools(patch["allowed-tools"]);
109365
+ const mergedTools = base.allowedTools || patchAllowedTools ? [...base.allowedTools || [], ...patchAllowedTools || []] : undefined;
109099
109366
  const description = patch.description || base.definition.description?.replace(/^\([^)]+\) /, "");
109100
109367
  return {
109101
109368
  ...base,
@@ -111296,7 +111563,7 @@ Use this skill to run a parallel security audit that separates real exploitabili
111296
111563
  Before starting, verify:
111297
111564
 
111298
111565
  1. \`team_*\` tools are available. If not, stop and tell the user:
111299
- \`security-research requires team-mode. Set team_mode.enabled: true in your oh-my-openagent config, restart opencode, then retry.\`
111566
+ \`security-research requires team-mode. Set team_mode.enabled: true in your .omo/omo.jsonc config, restart opencode, then retry.\`
111300
111567
  2. You are in the main session, not a background subagent.
111301
111568
  3. You have a concrete target: repository, diff range, PR, release candidate, path list, or threat surface.
111302
111569
 
@@ -119738,8 +120005,6 @@ async function runPreemptiveCompactionIfNeeded(args) {
119738
120005
  if (toastError instanceof Error)
119739
120006
  return;
119740
120007
  });
119741
- if (error instanceof Error)
119742
- return;
119743
120008
  } finally {
119744
120009
  compactionInProgress.delete(sessionID);
119745
120010
  }
@@ -121758,15 +122023,15 @@ function createRuntimeFallbackHook(ctx, options, factoryOverrides = {}) {
121758
122023
  const messageUpdateHandler = factories.createMessageUpdateHandler(deps, helpers);
121759
122024
  const chatMessageHandler = factories.createChatMessageHandler(deps);
121760
122025
  const firstPromptWatchdog = factories.createFirstPromptWatchdog(deps, helpers);
121761
- let cleanupInterval3 = null;
122026
+ let cleanupInterval4 = null;
121762
122027
  let intervalStarted = false;
121763
122028
  const ensureInterval = () => {
121764
122029
  if (intervalStarted)
121765
122030
  return;
121766
122031
  intervalStarted = true;
121767
- cleanupInterval3 = setInterval(helpers.cleanupStaleSessions, 5 * 60 * 1000);
121768
- if (typeof cleanupInterval3.unref === "function") {
121769
- cleanupInterval3.unref();
122032
+ cleanupInterval4 = setInterval(helpers.cleanupStaleSessions, 5 * 60 * 1000);
122033
+ if (typeof cleanupInterval4.unref === "function") {
122034
+ cleanupInterval4.unref();
121770
122035
  }
121771
122036
  };
121772
122037
  const eventHandler = async ({ event }) => {
@@ -121784,8 +122049,8 @@ function createRuntimeFallbackHook(ctx, options, factoryOverrides = {}) {
121784
122049
  await baseEventHandler({ event });
121785
122050
  };
121786
122051
  const dispose = () => {
121787
- if (cleanupInterval3) {
121788
- clearInterval(cleanupInterval3);
122052
+ if (cleanupInterval4) {
122053
+ clearInterval(cleanupInterval4);
121789
122054
  }
121790
122055
  for (const fallbackTimeout of deps.sessionFallbackTimeouts.values()) {
121791
122056
  clearTimeout(fallbackTimeout);
@@ -121991,7 +122256,6 @@ function toCanonicalPath2(absolutePath) {
121991
122256
  try {
121992
122257
  canonicalPath2 = realpathSync20.native(absolutePath);
121993
122258
  } catch (canonicalPathError) {
121994
- canonicalPathError instanceof Error;
121995
122259
  canonicalPath2 = absolutePath;
121996
122260
  }
121997
122261
  } else {
@@ -124907,16 +125171,41 @@ function formatFsyncSkipWarning(entries) {
124907
125171
  }
124908
125172
 
124909
125173
  // packages/omo-opencode/src/hooks/fsync-skip-warning/index.ts
125174
+ var FSYNC_SKIP_START_TTL_MS = 60000;
125175
+ var startTimesByCallId = new Map;
125176
+ var cleanupInterval4 = null;
125177
+ function pruneStaleStartTimes(now = Date.now()) {
125178
+ for (const [callID, startedAt] of startTimesByCallId) {
125179
+ if (now - startedAt > FSYNC_SKIP_START_TTL_MS) {
125180
+ startTimesByCallId.delete(callID);
125181
+ }
125182
+ }
125183
+ }
125184
+ function ensureCleanupInterval2() {
125185
+ if (cleanupInterval4)
125186
+ return;
125187
+ cleanupInterval4 = setInterval(() => pruneStaleStartTimes(), FSYNC_SKIP_START_TTL_MS);
125188
+ if (typeof cleanupInterval4 === "object" && "unref" in cleanupInterval4) {
125189
+ cleanupInterval4.unref();
125190
+ }
125191
+ }
125192
+ function stopFsyncSkipWarningCleanup() {
125193
+ startTimesByCallId.clear();
125194
+ if (!cleanupInterval4)
125195
+ return;
125196
+ clearInterval(cleanupInterval4);
125197
+ cleanupInterval4 = null;
125198
+ }
124910
125199
  function createFsyncSkipWarningHook() {
124911
- const startTimesByCallId = new Map;
124912
125200
  const toolExecuteBefore = async (input, _output) => {
125201
+ ensureCleanupInterval2();
124913
125202
  startTimesByCallId.set(input.callID, Date.now());
124914
125203
  };
124915
125204
  const toolExecuteAfter = async (input, output) => {
124916
- if (typeof output.output !== "string")
124917
- return;
124918
125205
  const startTimestamp = startTimesByCallId.get(input.callID) ?? 0;
124919
125206
  startTimesByCallId.delete(input.callID);
125207
+ if (typeof output.output !== "string")
125208
+ return;
124920
125209
  const skips = drainSkipsAfter(startTimestamp);
124921
125210
  const warning = formatFsyncSkipWarning(skips);
124922
125211
  if (warning.length === 0)
@@ -124927,7 +125216,8 @@ ${warning}`;
124927
125216
  };
124928
125217
  return {
124929
125218
  "tool.execute.before": toolExecuteBefore,
124930
- "tool.execute.after": toolExecuteAfter
125219
+ "tool.execute.after": toolExecuteAfter,
125220
+ dispose: stopFsyncSkipWarningCleanup
124931
125221
  };
124932
125222
  }
124933
125223
  // packages/omo-opencode/src/hooks/notepad-write-guard/index.ts
@@ -126604,6 +126894,23 @@ Has Transcript: Yes (234 entries)`;
126604
126894
  import { existsSync as existsSync94 } from "fs";
126605
126895
  import { readdir as readdir7, readFile as readFile10 } from "fs/promises";
126606
126896
  import { join as join118 } from "path";
126897
+
126898
+ // packages/omo-opencode/src/tools/session-manager/directory-filter.ts
126899
+ import { normalize as normalize4, parse as parse3, sep as sep3 } from "path";
126900
+ function toComparisonSeparators(path19) {
126901
+ return sep3 === "\\" ? path19.replace(/\\/g, "/") : path19;
126902
+ }
126903
+ function normalizeSessionDirectory(directory) {
126904
+ const normalized = normalize4(directory);
126905
+ const root = parse3(normalized).root;
126906
+ const withoutTrailing = normalized !== root && normalized.endsWith(sep3) ? normalized.slice(0, -1) : normalized;
126907
+ return toComparisonSeparators(withoutTrailing);
126908
+ }
126909
+ function sessionDirectoriesMatch(stored, filter) {
126910
+ return normalizeSessionDirectory(stored) === normalizeSessionDirectory(filter);
126911
+ }
126912
+
126913
+ // packages/omo-opencode/src/tools/session-manager/file-storage.ts
126607
126914
  function ignoreFileStorageError(error) {
126608
126915
  if (error instanceof Error)
126609
126916
  return;
@@ -126628,7 +126935,7 @@ async function getFileMainSessions(directory) {
126628
126935
  const meta = JSON.parse(content);
126629
126936
  if (meta.parentID)
126630
126937
  continue;
126631
- if (directory && meta.directory !== directory)
126938
+ if (directory && !sessionDirectoriesMatch(meta.directory, directory))
126632
126939
  continue;
126633
126940
  sessions.push(meta);
126634
126941
  } catch (error) {
@@ -126882,7 +127189,7 @@ async function getSdkMainSessions(client3, directory) {
126882
127189
  const sessions = normalizeSDKResponse(response, []);
126883
127190
  const mainSessions = sessions.filter((session) => !session.parentID);
126884
127191
  if (directory) {
126885
- return mainSessions.filter((session) => session.directory === directory).sort((a, b) => b.time.updated - a.time.updated);
127192
+ return mainSessions.filter((session) => sessionDirectoriesMatch(session.directory, directory)).sort((a, b) => b.time.updated - a.time.updated);
126886
127193
  }
126887
127194
  return mainSessions.sort((a, b) => b.time.updated - a.time.updated);
126888
127195
  }
@@ -128278,7 +128585,11 @@ Session ID: ${task2.sessionId}
128278
128585
 
128279
128586
  ---
128280
128587
 
128281
- (No new output since last check)`;
128588
+ (No new output since last check)
128589
+
128590
+ To retrieve the complete output, re-call this tool with:
128591
+ - background_output(task_id="${task2.id}", full_session=true) \u2014 re-fetches all messages, bypassing the incremental cursor
128592
+ - Or use session_read(session_id="${task2.sessionId}") to read the full child session transcript`;
128282
128593
  }
128283
128594
  const extractedContent = [];
128284
128595
  for (const message of newMessages) {
@@ -129892,7 +130203,7 @@ import { pathToFileURL } from "url";
129892
130203
 
129893
130204
  // packages/omo-opencode/src/tools/look-at/image-converter.ts
129894
130205
  import * as childProcess2 from "child_process";
129895
- import { existsSync as existsSync101, mkdtempSync, readFileSync as readFileSync65, rmSync as rmSync5, unlinkSync as unlinkSync15, writeFileSync as writeFileSync23 } from "fs";
130206
+ import { existsSync as existsSync101, mkdtempSync, readFileSync as readFileSync65, rmSync as rmSync6, unlinkSync as unlinkSync15, writeFileSync as writeFileSync23 } from "fs";
129896
130207
  import { tmpdir as tmpdir7 } from "os";
129897
130208
  import { dirname as dirname45, join as join126 } from "path";
129898
130209
  var SUPPORTED_FORMATS = new Set([
@@ -130001,7 +130312,7 @@ function cleanupConvertedImage(filePath) {
130001
130312
  log2(`[image-converter] Cleaned up temporary file: ${filePath}`);
130002
130313
  }
130003
130314
  if (existsSync101(tempDirectory)) {
130004
- rmSync5(tempDirectory, { recursive: true, force: true });
130315
+ rmSync6(tempDirectory, { recursive: true, force: true });
130005
130316
  log2(`[image-converter] Cleaned up temporary directory: ${tempDirectory}`);
130006
130317
  }
130007
130318
  } catch (error) {
@@ -131683,6 +131994,7 @@ function getTerminalSessionError(messages) {
131683
131994
  init_logger2();
131684
131995
  var ACTIVE_SESSION_STATUSES2 = new Set(["busy", "retry", "running"]);
131685
131996
  var CHILD_WAKE_GRACE_MS = 5000;
131997
+ var MAX_NON_ACTIVE_STATUS_STALENESS_POLLS = 10;
131686
131998
  function wait(milliseconds) {
131687
131999
  const sharedBuffer = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT);
131688
132000
  const typedArray = new Int32Array(sharedBuffer);
@@ -131702,8 +132014,15 @@ function abortSyncSession(client3, sessionID, reason) {
131702
132014
  function isActiveSessionStatus(status) {
131703
132015
  return status !== undefined && ACTIVE_SESSION_STATUSES2.has(status.type);
131704
132016
  }
132017
+ function hasMessagesAfterAnchor(messages, anchorMessageID, anchorMessageCount) {
132018
+ if (anchorMessageID !== undefined) {
132019
+ const anchorIndex = messages.findIndex((message) => message.info?.id === anchorMessageID);
132020
+ return anchorIndex === -1 || anchorIndex < messages.length - 1;
132021
+ }
132022
+ return anchorMessageCount === undefined || messages.length > anchorMessageCount;
132023
+ }
131705
132024
  async function fetchSessionMessages(client3, sessionID) {
131706
- const messagesResult = await client3.session.messages({ path: { id: sessionID } });
132025
+ const messagesResult = await client3.session.messages({ path: { id: sessionID }, query: { limit: 100 } });
131707
132026
  const rawData = messagesResult?.data ?? messagesResult;
131708
132027
  return Array.isArray(rawData) ? rawData : [];
131709
132028
  }
@@ -131715,6 +132034,9 @@ async function pollSyncSession(ctx, client3, input, timeoutMs) {
131715
132034
  const pollStart = Date.now();
131716
132035
  let inactiveStart = pollStart;
131717
132036
  let pollCount = 0;
132037
+ let nonActivePollsSinceMessageFetch = 0;
132038
+ let lastStatusRevision;
132039
+ let hasFetchedNonActiveMessages = false;
131718
132040
  let timedOut = false;
131719
132041
  let assistantTurnCount = 0;
131720
132042
  let lastSeenAssistantId;
@@ -131762,7 +132084,7 @@ async function pollSyncSession(ctx, client3, input, timeoutMs) {
131762
132084
  }
131763
132085
  }
131764
132086
  if (finalMessages) {
131765
- const hasNewMessages = input.anchorMessageCount === undefined || finalMessages.length > input.anchorMessageCount;
132087
+ const hasNewMessages = hasMessagesAfterAnchor(finalMessages, input.anchorMessageID, input.anchorMessageCount);
131766
132088
  if (hasNewMessages && isSessionComplete(finalMessages)) {
131767
132089
  log2("[task] Abort detected after session already completed", { sessionID: input.sessionID });
131768
132090
  return null;
@@ -131800,6 +132122,15 @@ Session ID: ${input.sessionID}`;
131800
132122
  inactiveStart = Date.now();
131801
132123
  continue;
131802
132124
  }
132125
+ nonActivePollsSinceMessageFetch++;
132126
+ const statusRevision = sessionStatus && (sessionStatus.updatedAt ?? sessionStatus.revision ?? sessionStatus.messageCount);
132127
+ const statusChanged = statusRevision !== undefined && String(statusRevision) !== lastStatusRevision;
132128
+ if (hasFetchedNonActiveMessages && !statusChanged && nonActivePollsSinceMessageFetch < MAX_NON_ACTIVE_STATUS_STALENESS_POLLS) {
132129
+ continue;
132130
+ }
132131
+ lastStatusRevision = statusRevision === undefined ? lastStatusRevision : String(statusRevision);
132132
+ nonActivePollsSinceMessageFetch = 0;
132133
+ hasFetchedNonActiveMessages = true;
131803
132134
  let messages;
131804
132135
  try {
131805
132136
  messages = await fetchSessionMessages(client3, input.sessionID);
@@ -131808,9 +132139,8 @@ Session ID: ${input.sessionID}`;
131808
132139
  log2("[task] Poll messages fetch failed, retrying", { sessionID: input.sessionID, error: errorMessage });
131809
132140
  continue;
131810
132141
  }
131811
- if (input.anchorMessageCount !== undefined && messages.length <= input.anchorMessageCount) {
132142
+ if (!hasMessagesAfterAnchor(messages, input.anchorMessageID, input.anchorMessageCount))
131812
132143
  continue;
131813
- }
131814
132144
  const sessionError = getTerminalSessionError(messages);
131815
132145
  if (sessionError) {
131816
132146
  log2("[task] Poll detected terminal session error", { sessionID: input.sessionID, sessionError });
@@ -131992,6 +132322,54 @@ var syncContinuationDeps = {
131992
132322
 
131993
132323
  // packages/omo-opencode/src/tools/delegate-task/sync-continuation.ts
131994
132324
  init_logger2();
132325
+
132326
+ // packages/omo-opencode/src/features/background-agent/constants.ts
132327
+ var TASK_TTL_MS = 30 * 60 * 1000;
132328
+ var TERMINAL_TASK_TTL_MS = 30 * 60 * 1000;
132329
+ var MIN_STABILITY_TIME_MS2 = 10 * 1000;
132330
+ var DEFAULT_STALE_TIMEOUT_MS = 2700000;
132331
+ var DEFAULT_MESSAGE_STALENESS_TIMEOUT_MS = 3600000;
132332
+ var DEFAULT_MAX_TOOL_CALLS = 4000;
132333
+ var DEFAULT_CIRCUIT_BREAKER_CONSECUTIVE_THRESHOLD = 20;
132334
+ var DEFAULT_CIRCUIT_BREAKER_ENABLED = true;
132335
+ var MIN_RUNTIME_BEFORE_STALE_MS = 30000;
132336
+ var DEFAULT_SESSION_GONE_TIMEOUT_MS = 60000;
132337
+ var MIN_IDLE_TIME_MS = 5000;
132338
+ var POLLING_INTERVAL_MS = 3000;
132339
+ var TASK_CLEANUP_DELAY_MS = 10 * 60 * 1000;
132340
+
132341
+ // packages/omo-opencode/src/tools/delegate-task/sync-session-cleanup.ts
132342
+ init_logger2();
132343
+ var pendingDeletionTimers = new Map;
132344
+ function cancelSyncSessionDeletion(sessionID) {
132345
+ const timer = pendingDeletionTimers.get(sessionID);
132346
+ if (!timer)
132347
+ return;
132348
+ clearTimeout(timer);
132349
+ pendingDeletionTimers.delete(sessionID);
132350
+ }
132351
+ function scheduleSyncSessionDeletion(client3, sessionID, delayMs = TASK_CLEANUP_DELAY_MS) {
132352
+ cancelSyncSessionDeletion(sessionID);
132353
+ const deleteSession = client3?.session?.delete?.bind(client3.session);
132354
+ if (typeof deleteSession !== "function")
132355
+ return;
132356
+ const timer = setTimeout(() => {
132357
+ pendingDeletionTimers.delete(sessionID);
132358
+ try {
132359
+ deleteSession({ path: { id: sessionID } }).then(() => {
132360
+ handedBackSyncSessions.delete(sessionID);
132361
+ }).catch((error) => {
132362
+ log2("[task] Failed to delete completed sync session:", { sessionID, error: String(error) });
132363
+ });
132364
+ } catch (error) {
132365
+ log2("[task] Failed to schedule completed sync session deletion:", { sessionID, error: String(error) });
132366
+ }
132367
+ }, delayMs);
132368
+ pendingDeletionTimers.set(sessionID, timer);
132369
+ timer.unref();
132370
+ }
132371
+
132372
+ // packages/omo-opencode/src/tools/delegate-task/sync-continuation.ts
131995
132373
  function shouldAttemptPollErrorRecovery(pollError) {
131996
132374
  const trimmed = pollError.trim();
131997
132375
  if (trimmed.length === 0) {
@@ -132022,11 +132400,12 @@ async function resolveResumeContext(client3, continuationID) {
132022
132400
  resumeAgent: info.agent,
132023
132401
  resumeModel: info.model ?? (info.providerID && info.modelID ? { providerID: info.providerID, modelID: info.modelID } : undefined),
132024
132402
  resumeVariant: info.variant,
132025
- anchorMessageCount: messages.length
132403
+ anchorMessageCount: messages.length,
132404
+ anchorMessageID: messages.at(-1)?.info?.id
132026
132405
  };
132027
132406
  }
132028
132407
  }
132029
- return { anchorMessageCount: messages.length };
132408
+ return { anchorMessageCount: messages.length, anchorMessageID: messages.at(-1)?.info?.id };
132030
132409
  } catch (error) {
132031
132410
  if (!(error instanceof Error))
132032
132411
  throw error;
@@ -132047,6 +132426,7 @@ async function executeSyncContinuation(args, ctx, executorCtx, parentContext, de
132047
132426
  if (!continuationID) {
132048
132427
  throw new Error("task_id is required to continue a sync task");
132049
132428
  }
132429
+ cancelSyncSessionDeletion(continuationID);
132050
132430
  const taskId = `resume_sync_${continuationID.slice(0, 8)}`;
132051
132431
  const startTime = new Date;
132052
132432
  if (toastManager) {
@@ -132061,6 +132441,7 @@ async function executeSyncContinuation(args, ctx, executorCtx, parentContext, de
132061
132441
  let resumeModel;
132062
132442
  let resumeVariant;
132063
132443
  let anchorMessageCount;
132444
+ let anchorMessageID;
132064
132445
  let handedBackToParent = false;
132065
132446
  try {
132066
132447
  const resumeContext = await resolveResumeContext(client3, continuationID);
@@ -132068,6 +132449,7 @@ async function executeSyncContinuation(args, ctx, executorCtx, parentContext, de
132068
132449
  resumeModel = resumeContext.resumeModel;
132069
132450
  resumeVariant = resumeContext.resumeVariant;
132070
132451
  anchorMessageCount = resumeContext.anchorMessageCount;
132452
+ anchorMessageID = resumeContext.anchorMessageID;
132071
132453
  const resumeModelForMetadata = resumeModel && resumeVariant !== undefined ? { ...resumeModel, variant: resumeVariant } : resumeModel;
132072
132454
  const syncContMeta = {
132073
132455
  title: args.description,
@@ -132116,6 +132498,7 @@ async function executeSyncContinuation(args, ctx, executorCtx, parentContext, de
132116
132498
  toastManager.removeTask(taskId);
132117
132499
  }
132118
132500
  const errorMessage = promptError instanceof Error ? promptError.message : String(promptError);
132501
+ scheduleSyncSessionDeletion(client3, continuationID);
132119
132502
  return `Failed to send continuation prompt: ${errorMessage}
132120
132503
 
132121
132504
  Task ID: ${continuationID}`;
@@ -132126,7 +132509,8 @@ Task ID: ${continuationID}`;
132126
132509
  agentToUse: resumeAgent ?? "continue",
132127
132510
  toastManager,
132128
132511
  taskId,
132129
- anchorMessageCount
132512
+ anchorMessageCount,
132513
+ anchorMessageID
132130
132514
  }, syncPollTimeoutMs);
132131
132515
  if (pollError && shouldAttemptPollErrorRecovery(pollError)) {
132132
132516
  if (anchorMessageCount === undefined) {
@@ -132188,6 +132572,7 @@ ${buildTaskMetadataBlock({
132188
132572
  });
132189
132573
  }
132190
132574
  }
132575
+ scheduleSyncSessionDeletion(client3, continuationID);
132191
132576
  }
132192
132577
  }
132193
132578
  // packages/omo-opencode/src/tools/delegate-task/cancel-unstable-agent-task.ts
@@ -133151,7 +133536,14 @@ async function executeSyncTask(args, ctx, executorCtx, parentContext, agentToUse
133151
133536
  let taskId;
133152
133537
  let syncSessionID;
133153
133538
  let spawnReservation;
133539
+ let concurrencyAcquired = false;
133540
+ const concurrencyModel = categoryModel && typeof categoryModel.providerID === "string" && typeof categoryModel.modelID === "string" ? `${categoryModel.providerID}/${categoryModel.modelID}` : typeof agentToUse === "string" ? agentToUse : "default";
133541
+ const manager = executorCtx?.manager;
133154
133542
  try {
133543
+ if (!subagentSessions.has(parentContext.sessionID) && typeof manager?.acquireSyncSubagentConcurrency === "function") {
133544
+ await manager.acquireSyncSubagentConcurrency(concurrencyModel);
133545
+ concurrencyAcquired = true;
133546
+ }
133155
133547
  const spawn5 = await reserveSyncSubagentSpawn(executorCtx, parentContext);
133156
133548
  spawnReservation = spawn5.reservation;
133157
133549
  const { spawnContext } = spawn5;
@@ -133260,11 +133652,15 @@ async function executeSyncTask(args, ctx, executorCtx, parentContext, agentToUse
133260
133652
  if (syncSessionID) {
133261
133653
  cleanupSyncSessionSideEffects(syncSessionID, executorCtx);
133262
133654
  handedBackSyncSessions.add(syncSessionID);
133263
- if (typeof client3.session.abort === "function") {
133655
+ if (typeof client3?.session?.abort === "function") {
133264
133656
  client3.session.abort({ path: { id: syncSessionID } }).catch((error) => {
133265
133657
  log2(`[task] Failed to abort completed sync session:`, error);
133266
133658
  });
133267
133659
  }
133660
+ scheduleSyncSessionDeletion(client3, syncSessionID);
133661
+ }
133662
+ if (concurrencyAcquired && typeof manager?.releaseSyncSubagentConcurrency === "function") {
133663
+ manager.releaseSyncSubagentConcurrency(concurrencyModel);
133268
133664
  }
133269
133665
  }
133270
133666
  }
@@ -135406,7 +135802,8 @@ async function deliverLiveToRecipient(input) {
135406
135802
  recipientMember,
135407
135803
  reservation,
135408
135804
  config: config3,
135409
- directory
135805
+ directory,
135806
+ settleMs
135410
135807
  } = input;
135411
135808
  const recipientSessionId = recipientMember.sessionId;
135412
135809
  if (recipientMember.pendingInjectedMessageIds.length > 0) {
@@ -135466,6 +135863,7 @@ async function deliverLiveToRecipient(input) {
135466
135863
  sessionID: recipientSessionId,
135467
135864
  source: "team-live-delivery",
135468
135865
  queueBehavior: "defer",
135866
+ settleMs,
135469
135867
  input: {
135470
135868
  path: { id: recipientSessionId },
135471
135869
  body: buildMemberPromptBody(recipientMember, envelope),
@@ -135600,7 +135998,8 @@ async function deliverLive(client3, message, teamRunId, deliveredTo, config3, di
135600
135998
  recipientMember,
135601
135999
  reservation,
135602
136000
  config: config3,
135603
- directory
136001
+ directory,
136002
+ settleMs: deps.liveDeliverySettleMs
135604
136003
  });
135605
136004
  }
135606
136005
  }
@@ -136926,10 +137325,13 @@ function mergeStoredMessages(messages, sessionID) {
136926
137325
  ...message.model.variant ? { variant: message.model.variant } : {}
136927
137326
  };
136928
137327
  }
137328
+ if (merged.model?.providerID && merged.model.modelID && !merged.model.variant && message.model?.providerID === merged.model.providerID && message.model.modelID === merged.model.modelID && message.model.variant) {
137329
+ merged.model.variant = message.model.variant;
137330
+ }
136929
137331
  if (!merged.tools && message.tools) {
136930
137332
  merged.tools = message.tools;
136931
137333
  }
136932
- if (hasFullAgentAndModel(merged) && merged.tools) {
137334
+ if (hasFullAgentAndModel(merged) && merged.tools && merged.model?.variant) {
136933
137335
  break;
136934
137336
  }
136935
137337
  }
@@ -137105,21 +137507,6 @@ class ConcurrencyManager {
137105
137507
  }
137106
137508
  }
137107
137509
 
137108
- // packages/omo-opencode/src/features/background-agent/constants.ts
137109
- var TASK_TTL_MS = 30 * 60 * 1000;
137110
- var TERMINAL_TASK_TTL_MS = 30 * 60 * 1000;
137111
- var MIN_STABILITY_TIME_MS2 = 10 * 1000;
137112
- var DEFAULT_STALE_TIMEOUT_MS = 2700000;
137113
- var DEFAULT_MESSAGE_STALENESS_TIMEOUT_MS = 3600000;
137114
- var DEFAULT_MAX_TOOL_CALLS = 4000;
137115
- var DEFAULT_CIRCUIT_BREAKER_CONSECUTIVE_THRESHOLD = 20;
137116
- var DEFAULT_CIRCUIT_BREAKER_ENABLED = true;
137117
- var MIN_RUNTIME_BEFORE_STALE_MS = 30000;
137118
- var DEFAULT_SESSION_GONE_TIMEOUT_MS = 60000;
137119
- var MIN_IDLE_TIME_MS = 5000;
137120
- var POLLING_INTERVAL_MS = 3000;
137121
- var TASK_CLEANUP_DELAY_MS = 10 * 60 * 1000;
137122
-
137123
137510
  // packages/omo-opencode/src/features/background-agent/duration-formatter.ts
137124
137511
  function formatDuration3(start, end) {
137125
137512
  const duration = (end ?? new Date).getTime() - start.getTime();
@@ -137557,9 +137944,6 @@ class ParentWakeDispatchedTracker {
137557
137944
  getWake(sessionID) {
137558
137945
  return this.dispatchedParentWakes.get(sessionID);
137559
137946
  }
137560
- hasWake(sessionID) {
137561
- return this.dispatchedParentWakes.has(sessionID);
137562
- }
137563
137947
  clearWake(sessionID) {
137564
137948
  const timer = this.dispatchedParentWakeTimers.get(sessionID);
137565
137949
  if (timer) {
@@ -137608,7 +137992,7 @@ class ParentWakeDispatchedTracker {
137608
137992
  }
137609
137993
  }
137610
137994
 
137611
- // packages/omo-opencode/src/shared/prompt-async-gate/prompt-message-state.ts
137995
+ // packages/omo-opencode/src/features/background-agent/parent-wake-history-state.ts
137612
137996
  init_prompt_message_state();
137613
137997
 
137614
137998
  // packages/omo-opencode/src/features/background-agent/parent-wake-message-activity.ts
@@ -138160,10 +138544,11 @@ class ParentWakePendingQueue {
138160
138544
  }
138161
138545
  }
138162
138546
 
138163
- // packages/omo-opencode/src/shared/prompt-async-gate/message-inspection-error.ts
138547
+ // packages/omo-opencode/src/features/background-agent/parent-wake-session-inspector.ts
138164
138548
  init_message_inspection_error();
138165
138549
 
138166
138550
  // packages/omo-opencode/src/features/background-agent/parent-wake-session-history.ts
138551
+ init_pending_tool_turn();
138167
138552
  function parentWakeUserMessageIsInProgress(input) {
138168
138553
  if (input.windowMs <= 0) {
138169
138554
  return false;
@@ -139108,31 +139493,29 @@ function invokeTmuxSessionCreatedCallback(invocation) {
139108
139493
 
139109
139494
  // packages/omo-opencode/src/features/background-agent/subagent-spawn-limits.ts
139110
139495
  var DEFAULT_MAX_SUBAGENT_DEPTH = 3;
139496
+ var DEFAULT_MAX_LIVE_DESCENDANTS_PER_ROOT = 24;
139111
139497
  function getMaxSubagentDepth(config3) {
139112
139498
  return config3?.maxDepth ?? DEFAULT_MAX_SUBAGENT_DEPTH;
139113
139499
  }
139500
+ function getMaxLiveDescendantsPerRoot(config3) {
139501
+ return config3?.maxLiveDescendantsPerRoot ?? DEFAULT_MAX_LIVE_DESCENDANTS_PER_ROOT;
139502
+ }
139114
139503
  async function resolveSubagentSpawnContext(client3, parentSessionID, directory) {
139115
139504
  const visitedSessionIDs = new Set;
139116
139505
  let rootSessionID = parentSessionID;
139117
139506
  let currentSessionID = parentSessionID;
139118
139507
  let parentDepth = 0;
139119
139508
  while (true) {
139120
- if (visitedSessionIDs.has(currentSessionID)) {
139509
+ if (visitedSessionIDs.has(currentSessionID))
139121
139510
  throw new Error(`Detected a session parent cycle while resolving ${parentSessionID}`);
139122
- }
139123
139511
  visitedSessionIDs.add(currentSessionID);
139124
139512
  let nextParentSessionID;
139125
139513
  try {
139126
- const response = await client3.session.get({
139127
- path: { id: currentSessionID },
139128
- ...directory ? { query: { directory } } : {}
139129
- });
139130
- if (response.error) {
139514
+ const response = await client3.session.get({ path: { id: currentSessionID }, ...directory ? { query: { directory } } : {} });
139515
+ if (response.error)
139131
139516
  throw new Error(String(response.error));
139132
- }
139133
- if (!response.data) {
139517
+ if (!response.data)
139134
139518
  throw new Error("No session data returned");
139135
- }
139136
139519
  nextParentSessionID = response.data.parentID;
139137
139520
  } catch (error) {
139138
139521
  const reason = error instanceof Error ? error.message : String(error);
@@ -139145,15 +139528,13 @@ async function resolveSubagentSpawnContext(client3, parentSessionID, directory)
139145
139528
  currentSessionID = nextParentSessionID;
139146
139529
  parentDepth += 1;
139147
139530
  }
139148
- return {
139149
- rootSessionID,
139150
- parentDepth,
139151
- childDepth: parentDepth + 1
139152
- };
139531
+ return { rootSessionID, parentDepth, childDepth: parentDepth + 1 };
139153
139532
  }
139154
139533
  function createSubagentDepthLimitError(input) {
139155
- const { childDepth, maxDepth, parentSessionID, rootSessionID } = input;
139156
- return new Error(`Subagent spawn blocked: child depth ${childDepth} exceeds background_task.maxDepth=${maxDepth}. Parent session: ${parentSessionID}. Root session: ${rootSessionID}. Continue in an existing subagent session instead of spawning another.`);
139534
+ return new Error(`Subagent spawn blocked: child depth ${input.childDepth} exceeds background_task.maxDepth=${input.maxDepth}. Parent session: ${input.parentSessionID}. Root session: ${input.rootSessionID}. Continue in an existing subagent session instead of spawning another.`);
139535
+ }
139536
+ function createSubagentDescendantLimitError(input) {
139537
+ return new Error(`Subagent spawn blocked: root session ${input.rootSessionID} already has ${input.descendantCount} live descendants, reaching background_task.maxLiveDescendantsPerRoot=${input.maxDescendants}. Parent session: ${input.parentSessionID}.`);
139157
139538
  }
139158
139539
 
139159
139540
  // packages/omo-opencode/src/features/background-agent/task-history.ts
@@ -139855,6 +140236,16 @@ class BackgroundManager {
139855
140236
  }
139856
140237
  async reserveSubagentSpawn(parentSessionID) {
139857
140238
  const spawnContext = await this.assertCanSpawn(parentSessionID);
140239
+ const maxDescendants = getMaxLiveDescendantsPerRoot(this.config);
140240
+ const currentCount = this.rootDescendantCounts.get(spawnContext.rootSessionID) ?? 0;
140241
+ if (maxDescendants !== 0 && currentCount >= maxDescendants) {
140242
+ throw createSubagentDescendantLimitError({
140243
+ descendantCount: currentCount,
140244
+ maxDescendants,
140245
+ parentSessionID,
140246
+ rootSessionID: spawnContext.rootSessionID
140247
+ });
140248
+ }
139858
140249
  const descendantCount = this.registerRootDescendant(spawnContext.rootSessionID);
139859
140250
  let settled = false;
139860
140251
  return {
@@ -139872,6 +140263,12 @@ class BackgroundManager {
139872
140263
  }
139873
140264
  };
139874
140265
  }
140266
+ async acquireSyncSubagentConcurrency(model, taskId) {
140267
+ await this.concurrencyManager.acquire(model, taskId);
140268
+ }
140269
+ releaseSyncSubagentConcurrency(model) {
140270
+ this.concurrencyManager.release(model);
140271
+ }
139875
140272
  registerRootDescendant(rootSessionID) {
139876
140273
  const nextCount = (this.rootDescendantCounts.get(rootSessionID) ?? 0) + 1;
139877
140274
  this.rootDescendantCounts.set(rootSessionID, nextCount);
@@ -140775,18 +141172,6 @@ The fallback retry session is now created and can be inspected directly.
140775
141172
  clearSessionTodoObservation(sessionID) {
140776
141173
  this.observedIncompleteTodosBySession.delete(sessionID);
140777
141174
  }
140778
- messageUpdatedInfoHasParentWakeOutput(info, role) {
140779
- if (role === "tool") {
140780
- return true;
140781
- }
140782
- if (role !== "assistant") {
140783
- return false;
140784
- }
140785
- if (info.error) {
140786
- return false;
140787
- }
140788
- return !isEmptyNoProgressAssistantTurnInfo(info);
140789
- }
140790
141175
  shouldHoldDispatchedParentWakeForTextDelta(eventType, partInfo, sessionID, wake) {
140791
141176
  if (eventType !== "message.part.delta") {
140792
141177
  return false;
@@ -141414,7 +141799,7 @@ The task was re-queued on a fallback model after a retryable failure.
141414
141799
  clearTimeout(existingTimer);
141415
141800
  this.completionTimers.delete(taskId);
141416
141801
  }
141417
- const timer = setTimeout(() => {
141802
+ const timer = setTimeout(async () => {
141418
141803
  this.completionTimers.delete(taskId);
141419
141804
  const task2 = this.tasks.get(taskId);
141420
141805
  if (!task2)
@@ -141436,6 +141821,12 @@ The task was re-queued on a fallback model after a retryable failure.
141436
141821
  subagentSessions.delete(task2.sessionId);
141437
141822
  clearDelegatedChildSessionBootstrap(task2.sessionId);
141438
141823
  SessionCategoryRegistry.remove(task2.sessionId);
141824
+ const deleteSession = this.client.session.delete?.bind(this.client.session);
141825
+ if (typeof deleteSession === "function") {
141826
+ await deleteSession({ path: { id: task2.sessionId } }).catch((error) => {
141827
+ log2("[background-agent] Failed to delete completed subagent session:", { sessionID: task2.sessionId, error: String(error) });
141828
+ });
141829
+ }
141439
141830
  }
141440
141831
  log2("[background-agent] Removed completed task from memory:", taskId);
141441
141832
  }, this.config?.taskCleanupDelayMs ?? TASK_CLEANUP_DELAY_MS);
@@ -142421,6 +142812,7 @@ function formatStatus(record12, batch2) {
142421
142812
  }
142422
142813
 
142423
142814
  // packages/omo-opencode/src/features/monitor/output-injector-session-inspect.ts
142815
+ init_pending_tool_turn();
142424
142816
  async function loadMonitorSessionMessages(client3, directory, sessionID) {
142425
142817
  try {
142426
142818
  const messagesResp = await client3.session?.messages?.({
@@ -148047,6 +148439,7 @@ var SENSITIVE_PATTERNS = [
148047
148439
  /sk-[a-zA-Z0-9]{20,}/g,
148048
148440
  /gh[pousr]_[a-zA-Z0-9]{20,}/gi,
148049
148441
  /glpat-[a-zA-Z0-9_-]{20,}/gi,
148442
+ /xox[baprs]-[a-zA-Z0-9-]{10,}/gi,
148050
148443
  /[A-Za-z0-9_]{20,}-[A-Za-z0-9_]{10,}-[A-Za-z0-9_]{10,}/g
148051
148444
  ];
148052
148445
  var REDACTION_MARKER = "[REDACTED]";
@@ -148554,10 +148947,9 @@ class StdioClientTransport {
148554
148947
  // packages/mcp-client-core/src/skill-mcp-manager/env-cleaner.ts
148555
148948
  var EXCLUDED_ENV_PATTERNS = [
148556
148949
  /^NPM_CONFIG_/i,
148557
- /^npm_config_/,
148558
- /^YARN_/,
148559
- /^PNPM_/,
148560
- /^NO_UPDATE_NOTIFIER$/,
148950
+ /^YARN_/i,
148951
+ /^PNPM_/i,
148952
+ /^NO_UPDATE_NOTIFIER$/i,
148561
148953
  /^ANTHROPIC_API_KEY$/i,
148562
148954
  /^AWS_ACCESS_KEY_ID$/i,
148563
148955
  /^AWS_SECRET_ACCESS_KEY$/i,
@@ -149329,6 +149721,7 @@ class TuiStateMirror {
149329
149721
  this.heartbeatID = setInterval(() => {
149330
149722
  this.flush();
149331
149723
  }, HEARTBEAT_MS);
149724
+ this.heartbeatID.unref?.();
149332
149725
  }
149333
149726
  stop() {
149334
149727
  this.stopped = true;
@@ -153106,10 +153499,17 @@ async function createRuntimeSkillSourceServer(options, runtimeEnv = runtime6) {
153106
153499
  import { existsSync as existsSync112, readFileSync as readFileSync77 } from "fs";
153107
153500
  import { join as join142 } from "path";
153108
153501
  import { homedir as homedir36 } from "os";
153109
- function getMcpConfigPaths() {
153110
- const claudeConfigDir = getClaudeConfigDir3();
153111
- const homeDir = getHomeDir();
153112
- const cwd = process.cwd();
153502
+ function resolveMcpLoaderContext(options = {}) {
153503
+ const cwd = options.cwd ?? process.cwd();
153504
+ const homeDir = options.homeDir ?? getHomeDir();
153505
+ const claudeConfigDir = options.claudeConfigDir ?? (options.homeDir === undefined ? getClaudeConfigDir3() : join142(homeDir, ".claude"));
153506
+ return { cwd, homeDir, claudeConfigDir };
153507
+ }
153508
+ var mcpLoaderInternals = {
153509
+ resolveMcpLoaderContext
153510
+ };
153511
+ function getMcpConfigPaths(context) {
153512
+ const { claudeConfigDir, homeDir, cwd } = context;
153113
153513
  return [
153114
153514
  { path: join142(homeDir, ".claude.json"), scope: "user" },
153115
153515
  { path: join142(claudeConfigDir, ".mcp.json"), scope: "user" },
@@ -153136,10 +153536,11 @@ async function loadMcpConfigFile(filePath) {
153136
153536
  return null;
153137
153537
  }
153138
153538
  }
153139
- function getSystemMcpServerNames() {
153539
+ function getSystemMcpServerNames(options = {}) {
153140
153540
  const names = new Set;
153141
- const paths3 = getMcpConfigPaths();
153142
- const cwd = process.cwd();
153541
+ const context = mcpLoaderInternals.resolveMcpLoaderContext(options);
153542
+ const paths3 = getMcpConfigPaths(context);
153543
+ const { cwd } = context;
153143
153544
  for (const { path: path22 } of paths3) {
153144
153545
  if (!existsSync112(path22))
153145
153546
  continue;
@@ -153165,12 +153566,13 @@ function getSystemMcpServerNames() {
153165
153566
  }
153166
153567
  return names;
153167
153568
  }
153168
- async function loadMcpConfigs(disabledMcps = []) {
153569
+ async function loadMcpConfigs(disabledMcps = [], options = {}) {
153169
153570
  const servers = {};
153170
153571
  const loadedServers = [];
153171
- const paths3 = getMcpConfigPaths();
153572
+ const context = mcpLoaderInternals.resolveMcpLoaderContext(options);
153573
+ const paths3 = getMcpConfigPaths(context);
153172
153574
  const disabledSet = new Set(disabledMcps);
153173
- const cwd = process.cwd();
153575
+ const { cwd } = context;
153174
153576
  for (const { path: path22, scope } of paths3) {
153175
153577
  const config3 = await loadMcpConfigFile(path22);
153176
153578
  if (!config3?.mcpServers)
@@ -153864,7 +154266,7 @@ var opengateway_models_default = {
153864
154266
  cache_write: 0
153865
154267
  },
153866
154268
  limit: {
153867
- context: 1048576,
154269
+ context: 262144,
153868
154270
  output: 131072
153869
154271
  }
153870
154272
  },
@@ -173235,7 +173637,7 @@ async function createTools(args) {
173235
173637
  }
173236
173638
  // packages/omo-opencode/src/plugin-dispose.ts
173237
173639
  function createPluginDispose(args) {
173238
- const { backgroundManager, skillMcpManager, disposeHooks } = args;
173640
+ const { backgroundManager, skillMcpManager, tuiStateMirror, disposeHooks } = args;
173239
173641
  let disposePromise = null;
173240
173642
  return async () => {
173241
173643
  if (disposePromise) {
@@ -173243,6 +173645,11 @@ function createPluginDispose(args) {
173243
173645
  return;
173244
173646
  }
173245
173647
  disposePromise = (async () => {
173648
+ try {
173649
+ tuiStateMirror?.stop();
173650
+ } catch (error) {
173651
+ log2("[plugin-dispose] tuiStateMirror.stop() error:", error);
173652
+ }
173246
173653
  try {
173247
173654
  await backgroundManager.shutdown();
173248
173655
  } catch (error) {
@@ -174874,6 +175281,8 @@ async function handleSessionDeletedEvent(args) {
174874
175281
  await args.managers.monitorManager?.stopSessionMonitors(sessionID);
174875
175282
  const wasSyncSubagentSession = syncSubagentSessions.has(sessionID);
174876
175283
  clearSessionAgent(sessionID);
175284
+ handedBackSyncSessions.delete(sessionID);
175285
+ subagentSessions.delete(sessionID);
174877
175286
  args.clearModelFallbackSession(sessionID);
174878
175287
  resetMessageCursor(sessionID);
174879
175288
  clearBackgroundOutputConsumptionsForParentSession(sessionID);
@@ -174885,8 +175294,6 @@ async function handleSessionDeletedEvent(args) {
174885
175294
  if (!isBtwSideSession) {
174886
175295
  await dispatchOpenClawSessionEvent({ ...args, rawEvent: "session.deleted", sessionID });
174887
175296
  }
174888
- if (wasSyncSubagentSession)
174889
- subagentSessions.delete(sessionID);
174890
175297
  deleteSessionTools(sessionID);
174891
175298
  await args.managers.skillMcpManager.disconnectSession(sessionID);
174892
175299
  if (args.tmuxIntegrationEnabled && !isBtwSideSession) {
@@ -176429,7 +176836,7 @@ function getTelemetryHost(env2 = process.env, defaultHost = DEFAULT_POSTHOG_HOST
176429
176836
  }
176430
176837
 
176431
176838
  // node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
176432
- import { dirname as dirname52, posix as posix12, sep as sep3 } from "path";
176839
+ import { dirname as dirname52, posix as posix12, sep as sep4 } from "path";
176433
176840
  function createModulerModifier() {
176434
176841
  const getModuleFromFileName = createGetModuleFromFilename();
176435
176842
  return async (frames) => {
@@ -176438,7 +176845,7 @@ function createModulerModifier() {
176438
176845
  return frames;
176439
176846
  };
176440
176847
  }
176441
- function createGetModuleFromFilename(basePath = process.argv[1] ? dirname52(process.argv[1]) : process.cwd(), isWindows2 = sep3 === "\\") {
176848
+ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname52(process.argv[1]) : process.cwd(), isWindows2 = sep4 === "\\") {
176442
176849
  const normalizedBase = isWindows2 ? normalizeWindowsPath(basePath) : basePath;
176443
176850
  return (filename) => {
176444
176851
  if (!filename)
@@ -180454,9 +180861,9 @@ function snipLine(line, colno) {
180454
180861
  }
180455
180862
 
180456
180863
  // node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/relative-path.node.mjs
180457
- import { isAbsolute as isAbsolute21, relative as relative16, sep as sep4 } from "path";
180864
+ import { isAbsolute as isAbsolute21, relative as relative16, sep as sep5 } from "path";
180458
180865
  function createRelativePathModifier(basePath = process.cwd()) {
180459
- const isWindows2 = sep4 === "\\";
180866
+ const isWindows2 = sep5 === "\\";
180460
180867
  const toUnix = (p) => isWindows2 ? p.replace(/\\/g, "/") : p;
180461
180868
  const normalizedBase = toUnix(basePath);
180462
180869
  return async (frames) => {
@@ -184121,6 +184528,7 @@ function createPluginModule(overrides2 = {}) {
184121
184528
  const dispose = createPluginDispose({
184122
184529
  backgroundManager: managers.backgroundManager,
184123
184530
  skillMcpManager: managers.skillMcpManager,
184531
+ tuiStateMirror: managers.tuiStateMirror,
184124
184532
  disposeHooks: hooks2.disposeHooks
184125
184533
  });
184126
184534
  const pluginHooks = {