Skip to content

fix(cli): stop steering known slash commands into a running turn - #3310

Merged
Astro-Han merged 1 commit into
apache:mainfrom
me2seeks:fix/cli-mid-turn-slash-routing
Aug 20, 2026
Merged

fix(cli): stop steering known slash commands into a running turn#3310
Astro-Han merged 1 commit into
apache:mainfrom
me2seeks:fix/cli-mid-turn-slash-routing

Conversation

@me2seeks

Copy link
Copy Markdown
Contributor

Summary

Typing /recap or /resume in the TUI while a turn is running never ran the command: editor.onSubmit only special-cased exit forms, /swarm, /graph, and /goal, so every other input — including known slash commands — went to steerRunningTurn() and the model received the literal text (Steering: /resume) as a user message. Whether the command executed at all depended on whether the turn was still alive when the enqueue landed (the fallback path re-routes through submitPrompt).

Mid-turn submissions of known slash commands now route explicitly: /goal and /recap answer locally (both are independent of the running turn — recap uses the separate session.recap.generate call behind its own in-flight lock); every other known command is refused with a clear message ("Cannot run /X while a turn is running — interrupt it (Esc) or wait for it to finish.") instead of being steered or silently no-opping on the runControl busy gate; unknown slash-prefixed text (skill invocations like /skill:<name>, paths) still steers unchanged.

Fixes #3308

Verification

  • npm --workspace maka-agent test: 320 pass / 0 fail, including 4 new tests under slash commands during a running turn (/recap answers locally, /resume and /model refuse with a message, unknown slash text still steers).
  • The new tests fail without the fix: reverting pi-tui-runner.ts and rebuilding makes the /recap, /resume, and /model tests fail while the unknown-slash test still passes.
  • npm run lint, npm run format:check, npm run typecheck: pass.
  • Not run: desktop e2e (no desktop change).

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Maka (AI agent) located the routing defect, implemented the fix and tests, and ran the verification; the commit carries the Generated-by: Maka trailer. Human contributor of record reviewed the diagnosis and the routing design and decided to submit.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

Typing /recap or /resume while a turn is running injected the literal
text into the model as a steering message instead of running the
command; whether it executed at all depended on whether the turn was
still alive when the enqueue landed.

Mid-turn submissions of known slash commands now route explicitly:
/goal and /recap answer locally (both are independent of the running
turn), every other known command is refused with a clear message, and
unknown slash-prefixed text (skill invocations, paths) still steers.

Refs apache#3308

Generated-by: Maka

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVE.

The routing is right and the tests pin it at the observable boundary: driver.steered stays empty for /recap, /resume and /model, and /skill:review still steers, so both directions are covered rather than just the fixed one.

I checked the three claims the new comment rests on, and all three hold at 5c4ee2284:

  • runAgentTurn sets busy and turnRunning together (pi-tui-runner.ts:1128-1130), so runControl's if (busy) return at :633 really would swallow /help, /context, /new and the rest without a word. Refusing loudly is strictly better than that silent no-op, and the rationale in the comment is accurate.
  • recap.run goes straight to runRecap('manual') (:2857-2861) and never enters runControl, so answering /recap mid-turn is genuinely safe rather than merely untested.
  • /goal <action> already carries its own if (busy) notice (:2713-2722), so exempting /goal from the refusal does not reintroduce a silent no-op on the mutating path. That was my first suspicion and the code refutes it.

biome format is clean on both changed files at this head.

One non-blocking P3 inline. Separately, and not a review finding: statusCheckRollup is empty on this head — the test check has not run at all — so this approval covers the diff, not CI.

AI disclosure: this review was assisted by Claude (Opus) for code search and cross-checking. Everything above I re-derived myself against the source at 5c4ee2284.

Comment thread packages/cli/src/pi-tui-runner.ts
@Astro-Han
Astro-Han merged commit 04761f4 into apache:main Aug 20, 2026
1 check passed
me2seeks added a commit to me2seeks/maka-agent that referenced this pull request Aug 21, 2026
Follow-up to apache#3310: the routing call site matched command names
('goal' | 'recap') to decide which slash commands answer locally while
a turn is running. Move that knowledge onto MakaSlashCommand as a
required midTurn field ('local' | 'refuse' | 'intercepted') declared
next to each handler, so the handler that has to be safe mid-turn
carries the declaration, and a newly added command must state its
answer — omitting midTurn is a compile error. 'intercepted' documents
/exit, /swarm and /graph, which their dedicated checks claim ahead of
generic routing. Behavior is unchanged; the mid-turn routing tests
from apache#3310 pin it.

Generated-by: Maka
Astro-Han pushed a commit that referenced this pull request Aug 21, 2026
…pec (#3379)

Follow-up to #3310: the routing call site matched command names
('goal' | 'recap') to decide which slash commands answer locally while
a turn is running. Move that knowledge onto MakaSlashCommand as a
required midTurn field ('local' | 'refuse' | 'intercepted') declared
next to each handler, so the handler that has to be safe mid-turn
carries the declaration, and a newly added command must state its
answer — omitting midTurn is a compile error. 'intercepted' documents
/exit, /swarm and /graph, which their dedicated checks claim ahead of
generic routing. Behavior is unchanged; the mid-turn routing tests
from #3310 pin it.

Generated-by: Maka
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.

fix(cli): /recap and /resume typed during a running turn are steered into the model as prompt text

2 participants