@zenalexa/unicli 0.221.1 → 0.222.0

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.
Files changed (125) hide show
  1. package/AGENTS.md +2 -2
  2. package/README.md +29 -22
  3. package/README.zh-CN.md +26 -22
  4. package/crates/unicli-atspi/src/errors.rs +2 -2
  5. package/crates/unicli-uia/src/errors.rs +1 -1
  6. package/dist/commands/compute.d.ts.map +1 -1
  7. package/dist/commands/compute.js +1 -1
  8. package/dist/commands/compute.js.map +1 -1
  9. package/dist/commands/doctor-compute.js +11 -7
  10. package/dist/commands/doctor-compute.js.map +1 -1
  11. package/dist/commands/lint.js +3 -3
  12. package/dist/commands/lint.js.map +1 -1
  13. package/dist/commands/migrate-schema.d.ts.map +1 -1
  14. package/dist/commands/migrate-schema.js +26 -22
  15. package/dist/commands/migrate-schema.js.map +1 -1
  16. package/dist/discovery/loader.d.ts.map +1 -1
  17. package/dist/discovery/loader.js +47 -2
  18. package/dist/discovery/loader.js.map +1 -1
  19. package/dist/electron-apps.d.ts +1 -1
  20. package/dist/electron-apps.d.ts.map +1 -1
  21. package/dist/electron-apps.js +2 -2
  22. package/dist/electron-apps.js.map +1 -1
  23. package/dist/engine/executor.d.ts +1 -1
  24. package/dist/engine/executor.js +7 -7
  25. package/dist/engine/executor.js.map +1 -1
  26. package/dist/engine/repair/remedies.js +3 -3
  27. package/dist/engine/repair/remedies.js.map +1 -1
  28. package/dist/engine/steps/desktop-ax.d.ts +4 -0
  29. package/dist/engine/steps/desktop-ax.d.ts.map +1 -1
  30. package/dist/engine/steps/desktop-ax.js +8 -0
  31. package/dist/engine/steps/desktop-ax.js.map +1 -1
  32. package/dist/engine/steps/desktop-sidecar.d.ts +1 -1
  33. package/dist/engine/steps/desktop-sidecar.js +1 -1
  34. package/dist/engine/steps/index.d.ts +1 -1
  35. package/dist/engine/steps/index.d.ts.map +1 -1
  36. package/dist/engine/steps/index.js +1 -1
  37. package/dist/engine/steps/index.js.map +1 -1
  38. package/dist/engine/steps/visual.d.ts +47 -0
  39. package/dist/engine/steps/visual.d.ts.map +1 -0
  40. package/dist/engine/steps/visual.js +66 -0
  41. package/dist/engine/steps/visual.js.map +1 -0
  42. package/dist/engine/transport/mcp-browser.d.ts +1 -1
  43. package/dist/engine/transport/mcp-browser.js +1 -1
  44. package/dist/manifest-compact.txt +2 -2
  45. package/dist/manifest-search.json +1 -1
  46. package/dist/manifest.json +68 -54
  47. package/dist/transport/adapters/desktop-atspi.js +1 -1
  48. package/dist/transport/adapters/desktop-atspi.js.map +1 -1
  49. package/dist/transport/adapters/desktop-ax-background-activation-swift.d.ts +9 -0
  50. package/dist/transport/adapters/desktop-ax-background-activation-swift.d.ts.map +1 -0
  51. package/dist/transport/adapters/desktop-ax-background-activation-swift.js +99 -0
  52. package/dist/transport/adapters/desktop-ax-background-activation-swift.js.map +1 -0
  53. package/dist/transport/adapters/desktop-ax-background-click-swift.d.ts.map +1 -1
  54. package/dist/transport/adapters/desktop-ax-background-click-swift.js +10 -133
  55. package/dist/transport/adapters/desktop-ax-background-click-swift.js.map +1 -1
  56. package/dist/transport/adapters/desktop-ax-background-click.d.ts +1 -3
  57. package/dist/transport/adapters/desktop-ax-background-click.d.ts.map +1 -1
  58. package/dist/transport/adapters/desktop-ax-background-click.js +1 -69
  59. package/dist/transport/adapters/desktop-ax-background-click.js.map +1 -1
  60. package/dist/transport/adapters/desktop-ax-background-dispatch-swift.d.ts +9 -0
  61. package/dist/transport/adapters/desktop-ax-background-dispatch-swift.d.ts.map +1 -0
  62. package/dist/transport/adapters/desktop-ax-background-dispatch-swift.js +169 -0
  63. package/dist/transport/adapters/desktop-ax-background-dispatch-swift.js.map +1 -0
  64. package/dist/transport/adapters/desktop-ax-background-input-swift.d.ts +23 -0
  65. package/dist/transport/adapters/desktop-ax-background-input-swift.d.ts.map +1 -0
  66. package/dist/transport/adapters/desktop-ax-background-input-swift.js +157 -0
  67. package/dist/transport/adapters/desktop-ax-background-input-swift.js.map +1 -0
  68. package/dist/transport/adapters/desktop-ax-background-input.d.ts +13 -0
  69. package/dist/transport/adapters/desktop-ax-background-input.d.ts.map +1 -0
  70. package/dist/transport/adapters/desktop-ax-background-input.js +124 -0
  71. package/dist/transport/adapters/desktop-ax-background-input.js.map +1 -0
  72. package/dist/transport/adapters/desktop-ax-background-window-swift.d.ts +9 -0
  73. package/dist/transport/adapters/desktop-ax-background-window-swift.d.ts.map +1 -0
  74. package/dist/transport/adapters/desktop-ax-background-window-swift.js +110 -0
  75. package/dist/transport/adapters/desktop-ax-background-window-swift.js.map +1 -0
  76. package/dist/transport/adapters/desktop-ax-swift.d.ts +1 -0
  77. package/dist/transport/adapters/desktop-ax-swift.d.ts.map +1 -1
  78. package/dist/transport/adapters/desktop-ax-swift.js +1 -0
  79. package/dist/transport/adapters/desktop-ax-swift.js.map +1 -1
  80. package/dist/transport/adapters/desktop-ax.d.ts +4 -1
  81. package/dist/transport/adapters/desktop-ax.d.ts.map +1 -1
  82. package/dist/transport/adapters/desktop-ax.js +57 -6
  83. package/dist/transport/adapters/desktop-ax.js.map +1 -1
  84. package/dist/transport/adapters/desktop-uia.js +1 -1
  85. package/dist/transport/adapters/desktop-uia.js.map +1 -1
  86. package/dist/transport/adapters/visual.d.ts +114 -0
  87. package/dist/transport/adapters/visual.d.ts.map +1 -0
  88. package/dist/transport/adapters/visual.js +473 -0
  89. package/dist/transport/adapters/visual.js.map +1 -0
  90. package/dist/transport/bus.d.ts +1 -1
  91. package/dist/transport/bus.js +3 -3
  92. package/dist/transport/bus.js.map +1 -1
  93. package/dist/transport/capability.d.ts.map +1 -1
  94. package/dist/transport/capability.js +32 -30
  95. package/dist/transport/capability.js.map +1 -1
  96. package/dist/transport/cascade.js +27 -27
  97. package/dist/transport/cascade.js.map +1 -1
  98. package/dist/transport/types.d.ts +5 -5
  99. package/dist/transport/types.d.ts.map +1 -1
  100. package/dist/transport/types.js +1 -1
  101. package/docs/operate/compute.md +20 -7
  102. package/docs/operate/focus-behavior.md +21 -12
  103. package/docs/operate/troubleshooting.md +17 -12
  104. package/package.json +5 -11
  105. package/server.json +2 -2
  106. package/skills/unicli/SKILL.md +1 -1
  107. package/skills/unicli-claude-code/SKILL.md +1 -1
  108. package/skills/unicli-hermes/SKILL.md +1 -1
  109. package/skills/unicli-repair/references/error-codes.md +7 -7
  110. package/src/adapters/_archived/README.md +6 -6
  111. package/src/adapters/_archived/apple-music/rate-album.yaml +15 -15
  112. package/src/adapters/_archived/archive.json +2 -2
  113. package/src/adapters/figma/export-selected.yaml +16 -16
  114. package/src/adapters/openalex/works.test.ts +40 -32
  115. package/src/adapters/zoom/toggle-mute.yaml +1 -1
  116. package/dist/engine/steps/cua.d.ts +0 -41
  117. package/dist/engine/steps/cua.d.ts.map +0 -1
  118. package/dist/engine/steps/cua.js +0 -59
  119. package/dist/engine/steps/cua.js.map +0 -1
  120. package/dist/transport/adapters/cua.d.ts +0 -239
  121. package/dist/transport/adapters/cua.d.ts.map +0 -1
  122. package/dist/transport/adapters/cua.js +0 -661
  123. package/dist/transport/adapters/cua.js.map +0 -1
  124. package/src/adapters/cua/bench-list.yaml +0 -28
  125. package/src/adapters/cua/bench-run.yaml +0 -40
@@ -2,24 +2,33 @@
2
2
 
3
3
  `unicli compute` defaults structured transports to `focus: false` for actuating
4
4
  verbs. Use `--focus` or `focus: true` only when the target app must be brought
5
- forward before the action can succeed. CUA is the visual fallback and is treated
6
- as focus-taking when the cascade reaches it.
5
+ forward before the action can succeed. The visual fallback is treated as
6
+ focus-taking when the cascade reaches it.
7
7
 
8
8
  ## Defaults
9
9
 
10
- | Verb | desktop-ax (macOS) | desktop-uia (Windows) | desktop-atspi (Linux) | cdp-browser | cua |
11
- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
12
- | `compute click` | Uses `AXUIElementPerformAction(..., AXPress)` without app activation. Proof: [desktop-ax-swift.ts](../../src/transport/adapters/desktop-ax-swift.ts). | Descendant refs prefer native UIA `InvokePattern.Invoke`, `TogglePattern.Toggle`, or `SelectionItemPattern.Select`, then fall back to bounded HWND `PostMessageW` click. Proof: [invoke.rs](../../crates/unicli-uia/src/invoke.rs). | Descendant refs prefer native AT-SPI `ActionProxy.do_action(0)`, then fall back to bounded X11/Wayland click helpers. Top-level X11 refs use `wmctrl`; AT-SPI-only synthetic refs use `ComponentProxy.grab_focus()`. Proof: [invoke.rs](../../crates/unicli-atspi/src/invoke.rs). | Uses the attached renderer page and does not activate the browser window. Proof: [cdp-browser.ts](../../src/transport/adapters/cdp-browser.ts). | Cascade passes `focus: true`; visual backend may move cursor or focus. Proof: [cua.ts](../../src/transport/adapters/cua.ts). |
13
- | `compute type` | Uses `AXUIElementSetAttributeValue` when possible, without activation. Proof: [desktop-ax-swift.ts](../../src/transport/adapters/desktop-ax-swift.ts). | Descendant refs prefer native UIA `ValuePattern.SetValue`; numeric values can fall through to `RangeValuePattern.SetValue` before bounded click plus `SendInput`. Proof: [invoke.rs](../../crates/unicli-uia/src/invoke.rs). | Descendant refs prefer native AT-SPI `ValueProxy.set_current_value(...)` or `EditableTextProxy.set_text_contents(...)`, then fall back to display-server text helpers. Proof: [invoke.rs](../../crates/unicli-atspi/src/invoke.rs). | Types through the attached renderer page. Proof: [cdp-browser.ts](../../src/transport/adapters/cdp-browser.ts). | Cascade passes `focus: true`; visual typing may move cursor or focus. Proof: [cua.ts](../../src/transport/adapters/cua.ts). |
14
- | `compute press` | Uses AX action dispatch when a ref/app scope is available; global key combos may require foreground app focus. Proof: [desktop-ax.ts](../../src/transport/adapters/desktop-ax.ts). | Planned per-window key dispatch keeps foreground changes behind `focus: true`. Proof: [unicli-uia main.rs](../../crates/unicli-uia/src/main.rs). | Uses display-server helpers for fallback key dispatch: `xdotool` on X11, `wtype` for printable Wayland keys, and `ydotool` for supported Wayland modifier combos. Proof: [input.rs](../../crates/unicli-atspi/src/input.rs). | Sends key events to the attached renderer page. Proof: [cdp-browser.ts](../../src/transport/adapters/cdp-browser.ts). | Cascade passes `focus: true`; visual key events may focus the active surface. Proof: [cua.ts](../../src/transport/adapters/cua.ts). |
15
- | `compute scroll` | Uses `AXScrollToVisible` through the AX element action path without activation. Proof: [desktop-ax-swift.ts](../../src/transport/adapters/desktop-ax-swift.ts). | Descendant refs prefer native UIA `ScrollPattern.Scroll(...)`, then fall back to `SendInput` wheel dispatch. Top-level window refs are foregrounded before `SendInput`. Proof: [input.rs](../../crates/unicli-uia/src/input.rs). | Descendant refs prefer native AT-SPI `Component.scroll_to(...)`, then fall back to display-server wheel helpers. Top-level refs are activated before helper wheel dispatch. Proof: [input.rs](../../crates/unicli-atspi/src/input.rs). | Sends wheel events to the attached renderer page. Proof: [cdp-browser.ts](../../src/transport/adapters/cdp-browser.ts). | Cascade passes `focus: true`; visual scrolling may move the cursor or active surface. Proof: [cua.ts](../../src/transport/adapters/cua.ts). |
16
- | `compute screenshot` | Reads window/screen state without activation; may require Screen Recording permission. Proof: [desktop-ax.ts](../../src/transport/adapters/desktop-ax.ts). | Descendant refs crop the owning HWND/GDI bitmap when bounds are known; top-level refs capture the window bitmap. Proof: [screenshot.rs](../../crates/unicli-uia/src/screenshot.rs). | Top-level X11 window refs capture with `import -window <id>`; Wayland refs with known bounds capture with `grim -g`. Other helper paths activate the target before screenshot. Proof: [screenshot.rs](../../crates/unicli-atspi/src/screenshot.rs). | Captures the attached renderer page. Proof: [cdp-browser.ts](../../src/transport/adapters/cdp-browser.ts). | Backend-specific screenshot behavior. Proof: [cua.ts](../../src/transport/adapters/cua.ts). |
10
+ | Verb | desktop-ax (macOS) | desktop-uia (Windows) | desktop-atspi (Linux) | cdp-browser | visual fallback |
11
+ | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
12
+ | `compute click` | Uses `AXUIElementPerformAction(..., AXPress)` first; if AX fails and ref/window coordinates are present, falls back to pid/window-addressed `ax_background_click` without foregrounding the app. Proof: [desktop-ax.ts](../../src/transport/adapters/desktop-ax.ts), [desktop-ax-background-input-swift.ts](../../src/transport/adapters/desktop-ax-background-input-swift.ts). | Descendant refs prefer native UIA `InvokePattern.Invoke`, `TogglePattern.Toggle`, or `SelectionItemPattern.Select`, then fall back to bounded HWND `PostMessageW` click. Proof: [invoke.rs](../../crates/unicli-uia/src/invoke.rs). | Descendant refs prefer native AT-SPI `ActionProxy.do_action(0)`, then fall back to bounded X11/Wayland click helpers. Top-level X11 refs use `wmctrl`; AT-SPI-only synthetic refs use `ComponentProxy.grab_focus()`. Proof: [invoke.rs](../../crates/unicli-atspi/src/invoke.rs). | Uses the attached renderer page and does not activate the browser window. Proof: [cdp-browser.ts](../../src/transport/adapters/cdp-browser.ts). | Cascade passes `focus: true`; visual backend may move cursor or focus. |
13
+ | `compute type` | Uses `AXUIElementSetAttributeValue` first; if AX fails and an app/ref target is scoped, falls back to `ax_background_type` with Unicode key events posted to the target pid/window. Proof: [desktop-ax.ts](../../src/transport/adapters/desktop-ax.ts), [desktop-ax-background-input.ts](../../src/transport/adapters/desktop-ax-background-input.ts). | Descendant refs prefer native UIA `ValuePattern.SetValue`; numeric values can fall through to `RangeValuePattern.SetValue` before bounded click plus `SendInput`. Proof: [invoke.rs](../../crates/unicli-uia/src/invoke.rs). | Descendant refs prefer native AT-SPI `ValueProxy.set_current_value(...)` or `EditableTextProxy.set_text_contents(...)`, then fall back to display-server text helpers. Proof: [invoke.rs](../../crates/unicli-atspi/src/invoke.rs). | Types through the attached renderer page. Proof: [cdp-browser.ts](../../src/transport/adapters/cdp-browser.ts). | Cascade passes `focus: true`; visual typing may move cursor or focus. |
14
+ | `compute press` | Uses `ax_background_press` for app/ref-scoped key combos before visual fallback, posting key events to the target pid/window. Unscoped global key combos still require a focus-taking fallback. Proof: [cascade.ts](../../src/transport/cascade.ts), [desktop-ax-background-input.ts](../../src/transport/adapters/desktop-ax-background-input.ts). | Planned per-window key dispatch keeps foreground changes behind `focus: true`. Proof: [unicli-uia main.rs](../../crates/unicli-uia/src/main.rs). | Uses display-server helpers for fallback key dispatch: `xdotool` on X11, `wtype` for printable Wayland keys, and `ydotool` for supported Wayland modifier combos. Proof: [input.rs](../../crates/unicli-atspi/src/input.rs). | Sends key events to the attached renderer page. Proof: [cdp-browser.ts](../../src/transport/adapters/cdp-browser.ts). | Cascade passes `focus: true`; visual key events may focus the active surface. |
15
+ | `compute scroll` | Uses `AXScrollToVisible` through the AX element action path without activation. Proof: [desktop-ax-swift.ts](../../src/transport/adapters/desktop-ax-swift.ts). | Descendant refs prefer native UIA `ScrollPattern.Scroll(...)`, then fall back to `SendInput` wheel dispatch. Top-level window refs are foregrounded before `SendInput`. Proof: [input.rs](../../crates/unicli-uia/src/input.rs). | Descendant refs prefer native AT-SPI `Component.scroll_to(...)`, then fall back to display-server wheel helpers. Top-level refs are activated before helper wheel dispatch. Proof: [input.rs](../../crates/unicli-atspi/src/input.rs). | Sends wheel events to the attached renderer page. Proof: [cdp-browser.ts](../../src/transport/adapters/cdp-browser.ts). | Cascade passes `focus: true`; visual scrolling may move the cursor or active surface. |
16
+ | `compute screenshot` | Reads window/screen state without activation; may require Screen Recording permission. Proof: [desktop-ax.ts](../../src/transport/adapters/desktop-ax.ts). | Descendant refs crop the owning HWND/GDI bitmap when bounds are known; top-level refs capture the window bitmap. Proof: [screenshot.rs](../../crates/unicli-uia/src/screenshot.rs). | Top-level X11 window refs capture with `import -window <id>`; Wayland refs with known bounds capture with `grim -g`. Other helper paths activate the target before screenshot. Proof: [screenshot.rs](../../crates/unicli-atspi/src/screenshot.rs). | Captures the attached renderer page. Proof: [cdp-browser.ts](../../src/transport/adapters/cdp-browser.ts). | Backend-specific screenshot behavior. |
17
17
 
18
18
  ## Operational Notes
19
19
 
20
20
  - `compute click`, `compute type`, `compute press`, and `compute scroll` pass
21
21
  `focus: false` to AX, UIA, AT-SPI, and CDP unless the caller sets `--focus`
22
22
  or `focus: true`.
23
+ - macOS background input is not a global HID path. It resolves a running app
24
+ and on-screen window, installs per-process event taps for the previous and
25
+ target apps, sends an AppKit activation primer plus a center primer only when
26
+ the target is not already frontmost, then posts events with target pid and
27
+ window fields.
28
+ - The macOS background path uses Accessibility and Input Monitoring
29
+ permissions. It may still fail for minimized, hidden, off-screen, disabled, or
30
+ security-hardened windows; those failures remain structured errors rather
31
+ than implicit foregrounding.
23
32
  - Linux AT-SPI refs from `compute snapshot` / `compute find --first` can target
24
33
  `compute click`, `compute type`, `compute scroll`, `compute screenshot`,
25
34
  `compute wait`, `compute observe`, and `compute assert`. Descendant click,
@@ -33,8 +42,8 @@ as focus-taking when the cascade reaches it.
33
42
  and scroll prefer native UIA patterns before bounded fallback paths.
34
43
  - Linux AT-SPI `compute press` remains a global display-server helper path, so
35
44
  it targets the active desktop surface.
36
- - CUA is a fallback for cases where structured transports cannot see or act on
37
- the target. Because it is visual-provider based, the cascade dispatches CUA
38
- actions with `focus: true`.
45
+ - The visual backend is a fallback for cases where structured transports cannot
46
+ see or act on the target. Because it is pixel/provider based, the cascade
47
+ dispatches those actions with `focus: true`.
39
48
  - If a target is minimized, hidden, disabled, or off screen, prefer a fresh
40
49
  `compute snapshot` and a structured retry before enabling `--focus`.
@@ -11,7 +11,7 @@ path.
11
11
 
12
12
  Remedy: run `unicli doctor compute --install`, then retry the compute command.
13
13
 
14
- Fallback: use CDP-backed Electron/browser control or CUA screenshot fallback if
14
+ Fallback: use CDP-backed Electron/browser control or visual fallback if
15
15
  configured.
16
16
 
17
17
  ## desktop-uia.startup_failed
@@ -46,7 +46,7 @@ Cause: the target element does not expose the UIA Invoke pattern.
46
46
  Remedy: use `unicli compute type`, `unicli compute press`, or focus the control
47
47
  first and retry.
48
48
 
49
- Fallback: use CUA when no structured pattern is exposed.
49
+ Fallback: use visual fallback when no structured pattern is exposed.
50
50
 
51
51
  ## desktop-uia.timeout
52
52
 
@@ -92,7 +92,7 @@ expected path.
92
92
 
93
93
  Remedy: run `unicli doctor compute --install`, then retry.
94
94
 
95
- Fallback: use CDP-backed Electron/browser control or CUA screenshot fallback if
95
+ Fallback: use CDP-backed Electron/browser control or visual fallback if
96
96
  configured.
97
97
 
98
98
  ## desktop-atspi.dbus_blocked
@@ -110,7 +110,7 @@ Cause: the target app does not expose a usable AT-SPI tree.
110
110
  Remedy: enable accessibility support for the app. Electron apps may need an
111
111
  accessibility flag at launch.
112
112
 
113
- Fallback: use CDP for Electron/browser targets or CUA screenshot fallback.
113
+ Fallback: use CDP for Electron/browser targets or visual fallback.
114
114
 
115
115
  ## desktop-atspi.atspi_apps
116
116
 
@@ -120,7 +120,7 @@ Remedy: ensure the AT-SPI bus is running. Uni-CLI prefers `wmctrl -lG -p` for
120
120
  real X11 window ids and geometry, but can fall back to AT-SPI-only registry
121
121
  roots when `wmctrl` is missing or empty.
122
122
 
123
- Fallback: target an Electron/browser app through CDP, or use CUA fallback.
123
+ Fallback: target an Electron/browser app through CDP, or use visual fallback.
124
124
 
125
125
  ## desktop-atspi.atspi_windows
126
126
 
@@ -130,7 +130,7 @@ Remedy: install `wmctrl` when real X11 window ids are needed. On Wayland or
130
130
  minimal environments, verify the AT-SPI bus is running so Uni-CLI can use
131
131
  synthetic `atspi-root-N` windows from the accessibility registry.
132
132
 
133
- Fallback: use `compute snapshot` on another transport or CUA fallback.
133
+ Fallback: use `compute snapshot` on another transport or visual fallback.
134
134
 
135
135
  ## desktop-atspi.wayland-input
136
136
 
@@ -157,7 +157,7 @@ Remedy: install ImageMagick `import` for X11 top-level window capture, or
157
157
  install `grim` for Wayland top-level bounds capture. Install
158
158
  `gnome-screenshot` / `grim` for display-server fallback capture.
159
159
 
160
- Fallback: use CDP for Electron/browser targets or CUA screenshot fallback.
160
+ Fallback: use CDP for Electron/browser targets or visual fallback.
161
161
 
162
162
  ## desktop-atspi.invalid_input
163
163
 
@@ -275,13 +275,18 @@ for example `sudo apt-get install libgtk-3-bin`.
275
275
  Fallback: start the app manually, then use `compute attach`, `compute snapshot`,
276
276
  or the native desktop transport for follow-up actions.
277
277
 
278
- ## cua.no_backend
278
+ ## visual.no_backend
279
279
 
280
- Cause: screenshot/VLM fallback is enabled in the cascade, but no backend API key
281
- is configured.
280
+ Cause: visual fallback is enabled in the cascade, but no backend endpoint or
281
+ credential is configured.
282
282
 
283
- Remedy: set a supported backend environment variable such as
284
- `ANTHROPIC_API_KEY`, `TRYCUA_API_KEY`, or `OPENAI_API_KEY`.
283
+ Remedy: set the generic visual backend environment:
284
+
285
+ ```bash
286
+ export VISUAL_BACKEND=remote
287
+ export VISUAL_BACKEND_ENDPOINT=http://localhost:8800
288
+ export VISUAL_BACKEND_API_KEY=...
289
+ ```
285
290
 
286
291
  Fallback: use structured AX/UIA/AT-SPI/CDP control where possible.
287
292
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenalexa/unicli",
3
- "version": "0.221.1",
3
+ "version": "0.222.0",
4
4
  "description": "Agent execution substrate for web, apps, local tools, and system capabilities. Self-repairing CLI catalog with stdio + Streamable HTTP MCP server.",
5
5
  "packageManager": "npm@11.14.0",
6
6
  "type": "module",
@@ -96,9 +96,9 @@
96
96
  "types": "./dist/transport/adapters/desktop-ax.d.ts",
97
97
  "import": "./dist/transport/adapters/desktop-ax.js"
98
98
  },
99
- "./transport/cua": {
100
- "types": "./dist/transport/adapters/cua.d.ts",
101
- "import": "./dist/transport/adapters/cua.js"
99
+ "./transport/visual": {
100
+ "types": "./dist/transport/adapters/visual.d.ts",
101
+ "import": "./dist/transport/adapters/visual.js"
102
102
  },
103
103
  "./browser/cdp": {
104
104
  "types": "./dist/browser/cdp-client.d.ts",
@@ -148,7 +148,7 @@
148
148
  "stats": "tsx scripts/build-manifest.js && tsx scripts/count-stats.ts && tsx scripts/build-readme.ts && tsx scripts/build-agents.ts",
149
149
  "stats:check": "tsx scripts/count-consistency.ts",
150
150
  "build:agents": "tsx scripts/build-agents.ts",
151
- "test": "vitest run --project unit",
151
+ "test": "vitest run --project unit --maxWorkers=1 --reporter=dot",
152
152
  "test:adapter": "vitest run --project adapter",
153
153
  "test:perf": "vitest run --project perf",
154
154
  "compute:smoke": "tsx scripts/compute-live-smoke.ts",
@@ -239,12 +239,6 @@
239
239
  "ws": "^8.20.0",
240
240
  "zod": "^4.3.6"
241
241
  },
242
- "optionalDependencies": {
243
- "@zenalexa/unicli-atspi-linux-arm64": "0.218.1",
244
- "@zenalexa/unicli-atspi-linux-x64": "0.218.1",
245
- "@zenalexa/unicli-uia-win32-arm64": "0.218.1",
246
- "@zenalexa/unicli-uia-win32-x64": "0.218.1"
247
- },
248
242
  "devDependencies": {
249
243
  "@ai-sdk/openai-compatible": "^2.0.41",
250
244
  "@base-ui/react": "^1.4.1",
package/server.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json",
3
3
  "name": "io.github.olo-dot-io/Uni-CLI",
4
4
  "description": "Self-repairing CLI catalog that exposes 282 websites, desktop apps, and external CLIs as one MCP server. 949 declarative YAML adapters and 1686 commands; structured error envelopes let agents fix failing adapters at runtime and retry.",
5
- "version": "0.221.1",
5
+ "version": "0.222.0",
6
6
  "repository": {
7
7
  "url": "https://github.com/olo-dot-io/Uni-CLI",
8
8
  "source": "github"
@@ -13,7 +13,7 @@
13
13
  "registryType": "npm",
14
14
  "registryBaseUrl": "https://registry.npmjs.org",
15
15
  "identifier": "@zenalexa/unicli",
16
- "version": "0.221.1",
16
+ "version": "0.222.0",
17
17
  "transport": {
18
18
  "type": "stdio"
19
19
  },
@@ -11,7 +11,7 @@ description: >
11
11
  major platform; run desktop workflows or system tasks; or when the user says
12
12
  "unicli", "scrape", "fetch from", "get trending", "check [site]", "find on
13
13
  [platform]", "获取", "查询", "抓取".
14
- version: 0.221.1
14
+ version: 0.222.0
15
15
  category: core
16
16
  depends-on:
17
17
  - talk-normal
@@ -6,7 +6,7 @@ description: >
6
6
  newlines, or inline JSON — shell-quoted invocations hit TC0 circuit
7
7
  limits and drop to <50% success above ICS=4. Also covers --describe
8
8
  introspection and next_actions-driven navigation.
9
- version: 0.221.1
9
+ version: 0.222.0
10
10
  depends-on:
11
11
  - talk-normal
12
12
  triggers:
@@ -4,7 +4,7 @@ description: >
4
4
  Use Uni-CLI to interact with 237 websites, desktop apps, and system tools.
5
5
  Trigger when: user asks to check a website, fetch data, control a desktop app,
6
6
  or interact with social media, news, finance, or AI platforms.
7
- version: 0.221.1
7
+ version: 0.222.0
8
8
  depends-on:
9
9
  - talk-normal
10
10
  triggers:
@@ -12,7 +12,7 @@ type Envelope<T> =
12
12
  | { ok: false; error: EnvelopeError; elapsedMs?: number };
13
13
 
14
14
  interface EnvelopeError {
15
- transport: TransportKind; // "fetch" | "cdp-browser" | "subprocess" | "cua" | "http" | "desktop-*" | ...
15
+ transport: TransportKind; // "fetch" | "cdp-browser" | "subprocess" | "visual" | "http" | "desktop-*" | ...
16
16
  adapter_path?: string; // relative to repo or ~/.unicli/adapters
17
17
  step: number; // 0-indexed pipeline step
18
18
  action: string; // step kind: "fetch", "select", "map", "click", ...
@@ -110,13 +110,13 @@ automatically; surfaces here as a quick map. Full doc anchors live under
110
110
  | `cdp-browser.attach_failed` | Check the CDP port; relaunch with remote debugging |
111
111
  | `cdp-browser.electron_running_without_debug_port` | `unicli compute launch <app> --debug-port 9229` |
112
112
 
113
- ### CUA / Compute
113
+ ### Visual / Compute
114
114
 
115
- | Capability | Fix |
116
- | --------------------------------------- | -------------------------------------------- |
117
- | `cua.no_backend` | Configure a CUA backend key for VLM fallback |
118
- | `compute.<step>.no-transport-available` | `unicli doctor compute` |
119
- | `compute.compute_find.ref-store` | `unicli compute snapshot`, then retry find |
115
+ | Capability | Fix |
116
+ | --------------------------------------- | ---------------------------------------------------------------- |
117
+ | `visual.no_backend` | Configure `VISUAL_BACKEND_ENDPOINT` and `VISUAL_BACKEND_API_KEY` |
118
+ | `compute.<step>.no-transport-available` | `unicli doctor compute` |
119
+ | `compute.compute_find.ref-store` | `unicli compute snapshot`, then retry find |
120
120
 
121
121
  ### Compute edge cases (suffix on `minimum_capability`)
122
122
 
@@ -4,9 +4,9 @@ These adapters are preserved for provenance but are outside active discovery.
4
4
  The loader, manifest builder, conformance report, and quarantine repair list
5
5
  skip underscore-prefixed adapter directories.
6
6
 
7
- | Site | Commands | Archived on | Replacement |
8
- | ----------- | ----------- | ----------- | ----------------------------------------------------------------------- |
9
- | apple-music | rate-album | 2026-05-06 | `unicli macos music-now`; `unicli macos music-control <action>` |
10
- | az | account | 2026-05-06 | `az account list --output json` through external CLI passthrough |
11
- | ctrip | hot, search | 2026-05-06 | `unicli web read` or browser/CUA against an authenticated Ctrip session |
12
- | gcloud | projects | 2026-05-06 | `gcloud projects list --format=json` through external CLI passthrough |
7
+ | Site | Commands | Archived on | Replacement |
8
+ | ----------- | ----------- | ----------- | -------------------------------------------------------------------------- |
9
+ | apple-music | rate-album | 2026-05-06 | `unicli macos music-now`; `unicli macos music-control <action>` |
10
+ | az | account | 2026-05-06 | `az account list --output json` through external CLI passthrough |
11
+ | ctrip | hot, search | 2026-05-06 | `unicli web read` or browser/Visual against an authenticated Ctrip session |
12
+ | gcloud | projects | 2026-05-06 | `gcloud projects list --format=json` through external CLI passthrough |
@@ -1,17 +1,17 @@
1
1
  # @owner src/adapters/_archived/apple-music/rate-album.yaml
2
- # @does Preserve the archived Apple Music CUA rating demo outside active discovery.
3
- # @needs macOS Music app, desktop AX transport, CUA backend, caller-provided star coordinates
2
+ # @does Preserve the archived Apple Music Visual rating demo outside active discovery.
3
+ # @needs macOS Music app, desktop AX transport, Visual backend, caller-provided star coordinates
4
4
  # @feeds src/adapters/_archived/archive.json provenance, historical adapter review
5
5
  # @breaks Moving back under an active site would reintroduce an archive-only discovered site.
6
6
  site: apple-music
7
7
  name: rate-album
8
- description: Rate the currently-playing Apple Music album via AX menu + CUA click
8
+ description: Rate the currently-playing Apple Music album via AX menu + Visual click
9
9
  type: browser
10
10
  strategy: ui
11
11
  domain: music.apple.com
12
12
  browser: false
13
13
  quarantine: true
14
- quarantineReason: Requires macOS + Apple Music desktop app + a CUA backend (quarantined 2026-04-15)
14
+ quarantineReason: Requires macOS + Apple Music desktop app + a Visual backend (quarantined 2026-04-15)
15
15
  args:
16
16
  stars:
17
17
  type: int
@@ -33,34 +33,34 @@ pipeline:
33
33
  - ax_focus:
34
34
  app: Music
35
35
 
36
- - cua_wait:
36
+ - visual_wait:
37
37
  ms: 300
38
38
 
39
- - cua_snapshot: {}
39
+ - visual_snapshot: {}
40
40
 
41
- - cua_ask:
41
+ - visual_ask:
42
42
  question: Is an album currently displayed with a star-rating row visible?
43
43
 
44
- - cua_click:
44
+ - visual_click:
45
45
  x: ${{ args.x }}
46
46
  y: ${{ args.y }}
47
47
 
48
- - cua_assert:
48
+ - visual_assert:
49
49
  predicate: The album now shows ${{ args.stars }} filled stars
50
50
 
51
51
  columns: [backend, stars]
52
52
 
53
53
  capabilities:
54
54
  [
55
- "cua.ask",
56
- "cua.assert",
57
- "cua.click",
58
- "cua.snapshot",
59
- "cua.wait",
55
+ "visual.ask",
56
+ "visual.assert",
57
+ "visual.click",
58
+ "visual.snapshot",
59
+ "visual.wait",
60
60
  "desktop-ax.focus",
61
61
  "desktop-ax.launch_app",
62
62
  ]
63
- minimum_capability: cua.click
63
+ minimum_capability: visual.click
64
64
  trust: user
65
65
  confidentiality: public
66
66
  schema_version: v2
@@ -7,7 +7,7 @@
7
7
  "commands": ["rate-album"],
8
8
  "original_paths": ["src/adapters/apple-music/rate-album.yaml"],
9
9
  "archived_paths": ["src/adapters/_archived/apple-music/rate-album.yaml"],
10
- "reason": "Host-app CUA demo requires the macOS Music app and a CUA backend; active Apple Music controls remain under the macos adapter.",
10
+ "reason": "Host-app Visual demo requires the macOS Music app and a Visual backend; active Apple Music controls remain under the macos adapter.",
11
11
  "replacement": "unicli macos music-now; unicli macos music-control <action>"
12
12
  },
13
13
  {
@@ -30,7 +30,7 @@
30
30
  "src/adapters/_archived/ctrip/search.yaml"
31
31
  ],
32
32
  "reason": "Public Ctrip endpoints were verified broken or CAPTCHA-gated on 2026-05-05, with no stable public replacement captured.",
33
- "replacement": "Use the web adapter or browser/CUA flow against an authenticated Ctrip session."
33
+ "replacement": "Use the web adapter or browser/Visual flow against an authenticated Ctrip session."
34
34
  },
35
35
  {
36
36
  "site": "gcloud",
@@ -1,21 +1,21 @@
1
- # CUA+AX demo — export the currently-selected Figma frame.
1
+ # Visual+AX demo — export the currently-selected Figma frame.
2
2
  #
3
3
  # Composes three transports:
4
4
  # 1. desktop-ax → launch & focus the desktop Figma app
5
- # 2. cua → VLM confirms the export dialog is visible
5
+ # 2. visual → VLM confirms the export dialog is visible
6
6
  # 3. desktop-ax → click through the File > Export menu path
7
7
  #
8
- # Quarantined because the Figma desktop app and a VLM backend
9
- # (ANTHROPIC_API_KEY | TRYCUA_API_KEY | …) are both required.
8
+ # Quarantined because the Figma desktop app and a visual backend are both
9
+ # required.
10
10
  site: figma
11
11
  name: export-selected
12
- description: Export the currently-selected Figma frame via CUA + macOS AX
12
+ description: Export the currently-selected Figma frame via Visual + macOS AX
13
13
  type: browser
14
14
  strategy: ui
15
15
  domain: figma.com
16
16
  browser: false
17
17
  quarantine: true
18
- quarantineReason: Requires macOS + Figma desktop app + a CUA backend (ANTHROPIC_API_KEY etc.) (quarantined 2026-04-15)
18
+ quarantineReason: Requires macOS + Figma desktop app + a visual backend (quarantined 2026-04-15)
19
19
  args:
20
20
  format:
21
21
  type: str
@@ -30,12 +30,12 @@ pipeline:
30
30
  - ax_focus:
31
31
  app: Figma
32
32
 
33
- - cua_wait:
33
+ - visual_wait:
34
34
  ms: 500
35
35
 
36
- - cua_snapshot: {}
36
+ - visual_snapshot: {}
37
37
 
38
- - cua_ask:
38
+ - visual_ask:
39
39
  question: Is a frame currently selected on the Figma canvas?
40
40
 
41
41
  - ax_menu_select:
@@ -44,10 +44,10 @@ pipeline:
44
44
  - File
45
45
  - Export ${{ args.format }}
46
46
 
47
- - cua_wait:
47
+ - visual_wait:
48
48
  ms: 800
49
49
 
50
- - cua_assert:
50
+ - visual_assert:
51
51
  predicate: The Figma export dialog is visible with a Save button
52
52
 
53
53
  columns: [backend, ok]
@@ -55,15 +55,15 @@ columns: [backend, ok]
55
55
  # schema-v2 metadata — injected by `unicli migrate schema-v2`
56
56
  capabilities:
57
57
  [
58
- "cua.ask",
59
- "cua.assert",
60
- "cua.snapshot",
61
- "cua.wait",
58
+ "visual.ask",
59
+ "visual.assert",
60
+ "visual.snapshot",
61
+ "visual.wait",
62
62
  "desktop-ax.focus",
63
63
  "desktop-ax.launch_app",
64
64
  "desktop-ax.menu_select",
65
65
  ]
66
- minimum_capability: cua.snapshot
66
+ minimum_capability: visual.snapshot
67
67
  trust: user
68
68
  confidentiality: public
69
69
  schema_version: v2
@@ -31,38 +31,46 @@ describe("openalex agent-facing commands", () => {
31
31
  });
32
32
 
33
33
  it("maps search rows", () => {
34
- expect(
35
- mapOpenAlexSearchRows(
36
- [
37
- {
38
- id: "https://openalex.org/W1234",
39
- doi: "https://doi.org/10.1/example",
40
- title: "A paper",
41
- publication_year: 2026,
42
- cited_by_count: 5,
43
- authorships: [{ author: { display_name: "Ada" } }],
44
- primary_location: { source: { display_name: "Journal" } },
45
- open_access: { is_oa: true },
46
- type: "article",
47
- },
48
- ],
49
- 20,
50
- ),
51
- ).toEqual([
52
- {
53
- rank: 1,
54
- id: "W1234",
55
- title: "A paper",
56
- year: 2026,
57
- citations: 5,
58
- firstAuthor: "Ada",
59
- venue: "Journal",
60
- openAccess: true,
61
- type: "article",
62
- doi: "10.1/example",
63
- url: "https://openalex.org/W1234",
64
- },
65
- ]);
34
+ const rows = mapOpenAlexSearchRows(
35
+ [
36
+ {
37
+ id: "https://openalex.org/W1234",
38
+ doi: "https://doi.org/10.1/example",
39
+ title: "A paper",
40
+ publication_year: 2026,
41
+ cited_by_count: 5,
42
+ authorships: [{ author: { display_name: "Ada" } }],
43
+ primary_location: { source: { display_name: "Journal" } },
44
+ open_access: { is_oa: true },
45
+ type: "article",
46
+ },
47
+ ],
48
+ 20,
49
+ );
50
+
51
+ expect(rows).toHaveLength(1);
52
+ expect(rows[0]).toMatchObject({
53
+ rank: 1,
54
+ id: "W1234",
55
+ title: "A paper",
56
+ year: 2026,
57
+ citations: 5,
58
+ firstAuthor: "Ada",
59
+ authors: ["Ada"],
60
+ venue: "Journal",
61
+ openAccess: true,
62
+ is_open_access: true,
63
+ type: "article",
64
+ doi: "10.1/example",
65
+ pdf_url: "",
66
+ openalex_id: "W1234",
67
+ source_adapter: "openalex",
68
+ source_url: "https://openalex.org/W1234",
69
+ url: "https://openalex.org/W1234",
70
+ });
71
+ expect(rows[0]?.retrieved_at).toEqual(
72
+ expect.stringMatching(/^\d{4}-\d{2}-\d{2}T/),
73
+ );
66
74
  });
67
75
 
68
76
  it("maps work detail rows", () => {
@@ -1,6 +1,6 @@
1
1
  # Pure AX demo — toggle microphone mute in an in-progress Zoom meeting.
2
2
  #
3
- # No CUA involved. Zoom's "Meeting > Mute/Unmute Audio" menu item is
3
+ # No Visual involved. Zoom's "Meeting > Mute/Unmute Audio" menu item is
4
4
  # deterministic and driven entirely through the Accessibility API.
5
5
  site: zoom
6
6
  name: toggle-mute
@@ -1,41 +0,0 @@
1
- /**
2
- * CUA pipeline step handlers — every cua_* action delegates to the
3
- * transport bus (`bus.require`/`adapter.open`/`adapter.action`). The bus
4
- * routes to whichever transport declares the step; `action()` never
5
- * throws — callers always receive an envelope.
6
- */
7
- import type { Envelope } from "../../core/envelope.js";
8
- import type { TransportBus, TransportContext } from "../../transport/types.js";
9
- /** Shared shape used by every cua_* handler. */
10
- export interface CuaStepContext {
11
- bus: TransportBus;
12
- transportCtx: TransportContext;
13
- platform?: NodeJS.Platform;
14
- }
15
- export declare function handleCuaSnapshot(ctx: CuaStepContext, params?: Record<string, unknown>): Promise<Envelope<unknown>>;
16
- export declare function handleCuaClick(ctx: CuaStepContext, params: Record<string, unknown>): Promise<Envelope<unknown>>;
17
- export declare function handleCuaType(ctx: CuaStepContext, params: Record<string, unknown>): Promise<Envelope<unknown>>;
18
- export declare function handleCuaKey(ctx: CuaStepContext, params: Record<string, unknown>): Promise<Envelope<unknown>>;
19
- export declare function handleCuaScroll(ctx: CuaStepContext, params: Record<string, unknown>): Promise<Envelope<unknown>>;
20
- export declare function handleCuaDrag(ctx: CuaStepContext, params: Record<string, unknown>): Promise<Envelope<unknown>>;
21
- export declare function handleCuaWait(ctx: CuaStepContext, params: Record<string, unknown>): Promise<Envelope<unknown>>;
22
- export declare function handleCuaAssert(ctx: CuaStepContext, params: Record<string, unknown>): Promise<Envelope<unknown>>;
23
- export declare function handleCuaAsk(ctx: CuaStepContext, params: Record<string, unknown>): Promise<Envelope<unknown>>;
24
- export declare function handleCuaBackend(ctx: CuaStepContext, params?: Record<string, unknown>): Promise<Envelope<unknown>>;
25
- export declare function handleCuaLaunch(ctx: CuaStepContext, params: Record<string, unknown>): Promise<Envelope<unknown>>;
26
- /** Kind → handler dispatch table (consumed by executor.dispatchBusStep in src/engine/executor.ts). */
27
- export declare const CUA_STEP_HANDLERS: {
28
- readonly cua_snapshot: typeof handleCuaSnapshot;
29
- readonly cua_click: typeof handleCuaClick;
30
- readonly cua_type: typeof handleCuaType;
31
- readonly cua_key: typeof handleCuaKey;
32
- readonly cua_scroll: typeof handleCuaScroll;
33
- readonly cua_drag: typeof handleCuaDrag;
34
- readonly cua_wait: typeof handleCuaWait;
35
- readonly cua_assert: typeof handleCuaAssert;
36
- readonly cua_ask: typeof handleCuaAsk;
37
- readonly cua_backend: typeof handleCuaBackend;
38
- readonly cua_launch: typeof handleCuaLaunch;
39
- };
40
- export type CuaStepKind = keyof typeof CUA_STEP_HANDLERS;
41
- //# sourceMappingURL=cua.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cua.d.ts","sourceRoot":"","sources":["../../../src/engine/steps/cua.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAGV,YAAY,EACZ,gBAAgB,EACjB,MAAM,0BAA0B,CAAC;AAElC,gDAAgD;AAChD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,YAAY,CAAC;IAClB,YAAY,EAAE,gBAAgB,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CAC5B;AAYD,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,cAAc,EACnB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAE5B;AAED,wBAAsB,cAAc,CAClC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAE5B;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAE5B;AAED,wBAAsB,YAAY,CAChC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAE5B;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAE5B;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAE5B;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAE5B;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAE5B;AAED,wBAAsB,YAAY,CAChC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAE5B;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,cAAc,EACnB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAE5B;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAE5B;AAED,sGAAsG;AACtG,eAAO,MAAM,iBAAiB;;;;;;;;;;;;CAYpB,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,iBAAiB,CAAC"}