@appilots/sdk 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -0
- package/dist/{chunk-DZ7QRFHD.js → chunk-AYWMBMSN.js} +255 -17
- package/dist/{chunk-R4D34FEW.mjs → chunk-C2KVVJ5K.mjs} +253 -17
- package/dist/{chunk-KYFAXT6V.js → chunk-H7BMQTXH.js} +5 -5
- package/dist/{chunk-KUFWRJC4.mjs → chunk-MHWVRZYF.mjs} +100 -35
- package/dist/{chunk-HFRIB4YN.js → chunk-N7EAOLBP.js} +259 -194
- package/dist/{chunk-DR75QTYK.mjs → chunk-ZSEACJKU.mjs} +1 -1
- 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-nI-s3Exg.d.mts → index-BdYY-dvG.d.mts} +63 -11
- package/dist/{index-nI-s3Exg.d.ts → index-BdYY-dvG.d.ts} +63 -11
- package/dist/index.d.mts +30 -12
- package/dist/index.d.ts +30 -12
- package/dist/index.js +72 -67
- package/dist/index.mjs +10 -5
- package/dist/navigation/index.js +13 -13
- package/dist/navigation/index.mjs +2 -2
- package/package.json +13 -5
|
@@ -76,7 +76,9 @@ var AppilotsClient = class {
|
|
|
76
76
|
"Content-Type": "application/json",
|
|
77
77
|
// Version telemetry: lets the server correlate behavior per SDK
|
|
78
78
|
// release and pick the MCP doc matching this app build (B.4).
|
|
79
|
-
|
|
79
|
+
// The platform SDK supplies its own published version; the
|
|
80
|
+
// client-core constant is only the fallback (see `sdkVersion`).
|
|
81
|
+
"X-Appilots-Sdk-Version": options.sdkVersion ?? SDK_VERSION,
|
|
80
82
|
...options.appVersion ? { "X-App-Version": options.appVersion } : {},
|
|
81
83
|
...options.mcpVersion ? { "X-Appilots-Mcp-Version": options.mcpVersion } : {},
|
|
82
84
|
...options.apiKey ? { Authorization: `Bearer ${options.apiKey}` } : {},
|
|
@@ -191,7 +193,8 @@ var AppilotsClient = class {
|
|
|
191
193
|
introspectionFragment() {
|
|
192
194
|
try {
|
|
193
195
|
const report = this.introspectionReporter?.();
|
|
194
|
-
if (!report
|
|
196
|
+
if (!report) return {};
|
|
197
|
+
if (report.captured !== false && !report.failureReason) return {};
|
|
195
198
|
return { introspection: report };
|
|
196
199
|
} catch {
|
|
197
200
|
return {};
|
|
@@ -2842,6 +2845,114 @@ function attachElementIdsToChoiceGroups(choiceGroups, elements) {
|
|
|
2842
2845
|
})
|
|
2843
2846
|
}));
|
|
2844
2847
|
}
|
|
2848
|
+
var WIRE_LIMITS = {
|
|
2849
|
+
route: 200,
|
|
2850
|
+
texts: 500,
|
|
2851
|
+
textLength: 2e3,
|
|
2852
|
+
inputs: 300,
|
|
2853
|
+
buttons: 300,
|
|
2854
|
+
toggles: 300,
|
|
2855
|
+
sliders: 100,
|
|
2856
|
+
lists: 100,
|
|
2857
|
+
listItems: 500,
|
|
2858
|
+
listDataPreview: 500,
|
|
2859
|
+
listDataPreviewTextLength: 500,
|
|
2860
|
+
choiceGroups: 100,
|
|
2861
|
+
choiceOptions: 200,
|
|
2862
|
+
elements: 1e3,
|
|
2863
|
+
elementTexts: 50,
|
|
2864
|
+
elementTextLength: 500,
|
|
2865
|
+
elementActions: 20,
|
|
2866
|
+
idLength: 160,
|
|
2867
|
+
labelLength: 300,
|
|
2868
|
+
valueLength: 4096,
|
|
2869
|
+
containerTypeLength: 60};
|
|
2870
|
+
var Cut = class {
|
|
2871
|
+
dropped = false;
|
|
2872
|
+
/** Cap an array's length, remembering whether entries were lost. */
|
|
2873
|
+
array(values, max) {
|
|
2874
|
+
if (!values || values.length <= max) return values;
|
|
2875
|
+
this.dropped = true;
|
|
2876
|
+
return values.slice(0, max);
|
|
2877
|
+
}
|
|
2878
|
+
string(value, max) {
|
|
2879
|
+
if (value === void 0 || value.length <= max) return value;
|
|
2880
|
+
this.dropped = true;
|
|
2881
|
+
return value.slice(0, max);
|
|
2882
|
+
}
|
|
2883
|
+
};
|
|
2884
|
+
function clampInput(cut, input) {
|
|
2885
|
+
input.id = cut.string(input.id, WIRE_LIMITS.idLength);
|
|
2886
|
+
input.label = cut.string(input.label, WIRE_LIMITS.labelLength);
|
|
2887
|
+
input.placeholder = cut.string(input.placeholder, WIRE_LIMITS.labelLength);
|
|
2888
|
+
input.value = cut.string(input.value, WIRE_LIMITS.valueLength);
|
|
2889
|
+
return input;
|
|
2890
|
+
}
|
|
2891
|
+
function clampList(cut, list) {
|
|
2892
|
+
list.id = cut.string(list.id, WIRE_LIMITS.idLength);
|
|
2893
|
+
list.containerType = cut.string(list.containerType, WIRE_LIMITS.containerTypeLength);
|
|
2894
|
+
list.label = cut.string(list.label, WIRE_LIMITS.labelLength);
|
|
2895
|
+
list.items = cut.array(list.items, WIRE_LIMITS.listItems) ?? [];
|
|
2896
|
+
if (list.dataPreview) {
|
|
2897
|
+
list.dataPreview = cut.array(list.dataPreview, WIRE_LIMITS.listDataPreview);
|
|
2898
|
+
for (const entry of list.dataPreview ?? []) {
|
|
2899
|
+
entry.key = cut.string(entry.key, WIRE_LIMITS.idLength);
|
|
2900
|
+
entry.text = cut.string(entry.text, WIRE_LIMITS.listDataPreviewTextLength);
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
return list;
|
|
2904
|
+
}
|
|
2905
|
+
function clampChoiceGroup(cut, group) {
|
|
2906
|
+
group.id = cut.string(group.id, WIRE_LIMITS.idLength);
|
|
2907
|
+
group.label = cut.string(group.label, WIRE_LIMITS.labelLength);
|
|
2908
|
+
group.options = cut.array(group.options, WIRE_LIMITS.choiceOptions) ?? [];
|
|
2909
|
+
return group;
|
|
2910
|
+
}
|
|
2911
|
+
function clampSnapshotToWireLimits(snapshot) {
|
|
2912
|
+
const cut = new Cut();
|
|
2913
|
+
if (typeof snapshot.route === "string") {
|
|
2914
|
+
snapshot.route = cut.string(snapshot.route, WIRE_LIMITS.route);
|
|
2915
|
+
}
|
|
2916
|
+
snapshot.texts = (cut.array(snapshot.texts, WIRE_LIMITS.texts) ?? []).map(
|
|
2917
|
+
(text) => cut.string(text, WIRE_LIMITS.textLength)
|
|
2918
|
+
);
|
|
2919
|
+
snapshot.inputs = (cut.array(snapshot.inputs, WIRE_LIMITS.inputs) ?? []).map(
|
|
2920
|
+
(input) => clampInput(cut, input)
|
|
2921
|
+
);
|
|
2922
|
+
snapshot.buttons = (cut.array(snapshot.buttons, WIRE_LIMITS.buttons) ?? []).map((button) => {
|
|
2923
|
+
button.id = cut.string(button.id, WIRE_LIMITS.idLength);
|
|
2924
|
+
button.label = cut.string(button.label, WIRE_LIMITS.labelLength);
|
|
2925
|
+
return button;
|
|
2926
|
+
});
|
|
2927
|
+
snapshot.toggles = (cut.array(snapshot.toggles, WIRE_LIMITS.toggles) ?? []).map((toggle) => {
|
|
2928
|
+
toggle.id = cut.string(toggle.id, WIRE_LIMITS.idLength);
|
|
2929
|
+
toggle.label = cut.string(toggle.label, WIRE_LIMITS.labelLength);
|
|
2930
|
+
return toggle;
|
|
2931
|
+
});
|
|
2932
|
+
snapshot.sliders = (cut.array(snapshot.sliders, WIRE_LIMITS.sliders) ?? []).map((slider) => {
|
|
2933
|
+
slider.id = cut.string(slider.id, WIRE_LIMITS.idLength);
|
|
2934
|
+
slider.label = cut.string(slider.label, WIRE_LIMITS.labelLength);
|
|
2935
|
+
return slider;
|
|
2936
|
+
});
|
|
2937
|
+
snapshot.lists = (cut.array(snapshot.lists, WIRE_LIMITS.lists) ?? []).map(
|
|
2938
|
+
(list) => clampList(cut, list)
|
|
2939
|
+
);
|
|
2940
|
+
snapshot.choiceGroups = (cut.array(snapshot.choiceGroups, WIRE_LIMITS.choiceGroups) ?? []).map(
|
|
2941
|
+
(group) => clampChoiceGroup(cut, group)
|
|
2942
|
+
);
|
|
2943
|
+
snapshot.elements = (cut.array(snapshot.elements, WIRE_LIMITS.elements) ?? []).map((element) => {
|
|
2944
|
+
element.id = cut.string(element.id, WIRE_LIMITS.idLength);
|
|
2945
|
+
element.label = cut.string(element.label, WIRE_LIMITS.labelLength);
|
|
2946
|
+
element.targetId = cut.string(element.targetId, WIRE_LIMITS.idLength);
|
|
2947
|
+
element.texts = (cut.array(element.texts, WIRE_LIMITS.elementTexts) ?? []).map(
|
|
2948
|
+
(text) => cut.string(text, WIRE_LIMITS.elementTextLength)
|
|
2949
|
+
);
|
|
2950
|
+
element.actions = cut.array(element.actions, WIRE_LIMITS.elementActions) ?? [];
|
|
2951
|
+
return element;
|
|
2952
|
+
});
|
|
2953
|
+
if (cut.dropped) snapshot.truncated = true;
|
|
2954
|
+
return snapshot;
|
|
2955
|
+
}
|
|
2845
2956
|
|
|
2846
2957
|
// src/registry/ComponentRegistry.ts
|
|
2847
2958
|
var ComponentRegistryImpl = class {
|
|
@@ -3119,6 +3230,40 @@ function sectionListFlatIndex(sections, section, localIndex) {
|
|
|
3119
3230
|
return base + localIndex;
|
|
3120
3231
|
}
|
|
3121
3232
|
|
|
3233
|
+
// src/auto/interceptGuard.ts
|
|
3234
|
+
var _intercept = null;
|
|
3235
|
+
var _failures = 0;
|
|
3236
|
+
var INTERCEPT_FAILURE_LIMIT = 25;
|
|
3237
|
+
function setInterceptor(fn) {
|
|
3238
|
+
_intercept = fn;
|
|
3239
|
+
_failures = 0;
|
|
3240
|
+
}
|
|
3241
|
+
function isInterceptionActive() {
|
|
3242
|
+
return _intercept !== null;
|
|
3243
|
+
}
|
|
3244
|
+
function safeIntercept(type, props) {
|
|
3245
|
+
const intercept = _intercept;
|
|
3246
|
+
if (!intercept) return null;
|
|
3247
|
+
try {
|
|
3248
|
+
return intercept(type, props);
|
|
3249
|
+
} catch (err) {
|
|
3250
|
+
_failures += 1;
|
|
3251
|
+
if (_failures === 1) {
|
|
3252
|
+
console.error(
|
|
3253
|
+
"[Appilots] Auto-tracking failed to inspect an element and passed it through unchanged. Your app is unaffected; the agent may not see this component. This is an Appilots bug \u2014 please report it: https://github.com/Axtern-Labs/Appilots/issues",
|
|
3254
|
+
err
|
|
3255
|
+
);
|
|
3256
|
+
}
|
|
3257
|
+
if (_failures >= INTERCEPT_FAILURE_LIMIT) {
|
|
3258
|
+
_intercept = null;
|
|
3259
|
+
console.error(
|
|
3260
|
+
`[Appilots] Auto-tracking disabled after ${INTERCEPT_FAILURE_LIMIT} failures. The agent will only see components registered explicitly via registerScreen(). Your app is unaffected.`
|
|
3261
|
+
);
|
|
3262
|
+
}
|
|
3263
|
+
return null;
|
|
3264
|
+
}
|
|
3265
|
+
}
|
|
3266
|
+
|
|
3122
3267
|
// src/auto/enableAutoTracking.tsx
|
|
3123
3268
|
function extractId(props) {
|
|
3124
3269
|
const raw = props?.testID ?? props?.nativeID ?? props?.id ?? props?.accessibilityLabel ?? props?.name ?? props?.placeholder ?? (typeof props?.autoComplete === "string" && props.autoComplete !== "off" ? props.autoComplete : void 0);
|
|
@@ -3577,15 +3722,15 @@ function enableAppilotsAutoTracking(options) {
|
|
|
3577
3722
|
}
|
|
3578
3723
|
return null;
|
|
3579
3724
|
}
|
|
3725
|
+
setInterceptor(interceptType);
|
|
3580
3726
|
React2.createElement = function(type, props, ...children) {
|
|
3581
|
-
const replacement =
|
|
3727
|
+
const replacement = safeIntercept(type, props);
|
|
3582
3728
|
if (replacement) {
|
|
3583
3729
|
return originalCreateElement(replacement.type, replacement.props, ...children);
|
|
3584
3730
|
}
|
|
3585
3731
|
return originalCreateElement(type, props, ...children);
|
|
3586
3732
|
};
|
|
3587
3733
|
console.log("[Appilots] Auto-tracking: React.createElement patched");
|
|
3588
|
-
_interceptType = interceptType;
|
|
3589
3734
|
try {
|
|
3590
3735
|
const jsxRuntime = __require("react/jsx-runtime");
|
|
3591
3736
|
if (jsxRuntime) {
|
|
@@ -3603,18 +3748,16 @@ function enableAppilotsAutoTracking(options) {
|
|
|
3603
3748
|
console.log("[Appilots] Auto-tracking: react/jsx-dev-runtime not available internally (will be patched by metro shim)");
|
|
3604
3749
|
}
|
|
3605
3750
|
}
|
|
3606
|
-
var _interceptType = null;
|
|
3607
3751
|
var _jsxRuntimePatched = false;
|
|
3608
3752
|
var _jsxDevRuntimePatched = false;
|
|
3609
3753
|
function _patchJsxRuntimeModule(jsxRuntime) {
|
|
3610
|
-
if (_jsxRuntimePatched || !
|
|
3754
|
+
if (_jsxRuntimePatched || !isInterceptionActive() || !jsxRuntime) return;
|
|
3611
3755
|
_jsxRuntimePatched = true;
|
|
3612
|
-
const interceptType = _interceptType;
|
|
3613
3756
|
const origJsx = jsxRuntime.jsx;
|
|
3614
3757
|
const origJsxs = jsxRuntime.jsxs;
|
|
3615
3758
|
if (origJsx) {
|
|
3616
3759
|
jsxRuntime.jsx = function(type, props, key) {
|
|
3617
|
-
const replacement =
|
|
3760
|
+
const replacement = safeIntercept(type, props);
|
|
3618
3761
|
if (replacement) {
|
|
3619
3762
|
return origJsx(replacement.type, replacement.props, key);
|
|
3620
3763
|
}
|
|
@@ -3624,7 +3767,7 @@ function _patchJsxRuntimeModule(jsxRuntime) {
|
|
|
3624
3767
|
}
|
|
3625
3768
|
if (origJsxs) {
|
|
3626
3769
|
jsxRuntime.jsxs = function(type, props, key) {
|
|
3627
|
-
const replacement =
|
|
3770
|
+
const replacement = safeIntercept(type, props);
|
|
3628
3771
|
if (replacement) {
|
|
3629
3772
|
return origJsxs(replacement.type, replacement.props, key);
|
|
3630
3773
|
}
|
|
@@ -3634,13 +3777,12 @@ function _patchJsxRuntimeModule(jsxRuntime) {
|
|
|
3634
3777
|
}
|
|
3635
3778
|
}
|
|
3636
3779
|
function _patchJsxDevRuntimeModule(jsxDevRuntime) {
|
|
3637
|
-
if (_jsxDevRuntimePatched || !
|
|
3780
|
+
if (_jsxDevRuntimePatched || !isInterceptionActive() || !jsxDevRuntime) return;
|
|
3638
3781
|
_jsxDevRuntimePatched = true;
|
|
3639
|
-
const interceptType = _interceptType;
|
|
3640
3782
|
if (jsxDevRuntime.jsxDEV) {
|
|
3641
3783
|
const origJsxDEV = jsxDevRuntime.jsxDEV;
|
|
3642
3784
|
jsxDevRuntime.jsxDEV = function(type, props, key, isStaticChildren, source, self) {
|
|
3643
|
-
const replacement =
|
|
3785
|
+
const replacement = safeIntercept(type, props);
|
|
3644
3786
|
if (replacement) {
|
|
3645
3787
|
return origJsxDEV(replacement.type, replacement.props, key, isStaticChildren, source, self);
|
|
3646
3788
|
}
|
|
@@ -3650,7 +3792,7 @@ function _patchJsxDevRuntimeModule(jsxDevRuntime) {
|
|
|
3650
3792
|
}
|
|
3651
3793
|
}
|
|
3652
3794
|
function _patchJsxRuntimes(jsxRuntime, jsxDevRuntime) {
|
|
3653
|
-
if (!
|
|
3795
|
+
if (!isInterceptionActive()) {
|
|
3654
3796
|
console.warn("[Appilots] _patchJsxRuntimes called but auto-tracking is not enabled");
|
|
3655
3797
|
return;
|
|
3656
3798
|
}
|
|
@@ -3720,7 +3862,14 @@ function setFiberRoot(fiber) {
|
|
|
3720
3862
|
_diagnostics.captured = true;
|
|
3721
3863
|
}
|
|
3722
3864
|
function getFiberRoot() {
|
|
3723
|
-
return _fiberRoot;
|
|
3865
|
+
return resolveCurrentRoot(_fiberRoot);
|
|
3866
|
+
}
|
|
3867
|
+
function resolveCurrentRoot(fiber) {
|
|
3868
|
+
const current = fiber?.stateNode?.current;
|
|
3869
|
+
if (current && (current === fiber || current.alternate === fiber)) {
|
|
3870
|
+
return current;
|
|
3871
|
+
}
|
|
3872
|
+
return fiber;
|
|
3724
3873
|
}
|
|
3725
3874
|
function recordIntrospectionFailure(reason, reactVersion) {
|
|
3726
3875
|
_diagnostics.failureCount += 1;
|
|
@@ -3729,6 +3878,13 @@ function recordIntrospectionFailure(reason, reactVersion) {
|
|
|
3729
3878
|
_diagnostics.reactVersion = reactVersion;
|
|
3730
3879
|
}
|
|
3731
3880
|
}
|
|
3881
|
+
function recordRenderFailure(reactVersion) {
|
|
3882
|
+
_fiberRoot = null;
|
|
3883
|
+
_diagnostics.captured = false;
|
|
3884
|
+
_diagnostics.failureCount += 1;
|
|
3885
|
+
_diagnostics.failureReason = "render-crashed";
|
|
3886
|
+
_diagnostics.reactVersion = reactVersion;
|
|
3887
|
+
}
|
|
3732
3888
|
function getIntrospectionDiagnostics() {
|
|
3733
3889
|
return { ..._diagnostics };
|
|
3734
3890
|
}
|
|
@@ -3740,6 +3896,9 @@ function typeName(fiber) {
|
|
|
3740
3896
|
if (typeof t === "object") return t.displayName ?? t.render?.displayName ?? t.render?.name ?? "forwardRef/memo";
|
|
3741
3897
|
return String(t);
|
|
3742
3898
|
}
|
|
3899
|
+
|
|
3900
|
+
// src/version.ts
|
|
3901
|
+
var SDK_VERSION2 = "0.8.0";
|
|
3743
3902
|
var FiberSentinel = class extends React2.Component {
|
|
3744
3903
|
componentDidMount() {
|
|
3745
3904
|
const fiber = this._reactInternals ?? this._reactInternalFiber ?? null;
|
|
@@ -3789,10 +3948,83 @@ function appilotsDebugWarn(...args) {
|
|
|
3789
3948
|
if (!isDebugEnabled()) return;
|
|
3790
3949
|
console.log("[Appilots]", ...args);
|
|
3791
3950
|
}
|
|
3951
|
+
var AppilotsErrorBoundary = class extends React2.Component {
|
|
3952
|
+
state = { degraded: false, escalate: null };
|
|
3953
|
+
/**
|
|
3954
|
+
* Instance field rather than state: `componentDidCatch` needs to know
|
|
3955
|
+
* whether THIS is the first failure, and by the time it runs
|
|
3956
|
+
* `getDerivedStateFromError` has already flipped `state.degraded`.
|
|
3957
|
+
*/
|
|
3958
|
+
hasDegradedOnce = false;
|
|
3959
|
+
static getDerivedStateFromError() {
|
|
3960
|
+
return { degraded: true };
|
|
3961
|
+
}
|
|
3962
|
+
componentDidCatch(error, info) {
|
|
3963
|
+
if (this.hasDegradedOnce) {
|
|
3964
|
+
this.setState({ escalate: error ?? new Error("Appilots: re-thrown host render error") });
|
|
3965
|
+
return;
|
|
3966
|
+
}
|
|
3967
|
+
this.hasDegradedOnce = true;
|
|
3968
|
+
console.error(
|
|
3969
|
+
`[Appilots] The Appilots ${this.props.surface} threw while rendering and has been disabled for the rest of this session. Your app keeps running \u2014 this is an Appilots bug, not a bug in your code. Please report it with the stack below: https://github.com/Axtern-Labs/Appilots/issues`,
|
|
3970
|
+
error
|
|
3971
|
+
);
|
|
3972
|
+
try {
|
|
3973
|
+
this.props.onError?.(error, info?.componentStack ?? null);
|
|
3974
|
+
} catch {
|
|
3975
|
+
}
|
|
3976
|
+
}
|
|
3977
|
+
render() {
|
|
3978
|
+
if (this.state.escalate !== null) throw this.state.escalate;
|
|
3979
|
+
if (this.state.degraded) return this.props.fallback;
|
|
3980
|
+
return this.props.children;
|
|
3981
|
+
}
|
|
3982
|
+
};
|
|
3792
3983
|
|
|
3793
3984
|
// src/context/AppilotsProvider.tsx
|
|
3794
3985
|
var AppilotsContext = createContext(null);
|
|
3795
|
-
function
|
|
3986
|
+
function createInertClient() {
|
|
3987
|
+
const unavailable = () => Promise.reject(
|
|
3988
|
+
new Error("Appilots is unavailable: the SDK degraded after a render error.")
|
|
3989
|
+
);
|
|
3990
|
+
return new Proxy({}, {
|
|
3991
|
+
get: (_target, prop) => {
|
|
3992
|
+
if (prop === "then" || typeof prop === "symbol") return void 0;
|
|
3993
|
+
return unavailable;
|
|
3994
|
+
}
|
|
3995
|
+
});
|
|
3996
|
+
}
|
|
3997
|
+
function createDegradedContext(config) {
|
|
3998
|
+
return {
|
|
3999
|
+
config: config ?? { projectId: "" },
|
|
4000
|
+
client: createInertClient(),
|
|
4001
|
+
subscribe: () => () => {
|
|
4002
|
+
},
|
|
4003
|
+
emit: () => {
|
|
4004
|
+
},
|
|
4005
|
+
remotePersonalization: null,
|
|
4006
|
+
degraded: true
|
|
4007
|
+
};
|
|
4008
|
+
}
|
|
4009
|
+
function AppilotsProvider({ config, children, client }) {
|
|
4010
|
+
return /* @__PURE__ */ React2.createElement(
|
|
4011
|
+
AppilotsErrorBoundary,
|
|
4012
|
+
{
|
|
4013
|
+
surface: "provider",
|
|
4014
|
+
onError: reportProviderRenderFailure,
|
|
4015
|
+
fallback: /* @__PURE__ */ React2.createElement(AppilotsContext.Provider, { value: createDegradedContext(config ?? null) }, children)
|
|
4016
|
+
},
|
|
4017
|
+
/* @__PURE__ */ React2.createElement(AppilotsProviderInner, { config, client }, children)
|
|
4018
|
+
);
|
|
4019
|
+
}
|
|
4020
|
+
function reportProviderRenderFailure() {
|
|
4021
|
+
recordRenderFailure(readReactVersion());
|
|
4022
|
+
}
|
|
4023
|
+
function readReactVersion() {
|
|
4024
|
+
const version = React2.version;
|
|
4025
|
+
return typeof version === "string" ? version : null;
|
|
4026
|
+
}
|
|
4027
|
+
function AppilotsProviderInner({ config: configProp, children, client: externalClient }) {
|
|
3796
4028
|
console.log(`[Appilots] AppilotsProvider initializing \u2014 config source: ${configProp ? "prop" : "auto (globalThis.__APPILOTS_RC__)"}`);
|
|
3797
4029
|
tryAutoConfig();
|
|
3798
4030
|
const globalConfig = getGlobalConfig();
|
|
@@ -3805,7 +4037,8 @@ function AppilotsProvider({ config: configProp, children, client: externalClient
|
|
|
3805
4037
|
debug: globalConfig.debug,
|
|
3806
4038
|
appVersion: globalConfig.appVersion,
|
|
3807
4039
|
mcpVersion: globalConfig.mcpVersion,
|
|
3808
|
-
fetchPersonalization: globalConfig.fetchPersonalization
|
|
4040
|
+
fetchPersonalization: globalConfig.fetchPersonalization,
|
|
4041
|
+
suppressNativeConfirm: globalConfig.suppressNativeConfirm
|
|
3809
4042
|
} : null);
|
|
3810
4043
|
if (!config?.projectId) {
|
|
3811
4044
|
throw new Error(
|
|
@@ -3844,6 +4077,9 @@ function AppilotsProvider({ config: configProp, children, client: externalClient
|
|
|
3844
4077
|
debug: config.debug,
|
|
3845
4078
|
appVersion: config.appVersion,
|
|
3846
4079
|
mcpVersion: config.mcpVersion,
|
|
4080
|
+
// This package's published version, so the server knows which
|
|
4081
|
+
// SDK is actually in the field (issue #312).
|
|
4082
|
+
sdkVersion: SDK_VERSION2,
|
|
3847
4083
|
user: config.user,
|
|
3848
4084
|
// Only reports a FAILED reading; the happy path sends nothing.
|
|
3849
4085
|
introspectionReporter: getIntrospectionDiagnostics
|
|
@@ -4386,4 +4622,4 @@ function clearScreenRegistry() {
|
|
|
4386
4622
|
screenRegistry.clear();
|
|
4387
4623
|
}
|
|
4388
4624
|
|
|
4389
|
-
export { ActionQueueMachine, AppilotsClient, AppilotsProvider, AppilotsRegistryProvider, ChatSessionMachine, OPTIONAL_STEP_AUTOMATION_HINT, RateLimitedError, SDK_VERSION, _patchJsxRuntimes, actionPressTargetId, appilotsDebugLog, appilotsDebugWarn, attachElementIdsToChoiceGroups, clearAppilotsDebugTraces, clearScreenRegistry, componentRegistry, createComponentRegistry, createElementRegistry, createListRegistry, defaultDarkTheme, defaultLightTheme, deriveInteractionElements, describeAction, elementRegistry, enableAppilotsAutoTracking, getActiveRouteNames, getAllScreens, getAppilotsDebugTraces, getCurrentScreen, getCurrentScreenSignature, getDefaultRegistry, getFiberRoot, getGlobalConfig, getIntrospectionDiagnostics, getNavigationRef, getNavigationStateSnapshot, getScreenMetadata, humanizeError, idLooselyMatches, initAppilots, isAutoTrackingEnabled, isGenericSelectValue, isListItemPressTarget, isOptionalStepAutomationFailure, listRegistry, looksDestructiveActionLabel, matchScore, mergeThemeTokens, normalize3, parseStableElementId, probeLoadingState, recordAppilotsDebugTrace, recordIntrospectionFailure, registerScreen, resolveBaseTheme, routesBelongToSameFeature, screenDepartedBaseline, setCurrentScreen, setNavigationRef, snapshotShowsOpenCreateForm, subscribeAppilotsDebugTraces, useAppilotsContext, useResolvedRegistry, waitForLoadingSettle, waitForScreenSettle };
|
|
4625
|
+
export { ActionQueueMachine, AppilotsClient, AppilotsErrorBoundary, AppilotsProvider, AppilotsRegistryProvider, ChatSessionMachine, OPTIONAL_STEP_AUTOMATION_HINT, RateLimitedError, SDK_VERSION2 as SDK_VERSION, _patchJsxRuntimes, actionPressTargetId, appilotsDebugLog, appilotsDebugWarn, attachElementIdsToChoiceGroups, clampSnapshotToWireLimits, clearAppilotsDebugTraces, clearScreenRegistry, componentRegistry, createComponentRegistry, createElementRegistry, createListRegistry, defaultDarkTheme, defaultLightTheme, deriveInteractionElements, describeAction, elementRegistry, enableAppilotsAutoTracking, getActiveRouteNames, getAllScreens, getAppilotsDebugTraces, getCurrentScreen, getCurrentScreenSignature, getDefaultRegistry, getFiberRoot, getGlobalConfig, getIntrospectionDiagnostics, getNavigationRef, getNavigationStateSnapshot, getScreenMetadata, humanizeError, idLooselyMatches, initAppilots, isAutoTrackingEnabled, isGenericSelectValue, isListItemPressTarget, isOptionalStepAutomationFailure, listRegistry, looksDestructiveActionLabel, matchScore, mergeThemeTokens, normalize3, parseStableElementId, probeLoadingState, recordAppilotsDebugTrace, recordIntrospectionFailure, registerScreen, resolveBaseTheme, routesBelongToSameFeature, screenDepartedBaseline, setCurrentScreen, setNavigationRef, snapshotShowsOpenCreateForm, subscribeAppilotsDebugTraces, useAppilotsContext, useResolvedRegistry, waitForLoadingSettle, waitForScreenSettle };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkAYWMBMSN_js = require('./chunk-AYWMBMSN.js');
|
|
4
4
|
var React = require('react');
|
|
5
5
|
|
|
6
6
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -15,11 +15,11 @@ function getActiveRouteName(state) {
|
|
|
15
15
|
return route.name;
|
|
16
16
|
}
|
|
17
17
|
function AppilotsNavigationContainer({ children }) {
|
|
18
|
-
const { emit } =
|
|
18
|
+
const { emit } = chunkAYWMBMSN_js.useAppilotsContext();
|
|
19
19
|
const internalRef = React.useRef(null);
|
|
20
20
|
const handleRef = React.useCallback((instance) => {
|
|
21
21
|
internalRef.current = instance;
|
|
22
|
-
|
|
22
|
+
chunkAYWMBMSN_js.setNavigationRef(instance);
|
|
23
23
|
const childRef = children.ref;
|
|
24
24
|
if (typeof childRef === "function") childRef(instance);
|
|
25
25
|
else if (childRef && typeof childRef === "object") childRef.current = instance;
|
|
@@ -32,7 +32,7 @@ function AppilotsNavigationContainer({ children }) {
|
|
|
32
32
|
const routeName = getActiveRouteName(state);
|
|
33
33
|
if (routeName) {
|
|
34
34
|
console.log(`[Appilots] Screen changed \u2192 "${routeName}"`);
|
|
35
|
-
|
|
35
|
+
chunkAYWMBMSN_js.setCurrentScreen(routeName);
|
|
36
36
|
emit({
|
|
37
37
|
type: "navigation:change",
|
|
38
38
|
timestamp: Date.now(),
|
|
@@ -48,7 +48,7 @@ function AppilotsNavigationContainer({ children }) {
|
|
|
48
48
|
const route = internalRef.current?.getCurrentRoute?.();
|
|
49
49
|
if (route?.name) {
|
|
50
50
|
console.log(`[Appilots] Initial screen \u2192 "${route.name}"`);
|
|
51
|
-
|
|
51
|
+
chunkAYWMBMSN_js.setCurrentScreen(route.name);
|
|
52
52
|
emit({
|
|
53
53
|
type: "navigation:change",
|
|
54
54
|
timestamp: Date.now(),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getFiberRoot, recordIntrospectionFailure, getCurrentScreen, getActiveRouteNames, deriveInteractionElements, attachElementIdsToChoiceGroups, elementRegistry, appilotsDebugWarn, getDefaultRegistry, useAppilotsContext, ChatSessionMachine, getCurrentScreenSignature, ActionQueueMachine, getScreenMetadata, setCurrentScreen, useResolvedRegistry, listRegistry, componentRegistry, probeLoadingState, isListItemPressTarget, waitForLoadingSettle, appilotsDebugLog, waitForScreenSettle, screenDepartedBaseline, routesBelongToSameFeature, actionPressTargetId, getNavigationStateSnapshot, getNavigationRef, isOptionalStepAutomationFailure, OPTIONAL_STEP_AUTOMATION_HINT, normalize3, matchScore, idLooselyMatches, parseStableElementId, getAllScreens, snapshotShowsOpenCreateForm, looksDestructiveActionLabel, isGenericSelectValue } from './chunk-
|
|
1
|
+
import { getFiberRoot, recordIntrospectionFailure, getCurrentScreen, getActiveRouteNames, clampSnapshotToWireLimits, deriveInteractionElements, attachElementIdsToChoiceGroups, elementRegistry, appilotsDebugWarn, getDefaultRegistry, useAppilotsContext, ChatSessionMachine, getCurrentScreenSignature, ActionQueueMachine, getScreenMetadata, setCurrentScreen, useResolvedRegistry, listRegistry, componentRegistry, probeLoadingState, isListItemPressTarget, waitForLoadingSettle, appilotsDebugLog, waitForScreenSettle, screenDepartedBaseline, routesBelongToSameFeature, actionPressTargetId, getNavigationStateSnapshot, getNavigationRef, isOptionalStepAutomationFailure, OPTIONAL_STEP_AUTOMATION_HINT, normalize3, matchScore, idLooselyMatches, parseStableElementId, getAllScreens, snapshotShowsOpenCreateForm, looksDestructiveActionLabel, isGenericSelectValue } from './chunk-C2KVVJ5K.mjs';
|
|
2
2
|
import { useMemo, useRef, useSyncExternalStore, useEffect, useCallback, useState } from 'react';
|
|
3
3
|
import { Alert } from 'react-native';
|
|
4
4
|
|
|
@@ -770,11 +770,13 @@ function captureSnapshot() {
|
|
|
770
770
|
if (deepestRoute) snapshot.route = deepestRoute;
|
|
771
771
|
mergeRegisteredLists(snapshot);
|
|
772
772
|
reconcileSliders(snapshot);
|
|
773
|
+
clampSnapshotToWireLimits(snapshot);
|
|
773
774
|
snapshot.elements = deriveInteractionElements(snapshot);
|
|
774
775
|
snapshot.choiceGroups = attachElementIdsToChoiceGroups(
|
|
775
776
|
snapshot.choiceGroups,
|
|
776
777
|
snapshot.elements
|
|
777
778
|
);
|
|
779
|
+
clampSnapshotToWireLimits(snapshot);
|
|
778
780
|
elementRegistry.replaceAll(snapshot.elements);
|
|
779
781
|
const elapsed = Date.now() - start;
|
|
780
782
|
const totalListItems = snapshot.lists.reduce(
|
|
@@ -786,7 +788,7 @@ function captureSnapshot() {
|
|
|
786
788
|
0
|
|
787
789
|
);
|
|
788
790
|
console.log(
|
|
789
|
-
`[Appilots] 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} (walked ${snapshot.stats?.visitedFibers ?? 0} fibers, skipped ${snapshot.stats?.skippedHidden ?? 0} hidden, ${elapsed}ms)`
|
|
791
|
+
`[Appilots] 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)`
|
|
790
792
|
);
|
|
791
793
|
console.log(
|
|
792
794
|
`[Appilots] captureSnapshot detail: lists=[${snapshot.lists.map((l) => `${l.containerType}:${l.id ?? l.label ?? "?"}(${l.items.map((it) => it.texts[0] ?? it.buttons[0]?.id ?? "?").join("|")})`).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(", ")}]`
|
|
@@ -3963,6 +3965,95 @@ async function executeAction(action, context) {
|
|
|
3963
3965
|
});
|
|
3964
3966
|
return result;
|
|
3965
3967
|
}
|
|
3968
|
+
|
|
3969
|
+
// src/platform/confirmedDestructiveAlert.ts
|
|
3970
|
+
var SUPPRESSION_WINDOW_MS = 1e3;
|
|
3971
|
+
var _active = null;
|
|
3972
|
+
function resolveConfirmButton(buttons) {
|
|
3973
|
+
if (!buttons || buttons.length === 0) return void 0;
|
|
3974
|
+
const destructive = buttons.find(
|
|
3975
|
+
(button) => button.style === "destructive" && typeof button.onPress === "function"
|
|
3976
|
+
);
|
|
3977
|
+
if (destructive) return destructive;
|
|
3978
|
+
return buttons.find(
|
|
3979
|
+
(button) => button.style !== "cancel" && typeof button.onPress === "function"
|
|
3980
|
+
);
|
|
3981
|
+
}
|
|
3982
|
+
function restore(suppression) {
|
|
3983
|
+
if (suppression.timer) {
|
|
3984
|
+
clearTimeout(suppression.timer);
|
|
3985
|
+
suppression.timer = null;
|
|
3986
|
+
}
|
|
3987
|
+
if (_active !== suppression) return;
|
|
3988
|
+
if (suppression.host.alert === _patchedAlert) {
|
|
3989
|
+
suppression.host.alert = suppression.originalAlert;
|
|
3990
|
+
}
|
|
3991
|
+
_active = null;
|
|
3992
|
+
}
|
|
3993
|
+
var _patchedAlert = (title, message, buttons, options) => {
|
|
3994
|
+
const suppression = _active;
|
|
3995
|
+
if (!suppression) return;
|
|
3996
|
+
if (suppression.consumed) {
|
|
3997
|
+
return suppression.originalAlert(title, message, buttons, options);
|
|
3998
|
+
}
|
|
3999
|
+
const button = resolveConfirmButton(buttons);
|
|
4000
|
+
if (!button?.onPress) {
|
|
4001
|
+
return suppression.originalAlert(title, message, buttons, options);
|
|
4002
|
+
}
|
|
4003
|
+
suppression.consumed = true;
|
|
4004
|
+
console.log(
|
|
4005
|
+
"[Appilots] Suppressing native Alert during already-confirmed destructive agent action"
|
|
4006
|
+
);
|
|
4007
|
+
try {
|
|
4008
|
+
suppression.pending = Promise.resolve(button.onPress()).then(() => void 0).catch((err) => reportHandlerFailure(err));
|
|
4009
|
+
} catch (err) {
|
|
4010
|
+
reportHandlerFailure(err);
|
|
4011
|
+
suppression.pending = null;
|
|
4012
|
+
}
|
|
4013
|
+
};
|
|
4014
|
+
function reportHandlerFailure(err) {
|
|
4015
|
+
console.error("[Appilots] The app\u2019s Alert handler threw while being auto-confirmed", err);
|
|
4016
|
+
}
|
|
4017
|
+
async function runWithConfirmedDestructiveContext(enabled, host, fn) {
|
|
4018
|
+
if (!enabled) return fn();
|
|
4019
|
+
if (_active) {
|
|
4020
|
+
_active.depth += 1;
|
|
4021
|
+
const joined = _active;
|
|
4022
|
+
try {
|
|
4023
|
+
return await fn();
|
|
4024
|
+
} finally {
|
|
4025
|
+
joined.depth -= 1;
|
|
4026
|
+
if (joined.depth === 0) {
|
|
4027
|
+
if (joined.pending) await joined.pending.catch(() => void 0);
|
|
4028
|
+
restore(joined);
|
|
4029
|
+
}
|
|
4030
|
+
}
|
|
4031
|
+
}
|
|
4032
|
+
const suppression = {
|
|
4033
|
+
host,
|
|
4034
|
+
originalAlert: host.alert,
|
|
4035
|
+
depth: 1,
|
|
4036
|
+
consumed: false,
|
|
4037
|
+
pending: null,
|
|
4038
|
+
timer: null
|
|
4039
|
+
};
|
|
4040
|
+
_active = suppression;
|
|
4041
|
+
host.alert = _patchedAlert;
|
|
4042
|
+
suppression.timer = setTimeout(() => {
|
|
4043
|
+
if (!suppression.consumed) restore(suppression);
|
|
4044
|
+
}, SUPPRESSION_WINDOW_MS);
|
|
4045
|
+
suppression.timer?.unref?.();
|
|
4046
|
+
try {
|
|
4047
|
+
const result = await fn();
|
|
4048
|
+
if (suppression.pending) await suppression.pending.catch(() => void 0);
|
|
4049
|
+
return result;
|
|
4050
|
+
} finally {
|
|
4051
|
+
suppression.depth -= 1;
|
|
4052
|
+
if (suppression.depth === 0) restore(suppression);
|
|
4053
|
+
}
|
|
4054
|
+
}
|
|
4055
|
+
|
|
4056
|
+
// src/platform/reactNativeAdapter.ts
|
|
3966
4057
|
var POST_ACTION_LOADING_MAX_MS = 6e3;
|
|
3967
4058
|
function resolveScreenMetadata() {
|
|
3968
4059
|
const activePath = getActiveRouteNames();
|
|
@@ -4113,42 +4204,14 @@ var reactNativeChatAdapter = {
|
|
|
4113
4204
|
getCurrentScreenSignature,
|
|
4114
4205
|
settleTurn
|
|
4115
4206
|
};
|
|
4116
|
-
async function runWithConfirmedDestructiveContext(enabled, fn) {
|
|
4117
|
-
if (!enabled) return fn();
|
|
4118
|
-
const originalAlert = Alert.alert;
|
|
4119
|
-
let consumed = false;
|
|
4120
|
-
let alertWork = null;
|
|
4121
|
-
Alert.alert = (title, message, buttons, options) => {
|
|
4122
|
-
if (consumed) {
|
|
4123
|
-
return originalAlert(title, message, buttons, options);
|
|
4124
|
-
}
|
|
4125
|
-
const destructive = buttons?.find((button) => button.style === "destructive");
|
|
4126
|
-
const actionable = destructive ?? buttons?.find((button) => button.style !== "cancel" && typeof button.onPress === "function");
|
|
4127
|
-
if (actionable?.onPress) {
|
|
4128
|
-
consumed = true;
|
|
4129
|
-
console.log(
|
|
4130
|
-
"[Appilots] Suppressing native Alert during already-confirmed destructive agent action"
|
|
4131
|
-
);
|
|
4132
|
-
alertWork = Promise.resolve(actionable.onPress()).then(() => void 0);
|
|
4133
|
-
return;
|
|
4134
|
-
}
|
|
4135
|
-
return originalAlert(title, message, buttons, options);
|
|
4136
|
-
};
|
|
4137
|
-
try {
|
|
4138
|
-
const result = await fn();
|
|
4139
|
-
if (alertWork) await alertWork;
|
|
4140
|
-
return result;
|
|
4141
|
-
} finally {
|
|
4142
|
-
Alert.alert = originalAlert;
|
|
4143
|
-
}
|
|
4144
|
-
}
|
|
4145
4207
|
function createReactNativeActionRunner(getOptions) {
|
|
4146
4208
|
return {
|
|
4147
4209
|
async execute(action, { confirmedDestructive }) {
|
|
4148
|
-
const { permissions, emit, navigationRef } = getOptions();
|
|
4210
|
+
const { permissions, emit, navigationRef, suppressNativeConfirm } = getOptions();
|
|
4149
4211
|
const navRef = navigationRef?.current ? navigationRef : { current: getNavigationRef() };
|
|
4150
4212
|
return runWithConfirmedDestructiveContext(
|
|
4151
|
-
confirmedDestructive,
|
|
4213
|
+
confirmedDestructive && suppressNativeConfirm !== false,
|
|
4214
|
+
Alert,
|
|
4152
4215
|
() => executeAction(action, {
|
|
4153
4216
|
navigationRef: navRef,
|
|
4154
4217
|
permissions,
|
|
@@ -4218,12 +4281,14 @@ function useAppilotsActions(options = {}) {
|
|
|
4218
4281
|
const runnerOptionsRef = useRef({
|
|
4219
4282
|
permissions: config.permissions ?? DEFAULT_PERMISSIONS2,
|
|
4220
4283
|
emit,
|
|
4221
|
-
navigationRef
|
|
4284
|
+
navigationRef,
|
|
4285
|
+
suppressNativeConfirm: config.suppressNativeConfirm
|
|
4222
4286
|
});
|
|
4223
4287
|
runnerOptionsRef.current = {
|
|
4224
4288
|
permissions: config.permissions ?? DEFAULT_PERMISSIONS2,
|
|
4225
4289
|
emit,
|
|
4226
|
-
navigationRef
|
|
4290
|
+
navigationRef,
|
|
4291
|
+
suppressNativeConfirm: config.suppressNativeConfirm
|
|
4227
4292
|
};
|
|
4228
4293
|
const machine = useMemo(
|
|
4229
4294
|
() => new ActionQueueMachine(
|