@aryacode/dsh-plugin-arya-computer-use 0.0.0-stage → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE.md +18 -0
- package/README.md +108 -2
- package/client.js +492 -0
- package/cordis.patch.yml +16 -0
- package/docs/PLAN.md +151 -0
- package/icon.svg +6 -0
- package/index.js +622 -0
- package/locale/en.json +6 -0
- package/mcp/activity.mjs +299 -0
- package/mcp/adapter-server.mjs +626 -0
- package/mcp/browser-launcher.mjs +66 -0
- package/mcp/settings.mjs +87 -0
- package/mcp/takeover.mjs +253 -0
- package/package.json +88 -4
- package/scripts/ocr.ps1 +95 -0
- package/scripts/windows-takeover.cs +1190 -0
- package/scripts/windows-takeover.ps1 +25 -0
- package/skills/arya-desktop/SKILL.md +75 -0
package/docs/PLAN.md
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Arya Desktop — computer-use plugin plan (v1)
|
|
2
|
+
|
|
3
|
+
Status: complete plan for review. Engine = `dsh-arya-agent-desktop` (mirror of vercel-labs/agent-desktop v1.2.0, Apache-2.0). Replaces `dsh-computer-use-win` (wincu) completely.
|
|
4
|
+
Decisions locked by user (m00113): full move away from wincu (no coexistence) · Lite must cover app driving + OCR · headless default + per-conversation headed toggle · takeover UI parity (edge glow, status bar, Esc=kill, separate mouse) · publish as KonnectSuite package · safety guards = wincu parity.
|
|
5
|
+
|
|
6
|
+
## 1. What we are building
|
|
7
|
+
|
|
8
|
+
A Cordis bundle `@konnectsuite/dsh-plugin-arya-desktop` that gives DSH first-class computer use:
|
|
9
|
+
|
|
10
|
+
- **Native apps**: driven through Windows UIA via the `agent-desktop` Rust CLI — refs, not pixels. Measured on Windows: snapshot 117 ms, ref action 197 ms, list-apps 38 ms (probes/windows/FINDINGS.md:554). Headless = no pointer movement, no focus stealing.
|
|
11
|
+
- **Web pages**: driven through `agent-browser` (Vercel Labs sibling, `agent-browser mcp` stdio server, same ref model, CDP daemon, profiles/auth for sign-in keeping, `--cdp`/`--auto-connect` to attach to the user's real Chrome/Edge).
|
|
12
|
+
- **OCR**: agent-desktop has **zero OCR** (grep-confirmed). Our adapter adds `arya_ocr` = WinRT OCR (Windows.Media.Ocr) over a screenshot — same engine wincu uses, ported from its `scripts/windows-uia.ps1` approach (MIT).
|
|
13
|
+
- **Takeover UI parity**: edge glow + status bar + global Esc kill (PowerShell helper, adapted from wincu's `windows-takeover.ps1`) + agent-desktop's native **cursor overlay** = the "separate mouse": a presentation-only cursor (click-through topmost window, label pill, caret tracking) that animates to each target while the user's real mouse stays free.
|
|
14
|
+
- **Settings page + chat step rows** (wincu parity, English).
|
|
15
|
+
|
|
16
|
+
## 2. Architecture
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
DSH session ── Host plugin (adapter service)
|
|
20
|
+
├─ settings store (cordis.patch.yml row, wincu pattern)
|
|
21
|
+
├─ driver lock: one conversation drives desktop at a time
|
|
22
|
+
├─ takeover helper process (scripts/takeover.ps1: glow, status bar, global Esc)
|
|
23
|
+
└─ loopback status endpoint (sidebar panel)
|
|
24
|
+
── official MCP bridge
|
|
25
|
+
├─ MCP row `arya_desktop` → node mcp/adapter-server.mjs (our adapter)
|
|
26
|
+
│ ├─ proxies agent-desktop CLI per call (spawns binary, injects --session/--agent-id/--headed)
|
|
27
|
+
│ ├─ custom tools: arya_ocr (scripts/ocr.ps1 WinRT), arya_screenshot→file path,
|
|
28
|
+
│ │ arya_tools (list/load/health/headed), batch guard
|
|
29
|
+
│ └─ per-conversation agent-desktop session + cursor-overlay lifecycle
|
|
30
|
+
└─ MCP row `arya_browser` → agent-browser mcp (web lane, sign-in profiles)
|
|
31
|
+
── Client plugin (Settings→Computer Use page, chat step rows, status panel)
|
|
32
|
+
── Skill row `arya-desktop` (observe-act loop, envelope, safety, Windows gotchas)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Key design facts this rests on (verified in deep dive):
|
|
36
|
+
- DSH mcp-client has **no tool filtering** — every server tool registers as `mcp__<serverName>__<tool>` and all schemas enter every request. Tool-surface control must be server-side → the adapter owns the tool list (wincu Lite-12 precedent).
|
|
37
|
+
- agent-desktop's MCP fixes global flags at server start (no per-call `--session/--headed`) → we do NOT use `agent-desktop mcp` directly; the adapter proxies the CLI and injects per-call flags. (Phase 0 spike may use raw `agent-desktop mcp` for evaluation only.)
|
|
38
|
+
- DSH keeps `structuredContent` programmatic-only (no double token cost); images enter context via attachment store; env scrubbing drops `*KEY|PASSWORD|SECRET|TOKEN*` + ambient `DSH_*` (AGENT_DESKTOP_* vars are safe to set in rows).
|
|
39
|
+
- engines pin `>=0.2.1-rc.3 <0.3.0-0` fits installed DSH 0.2.2-alpha.3.
|
|
40
|
+
|
|
41
|
+
## 3. Tool surface (adapter-owned, wincu-style presets)
|
|
42
|
+
|
|
43
|
+
Lite (default, 14) — superset of wincu Lite 12 (`list_windows, find, click, scroll, type_text, keypress, ocr, screenshot, wait_for, launch_app, batch, tools`):
|
|
44
|
+
|
|
45
|
+
| Our tool | Engine | Notes |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| arya_snapshot | desktop_snapshot | skeleton-first, `--root @ref` drill, `--timeout-ms` for Chromium |
|
|
48
|
+
| arya_find | desktop_find | role/text locators |
|
|
49
|
+
| arya_get / arya_is | desktop_get / desktop_is | element detail + state checks |
|
|
50
|
+
| arya_click | desktop_click | headless semantic |
|
|
51
|
+
| arya_set_value | desktop_set_value | headless text entry (preferred) |
|
|
52
|
+
| arya_type | desktop_type | headed SendInput (auto-requires headed) |
|
|
53
|
+
| arya_press | desktop_press | key chords; `ctrl+c` not `meta+c` |
|
|
54
|
+
| arya_scroll | desktop_scroll / scroll_to | |
|
|
55
|
+
| arya_list_windows | desktop_list_windows | + list_apps |
|
|
56
|
+
| arya_launch | desktop_launch | absolute path or System32 name |
|
|
57
|
+
| arya_wait | desktop_wait | ms/--element/--window/--text/--menu/--event |
|
|
58
|
+
| arya_screenshot | desktop_screenshot `--output` | returns PNG **file path**, bytes stay out of context |
|
|
59
|
+
| arya_ocr | custom (scripts/ocr.ps1, WinRT) | text + word coordinates (SCREEN coords) |
|
|
60
|
+
| arya_tools | adapter | list/load tools, health, headed toggle, session status |
|
|
61
|
+
|
|
62
|
+
Lazy preset: starts with `arya_tools` + snapshot + click (3), loads the rest on demand via `tools/list_changed` (verify DSH re-sync support in Phase 1; fallback = static Lite).
|
|
63
|
+
All preset: full agent-desktop surface (toggle/expand/collapse/select/check, drag, hover, mouse-click --xy, window mgmt, clipboard, notifications, displays, close-app, batch, cursor_overlay, trace) + web lane.
|
|
64
|
+
Web lane tools (second row `arya_browser` → `mcp__arya_browser__*`): open, snapshot, click, fill, press, read, get, tab, dialog, wait, screenshot, cookies, storage, profiles, state — agent-browser's surface, preset-filtered by the same Lite/Lazy policy where its MCP supports filtering (else accept its default set; verify count in Phase 3).
|
|
65
|
+
|
|
66
|
+
## 4. Session + headed model
|
|
67
|
+
|
|
68
|
+
- Host plugin tracks turns; **driver lock**: only one conversation drives the desktop at a time (wincu parity) + agent-desktop's cross-process interaction lock underneath.
|
|
69
|
+
- First desktop call in a conversation → adapter runs `agent-desktop session start` (with `--cursor` when overlay enabled) → session id; every call injects `--session <id> --agent-id <conversation-id>` → refs are namespaced per conversation (no cross-conversation collisions).
|
|
70
|
+
- Turn end / Esc / session end → `cursor-overlay disable` + `session end` (renderer self-reclaims ≤3000 ms; held input released via SIGTERM semantics).
|
|
71
|
+
- **Headless default.** Per-conversation toggle: `arya_tools {operation:"headed", on:true}` — adapter injects `--headed` for that conversation. Skill documents when headed is required: `type`, right-click, double/triple-click, focus, cursor-moving input, notifications, shell surfaces (start-menu/tray/action-center).
|
|
72
|
+
- State root: `AGENT_DESKTOP_HOME=%LOCALAPPDATA%\dsh-plugin-arya-desktop\state` (set in row env).
|
|
73
|
+
|
|
74
|
+
## 5. Takeover UI (parity checklist)
|
|
75
|
+
|
|
76
|
+
| wincu feature | Ours |
|
|
77
|
+
|---|---|
|
|
78
|
+
| Screen edge glow during physical input | takeover.ps1 helper (adapted, MIT) fed by adapter events |
|
|
79
|
+
| Status bar ("DSH is controlling…") | same helper; shows session + headed state |
|
|
80
|
+
| Pointer DSH tag | agent-desktop cursor overlay (separate mouse) + label pill per action (`--label` from step text) |
|
|
81
|
+
| Global Esc = kill | helper listens Esc directly → Host plugin: session end, overlay off, driver lock release, "stopped" status |
|
|
82
|
+
| Reasoning/progress overlay | client plugin chat step rows (human-readable rows from `mcp__arya_desktop__*` events) |
|
|
83
|
+
| Settings page | client plugin: preset (Lite/Lazy/All/Custom), headed default, overlay on/off, glow on/off, browser settings |
|
|
84
|
+
|
|
85
|
+
Overlay cost: ~355 ms per headless action (click 427→782 ms). Setting default: **overlay ON** (user wants the separate mouse); power users can disable for speed.
|
|
86
|
+
|
|
87
|
+
## 6. Safety guards (wincu parity + native)
|
|
88
|
+
|
|
89
|
+
- Elevated/admin windows: UIPI boundary fails closed natively (agent-desktop) — same practical effect as wincu's admin protection; UAC secure desktop unaddressable by both.
|
|
90
|
+
- Occlusion/hidden/disabled targets: agent-desktop actionability checks (stronger than wincu POINT_COVERED: identity corroboration immediately before each write; `AMBIGUOUS_TARGET` refuses identical twins instead of mis-clicking).
|
|
91
|
+
- Foreground borrow-and-return: adapter restores the user's foreground window after headed actions.
|
|
92
|
+
- Batch: native `desktop_batch` + adapter guard (1–20 steps, stop on first error/dialog/new-window, per-step delivery disposition).
|
|
93
|
+
- Blocked system shortcuts (alt+f4, win+l, alt+tab, …) refused natively without `--force`; `--force` not exposed by default.
|
|
94
|
+
- Delivery honesty: `delivered_verified / delivered_unverified / not_delivered` + `retry: safe|unsafe` — skill teaches: never retry unsafe; read `details.post_state`.
|
|
95
|
+
- Destructive-action gate (jev-inspired, in skill): model must `ask_user_question` before destructive steps (delete/send/uncheck-security) — confidence-style rule translated to DSH.
|
|
96
|
+
- Optional setting: require DSH approval for `arya_launch` / close-app / clipboard (off by default = wincu parity).
|
|
97
|
+
|
|
98
|
+
## 7. Packaging + install
|
|
99
|
+
|
|
100
|
+
- Repo `KonnectSuite/dsh-arya-computer-use` (created 2026-11-06, public, alongside the engine mirror).
|
|
101
|
+
- npm package `@aryacode/dsh-plugin-arya-computer-use`, Cordis bundle manifest:
|
|
102
|
+
- Host entry: adapter service (settings store, driver lock, takeover helper spawn/teardown, loopback `GET /plugins/arya/status`).
|
|
103
|
+
- Client entry: settings page + step rows + status panel.
|
|
104
|
+
- Bundle patch: MCP rows `arya_desktop` (`command: node`, `args: [<adapter-server.mjs via packageDir !!js>]`) + `arya_browser` (`command: npx -y agent-browser@<pinned> mcp --session ...`) + skill row `arya-desktop`.
|
|
105
|
+
- deps: `agent-desktop@1.2.0` (pinned; npm ships native win32 x64/arm64 binaries — no Rust toolchain needed), `agent-browser@<pinned>`.
|
|
106
|
+
- scripts: `takeover.ps1`, `ocr.ps1` (standalone powershell.exe processes → FullLanguage, not affected by DSH pwsh sandbox).
|
|
107
|
+
- `engines.dsh: >=0.2.1-rc.3 <0.3.0-0`.
|
|
108
|
+
- Install: `plugin_manager install_bundle` from git URL (npm publish later). First-run: settings page button runs `agent-browser install` (Chrome for Testing download).
|
|
109
|
+
- Migration: wincu stays installed during Phases 0–2; at Phase 3 acceptance, delete row `mcp-dsh-computer-use-win` from `cordis.patch.yml` and uninstall wincu.
|
|
110
|
+
|
|
111
|
+
## 8. Phases + acceptance
|
|
112
|
+
|
|
113
|
+
- **Phase 0 — eval spike (no plugin code, ~1 day)** — ✅ **DONE 2026-11-06/07**: spike row installed via local bundle (raw CLI path form), full `desktop_*` tool set registered, eval battery passed under elevated host (Notepad 19-ref tree, File menu expand, Explorer 184-ref tree, Chrome 100-ref chrome-UI tree with thin page content confirming the CDP-lane need; snapshot 125 ms). User accepted + confirmed elevated-always. Spike removed. Key finding: elevation is the lease fix.
|
|
114
|
+
- **Phase 1 — adapter server** — 🟡 **BUILT + SMOKE-TESTED 2026-11-07**: Lite 16, per-conversation session lifecycle (env-scoped), headed toggle, foreground promotion via headed click, screenshot→file path, WinRT OCR (verified en-US), batch guard, tools entry, skill provider (REA pattern). Full loop test passed (launch→find→type→ocr→session_end). Remaining: in-host install + drive test. Accept: drive Notepad/Explorer headless end-to-end; OCR reads a canvas app; Lite token footprint ≪ wincu All-26.
|
|
115
|
+
- **Phase 2 — takeover + UI**: Host/Client plugins, settings page, step rows, edge glow/status bar/Esc kill, cursor overlay lifecycle, driver lock. Accept: wincu-parity UX, English throughout, Esc stops everything in <1 s.
|
|
116
|
+
- **Phase 3 — web lane + retirement** — ✅ **DONE 2026-11-07**: `arya_browser` row now runs through `mcp/browser-launcher.mjs`, which applies the settings (`browserTools`, `browserProfile`, `browserSession`, `browserStateFile`, `browserCdp`, `browserHeaded`) to `agent-browser mcp`; web step rows use the same toolview/step-row pipeline as desktop. Verified live: core profile (29 tools) through the launcher, page open/read, settings page renders the Web lane section. **wincu retirement already complete** — the profile has no `dsh-computer-use-win` row or dependency, and the bundle list has no wincu entry.
|
|
117
|
+
- **Phase 4 — polish** — 🟡 **IN PROGRESS 2026-11-07**: Lazy preset shipped and verified live (3 tools + `tools {operation:"load"}`; DSH's mcp-client really re-syncs on `notifications/tools/list_changed`). **In-process MCP mounting** shipped: `index.js` resolves the host `@deepseek-ai/dsh-mcp-client` bridge (dev override → bare import → host asar → profile paths) and mounts `arya_desktop` + `arya_browser` with `ctx.plugin`, so `cordis.patch.yml` is a single row with no absolute paths. **Published** `@aryacode/dsh-plugin-arya-computer-use@1.0.0` to npm (public) with a format-1 market index (`index.json`) served from the repo. Remaining: notifications/clipboard/trace surfaces; Esc/resume kill needs one real hardware keypress.
|
|
118
|
+
|
|
119
|
+
## 9. Risks + mitigations
|
|
120
|
+
|
|
121
|
+
- **Elevation required (CONFIRMED Phase 0)**: engine interaction lease `C:\ProgramData\agent-desktop\<SID>\interaction.lock` needs protected DACL `{SY, BA, token user}`; medium-IL token fails `lease_directory_untrusted`. Mitigation: plugin requires elevated host (user's normal mode — wincu runs elevated too); adapter appends explicit "run AryaCode as administrator" hint on that error kind.
|
|
122
|
+
- **`AGENT_DESKTOP_HOME` override fails engine private-DACL check** under `%LOCALAPPDATA%` (inherited AppContainer ACEs) → use engine default `~/.agent-desktop`; adapter keeps its own screenshots dir at `%LOCALAPPDATA%\dsh-plugin-arya-desktop\screenshots`.
|
|
123
|
+
- **Windows foreground lock (CONFIRMED Phase 1)**: headed delivery needs the target frontmost; `focus`/`focus-window`/`AppActivate` all fail from a background process. Working recipe: headed `mouse-click --xy` at target bounds center → then headed input. Adapter `ensureForeground()` does this automatically before `type`.
|
|
124
|
+
- **Snapshots are session-scoped**: refs from session X are `SNAPSHOT_NOT_FOUND` in a call without `AGENT_DESKTOP_SESSION` env. Adapter starts a session per conversation and sets the env on every CLI call.
|
|
125
|
+
- WinUI3/MSIX menus "not detected" (native gap) → OCR fallback + headed `mouse-click --xy`; document in skill.
|
|
126
|
+
- Chromium cold trees read 13× thin (Obsidian 12 vs 165 nodes; settle 10–25 s) → skill mandates `--timeout-ms` + re-snapshot; covered Chromium windows hold the shell → fresh observation after waits.
|
|
127
|
+
- npm lifecycle scripts blocked in AryaCode's Node env → 1.0.2 launcher prints notice; verify binary linking in Phase 0; fallback = vendored binary download in postinstall of our package.
|
|
128
|
+
- ~~DSH dynamic tool re-sync (`tools/list_changed`) unverified~~ **RESOLVED 2026-11-07**: dsh-mcp-client wires `listChanged: { tools: { autoRefresh: false, onChanged: () => refreshTools() } }`, so the Lazy preset works without a restart.
|
|
129
|
+
- ~~npm publish blocked on row paths~~ **RESOLVED 2026-11-07**: the rows are gone; the two lanes mount in-process from `index.js`, so the published tarball needs no absolute paths and no `npx` child (a `.cmd` shim cannot be an MCP stdio child on Windows).
|
|
130
|
+
- Cursor overlay multi-monitor placement unit-tested only → test on user's monitors in Phase 2. `rendered:false` under sandboxed pwsh = renderer unreachable via named pipes (sandbox boundary); expect `true` under unconfined host — verify Phase 2.
|
|
131
|
+
- 56-tool token cost in All preset → Lite default; Lazy when verified.
|
|
132
|
+
- agent-desktop cannot see UIs with no accessibility tree (some games/canvas) → OCR + headed coordinate fallback documented.
|
|
133
|
+
- WinRT OCR needs FullLanguage `powershell.exe` (adapter spawns it directly; sandboxed pwsh is ConstrainedLanguage) + canonical `Await($op, $ResultType)` generic-AsTask pattern (WinRT ops arrive as raw `__ComObject`). Verified working en-US.
|
|
134
|
+
|
|
135
|
+
## 10. Open questions (non-blocking)
|
|
136
|
+
|
|
137
|
+
1. ~~Package name~~ **RESOLVED 2026-11-06**: repo `dsh-arya-computer-use`, npm `@aryacode/dsh-plugin-arya-computer-use`; MCP serverNames stay `arya_desktop` / `arya_browser`.
|
|
138
|
+
2. Cursor overlay default ON (visibility) vs OFF (speed)?
|
|
139
|
+
3. ~~Lite list confirmation (14 tools above)?~~ **RESOLVED 2026-11-07**: Lite 16 shipped in adapter — `snapshot, find, get, is, click, set_value, type, press, scroll, list_windows, launch, wait, screenshot, ocr, batch, tools`.
|
|
140
|
+
4. Publish to public npm, or GitHub-install only?
|
|
141
|
+
|
|
142
|
+
### Overlay behaviour (2026-11-07)
|
|
143
|
+
|
|
144
|
+
- The takeover overlay frames **the app window being driven**, not the monitor edges: `Frame` receives
|
|
145
|
+
the window rect and a surface that grows a pill band above (or below when the window sits at the
|
|
146
|
+
monitor top). Monitor-edge glow remains only as the fallback when no target window is known.
|
|
147
|
+
- The pointer indicator is a **ghost cursor**: a synthetic arrow plus a "DSH" tag drawn where the
|
|
148
|
+
harness acts (element centre from `get <ref> --property bounds`, else the window centre). The real
|
|
149
|
+
cursor is never read, moved or highlighted; background actions report `mechanism: semantic_api`.
|
|
150
|
+
- Channel: adapter writes `control/target.json` -> `mcp/takeover.mjs` sends the `hint` command ->
|
|
151
|
+
overlay re-frames / re-aims. `list-windows` returns a bare array in `data`.
|
package/icon.svg
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
|
2
|
+
<rect x="2" y="2" width="60" height="60" rx="12" fill="#1B2733"/>
|
|
3
|
+
<path d="M20 12 L20 46 L28 38 L34 50 L40 47 L34 36 L44 36 Z" fill="#E8EEF4"/>
|
|
4
|
+
<circle cx="46" cy="18" r="6" fill="#FF3B7B"/>
|
|
5
|
+
<path d="M8 54 h48" stroke="#37C6A0" stroke-width="4" stroke-linecap="round"/>
|
|
6
|
+
</svg>
|