@appilots/sdk 0.11.1 → 0.11.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.build-meta.json +3 -3
- package/dist/{chunk-GSHE45YX.mjs → chunk-2ZDELL54.mjs} +90 -34
- package/dist/{chunk-DRXUBLGY.js → chunk-5UVMNKPT.js} +8 -8
- package/dist/{chunk-LLH7QCSX.mjs → chunk-JKLE5SLN.mjs} +1 -1
- package/dist/{chunk-PQZ64CCE.mjs → chunk-ROXXCDIG.mjs} +297 -15
- package/dist/{chunk-KZ2BLMS4.js → chunk-SUMIABJK.js} +297 -14
- package/dist/{chunk-X4MPSZL3.js → chunk-UFMTRGML.js} +365 -309
- 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-C01Spw6F.d.mts → index-BR-33WMN.d.mts} +111 -0
- package/dist/{index-C01Spw6F.d.ts → index-BR-33WMN.d.ts} +111 -0
- package/dist/index.d.mts +28 -3
- package/dist/index.d.ts +28 -3
- package/dist/index.js +112 -82
- package/dist/index.mjs +45 -15
- package/dist/navigation/index.d.mts +42 -6
- package/dist/navigation/index.d.ts +42 -6
- package/dist/navigation/index.js +13 -13
- package/dist/navigation/index.mjs +2 -2
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkSUMIABJK_js = require('./chunk-SUMIABJK.js');
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var reactNative = require('react-native');
|
|
6
6
|
|
|
@@ -23,9 +23,9 @@ function fiberSliderMatches(fiber, registryId, registryLabel) {
|
|
|
23
23
|
function reconcileSliders(snapshot) {
|
|
24
24
|
const fiberSliders = snapshot.sliders;
|
|
25
25
|
const out = [];
|
|
26
|
-
for (const { id, kind } of
|
|
26
|
+
for (const { id, kind } of chunkSUMIABJK_js.componentRegistry.snapshot()) {
|
|
27
27
|
if (kind !== "slider") continue;
|
|
28
|
-
const entry =
|
|
28
|
+
const entry = chunkSUMIABJK_js.componentRegistry.getSlider(id);
|
|
29
29
|
if (!entry) continue;
|
|
30
30
|
const fiber = fiberSliders.find((s) => fiberSliderMatches(s, id, entry.label));
|
|
31
31
|
const visible = !!fiber || typeof entry.screen === "string" && entry.screen === snapshot.route;
|
|
@@ -53,7 +53,7 @@ function normalizeFieldKey(value) {
|
|
|
53
53
|
}
|
|
54
54
|
function canonicalizeRegisteredFields(snapshot) {
|
|
55
55
|
const claimed = /* @__PURE__ */ new Set();
|
|
56
|
-
for (const { id, kind, label } of
|
|
56
|
+
for (const { id, kind, label } of chunkSUMIABJK_js.componentRegistry.snapshot()) {
|
|
57
57
|
if (kind !== "field") continue;
|
|
58
58
|
if (snapshot.inputs.some((input) => input.id === id)) continue;
|
|
59
59
|
const registryLabel = (label ?? "").toLowerCase();
|
|
@@ -72,7 +72,7 @@ function canonicalizeRegisteredFields(snapshot) {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
function mergeRegisteredLists(snapshot) {
|
|
75
|
-
const registered =
|
|
75
|
+
const registered = chunkSUMIABJK_js.listRegistry.snapshot();
|
|
76
76
|
if (registered.length === 0) return;
|
|
77
77
|
const byId = /* @__PURE__ */ new Map();
|
|
78
78
|
for (const list of snapshot.lists) {
|
|
@@ -121,7 +121,7 @@ function mergeRegisteredLists(snapshot) {
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
function mergeRegisteredScrollables(snapshot) {
|
|
124
|
-
const registered =
|
|
124
|
+
const registered = chunkSUMIABJK_js.listRegistry.snapshot().filter((e) => e.kind === "scroll");
|
|
125
125
|
if (registered.length === 0) return;
|
|
126
126
|
const listsById = /* @__PURE__ */ new Map();
|
|
127
127
|
for (const list of snapshot.lists) {
|
|
@@ -154,7 +154,7 @@ function mergeRegisteredScrollables(snapshot) {
|
|
|
154
154
|
if (out.length > 0) snapshot.scrollables = out;
|
|
155
155
|
}
|
|
156
156
|
function mergeNativeDialog(snapshot) {
|
|
157
|
-
const dialog =
|
|
157
|
+
const dialog = chunkSUMIABJK_js.getOpenNativeDialog();
|
|
158
158
|
if (!dialog) return;
|
|
159
159
|
snapshot.nativeDialog = {
|
|
160
160
|
id: dialog.id,
|
|
@@ -169,21 +169,21 @@ function mergeNativeDialog(snapshot) {
|
|
|
169
169
|
}
|
|
170
170
|
var MIN_FIBERS_FOR_BLINDNESS = 200;
|
|
171
171
|
function recordBlindWalk() {
|
|
172
|
-
const walk =
|
|
172
|
+
const walk = chunkSUMIABJK_js.getLastWalkDiagnostics();
|
|
173
173
|
if (!walk) return;
|
|
174
174
|
if (walk.visitedFibers < MIN_FIBERS_FOR_BLINDNESS) return;
|
|
175
|
-
if (
|
|
176
|
-
|
|
175
|
+
if (chunkSUMIABJK_js.totalDetectorHits(walk.detectors) > 0) return;
|
|
176
|
+
chunkSUMIABJK_js.recordIntrospectionFailure("walk-recognized-nothing", null);
|
|
177
177
|
}
|
|
178
178
|
function captureSnapshot() {
|
|
179
|
-
const root =
|
|
179
|
+
const root = chunkSUMIABJK_js.getFiberRoot();
|
|
180
180
|
if (!root) {
|
|
181
|
-
|
|
181
|
+
chunkSUMIABJK_js.appilotsDebugWarn(
|
|
182
182
|
"captureSnapshot: fiber root not captured yet. Ensure <AppilotsProvider> has rendered before calling this."
|
|
183
183
|
);
|
|
184
|
-
|
|
184
|
+
chunkSUMIABJK_js.recordIntrospectionFailure("never-mounted", null);
|
|
185
185
|
return {
|
|
186
|
-
route:
|
|
186
|
+
route: chunkSUMIABJK_js.getCurrentScreen(),
|
|
187
187
|
texts: [],
|
|
188
188
|
inputs: [],
|
|
189
189
|
buttons: [],
|
|
@@ -197,9 +197,9 @@ function captureSnapshot() {
|
|
|
197
197
|
};
|
|
198
198
|
}
|
|
199
199
|
const start = Date.now();
|
|
200
|
-
const snapshot =
|
|
200
|
+
const snapshot = chunkSUMIABJK_js.walkFiber(root);
|
|
201
201
|
recordBlindWalk();
|
|
202
|
-
const activePath =
|
|
202
|
+
const activePath = chunkSUMIABJK_js.getActiveRouteNames();
|
|
203
203
|
const deepestRoute = activePath[activePath.length - 1];
|
|
204
204
|
if (deepestRoute) snapshot.route = deepestRoute;
|
|
205
205
|
mergeRegisteredLists(snapshot);
|
|
@@ -207,15 +207,15 @@ function captureSnapshot() {
|
|
|
207
207
|
mergeNativeDialog(snapshot);
|
|
208
208
|
reconcileSliders(snapshot);
|
|
209
209
|
canonicalizeRegisteredFields(snapshot);
|
|
210
|
-
|
|
211
|
-
const entries =
|
|
210
|
+
chunkSUMIABJK_js.clampSnapshotToWireLimits(snapshot);
|
|
211
|
+
const entries = chunkSUMIABJK_js.deriveInteractionElements(snapshot, { rectOf: chunkSUMIABJK_js.rectForNode });
|
|
212
212
|
const rectById = new Map(
|
|
213
213
|
entries.flatMap((entry) => entry.rect ? [[entry.id, entry.rect]] : [])
|
|
214
214
|
);
|
|
215
|
-
snapshot.elements = entries.map(
|
|
216
|
-
snapshot.choiceGroups =
|
|
217
|
-
|
|
218
|
-
|
|
215
|
+
snapshot.elements = entries.map(chunkSUMIABJK_js.toWireElement);
|
|
216
|
+
snapshot.choiceGroups = chunkSUMIABJK_js.attachElementIdsToChoiceGroups(snapshot.choiceGroups, snapshot.elements);
|
|
217
|
+
chunkSUMIABJK_js.clampSnapshotToWireLimits(snapshot);
|
|
218
|
+
chunkSUMIABJK_js.elementRegistry.replaceAll(
|
|
219
219
|
snapshot.elements.map((element) => {
|
|
220
220
|
const rect = rectById.get(element.id);
|
|
221
221
|
return rect ? { ...element, rect } : element;
|
|
@@ -227,10 +227,10 @@ function captureSnapshot() {
|
|
|
227
227
|
(acc, l) => acc + (typeof l.itemCount === "number" ? l.itemCount : 0),
|
|
228
228
|
0
|
|
229
229
|
);
|
|
230
|
-
|
|
230
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
231
231
|
`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
232
|
);
|
|
233
|
-
|
|
233
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
234
234
|
`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
235
|
);
|
|
236
236
|
return snapshot;
|
|
@@ -241,10 +241,10 @@ function registryCounts() {
|
|
|
241
241
|
toggles: 0,
|
|
242
242
|
sliders: 0,
|
|
243
243
|
targets: 0,
|
|
244
|
-
lists:
|
|
245
|
-
elements:
|
|
244
|
+
lists: chunkSUMIABJK_js.listRegistry.snapshot().length,
|
|
245
|
+
elements: chunkSUMIABJK_js.elementRegistry.size
|
|
246
246
|
};
|
|
247
|
-
for (const { kind } of
|
|
247
|
+
for (const { kind } of chunkSUMIABJK_js.componentRegistry.snapshot()) {
|
|
248
248
|
if (kind === "field") counts.fields++;
|
|
249
249
|
else if (kind === "toggle") counts.toggles++;
|
|
250
250
|
else if (kind === "slider") counts.sliders++;
|
|
@@ -253,26 +253,26 @@ function registryCounts() {
|
|
|
253
253
|
return counts;
|
|
254
254
|
}
|
|
255
255
|
function appilotsSelfCheck() {
|
|
256
|
-
const root =
|
|
256
|
+
const root = chunkSUMIABJK_js.getFiberRoot();
|
|
257
257
|
const start = Date.now();
|
|
258
|
-
if (root)
|
|
258
|
+
if (root) chunkSUMIABJK_js.walkFiber(root);
|
|
259
259
|
const elapsedMs = Date.now() - start;
|
|
260
|
-
const walk =
|
|
260
|
+
const walk = chunkSUMIABJK_js.getLastWalkDiagnostics();
|
|
261
261
|
return {
|
|
262
|
-
sdkVersion:
|
|
262
|
+
sdkVersion: chunkSUMIABJK_js.SDK_VERSION,
|
|
263
263
|
reactVersion: React__default.default.version ?? null,
|
|
264
|
-
route:
|
|
265
|
-
introspection:
|
|
266
|
-
autoTracking:
|
|
264
|
+
route: chunkSUMIABJK_js.getCurrentScreen() || null,
|
|
265
|
+
introspection: chunkSUMIABJK_js.getIntrospectionDiagnostics(),
|
|
266
|
+
autoTracking: chunkSUMIABJK_js.getAutoTrackingState(),
|
|
267
267
|
walk: {
|
|
268
268
|
visitedFibers: root ? walk?.visitedFibers ?? 0 : 0,
|
|
269
269
|
skippedHidden: root ? walk?.skippedHidden ?? 0 : 0,
|
|
270
270
|
elapsedMs
|
|
271
271
|
},
|
|
272
|
-
detectors: root ? walk?.detectors ??
|
|
272
|
+
detectors: root ? walk?.detectors ?? chunkSUMIABJK_js.emptyDetectorCounts() : chunkSUMIABJK_js.emptyDetectorCounts(),
|
|
273
273
|
registry: registryCounts(),
|
|
274
|
-
nameMangling:
|
|
275
|
-
geometry: { availability:
|
|
274
|
+
nameMangling: chunkSUMIABJK_js.getNameManglingProbe(),
|
|
275
|
+
geometry: { availability: chunkSUMIABJK_js.geometryAvailability(), ...chunkSUMIABJK_js.geometryStats() }
|
|
276
276
|
};
|
|
277
277
|
}
|
|
278
278
|
|
|
@@ -285,7 +285,7 @@ function declaredState(props) {
|
|
|
285
285
|
return typeof checked === "boolean" ? checked : void 0;
|
|
286
286
|
}
|
|
287
287
|
function isReactNativeSwitch(fiber) {
|
|
288
|
-
return
|
|
288
|
+
return chunkSUMIABJK_js.getTypeName(fiber?.type) === "Switch" || chunkSUMIABJK_js.getTypeName(fiber?.elementType) === "Switch";
|
|
289
289
|
}
|
|
290
290
|
var SWITCH_FLIP_HANDLERS = ["onValueChange", "onChange", "onPress"];
|
|
291
291
|
function flipSwitchFiber(fiber, next) {
|
|
@@ -383,7 +383,7 @@ function shouldSkipSubtree2(fiber) {
|
|
|
383
383
|
const typeName = getTypeName2(fiber.type) ?? getTypeName2(fiber.elementType);
|
|
384
384
|
if (typeName && SELF_REFERENTIAL_COMPONENTS.has(typeName)) return true;
|
|
385
385
|
if (isAppilotsSkipMarked(props)) return true;
|
|
386
|
-
if (
|
|
386
|
+
if (chunkSUMIABJK_js.isModalFiber(fiber) && props.visible === false) return true;
|
|
387
387
|
if (matchesName(fiber, "Screen") && props.activityState === 0) return true;
|
|
388
388
|
const style = props.style;
|
|
389
389
|
if (style) {
|
|
@@ -393,7 +393,7 @@ function shouldSkipSubtree2(fiber) {
|
|
|
393
393
|
}
|
|
394
394
|
return false;
|
|
395
395
|
}
|
|
396
|
-
var normalize =
|
|
396
|
+
var normalize = chunkSUMIABJK_js.foldForCompare;
|
|
397
397
|
function scoreMatchDetail(fiber, queryNorm, queryRaw) {
|
|
398
398
|
const props = fiber.memoizedProps ?? {};
|
|
399
399
|
const candidates = [];
|
|
@@ -468,7 +468,7 @@ function wrapSwitch(fiber) {
|
|
|
468
468
|
// `accessibilityRole="switch"`) has only the former, and reporting
|
|
469
469
|
// `false` for a control that is on is worse than reporting nothing:
|
|
470
470
|
// the caller inverts this to decide where to move.
|
|
471
|
-
getValue: () =>
|
|
471
|
+
getValue: () => chunkSUMIABJK_js.switchValue(getProps()),
|
|
472
472
|
setValue: (value) => {
|
|
473
473
|
const boolVal = typeof value === "boolean" ? value : value === "true" || value === true;
|
|
474
474
|
const flipped = flipSwitchFiber(fiber, boolVal);
|
|
@@ -523,9 +523,9 @@ function isDescendantOf(fiber, ancestor) {
|
|
|
523
523
|
return false;
|
|
524
524
|
}
|
|
525
525
|
function findInteractiveByIdentifier(query, options = {}) {
|
|
526
|
-
const root =
|
|
526
|
+
const root = chunkSUMIABJK_js.getFiberRoot();
|
|
527
527
|
if (!root) {
|
|
528
|
-
|
|
528
|
+
chunkSUMIABJK_js.appilotsDebugWarn("findInteractiveByIdentifier: fiber root not captured yet");
|
|
529
529
|
return null;
|
|
530
530
|
}
|
|
531
531
|
const queryNorm = normalize(query);
|
|
@@ -549,7 +549,7 @@ function findInteractiveByIdentifier(query, options = {}) {
|
|
|
549
549
|
const props = fiber.memoizedProps ?? {};
|
|
550
550
|
let kind = null;
|
|
551
551
|
if (matchesName(fiber, "TextInput")) kind = "field";
|
|
552
|
-
else if (
|
|
552
|
+
else if (chunkSUMIABJK_js.isSwitchLike(fiber, props)) kind = "toggle";
|
|
553
553
|
else if (isPressableTarget(fiber)) kind = "target";
|
|
554
554
|
if (kind && (!options.kind || options.kind === kind)) {
|
|
555
555
|
const detail = scoreMatchDetail(fiber, queryNorm, queryRaw);
|
|
@@ -574,7 +574,7 @@ function findInteractiveByIdentifier(query, options = {}) {
|
|
|
574
574
|
if (fiber.child) stack.push(fiber.child);
|
|
575
575
|
}
|
|
576
576
|
if (bestHandle && bestScore < (options.minScore ?? 0)) {
|
|
577
|
-
|
|
577
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
578
578
|
`findInteractiveByIdentifier: query="${query}" \u2192 best match scored ${bestScore}, below the requested floor of ${options.minScore} \u2014 refusing it`
|
|
579
579
|
);
|
|
580
580
|
return null;
|
|
@@ -590,11 +590,11 @@ function findInteractiveByIdentifier(query, options = {}) {
|
|
|
590
590
|
bestHandle.disabled = bestDisabled;
|
|
591
591
|
const candidates = independent.map(({ fiber, kind }) => describeCandidate(fiber, kind)).filter((id) => typeof id === "string" && id.length > 0).slice(0, 8);
|
|
592
592
|
if (candidates.length > 0) bestHandle.matchCandidates = candidates;
|
|
593
|
-
|
|
593
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
594
594
|
`findInteractiveByIdentifier: query="${query}" \u2192 kind=${bestHandle.kind} label="${bestHandle.label ?? bestId}" score=${bestScore} named=${bestNamed} disabled=${bestDisabled} tied=${independent.length}`
|
|
595
595
|
);
|
|
596
596
|
} else {
|
|
597
|
-
|
|
597
|
+
chunkSUMIABJK_js.appilotsDebugLog(`findInteractiveByIdentifier: query="${query}" \u2192 no match`);
|
|
598
598
|
}
|
|
599
599
|
return bestHandle;
|
|
600
600
|
}
|
|
@@ -643,7 +643,7 @@ function screenExistsAnywhere(state, screenName) {
|
|
|
643
643
|
function safeNavigate(nav, screenName, params, path) {
|
|
644
644
|
if (path && path.length > 0) {
|
|
645
645
|
const { root, nestedParams } = buildNestedParams(path, screenName, params);
|
|
646
|
-
|
|
646
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
647
647
|
`safeNavigate: using path-based navigation \u2014 root="${root}", nested=${JSON.stringify(nestedParams)}`
|
|
648
648
|
);
|
|
649
649
|
nav.navigate(root, nestedParams);
|
|
@@ -660,16 +660,16 @@ function safeNavigate(nav, screenName, params, path) {
|
|
|
660
660
|
`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
661
|
);
|
|
662
662
|
}
|
|
663
|
-
|
|
663
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
664
664
|
`safeNavigate: screen exists in nested navigator, attempting direct navigation to "${screenName}"`
|
|
665
665
|
);
|
|
666
666
|
nav.navigate(screenName, params);
|
|
667
667
|
}
|
|
668
668
|
function navigateHandler(payload, context) {
|
|
669
|
-
|
|
669
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
670
670
|
// Params carry record ids and, on some screens, the user's own
|
|
671
671
|
// data — the count answers "were params passed?" and nothing else.
|
|
672
|
-
`navigateHandler called: screenName="${payload.screenName}" action="${payload.navigationAction}" params=${
|
|
672
|
+
`navigateHandler called: screenName="${payload.screenName}" action="${payload.navigationAction}" params=${chunkSUMIABJK_js.describeValue(payload.params)}`
|
|
673
673
|
);
|
|
674
674
|
const { navigationRef, permissions } = context;
|
|
675
675
|
const nav = navigationRef.current;
|
|
@@ -762,12 +762,12 @@ function navigateHandler(payload, context) {
|
|
|
762
762
|
diagnose: { category: "unknown", screen: payload.screenName }
|
|
763
763
|
};
|
|
764
764
|
}
|
|
765
|
-
|
|
765
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
766
766
|
`navigateHandler: navigation succeeded for "${payload.screenName}" (action="${payload.navigationAction}")`
|
|
767
767
|
);
|
|
768
768
|
return { success: true };
|
|
769
769
|
} catch (err) {
|
|
770
|
-
|
|
770
|
+
chunkSUMIABJK_js.appilotsDebugWarn(
|
|
771
771
|
`navigateHandler: navigation failed for "${payload.screenName}": ${err?.message}`
|
|
772
772
|
);
|
|
773
773
|
const msg = String(err?.message ?? "Navigation failed");
|
|
@@ -815,18 +815,18 @@ function markedItemIndexFromFiber(fiber) {
|
|
|
815
815
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
816
816
|
}
|
|
817
817
|
function normalize2(value) {
|
|
818
|
-
return
|
|
818
|
+
return chunkSUMIABJK_js.foldForCompare(String(value ?? ""));
|
|
819
819
|
}
|
|
820
820
|
function hasPressHandler2(fiber) {
|
|
821
821
|
const props = fiber?.memoizedProps ?? {};
|
|
822
822
|
return typeof props.onPress === "function" || typeof props.onPressIn === "function";
|
|
823
823
|
}
|
|
824
824
|
function isPressableFiber(fiber) {
|
|
825
|
-
const typeName =
|
|
826
|
-
return
|
|
825
|
+
const typeName = chunkSUMIABJK_js.getTypeName(fiber.type) ?? chunkSUMIABJK_js.getTypeName(fiber.elementType) ?? "";
|
|
826
|
+
return chunkSUMIABJK_js.TOUCHABLE_NAMES.has(typeName) || hasPressHandler2(fiber);
|
|
827
827
|
}
|
|
828
828
|
function findListContainers(options = {}) {
|
|
829
|
-
const root =
|
|
829
|
+
const root = chunkSUMIABJK_js.getFiberRoot();
|
|
830
830
|
if (!root) return [];
|
|
831
831
|
const containers = [];
|
|
832
832
|
const visited = /* @__PURE__ */ new WeakSet();
|
|
@@ -837,17 +837,17 @@ function findListContainers(options = {}) {
|
|
|
837
837
|
if (!fiber || visited.has(fiber)) continue;
|
|
838
838
|
visited.add(fiber);
|
|
839
839
|
if (fiber.sibling) stack.push(fiber.sibling);
|
|
840
|
-
if (
|
|
841
|
-
if (
|
|
842
|
-
const minItems =
|
|
843
|
-
const items =
|
|
840
|
+
if (chunkSUMIABJK_js.shouldSkipSubtree(fiber)) continue;
|
|
841
|
+
if (chunkSUMIABJK_js.isAlwaysListContainer(fiber) || chunkSUMIABJK_js.isHeuristicListContainer(fiber)) {
|
|
842
|
+
const minItems = chunkSUMIABJK_js.isAlwaysListContainer(fiber) || options.allowSingleHeuristic ? 1 : 2;
|
|
843
|
+
const items = chunkSUMIABJK_js.findListItems(fiber, minItems);
|
|
844
844
|
if (items && items.length >= minItems) {
|
|
845
845
|
containers.push({
|
|
846
846
|
container: fiber,
|
|
847
847
|
items,
|
|
848
848
|
listId: listIdFromContainer(fiber),
|
|
849
849
|
listLabel: listLabelFromContainer(fiber),
|
|
850
|
-
containerType:
|
|
850
|
+
containerType: chunkSUMIABJK_js.getTypeName(fiber.type) ?? chunkSUMIABJK_js.getTypeName(fiber.elementType) ?? "List"
|
|
851
851
|
});
|
|
852
852
|
continue;
|
|
853
853
|
}
|
|
@@ -866,7 +866,7 @@ function findFirstTouchable(item) {
|
|
|
866
866
|
const { fiber, includeSibling } = stack.pop();
|
|
867
867
|
if (!fiber || visited.has(fiber)) continue;
|
|
868
868
|
visited.add(fiber);
|
|
869
|
-
if (
|
|
869
|
+
if (chunkSUMIABJK_js.shouldSkipSubtree(fiber)) continue;
|
|
870
870
|
if (isPressableFiber(fiber)) {
|
|
871
871
|
const props = fiber.memoizedProps ?? {};
|
|
872
872
|
if (typeof props.onPress === "function" || typeof props.onPressIn === "function") {
|
|
@@ -893,7 +893,7 @@ function findTouchableFibers(item) {
|
|
|
893
893
|
const { fiber, includeSibling } = stack.pop();
|
|
894
894
|
if (!fiber || visited.has(fiber)) continue;
|
|
895
895
|
visited.add(fiber);
|
|
896
|
-
if (
|
|
896
|
+
if (chunkSUMIABJK_js.shouldSkipSubtree(fiber)) continue;
|
|
897
897
|
const props = fiber.memoizedProps ?? {};
|
|
898
898
|
if (isPressableFiber(fiber) && (typeof props.onPress === "function" || typeof props.onPressIn === "function")) {
|
|
899
899
|
found.push(fiber);
|
|
@@ -937,7 +937,7 @@ function findFirstText(fiber) {
|
|
|
937
937
|
const node = stack.pop();
|
|
938
938
|
if (!node || visited.has(node)) continue;
|
|
939
939
|
visited.add(node);
|
|
940
|
-
const typeName =
|
|
940
|
+
const typeName = chunkSUMIABJK_js.getTypeName(node.type) ?? chunkSUMIABJK_js.getTypeName(node.elementType) ?? "";
|
|
941
941
|
if (typeName === "Text") {
|
|
942
942
|
const text = textFromChildren(node.memoizedProps?.children).trim();
|
|
943
943
|
if (text) return text;
|
|
@@ -956,7 +956,7 @@ function collectTexts(fiber) {
|
|
|
956
956
|
const node = stack.pop();
|
|
957
957
|
if (!node || visited.has(node)) continue;
|
|
958
958
|
visited.add(node);
|
|
959
|
-
const typeName =
|
|
959
|
+
const typeName = chunkSUMIABJK_js.getTypeName(node.type) ?? chunkSUMIABJK_js.getTypeName(node.elementType) ?? "";
|
|
960
960
|
if (typeName === "Text") {
|
|
961
961
|
const text = textFromChildren(node.memoizedProps?.children).trim();
|
|
962
962
|
if (text) out.push(text);
|
|
@@ -968,10 +968,10 @@ function collectTexts(fiber) {
|
|
|
968
968
|
}
|
|
969
969
|
function hasUsefulTouchableIdentity(fiber) {
|
|
970
970
|
const props = fiber?.memoizedProps ?? {};
|
|
971
|
-
if (
|
|
972
|
-
if (
|
|
973
|
-
if (
|
|
974
|
-
return
|
|
971
|
+
if (chunkSUMIABJK_js.isReferenceable(props.testID)) return true;
|
|
972
|
+
if (chunkSUMIABJK_js.isReferenceable(props.accessibilityLabel)) return true;
|
|
973
|
+
if (chunkSUMIABJK_js.isReferenceable(props.label)) return true;
|
|
974
|
+
return chunkSUMIABJK_js.isReferenceable(findFirstText(fiber));
|
|
975
975
|
}
|
|
976
976
|
function describeTouchable(fiber) {
|
|
977
977
|
const props = fiber?.memoizedProps ?? {};
|
|
@@ -982,10 +982,10 @@ function describeTouchable(fiber) {
|
|
|
982
982
|
}
|
|
983
983
|
function touchableLooksDestructive(fiber) {
|
|
984
984
|
const descriptor = describeTouchable(fiber);
|
|
985
|
-
if (descriptor &&
|
|
985
|
+
if (descriptor && chunkSUMIABJK_js.looksDestructiveActionLabel(descriptor)) return true;
|
|
986
986
|
const props = fiber?.memoizedProps ?? {};
|
|
987
987
|
const haystack = [props.testID, props.accessibilityLabel, props.accessibilityHint, props.label].filter((value) => typeof value === "string").join(" ");
|
|
988
|
-
return
|
|
988
|
+
return chunkSUMIABJK_js.looksDestructiveActionLabel(haystack);
|
|
989
989
|
}
|
|
990
990
|
function describeItemCandidate(listIndex, zeroBasedIndex, item) {
|
|
991
991
|
const syntheticId = `list-${listIndex}-item-${zeroBasedIndex + 1}`;
|
|
@@ -1034,7 +1034,7 @@ function pressResolvedListItem(list, itemFiber, listIndex, itemIndex) {
|
|
|
1034
1034
|
(candidate) => candidate !== touchable && containsFiber(touchable, candidate)
|
|
1035
1035
|
);
|
|
1036
1036
|
if (primaryWrapsNestedTargets) {
|
|
1037
|
-
|
|
1037
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
1038
1038
|
`listItemDispatch: item "list-${listIndex}-item-${itemIndex}" has nested pressables; pressing outer row target`
|
|
1039
1039
|
);
|
|
1040
1040
|
} else {
|
|
@@ -1069,14 +1069,14 @@ function pressResolvedListItem(list, itemFiber, listIndex, itemIndex) {
|
|
|
1069
1069
|
}
|
|
1070
1070
|
return {
|
|
1071
1071
|
ok: true,
|
|
1072
|
-
containerType:
|
|
1072
|
+
containerType: chunkSUMIABJK_js.getTypeName(container.type) ?? chunkSUMIABJK_js.getTypeName(container.elementType) ?? list.containerType
|
|
1073
1073
|
};
|
|
1074
1074
|
} catch (err) {
|
|
1075
1075
|
return {
|
|
1076
1076
|
ok: false,
|
|
1077
1077
|
reason: "press-threw",
|
|
1078
1078
|
error: err?.message ?? "press handler threw",
|
|
1079
|
-
containerType:
|
|
1079
|
+
containerType: chunkSUMIABJK_js.getTypeName(container.type) ?? chunkSUMIABJK_js.getTypeName(container.elementType) ?? list.containerType
|
|
1080
1080
|
};
|
|
1081
1081
|
}
|
|
1082
1082
|
}
|
|
@@ -1132,7 +1132,7 @@ function candidateLists(containers, locator) {
|
|
|
1132
1132
|
return containers.map((list, listIndex) => ({ list, listIndex }));
|
|
1133
1133
|
}
|
|
1134
1134
|
function pressListItemAtOrdinal(listIndex, itemIndex) {
|
|
1135
|
-
if (!
|
|
1135
|
+
if (!chunkSUMIABJK_js.getFiberRoot()) return { ok: false, reason: "no-fiber-root" };
|
|
1136
1136
|
const containers = findListContainers({ allowSingleHeuristic: true });
|
|
1137
1137
|
if (listIndex < 0 || listIndex >= containers.length) {
|
|
1138
1138
|
return { ok: false, reason: "list-not-found" };
|
|
@@ -1146,7 +1146,7 @@ function pressListItemAtOrdinal(listIndex, itemIndex) {
|
|
|
1146
1146
|
return pressResolvedListItem(list, items[zeroBased], listIndex, itemIndex);
|
|
1147
1147
|
}
|
|
1148
1148
|
function resolveListItemByIdentity(locator) {
|
|
1149
|
-
if (!
|
|
1149
|
+
if (!chunkSUMIABJK_js.getFiberRoot()) return { ok: false, result: { ok: false, reason: "no-fiber-root" } };
|
|
1150
1150
|
const parsed = locator.syntheticId ? parseSyntheticListItemId(locator.syntheticId) : null;
|
|
1151
1151
|
const effective = parsed ? { ...locator, listIndex: parsed.listIndex, itemIndex: parsed.itemIndex } : locator;
|
|
1152
1152
|
const containers = findListContainers({ allowSingleHeuristic: true });
|
|
@@ -1207,9 +1207,9 @@ function findSwitchFibers(item) {
|
|
|
1207
1207
|
const { fiber, includeSibling } = stack.pop();
|
|
1208
1208
|
if (!fiber || visited.has(fiber)) continue;
|
|
1209
1209
|
visited.add(fiber);
|
|
1210
|
-
if (
|
|
1210
|
+
if (chunkSUMIABJK_js.shouldSkipSubtree(fiber)) continue;
|
|
1211
1211
|
const props = fiber.memoizedProps ?? {};
|
|
1212
|
-
if (
|
|
1212
|
+
if (chunkSUMIABJK_js.isSwitchLike(fiber, props)) {
|
|
1213
1213
|
if (props.__appilotsInternal !== true) found.push(fiber);
|
|
1214
1214
|
if (includeSibling && fiber.sibling) {
|
|
1215
1215
|
stack.push({ fiber: fiber.sibling, includeSibling: true });
|
|
@@ -1243,7 +1243,7 @@ function toggleListItemByIdentity(locator, options) {
|
|
|
1243
1243
|
}
|
|
1244
1244
|
const target = switches[0];
|
|
1245
1245
|
const props = target?.memoizedProps ?? {};
|
|
1246
|
-
const current =
|
|
1246
|
+
const current = chunkSUMIABJK_js.switchValue(props);
|
|
1247
1247
|
if (options?.expected !== void 0 && current === options.expected) {
|
|
1248
1248
|
return { ok: true, containerType: list.containerType, value: current, noop: true };
|
|
1249
1249
|
}
|
|
@@ -1282,7 +1282,7 @@ function screenDiagnose(targetId, category = "component-not-found") {
|
|
|
1282
1282
|
return {
|
|
1283
1283
|
category,
|
|
1284
1284
|
targetId,
|
|
1285
|
-
screen:
|
|
1285
|
+
screen: chunkSUMIABJK_js.getCurrentScreen() ?? void 0
|
|
1286
1286
|
};
|
|
1287
1287
|
}
|
|
1288
1288
|
function isPressLike(action) {
|
|
@@ -1302,10 +1302,10 @@ function elementLookupKey(value) {
|
|
|
1302
1302
|
return canonicalElementId(value).toLowerCase().replace(/[\s_]+/g, "-");
|
|
1303
1303
|
}
|
|
1304
1304
|
function findRegisteredElement(elementId) {
|
|
1305
|
-
const direct =
|
|
1305
|
+
const direct = chunkSUMIABJK_js.elementRegistry.get(elementId) ?? chunkSUMIABJK_js.elementRegistry.get(canonicalElementId(elementId));
|
|
1306
1306
|
if (direct) return direct;
|
|
1307
1307
|
const wanted = elementLookupKey(elementId);
|
|
1308
|
-
return
|
|
1308
|
+
return chunkSUMIABJK_js.elementRegistry.snapshot().find((element) => elementLookupKey(element.id) === wanted);
|
|
1309
1309
|
}
|
|
1310
1310
|
function resolveInteractionElement(elementId) {
|
|
1311
1311
|
return getLatestElement(elementId);
|
|
@@ -1425,7 +1425,7 @@ function dispatchIdentifiedToggle(targetId, action) {
|
|
|
1425
1425
|
diagnose: { ...screenDiagnose(targetId, "unknown"), recoverable: true }
|
|
1426
1426
|
};
|
|
1427
1427
|
}
|
|
1428
|
-
|
|
1428
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
1429
1429
|
`elementDispatch: "${action}" on "${targetId}" names a switch \u2014 flipping it instead of pressing, so the verb cannot land on an ancestor`
|
|
1430
1430
|
);
|
|
1431
1431
|
try {
|
|
@@ -1634,7 +1634,7 @@ function dispatchToggleElement(element, registry) {
|
|
|
1634
1634
|
}
|
|
1635
1635
|
function dispatchStructuredElementId(identifier, action) {
|
|
1636
1636
|
if (!isElementIdentifier(identifier) || !isPressLike(action)) return null;
|
|
1637
|
-
const parsed =
|
|
1637
|
+
const parsed = chunkSUMIABJK_js.parseStableElementId(identifier);
|
|
1638
1638
|
if (!parsed || parsed.role !== "option") return null;
|
|
1639
1639
|
if (!parsed.itemKey && !parsed.listId) return null;
|
|
1640
1640
|
const pressed = pressListItemByIdentity({
|
|
@@ -1644,7 +1644,7 @@ function dispatchStructuredElementId(identifier, action) {
|
|
|
1644
1644
|
texts: parsed.itemKey ? [parsed.itemKey] : void 0
|
|
1645
1645
|
});
|
|
1646
1646
|
if (pressed.ok) {
|
|
1647
|
-
|
|
1647
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
1648
1648
|
`elementDispatch: resolved stale el id "${identifier}" via structural identity (listId="${parsed.listId}", itemKey="${parsed.itemKey}")`
|
|
1649
1649
|
);
|
|
1650
1650
|
return { success: true };
|
|
@@ -1675,20 +1675,20 @@ function normalize4(value) {
|
|
|
1675
1675
|
return value.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]/g, "");
|
|
1676
1676
|
}
|
|
1677
1677
|
function resolveScreenForFormFields() {
|
|
1678
|
-
const activePath =
|
|
1678
|
+
const activePath = chunkSUMIABJK_js.getActiveRouteNames();
|
|
1679
1679
|
for (let i = activePath.length - 1; i >= 0; i--) {
|
|
1680
1680
|
const name = activePath[i];
|
|
1681
|
-
const meta = name ?
|
|
1681
|
+
const meta = name ? chunkSUMIABJK_js.getScreenMetadata(name) : void 0;
|
|
1682
1682
|
if (name && Array.isArray(meta?.fields) && meta.fields.length > 0) return name;
|
|
1683
1683
|
}
|
|
1684
|
-
return
|
|
1684
|
+
return chunkSUMIABJK_js.getCurrentScreen();
|
|
1685
1685
|
}
|
|
1686
1686
|
function collectKnownFormFields(registry) {
|
|
1687
1687
|
const registryFields = registry.snapshot().filter((entry) => entry.kind === "field" || entry.kind === "slider").map((entry) => ({ id: entry.id, label: entry.label }));
|
|
1688
1688
|
if (registryFields.length >= 2) return registryFields;
|
|
1689
1689
|
const screen = resolveScreenForFormFields();
|
|
1690
1690
|
if (screen) {
|
|
1691
|
-
const metaFields =
|
|
1691
|
+
const metaFields = chunkSUMIABJK_js.getScreenMetadata(screen)?.fields;
|
|
1692
1692
|
if (Array.isArray(metaFields) && metaFields.length > 0) {
|
|
1693
1693
|
return metaFields.filter((field) => !!field && typeof field.id === "string").map((field) => ({
|
|
1694
1694
|
id: field.id,
|
|
@@ -1698,7 +1698,7 @@ function collectKnownFormFields(registry) {
|
|
|
1698
1698
|
}));
|
|
1699
1699
|
}
|
|
1700
1700
|
}
|
|
1701
|
-
for (const meta of
|
|
1701
|
+
for (const meta of chunkSUMIABJK_js.getAllScreens()) {
|
|
1702
1702
|
if (Array.isArray(meta.fields) && meta.fields.length > 0) {
|
|
1703
1703
|
return meta.fields.filter((field) => !!field && typeof field.id === "string").map((field) => ({
|
|
1704
1704
|
id: field.id,
|
|
@@ -1811,7 +1811,7 @@ function rewriteMisplacedFormFillFields(fields, registry) {
|
|
|
1811
1811
|
const inferred = inferFieldIdForValue(String(field.value ?? ""), knownFields, used);
|
|
1812
1812
|
if (!inferred) return field;
|
|
1813
1813
|
used.add(inferred);
|
|
1814
|
-
|
|
1814
|
+
chunkSUMIABJK_js.appilotsDebugWarn(
|
|
1815
1815
|
`formFieldRewrite: ${field.fieldId} \u2192 ${inferred} (value=${JSON.stringify(field.value)})`
|
|
1816
1816
|
);
|
|
1817
1817
|
return { ...field, fieldId: inferred };
|
|
@@ -1819,8 +1819,8 @@ function rewriteMisplacedFormFillFields(fields, registry) {
|
|
|
1819
1819
|
}
|
|
1820
1820
|
|
|
1821
1821
|
// src/executor/formValidation.ts
|
|
1822
|
-
var FORM_VALIDATION_TEXT_RE2 =
|
|
1823
|
-
var FORM_SUCCESS_TEXT_RE =
|
|
1822
|
+
var FORM_VALIDATION_TEXT_RE2 = chunkSUMIABJK_js.FORM_VALIDATION_TEXT_RE;
|
|
1823
|
+
var FORM_SUCCESS_TEXT_RE = chunkSUMIABJK_js.FORM_WRITE_SUCCESS_TEXT_RE;
|
|
1824
1824
|
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1825
1825
|
function inferValidationFieldId(message, inputs) {
|
|
1826
1826
|
const haystack = normalizeText(message);
|
|
@@ -1857,7 +1857,7 @@ function readVisibleFormSuccess(snap) {
|
|
|
1857
1857
|
return (snap.texts ?? []).find((text) => text?.trim() && FORM_SUCCESS_TEXT_RE.test(text));
|
|
1858
1858
|
}
|
|
1859
1859
|
function submitAsyncStillPending(submitTargetId) {
|
|
1860
|
-
const probe =
|
|
1860
|
+
const probe = chunkSUMIABJK_js.probeLoadingState(submitTargetId ?? null, chunkSUMIABJK_js.getCurrentScreen());
|
|
1861
1861
|
if (probe.loading) return true;
|
|
1862
1862
|
if (submitTargetId && probe.pressedFound && probe.pressedDisabled) return true;
|
|
1863
1863
|
return false;
|
|
@@ -1869,7 +1869,7 @@ function evaluatePostSubmitSnapshot(snap, activePath) {
|
|
|
1869
1869
|
}
|
|
1870
1870
|
const successText = readVisibleFormSuccess(snap);
|
|
1871
1871
|
if (successText) return { status: "success", message: successText };
|
|
1872
|
-
if (!
|
|
1872
|
+
if (!chunkSUMIABJK_js.snapshotShowsOpenCreateForm(snap, activePath)) {
|
|
1873
1873
|
return { status: "success" };
|
|
1874
1874
|
}
|
|
1875
1875
|
return void 0;
|
|
@@ -1885,7 +1885,7 @@ async function waitForPostSubmitOutcome(options) {
|
|
|
1885
1885
|
continue;
|
|
1886
1886
|
}
|
|
1887
1887
|
const snap2 = captureSnapshot();
|
|
1888
|
-
const activePath2 =
|
|
1888
|
+
const activePath2 = chunkSUMIABJK_js.getActiveRouteNames();
|
|
1889
1889
|
const outcome2 = evaluatePostSubmitSnapshot(snap2, activePath2);
|
|
1890
1890
|
if (outcome2) return outcome2;
|
|
1891
1891
|
await sleep(pollMs);
|
|
@@ -1897,7 +1897,7 @@ async function waitForPostSubmitOutcome(options) {
|
|
|
1897
1897
|
};
|
|
1898
1898
|
}
|
|
1899
1899
|
const snap = captureSnapshot();
|
|
1900
|
-
const activePath =
|
|
1900
|
+
const activePath = chunkSUMIABJK_js.getActiveRouteNames();
|
|
1901
1901
|
const outcome = evaluatePostSubmitSnapshot(snap, activePath);
|
|
1902
1902
|
if (outcome) return outcome;
|
|
1903
1903
|
return {
|
|
@@ -2003,16 +2003,16 @@ function findSnapshotButton(targetId) {
|
|
|
2003
2003
|
}
|
|
2004
2004
|
}
|
|
2005
2005
|
function buildUiDiagnose(targetId, cause) {
|
|
2006
|
-
const activePath =
|
|
2007
|
-
const screen = activePath[activePath.length - 1] ??
|
|
2006
|
+
const activePath = chunkSUMIABJK_js.getActiveRouteNames();
|
|
2007
|
+
const screen = activePath[activePath.length - 1] ?? chunkSUMIABJK_js.getCurrentScreen() ?? void 0;
|
|
2008
2008
|
const screenPath = activePath.length > 1 ? activePath.join("/") : screen;
|
|
2009
2009
|
const diagnose = {
|
|
2010
2010
|
category: cause === "not-found" ? "component-not-found" : cause === "disabled" ? "disabled" : "unknown",
|
|
2011
2011
|
targetId,
|
|
2012
2012
|
screen: screenPath
|
|
2013
2013
|
};
|
|
2014
|
-
if (
|
|
2015
|
-
diagnose.visibleMessage =
|
|
2014
|
+
if (chunkSUMIABJK_js.isOptionalStepAutomationFailure(targetId, screenPath, activePath)) {
|
|
2015
|
+
diagnose.visibleMessage = chunkSUMIABJK_js.OPTIONAL_STEP_AUTOMATION_HINT;
|
|
2016
2016
|
diagnose.recoverable = true;
|
|
2017
2017
|
}
|
|
2018
2018
|
return diagnose;
|
|
@@ -2070,15 +2070,15 @@ function resolveComponentId(componentId, registry, action) {
|
|
|
2070
2070
|
const snapshot = registry.snapshot();
|
|
2071
2071
|
for (const comp of snapshot) {
|
|
2072
2072
|
if (comp.id.toLowerCase() === lower) {
|
|
2073
|
-
|
|
2073
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
2074
2074
|
`resolveComponentId: case-insensitive match "${componentId}" \u2192 "${comp.id}"`
|
|
2075
2075
|
);
|
|
2076
2076
|
return comp.id;
|
|
2077
2077
|
}
|
|
2078
2078
|
}
|
|
2079
|
-
const currentScreen =
|
|
2079
|
+
const currentScreen = chunkSUMIABJK_js.getCurrentScreen();
|
|
2080
2080
|
if (currentScreen) {
|
|
2081
|
-
const screenMeta =
|
|
2081
|
+
const screenMeta = chunkSUMIABJK_js.getScreenMetadata(currentScreen);
|
|
2082
2082
|
const actions = screenMeta?.actions;
|
|
2083
2083
|
if (actions && Array.isArray(actions)) {
|
|
2084
2084
|
const metaAction = actions.find(
|
|
@@ -2087,14 +2087,14 @@ function resolveComponentId(componentId, registry, action) {
|
|
|
2087
2087
|
if (metaAction && typeof metaAction === "object" && metaAction.label) {
|
|
2088
2088
|
const metaLabel = metaAction.label;
|
|
2089
2089
|
const normalizedMetaLabel = metaLabel.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]/g, "");
|
|
2090
|
-
|
|
2090
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
2091
2091
|
`resolveComponentId: found screen metadata for "${componentId}" \u2192 label="${metaLabel}"`
|
|
2092
2092
|
);
|
|
2093
2093
|
for (const comp of snapshot) {
|
|
2094
2094
|
if (!comp.label) continue;
|
|
2095
2095
|
const compLabel = comp.label.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]/g, "");
|
|
2096
2096
|
if (compLabel === normalizedMetaLabel || compLabel.includes(normalizedMetaLabel) || normalizedMetaLabel.includes(compLabel)) {
|
|
2097
|
-
|
|
2097
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
2098
2098
|
`resolveComponentId: FOUND via metadata: "${componentId}" \u2192 "${comp.id}" (label="${comp.label}")`
|
|
2099
2099
|
);
|
|
2100
2100
|
return comp.id;
|
|
@@ -2111,7 +2111,7 @@ function resolveComponentId(componentId, registry, action) {
|
|
|
2111
2111
|
}));
|
|
2112
2112
|
const match = resolveTarget(componentId, candidates, { action });
|
|
2113
2113
|
if (match.status === "matched") {
|
|
2114
|
-
|
|
2114
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
2115
2115
|
`resolveComponentId: matched "${componentId}" -> "${match.id}" (tier=${match.tier})`
|
|
2116
2116
|
);
|
|
2117
2117
|
return match.id;
|
|
@@ -2201,7 +2201,7 @@ function setValueHandler(rawComponentId, requested, registry) {
|
|
|
2201
2201
|
try {
|
|
2202
2202
|
slider.setValue(applied);
|
|
2203
2203
|
if (applied !== requestedValue) {
|
|
2204
|
-
|
|
2204
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
2205
2205
|
`uiInteractionHandler: set_value snapped ${requestedValue} \u2192 ${applied} for "${componentId}" (step=${step})`
|
|
2206
2206
|
);
|
|
2207
2207
|
}
|
|
@@ -2236,7 +2236,7 @@ function checkModalOcclusion(rawComponentId, action) {
|
|
|
2236
2236
|
return null;
|
|
2237
2237
|
}
|
|
2238
2238
|
if (typeof rawComponentId !== "string" || rawComponentId.trim().length === 0) return null;
|
|
2239
|
-
const dialog =
|
|
2239
|
+
const dialog = chunkSUMIABJK_js.getOpenNativeDialog();
|
|
2240
2240
|
if (dialog) {
|
|
2241
2241
|
const needle = normalizeIdent(rawComponentId);
|
|
2242
2242
|
if (dialog.buttons.some((b) => normalizeIdent(b.label) === needle)) return null;
|
|
@@ -2246,16 +2246,16 @@ function checkModalOcclusion(rawComponentId, action) {
|
|
|
2246
2246
|
diagnose: {
|
|
2247
2247
|
category: "ambiguous-target",
|
|
2248
2248
|
targetId: rawComponentId,
|
|
2249
|
-
screen:
|
|
2249
|
+
screen: chunkSUMIABJK_js.getCurrentScreen() ?? void 0,
|
|
2250
2250
|
candidates: dialog.buttons.map((b) => b.label).slice(0, 8)
|
|
2251
2251
|
}
|
|
2252
2252
|
};
|
|
2253
2253
|
}
|
|
2254
|
-
const fiberRoot =
|
|
2254
|
+
const fiberRoot = chunkSUMIABJK_js.getFiberRoot();
|
|
2255
2255
|
if (!fiberRoot) return null;
|
|
2256
2256
|
let snap;
|
|
2257
2257
|
try {
|
|
2258
|
-
snap =
|
|
2258
|
+
snap = chunkSUMIABJK_js.walkFiber(fiberRoot);
|
|
2259
2259
|
} catch {
|
|
2260
2260
|
return null;
|
|
2261
2261
|
}
|
|
@@ -2317,7 +2317,7 @@ function checkModalOcclusion(rawComponentId, action) {
|
|
|
2317
2317
|
}
|
|
2318
2318
|
function uiInteractionHandler(payload, context) {
|
|
2319
2319
|
const { permissions } = context;
|
|
2320
|
-
const registry = context.registry ??
|
|
2320
|
+
const registry = context.registry ?? chunkSUMIABJK_js.componentRegistry;
|
|
2321
2321
|
if (!permissions.canInteractUI) {
|
|
2322
2322
|
return {
|
|
2323
2323
|
success: false,
|
|
@@ -2339,7 +2339,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2339
2339
|
if (sliderId) {
|
|
2340
2340
|
const smuggled = payload.value ?? payload.params?.value;
|
|
2341
2341
|
if (smuggled !== void 0) {
|
|
2342
|
-
|
|
2342
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
2343
2343
|
`uiInteractionHandler: "${actionStr}" on slider "${sliderId}" carried value=${JSON.stringify(smuggled)} \u2014 routing to set_value`
|
|
2344
2344
|
);
|
|
2345
2345
|
return setValueHandler(rawComponentId, smuggled, registry);
|
|
@@ -2350,23 +2350,23 @@ function uiInteractionHandler(payload, context) {
|
|
|
2350
2350
|
diagnose: { ...buildUiDiagnose(sliderId, "unknown"), recoverable: true }
|
|
2351
2351
|
};
|
|
2352
2352
|
}
|
|
2353
|
-
const openDialog =
|
|
2353
|
+
const openDialog = chunkSUMIABJK_js.getOpenNativeDialog();
|
|
2354
2354
|
const isPressVerb = actionStr === "press" || actionStr === "tap" || actionStr === "click";
|
|
2355
2355
|
if (openDialog && isPressVerb) {
|
|
2356
2356
|
const needle = normalizeIdent(rawComponentId);
|
|
2357
2357
|
const button = openDialog.buttons.find((b) => normalizeIdent(b.label) === needle);
|
|
2358
2358
|
if (button) {
|
|
2359
2359
|
button.press();
|
|
2360
|
-
|
|
2360
|
+
chunkSUMIABJK_js.appilotsDebugLog(`uiInteractionHandler: pressed native dialog button "${button.label}"`);
|
|
2361
2361
|
return { success: true, effect: "changed" };
|
|
2362
2362
|
}
|
|
2363
2363
|
}
|
|
2364
2364
|
if (!openDialog && isPressVerb) {
|
|
2365
|
-
const answered =
|
|
2365
|
+
const answered = chunkSUMIABJK_js.getLastAnsweredNativeDialog();
|
|
2366
2366
|
const needle = normalizeIdent(rawComponentId);
|
|
2367
2367
|
if (answered && needle) {
|
|
2368
2368
|
if (answered.answeredWith && normalizeIdent(answered.answeredWith) === needle) {
|
|
2369
|
-
|
|
2369
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
2370
2370
|
`uiInteractionHandler: native dialog button "${answered.answeredWith}" was already pressed and the dialog is closed \u2014 treating the repeat as done`
|
|
2371
2371
|
);
|
|
2372
2372
|
return { success: true, effect: "completed" };
|
|
@@ -2378,7 +2378,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2378
2378
|
diagnose: {
|
|
2379
2379
|
category: "component-not-found",
|
|
2380
2380
|
targetId: rawComponentId,
|
|
2381
|
-
screen:
|
|
2381
|
+
screen: chunkSUMIABJK_js.getCurrentScreen() ?? void 0,
|
|
2382
2382
|
recoverable: false
|
|
2383
2383
|
}
|
|
2384
2384
|
};
|
|
@@ -2387,7 +2387,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2387
2387
|
}
|
|
2388
2388
|
const occluded = checkModalOcclusion(rawComponentId, actionStr);
|
|
2389
2389
|
if (occluded) {
|
|
2390
|
-
|
|
2390
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
2391
2391
|
`uiInteractionHandler: blocked "${actionStr}" on "${rawComponentId}" \u2014 target is behind an open modal`
|
|
2392
2392
|
);
|
|
2393
2393
|
return occluded;
|
|
@@ -2395,7 +2395,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2395
2395
|
if (typeof rawComponentId === "string" && rawComponentId.trim().toLowerCase().startsWith("el:")) {
|
|
2396
2396
|
const result = dispatchElementOrTarget(rawComponentId, registry, actionStr);
|
|
2397
2397
|
if (result.success) {
|
|
2398
|
-
|
|
2398
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
2399
2399
|
`uiInteractionHandler: interaction element dispatch succeeded for "${rawComponentId}"`
|
|
2400
2400
|
);
|
|
2401
2401
|
}
|
|
@@ -2403,17 +2403,17 @@ function uiInteractionHandler(payload, context) {
|
|
|
2403
2403
|
}
|
|
2404
2404
|
const ordinal = parseSyntheticListItemId(rawComponentId);
|
|
2405
2405
|
if (ordinal && (action === "press" || actionStr === "tap" || actionStr === "click" || actionStr === "longPress")) {
|
|
2406
|
-
|
|
2406
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
2407
2407
|
`uiInteractionHandler: dispatching synthetic list ordinal \u2014 componentId="${rawComponentId}" list=${ordinal.listIndex} item=${ordinal.itemIndex}`
|
|
2408
2408
|
);
|
|
2409
2409
|
const result = pressListItemAtOrdinal(ordinal.listIndex, ordinal.itemIndex);
|
|
2410
2410
|
if (result.ok) {
|
|
2411
|
-
|
|
2411
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
2412
2412
|
`uiInteractionHandler: synthetic ordinal press succeeded (container=${result.containerType ?? "List"})`
|
|
2413
2413
|
);
|
|
2414
2414
|
return { success: true };
|
|
2415
2415
|
}
|
|
2416
|
-
const screen =
|
|
2416
|
+
const screen = chunkSUMIABJK_js.getCurrentScreen() ?? void 0;
|
|
2417
2417
|
if (result.reason === "list-not-found" || result.reason === "item-not-found") {
|
|
2418
2418
|
return {
|
|
2419
2419
|
success: false,
|
|
@@ -2454,7 +2454,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2454
2454
|
};
|
|
2455
2455
|
}
|
|
2456
2456
|
const componentId = resolveComponentId(rawComponentId, registry, actionStr);
|
|
2457
|
-
|
|
2457
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
2458
2458
|
`uiInteractionHandler: resolved componentId="${payload.componentId}" \u2192 "${componentId}"`
|
|
2459
2459
|
);
|
|
2460
2460
|
const target = registry.getTarget(componentId);
|
|
@@ -2507,7 +2507,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2507
2507
|
return { success: false, error: err?.message ?? "Focus failed" };
|
|
2508
2508
|
}
|
|
2509
2509
|
}
|
|
2510
|
-
|
|
2510
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
2511
2511
|
`uiInteractionHandler: registry miss for "${componentId}", falling back to fiber tree`
|
|
2512
2512
|
);
|
|
2513
2513
|
const namedToggle = dispatchIdentifiedToggle(componentId, actionStr);
|
|
@@ -2519,7 +2519,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2519
2519
|
try {
|
|
2520
2520
|
if (actionStr === "press" && handle.kind === "target" && handle.press) {
|
|
2521
2521
|
handle.press();
|
|
2522
|
-
|
|
2522
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
2523
2523
|
`uiInteractionHandler: fiber fallback press succeeded for "${componentId}"`
|
|
2524
2524
|
);
|
|
2525
2525
|
return { success: true };
|
|
@@ -2582,7 +2582,7 @@ function submitLabelHintsSubmit(label) {
|
|
|
2582
2582
|
return SUBMIT_LABEL_HINT_RE.test(trimmed);
|
|
2583
2583
|
}
|
|
2584
2584
|
function screenDeclaresSubmitAction(screenName) {
|
|
2585
|
-
const meta =
|
|
2585
|
+
const meta = chunkSUMIABJK_js.getScreenMetadata(screenName);
|
|
2586
2586
|
return Array.isArray(meta?.actions) && meta.actions.some(
|
|
2587
2587
|
(action) => typeof action === "object" && action !== null && action.type === "submit"
|
|
2588
2588
|
);
|
|
@@ -2615,7 +2615,7 @@ function resolveFormScreensForSubmit(screen, activePath, registry) {
|
|
|
2615
2615
|
} else {
|
|
2616
2616
|
push(screen);
|
|
2617
2617
|
}
|
|
2618
|
-
push(
|
|
2618
|
+
push(chunkSUMIABJK_js.getCurrentScreen() ?? void 0);
|
|
2619
2619
|
const withSubmit = [];
|
|
2620
2620
|
const rest = [];
|
|
2621
2621
|
for (const name of ordered) {
|
|
@@ -2633,7 +2633,7 @@ function collectSubmitTargetCandidates(screens, registry) {
|
|
|
2633
2633
|
candidates.push(id);
|
|
2634
2634
|
};
|
|
2635
2635
|
for (const screenName of screens) {
|
|
2636
|
-
const meta =
|
|
2636
|
+
const meta = chunkSUMIABJK_js.getScreenMetadata(screenName);
|
|
2637
2637
|
const submitMeta = Array.isArray(meta?.actions) ? meta.actions.find(
|
|
2638
2638
|
(action) => typeof action === "object" && action !== null && action.type === "submit"
|
|
2639
2639
|
) : void 0;
|
|
@@ -2677,8 +2677,8 @@ function readVisibleValidation(fieldId, label) {
|
|
|
2677
2677
|
return void 0;
|
|
2678
2678
|
}
|
|
2679
2679
|
function resolveScreenContext() {
|
|
2680
|
-
const activePath =
|
|
2681
|
-
const screen = activePath[activePath.length - 1] ??
|
|
2680
|
+
const activePath = chunkSUMIABJK_js.getActiveRouteNames();
|
|
2681
|
+
const screen = activePath[activePath.length - 1] ?? chunkSUMIABJK_js.getCurrentScreen() ?? void 0;
|
|
2682
2682
|
return { screen, activePath };
|
|
2683
2683
|
}
|
|
2684
2684
|
function selectValueApplied(fieldId, requestedValue, currentValue, registry) {
|
|
@@ -2686,36 +2686,36 @@ function selectValueApplied(fieldId, requestedValue, currentValue, registry) {
|
|
|
2686
2686
|
if (!requested) return false;
|
|
2687
2687
|
const meta = getMetadataField(fieldId, registry);
|
|
2688
2688
|
const options = Array.isArray(meta?.options) ? meta.options : [];
|
|
2689
|
-
const requestedNorm =
|
|
2690
|
-
const currentNorm =
|
|
2689
|
+
const requestedNorm = chunkSUMIABJK_js.normalize3(requested);
|
|
2690
|
+
const currentNorm = chunkSUMIABJK_js.normalize3(currentValue);
|
|
2691
2691
|
if (currentNorm === requestedNorm) return true;
|
|
2692
2692
|
for (const option of options) {
|
|
2693
2693
|
const value = typeof option?.value === "string" ? option.value : "";
|
|
2694
2694
|
const label = typeof option?.label === "string" ? option.label : "";
|
|
2695
|
-
if (
|
|
2696
|
-
if (
|
|
2697
|
-
if (
|
|
2695
|
+
if (chunkSUMIABJK_js.normalize3(value) === requestedNorm && chunkSUMIABJK_js.normalize3(label) === currentNorm) return true;
|
|
2696
|
+
if (chunkSUMIABJK_js.normalize3(label) === requestedNorm && chunkSUMIABJK_js.normalize3(label) === currentNorm) return true;
|
|
2697
|
+
if (chunkSUMIABJK_js.normalize3(value) === requestedNorm && chunkSUMIABJK_js.normalize3(value) === currentNorm) return true;
|
|
2698
2698
|
}
|
|
2699
2699
|
return false;
|
|
2700
2700
|
}
|
|
2701
2701
|
function getMetadataField(fieldId, registry) {
|
|
2702
2702
|
const screens = /* @__PURE__ */ new Set();
|
|
2703
|
-
for (const name of
|
|
2704
|
-
const current =
|
|
2703
|
+
for (const name of chunkSUMIABJK_js.getActiveRouteNames()) screens.add(name);
|
|
2704
|
+
const current = chunkSUMIABJK_js.getCurrentScreen();
|
|
2705
2705
|
if (current) screens.add(current);
|
|
2706
2706
|
if (registry) {
|
|
2707
2707
|
for (const comp of registry.snapshot()) {
|
|
2708
2708
|
if (comp.kind === "field" && comp.screen) screens.add(comp.screen);
|
|
2709
2709
|
}
|
|
2710
2710
|
}
|
|
2711
|
-
const needle =
|
|
2711
|
+
const needle = chunkSUMIABJK_js.normalize3(fieldId);
|
|
2712
2712
|
for (const screenName of screens) {
|
|
2713
|
-
const screenMeta =
|
|
2713
|
+
const screenMeta = chunkSUMIABJK_js.getScreenMetadata(screenName);
|
|
2714
2714
|
const fields = Array.isArray(screenMeta?.fields) ? screenMeta.fields : [];
|
|
2715
2715
|
const match = fields.find((field) => {
|
|
2716
2716
|
if (!field || typeof field !== "object") return false;
|
|
2717
|
-
const id = typeof field.id === "string" ?
|
|
2718
|
-
const label = typeof field.label === "string" ?
|
|
2717
|
+
const id = typeof field.id === "string" ? chunkSUMIABJK_js.normalize3(field.id) : "";
|
|
2718
|
+
const label = typeof field.label === "string" ? chunkSUMIABJK_js.normalize3(field.label) : "";
|
|
2719
2719
|
return id === needle || label === needle;
|
|
2720
2720
|
});
|
|
2721
2721
|
if (match) return match;
|
|
@@ -2727,11 +2727,11 @@ function resolveSelectOption(fieldId, value, registry) {
|
|
|
2727
2727
|
if (!requested) return void 0;
|
|
2728
2728
|
const meta = getMetadataField(fieldId, registry);
|
|
2729
2729
|
const options = Array.isArray(meta?.options) ? meta.options : [];
|
|
2730
|
-
const requestedNorm =
|
|
2730
|
+
const requestedNorm = chunkSUMIABJK_js.normalize3(requested);
|
|
2731
2731
|
for (const option of options) {
|
|
2732
2732
|
const optionValue = typeof option?.value === "string" ? option.value : "";
|
|
2733
2733
|
const optionLabel = typeof option?.label === "string" ? option.label : "";
|
|
2734
|
-
if (
|
|
2734
|
+
if (chunkSUMIABJK_js.normalize3(optionValue) === requestedNorm || chunkSUMIABJK_js.normalize3(optionLabel) === requestedNorm) {
|
|
2735
2735
|
return { value: optionValue, label: optionLabel };
|
|
2736
2736
|
}
|
|
2737
2737
|
}
|
|
@@ -2781,12 +2781,12 @@ async function tryPressSelectOption(fieldId, value, registry, options = {}) {
|
|
|
2781
2781
|
return {
|
|
2782
2782
|
success: false,
|
|
2783
2783
|
error: `No pressable option found for select field "${fieldId}"`,
|
|
2784
|
-
diagnose: { category: "component-not-found", fieldId, screen:
|
|
2784
|
+
diagnose: { category: "component-not-found", fieldId, screen: chunkSUMIABJK_js.getCurrentScreen() ?? void 0 }
|
|
2785
2785
|
};
|
|
2786
2786
|
}
|
|
2787
2787
|
function normalizeFieldType(type) {
|
|
2788
2788
|
if (typeof type !== "string") return void 0;
|
|
2789
|
-
const normalized =
|
|
2789
|
+
const normalized = chunkSUMIABJK_js.normalize3(type);
|
|
2790
2790
|
if (normalized === "select" || normalized === "picker" || normalized === "dropdown")
|
|
2791
2791
|
return "select";
|
|
2792
2792
|
if (normalized === "toggle" || normalized === "switch" || normalized === "checkbox")
|
|
@@ -2816,7 +2816,7 @@ function fieldCueTerms(fieldId, label) {
|
|
|
2816
2816
|
);
|
|
2817
2817
|
const terms = /* @__PURE__ */ new Set();
|
|
2818
2818
|
for (const value of raw) {
|
|
2819
|
-
const normalized =
|
|
2819
|
+
const normalized = chunkSUMIABJK_js.normalize3(value);
|
|
2820
2820
|
if (normalized.length >= 3 && normalized !== "id") terms.add(normalized);
|
|
2821
2821
|
}
|
|
2822
2822
|
return [...terms];
|
|
@@ -2824,17 +2824,17 @@ function fieldCueTerms(fieldId, label) {
|
|
|
2824
2824
|
function snapshotHasFieldCue(snap, fieldId, label) {
|
|
2825
2825
|
const terms = fieldCueTerms(fieldId, label);
|
|
2826
2826
|
if (terms.length === 0) return false;
|
|
2827
|
-
const visible = [...snap.texts ?? [], ...(snap.buttons ?? []).map((b) => b.label ?? b.id ?? "")].map((text) =>
|
|
2827
|
+
const visible = [...snap.texts ?? [], ...(snap.buttons ?? []).map((b) => b.label ?? b.id ?? "")].map((text) => chunkSUMIABJK_js.normalize3(text)).filter(Boolean);
|
|
2828
2828
|
return visible.some((text) => terms.some((term) => text.includes(term) || term.includes(text)));
|
|
2829
2829
|
}
|
|
2830
2830
|
function scoreCandidateText(value, texts) {
|
|
2831
|
-
const valueNorm =
|
|
2831
|
+
const valueNorm = chunkSUMIABJK_js.normalize3(String(value ?? ""));
|
|
2832
2832
|
if (!valueNorm) return 0;
|
|
2833
2833
|
let best = 0;
|
|
2834
2834
|
for (const text of texts) {
|
|
2835
|
-
const textNorm =
|
|
2835
|
+
const textNorm = chunkSUMIABJK_js.normalize3(text);
|
|
2836
2836
|
if (!textNorm) continue;
|
|
2837
|
-
best = Math.max(best,
|
|
2837
|
+
best = Math.max(best, chunkSUMIABJK_js.matchScore(valueNorm, textNorm));
|
|
2838
2838
|
}
|
|
2839
2839
|
return best;
|
|
2840
2840
|
}
|
|
@@ -2848,7 +2848,7 @@ function optionTexts(option) {
|
|
|
2848
2848
|
function buildChoiceCandidates(snap, fieldId, value, allowFirstVisibleWhenNoCue, registry) {
|
|
2849
2849
|
const fieldLabel = getFieldLabel(fieldId, registry);
|
|
2850
2850
|
const fieldCueVisible = snapshotHasFieldCue(snap, fieldId, fieldLabel);
|
|
2851
|
-
const genericValue =
|
|
2851
|
+
const genericValue = chunkSUMIABJK_js.isGenericSelectValue(value);
|
|
2852
2852
|
const candidates = [];
|
|
2853
2853
|
let order = 0;
|
|
2854
2854
|
const choiceGroups = snap.choiceGroups ?? [];
|
|
@@ -2860,7 +2860,7 @@ function buildChoiceCandidates(snap, fieldId, value, allowFirstVisibleWhenNoCue,
|
|
|
2860
2860
|
const groupCueScore = Math.max(
|
|
2861
2861
|
globalCueScore,
|
|
2862
2862
|
...groupTexts.map((text) => {
|
|
2863
|
-
const normalized =
|
|
2863
|
+
const normalized = chunkSUMIABJK_js.normalize3(text);
|
|
2864
2864
|
return fieldCueTerms(fieldId, fieldLabel).some(
|
|
2865
2865
|
(term) => normalized.includes(term) || term.includes(normalized)
|
|
2866
2866
|
) ? 80 : 0;
|
|
@@ -2897,7 +2897,7 @@ function buildChoiceCandidates(snap, fieldId, value, allowFirstVisibleWhenNoCue,
|
|
|
2897
2897
|
const elementCueScore = Math.max(
|
|
2898
2898
|
fieldCueVisible && elements.length <= 12 ? 50 : 0,
|
|
2899
2899
|
...cueTexts.map((text) => {
|
|
2900
|
-
const normalized =
|
|
2900
|
+
const normalized = chunkSUMIABJK_js.normalize3(text);
|
|
2901
2901
|
return fieldTerms.some((term) => normalized.includes(term) || term.includes(normalized)) ? 80 : 0;
|
|
2902
2902
|
})
|
|
2903
2903
|
);
|
|
@@ -2955,7 +2955,7 @@ async function selectVisibleChoiceAsync(fieldId, value, registry, options) {
|
|
|
2955
2955
|
return {
|
|
2956
2956
|
success: false,
|
|
2957
2957
|
error: err?.message ?? "Could not capture visible choices",
|
|
2958
|
-
diagnose: { category: "unknown", fieldId, screen:
|
|
2958
|
+
diagnose: { category: "unknown", fieldId, screen: chunkSUMIABJK_js.getCurrentScreen() ?? void 0 }
|
|
2959
2959
|
};
|
|
2960
2960
|
}
|
|
2961
2961
|
const candidates = buildChoiceCandidates(
|
|
@@ -2973,7 +2973,7 @@ async function selectVisibleChoiceAsync(fieldId, value, registry, options) {
|
|
|
2973
2973
|
diagnose: {
|
|
2974
2974
|
category: "component-not-found",
|
|
2975
2975
|
fieldId,
|
|
2976
|
-
screen:
|
|
2976
|
+
screen: chunkSUMIABJK_js.getCurrentScreen() ?? void 0
|
|
2977
2977
|
}
|
|
2978
2978
|
};
|
|
2979
2979
|
}
|
|
@@ -2987,7 +2987,7 @@ async function selectVisibleChoiceAsync(fieldId, value, registry, options) {
|
|
|
2987
2987
|
}
|
|
2988
2988
|
function isContinuationButton(label) {
|
|
2989
2989
|
if (!label) return false;
|
|
2990
|
-
return /^(next|continue|proximo|prox|continuar|avancar|avançar)$/i.test(
|
|
2990
|
+
return /^(next|continue|proximo|prox|continuar|avancar|avançar)$/i.test(chunkSUMIABJK_js.normalize3(label));
|
|
2991
2991
|
}
|
|
2992
2992
|
function pressContinuationButton(registry) {
|
|
2993
2993
|
const snap = captureSnapshot();
|
|
@@ -3000,40 +3000,40 @@ function pressContinuationButton(registry) {
|
|
|
3000
3000
|
return {
|
|
3001
3001
|
success: false,
|
|
3002
3002
|
error: "No enabled continuation button is visible",
|
|
3003
|
-
diagnose: { category: "component-not-found", screen:
|
|
3003
|
+
diagnose: { category: "component-not-found", screen: chunkSUMIABJK_js.getCurrentScreen() ?? void 0 }
|
|
3004
3004
|
};
|
|
3005
3005
|
}
|
|
3006
3006
|
return pressTargetByIdOrLabel(id, registry);
|
|
3007
3007
|
}
|
|
3008
3008
|
function findField(fieldId, registry) {
|
|
3009
|
-
|
|
3009
|
+
chunkSUMIABJK_js.appilotsDebugLog(`findField: searching for fieldId="${fieldId}"`);
|
|
3010
3010
|
const exact = registry.getField(fieldId);
|
|
3011
3011
|
if (exact) {
|
|
3012
|
-
|
|
3012
|
+
chunkSUMIABJK_js.appilotsDebugLog(`findField: FOUND exact match for fieldId="${fieldId}"`);
|
|
3013
3013
|
return exact;
|
|
3014
3014
|
}
|
|
3015
3015
|
const lower = fieldId.toLowerCase();
|
|
3016
3016
|
const snapshot = registry.snapshot();
|
|
3017
3017
|
for (const comp of snapshot) {
|
|
3018
3018
|
if (comp.kind === "field" && comp.id.toLowerCase() === lower) {
|
|
3019
|
-
|
|
3019
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
3020
3020
|
`findField: FOUND case-insensitive match: registered="${comp.id}" for searched="${fieldId}"`
|
|
3021
3021
|
);
|
|
3022
3022
|
return registry.getField(comp.id);
|
|
3023
3023
|
}
|
|
3024
3024
|
}
|
|
3025
|
-
const currentScreenForTieBreak =
|
|
3026
|
-
const needle =
|
|
3025
|
+
const currentScreenForTieBreak = chunkSUMIABJK_js.getCurrentScreen();
|
|
3026
|
+
const needle = chunkSUMIABJK_js.normalize3(fieldId);
|
|
3027
3027
|
let bestComp;
|
|
3028
3028
|
let bestScore = 0;
|
|
3029
3029
|
let bestOnCurrentScreen = false;
|
|
3030
3030
|
for (const comp of snapshot) {
|
|
3031
3031
|
if (comp.kind !== "field") continue;
|
|
3032
|
-
const candidates = [
|
|
3033
|
-
if (comp.label) candidates.push(
|
|
3032
|
+
const candidates = [chunkSUMIABJK_js.normalize3(comp.id)];
|
|
3033
|
+
if (comp.label) candidates.push(chunkSUMIABJK_js.normalize3(comp.label));
|
|
3034
3034
|
let candidateScore = 0;
|
|
3035
3035
|
for (const cand of candidates) {
|
|
3036
|
-
const s =
|
|
3036
|
+
const s = chunkSUMIABJK_js.matchScore(needle, cand);
|
|
3037
3037
|
if (s > candidateScore) candidateScore = s;
|
|
3038
3038
|
}
|
|
3039
3039
|
if (candidateScore === 0) continue;
|
|
@@ -3046,14 +3046,14 @@ function findField(fieldId, registry) {
|
|
|
3046
3046
|
}
|
|
3047
3047
|
}
|
|
3048
3048
|
if (bestComp && bestScore >= 75) {
|
|
3049
|
-
|
|
3049
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
3050
3050
|
`findField: scored match "${fieldId}" -> "${bestComp.id}" (label="${bestComp.label}", score=${bestScore})`
|
|
3051
3051
|
);
|
|
3052
3052
|
return registry.getField(bestComp.id);
|
|
3053
3053
|
}
|
|
3054
|
-
const currentScreen =
|
|
3054
|
+
const currentScreen = chunkSUMIABJK_js.getCurrentScreen();
|
|
3055
3055
|
if (currentScreen) {
|
|
3056
|
-
const screenMeta =
|
|
3056
|
+
const screenMeta = chunkSUMIABJK_js.getScreenMetadata(currentScreen);
|
|
3057
3057
|
const fields = screenMeta?.fields;
|
|
3058
3058
|
if (fields && Array.isArray(fields)) {
|
|
3059
3059
|
const metaField = fields.find(
|
|
@@ -3061,19 +3061,19 @@ function findField(fieldId, registry) {
|
|
|
3061
3061
|
);
|
|
3062
3062
|
if (metaField && typeof metaField === "object" && metaField.label) {
|
|
3063
3063
|
const metaLabel = metaField.label;
|
|
3064
|
-
const metaNeedle =
|
|
3064
|
+
const metaNeedle = chunkSUMIABJK_js.normalize3(metaLabel);
|
|
3065
3065
|
let mBest;
|
|
3066
3066
|
let mBestScore = 0;
|
|
3067
3067
|
for (const comp of snapshot) {
|
|
3068
3068
|
if (comp.kind !== "field" || !comp.label) continue;
|
|
3069
|
-
const score =
|
|
3069
|
+
const score = chunkSUMIABJK_js.matchScore(metaNeedle, chunkSUMIABJK_js.normalize3(comp.label));
|
|
3070
3070
|
if (score > mBestScore) {
|
|
3071
3071
|
mBestScore = score;
|
|
3072
3072
|
mBest = comp;
|
|
3073
3073
|
}
|
|
3074
3074
|
}
|
|
3075
3075
|
if (mBest && mBestScore >= 60) {
|
|
3076
|
-
|
|
3076
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
3077
3077
|
`findField: FOUND via screen metadata translation: fieldId="${fieldId}" -> metaLabel="${metaLabel}" -> registered="${mBest.id}" (score=${mBestScore})`
|
|
3078
3078
|
);
|
|
3079
3079
|
return registry.getField(mBest.id);
|
|
@@ -3082,34 +3082,34 @@ function findField(fieldId, registry) {
|
|
|
3082
3082
|
}
|
|
3083
3083
|
}
|
|
3084
3084
|
if (bestComp && bestScore >= 40) {
|
|
3085
|
-
|
|
3085
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
3086
3086
|
`findField: weak substring match "${fieldId}" -> "${bestComp.id}" (label="${bestComp.label}", score=${bestScore})`
|
|
3087
3087
|
);
|
|
3088
3088
|
return registry.getField(bestComp.id);
|
|
3089
3089
|
}
|
|
3090
|
-
|
|
3090
|
+
chunkSUMIABJK_js.appilotsDebugWarn(
|
|
3091
3091
|
`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
3092
|
);
|
|
3093
3093
|
return void 0;
|
|
3094
3094
|
}
|
|
3095
3095
|
function findToggle(fieldId, registry) {
|
|
3096
|
-
|
|
3096
|
+
chunkSUMIABJK_js.appilotsDebugLog(`findToggle: searching for fieldId="${fieldId}"`);
|
|
3097
3097
|
const exact = registry.getToggle(fieldId);
|
|
3098
3098
|
if (exact) {
|
|
3099
|
-
|
|
3099
|
+
chunkSUMIABJK_js.appilotsDebugLog(`findToggle: FOUND exact match for "${fieldId}"`);
|
|
3100
3100
|
return exact;
|
|
3101
3101
|
}
|
|
3102
3102
|
const lower = fieldId.toLowerCase();
|
|
3103
3103
|
const snapshot = registry.snapshot();
|
|
3104
3104
|
for (const comp of snapshot) {
|
|
3105
3105
|
if (comp.kind === "toggle" && comp.id.toLowerCase() === lower) {
|
|
3106
|
-
|
|
3106
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
3107
3107
|
`findToggle: FOUND case-insensitive match: registered="${comp.id}" for searched="${fieldId}"`
|
|
3108
3108
|
);
|
|
3109
3109
|
return registry.getToggle(comp.id);
|
|
3110
3110
|
}
|
|
3111
3111
|
}
|
|
3112
|
-
|
|
3112
|
+
chunkSUMIABJK_js.appilotsDebugWarn(
|
|
3113
3113
|
`findToggle: NOT FOUND \u2014 fieldId="${fieldId}" not in registry. Available toggles: ${snapshot.filter((c) => c.kind === "toggle").map((c) => `"${c.id}"`).join(", ") || "none"}`
|
|
3114
3114
|
);
|
|
3115
3115
|
return void 0;
|
|
@@ -3120,7 +3120,7 @@ function findSlider(fieldId, registry) {
|
|
|
3120
3120
|
const lower = fieldId.toLowerCase();
|
|
3121
3121
|
for (const comp of registry.snapshot()) {
|
|
3122
3122
|
if (comp.kind === "slider" && comp.id.toLowerCase() === lower) {
|
|
3123
|
-
|
|
3123
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
3124
3124
|
`findSlider: FOUND case-insensitive match: registered="${comp.id}" for searched="${fieldId}"`
|
|
3125
3125
|
);
|
|
3126
3126
|
return registry.getSlider(comp.id);
|
|
@@ -3131,7 +3131,7 @@ function findSlider(fieldId, registry) {
|
|
|
3131
3131
|
var sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
3132
3132
|
async function formFillHandler(payload, context) {
|
|
3133
3133
|
const { permissions } = context;
|
|
3134
|
-
const registry = context.registry ??
|
|
3134
|
+
const registry = context.registry ?? chunkSUMIABJK_js.componentRegistry;
|
|
3135
3135
|
const { screen, activePath } = resolveScreenContext();
|
|
3136
3136
|
const screenPath = activePath.length > 1 ? activePath.join("/") : screen;
|
|
3137
3137
|
if (!permissions.canFillForms) {
|
|
@@ -3150,11 +3150,11 @@ async function formFillHandler(payload, context) {
|
|
|
3150
3150
|
}
|
|
3151
3151
|
const registrySnapshot = registry.snapshot();
|
|
3152
3152
|
if (registrySnapshot.length === 0) {
|
|
3153
|
-
|
|
3153
|
+
chunkSUMIABJK_js.appilotsDebugWarn(
|
|
3154
3154
|
"formFillHandler: registry is EMPTY \u2014 auto-tracking may not be active. Ensure enableAppilotsAutoTracking() runs before components mount."
|
|
3155
3155
|
);
|
|
3156
3156
|
} else {
|
|
3157
|
-
|
|
3157
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
3158
3158
|
`[Appilots formFillHandler] Registry has ${registrySnapshot.length} components:`,
|
|
3159
3159
|
registrySnapshot.map((c) => `${c.kind}:${c.id}`).join(", ")
|
|
3160
3160
|
);
|
|
@@ -3162,7 +3162,7 @@ async function formFillHandler(payload, context) {
|
|
|
3162
3162
|
const fieldResults = [];
|
|
3163
3163
|
let allSuccess = true;
|
|
3164
3164
|
let selectedChoiceThisBatch = false;
|
|
3165
|
-
|
|
3165
|
+
chunkSUMIABJK_js.appilotsDebugLog(`formFillHandler: processing ${payload.fields.length} fields`);
|
|
3166
3166
|
const availableFieldIds = () => registry.snapshot().filter((comp) => comp.kind === "field").map((comp) => `${comp.id}${comp.label ? ` (${comp.label})` : ""}`).slice(0, 8);
|
|
3167
3167
|
const isElementIdField = (field) => typeof field.fieldId === "string" && field.fieldId.trim().toLowerCase().startsWith("el:");
|
|
3168
3168
|
for (const field of payload.fields.filter(isElementIdField)) {
|
|
@@ -3189,13 +3189,13 @@ async function formFillHandler(payload, context) {
|
|
|
3189
3189
|
const { fieldId, fieldType, value } = field;
|
|
3190
3190
|
const effectiveFieldType = getEffectiveFieldType(fieldId, fieldType, registry);
|
|
3191
3191
|
let selectFailure;
|
|
3192
|
-
|
|
3193
|
-
`formFillHandler: looking up fieldId="${fieldId}" fieldType="${fieldType}" effectiveFieldType="${effectiveFieldType}" value=${
|
|
3192
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
3193
|
+
`formFillHandler: looking up fieldId="${fieldId}" fieldType="${fieldType}" effectiveFieldType="${effectiveFieldType}" value=${chunkSUMIABJK_js.describeValue(value)}`
|
|
3194
3194
|
);
|
|
3195
3195
|
const fieldEntry = findField(fieldId, registry);
|
|
3196
3196
|
if (fieldEntry) {
|
|
3197
3197
|
try {
|
|
3198
|
-
|
|
3198
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
3199
3199
|
`formFillHandler: found field "${fieldId}" via registry, calling setValue(<${String(value).length} chars>)`
|
|
3200
3200
|
);
|
|
3201
3201
|
const beforeValue = effectiveFieldType === "date" ? fieldEntry.getValue?.() ?? "" : void 0;
|
|
@@ -3226,7 +3226,7 @@ async function formFillHandler(payload, context) {
|
|
|
3226
3226
|
after = fieldEntry.getValue?.() ?? "";
|
|
3227
3227
|
}
|
|
3228
3228
|
if (!selectValueApplied(fieldId, value, after, registry)) {
|
|
3229
|
-
|
|
3229
|
+
chunkSUMIABJK_js.appilotsDebugWarn(
|
|
3230
3230
|
`formFillHandler: select field "${fieldId}" setValue did not stick (wrote <${String(value).length} chars>, current is <${String(after ?? "").length} chars>), trying visible choice fallback`
|
|
3231
3231
|
);
|
|
3232
3232
|
const selectResult = await selectVisibleChoice(fieldId, value, registry, {
|
|
@@ -3351,7 +3351,7 @@ async function formFillHandler(payload, context) {
|
|
|
3351
3351
|
}
|
|
3352
3352
|
if (selectResult.success) {
|
|
3353
3353
|
selectedChoiceThisBatch = true;
|
|
3354
|
-
|
|
3354
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
3355
3355
|
`formFillHandler: selected visible option for "${fieldId}"` + (selectResult.selectedLabel ? ` \u2192 "${selectResult.selectedLabel}"` : "")
|
|
3356
3356
|
);
|
|
3357
3357
|
await sleep2(120);
|
|
@@ -3360,7 +3360,7 @@ async function formFillHandler(payload, context) {
|
|
|
3360
3360
|
}
|
|
3361
3361
|
selectFailure = selectResult;
|
|
3362
3362
|
}
|
|
3363
|
-
|
|
3363
|
+
chunkSUMIABJK_js.appilotsDebugLog(`formFillHandler: registry miss for "${fieldId}", falling back to fiber tree`);
|
|
3364
3364
|
const handle = findInteractiveByIdentifier(fieldId, {
|
|
3365
3365
|
kind: effectiveFieldType === "toggle" ? "toggle" : "field"
|
|
3366
3366
|
});
|
|
@@ -3368,7 +3368,7 @@ async function formFillHandler(payload, context) {
|
|
|
3368
3368
|
try {
|
|
3369
3369
|
handle.focus?.();
|
|
3370
3370
|
handle.setValue(value);
|
|
3371
|
-
|
|
3371
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
3372
3372
|
`formFillHandler: fiber fallback succeeded for "${fieldId}" \u2192 label="${handle.label}"`
|
|
3373
3373
|
);
|
|
3374
3374
|
fieldResults.push({ fieldId, success: true });
|
|
@@ -3405,13 +3405,24 @@ async function formFillHandler(payload, context) {
|
|
|
3405
3405
|
allSuccess = false;
|
|
3406
3406
|
}
|
|
3407
3407
|
if (payload.submitAfterFill === true) {
|
|
3408
|
+
if (!permissions.canSubmitForms) {
|
|
3409
|
+
return {
|
|
3410
|
+
success: false,
|
|
3411
|
+
error: "Form submission is not permitted",
|
|
3412
|
+
fieldResults,
|
|
3413
|
+
diagnose: { category: "unknown", screen: screenPath }
|
|
3414
|
+
};
|
|
3415
|
+
}
|
|
3408
3416
|
if (!allSuccess) {
|
|
3409
3417
|
const failedIds = fieldResults.filter((result) => !result.success).map((result) => result.fieldId);
|
|
3410
|
-
|
|
3418
|
+
chunkSUMIABJK_js.appilotsDebugWarn(
|
|
3411
3419
|
"formFillHandler: submitAfterFill=true requested but some fields failed; NOT submitting" + (failedIds.length > 0 ? ` (failed: ${failedIds.join(", ")})` : "")
|
|
3412
3420
|
);
|
|
3413
3421
|
} else {
|
|
3414
3422
|
await sleep2(120);
|
|
3423
|
+
if (!permissions.canSubmitForms) {
|
|
3424
|
+
return { success: false, error: "Form submission is not permitted", fieldResults };
|
|
3425
|
+
}
|
|
3415
3426
|
const submitResult = pressSubmitButton(
|
|
3416
3427
|
{
|
|
3417
3428
|
screen,
|
|
@@ -3422,7 +3433,7 @@ async function formFillHandler(payload, context) {
|
|
|
3422
3433
|
registry
|
|
3423
3434
|
);
|
|
3424
3435
|
if (!submitResult.success) {
|
|
3425
|
-
|
|
3436
|
+
chunkSUMIABJK_js.appilotsDebugWarn(`formFillHandler: submitAfterFill failed \u2014 ${submitResult.error}`);
|
|
3426
3437
|
return {
|
|
3427
3438
|
success: false,
|
|
3428
3439
|
error: submitResult.error,
|
|
@@ -3434,7 +3445,7 @@ async function formFillHandler(payload, context) {
|
|
|
3434
3445
|
submitTargetId: submitResult.pressedTargetId
|
|
3435
3446
|
});
|
|
3436
3447
|
if (postSubmit.status === "pending") {
|
|
3437
|
-
|
|
3448
|
+
chunkSUMIABJK_js.appilotsDebugWarn(`formFillHandler: submit still pending \u2014 ${postSubmit.message}`);
|
|
3438
3449
|
return {
|
|
3439
3450
|
success: false,
|
|
3440
3451
|
error: postSubmit.message,
|
|
@@ -3443,7 +3454,7 @@ async function formFillHandler(payload, context) {
|
|
|
3443
3454
|
};
|
|
3444
3455
|
}
|
|
3445
3456
|
if (postSubmit.status === "failure") {
|
|
3446
|
-
|
|
3457
|
+
chunkSUMIABJK_js.appilotsDebugWarn(
|
|
3447
3458
|
`formFillHandler: submit rejected by visible validation \u2014 ${postSubmit.message}`
|
|
3448
3459
|
);
|
|
3449
3460
|
return {
|
|
@@ -3458,7 +3469,7 @@ async function formFillHandler(payload, context) {
|
|
|
3458
3469
|
}
|
|
3459
3470
|
};
|
|
3460
3471
|
}
|
|
3461
|
-
|
|
3472
|
+
chunkSUMIABJK_js.appilotsDebugLog("formFillHandler: submitAfterFill \u2014 submit completed");
|
|
3462
3473
|
}
|
|
3463
3474
|
}
|
|
3464
3475
|
const aggregatedDiagnose = aggregateFieldDiagnoses(fieldResults, screenPath);
|
|
@@ -3470,17 +3481,17 @@ async function formFillHandler(payload, context) {
|
|
|
3470
3481
|
};
|
|
3471
3482
|
}
|
|
3472
3483
|
function pressSubmitButton(context, registry) {
|
|
3473
|
-
const activePath = context.activePath ??
|
|
3484
|
+
const activePath = context.activePath ?? chunkSUMIABJK_js.getActiveRouteNames();
|
|
3474
3485
|
const hintScreen = context.screen ?? context.screenPath;
|
|
3475
3486
|
const formScreens = resolveFormScreensForSubmit(hintScreen, activePath, registry);
|
|
3476
|
-
const resolvedScreen = formScreens.find((name) => screenDeclaresSubmit(name)) ?? formScreens[0] ?? hintScreen ??
|
|
3487
|
+
const resolvedScreen = formScreens.find((name) => screenDeclaresSubmit(name)) ?? formScreens[0] ?? hintScreen ?? chunkSUMIABJK_js.getCurrentScreen() ?? void 0;
|
|
3477
3488
|
const candidates = collectSubmitTargetCandidates(formScreens, registry);
|
|
3478
3489
|
for (const candidate of candidates) {
|
|
3479
3490
|
const target = registry.getTarget(candidate);
|
|
3480
3491
|
if (target) {
|
|
3481
3492
|
try {
|
|
3482
3493
|
target.press();
|
|
3483
|
-
|
|
3494
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
3484
3495
|
`formFillHandler: submitAfterFill \u2014 pressed registry target "${candidate}"` + (resolvedScreen ? ` on screen "${resolvedScreen}"` : "")
|
|
3485
3496
|
);
|
|
3486
3497
|
return { success: true, pressedTargetId: candidate };
|
|
@@ -3494,7 +3505,7 @@ function pressSubmitButton(context, registry) {
|
|
|
3494
3505
|
}
|
|
3495
3506
|
}
|
|
3496
3507
|
for (const screenName of formScreens) {
|
|
3497
|
-
const screenMeta =
|
|
3508
|
+
const screenMeta = chunkSUMIABJK_js.getScreenMetadata(screenName);
|
|
3498
3509
|
const submitMeta = Array.isArray(screenMeta?.actions) ? screenMeta.actions.find(
|
|
3499
3510
|
(action) => typeof action === "object" && action !== null && action.type === "submit"
|
|
3500
3511
|
) : void 0;
|
|
@@ -3505,7 +3516,7 @@ function pressSubmitButton(context, registry) {
|
|
|
3505
3516
|
if (handle?.press) {
|
|
3506
3517
|
try {
|
|
3507
3518
|
handle.press();
|
|
3508
|
-
|
|
3519
|
+
chunkSUMIABJK_js.appilotsDebugLog(`formFillHandler: submitAfterFill \u2014 fiber fallback "${submitLabel}"`);
|
|
3509
3520
|
return { success: true, pressedTargetId: submitId ?? submitLabel };
|
|
3510
3521
|
} catch (err) {
|
|
3511
3522
|
return {
|
|
@@ -3527,7 +3538,7 @@ function pressSubmitButton(context, registry) {
|
|
|
3527
3538
|
if (id) {
|
|
3528
3539
|
const pressed = pressTargetByIdOrLabel(id, registry);
|
|
3529
3540
|
if (pressed.success) {
|
|
3530
|
-
|
|
3541
|
+
chunkSUMIABJK_js.appilotsDebugLog(`formFillHandler: submitAfterFill \u2014 pressed visible heuristic "${id}"`);
|
|
3531
3542
|
return { success: true, pressedTargetId: id };
|
|
3532
3543
|
}
|
|
3533
3544
|
}
|
|
@@ -3541,7 +3552,7 @@ function pressSubmitButton(context, registry) {
|
|
|
3541
3552
|
if (target) {
|
|
3542
3553
|
try {
|
|
3543
3554
|
target.press();
|
|
3544
|
-
|
|
3555
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
3545
3556
|
`formFillHandler: submitAfterFill \u2014 pressed by label heuristic "${comp.label}"`
|
|
3546
3557
|
);
|
|
3547
3558
|
return { success: true, pressedTargetId: comp.id };
|
|
@@ -3557,7 +3568,7 @@ function pressSubmitButton(context, registry) {
|
|
|
3557
3568
|
for (const fieldId of [...context.filledFieldIds ?? []].reverse()) {
|
|
3558
3569
|
const handle = findInteractiveByIdentifier(fieldId, { kind: "field" });
|
|
3559
3570
|
if (handle?.submitFromKeyboard?.()) {
|
|
3560
|
-
|
|
3571
|
+
chunkSUMIABJK_js.appilotsDebugLog(`formFillHandler: submitAfterFill \u2014 return key on "${fieldId}"`);
|
|
3561
3572
|
return { success: true, pressedTargetId: fieldId };
|
|
3562
3573
|
}
|
|
3563
3574
|
}
|
|
@@ -3603,12 +3614,12 @@ function buildDiagnose(category, targetId, candidates) {
|
|
|
3603
3614
|
return {
|
|
3604
3615
|
category,
|
|
3605
3616
|
targetId,
|
|
3606
|
-
screen:
|
|
3617
|
+
screen: chunkSUMIABJK_js.getCurrentScreen() ?? void 0,
|
|
3607
3618
|
...candidates && candidates.length > 0 ? { candidates: candidates.slice(0, 8) } : {}
|
|
3608
3619
|
};
|
|
3609
3620
|
}
|
|
3610
3621
|
function resolveListEntry(listId) {
|
|
3611
|
-
const entries =
|
|
3622
|
+
const entries = chunkSUMIABJK_js.listRegistry.snapshot();
|
|
3612
3623
|
if (entries.length === 0) return {};
|
|
3613
3624
|
if (listId) {
|
|
3614
3625
|
const wanted = normalizeId2(listId);
|
|
@@ -3717,6 +3728,59 @@ async function confirmHandler(_actionId, _payload) {
|
|
|
3717
3728
|
return { success: true, effect: "unknown" };
|
|
3718
3729
|
}
|
|
3719
3730
|
|
|
3731
|
+
// src/platform/asyncBudget.ts
|
|
3732
|
+
var POST_ACTION_LOADING_MAX_MS = 6e3;
|
|
3733
|
+
var INFERRED_ASYNC_LOADING_MAX_MS = 1e4;
|
|
3734
|
+
var POST_NAVIGATE_LOADING_MAX_MS = 3e3;
|
|
3735
|
+
var MAX_DECLARED_ASYNC_BUDGET_MS = 12e4;
|
|
3736
|
+
var ASYNC_BUSY_CEILING_MS = MAX_DECLARED_ASYNC_BUDGET_MS;
|
|
3737
|
+
function declaredBudgetMs(hints) {
|
|
3738
|
+
const declared = hints?.asyncBudgetMs;
|
|
3739
|
+
if (typeof declared !== "number" || !Number.isFinite(declared) || declared <= 0) return void 0;
|
|
3740
|
+
return Math.min(declared, MAX_DECLARED_ASYNC_BUDGET_MS);
|
|
3741
|
+
}
|
|
3742
|
+
function resolveSettleCapMs(hints) {
|
|
3743
|
+
const declared = declaredBudgetMs(hints);
|
|
3744
|
+
if (declared !== void 0) return declared;
|
|
3745
|
+
return hints?.isAsyncTrigger === true ? INFERRED_ASYNC_LOADING_MAX_MS : POST_ACTION_LOADING_MAX_MS;
|
|
3746
|
+
}
|
|
3747
|
+
function resolveBusyCeilingMs(hints) {
|
|
3748
|
+
return declaredBudgetMs(hints) === void 0 ? ASYNC_BUSY_CEILING_MS : void 0;
|
|
3749
|
+
}
|
|
3750
|
+
function resolvePostNavigateCapMs(hints) {
|
|
3751
|
+
return Math.max(POST_NAVIGATE_LOADING_MAX_MS, declaredBudgetMs(hints) ?? 0);
|
|
3752
|
+
}
|
|
3753
|
+
function resolveActionHints(screen, pressedComponentId, actionPayload) {
|
|
3754
|
+
if (actionPayload && typeof actionPayload === "object") {
|
|
3755
|
+
const payload = actionPayload;
|
|
3756
|
+
const inline = payload._appilotsInferred;
|
|
3757
|
+
const declared = payload._appilotsAsyncBudgetMs;
|
|
3758
|
+
if (inline && typeof inline === "object") {
|
|
3759
|
+
const hints = { ...inline };
|
|
3760
|
+
if (typeof declared === "number") hints.asyncBudgetMs = declared;
|
|
3761
|
+
return hints;
|
|
3762
|
+
}
|
|
3763
|
+
if (typeof declared === "number") return { asyncBudgetMs: declared };
|
|
3764
|
+
}
|
|
3765
|
+
if (!screen || !pressedComponentId) return void 0;
|
|
3766
|
+
const meta = chunkSUMIABJK_js.getScreenMetadata(screen);
|
|
3767
|
+
const actions = meta?.actions;
|
|
3768
|
+
if (!actions || actions.length === 0) return void 0;
|
|
3769
|
+
for (const a of actions) {
|
|
3770
|
+
if (typeof a === "string") continue;
|
|
3771
|
+
if (chunkSUMIABJK_js.idLooselyMatches(a.id, pressedComponentId)) {
|
|
3772
|
+
const inferred = a.appilotsInferred;
|
|
3773
|
+
const declared = a.asyncBudgetMs;
|
|
3774
|
+
const hints = {
|
|
3775
|
+
...inferred && typeof inferred === "object" ? inferred : {},
|
|
3776
|
+
...typeof declared === "number" ? { asyncBudgetMs: declared } : {}
|
|
3777
|
+
};
|
|
3778
|
+
return Object.keys(hints).length > 0 ? hints : void 0;
|
|
3779
|
+
}
|
|
3780
|
+
}
|
|
3781
|
+
return void 0;
|
|
3782
|
+
}
|
|
3783
|
+
|
|
3720
3784
|
// src/executor/postInteractionSettle.ts
|
|
3721
3785
|
var sleepMs = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
3722
3786
|
function targetIdFromPayload(payload) {
|
|
@@ -3737,9 +3801,9 @@ function hashFieldValue(value) {
|
|
|
3737
3801
|
var DISCRETE_FIELD_TYPES = /* @__PURE__ */ new Set(["select", "date"]);
|
|
3738
3802
|
function discreteFieldSignature() {
|
|
3739
3803
|
const sigs = [];
|
|
3740
|
-
for (const { id, kind } of
|
|
3804
|
+
for (const { id, kind } of chunkSUMIABJK_js.componentRegistry.snapshot()) {
|
|
3741
3805
|
if (kind !== "field") continue;
|
|
3742
|
-
const entry =
|
|
3806
|
+
const entry = chunkSUMIABJK_js.componentRegistry.getField(id);
|
|
3743
3807
|
if (!entry || !DISCRETE_FIELD_TYPES.has(entry.fieldType ?? "")) continue;
|
|
3744
3808
|
try {
|
|
3745
3809
|
sigs.push(`${id}:${hashFieldValue(String(entry.getValue() ?? ""))}`);
|
|
@@ -3750,32 +3814,33 @@ function discreteFieldSignature() {
|
|
|
3750
3814
|
}
|
|
3751
3815
|
async function waitForPostInteractionSettle(payload) {
|
|
3752
3816
|
const targetId = targetIdFromPayload(payload);
|
|
3753
|
-
const fromScreen =
|
|
3754
|
-
const baseline =
|
|
3817
|
+
const fromScreen = chunkSUMIABJK_js.getCurrentScreen();
|
|
3818
|
+
const baseline = chunkSUMIABJK_js.probeLoadingState(targetId || null, fromScreen);
|
|
3755
3819
|
const baselineFields = discreteFieldSignature();
|
|
3756
3820
|
const readable = baseline.fingerprint !== "";
|
|
3757
3821
|
await sleepMs(100);
|
|
3758
|
-
const afterPress =
|
|
3822
|
+
const afterPress = chunkSUMIABJK_js.probeLoadingState(targetId || null, chunkSUMIABJK_js.getCurrentScreen());
|
|
3759
3823
|
const modalOrLoading = afterPress.modalOpen || afterPress.loading || afterPress.pressedDisabled;
|
|
3760
3824
|
const fingerprintChanged = afterPress.fingerprint !== baseline.fingerprint;
|
|
3761
3825
|
const verdict = () => {
|
|
3762
3826
|
if (!readable) return { effect: "unknown" };
|
|
3763
|
-
const settled =
|
|
3827
|
+
const settled = chunkSUMIABJK_js.probeLoadingState(targetId || null, chunkSUMIABJK_js.getCurrentScreen());
|
|
3764
3828
|
if (settled.fingerprint === "") return { effect: "unknown" };
|
|
3765
3829
|
if (discreteFieldSignature() !== baselineFields) return { effect: "changed" };
|
|
3766
3830
|
return { effect: settled.fingerprint !== baseline.fingerprint ? "changed" : "none" };
|
|
3767
3831
|
};
|
|
3768
|
-
const
|
|
3832
|
+
const declared = declaredBudgetMs(resolveActionHints(fromScreen, targetId || null, payload));
|
|
3833
|
+
const capMs = declared ?? (chunkSUMIABJK_js.isListItemPressTarget(targetId) ? 5e3 : 1e4);
|
|
3769
3834
|
if (modalOrLoading || fingerprintChanged) {
|
|
3770
|
-
await
|
|
3835
|
+
await chunkSUMIABJK_js.waitForLoadingSettle({
|
|
3771
3836
|
pressedComponentId: targetId || null,
|
|
3772
3837
|
fromScreen,
|
|
3773
3838
|
maxMs: capMs
|
|
3774
3839
|
});
|
|
3775
3840
|
return verdict();
|
|
3776
3841
|
}
|
|
3777
|
-
if (
|
|
3778
|
-
await
|
|
3842
|
+
if (chunkSUMIABJK_js.isListItemPressTarget(targetId)) {
|
|
3843
|
+
await chunkSUMIABJK_js.waitForLoadingSettle({
|
|
3779
3844
|
fromScreen,
|
|
3780
3845
|
maxMs: 3e3
|
|
3781
3846
|
});
|
|
@@ -3796,7 +3861,7 @@ function validateActionPayload(action) {
|
|
|
3796
3861
|
error: message,
|
|
3797
3862
|
diagnose: {
|
|
3798
3863
|
category: "validation",
|
|
3799
|
-
screen:
|
|
3864
|
+
screen: chunkSUMIABJK_js.getCurrentScreen() ?? void 0,
|
|
3800
3865
|
...ids ?? {}
|
|
3801
3866
|
}
|
|
3802
3867
|
});
|
|
@@ -3857,7 +3922,7 @@ function isDestructivePayload(payload) {
|
|
|
3857
3922
|
return !!params && typeof params === "object" && params.destructive === true;
|
|
3858
3923
|
}
|
|
3859
3924
|
async function executeAction(action, context) {
|
|
3860
|
-
|
|
3925
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
3861
3926
|
`executeAction called: type="${action.type}", id="${action.id}", payload=${JSON.stringify(action.payload)}`
|
|
3862
3927
|
);
|
|
3863
3928
|
const permissions = context.permissions ?? DEFAULT_PERMISSIONS;
|
|
@@ -3886,7 +3951,7 @@ async function executeAction(action, context) {
|
|
|
3886
3951
|
let result;
|
|
3887
3952
|
const validationFailure = validateActionPayload(action);
|
|
3888
3953
|
if (validationFailure) {
|
|
3889
|
-
|
|
3954
|
+
chunkSUMIABJK_js.appilotsDebugWarn(
|
|
3890
3955
|
`executeAction: payload validation failed for type="${action.type}" id="${action.id}": ${validationFailure.error}`
|
|
3891
3956
|
);
|
|
3892
3957
|
context.emit({
|
|
@@ -3913,14 +3978,14 @@ async function executeAction(action, context) {
|
|
|
3913
3978
|
case "form_fill":
|
|
3914
3979
|
result = await formFillHandler(action.payload, {
|
|
3915
3980
|
permissions,
|
|
3916
|
-
registry: context.registry ??
|
|
3981
|
+
registry: context.registry ?? chunkSUMIABJK_js.getDefaultRegistry()
|
|
3917
3982
|
});
|
|
3918
3983
|
break;
|
|
3919
3984
|
case "ui_interaction": {
|
|
3920
3985
|
const payload = action.payload;
|
|
3921
3986
|
result = uiInteractionHandler(payload, {
|
|
3922
3987
|
permissions,
|
|
3923
|
-
registry: context.registry ??
|
|
3988
|
+
registry: context.registry ?? chunkSUMIABJK_js.getDefaultRegistry()
|
|
3924
3989
|
});
|
|
3925
3990
|
if (result.success) {
|
|
3926
3991
|
const settle = await waitForPostInteractionSettle(payload);
|
|
@@ -3949,7 +4014,7 @@ async function executeAction(action, context) {
|
|
|
3949
4014
|
};
|
|
3950
4015
|
}
|
|
3951
4016
|
} catch (err) {
|
|
3952
|
-
|
|
4017
|
+
chunkSUMIABJK_js.appilotsDebugWarn(
|
|
3953
4018
|
`executeAction: exception during action type="${action.type}" id="${action.id}": ${err?.message}`
|
|
3954
4019
|
);
|
|
3955
4020
|
result = {
|
|
@@ -3957,7 +4022,7 @@ async function executeAction(action, context) {
|
|
|
3957
4022
|
error: err?.message ?? "Action execution failed unexpectedly"
|
|
3958
4023
|
};
|
|
3959
4024
|
}
|
|
3960
|
-
|
|
4025
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
3961
4026
|
`executeAction result: type="${action.type}", id="${action.id}", success=${result.success}, error=${result.error ?? "none"}`
|
|
3962
4027
|
);
|
|
3963
4028
|
context.emit({
|
|
@@ -4011,7 +4076,7 @@ var _patchedAlert = (title, message, buttons, options) => {
|
|
|
4011
4076
|
return suppression.originalAlert(title, message, buttons, options);
|
|
4012
4077
|
}
|
|
4013
4078
|
suppression.consumed = true;
|
|
4014
|
-
|
|
4079
|
+
chunkSUMIABJK_js.appilotsDebugLog("Suppressing native Alert during already-confirmed destructive agent action");
|
|
4015
4080
|
try {
|
|
4016
4081
|
suppression.pending = Promise.resolve(button.onPress()).then(() => void 0).catch((err) => reportHandlerFailure(err));
|
|
4017
4082
|
} catch (err) {
|
|
@@ -4062,37 +4127,41 @@ async function runWithConfirmedDestructiveContext(enabled, host, fn) {
|
|
|
4062
4127
|
}
|
|
4063
4128
|
|
|
4064
4129
|
// src/platform/reactNativeAdapter.ts
|
|
4065
|
-
var
|
|
4130
|
+
var deltaTracker = chunkSUMIABJK_js.createSnapshotDeltaTracker();
|
|
4066
4131
|
function resolveScreenMetadata() {
|
|
4067
|
-
const activePath =
|
|
4132
|
+
const activePath = chunkSUMIABJK_js.getActiveRouteNames();
|
|
4068
4133
|
for (let i = activePath.length - 1; i >= 0; i--) {
|
|
4069
4134
|
const name = activePath[i];
|
|
4070
|
-
const meta = name ?
|
|
4135
|
+
const meta = name ? chunkSUMIABJK_js.getScreenMetadata(name) : void 0;
|
|
4071
4136
|
if (meta && (Array.isArray(meta.fields) && meta.fields.length > 0 || Array.isArray(meta.actions) && meta.actions.length > 0)) {
|
|
4072
4137
|
return meta;
|
|
4073
4138
|
}
|
|
4074
4139
|
}
|
|
4075
|
-
const screen =
|
|
4076
|
-
return screen ?
|
|
4140
|
+
const screen = chunkSUMIABJK_js.getCurrentScreen();
|
|
4141
|
+
return screen ? chunkSUMIABJK_js.getScreenMetadata(screen) : void 0;
|
|
4077
4142
|
}
|
|
4078
4143
|
function buildAgentContext(extras = {}) {
|
|
4144
|
+
if (extras.newMission === true) deltaTracker.reset();
|
|
4079
4145
|
const context = {};
|
|
4080
4146
|
context.platform = "react-native";
|
|
4081
|
-
const screen =
|
|
4147
|
+
const screen = chunkSUMIABJK_js.getCurrentScreen();
|
|
4082
4148
|
if (screen) context.currentScreen = screen;
|
|
4083
|
-
const navigationState =
|
|
4149
|
+
const navigationState = chunkSUMIABJK_js.getNavigationStateSnapshot();
|
|
4084
4150
|
if (navigationState) context.navigationState = navigationState;
|
|
4085
4151
|
const screenMeta = resolveScreenMetadata();
|
|
4086
4152
|
if (screenMeta) context.screenMetadata = screenMeta;
|
|
4087
4153
|
try {
|
|
4088
|
-
|
|
4154
|
+
const snapshot = captureSnapshot();
|
|
4155
|
+
const delta = deltaTracker.observe(snapshot);
|
|
4156
|
+
if (delta) snapshot.delta = delta;
|
|
4157
|
+
context.snapshot = snapshot;
|
|
4089
4158
|
} catch (err) {
|
|
4090
|
-
|
|
4159
|
+
chunkSUMIABJK_js.appilotsDebugWarn("buildAgentContext: captureSnapshot failed", err);
|
|
4091
4160
|
}
|
|
4092
|
-
const registry =
|
|
4161
|
+
const registry = chunkSUMIABJK_js.componentRegistry.snapshot();
|
|
4093
4162
|
const filtered = screen ? registry.filter((c) => !c.screen || c.screen === screen) : registry;
|
|
4094
4163
|
if (filtered.length > 0) context.registeredComponents = filtered;
|
|
4095
|
-
const registeredLists =
|
|
4164
|
+
const registeredLists = chunkSUMIABJK_js.listRegistry.snapshot();
|
|
4096
4165
|
if (registeredLists.length > 0) {
|
|
4097
4166
|
context.registeredLists = registeredLists.map(
|
|
4098
4167
|
({ scrollToIndex, scrollToOffset, getScrollMetrics, dataPreview, ...rest }) => rest
|
|
@@ -4101,95 +4170,82 @@ function buildAgentContext(extras = {}) {
|
|
|
4101
4170
|
if (extras.loadingPending === true) context.loadingPending = true;
|
|
4102
4171
|
return context;
|
|
4103
4172
|
}
|
|
4104
|
-
function resolveActionHints(screen, pressedComponentId, actionPayload) {
|
|
4105
|
-
if (actionPayload && typeof actionPayload === "object") {
|
|
4106
|
-
const inline = actionPayload._appilotsInferred;
|
|
4107
|
-
if (inline && typeof inline === "object") {
|
|
4108
|
-
return inline;
|
|
4109
|
-
}
|
|
4110
|
-
}
|
|
4111
|
-
if (!screen || !pressedComponentId) return void 0;
|
|
4112
|
-
const meta = chunkKZ2BLMS4_js.getScreenMetadata(screen);
|
|
4113
|
-
const actions = meta?.actions;
|
|
4114
|
-
if (!actions || actions.length === 0) return void 0;
|
|
4115
|
-
for (const a of actions) {
|
|
4116
|
-
if (typeof a === "string") continue;
|
|
4117
|
-
if (chunkKZ2BLMS4_js.idLooselyMatches(a.id, pressedComponentId)) {
|
|
4118
|
-
const inferred = a.appilotsInferred;
|
|
4119
|
-
if (inferred && typeof inferred === "object") return inferred;
|
|
4120
|
-
return void 0;
|
|
4121
|
-
}
|
|
4122
|
-
}
|
|
4123
|
-
return void 0;
|
|
4124
|
-
}
|
|
4125
4173
|
async function settleTurn(input) {
|
|
4126
4174
|
const toolWithoutEffectIds = /* @__PURE__ */ new Set();
|
|
4127
4175
|
let loadingPending = false;
|
|
4128
4176
|
const { turnActions, pressedComponentId: pressedId, navigateTargetScreen } = input;
|
|
4129
4177
|
const successById = new Map(input.results.map((r) => [r.actionId, r.success]));
|
|
4130
4178
|
const typeById = new Map(input.results.map((r) => [r.actionId, r.type]));
|
|
4179
|
+
const pressedAction = turnActions.find(
|
|
4180
|
+
(a) => a.type === "ui_interaction" && a.payload?.componentId === pressedId
|
|
4181
|
+
);
|
|
4182
|
+
const hints = resolveActionHints(
|
|
4183
|
+
chunkSUMIABJK_js.getCurrentScreen(),
|
|
4184
|
+
pressedId,
|
|
4185
|
+
pressedAction?.payload
|
|
4186
|
+
);
|
|
4187
|
+
const capSource = typeof hints?.asyncBudgetMs === "number" && hints.asyncBudgetMs > 0 ? " (app-declared)" : hints?.isAsyncTrigger ? " (mcp-inferred)" : "";
|
|
4131
4188
|
if (input.hadNavigate) {
|
|
4132
|
-
const settle = await
|
|
4189
|
+
const settle = await chunkSUMIABJK_js.waitForScreenSettle({
|
|
4133
4190
|
expectingChange: true,
|
|
4134
4191
|
fromScreen: input.preNavigateScreen ?? null,
|
|
4135
4192
|
fromSignature: input.preNavigateSignature ?? null,
|
|
4136
4193
|
targetScreen: navigateTargetScreen,
|
|
4137
4194
|
maxMs: 3500
|
|
4138
4195
|
});
|
|
4139
|
-
|
|
4196
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
4140
4197
|
`settleTurn: post-navigate settle done \u2014 screen="${settle.screen}" transitioned=${settle.transitioned} timedOut=${settle.timedOut} waitedMs=${settle.waitedMs}`
|
|
4141
4198
|
);
|
|
4142
|
-
const navigationMoved = settle.transitioned ||
|
|
4199
|
+
const navigationMoved = settle.transitioned || chunkSUMIABJK_js.screenDepartedBaseline(input.preNavigateScreen ?? null, input.preNavigateSignature ?? null) || !!navigateTargetScreen && !!settle.screen && chunkSUMIABJK_js.routesBelongToSameFeature(settle.screen, navigateTargetScreen);
|
|
4143
4200
|
if (!navigationMoved) {
|
|
4144
|
-
|
|
4201
|
+
chunkSUMIABJK_js.appilotsDebugWarn(
|
|
4145
4202
|
`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.`
|
|
4146
4203
|
);
|
|
4147
4204
|
for (const [actionId, type] of typeById) {
|
|
4148
4205
|
if (type === "navigate") toolWithoutEffectIds.add(actionId);
|
|
4149
4206
|
}
|
|
4150
4207
|
}
|
|
4151
|
-
const
|
|
4208
|
+
const postNavigateCapMs = resolvePostNavigateCapMs(hints);
|
|
4209
|
+
const loadSettle = await chunkSUMIABJK_js.waitForLoadingSettle({
|
|
4152
4210
|
fromScreen: settle.screen ?? null,
|
|
4153
|
-
maxMs:
|
|
4211
|
+
maxMs: postNavigateCapMs
|
|
4154
4212
|
});
|
|
4155
|
-
|
|
4156
|
-
`settleTurn: post-navigate loading settle \u2014 settled=${loadSettle.settled} loadingPending=${loadSettle.loadingPending} probes=${loadSettle.probeCount} waitedMs=${loadSettle.waitedMs}`
|
|
4213
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
4214
|
+
`settleTurn: post-navigate loading settle \u2014 settled=${loadSettle.settled} loadingPending=${loadSettle.loadingPending} probes=${loadSettle.probeCount} waitedMs=${loadSettle.waitedMs} cap=${postNavigateCapMs}${capSource}`
|
|
4157
4215
|
);
|
|
4158
4216
|
if (loadSettle.loadingPending) loadingPending = true;
|
|
4159
4217
|
} else {
|
|
4160
|
-
const
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
const hints = resolveActionHints(chunkKZ2BLMS4_js.getCurrentScreen(), pressedId, pressedAction?.payload);
|
|
4164
|
-
const settleCapMs = hints?.isAsyncTrigger === true ? 1e4 : POST_ACTION_LOADING_MAX_MS;
|
|
4165
|
-
const loadSettle = await chunkKZ2BLMS4_js.waitForLoadingSettle({
|
|
4218
|
+
const settleCapMs = resolveSettleCapMs(hints);
|
|
4219
|
+
const busyMaxMs = resolveBusyCeilingMs(hints);
|
|
4220
|
+
const loadSettle = await chunkSUMIABJK_js.waitForLoadingSettle({
|
|
4166
4221
|
pressedComponentId: pressedId,
|
|
4167
|
-
fromScreen:
|
|
4168
|
-
maxMs: settleCapMs
|
|
4222
|
+
fromScreen: chunkSUMIABJK_js.getCurrentScreen(),
|
|
4223
|
+
maxMs: settleCapMs,
|
|
4224
|
+
...busyMaxMs !== void 0 ? { busyMaxMs } : {}
|
|
4169
4225
|
});
|
|
4170
|
-
|
|
4171
|
-
`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}${
|
|
4226
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
4227
|
+
`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}` : ""}`
|
|
4172
4228
|
);
|
|
4173
4229
|
if (loadSettle.loadingPending) loadingPending = true;
|
|
4174
4230
|
const listPressActions = turnActions.filter((action) => {
|
|
4175
|
-
const target =
|
|
4176
|
-
return target ?
|
|
4231
|
+
const target = chunkSUMIABJK_js.actionPressTargetId(action);
|
|
4232
|
+
return target ? chunkSUMIABJK_js.isListItemPressTarget(target) : false;
|
|
4177
4233
|
});
|
|
4178
4234
|
if (listPressActions.length > 0) {
|
|
4179
|
-
const baselineFingerprint =
|
|
4180
|
-
const postPressSettle = await
|
|
4235
|
+
const baselineFingerprint = chunkSUMIABJK_js.probeLoadingState(pressedId, chunkSUMIABJK_js.getCurrentScreen()).fingerprint;
|
|
4236
|
+
const postPressSettle = await chunkSUMIABJK_js.waitForScreenSettle({
|
|
4181
4237
|
expectingChange: true,
|
|
4182
4238
|
fromScreen: input.preNavigateScreen ?? null,
|
|
4183
4239
|
fromSignature: input.preNavigateSignature ?? null,
|
|
4184
4240
|
maxMs: 2500
|
|
4185
4241
|
});
|
|
4186
|
-
await
|
|
4242
|
+
await chunkSUMIABJK_js.waitForLoadingSettle({
|
|
4187
4243
|
pressedComponentId: pressedId,
|
|
4188
|
-
fromScreen:
|
|
4244
|
+
fromScreen: chunkSUMIABJK_js.getCurrentScreen(),
|
|
4189
4245
|
maxMs: 4e3
|
|
4190
4246
|
});
|
|
4191
|
-
const afterFingerprint =
|
|
4192
|
-
|
|
4247
|
+
const afterFingerprint = chunkSUMIABJK_js.probeLoadingState(pressedId, chunkSUMIABJK_js.getCurrentScreen()).fingerprint;
|
|
4248
|
+
chunkSUMIABJK_js.appilotsDebugLog(
|
|
4193
4249
|
`settleTurn: post-list-press settle \u2014 screen="${postPressSettle.screen}" transitioned=${postPressSettle.transitioned} timedOut=${postPressSettle.timedOut} waitedMs=${postPressSettle.waitedMs}`
|
|
4194
4250
|
);
|
|
4195
4251
|
if (!postPressSettle.transitioned && baselineFingerprint === afterFingerprint) {
|
|
@@ -4205,15 +4261,15 @@ async function settleTurn(input) {
|
|
|
4205
4261
|
}
|
|
4206
4262
|
var reactNativeChatAdapter = {
|
|
4207
4263
|
buildContext: buildAgentContext,
|
|
4208
|
-
getCurrentScreen:
|
|
4209
|
-
getCurrentScreenSignature:
|
|
4264
|
+
getCurrentScreen: chunkSUMIABJK_js.getCurrentScreen,
|
|
4265
|
+
getCurrentScreenSignature: chunkSUMIABJK_js.getCurrentScreenSignature,
|
|
4210
4266
|
settleTurn
|
|
4211
4267
|
};
|
|
4212
4268
|
function createReactNativeActionRunner(getOptions) {
|
|
4213
4269
|
return {
|
|
4214
4270
|
async execute(action, { confirmedDestructive }) {
|
|
4215
4271
|
const { permissions, emit, navigationRef, suppressNativeConfirm } = getOptions();
|
|
4216
|
-
const navRef = navigationRef?.current ? navigationRef : { current:
|
|
4272
|
+
const navRef = navigationRef?.current ? navigationRef : { current: chunkSUMIABJK_js.getNavigationRef() };
|
|
4217
4273
|
return runWithConfirmedDestructiveContext(
|
|
4218
4274
|
confirmedDestructive && suppressNativeConfirm !== false,
|
|
4219
4275
|
reactNative.Alert,
|
|
@@ -4224,21 +4280,21 @@ function createReactNativeActionRunner(getOptions) {
|
|
|
4224
4280
|
})
|
|
4225
4281
|
);
|
|
4226
4282
|
},
|
|
4227
|
-
getCurrentScreen:
|
|
4228
|
-
getCurrentScreenSignature:
|
|
4283
|
+
getCurrentScreen: chunkSUMIABJK_js.getCurrentScreen,
|
|
4284
|
+
getCurrentScreenSignature: chunkSUMIABJK_js.getCurrentScreenSignature,
|
|
4229
4285
|
getScreenActionsMetadata(screen) {
|
|
4230
|
-
return
|
|
4286
|
+
return chunkSUMIABJK_js.getScreenMetadata(screen)?.actions;
|
|
4231
4287
|
},
|
|
4232
|
-
waitForScreenSettle:
|
|
4288
|
+
waitForScreenSettle: chunkSUMIABJK_js.waitForScreenSettle
|
|
4233
4289
|
};
|
|
4234
4290
|
}
|
|
4235
4291
|
|
|
4236
4292
|
// src/hooks/useAppilotsChat.ts
|
|
4237
4293
|
function useAppilotsChat(options = {}) {
|
|
4238
|
-
const { client, emit, subscribe } =
|
|
4294
|
+
const { client, emit, subscribe } = chunkSUMIABJK_js.useAppilotsContext();
|
|
4239
4295
|
const machine = React.useMemo(
|
|
4240
|
-
() => new
|
|
4241
|
-
{ client, adapter: reactNativeChatAdapter, emit, warn:
|
|
4296
|
+
() => new chunkSUMIABJK_js.ChatSessionMachine(
|
|
4297
|
+
{ client, adapter: reactNativeChatAdapter, emit, warn: chunkSUMIABJK_js.appilotsDebugWarn },
|
|
4242
4298
|
options
|
|
4243
4299
|
),
|
|
4244
4300
|
// A new machine per client/provider instance — options are pushed in
|
|
@@ -4281,7 +4337,7 @@ var DEFAULT_PERMISSIONS2 = {
|
|
|
4281
4337
|
canSubmitForms: true
|
|
4282
4338
|
};
|
|
4283
4339
|
function useAppilotsActions(options = {}) {
|
|
4284
|
-
const { client, subscribe, config, emit } =
|
|
4340
|
+
const { client, subscribe, config, emit } = chunkSUMIABJK_js.useAppilotsContext();
|
|
4285
4341
|
const { navigationRef, autoExecute = false } = options;
|
|
4286
4342
|
const runnerOptionsRef = React.useRef({
|
|
4287
4343
|
permissions: config.permissions ?? DEFAULT_PERMISSIONS2,
|
|
@@ -4296,12 +4352,12 @@ function useAppilotsActions(options = {}) {
|
|
|
4296
4352
|
suppressNativeConfirm: config.suppressNativeConfirm
|
|
4297
4353
|
};
|
|
4298
4354
|
const machine = React.useMemo(
|
|
4299
|
-
() => new
|
|
4355
|
+
() => new chunkSUMIABJK_js.ActionQueueMachine(
|
|
4300
4356
|
{
|
|
4301
4357
|
client,
|
|
4302
4358
|
adapter: createReactNativeActionRunner(() => runnerOptionsRef.current),
|
|
4303
4359
|
emit,
|
|
4304
|
-
warn:
|
|
4360
|
+
warn: chunkSUMIABJK_js.appilotsDebugWarn
|
|
4305
4361
|
},
|
|
4306
4362
|
{ autoExecute }
|
|
4307
4363
|
),
|
|
@@ -4358,7 +4414,7 @@ function shouldShowSuggestedPrompts(args) {
|
|
|
4358
4414
|
|
|
4359
4415
|
// src/hooks/useSuggestedPrompts.ts
|
|
4360
4416
|
function useSuggestedPrompts(options) {
|
|
4361
|
-
const { client } =
|
|
4417
|
+
const { client } = chunkSUMIABJK_js.useAppilotsContext();
|
|
4362
4418
|
const { enabled, limit = 4 } = options;
|
|
4363
4419
|
const [prompts, setPrompts] = React.useState([]);
|
|
4364
4420
|
const [isLoading, setIsLoading] = React.useState(false);
|
|
@@ -4368,8 +4424,8 @@ function useSuggestedPrompts(options) {
|
|
|
4368
4424
|
if (!enabled) return;
|
|
4369
4425
|
const requestId = ++requestIdRef.current;
|
|
4370
4426
|
let cancelled = false;
|
|
4371
|
-
const screen =
|
|
4372
|
-
const localDev = screen ? (
|
|
4427
|
+
const screen = chunkSUMIABJK_js.getCurrentScreen() ?? void 0;
|
|
4428
|
+
const localDev = screen ? (chunkSUMIABJK_js.getScreenMetadata(screen)?.suggestedPrompts ?? []).map((text) => ({
|
|
4373
4429
|
text,
|
|
4374
4430
|
source: "dev-defined"
|
|
4375
4431
|
})) : [];
|
|
@@ -4383,7 +4439,7 @@ function useSuggestedPrompts(options) {
|
|
|
4383
4439
|
if (cancelled || requestIdRef.current !== requestId) return;
|
|
4384
4440
|
setPrompts(mergePromptSources(localDev, data, limit));
|
|
4385
4441
|
}).catch((err) => {
|
|
4386
|
-
|
|
4442
|
+
chunkSUMIABJK_js.appilotsDebugWarn("useSuggestedPrompts: fetch failed", err);
|
|
4387
4443
|
}).finally(() => {
|
|
4388
4444
|
if (cancelled || requestIdRef.current !== requestId) return;
|
|
4389
4445
|
setIsLoading(false);
|
|
@@ -4394,9 +4450,9 @@ function useSuggestedPrompts(options) {
|
|
|
4394
4450
|
}, [client, enabled, limit, refreshTick]);
|
|
4395
4451
|
React.useEffect(() => {
|
|
4396
4452
|
if (!enabled) return;
|
|
4397
|
-
let lastScreen =
|
|
4453
|
+
let lastScreen = chunkSUMIABJK_js.getCurrentScreen();
|
|
4398
4454
|
const interval = setInterval(() => {
|
|
4399
|
-
const current =
|
|
4455
|
+
const current = chunkSUMIABJK_js.getCurrentScreen();
|
|
4400
4456
|
if (current !== lastScreen) {
|
|
4401
4457
|
lastScreen = current;
|
|
4402
4458
|
setRefreshTick((t) => t + 1);
|
|
@@ -4411,14 +4467,14 @@ function useSuggestedPrompts(options) {
|
|
|
4411
4467
|
};
|
|
4412
4468
|
}
|
|
4413
4469
|
function useAppilotsNavigation() {
|
|
4414
|
-
const { emit } =
|
|
4470
|
+
const { emit } = chunkSUMIABJK_js.useAppilotsContext();
|
|
4415
4471
|
const [currentScreen, setCurrentScreenState] = React.useState(null);
|
|
4416
4472
|
const [navigationHistory, setNavigationHistory] = React.useState([]);
|
|
4417
4473
|
const navigationRef = React.useRef(null);
|
|
4418
4474
|
const setCurrentScreen2 = React.useCallback(
|
|
4419
4475
|
(screenName) => {
|
|
4420
4476
|
setCurrentScreenState(screenName);
|
|
4421
|
-
|
|
4477
|
+
chunkSUMIABJK_js.setCurrentScreen(screenName);
|
|
4422
4478
|
setNavigationHistory((prev) => [...prev, screenName]);
|
|
4423
4479
|
emit({
|
|
4424
4480
|
type: "navigation:change",
|
|
@@ -4449,7 +4505,7 @@ function useAppilotsNavigation() {
|
|
|
4449
4505
|
|
|
4450
4506
|
// src/hooks/useAppilots.ts
|
|
4451
4507
|
function useAppilots() {
|
|
4452
|
-
const { config, client } =
|
|
4508
|
+
const { config, client } = chunkSUMIABJK_js.useAppilotsContext();
|
|
4453
4509
|
const chat = useAppilotsChat();
|
|
4454
4510
|
const navigation = useAppilotsNavigation();
|
|
4455
4511
|
const actions = useAppilotsActions();
|
|
@@ -4478,7 +4534,7 @@ function useAppilots() {
|
|
|
4478
4534
|
}
|
|
4479
4535
|
function useAppilotsField(id, options) {
|
|
4480
4536
|
const { value, onChangeText, ref, fieldType, label, screen } = options;
|
|
4481
|
-
const registry =
|
|
4537
|
+
const registry = chunkSUMIABJK_js.useResolvedRegistry();
|
|
4482
4538
|
const valueRef = React.useRef(value);
|
|
4483
4539
|
const onChangeRef = React.useRef(onChangeText);
|
|
4484
4540
|
valueRef.current = value;
|
|
@@ -4506,7 +4562,7 @@ function useAppilotsField(id, options) {
|
|
|
4506
4562
|
}
|
|
4507
4563
|
function useAppilotsTarget(id, options) {
|
|
4508
4564
|
const { onPress, onLongPress, onScrollTo, label, screen } = options;
|
|
4509
|
-
const registry =
|
|
4565
|
+
const registry = chunkSUMIABJK_js.useResolvedRegistry();
|
|
4510
4566
|
const onPressRef = React.useRef(onPress);
|
|
4511
4567
|
const onLongPressRef = React.useRef(onLongPress);
|
|
4512
4568
|
const onScrollToRef = React.useRef(onScrollTo);
|
|
@@ -4533,7 +4589,7 @@ function useAppilotsTarget(id, options) {
|
|
|
4533
4589
|
}
|
|
4534
4590
|
function useAppilotsToggle(id, options) {
|
|
4535
4591
|
const { value, onValueChange, label, screen } = options;
|
|
4536
|
-
const registry =
|
|
4592
|
+
const registry = chunkSUMIABJK_js.useResolvedRegistry();
|
|
4537
4593
|
const valueRef = React.useRef(value);
|
|
4538
4594
|
const onChangeRef = React.useRef(onValueChange);
|
|
4539
4595
|
valueRef.current = value;
|
|
@@ -4556,7 +4612,7 @@ function useAppilotsToggle(id, options) {
|
|
|
4556
4612
|
}
|
|
4557
4613
|
function useAppilotsSlider(id, options) {
|
|
4558
4614
|
const { value, onValueChange, min, max, step, label, screen } = options;
|
|
4559
|
-
const registry =
|
|
4615
|
+
const registry = chunkSUMIABJK_js.useResolvedRegistry();
|
|
4560
4616
|
const valueRef = React.useRef(value);
|
|
4561
4617
|
const onChangeRef = React.useRef(onValueChange);
|
|
4562
4618
|
valueRef.current = value;
|