@agent-native/core 0.37.2 → 0.38.0

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 (377) hide show
  1. package/README.md +19 -6
  2. package/dist/action.d.ts +60 -2
  3. package/dist/action.d.ts.map +1 -1
  4. package/dist/action.js +6 -2
  5. package/dist/action.js.map +1 -1
  6. package/dist/agent/production-agent.d.ts +12 -6
  7. package/dist/agent/production-agent.d.ts.map +1 -1
  8. package/dist/agent/production-agent.js +161 -11
  9. package/dist/agent/production-agent.js.map +1 -1
  10. package/dist/agent/types.d.ts +2 -0
  11. package/dist/agent/types.d.ts.map +1 -1
  12. package/dist/agent/types.js.map +1 -1
  13. package/dist/catalog.json +2 -2
  14. package/dist/cli/connect.d.ts.map +1 -1
  15. package/dist/cli/connect.js +15 -0
  16. package/dist/cli/connect.js.map +1 -1
  17. package/dist/cli/index.js +10 -6
  18. package/dist/cli/index.js.map +1 -1
  19. package/dist/cli/plan-publish-store.d.ts +52 -0
  20. package/dist/cli/plan-publish-store.d.ts.map +1 -0
  21. package/dist/cli/plan-publish-store.js +103 -0
  22. package/dist/cli/plan-publish-store.js.map +1 -0
  23. package/dist/cli/skills.d.ts +29 -0
  24. package/dist/cli/skills.d.ts.map +1 -1
  25. package/dist/cli/skills.js +1349 -544
  26. package/dist/cli/skills.js.map +1 -1
  27. package/dist/cli/templates-meta.js +12 -12
  28. package/dist/cli/templates-meta.js.map +1 -1
  29. package/dist/client/AssistantChat.d.ts +3 -1
  30. package/dist/client/AssistantChat.d.ts.map +1 -1
  31. package/dist/client/AssistantChat.js +65 -15
  32. package/dist/client/AssistantChat.js.map +1 -1
  33. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  34. package/dist/client/MultiTabAssistantChat.js +20 -2
  35. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  36. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  37. package/dist/client/agent-chat-adapter.js +12 -0
  38. package/dist/client/agent-chat-adapter.js.map +1 -1
  39. package/dist/client/agent-engine-key.d.ts +24 -0
  40. package/dist/client/agent-engine-key.d.ts.map +1 -0
  41. package/dist/client/agent-engine-key.js +49 -0
  42. package/dist/client/agent-engine-key.js.map +1 -0
  43. package/dist/client/analytics.d.ts.map +1 -1
  44. package/dist/client/analytics.js +34 -0
  45. package/dist/client/analytics.js.map +1 -1
  46. package/dist/client/blocks/BlockView.d.ts +26 -0
  47. package/dist/client/blocks/BlockView.d.ts.map +1 -0
  48. package/dist/client/blocks/BlockView.js +24 -0
  49. package/dist/client/blocks/BlockView.js.map +1 -0
  50. package/dist/client/blocks/SchemaBlockEditor.d.ts +25 -0
  51. package/dist/client/blocks/SchemaBlockEditor.d.ts.map +1 -0
  52. package/dist/client/blocks/SchemaBlockEditor.js +72 -0
  53. package/dist/client/blocks/SchemaBlockEditor.js.map +1 -0
  54. package/dist/client/blocks/agent.d.ts +30 -0
  55. package/dist/client/blocks/agent.d.ts.map +1 -0
  56. package/dist/client/blocks/agent.js +61 -0
  57. package/dist/client/blocks/agent.js.map +1 -0
  58. package/dist/client/blocks/index.d.ts +34 -0
  59. package/dist/client/blocks/index.d.ts.map +1 -0
  60. package/dist/client/blocks/index.js +42 -0
  61. package/dist/client/blocks/index.js.map +1 -0
  62. package/dist/client/blocks/library/checklist.config.d.ts +36 -0
  63. package/dist/client/blocks/library/checklist.config.d.ts.map +1 -0
  64. package/dist/client/blocks/library/checklist.config.js +25 -0
  65. package/dist/client/blocks/library/checklist.config.js.map +1 -0
  66. package/dist/client/blocks/library/checklist.d.ts +26 -0
  67. package/dist/client/blocks/library/checklist.d.ts.map +1 -0
  68. package/dist/client/blocks/library/checklist.js +76 -0
  69. package/dist/client/blocks/library/checklist.js.map +1 -0
  70. package/dist/client/blocks/library/code-tabs.config.d.ts +36 -0
  71. package/dist/client/blocks/library/code-tabs.config.d.ts.map +1 -0
  72. package/dist/client/blocks/library/code-tabs.config.js +30 -0
  73. package/dist/client/blocks/library/code-tabs.config.js.map +1 -0
  74. package/dist/client/blocks/library/code-tabs.d.ts +3 -0
  75. package/dist/client/blocks/library/code-tabs.d.ts.map +1 -0
  76. package/dist/client/blocks/library/code-tabs.js +165 -0
  77. package/dist/client/blocks/library/code-tabs.js.map +1 -0
  78. package/dist/client/blocks/library/html.config.d.ts +37 -0
  79. package/dist/client/blocks/library/html.config.d.ts.map +1 -0
  80. package/dist/client/blocks/library/html.config.js +46 -0
  81. package/dist/client/blocks/library/html.config.js.map +1 -0
  82. package/dist/client/blocks/library/html.d.ts +21 -0
  83. package/dist/client/blocks/library/html.d.ts.map +1 -0
  84. package/dist/client/blocks/library/html.js +69 -0
  85. package/dist/client/blocks/library/html.js.map +1 -0
  86. package/dist/client/blocks/library/table.config.d.ts +30 -0
  87. package/dist/client/blocks/library/table.config.d.ts.map +1 -0
  88. package/dist/client/blocks/library/table.config.js +22 -0
  89. package/dist/client/blocks/library/table.config.js.map +1 -0
  90. package/dist/client/blocks/library/table.d.ts +8 -0
  91. package/dist/client/blocks/library/table.d.ts.map +1 -0
  92. package/dist/client/blocks/library/table.js +107 -0
  93. package/dist/client/blocks/library/table.js.map +1 -0
  94. package/dist/client/blocks/library/tabs.config.d.ts +56 -0
  95. package/dist/client/blocks/library/tabs.config.d.ts.map +1 -0
  96. package/dist/client/blocks/library/tabs.config.js +36 -0
  97. package/dist/client/blocks/library/tabs.config.js.map +1 -0
  98. package/dist/client/blocks/library/tabs.d.ts +20 -0
  99. package/dist/client/blocks/library/tabs.d.ts.map +1 -0
  100. package/dist/client/blocks/library/tabs.js +123 -0
  101. package/dist/client/blocks/library/tabs.js.map +1 -0
  102. package/dist/client/blocks/mdx.d.ts +74 -0
  103. package/dist/client/blocks/mdx.d.ts.map +1 -0
  104. package/dist/client/blocks/mdx.js +205 -0
  105. package/dist/client/blocks/mdx.js.map +1 -0
  106. package/dist/client/blocks/provider.d.ts +25 -0
  107. package/dist/client/blocks/provider.d.ts.map +1 -0
  108. package/dist/client/blocks/provider.js +19 -0
  109. package/dist/client/blocks/provider.js.map +1 -0
  110. package/dist/client/blocks/registry.d.ts +24 -0
  111. package/dist/client/blocks/registry.d.ts.map +1 -0
  112. package/dist/client/blocks/registry.js +50 -0
  113. package/dist/client/blocks/registry.js.map +1 -0
  114. package/dist/client/blocks/schema-form/introspect.d.ts +31 -0
  115. package/dist/client/blocks/schema-form/introspect.d.ts.map +1 -0
  116. package/dist/client/blocks/schema-form/introspect.js +164 -0
  117. package/dist/client/blocks/schema-form/introspect.js.map +1 -0
  118. package/dist/client/blocks/server.d.ts +22 -0
  119. package/dist/client/blocks/server.d.ts.map +1 -0
  120. package/dist/client/blocks/server.js +25 -0
  121. package/dist/client/blocks/server.js.map +1 -0
  122. package/dist/client/blocks/types.d.ts +212 -0
  123. package/dist/client/blocks/types.d.ts.map +1 -0
  124. package/dist/client/blocks/types.js +5 -0
  125. package/dist/client/blocks/types.js.map +1 -0
  126. package/dist/client/composer/ComposerPlusMenu.js +10 -1
  127. package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
  128. package/dist/client/guided-questions.d.ts +68 -0
  129. package/dist/client/guided-questions.d.ts.map +1 -1
  130. package/dist/client/guided-questions.js +158 -3
  131. package/dist/client/guided-questions.js.map +1 -1
  132. package/dist/client/index.d.ts +5 -1
  133. package/dist/client/index.d.ts.map +1 -1
  134. package/dist/client/index.js +15 -1
  135. package/dist/client/index.js.map +1 -1
  136. package/dist/client/rich-markdown-editor/BubbleToolbar.d.ts +37 -0
  137. package/dist/client/rich-markdown-editor/BubbleToolbar.d.ts.map +1 -0
  138. package/dist/client/rich-markdown-editor/BubbleToolbar.js +161 -0
  139. package/dist/client/rich-markdown-editor/BubbleToolbar.js.map +1 -0
  140. package/dist/client/rich-markdown-editor/ImageExtension.d.ts +63 -0
  141. package/dist/client/rich-markdown-editor/ImageExtension.d.ts.map +1 -0
  142. package/dist/client/rich-markdown-editor/ImageExtension.js +242 -0
  143. package/dist/client/rich-markdown-editor/ImageExtension.js.map +1 -0
  144. package/dist/client/rich-markdown-editor/RichMarkdownEditor.d.ts +51 -0
  145. package/dist/client/rich-markdown-editor/RichMarkdownEditor.d.ts.map +1 -0
  146. package/dist/client/rich-markdown-editor/RichMarkdownEditor.js +37 -0
  147. package/dist/client/rich-markdown-editor/RichMarkdownEditor.js.map +1 -0
  148. package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts +61 -0
  149. package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts.map +1 -0
  150. package/dist/client/rich-markdown-editor/SharedRichEditor.js +121 -0
  151. package/dist/client/rich-markdown-editor/SharedRichEditor.js.map +1 -0
  152. package/dist/client/rich-markdown-editor/SlashCommandMenu.d.ts +36 -0
  153. package/dist/client/rich-markdown-editor/SlashCommandMenu.d.ts.map +1 -0
  154. package/dist/client/rich-markdown-editor/SlashCommandMenu.js +193 -0
  155. package/dist/client/rich-markdown-editor/SlashCommandMenu.js.map +1 -0
  156. package/dist/client/rich-markdown-editor/extensions.d.ts +166 -0
  157. package/dist/client/rich-markdown-editor/extensions.d.ts.map +1 -0
  158. package/dist/client/rich-markdown-editor/extensions.js +222 -0
  159. package/dist/client/rich-markdown-editor/extensions.js.map +1 -0
  160. package/dist/client/rich-markdown-editor/index.d.ts +9 -0
  161. package/dist/client/rich-markdown-editor/index.d.ts.map +1 -0
  162. package/dist/client/rich-markdown-editor/index.js +9 -0
  163. package/dist/client/rich-markdown-editor/index.js.map +1 -0
  164. package/dist/client/rich-markdown-editor/uploadEditorImage.d.ts +18 -0
  165. package/dist/client/rich-markdown-editor/uploadEditorImage.d.ts.map +1 -0
  166. package/dist/client/rich-markdown-editor/uploadEditorImage.js +57 -0
  167. package/dist/client/rich-markdown-editor/uploadEditorImage.js.map +1 -0
  168. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts +91 -0
  169. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -0
  170. package/dist/client/rich-markdown-editor/useCollabReconcile.js +342 -0
  171. package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -0
  172. package/dist/client/track.d.ts +25 -0
  173. package/dist/client/track.d.ts.map +1 -0
  174. package/dist/client/track.js +53 -0
  175. package/dist/client/track.js.map +1 -0
  176. package/dist/client/use-action.d.ts.map +1 -1
  177. package/dist/client/use-action.js +6 -0
  178. package/dist/client/use-action.js.map +1 -1
  179. package/dist/client/use-session.d.ts +3 -2
  180. package/dist/client/use-session.d.ts.map +1 -1
  181. package/dist/client/use-session.js +3 -2
  182. package/dist/client/use-session.js.map +1 -1
  183. package/dist/deploy/build.d.ts +5 -0
  184. package/dist/deploy/build.d.ts.map +1 -1
  185. package/dist/deploy/build.js +67 -1
  186. package/dist/deploy/build.js.map +1 -1
  187. package/dist/extensions/schema.d.ts +1 -1
  188. package/dist/mcp/build-server.d.ts.map +1 -1
  189. package/dist/mcp/build-server.js +9 -2
  190. package/dist/mcp/build-server.js.map +1 -1
  191. package/dist/mcp/server.d.ts +1 -1
  192. package/dist/mcp/server.d.ts.map +1 -1
  193. package/dist/mcp/server.js +35 -2
  194. package/dist/mcp/server.js.map +1 -1
  195. package/dist/provider-api/index.d.ts +1 -1
  196. package/dist/provider-api/index.d.ts.map +1 -1
  197. package/dist/scripts/docs/search.d.ts.map +1 -1
  198. package/dist/scripts/docs/search.js +5 -2
  199. package/dist/scripts/docs/search.js.map +1 -1
  200. package/dist/scripts/runner.d.ts.map +1 -1
  201. package/dist/scripts/runner.js +16 -3
  202. package/dist/scripts/runner.js.map +1 -1
  203. package/dist/server/action-discovery.d.ts.map +1 -1
  204. package/dist/server/action-discovery.js +2 -0
  205. package/dist/server/action-discovery.js.map +1 -1
  206. package/dist/server/action-routes.d.ts.map +1 -1
  207. package/dist/server/action-routes.js +30 -4
  208. package/dist/server/action-routes.js.map +1 -1
  209. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  210. package/dist/server/agent-chat-plugin.js +65 -19
  211. package/dist/server/agent-chat-plugin.js.map +1 -1
  212. package/dist/server/agent-teams.d.ts.map +1 -1
  213. package/dist/server/agent-teams.js +8 -1
  214. package/dist/server/agent-teams.js.map +1 -1
  215. package/dist/server/agents-bundle.d.ts +27 -1
  216. package/dist/server/agents-bundle.d.ts.map +1 -1
  217. package/dist/server/agents-bundle.js +41 -3
  218. package/dist/server/agents-bundle.js.map +1 -1
  219. package/dist/server/auth.d.ts.map +1 -1
  220. package/dist/server/auth.js +76 -3
  221. package/dist/server/auth.js.map +1 -1
  222. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  223. package/dist/server/core-routes-plugin.js +60 -0
  224. package/dist/server/core-routes-plugin.js.map +1 -1
  225. package/dist/server/onboarding-html.d.ts.map +1 -1
  226. package/dist/server/onboarding-html.js +160 -22
  227. package/dist/server/onboarding-html.js.map +1 -1
  228. package/dist/server/sentry.d.ts.map +1 -1
  229. package/dist/server/sentry.js +6 -0
  230. package/dist/server/sentry.js.map +1 -1
  231. package/dist/server/social-og-image.d.ts +2 -1
  232. package/dist/server/social-og-image.d.ts.map +1 -1
  233. package/dist/server/social-og-image.js +24 -4
  234. package/dist/server/social-og-image.js.map +1 -1
  235. package/dist/sharing/schema.d.ts +1 -1
  236. package/dist/styles/agent-native.css +1 -0
  237. package/dist/styles/rich-markdown-editor.css +439 -0
  238. package/dist/templates/default/.agents/skills/actions/SKILL.md +4 -1
  239. package/dist/templates/default/.agents/skills/security/SKILL.md +13 -4
  240. package/dist/templates/default/.agents/skills/storing-data/SKILL.md +15 -3
  241. package/dist/templates/default/AGENTS.md +1 -0
  242. package/dist/templates/default/DEVELOPING.md +2 -0
  243. package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +10 -3
  244. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +98 -10
  245. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +45 -3
  246. package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +2 -0
  247. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +37 -4
  248. package/dist/templates/workspace-core/.agents/skills/automations/SKILL.md +9 -4
  249. package/dist/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +2 -0
  250. package/dist/templates/workspace-core/.agents/skills/client-methods/SKILL.md +106 -0
  251. package/dist/templates/workspace-core/.agents/skills/client-methods/references/legacy-client-fetch-audit-2026-06-03.md +53 -0
  252. package/dist/templates/workspace-core/.agents/skills/client-side-routing/SKILL.md +2 -0
  253. package/dist/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +62 -61
  254. package/dist/templates/workspace-core/.agents/skills/context-xray/SKILL.md +47 -0
  255. package/dist/templates/workspace-core/.agents/skills/create-skill/SKILL.md +28 -0
  256. package/dist/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +52 -1
  257. package/dist/templates/workspace-core/.agents/skills/extension-points/SKILL.md +2 -0
  258. package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +95 -433
  259. package/dist/templates/workspace-core/.agents/skills/extensions/references/api.md +285 -0
  260. package/dist/templates/workspace-core/.agents/skills/extensions/references/examples.md +259 -0
  261. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +398 -0
  262. package/dist/templates/workspace-core/.agents/skills/external-agents/references/mcp-apps-embedding.md +157 -0
  263. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +17 -0
  264. package/dist/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +13 -2
  265. package/dist/templates/workspace-core/.agents/skills/mvp-followup/SKILL.md +51 -0
  266. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +14 -4
  267. package/dist/templates/workspace-core/.agents/skills/onboarding/SKILL.md +13 -1
  268. package/dist/templates/workspace-core/.agents/skills/portability/SKILL.md +27 -5
  269. package/dist/templates/workspace-core/.agents/skills/qa/SKILL.md +24 -8
  270. package/dist/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +53 -7
  271. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +43 -10
  272. package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +2 -0
  273. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +43 -14
  274. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +50 -1
  275. package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +4 -2
  276. package/dist/templates/workspace-core/.agents/skills/server-plugins/SKILL.md +11 -1
  277. package/dist/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +15 -0
  278. package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +5 -1
  279. package/dist/templates/workspace-core/.agents/skills/storing-data/SKILL.md +48 -19
  280. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +7 -3
  281. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +13 -6
  282. package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +236 -0
  283. package/dist/templates/workspace-core/AGENTS.md +5 -1
  284. package/dist/templates/workspace-root/AGENTS.md +5 -2
  285. package/dist/tracking/route.d.ts +43 -0
  286. package/dist/tracking/route.d.ts.map +1 -0
  287. package/dist/tracking/route.js +85 -0
  288. package/dist/tracking/route.js.map +1 -0
  289. package/dist/vite/client.d.ts.map +1 -1
  290. package/dist/vite/client.js +15 -0
  291. package/dist/vite/client.js.map +1 -1
  292. package/docs/content/a2a-protocol.md +18 -4
  293. package/docs/content/actions.md +87 -0
  294. package/docs/content/agent-mentions.md +2 -1
  295. package/docs/content/authentication.md +2 -1
  296. package/docs/content/client.md +64 -13
  297. package/docs/content/cloneable-saas.md +1 -1
  298. package/docs/content/code-agents-ui.md +17 -11
  299. package/docs/content/context-awareness.md +23 -28
  300. package/docs/content/creating-templates.md +1 -1
  301. package/docs/content/drop-in-agent.md +2 -0
  302. package/docs/content/getting-started.md +2 -2
  303. package/docs/content/key-concepts.md +2 -2
  304. package/docs/content/messaging.md +57 -15
  305. package/docs/content/migration-workbench.md +1 -1
  306. package/docs/content/multi-app-workspace.md +1 -1
  307. package/docs/content/multi-tenancy.md +17 -15
  308. package/docs/content/real-time-collaboration.md +1 -1
  309. package/docs/content/recurring-jobs.md +1 -1
  310. package/docs/content/security.md +2 -2
  311. package/docs/content/server.md +4 -4
  312. package/docs/content/skills-guide.md +30 -0
  313. package/docs/content/template-analytics.md +2 -2
  314. package/docs/content/template-assets.md +17 -1
  315. package/docs/content/template-brain.md +2 -2
  316. package/docs/content/template-calendar.md +1 -1
  317. package/docs/content/template-clips.md +3 -3
  318. package/docs/content/template-content.md +2 -2
  319. package/docs/content/template-design.md +2 -2
  320. package/docs/content/template-dispatch.md +3 -3
  321. package/docs/content/template-forms.md +14 -2
  322. package/docs/content/template-mail.md +1 -3
  323. package/docs/content/template-plan.md +118 -0
  324. package/docs/content/template-slides.md +5 -4
  325. package/docs/content/template-starter.md +4 -4
  326. package/docs/content/template-videos.md +6 -11
  327. package/docs/content/tracking.md +21 -1
  328. package/docs/content/visual-plans.md +72 -0
  329. package/docs/content/workspace.md +9 -9
  330. package/package.json +26 -11
  331. package/src/templates/default/.agents/skills/actions/SKILL.md +4 -1
  332. package/src/templates/default/.agents/skills/security/SKILL.md +13 -4
  333. package/src/templates/default/.agents/skills/storing-data/SKILL.md +15 -3
  334. package/src/templates/default/AGENTS.md +1 -0
  335. package/src/templates/default/DEVELOPING.md +2 -0
  336. package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +10 -3
  337. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +98 -10
  338. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +45 -3
  339. package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +2 -0
  340. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +37 -4
  341. package/src/templates/workspace-core/.agents/skills/automations/SKILL.md +9 -4
  342. package/src/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +2 -0
  343. package/src/templates/workspace-core/.agents/skills/client-methods/SKILL.md +106 -0
  344. package/src/templates/workspace-core/.agents/skills/client-methods/references/legacy-client-fetch-audit-2026-06-03.md +53 -0
  345. package/src/templates/workspace-core/.agents/skills/client-side-routing/SKILL.md +2 -0
  346. package/src/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +62 -61
  347. package/src/templates/workspace-core/.agents/skills/context-xray/SKILL.md +47 -0
  348. package/src/templates/workspace-core/.agents/skills/create-skill/SKILL.md +28 -0
  349. package/src/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +52 -1
  350. package/src/templates/workspace-core/.agents/skills/extension-points/SKILL.md +2 -0
  351. package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +95 -433
  352. package/src/templates/workspace-core/.agents/skills/extensions/references/api.md +285 -0
  353. package/src/templates/workspace-core/.agents/skills/extensions/references/examples.md +259 -0
  354. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +398 -0
  355. package/src/templates/workspace-core/.agents/skills/external-agents/references/mcp-apps-embedding.md +157 -0
  356. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +17 -0
  357. package/src/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +13 -2
  358. package/src/templates/workspace-core/.agents/skills/mvp-followup/SKILL.md +51 -0
  359. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +14 -4
  360. package/src/templates/workspace-core/.agents/skills/onboarding/SKILL.md +13 -1
  361. package/src/templates/workspace-core/.agents/skills/portability/SKILL.md +27 -5
  362. package/src/templates/workspace-core/.agents/skills/qa/SKILL.md +24 -8
  363. package/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +53 -7
  364. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +43 -10
  365. package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +2 -0
  366. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +43 -14
  367. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +50 -1
  368. package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +4 -2
  369. package/src/templates/workspace-core/.agents/skills/server-plugins/SKILL.md +11 -1
  370. package/src/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +15 -0
  371. package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +5 -1
  372. package/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +48 -19
  373. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +7 -3
  374. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +13 -6
  375. package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +236 -0
  376. package/src/templates/workspace-core/AGENTS.md +5 -1
  377. package/src/templates/workspace-root/AGENTS.md +5 -2
@@ -0,0 +1,107 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { IconColumnInsertRight, IconPlus, IconRowInsertBottom, IconTable, IconTrash, IconX, } from "@tabler/icons-react";
3
+ import { defineBlock } from "../types.js";
4
+ import { tableMdx, tableSchema } from "./table.config.js";
5
+ /**
6
+ * Standard `table` block — a simple grid of header columns and string rows.
7
+ * STANDARD library block: lives in core (`@agent-native/core/blocks`) so any
8
+ * app can register it. The plan app's registries (server + client) import
9
+ * {@link tableBlock} (browser) and the React-free {@link tableMdx}/
10
+ * {@link tableSchema} config (server) so its render + MDX round-trip move out
11
+ * of the plan `PlanBlockView` switch / `serializeBlock` into the registry,
12
+ * while the legacy branch stays as a backward-compatible fallback for
13
+ * unregistered renderers.
14
+ */
15
+ /**
16
+ * Read-only renderer. Mirrors the legacy plan `PlanBlockView` table branch
17
+ * markup byte-for-byte (same `plan-block overflow-x-auto` section + title +
18
+ * `plan-line`/`plan-muted` table) so converting the block to the registry does
19
+ * not change the rendered output. The `plan-*` class names are styled by the
20
+ * consuming app's CSS — core only emits the markup, exactly like the existing
21
+ * `CalloutBlock` read renderer.
22
+ */
23
+ function TableBlockRead({ data, blockId, title }) {
24
+ return (_jsxs("section", { className: "plan-block overflow-x-auto", "data-block-id": blockId, children: [title && _jsx("h2", { children: title }), _jsxs("table", { className: "w-full min-w-[640px] border-collapse text-left", children: [_jsx("thead", { children: _jsx("tr", { className: "border-b border-plan-line text-sm text-plan-muted", children: data.columns.map((column) => (_jsx("th", { className: "py-3 pr-4 font-semibold", children: column }, column))) }) }), _jsx("tbody", { children: data.rows.map((row, index) => (_jsx("tr", { className: "border-b border-plan-line", children: row.map((cell, cellIndex) => (_jsx("td", { className: "py-4 pr-4 text-plan-muted", children: cell }, cellIndex))) }, index))) })] })] }));
25
+ }
26
+ const editInputClass = "h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50";
27
+ const iconButtonClass = "inline-flex size-7 items-center justify-center rounded-md border border-input text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50";
28
+ const addButtonClass = "inline-flex items-center gap-1.5 rounded-md border border-input bg-transparent px-3 py-1.5 text-sm text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50";
29
+ /**
30
+ * Editable grid. The schema's `columns: string[]` / `rows: string[][]` are
31
+ * positional/structured, which the schema auto-editor intentionally cannot
32
+ * render, so this block supplies its own `Edit`: an editable header row plus a
33
+ * body grid, with add/remove controls for both columns and rows. Every change
34
+ * commits a full new `{ columns, rows }` value (re-validated upstream by the
35
+ * registry), keeping rows rectangular with the column count.
36
+ */
37
+ function TableBlockEdit({ data, onChange, editable, }) {
38
+ const columns = data.columns ?? [];
39
+ const rows = data.rows ?? [];
40
+ const columnCount = columns.length;
41
+ const commit = (next) => onChange(next);
42
+ const setColumn = (index, value) => {
43
+ commit({
44
+ columns: columns.map((c, i) => (i === index ? value : c)),
45
+ rows,
46
+ });
47
+ };
48
+ const setCell = (rowIndex, cellIndex, value) => {
49
+ commit({
50
+ columns,
51
+ rows: rows.map((row, i) => i === rowIndex
52
+ ? row.map((cell, j) => (j === cellIndex ? value : cell))
53
+ : row),
54
+ });
55
+ };
56
+ const addColumn = () => {
57
+ commit({
58
+ columns: [...columns, `Column ${columnCount + 1}`],
59
+ // Keep rows rectangular: append an empty cell to every row.
60
+ rows: rows.map((row) => [...row, ""]),
61
+ });
62
+ };
63
+ const removeColumn = (index) => {
64
+ commit({
65
+ columns: columns.filter((_, i) => i !== index),
66
+ rows: rows.map((row) => row.filter((_, i) => i !== index)),
67
+ });
68
+ };
69
+ const addRow = () => {
70
+ commit({
71
+ columns,
72
+ // New row matches the current column count.
73
+ rows: [
74
+ ...rows,
75
+ Array.from({ length: Math.max(columnCount, 1) }, () => ""),
76
+ ],
77
+ });
78
+ };
79
+ const removeRow = (index) => {
80
+ commit({ columns, rows: rows.filter((_, i) => i !== index) });
81
+ };
82
+ return (_jsxs("div", { className: "an-table-block-editor flex flex-col gap-3", children: [_jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full min-w-[480px] border-collapse text-left", children: [_jsx("thead", { children: _jsxs("tr", { children: [columns.map((column, index) => (_jsx("th", { className: "p-1 align-top", children: _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("input", { type: "text", "data-plan-interactive": true, "aria-label": `Column ${index + 1} header`, className: editInputClass, value: column, disabled: !editable, onChange: (event) => setColumn(index, event.target.value) }), _jsx("button", { type: "button", "data-plan-interactive": true, "aria-label": `Remove column ${index + 1}`, className: iconButtonClass, disabled: !editable, onClick: () => removeColumn(index), children: _jsx(IconX, { size: 14 }) })] }) }, index))), _jsx("th", { className: "p-1 align-top", children: _jsx("button", { type: "button", "data-plan-interactive": true, "aria-label": "Add column", className: iconButtonClass, disabled: !editable, onClick: addColumn, children: _jsx(IconColumnInsertRight, { size: 16 }) }) })] }) }), _jsx("tbody", { children: rows.map((row, rowIndex) => (_jsxs("tr", { children: [Array.from({ length: columnCount }).map((_, cellIndex) => (_jsx("td", { className: "p-1 align-top", children: _jsx("input", { type: "text", "data-plan-interactive": true, "aria-label": `Row ${rowIndex + 1}, column ${cellIndex + 1}`, className: editInputClass, value: row[cellIndex] ?? "", disabled: !editable, onChange: (event) => setCell(rowIndex, cellIndex, event.target.value) }) }, cellIndex))), _jsx("td", { className: "p-1 align-top", children: _jsx("button", { type: "button", "data-plan-interactive": true, "aria-label": `Remove row ${rowIndex + 1}`, className: iconButtonClass, disabled: !editable, onClick: () => removeRow(rowIndex), children: _jsx(IconTrash, { size: 14 }) }) })] }, rowIndex))) })] }) }), _jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsxs("button", { type: "button", "data-plan-interactive": true, className: addButtonClass, disabled: !editable, onClick: addRow, children: [_jsx(IconRowInsertBottom, { size: 16 }), "Add row"] }), _jsxs("button", { type: "button", "data-plan-interactive": true, className: addButtonClass, disabled: !editable, onClick: addColumn, children: [_jsx(IconPlus, { size: 16 }), "Add column"] })] })] }));
83
+ }
84
+ /**
85
+ * The full standard `table` `BlockSpec`. Pairs the React-free
86
+ * {@link tableSchema}/{@link tableMdx} config (also used by the server registry)
87
+ * with the React `Read`/`Edit`. `empty()` seeds a 2×2 grid for slash insertion.
88
+ */
89
+ export const tableBlock = defineBlock({
90
+ type: "table",
91
+ schema: tableSchema,
92
+ mdx: tableMdx,
93
+ Read: TableBlockRead,
94
+ Edit: TableBlockEdit,
95
+ placement: ["block"],
96
+ label: "Table",
97
+ icon: ({ size, className }) => (_jsx(IconTable, { size: size, className: className })),
98
+ description: "A simple grid with header columns and string rows for comparisons, parameters, or structured lists.",
99
+ empty: () => ({
100
+ columns: ["Column 1", "Column 2"],
101
+ rows: [
102
+ ["", ""],
103
+ ["", ""],
104
+ ],
105
+ }),
106
+ });
107
+ //# sourceMappingURL=table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/table.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n IconColumnInsertRight,\n IconPlus,\n IconRowInsertBottom,\n IconTable,\n IconTrash,\n IconX,\n} from \"@tabler/icons-react\";\nimport { defineBlock } from \"../types.js\";\nimport type { BlockEditProps, BlockReadProps } from \"../types.js\";\nimport { tableMdx, tableSchema, type TableData } from \"./table.config.js\";\n\n/**\n * Standard `table` block — a simple grid of header columns and string rows.\n * STANDARD library block: lives in core (`@agent-native/core/blocks`) so any\n * app can register it. The plan app's registries (server + client) import\n * {@link tableBlock} (browser) and the React-free {@link tableMdx}/\n * {@link tableSchema} config (server) so its render + MDX round-trip move out\n * of the plan `PlanBlockView` switch / `serializeBlock` into the registry,\n * while the legacy branch stays as a backward-compatible fallback for\n * unregistered renderers.\n */\n\n/**\n * Read-only renderer. Mirrors the legacy plan `PlanBlockView` table branch\n * markup byte-for-byte (same `plan-block overflow-x-auto` section + title +\n * `plan-line`/`plan-muted` table) so converting the block to the registry does\n * not change the rendered output. The `plan-*` class names are styled by the\n * consuming app's CSS — core only emits the markup, exactly like the existing\n * `CalloutBlock` read renderer.\n */\nfunction TableBlockRead({ data, blockId, title }: BlockReadProps<TableData>) {\n return (\n <section className=\"plan-block overflow-x-auto\" data-block-id={blockId}>\n {title && <h2>{title}</h2>}\n <table className=\"w-full min-w-[640px] border-collapse text-left\">\n <thead>\n <tr className=\"border-b border-plan-line text-sm text-plan-muted\">\n {data.columns.map((column) => (\n <th key={column} className=\"py-3 pr-4 font-semibold\">\n {column}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {data.rows.map((row, index) => (\n <tr key={index} className=\"border-b border-plan-line\">\n {row.map((cell, cellIndex) => (\n <td key={cellIndex} className=\"py-4 pr-4 text-plan-muted\">\n {cell}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </section>\n );\n}\n\nconst editInputClass =\n \"h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\";\n\nconst iconButtonClass =\n \"inline-flex size-7 items-center justify-center rounded-md border border-input text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50\";\n\nconst addButtonClass =\n \"inline-flex items-center gap-1.5 rounded-md border border-input bg-transparent px-3 py-1.5 text-sm text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50\";\n\n/**\n * Editable grid. The schema's `columns: string[]` / `rows: string[][]` are\n * positional/structured, which the schema auto-editor intentionally cannot\n * render, so this block supplies its own `Edit`: an editable header row plus a\n * body grid, with add/remove controls for both columns and rows. Every change\n * commits a full new `{ columns, rows }` value (re-validated upstream by the\n * registry), keeping rows rectangular with the column count.\n */\nfunction TableBlockEdit({\n data,\n onChange,\n editable,\n}: BlockEditProps<TableData>) {\n const columns = data.columns ?? [];\n const rows = data.rows ?? [];\n const columnCount = columns.length;\n\n const commit = (next: TableData) => onChange(next);\n\n const setColumn = (index: number, value: string) => {\n commit({\n columns: columns.map((c, i) => (i === index ? value : c)),\n rows,\n });\n };\n\n const setCell = (rowIndex: number, cellIndex: number, value: string) => {\n commit({\n columns,\n rows: rows.map((row, i) =>\n i === rowIndex\n ? row.map((cell, j) => (j === cellIndex ? value : cell))\n : row,\n ),\n });\n };\n\n const addColumn = () => {\n commit({\n columns: [...columns, `Column ${columnCount + 1}`],\n // Keep rows rectangular: append an empty cell to every row.\n rows: rows.map((row) => [...row, \"\"]),\n });\n };\n\n const removeColumn = (index: number) => {\n commit({\n columns: columns.filter((_, i) => i !== index),\n rows: rows.map((row) => row.filter((_, i) => i !== index)),\n });\n };\n\n const addRow = () => {\n commit({\n columns,\n // New row matches the current column count.\n rows: [\n ...rows,\n Array.from({ length: Math.max(columnCount, 1) }, () => \"\"),\n ],\n });\n };\n\n const removeRow = (index: number) => {\n commit({ columns, rows: rows.filter((_, i) => i !== index) });\n };\n\n return (\n <div className=\"an-table-block-editor flex flex-col gap-3\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full min-w-[480px] border-collapse text-left\">\n <thead>\n <tr>\n {columns.map((column, index) => (\n <th key={index} className=\"p-1 align-top\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"text\"\n data-plan-interactive\n aria-label={`Column ${index + 1} header`}\n className={editInputClass}\n value={column}\n disabled={!editable}\n onChange={(event) => setColumn(index, event.target.value)}\n />\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Remove column ${index + 1}`}\n className={iconButtonClass}\n disabled={!editable}\n onClick={() => removeColumn(index)}\n >\n <IconX size={14} />\n </button>\n </div>\n </th>\n ))}\n <th className=\"p-1 align-top\">\n <button\n type=\"button\"\n data-plan-interactive\n aria-label=\"Add column\"\n className={iconButtonClass}\n disabled={!editable}\n onClick={addColumn}\n >\n <IconColumnInsertRight size={16} />\n </button>\n </th>\n </tr>\n </thead>\n <tbody>\n {rows.map((row, rowIndex) => (\n <tr key={rowIndex}>\n {Array.from({ length: columnCount }).map((_, cellIndex) => (\n <td key={cellIndex} className=\"p-1 align-top\">\n <input\n type=\"text\"\n data-plan-interactive\n aria-label={`Row ${rowIndex + 1}, column ${cellIndex + 1}`}\n className={editInputClass}\n value={row[cellIndex] ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n setCell(rowIndex, cellIndex, event.target.value)\n }\n />\n </td>\n ))}\n <td className=\"p-1 align-top\">\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Remove row ${rowIndex + 1}`}\n className={iconButtonClass}\n disabled={!editable}\n onClick={() => removeRow(rowIndex)}\n >\n <IconTrash size={14} />\n </button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <button\n type=\"button\"\n data-plan-interactive\n className={addButtonClass}\n disabled={!editable}\n onClick={addRow}\n >\n <IconRowInsertBottom size={16} />\n Add row\n </button>\n <button\n type=\"button\"\n data-plan-interactive\n className={addButtonClass}\n disabled={!editable}\n onClick={addColumn}\n >\n <IconPlus size={16} />\n Add column\n </button>\n </div>\n </div>\n );\n}\n\n/**\n * The full standard `table` `BlockSpec`. Pairs the React-free\n * {@link tableSchema}/{@link tableMdx} config (also used by the server registry)\n * with the React `Read`/`Edit`. `empty()` seeds a 2×2 grid for slash insertion.\n */\nexport const tableBlock = defineBlock<TableData>({\n type: \"table\",\n schema: tableSchema,\n mdx: tableMdx,\n Read: TableBlockRead,\n Edit: TableBlockEdit,\n placement: [\"block\"],\n label: \"Table\",\n icon: ({ size, className }) => (\n <IconTable size={size} className={className} />\n ),\n description:\n \"A simple grid with header columns and string rows for comparisons, parameters, or structured lists.\",\n empty: () => ({\n columns: [\"Column 1\", \"Column 2\"],\n rows: [\n [\"\", \"\"],\n [\"\", \"\"],\n ],\n }),\n});\n"]}
@@ -0,0 +1,56 @@
1
+ import { z } from "zod";
2
+ import type { BlockMdxConfig } from "../types.js";
3
+ import type { NestedBlock } from "../types.js";
4
+ /**
5
+ * Pure (React-free) part of the standard `tabs` block: its data schema and MDX
6
+ * round-trip config. Shared by the server MDX adapter (a plan/content app
7
+ * registers it via `@agent-native/core/blocks/server`) and the full client spec
8
+ * (`tabs.tsx`). Keeping this React-free means importing it into a server module
9
+ * never pulls React into the Nitro/SSR bundle.
10
+ *
11
+ * `tabs` is a STANDARD library block: a horizontal pill-tab container where each
12
+ * tab holds a list of child blocks. The children are rendered RECURSIVELY
13
+ * through the app's own block dispatcher (`ctx.renderBlock`), so registered
14
+ * children render via their spec and unconverted children still fall through the
15
+ * app's legacy switch — the coexistence seam.
16
+ *
17
+ * Its schema MUST stay data-compatible with the legacy plan `tabs` branch of
18
+ * `planBlockSchema` (`tabs[]` of `{ id, label, blocks: Block[] }`), and the MDX
19
+ * `tag` + attribute shape MUST match the legacy
20
+ * `<TabsBlock … tabs={[…]} />` encoding — the WHOLE `tabs` array (including
21
+ * nested child blocks) encoded as one JSON prop, NOT nested MDX
22
+ * (`plan-mdx.ts` `serializeBlock` L349 / `parseBlock` L705) — so stored `.mdx`
23
+ * round-trips byte-compatibly.
24
+ */
25
+ /** One tab: a label and the child blocks it contains. */
26
+ export interface TabsTab {
27
+ id: string;
28
+ label: string;
29
+ /**
30
+ * Child blocks. Typed loosely as {@link NestedBlock} because the app owns the
31
+ * authoritative recursive block union (`planBlockSchema`); the tabs spec only
32
+ * validates the tab envelope (`id`/`label`) and passes children through.
33
+ */
34
+ blocks: NestedBlock[];
35
+ }
36
+ export interface TabsData {
37
+ tabs: TabsTab[];
38
+ }
39
+ /**
40
+ * Child blocks are validated by the app's own recursive `planBlockSchema` when
41
+ * the plan persists; here they pass through untyped (`z.any()`) so core never
42
+ * needs to import an app-specific block union. The tab envelope (`id`/`label`)
43
+ * mirrors the plan tabs schema bounds (`plan-content.ts` L1051) exactly.
44
+ */
45
+ export declare const tabsSchema: z.ZodType<TabsData>;
46
+ /**
47
+ * MDX config: `tabs` is a single JSON-encoded attribute and the block is
48
+ * self-closing — exactly the legacy `<TabsBlock id … tabs={[…]} />` form. The
49
+ * entire `tabs` array (labels + nested child blocks) is one JSON prop; child
50
+ * blocks are NOT serialized as nested MDX, which preserves the current byte
51
+ * output. `toAttrs` returns only `tabs`; `fromAttrs` reads the `tabs` array
52
+ * (defaulting to `[]` for backward-compat with malformed/empty stored blocks,
53
+ * mirroring the legacy `arrayAttr(node, "tabs") ?? []`).
54
+ */
55
+ export declare const tabsMdx: BlockMdxConfig<TabsData>;
56
+ //# sourceMappingURL=tabs.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabs.config.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/tabs.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,yDAAyD;AACzD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,OAAO,EAAE,CAAC;CACjB;AAKD;;;;;GAKG;AACH,eAAO,MAAM,UAAU,EAWN,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;AAErC;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,EAAE,cAAc,CAAC,QAAQ,CAM5C,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { z } from "zod";
2
+ /** Matches the plan `idSchema` (`z.string().trim().min(1).max(120)`). */
3
+ const tabIdSchema = z.string().trim().min(1).max(120);
4
+ /**
5
+ * Child blocks are validated by the app's own recursive `planBlockSchema` when
6
+ * the plan persists; here they pass through untyped (`z.any()`) so core never
7
+ * needs to import an app-specific block union. The tab envelope (`id`/`label`)
8
+ * mirrors the plan tabs schema bounds (`plan-content.ts` L1051) exactly.
9
+ */
10
+ export const tabsSchema = z.object({
11
+ tabs: z
12
+ .array(z.object({
13
+ id: tabIdSchema,
14
+ label: z.string().trim().min(1).max(120),
15
+ blocks: z.array(z.any()).max(40),
16
+ }))
17
+ .min(1)
18
+ .max(12),
19
+ });
20
+ /**
21
+ * MDX config: `tabs` is a single JSON-encoded attribute and the block is
22
+ * self-closing — exactly the legacy `<TabsBlock id … tabs={[…]} />` form. The
23
+ * entire `tabs` array (labels + nested child blocks) is one JSON prop; child
24
+ * blocks are NOT serialized as nested MDX, which preserves the current byte
25
+ * output. `toAttrs` returns only `tabs`; `fromAttrs` reads the `tabs` array
26
+ * (defaulting to `[]` for backward-compat with malformed/empty stored blocks,
27
+ * mirroring the legacy `arrayAttr(node, "tabs") ?? []`).
28
+ */
29
+ export const tabsMdx = {
30
+ tag: "TabsBlock",
31
+ toAttrs: (data) => ({ tabs: data.tabs }),
32
+ fromAttrs: (attrs) => ({
33
+ tabs: (attrs.array("tabs") ?? []),
34
+ }),
35
+ };
36
+ //# sourceMappingURL=tabs.config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabs.config.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/tabs.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA0CxB,yEAAyE;AACzE,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,IAAI,EAAE,CAAC;SACJ,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;QACP,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;QACxC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;KACjC,CAAC,CACH;SACA,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,EAAE,CAAC;CACX,CAAmC,CAAC;AAErC;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,OAAO,GAA6B;IAC/C,GAAG,EAAE,WAAW;IAChB,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IACxC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACrB,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAU,MAAM,CAAC,IAAI,EAAE,CAAc;KACxD,CAAC;CACH,CAAC","sourcesContent":["import { z } from \"zod\";\nimport type { BlockMdxConfig } from \"../types.js\";\nimport type { NestedBlock } from \"../types.js\";\n\n/**\n * Pure (React-free) part of the standard `tabs` block: its data schema and MDX\n * round-trip config. Shared by the server MDX adapter (a plan/content app\n * registers it via `@agent-native/core/blocks/server`) and the full client spec\n * (`tabs.tsx`). Keeping this React-free means importing it into a server module\n * never pulls React into the Nitro/SSR bundle.\n *\n * `tabs` is a STANDARD library block: a horizontal pill-tab container where each\n * tab holds a list of child blocks. The children are rendered RECURSIVELY\n * through the app's own block dispatcher (`ctx.renderBlock`), so registered\n * children render via their spec and unconverted children still fall through the\n * app's legacy switch — the coexistence seam.\n *\n * Its schema MUST stay data-compatible with the legacy plan `tabs` branch of\n * `planBlockSchema` (`tabs[]` of `{ id, label, blocks: Block[] }`), and the MDX\n * `tag` + attribute shape MUST match the legacy\n * `<TabsBlock … tabs={[…]} />` encoding — the WHOLE `tabs` array (including\n * nested child blocks) encoded as one JSON prop, NOT nested MDX\n * (`plan-mdx.ts` `serializeBlock` L349 / `parseBlock` L705) — so stored `.mdx`\n * round-trips byte-compatibly.\n */\n\n/** One tab: a label and the child blocks it contains. */\nexport interface TabsTab {\n id: string;\n label: string;\n /**\n * Child blocks. Typed loosely as {@link NestedBlock} because the app owns the\n * authoritative recursive block union (`planBlockSchema`); the tabs spec only\n * validates the tab envelope (`id`/`label`) and passes children through.\n */\n blocks: NestedBlock[];\n}\n\nexport interface TabsData {\n tabs: TabsTab[];\n}\n\n/** Matches the plan `idSchema` (`z.string().trim().min(1).max(120)`). */\nconst tabIdSchema = z.string().trim().min(1).max(120);\n\n/**\n * Child blocks are validated by the app's own recursive `planBlockSchema` when\n * the plan persists; here they pass through untyped (`z.any()`) so core never\n * needs to import an app-specific block union. The tab envelope (`id`/`label`)\n * mirrors the plan tabs schema bounds (`plan-content.ts` L1051) exactly.\n */\nexport const tabsSchema = z.object({\n tabs: z\n .array(\n z.object({\n id: tabIdSchema,\n label: z.string().trim().min(1).max(120),\n blocks: z.array(z.any()).max(40),\n }),\n )\n .min(1)\n .max(12),\n}) as unknown as z.ZodType<TabsData>;\n\n/**\n * MDX config: `tabs` is a single JSON-encoded attribute and the block is\n * self-closing — exactly the legacy `<TabsBlock id … tabs={[…]} />` form. The\n * entire `tabs` array (labels + nested child blocks) is one JSON prop; child\n * blocks are NOT serialized as nested MDX, which preserves the current byte\n * output. `toAttrs` returns only `tabs`; `fromAttrs` reads the `tabs` array\n * (defaulting to `[]` for backward-compat with malformed/empty stored blocks,\n * mirroring the legacy `arrayAttr(node, \"tabs\") ?? []`).\n */\nexport const tabsMdx: BlockMdxConfig<TabsData> = {\n tag: \"TabsBlock\",\n toAttrs: (data) => ({ tabs: data.tabs }),\n fromAttrs: (attrs) => ({\n tabs: (attrs.array<TabsTab>(\"tabs\") ?? []) as TabsTab[],\n }),\n};\n"]}
@@ -0,0 +1,20 @@
1
+ import type { BlockReadProps, BlockEditProps } from "../types.js";
2
+ import { type TabsData } from "./tabs.config.js";
3
+ /** Read renderer: pill tabs, child blocks rendered read-only via the app. */
4
+ export declare function TabsBlockReader({ data, blockId, title, ctx, }: BlockReadProps<TabsData>): import("react/jsx-runtime").JSX.Element;
5
+ /**
6
+ * Editor: pill tabs plus tab management (add/remove/rename), with child blocks
7
+ * rendered editable in place through the app dispatcher. A child change updates
8
+ * that child within its tab and commits the whole tabs block — mirroring the
9
+ * legacy `TabsBlock` onChange bubbling so the plan's recursive `updateBlocks`/
10
+ * `findBlock` (`PlanContentRenderer`) keeps working unchanged.
11
+ */
12
+ export declare function TabsBlockEditor({ data, onChange, editable, blockId, title, ctx, }: BlockEditProps<TabsData>): import("react/jsx-runtime").JSX.Element;
13
+ /**
14
+ * The standard tabs block spec (with React `Read`/`Edit`). Apps register this in
15
+ * their browser registry. The schema + MDX config come from `./tabs.config.ts`,
16
+ * the exact same object server / agent code registers, so rendering and source
17
+ * round-trip never drift.
18
+ */
19
+ export declare const tabsBlock: import("../types.js").BlockSpec<TabsData>;
20
+ //# sourceMappingURL=tabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/tabs.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAe,MAAM,aAAa,CAAC;AAC/E,OAAO,EAGL,KAAK,QAAQ,EAEd,MAAM,kBAAkB,CAAC;AAuE1B,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,OAAO,EACP,KAAK,EACL,GAAG,GACJ,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAuB1B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,KAAK,EACL,GAAG,GACJ,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAsI1B;AAED;;;;;GAKG;AACH,eAAO,MAAM,SAAS,2CAYpB,CAAC"}
@@ -0,0 +1,123 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { IconLayoutNavbar, IconPlus, IconX } from "@tabler/icons-react";
4
+ import { cn } from "../../utils.js";
5
+ import { defineBlock } from "../types.js";
6
+ import { tabsSchema, tabsMdx, } from "./tabs.config.js";
7
+ /**
8
+ * Standard `tabs` block: a horizontal pill-tab container whose tabs each hold a
9
+ * list of child blocks. Lives in core so any app (plan today, content later) can
10
+ * register it.
11
+ *
12
+ * `Read`/`Edit` mirror the legacy plan `TabsBlock` markup byte-for-byte (same
13
+ * `plan-block` section, the `inline-flex` pill tab rail with `role="tablist"`/
14
+ * `role="tab"`, the same active-tab `useState`, and the `compactVisuals`
15
+ * heuristic on the block title) so converting the block to the registry does not
16
+ * change rendered output. The plan CSS classes (`plan-block`, `bg-plan-block`,
17
+ * `text-plan-*`) resolve against the plan app's stylesheet at render time,
18
+ * exactly as before.
19
+ *
20
+ * Child rendering flows through `ctx.renderBlock` — the app's own block
21
+ * dispatcher — so registered children render via their spec and unconverted
22
+ * children fall through the app's legacy switch. This is the coexistence seam:
23
+ * the core tabs block never has to know app-specific child block types.
24
+ */
25
+ /** Mint a reasonably-unique tab id without pulling a dep into core. */
26
+ function newTabId() {
27
+ return `tab-${Math.random().toString(36).slice(2, 10)}`;
28
+ }
29
+ /** Compact embedded visuals for dense tab panes, matching legacy behavior. */
30
+ function isCompact(title) {
31
+ return /interaction|component|note/i.test(title ?? "");
32
+ }
33
+ /** Shared pill-tab rail. */
34
+ function TabRail({ tabs, activeId, onSelect, }) {
35
+ return (_jsx("div", { className: "mb-8 inline-flex max-w-full gap-1 overflow-x-auto", role: "tablist", "data-plan-interactive": true, children: tabs.map((tab) => {
36
+ const selected = tab.id === activeId;
37
+ return (_jsx("button", { type: "button", role: "tab", "aria-selected": selected, onClick: () => onSelect(tab.id), className: cn("rounded-lg px-4 py-2 text-sm font-semibold transition-colors", selected
38
+ ? "bg-plan-block text-plan-text shadow-sm"
39
+ : "text-plan-muted hover:bg-plan-block/60 hover:text-plan-text"), children: tab.label }, tab.id));
40
+ }) }));
41
+ }
42
+ /** Read renderer: pill tabs, child blocks rendered read-only via the app. */
43
+ export function TabsBlockReader({ data, blockId, title, ctx, }) {
44
+ const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? "");
45
+ const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];
46
+ const compact = isCompact(title);
47
+ return (_jsxs("section", { className: "plan-block", "data-block-id": blockId, children: [title && _jsx("h2", { children: title }), _jsx(TabRail, { tabs: data.tabs, activeId: active?.id, onSelect: setActiveId }), active && (_jsx("div", { children: active.blocks.map((child) => (_jsx("div", { children: ctx.renderBlock?.({
48
+ block: child,
49
+ editing: false,
50
+ compactVisuals: compact,
51
+ }) }, child.id))) }))] }));
52
+ }
53
+ /**
54
+ * Editor: pill tabs plus tab management (add/remove/rename), with child blocks
55
+ * rendered editable in place through the app dispatcher. A child change updates
56
+ * that child within its tab and commits the whole tabs block — mirroring the
57
+ * legacy `TabsBlock` onChange bubbling so the plan's recursive `updateBlocks`/
58
+ * `findBlock` (`PlanContentRenderer`) keeps working unchanged.
59
+ */
60
+ export function TabsBlockEditor({ data, onChange, editable, blockId, title, ctx, }) {
61
+ const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? "");
62
+ const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];
63
+ const compact = isCompact(title);
64
+ const commit = (tabs) => onChange({ tabs });
65
+ const renameTab = (id, label) => commit(data.tabs.map((tab) => (tab.id === id ? { ...tab, label } : tab)));
66
+ const removeTab = (id) => {
67
+ const next = data.tabs.filter((tab) => tab.id !== id);
68
+ if (next.length === 0)
69
+ return; // tabs must keep at least one (schema min 1)
70
+ commit(next);
71
+ if (activeId === id)
72
+ setActiveId(next[0]?.id ?? "");
73
+ };
74
+ const addTab = () => {
75
+ if (data.tabs.length >= 12)
76
+ return; // schema max
77
+ const id = newTabId();
78
+ commit([
79
+ ...data.tabs,
80
+ { id, label: `Tab ${data.tabs.length + 1}`, blocks: [] },
81
+ ]);
82
+ setActiveId(id);
83
+ };
84
+ const updateChild = (tabId, child) => commit(data.tabs.map((tab) => tab.id === tabId
85
+ ? {
86
+ ...tab,
87
+ blocks: tab.blocks.map((existing) => existing.id === child.id ? child : existing),
88
+ }
89
+ : tab));
90
+ // Renders BARE (no `plan-block` section / title): in edit mode the app's
91
+ // block dispatcher already wraps registered editors in a titled `plan-block`
92
+ // section, so wrapping again here would double-nest. The read renderer
93
+ // (`TabsBlockReader`) owns its own section because read mode renders the spec
94
+ // directly.
95
+ return (_jsxs("div", { "data-tabs-edit-block": blockId, children: [_jsxs("div", { className: "mb-8 flex max-w-full flex-wrap items-center gap-1 overflow-x-auto", role: "tablist", "data-plan-interactive": true, children: [data.tabs.map((tab) => {
96
+ const selected = tab.id === active?.id;
97
+ return (_jsxs("div", { className: cn("group flex items-center gap-1 rounded-lg pr-1 transition-colors", selected ? "bg-plan-block shadow-sm" : "hover:bg-plan-block/60"), children: [_jsx("button", { type: "button", role: "tab", "aria-selected": selected, onClick: () => setActiveId(tab.id), className: cn("rounded-lg px-4 py-2 text-sm font-semibold transition-colors", selected ? "text-plan-text" : "text-plan-muted"), children: tab.label }), editable && data.tabs.length > 1 && (_jsx("button", { type: "button", "data-plan-interactive": true, "aria-label": `Remove ${tab.label}`, className: cn("flex size-6 shrink-0 items-center justify-center rounded text-plan-muted transition-opacity", "opacity-0 group-hover:opacity-100 group-focus-within:opacity-100", "hover:bg-muted hover:text-foreground"), onClick: () => removeTab(tab.id), children: _jsx(IconX, { className: "size-3.5 shrink-0" }) }))] }, tab.id));
98
+ }), editable && data.tabs.length < 12 && (_jsxs("button", { type: "button", "data-plan-interactive": true, "aria-label": "Add tab", className: "flex items-center gap-1.5 rounded-md px-2 py-2 text-sm text-plan-muted hover:bg-plan-block/60 hover:text-plan-text", onClick: addTab, children: [_jsx(IconPlus, { className: "size-4" }), "Add tab"] }))] }), active && (_jsxs("div", { className: "grid gap-3", children: [editable && (_jsx("input", { type: "text", "data-plan-interactive": true, className: "flex h-9 w-full max-w-xs rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", placeholder: "Tab label", value: active.label, onChange: (event) => renameTab(active.id, event.target.value) })), _jsx("div", { children: active.blocks.map((child) => (_jsx("div", { children: ctx.renderBlock?.({
99
+ block: child,
100
+ editing: true,
101
+ compactVisuals: compact,
102
+ onChange: (next) => updateChild(active.id, next),
103
+ }) }, child.id))) })] }))] }));
104
+ }
105
+ /**
106
+ * The standard tabs block spec (with React `Read`/`Edit`). Apps register this in
107
+ * their browser registry. The schema + MDX config come from `./tabs.config.ts`,
108
+ * the exact same object server / agent code registers, so rendering and source
109
+ * round-trip never drift.
110
+ */
111
+ export const tabsBlock = defineBlock({
112
+ type: "tabs",
113
+ schema: tabsSchema,
114
+ mdx: tabsMdx,
115
+ Read: TabsBlockReader,
116
+ Edit: TabsBlockEditor,
117
+ placement: ["block", "inline"],
118
+ label: "Tabs",
119
+ icon: IconLayoutNavbar,
120
+ description: "A horizontal pill-tab container; each tab holds its own list of blocks.",
121
+ empty: () => ({ tabs: [{ id: newTabId(), label: "Tab 1", blocks: [] }] }),
122
+ });
123
+ //# sourceMappingURL=tabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/tabs.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from \"react\";\nimport { IconLayoutNavbar, IconPlus, IconX } from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type { BlockReadProps, BlockEditProps, NestedBlock } from \"../types.js\";\nimport {\n tabsSchema,\n tabsMdx,\n type TabsData,\n type TabsTab,\n} from \"./tabs.config.js\";\n\n/**\n * Standard `tabs` block: a horizontal pill-tab container whose tabs each hold a\n * list of child blocks. Lives in core so any app (plan today, content later) can\n * register it.\n *\n * `Read`/`Edit` mirror the legacy plan `TabsBlock` markup byte-for-byte (same\n * `plan-block` section, the `inline-flex` pill tab rail with `role=\"tablist\"`/\n * `role=\"tab\"`, the same active-tab `useState`, and the `compactVisuals`\n * heuristic on the block title) so converting the block to the registry does not\n * change rendered output. The plan CSS classes (`plan-block`, `bg-plan-block`,\n * `text-plan-*`) resolve against the plan app's stylesheet at render time,\n * exactly as before.\n *\n * Child rendering flows through `ctx.renderBlock` — the app's own block\n * dispatcher — so registered children render via their spec and unconverted\n * children fall through the app's legacy switch. This is the coexistence seam:\n * the core tabs block never has to know app-specific child block types.\n */\n\n/** Mint a reasonably-unique tab id without pulling a dep into core. */\nfunction newTabId(): string {\n return `tab-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Compact embedded visuals for dense tab panes, matching legacy behavior. */\nfunction isCompact(title: string | undefined): boolean {\n return /interaction|component|note/i.test(title ?? \"\");\n}\n\n/** Shared pill-tab rail. */\nfunction TabRail({\n tabs,\n activeId,\n onSelect,\n}: {\n tabs: TabsTab[];\n activeId: string | undefined;\n onSelect: (id: string) => void;\n}) {\n return (\n <div\n className=\"mb-8 inline-flex max-w-full gap-1 overflow-x-auto\"\n role=\"tablist\"\n data-plan-interactive\n >\n {tabs.map((tab) => {\n const selected = tab.id === activeId;\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n onClick={() => onSelect(tab.id)}\n className={cn(\n \"rounded-lg px-4 py-2 text-sm font-semibold transition-colors\",\n selected\n ? \"bg-plan-block text-plan-text shadow-sm\"\n : \"text-plan-muted hover:bg-plan-block/60 hover:text-plan-text\",\n )}\n >\n {tab.label}\n </button>\n );\n })}\n </div>\n );\n}\n\n/** Read renderer: pill tabs, child blocks rendered read-only via the app. */\nexport function TabsBlockReader({\n data,\n blockId,\n title,\n ctx,\n}: BlockReadProps<TabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n const compact = isCompact(title);\n return (\n <section className=\"plan-block\" data-block-id={blockId}>\n {title && <h2>{title}</h2>}\n <TabRail tabs={data.tabs} activeId={active?.id} onSelect={setActiveId} />\n {active && (\n <div>\n {active.blocks.map((child) => (\n <div key={child.id}>\n {ctx.renderBlock?.({\n block: child,\n editing: false,\n compactVisuals: compact,\n })}\n </div>\n ))}\n </div>\n )}\n </section>\n );\n}\n\n/**\n * Editor: pill tabs plus tab management (add/remove/rename), with child blocks\n * rendered editable in place through the app dispatcher. A child change updates\n * that child within its tab and commits the whole tabs block — mirroring the\n * legacy `TabsBlock` onChange bubbling so the plan's recursive `updateBlocks`/\n * `findBlock` (`PlanContentRenderer`) keeps working unchanged.\n */\nexport function TabsBlockEditor({\n data,\n onChange,\n editable,\n blockId,\n title,\n ctx,\n}: BlockEditProps<TabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n const compact = isCompact(title);\n\n const commit = (tabs: TabsTab[]) => onChange({ tabs });\n\n const renameTab = (id: string, label: string) =>\n commit(data.tabs.map((tab) => (tab.id === id ? { ...tab, label } : tab)));\n\n const removeTab = (id: string) => {\n const next = data.tabs.filter((tab) => tab.id !== id);\n if (next.length === 0) return; // tabs must keep at least one (schema min 1)\n commit(next);\n if (activeId === id) setActiveId(next[0]?.id ?? \"\");\n };\n\n const addTab = () => {\n if (data.tabs.length >= 12) return; // schema max\n const id = newTabId();\n commit([\n ...data.tabs,\n { id, label: `Tab ${data.tabs.length + 1}`, blocks: [] },\n ]);\n setActiveId(id);\n };\n\n const updateChild = (tabId: string, child: NestedBlock) =>\n commit(\n data.tabs.map((tab) =>\n tab.id === tabId\n ? {\n ...tab,\n blocks: tab.blocks.map((existing) =>\n existing.id === child.id ? child : existing,\n ),\n }\n : tab,\n ),\n );\n\n // Renders BARE (no `plan-block` section / title): in edit mode the app's\n // block dispatcher already wraps registered editors in a titled `plan-block`\n // section, so wrapping again here would double-nest. The read renderer\n // (`TabsBlockReader`) owns its own section because read mode renders the spec\n // directly.\n return (\n <div data-tabs-edit-block={blockId}>\n <div\n className=\"mb-8 flex max-w-full flex-wrap items-center gap-1 overflow-x-auto\"\n role=\"tablist\"\n data-plan-interactive\n >\n {data.tabs.map((tab) => {\n const selected = tab.id === active?.id;\n return (\n <div\n key={tab.id}\n className={cn(\n \"group flex items-center gap-1 rounded-lg pr-1 transition-colors\",\n selected ? \"bg-plan-block shadow-sm\" : \"hover:bg-plan-block/60\",\n )}\n >\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n onClick={() => setActiveId(tab.id)}\n className={cn(\n \"rounded-lg px-4 py-2 text-sm font-semibold transition-colors\",\n selected ? \"text-plan-text\" : \"text-plan-muted\",\n )}\n >\n {tab.label}\n </button>\n {editable && data.tabs.length > 1 && (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Remove ${tab.label}`}\n className={cn(\n \"flex size-6 shrink-0 items-center justify-center rounded text-plan-muted transition-opacity\",\n \"opacity-0 group-hover:opacity-100 group-focus-within:opacity-100\",\n \"hover:bg-muted hover:text-foreground\",\n )}\n onClick={() => removeTab(tab.id)}\n >\n <IconX className=\"size-3.5 shrink-0\" />\n </button>\n )}\n </div>\n );\n })}\n {editable && data.tabs.length < 12 && (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label=\"Add tab\"\n className=\"flex items-center gap-1.5 rounded-md px-2 py-2 text-sm text-plan-muted hover:bg-plan-block/60 hover:text-plan-text\"\n onClick={addTab}\n >\n <IconPlus className=\"size-4\" />\n Add tab\n </button>\n )}\n </div>\n {active && (\n <div className=\"grid gap-3\">\n {editable && (\n <input\n type=\"text\"\n data-plan-interactive\n className=\"flex h-9 w-full max-w-xs rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n placeholder=\"Tab label\"\n value={active.label}\n onChange={(event) => renameTab(active.id, event.target.value)}\n />\n )}\n <div>\n {active.blocks.map((child) => (\n <div key={child.id}>\n {ctx.renderBlock?.({\n block: child,\n editing: true,\n compactVisuals: compact,\n onChange: (next) => updateChild(active.id, next),\n })}\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n );\n}\n\n/**\n * The standard tabs block spec (with React `Read`/`Edit`). Apps register this in\n * their browser registry. The schema + MDX config come from `./tabs.config.ts`,\n * the exact same object server / agent code registers, so rendering and source\n * round-trip never drift.\n */\nexport const tabsBlock = defineBlock<TabsData>({\n type: \"tabs\",\n schema: tabsSchema,\n mdx: tabsMdx,\n Read: TabsBlockReader,\n Edit: TabsBlockEditor,\n placement: [\"block\", \"inline\"],\n label: \"Tabs\",\n icon: IconLayoutNavbar,\n description:\n \"A horizontal pill-tab container; each tab holds its own list of blocks.\",\n empty: () => ({ tabs: [{ id: newTabId(), label: \"Tab 1\", blocks: [] }] }),\n});\n"]}
@@ -0,0 +1,74 @@
1
+ import type { BlockSpec, BlockAttrReader } from "./types.js";
2
+ import type { BlockRegistry } from "./registry.js";
3
+ /**
4
+ * Registry-driven MDX serialize/parse, plus the shared encoder primitives that
5
+ * are the round-trip contract. This module is React-free so the server MDX
6
+ * adapter (`plan-mdx.ts`) and the agent schema export can import it. The encoder
7
+ * + estree literal walker are kept BYTE-FOR-BYTE identical to the originals in
8
+ * `plan-mdx.ts` — `plan-mdx.ts` re-imports them so nothing else there changes
9
+ * and stored `.mdx` files round-trip the same.
10
+ */
11
+ export declare function jsonExpression(value: unknown): string;
12
+ export declare function escapeAttr(value: string): string;
13
+ /**
14
+ * Encode a single attribute. Returns "" (the attribute is dropped) for
15
+ * undefined/null; a bare/`={false}` flag for booleans; `={n}` for numbers; a
16
+ * quoted string when it matches the safe charset and is short, else a JSON
17
+ * expression. Objects/arrays always serialize as a JSON expression.
18
+ */
19
+ export declare function prop(name: string, value: unknown): string;
20
+ /** Minimal MDX AST node shape (subset of the remark-mdx jsx element). */
21
+ export type MdxAttrNode = {
22
+ type: string;
23
+ name?: string;
24
+ value?: string | null | MdxAttrExpression;
25
+ };
26
+ type MdxAttrExpression = {
27
+ type: string;
28
+ value: string;
29
+ data?: unknown;
30
+ };
31
+ export type MdxJsxNode = {
32
+ type: string;
33
+ name?: string;
34
+ attributes?: MdxAttrNode[];
35
+ children?: unknown[];
36
+ [key: string]: unknown;
37
+ };
38
+ export declare function attributeValue(attr: MdxAttrNode | undefined): unknown;
39
+ /** Build a {@link BlockAttrReader} bound to one parsed JSX node. */
40
+ export declare function createAttrReader(node: MdxJsxNode): BlockAttrReader;
41
+ /** The base-attribute + body shape every block carries. */
42
+ export interface SerializableBlock {
43
+ id: string;
44
+ title?: string;
45
+ summary?: string;
46
+ editable?: boolean;
47
+ data: unknown;
48
+ }
49
+ /** Base block attributes parsed from a node, before the type-specific data. */
50
+ export interface ParsedBlockBase {
51
+ id: string;
52
+ title?: string;
53
+ summary?: string;
54
+ editable?: boolean;
55
+ }
56
+ /**
57
+ * Serialize a block to its MDX element using its spec. Byte output MUST match
58
+ * the legacy `serializeBlock` for every converted block: base attrs
59
+ * (`id,title,summary,editable`) first, then the spec's `toAttrs` in insertion
60
+ * order, then either nested children, prose children, or self-closing.
61
+ */
62
+ export declare function serializeSpecBlock(spec: BlockSpec<any>, block: SerializableBlock): string;
63
+ /**
64
+ * Parse one MDX JSX node into a block via the registry, if its tag is
65
+ * registered. Returns `null` for unregistered tags so the caller can fall back
66
+ * to its legacy parser. `base` is the already-extracted id/title/summary/
67
+ * editable; `children` is the stringified prose children.
68
+ */
69
+ export declare function parseSpecBlock(registry: BlockRegistry, node: MdxJsxNode, base: ParsedBlockBase, children: string, idContext: string): {
70
+ type: string;
71
+ data: unknown;
72
+ } | null;
73
+ export {};
74
+ //# sourceMappingURL=mdx.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mdx.d.ts","sourceRoot":"","sources":["../../../src/client/blocks/mdx.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAgB,MAAM,YAAY,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD;;;;;;;GAOG;AAMH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAErD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAazD;AAMD,yEAAyE;AACzE,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,CAAC;CAC3C,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAgBF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,WAAW,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAWF,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,CAgBrE;AA+CD,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,eAAe,CAyBlE;AAMD,2DAA2D;AAC3D,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,+EAA+E;AAC/E,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,EACpB,KAAK,EAAE,iBAAiB,GACvB,MAAM,CA+BR;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,aAAa,EACvB,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,eAAe,EACrB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAmBxC"}