@zenalexa/unicli 0.216.3 → 0.217.3
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/AGENTS.md +7 -6
- package/README.md +67 -19
- package/README.zh-CN.md +44 -16
- package/crates/unicli-atspi/Cargo.toml +47 -0
- package/crates/unicli-atspi/README.md +6 -0
- package/crates/unicli-atspi/src/errors.rs +213 -0
- package/crates/unicli-atspi/src/input.rs +1004 -0
- package/crates/unicli-atspi/src/invoke.rs +1132 -0
- package/crates/unicli-atspi/src/main.rs +130 -0
- package/crates/unicli-atspi/src/refs.rs +24 -0
- package/crates/unicli-atspi/src/screenshot.rs +756 -0
- package/crates/unicli-atspi/src/tree.rs +2319 -0
- package/crates/unicli-shared/Cargo.toml +13 -0
- package/crates/unicli-shared/src/lib.rs +77 -0
- package/crates/unicli-uia/Cargo.toml +29 -0
- package/crates/unicli-uia/README.md +6 -0
- package/crates/unicli-uia/src/errors.rs +179 -0
- package/crates/unicli-uia/src/input.rs +790 -0
- package/crates/unicli-uia/src/invoke.rs +977 -0
- package/crates/unicli-uia/src/main.rs +130 -0
- package/crates/unicli-uia/src/refs.rs +24 -0
- package/crates/unicli-uia/src/screenshot.rs +685 -0
- package/crates/unicli-uia/src/tree.rs +2135 -0
- package/dist/adapters/_electron/desktop-shared.d.ts.map +1 -1
- package/dist/adapters/_electron/desktop-shared.js +13 -0
- package/dist/adapters/_electron/desktop-shared.js.map +1 -1
- package/dist/adapters/_electron/shared.d.ts +1 -0
- package/dist/adapters/_electron/shared.d.ts.map +1 -1
- package/dist/adapters/_electron/shared.js +49 -2
- package/dist/adapters/_electron/shared.js.map +1 -1
- package/dist/adapters/macos/actions.d.ts +9 -0
- package/dist/adapters/macos/actions.d.ts.map +1 -0
- package/dist/adapters/macos/actions.js +55 -0
- package/dist/adapters/macos/actions.js.map +1 -0
- package/dist/browser/bridge.d.ts +5 -1
- package/dist/browser/bridge.d.ts.map +1 -1
- package/dist/browser/bridge.js +86 -23
- package/dist/browser/bridge.js.map +1 -1
- package/dist/browser/cdp-client.d.ts +2 -0
- package/dist/browser/cdp-client.d.ts.map +1 -1
- package/dist/browser/cdp-client.js +7 -0
- package/dist/browser/cdp-client.js.map +1 -1
- package/dist/browser/page.d.ts +2 -0
- package/dist/browser/page.d.ts.map +1 -1
- package/dist/browser/page.js +35 -0
- package/dist/browser/page.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +17 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/approvals.d.ts +3 -0
- package/dist/commands/approvals.d.ts.map +1 -0
- package/dist/commands/approvals.js +123 -0
- package/dist/commands/approvals.js.map +1 -0
- package/dist/commands/browser-operator-runtime.d.ts.map +1 -1
- package/dist/commands/browser-operator-runtime.js +5 -2
- package/dist/commands/browser-operator-runtime.js.map +1 -1
- package/dist/commands/browser-operator.d.ts.map +1 -1
- package/dist/commands/browser-operator.js +182 -38
- package/dist/commands/browser-operator.js.map +1 -1
- package/dist/commands/compute.d.ts +3 -0
- package/dist/commands/compute.d.ts.map +1 -0
- package/dist/commands/compute.js +324 -0
- package/dist/commands/compute.js.map +1 -0
- package/dist/commands/describe.d.ts.map +1 -1
- package/dist/commands/describe.js +20 -1
- package/dist/commands/describe.js.map +1 -1
- package/dist/commands/dispatch.d.ts +3 -0
- package/dist/commands/dispatch.d.ts.map +1 -1
- package/dist/commands/dispatch.js +76 -4
- package/dist/commands/dispatch.js.map +1 -1
- package/dist/commands/doctor-compute.d.ts +38 -0
- package/dist/commands/doctor-compute.d.ts.map +1 -0
- package/dist/commands/doctor-compute.js +376 -0
- package/dist/commands/doctor-compute.js.map +1 -0
- package/dist/commands/lint.d.ts.map +1 -1
- package/dist/commands/lint.js +69 -1
- package/dist/commands/lint.js.map +1 -1
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +4 -0
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/runs.d.ts +3 -0
- package/dist/commands/runs.d.ts.map +1 -0
- package/dist/commands/runs.js +367 -0
- package/dist/commands/runs.js.map +1 -0
- package/dist/core/envelope.d.ts +8 -0
- package/dist/core/envelope.d.ts.map +1 -1
- package/dist/core/envelope.js +1 -0
- package/dist/core/envelope.js.map +1 -1
- package/dist/core/schema-v2.d.ts +2 -2
- package/dist/discovery/aliases.d.ts.map +1 -1
- package/dist/discovery/aliases.js +15 -0
- package/dist/discovery/aliases.js.map +1 -1
- package/dist/discovery/loader.d.ts.map +1 -1
- package/dist/discovery/loader.js +11 -0
- package/dist/discovery/loader.js.map +1 -1
- package/dist/discovery/macos-dynamic.d.ts +58 -0
- package/dist/discovery/macos-dynamic.d.ts.map +1 -0
- package/dist/discovery/macos-dynamic.js +429 -0
- package/dist/discovery/macos-dynamic.js.map +1 -0
- package/dist/discovery/search.d.ts.map +1 -1
- package/dist/discovery/search.js +152 -3
- package/dist/discovery/search.js.map +1 -1
- package/dist/electron-apps.d.ts +1 -0
- package/dist/electron-apps.d.ts.map +1 -1
- package/dist/electron-apps.js +1 -0
- package/dist/electron-apps.js.map +1 -1
- package/dist/engine/approval-store.d.ts +43 -0
- package/dist/engine/approval-store.d.ts.map +1 -0
- package/dist/engine/approval-store.js +193 -0
- package/dist/engine/approval-store.js.map +1 -0
- package/dist/engine/browser/action-evidence.d.ts +30 -0
- package/dist/engine/browser/action-evidence.d.ts.map +1 -0
- package/dist/engine/browser/action-evidence.js +354 -0
- package/dist/engine/browser/action-evidence.js.map +1 -0
- package/dist/engine/browser/evidence.d.ts +85 -0
- package/dist/engine/browser/evidence.d.ts.map +1 -0
- package/dist/engine/browser/evidence.js +373 -0
- package/dist/engine/browser/evidence.js.map +1 -0
- package/dist/engine/browser/session-lease.d.ts +53 -0
- package/dist/engine/browser/session-lease.d.ts.map +1 -0
- package/dist/engine/browser/session-lease.js +100 -0
- package/dist/engine/browser/session-lease.js.map +1 -0
- package/dist/engine/browser/session-lock.d.ts +17 -0
- package/dist/engine/browser/session-lock.d.ts.map +1 -0
- package/dist/engine/browser/session-lock.js +114 -0
- package/dist/engine/browser/session-lock.js.map +1 -0
- package/dist/engine/browser/session-runtime.d.ts +10 -0
- package/dist/engine/browser/session-runtime.d.ts.map +1 -0
- package/dist/engine/browser/session-runtime.js +87 -0
- package/dist/engine/browser/session-runtime.js.map +1 -0
- package/dist/engine/capability-policy.d.ts +50 -0
- package/dist/engine/capability-policy.d.ts.map +1 -0
- package/dist/engine/capability-policy.js +305 -0
- package/dist/engine/capability-policy.js.map +1 -0
- package/dist/engine/executor.d.ts +8 -3
- package/dist/engine/executor.d.ts.map +1 -1
- package/dist/engine/executor.js +9 -2
- package/dist/engine/executor.js.map +1 -1
- package/dist/engine/kernel/execute.d.ts +5 -1
- package/dist/engine/kernel/execute.d.ts.map +1 -1
- package/dist/engine/kernel/execute.js +215 -11
- package/dist/engine/kernel/execute.js.map +1 -1
- package/dist/engine/kernel/types.d.ts +15 -0
- package/dist/engine/kernel/types.d.ts.map +1 -1
- package/dist/engine/operation-policy.d.ts +60 -0
- package/dist/engine/operation-policy.d.ts.map +1 -0
- package/dist/engine/operation-policy.js +364 -0
- package/dist/engine/operation-policy.js.map +1 -0
- package/dist/engine/permission-rules.d.ts +43 -0
- package/dist/engine/permission-rules.d.ts.map +1 -0
- package/dist/engine/permission-rules.js +401 -0
- package/dist/engine/permission-rules.js.map +1 -0
- package/dist/engine/permission-runtime.d.ts +11 -0
- package/dist/engine/permission-runtime.d.ts.map +1 -0
- package/dist/engine/permission-runtime.js +21 -0
- package/dist/engine/permission-runtime.js.map +1 -0
- package/dist/engine/repair/remedies.d.ts +4 -0
- package/dist/engine/repair/remedies.d.ts.map +1 -0
- package/dist/engine/repair/remedies.js +169 -0
- package/dist/engine/repair/remedies.js.map +1 -0
- package/dist/engine/runtime-resource-guard.d.ts +23 -0
- package/dist/engine/runtime-resource-guard.d.ts.map +1 -0
- package/dist/engine/runtime-resource-guard.js +85 -0
- package/dist/engine/runtime-resource-guard.js.map +1 -0
- package/dist/engine/session/args.d.ts +3 -0
- package/dist/engine/session/args.d.ts.map +1 -0
- package/dist/engine/session/args.js +17 -0
- package/dist/engine/session/args.js.map +1 -0
- package/dist/engine/session/compare.d.ts +92 -0
- package/dist/engine/session/compare.d.ts.map +1 -0
- package/dist/engine/session/compare.js +324 -0
- package/dist/engine/session/compare.js.map +1 -0
- package/dist/engine/session/environment.d.ts +4 -0
- package/dist/engine/session/environment.d.ts.map +1 -0
- package/dist/engine/session/environment.js +25 -0
- package/dist/engine/session/environment.js.map +1 -0
- package/dist/engine/session/events.d.ts +24 -0
- package/dist/engine/session/events.d.ts.map +1 -0
- package/dist/engine/session/events.js +78 -0
- package/dist/engine/session/events.js.map +1 -0
- package/dist/engine/session/query.d.ts +47 -0
- package/dist/engine/session/query.d.ts.map +1 -0
- package/dist/engine/session/query.js +299 -0
- package/dist/engine/session/query.js.map +1 -0
- package/dist/engine/session/replay.d.ts +35 -0
- package/dist/engine/session/replay.d.ts.map +1 -0
- package/dist/engine/session/replay.js +144 -0
- package/dist/engine/session/replay.js.map +1 -0
- package/dist/engine/session/run-loop.d.ts +11 -0
- package/dist/engine/session/run-loop.d.ts.map +1 -0
- package/dist/engine/session/run-loop.js +212 -0
- package/dist/engine/session/run-loop.js.map +1 -0
- package/dist/engine/session/store.d.ts +26 -0
- package/dist/engine/session/store.d.ts.map +1 -0
- package/dist/engine/session/store.js +214 -0
- package/dist/engine/session/store.js.map +1 -0
- package/dist/engine/session/types.d.ts +39 -0
- package/dist/engine/session/types.d.ts.map +1 -0
- package/dist/engine/session/types.js +2 -0
- package/dist/engine/session/types.js.map +1 -0
- package/dist/engine/steps/compute.d.ts +41 -0
- package/dist/engine/steps/compute.d.ts.map +1 -0
- package/dist/engine/steps/compute.js +55 -0
- package/dist/engine/steps/compute.js.map +1 -0
- package/dist/engine/steps/desktop-ax.d.ts +8 -0
- package/dist/engine/steps/desktop-ax.d.ts.map +1 -1
- package/dist/engine/steps/desktop-ax.js +16 -0
- package/dist/engine/steps/desktop-ax.js.map +1 -1
- package/dist/engine/steps/desktop-sidecar.d.ts +49 -0
- package/dist/engine/steps/desktop-sidecar.d.ts.map +1 -0
- package/dist/engine/steps/desktop-sidecar.js +50 -0
- package/dist/engine/steps/desktop-sidecar.js.map +1 -0
- package/dist/engine/steps/download.d.ts +1 -1
- package/dist/engine/steps/download.d.ts.map +1 -1
- package/dist/engine/steps/download.js +24 -2
- package/dist/engine/steps/download.js.map +1 -1
- package/dist/engine/steps/exec.d.ts +1 -1
- package/dist/engine/steps/exec.d.ts.map +1 -1
- package/dist/engine/steps/exec.js +23 -7
- package/dist/engine/steps/exec.js.map +1 -1
- package/dist/engine/steps/fetch-text.d.ts +2 -2
- package/dist/engine/steps/fetch-text.d.ts.map +1 -1
- package/dist/engine/steps/fetch-text.js +61 -19
- package/dist/engine/steps/fetch-text.js.map +1 -1
- package/dist/engine/steps/fetch.d.ts +3 -1
- package/dist/engine/steps/fetch.d.ts.map +1 -1
- package/dist/engine/steps/fetch.js +36 -7
- package/dist/engine/steps/fetch.js.map +1 -1
- package/dist/engine/steps/index.d.ts +2 -0
- package/dist/engine/steps/index.d.ts.map +1 -1
- package/dist/engine/steps/index.js +2 -0
- package/dist/engine/steps/index.js.map +1 -1
- package/dist/engine/steps/navigate.d.ts +1 -1
- package/dist/engine/steps/navigate.d.ts.map +1 -1
- package/dist/engine/steps/navigate.js +29 -2
- package/dist/engine/steps/navigate.js.map +1 -1
- package/dist/engine/steps/parse-rss.d.ts.map +1 -1
- package/dist/engine/steps/parse-rss.js +9 -4
- package/dist/engine/steps/parse-rss.js.map +1 -1
- package/dist/engine/template.d.ts.map +1 -1
- package/dist/engine/template.js +2 -1
- package/dist/engine/template.js.map +1 -1
- package/dist/engine/text-normalize.d.ts +6 -0
- package/dist/engine/text-normalize.d.ts.map +1 -0
- package/dist/engine/text-normalize.js +63 -0
- package/dist/engine/text-normalize.js.map +1 -0
- package/dist/fast-path.d.ts.map +1 -1
- package/dist/fast-path.js +291 -8
- package/dist/fast-path.js.map +1 -1
- package/dist/main.d.ts +1 -1
- package/dist/main.js +1 -1
- package/dist/manifest-compact.txt +2 -2
- package/dist/manifest-search.json +1 -1
- package/dist/manifest.json +4313 -533
- package/dist/mcp/dispatch.d.ts +3 -3
- package/dist/mcp/dispatch.d.ts.map +1 -1
- package/dist/mcp/dispatch.js +6 -5
- package/dist/mcp/dispatch.js.map +1 -1
- package/dist/mcp/handler.d.ts +2 -2
- package/dist/mcp/handler.d.ts.map +1 -1
- package/dist/mcp/handler.js +59 -5
- package/dist/mcp/handler.js.map +1 -1
- package/dist/mcp/profiles/computer-use.d.ts +4 -0
- package/dist/mcp/profiles/computer-use.d.ts.map +1 -0
- package/dist/mcp/profiles/computer-use.js +305 -0
- package/dist/mcp/profiles/computer-use.js.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +30 -6
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts +9 -0
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +20 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/output/envelope.d.ts +6 -0
- package/dist/output/envelope.d.ts.map +1 -1
- package/dist/output/envelope.js.map +1 -1
- package/dist/output/error-map.d.ts.map +1 -1
- package/dist/output/error-map.js +25 -0
- package/dist/output/error-map.js.map +1 -1
- package/dist/protocol/acp-helpers.d.ts +2 -2
- package/dist/protocol/acp-helpers.d.ts.map +1 -1
- package/dist/protocol/acp-helpers.js +5 -4
- package/dist/protocol/acp-helpers.js.map +1 -1
- package/dist/registry.d.ts +4 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +7 -0
- package/dist/registry.js.map +1 -1
- package/dist/transport/adapters/cdp-browser.d.ts +38 -2
- package/dist/transport/adapters/cdp-browser.d.ts.map +1 -1
- package/dist/transport/adapters/cdp-browser.js +349 -22
- package/dist/transport/adapters/cdp-browser.js.map +1 -1
- package/dist/transport/adapters/desktop-atspi.d.ts +23 -17
- package/dist/transport/adapters/desktop-atspi.d.ts.map +1 -1
- package/dist/transport/adapters/desktop-atspi.js +143 -32
- package/dist/transport/adapters/desktop-atspi.js.map +1 -1
- package/dist/transport/adapters/desktop-ax-helpers.d.ts +24 -0
- package/dist/transport/adapters/desktop-ax-helpers.d.ts.map +1 -0
- package/dist/transport/adapters/desktop-ax-helpers.js +190 -0
- package/dist/transport/adapters/desktop-ax-helpers.js.map +1 -0
- package/dist/transport/adapters/desktop-ax-swift.d.ts +13 -0
- package/dist/transport/adapters/desktop-ax-swift.d.ts.map +1 -1
- package/dist/transport/adapters/desktop-ax-swift.js +176 -2
- package/dist/transport/adapters/desktop-ax-swift.js.map +1 -1
- package/dist/transport/adapters/desktop-ax.d.ts +11 -2
- package/dist/transport/adapters/desktop-ax.d.ts.map +1 -1
- package/dist/transport/adapters/desktop-ax.js +131 -16
- package/dist/transport/adapters/desktop-ax.js.map +1 -1
- package/dist/transport/adapters/desktop-sidecar-errors.d.ts +3 -0
- package/dist/transport/adapters/desktop-sidecar-errors.d.ts.map +1 -0
- package/dist/transport/adapters/desktop-sidecar-errors.js +34 -0
- package/dist/transport/adapters/desktop-sidecar-errors.js.map +1 -0
- package/dist/transport/adapters/desktop-sidecar-snapshot.d.ts +10 -0
- package/dist/transport/adapters/desktop-sidecar-snapshot.d.ts.map +1 -0
- package/dist/transport/adapters/desktop-sidecar-snapshot.js +89 -0
- package/dist/transport/adapters/desktop-sidecar-snapshot.js.map +1 -0
- package/dist/transport/adapters/desktop-uia.d.ts +23 -17
- package/dist/transport/adapters/desktop-uia.d.ts.map +1 -1
- package/dist/transport/adapters/desktop-uia.js +142 -32
- package/dist/transport/adapters/desktop-uia.js.map +1 -1
- package/dist/transport/adapters/subprocess.d.ts +7 -0
- package/dist/transport/adapters/subprocess.d.ts.map +1 -1
- package/dist/transport/adapters/subprocess.js +64 -0
- package/dist/transport/adapters/subprocess.js.map +1 -1
- package/dist/transport/bus.d.ts +2 -0
- package/dist/transport/bus.d.ts.map +1 -1
- package/dist/transport/bus.js +7 -11
- package/dist/transport/bus.js.map +1 -1
- package/dist/transport/capability.d.ts.map +1 -1
- package/dist/transport/capability.js +123 -98
- package/dist/transport/capability.js.map +1 -1
- package/dist/transport/cascade.d.ts +5 -0
- package/dist/transport/cascade.d.ts.map +1 -0
- package/dist/transport/cascade.js +550 -0
- package/dist/transport/cascade.js.map +1 -0
- package/dist/transport/cdp-session.d.ts +11 -0
- package/dist/transport/cdp-session.d.ts.map +1 -0
- package/dist/transport/cdp-session.js +52 -0
- package/dist/transport/cdp-session.js.map +1 -0
- package/dist/transport/refs.d.ts +51 -0
- package/dist/transport/refs.d.ts.map +1 -0
- package/dist/transport/refs.js +135 -0
- package/dist/transport/refs.js.map +1 -0
- package/dist/transport/sidecar-binary.d.ts +18 -0
- package/dist/transport/sidecar-binary.d.ts.map +1 -0
- package/dist/transport/sidecar-binary.js +55 -0
- package/dist/transport/sidecar-binary.js.map +1 -0
- package/dist/transport/sidecar.d.ts +35 -0
- package/dist/transport/sidecar.d.ts.map +1 -0
- package/dist/transport/sidecar.js +134 -0
- package/dist/transport/sidecar.js.map +1 -0
- package/dist/transport/snapshot-encoder.d.ts +34 -0
- package/dist/transport/snapshot-encoder.d.ts.map +1 -0
- package/dist/transport/snapshot-encoder.js +139 -0
- package/dist/transport/snapshot-encoder.js.map +1 -0
- package/dist/transport/types.d.ts +6 -1
- package/dist/transport/types.d.ts.map +1 -1
- package/dist/types.d.ts +11 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/docs/mcp/clients/claude-code.md +29 -0
- package/docs/mcp/clients/claude-desktop.md +47 -0
- package/docs/mcp/clients/codex.md +29 -0
- package/docs/mcp/clients/cursor.md +38 -0
- package/docs/mcp/clients/gemini-cli.md +38 -0
- package/docs/operate/compute.md +172 -0
- package/docs/operate/electron.md +87 -0
- package/docs/operate/focus-behavior.md +40 -0
- package/docs/operate/troubleshooting.md +379 -0
- package/package.json +44 -19
- package/src/adapters/36kr/news.yaml +4 -1
- package/src/adapters/_electron/desktop-shared.ts +14 -0
- package/src/adapters/_electron/shared.ts +54 -2
- package/src/adapters/juejin/hot.test.ts +25 -0
- package/src/adapters/juejin/hot.yaml +52 -0
- package/src/adapters/juejin/search.test.ts +27 -0
- package/src/adapters/juejin/search.yaml +58 -0
- package/src/adapters/leetcode/discuss-search.test.ts +29 -0
- package/src/adapters/leetcode/discuss-search.yaml +56 -0
- package/src/adapters/macos/actions.ts +63 -0
package/AGENTS.md
CHANGED
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
Agent routing: unicli agents matrix && unicli agents recommend <agent>
|
|
7
7
|
Run: unicli <site> <command> [args]
|
|
8
8
|
Output is structured Markdown by default (non-TTY + agent UA auto-detected). Use -f json for JSON. Errors are structured envelopes to stderr.
|
|
9
|
+
Style: load skills/talk-normal/SKILL.md before writing docs or user-facing text; keep prose direct and avoid filler.
|
|
9
10
|
You can fix broken adapters yourself — read the Self-Repair section. -->
|
|
10
11
|
|
|
11
12
|
<!-- BEGIN COUNTS -->
|
|
12
13
|
|
|
13
|
-
> <!-- STATS:site_count -->
|
|
14
|
+
> <!-- STATS:site_count -->237<!-- /STATS --> sites, <!-- STATS:command_count -->1453<!-- /STATS --> commands, <!-- STATS:pipeline_step_count -->101<!-- /STATS --> pipeline steps, BM25 bilingual search. `npm install -g @zenalexa/unicli`
|
|
14
15
|
|
|
15
16
|
<!-- END COUNTS -->
|
|
16
17
|
|
|
@@ -39,7 +40,7 @@ npm install -g @zenalexa/unicli
|
|
|
39
40
|
|
|
40
41
|
**Chinese**: zhihu (24), xiaohongshu (22), bilibili (20), douyin (13), douban (12), v2ex (12), linux-do (11), jike (10), +31 more (`unicli list`)
|
|
41
42
|
|
|
42
|
-
**International**: twitter (38), instagram (26), reddit (20), tiktok (16), youtube (16), nowcoder (16), discord-app (15), lesswrong (15), +
|
|
43
|
+
**International**: twitter (38), instagram (26), reddit (20), tiktok (16), youtube (16), nowcoder (16), discord-app (15), lesswrong (15), +50 more (`unicli list`)
|
|
43
44
|
|
|
44
45
|
**AI / ML**: antigravity (16), chatwise (16), chatgpt (15), notebooklm (15), doubao-app (13), doubao (9), doubao-web (9), perplexity (8), +13 more (`unicli list`)
|
|
45
46
|
|
|
@@ -51,9 +52,9 @@ npm install -g @zenalexa/unicli
|
|
|
51
52
|
|
|
52
53
|
**Reference**: spotify (23), netease-music (17), linear (10), imdb (7), bitwarden (7), todoist (7), wikipedia (5), xiaoyuzhou (5), +11 more (`unicli list`)
|
|
53
54
|
|
|
54
|
-
### macOS (
|
|
55
|
+
### macOS (60 cmds)
|
|
55
56
|
|
|
56
|
-
active-app, apps, apps-list, battery, bluetooth, brightness, caffeinate, calendar-create, calendar-list, calendar-today,
|
|
57
|
+
active-app, app-actions, apps, apps-list, automation-smoke, battery, bluetooth, brightness, caffeinate, calendar-create, calendar-list, calendar-today, … (`unicli list --site macos`)
|
|
57
58
|
|
|
58
59
|
### Desktop (28 apps)
|
|
59
60
|
|
|
@@ -185,7 +186,7 @@ Full reference: [`docs/ADAPTER-FORMAT.md`](docs/ADAPTER-FORMAT.md).
|
|
|
185
186
|
```bash
|
|
186
187
|
npx @zenalexa/unicli mcp serve # stdio (4 meta-tools)
|
|
187
188
|
npx @zenalexa/unicli mcp serve --transport streamable --port 19826
|
|
188
|
-
npx @zenalexa/unicli mcp serve --transport sse --port 19826 #
|
|
189
|
+
npx @zenalexa/unicli mcp serve --transport sse --port 19826 # legacy alias for streamable
|
|
189
190
|
npx @zenalexa/unicli mcp serve --auth # OAuth 2.1 PKCE
|
|
190
191
|
```
|
|
191
192
|
|
|
@@ -212,4 +213,4 @@ unicli lark-cli calendar +agenda # Direct passthrough
|
|
|
212
213
|
|
|
213
214
|
## Version
|
|
214
215
|
|
|
215
|
-
0.
|
|
216
|
+
0.217.3 — Apollo · Shepard
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<h1 align="center">Uni-CLI</h1>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
<strong>
|
|
8
|
+
<strong>The agent execution substrate for the world's software.</strong>
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
</p>
|
|
18
18
|
|
|
19
19
|
<p align="center">
|
|
20
|
-
Search by intent,
|
|
20
|
+
Search by intent, execute governed commands across web, apps, local tools, and system capabilities, then return evidence-rich AgentEnvelopes that agents can inspect and repair.
|
|
21
21
|
</p>
|
|
22
22
|
|
|
23
23
|
<p align="center">
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
</p>
|
|
29
29
|
|
|
30
30
|
<p align="center">
|
|
31
|
-
<sub><!-- STATS:site_count -->
|
|
31
|
+
<sub><!-- STATS:site_count -->237<!-- /STATS --> sites · <!-- STATS:command_count -->1453<!-- /STATS --> commands · <!-- STATS:pipeline_step_count -->101<!-- /STATS --> pipeline steps · <!-- STATS:test_count -->7747<!-- /STATS --> tests</sub>
|
|
32
32
|
</p>
|
|
33
33
|
|
|
34
34
|
<p align="center">
|
|
@@ -129,26 +129,30 @@ Prefer native CLI / JSON stream / MCP for agent runtimes. Use ACP as an editor c
|
|
|
129
129
|
|
|
130
130
|
## What It Does
|
|
131
131
|
|
|
132
|
-
Uni-CLI turns software surfaces into commands that agents can discover,
|
|
132
|
+
Uni-CLI sits under agent applications and turns software surfaces into commands that agents can discover, execute, record, and repair.
|
|
133
133
|
|
|
134
|
-
| Surface | What you get
|
|
135
|
-
| ------------------ |
|
|
136
|
-
| Websites and APIs | Declarative adapters for public, cookie, header, and browser-intercept workflows
|
|
137
|
-
| Browser automation | CDP steps for navigate, click, type, intercept, snapshot, extract, wait, and related browser work
|
|
138
|
-
| Desktop and macOS | System commands, app adapters, screenshots, clipboard, calendar, brightness, and local tools
|
|
139
|
-
| External CLIs | 58 registered pass-through bridges with install/status discovery
|
|
140
|
-
| Agent backends | Route matrix for native CLI, JSON stream, MCP, ACP, HTTP API, OpenAI-compatible, and bridge routes
|
|
141
|
-
|
|
|
142
|
-
|
|
|
134
|
+
| Surface | What you get |
|
|
135
|
+
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
136
|
+
| Websites and APIs | Declarative adapters for public, cookie, header, and browser-intercept workflows |
|
|
137
|
+
| Browser automation | CDP steps for navigate, click, type, intercept, snapshot, extract, wait, and related browser work |
|
|
138
|
+
| Desktop and macOS | System commands, app adapters, real-time Shortcuts/App Intent discovery, screenshots, clipboard, calendar, brightness, and local tools |
|
|
139
|
+
| External CLIs | 58 registered pass-through bridges with install/status discovery |
|
|
140
|
+
| Agent backends | Route matrix for native CLI, JSON stream, MCP, ACP, HTTP API, OpenAI-compatible, and bridge routes |
|
|
141
|
+
| Operation policy | `open`, `confirm`, and `locked` profiles with effect/risk scopes, local deny rules, `--yes`, and persisted approval memory |
|
|
142
|
+
| Evidence | Run traces with environment snapshots, probe/replay/compare scores, structured gate results, browser session leases with tab/auth posture, render-aware evidence, movement checks, and stale-ref details |
|
|
143
|
+
| Output | v2 `AgentEnvelope` in Markdown, JSON, YAML, CSV, or compact format |
|
|
144
|
+
| Repair | Structured errors with `adapter_path`, failing `step`, retryability, suggestions, and alternatives |
|
|
143
145
|
|
|
144
146
|
## For Agents
|
|
145
147
|
|
|
146
148
|
Use search first, then run the smallest matching command.
|
|
147
149
|
|
|
148
150
|
```bash
|
|
149
|
-
unicli search "
|
|
150
|
-
unicli
|
|
151
|
-
unicli
|
|
151
|
+
unicli search "connect slack messages" --limit 5
|
|
152
|
+
unicli slack search "deploy incident" -f json
|
|
153
|
+
unicli macos app-actions --app WhatsApp -f json
|
|
154
|
+
unicli macos automation-smoke -f json
|
|
155
|
+
unicli repair slack search
|
|
152
156
|
```
|
|
153
157
|
|
|
154
158
|
Output defaults to structured Markdown for non-TTY and agent-user-agent runs. Force a machine format when you need one:
|
|
@@ -156,6 +160,17 @@ Output defaults to structured Markdown for non-TTY and agent-user-agent runs. Fo
|
|
|
156
160
|
```bash
|
|
157
161
|
UNICLI_OUTPUT=json unicli reddit hot --limit 10
|
|
158
162
|
unicli hackernews top --limit 5 -f yaml
|
|
163
|
+
unicli --record --permission-profile confirm twitter search "coding agents" -f json
|
|
164
|
+
unicli runs list -f json
|
|
165
|
+
unicli runs show <run_id> -f json
|
|
166
|
+
unicli runs probe <run_id> -f json
|
|
167
|
+
unicli runs replay <run_id> --permission-profile confirm --yes --min-score 1 --min-context-score 1 --min-overall-score 1 -f json
|
|
168
|
+
unicli runs compare <run_id> <replay_run_id> -f json
|
|
169
|
+
unicli runs compare <run_id> <replay_run_id> --min-score 1 --min-context-score 1 --min-overall-score 1 -f json
|
|
170
|
+
unicli --permission-profile locked --yes --remember-approval word set-font "Inter"
|
|
171
|
+
unicli approvals list -f json
|
|
172
|
+
unicli approvals revoke <approval_key> -f json
|
|
173
|
+
unicli browser evidence --render-aware --expect-domain example.com -f json
|
|
159
174
|
```
|
|
160
175
|
|
|
161
176
|
Protocol entry points:
|
|
@@ -170,9 +185,25 @@ unicli agents matrix
|
|
|
170
185
|
|
|
171
186
|
ACP is supported for editors and bridge tooling. The primary runtime path stays native CLI, JSON stream, or MCP when those routes are available.
|
|
172
187
|
|
|
188
|
+
## Local Computer Control
|
|
189
|
+
|
|
190
|
+
`unicli compute` controls installed apps through native accessibility, Electron CDP, and visual fallback transports.
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
unicli compute apps
|
|
194
|
+
unicli compute snapshot --app Calculator --format compact
|
|
195
|
+
unicli compute find --role button --name 5 --first
|
|
196
|
+
unicli compute find --role input --text 8 --first
|
|
197
|
+
unicli compute click @e7
|
|
198
|
+
unicli doctor compute --json
|
|
199
|
+
npx @zenalexa/unicli mcp serve --profile computer-use
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Start with [Compute](docs/operate/compute.md), [Electron App Control](docs/operate/electron.md), and [Compute Troubleshooting](docs/operate/troubleshooting.md).
|
|
203
|
+
|
|
173
204
|
## Coverage
|
|
174
205
|
|
|
175
|
-
The catalog is intentionally broad
|
|
206
|
+
The catalog is intentionally broad. Every command is discoverable, typed, and repairable.
|
|
176
207
|
|
|
177
208
|
| Area | Examples |
|
|
178
209
|
| ----------------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
@@ -288,9 +319,26 @@ Docs:
|
|
|
288
319
|
|
|
289
320
|
- Auth-required sites use local cookie files under `~/.unicli/cookies/<site>.json`.
|
|
290
321
|
- Browser adapters require a reachable Chrome/CDP session.
|
|
322
|
+
- Permission profiles are user-selected runtime policy. The default is `open`;
|
|
323
|
+
stricter `confirm` and `locked` profiles require `--yes` or `UNICLI_APPROVE=1`
|
|
324
|
+
for blocked operations. Add `--remember-approval` with `--yes` to store the
|
|
325
|
+
same command capability and resource scope under `~/.unicli/approvals.jsonl`.
|
|
326
|
+
Resource scope covers stable metadata such as domain, account surface, app,
|
|
327
|
+
process family, and path argument slots. Use
|
|
328
|
+
`unicli approvals list`, `revoke`, and `clear` to inspect or remove remembered
|
|
329
|
+
scopes. The file stores scope metadata; runtime args stay out of approval
|
|
330
|
+
memory.
|
|
331
|
+
- Local deny rules live at `~/.unicli/permission-rules.json`, or at
|
|
332
|
+
`UNICLI_PERMISSION_RULES_PATH`. They match site, command, effect, capability
|
|
333
|
+
dimensions, and resource metadata, then block before `--yes` and remembered
|
|
334
|
+
approvals. Runtime guards also check fetched domains, browser navigation
|
|
335
|
+
targets, download and output paths, and subprocess executables before the
|
|
336
|
+
request, write, or process spawn happens.
|
|
337
|
+
- Run recording is opt-in. Use `--record` or `UNICLI_RECORD_RUN=1` when you need
|
|
338
|
+
append-only evidence under `~/.unicli/runs`.
|
|
291
339
|
- CUA routes require a configured real backend. Declared-but-unavailable providers fail closed with structured errors.
|
|
292
340
|
- User adapters and repairs live in `~/.unicli/adapters/`; committed adapters remain the package baseline.
|
|
293
|
-
- If a site blocks automation or changes a private API,
|
|
341
|
+
- If a site blocks automation or changes a private API, Uni-CLI returns a clear failure envelope.
|
|
294
342
|
|
|
295
343
|
## Development
|
|
296
344
|
|
|
@@ -306,5 +354,5 @@ npm run verify
|
|
|
306
354
|
[Apache-2.0](./LICENSE)
|
|
307
355
|
|
|
308
356
|
<p align="center">
|
|
309
|
-
<sub>v0.
|
|
357
|
+
<sub>v0.217.3 — Apollo · Shepard</sub>
|
|
310
358
|
</p>
|
package/README.zh-CN.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<h1 align="center">Uni-CLI</h1>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
<strong
|
|
8
|
+
<strong>面向真实软件的 Agent 执行底座。</strong>
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
</p>
|
|
18
18
|
|
|
19
19
|
<p align="center">
|
|
20
|
-
|
|
20
|
+
按意图发现命令,跨 Web、应用、本地工具和系统能力执行可治理操作,再返回带证据的 AgentEnvelope,方便智能体检查和修复。
|
|
21
21
|
</p>
|
|
22
22
|
|
|
23
23
|
<p align="center">
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
</p>
|
|
29
29
|
|
|
30
30
|
<p align="center">
|
|
31
|
-
<sub><!-- STATS:site_count -->
|
|
31
|
+
<sub><!-- STATS:site_count -->237<!-- /STATS --> 个站点 · <!-- STATS:command_count -->1453<!-- /STATS --> 条命令 · <!-- STATS:pipeline_step_count -->101<!-- /STATS --> 个 pipeline step · <!-- STATS:test_count -->7747<!-- /STATS --> 个测试</sub>
|
|
32
32
|
</p>
|
|
33
33
|
|
|
34
34
|
<p align="center">
|
|
@@ -129,17 +129,19 @@ Prefer native CLI / JSON stream / MCP for agent runtimes. Use ACP as an editor c
|
|
|
129
129
|
|
|
130
130
|
## 它解决什么
|
|
131
131
|
|
|
132
|
-
Uni-CLI
|
|
132
|
+
Uni-CLI 位于 Agent 应用之下,把软件表面收敛成 Agent 能发现、能执行、能记录、能修的命令。
|
|
133
133
|
|
|
134
|
-
| 表面 | 能力
|
|
135
|
-
| ------------ |
|
|
136
|
-
| 网站和 API | public、cookie、header、browser-intercept 等 adapter
|
|
137
|
-
| 浏览器自动化 | CDP 的 navigate、click、type、intercept、snapshot、extract、wait 等步骤
|
|
138
|
-
| 桌面和 macOS | 系统命令、App adapter
|
|
139
|
-
| 外部 CLI | 58 个已登记的 passthrough bridge,支持安装和状态发现
|
|
140
|
-
| Agent 后端 | native CLI、JSON stream、MCP、ACP、HTTP API、OpenAI-compatible、bridge 路由矩阵
|
|
141
|
-
|
|
|
142
|
-
|
|
|
134
|
+
| 表面 | 能力 |
|
|
135
|
+
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
136
|
+
| 网站和 API | public、cookie、header、browser-intercept 等 adapter |
|
|
137
|
+
| 浏览器自动化 | CDP 的 navigate、click、type、intercept、snapshot、extract、wait 等步骤 |
|
|
138
|
+
| 桌面和 macOS | 系统命令、App adapter、实时 Shortcuts/App Intent 发现、截图、剪贴板、日历、亮度、本地工具 |
|
|
139
|
+
| 外部 CLI | 58 个已登记的 passthrough bridge,支持安装和状态发现 |
|
|
140
|
+
| Agent 后端 | native CLI、JSON stream、MCP、ACP、HTTP API、OpenAI-compatible、bridge 路由矩阵 |
|
|
141
|
+
| 操作策略 | `open`、`confirm`、`locked` profile,暴露 effect/risk scope、本地 deny 规则、`--yes` 和持久审批记忆 |
|
|
142
|
+
| 执行证据 | run trace 会记录环境快照,也能 probe/replay/compare 打分并输出结构化 gate 结果;浏览器 session lease 带 tab/auth 姿态,还支持 render-aware 证据、移动检测和 stale-ref 细节 |
|
|
143
|
+
| 输出 | v2 `AgentEnvelope`,支持 Markdown、JSON、YAML、CSV、compact |
|
|
144
|
+
| 修复 | 错误里带 `adapter_path`、失败 `step`、是否可重试、修复建议和替代命令 |
|
|
143
145
|
|
|
144
146
|
## 给 Agent 的入口
|
|
145
147
|
|
|
@@ -148,6 +150,8 @@ Uni-CLI 把软件表面封装成 Agent 能发现、能执行、能修的命令
|
|
|
148
150
|
```bash
|
|
149
151
|
unicli search "推特热门" --limit 5
|
|
150
152
|
unicli twitter search "coding agents" -f json
|
|
153
|
+
unicli macos app-actions --app WhatsApp -f json
|
|
154
|
+
unicli macos automation-smoke -f json
|
|
151
155
|
unicli repair twitter search
|
|
152
156
|
```
|
|
153
157
|
|
|
@@ -156,6 +160,17 @@ unicli repair twitter search
|
|
|
156
160
|
```bash
|
|
157
161
|
UNICLI_OUTPUT=json unicli reddit hot --limit 10
|
|
158
162
|
unicli hackernews top --limit 5 -f yaml
|
|
163
|
+
unicli --record --permission-profile confirm twitter search "coding agents" -f json
|
|
164
|
+
unicli runs list -f json
|
|
165
|
+
unicli runs show <run_id> -f json
|
|
166
|
+
unicli runs probe <run_id> -f json
|
|
167
|
+
unicli runs replay <run_id> --permission-profile confirm --yes --min-score 1 --min-context-score 1 --min-overall-score 1 -f json
|
|
168
|
+
unicli runs compare <run_id> <replay_run_id> -f json
|
|
169
|
+
unicli runs compare <run_id> <replay_run_id> --min-score 1 --min-context-score 1 --min-overall-score 1 -f json
|
|
170
|
+
unicli --permission-profile locked --yes --remember-approval word set-font "Inter"
|
|
171
|
+
unicli approvals list -f json
|
|
172
|
+
unicli approvals revoke <approval_key> -f json
|
|
173
|
+
unicli browser evidence --render-aware --expect-domain example.com -f json
|
|
159
174
|
```
|
|
160
175
|
|
|
161
176
|
协议入口:
|
|
@@ -172,7 +187,7 @@ ACP 作为编辑器和桥接兼容层保留。真正跑任务时,优先 native
|
|
|
172
187
|
|
|
173
188
|
## 覆盖范围
|
|
174
189
|
|
|
175
|
-
|
|
190
|
+
每条命令都能搜索、可声明、可验证、可修。
|
|
176
191
|
|
|
177
192
|
| 领域 | 例子 |
|
|
178
193
|
| ------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
@@ -288,9 +303,22 @@ columns: [title, url]
|
|
|
288
303
|
|
|
289
304
|
- 需要登录的网站使用本地 cookie 文件:`~/.unicli/cookies/<site>.json`。
|
|
290
305
|
- Browser adapter 需要可连接的 Chrome/CDP。
|
|
306
|
+
- Permission profile 是用户选择的运行时策略。默认是 `open`;更严格的
|
|
307
|
+
`confirm` 和 `locked` profile 会要求 `--yes` 或 `UNICLI_APPROVE=1`。
|
|
308
|
+
`--yes` 加 `--remember-approval` 会把同一条命令的 capability 和资源 scope
|
|
309
|
+
记到 `~/.unicli/approvals.jsonl`。资源 scope 来自稳定 metadata,比如域名、
|
|
310
|
+
账号面、应用、进程族和路径参数槽。用 `unicli approvals list`、`revoke`、
|
|
311
|
+
`clear` 查看或移除已记住的 scope。文件只存 scope metadata,原始运行参数留在审批记忆之外。
|
|
312
|
+
- 本地 deny 规则放在 `~/.unicli/permission-rules.json`,也可以用
|
|
313
|
+
`UNICLI_PERMISSION_RULES_PATH` 指定。规则按站点、命令、effect、capability
|
|
314
|
+
维度和资源 metadata 匹配,优先级高于 `--yes` 和已记住的审批。运行时还会检查
|
|
315
|
+
fetch 域名、浏览器跳转目标、下载和输出路径、子进程可执行文件,命中后在请求、写入或
|
|
316
|
+
启动进程之前停下。
|
|
317
|
+
- Run recording 是显式启用能力。需要可审查证据时使用 `--record` 或
|
|
318
|
+
`UNICLI_RECORD_RUN=1`,追加写入 `~/.unicli/runs`。
|
|
291
319
|
- CUA 路由必须配置真实 backend。声明了但不可用的 provider 会失败关闭,并返回结构化错误。
|
|
292
320
|
- 用户 adapter 和修复放在 `~/.unicli/adapters/`;包内 adapter 是基线。
|
|
293
|
-
- 如果网站阻止自动化或私有 API
|
|
321
|
+
- 如果网站阻止自动化或私有 API 变了,Uni-CLI 会返回清楚的失败 envelope。
|
|
294
322
|
|
|
295
323
|
## 开发
|
|
296
324
|
|
|
@@ -306,5 +334,5 @@ npm run verify
|
|
|
306
334
|
[Apache-2.0](./LICENSE)
|
|
307
335
|
|
|
308
336
|
<p align="center">
|
|
309
|
-
<sub>v0.
|
|
337
|
+
<sub>v0.217.3 — Apollo · Shepard</sub>
|
|
310
338
|
</p>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "unicli-atspi"
|
|
3
|
+
version.workspace = true
|
|
4
|
+
edition.workspace = true
|
|
5
|
+
rust-version.workspace = true
|
|
6
|
+
license.workspace = true
|
|
7
|
+
homepage.workspace = true
|
|
8
|
+
repository.workspace = true
|
|
9
|
+
|
|
10
|
+
[[bin]]
|
|
11
|
+
name = "unicli-atspi"
|
|
12
|
+
path = "src/main.rs"
|
|
13
|
+
|
|
14
|
+
[dependencies]
|
|
15
|
+
anyhow.workspace = true
|
|
16
|
+
clap.workspace = true
|
|
17
|
+
serde.workspace = true
|
|
18
|
+
serde_json.workspace = true
|
|
19
|
+
tokio.workspace = true
|
|
20
|
+
tracing.workspace = true
|
|
21
|
+
tracing-subscriber.workspace = true
|
|
22
|
+
unicli-shared.workspace = true
|
|
23
|
+
|
|
24
|
+
[target.'cfg(target_os = "linux")'.dependencies]
|
|
25
|
+
atspi = { version = "0.29.0", default-features = false, features = [
|
|
26
|
+
"connection",
|
|
27
|
+
"proxies",
|
|
28
|
+
"wrappers",
|
|
29
|
+
] }
|
|
30
|
+
async-lock = "=3.4.1"
|
|
31
|
+
async-signal = "=0.2.13"
|
|
32
|
+
futures-lite = "=2.6.1"
|
|
33
|
+
indexmap = "=2.11.3"
|
|
34
|
+
proc-macro-crate = "=3.4.0"
|
|
35
|
+
tempfile = "=3.22.0"
|
|
36
|
+
toml_datetime = "=0.7.1"
|
|
37
|
+
toml_edit = "=0.23.5"
|
|
38
|
+
toml_parser = "=1.0.2"
|
|
39
|
+
toml_writer = "=1.0.2"
|
|
40
|
+
wasip2 = "=1.0.1"
|
|
41
|
+
winnow = "=0.7.13"
|
|
42
|
+
wit-bindgen = "=0.46.0"
|
|
43
|
+
zbus = { version = "=5.11.0", features = ["async-io"], default-features = false }
|
|
44
|
+
zbus_macros = "=5.11.0"
|
|
45
|
+
zvariant = "=5.7.0"
|
|
46
|
+
zvariant_derive = "=5.7.0"
|
|
47
|
+
zvariant_utils = "=3.2.1"
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
use serde_json::Value;
|
|
2
|
+
use unicli_shared::{SidecarError, SidecarResponse};
|
|
3
|
+
|
|
4
|
+
pub type HandlerResult = Result<Value, AtspiError>;
|
|
5
|
+
|
|
6
|
+
#[derive(Debug, Clone)]
|
|
7
|
+
pub struct AtspiError {
|
|
8
|
+
reason: String,
|
|
9
|
+
suggestion: String,
|
|
10
|
+
minimum_capability: Option<String>,
|
|
11
|
+
r#ref: Option<String>,
|
|
12
|
+
exit_code: u8,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
impl AtspiError {
|
|
16
|
+
pub fn unavailable(reason: impl Into<String>) -> Self {
|
|
17
|
+
Self {
|
|
18
|
+
reason: reason.into(),
|
|
19
|
+
suggestion:
|
|
20
|
+
"run on Linux with the native AT-SPI backend available, or fall back to CUA".into(),
|
|
21
|
+
minimum_capability: None,
|
|
22
|
+
r#ref: None,
|
|
23
|
+
exit_code: 69,
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
pub fn invalid_input(reason: impl Into<String>) -> Self {
|
|
28
|
+
Self {
|
|
29
|
+
reason: reason.into(),
|
|
30
|
+
suggestion:
|
|
31
|
+
"pass a desktop-atspi stable top-level window ref from atspi_snapshot or atspi_find"
|
|
32
|
+
.into(),
|
|
33
|
+
minimum_capability: Some("desktop-atspi.invalid_input".into()),
|
|
34
|
+
r#ref: None,
|
|
35
|
+
exit_code: 78,
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
#[allow(dead_code)] // Used by native Linux AT-SPI handlers.
|
|
40
|
+
pub fn no_element(r#ref: impl Into<String>) -> Self {
|
|
41
|
+
let r#ref = r#ref.into();
|
|
42
|
+
Self {
|
|
43
|
+
reason: format!("no AT-SPI element matched {ref}"),
|
|
44
|
+
suggestion: "re-snapshot; the ref may be stale".into(),
|
|
45
|
+
minimum_capability: Some("desktop-atspi.no_element".into()),
|
|
46
|
+
r#ref: Some(r#ref),
|
|
47
|
+
exit_code: 66,
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
pub fn not_invokable(r#ref: impl Into<String>) -> Self {
|
|
52
|
+
let r#ref = r#ref.into();
|
|
53
|
+
Self {
|
|
54
|
+
reason: format!("AT-SPI element {ref} does not expose a native action"),
|
|
55
|
+
suggestion: "try CUA fallback, set-value, press, or focus before retrying".into(),
|
|
56
|
+
minimum_capability: Some("desktop-atspi.not_invokable".into()),
|
|
57
|
+
r#ref: Some(r#ref),
|
|
58
|
+
exit_code: 69,
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
#[allow(dead_code)] // Used by the native Linux AT-SPI connection path.
|
|
63
|
+
pub fn dbus_blocked(reason: impl Into<String>) -> Self {
|
|
64
|
+
Self {
|
|
65
|
+
reason: reason.into(),
|
|
66
|
+
suggestion: "start the user AT-SPI D-Bus daemon".into(),
|
|
67
|
+
minimum_capability: Some("desktop-atspi.dbus_blocked".into()),
|
|
68
|
+
r#ref: None,
|
|
69
|
+
exit_code: 69,
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
#[allow(dead_code)] // Used when a target app exposes no useful AT-SPI tree.
|
|
74
|
+
pub fn no_a11y_attr(reason: impl Into<String>) -> Self {
|
|
75
|
+
Self {
|
|
76
|
+
reason: reason.into(),
|
|
77
|
+
suggestion: "enable accessibility support for the target app".into(),
|
|
78
|
+
minimum_capability: Some("desktop-atspi.no_a11y_attr".into()),
|
|
79
|
+
r#ref: None,
|
|
80
|
+
exit_code: 69,
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
#[allow(dead_code)] // Used by Wayland fallback input dispatch.
|
|
85
|
+
pub fn wayland_input_missing(reason: impl Into<String>) -> Self {
|
|
86
|
+
Self {
|
|
87
|
+
reason: reason.into(),
|
|
88
|
+
suggestion: "install ydotool or another supported Wayland input helper".into(),
|
|
89
|
+
minimum_capability: Some("desktop-atspi.wayland-input".into()),
|
|
90
|
+
r#ref: None,
|
|
91
|
+
exit_code: 69,
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
#[allow(dead_code)] // Used by X11 fallback input dispatch.
|
|
96
|
+
pub fn x11_input_missing(reason: impl Into<String>) -> Self {
|
|
97
|
+
Self {
|
|
98
|
+
reason: reason.into(),
|
|
99
|
+
suggestion: "install xdotool for X11 fallback input".into(),
|
|
100
|
+
minimum_capability: Some("desktop-atspi.x11-input".into()),
|
|
101
|
+
r#ref: None,
|
|
102
|
+
exit_code: 69,
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
pub trait IntoSidecarResponse {
|
|
108
|
+
fn into_response(self, id: u64, kind: String) -> SidecarResponse;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
impl IntoSidecarResponse for HandlerResult {
|
|
112
|
+
fn into_response(self, id: u64, kind: String) -> SidecarResponse {
|
|
113
|
+
match self {
|
|
114
|
+
Ok(data) => SidecarResponse::ok(id, kind, data),
|
|
115
|
+
Err(err) => {
|
|
116
|
+
let minimum_capability = err
|
|
117
|
+
.minimum_capability
|
|
118
|
+
.unwrap_or_else(|| format!("desktop-atspi.{kind}"));
|
|
119
|
+
SidecarResponse {
|
|
120
|
+
id,
|
|
121
|
+
kind: kind.clone(),
|
|
122
|
+
ok: false,
|
|
123
|
+
data: None,
|
|
124
|
+
error: Some(SidecarError {
|
|
125
|
+
transport: "desktop-atspi".into(),
|
|
126
|
+
action: kind,
|
|
127
|
+
reason: err.reason,
|
|
128
|
+
suggestion: err.suggestion,
|
|
129
|
+
minimum_capability,
|
|
130
|
+
exit_code: err.exit_code,
|
|
131
|
+
stable_token: None,
|
|
132
|
+
r#ref: err.r#ref,
|
|
133
|
+
}),
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
pub fn backend_unavailable() -> AtspiError {
|
|
141
|
+
if cfg!(target_os = "linux") {
|
|
142
|
+
AtspiError::unavailable(backend_unavailable_reason("linux"))
|
|
143
|
+
} else {
|
|
144
|
+
AtspiError::unavailable(backend_unavailable_reason(std::env::consts::OS))
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
fn backend_unavailable_reason(target_os: &str) -> String {
|
|
149
|
+
if target_os == "linux" {
|
|
150
|
+
"Linux AT-SPI backend is unavailable for this request".into()
|
|
151
|
+
} else {
|
|
152
|
+
format!("desktop-atspi is only available on Linux; current target is {target_os}")
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
#[cfg(test)]
|
|
157
|
+
mod tests {
|
|
158
|
+
use super::*;
|
|
159
|
+
|
|
160
|
+
fn error_for(err: AtspiError) -> unicli_shared::SidecarError {
|
|
161
|
+
let response = Err::<Value, _>(err).into_response(9, "atspi_invoke".into());
|
|
162
|
+
response.error.expect("error response")
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
#[test]
|
|
166
|
+
fn no_element_uses_semantic_minimum_capability() {
|
|
167
|
+
let error = error_for(AtspiError::no_element("@e42"));
|
|
168
|
+
assert_eq!(error.minimum_capability, "desktop-atspi.no_element");
|
|
169
|
+
assert_eq!(error.r#ref.as_deref(), Some("@e42"));
|
|
170
|
+
assert_eq!(error.exit_code, 66);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
#[test]
|
|
174
|
+
fn not_invokable_uses_semantic_minimum_capability() {
|
|
175
|
+
let error = error_for(AtspiError::not_invokable("@e42"));
|
|
176
|
+
assert_eq!(error.minimum_capability, "desktop-atspi.not_invokable");
|
|
177
|
+
assert_eq!(error.r#ref.as_deref(), Some("@e42"));
|
|
178
|
+
assert_eq!(error.exit_code, 69);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
#[test]
|
|
182
|
+
fn dbus_blocked_uses_semantic_minimum_capability() {
|
|
183
|
+
let error = error_for(AtspiError::dbus_blocked("AT-SPI D-Bus is unavailable"));
|
|
184
|
+
assert_eq!(error.minimum_capability, "desktop-atspi.dbus_blocked");
|
|
185
|
+
assert_eq!(error.exit_code, 69);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
#[test]
|
|
189
|
+
fn wayland_input_uses_semantic_minimum_capability() {
|
|
190
|
+
let error = error_for(AtspiError::wayland_input_missing("ydotool is missing"));
|
|
191
|
+
assert_eq!(error.minimum_capability, "desktop-atspi.wayland-input");
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
#[test]
|
|
195
|
+
fn no_a11y_attr_uses_semantic_minimum_capability() {
|
|
196
|
+
let error = error_for(AtspiError::no_a11y_attr("no accessibility attributes"));
|
|
197
|
+
assert_eq!(error.minimum_capability, "desktop-atspi.no_a11y_attr");
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
#[test]
|
|
201
|
+
fn x11_input_uses_semantic_minimum_capability() {
|
|
202
|
+
let error = error_for(AtspiError::x11_input_missing("xdotool is missing"));
|
|
203
|
+
assert_eq!(error.minimum_capability, "desktop-atspi.x11-input");
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
#[test]
|
|
207
|
+
fn backend_unavailable_reason_does_not_claim_native_traversal_pending() {
|
|
208
|
+
let reason = backend_unavailable_reason("linux");
|
|
209
|
+
|
|
210
|
+
assert!(!reason.contains("pending"));
|
|
211
|
+
assert!(reason.contains("unavailable"));
|
|
212
|
+
}
|
|
213
|
+
}
|