Repository navigation
feat(sidebar): show setting up while a repo's setup script runs - #19
Merged
Merged
Conversation
A new workspace's setup script runs as a plain shell script in a terminal that main spawns, so the sidebar could see only a live PTY and rendered the workspace as plain green "Active" for the entire setup. The execution host now announces the runner over the existing host-to-client event stream, and the sidebar renders a pulsing amber "Setting up…" dot with its own #WorktreeStatus so it is distinct from the agent working spinner. Clearing is deliberately redundant, because a stuck dot is worse than a missing one: the completion marker (shell-agnostic, so cmd.exe is covered), OSC 133;D on the setup PTY (an interrupted runner returns to its prompt without ever printing the marker), the PTY exit reaper, and an hour-long watchdog for a shell that never runs the queued command at all. State is in-memory and replayed on subscribe, so a reload or a dropped event cannot strand it either.
nplez1
added a commit
that referenced
this pull request
Sep 22, 2026
A new workspace's setup script runs as a plain shell script in a terminal that main spawns, so the sidebar could see only a live PTY and rendered the workspace as plain green "Active" for the entire setup. The execution host now announces the runner over the existing host-to-client event stream, and the sidebar renders a pulsing amber "Setting up…" dot with its own #WorktreeStatus so it is distinct from the agent working spinner. Clearing is deliberately redundant, because a stuck dot is worse than a missing one: the completion marker (shell-agnostic, so cmd.exe is covered), OSC 133;D on the setup PTY (an interrupted runner returns to its prompt without ever printing the marker), the PTY exit reaper, and an hour-long watchdog for a shell that never runs the queued command at all. State is in-memory and replayed on subscribe, so a reload or a dropped event cannot strand it either.
6 of 9 tasks
nplez1
added a commit
that referenced
this pull request
Sep 25, 2026
A new workspace's setup script runs as a plain shell script in a terminal that main spawns, so the sidebar could see only a live PTY and rendered the workspace as plain green "Active" for the entire setup. The execution host now announces the runner over the existing host-to-client event stream, and the sidebar renders a pulsing amber "Setting up…" dot with its own #WorktreeStatus so it is distinct from the agent working spinner. Clearing is deliberately redundant, because a stuck dot is worse than a missing one: the completion marker (shell-agnostic, so cmd.exe is covered), OSC 133;D on the setup PTY (an interrupted runner returns to its prompt without ever printing the marker), the PTY exit reaper, and an hour-long watchdog for a shell that never runs the queued command at all. State is in-memory and replayed on subscribe, so a reload or a dropped event cannot strand it either.
nplez1
added a commit
that referenced
this pull request
Sep 27, 2026
A new workspace's setup script runs as a plain shell script in a terminal that main spawns, so the sidebar could see only a live PTY and rendered the workspace as plain green "Active" for the entire setup. The execution host now announces the runner over the existing host-to-client event stream, and the sidebar renders a pulsing amber "Setting up…" dot with its own #WorktreeStatus so it is distinct from the agent working spinner. Clearing is deliberately redundant, because a stuck dot is worse than a missing one: the completion marker (shell-agnostic, so cmd.exe is covered), OSC 133;D on the setup PTY (an interrupted runner returns to its prompt without ever printing the marker), the PTY exit reaper, and an hour-long watchdog for a shell that never runs the queued command at all. State is in-memory and replayed on subscribe, so a reload or a dropped event cannot strand it either.
nplez1
added a commit
that referenced
this pull request
Sep 29, 2026
A new workspace's setup script runs as a plain shell script in a terminal that main spawns, so the sidebar could see only a live PTY and rendered the workspace as plain green "Active" for the entire setup. The execution host now announces the runner over the existing host-to-client event stream, and the sidebar renders a pulsing amber "Setting up…" dot with its own #WorktreeStatus so it is distinct from the agent working spinner. Clearing is deliberately redundant, because a stuck dot is worse than a missing one: the completion marker (shell-agnostic, so cmd.exe is covered), OSC 133;D on the setup PTY (an interrupted runner returns to its prompt without ever printing the marker), the PTY exit reaper, and an hour-long watchdog for a shell that never runs the queued command at all. State is in-memory and replayed on subscribe, so a reload or a dropped event cannot strand it either.
nplez1
added a commit
that referenced
this pull request
Oct 1, 2026
A new workspace's setup script runs as a plain shell script in a terminal that main spawns, so the sidebar could see only a live PTY and rendered the workspace as plain green "Active" for the entire setup. The execution host now announces the runner over the existing host-to-client event stream, and the sidebar renders a pulsing amber "Setting up…" dot with its own #WorktreeStatus so it is distinct from the agent working spinner. Clearing is deliberately redundant, because a stuck dot is worse than a missing one: the completion marker (shell-agnostic, so cmd.exe is covered), OSC 133;D on the setup PTY (an interrupted runner returns to its prompt without ever printing the marker), the PTY exit reaper, and an hour-long watchdog for a shell that never runs the queued command at all. State is in-memory and replayed on subscribe, so a reload or a dropped event cannot strand it either.
nplez1
added a commit
that referenced
this pull request
Oct 6, 2026
A new workspace's setup script runs as a plain shell script in a terminal that main spawns, so the sidebar could see only a live PTY and rendered the workspace as plain green "Active" for the entire setup. The execution host now announces the runner over the existing host-to-client event stream, and the sidebar renders a pulsing amber "Setting up…" dot with its own #WorktreeStatus so it is distinct from the agent working spinner. Clearing is deliberately redundant, because a stuck dot is worse than a missing one: the completion marker (shell-agnostic, so cmd.exe is covered), OSC 133;D on the setup PTY (an interrupted runner returns to its prompt without ever printing the marker), the PTY exit reaper, and an hour-long watchdog for a shell that never runs the queued command at all. State is in-memory and replayed on subscribe, so a reload or a dropped event cannot strand it either.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ELI5
When you add a workspace, Orca runs that repo's setup script (install dependencies, copy config, whatever the repo needs) before you can really use it. That script is a plain shell script, not an AI agent, so Orca had nothing to read about it and showed the new workspace as ordinary green — the same as an idle terminal. This makes it show a pulsing amber "Setting up…" dot until the script actually finishes, and it is built so that dot can never get stuck.
What Changed
Before
activeis also what an idle shell shows, so there was no way to tell "still installing" from "ready".After
WorktreeStatusmember (setup), not a reusedworking: it renders a plain pulsing dot rather than the agent spinner, and its tooltip says Setting up… rather than Working, so it never claims an agent is doing something.QUIET_REVIEW_REPLACEABLE_STATUSESdeliberately does not include it), and the setup dot appears in both compact and detailed cards.The mechanism, since the renderer could not see this on its own:
setupReceipt/terminalHandle— there is no renderer-side way to identify the runner. So the execution host owns the fact, perdocs/reference/agent-status-store.md.RuntimeClientEvent) asworktreeSetupRunnerState { worktreeId, running }, not over a new channel, and the renderer keeps it in one small store slice (setupRunningWorktreeIds) that the status hooks read.buildObservedSetupCommand+ a token, so the wrapper prints a completion marker whatever shell the user runs.Clearing is deliberately redundant. A stuck "Setting up…" is worse than a missing one, so four independent host-observed signals clear it:
__ORCA_SETUP_COMPLETE__)set -eabort — andcmd.exe, which emits no OSC 133OSC 133;Don the setup PTYPlus two properties that are not signal-dependent: the state is in-memory only, so a main-process restart cannot carry it over; and it is replayed to every subscriber (
getSetupRunnerClientEventSnapshot), so a renderer reload or an event dropped during a transport blip converges on the host's current truth instead of stranding the dot. The host clears its own set on completion regardless of who is listening, so the replay is always correct even after a missedrunning: false.Why
spawnLocalStartupAndSetupTerminals), and the renderer holds no handle for it. A renderer-side heuristic would have to guess from the tab title, which is localizable text main also sets for other tabs.working.workingdrives the agent spinner and the Working tooltip, and it is what the agent sidebar keys off. Setup is not an agent, and the state deliberately does not appear as an agent row anywhere.agent-status-store.mdis about agent status; writing a synthetic row there would surface a fake agent in the sidebar and inworktree ps. The client-event stream is the existing host→client state channel (worktreeTerminalSleepStateis the closest precedent).OSC 133;Das well as the marker. Verified inlocal-pty-shell-ready-bash-rcfile.tsthat bash's133;Dis gated on__orca_in_command(set by the133;Cpreexec), so it fires only when a command genuinely returns to its prompt — it cannot fire spuriously at shell startup, and it does fire after Ctrl+C. PowerShell's bootstrap has the equivalentHasSeenPromptgate. A marker-only design would have been stuck on every interrupted setup.bg-workspace-status-progress(#d4a300) withanimate-pulseandmotion-reduce:animate-none— no new palette value, so the design-system gate stays clean and reduced-motion users get a static dot.Linked Issue
No tracking issue — this was requested directly.
Visual Proof
No attachments: the
$electronskill is not installed in this environment (the available skills arecomputer-use,find-skills,orca-cli, andorchestration), and I did not run the app, so I am describing the difference rather than showing it.pnpm install(or whatever the repo's setup script does) runs in the background Setup tab, the workspace's sidebar dot is solid green, identical to the same workspace once it is idle and ready. Tooltip: Active.StatusIndicator.test.tsrenders the production component forsetupand checks the amber token class,animate-pulse,motion-reduce:animate-none, the absence of the agent spinner, and the Setting up… tooltip.Testing
pnpm tc— full typecheck (main, preload, renderer, web, cli, e2e).pnpm run check:code-quality:changed— including the casting, type-aware, design-system, React Doctor, and casting-SAFETY gates: 0 findings across 29 changed files.pnpm run verify:rpc-params-catalog,verify:localization-extraction,verify:localization-coverage— clean (the new tooltip label is a plain string in the existingSTATUS_LABELSmap, alongside Active/Done, so there is no new i18n key).pnpm test(full suite): 86834 passed, 1 expected fail, 653 skipped, 14 failed. All 14 failures are pre-existing and unrelated —src/main/browser/browser-manager-viewport-ownership.test.ts(12),tests/e2e/e2e-worker-env-isolation.unit.test.ts(2), andtests/e2e/relay-region-correction.unit.test.ts(1). I confirmed they fail identically on the base commit3bb346380aby stashing this work and re-running exactly those three files (14 failed, 1 passed).pty-exit-per-pty-map-reaper-ratchettest caught a real omission during development — a new per-PTY map has to be reaped byonPtyExit— and now classifies the field against its reaper helper.New tests (13):
terminal-creation-and-readiness-part-06.spec.ts— announces on arm and clears on the completion marker; clears on an interrupted runner given133;D;130with no marker; clears on PTY exit and does not resurrect; clears on the watchdog (fake timers); does not announce for an already-dead handle; keeps the worktree setting up until every runner for it has ended.client-events.test.ts— the setting-up snapshot is replayed on subscribe.worktree-setup-runner.test.ts— the store slice sets, clears, is identity-stable on a repeat, and tracks worktrees independently.worktree-status.test.ts—setupoutranks interrupted/done/active, and loses to permission/working/monitoring.StatusIndicator.test.ts— the dot's classes and tooltip.use-worktree-activity-status.test.tsx— the store flag reaches the resolved status.worktrees-local-create-flow.test.ts— the desktop create wraps the runner and arms the observation.Not run:
pnpm build, and no manual app run. Manual steps a reviewer can follow: add a workspace whose repo has a setup script that sleeps for ~20s → the dot pulses amber and returns to green when it ends; Ctrl+C in the Setup tab mid-run → the dot clears immediately; close the Setup tab → the dot clears.AI Disclosure
Authored with an AI coding agent (pi,
deepseek-flash) under human direction. Every change was reviewed against the repo's gates, and the failure-mode behaviour was verified by tests rather than assumed.Review
Start with
src/main/runtime/orca-runtime-setup-runner-state.ts— it is the whole state machine, and the four clears are the part worth scrutinising. Thensrc/main/ipc/worktree-remote.ts(spawnLocalStartupAndSetupTerminals, where the runner is wrapped and armed) and the two renderer hops:runtime-client-ipc-bridge.tsintostore/slices/worktree-setup-runner.ts, andlib/worktree-status.tswheresetupRunningis placed in the precedence ladder.StatusIndicator.tsxis the pixels.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
resolveSetupRunnerCommandquoting), and no new IPC channel exposed to the renderer — it is one new member of an already-broadcast state event. The heartbeat is a worktree id and a boolean.cmd.execase (windows-shell-args.tsgives cmd no OSC 133) — so the wrapper is load-bearing there rather than decorative. Amber uses a theme-independent token. Not manually tested on Windows or Linux; the OS-specific branch (buildObservedSetupCommand's PowerShell path) is exercised by existing runtime setup tests.type— the renderer'sisRuntimeClientEventgate drops it, which is the safe degradation.RuntimeClientEventunion is delivered only to clients that already handle it; older clients ignore the type and show the previous green dot. No opcode, no handshake, no capability change.queueSetupAndIssueCommands, used when main fails to spawn setup) and thewait-for-setupsequenced variant stay green. Both are separate launch paths from the one this fixes, and arming either would need its own completion token.