@agent-native/core 0.167.1 → 0.168.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/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/assets/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/brain/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/brain/actions/list-sources.ts +17 -7
- package/corpus/templates/brain/app/components/brain/Surface.tsx +4 -2
- package/corpus/templates/brain/app/lib/brain.ts +13 -3
- package/corpus/templates/brain/server/lib/brain-health.ts +5 -8
- package/corpus/templates/brain/server/lib/brain.ts +1 -0
- package/corpus/templates/brain/server/lib/capture-sanitization.ts +5 -0
- package/corpus/templates/brain/server/routes/api/brain/queue/run.post.ts +3 -2
- package/corpus/templates/calendar/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/chat/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/clips/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/clips/app/routes/download.tsx +78 -131
- package/corpus/templates/clips/desktop/src/app.tsx +11 -10
- package/corpus/templates/clips/desktop/src/lib/desktop-oauth-window.ts +23 -0
- package/corpus/templates/content/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/crm/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/design/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/dispatch/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/factory/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/forms/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/macros/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/mail/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/plan/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/slides/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/dist/chat-threads/store.d.ts +7 -0
- package/dist/chat-threads/store.js +15 -0
- package/dist/client/AboutAgentNativeDialog.d.ts +5 -0
- package/dist/client/AboutAgentNativeDialog.js +56 -0
- package/dist/client/AgentPanel.d.ts +5 -1
- package/dist/client/AgentPanel.js +8 -8
- package/dist/client/AssistantChat.d.ts +3 -1
- package/dist/client/AssistantChat.js +22 -6
- package/dist/client/CommandMenu.d.ts +6 -1
- package/dist/client/CommandMenu.js +46 -3
- package/dist/client/EnvironmentBadge.js +4 -1
- package/dist/client/MultiTabAssistantChat.d.ts +3 -1
- package/dist/client/MultiTabAssistantChat.js +5 -4
- package/dist/client/agent-native-version.d.ts +12 -0
- package/dist/client/agent-native-version.js +36 -0
- package/dist/client/agent-page/AgentJobsTab.js +39 -6
- package/dist/client/agent-page/AutomationScheduleDialog.d.ts +10 -1
- package/dist/client/agent-page/AutomationScheduleDialog.js +3 -2
- package/dist/client/agent-page/ScheduledTriggerNotice.d.ts +22 -0
- package/dist/client/agent-page/ScheduledTriggerNotice.js +84 -0
- package/dist/client/agent-page/scheduled-trigger-state.d.ts +28 -0
- package/dist/client/agent-page/scheduled-trigger-state.js +10 -0
- package/dist/client/agent-page/use-jobs.d.ts +7 -0
- package/dist/client/agent-page/use-jobs.js +14 -0
- package/dist/client/blocks/library/diagram.config.d.ts +4 -1
- package/dist/client/blocks/library/diagram.js +1 -1
- package/dist/client/chat/run-recovery.js +15 -7
- package/dist/client/use-chat-threads.d.ts +7 -0
- package/dist/client/use-chat-threads.js +144 -40
- package/dist/collab/routes.d.ts +1 -1
- package/dist/config.d.ts +3 -1
- package/dist/config.js +14 -9
- package/dist/deploy/build.d.ts +5 -0
- package/dist/deploy/build.js +12 -1
- package/dist/framework-tools.js +1 -0
- package/dist/jobs/actions/get-scheduled-trigger-status.d.ts +13 -0
- package/dist/jobs/actions/get-scheduled-trigger-status.js +21 -0
- package/dist/localization/core-messages/ar-SA.js +6 -0
- package/dist/localization/core-messages/de-DE.js +6 -0
- package/dist/localization/core-messages/en-US.d.ts +6 -0
- package/dist/localization/core-messages/en-US.js +6 -0
- package/dist/localization/core-messages/es-ES.js +6 -0
- package/dist/localization/core-messages/fr-FR.js +6 -0
- package/dist/localization/core-messages/hi-IN.js +6 -0
- package/dist/localization/core-messages/ja-JP.js +6 -0
- package/dist/localization/core-messages/ko-KR.js +6 -0
- package/dist/localization/core-messages/pt-BR.js +6 -0
- package/dist/localization/core-messages/zh-CN.js +6 -0
- package/dist/localization/core-messages/zh-TW.js +6 -0
- package/dist/localization/core-messages.d.ts +6 -0
- package/dist/localization/default-messages.d.ts +14 -0
- package/dist/localization/default-messages.js +14 -0
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/provider-api/actions/custom-provider-registration.d.ts +1 -1
- package/dist/provider-api/actions/provider-api.d.ts +12 -12
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/server/action-discovery.js +4 -0
- package/dist/server/agent-chat/recurring-jobs-runtime.d.ts +42 -1
- package/dist/server/agent-chat/recurring-jobs-runtime.js +102 -9
- package/dist/server/agent-chat-plugin.d.ts +3 -1
- package/dist/server/agent-chat-plugin.js +115 -24
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/attribution.d.ts +29 -0
- package/dist/server/attribution.js +68 -0
- package/dist/server/auth.js +58 -15
- package/dist/server/better-auth-instance.js +16 -4
- package/dist/server/identity-sso.js +14 -2
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/request-context.d.ts +8 -0
- package/dist/server/request-context.js +4 -0
- package/dist/templates/chat/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/dist/vite/agent-native-config-loader.js +1 -1
- package/dist/vite/client.js +19 -8
- package/dist/vite/package-versions.d.ts +1 -0
- package/dist/vite/package-versions.js +97 -0
- package/docs/content/agent-native-config.mdx +55 -31
- package/docs/content/deployment.mdx +3 -1
- package/docs/content/environment-variables.mdx +51 -14
- package/docs/content/recurring-jobs.mdx +6 -0
- package/package.json +2 -2
- package/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +11 -0
- package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +11 -0
package/dist/server/auth.js
CHANGED
|
@@ -58,7 +58,7 @@ import { isValidWorkspaceAppIdFormat } from "../shared/workspace-app-id.js";
|
|
|
58
58
|
import { injectAnalyticsIntoHtml } from "./analytics.js";
|
|
59
59
|
import { getConfiguredAppBasePath } from "./app-base-path.js";
|
|
60
60
|
import { getAppProductionUrl } from "./app-url.js";
|
|
61
|
-
import { readAnalyticsAnonymousId, readFirstTouchAttribution, signupAttributionFromCookieHeader, } from "./attribution.js";
|
|
61
|
+
import { addSignupAttributionHeader, readAnalyticsAnonymousId, readFirstTouchAttribution, signupAttributionContextFromCookieHeader, signupAttributionFromCookieHeader, } from "./attribution.js";
|
|
62
62
|
import { getAuthLoginMode } from "./auth-login-mode.js";
|
|
63
63
|
import { injectBetaOptOutPersistence } from "./beta-opt-out-html.js";
|
|
64
64
|
import { createBetterAuthSessionForEmail, ensureGoogleAuthIdentity, getAuthSecret, getBetterAuth, getBetterAuthSync, isDeployPreview, } from "./better-auth-instance.js";
|
|
@@ -73,6 +73,7 @@ import { ensureCanonicalUserForLegacySession } from "./legacy-auth-migration.js"
|
|
|
73
73
|
import { encodeMagicLinkSignupAttribution, MAGIC_LINK_ATTRIBUTION_PARAM, } from "./magic-link-attribution.js";
|
|
74
74
|
import { safeOAuthReturnUrl } from "./oauth-return-url.js";
|
|
75
75
|
import { getOnboardingHtml, getResetPasswordHtml, } from "./onboarding-html.js";
|
|
76
|
+
import { getRequestContext, hasContinuationLocalRequestContext, runWithRequestContext, } from "./request-context.js";
|
|
76
77
|
import { captureAuthError } from "./sentry.js";
|
|
77
78
|
import { forgetCachedSessionEmail, getCachedSessionEmail, invalidateSessionEmailCache, setCachedSessionEmail, } from "./session-email-cache.js";
|
|
78
79
|
import { isWorkspaceOAuthCallbackRelayEnabled } from "./workspace-oauth.js";
|
|
@@ -83,6 +84,23 @@ import { isWorkspaceOAuthCallbackRelayEnabled } from "./workspace-oauth.js";
|
|
|
83
84
|
export function getSessionMaxAge() {
|
|
84
85
|
return sessionMaxAge;
|
|
85
86
|
}
|
|
87
|
+
function withSignupAttributionContext(cookieHeader, fn) {
|
|
88
|
+
const signupAttribution = signupAttributionContextFromCookieHeader(cookieHeader);
|
|
89
|
+
if (!hasContinuationLocalRequestContext())
|
|
90
|
+
return fn();
|
|
91
|
+
return runWithRequestContext({
|
|
92
|
+
...(getRequestContext() ?? {}),
|
|
93
|
+
signupAttribution,
|
|
94
|
+
}, fn);
|
|
95
|
+
}
|
|
96
|
+
function requestWithSignupAttribution(request, signupAttribution) {
|
|
97
|
+
return new Request(request, {
|
|
98
|
+
headers: addSignupAttributionHeader(request.headers, signupAttribution),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
function headersWithSignupAttribution(headers, cookieHeader) {
|
|
102
|
+
return addSignupAttributionHeader(headers, signupAttributionContextFromCookieHeader(cookieHeader));
|
|
103
|
+
}
|
|
86
104
|
// ---------------------------------------------------------------------------
|
|
87
105
|
// Constants
|
|
88
106
|
// ---------------------------------------------------------------------------
|
|
@@ -416,6 +434,9 @@ async function readDesktopSsoSafely(event) {
|
|
|
416
434
|
return null;
|
|
417
435
|
return await readDesktopSso();
|
|
418
436
|
}
|
|
437
|
+
function isDesktopSessionCookieOnlyCheck(event) {
|
|
438
|
+
return getHeader(event, "x-agent-native-session-check") === "cookie-only";
|
|
439
|
+
}
|
|
419
440
|
/**
|
|
420
441
|
* Extract the framework session token from a Better Auth response's
|
|
421
442
|
* Set-Cookie headers, if any. Used by the password-reset path to skip
|
|
@@ -2688,6 +2709,7 @@ export async function getSession(event) {
|
|
|
2688
2709
|
})());
|
|
2689
2710
|
}
|
|
2690
2711
|
async function resolveSessionUncached(event) {
|
|
2712
|
+
const cookieOnlyDesktopCheck = isDesktopSessionCookieOnlyCheck(event);
|
|
2691
2713
|
// 1. MCP App embed session. This is a short-lived browser session minted
|
|
2692
2714
|
// from a one-time ticket that was scoped to the authenticated MCP caller.
|
|
2693
2715
|
// It lets an inline MCP App iframe load the real app without reusing the
|
|
@@ -2724,9 +2746,11 @@ async function resolveSessionUncached(event) {
|
|
|
2724
2746
|
// templates too. Gated on `readDesktopSsoSafely` so a non-loopback
|
|
2725
2747
|
// request that spoofs `User-Agent: ... Electron/...` cannot read the
|
|
2726
2748
|
// home-dir broker file (and so production builds never consult it).
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2749
|
+
if (!cookieOnlyDesktopCheck) {
|
|
2750
|
+
const sso = await readDesktopSsoSafely(event);
|
|
2751
|
+
if (sso?.email)
|
|
2752
|
+
return { email: sso.email, token: sso.token };
|
|
2753
|
+
}
|
|
2730
2754
|
// Fall through to mobile _session check
|
|
2731
2755
|
}
|
|
2732
2756
|
else {
|
|
@@ -2765,9 +2789,11 @@ async function resolveSessionUncached(event) {
|
|
|
2765
2789
|
// a loopback (127.0.0.1 / ::1) source IP, and a non-production NODE_ENV
|
|
2766
2790
|
// — anything else is rejected so a hostile network request cannot
|
|
2767
2791
|
// impersonate whichever email last signed into the desktop app.
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2792
|
+
if (!cookieOnlyDesktopCheck) {
|
|
2793
|
+
const sso = await readDesktopSsoSafely(event);
|
|
2794
|
+
if (sso?.email) {
|
|
2795
|
+
return { email: sso.email, token: sso.token };
|
|
2796
|
+
}
|
|
2771
2797
|
}
|
|
2772
2798
|
}
|
|
2773
2799
|
// 8. Mobile WebView bridge — _session query param
|
|
@@ -3699,11 +3725,18 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
3699
3725
|
getMethod(event) === "POST";
|
|
3700
3726
|
const isMagicLinkRequest = reqPath.includes("/sign-in/magic-link") && getMethod(event) === "POST";
|
|
3701
3727
|
const isMagicLinkVerification = reqPath.includes("/magic-link/verify") && getMethod(event) === "GET";
|
|
3728
|
+
const isEmailSignup = reqPath.includes("/sign-up/email") && getMethod(event) === "POST";
|
|
3702
3729
|
const isSignOut = reqPath.includes("sign-out") && getMethod(event) === "POST";
|
|
3703
3730
|
if (isSignOut)
|
|
3704
3731
|
optOutOfAuthDisabledSession(event);
|
|
3705
3732
|
const authRequest = toWebRequest(event);
|
|
3706
3733
|
let requestForAuth = authRequest;
|
|
3734
|
+
const signupCookieHeader = isEmailSignup
|
|
3735
|
+
? authRequest.headers.get("cookie")
|
|
3736
|
+
: undefined;
|
|
3737
|
+
const signupAttribution = isEmailSignup
|
|
3738
|
+
? signupAttributionContextFromCookieHeader(signupCookieHeader)
|
|
3739
|
+
: undefined;
|
|
3707
3740
|
let magicLinkPreConsume;
|
|
3708
3741
|
if (isMagicLinkVerification) {
|
|
3709
3742
|
const verificationURL = new URL(authRequest.url);
|
|
@@ -3820,9 +3853,14 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
3820
3853
|
// validation error.
|
|
3821
3854
|
}
|
|
3822
3855
|
}
|
|
3856
|
+
if (signupAttribution) {
|
|
3857
|
+
requestForAuth = requestWithSignupAttribution(requestForAuth, signupAttribution);
|
|
3858
|
+
}
|
|
3823
3859
|
let response;
|
|
3824
3860
|
try {
|
|
3825
|
-
response = await
|
|
3861
|
+
response = await (isEmailSignup
|
|
3862
|
+
? withSignupAttributionContext(signupCookieHeader, () => auth.handler(requestForAuth))
|
|
3863
|
+
: auth.handler(requestForAuth));
|
|
3826
3864
|
}
|
|
3827
3865
|
catch (error) {
|
|
3828
3866
|
if (isMagicLinkVerification) {
|
|
@@ -4127,10 +4165,15 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
4127
4165
|
return { error: GOOGLE_AUTH_REQUIRED_MESSAGE };
|
|
4128
4166
|
}
|
|
4129
4167
|
try {
|
|
4130
|
-
await auth.api.signUpEmail({
|
|
4131
|
-
body: {
|
|
4132
|
-
|
|
4133
|
-
|
|
4168
|
+
await withSignupAttributionContext(getHeader(event, "cookie") ?? null, () => auth.api.signUpEmail({
|
|
4169
|
+
body: {
|
|
4170
|
+
email,
|
|
4171
|
+
password,
|
|
4172
|
+
name: email.split("@")[0],
|
|
4173
|
+
callbackURL,
|
|
4174
|
+
},
|
|
4175
|
+
headers: headersWithSignupAttribution(event.headers, getHeader(event, "cookie") ?? null),
|
|
4176
|
+
}));
|
|
4134
4177
|
setFirstRunOnboardingCookie(event);
|
|
4135
4178
|
return { ok: true };
|
|
4136
4179
|
}
|
|
@@ -4384,10 +4427,10 @@ function mountAuthFallbackRoutes(app) {
|
|
|
4384
4427
|
}
|
|
4385
4428
|
try {
|
|
4386
4429
|
const auth = await getBetterAuth();
|
|
4387
|
-
await auth.api.signUpEmail({
|
|
4430
|
+
await withSignupAttributionContext(getHeader(event, "cookie") ?? null, () => auth.api.signUpEmail({
|
|
4388
4431
|
body: { email, password, name: email.split("@")[0] },
|
|
4389
|
-
headers: event.headers,
|
|
4390
|
-
});
|
|
4432
|
+
headers: headersWithSignupAttribution(event.headers, getHeader(event, "cookie") ?? null),
|
|
4433
|
+
}));
|
|
4391
4434
|
setFirstRunOnboardingCookie(event);
|
|
4392
4435
|
return { ok: true };
|
|
4393
4436
|
}
|
|
@@ -26,13 +26,14 @@ import { PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, } from "../shared/password-po
|
|
|
26
26
|
import { formatRuntimeConfigReport, getRuntimeConfigReport, } from "../shared/runtime-config.js";
|
|
27
27
|
import { flushTracking, identify, track } from "../tracking/index.js";
|
|
28
28
|
import { getAppProductionUrl } from "./app-url.js";
|
|
29
|
-
import {
|
|
29
|
+
import { signupAttributionContextFromCookieHeader, signupAttributionContextFromHeaders, } from "./attribution.js";
|
|
30
30
|
import { resolveAuthCookieNamespace } from "./cookie-namespace.js";
|
|
31
31
|
import { getWorkspaceA2ADerivedSecret } from "./derived-secret.js";
|
|
32
32
|
import { renderMagicLinkEmail, renderResetPasswordEmail, renderVerifySignupEmail, } from "./email-templates.js";
|
|
33
33
|
import { getEmailReadiness, sendEmail } from "./email.js";
|
|
34
34
|
import { resolveGoogleSignInCredentials } from "./google-oauth-credentials.js";
|
|
35
35
|
import { readMagicLinkSignupAttribution } from "./magic-link-attribution.js";
|
|
36
|
+
import { getRequestContext, hasContinuationLocalRequestContext, } from "./request-context.js";
|
|
36
37
|
export { getAuthLoginMode, resolveAuthLoginMode, resolveAuthLoginModeFromReadiness, } from "./auth-login-mode.js";
|
|
37
38
|
async function flushSignupTracking() {
|
|
38
39
|
try {
|
|
@@ -1045,14 +1046,25 @@ async function createBetterAuthInstance(config) {
|
|
|
1045
1046
|
const cookieHeader = context?.headers?.get("cookie") ??
|
|
1046
1047
|
context?.request?.headers?.get("cookie") ??
|
|
1047
1048
|
null;
|
|
1049
|
+
const scopedSignupAttribution = hasContinuationLocalRequestContext()
|
|
1050
|
+
? getRequestContext()?.signupAttribution
|
|
1051
|
+
: undefined;
|
|
1052
|
+
const requestSignupAttribution = signupAttributionContextFromCookieHeader(cookieHeader);
|
|
1053
|
+
const headerSignupAttribution = signupAttributionContextFromHeaders(context?.headers) ??
|
|
1054
|
+
signupAttributionContextFromHeaders(context?.request?.headers);
|
|
1048
1055
|
const magicLinkAttribution = context?.request?.url?.includes("newUserCallbackURL")
|
|
1049
1056
|
? readMagicLinkSignupAttribution(context.request.url, getAuthSecret())
|
|
1050
1057
|
: undefined;
|
|
1051
|
-
attribution =
|
|
1052
|
-
|
|
1058
|
+
attribution =
|
|
1059
|
+
magicLinkAttribution?.attribution ??
|
|
1060
|
+
scopedSignupAttribution?.attribution ??
|
|
1061
|
+
headerSignupAttribution?.attribution ??
|
|
1062
|
+
requestSignupAttribution.attribution;
|
|
1053
1063
|
anonymousId =
|
|
1054
1064
|
magicLinkAttribution?.anonymousId ??
|
|
1055
|
-
|
|
1065
|
+
scopedSignupAttribution?.anonymousId ??
|
|
1066
|
+
headerSignupAttribution?.anonymousId ??
|
|
1067
|
+
requestSignupAttribution.anonymousId;
|
|
1056
1068
|
}
|
|
1057
1069
|
catch (err) {
|
|
1058
1070
|
console.error("[auth] failed to derive signup attribution", err);
|
|
@@ -19,10 +19,12 @@ import { getAppConfig } from "../app-config/index.js";
|
|
|
19
19
|
import { GOOGLE_AUTH_REQUIRED_MESSAGE, isGoogleSignInRequiredForEmail, } from "../org/auth-policy.js";
|
|
20
20
|
import { SIGN_IN_ENTRY_PATH } from "../shared/sign-in-journey.js";
|
|
21
21
|
import { getAppName } from "./app-name.js";
|
|
22
|
+
import { addSignupAttributionHeader, signupAttributionContextFromCookieHeader, } from "./attribution.js";
|
|
22
23
|
import { getSession, isExpectedAuthFailure, safeReturnPath } from "./auth.js";
|
|
23
24
|
import { getBetterAuth, getBetterAuthInternalAdapter, } from "./better-auth-instance.js";
|
|
24
25
|
import { createOAuthSession, getOrigin } from "./google-oauth.js";
|
|
25
26
|
import { consumeSsoState, createSsoState, CANONICAL_IDENTITY_SSO_HUB_URL, getIdentityHubUrl, identitySsoLoginButtonHtml, isCanonicalIdentitySsoClientRequest, isDesktopSsoUserAgent, isIdentitySsoExplicitlyEnabled, isIdentitySsoEnabled, isJtiReplayed, SSO_STATE_TTL_MS, } from "./identity-sso-store.js";
|
|
27
|
+
import { getRequestContext, hasContinuationLocalRequestContext, runWithRequestContext, } from "./request-context.js";
|
|
26
28
|
export { getIdentityHubUrl, identitySsoLoginButtonHtml, isIdentitySsoEnabled };
|
|
27
29
|
export const IDENTITY_SSO_PROVIDER_ID = "agent-native";
|
|
28
30
|
export const IDENTITY_SSO_SCOPE = "identity";
|
|
@@ -269,7 +271,7 @@ async function exchangeIdentityCode(hub, binding, input) {
|
|
|
269
271
|
return null;
|
|
270
272
|
}
|
|
271
273
|
}
|
|
272
|
-
async function jitLinkIdentity(identity) {
|
|
274
|
+
async function jitLinkIdentity(identity, signupHeaders) {
|
|
273
275
|
const adapter = await getBetterAuthInternalAdapter();
|
|
274
276
|
let existing = adapter
|
|
275
277
|
? await adapter
|
|
@@ -288,6 +290,7 @@ async function jitLinkIdentity(identity) {
|
|
|
288
290
|
password: createUnusableSsoCredential(),
|
|
289
291
|
name: identity.name || identity.email.split("@")[0] || "User",
|
|
290
292
|
},
|
|
293
|
+
...(signupHeaders ? { headers: signupHeaders } : {}),
|
|
291
294
|
});
|
|
292
295
|
}
|
|
293
296
|
catch (error) {
|
|
@@ -463,7 +466,16 @@ export async function handleIdentitySso(event, subpath) {
|
|
|
463
466
|
return errorPage(GOOGLE_AUTH_REQUIRED_MESSAGE, loginPath);
|
|
464
467
|
}
|
|
465
468
|
try {
|
|
466
|
-
|
|
469
|
+
const signupCookieHeader = getHeader(event, "cookie") ?? null;
|
|
470
|
+
const signupAttribution = signupAttributionContextFromCookieHeader(signupCookieHeader);
|
|
471
|
+
const signupHeaders = addSignupAttributionHeader(event.headers, signupAttribution);
|
|
472
|
+
const linkIdentity = () => jitLinkIdentity(identity, signupHeaders);
|
|
473
|
+
await (hasContinuationLocalRequestContext()
|
|
474
|
+
? runWithRequestContext({
|
|
475
|
+
...(getRequestContext() ?? {}),
|
|
476
|
+
signupAttribution,
|
|
477
|
+
}, linkIdentity)
|
|
478
|
+
: linkIdentity());
|
|
467
479
|
}
|
|
468
480
|
catch {
|
|
469
481
|
return errorPage("Could not finish linking your account. Please try again.", loginPath);
|
|
@@ -26,8 +26,8 @@ export declare function createRealtimeTokenHandler(): import("h3").EventHandlerW
|
|
|
26
26
|
expiresAt?: undefined;
|
|
27
27
|
ttlSeconds?: undefined;
|
|
28
28
|
} | {
|
|
29
|
-
error?: undefined;
|
|
30
29
|
token: string;
|
|
31
30
|
expiresAt: string;
|
|
32
31
|
ttlSeconds: number;
|
|
32
|
+
error?: undefined;
|
|
33
33
|
}>>;
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* process.env so existing `AGENT_USER_EMAIL=x pnpm action foo` invocations
|
|
16
16
|
* continue to work.
|
|
17
17
|
*/
|
|
18
|
+
import type { SignupAttributionContext } from "./attribution.js";
|
|
18
19
|
/**
|
|
19
20
|
* Per-request agent-run state. Lives on `RequestContext.run` so the
|
|
20
21
|
* agent-chat plugin can populate fields as the run progresses (owner,
|
|
@@ -109,6 +110,11 @@ export interface RequestContext {
|
|
|
109
110
|
* replay; never used for authorization.
|
|
110
111
|
*/
|
|
111
112
|
browserSessionId?: string;
|
|
113
|
+
/**
|
|
114
|
+
* Browser attribution captured before a Better Auth signup crosses into its
|
|
115
|
+
* async user-create hook. Analytics-only; never used for authorization.
|
|
116
|
+
*/
|
|
117
|
+
signupAttribution?: SignupAttributionContext;
|
|
112
118
|
/** Canonical client surface for analytics attribution. */
|
|
113
119
|
clientPlatform?: import("../shared/analytics-platform.js").AnalyticsClientPlatform;
|
|
114
120
|
/**
|
|
@@ -188,6 +194,8 @@ type RequestContextObserver = (ctx: RequestContext) => void;
|
|
|
188
194
|
* overlapping async requests are only isolated by native AsyncLocalStorage.
|
|
189
195
|
*/
|
|
190
196
|
export declare function assertRequestActionSurfaceIsolation(): void;
|
|
197
|
+
/** Whether request context values are isolated across overlapping promises. */
|
|
198
|
+
export declare function hasContinuationLocalRequestContext(): boolean;
|
|
191
199
|
/**
|
|
192
200
|
* Register a callback fired every time `runWithRequestContext` enters a new
|
|
193
201
|
* scope. The hook runs INSIDE the AsyncLocalStorage scope, so observability
|
|
@@ -80,6 +80,10 @@ export function assertRequestActionSurfaceIsolation() {
|
|
|
80
80
|
throw new Error("Request-scoped action surfaces require continuation-local request context storage; " +
|
|
81
81
|
"this runtime only provides the non-isolated fallback.");
|
|
82
82
|
}
|
|
83
|
+
/** Whether request context values are isolated across overlapping promises. */
|
|
84
|
+
export function hasContinuationLocalRequestContext() {
|
|
85
|
+
return globalRef[CONTINUATION_LOCAL_KEY] === true;
|
|
86
|
+
}
|
|
83
87
|
/**
|
|
84
88
|
* Register a callback fired every time `runWithRequestContext` enters a new
|
|
85
89
|
* scope. The hook runs INSIDE the AsyncLocalStorage scope, so observability
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -134,3 +134,14 @@ hand-duplicating framework logic.
|
|
|
134
134
|
`agent-surfaces`.
|
|
135
135
|
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
136
136
|
will do; read `customizing-agent-native` for the supported override ladder.
|
|
137
|
+
|
|
138
|
+
## Authoring visual docs blocks
|
|
139
|
+
|
|
140
|
+
Treat the shared `Diagram` block as a renderer, not as a reason to style every
|
|
141
|
+
docs UI as a sketch. Use the hand-drawn font and Rough.js only for actual
|
|
142
|
+
diagrams or wireframes that communicate structure, flow, or a design draft.
|
|
143
|
+
For polished UI-like content - cards, logo walls, tables, controls, or product
|
|
144
|
+
shells — set `renderMode="design"` (and usually `frame="hide"` when the block
|
|
145
|
+
is the content itself). Design mode preserves normal docs typography and
|
|
146
|
+
disables the Rough.js overlay. Keep `data-rough` only on elements intentionally
|
|
147
|
+
sketched inside a real diagram.
|
|
@@ -81,7 +81,7 @@ export async function loadResolvedAgentNativeConfig(cwd, context, options = {})
|
|
|
81
81
|
: await loadAgentNativeConfigFile(cwd));
|
|
82
82
|
return resolveAgentNativeConfig(mergeAgentNativeConfigs(mergeAgentNativeConfigs(mergeAgentNativeConfigs(workspaceConfig
|
|
83
83
|
? resolveAgentNativeConfig(workspaceConfig, context)
|
|
84
|
-
: {}, readAgentNativeJsonConfig(cwd)), readAgentNativeConfigEnv(options.environment ?? process.env)
|
|
84
|
+
: {}, readAgentNativeJsonConfig(cwd)), projectConfig ? resolveAgentNativeConfig(projectConfig, context) : {}), readAgentNativeConfigEnv(options.environment ?? process.env), { arrayStrategy: "replace" }), context);
|
|
85
85
|
}
|
|
86
86
|
function findConfigPath(cwd) {
|
|
87
87
|
return AGENT_NATIVE_CONFIG_FILE_CANDIDATES.map((filename) => path.join(cwd, filename)).find((candidate) => fs.existsSync(candidate));
|
package/dist/vite/client.js
CHANGED
|
@@ -10,6 +10,7 @@ import { getViteDevRecoveryScript } from "../client/vite-dev-recovery-script.js"
|
|
|
10
10
|
import { inferAgentNativeDeploymentEnvironment, mergeAgentNativeConfigs, readAgentNativeConfigEnv, resolveAgentNativeConfig, } from "../config.js";
|
|
11
11
|
import { writeAgentNativeNitroPresetMarker } from "../deploy/nitro-preset.js";
|
|
12
12
|
import { findWorkspaceRoot } from "../scripts/utils.js";
|
|
13
|
+
import { RECURRING_JOBS_BUILD_MARKER_ENV_VAR, resolveRecurringJobsBuildMarker, } from "../server/agent-chat/recurring-jobs-runtime.js";
|
|
13
14
|
import { verifyEmbedSessionToken } from "../server/embed-session.js";
|
|
14
15
|
import { EMBED_SESSION_COOKIE, EMBED_TOKEN_QUERY_PARAM, MCP_APP_CHAT_BRIDGE_QUERY_PARAM, } from "../shared/embed-auth.js";
|
|
15
16
|
import { isMcpEmbedCorsOrigin, MCP_EMBED_CORS_ALLOW_HEADERS, MCP_EMBED_STATIC_ASSET_HEADERS, mcpEmbedStaticAssetRouteRules, shouldAllowMcpEmbedCredentials, } from "../shared/mcp-embed-headers.js";
|
|
@@ -19,6 +20,7 @@ import { formatRuntimeConfigReport, getRuntimeConfigReport, isTruthyRuntimeValue
|
|
|
19
20
|
import { actionTypesPlugin } from "./action-types-plugin.js";
|
|
20
21
|
import { createAgentNativeConfigContext, loadAgentNativeConfigFile, loadWorkspaceAgentNativeConfigFile, readAgentNativeJsonConfig, } from "./agent-native-config-loader.js";
|
|
21
22
|
import { agentsBundlePlugin } from "./agents-bundle-plugin.js";
|
|
23
|
+
import { resolveAgentNativePackageVersions } from "./package-versions.js";
|
|
22
24
|
const require = createRequire(import.meta.url);
|
|
23
25
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
24
26
|
let nitroFsWatchGuardInstalled = false;
|
|
@@ -2561,6 +2563,10 @@ function createNitroDevPlugin(options, appBasePath) {
|
|
|
2561
2563
|
// injected into deployed Functions. Nitro is a separate server build,
|
|
2562
2564
|
// so it needs the release ownership decision in its own replacement map.
|
|
2563
2565
|
"process.env.AGENT_NATIVE_RELEASE_MIGRATIONS": JSON.stringify(process.env.AGENT_NATIVE_RELEASE_MIGRATIONS?.trim() || ""),
|
|
2566
|
+
// Same reason as the release owner above: the recurring-jobs decision
|
|
2567
|
+
// belongs to the build env, and Nitro is a separate server build with its
|
|
2568
|
+
// own replacement map.
|
|
2569
|
+
[`process.env.${RECURRING_JOBS_BUILD_MARKER_ENV_VAR}`]: JSON.stringify(resolveRecurringJobsBuildMarker(process.env)),
|
|
2564
2570
|
},
|
|
2565
2571
|
// Never auto-load test files as server handlers/plugins/middleware.
|
|
2566
2572
|
// Nitro scans server/{plugins,middleware,routes,api}/*; a co-located
|
|
@@ -2801,7 +2807,7 @@ function reportRuntimeConfigDiagnostics(appConfig, context, mode, env = process.
|
|
|
2801
2807
|
}
|
|
2802
2808
|
console.warn(message);
|
|
2803
2809
|
}
|
|
2804
|
-
function createAgentNativeConfig(options = {}, command, userConfig = {}, mode = process.env.NODE_ENV === "production" ? "production" : "development", projectConfig) {
|
|
2810
|
+
function createAgentNativeConfig(options = {}, command, userConfig = {}, mode = process.env.NODE_ENV === "production" ? "production" : "development", projectConfig, workspaceConfig) {
|
|
2805
2811
|
const cwd = process.cwd();
|
|
2806
2812
|
const configContext = createAgentNativeConfigContext(command, mode);
|
|
2807
2813
|
const projectConfigInput = projectConfig ?? options.agentNativeConfig;
|
|
@@ -2817,9 +2823,11 @@ function createAgentNativeConfig(options = {}, command, userConfig = {}, mode =
|
|
|
2817
2823
|
...loadEnv(mode, cwd, ""),
|
|
2818
2824
|
...process.env,
|
|
2819
2825
|
};
|
|
2820
|
-
const appConfig = resolveAgentNativeConfig(mergeAgentNativeConfigs(mergeAgentNativeConfigs(
|
|
2826
|
+
const appConfig = resolveAgentNativeConfig(mergeAgentNativeConfigs(mergeAgentNativeConfigs(mergeAgentNativeConfigs(workspaceConfig
|
|
2827
|
+
? resolveAgentNativeConfig(workspaceConfig, configContext)
|
|
2828
|
+
: {}, readAgentNativeJsonConfig(cwd)), projectConfigInput
|
|
2821
2829
|
? resolveAgentNativeConfig(projectConfigInput, configContext)
|
|
2822
|
-
: {}), configContext);
|
|
2830
|
+
: {}), readAgentNativeConfigEnv(runtimeEnv), { arrayStrategy: "replace" }), configContext);
|
|
2823
2831
|
const inferredDeploymentEnvironment = appConfig.deployment?.environment ??
|
|
2824
2832
|
inferAgentNativeDeploymentEnvironment(process.env, mode);
|
|
2825
2833
|
const resolvedAppConfig = appConfig.deployment?.environment === undefined &&
|
|
@@ -2835,6 +2843,7 @@ function createAgentNativeConfig(options = {}, command, userConfig = {}, mode =
|
|
|
2835
2843
|
process.env.CF_PAGES_COMMIT_SHA?.trim() ||
|
|
2836
2844
|
process.env.AGENT_NATIVE_BUILD_SHA?.trim() ||
|
|
2837
2845
|
"development";
|
|
2846
|
+
const packageVersions = resolveAgentNativePackageVersions(cwd);
|
|
2838
2847
|
// Preload workspace-root .env into process.env so Nitro server code sees
|
|
2839
2848
|
// shared keys during dev (Nitro reads process.env, not vite's envDir).
|
|
2840
2849
|
if (workspaceRoot && workspaceRoot !== cwd) {
|
|
@@ -2905,6 +2914,7 @@ function createAgentNativeConfig(options = {}, command, userConfig = {}, mode =
|
|
|
2905
2914
|
...(userConfig.define ?? {}),
|
|
2906
2915
|
...(options.define ?? {}),
|
|
2907
2916
|
__AGENT_NATIVE_BUILD_ID__: JSON.stringify(buildId),
|
|
2917
|
+
__AGENT_NATIVE_PACKAGE_VERSIONS__: JSON.stringify(packageVersions),
|
|
2908
2918
|
__AGENT_NATIVE_CLIENT_COMPATIBILITY_VERSION__: JSON.stringify(options.clientCompatibilityVersion?.trim() || ""),
|
|
2909
2919
|
__AGENT_NATIVE_APP_CONFIG__: JSON.stringify(resolvedAppConfig),
|
|
2910
2920
|
__AGENT_NATIVE_BUILD_GA_MEASUREMENT_ID__: JSON.stringify(process.env.GA_MEASUREMENT_ID?.trim() || ""),
|
|
@@ -2913,6 +2923,11 @@ function createAgentNativeConfig(options = {}, command, userConfig = {}, mode =
|
|
|
2913
2923
|
// netlify.toml environment is available to the build but not injected
|
|
2914
2924
|
// into deployed Functions, so embed the decision in the server bundle.
|
|
2915
2925
|
"process.env.AGENT_NATIVE_RELEASE_MIGRATIONS": JSON.stringify(process.env.AGENT_NATIVE_RELEASE_MIGRATIONS?.trim() || ""),
|
|
2926
|
+
// Recurring jobs are turned off (and their platform scheduled trigger
|
|
2927
|
+
// omitted) by the BUILD environment, which a deployed serverless runtime
|
|
2928
|
+
// never sees. Embed the decision so the Automations page reports what
|
|
2929
|
+
// will actually fire instead of inferring it from runtime-only markers.
|
|
2930
|
+
[`process.env.${RECURRING_JOBS_BUILD_MARKER_ENV_VAR}`]: JSON.stringify(resolveRecurringJobsBuildMarker(process.env)),
|
|
2916
2931
|
...(resolvedAppConfig.deployment?.environment
|
|
2917
2932
|
? {
|
|
2918
2933
|
"process.env.AGENT_NATIVE_DEPLOYMENT_ENVIRONMENT": JSON.stringify(resolvedAppConfig.deployment.environment),
|
|
@@ -3129,14 +3144,10 @@ function createAgentNativeConfigPlugin(options) {
|
|
|
3129
3144
|
name: "agent-native-config",
|
|
3130
3145
|
enforce: "pre",
|
|
3131
3146
|
async config(config, env) {
|
|
3132
|
-
const context = createAgentNativeConfigContext(env.command, env.mode);
|
|
3133
3147
|
const workspaceConfig = await loadWorkspaceAgentNativeConfigFile(process.cwd());
|
|
3134
3148
|
const projectConfig = options.agentNativeConfig ??
|
|
3135
3149
|
(await loadAgentNativeConfigFile(process.cwd()));
|
|
3136
|
-
|
|
3137
|
-
? resolveAgentNativeConfig(workspaceConfig, context)
|
|
3138
|
-
: {}, projectConfig ? resolveAgentNativeConfig(projectConfig, context) : {});
|
|
3139
|
-
return createAgentNativeConfig(options, env.command, config, env.mode, resolvedConfig);
|
|
3150
|
+
return createAgentNativeConfig(options, env.command, config, env.mode, projectConfig, workspaceConfig);
|
|
3140
3151
|
},
|
|
3141
3152
|
};
|
|
3142
3153
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function resolveAgentNativePackageVersions(cwd: string): Record<string, string>;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import { createRequire } from "module";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
const AGENT_NATIVE_PACKAGE_PREFIX = "@agent-native/";
|
|
6
|
+
function readPackageManifest(manifestPath) {
|
|
7
|
+
try {
|
|
8
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
9
|
+
return manifest && typeof manifest === "object"
|
|
10
|
+
? manifest
|
|
11
|
+
: null;
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
// coercion-ok: missing or malformed manifests are typed absence from the optional version inventory.
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function dependencyNames(manifest, includeDevDependencies = false) {
|
|
19
|
+
if (!manifest) {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
return [
|
|
23
|
+
...Object.keys(manifest.dependencies ?? {}),
|
|
24
|
+
...Object.keys(manifest.optionalDependencies ?? {}),
|
|
25
|
+
...Object.keys(manifest.peerDependencies ?? {}),
|
|
26
|
+
...(includeDevDependencies
|
|
27
|
+
? Object.keys(manifest.devDependencies ?? {})
|
|
28
|
+
: []),
|
|
29
|
+
];
|
|
30
|
+
}
|
|
31
|
+
function resolvePackageManifest(packageName, resolutionBase) {
|
|
32
|
+
let entryPath;
|
|
33
|
+
const packageRequire = createRequire(path.join(resolutionBase, "package.json"));
|
|
34
|
+
try {
|
|
35
|
+
entryPath = packageRequire.resolve(packageName);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
if (packageName !== "@agent-native/core") {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const coreManifestPath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../package.json");
|
|
42
|
+
const coreManifest = readPackageManifest(coreManifestPath);
|
|
43
|
+
return coreManifest?.name === packageName
|
|
44
|
+
? { manifest: coreManifest, manifestPath: coreManifestPath }
|
|
45
|
+
: null;
|
|
46
|
+
}
|
|
47
|
+
let directory = path.dirname(entryPath);
|
|
48
|
+
for (let depth = 0; depth < 20; depth += 1) {
|
|
49
|
+
const manifestPath = path.join(directory, "package.json");
|
|
50
|
+
const manifest = readPackageManifest(manifestPath);
|
|
51
|
+
if (manifest?.name === packageName) {
|
|
52
|
+
return { manifest, manifestPath };
|
|
53
|
+
}
|
|
54
|
+
const parent = path.dirname(directory);
|
|
55
|
+
if (parent === directory) {
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
directory = parent;
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
export function resolveAgentNativePackageVersions(cwd) {
|
|
63
|
+
const appManifest = readPackageManifest(path.join(cwd, "package.json"));
|
|
64
|
+
const packageNames = new Set([
|
|
65
|
+
"@agent-native/core",
|
|
66
|
+
...dependencyNames(appManifest, true).filter((name) => name.startsWith(AGENT_NATIVE_PACKAGE_PREFIX)),
|
|
67
|
+
]);
|
|
68
|
+
const resolvedVersions = new Map();
|
|
69
|
+
const queuedPackages = [...packageNames].map((packageName) => ({
|
|
70
|
+
packageName,
|
|
71
|
+
resolutionBase: cwd,
|
|
72
|
+
}));
|
|
73
|
+
while (queuedPackages.length > 0) {
|
|
74
|
+
const queuedPackage = queuedPackages.shift();
|
|
75
|
+
if (!queuedPackage)
|
|
76
|
+
continue;
|
|
77
|
+
const resolvedPackage = resolvePackageManifest(queuedPackage.packageName, queuedPackage.resolutionBase);
|
|
78
|
+
if (!resolvedPackage) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const { manifest } = resolvedPackage;
|
|
82
|
+
if (typeof manifest.version === "string" && manifest.version.trim()) {
|
|
83
|
+
resolvedVersions.set(queuedPackage.packageName, manifest.version.trim());
|
|
84
|
+
}
|
|
85
|
+
for (const dependencyName of dependencyNames(manifest)) {
|
|
86
|
+
if (dependencyName.startsWith(AGENT_NATIVE_PACKAGE_PREFIX) &&
|
|
87
|
+
!packageNames.has(dependencyName)) {
|
|
88
|
+
packageNames.add(dependencyName);
|
|
89
|
+
queuedPackages.push({
|
|
90
|
+
packageName: dependencyName,
|
|
91
|
+
resolutionBase: path.dirname(resolvedPackage.manifestPath),
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return Object.fromEntries([...resolvedVersions.entries()].sort(([left], [right]) => left.localeCompare(right)));
|
|
97
|
+
}
|