Repository navigation
fix(orchestration): give an OpenCode worker its task only once OpenCode can submit it - #25101
Conversation
…sk starts OpenCode 2 draws its input box before it has loaded its agent list from its server, and silently drops an Enter that arrives in that gap. On a loaded machine the gap outlasts the 0.5 s Orca waits after pasting, so a worker's task sat unsent in the box while worker-start reported it ready. OpenCode's turn start is now observed through its status hooks, like Codex and Claude. While no turn has started, the prompt verifier presses Enter again on an interval (per the agent row, opencode and opencode2) for as long as the pane's hooks are reporting, never past an approval or question prompt or a replaced pane, and at most a fixed number of times. A pane whose hooks never report keeps today's single Enter and unobserved receipt. Co-Authored-By: Claude <noreply@anthropic.com>
…code-worker # Conflicts: # src/main/runtime/agent-prompt-submission-verification.ts
OpenCode 2 draws its input box, and shows its cursor there, before its agent list has loaded from its server, and it silently drops an Enter that arrives in that gap. Orca pasted a worker's task on the box's cursor and pressed Enter half a second later, so on a loaded machine the task stayed unsent in the box while the worker read as started. OpenCode's paste readiness now also waits for the row under the input box (`<agent> · <model>`), which OpenCode paints only once the agent list exists. The rule keys on the row's separator inside OpenCode's alternate screen, not on names or colours. Both the opencode and opencode2 rows use it, worker start and the renderer's draft paste alike. OpenCode 1 paints the row in the box's own frame, so it is ready on the same read as before. Recorded OpenCode 2.0.21 boots (cold, hidden pane, four at once, attached to a running server) are the evidence; two more show an Enter after the row submitting and one at the box being dropped. The earlier resubmit loop and the settlement-provider changes are removed. Co-Authored-By: Claude <noreply@anthropic.com>
…ever paste a draft blind Replaces three recordings made by launching four OpenCode boots at once with natural single-run evidence: one cold start that pasted on the agent row and pressed Enter on Orca's real 500 ms timing (submitted), and one cold start recorded under heavy load from other sessions, where the paste on the box's cursor and Orca's Enter came before the agent row and the brief stayed unsent. Adds a 2.0.14 cold start as a cross-version check. The renderer's draft paste no longer falls back to a blind paste when the OpenCode agent-row signal never arrives: OpenCode would drop the Enter and leave the draft in its box, so the caller gets its timeout notice instead. Other agents keep the fallback. Co-Authored-By: Claude <noreply@anthropic.com>
…gnals Co-Authored-By: Claude <noreply@anthropic.com>
… it only before Enter - The agent-row signal now keys on structure: the `·` must sit on the line directly above the input box's bottom-left corner, so a `·` in the footer path or a session tab title no longer counts. Leaving the alternate screen or turning bracketed paste off withdraws what each part established. - Only deliveries that press Enter wait for the row (new `submitPasteReadySignal`); drafts keep the box-cursor rule, as on main. Worker start always submits. - When the box cursor has shown but the row never comes (OpenCode 2 drops the agent below 44 columns), both waiters proceed after a 5 s grace, as main did. A natural 40-column capture proves that start submits. - The renderer's blind-paste fallback is back to main's behaviour. Co-Authored-By: Claude <noreply@anthropic.com>
…-row grace is pending - Both paste waiters resolve ready, not timed out, when the hard deadline lands while the 5 s grace is pending: the box was seen, so this is the verdict the box rule gave before. - Tab-bound draft paste is tested to wait on the agent row only when Enter follows. - Scanner: a separator pairs with its corner only inside one synchronized frame, row 0 clamps to 1, and the grace comment names the transparent-theme case. The draft signal type no longer admits the agent-row signal, whose grace only the paste waiters honour. Co-Authored-By: Claude <noreply@anthropic.com>
…alternate screen If OpenCode exited after drawing its box but before its agent row, the grace still ran out and the task was pasted into the shell. Leaving the alternate screen now clears the box cursor, and once an app has left it a cursor the shell shows outside it no longer starts a grace. A terminal that never forwards the alternate screen still gets one. Co-Authored-By: Claude <noreply@anthropic.com>
|
Status update: CI on 6ce7d6f finished green (run 37237091526: all test shards, Final status (head 6ce7d6f)The problem. An OpenCode worker started with
What changes for users.
Fixed in review. The first version of this PR pressed Enter again until a turn started. Review showed that needed per-prompt bookkeeping that could pin later turns to stale prompts. It could also press Enter into a busy OpenCode, where Enter approves a permission prompt. That version was replaced with the readiness wait. Review of the readiness wait then fixed:
The final readiness review found no P0–P2 issues. Deferred / not in this PR.
Verified.
Not verified.
Note: these images were uploaded from the OrcaWin account. They load for signed-in GitHub users but returned 404 to an anonymous request, so if they don't render for you, that is why. The originals are on the M4Air under |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. 🧰 Additional context used📚 Code guidelines (1)📝 WalkthroughWalkthroughThe change adds a structural scanner that detects OpenCode’s agent row above the input box. OpenCode configurations use this signal when a paste will be submitted. Renderer and runtime readiness waits now handle scanner-provided grace delays. New timed captures, census records, and tests cover startup, submission, delayed agent-row rendering, and narrow-pane behavior. Priority: ➖ Normal Merge Risk: 🔵 Low · up to If OpenCode exits during the readiness wait, a launch can report its task as delivered when it was not. Cancel readiness on PTY exit before merging, or accept this bounded failure case. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The change improves startup timing without granting new access. However, a stopped session can still be reported as having received its task, weakening failure detection and recovery. Retained concerns
Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
🛠️ Fix failing CI checks 💡
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. Comment |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
A new submit-readiness signal lets Orca wait until OpenCode can actually accept its task before pasting and pressing Enter, closing the STA-9359 race where the Enter was dropped on a slow start.
- New structural scanner (
src/shared/opencode-agent-row-scanner.ts) — detects OpenCode's<agent> · <model>row by screen position (separator on the line directly above the box's╹corner, inside the alt screen, with the box cursor shown under bracketed paste), and asks for a 5 s grace while the box is up without the row. - Signal plumbing —
resolvePasteReadySignal(config, submit)plussubmitPasteReadySignalin the agent config;opencode/opencode2useopencode-agent-rowonly when Enter follows the paste, so draft-only pastes keeprender-cursor-after-bracketed-paste. - Waiters — main and renderer readiness waiters arm a one-shot grace from
readyAfterMs(withdrawn on null, not restarted), and the hard deadline takes the box when a grace is pending. - Worker start —
waitForFreshWorkerComposernow passessubmit: true, so a fresh OpenCode worker's task is delivered only once the row is painted. - Evidence — new timed fixtures (cold standalone, hidden pane, warm server, natural-load Enter-dropped, narrow pane, enter-after-row) with meta/timing JSON and census snapshots, plus scanner, chunking, worker-lane, and launched-agent transcript suites. The tests replay the real emulator and assert the ready read against the row position; the dropped-Enter and grace cases are pinned to recorded timings.
The implementation reads cleanly against the existing single-signal scanner: leftAltScreen correctly prevents a shell cursor outside the alt screen from re-arming the grace, and the OpenCode 1 row-before-corner case is handled by the synchronized-frame pending set. Windows remains the main uncertainty (documented in the PR): if the alt-screen/bracketed-paste/╹ frames are not forwarded, the row cannot fire and the 5 s grace falls back to today's behavior rather than pasting early.
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
…d-restore counts The six OpenCode 2 captures this PR adds hit the serializer limitations the 1.18.32 and 2.0.18 captures are already registered for: the live pen's background (and once its bold bit) on restored cells, rows kept below the source after a shrink, and the cursor one column short after a shrink. No I1 or I3 failure; the serializer is unchanged. Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
This is a re-review of the OpenCode submit-readiness fix (STA-9359): a submitted task now waits for OpenCode's <agent> · <model> row, not just the input-box cursor, before Orca pastes and presses Enter. Since the prior pullfrog review approved a89d9a5, the only delta is a test-baseline commit and a merge of origin/main.
- New structural scanner (
src/shared/opencode-agent-row-scanner.ts) — detects OpenCode's<agent> · <model>row by screen position (separator on the line directly above the box's╹corner, inside the alt screen, with the box cursor shown under bracketed paste), asks for a 5 s grace while the box is up without the row, and withdraws readiness/grace on alt-screen leave or bracketed-paste off.leftAltScreenprevents a shell cursor outside the alt screen from re-arming the grace. - Signal plumbing —
resolvePasteReadySignal(config, submit)plussubmitPasteReadySignal;opencode/opencode2useopencode-agent-rowonly when Enter follows the paste, so draft-only pastes keeprender-cursor-after-bracketed-paste. - Waiters — main and renderer readiness waiters arm a one-shot grace from
readyAfterMs(withdrawn on null, not restarted); the hard deadline takes the box when a grace is pending.waitForFreshWorkerComposerpassessubmit: true. - Serializer baseline (
0ec73d9) — registersKNOWN_PREEXISTING_I2_FAILUREScounts for the six new OpenCode captures. I re-ranserialize-grid-transcript-replay.test.tsfiltered toopencodeagainst the merged (changed-on-main) serializer: all 13 transcripts pass, so the exact-count registrations are still correct post-merge. - Evidence — scanner/transcript/chunking/worker-lane/launched-agent/runtime-readiness suites all pass; the dropped-Enter and grace cases are pinned to recorded timings.
The Windows gap (if alt-screen/2004/╹ are not forwarded, the 5 s grace falls back to today's behavior rather than pasting early) remains documented and unverified, as the PR states.
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
…code-worker # Conflicts: # src/main/runtime/launched-agent-composer-readiness.test.ts # src/main/runtime/orca-runtime-activate-managed-worktree.ts # src/main/runtime/runtime-worktree-startup-readiness.ts
With a grace pending, the deadline runs one more settle check, and over SSH its foreground read could hold a past-due wait for the channel's 30 s timeout. It now gives up after 2 s. Tests cover a hand-off, a failure and an abort during that check, a refused grace settled at the deadline, the bound, and the grace restarting at a hand-off. Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to GitHub limitations.
🟡 Minor · Cancel readiness when the PTY exits. · agent-draft-readiness.ts:61-71
src/renderer/src/lib/agent-draft-readiness.ts:61-71
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winCancel readiness when the PTY exits.
When OpenCode’s submit scanner sees the box cursor without the agent row, it arms a 5-second grace timer. The waiter does not settle on local PTY exit, and its remote stream subscription does not pass
onEnd; with no further data, the timer still resolvestrue.pasteDraftWhenAgentReadythen skips its process-check fallback and sends to the capturedptyId. If the local PTY has exited,writeAcceptedreturnsfalse, butsendRuntimePtyInputVerifiedfalls back to fire-and-forgetpty.writeand returnstrue. The launch path can report the dropped prompt as delivered. Settle the wait as false on local PTY exit or remote stream end.Suggested fix
import { subscribeToPtyData } from '@/components/terminal-pane/pty-data-sidecar-subscriptions' +import { subscribeToPtyExit } from '@/components/terminal-pane/pty-dispatcher' import { replayPreHandlerPtyData } from '@/components/terminal-pane/pty-pre-handler-buffer' ... let hardTimer: number | null = null let unsubscribe: (() => void) | null = null + let unsubscribeExit: (() => void) | null = null ... unsubscribe?.() + unsubscribeExit?.() resolve(value) ... `desktop:paste-ready:${ptyId}`, - observeData + observeData, + { onEnd: () => finish(false) } ) ... } else { + unsubscribeExit = subscribeToPtyExit(ptyId, () => finish(false)) unsubscribe = subscribeToPtyData(ptyId, observeData)
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
c126ec3d-3d1c-4c31-bb2b-00d544f5f63a
📒 Files selected for processing (6)
src/main/runtime/launched-agent-composer-readiness.test.tssrc/main/runtime/orca-runtime-activate-managed-worktree.tssrc/main/runtime/runtime-worktree-startup-readiness.test.tssrc/main/runtime/runtime-worktree-startup-readiness.tssrc/renderer/src/lib/agent-paste-draft.tssrc/shared/draft-paste-ready-scanner.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.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Incremental re-review of the OpenCode submit-readiness fix (STA-9359), covering everything since pullfrog's prior review at 6ce7d6f: the merge of origin/main (integration with #24257's agent-launch refactor) and a follow-up commit that bounds the readiness deadline's last settle check.
- Merged
origin/main's launch-readiness refactor (#24257) —isShellInFront,accept, hand-off tracking, and thesettleSignal/recheckAtmachinery are preserved intact from main; this PR's submit signal and grace timer layer on top through the extractedpassesSettleChecks, which is semantically identical to the inline checks it replaces. submit: truefor the fresh-worker composer —waitForFreshWorkerComposernow waits on OpenCode's agent row for every caller. All of its call sites (worker start,agent.launchterminal prompt, the grok marker race, and the non-marker idle fallback) paste and then press Enter, so the harder signal is only reached by deliveries that actually submit; other composer-marker agents fall back to their unchanged draft signal.- Deadline settle bound (
391700e) — the deadline's one final settle check is capped atDEADLINE_SETTLE_CHECK_MS(2 s), so an SSH foreground read can no longer hold a past-due wait to the channel timeout. A failure, abort, or shell hand-off during that check settlesnull, and a refused grace still takes the box once the agent is proven in front. - Test coverage — the new main-lane and renderer cases pin grace arming/withdrawal, the deadline fallback, and the 2 s bound with exact assertions (
advanceTimersByTimeAsync(1999)then(1), not loose truthiness).
I re-ran the readiness and scanner suites (runtime-worktree-startup-readiness, launched-agent-composer-readiness, opencode-worker-composer-transcript, opencode-agent-row-enter/structure-transcript, draft-paste-ready-scanner-chunking, draft-paste-ready-scanner) — 238 tests pass. The Windows gap (if alt-screen/2004/╹ are not forwarded, the 5 s grace falls back to today's behavior rather than pasting early) remains documented and unverified, as the PR states.
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
…ch-prompt-argv-carry Conflicts resolved against #23962's head this branch had merged (83de487), so each keeps main's squashed #23962 plus this branch's change: - daemon protocol v42 (launch files), v41 (#23962's staged startup lines) now in PREVIOUS; build compatibility contract and pinned version tests follow. - agent-draft-readiness keeps main's OpenCode agent-row grace (#25101) and this branch's bracketed-paste-off revocation of the quiet window. - startup-line-prompt-carry.test.ts stays deleted; its rule lives in launch-prompt-carry. Semantic follow-ups from #23672 (CR submission, one-line PowerShell quoting): - windowsLaunchLineVerdict reads line breaks from the prompt too: PowerShell now quotes a multi-line prompt onto one physical line, which hid the measured multi-line rows (a 9 KB multi-line prompt read as exact) and the shim's line-break cut. - Typed launch lines end in CR; raw multi-line lines submit each break with CR; the PowerShell multi-line expectations use the one-line backtick form. - A duplicated pair of #23962 staging tests left by the auto-merge is removed. - agent-paste-draft: the two identical launch-paste tails share sendLaunchPaste; tui-agent-config writes devin on one line like jcode (main sat at the line cap).
…de can submit it (stablyai#25101) * fix(orchestration): keep pressing Enter until an OpenCode worker's task starts OpenCode 2 draws its input box before it has loaded its agent list from its server, and silently drops an Enter that arrives in that gap. On a loaded machine the gap outlasts the 0.5 s Orca waits after pasting, so a worker's task sat unsent in the box while worker-start reported it ready. OpenCode's turn start is now observed through its status hooks, like Codex and Claude. While no turn has started, the prompt verifier presses Enter again on an interval (per the agent row, opencode and opencode2) for as long as the pane's hooks are reporting, never past an approval or question prompt or a replaced pane, and at most a fixed number of times. A pane whose hooks never report keeps today's single Enter and unobserved receipt. Co-Authored-By: Claude <noreply@anthropic.com> * fix(opencode): give a worker its task only once OpenCode can submit it OpenCode 2 draws its input box, and shows its cursor there, before its agent list has loaded from its server, and it silently drops an Enter that arrives in that gap. Orca pasted a worker's task on the box's cursor and pressed Enter half a second later, so on a loaded machine the task stayed unsent in the box while the worker read as started. OpenCode's paste readiness now also waits for the row under the input box (`<agent> · <model>`), which OpenCode paints only once the agent list exists. The rule keys on the row's separator inside OpenCode's alternate screen, not on names or colours. Both the opencode and opencode2 rows use it, worker start and the renderer's draft paste alike. OpenCode 1 paints the row in the box's own frame, so it is ready on the same read as before. Recorded OpenCode 2.0.21 boots (cold, hidden pane, four at once, attached to a running server) are the evidence; two more show an Enter after the row submitting and one at the box being dropped. The earlier resubmit loop and the settlement-provider changes are removed. Co-Authored-By: Claude <noreply@anthropic.com> * fix(opencode): prove the agent-row signal with natural captures and never paste a draft blind Replaces three recordings made by launching four OpenCode boots at once with natural single-run evidence: one cold start that pasted on the agent row and pressed Enter on Orca's real 500 ms timing (submitted), and one cold start recorded under heavy load from other sessions, where the paste on the box's cursor and Orca's Enter came before the agent row and the brief stayed unsent. Adds a 2.0.14 cold start as a cross-version check. The renderer's draft paste no longer falls back to a blind paste when the OpenCode agent-row signal never arrives: OpenCode would drop the Enter and leave the draft in its box, so the caller gets its timeout notice instead. Other agents keep the fallback. Co-Authored-By: Claude <noreply@anthropic.com> * fix(opencode): type the single-signal predicate against the public signals Co-Authored-By: Claude <noreply@anthropic.com> * fix(opencode): read the agent row by its place on screen and wait for it only before Enter - The agent-row signal now keys on structure: the `·` must sit on the line directly above the input box's bottom-left corner, so a `·` in the footer path or a session tab title no longer counts. Leaving the alternate screen or turning bracketed paste off withdraws what each part established. - Only deliveries that press Enter wait for the row (new `submitPasteReadySignal`); drafts keep the box-cursor rule, as on main. Worker start always submits. - When the box cursor has shown but the row never comes (OpenCode 2 drops the agent below 44 columns), both waiters proceed after a 5 s grace, as main did. A natural 40-column capture proves that start submits. - The renderer's blind-paste fallback is back to main's behaviour. Co-Authored-By: Claude <noreply@anthropic.com> * fix(opencode): take the box at the readiness deadline while the agent-row grace is pending - Both paste waiters resolve ready, not timed out, when the hard deadline lands while the 5 s grace is pending: the box was seen, so this is the verdict the box rule gave before. - Tab-bound draft paste is tested to wait on the agent row only when Enter follows. - Scanner: a separator pairs with its corner only inside one synchronized frame, row 0 clamps to 1, and the grace comment names the transparent-theme case. The draft signal type no longer admits the agent-row signal, whose grace only the paste waiters honour. Co-Authored-By: Claude <noreply@anthropic.com> * fix(opencode): withdraw the agent-row grace when OpenCode leaves the alternate screen If OpenCode exited after drawing its box but before its agent row, the grace still ran out and the task was pasted into the shell. Leaving the alternate screen now clears the box cursor, and once an app has left it a cursor the shell shows outside it no longer starts a grace. A terminal that never forwards the alternate screen still gets one. Co-Authored-By: Claude <noreply@anthropic.com> * test(serialize): register the new OpenCode captures' pre-existing grid-restore counts The six OpenCode 2 captures this PR adds hit the serializer limitations the 1.18.32 and 2.0.18 captures are already registered for: the live pen's background (and once its bold bit) on restored cells, rows kept below the source after a shrink, and the cursor one column short after a shrink. No I1 or I3 failure; the serializer is unchanged. Co-Authored-By: Claude <noreply@anthropic.com> * fix(opencode): bound the readiness deadline's last settle check With a grace pending, the deadline runs one more settle check, and over SSH its foreground read could hold a past-due wait for the channel's 30 s timeout. It now gives up after 2 s. Tests cover a hand-off, a failure and an abort during that check, a refused grace settled at the deadline, the bound, and the grace restarting at a hand-off. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: m4air <m4air@Mac.localdomain> Co-authored-by: Claude <noreply@anthropic.com> (cherry picked from commit 990b0ed)



ELI5
When a coordinator starts an OpenCode worker, Orca waits for OpenCode's input box, types the task in, and presses Enter. OpenCode 2 draws the input box a moment before it can accept a message. On a busy machine that gap can be over a second, and an Enter pressed inside it is ignored without any sign: the task sits in the box unsent, and the worker never runs or reports back. Orca now waits for the row OpenCode draws under the input box once it is actually ready, so the Enter lands even on a slow start.
What Changed
The problem (STA-9359).
orca orchestration worker-start --agent opencode.stage: input_accepted), and the worker showsready.dispatched, with no heartbeat and noworker_done, and the terminal is still alive.Reproduced on macOS with Orca 1.4.219 and OpenCode 2.0.21. OpenCode's screen showed the whole task sitting unsent in its input box as
[Pasted ~82 lines], and one manual Enter made the worker run and report straight away.Why it happened.
What is different for you.
An OpenCode or OpenCode 2 worker started by
worker-startin a fresh terminal gets its task only once OpenCode is ready to submit it, so the task is not left unsent on a slow start.Agent tabs launched with a prompt that Orca submits (quick launch, the checks "fix" launch, notes, source-control actions and the other launches that paste and press Enter) get the same fix, because they use the same readiness signal.
Drafts that Orca pastes without pressing Enter are unchanged. Typing into the input box doesn't need OpenCode's agent list.
On a normal machine, starts take about as long as before: the row usually follows the input box within about 100 ms.
If the input box appears but the row doesn't within 5 s, Orca goes ahead exactly as it does today. In every measured start the row came within 1.8 s, so this only applies where the row is never drawn. Examples:
Nothing becomes worse than today.
If the input box never appears, nothing changes:
worker-startfails with a timeout, as it already does (Wait for OpenCode worker input before the first dispatch #24601), and launched tabs keep their existing fallback.OpenCode 1.x is unchanged. It draws the row in the same frame as the input box, so the signal fires on the same read as before.
Not covered by this PR:
worker-start --terminalwith an existing pane: it keeps today's general "agent looks idle" wait, unchanged here.Mechanism.
draftPasteReadySignal: ready for typed text, unchanged;submitPasteReadySignal: ready to submit.opencodeandopencode2set the submit signal to a newopencode-agent-rowscanner (opencode-agent-row-scanner.ts). It is ready once OpenCode has drawn its agent/model row: the·between the agent and the model, on the line directly above the input box's bottom-left corner, inside OpenCode's full-screen view.·elsewhere on the screen doesn't count:opencodecommand;·in the row, that submitted after the grace;Why
opencode --prompt(yet). Letting OpenCode submit the task itself is the sturdiest cue, since OpenCode only auto-submits once it is fully ready. But it doesn't fit worker start without a redesign, so it is a follow-up:cmd.exe's command-line limit;--terminalworkers still need the paste path;Out of scope:
worker-start --on <host>(a worker on a paired Orca host): that path gets the new readiness wait once the host runs this version. The home side still doesn't observe a turn start for any agent, which is a separate follow-up.Known and out of scope: OpenCode subagents.
worker_done, Orca can refuse it as coming from another terminal ("This terminal is a Run coordinator…"). We reproduced this.Linked Issue
Fixes STA-9359 (Linear), for the failure reproduced there: the task reached OpenCode's input box, but its Enter was lost.
Related, not fixed by this PR: #22580 and #24913 (problem 1). Users there describe a different symptom: OpenCode's input box stays empty ("Ask anything…") and the task never appears.
Visual Proof
Isolated QA run on macOS (an app build of this branch with its own profile and home, hidden window, real OpenCode 2.0.21 on a free model).
An OpenCode worker started by
worker-start: the task was submitted and the worker reportedworker_done.An OpenCode tab launched by a quick command that submits its prompt:
Same flow on main, for comparison (at today's load main also submitted; the drop needs a busy machine, see the recorded drop transcript):
Testing
I manually tested these changes locally (isolated app build on macOS; see the QA comment)
Automated tests added/updated, or explained why not below
Transcript replay, for every recording:
·substituted into the footer path (all seven OpenCode 2 recordings) or a tab title (the two recordings that show tabs) doesn't fire it early; these tests fail if the position check is removed;Scanner tests: chunk boundaries; withdrawal when the full-screen view is left or bracketed paste is turned off; the grace timer isn't restarted by later output.
Renderer and main waiters: submit deliveries use the submit signal; drafts use the unchanged one.
Repo transcript secret scan: clean.
Typecheck:
tc:node,tc:webandtc:cli.Review
Author: @BrennanKB5
Agent skill upstream boundary
docs/reference/agent-skill-sharing-upstream-boundary.mdand copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.Notes
·reaching Orca's Windows terminal. Other agents' signals already rely on that switch there. If either didn't arrive, or if Windows' terminal layer redrew the row with cursor moves the scanner doesn't follow, the 5 s grace falls back to today's behaviour. That would cost each start up to 5 s but never paste early. Not verified on Windows: the one Windows QA machine reachable from this run has no OpenCode installed.worker-start --on <host>scans on the host, which needs this version.Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)