{"data":{"skill":{"slug":"vercel-labs-agent-desktop","name":"agent-desktop","icon":"📦","repo":"https://github.com/vercel-labs/agent-desktop/tree/5261b5287b5208e7c4bf3713df6f66faaaf2c4cc/skills/agent-desktop","status":"approved","author":"vercel-labs","authorVersion":null,"skillstoreRevision":1},"audit":{"id":"6efbf84b-7a78-4a52-83be-85d655debdee","skill_id":"cb6292d7-75fd-46b3-b814-682bad5207dd","version":1,"content_hash":"v3:443e0d99cb0af7754aabaecc5bf8b6dcf2dae44d:359140fc5ede5ba29c54c24b4bb4eae374f65ecc883a83404cb7f96dc5edc3b9:b328acda88308da904e5ff151f450ccdab5ce12259d31b5d02ec217e2a42fca8:736b696c6c732f76657263656c2d6c6162732f6167656e742d6465736b746f70:5b8baca0d936dda7e84547be9bc6aa59","risk_level":"medium","is_blocked":false,"safe_to_publish":true,"analysis_status":"ok","agent_auto_install_policy":"allowed","manual_install_policy":"allowed","summary":"All 67 static findings are benign documentation matches, including Markdown backticks, keystroke delivery, local session storage, and loopback CDP endpoints. One semantic finding concerns pointer dispatch after inconclusive hit tests, which can misdirect input despite visibility checks. No evidence found of credential theft, covert keylogging, external exfiltration, or audit-directed prompt injection in the five reviewed files.","remediation":[{"issue":"Pointer delivery proceeds when the receives_events hit test is inconclusive.","severity":"medium","suggestion":"Reject unknown hit-test results before pointer dispatch, or require explicit user confirmation after presenting the target and uncertainty."}],"risk_factor_evidence":[{"factor":"external_commands","evidence":[{"file":"references/commands-system.md","line_end":171,"line_start":171},{"file":"references/workflows.md","line_end":187,"line_start":187},{"file":"references/workflows.md","line_end":188,"line_start":188},{"file":"SKILL.md","line_end":20,"line_start":20},{"file":"SKILL.md","line_end":24,"line_start":24},{"file":"SKILL.md","line_end":28,"line_start":28},{"file":"SKILL.md","line_end":29,"line_start":29},{"file":"SKILL.md","line_end":30,"line_start":30},{"file":"SKILL.md","line_end":34,"line_start":34},{"file":"SKILL.md","line_end":41,"line_start":36},{"file":"SKILL.md","line_end":43,"line_start":41},{"file":"SKILL.md","line_end":44,"line_start":43},{"file":"SKILL.md","line_end":44,"line_start":44},{"file":"SKILL.md","line_end":46,"line_start":45},{"file":"SKILL.md","line_end":46,"line_start":46},{"file":"SKILL.md","line_end":50,"line_start":50},{"file":"SKILL.md","line_end":54,"line_start":53},{"file":"SKILL.md","line_end":54,"line_start":54},{"file":"SKILL.md","line_end":59,"line_start":55},{"file":"SKILL.md","line_end":59,"line_start":59},{"file":"SKILL.md","line_end":61,"line_start":61},{"file":"SKILL.md","line_end":63,"line_start":62},{"file":"SKILL.md","line_end":63,"line_start":63},{"file":"SKILL.md","line_end":64,"line_start":64},{"file":"SKILL.md","line_end":69,"line_start":65},{"file":"SKILL.md","line_end":69,"line_start":69},{"file":"SKILL.md","line_end":77,"line_start":73},{"file":"SKILL.md","line_end":77,"line_start":77},{"file":"SKILL.md","line_end":79,"line_start":78},{"file":"SKILL.md","line_end":79,"line_start":79},{"file":"SKILL.md","line_end":24,"line_start":24},{"file":"SKILL.md","line_end":24,"line_start":24},{"file":"SKILL.md","line_end":24,"line_start":24}]},{"factor":"network","evidence":[{"file":"references/commands-system.md","line_end":33,"line_start":33},{"file":"references/commands-system.md","line_end":33,"line_start":33},{"file":"references/commands-system.md","line_end":34,"line_start":34}]},{"factor":"filesystem","evidence":[{"file":"references/commands-system.md","line_end":110,"line_start":110},{"file":"references/commands-system.md","line_end":168,"line_start":168},{"file":"references/commands-system.md","line_end":110,"line_start":110},{"file":"references/commands-system.md","line_end":168,"line_start":168},{"file":"references/commands-system.md","line_end":10,"line_start":10},{"file":"references/commands-system.md","line_end":102,"line_start":102},{"file":"references/commands-system.md","line_end":104,"line_start":104},{"file":"references/commands-system.md","line_end":105,"line_start":105}]}],"critical_findings":[],"high_findings":[],"medium_findings":[{"title":"Pointer Delivery Proceeds After Inconclusive Hit Tests","locations":[{"file":"references/commands-interaction.md","line_end":74,"line_start":71}],"confidence":0.95,"description":"The documentation states that receives_events fails open when a hit test is inconclusive. Pointer input can reach an obscuring control or window, causing unintended actions or disclosure of typed data.","review_kind":"security","source_category":"semantic","source_severity":"medium","confidence_reasoning":"The reference explicitly states that unknown hit-test results still dispatch input. The implementation was not supplied, so this finding concerns documented behavior."}],"low_findings":[],"dangerous_patterns":[],"files_scanned":5,"total_lines":846,"audit_model":"codex","audited_at":"2026-10-31T14:11:33.437+00:00","created_at":"2026-10-31T16:10:24.085384+00:00","static_findings":[{"id":"sensitive:references/commands-interaction.md:106:certificate-key-files","file":"references/commands-interaction.md","pattern":"Certificate/key files","snippet":"- `type --interval-ms N` (1 to 2000) types one keystroke every N ms inside one command; `--timeout-m","category":"sensitive","line_end":106,"severity":"high","line_start":106},{"id":"blocker:references/commands-interaction.md:104:keylogger-keywords","file":"references/commands-interaction.md","pattern":"Keylogger keywords","snippet":"- `type` inserts text and checks the result when value and selection are readable. A readable mismat","category":"blocker","line_end":104,"severity":"critical","line_start":104},{"id":"blocker:references/commands-interaction.md:106:keylogger-keywords","file":"references/commands-interaction.md","pattern":"Keylogger keywords","snippet":"- `type --interval-ms N` (1 to 2000) types one keystroke every N ms inside one command; `--timeout-m","category":"blocker","line_end":106,"severity":"critical","line_start":106},{"id":"blocker:references/commands-interaction.md:48:system-reconnaissance","file":"references/commands-interaction.md","pattern":"System reconnaissance","snippet":"| `SNAPSHOT_NOT_FOUND` | Snapshot id missing or expired | Snapshot again |","category":"blocker","line_end":48,"severity":"low","line_start":48},{"id":"blocker:references/commands-interaction.md:148:system-reconnaissance","file":"references/commands-interaction.md","pattern":"System reconnaissance","snippet":"- `press` reports `delivered_unverified`, because delivery does not prove the shortcut did its job. ","category":"blocker","line_end":148,"severity":"low","line_start":148},{"id":"blocker:references/commands-interaction.md:182:system-reconnaissance","file":"references/commands-interaction.md","pattern":"System reconnaissance","snippet":"- `drag --timeout-ms` covers the whole gesture as well as target preparation. An explicit `--duratio","category":"blocker","line_end":182,"severity":"low","line_start":182},{"id":"blocker:references/commands-observation.md:14:system-reconnaissance","file":"references/commands-observation.md","pattern":"System reconnaissance","snippet":"agent-desktop snapshot --app \"App\" --window-id w-1234 -i","category":"blocker","line_end":14,"severity":"low","line_start":14},{"id":"external_commands:references/commands-system.md:171:shell-command-substitution","file":"references/commands-system.md","pattern":"Shell command substitution","snippet":"export AGENT_DESKTOP_SESSION=\"$(agent-desktop session start --name \"invoice-bot\" | jq -r '.data.sess","category":"external_commands","line_end":171,"severity":"medium","line_start":171},{"id":"network:references/commands-system.md:33:hardcoded-url","file":"references/commands-system.md","pattern":"Hardcoded URL","snippet":"{ \"app\": \"Obsidian\", \"pid\": 4821, \"cdp\": { \"port\": 9229, \"http_endpoint\": \"http://127.0.0.1:9229\",","category":"network","line_end":33,"severity":"low","line_start":33},{"id":"network:references/commands-system.md:33:hardcoded-ip-address","file":"references/commands-system.md","pattern":"Hardcoded IP address","snippet":"{ \"app\": \"Obsidian\", \"pid\": 4821, \"cdp\": { \"port\": 9229, \"http_endpoint\": \"http://127.0.0.1:9229\",","category":"network","line_end":33,"severity":"medium","line_start":33},{"id":"network:references/commands-system.md:34:hardcoded-ip-address","file":"references/commands-system.md","pattern":"Hardcoded IP address","snippet":"\"websocket_url\": \"ws://127.0.0.1:9229/devtools/browser/<id>\", \"product\": \"Chrome/142.0.7444.265\" } }","category":"network","line_end":34,"severity":"medium","line_start":34},{"id":"filesystem:references/commands-system.md:110:hidden-file-in-home-directory","file":"references/commands-system.md","pattern":"Hidden file in home directory","snippet":"- Image bytes go to `--out`, or to a private file under the active session directory (or `~/.agent-d","category":"filesystem","line_end":110,"severity":"high","line_start":110},{"id":"filesystem:references/commands-system.md:168:hidden-file-in-home-directory","file":"references/commands-system.md","pattern":"Hidden file in home directory","snippet":"A session is an on-disk container under `<state root>/sessions/<id>/` with a manifest, snapshot refm","category":"filesystem","line_end":168,"severity":"high","line_start":168},{"id":"filesystem:references/commands-system.md:110:hidden-file-access","file":"references/commands-system.md","pattern":"Hidden file access","snippet":"- Image bytes go to `--out`, or to a private file under the active session directory (or `~/.agent-d","category":"filesystem","line_end":110,"severity":"medium","line_start":110},{"id":"filesystem:references/commands-system.md:168:hidden-file-access","file":"references/commands-system.md","pattern":"Hidden file access","snippet":"A session is an on-disk container under `<state root>/sessions/<id>/` with a manifest, snapshot refm","category":"filesystem","line_end":168,"severity":"medium","line_start":168},{"id":"filesystem:references/commands-system.md:10:temp-directory-access","file":"references/commands-system.md","pattern":"Temp directory access","snippet":"agent-desktop launch \"MyTool\" --arg /tmp/notes.txt --env KEY=VALUE --no-attach","category":"filesystem","line_end":10,"severity":"medium","line_start":10},{"id":"filesystem:references/commands-system.md:102:temp-directory-access","file":"references/commands-system.md","pattern":"Temp directory access","snippet":"agent-desktop clipboard-get --format image --out /tmp/clip.png","category":"filesystem","line_end":102,"severity":"medium","line_start":102},{"id":"filesystem:references/commands-system.md:104:temp-directory-access","file":"references/commands-system.md","pattern":"Temp directory access","snippet":"agent-desktop clipboard-set --image /tmp/a.png","category":"filesystem","line_end":104,"severity":"medium","line_start":104},{"id":"filesystem:references/commands-system.md:105:temp-directory-access","file":"references/commands-system.md","pattern":"Temp directory access","snippet":"agent-desktop clipboard-set --file-url /tmp/a.txt --file-url /tmp/b.txt","category":"filesystem","line_end":105,"severity":"medium","line_start":105},{"id":"blocker:references/commands-system.md:203:keylogger-keywords","file":"references/commands-system.md","pattern":"Keylogger keywords","snippet":"On macOS and Windows, after `type` or `set-value` lands, the overlay draws the agent's caret, a thin","category":"blocker","line_end":203,"severity":"critical","line_start":203},{"id":"blocker:references/commands-system.md:48:system-reconnaissance","file":"references/commands-system.md","pattern":"System reconnaissance","snippet":"Keep these on agent-desktop even with CDP connected: the native menu bar, file dialogs and sheets, w","category":"blocker","line_end":48,"severity":"low","line_start":48},{"id":"blocker:references/commands-system.md:75:system-reconnaissance","file":"references/commands-system.md","pattern":"System reconnaissance","snippet":"agent-desktop focus-window --window-id w-4521","category":"blocker","line_end":75,"severity":"low","line_start":75},{"id":"blocker:references/commands-system.md:131:system-reconnaissance","file":"references/commands-system.md","pattern":"System reconnaissance","snippet":"- **Text.** Selects one app window, then waits for text in that tree. `--count N` waits until exactl","category":"blocker","line_end":131,"severity":"low","line_start":131},{"id":"blocker:references/commands-system.md:133:system-reconnaissance","file":"references/commands-system.md","pattern":"System reconnaissance","snippet":"- **Event.** `--event` is one of `window-opened`, `window-closed`, `app-launched`, `app-terminated`,","category":"blocker","line_end":133,"severity":"low","line_start":133},{"id":"blocker:references/commands-system.md:175:system-reconnaissance","file":"references/commands-system.md","pattern":"System reconnaissance","snippet":"- `session start` creates the session and prints `{ session_id, name, trace, created_at }`. `--name`","category":"blocker","line_end":175,"severity":"low","line_start":175},{"id":"blocker:references/commands-system.md:198:system-reconnaissance","file":"references/commands-system.md","pattern":"System reconnaissance","snippet":"- `--image` and `--pointer-image` take a PNG of at most 2 MiB and 1024 pixels per side, drawn at `--","category":"blocker","line_end":198,"severity":"low","line_start":198},{"id":"blocker:references/commands-system.md:205:system-reconnaissance","file":"references/commands-system.md","pattern":"System reconnaissance","snippet":"Multi-agent cursors (macOS and Windows): start with `session start --cursor --multi-agent`, then pas","category":"blocker","line_end":205,"severity":"low","line_start":205},{"id":"blocker:references/commands-system.md:207:system-reconnaissance","file":"references/commands-system.md","pattern":"System reconnaissance","snippet":"- Desktop UI actions then require an agent id: global `--agent-id <id>` or `AGENT_DESKTOP_AGENT_ID`.","category":"blocker","line_end":207,"severity":"low","line_start":207},{"id":"blocker:references/commands-system.md:208:system-reconnaissance","file":"references/commands-system.md","pattern":"System reconnaissance","snippet":"- An id has 1 to 64 letters, digits, `-` or `_`. It is scoped by session. Each distinct id gets its ","category":"blocker","line_end":208,"severity":"low","line_start":208},{"id":"blocker:references/commands-system.md:210:system-reconnaissance","file":"references/commands-system.md","pattern":"System reconnaissance","snippet":"- `--agent-id <id> cursor-overlay enable` saves a style for that agent. Do not add `--multi-agent` t","category":"blocker","line_end":210,"severity":"low","line_start":210},{"id":"external_commands:references/workflows.md:187:shell-command-substitution","file":"references/workflows.md","pattern":"Shell command substitution","snippet":"session_start=$(agent-desktop session start --name \"invoice-bot\")","category":"external_commands","line_end":187,"severity":"medium","line_start":187},{"id":"external_commands:references/workflows.md:188:shell-command-substitution","file":"references/workflows.md","pattern":"Shell command substitution","snippet":"AGENT_DESKTOP_SESSION=$(printf '%s\\n' \"$session_start\" | jq -er '.data.session_id')","category":"external_commands","line_end":188,"severity":"medium","line_start":188},{"id":"blocker:references/workflows.md:132:system-reconnaissance","file":"references/workflows.md","pattern":"System reconnaissance","snippet":"agent-desktop focus-window --window-id w-5678","category":"blocker","line_end":132,"severity":"low","line_start":132},{"id":"blocker:references/workflows.md:133:system-reconnaissance","file":"references/workflows.md","pattern":"System reconnaissance","snippet":"agent-desktop snapshot --app \"Finder\" --window-id w-5678 -i","category":"blocker","line_end":133,"severity":"low","line_start":133},{"id":"blocker:references/workflows.md:184:system-reconnaissance","file":"references/workflows.md","pattern":"System reconnaissance","snippet":"This example uses `jq` to read the session id returned by `session start`.","category":"blocker","line_end":184,"severity":"low","line_start":184},{"id":"external_commands:SKILL.md:20:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"agent-desktop is a CLI that lets an AI agent observe and operate desktop apps through the OS accessi","category":"external_commands","line_end":20,"severity":"medium","line_start":20},{"id":"external_commands:SKILL.md:24:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Examples use a POSIX shell. In PowerShell, quote every ref (`'@s8f3k2p9:e1'`), because a bare `@toke","category":"external_commands","line_end":24,"severity":"medium","line_start":24},{"id":"external_commands:SKILL.md:28:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"1. Run `agent-desktop status`. It reports the platform, permissions and `supported_surfaces`.","category":"external_commands","line_end":28,"severity":"medium","line_start":28},{"id":"external_commands:SKILL.md:29:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"2. Run `agent-desktop skills get platform`. It loads the skill for the OS the binary runs on (macOS,","category":"external_commands","line_end":29,"severity":"medium","line_start":29},{"id":"external_commands:SKILL.md:30:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"3. For flags and syntax, run `agent-desktop <command> --help`. This skill does not repeat flag lists","category":"external_commands","line_end":30,"severity":"medium","line_start":30},{"id":"external_commands:SKILL.md:34:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Use `find` when you know the role or exact name. Otherwise map the app first and drill into one regi","category":"external_commands","line_end":34,"severity":"medium","line_start":34},{"id":"external_commands:SKILL.md:36:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":41,"severity":"medium","line_start":36},{"id":"external_commands:SKILL.md:41:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":43,"severity":"medium","line_start":41},{"id":"external_commands:SKILL.md:43:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- A small app needs no skeleton. Take a full `snapshot -i`.","category":"external_commands","line_end":44,"severity":"medium","line_start":43},{"id":"external_commands:SKILL.md:44:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Never skeleton a surface (`--surface menu`, `sheet`, `alert`). A surface is already focused.","category":"external_commands","line_end":44,"severity":"medium","line_start":44},{"id":"external_commands:SKILL.md:45:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- An action that opens a menu, sheet or alert lists it in `data.surfaces`. Target that overlay next.","category":"external_commands","line_end":46,"severity":"medium","line_start":45},{"id":"external_commands:SKILL.md:46:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- After an async step, use `wait` (see `commands-system.md`). A fixed sleep is a race.","category":"external_commands","line_end":46,"severity":"medium","line_start":46},{"id":"external_commands:SKILL.md:50:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Output refs are qualified: `@<snapshot_id>:e<N>`, for example `@s8f3k2p9:e1`. Pass them to later c","category":"external_commands","line_end":50,"severity":"medium","line_start":50},{"id":"external_commands:SKILL.md:53:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `STALE_REF`: the ref no longer matches the live UI. Take a fresh snapshot and use the new ref.","category":"external_commands","line_end":54,"severity":"medium","line_start":53},{"id":"external_commands:SKILL.md:54:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `AMBIGUOUS_TARGET`: more than one live element matches. Narrow the target with `find --role --name","category":"external_commands","line_end":54,"severity":"medium","line_start":54},{"id":"external_commands:SKILL.md:55:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `SNAPSHOT_NOT_FOUND`: the snapshot id expired. Snapshot again.","category":"external_commands","line_end":59,"severity":"medium","line_start":55},{"id":"external_commands:SKILL.md:59:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Action results carry `data.disposition` and errors carry `error.disposition`, each with `delivery` a","category":"external_commands","line_end":59,"severity":"medium","line_start":59},{"id":"external_commands:SKILL.md:61:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Retry or substitute an action only when `disposition.retry` is `safe`. Only `not_delivered` is saf","category":"external_commands","line_end":61,"severity":"medium","line_start":61},{"id":"external_commands:SKILL.md:62:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Any other delivery value means the action may have landed. A repeat can click, type or submit twic","category":"external_commands","line_end":63,"severity":"medium","line_start":62},{"id":"external_commands:SKILL.md:63:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- On a result that is not safe, read the live state (`get`, `is`, or a fresh snapshot) and decide fr","category":"external_commands","line_end":63,"severity":"medium","line_start":63},{"id":"external_commands:SKILL.md:64:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Branch on `error.code` and `error.disposition`. Message and suggestion text can change.","category":"external_commands","line_end":64,"severity":"medium","line_start":64},{"id":"external_commands:SKILL.md:65:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `details.retryable: false` means waiting cannot change the outcome. Try a different approach.","category":"external_commands","line_end":69,"severity":"medium","line_start":65},{"id":"external_commands:SKILL.md:69:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Ref actions are headless by default. They use semantic accessibility calls and do not take focus, mo","category":"external_commands","line_end":69,"severity":"medium","line_start":69},{"id":"external_commands:SKILL.md:73:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Load one only when you need it: `agent-desktop skills get desktop <reference>`.","category":"external_commands","line_end":77,"severity":"medium","line_start":73},{"id":"external_commands:SKILL.md:77:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| `commands-observation` | You need `snapshot`, `find`, `get`, `is`, `screenshot`, `list-surfaces` s","category":"external_commands","line_end":77,"severity":"medium","line_start":77},{"id":"external_commands:SKILL.md:78:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| `commands-interaction` | You choose between click, type, set-value, select, toggle, scroll, press ","category":"external_commands","line_end":79,"severity":"medium","line_start":78},{"id":"external_commands:SKILL.md:79:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| `commands-system` | You launch or close apps, manage windows, use the clipboard, `wait`, `batch`, ","category":"external_commands","line_end":79,"severity":"medium","line_start":79},{"id":"external_commands:SKILL.md:24:shell-command-substitution","file":"SKILL.md","pattern":"Shell command substitution","snippet":"Examples use a POSIX shell. In PowerShell, quote every ref (`'@s8f3k2p9:e1'`), because a bare `@toke","category":"external_commands","line_end":24,"severity":"medium","line_start":24},{"id":"external_commands:SKILL.md:24:template-literal-with-command-substitution","file":"SKILL.md","pattern":"Template literal with command substitution","snippet":"Examples use a POSIX shell. In PowerShell, quote every ref (`'@s8f3k2p9:e1'`), because a bare `@toke","category":"external_commands","line_end":24,"severity":"medium","line_start":24},{"id":"external_commands:SKILL.md:24:powershell-invocation","file":"SKILL.md","pattern":"PowerShell invocation","snippet":"Examples use a POSIX shell. In PowerShell, quote every ref (`'@s8f3k2p9:e1'`), because a bare `@toke","category":"external_commands","line_end":24,"severity":"high","line_start":24},{"id":"blocker:SKILL.md:51:system-reconnaissance","file":"SKILL.md","pattern":"System reconnaissance","snippet":"- Refs are valid for one snapshot. After any UI change, re-drill the affected region or take a new s","category":"blocker","line_end":51,"severity":"low","line_start":51},{"id":"blocker:SKILL.md:55:system-reconnaissance","file":"SKILL.md","pattern":"System reconnaissance","snippet":"- `SNAPSHOT_NOT_FOUND`: the snapshot id expired. Snapshot again.","category":"blocker","line_end":55,"severity":"low","line_start":55}],"finding_verdicts":[{"id":"sensitive:references/commands-interaction.md:106:certificate-key-files","reason":"The passage describes timed keystroke delivery and focus checks. It contains no certificate paths, private keys, or credential-file access.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/commands-interaction.md:104:keylogger-keywords","reason":"The command sends supplied text and rereads the targeted field to verify delivery. It does not capture unrelated user keystrokes.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/commands-interaction.md:106:keylogger-keywords","reason":"Keystrokes refer to synthetic text input, not keyboard surveillance. Headed typing stops when the target process or focused element changes.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/commands-interaction.md:48:system-reconnaissance","reason":"This error-table row recommends refreshing an expired UI snapshot. It performs no host reconnaissance.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/commands-interaction.md:148:system-reconnaissance","reason":"The passage explains shortcut delivery uncertainty and warns against blind retries. Waiting for the intended UI effect is normal action verification.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/commands-interaction.md:182:system-reconnaissance","reason":"This describes drag duration, timeout validation, and completion budgets. It contains no system enumeration or reconnaissance instructions.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/commands-observation.md:14:system-reconnaissance","reason":"The example scopes an accessibility snapshot to one named app and window. This is the skill's declared observation workflow, not covert reconnaissance.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:references/commands-system.md:171:shell-command-substitution","reason":"Command substitution starts a named local session and parses its identifier with a fixed jq expression. The output becomes data, not executable shell syntax.","verdict":"false_positive","confidence":0.98},{"id":"network:references/commands-system.md:33:hardcoded-url","reason":"The URL is example output for an explicitly requested loopback-only CDP debugging endpoint. It is not an external data destination.","verdict":"false_positive","confidence":0.99},{"id":"network:references/commands-system.md:33:hardcoded-ip-address","reason":"127.0.0.1 is the local host address in a documented CDP response. The surrounding instructions disclose local-process access and recommend limiting exposure.","verdict":"false_positive","confidence":0.99},{"id":"network:references/commands-system.md:34:hardcoded-ip-address","reason":"The WebSocket address is loopback example output with a placeholder browser identifier. No remote collection service or external transmission is specified.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:references/commands-system.md:110:hidden-file-in-home-directory","reason":"The hidden directory is the tool's documented private clipboard-image storage. No unrelated hidden files or credentials are accessed.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:references/commands-system.md:168:hidden-file-in-home-directory","reason":"The tool stores its own session manifests, refmaps, and traces under its declared state root. This is ordinary application state, not stealth persistence.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:references/commands-system.md:110:hidden-file-access","reason":"Clipboard image output uses a documented private application directory unless an output path is supplied. Hidden-directory naming alone does not indicate unauthorized access.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:references/commands-system.md:168:hidden-file-access","reason":"The passage explains the configurable local session-state directory. It neither reads unrelated user configuration nor conceals the storage location.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:references/commands-system.md:10:temp-directory-access","reason":"The temporary notes path is an illustrative argument passed to a named application. No secret harvesting, destructive operation, or automatic execution is shown.","verdict":"false_positive","confidence":0.97},{"id":"filesystem:references/commands-system.md:102:temp-directory-access","reason":"This explicit clipboard-image export writes to an example output path. The documentation shows no covert collection or transfer beyond the local machine.","verdict":"false_positive","confidence":0.96},{"id":"filesystem:references/commands-system.md:104:temp-directory-access","reason":"The example sets the clipboard from a specified local image. Reading that chosen input is expected clipboard functionality, not arbitrary filesystem harvesting.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:references/commands-system.md:105:temp-directory-access","reason":"The example places explicitly named local file references on the clipboard. The following documentation requires those paths to exist and specifies no external transmission.","verdict":"false_positive","confidence":0.98},{"id":"blocker:references/commands-system.md:203:keylogger-keywords","reason":"The optional overlay displays the agent's caret after its own typing actions. It describes visual feedback, not recording the user's keyboard activity.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/commands-system.md:48:system-reconnaissance","reason":"The passage separates native desktop actions from CDP and warns about same-user local access. It recommends closing the app to end exposure, not reconnaissance.","verdict":"false_positive","confidence":0.98},{"id":"blocker:references/commands-system.md:75:system-reconnaissance","reason":"Focusing one explicit window is an ordinary window-management example. It does not enumerate host internals or collect system information.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/commands-system.md:131:system-reconnaissance","reason":"Text waits inspect a selected app and require disambiguation when several windows qualify. The listed commands are scoped UI recovery steps.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/commands-system.md:133:system-reconnaissance","reason":"The event list supports waiting for app and window lifecycle changes. This is declared desktop synchronization, not hidden host reconnaissance.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/commands-system.md:175:system-reconnaissance","reason":"Session identifiers scope the tool's own state across processes. The paragraph documents validation and session selection rather than system discovery.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/commands-system.md:198:system-reconnaissance","reason":"The passage constrains custom cursor PNG size and describes fallback behavior. Local presentation-asset handling is unrelated to reconnaissance.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/commands-system.md:205:system-reconnaissance","reason":"Sharing a session identifier enables documented multi-agent cursor presentation. It does not discover machine identities or gather host information.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/commands-system.md:207:system-reconnaissance","reason":"The agent identifier labels desktop actions inside a session. The environment variable configures the tool rather than extracting system data.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/commands-system.md:208:system-reconnaissance","reason":"This specifies allowed identifier characters and cursor reuse. It is input validation documentation, not enumeration.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/commands-system.md:210:system-reconnaissance","reason":"Saving a per-agent cursor style changes presentation settings only. The command neither inspects system resources nor expands access.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:references/workflows.md:187:shell-command-substitution","reason":"The fixed command starts a local session and captures its response. No dynamic command text, eval, or untrusted executable name is involved.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:references/workflows.md:188:shell-command-substitution","reason":"printf uses a fixed format with quoted session data, and jq extracts the identifier with a fixed query. Captured output is not executed.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/workflows.md:132:system-reconnaissance","reason":"The command focuses a selected window during a multiple-window workflow. This is ordinary desktop control rather than system reconnaissance.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/workflows.md:133:system-reconnaissance","reason":"The snapshot targets the Finder window selected in the preceding step. It illustrates scoped UI observation, not broad host discovery.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/workflows.md:184:system-reconnaissance","reason":"The sentence explains parsing the tool's own session identifier with jq. No system-identification command or reconnaissance target appears.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:20:ruby-shell-backtick-execution","reason":"Backticks mark JSON envelope field names in Markdown prose. They are not Ruby expressions or executable shell substitutions.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:24:ruby-shell-backtick-execution","reason":"Backticks delimit shell syntax examples in documentation. The passage gives quoting guidance and contains no Ruby execution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:28:ruby-shell-backtick-execution","reason":"The inline command checks the tool's platform, permissions, and supported surfaces. Markdown formatting is not backtick command execution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:29:ruby-shell-backtick-execution","reason":"The documented command loads OS-specific skill text bundled with the binary. Inline backticks are Markdown delimiters, not executable Ruby syntax.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:30:ruby-shell-backtick-execution","reason":"The inline example requests command help. Its Markdown backticks do not evaluate code or execute untrusted input.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:34:ruby-shell-backtick-execution","reason":"The word find names the tool's UI search command. Backticks only format the command name within ordinary guidance.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:36:ruby-shell-backtick-execution","reason":"These triple backticks open a Markdown example block showing scoped snapshots and a click. They are not Ruby shell-execution operators.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:41:ruby-shell-backtick-execution","reason":"The triple backticks close the UI workflow example. The adjacent inline snapshot command is documentation, not executable backtick interpolation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:43:ruby-shell-backtick-execution","reason":"The sentence recommends a compact snapshot for a small application. Backticks mark command text and do not execute it.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:44:ruby-shell-backtick-execution","reason":"The inline surface selector describes focused menu and dialog snapshots. It is Markdown syntax, not Ruby or shell execution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:45:ruby-shell-backtick-execution","reason":"Backticks format a response field and the wait command. The paragraph directs attention to open overlays rather than executing dynamic code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:46:ruby-shell-backtick-execution","reason":"The passage recommends event-aware waiting and cites a reference document. Neither inline code span is an execution construct.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:50:ruby-shell-backtick-execution","reason":"The backticks enclose example snapshot-qualified references. These are UI identifiers, not executable shell commands.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:53:ruby-shell-backtick-execution","reason":"The text documents stale-reference and ambiguous-target recovery. Error names and search flags are Markdown code spans, not executable interpolation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:54:ruby-shell-backtick-execution","reason":"The example narrows an ambiguous UI target with role, name, or root filters. No backtick-based execution or untrusted command construction occurs.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:55:ruby-shell-backtick-execution","reason":"Error names and response fields are formatted as inline Markdown code. The passage describes snapshot expiration and delivery metadata.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:59:ruby-shell-backtick-execution","reason":"Backticks identify response fields and disposition values. This is structured-result documentation, not executable code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:61:ruby-shell-backtick-execution","reason":"The paragraph restricts retries to actions known not to have been delivered. Backticks only label the relevant disposition fields and values.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:62:ruby-shell-backtick-execution","reason":"The text warns against duplicate actions and recommends reading live state. Inline command names do not constitute shell execution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:63:ruby-shell-backtick-execution","reason":"The get and is command names identify read-only verification options. Backticks are Markdown formatting, not a dynamic execution mechanism.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:64:ruby-shell-backtick-execution","reason":"The inline spans identify stable error fields for branching. No Ruby expression, shell command, or evaluated input is present.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:65:ruby-shell-backtick-execution","reason":"The passage discusses nonretryable errors and headless action policy. Backticks format field values and flags without executing them.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:69:ruby-shell-backtick-execution","reason":"The text requires explicit user permission for physical input and forbids automatic headed fallback. Its inline flags are ordinary Markdown documentation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:73:ruby-shell-backtick-execution","reason":"The example retrieves a named reference from the tool's bundled skills. Markdown delimiters do not execute commands or load remote scripts.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:77:ruby-shell-backtick-execution","reason":"This table lists observation commands and reference names. Its code spans are labels, not Ruby shell-execution expressions.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:78:ruby-shell-backtick-execution","reason":"The reference table describes interaction and system command topics. Backtick-delimited names contain no executable payload.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:79:ruby-shell-backtick-execution","reason":"The table row lists documented system features, including clipboard, waits, and sessions. Markdown command-name formatting is not code execution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:24:shell-command-substitution","reason":"The literal substitution notation explains shell differences and recommends PowerShell equivalents. It contains no executable command inside the notation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:24:template-literal-with-command-substitution","reason":"This is Markdown prose about POSIX and PowerShell syntax, not a JavaScript template literal. No interpolated command or evaluation exists.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:24:powershell-invocation","reason":"PowerShell is mentioned to explain quoting and environment-variable syntax. The line does not invoke PowerShell, bypass execution policy, or execute a script.","verdict":"false_positive","confidence":0.99},{"id":"blocker:SKILL.md:51:system-reconnaissance","reason":"Refreshing refs after UI changes prevents stale-target actions. The instruction concerns accessibility snapshot validity, not host reconnaissance.","verdict":"false_positive","confidence":0.99},{"id":"blocker:SKILL.md:55:system-reconnaissance","reason":"The line defines an expired-snapshot error and its recovery. It contains no system discovery or information-gathering behavior.","verdict":"false_positive","confidence":0.99}],"semantic_findings":[{"title":"Pointer Delivery Proceeds After Inconclusive Hit Tests","severity":"medium","locations":[{"file":"references/commands-interaction.md","line_end":74,"line_start":71}],"confidence":0.95,"description":"The documentation states that receives_events fails open when a hit test is inconclusive. Pointer input can reach an obscuring control or window, causing unintended actions or disclosure of typed data.","confidence_reasoning":"The reference explicitly states that unknown hit-test results still dispatch input. The implementation was not supplied, so this finding concerns documented behavior."}],"subject_marketplace_commit_sha":"443e0d99cb0af7754aabaecc5bf8b6dcf2dae44d","subject_content_hash":"359140fc5ede5ba29c54c24b4bb4eae374f65ecc883a83404cb7f96dc5edc3b9","subject_tree_hash":"b328acda88308da904e5ff151f450ccdab5ce12259d31b5d02ec217e2a42fca8","subject_plugin_path":"skills/vercel-labs/agent-desktop","audit_payload_hash":"5b8baca0d936dda7e84547be9bc6aa59","confirmed_risk_level":"medium","scanner_version":"3.0.0","policy_version":"skillstore-security-audit-policy-v1","subject":{"marketplaceCommitSha":"443e0d99cb0af7754aabaecc5bf8b6dcf2dae44d","contentHash":"359140fc5ede5ba29c54c24b4bb4eae374f65ecc883a83404cb7f96dc5edc3b9","treeHash":"b328acda88308da904e5ff151f450ccdab5ce12259d31b5d02ec217e2a42fca8","pluginPath":"skills/vercel-labs/agent-desktop","auditPayloadHash":"5b8baca0d936dda7e84547be9bc6aa59"},"scannerVersion":"3.0.0","policyVersion":"skillstore-security-audit-policy-v1"},"auditTranslation":null,"localization":{"requestedLocale":"en","contentLocale":"en","availableLocales":["en"],"fallbackToEnglish":false},"attestation":{"availability":"issued","url":"/api/skills/vercel-labs-agent-desktop/audits/1/attestation","status":"active"},"trust":{"publicState":"public","auditState":"complete","auditCurrentness":null,"confirmedRiskLevel":"medium","confirmedFindingCount":1,"capabilityReviewCount":0,"needsReviewCount":0,"falsePositiveCount":0,"agentAutoInstallPolicy":"allowed","manualInstallPolicy":"allowed","artifactSignatureState":"available","attestationState":"active","verificationState":"not_verified"},"isLatest":true}}