Skip to content

fix(native-chat): Grok chats run the saved Command and honor or refuse the saved Arguments - #26367

Closed
brennanb2025 wants to merge 4 commits into
brennanb2025/native-chat-codex-argumentsfrom
brennanb2025/native-chat-grok-arguments
Closed

brennanb2025 wants to merge 4 commits into
brennanb2025/native-chat-codex-argumentsfrom
brennanb2025/native-chat-grok-arguments

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

ELI5

Settings → Agents → Command and Arguments are shared by terminal tabs and native chat. Grok native chat ignored both:

  • it always ran the stock grok from PATH, even when the saved Command pointed somewhere else or couldn't run;
  • it read nothing from saved Arguments except whether full access was on, so --model, --effort and the rest were silently dropped.

Now Grok chat runs the saved Command, or refuses to start with the same message Claude and Codex chats show. Every saved Argument is applied the way a Grok terminal applies it, or refused by name.

Stacked on #26059 (the same change for Codex). It reuses that PR's refusal wording and unclosed-quote handling, and is retargeted to main after #26059 merges.

What Changed

Before (Grok native chat):

  • The Command setting was ignored, so a custom Grok binary never ran in chat, and an unrunnable Command silently fell back to the stock grok.
  • Arguments were never read; only the full-access flag was checked.

After:

  • Command is the program the chat runs. It goes through the same resolver Claude and Codex chats use, and a Command that can't run refuses the start with the existing "can't run" message. A blank Command resolves grok exactly as before, including the $GROK_HOME/bin search. A test pins this on macOS and Linux.
  • Arguments are translated for grok [options] agent [agent options] stdio, the only shape Grok's chat mode accepts:
    • Kept before agent: --debug, --debug-file, --leader-socket, --disable-web-search, --no-auto-update, --compaction-mode, --compaction-detail, --log-sampling.
    • Moved after agent, where Grok's chat mode reads them: -m/--model (refused if given twice), --effort/--reasoning-effort, --no-leader.
    • Dropped, because permissions come from Orca's settings, not launch arguments: --permission-mode, --always-approve/--yolo/--dangerously-skip-permissions, --allow, --deny, --sandbox, --trust.
    • Dropped, terminal-only: display, help and version flags, and the sign-in flags --oauth / --force-login, which only affect the terminal's sign-in screen.
    • Dropped, Orca owns the session: resume, continue, session-id, fork and print options.
    • Refused by name: --cwd and --worktree, which get the hint "A chat already works in its workspace folder". Also --leader, --rules, --system-prompt, --tools, prompt text, unknown options, and an unclosed quote. An unclosed quote is refused by name when the host starts or restarts a chat. A NEW chat opened from the desktop tab bar is stopped earlier, by the shared terminal-launch planning, and shows main's toast "Could not build launch command for Grok." Terminal tabs behave the same way; this is the same follow-up noted in fix(native-chat): apply or refuse saved Codex Arguments instead of silently dropping them #26059.
  • Trade-off (decided, the same as fix(native-chat): apply or refuse saved Codex Arguments instead of silently dropping them #26059): Grok's chat mode ignores many terminal options, for example --no-memory, --no-subagents, --no-plan, --agent, --max-turns and --disallowed-tools. These now stop the chat from starting and name the option. Before, a Grok chat ignored all Arguments and always started. Arguments are shared with Grok terminal tabs, so removing such an option there changes terminal tabs too.
  • The chat's model and effort pick still wins. An Arguments --model only sets the starting model for a chat with no pick; Orca re-applies the chat's saved model over the session after it opens.
  • Full access is unchanged: grok agent --always-approve stdio when the setting says full access.

Why

Grok's chat mode honors only some of the options a terminal grok accepts, and it reads the model and effort only as agent options. So saved terminal Arguments need the same honor-or-refuse translation #26059 gives Codex, rather than being passed through raw or ignored. The common pattern for a Grok binary is a path setting, used as-is; for launch arguments to a stdio agent, it refuses reserved options by name and keeps the user's arguments after its own.

Differences from the common pattern:

  • An unrunnable Command is refused instead of being attempted. Intended: this is the same rule fix(native-chat): refuse a Command that can't run instead of silently running the stock CLI #25667 applies to Claude and Codex.
  • Grok's top-level options go before agent, and model, effort and --no-leader go after it. Intended: this is the only placement Grok's chat mode reads.
  • Permission, session, terminal-display and sign-in options are dropped quietly instead of refused. Intended: permissions come from Orca's settings, Orca owns the session, and the rest only shape a terminal. The same rule applies to Claude and Codex.
  • Under Ask, Grok's own config still decides the permission mode. Temporary, until STA-9763 (below).

Temporary: until STA-9763, Grok chat under Ask follows the user's Grok config. With full access off, Orca passes Grok no permission mode, so a ~/.grok config that auto-approves still auto-approves in chat. Making Grok chat state its mode from the chat permission setting (Ask → --permission-mode default, Full access → agent --always-approve, plus the other modes) is owned by STA-9763, a follow-up of the chat permission setting work. This PR only changes Command and Arguments.

Linked Issue

Follow-up to #25721, #25667 and #26059.

Visual Proof

QA ran on Windows (low spec), driven by a non-Claude agent over the DevTools protocol against a hidden window. The Grok agent was a stand-in that replays a recorded Grok session and logs its full command line. The box's real agent configs and its real ~/.grok were unchanged at every step.

Untouched settings start as before: grok agent --always-approve stdio, found on PATH the way stock grok is. Manual is agent stdio:
r1-G1.jpg
r1-G2.jpg

A saved Command runs (quoted path with a space). An unrunnable Command refuses with the shared message, and nothing starts:
r1-G3.jpg
r1-G4.jpg

Arguments placed where Grok's chat mode reads them. Saved --debug --disable-web-search -m qa-model --effort high --no-leader --sandbox read-only --oauth --resume x started grok --debug --disable-web-search agent --model qa-model --reasoning-effort high --no-leader stdio. The sandbox, sign-in and resume flags were dropped. A joined --debug-file=-x.log stays joined:
r1-G5.jpg
r1-G9.jpg

Refused by name (--cwd with the workspace hint, --no-memory, -m given twice). Nothing starts, and Retry works after fixing Arguments:
r1-G6.jpg
r1-G7.jpg
r1-G8.jpg
r1-G11.jpg

The chat's model pick wins. After picking Grok 4.6, a new chat with saved -m qa-other starts on qa-other, then switches to the picked model before replying:
r1-G10pick.jpg
r1-G10b.jpg

Testing

  • Targeted vitest files: the Grok launch-args translator, ACP launch resolution, command resolution (a blank Command resolves the same path as before), refusal copy, and runtime wiring.
  • orca-ci-checks, which runs CI's lint, code-quality, localization and typecheck steps: 23/23 pass.
  • A test drives a Grok Arguments refusal and an unrunnable Command through the real launch resolver and ACP start, and checks the typed refusal the client receives.
  • Electron QA on Windows (low spec) against a stand-in Grok agent: see Visual Proof.

Review

Pending.

Agent skill upstream boundary

  • Not applicable, or this change follows docs/reference/agent-skill-sharing-upstream-boundary.md and copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

  • Mixed versions: the argument-problem agent field gains Grok. An older client doesn't recognize it. On a new chat it shows the generic "Chat could not be started." with Retry; in an existing chat, the status row and message cards show the host's full sentence.
  • SSH/WSL: unchanged. The Grok chat runs where it ran before, and Arguments are read there.
  • Mobile: shows the host's sentence.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

…e the saved Arguments

A Grok chat always ran the stock `grok agent [--always-approve] stdio`: it
ignored the Command setting, even one that named no program, and never read
the saved Arguments beyond the permission posture, so a terminal's
`-m grok-4`, `--debug` or `--cwd` silently did nothing in chat.

The Command now resolves through the same resolver Claude and Codex chats
use: blank runs the stock grok found on PATH or in $GROK_HOME/bin exactly as
before, a set Command runs that program, and one that names no runnable
program refuses the start with the existing Command copy.

The saved Arguments, written for a terminal's `grok`, are placed where
`grok agent` reads them: --debug, --debug-file, --leader-socket,
--disable-web-search and --no-auto-update stay before `agent`; -m/--model,
--effort and --no-leader move to the agent's own options. Permission options
(--permission-mode, --always-approve, --allow/--deny, --sandbox, --trust),
terminal-only ones and session/print options drop, since Agent Permissions
and the chat own those. --cwd/--worktree, --leader, --rules,
--system-prompt, --tools, prompts and unknown options refuse by name.
Untouched Arguments launch exactly today's argv.
…nal sign-in options

A saved `--debug-file=-grok.log` (any `--opt=value` whose value starts with
`-`) was accepted and then handed to Grok as two tokens, which Grok's parser
reads as a new option, so the chat failed to start with a raw error. A
value written joined now reaches Grok joined, where it stays a value.

`--oauth` and `--force-login` only shape the terminal's sign-in screen and
`grok agent` never reads them, so they now drop like the other
terminal-only options instead of refusing the chat.

A test drives a refused Grok Argument and an unrunnable Command through
the real launch resolver and the ACP start path to the refusal a client
receives, before any spawn.
@brennanb2025

Copy link
Copy Markdown
Contributor Author

Review summary

Problem. Grok native chat ignored Settings → Agents → Command and Arguments:

User-facing change.

  • Command: Grok chat runs the saved Command, or refuses to start with the same "can't run" message Claude and Codex chats show.
  • Arguments: each saved Argument is placed where Grok's chat mode reads it (grok [options] agent [agent options] stdio), dropped, or refused by name:
    • Dropped: permission flags (permissions come from Orca's settings), terminal-only and sign-in flags, and session flags (Orca owns the session).
    • Refused by name, with a hint where one exists: everything else.
  • Model pick: the chat's own model and effort pick still wins over -m / --effort.

What review fixed (2 rounds plus readiness):

  • A joined value that starts with - (--debug-file=-x.log) is now passed to Grok joined. Before, it was split into a fake option and Grok failed to start.
  • --oauth / --force-login are dropped as terminal-only instead of refusing the chat; they only affect the terminal's sign-in screen.
  • A test now drives a Grok Arguments refusal and an unrunnable Command through the real launch resolver and ACP start, and checks the typed refusal the client receives.
  • The permission comment and the PR body were corrected: mixed-version behavior, the decided trade-off, the unclosed-quote caveat, and which differences are intended vs temporary.

Design decisions:

  • Ask-mode pin dropped. A pin of --permission-mode default under Ask was built and then dropped. Brennan didn't want chat to override the user's own Grok config yet. I checked the Grok source first: a resumed session doesn't keep its old permission mode across processes. Temporary: until STA-9763, Grok chat under Ask follows the user's Grok config. STA-9763 owns Grok's chat permission modes under the new chat permission setting (feat(native-chat): each Claude/Codex chat gets its own permission mode #26116 covers only Claude and Codex).
  • Decided trade-off. Options Grok's chat mode ignores (e.g. --no-memory, --max-turns) now refuse the chat by name. Before, all Arguments were ignored.

Deferred:

Verified:

  • Grok CLI placement, the honored options, -m repeat behavior and the hidden compaction/log options, read from the grok-build source with file:line.
  • Blank-Command resolution is identical to main.
  • orca-ci-checks 23/23 (lint, code-quality, localization, typecheck); 71 targeted test files.
  • Full CI on a3dd096:
    • Unit full passes on attempt 2. Attempt 1 failed only the flake above.
    • LoC and Mobile pass; Headless skipped.
  • Electron QA on Windows (low spec), Codex gpt-5.6-terra driver, with a stand-in Grok agent that replays a recorded Grok session. G1–G9, G11 and G10a/b pass:
    • exact argv for blank, saved and missing Commands;
    • placement and drops;
    • refusals word for word with nothing started;
    • Retry in place;
    • the model pick winning.
  • The box's real configs and real ~/.grok were unchanged.
  • The readiness checklist found no P0, P1 or P2.

Not verified:

  • The real grok binary (stand-in only).
  • Restarting the same chat with a saved pick (G10c; covered by a new chat).
  • The Windows $GROK_HOME\bin fallback, live.
  • macOS/Linux Electron QA.
  • SSH/WSL (Grok chat runs only on its local host; unchanged).

Stacking: this targets #26059's branch and is retargeted to main after #26059 merges (merge order: #26116 → #26059 → #26127 / this).

@brennanb2025

Copy link
Copy Markdown
Contributor Author

Closing unmerged. Grok chat already runs the saved Command, and refuses one that can't run, since #25845. Native chat no longer reads saved Arguments for any agent (#26506).

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