@agent-native/core 0.101.14 → 0.102.1

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 (316) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +12 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/cli/templates-meta.ts +13 -0
  5. package/corpus/core/src/client/agent-page/AgentTabsPage.tsx +1 -1
  6. package/corpus/core/src/client/org/OrgSwitcher.tsx +2 -0
  7. package/corpus/templates/analytics/changelog/2026-07-15-fixed-the-agent-discarding-a-successful-dashboard-edit-and-r.md +6 -0
  8. package/corpus/templates/analytics/server/lib/real-data-actions.ts +30 -1
  9. package/corpus/templates/analytics/server/plugins/agent-chat.ts +15 -0
  10. package/corpus/templates/content/actions/_database-source-utils.ts +59 -4
  11. package/corpus/templates/content/actions/prepare-builder-source-review.ts +9 -0
  12. package/corpus/templates/content/actions/preview-builder-source-review.ts +6 -4
  13. package/corpus/templates/content/app/components/editor/DescriptionField.tsx +10 -2
  14. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +4 -0
  15. package/corpus/templates/content/changelog/2026-07-15-page-and-database-descriptions-now-use-a-clean-single-line-f.md +6 -0
  16. package/corpus/templates/content/changelog/2026-07-15-selected-builder-reviews-now-load-only-the-chosen-rows-avoid.md +6 -0
  17. package/corpus/templates/content/shared/api.ts +1 -0
  18. package/corpus/templates/tasks/.agents/commands/visual-plan.md +9 -0
  19. package/corpus/templates/tasks/.agents/commands/visual-recap.md +8 -0
  20. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +492 -0
  21. package/corpus/templates/tasks/.agents/skills/adding-a-feature/SKILL.md +189 -0
  22. package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +76 -0
  23. package/corpus/templates/tasks/.agents/skills/agent-watchdog/README.md +43 -0
  24. package/corpus/templates/tasks/.agents/skills/agent-watchdog/SKILL.md +110 -0
  25. package/corpus/templates/tasks/.agents/skills/agent-watchdog/agents/openai.yaml +4 -0
  26. package/corpus/templates/tasks/.agents/skills/capture-learnings/SKILL.md +89 -0
  27. package/corpus/templates/tasks/.agents/skills/change-summary/SKILL.md +83 -0
  28. package/corpus/templates/tasks/.agents/skills/create-skill/SKILL.md +221 -0
  29. package/corpus/templates/tasks/.agents/skills/delegate-to-agent/SKILL.md +263 -0
  30. package/corpus/templates/tasks/.agents/skills/efficient-fable/README.md +75 -0
  31. package/corpus/templates/tasks/.agents/skills/efficient-fable/SKILL.md +95 -0
  32. package/corpus/templates/tasks/.agents/skills/efficient-frontier/README.md +53 -0
  33. package/corpus/templates/tasks/.agents/skills/efficient-frontier/SKILL.md +73 -0
  34. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +112 -0
  35. package/corpus/templates/tasks/.agents/skills/plan-arbiter/README.md +41 -0
  36. package/corpus/templates/tasks/.agents/skills/plan-arbiter/SKILL.md +114 -0
  37. package/corpus/templates/tasks/.agents/skills/plan-arbiter/agents/openai.yaml +4 -0
  38. package/corpus/templates/tasks/.agents/skills/plow-ahead/README.md +42 -0
  39. package/corpus/templates/tasks/.agents/skills/plow-ahead/SKILL.md +104 -0
  40. package/corpus/templates/tasks/.agents/skills/plow-ahead/agents/openai.yaml +4 -0
  41. package/corpus/templates/tasks/.agents/skills/quick-recap/README.md +55 -0
  42. package/corpus/templates/tasks/.agents/skills/quick-recap/SKILL.md +54 -0
  43. package/corpus/templates/tasks/.agents/skills/read-the-damn-docs/README.md +54 -0
  44. package/corpus/templates/tasks/.agents/skills/read-the-damn-docs/SKILL.md +126 -0
  45. package/corpus/templates/tasks/.agents/skills/read-the-damn-docs/agents/openai.yaml +4 -0
  46. package/corpus/templates/tasks/.agents/skills/real-time-sync/SKILL.md +232 -0
  47. package/corpus/templates/tasks/.agents/skills/security/SKILL.md +280 -0
  48. package/corpus/templates/tasks/.agents/skills/self-modifying-code/SKILL.md +106 -0
  49. package/corpus/templates/tasks/.agents/skills/shadcn-ui/SKILL.md +95 -0
  50. package/corpus/templates/tasks/.agents/skills/stay-within-limits/README.md +61 -0
  51. package/corpus/templates/tasks/.agents/skills/stay-within-limits/SKILL.md +83 -0
  52. package/corpus/templates/tasks/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  53. package/corpus/templates/tasks/.agents/skills/visual-plan/SKILL.md +547 -0
  54. package/corpus/templates/tasks/.agents/skills/visual-plan/agent-native-skill.json +12 -0
  55. package/corpus/templates/tasks/.agents/skills/visual-plan/references/canvas.md +121 -0
  56. package/corpus/templates/tasks/.agents/skills/visual-plan/references/document-quality.md +178 -0
  57. package/corpus/templates/tasks/.agents/skills/visual-plan/references/exemplar.md +62 -0
  58. package/corpus/templates/tasks/.agents/skills/visual-plan/references/wireframe.md +264 -0
  59. package/corpus/templates/tasks/.agents/skills/visual-recap/SKILL.md +634 -0
  60. package/corpus/templates/tasks/.agents/skills/visual-recap/agent-native-skill.json +12 -0
  61. package/corpus/templates/tasks/.agents/skills/visual-recap/references/wireframe.md +264 -0
  62. package/corpus/templates/tasks/.claude/commands/visual-plan.md +9 -0
  63. package/corpus/templates/tasks/.claude/commands/visual-recap.md +8 -0
  64. package/corpus/templates/tasks/.env.example +5 -0
  65. package/corpus/templates/tasks/.ignore +0 -0
  66. package/corpus/templates/tasks/.prettierrc +5 -0
  67. package/corpus/templates/tasks/AGENTS.md +158 -0
  68. package/corpus/templates/tasks/DEVELOPING.md +185 -0
  69. package/corpus/templates/tasks/README.md +16 -0
  70. package/corpus/templates/tasks/actions/bulk-delete-inbox-items.ts +24 -0
  71. package/corpus/templates/tasks/actions/bulk-delete-tasks.ts +21 -0
  72. package/corpus/templates/tasks/actions/bulk-mark-inbox-items-ready.ts +27 -0
  73. package/corpus/templates/tasks/actions/bulk-update-tasks.ts +35 -0
  74. package/corpus/templates/tasks/actions/create-custom-field.ts +22 -0
  75. package/corpus/templates/tasks/actions/create-inbox-item.ts +30 -0
  76. package/corpus/templates/tasks/actions/create-task.ts +33 -0
  77. package/corpus/templates/tasks/actions/delete-custom-field.ts +19 -0
  78. package/corpus/templates/tasks/actions/delete-inbox-item.ts +17 -0
  79. package/corpus/templates/tasks/actions/delete-task.ts +17 -0
  80. package/corpus/templates/tasks/actions/lib/boolean-query-param.ts +30 -0
  81. package/corpus/templates/tasks/actions/list-custom-fields.ts +18 -0
  82. package/corpus/templates/tasks/actions/list-inbox-items.ts +16 -0
  83. package/corpus/templates/tasks/actions/list-tasks.ts +52 -0
  84. package/corpus/templates/tasks/actions/list-visible-task-fields.ts +18 -0
  85. package/corpus/templates/tasks/actions/mark-inbox-item-ready.ts +31 -0
  86. package/corpus/templates/tasks/actions/navigate.ts +51 -0
  87. package/corpus/templates/tasks/actions/reorder-custom-fields.ts +27 -0
  88. package/corpus/templates/tasks/actions/reorder-inbox-items.ts +24 -0
  89. package/corpus/templates/tasks/actions/reorder-tasks.ts +29 -0
  90. package/corpus/templates/tasks/actions/run.ts +2 -0
  91. package/corpus/templates/tasks/actions/update-custom-field.ts +33 -0
  92. package/corpus/templates/tasks/actions/update-inbox-item.ts +24 -0
  93. package/corpus/templates/tasks/actions/update-task.ts +68 -0
  94. package/corpus/templates/tasks/actions/update-visible-task-fields.ts +27 -0
  95. package/corpus/templates/tasks/actions/view-screen-helpers.ts +68 -0
  96. package/corpus/templates/tasks/actions/view-screen.ts +207 -0
  97. package/corpus/templates/tasks/app/components/custom-fields/FieldCreateBar.tsx +121 -0
  98. package/corpus/templates/tasks/app/components/custom-fields/FieldListRow.tsx +116 -0
  99. package/corpus/templates/tasks/app/components/custom-fields/FieldsList.tsx +225 -0
  100. package/corpus/templates/tasks/app/components/custom-fields/FieldsListSkeleton.tsx +18 -0
  101. package/corpus/templates/tasks/app/components/custom-fields/FieldsPage.tsx +42 -0
  102. package/corpus/templates/tasks/app/components/custom-fields/editor/FieldEditorSidebar.tsx +69 -0
  103. package/corpus/templates/tasks/app/components/custom-fields/editor/FieldTitleSection.tsx +32 -0
  104. package/corpus/templates/tasks/app/components/custom-fields/editor/config/CurrencyConfigControl.tsx +49 -0
  105. package/corpus/templates/tasks/app/components/custom-fields/editor/config/FieldConfigControl.tsx +56 -0
  106. package/corpus/templates/tasks/app/components/custom-fields/editor/config/NumberConfigControl.tsx +52 -0
  107. package/corpus/templates/tasks/app/components/custom-fields/editor/config/PercentConfigControl.tsx +30 -0
  108. package/corpus/templates/tasks/app/components/custom-fields/editor/config/SelectConfigControl.tsx +135 -0
  109. package/corpus/templates/tasks/app/components/custom-fields/editor/config/select-colors.ts +23 -0
  110. package/corpus/templates/tasks/app/components/custom-fields/editor/config/utils.ts +52 -0
  111. package/corpus/templates/tasks/app/components/custom-fields/editor/types.ts +7 -0
  112. package/corpus/templates/tasks/app/components/dnd/SortableItem.tsx +72 -0
  113. package/corpus/templates/tasks/app/components/dnd/SortableList.tsx +136 -0
  114. package/corpus/templates/tasks/app/components/dnd/reorder-moving-items.ts +160 -0
  115. package/corpus/templates/tasks/app/components/dnd/sortable-drag-props.ts +60 -0
  116. package/corpus/templates/tasks/app/components/inbox/InboxList.tsx +222 -0
  117. package/corpus/templates/tasks/app/components/inbox/InboxListPage.tsx +39 -0
  118. package/corpus/templates/tasks/app/components/inbox/InboxListRow.tsx +122 -0
  119. package/corpus/templates/tasks/app/components/layout/Header.tsx +55 -0
  120. package/corpus/templates/tasks/app/components/layout/HeaderActions.tsx +84 -0
  121. package/corpus/templates/tasks/app/components/layout/Layout.tsx +134 -0
  122. package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +211 -0
  123. package/corpus/templates/tasks/app/components/shared/AddListItemInput.tsx +57 -0
  124. package/corpus/templates/tasks/app/components/shared/AlertDialog.tsx +53 -0
  125. package/corpus/templates/tasks/app/components/shared/BulkDeleteDialog.tsx +76 -0
  126. package/corpus/templates/tasks/app/components/shared/ChipSelect.tsx +240 -0
  127. package/corpus/templates/tasks/app/components/shared/DeleteItemDialog.tsx +40 -0
  128. package/corpus/templates/tasks/app/components/shared/InlineEditable.tsx +166 -0
  129. package/corpus/templates/tasks/app/components/shared/ListEmptyState.tsx +13 -0
  130. package/corpus/templates/tasks/app/components/shared/ListErrorMessage.tsx +15 -0
  131. package/corpus/templates/tasks/app/components/shared/ListViewHeader.tsx +75 -0
  132. package/corpus/templates/tasks/app/components/shared/PageHeader.tsx +25 -0
  133. package/corpus/templates/tasks/app/components/shared/RowActionsMenu.tsx +42 -0
  134. package/corpus/templates/tasks/app/components/shared/SidePanel.tsx +99 -0
  135. package/corpus/templates/tasks/app/components/shared/dnd/ListRowPreview.tsx +37 -0
  136. package/corpus/templates/tasks/app/components/shared/list/List.tsx +63 -0
  137. package/corpus/templates/tasks/app/components/shared/list/ListRow.tsx +159 -0
  138. package/corpus/templates/tasks/app/components/shared/list/ListRowDragHandle.tsx +52 -0
  139. package/corpus/templates/tasks/app/components/shared/list/ListSkeletonRows.tsx +11 -0
  140. package/corpus/templates/tasks/app/components/shared/list/SortableListItemShell.tsx +32 -0
  141. package/corpus/templates/tasks/app/components/shared/list/types.ts +1 -0
  142. package/corpus/templates/tasks/app/components/shared/selection/ListSelectionBar.tsx +158 -0
  143. package/corpus/templates/tasks/app/components/shared/selection/ListSelectionHeaderToggle.tsx +28 -0
  144. package/corpus/templates/tasks/app/components/shared/selection/ListSelectionToolbar.tsx +81 -0
  145. package/corpus/templates/tasks/app/components/shared/selection/get-list-row-selection-ui.ts +41 -0
  146. package/corpus/templates/tasks/app/components/shared/selection/use-list-selection.ts +196 -0
  147. package/corpus/templates/tasks/app/components/tasks/TaskList.tsx +333 -0
  148. package/corpus/templates/tasks/app/components/tasks/TaskListHeaderRow.tsx +46 -0
  149. package/corpus/templates/tasks/app/components/tasks/TaskListPage.tsx +115 -0
  150. package/corpus/templates/tasks/app/components/tasks/TaskListRow.css +49 -0
  151. package/corpus/templates/tasks/app/components/tasks/TaskListRow.tsx +307 -0
  152. package/corpus/templates/tasks/app/components/tasks/fields/TaskFieldsSidebar.tsx +102 -0
  153. package/corpus/templates/tasks/app/components/tasks/fields/TaskTitleSection.tsx +27 -0
  154. package/corpus/templates/tasks/app/components/tasks/fields/controls/DateValueControl.tsx +21 -0
  155. package/corpus/templates/tasks/app/components/tasks/fields/controls/FieldValueControl.tsx +76 -0
  156. package/corpus/templates/tasks/app/components/tasks/fields/controls/MultiSelectValueControl.tsx +52 -0
  157. package/corpus/templates/tasks/app/components/tasks/fields/controls/NumberValueControl.tsx +56 -0
  158. package/corpus/templates/tasks/app/components/tasks/fields/controls/RichTextValueControl.tsx +115 -0
  159. package/corpus/templates/tasks/app/components/tasks/fields/controls/SingleSelectValueControl.tsx +61 -0
  160. package/corpus/templates/tasks/app/components/tasks/fields/controls/TextValueControl.tsx +20 -0
  161. package/corpus/templates/tasks/app/components/tasks/use-task-row-completion-animation.ts +181 -0
  162. package/corpus/templates/tasks/app/components/ui/accordion.tsx +56 -0
  163. package/corpus/templates/tasks/app/components/ui/alert-dialog.tsx +1 -0
  164. package/corpus/templates/tasks/app/components/ui/alert.tsx +1 -0
  165. package/corpus/templates/tasks/app/components/ui/aspect-ratio.tsx +5 -0
  166. package/corpus/templates/tasks/app/components/ui/avatar.tsx +1 -0
  167. package/corpus/templates/tasks/app/components/ui/badge.tsx +1 -0
  168. package/corpus/templates/tasks/app/components/ui/breadcrumb.tsx +115 -0
  169. package/corpus/templates/tasks/app/components/ui/button.tsx +1 -0
  170. package/corpus/templates/tasks/app/components/ui/calendar.tsx +70 -0
  171. package/corpus/templates/tasks/app/components/ui/card.tsx +1 -0
  172. package/corpus/templates/tasks/app/components/ui/carousel.tsx +260 -0
  173. package/corpus/templates/tasks/app/components/ui/chart.tsx +379 -0
  174. package/corpus/templates/tasks/app/components/ui/checkbox.tsx +1 -0
  175. package/corpus/templates/tasks/app/components/ui/collapsible.tsx +1 -0
  176. package/corpus/templates/tasks/app/components/ui/command.tsx +1 -0
  177. package/corpus/templates/tasks/app/components/ui/context-menu.tsx +1 -0
  178. package/corpus/templates/tasks/app/components/ui/dialog.tsx +1 -0
  179. package/corpus/templates/tasks/app/components/ui/drawer.tsx +1 -0
  180. package/corpus/templates/tasks/app/components/ui/dropdown-menu.tsx +1 -0
  181. package/corpus/templates/tasks/app/components/ui/form.tsx +177 -0
  182. package/corpus/templates/tasks/app/components/ui/hover-card.tsx +27 -0
  183. package/corpus/templates/tasks/app/components/ui/input-otp.tsx +69 -0
  184. package/corpus/templates/tasks/app/components/ui/input.tsx +1 -0
  185. package/corpus/templates/tasks/app/components/ui/label.tsx +1 -0
  186. package/corpus/templates/tasks/app/components/ui/menubar.tsx +254 -0
  187. package/corpus/templates/tasks/app/components/ui/navigation-menu.tsx +128 -0
  188. package/corpus/templates/tasks/app/components/ui/pagination.tsx +121 -0
  189. package/corpus/templates/tasks/app/components/ui/popover.tsx +1 -0
  190. package/corpus/templates/tasks/app/components/ui/progress.tsx +1 -0
  191. package/corpus/templates/tasks/app/components/ui/radio-group.tsx +1 -0
  192. package/corpus/templates/tasks/app/components/ui/resizable.tsx +43 -0
  193. package/corpus/templates/tasks/app/components/ui/scroll-area.tsx +1 -0
  194. package/corpus/templates/tasks/app/components/ui/select.tsx +1 -0
  195. package/corpus/templates/tasks/app/components/ui/separator.tsx +1 -0
  196. package/corpus/templates/tasks/app/components/ui/sheet.tsx +1 -0
  197. package/corpus/templates/tasks/app/components/ui/sidebar.tsx +782 -0
  198. package/corpus/templates/tasks/app/components/ui/skeleton.tsx +1 -0
  199. package/corpus/templates/tasks/app/components/ui/slider.tsx +1 -0
  200. package/corpus/templates/tasks/app/components/ui/sonner.tsx +1 -0
  201. package/corpus/templates/tasks/app/components/ui/spinner.tsx +1 -0
  202. package/corpus/templates/tasks/app/components/ui/switch.tsx +1 -0
  203. package/corpus/templates/tasks/app/components/ui/table.tsx +1 -0
  204. package/corpus/templates/tasks/app/components/ui/tabs.tsx +1 -0
  205. package/corpus/templates/tasks/app/components/ui/textarea.tsx +1 -0
  206. package/corpus/templates/tasks/app/components/ui/toast.tsx +1 -0
  207. package/corpus/templates/tasks/app/components/ui/toaster.tsx +1 -0
  208. package/corpus/templates/tasks/app/components/ui/toggle-group.tsx +1 -0
  209. package/corpus/templates/tasks/app/components/ui/toggle.tsx +43 -0
  210. package/corpus/templates/tasks/app/components/ui/tooltip.tsx +1 -0
  211. package/corpus/templates/tasks/app/components/ui/use-toast.ts +3 -0
  212. package/corpus/templates/tasks/app/entry.client.tsx +19 -0
  213. package/corpus/templates/tasks/app/entry.server.tsx +10 -0
  214. package/corpus/templates/tasks/app/global.css +93 -0
  215. package/corpus/templates/tasks/app/hooks/cache.ts +31 -0
  216. package/corpus/templates/tasks/app/hooks/use-custom-fields.ts +93 -0
  217. package/corpus/templates/tasks/app/hooks/use-inbox-items.ts +196 -0
  218. package/corpus/templates/tasks/app/hooks/use-mobile.tsx +21 -0
  219. package/corpus/templates/tasks/app/hooks/use-navigation-state.ts +40 -0
  220. package/corpus/templates/tasks/app/hooks/use-tasks.ts +276 -0
  221. package/corpus/templates/tasks/app/hooks/use-toast.ts +188 -0
  222. package/corpus/templates/tasks/app/hooks/use-visible-task-fields.ts +140 -0
  223. package/corpus/templates/tasks/app/lib/app-config.ts +11 -0
  224. package/corpus/templates/tasks/app/lib/tab-id.ts +1 -0
  225. package/corpus/templates/tasks/app/lib/utils.ts +1 -0
  226. package/corpus/templates/tasks/app/root.tsx +130 -0
  227. package/corpus/templates/tasks/app/routes/_index.tsx +22 -0
  228. package/corpus/templates/tasks/app/routes/extensions.$id.$slug.tsx +2 -0
  229. package/corpus/templates/tasks/app/routes/extensions.$id.tsx +11 -0
  230. package/corpus/templates/tasks/app/routes/extensions._index.tsx +11 -0
  231. package/corpus/templates/tasks/app/routes/extensions.tsx +5 -0
  232. package/corpus/templates/tasks/app/routes/fields.tsx +16 -0
  233. package/corpus/templates/tasks/app/routes/inbox.tsx +16 -0
  234. package/corpus/templates/tasks/app/routes/tasks.tsx +17 -0
  235. package/corpus/templates/tasks/app/routes/team.tsx +17 -0
  236. package/corpus/templates/tasks/app/routes.ts +4 -0
  237. package/corpus/templates/tasks/app/vite-env.d.ts +6 -0
  238. package/corpus/templates/tasks/components.json +20 -0
  239. package/corpus/templates/tasks/data/sync-config.json +1 -0
  240. package/corpus/templates/tasks/docs/features/README.md +81 -0
  241. package/corpus/templates/tasks/docs/features/f1-tasks.mdx +67 -0
  242. package/corpus/templates/tasks/docs/features/f2-custom-fields.mdx +68 -0
  243. package/corpus/templates/tasks/docs/features/f3-projects.mdx +33 -0
  244. package/corpus/templates/tasks/docs/features/f4-inbox.mdx +55 -0
  245. package/corpus/templates/tasks/docs/features/f5-views.mdx +65 -0
  246. package/corpus/templates/tasks/docs/features/f6-search.mdx +43 -0
  247. package/corpus/templates/tasks/docs/features/f7-first-run.mdx +66 -0
  248. package/corpus/templates/tasks/docs/features/f8-chat.mdx +120 -0
  249. package/corpus/templates/tasks/e2e/global-setup.ts +42 -0
  250. package/corpus/templates/tasks/e2e/helpers/inbox.ts +71 -0
  251. package/corpus/templates/tasks/e2e/helpers/tasks.ts +99 -0
  252. package/corpus/templates/tasks/learnings.defaults.md +5 -0
  253. package/corpus/templates/tasks/netlify.toml +10 -0
  254. package/corpus/templates/tasks/package.json +104 -0
  255. package/corpus/templates/tasks/playwright.config.ts +34 -0
  256. package/corpus/templates/tasks/public/agent-native-icon-dark.svg +10 -0
  257. package/corpus/templates/tasks/public/agent-native-icon-light.svg +10 -0
  258. package/corpus/templates/tasks/public/agent-native-logo-dark.svg +21 -0
  259. package/corpus/templates/tasks/public/agent-native-logo-light.svg +21 -0
  260. package/corpus/templates/tasks/public/favicon.svg +1 -0
  261. package/corpus/templates/tasks/public/icon-180.svg +1 -0
  262. package/corpus/templates/tasks/public/icon-192.svg +1 -0
  263. package/corpus/templates/tasks/public/icon-512.svg +1 -0
  264. package/corpus/templates/tasks/public/manifest.json +21 -0
  265. package/corpus/templates/tasks/react-router.config.ts +7 -0
  266. package/corpus/templates/tasks/server/custom-fields/normalize.ts +163 -0
  267. package/corpus/templates/tasks/server/custom-fields/parse.ts +146 -0
  268. package/corpus/templates/tasks/server/custom-fields/schema.ts +147 -0
  269. package/corpus/templates/tasks/server/custom-fields/store.ts +425 -0
  270. package/corpus/templates/tasks/server/custom-fields/task-fields.ts +104 -0
  271. package/corpus/templates/tasks/server/custom-fields/types.ts +98 -0
  272. package/corpus/templates/tasks/server/custom-fields/validate.ts +210 -0
  273. package/corpus/templates/tasks/server/custom-fields/values/store.ts +386 -0
  274. package/corpus/templates/tasks/server/db/bulk-write.ts +30 -0
  275. package/corpus/templates/tasks/server/db/index.ts +5 -0
  276. package/corpus/templates/tasks/server/db/record-utils.ts +7 -0
  277. package/corpus/templates/tasks/server/db/schema.ts +67 -0
  278. package/corpus/templates/tasks/server/db/test-tasks-table.ts +76 -0
  279. package/corpus/templates/tasks/server/db/transaction.ts +6 -0
  280. package/corpus/templates/tasks/server/errors.ts +31 -0
  281. package/corpus/templates/tasks/server/inbox/store.ts +216 -0
  282. package/corpus/templates/tasks/server/middleware/auth.ts +15 -0
  283. package/corpus/templates/tasks/server/plugins/agent-chat.ts +46 -0
  284. package/corpus/templates/tasks/server/plugins/auth.ts +15 -0
  285. package/corpus/templates/tasks/server/plugins/db.ts +90 -0
  286. package/corpus/templates/tasks/server/routes/[...page].get.ts +5 -0
  287. package/corpus/templates/tasks/server/stored-items/store.ts +548 -0
  288. package/corpus/templates/tasks/server/tasks/store.ts +306 -0
  289. package/corpus/templates/tasks/server/user-config/store.ts +138 -0
  290. package/corpus/templates/tasks/shared/app-state-tabs.ts +15 -0
  291. package/corpus/templates/tasks/shared/boolean-param.ts +22 -0
  292. package/corpus/templates/tasks/shared/bulk-limits.ts +7 -0
  293. package/corpus/templates/tasks/shared/list-screen-snapshot.ts +90 -0
  294. package/corpus/templates/tasks/shared/navigation.ts +104 -0
  295. package/corpus/templates/tasks/shared/visible-task-fields.ts +2 -0
  296. package/corpus/templates/tasks/ssr-entry.ts +15 -0
  297. package/corpus/templates/tasks/tsconfig.json +24 -0
  298. package/corpus/templates/tasks/vite.config.ts +19 -0
  299. package/corpus/templates/tasks/vitest.config.ts +8 -0
  300. package/dist/cli/templates-meta.d.ts.map +1 -1
  301. package/dist/cli/templates-meta.js +13 -0
  302. package/dist/cli/templates-meta.js.map +1 -1
  303. package/dist/client/agent-page/AgentTabsPage.js +1 -1
  304. package/dist/client/agent-page/AgentTabsPage.js.map +1 -1
  305. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  306. package/dist/client/org/OrgSwitcher.js +2 -1
  307. package/dist/client/org/OrgSwitcher.js.map +1 -1
  308. package/dist/collab/routes.d.ts +1 -1
  309. package/dist/collab/struct-routes.d.ts +1 -1
  310. package/dist/notifications/routes.d.ts +2 -2
  311. package/dist/observability/routes.d.ts +5 -5
  312. package/dist/resources/handlers.d.ts +3 -3
  313. package/dist/secrets/routes.d.ts +9 -9
  314. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  315. package/dist/server/transcribe-voice.d.ts +1 -1
  316. package/package.json +1 -1
@@ -0,0 +1,280 @@
1
+ ---
2
+ name: security
3
+ description: >-
4
+ Secure coding practices for agent-native apps: input validation, SQL
5
+ injection, XSS, secrets, data scoping, and auth. Use when writing any action,
6
+ route, or component that touches user data or external input.
7
+ scope: dev
8
+ metadata:
9
+ internal: true
10
+ ---
11
+
12
+ # Security
13
+
14
+ ## Rule
15
+
16
+ Use the framework's security primitives everywhere. Never bypass them.
17
+
18
+ ## Absolute Secrets Rule
19
+
20
+ Never hardcode secret values or real private data. This applies to source code,
21
+ docs, tests, fixtures, generated prompts, screenshots, seed data, and extension
22
+ HTML just as much as production code.
23
+
24
+ Do not paste or invent real-looking API keys, bearer tokens, OAuth refresh
25
+ tokens, webhook URLs, signing secrets, private Builder/internal data, or customer
26
+ data into the repo. Examples must use obvious placeholders such as
27
+ `<OPENAI_API_KEY>`, `${keys.SLACK_WEBHOOK}`, `sk-test-example`, or
28
+ `example.customer@example.com`. Test literals should be clearly fake and must
29
+ not match real provider token formats when an `example` token will do.
30
+
31
+ Credential values enter the system only through approved runtime channels:
32
+ deployment env vars for deploy-level secrets, the encrypted `app_secrets` vault
33
+ or `saveCredential` / `resolveCredential` for user/org/workspace API keys, and
34
+ `oauth_tokens` for OAuth. Code and instructions may name the credential key
35
+ (`OPENAI_API_KEY`), but must never contain the credential value.
36
+
37
+ ## Input Validation
38
+
39
+ Use `defineAction` with a Zod `schema:` for every action. The framework validates input automatically and returns clear 400 errors for HTTP callers and structured error results for agent tool calls.
40
+
41
+ ```ts
42
+ export default defineAction({
43
+ schema: z.object({
44
+ email: z.string().email(),
45
+ role: z.enum(["admin", "member"]),
46
+ limit: z.coerce.number().int().min(1).max(100).default(25),
47
+ }),
48
+ run: async (args) => { /* args is fully typed and validated */ },
49
+ });
50
+ ```
51
+
52
+ The legacy `parameters:` field (plain JSON Schema) has no runtime validation — do not use it for new code.
53
+
54
+ ## Large Payloads
55
+
56
+ Do not accept or persist unbounded base64/file blobs through actions, SQL writes,
57
+ or `application_state`. Route uploads through the file-upload provider and store
58
+ references. This prevents database bloat, slow hot paths, and accidental secret
59
+ or customer-data embedding inside binary payloads.
60
+
61
+ ## SQL Injection
62
+
63
+ Never concatenate user input into SQL strings. Use Drizzle ORM's query builder (always safe) or parameterized queries:
64
+
65
+ ```ts
66
+ // Safe — Drizzle ORM
67
+ await db.select().from(users).where(eq(users.email, args.email));
68
+
69
+ // Safe — parameterized raw SQL
70
+ await client.execute({ sql: "SELECT * FROM users WHERE id = ?", args: [id] });
71
+
72
+ // NEVER do this
73
+ await client.execute(`SELECT * FROM users WHERE id = '${id}'`);
74
+ ```
75
+
76
+ ## XSS
77
+
78
+ - React auto-escapes JSX content — trust it.
79
+ - Never use `dangerouslySetInnerHTML`, `innerHTML`, `eval()`, or `document.write()` with user-controlled content.
80
+ - For rich text editing, use TipTap (framework dependency).
81
+ - For rendering markdown, use `react-markdown`.
82
+
83
+ ## SSRF
84
+
85
+ Any server-side `fetch` of a user- or agent-controlled URL must go through the framework SSRF guard — a bare `fetch()` can be steered at cloud metadata (`169.254.169.254`), `localhost`, or internal services.
86
+
87
+ ```ts
88
+ import { ssrfSafeFetch } from "@agent-native/core/extensions/url-safety";
89
+ // Blocks private/internal targets, re-checks the resolved IP at connect time
90
+ // (DNS rebinding), and re-validates every redirect hop.
91
+ const res = await ssrfSafeFetch(userProvidedUrl, {}, { maxRedirects: 3 });
92
+ ```
93
+
94
+ For a pre-flight-only check (e.g. before a streaming or one-shot fetch), use `isBlockedExtensionUrlWithDns(url)` plus `createSsrfSafeDispatcher()` from the same module, and set `redirect: "manual"`. Never let the default `fetch` follow redirects for an untrusted URL — a public URL can 30x into the private network.
95
+
96
+ ## Secrets
97
+
98
+ - OAuth tokens go in the `oauth_tokens` store via `saveOAuthTokens()`.
99
+ - Per-user / per-org API keys go through `saveCredential` / `resolveCredential` (`@agent-native/core/credentials`) or the `app_secrets` vault. Both encrypt values at rest with AES-256-GCM (keyed by `SECRETS_ENCRYPTION_KEY`, falling back to `BETTER_AUTH_SECRET`; production refuses to start without one).
100
+ - Never hand-roll secrets into `settings`, `application_state`, source code, or action responses sent to the client. The credential / vault APIs above are the only sanctioned stores.
101
+ - Never commit real keys, tokens, webhook URLs, signing secrets, or private
102
+ Builder/customer data in examples or fixtures. Use placeholders that cannot be
103
+ mistaken for working credentials.
104
+
105
+ ## User Credentials Are Per-User Data — Never `process.env`
106
+
107
+ User credentials (API keys, third-party tokens) are per-user (or per-org) data. They MUST live in SQL, scoped per-user (`u:<email>:credential:KEY`) or per-org (`o:<orgId>:credential:KEY`). Always read with the request context:
108
+
109
+ ```ts
110
+ import { resolveCredential } from "@agent-native/core/credentials";
111
+ const apiKey = await resolveCredential("OPENAI_API_KEY", { userEmail, orgId });
112
+ ```
113
+
114
+ Values are encrypted at rest (AES-256-GCM, shared `secrets/crypto.ts`): `saveCredential` encrypts on write and `resolveCredential` decrypts on read, with a transparent fallback for legacy plaintext rows. The agent's raw `db-query` / `db-exec` tools also cannot read credential rows — they are excluded from the scoped `settings` view. To encrypt pre-existing rows in place, run `pnpm action db-migrate-encrypt-credentials` (idempotent, non-destructive; needs the same `SECRETS_ENCRYPTION_KEY` / `BETTER_AUTH_SECRET` as the app).
115
+
116
+ On 2026-04-29 the previous one-arg `resolveCredential(key)` form fell back to `process.env[key]` and an unscoped global `settings` row, so every signed-in user inherited the deployment's credentials. Two guards now block this in CI (`pnpm prep`):
117
+
118
+ - `scripts/guard-no-env-credentials.mjs` — bans `process.env.<KEY>` reads in `packages/core/src/credentials/`, `secrets/`, `vault/`, and `templates/*/server/{lib,routes/api}/credential*` paths, except for an explicit allowlist of deploy-level vars (`DATABASE_URL`, `BETTER_AUTH_SECRET`, `NETLIFY_*`, etc.). Per-line opt-out: `// guard:allow-env-credential — <reason>`.
119
+ - `scripts/guard-no-unscoped-credentials.mjs` — bans one-arg calls to `resolveCredential` / `hasCredential` / `saveCredential` / `deleteCredential`. Per-line opt-out: `// guard:allow-unscoped-credential — <reason>`.
120
+
121
+ If a deploy-level value genuinely needs an env var (CI-set token, host secret), it's not a user credential — keep it out of the credentials/ secrets/ vault/ paths and the env-credentials guard won't see it.
122
+
123
+ ## Guards
124
+
125
+ Two more CI guards (also wired into `pnpm prep`) target the 2026-04 cross-tenant leak class — request-state escaping into shared process state, and dev-mode sentinel identities used as production fallbacks.
126
+
127
+ - `scripts/guard-no-env-mutation.mjs` — bans `process.env.<KEY> = …` (and bracket / compound forms) anywhere in production code. On serverless, every warm container handles many concurrent requests in one Node process, so `process.env` mutation leaks across in-flight requests (the "restore" line at the end of a handler races and never helps — most recently the Zoom webhook). Use `runWithRequestContext({ userEmail, orgId, timezone }, fn)` from `@agent-native/core/server` instead — it's AsyncLocalStorage-backed and per-request safe. Allowlisted paths: `scripts/`, `*.spec.ts` / `*.test.ts`, `packages/core/src/dev**`, `templates/*/test/`, anything under `/cli/` or `/scaffold/`. Per-line opt-out: `process.env.X = y // guard:allow-env-mutation — <reason>`.
128
+ - `scripts/guard-no-localhost-fallback.mjs` — bans the literal `"local@localhost"` / `'local@localhost'` / `` `local@localhost` `` in production code. The bug class: `getRequestUserEmail() ?? "local@localhost"` silently pools every unauthenticated request into a single shared tenant, leaking credentials, tools, and `application_state` rows between accounts. The right behavior is to throw / 401 when there's no session. Allowlisted paths: the dev-mode auth shim (`packages/core/src/server/auth.ts`), `packages/core/src/dev**`, tests, `scripts/`, `seed/` / `seeds/`, plus a few framework helpers that intentionally inspect or migrate the dev identity. SQL DDL `DEFAULT 'local@localhost'` and the Drizzle helper `.default('local@localhost')` are skipped per-line — schema column defaults are intentional dev fixtures, not the dangerous fallback pattern. Per-line opt-out: `email ?? "local@localhost" // guard:allow-localhost-fallback — <reason>`.
129
+
130
+ ## Auth
131
+
132
+ - All actions are protected by the auth guard automatically.
133
+ - Prefer actions for normal app data. Do not hand-write `/api/*` routes for
134
+ CRUD, data queries, or action re-exports just to add auth; action endpoints
135
+ already get auth and request context.
136
+ - If you must create custom `/api/` routes, always call `getSession(event)` and reject requests without a session:
137
+
138
+ ```ts
139
+ import { getSession } from "@agent-native/core/server";
140
+
141
+ export default defineEventHandler(async (event) => {
142
+ const session = await getSession(event);
143
+ if (!session) throw createError({ statusCode: 401 });
144
+ // ...
145
+ });
146
+ ```
147
+
148
+ - Never create unprotected routes that modify data.
149
+
150
+ **Exception — the SSR HTML/`.data` catch-all is deliberately session-blind.**
151
+ The rule above is for routes that read or mutate user data. The SSR page
152
+ render and React Router `.data` route are different: they serve one
153
+ impersonal, public-cacheable shell to every visitor by design, and loaders on
154
+ that path render no user data. Do not "fix" this by adding `getSession`,
155
+ `private`, or `no-store` to it — that regresses the CDN cache contract for the
156
+ whole site. Data scoping lives in actions and API routes; the client gates
157
+ private UI after the shell loads. See the `authentication` skill and
158
+ `guard:ssr-cache-shell` / `ssr-handler.spec.ts`.
159
+
160
+ ## Human-in-the-Loop Approval for High-Consequence Actions
161
+
162
+ For a small set of outward-facing, hard-to-undo operations — sending an email, charging a card, deleting an account, posting publicly — auth and access control are necessary but not sufficient: you also do not want the **agent** to perform them autonomously. Set `needsApproval` on the `defineAction` so the agent cannot run the action without a human approving the specific call.
163
+
164
+ ```ts
165
+ export default defineAction({
166
+ description: "Send an email via Gmail.",
167
+ schema: z.object({ to: z.string(), subject: z.string(), body: z.string() }),
168
+ needsApproval: true, // or (args, ctx) => boolean | Promise<boolean>
169
+ run: async (args) => {
170
+ /* ...actually send... */
171
+ },
172
+ });
173
+ ```
174
+
175
+ When the gate is truthy and the call is not yet approved, the loop emits an `approval_required` event and **stops the turn — `run()` never executes**. The human approves via the chat UI's Approve affordance, which re-issues the turn with the call's stable `approvalKey`; only then does the action run. A predicate gates conditionally (e.g. only external recipients) and **fails closed** — a throw is treated as "approval required".
176
+
177
+ Rules:
178
+
179
+ - Reach for `needsApproval` only for genuinely high-consequence operations. The default is off, and the framework intentionally keeps approvals rare — over-gating turns the agent into a click-through wizard. The canonical (and intentionally lone) framework example is Mail's `send-email`.
180
+ - `needsApproval` is **not** a substitute for `accessFilter` / `assertAccess` or for hiding sensitive operations from the model with `agentTool: false` / `toolCallable: false`. It is the layer for "a human must explicitly bless this specific outward-facing call," not for scoping data. See the `actions` skill for the full surface.
181
+
182
+ ## Custom HTTP Routes Must Apply Access Control Themselves
183
+
184
+ This is the single most-failed rule in the codebase. Auto-mounted action routes (`/_agent-native/actions/...`) get a request context wired up automatically. **Hand-written `/api/*` Nitro routes do not.** If your handler queries an ownable resource (any table with `...ownableColumns()`), you MUST:
185
+
186
+ 1. Read the session: `const session = await getSession(event).catch(() => null)`.
187
+ 2. Run the work inside `runWithRequestContext({ userEmail: session?.email, orgId: session?.orgId }, fn)` from `@agent-native/core/server`.
188
+ 3. Inside `fn`, query through one of:
189
+ - `accessFilter(table, sharesTable)` in the WHERE clause for list/read-many.
190
+ - `resolveAccess("<type>", id)` for read-by-id (returns null if no access — return 404, not 403, so existence isn't leaked).
191
+ - `assertAccess("<type>", id, "viewer"|"editor"|"admin")` for write/delete-by-id.
192
+
193
+ ```ts
194
+ // Bad — Brent's signup leaked every other user's decks because of this exact shape.
195
+ export default defineEventHandler(async () => {
196
+ const db = getDb();
197
+ return db.select().from(schema.decks); // no access filter!
198
+ });
199
+
200
+ // Good
201
+ import { getSession, runWithRequestContext } from "@agent-native/core/server";
202
+ import { accessFilter } from "@agent-native/core/sharing";
203
+ export default defineEventHandler(async (event) => {
204
+ const session = await getSession(event).catch(() => null);
205
+ return runWithRequestContext(
206
+ { userEmail: session?.email, orgId: session?.orgId },
207
+ async () => {
208
+ const db = getDb();
209
+ return db
210
+ .select()
211
+ .from(schema.decks)
212
+ .where(accessFilter(schema.decks, schema.deckShares));
213
+ },
214
+ );
215
+ });
216
+ ```
217
+
218
+ `scripts/guard-no-unscoped-queries.mjs` runs in `pnpm prep` and fails the build if any file in `templates/*/server/`, `templates/*/actions/`, or `packages/*/src/` queries an ownable table without one of the access helpers. Last-resort opt-out is the marker comment `// guard:allow-unscoped — <reason>` — only use it for cases like the sharing primitives themselves or share-token-public viewer endpoints, and always include a reviewer-readable reason.
219
+
220
+ ## Data Scoping
221
+
222
+ In production, the framework automatically restricts all agent SQL queries to the current user's data using temporary views. This is enforced at the SQL level — the agent cannot bypass it.
223
+
224
+ The `db-query` / `db-exec` tools (and the extension SQL bridge, which shares the same path) reject schema-qualified table references like `public.<table>` or `main.<table>` — a qualified name resolves to the base table and would skip the temp view. Use bare table names; scoping is applied automatically.
225
+
226
+ ### Per-User Scoping (`owner_email`)
227
+
228
+ Every template table with user data **must** have an `owner_email` text column:
229
+
230
+ 1. Framework detects `owner_email` via schema introspection
231
+ 2. Creates temp views `WHERE owner_email = <current user>` before each query
232
+ 3. Auto-injects `owner_email` into INSERT statements
233
+
234
+ The current user is resolved from `AGENT_USER_EMAIL` (set automatically from the session).
235
+
236
+ ### Per-Org Scoping (`org_id`)
237
+
238
+ For multi-org apps, tables also need `org_id`:
239
+
240
+ 1. `WHERE org_id = <current org>` is added (in addition to `owner_email` if present)
241
+ 2. `org_id` is auto-injected into INSERT statements
242
+
243
+ Enable org scoping in the agent-chat plugin:
244
+
245
+ ```ts
246
+ createAgentChatPlugin({
247
+ resolveOrgId: async (event) => {
248
+ const ctx = await getOrgContext(event);
249
+ return ctx.orgId;
250
+ },
251
+ });
252
+ ```
253
+
254
+ ### Column Conventions
255
+
256
+ | Column | Purpose | Required |
257
+ | ------------- | ----------------------- | ------------------------------- |
258
+ | `owner_email` | Per-user data isolation | Yes, for all user-facing tables |
259
+ | `org_id` | Per-org data isolation | Yes, for multi-org apps |
260
+
261
+ Run `pnpm action db-check-scoping` to verify. Use `--require-org` for multi-org apps.
262
+
263
+ ## Checklist
264
+
265
+ - [ ] New action uses `defineAction` with a Zod `schema:`
266
+ - [ ] No SQL string concatenation with user input
267
+ - [ ] No `dangerouslySetInnerHTML` with user content
268
+ - [ ] Server-side fetches of user/agent URLs use `ssrfSafeFetch`, not bare `fetch`
269
+ - [ ] Secrets stored via `saveCredential` / the vault (encrypted), never raw in `settings` or responses
270
+ - [ ] No hardcoded API keys, tokens, webhook URLs, signing secrets, real
271
+ credential-looking strings, private Builder/internal data, or customer data
272
+ - [ ] New env vars in `.env` only, not committed
273
+ - [ ] New user-data tables have `owner_email` column
274
+ - [ ] Custom routes call `getSession` and reject unauthenticated requests
275
+
276
+ ## Related Skills
277
+
278
+ - `storing-data` — SQL patterns and the agent's db tools
279
+ - `actions` — `defineAction` with Zod schema validation
280
+ - `authentication` — Auth modes, sessions, and org context
@@ -0,0 +1,106 @@
1
+ ---
2
+ name: self-modifying-code
3
+ description: >-
4
+ How the agent can modify the app's own source code. Use when the agent needs
5
+ to edit components, routes, styles, or scripts, when designing UI for agent
6
+ editability, or when deciding what the agent should and shouldn't modify.
7
+ scope: dev
8
+ metadata:
9
+ internal: true
10
+ ---
11
+
12
+ # Self-Modifying Code
13
+
14
+ ## Rule
15
+
16
+ The agent can edit the app's own source code — components, routes, styles, scripts. This is a feature, not a bug. Design your app expecting this.
17
+
18
+ ## Why
19
+
20
+ An agent-native app isn't just an app the agent can _use_ — it's an app the agent can _change_. The agent can fix bugs, add features, adjust styles, and restructure code. This makes the agent a true collaborator, not just an operator.
21
+
22
+ ## Modification Taxonomy
23
+
24
+ Not all modifications are equal. Use this to decide what level of care is needed:
25
+
26
+ | Tier | What | Examples | After modifying |
27
+ | ------------- | --------------------- | ------------------------------------------------ | --------------------------------- |
28
+ | 1: Data | Files in `data/` | JSON state, generated content, markdown | Nothing — these are routine |
29
+ | 2: Source | App code | Components, routes, styles, scripts | Run `pnpm typecheck && pnpm lint` |
30
+ | 3: Config | Project config | `package.json`, `tsconfig.json`, `vite.config.*` | Ask for explicit approval first |
31
+ | 4: Off limits | Secrets and framework | `.env`, `@agent-native/*` packages & overrides | Never modify these |
32
+
33
+ Tier 4 includes **all** of the following — not only editing package source:
34
+
35
+ - Files under `node_modules/@agent-native/*` (core, dispatch, scheduling, …)
36
+ - `pnpm.overrides`, `overrides`, `resolutions`, or `patchedDependencies` that
37
+ target any `@agent-native/*` package
38
+ - Local patches, vendored copies, or invented "dispatch/core behavior"
39
+ shims meant to paper over a version skew or failed upgrade
40
+
41
+ When an older branch needs current packages, use **`agent-native upgrade`**
42
+ (see the `upgrade-agent-native` skill). If upgrade or typecheck fails, fix
43
+ **app** code or stop and ask — do not patch the framework.
44
+
45
+ ## Git Checkpoint Pattern
46
+
47
+ Before modifying source code (Tier 2+), create a rollback point:
48
+
49
+ 1. Commit or stash current state
50
+ 2. Make the edit
51
+ 3. Run `pnpm typecheck && pnpm lint`
52
+ 4. If verification fails → revert with `git checkout -- <file>`
53
+ 5. If verification passes → continue
54
+
55
+ This ensures the agent can experiment without breaking the app.
56
+
57
+ ## Designing for Agent Editability
58
+
59
+ Make your app easy for the agent to understand and modify:
60
+
61
+ **Expose UI state via `data-*` attributes** so the agent knows what's selected:
62
+
63
+ ```ts
64
+ const el = document.documentElement;
65
+ el.dataset.currentView = view;
66
+ el.dataset.selectedId = selectedItem?.id || "";
67
+ ```
68
+
69
+ **Expose richer context via `window.__appState`** for complex state:
70
+
71
+ ```ts
72
+ (window as any).__appState = {
73
+ selectedId: id,
74
+ currentLayout: layout,
75
+ itemCount: items.length,
76
+ };
77
+ ```
78
+
79
+ **Use configuration-driven rendering** — Extract visual decisions (colors, layouts, sizes) into JSON config files in `data/`. The agent can modify the config (Tier 1) instead of the component source (Tier 2).
80
+
81
+ **Keep localized copy in catalogs** — When editing visible UI copy, labels,
82
+ toasts, empty states, prompts, or formatting, read `internationalization` and
83
+ update `app/i18n/en-US.ts` plus existing locale catalogs instead of leaving new
84
+ inline strings in components.
85
+
86
+ ## Don't
87
+
88
+ - Don't modify `.env` files or files containing secrets
89
+ - Don't modify `@agent-native/core`, `@agent-native/dispatch`, or other
90
+ `@agent-native/*` package internals (including under `node_modules`)
91
+ - Don't add `pnpm.overrides` / `patchedDependencies` / `resolutions` for
92
+ `@agent-native/*` to "make the app run" after a version bump
93
+ - Don't invent local dispatch/core behavior overrides when upgrade fails —
94
+ run `npx @agent-native/core@latest upgrade`, then fix app-level errors only
95
+ - Don't modify `.agents/skills/` or `AGENTS.md` unless explicitly requested
96
+ - Don't skip the typecheck/lint step after editing source code
97
+ - Don't make source changes without a git checkpoint to roll back to
98
+
99
+ ## Related Skills
100
+
101
+ - **upgrade-agent-native** — supported path to bring an older app/workspace current
102
+ - **storing-data** — Tier 1 modifications (data files) are the safest and most common
103
+ - **actions** — The agent can create or modify actions to add new capabilities
104
+ - **delegate-to-agent** — Self-modification requests come through the agent chat
105
+ - **real-time-sync** — Database writes trigger change events to update the UI
106
+ - **internationalization** — UI copy, language catalogs, locale switching, and RTL-safe edits
@@ -0,0 +1,95 @@
1
+ ---
2
+ name: shadcn-ui
3
+ description: >-
4
+ Use when adding, updating, debugging, styling, or composing shadcn/ui
5
+ components, forms, dialogs, menus, charts, sidebars, themes, registries, or
6
+ any project with a components.json file.
7
+ scope: dev
8
+ source: https://ui.shadcn.com/docs/skills
9
+ metadata:
10
+ internal: true
11
+ ---
12
+
13
+ # shadcn/ui
14
+
15
+ This skill keeps shadcn/ui work project-aware. Components are source files in the app, so always inspect the local project before adding, importing, or rewriting them.
16
+
17
+ ## First Steps
18
+
19
+ 1. Work from the app root that owns `components.json`.
20
+ 2. Run `pnpm dlx shadcn@latest info --json` when you need current project context: framework, Tailwind version, aliases, icon library, installed components, and resolved paths.
21
+ 3. Use the actual aliases from `components.json` or `shadcn info`; do not assume `@/components/ui` if the project says otherwise.
22
+ 4. Check `app/components/ui/` or the resolved `ui` path before importing a component.
23
+ 5. For unfamiliar components, run `pnpm dlx shadcn@latest docs <component>` and read the returned docs or examples before coding.
24
+
25
+ ## Adding Or Updating Components
26
+
27
+ - Add missing primitives with `pnpm dlx shadcn@latest add <component>` from the app root.
28
+ - Before overwriting an existing component, use `pnpm dlx shadcn@latest add <component> --dry-run` and `--diff` to inspect the change.
29
+ - After adding registry code, read the generated files. Fix import aliases, icon imports, missing subcomponents, and composition issues before using the component.
30
+ - Do not fetch raw component files manually from GitHub when the shadcn CLI can resolve the registry item.
31
+ - If a user asks to add a third-party block but does not name a registry, ask which registry to use instead of guessing.
32
+
33
+ ## Component Composition
34
+
35
+ - Use existing primitives before custom markup: `Alert` for callouts, `Badge` for small status labels, `Separator` for dividers, `Skeleton` for placeholders, `Table` for tabular data, and `Card` for framed content.
36
+ - Use full card anatomy when appropriate: `CardHeader`, `CardTitle`, `CardDescription`, `CardContent`, and `CardFooter`.
37
+ - Dialog, Sheet, Drawer, and AlertDialog content must include an accessible title. Use visually hidden titles only when the visible UI already communicates the title.
38
+ - Put items inside their group components: `SelectItem` in `SelectGroup`, `DropdownMenuItem` in `DropdownMenuGroup`, `CommandItem` in `CommandGroup`, and equivalent menu groups.
39
+ - `TabsTrigger` belongs inside `TabsList`.
40
+ - `Avatar` always needs `AvatarFallback`.
41
+ - Buttons do not have magic loading props. Compose loading with `disabled`, `Spinner`, and clear text.
42
+
43
+ ## Forms And Inputs
44
+
45
+ - Use the app's shadcn form primitives instead of raw div stacks.
46
+ - If `Field`, `FieldGroup`, `FieldSet`, or `InputGroup` are installed or worth adding, use them for form layout, grouped fields, and input add-ons.
47
+ - Do not place buttons inside inputs with absolute positioning. Use `InputGroup` and `InputGroupAddon` when available.
48
+ - Use `ToggleGroup` for small option sets, `RadioGroup` for one-of-many choices, `Checkbox` for multi-select, `Switch` for settings toggles, `Select` or `Combobox` for predefined choices, and `Slider` or numeric input for numeric values.
49
+ - Validation must be accessible: pair visual invalid states with `aria-invalid`, and connect descriptions/errors to controls.
50
+
51
+ ## Styling And Theming
52
+
53
+ - Use semantic tokens (`bg-background`, `text-foreground`, `text-muted-foreground`, `bg-primary`, `border-border`, `text-destructive`) instead of raw colors for reusable app UI.
54
+ - Prefer built-in variants and sizes before custom classes.
55
+ - Use `className` mostly for layout and spacing; avoid overriding component colors and typography unless the component is intentionally being extended.
56
+ - Use `gap-*` instead of `space-x-*` / `space-y-*`.
57
+ - Use `size-*` when width and height are equal.
58
+ - Use `truncate` for single-line clipping.
59
+ - Use `cn()` for conditional classes.
60
+ - Do not add manual `z-index` to overlay primitives unless you are fixing a verified stacking bug.
61
+ - Add custom colors as CSS variables in the existing Tailwind CSS file reported by shadcn info. For Tailwind v4, register variables with `@theme inline`.
62
+
63
+ ## Transitions And Motion
64
+
65
+ shadcn's built-in component animations are the right level of polish — keep them. The goal is a snappy, clean UI, not a motionless one. Match shadcn's motion vocabulary; don't strip it and don't pile on decorative custom animation.
66
+
67
+ - **Never remove or override a shadcn component's default animation.** `data-[state=open]:animate-in`, `data-[state=closed]:animate-out`, `fade-in/out`, `zoom-in/out`, `slide-in-from-*`, accordion height, the `tailwindcss-animate` utilities — these ship for a reason. Leave them as-is.
68
+ - **Custom transitions are fine when they communicate a state change and match shadcn's feel.** Reuse the same vocabulary: short durations (~120–200ms), `ease-out`, opacity/transform only, gated on `data-[state=...]`. Examples that are good and welcome:
69
+ - A portaled custom popover/tooltip/sheet that fades + scales/slides in on `data-[state=delayed-open]` / `data-[state=closed]`, mirroring Radix's own content animation.
70
+ - A list row or toast that fades/slides in on mount and out on dismiss.
71
+ - A chevron/caret `rotate` on expand, a subtle `opacity`/`color` hover on an icon button, skeleton shimmer, a progress/height transition on a collapsible.
72
+ - Continuous, product-defining motion where it _is_ the experience (e.g. a multi-stage booking flow's stage transitions) — fine, and framer-motion is acceptable there.
73
+ - **Avoid decorative, attention-seeking, or slow motion:** hand-rolled `duration-700` hero fade-ins, parallax, bouncing/spring entrances on ordinary content, animated gradients, staggered cascades on long lists, anything that delays the user seeing or acting on content. If an animation makes the UI feel slower, cut it.
74
+ - Rule of thumb: if the motion clarifies what just changed and is over in well under a quarter-second, it's polish; if it's there to look impressive, it's bloat.
75
+
76
+ ## Icons
77
+
78
+ - Agent-native apps use `@tabler/icons-react`. Do not add `lucide-react` because a registry example used it.
79
+ - If registry code imports a different icon package, replace those imports with Tabler equivalents before finishing.
80
+ - Let shadcn components size icons through their CSS. Avoid manual icon sizing inside buttons, menus, alerts, and sidebars unless the local component API requires it.
81
+
82
+ ## Base-Specific APIs
83
+
84
+ Check the project context before using trigger composition APIs:
85
+
86
+ - Radix-based components use `asChild` for custom triggers.
87
+ - Base UI components may use `render` and sometimes `nativeButton={false}`.
88
+
89
+ Do not wrap triggers in extra divs just to place a Button or Link inside them.
90
+
91
+ ## Related Skills
92
+
93
+ - **frontend-design** — Product UX, visual direction, responsive polish, and verification
94
+ - **actions** — Data fetching and mutation patterns for agent-native apps
95
+ - **security** — User data, forms, external input, and action safety
@@ -0,0 +1,61 @@
1
+ # /stay-within-limits
2
+
3
+ Keep long-running agent work inside model and account usage windows.
4
+
5
+ `/stay-within-limits` gives coding agents a lightweight budget loop for broad,
6
+ parallel, or multi-hour work. The agent checks current 5-hour and weekly usage,
7
+ runs work in bounded waves, and pauses before it crosses the limit instead of
8
+ burning through the last usable budget mid-task.
9
+
10
+ ## What It Does
11
+
12
+ - Checks 5-hour and weekly usage before substantial work and between waves.
13
+ - Uses waves of at most 3 parallel subagents by default.
14
+ - Pauses new work when either window reaches 95% of its limit.
15
+ - Resumes only after re-checking that the actual window or block is clear.
16
+ - Makes wake prompts self-contained so work can continue after a long pause.
17
+ - Carries the remaining plan, verification steps, and delegation stop
18
+ conditions into the resume prompt.
19
+ - Documents the Claude Code-compatible `ccusage` command while allowing host
20
+ usage tools to take priority.
21
+
22
+ ## When To Use It
23
+
24
+ Use this for long-running coding sessions, PR babysitting, broad reviews,
25
+ multi-wave refactors, large research tasks, or any task where parallel agents
26
+ could exhaust the current 5-hour or weekly budget.
27
+
28
+ Skip it for small one-shot edits where checking budget would add more ceremony
29
+ than value.
30
+
31
+ ## Claude Code Usage Check
32
+
33
+ When Claude Code does not expose a better first-party usage signal, use:
34
+
35
+ ```sh
36
+ npx -y ccusage@latest blocks --active --json
37
+ ```
38
+
39
+ The agent should read the active block start, current usage or cost, and time
40
+ remaining. On wake, it should compare the block start timestamp with the
41
+ previous check rather than trusting elapsed time alone.
42
+
43
+ ## Resume Pattern
44
+
45
+ For hosts with a wake/resume tool, the wake prompt should restate the remaining
46
+ plan, the 95% pause threshold, the wave throttle, the exact usage check, and the
47
+ rule to reschedule if the limit is still too high. If more delegated work
48
+ remains, include the next wave's scope, verification commands, and stop
49
+ conditions so the resumed agent does not depend on old chat momentum.
50
+
51
+ For waits longer than an hour, chain wakeups. For budget pauses, preserving the
52
+ usage window matters more than keeping the prompt cache warm.
53
+
54
+ ## Install
55
+
56
+ ```sh
57
+ npx @agent-native/skills@latest add --skill stay-within-limits --update-instructions
58
+ ```
59
+
60
+ Use `--update-instructions` when you want the 5-hour and weekly limit convention
61
+ added to `AGENTS.md` or `CLAUDE.md` automatically.
@@ -0,0 +1,83 @@
1
+ ---
2
+ name: stay-within-limits
3
+ description: Use when long-running or parallel agent work must respect 5-hour and weekly usage limits by checking usage between waves, pausing near the cap, and resuming only when the window is clear.
4
+ ---
5
+
6
+ # Stay Within Limits
7
+
8
+ Keep long-running agent work inside the current 5-hour and weekly usage windows.
9
+ Check usage before launching substantial work and between waves of parallel
10
+ subagents. If an active 5-hour or weekly limit is at or above 95%, pause new
11
+ work until the window is clear enough to continue safely.
12
+
13
+ ## Core Loop
14
+
15
+ 1. Run a bounded wave of work. Default to at most 3 parallel subagents unless
16
+ the user or host gives a different throttle.
17
+ 2. Wait for the wave to finish. Do not interrupt in-flight subagents just to
18
+ save budget; that usually loses work.
19
+ 3. Check current 5-hour and weekly usage with the host's usage/budget tool.
20
+ 4. If either window is at or above 95%, stop launching work and schedule a
21
+ self-contained resume when the relevant window should clear.
22
+ 5. On resume, re-check the real window or block before continuing. Do not trust
23
+ elapsed wall-clock time alone.
24
+
25
+ ## Usage Signals
26
+
27
+ Prefer a first-party host usage tool when available. In Claude Code, use:
28
+
29
+ ```sh
30
+ npx -y ccusage@latest blocks --active --json
31
+ ```
32
+
33
+ Use the JSON to identify the active block start, current cost or percentage, and
34
+ time remaining. On wake, compare the active block start timestamp with the
35
+ previous one; a new timestamp is stronger evidence than "enough time passed."
36
+
37
+ If the tool reports cost instead of a direct percentage, convert through the
38
+ current account limit when known. For Claude Max-style 5-hour blocks, some users
39
+ prefer an earlier caution threshold around $500-550; treat that as a
40
+ user-configured guardrail, not a universal rule. The default stop rule is still
41
+ 95% of the active 5-hour or weekly limit.
42
+
43
+ ## Pausing And Resuming
44
+
45
+ When a wake/resume tool is available, schedule a wakeup for:
46
+
47
+ ```txt
48
+ min(3600, secondsUntilWindowClears)
49
+ ```
50
+
51
+ If the runtime clamps wake delays to 60-3600 seconds, chain wakeups for longer
52
+ waits. Each wakeup should re-check usage, reschedule if still over budget, and
53
+ continue only when the window is safely below the threshold.
54
+
55
+ Make wake prompts self-contained. Include:
56
+
57
+ - The remaining plan.
58
+ - The check-then-reschedule rule.
59
+ - The 95% threshold and wave throttle.
60
+ - The exact usage command or host usage tool to run.
61
+ - The previous block/window identifier when available.
62
+ - The next verification steps.
63
+ - The next wave's handoff packets, including scope, verification commands, and
64
+ stop conditions, if delegation will resume.
65
+
66
+ ## Choosing The Wait Mechanism
67
+
68
+ - Use a wake/resume tool when the agent needs instructions attached to the
69
+ future resume.
70
+ - Use a background sleep or watcher for fixed timers and things a process can
71
+ observe directly.
72
+ - Use cron or recurring schedules only for recurring fresh-session work.
73
+
74
+ Avoid short-interval polling for things the host will notify you about, such as
75
+ background task or subagent completion. For budget pauses, a prompt-cache miss
76
+ after a long sleep is acceptable; preserving the limit matters more.
77
+
78
+ ## Reporting
79
+
80
+ If you pause, tell the user which window is over threshold, the observed usage,
81
+ when you scheduled or expect the next check, and what work remains. Keep enough
82
+ state in the wake prompt that the next turn can resume without relying on
83
+ conversation momentum.