mirror of
https://github.com/stablyai/orca.git
synced 2026-11-14 09:57:48 +00:00
a0d34074ea367f92ecde4609a7581e4f96135bd7
5
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d3ef8b4255 |
test: remove 216 low-value cases and 42 whole suites (#41030)
* test: remove 216 low-value cases and 42 whole suites * test: retire unprotected snapshot adoption gate --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
6b7da572e5 |
perf(persistence): window moves and UI edits no longer re-save the whole profile (#40627)
* perf(persistence): saves name the profile domains they changed UI changes, window moves, SSH terminal exits, phone tab switches and repo/folder/SSH/lineage edits no longer re-serialize and hash the whole profile on the main thread. Each save names its domains (or 'whole' where an operation can't know them), and one per-domain saved form serves both selective and whole saves, writing dependent domains together. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(persistence): keep folder re-tiering and plugin context on named saves Folder workspace unread writes re-tier sort stamps again, and plugins hear an active folder's rename, now that those saves name their domain instead of the whole profile. The folder-note test drains the load's whole save so it checks the named save. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(persistence): typed folder workspace fixture for the re-tier case Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(persistence): build the serializer from typed state in the parity test Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(persistence): read unprojected domains without a type assertion Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(persistence): stall and fail the selective writer UI saves now use Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * perf(persistence): every mutation saves only the domains it changed Removing a project, renaming a worktree's path, re-adopting an SSH target, importing a catalog, deleting a group or folder workspace, retrying a failed terminal close and remapping session panes now name their domains instead of rewriting the whole profile. Only startup load and maintenance resume rewrite every domain, through a separately named entry point a lint rule keeps out of mutation code. A named automationRuns save refreshes a pending run delta so it can't write an older run list. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(persistence): a named automation-run save supersedes older run lists A catalog import replaces the run list while an earlier run write can still be in flight; if that write fails, its restored pending list must not win over the import. Domain lists name the local session through the shared constant so the layout-writer ratchet stays exact. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(persistence): keep the whole-row fallback for replaced run lists A run list replaced outside the run-delta path (catalog import, SSH re-adoption) saves as a whole row again, so histories that can't use the per-run storage still save. A failed in-flight run write restores its pending list only while that list is still current; otherwise it marks the run domain for a whole-row save. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(persistence): save run lists per-run rows can't hold as one row A run delta whose list can't be stored as per-run rows (a legacy history with duplicate run ids) now saves as the ordinary whole-row replacement instead of failing the transaction, so a catalog import or run edit on such a profile still commits. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
be108a4981 |
fix(plugins): emit workspace.changed when focus moves between identical workspaces (#40505)
The watcher deduped on the public payload (branch, displayName, terminals), so moving focus between two workspaces that project to the same payload was dropped. Dedupe on the focused worktree id as well; the emitted payload still omits that id because it can embed a provider path. Fixes #40502 Co-authored-by: Neil <neil@stably.ai> |
||
|
|
9ef524f973 |
fix(plugins): stop terminal inventories for agent status events nobody hears (#39383)
* fix(plugins): stop terminal inventories for agent status events nobody hears Each agent.status.changed event for plugins lists the workspace's terminals, which refreshes every PTY provider and host. Interest was only checked when an event was admitted, so after the last panel closed the queued backlog kept running full inventories with no one to deliver to. Recheck interest before each lookup and drop the backlog once nobody listens, and let events queued behind a slow lookup share one listing per workspace while keeping arrival order. (STA-13319) * fix(plugins): keep the agent status queue moving past a throwing delivery A synchronous throw from one emitEvent dropped the rest of its batch and left later queued events waiting for the next arrival. Catch per delivery, and cover a failed listing, a 1000-event storm, a panel reopening mid-lookup, and several panels on the real bridge; the panel e2e now checks a burst arrives in order. (STA-13319) |
||
|
|
ec0d3cedd1 |
Plugin panels talk to their worker; panel storage, settings and agent events (#37013)
* feat(plugins): panels talk to their own worker, read storage, settings and events
- plugin.request (host API 1.2): a panel or editor asks its plugin's worker, which answers with
orca.panels.handle(name); the worker pushes with orca.panels.post. Same plugin only, JSON
checked, 1 MiB answers, 256 KiB/200-per-10s posts, a deadline and the panel's lifetime.
- Panels and editors get storage.*, settings.* and secrets.* behind the same capabilities, and
storage/settings onDidChange on every surface; events.subscribe delivers workspace and agent
events to panels that hold the read capability.
- contributes.settings: typed settings (a JSON Schema subset) with defaults and value checks.
- Frames get orca.plugin/storage/settings/secrets; components panels import plugin, storage,
settings, secrets from 'orca', and atom(key, init, { persist: 'storage' }) shares a value with
the worker. Workers get orca.panels/storage/settings/secrets sugar.
- One typed contract: declare module 'orca' { interface PluginRequests / PluginPanelEvents }.
- Desktop push channel per open panel session (plugins:openPanelPush).
* feat(plugins): Orca Settings shows and edits a plugin's contributes.settings
The plugin page lists declared settings with Orca's own controls (switch, picker, text and
number fields, Reset to default). Edits are checked against the declaration in main, written to
the plugin's settings, and reach open panels and the running worker through onDidChange.
* docs(plugins): hello-tsx talks to its worker; authoring guide covers panels, workers and data
The example now uses one of each: plugin.request answered by orca.panels.handle, a worker post
heard with plugin.on, a persist: 'storage' atom the worker watches, two contributes.settings and
agent.status.changed in the panel, all typed by one src/protocol.ts. The build-less TSX e2e
drives the whole loop.
* fix(plugins): typed bridge overloads, panel call budget, settings IPC and catalog keys
- PluginBridgeApi/PanelsApi use overloads: declared names are typed (and complete), any other
name carries JSON; no never-unions for the type-aware lint.
- The per-plugin panel call budget is 120 per 10 s, since a panel loading storage atoms,
settings and its first requests makes a burst; the hostile fixture floods past it.
- Settings IPC builds its host per call; the settings section's strings are in en.json.
* test(plugins): the example's declared settings show under the plugin with the person's value
* refactor(plugins): keep hello-tsx the minimal starter; the bridge demo is hello-worker-panel
hello-tsx goes back to a sandboxed-ui panel with no worker or capabilities. The worker, protocol,
storage atom, settings and events move to examples/plugins/hello-worker-panel, with their own
e2e (plugin-worker-panel) and PR route.
* feat(plugins): test kit covers the panel bridge and plugin data
mockHost keeps the plugin's storage, settings and secrets in memory (seeded with storage,
settings, secrets; read with host.data()) and fakes the worker with requests, so plugin.request,
storage/settings/secrets and persist: 'storage' atoms work under mount(), writes reach
onDidChange, and panel.post(event, payload) is what plugin.on hears. Typed by PluginRequests and
PluginPanelEvents.
* test(plugins): focusInGuest waits for the guest and retries focusing as one step
Under load the custom-editor guest could still be attaching, so executeJavaScript threw
'dom-ready' before the focus poll began. Wait for waitForGuestReady, then retry focusing the
webview and the element together, tolerating a guest that is still attaching or remounts.
* docs(plugins): the authoring skill covers panels, workers and data; persistence leaves the renderer
- skill-guides/orca-plugin-authoring.md gains Panels, workers and data (plugin.request/on,
orca.panels.handle/post, persist: 'storage', contributes.settings, panel events, test kit), and
its generated references read orca-services.d.ts for shell, files, on and the bridge types.
- After the dev-loop rebase, persisted-atom wiring (queue plus storage sync) moves to
createDeclarativePersistence so the renderer stays under max-lines.
* feat(plugins): panels show agents: agents.list, terminal ids on agent events, workspace.changed
- agents.list (agent:read, every surface): the focused workspace's agents with terminalId,
title, agent kind, state and stateStartedAt, from the hook server's store.
- agent.status.changed carries terminalId and title: paneKey mapped through the runtime's
terminal list (tabId:leafId) or the status's terminal handle; looked up only while a plugin
listens, in arrival order.
- workspace.readContext terminals carry title; workspace.changed (workspace:read) fires after
workspace session writes when the focused workspace or its terminals change.
- Event subscriptions are kept per panel session, so one made before the push channel opens
still counts.
- shell.openExternal never prompts on a hidden or minimized window: it settles
{ opened: false, reason: 'consent-unavailable' } and says so in the plugin log, which also
notes 'waiting for the person to confirm' while a prompt is up; the rate budget is spent only
when Orca acts. e2e launches never open a real browser or mail client.
- A worker may export activate as default or by name; docs, typings and the authoring skill
document the entry, the agent events and a live agent status recipe.
* fix(plugins): the plugin page names the workspace.changed subscription
* fix(plugins): workers activate only by default export, and say so when it is named
Orca calls the worker module's default export. A module with a named `activate` and no default
now fails to start with an error naming the fix (`export default function activate(orca)`),
instead of being called by a fallback; docs, typings and the skill say default export.
hello-worker-panel gains a picker setting (suggestionOrder) the worker reads.
|