@appilots/sdk 0.4.0 → 0.5.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/dist/{chunk-42WI3UDB.mjs → chunk-3D7PHOV7.mjs} +6 -3
- package/dist/{chunk-CHY5D2PV.js → chunk-45AMQGS3.js} +5 -5
- package/dist/{chunk-JBOLV5AM.mjs → chunk-BIEF6MNR.mjs} +66 -10
- package/dist/{chunk-GEKCGVJN.mjs → chunk-NIW7E3QD.mjs} +1 -1
- package/dist/{chunk-V3TUIIT2.js → chunk-PQHZTAFG.js} +68 -9
- package/dist/{chunk-Y7EA6R2G.js → chunk-ZWQUIDBZ.js} +163 -160
- 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-Cb0D6uKH.d.mts → index-GvF_FlwO.d.mts} +31 -1
- package/dist/{index-Cb0D6uKH.d.ts → index-GvF_FlwO.d.ts} +31 -1
- package/dist/index.d.mts +40 -3
- package/dist/index.d.ts +40 -3
- package/dist/index.js +69 -65
- package/dist/index.mjs +5 -5
- package/dist/navigation/index.js +13 -13
- package/dist/navigation/index.mjs +2 -2
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getFiberRoot, getCurrentScreen, getActiveRouteNames, deriveInteractionElements, attachElementIdsToChoiceGroups, elementRegistry, appilotsDebugWarn, getDefaultRegistry, useAppilotsContext, ChatSessionMachine, getCurrentScreenSignature, ActionQueueMachine, getScreenMetadata, setCurrentScreen, useResolvedRegistry, listRegistry, componentRegistry, probeLoadingState, isListItemPressTarget, waitForLoadingSettle, 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, 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-BIEF6MNR.mjs';
|
|
2
2
|
import { useMemo, useRef, useSyncExternalStore, useEffect, useCallback, useState } from 'react';
|
|
3
3
|
import { Alert } from 'react-native';
|
|
4
4
|
|
|
@@ -748,6 +748,7 @@ function captureSnapshot() {
|
|
|
748
748
|
console.warn(
|
|
749
749
|
"[Appilots] captureSnapshot: fiber root not captured yet. Ensure <AppilotsProvider> has rendered before calling this."
|
|
750
750
|
);
|
|
751
|
+
recordIntrospectionFailure("never-mounted", null);
|
|
751
752
|
return {
|
|
752
753
|
route: getCurrentScreen(),
|
|
753
754
|
texts: [],
|
|
@@ -3267,7 +3268,9 @@ async function formFillHandler(payload, context) {
|
|
|
3267
3268
|
const fieldEntry = findField(fieldId, registry);
|
|
3268
3269
|
if (fieldEntry) {
|
|
3269
3270
|
try {
|
|
3270
|
-
|
|
3271
|
+
appilotsDebugLog(
|
|
3272
|
+
`formFillHandler: found field "${fieldId}" via registry, calling setValue(<${String(value).length} chars>)`
|
|
3273
|
+
);
|
|
3271
3274
|
const beforeValue = effectiveFieldType === "date" ? fieldEntry.getValue?.() ?? "" : void 0;
|
|
3272
3275
|
fieldEntry.focus?.();
|
|
3273
3276
|
fieldEntry.setValue(String(value));
|
|
@@ -3297,7 +3300,7 @@ async function formFillHandler(payload, context) {
|
|
|
3297
3300
|
}
|
|
3298
3301
|
if (!selectValueApplied(fieldId, value, after, registry)) {
|
|
3299
3302
|
appilotsDebugWarn(
|
|
3300
|
-
`formFillHandler: select field "${fieldId}" setValue
|
|
3303
|
+
`formFillHandler: select field "${fieldId}" setValue did not stick (wrote <${String(value).length} chars>, current is <${String(after ?? "").length} chars>), trying visible choice fallback`
|
|
3301
3304
|
);
|
|
3302
3305
|
const selectResult = await selectVisibleChoice(fieldId, value, registry, {
|
|
3303
3306
|
allowFirstVisibleWhenNoCue: !selectedChoiceThisBatch
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkPQHZTAFG_js = require('./chunk-PQHZTAFG.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 } = chunkPQHZTAFG_js.useAppilotsContext();
|
|
19
19
|
const internalRef = React.useRef(null);
|
|
20
20
|
const handleRef = React.useCallback((instance) => {
|
|
21
21
|
internalRef.current = instance;
|
|
22
|
-
|
|
22
|
+
chunkPQHZTAFG_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
|
+
chunkPQHZTAFG_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
|
+
chunkPQHZTAFG_js.setCurrentScreen(route.name);
|
|
52
52
|
emit({
|
|
53
53
|
type: "navigation:change",
|
|
54
54
|
timestamp: Date.now(),
|
|
@@ -44,6 +44,7 @@ var AppilotsClient = class {
|
|
|
44
44
|
timeout;
|
|
45
45
|
debug;
|
|
46
46
|
mcpVersion;
|
|
47
|
+
introspectionReporter;
|
|
47
48
|
user;
|
|
48
49
|
sessionId = null;
|
|
49
50
|
/** Guard so identify fires at most once per client instance. */
|
|
@@ -54,6 +55,7 @@ var AppilotsClient = class {
|
|
|
54
55
|
this.timeout = options.timeout ?? 6e4;
|
|
55
56
|
this.debug = options.debug ?? false;
|
|
56
57
|
this.mcpVersion = options.mcpVersion;
|
|
58
|
+
this.introspectionReporter = options.introspectionReporter;
|
|
57
59
|
this.user = options.user;
|
|
58
60
|
this.headers = {
|
|
59
61
|
"Content-Type": "application/json",
|
|
@@ -156,6 +158,21 @@ var AppilotsClient = class {
|
|
|
156
158
|
getSessionId() {
|
|
157
159
|
return this.sessionId;
|
|
158
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* Wire fragment for introspection health. Empty on the happy path —
|
|
163
|
+
* a working client sends nothing, so the field costs a byte only
|
|
164
|
+
* when something is actually wrong. Never throws: a broken reporter
|
|
165
|
+
* must not take the message down with it.
|
|
166
|
+
*/
|
|
167
|
+
introspectionFragment() {
|
|
168
|
+
try {
|
|
169
|
+
const report = this.introspectionReporter?.();
|
|
170
|
+
if (!report || report.captured !== false) return {};
|
|
171
|
+
return { introspection: report };
|
|
172
|
+
} catch {
|
|
173
|
+
return {};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
159
176
|
// ── Messages ──────────────────────────────────────────────────
|
|
160
177
|
async sendMessage(content, context) {
|
|
161
178
|
if (!this.sessionId) {
|
|
@@ -169,7 +186,8 @@ var AppilotsClient = class {
|
|
|
169
186
|
context,
|
|
170
187
|
// Optional MCP version bundled with this app build. Server
|
|
171
188
|
// compares vs the active MCP doc to detect stale uploads.
|
|
172
|
-
...this.mcpVersion ? { mcpVersion: this.mcpVersion } : {}
|
|
189
|
+
...this.mcpVersion ? { mcpVersion: this.mcpVersion } : {},
|
|
190
|
+
...this.introspectionFragment()
|
|
173
191
|
})
|
|
174
192
|
});
|
|
175
193
|
if (data.sessionId) {
|
|
@@ -396,7 +414,8 @@ var AppilotsClient = class {
|
|
|
396
414
|
content,
|
|
397
415
|
sessionId: this.sessionId,
|
|
398
416
|
context,
|
|
399
|
-
...this.mcpVersion ? { mcpVersion: this.mcpVersion } : {}
|
|
417
|
+
...this.mcpVersion ? { mcpVersion: this.mcpVersion } : {},
|
|
418
|
+
...this.introspectionFragment()
|
|
400
419
|
})
|
|
401
420
|
);
|
|
402
421
|
});
|
|
@@ -3622,15 +3641,32 @@ function getGlobalConfig() {
|
|
|
3622
3641
|
|
|
3623
3642
|
// src/introspection/fiberRoot.ts
|
|
3624
3643
|
var _fiberRoot = null;
|
|
3644
|
+
var _diagnostics = {
|
|
3645
|
+
captured: false,
|
|
3646
|
+
failureReason: null,
|
|
3647
|
+
reactVersion: null,
|
|
3648
|
+
failureCount: 0
|
|
3649
|
+
};
|
|
3625
3650
|
function setFiberRoot(fiber) {
|
|
3626
3651
|
if (_fiberRoot !== fiber) {
|
|
3627
3652
|
console.log(`[Appilots] Introspection: fiber root captured (type=${typeName(fiber)})`);
|
|
3628
3653
|
_fiberRoot = fiber;
|
|
3629
3654
|
}
|
|
3655
|
+
_diagnostics.captured = true;
|
|
3630
3656
|
}
|
|
3631
3657
|
function getFiberRoot() {
|
|
3632
3658
|
return _fiberRoot;
|
|
3633
3659
|
}
|
|
3660
|
+
function recordIntrospectionFailure(reason, reactVersion) {
|
|
3661
|
+
_diagnostics.failureCount += 1;
|
|
3662
|
+
if (_diagnostics.failureReason === null) {
|
|
3663
|
+
_diagnostics.failureReason = reason;
|
|
3664
|
+
_diagnostics.reactVersion = reactVersion;
|
|
3665
|
+
}
|
|
3666
|
+
}
|
|
3667
|
+
function getIntrospectionDiagnostics() {
|
|
3668
|
+
return { ..._diagnostics };
|
|
3669
|
+
}
|
|
3634
3670
|
function typeName(fiber) {
|
|
3635
3671
|
const t = fiber?.type ?? fiber?.elementType;
|
|
3636
3672
|
if (!t) return "unknown";
|
|
@@ -3639,15 +3675,16 @@ function typeName(fiber) {
|
|
|
3639
3675
|
if (typeof t === "object") return t.displayName ?? t.render?.displayName ?? t.render?.name ?? "forwardRef/memo";
|
|
3640
3676
|
return String(t);
|
|
3641
3677
|
}
|
|
3642
|
-
|
|
3643
|
-
// src/introspection/AppilotsFiberRoot.tsx
|
|
3644
3678
|
var FiberSentinel = class extends React2.Component {
|
|
3645
3679
|
componentDidMount() {
|
|
3646
3680
|
const fiber = this._reactInternals ?? this._reactInternalFiber ?? null;
|
|
3647
3681
|
if (!fiber) {
|
|
3682
|
+
const reactVersion = React2.version ?? null;
|
|
3648
3683
|
console.warn(
|
|
3649
|
-
|
|
3684
|
+
`[Appilots] FiberSentinel: this._reactInternals is undefined; snapshot capture will fall back to render-time owner. React version may be incompatible (react=${reactVersion}).`
|
|
3650
3685
|
);
|
|
3686
|
+
recordIntrospectionFailure("sentinel-missing-internals", reactVersion);
|
|
3687
|
+
this.props.onUnavailable?.({ reactVersion });
|
|
3651
3688
|
return;
|
|
3652
3689
|
}
|
|
3653
3690
|
let top = fiber;
|
|
@@ -3658,13 +3695,16 @@ var FiberSentinel = class extends React2.Component {
|
|
|
3658
3695
|
return this.props.children ?? null;
|
|
3659
3696
|
}
|
|
3660
3697
|
};
|
|
3661
|
-
function AppilotsFiberRoot({
|
|
3698
|
+
function AppilotsFiberRoot({
|
|
3699
|
+
children,
|
|
3700
|
+
onUnavailable
|
|
3701
|
+
}) {
|
|
3662
3702
|
const Internals = React2.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED_IN_THIS_VERSION_OF_REACT;
|
|
3663
3703
|
const ownerFiber = Internals?.ReactCurrentOwner?.current;
|
|
3664
3704
|
if (ownerFiber && !getFiberRoot()) {
|
|
3665
3705
|
setFiberRoot(ownerFiber);
|
|
3666
3706
|
}
|
|
3667
|
-
return /* @__PURE__ */ React2.createElement(FiberSentinel,
|
|
3707
|
+
return /* @__PURE__ */ React2.createElement(FiberSentinel, { onUnavailable }, children);
|
|
3668
3708
|
}
|
|
3669
3709
|
|
|
3670
3710
|
// src/debug/logger.ts
|
|
@@ -3676,6 +3716,10 @@ function isDebugEnabled() {
|
|
|
3676
3716
|
if (debugOverride !== void 0) return debugOverride;
|
|
3677
3717
|
return getGlobalConfig()?.debug === true;
|
|
3678
3718
|
}
|
|
3719
|
+
function appilotsDebugLog(...args) {
|
|
3720
|
+
if (!isDebugEnabled()) return;
|
|
3721
|
+
console.log("[Appilots]", ...args);
|
|
3722
|
+
}
|
|
3679
3723
|
function appilotsDebugWarn(...args) {
|
|
3680
3724
|
if (!isDebugEnabled()) return;
|
|
3681
3725
|
console.log("[Appilots]", ...args);
|
|
@@ -3717,6 +3761,16 @@ function AppilotsProvider({ config: configProp, children, client: externalClient
|
|
|
3717
3761
|
recordAppilotsEventTrace(event);
|
|
3718
3762
|
listenersRef.current.forEach((handler) => handler(event));
|
|
3719
3763
|
}, []);
|
|
3764
|
+
const handleIntrospectionUnavailable = useCallback(
|
|
3765
|
+
({ reactVersion }) => {
|
|
3766
|
+
emit({
|
|
3767
|
+
type: "sdk:introspection:unavailable",
|
|
3768
|
+
timestamp: Date.now(),
|
|
3769
|
+
data: { reason: "sentinel-missing-internals", reactVersion }
|
|
3770
|
+
});
|
|
3771
|
+
},
|
|
3772
|
+
[emit]
|
|
3773
|
+
);
|
|
3720
3774
|
const client = useMemo(
|
|
3721
3775
|
() => externalClient ?? new AppilotsClient({
|
|
3722
3776
|
projectId: config.projectId,
|
|
@@ -3725,7 +3779,9 @@ function AppilotsProvider({ config: configProp, children, client: externalClient
|
|
|
3725
3779
|
debug: config.debug,
|
|
3726
3780
|
appVersion: config.appVersion,
|
|
3727
3781
|
mcpVersion: config.mcpVersion,
|
|
3728
|
-
user: config.user
|
|
3782
|
+
user: config.user,
|
|
3783
|
+
// Only reports a FAILED reading; the happy path sends nothing.
|
|
3784
|
+
introspectionReporter: getIntrospectionDiagnostics
|
|
3729
3785
|
}),
|
|
3730
3786
|
[config.projectId, config.apiBaseUrl, config.apiKey, config.debug, config.appVersion, config.mcpVersion, config.user, externalClient]
|
|
3731
3787
|
);
|
|
@@ -3746,7 +3802,7 @@ function AppilotsProvider({ config: configProp, children, client: externalClient
|
|
|
3746
3802
|
() => ({ config, client, subscribe, emit, remotePersonalization }),
|
|
3747
3803
|
[config, client, subscribe, emit, remotePersonalization]
|
|
3748
3804
|
);
|
|
3749
|
-
return /* @__PURE__ */ React2.createElement(AppilotsContext.Provider, { value }, /* @__PURE__ */ React2.createElement(AppilotsFiberRoot,
|
|
3805
|
+
return /* @__PURE__ */ React2.createElement(AppilotsContext.Provider, { value }, /* @__PURE__ */ React2.createElement(AppilotsFiberRoot, { onUnavailable: handleIntrospectionUnavailable }, children));
|
|
3750
3806
|
}
|
|
3751
3807
|
function useAppilotsContext() {
|
|
3752
3808
|
const context = useContext(AppilotsContext);
|
|
@@ -4265,4 +4321,4 @@ function clearScreenRegistry() {
|
|
|
4265
4321
|
screenRegistry.clear();
|
|
4266
4322
|
}
|
|
4267
4323
|
|
|
4268
|
-
export { ActionQueueMachine, AppilotsClient, AppilotsProvider, AppilotsRegistryProvider, ChatSessionMachine, OPTIONAL_STEP_AUTOMATION_HINT, SDK_VERSION, _patchJsxRuntimes, actionPressTargetId, appilotsDebugWarn, attachElementIdsToChoiceGroups, clearAppilotsDebugTraces, clearScreenRegistry, componentRegistry, createComponentRegistry, createElementRegistry, createListRegistry, defaultDarkTheme, defaultLightTheme, deriveInteractionElements, describeAction, elementRegistry, enableAppilotsAutoTracking, getActiveRouteNames, getAllScreens, getAppilotsDebugTraces, getCurrentScreen, getCurrentScreenSignature, getDefaultRegistry, getFiberRoot, getGlobalConfig, getNavigationRef, getNavigationStateSnapshot, getScreenMetadata, humanizeError, idLooselyMatches, initAppilots, isAutoTrackingEnabled, isGenericSelectValue, isListItemPressTarget, isOptionalStepAutomationFailure, listRegistry, looksDestructiveActionLabel, matchScore, mergeThemeTokens, normalize3, parseStableElementId, probeLoadingState, recordAppilotsDebugTrace, registerScreen, resolveBaseTheme, routesBelongToSameFeature, screenDepartedBaseline, setCurrentScreen, setNavigationRef, snapshotShowsOpenCreateForm, subscribeAppilotsDebugTraces, useAppilotsContext, useResolvedRegistry, waitForLoadingSettle, waitForScreenSettle };
|
|
4324
|
+
export { ActionQueueMachine, AppilotsClient, AppilotsProvider, AppilotsRegistryProvider, ChatSessionMachine, OPTIONAL_STEP_AUTOMATION_HINT, 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 };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useAppilotsContext, setNavigationRef, setCurrentScreen } from './chunk-
|
|
1
|
+
import { useAppilotsContext, setNavigationRef, setCurrentScreen } from './chunk-BIEF6MNR.mjs';
|
|
2
2
|
import React, { useRef, useCallback, useEffect } from 'react';
|
|
3
3
|
|
|
4
4
|
function getActiveRouteName(state) {
|
|
@@ -50,6 +50,7 @@ var AppilotsClient = class {
|
|
|
50
50
|
timeout;
|
|
51
51
|
debug;
|
|
52
52
|
mcpVersion;
|
|
53
|
+
introspectionReporter;
|
|
53
54
|
user;
|
|
54
55
|
sessionId = null;
|
|
55
56
|
/** Guard so identify fires at most once per client instance. */
|
|
@@ -60,6 +61,7 @@ var AppilotsClient = class {
|
|
|
60
61
|
this.timeout = options.timeout ?? 6e4;
|
|
61
62
|
this.debug = options.debug ?? false;
|
|
62
63
|
this.mcpVersion = options.mcpVersion;
|
|
64
|
+
this.introspectionReporter = options.introspectionReporter;
|
|
63
65
|
this.user = options.user;
|
|
64
66
|
this.headers = {
|
|
65
67
|
"Content-Type": "application/json",
|
|
@@ -162,6 +164,21 @@ var AppilotsClient = class {
|
|
|
162
164
|
getSessionId() {
|
|
163
165
|
return this.sessionId;
|
|
164
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* Wire fragment for introspection health. Empty on the happy path —
|
|
169
|
+
* a working client sends nothing, so the field costs a byte only
|
|
170
|
+
* when something is actually wrong. Never throws: a broken reporter
|
|
171
|
+
* must not take the message down with it.
|
|
172
|
+
*/
|
|
173
|
+
introspectionFragment() {
|
|
174
|
+
try {
|
|
175
|
+
const report = this.introspectionReporter?.();
|
|
176
|
+
if (!report || report.captured !== false) return {};
|
|
177
|
+
return { introspection: report };
|
|
178
|
+
} catch {
|
|
179
|
+
return {};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
165
182
|
// ── Messages ──────────────────────────────────────────────────
|
|
166
183
|
async sendMessage(content, context) {
|
|
167
184
|
if (!this.sessionId) {
|
|
@@ -175,7 +192,8 @@ var AppilotsClient = class {
|
|
|
175
192
|
context,
|
|
176
193
|
// Optional MCP version bundled with this app build. Server
|
|
177
194
|
// compares vs the active MCP doc to detect stale uploads.
|
|
178
|
-
...this.mcpVersion ? { mcpVersion: this.mcpVersion } : {}
|
|
195
|
+
...this.mcpVersion ? { mcpVersion: this.mcpVersion } : {},
|
|
196
|
+
...this.introspectionFragment()
|
|
179
197
|
})
|
|
180
198
|
});
|
|
181
199
|
if (data.sessionId) {
|
|
@@ -402,7 +420,8 @@ var AppilotsClient = class {
|
|
|
402
420
|
content,
|
|
403
421
|
sessionId: this.sessionId,
|
|
404
422
|
context,
|
|
405
|
-
...this.mcpVersion ? { mcpVersion: this.mcpVersion } : {}
|
|
423
|
+
...this.mcpVersion ? { mcpVersion: this.mcpVersion } : {},
|
|
424
|
+
...this.introspectionFragment()
|
|
406
425
|
})
|
|
407
426
|
);
|
|
408
427
|
});
|
|
@@ -3628,15 +3647,32 @@ function getGlobalConfig() {
|
|
|
3628
3647
|
|
|
3629
3648
|
// src/introspection/fiberRoot.ts
|
|
3630
3649
|
var _fiberRoot = null;
|
|
3650
|
+
var _diagnostics = {
|
|
3651
|
+
captured: false,
|
|
3652
|
+
failureReason: null,
|
|
3653
|
+
reactVersion: null,
|
|
3654
|
+
failureCount: 0
|
|
3655
|
+
};
|
|
3631
3656
|
function setFiberRoot(fiber) {
|
|
3632
3657
|
if (_fiberRoot !== fiber) {
|
|
3633
3658
|
console.log(`[Appilots] Introspection: fiber root captured (type=${typeName(fiber)})`);
|
|
3634
3659
|
_fiberRoot = fiber;
|
|
3635
3660
|
}
|
|
3661
|
+
_diagnostics.captured = true;
|
|
3636
3662
|
}
|
|
3637
3663
|
function getFiberRoot() {
|
|
3638
3664
|
return _fiberRoot;
|
|
3639
3665
|
}
|
|
3666
|
+
function recordIntrospectionFailure(reason, reactVersion) {
|
|
3667
|
+
_diagnostics.failureCount += 1;
|
|
3668
|
+
if (_diagnostics.failureReason === null) {
|
|
3669
|
+
_diagnostics.failureReason = reason;
|
|
3670
|
+
_diagnostics.reactVersion = reactVersion;
|
|
3671
|
+
}
|
|
3672
|
+
}
|
|
3673
|
+
function getIntrospectionDiagnostics() {
|
|
3674
|
+
return { ..._diagnostics };
|
|
3675
|
+
}
|
|
3640
3676
|
function typeName(fiber) {
|
|
3641
3677
|
const t = fiber?.type ?? fiber?.elementType;
|
|
3642
3678
|
if (!t) return "unknown";
|
|
@@ -3645,15 +3681,16 @@ function typeName(fiber) {
|
|
|
3645
3681
|
if (typeof t === "object") return t.displayName ?? t.render?.displayName ?? t.render?.name ?? "forwardRef/memo";
|
|
3646
3682
|
return String(t);
|
|
3647
3683
|
}
|
|
3648
|
-
|
|
3649
|
-
// src/introspection/AppilotsFiberRoot.tsx
|
|
3650
3684
|
var FiberSentinel = class extends React2__default.default.Component {
|
|
3651
3685
|
componentDidMount() {
|
|
3652
3686
|
const fiber = this._reactInternals ?? this._reactInternalFiber ?? null;
|
|
3653
3687
|
if (!fiber) {
|
|
3688
|
+
const reactVersion = React2__default.default.version ?? null;
|
|
3654
3689
|
console.warn(
|
|
3655
|
-
|
|
3690
|
+
`[Appilots] FiberSentinel: this._reactInternals is undefined; snapshot capture will fall back to render-time owner. React version may be incompatible (react=${reactVersion}).`
|
|
3656
3691
|
);
|
|
3692
|
+
recordIntrospectionFailure("sentinel-missing-internals", reactVersion);
|
|
3693
|
+
this.props.onUnavailable?.({ reactVersion });
|
|
3657
3694
|
return;
|
|
3658
3695
|
}
|
|
3659
3696
|
let top = fiber;
|
|
@@ -3664,13 +3701,16 @@ var FiberSentinel = class extends React2__default.default.Component {
|
|
|
3664
3701
|
return this.props.children ?? null;
|
|
3665
3702
|
}
|
|
3666
3703
|
};
|
|
3667
|
-
function AppilotsFiberRoot({
|
|
3704
|
+
function AppilotsFiberRoot({
|
|
3705
|
+
children,
|
|
3706
|
+
onUnavailable
|
|
3707
|
+
}) {
|
|
3668
3708
|
const Internals = React2__default.default.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED_IN_THIS_VERSION_OF_REACT;
|
|
3669
3709
|
const ownerFiber = Internals?.ReactCurrentOwner?.current;
|
|
3670
3710
|
if (ownerFiber && !getFiberRoot()) {
|
|
3671
3711
|
setFiberRoot(ownerFiber);
|
|
3672
3712
|
}
|
|
3673
|
-
return /* @__PURE__ */ React2__default.default.createElement(FiberSentinel,
|
|
3713
|
+
return /* @__PURE__ */ React2__default.default.createElement(FiberSentinel, { onUnavailable }, children);
|
|
3674
3714
|
}
|
|
3675
3715
|
|
|
3676
3716
|
// src/debug/logger.ts
|
|
@@ -3682,6 +3722,10 @@ function isDebugEnabled() {
|
|
|
3682
3722
|
if (debugOverride !== void 0) return debugOverride;
|
|
3683
3723
|
return getGlobalConfig()?.debug === true;
|
|
3684
3724
|
}
|
|
3725
|
+
function appilotsDebugLog(...args) {
|
|
3726
|
+
if (!isDebugEnabled()) return;
|
|
3727
|
+
console.log("[Appilots]", ...args);
|
|
3728
|
+
}
|
|
3685
3729
|
function appilotsDebugWarn(...args) {
|
|
3686
3730
|
if (!isDebugEnabled()) return;
|
|
3687
3731
|
console.log("[Appilots]", ...args);
|
|
@@ -3723,6 +3767,16 @@ function AppilotsProvider({ config: configProp, children, client: externalClient
|
|
|
3723
3767
|
recordAppilotsEventTrace(event);
|
|
3724
3768
|
listenersRef.current.forEach((handler) => handler(event));
|
|
3725
3769
|
}, []);
|
|
3770
|
+
const handleIntrospectionUnavailable = React2.useCallback(
|
|
3771
|
+
({ reactVersion }) => {
|
|
3772
|
+
emit({
|
|
3773
|
+
type: "sdk:introspection:unavailable",
|
|
3774
|
+
timestamp: Date.now(),
|
|
3775
|
+
data: { reason: "sentinel-missing-internals", reactVersion }
|
|
3776
|
+
});
|
|
3777
|
+
},
|
|
3778
|
+
[emit]
|
|
3779
|
+
);
|
|
3726
3780
|
const client = React2.useMemo(
|
|
3727
3781
|
() => externalClient ?? new AppilotsClient({
|
|
3728
3782
|
projectId: config.projectId,
|
|
@@ -3731,7 +3785,9 @@ function AppilotsProvider({ config: configProp, children, client: externalClient
|
|
|
3731
3785
|
debug: config.debug,
|
|
3732
3786
|
appVersion: config.appVersion,
|
|
3733
3787
|
mcpVersion: config.mcpVersion,
|
|
3734
|
-
user: config.user
|
|
3788
|
+
user: config.user,
|
|
3789
|
+
// Only reports a FAILED reading; the happy path sends nothing.
|
|
3790
|
+
introspectionReporter: getIntrospectionDiagnostics
|
|
3735
3791
|
}),
|
|
3736
3792
|
[config.projectId, config.apiBaseUrl, config.apiKey, config.debug, config.appVersion, config.mcpVersion, config.user, externalClient]
|
|
3737
3793
|
);
|
|
@@ -3752,7 +3808,7 @@ function AppilotsProvider({ config: configProp, children, client: externalClient
|
|
|
3752
3808
|
() => ({ config, client, subscribe, emit, remotePersonalization }),
|
|
3753
3809
|
[config, client, subscribe, emit, remotePersonalization]
|
|
3754
3810
|
);
|
|
3755
|
-
return /* @__PURE__ */ React2__default.default.createElement(AppilotsContext.Provider, { value }, /* @__PURE__ */ React2__default.default.createElement(AppilotsFiberRoot,
|
|
3811
|
+
return /* @__PURE__ */ React2__default.default.createElement(AppilotsContext.Provider, { value }, /* @__PURE__ */ React2__default.default.createElement(AppilotsFiberRoot, { onUnavailable: handleIntrospectionUnavailable }, children));
|
|
3756
3812
|
}
|
|
3757
3813
|
function useAppilotsContext() {
|
|
3758
3814
|
const context = React2.useContext(AppilotsContext);
|
|
@@ -4280,6 +4336,7 @@ exports.OPTIONAL_STEP_AUTOMATION_HINT = OPTIONAL_STEP_AUTOMATION_HINT;
|
|
|
4280
4336
|
exports.SDK_VERSION = SDK_VERSION;
|
|
4281
4337
|
exports._patchJsxRuntimes = _patchJsxRuntimes;
|
|
4282
4338
|
exports.actionPressTargetId = actionPressTargetId;
|
|
4339
|
+
exports.appilotsDebugLog = appilotsDebugLog;
|
|
4283
4340
|
exports.appilotsDebugWarn = appilotsDebugWarn;
|
|
4284
4341
|
exports.attachElementIdsToChoiceGroups = attachElementIdsToChoiceGroups;
|
|
4285
4342
|
exports.clearAppilotsDebugTraces = clearAppilotsDebugTraces;
|
|
@@ -4302,6 +4359,7 @@ exports.getCurrentScreenSignature = getCurrentScreenSignature;
|
|
|
4302
4359
|
exports.getDefaultRegistry = getDefaultRegistry;
|
|
4303
4360
|
exports.getFiberRoot = getFiberRoot;
|
|
4304
4361
|
exports.getGlobalConfig = getGlobalConfig;
|
|
4362
|
+
exports.getIntrospectionDiagnostics = getIntrospectionDiagnostics;
|
|
4305
4363
|
exports.getNavigationRef = getNavigationRef;
|
|
4306
4364
|
exports.getNavigationStateSnapshot = getNavigationStateSnapshot;
|
|
4307
4365
|
exports.getScreenMetadata = getScreenMetadata;
|
|
@@ -4320,6 +4378,7 @@ exports.normalize3 = normalize3;
|
|
|
4320
4378
|
exports.parseStableElementId = parseStableElementId;
|
|
4321
4379
|
exports.probeLoadingState = probeLoadingState;
|
|
4322
4380
|
exports.recordAppilotsDebugTrace = recordAppilotsDebugTrace;
|
|
4381
|
+
exports.recordIntrospectionFailure = recordIntrospectionFailure;
|
|
4323
4382
|
exports.registerScreen = registerScreen;
|
|
4324
4383
|
exports.resolveBaseTheme = resolveBaseTheme;
|
|
4325
4384
|
exports.routesBelongToSameFeature = routesBelongToSameFeature;
|