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
@@ -9233,6 +9233,11 @@
9233
9233
  "minimum": 1,
9234
9234
  "maximum": 9007199254740991
9235
9235
  },
9236
+ "maxLiveDescendantsPerRoot": {
9237
+ "type": "integer",
9238
+ "minimum": 0,
9239
+ "maximum": 9007199254740991
9240
+ },
9236
9241
  "staleTimeoutMs": {
9237
9242
  "type": "number",
9238
9243
  "minimum": 60000
@@ -6,5 +6,8 @@ export declare function createPluginDispose(args: {
6
6
  skillMcpManager: {
7
7
  disconnectAll: () => Promise<void>;
8
8
  };
9
+ tuiStateMirror?: {
10
+ stop: () => void;
11
+ };
9
12
  disposeHooks: () => void;
10
13
  }): PluginDispose;
@@ -2,5 +2,4 @@ type AgentToolRestrictionsOptions = {
2
2
  includeTeamToolDenylist?: boolean;
3
3
  };
4
4
  export declare function getAgentToolRestrictions(agentName: string, options?: AgentToolRestrictionsOptions): Record<string, boolean>;
5
- export declare function hasAgentToolRestrictions(agentName: string): boolean;
6
5
  export {};
@@ -16,7 +16,8 @@
16
16
  1. WebFetch, 즉흥 curl, 수동 헤더 조합 **시도 금지**
17
17
  2. 즉시 다음을 실행:
18
18
  ```bash
19
- python3 -m engine "<URL>" [--selector "<CSS>"] [--device auto|desktop|mobile] [--trace]
19
+ python3 -m engine "<URL>" [--selector "<CSS>"] [--device auto|desktop|mobile] [--trace] \
20
+ [--no-retry] [--no-extract]
20
21
  ```
21
22
  3. 종료코드 0(ok) 또는 1(fail) 받은 뒤 판단. trace를 먼저 읽고 재시도 결정.
22
23
  4. 실패 시에만 `--trace --json`으로 재호출해서 원인 진단 후 `--device` 또는 `user_hint` 조정.
@@ -135,7 +136,13 @@ result = fetch(
135
136
 
136
137
  if result.ok:
137
138
  print(result.verdict) # strong_ok | weak_ok
138
- html = result.content
139
+ html = result.content # raw body — 단, content-rescue가 발동한 경우 구조 텍스트
140
+ # v0.10.0 content-rescue: PDF 응답은 pypdf 추출 텍스트, visible text가 얇은
141
+ # SPA 셸은 JSON-LD articleBody / 렌더된 innerText로 대체될 수 있다.
142
+ # result.extraction_source로 판별: "raw"(원문 그대로) | pdf | json_ld | *+inner_text.
143
+ # 일반 HTML 성공은 항상 raw. 끄기: enable_extraction=False / --no-extract.
144
+ # 429/502/503/504는 probe에서 백오프 재시도(Retry-After 반영, 총 10초 캡);
145
+ # 끄기: enable_retry=False / --no-retry.
139
146
  else:
140
147
  # Phase 3 수동 개입 (Playwright MCP) 필요 — result.trace로 원인 진단
141
148
  pass
@@ -0,0 +1,3 @@
1
+ import type { OpencodeClient } from "./types";
2
+ export declare function cancelSyncSessionDeletion(sessionID: string): void;
3
+ export declare function scheduleSyncSessionDeletion(client: OpencodeClient, sessionID: string, delayMs?: number): void;
@@ -8,6 +8,7 @@ export declare function pollSyncSession(ctx: ToolContextWithMetadata, client: Op
8
8
  } | null | undefined;
9
9
  taskId: string | undefined;
10
10
  anchorMessageCount?: number;
11
+ anchorMessageID?: string;
11
12
  maxAssistantTurns?: number;
12
13
  hasActiveChildBackgroundTasks?: (sessionID: string) => boolean;
13
14
  hasPendingParentWake?: (sessionID: string) => boolean;
@@ -46,6 +46,7 @@ export interface OmoAgentClient {
46
46
  };
47
47
  readonly session: {
48
48
  readonly abort: (input: SessionPathInput) => Promise<unknown>;
49
+ readonly delete?: (input: SessionPathInput) => Promise<unknown>;
49
50
  readonly create: (input: {
50
51
  readonly body: Record<string, unknown>;
51
52
  readonly query?: {
@@ -0,0 +1,2 @@
1
+ export declare function normalizeSessionDirectory(directory: string): string;
2
+ export declare function sessionDirectoriesMatch(stored: string, filter: string): boolean;
package/dist/tui.js CHANGED
@@ -17156,7 +17156,7 @@ var init_git_master = __esm(() => {
17156
17156
  });
17157
17157
 
17158
17158
  // packages/omo-config-core/src/schema/memory.ts
17159
- var OmoMemoryReflectionTriggerSchema, OmoMemoryReflectionSchema, OmoMemorySyncSchema, OmoMemorySearchSchema, OmoMemoryNudgeSchema, OmoMemoryFactsSchema, OmoMemoryDreamSchema, OmoMemoryPeopleSchema, OmoMemorySoulSchema, OmoMemoryWriteNoticeSchema, OmoMemoryReflectionTriggerLayerSchema, OmoMemoryReflectionLayerSchema, OmoMemorySyncLayerSchema, OmoMemorySearchLayerSchema, OmoMemoryNudgeLayerSchema, OmoMemoryFactsLayerSchema, OmoMemoryDreamLayerSchema, OmoMemoryPeopleLayerSchema, OmoMemorySoulLayerSchema, OmoMemoryWriteNoticeLayerSchema, OmoMemoryAgentOverridesSchema, OmoMemorySettingsSchema, OmoMemorySettingsLayerSchema;
17159
+ 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;
17160
17160
  var init_memory = __esm(() => {
17161
17161
  init_zod();
17162
17162
  OmoMemoryReflectionTriggerSchema = object({
@@ -17178,6 +17178,10 @@ var init_memory = __esm(() => {
17178
17178
  OmoMemorySearchSchema = object({
17179
17179
  enabled: boolean2().default(true)
17180
17180
  }).strict();
17181
+ OmoMemoryRecallSchema = object({
17182
+ enabled: boolean2().default(true),
17183
+ max_items: number2().int().min(1).max(5).default(2)
17184
+ }).strict();
17181
17185
  OmoMemoryNudgeSchema = object({
17182
17186
  enabled: boolean2().default(true),
17183
17187
  every_user_turns: number2().int().min(1).default(10)
@@ -17224,6 +17228,10 @@ var init_memory = __esm(() => {
17224
17228
  OmoMemorySearchLayerSchema = object({
17225
17229
  enabled: boolean2().optional()
17226
17230
  }).strict();
17231
+ OmoMemoryRecallLayerSchema = object({
17232
+ enabled: boolean2().optional(),
17233
+ max_items: number2().int().min(1).max(5).optional()
17234
+ }).strict();
17227
17235
  OmoMemoryNudgeLayerSchema = object({
17228
17236
  enabled: boolean2().optional(),
17229
17237
  every_user_turns: number2().int().min(1).optional()
@@ -17263,6 +17271,7 @@ var init_memory = __esm(() => {
17263
17271
  write_notice: OmoMemoryWriteNoticeLayerSchema.optional(),
17264
17272
  sync: OmoMemorySyncLayerSchema.optional(),
17265
17273
  search: OmoMemorySearchLayerSchema.optional(),
17274
+ recall: OmoMemoryRecallLayerSchema.optional(),
17266
17275
  compile_warn_tokens: number2().int().positive().optional()
17267
17276
  }).strict();
17268
17277
  OmoMemorySettingsSchema = object({
@@ -17292,6 +17301,7 @@ var init_memory = __esm(() => {
17292
17301
  write_notice: OmoMemoryWriteNoticeSchema.default({ enabled: true }),
17293
17302
  sync: OmoMemorySyncSchema.default({ enabled: true }),
17294
17303
  search: OmoMemorySearchSchema.default({ enabled: true }),
17304
+ recall: OmoMemoryRecallSchema.default({ enabled: true, max_items: 2 }),
17295
17305
  compile_warn_tokens: number2().int().positive().default(30000),
17296
17306
  agents: record(string2(), OmoMemoryAgentOverridesSchema).default({})
17297
17307
  }).strict();
@@ -17308,6 +17318,7 @@ var init_memory = __esm(() => {
17308
17318
  write_notice: OmoMemoryWriteNoticeLayerSchema.optional(),
17309
17319
  sync: OmoMemorySyncLayerSchema.optional(),
17310
17320
  search: OmoMemorySearchLayerSchema.optional(),
17321
+ recall: OmoMemoryRecallLayerSchema.optional(),
17311
17322
  compile_warn_tokens: number2().int().positive().optional(),
17312
17323
  agents: record(string2(), OmoMemoryAgentOverridesSchema).optional()
17313
17324
  }).strict();
@@ -17341,11 +17352,11 @@ function resolveOmoTaskSettings(input, resolveParallelism = availableParallelism
17341
17352
  const record2 = record(string2(), unknown()).parse(input);
17342
17353
  return OmoTaskSettingsSchema.parse({
17343
17354
  ...record2,
17344
- residency_max_children: record2["residency_max_children"] ?? Math.max(8, resolveParallelism() * 3),
17355
+ residency_max_children: record2["residency_max_children"] ?? Math.min(DEFAULT_RESIDENCY_MAX_CHILDREN, Math.max(8, resolveParallelism() * 2)),
17345
17356
  global_concurrency: record2["global_concurrency"] ?? Math.max(8, resolveParallelism() * 2)
17346
17357
  });
17347
17358
  }
17348
- var ResidencyMaxChildrenInputSchema, OmoTaskWaitSchema, OmoTaskTeamSettingsSchema, OmoTaskWarningsSchema, OmoTaskDagSettingsSchema, OmoTaskSettingsSchema, OmoTaskDagSettingsLayerSchema, OmoTaskWaitLayerSchema, OmoTaskTeamSettingsLayerSchema, OmoTaskWarningsLayerSchema, OmoTaskSettingsLayerSchema;
17359
+ var DEFAULT_RESIDENCY_MAX_CHILDREN = 16, ResidencyMaxChildrenInputSchema, OmoTaskWaitSchema, OmoTaskTeamSettingsSchema, OmoTaskWarningsSchema, OmoTaskDagSettingsSchema, OmoTaskSettingsSchema, OmoTaskDagSettingsLayerSchema, OmoTaskWaitLayerSchema, OmoTaskTeamSettingsLayerSchema, OmoTaskWarningsLayerSchema, OmoTaskSettingsLayerSchema;
17349
17360
  var init_task = __esm(() => {
17350
17361
  init_zod();
17351
17362
  ResidencyMaxChildrenInputSchema = union([number2().int().nonnegative(), literal("unlimited")]);
@@ -19367,6 +19378,33 @@ var init_agent_model_requirements = __esm(() => {
19367
19378
  { providers: ["opencode-go"], model: "glm-5.2" }
19368
19379
  ]
19369
19380
  },
19381
+ "omo-senpi-code-reviewer": {
19382
+ fallbackChain: [
19383
+ { providers: ["openai", "openai-codex"], model: "gpt-5.6-terra", variant: "medium" },
19384
+ { providers: ["github-copilot"], model: "gpt-5.6-terra", variant: "medium" },
19385
+ { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-6" },
19386
+ { providers: ["opencode-go"], model: "glm-5.2" },
19387
+ { providers: ["kimi-for-coding"], model: "kimi-k3" }
19388
+ ]
19389
+ },
19390
+ "omo-senpi-qa-executor": {
19391
+ fallbackChain: [
19392
+ { providers: ["openai", "openai-codex"], model: "gpt-5.6-luna", variant: "high" },
19393
+ { providers: ["github-copilot"], model: "gpt-5.6-luna", variant: "high" },
19394
+ { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-6" },
19395
+ { providers: ["opencode-go"], model: "glm-5.2" },
19396
+ { providers: ["kimi-for-coding"], model: "kimi-k3" }
19397
+ ]
19398
+ },
19399
+ "omo-senpi-gate-reviewer": {
19400
+ fallbackChain: [
19401
+ { providers: ["openai", "openai-codex"], model: "gpt-5.6-sol", variant: "low" },
19402
+ { providers: ["github-copilot"], model: "gpt-5.6-sol", variant: "low" },
19403
+ { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-5", variant: "max" },
19404
+ { providers: ["opencode-go"], model: "glm-5.2" },
19405
+ { providers: ["kimi-for-coding"], model: "kimi-k3" }
19406
+ ]
19407
+ },
19370
19408
  atlas: {
19371
19409
  fallbackChain: [
19372
19410
  { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-5" },
@@ -19996,6 +20034,111 @@ var init_supplemental_entries = __esm(() => {
19996
20034
  input: 272000,
19997
20035
  output: 128000
19998
20036
  }
20037
+ },
20038
+ "grok-4.5": {
20039
+ id: "grok-4.5",
20040
+ family: "grok",
20041
+ reasoning: false,
20042
+ temperature: true,
20043
+ toolCall: true,
20044
+ modalities: {
20045
+ input: ["text", "image"],
20046
+ output: ["text"]
20047
+ },
20048
+ limit: {
20049
+ context: 500000,
20050
+ output: 32768
20051
+ }
20052
+ },
20053
+ "xai/grok-4.5": {
20054
+ id: "xai/grok-4.5",
20055
+ family: "grok",
20056
+ reasoning: false,
20057
+ temperature: true,
20058
+ toolCall: true,
20059
+ modalities: {
20060
+ input: ["text", "image"],
20061
+ output: ["text"]
20062
+ },
20063
+ limit: {
20064
+ context: 500000,
20065
+ output: 32768
20066
+ }
20067
+ },
20068
+ "x-ai/grok-4.5": {
20069
+ id: "x-ai/grok-4.5",
20070
+ family: "grok",
20071
+ reasoning: false,
20072
+ temperature: true,
20073
+ toolCall: true,
20074
+ modalities: {
20075
+ input: ["text", "image"],
20076
+ output: ["text"]
20077
+ },
20078
+ limit: {
20079
+ context: 500000,
20080
+ output: 32768
20081
+ }
20082
+ },
20083
+ "grok-4.6": {
20084
+ id: "grok-4.6",
20085
+ family: "grok",
20086
+ reasoning: false,
20087
+ temperature: true,
20088
+ toolCall: true,
20089
+ modalities: {
20090
+ input: ["text", "image"],
20091
+ output: ["text"]
20092
+ },
20093
+ limit: {
20094
+ context: 500000,
20095
+ output: 32768
20096
+ }
20097
+ },
20098
+ "xai/grok-4.6": {
20099
+ id: "xai/grok-4.6",
20100
+ family: "grok",
20101
+ reasoning: false,
20102
+ temperature: true,
20103
+ toolCall: true,
20104
+ modalities: {
20105
+ input: ["text", "image"],
20106
+ output: ["text"]
20107
+ },
20108
+ limit: {
20109
+ context: 500000,
20110
+ output: 32768
20111
+ }
20112
+ },
20113
+ "xai/grok-build-0.1": {
20114
+ id: "xai/grok-build-0.1",
20115
+ family: "grok",
20116
+ reasoning: false,
20117
+ temperature: true,
20118
+ toolCall: true,
20119
+ modalities: {
20120
+ input: ["text", "image"],
20121
+ output: ["text"]
20122
+ },
20123
+ limit: {
20124
+ context: 256000,
20125
+ output: 32768
20126
+ }
20127
+ },
20128
+ "x-ai/grok-build-0.1": {
20129
+ id: "x-ai/grok-build-0.1",
20130
+ family: "grok",
20131
+ reasoning: false,
20132
+ temperature: true,
20133
+ toolCall: true,
20134
+ modalities: {
20135
+ input: ["text", "image"],
20136
+ output: ["text"]
20137
+ },
20138
+ limit: {
20139
+ context: 256000,
20140
+ output: 32768
20141
+ }
19999
20142
  }
20000
20143
  };
20001
20144
  });
@@ -78487,14 +78630,9 @@ var init_claude_code_plugin_loader = __esm(() => {
78487
78630
  init_hook_loader();
78488
78631
  });
78489
78632
 
78490
- // packages/omo-opencode/src/features/claude-code-plugin-loader/index.ts
78491
- var init_claude_code_plugin_loader2 = __esm(() => {
78492
- init_claude_code_plugin_loader();
78493
- });
78494
-
78495
78633
  // packages/omo-opencode/src/shared/plugin-command-discovery.ts
78496
78634
  var init_plugin_command_discovery = __esm(() => {
78497
- init_claude_code_plugin_loader2();
78635
+ init_claude_code_plugin_loader();
78498
78636
  });
78499
78637
 
78500
78638
  // packages/omo-opencode/src/shared/session-category-registry.ts
@@ -79135,6 +79273,7 @@ var init_background_task = __esm(() => {
79135
79273
  providerConcurrency: exports_external.record(exports_external.string(), exports_external.number().min(0)).optional(),
79136
79274
  modelConcurrency: exports_external.record(exports_external.string(), exports_external.number().min(0)).optional(),
79137
79275
  maxDepth: exports_external.number().int().min(1).optional(),
79276
+ maxLiveDescendantsPerRoot: exports_external.number().int().min(0).optional(),
79138
79277
  staleTimeoutMs: exports_external.number().min(60000).optional(),
79139
79278
  messageStalenessTimeoutMs: exports_external.number().min(60000).optional(),
79140
79279
  taskTtlMs: exports_external.number().min(300000).optional(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-opencode",
3
- "version": "5.0.0-beta.30",
3
+ "version": "5.0.0-beta.32",
4
4
  "description": "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
5
5
  "main": "./dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -113,6 +113,7 @@
113
113
  "install:codex-dev": "bun run script/build-codex-install.ts && bun run script/install-codex-dev.ts",
114
114
  "build:codex-plugin": "npm --prefix packages/omo-codex/plugin ci && bun run --cwd packages/omo-codex/plugin build",
115
115
  "build:senpi-plugin": "bun run build:lsp-daemon && bun run build:ast-grep-mcp && bun run build:senpi-plugin:stage",
116
+ "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",
116
117
  "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",
117
118
  "build:materialize-frontend": "node packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs --strict",
118
119
  "build:shared-skills-assets": "bun run build:materialize-frontend && rm -rf dist/skills && cp -R packages/shared-skills/skills dist/skills",
@@ -181,7 +182,7 @@
181
182
  "zod": "^4.4.3"
182
183
  },
183
184
  "devDependencies": {
184
- "@code-yeongyu/senpi": "2026.8.30-3",
185
+ "@code-yeongyu/senpi": "2026.9.2",
185
186
  "@oh-my-opencode/agents-md-core": "workspace:*",
186
187
  "@oh-my-opencode/ast-grep-mcp": "workspace:*",
187
188
  "@oh-my-opencode/boulder-state": "workspace:*",
@@ -222,18 +223,18 @@
222
223
  "typescript": "^7.0.2"
223
224
  },
224
225
  "optionalDependencies": {
225
- "oh-my-opencode-darwin-arm64": "5.0.0-beta.30",
226
- "oh-my-opencode-darwin-x64": "5.0.0-beta.30",
227
- "oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.30",
228
- "oh-my-opencode-linux-arm64": "5.0.0-beta.30",
229
- "oh-my-opencode-linux-arm64-musl": "5.0.0-beta.30",
230
- "oh-my-opencode-linux-x64": "5.0.0-beta.30",
231
- "oh-my-opencode-linux-x64-baseline": "5.0.0-beta.30",
232
- "oh-my-opencode-linux-x64-musl": "5.0.0-beta.30",
233
- "oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.30",
234
- "oh-my-opencode-windows-arm64": "5.0.0-beta.30",
235
- "oh-my-opencode-windows-x64": "5.0.0-beta.30",
236
- "oh-my-opencode-windows-x64-baseline": "5.0.0-beta.30"
226
+ "oh-my-opencode-darwin-arm64": "5.0.0-beta.32",
227
+ "oh-my-opencode-darwin-x64": "5.0.0-beta.32",
228
+ "oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.32",
229
+ "oh-my-opencode-linux-arm64": "5.0.0-beta.32",
230
+ "oh-my-opencode-linux-arm64-musl": "5.0.0-beta.32",
231
+ "oh-my-opencode-linux-x64": "5.0.0-beta.32",
232
+ "oh-my-opencode-linux-x64-baseline": "5.0.0-beta.32",
233
+ "oh-my-opencode-linux-x64-musl": "5.0.0-beta.32",
234
+ "oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.32",
235
+ "oh-my-opencode-windows-arm64": "5.0.0-beta.32",
236
+ "oh-my-opencode-windows-x64": "5.0.0-beta.32",
237
+ "oh-my-opencode-windows-x64-baseline": "5.0.0-beta.32"
237
238
  },
238
239
  "overrides": {
239
240
  "@earendil-works/pi-agent-core": "0.84.2",
@@ -251,6 +252,6 @@
251
252
  "@code-yeongyu/comment-checker"
252
253
  ],
253
254
  "patchedDependencies": {
254
- "@code-yeongyu/senpi@2026.8.30-3": "patches/@code-yeongyu%2Fsenpi@2026.8.30-3.patch"
255
+ "@code-yeongyu/senpi@2026.9.2": "patches/@code-yeongyu%2Fsenpi@2026.9.2.patch"
255
256
  }
256
257
  }
@@ -180,6 +180,7 @@ async function runJsonRpcStdioServer(config) {
180
180
  const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
181
181
  isClosed = true;
182
182
  config.onIdleTimeout?.();
183
+ config.input.destroy();
183
184
  });
184
185
  const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
185
186
  isClosed = true;
@@ -2,6 +2,8 @@ import { writeFileSync } from "node:fs";
2
2
 
3
3
  import { afterEach, describe, expect, it } from "bun:test";
4
4
 
5
+ import { ControlledClock } from "./controlled-clock-test-support.js";
6
+
5
7
  import {
6
8
  createWorkspaceEditTestHarness,
7
9
  diagnostic,
@@ -17,6 +19,7 @@ afterEach(async () => {
17
19
 
18
20
  describe("LspClient diagnostics freshness", () => {
19
21
  it("#given a versionless publish that arrives after the current change #when no newer eligible publish arrives before quiescence #then diagnostics wait for that quiescence window and return the versionless payload", async () => {
22
+ const clock = new ControlledClock();
20
23
  const context = await harness.makeClient(
21
24
  {
22
25
  publishDiagnostics: [
@@ -27,7 +30,7 @@ describe("LspClient diagnostics freshness", () => {
27
30
  },
28
31
  ],
29
32
  },
30
- { diagnosticsFreshnessTimeoutMs: 80, versionlessPublishQuiescenceMs: 20 },
33
+ { diagnosticsFreshnessTimeoutMs: 80, versionlessPublishQuiescenceMs: 20, timerProvider: clock },
31
34
  );
32
35
  await context.client.openFile(context.source);
33
36
  const versionlessDelivery = waitForEventCount(
@@ -35,42 +38,59 @@ describe("LspClient diagnostics freshness", () => {
35
38
  (event) => event.type === "clientResponse" && event.method === "workspace/configuration",
36
39
  1,
37
40
  );
38
- const startedAt = Date.now();
39
41
  writeFileSync(context.source, "const after = 1;\n", "utf-8");
40
42
  await context.client.openFile(context.source);
41
43
  expect(await versionlessDelivery).toHaveLength(1);
42
44
 
43
- const result = await context.client.diagnostics(context.source);
44
- const elapsedMs = Date.now() - startedAt;
45
+ const pending = context.client.diagnostics(context.source);
46
+ await clock.waitForTimer(20);
47
+ expect(clock.scheduledDelays.at(-1)).toBe(20);
48
+ clock.advanceBy(20);
49
+ const result = await pending;
45
50
 
46
51
  expect(result.items).toEqual([diagnostic("post-generation-versionless")]);
47
- expect(elapsedMs).toBeGreaterThanOrEqual(15);
48
52
  });
49
53
 
50
54
  it("#given only a pre-generation versionless publish #when a newer local version asks for diagnostics #then the stale versionless publish is ignored and the request does not resolve clean", async () => {
55
+ const clock = new ControlledClock();
51
56
  const context = await harness.makeClient(
52
57
  {
53
58
  publishDiagnostics: [
54
59
  {
55
60
  trigger: "didOpen",
56
61
  diagnostics: [diagnostic("pre-generation-versionless")],
62
+ awaitClientDelivery: true,
57
63
  },
58
64
  ],
59
65
  },
60
- { diagnosticsFreshnessTimeoutMs: 300, versionlessPublishQuiescenceMs: 5 },
66
+ { diagnosticsFreshnessTimeoutMs: 300, versionlessPublishQuiescenceMs: 5, timerProvider: clock },
61
67
  );
62
68
  await context.client.openFile(context.source);
63
- expect((await context.client.diagnostics(context.source)).items).toEqual([diagnostic("pre-generation-versionless")]);
69
+ await waitForEventCount(
70
+ context.events,
71
+ (event) => event.type === "clientResponse" && event.method === "workspace/configuration",
72
+ 1,
73
+ );
74
+ const initial = context.client.diagnostics(context.source);
75
+ await clock.waitForTimer(5);
76
+ expect(clock.scheduledDelays.at(-1)).toBe(5);
77
+ clock.advanceBy(5);
78
+ expect((await initial).items).toEqual([diagnostic("pre-generation-versionless")]);
64
79
  writeFileSync(context.source, "const after = 1;\n", "utf-8");
65
80
  await context.client.openFile(context.source);
66
81
 
67
- const result = await context.client.diagnostics(context.source);
82
+ const pending = context.client.diagnostics(context.source);
83
+ await clock.waitForTimer(300);
84
+ expect(clock.scheduledDelays.at(-1)).toBe(300);
85
+ clock.advanceBy(300);
86
+ const result = await pending;
68
87
 
69
88
  expect(result.items).toEqual([]);
70
89
  expect(result.transientError?.kind).toBe("freshness_timeout");
71
90
  });
72
91
 
73
92
  it("#given stale and future publish versions #when diagnostics target the current version #then neither stale nor future diagnostics satisfy the request", async () => {
93
+ const staleClock = new ControlledClock();
74
94
  const stale = await harness.makeClient(
75
95
  {
76
96
  publishDiagnostics: [
@@ -82,7 +102,7 @@ describe("LspClient diagnostics freshness", () => {
82
102
  },
83
103
  ],
84
104
  },
85
- { diagnosticsFreshnessTimeoutMs: 100, versionlessPublishQuiescenceMs: 5 },
105
+ { diagnosticsFreshnessTimeoutMs: 100, versionlessPublishQuiescenceMs: 5, timerProvider: staleClock },
86
106
  );
87
107
  await stale.client.openFile(stale.source);
88
108
  const staleDelivery = waitForEventCount(
@@ -94,13 +114,17 @@ describe("LspClient diagnostics freshness", () => {
94
114
  await stale.client.openFile(stale.source);
95
115
  expect(await staleDelivery).toHaveLength(1);
96
116
 
97
- const staleResult = await stale.client.diagnostics(stale.source);
117
+ const stalePending = stale.client.diagnostics(stale.source);
118
+ await staleClock.waitForTimer(100);
119
+ staleClock.advanceBy(100);
120
+ const staleResult = await stalePending;
98
121
 
99
122
  expect(staleResult.items).toEqual([]);
100
123
  expect(staleResult.transientError?.kind).toBe("freshness_timeout");
101
124
 
102
125
  await harness.cleanup();
103
126
 
127
+ const futureClock = new ControlledClock();
104
128
  const future = await harness.makeClient(
105
129
  {
106
130
  publishDiagnostics: [
@@ -112,7 +136,7 @@ describe("LspClient diagnostics freshness", () => {
112
136
  },
113
137
  ],
114
138
  },
115
- { diagnosticsFreshnessTimeoutMs: 100, versionlessPublishQuiescenceMs: 5 },
139
+ { diagnosticsFreshnessTimeoutMs: 100, versionlessPublishQuiescenceMs: 5, timerProvider: futureClock },
116
140
  );
117
141
  await future.client.openFile(future.source);
118
142
  const futureDelivery = waitForEventCount(
@@ -124,7 +148,10 @@ describe("LspClient diagnostics freshness", () => {
124
148
  await future.client.openFile(future.source);
125
149
  expect(await futureDelivery).toHaveLength(1);
126
150
 
127
- const futureResult = await future.client.diagnostics(future.source);
151
+ const futurePending = future.client.diagnostics(future.source);
152
+ await futureClock.waitForTimer(100);
153
+ futureClock.advanceBy(100);
154
+ const futureResult = await futurePending;
128
155
 
129
156
  expect(futureResult.items).toEqual([]);
130
157
  expect(futureResult.transientError?.kind).toBe("freshness_timeout");
@@ -136,7 +163,7 @@ describe("LspClient diagnostics freshness", () => {
136
163
  capabilities: { diagnosticProvider: { interFileDependencies: false, workspaceDiagnostics: false } },
137
164
  diagnosticResponses: [
138
165
  {
139
- delayMs: 200,
166
+ releaseOnDidChange: true,
140
167
  report: { kind: "full", resultId: "v1", items: [diagnostic("pull-stale")] },
141
168
  },
142
169
  {
@@ -248,19 +275,20 @@ describe("LspClient diagnostics freshness", () => {
248
275
  });
249
276
 
250
277
  it("#given a server without pull support that never publishes diagnostics #when diagnostics run on a clean file #then the request resolves clean after the freshness window instead of reporting a timeout", async () => {
278
+ const clock = new ControlledClock();
251
279
  const context = await harness.makeClient(
252
280
  {},
253
- { diagnosticsFreshnessTimeoutMs: 60, versionlessPublishQuiescenceMs: 5 },
281
+ { diagnosticsFreshnessTimeoutMs: 60, versionlessPublishQuiescenceMs: 5, timerProvider: clock },
254
282
  );
255
283
 
256
- const startedAt = Date.now();
257
- const result = await context.client.diagnostics(context.source);
258
- const elapsedMs = Date.now() - startedAt;
284
+ const pending = context.client.diagnostics(context.source);
285
+ await clock.waitForTimer(60);
286
+ expect(clock.scheduledDelays.at(-1)).toBe(60);
287
+ clock.advanceBy(60);
288
+ const result = await pending;
259
289
 
260
290
  expect(result.transientError).toBeUndefined();
261
291
  expect(result.items).toEqual([]);
262
- // The full freshness window is still honored so a slow publisher can win.
263
- expect(elapsedMs).toBeGreaterThanOrEqual(45);
264
292
  });
265
293
 
266
294
  it("#given a pull-supported server that cached diagnostics for an older document version #when the file changes and a later pull is rejected as unsupported without any publish #then the fallback resolves empty instead of returning the stale cached diagnostics", async () => {
@@ -0,0 +1,64 @@
1
+ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+
5
+ import { afterEach, describe, expect, it } from "bun:test";
6
+
7
+ import { ControlledClock } from "./controlled-clock-test-support.js";
8
+ import { LspClient } from "./client.js";
9
+ import { LspRequestTimeoutError } from "./errors.js";
10
+ import type { ResolvedServer } from "./types.js";
11
+
12
+ const fakeServer: ResolvedServer = {
13
+ id: "pull-timeout-fake",
14
+ command: ["pull-timeout-fake"],
15
+ extensions: [".ts"],
16
+ priority: 0,
17
+ };
18
+
19
+ class HangingPullClient extends LspClient {
20
+ readonly grantedPullTimeouts: number[] = [];
21
+
22
+ constructor(root: string, private readonly clock: ControlledClock) {
23
+ super(root, fakeServer, { diagnosticsFreshnessTimeoutMs: 50, versionlessPublishQuiescenceMs: 5, timerProvider: clock });
24
+ this.setDiagnosticPullSupported(true);
25
+ }
26
+
27
+ protected override async sendNotification(): Promise<void> {}
28
+
29
+ protected override async sendRequest<T>(
30
+ method: string,
31
+ ...args: [] | [unknown] | [unknown, { timeoutMs?: number; signal?: AbortSignal }]
32
+ ): Promise<T> {
33
+ if (method !== "textDocument/diagnostic") {
34
+ throw new Error(`unexpected request in hanging-pull fixture: ${method}`);
35
+ }
36
+ const timeoutMs = args[1]?.timeoutMs ?? 0;
37
+ this.grantedPullTimeouts.push(timeoutMs);
38
+ this.clock.advanceBy(timeoutMs);
39
+ throw new LspRequestTimeoutError(method);
40
+ }
41
+ }
42
+
43
+ describe("LspClient diagnostics pull timeout conversion", () => {
44
+ let root: string | null = null;
45
+
46
+ afterEach(() => {
47
+ if (root !== null) rmSync(root, { recursive: true, force: true });
48
+ root = null;
49
+ });
50
+
51
+ it("#given a pull that exhausts the freshness window #when diagnostics settle #then the timeout converts to freshness_timeout instead of rejecting", async () => {
52
+ root = mkdtempSync(join(tmpdir(), "lsp-pull-timeout-"));
53
+ const source = join(root, "sample.ts");
54
+ writeFileSync(source, "const value = 1;\n", "utf-8");
55
+ const clock = new ControlledClock();
56
+ const client = new HangingPullClient(root, clock);
57
+
58
+ const result = await client.diagnostics(source);
59
+
60
+ expect(client.grantedPullTimeouts).toEqual([50]);
61
+ expect(result.items).toEqual([]);
62
+ expect(result.transientError?.kind).toBe("freshness_timeout");
63
+ });
64
+ });