mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 02:17:31 +00:00
2fb3a0975ede2dfdd215b2a4068a1bc71d0109c0
4405
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2fb3a0975e |
feat(plugins): workers can open files and run built-in actions (#37323)
* feat(plugins): add editor.open and commands.run for full-access workers Both ride the existing plugin view request channel (the one plugin open and plugin shot use) to the one main window's renderer; headless serve and a missing window answer unavailable. editor.open takes a path that stays inside the workspace (Git worktrees and folders) and opens it as a tab without switching what the person sees. commands.run takes only the built-in contributes.commands action list and dispatches Orca's own handler, never a plugin replacement. Both need workspace:write. workspace.list now also lists project-group folder workspaces. * fix(plugins): open folder workspaces and host-naming ids through Orca's window workspace.open of a project-group folder asks the window to show it (setActiveFolderWorkspace), since the runtime activates Git worktrees only. editor.open resolves the identity: ids workspace.list now returns. commands.run documents that it must call the raw built-in, never a replacement wrapper. * plugins: regenerate the testing bundle and skill guides on the rebased host actions Generated files only (lint-staged's oxlint refuses a commit with no lintable files). Co-Authored-By: Claude <noreply@anthropic.com> * chore(plugins): regenerate the testing bundle on main --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
544577fe02 |
feat(plugins): workers can list and open workspaces, create and read terminals, launch agents (#37312)
* feat(plugins): let full-access workers act on workspaces, terminals and agents Host API minor 3 adds worker-only rows: workspace.list (workspace:read), workspace.open (workspace:write), terminal.create (terminal:send), terminal.read (terminal:read, at most 2,000 lines) and agent.launch (agent:launch). Each dispatches the runtime RPC method the orca CLI calls, in process with the CLI's identity, so it runs on the host that owns the workspace (local, WSL or SSH) and covers folder workspaces. The new capabilities arrive in 1.4.248; typings, docs and skill references are generated from the table. * fix(plugins): make workspace host actions safe to revoke, cancel and target - Each runtime effect re-checks the plugin's approval right before the runtime acts (a dispatcher beforeInvoke hook, after its own waits), and a worker's cancel or exit now aborts the call's signal through to the runtime. - agent.launch starts the agent's CLI in a background terminal and returns its handle at once; a prompt is delivered afterwards through the runtime's own reuse-terminal path, so the host call never waits for the composer. - workspace.list adds project-group folder workspaces and returns ids that name their host (identity: keys), so twins on two hosts are never ambiguous. - terminal.create passes presentation background; terminal.read counts a runtime-limited read as truncated. workspace.open refuses folders as unavailable until a window-side open lands. * plugins: keep both API extensions and host-call tracking under the line limits after rebasing on the hooks Worker-only status bar and workspace methods spread into PLUGIN_HOST_API through one module, the in-flight host call map moves into PluginWorkerHostCalls, and bindPluginRuntime builds the runtime RPC so main-process-plugins.ts keeps its size; regenerated docs and typings. Co-Authored-By: Claude <noreply@anthropic.com> * chore(plugins): regenerate after rebasing on the editor recipe and shots * chore(plugins): regenerate after rebasing on the plugin shot recipe --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
06b8f7dc37 |
Keep Windows and Linux chat switching separate from worktree shortcuts (#37199)
* fix(shortcuts): give Windows and Linux chat switching a working default * test(shortcuts): verify the worktree and chat chords independently * fix(shortcuts): preserve agent newline keys while switching chat views * fix(shortcuts): use Ctrl+Shift+F11 for Windows and Linux chat switching The Ctrl+Alt+Shift+J default could not match non-Latin layouts or IME input, because Ctrl+Alt chords skip the physical-key fallback that protects AltGr characters. A function-key primary matches on every layout; Ctrl+Shift+J stays as the alias where Switch worktree doesn't claim it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(shortcuts): keep the chat toggle's own default alias when its shortcuts are edited Saving any change to Switch between Chat UI and terminal on Windows and Linux kept its untouched Ctrl+Shift+J alias, which the conflict check then refused against the worktree palette's default, so replacing or removing the primary failed. The check now exempts a chord per binding when it is the action's own default and every other owner also holds it as a default, so non-default explicit claims are still refused. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(shortcuts): expect the new Windows/Linux chat switch label The context menus show the toggle's primary binding, which is now Ctrl+Shift+F11 on Windows and Linux. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
9ce35be4ff |
fix(native-chat): effort, speed and fast controls stay usable while the model list refreshes; dotted versions in id-derived model labels (#36870)
* fix(native-chat): running chats keep effort menus during model discovery; dotted versions in id-derived model labels
* fix(native-chat): options stay usable while a model list refreshes; dated preview ids keep their dashes
A running host listing no longer disables effort, speed or fast mode. Those
controls follow the data they draw from: before any list exists they show
the placeholder or a read-only saved effort, and once a list or the chat's
own answer is shown they stay usable through every refresh, for every agent.
The listing flag is now only the host's raw fact, which keeps a seed from
settling to the built-in list while discovery runs.
Id-derived labels no longer dot a zero-led part, so MM-DD preview dates
(gemini-2.5-flash-preview-05-20) stay dates.
* fix(native-chat): a model list refresh keeps the verified models and default effort already shown
While the host refreshes a Claude or Codex list, the chat keeps the model
ids an earlier finished listing verified that the refreshing rows still
contain, so a running Codex chat's CLI-default effort ("Medium") no longer
blanks from the pill and menu until the listing lands. Ids no finished
listing verified stay unverified, and a finished listing still replaces
the set.
* test(native-chat): type the listing-wait check without an assertion
* fix(model-labels): month-day dates after October stay undotted
* refactor(native-chat): listing-verified model ids get their own module
|
||
|
|
0bf96e0d7a |
Show a GitLab MR's pipeline result even when it has no jobs (#37177)
* Show failed pipelines and check suites without jobs * Use the parent pipeline as the GitLab checks verdict The MR's own pipeline status now leads the Source Control Checks panel, the MR dialog and the phone checks badge whenever the details reply carries it, even when the returned jobs are empty, partial or all passing. Job rows and counts stay a separate breakdown. The parent follows pipeline-level policy (required manual is pending, canceled and skipped are not failures, mergeable manual is neutral) from one shared rule, and it is a provider link rather than an expandable job, so it never shows a details error with Retry. A failed parent leads the triage strip and joins the Fix prompt by name and link. Drops the GitHub zero-run failed check-suite rows from this change; existing approval-required suite rows are unchanged. * Name the GitLab pipeline outcome and keep its verdict in one rule The host now settles the parent pipeline's verdict with the same rule and reply that produce the MR status, so a manual pipeline on older GitLab reads pending everywhere. The phone checks badge names the pipeline outcome (Pipeline passed/failed/pending) instead of an unlabeled one-item count; job wording without a parent is unchanged. The desktop parent row's status is localized, and a failed MR-details read still shows its error beside a kept parent with no jobs. * Keep Fix for failed GitLab jobs and treat waiting_for_callback as pending The triage strip shows again when a returned job failed under a passing parent pipeline, so its Fix stays available; a failed parent still leads. A waiting_for_callback pipeline now reads pending instead of neutral, in the MR status and the parent pipeline alike. * Mark the checks-panel action test fixture cast as safe * Pause the pipeline row spinner offscreen and under reduced motion |
||
|
|
f908d2f40a |
feat(plugins): plugin shot --editor to screenshot and drive custom editors (#37302)
* plugins: orca plugin shot --editor, and plugin open --editor opens the file's folder plugin open --editor now opens the file in the workspace that holds it, matching its real path too (/tmp vs /private/tmp), and otherwise adds the file's folder as a folder workspace instead of failing with no_workspace. plugin shot <dir|key> --editor <file> [--theme] [--width --height] [--act] loads the editor afresh in a hidden tab, waits for it to get its document and ask for it (a new editor.subscribed frame event), captures the editor's guest with the panel shot's capture path, and sends --act clicks, drags and keys as real input via sendInputEvent. It exits 1 with the frame's errors when the editor throws, is blocked by its content policy, or never asks for its document within 5s; theme and size are put back. New RPC method plugins.shotEditor so older hosts fail cleanly. * plugins: shot --editor never changes the author's file With --act the shot copies the file into a temporary folder, shoots the copy in a temporary folder workspace, then closes its tab and removes the workspace and folder; --in-place acts on the file itself. Without --act it opens the real file, leaves its buffer alone and closes the tab if the shot opened it. Afterwards Orca shows the workspace it showed before. Regenerates the skill's CLI reference. * plugins: fix editor shot typecheck (refusal next step, RPC test mock) * plugins: editor shot targets its own guest, flushes before reload, scopes cleanup per capture - Main captures the exact guest WebContents the shot's tab mounted, not the first with its URL. - An open editor's pending edits are flushed before the shot reloads it; the shot fails if not. - --act --in-place keeps the acted tab and its unsaved edits. - end-capture undoes only its own capture (per-capture id), so overlapping shots don't clash. - The file's workspace lookup includes local folder workspaces. * plugins: shot --status-bar/--window, key acts focus the editor guest, panel shot selects a workspace - Editor --act keys first give the guest's <webview> DOM focus and refocus its target, so a canvas that keeps focus no longer drops later keys; never webContents.focus(), which focuses the window. - orca plugin shot <dir|key> --status-bar | --window [--theme]: captures Orca's status bar or the whole hidden window (plugins.shotChrome) with the existing capture helpers. - With no workspace showing, a panel shot selects this machine's most recent workspace in the hidden window instead of failing. * plugins: a shot's end restores only its own capture overrides * plugins: regenerate the testing runtime with the editor subscribed signal * plugins: editor capture refusals go through one CLI-message helper * fix(plugins): give the chrome shot refusal a next step |
||
|
|
9b39188021 | refactor: organize session option and conversation owners (#37289) | ||
|
|
591f2acbc8 |
docs(plugins): add a rich-editor recipe and list frame theme variables in the skill (#37306)
recipes.md gains "A rich editor with a library" beside the hooks and status bar recipes: an isolated-frame custom editor that vendors its library behind an import map, syncs through orca.document.session with a merge by id, and tests that sync with mockEditorHost. host-api.md lists every --orca-* frame variable and what it paints, generated from the frame token allowlist. |
||
|
|
fa7c3f95fe |
feat(plugins): check custom editors and test them with mockEditorHost (#37293)
* feat(plugins): check custom editors statically and add mockEditorHost orca plugin check now follows each custom editor entry (local script src, inline module scripts, relative imports), transpiled and resolved as the frame loader does, and fails at file:line:column on syntax errors, missing files, refused imports, string eval/Function and files over their size cap, with no running Orca. The check ships in the test hooks bundle. orca/testing gains mockEditorHost: it runs the frame shell's real window.orca (document API and session) over an in-memory text or bytes file, with edits, replace, conflictNext, flush, setTheme and dispose. Typings, docs and the skill guide cover both. * feat(plugins): warn on editor eval and check editors in dev watch editor_eval comes from a lexical scan that can misread rare code, so it is now a warning that does not fail orca plugin check. dev watch --check runs the editor check beside the panel check and reports it under editors. * fix(plugins): check editors by the frame protocol's rules; mock blocks lost saves The static editor check now reads files through the loader's contained reader (symlinks out of the plugin are refused), runs only JavaScript script types, honors the page's import map for native modules, classifies files by the protocol's content types (JSON imports, extensionless HTML entries), decodes escaped script URLs, and uses the protocol's caps: 10 MiB entry, 1 MiB transpiled module, 16 MiB checked dependency. mockEditorHost refuses an oversized edit before reading it and then rejects flush() until a later edit lands, as Orca blocks the save. * test(plugins): type mockEditorHost's frame API instead of reflecting on it * fix(plugins): keep main's case-spelling check and hook typings through the rebase The rebase onto main resolved plugin-artifact-validation.ts and orca-testing.d.ts to B4's side; this puts back main's exact-path-spelling check and hooks typings beside B4's contained reader and mockEditorHost types, and regenerates the testing bundle. |
||
|
|
7989c05ad3 |
feat(plugins): agent tool-call hooks (Claude Code can block or rewrite) (#37303)
* plugins: agent.tool.before and agent.tool.after hooks; Claude Code PreToolUse blocks
The hook server runs plugins' tool hooks after recording status. Claude Code's
POSIX hook script now asks for an answer on PreToolUse (X-Orca-Hook-Decision),
waits at most 8 s (Orca answers within 6 s) and prints the decision: a deny
with the plugin's reason, or updatedInput without approving it. Timeouts,
errors and an unreachable Orca print {}, so the call proceeds. Other events
still print {} before posting. Every other agent, Windows scripts and SSH/WSL
relays only observe or are not hooked yet (per-agent table in the
agent-hooks README).
Co-Authored-By: Claude <noreply@anthropic.com>
* plugins: verify PreToolUse answers against the real Claude CLI; 204 at once when no tool hook listens
A real-CLI test (ORCA_REAL_CLAUDE_CLI_TEST=1) shows Claude Code 2.1.316 runs
updatedInput sent without permissionDecision, still asks for approval of the
rewritten call, and refuses a deny. With no plugin listing a tool hook, the
server answers 204 before any await and runs no chain.
Co-Authored-By: Claude <noreply@anthropic.com>
* test(claude): type the real-CLI PreToolUse answer
* plugins: harden agent tool hooks (partial replies, fenced posts, OpenClaude, Amp/Copilot/Cursor)
- Drop a failed curl's partial body and print only a complete PreToolUse decision.
- Run tool plugins only for posts status ingestion accepted; name the owner's terminal.
- Enable PreToolUse decision mode only for Claude Code, not CLIs reusing its script.
- Decode Amp tool.call/tool.result, Copilot envelope/implied events and Cursor shell/MCP calls.
Co-Authored-By: Claude <noreply@anthropic.com>
* plugins: regenerate the testing bundle on the rebased tool hooks
Generated file only (lint-staged's oxlint refuses a commit with no lintable files).
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
|
||
|
|
60d262ebee |
feat(plugins): hooks for agent launches and prompts, plus plugin dev hook (#37295)
* plugins: agent.launch.before and agent.prompt.before hooks; orca plugin dev hook agent.launch.before runs at the PTY spawn every agent terminal goes through (window tabs, runtime/CLI agent launch, automations, orchestration), before dispatch to its host: change the command line, add env (Orca's own ORCA_* variables and the agent's environment stay hidden), or deny. Restores and resumes are not hooked. agent.prompt.before runs in sendTerminalAgentPrompt (launch prompts, orchestration dispatch, terminal send to an agent) with the agent named: rewrite or deny. The terminal hooks move into one runtime layer. orca plugin dev hook runs a hook through one dev plugin and prints the decision. Co-Authored-By: Claude <noreply@anthropic.com> * plugins: recheck rewritten launch commands, forward hook env to WSL, keep prompt delivery outside the hook order - A command agent.launch.before rewrote passes the AI Vault resume check again on both spawn paths. - Variables a hook adds are named in WSLENV on Windows so WSL agents get them. - agent.prompt.before holds the terminal's order only while it decides; a delivery waiting on a permission answer no longer blocks later input. Co-Authored-By: Claude <noreply@anthropic.com> * plugins: plugin dev hook honours onError: deny Co-Authored-By: Claude <noreply@anthropic.com> * plugins: regenerate the testing bundle and skill guides on the rebased hooks Generated files only (lint-staged's oxlint refuses a commit with no lintable files). Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
ac8c1125f0 |
feat(plugins): hooks that can change or block terminal sends and workspace creation (#37287)
* plugins: contributes.hooks runtime with terminal.send and workspace.create hooks
Workers register orca.hooks.on(hook, (event, next) => ...). Orca runs listed
plugins in order before it acts: next(event) continues with allowed fields
changed, { deny } stops, nothing passes. A plugin past its 2 s deadline, or
one that throws, crashes or is disabled, counts as passing and is logged with
plugin, hook and duration. First hooks: terminal.send (runtime sendTerminal),
workspace.create.before (IPC and runtime creates, folders included) and
observe-only workspace.create.after. orca/testing mountWorker gains
hooks.fire. Needs main + trusted-worker and engines.orca >=1.4.248.
Co-Authored-By: Claude <noreply@anthropic.com>
* plugins: keep hook plugins' workers started; bound start-up separately from the hook deadline
Workers of enabled plugins that list hooks start as soon as they are approved
and are never idle-reaped; crash restarts follow the manager's policy. A hook
waits up to the worker ready timeout for start-up, then gives the handler its
full 2 s, so a cold worker no longer lets the first hooked action through.
Co-Authored-By: Claude <noreply@anthropic.com>
* plugins: give hook workers their own soft cap instead of the active-worker cap
Always-running hook workers no longer hold slots of the shared 5-worker cap, so
many hook plugins cannot starve the rest. They have a soft cap of 16; past it a
hook worker waits for another to stop, logged once.
Co-Authored-By: Claude <noreply@anthropic.com>
* test(plugins): type the hook warmer's ensureWorker mock
* plugins: address hook review: ordering, human input, overflow, revalidation, folder creates
- Hook workers past the soft cap start as overflow (logged once) instead of
waiting, so reconciliation, disable and uninstall never hang.
- Writes to one terminal stay in order while terminal.send decides, so a later
Enter cannot submit the previous line.
- terminal.send runs only for programmatic sends (main, plugins, the CLI);
desktop, mobile and legacy client input is a person's typing.
- Text a hook rewrote passes the AI Vault resume check again.
- Project-group folder workspace creates (RPC, agent launch, window) run the
workspace.create hooks through one boundary.
- A decision from a plugin disabled or changed while it ran is discarded.
Co-Authored-By: Claude <noreply@anthropic.com>
* test(plugins): drive hook start-up timing with fake-timer deferreds, no real sleeps
Co-Authored-By: Claude <noreply@anthropic.com>
* plugins: only the hook decision holds a terminal's write order
A delivery that waits (a permission prompt, the launch composer) no longer
blocks later writes, and a person's input, interrupts and query replies never
wait behind a pending decision.
Co-Authored-By: Claude <noreply@anthropic.com>
* plugins: hook DX: onError deny, denied_by_plugin, a Hooks reference, --template hook
- contributes.hooks[].onError: "deny" makes a throw, timeout, crash or bad
answer refuse the action, naming the plugin; the default still passes.
orca/testing mountWorker honours it, and mockHost answers fire-and-forget
methods (result { ok: true }) with success by default.
- A plugin denial reaches RPC clients as denied_by_plugin with the plugin and
reason, and the CLI no longer suggests a retry for it.
- The skill's host-api reference gains a generated Hooks section (event, what
next may change, stop result); the recipe passes sends through unchanged and
warns against awaiting other calls before deciding.
- orca plugin create --template hook: a worker-only terminal.send guard that
fails closed, with a test.
Co-Authored-By: Claude <noreply@anthropic.com>
* plugins: regenerate hook docs on main; bind the plugin runtime and its hook runner in one call
Keeps main-process-plugins.ts under 300 lines now that status bar items landed.
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
|
||
|
|
764bd0be44 |
Continue Fix checks and project actions through setup confirmation (#36539)
* Resume direct work item launches after setup confirmation * Preserve setup review and settle cancelled work item preparation * Fix setup test types and synchronize localization artifacts * Keep accepted setup launches owned through completion * fix: declare accepted create dialog result * fix: report direct launch preparation failures * Reuse workspace setup preparation and section * Use compact dialog description for setup help * Construct omitted setup decision fixture through serialization * Match optional signal in background setup trust test |
||
|
|
98d22faa8d |
test: remove 96 low-value test cases (#37296)
* test: remove 96 low-value test declarations * test: update timeout baseline after audit903 --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
a9b1041ecc |
feat(plugins): status bar items plugins can update live (#37291)
* plugins: contributes.statusBarItems with worker updates (statusBar.update)
A plugin declares status bar items { id, text?, icon?, tone?, tooltip?,
command? } (declarative profile, engines >=1.4.247); pressing one runs
its own command. A trusted worker changes them with the new worker-only
host method statusBar.update; main keeps the session's changes and
pushes snapshots to desktop windows over plugins:statusBarChanged.
Regenerates schemas, references, typings and the authoring skill.
* plugins: statusBarItems ship in 1.4.248, beside contributes.hooks
* plugins: clear a plugin's status bar changes when it is disabled, removed or updated
* plugins: list status bar items in the plugin page's Adds section
* plugins: count statusBarItems' since in the host's newest readable version
* i18n: add the plugin page's status bar row label to en.json
* plugins: status bar items respect workspace commands, dev reloads and catalog summaries
- An item whose command needs a workspace is disabled with no open workspace.
- A dev code edit (new devRevision) drops the old worker's status bar changes.
- Catalog summaries list status bar items, and marketplace details show them.
* plugins: authoring skill lists status bar items as buildable; approval lists them
The skill no longer calls status bar items reserved and gains a row for them. The
dev-load/inspect approval already lists them via the contribution summary; a test pins
that and the fingerprint binding.
* chore(plugins): regenerate the testing bundle after rebasing on main
|
||
|
|
4a0ee07bd2 |
feat(plugins): orca.document.session() for custom editors (#37285)
* feat(plugins): add orca.document.session() for custom editors One call replaces the document sync every editor rebuilds: decode/encode (plain text by default), optional merge, debounce. One edit in flight with later changes coalesced; the baseline moves only on accept; a refused edit keeps the draft and rejects flush(); own accepted edits never reach onReplace; a conflict merges once against the last accepted value and resubmits, or keeps the draft without merge. The session answers editor.flush itself and resolves after hello and the first document. The --template editor now uses it. Docs and typings state the session and the undo model (the editor owns undo). * fix(plugins): let the outside document win a session conflict without merge Agents write files while people edit them, so keeping the draft lost the agent's write on the next keystroke. Without merge the session now drops the draft, fires onReplace with the outside value and rejects flush() with conflict; editors that want both sides pass merge. * fix(plugins): serialize session edits through saves and settle before answering - One edit in flight at all times, saves included; editor.flush is answered only once every change is accepted or refused with nothing newer to send. - The editor host commits a held edit when a save starts and admits edits during the save at once, so waiting fits the 1 s deadline. - A change generation replaces identity checks, and sent bytes are snapshotted, so a reused buffer is never mistaken for an accepted edit. - A waiting flush keeps its conflict rejection when the outside document wins, and nothing merges or sends after dispose. * test(plugins): read session test edits through typed helpers * fix(plugins): drain session flushes, reject dropped drafts, snapshot the baseline - flush() keeps going until no change made during it is left unsent. - A waiting flush rejects with conflict whenever the outside document replaced a draft, newer ones included. - The accepted baseline is decoded from the sent snapshot, so a reused value buffer cannot change merge's base. * test(plugins): name the session test option and message types |
||
|
|
51f302167e |
feat(plugins): let a custom editor require the desktop app's isolated frame (#37298)
* feat(plugins): let a custom editor require isolated frames customEditors[].frame: "isolated" | "any" (default any, since 1.4.248). An isolated-only editor never runs in the srcdoc fallback: main serves its fallback shell without the entry, and when this window has no isolated guest (browser clients, or desktop with isolated frames off) the file opens in Source with "This editor needs the Orca desktop app". Picking the editor shows the same notice with an Open Source button. * i18n: add the needs-desktop editor notice strings * plugins: refresh frame isolation when its setting changes; browser clients open Source - The learned isolated-frames answer is tied to the setting it was learned under, so turning isolated frames back on lets isolated-only editors open by default again. - A browser client's plugin bridge has no list, so the plugin store settles on no plugins instead of erroring and retrying; files open in Source. |
||
|
|
8cbd822e4c |
Keep readable conversations out of Session History warnings (#37211)
* Keep recovered conversations out of history warnings * Name the agent when a History conversation is too large to load A conversation whose only records exceed the transcript record limit now reports its own coded reason naming the agent and suggesting resuming it in that agent, instead of the generic session-metadata message. Adds a rendered banner test and a non-user Codex case. * Build History banner test values without type assertions * Name the conversation's writer in the too-large History reason Labels the reason with the parsed agent so an OMP transcript found under Pi's folder names OMP, ships the new key in the English runtime catalog, and renders the reason in the phone's History panel test. * Cover the phone History notice for readable results and Spanish Test-only: a ready result without issues shows no skipped notice, and the too-large case keeps its English reason after switching the phone to Spanish while the count is translated. |
||
|
|
8e326f2629 |
Keep GitHub task assignees and rows current after dialog edits (#34245)
* fix(tasks): publish confirmed dialog assignee changes to the list Record successful per-login changes in the existing assignee snapshot and patch the Tasks cache. Qualify snapshot writers, composition and quiet release by canonical repository so fork and host twins stay isolated. Co-authored-by: Max Hsu <maxmilian@gmail.com> * test(tasks): bound confirmed assignee publication work * Add explicit task refresh through registered details * Refresh registered tasks with finite request ownership * Preserve addressed task display and ordinary edit boundaries * Derive task membership from owned rows and batch cache updates * Preserve task list intent across account changes and query resets * Preserve GitHub task content through final delivery * Preserve accepted task content across cold query changes * Batch finite task delivery publications and index ordered list folds * Capture immutable Tasks publication inputs and translate Refresh feedback * Preserve live scalar settlement beside captured publication inputs * test: make task refresh contracts deterministic for static checks * test: derive lifetime token annotations from production origins * test: initialize current repo catalog defaults for refresh fixtures * Fix refresh import dependencies for static checks * Fix GitHub task refresh adapters and verification inputs * Exercise omitted mutation observation in overlap contract * fix(tasks): refresh live list bases and align delivery contracts * test(tasks): retain actual pagination setter inputs * fix(tasks): express page array mutability with checked overloads * fix(tasks): preserve complete models through refresh stages * fix(tasks): align origin and query row input contracts * test: declare portable task refresh mock contracts * test: allow zero-argument task refresh mutation calls * Keep GitHub task copies fresh after edits and refresh * Keep task rows visible and simplify the shared task record Rows are never filtered for a stale connection or account binding; only a current record for the row's own repo overlays its facts, derived at read from repoId/repoHostId. Records cover issues only, conflicts compare only state, title, label names and assignee logins, and truncated Project lists never count as conflicts. Project tables stay raw in the store and are projected where they are read. Ordinary local dialog opens keep cached, lenient reads; only Refresh asks for the fresh, strict read. Refresh waits on the record's own pending edits instead of a second write registry, reports a failed user Refresh once through the existing toast, and explains in its tooltip when the server needs an update. Background verification never shows a failure. A successful dialog assign keeps the selection until a newer reading lands, main's soft-hide for Tasks-row edits is unchanged, and pins/eviction are gone because only user edits and Refreshes create records. * Let saved descriptions win over Refresh and roll back disposed edits Refresh is now the only fresh, strict read: it writes the same details entry ordinary loads use, and later reopens and post-edit refetches go back to the cached, lenient path. An issue's saved description supersedes any read already in flight, so Refresh rereads after the save instead of restoring the older body. A failed Refresh with nothing loaded yet leaves only the body's existing load error. A record disposed while its edit is in flight still settles the copies its edit patched, so a failed edit rolls back in Tasks and the dialog as before. A record whose own connection fence went stale is dropped when next looked up. Rows without a record pass through acceptSearch unchanged. * Settle disposed edits through their owner and connect Project edits A late edit whose record was disposed mid-flight now finishes through the same base/pending reducer: copies receive only that operation's own change (one label or login added or removed, a state set), a replacement record reconciles with its own item read, and settle never returns null so dialog and Tasks rollback always run. Untracked edits publish the same semantic change at begin and undo it on failure. Dialog callers stop re-patching Tasks rows; an unsupported server's live record keeps new edits joined until its last one settles. Refresh clicked during the first details load waits for that load, then runs the strict read; a failed click always shows its one toast and never installs an inline load error. Project-row issue edits now publish to Tasks copies with no prior record, seeded from a complete Tasks row for the matched repo binding, or established by an item read after the edit lands. * Give a task record its base only from an accepted provider reading Starting an edit or a Refresh no longer turns the caller's cached row into the record's full value. Until an owned canonical read is accepted, a record holds only its pending changes and the coalesced successful ones, and every copy (Tasks rows, pickers, the board) shows its own facts plus only those changes. A successful edit applies just its change to the stored copies and keeps it until one coalesced read through the existing read lane establishes the base; a failed edit with nothing else owed retires the owner, and a failed first Refresh leaves nothing behind. Search deliveries and board fetches wake a read still owed. Edits are now semantic change values (set title or state, add or remove a named label or login) instead of closures, so they coalesce and apply to any copy. Project edits keep their producer but no longer seed from a cached row, and the separate establishing read is gone. A Project save with no title, label or assignee change (a body-only save) skips the record entirely. * Keep pending task edits out of stored copies and re-admit queued reads Accepted records now follow the rule records without a reading already followed: stored Tasks copies hold only accepted readings and confirmed changes, and pending changes reach users only through read-time projection. A search during a pending edit stores the accepted facts, never the edit; a failed or disposed edit just drops its token instead of computing an undo over current copies, so a newer reading can't be overwritten by an old edit's rollback. The cross-copy undo helper is removed. Without a tracked owner (no binding, or a server without the item route), other copies change only when an edit succeeds, and a board edit on a server known to lack the item route stays board-only. Dialog state and label edits roll back to what the dialog showed. A canonical read queued behind another one re-enters admission after each wait, so a Refresh clicked after a discarded one still reads, and a read whose binding or server support went away meanwhile ends without leaving an owner. * Store only readings, keep task data across reconnects, park failed reads Stored Tasks copies (the fresh-cache fetch return, details settle) hold only accepted readings and confirmed edits; Cmd-J applies its open-only filter to what it shows, pending edits included. Records, details entries and optimistic comments are keyed by account binding and issue; a connection change re-captures the binding and fences each read and send without deleting what the dialog shows. A server's missing route marks only the connection that answered. An unusable canonical read keeps what is known and waits for the next provider delivery, which retries one owed read per binding, the longest-waiting first. The dialog's label chips follow the displayed item, and the duplicate target fence and write-only details generation are removed. * Park only reads that were owed, so a failed Refresh never delays a later one A failed Refresh on a record with nothing owed no longer marks it as a parked retry; a later obligation on that issue reads on the next delivery instead of waiting behind every parked record. The refresh hook stops returning its unused target. * Keep the ordinary-open details case after main removed its suite Ports the one case that pins an ordinary open with an issue repository to the cached, lenient read (a failed timeline read still returns details) into the main details suite. * Keep pull-request lookups off the task records and repair CI tests Pull requests never have a task record, so their lookups no longer load the store or report a search reading; terminal PR-link confirmation reads as on main. Tests follow the explicit canonical details flag, the current dialog edit signature (records hold a dialog close over a lagging search), confirmed-only untracked publication, and a fixed board timestamp. * Keep main's close hold where no task record can own it, and split the record cache A dialog close or reopen that no task record can own (no binding, or a server without the item route) keeps main's confirmed-state hold, so a lagging search cannot show the issue open again; a record that takes over retires it. Tracked edits still go through the record only. The record cache moves, unchanged, into model, owners and reads layers under the Project-facing cache, so no module needs a max-lines exception. * Hold an untracked dialog close only after it is confirmed A dialog close or reopen no record can own changes no stored copy while the request runs, so a refresh during a failed request leaves every copy as it was and nothing needs undoing. At success the edit is admitted again: a record that can now own it (after a reconnect or upgrade) settles it, otherwise main's confirmed-state hold is asserted and the change is published once. * Name the task binding incarnation token type The binding incarnation, compared by reference, gets its own named type instead of the broad object type; no behavior change. * Import Cmd-J task search results from one statement * Type changed code without assertions and keep the assignee callback stable Tests build typed fixtures and hoisted mocks instead of casting; the landing refresh takes only the model parts it reads. Lookups and the comments parse annotate their values instead of asserting them. The edit section's empty assignee list is one shared value, so its toggle callback keeps its identity. * Stamp the opened row onto main's details item before it reaches typed record reads * Pin the parked-read and board-read budgets at 10 and 100 records * Size the dialog's Refresh task button like Copy link and Open on GitHub --------- Co-authored-by: Max Hsu <maxmilian@gmail.com> |
||
|
|
5e33efa36a |
fix(plugins): keep custom editor documents in step with accepted edits (#37277)
* fix(plugins): keep custom editor document in step with accepted edits - orca.document.get() returns the content of an accepted applyEdit at the same version, without firing onDidChange; a newer document wins. - onDidChange skips its replay for a subscription disposed before it runs. - The --template editor keeps unaccepted typing when the file changes outside, and shows a refused edit in the frame instead of only logging. - Extract the srcdoc shell mount into a shared test fixture. * fix(plugins): acknowledge custom editor edits only once committed - The host answers a superseded held edit with the answer of the edit that replaced it, and keeps a held edit when an oversized one follows (the save stays blocked), so success always means the buffer has it. - The frame shell copies accepted bytes so a reused buffer cannot change what get() returns. - The editor template settles dirty and its notice only on the newest input's answer. * test(plugins): annotate the frame shell mount fixture's types |
||
|
|
5020bfead6 |
Keep Session History open when a chat workspace was deleted (#37200)
* Keep deleted-workspace chat Resume in History * Address review: keep notification bounce, announce History toast, tidy refusal outcome * Fix mobile type narrowing in History open failure * Re-measure mobile web bundle sweep after History notice import removal |
||
|
|
263d3b16aa |
test: remove 104 low-value test declarations (#37290)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
f037753ee3 |
Keep chat pickers usable while options recover (#37168)
* Keep chat pickers usable while options recover * Show only the current process's reported permission and effort after a restart When a native chat's agent restarted, the first frame at the new process could still show the old process's reported permission (for example "Full access" on an Own chat) as pickable, then flip to unknown a moment later. A reported value now counts only while the options answer that carried it belongs to the current process, on desktop and phone. Also updates the restart tests: a pick made while the new process's options read is pending or failing goes to the new process on both desktop and phone. |
||
|
|
9fb4929055 |
fix: keep read-only close errors from blocking agent launch and AppImage CLI setup (#37155)
* fix(cli-runtime): preserve advisory inspection results on close failure * fix(appimage): keep close errors from overriding verified inspection results The AppImage identity and stable launcher readers closed their read-only handle in an unguarded finally, so a close error replaced the verified result and broke CLI status, startup crash capture and launcher upgrades. Attempt the close once and discard its error, as the CLI runtime check does. Also load the real closeSync in the node:fs mock factory instead of inside the test body. * test(cli-runtime): drop type assertions from close-failure fixtures |
||
|
|
097d77ac80 |
fix(terminal): recognize Claude drafts with labelled input boxes and the default hidden cursor (#37171)
* fix(terminal): recognize labelled Claude composer frames * fix(terminal): recognize Claude's default simulated cursor in the composer Claude Code's default caret hides the native cursor and parks it at a painted caret cell, so its composer (labelled or bare) was never detected: the draft leaked into screen reads and automatic mail was not held. Accept a hidden cursor on the Claude prompt only inside a complete composer frame with the cursor right of the glyph. On the normal buffer the parked cursor suffices (Claude drops the inverse caret paint on focus-out); on an alternate or unknown buffer the cursor cell must also be inverse. Both facts are read per call from xterm, only while the cursor is hidden. The closing rule now comes from the row where the continuation walk stopped, removing the extra rows-below scan. Codex and boxed composers keep rejecting hidden cursors. * test(terminal): scrub worktree name from blurred Claude fixture |
||
|
|
5bbbdebe6b |
Open the goal composer from /goal in Claude and Grok chats (#37212)
* Make goal command entry consistent across supported chat agents * Keep the composer goal mode binding local * Open the goal chip only for the provider's built-in /goal Carry the provider's built-in marker on slash-command rows (Claude's initialize descriptors report it) through to the picker, and enter goal mode from a picked /goal only when the session has host goals or the row is the provider's own built-in. A user command or skill named goal keeps its normal invocation, and bare /goal without host goals is sent as typed again. Host goal objectives resolve pasted text before the /goal prefix is stripped, as before. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Mark Grok's built-in slash commands from its initialize response Grok lists its own built-ins in the initialize response of each process. Carry that onto the session command rows as the existing built-in marker, so picking Grok's /goal opens the goal chip like Claude's. A row that Grok tags as a skill or workflow never takes the marker, since a session can close the built-in and let a same-named skill take its name. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Feed the Grok built-in command test a recorded initialize response Replace the hand-trimmed initialize reply with Grok 1.0.70's recorded initialize result, keeping its seven built-in command rows and removing host-identifying metadata. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Type the composer send result as boolean in the IME composition test The structured composer send now resolves to whether it was admitted. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
a29461bc15 |
test: remove 88 low-value test declarations (#37280)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
a94f784f84 |
Continue in Chat UI opens the chat before closing the terminal, and stops a CLI still starting (#37227)
* Continue in Chat UI opens the chat before closing the terminal, and stops a CLI still starting The chat tab now opens right after the terminal and is selected before the terminal closes; its create waits for proof the CLI exited, so the workspace never sits empty while a large conversation loads. The terminal is kept only when the host proves its shell runs nothing, so a CLI clicked before its first status update is stopped instead of left writing beside a chat that can't send. * Continue in Chat UI asks before stopping another job, shows a chat already opening, and keeps a failed chat in place A job started in the shell after the agent quit now goes through the terminal's running-process prompt instead of being stopped silently. A pane not bound to its terminal on this client is treated as unverifiable and closed, like any unverifiable read. When a chat for the same conversation is already opening, Continue shows it and keeps the terminal rather than handing the terminal into a launch it doesn't own. After the terminal closed, a failed start stays in the chat that took its place and says why once, including when the CLI's exit couldn't be confirmed, so the workspace is never left blank. A launch that ended before its tab opened reports its failure again, and a tab picked during the close stays selected. * Continue in Chat UI asks before stopping a different agent, and answers a chat still opening without joining it Only the conversation's own agent is stopped without the running-process prompt; another agent started in that shell is asked about like any other job. A chat already opening the same conversation is found before the new chat starts and shown (or named, from the tab menu) with the terminal kept, so an unconfirmed chat's create is never re-sent beside the running CLI. The in-chat message for an unconfirmed stop no longer points at a host connection. Test timestamps are fixed values. |
||
|
|
608f83061e |
test: remove 58 low-value test declarations (#37270)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
c494be1906 |
fix(agent-status): match OSC 7501 spec length limits and progress parsing (#37267)
* fix(agent-status): match OSC 7501 spec length limits and progress parsing * fix(agent-status): keep a capped OSC 7501 body whose ST splits across chunks |
||
|
|
380f68149e |
test: remove 39 low-value test declarations (#37261)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
8fa8c9fee3 |
test: remove 110 low-value test declarations (#37251)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
29479ddd3e |
Chat UI roll out implementation (#37222)
* Adjust Chat UI announcement rollout and show a nonblocking card - Assign new profiles to an 80/20 control and treatment experiment, with treatment split between all users and eligible harnesses. - Show terminal-default users a corner card and record targeting assignments to measure outcomes. * Refine the Chat UI announcement card layout and copy * Add live switching demo to Chat UI launch tip experiment * fix test * Shorten Chat UI announcement telemetry documentation * Add a swapped-button cohort to the Chat UI launch tip - Assign 10% of new enrollments to the new variant while preserving existing assignments. - Track live-switching link exposure and simplify the demo copy. * Adjust Chat UI launch tip rollout and switching options - Add a centered dialog cohort and independently vary button emphasis. - Target users who have not switched and allow switching back to terminal. - Record live-switching exposure only when the link is visible. * Validate persisted chat tip emphasis before initializing telemetry * Target chat UI launch tips using the current default surface Freeze eligibility at enrollment while preserving the historical audience. |
||
|
|
07b437c9e9 |
fix(terminal): detect foreground from the physical PTY owner (#36342)
* fix(terminal): observe foreground at the physical PTY owner
* fix(terminal): keep existing inventory, inspection and display semantics around master-group foreground
Review round 1 fixes for the physical-owner foreground observation:
- Stop and liveness verification keep complete-inventory proof: the router's
scoped listProcesses({ptyIds}) is owner resolution again (absent = []).
Only the launch guard's old-owner fallback asks for an established
target's owner via an internal targetOwnerOnly option.
- Degraded daemon mode routes foreground observations and target reads to
the established owner, so an unreachable unrelated daemon cannot refuse a
known terminal there either.
- Display and name refreshes read the master's foreground group but take
member rows from the shared single-flight process-table snapshot; no
per-terminal ps per refresh. Recognized agent names skip the confirm scan
again, and builds without the native accessor keep the existing reader.
- Ordinary inspections keep their first-match routing; strict owner and
incarnation checks apply only to foreground decisions. The unused
foregroundOnly preload/IPC/RPC surface is removed.
- Local inventory forwards only the target scope, never caller deadlines.
- An interpreter running an agent script counts as that agent, as before;
a blank argv row no longer voids a terminal capture outside the
foreground group.
- Bump the packaged compatibility contract to daemon protocol 55 and move
the node-pty accessor above the process getter's doc comment.
* fix(terminal): keep the node-pty patch hunk well-formed and drop redundant foreground tests
Remove two stray context lines from the src/unixTerminal.ts hunk so its body
matches its header (strict patch parsers reject the mismatch), and update the
lockfile patch hash. Prune foreground tests whose rows repeat branches the
parity table already covers.
* fix(terminal): index the shared snapshot by TTY once and keep observation age nonnegative
Display refreshes filtered the whole shared process table per pane, so
work grew with panes times processes. Group each snapshot by normalized
TTY once, memoized by array identity, and look each pane up directly;
the scaling contract now counts row TTY reads at N and 10N panes.
Both foreground observation producers clamp capturedAgeMs at zero, so a
wall-clock step back during the read no longer yields an envelope the
validator rejects and the launch guard refuses.
* test: move foreground-observation compat tests into the protocol compatibility suite
Main removed daemon-pty-adapter-steady-state-compat.test.ts; the merge restored it with only this branch's block. Reuse the suite's existing inspection adapter helper so no new type assertion is added.
|
||
|
|
a7d6926f77 |
fix(git): show encrypted and textconv files as text diffs, not binary (#37105)
* fix(git): apply textconv filter to original blob in diff view (#37100) Apply git cat-file --textconv when reading non-previewable blobs for diffs so that encrypted or filtered files (git-crypt, sops, etc.) are rendered as readable text instead of binary. Fixes #37100 * fix(git): apply textconv to binary working-tree files for unstaged diffs * fix(git): textconv only diffs whose editable side stays byte-exact Unstaged diffs keep raw bytes unless the path's driver leaves the working tree unchanged (clean/smudge encryption such as git-crypt); the check runs in a scratch object store so nothing is written to the repo. Drops the binary working-tree textconv, which made converted text editable. * fix(git): read the stored blob first and convert only paths with a driver cat-file --textconv pretty-prints trees, so a directory replaced by a file showed a tree listing. Reading the blob first keeps absence and type handling unchanged, and drivers are looked up in parallel so paths without one cost no extra wait. Driver failures are kept out of the settled cache, deleted files convert, and the clean-filter probe gets a read deadline. * fix(git): never settle-cache diffs that ran a textconv driver Driver output depends on config, keys and tools the worktree stamp does not cover, so a locked key or failing driver could pin a raw result. Deleted files stay raw, since Monaco's revert arrows would restore converted text, and drivers run off the WSL direct-read route so profile variables reach them. * fix(git): show the editable unstaged side against checkout bytes A worktree that the driver leaves unchanged does not make the converted original safe: Monaco's revert copies the original into the editable side, and a driver like `tr a-z A-Z` would restore ONE where checkout writes one. Unstaged diffs now read the Git side with `cat-file --filters`, which is exactly what checkout writes and decrypts clean/smudge encryption, so the scratch-store probe is gone. * fix(git): share one driver lookup per path and keep editable ranges in checkout form check-attr is a read, so it no longer counts as a worktree mutation or waits on WSL write probes. Commit, branch and submodule diffs look the driver up once per path, the unstaged submodule range shows checkout bytes like the rest of the editable side, and a staged rename stays out of the settled cache when either path has a driver. * test(git): age the diff stamp with a fixed timestamp --------- Co-authored-by: Hrithik <hrithik@Hrithiks-MacBook-Pro.local> Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com> |
||
|
|
245de319d3 |
fix(emulator): report when Xcode Device Hub blocks iOS simulator input instead of a silent ok (#37140)
* fix(emulator): report Device Hub blocking iOS simulator input instead of a silent success * fix(emulator): keep the session backend so the pane input check sees iOS sessions * test(emulator): pin the pane input check to active iOS sessions * fix(emulator): probe Device Hub via process-host and recheck on pane keyboard input * refactor(emulator): use the shared RPC error-code predicate in the pane input check * fix(emulator): key the pane input check on the live stream after the session hook stopped returning session Main's session hook no longer returns session and sits at its line cap, so the pane keys the check on the live preview URL. The iOS-only session check moves into its own module to keep the runtime commands under the cap. |
||
|
|
c18c358fce |
Keep child-worktree creation in the caller’s project (#35787)
* fix(cli): keep inferred worktree creation in the caller project * Fix caller checkout ranking and creation guidance * Share caller-host containment preparation across CLI selections * Correct Windows CLI fixture syntax and snapshot command * Match worktree fixture output to typed execution hosts * Regenerate bundled workspace placement guidance * Refuse ambiguous workspace ownership and preserve launch replay * Scope runtime filesystem mocks to their aggregate tests * Preserve launch proof semantics under strict test diagnostics * Keep launch proof imports within their compiler project boundary * Consolidate journal cleanup test imports * Adapt launch fixtures to the current host settings contract * Keep the CLI error formatter under the file-size limit Move the selector-ambiguity workspace-choice check into selector-ambiguity-recovery.ts, which already owns that error's recovery text. Behavior is unchanged. * Expect main's concise orchestration output in the workspace-choice CLI tests Orchestration commands now print the one-line failure on stderr and the workspace choices and next steps on stdout (or compact JSON plus the stderr line with --json), and print concise success fields. --------- Co-authored-by: Orca QA <orca-qa@users.noreply.github.com> |
||
|
|
0fa5dae2f9 |
Read who each agent works with: its manager, workers and peers (#34890)
* Nest chat-UI orchestration workers under the agent that started them
Main's lineage projection only walked terminal panes, so workers running
in the chat UI never got a parent link and listed flat in the sidebar.
It now also projects chat workers, keyed by their visible chat row, and
resolves a chat creator or coordinator to that chat's visible row
instead of its handle or private mailbox pane key.
* Fix public worker lineage across assignment and row identities
* Complete terminal lineage provenance and bound active session selection
* Repair lineage test runtime boundaries and SQLite counters
* Provide read-only crew snapshots for each agent
* Batch public lineage verification after exact recency selection
* Derive crew relations once per meaningful host change
* Remove package manager lockfile churn from hook
* Use checked runtime values in lineage integration tests
* Document the trusted Dispatch SQL row boundary
* Keep lineage integration imports within their test programs
* Load native lineage fixtures before test execution
* test: complete lineage inputs in runtime and sidebar fixtures
* test: seed benchmark facts from active dispatches
* test: replace partial orchestration DB casts with typed fixtures
* test: complete stale-leaf mailbox fixture session input
* Derive durable crew parents from retained assignment proof
* fix(test): render worker lineage fixture with production list
* Add scoped terminal identity acquisition and preserve crew source wakes
* Share raw crew identity inputs through scoped production readers
* Exercise crew generation retirement through actual source owners
* Retire crew inputs on consumed ownership and visibility writes
* Use typed crew mutation and fixture access
* Repair crew fixture and RPC type contracts
* Align crew integration fixtures and RPC parameter contracts
* Encapsulate terminal identity mutations and captured reader contracts
* Seed terminal identity fixtures through canonical mutations
* Fix terminal identity fixture return type
* Cover terminal identity lifecycle schedules
* Align terminal fixtures with canonical identity sources
* Repair runtime fixture source contracts
* Use checked database fixtures for federation contracts
* Update crew source inventories and exit fixtures
* Preserve crew setup outcomes at existing subscription owners
* Match managed restore fixture to its nullable async return type
* Keep absent setup observations distinct from undefined failures
* Drive pending Crew questions from existing metadata
* Preserve nested pairing repair outcomes for shared callers
* Route attached workers to explicit local recipients
* Type Crew pending-question measurement receipts
* Match SSH repair fixture target absence to store contract
* Bound cold terminal layout construction and finite pane acquisition
* test: use public runtime identity in pane acquisition fixture
* Avoid repeated searches in cold workspace layout loading
* Verify cold loader fault identity and hook claimant effects
* Revert "Route attached workers to explicit local recipients"
This reverts commit
|
||
|
|
2fa9cff16f | fix(emulator): report why an Android AVD failed to start instead of timing out after 3 minutes (#37137) | ||
|
|
dc5cfd945d |
feat(mobile): keep the PR tab live, show each thread's code and ask the agent to fix bot findings (#37023)
The PR tab and the Checks and Comments screens refresh by themselves while they are open and the app is in the foreground, on desktop's checks-panel cadence (policy moved to src/shared). A failed background read keeps the PR on screen and backs off instead of replacing it with an error. Review threads show the lines they are about: the host forwards the tail of each thread root's diff hunk, and mobile numbers it back from the thread's line. Bot findings get "Ask <agent> to fix", which launches desktop's Resolve comments prompt (moved to src/shared) for that thread. Fix and Ask buttons name the agent that would start. |
||
|
|
d1665d1b40 |
Add run and skip setup choices to the automation CLI (#36543)
* Allow automation CLI setup choices for new workspaces * Explain automation --setup refusals and read back the saved choice Name why --setup is refused and what to pass, show the setup choice in text output, document --setup in the CLI guide, fail when a host drops the choice, and cover the app-open Terminal dispatch. * Refuse automation --setup on hosts that can't keep it, and fence the edit's mode Explicit --setup now needs the host's new setup-choice capability, checked before any write; commands without --setup are unchanged. An edit whose setup choice relies on the current new-per-run mode sends a mode precondition the store checks against the saved record, so a concurrent switch to an existing worktree refuses the whole edit. Text output shows the saved choice or "not set", the existing-workspace refusal offers a remedy that works for every input, and the after-write readback is gone. * Make the too-old --setup message true for edit and cover a saved setup edit Omitting --setup on edit keeps the saved choice, so the refusal now says to run the command without --setup. A new test saves a --setup run edit through the controller into the store and reads it back after reload. |
||
|
|
ebe94bc32e |
feat(mobile): rebuild the PR tab around what is blocking the merge (#36999)
The PR tab now leads with the PR's identity, one row per merge gate (checks, unresolved threads, approvals, conflicts) that opens the screen or sheet that resolves it, a changes card and a collapsed description. Close, Unlink, Auto-merge, Edit title and Copy link move into the ⋯ menu. Checks and Comments become pushed screens: failures open with their annotation and Fix / Rerun / Open / Log on the failure, running checks next, passed folded; comments filter by Unresolved / All / Hide bots with Resolve and Reply on each thread and a comment box at the bottom. Merge opens a sheet that lists only the methods the repo allows, starting on its default. Reviewers move into a sheet with search to add and remove. Every Create PR entry point opens one sheet: title and description seeded from the branch's commits (shared seed rule in src/shared, GitHub's own default), Write with AI, base picker and draft. It pushes first when needed, works for all five providers and lands on the PR tab for GitHub. |
||
|
|
42bdeffbe4 |
Move chat readers to the newest saved step after a no-op save (#37118)
* fix(chat): move forward readers to the covered tip after a no-op save A write whose fold changes nothing stores no outcome record, so its sequence never appears in a forward read. Readers placed themselves at the last returned row and stayed behind the live cursor, so open chats re-read an empty page and recomputed the prompt projection on every later delivery until the next real save. Forward journal reads now report the highest sequence they covered. History pages move there when the read was complete, prompt reuse and native responses compare against it, and a read cut short by its limit, byte budget or damage still stops at the last returned row. * fix(chat): append unlimited outcome reads without spreading, and report coverage from the mobile journal fake * fix(chat): skip the retention scan for batches that change no journal items |
||
|
|
78484aac31 |
feat(mobile): one next-step bar under both Source Control tabs (#37104)
* feat(mobile): one next-step bar under both Source Control tabs Changes and Pull request are the only segments. A bar at the foot of both shows the branch's one next action: the commit box, push or pull, create the review, resolve or fix with the workspace's agent, merge when ready, merge, or why it can't. Commits opens as a pushed screen. * fix(mobile): keep Merge reachable and show bar failures on both tabs * test(mobile): expect the two Source Control segments in the page render test |
||
|
|
ad864a6ec7 |
Show a card in the chat when its agent hands work to another agent (#36848)
* Show a card in the chat when its agent hands work to another agent An agent that hands work off with 'orca agent launch' from a native chat now leaves a 'Handed off to agent' card there, linking to the new chat or terminal, the way a supervised worker-start leaves 'Started worker'. The CLI names its chat on agent launches (same-host only); the host records a display-only agent-handoff item after a successful launch with a submitted prompt, once per launch operation. Nothing about the card can refuse or delay the launch. Tracked in STA-13209. * Keep orca commands working in a native chat that has no terminal handle The launch-caller evidence read the host stamp off an absent evidence object, so every orca command from an ordinary native chat threw before sending. Adds CLI tests for which requests name the launching chat, restores the lockfile to the base, and fixes the Korean heading. * Read a card's heading from its creation flags together A caller passing only the started flag drew a handoff as Started worker; the heading now takes the message's flags as one argument. * Show the handoff card for every agent a chat launches A launch without a delivered task now records the card too, with no task text, as the common pattern records every agent a chat creates. The handoff tests now run the real chat host and journal: one card per launch operation, none on replay, a removed card stays removed across a restart, and the clock is fixed. * Head a launch card Started agent when no task reached the new agent Handed off to agent now appears only when the card carries a task; a card for an agent started with no task (no prompt, a draft, or a prompt that wasn't delivered) reads Started agent. The heading is derived from the card's text, so nothing new is saved. Also drops a self-launch check the launch path already refuses first. * Show the handoff headings on the phone's agent cards The phone card passed only the started flag, so with the new heading rules it would draw every creation card as a plain message. It now passes the message and has a heading for every case, so a missing one fails the build. The heading function now requires the message's creation facts, so no caller can leave them out. Adds the phone strings in every language, and the Japanese "Started agent" now uses the catalog's term for agent. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
c24d916f31 |
Route hosted review operations to the owning host (#36003)
* Route hosted review refreshes to their owning host * Route remote review operations to their owning host - Refresh the correct hosted review after remote git operations - Scope comment mutations and AI acknowledgements to the owner cache * Route legacy paired SSH reviews through their server owner - Recover proxied runtime owners for older SSH worktree listings - Preserve direct and ambiguous host routing safeguards * Preserve review ownership across remote workspace operations - Route checks, comments, and linked-review clears through the selected repository owner - Reject ambiguous or mismatched host context to prevent cross-machine mutations * Keep check detail tabs scoped to their remote owner * Preserve remote worktree ownership across reconstructed check tabs * Preserve direct SSH check tabs when proxy listings overlap * Scope PR refresh ownership state and safely roll back comment mutations - Preserve linked-review clear scopes beyond cache eviction and clean them up on expiry - Handle failed or refused comment reactions and thread resolutions without stale optimistic UI * Preserve remote review ownership when SSH copies overlap * Fix review routing for overlapping remote repository hosts - Preserve server-owned review refreshes when a direct SSH copy exists - Fail comment mutations and refetches safely when ownership becomes invalid - Resolve check and sidebar data through the workspace’s owning host * Relax cache-sensitive test expectations * Route check refreshes to runtime owners and isolate restored requests * Scope reconstructed check detail tabs by execution owner * Fix review refresh ownership for shared remote hosts - Prefer explicit execution owners when matching worktrees. - Avoid repeated tab scans when restoring check details. * Fix hosted review polling for workspaces on multiple hosts * test: trim redundant review ownership scenarios |
||
|
|
af6dabd70b |
feat(plugins): orca plugin shot --scenario replays a check scenario; dev watch shot pendingRequests (#37090)
- shot <key|dir> --scenario <name> renders the panel in that check scenario through the check runner (a separate Node process on a mock host and mounted worker), sends the validated drawn tree to a new plugins.shotReplay, and captures it in a throwaway preview surface: no guest, no live host, no real storage or settings, no real worker, images as placeholders. Window hidden or minimized only; --act, --environment and bridged shells refused; an older host answers method_not_found (runtime_unsupported) rather than doing a live shot. - dev watch's shot event carries pendingRequests. |
||
|
|
225db8cfb2 | Hide no-action attention in concise worker views; say kept-open workers stay open (#36963) | ||
|
|
9ecf57545e |
feat(github): let mobile turn a pull request back into a draft (#37000)
Adds github.markPRDraft (gh pr ready --undo) on the host, allowlisted for paired phones and advertised with mobile.github.markPRDraft.v1 so older hosts simply hide the action. |
||
|
|
dfbaa2fc29 |
Plugin shots wait for the worker and restore after --act; terminal approval prompt (#37066)
* feat(plugins): dev watch asks for first-load approval in a terminal; acronym-aware names
- In an interactive terminal without --json, a first dev watch load that needs approval shows
the grants (as plugin inspect prints them) and asks Approve and load? [y/N]; yes reloads with
the host's fingerprint and keeps watching. --json and non-TTY runs keep the exit-3 flow.
- create keeps known acronyms uppercase when it derives a name from the id (pr-queue → PR Queue).
* fix(plugins): a declined dev watch approval prints only the re-run command
The person just read the grants in the prompt, so the exit-3 error no longer repeats them:
Not approved. To approve later, run: <command>.
* feat(plugins): shots wait for the worker; --act restores the panel; Table and Tree acts
- A shot settles once the panel has no plugin.request or host call in flight and no new tree for
a quiet spell (capped at 3 s), so a cold worker's skeleton is not captured; pendingRequests
reports what was still pending.
- After --act and the capture, the guest restores every plugin-written atom it had before (new
ui.snapshot/ui.restore; persisted atoms re-persist) and Orca remounts its drawn controls;
restored: true|false. Worker-side effects are not rolled back.
- --act gains the kit's slide, sort, selectRows, activateRow, loadMore, expand, collapse,
selectItem and activateItem.
- Docs: the dev watch first-load prompt; shot settle, restore and the new verbs.
* fix(plugins): a shot waits for the theme repaint and retries a bare capture
Linux CI captured a dark --theme shot as a bare background (2 colors). The renderer now waits
until the document shows the asked color scheme and paints, adds a frame after a --width
resize, and main recaptures a panel image that is still a background and a border (two colors
or fewer) up to 8 times, 150 ms apart, before returning it. Html panels keep their guest
composite.
* fix(plugins): capture the main window with stayHidden
webContents.capturePage(rect, { stayHidden: true }) keeps a hidden window rendering for the
capture, as the components gallery screenshots do. The repaint wait stays, and the bare-capture
retry stays as a fallback.
|