@agent-native/core 0.26.2 → 0.26.5

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 (71) hide show
  1. package/dist/cli/skills.d.ts.map +1 -1
  2. package/dist/cli/skills.js +4 -1
  3. package/dist/cli/skills.js.map +1 -1
  4. package/dist/client/mcp-app-host.d.ts +1 -0
  5. package/dist/client/mcp-app-host.d.ts.map +1 -1
  6. package/dist/client/mcp-app-host.js +44 -6
  7. package/dist/client/mcp-app-host.js.map +1 -1
  8. package/dist/deploy/build.d.ts +6 -1
  9. package/dist/deploy/build.d.ts.map +1 -1
  10. package/dist/deploy/build.js +92 -10
  11. package/dist/deploy/build.js.map +1 -1
  12. package/dist/deploy/immutable-assets.d.ts +11 -0
  13. package/dist/deploy/immutable-assets.d.ts.map +1 -0
  14. package/dist/deploy/immutable-assets.js +49 -0
  15. package/dist/deploy/immutable-assets.js.map +1 -0
  16. package/dist/deploy/workspace-deploy.d.ts.map +1 -1
  17. package/dist/deploy/workspace-deploy.js +37 -1
  18. package/dist/deploy/workspace-deploy.js.map +1 -1
  19. package/dist/mcp/build-server.d.ts.map +1 -1
  20. package/dist/mcp/build-server.js +95 -8
  21. package/dist/mcp/build-server.js.map +1 -1
  22. package/dist/mcp/embed-app.d.ts.map +1 -1
  23. package/dist/mcp/embed-app.js +247 -30
  24. package/dist/mcp/embed-app.js.map +1 -1
  25. package/dist/mcp/server.d.ts +5 -7
  26. package/dist/mcp/server.d.ts.map +1 -1
  27. package/dist/mcp/server.js +16 -12
  28. package/dist/mcp/server.js.map +1 -1
  29. package/dist/server/action-routes.d.ts.map +1 -1
  30. package/dist/server/action-routes.js +23 -7
  31. package/dist/server/action-routes.js.map +1 -1
  32. package/dist/server/auth.d.ts.map +1 -1
  33. package/dist/server/auth.js +69 -38
  34. package/dist/server/auth.js.map +1 -1
  35. package/dist/server/core-routes-plugin.d.ts +12 -1
  36. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  37. package/dist/server/core-routes-plugin.js +48 -44
  38. package/dist/server/core-routes-plugin.js.map +1 -1
  39. package/dist/server/create-server.d.ts.map +1 -1
  40. package/dist/server/create-server.js +3 -1
  41. package/dist/server/create-server.js.map +1 -1
  42. package/dist/server/credential-provider.d.ts +1 -0
  43. package/dist/server/credential-provider.d.ts.map +1 -1
  44. package/dist/server/credential-provider.js +15 -4
  45. package/dist/server/credential-provider.js.map +1 -1
  46. package/dist/server/embed-route.d.ts.map +1 -1
  47. package/dist/server/embed-route.js +28 -2
  48. package/dist/server/embed-route.js.map +1 -1
  49. package/dist/server/embed-session.d.ts.map +1 -1
  50. package/dist/server/embed-session.js +26 -7
  51. package/dist/server/embed-session.js.map +1 -1
  52. package/dist/server/onboarding-html.d.ts.map +1 -1
  53. package/dist/server/onboarding-html.js +52 -5
  54. package/dist/server/onboarding-html.js.map +1 -1
  55. package/dist/server/ssr-handler.d.ts +1 -1
  56. package/dist/server/ssr-handler.d.ts.map +1 -1
  57. package/dist/server/ssr-handler.js +23 -10
  58. package/dist/server/ssr-handler.js.map +1 -1
  59. package/dist/shared/cache-control.d.ts +2 -0
  60. package/dist/shared/cache-control.d.ts.map +1 -0
  61. package/dist/shared/cache-control.js +2 -0
  62. package/dist/shared/cache-control.js.map +1 -0
  63. package/dist/shared/mcp-embed-headers.d.ts +2 -1
  64. package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
  65. package/dist/shared/mcp-embed-headers.js +3 -1
  66. package/dist/shared/mcp-embed-headers.js.map +1 -1
  67. package/dist/templates/workspace-root/package.json +5 -0
  68. package/docs/content/mcp-protocol.md +0 -1
  69. package/docs/content/template-assets.md +5 -0
  70. package/package.json +2 -2
  71. package/src/templates/workspace-root/package.json +5 -0
@@ -22,6 +22,7 @@ import { getWorkspaceCoreExports, } from "./workspace-core.js";
22
22
  import { generateActionRegistryForProject } from "../vite/action-types-plugin.js";
23
23
  import { mcpEmbedStaticAssetRouteRules } from "../shared/mcp-embed-headers.js";
24
24
  import { AGENT_NATIVE_DEFAULT_SOCIAL_IMAGE } from "../shared/social-meta.js";
25
+ import { collectImmutableAssetPaths, IMMUTABLE_ASSET_CACHE_CONTROL, IMMUTABLE_ASSET_CACHE_HEADERS, prefixAssetPath, } from "./immutable-assets.js";
25
26
  const cwd = process.cwd();
26
27
  const preset = process.env.NITRO_PRESET || "node";
27
28
  const DEFAULT_SSR_CACHE_CONTROL = "public, max-age=5, stale-while-revalidate=604800, stale-if-error=3600";
@@ -48,6 +49,25 @@ function isNodeOnlyPlugin(filePath) {
48
49
  const basename = path.basename(filePath, path.extname(filePath));
49
50
  return NODE_ONLY_PLUGINS.has(basename);
50
51
  }
52
+ function addImmutableAssetRouteRule(routeRules, pathname) {
53
+ const existing = routeRules[pathname] ?? {};
54
+ routeRules[pathname] = {
55
+ ...existing,
56
+ headers: {
57
+ ...(existing.headers ?? {}),
58
+ ...IMMUTABLE_ASSET_CACHE_HEADERS,
59
+ },
60
+ };
61
+ }
62
+ export function addImmutableAssetRouteRulesForClientBuild(routeRules, clientDir, appBasePath = "") {
63
+ for (const assetPath of collectImmutableAssetPaths(clientDir)) {
64
+ addImmutableAssetRouteRule(routeRules, assetPath);
65
+ const mountedPath = prefixAssetPath(assetPath, appBasePath);
66
+ if (mountedPath !== assetPath) {
67
+ addImmutableAssetRouteRule(routeRules, mountedPath);
68
+ }
69
+ }
70
+ }
51
71
  /**
52
72
  * Generate the worker entry source code that wires up H3 + React Router SSR.
53
73
  *
@@ -57,7 +77,7 @@ function isNodeOnlyPlugin(filePath) {
57
77
  * `@agent-native/core/server`. This is the middle layer of the three-layer
58
78
  * inheritance model: app local > workspace core > framework default.
59
79
  */
60
- export function generateWorkerEntry(routes, pluginPaths, defaultPluginStems = [], actions = [], workspaceCore = null) {
80
+ export function generateWorkerEntry(routes, pluginPaths, defaultPluginStems = [], actions = [], workspaceCore = null, immutableAssetPaths = []) {
61
81
  const routeImports = [];
62
82
  const routeRegistrations = [];
63
83
  for (let i = 0; i < routes.length; i++) {
@@ -263,6 +283,8 @@ function injectHeadScript(html, script) {
263
283
  }
264
284
 
265
285
  const DEFAULT_SSR_CACHE_CONTROL = ${JSON.stringify(DEFAULT_SSR_CACHE_CONTROL)};
286
+ const IMMUTABLE_ASSET_CACHE_CONTROL = ${JSON.stringify(IMMUTABLE_ASSET_CACHE_CONTROL)};
287
+ const IMMUTABLE_ASSET_PATHS = new Set(${JSON.stringify([...new Set(immutableAssetPaths)].sort())});
266
288
  const AGENT_NATIVE_DEFAULT_SOCIAL_IMAGE = ${JSON.stringify(AGENT_NATIVE_DEFAULT_SOCIAL_IMAGE)};
267
289
  const OG_IMAGE_META_RE = /<meta\\b(?=[^>]*\\bproperty=(["'])og:image\\1)[^>]*>/i;
268
290
  const TWITTER_CARD_META_RE = /<meta\\b(?=[^>]*\\bname=(["'])twitter:card\\1)[^>]*>/i;
@@ -290,20 +312,74 @@ function injectDefaultSocialImageMeta(html) {
290
312
  return html.slice(0, headCloseIdx) + tags.join("") + html.slice(headCloseIdx);
291
313
  }
292
314
 
293
- function applyDefaultSsrCacheHeader(headers, status) {
294
- if (headers.has("cache-control")) return;
295
- if (status < 200 || status >= 400) return;
315
+ const ANONYMOUS_SESSION_COOKIE_NAMES = new Set(["an_docs_session"]);
316
+ const AUTH_SESSION_COOKIE_RE = /^(?:an_session(?:_[^=;]+)?|an_embed_session|[^=;]+\\.session_(?:token|data))$/;
317
+
318
+ function requestHasAuthenticatedCookie(cookieHeader) {
319
+ if (!cookieHeader) return false;
320
+ return cookieHeader
321
+ .split(";")
322
+ .map((cookie) => cookie.trim().split("=", 1)[0]?.trim())
323
+ .filter(Boolean)
324
+ .map((name) => name.replace(/^__(?:Secure|Host)-/, ""))
325
+ .some((name) => !ANONYMOUS_SESSION_COOKIE_NAMES.has(name) && AUTH_SESSION_COOKIE_RE.test(name));
326
+ }
327
+
328
+ function requestHasAuthSignal(request) {
329
+ const url = new URL(request.url);
330
+ return Boolean(
331
+ request.headers.get("authorization") ||
332
+ requestHasAuthenticatedCookie(request.headers.get("cookie")) ||
333
+ url.searchParams.has("__an_embed_token") ||
334
+ url.searchParams.has("_session")
335
+ );
336
+ }
337
+
338
+ function shouldUseDefaultSsrCacheHeader(headers, status, pathname, hasAuthSignal) {
339
+ if (status < 200 || status >= 400) return false;
296
340
 
297
341
  const contentType = (headers.get("content-type") || "").toLowerCase();
298
- if (!contentType.includes("text/html")) return;
342
+ if (contentType.includes("text/html")) {
343
+ return !headers.has("cache-control");
344
+ }
345
+
346
+ if (!pathname.endsWith(".data")) return false;
347
+ if (hasAuthSignal) return false;
348
+ if (!contentType.includes("text/x-script")) return false;
299
349
 
350
+ const cacheControl = headers.get("cache-control");
351
+ return !cacheControl || cacheControl.trim().toLowerCase() === "no-cache";
352
+ }
353
+
354
+ function applyDefaultSsrCacheHeader(headers, status, pathname, hasAuthSignal) {
355
+ if (!shouldUseDefaultSsrCacheHeader(headers, status, pathname, hasAuthSignal)) return;
300
356
  headers.set("cache-control", DEFAULT_SSR_CACHE_CONTROL);
301
357
  }
302
358
 
303
- async function rewriteMountedResponse(response, basePath) {
359
+ function isImmutableAssetRequest(request) {
360
+ const pathname = stripAppBasePath(new URL(request.url).pathname);
361
+ return IMMUTABLE_ASSET_PATHS.has(pathname);
362
+ }
363
+
364
+ function applyImmutableAssetCacheHeaders(response, request) {
365
+ if (!isImmutableAssetRequest(request)) return response;
366
+ if (!((response.status >= 200 && response.status < 300) || response.status === 304)) {
367
+ return response;
368
+ }
369
+ const headers = new Headers(response.headers);
370
+ headers.set("Cache-Control", IMMUTABLE_ASSET_CACHE_CONTROL);
371
+ headers.set("CDN-Cache-Control", IMMUTABLE_ASSET_CACHE_CONTROL);
372
+ return new Response(response.body, {
373
+ status: response.status,
374
+ statusText: response.statusText,
375
+ headers,
376
+ });
377
+ }
378
+
379
+ async function rewriteMountedResponse(response, basePath, pathname, hasAuthSignal) {
304
380
  const sentryClientConfigScript = getSentryClientConfigScript();
305
381
  const headers = new Headers(response.headers);
306
- applyDefaultSsrCacheHeader(headers, response.status);
382
+ applyDefaultSsrCacheHeader(headers, response.status, pathname, hasAuthSignal);
307
383
 
308
384
  const location = headers.get("location");
309
385
  if (location?.startsWith("/") && !location.startsWith("//")) {
@@ -414,6 +490,7 @@ ${actionRegistrations.join("\n")}
414
490
  return new Response(null, { status: 404 });
415
491
  }
416
492
  const request = requestWithPathname(event.req, p);
493
+ const hasAuthSignal = requestHasAuthSignal(event.req);
417
494
  if (event.req.method === "HEAD") {
418
495
  const getRequest = requestWithMethod(request, "GET");
419
496
  const response = await rrHandler(getRequest);
@@ -424,9 +501,11 @@ ${actionRegistrations.join("\n")}
424
501
  headers: response.headers,
425
502
  }),
426
503
  basePath,
504
+ p,
505
+ hasAuthSignal,
427
506
  );
428
507
  }
429
- return rewriteMountedResponse(await rrHandler(request), basePath);
508
+ return rewriteMountedResponse(await rrHandler(request), basePath, p, hasAuthSignal);
430
509
  }));
431
510
 
432
511
  _handler = app.fetch.bind(app);
@@ -458,7 +537,7 @@ export default {
458
537
  try {
459
538
  const assetResponse = await env.ASSETS.fetch(request);
460
539
  if (assetResponse.status !== 404) {
461
- return assetResponse;
540
+ return applyImmutableAssetCacheHeaders(assetResponse, request);
462
541
  }
463
542
  } catch {
464
543
  // Asset fetch failed — fall through to SSR
@@ -517,7 +596,8 @@ async function buildCloudflarePages() {
517
596
  : 0;
518
597
  console.log(`[deploy] ${routes.length} API routes, ${actions.length} actions, ${plugins.length} plugins (${plugins.filter((p) => isNodeOnlyPlugin(p)).length} skipped as Node-only), ${missingDefaults.length} auto-mounted defaults${workspaceCore ? `, workspace-core ${workspaceCore.packageName} (${workspaceSlotCount} plugin slots)` : ""}`);
519
598
  // Generate the worker entry
520
- const entrySource = generateWorkerEntry(routes, plugins, missingDefaults, actions, workspaceCore);
599
+ const immutableAssetPaths = collectImmutableAssetPaths(clientDir);
600
+ const entrySource = generateWorkerEntry(routes, plugins, missingDefaults, actions, workspaceCore, immutableAssetPaths);
521
601
  // Create _worker.js output directory
522
602
  const workerOutDir = path.join(distDir, "_worker.js");
523
603
  fs.mkdirSync(workerOutDir, { recursive: true });
@@ -1064,6 +1144,8 @@ export async function runNitroBuildPipeline(opts) {
1064
1144
  if (appBasePath) {
1065
1145
  copyDir(clientDir, path.join(publicOutputDir, appBasePath.slice(1)));
1066
1146
  }
1147
+ nitro.options.routeRules ??= {};
1148
+ addImmutableAssetRouteRulesForClientBuild(nitro.options.routeRules, clientDir, appBasePath);
1067
1149
  console.log(`[deploy] Copied client assets to ${path.relative(cwd, publicOutputDir)}`);
1068
1150
  }
1069
1151
  await hooks.nitroBuild(nitro);