Skip to content

fix(opencode): list file commands without blocking on MCP connections - #48630

Closed
luochen1990 wants to merge 1 commit into
anomalyco:devfrom
luochen1990:perf-async-command-prompts-20260912-1222
Closed

luochen1990 wants to merge 1 commit into
anomalyco:devfrom
luochen1990:perf-async-command-prompts-20260912-1222

Conversation

@luochen1990

@luochen1990 luochen1990 commented Sep 12, 2026 •

Copy link
Copy Markdown
Contributor

Issue for this PR

Closes #36288
Closes #48629

Type of change

  • Bug fix

What does this PR do?

/command currently waits for all MCP servers to connect before returning file-based commands (measured 5.6s with 9 servers, 0.65s with MCP disabled — see issue). This PR makes the initial listing immediate and merges MCP prompts asynchronously:

  • Command.init now loads defaults + config commands + skills synchronously; mcp.prompts() is forked into a background fiber (scoped to the cache entry) that merges prompts in-place once servers settle, preserving the existing mcp > config > skill precedence
  • new command.updated event (same shape/pattern as lsp.updated) is published when the merge lands; the TUI sync store re-fetches command.list on receipt, so prompts appear in the / menu as soon as they exist
  • command.ready() lets callers opt back into the old wait-for-prompts semantics; the ACP directory loader uses it (its snapshot is cached per-directory forever, so it must capture the merged state — behavior there is unchanged)
  • prompt execution path is unaffected: it reads state fresh at execution time

Known trade-off (stated in the issue): a one-shot API consumer that neither subscribes to events nor re-fetches will see prompts missing from its first response during the connection window. The web app's bootstrap fetch is currently one-shot too; I'm happy to wire command.updated into it as a follow-up for consistency.

How did you verify your code works?

  • new regression tests (packages/opencode/test/command/index.test.ts): a stdio MCP server fixture with a 1.5s handshake delay — command.list() returns file commands within a 1s budget without the prompt, the prompt appears after ready(), and command.updated is received via EventV2Bridge; a second test covers the no-MCP-servers case (ready() resolves without hanging). Verified that both fail on the old implementation (the first behaviorally, the second at the missing ready() API).
  • full packages/opencode suite: 3276 pass / 2 fail, both failures reproduce on the base commit (umask-dependent file mode assert + audio decode, unrelated)
  • typecheck + prettier + generated SDK check pass
  • manual smoke against a real server with a deliberately slow (5s) MCP server: /command returns in 0.52s at t≈2s with file commands only; after settle, prompt is listed (8ms)

Screenshots / recordings

N/A (no visual change; behavior is timing-only)

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

command.list now returns config/skill commands immediately; MCP prompts
merge into the state from a background fiber and publish command.updated
so clients re-fetch. ACP directory snapshots await Command.ready() to
keep their previous blocking capture semantics.
@github-actions

Copy link
Copy Markdown
Contributor

Hey! Your PR title perf(command): list file commands without blocking on MCP connections doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@luochen1990 luochen1990 changed the title perf(command): list file commands without blocking on MCP connections fix(opencode): list file commands without blocking on MCP connections Sep 12, 2026
@thdxr

thdxr commented Oct 10, 2026

Copy link
Copy Markdown
Member

This branch has been upgraded to V2. We're no longer taking PRs for V1. If you think this is still relevant, please port it over and open it for V2.

— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

@thdxr thdxr closed this Oct 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

2 participants