@agent-native/core 0.161.17 → 0.161.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) 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/actions/finalize-meeting.ts +57 -21
  27. package/corpus/templates/clips/actions/get-meeting.ts +11 -3
  28. package/corpus/templates/clips/actions/request-transcript.ts +183 -8
  29. package/corpus/templates/clips/actions/update-meeting.ts +66 -14
  30. package/corpus/templates/clips/app/components/meetings/canvas-editor.tsx +80 -135
  31. package/corpus/templates/clips/app/components/player/video-player.tsx +4 -0
  32. package/corpus/templates/clips/app/hooks/use-playback-position.ts +10 -2
  33. package/corpus/templates/clips/app/i18n/en-US.ts +4 -0
  34. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +470 -35
  35. package/corpus/templates/clips/app/routes/embed.$shareId.tsx +1 -0
  36. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +26 -25
  37. package/corpus/templates/clips/app/routes/share.$shareId.tsx +1 -0
  38. package/corpus/templates/clips/changelog/2026-08-18-clips-no-longer-opens-welcome-window-on-first-launch.md +6 -0
  39. package/corpus/templates/clips/changelog/2026-08-18-meeting-notes-support-rich-editing-for-personal-notes-summar.md +6 -0
  40. package/corpus/templates/clips/changelog/2026-08-18-pending-recording-files-now-use-a-clips-prefixed-name.md +6 -0
  41. package/corpus/templates/clips/desktop/src/main.tsx +0 -3
  42. package/corpus/templates/clips/desktop/src/shared/config.ts +0 -1
  43. package/corpus/templates/clips/desktop/src/styles.css +0 -118
  44. package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +0 -1
  45. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +0 -45
  46. package/corpus/templates/clips/desktop/src-tauri/src/config.rs +1 -4
  47. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +0 -10
  48. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +57 -5
  49. package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +13 -3
  50. package/corpus/templates/content/.agents/skills/adding-a-feature/SKILL.md +10 -0
  51. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  52. package/corpus/templates/content/.agents/skills/secrets/SKILL.md +29 -2
  53. package/corpus/templates/content/AGENTS.md +1 -0
  54. package/corpus/templates/crm/.agents/skills/adding-a-feature/SKILL.md +10 -0
  55. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  56. package/corpus/templates/crm/.agents/skills/secrets/SKILL.md +29 -2
  57. package/corpus/templates/crm/AGENTS.md +1 -0
  58. package/corpus/templates/design/.agents/skills/adding-a-feature/SKILL.md +10 -0
  59. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  60. package/corpus/templates/design/.agents/skills/secrets/SKILL.md +29 -2
  61. package/corpus/templates/design/AGENTS.md +1 -0
  62. package/corpus/templates/design/app/i18n-data.ts +11 -0
  63. package/corpus/templates/design/app/lib/agent-chat.ts +9 -8
  64. package/corpus/templates/dispatch/.agents/skills/adding-a-feature/SKILL.md +10 -0
  65. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  66. package/corpus/templates/dispatch/.agents/skills/secrets/SKILL.md +29 -2
  67. package/corpus/templates/dispatch/AGENTS.md +5 -5
  68. package/corpus/templates/factory/.agents/skills/adding-a-feature/SKILL.md +10 -0
  69. package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  70. package/corpus/templates/factory/.agents/skills/secrets/SKILL.md +29 -2
  71. package/corpus/templates/factory/AGENTS.md +1 -0
  72. package/corpus/templates/forms/.agents/skills/adding-a-feature/SKILL.md +10 -0
  73. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  74. package/corpus/templates/forms/.agents/skills/secrets/SKILL.md +29 -2
  75. package/corpus/templates/forms/AGENTS.md +1 -0
  76. package/corpus/templates/macros/.agents/skills/adding-a-feature/SKILL.md +10 -0
  77. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  78. package/corpus/templates/macros/.agents/skills/secrets/SKILL.md +29 -2
  79. package/corpus/templates/macros/AGENTS.md +1 -0
  80. package/corpus/templates/mail/.agents/skills/adding-a-feature/SKILL.md +10 -0
  81. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  82. package/corpus/templates/mail/.agents/skills/secrets/SKILL.md +29 -2
  83. package/corpus/templates/mail/AGENTS.md +1 -0
  84. package/corpus/templates/mail/app/components/email/EmailList.tsx +74 -22
  85. package/corpus/templates/mail/app/components/email/infinite-pagination.ts +82 -0
  86. package/corpus/templates/mail/app/hooks/use-emails.ts +1 -0
  87. package/corpus/templates/mail/app/pages/InboxPage.tsx +15 -10
  88. package/corpus/templates/mail/app/pages/inbox-zero.ts +35 -0
  89. package/corpus/templates/mail/changelog/2026-08-18-pinned-labels-load-matches.md +6 -0
  90. package/corpus/templates/plan/.agents/skills/adding-a-feature/SKILL.md +10 -0
  91. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  92. package/corpus/templates/plan/.agents/skills/secrets/SKILL.md +29 -2
  93. package/corpus/templates/plan/AGENTS.md +1 -0
  94. package/corpus/templates/slides/.agents/skills/adding-a-feature/SKILL.md +10 -0
  95. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  96. package/corpus/templates/slides/.agents/skills/secrets/SKILL.md +29 -2
  97. package/corpus/templates/slides/AGENTS.md +2 -1
  98. package/corpus/templates/slides/actions/get-deck.ts +5 -1
  99. package/corpus/templates/slides/actions/list-decks.ts +29 -8
  100. package/corpus/templates/slides/actions/view-screen.ts +7 -3
  101. package/corpus/templates/slides/changelog/2026-08-18-decks-appear-under-mine.md +6 -0
  102. package/corpus/templates/slides/shared/ownership.ts +6 -0
  103. package/corpus/templates/tasks/.agents/skills/adding-a-feature/SKILL.md +10 -0
  104. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  105. package/corpus/templates/tasks/.agents/skills/secrets/SKILL.md +29 -2
  106. package/corpus/templates/tasks/AGENTS.md +1 -0
  107. package/dist/action.js +43 -1
  108. package/dist/app-config/schema.d.ts +2 -0
  109. package/dist/app-config/workspace.d.ts +2 -0
  110. package/dist/app-config/workspace.js +18 -0
  111. package/dist/catalog.json +23 -23
  112. package/dist/client/analytics.d.ts +1 -0
  113. package/dist/client/api-path.js +7 -3
  114. package/dist/client/chat/run-recovery.js +1 -1
  115. package/dist/client/frame.js +20 -6
  116. package/dist/client/org/workspace-app-links.js +10 -1
  117. package/dist/client/route-state.js +17 -13
  118. package/dist/collab/awareness.d.ts +2 -2
  119. package/dist/collab/routes.d.ts +1 -1
  120. package/dist/collab/struct-routes.d.ts +1 -1
  121. package/dist/deploy/build.js +26 -2
  122. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  123. package/dist/notifications/routes.d.ts +1 -1
  124. package/dist/observability/routes.d.ts +5 -5
  125. package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
  126. package/dist/provider-api/actions/provider-api.d.ts +15 -15
  127. package/dist/secrets/routes.d.ts +9 -9
  128. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  129. package/dist/server/app-origin-config.d.ts +1 -0
  130. package/dist/server/app-origin-config.js +3 -0
  131. package/dist/server/auth.d.ts +6 -0
  132. package/dist/server/auth.js +25 -7
  133. package/dist/server/cookie-namespace.js +17 -2
  134. package/dist/server/credential-provider.js +5 -2
  135. package/dist/server/derived-secret.js +3 -2
  136. package/dist/server/onboarding-html.js +34 -2
  137. package/dist/server/workspace-oauth.js +11 -6
  138. package/dist/shared/runtime-config.d.ts +2 -0
  139. package/dist/shared/runtime-config.js +12 -3
  140. package/dist/templates/chat/.agents/skills/adding-a-feature/SKILL.md +10 -0
  141. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  142. package/dist/templates/chat/.agents/skills/secrets/SKILL.md +29 -2
  143. package/dist/templates/chat/AGENTS.md +4 -0
  144. package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +10 -0
  145. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  146. package/dist/templates/default/.agents/skills/secrets/SKILL.md +29 -2
  147. package/dist/templates/default/AGENTS.md +4 -0
  148. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  149. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +29 -2
  150. package/dist/templates/headless/AGENTS.md +4 -0
  151. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +10 -0
  152. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  153. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +29 -2
  154. package/dist/templates/workspace-core/AGENTS.md +4 -0
  155. package/dist/templates/workspace-root/AGENTS.md +9 -0
  156. package/dist/vite/client.js +5 -2
  157. package/docs/content/deployment.mdx +70 -0
  158. package/docs/content/faq.mdx +1 -1
  159. package/package.json +2 -2
  160. package/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +10 -0
  161. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  162. package/src/templates/chat/.agents/skills/secrets/SKILL.md +29 -2
  163. package/src/templates/chat/AGENTS.md +4 -0
  164. package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +10 -0
  165. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  166. package/src/templates/default/.agents/skills/secrets/SKILL.md +29 -2
  167. package/src/templates/default/AGENTS.md +4 -0
  168. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  169. package/src/templates/headless/.agents/skills/secrets/SKILL.md +29 -2
  170. package/src/templates/headless/AGENTS.md +4 -0
  171. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +10 -0
  172. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  173. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +29 -2
  174. package/src/templates/workspace-core/AGENTS.md +4 -0
  175. package/src/templates/workspace-root/AGENTS.md +9 -0
  176. package/corpus/templates/clips/desktop/src/overlays/onboarding.tsx +0 -314
@@ -1,9 +1,12 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
+ import { getAppConfig } from "../app-config/index.js";
4
+ import { isTruthyRuntimeValue } from "../shared/runtime-config.js";
3
5
  const FIRST_PARTY_COOKIE_DOMAIN = "agent-native.com";
4
6
  export function resolveAuthCookieNamespace(env = process.env, cwd = process.cwd()) {
5
- const isWorkspaceMode = env.AGENT_NATIVE_WORKSPACE === "1" ||
6
- env.VITE_AGENT_NATIVE_WORKSPACE === "1";
7
+ const isWorkspaceMode = env === process.env
8
+ ? isConfiguredWorkspaceRuntime()
9
+ : isWorkspaceModeFromEnv(env);
7
10
  const configuredCookieDomain = normalizeCookieDomain(env.COOKIE_DOMAIN);
8
11
  const isFirstPartyCookieDomain = normalizeDomainForCompare(configuredCookieDomain) ===
9
12
  FIRST_PARTY_COOKIE_DOMAIN;
@@ -63,6 +66,18 @@ export function resolveAuthCookieNamespace(env = process.env, cwd = process.cwd(
63
66
  isFirstPartyCookieDomain,
64
67
  };
65
68
  }
69
+ function isConfiguredWorkspaceRuntime() {
70
+ const workspace = getAppConfig().workspace;
71
+ return (workspace.isWorkspace === true || typeof workspace.appsJson === "string");
72
+ }
73
+ function isWorkspaceModeFromEnv(env) {
74
+ const workspaceFlag = firstConfiguredValue(env.AGENT_NATIVE_WORKSPACE, env.VITE_AGENT_NATIVE_WORKSPACE);
75
+ const workspaceApps = firstConfiguredValue(env.AGENT_NATIVE_WORKSPACE_APPS_JSON, env.VITE_AGENT_NATIVE_WORKSPACE_APPS_JSON);
76
+ return isTruthyRuntimeValue(workspaceFlag) || Boolean(workspaceApps);
77
+ }
78
+ function firstConfiguredValue(...values) {
79
+ return values.find((value) => value?.trim())?.trim();
80
+ }
66
81
  function readPackageJsonName(cwd) {
67
82
  try {
68
83
  const raw = fs.readFileSync(path.join(cwd, "package.json"), "utf8");
@@ -22,6 +22,7 @@ import { CREDENTIAL_STORE_UNAVAILABLE_ERROR_CODE, GATEWAY_UNAVAILABLE_VISITOR_ME
22
22
  import { getAppConfig } from "../app-config/index.js";
23
23
  import { getDbExec, isLocalDatabase, isTransientDatabaseError, } from "../db/client.js";
24
24
  import { getOrgSetting } from "../settings/org-settings.js";
25
+ import { isTruthyRuntimeValue } from "../shared/runtime-config.js";
25
26
  import { getRequestUserEmail, getRequestOrgId } from "./request-context.js";
26
27
  const DISPATCH_VAULT_ACCESS_SETTINGS_KEY = "dispatch-vault-access-settings";
27
28
  /**
@@ -209,8 +210,10 @@ function isHostedWorkspaceRuntime() {
209
210
  const hasFusionPreview = Boolean(process.env.FUSION_ENVIRONMENT ||
210
211
  process.env.FUSION_ENV_ORIGIN ||
211
212
  process.env.VITE_FUSION_ENV_ORIGIN);
212
- return (/^(1|true)$/i.test(process.env.AGENT_NATIVE_WORKSPACE ?? "") ||
213
- /^(1|true)$/i.test(process.env.VITE_AGENT_NATIVE_WORKSPACE ?? "") ||
213
+ return (isTruthyRuntimeValue(process.env.AGENT_NATIVE_WORKSPACE) ||
214
+ isTruthyRuntimeValue(process.env.VITE_AGENT_NATIVE_WORKSPACE) ||
215
+ Boolean(process.env.AGENT_NATIVE_WORKSPACE_APPS_JSON?.trim()) ||
216
+ Boolean(process.env.VITE_AGENT_NATIVE_WORKSPACE_APPS_JSON?.trim()) ||
214
217
  hasFusionPreview);
215
218
  }
216
219
  function isProductionLikeRuntime() {
@@ -1,8 +1,9 @@
1
1
  import crypto from "node:crypto";
2
+ import { getAppConfig } from "../app-config/index.js";
2
3
  const DERIVED_SECRET_PREFIX = "agent-native:derived-secret:v1";
3
4
  function isWorkspaceRuntime() {
4
- return (process.env.AGENT_NATIVE_WORKSPACE === "1" ||
5
- process.env.VITE_AGENT_NATIVE_WORKSPACE === "1");
5
+ const workspace = getAppConfig().workspace;
6
+ return (workspace.isWorkspace === true || typeof workspace.appsJson === "string");
6
7
  }
7
8
  export function deriveServerSecret(rootSecret, purpose) {
8
9
  return crypto
@@ -6,6 +6,7 @@
6
6
  *
7
7
  * After first account exists, this page acts as a normal login page.
8
8
  */
9
+ import { getAppConfig } from "../app-config/index.js";
9
10
  import { getLocaleInitScript } from "../localization/server.js";
10
11
  import { DEFAULT_LOCALE, LOCALE_METADATA, LOCALE_STORAGE_KEY, SUPPORTED_LOCALES, } from "../localization/shared.js";
11
12
  import { NATIVE_AUTH_COPY } from "../shared/auth-copy.js";
@@ -42,6 +43,25 @@ function getConnectionLabel() {
42
43
  return "Turso";
43
44
  return "SQL database";
44
45
  }
46
+ function isWorkspaceRuntime() {
47
+ const workspace = getAppConfig().workspace;
48
+ return (workspace.isWorkspace === true || typeof workspace.appsJson === "string");
49
+ }
50
+ function workspaceBasePathFromRequest(requestPath) {
51
+ if (!isWorkspaceRuntime() || !requestPath)
52
+ return "";
53
+ const pathname = requestPath.split(/[?#]/, 1)[0] || "/";
54
+ const firstSegment = pathname.split("/").find(Boolean);
55
+ if (!firstSegment ||
56
+ firstSegment === "_agent-native" ||
57
+ firstSegment === "api" ||
58
+ firstSegment === "sign-in" ||
59
+ firstSegment === "login" ||
60
+ firstSegment === "signup") {
61
+ return "";
62
+ }
63
+ return normalizeAppBasePath(`/${firstSegment}`);
64
+ }
45
65
  function withAppBasePath(path) {
46
66
  const cleanPath = path.startsWith("/") ? path : `/${path}`;
47
67
  const basePath = normalizeAppBasePath(process.env.VITE_APP_BASE_PATH || process.env.APP_BASE_PATH);
@@ -997,7 +1017,9 @@ export function getOnboardingHtml(opts = {}) {
997
1017
  // for every visitor. A genuinely misconfigured server instead surfaces a
998
1018
  // clear error at click time via the auth API.
999
1019
  const renderGoogleButton = showGoogle || googleOnly;
1000
- const appBasePath = normalizeAppBasePath(process.env.VITE_APP_BASE_PATH || process.env.APP_BASE_PATH);
1020
+ const configuredAppBasePath = normalizeAppBasePath(process.env.VITE_APP_BASE_PATH || process.env.APP_BASE_PATH);
1021
+ const appBasePath = configuredAppBasePath || workspaceBasePathFromRequest(opts.requestPath);
1022
+ const workspaceRuntime = isWorkspaceRuntime();
1001
1023
  const publicOAuthOrigin = getPublicOAuthOrigin();
1002
1024
  const workspaceGatewayReturnOrigin = getWorkspaceGatewayReturnOrigin();
1003
1025
  const googleAuthMode = resolveGoogleAuthMode(opts.googleAuthMode);
@@ -2126,7 +2148,17 @@ ${signupLocalModeNoteHtml}
2126
2148
  if (configured) return configured;
2127
2149
  var marker = '/_agent-native';
2128
2150
  var idx = window.location.pathname.indexOf(marker);
2129
- return idx > 0 ? window.location.pathname.slice(0, idx) : '';
2151
+ if (idx > 0) return window.location.pathname.slice(0, idx);
2152
+ if (${JSON.stringify(workspaceRuntime)}) {
2153
+ var segments = window.location.pathname.split('/');
2154
+ for (var i = 0; i < segments.length; i++) {
2155
+ var segment = segments[i];
2156
+ if (segment && segment !== '_agent-native' && segment !== 'api' && segment !== 'sign-in' && segment !== 'login' && segment !== 'signup') {
2157
+ return '/' + segment;
2158
+ }
2159
+ }
2160
+ }
2161
+ return '';
2130
2162
  }
2131
2163
  function __anPath(path) {
2132
2164
  return __anBasePath() + path;
@@ -1,3 +1,5 @@
1
+ import { getAppConfig } from "../app-config/index.js";
2
+ import { isTruthyRuntimeValue } from "../shared/runtime-config.js";
1
3
  /**
2
4
  * Whether workspace OAuth callbacks use the root framework relay.
3
5
  *
@@ -8,13 +10,16 @@
8
10
  * the mounted app that initiated it.
9
11
  */
10
12
  export function isWorkspaceOAuthCallbackRelayEnabled() {
13
+ const workspace = getAppConfig().workspace;
11
14
  const metaEnv = import.meta.env;
12
- return ([
13
- process.env.AGENT_NATIVE_WORKSPACE,
14
- process.env.VITE_AGENT_NATIVE_WORKSPACE,
15
- metaEnv?.AGENT_NATIVE_WORKSPACE,
16
- metaEnv?.VITE_AGENT_NATIVE_WORKSPACE,
17
- ].some((value) => value === "1" || value === "true") ||
15
+ return (workspace.isWorkspace === true ||
16
+ typeof workspace.appsJson === "string" ||
17
+ [
18
+ process.env.AGENT_NATIVE_WORKSPACE,
19
+ process.env.VITE_AGENT_NATIVE_WORKSPACE,
20
+ metaEnv?.AGENT_NATIVE_WORKSPACE,
21
+ metaEnv?.VITE_AGENT_NATIVE_WORKSPACE,
22
+ ].some((value) => isTruthyRuntimeValue(value)) ||
18
23
  [
19
24
  process.env.AGENT_NATIVE_WORKSPACE_APP_ID,
20
25
  process.env.VITE_AGENT_NATIVE_WORKSPACE_APP_ID,
@@ -37,6 +37,8 @@ export interface RuntimeConfigReportOptions {
37
37
  phase?: RuntimeConfigPhase;
38
38
  appName?: string;
39
39
  }
40
+ /** Parse the truthy spellings accepted by typed runtime configuration flags. */
41
+ export declare function isTruthyRuntimeValue(value: string | boolean | undefined): boolean;
40
42
  export declare function runtimeConfigRequirementsFromSearchParams(searchParams: URLSearchParams): RuntimeConfigRequirements;
41
43
  export declare function buildRuntimeConfigPrompt(report: Pick<RuntimeConfigReport, "environment" | "phase" | "issues">, appName?: string): string;
42
44
  export declare function getRuntimeConfigReport(env: Record<string, string | undefined>, requirements?: RuntimeConfigRequirements, options?: RuntimeConfigReportOptions): RuntimeConfigReport;
@@ -5,6 +5,13 @@
5
5
  * process.env so the same rules can run during a Vite build, on the server,
6
6
  * and in focused tests without ever exposing secret values to the browser.
7
7
  */
8
+ /** Parse the truthy spellings accepted by typed runtime configuration flags. */
9
+ export function isTruthyRuntimeValue(value) {
10
+ if (value === true)
11
+ return true;
12
+ return (typeof value === "string" &&
13
+ ["1", "true", "yes", "on"].includes(value.trim().toLowerCase()));
14
+ }
8
15
  const ENV_KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
9
16
  const RUNTIME_CONFIG_ISSUE_CODES = new Set([
10
17
  "auth-disabled-in-production",
@@ -36,7 +43,7 @@ function valueOf(env, key) {
36
43
  return value || undefined;
37
44
  }
38
45
  function truthy(value) {
39
- return value === "1" || value?.toLowerCase() === "true";
46
+ return isTruthyRuntimeValue(value);
40
47
  }
41
48
  function isProductionEnvironment(env) {
42
49
  return (valueOf(env, "NODE_ENV") === "production" ||
@@ -44,8 +51,10 @@ function isProductionEnvironment(env) {
44
51
  valueOf(env, "VERCEL_ENV") === "production");
45
52
  }
46
53
  function isWorkspaceRuntime(env) {
47
- return (valueOf(env, "AGENT_NATIVE_WORKSPACE") === "1" ||
48
- valueOf(env, "VITE_AGENT_NATIVE_WORKSPACE") === "1");
54
+ return (isTruthyRuntimeValue(valueOf(env, "AGENT_NATIVE_WORKSPACE")) ||
55
+ isTruthyRuntimeValue(valueOf(env, "VITE_AGENT_NATIVE_WORKSPACE")) ||
56
+ Boolean(valueOf(env, "AGENT_NATIVE_WORKSPACE_APPS_JSON")) ||
57
+ Boolean(valueOf(env, "VITE_AGENT_NATIVE_WORKSPACE_APPS_JSON")));
49
58
  }
50
59
  function appEnvPrefix(env, appName) {
51
60
  const raw = appName ?? valueOf(env, "APP_NAME");
@@ -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