@agent-native/core 0.161.17 → 0.161.20

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 (130) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/adding-a-feature/SKILL.md +10 -0
  3. package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  4. package/corpus/templates/analytics/.agents/skills/secrets/SKILL.md +29 -2
  5. package/corpus/templates/analytics/AGENTS.md +1 -0
  6. package/corpus/templates/analytics/server/plugins/auth.ts +4 -0
  7. package/corpus/templates/assets/.agents/skills/adding-a-feature/SKILL.md +10 -0
  8. package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  9. package/corpus/templates/assets/.agents/skills/secrets/SKILL.md +29 -2
  10. package/corpus/templates/assets/AGENTS.md +1 -0
  11. package/corpus/templates/brain/.agents/skills/adding-a-feature/SKILL.md +10 -0
  12. package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  13. package/corpus/templates/brain/.agents/skills/secrets/SKILL.md +29 -2
  14. package/corpus/templates/brain/AGENTS.md +1 -0
  15. package/corpus/templates/calendar/.agents/skills/adding-a-feature/SKILL.md +10 -0
  16. package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  17. package/corpus/templates/calendar/.agents/skills/secrets/SKILL.md +29 -2
  18. package/corpus/templates/calendar/AGENTS.md +1 -0
  19. package/corpus/templates/chat/.agents/skills/adding-a-feature/SKILL.md +10 -0
  20. package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  21. package/corpus/templates/chat/.agents/skills/secrets/SKILL.md +29 -2
  22. package/corpus/templates/chat/AGENTS.md +4 -0
  23. package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  24. package/corpus/templates/clips/.agents/skills/secrets/SKILL.md +29 -2
  25. package/corpus/templates/clips/AGENTS.md +1 -0
  26. package/corpus/templates/clips/app/components/player/video-player.tsx +4 -0
  27. package/corpus/templates/clips/app/hooks/use-playback-position.ts +10 -2
  28. package/corpus/templates/clips/app/routes/embed.$shareId.tsx +1 -0
  29. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +26 -25
  30. package/corpus/templates/clips/app/routes/share.$shareId.tsx +1 -0
  31. package/corpus/templates/clips/changelog/2026-08-18-clips-no-longer-opens-welcome-window-on-first-launch.md +6 -0
  32. package/corpus/templates/clips/changelog/2026-08-18-pending-recording-files-now-use-a-clips-prefixed-name.md +6 -0
  33. package/corpus/templates/clips/desktop/src/main.tsx +0 -3
  34. package/corpus/templates/clips/desktop/src/shared/config.ts +0 -1
  35. package/corpus/templates/clips/desktop/src/styles.css +0 -118
  36. package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +0 -1
  37. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +0 -45
  38. package/corpus/templates/clips/desktop/src-tauri/src/config.rs +1 -4
  39. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +0 -10
  40. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +57 -5
  41. package/corpus/templates/content/.agents/skills/adding-a-feature/SKILL.md +10 -0
  42. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  43. package/corpus/templates/content/.agents/skills/secrets/SKILL.md +29 -2
  44. package/corpus/templates/content/AGENTS.md +1 -0
  45. package/corpus/templates/crm/.agents/skills/adding-a-feature/SKILL.md +10 -0
  46. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  47. package/corpus/templates/crm/.agents/skills/secrets/SKILL.md +29 -2
  48. package/corpus/templates/crm/AGENTS.md +1 -0
  49. package/corpus/templates/design/.agents/skills/adding-a-feature/SKILL.md +10 -0
  50. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  51. package/corpus/templates/design/.agents/skills/secrets/SKILL.md +29 -2
  52. package/corpus/templates/design/AGENTS.md +1 -0
  53. package/corpus/templates/design/app/i18n-data.ts +11 -0
  54. package/corpus/templates/design/app/lib/agent-chat.ts +9 -8
  55. package/corpus/templates/dispatch/.agents/skills/adding-a-feature/SKILL.md +10 -0
  56. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  57. package/corpus/templates/dispatch/.agents/skills/secrets/SKILL.md +29 -2
  58. package/corpus/templates/dispatch/AGENTS.md +5 -5
  59. package/corpus/templates/factory/.agents/skills/adding-a-feature/SKILL.md +10 -0
  60. package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  61. package/corpus/templates/factory/.agents/skills/secrets/SKILL.md +29 -2
  62. package/corpus/templates/factory/AGENTS.md +1 -0
  63. package/corpus/templates/forms/.agents/skills/adding-a-feature/SKILL.md +10 -0
  64. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  65. package/corpus/templates/forms/.agents/skills/secrets/SKILL.md +29 -2
  66. package/corpus/templates/forms/AGENTS.md +1 -0
  67. package/corpus/templates/macros/.agents/skills/adding-a-feature/SKILL.md +10 -0
  68. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  69. package/corpus/templates/macros/.agents/skills/secrets/SKILL.md +29 -2
  70. package/corpus/templates/macros/AGENTS.md +1 -0
  71. package/corpus/templates/mail/.agents/skills/adding-a-feature/SKILL.md +10 -0
  72. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  73. package/corpus/templates/mail/.agents/skills/secrets/SKILL.md +29 -2
  74. package/corpus/templates/mail/AGENTS.md +1 -0
  75. package/corpus/templates/plan/.agents/skills/adding-a-feature/SKILL.md +10 -0
  76. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  77. package/corpus/templates/plan/.agents/skills/secrets/SKILL.md +29 -2
  78. package/corpus/templates/plan/AGENTS.md +1 -0
  79. package/corpus/templates/slides/.agents/skills/adding-a-feature/SKILL.md +10 -0
  80. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  81. package/corpus/templates/slides/.agents/skills/secrets/SKILL.md +29 -2
  82. package/corpus/templates/slides/AGENTS.md +2 -1
  83. package/corpus/templates/tasks/.agents/skills/adding-a-feature/SKILL.md +10 -0
  84. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  85. package/corpus/templates/tasks/.agents/skills/secrets/SKILL.md +29 -2
  86. package/corpus/templates/tasks/AGENTS.md +1 -0
  87. package/dist/action.js +43 -1
  88. package/dist/client/chat/run-recovery.js +1 -1
  89. package/dist/client/route-state.js +17 -13
  90. package/dist/collab/routes.d.ts +1 -1
  91. package/dist/observability/routes.d.ts +2 -2
  92. package/dist/progress/routes.d.ts +1 -1
  93. package/dist/server/auth.d.ts +6 -0
  94. package/dist/server/auth.js +23 -5
  95. package/dist/templates/chat/.agents/skills/adding-a-feature/SKILL.md +10 -0
  96. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  97. package/dist/templates/chat/.agents/skills/secrets/SKILL.md +29 -2
  98. package/dist/templates/chat/AGENTS.md +4 -0
  99. package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +10 -0
  100. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  101. package/dist/templates/default/.agents/skills/secrets/SKILL.md +29 -2
  102. package/dist/templates/default/AGENTS.md +4 -0
  103. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  104. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +29 -2
  105. package/dist/templates/headless/AGENTS.md +4 -0
  106. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +10 -0
  107. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  108. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +29 -2
  109. package/dist/templates/workspace-core/AGENTS.md +4 -0
  110. package/dist/templates/workspace-root/AGENTS.md +9 -0
  111. package/docs/content/deployment.mdx +70 -0
  112. package/docs/content/faq.mdx +1 -1
  113. package/package.json +1 -1
  114. package/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +10 -0
  115. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  116. package/src/templates/chat/.agents/skills/secrets/SKILL.md +29 -2
  117. package/src/templates/chat/AGENTS.md +4 -0
  118. package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +10 -0
  119. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  120. package/src/templates/default/.agents/skills/secrets/SKILL.md +29 -2
  121. package/src/templates/default/AGENTS.md +4 -0
  122. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  123. package/src/templates/headless/.agents/skills/secrets/SKILL.md +29 -2
  124. package/src/templates/headless/AGENTS.md +4 -0
  125. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +10 -0
  126. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  127. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +29 -2
  128. package/src/templates/workspace-core/AGENTS.md +4 -0
  129. package/src/templates/workspace-root/AGENTS.md +9 -0
  130. package/corpus/templates/clips/desktop/src/overlays/onboarding.tsx +0 -314
@@ -158,7 +158,7 @@ export function BuilderSetupContent({ onConnected, layout = "default", }) {
158
158
  return (_jsxs("div", { className: cn("agent-builder-setup-content", sidebarLayout && "agent-builder-setup-card--sidebar"), children: [_jsxs("div", { className: cn("agent-builder-setup-card__content flex flex-col sm:flex-row sm:items-center sm:justify-between", sidebarLayout ? "gap-2" : "gap-3"), children: [_jsxs("div", { className: "agent-builder-setup-card__copy min-w-0", children: [_jsx("h3", { className: "text-[13px] font-medium text-foreground", children: t("agentPanel.connectAi", { defaultValue: "Connect AI" }) }), _jsx("p", { className: "mt-0.5 text-[11px] leading-relaxed text-muted-foreground", children: t("agentPanel.builderOrOwnKeys", {
159
159
  defaultValue: "Choose Builder.io or custom keys.",
160
160
  }) })] }), _jsxs("div", { className: cn("agent-builder-setup-card__actions flex shrink-0", sidebarLayout
161
- ? "flex-col items-start gap-1 sm:items-center"
161
+ ? "flex-row items-center gap-1"
162
162
  : "flex-nowrap items-center gap-2"), children: [_jsx(BuilderConnectCta, { variant: "compact", onConnected: onConnected }), _jsx("button", { type: "button", onClick: () => setKeyOpen((open) => !open), className: cn("agent-builder-setup-card__key-button inline-flex shrink-0 items-center whitespace-nowrap rounded-md text-[11px] font-medium", sidebarLayout
163
163
  ? "h-7 border-0 bg-transparent px-0 text-muted-foreground hover:bg-transparent hover:text-foreground"
164
164
  : "h-8 border border-border bg-background px-3 text-foreground hover:bg-accent"), "aria-expanded": keyOpen, children: t("agentPanel.addOwnKeys", {
@@ -58,19 +58,24 @@ function shallowEqualNavigationState(left, right) {
58
58
  }
59
59
  return true;
60
60
  }
61
- function stringifyForWriteDedup(value) {
61
+ /**
62
+ * Dedup token for the navigation write. Unserializable state falls back to the
63
+ * state's own identity, never a fresh symbol: the caller's `navigationKeys` is
64
+ * usually a new array each render, so a symbol recomputed here would never
65
+ * match the last one and every re-render would issue another failing write.
66
+ * Identity still lets a genuinely different state reach the write path.
67
+ */
68
+ function navigationWriteDedupToken(keys, state) {
62
69
  try {
63
- const serialized = JSON.stringify(value);
64
- return typeof serialized === "string"
65
- ? serialized
66
- : Symbol("unserializable navigation state");
70
+ const serialized = JSON.stringify({ keys, state });
71
+ if (typeof serialized === "string")
72
+ return serialized;
67
73
  }
68
74
  catch {
69
- // Do not turn a serialization failure into a reusable string key. A
70
- // distinct token lets a changed unserializable state reach the write path
71
- // and surface its real error instead of being silently deduplicated.
72
- return Symbol("unserializable navigation state");
75
+ // coercion-ok: deferred, not dropped — the write below still rejects with
76
+ // this error and reports it through `onError`.
73
77
  }
78
+ return state;
74
79
  }
75
80
  function resolveAgentChatViewTransitionOption(option, command, path) {
76
81
  const resolved = typeof option === "function" ? option(command, path) : option;
@@ -92,16 +97,15 @@ export function useSemanticNavigationState(options) {
92
97
  const commandKeys = useMemo(() => uniqueKeys(options.commandKeys ?? ["navigate"]), [options.commandKeys]);
93
98
  const commandQueryKey = useMemo(() => options.commandQueryKey ?? ["navigate-command"], [options.commandQueryKey]);
94
99
  const navigationState = options.state ?? null;
95
- const navigationWriteDedup = useMemo(() => stringifyForWriteDedup({
96
- keys: navigationKeys,
97
- state: navigationState,
98
- }), [navigationKeys, navigationState]);
100
+ const navigationWriteDedup = useMemo(() => navigationWriteDedupToken(navigationKeys, navigationState), [navigationKeys, navigationState]);
99
101
  const getCommandDedupKeyRef = useRef(options.getCommandDedupKey);
100
102
  const onCommandRef = useRef(options.onCommand);
101
103
  const onErrorRef = useRef(options.onError);
102
104
  getCommandDedupKeyRef.current = options.getCommandDedupKey;
103
105
  onCommandRef.current = options.onCommand;
104
106
  onErrorRef.current = options.onError;
107
+ // `null` is safe as "never written": a null state serializes to a string, so
108
+ // the token itself is never null.
105
109
  const lastNavigationWriteRef = useRef(null);
106
110
  useEffect(() => {
107
111
  if (!enabled)
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
26
26
  * Body: { update: string (base64), requestSource?: string }
27
27
  */
28
28
  export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
29
- error: string;
30
29
  ok?: undefined;
30
+ error: string;
31
31
  } | {
32
32
  error?: undefined;
33
33
  ok: boolean;
@@ -44,14 +44,14 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
44
44
  summary: import("./types.js").TraceSummary;
45
45
  spans: import("./types.js").TraceSpan[];
46
46
  id?: undefined;
47
- error?: undefined;
48
47
  ok?: undefined;
48
+ error?: undefined;
49
49
  } | {
50
50
  summary?: undefined;
51
51
  spans?: undefined;
52
52
  id: string;
53
- error?: undefined;
54
53
  ok?: undefined;
54
+ error?: undefined;
55
55
  } | {
56
56
  summary?: undefined;
57
57
  spans?: undefined;
@@ -15,6 +15,6 @@ export declare function createProgressHandler(): import("h3").EventHandlerWithFe
15
15
  error: string;
16
16
  ok?: undefined;
17
17
  } | {
18
- error?: undefined;
19
18
  ok: boolean;
19
+ error?: undefined;
20
20
  }>>;
@@ -37,6 +37,12 @@ export interface AuthOptions {
37
37
  * Both page routes and API routes can be made public.
38
38
  */
39
39
  publicPaths?: string[];
40
+ /**
41
+ * Public, unauthenticated ingest paths that may receive cross-origin
42
+ * requests when CORS_ALLOWED_ORIGINS is unset. These routes must perform
43
+ * their own request validation and must not rely on cookies for auth.
44
+ */
45
+ publicCorsPaths?: string[];
40
46
  /**
41
47
  * Workspace-level audience for the app.
42
48
  *
@@ -1380,11 +1380,11 @@ export async function runAuthGuard(event) {
1380
1380
  * unauthenticated requests. Returns the login HTML for page routes
1381
1381
  * or a 401 JSON response for API routes.
1382
1382
  *
1383
- * Reads loginHtml and publicPaths from _authGuardConfig on every request
1383
+ * Reads loginHtml and public paths from _authGuardConfig on every request
1384
1384
  * so that a custom plugin can update them after the default has already
1385
1385
  * installed this middleware (the production race condition fix).
1386
1386
  */
1387
- function applyCorsHeaders(event) {
1387
+ function applyCorsHeaders(event, publicCorsPaths = [], requestPath) {
1388
1388
  // Framework-level CORS. The auth guard runs before any of the app's own
1389
1389
  // route handlers, so we need to set CORS here too — otherwise a 401
1390
1390
  // response would be missing the Allow-Origin header and the browser
@@ -1404,15 +1404,22 @@ function applyCorsHeaders(event) {
1404
1404
  Boolean(getHeader(event, EMBED_TARGET_HEADER)) ||
1405
1405
  Boolean(getHeader(event, EMBED_TRANSPLANT_HEADER)) ||
1406
1406
  Boolean(getHeader(event, "authorization")));
1407
+ const isPublicCorsPath = Boolean(requestPath && matchesPathList(requestPath, publicCorsPaths));
1407
1408
  const allowedOrigin = getAllowedCorsOrigin(origin, {
1408
1409
  allowedOrigins: readCorsAllowedOrigins(),
1410
+ // Public ingestion endpoints such as analytics replay are intentionally
1411
+ // callable by browser apps on arbitrary origins. The endpoint still owns
1412
+ // its public-key, payload, quota, and origin checks; this only lets the
1413
+ // browser complete the preflight when no deployment-wide allowlist exists.
1414
+ allowAnyOriginWhenNoAllowlist: isPublicCorsPath,
1409
1415
  });
1410
1416
  const responseOrigin = mcpEmbedCorsRequest ? origin : allowedOrigin;
1411
1417
  if (!responseOrigin)
1412
1418
  return { hasOrigin: true, allowed: false };
1413
1419
  setResponseHeader(event, "Access-Control-Allow-Origin", responseOrigin);
1414
1420
  setResponseHeader(event, "Vary", "Origin");
1415
- if (!mcpEmbedCorsRequest || shouldAllowMcpEmbedCredentials(responseOrigin)) {
1421
+ if (!isPublicCorsPath &&
1422
+ (!mcpEmbedCorsRequest || shouldAllowMcpEmbedCredentials(responseOrigin))) {
1416
1423
  setResponseHeader(event, "Access-Control-Allow-Credentials", "true");
1417
1424
  }
1418
1425
  setResponseHeader(event, "Access-Control-Allow-Methods", "GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS");
@@ -1431,7 +1438,7 @@ function applyCorsHeaders(event) {
1431
1438
  }
1432
1439
  function createAuthCorsHandler() {
1433
1440
  return defineEventHandler((event) => {
1434
- const cors = applyCorsHeaders(event);
1441
+ const cors = applyCorsHeaders(event, _authGuardConfig?.publicCorsPaths);
1435
1442
  if (getMethod(event) !== "OPTIONS")
1436
1443
  return;
1437
1444
  if (cors.hasOrigin && !cors.allowed) {
@@ -1835,7 +1842,7 @@ function createAuthGuardFn(app) {
1835
1842
  return callbackRelay;
1836
1843
  // Emit CORS headers on every request the guard sees so that even
1837
1844
  // error responses (401) reach the browser.
1838
- const cors = applyCorsHeaders(event);
1845
+ const cors = applyCorsHeaders(event, config.publicCorsPaths, p);
1839
1846
  // Preflight short-circuit: the browser sends OPTIONS before the real
1840
1847
  // credentialed request. Must return success without invoking auth.
1841
1848
  if (getMethod(event) === "OPTIONS") {
@@ -4039,6 +4046,7 @@ async function mountBetterAuthRoutes(app, options) {
4039
4046
  _authGuardConfig = {
4040
4047
  ...loginHtmlConfig,
4041
4048
  publicPaths,
4049
+ publicCorsPaths: options.publicCorsPaths ?? [],
4042
4050
  workspaceAppAudience,
4043
4051
  workspaceAppPublicPaths: workspaceAppRouteAccess.publicPaths,
4044
4052
  workspaceAppProtectedPaths: workspaceAppRouteAccess.protectedPaths,
@@ -4236,6 +4244,14 @@ export async function autoMountAuth(app, options = {}) {
4236
4244
  ...options.publicPaths,
4237
4245
  ];
4238
4246
  }
4247
+ if (options.publicCorsPaths) {
4248
+ _authGuardConfig.publicCorsPaths = [
4249
+ ...new Set([
4250
+ ...(_authGuardConfig.publicCorsPaths ?? []),
4251
+ ...options.publicCorsPaths,
4252
+ ]),
4253
+ ];
4254
+ }
4239
4255
  if (options.workspaceAppAudience) {
4240
4256
  _authGuardConfig.workspaceAppAudience =
4241
4257
  resolveWorkspaceAppAudience(options);
@@ -4307,6 +4323,7 @@ export async function autoMountAuth(app, options = {}) {
4307
4323
  getLoginHtml: () => getCustomAuthRequiredHtml(),
4308
4324
  }),
4309
4325
  publicPaths,
4326
+ publicCorsPaths: options.publicCorsPaths ?? [],
4310
4327
  workspaceAppAudience,
4311
4328
  workspaceAppPublicPaths: workspaceAppRouteAccess.publicPaths,
4312
4329
  workspaceAppProtectedPaths: workspaceAppRouteAccess.protectedPaths,
@@ -4334,6 +4351,7 @@ export async function autoMountAuth(app, options = {}) {
4334
4351
  _authGuardConfig = {
4335
4352
  ...loginHtmlConfig,
4336
4353
  publicPaths,
4354
+ publicCorsPaths: options.publicCorsPaths ?? [],
4337
4355
  workspaceAppAudience,
4338
4356
  workspaceAppPublicPaths: workspaceAppRouteAccess.publicPaths,
4339
4357
  workspaceAppProtectedPaths: workspaceAppRouteAccess.protectedPaths,
@@ -76,6 +76,16 @@ Builder/internal data, or customer data in the action, UI, seed data, fixtures,
76
76
  docs, prompts, or generated extension/app content. Register required secrets,
77
77
  use OAuth helpers, or read scoped values from the vault/credential store.
78
78
 
79
+ Before writing custom setup or credential UI, perform the shared-primitive
80
+ preflight from `agent-native-toolkit`: inspect the workspace/provider connection
81
+ catalog first, then settings, secrets/vault, OAuth, onboarding, and provider API
82
+ support. Reuse an existing connection's app grant and scoped credential
83
+ resolver; only use app-local vault or OAuth primitives when no reusable
84
+ connection exists. Keep any wizard thin and provider-specific - it may explain
85
+ prerequisites, ordering, or readiness, but must not become a second vault or
86
+ custom credential transport. Do not mark each field `required` by reflex;
87
+ model onboarding around the logical connection outcome.
88
+
79
89
  If the feature involves attachments, images, recordings, screenshots, exports,
80
90
  or other file-like payloads, design the upload path in the same change:
81
91
  provider upload first, then URL/id/blob handle in SQL. Do not add base64/binary
@@ -152,6 +152,30 @@ preference, notification preference, or usage/billing surface, register it as a
152
152
  settings tab or app settings panel first. Only add sidebar UI when it is needed
153
153
  in the moment of agent use.
154
154
 
155
+ ## Integration Setup Preflight
156
+
157
+ Before building any setup, settings, credential, OAuth, or connection surface,
158
+ search the workspace/provider connection catalog first. If the provider already
159
+ has a reusable connection, use its catalog, app grant, and scoped credential
160
+ resolver rather than registering a parallel secret. Only then classify fields
161
+ that still need app-local setup by lifecycle and scope:
162
+
163
+ | Need | Default primitive |
164
+ | --- | --- |
165
+ | Deploy- or app-level configuration | Runtime configuration or deployment env vars |
166
+ | Existing workspace/provider connection | Workspace-connection catalog/grant plus `resolveWorkspaceConnectionCredential(s)ForApp` |
167
+ | App-local API/service key with no reusable connection | `registerRequiredSecret({ kind: "api-key" })` and the vault |
168
+ | Authorization-code or refresh-token flow | `kind: "oauth"` with `@agent-native/core/oauth-tokens` |
169
+ | Account, customer, or other non-secret identifiers | Scoped connection metadata or app data |
170
+ | Provider-specific prerequisites, sequencing, or health | A thin app-local guide over the shared primitives |
171
+
172
+ Do not register every provider field as a generic secret, mark every field as
173
+ required, or create a second credential-management surface. One logical
174
+ connection should normally produce one onboarding outcome. A custom setup page
175
+ is appropriate only when it adds domain-specific guidance or readiness checks;
176
+ it should link to or call the shared settings, OAuth, and action surfaces rather
177
+ than duplicating their storage or transport.
178
+
155
179
  ## Reusable Kits
156
180
 
157
181
  - **Settings kit**: a searchable settings page with account, workspace, AI
@@ -3,8 +3,8 @@ name: secrets
3
3
  description: >-
4
4
  Declaratively register API keys and service credentials a template needs so
5
5
  they appear in the agent sidebar settings UI and the onboarding checklist.
6
- Use for any third-party API key (OpenAI, Stripe, Twilio, etc.) and for
7
- surfacing OAuth connections in the unified settings UI.
6
+ Use before adding any third-party credential or setup UI so API keys, OAuth
7
+ connections, and scoped configuration use the correct shared primitive.
8
8
  scope: dev
9
9
  metadata:
10
10
  internal: true
@@ -24,6 +24,33 @@ encrypted `app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
24
24
  `${keys.NAME}` substitution. Examples must use obvious placeholders such as
25
25
  `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not real-looking copied values.
26
26
 
27
+ ## Credential Modeling Preflight
28
+
29
+ Before registering a provider's fields, inspect the workspace/provider connection
30
+ catalog first. If a reusable connection exists, use its app grant and scoped
31
+ `resolveWorkspaceConnectionCredential(s)ForApp` path instead of registering a
32
+ parallel secret. Only classify fields for app-local setup when no reusable
33
+ connection exists:
34
+
35
+ - **API or service key** - register it as `kind: "api-key"` with the narrowest
36
+ correct `scope`, a human label, a description, a docs link, and a validator.
37
+ - **OAuth authorization or refresh token** - use the OAuth token store and
38
+ register a `kind: "oauth"` entry so the shared UI renders Connect and the
39
+ runtime owns status, refresh, and reauthorization.
40
+ - **Deploy- or app-level configuration** - use deployment/runtime
41
+ configuration, not a per-user secret row.
42
+ - **Account, customer, manager, or other non-secret identifier** - store it as
43
+ scoped connection metadata or app data, not as a masked secret field.
44
+
45
+ `required: true` is for a logical setup requirement. If a provider needs
46
+ several values, do not automatically create one required checklist item per
47
+ field; use one composite onboarding step or a registered connection readiness
48
+ check.
49
+
50
+ Custom setup UI is allowed for provider-specific prerequisites, ordering, or
51
+ health checks, but it must delegate credential storage and connection state to
52
+ the shared vault/OAuth/settings surfaces.
53
+
27
54
  ## When to use
28
55
 
29
56
  Use this for any external credential your template needs: API keys, service
@@ -25,6 +25,10 @@ the matching skill only when this app actually uses that workflow. The
25
25
  - Never hardcode API keys, tokens, webhook URLs, signing secrets, private
26
26
  Builder/internal data, customer data, or credential-looking literals. Use
27
27
  secrets/OAuth/runtime configuration and obvious placeholders in examples.
28
+ - For external integrations, inspect the workspace/provider connection catalog
29
+ first. Reuse an existing connection and its scoped credential resolver; only
30
+ use app-local vault/OAuth/settings primitives when no reusable connection
31
+ exists. Keep custom setup UI provider-specific and never duplicate storage.
28
32
  - Keep actions deterministic and focused. Research, analysis, generation,
29
33
  recommendation, and synthesis start in the AgentSidebar and let the agent
30
34
  orchestrate its tools; follow-ups stay in the same thread rather than moving
@@ -76,6 +76,16 @@ Builder/internal data, or customer data in the action, UI, seed data, fixtures,
76
76
  docs, prompts, or generated extension/app content. Register required secrets,
77
77
  use OAuth helpers, or read scoped values from the vault/credential store.
78
78
 
79
+ Before writing custom setup or credential UI, perform the shared-primitive
80
+ preflight from `agent-native-toolkit`: inspect the workspace/provider connection
81
+ catalog first, then settings, secrets/vault, OAuth, onboarding, and provider API
82
+ support. Reuse an existing connection's app grant and scoped credential
83
+ resolver; only use app-local vault or OAuth primitives when no reusable
84
+ connection exists. Keep any wizard thin and provider-specific - it may explain
85
+ prerequisites, ordering, or readiness, but must not become a second vault or
86
+ custom credential transport. Do not mark each field `required` by reflex;
87
+ model onboarding around the logical connection outcome.
88
+
79
89
  If the feature involves attachments, images, recordings, screenshots, exports,
80
90
  or other file-like payloads, design the upload path in the same change:
81
91
  provider upload first, then URL/id/blob handle in SQL. Do not add base64/binary
@@ -152,6 +152,30 @@ preference, notification preference, or usage/billing surface, register it as a
152
152
  settings tab or app settings panel first. Only add sidebar UI when it is needed
153
153
  in the moment of agent use.
154
154
 
155
+ ## Integration Setup Preflight
156
+
157
+ Before building any setup, settings, credential, OAuth, or connection surface,
158
+ search the workspace/provider connection catalog first. If the provider already
159
+ has a reusable connection, use its catalog, app grant, and scoped credential
160
+ resolver rather than registering a parallel secret. Only then classify fields
161
+ that still need app-local setup by lifecycle and scope:
162
+
163
+ | Need | Default primitive |
164
+ | --- | --- |
165
+ | Deploy- or app-level configuration | Runtime configuration or deployment env vars |
166
+ | Existing workspace/provider connection | Workspace-connection catalog/grant plus `resolveWorkspaceConnectionCredential(s)ForApp` |
167
+ | App-local API/service key with no reusable connection | `registerRequiredSecret({ kind: "api-key" })` and the vault |
168
+ | Authorization-code or refresh-token flow | `kind: "oauth"` with `@agent-native/core/oauth-tokens` |
169
+ | Account, customer, or other non-secret identifiers | Scoped connection metadata or app data |
170
+ | Provider-specific prerequisites, sequencing, or health | A thin app-local guide over the shared primitives |
171
+
172
+ Do not register every provider field as a generic secret, mark every field as
173
+ required, or create a second credential-management surface. One logical
174
+ connection should normally produce one onboarding outcome. A custom setup page
175
+ is appropriate only when it adds domain-specific guidance or readiness checks;
176
+ it should link to or call the shared settings, OAuth, and action surfaces rather
177
+ than duplicating their storage or transport.
178
+
155
179
  ## Reusable Kits
156
180
 
157
181
  - **Settings kit**: a searchable settings page with account, workspace, AI
@@ -3,8 +3,8 @@ name: secrets
3
3
  description: >-
4
4
  Declaratively register API keys and service credentials a template needs so
5
5
  they appear in the agent sidebar settings UI and the onboarding checklist.
6
- Use for any third-party API key (OpenAI, Stripe, Twilio, etc.) and for
7
- surfacing OAuth connections in the unified settings UI.
6
+ Use before adding any third-party credential or setup UI so API keys, OAuth
7
+ connections, and scoped configuration use the correct shared primitive.
8
8
  scope: dev
9
9
  metadata:
10
10
  internal: true
@@ -24,6 +24,33 @@ encrypted `app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
24
24
  `${keys.NAME}` substitution. Examples must use obvious placeholders such as
25
25
  `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not real-looking copied values.
26
26
 
27
+ ## Credential Modeling Preflight
28
+
29
+ Before registering a provider's fields, inspect the workspace/provider connection
30
+ catalog first. If a reusable connection exists, use its app grant and scoped
31
+ `resolveWorkspaceConnectionCredential(s)ForApp` path instead of registering a
32
+ parallel secret. Only classify fields for app-local setup when no reusable
33
+ connection exists:
34
+
35
+ - **API or service key** - register it as `kind: "api-key"` with the narrowest
36
+ correct `scope`, a human label, a description, a docs link, and a validator.
37
+ - **OAuth authorization or refresh token** - use the OAuth token store and
38
+ register a `kind: "oauth"` entry so the shared UI renders Connect and the
39
+ runtime owns status, refresh, and reauthorization.
40
+ - **Deploy- or app-level configuration** - use deployment/runtime
41
+ configuration, not a per-user secret row.
42
+ - **Account, customer, manager, or other non-secret identifier** - store it as
43
+ scoped connection metadata or app data, not as a masked secret field.
44
+
45
+ `required: true` is for a logical setup requirement. If a provider needs
46
+ several values, do not automatically create one required checklist item per
47
+ field; use one composite onboarding step or a registered connection readiness
48
+ check.
49
+
50
+ Custom setup UI is allowed for provider-specific prerequisites, ordering, or
51
+ health checks, but it must delegate credential storage and connection state to
52
+ the shared vault/OAuth/settings surfaces.
53
+
27
54
  ## When to use
28
55
 
29
56
  Use this for any external credential your template needs: API keys, service
@@ -52,6 +52,10 @@ cross-cutting work and `self-modifying-code` when changing app source.
52
52
  and focused-object context.
53
53
  - Never hardcode keys, tokens, webhook URLs, private data, or credential-like
54
54
  literals. Use secrets, OAuth, or obvious placeholders.
55
+ - For external integrations, inspect the workspace/provider connection catalog
56
+ first. Reuse an existing connection and its scoped credential resolver; only
57
+ use app-local vault/OAuth/settings primitives when no reusable connection
58
+ exists. Keep custom setup UI provider-specific and never duplicate storage.
55
59
  - A missing or unreadable value must stay distinguishable from success. Throw or
56
60
  return an explicit error instead of silently falling back to an empty value.
57
61
 
@@ -152,6 +152,30 @@ preference, notification preference, or usage/billing surface, register it as a
152
152
  settings tab or app settings panel first. Only add sidebar UI when it is needed
153
153
  in the moment of agent use.
154
154
 
155
+ ## Integration Setup Preflight
156
+
157
+ Before building any setup, settings, credential, OAuth, or connection surface,
158
+ search the workspace/provider connection catalog first. If the provider already
159
+ has a reusable connection, use its catalog, app grant, and scoped credential
160
+ resolver rather than registering a parallel secret. Only then classify fields
161
+ that still need app-local setup by lifecycle and scope:
162
+
163
+ | Need | Default primitive |
164
+ | --- | --- |
165
+ | Deploy- or app-level configuration | Runtime configuration or deployment env vars |
166
+ | Existing workspace/provider connection | Workspace-connection catalog/grant plus `resolveWorkspaceConnectionCredential(s)ForApp` |
167
+ | App-local API/service key with no reusable connection | `registerRequiredSecret({ kind: "api-key" })` and the vault |
168
+ | Authorization-code or refresh-token flow | `kind: "oauth"` with `@agent-native/core/oauth-tokens` |
169
+ | Account, customer, or other non-secret identifiers | Scoped connection metadata or app data |
170
+ | Provider-specific prerequisites, sequencing, or health | A thin app-local guide over the shared primitives |
171
+
172
+ Do not register every provider field as a generic secret, mark every field as
173
+ required, or create a second credential-management surface. One logical
174
+ connection should normally produce one onboarding outcome. A custom setup page
175
+ is appropriate only when it adds domain-specific guidance or readiness checks;
176
+ it should link to or call the shared settings, OAuth, and action surfaces rather
177
+ than duplicating their storage or transport.
178
+
155
179
  ## Reusable Kits
156
180
 
157
181
  - **Settings kit**: a searchable settings page with account, workspace, AI
@@ -3,8 +3,8 @@ name: secrets
3
3
  description: >-
4
4
  Declaratively register API keys and service credentials a template needs so
5
5
  they appear in the agent sidebar settings UI and the onboarding checklist.
6
- Use for any third-party API key (OpenAI, Stripe, Twilio, etc.) and for
7
- surfacing OAuth connections in the unified settings UI.
6
+ Use before adding any third-party credential or setup UI so API keys, OAuth
7
+ connections, and scoped configuration use the correct shared primitive.
8
8
  scope: dev
9
9
  metadata:
10
10
  internal: true
@@ -24,6 +24,33 @@ encrypted `app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
24
24
  `${keys.NAME}` substitution. Examples must use obvious placeholders such as
25
25
  `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not real-looking copied values.
26
26
 
27
+ ## Credential Modeling Preflight
28
+
29
+ Before registering a provider's fields, inspect the workspace/provider connection
30
+ catalog first. If a reusable connection exists, use its app grant and scoped
31
+ `resolveWorkspaceConnectionCredential(s)ForApp` path instead of registering a
32
+ parallel secret. Only classify fields for app-local setup when no reusable
33
+ connection exists:
34
+
35
+ - **API or service key** - register it as `kind: "api-key"` with the narrowest
36
+ correct `scope`, a human label, a description, a docs link, and a validator.
37
+ - **OAuth authorization or refresh token** - use the OAuth token store and
38
+ register a `kind: "oauth"` entry so the shared UI renders Connect and the
39
+ runtime owns status, refresh, and reauthorization.
40
+ - **Deploy- or app-level configuration** - use deployment/runtime
41
+ configuration, not a per-user secret row.
42
+ - **Account, customer, manager, or other non-secret identifier** - store it as
43
+ scoped connection metadata or app data, not as a masked secret field.
44
+
45
+ `required: true` is for a logical setup requirement. If a provider needs
46
+ several values, do not automatically create one required checklist item per
47
+ field; use one composite onboarding step or a registered connection readiness
48
+ check.
49
+
50
+ Custom setup UI is allowed for provider-specific prerequisites, ordering, or
51
+ health checks, but it must delegate credential storage and connection state to
52
+ the shared vault/OAuth/settings surfaces.
53
+
27
54
  ## When to use
28
55
 
29
56
  Use this for any external credential your template needs: API keys, service
@@ -13,6 +13,10 @@ This app is not stateless. The Agent Native runtime uses SQL-backed stores for a
13
13
  ZIPs, screenshots, thumbnails, session replay chunks) in configured file/blob
14
14
  storage and persist only URLs, ids, or handles.
15
15
  - Do not hardcode API keys, tokens, webhook URLs, private data, or credential-looking literals.
16
+ - For external integrations, inspect the workspace/provider connection catalog
17
+ first. Reuse an existing connection and its scoped credential resolver; only
18
+ use app-local vault/OAuth/settings primitives when no reusable connection
19
+ exists. Keep custom setup UI provider-specific and never duplicate storage.
16
20
  - `actions/run.ts` is the CLI dispatcher for `pnpm action ...`, not an app
17
21
  action. Leave it in place and add callable primitives as separate
18
22
  `actions/<name>.ts` files.
@@ -76,6 +76,16 @@ Builder/internal data, or customer data in the action, UI, seed data, fixtures,
76
76
  docs, prompts, or generated extension/app content. Register required secrets,
77
77
  use OAuth helpers, or read scoped values from the vault/credential store.
78
78
 
79
+ Before writing custom setup or credential UI, perform the shared-primitive
80
+ preflight from `agent-native-toolkit`: inspect the workspace/provider connection
81
+ catalog first, then settings, secrets/vault, OAuth, onboarding, and provider API
82
+ support. Reuse an existing connection's app grant and scoped credential
83
+ resolver; only use app-local vault or OAuth primitives when no reusable
84
+ connection exists. Keep any wizard thin and provider-specific - it may explain
85
+ prerequisites, ordering, or readiness, but must not become a second vault or
86
+ custom credential transport. Do not mark each field `required` by reflex;
87
+ model onboarding around the logical connection outcome.
88
+
79
89
  If the feature involves attachments, images, recordings, screenshots, exports,
80
90
  or other file-like payloads, design the upload path in the same change:
81
91
  provider upload first, then URL/id/blob handle in SQL. Do not add base64/binary
@@ -152,6 +152,30 @@ preference, notification preference, or usage/billing surface, register it as a
152
152
  settings tab or app settings panel first. Only add sidebar UI when it is needed
153
153
  in the moment of agent use.
154
154
 
155
+ ## Integration Setup Preflight
156
+
157
+ Before building any setup, settings, credential, OAuth, or connection surface,
158
+ search the workspace/provider connection catalog first. If the provider already
159
+ has a reusable connection, use its catalog, app grant, and scoped credential
160
+ resolver rather than registering a parallel secret. Only then classify fields
161
+ that still need app-local setup by lifecycle and scope:
162
+
163
+ | Need | Default primitive |
164
+ | --- | --- |
165
+ | Deploy- or app-level configuration | Runtime configuration or deployment env vars |
166
+ | Existing workspace/provider connection | Workspace-connection catalog/grant plus `resolveWorkspaceConnectionCredential(s)ForApp` |
167
+ | App-local API/service key with no reusable connection | `registerRequiredSecret({ kind: "api-key" })` and the vault |
168
+ | Authorization-code or refresh-token flow | `kind: "oauth"` with `@agent-native/core/oauth-tokens` |
169
+ | Account, customer, or other non-secret identifiers | Scoped connection metadata or app data |
170
+ | Provider-specific prerequisites, sequencing, or health | A thin app-local guide over the shared primitives |
171
+
172
+ Do not register every provider field as a generic secret, mark every field as
173
+ required, or create a second credential-management surface. One logical
174
+ connection should normally produce one onboarding outcome. A custom setup page
175
+ is appropriate only when it adds domain-specific guidance or readiness checks;
176
+ it should link to or call the shared settings, OAuth, and action surfaces rather
177
+ than duplicating their storage or transport.
178
+
155
179
  ## Reusable Kits
156
180
 
157
181
  - **Settings kit**: a searchable settings page with account, workspace, AI
@@ -3,8 +3,8 @@ name: secrets
3
3
  description: >-
4
4
  Declaratively register API keys and service credentials a template needs so
5
5
  they appear in the agent sidebar settings UI and the onboarding checklist.
6
- Use for any third-party API key (OpenAI, Stripe, Twilio, etc.) and for
7
- surfacing OAuth connections in the unified settings UI.
6
+ Use before adding any third-party credential or setup UI so API keys, OAuth
7
+ connections, and scoped configuration use the correct shared primitive.
8
8
  scope: dev
9
9
  metadata:
10
10
  internal: true
@@ -24,6 +24,33 @@ encrypted `app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
24
24
  `${keys.NAME}` substitution. Examples must use obvious placeholders such as
25
25
  `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not real-looking copied values.
26
26
 
27
+ ## Credential Modeling Preflight
28
+
29
+ Before registering a provider's fields, inspect the workspace/provider connection
30
+ catalog first. If a reusable connection exists, use its app grant and scoped
31
+ `resolveWorkspaceConnectionCredential(s)ForApp` path instead of registering a
32
+ parallel secret. Only classify fields for app-local setup when no reusable
33
+ connection exists:
34
+
35
+ - **API or service key** - register it as `kind: "api-key"` with the narrowest
36
+ correct `scope`, a human label, a description, a docs link, and a validator.
37
+ - **OAuth authorization or refresh token** - use the OAuth token store and
38
+ register a `kind: "oauth"` entry so the shared UI renders Connect and the
39
+ runtime owns status, refresh, and reauthorization.
40
+ - **Deploy- or app-level configuration** - use deployment/runtime
41
+ configuration, not a per-user secret row.
42
+ - **Account, customer, manager, or other non-secret identifier** - store it as
43
+ scoped connection metadata or app data, not as a masked secret field.
44
+
45
+ `required: true` is for a logical setup requirement. If a provider needs
46
+ several values, do not automatically create one required checklist item per
47
+ field; use one composite onboarding step or a registered connection readiness
48
+ check.
49
+
50
+ Custom setup UI is allowed for provider-specific prerequisites, ordering, or
51
+ health checks, but it must delegate credential storage and connection state to
52
+ the shared vault/OAuth/settings surfaces.
53
+
27
54
  ## When to use
28
55
 
29
56
  Use this for any external credential your template needs: API keys, service
@@ -98,3 +98,7 @@ file plus `.agents/skills/` for workspace-specific conventions.
98
98
  | --- | --- |
99
99
  | `docs-search` | Search version-matched framework docs by query or slug, or list |
100
100
  | `source-search` | Search the bundled core/template source corpus by pattern or path |
101
+
102
+ - For external integrations, check the provider connection catalog first; reuse
103
+ its scoped resolver before app-local vault/OAuth/settings. Custom UI is for
104
+ provider readiness only, never duplicate credential storage.
@@ -164,6 +164,15 @@ an additional locale or changelog.
164
164
  - Dispatch vault access is workspace-wide by default: every saved vault key is
165
165
  available to every workspace app. Only create or request per-app vault grants
166
166
  when Dispatch's vault access setting is switched to manual mode.
167
+ - Before implementing an app that connects to an external service, inspect the
168
+ workspace/provider connection catalog first. Reuse an existing connection and
169
+ its scoped credential resolver; only then use shared settings, vault, OAuth,
170
+ onboarding, and provider API primitives for app-local setup.
171
+ - Keep custom setup UI only for provider-specific prerequisites, sequencing,
172
+ readiness, or health checks. It must link to or call shared settings/OAuth and
173
+ action surfaces, not duplicate credential storage or transport. Model one
174
+ logical connection as one onboarding outcome instead of marking every field
175
+ required by reflex.
167
176
  - When an app needs a provider credential, read it through the framework's
168
177
  scoped secret or workspace-connection resolver so the Dispatch vault remains
169
178
  the source of truth. Framework apps should use `resolveSecret` from