@agent-native/core 0.63.1 → 0.63.3

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 (123) hide show
  1. package/dist/agent/harness/ai-sdk-adapter.d.ts +44 -0
  2. package/dist/agent/harness/ai-sdk-adapter.d.ts.map +1 -1
  3. package/dist/agent/harness/ai-sdk-adapter.js +120 -1
  4. package/dist/agent/harness/ai-sdk-adapter.js.map +1 -1
  5. package/dist/agent/harness/index.d.ts +1 -1
  6. package/dist/agent/harness/index.d.ts.map +1 -1
  7. package/dist/agent/harness/index.js.map +1 -1
  8. package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
  9. package/dist/client/blocks/library/AnnotatedCodeBlock.js +29 -10
  10. package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
  11. package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -1
  12. package/dist/client/blocks/library/DiffBlock.js +48 -20
  13. package/dist/client/blocks/library/DiffBlock.js.map +1 -1
  14. package/dist/client/blocks/library/diagram.d.ts.map +1 -1
  15. package/dist/client/blocks/library/diagram.js +14 -3
  16. package/dist/client/blocks/library/diagram.js.map +1 -1
  17. package/dist/client/blocks/library/wireframe.d.ts.map +1 -1
  18. package/dist/client/blocks/library/wireframe.js +14 -3
  19. package/dist/client/blocks/library/wireframe.js.map +1 -1
  20. package/dist/client/blocks/types.d.ts +5 -0
  21. package/dist/client/blocks/types.d.ts.map +1 -1
  22. package/dist/client/blocks/types.js.map +1 -1
  23. package/dist/server/action-discovery.d.ts.map +1 -1
  24. package/dist/server/action-discovery.js +24 -2
  25. package/dist/server/action-discovery.js.map +1 -1
  26. package/dist/server/deep-link.d.ts +2 -2
  27. package/dist/server/deep-link.d.ts.map +1 -1
  28. package/dist/server/deep-link.js +2 -2
  29. package/dist/server/deep-link.js.map +1 -1
  30. package/dist/styles/blocks.css +25 -3
  31. package/dist/tailwind.preset.d.ts.map +1 -1
  32. package/dist/tailwind.preset.js +8 -1
  33. package/dist/tailwind.preset.js.map +1 -1
  34. package/dist/templates/default/package.json +1 -0
  35. package/dist/templates/headless/AGENTS.md +3 -0
  36. package/dist/templates/headless/DEVELOPING.md +4 -0
  37. package/dist/templates/headless/actions/run.ts +6 -0
  38. package/docs/content/a2a-protocol.md +48 -10
  39. package/docs/content/actions.md +35 -16
  40. package/docs/content/agent-mentions.md +25 -32
  41. package/docs/content/agent-surfaces.md +31 -0
  42. package/docs/content/agent-teams.md +17 -14
  43. package/docs/content/agent-web-surfaces.md +24 -15
  44. package/docs/content/authentication.md +21 -0
  45. package/docs/content/automations.md +37 -21
  46. package/docs/content/blueprint-installer.md +7 -0
  47. package/docs/content/cli-adapters.md +7 -0
  48. package/docs/content/client.md +14 -0
  49. package/docs/content/cloneable-saas.md +14 -0
  50. package/docs/content/code-agents-ui.md +30 -2
  51. package/docs/content/components.md +21 -0
  52. package/docs/content/context-awareness.md +33 -48
  53. package/docs/content/creating-templates.md +43 -52
  54. package/docs/content/cross-app-sso.md +41 -0
  55. package/docs/content/database.md +41 -21
  56. package/docs/content/deployment.md +23 -6
  57. package/docs/content/dispatch.md +27 -0
  58. package/docs/content/drop-in-agent.md +26 -27
  59. package/docs/content/durable-resume.md +13 -1
  60. package/docs/content/embedding-sdk.md +14 -0
  61. package/docs/content/evals.md +14 -0
  62. package/docs/content/extensions.md +19 -0
  63. package/docs/content/external-agents.md +39 -2
  64. package/docs/content/faq.md +14 -0
  65. package/docs/content/file-uploads.md +20 -0
  66. package/docs/content/frames.md +14 -0
  67. package/docs/content/getting-started.md +34 -16
  68. package/docs/content/harness-agents.md +49 -8
  69. package/docs/content/human-approval.md +15 -30
  70. package/docs/content/key-concepts.md +37 -0
  71. package/docs/content/local-file-mode.md +26 -19
  72. package/docs/content/mcp-apps.md +36 -1
  73. package/docs/content/mcp-clients.md +49 -0
  74. package/docs/content/mcp-protocol.md +36 -0
  75. package/docs/content/messaging.md +34 -8
  76. package/docs/content/migration-workbench.md +7 -0
  77. package/docs/content/multi-app-workspace.md +29 -16
  78. package/docs/content/multi-tenancy.md +14 -0
  79. package/docs/content/native-chat-ui.md +20 -3
  80. package/docs/content/notifications.md +30 -0
  81. package/docs/content/observability.md +20 -1
  82. package/docs/content/observational-memory.md +14 -0
  83. package/docs/content/onboarding.md +32 -41
  84. package/docs/content/plan-plugin.md +14 -0
  85. package/docs/content/pr-visual-recap.md +14 -0
  86. package/docs/content/processors.md +7 -0
  87. package/docs/content/progress.md +23 -0
  88. package/docs/content/pure-agent-apps.md +7 -0
  89. package/docs/content/real-time-collaboration.md +19 -18
  90. package/docs/content/recurring-jobs.md +22 -19
  91. package/docs/content/routing.md +8 -0
  92. package/docs/content/sandbox-adapters.md +19 -0
  93. package/docs/content/security.md +38 -0
  94. package/docs/content/server.md +47 -25
  95. package/docs/content/sharing.md +50 -0
  96. package/docs/content/skills-guide.md +27 -42
  97. package/docs/content/template-analytics.md +60 -0
  98. package/docs/content/template-assets.md +68 -0
  99. package/docs/content/template-brain.md +83 -0
  100. package/docs/content/template-calendar.md +74 -0
  101. package/docs/content/template-chat.md +19 -0
  102. package/docs/content/template-clips.md +113 -0
  103. package/docs/content/template-content.md +133 -0
  104. package/docs/content/template-design.md +55 -0
  105. package/docs/content/template-dispatch.md +50 -0
  106. package/docs/content/template-forms.md +59 -0
  107. package/docs/content/template-mail.md +62 -0
  108. package/docs/content/template-plan.md +80 -5
  109. package/docs/content/template-slides.md +82 -0
  110. package/docs/content/template-videos.md +62 -0
  111. package/docs/content/tracking.md +21 -0
  112. package/docs/content/using-your-agent.md +14 -0
  113. package/docs/content/voice-input.md +31 -10
  114. package/docs/content/what-is-agent-native.md +25 -13
  115. package/docs/content/workspace-connections.md +49 -0
  116. package/docs/content/workspace-management.md +24 -0
  117. package/docs/content/workspace.md +50 -19
  118. package/docs/content/writing-agent-instructions.md +7 -0
  119. package/package.json +6 -2
  120. package/src/templates/default/package.json +1 -0
  121. package/src/templates/headless/AGENTS.md +3 -0
  122. package/src/templates/headless/DEVELOPING.md +4 -0
  123. package/src/templates/headless/actions/run.ts +6 -0
@@ -9,7 +9,7 @@ async function getFs() {
9
9
  }
10
10
  return _fs;
11
11
  }
12
- import { fileURLToPath } from "node:url";
12
+ import { fileURLToPath, pathToFileURL } from "node:url";
13
13
  /** Files to skip during auto-discovery (no extension). */
14
14
  const SKIP_FILES = new Set([
15
15
  "helpers",
@@ -176,6 +176,28 @@ function preserveActionFlags(entry) {
176
176
  }
177
177
  return out;
178
178
  }
179
+ function shouldRetryWithJiti(filePath, err) {
180
+ if (!filePath.endsWith(".ts"))
181
+ return false;
182
+ const candidate = err;
183
+ if (candidate?.code === "ERR_UNKNOWN_FILE_EXTENSION")
184
+ return true;
185
+ return /Unknown file extension ".ts"/.test(String(candidate?.message ?? ""));
186
+ }
187
+ async function importRuntimeSourceModule(filePath) {
188
+ try {
189
+ return await import(/* @vite-ignore */ pathToFileURL(filePath).href);
190
+ }
191
+ catch (err) {
192
+ if (!shouldRetryWithJiti(filePath, err))
193
+ throw err;
194
+ const { createJiti } = await import("jiti");
195
+ const jiti = createJiti(pathToFileURL(filePath).href, {
196
+ interopDefault: true,
197
+ });
198
+ return (await jiti.import(filePath));
199
+ }
200
+ }
179
201
  /**
180
202
  * Resolve the actions directory from the caller's context.
181
203
  *
@@ -259,7 +281,7 @@ async function loadActionsIntoRegistry(actionsDir, registry, skipExisting) {
259
281
  continue;
260
282
  const filePath = nodePath.join(actionsDir, file);
261
283
  try {
262
- const mod = await import(/* @vite-ignore */ filePath);
284
+ const mod = await importRuntimeSourceModule(filePath);
263
285
  if (mod.tool && typeof mod.run === "function") {
264
286
  registry[name] = {
265
287
  tool: mod.tool,
@@ -1 +1 @@
1
- {"version":3,"file":"action-discovery.js","sourceRoot":"","sources":["../../src/server/action-discovery.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Auto-discover actions from a template's actions/ directory.\n *\n * Scans for .ts/.js files and builds an action registry suitable for\n * `createAgentChatPlugin({ actions })`.\n *\n * Supports two action conventions:\n *\n * 1. **Full interface** — exports `tool: ActionTool` and `run(args): Promise<string>`.\n * These are used directly.\n *\n * 2. **CLI-style** — exports only `default async function(args: string[])`.\n * These are wrapped: args are converted from `Record<string, string>` to\n * `[\"--key\", \"value\", ...]`, console output is captured, and a tool\n * definition is synthesized from the action name.\n *\n * 3. **defineAction** — exports `default` from `defineAction()`. Has `tool` and `run`.\n *\n * Usage in agent-chat plugins:\n * ```ts\n * import { autoDiscoverActions } from \"@agent-native/core/server\";\n *\n * export default createAgentChatPlugin({\n * actions: () => autoDiscoverActions(import.meta.url),\n * });\n * ```\n */\nimport type { ActionEntry } from \"../agent/production-agent.js\";\nimport type { ActionTool } from \"../agent/types.js\";\nimport nodePath from \"node:path\";\nimport { captureCliOutput } from \"./cli-capture.js\";\n\n// Lazy fs — loaded via dynamic import() on first use.\n// Avoids require() which bundlers convert to createRequire() that crashes on CF Workers.\nlet _fs: typeof import(\"fs\") | undefined;\nasync function getFs(): Promise<typeof import(\"fs\")> {\n if (!_fs) {\n _fs = await import(\"node:fs\");\n }\n return _fs;\n}\nimport { fileURLToPath } from \"node:url\";\n\n/** Files to skip during auto-discovery (no extension). */\nconst SKIP_FILES = new Set([\n \"helpers\",\n \"run\",\n \"db-connect\",\n \"db-status\",\n \"registry\",\n]);\n\nfunction isRuntimeSourceFile(filename: string): boolean {\n if (!/\\.(ts|js)$/.test(filename)) return false;\n if (/\\.d\\.ts$/.test(filename)) return false;\n if (/\\.(test|spec)\\.(ts|js)$/.test(filename)) return false;\n return true;\n}\n\n/**\n * Global registry of actions contributed by published packages\n * (e.g. `@agent-native/dispatch`). Populated by `registerPackageActions()`\n * which the package calls from import side effects, then merged into\n * `autoDiscoverActions` after the template's local `actions/` directory.\n *\n * Ordering: template `actions/` files always win on name collision so\n * consumers can override a packaged action by dropping a same-named file\n * in their own `actions/` dir.\n */\nconst packageActionRegistry: Record<string, ActionEntry> = {};\n\n/**\n * Register a map of actions contributed by a published package.\n *\n * Called from a package's server entrypoint via import side effects:\n * ```ts\n * // packages/dispatch/src/server/index.ts\n * import { registerPackageActions } from \"@agent-native/core/server\";\n * import { actions } from \"../actions/index.js\";\n * registerPackageActions(actions);\n * ```\n *\n * Idempotent — re-registering the same name from the same import is a no-op\n * so HMR / repeated dynamic imports don't double-warn.\n */\nexport function registerPackageActions(\n actions: Record<string, ActionEntry>,\n): void {\n for (const [name, entry] of Object.entries(actions)) {\n if (packageActionRegistry[name]) continue;\n packageActionRegistry[name] = entry;\n }\n}\n\n/** Internal — used by `autoDiscoverActions`. Returns a shallow copy. */\nfunction getPackageActions(): Record<string, ActionEntry> {\n return { ...packageActionRegistry };\n}\n\n/**\n * Split a string into shell-like tokens, handling double and single quotes.\n * `--title \"My Page\" --content \"\"` → `[\"--title\", \"My Page\", \"--content\", \"\"]`\n */\nfunction splitShellArgs(input: string): string[] {\n const tokens: string[] = [];\n let current = \"\";\n let inDouble = false;\n let inSingle = false;\n let wasQuoted = false;\n\n for (let i = 0; i < input.length; i++) {\n const ch = input[i];\n if (ch === '\"' && !inSingle) {\n inDouble = !inDouble;\n wasQuoted = true;\n continue;\n }\n if (ch === \"'\" && !inDouble) {\n inSingle = !inSingle;\n wasQuoted = true;\n continue;\n }\n if ((ch === \" \" || ch === \"\\t\") && !inDouble && !inSingle) {\n if (current.length > 0 || wasQuoted) {\n tokens.push(current);\n }\n current = \"\";\n wasQuoted = false;\n continue;\n }\n current += ch;\n }\n if (current.length > 0 || wasQuoted) {\n tokens.push(current);\n }\n return tokens;\n}\n\n/**\n * Wrap a CLI-style action (that writes to console.log) as an ActionEntry\n * by capturing stdout/stderr and intercepting process.exit. Uses the\n * shared AsyncLocalStorage-backed capture so concurrent invocations do\n * not corrupt the global `console.log` / `process.stdout.write` /\n * `process.exit` pointers (see `cli-capture.ts`).\n */\nfunction wrapDefaultExport(\n name: string,\n defaultFn: (args: string[]) => Promise<void>,\n): ActionEntry {\n const tool: ActionTool = {\n description: `Run the \"${name}\" action. Pass arguments as key-value pairs.`,\n parameters: {\n type: \"object\",\n properties: {\n args: {\n type: \"string\",\n description:\n \"Space-separated CLI arguments (e.g. '--id abc --title Hello')\",\n },\n },\n },\n };\n\n return {\n tool,\n run: async (args: Record<string, string>): Promise<string> => {\n const cliArgs: string[] = [];\n // If only an \"args\" key was provided, split it into CLI tokens\n if (args.args && Object.keys(args).length === 1) {\n cliArgs.push(...splitShellArgs(args.args));\n } else {\n for (const [k, v] of Object.entries(args)) {\n cliArgs.push(`--${k}`, v);\n }\n }\n return captureCliOutput(() => defaultFn(cliArgs));\n },\n };\n}\n\nfunction preserveActionFlags(entry: Record<string, any>): Partial<ActionEntry> {\n const out: Partial<ActionEntry> = {};\n if (typeof entry.agentTool === \"boolean\") out.agentTool = entry.agentTool;\n if (typeof entry.requiresAuth === \"boolean\") {\n out.requiresAuth = entry.requiresAuth;\n }\n if (typeof entry.readOnly === \"boolean\") out.readOnly = entry.readOnly;\n if (typeof entry.parallelSafe === \"boolean\") {\n out.parallelSafe = entry.parallelSafe;\n }\n if (typeof entry.toolCallable === \"boolean\") {\n out.toolCallable = entry.toolCallable;\n }\n if (\n entry.publicAgent &&\n typeof entry.publicAgent === \"object\" &&\n !Array.isArray(entry.publicAgent)\n ) {\n out.publicAgent = entry.publicAgent;\n }\n if (typeof entry.link === \"function\") {\n out.link = entry.link;\n }\n if (\n entry.mcpApp &&\n typeof entry.mcpApp === \"object\" &&\n !Array.isArray(entry.mcpApp)\n ) {\n out.mcpApp = entry.mcpApp;\n }\n if (\n entry.chatUI &&\n typeof entry.chatUI === \"object\" &&\n !Array.isArray(entry.chatUI)\n ) {\n out.chatUI = entry.chatUI;\n }\n if (\n typeof entry.needsApproval === \"boolean\" ||\n typeof entry.needsApproval === \"function\"\n ) {\n out.needsApproval = entry.needsApproval;\n }\n return out;\n}\n\n/**\n * Resolve the actions directory from the caller's context.\n *\n * @param from - Either an `import.meta.url` (file:// URL from a plugin file),\n * an absolute directory path, or \"auto\" to use `process.cwd() + \"/actions\"`.\n * When an import.meta.url is provided, the actions directory is resolved as\n * `../../actions/` relative to the caller (typically `server/plugins/agent-chat.ts`).\n * If the resolved directory doesn't exist, falls back to `../../scripts/` for\n * backwards compatibility, then to `process.cwd() + \"/actions\"`.\n */\nasync function resolveActionsDir(from: string): Promise<string> {\n const fs = await getFs();\n const exists = (p: string) => {\n try {\n return fs.existsSync(p);\n } catch {\n return false;\n }\n };\n // On edge runtimes (e.g. Cloudflare Workers), import.meta.url may be\n // undefined after bundling. Fall back to cwd-based discovery.\n if (!from) {\n const cwdActions = nodePath.join(process.cwd(), \"actions\");\n if (exists(cwdActions)) return cwdActions;\n return nodePath.join(process.cwd(), \"scripts\");\n }\n if (from.startsWith(\"file://\") || from.startsWith(\"file:///\")) {\n const callerPath = fileURLToPath(from);\n const callerDir = nodePath.dirname(callerPath);\n const actionsResolved = nodePath.resolve(callerDir, \"../../actions\");\n if (exists(actionsResolved)) return actionsResolved;\n const scriptsResolved = nodePath.resolve(callerDir, \"../../scripts\");\n if (exists(scriptsResolved)) return scriptsResolved;\n const cwdActions = nodePath.join(process.cwd(), \"actions\");\n if (exists(cwdActions)) return cwdActions;\n return nodePath.join(process.cwd(), \"scripts\");\n }\n if (from === \"auto\") {\n const cwdActions = nodePath.join(process.cwd(), \"actions\");\n if (exists(cwdActions)) return cwdActions;\n return nodePath.join(process.cwd(), \"scripts\");\n }\n return nodePath.resolve(from);\n}\n\n/**\n * Load actions from a single directory into the given registry. Shared by\n * both the template-actions discovery path and the workspace-core actions\n * layer. When `skipExisting` is true, an entry with the same name that's\n * already in the registry is left untouched (template-wins on collision).\n */\nasync function loadActionsIntoRegistry(\n actionsDir: string,\n registry: Record<string, ActionEntry>,\n skipExisting: boolean,\n): Promise<void> {\n let files: string[];\n try {\n const fs = await getFs();\n if (!fs.existsSync(actionsDir)) return;\n files = fs.readdirSync(actionsDir);\n } catch {\n return;\n }\n\n const actionFiles = files.filter((f) => {\n if (!isRuntimeSourceFile(f)) return false;\n const name = f.replace(/\\.(ts|js)$/, \"\");\n if (name.startsWith(\"_\")) return false;\n if (SKIP_FILES.has(name)) return false;\n return true;\n });\n\n for (const file of actionFiles) {\n const name = file.replace(/\\.(ts|js)$/, \"\");\n if (skipExisting && registry[name]) continue;\n\n const filePath = nodePath.join(actionsDir, file);\n try {\n const mod = await import(/* @vite-ignore */ filePath);\n\n if (mod.tool && typeof mod.run === \"function\") {\n registry[name] = {\n tool: mod.tool,\n run: mod.run,\n ...(mod.http !== undefined ? { http: mod.http } : {}),\n ...preserveActionFlags(mod),\n };\n } else if (\n mod.default &&\n typeof mod.default === \"object\" &&\n mod.default.tool &&\n typeof mod.default.run === \"function\"\n ) {\n registry[name] = {\n tool: mod.default.tool,\n run: mod.default.run,\n ...(mod.default.http !== undefined ? { http: mod.default.http } : {}),\n ...preserveActionFlags(mod.default),\n };\n } else if (typeof mod.default === \"function\") {\n registry[name] = wrapDefaultExport(name, mod.default);\n }\n } catch (err) {\n // CLI-style scripts (top-level execution) throw on import — expected,\n // they're available via `pnpm action <name>` / shell instead. But a\n // syntax error, bad import, or malformed defineAction in a real action\n // file lands here too and would silently vanish from the agent's tools.\n // Warn so a broken action file is diagnosable instead of mysteriously\n // missing.\n const msg =\n err instanceof Error ? (err.stack ?? err.message) : String(err);\n console.warn(\n `[action-discovery] Skipped \"${file}\" — failed to import. If this is an ` +\n `agent action (not a CLI script), it will be missing from the agent's tools:\\n${msg}`,\n );\n }\n }\n}\n\n/**\n * Normalize a pre-bundled static action registry (name → raw module) into\n * the `Record<string, ActionEntry>` shape the agent-chat plugin expects.\n *\n * Used by `autoDiscoverActions` when `.generated/actions-registry.ts` is\n * present so that Nitro-bundled serverless functions (Netlify, Vercel,\n * AWS-Lambda) can serve `/_agent-native/actions/*` routes without relying\n * on a filesystem scan that doesn't work in bundled output.\n */\nexport function loadActionsFromStaticRegistry(\n modules: Record<string, unknown>,\n): Record<string, ActionEntry> {\n const registry: Record<string, ActionEntry> = {};\n for (const [name, raw] of Object.entries(modules)) {\n const mod = raw as Record<string, any> | null | undefined;\n if (!mod) continue;\n\n if (mod.tool && typeof mod.run === \"function\") {\n registry[name] = {\n tool: mod.tool,\n run: mod.run,\n ...(mod.http !== undefined ? { http: mod.http } : {}),\n ...preserveActionFlags(mod),\n };\n continue;\n }\n\n const def = mod.default;\n if (\n def &&\n typeof def === \"object\" &&\n def.tool &&\n typeof def.run === \"function\"\n ) {\n registry[name] = {\n tool: def.tool,\n run: def.run,\n ...(def.http !== undefined ? { http: def.http } : {}),\n ...preserveActionFlags(def),\n };\n continue;\n }\n\n if (typeof def === \"function\") {\n registry[name] = wrapDefaultExport(name, def);\n }\n }\n return registry;\n}\n\n/**\n * Auto-discover actions from a directory.\n *\n * Merges in any actions from the enterprise workspace core (if present in\n * the ancestor chain). Template actions take precedence over workspace-core\n * actions on name collision, so an app can override an enterprise-wide\n * action by dropping a same-named file under its own `actions/`.\n *\n * Note: this helper uses a filesystem scan, which works in dev and in\n * non-bundled Node deployments. In bundled serverless functions (Nitro's\n * netlify / vercel / aws-lambda presets) the `actions/` directory is not\n * on disk at runtime; templates should pass the static registry generated\n * by the Vite plugin to `createAgentChatPlugin({ actions })` instead, so\n * the bundler sees static imports and pulls every action into the bundle.\n *\n * @param from - The caller's `import.meta.url` or an absolute path to the\n * actions directory.\n * @returns A record mapping action names to ActionEntry objects, suitable for\n * passing to `createAgentChatPlugin({ actions })`.\n */\nexport async function autoDiscoverActions(\n from: string,\n): Promise<Record<string, ActionEntry>> {\n const actionsDir = await resolveActionsDir(from);\n const registry: Record<string, ActionEntry> = {};\n\n // 1. Template actions first — these are the authoritative layer for the\n // current app and must override any workspace-core entry with the same\n // name.\n try {\n await loadActionsIntoRegistry(actionsDir, registry, false);\n } catch (err: any) {\n console.warn(\n `[autoDiscoverActions] Could not read actions directory: ${actionsDir} — ${err?.message}`,\n );\n }\n\n // 1b. Fallback: if filesystem discovery found no template actions (common\n // in bundled serverless environments like Netlify/Vercel where the\n // actions/ directory doesn't exist on disk), try importing the\n // generated static registry at .generated/actions-registry.\n //\n // This prevents the silent-empty-tools footgun where the agent has no\n // template actions and falls back to generic tools like web-request.\n // Prefer `loadActionsFromStaticRegistry` over `autoDiscoverActions` for\n // production reliability — this fallback is a safety net, not the\n // primary path.\n if (Object.keys(registry).length === 0 && from) {\n try {\n let registryPath: string;\n if (from.startsWith(\"file://\") || from.startsWith(\"file:///\")) {\n const callerDir = nodePath.dirname(fileURLToPath(from));\n registryPath = nodePath.resolve(\n callerDir,\n \"../../.generated/actions-registry.js\",\n );\n } else {\n registryPath = nodePath.resolve(\n from,\n \"../.generated/actions-registry.js\",\n );\n }\n const mod = await import(/* @vite-ignore */ registryPath);\n const staticEntries = loadActionsFromStaticRegistry(mod.default || mod);\n Object.assign(registry, staticEntries);\n if (Object.keys(staticEntries).length > 0) {\n console.log(\n `[autoDiscoverActions] Filesystem scan found 0 actions — loaded ${Object.keys(staticEntries).length} from .generated/actions-registry.ts instead. ` +\n `Consider switching to loadActionsFromStaticRegistry(actionsRegistry) for production reliability.`,\n );\n }\n } catch {\n // No generated registry available — registry stays empty.\n }\n }\n\n // If still empty after all fallbacks, warn loudly.\n if (Object.keys(registry).length === 0) {\n console.warn(\n `[autoDiscoverActions] WARNING: No template actions found! ` +\n `The agent will have no template-specific tools. ` +\n `If in production, switch from autoDiscoverActions to loadActionsFromStaticRegistry. ` +\n `See: https://docs.agent-native.com/actions#static-registry`,\n );\n }\n\n // 1c. Package-registered actions — contributed by published packages\n // (e.g. @agent-native/dispatch) via `registerPackageActions()` from\n // import side effects. Merged with skip-existing so the template's\n // own actions/ files always win on name collision.\n for (const [name, entry] of Object.entries(getPackageActions())) {\n if (registry[name]) continue;\n registry[name] = entry;\n }\n\n // 2. Workspace-core actions — merged in with skipExisting so they can't\n // overwrite template entries.\n try {\n const { getWorkspaceCoreExports } =\n await import(\"../deploy/workspace-core.js\");\n const ws = await getWorkspaceCoreExports(process.cwd());\n if (ws && ws.actionsDir) {\n await loadActionsIntoRegistry(ws.actionsDir, registry, true);\n }\n } catch {\n // workspace-core discovery unavailable (e.g. edge runtime) — skip.\n }\n\n // 3. Framework-level sharing + file-upload actions — always available to any\n // template. Merged with skipExisting so templates can override by\n // providing a same-named file.\n try {\n await mergeCoreSharingActions(registry);\n } catch {\n // Ignore — templates without sharing still work.\n }\n\n return registry;\n}\n\nexport async function mergeCoreSharingActions(\n registry: Record<string, ActionEntry>,\n): Promise<void> {\n const entries: Array<[string, () => Promise<any>]> = [\n [\"share-resource\", () => import(\"../sharing/actions/share-resource.js\")],\n [\n \"unshare-resource\",\n () => import(\"../sharing/actions/unshare-resource.js\"),\n ],\n [\n \"list-resource-shares\",\n () => import(\"../sharing/actions/list-resource-shares.js\"),\n ],\n [\n \"set-resource-visibility\",\n () => import(\"../sharing/actions/set-resource-visibility.js\"),\n ],\n [\"upload-image\", () => import(\"../file-upload/actions/upload-image.js\")],\n [\n \"context-manifest-get\",\n () => import(\"../agent/context-xray/actions/context-manifest-get.js\"),\n ],\n [\n \"context-pin\",\n () => import(\"../agent/context-xray/actions/context-pin.js\"),\n ],\n [\n \"context-evict\",\n () => import(\"../agent/context-xray/actions/context-evict.js\"),\n ],\n [\n \"context-restore\",\n () => import(\"../agent/context-xray/actions/context-restore.js\"),\n ],\n [\n \"context-report\",\n () => import(\"../agent/context-xray/actions/context-report.js\"),\n ],\n [\n \"change-appearance\",\n () => import(\"../appearance/actions/change-appearance.js\"),\n ],\n [\"toggle-demo-mode\", () => import(\"../demo/actions/toggle-demo-mode.js\")],\n // Org service tokens (CI credentials, e.g. PLAN_RECAP_TOKEN). Mint/revoke\n // are toolCallable:false — preserved via preserveActionFlags below.\n [\n \"create-org-service-token\",\n () => import(\"../mcp/actions/create-org-service-token.js\"),\n ],\n [\n \"list-org-service-tokens\",\n () => import(\"../mcp/actions/list-org-service-tokens.js\"),\n ],\n [\n \"revoke-org-service-token\",\n () => import(\"../mcp/actions/revoke-org-service-token.js\"),\n ],\n ];\n for (const [name, loader] of entries) {\n if (registry[name]) continue;\n try {\n const mod = await loader();\n const def = mod.default;\n if (def && def.tool && typeof def.run === \"function\") {\n registry[name] = {\n tool: def.tool,\n run: def.run,\n ...(def.http !== undefined ? { http: def.http } : {}),\n // Carry security-relevant flags (toolCallable, publicAgent, link,\n // mcpApp) plus readOnly/parallelSafe. Without this, the sharing\n // actions' `toolCallable: false` (audit-H5) is dropped and the\n // tools-iframe bridge 403 in action-routes.ts never fires.\n ...preserveActionFlags(def),\n };\n }\n } catch {\n // Skip any sharing action that fails to import.\n }\n }\n}\n\n/** @deprecated Use `autoDiscoverActions` instead */\nexport const autoDiscoverScripts = autoDiscoverActions;\n"]}
1
+ {"version":3,"file":"action-discovery.js","sourceRoot":"","sources":["../../src/server/action-discovery.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Auto-discover actions from a template's actions/ directory.\n *\n * Scans for .ts/.js files and builds an action registry suitable for\n * `createAgentChatPlugin({ actions })`.\n *\n * Supports two action conventions:\n *\n * 1. **Full interface** — exports `tool: ActionTool` and `run(args): Promise<string>`.\n * These are used directly.\n *\n * 2. **CLI-style** — exports only `default async function(args: string[])`.\n * These are wrapped: args are converted from `Record<string, string>` to\n * `[\"--key\", \"value\", ...]`, console output is captured, and a tool\n * definition is synthesized from the action name.\n *\n * 3. **defineAction** — exports `default` from `defineAction()`. Has `tool` and `run`.\n *\n * Usage in agent-chat plugins:\n * ```ts\n * import { autoDiscoverActions } from \"@agent-native/core/server\";\n *\n * export default createAgentChatPlugin({\n * actions: () => autoDiscoverActions(import.meta.url),\n * });\n * ```\n */\nimport type { ActionEntry } from \"../agent/production-agent.js\";\nimport type { ActionTool } from \"../agent/types.js\";\nimport nodePath from \"node:path\";\nimport { captureCliOutput } from \"./cli-capture.js\";\n\n// Lazy fs — loaded via dynamic import() on first use.\n// Avoids require() which bundlers convert to createRequire() that crashes on CF Workers.\nlet _fs: typeof import(\"fs\") | undefined;\nasync function getFs(): Promise<typeof import(\"fs\")> {\n if (!_fs) {\n _fs = await import(\"node:fs\");\n }\n return _fs;\n}\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\n\n/** Files to skip during auto-discovery (no extension). */\nconst SKIP_FILES = new Set([\n \"helpers\",\n \"run\",\n \"db-connect\",\n \"db-status\",\n \"registry\",\n]);\n\nfunction isRuntimeSourceFile(filename: string): boolean {\n if (!/\\.(ts|js)$/.test(filename)) return false;\n if (/\\.d\\.ts$/.test(filename)) return false;\n if (/\\.(test|spec)\\.(ts|js)$/.test(filename)) return false;\n return true;\n}\n\n/**\n * Global registry of actions contributed by published packages\n * (e.g. `@agent-native/dispatch`). Populated by `registerPackageActions()`\n * which the package calls from import side effects, then merged into\n * `autoDiscoverActions` after the template's local `actions/` directory.\n *\n * Ordering: template `actions/` files always win on name collision so\n * consumers can override a packaged action by dropping a same-named file\n * in their own `actions/` dir.\n */\nconst packageActionRegistry: Record<string, ActionEntry> = {};\n\n/**\n * Register a map of actions contributed by a published package.\n *\n * Called from a package's server entrypoint via import side effects:\n * ```ts\n * // packages/dispatch/src/server/index.ts\n * import { registerPackageActions } from \"@agent-native/core/server\";\n * import { actions } from \"../actions/index.js\";\n * registerPackageActions(actions);\n * ```\n *\n * Idempotent — re-registering the same name from the same import is a no-op\n * so HMR / repeated dynamic imports don't double-warn.\n */\nexport function registerPackageActions(\n actions: Record<string, ActionEntry>,\n): void {\n for (const [name, entry] of Object.entries(actions)) {\n if (packageActionRegistry[name]) continue;\n packageActionRegistry[name] = entry;\n }\n}\n\n/** Internal — used by `autoDiscoverActions`. Returns a shallow copy. */\nfunction getPackageActions(): Record<string, ActionEntry> {\n return { ...packageActionRegistry };\n}\n\n/**\n * Split a string into shell-like tokens, handling double and single quotes.\n * `--title \"My Page\" --content \"\"` → `[\"--title\", \"My Page\", \"--content\", \"\"]`\n */\nfunction splitShellArgs(input: string): string[] {\n const tokens: string[] = [];\n let current = \"\";\n let inDouble = false;\n let inSingle = false;\n let wasQuoted = false;\n\n for (let i = 0; i < input.length; i++) {\n const ch = input[i];\n if (ch === '\"' && !inSingle) {\n inDouble = !inDouble;\n wasQuoted = true;\n continue;\n }\n if (ch === \"'\" && !inDouble) {\n inSingle = !inSingle;\n wasQuoted = true;\n continue;\n }\n if ((ch === \" \" || ch === \"\\t\") && !inDouble && !inSingle) {\n if (current.length > 0 || wasQuoted) {\n tokens.push(current);\n }\n current = \"\";\n wasQuoted = false;\n continue;\n }\n current += ch;\n }\n if (current.length > 0 || wasQuoted) {\n tokens.push(current);\n }\n return tokens;\n}\n\n/**\n * Wrap a CLI-style action (that writes to console.log) as an ActionEntry\n * by capturing stdout/stderr and intercepting process.exit. Uses the\n * shared AsyncLocalStorage-backed capture so concurrent invocations do\n * not corrupt the global `console.log` / `process.stdout.write` /\n * `process.exit` pointers (see `cli-capture.ts`).\n */\nfunction wrapDefaultExport(\n name: string,\n defaultFn: (args: string[]) => Promise<void>,\n): ActionEntry {\n const tool: ActionTool = {\n description: `Run the \"${name}\" action. Pass arguments as key-value pairs.`,\n parameters: {\n type: \"object\",\n properties: {\n args: {\n type: \"string\",\n description:\n \"Space-separated CLI arguments (e.g. '--id abc --title Hello')\",\n },\n },\n },\n };\n\n return {\n tool,\n run: async (args: Record<string, string>): Promise<string> => {\n const cliArgs: string[] = [];\n // If only an \"args\" key was provided, split it into CLI tokens\n if (args.args && Object.keys(args).length === 1) {\n cliArgs.push(...splitShellArgs(args.args));\n } else {\n for (const [k, v] of Object.entries(args)) {\n cliArgs.push(`--${k}`, v);\n }\n }\n return captureCliOutput(() => defaultFn(cliArgs));\n },\n };\n}\n\nfunction preserveActionFlags(entry: Record<string, any>): Partial<ActionEntry> {\n const out: Partial<ActionEntry> = {};\n if (typeof entry.agentTool === \"boolean\") out.agentTool = entry.agentTool;\n if (typeof entry.requiresAuth === \"boolean\") {\n out.requiresAuth = entry.requiresAuth;\n }\n if (typeof entry.readOnly === \"boolean\") out.readOnly = entry.readOnly;\n if (typeof entry.parallelSafe === \"boolean\") {\n out.parallelSafe = entry.parallelSafe;\n }\n if (typeof entry.toolCallable === \"boolean\") {\n out.toolCallable = entry.toolCallable;\n }\n if (\n entry.publicAgent &&\n typeof entry.publicAgent === \"object\" &&\n !Array.isArray(entry.publicAgent)\n ) {\n out.publicAgent = entry.publicAgent;\n }\n if (typeof entry.link === \"function\") {\n out.link = entry.link;\n }\n if (\n entry.mcpApp &&\n typeof entry.mcpApp === \"object\" &&\n !Array.isArray(entry.mcpApp)\n ) {\n out.mcpApp = entry.mcpApp;\n }\n if (\n entry.chatUI &&\n typeof entry.chatUI === \"object\" &&\n !Array.isArray(entry.chatUI)\n ) {\n out.chatUI = entry.chatUI;\n }\n if (\n typeof entry.needsApproval === \"boolean\" ||\n typeof entry.needsApproval === \"function\"\n ) {\n out.needsApproval = entry.needsApproval;\n }\n return out;\n}\n\nfunction shouldRetryWithJiti(filePath: string, err: unknown): boolean {\n if (!filePath.endsWith(\".ts\")) return false;\n const candidate = err as { code?: unknown; message?: unknown } | undefined;\n if (candidate?.code === \"ERR_UNKNOWN_FILE_EXTENSION\") return true;\n return /Unknown file extension \".ts\"/.test(String(candidate?.message ?? \"\"));\n}\n\nasync function importRuntimeSourceModule(\n filePath: string,\n): Promise<Record<string, any>> {\n try {\n return await import(/* @vite-ignore */ pathToFileURL(filePath).href);\n } catch (err) {\n if (!shouldRetryWithJiti(filePath, err)) throw err;\n\n const { createJiti } = await import(\"jiti\");\n const jiti = createJiti(pathToFileURL(filePath).href, {\n interopDefault: true,\n });\n return (await jiti.import(filePath)) as Record<string, any>;\n }\n}\n\n/**\n * Resolve the actions directory from the caller's context.\n *\n * @param from - Either an `import.meta.url` (file:// URL from a plugin file),\n * an absolute directory path, or \"auto\" to use `process.cwd() + \"/actions\"`.\n * When an import.meta.url is provided, the actions directory is resolved as\n * `../../actions/` relative to the caller (typically `server/plugins/agent-chat.ts`).\n * If the resolved directory doesn't exist, falls back to `../../scripts/` for\n * backwards compatibility, then to `process.cwd() + \"/actions\"`.\n */\nasync function resolveActionsDir(from: string): Promise<string> {\n const fs = await getFs();\n const exists = (p: string) => {\n try {\n return fs.existsSync(p);\n } catch {\n return false;\n }\n };\n // On edge runtimes (e.g. Cloudflare Workers), import.meta.url may be\n // undefined after bundling. Fall back to cwd-based discovery.\n if (!from) {\n const cwdActions = nodePath.join(process.cwd(), \"actions\");\n if (exists(cwdActions)) return cwdActions;\n return nodePath.join(process.cwd(), \"scripts\");\n }\n if (from.startsWith(\"file://\") || from.startsWith(\"file:///\")) {\n const callerPath = fileURLToPath(from);\n const callerDir = nodePath.dirname(callerPath);\n const actionsResolved = nodePath.resolve(callerDir, \"../../actions\");\n if (exists(actionsResolved)) return actionsResolved;\n const scriptsResolved = nodePath.resolve(callerDir, \"../../scripts\");\n if (exists(scriptsResolved)) return scriptsResolved;\n const cwdActions = nodePath.join(process.cwd(), \"actions\");\n if (exists(cwdActions)) return cwdActions;\n return nodePath.join(process.cwd(), \"scripts\");\n }\n if (from === \"auto\") {\n const cwdActions = nodePath.join(process.cwd(), \"actions\");\n if (exists(cwdActions)) return cwdActions;\n return nodePath.join(process.cwd(), \"scripts\");\n }\n return nodePath.resolve(from);\n}\n\n/**\n * Load actions from a single directory into the given registry. Shared by\n * both the template-actions discovery path and the workspace-core actions\n * layer. When `skipExisting` is true, an entry with the same name that's\n * already in the registry is left untouched (template-wins on collision).\n */\nasync function loadActionsIntoRegistry(\n actionsDir: string,\n registry: Record<string, ActionEntry>,\n skipExisting: boolean,\n): Promise<void> {\n let files: string[];\n try {\n const fs = await getFs();\n if (!fs.existsSync(actionsDir)) return;\n files = fs.readdirSync(actionsDir);\n } catch {\n return;\n }\n\n const actionFiles = files.filter((f) => {\n if (!isRuntimeSourceFile(f)) return false;\n const name = f.replace(/\\.(ts|js)$/, \"\");\n if (name.startsWith(\"_\")) return false;\n if (SKIP_FILES.has(name)) return false;\n return true;\n });\n\n for (const file of actionFiles) {\n const name = file.replace(/\\.(ts|js)$/, \"\");\n if (skipExisting && registry[name]) continue;\n\n const filePath = nodePath.join(actionsDir, file);\n try {\n const mod = await importRuntimeSourceModule(filePath);\n\n if (mod.tool && typeof mod.run === \"function\") {\n registry[name] = {\n tool: mod.tool,\n run: mod.run,\n ...(mod.http !== undefined ? { http: mod.http } : {}),\n ...preserveActionFlags(mod),\n };\n } else if (\n mod.default &&\n typeof mod.default === \"object\" &&\n mod.default.tool &&\n typeof mod.default.run === \"function\"\n ) {\n registry[name] = {\n tool: mod.default.tool,\n run: mod.default.run,\n ...(mod.default.http !== undefined ? { http: mod.default.http } : {}),\n ...preserveActionFlags(mod.default),\n };\n } else if (typeof mod.default === \"function\") {\n registry[name] = wrapDefaultExport(name, mod.default);\n }\n } catch (err) {\n // CLI-style scripts (top-level execution) throw on import — expected,\n // they're available via `pnpm action <name>` / shell instead. But a\n // syntax error, bad import, or malformed defineAction in a real action\n // file lands here too and would silently vanish from the agent's tools.\n // Warn so a broken action file is diagnosable instead of mysteriously\n // missing.\n const msg =\n err instanceof Error ? (err.stack ?? err.message) : String(err);\n console.warn(\n `[action-discovery] Skipped \"${file}\" — failed to import. If this is an ` +\n `agent action (not a CLI script), it will be missing from the agent's tools:\\n${msg}`,\n );\n }\n }\n}\n\n/**\n * Normalize a pre-bundled static action registry (name → raw module) into\n * the `Record<string, ActionEntry>` shape the agent-chat plugin expects.\n *\n * Used by `autoDiscoverActions` when `.generated/actions-registry.ts` is\n * present so that Nitro-bundled serverless functions (Netlify, Vercel,\n * AWS-Lambda) can serve `/_agent-native/actions/*` routes without relying\n * on a filesystem scan that doesn't work in bundled output.\n */\nexport function loadActionsFromStaticRegistry(\n modules: Record<string, unknown>,\n): Record<string, ActionEntry> {\n const registry: Record<string, ActionEntry> = {};\n for (const [name, raw] of Object.entries(modules)) {\n const mod = raw as Record<string, any> | null | undefined;\n if (!mod) continue;\n\n if (mod.tool && typeof mod.run === \"function\") {\n registry[name] = {\n tool: mod.tool,\n run: mod.run,\n ...(mod.http !== undefined ? { http: mod.http } : {}),\n ...preserveActionFlags(mod),\n };\n continue;\n }\n\n const def = mod.default;\n if (\n def &&\n typeof def === \"object\" &&\n def.tool &&\n typeof def.run === \"function\"\n ) {\n registry[name] = {\n tool: def.tool,\n run: def.run,\n ...(def.http !== undefined ? { http: def.http } : {}),\n ...preserveActionFlags(def),\n };\n continue;\n }\n\n if (typeof def === \"function\") {\n registry[name] = wrapDefaultExport(name, def);\n }\n }\n return registry;\n}\n\n/**\n * Auto-discover actions from a directory.\n *\n * Merges in any actions from the enterprise workspace core (if present in\n * the ancestor chain). Template actions take precedence over workspace-core\n * actions on name collision, so an app can override an enterprise-wide\n * action by dropping a same-named file under its own `actions/`.\n *\n * Note: this helper uses a filesystem scan, which works in dev and in\n * non-bundled Node deployments. In bundled serverless functions (Nitro's\n * netlify / vercel / aws-lambda presets) the `actions/` directory is not\n * on disk at runtime; templates should pass the static registry generated\n * by the Vite plugin to `createAgentChatPlugin({ actions })` instead, so\n * the bundler sees static imports and pulls every action into the bundle.\n *\n * @param from - The caller's `import.meta.url` or an absolute path to the\n * actions directory.\n * @returns A record mapping action names to ActionEntry objects, suitable for\n * passing to `createAgentChatPlugin({ actions })`.\n */\nexport async function autoDiscoverActions(\n from: string,\n): Promise<Record<string, ActionEntry>> {\n const actionsDir = await resolveActionsDir(from);\n const registry: Record<string, ActionEntry> = {};\n\n // 1. Template actions first — these are the authoritative layer for the\n // current app and must override any workspace-core entry with the same\n // name.\n try {\n await loadActionsIntoRegistry(actionsDir, registry, false);\n } catch (err: any) {\n console.warn(\n `[autoDiscoverActions] Could not read actions directory: ${actionsDir} — ${err?.message}`,\n );\n }\n\n // 1b. Fallback: if filesystem discovery found no template actions (common\n // in bundled serverless environments like Netlify/Vercel where the\n // actions/ directory doesn't exist on disk), try importing the\n // generated static registry at .generated/actions-registry.\n //\n // This prevents the silent-empty-tools footgun where the agent has no\n // template actions and falls back to generic tools like web-request.\n // Prefer `loadActionsFromStaticRegistry` over `autoDiscoverActions` for\n // production reliability — this fallback is a safety net, not the\n // primary path.\n if (Object.keys(registry).length === 0 && from) {\n try {\n let registryPath: string;\n if (from.startsWith(\"file://\") || from.startsWith(\"file:///\")) {\n const callerDir = nodePath.dirname(fileURLToPath(from));\n registryPath = nodePath.resolve(\n callerDir,\n \"../../.generated/actions-registry.js\",\n );\n } else {\n registryPath = nodePath.resolve(\n from,\n \"../.generated/actions-registry.js\",\n );\n }\n const mod = await import(/* @vite-ignore */ registryPath);\n const staticEntries = loadActionsFromStaticRegistry(mod.default || mod);\n Object.assign(registry, staticEntries);\n if (Object.keys(staticEntries).length > 0) {\n console.log(\n `[autoDiscoverActions] Filesystem scan found 0 actions — loaded ${Object.keys(staticEntries).length} from .generated/actions-registry.ts instead. ` +\n `Consider switching to loadActionsFromStaticRegistry(actionsRegistry) for production reliability.`,\n );\n }\n } catch {\n // No generated registry available — registry stays empty.\n }\n }\n\n // If still empty after all fallbacks, warn loudly.\n if (Object.keys(registry).length === 0) {\n console.warn(\n `[autoDiscoverActions] WARNING: No template actions found! ` +\n `The agent will have no template-specific tools. ` +\n `If in production, switch from autoDiscoverActions to loadActionsFromStaticRegistry. ` +\n `See: https://docs.agent-native.com/actions#static-registry`,\n );\n }\n\n // 1c. Package-registered actions — contributed by published packages\n // (e.g. @agent-native/dispatch) via `registerPackageActions()` from\n // import side effects. Merged with skip-existing so the template's\n // own actions/ files always win on name collision.\n for (const [name, entry] of Object.entries(getPackageActions())) {\n if (registry[name]) continue;\n registry[name] = entry;\n }\n\n // 2. Workspace-core actions — merged in with skipExisting so they can't\n // overwrite template entries.\n try {\n const { getWorkspaceCoreExports } =\n await import(\"../deploy/workspace-core.js\");\n const ws = await getWorkspaceCoreExports(process.cwd());\n if (ws && ws.actionsDir) {\n await loadActionsIntoRegistry(ws.actionsDir, registry, true);\n }\n } catch {\n // workspace-core discovery unavailable (e.g. edge runtime) — skip.\n }\n\n // 3. Framework-level sharing + file-upload actions — always available to any\n // template. Merged with skipExisting so templates can override by\n // providing a same-named file.\n try {\n await mergeCoreSharingActions(registry);\n } catch {\n // Ignore — templates without sharing still work.\n }\n\n return registry;\n}\n\nexport async function mergeCoreSharingActions(\n registry: Record<string, ActionEntry>,\n): Promise<void> {\n const entries: Array<[string, () => Promise<any>]> = [\n [\"share-resource\", () => import(\"../sharing/actions/share-resource.js\")],\n [\n \"unshare-resource\",\n () => import(\"../sharing/actions/unshare-resource.js\"),\n ],\n [\n \"list-resource-shares\",\n () => import(\"../sharing/actions/list-resource-shares.js\"),\n ],\n [\n \"set-resource-visibility\",\n () => import(\"../sharing/actions/set-resource-visibility.js\"),\n ],\n [\"upload-image\", () => import(\"../file-upload/actions/upload-image.js\")],\n [\n \"context-manifest-get\",\n () => import(\"../agent/context-xray/actions/context-manifest-get.js\"),\n ],\n [\n \"context-pin\",\n () => import(\"../agent/context-xray/actions/context-pin.js\"),\n ],\n [\n \"context-evict\",\n () => import(\"../agent/context-xray/actions/context-evict.js\"),\n ],\n [\n \"context-restore\",\n () => import(\"../agent/context-xray/actions/context-restore.js\"),\n ],\n [\n \"context-report\",\n () => import(\"../agent/context-xray/actions/context-report.js\"),\n ],\n [\n \"change-appearance\",\n () => import(\"../appearance/actions/change-appearance.js\"),\n ],\n [\"toggle-demo-mode\", () => import(\"../demo/actions/toggle-demo-mode.js\")],\n // Org service tokens (CI credentials, e.g. PLAN_RECAP_TOKEN). Mint/revoke\n // are toolCallable:false — preserved via preserveActionFlags below.\n [\n \"create-org-service-token\",\n () => import(\"../mcp/actions/create-org-service-token.js\"),\n ],\n [\n \"list-org-service-tokens\",\n () => import(\"../mcp/actions/list-org-service-tokens.js\"),\n ],\n [\n \"revoke-org-service-token\",\n () => import(\"../mcp/actions/revoke-org-service-token.js\"),\n ],\n ];\n for (const [name, loader] of entries) {\n if (registry[name]) continue;\n try {\n const mod = await loader();\n const def = mod.default;\n if (def && def.tool && typeof def.run === \"function\") {\n registry[name] = {\n tool: def.tool,\n run: def.run,\n ...(def.http !== undefined ? { http: def.http } : {}),\n // Carry security-relevant flags (toolCallable, publicAgent, link,\n // mcpApp) plus readOnly/parallelSafe. Without this, the sharing\n // actions' `toolCallable: false` (audit-H5) is dropped and the\n // tools-iframe bridge 403 in action-routes.ts never fires.\n ...preserveActionFlags(def),\n };\n }\n } catch {\n // Skip any sharing action that fails to import.\n }\n }\n}\n\n/** @deprecated Use `autoDiscoverActions` instead */\nexport const autoDiscoverScripts = autoDiscoverActions;\n"]}
@@ -2,8 +2,8 @@
2
2
  export declare const OPEN_ROUTE_SUBPATH = "/open";
3
3
  /** Custom URL scheme the desktop app registers (`agentnative://open?...`). */
4
4
  export declare const DESKTOP_OPEN_URL = "agentnative://open";
5
- /** VS Code extension URI used by builderio.agent-native to open a webview. */
6
- export declare const VSCODE_OPEN_URL = "vscode://builderio.agent-native/open";
5
+ /** VS Code extension URI used by Builder.agent-native to open a webview. */
6
+ export declare const VSCODE_OPEN_URL = "vscode://builder.agent-native/open";
7
7
  export interface DeepLinkInput {
8
8
  /** App id (informational + multi-app/desktop routing), e.g. "mail". */
9
9
  app?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"deep-link.d.ts","sourceRoot":"","sources":["../../src/server/deep-link.ts"],"names":[],"mappings":"AAwBA,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAE1C,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,uBAAuB,CAAC;AAErD,8EAA8E;AAC9E,eAAO,MAAM,eAAe,yCAAyC,CAAC;AAEtE,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb;yEACqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACtE;uDACmD;IACnD,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAcD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAI1D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,MAAM,CAMR;AAgBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAI1D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAIzD"}
1
+ {"version":3,"file":"deep-link.d.ts","sourceRoot":"","sources":["../../src/server/deep-link.ts"],"names":[],"mappings":"AAwBA,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAE1C,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,uBAAuB,CAAC;AAErD,4EAA4E;AAC5E,eAAO,MAAM,eAAe,uCAAuC,CAAC;AAEpE,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb;yEACqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACtE;uDACmD;IACnD,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAcD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAI1D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,MAAM,CAMR;AAgBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAI1D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAIzD"}
@@ -22,8 +22,8 @@ import { getConfiguredAppBasePath, normalizeAppBasePath, } from "./app-base-path
22
22
  export const OPEN_ROUTE_SUBPATH = "/open";
23
23
  /** Custom URL scheme the desktop app registers (`agentnative://open?...`). */
24
24
  export const DESKTOP_OPEN_URL = "agentnative://open";
25
- /** VS Code extension URI used by builderio.agent-native to open a webview. */
26
- export const VSCODE_OPEN_URL = "vscode://builderio.agent-native/open";
25
+ /** VS Code extension URI used by Builder.agent-native to open a webview. */
26
+ export const VSCODE_OPEN_URL = "vscode://builder.agent-native/open";
27
27
  function buildQuery(input) {
28
28
  const sp = new URLSearchParams();
29
29
  if (input.app)
@@ -1 +1 @@
1
- {"version":3,"file":"deep-link.js","sourceRoot":"","sources":["../../src/server/deep-link.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Deep-link helpers — the single source of truth for the\n * `/_agent-native/open` URL format.\n *\n * Every artifact-producing / list action that wants an external agent (MCP /\n * A2A) to surface an \"Open in <app> →\" link returns\n * `{ url: buildDeepLink(...), label }` from its `link` builder. The MCP layer\n * turns the relative path into an absolute web URL, an `agentnative://`\n * desktop URL, and a VS Code extension URL using the request origin.\n *\n * The `/_agent-native/open` route (see `open-route.ts`) consumes these: it\n * resolves the *browser session's* identity, writes the existing one-shot\n * `navigate` application-state command, and 302-redirects to the rendered SPA\n * view so any browser / inline webview lands on the right screen with the\n * record focused. We never invent a new navigation mechanism — this just\n * bridges external surfaces to the `navigate`/`application_state` contract the\n * UI already drains every 2s.\n */\nimport { withCollapsedAgentSidebarParam } from \"../shared/agent-sidebar-url.js\";\nimport {\n getConfiguredAppBasePath,\n normalizeAppBasePath,\n} from \"./app-base-path.js\";\n\n/** Path of the framework deep-link route, relative to the route prefix. */\nexport const OPEN_ROUTE_SUBPATH = \"/open\";\n\n/** Custom URL scheme the desktop app registers (`agentnative://open?...`). */\nexport const DESKTOP_OPEN_URL = \"agentnative://open\";\n\n/** VS Code extension URI used by builderio.agent-native to open a webview. */\nexport const VSCODE_OPEN_URL = \"vscode://builderio.agent-native/open\";\n\nexport interface DeepLinkInput {\n /** App id (informational + multi-app/desktop routing), e.g. \"mail\". */\n app?: string;\n /** Target view — maps to the `navigate` command `view`. */\n view: string;\n /** Record-focus + filter params, e.g. `{ threadId }`, `{ eventId, date }`,\n * `{ dashboardId }`. `undefined`/`null`/`\"\"` values are dropped. */\n params?: Record<string, string | number | boolean | null | undefined>;\n /** Explicit client-side path override (must be a same-origin, leading-slash\n * relative path — enforced by the open route). */\n to?: string;\n}\n\nfunction buildQuery(input: DeepLinkInput): string {\n const sp = new URLSearchParams();\n if (input.app) sp.set(\"app\", input.app);\n sp.set(\"view\", input.view);\n if (input.to) sp.set(\"to\", input.to);\n for (const [k, v] of Object.entries(input.params ?? {})) {\n if (v === undefined || v === null || v === \"\") continue;\n sp.set(k, String(v));\n }\n return sp.toString();\n}\n\n/**\n * Build the app-relative deep-link path:\n * `/_agent-native/open?app=mail&view=inbox&threadId=abc`.\n * Per-app `link` builders call this; never hand-format the URL.\n */\nexport function buildDeepLink(input: DeepLinkInput): string {\n return withCollapsedAgentSidebarParam(\n `/_agent-native${OPEN_ROUTE_SUBPATH}?${buildQuery(input)}`,\n );\n}\n\n/**\n * Resolve a (possibly relative) deep link to an absolute web URL using the\n * inbound request origin. Absolute URLs pass through unchanged.\n */\nexport function toAbsoluteOpenUrl(\n urlOrPath: string,\n origin: string | undefined,\n): string {\n if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(urlOrPath)) return urlOrPath;\n const basePath = getConfiguredAppBasePath();\n const path = withBasePath(urlOrPath, basePath);\n if (!origin) return path;\n return `${origin.replace(/\\/+$/, \"\")}${path.startsWith(\"/\") ? \"\" : \"/\"}${path}`;\n}\n\nfunction withBasePath(urlOrPath: string, basePath: string): string {\n if (!basePath) return urlOrPath;\n const leadingPath = urlOrPath.startsWith(\"/\") ? urlOrPath : `/${urlOrPath}`;\n const [pathname] = leadingPath.split(/[?#]/, 1);\n const normalizedPathname = normalizeAppBasePath(pathname);\n if (\n normalizedPathname === basePath ||\n normalizedPathname.startsWith(`${basePath}/`)\n ) {\n return urlOrPath;\n }\n return `${basePath}${leadingPath}`;\n}\n\n/**\n * Rewrite a deep link to the desktop `agentnative://open?...` scheme so the\n * desktop app's existing `handleDeepLink` opens it inside the app webview.\n * Accepts either an app-relative `/_agent-native/open?...` path or an absolute\n * web URL; preserves the query string.\n */\nexport function toDesktopOpenUrl(urlOrPath: string): string {\n const qIdx = urlOrPath.indexOf(\"?\");\n const query = qIdx >= 0 ? urlOrPath.slice(qIdx + 1) : \"\";\n return query ? `${DESKTOP_OPEN_URL}?${query}` : DESKTOP_OPEN_URL;\n}\n\n/**\n * Wrap an Agent Native web URL in the VS Code extension URI so external agents\n * can hand users a link that opens the app inside a VS Code webview.\n */\nexport function toVsCodeOpenUrl(urlOrPath: string): string {\n const sp = new URLSearchParams();\n sp.set(\"url\", urlOrPath);\n return `${VSCODE_OPEN_URL}?${sp.toString()}`;\n}\n"]}
1
+ {"version":3,"file":"deep-link.js","sourceRoot":"","sources":["../../src/server/deep-link.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Deep-link helpers — the single source of truth for the\n * `/_agent-native/open` URL format.\n *\n * Every artifact-producing / list action that wants an external agent (MCP /\n * A2A) to surface an \"Open in <app> →\" link returns\n * `{ url: buildDeepLink(...), label }` from its `link` builder. The MCP layer\n * turns the relative path into an absolute web URL, an `agentnative://`\n * desktop URL, and a VS Code extension URL using the request origin.\n *\n * The `/_agent-native/open` route (see `open-route.ts`) consumes these: it\n * resolves the *browser session's* identity, writes the existing one-shot\n * `navigate` application-state command, and 302-redirects to the rendered SPA\n * view so any browser / inline webview lands on the right screen with the\n * record focused. We never invent a new navigation mechanism — this just\n * bridges external surfaces to the `navigate`/`application_state` contract the\n * UI already drains every 2s.\n */\nimport { withCollapsedAgentSidebarParam } from \"../shared/agent-sidebar-url.js\";\nimport {\n getConfiguredAppBasePath,\n normalizeAppBasePath,\n} from \"./app-base-path.js\";\n\n/** Path of the framework deep-link route, relative to the route prefix. */\nexport const OPEN_ROUTE_SUBPATH = \"/open\";\n\n/** Custom URL scheme the desktop app registers (`agentnative://open?...`). */\nexport const DESKTOP_OPEN_URL = \"agentnative://open\";\n\n/** VS Code extension URI used by Builder.agent-native to open a webview. */\nexport const VSCODE_OPEN_URL = \"vscode://builder.agent-native/open\";\n\nexport interface DeepLinkInput {\n /** App id (informational + multi-app/desktop routing), e.g. \"mail\". */\n app?: string;\n /** Target view — maps to the `navigate` command `view`. */\n view: string;\n /** Record-focus + filter params, e.g. `{ threadId }`, `{ eventId, date }`,\n * `{ dashboardId }`. `undefined`/`null`/`\"\"` values are dropped. */\n params?: Record<string, string | number | boolean | null | undefined>;\n /** Explicit client-side path override (must be a same-origin, leading-slash\n * relative path — enforced by the open route). */\n to?: string;\n}\n\nfunction buildQuery(input: DeepLinkInput): string {\n const sp = new URLSearchParams();\n if (input.app) sp.set(\"app\", input.app);\n sp.set(\"view\", input.view);\n if (input.to) sp.set(\"to\", input.to);\n for (const [k, v] of Object.entries(input.params ?? {})) {\n if (v === undefined || v === null || v === \"\") continue;\n sp.set(k, String(v));\n }\n return sp.toString();\n}\n\n/**\n * Build the app-relative deep-link path:\n * `/_agent-native/open?app=mail&view=inbox&threadId=abc`.\n * Per-app `link` builders call this; never hand-format the URL.\n */\nexport function buildDeepLink(input: DeepLinkInput): string {\n return withCollapsedAgentSidebarParam(\n `/_agent-native${OPEN_ROUTE_SUBPATH}?${buildQuery(input)}`,\n );\n}\n\n/**\n * Resolve a (possibly relative) deep link to an absolute web URL using the\n * inbound request origin. Absolute URLs pass through unchanged.\n */\nexport function toAbsoluteOpenUrl(\n urlOrPath: string,\n origin: string | undefined,\n): string {\n if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(urlOrPath)) return urlOrPath;\n const basePath = getConfiguredAppBasePath();\n const path = withBasePath(urlOrPath, basePath);\n if (!origin) return path;\n return `${origin.replace(/\\/+$/, \"\")}${path.startsWith(\"/\") ? \"\" : \"/\"}${path}`;\n}\n\nfunction withBasePath(urlOrPath: string, basePath: string): string {\n if (!basePath) return urlOrPath;\n const leadingPath = urlOrPath.startsWith(\"/\") ? urlOrPath : `/${urlOrPath}`;\n const [pathname] = leadingPath.split(/[?#]/, 1);\n const normalizedPathname = normalizeAppBasePath(pathname);\n if (\n normalizedPathname === basePath ||\n normalizedPathname.startsWith(`${basePath}/`)\n ) {\n return urlOrPath;\n }\n return `${basePath}${leadingPath}`;\n}\n\n/**\n * Rewrite a deep link to the desktop `agentnative://open?...` scheme so the\n * desktop app's existing `handleDeepLink` opens it inside the app webview.\n * Accepts either an app-relative `/_agent-native/open?...` path or an absolute\n * web URL; preserves the query string.\n */\nexport function toDesktopOpenUrl(urlOrPath: string): string {\n const qIdx = urlOrPath.indexOf(\"?\");\n const query = qIdx >= 0 ? urlOrPath.slice(qIdx + 1) : \"\";\n return query ? `${DESKTOP_OPEN_URL}?${query}` : DESKTOP_OPEN_URL;\n}\n\n/**\n * Wrap an Agent Native web URL in the VS Code extension URI so external agents\n * can hand users a link that opens the app inside a VS Code webview.\n */\nexport function toVsCodeOpenUrl(urlOrPath: string): string {\n const sp = new URLSearchParams();\n sp.set(\"url\", urlOrPath);\n return `${VSCODE_OPEN_URL}?${sp.toString()}`;\n}\n"]}
@@ -1342,6 +1342,19 @@
1342
1342
  max-width: 100%;
1343
1343
  }
1344
1344
 
1345
+ /* Base padding so primitive text never touches the box edge, even when an author
1346
+ * diagram omits its own padding. The wildcard selectors mirror the theme-color
1347
+ * rules above so every box/card/panel variant authors use is covered. Author CSS
1348
+ * (higher specificity, scoped to the diagram instance) still overrides this when
1349
+ * it sets padding explicitly. */
1350
+ .plan-diagram-frame :is(.diagram-node, .diagram-box, [class*="box"]) {
1351
+ padding: 8px 12px;
1352
+ }
1353
+ .plan-diagram-frame
1354
+ :is(.diagram-card, .diagram-panel, [class*="card"], [class*="panel"]) {
1355
+ padding: 14px 16px;
1356
+ }
1357
+
1345
1358
  .plan-diagram-frame :is(.diagram-node, .diagram-box, .diagram-card) small {
1346
1359
  display: block;
1347
1360
  max-width: 100%;
@@ -1383,15 +1396,24 @@
1383
1396
  }
1384
1397
 
1385
1398
  .plan-diagram-frame[data-style="sketchy"] :is(.diagram-node, .diagram-box) {
1386
- padding-inline: 7px;
1399
+ padding-inline: 12px;
1387
1400
  }
1388
1401
 
1389
- .plan-diagram-frame .diagram-pill {
1402
+ .plan-diagram-frame
1403
+ :is(.diagram-pill, [class*="pill"], [class*="badge"], [class*="chip"]) {
1390
1404
  display: inline-flex;
1391
1405
  align-items: center;
1406
+ justify-content: center;
1407
+ /* A pill hugs its label. `fit-content` is a definite cross size, so a flex
1408
+ * column with the default `align-items: stretch` no longer blows the pill out
1409
+ * to full width (the number chips and short status labels stay pill-shaped).
1410
+ * The wildcard selectors match the theme-color rules so every pill/badge/chip
1411
+ * variant used across the docs diagrams stays pill-shaped, not a full bar. */
1412
+ width: fit-content;
1413
+ max-width: 100%;
1392
1414
  border: 1px solid var(--wf-line);
1393
1415
  border-radius: 999px;
1394
- padding: 2px 8px;
1416
+ padding: 3px 11px;
1395
1417
  color: var(--wf-ink);
1396
1418
  background: var(--wf-paper);
1397
1419
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tailwind.preset.d.ts","sourceRoot":"","sources":["../src/tailwind.preset.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA2B1C;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,QAA2C,CAAC;wBAiGpC,MAAM;AAA1C,wBAA2C"}
1
+ {"version":3,"file":"tailwind.preset.d.ts","sourceRoot":"","sources":["../src/tailwind.preset.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA2B1C;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,QAA2C,CAAC;wBAuGpC,MAAM;AAA1C,wBAA2C"}
@@ -122,7 +122,14 @@ const preset = {
122
122
  return null;
123
123
  }
124
124
  })(),
125
- require("@tailwindcss/typography"),
125
+ (() => {
126
+ try {
127
+ return require("@tailwindcss/typography");
128
+ }
129
+ catch {
130
+ return null;
131
+ }
132
+ })(),
126
133
  ].filter(Boolean),
127
134
  };
128
135
  export default preset;
@@ -1 +1 @@
1
- {"version":3,"file":"tailwind.preset.js","sourceRoot":"","sources":["../src/tailwind.preset.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,qEAAqE;AACrE,oDAAoD;AACpD,MAAM,OAAO,GACX,OAAO,SAAS,KAAK,WAAW;IAC9B,CAAC,CAAC,SAAS;IACX,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE9C;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;AAExE,+EAA+E;AAC/E,4EAA4E;AAC5E,yDAAyD;AACzD,MAAM,MAAM,GAAG;IACb,QAAQ,EAAE,CAAC,OAAO,CAAC;IACnB,OAAO,EAAE,CAAC,eAAe,CAAC;IAC1B,MAAM,EAAE,EAAE;IACV,KAAK,EAAE;QACL,SAAS,EAAE;YACT,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,MAAM;YACf,OAAO,EAAE;gBACP,KAAK,EAAE,QAAQ;aAChB;SACF;QACD,MAAM,EAAE;YACN,MAAM,EAAE;gBACN,MAAM,EAAE,oBAAoB;gBAC5B,KAAK,EAAE,mBAAmB;gBAC1B,IAAI,EAAE,kBAAkB;gBACxB,UAAU,EAAE,wBAAwB;gBACpC,UAAU,EAAE,wBAAwB;gBACpC,OAAO,EAAE;oBACP,OAAO,EAAE,qBAAqB;oBAC9B,UAAU,EAAE,gCAAgC;iBAC7C;gBACD,SAAS,EAAE;oBACT,OAAO,EAAE,uBAAuB;oBAChC,UAAU,EAAE,kCAAkC;iBAC/C;gBACD,WAAW,EAAE;oBACX,OAAO,EAAE,yBAAyB;oBAClC,UAAU,EAAE,oCAAoC;iBACjD;gBACD,KAAK,EAAE;oBACL,OAAO,EAAE,mBAAmB;oBAC5B,UAAU,EAAE,8BAA8B;iBAC3C;gBACD,MAAM,EAAE;oBACN,OAAO,EAAE,oBAAoB;oBAC7B,UAAU,EAAE,+BAA+B;iBAC5C;gBACD,OAAO,EAAE;oBACP,OAAO,EAAE,qBAAqB;oBAC9B,UAAU,EAAE,gCAAgC;iBAC7C;gBACD,IAAI,EAAE;oBACJ,OAAO,EAAE,kBAAkB;oBAC3B,UAAU,EAAE,6BAA6B;iBAC1C;gBACD,OAAO,EAAE;oBACP,OAAO,EAAE,gCAAgC;oBACzC,UAAU,EAAE,gCAAgC;oBAC5C,OAAO,EAAE,6BAA6B;oBACtC,oBAAoB,EAAE,wCAAwC;oBAC9D,MAAM,EAAE,4BAA4B;oBACpC,mBAAmB,EAAE,uCAAuC;oBAC5D,MAAM,EAAE,4BAA4B;oBACpC,IAAI,EAAE,0BAA0B;iBACjC;aACF;YACD,YAAY,EAAE;gBACZ,EAAE,EAAE,eAAe;gBACnB,EAAE,EAAE,2BAA2B;gBAC/B,EAAE,EAAE,2BAA2B;aAChC;YACD,SAAS,EAAE;gBACT,gBAAgB,EAAE;oBAChB,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE;oBACrB,EAAE,EAAE,EAAE,MAAM,EAAE,uCAAuC,EAAE;iBACxD;gBACD,cAAc,EAAE;oBACd,IAAI,EAAE,EAAE,MAAM,EAAE,uCAAuC,EAAE;oBACzD,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE;iBACpB;aACF;YACD,SAAS,EAAE;gBACT,gBAAgB,EAAE,8BAA8B;gBAChD,cAAc,EAAE,4BAA4B;aAC7C;SACF;KACF;IACD,OAAO,EAAE;QACP,kFAAkF;QAClF,CAAC,GAAG,EAAE;YACJ,IAAI,CAAC;gBACH,OAAO,OAAO,CAAC,qBAAqB,CAAC,CAAC;YACxC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC,CAAC,EAAE;QACJ,OAAO,CAAC,yBAAyB,CAAC;KACnC,CAAC,MAAM,CAAC,OAAO,CAAC;CAClB,CAAC;AAEF,eAAe,MAA2B,CAAC","sourcesContent":["import type { Config } from \"tailwindcss\";\n\n/**\n * @deprecated Legacy Tailwind v3 preset.\n *\n * The framework has moved to Tailwind v4. Templates should now use the shared\n * stylesheet from CSS instead of a `tailwind.config.ts`:\n *\n * // app/global.css\n * @import \"tailwindcss\";\n * @import \"@agent-native/core/styles/agent-native.css\";\n *\n * No `tailwind.config.ts` or `postcss.config.js` is needed. The\n * `@tailwindcss/vite` plugin is auto-injected by `defineConfig()`.\n *\n * This export is kept only for third-party templates still on the v3 PostCSS pipeline.\n */\nimport { join, dirname } from \"path\";\nimport { fileURLToPath } from \"url\";\n\n// Scan @agent-native/core's dist/client for Tailwind classes used in\n// core components (AgentPanel, AssistantChat, etc.)\nconst thisDir =\n typeof __dirname !== \"undefined\"\n ? __dirname\n : dirname(fileURLToPath(import.meta.url));\n\n/**\n * Glob pattern that matches all core client component files.\n * Templates MUST include this in their `content` array — Tailwind v3\n * does NOT merge `content` from presets, so the preset alone isn't enough.\n *\n * Usage:\n * import preset, { coreContentGlob } from \"@agent-native/core/tailwind\";\n * export default { presets: [preset], content: [\"./app/**\\/*.{ts,tsx}\", coreContentGlob] };\n */\nexport const coreContentGlob = join(thisDir, \"client\", \"**/*.{js,mjs}\");\n\n// Cast to `any` for the inner config — Tailwind v4 ships stricter Config types\n// than v3 (e.g. `darkMode: [\"class\"]` is v3-only). This file exists only to\n// keep third-party v3 setups working until they migrate.\nconst preset = {\n darkMode: [\"class\"],\n content: [coreContentGlob],\n prefix: \"\",\n theme: {\n container: {\n center: true,\n padding: \"2rem\",\n screens: {\n \"2xl\": \"1400px\",\n },\n },\n extend: {\n colors: {\n border: \"hsl(var(--border))\",\n input: \"hsl(var(--input))\",\n ring: \"hsl(var(--ring))\",\n background: \"hsl(var(--background))\",\n foreground: \"hsl(var(--foreground))\",\n primary: {\n DEFAULT: \"hsl(var(--primary))\",\n foreground: \"hsl(var(--primary-foreground))\",\n },\n secondary: {\n DEFAULT: \"hsl(var(--secondary))\",\n foreground: \"hsl(var(--secondary-foreground))\",\n },\n destructive: {\n DEFAULT: \"hsl(var(--destructive))\",\n foreground: \"hsl(var(--destructive-foreground))\",\n },\n muted: {\n DEFAULT: \"hsl(var(--muted))\",\n foreground: \"hsl(var(--muted-foreground))\",\n },\n accent: {\n DEFAULT: \"hsl(var(--accent))\",\n foreground: \"hsl(var(--accent-foreground))\",\n },\n popover: {\n DEFAULT: \"hsl(var(--popover))\",\n foreground: \"hsl(var(--popover-foreground))\",\n },\n card: {\n DEFAULT: \"hsl(var(--card))\",\n foreground: \"hsl(var(--card-foreground))\",\n },\n sidebar: {\n DEFAULT: \"hsl(var(--sidebar-background))\",\n foreground: \"hsl(var(--sidebar-foreground))\",\n primary: \"hsl(var(--sidebar-primary))\",\n \"primary-foreground\": \"hsl(var(--sidebar-primary-foreground))\",\n accent: \"hsl(var(--sidebar-accent))\",\n \"accent-foreground\": \"hsl(var(--sidebar-accent-foreground))\",\n border: \"hsl(var(--sidebar-border))\",\n ring: \"hsl(var(--sidebar-ring))\",\n },\n },\n borderRadius: {\n lg: \"var(--radius)\",\n md: \"calc(var(--radius) - 2px)\",\n sm: \"calc(var(--radius) - 4px)\",\n },\n keyframes: {\n \"accordion-down\": {\n from: { height: \"0\" },\n to: { height: \"var(--radix-accordion-content-height)\" },\n },\n \"accordion-up\": {\n from: { height: \"var(--radix-accordion-content-height)\" },\n to: { height: \"0\" },\n },\n },\n animation: {\n \"accordion-down\": \"accordion-down 0.2s ease-out\",\n \"accordion-up\": \"accordion-up 0.2s ease-out\",\n },\n },\n },\n plugins: [\n // tailwindcss-animate is v3-only and is no longer a peer dep — guard the require.\n (() => {\n try {\n return require(\"tailwindcss-animate\");\n } catch {\n return null;\n }\n })(),\n require(\"@tailwindcss/typography\"),\n ].filter(Boolean),\n};\n\nexport default preset as unknown as Config;\n"]}
1
+ {"version":3,"file":"tailwind.preset.js","sourceRoot":"","sources":["../src/tailwind.preset.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Config } from \"tailwindcss\";\n\n/**\n * @deprecated Legacy Tailwind v3 preset.\n *\n * The framework has moved to Tailwind v4. Templates should now use the shared\n * stylesheet from CSS instead of a `tailwind.config.ts`:\n *\n * // app/global.css\n * @import \"tailwindcss\";\n * @import \"@agent-native/core/styles/agent-native.css\";\n *\n * No `tailwind.config.ts` or `postcss.config.js` is needed. The\n * `@tailwindcss/vite` plugin is auto-injected by `defineConfig()`.\n *\n * This export is kept only for third-party templates still on the v3 PostCSS pipeline.\n */\nimport { join, dirname } from \"path\";\nimport { fileURLToPath } from \"url\";\n\n// Scan @agent-native/core's dist/client for Tailwind classes used in\n// core components (AgentPanel, AssistantChat, etc.)\nconst thisDir =\n typeof __dirname !== \"undefined\"\n ? __dirname\n : dirname(fileURLToPath(import.meta.url));\n\n/**\n * Glob pattern that matches all core client component files.\n * Templates MUST include this in their `content` array — Tailwind v3\n * does NOT merge `content` from presets, so the preset alone isn't enough.\n *\n * Usage:\n * import preset, { coreContentGlob } from \"@agent-native/core/tailwind\";\n * export default { presets: [preset], content: [\"./app/**\\/*.{ts,tsx}\", coreContentGlob] };\n */\nexport const coreContentGlob = join(thisDir, \"client\", \"**/*.{js,mjs}\");\n\n// Cast to `any` for the inner config — Tailwind v4 ships stricter Config types\n// than v3 (e.g. `darkMode: [\"class\"]` is v3-only). This file exists only to\n// keep third-party v3 setups working until they migrate.\nconst preset = {\n darkMode: [\"class\"],\n content: [coreContentGlob],\n prefix: \"\",\n theme: {\n container: {\n center: true,\n padding: \"2rem\",\n screens: {\n \"2xl\": \"1400px\",\n },\n },\n extend: {\n colors: {\n border: \"hsl(var(--border))\",\n input: \"hsl(var(--input))\",\n ring: \"hsl(var(--ring))\",\n background: \"hsl(var(--background))\",\n foreground: \"hsl(var(--foreground))\",\n primary: {\n DEFAULT: \"hsl(var(--primary))\",\n foreground: \"hsl(var(--primary-foreground))\",\n },\n secondary: {\n DEFAULT: \"hsl(var(--secondary))\",\n foreground: \"hsl(var(--secondary-foreground))\",\n },\n destructive: {\n DEFAULT: \"hsl(var(--destructive))\",\n foreground: \"hsl(var(--destructive-foreground))\",\n },\n muted: {\n DEFAULT: \"hsl(var(--muted))\",\n foreground: \"hsl(var(--muted-foreground))\",\n },\n accent: {\n DEFAULT: \"hsl(var(--accent))\",\n foreground: \"hsl(var(--accent-foreground))\",\n },\n popover: {\n DEFAULT: \"hsl(var(--popover))\",\n foreground: \"hsl(var(--popover-foreground))\",\n },\n card: {\n DEFAULT: \"hsl(var(--card))\",\n foreground: \"hsl(var(--card-foreground))\",\n },\n sidebar: {\n DEFAULT: \"hsl(var(--sidebar-background))\",\n foreground: \"hsl(var(--sidebar-foreground))\",\n primary: \"hsl(var(--sidebar-primary))\",\n \"primary-foreground\": \"hsl(var(--sidebar-primary-foreground))\",\n accent: \"hsl(var(--sidebar-accent))\",\n \"accent-foreground\": \"hsl(var(--sidebar-accent-foreground))\",\n border: \"hsl(var(--sidebar-border))\",\n ring: \"hsl(var(--sidebar-ring))\",\n },\n },\n borderRadius: {\n lg: \"var(--radius)\",\n md: \"calc(var(--radius) - 2px)\",\n sm: \"calc(var(--radius) - 4px)\",\n },\n keyframes: {\n \"accordion-down\": {\n from: { height: \"0\" },\n to: { height: \"var(--radix-accordion-content-height)\" },\n },\n \"accordion-up\": {\n from: { height: \"var(--radix-accordion-content-height)\" },\n to: { height: \"0\" },\n },\n },\n animation: {\n \"accordion-down\": \"accordion-down 0.2s ease-out\",\n \"accordion-up\": \"accordion-up 0.2s ease-out\",\n },\n },\n },\n plugins: [\n // tailwindcss-animate is v3-only and is no longer a peer dep — guard the require.\n (() => {\n try {\n return require(\"tailwindcss-animate\");\n } catch {\n return null;\n }\n })(),\n (() => {\n try {\n return require(\"@tailwindcss/typography\");\n } catch {\n return null;\n }\n })(),\n ].filter(Boolean),\n};\n\nexport default preset as unknown as Config;\n"]}
@@ -24,6 +24,7 @@
24
24
  "devDependencies": {
25
25
  "@react-router/dev": "^7.16.0",
26
26
  "@react-router/fs-routes": "^7.16.0",
27
+ "@tailwindcss/typography": "^0.5.20",
27
28
  "@tailwindcss/vite": "^4.1.18",
28
29
  "@tanstack/react-query": "^5.99.2",
29
30
  "@types/node": "^24.2.1",
@@ -9,6 +9,9 @@ This app is not stateless. The Agent Native runtime uses SQL-backed stores for a
9
9
  - Prefer actions in `actions/` for every app operation. Do not create REST wrappers around actions.
10
10
  - Keep action inputs validated with Zod and return structured data, not JSON strings.
11
11
  - Do not hardcode API keys, tokens, webhook URLs, private data, or credential-looking literals.
12
+ - `actions/run.ts` is the CLI dispatcher for `pnpm action ...`, not an app
13
+ action. Leave it in place and add callable primitives as separate
14
+ `actions/<name>.ts` files.
12
15
  - There is intentionally no `app/` UI shell in this scaffold. When you need a browser UI, use the Chat template as the UI on-ramp and keep `agent-native add` for integration blueprints.
13
16
 
14
17
  ## Framework Docs Lookup
@@ -7,6 +7,10 @@ pnpm install
7
7
  pnpm action hello --name Builder
8
8
  ```
9
9
 
10
+ `actions/run.ts` is only the shared CLI dispatcher that powers
11
+ `pnpm action <name>`. Add real agent-callable actions as separate files such as
12
+ `actions/hello.ts`.
13
+
10
14
  Then run the production app-agent loop against this folder:
11
15
 
12
16
  ```bash
@@ -1,3 +1,9 @@
1
+ /**
2
+ * CLI dispatcher for `pnpm action ...`.
3
+ *
4
+ * This file lives in actions/ so the Agent Native CLI can find it. It is skipped
5
+ * by action discovery and is not exposed as an agent tool.
6
+ */
1
7
  import { runScript } from "@agent-native/core/scripts";
2
8
 
3
9
  runScript();
@@ -20,6 +20,13 @@ Key concepts:
20
20
  - **Tasks** — each message creates a task with a lifecycle (submitted, working, completed, failed, canceled)
21
21
  - **JWT bearer auth** — production A2A requires `A2A_SECRET` or an explicit legacy `apiKeyEnv`
22
22
 
23
+ ```an-diagram title="One agent hands work to another" summary="A mail agent discovers the analytics agent's card, sends a JSON-RPC message, and gets a completed task back."
24
+ {
25
+ "html": "<div class=\"diagram-handoff\"><div class=\"diagram-card\"><strong>Mail agent</strong><small class=\"diagram-muted\">needs analytics</small></div><div class=\"diagram-col\"><div class=\"diagram-pill\">GET /.well-known/agent-card.json</div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-pill accent\">POST /_agent-native/a2a<br><small class=\"diagram-muted\">message/send</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&larr;</div><div class=\"diagram-pill ok\">task · completed</div></div><div class=\"diagram-card\" data-rough><strong>Analytics agent</strong><small class=\"diagram-muted\">runs run-query, returns result</small></div></div>",
26
+ "css": ".diagram-handoff{display:flex;align-items:center;gap:16px;flex-wrap:wrap}.diagram-handoff .diagram-col{display:flex;flex-direction:column;align-items:center;gap:6px}.diagram-handoff .diagram-arrow{font-size:20px;line-height:1}"
27
+ }
28
+ ```
29
+
23
30
  ## Server setup {#server-setup}
24
31
 
25
32
  Most templates get A2A through the framework agent chat plugin. If you are mounting it yourself, call `mountA2A()` in a server plugin:
@@ -112,24 +119,55 @@ All methods are called via `POST /_agent-native/a2a` with JSON-RPC 2.0 format:
112
119
  | `tasks/get` | Fetch a task by ID — used to poll an async task to completion | `id` |
113
120
  | `tasks/cancel` | Cancel a running task | `id` |
114
121
 
122
+ ```an-api title="Primary A2A endpoint" summary="All JSON-RPC methods are POSTed here. message/send shown."
123
+ {
124
+ "method": "POST",
125
+ "path": "/_agent-native/a2a",
126
+ "summary": "Send a message and wait for the completed task",
127
+ "description": "JSON-RPC 2.0 endpoint for `message/send`, `message/stream`, `tasks/get`, and `tasks/cancel`. Pass `async: true` to return immediately in `working` state and poll with `tasks/get`.",
128
+ "auth": "JWT bearer signed with A2A_SECRET (or legacy apiKeyEnv static token)",
129
+ "params": [
130
+ { "name": "Authorization", "in": "header", "type": "string", "required": false, "description": "Bearer token. Required in hosted production runtimes; optional in local dev." },
131
+ { "name": "method", "in": "body", "type": "string", "required": true, "description": "One of message/send, message/stream, tasks/get, tasks/cancel." },
132
+ { "name": "params.message", "in": "body", "type": "object", "required": false, "description": "{ role, parts[] } for message/send and message/stream." },
133
+ { "name": "params.async", "in": "body", "type": "boolean", "required": false, "description": "Return immediately in working state and poll via tasks/get. Use on serverless hosts." },
134
+ { "name": "params.id", "in": "body", "type": "string", "required": false, "description": "Task id for tasks/get and tasks/cancel." }
135
+ ],
136
+ "request": {
137
+ "contentType": "application/json",
138
+ "example": "{\n \"jsonrpc\": \"2.0\",\n \"id\": 1,\n \"method\": \"message/send\",\n \"params\": {\n \"message\": {\n \"role\": \"user\",\n \"parts\": [{ \"type\": \"text\", \"text\": \"Show signups by source\" }]\n },\n \"async\": true\n }\n}"
139
+ },
140
+ "responses": [
141
+ { "status": "200", "description": "JSON-RPC result containing the task. With async:true the task returns in working state.", "example": "{\n \"jsonrpc\": \"2.0\",\n \"id\": 1,\n \"result\": { \"id\": \"task_123\", \"status\": { \"state\": \"working\" } }\n}" },
142
+ { "status": "503", "description": "Hosted production runtime with no A2A_SECRET configured — fails closed instead of running unauthenticated." }
143
+ ]
144
+ }
145
+ ```
146
+
115
147
  When `message/send` is called with `async: true`, the JSON-RPC handler enqueues the task and self-fires a POST to an internal `/_agent-native/a2a/_process-task` route so the handler runs in a fresh function execution with its own full timeout. This route is authenticated with an HMAC token bound to the task ID (5-minute lifetime, signed with `A2A_SECRET`). It is mounted before the `/_agent-native/a2a` JSON-RPC route so h3's prefix matching does not swallow it.
116
148
 
149
+ ```an-diagram title="Async task lifecycle on serverless" summary="async:true returns working in milliseconds, then a fresh execution runs the agent loop while the caller polls."
150
+ {
151
+ "html": "<div class=\"diagram-async\"><div class=\"diagram-box\" data-rough>message/send<br><small class=\"diagram-muted\">async: true</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-panel\"><span class=\"diagram-pill\">enqueue task</span><span class=\"diagram-pill warn\">return working</span><small class=\"diagram-muted\">~milliseconds</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&darr;</div><div class=\"diagram-box\" data-rough>self-fire POST /_agent-native/a2a/_process-task<br><small class=\"diagram-muted\">HMAC token · fresh execution · full timeout</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-col\"><div class=\"diagram-pill\">tasks/get (poll)</div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&#8635;</div><div class=\"diagram-pill ok\">completed</div></div></div>",
152
+ "css": ".diagram-async{display:flex;align-items:center;gap:14px;flex-wrap:wrap}.diagram-async .diagram-panel{display:flex;flex-direction:column;align-items:center;gap:6px}.diagram-async .diagram-col{display:flex;flex-direction:column;align-items:center;gap:6px}.diagram-async .diagram-arrow{font-size:20px;line-height:1}",
153
+ "caption": "A recurring sweeper re-claims any task left in flight if the function execution dies mid-run."
154
+ }
155
+ ```
156
+
117
157
  > [!IMPORTANT]
118
158
  > **Serverless Webhook & Gateway Timeouts:**
119
159
  > Hosted environment gateways (such as Netlify, Vercel, or Cloudflare Pages) impose strict execution limits (often 10 to 30 seconds) on public-facing HTTP routes. Because agent loops can take significant time to run queries, fetch context, and execute tools, you **must use `async: true`** when calling A2A endpoints or handling external webhooks. This immediately returns a `working` status to the API gateway, keeping the connection open only for a few milliseconds, while the self-fired `/process-task` POST executes the agent loop in the background. Do not block the primary HTTP request waiting for the agent loop to finish.
120
160
 
121
- Messages contain typed parts:
161
+ Messages contain typed parts — text, structured data, and files can all travel in one message:
122
162
 
123
- ```json
163
+ ```an-annotated-code title="A2A message with typed parts"
124
164
  {
125
- "role": "user",
126
- "parts": [
127
- { "type": "text", "text": "Show signups by source" },
128
- { "type": "data", "data": { "dateRange": "last-30d" } },
129
- {
130
- "type": "file",
131
- "file": { "name": "report.csv", "mimeType": "text/csv", "bytes": "..." }
132
- }
165
+ "language": "json",
166
+ "code": "{\n \"role\": \"user\",\n \"parts\": [\n { \"type\": \"text\", \"text\": \"Show signups by source\" },\n { \"type\": \"data\", \"data\": { \"dateRange\": \"last-30d\" } },\n {\n \"type\": \"file\",\n \"file\": { \"name\": \"report.csv\", \"mimeType\": \"text/csv\", \"bytes\": \"...\" }\n }\n ]\n}",
167
+ "annotations": [
168
+ { "lines": "4", "label": "text part", "note": "Plain natural-language instruction the agent reads." },
169
+ { "lines": "5", "label": "data part", "note": "Structured JSON arguments — e.g. a date range — passed alongside the prompt." },
170
+ { "lines": "6-9", "label": "file part", "note": "Attach a file by name, `mimeType`, and base64 `bytes`." }
133
171
  ]
134
172
  }
135
173
  ```