@appilots/sdk 0.11.3 → 0.13.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.
- package/control-transformer.js +69 -0
- package/dist/.build-meta.json +3 -3
- package/dist/{chunk-UFMTRGML.js → chunk-AJDHZRBN.js} +1097 -460
- package/dist/{chunk-5UVMNKPT.js → chunk-ALJGKORS.js} +8 -8
- package/dist/{chunk-ROXXCDIG.mjs → chunk-HRWBK35Y.mjs} +5738 -540
- package/dist/{chunk-JKLE5SLN.mjs → chunk-L3SY3Q4K.mjs} +1 -1
- package/dist/{chunk-2ZDELL54.mjs → chunk-UYBKXULM.mjs} +815 -191
- package/dist/{chunk-SUMIABJK.js → chunk-UZ2D4BVX.js} +5756 -538
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +11 -11
- package/dist/hooks/index.mjs +2 -2
- package/dist/{index-BR-33WMN.d.mts → index-CI4jmSoP.d.mts} +136 -660
- package/dist/{index-BR-33WMN.d.ts → index-CI4jmSoP.d.ts} +136 -660
- package/dist/index.d.mts +1447 -76
- package/dist/index.d.ts +1447 -76
- package/dist/index.js +1069 -672
- package/dist/index.mjs +902 -564
- package/dist/navigation/index.d.mts +22 -1
- package/dist/navigation/index.d.ts +22 -1
- package/dist/navigation/index.js +13 -13
- package/dist/navigation/index.mjs +2 -2
- package/metro.d.ts +3 -5
- package/metro.js +46 -5
- package/package.json +16 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkUZ2D4BVX_js = require('./chunk-UZ2D4BVX.js');
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var reactNative = require('react-native');
|
|
6
6
|
|
|
@@ -8,6 +8,261 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
8
8
|
|
|
9
9
|
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
10
10
|
|
|
11
|
+
// src/i18n/bundles/pt-BR.ts
|
|
12
|
+
var ptBR = {
|
|
13
|
+
chatTitle: "Assistente Appilots",
|
|
14
|
+
clearButton: "Limpar",
|
|
15
|
+
inputPlaceholder: "Digite uma mensagem...",
|
|
16
|
+
emptyTitle: "Como posso ajudar?",
|
|
17
|
+
emptySubtitle: "Navego, preencho formul\xE1rios e executo a\xE7\xF5es neste app.",
|
|
18
|
+
thinking: "Pensando...",
|
|
19
|
+
statusAnalyzing: "Analisando a tela...",
|
|
20
|
+
statusWaitingApp: "Aguardando o app responder...",
|
|
21
|
+
statusAdjusting: "Ajustando o plano...",
|
|
22
|
+
poweredBy: "Powered by Appilots",
|
|
23
|
+
approve: "Aprovar",
|
|
24
|
+
reject: "Rejeitar",
|
|
25
|
+
cancelledByUser: "Cancelado pelo usu\xE1rio",
|
|
26
|
+
confirmDestructiveTitle: "A\xE7\xE3o destrutiva",
|
|
27
|
+
confirmTitle: "Confirma\xE7\xE3o necess\xE1ria",
|
|
28
|
+
confirmMessage: 'Tem certeza que deseja "{action}"?',
|
|
29
|
+
confirmDestructiveApprove: "Sim, executar",
|
|
30
|
+
confirmApprove: "Confirmar",
|
|
31
|
+
confirmCancel: "Cancelar",
|
|
32
|
+
confirmThisAction: "esta a\xE7\xE3o",
|
|
33
|
+
unknownAction: "A\xE7\xE3o desconhecida",
|
|
34
|
+
somethingWentWrong: "Algo deu errado",
|
|
35
|
+
openChatA11y: "Abrir chat do assistente",
|
|
36
|
+
closeChatA11y: "Fechar chat do assistente",
|
|
37
|
+
stopGeneratingA11y: "Parar gera\xE7\xE3o",
|
|
38
|
+
talkToHumanA11y: "Falar com um atendente humano",
|
|
39
|
+
humanAgentLabel: "Atendente",
|
|
40
|
+
escalationRequested: "Certo! Chamei um atendente humano. Voc\xEA pode continuar usando o app normalmente enquanto isso.",
|
|
41
|
+
escalationConnected: "Um atendente entrou na conversa.",
|
|
42
|
+
escalationResolved: "O atendimento humano foi encerrado. Voltei a te ajudar por aqui.",
|
|
43
|
+
escalationOffer: "Se preferir, posso chamar uma pessoa para ajudar.",
|
|
44
|
+
escalationOfferChip: "Falar com um atendente",
|
|
45
|
+
escalationPendingBanner: "Aguardando um atendente...",
|
|
46
|
+
escalationActiveBanner: "Voc\xEA est\xE1 falando com um atendente",
|
|
47
|
+
pillWorking: "Trabalhando...",
|
|
48
|
+
pillExpandA11y: "Abrir a conversa do assistente",
|
|
49
|
+
pillStopA11y: "Parar o assistente",
|
|
50
|
+
missionPause: "Pausar",
|
|
51
|
+
missionResume: "Retomar tarefa",
|
|
52
|
+
missionCancel: "Cancelar tarefa",
|
|
53
|
+
missionPaused: "Pausada",
|
|
54
|
+
pillDone: "Pronto \u2014 toque para ver",
|
|
55
|
+
micStartA11y: "Segurar para falar",
|
|
56
|
+
micStopA11y: "Soltar para enviar",
|
|
57
|
+
micListening: "Ouvindo..."
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// src/i18n/bundles/en.ts
|
|
61
|
+
var en = {
|
|
62
|
+
chatTitle: "Appilots Assistant",
|
|
63
|
+
clearButton: "Clear",
|
|
64
|
+
inputPlaceholder: "Type a message...",
|
|
65
|
+
emptyTitle: "How can I help?",
|
|
66
|
+
emptySubtitle: "I navigate, fill forms, and run actions in this app.",
|
|
67
|
+
thinking: "Thinking...",
|
|
68
|
+
statusAnalyzing: "Reading the screen...",
|
|
69
|
+
statusWaitingApp: "Waiting for the app...",
|
|
70
|
+
statusAdjusting: "Adjusting the plan...",
|
|
71
|
+
poweredBy: "Powered by Appilots",
|
|
72
|
+
approve: "Approve",
|
|
73
|
+
reject: "Reject",
|
|
74
|
+
cancelledByUser: "Cancelled by user",
|
|
75
|
+
confirmDestructiveTitle: "Destructive action",
|
|
76
|
+
confirmTitle: "Confirmation needed",
|
|
77
|
+
confirmMessage: 'Are you sure you want to "{action}"?',
|
|
78
|
+
confirmDestructiveApprove: "Yes, do it",
|
|
79
|
+
confirmApprove: "Confirm",
|
|
80
|
+
confirmCancel: "Cancel",
|
|
81
|
+
confirmThisAction: "this action",
|
|
82
|
+
unknownAction: "Unknown action",
|
|
83
|
+
somethingWentWrong: "Something went wrong",
|
|
84
|
+
openChatA11y: "Open assistant chat",
|
|
85
|
+
closeChatA11y: "Close assistant chat",
|
|
86
|
+
stopGeneratingA11y: "Stop generating",
|
|
87
|
+
talkToHumanA11y: "Talk to a human agent",
|
|
88
|
+
humanAgentLabel: "Agent",
|
|
89
|
+
escalationRequested: "Done! I've called a human agent. You can keep using the app normally in the meantime.",
|
|
90
|
+
escalationConnected: "A human agent joined the conversation.",
|
|
91
|
+
escalationResolved: "The human handoff has ended. I'm back to help you here.",
|
|
92
|
+
escalationOffer: "If you prefer, I can bring in a person to help.",
|
|
93
|
+
escalationOfferChip: "Talk to a human",
|
|
94
|
+
escalationPendingBanner: "Waiting for a human agent...",
|
|
95
|
+
escalationActiveBanner: "You're talking to a human agent",
|
|
96
|
+
pillWorking: "Working...",
|
|
97
|
+
pillExpandA11y: "Open the assistant conversation",
|
|
98
|
+
pillStopA11y: "Stop the assistant",
|
|
99
|
+
missionPause: "Pause",
|
|
100
|
+
missionResume: "Resume task",
|
|
101
|
+
missionCancel: "Cancel task",
|
|
102
|
+
missionPaused: "Paused",
|
|
103
|
+
pillDone: "Done \u2014 tap to read",
|
|
104
|
+
micStartA11y: "Hold to talk",
|
|
105
|
+
micStopA11y: "Release to send",
|
|
106
|
+
micListening: "Listening..."
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// src/i18n/bundles/es.ts
|
|
110
|
+
var es = {
|
|
111
|
+
chatTitle: "Asistente Appilots",
|
|
112
|
+
clearButton: "Limpiar",
|
|
113
|
+
inputPlaceholder: "Escribe un mensaje...",
|
|
114
|
+
emptyTitle: "\xBFEn qu\xE9 puedo ayudarte?",
|
|
115
|
+
emptySubtitle: "Navego, relleno formularios y ejecuto acciones en esta app.",
|
|
116
|
+
thinking: "Pensando...",
|
|
117
|
+
statusAnalyzing: "Analizando la pantalla...",
|
|
118
|
+
statusWaitingApp: "Esperando a la app...",
|
|
119
|
+
statusAdjusting: "Ajustando el plan...",
|
|
120
|
+
poweredBy: "Hecho con Appilots",
|
|
121
|
+
approve: "Aprobar",
|
|
122
|
+
reject: "Rechazar",
|
|
123
|
+
cancelledByUser: "Cancelado por el usuario",
|
|
124
|
+
confirmDestructiveTitle: "Acci\xF3n destructiva",
|
|
125
|
+
confirmTitle: "Confirmaci\xF3n necesaria",
|
|
126
|
+
confirmMessage: '\xBFSeguro que quieres "{action}"?',
|
|
127
|
+
confirmDestructiveApprove: "S\xED, ejecutar",
|
|
128
|
+
confirmApprove: "Confirmar",
|
|
129
|
+
confirmCancel: "Cancelar",
|
|
130
|
+
confirmThisAction: "esta acci\xF3n",
|
|
131
|
+
unknownAction: "Acci\xF3n desconocida",
|
|
132
|
+
somethingWentWrong: "Algo sali\xF3 mal",
|
|
133
|
+
openChatA11y: "Abrir chat del asistente",
|
|
134
|
+
closeChatA11y: "Cerrar chat del asistente",
|
|
135
|
+
stopGeneratingA11y: "Detener generaci\xF3n",
|
|
136
|
+
talkToHumanA11y: "Hablar con un agente humano",
|
|
137
|
+
humanAgentLabel: "Agente",
|
|
138
|
+
escalationRequested: "\xA1Listo! Llam\xE9 a un agente humano. Mientras tanto puedes seguir usando la app con normalidad.",
|
|
139
|
+
escalationConnected: "Un agente humano se uni\xF3 a la conversaci\xF3n.",
|
|
140
|
+
escalationResolved: "La atenci\xF3n humana termin\xF3. Vuelvo a ayudarte por aqu\xED.",
|
|
141
|
+
escalationOffer: "Si prefieres, puedo llamar a una persona para ayudarte.",
|
|
142
|
+
escalationOfferChip: "Hablar con un agente",
|
|
143
|
+
escalationPendingBanner: "Esperando a un agente...",
|
|
144
|
+
escalationActiveBanner: "Est\xE1s hablando con un agente humano",
|
|
145
|
+
pillWorking: "Trabajando...",
|
|
146
|
+
pillExpandA11y: "Abrir la conversaci\xF3n del asistente",
|
|
147
|
+
pillStopA11y: "Detener el asistente",
|
|
148
|
+
missionPause: "Pausar",
|
|
149
|
+
missionResume: "Reanudar tarea",
|
|
150
|
+
missionCancel: "Cancelar tarea",
|
|
151
|
+
missionPaused: "Pausada",
|
|
152
|
+
pillDone: "Listo \u2014 toca para ver",
|
|
153
|
+
micStartA11y: "Mantener para hablar",
|
|
154
|
+
micStopA11y: "Soltar para enviar",
|
|
155
|
+
micListening: "Escuchando..."
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// src/i18n/bundles/fr.ts
|
|
159
|
+
var fr = {
|
|
160
|
+
chatTitle: "Assistant Appilots",
|
|
161
|
+
clearButton: "Effacer",
|
|
162
|
+
inputPlaceholder: "\xC9crivez un message\u2026",
|
|
163
|
+
emptyTitle: "Comment puis-je vous aider ?",
|
|
164
|
+
emptySubtitle: "Je navigue, remplis les formulaires et effectue des actions dans cette application.",
|
|
165
|
+
thinking: "R\xE9flexion en cours\u2026",
|
|
166
|
+
statusAnalyzing: "Lecture de l\u2019\xE9cran\u2026",
|
|
167
|
+
statusWaitingApp: "En attente de l\u2019application\u2026",
|
|
168
|
+
statusAdjusting: "Ajustement du plan\u2026",
|
|
169
|
+
poweredBy: "Propuls\xE9 par Appilots",
|
|
170
|
+
approve: "Approuver",
|
|
171
|
+
reject: "Refuser",
|
|
172
|
+
cancelledByUser: "Annul\xE9 par l\u2019utilisateur",
|
|
173
|
+
confirmDestructiveTitle: "Action destructive",
|
|
174
|
+
confirmTitle: "Confirmation requise",
|
|
175
|
+
confirmMessage: "Voulez-vous vraiment \xAB {action} \xBB ?",
|
|
176
|
+
confirmDestructiveApprove: "Oui, ex\xE9cuter",
|
|
177
|
+
confirmApprove: "Confirmer",
|
|
178
|
+
confirmCancel: "Annuler",
|
|
179
|
+
confirmThisAction: "cette action",
|
|
180
|
+
unknownAction: "Action inconnue",
|
|
181
|
+
somethingWentWrong: "Une erreur est survenue",
|
|
182
|
+
openChatA11y: "Ouvrir la conversation avec l\u2019assistant",
|
|
183
|
+
closeChatA11y: "Fermer la conversation",
|
|
184
|
+
stopGeneratingA11y: "Arr\xEAter la g\xE9n\xE9ration",
|
|
185
|
+
talkToHumanA11y: "Parler \xE0 un conseiller",
|
|
186
|
+
humanAgentLabel: "Conseiller",
|
|
187
|
+
escalationRequested: "J\u2019ai contact\xE9 un conseiller. Vous pouvez continuer \xE0 utiliser l\u2019application en attendant.",
|
|
188
|
+
escalationConnected: "Un conseiller a rejoint la conversation.",
|
|
189
|
+
escalationResolved: "L\u2019intervention du conseiller est termin\xE9e. Je peux \xE0 nouveau vous aider.",
|
|
190
|
+
escalationOffer: "Si vous pr\xE9f\xE9rez, je peux faire appel \xE0 un conseiller.",
|
|
191
|
+
escalationOfferChip: "Parler \xE0 un conseiller",
|
|
192
|
+
escalationPendingBanner: "En attente d\u2019un conseiller\u2026",
|
|
193
|
+
escalationActiveBanner: "Vous discutez avec un conseiller",
|
|
194
|
+
pillWorking: "En cours\u2026",
|
|
195
|
+
pillExpandA11y: "Ouvrir la conversation avec l\u2019assistant",
|
|
196
|
+
pillStopA11y: "Arr\xEAter l\u2019assistant",
|
|
197
|
+
missionPause: "Mettre en pause",
|
|
198
|
+
missionResume: "Reprendre la t\xE2che",
|
|
199
|
+
missionCancel: "Annuler la t\xE2che",
|
|
200
|
+
missionPaused: "En pause",
|
|
201
|
+
pillDone: "Termin\xE9 \u2014 touchez pour lire",
|
|
202
|
+
micStartA11y: "Maintenez pour parler",
|
|
203
|
+
micStopA11y: "Rel\xE2chez pour envoyer",
|
|
204
|
+
micListening: "\xC9coute en cours\u2026"
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
// src/i18n/I18nProvider.tsx
|
|
208
|
+
var BUNDLES = {
|
|
209
|
+
"pt-BR": ptBR,
|
|
210
|
+
en,
|
|
211
|
+
es,
|
|
212
|
+
fr
|
|
213
|
+
};
|
|
214
|
+
var DEFAULT_LOCALE = "en";
|
|
215
|
+
function detectDeviceLocale() {
|
|
216
|
+
try {
|
|
217
|
+
let raw;
|
|
218
|
+
if (reactNative.Platform.OS === "ios") {
|
|
219
|
+
const manager = reactNative.NativeModules?.SettingsManager;
|
|
220
|
+
const settings = manager?.getConstants?.()?.settings ?? manager?.settings;
|
|
221
|
+
const languages = Array.isArray(settings?.AppleLanguages) ? settings.AppleLanguages : [];
|
|
222
|
+
for (const language of languages) {
|
|
223
|
+
const locale = chunkUZ2D4BVX_js.normalizeAppilotsLocale(language);
|
|
224
|
+
if (locale) return locale;
|
|
225
|
+
}
|
|
226
|
+
raw = settings?.AppleLocale;
|
|
227
|
+
} else if (reactNative.Platform.OS === "android") {
|
|
228
|
+
const manager = reactNative.NativeModules?.I18nManager;
|
|
229
|
+
raw = manager?.getConstants?.()?.localeIdentifier ?? manager?.localeIdentifier;
|
|
230
|
+
}
|
|
231
|
+
if (!raw || typeof raw !== "string") return null;
|
|
232
|
+
return chunkUZ2D4BVX_js.normalizeAppilotsLocale(raw) ?? null;
|
|
233
|
+
} catch {
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function resolveLocale(prop) {
|
|
238
|
+
if (prop && BUNDLES[prop]) return prop;
|
|
239
|
+
const detected = detectDeviceLocale();
|
|
240
|
+
if (detected && BUNDLES[detected]) return detected;
|
|
241
|
+
return DEFAULT_LOCALE;
|
|
242
|
+
}
|
|
243
|
+
var I18nContext = React.createContext(null);
|
|
244
|
+
function AppilotsI18nProvider({ locale, overrides, children }) {
|
|
245
|
+
const value = React.useMemo(() => {
|
|
246
|
+
const resolved = resolveLocale(locale ?? null);
|
|
247
|
+
const merged = overrides ? { ...BUNDLES[resolved], ...overrides } : BUNDLES[resolved];
|
|
248
|
+
return {
|
|
249
|
+
locale: resolved,
|
|
250
|
+
strings: merged,
|
|
251
|
+
t: (key) => merged[key]
|
|
252
|
+
};
|
|
253
|
+
}, [locale, overrides]);
|
|
254
|
+
return /* @__PURE__ */ React__default.default.createElement(I18nContext.Provider, { value }, children);
|
|
255
|
+
}
|
|
256
|
+
function useAppilotsI18n() {
|
|
257
|
+
const ctx = React.useContext(I18nContext);
|
|
258
|
+
if (ctx) return ctx;
|
|
259
|
+
return {
|
|
260
|
+
locale: DEFAULT_LOCALE,
|
|
261
|
+
strings: BUNDLES[DEFAULT_LOCALE],
|
|
262
|
+
t: (key) => BUNDLES[DEFAULT_LOCALE][key]
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
|
|
11
266
|
// src/introspection/captureSnapshot.ts
|
|
12
267
|
function normalizeSliderKey(value) {
|
|
13
268
|
return (value ?? "").toLowerCase().replace(/^slider[-_]/, "");
|
|
@@ -23,9 +278,9 @@ function fiberSliderMatches(fiber, registryId, registryLabel) {
|
|
|
23
278
|
function reconcileSliders(snapshot) {
|
|
24
279
|
const fiberSliders = snapshot.sliders;
|
|
25
280
|
const out = [];
|
|
26
|
-
for (const { id, kind } of
|
|
281
|
+
for (const { id, kind } of chunkUZ2D4BVX_js.componentRegistry.snapshot()) {
|
|
27
282
|
if (kind !== "slider") continue;
|
|
28
|
-
const entry =
|
|
283
|
+
const entry = chunkUZ2D4BVX_js.componentRegistry.getSlider(id);
|
|
29
284
|
if (!entry) continue;
|
|
30
285
|
const fiber = fiberSliders.find((s) => fiberSliderMatches(s, id, entry.label));
|
|
31
286
|
const visible = !!fiber || typeof entry.screen === "string" && entry.screen === snapshot.route;
|
|
@@ -53,7 +308,7 @@ function normalizeFieldKey(value) {
|
|
|
53
308
|
}
|
|
54
309
|
function canonicalizeRegisteredFields(snapshot) {
|
|
55
310
|
const claimed = /* @__PURE__ */ new Set();
|
|
56
|
-
for (const { id, kind, label } of
|
|
311
|
+
for (const { id, kind, label } of chunkUZ2D4BVX_js.componentRegistry.snapshot()) {
|
|
57
312
|
if (kind !== "field") continue;
|
|
58
313
|
if (snapshot.inputs.some((input) => input.id === id)) continue;
|
|
59
314
|
const registryLabel = (label ?? "").toLowerCase();
|
|
@@ -72,7 +327,7 @@ function canonicalizeRegisteredFields(snapshot) {
|
|
|
72
327
|
}
|
|
73
328
|
}
|
|
74
329
|
function mergeRegisteredLists(snapshot) {
|
|
75
|
-
const registered =
|
|
330
|
+
const registered = chunkUZ2D4BVX_js.listRegistry.snapshot();
|
|
76
331
|
if (registered.length === 0) return;
|
|
77
332
|
const byId = /* @__PURE__ */ new Map();
|
|
78
333
|
for (const list of snapshot.lists) {
|
|
@@ -80,20 +335,35 @@ function mergeRegisteredLists(snapshot) {
|
|
|
80
335
|
}
|
|
81
336
|
for (const entry of registered) {
|
|
82
337
|
if (entry.kind === "scroll") continue;
|
|
338
|
+
const existing = byId.get(entry.id);
|
|
339
|
+
if (!existing && !(entry.screen && entry.screen === snapshot.route)) continue;
|
|
83
340
|
const metrics = entry.getScrollMetrics?.();
|
|
84
341
|
const scrollFacts = metrics ? {
|
|
85
342
|
scrollOffsetY: Math.max(0, Math.round(metrics.offset)),
|
|
86
343
|
canScrollUp: metrics.offset > 8,
|
|
87
344
|
canScrollDown: metrics.offset + metrics.visibleLength < metrics.contentLength - 8
|
|
88
345
|
} : void 0;
|
|
89
|
-
const existing = byId.get(entry.id);
|
|
90
346
|
if (existing) {
|
|
91
347
|
existing.itemCount = existing.itemCount ?? entry.itemCount;
|
|
348
|
+
existing.totalItemCount = existing.totalItemCount ?? entry.totalItemCount;
|
|
92
349
|
existing.refreshing = existing.refreshing ?? entry.refreshing;
|
|
93
350
|
existing.empty = existing.empty ?? entry.empty;
|
|
94
351
|
existing.label = existing.label ?? entry.label;
|
|
95
352
|
existing.source = existing.source ?? "auto-tracked";
|
|
96
353
|
existing.visibleItemCount = existing.items.length;
|
|
354
|
+
const viewport = entry.measureViewport?.();
|
|
355
|
+
if (viewport && viewport.width > 0 && viewport.height > 0) {
|
|
356
|
+
let measured = 0;
|
|
357
|
+
let inViewport = 0;
|
|
358
|
+
for (const item of existing.items) {
|
|
359
|
+
const rect = chunkUZ2D4BVX_js.rectForNode(item);
|
|
360
|
+
if (!rect) continue;
|
|
361
|
+
measured++;
|
|
362
|
+
item.onScreen = rect.width > 0 && rect.height > 0 && rect.x < viewport.x + viewport.width && rect.x + rect.width > viewport.x && rect.y < viewport.y + viewport.height && rect.y + rect.height > viewport.y;
|
|
363
|
+
if (item.onScreen) inViewport++;
|
|
364
|
+
}
|
|
365
|
+
if (measured === existing.items.length) existing.viewportItemCount = inViewport;
|
|
366
|
+
}
|
|
97
367
|
if (entry.dataPreview && entry.dataPreview.length > 0) {
|
|
98
368
|
existing.dataPreview = entry.dataPreview;
|
|
99
369
|
}
|
|
@@ -110,6 +380,7 @@ function mergeRegisteredLists(snapshot) {
|
|
|
110
380
|
containerType: entry.component,
|
|
111
381
|
source: "registry",
|
|
112
382
|
itemCount: entry.itemCount,
|
|
383
|
+
totalItemCount: entry.totalItemCount,
|
|
113
384
|
visibleItemCount: 0,
|
|
114
385
|
refreshing: entry.refreshing,
|
|
115
386
|
empty: entry.empty,
|
|
@@ -121,7 +392,7 @@ function mergeRegisteredLists(snapshot) {
|
|
|
121
392
|
}
|
|
122
393
|
}
|
|
123
394
|
function mergeRegisteredScrollables(snapshot) {
|
|
124
|
-
const registered =
|
|
395
|
+
const registered = chunkUZ2D4BVX_js.listRegistry.snapshot().filter((e) => e.kind === "scroll");
|
|
125
396
|
if (registered.length === 0) return;
|
|
126
397
|
const listsById = /* @__PURE__ */ new Map();
|
|
127
398
|
for (const list of snapshot.lists) {
|
|
@@ -154,7 +425,7 @@ function mergeRegisteredScrollables(snapshot) {
|
|
|
154
425
|
if (out.length > 0) snapshot.scrollables = out;
|
|
155
426
|
}
|
|
156
427
|
function mergeNativeDialog(snapshot) {
|
|
157
|
-
const dialog =
|
|
428
|
+
const dialog = chunkUZ2D4BVX_js.getOpenNativeDialog();
|
|
158
429
|
if (!dialog) return;
|
|
159
430
|
snapshot.nativeDialog = {
|
|
160
431
|
id: dialog.id,
|
|
@@ -169,21 +440,58 @@ function mergeNativeDialog(snapshot) {
|
|
|
169
440
|
}
|
|
170
441
|
var MIN_FIBERS_FOR_BLINDNESS = 200;
|
|
171
442
|
function recordBlindWalk() {
|
|
172
|
-
const walk =
|
|
443
|
+
const walk = chunkUZ2D4BVX_js.getLastWalkDiagnostics();
|
|
173
444
|
if (!walk) return;
|
|
174
445
|
if (walk.visitedFibers < MIN_FIBERS_FOR_BLINDNESS) return;
|
|
175
|
-
if (
|
|
176
|
-
|
|
446
|
+
if (chunkUZ2D4BVX_js.totalDetectorHits(walk.detectors) > 0) return;
|
|
447
|
+
chunkUZ2D4BVX_js.recordIntrospectionFailure("walk-recognized-nothing", null);
|
|
448
|
+
}
|
|
449
|
+
function mergeRegisteredFieldValues(snapshot) {
|
|
450
|
+
const present = new Set(snapshot.inputs.map((i) => normalizeFieldKey(i.id)));
|
|
451
|
+
const onScreenIds = [
|
|
452
|
+
...snapshot.buttons.map((b) => (b.id ?? "").toLowerCase()),
|
|
453
|
+
...snapshot.toggles.map((t) => (t.id ?? "").toLowerCase())
|
|
454
|
+
].filter(Boolean);
|
|
455
|
+
const onScreenLabels = new Set(
|
|
456
|
+
[...snapshot.buttons.map((b) => b.label), ...snapshot.texts].filter((l) => !!l).map((l) => l.toLowerCase())
|
|
457
|
+
);
|
|
458
|
+
for (const { id, kind, screen, label } of chunkUZ2D4BVX_js.componentRegistry.snapshot()) {
|
|
459
|
+
if (kind !== "field") continue;
|
|
460
|
+
const key = normalizeFieldKey(id);
|
|
461
|
+
if (!key || present.has(key)) continue;
|
|
462
|
+
const entry = chunkUZ2D4BVX_js.componentRegistry.getField(id);
|
|
463
|
+
if (!entry) continue;
|
|
464
|
+
const fieldType = entry.fieldType ?? "";
|
|
465
|
+
if (fieldType === "text" || fieldType === "") continue;
|
|
466
|
+
const declaresRoute = typeof screen === "string" && screen === snapshot.route;
|
|
467
|
+
if (screen && !declaresRoute && !chunkUZ2D4BVX_js.getActiveRouteNames().includes(screen)) continue;
|
|
468
|
+
const idEvidence = onScreenIds.some((candidate) => candidate.split(/[^a-z0-9]+/).includes(key));
|
|
469
|
+
const labelEvidence = !!entry.label && onScreenLabels.has(entry.label.toLowerCase());
|
|
470
|
+
if (!declaresRoute && !idEvidence && !labelEvidence) continue;
|
|
471
|
+
let value;
|
|
472
|
+
try {
|
|
473
|
+
value = String(entry.getValue() ?? "");
|
|
474
|
+
} catch {
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
snapshot.inputs.push({
|
|
478
|
+
id,
|
|
479
|
+
label: entry.label ?? label,
|
|
480
|
+
value,
|
|
481
|
+
type: fieldType
|
|
482
|
+
});
|
|
483
|
+
present.add(key);
|
|
484
|
+
}
|
|
177
485
|
}
|
|
178
486
|
function captureSnapshot() {
|
|
179
|
-
const root =
|
|
487
|
+
const root = chunkUZ2D4BVX_js.getFiberRoot();
|
|
180
488
|
if (!root) {
|
|
181
|
-
|
|
489
|
+
chunkUZ2D4BVX_js.appilotsDebugWarn(
|
|
182
490
|
"captureSnapshot: fiber root not captured yet. Ensure <AppilotsProvider> has rendered before calling this."
|
|
183
491
|
);
|
|
184
|
-
|
|
492
|
+
chunkUZ2D4BVX_js.recordIntrospectionFailure("never-mounted", null);
|
|
185
493
|
return {
|
|
186
|
-
route:
|
|
494
|
+
route: chunkUZ2D4BVX_js.getCurrentScreen(),
|
|
187
495
|
texts: [],
|
|
188
496
|
inputs: [],
|
|
189
497
|
buttons: [],
|
|
@@ -197,9 +505,9 @@ function captureSnapshot() {
|
|
|
197
505
|
};
|
|
198
506
|
}
|
|
199
507
|
const start = Date.now();
|
|
200
|
-
const snapshot =
|
|
508
|
+
const snapshot = chunkUZ2D4BVX_js.walkFiber(root);
|
|
201
509
|
recordBlindWalk();
|
|
202
|
-
const activePath =
|
|
510
|
+
const activePath = chunkUZ2D4BVX_js.getActiveRouteNames();
|
|
203
511
|
const deepestRoute = activePath[activePath.length - 1];
|
|
204
512
|
if (deepestRoute) snapshot.route = deepestRoute;
|
|
205
513
|
mergeRegisteredLists(snapshot);
|
|
@@ -207,15 +515,16 @@ function captureSnapshot() {
|
|
|
207
515
|
mergeNativeDialog(snapshot);
|
|
208
516
|
reconcileSliders(snapshot);
|
|
209
517
|
canonicalizeRegisteredFields(snapshot);
|
|
210
|
-
|
|
211
|
-
|
|
518
|
+
mergeRegisteredFieldValues(snapshot);
|
|
519
|
+
chunkUZ2D4BVX_js.clampSnapshotToWireLimits(snapshot);
|
|
520
|
+
const entries = chunkUZ2D4BVX_js.deriveInteractionElements(snapshot, { rectOf: chunkUZ2D4BVX_js.rectForNode });
|
|
212
521
|
const rectById = new Map(
|
|
213
522
|
entries.flatMap((entry) => entry.rect ? [[entry.id, entry.rect]] : [])
|
|
214
523
|
);
|
|
215
|
-
snapshot.elements = entries.map(
|
|
216
|
-
snapshot.choiceGroups =
|
|
217
|
-
|
|
218
|
-
|
|
524
|
+
snapshot.elements = entries.map(chunkUZ2D4BVX_js.toWireElement);
|
|
525
|
+
snapshot.choiceGroups = chunkUZ2D4BVX_js.attachElementIdsToChoiceGroups(snapshot.choiceGroups, snapshot.elements);
|
|
526
|
+
chunkUZ2D4BVX_js.clampSnapshotToWireLimits(snapshot);
|
|
527
|
+
chunkUZ2D4BVX_js.elementRegistry.replaceAll(
|
|
219
528
|
snapshot.elements.map((element) => {
|
|
220
529
|
const rect = rectById.get(element.id);
|
|
221
530
|
return rect ? { ...element, rect } : element;
|
|
@@ -227,10 +536,10 @@ function captureSnapshot() {
|
|
|
227
536
|
(acc, l) => acc + (typeof l.itemCount === "number" ? l.itemCount : 0),
|
|
228
537
|
0
|
|
229
538
|
);
|
|
230
|
-
|
|
539
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
231
540
|
`captureSnapshot: route="${snapshot.route}" texts=${snapshot.texts.length} inputs=${snapshot.inputs.length} buttons=${snapshot.buttons.length} toggles=${snapshot.toggles.length} sliders=${snapshot.sliders.length} loading=${snapshot.loading} modal=${snapshot.modalOpen} lists=${snapshot.lists.length}(visibleItems=${totalListItems}, dataItems=${totalListDataItems}) choices=${snapshot.choiceGroups.length} elements=${snapshot.elements.length} ` + (snapshot.truncated ? "truncated=true " : "") + `(walked ${snapshot.stats?.visitedFibers ?? 0} fibers, skipped ${snapshot.stats?.skippedHidden ?? 0} hidden, ${elapsed}ms)`
|
|
232
541
|
);
|
|
233
|
-
|
|
542
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
234
543
|
`captureSnapshot detail: lists=[${snapshot.lists.map((l) => `${l.containerType}:${l.id ?? l.label ?? "?"}(rows=${l.items.length})`).join(", ")}] inputs=[${snapshot.inputs.map((i) => i.id ?? i.label ?? "?").slice(0, 12).join(", ")}] buttons=[${snapshot.buttons.map((b) => b.id ?? b.label ?? "?").slice(0, 15).join(", ")}]`
|
|
235
544
|
);
|
|
236
545
|
return snapshot;
|
|
@@ -241,10 +550,10 @@ function registryCounts() {
|
|
|
241
550
|
toggles: 0,
|
|
242
551
|
sliders: 0,
|
|
243
552
|
targets: 0,
|
|
244
|
-
lists:
|
|
245
|
-
elements:
|
|
553
|
+
lists: chunkUZ2D4BVX_js.listRegistry.snapshot().length,
|
|
554
|
+
elements: chunkUZ2D4BVX_js.elementRegistry.size
|
|
246
555
|
};
|
|
247
|
-
for (const { kind } of
|
|
556
|
+
for (const { kind } of chunkUZ2D4BVX_js.componentRegistry.snapshot()) {
|
|
248
557
|
if (kind === "field") counts.fields++;
|
|
249
558
|
else if (kind === "toggle") counts.toggles++;
|
|
250
559
|
else if (kind === "slider") counts.sliders++;
|
|
@@ -253,26 +562,26 @@ function registryCounts() {
|
|
|
253
562
|
return counts;
|
|
254
563
|
}
|
|
255
564
|
function appilotsSelfCheck() {
|
|
256
|
-
const root =
|
|
565
|
+
const root = chunkUZ2D4BVX_js.getFiberRoot();
|
|
257
566
|
const start = Date.now();
|
|
258
|
-
if (root)
|
|
567
|
+
if (root) chunkUZ2D4BVX_js.walkFiber(root);
|
|
259
568
|
const elapsedMs = Date.now() - start;
|
|
260
|
-
const walk =
|
|
569
|
+
const walk = chunkUZ2D4BVX_js.getLastWalkDiagnostics();
|
|
261
570
|
return {
|
|
262
|
-
sdkVersion:
|
|
571
|
+
sdkVersion: chunkUZ2D4BVX_js.SDK_VERSION,
|
|
263
572
|
reactVersion: React__default.default.version ?? null,
|
|
264
|
-
route:
|
|
265
|
-
introspection:
|
|
266
|
-
autoTracking:
|
|
573
|
+
route: chunkUZ2D4BVX_js.getCurrentScreen() || null,
|
|
574
|
+
introspection: chunkUZ2D4BVX_js.getIntrospectionDiagnostics(),
|
|
575
|
+
autoTracking: chunkUZ2D4BVX_js.getAutoTrackingState(),
|
|
267
576
|
walk: {
|
|
268
577
|
visitedFibers: root ? walk?.visitedFibers ?? 0 : 0,
|
|
269
578
|
skippedHidden: root ? walk?.skippedHidden ?? 0 : 0,
|
|
270
579
|
elapsedMs
|
|
271
580
|
},
|
|
272
|
-
detectors: root ? walk?.detectors ??
|
|
581
|
+
detectors: root ? walk?.detectors ?? chunkUZ2D4BVX_js.emptyDetectorCounts() : chunkUZ2D4BVX_js.emptyDetectorCounts(),
|
|
273
582
|
registry: registryCounts(),
|
|
274
|
-
nameMangling:
|
|
275
|
-
geometry: { availability:
|
|
583
|
+
nameMangling: chunkUZ2D4BVX_js.getNameManglingProbe(),
|
|
584
|
+
geometry: { availability: chunkUZ2D4BVX_js.geometryAvailability(), ...chunkUZ2D4BVX_js.geometryStats() }
|
|
276
585
|
};
|
|
277
586
|
}
|
|
278
587
|
|
|
@@ -285,7 +594,7 @@ function declaredState(props) {
|
|
|
285
594
|
return typeof checked === "boolean" ? checked : void 0;
|
|
286
595
|
}
|
|
287
596
|
function isReactNativeSwitch(fiber) {
|
|
288
|
-
return
|
|
597
|
+
return chunkUZ2D4BVX_js.getTypeName(fiber?.type) === "Switch" || chunkUZ2D4BVX_js.getTypeName(fiber?.elementType) === "Switch";
|
|
289
598
|
}
|
|
290
599
|
var SWITCH_FLIP_HANDLERS = ["onValueChange", "onChange", "onPress"];
|
|
291
600
|
function flipSwitchFiber(fiber, next) {
|
|
@@ -309,6 +618,11 @@ function flipSwitchFiber(fiber, next) {
|
|
|
309
618
|
return { ok: true, via: handler.via };
|
|
310
619
|
}
|
|
311
620
|
|
|
621
|
+
// src/introspection/positionalIdentity.ts
|
|
622
|
+
function isPositionalControlId(value) {
|
|
623
|
+
return /^(?:list-\d+-item-\d+-)?(?:btn|input|slider|toggle)-\d+$/i.test(value.trim());
|
|
624
|
+
}
|
|
625
|
+
|
|
312
626
|
// src/introspection/findInteractive.ts
|
|
313
627
|
function getTypeName2(type) {
|
|
314
628
|
if (!type) return null;
|
|
@@ -383,7 +697,7 @@ function shouldSkipSubtree2(fiber) {
|
|
|
383
697
|
const typeName = getTypeName2(fiber.type) ?? getTypeName2(fiber.elementType);
|
|
384
698
|
if (typeName && SELF_REFERENTIAL_COMPONENTS.has(typeName)) return true;
|
|
385
699
|
if (isAppilotsSkipMarked(props)) return true;
|
|
386
|
-
if (
|
|
700
|
+
if (chunkUZ2D4BVX_js.isModalFiber(fiber) && props.visible === false) return true;
|
|
387
701
|
if (matchesName(fiber, "Screen") && props.activityState === 0) return true;
|
|
388
702
|
const style = props.style;
|
|
389
703
|
if (style) {
|
|
@@ -393,9 +707,14 @@ function shouldSkipSubtree2(fiber) {
|
|
|
393
707
|
}
|
|
394
708
|
return false;
|
|
395
709
|
}
|
|
396
|
-
var normalize =
|
|
710
|
+
var normalize = chunkUZ2D4BVX_js.foldForCompare;
|
|
397
711
|
function scoreMatchDetail(fiber, queryNorm, queryRaw) {
|
|
398
712
|
const props = fiber.memoizedProps ?? {};
|
|
713
|
+
if (chunkUZ2D4BVX_js.isSourceControlId(queryRaw)) {
|
|
714
|
+
const matches = chunkUZ2D4BVX_js.sourceControlId(fiber) === queryRaw;
|
|
715
|
+
const disabled = props.disabled === true || props.accessibilityState?.disabled === true;
|
|
716
|
+
return { score: matches ? disabled ? 60 : 120 : 0, named: matches, disabled };
|
|
717
|
+
}
|
|
399
718
|
const candidates = [];
|
|
400
719
|
if (typeof props.testID === "string") candidates.push({ val: props.testID, weight: 100 });
|
|
401
720
|
if (typeof props.accessibilityLabel === "string")
|
|
@@ -414,11 +733,11 @@ function scoreMatchDetail(fiber, queryNorm, queryRaw) {
|
|
|
414
733
|
if (!vNorm) continue;
|
|
415
734
|
if (val === queryRaw) best = Math.max(best, weight + 20);
|
|
416
735
|
else if (vNorm === queryNorm) best = Math.max(best, weight + 10);
|
|
417
|
-
else if (queryNorm && (vNorm.includes(queryNorm) || queryNorm.includes(vNorm)))
|
|
736
|
+
else if (!isPositionalControlId(queryRaw) && queryNorm && (vNorm.includes(queryNorm) || queryNorm.includes(vNorm)))
|
|
418
737
|
best = Math.max(best, weight - 20);
|
|
419
738
|
}
|
|
420
739
|
const named = best >= IDENTITY_MATCH_SCORE;
|
|
421
|
-
const disabledProp = props.disabled === true;
|
|
740
|
+
const disabledProp = props.disabled === true || props.editable === false || props.readOnly === true;
|
|
422
741
|
const disabledA11y = typeof props.accessibilityState === "object" && props.accessibilityState !== null && props.accessibilityState.disabled === true;
|
|
423
742
|
if (best > 0 && disabledProp) {
|
|
424
743
|
best = Math.max(1, best - 60);
|
|
@@ -428,12 +747,18 @@ function scoreMatchDetail(fiber, queryNorm, queryRaw) {
|
|
|
428
747
|
}
|
|
429
748
|
return { score: best, named, disabled: disabledProp || disabledA11y };
|
|
430
749
|
}
|
|
750
|
+
var inputIdentities = /* @__PURE__ */ new WeakMap();
|
|
431
751
|
function wrapTextInput(fiber) {
|
|
752
|
+
const identity = inputIdentities.get(fiber) ?? (fiber.alternate && inputIdentities.get(fiber.alternate)) ?? {};
|
|
753
|
+
inputIdentities.set(fiber, identity);
|
|
754
|
+
if (fiber.alternate) inputIdentities.set(fiber.alternate, identity);
|
|
432
755
|
const getProps = () => fiber.memoizedProps ?? {};
|
|
433
756
|
return {
|
|
434
757
|
kind: "field",
|
|
758
|
+
controlIdentity: identity,
|
|
435
759
|
label: getProps().accessibilityLabel ?? getProps().label ?? getProps().placeholder ?? getProps().testID,
|
|
436
760
|
getValue: () => getProps().value,
|
|
761
|
+
finishEditing: () => chunkUZ2D4BVX_js.endTextInputEditing(getProps()),
|
|
437
762
|
setValue: (value) => {
|
|
438
763
|
const { onChangeText, onChange } = getProps();
|
|
439
764
|
if (typeof onChangeText === "function") {
|
|
@@ -468,7 +793,7 @@ function wrapSwitch(fiber) {
|
|
|
468
793
|
// `accessibilityRole="switch"`) has only the former, and reporting
|
|
469
794
|
// `false` for a control that is on is worse than reporting nothing:
|
|
470
795
|
// the caller inverts this to decide where to move.
|
|
471
|
-
getValue: () =>
|
|
796
|
+
getValue: () => chunkUZ2D4BVX_js.switchValue(getProps()),
|
|
472
797
|
setValue: (value) => {
|
|
473
798
|
const boolVal = typeof value === "boolean" ? value : value === "true" || value === true;
|
|
474
799
|
const flipped = flipSwitchFiber(fiber, boolVal);
|
|
@@ -514,18 +839,18 @@ function describeCandidate(fiber, kind) {
|
|
|
514
839
|
const props = fiber?.memoizedProps ?? {};
|
|
515
840
|
return props.testID ?? props.accessibilityLabel ?? props.placeholder ?? (kind === "target" ? findChildText(fiber) : void 0);
|
|
516
841
|
}
|
|
517
|
-
function isDescendantOf(fiber, ancestor) {
|
|
842
|
+
function isDescendantOf(fiber, ancestor, parents) {
|
|
518
843
|
if (!fiber || !ancestor) return false;
|
|
519
|
-
let node = fiber
|
|
520
|
-
for (let depth = 0; node && depth < 200; depth++, node = node
|
|
844
|
+
let node = parents.get(fiber);
|
|
845
|
+
for (let depth = 0; node && depth < 200; depth++, node = parents.get(node)) {
|
|
521
846
|
if (node === ancestor) return true;
|
|
522
847
|
}
|
|
523
848
|
return false;
|
|
524
849
|
}
|
|
525
850
|
function findInteractiveByIdentifier(query, options = {}) {
|
|
526
|
-
const root =
|
|
851
|
+
const root = chunkUZ2D4BVX_js.getFiberRoot();
|
|
527
852
|
if (!root) {
|
|
528
|
-
|
|
853
|
+
chunkUZ2D4BVX_js.appilotsDebugWarn("findInteractiveByIdentifier: fiber root not captured yet");
|
|
529
854
|
return null;
|
|
530
855
|
}
|
|
531
856
|
const queryNorm = normalize(query);
|
|
@@ -538,18 +863,20 @@ function findInteractiveByIdentifier(query, options = {}) {
|
|
|
538
863
|
let bestDisabled = false;
|
|
539
864
|
let tied = [];
|
|
540
865
|
const visited = /* @__PURE__ */ new WeakSet();
|
|
866
|
+
const parents = /* @__PURE__ */ new WeakMap();
|
|
541
867
|
const stack = [];
|
|
542
|
-
if (root.child) stack.push(root.child);
|
|
868
|
+
if (root.child) stack.push({ fiber: root.child, parent: root });
|
|
543
869
|
while (stack.length > 0) {
|
|
544
|
-
const fiber = stack.pop();
|
|
870
|
+
const { fiber, parent } = stack.pop();
|
|
545
871
|
if (!fiber || visited.has(fiber)) continue;
|
|
546
872
|
visited.add(fiber);
|
|
547
|
-
|
|
873
|
+
parents.set(fiber, parent);
|
|
874
|
+
if (fiber.sibling) stack.push({ fiber: fiber.sibling, parent });
|
|
548
875
|
if (shouldSkipSubtree2(fiber)) continue;
|
|
549
876
|
const props = fiber.memoizedProps ?? {};
|
|
550
877
|
let kind = null;
|
|
551
878
|
if (matchesName(fiber, "TextInput")) kind = "field";
|
|
552
|
-
else if (
|
|
879
|
+
else if (chunkUZ2D4BVX_js.isSwitchLike(fiber, props)) kind = "toggle";
|
|
553
880
|
else if (isPressableTarget(fiber)) kind = "target";
|
|
554
881
|
if (kind && (!options.kind || options.kind === kind)) {
|
|
555
882
|
const detail = scoreMatchDetail(fiber, queryNorm, queryRaw);
|
|
@@ -558,7 +885,7 @@ function findInteractiveByIdentifier(query, options = {}) {
|
|
|
558
885
|
if (score > bestScore) tied = [{ fiber, kind }];
|
|
559
886
|
else if (score === bestScore) tied.push({ fiber, kind });
|
|
560
887
|
}
|
|
561
|
-
const beatsBest = score > bestScore || score > 0 && score === bestScore && isDescendantOf(fiber, bestFiber);
|
|
888
|
+
const beatsBest = score > bestScore || score > 0 && score === bestScore && isDescendantOf(fiber, bestFiber, parents);
|
|
562
889
|
if (beatsBest) {
|
|
563
890
|
bestScore = score;
|
|
564
891
|
bestFiber = fiber;
|
|
@@ -567,14 +894,18 @@ function findInteractiveByIdentifier(query, options = {}) {
|
|
|
567
894
|
bestId = describeCandidate(fiber, kind);
|
|
568
895
|
if (kind === "field") bestHandle = wrapTextInput(fiber);
|
|
569
896
|
else if (kind === "toggle") bestHandle = wrapSwitch(fiber);
|
|
570
|
-
else
|
|
897
|
+
else if (chunkUZ2D4BVX_js.isSourceControlId(queryRaw)) {
|
|
898
|
+
const bound = chunkUZ2D4BVX_js.sourceControlTarget(fiber);
|
|
899
|
+
if (!bound || bound.disabled) bestHandle = null;
|
|
900
|
+
else bestHandle = wrapTouchable(bound.fiber, findChildText(fiber));
|
|
901
|
+
} else bestHandle = wrapTouchable(fiber, findChildText(fiber));
|
|
571
902
|
}
|
|
572
903
|
}
|
|
573
904
|
if (kind === "toggle") continue;
|
|
574
|
-
if (fiber.child) stack.push(fiber.child);
|
|
905
|
+
if (fiber.child) stack.push({ fiber: fiber.child, parent: fiber });
|
|
575
906
|
}
|
|
576
907
|
if (bestHandle && bestScore < (options.minScore ?? 0)) {
|
|
577
|
-
|
|
908
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
578
909
|
`findInteractiveByIdentifier: query="${query}" \u2192 best match scored ${bestScore}, below the requested floor of ${options.minScore} \u2014 refusing it`
|
|
579
910
|
);
|
|
580
911
|
return null;
|
|
@@ -582,23 +913,138 @@ function findInteractiveByIdentifier(query, options = {}) {
|
|
|
582
913
|
if (bestHandle) {
|
|
583
914
|
const independent = tied.filter(
|
|
584
915
|
(candidate) => !tied.some(
|
|
585
|
-
(other) => other.fiber !== candidate.fiber && isDescendantOf(other.fiber, candidate.fiber)
|
|
916
|
+
(other) => other.fiber !== candidate.fiber && isDescendantOf(other.fiber, candidate.fiber, parents)
|
|
586
917
|
)
|
|
587
918
|
);
|
|
588
919
|
bestHandle.matchCount = independent.length;
|
|
589
920
|
bestHandle.named = bestNamed;
|
|
590
921
|
bestHandle.disabled = bestDisabled;
|
|
922
|
+
const measured = bestFiber;
|
|
923
|
+
bestHandle.measure = () => chunkUZ2D4BVX_js.rectOfFiber(measured);
|
|
591
924
|
const candidates = independent.map(({ fiber, kind }) => describeCandidate(fiber, kind)).filter((id) => typeof id === "string" && id.length > 0).slice(0, 8);
|
|
592
925
|
if (candidates.length > 0) bestHandle.matchCandidates = candidates;
|
|
593
|
-
|
|
926
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
594
927
|
`findInteractiveByIdentifier: query="${query}" \u2192 kind=${bestHandle.kind} label="${bestHandle.label ?? bestId}" score=${bestScore} named=${bestNamed} disabled=${bestDisabled} tied=${independent.length}`
|
|
595
928
|
);
|
|
596
929
|
} else {
|
|
597
|
-
|
|
930
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(`findInteractiveByIdentifier: query="${query}" \u2192 no match`);
|
|
598
931
|
}
|
|
599
932
|
return bestHandle;
|
|
600
933
|
}
|
|
601
934
|
|
|
935
|
+
// src/introspection/spotlightTarget.ts
|
|
936
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
937
|
+
var current = null;
|
|
938
|
+
var seq = 0;
|
|
939
|
+
var expiry = null;
|
|
940
|
+
var SPOTLIGHT_TTL_MS = 1200;
|
|
941
|
+
var mode = "off";
|
|
942
|
+
function setSpotlightMode(next) {
|
|
943
|
+
mode = next;
|
|
944
|
+
}
|
|
945
|
+
function getSpotlightMode() {
|
|
946
|
+
return mode;
|
|
947
|
+
}
|
|
948
|
+
function emit() {
|
|
949
|
+
for (const listener of listeners) listener(current);
|
|
950
|
+
}
|
|
951
|
+
function setSpotlightTarget(rect, label) {
|
|
952
|
+
if (expiry) {
|
|
953
|
+
clearTimeout(expiry);
|
|
954
|
+
expiry = null;
|
|
955
|
+
}
|
|
956
|
+
if (!rect) {
|
|
957
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
958
|
+
`setSpotlightTarget: cleared${label ? ` (was about to mark "${label}")` : ""}`
|
|
959
|
+
);
|
|
960
|
+
if (current === null) return;
|
|
961
|
+
current = null;
|
|
962
|
+
emit();
|
|
963
|
+
return;
|
|
964
|
+
}
|
|
965
|
+
current = { rect, label, seq: ++seq };
|
|
966
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
967
|
+
`setSpotlightTarget: seq=${current.seq} label="${label ?? ""}" rect=${Math.round(rect.x)},${Math.round(rect.y)} ${Math.round(rect.width)}x${Math.round(rect.height)}`
|
|
968
|
+
);
|
|
969
|
+
emit();
|
|
970
|
+
expiry = setTimeout(() => {
|
|
971
|
+
expiry = null;
|
|
972
|
+
current = null;
|
|
973
|
+
emit();
|
|
974
|
+
}, SPOTLIGHT_TTL_MS);
|
|
975
|
+
}
|
|
976
|
+
function getSpotlightTarget() {
|
|
977
|
+
return current;
|
|
978
|
+
}
|
|
979
|
+
function subscribeSpotlight(listener) {
|
|
980
|
+
listeners.add(listener);
|
|
981
|
+
return () => {
|
|
982
|
+
listeners.delete(listener);
|
|
983
|
+
};
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
// src/introspection/scrollIntoView.ts
|
|
987
|
+
var REVEAL_MARGIN = 24;
|
|
988
|
+
function offsetToReveal({ rect, viewport, metrics }) {
|
|
989
|
+
const maxOffset = Math.max(0, metrics.contentLength - metrics.visibleLength);
|
|
990
|
+
const viewTop = viewport.top + REVEAL_MARGIN;
|
|
991
|
+
const viewBottom = viewport.top + viewport.height - REVEAL_MARGIN;
|
|
992
|
+
const tallerThanViewport = rect.height > viewport.height - REVEAL_MARGIN * 2;
|
|
993
|
+
let delta;
|
|
994
|
+
if (tallerThanViewport) {
|
|
995
|
+
if (rect.y >= viewTop && rect.y <= viewBottom) return null;
|
|
996
|
+
delta = rect.y - viewTop;
|
|
997
|
+
} else if (rect.y < viewTop) {
|
|
998
|
+
delta = rect.y - viewTop;
|
|
999
|
+
} else if (rect.y + rect.height > viewBottom) {
|
|
1000
|
+
delta = rect.y + rect.height - viewBottom;
|
|
1001
|
+
} else {
|
|
1002
|
+
return null;
|
|
1003
|
+
}
|
|
1004
|
+
const target = clamp(metrics.offset + delta, 0, maxOffset);
|
|
1005
|
+
if (Math.abs(target - metrics.offset) < 1) return null;
|
|
1006
|
+
return target;
|
|
1007
|
+
}
|
|
1008
|
+
function clamp(value, min, max) {
|
|
1009
|
+
return Math.min(max, Math.max(min, value));
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
// src/introspection/revealTarget.ts
|
|
1013
|
+
function revealTarget(rect) {
|
|
1014
|
+
const host = chunkUZ2D4BVX_js.getGeometryHost();
|
|
1015
|
+
if (!host) return { rect, scrolled: false };
|
|
1016
|
+
if (chunkUZ2D4BVX_js.isRectOnScreen(rect, host.window)) return { rect, scrolled: false };
|
|
1017
|
+
const scrollable = resolveScrollable();
|
|
1018
|
+
if (!scrollable) return { rect, scrolled: false };
|
|
1019
|
+
const metrics = scrollable.getScrollMetrics?.();
|
|
1020
|
+
if (!metrics) return { rect, scrolled: false };
|
|
1021
|
+
const box = scrollable.measureViewport?.();
|
|
1022
|
+
const viewport = box ? { top: box.y, height: box.height } : { top: 0, height: host.window.height };
|
|
1023
|
+
const target = offsetToReveal({ rect, viewport, metrics });
|
|
1024
|
+
if (target === null) return { rect, scrolled: false };
|
|
1025
|
+
const moved = scrollable.scrollToOffset?.(target) ?? false;
|
|
1026
|
+
if (!moved) {
|
|
1027
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(`revealTarget: "${scrollable.id}" refused scrollToOffset(${target})`);
|
|
1028
|
+
return { rect, scrolled: false };
|
|
1029
|
+
}
|
|
1030
|
+
const delta = target - metrics.offset;
|
|
1031
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
1032
|
+
`revealTarget: scrolled "${scrollable.id}" by ${Math.round(delta)}px (${Math.round(metrics.offset)} \u2192 ${Math.round(target)})`
|
|
1033
|
+
);
|
|
1034
|
+
return { rect: { ...rect, y: rect.y - delta }, scrolled: true };
|
|
1035
|
+
}
|
|
1036
|
+
function resolveScrollable() {
|
|
1037
|
+
const screen = chunkUZ2D4BVX_js.getCurrentScreen();
|
|
1038
|
+
const candidates = chunkUZ2D4BVX_js.listRegistry.snapshot().filter((entry) => entry.scrollToOffset && entry.getScrollMetrics).filter((entry) => !screen || !entry.screen || entry.screen === screen);
|
|
1039
|
+
if (candidates.length === 1) return candidates[0];
|
|
1040
|
+
if (candidates.length > 1) {
|
|
1041
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
1042
|
+
`revealTarget: ${candidates.length} scrollables on "${screen ?? "?"}" \u2014 cannot tell which holds the target, so not scrolling.`
|
|
1043
|
+
);
|
|
1044
|
+
}
|
|
1045
|
+
return null;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
602
1048
|
// src/executor/handlers/navigateHandler.ts
|
|
603
1049
|
var _reportedMissingNavRef = false;
|
|
604
1050
|
function reportMissingNavigationRef() {
|
|
@@ -641,43 +1087,52 @@ function screenExistsAnywhere(state, screenName) {
|
|
|
641
1087
|
return false;
|
|
642
1088
|
}
|
|
643
1089
|
function safeNavigate(nav, screenName, params, path) {
|
|
1090
|
+
const state = nav.getState?.();
|
|
1091
|
+
const rootState = nav.getRootState?.() ?? state;
|
|
644
1092
|
if (path && path.length > 0) {
|
|
1093
|
+
if (Array.isArray(rootState?.routeNames) && !screenExistsAnywhere(rootState, path[0]) && !state?.routeNames?.includes(path[0])) {
|
|
1094
|
+
if (state?.routeNames?.includes(screenName)) {
|
|
1095
|
+
nav.navigate(screenName, params);
|
|
1096
|
+
return;
|
|
1097
|
+
}
|
|
1098
|
+
throw new Error(
|
|
1099
|
+
`Route "${path[0]}" is not registered in any navigator. Cannot resolve the supplied path to "${screenName}".`
|
|
1100
|
+
);
|
|
1101
|
+
}
|
|
645
1102
|
const { root, nestedParams } = buildNestedParams(path, screenName, params);
|
|
646
|
-
|
|
1103
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
647
1104
|
`safeNavigate: using path-based navigation \u2014 root="${root}", nested=${JSON.stringify(nestedParams)}`
|
|
648
1105
|
);
|
|
649
1106
|
nav.navigate(root, nestedParams);
|
|
650
1107
|
return;
|
|
651
1108
|
}
|
|
652
|
-
const state = nav.getState?.();
|
|
653
1109
|
if (state?.routeNames?.includes(screenName)) {
|
|
654
1110
|
nav.navigate(screenName, params);
|
|
655
1111
|
return;
|
|
656
1112
|
}
|
|
657
|
-
const rootState = nav.getRootState?.() ?? state;
|
|
658
1113
|
if (!screenExistsAnywhere(rootState, screenName)) {
|
|
659
1114
|
throw new Error(
|
|
660
1115
|
`Screen "${screenName}" is not registered in any navigator. The screen may have been removed, may live inside a flow that is not currently mounted (e.g. Auth stack after login), or the MCP doc is stale.`
|
|
661
1116
|
);
|
|
662
1117
|
}
|
|
663
|
-
|
|
1118
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
664
1119
|
`safeNavigate: screen exists in nested navigator, attempting direct navigation to "${screenName}"`
|
|
665
1120
|
);
|
|
666
1121
|
nav.navigate(screenName, params);
|
|
667
1122
|
}
|
|
668
1123
|
function navigateHandler(payload, context) {
|
|
669
|
-
|
|
1124
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
670
1125
|
// Params carry record ids and, on some screens, the user's own
|
|
671
1126
|
// data — the count answers "were params passed?" and nothing else.
|
|
672
|
-
`navigateHandler called: screenName="${payload.screenName}" action="${payload.navigationAction}" params=${
|
|
1127
|
+
`navigateHandler called: screenName="${payload.screenName}" action="${payload.navigationAction}" params=${chunkUZ2D4BVX_js.describeValue(payload.params)}`
|
|
673
1128
|
);
|
|
674
1129
|
const { navigationRef, permissions } = context;
|
|
675
1130
|
const nav = navigationRef.current;
|
|
676
1131
|
if (!permissions.canNavigate) {
|
|
677
1132
|
return {
|
|
678
1133
|
success: false,
|
|
679
|
-
error: "Navigation
|
|
680
|
-
diagnose: { category: "unknown", screen: payload.screenName }
|
|
1134
|
+
error: chunkUZ2D4BVX_js.permissionDeniedMessage("Navigation", "canNavigate"),
|
|
1135
|
+
diagnose: { category: "unknown", screen: payload.screenName, recoverable: false }
|
|
681
1136
|
};
|
|
682
1137
|
}
|
|
683
1138
|
const isGoBack = payload.navigationAction === "goBack";
|
|
@@ -762,12 +1217,12 @@ function navigateHandler(payload, context) {
|
|
|
762
1217
|
diagnose: { category: "unknown", screen: payload.screenName }
|
|
763
1218
|
};
|
|
764
1219
|
}
|
|
765
|
-
|
|
1220
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
766
1221
|
`navigateHandler: navigation succeeded for "${payload.screenName}" (action="${payload.navigationAction}")`
|
|
767
1222
|
);
|
|
768
1223
|
return { success: true };
|
|
769
1224
|
} catch (err) {
|
|
770
|
-
|
|
1225
|
+
chunkUZ2D4BVX_js.appilotsDebugWarn(
|
|
771
1226
|
`navigateHandler: navigation failed for "${payload.screenName}": ${err?.message}`
|
|
772
1227
|
);
|
|
773
1228
|
const msg = String(err?.message ?? "Navigation failed");
|
|
@@ -815,18 +1270,18 @@ function markedItemIndexFromFiber(fiber) {
|
|
|
815
1270
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
816
1271
|
}
|
|
817
1272
|
function normalize2(value) {
|
|
818
|
-
return
|
|
1273
|
+
return chunkUZ2D4BVX_js.foldForCompare(String(value ?? ""));
|
|
819
1274
|
}
|
|
820
1275
|
function hasPressHandler2(fiber) {
|
|
821
1276
|
const props = fiber?.memoizedProps ?? {};
|
|
822
1277
|
return typeof props.onPress === "function" || typeof props.onPressIn === "function";
|
|
823
1278
|
}
|
|
824
1279
|
function isPressableFiber(fiber) {
|
|
825
|
-
const typeName =
|
|
826
|
-
return
|
|
1280
|
+
const typeName = chunkUZ2D4BVX_js.getTypeName(fiber.type) ?? chunkUZ2D4BVX_js.getTypeName(fiber.elementType) ?? "";
|
|
1281
|
+
return chunkUZ2D4BVX_js.TOUCHABLE_NAMES.has(typeName) || hasPressHandler2(fiber);
|
|
827
1282
|
}
|
|
828
1283
|
function findListContainers(options = {}) {
|
|
829
|
-
const root =
|
|
1284
|
+
const root = chunkUZ2D4BVX_js.getFiberRoot();
|
|
830
1285
|
if (!root) return [];
|
|
831
1286
|
const containers = [];
|
|
832
1287
|
const visited = /* @__PURE__ */ new WeakSet();
|
|
@@ -837,17 +1292,17 @@ function findListContainers(options = {}) {
|
|
|
837
1292
|
if (!fiber || visited.has(fiber)) continue;
|
|
838
1293
|
visited.add(fiber);
|
|
839
1294
|
if (fiber.sibling) stack.push(fiber.sibling);
|
|
840
|
-
if (
|
|
841
|
-
if (
|
|
842
|
-
const minItems =
|
|
843
|
-
const items =
|
|
1295
|
+
if (chunkUZ2D4BVX_js.shouldSkipSubtree(fiber)) continue;
|
|
1296
|
+
if (chunkUZ2D4BVX_js.isAlwaysListContainer(fiber) || chunkUZ2D4BVX_js.isHeuristicListContainer(fiber)) {
|
|
1297
|
+
const minItems = chunkUZ2D4BVX_js.isAlwaysListContainer(fiber) || options.allowSingleHeuristic ? 1 : 2;
|
|
1298
|
+
const items = chunkUZ2D4BVX_js.findListItems(fiber, minItems);
|
|
844
1299
|
if (items && items.length >= minItems) {
|
|
845
1300
|
containers.push({
|
|
846
1301
|
container: fiber,
|
|
847
1302
|
items,
|
|
848
1303
|
listId: listIdFromContainer(fiber),
|
|
849
1304
|
listLabel: listLabelFromContainer(fiber),
|
|
850
|
-
containerType:
|
|
1305
|
+
containerType: chunkUZ2D4BVX_js.getTypeName(fiber.type) ?? chunkUZ2D4BVX_js.getTypeName(fiber.elementType) ?? "List"
|
|
851
1306
|
});
|
|
852
1307
|
continue;
|
|
853
1308
|
}
|
|
@@ -866,7 +1321,7 @@ function findFirstTouchable(item) {
|
|
|
866
1321
|
const { fiber, includeSibling } = stack.pop();
|
|
867
1322
|
if (!fiber || visited.has(fiber)) continue;
|
|
868
1323
|
visited.add(fiber);
|
|
869
|
-
if (
|
|
1324
|
+
if (chunkUZ2D4BVX_js.shouldSkipSubtree(fiber)) continue;
|
|
870
1325
|
if (isPressableFiber(fiber)) {
|
|
871
1326
|
const props = fiber.memoizedProps ?? {};
|
|
872
1327
|
if (typeof props.onPress === "function" || typeof props.onPressIn === "function") {
|
|
@@ -893,7 +1348,7 @@ function findTouchableFibers(item) {
|
|
|
893
1348
|
const { fiber, includeSibling } = stack.pop();
|
|
894
1349
|
if (!fiber || visited.has(fiber)) continue;
|
|
895
1350
|
visited.add(fiber);
|
|
896
|
-
if (
|
|
1351
|
+
if (chunkUZ2D4BVX_js.shouldSkipSubtree(fiber)) continue;
|
|
897
1352
|
const props = fiber.memoizedProps ?? {};
|
|
898
1353
|
if (isPressableFiber(fiber) && (typeof props.onPress === "function" || typeof props.onPressIn === "function")) {
|
|
899
1354
|
found.push(fiber);
|
|
@@ -937,7 +1392,7 @@ function findFirstText(fiber) {
|
|
|
937
1392
|
const node = stack.pop();
|
|
938
1393
|
if (!node || visited.has(node)) continue;
|
|
939
1394
|
visited.add(node);
|
|
940
|
-
const typeName =
|
|
1395
|
+
const typeName = chunkUZ2D4BVX_js.getTypeName(node.type) ?? chunkUZ2D4BVX_js.getTypeName(node.elementType) ?? "";
|
|
941
1396
|
if (typeName === "Text") {
|
|
942
1397
|
const text = textFromChildren(node.memoizedProps?.children).trim();
|
|
943
1398
|
if (text) return text;
|
|
@@ -956,7 +1411,7 @@ function collectTexts(fiber) {
|
|
|
956
1411
|
const node = stack.pop();
|
|
957
1412
|
if (!node || visited.has(node)) continue;
|
|
958
1413
|
visited.add(node);
|
|
959
|
-
const typeName =
|
|
1414
|
+
const typeName = chunkUZ2D4BVX_js.getTypeName(node.type) ?? chunkUZ2D4BVX_js.getTypeName(node.elementType) ?? "";
|
|
960
1415
|
if (typeName === "Text") {
|
|
961
1416
|
const text = textFromChildren(node.memoizedProps?.children).trim();
|
|
962
1417
|
if (text) out.push(text);
|
|
@@ -968,10 +1423,10 @@ function collectTexts(fiber) {
|
|
|
968
1423
|
}
|
|
969
1424
|
function hasUsefulTouchableIdentity(fiber) {
|
|
970
1425
|
const props = fiber?.memoizedProps ?? {};
|
|
971
|
-
if (
|
|
972
|
-
if (
|
|
973
|
-
if (
|
|
974
|
-
return
|
|
1426
|
+
if (chunkUZ2D4BVX_js.isReferenceable(props.testID)) return true;
|
|
1427
|
+
if (chunkUZ2D4BVX_js.isReferenceable(props.accessibilityLabel)) return true;
|
|
1428
|
+
if (chunkUZ2D4BVX_js.isReferenceable(props.label)) return true;
|
|
1429
|
+
return chunkUZ2D4BVX_js.isReferenceable(findFirstText(fiber));
|
|
975
1430
|
}
|
|
976
1431
|
function describeTouchable(fiber) {
|
|
977
1432
|
const props = fiber?.memoizedProps ?? {};
|
|
@@ -982,10 +1437,10 @@ function describeTouchable(fiber) {
|
|
|
982
1437
|
}
|
|
983
1438
|
function touchableLooksDestructive(fiber) {
|
|
984
1439
|
const descriptor = describeTouchable(fiber);
|
|
985
|
-
if (descriptor &&
|
|
1440
|
+
if (descriptor && chunkUZ2D4BVX_js.looksDestructiveActionLabel(descriptor)) return true;
|
|
986
1441
|
const props = fiber?.memoizedProps ?? {};
|
|
987
1442
|
const haystack = [props.testID, props.accessibilityLabel, props.accessibilityHint, props.label].filter((value) => typeof value === "string").join(" ");
|
|
988
|
-
return
|
|
1443
|
+
return chunkUZ2D4BVX_js.looksDestructiveActionLabel(haystack);
|
|
989
1444
|
}
|
|
990
1445
|
function describeItemCandidate(listIndex, zeroBasedIndex, item) {
|
|
991
1446
|
const syntheticId = `list-${listIndex}-item-${zeroBasedIndex + 1}`;
|
|
@@ -1034,8 +1489,10 @@ function pressResolvedListItem(list, itemFiber, listIndex, itemIndex) {
|
|
|
1034
1489
|
(candidate) => candidate !== touchable && containsFiber(touchable, candidate)
|
|
1035
1490
|
);
|
|
1036
1491
|
if (primaryWrapsNestedTargets) {
|
|
1037
|
-
|
|
1038
|
-
|
|
1492
|
+
const outer = describeTouchable(touchable) ?? "?";
|
|
1493
|
+
const nested = safeIdentifiableTouchables.filter((candidate) => candidate !== touchable && containsFiber(touchable, candidate)).map((candidate) => describeTouchable(candidate) ?? "?").slice(0, 6);
|
|
1494
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
1495
|
+
`listItemDispatch: item "list-${listIndex}-item-${itemIndex}" has nested pressables; pressing outer row target [outer=${outer}] [nested=${nested.join(", ")}] [outerHasOnPress=${typeof touchable?.memoizedProps?.onPress === "function"}]`
|
|
1039
1496
|
);
|
|
1040
1497
|
} else {
|
|
1041
1498
|
const candidates = safeIdentifiableTouchables.map(describeTouchable).filter((d) => !!d).slice(0, 8);
|
|
@@ -1069,14 +1526,14 @@ function pressResolvedListItem(list, itemFiber, listIndex, itemIndex) {
|
|
|
1069
1526
|
}
|
|
1070
1527
|
return {
|
|
1071
1528
|
ok: true,
|
|
1072
|
-
containerType:
|
|
1529
|
+
containerType: chunkUZ2D4BVX_js.getTypeName(container.type) ?? chunkUZ2D4BVX_js.getTypeName(container.elementType) ?? list.containerType
|
|
1073
1530
|
};
|
|
1074
1531
|
} catch (err) {
|
|
1075
1532
|
return {
|
|
1076
1533
|
ok: false,
|
|
1077
1534
|
reason: "press-threw",
|
|
1078
1535
|
error: err?.message ?? "press handler threw",
|
|
1079
|
-
containerType:
|
|
1536
|
+
containerType: chunkUZ2D4BVX_js.getTypeName(container.type) ?? chunkUZ2D4BVX_js.getTypeName(container.elementType) ?? list.containerType
|
|
1080
1537
|
};
|
|
1081
1538
|
}
|
|
1082
1539
|
}
|
|
@@ -1102,10 +1559,12 @@ function scoreItemCandidate(item, zeroBasedIndex, locator) {
|
|
|
1102
1559
|
if (locator.itemKey) {
|
|
1103
1560
|
if (itemKey === locator.itemKey) score += 1e3;
|
|
1104
1561
|
else if (itemKey && normalize2(itemKey) === normalize2(locator.itemKey)) score += 950;
|
|
1562
|
+
else return 0;
|
|
1105
1563
|
}
|
|
1106
1564
|
if (locator.reactKey) {
|
|
1107
1565
|
if (reactKey === locator.reactKey) score += 900;
|
|
1108
1566
|
else if (reactKey && normalize2(reactKey) === normalize2(locator.reactKey)) score += 850;
|
|
1567
|
+
else if (!locator.itemKey) return 0;
|
|
1109
1568
|
}
|
|
1110
1569
|
if (locator.itemIndex && zeroBasedIndex === locator.itemIndex - 1) score += 750;
|
|
1111
1570
|
if (locator.itemIndex && markedIndex !== void 0 && (markedIndex === locator.itemIndex || markedIndex === locator.itemIndex - 1)) {
|
|
@@ -1132,7 +1591,7 @@ function candidateLists(containers, locator) {
|
|
|
1132
1591
|
return containers.map((list, listIndex) => ({ list, listIndex }));
|
|
1133
1592
|
}
|
|
1134
1593
|
function pressListItemAtOrdinal(listIndex, itemIndex) {
|
|
1135
|
-
if (!
|
|
1594
|
+
if (!chunkUZ2D4BVX_js.getFiberRoot()) return { ok: false, reason: "no-fiber-root" };
|
|
1136
1595
|
const containers = findListContainers({ allowSingleHeuristic: true });
|
|
1137
1596
|
if (listIndex < 0 || listIndex >= containers.length) {
|
|
1138
1597
|
return { ok: false, reason: "list-not-found" };
|
|
@@ -1146,7 +1605,7 @@ function pressListItemAtOrdinal(listIndex, itemIndex) {
|
|
|
1146
1605
|
return pressResolvedListItem(list, items[zeroBased], listIndex, itemIndex);
|
|
1147
1606
|
}
|
|
1148
1607
|
function resolveListItemByIdentity(locator) {
|
|
1149
|
-
if (!
|
|
1608
|
+
if (!chunkUZ2D4BVX_js.getFiberRoot()) return { ok: false, result: { ok: false, reason: "no-fiber-root" } };
|
|
1150
1609
|
const parsed = locator.syntheticId ? parseSyntheticListItemId(locator.syntheticId) : null;
|
|
1151
1610
|
const effective = parsed ? { ...locator, listIndex: parsed.listIndex, itemIndex: parsed.itemIndex } : locator;
|
|
1152
1611
|
const containers = findListContainers({ allowSingleHeuristic: true });
|
|
@@ -1175,7 +1634,7 @@ function resolveListItemByIdentity(locator) {
|
|
|
1175
1634
|
scoredCandidates.sort((a, b) => b.score - a.score);
|
|
1176
1635
|
const best = scoredCandidates[0];
|
|
1177
1636
|
const tiedCandidates = scoredCandidates.filter((c) => c.score === best.score);
|
|
1178
|
-
if (tiedCandidates.length > 1 && best.score < 750) {
|
|
1637
|
+
if (tiedCandidates.length > 1 && (best.score < 750 || Boolean(effective.itemKey || effective.reactKey))) {
|
|
1179
1638
|
const candidates = tiedCandidates.map((c) => describeItemCandidate(c.listIndex, c.itemIndex - 1, c.item)).slice(0, 8);
|
|
1180
1639
|
return {
|
|
1181
1640
|
ok: false,
|
|
@@ -1207,9 +1666,9 @@ function findSwitchFibers(item) {
|
|
|
1207
1666
|
const { fiber, includeSibling } = stack.pop();
|
|
1208
1667
|
if (!fiber || visited.has(fiber)) continue;
|
|
1209
1668
|
visited.add(fiber);
|
|
1210
|
-
if (
|
|
1669
|
+
if (chunkUZ2D4BVX_js.shouldSkipSubtree(fiber)) continue;
|
|
1211
1670
|
const props = fiber.memoizedProps ?? {};
|
|
1212
|
-
if (
|
|
1671
|
+
if (chunkUZ2D4BVX_js.isSwitchLike(fiber, props)) {
|
|
1213
1672
|
if (props.__appilotsInternal !== true) found.push(fiber);
|
|
1214
1673
|
if (includeSibling && fiber.sibling) {
|
|
1215
1674
|
stack.push({ fiber: fiber.sibling, includeSibling: true });
|
|
@@ -1243,11 +1702,11 @@ function toggleListItemByIdentity(locator, options) {
|
|
|
1243
1702
|
}
|
|
1244
1703
|
const target = switches[0];
|
|
1245
1704
|
const props = target?.memoizedProps ?? {};
|
|
1246
|
-
const
|
|
1247
|
-
if (options?.expected !== void 0 &&
|
|
1248
|
-
return { ok: true, containerType: list.containerType, value:
|
|
1705
|
+
const current2 = chunkUZ2D4BVX_js.switchValue(props);
|
|
1706
|
+
if (options?.expected !== void 0 && current2 === options.expected) {
|
|
1707
|
+
return { ok: true, containerType: list.containerType, value: current2, noop: true };
|
|
1249
1708
|
}
|
|
1250
|
-
const flipped = flipSwitchFiber(target, !
|
|
1709
|
+
const flipped = flipSwitchFiber(target, !current2);
|
|
1251
1710
|
if (!flipped.ok) {
|
|
1252
1711
|
if (flipped.reason === "no-handler") {
|
|
1253
1712
|
return {
|
|
@@ -1264,7 +1723,7 @@ function toggleListItemByIdentity(locator, options) {
|
|
|
1264
1723
|
containerType: list.containerType
|
|
1265
1724
|
};
|
|
1266
1725
|
}
|
|
1267
|
-
return { ok: true, containerType: list.containerType, value: !
|
|
1726
|
+
return { ok: true, containerType: list.containerType, value: !current2 };
|
|
1268
1727
|
}
|
|
1269
1728
|
function pressListItemByIdentity(locator) {
|
|
1270
1729
|
const resolved = resolveListItemByIdentity(locator);
|
|
@@ -1282,7 +1741,7 @@ function screenDiagnose(targetId, category = "component-not-found") {
|
|
|
1282
1741
|
return {
|
|
1283
1742
|
category,
|
|
1284
1743
|
targetId,
|
|
1285
|
-
screen:
|
|
1744
|
+
screen: chunkUZ2D4BVX_js.getCurrentScreen() ?? void 0
|
|
1286
1745
|
};
|
|
1287
1746
|
}
|
|
1288
1747
|
function isPressLike(action) {
|
|
@@ -1302,10 +1761,10 @@ function elementLookupKey(value) {
|
|
|
1302
1761
|
return canonicalElementId(value).toLowerCase().replace(/[\s_]+/g, "-");
|
|
1303
1762
|
}
|
|
1304
1763
|
function findRegisteredElement(elementId) {
|
|
1305
|
-
const direct =
|
|
1764
|
+
const direct = chunkUZ2D4BVX_js.elementRegistry.get(elementId) ?? chunkUZ2D4BVX_js.elementRegistry.get(canonicalElementId(elementId));
|
|
1306
1765
|
if (direct) return direct;
|
|
1307
1766
|
const wanted = elementLookupKey(elementId);
|
|
1308
|
-
return
|
|
1767
|
+
return chunkUZ2D4BVX_js.elementRegistry.snapshot().find((element) => elementLookupKey(element.id) === wanted);
|
|
1309
1768
|
}
|
|
1310
1769
|
function resolveInteractionElement(elementId) {
|
|
1311
1770
|
return getLatestElement(elementId);
|
|
@@ -1425,7 +1884,7 @@ function dispatchIdentifiedToggle(targetId, action) {
|
|
|
1425
1884
|
diagnose: { ...screenDiagnose(targetId, "unknown"), recoverable: true }
|
|
1426
1885
|
};
|
|
1427
1886
|
}
|
|
1428
|
-
|
|
1887
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
1429
1888
|
`elementDispatch: "${action}" on "${targetId}" names a switch \u2014 flipping it instead of pressing, so the verb cannot land on an ancestor`
|
|
1430
1889
|
);
|
|
1431
1890
|
try {
|
|
@@ -1459,6 +1918,12 @@ function dispatchFiberTarget(targetId, action) {
|
|
|
1459
1918
|
diagnose: screenDiagnose(targetId)
|
|
1460
1919
|
};
|
|
1461
1920
|
}
|
|
1921
|
+
const measured = handle.measure?.() ?? null;
|
|
1922
|
+
if (measured && getSpotlightMode() === "guided") {
|
|
1923
|
+
setSpotlightTarget(revealTarget(measured).rect, handle.label);
|
|
1924
|
+
} else {
|
|
1925
|
+
setSpotlightTarget(measured, handle.label);
|
|
1926
|
+
}
|
|
1462
1927
|
try {
|
|
1463
1928
|
if (isPressLike(action) && handle.kind === "target" && handle.press) {
|
|
1464
1929
|
handle.press();
|
|
@@ -1509,6 +1974,13 @@ function dispatchLegacyTarget(targetId, registry, action) {
|
|
|
1509
1974
|
};
|
|
1510
1975
|
}
|
|
1511
1976
|
function dispatchElement(element, registry, action) {
|
|
1977
|
+
if (element.dispatchable === false) {
|
|
1978
|
+
return {
|
|
1979
|
+
success: false,
|
|
1980
|
+
error: `Element "${element.id}" is observation-only and has no exact live control binding.`,
|
|
1981
|
+
diagnose: { ...screenDiagnose(element.id, "ambiguous-target"), recoverable: false }
|
|
1982
|
+
};
|
|
1983
|
+
}
|
|
1512
1984
|
if (element.disabled === true) {
|
|
1513
1985
|
return {
|
|
1514
1986
|
success: false,
|
|
@@ -1527,6 +1999,13 @@ function dispatchElement(element, registry, action) {
|
|
|
1527
1999
|
texts: element.texts
|
|
1528
2000
|
});
|
|
1529
2001
|
if (pressed.ok) return { success: true };
|
|
2002
|
+
if (!pressed.refusal && (element.listContext.itemKey || element.listContext.reactKey)) {
|
|
2003
|
+
return {
|
|
2004
|
+
success: false,
|
|
2005
|
+
error: pressed.error ?? `The observed list entity "${element.label ?? element.id}" could not be resolved. Reobserve; do not substitute its old position.`,
|
|
2006
|
+
diagnose: { ...screenDiagnose(element.id, "ambiguous-target"), recoverable: true }
|
|
2007
|
+
};
|
|
2008
|
+
}
|
|
1530
2009
|
if (pressed.refusal) {
|
|
1531
2010
|
return {
|
|
1532
2011
|
success: false,
|
|
@@ -1634,7 +2113,7 @@ function dispatchToggleElement(element, registry) {
|
|
|
1634
2113
|
}
|
|
1635
2114
|
function dispatchStructuredElementId(identifier, action) {
|
|
1636
2115
|
if (!isElementIdentifier(identifier) || !isPressLike(action)) return null;
|
|
1637
|
-
const parsed =
|
|
2116
|
+
const parsed = chunkUZ2D4BVX_js.parseStableElementId(identifier);
|
|
1638
2117
|
if (!parsed || parsed.role !== "option") return null;
|
|
1639
2118
|
if (!parsed.itemKey && !parsed.listId) return null;
|
|
1640
2119
|
const pressed = pressListItemByIdentity({
|
|
@@ -1644,7 +2123,7 @@ function dispatchStructuredElementId(identifier, action) {
|
|
|
1644
2123
|
texts: parsed.itemKey ? [parsed.itemKey] : void 0
|
|
1645
2124
|
});
|
|
1646
2125
|
if (pressed.ok) {
|
|
1647
|
-
|
|
2126
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
1648
2127
|
`elementDispatch: resolved stale el id "${identifier}" via structural identity (listId="${parsed.listId}", itemKey="${parsed.itemKey}")`
|
|
1649
2128
|
);
|
|
1650
2129
|
return { success: true };
|
|
@@ -1675,20 +2154,20 @@ function normalize4(value) {
|
|
|
1675
2154
|
return value.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]/g, "");
|
|
1676
2155
|
}
|
|
1677
2156
|
function resolveScreenForFormFields() {
|
|
1678
|
-
const activePath =
|
|
2157
|
+
const activePath = chunkUZ2D4BVX_js.getActiveRouteNames();
|
|
1679
2158
|
for (let i = activePath.length - 1; i >= 0; i--) {
|
|
1680
2159
|
const name = activePath[i];
|
|
1681
|
-
const meta = name ?
|
|
2160
|
+
const meta = name ? chunkUZ2D4BVX_js.getScreenMetadata(name) : void 0;
|
|
1682
2161
|
if (name && Array.isArray(meta?.fields) && meta.fields.length > 0) return name;
|
|
1683
2162
|
}
|
|
1684
|
-
return
|
|
2163
|
+
return chunkUZ2D4BVX_js.getCurrentScreen();
|
|
1685
2164
|
}
|
|
1686
2165
|
function collectKnownFormFields(registry) {
|
|
1687
2166
|
const registryFields = registry.snapshot().filter((entry) => entry.kind === "field" || entry.kind === "slider").map((entry) => ({ id: entry.id, label: entry.label }));
|
|
1688
2167
|
if (registryFields.length >= 2) return registryFields;
|
|
1689
2168
|
const screen = resolveScreenForFormFields();
|
|
1690
2169
|
if (screen) {
|
|
1691
|
-
const metaFields =
|
|
2170
|
+
const metaFields = chunkUZ2D4BVX_js.getScreenMetadata(screen)?.fields;
|
|
1692
2171
|
if (Array.isArray(metaFields) && metaFields.length > 0) {
|
|
1693
2172
|
return metaFields.filter((field) => !!field && typeof field.id === "string").map((field) => ({
|
|
1694
2173
|
id: field.id,
|
|
@@ -1698,7 +2177,7 @@ function collectKnownFormFields(registry) {
|
|
|
1698
2177
|
}));
|
|
1699
2178
|
}
|
|
1700
2179
|
}
|
|
1701
|
-
for (const meta of
|
|
2180
|
+
for (const meta of chunkUZ2D4BVX_js.getAllScreens()) {
|
|
1702
2181
|
if (Array.isArray(meta.fields) && meta.fields.length > 0) {
|
|
1703
2182
|
return meta.fields.filter((field) => !!field && typeof field.id === "string").map((field) => ({
|
|
1704
2183
|
id: field.id,
|
|
@@ -1811,7 +2290,7 @@ function rewriteMisplacedFormFillFields(fields, registry) {
|
|
|
1811
2290
|
const inferred = inferFieldIdForValue(String(field.value ?? ""), knownFields, used);
|
|
1812
2291
|
if (!inferred) return field;
|
|
1813
2292
|
used.add(inferred);
|
|
1814
|
-
|
|
2293
|
+
chunkUZ2D4BVX_js.appilotsDebugWarn(
|
|
1815
2294
|
`formFieldRewrite: ${field.fieldId} \u2192 ${inferred} (value=${JSON.stringify(field.value)})`
|
|
1816
2295
|
);
|
|
1817
2296
|
return { ...field, fieldId: inferred };
|
|
@@ -1819,8 +2298,8 @@ function rewriteMisplacedFormFillFields(fields, registry) {
|
|
|
1819
2298
|
}
|
|
1820
2299
|
|
|
1821
2300
|
// src/executor/formValidation.ts
|
|
1822
|
-
var FORM_VALIDATION_TEXT_RE2 =
|
|
1823
|
-
var FORM_SUCCESS_TEXT_RE =
|
|
2301
|
+
var FORM_VALIDATION_TEXT_RE2 = chunkUZ2D4BVX_js.FORM_VALIDATION_TEXT_RE;
|
|
2302
|
+
var FORM_SUCCESS_TEXT_RE = chunkUZ2D4BVX_js.FORM_WRITE_SUCCESS_TEXT_RE;
|
|
1824
2303
|
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1825
2304
|
function inferValidationFieldId(message, inputs) {
|
|
1826
2305
|
const haystack = normalizeText(message);
|
|
@@ -1844,12 +2323,18 @@ function normalizeText(value) {
|
|
|
1844
2323
|
function containsWord(haystack, needle) {
|
|
1845
2324
|
return ` ${haystack} `.includes(` ${needle} `);
|
|
1846
2325
|
}
|
|
1847
|
-
function readVisibleFormValidation(snap) {
|
|
2326
|
+
function readVisibleFormValidation(snap, beforeTexts) {
|
|
1848
2327
|
if (!snap) return void 0;
|
|
2328
|
+
const invalid = snap.inputs?.find((input) => input.invalid === true);
|
|
2329
|
+
const hasSubmitControl = snap.buttons?.some(
|
|
2330
|
+
(button) => chunkUZ2D4BVX_js.SUBMIT_CONTROL_RE.test(button.label ?? button.id ?? "")
|
|
2331
|
+
);
|
|
1849
2332
|
for (const text of snap.texts ?? []) {
|
|
1850
|
-
if (!text?.trim() || !
|
|
2333
|
+
if (!text?.trim() || !chunkUZ2D4BVX_js.isVisibleValidationText(text, { invalid: !!invalid, hasSubmitControl, beforeTexts }))
|
|
2334
|
+
continue;
|
|
1851
2335
|
return { fieldId: inferValidationFieldId(text, snap.inputs), message: text };
|
|
1852
2336
|
}
|
|
2337
|
+
if (invalid) return { fieldId: invalid.id, message: "The app marks this field as invalid." };
|
|
1853
2338
|
return void 0;
|
|
1854
2339
|
}
|
|
1855
2340
|
function readVisibleFormSuccess(snap) {
|
|
@@ -1857,20 +2342,23 @@ function readVisibleFormSuccess(snap) {
|
|
|
1857
2342
|
return (snap.texts ?? []).find((text) => text?.trim() && FORM_SUCCESS_TEXT_RE.test(text));
|
|
1858
2343
|
}
|
|
1859
2344
|
function submitAsyncStillPending(submitTargetId) {
|
|
1860
|
-
const probe =
|
|
2345
|
+
const probe = chunkUZ2D4BVX_js.probeLoadingState(submitTargetId ?? null, chunkUZ2D4BVX_js.getCurrentScreen());
|
|
1861
2346
|
if (probe.loading) return true;
|
|
1862
2347
|
if (submitTargetId && probe.pressedFound && probe.pressedDisabled) return true;
|
|
1863
2348
|
return false;
|
|
1864
2349
|
}
|
|
1865
|
-
function evaluatePostSubmitSnapshot(snap, activePath) {
|
|
1866
|
-
const validation = readVisibleFormValidation(snap);
|
|
2350
|
+
function evaluatePostSubmitSnapshot(snap, activePath, beforeTexts) {
|
|
2351
|
+
const validation = readVisibleFormValidation(snap, beforeTexts);
|
|
1867
2352
|
if (validation) {
|
|
1868
2353
|
return { status: "failure", fieldId: validation.fieldId, message: validation.message };
|
|
1869
2354
|
}
|
|
1870
2355
|
const successText = readVisibleFormSuccess(snap);
|
|
1871
2356
|
if (successText) return { status: "success", message: successText };
|
|
1872
|
-
if (!
|
|
1873
|
-
return {
|
|
2357
|
+
if (!chunkUZ2D4BVX_js.snapshotShowsOpenCreateForm(snap, activePath)) {
|
|
2358
|
+
return {
|
|
2359
|
+
status: "unverified",
|
|
2360
|
+
message: "The form closed without a visible success receipt. Inspect the resulting record before claiming the goal is complete."
|
|
2361
|
+
};
|
|
1874
2362
|
}
|
|
1875
2363
|
return void 0;
|
|
1876
2364
|
}
|
|
@@ -1885,8 +2373,8 @@ async function waitForPostSubmitOutcome(options) {
|
|
|
1885
2373
|
continue;
|
|
1886
2374
|
}
|
|
1887
2375
|
const snap2 = captureSnapshot();
|
|
1888
|
-
const activePath2 =
|
|
1889
|
-
const outcome2 = evaluatePostSubmitSnapshot(snap2, activePath2);
|
|
2376
|
+
const activePath2 = chunkUZ2D4BVX_js.getActiveRouteNames();
|
|
2377
|
+
const outcome2 = evaluatePostSubmitSnapshot(snap2, activePath2, options?.beforeTexts);
|
|
1890
2378
|
if (outcome2) return outcome2;
|
|
1891
2379
|
await sleep(pollMs);
|
|
1892
2380
|
}
|
|
@@ -1897,8 +2385,8 @@ async function waitForPostSubmitOutcome(options) {
|
|
|
1897
2385
|
};
|
|
1898
2386
|
}
|
|
1899
2387
|
const snap = captureSnapshot();
|
|
1900
|
-
const activePath =
|
|
1901
|
-
const outcome = evaluatePostSubmitSnapshot(snap, activePath);
|
|
2388
|
+
const activePath = chunkUZ2D4BVX_js.getActiveRouteNames();
|
|
2389
|
+
const outcome = evaluatePostSubmitSnapshot(snap, activePath, options?.beforeTexts);
|
|
1902
2390
|
if (outcome) return outcome;
|
|
1903
2391
|
return {
|
|
1904
2392
|
status: "failure",
|
|
@@ -1906,91 +2394,6 @@ async function waitForPostSubmitOutcome(options) {
|
|
|
1906
2394
|
};
|
|
1907
2395
|
}
|
|
1908
2396
|
|
|
1909
|
-
// ../shared/dist/chunk-ERITSWKE.mjs
|
|
1910
|
-
var DEFAULT_FUZZY_FLOOR = 4;
|
|
1911
|
-
function normalizeId(value) {
|
|
1912
|
-
return String(value ?? "").normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
1913
|
-
}
|
|
1914
|
-
var KIND_PREFIX_WORDS = "button|switch|toggle|input|field|link|btn|slider";
|
|
1915
|
-
var KEBAB_SNAKE_PREFIX_RE = new RegExp(`^(?:${KIND_PREFIX_WORDS})[-_]`, "i");
|
|
1916
|
-
var CAMEL_PREFIX_RE = new RegExp(`^(?:${KIND_PREFIX_WORDS})(?=[A-Z])`, "");
|
|
1917
|
-
function stripKindPrefix(id) {
|
|
1918
|
-
const raw = String(id ?? "");
|
|
1919
|
-
if (KEBAB_SNAKE_PREFIX_RE.test(raw)) return raw.replace(KEBAB_SNAKE_PREFIX_RE, "");
|
|
1920
|
-
if (CAMEL_PREFIX_RE.test(raw)) return raw.replace(CAMEL_PREFIX_RE, "");
|
|
1921
|
-
return raw;
|
|
1922
|
-
}
|
|
1923
|
-
function actionAllowsKind(action, kind) {
|
|
1924
|
-
if (!action || !kind) return true;
|
|
1925
|
-
switch (action) {
|
|
1926
|
-
case "press":
|
|
1927
|
-
case "longPress":
|
|
1928
|
-
return kind !== "field" && kind !== "input" && kind !== "slider";
|
|
1929
|
-
case "set_value":
|
|
1930
|
-
return kind === "slider" || kind === "field" || kind === "input";
|
|
1931
|
-
case "focus":
|
|
1932
|
-
return kind === "field" || kind === "input";
|
|
1933
|
-
case "toggle":
|
|
1934
|
-
return kind === "toggle";
|
|
1935
|
-
default:
|
|
1936
|
-
return true;
|
|
1937
|
-
}
|
|
1938
|
-
}
|
|
1939
|
-
function distinctIds(candidates) {
|
|
1940
|
-
return [...new Set(candidates.map((c) => c.id))];
|
|
1941
|
-
}
|
|
1942
|
-
function resolveTarget(requested, candidates, opts = {}) {
|
|
1943
|
-
const floor = opts.fuzzyFloor ?? DEFAULT_FUZZY_FLOOR;
|
|
1944
|
-
const nReq = normalizeId(requested);
|
|
1945
|
-
if (!nReq || candidates.length === 0) {
|
|
1946
|
-
return { status: "unverified", reason: "not-found" };
|
|
1947
|
-
}
|
|
1948
|
-
for (const c of candidates) {
|
|
1949
|
-
if (normalizeId(c.id) === nReq) {
|
|
1950
|
-
return { status: "matched", id: c.id, tier: "exact" };
|
|
1951
|
-
}
|
|
1952
|
-
}
|
|
1953
|
-
const labelExact = distinctIds(
|
|
1954
|
-
candidates.filter((c) => c.label && normalizeId(c.label) === nReq)
|
|
1955
|
-
);
|
|
1956
|
-
if (labelExact.length === 1) return { status: "matched", id: labelExact[0], tier: "exact" };
|
|
1957
|
-
if (labelExact.length > 1) return { status: "unverified", reason: "ambiguous" };
|
|
1958
|
-
const nReqStripped = normalizeId(stripKindPrefix(requested));
|
|
1959
|
-
for (const c of candidates) {
|
|
1960
|
-
const nId = normalizeId(c.id);
|
|
1961
|
-
const nIdStripped = normalizeId(stripKindPrefix(c.id));
|
|
1962
|
-
if (nReqStripped && (nReqStripped === nId || nReqStripped === nIdStripped) || nIdStripped && nIdStripped === nReq) {
|
|
1963
|
-
return { status: "matched", id: c.id, tier: "prefix" };
|
|
1964
|
-
}
|
|
1965
|
-
}
|
|
1966
|
-
if (opts.destructive) {
|
|
1967
|
-
return { status: "unverified", reason: "destructive-inexact" };
|
|
1968
|
-
}
|
|
1969
|
-
if (nReq.length < floor) {
|
|
1970
|
-
return { status: "unverified", reason: "not-found" };
|
|
1971
|
-
}
|
|
1972
|
-
const fuzzy = candidates.filter((c) => {
|
|
1973
|
-
for (const s of [c.id, c.label]) {
|
|
1974
|
-
if (!s) continue;
|
|
1975
|
-
const ns = normalizeId(s);
|
|
1976
|
-
if (ns.length >= floor && (ns.includes(nReq) || nReq.includes(ns))) return true;
|
|
1977
|
-
}
|
|
1978
|
-
return false;
|
|
1979
|
-
});
|
|
1980
|
-
if (fuzzy.length === 0) {
|
|
1981
|
-
return { status: "unverified", reason: "not-found" };
|
|
1982
|
-
}
|
|
1983
|
-
const typed = fuzzy.filter((c) => actionAllowsKind(opts.action, c.kind));
|
|
1984
|
-
if (typed.length === 0) {
|
|
1985
|
-
return { status: "unverified", reason: "type-mismatch" };
|
|
1986
|
-
}
|
|
1987
|
-
const ids = distinctIds(typed);
|
|
1988
|
-
if (ids.length > 1) {
|
|
1989
|
-
return { status: "unverified", reason: "ambiguous" };
|
|
1990
|
-
}
|
|
1991
|
-
return { status: "matched", id: ids[0], tier: "fuzzy" };
|
|
1992
|
-
}
|
|
1993
|
-
|
|
1994
2397
|
// src/executor/handlers/uiInteractionHandler.ts
|
|
1995
2398
|
function findSnapshotButton(targetId) {
|
|
1996
2399
|
try {
|
|
@@ -2003,16 +2406,16 @@ function findSnapshotButton(targetId) {
|
|
|
2003
2406
|
}
|
|
2004
2407
|
}
|
|
2005
2408
|
function buildUiDiagnose(targetId, cause) {
|
|
2006
|
-
const activePath =
|
|
2007
|
-
const screen = activePath[activePath.length - 1] ??
|
|
2409
|
+
const activePath = chunkUZ2D4BVX_js.getActiveRouteNames();
|
|
2410
|
+
const screen = activePath[activePath.length - 1] ?? chunkUZ2D4BVX_js.getCurrentScreen() ?? void 0;
|
|
2008
2411
|
const screenPath = activePath.length > 1 ? activePath.join("/") : screen;
|
|
2009
2412
|
const diagnose = {
|
|
2010
2413
|
category: cause === "not-found" ? "component-not-found" : cause === "disabled" ? "disabled" : "unknown",
|
|
2011
2414
|
targetId,
|
|
2012
2415
|
screen: screenPath
|
|
2013
2416
|
};
|
|
2014
|
-
if (
|
|
2015
|
-
diagnose.visibleMessage =
|
|
2417
|
+
if (chunkUZ2D4BVX_js.isOptionalStepAutomationFailure(targetId, screenPath, activePath)) {
|
|
2418
|
+
diagnose.visibleMessage = chunkUZ2D4BVX_js.OPTIONAL_STEP_AUTOMATION_HINT;
|
|
2016
2419
|
diagnose.recoverable = true;
|
|
2017
2420
|
}
|
|
2018
2421
|
return diagnose;
|
|
@@ -2063,6 +2466,7 @@ function stripComponentPrefix(componentId) {
|
|
|
2063
2466
|
return null;
|
|
2064
2467
|
}
|
|
2065
2468
|
function resolveComponentId(componentId, registry, action) {
|
|
2469
|
+
if (chunkUZ2D4BVX_js.isSourceControlId(componentId)) return componentId;
|
|
2066
2470
|
if (registry.getTarget(componentId) || registry.getToggle(componentId) || registry.getField(componentId) || registry.getSlider(componentId)) {
|
|
2067
2471
|
return componentId;
|
|
2068
2472
|
}
|
|
@@ -2070,15 +2474,16 @@ function resolveComponentId(componentId, registry, action) {
|
|
|
2070
2474
|
const snapshot = registry.snapshot();
|
|
2071
2475
|
for (const comp of snapshot) {
|
|
2072
2476
|
if (comp.id.toLowerCase() === lower) {
|
|
2073
|
-
|
|
2477
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
2074
2478
|
`resolveComponentId: case-insensitive match "${componentId}" \u2192 "${comp.id}"`
|
|
2075
2479
|
);
|
|
2076
2480
|
return comp.id;
|
|
2077
2481
|
}
|
|
2078
2482
|
}
|
|
2079
|
-
|
|
2483
|
+
if (isPositionalControlId(componentId)) return componentId;
|
|
2484
|
+
const currentScreen = chunkUZ2D4BVX_js.getCurrentScreen();
|
|
2080
2485
|
if (currentScreen) {
|
|
2081
|
-
const screenMeta =
|
|
2486
|
+
const screenMeta = chunkUZ2D4BVX_js.getScreenMetadata(currentScreen);
|
|
2082
2487
|
const actions = screenMeta?.actions;
|
|
2083
2488
|
if (actions && Array.isArray(actions)) {
|
|
2084
2489
|
const metaAction = actions.find(
|
|
@@ -2087,14 +2492,14 @@ function resolveComponentId(componentId, registry, action) {
|
|
|
2087
2492
|
if (metaAction && typeof metaAction === "object" && metaAction.label) {
|
|
2088
2493
|
const metaLabel = metaAction.label;
|
|
2089
2494
|
const normalizedMetaLabel = metaLabel.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]/g, "");
|
|
2090
|
-
|
|
2495
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
2091
2496
|
`resolveComponentId: found screen metadata for "${componentId}" \u2192 label="${metaLabel}"`
|
|
2092
2497
|
);
|
|
2093
2498
|
for (const comp of snapshot) {
|
|
2094
2499
|
if (!comp.label) continue;
|
|
2095
2500
|
const compLabel = comp.label.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]/g, "");
|
|
2096
2501
|
if (compLabel === normalizedMetaLabel || compLabel.includes(normalizedMetaLabel) || normalizedMetaLabel.includes(compLabel)) {
|
|
2097
|
-
|
|
2502
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
2098
2503
|
`resolveComponentId: FOUND via metadata: "${componentId}" \u2192 "${comp.id}" (label="${comp.label}")`
|
|
2099
2504
|
);
|
|
2100
2505
|
return comp.id;
|
|
@@ -2109,9 +2514,9 @@ function resolveComponentId(componentId, registry, action) {
|
|
|
2109
2514
|
label: c.label,
|
|
2110
2515
|
kind: c.kind
|
|
2111
2516
|
}));
|
|
2112
|
-
const match = resolveTarget(componentId, candidates, { action });
|
|
2517
|
+
const match = chunkUZ2D4BVX_js.resolveTarget(componentId, candidates, { action });
|
|
2113
2518
|
if (match.status === "matched") {
|
|
2114
|
-
|
|
2519
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
2115
2520
|
`resolveComponentId: matched "${componentId}" -> "${match.id}" (tier=${match.tier})`
|
|
2116
2521
|
);
|
|
2117
2522
|
return match.id;
|
|
@@ -2201,7 +2606,7 @@ function setValueHandler(rawComponentId, requested, registry) {
|
|
|
2201
2606
|
try {
|
|
2202
2607
|
slider.setValue(applied);
|
|
2203
2608
|
if (applied !== requestedValue) {
|
|
2204
|
-
|
|
2609
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
2205
2610
|
`uiInteractionHandler: set_value snapped ${requestedValue} \u2192 ${applied} for "${componentId}" (step=${step})`
|
|
2206
2611
|
);
|
|
2207
2612
|
}
|
|
@@ -2236,7 +2641,7 @@ function checkModalOcclusion(rawComponentId, action) {
|
|
|
2236
2641
|
return null;
|
|
2237
2642
|
}
|
|
2238
2643
|
if (typeof rawComponentId !== "string" || rawComponentId.trim().length === 0) return null;
|
|
2239
|
-
const dialog =
|
|
2644
|
+
const dialog = chunkUZ2D4BVX_js.getOpenNativeDialog();
|
|
2240
2645
|
if (dialog) {
|
|
2241
2646
|
const needle = normalizeIdent(rawComponentId);
|
|
2242
2647
|
if (dialog.buttons.some((b) => normalizeIdent(b.label) === needle)) return null;
|
|
@@ -2246,16 +2651,16 @@ function checkModalOcclusion(rawComponentId, action) {
|
|
|
2246
2651
|
diagnose: {
|
|
2247
2652
|
category: "ambiguous-target",
|
|
2248
2653
|
targetId: rawComponentId,
|
|
2249
|
-
screen:
|
|
2654
|
+
screen: chunkUZ2D4BVX_js.getCurrentScreen() ?? void 0,
|
|
2250
2655
|
candidates: dialog.buttons.map((b) => b.label).slice(0, 8)
|
|
2251
2656
|
}
|
|
2252
2657
|
};
|
|
2253
2658
|
}
|
|
2254
|
-
const fiberRoot =
|
|
2659
|
+
const fiberRoot = chunkUZ2D4BVX_js.getFiberRoot();
|
|
2255
2660
|
if (!fiberRoot) return null;
|
|
2256
2661
|
let snap;
|
|
2257
2662
|
try {
|
|
2258
|
-
snap =
|
|
2663
|
+
snap = chunkUZ2D4BVX_js.walkFiber(fiberRoot);
|
|
2259
2664
|
} catch {
|
|
2260
2665
|
return null;
|
|
2261
2666
|
}
|
|
@@ -2317,15 +2722,18 @@ function checkModalOcclusion(rawComponentId, action) {
|
|
|
2317
2722
|
}
|
|
2318
2723
|
function uiInteractionHandler(payload, context) {
|
|
2319
2724
|
const { permissions } = context;
|
|
2320
|
-
const registry = context.registry ??
|
|
2725
|
+
const registry = context.registry ?? chunkUZ2D4BVX_js.componentRegistry;
|
|
2321
2726
|
if (!permissions.canInteractUI) {
|
|
2322
2727
|
return {
|
|
2323
2728
|
success: false,
|
|
2324
|
-
error: "UI interaction
|
|
2325
|
-
diagnose:
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2729
|
+
error: chunkUZ2D4BVX_js.permissionDeniedMessage("UI interaction", "canInteractUI"),
|
|
2730
|
+
diagnose: {
|
|
2731
|
+
...buildUiDiagnose(
|
|
2732
|
+
payload.componentId ?? payload.targetId ?? "",
|
|
2733
|
+
"unknown"
|
|
2734
|
+
),
|
|
2735
|
+
recoverable: false
|
|
2736
|
+
}
|
|
2329
2737
|
};
|
|
2330
2738
|
}
|
|
2331
2739
|
const { action } = payload;
|
|
@@ -2339,7 +2747,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2339
2747
|
if (sliderId) {
|
|
2340
2748
|
const smuggled = payload.value ?? payload.params?.value;
|
|
2341
2749
|
if (smuggled !== void 0) {
|
|
2342
|
-
|
|
2750
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
2343
2751
|
`uiInteractionHandler: "${actionStr}" on slider "${sliderId}" carried value=${JSON.stringify(smuggled)} \u2014 routing to set_value`
|
|
2344
2752
|
);
|
|
2345
2753
|
return setValueHandler(rawComponentId, smuggled, registry);
|
|
@@ -2350,23 +2758,23 @@ function uiInteractionHandler(payload, context) {
|
|
|
2350
2758
|
diagnose: { ...buildUiDiagnose(sliderId, "unknown"), recoverable: true }
|
|
2351
2759
|
};
|
|
2352
2760
|
}
|
|
2353
|
-
const openDialog =
|
|
2761
|
+
const openDialog = chunkUZ2D4BVX_js.getOpenNativeDialog();
|
|
2354
2762
|
const isPressVerb = actionStr === "press" || actionStr === "tap" || actionStr === "click";
|
|
2355
2763
|
if (openDialog && isPressVerb) {
|
|
2356
2764
|
const needle = normalizeIdent(rawComponentId);
|
|
2357
2765
|
const button = openDialog.buttons.find((b) => normalizeIdent(b.label) === needle);
|
|
2358
2766
|
if (button) {
|
|
2359
2767
|
button.press();
|
|
2360
|
-
|
|
2768
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(`uiInteractionHandler: pressed native dialog button "${button.label}"`);
|
|
2361
2769
|
return { success: true, effect: "changed" };
|
|
2362
2770
|
}
|
|
2363
2771
|
}
|
|
2364
2772
|
if (!openDialog && isPressVerb) {
|
|
2365
|
-
const answered =
|
|
2773
|
+
const answered = chunkUZ2D4BVX_js.getLastAnsweredNativeDialog();
|
|
2366
2774
|
const needle = normalizeIdent(rawComponentId);
|
|
2367
2775
|
if (answered && needle) {
|
|
2368
2776
|
if (answered.answeredWith && normalizeIdent(answered.answeredWith) === needle) {
|
|
2369
|
-
|
|
2777
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
2370
2778
|
`uiInteractionHandler: native dialog button "${answered.answeredWith}" was already pressed and the dialog is closed \u2014 treating the repeat as done`
|
|
2371
2779
|
);
|
|
2372
2780
|
return { success: true, effect: "completed" };
|
|
@@ -2378,7 +2786,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2378
2786
|
diagnose: {
|
|
2379
2787
|
category: "component-not-found",
|
|
2380
2788
|
targetId: rawComponentId,
|
|
2381
|
-
screen:
|
|
2789
|
+
screen: chunkUZ2D4BVX_js.getCurrentScreen() ?? void 0,
|
|
2382
2790
|
recoverable: false
|
|
2383
2791
|
}
|
|
2384
2792
|
};
|
|
@@ -2387,7 +2795,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2387
2795
|
}
|
|
2388
2796
|
const occluded = checkModalOcclusion(rawComponentId, actionStr);
|
|
2389
2797
|
if (occluded) {
|
|
2390
|
-
|
|
2798
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
2391
2799
|
`uiInteractionHandler: blocked "${actionStr}" on "${rawComponentId}" \u2014 target is behind an open modal`
|
|
2392
2800
|
);
|
|
2393
2801
|
return occluded;
|
|
@@ -2395,7 +2803,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2395
2803
|
if (typeof rawComponentId === "string" && rawComponentId.trim().toLowerCase().startsWith("el:")) {
|
|
2396
2804
|
const result = dispatchElementOrTarget(rawComponentId, registry, actionStr);
|
|
2397
2805
|
if (result.success) {
|
|
2398
|
-
|
|
2806
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
2399
2807
|
`uiInteractionHandler: interaction element dispatch succeeded for "${rawComponentId}"`
|
|
2400
2808
|
);
|
|
2401
2809
|
}
|
|
@@ -2403,17 +2811,17 @@ function uiInteractionHandler(payload, context) {
|
|
|
2403
2811
|
}
|
|
2404
2812
|
const ordinal = parseSyntheticListItemId(rawComponentId);
|
|
2405
2813
|
if (ordinal && (action === "press" || actionStr === "tap" || actionStr === "click" || actionStr === "longPress")) {
|
|
2406
|
-
|
|
2814
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
2407
2815
|
`uiInteractionHandler: dispatching synthetic list ordinal \u2014 componentId="${rawComponentId}" list=${ordinal.listIndex} item=${ordinal.itemIndex}`
|
|
2408
2816
|
);
|
|
2409
2817
|
const result = pressListItemAtOrdinal(ordinal.listIndex, ordinal.itemIndex);
|
|
2410
2818
|
if (result.ok) {
|
|
2411
|
-
|
|
2819
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
2412
2820
|
`uiInteractionHandler: synthetic ordinal press succeeded (container=${result.containerType ?? "List"})`
|
|
2413
2821
|
);
|
|
2414
2822
|
return { success: true };
|
|
2415
2823
|
}
|
|
2416
|
-
const screen =
|
|
2824
|
+
const screen = chunkUZ2D4BVX_js.getCurrentScreen() ?? void 0;
|
|
2417
2825
|
if (result.reason === "list-not-found" || result.reason === "item-not-found") {
|
|
2418
2826
|
return {
|
|
2419
2827
|
success: false,
|
|
@@ -2454,7 +2862,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2454
2862
|
};
|
|
2455
2863
|
}
|
|
2456
2864
|
const componentId = resolveComponentId(rawComponentId, registry, actionStr);
|
|
2457
|
-
|
|
2865
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
2458
2866
|
`uiInteractionHandler: resolved componentId="${payload.componentId}" \u2192 "${componentId}"`
|
|
2459
2867
|
);
|
|
2460
2868
|
const target = registry.getTarget(componentId);
|
|
@@ -2507,7 +2915,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2507
2915
|
return { success: false, error: err?.message ?? "Focus failed" };
|
|
2508
2916
|
}
|
|
2509
2917
|
}
|
|
2510
|
-
|
|
2918
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
2511
2919
|
`uiInteractionHandler: registry miss for "${componentId}", falling back to fiber tree`
|
|
2512
2920
|
);
|
|
2513
2921
|
const namedToggle = dispatchIdentifiedToggle(componentId, actionStr);
|
|
@@ -2519,7 +2927,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2519
2927
|
try {
|
|
2520
2928
|
if (actionStr === "press" && handle.kind === "target" && handle.press) {
|
|
2521
2929
|
handle.press();
|
|
2522
|
-
|
|
2930
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
2523
2931
|
`uiInteractionHandler: fiber fallback press succeeded for "${componentId}"`
|
|
2524
2932
|
);
|
|
2525
2933
|
return { success: true };
|
|
@@ -2555,6 +2963,28 @@ function uiInteractionHandler(payload, context) {
|
|
|
2555
2963
|
};
|
|
2556
2964
|
}
|
|
2557
2965
|
|
|
2966
|
+
// src/executor/completeTextEdit.ts
|
|
2967
|
+
var sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
2968
|
+
async function completeTextEdit(fieldId, expected, registered, origin, resolveRegistered) {
|
|
2969
|
+
await sleep2(80);
|
|
2970
|
+
const current2 = findInteractiveByIdentifier(fieldId, { kind: "field" });
|
|
2971
|
+
if (origin?.controlIdentity && current2?.controlIdentity !== origin.controlIdentity) return false;
|
|
2972
|
+
if (registered && resolveRegistered && resolveRegistered() !== registered) return false;
|
|
2973
|
+
if (registered?.finishEditing) registered.finishEditing();
|
|
2974
|
+
else if (current2 && (current2.matchCount ?? 1) === 1 && !current2.disabled)
|
|
2975
|
+
current2.finishEditing?.();
|
|
2976
|
+
const started = Date.now();
|
|
2977
|
+
do {
|
|
2978
|
+
await sleep2(80);
|
|
2979
|
+
const live = findInteractiveByIdentifier(fieldId, { kind: "field" });
|
|
2980
|
+
if (origin?.controlIdentity && live?.controlIdentity !== origin.controlIdentity) return false;
|
|
2981
|
+
if (registered && resolveRegistered && resolveRegistered() !== registered) return false;
|
|
2982
|
+
const value = registered ? registered.getValue() : live?.getValue?.();
|
|
2983
|
+
if (value !== void 0 && value !== null && String(value) === String(expected)) return true;
|
|
2984
|
+
} while (Date.now() - started < 480);
|
|
2985
|
+
return false;
|
|
2986
|
+
}
|
|
2987
|
+
|
|
2558
2988
|
// src/executor/formSubmitResolve.ts
|
|
2559
2989
|
var SUBMIT_LABEL_HINT_RE = /\b(submit|save|send|continue|next|sign\s*in|log\s*in|register|salvar|enviar|entrar|cadastrar|continuar|proximo|próximo|avancar|avançar|confirmar|guardar|registrarse|iniciar\s+sesi[óo]n|enregistrer|envoyer|valider|soumettre|confirmer|se\s+connecter|s['e]\s*inscrire)\b/i;
|
|
2560
2990
|
var AGENT_CHROME_TARGET_RE = /\b(fechar|close|dismiss|cancelar|cancel|limpar|clear|chat\s+do\s+assistente|assistant\s+chat)\b/i;
|
|
@@ -2582,7 +3012,7 @@ function submitLabelHintsSubmit(label) {
|
|
|
2582
3012
|
return SUBMIT_LABEL_HINT_RE.test(trimmed);
|
|
2583
3013
|
}
|
|
2584
3014
|
function screenDeclaresSubmitAction(screenName) {
|
|
2585
|
-
const meta =
|
|
3015
|
+
const meta = chunkUZ2D4BVX_js.getScreenMetadata(screenName);
|
|
2586
3016
|
return Array.isArray(meta?.actions) && meta.actions.some(
|
|
2587
3017
|
(action) => typeof action === "object" && action !== null && action.type === "submit"
|
|
2588
3018
|
);
|
|
@@ -2615,7 +3045,7 @@ function resolveFormScreensForSubmit(screen, activePath, registry) {
|
|
|
2615
3045
|
} else {
|
|
2616
3046
|
push(screen);
|
|
2617
3047
|
}
|
|
2618
|
-
push(
|
|
3048
|
+
push(chunkUZ2D4BVX_js.getCurrentScreen() ?? void 0);
|
|
2619
3049
|
const withSubmit = [];
|
|
2620
3050
|
const rest = [];
|
|
2621
3051
|
for (const name of ordered) {
|
|
@@ -2633,7 +3063,7 @@ function collectSubmitTargetCandidates(screens, registry) {
|
|
|
2633
3063
|
candidates.push(id);
|
|
2634
3064
|
};
|
|
2635
3065
|
for (const screenName of screens) {
|
|
2636
|
-
const meta =
|
|
3066
|
+
const meta = chunkUZ2D4BVX_js.getScreenMetadata(screenName);
|
|
2637
3067
|
const submitMeta = Array.isArray(meta?.actions) ? meta.actions.find(
|
|
2638
3068
|
(action) => typeof action === "object" && action !== null && action.type === "submit"
|
|
2639
3069
|
) : void 0;
|
|
@@ -2677,8 +3107,8 @@ function readVisibleValidation(fieldId, label) {
|
|
|
2677
3107
|
return void 0;
|
|
2678
3108
|
}
|
|
2679
3109
|
function resolveScreenContext() {
|
|
2680
|
-
const activePath =
|
|
2681
|
-
const screen = activePath[activePath.length - 1] ??
|
|
3110
|
+
const activePath = chunkUZ2D4BVX_js.getActiveRouteNames();
|
|
3111
|
+
const screen = activePath[activePath.length - 1] ?? chunkUZ2D4BVX_js.getCurrentScreen() ?? void 0;
|
|
2682
3112
|
return { screen, activePath };
|
|
2683
3113
|
}
|
|
2684
3114
|
function selectValueApplied(fieldId, requestedValue, currentValue, registry) {
|
|
@@ -2686,36 +3116,36 @@ function selectValueApplied(fieldId, requestedValue, currentValue, registry) {
|
|
|
2686
3116
|
if (!requested) return false;
|
|
2687
3117
|
const meta = getMetadataField(fieldId, registry);
|
|
2688
3118
|
const options = Array.isArray(meta?.options) ? meta.options : [];
|
|
2689
|
-
const requestedNorm =
|
|
2690
|
-
const currentNorm =
|
|
3119
|
+
const requestedNorm = chunkUZ2D4BVX_js.normalize3(requested);
|
|
3120
|
+
const currentNorm = chunkUZ2D4BVX_js.normalize3(currentValue);
|
|
2691
3121
|
if (currentNorm === requestedNorm) return true;
|
|
2692
3122
|
for (const option of options) {
|
|
2693
3123
|
const value = typeof option?.value === "string" ? option.value : "";
|
|
2694
3124
|
const label = typeof option?.label === "string" ? option.label : "";
|
|
2695
|
-
if (
|
|
2696
|
-
if (
|
|
2697
|
-
if (
|
|
3125
|
+
if (chunkUZ2D4BVX_js.normalize3(value) === requestedNorm && chunkUZ2D4BVX_js.normalize3(label) === currentNorm) return true;
|
|
3126
|
+
if (chunkUZ2D4BVX_js.normalize3(label) === requestedNorm && chunkUZ2D4BVX_js.normalize3(label) === currentNorm) return true;
|
|
3127
|
+
if (chunkUZ2D4BVX_js.normalize3(value) === requestedNorm && chunkUZ2D4BVX_js.normalize3(value) === currentNorm) return true;
|
|
2698
3128
|
}
|
|
2699
3129
|
return false;
|
|
2700
3130
|
}
|
|
2701
3131
|
function getMetadataField(fieldId, registry) {
|
|
2702
3132
|
const screens = /* @__PURE__ */ new Set();
|
|
2703
|
-
for (const name of
|
|
2704
|
-
const
|
|
2705
|
-
if (
|
|
3133
|
+
for (const name of chunkUZ2D4BVX_js.getActiveRouteNames()) screens.add(name);
|
|
3134
|
+
const current2 = chunkUZ2D4BVX_js.getCurrentScreen();
|
|
3135
|
+
if (current2) screens.add(current2);
|
|
2706
3136
|
if (registry) {
|
|
2707
3137
|
for (const comp of registry.snapshot()) {
|
|
2708
3138
|
if (comp.kind === "field" && comp.screen) screens.add(comp.screen);
|
|
2709
3139
|
}
|
|
2710
3140
|
}
|
|
2711
|
-
const needle =
|
|
3141
|
+
const needle = chunkUZ2D4BVX_js.normalize3(fieldId);
|
|
2712
3142
|
for (const screenName of screens) {
|
|
2713
|
-
const screenMeta =
|
|
3143
|
+
const screenMeta = chunkUZ2D4BVX_js.getScreenMetadata(screenName);
|
|
2714
3144
|
const fields = Array.isArray(screenMeta?.fields) ? screenMeta.fields : [];
|
|
2715
3145
|
const match = fields.find((field) => {
|
|
2716
3146
|
if (!field || typeof field !== "object") return false;
|
|
2717
|
-
const id = typeof field.id === "string" ?
|
|
2718
|
-
const label = typeof field.label === "string" ?
|
|
3147
|
+
const id = typeof field.id === "string" ? chunkUZ2D4BVX_js.normalize3(field.id) : "";
|
|
3148
|
+
const label = typeof field.label === "string" ? chunkUZ2D4BVX_js.normalize3(field.label) : "";
|
|
2719
3149
|
return id === needle || label === needle;
|
|
2720
3150
|
});
|
|
2721
3151
|
if (match) return match;
|
|
@@ -2727,11 +3157,11 @@ function resolveSelectOption(fieldId, value, registry) {
|
|
|
2727
3157
|
if (!requested) return void 0;
|
|
2728
3158
|
const meta = getMetadataField(fieldId, registry);
|
|
2729
3159
|
const options = Array.isArray(meta?.options) ? meta.options : [];
|
|
2730
|
-
const requestedNorm =
|
|
3160
|
+
const requestedNorm = chunkUZ2D4BVX_js.normalize3(requested);
|
|
2731
3161
|
for (const option of options) {
|
|
2732
3162
|
const optionValue = typeof option?.value === "string" ? option.value : "";
|
|
2733
3163
|
const optionLabel = typeof option?.label === "string" ? option.label : "";
|
|
2734
|
-
if (
|
|
3164
|
+
if (chunkUZ2D4BVX_js.normalize3(optionValue) === requestedNorm || chunkUZ2D4BVX_js.normalize3(optionLabel) === requestedNorm) {
|
|
2735
3165
|
return { value: optionValue, label: optionLabel };
|
|
2736
3166
|
}
|
|
2737
3167
|
}
|
|
@@ -2743,7 +3173,7 @@ async function tryOpenSelectModal(fieldId, registry) {
|
|
|
2743
3173
|
if (!target) continue;
|
|
2744
3174
|
try {
|
|
2745
3175
|
target.press();
|
|
2746
|
-
await
|
|
3176
|
+
await sleep3(180);
|
|
2747
3177
|
return true;
|
|
2748
3178
|
} catch {
|
|
2749
3179
|
}
|
|
@@ -2781,12 +3211,12 @@ async function tryPressSelectOption(fieldId, value, registry, options = {}) {
|
|
|
2781
3211
|
return {
|
|
2782
3212
|
success: false,
|
|
2783
3213
|
error: `No pressable option found for select field "${fieldId}"`,
|
|
2784
|
-
diagnose: { category: "component-not-found", fieldId, screen:
|
|
3214
|
+
diagnose: { category: "component-not-found", fieldId, screen: chunkUZ2D4BVX_js.getCurrentScreen() ?? void 0 }
|
|
2785
3215
|
};
|
|
2786
3216
|
}
|
|
2787
3217
|
function normalizeFieldType(type) {
|
|
2788
3218
|
if (typeof type !== "string") return void 0;
|
|
2789
|
-
const normalized =
|
|
3219
|
+
const normalized = chunkUZ2D4BVX_js.normalize3(type);
|
|
2790
3220
|
if (normalized === "select" || normalized === "picker" || normalized === "dropdown")
|
|
2791
3221
|
return "select";
|
|
2792
3222
|
if (normalized === "toggle" || normalized === "switch" || normalized === "checkbox")
|
|
@@ -2816,7 +3246,7 @@ function fieldCueTerms(fieldId, label) {
|
|
|
2816
3246
|
);
|
|
2817
3247
|
const terms = /* @__PURE__ */ new Set();
|
|
2818
3248
|
for (const value of raw) {
|
|
2819
|
-
const normalized =
|
|
3249
|
+
const normalized = chunkUZ2D4BVX_js.normalize3(value);
|
|
2820
3250
|
if (normalized.length >= 3 && normalized !== "id") terms.add(normalized);
|
|
2821
3251
|
}
|
|
2822
3252
|
return [...terms];
|
|
@@ -2824,17 +3254,17 @@ function fieldCueTerms(fieldId, label) {
|
|
|
2824
3254
|
function snapshotHasFieldCue(snap, fieldId, label) {
|
|
2825
3255
|
const terms = fieldCueTerms(fieldId, label);
|
|
2826
3256
|
if (terms.length === 0) return false;
|
|
2827
|
-
const visible = [...snap.texts ?? [], ...(snap.buttons ?? []).map((b) => b.label ?? b.id ?? "")].map((text) =>
|
|
3257
|
+
const visible = [...snap.texts ?? [], ...(snap.buttons ?? []).map((b) => b.label ?? b.id ?? "")].map((text) => chunkUZ2D4BVX_js.normalize3(text)).filter(Boolean);
|
|
2828
3258
|
return visible.some((text) => terms.some((term) => text.includes(term) || term.includes(text)));
|
|
2829
3259
|
}
|
|
2830
3260
|
function scoreCandidateText(value, texts) {
|
|
2831
|
-
const valueNorm =
|
|
3261
|
+
const valueNorm = chunkUZ2D4BVX_js.normalize3(String(value ?? ""));
|
|
2832
3262
|
if (!valueNorm) return 0;
|
|
2833
3263
|
let best = 0;
|
|
2834
3264
|
for (const text of texts) {
|
|
2835
|
-
const textNorm =
|
|
3265
|
+
const textNorm = chunkUZ2D4BVX_js.normalize3(text);
|
|
2836
3266
|
if (!textNorm) continue;
|
|
2837
|
-
best = Math.max(best,
|
|
3267
|
+
best = Math.max(best, chunkUZ2D4BVX_js.matchScore(valueNorm, textNorm));
|
|
2838
3268
|
}
|
|
2839
3269
|
return best;
|
|
2840
3270
|
}
|
|
@@ -2848,7 +3278,7 @@ function optionTexts(option) {
|
|
|
2848
3278
|
function buildChoiceCandidates(snap, fieldId, value, allowFirstVisibleWhenNoCue, registry) {
|
|
2849
3279
|
const fieldLabel = getFieldLabel(fieldId, registry);
|
|
2850
3280
|
const fieldCueVisible = snapshotHasFieldCue(snap, fieldId, fieldLabel);
|
|
2851
|
-
const genericValue =
|
|
3281
|
+
const genericValue = chunkUZ2D4BVX_js.isGenericSelectValue(value);
|
|
2852
3282
|
const candidates = [];
|
|
2853
3283
|
let order = 0;
|
|
2854
3284
|
const choiceGroups = snap.choiceGroups ?? [];
|
|
@@ -2860,7 +3290,7 @@ function buildChoiceCandidates(snap, fieldId, value, allowFirstVisibleWhenNoCue,
|
|
|
2860
3290
|
const groupCueScore = Math.max(
|
|
2861
3291
|
globalCueScore,
|
|
2862
3292
|
...groupTexts.map((text) => {
|
|
2863
|
-
const normalized =
|
|
3293
|
+
const normalized = chunkUZ2D4BVX_js.normalize3(text);
|
|
2864
3294
|
return fieldCueTerms(fieldId, fieldLabel).some(
|
|
2865
3295
|
(term) => normalized.includes(term) || term.includes(normalized)
|
|
2866
3296
|
) ? 80 : 0;
|
|
@@ -2897,7 +3327,7 @@ function buildChoiceCandidates(snap, fieldId, value, allowFirstVisibleWhenNoCue,
|
|
|
2897
3327
|
const elementCueScore = Math.max(
|
|
2898
3328
|
fieldCueVisible && elements.length <= 12 ? 50 : 0,
|
|
2899
3329
|
...cueTexts.map((text) => {
|
|
2900
|
-
const normalized =
|
|
3330
|
+
const normalized = chunkUZ2D4BVX_js.normalize3(text);
|
|
2901
3331
|
return fieldTerms.some((term) => normalized.includes(term) || term.includes(normalized)) ? 80 : 0;
|
|
2902
3332
|
})
|
|
2903
3333
|
);
|
|
@@ -2955,7 +3385,7 @@ async function selectVisibleChoiceAsync(fieldId, value, registry, options) {
|
|
|
2955
3385
|
return {
|
|
2956
3386
|
success: false,
|
|
2957
3387
|
error: err?.message ?? "Could not capture visible choices",
|
|
2958
|
-
diagnose: { category: "unknown", fieldId, screen:
|
|
3388
|
+
diagnose: { category: "unknown", fieldId, screen: chunkUZ2D4BVX_js.getCurrentScreen() ?? void 0 }
|
|
2959
3389
|
};
|
|
2960
3390
|
}
|
|
2961
3391
|
const candidates = buildChoiceCandidates(
|
|
@@ -2973,7 +3403,7 @@ async function selectVisibleChoiceAsync(fieldId, value, registry, options) {
|
|
|
2973
3403
|
diagnose: {
|
|
2974
3404
|
category: "component-not-found",
|
|
2975
3405
|
fieldId,
|
|
2976
|
-
screen:
|
|
3406
|
+
screen: chunkUZ2D4BVX_js.getCurrentScreen() ?? void 0
|
|
2977
3407
|
}
|
|
2978
3408
|
};
|
|
2979
3409
|
}
|
|
@@ -2987,7 +3417,7 @@ async function selectVisibleChoiceAsync(fieldId, value, registry, options) {
|
|
|
2987
3417
|
}
|
|
2988
3418
|
function isContinuationButton(label) {
|
|
2989
3419
|
if (!label) return false;
|
|
2990
|
-
return /^(next|continue|proximo|prox|continuar|avancar|avançar)$/i.test(
|
|
3420
|
+
return /^(next|continue|proximo|prox|continuar|avancar|avançar)$/i.test(chunkUZ2D4BVX_js.normalize3(label));
|
|
2991
3421
|
}
|
|
2992
3422
|
function pressContinuationButton(registry) {
|
|
2993
3423
|
const snap = captureSnapshot();
|
|
@@ -3000,40 +3430,40 @@ function pressContinuationButton(registry) {
|
|
|
3000
3430
|
return {
|
|
3001
3431
|
success: false,
|
|
3002
3432
|
error: "No enabled continuation button is visible",
|
|
3003
|
-
diagnose: { category: "component-not-found", screen:
|
|
3433
|
+
diagnose: { category: "component-not-found", screen: chunkUZ2D4BVX_js.getCurrentScreen() ?? void 0 }
|
|
3004
3434
|
};
|
|
3005
3435
|
}
|
|
3006
3436
|
return pressTargetByIdOrLabel(id, registry);
|
|
3007
3437
|
}
|
|
3008
3438
|
function findField(fieldId, registry) {
|
|
3009
|
-
|
|
3439
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(`findField: searching for fieldId="${fieldId}"`);
|
|
3010
3440
|
const exact = registry.getField(fieldId);
|
|
3011
3441
|
if (exact) {
|
|
3012
|
-
|
|
3442
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(`findField: FOUND exact match for fieldId="${fieldId}"`);
|
|
3013
3443
|
return exact;
|
|
3014
3444
|
}
|
|
3015
3445
|
const lower = fieldId.toLowerCase();
|
|
3016
3446
|
const snapshot = registry.snapshot();
|
|
3017
3447
|
for (const comp of snapshot) {
|
|
3018
3448
|
if (comp.kind === "field" && comp.id.toLowerCase() === lower) {
|
|
3019
|
-
|
|
3449
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
3020
3450
|
`findField: FOUND case-insensitive match: registered="${comp.id}" for searched="${fieldId}"`
|
|
3021
3451
|
);
|
|
3022
3452
|
return registry.getField(comp.id);
|
|
3023
3453
|
}
|
|
3024
3454
|
}
|
|
3025
|
-
const currentScreenForTieBreak =
|
|
3026
|
-
const needle =
|
|
3455
|
+
const currentScreenForTieBreak = chunkUZ2D4BVX_js.getCurrentScreen();
|
|
3456
|
+
const needle = chunkUZ2D4BVX_js.normalize3(fieldId);
|
|
3027
3457
|
let bestComp;
|
|
3028
3458
|
let bestScore = 0;
|
|
3029
3459
|
let bestOnCurrentScreen = false;
|
|
3030
3460
|
for (const comp of snapshot) {
|
|
3031
3461
|
if (comp.kind !== "field") continue;
|
|
3032
|
-
const candidates = [
|
|
3033
|
-
if (comp.label) candidates.push(
|
|
3462
|
+
const candidates = [chunkUZ2D4BVX_js.normalize3(comp.id)];
|
|
3463
|
+
if (comp.label) candidates.push(chunkUZ2D4BVX_js.normalize3(comp.label));
|
|
3034
3464
|
let candidateScore = 0;
|
|
3035
3465
|
for (const cand of candidates) {
|
|
3036
|
-
const s =
|
|
3466
|
+
const s = chunkUZ2D4BVX_js.matchScore(needle, cand);
|
|
3037
3467
|
if (s > candidateScore) candidateScore = s;
|
|
3038
3468
|
}
|
|
3039
3469
|
if (candidateScore === 0) continue;
|
|
@@ -3046,14 +3476,14 @@ function findField(fieldId, registry) {
|
|
|
3046
3476
|
}
|
|
3047
3477
|
}
|
|
3048
3478
|
if (bestComp && bestScore >= 75) {
|
|
3049
|
-
|
|
3479
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
3050
3480
|
`findField: scored match "${fieldId}" -> "${bestComp.id}" (label="${bestComp.label}", score=${bestScore})`
|
|
3051
3481
|
);
|
|
3052
3482
|
return registry.getField(bestComp.id);
|
|
3053
3483
|
}
|
|
3054
|
-
const currentScreen =
|
|
3484
|
+
const currentScreen = chunkUZ2D4BVX_js.getCurrentScreen();
|
|
3055
3485
|
if (currentScreen) {
|
|
3056
|
-
const screenMeta =
|
|
3486
|
+
const screenMeta = chunkUZ2D4BVX_js.getScreenMetadata(currentScreen);
|
|
3057
3487
|
const fields = screenMeta?.fields;
|
|
3058
3488
|
if (fields && Array.isArray(fields)) {
|
|
3059
3489
|
const metaField = fields.find(
|
|
@@ -3061,19 +3491,19 @@ function findField(fieldId, registry) {
|
|
|
3061
3491
|
);
|
|
3062
3492
|
if (metaField && typeof metaField === "object" && metaField.label) {
|
|
3063
3493
|
const metaLabel = metaField.label;
|
|
3064
|
-
const metaNeedle =
|
|
3494
|
+
const metaNeedle = chunkUZ2D4BVX_js.normalize3(metaLabel);
|
|
3065
3495
|
let mBest;
|
|
3066
3496
|
let mBestScore = 0;
|
|
3067
3497
|
for (const comp of snapshot) {
|
|
3068
3498
|
if (comp.kind !== "field" || !comp.label) continue;
|
|
3069
|
-
const score =
|
|
3499
|
+
const score = chunkUZ2D4BVX_js.matchScore(metaNeedle, chunkUZ2D4BVX_js.normalize3(comp.label));
|
|
3070
3500
|
if (score > mBestScore) {
|
|
3071
3501
|
mBestScore = score;
|
|
3072
3502
|
mBest = comp;
|
|
3073
3503
|
}
|
|
3074
3504
|
}
|
|
3075
3505
|
if (mBest && mBestScore >= 60) {
|
|
3076
|
-
|
|
3506
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
3077
3507
|
`findField: FOUND via screen metadata translation: fieldId="${fieldId}" -> metaLabel="${metaLabel}" -> registered="${mBest.id}" (score=${mBestScore})`
|
|
3078
3508
|
);
|
|
3079
3509
|
return registry.getField(mBest.id);
|
|
@@ -3082,34 +3512,34 @@ function findField(fieldId, registry) {
|
|
|
3082
3512
|
}
|
|
3083
3513
|
}
|
|
3084
3514
|
if (bestComp && bestScore >= 40) {
|
|
3085
|
-
|
|
3515
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
3086
3516
|
`findField: weak substring match "${fieldId}" -> "${bestComp.id}" (label="${bestComp.label}", score=${bestScore})`
|
|
3087
3517
|
);
|
|
3088
3518
|
return registry.getField(bestComp.id);
|
|
3089
3519
|
}
|
|
3090
|
-
|
|
3520
|
+
chunkUZ2D4BVX_js.appilotsDebugWarn(
|
|
3091
3521
|
`findField: NOT FOUND \u2014 fieldId="${fieldId}" not in registry. Available fields: ${snapshot.filter((c) => c.kind === "field").map((c) => `"${c.id}" (label: ${c.label})`).join(", ") || "none"}`
|
|
3092
3522
|
);
|
|
3093
3523
|
return void 0;
|
|
3094
3524
|
}
|
|
3095
3525
|
function findToggle(fieldId, registry) {
|
|
3096
|
-
|
|
3526
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(`findToggle: searching for fieldId="${fieldId}"`);
|
|
3097
3527
|
const exact = registry.getToggle(fieldId);
|
|
3098
3528
|
if (exact) {
|
|
3099
|
-
|
|
3529
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(`findToggle: FOUND exact match for "${fieldId}"`);
|
|
3100
3530
|
return exact;
|
|
3101
3531
|
}
|
|
3102
3532
|
const lower = fieldId.toLowerCase();
|
|
3103
3533
|
const snapshot = registry.snapshot();
|
|
3104
3534
|
for (const comp of snapshot) {
|
|
3105
3535
|
if (comp.kind === "toggle" && comp.id.toLowerCase() === lower) {
|
|
3106
|
-
|
|
3536
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
3107
3537
|
`findToggle: FOUND case-insensitive match: registered="${comp.id}" for searched="${fieldId}"`
|
|
3108
3538
|
);
|
|
3109
3539
|
return registry.getToggle(comp.id);
|
|
3110
3540
|
}
|
|
3111
3541
|
}
|
|
3112
|
-
|
|
3542
|
+
chunkUZ2D4BVX_js.appilotsDebugWarn(
|
|
3113
3543
|
`findToggle: NOT FOUND \u2014 fieldId="${fieldId}" not in registry. Available toggles: ${snapshot.filter((c) => c.kind === "toggle").map((c) => `"${c.id}"`).join(", ") || "none"}`
|
|
3114
3544
|
);
|
|
3115
3545
|
return void 0;
|
|
@@ -3120,7 +3550,7 @@ function findSlider(fieldId, registry) {
|
|
|
3120
3550
|
const lower = fieldId.toLowerCase();
|
|
3121
3551
|
for (const comp of registry.snapshot()) {
|
|
3122
3552
|
if (comp.kind === "slider" && comp.id.toLowerCase() === lower) {
|
|
3123
|
-
|
|
3553
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
3124
3554
|
`findSlider: FOUND case-insensitive match: registered="${comp.id}" for searched="${fieldId}"`
|
|
3125
3555
|
);
|
|
3126
3556
|
return registry.getSlider(comp.id);
|
|
@@ -3128,17 +3558,17 @@ function findSlider(fieldId, registry) {
|
|
|
3128
3558
|
}
|
|
3129
3559
|
return void 0;
|
|
3130
3560
|
}
|
|
3131
|
-
var
|
|
3561
|
+
var sleep3 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
3132
3562
|
async function formFillHandler(payload, context) {
|
|
3133
3563
|
const { permissions } = context;
|
|
3134
|
-
const registry = context.registry ??
|
|
3564
|
+
const registry = context.registry ?? chunkUZ2D4BVX_js.componentRegistry;
|
|
3135
3565
|
const { screen, activePath } = resolveScreenContext();
|
|
3136
3566
|
const screenPath = activePath.length > 1 ? activePath.join("/") : screen;
|
|
3137
3567
|
if (!permissions.canFillForms) {
|
|
3138
3568
|
return {
|
|
3139
3569
|
success: false,
|
|
3140
|
-
error: "Form filling
|
|
3141
|
-
diagnose: { category: "unknown", screen: screenPath }
|
|
3570
|
+
error: chunkUZ2D4BVX_js.permissionDeniedMessage("Form filling", "canFillForms"),
|
|
3571
|
+
diagnose: { category: "unknown", screen: screenPath, recoverable: false }
|
|
3142
3572
|
};
|
|
3143
3573
|
}
|
|
3144
3574
|
if (!payload.fields || payload.fields.length === 0) {
|
|
@@ -3150,11 +3580,11 @@ async function formFillHandler(payload, context) {
|
|
|
3150
3580
|
}
|
|
3151
3581
|
const registrySnapshot = registry.snapshot();
|
|
3152
3582
|
if (registrySnapshot.length === 0) {
|
|
3153
|
-
|
|
3583
|
+
chunkUZ2D4BVX_js.appilotsDebugWarn(
|
|
3154
3584
|
"formFillHandler: registry is EMPTY \u2014 auto-tracking may not be active. Ensure enableAppilotsAutoTracking() runs before components mount."
|
|
3155
3585
|
);
|
|
3156
3586
|
} else {
|
|
3157
|
-
|
|
3587
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
3158
3588
|
`[Appilots formFillHandler] Registry has ${registrySnapshot.length} components:`,
|
|
3159
3589
|
registrySnapshot.map((c) => `${c.kind}:${c.id}`).join(", ")
|
|
3160
3590
|
);
|
|
@@ -3162,7 +3592,7 @@ async function formFillHandler(payload, context) {
|
|
|
3162
3592
|
const fieldResults = [];
|
|
3163
3593
|
let allSuccess = true;
|
|
3164
3594
|
let selectedChoiceThisBatch = false;
|
|
3165
|
-
|
|
3595
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(`formFillHandler: processing ${payload.fields.length} fields`);
|
|
3166
3596
|
const availableFieldIds = () => registry.snapshot().filter((comp) => comp.kind === "field").map((comp) => `${comp.id}${comp.label ? ` (${comp.label})` : ""}`).slice(0, 8);
|
|
3167
3597
|
const isElementIdField = (field) => typeof field.fieldId === "string" && field.fieldId.trim().toLowerCase().startsWith("el:");
|
|
3168
3598
|
for (const field of payload.fields.filter(isElementIdField)) {
|
|
@@ -3189,20 +3619,57 @@ async function formFillHandler(payload, context) {
|
|
|
3189
3619
|
const { fieldId, fieldType, value } = field;
|
|
3190
3620
|
const effectiveFieldType = getEffectiveFieldType(fieldId, fieldType, registry);
|
|
3191
3621
|
let selectFailure;
|
|
3192
|
-
|
|
3193
|
-
`formFillHandler: looking up fieldId="${fieldId}" fieldType="${fieldType}" effectiveFieldType="${effectiveFieldType}" value=${
|
|
3622
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
3623
|
+
`formFillHandler: looking up fieldId="${fieldId}" fieldType="${fieldType}" effectiveFieldType="${effectiveFieldType}" value=${chunkUZ2D4BVX_js.describeValue(value)}`
|
|
3194
3624
|
);
|
|
3195
3625
|
const fieldEntry = findField(fieldId, registry);
|
|
3196
3626
|
if (fieldEntry) {
|
|
3197
3627
|
try {
|
|
3198
|
-
|
|
3628
|
+
const nativeField = findInteractiveByIdentifier(fieldId, { kind: "field" });
|
|
3629
|
+
if (nativeField?.disabled || (nativeField?.matchCount ?? 1) > 1) {
|
|
3630
|
+
fieldResults.push({
|
|
3631
|
+
fieldId,
|
|
3632
|
+
success: false,
|
|
3633
|
+
error: nativeField?.disabled ? "The field is disabled" : "The field identifier matches multiple controls",
|
|
3634
|
+
diagnose: {
|
|
3635
|
+
category: nativeField?.disabled ? "disabled" : "ambiguous-target",
|
|
3636
|
+
fieldId,
|
|
3637
|
+
screen: screenPath
|
|
3638
|
+
}
|
|
3639
|
+
});
|
|
3640
|
+
allSuccess = false;
|
|
3641
|
+
continue;
|
|
3642
|
+
}
|
|
3643
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
3199
3644
|
`formFillHandler: found field "${fieldId}" via registry, calling setValue(<${String(value).length} chars>)`
|
|
3200
3645
|
);
|
|
3201
3646
|
const beforeValue = effectiveFieldType === "date" ? fieldEntry.getValue?.() ?? "" : void 0;
|
|
3202
3647
|
fieldEntry.focus?.();
|
|
3203
3648
|
fieldEntry.setValue(String(value));
|
|
3649
|
+
if (effectiveFieldType === "text" || effectiveFieldType === "number") {
|
|
3650
|
+
if (!await completeTextEdit(
|
|
3651
|
+
fieldId,
|
|
3652
|
+
value,
|
|
3653
|
+
fieldEntry,
|
|
3654
|
+
nativeField,
|
|
3655
|
+
() => findField(fieldId, registry)
|
|
3656
|
+
)) {
|
|
3657
|
+
fieldResults.push({
|
|
3658
|
+
fieldId,
|
|
3659
|
+
success: false,
|
|
3660
|
+
error: "The field did not retain the requested value after editing ended. Inspect its current value before retrying.",
|
|
3661
|
+
diagnose: { category: "validation", fieldId, screen: screenPath }
|
|
3662
|
+
});
|
|
3663
|
+
allSuccess = false;
|
|
3664
|
+
continue;
|
|
3665
|
+
}
|
|
3666
|
+
}
|
|
3204
3667
|
if (effectiveFieldType === "date") {
|
|
3205
|
-
|
|
3668
|
+
let afterValue = fieldEntry.getValue?.() ?? "";
|
|
3669
|
+
if (afterValue === beforeValue) {
|
|
3670
|
+
await sleep3(80);
|
|
3671
|
+
afterValue = fieldEntry.getValue?.() ?? "";
|
|
3672
|
+
}
|
|
3206
3673
|
if (afterValue === beforeValue) {
|
|
3207
3674
|
fieldResults.push({
|
|
3208
3675
|
fieldId,
|
|
@@ -3222,11 +3689,11 @@ async function formFillHandler(payload, context) {
|
|
|
3222
3689
|
if (effectiveFieldType === "select") {
|
|
3223
3690
|
let after = fieldEntry.getValue?.() ?? "";
|
|
3224
3691
|
if (!selectValueApplied(fieldId, value, after, registry)) {
|
|
3225
|
-
await
|
|
3692
|
+
await sleep3(80);
|
|
3226
3693
|
after = fieldEntry.getValue?.() ?? "";
|
|
3227
3694
|
}
|
|
3228
3695
|
if (!selectValueApplied(fieldId, value, after, registry)) {
|
|
3229
|
-
|
|
3696
|
+
chunkUZ2D4BVX_js.appilotsDebugWarn(
|
|
3230
3697
|
`formFillHandler: select field "${fieldId}" setValue did not stick (wrote <${String(value).length} chars>, current is <${String(after ?? "").length} chars>), trying visible choice fallback`
|
|
3231
3698
|
);
|
|
3232
3699
|
const selectResult = await selectVisibleChoice(fieldId, value, registry, {
|
|
@@ -3343,7 +3810,7 @@ async function formFillHandler(payload, context) {
|
|
|
3343
3810
|
if (!selectResult.success && selectedChoiceThisBatch) {
|
|
3344
3811
|
const nextResult = pressContinuationButton(registry);
|
|
3345
3812
|
if (nextResult.success) {
|
|
3346
|
-
await
|
|
3813
|
+
await sleep3(180);
|
|
3347
3814
|
selectResult = await selectVisibleChoice(fieldId, value, registry, {
|
|
3348
3815
|
allowFirstVisibleWhenNoCue: true
|
|
3349
3816
|
});
|
|
@@ -3351,24 +3818,50 @@ async function formFillHandler(payload, context) {
|
|
|
3351
3818
|
}
|
|
3352
3819
|
if (selectResult.success) {
|
|
3353
3820
|
selectedChoiceThisBatch = true;
|
|
3354
|
-
|
|
3821
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
3355
3822
|
`formFillHandler: selected visible option for "${fieldId}"` + (selectResult.selectedLabel ? ` \u2192 "${selectResult.selectedLabel}"` : "")
|
|
3356
3823
|
);
|
|
3357
|
-
await
|
|
3824
|
+
await sleep3(120);
|
|
3358
3825
|
fieldResults.push({ fieldId, success: true });
|
|
3359
3826
|
continue;
|
|
3360
3827
|
}
|
|
3361
3828
|
selectFailure = selectResult;
|
|
3362
3829
|
}
|
|
3363
|
-
|
|
3830
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(`formFillHandler: registry miss for "${fieldId}", falling back to fiber tree`);
|
|
3364
3831
|
const handle = findInteractiveByIdentifier(fieldId, {
|
|
3365
3832
|
kind: effectiveFieldType === "toggle" ? "toggle" : "field"
|
|
3366
3833
|
});
|
|
3367
3834
|
if (handle?.setValue) {
|
|
3368
3835
|
try {
|
|
3836
|
+
if (handle.disabled || (handle.matchCount ?? 1) > 1) {
|
|
3837
|
+
fieldResults.push({
|
|
3838
|
+
fieldId,
|
|
3839
|
+
success: false,
|
|
3840
|
+
error: handle.disabled ? "The field is disabled" : "The field identifier matches multiple controls",
|
|
3841
|
+
diagnose: {
|
|
3842
|
+
category: handle.disabled ? "disabled" : "ambiguous-target",
|
|
3843
|
+
fieldId,
|
|
3844
|
+
screen: screenPath,
|
|
3845
|
+
candidates: handle.matchCandidates
|
|
3846
|
+
}
|
|
3847
|
+
});
|
|
3848
|
+
allSuccess = false;
|
|
3849
|
+
continue;
|
|
3850
|
+
}
|
|
3851
|
+
setSpotlightTarget(handle.measure?.() ?? null, handle.label);
|
|
3369
3852
|
handle.focus?.();
|
|
3370
3853
|
handle.setValue(value);
|
|
3371
|
-
|
|
3854
|
+
if (handle.kind === "field" && !await completeTextEdit(fieldId, value, void 0, handle)) {
|
|
3855
|
+
fieldResults.push({
|
|
3856
|
+
fieldId,
|
|
3857
|
+
success: false,
|
|
3858
|
+
error: "The field did not retain the requested value after editing ended. Inspect its current value before retrying.",
|
|
3859
|
+
diagnose: { category: "validation", fieldId, screen: screenPath }
|
|
3860
|
+
});
|
|
3861
|
+
allSuccess = false;
|
|
3862
|
+
continue;
|
|
3863
|
+
}
|
|
3864
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
3372
3865
|
`formFillHandler: fiber fallback succeeded for "${fieldId}" \u2192 label="${handle.label}"`
|
|
3373
3866
|
);
|
|
3374
3867
|
fieldResults.push({ fieldId, success: true });
|
|
@@ -3415,14 +3908,15 @@ async function formFillHandler(payload, context) {
|
|
|
3415
3908
|
}
|
|
3416
3909
|
if (!allSuccess) {
|
|
3417
3910
|
const failedIds = fieldResults.filter((result) => !result.success).map((result) => result.fieldId);
|
|
3418
|
-
|
|
3911
|
+
chunkUZ2D4BVX_js.appilotsDebugWarn(
|
|
3419
3912
|
"formFillHandler: submitAfterFill=true requested but some fields failed; NOT submitting" + (failedIds.length > 0 ? ` (failed: ${failedIds.join(", ")})` : "")
|
|
3420
3913
|
);
|
|
3421
3914
|
} else {
|
|
3422
|
-
await
|
|
3915
|
+
await sleep3(120);
|
|
3423
3916
|
if (!permissions.canSubmitForms) {
|
|
3424
3917
|
return { success: false, error: "Form submission is not permitted", fieldResults };
|
|
3425
3918
|
}
|
|
3919
|
+
const beforeSubmitTexts = captureSnapshot().texts;
|
|
3426
3920
|
const submitResult = pressSubmitButton(
|
|
3427
3921
|
{
|
|
3428
3922
|
screen,
|
|
@@ -3433,7 +3927,7 @@ async function formFillHandler(payload, context) {
|
|
|
3433
3927
|
registry
|
|
3434
3928
|
);
|
|
3435
3929
|
if (!submitResult.success) {
|
|
3436
|
-
|
|
3930
|
+
chunkUZ2D4BVX_js.appilotsDebugWarn(`formFillHandler: submitAfterFill failed \u2014 ${submitResult.error}`);
|
|
3437
3931
|
return {
|
|
3438
3932
|
success: false,
|
|
3439
3933
|
error: submitResult.error,
|
|
@@ -3442,10 +3936,11 @@ async function formFillHandler(payload, context) {
|
|
|
3442
3936
|
};
|
|
3443
3937
|
}
|
|
3444
3938
|
const postSubmit = await waitForPostSubmitOutcome({
|
|
3445
|
-
submitTargetId: submitResult.pressedTargetId
|
|
3939
|
+
submitTargetId: submitResult.pressedTargetId,
|
|
3940
|
+
beforeTexts: beforeSubmitTexts
|
|
3446
3941
|
});
|
|
3447
3942
|
if (postSubmit.status === "pending") {
|
|
3448
|
-
|
|
3943
|
+
chunkUZ2D4BVX_js.appilotsDebugWarn(`formFillHandler: submit still pending \u2014 ${postSubmit.message}`);
|
|
3449
3944
|
return {
|
|
3450
3945
|
success: false,
|
|
3451
3946
|
error: postSubmit.message,
|
|
@@ -3454,7 +3949,7 @@ async function formFillHandler(payload, context) {
|
|
|
3454
3949
|
};
|
|
3455
3950
|
}
|
|
3456
3951
|
if (postSubmit.status === "failure") {
|
|
3457
|
-
|
|
3952
|
+
chunkUZ2D4BVX_js.appilotsDebugWarn(
|
|
3458
3953
|
`formFillHandler: submit rejected by visible validation \u2014 ${postSubmit.message}`
|
|
3459
3954
|
);
|
|
3460
3955
|
return {
|
|
@@ -3469,7 +3964,10 @@ async function formFillHandler(payload, context) {
|
|
|
3469
3964
|
}
|
|
3470
3965
|
};
|
|
3471
3966
|
}
|
|
3472
|
-
|
|
3967
|
+
if (postSubmit.status === "unverified") {
|
|
3968
|
+
return { success: true, fieldResults, effect: "unknown" };
|
|
3969
|
+
}
|
|
3970
|
+
chunkUZ2D4BVX_js.appilotsDebugLog("formFillHandler: submitAfterFill \u2014 submit completed");
|
|
3473
3971
|
}
|
|
3474
3972
|
}
|
|
3475
3973
|
const aggregatedDiagnose = aggregateFieldDiagnoses(fieldResults, screenPath);
|
|
@@ -3481,17 +3979,17 @@ async function formFillHandler(payload, context) {
|
|
|
3481
3979
|
};
|
|
3482
3980
|
}
|
|
3483
3981
|
function pressSubmitButton(context, registry) {
|
|
3484
|
-
const activePath = context.activePath ??
|
|
3982
|
+
const activePath = context.activePath ?? chunkUZ2D4BVX_js.getActiveRouteNames();
|
|
3485
3983
|
const hintScreen = context.screen ?? context.screenPath;
|
|
3486
3984
|
const formScreens = resolveFormScreensForSubmit(hintScreen, activePath, registry);
|
|
3487
|
-
const resolvedScreen = formScreens.find((name) => screenDeclaresSubmit(name)) ?? formScreens[0] ?? hintScreen ??
|
|
3985
|
+
const resolvedScreen = formScreens.find((name) => screenDeclaresSubmit(name)) ?? formScreens[0] ?? hintScreen ?? chunkUZ2D4BVX_js.getCurrentScreen() ?? void 0;
|
|
3488
3986
|
const candidates = collectSubmitTargetCandidates(formScreens, registry);
|
|
3489
3987
|
for (const candidate of candidates) {
|
|
3490
3988
|
const target = registry.getTarget(candidate);
|
|
3491
3989
|
if (target) {
|
|
3492
3990
|
try {
|
|
3493
3991
|
target.press();
|
|
3494
|
-
|
|
3992
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
3495
3993
|
`formFillHandler: submitAfterFill \u2014 pressed registry target "${candidate}"` + (resolvedScreen ? ` on screen "${resolvedScreen}"` : "")
|
|
3496
3994
|
);
|
|
3497
3995
|
return { success: true, pressedTargetId: candidate };
|
|
@@ -3505,7 +4003,7 @@ function pressSubmitButton(context, registry) {
|
|
|
3505
4003
|
}
|
|
3506
4004
|
}
|
|
3507
4005
|
for (const screenName of formScreens) {
|
|
3508
|
-
const screenMeta =
|
|
4006
|
+
const screenMeta = chunkUZ2D4BVX_js.getScreenMetadata(screenName);
|
|
3509
4007
|
const submitMeta = Array.isArray(screenMeta?.actions) ? screenMeta.actions.find(
|
|
3510
4008
|
(action) => typeof action === "object" && action !== null && action.type === "submit"
|
|
3511
4009
|
) : void 0;
|
|
@@ -3516,7 +4014,7 @@ function pressSubmitButton(context, registry) {
|
|
|
3516
4014
|
if (handle?.press) {
|
|
3517
4015
|
try {
|
|
3518
4016
|
handle.press();
|
|
3519
|
-
|
|
4017
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(`formFillHandler: submitAfterFill \u2014 fiber fallback "${submitLabel}"`);
|
|
3520
4018
|
return { success: true, pressedTargetId: submitId ?? submitLabel };
|
|
3521
4019
|
} catch (err) {
|
|
3522
4020
|
return {
|
|
@@ -3538,7 +4036,7 @@ function pressSubmitButton(context, registry) {
|
|
|
3538
4036
|
if (id) {
|
|
3539
4037
|
const pressed = pressTargetByIdOrLabel(id, registry);
|
|
3540
4038
|
if (pressed.success) {
|
|
3541
|
-
|
|
4039
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(`formFillHandler: submitAfterFill \u2014 pressed visible heuristic "${id}"`);
|
|
3542
4040
|
return { success: true, pressedTargetId: id };
|
|
3543
4041
|
}
|
|
3544
4042
|
}
|
|
@@ -3552,7 +4050,7 @@ function pressSubmitButton(context, registry) {
|
|
|
3552
4050
|
if (target) {
|
|
3553
4051
|
try {
|
|
3554
4052
|
target.press();
|
|
3555
|
-
|
|
4053
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
3556
4054
|
`formFillHandler: submitAfterFill \u2014 pressed by label heuristic "${comp.label}"`
|
|
3557
4055
|
);
|
|
3558
4056
|
return { success: true, pressedTargetId: comp.id };
|
|
@@ -3568,7 +4066,7 @@ function pressSubmitButton(context, registry) {
|
|
|
3568
4066
|
for (const fieldId of [...context.filledFieldIds ?? []].reverse()) {
|
|
3569
4067
|
const handle = findInteractiveByIdentifier(fieldId, { kind: "field" });
|
|
3570
4068
|
if (handle?.submitFromKeyboard?.()) {
|
|
3571
|
-
|
|
4069
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(`formFillHandler: submitAfterFill \u2014 return key on "${fieldId}"`);
|
|
3572
4070
|
return { success: true, pressedTargetId: fieldId };
|
|
3573
4071
|
}
|
|
3574
4072
|
}
|
|
@@ -3606,7 +4104,21 @@ function aggregateFieldDiagnoses(results, screen) {
|
|
|
3606
4104
|
var FALLBACK_PAGE_PX = 600;
|
|
3607
4105
|
var PAGE_FRACTION = 0.85;
|
|
3608
4106
|
var POST_SCROLL_MOUNT_MS = 400;
|
|
3609
|
-
var
|
|
4107
|
+
var PAGINATION_MAX_WAIT_MS = 4e3;
|
|
4108
|
+
var PAGINATION_POLL_MS = 150;
|
|
4109
|
+
var sleep4 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
4110
|
+
async function settleAfterScroll() {
|
|
4111
|
+
await sleep4(POST_SCROLL_MOUNT_MS);
|
|
4112
|
+
if (!chunkUZ2D4BVX_js.probeLoadingState(void 0, chunkUZ2D4BVX_js.getCurrentScreen()).loading) return;
|
|
4113
|
+
const deadline = Date.now() + PAGINATION_MAX_WAIT_MS;
|
|
4114
|
+
while (Date.now() < deadline) {
|
|
4115
|
+
await sleep4(PAGINATION_POLL_MS);
|
|
4116
|
+
if (!chunkUZ2D4BVX_js.probeLoadingState(void 0, chunkUZ2D4BVX_js.getCurrentScreen()).loading) {
|
|
4117
|
+
await sleep4(POST_SCROLL_MOUNT_MS);
|
|
4118
|
+
return;
|
|
4119
|
+
}
|
|
4120
|
+
}
|
|
4121
|
+
}
|
|
3610
4122
|
function normalizeId2(value) {
|
|
3611
4123
|
return String(value ?? "").toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "");
|
|
3612
4124
|
}
|
|
@@ -3614,12 +4126,12 @@ function buildDiagnose(category, targetId, candidates) {
|
|
|
3614
4126
|
return {
|
|
3615
4127
|
category,
|
|
3616
4128
|
targetId,
|
|
3617
|
-
screen:
|
|
4129
|
+
screen: chunkUZ2D4BVX_js.getCurrentScreen() ?? void 0,
|
|
3618
4130
|
...candidates && candidates.length > 0 ? { candidates: candidates.slice(0, 8) } : {}
|
|
3619
4131
|
};
|
|
3620
4132
|
}
|
|
3621
4133
|
function resolveListEntry(listId) {
|
|
3622
|
-
const entries =
|
|
4134
|
+
const entries = chunkUZ2D4BVX_js.listRegistry.snapshot();
|
|
3623
4135
|
if (entries.length === 0) return {};
|
|
3624
4136
|
if (listId) {
|
|
3625
4137
|
const wanted = normalizeId2(listId);
|
|
@@ -3642,13 +4154,26 @@ function pageOffset(metrics, direction) {
|
|
|
3642
4154
|
}
|
|
3643
4155
|
return next;
|
|
3644
4156
|
}
|
|
4157
|
+
async function finishScroll(entry, before) {
|
|
4158
|
+
await settleAfterScroll();
|
|
4159
|
+
const current2 = chunkUZ2D4BVX_js.listRegistry.get(entry.id) ?? entry;
|
|
4160
|
+
const after = current2.getScrollMetrics?.();
|
|
4161
|
+
const grew = typeof entry.itemCount === "number" && typeof current2.itemCount === "number" && current2.itemCount > entry.itemCount;
|
|
4162
|
+
const moved = grew || !!(before && after && (Math.abs(after.offset - before.offset) > 2 || after.contentLength > before.contentLength + 2));
|
|
4163
|
+
const outcome = moved ? "moved" : before && after ? "no-progress" : "unverified";
|
|
4164
|
+
current2.exploration?.recordScroll(outcome);
|
|
4165
|
+
return {
|
|
4166
|
+
success: true,
|
|
4167
|
+
effect: moved ? "changed" : outcome === "no-progress" ? "none" : "unknown"
|
|
4168
|
+
};
|
|
4169
|
+
}
|
|
3645
4170
|
async function scrollListHandler(payload, context) {
|
|
3646
4171
|
const { permissions } = context;
|
|
3647
4172
|
if (!permissions.canInteractUI) {
|
|
3648
4173
|
return {
|
|
3649
4174
|
success: false,
|
|
3650
|
-
error: "UI interaction
|
|
3651
|
-
diagnose: buildDiagnose("unknown", payload.listId)
|
|
4175
|
+
error: chunkUZ2D4BVX_js.permissionDeniedMessage("UI interaction", "canInteractUI"),
|
|
4176
|
+
diagnose: { ...buildDiagnose("unknown", payload.listId), recoverable: false }
|
|
3652
4177
|
};
|
|
3653
4178
|
}
|
|
3654
4179
|
const toIndex = typeof payload.toIndex === "number" ? payload.toIndex : void 0;
|
|
@@ -3676,6 +4201,15 @@ async function scrollListHandler(payload, context) {
|
|
|
3676
4201
|
diagnose: buildDiagnose("component-not-found", payload.listId, candidates)
|
|
3677
4202
|
};
|
|
3678
4203
|
}
|
|
4204
|
+
const exploration = entry.exploration?.snapshot();
|
|
4205
|
+
if (exploration && (exploration.remainingScrollSteps === 0 || exploration.consecutiveNoProgress >= 2)) {
|
|
4206
|
+
return {
|
|
4207
|
+
success: false,
|
|
4208
|
+
effect: "none",
|
|
4209
|
+
error: "List exploration stopped: scroll budget exhausted or repeated no progress. Use the current loaded count/coverage and report any remaining uncertainty; do not repeat this scroll.",
|
|
4210
|
+
diagnose: { ...buildDiagnose("validation", entry.id), recoverable: false }
|
|
4211
|
+
};
|
|
4212
|
+
}
|
|
3679
4213
|
if (toIndex !== void 0) {
|
|
3680
4214
|
if (entry.kind === "scroll") {
|
|
3681
4215
|
return {
|
|
@@ -3691,17 +4225,16 @@ async function scrollListHandler(payload, context) {
|
|
|
3691
4225
|
diagnose: buildDiagnose("validation", entry.id)
|
|
3692
4226
|
};
|
|
3693
4227
|
}
|
|
4228
|
+
const before = entry.getScrollMetrics?.();
|
|
3694
4229
|
const zeroBased = toIndex - 1;
|
|
3695
4230
|
if (entry.scrollToIndex?.(zeroBased)) {
|
|
3696
|
-
|
|
3697
|
-
return { success: true };
|
|
4231
|
+
return finishScroll(entry, before);
|
|
3698
4232
|
}
|
|
3699
4233
|
const metrics2 = entry.getScrollMetrics?.();
|
|
3700
4234
|
if (metrics2 && metrics2.contentLength > 0 && typeof entry.itemCount === "number" && entry.itemCount > 0) {
|
|
3701
4235
|
const estimated = zeroBased / entry.itemCount * metrics2.contentLength;
|
|
3702
4236
|
if (entry.scrollToOffset?.(Math.max(0, estimated))) {
|
|
3703
|
-
|
|
3704
|
-
return { success: true };
|
|
4237
|
+
return finishScroll(entry, before);
|
|
3705
4238
|
}
|
|
3706
4239
|
}
|
|
3707
4240
|
return {
|
|
@@ -3711,10 +4244,21 @@ async function scrollListHandler(payload, context) {
|
|
|
3711
4244
|
};
|
|
3712
4245
|
}
|
|
3713
4246
|
const metrics = entry.getScrollMetrics?.();
|
|
4247
|
+
if (!metrics && exploration?.lastScroll === "unverified") {
|
|
4248
|
+
return {
|
|
4249
|
+
success: false,
|
|
4250
|
+
effect: "unknown",
|
|
4251
|
+
error: "Scroll offset is still unavailable after one probe. Cannot safely page again; do not infer the end or repeat the same absolute offset.",
|
|
4252
|
+
diagnose: { ...buildDiagnose("validation", entry.id), recoverable: false }
|
|
4253
|
+
};
|
|
4254
|
+
}
|
|
3714
4255
|
const target = pageOffset(metrics, direction);
|
|
4256
|
+
if (metrics && Math.abs(target - metrics.offset) <= 2) {
|
|
4257
|
+
entry.exploration?.recordScroll("boundary");
|
|
4258
|
+
return { success: true, effect: "none" };
|
|
4259
|
+
}
|
|
3715
4260
|
if (entry.scrollToOffset?.(target)) {
|
|
3716
|
-
|
|
3717
|
-
return { success: true };
|
|
4261
|
+
return finishScroll(entry, metrics);
|
|
3718
4262
|
}
|
|
3719
4263
|
return {
|
|
3720
4264
|
success: false,
|
|
@@ -3763,12 +4307,12 @@ function resolveActionHints(screen, pressedComponentId, actionPayload) {
|
|
|
3763
4307
|
if (typeof declared === "number") return { asyncBudgetMs: declared };
|
|
3764
4308
|
}
|
|
3765
4309
|
if (!screen || !pressedComponentId) return void 0;
|
|
3766
|
-
const meta =
|
|
4310
|
+
const meta = chunkUZ2D4BVX_js.getScreenMetadata(screen);
|
|
3767
4311
|
const actions = meta?.actions;
|
|
3768
4312
|
if (!actions || actions.length === 0) return void 0;
|
|
3769
4313
|
for (const a of actions) {
|
|
3770
4314
|
if (typeof a === "string") continue;
|
|
3771
|
-
if (
|
|
4315
|
+
if (chunkUZ2D4BVX_js.idLooselyMatches(a.id, pressedComponentId)) {
|
|
3772
4316
|
const inferred = a.appilotsInferred;
|
|
3773
4317
|
const declared = a.asyncBudgetMs;
|
|
3774
4318
|
const hints = {
|
|
@@ -3798,12 +4342,12 @@ function hashFieldValue(value) {
|
|
|
3798
4342
|
}
|
|
3799
4343
|
return (hash >>> 0).toString(36);
|
|
3800
4344
|
}
|
|
3801
|
-
var DISCRETE_FIELD_TYPES = /* @__PURE__ */ new Set(["select", "date"]);
|
|
4345
|
+
var DISCRETE_FIELD_TYPES = /* @__PURE__ */ new Set(["select", "date", "number"]);
|
|
3802
4346
|
function discreteFieldSignature() {
|
|
3803
4347
|
const sigs = [];
|
|
3804
|
-
for (const { id, kind } of
|
|
4348
|
+
for (const { id, kind } of chunkUZ2D4BVX_js.componentRegistry.snapshot()) {
|
|
3805
4349
|
if (kind !== "field") continue;
|
|
3806
|
-
const entry =
|
|
4350
|
+
const entry = chunkUZ2D4BVX_js.componentRegistry.getField(id);
|
|
3807
4351
|
if (!entry || !DISCRETE_FIELD_TYPES.has(entry.fieldType ?? "")) continue;
|
|
3808
4352
|
try {
|
|
3809
4353
|
sigs.push(`${id}:${hashFieldValue(String(entry.getValue() ?? ""))}`);
|
|
@@ -3812,35 +4356,46 @@ function discreteFieldSignature() {
|
|
|
3812
4356
|
}
|
|
3813
4357
|
return sigs.sort().join(",");
|
|
3814
4358
|
}
|
|
3815
|
-
|
|
4359
|
+
function capturePreInteractionBaseline(payload) {
|
|
4360
|
+
const targetId = targetIdFromPayload(payload);
|
|
4361
|
+
const screen = chunkUZ2D4BVX_js.getCurrentScreen();
|
|
4362
|
+
const probe = chunkUZ2D4BVX_js.probeLoadingState(targetId || null, screen);
|
|
4363
|
+
return {
|
|
4364
|
+
fingerprint: probe.fingerprint,
|
|
4365
|
+
fields: discreteFieldSignature(),
|
|
4366
|
+
screen,
|
|
4367
|
+
readable: probe.fingerprint !== ""
|
|
4368
|
+
};
|
|
4369
|
+
}
|
|
4370
|
+
async function waitForPostInteractionSettle(payload, preBaseline) {
|
|
3816
4371
|
const targetId = targetIdFromPayload(payload);
|
|
3817
|
-
const
|
|
3818
|
-
const
|
|
3819
|
-
const baselineFields =
|
|
3820
|
-
const readable = baseline.
|
|
4372
|
+
const baseline = preBaseline ?? capturePreInteractionBaseline(payload);
|
|
4373
|
+
const fromScreen = baseline.screen;
|
|
4374
|
+
const baselineFields = baseline.fields;
|
|
4375
|
+
const readable = baseline.readable;
|
|
3821
4376
|
await sleepMs(100);
|
|
3822
|
-
const afterPress =
|
|
4377
|
+
const afterPress = chunkUZ2D4BVX_js.probeLoadingState(targetId || null, chunkUZ2D4BVX_js.getCurrentScreen());
|
|
3823
4378
|
const modalOrLoading = afterPress.modalOpen || afterPress.loading || afterPress.pressedDisabled;
|
|
3824
4379
|
const fingerprintChanged = afterPress.fingerprint !== baseline.fingerprint;
|
|
3825
4380
|
const verdict = () => {
|
|
3826
4381
|
if (!readable) return { effect: "unknown" };
|
|
3827
|
-
const settled =
|
|
4382
|
+
const settled = chunkUZ2D4BVX_js.probeLoadingState(targetId || null, chunkUZ2D4BVX_js.getCurrentScreen());
|
|
3828
4383
|
if (settled.fingerprint === "") return { effect: "unknown" };
|
|
3829
4384
|
if (discreteFieldSignature() !== baselineFields) return { effect: "changed" };
|
|
3830
4385
|
return { effect: settled.fingerprint !== baseline.fingerprint ? "changed" : "none" };
|
|
3831
4386
|
};
|
|
3832
4387
|
const declared = declaredBudgetMs(resolveActionHints(fromScreen, targetId || null, payload));
|
|
3833
|
-
const capMs = declared ?? (
|
|
4388
|
+
const capMs = declared ?? (chunkUZ2D4BVX_js.isListItemPressTarget(targetId) ? 5e3 : 1e4);
|
|
3834
4389
|
if (modalOrLoading || fingerprintChanged) {
|
|
3835
|
-
await
|
|
4390
|
+
await chunkUZ2D4BVX_js.waitForLoadingSettle({
|
|
3836
4391
|
pressedComponentId: targetId || null,
|
|
3837
4392
|
fromScreen,
|
|
3838
4393
|
maxMs: capMs
|
|
3839
4394
|
});
|
|
3840
4395
|
return verdict();
|
|
3841
4396
|
}
|
|
3842
|
-
if (
|
|
3843
|
-
await
|
|
4397
|
+
if (chunkUZ2D4BVX_js.isListItemPressTarget(targetId)) {
|
|
4398
|
+
await chunkUZ2D4BVX_js.waitForLoadingSettle({
|
|
3844
4399
|
fromScreen,
|
|
3845
4400
|
maxMs: 3e3
|
|
3846
4401
|
});
|
|
@@ -3849,19 +4404,13 @@ async function waitForPostInteractionSettle(payload) {
|
|
|
3849
4404
|
}
|
|
3850
4405
|
|
|
3851
4406
|
// src/executor/ActionExecutor.ts
|
|
3852
|
-
var DEFAULT_PERMISSIONS = {
|
|
3853
|
-
canNavigate: true,
|
|
3854
|
-
canFillForms: true,
|
|
3855
|
-
canInteractUI: true,
|
|
3856
|
-
canSubmitForms: true
|
|
3857
|
-
};
|
|
3858
4407
|
function validateActionPayload(action) {
|
|
3859
4408
|
const invalid = (message, ids) => ({
|
|
3860
4409
|
success: false,
|
|
3861
4410
|
error: message,
|
|
3862
4411
|
diagnose: {
|
|
3863
4412
|
category: "validation",
|
|
3864
|
-
screen:
|
|
4413
|
+
screen: chunkUZ2D4BVX_js.getCurrentScreen() ?? void 0,
|
|
3865
4414
|
...ids ?? {}
|
|
3866
4415
|
}
|
|
3867
4416
|
});
|
|
@@ -3922,10 +4471,10 @@ function isDestructivePayload(payload) {
|
|
|
3922
4471
|
return !!params && typeof params === "object" && params.destructive === true;
|
|
3923
4472
|
}
|
|
3924
4473
|
async function executeAction(action, context) {
|
|
3925
|
-
|
|
4474
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
3926
4475
|
`executeAction called: type="${action.type}", id="${action.id}", payload=${JSON.stringify(action.payload)}`
|
|
3927
4476
|
);
|
|
3928
|
-
const permissions = context.permissions
|
|
4477
|
+
const permissions = chunkUZ2D4BVX_js.resolveAgentPermissions(context.permissions);
|
|
3929
4478
|
context.emit({
|
|
3930
4479
|
type: "agent:action:start",
|
|
3931
4480
|
timestamp: Date.now(),
|
|
@@ -3951,7 +4500,7 @@ async function executeAction(action, context) {
|
|
|
3951
4500
|
let result;
|
|
3952
4501
|
const validationFailure = validateActionPayload(action);
|
|
3953
4502
|
if (validationFailure) {
|
|
3954
|
-
|
|
4503
|
+
chunkUZ2D4BVX_js.appilotsDebugWarn(
|
|
3955
4504
|
`executeAction: payload validation failed for type="${action.type}" id="${action.id}": ${validationFailure.error}`
|
|
3956
4505
|
);
|
|
3957
4506
|
context.emit({
|
|
@@ -3978,17 +4527,18 @@ async function executeAction(action, context) {
|
|
|
3978
4527
|
case "form_fill":
|
|
3979
4528
|
result = await formFillHandler(action.payload, {
|
|
3980
4529
|
permissions,
|
|
3981
|
-
registry: context.registry ??
|
|
4530
|
+
registry: context.registry ?? chunkUZ2D4BVX_js.getDefaultRegistry()
|
|
3982
4531
|
});
|
|
3983
4532
|
break;
|
|
3984
4533
|
case "ui_interaction": {
|
|
3985
4534
|
const payload = action.payload;
|
|
4535
|
+
const baseline = capturePreInteractionBaseline(payload);
|
|
3986
4536
|
result = uiInteractionHandler(payload, {
|
|
3987
4537
|
permissions,
|
|
3988
|
-
registry: context.registry ??
|
|
4538
|
+
registry: context.registry ?? chunkUZ2D4BVX_js.getDefaultRegistry()
|
|
3989
4539
|
});
|
|
3990
4540
|
if (result.success) {
|
|
3991
|
-
const settle = await waitForPostInteractionSettle(payload);
|
|
4541
|
+
const settle = await waitForPostInteractionSettle(payload, baseline);
|
|
3992
4542
|
result.effect = result.effect ?? effectFor(payload, settle.effect);
|
|
3993
4543
|
}
|
|
3994
4544
|
break;
|
|
@@ -4014,7 +4564,7 @@ async function executeAction(action, context) {
|
|
|
4014
4564
|
};
|
|
4015
4565
|
}
|
|
4016
4566
|
} catch (err) {
|
|
4017
|
-
|
|
4567
|
+
chunkUZ2D4BVX_js.appilotsDebugWarn(
|
|
4018
4568
|
`executeAction: exception during action type="${action.type}" id="${action.id}": ${err?.message}`
|
|
4019
4569
|
);
|
|
4020
4570
|
result = {
|
|
@@ -4022,7 +4572,7 @@ async function executeAction(action, context) {
|
|
|
4022
4572
|
error: err?.message ?? "Action execution failed unexpectedly"
|
|
4023
4573
|
};
|
|
4024
4574
|
}
|
|
4025
|
-
|
|
4575
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
4026
4576
|
`executeAction result: type="${action.type}", id="${action.id}", success=${result.success}, error=${result.error ?? "none"}`
|
|
4027
4577
|
);
|
|
4028
4578
|
context.emit({
|
|
@@ -4076,18 +4626,28 @@ var _patchedAlert = (title, message, buttons, options) => {
|
|
|
4076
4626
|
return suppression.originalAlert(title, message, buttons, options);
|
|
4077
4627
|
}
|
|
4078
4628
|
suppression.consumed = true;
|
|
4079
|
-
|
|
4629
|
+
const report = (handlerCompleted) => suppression.onHandled?.({
|
|
4630
|
+
title: title.slice(0, 300),
|
|
4631
|
+
message: message?.slice(0, 1e3),
|
|
4632
|
+
buttonLabel: button.text?.slice(0, 160),
|
|
4633
|
+
handlerCompleted
|
|
4634
|
+
});
|
|
4635
|
+
chunkUZ2D4BVX_js.appilotsDebugLog("Suppressing native Alert during already-confirmed destructive agent action");
|
|
4080
4636
|
try {
|
|
4081
|
-
suppression.pending = Promise.resolve(button.onPress()).then(() =>
|
|
4637
|
+
suppression.pending = Promise.resolve(button.onPress()).then(() => report(true)).catch((err) => {
|
|
4638
|
+
reportHandlerFailure(err);
|
|
4639
|
+
report(false);
|
|
4640
|
+
});
|
|
4082
4641
|
} catch (err) {
|
|
4083
4642
|
reportHandlerFailure(err);
|
|
4084
4643
|
suppression.pending = null;
|
|
4644
|
+
report(false);
|
|
4085
4645
|
}
|
|
4086
4646
|
};
|
|
4087
4647
|
function reportHandlerFailure(err) {
|
|
4088
4648
|
console.error("[Appilots] The app\u2019s Alert handler threw while being auto-confirmed", err);
|
|
4089
4649
|
}
|
|
4090
|
-
async function runWithConfirmedDestructiveContext(enabled, host, fn) {
|
|
4650
|
+
async function runWithConfirmedDestructiveContext(enabled, host, fn, onHandled) {
|
|
4091
4651
|
if (!enabled) return fn();
|
|
4092
4652
|
if (_active) {
|
|
4093
4653
|
_active.depth += 1;
|
|
@@ -4108,6 +4668,7 @@ async function runWithConfirmedDestructiveContext(enabled, host, fn) {
|
|
|
4108
4668
|
depth: 1,
|
|
4109
4669
|
consumed: false,
|
|
4110
4670
|
pending: null,
|
|
4671
|
+
onHandled,
|
|
4111
4672
|
timer: null
|
|
4112
4673
|
};
|
|
4113
4674
|
_active = suppression;
|
|
@@ -4127,45 +4688,67 @@ async function runWithConfirmedDestructiveContext(enabled, host, fn) {
|
|
|
4127
4688
|
}
|
|
4128
4689
|
|
|
4129
4690
|
// src/platform/reactNativeAdapter.ts
|
|
4130
|
-
var deltaTracker =
|
|
4691
|
+
var deltaTracker = chunkUZ2D4BVX_js.createSnapshotDeltaTracker();
|
|
4131
4692
|
function resolveScreenMetadata() {
|
|
4132
|
-
const activePath =
|
|
4693
|
+
const activePath = chunkUZ2D4BVX_js.getActiveRouteNames();
|
|
4133
4694
|
for (let i = activePath.length - 1; i >= 0; i--) {
|
|
4134
4695
|
const name = activePath[i];
|
|
4135
|
-
const meta = name ?
|
|
4696
|
+
const meta = name ? chunkUZ2D4BVX_js.getScreenMetadata(name) : void 0;
|
|
4136
4697
|
if (meta && (Array.isArray(meta.fields) && meta.fields.length > 0 || Array.isArray(meta.actions) && meta.actions.length > 0)) {
|
|
4137
4698
|
return meta;
|
|
4138
4699
|
}
|
|
4139
4700
|
}
|
|
4140
|
-
const screen =
|
|
4141
|
-
return screen ?
|
|
4701
|
+
const screen = chunkUZ2D4BVX_js.getCurrentScreen();
|
|
4702
|
+
return screen ? chunkUZ2D4BVX_js.getScreenMetadata(screen) : void 0;
|
|
4142
4703
|
}
|
|
4143
4704
|
function buildAgentContext(extras = {}) {
|
|
4144
|
-
if (extras.newMission === true)
|
|
4705
|
+
if (extras.newMission === true) {
|
|
4706
|
+
deltaTracker.reset();
|
|
4707
|
+
for (const entry of chunkUZ2D4BVX_js.listRegistry.snapshot()) entry.exploration?.reset();
|
|
4708
|
+
}
|
|
4145
4709
|
const context = {};
|
|
4146
4710
|
context.platform = "react-native";
|
|
4147
|
-
|
|
4711
|
+
context.missionProtocol = 1;
|
|
4712
|
+
context.deviceLocale = detectDeviceLocale() ?? "en";
|
|
4713
|
+
const screen = chunkUZ2D4BVX_js.getCurrentScreen();
|
|
4148
4714
|
if (screen) context.currentScreen = screen;
|
|
4149
|
-
const navigationState =
|
|
4715
|
+
const navigationState = chunkUZ2D4BVX_js.getNavigationStateSnapshot();
|
|
4150
4716
|
if (navigationState) context.navigationState = navigationState;
|
|
4151
4717
|
const screenMeta = resolveScreenMetadata();
|
|
4152
4718
|
if (screenMeta) context.screenMetadata = screenMeta;
|
|
4153
4719
|
try {
|
|
4154
4720
|
const snapshot = captureSnapshot();
|
|
4721
|
+
for (const list of snapshot.lists) {
|
|
4722
|
+
const memory = list.id ? chunkUZ2D4BVX_js.listRegistry.get(list.id)?.exploration : void 0;
|
|
4723
|
+
if (!memory) continue;
|
|
4724
|
+
memory.observe(list.items);
|
|
4725
|
+
list.exploration = memory.snapshot();
|
|
4726
|
+
}
|
|
4155
4727
|
const delta = deltaTracker.observe(snapshot);
|
|
4156
4728
|
if (delta) snapshot.delta = delta;
|
|
4157
4729
|
context.snapshot = snapshot;
|
|
4158
4730
|
} catch (err) {
|
|
4159
|
-
|
|
4731
|
+
chunkUZ2D4BVX_js.appilotsDebugWarn("buildAgentContext: captureSnapshot failed", err);
|
|
4160
4732
|
}
|
|
4161
|
-
const registry =
|
|
4733
|
+
const registry = chunkUZ2D4BVX_js.componentRegistry.snapshot();
|
|
4162
4734
|
const filtered = screen ? registry.filter((c) => !c.screen || c.screen === screen) : registry;
|
|
4163
4735
|
if (filtered.length > 0) context.registeredComponents = filtered;
|
|
4164
|
-
const registeredLists =
|
|
4736
|
+
const registeredLists = chunkUZ2D4BVX_js.listRegistry.snapshot();
|
|
4165
4737
|
if (registeredLists.length > 0) {
|
|
4166
|
-
|
|
4167
|
-
|
|
4738
|
+
const snapshot = context.snapshot;
|
|
4739
|
+
const activeIds = new Set(
|
|
4740
|
+
[...snapshot?.lists ?? [], ...snapshot?.scrollables ?? []].map((l) => l.id)
|
|
4168
4741
|
);
|
|
4742
|
+
context.registeredLists = registeredLists.filter((entry) => activeIds.has(entry.id)).map(({ id, kind, component, itemCount, totalItemCount, label, refreshing, empty }) => ({
|
|
4743
|
+
id,
|
|
4744
|
+
kind,
|
|
4745
|
+
component,
|
|
4746
|
+
itemCount,
|
|
4747
|
+
totalItemCount,
|
|
4748
|
+
label,
|
|
4749
|
+
refreshing,
|
|
4750
|
+
empty
|
|
4751
|
+
}));
|
|
4169
4752
|
}
|
|
4170
4753
|
if (extras.loadingPending === true) context.loadingPending = true;
|
|
4171
4754
|
return context;
|
|
@@ -4175,30 +4758,31 @@ async function settleTurn(input) {
|
|
|
4175
4758
|
let loadingPending = false;
|
|
4176
4759
|
const { turnActions, pressedComponentId: pressedId, navigateTargetScreen } = input;
|
|
4177
4760
|
const successById = new Map(input.results.map((r) => [r.actionId, r.success]));
|
|
4761
|
+
const effectById = new Map(input.results.map((r) => [r.actionId, r.effect]));
|
|
4178
4762
|
const typeById = new Map(input.results.map((r) => [r.actionId, r.type]));
|
|
4179
4763
|
const pressedAction = turnActions.find(
|
|
4180
4764
|
(a) => a.type === "ui_interaction" && a.payload?.componentId === pressedId
|
|
4181
4765
|
);
|
|
4182
4766
|
const hints = resolveActionHints(
|
|
4183
|
-
|
|
4767
|
+
chunkUZ2D4BVX_js.getCurrentScreen(),
|
|
4184
4768
|
pressedId,
|
|
4185
4769
|
pressedAction?.payload
|
|
4186
4770
|
);
|
|
4187
4771
|
const capSource = typeof hints?.asyncBudgetMs === "number" && hints.asyncBudgetMs > 0 ? " (app-declared)" : hints?.isAsyncTrigger ? " (mcp-inferred)" : "";
|
|
4188
4772
|
if (input.hadNavigate) {
|
|
4189
|
-
const settle = await
|
|
4773
|
+
const settle = await chunkUZ2D4BVX_js.waitForScreenSettle({
|
|
4190
4774
|
expectingChange: true,
|
|
4191
4775
|
fromScreen: input.preNavigateScreen ?? null,
|
|
4192
4776
|
fromSignature: input.preNavigateSignature ?? null,
|
|
4193
4777
|
targetScreen: navigateTargetScreen,
|
|
4194
4778
|
maxMs: 3500
|
|
4195
4779
|
});
|
|
4196
|
-
|
|
4780
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
4197
4781
|
`settleTurn: post-navigate settle done \u2014 screen="${settle.screen}" transitioned=${settle.transitioned} timedOut=${settle.timedOut} waitedMs=${settle.waitedMs}`
|
|
4198
4782
|
);
|
|
4199
|
-
const navigationMoved = settle.transitioned ||
|
|
4783
|
+
const navigationMoved = settle.transitioned || chunkUZ2D4BVX_js.screenDepartedBaseline(input.preNavigateScreen ?? null, input.preNavigateSignature ?? null) || !!navigateTargetScreen && !!settle.screen && chunkUZ2D4BVX_js.routesBelongToSameFeature(settle.screen, navigateTargetScreen);
|
|
4200
4784
|
if (!navigationMoved) {
|
|
4201
|
-
|
|
4785
|
+
chunkUZ2D4BVX_js.appilotsDebugWarn(
|
|
4202
4786
|
`tool-without-effect: navigate emitted but screen did not change (stayed at "${input.preNavigateScreen ?? "unknown"}", waitedMs=${settle.waitedMs}). Likely causes: target screenName missing from MCP doc, nested-nav path absent, or React Navigation rejected the route.`
|
|
4203
4787
|
);
|
|
4204
4788
|
for (const [actionId, type] of typeById) {
|
|
@@ -4206,50 +4790,51 @@ async function settleTurn(input) {
|
|
|
4206
4790
|
}
|
|
4207
4791
|
}
|
|
4208
4792
|
const postNavigateCapMs = resolvePostNavigateCapMs(hints);
|
|
4209
|
-
const loadSettle = await
|
|
4793
|
+
const loadSettle = await chunkUZ2D4BVX_js.waitForLoadingSettle({
|
|
4210
4794
|
fromScreen: settle.screen ?? null,
|
|
4211
4795
|
maxMs: postNavigateCapMs
|
|
4212
4796
|
});
|
|
4213
|
-
|
|
4797
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
4214
4798
|
`settleTurn: post-navigate loading settle \u2014 settled=${loadSettle.settled} loadingPending=${loadSettle.loadingPending} probes=${loadSettle.probeCount} waitedMs=${loadSettle.waitedMs} cap=${postNavigateCapMs}${capSource}`
|
|
4215
4799
|
);
|
|
4216
4800
|
if (loadSettle.loadingPending) loadingPending = true;
|
|
4217
4801
|
} else {
|
|
4218
4802
|
const settleCapMs = resolveSettleCapMs(hints);
|
|
4219
4803
|
const busyMaxMs = resolveBusyCeilingMs(hints);
|
|
4220
|
-
const loadSettle = await
|
|
4804
|
+
const loadSettle = await chunkUZ2D4BVX_js.waitForLoadingSettle({
|
|
4221
4805
|
pressedComponentId: pressedId,
|
|
4222
|
-
fromScreen:
|
|
4806
|
+
fromScreen: chunkUZ2D4BVX_js.getCurrentScreen(),
|
|
4223
4807
|
maxMs: settleCapMs,
|
|
4224
4808
|
...busyMaxMs !== void 0 ? { busyMaxMs } : {}
|
|
4225
4809
|
});
|
|
4226
|
-
|
|
4810
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
4227
4811
|
`settleTurn: post-action loading settle \u2014 pressedId="${pressedId ?? ""}" settled=${loadSettle.settled} transitioned=${loadSettle.transitioned} loadingPending=${loadSettle.loadingPending} probes=${loadSettle.probeCount} waitedMs=${loadSettle.waitedMs} cap=${settleCapMs}${capSource}${busyMaxMs !== void 0 ? ` busyCap=${busyMaxMs}` : ""}`
|
|
4228
4812
|
);
|
|
4229
4813
|
if (loadSettle.loadingPending) loadingPending = true;
|
|
4230
4814
|
const listPressActions = turnActions.filter((action) => {
|
|
4231
|
-
const target =
|
|
4232
|
-
return target ?
|
|
4815
|
+
const target = chunkUZ2D4BVX_js.actionPressTargetId(action);
|
|
4816
|
+
return target ? chunkUZ2D4BVX_js.isListItemPressTarget(target) : false;
|
|
4233
4817
|
});
|
|
4234
4818
|
if (listPressActions.length > 0) {
|
|
4235
|
-
const baselineFingerprint =
|
|
4236
|
-
const postPressSettle = await
|
|
4819
|
+
const baselineFingerprint = chunkUZ2D4BVX_js.probeLoadingState(pressedId, chunkUZ2D4BVX_js.getCurrentScreen()).fingerprint;
|
|
4820
|
+
const postPressSettle = await chunkUZ2D4BVX_js.waitForScreenSettle({
|
|
4237
4821
|
expectingChange: true,
|
|
4238
4822
|
fromScreen: input.preNavigateScreen ?? null,
|
|
4239
4823
|
fromSignature: input.preNavigateSignature ?? null,
|
|
4240
4824
|
maxMs: 2500
|
|
4241
4825
|
});
|
|
4242
|
-
await
|
|
4826
|
+
await chunkUZ2D4BVX_js.waitForLoadingSettle({
|
|
4243
4827
|
pressedComponentId: pressedId,
|
|
4244
|
-
fromScreen:
|
|
4828
|
+
fromScreen: chunkUZ2D4BVX_js.getCurrentScreen(),
|
|
4245
4829
|
maxMs: 4e3
|
|
4246
4830
|
});
|
|
4247
|
-
const afterFingerprint =
|
|
4248
|
-
|
|
4831
|
+
const afterFingerprint = chunkUZ2D4BVX_js.probeLoadingState(pressedId, chunkUZ2D4BVX_js.getCurrentScreen()).fingerprint;
|
|
4832
|
+
chunkUZ2D4BVX_js.appilotsDebugLog(
|
|
4249
4833
|
`settleTurn: post-list-press settle \u2014 screen="${postPressSettle.screen}" transitioned=${postPressSettle.transitioned} timedOut=${postPressSettle.timedOut} waitedMs=${postPressSettle.waitedMs}`
|
|
4250
4834
|
);
|
|
4251
4835
|
if (!postPressSettle.transitioned && baselineFingerprint === afterFingerprint) {
|
|
4252
4836
|
for (const action of listPressActions) {
|
|
4837
|
+
if (effectById.get(action.id) === "changed") continue;
|
|
4253
4838
|
if (successById.get(action.id)) {
|
|
4254
4839
|
toolWithoutEffectIds.add(action.id);
|
|
4255
4840
|
}
|
|
@@ -4261,46 +4846,68 @@ async function settleTurn(input) {
|
|
|
4261
4846
|
}
|
|
4262
4847
|
var reactNativeChatAdapter = {
|
|
4263
4848
|
buildContext: buildAgentContext,
|
|
4264
|
-
getCurrentScreen:
|
|
4265
|
-
getCurrentScreenSignature:
|
|
4849
|
+
getCurrentScreen: chunkUZ2D4BVX_js.getCurrentScreen,
|
|
4850
|
+
getCurrentScreenSignature: chunkUZ2D4BVX_js.getCurrentScreenSignature,
|
|
4266
4851
|
settleTurn
|
|
4267
4852
|
};
|
|
4268
4853
|
function createReactNativeActionRunner(getOptions) {
|
|
4269
4854
|
return {
|
|
4855
|
+
buildMissionContext: () => reactNativeChatAdapter.buildContext(),
|
|
4270
4856
|
async execute(action, { confirmedDestructive }) {
|
|
4271
|
-
const { permissions, emit, navigationRef, suppressNativeConfirm } = getOptions();
|
|
4272
|
-
const navRef = navigationRef?.current ? navigationRef : { current:
|
|
4273
|
-
|
|
4857
|
+
const { permissions, emit: emit2, navigationRef, suppressNativeConfirm } = getOptions();
|
|
4858
|
+
const navRef = navigationRef?.current ? navigationRef : { current: chunkUZ2D4BVX_js.getNavigationRef() };
|
|
4859
|
+
let receipt;
|
|
4860
|
+
let terminal;
|
|
4861
|
+
const result = await runWithConfirmedDestructiveContext(
|
|
4274
4862
|
confirmedDestructive && suppressNativeConfirm !== false,
|
|
4275
4863
|
reactNative.Alert,
|
|
4276
4864
|
() => executeAction(action, {
|
|
4277
4865
|
navigationRef: navRef,
|
|
4278
4866
|
permissions,
|
|
4279
|
-
emit
|
|
4280
|
-
|
|
4867
|
+
emit: (event) => {
|
|
4868
|
+
if (confirmedDestructive && (event.type === "agent:action:complete" || event.type === "agent:action:error"))
|
|
4869
|
+
terminal = event;
|
|
4870
|
+
else emit2(event);
|
|
4871
|
+
}
|
|
4872
|
+
}),
|
|
4873
|
+
(handled) => {
|
|
4874
|
+
receipt = handled;
|
|
4875
|
+
}
|
|
4281
4876
|
);
|
|
4877
|
+
const failed = receipt?.handlerCompleted === false;
|
|
4878
|
+
if (terminal)
|
|
4879
|
+
emit2({
|
|
4880
|
+
...terminal,
|
|
4881
|
+
type: failed ? "agent:action:error" : terminal.type,
|
|
4882
|
+
data: {
|
|
4883
|
+
...terminal.data,
|
|
4884
|
+
...receipt ? { nativeConfirmation: receipt } : {},
|
|
4885
|
+
...failed ? { success: false, error: "Native confirmation callback failed" } : {}
|
|
4886
|
+
}
|
|
4887
|
+
});
|
|
4888
|
+
return failed ? { ...result, success: false, error: "Native confirmation callback failed" } : result;
|
|
4282
4889
|
},
|
|
4283
|
-
getCurrentScreen:
|
|
4284
|
-
getCurrentScreenSignature:
|
|
4890
|
+
getCurrentScreen: chunkUZ2D4BVX_js.getCurrentScreen,
|
|
4891
|
+
getCurrentScreenSignature: chunkUZ2D4BVX_js.getCurrentScreenSignature,
|
|
4285
4892
|
getScreenActionsMetadata(screen) {
|
|
4286
|
-
return
|
|
4893
|
+
return chunkUZ2D4BVX_js.getScreenMetadata(screen)?.actions;
|
|
4287
4894
|
},
|
|
4288
|
-
waitForScreenSettle:
|
|
4895
|
+
waitForScreenSettle: chunkUZ2D4BVX_js.waitForScreenSettle
|
|
4289
4896
|
};
|
|
4290
4897
|
}
|
|
4291
4898
|
|
|
4292
4899
|
// src/hooks/useAppilotsChat.ts
|
|
4293
4900
|
function useAppilotsChat(options = {}) {
|
|
4294
|
-
const { client, emit, subscribe } =
|
|
4901
|
+
const { client, emit: emit2, subscribe } = chunkUZ2D4BVX_js.useAppilotsContext();
|
|
4295
4902
|
const machine = React.useMemo(
|
|
4296
|
-
() => new
|
|
4297
|
-
{ client, adapter: reactNativeChatAdapter, emit, warn:
|
|
4903
|
+
() => new chunkUZ2D4BVX_js.ChatSessionMachine(
|
|
4904
|
+
{ client, adapter: reactNativeChatAdapter, emit: emit2, warn: chunkUZ2D4BVX_js.appilotsDebugWarn },
|
|
4298
4905
|
options
|
|
4299
4906
|
),
|
|
4300
4907
|
// A new machine per client/provider instance — options are pushed in
|
|
4301
4908
|
// below so changing copy never resets the transcript.
|
|
4302
4909
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4303
|
-
[client,
|
|
4910
|
+
[client, emit2]
|
|
4304
4911
|
);
|
|
4305
4912
|
const optionsRef = React.useRef(options);
|
|
4306
4913
|
optionsRef.current = options;
|
|
@@ -4308,6 +4915,14 @@ function useAppilotsChat(options = {}) {
|
|
|
4308
4915
|
const state = React.useSyncExternalStore(machine.subscribeState, machine.getState, machine.getState);
|
|
4309
4916
|
React.useEffect(() => subscribe(machine.handleEvent), [subscribe, machine]);
|
|
4310
4917
|
React.useEffect(() => () => machine.dispose(), [machine]);
|
|
4918
|
+
React.useEffect(() => {
|
|
4919
|
+
void machine.restoreMission();
|
|
4920
|
+
const subscription = reactNative.AppState?.addEventListener?.("change", (next) => {
|
|
4921
|
+
if (next !== "active" && machine.getState().mission?.status === "running")
|
|
4922
|
+
void machine.pauseMission();
|
|
4923
|
+
});
|
|
4924
|
+
return () => subscription?.remove();
|
|
4925
|
+
}, [machine]);
|
|
4311
4926
|
const requestHuman = React.useCallback(
|
|
4312
4927
|
(reason) => machine.requestHuman(reason),
|
|
4313
4928
|
[machine]
|
|
@@ -4317,7 +4932,13 @@ function useAppilotsChat(options = {}) {
|
|
|
4317
4932
|
const clearMessages = React.useCallback(() => machine.clearMessages(), [machine]);
|
|
4318
4933
|
const clearError = React.useCallback(() => machine.clearError(), [machine]);
|
|
4319
4934
|
return {
|
|
4935
|
+
mission: state.mission,
|
|
4936
|
+
pauseMission: () => machine.pauseMission(),
|
|
4937
|
+
resumeMission: () => machine.resumeMission(),
|
|
4938
|
+
cancelMission: () => machine.cancelMission(),
|
|
4939
|
+
hasStartedActing: state.hasStartedActing,
|
|
4320
4940
|
messages: state.messages,
|
|
4941
|
+
replyLocale: state.replyLocale,
|
|
4321
4942
|
isLoading: state.isLoading,
|
|
4322
4943
|
loadingStatusKey: state.loadingStatusKey,
|
|
4323
4944
|
error: state.error,
|
|
@@ -4330,39 +4951,33 @@ function useAppilotsChat(options = {}) {
|
|
|
4330
4951
|
clearError
|
|
4331
4952
|
};
|
|
4332
4953
|
}
|
|
4333
|
-
var DEFAULT_PERMISSIONS2 = {
|
|
4334
|
-
canNavigate: true,
|
|
4335
|
-
canFillForms: true,
|
|
4336
|
-
canInteractUI: true,
|
|
4337
|
-
canSubmitForms: true
|
|
4338
|
-
};
|
|
4339
4954
|
function useAppilotsActions(options = {}) {
|
|
4340
|
-
const { client, subscribe, config, emit } =
|
|
4955
|
+
const { client, subscribe, config, emit: emit2 } = chunkUZ2D4BVX_js.useAppilotsContext();
|
|
4341
4956
|
const { navigationRef, autoExecute = false } = options;
|
|
4342
4957
|
const runnerOptionsRef = React.useRef({
|
|
4343
|
-
permissions: config.permissions
|
|
4344
|
-
emit,
|
|
4958
|
+
permissions: chunkUZ2D4BVX_js.resolveAgentPermissions(config.permissions),
|
|
4959
|
+
emit: emit2,
|
|
4345
4960
|
navigationRef,
|
|
4346
4961
|
suppressNativeConfirm: config.suppressNativeConfirm
|
|
4347
4962
|
});
|
|
4348
4963
|
runnerOptionsRef.current = {
|
|
4349
|
-
permissions: config.permissions
|
|
4350
|
-
emit,
|
|
4964
|
+
permissions: chunkUZ2D4BVX_js.resolveAgentPermissions(config.permissions),
|
|
4965
|
+
emit: emit2,
|
|
4351
4966
|
navigationRef,
|
|
4352
4967
|
suppressNativeConfirm: config.suppressNativeConfirm
|
|
4353
4968
|
};
|
|
4354
4969
|
const machine = React.useMemo(
|
|
4355
|
-
() => new
|
|
4970
|
+
() => new chunkUZ2D4BVX_js.ActionQueueMachine(
|
|
4356
4971
|
{
|
|
4357
4972
|
client,
|
|
4358
4973
|
adapter: createReactNativeActionRunner(() => runnerOptionsRef.current),
|
|
4359
|
-
emit,
|
|
4360
|
-
warn:
|
|
4974
|
+
emit: emit2,
|
|
4975
|
+
warn: chunkUZ2D4BVX_js.appilotsDebugWarn
|
|
4361
4976
|
},
|
|
4362
4977
|
{ autoExecute }
|
|
4363
4978
|
),
|
|
4364
4979
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4365
|
-
[client,
|
|
4980
|
+
[client, emit2]
|
|
4366
4981
|
);
|
|
4367
4982
|
machine.setOptions({ autoExecute });
|
|
4368
4983
|
const state = React.useSyncExternalStore(machine.subscribeState, machine.getState, machine.getState);
|
|
@@ -4414,7 +5029,7 @@ function shouldShowSuggestedPrompts(args) {
|
|
|
4414
5029
|
|
|
4415
5030
|
// src/hooks/useSuggestedPrompts.ts
|
|
4416
5031
|
function useSuggestedPrompts(options) {
|
|
4417
|
-
const { client } =
|
|
5032
|
+
const { client } = chunkUZ2D4BVX_js.useAppilotsContext();
|
|
4418
5033
|
const { enabled, limit = 4 } = options;
|
|
4419
5034
|
const [prompts, setPrompts] = React.useState([]);
|
|
4420
5035
|
const [isLoading, setIsLoading] = React.useState(false);
|
|
@@ -4424,8 +5039,8 @@ function useSuggestedPrompts(options) {
|
|
|
4424
5039
|
if (!enabled) return;
|
|
4425
5040
|
const requestId = ++requestIdRef.current;
|
|
4426
5041
|
let cancelled = false;
|
|
4427
|
-
const screen =
|
|
4428
|
-
const localDev = screen ? (
|
|
5042
|
+
const screen = chunkUZ2D4BVX_js.getCurrentScreen() ?? void 0;
|
|
5043
|
+
const localDev = screen ? (chunkUZ2D4BVX_js.getScreenMetadata(screen)?.suggestedPrompts ?? []).map((text) => ({
|
|
4429
5044
|
text,
|
|
4430
5045
|
source: "dev-defined"
|
|
4431
5046
|
})) : [];
|
|
@@ -4439,7 +5054,7 @@ function useSuggestedPrompts(options) {
|
|
|
4439
5054
|
if (cancelled || requestIdRef.current !== requestId) return;
|
|
4440
5055
|
setPrompts(mergePromptSources(localDev, data, limit));
|
|
4441
5056
|
}).catch((err) => {
|
|
4442
|
-
|
|
5057
|
+
chunkUZ2D4BVX_js.appilotsDebugWarn("useSuggestedPrompts: fetch failed", err);
|
|
4443
5058
|
}).finally(() => {
|
|
4444
5059
|
if (cancelled || requestIdRef.current !== requestId) return;
|
|
4445
5060
|
setIsLoading(false);
|
|
@@ -4450,11 +5065,11 @@ function useSuggestedPrompts(options) {
|
|
|
4450
5065
|
}, [client, enabled, limit, refreshTick]);
|
|
4451
5066
|
React.useEffect(() => {
|
|
4452
5067
|
if (!enabled) return;
|
|
4453
|
-
let lastScreen =
|
|
5068
|
+
let lastScreen = chunkUZ2D4BVX_js.getCurrentScreen();
|
|
4454
5069
|
const interval = setInterval(() => {
|
|
4455
|
-
const
|
|
4456
|
-
if (
|
|
4457
|
-
lastScreen =
|
|
5070
|
+
const current2 = chunkUZ2D4BVX_js.getCurrentScreen();
|
|
5071
|
+
if (current2 !== lastScreen) {
|
|
5072
|
+
lastScreen = current2;
|
|
4458
5073
|
setRefreshTick((t) => t + 1);
|
|
4459
5074
|
}
|
|
4460
5075
|
}, 800);
|
|
@@ -4467,22 +5082,22 @@ function useSuggestedPrompts(options) {
|
|
|
4467
5082
|
};
|
|
4468
5083
|
}
|
|
4469
5084
|
function useAppilotsNavigation() {
|
|
4470
|
-
const { emit } =
|
|
5085
|
+
const { emit: emit2 } = chunkUZ2D4BVX_js.useAppilotsContext();
|
|
4471
5086
|
const [currentScreen, setCurrentScreenState] = React.useState(null);
|
|
4472
5087
|
const [navigationHistory, setNavigationHistory] = React.useState([]);
|
|
4473
5088
|
const navigationRef = React.useRef(null);
|
|
4474
5089
|
const setCurrentScreen2 = React.useCallback(
|
|
4475
5090
|
(screenName) => {
|
|
4476
5091
|
setCurrentScreenState(screenName);
|
|
4477
|
-
|
|
5092
|
+
chunkUZ2D4BVX_js.setCurrentScreen(screenName);
|
|
4478
5093
|
setNavigationHistory((prev) => [...prev, screenName]);
|
|
4479
|
-
|
|
5094
|
+
emit2({
|
|
4480
5095
|
type: "navigation:change",
|
|
4481
5096
|
timestamp: Date.now(),
|
|
4482
5097
|
data: { screenName }
|
|
4483
5098
|
});
|
|
4484
5099
|
},
|
|
4485
|
-
[
|
|
5100
|
+
[emit2]
|
|
4486
5101
|
);
|
|
4487
5102
|
React.useEffect(() => {
|
|
4488
5103
|
const nav = navigationRef.current;
|
|
@@ -4505,7 +5120,7 @@ function useAppilotsNavigation() {
|
|
|
4505
5120
|
|
|
4506
5121
|
// src/hooks/useAppilots.ts
|
|
4507
5122
|
function useAppilots() {
|
|
4508
|
-
const { config, client } =
|
|
5123
|
+
const { config, client } = chunkUZ2D4BVX_js.useAppilotsContext();
|
|
4509
5124
|
const chat = useAppilotsChat();
|
|
4510
5125
|
const navigation = useAppilotsNavigation();
|
|
4511
5126
|
const actions = useAppilotsActions();
|
|
@@ -4532,9 +5147,14 @@ function useAppilots() {
|
|
|
4532
5147
|
rejectAction: actions.rejectAction
|
|
4533
5148
|
};
|
|
4534
5149
|
}
|
|
5150
|
+
function useAppilotsElementProps(id) {
|
|
5151
|
+
return React.useMemo(() => ({ testID: id }), [id]);
|
|
5152
|
+
}
|
|
5153
|
+
|
|
5154
|
+
// src/hooks/useAppilotsField.ts
|
|
4535
5155
|
function useAppilotsField(id, options) {
|
|
4536
5156
|
const { value, onChangeText, ref, fieldType, label, screen } = options;
|
|
4537
|
-
const registry =
|
|
5157
|
+
const registry = chunkUZ2D4BVX_js.useResolvedRegistry();
|
|
4538
5158
|
const valueRef = React.useRef(value);
|
|
4539
5159
|
const onChangeRef = React.useRef(onChangeText);
|
|
4540
5160
|
valueRef.current = value;
|
|
@@ -4559,10 +5179,11 @@ function useAppilotsField(id, options) {
|
|
|
4559
5179
|
registry.unregister(id);
|
|
4560
5180
|
};
|
|
4561
5181
|
}, [id, registry, getValue, setValue, focus, ref, fieldType, label, screen]);
|
|
5182
|
+
return useAppilotsElementProps(id);
|
|
4562
5183
|
}
|
|
4563
5184
|
function useAppilotsTarget(id, options) {
|
|
4564
5185
|
const { onPress, onLongPress, onScrollTo, label, screen } = options;
|
|
4565
|
-
const registry =
|
|
5186
|
+
const registry = chunkUZ2D4BVX_js.useResolvedRegistry();
|
|
4566
5187
|
const onPressRef = React.useRef(onPress);
|
|
4567
5188
|
const onLongPressRef = React.useRef(onLongPress);
|
|
4568
5189
|
const onScrollToRef = React.useRef(onScrollTo);
|
|
@@ -4586,10 +5207,11 @@ function useAppilotsTarget(id, options) {
|
|
|
4586
5207
|
registry.unregister(id);
|
|
4587
5208
|
};
|
|
4588
5209
|
}, [id, registry, press, longPress, scrollTo, onLongPress, onScrollTo, label, screen]);
|
|
5210
|
+
return useAppilotsElementProps(id);
|
|
4589
5211
|
}
|
|
4590
5212
|
function useAppilotsToggle(id, options) {
|
|
4591
5213
|
const { value, onValueChange, label, screen } = options;
|
|
4592
|
-
const registry =
|
|
5214
|
+
const registry = chunkUZ2D4BVX_js.useResolvedRegistry();
|
|
4593
5215
|
const valueRef = React.useRef(value);
|
|
4594
5216
|
const onChangeRef = React.useRef(onValueChange);
|
|
4595
5217
|
valueRef.current = value;
|
|
@@ -4609,10 +5231,11 @@ function useAppilotsToggle(id, options) {
|
|
|
4609
5231
|
registry.unregister(id);
|
|
4610
5232
|
};
|
|
4611
5233
|
}, [id, registry, getValue, setValue, label, screen]);
|
|
5234
|
+
return useAppilotsElementProps(id);
|
|
4612
5235
|
}
|
|
4613
5236
|
function useAppilotsSlider(id, options) {
|
|
4614
5237
|
const { value, onValueChange, min, max, step, label, screen } = options;
|
|
4615
|
-
const registry =
|
|
5238
|
+
const registry = chunkUZ2D4BVX_js.useResolvedRegistry();
|
|
4616
5239
|
const valueRef = React.useRef(value);
|
|
4617
5240
|
const onChangeRef = React.useRef(onValueChange);
|
|
4618
5241
|
valueRef.current = value;
|
|
@@ -4635,16 +5258,30 @@ function useAppilotsSlider(id, options) {
|
|
|
4635
5258
|
registry.unregister(id);
|
|
4636
5259
|
};
|
|
4637
5260
|
}, [id, registry, getValue, setValue, min, max, step, label, screen]);
|
|
5261
|
+
return useAppilotsElementProps(id);
|
|
4638
5262
|
}
|
|
4639
5263
|
|
|
5264
|
+
exports.AppilotsI18nProvider = AppilotsI18nProvider;
|
|
5265
|
+
exports.REVEAL_MARGIN = REVEAL_MARGIN;
|
|
5266
|
+
exports.SPOTLIGHT_TTL_MS = SPOTLIGHT_TTL_MS;
|
|
4640
5267
|
exports.appilotsSelfCheck = appilotsSelfCheck;
|
|
4641
5268
|
exports.captureSnapshot = captureSnapshot;
|
|
5269
|
+
exports.detectDeviceLocale = detectDeviceLocale;
|
|
4642
5270
|
exports.executeAction = executeAction;
|
|
5271
|
+
exports.getSpotlightMode = getSpotlightMode;
|
|
5272
|
+
exports.getSpotlightTarget = getSpotlightTarget;
|
|
5273
|
+
exports.offsetToReveal = offsetToReveal;
|
|
5274
|
+
exports.resolveLocale = resolveLocale;
|
|
5275
|
+
exports.revealTarget = revealTarget;
|
|
5276
|
+
exports.setSpotlightMode = setSpotlightMode;
|
|
5277
|
+
exports.setSpotlightTarget = setSpotlightTarget;
|
|
4643
5278
|
exports.shouldShowSuggestedPrompts = shouldShowSuggestedPrompts;
|
|
5279
|
+
exports.subscribeSpotlight = subscribeSpotlight;
|
|
4644
5280
|
exports.useAppilots = useAppilots;
|
|
4645
5281
|
exports.useAppilotsActions = useAppilotsActions;
|
|
4646
5282
|
exports.useAppilotsChat = useAppilotsChat;
|
|
4647
5283
|
exports.useAppilotsField = useAppilotsField;
|
|
5284
|
+
exports.useAppilotsI18n = useAppilotsI18n;
|
|
4648
5285
|
exports.useAppilotsNavigation = useAppilotsNavigation;
|
|
4649
5286
|
exports.useAppilotsSlider = useAppilotsSlider;
|
|
4650
5287
|
exports.useAppilotsTarget = useAppilotsTarget;
|