oh-my-opencode 4.18.1 → 4.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/.agents/skills/codex-qa/scripts/lsp-e2e.sh +39 -16
  2. package/.agents/skills/opencode-qa/scripts/lsp-e2e.sh +111 -28
  3. package/README.ja.md +2 -2
  4. package/README.ko.md +2 -2
  5. package/README.md +4 -4
  6. package/README.ru.md +2 -2
  7. package/README.zh-cn.md +2 -2
  8. package/bin/AGENTS.md +33 -0
  9. package/dist/agents/atlas/agent.d.ts +6 -5
  10. package/dist/agents/sisyphus/index.d.ts +5 -0
  11. package/dist/agents/sisyphus/kimi-k3.d.ts +19 -0
  12. package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
  13. package/dist/agents/sisyphus-junior/agent.d.ts +8 -4
  14. package/dist/agents/sisyphus-junior/index.d.ts +2 -0
  15. package/dist/agents/sisyphus-junior/kimi-k3.d.ts +12 -0
  16. package/dist/agents/types.d.ts +2 -2
  17. package/dist/cli/index.js +690 -139
  18. package/dist/cli-node/index.js +690 -139
  19. package/dist/config/index.d.ts +1 -1
  20. package/dist/config/schema/browser-automation.d.ts +1 -0
  21. package/dist/config/schema/commands.d.ts +1 -3
  22. package/dist/config/schema/default-mode.d.ts +1 -1
  23. package/dist/config/schema/goal.d.ts +7 -0
  24. package/dist/config/schema/hooks.d.ts +1 -1
  25. package/dist/config/schema/oh-my-opencode-config.d.ts +6 -10
  26. package/dist/config/schema/ralph-loop.d.ts +1 -1
  27. package/dist/config/schema.d.ts +1 -1
  28. package/dist/create-hooks.d.ts +1 -1
  29. package/dist/features/builtin-commands/templates/goal.d.ts +1 -0
  30. package/dist/features/builtin-commands/templates/stop-continuation.d.ts +1 -1
  31. package/dist/features/builtin-commands/types.d.ts +1 -1
  32. package/dist/hooks/anthropic-context-window-limit-recovery/empty-content-recovery-sdk.d.ts +6 -0
  33. package/dist/hooks/auto-slash-command/executor.d.ts +1 -0
  34. package/dist/hooks/category-skill-reminder/hook.d.ts +9 -1
  35. package/dist/hooks/comment-checker/hook.d.ts +8 -1
  36. package/dist/hooks/goal/command-arguments.d.ts +13 -0
  37. package/dist/hooks/goal/controller.d.ts +26 -0
  38. package/dist/hooks/goal/index.d.ts +23 -0
  39. package/dist/hooks/goal/prompt.d.ts +3 -0
  40. package/dist/hooks/goal/store.d.ts +8 -0
  41. package/dist/hooks/goal/tools.d.ts +10 -0
  42. package/dist/hooks/goal/types.d.ts +93 -0
  43. package/dist/hooks/goal/validation.d.ts +4 -0
  44. package/dist/hooks/index.d.ts +1 -0
  45. package/dist/hooks/keyword-detector/hook.d.ts +1 -2
  46. package/dist/hooks/ralph-loop/types.d.ts +1 -1
  47. package/dist/hooks/todo-continuation-enforcer/types.d.ts +3 -0
  48. package/dist/index.js +3706 -4329
  49. package/dist/oh-my-opencode.schema.json +23 -19
  50. package/dist/plugin/chat-message/loop-commands.d.ts +1 -1
  51. package/dist/plugin/chat-message/types.d.ts +23 -10
  52. package/dist/plugin/hooks/create-core-hooks.d.ts +1 -1
  53. package/dist/plugin/hooks/create-session-hooks.d.ts +3 -2
  54. package/dist/plugin/hooks/create-transform-hooks.d.ts +0 -2
  55. package/dist/plugin/messages-transform.d.ts +1 -0
  56. package/dist/plugin/stop-continuation.d.ts +2 -2
  57. package/dist/plugin-handlers/prometheus-agent-config-builder.d.ts +2 -0
  58. package/dist/shared/system-directive.d.ts +0 -1
  59. package/dist/skills/ulw-plan/SKILL.md +11 -7
  60. package/dist/skills/ulw-plan/references/full-workflow.md +117 -6
  61. package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  62. package/dist/skills/ulw-research/SKILL.md +3 -3
  63. package/dist/tools/delegate-task/types.d.ts +0 -1
  64. package/dist/tui.js +115 -28
  65. package/package.json +14 -14
  66. package/packages/git-bash-mcp/dist/cli.js +81 -19
  67. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +4 -4
  68. package/packages/lsp-core/src/lsp/directory-diagnostics.test.ts +118 -1
  69. package/packages/lsp-core/src/lsp/directory-diagnostics.ts +1 -1
  70. package/packages/lsp-daemon/dist/cli.js +262 -63
  71. package/packages/lsp-daemon/dist/client.js +194 -50
  72. package/packages/lsp-daemon/dist/daemon-client.d.ts +2 -2
  73. package/packages/lsp-daemon/dist/daemon-client.js +26 -2
  74. package/packages/lsp-daemon/dist/ensure-daemon.d.ts +5 -4
  75. package/packages/lsp-daemon/dist/ensure-daemon.js +79 -18
  76. package/packages/lsp-daemon/dist/index.js +262 -63
  77. package/packages/lsp-daemon/dist/proxy.d.ts +2 -0
  78. package/packages/lsp-daemon/dist/proxy.js +79 -23
  79. package/packages/lsp-tools-mcp/dist/cli.js +82 -20
  80. package/packages/lsp-tools-mcp/dist/mcp.js +82 -20
  81. package/packages/lsp-tools-mcp/dist/tools.js +1 -1
  82. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  83. package/packages/omo-codex/plugin/.mcp.json +2 -1
  84. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +352 -17
  85. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  86. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  87. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +7 -6
  88. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +195 -56
  89. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +100 -28
  90. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  91. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +21 -9
  92. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +1 -1
  93. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +35 -0
  94. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +69 -0
  95. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +57 -1
  96. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  97. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  98. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  99. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  100. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  101. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  102. package/packages/omo-codex/plugin/components/lsp/.mcp.json +2 -1
  103. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +1 -0
  104. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
  105. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +113 -31
  106. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  107. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  108. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +1 -0
  109. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.5.md +1 -1
  110. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.6.md +5 -3
  111. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  112. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  113. package/packages/omo-codex/plugin/components/start-work-continuation/AGENTS.md +8 -0
  114. package/packages/omo-codex/plugin/components/start-work-continuation/README.md +2 -2
  115. package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +3 -3
  116. package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +148 -61
  117. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  118. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  119. package/packages/omo-codex/plugin/components/start-work-continuation/src/boulder-reader.ts +4 -72
  120. package/packages/omo-codex/plugin/components/start-work-continuation/src/codex-hook.ts +1 -1
  121. package/packages/omo-codex/plugin/components/start-work-continuation/src/plan-checklist.ts +171 -0
  122. package/packages/omo-codex/plugin/components/start-work-continuation/test/boulder-reader.test.ts +213 -24
  123. package/packages/omo-codex/plugin/components/start-work-continuation/test/cli.test.ts +4 -3
  124. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +25 -4
  125. package/packages/omo-codex/plugin/components/start-work-continuation/test/fixtures/plan-scaffold.md +15 -0
  126. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  127. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  128. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  129. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  130. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -10
  131. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +3 -3
  132. package/packages/omo-codex/plugin/components/ultrawork/directive.md +50 -33
  133. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  134. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  135. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +50 -33
  136. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +11 -7
  137. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +117 -6
  138. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  139. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +50 -33
  140. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +3 -3
  141. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +5 -6
  142. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  143. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  144. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +1 -1
  145. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +5 -6
  146. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +2 -2
  147. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  148. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  149. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  150. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  151. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  152. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  153. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  154. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  155. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  156. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  157. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  158. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  159. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  160. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  161. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  162. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  163. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  164. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  165. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  166. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  167. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  168. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  169. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  170. package/packages/omo-codex/plugin/package-lock.json +13 -13
  171. package/packages/omo-codex/plugin/package.json +1 -1
  172. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +32 -28
  173. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +17 -45
  174. package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +455 -0
  175. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +13 -20
  176. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +7 -0
  177. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +3 -2
  178. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +50 -33
  179. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +1 -1
  180. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +11 -7
  181. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +117 -6
  182. package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  183. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +2 -2
  184. package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +2 -2
  185. package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -0
  186. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +6 -6
  187. package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +3 -3
  188. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +62 -0
  189. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +271 -14
  190. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +7 -0
  191. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +38 -22
  192. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +0 -5
  193. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +293 -0
  194. package/packages/omo-codex/scripts/install-config.test.mjs +10 -10
  195. package/packages/omo-codex/scripts/install-dist/install-local.mjs +353 -18
  196. package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +39 -2
  197. package/packages/shared-skills/skills/ulw-plan/SKILL.md +11 -7
  198. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +117 -6
  199. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  200. package/packages/shared-skills/skills/ulw-research/SKILL.md +3 -3
  201. package/dist/features/builtin-commands/templates/ralph-loop.d.ts +0 -3
  202. package/dist/skills/ultraresearch/SKILL.md +0 -10
  203. package/packages/shared-skills/skills/lcx-contribute-bug-fix/SKILL.md +0 -273
  204. package/packages/shared-skills/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -12
  205. package/packages/shared-skills/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -107
  206. package/packages/shared-skills/skills/lcx-doctor/SKILL.md +0 -128
  207. package/packages/shared-skills/skills/lcx-doctor/agents/openai.yaml +0 -11
  208. package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +0 -268
  209. package/packages/shared-skills/skills/lcx-report-bug/agents/openai.yaml +0 -11
  210. package/packages/shared-skills/skills/ultraresearch/SKILL.md +0 -10
  211. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/SKILL.md +0 -0
  212. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -0
  213. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -0
  214. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-doctor/SKILL.md +0 -0
  215. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-doctor/agents/openai.yaml +0 -0
  216. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-report-bug/SKILL.md +0 -0
  217. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-report-bug/agents/openai.yaml +0 -0
@@ -3021,6 +3021,9 @@ function errorResponse(id, code, message, data) {
3021
3021
  function jsonRpcId(value) {
3022
3022
  return typeof value === "string" || typeof value === "number" || value === null ? value : null;
3023
3023
  }
3024
+ function messageFromError(error) {
3025
+ return error instanceof Error ? error.message : String(error);
3026
+ }
3024
3027
  // ../mcp-stdio-core/src/transport.ts
3025
3028
  var HEADER_SEPARATOR2 = Buffer.from(`\r
3026
3029
  \r
@@ -3043,16 +3046,45 @@ async function* readStdioJsonRpcMessages(input) {
3043
3046
  yield parseJsonPayload(trailing, "line");
3044
3047
  }
3045
3048
  }
3046
- function writeStdioJsonRpcResponse(output, response, responseMode) {
3049
+ async function writeStdioJsonRpcResponse(output, response, responseMode) {
3047
3050
  const body = JSON.stringify(response);
3048
- if (responseMode === "framed") {
3049
- output.write(`Content-Length: ${Buffer.byteLength(body, "utf8")}\r
3051
+ const payload = responseMode === "framed" ? `Content-Length: ${Buffer.byteLength(body, "utf8")}\r
3050
3052
  \r
3051
- ${body}`);
3052
- return;
3053
- }
3054
- output.write(`${body}
3055
- `);
3053
+ ${body}` : `${body}
3054
+ `;
3055
+ await writeChunk(output, payload);
3056
+ }
3057
+ function writeChunk(output, chunk) {
3058
+ return new Promise((resolve6, reject) => {
3059
+ let settled = false;
3060
+ const onError = (error) => {
3061
+ if (settled)
3062
+ return;
3063
+ settled = true;
3064
+ reject(error);
3065
+ };
3066
+ output.once("error", onError);
3067
+ try {
3068
+ output.write(chunk, (error) => {
3069
+ if (settled)
3070
+ return;
3071
+ settled = true;
3072
+ if (error) {
3073
+ queueMicrotask(() => output.removeListener("error", onError));
3074
+ reject(error);
3075
+ return;
3076
+ }
3077
+ output.removeListener("error", onError);
3078
+ resolve6();
3079
+ });
3080
+ } catch (error) {
3081
+ output.removeListener("error", onError);
3082
+ if (settled)
3083
+ return;
3084
+ settled = true;
3085
+ reject(error);
3086
+ }
3087
+ });
3056
3088
  }
3057
3089
  function readNextMessage(buffer) {
3058
3090
  if (buffer.length === 0)
@@ -3148,39 +3180,69 @@ async function runJsonRpcStdioServer(config) {
3148
3180
  break;
3149
3181
  idleTimer.arm();
3150
3182
  if (message.kind === "parse_error") {
3151
- handleParseError(message, config, log);
3183
+ if (!await handleParseError(message, config, log))
3184
+ break;
3152
3185
  continue;
3153
3186
  }
3154
- await handleRequest(message, config, log);
3187
+ if (!await handleRequest(message, config, log))
3188
+ break;
3155
3189
  }
3156
3190
  } finally {
3157
3191
  idleTimer.clear();
3158
3192
  log("stdio_stopped");
3159
3193
  }
3160
3194
  }
3161
- function handleParseError(message, config, log) {
3195
+ async function handleParseError(message, config, log) {
3162
3196
  log("parse_error", { message: message.message });
3163
3197
  const response = config.parseErrorResponse?.(message.message) ?? errorResponse(null, -32700, "Parse error", message.message);
3164
- if (response !== undefined) {
3165
- writeStdioJsonRpcResponse(config.output, response, message.responseMode);
3166
- }
3198
+ if (response === undefined)
3199
+ return true;
3200
+ return writeResponse(response, {
3201
+ output: config.output,
3202
+ responseMode: message.responseMode,
3203
+ log
3204
+ });
3167
3205
  }
3168
3206
  async function handleRequest(message, config, log) {
3169
3207
  const parsed = message.payload;
3170
3208
  const id = isPlainRecord(parsed) ? jsonRpcId(parsed["id"]) : null;
3171
3209
  const method = isPlainRecord(parsed) && typeof parsed["method"] === "string" ? parsed["method"] : null;
3172
3210
  log("request", { id: id === null ? null : String(id), method });
3211
+ let response;
3173
3212
  try {
3174
- const response = await config.handler(parsed, config.handlerOptions);
3175
- if (response === undefined)
3176
- return;
3177
- writeStdioJsonRpcResponse(config.output, response, message.responseMode);
3178
- log("response", { id: String(response.id), method, is_error: response.error !== undefined });
3213
+ response = await config.handler(parsed, config.handlerOptions);
3179
3214
  } catch (error) {
3180
3215
  if (config.onHandlerError === undefined)
3181
3216
  throw error;
3182
3217
  config.onHandlerError(error);
3218
+ return true;
3183
3219
  }
3220
+ if (response === undefined)
3221
+ return true;
3222
+ if (!await writeResponse(response, {
3223
+ output: config.output,
3224
+ responseMode: message.responseMode,
3225
+ log
3226
+ }))
3227
+ return false;
3228
+ log("response", { id: String(response.id), method, is_error: response.error !== undefined });
3229
+ return true;
3230
+ }
3231
+ async function writeResponse(response, context) {
3232
+ try {
3233
+ await writeStdioJsonRpcResponse(context.output, response, context.responseMode);
3234
+ return true;
3235
+ } catch (error) {
3236
+ if (!isTerminalOutputError(error))
3237
+ throw error;
3238
+ context.log("output_error", { message: messageFromError(error) });
3239
+ return false;
3240
+ }
3241
+ }
3242
+ function isTerminalOutputError(error) {
3243
+ if (!(error instanceof Error) || !("code" in error))
3244
+ return false;
3245
+ return error.code === "EPIPE" || error.code === "ERR_STREAM_DESTROYED" || error.code === "ERR_STREAM_WRITE_AFTER_END";
3184
3246
  }
3185
3247
  function createIdleTimer(idleTimeoutMs, log, onIdleTimeout) {
3186
3248
  let timer = null;
@@ -4243,7 +4305,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4243
4305
  const fileErrors = [];
4244
4306
  const maxConcurrency = Math.max(1, options.maxConcurrency ?? DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY);
4245
4307
  options.signal?.throwIfAborted();
4246
- const client = await manager2.getClient(root, server2);
4308
+ const client = await manager2.getClient(root, server2, options.signal);
4247
4309
  try {
4248
4310
  let nextIndex = 0;
4249
4311
  const workers = Array.from({ length: Math.min(maxConcurrency, filesToProcess.length) }, async () => {
@@ -12,6 +12,9 @@ function errorResponse(id, code, message, data) {
12
12
  function jsonRpcId(value) {
13
13
  return typeof value === "string" || typeof value === "number" || value === null ? value : null;
14
14
  }
15
+ function messageFromError(error) {
16
+ return error instanceof Error ? error.message : String(error);
17
+ }
15
18
  // ../mcp-stdio-core/src/transport.ts
16
19
  var HEADER_SEPARATOR = Buffer.from(`\r
17
20
  \r
@@ -34,16 +37,45 @@ async function* readStdioJsonRpcMessages(input) {
34
37
  yield parseJsonPayload(trailing, "line");
35
38
  }
36
39
  }
37
- function writeStdioJsonRpcResponse(output, response, responseMode) {
40
+ async function writeStdioJsonRpcResponse(output, response, responseMode) {
38
41
  const body = JSON.stringify(response);
39
- if (responseMode === "framed") {
40
- output.write(`Content-Length: ${Buffer.byteLength(body, "utf8")}\r
42
+ const payload = responseMode === "framed" ? `Content-Length: ${Buffer.byteLength(body, "utf8")}\r
41
43
  \r
42
- ${body}`);
43
- return;
44
- }
45
- output.write(`${body}
46
- `);
44
+ ${body}` : `${body}
45
+ `;
46
+ await writeChunk(output, payload);
47
+ }
48
+ function writeChunk(output, chunk) {
49
+ return new Promise((resolve, reject) => {
50
+ let settled = false;
51
+ const onError = (error) => {
52
+ if (settled)
53
+ return;
54
+ settled = true;
55
+ reject(error);
56
+ };
57
+ output.once("error", onError);
58
+ try {
59
+ output.write(chunk, (error) => {
60
+ if (settled)
61
+ return;
62
+ settled = true;
63
+ if (error) {
64
+ queueMicrotask(() => output.removeListener("error", onError));
65
+ reject(error);
66
+ return;
67
+ }
68
+ output.removeListener("error", onError);
69
+ resolve();
70
+ });
71
+ } catch (error) {
72
+ output.removeListener("error", onError);
73
+ if (settled)
74
+ return;
75
+ settled = true;
76
+ reject(error);
77
+ }
78
+ });
47
79
  }
48
80
  function readNextMessage(buffer) {
49
81
  if (buffer.length === 0)
@@ -139,40 +171,70 @@ async function runJsonRpcStdioServer(config) {
139
171
  break;
140
172
  idleTimer.arm();
141
173
  if (message.kind === "parse_error") {
142
- handleParseError(message, config, log);
174
+ if (!await handleParseError(message, config, log))
175
+ break;
143
176
  continue;
144
177
  }
145
- await handleRequest(message, config, log);
178
+ if (!await handleRequest(message, config, log))
179
+ break;
146
180
  }
147
181
  } finally {
148
182
  idleTimer.clear();
149
183
  log("stdio_stopped");
150
184
  }
151
185
  }
152
- function handleParseError(message, config, log) {
186
+ async function handleParseError(message, config, log) {
153
187
  log("parse_error", { message: message.message });
154
188
  const response = config.parseErrorResponse?.(message.message) ?? errorResponse(null, -32700, "Parse error", message.message);
155
- if (response !== undefined) {
156
- writeStdioJsonRpcResponse(config.output, response, message.responseMode);
157
- }
189
+ if (response === undefined)
190
+ return true;
191
+ return writeResponse(response, {
192
+ output: config.output,
193
+ responseMode: message.responseMode,
194
+ log
195
+ });
158
196
  }
159
197
  async function handleRequest(message, config, log) {
160
198
  const parsed = message.payload;
161
199
  const id = isPlainRecord(parsed) ? jsonRpcId(parsed["id"]) : null;
162
200
  const method = isPlainRecord(parsed) && typeof parsed["method"] === "string" ? parsed["method"] : null;
163
201
  log("request", { id: id === null ? null : String(id), method });
202
+ let response;
164
203
  try {
165
- const response = await config.handler(parsed, config.handlerOptions);
166
- if (response === undefined)
167
- return;
168
- writeStdioJsonRpcResponse(config.output, response, message.responseMode);
169
- log("response", { id: String(response.id), method, is_error: response.error !== undefined });
204
+ response = await config.handler(parsed, config.handlerOptions);
170
205
  } catch (error) {
171
206
  if (config.onHandlerError === undefined)
172
207
  throw error;
173
208
  config.onHandlerError(error);
209
+ return true;
210
+ }
211
+ if (response === undefined)
212
+ return true;
213
+ if (!await writeResponse(response, {
214
+ output: config.output,
215
+ responseMode: message.responseMode,
216
+ log
217
+ }))
218
+ return false;
219
+ log("response", { id: String(response.id), method, is_error: response.error !== undefined });
220
+ return true;
221
+ }
222
+ async function writeResponse(response, context) {
223
+ try {
224
+ await writeStdioJsonRpcResponse(context.output, response, context.responseMode);
225
+ return true;
226
+ } catch (error) {
227
+ if (!isTerminalOutputError(error))
228
+ throw error;
229
+ context.log("output_error", { message: messageFromError(error) });
230
+ return false;
174
231
  }
175
232
  }
233
+ function isTerminalOutputError(error) {
234
+ if (!(error instanceof Error) || !("code" in error))
235
+ return false;
236
+ return error.code === "EPIPE" || error.code === "ERR_STREAM_DESTROYED" || error.code === "ERR_STREAM_WRITE_AFTER_END";
237
+ }
176
238
  function createIdleTimer(idleTimeoutMs, log, onIdleTimeout) {
177
239
  let timer = null;
178
240
  let isClosed = false;
@@ -4242,7 +4304,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4242
4304
  const fileErrors = [];
4243
4305
  const maxConcurrency = Math.max(1, options.maxConcurrency ?? DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY);
4244
4306
  options.signal?.throwIfAborted();
4245
- const client = await manager.getClient(root, server2);
4307
+ const client = await manager.getClient(root, server2, options.signal);
4246
4308
  try {
4247
4309
  let nextIndex = 0;
4248
4310
  const workers = Array.from({ length: Math.min(maxConcurrency, filesToProcess.length) }, async () => {
@@ -4042,7 +4042,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4042
4042
  const fileErrors = [];
4043
4043
  const maxConcurrency = Math.max(1, options.maxConcurrency ?? DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY);
4044
4044
  options.signal?.throwIfAborted();
4045
- const client = await manager.getClient(root, server);
4045
+ const client = await manager.getClient(root, server, options.signal);
4046
4046
  try {
4047
4047
  let nextIndex = 0;
4048
4048
  const workers = Array.from({ length: Math.min(maxConcurrency, filesToProcess.length) }, async () => {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omo",
3
- "version": "4.18.1",
3
+ "version": "4.19.0",
4
4
  "description": "One Codex plugin namespace for Yeongyu's local Codex components.",
5
5
  "author": {
6
6
  "name": "Yeongyu Kim",
@@ -20,7 +20,8 @@
20
20
  "lsp": {
21
21
  "command": "node",
22
22
  "args": ["../../lsp-daemon/dist/cli.js", "mcp"],
23
- "cwd": "."
23
+ "cwd": ".",
24
+ "startup_timeout_sec": 10
24
25
  }
25
26
  }
26
27
  }