@qontinui/ui-bridge-native 0.5.1 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/index.js +38 -4
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +38 -4
- package/dist/core/index.mjs.map +1 -1
- package/dist/core/registry.d.ts +30 -1
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/core/types.d.ts +18 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +175 -29
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +175 -29
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.js +150 -29
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +150 -29
- package/dist/react/index.mjs.map +1 -1
- package/dist/react/useUIElement.d.ts +73 -35
- package/dist/react/useUIElement.d.ts.map +1 -1
- package/dist/server/handlers.d.ts.map +1 -1
- package/dist/server/http-server.d.ts.map +1 -1
- package/dist/server/index.js +84 -3
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +84 -3
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/types.d.ts +4 -0
- package/dist/server/types.d.ts.map +1 -1
- package/package.json +3 -2
|
@@ -4,14 +4,33 @@
|
|
|
4
4
|
* Register a native element with UI Bridge for control and observation.
|
|
5
5
|
*/
|
|
6
6
|
import type { NativeElementType, NativeStandardAction, NativeCustomAction, NativeElementState, NativeElementIdentifier, RegisteredNativeElement, NativeElementRef } from '../core/types';
|
|
7
|
+
type AnyHandler = (...args: any[]) => any;
|
|
7
8
|
/**
|
|
8
|
-
*
|
|
9
|
+
* A press handler for `button`/`pressable` types. Matches the loose RN
|
|
10
|
+
* `Pressable` `onPress` shape (no required argument), so consumers can pass
|
|
11
|
+
* either a no-arg callback or one that consumes the gesture event.
|
|
9
12
|
*/
|
|
10
|
-
export
|
|
13
|
+
export type PressHandler = (event?: unknown) => void;
|
|
14
|
+
/**
|
|
15
|
+
* Element types that require a press handler at registration. The TS
|
|
16
|
+
* signature on `useUIElement` rejects these types unless `handlers.onPress`
|
|
17
|
+
* is provided in options.
|
|
18
|
+
*
|
|
19
|
+
* Picked from the action-executor in `control/action-executor.ts` — the
|
|
20
|
+
* `press` action looks up `props.onPress` (or `onPressIn` /
|
|
21
|
+
* `onResponderRelease`); registering a button without one is a guaranteed
|
|
22
|
+
* dead-button per the 2026-05-20 manual-test session.
|
|
23
|
+
*/
|
|
24
|
+
export type PressNeedingNativeElementType = 'button' | 'pressable';
|
|
25
|
+
/**
|
|
26
|
+
* Base options for `useUIElement`. The discriminated union below layers
|
|
27
|
+
* `handlers` requirements on top of this — see {@link UseUIElementOptions}.
|
|
28
|
+
*/
|
|
29
|
+
export interface UseUIElementOptionsBase<T extends NativeElementType = NativeElementType> {
|
|
11
30
|
/** Unique identifier for the element */
|
|
12
31
|
id: string;
|
|
13
32
|
/** Element type (defaults to 'custom') */
|
|
14
|
-
type?:
|
|
33
|
+
type?: T;
|
|
15
34
|
/** Human-readable label */
|
|
16
35
|
label?: string;
|
|
17
36
|
/** Override available actions */
|
|
@@ -32,10 +51,24 @@ export interface UseUIElementOptions {
|
|
|
32
51
|
focused?: unknown;
|
|
33
52
|
disabled?: unknown;
|
|
34
53
|
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Options shape for press-needing types — `handlers.onPress` is REQUIRED.
|
|
57
|
+
* Registering a `button`/`pressable` without an `onPress` produces a
|
|
58
|
+
* "No press handler found on element" error when the bridge fires
|
|
59
|
+
* `POST /control/element/:id/action {"action":"press"}`. Phase 1 of plan
|
|
60
|
+
* `2026-05-20-manual-test-remediation` makes that a compile-time error.
|
|
61
|
+
*
|
|
62
|
+
* Consumers that wire `onPress` lazily (e.g. computed from props during
|
|
63
|
+
* render) should use {@link useUIElementWithProps} + `captureProps({ onPress })`
|
|
64
|
+
* instead. The runtime guard in this hook also warns once per id when
|
|
65
|
+
* `onPress` never reaches the registry.
|
|
66
|
+
*/
|
|
67
|
+
export interface UseUIElementOptionsHandlersRequired<T extends PressNeedingNativeElementType = PressNeedingNativeElementType> extends UseUIElementOptionsBase<T> {
|
|
35
68
|
/**
|
|
36
69
|
* Handler props to auto-register with the bridge for action execution.
|
|
37
|
-
*
|
|
38
|
-
*
|
|
70
|
+
* For `button`/`pressable`, `onPress` is required — UI Bridge invokes it
|
|
71
|
+
* when a `press` action is dispatched.
|
|
39
72
|
*
|
|
40
73
|
* @example
|
|
41
74
|
* ```tsx
|
|
@@ -46,8 +79,32 @@ export interface UseUIElementOptions {
|
|
|
46
79
|
* });
|
|
47
80
|
* ```
|
|
48
81
|
*/
|
|
49
|
-
handlers
|
|
82
|
+
handlers: {
|
|
83
|
+
/** Required — UI Bridge invokes this on `press`/`click` actions. */
|
|
84
|
+
onPress: PressHandler;
|
|
85
|
+
/** Additional handlers (`onLongPress`, `onPressIn`, etc.) */
|
|
86
|
+
[key: string]: AnyHandler | undefined;
|
|
87
|
+
};
|
|
50
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Options shape for non-press-needing types — `handlers` is optional.
|
|
91
|
+
* Applies to `input`, `text`, `view`, `list`, etc. — anything where a
|
|
92
|
+
* missing `onPress` doesn't indicate a dead button.
|
|
93
|
+
*/
|
|
94
|
+
export interface UseUIElementOptionsHandlersOptional<T extends NativeElementType = NativeElementType> extends UseUIElementOptionsBase<T> {
|
|
95
|
+
/**
|
|
96
|
+
* Handler props to auto-register with the bridge for action execution.
|
|
97
|
+
* Optional for non-press-needing types.
|
|
98
|
+
*/
|
|
99
|
+
handlers?: Record<string, AnyHandler | undefined>;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* useUIElement options — discriminated union over element type.
|
|
103
|
+
*
|
|
104
|
+
* For `type: 'button' | 'pressable'`, `handlers.onPress` is required.
|
|
105
|
+
* For all other types, `handlers` is optional.
|
|
106
|
+
*/
|
|
107
|
+
export type UseUIElementOptions<T extends NativeElementType = NativeElementType> = T extends PressNeedingNativeElementType ? UseUIElementOptionsHandlersRequired<T> : UseUIElementOptionsHandlersOptional<T>;
|
|
51
108
|
/**
|
|
52
109
|
* Bridge props to spread onto the component
|
|
53
110
|
*/
|
|
@@ -97,34 +154,7 @@ export interface UseUIElementReturn {
|
|
|
97
154
|
disabled?: unknown;
|
|
98
155
|
}) => void;
|
|
99
156
|
}
|
|
100
|
-
|
|
101
|
-
* useUIElement hook for React Native
|
|
102
|
-
*
|
|
103
|
-
* Registers a native element with UI Bridge for programmatic control.
|
|
104
|
-
*
|
|
105
|
-
* @example
|
|
106
|
-
* ```tsx
|
|
107
|
-
* function SubmitButton() {
|
|
108
|
-
* const { ref, onLayout, bridgeProps, trigger } = useUIElement({
|
|
109
|
-
* id: 'submit-btn',
|
|
110
|
-
* type: 'button',
|
|
111
|
-
* label: 'Submit Form',
|
|
112
|
-
* });
|
|
113
|
-
*
|
|
114
|
-
* return (
|
|
115
|
-
* <Pressable
|
|
116
|
-
* ref={ref}
|
|
117
|
-
* onLayout={onLayout}
|
|
118
|
-
* {...bridgeProps}
|
|
119
|
-
* onPress={() => handleSubmit()}
|
|
120
|
-
* >
|
|
121
|
-
* <Text>Submit</Text>
|
|
122
|
-
* </Pressable>
|
|
123
|
-
* );
|
|
124
|
-
* }
|
|
125
|
-
* ```
|
|
126
|
-
*/
|
|
127
|
-
export declare function useUIElement(options: UseUIElementOptions): UseUIElementReturn;
|
|
157
|
+
export declare function useUIElement<T extends NativeElementType = NativeElementType>(options: UseUIElementOptions<T>): UseUIElementReturn;
|
|
128
158
|
/**
|
|
129
159
|
* useUIElementWithProps hook
|
|
130
160
|
*
|
|
@@ -158,5 +188,13 @@ export interface UseUIElementWithPropsReturn extends UseUIElementReturn {
|
|
|
158
188
|
/** Capture props for action execution */
|
|
159
189
|
captureProps: (props: Record<string, unknown>) => void;
|
|
160
190
|
}
|
|
161
|
-
|
|
191
|
+
/**
|
|
192
|
+
* Loose options for `useUIElementWithProps` — `handlers` is optional for ALL
|
|
193
|
+
* element types because the consumer will later call `captureProps({ onPress,
|
|
194
|
+
* ... })` from the render body. The runtime warning in {@link useUIElement}
|
|
195
|
+
* still backstops the "captured but never called with onPress" case.
|
|
196
|
+
*/
|
|
197
|
+
export type UseUIElementWithPropsOptions<T extends NativeElementType = NativeElementType> = UseUIElementOptionsHandlersOptional<T>;
|
|
198
|
+
export declare function useUIElementWithProps<T extends NativeElementType = NativeElementType>(options: UseUIElementWithPropsOptions<T>): UseUIElementWithPropsReturn;
|
|
199
|
+
export {};
|
|
162
200
|
//# sourceMappingURL=useUIElement.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUIElement.d.ts","sourceRoot":"","sources":["../../src/react/useUIElement.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,uBAAuB,EACvB,gBAAgB,EAEjB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"useUIElement.d.ts","sourceRoot":"","sources":["../../src/react/useUIElement.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/server/handlers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,sBAAsB,EAAuB,MAAM,kBAAkB,CAAC;AAQpF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAQV,oBAAoB,EAKrB,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AA+PhF;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,sBAAsB,EAChC,QAAQ,EAAE,oBAAoB,EAC9B,MAAM,CAAC,EAAE;IACP,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClF,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,iFAAiF;IACjF,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C,GACA,oBAAoB,
|
|
1
|
+
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/server/handlers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,sBAAsB,EAAuB,MAAM,kBAAkB,CAAC;AAQpF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAQV,oBAAoB,EAKrB,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AA+PhF;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,sBAAsB,EAChC,QAAQ,EAAE,oBAAoB,EAC9B,MAAM,CAAC,EAAE;IACP,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClF,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,iFAAiF;IACjF,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C,GACA,oBAAoB,CAkzBtB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../../src/server/http-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAA0B,MAAM,kBAAkB,CAAC;AACrF,OAAO,KAAK,EACV,kBAAkB,EAElB,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EAGlB,MAAM,SAAS,CAAC;AAIjB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../../src/server/http-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAA0B,MAAM,kBAAkB,CAAC;AACrF,OAAO,KAAK,EACV,kBAAkB,EAElB,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EAGlB,MAAM,SAAS,CAAC;AAIjB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA4UlE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAE7E;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,uBAAuB;IACvB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,sBAAsB;IACtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,iCAAiC;IACjC,SAAS,IAAI,OAAO,CAAC;CACtB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,sBAAuB,SAAQ,aAAa;IAC3D,mGAAmG;IACnG,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACjF,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,sDAAsD;IACtD,qBAAqB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7D,kDAAkD;IAClD,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED;;GAEG;AACH,qBAAa,oBAAoB;IAuB7B,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,QAAQ;IAvBlB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,OAAO,CAAC,CAAgB;IAChC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,iBAAiB,CAAC,CAAoB;IAC9C;;;;OAIG;IACH,OAAO,CAAC,cAAc,CAAsC;IAE5D;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,oBAAoB,CAAuB;gBAGzC,QAAQ,EAAE,sBAAsB,EAChC,QAAQ,EAAE,oBAAoB,EACtC,MAAM,GAAE,kBAAuB;IA6CjC;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAIxC;;;OAGG;IACH,qBAAqB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI;IAiGzD;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAsC/C;;;OAGG;IACH,qBAAqB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI;IA6BzD;;;;OAIG;IACH,oBAAoB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IA4BvD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAe3B;;OAEG;IACH,SAAS,IAAI,OAAO;IAMpB,OAAO,CAAC,WAAW,CAAC,CAAuB;IAE3C;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI;IAIlD;;;;OAIG;IACG,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA4IxF;;OAEG;IACG,kBAAkB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAwB7E;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAetB;;;;OAIG;IACH,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAa/C;;;OAGG;YACW,oBAAoB;IAwHlC;;;;;;;;;;;OAWG;YACW,sBAAsB;IAmJpC;;;OAGG;YACW,cAAc;IA6E5B;;;;;;;;;;;OAWG;YACW,oBAAoB;IAgClC;;;;;OAKG;IACG,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAuDhE;;;;;;;;;;;OAWG;YACW,YAAY;CAuE3B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,sBAAsB,EAChC,QAAQ,EAAE,oBAAoB,EAC9B,MAAM,CAAC,EAAE,kBAAkB,GAC1B,oBAAoB,CAEtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG"}
|
package/dist/server/index.js
CHANGED
|
@@ -141,6 +141,31 @@ var UI_BRIDGE_NATIVE_ROUTES = {
|
|
|
141
141
|
path: "/ui-bridge/ai/fill-form",
|
|
142
142
|
description: "Fill multiple input elements in a single call"
|
|
143
143
|
},
|
|
144
|
+
// AI helpers (NOT_SUPPORTED stubs) — these endpoints exist on the runner-side
|
|
145
|
+
// UI Bridge surface but have no analog on mobile React Native. The mobile
|
|
146
|
+
// bridge registers explicit stubs so callers get a structured NOT_SUPPORTED
|
|
147
|
+
// envelope instead of a confusing HTTP 404. The mobile bridge's snapshot +
|
|
148
|
+
// `/control/find` already cover what an operator would reach for these for.
|
|
149
|
+
AI_FORMS: {
|
|
150
|
+
method: "GET",
|
|
151
|
+
path: "/ui-bridge/ai/forms",
|
|
152
|
+
description: "Discover forms (runner-only; mobile returns NOT_SUPPORTED)"
|
|
153
|
+
},
|
|
154
|
+
AI_IDLE_STATUS: {
|
|
155
|
+
method: "GET",
|
|
156
|
+
path: "/ui-bridge/ai/idle-status",
|
|
157
|
+
description: "Get page-idle signal (runner-only; mobile returns NOT_SUPPORTED)"
|
|
158
|
+
},
|
|
159
|
+
AI_CHANGE_BUFFER_ENABLE: {
|
|
160
|
+
method: "POST",
|
|
161
|
+
path: "/ui-bridge/ai/change-buffer/enable",
|
|
162
|
+
description: "Enable DOM change buffer (runner-only; mobile returns NOT_SUPPORTED)"
|
|
163
|
+
},
|
|
164
|
+
AI_WAIT_FOR_ELEMENT: {
|
|
165
|
+
method: "POST",
|
|
166
|
+
path: "/ui-bridge/ai/wait-for-element",
|
|
167
|
+
description: "Wait for element predicate via HTTP (runner-only; mobile returns NOT_SUPPORTED \u2014 use WS waitForElement instead)"
|
|
168
|
+
},
|
|
144
169
|
// Test hooks — drive ModalDetector state from outside the React tree
|
|
145
170
|
// (gated by `features.testHooks`). Mirrors `pushModal` / `dismissModal`
|
|
146
171
|
// calls that components normally make in-process.
|
|
@@ -847,22 +872,25 @@ function createServerHandlers(registry, executor, config) {
|
|
|
847
872
|
getElements: async (ctx) => {
|
|
848
873
|
const visibleOnly = ctx.query?.visibleOnly === "true" || ctx.body?.visibleOnly === true;
|
|
849
874
|
const forRoute = ctx.query?.route || ctx.body?.route;
|
|
850
|
-
let allElements = visibleOnly ? registry.
|
|
875
|
+
let allElements = visibleOnly ? registry.getMountedVisibleElements() : registry.getAllElements();
|
|
851
876
|
if (forRoute) {
|
|
852
877
|
allElements = allElements.filter((e) => e.registrationRoute === forRoute);
|
|
853
878
|
}
|
|
854
879
|
const elements = allElements.map((e) => {
|
|
855
880
|
const handlers = extractHandlerNames(e.props);
|
|
881
|
+
const state = e.getState();
|
|
882
|
+
const visibility = !state.visible ? "hidden" : state.layout !== null ? "visible" : "likely-visible";
|
|
856
883
|
return {
|
|
857
884
|
id: e.id,
|
|
858
885
|
type: e.type,
|
|
859
886
|
label: e.label,
|
|
860
887
|
identifier: e.getIdentifier(),
|
|
861
|
-
state
|
|
888
|
+
state,
|
|
862
889
|
actions: e.actions,
|
|
863
890
|
customActions: e.customActions ? Object.keys(e.customActions) : void 0,
|
|
864
891
|
registeredHandlers: handlers.length > 0 ? handlers : void 0,
|
|
865
|
-
registrationRoute: e.registrationRoute
|
|
892
|
+
registrationRoute: e.registrationRoute,
|
|
893
|
+
visibility
|
|
866
894
|
};
|
|
867
895
|
});
|
|
868
896
|
return success2({ elements });
|
|
@@ -1125,6 +1153,37 @@ function createServerHandlers(registry, executor, config) {
|
|
|
1125
1153
|
"NOT_SUPPORTED"
|
|
1126
1154
|
);
|
|
1127
1155
|
},
|
|
1156
|
+
// AI helpers — runner-only endpoints that have no React Native analog.
|
|
1157
|
+
//
|
|
1158
|
+
// The mobile bridge mounts explicit NOT_SUPPORTED stubs at the runner's
|
|
1159
|
+
// cheatsheet paths so callers (and the /manual-test skill in particular)
|
|
1160
|
+
// get a structured envelope explaining the gap rather than a confusing
|
|
1161
|
+
// HTTP 404. Each error message names an in-tree mobile replacement so
|
|
1162
|
+
// operators aren't left guessing what to use instead.
|
|
1163
|
+
aiForms: async () => {
|
|
1164
|
+
return error2(
|
|
1165
|
+
'ai/forms (form discovery) is runner-only; mobile React Native has no DOM to walk. Use GET /ui-bridge/control/snapshot and filter for type === "input" instead.',
|
|
1166
|
+
"NOT_SUPPORTED"
|
|
1167
|
+
);
|
|
1168
|
+
},
|
|
1169
|
+
aiIdleStatus: async () => {
|
|
1170
|
+
return error2(
|
|
1171
|
+
'ai/idle-status (page-idle signal) is runner-only; mobile React Native has no DOM-mutation / network-idle signals. Use the registry event stream (WS subscribe to "element:registered"/"element:stateChanged") or poll /control/snapshot for stability.',
|
|
1172
|
+
"NOT_SUPPORTED"
|
|
1173
|
+
);
|
|
1174
|
+
},
|
|
1175
|
+
aiChangeBufferEnable: async () => {
|
|
1176
|
+
return error2(
|
|
1177
|
+
'ai/change-buffer (DOM mutation diff buffer) is runner-only; mobile React Native has no DOM. Use the WS event bridge (subscribe to "element:registered"/"element:unregistered"/"element:stateChanged") for change notifications.',
|
|
1178
|
+
"NOT_SUPPORTED"
|
|
1179
|
+
);
|
|
1180
|
+
},
|
|
1181
|
+
aiWaitForElement: async () => {
|
|
1182
|
+
return error2(
|
|
1183
|
+
'POST /ai/wait-for-element is runner-only on mobile. Use the WS "waitForElement" JSON-RPC method or "waitForCondition" instead \u2014 same semantics, no HTTP polling overhead.',
|
|
1184
|
+
"NOT_SUPPORTED"
|
|
1185
|
+
);
|
|
1186
|
+
},
|
|
1128
1187
|
// Meta / Introspection (stub — server constructor overrides with real route table)
|
|
1129
1188
|
getMethods: async () => {
|
|
1130
1189
|
return error2("Methods introspection not configured", "NOT_SUPPORTED");
|
|
@@ -1780,6 +1839,24 @@ var WS_ROUTES = [
|
|
|
1780
1839
|
{ pattern: "meta/methods", handler: "getMethods", httpMethods: ["GET"] },
|
|
1781
1840
|
// AI helpers — mobile parity with the runner's `/ui-bridge/ai/*` family.
|
|
1782
1841
|
{ pattern: "ai/fill-form", handler: "fillForm", httpMethods: ["POST"] },
|
|
1842
|
+
// AI helpers — NOT_SUPPORTED stubs. These endpoints exist on the runner-side
|
|
1843
|
+
// UI Bridge surface (and the /manual-test skill's cheatsheet documents them
|
|
1844
|
+
// as if they're universally available). Mobile React Native has no DOM, so
|
|
1845
|
+
// the mobile bridge mounts explicit stubs so callers get a structured
|
|
1846
|
+
// NOT_SUPPORTED envelope (with a hint pointing at the mobile-native
|
|
1847
|
+
// replacement) instead of a confusing HTTP 404.
|
|
1848
|
+
{ pattern: "ai/forms", handler: "aiForms", httpMethods: ["GET"] },
|
|
1849
|
+
{ pattern: "ai/idle-status", handler: "aiIdleStatus", httpMethods: ["GET"] },
|
|
1850
|
+
{
|
|
1851
|
+
pattern: "ai/change-buffer/enable",
|
|
1852
|
+
handler: "aiChangeBufferEnable",
|
|
1853
|
+
httpMethods: ["POST"]
|
|
1854
|
+
},
|
|
1855
|
+
{
|
|
1856
|
+
pattern: "ai/wait-for-element",
|
|
1857
|
+
handler: "aiWaitForElement",
|
|
1858
|
+
httpMethods: ["POST"]
|
|
1859
|
+
},
|
|
1783
1860
|
// Coord-based tap — synthesizes a press at the given screen coords by
|
|
1784
1861
|
// matching against registered elements' layout rects.
|
|
1785
1862
|
{ pattern: "control/tap", handler: "tapAt", httpMethods: ["POST"] },
|
|
@@ -1852,6 +1929,10 @@ var HANDLER_DESCRIPTIONS = {
|
|
|
1852
1929
|
diffBaseline: "Diff current UI against a saved baseline",
|
|
1853
1930
|
getMethods: "List every handler name (legacy introspection)",
|
|
1854
1931
|
fillForm: "Fill multiple inputs in one call: body { fields: [{elementId, value}] } \u2014 each field dispatches `type` + `clear:true`",
|
|
1932
|
+
aiForms: 'STUB \u2014 runner-only; mobile returns NOT_SUPPORTED. Use /control/snapshot + filter type==="input" instead.',
|
|
1933
|
+
aiIdleStatus: "STUB \u2014 runner-only; mobile returns NOT_SUPPORTED. Subscribe to registry events over WS for change signals.",
|
|
1934
|
+
aiChangeBufferEnable: "STUB \u2014 runner-only; mobile returns NOT_SUPPORTED. Use WS event subscriptions for change notifications.",
|
|
1935
|
+
aiWaitForElement: "STUB \u2014 runner-only; mobile returns NOT_SUPPORTED. Use the WS waitForElement / waitForCondition JSON-RPC methods.",
|
|
1855
1936
|
tapAt: "Synthesize a press at given screen coords by matching registered element layout rects: body { x, y, action? }",
|
|
1856
1937
|
getConsoleErrors: "TEST HOOK \u2014 last-N console.error/console.warn entries; ?since=<ms>&limit=<n>",
|
|
1857
1938
|
getNetworkRequests: "TEST HOOK \u2014 last-N fetch/XHR entries with status + duration; ?since=<ms>&limit=<n>",
|