@agent-native/core 0.205.0 → 0.206.0-nightly-20261009011246

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.
Files changed (115) hide show
  1. package/dist/a2a/client.d.ts +2 -2
  2. package/dist/agent/engine/anthropic-engine.d.ts +1 -1
  3. package/dist/agent/engine/builder-engine.d.ts +1 -1
  4. package/dist/agent/engine/builder-engine.js +23 -8
  5. package/dist/agent/engine/error-telemetry.d.ts +5 -0
  6. package/dist/agent/engine/error-telemetry.js +41 -0
  7. package/dist/agent/engine/registry.d.ts +1 -6
  8. package/dist/agent/engine/registry.js +2 -31
  9. package/dist/agent/model-config.d.ts +26 -14
  10. package/dist/agent/model-config.js +131 -8
  11. package/dist/agent/model-version.d.ts +19 -0
  12. package/dist/agent/model-version.js +153 -0
  13. package/dist/agent/production-agent.d.ts +1 -0
  14. package/dist/agent/production-agent.js +24 -6
  15. package/dist/agent/provider-model-selection.js +6 -4
  16. package/dist/agent/run-manager.js +5 -11
  17. package/dist/agent/thread-data-builder.js +14 -6
  18. package/dist/authorization/check-action.js +8 -4
  19. package/dist/chat-threads/store.js +22 -9
  20. package/dist/client/analytics.d.ts +1 -0
  21. package/dist/client/analytics.js +10 -2
  22. package/dist/client/chat/runtime.js +18 -0
  23. package/dist/client/chat-model-groups.d.ts +3 -0
  24. package/dist/client/error-format.js +10 -7
  25. package/dist/client/onboarding/use-onboarding.d.ts +12 -0
  26. package/dist/client/onboarding/use-onboarding.js +491 -4
  27. package/dist/client/session-replay-privacy.d.ts +8 -0
  28. package/dist/client/session-replay-privacy.js +8 -0
  29. package/dist/client/session-replay.d.ts +1 -0
  30. package/dist/client/session-replay.js +18 -9
  31. package/dist/client/sse-event-processor.js +10 -6
  32. package/dist/client/use-chat-models.d.ts +5 -0
  33. package/dist/client/use-chat-models.js +51 -5
  34. package/dist/client/use-session.d.ts +8 -1
  35. package/dist/client/use-session.js +20 -1
  36. package/dist/collab/struct-routes.d.ts +1 -1
  37. package/dist/deploy/build.js +353 -3
  38. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  39. package/dist/jobs/backfill-run-history-ownership.d.ts +12 -0
  40. package/dist/jobs/backfill-run-history-ownership.js +87 -0
  41. package/dist/jobs/background-automation-runner.js +3 -9
  42. package/dist/jobs/remote-execution.js +3 -9
  43. package/dist/jobs/run-history-ownership.d.ts +5 -0
  44. package/dist/jobs/run-history-ownership.js +16 -0
  45. package/dist/jobs/run-now.js +2 -3
  46. package/dist/localization/agent-resources-messages.d.ts +3 -0
  47. package/dist/localization/agent-resources-messages.js +33 -0
  48. package/dist/mcp/actions/create-org-service-token.js +5 -7
  49. package/dist/mcp/build-server.d.ts +23 -18
  50. package/dist/mcp/build-server.js +220 -212
  51. package/dist/mcp/connect-route.d.ts +11 -2
  52. package/dist/mcp/connect-route.js +34 -24
  53. package/dist/mcp/connect-store.d.ts +9 -13
  54. package/dist/mcp/connect-store.js +11 -24
  55. package/dist/mcp/credential-membership.js +17 -6
  56. package/dist/mcp/oauth-route.d.ts +11 -1
  57. package/dist/mcp/oauth-route.js +28 -6
  58. package/dist/mcp/oauth-token.d.ts +12 -2
  59. package/dist/mcp/oauth-token.js +15 -4
  60. package/dist/mcp/server.js +9 -5
  61. package/dist/notifications/routes.d.ts +2 -2
  62. package/dist/observability/posthog-ai.d.ts +1 -0
  63. package/dist/observability/posthog-ai.js +20 -8
  64. package/dist/observability/routes.d.ts +6 -6
  65. package/dist/observability/traces.js +61 -39
  66. package/dist/org/app-roles.d.ts +8 -1
  67. package/dist/org/app-roles.js +29 -9
  68. package/dist/org/context.js +24 -8
  69. package/dist/org/index.d.ts +2 -2
  70. package/dist/org/workspace-app-identity.d.ts +1 -0
  71. package/dist/org/workspace-app-identity.js +25 -0
  72. package/dist/progress/routes.d.ts +1 -1
  73. package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
  74. package/dist/provider-api/actions/provider-api.d.ts +3 -3
  75. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  76. package/dist/scripts/agent-engines/list-agent-engines.js +1 -0
  77. package/dist/server/action-routes.js +8 -1
  78. package/dist/server/agent-chat-plugin.js +1 -0
  79. package/dist/server/agent-engine-default-model-route.d.ts +1 -1
  80. package/dist/server/auth.js +33 -17
  81. package/dist/server/bearer-credential-refusal.d.ts +23 -0
  82. package/dist/server/bearer-credential-refusal.js +67 -0
  83. package/dist/server/better-auth-instance.js +13 -6
  84. package/dist/server/builder-browser.d.ts +2 -0
  85. package/dist/server/builder-browser.js +16 -3
  86. package/dist/server/capture-error.d.ts +1 -0
  87. package/dist/server/capture-error.js +28 -4
  88. package/dist/server/complete-text.js +16 -3
  89. package/dist/server/core-routes-plugin.js +2 -0
  90. package/dist/server/dev-action-bridge.js +7 -1
  91. package/dist/server/google-oauth.js +6 -3
  92. package/dist/server/index.d.ts +1 -1
  93. package/dist/server/index.js +1 -1
  94. package/dist/server/realtime-token.d.ts +1 -1
  95. package/dist/server/recap-image-route.js +4 -0
  96. package/dist/server/request-context.d.ts +16 -0
  97. package/dist/server/request-context.js +17 -0
  98. package/dist/shared/agent-chat-context.d.ts +1 -0
  99. package/dist/shared/agent-chat-context.js +26 -0
  100. package/dist/shared/index.d.ts +1 -1
  101. package/dist/shared/index.js +1 -1
  102. package/dist/shared/reasoning-effort.js +10 -1
  103. package/dist/shared/ssr-session-bootstrap.d.ts +7 -0
  104. package/dist/shared/ssr-session-bootstrap.js +21 -0
  105. package/dist/sharing/access.js +86 -5
  106. package/dist/templates/builder-code-starter/server/routes/index.get.ts +2 -0
  107. package/dist/triggers/routes.js +2 -1
  108. package/docs/content/automation-connectors.mdx +5 -3
  109. package/docs/content/automations.mdx +78 -49
  110. package/docs/content/observability.mdx +16 -5
  111. package/docs/content/organizations-teams-permissions.mdx +44 -2
  112. package/docs/content/recurring-jobs.mdx +4 -8
  113. package/docs/content/template-forms.mdx +6 -0
  114. package/package.json +5 -4
  115. package/src/templates/builder-code-starter/server/routes/index.get.ts +2 -0
@@ -504,17 +504,21 @@ async function readChunkWithProgressTimeout(reader, lastMeaningfulEventAt, noPro
504
504
  function isAutoRecoverableError(ev, errMsg) {
505
505
  const code = String(ev.errorCode ?? "").toLowerCase();
506
506
  const msg = errMsg.toLowerCase();
507
- // An explicit `recoverable: false` outranks EVERY inference below — the code
508
- // list as well as the message sniff — matching the server's own precedence in
509
- // `isRecoverableContinuationError`. The repeat guards stop a turn with a
507
+ // Explicit terminal classifications outrank EVERY inference below — the
508
+ // code list as well as the message sniff — matching the server's precedence
509
+ // in `isRecoverableContinuationError`. The repeat guards stop a turn with a
510
510
  // message that names the looping tool, so a stop on
511
511
  // `list-workspace-connections` matched the "connection" sniff and
512
512
  // auto-continued the very loop it was emitted to break; the background
513
513
  // no-progress breaker stops one while PRESERVING the underlying transient
514
514
  // code (so the failure stays diagnosable), so reading the code instead of the
515
515
  // flag re-POSTs the exact chain the server just refused to continue.
516
- if (ev.recoverable === false)
516
+ if (ev.providerRetryable === false || ev.recoverable === false)
517
517
  return false;
518
+ // A recoverable server timeout is a continuation boundary, even though its
519
+ // visitor-facing message sounds terminal.
520
+ if (code === "run_timeout" && ev.recoverable === true)
521
+ return true;
518
522
  // These messages can carry `recoverable: true` for banner rendering, but
519
523
  // repeating the request would retry the same rejected credential or a run
520
524
  // the user already stopped.
@@ -539,6 +543,7 @@ function isAutoRecoverableError(ev, errMsg) {
539
543
  code === "gateway_not_enabled" ||
540
544
  code === "missing_api_key" ||
541
545
  code === "missing_credentials" ||
546
+ code === "invalid_request" ||
542
547
  code === "invalid_request_error" ||
543
548
  code === "request_too_large" ||
544
549
  code === "not_found_error" ||
@@ -1619,8 +1624,7 @@ export function processEvent(ev, content, toolCallCounter, tabId, state, context
1619
1624
  }
1620
1625
  if (ev.type === "error") {
1621
1626
  const errMsg = ev.error ?? "Unknown error";
1622
- if ((ev.errorCode === "run_timeout" && ev.recoverable) ||
1623
- isAutoRecoverableError(ev, errMsg)) {
1627
+ if (isAutoRecoverableError(ev, errMsg)) {
1624
1628
  const normalized = normalizeChatError(errMsg, ev.errorCode);
1625
1629
  return {
1626
1630
  action: "auto_continue",
@@ -1,4 +1,5 @@
1
1
  import { DEFAULT_MODEL } from "../agent/default-model.js";
2
+ import { type ModelEngineConfig } from "../agent/model-version.js";
2
3
  export { DEFAULT_MODEL };
3
4
  import { type ReasoningEffort } from "../shared/reasoning-effort.js";
4
5
  import { type EngineModelGroup } from "./chat-model-groups.js";
@@ -36,6 +37,10 @@ export interface PersistedModelSelection {
36
37
  export type ChatModelCatalogLoad = {
37
38
  state: "available";
38
39
  groups: EngineModelGroup[];
40
+ /** Runtime normalization config for the engines represented in groups. */
41
+ modelEngines: Readonly<Record<string, ModelEngineConfig>>;
42
+ /** The server-selected engine, independent of a persisted chat choice. */
43
+ currentModelEngine: ModelEngineConfig | null;
39
44
  /** The server's current model, or `DEFAULT_MODEL` when it names none. */
40
45
  defaultModel: string;
41
46
  /**
@@ -1,6 +1,6 @@
1
1
  import { useCallback, useEffect, useRef, useState } from "react";
2
2
  import { DEFAULT_MODEL } from "../agent/default-model.js";
3
- import { upgradeModelToLatestSupportedVersion } from "../agent/model-version.js";
3
+ import { upgradeModelForProvider, } from "../agent/model-version.js";
4
4
  export { DEFAULT_MODEL };
5
5
  import { DEFAULT_REASONING_EFFORT, getReasoningEffortOptionsForModel, resolveReasoningEffortSelection, } from "../shared/reasoning-effort.js";
6
6
  import { fetchOllamaModels } from "./agent-engine-key.js";
@@ -54,6 +54,7 @@ export async function loadChatModelCatalog() {
54
54
  const builderConnected = builderResult.value?.configured === true;
55
55
  const currentEngineName = enginesData.current?.engine;
56
56
  const currentModel = enginesData.current?.model;
57
+ const currentEngine = enginesData.engines.find((engine) => engine.name === currentEngineName);
57
58
  const build = (engines) => buildChatModelGroups({
58
59
  engines,
59
60
  configuredKeys,
@@ -61,10 +62,55 @@ export async function loadChatModelCatalog() {
61
62
  currentEngineName,
62
63
  currentModel,
63
64
  });
65
+ const groups = build(enginesData.engines);
66
+ const modelEngines = Object.fromEntries(enginesData.engines.flatMap((engine) => {
67
+ if (!engine.defaultModel)
68
+ return [];
69
+ const selectableModels = groups
70
+ .filter((group) => group.engine === engine.name)
71
+ .flatMap((group) => group.models);
72
+ const supportedModels = engine.runtimeSupportedModels ??
73
+ engine.supportedModels ??
74
+ selectableModels;
75
+ if (supportedModels.length === 0)
76
+ return [];
77
+ return [
78
+ [
79
+ engine.name,
80
+ {
81
+ name: engine.name,
82
+ label: engine.label,
83
+ defaultModel: engine.defaultModel,
84
+ supportedModels,
85
+ selectableModels,
86
+ ...(engine.acceptsCustomModels
87
+ ? { acceptsCustomModels: true }
88
+ : {}),
89
+ ...(engine.preserveCustomModels
90
+ ? { preserveCustomModels: true }
91
+ : {}),
92
+ },
93
+ ],
94
+ ];
95
+ }));
96
+ const currentModelEngine = currentEngineName
97
+ ? (modelEngines[currentEngineName] ?? null)
98
+ : null;
99
+ const currentEngineModels = groups
100
+ .filter((group) => group.engine === currentEngineName)
101
+ .flatMap((group) => group.models);
102
+ const defaultModelCandidates = currentEngine?.runtimeSupportedModels ?? currentEngineModels;
103
+ const defaultModel = currentModel
104
+ ? currentEngine?.preserveCustomModels
105
+ ? currentModel
106
+ : (upgradeModelForProvider(currentModel, defaultModelCandidates, currentEngineName ?? "") ?? currentModel)
107
+ : DEFAULT_MODEL;
64
108
  return {
65
109
  state: "available",
66
- groups: build(enginesData.engines),
67
- defaultModel: currentModel ?? DEFAULT_MODEL,
110
+ groups,
111
+ modelEngines,
112
+ currentModelEngine,
113
+ defaultModel,
68
114
  loadLiveGroups: async () => {
69
115
  // Gated on Ollama actually being the current engine (not merely present
70
116
  // in the catalog, which it always is): every app registers it by
@@ -300,14 +346,14 @@ export function useChatModels({ storageKey = DEFAULT_STORAGE_KEY, enabled = true
300
346
  const model = group.preserveCustomModels &&
301
347
  selection.selectedEngine === group.engine
302
348
  ? selection.selectedModel
303
- : upgradeModelToLatestSupportedVersion(selection.selectedModel, group.models);
349
+ : upgradeModelForProvider(selection.selectedModel, group.models, group.engine);
304
350
  return model ? [{ group, model }] : [];
305
351
  });
306
352
  const upgradeCandidateKeys = new Set(upgradeCandidates.map(({ group, model }) => JSON.stringify([group.engine, model])));
307
353
  const upgradedSelection = upgradeCandidateKeys.size === 1 ? upgradeCandidates[0] : undefined;
308
354
  const selectedGroup = exactSelectedGroup ?? upgradedSelection?.group;
309
355
  if (selectedGroup) {
310
- const selectedModel = upgradeModelToLatestSupportedVersion(selection.selectedModel, selectedGroup.models) ?? selection.selectedModel;
356
+ const selectedModel = upgradeModelForProvider(selection.selectedModel, selectedGroup.models, selectedGroup.engine) ?? selection.selectedModel;
311
357
  const nextSelection = {
312
358
  ...selection,
313
359
  selectedModel,
@@ -1,6 +1,6 @@
1
1
  import type { AuthSession } from "../server/auth.js";
2
2
  export type { AuthSession };
3
- export { isSessionNavigationPending } from "../shared/ssr-session-bootstrap.js";
3
+ export { hasSessionHint, isSessionNavigationPending, } from "../shared/ssr-session-bootstrap.js";
4
4
  /**
5
5
  * What the session endpoint said that the page acted on: a signed-out body,
6
6
  * an HTTP 401, or a signed-in answer. Recorded with every session-driven
@@ -25,6 +25,13 @@ interface UseSessionResult {
25
25
  }
26
26
  export declare function notifySessionInvalidated(): void;
27
27
  export declare function isSigningOut(): boolean;
28
+ /**
29
+ * Whether the session this tab holds is the answer to the page load's first
30
+ * session read. A request the load sent before the session was known belongs
31
+ * to the account this session names only while this holds: once a retry or an
32
+ * invalidation answers instead, another tab may have changed the cookies.
33
+ */
34
+ export declare function isSessionFromFirstRead(): boolean;
28
35
  /**
29
36
  * Re-resolve the session because an authenticated request came back 401.
30
37
  *
@@ -4,7 +4,7 @@ import { setSentryUser, trackEvent, trackSessionStatus } from "./analytics.js";
4
4
  import { agentNativeApiDisabledReason } from "./api-surface.js";
5
5
  import { expireClientStatusResult, fetchAuthSessionStatus, invalidateClientStatusRequest, SESSION_RESULT_LIFETIME_MS, } from "./client-status-requests.js";
6
6
  import { getFrameOrigin, getFramePostMessageTargetOrigin } from "./frame.js";
7
- export { isSessionNavigationPending } from "../shared/ssr-session-bootstrap.js";
7
+ export { hasSessionHint, isSessionNavigationPending, } from "../shared/ssr-session-bootstrap.js";
8
8
  let cachedEvidence;
9
9
  let lastResolution;
10
10
  /**
@@ -47,6 +47,11 @@ let sessionRequest;
47
47
  let trackedSessionIdentity;
48
48
  let trackedSessionAuthUserId;
49
49
  let sessionGeneration = 0;
50
+ // The page load's own session read is the only one sent with the cookies a
51
+ // request made before the session was known also carried. A retry or a reset
52
+ // replaces it for the life of the document.
53
+ let firstSessionReadUnsent = true;
54
+ let cachedSessionFromFirstRead = false;
50
55
  let sessionInvalidationListenersInstalled = false;
51
56
  let staleSessionRecheck;
52
57
  let signingOut = false;
@@ -130,6 +135,8 @@ function notifyParentAuthState(status) {
130
135
  }
131
136
  function resetSessionCache() {
132
137
  sessionGeneration += 1;
138
+ firstSessionReadUnsent = false;
139
+ cachedSessionFromFirstRead = false;
133
140
  cachedSession = undefined;
134
141
  cachedSessionAt = 0;
135
142
  cachedEvidence = undefined;
@@ -223,6 +230,15 @@ export function notifySessionInvalidated() {
223
230
  export function isSigningOut() {
224
231
  return signingOut;
225
232
  }
233
+ /**
234
+ * Whether the session this tab holds is the answer to the page load's first
235
+ * session read. A request the load sent before the session was known belongs
236
+ * to the account this session names only while this holds: once a retry or an
237
+ * invalidation answers instead, another tab may have changed the cookies.
238
+ */
239
+ export function isSessionFromFirstRead() {
240
+ return cachedSession !== undefined && cachedSessionFromFirstRead;
241
+ }
226
242
  const UNAUTHORIZED_RECHECK_MIN_INTERVAL_MS = 5_000;
227
243
  let lastUnauthorizedRecheckAt = 0;
228
244
  /**
@@ -282,6 +298,8 @@ function fetchSharedSession() {
282
298
  if (sessionRequest)
283
299
  return sessionRequest;
284
300
  const requestGeneration = sessionGeneration;
301
+ const firstRead = firstSessionReadUnsent;
302
+ firstSessionReadUnsent = false;
285
303
  let request;
286
304
  const requestResult = (async () => {
287
305
  try {
@@ -306,6 +324,7 @@ function fetchSharedSession() {
306
324
  : data;
307
325
  cachedSession = session;
308
326
  cachedSessionAt = Date.now();
327
+ cachedSessionFromFirstRead = firstRead;
309
328
  cachedEvidence = session
310
329
  ? "signed_in"
311
330
  : result.state === "unavailable"
@@ -1,6 +1,6 @@
1
1
  export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
2
- error: string;
3
2
  ok?: undefined;
3
+ error: string;
4
4
  } | {
5
5
  error?: undefined;
6
6
  ok: boolean;
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { execFileSync } from "child_process";
3
3
  import fs from "fs";
4
- import { createRequire } from "module";
4
+ import { createRequire, isBuiltin } from "module";
5
5
  import path from "path";
6
6
  import { fileURLToPath } from "url";
7
7
  import { runInNewContext } from "vm";
@@ -3853,6 +3853,342 @@ function copyInstalledFfmpegStaticPackage(serverDir) {
3853
3853
  copyDir(src, path.join(serverDir, "node_modules", FFMPEG_STATIC_PACKAGE_NAME));
3854
3854
  console.log("[deploy] Copied ffmpeg-static into the server bundle for media transcription fallback.");
3855
3855
  }
3856
+ function exclusiveBrowserInstallerPackages(functionDir) {
3857
+ const nodeModulesDir = path.join(functionDir, "node_modules");
3858
+ if (!fs.existsSync(path.join(nodeModulesDir, "@puppeteer/browsers")))
3859
+ return new Set();
3860
+ const functionRoot = fs.realpathSync(functionDir);
3861
+ const isWithinFunction = (directory) => {
3862
+ const relative = path.relative(functionRoot, directory);
3863
+ return (relative === "" ||
3864
+ (relative !== ".." &&
3865
+ !relative.startsWith(`..${path.sep}`) &&
3866
+ !path.isAbsolute(relative)));
3867
+ };
3868
+ const packageSegments = (name) => {
3869
+ const segments = name.split("/");
3870
+ if (!name ||
3871
+ name.includes("\\") ||
3872
+ segments.some((segment) => !segment || segment === "." || segment === "..") ||
3873
+ segments.length > 2 ||
3874
+ (segments.length === 2 && !segments[0].startsWith("@")) ||
3875
+ (segments.length === 1 && segments[0].startsWith("@")))
3876
+ return null;
3877
+ return segments;
3878
+ };
3879
+ const resolvePackageDirectory = (segments, fromPackageDir, resolvedPackageDir) => {
3880
+ if (resolvedPackageDir) {
3881
+ const resolved = fs.realpathSync(resolvedPackageDir);
3882
+ if (!isWithinFunction(resolved))
3883
+ return null;
3884
+ return fs.statSync(resolved).isDirectory() ? resolved : null;
3885
+ }
3886
+ let current = fromPackageDir ?? functionRoot;
3887
+ if (!isWithinFunction(current))
3888
+ return null;
3889
+ while (isWithinFunction(current)) {
3890
+ if (current === functionRoot ||
3891
+ path.basename(current) !== "node_modules") {
3892
+ const candidate = path.join(current, "node_modules", ...segments);
3893
+ if (fs.existsSync(candidate)) {
3894
+ const resolved = fs.realpathSync(candidate);
3895
+ // A nearer out-of-bound install must not fall through to another version.
3896
+ if (!isWithinFunction(resolved))
3897
+ return null;
3898
+ if (fs.statSync(resolved).isDirectory())
3899
+ return resolved;
3900
+ return null;
3901
+ }
3902
+ }
3903
+ if (current === functionRoot)
3904
+ break;
3905
+ const parent = path.dirname(current);
3906
+ if (parent === current)
3907
+ break;
3908
+ current = parent;
3909
+ }
3910
+ return null;
3911
+ };
3912
+ const candidateReferencesByFile = new Map();
3913
+ const packageReferencesByDirectory = new Map();
3914
+ const isEnoent = (error) => error !== null &&
3915
+ typeof error === "object" &&
3916
+ "code" in error &&
3917
+ error.code === "ENOENT";
3918
+ const isMissingDanglingSymlink = (fileStats, error) => fileStats.isSymbolicLink() && isEnoent(error);
3919
+ const resolveScannablePath = (filePath) => {
3920
+ const fileStats = fs.lstatSync(filePath);
3921
+ let resolvedPath;
3922
+ try {
3923
+ resolvedPath = fs.realpathSync(filePath);
3924
+ }
3925
+ catch (error) {
3926
+ if (isMissingDanglingSymlink(fileStats, error))
3927
+ return null;
3928
+ throw error;
3929
+ }
3930
+ if (!isWithinFunction(resolvedPath))
3931
+ return null;
3932
+ let stats;
3933
+ try {
3934
+ stats = fs.statSync(filePath);
3935
+ }
3936
+ catch (error) {
3937
+ if (isMissingDanglingSymlink(fileStats, error))
3938
+ return null;
3939
+ throw error;
3940
+ }
3941
+ return { path: resolvedPath, stats };
3942
+ };
3943
+ const collect = (roots, scanPackageReferences) => {
3944
+ const collected = new Set();
3945
+ const visited = new Set();
3946
+ const visit = (request, parentPackageDir) => {
3947
+ const name = typeof request === "string" ? request : request.name;
3948
+ const fromPackageDir = typeof request === "string" ? parentPackageDir : request.fromPackageDir;
3949
+ const segments = packageSegments(name);
3950
+ if (!segments)
3951
+ return;
3952
+ if (scanPackageReferences &&
3953
+ SERVERLESS_FUNCTION_PACKAGE_DENYLIST.has(name))
3954
+ return;
3955
+ collected.add(name);
3956
+ const packageDir = resolvePackageDirectory(segments, fromPackageDir, typeof request === "string" ? undefined : request.resolvedPackageDir);
3957
+ if (!packageDir)
3958
+ return;
3959
+ const manifest = readPackageManifest(packageDir);
3960
+ const version = typeof manifest?.version === "string" ? manifest.version : "";
3961
+ const identity = `${packageDir}\0${version}`;
3962
+ if (visited.has(identity))
3963
+ return;
3964
+ visited.add(identity);
3965
+ if (scanPackageReferences) {
3966
+ for (const reference of scanPackageReferences(packageDir))
3967
+ visit(reference);
3968
+ }
3969
+ for (const field of [
3970
+ ...RUNTIME_PACKAGE_DEPENDENCY_FIELDS,
3971
+ "peerDependencies",
3972
+ ]) {
3973
+ const dependencies = manifest?.[field];
3974
+ if (!dependencies ||
3975
+ typeof dependencies !== "object" ||
3976
+ Array.isArray(dependencies))
3977
+ continue;
3978
+ for (const dependency of Object.keys(dependencies))
3979
+ visit(dependency, packageDir);
3980
+ }
3981
+ };
3982
+ for (const root of roots)
3983
+ visit(root);
3984
+ return collected;
3985
+ };
3986
+ const candidates = collect([
3987
+ "puppeteer",
3988
+ "puppeteer-core",
3989
+ "chromium-bidi",
3990
+ "@puppeteer/browsers",
3991
+ ]);
3992
+ const findResolvedCandidate = (specifier, fromPackageDir) => {
3993
+ if (!specifier.startsWith("./") &&
3994
+ !specifier.startsWith("../") &&
3995
+ !path.isAbsolute(specifier))
3996
+ return;
3997
+ const target = path.resolve(fromPackageDir, specifier);
3998
+ if (!isWithinFunction(target))
3999
+ return;
4000
+ let match;
4001
+ for (const name of candidates) {
4002
+ if (SERVERLESS_FUNCTION_PACKAGE_DENYLIST.has(name))
4003
+ continue;
4004
+ const marker = `${path.sep}node_modules${path.sep}${name
4005
+ .split("/")
4006
+ .join(path.sep)}`;
4007
+ const markerStart = target.lastIndexOf(marker);
4008
+ const suffix = target[markerStart + marker.length];
4009
+ if (markerStart < 0 || (suffix !== undefined && suffix !== path.sep))
4010
+ continue;
4011
+ const candidateDir = target.slice(0, markerStart + marker.length);
4012
+ if (!fs.existsSync(candidateDir))
4013
+ continue;
4014
+ const resolvedPackageDir = fs.realpathSync(candidateDir);
4015
+ if (!isWithinFunction(resolvedPackageDir) ||
4016
+ !fs.statSync(resolvedPackageDir).isDirectory())
4017
+ continue;
4018
+ if (!match || markerStart > match.markerStart)
4019
+ match = { name, resolvedPackageDir, markerStart };
4020
+ }
4021
+ return (match && {
4022
+ name: match.name,
4023
+ resolvedPackageDir: match.resolvedPackageDir,
4024
+ });
4025
+ };
4026
+ const isNonPackageSpecifier = (specifier) => path.isAbsolute(specifier) ||
4027
+ specifier.startsWith(".") ||
4028
+ specifier.startsWith("#") ||
4029
+ /^[A-Za-z][A-Za-z\d+.-]*:/.test(specifier);
4030
+ const findResolvedPackage = (specifier, fromPackageDir) => {
4031
+ const relativeCandidate = findResolvedCandidate(specifier, fromPackageDir);
4032
+ if (relativeCandidate)
4033
+ return relativeCandidate;
4034
+ if (isNonPackageSpecifier(specifier))
4035
+ return;
4036
+ const specifierSegments = specifier.split("/");
4037
+ const name = specifierSegments[0]?.startsWith("@")
4038
+ ? specifierSegments.slice(0, 2).join("/")
4039
+ : specifierSegments[0];
4040
+ const segments = name && packageSegments(name);
4041
+ if (!name ||
4042
+ !segments ||
4043
+ isBuiltin(name) ||
4044
+ SERVERLESS_FUNCTION_PACKAGE_DENYLIST.has(name))
4045
+ return;
4046
+ const resolvedPackageDir = resolvePackageDirectory(segments, fromPackageDir);
4047
+ return resolvedPackageDir ? { name, resolvedPackageDir } : undefined;
4048
+ };
4049
+ const findPackageImportReferences = (packageDir, packageManifest = readPackageManifest(packageDir)) => {
4050
+ const imports = packageManifest?.imports;
4051
+ if (!imports || typeof imports !== "object" || Array.isArray(imports))
4052
+ return [];
4053
+ const targets = [];
4054
+ const collectTargets = (value) => {
4055
+ if (typeof value === "string") {
4056
+ targets.push(value);
4057
+ }
4058
+ else if (Array.isArray(value)) {
4059
+ for (const target of value)
4060
+ collectTargets(target);
4061
+ }
4062
+ else if (value && typeof value === "object") {
4063
+ for (const target of Object.values(value))
4064
+ collectTargets(target);
4065
+ }
4066
+ };
4067
+ for (const target of Object.values(imports))
4068
+ collectTargets(target);
4069
+ const references = new Map();
4070
+ for (const target of targets) {
4071
+ const resolved = findResolvedPackage(target, packageDir);
4072
+ if (resolved) {
4073
+ const reference = { ...resolved, fromPackageDir: packageDir };
4074
+ references.set(`${reference.name}\0${reference.resolvedPackageDir}`, reference);
4075
+ continue;
4076
+ }
4077
+ if (isNonPackageSpecifier(target))
4078
+ continue;
4079
+ const targetSegments = target.split("/");
4080
+ const packageName = targetSegments[0]?.startsWith("@")
4081
+ ? targetSegments.slice(0, 2).join("/")
4082
+ : targetSegments[0];
4083
+ if (packageName?.includes("*")) {
4084
+ for (const name of candidates) {
4085
+ if (SERVERLESS_FUNCTION_PACKAGE_DENYLIST.has(name))
4086
+ continue;
4087
+ const reference = { name, fromPackageDir: packageDir };
4088
+ references.set(`${name}\0`, reference);
4089
+ }
4090
+ continue;
4091
+ }
4092
+ }
4093
+ return [...references.values()];
4094
+ };
4095
+ const manifest = readPackageManifest(functionDir);
4096
+ // Nitro's manifest flattens transitive dependencies, so installer children
4097
+ // are not independent runtime roots merely because they appear there.
4098
+ const retained = new Set(PACKAGE_DEPENDENCY_FIELDS.flatMap((field) => Object.keys(manifest?.[field] ?? {})).filter((name) => !candidates.has(name) &&
4099
+ !SERVERLESS_FUNCTION_PACKAGE_DENYLIST.has(name)));
4100
+ const findCandidateReferences = (resolvedFilePath) => {
4101
+ const cached = candidateReferencesByFile.get(resolvedFilePath);
4102
+ if (cached)
4103
+ return cached;
4104
+ const fromPackageDir = path.dirname(resolvedFilePath);
4105
+ const source = fs.readFileSync(resolvedFilePath, "utf8");
4106
+ const references = new Map();
4107
+ const addReference = (reference) => {
4108
+ const identity = `${reference.name}\0${reference.fromPackageDir}\0${reference.resolvedPackageDir ?? ""}`;
4109
+ references.set(identity, reference);
4110
+ };
4111
+ const literalSpecifier = /\b(?:import|export)\s*(?:[^;'"`]*?\s*from\s*)?(['"`])([^'"`]+)\1|\b(?:import\s*\.\s*meta\s*\.\s*resolve|import|require(?:\s*\.\s*resolve)?)\s*\(\s*(['"`])([^'"`]+)\3/g;
4112
+ for (const match of source.matchAll(literalSpecifier)) {
4113
+ const specifier = match[2] ?? match[4];
4114
+ if (!specifier)
4115
+ continue;
4116
+ const resolved = findResolvedPackage(specifier, fromPackageDir);
4117
+ if (resolved)
4118
+ addReference({ ...resolved, fromPackageDir });
4119
+ }
4120
+ for (const name of candidates) {
4121
+ if (!SERVERLESS_FUNCTION_PACKAGE_DENYLIST.has(name) &&
4122
+ source.includes(name) &&
4123
+ (hasExternalSsrRuntimeReference(source, name) ||
4124
+ ["/", '"', "'", "`"].some((boundary) => source.includes(`node_modules/${name}${boundary}`))))
4125
+ addReference({ name, fromPackageDir });
4126
+ }
4127
+ const found = [...references.values()];
4128
+ candidateReferencesByFile.set(resolvedFilePath, found);
4129
+ return found;
4130
+ };
4131
+ const collectTreeReferences = (roots) => {
4132
+ const references = new Map();
4133
+ const visitedDirectories = new Set();
4134
+ const visitedFiles = new Set();
4135
+ const visit = (entryPath) => {
4136
+ const resolved = resolveScannablePath(entryPath);
4137
+ if (!resolved)
4138
+ return;
4139
+ if (resolved.stats.isDirectory()) {
4140
+ if (visitedDirectories.has(resolved.path))
4141
+ return;
4142
+ visitedDirectories.add(resolved.path);
4143
+ for (const entry of fs.readdirSync(resolved.path, {
4144
+ withFileTypes: true,
4145
+ })) {
4146
+ if (entry.isDirectory() ||
4147
+ entry.isSymbolicLink() ||
4148
+ (entry.isFile() && /\.(?:[cm]?js)$/.test(entry.name)))
4149
+ visit(path.join(resolved.path, entry.name));
4150
+ }
4151
+ return;
4152
+ }
4153
+ if (!resolved.stats.isFile() ||
4154
+ !/\.(?:[cm]?js)$/.test(path.basename(entryPath)) ||
4155
+ visitedFiles.has(resolved.path))
4156
+ return;
4157
+ visitedFiles.add(resolved.path);
4158
+ for (const reference of findCandidateReferences(resolved.path)) {
4159
+ const identity = `${reference.name}\0${reference.fromPackageDir}\0${reference.resolvedPackageDir ?? ""}`;
4160
+ references.set(identity, reference);
4161
+ }
4162
+ };
4163
+ for (const root of roots)
4164
+ visit(root);
4165
+ return [...references.values()];
4166
+ };
4167
+ const emittedRoots = fs
4168
+ .readdirSync(functionDir, { withFileTypes: true })
4169
+ .filter((entry) => entry.name !== "node_modules" &&
4170
+ (entry.isDirectory() ||
4171
+ entry.isSymbolicLink() ||
4172
+ (entry.isFile() && /\.(?:[cm]?js)$/.test(entry.name))))
4173
+ .map((entry) => path.join(functionDir, entry.name));
4174
+ const emittedReferences = collectTreeReferences(emittedRoots);
4175
+ const needed = collect([
4176
+ ...retained,
4177
+ ...emittedReferences,
4178
+ ...findPackageImportReferences(functionDir, manifest),
4179
+ ], (packageDir) => {
4180
+ const cached = packageReferencesByDirectory.get(packageDir);
4181
+ if (cached)
4182
+ return cached;
4183
+ const references = [
4184
+ ...collectTreeReferences([packageDir]),
4185
+ ...findPackageImportReferences(packageDir),
4186
+ ];
4187
+ packageReferencesByDirectory.set(packageDir, references);
4188
+ return references;
4189
+ });
4190
+ return new Set([...candidates].filter((name) => !needed.has(name)));
4191
+ }
3856
4192
  export function sanitizeServerlessFunctionPackageManifest(functionDir) {
3857
4193
  if (!functionDir || !fs.existsSync(functionDir))
3858
4194
  return;
@@ -3866,13 +4202,17 @@ export function sanitizeServerlessFunctionPackageManifest(functionDir) {
3866
4202
  catch {
3867
4203
  return;
3868
4204
  }
4205
+ const deniedPackages = new Set([
4206
+ ...SERVERLESS_FUNCTION_PACKAGE_DENYLIST,
4207
+ ...exclusiveBrowserInstallerPackages(functionDir),
4208
+ ]);
3869
4209
  let removed = 0;
3870
4210
  for (const field of PACKAGE_DEPENDENCY_FIELDS) {
3871
4211
  const deps = packageJson[field];
3872
4212
  if (!deps || typeof deps !== "object" || Array.isArray(deps))
3873
4213
  continue;
3874
4214
  const depRecord = deps;
3875
- for (const packageName of SERVERLESS_FUNCTION_PACKAGE_DENYLIST) {
4215
+ for (const packageName of deniedPackages) {
3876
4216
  if (Object.prototype.hasOwnProperty.call(depRecord, packageName)) {
3877
4217
  delete depRecord[packageName];
3878
4218
  removed++;
@@ -3883,7 +4223,7 @@ export function sanitizeServerlessFunctionPackageManifest(functionDir) {
3883
4223
  }
3884
4224
  }
3885
4225
  const nodeModulesDir = path.join(functionDir, "node_modules");
3886
- for (const packageName of SERVERLESS_FUNCTION_PACKAGE_DENYLIST) {
4226
+ for (const packageName of deniedPackages) {
3887
4227
  const packageDir = path.join(nodeModulesDir, ...packageName.split("/"));
3888
4228
  if (fs.existsSync(packageDir)) {
3889
4229
  fs.rmSync(packageDir, { recursive: true, force: true });
@@ -4029,6 +4369,12 @@ export async function runNitroBuildPipeline(opts) {
4029
4369
  patchReactRouterServerManifestInOutput(nitro.options.output.serverDir, trustedClientDirectory, resolvedClientDir);
4030
4370
  }
4031
4371
  }
4372
+ function removeServerSourceMaps(serverDir) {
4373
+ const sourceMaps = fs.globSync("**/*.map", { cwd: serverDir });
4374
+ for (const sourceMap of sourceMaps) {
4375
+ fs.rmSync(path.join(serverDir, sourceMap), { force: true });
4376
+ }
4377
+ }
4032
4378
  function resolveNitroClientDirectory(cwd, defaultClientDirectory) {
4033
4379
  const configured = process.env[PREBUILT_CLIENT_DIRECTORY_ENV]?.trim();
4034
4380
  const clientDirectory = configured
@@ -4357,6 +4703,10 @@ export default bundle;
4357
4703
  if (isCloudflareModulePreset(preset)) {
4358
4704
  bundleYjsRuntimeForServerlessOutput(nitro.options.output.serverDir, cwd);
4359
4705
  }
4706
+ if (sentryServerSourceMapPlugins.length > 0) {
4707
+ removeServerSourceMaps(nitro.options.output.serverDir);
4708
+ console.log("[deploy] Ensured Nitro server output is free of source maps before function packaging.");
4709
+ }
4360
4710
  if (preset === "netlify") {
4361
4711
  if (isDurableBackgroundEmitRequired()) {
4362
4712
  emitSingleTemplateNetlifyBackgroundFunction(cwd);
@@ -33,9 +33,9 @@ declare const _default: import("../../action.js").ActionDefinition<{
33
33
  idempotencyKey: string;
34
34
  deleted: boolean;
35
35
  } | {
36
- id?: undefined;
37
36
  error: string;
38
37
  url?: undefined;
38
+ id?: undefined;
39
39
  provider?: undefined;
40
40
  configured?: undefined;
41
41
  } | {
@@ -45,8 +45,8 @@ declare const _default: import("../../action.js").ActionDefinition<{
45
45
  configured?: undefined;
46
46
  error?: undefined;
47
47
  } | {
48
- id?: undefined;
49
48
  url?: undefined;
49
+ id?: undefined;
50
50
  provider?: undefined;
51
51
  error: string;
52
52
  configured: boolean;