From eaddccf7c304d15657e91697ee38ef8cd249c3bc Mon Sep 17 00:00:00 2001 From: ryushione <108252882+ryushione@users.noreply.github.com> Date: Sun, 12 Jul 2026 10:00:48 +0900 Subject: [PATCH] skills: prefer agent-first worktree launch; avoid empty shell tabs (#7957) * skills: prefer agent-first worktree launch; avoid empty shell tabs Document Orca's first-terminal behavior so agents do not leave dead shell tabs: --agent runs in the first terminal (one tab), bare worktree create + terminal create leaves shell + agent (two tabs). Also: re-resolve live handles via terminal list after create, message one handle only, and prefer orchestration check --inject over terminal send for pure orchestration pings. Aligns with CLI docs (--agent launches the selected agent in the first terminal). * fix skill guidance for agent-first worktrees --------- Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com> --- .../scripts/orca-cli-skill-guidance.test.mjs | 22 ++++++++++++++ .../orchestration-skill-guidance.test.mjs | 30 +++++++++++++++++++ skills/orca-cli/SKILL.md | 22 ++++++++------ skills/orchestration/SKILL.md | 13 ++++++-- 4 files changed, 75 insertions(+), 12 deletions(-) diff --git a/config/scripts/orca-cli-skill-guidance.test.mjs b/config/scripts/orca-cli-skill-guidance.test.mjs index 3fb29539d..d42e32c81 100644 --- a/config/scripts/orca-cli-skill-guidance.test.mjs +++ b/config/scripts/orca-cli-skill-guidance.test.mjs @@ -45,6 +45,28 @@ describe('orca CLI skill guidance', () => { expect(skill).toContain('send the prompt, and stop') }) + it('prefers agent-first workers without duplicating terminal delivery', () => { + const skill = readSkill() + + expect(skill).toContain('Prefer agent-first create for agent workers') + expect(skill).toContain('fallback shell plus a later `terminal create') + expect(skill).toContain('Repo setup or default-terminal settings may still add tabs or splits') + expect(skill).toContain( + 'when no repo default-terminal configuration supplies a primary terminal' + ) + expect(skill).toContain('Configured default tabs are materialized instead') + expect(skill).toContain( + 'only after `terminal list` or `terminal show` confirms it is an unused shell' + ) + expect(skill).not.toContain('bare `worktree create` (no `--agent`) still opens') + expect(skill).not.toContain('ends with **one** tab') + expect(skill).toContain('Use `startupTerminal.handle` as the sole agent handle') + expect(skill).toContain('never dual-send to old and replacement handles') + expect(skill).toContain( + "this checks the caller's inbox and does not remotely deliver input to another terminal" + ) + }) + it('keeps browser injection guidance narrow and avoids literal secret examples', () => { const skill = readSkill() diff --git a/config/scripts/orchestration-skill-guidance.test.mjs b/config/scripts/orchestration-skill-guidance.test.mjs index 78a51ad10..7c7196d86 100644 --- a/config/scripts/orchestration-skill-guidance.test.mjs +++ b/config/scripts/orchestration-skill-guidance.test.mjs @@ -188,4 +188,34 @@ describe('orchestration skill guidance', () => { expect(skill).not.toContain('post-completion polling messages') expect(skill).not.toContain('every 2 minutes') }) + + it('keeps agent-first launch, handle recovery, and inbox injection distinct', () => { + const skill = readSkill() + const messaging = getSection(skill, 'Messaging') + const workerTerminals = getSection(skill, 'Worker Terminals') + const agentFirstExample = workerTerminals.match( + /```bash\norca worktree create --name --agent codex --json\n[\s\S]*?```/ + )?.[0] + + expect(workerTerminals).toContain('Agent-first (required for ordinary agent workers)') + expect(workerTerminals).toContain('fallback shell + agent pair') + expect(workerTerminals).toContain( + 'Repo setup or default-terminal settings may still add tabs or splits' + ) + expect(workerTerminals).toContain('without configured default tabs') + expect(workerTerminals).toContain( + 'only after `terminal list` or `terminal show` confirms it is an unused shell' + ) + expect(workerTerminals).not.toContain('bare create opens a default shell') + expect(workerTerminals).not.toContain('ends with **one** agent tab') + expect(agentFirstExample).toBeDefined() + expect(agentFirstExample).not.toContain('orca terminal list') + expect(agentFirstExample).toContain('startupTerminal.handle') + expect(messaging).toContain( + 'Use `startupTerminal.handle` from the create response when present' + ) + expect(messaging).toContain('continue with the replacement only') + expect(messaging).toContain('it does not remotely wake another terminal') + expect(messaging).toContain('Use `orchestration dispatch --inject` to deliver a tracked task') + }) }) diff --git a/skills/orca-cli/SKILL.md b/skills/orca-cli/SKILL.md index e4e82d972..3875a37d2 100644 --- a/skills/orca-cli/SKILL.md +++ b/skills/orca-cli/SKILL.md @@ -55,7 +55,9 @@ Use `--no-parent` and omit `--base-branch` for independent top-level handoffs un Custom Codex model/effort handoff: -`worktree create --agent codex --prompt ...` launches the known Codex agent but does not accept Codex-specific `--model` or `-c model_reasoning_effort=...` arguments. For requests such as `gpt-5.5 xhigh`, create the independent worktree, launch the requested Codex command there, wait only for TUI readiness if needed to avoid losing input, send the prompt, and stop: +`worktree create --agent codex --prompt ...` launches the known Codex agent but does not accept Codex-specific `--model` or `-c model_reasoning_effort=...` arguments. For requests such as `gpt-5.5 xhigh`, create the independent worktree, launch the requested Codex command there, wait only for TUI readiness if needed to avoid losing input, send the prompt, and stop. + +**Extra first terminal:** when no repo default-terminal configuration supplies a primary terminal, bare `worktree create` (no `--agent`) opens a fallback shell before the later `terminal create --command ...` adds the agent. Configured default tabs are materialized instead and may run real commands. Prefer `--agent` whenever the built-in launcher is enough. When custom argv forces the two-step path, target the agent handle only; close a prior terminal only after `terminal list` or `terminal show` confirms it is an unused shell. ```bash orca worktree create --name --no-parent --json @@ -121,13 +123,15 @@ orca worktree create --name task --setup skip --json orca worktree create --name task --run-hooks --json ``` -- `--agent ` launches that agent in the first terminal; `--prompt ` sends initial work to it. +- `--agent ` launches that agent **in the first terminal** (Orca docs: *"`--agent` launches the selected agent in the first terminal"*); `--prompt ` sends initial work to it. Known ids include `claude`, `codex`, `omp`, `pi`, `grok`, and other installed TUI agents. +- **Prefer agent-first create for agent workers.** `orca worktree create --agent --prompt "..."` puts the agent in the worktree's first terminal without adding a separate fallback shell for that worker. Repo setup or default-terminal settings may still add tabs or splits. Without configured default tabs, the bare-create fallback shell plus a later `terminal create --command ` is an anti-pattern for ordinary agent worktrees — use `--agent` instead of “create worktree, then open agent.” Configured default tabs are intentional surfaces; never treat one as disposable without verifying that it is an unused shell. +- After create, use exactly one agent handle: `startupTerminal.handle` from the create response when present, or the matching result from `orca terminal list --worktree id: --json` (or `name:`) when the response omits it. If a handle later returns `terminal_handle_stale`, re-list it; never dual-send to old and replacement handles. - `--setup run|skip|inherit` controls repo setup hooks. Default is `inherit`, which follows the repo's setup policy. - `--run-hooks` is a legacy alias for `--setup run`; it also reveals/activates the new worktree. - `--agent`, `--activate`, and `--run-hooks` reveal the new worktree. Plain create stays in the background. -- Let Orca choose setup terminal placement from repo settings, including tab vs split behavior. Do not manually create extra setup terminals. -- If an older installed CLI rejects `--agent`, `--prompt`, or `--setup`, create the worktree normally, then run `orca terminal create --worktree --command "codex"` and `orca terminal send` if a prompt is needed. -- `worktree create` creates a new checkout. For a fresh agent in the current checkout, use `orca terminal create --worktree active --command "codex" --json`. +- Let Orca choose setup terminal placement from repo settings, including tab vs split behavior. Do not manually create extra setup terminals when `--agent` already owns the first tab. +- If an older installed CLI rejects `--agent`, `--prompt`, or `--setup`, create the worktree normally, then run `orca terminal create --worktree --command "codex"` and `orca terminal send` if a prompt is needed. This can leave a fallback shell when no default tabs are configured; close it only after confirming it is unused. +- `worktree create` creates a new checkout. For a fresh agent in the **current** checkout (no new worktree), use `orca terminal create --worktree active --command "codex" --json` — that path does not create a second worktree shell. ## Worktree Comments @@ -173,10 +177,10 @@ Terminal rules: - `--terminal` is optional for most commands; omitted means the active terminal in the current worktree. - Use `terminal read` before `terminal send` unless the next input is obvious. - Use `terminal send` only for direct terminal input or one-off prompts where no task state, inbox, or reply tracking is needed. -- For structured coordination, invoke the `orchestration` skill; it uses `orca orchestration ...` commands for messages, handoffs, task DAGs, dispatches, inbox/reply flows, and coordinator loops. -- Use `terminal create --worktree active --command ""` for a fresh agent in the current worktree. Use `worktree create --agent ` only for a separate checkout. -- Use `terminal wait --for tui-idle` for agent CLIs such as Claude Code, Gemini, and Codex; always pass `--timeout-ms`. -- Terminal handles are runtime-scoped. If Orca restarts or returns `terminal_handle_stale`, reacquire with `terminal list`. +- For structured coordination, invoke the `orchestration` skill; it uses `orca orchestration ...` commands for messages, handoffs, task DAGs, dispatches, inbox/reply flows, and coordinator loops. A receiving agent can run `orca orchestration check --unread --inject` to render its unread mail in agent-readable form; this checks the caller's inbox and does not remotely deliver input to another terminal. +- Use `terminal create --worktree active --command ""` for a fresh agent in the current worktree. Use `worktree create --agent ` only for a separate checkout (agent in the first terminal — do not also `terminal create` the same agent). +- Use `terminal wait --for tui-idle` for agent CLIs such as Claude Code, Gemini, Codex, OMP, Pi, and Grok; always pass `--timeout-ms`. +- Terminal handles are runtime-scoped. Use `startupTerminal.handle` as the sole agent handle when `worktree create --agent` returns it; if Orca restarts, omits the handle, or returns `terminal_handle_stale`, reacquire with `terminal list` and continue with the replacement only. - For long output, use cursor reads. After a limited tail preview, page from `oldestCursor`; after a cursor read, continue with `nextCursor` while `limited` is true and `nextCursor !== latestCursor`. - `--direction horizontal` splits left/right. `--direction vertical` splits top/bottom. diff --git a/skills/orchestration/SKILL.md b/skills/orchestration/SKILL.md index 90aeb093c..dd50b7756 100644 --- a/skills/orchestration/SKILL.md +++ b/skills/orchestration/SKILL.md @@ -88,6 +88,8 @@ orca orchestration inbox [--limit ] [--json] Rules: - Omit `--from` unless impersonating another terminal; Orca auto-resolves it from the current terminal. +- Message **one** live agent handle per worker. Use `startupTerminal.handle` from the create response when present; if it is missing or later returns `terminal_handle_stale`, re-resolve with `orca terminal list --worktree ... --json` and continue with the replacement only. +- `orca orchestration check --unread --inject --json` renders unread mail for the agent terminal that runs it; it does not remotely wake another terminal. Use `orchestration dispatch --inject` to deliver a tracked task, or `terminal send` when an existing agent needs a free-form prompt. - While supervising workers manually, use `check --wait --types worker_done,escalation,decision_gate --timeout-ms ` instead of sleep/poll loops. Reply to `decision_gate` messages with `orca orchestration reply --id --body --json`, then keep waiting. - Treat a `check --wait` timeout or `{count:0}` as a checkpoint, not a worker failure. Long coding tasks routinely run 15-60 minutes; keep using rolling waits unless you receive `worker_done`/`escalation`, the terminal exits or disappears, or the user explicitly asks you to stop. - Heartbeats and visible terminal activity mean the worker is alive, not done. Do not stop, close, kill, or restart a worker just because it has not produced a completion message yet. @@ -159,7 +161,9 @@ orca terminal send --terminal --text "" --enter --json Custom Codex model/effort handoff: -`orca worktree create --agent codex --prompt ...` launches the known Codex agent but does not accept Codex-specific `--model` or `-c model_reasoning_effort=...` arguments. When the user asks for a specific Codex model or effort, create the independent worktree first, launch Codex with the requested command in that worktree, wait only for TUI readiness if prompt delivery would otherwise race startup, send the prompt, and stop: +`orca worktree create --agent codex --prompt ...` launches the known Codex agent but does not accept Codex-specific `--model` or `-c model_reasoning_effort=...` arguments. When the user asks for a specific Codex model or effort, create the independent worktree first, launch Codex with the requested command in that worktree, wait only for TUI readiness if prompt delivery would otherwise race startup, send the prompt, and stop. + +Note: when no repo default-terminal configuration supplies a primary terminal, bare create opens a fallback shell before `terminal create` adds the agent. Configured default tabs are materialized instead and may run real commands. Prefer `--agent` whenever custom argv is not required. With the two-step path, target only the agent handle; close a prior terminal only after `terminal list` or `terminal show` confirms it is an unused shell. ```bash orca worktree create --name --no-parent --json @@ -186,12 +190,15 @@ Reuse an idle agent in the required worktree only if the prompt allows reuse; ot ```bash orca worktree create --name --agent codex --json -orca terminal list --worktree id: --json +# or: --agent claude | omp | pi | grok | ... +# Read from startupTerminal.handle in the create response. orca terminal wait --terminal --for tui-idle --timeout-ms 60000 --json orca orchestration dispatch --task --to --inject --json ``` -For new-worktree workers, read the id from `worktree create`, then use `terminal list` to get the agent handle. Omit `--repo` only inside an Orca-managed worktree; otherwise pass `--repo `. `--agent` reveals the new worktree and launches the selected agent in its first terminal, so do not create a separate startup terminal. Do not run `worktree create` when the task must stay in the current worktree. +For new-worktree workers, read the id and `startupTerminal.handle` from `worktree create`. Use that as the sole worker handle when present; otherwise use `terminal list` to resolve the agent handle. Omit `--repo` only inside an Orca-managed worktree; otherwise pass `--repo `. + +**Agent-first (required for ordinary agent workers):** `--agent` reveals the new worktree and launches the selected agent **in its first terminal**, without adding a separate fallback shell for that worker. Repo setup or default-terminal settings may still add tabs or splits. Do **not** run bare `worktree create` and then `terminal create --command ` for the same worker when agent-first create is available: without configured default tabs, that two-step path leaves a fallback shell + agent pair. Only use it when custom agent argv is required (for example Codex model/effort flags) or when an older CLI rejects `--agent`; if you must, message only the agent handle. Configured default tabs are intentional surfaces, so close a prior terminal only after `terminal list` or `terminal show` confirms it is an unused shell. Do not run `worktree create` when the task must stay in the current worktree. Use `orca worktree create --prompt ...` or `orca terminal send ...` for full handoffs or untracked/lightweight prompts. Those paths do not attach `taskId`/`dispatchId`; the worker should not send lifecycle messages unless the prompt supplies a live orchestration preamble.