Common seat tune-ups

Terminal UI Orchemax owns, vendor MCP/tool allowlists, account/plan login seats (no API key), OpenClaude pinning, dontAsk vs bypassPermissions, Notification wire, and turn caps.

Goal#

Day-to-day seat friction that is still yours to configure (model pin, permissions, notify wire, vendor allowlists, account vs gateway login).

You do not need OpenCode / Claude Code mouse or Quick Edit tricks anymore. Orchemax owns the Windows terminal path for interactive seats (ConPTY / native child attach, scroll by capability, detach/reattach, live orch seat *).

Terminal UI (Windows seats) — handled by Orchemax#

Interactive orch <agent> on Windows should feel like the vendor CLI alone: typing, wheel, select/copy, and a clean prompt on exit. Orchemax does that without you setting OPENCODE_DISABLE_MOUSE, toggling Quick Edit, or pasting vendor mouse knobs.

agents:
  seat_host: true   # default on Windows; ORCH_SEAT_HOST=0 turns it off
Capability What happens
Host-scroll (Claude-settings family, e.g. OpenClaude) ConPTY hold; host VT scrollback; End follows; DEC mouse off so WT select/copy works
Child-scroll (OpenCode + unknown BYO) Native attach — vendor TUI owns scroll; Orchemax clears Quick Edit and skips forced alt-screen so typing works
Live status orch seat status|wait|read|report (+ MCP seat_*) against .orch/seats/ — not screen scraping as policy
Detach / reattach (hosted hold) LLM seat_detach when you leave the UI; come back with orch <agent> — Orchemax reattaches. No mux sidebar. Native-child seats cannot detach

Unknown orch <bin> with no catalog entry defaults to child-scroll — not a name allowlist. Catalog SeatScroll / HookLayout are optional hints only.

orch seat report <session> --state working|ready|blocked|exit
orch seat status <session> --json
orch seat wait <session> --until blocked --timeout 120
orch seat read <session> --lines 80
orch seat read <session> --deep --lines 120   # larger VT dump / paged child viewport

Tail file: .orch/seats/<session>.tail.txt while the seat runs. Hints such as maybe_blocked never satisfy wait --until blocked. Resume: --resume-ref on report (or ORCH_RESUME_REF).

Escape hatch only (seat_host: false / ORCH_SEAT_HOST=0):

agents:
  disable_mouse: off      # default — leave mouse to the agent
  # disable_mouse: clicks # Claude-family classic + DISABLE_MOUSE
  # disable_mouse: all    # same Claude knobs; Orchemax never sets OPENCODE_DISABLE_MOUSE

Env: ORCH_AGENT_MOUSE=off|clicks|all. Prefer leaving seat_host on.

One CLI's TUI fights the terminal host#

Who owns the wheel is decided per agent, not per family: child leaves the agent's own fullscreen TUI and mouse alone, host gives the scrollback to Orchemax and turns the agent's mouse off.

The same claude binary serves every workshop on a machine, so this belongs to the machine. Write it once in seats.yaml in machine-home (orch home prints the folder):

seat_scroll:
    claude: child       # keep its own mouse and alternate screen
    openclaude: child

A workshop overrides it per preset when one of them needs something else:

agents:
  seat_scroll:
    opencode: host    # hand the wheel to the terminal host, in this workshop only

Order: the workshop's orch.yaml, then seats.yaml, then the agent's catalog entry — so a CLI nobody catalogued keeps its own TUI. Name the agent here rather than reaching for disable_mouse, which speaks for all of them.

Export chat outside the seat#

orch session transcript          # newest Claude/OpenClaude JSONL → markdown
orch session transcript --open   # open .orch/transcripts/latest.md

OpenClaude model picker always snaps back (e.g. orchemax/pareto)#

Cause: ~/.openclaude/settings.json had env.OPENAI_MODEL pinned. OpenClaude merges settings.env onto the process at startup, so that value overrides the model field and the in-UI picker.

Fix: route the gateway in env, pick the model only via model:

{
  "model": "orchemax/deepseek-v4.1-flash",
  "env": {
    "CLAUDE_CODE_USE_OPENAI": "1",
    "OPENAI_BASE_URL": "http://127.0.0.1:8788/v1"
  }
}

Do not put OPENAI_MODEL (or a pasted orch_gk_…) in env when you launch with orch openclaude — the session injects the key, and orch openclaude scrubs a persisted env.OPENAI_MODEL on launch.

No permission prompts (Chair and workers)#

Under Orchemax the workshop is the perimeter (locks, guards, worktrees) — not the vendor “Allow this tool?” dialog on every Bash/Edit/MCP call.

Best default (what Orchemax wires):

Seat How auto-approval is applied
Chair interactive (Claude / OpenClaude / agy) CLI flag --dangerously-skip-permissions on the default orch <agent> command
Worker headless (same family) Same flag on the headless preset; dispatch also injects it if missing
OpenCode worker opencode run --auto
Cursor Chair + worker Interactive: --approve-mcps --trust. Headless: --force --trust --approve-mcps (Cursor’s MCP approval whitelist re-prompts when Orchemax rewrites .cursor/mcp.json)
Claude-settings JSON orch guard wire sets permissions.defaultMode: bypassPermissions when unset, and always allows mcp__orch__*

So a Chair that spawns a worker does not inherit a chain of human prompts — the worker never has a human at the keyboard. If a headless seat still hits a permission wall, Orchemax marks exit 126.

Prefer bypassPermissions over dontAsk (dontAsk denies anything not on permissions.allow):

"permissions": {
  "defaultMode": "bypassPermissions",
  "allow": [
    "mcp__orch__*",
    "Bash(*)",
    "Read(*)",
    "Edit(*)",
    "Write(*)",
    "MultiEdit(*)"
  ]
}

orch guard wire --openclaude / --claude merges mcp__orch__* and fills bypassPermissions when defaultMode is missing. Restart the seat after editing. To keep vendor prompts, set an explicit defaultMode (e.g. default) — Orchemax will not overwrite it.

Vendor allowlists / MCP approval walls#

Pattern: Orchemax rewrites seat MCP/config every launch (fresh ORCH_SESSION, role, paths). Many CLIs key a local allowlist or hash off that file. When the hash changes, the vendor re-prompts — fine in a desktop IDE, fatal for headless workers, and on some Windows TUIs the approve dialog hangs after you pick an option (you must kill the terminal).

This is not an Orchemax name-allowlist. Prefer each CLI’s native auto-approve flag on both interactive and headless presets. For a BYO agent, put the same class of flag in agents.interactive.<id> and agents.cmds.<id>.

CLI / surface What re-prompts Orchemax default / fix
Cursor (cursor-agent) Project MCP approval (mcp-approvals.json hashes the server entry; Orchemax puts ORCH_SESSION in .cursor/mcp.json env → new hash almost every seat) Interactive: cursor-agent --approve-mcps --trust. Headless: -p … --force --trust --approve-mcps
Claude / OpenClaude / agy Per-tool “Allow?” --dangerously-skip-permissions on interactive + headless
Claude-settings dontAsk MCP tools missing from permissions.allow Allow mcp__orch__*; prefer bypassPermissions (section above)
OpenCode Tool approval in run opencode run --auto
agy MCP No per-workspace MCP orch guard wire --agy --scope user --allow-user-scope once
BYO Trust / yolo / approve-mcp (vendor docs) Native flags in orch.yaml; never rely on a human at the worker keyboard

Cursor: MCP approve TUI freezes on orch cursor#

Symptom: MCP approval TUI hangs on “Applying your selection…”.

Fix: interactive default is already cursor-agent --approve-mcps --trust (update orch if yours is older). Override in orch.yaml or see configure-agents and troubleshooting.

Account / plan login seats (no API key)#

Vendor plan seats keep their own login — model traffic does not go through the local gateway. orch setup seeds agents.auth.<preset>: account for Cursor / Claude / Codex / agy / Gemini; API-key CLIs get gateway.

Do not put provider keys in keys.env for plan seats, and do not run orch gateway connect to replace the login. Override only when you mean it:

agents:
  auth:
    claude: gateway   # Anthropic API key via gateway — not the Pro/Max login

Full matrix: configure-agents, gateway-keys-and-connect.

OpenClaude needs a reply — no desktop toast#

orch guard wire --openclaude

OpenClaude reads .openclaude/, not .claude/. Opening orch openclaude also injects project .openclaude/settings.local.json. Prove the channel: orch notify test --desktop.

OpenClaude /compact fails (manual and automatic)#

Cause: compactModel (or the main model when unset) is a flash/reasoning id such as orchemax/deepseek-flash-latest. Those models often put the summary in reasoning deltas; OpenClaude only reads chat content, so it errors with “no summary text” / active-message safety limit.

Fix: orch openclaude rewrites a weak compactModel in ~/.openclaude.json to orchemax/pareto (override with ORCH_OPENCLAUDE_COMPACT_MODEL=…, opt out with =off). Then start a new seat (/new) and run /compact again — a session already past the safety stop usually will not recover in-place.

"compactModel": "orchemax/pareto"

Keep a flash model for interactive chat if you want; only compact needs a content-stable model.

OpenClaude stops at 50 turns#

openclaude --max-turns 0
# or OPENCLAUDE_MAX_TURNS=200

Or in orch.yaml:

agents:
  interactive:
    openclaude: openclaude --max-turns 0