@avasapp/agent-bridge 0.4.2 → 0.6.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 (65) hide show
  1. package/README.md +36 -14
  2. package/dist/adapters/ably.cjs +79 -3
  3. package/dist/adapters/ably.d.cts +2 -1
  4. package/dist/adapters/async-storage.cjs +158 -0
  5. package/dist/adapters/async-storage.d.cts +14 -0
  6. package/dist/adapters/device.cjs +1110 -0
  7. package/dist/adapters/device.d.cts +49 -0
  8. package/dist/adapters/expo-router.cjs +112 -6
  9. package/dist/adapters/expo-router.d.cts +1 -1
  10. package/dist/adapters/jotai.cjs +266 -0
  11. package/dist/adapters/jotai.d.cts +19 -0
  12. package/dist/adapters/react-native-mmkv.cjs +80 -0
  13. package/dist/adapters/react-native-mmkv.d.cts +3 -1
  14. package/dist/adapters/react-native-webview.d.cts +1 -1
  15. package/dist/adapters/react-navigation.cjs +293 -0
  16. package/dist/adapters/react-navigation.d.cts +55 -0
  17. package/dist/adapters/redux.cjs +322 -0
  18. package/dist/adapters/redux.d.cts +28 -0
  19. package/dist/adapters/secure-store.cjs +169 -0
  20. package/dist/adapters/secure-store.d.cts +28 -0
  21. package/dist/adapters/socket-io.cjs +77 -3
  22. package/dist/adapters/socket-io.d.cts +2 -1
  23. package/dist/adapters/tanstack-query.cjs +3 -0
  24. package/dist/adapters/tanstack-query.d.cts +13 -4
  25. package/dist/adapters/zustand.cjs +193 -22
  26. package/dist/adapters/zustand.d.cts +11 -15
  27. package/dist/{chunk-TA2OLPPT.js → chunk-Y6QFU5ON.js} +477 -165
  28. package/dist/cli.js +2370 -103
  29. package/dist/client/index.cjs +441 -136
  30. package/dist/client/index.d.ts +67 -4
  31. package/dist/client/index.js +5 -3
  32. package/dist/expo/index.d.cts +1 -1
  33. package/dist/network/index.cjs +320 -73
  34. package/dist/network/index.d.cts +18 -3
  35. package/dist/noop/async-storage.cjs +26 -0
  36. package/dist/noop/device.cjs +26 -0
  37. package/dist/noop/jotai.cjs +26 -0
  38. package/dist/noop/react-navigation.cjs +26 -0
  39. package/dist/noop/realtime.cjs +6 -1
  40. package/dist/noop/redux.cjs +28 -0
  41. package/dist/noop/secure-store.cjs +26 -0
  42. package/dist/realtime/index.cjs +71 -4
  43. package/dist/realtime/index.d.cts +21 -2
  44. package/dist/runtime/index.cjs +838 -128
  45. package/dist/runtime/index.d.cts +4 -2
  46. package/dist/store-common-j0cHHvBr.d.cts +23 -0
  47. package/dist/{types-BmpykP1P.d.cts → types-qlwdcGjt.d.cts} +22 -0
  48. package/entries/async-storage.cjs +9 -0
  49. package/entries/device.cjs +9 -0
  50. package/entries/jotai.cjs +9 -0
  51. package/entries/react-navigation.cjs +9 -0
  52. package/entries/redux.cjs +9 -0
  53. package/entries/secure-store.cjs +9 -0
  54. package/package.json +34 -2
  55. package/skills/agent-bridge/SKILL.md +70 -22
  56. package/skills/agent-bridge/references/device.md +21 -0
  57. package/skills/agent-bridge/references/flows.md +19 -8
  58. package/skills/agent-bridge/references/large-data.md +6 -6
  59. package/skills/agent-bridge/references/network.md +25 -7
  60. package/skills/agent-bridge/references/realtime.md +5 -5
  61. package/skills/agent-bridge/references/restore.md +25 -7
  62. package/skills/agent-bridge/references/screen.md +25 -11
  63. package/skills/agent-bridge/references/state.md +31 -11
  64. package/skills/agent-bridge/references/webview.md +9 -9
  65. package/skills/agent-bridge/references/writing-scenarios.md +3 -3
@@ -1,22 +1,36 @@
1
1
  # See and use the screen
2
2
 
3
3
  ```sh
4
- npx agent-bridge call screen.snapshot # buttons, inputs, text on the focused screen (`hidden` counts what was skipped; {"all":true} lists everything)
5
- npx agent-bridge call screen.findText "Payment" # text or accessibility label; {"labels":false} for text only
6
- npx agent-bridge call screen.press '"add-plant"' # by testID, label or text
7
- npx agent-bridge call screen.press '[{"at":[350,60]}]' # icon-only button: by point; {"index":1} picks among matches; {"force":true} presses disabled
8
- npx agent-bridge call screen.press '["save-plant", {"scroll":true}]' # scrolls an off-screen target into view first
9
- npx agent-bridge call screen.scroll '"Notes"' # bring a target to the middle of its ScrollView/FlatList; {"toEnd":true}, {"by":400}, [{"toEnd":true},{"within":"list"}]
10
- npx agent-bridge call screen.refresh # pull to refresh (the RefreshControl's onRefresh); then screen.waitFor the data
11
- npx agent-bridge call screen.fill '["plant-name", "Fern"]' # runs the input's handlers
12
- npx agent-bridge call screen.waitFor '"Name is required"' # {"gone": true} waits for it to go
13
- npx agent-bridge call screen.waitFor '["Section title", {"scroll":true}]' # also below the fold: scrolls it into view (not with gone)
4
+ npx @avasapp/agent-bridge call screen.snapshot # one line per element: `button #save "Save" disabled` (`hidden` counts what was skipped; {"all":true} lists everything)
5
+ npx @avasapp/agent-bridge call screen.snapshot '{"kinds":["input","button"],"within":"checkout-form"}' # only those kinds, only inside that target
6
+ npx @avasapp/agent-bridge call screen.snapshot --json # JSON with rects and `role` (the text form already shows actions=, readonly, offscreen); `@x,y` on a line is `{"at":[x,y]}`, `index=N` is `{"index":N}`
7
+ npx @avasapp/agent-bridge call screen.findText "Payment" # text or accessibility label; {"labels":false} for text only
8
+ npx @avasapp/agent-bridge call screen.press '"add-plant"' # by testID, label or text
9
+ npx @avasapp/agent-bridge call screen.press '[{"at":[350,60]}]' # icon-only button: by point; {"index":1} picks among matches; {"force":true} presses disabled
10
+ npx @avasapp/agent-bridge call screen.press '["save-plant", {"scroll":true}]' # scrolls an off-screen target into view first
11
+ npx @avasapp/agent-bridge call screen.press '"Swipe to confirm"' # no onPress: sends the "activate" accessibility action
12
+ npx @avasapp/agent-bridge call screen.press '["Volume", {"action":"increment"}]' # any action in the element's snapshot `actions`
13
+ npx @avasapp/agent-bridge call screen.press '["Item 80", {"scroll":true}]' # a row a FlatList has not rendered yet: pages the main list until it shows up (waitFor does not page)
14
+ npx @avasapp/agent-bridge call screen.press '["Message", {"long":true}]' # onPressIn, onLongPress, onPressOut; errors when there is no onLongPress
15
+ npx @avasapp/agent-bridge call screen.press '"dark-mode"' # a Switch is toggled with onValueChange(!value)
16
+ npx @avasapp/agent-bridge call screen.setValue '["volume", 7]' # Switch true/false, Slider number, Picker or SegmentedControl item; reads the value back
17
+ npx @avasapp/agent-bridge call screen.scroll '"Notes"' # bring a target to the middle of its ScrollView/FlatList; {"toEnd":true}, {"by":400}, [{"toEnd":true},{"within":"list"}]
18
+ npx @avasapp/agent-bridge call screen.refresh # pull to refresh (the RefreshControl's onRefresh); then screen.waitFor the data
19
+ npx @avasapp/agent-bridge call screen.fill '["plant-name", "Fern"]' # runs the input's handlers
20
+ npx @avasapp/agent-bridge call screen.waitFor '"Name is required"' # {"gone": true} waits for it to go
21
+ npx @avasapp/agent-bridge call screen.waitFor '["Section title", {"scroll":true}]' # also below the fold: scrolls it into view (not with gone)
14
22
  ```
15
23
 
16
24
  `press` and `fill` return once the app has rendered the result, so the next
17
- check sees it. `fill` skips the keyboard: autocorrect and native-only input
25
+ check sees it. `fill` also takes `{"submit":true}` and `{"type":true}` (per-character, for debounced search); `""` clears. A press that hit an ancestor's handler says `via: "ancestor"`: check it did what you meant. `fill` skips the keyboard: autocorrect and native-only input
18
26
  behaviour need one real typing step from agent-device.
19
27
 
28
+ A swipe-to-confirm or slider with no `onPress` shows as a button (or a view)
29
+ with `actions` in the snapshot. `press` calls its `onAccessibilityAction` with
30
+ `activate`, as a screen reader's double tap does, and the reply says
31
+ `via: "accessibilityAction:activate"`. A gesture control with no `actions`
32
+ needs a real swipe from agent-device.
33
+
20
34
  A WebView shows in the snapshot as one element (`webview "checkout"`);
21
35
  `screen.*` can't reach inside it. See [webview.md](webview.md).
22
36
 
@@ -3,11 +3,11 @@
3
3
  ## Set state
4
4
 
5
5
  ```sh
6
- npx agent-bridge call query.pin '[["features"], <data>]' # stays through refetches
7
- npx agent-bridge call store.call '["settings", "setTheme", "dark"]'
8
- npx agent-bridge call router.navigate /inbox
9
- npx agent-bridge call router.current
10
- npx agent-bridge call router.dismiss # closes a route-based modal
6
+ npx @avasapp/agent-bridge call query.pin '[["features"], <data>]' # stays through refetches
7
+ npx @avasapp/agent-bridge call store.call '["settings", "setTheme", "dark"]'
8
+ npx @avasapp/agent-bridge call router.navigate /inbox
9
+ npx @avasapp/agent-bridge call router.current # React Navigation apps: nav.navigate Inbox, nav.current
10
+ npx @avasapp/agent-bridge call router.dismiss # closes a route-based modal
11
11
  ```
12
12
 
13
13
  `router.back` only pops the navigator: an in-app modal or sheet the app renders
@@ -19,18 +19,38 @@ own tool (e.g. `modal.close`) if it has one; check `tools` first.
19
19
  Read the current value first and change only what you need:
20
20
 
21
21
  ```sh
22
- npx agent-bridge call query.get '["todos", 1]' # a flat key or '[["todos", 1]]'
23
- npx agent-bridge call query.list '["todos"]' # key prefix; shows isStale, isInvalidated, fetchStatus
24
- npx agent-bridge call query.refetch '["todos"]' # {matched, refetched, data}; errors when nothing matches
25
- npx agent-bridge call store.get '["app", "auth.isLoggedIn"]' # or ["app","auth","isLoggedIn"]
26
- npx agent-bridge call store.get '["app", {"pick": ["auth.isLoggedIn", "settings.fontScale"]}]'
27
- npx agent-bridge call store.get '["app", {"keys": true}]' # top-level keys and types, no values
22
+ npx @avasapp/agent-bridge call query.get '["todos", 1]' # a flat key or '[["todos", 1]]'
23
+ npx @avasapp/agent-bridge call query.list '["todos"]' # key prefix; shows isStale, isInvalidated, fetchStatus
24
+ npx @avasapp/agent-bridge call query.refetch '["todos"]' # {matched, refetched, data}; errors when nothing matches
25
+ npx @avasapp/agent-bridge call store.get '["app", "auth.isLoggedIn"]' # or ["app","auth","isLoggedIn"]
26
+ npx @avasapp/agent-bridge call store.get '["app", {"pick": ["auth.isLoggedIn", "settings.fontScale"]}]'
27
+ npx @avasapp/agent-bridge call store.get '["app", {"keys": true}]' # top-level keys and types, no values
28
28
  ```
29
29
 
30
30
  `query.get` errors on a key that is not cached (with similar keys), so a
31
31
  `null` reply means the data is undefined. For a large query, narrow it with
32
32
  `pages` or `path`; see [large-data.md](large-data.md).
33
33
 
34
+ ## Redux and Jotai
35
+
36
+ Same ideas under their own prefixes, so a Zustand `store.*` and these can coexist.
37
+
38
+ ```sh
39
+ npx @avasapp/agent-bridge call redux.list
40
+ npx @avasapp/agent-bridge call redux.get '["auth", "user.name"]' # or [] for the whole state
41
+ npx @avasapp/agent-bridge call redux.dispatch '[{"type":"cart/add","payload":"apple"}]'
42
+ npx @avasapp/agent-bridge call redux.set '["auth", {"token": "abc"}]' # merge into a slice
43
+ npx @avasapp/agent-bridge call jotai.list # read-write or read-only
44
+ npx @avasapp/agent-bridge call jotai.get '["user", "name"]'
45
+ npx @avasapp/agent-bridge call jotai.set '["count", 5]' # writable atoms only
46
+ ```
47
+
48
+ `redux.set` and restore need the app to wrap its root reducer in
49
+ `bridgeReducer()` (inside `persistReducer` with redux-persist); without it they
50
+ fail and say so. `redux.set` merges into object slices only. `redux.dispatch`
51
+ sends plain actions only. `jotai.set` refuses atoms whose value isn't the one
52
+ sent (action atoms, `atomWithReducer`). Redacted slices, atoms and paths print as `"[redacted]"`.
53
+
34
54
  ## Argument shapes
35
55
 
36
56
  Arguments are a JSON array (or a single JSON value): the array is spread into
@@ -5,15 +5,15 @@
5
5
  `tools`), use the same verbs on the page:
6
6
 
7
7
  ```sh
8
- npx agent-bridge call webview.list # name, url, loaded, allowed
9
- npx agent-bridge call webview.snapshot '"checkout"' # buttons, links, inputs, text in the page
10
- npx agent-bridge call webview.press '["Pay now", {"webview": "checkout"}]'
11
- npx agent-bridge call webview.fill '["Email", "ada@example.com"]' # {"submit":true} presses Enter
12
- npx agent-bridge call webview.waitFor '["Payment complete", {"timeoutMs": 8000}]' # {"gone":true}
13
- npx agent-bridge call webview.messages '"checkout"' # page <-> app, last 100, bodies cut at 2 KB
14
- npx agent-bridge call webview.message 17 # one in full
15
- npx agent-bridge call webview.send '["checkout", {"type": "auth", "ok": true}]' # as if the app sent it
16
- npx agent-bridge call webview.receive '["checkout", {"type": "done"}]' # runs the app's onMessage
8
+ npx @avasapp/agent-bridge call webview.list # name, url, loaded, allowed
9
+ npx @avasapp/agent-bridge call webview.snapshot '"checkout"' # buttons, links, inputs, text in the page
10
+ npx @avasapp/agent-bridge call webview.press '["Pay now", {"webview": "checkout"}]'
11
+ npx @avasapp/agent-bridge call webview.fill '["Email", "ada@example.com"]' # {"submit":true} presses Enter
12
+ npx @avasapp/agent-bridge call webview.waitFor '["Payment complete", {"timeoutMs": 8000}]' # {"gone":true}
13
+ npx @avasapp/agent-bridge call webview.messages '"checkout"' # page <-> app, last 100, bodies cut at 2 KB
14
+ npx @avasapp/agent-bridge call webview.message 17 # one in full
15
+ npx @avasapp/agent-bridge call webview.send '["checkout", {"type": "auth", "ok": true}]' # as if the app sent it
16
+ npx @avasapp/agent-bridge call webview.receive '["checkout", {"type": "done"}]' # runs the app's onMessage
17
17
  ```
18
18
 
19
19
  Targets match in `screen.*` order: `data-testid` (also `data-test-id`,
@@ -56,8 +56,8 @@ useAgentBridge({ tools, scenarios })
56
56
  is back in its real state. If `apply` throws, the callbacks it had registered
57
57
  run straight away.
58
58
  - Tools: `scenario.list`, `scenario.apply [name, options?]` (applying an active
59
- one again undoes it first) and `scenario.restore`. `npx agent-bridge scenarios`
60
- lists them.
59
+ one again undoes it first) and `scenario.restore`.
60
+ `npx @avasapp/agent-bridge scenarios` lists them.
61
61
  - Flows declare scenarios with `export const scenario` or
62
62
  `export const scenarios`; see [flows.md](flows.md).
63
63
 
@@ -93,5 +93,5 @@ In a release build it's always open. `realtime.connection` isn't enough on its
93
93
  own: it hides the state from the app, but the client still connects.
94
94
 
95
95
  The agent-bridge repo's example app has a complete local `signedIn` in
96
- `example/src/dev/scenarios.ts`, and `example/flows/checks/signed-in.mjs`
96
+ `example/src/dev/scenarios.ts`, and `example/flows/checks/signed-in.flow.mjs`
97
97
  declares it.