mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 18:37:24 +00:00
c679989e6dbbfd2ce8eba8d2c07c3aaed7db623c
29
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a9bef96c56 |
test: remove low-value plugin schema and roster cases (#41683)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
0b83894696 |
test: remove low-value schema and unused-reader tests (#41638)
* test: remove routine relay response schema examples * test: remove suite for unused automation jobs reader * test: remove Box schema inventory and duplicate warning tests * test: remove unused relay predicate and schema budget examples --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
757b1e6167 |
feat(plugins): project.setHidden — hide and show projects from plugins (#41582)
- project.setHidden({ projectId, hostId?, hidden }) -> { hostId, hidden }: workspace:write,
worker only, host API 1.9 (unreleased, floor 1.4.258). Calls repo.setHidden by id: only,
always host-qualified; a twin without hostId is refused naming hostId; an answer without
hidden (an older host) is a fixed action_failed.
- project.list rows carry hidden.
- repo_not_found maps to 'no project has this id'.
- Audit summary by ids; workspace:write consent copy names hiding projects.
- Mock testing host echoes project.setHidden; regenerated plugin artifacts.
|
||
|
|
0b6497cfc8 |
test: remove low-value plugin, mobile and shared suites (#41571)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
75ce5be014 |
feat(plugins): host API 1.9 — agent session history, resume past sessions, task titles (#41542)
* feat(plugins): host API 1.9: agent.listSessions (history:read), resume past sessions, agents.list task titles * test(plugins): host API 1.9 coverage; regenerate plugin artifacts * fix(plugins): host API 1.9 review fixes - agent.resume starts a past session where the desktop's Resume would: the same preparation request and answer handling (now shared), and the transcript in the home it pins - AI Vault list cache keeps four scopes, so plugin reads never evict the panel's list - list fingerprints ignore scan id and issues, so an unchanged history revalidates - workspace mapping resolves symlinked workspaces and prefers a project over a folder - agents.list task only for open dispatches, read at most once a second - running matches OpenCode versions; history reads reset when the vault list is invalidated - truncation, consent copy and limitations documented * fix(plugins): forced history refresh supersedes cached scopes; resume legacy Codex sessions from their recorded transcript * fix(plugins): address host API 1.9 review threads - a scan that began before a forced history refresh no longer caches its older result - list fingerprints count which issues there are (not their wording) - symlinked workspaces rank by their resolved folder - a session-only status row is no live pane: resume prepares the session - a failed task-title read leaves agents.list rows intact - the symlink test uses a junction on Windows * test(ai-vault): order the stale scan before the forced refresh |
||
|
|
255b5c22c1 |
feat(plugins): host API 1.8 — create workspaces, resume agents, automations (#41528)
* feat(plugins): proposed tier for host methods not yet frozen
A method spec may set `proposed: true`: only development plugins may call
it (others get not_permitted), and the minor, frame/worker method lists,
typings and skill references omit it. The reference renders such methods
in a separate Proposed section; dev workers' host.has answers for them.
* feat(plugins): param capabilities, host confirmations, automation provenance
- PluginHostMethodSpec.paramCapabilities: a passed param can require a
second capability; executePluginHostCall and the mock host refuse it with
capability_denied before any audit or effect, and the reference shows it.
- confirmPluginAction generalizes the external-open prompt into a host-owned
confirmation, exposed as PluginHostServices.confirm (desktop only; absent
in headless serve). It re-checks the plugin's approval after the answer.
- Automations record createdBy { kind: 'plugin', pluginKey, name }, set by
the runtime from the in-process plugin caller (RpcContext.plugin), never
from params; the Automations detail shows "Created by <plugin>".
* feat(plugins): workspace:create, automation:read and automation:write capabilities
New closed-enum kinds (older Orcas refuse such manifests with the engines
message), worker-only, with consent copy that names what each allows;
release floor PLUGIN_HOST_API_1_8_SINCE (1.4.259) joins
PLUGIN_SCHEMA_NEWEST_SINCE. agent:launch copy now says it also resumes.
* feat(plugins): host API 1.8 methods: workspace.create, agent.resume, automation.*
- workspace.create (workspace:create; agent also needs agent:launch): a
worktree in a Git project, as orca worktree create does; with agent, the
CLI's agent.launch create-worktree path, so the agent starts after setup.
Setup is skipped or follows the project's settings; never run, an
approved hash or a startup command.
- agent.resume (agent:launch): terminal.ensureAgentSession by session id;
started is false when a terminal already ran it. agents.list rows and
agent.status.changed carry sessionId.
- automation.list/create/update/delete (automation:read/write): create
forwards only name, prompt, agent, target, schedule, time zone and
enabled; update/delete of automations another plugin or the person made
ask the person first and report cancelled or consent-unavailable.
* test(plugins): host API 1.8 coverage; regenerate plugin artifacts
Covers param capabilities (host and mock host), workspace.create payloads
and refusals, agent.resume keys and adoption, sessionId on agents.list,
automation projection, forbidden create fields, confirmation outcomes,
runtime-set provenance and capability access growth. Regenerates the
reference, schemas, typings, declarative runtime and skill references.
* fix(plugins): host API 1.8 review fixes
- Confirmations spend the frame dialog budget, allow one question per
plugin at a time and pause after a refusal (rate_limited); a worker's
question shows in the focused window, else the first visible one.
- Changing what an automation with extra agent settings runs (prompt,
schedule, resuming) asks first even for its creator, showing the prompt.
- Removing, disabling or blocking a plugin pauses its automations and ends
its ownership (createdBy.endedAt), so neither re-enabling nor a reinstall
under the key resumes or edits them silently; the remove dialog says so.
- workspace.create and agent.resume record the terminals they return as
the plugin's own; a launch that fails after its worktree exists names it.
- Setup-decision refusals are told by the runtime's error class (kept as
the in-process RPC error's cause); generated names see every worktree
of the project; resume transcripts match the workspace and host.
- Created by shows the plugin id beside its name.
* fix(plugins): end automation ownership only on uninstall, disable or block
- The ownership sweep no longer reads discovery: only an uninstall
(announced by the removal path), the disabled list, the kill list or
the plugin-system switch end it, and only once the service is ready,
so an unreadable plugins folder pauses nothing. An install under the
same key after a removal keeps what it creates.
- A new time zone on an automation with extra agent settings asks first.
- A failed launch names only a new worktree made from the requested name.
- Settings' plugins-off state and the CLI's plugin system off and plugin
disable say that plugin-created automations are paused and stay so.
* fix(plugins): address host API 1.8 review threads
- Confirmations close when the worker's call ends, freeing the plugin's
turn; they name the automation (short id, project, workspace,
schedule), show any new prompt, and are refused as `changed` when the
automation was edited while the person was asked.
- automation.create takes hostId (through the project's setup on that
host) and a creationKey scoped to the plugin; the runtime rechecks the
plugin's approval right before the write.
- agent.resume records only terminals it started; both it and
workspace.create recheck approval before recording.
- automation.list never cuts a schedule (null when too long) or fails on
an id too long to show.
- The Automations detail says when a creator plugin was removed or
disabled.
|
||
|
|
e24af39c47 |
feat(plugins): host API 1.7 — workspace ids, project/terminal list, terminal focus/close (#41508)
* feat(plugins): host API 1.7 — workspace ids, project/terminal list, terminal focus/close
Plugins that track workspaces and terminals across Orca had to read the private runtime
token or shell out to the CLI. Host API 1.7 gives them the same through consented methods:
- workspace.readContext (and workspace.changed) carry `workspaceId`, the id workspace.list
gives; workspace.created/removed and agent.status.changed add `workspaceListId` beside
their existing raw `workspaceId`, which keeps its meaning.
- workspace.list rows name their `projectId`; opt-in `includeStatus` joins each row's agent
state, unread flag, live terminal count and last activity from worktree.ps.
- project.list (workspace:read), terminal.list (workspace:read), terminal.focus
(workspace:write, desktop only, steers only this window) and terminal.close
(terminal:send, reports whether the process is known to have stopped).
- Runtime refusals (unknown or ambiguous workspace, stale or exited terminal) reach plugins
as fixed messages instead of runtime wording.
- Consent copy for workspace:read, workspace:write and terminal:send says what they now
allow; terminal.focus and terminal.close are audited by terminal id.
- PLUGIN_SCHEMA_NEWEST_SINCE covers the editor typography and theme video floors it missed,
and the provisional 1.7 floor, so development builds accept plugins requiring them.
* fix(plugins): narrow terminal.close and harden host API 1.7 from review
- terminal.close closes only terminals of the focused workspace (the check terminal.sendText
uses) or ones this plugin opened with terminal.create or agent.launch, recorded in a bounded
per-plugin registry that is forgotten when its worker stops or it is disabled or removed.
terminal.focus stays any-terminal; summaries and terminal:send copy say so.
- Lifecycle events carry the worktree's identity and host: from the new row on create, and read
host-qualified before the purge on every removal path. agent.status.changed looks up the
identity on the reporting host only. The global removed-identity map is gone.
- includeStatus shares one in-flight worktree.ps and a 1 s cache across plugins, and reports
statusTruncated when that listing stopped short.
- Stored remote contexts get their identity host-qualified; panels and editors never get a raw,
path-bearing workspace id from readContext or workspace.changed.
- Runtime refusals map to fixed messages (tab pinned, no window, tab gone, host disconnected);
any other runtime error or malformed answer is a fixed action_failed with the detail logged.
- hostId is `local`, `ssh:` or `runtime:` in both workspace.list and project.list; rows past the
id or path bounds are left out with truncated set instead of failing the list.
- The mock testing host answers terminal.focus and terminal.close by default.
* fix(plugins): keep shipped host API values and codes; honest terminal results
- workspace.list hostId keeps the values 1.3 shipped (recorded host, else null; folder rows
their executionHostId); project.list always names the host. Both summaries say which.
- Methods that shipped before 1.7 report every runtime refusal as action_failed, as before;
the unavailable/conflict mapping applies to 1.7 methods only.
- includeStatus shares a pending worktree.ps however long it runs; the 1 s TTL starts when it
lands.
- The opened-terminal registry records only for a call still approved and not cancelled, and is
pruned on disable or removal only, so event-driven workers keep close rights across restarts.
- terminal.close answers { closed: true }: a local close cannot tell whether the process exited.
terminal.focus answers focused: false when the request was superseded or not navigated.
- workspace.list and project.list cut labels to 512 instead of failing the list.
- Removal events from the runtime job and the IPC retry are tested to carry the identity read
before the purge; folder deletion carries its host.
* fix(plugins): name the status-listing owner type
|
||
|
|
9ef5e48f09 |
Plugins: add editor.readTypography and editor.typography.changed (#40736)
* feat(plugins): add editor.readTypography and editor.typography.changed Plugins that render code next to Orca's editor had to open the private profile database and reimplement Orca's font rules to match it. Host API 1.6 adds editor.readTypography (no capability; worker, panel and editor frames): the font family and CSS stack, size with editor zoom, weight, line height in px, ligatures, word wrap and minimap that the file editor resolves now. editor.typography.changed carries the same values after a settings write or an editor zoom changes them; it is the first event that needs no capability. The pure resolution (editor typography, editor zoom, monospace font stack) moves to src/shared so main and the renderer use one implementation. * fix(plugins): keep editor typography resolution from throwing in main A hand-edited profile with a non-string font family made the shared resolver throw, which the main-process watcher would surface at startup and on every settings write. Font values are now type-checked, the watcher catches and logs, and it reads live settings so a write without listeners cannot leave the event payload stale. Over-long font families are cut to the schema bound instead of failing every read. Regenerates the testing runtime. |
||
|
|
c0d3d2e0db |
test: remove 13 low-value suites and redundant cases (#40138)
* Remove low-value file, runtime and chat test cases * test: remove low-value shared contract and timing suites * test: remove leaking browser IPC mock suite * test: isolate legacy relay bridge transport fixture --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
5c5c7ca235 |
test: remove 283 low-value tests (#39533)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
068d9ad3fd |
fix(plugins): keep a workspace-scoped panel edit made just before a workspace switch (#39413)
* fix(plugins): keep a workspace-scoped panel edit made just before a workspace switch The guest's persist queue holds atoms, not values, and the renderer stored each ui.persist under whichever workspace was active when it arrived. An edit made less than 0.4 s before a switch was flushed after the new workspace's hydrate, so workspace B's value was written under B and A's edit was lost. The host now names each ui.hydrate; the guest flushes pending writes before applying the next hydrate and tags ui.persist with the hydration its values came from, and the renderer stores the write under that hydration's workspace. (STA-13316) * test(plugins): cover workspace-persist hydration routing edge cases and add switch e2e Adds unit coverage for A->B->A routing, legacy (no hydration) persists, the eight-hydration window, plugin-scope entries, and guest flush/tagging; adds an Electron e2e that types in workspace A, switches inside the persist debounce, and checks both workspaces after switching back and after the panel's guest is recreated. Regenerates orca-testing.mjs after rebasing on main. |
||
|
|
31fb68b669 | test: remove 47 low-value test declarations (#37860) | ||
|
|
39d02ae0bc | test: remove 49 low-value test declarations (#37856) | ||
|
|
36f17a04a7 |
plugins: Box layout container for components panels (catalog 4) (#37420)
- Box (ui.catalog 4, since 1.4.248): direction, gap/padding/paddingX/ paddingY/margin on the gap scale, align, justify, wrap, grow, shrink, width/height/min/max (px up to 4096 or whole percents), columns, scroll, border (true or a tone), radius, background (theme surfaces or tone tints). Strict props: hex colours, CSS lengths and unknown props are dropped with a warning like other components. - Renderer maps props to theme tokens through data attributes; sizes reach inline style only as validated px or percents. - Typings, docs, skill references, gallery Layout tab; orca/testing finds Boxes and summarizes danger or warning Boxes. |
||
|
|
5846caf2ba |
plugins: editor.save.before hook (format on save, or refuse the save) (#37347)
* plugins: editor.save.before hook (format on save, or refuse the save) Explicit saves of text files from an editor tab run plugins' editor.save.before in main before the write (local, SSH, WSL and folder workspaces all save through that one renderer path). A plugin can return changed text or deny with a reason, shown in the save error. The buffer takes the hook's text only if it is unchanged since the hook started; edits made meanwhile stay dirty. Autosave, restart saves and bytes documents are not hooked, and with no live plugin listing the hook the save path adds no await. Co-Authored-By: Claude <noreply@anthropic.com> * test(plugins): editor.save.before text reaches the visible Monaco model The hook writes its text into the tab's draft, which reaches the model through the same content-sync bridge as Reload from disk. A model-level test covers the formatted text showing, the next keystroke editing it, and edits typed during the hook staying in the model. Co-Authored-By: Claude <noreply@anthropic.com> * plugins: editor.save.before review fixes: flush held typing, update the surviving view, keep the denial - After the hook answers, pending view text (rich Markdown's serialize timer) is flushed before deciding whether the buffer still holds the hook's input. - The hook's text goes to whichever view of the buffer record is still open, so closing the saving view keeps a sibling view in step with disk. - The save-request bridge passes Errors through whole, so the toast shows the plugin and its reason instead of a generic failure. Co-Authored-By: Claude <noreply@anthropic.com> * chore(plugins): regenerate after rebasing the save hook on main --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
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. |
||
|
|
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>
|
||
|
|
263d3b16aa |
test: remove 104 low-value test declarations (#37290)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
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.
|
||
|
|
ce8ea081c0 |
Plugin check shows what drew; responsive Table columns; quieter Table and Stack (#37062)
* plugins: check shows what drew; responsive Table columns; quieter Table and Stack
- orca plugin check: each scenario result carries a summary (headings,
callouts, empty states, table and tree sizes, the selected tab, loading
placeholders, danger/warning text), printed under its line, and --json
adds the drawn tree. dev watch's check event keeps only the summary.
orca/testing gains panel.summary().
- Table columns take minWidth (floor for an auto column) and hideBelow
('sm' 360px, 'md' 480px), measured on the table itself; at least one
column stays. Cut-off cells and headers show their text on hover. The
kit's columnsOf(table, { width }) answers which columns fit.
- The active-row ring shows only while the grid has keyboard focus.
- A Stack with no align keeps buttons at their own width while fields,
tables and cards still fill it; align='stretch' stretches everything.
- Typings, docs, the skill's workflow reference, regenerated references;
the gallery's Kind column drops out in a narrow sidebar.
* plugins: check can render one scenario and return its drawn tree
For orca plugin shot --scenario (tree replay): checkPluginPanels takes
{ panel, scenario, drawnTree }, and with drawnTree returns each render's
validated tree exactly as Orca draws it (handlers as { $callback }),
re-validated on the CLI side. An unknown scenario is reported as an issue.
readPluginCheckScenarioNames(dir, entry) lists a panel's scenarios by
loading its .check file without mounting anything.
|
||
|
|
2666bbddbe |
Plugin dev loop: dev request, shot --act, worker-panel template, output polish (#37049)
* feat(plugins): orca plugin dev request; --template worker-panel - orca plugin dev request <dir|key> <name> [--data] [--panel] [--timeout-ms] calls a dev plugin's orca.panels.handle handler through the real panel bridge (plugins.devRequest) and prints the answer; handler errors become plugin_request_failed with the worker's code. - orca plugin create --template worker-panel scaffolds a build-less trusted-worker plugin: a components panel, src/worker.ts, a shared src/protocol.ts contract, and panel and worker tests that pass under orca plugin test and type-check with tsc. * feat(plugins): shot --act, shots in the plugin folder, quieter logs - orca plugin shot --act '<json>' presses, types, selects and toggles in the live components panel (the test kit's queries and acts, through Orca's own controls and onEvent) before the capture, waiting for each to settle. Only that plugin's panel, only with Orca's window hidden or minimized; html panels refused; acts are not user gestures. Results in actions[]. - shot run inside a plugin folder defaults to its .orca/shots, like dev watch --shot. - dev watch prints identical [frame] lines once per reload with a count; logged stacks drop <anonymous>/native frames; the floating workspace button hides during a capture. - Skill: worker-panel template in the decision table, dev request, shot --act, and a gotcha that a worker save drops its in-memory state. |
||
|
|
8503ecda71 |
plugins: check runs the worker and scenarios; RelativeTime (#37047)
- orca plugin check mounts the plugin's worker (main) on the same mock host
as each panel, so plugin.request reaches its orca.panels.handle handlers
as in Orca; a worker that fails to activate or deactivate is an issue
named after its file. In orca/testing, a worker mounted on a host answers
that host's panel requests unless `requests` stubs the name.
- Check scenarios: <entry>.check.ts (e.g. src/panel.check.ts) exports
defineCheck({ name: { ...mockHost options, persisted, theme, events } });
check renders the panel once per scenario and labels each result.
- RelativeTime (catalog 3, since 1.4.247) and { type: 'relative', at } Table
cells: Orca ticks them (each second under a minute, then less often), so
plugins never poll. Inline inside Text; test kit reads them as drawn.
- Typings, docs, skill guide, generated references; gallery shows it.
|
||
|
|
e5b87cb8e6 |
Components catalog 2 and worker tests: forms, tabs, table, tree, markdown, code, images (#36997)
* plugins: components catalog 2 (forms, tabs, table, tree, markdown, code, images)
Adds 18 components to TSX components panels, drawn with Orca's own
primitives and gated by ui.catalog 2 / ui.has() (Orca 1.4.247):
Textarea, Checkbox, RadioGroup, Slider, Field, Tabs/Tab, Collapsible,
Toolbar, Grid, a virtualized Table with sort, selection and pull-based
paging, a keyboard Tree with lazy children, Markdown (sanitized, links
through the checked open path), CodeView (Orca's highlighter), Image
(header-checked plugin files read by main), KeyValue, Callout and
Skeleton, plus a tooltip prop on Button and IconButton.
Value controls share the edit protocol; handlers get plain JSON event
args, including small objects ({ keys }, { key, expanded }). The test kit
gains matching actions and hides unselected tabs and closed collapsibles;
a components-gallery example and e2e cover the catalog end to end.
* plugins: worker test harness, host refusals in tests and check
- orca/testing gains mountWorker(main, { host, events, commands }): it calls
the default-exported activate(orca) with the orca object Orca itself builds
(createPluginWorkerOrcaApi, moved to shared so the kit reuses it), backed by
mockHost. emit() checks payloads against Orca's event schemas and only
delivers subscribed events; command(), request() (the worker's
orca.panels.handle, as a panel's plugin.request), posts, logs, refusals and
deactivate(). Storage and settings share the mock host's in-memory store.
- orca plugin test loads a worker main's module graph as Orca's worker host
does (.ts/.mts transform, Node resolution, no runtime orca import).
- mockHost records refusals (capability_denied, not_permitted, ...) even
when plugin code catches them; panel.refusals exposes them and
orca plugin check reports them as warnings. Check dedupes repeated issues.
- Typings, docs and a generated references/testing.md skill reference; the
reference generator reads the split orca typings.
|
||
|
|
1392c8e894 |
Plugin dev loop: orca plugin open/shot, dev emit, and dogfood fixes (#37008)
* feat(plugins): orca plugin open and shot; dev watch --shot - orca plugin open <key> [--panel|--editor] shows a panel in the right sidebar or a file in the plugin's custom editor, by changing renderer state only (no focus or window raise). - orca plugin shot <key> [--panel] [--theme] [--width] [--out] [--json] waits for the panel's current code to draw, then crops webContents.capturePage to the panel (html guests included), with background throttling off while hidden. --width and --theme are temporary in-memory overrides; the PNG returns base64 (5 MiB cap), so --environment works. - dev watch --shot <dir> writes a PNG per panel after the load and each good reload. - The authoring skill's loop is now dev watch --check --shot → read the PNG → plugin test. * fix(plugins): shots never disturb a visible Orca - shot --theme is skipped while the Orca window is on screen (themeApplied: false with a themeReason); the override applies only to a hidden or minimized window. - dev watch --shot opens the first panel (or --shot-panel <id>) once, then shoots it with ifShown: if the user moved the sidebar away it emits one shot_skipped instead of switching. * fix(plugins): dev loop dogfood fixes; orca plugin dev emit - dev watch: approval re-run command drops watch-only flags and old --approve; a folder added by a refused load is owned by the next approved load (Ctrl-C unloads it); check events carry the plugin's status (no green while pending/errored); reloaded prints before that reload's logs; --json errors are one NDJSON line. - Errors: log, banner and check share source-mapped positions (a line-1 prelude hands sucrase mappings to the components runtime); check dedupes issues and locates syntax errors; Orca runtime frames and the error module's bogus location are dropped from logs. - .orca/types tsconfig sets preserveSymlinks (tsc 7 loaded typings twice under /tmp). - Templates' READMEs use dev watch. - orca plugin dev emit <dir|key> <event> [--data] sends a test event to a dev plugin's worker through the real delivery rules (plugins.devEmit). * test(plugins): fixed timestamp in the dev emit test * fix(plugins): shot captures an html panel's guest itself On Linux the main window's capturePage leaves a <webview> guest blank. The renderer now reports the guest's rect, and main captures the guest's own webContents and draws it over the window capture at that rect (raw bitmaps, nativeImage only). Components panels are drawn by the host, so the window capture alone stays right for them. * refactor(plugins): keep plugin-service and main-process-plugins under max-lines After rebasing onto #37013 both files crossed 300 lines. The guest log sink moves into the desktop view binding (bindPluginDesktopViews), and plugin-service tightens emitEvent and its event-delivery imports. |
||
|
|
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.
|
||
|
|
b17d408416 |
Plugin dev loop: TS workers, hot reload with state, orca plugin dev watch, authoring skill (#36982)
* feat(plugins): build-less TypeScript workers A worker's main may be .ts/.mts. The plugin host installs module.registerHooks scoped to the plugin folder: .ts files are transpiled with the frames' sucrase options (lines kept, inline source map, source maps on), relative imports fall back to the frames' candidate files, and a value import of the type-only 'orca/worker' fails with a clear error. Needs engines.orca >=1.4.246. * feat(plugins): components panels hot reload with their state - In dev folders a save swaps only the hidden guest: keyed memory atoms are handed to the new guest (ui.retain → ui.hydrate memory), dropped when an atom's version changes. - A save that fails to load keeps the last good render and shows an inline file:line:col error banner; the next good save clears it. A subtle Reloaded mark follows a reload. - Transpile and import errors carry line and column; dev worker restarts keep storage. * feat(plugins): orca plugin dev watch One command for the inner loop: refreshes .orca/types, dev-loads the folder, follows its frame and worker logs (plugins.getLogs gains an optional cursor), prints reloads (optional devChangeCount on list entries) and status changes, and unloads on Ctrl-C. --json streams NDJSON events for agents. * feat(skills): orca-plugin-authoring bundled skill guide A guide for agents to build Orca plugins end to end (decision table, build-less rules, the dev watch loop, test/check, validate, release-entry, approvals, gotchas) with references generated from the component catalog, host API table, event schemas, manifest schema and CLI specs, checked for drift. Fixes the components template's Reset to set(count, 0). * feat(plugins): orca plugin dev watch --check; test kit details in the authoring skill - --check runs orca plugin check after the load and after each reload (one at a time; saves made meanwhile fold into one rerun) and prints each panel's render or errors inline, as a `check` event with --json. Local folders only, since it runs the plugin's code here. - The orca-plugin-authoring guide's Test and check section now documents orca plugin test and check from #36969 exactly (JSON results, exit codes, test placement, the orca/testing kit and its common mistakes), and the loop uses dev watch --check. * refactor(plugins): move the components renderer's timing and helper constants to their own module |
||
|
|
531658f1d1 |
Plugin test kit: orca/testing, orca plugin test and orca plugin check (#36969)
* feat(plugins): orca/testing kit, `orca plugin test` and `orca plugin check` - `orca/testing` mounts a components panel in plain Node (node:test, vitest, bun) with the real runtime and Orca's own tree validator: find by text/role/label/testId, press/type/submit/toggle/ select that resolve once the panel settles, tree() snapshots, errors (with stacks) and warnings, persisted state (with stored() for migrations), emit/setVisible/rerender, and unmount running setup cleanup. It re-exports node:test and strict assert so tests type-check without @types/node. - mockHost refuses what Orca refuses with the same codes (surface, capability from the manifest, params, a gesture method without a press), checks configured results against the host API, and records calls. - `orca plugin test [dir]` discovers *.test.ts(x) and runs them with node:test through Node module hooks that resolve `orca` like the guest's import map and transpile/resolve sources exactly as Orca's build-less loader, or with the plugin's own vitest via a generated config. - `orca plugin check [dir]` validates, then renders each components panel once and reports what it threw (file:line), layouts Orca would refuse, and props it would drop. - The kit, hooks and register entry ship minified beside orca-runtime.mjs and are unpacked from asar; typings land in .orca/types/orca-testing. The components template and hello-tsx get sample tests. - ui.error carries an optional stack; a new runtime starts every atom from its initial value; the hydration fallback timer is cleared once hydrated. * plugins: run plugin test/check on a system Node or Orca's own, and warn they are unsandboxed * test(plugins): run the shipped example plugin tests from the unit suite |
||
|
|
4ee788a725 |
Build-less TS/TSX plugins, typings and authoring tools (#36918)
* feat(plugins): build-less TS/TSX plugins, typings and authoring tools - Plugin frames transpile .ts/.tsx/.mts/.jsx on load (sucrase on a shared worker thread with a 2 s budget, cached in main), resolve relative imports to exact files, and refuse bare package imports by name. Components and html panel/editor entries may be .ts/.tsx. - orca plugin types writes typings for the components orca module, window.orca, worker activate(orca), host.call and events into .orca/types, from one host-typings generator. - orca plugin create --template components; templates omit publisher and target 1.4.246. - orca plugin release-entry, dev inspect and restart; validate:plugin checks named files. - Guest console errors reach orca plugin logs; dev workers restart on edits; the dev watcher ignores .git, .orca and node_modules; Git and folder installs cannot replace catalog installs. - examples/plugins/hello-tsx, docs, and the plugin-buildless-tsx e2e spec. * ci: run the Windows parity probes with one tsgo checker tsconfig.node peaks near 22 GB with tsgo's default four checkers (each holds its own types) and about 16 GB with one; the 16 GB Windows runner paged the native probe past its 900 s timeout once this branch's package.json change triggered the job. One checker gives the same diagnostics (verified locally with --parity-only); the timing benchmark is unchanged. |
||
|
|
7df246b9d1 | feat(plugins): components (TSX) plugin panels (#36814) |