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
@@ -63,18 +63,30 @@ export async function runBridgedCodegraphProcess(
63
63
  resolveExit(signal === null ? 0 : 1);
64
64
  });
65
65
  });
66
- const bridgeDone = Promise.all([
67
- forwardClientToCodegraph(options.input, childInput, pendingResponses, (mode) => {
68
- defaultResponseMode = mode;
69
- }),
70
- forwardCodegraphToClient(childOutput, options.output, pendingResponses, () => defaultResponseMode),
71
- ]);
66
+ const clientForwardingDone = forwardClientToCodegraph(options.input, childInput, pendingResponses, (mode) => {
67
+ defaultResponseMode = mode;
68
+ });
69
+ const responseForwardingDone = forwardCodegraphToClient(
70
+ childOutput,
71
+ options.output,
72
+ pendingResponses,
73
+ () => defaultResponseMode,
74
+ );
75
+ const bridgeDone = Promise.all([clientForwardingDone, responseForwardingDone]);
76
+ const childAndResponsesDone = Promise.all([childExit, responseForwardingDone]).then(([exitCode]) => exitCode);
72
77
  const destroyChildPipes = (): void => {
73
78
  childInput.destroy();
74
79
  childOutput.destroy();
75
80
  };
76
81
  void childExit.then(destroyChildPipes, destroyChildPipes);
77
- return Promise.race([childExit, bridgeDone.then(() => childExit)]);
82
+ try {
83
+ return await Promise.race([childAndResponsesDone, bridgeDone.then(() => childExit)]);
84
+ } catch (error) {
85
+ destroyChildPipes();
86
+ if (child.exitCode === null && child.signalCode === null) child.kill("SIGKILL");
87
+ await childExit.catch(() => undefined);
88
+ throw error;
89
+ }
78
90
  }
79
91
 
80
92
  async function forwardClientToCodegraph(
@@ -110,14 +122,14 @@ async function forwardCodegraphToClient(
110
122
  ): Promise<void> {
111
123
  for await (const message of readStdioJsonRpcMessages(childOutput)) {
112
124
  if (message.kind === "parse_error") {
113
- writeStdioJsonRpcResponse(output, errorResponse(null, -32700, "Parse error", message.message), defaultResponseMode());
125
+ await writeStdioJsonRpcResponse(output, errorResponse(null, -32700, "Parse error", message.message), defaultResponseMode());
114
126
  continue;
115
127
  }
116
128
  const key = responseModeKey(message.payload);
117
129
  const pendingResponse = key === null ? undefined : pendingResponses.get(key);
118
130
  const responseMode = pendingResponse?.responseMode ?? defaultResponseMode();
119
131
  if (key !== null) pendingResponses.delete(key);
120
- writeStdioJsonRpcResponse(output, clarifyCodegraphResponse(message.payload, pendingResponse), responseMode);
132
+ await writeStdioJsonRpcResponse(output, clarifyCodegraphResponse(message.payload, pendingResponse), responseMode);
121
133
  }
122
134
  }
123
135
 
@@ -21,7 +21,7 @@ describe("CodeGraph SessionStart exclusion policy", () => {
21
21
  const stdout: string[] = [];
22
22
  const spawned: WorkerSpawnInvocation[] = [];
23
23
  const stateRoot = createAllowedWorkspace("codegraph-omo-state");
24
- const workspace = join(stateRoot, ".omo", "ultraresearch", "run", "clones", "repo");
24
+ const workspace = join(stateRoot, ".omo", "ulw-research", "run", "clones", "repo");
25
25
  mkdirSync(workspace, { recursive: true });
26
26
 
27
27
  try {
@@ -49,6 +49,41 @@ export function writeFakeContractCodegraph(filePath: string): void {
49
49
  chmodSync(filePath, 0o755);
50
50
  }
51
51
 
52
+ export function writeFakeHeldOpenCodegraph(filePath: string): void {
53
+ writeFileSync(
54
+ filePath,
55
+ [
56
+ "#!/usr/bin/env node",
57
+ "const fs = require('node:fs');",
58
+ "const readline = require('node:readline');",
59
+ "fs.writeFileSync(process.env.CODEGRAPH_FAKE_LOG, String(process.pid));",
60
+ "const rl = readline.createInterface({ input: process.stdin });",
61
+ "rl.once('line', (line) => {",
62
+ " const request = JSON.parse(line);",
63
+ " process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id: request.id, result: { ok: true } }) + '\\n');",
64
+ "});",
65
+ "setInterval(() => {}, 1000);",
66
+ ].join("\n"),
67
+ );
68
+ chmodSync(filePath, 0o755);
69
+ }
70
+
71
+ export function writeFakeExitingCodegraph(filePath: string): void {
72
+ writeFileSync(
73
+ filePath,
74
+ [
75
+ "#!/usr/bin/env node",
76
+ "const readline = require('node:readline');",
77
+ "const rl = readline.createInterface({ input: process.stdin });",
78
+ "rl.once('line', (line) => {",
79
+ " const request = JSON.parse(line);",
80
+ " process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id: request.id, result: { ok: true } }) + '\\n', () => process.exit(0));",
81
+ "});",
82
+ ].join("\n"),
83
+ );
84
+ chmodSync(filePath, 0o755);
85
+ }
86
+
52
87
  export function frameMcpRequest(request: {
53
88
  readonly id: number;
54
89
  readonly method: string;
@@ -0,0 +1,69 @@
1
+ import { describe, expect, it } from "bun:test";
2
+ import { mkdirSync, mkdtempSync, realpathSync, rmSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { PassThrough, Writable } from "node:stream";
5
+ import { fileURLToPath } from "node:url";
6
+
7
+ import { runCodegraphServe } from "../src/serve.ts";
8
+ import {
9
+ frameMcpRequest,
10
+ writeFakeExitingCodegraph,
11
+ } from "./mcp-bridge-fixtures.ts";
12
+
13
+ const componentRoot = realpathSync(
14
+ fileURLToPath(new URL("..", import.meta.url)),
15
+ );
16
+
17
+ describe("runCodegraphServe MCP bridge lifecycle", () => {
18
+ it("#given an exiting Codegraph child and delayed closed parent output #when the final response write fails #then the output error is preserved", async () => {
19
+ const tempRoot = mkdtempSync(
20
+ join(componentRoot, ".tmp-codegraph-exit-output-failure-"),
21
+ );
22
+ const projectRoot = join(tempRoot, "project");
23
+ const fakeCodegraph = join(tempRoot, "codegraph-exiting.cjs");
24
+ const input = new PassThrough();
25
+ const outputError = Object.assign(
26
+ new Error("parent output closed after child exit"),
27
+ { code: "EPIPE" },
28
+ );
29
+ const writeStarted = Promise.withResolvers<void>();
30
+ const output = new Writable({
31
+ write(_chunk, _encoding, callback) {
32
+ writeStarted.resolve();
33
+ setTimeout(() => callback(outputError), 150);
34
+ },
35
+ });
36
+
37
+ try {
38
+ mkdirSync(projectRoot, { recursive: true });
39
+ writeFakeExitingCodegraph(fakeCodegraph);
40
+ const run = runCodegraphServe({
41
+ cwd: tempRoot,
42
+ env: {
43
+ CODEGRAPH_ALLOW_UNSAFE_NODE: "1",
44
+ OMO_CODEGRAPH_BIN: fakeCodegraph,
45
+ OMO_CODEGRAPH_PROJECT_CWD: projectRoot,
46
+ PATH: process.env["PATH"],
47
+ },
48
+ nodeVersion: "22.14.0",
49
+ buildEnv: () => ({}),
50
+ resolve: () => ({
51
+ argsPrefix: [],
52
+ command: fakeCodegraph,
53
+ exists: true,
54
+ source: "env",
55
+ }),
56
+ stderr: { write: () => undefined },
57
+ stdin: input,
58
+ stdout: output,
59
+ });
60
+
61
+ input.end(frameMcpRequest({ id: 1, method: "tools/list", params: {} }));
62
+
63
+ await writeStarted.promise;
64
+ await expect(run).rejects.toBe(outputError);
65
+ } finally {
66
+ rmSync(tempRoot, { recursive: true, force: true });
67
+ }
68
+ });
69
+ });
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it } from "bun:test";
2
2
  import { mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync } from "node:fs";
3
3
  import { join } from "node:path";
4
- import { PassThrough } from "node:stream";
4
+ import { PassThrough, Writable } from "node:stream";
5
5
  import { fileURLToPath } from "node:url";
6
6
 
7
7
  import { runCodegraphServe } from "../src/serve.ts";
@@ -14,6 +14,7 @@ import {
14
14
  recordValue,
15
15
  stringProperty,
16
16
  writeFakeContractCodegraph,
17
+ writeFakeHeldOpenCodegraph,
17
18
  writeFakeNewlineCodegraph,
18
19
  } from "./mcp-bridge-fixtures.ts";
19
20
 
@@ -190,4 +191,59 @@ describe("runCodegraphServe MCP protocol bridge", () => {
190
191
  rmSync(tempRoot, { recursive: true, force: true });
191
192
  }
192
193
  });
194
+
195
+ it("#given a held-open Codegraph child and closed parent output #when response forwarding fails #then the child is terminated before rejection", async () => {
196
+ const tempRoot = mkdtempSync(join(componentRoot, ".tmp-codegraph-output-failure-"));
197
+ const projectRoot = join(tempRoot, "project");
198
+ const fakeCodegraph = join(tempRoot, "codegraph-held-open.cjs");
199
+ const childPidFile = join(tempRoot, "child.pid");
200
+ const input = new PassThrough();
201
+ const outputError = Object.assign(new Error("parent output closed"), { code: "EPIPE" });
202
+ const output = new Writable({
203
+ write(_chunk, _encoding, callback) {
204
+ callback(outputError);
205
+ },
206
+ });
207
+ let childPid: number | undefined;
208
+
209
+ try {
210
+ mkdirSync(projectRoot, { recursive: true });
211
+ writeFakeHeldOpenCodegraph(fakeCodegraph);
212
+ const run = runCodegraphServe({
213
+ cwd: tempRoot,
214
+ env: {
215
+ CODEGRAPH_ALLOW_UNSAFE_NODE: "1",
216
+ CODEGRAPH_FAKE_LOG: childPidFile,
217
+ OMO_CODEGRAPH_BIN: fakeCodegraph,
218
+ OMO_CODEGRAPH_PROJECT_CWD: projectRoot,
219
+ PATH: process.env["PATH"],
220
+ },
221
+ nodeVersion: "22.14.0",
222
+ buildEnv: () => ({}),
223
+ resolve: () => ({ argsPrefix: [], command: fakeCodegraph, exists: true, source: "env" }),
224
+ stderr: { write: () => undefined },
225
+ stdin: input,
226
+ stdout: output,
227
+ });
228
+
229
+ input.end(frameMcpRequest({ id: 1, method: "tools/list", params: {} }));
230
+
231
+ await expect(run).rejects.toBe(outputError);
232
+ childPid = Number(readFileSync(childPidFile, "utf8"));
233
+ expect(isProcessAlive(childPid)).toBe(false);
234
+ } finally {
235
+ if (childPid !== undefined && isProcessAlive(childPid)) process.kill(childPid, "SIGKILL");
236
+ rmSync(tempRoot, { recursive: true, force: true });
237
+ }
238
+ });
193
239
  });
240
+
241
+ function isProcessAlive(pid: number): boolean {
242
+ try {
243
+ process.kill(pid, 0);
244
+ return true;
245
+ } catch (error) {
246
+ if (error instanceof Error && "code" in error && error.code === "ESRCH") return false;
247
+ throw error;
248
+ }
249
+ }
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
10
10
  "timeout": 30,
11
- "statusMessage": "(OmO 4.18.1) Checking Comments"
11
+ "statusMessage": "(OmO 4.19.0) Checking Comments"
12
12
  }
13
13
  ]
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-comment-checker",
3
- "version": "4.18.1",
3
+ "version": "4.19.0",
4
4
  "description": "Codex plugin that runs comment-checker after edit-like PostToolUse hooks.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook pre-tool-use",
10
10
  "timeout": 5,
11
- "statusMessage": "(OmO 4.18.1) Recommending Git Bash MCP"
11
+ "statusMessage": "(OmO 4.19.0) Recommending Git Bash MCP"
12
12
  }
13
13
  ]
14
14
  }
@@ -20,7 +20,7 @@
20
20
  "type": "command",
21
21
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
22
22
  "timeout": 5,
23
- "statusMessage": "(OmO 4.18.1) Resetting Git Bash MCP Reminder"
23
+ "statusMessage": "(OmO 4.19.0) Resetting Git Bash MCP Reminder"
24
24
  }
25
25
  ]
26
26
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sisyphuslabs/codex-git-bash-hook",
3
- "version": "4.18.1",
3
+ "version": "4.19.0",
4
4
  "description": "Codex hook component that reminds Windows sessions to prefer the OMO git_bash MCP.",
5
5
  "type": "module",
6
6
  "private": true,
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/components/lazycodex-executor-verify/dist/cli.js\" hook subagent-stop",
10
10
  "timeout": 10,
11
- "statusMessage": "(OmO 4.18.1) Verifying LazyCodex Executor Evidence"
11
+ "statusMessage": "(OmO 4.19.0) Verifying LazyCodex Executor Evidence"
12
12
  }
13
13
  ]
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-lazycodex-executor-verify",
3
- "version": "4.18.1",
3
+ "version": "4.19.0",
4
4
  "description": "Codex SubagentStop evidence verifier for LazyCodex executor completions.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -3,7 +3,8 @@
3
3
  "lsp": {
4
4
  "command": "node",
5
5
  "args": ["../../../../lsp-daemon/dist/cli.js", "mcp"],
6
- "cwd": "."
6
+ "cwd": ".",
7
+ "startup_timeout_sec": 10
7
8
  }
8
9
  }
9
10
  }
@@ -22,4 +22,5 @@ Conventions for humans and agents working on this repository.
22
22
  - LSP server processes are owned by `LspManager`.
23
23
  - Tool execution acquires clients through `withLspClient(...)` unless it only reports static status.
24
24
  - `lsp.rename` mutates files by applying workspace edits; keep it sequential at the MCP caller level.
25
+ - `.mcp.json` sets `lsp` MCP server `startup_timeout_sec: 10` to bound startup; preserve the bound on edits.
25
26
  - Do not add pi-coding-agent or omo source dependencies. This package is standalone.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "4.18.1",
4
- "inputDigest": "sha256:ce104d23ca60e4a61242e99e54232a9fc82078b6471381511abc3187f8489842",
3
+ "version": "4.19.0",
4
+ "inputDigest": "sha256:1c26ab90eb222f050b468e7088ee9e655d0db850605ab425e8636c089a910f79",
5
5
  "outputs": [
6
6
  {
7
7
  "path": "cli.d.ts",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  {
11
11
  "path": "cli.js",
12
- "sha256": "84e00d94acd6c757613daaf8dde1e9425861ab6aa16923daaebd207934bc8ca1"
12
+ "sha256": "e92c3fee5795bf44de9504b0e85c2be208c78a31e966ec9a7a807d621431c74a"
13
13
  },
14
14
  {
15
15
  "path": "codex-hook-cli.d.ts",
@@ -13,13 +13,13 @@ import { homedir as homedir3 } from "node:os";
13
13
  import { join as join11, resolve as resolve11 } from "node:path";
14
14
 
15
15
  // ../../../../lsp-daemon/dist/client.js
16
- import { connect as connect2 } from "node:net";
16
+ import { connect } from "node:net";
17
17
  import { AsyncLocalStorage } from "node:async_hooks";
18
18
  import { existsSync, realpathSync, statSync } from "node:fs";
19
19
  import { basename, delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
20
20
  import { spawn } from "node:child_process";
21
21
  import { closeSync as closeSync2, mkdirSync as mkdirSync2, openSync as openSync2 } from "node:fs";
22
- import { connect } from "node:net";
22
+ import { Socket } from "node:net";
23
23
  import { dirname as dirname3 } from "node:path";
24
24
  import { execPath } from "node:process";
25
25
  import {
@@ -426,42 +426,48 @@ class DaemonUnreachableError extends Error {
426
426
  async function ensureDaemonRunning(paths, deps = defaultEnsureDaemonDeps(), options = {}) {
427
427
  const readyTimeoutMs = options.readyTimeoutMs ?? DEFAULT_READY_TIMEOUT_MS;
428
428
  const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
429
- if (await deps.probe(paths))
429
+ const signal = options.signal;
430
+ throwIfAborted(signal);
431
+ if (await awaitWithSignal(deps.probe(paths, signal), signal))
430
432
  return;
433
+ throwIfAborted(signal);
431
434
  deps.spawnDaemon(paths);
432
- await waitUntilReachable(paths, deps, readyTimeoutMs, pollIntervalMs);
435
+ await waitUntilReachable(paths, deps, readyTimeoutMs, pollIntervalMs, signal);
433
436
  }
434
- async function waitUntilReachable(paths, deps, readyTimeoutMs, pollIntervalMs) {
437
+ async function waitUntilReachable(paths, deps, readyTimeoutMs, pollIntervalMs, signal) {
435
438
  const deadline = deps.now() + readyTimeoutMs;
436
439
  for (;; ) {
437
- if (await deps.probe(paths))
440
+ throwIfAborted(signal);
441
+ if (await awaitWithSignal(deps.probe(paths, signal), signal))
438
442
  return;
439
443
  if (deps.now() >= deadline)
440
444
  throw new DaemonUnreachableError(paths.socket);
441
- await deps.sleep(pollIntervalMs);
445
+ await awaitWithSignal(deps.sleep(pollIntervalMs, signal), signal);
442
446
  }
443
447
  }
444
- async function probeDaemon(paths, timeoutMs = PROBE_TIMEOUT_MS) {
448
+ async function probeDaemon(paths, timeoutMs = PROBE_TIMEOUT_MS, signal) {
445
449
  const token = readAuthToken(paths);
446
450
  if (!token)
447
451
  return false;
448
- return await pingDaemon(paths, token, timeoutMs) !== null;
452
+ return await pingDaemon(paths, token, timeoutMs, signal) !== null;
449
453
  }
450
- function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS) {
454
+ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS, signal) {
451
455
  return new Promise((resolve22) => {
452
- const socket = connect(paths.socket);
456
+ const socket = new Socket;
453
457
  let settled = false;
458
+ let timer;
454
459
  const finish = (value) => {
455
460
  if (settled)
456
461
  return;
457
462
  settled = true;
463
+ if (timer !== undefined)
464
+ clearTimeout(timer);
465
+ signal?.removeEventListener("abort", onAbort);
458
466
  socket.destroy();
459
467
  resolve22(value);
460
468
  };
461
- const timer = setTimeout(() => finish(null), timeoutMs);
462
- timer.unref?.();
469
+ const onAbort = () => finish(null);
463
470
  const decoder = createLineDecoder((message) => {
464
- clearTimeout(timer);
465
471
  finish(parsePingResponse(message));
466
472
  });
467
473
  socket.once("connect", () => {
@@ -469,9 +475,16 @@ function pingDaemon(paths, token, timeoutMs = PROBE_TIMEOUT_MS) {
469
475
  });
470
476
  socket.on("data", (chunk) => decoder.push(chunk));
471
477
  socket.once("error", () => {
472
- clearTimeout(timer);
473
478
  finish(null);
474
479
  });
480
+ timer = setTimeout(() => finish(null), timeoutMs);
481
+ timer.unref?.();
482
+ if (signal?.aborted) {
483
+ onAbort();
484
+ return;
485
+ }
486
+ signal?.addEventListener("abort", onAbort, { once: true });
487
+ socket.connect(paths.socket);
475
488
  });
476
489
  }
477
490
  function spawnDaemonProcess(paths) {
@@ -489,14 +502,62 @@ function spawnDaemonProcess(paths) {
489
502
  }
490
503
  function defaultEnsureDaemonDeps() {
491
504
  return {
492
- probe: (paths) => probeDaemon(paths),
505
+ probe: (paths, signal) => probeDaemon(paths, PROBE_TIMEOUT_MS, signal),
493
506
  spawnDaemon: (paths) => spawnDaemonProcess(paths),
494
- sleep: (ms) => new Promise((resolve22) => {
495
- setTimeout(resolve22, ms);
496
- }),
507
+ sleep: (ms, signal) => sleepWithSignal(ms, signal),
497
508
  now: () => Date.now()
498
509
  };
499
510
  }
511
+ function sleepWithSignal(ms, signal) {
512
+ return new Promise((resolve22) => {
513
+ let settled = false;
514
+ const finish = () => {
515
+ if (settled)
516
+ return;
517
+ settled = true;
518
+ clearTimeout(timer);
519
+ signal?.removeEventListener("abort", finish);
520
+ resolve22();
521
+ };
522
+ const timer = setTimeout(finish, ms);
523
+ if (signal?.aborted) {
524
+ finish();
525
+ return;
526
+ }
527
+ signal?.addEventListener("abort", finish, { once: true });
528
+ });
529
+ }
530
+ function awaitWithSignal(promise, signal) {
531
+ if (!signal)
532
+ return promise;
533
+ if (signal.aborted)
534
+ return Promise.reject(abortError(signal));
535
+ return new Promise((resolve22, reject) => {
536
+ let settled = false;
537
+ const finish = (run) => {
538
+ if (settled)
539
+ return;
540
+ settled = true;
541
+ signal.removeEventListener("abort", onAbort);
542
+ run();
543
+ };
544
+ const onAbort = () => finish(() => reject(abortError(signal)));
545
+ signal.addEventListener("abort", onAbort, { once: true });
546
+ promise.then((value) => finish(() => resolve22(value)), (error) => finish(() => reject(error)));
547
+ });
548
+ }
549
+ function throwIfAborted(signal) {
550
+ if (signal?.aborted)
551
+ throw abortError(signal);
552
+ }
553
+ function abortError(signal) {
554
+ const reason = signal.reason;
555
+ if (reason instanceof Error)
556
+ return reason;
557
+ const error = new Error(typeof reason === "string" ? reason : "daemon startup cancelled");
558
+ error.name = "AbortError";
559
+ return error;
560
+ }
500
561
  function parsePingResponse(message) {
501
562
  if (!message || typeof message !== "object" || Array.isArray(message))
502
563
  return null;
@@ -692,7 +753,7 @@ class JsonRpcConnection {
692
753
  settled = true;
693
754
  this.pendingRequests.delete(key);
694
755
  cleanup();
695
- const rejectCancelled = () => reject(abortError(options.signal));
756
+ const rejectCancelled = () => reject(abortError2(options.signal));
696
757
  if (!requestWritten) {
697
758
  cancelAfterWrite = true;
698
759
  rejectCancelled();
@@ -896,7 +957,7 @@ ${body}`;
896
957
  }
897
958
  }
898
959
  }
899
- function abortError(signal) {
960
+ function abortError2(signal) {
900
961
  const reason = signal?.reason;
901
962
  if (reason instanceof Error)
902
963
  return reason;
@@ -3118,11 +3179,11 @@ function waitForDiagnosticsActivity(wait, signal) {
3118
3179
  if (!signal)
3119
3180
  return wait;
3120
3181
  if (signal.aborted)
3121
- return Promise.reject(abortError2(signal));
3182
+ return Promise.reject(abortError3(signal));
3122
3183
  return new Promise((resolve72, reject) => {
3123
3184
  const onAbort = () => {
3124
3185
  signal.removeEventListener("abort", onAbort);
3125
- reject(abortError2(signal));
3186
+ reject(abortError3(signal));
3126
3187
  };
3127
3188
  signal.addEventListener("abort", onAbort, { once: true });
3128
3189
  wait.then(() => {
@@ -3157,7 +3218,7 @@ function preCommitAbortReason(source) {
3157
3218
  return reason;
3158
3219
  return new Error("LSP request cancelled before workspace edit commit");
3159
3220
  }
3160
- function abortError2(signal) {
3221
+ function abortError3(signal) {
3161
3222
  const reason = signal.reason;
3162
3223
  if (reason instanceof Error)
3163
3224
  return reason;
@@ -3188,7 +3249,7 @@ async function stopClientBestEffort(client) {
3188
3249
  reportBestEffortCleanupError("client stop", error);
3189
3250
  }
3190
3251
  }
3191
- function awaitWithSignal(promise, signal) {
3252
+ function awaitWithSignal2(promise, signal) {
3192
3253
  if (!signal)
3193
3254
  return promise;
3194
3255
  return new Promise((resolve72, reject) => {
@@ -3291,7 +3352,7 @@ class LspManager {
3291
3352
  if (managed.initPromise) {
3292
3353
  managed.pendingWaiters++;
3293
3354
  try {
3294
- await awaitWithSignal(managed.initPromise, signal);
3355
+ await awaitWithSignal2(managed.initPromise, signal);
3295
3356
  } catch (err) {
3296
3357
  managed.pendingWaiters--;
3297
3358
  await this.tryDeleteIfOrphaned(key, managed);
@@ -3329,7 +3390,7 @@ class LspManager {
3329
3390
  };
3330
3391
  this.clients.set(key, newManaged);
3331
3392
  try {
3332
- await awaitWithSignal(initPromise, signal);
3393
+ await awaitWithSignal2(initPromise, signal);
3333
3394
  } catch (err) {
3334
3395
  newManaged.pendingWaiters--;
3335
3396
  if (this.clients.get(key) === newManaged) {
@@ -4280,7 +4341,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4280
4341
  const fileErrors = [];
4281
4342
  const maxConcurrency = Math.max(1, options.maxConcurrency ?? DIRECTORY_DIAGNOSTICS_MAX_CONCURRENCY);
4282
4343
  options.signal?.throwIfAborted();
4283
- const client = await manager.getClient(root, server2);
4344
+ const client = await manager.getClient(root, server2, options.signal);
4284
4345
  try {
4285
4346
  let nextIndex = 0;
4286
4347
  const workers = Array.from({ length: Math.min(maxConcurrency, filesToProcess.length) }, async () => {
@@ -4960,14 +5021,14 @@ class DaemonRequestCancelledError extends DaemonRequestError {
4960
5021
  async function callToolViaDaemon(name, args, options) {
4961
5022
  const context = requireContext(options.context);
4962
5023
  const paths = options.paths ?? daemonPaths();
4963
- const ensure = options.ensure ?? ensureDaemonRunning;
5024
+ const ensure = options.ensure ?? ((ensurePaths, signal) => ensureDaemonRunning(ensurePaths, undefined, signal === undefined ? {} : { signal }));
4964
5025
  const timeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
4965
5026
  const requestArgs = withContext(args, context);
4966
5027
  let lastError;
4967
5028
  let authRefreshUsed = false;
4968
5029
  for (let attempt = 0;attempt < 3; attempt += 1) {
4969
5030
  try {
4970
- await ensure(paths);
5031
+ await ensureDaemonAvailable(paths, ensure, options.signal);
4971
5032
  const token = readAuthToken(paths);
4972
5033
  if (!token)
4973
5034
  throw new DaemonRequestError("daemon auth token missing", false);
@@ -4998,6 +5059,27 @@ function requireContext(context) {
4998
5059
  function withContext(args, context) {
4999
5060
  return { ...args, [CONTEXT_KEY]: context };
5000
5061
  }
5062
+ function ensureDaemonAvailable(paths, ensure, signal) {
5063
+ if (!signal)
5064
+ return ensure(paths);
5065
+ return new Promise((resolve9, reject) => {
5066
+ let settled = false;
5067
+ const finish = (run) => {
5068
+ if (settled)
5069
+ return;
5070
+ settled = true;
5071
+ signal.removeEventListener("abort", onAbort);
5072
+ run();
5073
+ };
5074
+ const onAbort = () => finish(() => reject(new DaemonRequestCancelledError(false)));
5075
+ if (signal.aborted) {
5076
+ onAbort();
5077
+ return;
5078
+ }
5079
+ signal.addEventListener("abort", onAbort, { once: true });
5080
+ Promise.resolve().then(() => ensure(paths, signal)).then(() => finish(() => resolve9()), (error) => finish(() => reject(signal.aborted ? new DaemonRequestCancelledError(false) : error)));
5081
+ });
5082
+ }
5001
5083
  function daemonUnreachableResult(paths, error) {
5002
5084
  const text2 = [
5003
5085
  `LSP daemon unreachable: ${errorText(error)}.`,
@@ -5011,7 +5093,7 @@ function daemonUnreachableResult(paths, error) {
5011
5093
  }
5012
5094
  function sendToolCall(paths, token, name, args, options) {
5013
5095
  return new Promise((resolve9, reject) => {
5014
- const socket = connect2(paths.socket);
5096
+ const socket = connect(paths.socket);
5015
5097
  const requestId = allocateProxyRequestId();
5016
5098
  let settled = false;
5017
5099
  let requestWritten = false;
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
10
10
  "timeout": 60,
11
- "statusMessage": "(OmO 4.18.1) Checking LSP Diagnostics"
11
+ "statusMessage": "(OmO 4.19.0) Checking LSP Diagnostics"
12
12
  }
13
13
  ]
14
14
  }
@@ -21,7 +21,7 @@
21
21
  "type": "command",
22
22
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
23
23
  "timeout": 5,
24
- "statusMessage": "(OmO 4.18.1) Resetting LSP Diagnostics Cache"
24
+ "statusMessage": "(OmO 4.19.0) Resetting LSP Diagnostics Cache"
25
25
  }
26
26
  ]
27
27
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-lsp",
3
- "version": "4.18.1",
3
+ "version": "4.19.0",
4
4
  "description": "Codex plugin that exposes Language Server Protocol tools and post-edit diagnostics.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",