Skip to content

feat(command): add noReply flag to skip LLM dispatch#28763

Open
Svtter wants to merge 3 commits into
anomalyco:devfrom
Svtter:feat/noReply-command
Open

feat(command): add noReply flag to skip LLM dispatch#28763
Svtter wants to merge 3 commits into
anomalyco:devfrom
Svtter:feat/noReply-command

Conversation

@Svtter
Copy link
Copy Markdown

@Svtter Svtter commented May 22, 2026

Issue for this PR

Related to #28292, #5305, #26022. Builds on the schema approach from #27521.

Type of change

  • Bug fix
  • New feature
  • Refactor
  • Other

What does this PR do?

Adds a noReply boolean flag to the command schema. When true, the LLM round-trip is skipped entirely and hook-modified parts are written as a completed assistant message so they render immediately in the TUI.

Problem: Plugins like opencode-review register toggle commands (/review:auto on/off) that just flip a boolean. Currently this requires a full LLM agent round-trip — wasting tokens and adding latency for an instant operation. The command.execute.before hook can intercept the command but cannot skip the LLM call.

Changes:

File Change
config/command.ts Add noReply to command config schema
command/index.ts Add noReply to command registry schema + pass through
session/prompt.ts Pass noReply from command() to prompt(); when set, create assistant message with parts directly (no LLM)
test/session/prompt.test.ts New test: noReply command skips LLM and creates assistant message with parts

Differences from PR #27521: That PR added the noReply schema but when it short-circuited the LLM, the command's parts silently disappeared. This PR also creates a visible assistant message in the TUI so the user sees the result.

Usage — command config (.opencode/commands/test.md):

---
noReply: true
description: instant command
---
Result: $ARGUMENTS

Or via plugin config hook:

openCodeConfig.command["my-cmd"] = {
  template: "placeholder",
  noReply: true,
}

Combined with command.execute.before hook:

"command.execute.before": async (input, output) => {
  if (input.command !== "my-cmd") return
  output.parts = [{ type: "text", text: "Done!" }]
}

How did you verify your code works?

  • bun run typecheck passes (15/15 packages)
  • New unit test passes: noReply command skips LLM and creates assistant message with parts
  • 52/54 existing tests pass (2 pre-existing flaky cancel race tests)
  • Manual test: opencode run --command test -- "hello" exits instantly, no LLM call
  • Integration test with opencode-review plugin: /review:auto off skips LLM, toggles state via hook

Screenshots / recordings

N/A (session/prompt behavior change, no TUI layout change)

Checklist

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

🤖 Generated with Claude Code

Svtter and others added 2 commits May 22, 2026 12:11
…s directly

When a command is configured with `noReply: true`, the LLM round-trip is
skipped entirely. The hook-modified parts are written as a completed
assistant message so they render immediately in the TUI without any token
cost or latency.

This enables plugins like opencode-review to register instant toggle
commands (e.g. `/review:auto on/off`) that execute purely locally via the
`command.execute.before` hook.

Closes anomalyco#28292

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions github-actions Bot added the needs:compliance This means the issue will auto-close after 2 hours. label May 22, 2026
@github-actions
Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Related PR Found:

PR #27521: feat(command): add noReply flag to skip LLM dispatch for display-only commands
#27521

Why they're related:
PR #27521 is an earlier attempt that introduced the noReply schema approach, but PR #28763 (the current PR) builds upon and improves it by solving the missing piece: ensuring command parts appear as a visible assistant message in the TUI when noReply short-circuits the LLM (instead of silently disappearing). The current PR explicitly acknowledges this relationship in its "Differences from PR #27521" section.

@github-actions github-actions Bot removed the needs:compliance This means the issue will auto-close after 2 hours. label May 22, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant