Skip to content

Send scheduled automation prompts to agents that read them after they start - #26703

Merged
brennanb2025 merged 1 commit into
mainfrom
brennanb2025/p1b-automation-followup
Oct 9, 2026
Merged

brennanb2025 merged 1 commit into
mainfrom
brennanb2025/p1b-automation-followup

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​78 0 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​78
Prod 1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​6 $\color{#cf222e}{\Huge{\mathbf{−}}}$​1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​5

ELI5

When Orca's server runs a scheduled automation in a workspace that already exists, some agents start up but never receive the task. They sit idle, and the run waits for work that was never handed over. This change types the task into those agents once they are ready, the same way Orca already does when the automation creates a new workspace for each run.

What Changed

Problem. A scheduled automation can run in an existing workspace or create a new workspace per run. When the Orca server (not the desktop window) runs it in an existing workspace, it starts the agent's terminal but never sends the automation's prompt to agents whose command line takes no prompt and expect it to be typed in after they start. That covers about two dozen configured agents, including Aider, Goose, Amp, Kiro, Crush, Cline and Claude agent teams. Agents that take the prompt on their command line, such as Claude and Codex, were never affected.

User-facing change. For those agents, a scheduled run on an existing workspace now actually performs its task: the prompt is typed into the agent once it is ready, instead of the agent starting idle. Nothing changes for Claude, Codex or the other agents that take the prompt on the command line, for automations that create a new workspace per run, or for automations the desktop app runs itself.

Mechanism. The host's launchAgentTerminal (used only by the server's automation runner, for the existing-workspace case) builds the agent's startup plan. For a type-it-in-after-start agent, that plan returns a bare launch command plus a separate follow-up prompt. The function used the command and dropped the follow-up. It now hands the follow-up to the existing sendStartupFollowupWhenReady writer, which waits until the agent is running and then types the prompt. That is the same writer and readiness wait the new-workspace-per-run branch already uses (runtime-local-worktree-terminal-startup.ts). No new writer was added.

Why

This approach reuses the delivery path the sibling branch already relies on, so both workspace modes now treat these agents the same way.

Alternatives considered:

  • Refuse these agents on existing workspaces, as some interactive terminal-create paths do. Rejected: automations that already work with a new workspace per run would then fail on an existing workspace.
  • Wait for the larger planned change that moves server automations onto the shared agent launcher. Rejected: that change depends on other open work, and this bug shouldn't wait for it.

Where it came from. The bug predates recent changes. launchAgentTerminal was added in #5071. Its current form, which builds the startup plan and passes only the command to createTerminal, comes from the runtime split in #17605 and the execution-host routing in #17919. The recent extraAgentArgs passthrough only forwards extra arguments and did not cause the bug.

Linked Issue

None (maintainer fix).

Visual Proof

Not a UI change, so the proof is a stand-in agent's own log. Orca ran in server mode on an isolated, hidden laptop profile, with an automation on an existing workspace using aider. A stand-in program took aider's place and logged START when launched and LINE for every line typed into it.

Before (main): the agent starts and never gets the prompt.

before.png

After (this PR): each run's prompt arrives exactly once, right after the agent starts.

after.png

Testing

  • New src/main/runtime/launch-agent-terminal-followup.test.ts uses the real startup builder:

    • Aider (a type-it-in-after-start agent): the follow-up goes out once, to the new terminal, with the automation's prompt. This test fails on main ("expected … to be called 1 times, but got 0 times").
    • Claude: no follow-up is sent.
  • agent-terminal-launch-host.test.ts and runtime-automation-service.test.ts still pass.

  • pnpm tc:node passes, as do oxlint and the changed-files code-quality check.

  • Manual check (macOS laptop, hidden isolated profile, stand-in agents only): main and this PR, each in server mode, ran three automations on an existing workspace:

    • aider, Run now: main never sends the prompt; this PR sends it once.
    • aider, scheduled: same result as Run now.
    • claude (control): the prompt goes on the command line and nothing is typed in, on both builds.
    • Side effects: no prompt was typed twice or into the shell, and no run finished before its prompt arrived.
  • Not checked live: an SSH workspace, Windows/WSL, real agent programs, and the other agents that take their prompt after start.

  • I manually tested these changes locally

  • Automated tests added/updated, or explained why not below

Review

Reviewed by two independent reviewers (one on the change itself, one on the run lifecycle and SSH/WSL/Windows hosts), plus a release-readiness checklist. None of them found a problem caused by this change. Older limits of the shared writer are listed in the review comment.

Agent skill upstream boundary

  • Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

  • SSH: the existing-workspace launch already resolves which host owns the workspace and refuses an ambiguous one; that is unchanged. The follow-up goes through the same readiness host the new-workspace path uses for SSH workspaces.
  • Windows and WSL: the follow-up writer and its readiness checks are unchanged and already handle both, for the new-workspace path.
  • Folder workspaces: these are valid existing-workspace targets, and the change does not depend on git.
  • Mobile and wire: host-internal only. No RPC or published-state change.

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)

@brennanb2025

Copy link
Copy Markdown
Contributor Author

Review and QA summary

Problem. When the Orca server ran a scheduled or "Run now" automation on an existing workspace, agents that take their task after they start (Aider, Goose, Amp, Kiro, Crush, Cline, Claude agent teams and about 17 others) launched but never received the prompt. They sat idle and the run did nothing. The bug predates this PR: it comes from how the server's existing-workspace launch was built (#5071, reshaped in #17605 and #17919). Agents that take the prompt on their command line (Claude, Codex) were never affected.

User-facing change. Those agents now receive the automation's prompt once they start, exactly like automations that create a new workspace for each run.

What was fixed. The existing-workspace launch now hands the agent's start-up prompt to the same writer that new-workspace runs already use, and adds no new writer. There is a regression test for an agent that takes its prompt after start (fails on main) and one for an agent that takes it on the command line (no extra prompt).

Review. Two independent reviewers covered:

  • the change itself: every agent of this kind is covered, the prompt is never sent twice, and the new terminal is found on local, SSH, WSL and folder workspaces;
  • the run lifecycle and hosts: completion tracking, retention, SSH/WSL/Windows, and paired desktop or phone clients.

A release-readiness checklist also ran. None found a problem caused by this PR.

Deferred: older limits of the shared prompt writer. These already affect new-workspace runs, are not changed here, and are planned to go away when server automations move onto the shared agent launcher.

  • The writer types the prompt as soon as the agent's process is running, without waiting for its input screen. If the agent isn't running within about 4.5 seconds, the prompt is dropped with only a log line, and the idle run is recorded as completed after the 2-minute grace period.
  • A multi-line prompt is typed as raw keys, so an early line break may submit early. Open fix(runtime): frame stdin-after-start follow-up prompts through the paste protocol #24689 changes this framing.
  • Over SSH, the "agent is running" check can be one round trip stale. In theory, an agent that exits in that window gets the prompt typed into the shell.

Verified.

  • CI: green.
  • Local checks: all 22 repo static checks and the tc:node typecheck pass; the three related test files pass.
  • Manual before/after (macOS laptop, hidden isolated server-mode profile, stand-in agents): results are in the PR body.
    • aider: main never sends the prompt; this PR sends it exactly once, for both Run now and scheduled runs.
    • claude: unchanged.
    • Side effects: none of the following happened: a prompt typed twice, a prompt typed into the shell, or a run finishing before its prompt arrived.
    • User config: unchanged by the run, checked by hash only.

Not verified. A live SSH workspace, Windows/WSL hosts, real agent programs (only stand-ins were used), and the other agents of this kind individually.

@brennanb2025
brennanb2025 marked this pull request as ready for review October 9, 2026 00:43
@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

📝 Walkthrough

Walkthrough

launchAgentTerminal now sends a startup follow-up after creating a terminal when a follow-up is present. Tests check that an aider launch sends the prompt and that a claude launch does not send a follow-up.

Priority: ➖ Normal

Merge Risk: 🔵 Low · up to 1e1c3

A slow-starting agent can leave a scheduled run without its prompt. This is a bounded failure, but the follow-up should be preserved or retried.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check Passed The description is complete and focused. It explains the problem, user-facing change, mechanism, rationale, testing, manual verification, scope considerations, and checklist status. The maintainer app…
Title check Passed The title clearly and concisely describes the primary change: sending scheduled automation prompts to agents that expect input after startup.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: dc0d72a8-3f4b-435e-bb87-f1e9e3e05880
📥 Commits

Reviewing files that changed from the base of the PR and between 59b9bde and 1e1c397.

📒 Files selected for processing (2)
  • src/main/runtime/launch-agent-terminal-followup.test.ts
  • src/main/runtime/orca-runtime-terminal-create-deduplication.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Comment on lines +179 to +183
// Why: agents that read the prompt after they start get it typed in, not on argv.
if (startup.followup) {
this.sendStartupFollowupWhenReady(terminal.handle, startup.followup)
}
return terminal

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.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

rg -n 'sendWorktreeStartupFollowupWhenReady|StartupFollowupWhenReady|startup\.followup|followup:' src/main/runtime src/main/automations
sed -n '135,190p' src/main/runtime/orca-runtime-terminal-create-deduplication.ts
sed -n '65,95p' src/main/automations/runtime-automation-service.ts

Repository: stablyai/orca

Length of output: 6440


🏁 Script executed:

set -eu
printf '%s\n' '--- readiness helper ---'
nl -ba src/main/runtime/runtime-worktree-startup-readiness.ts | sed -n '1,180p'
printf '%s\n' '--- readiness host and delegator ---'
nl -ba src/main/runtime/orca-runtime-activate-managed-worktree.ts | sed -n '270,305p'
rg -n -F --glob '*.ts' -- 'getWorktreeStartupReadinessHost' src/main/runtime
printf '%s\n' '--- startup follow-up construction ---'
nl -ba src/main/runtime/runtime-worktree-agent-startup.ts | sed -n '150,225p'
printf '%s\n' '--- existing-workspace automation caller ---'
nl -ba src/main/automations/runtime-automation-service.ts | sed -n '1,145p'
printf '%s\n' '--- automation service entrypoints and configuration uses ---'
rg -n -F --glob '*.ts' -- 'runAutomation|schedule|workspaceId|automation.prompt|automation.agentId' src/main/automations src/main | head -160

Repository: stablyai/orca

Length of output: 21300


🏁 Script executed:

set -eu
printf '%s\n' '--- dispatcher contract and invocation ---'
rg -n -F --glob '*.ts' -- 'headlessDispatcher' src/main src/shared
rg -n -F --glob '*.ts' -- 'workspaceMode' src/main/automations src/shared | head -120
printf '%s\n' '--- automation run dispatch path ---'
rg -n -E --glob '*.ts' 'dispatch|dispatcher|headless' src/main/automations/service.ts src/main/automations
printf '%s\n' '--- follow-up-producing startup plans/config ---'
rg -n -E --glob '*.ts' 'followupPrompt|expectedProcess|promptCandidate|onPromptCarry' src/main src/shared | head -160

Repository: stablyai/orca

Length of output: 9888


🏁 Script executed:

set -eu
printf '%s\n' '--- dispatch request ---'
nl -ba src/main/automations/automation-dispatch-request.ts | sed -n '1,180p'
printf '%s\n' '--- service dispatch call site ---'
nl -ba src/main/automations/service.ts | sed -n '260,340p'
printf '%s\n' '--- startup plan follow-up references ---'
rg -n -F --glob '*.ts' -- 'followupPrompt' src/main src/shared
printf '%s\n' '--- startup plan definitions around follow-up branches ---'
rg -n -F --glob '*.ts' -- 'buildAgentStartupPlan' src/main src/shared

Repository: stablyai/orca

Length of output: 26225


🏁 Script executed:

set -eu
nl -ba src/shared/tui-agent-startup.ts | sed -n '35,200p'

Repository: stablyai/orca

Length of output: 7137


Preserve the follow-up when readiness polling expires.

waitForWorktreeStartupFollowup stops after 30 polls with 150 ms delays. If the expected process is still not visible, it returns null. sendWorktreeStartupFollowupWhenReady then only logs a warning and discards followup.prompt.

A scheduled headless automation for an existing workspace reaches this helper through runtime.launchAgentTerminal. The terminal launch returns without waiting for the detached writer. Therefore, a slow agent startup can leave the run with a started terminal but without its prompt. Retry or retain the follow-up after the readiness wait expires.

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