@agent-native/core 0.131.4 → 0.131.6

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 (330) hide show
  1. package/corpus/README.md +3 -3
  2. package/corpus/core/CHANGELOG.md +69 -0
  3. package/corpus/core/docs/content/agent-native-toolkit.mdx +13 -6
  4. package/corpus/core/docs/content/cloneable-saas.mdx +5 -5
  5. package/corpus/core/docs/content/creating-templates.mdx +9 -0
  6. package/corpus/core/docs/content/deployment.mdx +14 -10
  7. package/corpus/core/docs/content/docs-components.mdx +491 -0
  8. package/corpus/core/docs/content/doctor.mdx +8 -1
  9. package/corpus/core/docs/content/drop-in-agent.mdx +1 -1
  10. package/corpus/core/docs/content/extensions.mdx +18 -18
  11. package/corpus/core/docs/content/faq.mdx +4 -4
  12. package/corpus/core/docs/content/key-concepts.mdx +30 -21
  13. package/corpus/core/docs/content/template-brain-developers.mdx +4 -1
  14. package/corpus/core/docs/content/template-mail-developers.mdx +4 -1
  15. package/corpus/core/docs/content/what-is-agent-native.mdx +6 -6
  16. package/corpus/core/package.json +1 -1
  17. package/corpus/core/src/a2a/client.ts +449 -66
  18. package/corpus/core/src/a2a/correlation.ts +31 -0
  19. package/corpus/core/src/a2a/types.ts +4 -0
  20. package/corpus/core/src/action.ts +3 -0
  21. package/corpus/core/src/agent/engine/registry.ts +45 -5
  22. package/corpus/core/src/agent/production-agent.ts +151 -18
  23. package/corpus/core/src/agent/run-loop-with-resume.ts +190 -3
  24. package/corpus/core/src/agent/run-manager.ts +117 -41
  25. package/corpus/core/src/agent/thread-debug-history.ts +86 -0
  26. package/corpus/core/src/agent/types.ts +3 -1
  27. package/corpus/core/src/cli/create.ts +11 -1
  28. package/corpus/core/src/cli/templates-meta.ts +2 -2
  29. package/corpus/core/src/client/agent-chat-adapter.ts +91 -13
  30. package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +11 -9
  31. package/corpus/core/src/client/sse-event-processor.ts +17 -3
  32. package/corpus/core/src/db/client.ts +57 -17
  33. package/corpus/core/src/integrations/adapters/slack.ts +8 -3
  34. package/corpus/core/src/localization/default-messages.ts +44 -0
  35. package/corpus/core/src/observability/traces.ts +78 -5
  36. package/corpus/core/src/scripts/call-agent.ts +290 -9
  37. package/corpus/core/src/scripts/describe-workspace-apps.ts +2 -2
  38. package/corpus/core/src/secrets/crypto.ts +126 -34
  39. package/corpus/core/src/secrets/storage.ts +61 -25
  40. package/corpus/core/src/server/agent-capabilities.ts +1 -1
  41. package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +111 -7
  42. package/corpus/core/src/server/agent-chat/context-tools.ts +2 -0
  43. package/corpus/core/src/server/agent-chat/plugin-options.ts +34 -1
  44. package/corpus/core/src/server/agent-chat/prompt-resources.ts +1 -1
  45. package/corpus/core/src/server/agent-chat-plugin.ts +91 -59
  46. package/corpus/core/src/templates/default/.agents/skills/secrets/SKILL.md +14 -7
  47. package/corpus/core/src/templates/headless/.agents/skills/secrets/SKILL.md +14 -7
  48. package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +18 -7
  49. package/corpus/core/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +15 -14
  50. package/corpus/core/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +14 -7
  51. package/corpus/core/src/vite/client.ts +1 -0
  52. package/corpus/templates/analytics/.agents/skills/dashboard-ops/SKILL.md +5 -4
  53. package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +6 -4
  54. package/corpus/templates/analytics/AGENTS.md +6 -4
  55. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +4 -3
  56. package/corpus/templates/analytics/changelog/2026-07-30-scheduled-dashboard-emails-complete-every-panel-without-pool.md +6 -0
  57. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +28 -1
  58. package/corpus/templates/analytics/server/jobs/dashboard-report.ts +18 -11
  59. package/corpus/templates/analytics/server/lib/analytics-connector-catalog.ts +4 -4
  60. package/corpus/templates/analytics/server/lib/canonical-first-party-dashboard-repair.ts +9 -5
  61. package/corpus/templates/analytics/server/lib/dashboard-panel-query.ts +6 -2
  62. package/corpus/templates/analytics/server/lib/dashboard-panel-source-resolver.ts +11 -4
  63. package/corpus/templates/analytics/server/lib/dashboard-report-render.ts +49 -31
  64. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +16 -8
  65. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +9 -3
  66. package/corpus/templates/analytics/server/lib/production-serverless-runtime.ts +11 -0
  67. package/corpus/templates/analytics/server/plugins/agent-chat.ts +3 -2
  68. package/corpus/templates/analytics/server/plugins/analytics-alert-jobs.ts +2 -1
  69. package/corpus/templates/analytics/server/plugins/dashboard-report-jobs.ts +2 -1
  70. package/corpus/templates/analytics/server/plugins/uptime-monitor-jobs.ts +1 -12
  71. package/corpus/templates/brain/.agents/skills/brain/RUNBOOK.md +54 -6
  72. package/corpus/templates/brain/.agents/skills/brain/SKILL.md +20 -9
  73. package/corpus/templates/brain/.agents/skills/ingestion-and-connectors/SKILL.md +33 -1
  74. package/corpus/templates/brain/AGENTS.md +3 -1
  75. package/corpus/templates/brain/README.md +4 -1
  76. package/corpus/templates/brain/actions/_schemas.ts +30 -8
  77. package/corpus/templates/brain/actions/ask-brain.ts +124 -14
  78. package/corpus/templates/brain/actions/create-source.ts +18 -2
  79. package/corpus/templates/brain/actions/enqueue-captures-distillation.ts +8 -123
  80. package/corpus/templates/brain/actions/enqueue-distillation.ts +6 -127
  81. package/corpus/templates/brain/actions/import-capture.ts +17 -5
  82. package/corpus/templates/brain/actions/import-transcript.ts +17 -5
  83. package/corpus/templates/brain/actions/update-source.ts +25 -5
  84. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +1 -1
  85. package/corpus/templates/brain/changelog/2026-07-30-blessed-resources-can-feed-cited-company-answers.md +6 -0
  86. package/corpus/templates/brain/changelog/2026-07-30-the-left-sidebar-no-longer-shows-a-blank-organization-placeh.md +6 -0
  87. package/corpus/templates/brain/server/lib/brain.ts +49 -19
  88. package/corpus/templates/brain/server/lib/distillation-queue.ts +147 -0
  89. package/corpus/templates/brain/server/lib/source-policy.ts +264 -0
  90. package/corpus/templates/brain/server/plugins/agent-chat.ts +3 -2
  91. package/corpus/templates/brain/server/routes/api/_agent-native/brain/ingest.post.ts +116 -19
  92. package/corpus/templates/clips/app/components/meetings/google-oauth-identity-notice.tsx +51 -0
  93. package/corpus/templates/clips/app/i18n/en-US.ts +4 -0
  94. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +3 -1
  95. package/corpus/templates/clips/changelog/2026-07-30-google-calendar-warning.md +6 -0
  96. package/corpus/templates/content/.agents/skills/content-product-development/SKILL.md +47 -0
  97. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +72 -8
  98. package/corpus/templates/content/changelog/2026-07-30-the-slash-command-hint-now-stays-on-only-the-active-empty-li.md +6 -0
  99. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +506 -11
  100. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +148 -17
  101. package/corpus/templates/design/app/components/design/canvas-interactions/design-canvas-interactions.ts +357 -0
  102. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +7 -466
  103. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +15 -311
  104. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +19 -997
  105. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +8 -1216
  106. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +31 -38
  107. package/corpus/templates/design/package.json +0 -1
  108. package/corpus/templates/dispatch/AGENTS.md +8 -0
  109. package/corpus/templates/dispatch/DEVELOPING.md +29 -0
  110. package/corpus/templates/dispatch/actions/view-screen.ts +34 -2
  111. package/corpus/templates/dispatch/app/i18n-data.ts +457 -0
  112. package/corpus/templates/dispatch/changelog/2026-07-30-delegated-dispatch-work-continues-reliably-in-the-background.md +6 -0
  113. package/corpus/templates/dispatch/changelog/2026-07-30-find-failed-runs-across-apps.md +6 -0
  114. package/corpus/templates/dispatch/netlify.toml +3 -0
  115. package/corpus/templates/slides/.agents/skills/analytics-data-for-decks/SKILL.md +8 -12
  116. package/corpus/templates/slides/AGENTS.md +4 -4
  117. package/corpus/templates/slides/actions/duplicate-deck.ts +19 -4
  118. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +2 -10
  119. package/corpus/templates/slides/app/components/deck/MermaidRenderer.tsx +12 -1
  120. package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +30 -13
  121. package/corpus/templates/slides/app/components/editor/DeckEditorSkeleton.tsx +35 -0
  122. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +63 -56
  123. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +21 -76
  124. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +1110 -292
  125. package/corpus/templates/slides/app/components/editor/SlideOverflowWarning.tsx +53 -0
  126. package/corpus/templates/slides/app/components/editor/SlideStyleInspector.tsx +235 -18
  127. package/corpus/templates/slides/app/components/editor/SpeakerNotesPanel.tsx +4 -1
  128. package/corpus/templates/slides/app/components/editor/canvas-interactions/index.ts +11 -0
  129. package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +129 -0
  130. package/corpus/templates/slides/app/components/editor/selection-overlay-measurement.ts +70 -0
  131. package/corpus/templates/slides/app/components/editor/slide-object-interactions.ts +519 -65
  132. package/corpus/templates/slides/app/components/visual-editor/CanvasCommentPins.tsx +36 -426
  133. package/corpus/templates/slides/app/components/visual-editor/DrawOverlay.tsx +19 -458
  134. package/corpus/templates/slides/app/context/DeckContext.tsx +179 -72
  135. package/corpus/templates/slides/app/global.css +105 -0
  136. package/corpus/templates/slides/app/i18n/en-US.ts +8 -0
  137. package/corpus/templates/slides/app/lib/deck-editor-loading.ts +26 -0
  138. package/corpus/templates/slides/app/lib/mermaid-blocks.ts +27 -0
  139. package/corpus/templates/slides/app/pages/DeckEditor.tsx +71 -38
  140. package/corpus/templates/slides/app/pages/Index.tsx +98 -41
  141. package/corpus/templates/slides/changelog/2026-07-30-deck-loading-no-longer-flashes-an-unavailable-message.md +6 -0
  142. package/corpus/templates/slides/changelog/2026-07-30-duplicating-a-deck-from-the-deck-list-now-opens-the-copy-imm.md +6 -0
  143. package/corpus/templates/slides/changelog/2026-07-30-layout-overflow-warning-is-readable-and-dismissible.md +6 -0
  144. package/corpus/templates/slides/changelog/2026-07-30-shared-canvas-annotations.md +6 -0
  145. package/corpus/templates/slides/changelog/2026-07-30-slide-objects-can-be-moved-as-a-group-copied-and-pasted-with.md +6 -0
  146. package/corpus/templates/slides/changelog/2026-07-30-slide-text-editing-and-object-controls-now-match-google-slides.md +6 -0
  147. package/corpus/templates/slides/changelog/2026-07-30-style-panel-now-scrolls-with-speaker-notes-open-shows-the-sl.md +6 -0
  148. package/corpus/templates/slides/changelog/2026-07-30-top-toolbar-controls-now-use-consistent-sizing-with-undo-and.md +6 -0
  149. package/corpus/templates/slides/netlify.toml +3 -1
  150. package/corpus/templates/slides/package.json +0 -1
  151. package/corpus/templates/slides/server/lib/chat-attachments.ts +18 -0
  152. package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -0
  153. package/corpus/templates/slides/vite.config.ts +0 -1
  154. package/corpus/toolkit/CHANGELOG.md +13 -0
  155. package/corpus/toolkit/README.md +19 -0
  156. package/corpus/toolkit/agent-native.eject.json +38 -0
  157. package/corpus/toolkit/package.json +29 -1
  158. package/corpus/toolkit/src/canvas-annotations/CanvasCommentPins.tsx +861 -0
  159. package/corpus/toolkit/src/canvas-annotations/DrawOverlay.tsx +1233 -0
  160. package/corpus/toolkit/src/canvas-annotations/index.ts +15 -0
  161. package/corpus/toolkit/src/canvas-annotations/types.ts +14 -0
  162. package/corpus/toolkit/src/canvas-interactions/canvas-interactions.ts +933 -0
  163. package/corpus/toolkit/src/canvas-interactions/index.ts +67 -0
  164. package/corpus/toolkit/src/design-tweaks/scrub-input-utils.ts +311 -0
  165. package/corpus/toolkit/src/design-tweaks/scrub-input.tsx +491 -0
  166. package/corpus/toolkit/src/design-tweaks/visual-style-controls.tsx +26 -171
  167. package/corpus/toolkit/src/index.ts +1 -0
  168. package/dist/a2a/client.d.ts +23 -0
  169. package/dist/a2a/client.d.ts.map +1 -1
  170. package/dist/a2a/client.js +309 -44
  171. package/dist/a2a/client.js.map +1 -1
  172. package/dist/a2a/correlation.d.ts +1 -0
  173. package/dist/a2a/correlation.d.ts.map +1 -1
  174. package/dist/a2a/correlation.js +27 -0
  175. package/dist/a2a/correlation.js.map +1 -1
  176. package/dist/a2a/types.d.ts +4 -0
  177. package/dist/a2a/types.d.ts.map +1 -1
  178. package/dist/a2a/types.js.map +1 -1
  179. package/dist/action.d.ts +3 -0
  180. package/dist/action.d.ts.map +1 -1
  181. package/dist/action.js.map +1 -1
  182. package/dist/agent/engine/registry.d.ts.map +1 -1
  183. package/dist/agent/engine/registry.js +34 -7
  184. package/dist/agent/engine/registry.js.map +1 -1
  185. package/dist/agent/production-agent.d.ts +40 -1
  186. package/dist/agent/production-agent.d.ts.map +1 -1
  187. package/dist/agent/production-agent.js +113 -15
  188. package/dist/agent/production-agent.js.map +1 -1
  189. package/dist/agent/run-loop-with-resume.d.ts +21 -0
  190. package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
  191. package/dist/agent/run-loop-with-resume.js +163 -4
  192. package/dist/agent/run-loop-with-resume.js.map +1 -1
  193. package/dist/agent/run-manager.d.ts +16 -9
  194. package/dist/agent/run-manager.d.ts.map +1 -1
  195. package/dist/agent/run-manager.js +93 -42
  196. package/dist/agent/run-manager.js.map +1 -1
  197. package/dist/agent/thread-debug-history.d.ts +10 -0
  198. package/dist/agent/thread-debug-history.d.ts.map +1 -0
  199. package/dist/agent/thread-debug-history.js +68 -0
  200. package/dist/agent/thread-debug-history.js.map +1 -0
  201. package/dist/agent/types.d.ts +3 -1
  202. package/dist/agent/types.d.ts.map +1 -1
  203. package/dist/agent/types.js.map +1 -1
  204. package/dist/cli/create.d.ts.map +1 -1
  205. package/dist/cli/create.js +6 -1
  206. package/dist/cli/create.js.map +1 -1
  207. package/dist/cli/templates-meta.js +2 -2
  208. package/dist/cli/templates-meta.js.map +1 -1
  209. package/dist/client/agent-chat-adapter.d.ts +1 -1
  210. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  211. package/dist/client/agent-chat-adapter.js +76 -13
  212. package/dist/client/agent-chat-adapter.js.map +1 -1
  213. package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
  214. package/dist/client/resources/McpIntegrationDialog.js +1 -1
  215. package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
  216. package/dist/client/sse-event-processor.d.ts.map +1 -1
  217. package/dist/client/sse-event-processor.js +12 -3
  218. package/dist/client/sse-event-processor.js.map +1 -1
  219. package/dist/collab/awareness.d.ts +2 -2
  220. package/dist/collab/awareness.d.ts.map +1 -1
  221. package/dist/db/client.d.ts.map +1 -1
  222. package/dist/db/client.js +48 -17
  223. package/dist/db/client.js.map +1 -1
  224. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  225. package/dist/integrations/adapters/slack.js +7 -3
  226. package/dist/integrations/adapters/slack.js.map +1 -1
  227. package/dist/localization/default-messages.d.ts +43 -0
  228. package/dist/localization/default-messages.d.ts.map +1 -1
  229. package/dist/localization/default-messages.js +43 -0
  230. package/dist/localization/default-messages.js.map +1 -1
  231. package/dist/notifications/routes.d.ts +2 -2
  232. package/dist/observability/traces.d.ts +3 -1
  233. package/dist/observability/traces.d.ts.map +1 -1
  234. package/dist/observability/traces.js +73 -4
  235. package/dist/observability/traces.js.map +1 -1
  236. package/dist/progress/routes.d.ts +1 -1
  237. package/dist/provider-api/actions/custom-provider-registration.d.ts +12 -12
  238. package/dist/provider-api/actions/provider-api.d.ts +13 -13
  239. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  240. package/dist/resources/handlers.d.ts +1 -1
  241. package/dist/scripts/call-agent.d.ts.map +1 -1
  242. package/dist/scripts/call-agent.js +233 -10
  243. package/dist/scripts/call-agent.js.map +1 -1
  244. package/dist/scripts/describe-workspace-apps.js +2 -2
  245. package/dist/scripts/describe-workspace-apps.js.map +1 -1
  246. package/dist/secrets/crypto.d.ts +31 -21
  247. package/dist/secrets/crypto.d.ts.map +1 -1
  248. package/dist/secrets/crypto.js +108 -33
  249. package/dist/secrets/crypto.js.map +1 -1
  250. package/dist/secrets/storage.d.ts +3 -5
  251. package/dist/secrets/storage.d.ts.map +1 -1
  252. package/dist/secrets/storage.js +40 -25
  253. package/dist/secrets/storage.js.map +1 -1
  254. package/dist/server/agent-capabilities.js +1 -1
  255. package/dist/server/agent-capabilities.js.map +1 -1
  256. package/dist/server/agent-chat/action-filters-a2a.d.ts +17 -3
  257. package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
  258. package/dist/server/agent-chat/action-filters-a2a.js +92 -3
  259. package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
  260. package/dist/server/agent-chat/context-tools.d.ts.map +1 -1
  261. package/dist/server/agent-chat/context-tools.js +2 -0
  262. package/dist/server/agent-chat/context-tools.js.map +1 -1
  263. package/dist/server/agent-chat/plugin-options.d.ts +23 -0
  264. package/dist/server/agent-chat/plugin-options.d.ts.map +1 -1
  265. package/dist/server/agent-chat/plugin-options.js +4 -1
  266. package/dist/server/agent-chat/plugin-options.js.map +1 -1
  267. package/dist/server/agent-chat/prompt-resources.js +1 -1
  268. package/dist/server/agent-chat/prompt-resources.js.map +1 -1
  269. package/dist/server/agent-chat-plugin.d.ts +2 -1
  270. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  271. package/dist/server/agent-chat-plugin.js +79 -56
  272. package/dist/server/agent-chat-plugin.js.map +1 -1
  273. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  274. package/dist/templates/default/.agents/skills/secrets/SKILL.md +14 -7
  275. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +14 -7
  276. package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +18 -7
  277. package/dist/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +15 -14
  278. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +14 -7
  279. package/dist/vite/client.d.ts.map +1 -1
  280. package/dist/vite/client.js +1 -0
  281. package/dist/vite/client.js.map +1 -1
  282. package/docs/content/agent-native-toolkit.mdx +13 -6
  283. package/docs/content/cloneable-saas.mdx +5 -5
  284. package/docs/content/creating-templates.mdx +9 -0
  285. package/docs/content/deployment.mdx +14 -10
  286. package/docs/content/docs-components.mdx +491 -0
  287. package/docs/content/doctor.mdx +8 -1
  288. package/docs/content/drop-in-agent.mdx +1 -1
  289. package/docs/content/extensions.mdx +18 -18
  290. package/docs/content/faq.mdx +4 -4
  291. package/docs/content/key-concepts.mdx +30 -21
  292. package/docs/content/template-brain-developers.mdx +4 -1
  293. package/docs/content/template-mail-developers.mdx +4 -1
  294. package/docs/content/what-is-agent-native.mdx +6 -6
  295. package/package.json +2 -2
  296. package/src/a2a/client.ts +449 -66
  297. package/src/a2a/correlation.ts +31 -0
  298. package/src/a2a/types.ts +4 -0
  299. package/src/action.ts +3 -0
  300. package/src/agent/engine/registry.ts +45 -5
  301. package/src/agent/production-agent.ts +151 -18
  302. package/src/agent/run-loop-with-resume.ts +190 -3
  303. package/src/agent/run-manager.ts +117 -41
  304. package/src/agent/thread-debug-history.ts +86 -0
  305. package/src/agent/types.ts +3 -1
  306. package/src/cli/create.ts +11 -1
  307. package/src/cli/templates-meta.ts +2 -2
  308. package/src/client/agent-chat-adapter.ts +91 -13
  309. package/src/client/resources/McpIntegrationDialog.tsx +11 -9
  310. package/src/client/sse-event-processor.ts +17 -3
  311. package/src/db/client.ts +57 -17
  312. package/src/integrations/adapters/slack.ts +8 -3
  313. package/src/localization/default-messages.ts +44 -0
  314. package/src/observability/traces.ts +78 -5
  315. package/src/scripts/call-agent.ts +290 -9
  316. package/src/scripts/describe-workspace-apps.ts +2 -2
  317. package/src/secrets/crypto.ts +126 -34
  318. package/src/secrets/storage.ts +61 -25
  319. package/src/server/agent-capabilities.ts +1 -1
  320. package/src/server/agent-chat/action-filters-a2a.ts +111 -7
  321. package/src/server/agent-chat/context-tools.ts +2 -0
  322. package/src/server/agent-chat/plugin-options.ts +34 -1
  323. package/src/server/agent-chat/prompt-resources.ts +1 -1
  324. package/src/server/agent-chat-plugin.ts +91 -59
  325. package/src/templates/default/.agents/skills/secrets/SKILL.md +14 -7
  326. package/src/templates/headless/.agents/skills/secrets/SKILL.md +14 -7
  327. package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +18 -7
  328. package/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +15 -14
  329. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +14 -7
  330. package/src/vite/client.ts +1 -0
@@ -0,0 +1,491 @@
1
+ import { IconArrowsHorizontal } from "@tabler/icons-react";
2
+ import {
3
+ useEffect,
4
+ useId,
5
+ useRef,
6
+ useState,
7
+ type KeyboardEvent,
8
+ type PointerEvent,
9
+ type ReactNode,
10
+ } from "react";
11
+
12
+ import { Input } from "../ui/input.js";
13
+ import { Label } from "../ui/label.js";
14
+ import {
15
+ Tooltip,
16
+ TooltipContent,
17
+ TooltipProvider,
18
+ TooltipTrigger,
19
+ } from "../ui/tooltip.js";
20
+ import { cn } from "../utils.js";
21
+ import {
22
+ formatScrubValue,
23
+ getScrubStepFromEvent,
24
+ normalizeScrubNumber,
25
+ parseScrubExpression,
26
+ roundScrubDragValue,
27
+ startScrubDrag,
28
+ updateScrubDrag,
29
+ type ScrubExpressionOptions,
30
+ } from "./scrub-input-utils.js";
31
+
32
+ type ScrubInputIcon = (props: {
33
+ className?: string;
34
+ "aria-hidden"?: boolean;
35
+ }) => ReactNode;
36
+
37
+ export interface ScrubInputChangeMeta {
38
+ source: "commit" | "keyboard" | "scrub";
39
+ expression?: string;
40
+ /**
41
+ * Gesture-lifecycle signal for downstream consumers that want to throttle
42
+ * expensive work during a drag and only do the expensive commit once.
43
+ *
44
+ * - "preview": a live, in-progress tick — e.g. one pointermove sample while
45
+ * scrubbing. There can be many of these per gesture; treat each as a
46
+ * cheap, throttleable preview of the value, not a point to commit at full
47
+ * cost.
48
+ * - "commit": the gesture's authoritative, final value. Fired exactly once
49
+ * per gesture: on pointerup that ends a scrub drag, and for every
50
+ * `source: "commit"` (blur/Enter) or `source: "keyboard"` (arrow step)
51
+ * change, since those are already discrete, complete edits.
52
+ */
53
+ phase: "preview" | "commit";
54
+ /**
55
+ * Set when an arrow-key nudge fires on a `mixed` selection (see
56
+ * `handleKeyDown`): there is no single current value to step from across a
57
+ * mixed selection, so `onChange`'s `value` arg is the step delta itself
58
+ * (not a new absolute value) and consumers that support per-target relative
59
+ * application should add this delta to each selected target's own current
60
+ * value instead of overwriting every target with `value`. Omitted for
61
+ * every other change — existing consumers that don't check for it keep
62
+ * receiving absolute values exactly as before.
63
+ */
64
+ relativeDelta?: number;
65
+ }
66
+
67
+ export interface ScrubInputProps extends ScrubExpressionOptions {
68
+ label: string;
69
+ value: number;
70
+ onChange: (value: number, meta: ScrubInputChangeMeta) => void;
71
+ id?: string;
72
+ step?: number;
73
+ icon?: ScrubInputIcon | null;
74
+ /** Use the compact icon-only prefix treatment without relying on CSS selectors. */
75
+ prefix?: "label" | "icon";
76
+ disabled?: boolean;
77
+ placeholder?: string;
78
+ mixed?: boolean;
79
+ mixedLabel?: string;
80
+ className?: string;
81
+ inputClassName?: string;
82
+ labelClassName?: string;
83
+ ariaLabel?: string;
84
+ tooltipLabel?: string;
85
+ }
86
+
87
+ export interface PendingScrubCommit {
88
+ value: number;
89
+ /** Incoming prop value at commit time. While this exact value remains, the
90
+ * host has not acknowledged the write yet and the optimistic draft should
91
+ * stay visible. A different incoming value is authoritative host
92
+ * normalization/rejection and must supersede the optimistic draft. */
93
+ baseline: number;
94
+ }
95
+
96
+ export function resolvePendingScrubCommit(
97
+ pending: PendingScrubCommit | null,
98
+ incomingValue: number,
99
+ options: ScrubExpressionOptions,
100
+ ): "none" | "hold" | "confirmed" | "superseded" {
101
+ if (pending === null) return "none";
102
+ const incoming = normalizeScrubNumber(incomingValue, options);
103
+ if (incoming === pending.value) return "confirmed";
104
+ return incoming === pending.baseline ? "hold" : "superseded";
105
+ }
106
+
107
+ export function VisualScrubInput({
108
+ label,
109
+ value,
110
+ onChange,
111
+ id,
112
+ step = 1,
113
+ unit,
114
+ min,
115
+ max,
116
+ precision,
117
+ icon: Icon = IconArrowsHorizontal,
118
+ prefix = "label",
119
+ disabled = false,
120
+ placeholder,
121
+ mixed = false,
122
+ mixedLabel,
123
+ className,
124
+ inputClassName,
125
+ labelClassName,
126
+ ariaLabel,
127
+ tooltipLabel,
128
+ }: ScrubInputProps) {
129
+ const resolvedMixedLabel = mixedLabel ?? "Mixed";
130
+ const generatedId = useId();
131
+ const inputId = id ?? generatedId;
132
+ const [draft, setDraft] = useState(() =>
133
+ mixed ? resolvedMixedLabel : formatScrubValue(value, { unit, precision }),
134
+ );
135
+ // Track the latest draft in a ref so commitDraft always reads the most
136
+ // up-to-date value even if the blur event fires before the React state
137
+ // update has been committed to the render tree (concurrent mode / batching).
138
+ const draftRef = useRef(draft);
139
+ const [focused, setFocused] = useState(false);
140
+ const [dragging, setDragging] = useState(false);
141
+ const inputRef = useRef<HTMLInputElement>(null);
142
+ const skipNextBlurCommitRef = useRef(false);
143
+ const dragRef = useRef({
144
+ pointerId: -1,
145
+ drag: startScrubDrag(0),
146
+ });
147
+ // The last normalized value emitted as a "preview" scrub tick, so endDrag
148
+ // can re-emit it once as the gesture's authoritative "commit" — without
149
+ // recomputing from stale pointer deltas after pointer capture is released.
150
+ const lastScrubValueRef = useRef(value);
151
+ // The most recent value THIS input committed (typed Enter/blur, keyboard
152
+ // nudge, or scrub release) that the host hasn't echoed back yet. While this
153
+ // is set, the resync effect below must hold the optimistic committed
154
+ // display instead of snapping back to the still-stale incoming `value`
155
+ // prop — otherwise a round-trip slower than one React render (host commit
156
+ // -> computedStyles update -> fresh `value` prop) clobbers the just-typed
157
+ // value back to the old one the instant focus leaves the input, which
158
+ // reads as "Enter resets to the old value". Cleared as soon as a fresh
159
+ // `value` prop confirms (or supersedes) the pending commit.
160
+ const pendingCommitRef = useRef<PendingScrubCommit | null>(null);
161
+ const options = { unit, min, max, precision };
162
+
163
+ useEffect(() => {
164
+ if (mixed) pendingCommitRef.current = null;
165
+ const resolution = resolvePendingScrubCommit(
166
+ pendingCommitRef.current,
167
+ value,
168
+ options,
169
+ );
170
+ if (resolution !== "none") {
171
+ if (resolution === "confirmed" || resolution === "superseded") {
172
+ // The host either echoed exactly what we committed or returned a new,
173
+ // authoritative normalized/rejected value. In both cases resume prop
174
+ // synchronization. The old equality-only logic held forever on the
175
+ // second path, leaving the field permanently stuck on a value the
176
+ // canvas never accepted.
177
+ pendingCommitRef.current = null;
178
+ } else {
179
+ // Still seeing the exact pre-commit prop — don't stomp the optimistic
180
+ // draft while the source-write round trip is pending.
181
+ return;
182
+ }
183
+ }
184
+ if (!focused) {
185
+ const formatted = mixed
186
+ ? resolvedMixedLabel
187
+ : formatScrubValue(value, { unit, precision });
188
+ draftRef.current = formatted;
189
+ setDraft(formatted);
190
+ }
191
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- `options` is a fresh object every render; the individual fields it's built from (unit/min/max/precision) are already listed below.
192
+ }, [focused, max, min, mixed, precision, resolvedMixedLabel, unit, value]);
193
+
194
+ const resolvedTooltipLabel = tooltipLabel ?? ariaLabel ?? label;
195
+
196
+ const setNextValue = (nextValue: number, meta: ScrubInputChangeMeta) => {
197
+ const normalized = normalizeScrubNumber(nextValue, options);
198
+ // Mark commit-phase writes as pending confirmation so the resync effect
199
+ // holds this optimistic display instead of reverting to a stale `value`
200
+ // prop before the host's round-trip lands (see pendingCommitRef above).
201
+ // Preview ticks don't need this: they're expected to be superseded by
202
+ // the next tick or the gesture's own final commit almost immediately.
203
+ if (meta.phase === "commit") {
204
+ pendingCommitRef.current = {
205
+ value: normalized,
206
+ baseline: normalizeScrubNumber(value, options),
207
+ };
208
+ }
209
+ onChange(normalized, meta);
210
+ const formatted = formatScrubValue(normalized, options);
211
+ draftRef.current = formatted;
212
+ setDraft(formatted);
213
+ return normalized;
214
+ };
215
+
216
+ const commitDraft = () => {
217
+ // Always read from the ref so we use the latest typed value even if the
218
+ // React render with the updated draft state hasn't committed yet (e.g.
219
+ // when blur fires in the same synchronous batch as the last onChange).
220
+ const currentDraft = draftRef.current;
221
+ if (mixed && currentDraft === resolvedMixedLabel) return;
222
+ const parsed = parseScrubExpression(currentDraft, value, options);
223
+ if (!parsed) {
224
+ const reverted = mixed
225
+ ? resolvedMixedLabel
226
+ : formatScrubValue(value, options);
227
+ draftRef.current = reverted;
228
+ setDraft(reverted);
229
+ return;
230
+ }
231
+
232
+ draftRef.current = parsed.normalized;
233
+ setDraft(parsed.normalized);
234
+ // From a mixed selection every explicitly typed value must commit, even
235
+ // when it equals the placeholder `value` prop (e.g. typing "0"): the
236
+ // selected objects hold differing values, so "no change" is meaningless.
237
+ if (parsed.value !== value || mixed) {
238
+ // See setNextValue's pendingCommitRef comment — this text-commit path
239
+ // (Enter/blur) bypasses setNextValue, so mark it pending here too.
240
+ pendingCommitRef.current = {
241
+ value: parsed.value,
242
+ baseline: normalizeScrubNumber(value, options),
243
+ };
244
+ onChange(parsed.value, {
245
+ source: "commit",
246
+ expression: currentDraft,
247
+ phase: "commit",
248
+ });
249
+ }
250
+ };
251
+
252
+ const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {
253
+ if (event.key === "ArrowUp" || event.key === "ArrowDown") {
254
+ event.preventDefault();
255
+ const direction = event.key === "ArrowUp" ? 1 : -1;
256
+ // getScrubStepFromEvent handles shiftKey (×10) and altKey (÷10).
257
+ // Cmd (metaKey) mirrors Shift for ×10 — editor convention on macOS.
258
+ const baseStep = getScrubStepFromEvent(event, step);
259
+ const cmdMultiplier = event.metaKey && !event.shiftKey ? 10 : 1;
260
+ const delta = direction * baseStep * cmdMultiplier;
261
+ // Mixed selection: the `value` prop is only a placeholder (typically 0)
262
+ // — there's no single current value to step from, and there's no
263
+ // typed draft either (mixed keeps the draft as the literal "Mixed"
264
+ // string, see commitDraft's guard). Figma's behavior here is a
265
+ // *relative* nudge: apply the same +/-delta to each selected object's
266
+ // own value rather than snapping every object to one absolute number.
267
+ // ScrubInput itself can't resolve each target's individual value, so
268
+ // emit the delta via `onChange` (as both `value` and
269
+ // `meta.relativeDelta`) and let the consumer apply it per-target. Do
270
+ // NOT route through setNextValue: that formats/displays one absolute
271
+ // number in the draft, which would incorrectly replace the "Mixed"
272
+ // placeholder text with a single value that was never actually common
273
+ // to the whole selection.
274
+ if (mixed) {
275
+ onChange(delta, {
276
+ source: "keyboard",
277
+ phase: "commit",
278
+ relativeDelta: delta,
279
+ });
280
+ return;
281
+ }
282
+ // Step from the currently typed draft, not the last-committed `value`
283
+ // prop — otherwise an in-progress, uncommitted edit (typed but not yet
284
+ // blurred/entered) is silently discarded the moment an arrow key is
285
+ // pressed. Parse the draft the same way commitDraft does, falling back
286
+ // to `value` only when the draft doesn't parse (e.g. empty/invalid).
287
+ const draftParsed = parseScrubExpression(
288
+ draftRef.current,
289
+ value,
290
+ options,
291
+ );
292
+ const base = draftParsed ? draftParsed.value : value;
293
+ setNextValue(base + delta, {
294
+ source: "keyboard",
295
+ phase: "commit",
296
+ });
297
+ return;
298
+ }
299
+
300
+ if (event.key === "Enter") {
301
+ event.preventDefault();
302
+ commitDraft();
303
+ skipNextBlurCommitRef.current = true;
304
+ event.currentTarget.blur();
305
+ return;
306
+ }
307
+
308
+ if (event.key === "Escape") {
309
+ event.preventDefault();
310
+ const reverted = mixed
311
+ ? resolvedMixedLabel
312
+ : formatScrubValue(value, options);
313
+ draftRef.current = reverted;
314
+ setDraft(reverted);
315
+ skipNextBlurCommitRef.current = true;
316
+ event.currentTarget.blur();
317
+ }
318
+ };
319
+
320
+ const handlePointerDown = (event: PointerEvent<HTMLLabelElement>) => {
321
+ if (disabled || event.button !== 0) return;
322
+ event.preventDefault();
323
+ dragRef.current = {
324
+ pointerId: event.pointerId,
325
+ drag: startScrubDrag(event.clientX),
326
+ };
327
+ // Re-seed the gesture's running base from the current prop right as the
328
+ // drag starts. Without this, a stale `lastScrubValueRef` left over from a
329
+ // previous gesture (or from an out-of-band prop update that arrived while
330
+ // not dragging) would silently become this gesture's starting point
331
+ // instead of the value actually displayed when the user grabbed the
332
+ // control.
333
+ lastScrubValueRef.current = value;
334
+ event.currentTarget.setPointerCapture(event.pointerId);
335
+ setDragging(true);
336
+ };
337
+
338
+ const handlePointerMove = (event: PointerEvent<HTMLLabelElement>) => {
339
+ if (!dragging || dragRef.current.pointerId !== event.pointerId) return;
340
+ // Mixed selection: scrubbing has no meaningful base value (the `value`
341
+ // prop is a placeholder), so committing drag deltas would snap every
342
+ // selected object to a step-from-0 value. Keep the drag inert; releasing
343
+ // without a committed drag focuses the input so the user can type an
344
+ // explicit value that then applies to all.
345
+ if (mixed) return;
346
+ // updateScrubDrag mirrors the jitter-threshold + hasDragged bookkeeping
347
+ // (see scrub-input-utils.ts) so it can be unit tested in isolation from
348
+ // real DOM pointer events.
349
+ const tick = updateScrubDrag(dragRef.current.drag, event.clientX);
350
+ dragRef.current.drag = tick.state;
351
+ if (tick.deltaX === null) return;
352
+ // Use incremental deltas from the last move so that clamped/rounded values
353
+ // committed by onChange are respected. A total-delta approach would create
354
+ // a dead zone equal to the amount dragged past the clamp boundary.
355
+ //
356
+ // Accumulate from this gesture's OWN last emitted value
357
+ // (lastScrubValueRef), not the `value` prop. The prop only reflects
358
+ // whatever the host last echoed back through computedStyles — a "preview"
359
+ // phase commit is not guaranteed to round-trip before the next
360
+ // pointermove tick fires (the host may debounce/throttle/skip preview
361
+ // writes), so re-reading `value` here would recompute every tick from a
362
+ // stale, pre-drag base plus one tiny incremental delta: the displayed
363
+ // number barely creeps from the original value instead of following the
364
+ // cursor, which reads as jittery/near-random rather than a smooth
365
+ // continuum. The gesture's own running total is always current because
366
+ // this component sets it itself on every tick below.
367
+ const next =
368
+ lastScrubValueRef.current +
369
+ tick.deltaX *
370
+ getScrubStepFromEvent(
371
+ { altKey: event.altKey, shiftKey: event.shiftKey },
372
+ step,
373
+ );
374
+ // Px-type fields snap to whole numbers while scrubbing (see
375
+ // roundScrubDragValue) even though `precision` — which also governs typed
376
+ // input and keyboard nudges — allows a decimal. Rounding here, before
377
+ // setNextValue's own normalizeScrubNumber pass, keeps every subsequent
378
+ // incremental delta measured from an already-whole value instead of
379
+ // drifting on fractional leftovers.
380
+ lastScrubValueRef.current = setNextValue(roundScrubDragValue(next, unit), {
381
+ source: "scrub",
382
+ phase: "preview",
383
+ });
384
+ };
385
+
386
+ const endDrag = (event: PointerEvent<HTMLLabelElement>) => {
387
+ if (dragRef.current.pointerId !== event.pointerId) return;
388
+ event.currentTarget.releasePointerCapture(event.pointerId);
389
+ const wasDrag = dragRef.current.drag.hasDragged;
390
+ setDragging(false);
391
+ // A real scrub drag emitted only "preview" ticks via handlePointerMove.
392
+ // Emit exactly one authoritative "commit" here with the final value so a
393
+ // downstream consumer can distinguish "gesture finished" from "still
394
+ // dragging" — without this, the last preview tick would be the only
395
+ // signal, and a consumer that ignores preview ticks would never commit.
396
+ if (wasDrag && !mixed) {
397
+ // See setNextValue's pendingCommitRef comment — mark this gesture's
398
+ // authoritative value as pending confirmation so releasing the drag
399
+ // can't be clobbered back to the pre-drag value by a slow host
400
+ // round-trip (same class of bug as the Enter/blur text-commit case).
401
+ pendingCommitRef.current = {
402
+ value: lastScrubValueRef.current,
403
+ baseline: normalizeScrubNumber(value, options),
404
+ };
405
+ onChange(lastScrubValueRef.current, {
406
+ source: "scrub",
407
+ phase: "commit",
408
+ });
409
+ }
410
+ // If the pointer was released without dragging (a plain click), focus the
411
+ // input so the user can type immediately — mirrors the design editor's label click
412
+ // behaviour (the event.preventDefault() in handlePointerDown blocks the
413
+ // native label→input focus transfer).
414
+ if (!wasDrag && !disabled) {
415
+ inputRef.current?.focus();
416
+ }
417
+ };
418
+
419
+ return (
420
+ <div className={cn("flex min-w-0 items-center gap-1.5", className)}>
421
+ <TooltipProvider>
422
+ <Tooltip>
423
+ <TooltipTrigger asChild>
424
+ <Label
425
+ htmlFor={inputId}
426
+ onPointerDown={handlePointerDown}
427
+ onPointerMove={handlePointerMove}
428
+ onPointerUp={endDrag}
429
+ onPointerCancel={endDrag}
430
+ className={cn(
431
+ "flex h-6 shrink-0 cursor-ew-resize select-none items-center gap-1 truncate whitespace-nowrap rounded-sm !text-[11px] text-muted-foreground transition-colors",
432
+ prefix === "icon" ? "w-8 justify-center gap-0" : "w-20",
433
+ "hover:bg-[var(--design-editor-control-bg)] hover:text-foreground",
434
+ dragging &&
435
+ "bg-[var(--design-editor-control-bg)] text-foreground",
436
+ disabled && "pointer-events-none cursor-not-allowed opacity-50",
437
+ labelClassName,
438
+ )}
439
+ >
440
+ {Icon ? (
441
+ <Icon className="size-3 shrink-0" aria-hidden={true} />
442
+ ) : null}
443
+ <span className={cn("truncate", prefix === "icon" && "sr-only")}>
444
+ {label}
445
+ </span>
446
+ </Label>
447
+ </TooltipTrigger>
448
+ <TooltipContent>{resolvedTooltipLabel}</TooltipContent>
449
+ </Tooltip>
450
+ </TooltipProvider>
451
+ <Input
452
+ ref={inputRef}
453
+ id={inputId}
454
+ value={draft}
455
+ disabled={disabled}
456
+ placeholder={placeholder}
457
+ inputMode="decimal"
458
+ aria-label={ariaLabel ?? label}
459
+ onFocus={(event) => {
460
+ setFocused(true);
461
+ if (mixed && mixedLabel !== undefined) {
462
+ const formatted = formatScrubValue(value, options);
463
+ draftRef.current = formatted;
464
+ setDraft(formatted);
465
+ }
466
+ event.currentTarget.select();
467
+ }}
468
+ onBlur={() => {
469
+ setFocused(false);
470
+ if (skipNextBlurCommitRef.current) {
471
+ skipNextBlurCommitRef.current = false;
472
+ return;
473
+ }
474
+ commitDraft();
475
+ }}
476
+ onChange={(event) => {
477
+ draftRef.current = event.target.value;
478
+ setDraft(event.target.value);
479
+ }}
480
+ onKeyDown={handleKeyDown}
481
+ className={cn(
482
+ // Compact design-editor: h-6, 11px tabular text, ring-1 with no offset.
483
+ "h-6 w-0 min-w-0 flex-1 !text-[11px] tabular-nums",
484
+ "focus-visible:ring-1 focus-visible:ring-offset-0",
485
+ inputClassName,
486
+ mixed && "text-muted-foreground",
487
+ )}
488
+ />
489
+ </div>
490
+ );
491
+ }