@agent-native/core 0.79.20 → 0.79.22
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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +16 -0
- package/corpus/core/docs/content/deployment.md +133 -0
- package/corpus/core/docs/content/faq.md +1 -1
- package/corpus/core/docs/content/multi-app-workspace.md +2 -0
- package/corpus/core/docs/content/tracking.md +3 -3
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/engine/openai-compatible-endpoint.ts +25 -0
- package/corpus/core/src/agent/engine/provider-env-vars.ts +2 -0
- package/corpus/core/src/agent/engine/registry.ts +59 -11
- package/corpus/core/src/client/FeedbackButton.tsx +11 -1
- package/corpus/core/src/client/agent-engine-key.ts +57 -10
- package/corpus/core/src/client/analytics.ts +78 -27
- package/corpus/core/src/client/blocks/library/HighlightedCode.tsx +1 -1
- package/corpus/core/src/client/index.ts +2 -0
- package/corpus/core/src/client/session-replay.ts +159 -17
- package/corpus/core/src/client/settings/SettingsPanel.tsx +119 -4
- package/corpus/core/src/scripts/agent-engines/manage-agent-engine.ts +5 -0
- package/corpus/core/src/scripts/agent-engines/set-agent-engine.ts +8 -3
- package/corpus/core/src/scripts/agent-engines/test-agent-engine.ts +54 -6
- package/corpus/core/src/server/agent-engine-api-key-route.ts +83 -12
- package/corpus/core/src/server/core-routes-plugin.ts +26 -2
- package/corpus/core/src/styles/blocks.css +23 -7
- package/corpus/templates/analytics/actions/list-session-recordings.ts +1 -1
- package/corpus/templates/analytics/app/components/layout/MobileNav.tsx +5 -10
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +22 -4
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +64 -50
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/dashboard-layout.ts +38 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/dashboard-sync.ts +89 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +138 -59
- package/corpus/templates/analytics/changelog/2026-06-27-dashboard-charts-drag-smoothly-when-rearranging-panels.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-27-dashboard-email-reports-still-send-when-the-live-screenshot-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-27-fixed-dashboard-edits-so-charts-no-longer-briefly-snap-back-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-27-mobile-navigation-chrome-and-motion.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-27-session-replay-lists-now-show-only-signed-in-recordings-with.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-27-sidebar-loading-placeholders-are-visible-in-light-mode.md +6 -0
- package/corpus/templates/analytics/netlify.toml +4 -0
- package/corpus/templates/analytics/scripts/seed-session-replay.ts +1 -0
- package/corpus/templates/analytics/server/jobs/dashboard-report.ts +1 -0
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +120 -29
- package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +1 -1
- package/corpus/templates/analytics/server/lib/session-replay.ts +158 -46
- package/corpus/templates/assets/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/assets/changelog/2026-06-27-mobile-navigation-chrome-and-motion.md +6 -0
- package/corpus/templates/clips/app/components/capture-install-options.tsx +0 -9
- package/corpus/templates/clips/app/components/recorder/pre-record-panel.tsx +20 -4
- package/corpus/templates/clips/app/hooks/use-desktop-promo.ts +6 -2
- package/corpus/templates/clips/changelog/2026-06-27-clips-no-longer-shows-desktop-app-prompts-on-mobile-screens.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-27-desktop-storage-setup-flow.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-27-recorder-download-options-now-show-the-chrome-extension-and-.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-27-recorder-setup-mobile-capture-options.md +6 -0
- package/corpus/templates/clips/chrome-extension/package.json +1 -1
- package/corpus/templates/clips/chrome-extension/src/sentry.ts +17 -1
- package/corpus/templates/clips/desktop/package.json +1 -0
- package/corpus/templates/clips/desktop/scripts/check-tauri-prereqs.mjs +45 -0
- package/corpus/templates/clips/desktop/src/app.tsx +32 -3
- package/corpus/templates/clips/desktop/src/lib/sentry.ts +71 -0
- package/corpus/templates/clips/desktop/src/main.tsx +2 -0
- package/corpus/templates/clips/desktop/src/styles.css +67 -0
- package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +2 -1
- package/corpus/templates/clips/desktop/src-tauri/build.rs +29 -0
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +3 -0
- package/corpus/templates/clips/desktop/src-tauri/src/logfile.rs +1 -0
- package/corpus/templates/clips/desktop/src-tauri/src/sentry_report.rs +142 -0
- package/corpus/templates/clips/desktop/vite.config.ts +66 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/design/changelog/2026-06-27-mobile-navigation-chrome-and-motion.md +6 -0
- package/corpus/templates/forms/actions/export-responses.ts +3 -2
- package/corpus/templates/forms/actions/list-responses.ts +2 -1
- package/corpus/templates/forms/actions/response-insights.ts +13 -4
- package/corpus/templates/forms/changelog/2026-06-27-anonymous-feedback-no-longer-shows-internal-agent-native-ano.md +6 -0
- package/corpus/templates/forms/server/handlers/submissions.ts +5 -8
- package/corpus/templates/forms/server/lib/integrations.ts +9 -6
- package/corpus/templates/forms/shared/submitter-email.ts +20 -0
- package/corpus/templates/forms/shared/types.ts +1 -1
- package/corpus/templates/plan/app/components/plan/wireframe/html-artboard.css +49 -10
- package/corpus/templates/slides/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/slides/changelog/2026-06-27-mobile-navigation-chrome-and-motion.md +6 -0
- package/dist/agent/engine/openai-compatible-endpoint.d.ts +3 -0
- package/dist/agent/engine/openai-compatible-endpoint.d.ts.map +1 -0
- package/dist/agent/engine/openai-compatible-endpoint.js +23 -0
- package/dist/agent/engine/openai-compatible-endpoint.js.map +1 -0
- package/dist/agent/engine/provider-env-vars.d.ts +1 -0
- package/dist/agent/engine/provider-env-vars.d.ts.map +1 -1
- package/dist/agent/engine/provider-env-vars.js +1 -0
- package/dist/agent/engine/provider-env-vars.js.map +1 -1
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js +39 -12
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/client/FeedbackButton.d.ts.map +1 -1
- package/dist/client/FeedbackButton.js +6 -1
- package/dist/client/FeedbackButton.js.map +1 -1
- package/dist/client/agent-engine-key.d.ts +14 -0
- package/dist/client/agent-engine-key.d.ts.map +1 -1
- package/dist/client/agent-engine-key.js +35 -10
- package/dist/client/agent-engine-key.js.map +1 -1
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +71 -24
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/blocks/library/HighlightedCode.d.ts +1 -1
- package/dist/client/blocks/library/HighlightedCode.js +1 -1
- package/dist/client/blocks/library/HighlightedCode.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/session-replay.d.ts +1 -1
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +115 -17
- package/dist/client/session-replay.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +42 -6
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/collab/routes.d.ts +2 -2
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +7 -7
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/scripts/agent-engines/manage-agent-engine.d.ts.map +1 -1
- package/dist/scripts/agent-engines/manage-agent-engine.js +4 -0
- package/dist/scripts/agent-engines/manage-agent-engine.js.map +1 -1
- package/dist/scripts/agent-engines/set-agent-engine.d.ts.map +1 -1
- package/dist/scripts/agent-engines/set-agent-engine.js +5 -4
- package/dist/scripts/agent-engines/set-agent-engine.js.map +1 -1
- package/dist/scripts/agent-engines/test-agent-engine.d.ts.map +1 -1
- package/dist/scripts/agent-engines/test-agent-engine.js +37 -5
- package/dist/scripts/agent-engines/test-agent-engine.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +5 -5
- package/dist/server/agent-engine-api-key-route.d.ts.map +1 -1
- package/dist/server/agent-engine-api-key-route.js +71 -11
- package/dist/server/agent-engine-api-key-route.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +20 -3
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/styles/blocks.css +23 -7
- package/docs/content/deployment.md +133 -0
- package/docs/content/faq.md +1 -1
- package/docs/content/multi-app-workspace.md +2 -0
- package/docs/content/tracking.md +3 -3
- package/package.json +1 -1
|
@@ -15,6 +15,18 @@ const PROVIDER_ENV_VAR = {
|
|
|
15
15
|
};
|
|
16
16
|
/** Event other parts of the agent UI listen for to re-check the LLM gate. */
|
|
17
17
|
const CONFIGURED_CHANGED_EVENT = "agent-engine:configured-changed";
|
|
18
|
+
function resolveProviderEnvVar(provider, key) {
|
|
19
|
+
const envVar = key?.trim() || (provider ? PROVIDER_ENV_VAR[provider] : "");
|
|
20
|
+
if (!envVar) {
|
|
21
|
+
throw new Error("Choose an API key provider first.");
|
|
22
|
+
}
|
|
23
|
+
return envVar;
|
|
24
|
+
}
|
|
25
|
+
function dispatchConfiguredChanged() {
|
|
26
|
+
if (typeof window !== "undefined") {
|
|
27
|
+
window.dispatchEvent(new CustomEvent(CONFIGURED_CHANGED_EVENT));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
18
30
|
/**
|
|
19
31
|
* Persist a provider API key for the current owner. Resolves on success.
|
|
20
32
|
* Throws an Error with a readable message on failure. On success it also
|
|
@@ -22,18 +34,33 @@ const CONFIGURED_CHANGED_EVENT = "agent-engine:configured-changed";
|
|
|
22
34
|
* out of its "needs setup" state without a reload.
|
|
23
35
|
*/
|
|
24
36
|
export async function saveAgentEngineApiKey({ provider, key, apiKey, scope, }) {
|
|
25
|
-
|
|
26
|
-
if (!trimmed) {
|
|
37
|
+
if (!apiKey.trim()) {
|
|
27
38
|
throw new Error("Enter an API key first.");
|
|
28
39
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
40
|
+
await saveAgentEngineProviderSettings({ provider, key, apiKey, scope });
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Persist provider-specific settings for the current owner. This intentionally
|
|
44
|
+
* stays narrow: API keys for built-in BYOK providers, plus OpenAI's optional
|
|
45
|
+
* compatible endpoint URL. Values are stored server-side in scoped secrets.
|
|
46
|
+
*/
|
|
47
|
+
export async function saveAgentEngineProviderSettings({ provider, key, apiKey, baseUrl, clearBaseUrl, scope, }) {
|
|
48
|
+
const trimmed = apiKey?.trim() ?? "";
|
|
49
|
+
const endpoint = baseUrl?.trim() ?? "";
|
|
50
|
+
if (!trimmed && !endpoint && !clearBaseUrl) {
|
|
51
|
+
throw new Error("Enter an API key or endpoint URL first.");
|
|
32
52
|
}
|
|
53
|
+
const envVar = resolveProviderEnvVar(provider, key);
|
|
33
54
|
const res = await fetch(agentNativePath("/_agent-native/agent-engine/api-key"), {
|
|
34
55
|
method: "POST",
|
|
35
56
|
headers: { "Content-Type": "application/json" },
|
|
36
|
-
body: JSON.stringify({
|
|
57
|
+
body: JSON.stringify({
|
|
58
|
+
key: envVar,
|
|
59
|
+
...(trimmed ? { value: trimmed } : {}),
|
|
60
|
+
...(endpoint ? { baseUrl: endpoint } : {}),
|
|
61
|
+
...(clearBaseUrl ? { clearBaseUrl: true } : {}),
|
|
62
|
+
scope,
|
|
63
|
+
}),
|
|
37
64
|
});
|
|
38
65
|
if (!res.ok) {
|
|
39
66
|
const message = await res
|
|
@@ -43,10 +70,8 @@ export async function saveAgentEngineApiKey({ provider, key, apiKey, scope, }) {
|
|
|
43
70
|
throw new Error(message ??
|
|
44
71
|
(res.status === 401
|
|
45
72
|
? "Sign in to save a key, or connect Builder instead."
|
|
46
|
-
: `Could not save
|
|
47
|
-
}
|
|
48
|
-
if (typeof window !== "undefined") {
|
|
49
|
-
window.dispatchEvent(new CustomEvent(CONFIGURED_CHANGED_EVENT));
|
|
73
|
+
: `Could not save provider settings (HTTP ${res.status}).`));
|
|
50
74
|
}
|
|
75
|
+
dispatchConfiguredChanged();
|
|
51
76
|
}
|
|
52
77
|
//# sourceMappingURL=agent-engine-key.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-engine-key.js","sourceRoot":"","sources":["../../src/client/agent-engine-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAKhD,MAAM,gBAAgB,GAAwC;IAC5D,SAAS,EAAE,mBAAmB;IAC9B,MAAM,EAAE,gBAAgB;CACzB,CAAC;AAEF,6EAA6E;AAC7E,MAAM,wBAAwB,GAAG,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-engine-key.js","sourceRoot":"","sources":["../../src/client/agent-engine-key.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Agent engine API-key helpers (browser).\n *\n * Named client helper for storing a bring-your-own provider key (Anthropic,\n * OpenAI, etc.) so the agent chat can run without a Builder connection or an\n * account. The key is persisted by the framework under the matching provider\n * key (e.g. ANTHROPIC_API_KEY) for the current user or org, exactly like the\n * LLM settings panel does — UI code should call this instead of hand-writing\n * a fetch to framework routes.\n */\n\nimport { agentNativePath } from \"./api-path.js\";\n\n/** Providers that can be configured with a single pasted API key. */\nexport type AgentEngineProvider = \"anthropic\" | \"openai\";\n\nconst PROVIDER_ENV_VAR: Record<AgentEngineProvider, string> = {\n anthropic: \"ANTHROPIC_API_KEY\",\n openai: \"OPENAI_API_KEY\",\n};\n\n/** Event other parts of the agent UI listen for to re-check the LLM gate. */\nconst CONFIGURED_CHANGED_EVENT = \"agent-engine:configured-changed\";\n\nexport interface SaveAgentEngineApiKeyOptions {\n provider?: AgentEngineProvider;\n key?: string;\n apiKey: string;\n scope?: \"user\" | \"org\";\n}\n\nexport interface SaveAgentEngineProviderSettingsOptions {\n provider?: AgentEngineProvider;\n key?: string;\n apiKey?: string;\n baseUrl?: string;\n clearBaseUrl?: boolean;\n scope?: \"user\" | \"org\";\n}\n\nfunction resolveProviderEnvVar(\n provider: AgentEngineProvider | undefined,\n key: string | undefined,\n): string {\n const envVar = key?.trim() || (provider ? PROVIDER_ENV_VAR[provider] : \"\");\n if (!envVar) {\n throw new Error(\"Choose an API key provider first.\");\n }\n return envVar;\n}\n\nfunction dispatchConfiguredChanged(): void {\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(new CustomEvent(CONFIGURED_CHANGED_EVENT));\n }\n}\n\n/**\n * Persist a provider API key for the current owner. Resolves on success.\n * Throws an Error with a readable message on failure. On success it also\n * dispatches `agent-engine:configured-changed` so any open agent chat flips\n * out of its \"needs setup\" state without a reload.\n */\nexport async function saveAgentEngineApiKey({\n provider,\n key,\n apiKey,\n scope,\n}: SaveAgentEngineApiKeyOptions): Promise<void> {\n if (!apiKey.trim()) {\n throw new Error(\"Enter an API key first.\");\n }\n await saveAgentEngineProviderSettings({ provider, key, apiKey, scope });\n}\n\n/**\n * Persist provider-specific settings for the current owner. This intentionally\n * stays narrow: API keys for built-in BYOK providers, plus OpenAI's optional\n * compatible endpoint URL. Values are stored server-side in scoped secrets.\n */\nexport async function saveAgentEngineProviderSettings({\n provider,\n key,\n apiKey,\n baseUrl,\n clearBaseUrl,\n scope,\n}: SaveAgentEngineProviderSettingsOptions): Promise<void> {\n const trimmed = apiKey?.trim() ?? \"\";\n const endpoint = baseUrl?.trim() ?? \"\";\n if (!trimmed && !endpoint && !clearBaseUrl) {\n throw new Error(\"Enter an API key or endpoint URL first.\");\n }\n const envVar = resolveProviderEnvVar(provider, key);\n const res = await fetch(\n agentNativePath(\"/_agent-native/agent-engine/api-key\"),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n key: envVar,\n ...(trimmed ? { value: trimmed } : {}),\n ...(endpoint ? { baseUrl: endpoint } : {}),\n ...(clearBaseUrl ? { clearBaseUrl: true } : {}),\n scope,\n }),\n },\n );\n if (!res.ok) {\n const message = await res\n .json()\n .then((body: { error?: string }) => body?.error)\n .catch(() => null);\n throw new Error(\n message ??\n (res.status === 401\n ? \"Sign in to save a key, or connect Builder instead.\"\n : `Could not save provider settings (HTTP ${res.status}).`),\n );\n }\n dispatchConfiguredChanged();\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/client/analytics.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,oBAAoB,EACpB,wBAAwB,EACzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,YAAY,EACV,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;QAChC,uBAAuB,CAAC,EAAE;YACxB,SAAS,CAAC,EAAE,MAAM,CAAC;YACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;SAC5B,CAAC;KACH;CACF;AAED,KAAK,eAAe,GAAG,CACrB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAChC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAO7B,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,aAAa,CAAC,EAAE,OAAO,GAAG,oBAAoB,CAAC;CAChD,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;
|
|
1
|
+
{"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/client/analytics.ts"],"names":[],"mappings":"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"}
|
package/dist/client/analytics.js
CHANGED
|
@@ -16,6 +16,9 @@ let _trackingIdentity = null;
|
|
|
16
16
|
let _trackingIdentityResolved = false;
|
|
17
17
|
let _trackingSessionRefresh = null;
|
|
18
18
|
let _trackingSessionRefreshInstalled = false;
|
|
19
|
+
let _sessionReplayOptions = null;
|
|
20
|
+
let _sessionReplayIdentitySnapshot = null;
|
|
21
|
+
let _sessionReplayStartPromise = null;
|
|
19
22
|
// Buffer for setSentryUser calls made before Sentry has initialized.
|
|
20
23
|
// `undefined` means "no pending update"; `null` means "pending clear".
|
|
21
24
|
let _pendingSentryUser = undefined;
|
|
@@ -171,17 +174,41 @@ function installLlmConnectionRefresh() {
|
|
|
171
174
|
function readTrackingString(value) {
|
|
172
175
|
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
173
176
|
}
|
|
177
|
+
function stopSessionReplayForAuthClear(previousIdentity) {
|
|
178
|
+
if (!_sessionReplayOptions?.requireSignedInUser) {
|
|
179
|
+
_sessionReplayIdentitySnapshot = null;
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (!previousIdentity?.userEmail)
|
|
183
|
+
return;
|
|
184
|
+
_sessionReplayIdentitySnapshot = previousIdentity;
|
|
185
|
+
void import("./session-replay.js")
|
|
186
|
+
.then((mod) => mod.stopSessionReplay("auth-cleared"))
|
|
187
|
+
.catch(() => {
|
|
188
|
+
// Auth clearing should never fail because replay cleanup failed.
|
|
189
|
+
})
|
|
190
|
+
.finally(() => {
|
|
191
|
+
if (_sessionReplayIdentitySnapshot === previousIdentity) {
|
|
192
|
+
_sessionReplayIdentitySnapshot = null;
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
function clearTrackingIdentity() {
|
|
197
|
+
const previousIdentity = _trackingIdentity;
|
|
198
|
+
stopSessionReplayForAuthClear(previousIdentity);
|
|
199
|
+
_trackingIdentity = null;
|
|
200
|
+
}
|
|
174
201
|
function setTrackingIdentityFromSession(data) {
|
|
175
202
|
const session = data;
|
|
176
203
|
if (!session || typeof session !== "object" || session.error) {
|
|
177
|
-
|
|
204
|
+
clearTrackingIdentity();
|
|
178
205
|
return;
|
|
179
206
|
}
|
|
180
207
|
const email = readTrackingString(session.email);
|
|
181
208
|
const authUserId = readTrackingString(session.userId);
|
|
182
209
|
const userId = email || authUserId;
|
|
183
210
|
if (!userId) {
|
|
184
|
-
|
|
211
|
+
clearTrackingIdentity();
|
|
185
212
|
return;
|
|
186
213
|
}
|
|
187
214
|
const userName = readTrackingString(session.name);
|
|
@@ -205,7 +232,7 @@ function refreshTrackingAuthSession() {
|
|
|
205
232
|
setTrackingIdentityFromSession(data);
|
|
206
233
|
})
|
|
207
234
|
.catch(() => {
|
|
208
|
-
|
|
235
|
+
clearTrackingIdentity();
|
|
209
236
|
})
|
|
210
237
|
.finally(() => {
|
|
211
238
|
_trackingIdentityResolved = true;
|
|
@@ -222,8 +249,7 @@ function installTrackingAuthSessionRefresh() {
|
|
|
222
249
|
void refreshTrackingAuthSession();
|
|
223
250
|
});
|
|
224
251
|
}
|
|
225
|
-
function applyTrackingIdentity(properties) {
|
|
226
|
-
const identity = _trackingIdentity;
|
|
252
|
+
function applyTrackingIdentity(properties, identity = _trackingIdentity) {
|
|
227
253
|
if (!identity)
|
|
228
254
|
return properties;
|
|
229
255
|
let next = properties;
|
|
@@ -633,21 +659,29 @@ function ensureSentry() {
|
|
|
633
659
|
* for filtering Sentry by tenant.
|
|
634
660
|
*/
|
|
635
661
|
export function setSentryUser(user, orgId) {
|
|
662
|
+
let shouldRetryReplay = false;
|
|
636
663
|
if (user) {
|
|
637
664
|
const userId = user.email || user.id;
|
|
638
|
-
|
|
639
|
-
|
|
665
|
+
if (userId) {
|
|
666
|
+
_trackingIdentity = {
|
|
640
667
|
userId,
|
|
641
668
|
...(user.email ? { userEmail: user.email } : {}),
|
|
642
669
|
...(user.username ? { userName: user.username } : {}),
|
|
643
670
|
orgId: orgId ?? null,
|
|
644
|
-
}
|
|
645
|
-
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
else {
|
|
674
|
+
clearTrackingIdentity();
|
|
675
|
+
}
|
|
676
|
+
shouldRetryReplay = Boolean(user.email);
|
|
646
677
|
}
|
|
647
678
|
else {
|
|
648
|
-
|
|
679
|
+
clearTrackingIdentity();
|
|
649
680
|
}
|
|
650
681
|
_trackingIdentityResolved = true;
|
|
682
|
+
if (shouldRetryReplay && _sessionReplayOptions?.requireSignedInUser) {
|
|
683
|
+
void startConfiguredSessionReplay(_sessionReplayOptions);
|
|
684
|
+
}
|
|
651
685
|
if (_sentryInitialized) {
|
|
652
686
|
Sentry.setUser(user);
|
|
653
687
|
if (orgId !== undefined) {
|
|
@@ -753,7 +787,14 @@ function sessionReplayRequiresSignedInUserFromEnv() {
|
|
|
753
787
|
const env = import.meta.env ?? {};
|
|
754
788
|
const value = env.VITE_AGENT_NATIVE_SESSION_REPLAY_REQUIRE_AUTH ||
|
|
755
789
|
env.VITE_SESSION_REPLAY_REQUIRE_AUTH;
|
|
756
|
-
|
|
790
|
+
const normalized = (value ?? "").trim();
|
|
791
|
+
if (!normalized)
|
|
792
|
+
return undefined;
|
|
793
|
+
if (/^(1|true|yes|on)$/i.test(normalized))
|
|
794
|
+
return true;
|
|
795
|
+
if (/^(0|false|no|off)$/i.test(normalized))
|
|
796
|
+
return false;
|
|
797
|
+
return undefined;
|
|
757
798
|
}
|
|
758
799
|
function configuredSessionReplayOptions(config, tracking = {}) {
|
|
759
800
|
const publicKey = tracking.publicKey || _agentNativeAnalyticsPublicKey;
|
|
@@ -768,7 +809,8 @@ function configuredSessionReplayOptions(config, tracking = {}) {
|
|
|
768
809
|
...(endpoint && !options.endpoint ? { endpoint } : {}),
|
|
769
810
|
...options,
|
|
770
811
|
requireSignedInUser: options.requireSignedInUser ??
|
|
771
|
-
sessionReplayRequiresSignedInUserFromEnv()
|
|
812
|
+
sessionReplayRequiresSignedInUserFromEnv() ??
|
|
813
|
+
true,
|
|
772
814
|
...(extraProperties ? { extraProperties } : {}),
|
|
773
815
|
};
|
|
774
816
|
};
|
|
@@ -792,7 +834,7 @@ function replayExtraPropertiesWithDefaults(source) {
|
|
|
792
834
|
: {};
|
|
793
835
|
const props = rawProps && typeof rawProps === "object" ? rawProps : {};
|
|
794
836
|
const withDefaults = _getDefaultProps?.("session_replay", props) ?? props;
|
|
795
|
-
return applyTrackingIdentity(withDefaults);
|
|
837
|
+
return applyTrackingIdentity(withDefaults, _trackingIdentity ?? _sessionReplayIdentitySnapshot);
|
|
796
838
|
};
|
|
797
839
|
}
|
|
798
840
|
function replayEndpointFromTrackingEndpoint(value) {
|
|
@@ -824,12 +866,13 @@ function maybeInstallSessionReplay(config, tracking) {
|
|
|
824
866
|
const options = configuredSessionReplayOptions(config, tracking);
|
|
825
867
|
if (!options)
|
|
826
868
|
return;
|
|
869
|
+
_sessionReplayOptions = options;
|
|
827
870
|
void startConfiguredSessionReplay(options);
|
|
828
871
|
}
|
|
829
872
|
async function waitForSessionReplayAuthIfRequired(options) {
|
|
830
873
|
if (!options.requireSignedInUser)
|
|
831
874
|
return true;
|
|
832
|
-
if (_trackingIdentity?.
|
|
875
|
+
if (_trackingIdentity?.userEmail)
|
|
833
876
|
return true;
|
|
834
877
|
try {
|
|
835
878
|
if (_trackingSessionRefresh) {
|
|
@@ -842,19 +885,23 @@ async function waitForSessionReplayAuthIfRequired(options) {
|
|
|
842
885
|
catch {
|
|
843
886
|
// best-effort; missing identity below keeps replay off
|
|
844
887
|
}
|
|
845
|
-
return !!_trackingIdentity?.
|
|
888
|
+
return !!_trackingIdentity?.userEmail;
|
|
846
889
|
}
|
|
847
890
|
async function startConfiguredSessionReplay(options) {
|
|
848
|
-
if (
|
|
849
|
-
return
|
|
850
|
-
|
|
851
|
-
|
|
891
|
+
if (_sessionReplayStartPromise)
|
|
892
|
+
return _sessionReplayStartPromise;
|
|
893
|
+
_sessionReplayStartPromise = (async () => {
|
|
894
|
+
if (!(await waitForSessionReplayAuthIfRequired(options))) {
|
|
895
|
+
return { started: false, reason: "missing-user-id" };
|
|
896
|
+
}
|
|
852
897
|
const mod = await import("./session-replay.js");
|
|
853
898
|
return mod.startSessionReplay(options);
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
899
|
+
})()
|
|
900
|
+
.catch(() => ({ started: false, reason: "import-failed" }))
|
|
901
|
+
.finally(() => {
|
|
902
|
+
_sessionReplayStartPromise = null;
|
|
903
|
+
});
|
|
904
|
+
return _sessionReplayStartPromise;
|
|
858
905
|
}
|
|
859
906
|
export async function startSessionReplay(options = {}) {
|
|
860
907
|
const configured = configuredSessionReplayOptions(options) ?? options;
|
|
@@ -874,7 +921,7 @@ export async function maybeStartSessionReplay(options = {}) {
|
|
|
874
921
|
}
|
|
875
922
|
export async function stopSessionReplay(reason = "manual") {
|
|
876
923
|
const mod = await import("./session-replay.js");
|
|
877
|
-
mod.stopSessionReplay(reason);
|
|
924
|
+
await mod.stopSessionReplay(reason);
|
|
878
925
|
}
|
|
879
926
|
function inferTemplateName(properties) {
|
|
880
927
|
const envTemplate = import.meta.env
|