#31617 made terminal pane owner resolution read state.unifiedTabsByWorktree, but this test's mocked store never had the field, so shell contracts fail on main with "Cannot read properties of undefined (reading 'wt-1')".
* feat(worktree): open the native chat while its worktree is still being created
When native chat is the default, creating a worktree now shows the chat
pane straight away instead of a spinner panel. Its composer works while
git runs. A message sent before the worktree exists shows as the first
user message with a step card under it (prepare, fetch base branch,
create worktree with checkout %, start the agent), and the chat launch
sends it as its first message once the worktree is ready. Text left
unsent moves into the real chat's composer. Failures mark the step that
failed and keep Retry and Dismiss.
The renderer holds the message and hands it to the existing launch
prompt path, so hosts need no protocol change. The terminal route,
folder workspaces, SSH and VM recipes keep the old panel.
* fix(worktree): keep a held chat message when the host declines the chat
A background create whose host declines native chat opens the agent
terminal from the submit-time plan, which never saw a message sent
while the worktree was being created. That message now lands unsent in
the agent's input. The pending composer draft is also only deleted
once it has been copied into the new chat.
Git checks out with one sequential worker by default, so creating a worktree in a large repo spends most of its time writing files on one core. Every create-path command that writes the working tree (worktree add, the prepared-checkout and tip-refresh resets, and the sparse checkout) now passes -c checkout.workers=0, which gives one worker per core. On a 41,924-file clone on a 14-core Mac, git worktree add dropped from 3.8-8.3s to 2.4-3.0s. If checkout.workers is set at any scope, read with git config --get on the same host and repo as the checkout, Orca leaves it alone. Git before 2.32 does not know the key and ignores it.
* fix(chat): collapse settled permission notices
* Keep notice scroll addresses unique per rendered row
* test(native-chat): cover notice scroll bounds and shared classification
* fix(mobile): preserve notice summary long-press actions
* Preserve mobile notice selection and caret rendering
* Use type imports in mobile notice web tests
* Resolve real SVG test host from mobile dependencies
* fix(acp): separate recovered history from outside activity
* Fix repeated recovered history divider corrections
* Compose ACP replay targets before checked settlement
* Explain ACP scaling fixture timeout
* Complete ACP fixture types and runtime English catalog
* Type exported ACP fixture warning mock
* Restore ACP history without an extra notice
Agent Dashboard terminal previews had no xterm linkHandler, so OSC 8
hyperlinks fell back to xterm's confirm() + window.open() default, which
Electron blocks. Route OSC 8 links through the same Mod+click activation
as plain-text URLs (opening via shell.openUrl) and show the destination
as a native title on hover, since previews have no pane tooltip.
Co-authored-by: alpenshtokk <wawesandways@gmail.com>
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
The copied .deb install command now passes
-o Binary::file::APT::Sandbox::User=root to apt. The _apt sandbox user
can't read the package in the user's private ~/.cache, so apt already
fell back to root and printed an "unsandboxed as root" notice; presetting
that fallback for the file: method removes the notice without changing
effective privilege, and network methods stay sandboxed.
Fixes#35641
Co-authored-by: Neil <neil@stably.ai>
Five more runs stop only orcad in the guest, as its idle exit does, then
reconnect with the distro still up. startupGate.orcadCold reports them
against the warm bar, marked not gated, with orcad's startup medians.
Orchestration commands print small flat fields in text and --json by default; --full prints the previous output. Failures exit non-zero with error: <code>: <message> on stderr.
Adds Slatewave to the popular dark extended catalog. Slatewave is a calm slate-and-teal palette with an existing theme family across Alacritty, Kitty, Ghostty, WezTerm, iTerm2, VS Code, Neovim, and Obsidian (https://getslatewave.com).
The ANSI mappings mirror the upstream Slatewave palette exactly, so terminal output stays visually aligned with the editor themes in the same family.
* feat(plugins): show public install counts in the plugin catalog
* fix(plugins): tolerate the empty stats placeholder; count bundled official plugins
* test(plugins): pin install-stats test clock
Writes the stack height and composer clearance vars only on the card stack and
toaster wrapper, skipping unchanged values, so a composer resize no longer
restyles the whole document.
Fixes STA-13053
* fix(plugins): protect every security and destructive string from language packs
Language packs could rewrite trust copy outside a hand-kept list of app
areas (catalog-link dialog, browser-extension Allow/Deny, Node mirror).
Protected keys are now generated from structure: every key in a file that
renders a security surface, a destructive confirmation, or a native message
box, or that carries a // @protected-copy pragma, plus same-directory copy
modules. verify:localization-catalogs fails when the list is stale.
Pack strings are also capped at max(64, 4x English) characters and may not
contain control or bidi characters. Validation stays strict; loading drops
only the offending entries.
* chore(plugins): resync protected copy keys with main
* fix(plugins): cap pack strings in shared strict checks and pin new trust copy
* fix(plugins): keep the packaged CLI off the English catalog
* chore(plugins): resync protected copy keys with main
* chore(plugins): resync protected copy keys with main
When the native exit watch fails to register, the child never reports an
exit, so a later kill() could signal a pid Windows has since reused. Mark
such a child untracked: kill() refuses it and the warning says so. No exit
is faked; the WSL holder already releases through its own pid and
creation-time check.
* fix(plugins): accept plain repo, release and tag page URLs in Git install
The Git URL install dialog refused anything without a #ref suffix, so pasting a
repository or GitHub release link failed with "Add a #tag or #commit". It now
reads owner/repo, repository URLs with or without .git, SSH URLs and GitHub /
GitLab release, tag, tree and commit pages, pins the newest version tag (or the
default branch's commit when there is none) with git ls-remote, shows that
version and commit, and installs only that exact commit.
* fix(plugins): let the Git install dialog close while a version check runs
Top-layer content (showModal dialogs, popovers, fullscreen elements)
paints above the overlay's max z-index and a modal dialog makes it inert,
so hover and clicks reached the page instead of the picker. The outline
now lives in the top layer and is raised again when new top-layer content
opens; the overlay reads hover and blocks trusted presses at window
capture and hands real pointer picks to awaitClick.
Fixes#28657
Codex never echoes a prompt its UserPromptSubmit hook refused, so the
turn record kept Codex's own echo key as its opener. Live, the pending
send anchored the turn; once the chat closed or the host restarted, the
send settled to unknown and the reopened chat lost the turn's Worked for
line.
Record the turn a turn/start reply names when the reply is received, and
have the journal translator name that send as the turn's opener at
turn/started, or at turn end when the reply was read after turn/started.
Turning WSL hosts off within the 60 s delay still downloaded the archive.
Re-check the gate and the setting when the timer fires; a later turn-on
schedules again. Also correct the build-architecture comment: an x64
build emulated on Arm fetches the x64 archive, which goes unused.
* Chat UI leaves Experimental: each agent's Chat | CLI choice decides launches
Remove the experimentalNativeChat switch and every gate on it. The Chat
settings page, Default Agent Chat | CLI choice, + menu Chat/CLI rows,
source-control surface choice, Antigravity chat section and orchestration
chat-error switch are always present. What a new launch opens comes only
from the per-agent choice (no saved choice opens a chat) plus the existing
support checks.
- One lookup, nativeChatPreferenceFor, keyed by agent id so host-registered
agents read the same way; unreadable settings still open a terminal.
- A relayed desktop stamp (nativeChatDefault) maps onto the launched agent;
an explicit surface still wins. Old phones' createSupport keeps admitting
by the host's per-agent choice.
- settings.get stops publishing the retired switch keys; nothing in the
repo reads them from a host.
- Startup chat sync and hydration run when some agent can open as a chat
or the machine already holds chats.
- The retired key is stripped on load. The one-time upgrade tip from the
chat upgrade is retired with its audience record; a new record, captured
once from the raw profile, marks which existing profiles had Chat UI off.
- The window-side AI-button tab path, which only ran with the switch off,
is deleted.
* Keep profiles that had Chat UI off on the terminal
Existing users who never turned Chat UI on would otherwise see new agent
launches open as chats, since an agent without a saved choice now opens as
a chat. The one-time load step that records the new audience also sets
every known agent to CLI for those profiles, in the same save and only
when the record was absent, overwriting saved chat choices the old switch
masked. Profiles that had Chat UI on and new profiles are untouched.
Browser profiles keep their own settings, so the web client does the same
once: a stored switch that is not on seeds CLI choices, and dropping the
key marks the step done.
Agents first seen after this step open as chats.
* Agents without a saved Chat | CLI choice open as their CLI
An agent with no saved choice now opens in the terminal for everyone,
including fresh installs and agents first seen later. The one-time load
step carries what launches opened while Chat UI was experimental: with
the switch on, every known agent without a saved choice is saved as
chat; with it off, chat choices the switch masked are saved as CLI.
Existing profiles join the launch tip audience whether the switch was on
or off. Browser profiles get the same carry from their saved key.
The startup chat restore and host agent list now run only when some
agent is saved as chat or the runtime holds chats.
* Chat UI is here: a one-time tip for profiles that upgraded
Profiles saved before Chat UI left Experimental see a "Chat UI is here"
tip once, on the first launch after updating. Fresh installs, unreadable
audience records and the web client never see it.
- Had Chat UI off: says agents can now open as a chat and that the
terminal stays fully supported. "Use Chat UI" saves Chat for every
agent Orca knows (the roster the load step carries), then closes;
"Stay in terminal", close and Escape change nothing.
- Had Chat UI on: says Chat UI is now part of Orca and the terminal
stays supported; one "Got it" closes without changes.
- Both link to Settings -> Agents. The visual is an animated miniature
chat that sends a question, reads a file and draws a flow diagram,
then fades as one and repeats; reduced motion shows the finished
frame.
- The variant comes from main's once-decided audience record over a
new onboarding IPC read; the startup gate waits for it.
- FeatureTipActions takes a secondary label; the frame takes a copy
column class, used here so the buttons line up with the card's
composer. Other tips are unchanged.
- Telemetry: chat_ui_feature_tip_shown and chat_ui_feature_tip_action.
* Preserve owned terminal launches and local chat choices
* Chat UI tip: translate the miniature, honor reduced motion mid-loop
- The miniature's conversation (tab title, prompt, reply, diagram and
arrow labels) is translated in every locale; the composer, permission
chip, working row and Read verb reuse the chat's own strings. File
names, the /login route and the model name stay as written.
- The reply is one paragraph that wraps naturally; words (segmented per
locale, so scripts without spaces still stream) reveal in turn.
Diagram boxes size to their labels and arrow labels never widen the
row.
- Turning reduced motion on mid-loop jumps to the finished still with
no transitions.
- Telemetry records use_chat_ui only after the save succeeds and has a
distinct stay_in_terminal action.
- The dialog renders its own title, so the duplicate catalog copy is
gone; Use Chat UI writes the full roster without re-spreading saved
choices.
- Buttons: the primary's focus ring meets the card's bottom edge.
* Clarify chat and terminal support
* Explain worker CLI integration timeout budget
* Use checked annotations for chat graduation test fixtures
* Store agent surface default separately from per-agent overrides
* Preserve explicit Chat intent across default changes
* Preserve current browser settings during host replies
* Correct browser settings factory and regression types
* Name exported launch fixture mock types and clarify agent defaults
* Preserve settings fallbacks and complete launch test lifecycles
* Check allocated tab identity before launch fixture interpolation
* Drop file links from the Chat UI tip copy
* Register combined integration project for compiler parity probes
* Use checked settings in the launch test fixture
* Settings → Agents: "Open agents as" Chat or Terminal tiles
A new top section in Settings → Agents sets this computer's default for
how agents open: two tiles, Chat ("Rich messages, visuals and images.")
and Terminal ("Each agent's own CLI."), each with a still preview. The
chat preview reuses the tip's copy and flow diagram; the terminal preview
draws Claude Code's interface in the user's terminal theme and font.
- Picking a tile writes only agentDefaultSurface, through the same queue
as the per-agent Chat | CLI rows. The tiles show the saved default; an
agent set on its own row keeps its choice and is not reflected up top.
- If any agent's own choice differs from the new default, one toast names
them ("Claude and Codex stay in the terminal, as you set.") with "Set
all to Chat" / "Set all to Terminal", which drops those choices so they
follow the default. Only agents whose row offers Chat | CLI count. No
toast when nothing differs, and never from the tip.
- "Choose per agent" scrolls to and focuses the Installed list.
- Shown for this computer only (not on a paired host's page); the web
client gets it too. Searchable as "Open agents as".
- Copy in all locales; the tip's intro copy in other locales also drops
"file links", matching English.
* Fix Chat UI settings navigation and acknowledged preference actions
* Keep the agent default surface controls in full Settings
* Keep the per-agent navigation button free of link underlining
* Use checked types and existing presentation primitives for Chat UI tips
* Preserve retired Chat preference data privately
* Align chat E2E fixtures and capture pane lifecycle evidence
* Use typed raw settings in retention contracts
* Fix Chat UI settings search types and localization catalogs
* Consolidate transcript diagnostic imports
* Keep setup-only dependency changes out of the branch
* Update dev education history expectation for Chat UI tip
* test: align chat fixtures with live pane and native menu contracts
* test: capture relay tab selection loss diagnostics
* test: wait for owned shells before synthetic chat fixtures
* test: preserve all-host visibility in SSH observer
* test: bind synthetic transcript fixtures before provider seeding
* test: assert selected chat owner after narrow image preview
* ci: allow fifth compiler project to complete comparison
* Drop 'keeps getting better' from the Chat UI tip's terminal line
* Trim the empty space above the Chat UI tip's visual
* Tighten the space above the Chat UI tip's flow diagram; undo the card resize
* Tighten the Chat UI tip's reply and diagram spacing
* Give the tip's flow diagram a little more room and shorten its tab bar
* Type the web-terminal fixture's chat map without an assertion
* Right-click the selection itself in the chat copy spec
* Chat UI leaves Experimental: each agent's Chat | CLI choice decides launches
Remove the experimentalNativeChat switch and every gate on it. The Chat
settings page, Default Agent Chat | CLI choice, + menu Chat/CLI rows,
source-control surface choice, Antigravity chat section and orchestration
chat-error switch are always present. What a new launch opens comes only
from the per-agent choice (no saved choice opens a chat) plus the existing
support checks.
- One lookup, nativeChatPreferenceFor, keyed by agent id so host-registered
agents read the same way; unreadable settings still open a terminal.
- A relayed desktop stamp (nativeChatDefault) maps onto the launched agent;
an explicit surface still wins. Old phones' createSupport keeps admitting
by the host's per-agent choice.
- settings.get stops publishing the retired switch keys; nothing in the
repo reads them from a host.
- Startup chat sync and hydration run when some agent can open as a chat
or the machine already holds chats.
- The retired key is stripped on load. The one-time upgrade tip from the
chat upgrade is retired with its audience record; a new record, captured
once from the raw profile, marks which existing profiles had Chat UI off.
- The window-side AI-button tab path, which only ran with the switch off,
is deleted.
* Keep profiles that had Chat UI off on the terminal
Existing users who never turned Chat UI on would otherwise see new agent
launches open as chats, since an agent without a saved choice now opens as
a chat. The one-time load step that records the new audience also sets
every known agent to CLI for those profiles, in the same save and only
when the record was absent, overwriting saved chat choices the old switch
masked. Profiles that had Chat UI on and new profiles are untouched.
Browser profiles keep their own settings, so the web client does the same
once: a stored switch that is not on seeds CLI choices, and dropping the
key marks the step done.
Agents first seen after this step open as chats.
* Agents without a saved Chat | CLI choice open as their CLI
An agent with no saved choice now opens in the terminal for everyone,
including fresh installs and agents first seen later. The one-time load
step carries what launches opened while Chat UI was experimental: with
the switch on, every known agent without a saved choice is saved as
chat; with it off, chat choices the switch masked are saved as CLI.
Existing profiles join the launch tip audience whether the switch was on
or off. Browser profiles get the same carry from their saved key.
The startup chat restore and host agent list now run only when some
agent is saved as chat or the runtime holds chats.
* Preserve owned terminal launches and local chat choices
* Clarify chat and terminal support
* Explain worker CLI integration timeout budget
* Use checked annotations for chat graduation test fixtures
* Store agent surface default separately from per-agent overrides
* Preserve explicit Chat intent across default changes
* Preserve current browser settings during host replies
* Correct browser settings factory and regression types
* Name exported launch fixture mock types and clarify agent defaults
* Preserve settings fallbacks and complete launch test lifecycles
* Check allocated tab identity before launch fixture interpolation
* Register combined integration project for compiler parity probes
* Use checked settings in the launch test fixture
* Preserve retired Chat preference data privately
* Align chat E2E fixtures and capture pane lifecycle evidence
* Use typed raw settings in retention contracts
* Consolidate transcript diagnostic imports
* test: align chat fixtures with live pane and native menu contracts
* test: capture relay tab selection loss diagnostics
* test: wait for owned shells before synthetic chat fixtures
* test: preserve all-host visibility in SSH observer
* test: bind synthetic transcript fixtures before provider seeding
* test: assert selected chat owner after narrow image preview
* ci: allow fifth compiler project to complete comparison
* Type the web-terminal fixture's chat map without an assertion
* Right-click the selection itself in the chat copy spec
* fix(agent-status): settle a Claude pane when a prompt hook blocks the prompt
Claude fires no Stop after a UserPromptSubmit hook blocks the prompt, so the
pane stayed Working: 2 minutes until the OSC 7501 fallback, or until the next
turn when Claude's idle landed before Orca's own prompt hook. A prompt now
claims the program's working run, and a claimed run that goes idle without a
result or user input settles the turn the way a plain Stop would, in either
order. Input during the run (Escape, Ctrl+C) leaves the verdict to interrupt
inference, and relayed panes keep the relay's adjudication.
* fix(agent-status): keep a typed prompt from claiming an earlier rested run
Any input since the run began now withdraws its rest from the blocked-prompt
settle, so the keystrokes of the next prompt stop a stale idle run from being
claimed if that prompt's hook lands before its own working report.
A first WSL deploy downloads the pinned Linux Node archive (about 55 MB)
while the user waits, and fails on a network that blocks it. Once the WSL
hosts flag is open and the setting is on, fetch it in the background into
the cache the deploy reads, through the same materializer (mirror, proxy,
hash check). Once per run, deduped, never boots a distro; a failure is
logged and the deploy's download path is unchanged.
* A chat rename also renames the agent's own conversation
Renaming a native chat saved the name only in Orca, so the agent's own resume list (claude --resume, Codex's resume picker) kept showing its old title for the same conversation.
After a rename is saved, the host now gives the chat's current agent conversation the same name, the way the agent's own rename does: Claude through its host rename request (or its title line when no Claude is running), Codex through thread/name/set (live, or from a short-lived app-server under the chat's account), Pi through set_session_name while it runs. A new agent conversation in the same chat (first message, /clear, rewind) takes the name when it starts; resuming one never does, so a rename typed in the agent's own CLI is kept. Names Orca chose are never pushed. Failures are logged and never affect the rename.
* Preserve provider naming across rewind, close, and configured launches
* Use a fixed timestamp in session title fixture
* Format session rename regressions and simplify setup
* Resolve idle naming without conversation launch admission
* Assert configured PATH in idle naming regression
* Fix Codex session rename lint errors
* Correct provider rename regression fixtures
* Remove redundant rename traversal test after corpus validation
* Restore filesystem rename scaling contract
* Reuse Codex close delegate for disposal
* Join accepted provider naming work before runtime shutdown
* Correct the provider naming shutdown test fixture
* Preserve explicit conversation names across Claude startup
* Settle proven retiring writers before naming follow-up
* Preserve configured Codex rename invocation and align integration fixtures
* Fix construction and fixtures exposed by CI
* fix(chat): reconcile naming owner on late Claude exit
* fix(chat): align naming fixtures with async contracts
* test: separate Claude initialization results from native fixture exits
* test: type Claude naming fixture launch options
* test: await original journal close completion
* fix: persist Claude prompt names with session titles
* fix(agents): accept launch-time --model and --effort for grok
Grok's session option catalog already maps model and reasoning effort to
-m / --reasoning-effort, but it did not opt into worker launch
preferences, so orchestration worker-start rejected --model/--effort for
grok. Opt the catalog in and list Grok in the CLI help and docs.
Fixes#36199
* test(orchestration): use an agent without launch preferences in the federation rejection test
Editor tabs called the built-in getFileTypeIcon table directly, so an
enabled plugin file-icon theme changed the explorer but not the tabs.
Plain file tabs now render the shared theme-aware FileTypeIcon, and
PluginContributionIcon accepts a ReactElement fallback so the icon
component type stays stable across renders. Simulator tabs pick the
phone icon from their language instead of their label, so they keep it
under a theme.
Fixes#36326
Co-authored-by: Neil <neil@stably.ai>
One-shot POSIX text generators (chat naming, commit/branch/PR text)
passed a bare CLI name to the supervisor, whose PATH-only lookup missed
version-manager installs (e.g. nvm) that native chats already find when
the GUI process PATH omits them. Resolve bare commands with the existing
guest-aware installed-CLI resolver, searching relative and empty PATH
entries from the agent's launch cwd so project recipe CLIs keep
precedence, and share that PATH resolution with Codex structured launch.
Fixes#35942
Co-authored-by: Neil <neil@stably.ai>
Git rejects a ref component ending in .lock, so creating a worktree from an
issue whose title ends that way (e.g. "... mise.lock") failed with
"is not a valid branch name". computeValidatedBranchName now rewrites a
trailing .lock to -lock in the branch name only, so the worktree folder
keeps the requested name.
Fixes#36404
Co-authored-by: Neil <neil@stably.ai>
* fix(terminal): only the Windows console-limit failure keeps a dead terminal open
#16045 retained every non-zero local PTY exit and only used the Git Bash
console-capacity marker to pick the overlay's label, so an ordinary shell
exiting after a failed command left a dead pane behind on macOS and Linux too.
Claim the exit for the capacity overlay only when all of it holds: a native
local Windows ConPTY pane, a non-zero code, the same PTY whose fresh spawn was
observed, no user input on that PTY (an unsettled write counts), and the exact
MSYS marker in that PTY's own output. Every other exit falls through to the
unchanged teardown path.
Per-PTY interaction rides on the existing per-PTY process-exit record, marked at
the input-forward chokepoint so a late write acknowledgement can never label a
replacement PTY.
STA-5604
* test(terminal): pin the two unpinned arms of the Git Bash capacity gate
Gate-level ablation of the six-clause capacity condition found the six
conjuncts each individually pinned, but two neighbouring arms free:
- the `session.deps.onPaneProcessDied` presence check. The callback is
optional on PaneConnectionDeps; without the guard a capacity exit calls
`undefined` and throws out of the exit handler, leaving the pane neither
retained nor torn down.
- the per-PTY keying in `noteTerminalInputForPty`. A generation installs its
exit state when its callbacks are captured, before the transport rebinds
its PTY id; a write in that window would be credited to the incoming PTY
and silently suppress its capacity overlay.
Both new tests fail with their own arm reverted and pass with it restored.
No production change.
* Preserve startup input intent across terminal connection
* Keep terminal input attempts with their launch across remounts
* Load the real capacity-test transport during suite setup
* Match the paste-input test result type to its API
node-pty falls back to WinPTY below Windows build 18309. WinPTY never sends
ConPTY's DA1 announcement, so every plain terminal was classified as having no
input reader and the healthy shell was killed and respawned. On v1.4.244 that
discard killed the WinPTY agent twice, and winpty's native kill throws
'Pty seems to have been killed already', failing every plain terminal spawn.
Fixes#36317
The local agent Environment editor returned null when an agent had no
default env, override, or draft, so only goose showed it while empty and
users had no UI path to add a first variable. Always render it, dropping
the showEmpty/hasDefaultEnv plumbing.
Fixes#35997