@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.
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +12 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/cli/templates-meta.ts +13 -0
- package/corpus/core/src/client/agent-page/AgentTabsPage.tsx +1 -1
- package/corpus/core/src/client/org/OrgSwitcher.tsx +2 -0
- package/corpus/templates/analytics/changelog/2026-07-15-fixed-the-agent-discarding-a-successful-dashboard-edit-and-r.md +6 -0
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +30 -1
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +15 -0
- package/corpus/templates/content/actions/_database-source-utils.ts +59 -4
- package/corpus/templates/content/actions/prepare-builder-source-review.ts +9 -0
- package/corpus/templates/content/actions/preview-builder-source-review.ts +6 -4
- package/corpus/templates/content/app/components/editor/DescriptionField.tsx +10 -2
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +4 -0
- package/corpus/templates/content/changelog/2026-07-15-page-and-database-descriptions-now-use-a-clean-single-line-f.md +6 -0
- package/corpus/templates/content/changelog/2026-07-15-selected-builder-reviews-now-load-only-the-chosen-rows-avoid.md +6 -0
- package/corpus/templates/content/shared/api.ts +1 -0
- package/corpus/templates/tasks/.agents/commands/visual-plan.md +9 -0
- package/corpus/templates/tasks/.agents/commands/visual-recap.md +8 -0
- package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +492 -0
- package/corpus/templates/tasks/.agents/skills/adding-a-feature/SKILL.md +189 -0
- package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +76 -0
- package/corpus/templates/tasks/.agents/skills/agent-watchdog/README.md +43 -0
- package/corpus/templates/tasks/.agents/skills/agent-watchdog/SKILL.md +110 -0
- package/corpus/templates/tasks/.agents/skills/agent-watchdog/agents/openai.yaml +4 -0
- package/corpus/templates/tasks/.agents/skills/capture-learnings/SKILL.md +89 -0
- package/corpus/templates/tasks/.agents/skills/change-summary/SKILL.md +83 -0
- package/corpus/templates/tasks/.agents/skills/create-skill/SKILL.md +221 -0
- package/corpus/templates/tasks/.agents/skills/delegate-to-agent/SKILL.md +263 -0
- package/corpus/templates/tasks/.agents/skills/efficient-fable/README.md +75 -0
- package/corpus/templates/tasks/.agents/skills/efficient-fable/SKILL.md +95 -0
- package/corpus/templates/tasks/.agents/skills/efficient-frontier/README.md +53 -0
- package/corpus/templates/tasks/.agents/skills/efficient-frontier/SKILL.md +73 -0
- package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +112 -0
- package/corpus/templates/tasks/.agents/skills/plan-arbiter/README.md +41 -0
- package/corpus/templates/tasks/.agents/skills/plan-arbiter/SKILL.md +114 -0
- package/corpus/templates/tasks/.agents/skills/plan-arbiter/agents/openai.yaml +4 -0
- package/corpus/templates/tasks/.agents/skills/plow-ahead/README.md +42 -0
- package/corpus/templates/tasks/.agents/skills/plow-ahead/SKILL.md +104 -0
- package/corpus/templates/tasks/.agents/skills/plow-ahead/agents/openai.yaml +4 -0
- package/corpus/templates/tasks/.agents/skills/quick-recap/README.md +55 -0
- package/corpus/templates/tasks/.agents/skills/quick-recap/SKILL.md +54 -0
- package/corpus/templates/tasks/.agents/skills/read-the-damn-docs/README.md +54 -0
- package/corpus/templates/tasks/.agents/skills/read-the-damn-docs/SKILL.md +126 -0
- package/corpus/templates/tasks/.agents/skills/read-the-damn-docs/agents/openai.yaml +4 -0
- package/corpus/templates/tasks/.agents/skills/real-time-sync/SKILL.md +232 -0
- package/corpus/templates/tasks/.agents/skills/security/SKILL.md +280 -0
- package/corpus/templates/tasks/.agents/skills/self-modifying-code/SKILL.md +106 -0
- package/corpus/templates/tasks/.agents/skills/shadcn-ui/SKILL.md +95 -0
- package/corpus/templates/tasks/.agents/skills/stay-within-limits/README.md +61 -0
- package/corpus/templates/tasks/.agents/skills/stay-within-limits/SKILL.md +83 -0
- package/corpus/templates/tasks/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/tasks/.agents/skills/visual-plan/SKILL.md +547 -0
- package/corpus/templates/tasks/.agents/skills/visual-plan/agent-native-skill.json +12 -0
- package/corpus/templates/tasks/.agents/skills/visual-plan/references/canvas.md +121 -0
- package/corpus/templates/tasks/.agents/skills/visual-plan/references/document-quality.md +178 -0
- package/corpus/templates/tasks/.agents/skills/visual-plan/references/exemplar.md +62 -0
- package/corpus/templates/tasks/.agents/skills/visual-plan/references/wireframe.md +264 -0
- package/corpus/templates/tasks/.agents/skills/visual-recap/SKILL.md +634 -0
- package/corpus/templates/tasks/.agents/skills/visual-recap/agent-native-skill.json +12 -0
- package/corpus/templates/tasks/.agents/skills/visual-recap/references/wireframe.md +264 -0
- package/corpus/templates/tasks/.claude/commands/visual-plan.md +9 -0
- package/corpus/templates/tasks/.claude/commands/visual-recap.md +8 -0
- package/corpus/templates/tasks/.env.example +5 -0
- package/corpus/templates/tasks/.ignore +0 -0
- package/corpus/templates/tasks/.prettierrc +5 -0
- package/corpus/templates/tasks/AGENTS.md +158 -0
- package/corpus/templates/tasks/DEVELOPING.md +185 -0
- package/corpus/templates/tasks/README.md +16 -0
- package/corpus/templates/tasks/actions/bulk-delete-inbox-items.ts +24 -0
- package/corpus/templates/tasks/actions/bulk-delete-tasks.ts +21 -0
- package/corpus/templates/tasks/actions/bulk-mark-inbox-items-ready.ts +27 -0
- package/corpus/templates/tasks/actions/bulk-update-tasks.ts +35 -0
- package/corpus/templates/tasks/actions/create-custom-field.ts +22 -0
- package/corpus/templates/tasks/actions/create-inbox-item.ts +30 -0
- package/corpus/templates/tasks/actions/create-task.ts +33 -0
- package/corpus/templates/tasks/actions/delete-custom-field.ts +19 -0
- package/corpus/templates/tasks/actions/delete-inbox-item.ts +17 -0
- package/corpus/templates/tasks/actions/delete-task.ts +17 -0
- package/corpus/templates/tasks/actions/lib/boolean-query-param.ts +30 -0
- package/corpus/templates/tasks/actions/list-custom-fields.ts +18 -0
- package/corpus/templates/tasks/actions/list-inbox-items.ts +16 -0
- package/corpus/templates/tasks/actions/list-tasks.ts +52 -0
- package/corpus/templates/tasks/actions/list-visible-task-fields.ts +18 -0
- package/corpus/templates/tasks/actions/mark-inbox-item-ready.ts +31 -0
- package/corpus/templates/tasks/actions/navigate.ts +51 -0
- package/corpus/templates/tasks/actions/reorder-custom-fields.ts +27 -0
- package/corpus/templates/tasks/actions/reorder-inbox-items.ts +24 -0
- package/corpus/templates/tasks/actions/reorder-tasks.ts +29 -0
- package/corpus/templates/tasks/actions/run.ts +2 -0
- package/corpus/templates/tasks/actions/update-custom-field.ts +33 -0
- package/corpus/templates/tasks/actions/update-inbox-item.ts +24 -0
- package/corpus/templates/tasks/actions/update-task.ts +68 -0
- package/corpus/templates/tasks/actions/update-visible-task-fields.ts +27 -0
- package/corpus/templates/tasks/actions/view-screen-helpers.ts +68 -0
- package/corpus/templates/tasks/actions/view-screen.ts +207 -0
- package/corpus/templates/tasks/app/components/custom-fields/FieldCreateBar.tsx +121 -0
- package/corpus/templates/tasks/app/components/custom-fields/FieldListRow.tsx +116 -0
- package/corpus/templates/tasks/app/components/custom-fields/FieldsList.tsx +225 -0
- package/corpus/templates/tasks/app/components/custom-fields/FieldsListSkeleton.tsx +18 -0
- package/corpus/templates/tasks/app/components/custom-fields/FieldsPage.tsx +42 -0
- package/corpus/templates/tasks/app/components/custom-fields/editor/FieldEditorSidebar.tsx +69 -0
- package/corpus/templates/tasks/app/components/custom-fields/editor/FieldTitleSection.tsx +32 -0
- package/corpus/templates/tasks/app/components/custom-fields/editor/config/CurrencyConfigControl.tsx +49 -0
- package/corpus/templates/tasks/app/components/custom-fields/editor/config/FieldConfigControl.tsx +56 -0
- package/corpus/templates/tasks/app/components/custom-fields/editor/config/NumberConfigControl.tsx +52 -0
- package/corpus/templates/tasks/app/components/custom-fields/editor/config/PercentConfigControl.tsx +30 -0
- package/corpus/templates/tasks/app/components/custom-fields/editor/config/SelectConfigControl.tsx +135 -0
- package/corpus/templates/tasks/app/components/custom-fields/editor/config/select-colors.ts +23 -0
- package/corpus/templates/tasks/app/components/custom-fields/editor/config/utils.ts +52 -0
- package/corpus/templates/tasks/app/components/custom-fields/editor/types.ts +7 -0
- package/corpus/templates/tasks/app/components/dnd/SortableItem.tsx +72 -0
- package/corpus/templates/tasks/app/components/dnd/SortableList.tsx +136 -0
- package/corpus/templates/tasks/app/components/dnd/reorder-moving-items.ts +160 -0
- package/corpus/templates/tasks/app/components/dnd/sortable-drag-props.ts +60 -0
- package/corpus/templates/tasks/app/components/inbox/InboxList.tsx +222 -0
- package/corpus/templates/tasks/app/components/inbox/InboxListPage.tsx +39 -0
- package/corpus/templates/tasks/app/components/inbox/InboxListRow.tsx +122 -0
- package/corpus/templates/tasks/app/components/layout/Header.tsx +55 -0
- package/corpus/templates/tasks/app/components/layout/HeaderActions.tsx +84 -0
- package/corpus/templates/tasks/app/components/layout/Layout.tsx +134 -0
- package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +211 -0
- package/corpus/templates/tasks/app/components/shared/AddListItemInput.tsx +57 -0
- package/corpus/templates/tasks/app/components/shared/AlertDialog.tsx +53 -0
- package/corpus/templates/tasks/app/components/shared/BulkDeleteDialog.tsx +76 -0
- package/corpus/templates/tasks/app/components/shared/ChipSelect.tsx +240 -0
- package/corpus/templates/tasks/app/components/shared/DeleteItemDialog.tsx +40 -0
- package/corpus/templates/tasks/app/components/shared/InlineEditable.tsx +166 -0
- package/corpus/templates/tasks/app/components/shared/ListEmptyState.tsx +13 -0
- package/corpus/templates/tasks/app/components/shared/ListErrorMessage.tsx +15 -0
- package/corpus/templates/tasks/app/components/shared/ListViewHeader.tsx +75 -0
- package/corpus/templates/tasks/app/components/shared/PageHeader.tsx +25 -0
- package/corpus/templates/tasks/app/components/shared/RowActionsMenu.tsx +42 -0
- package/corpus/templates/tasks/app/components/shared/SidePanel.tsx +99 -0
- package/corpus/templates/tasks/app/components/shared/dnd/ListRowPreview.tsx +37 -0
- package/corpus/templates/tasks/app/components/shared/list/List.tsx +63 -0
- package/corpus/templates/tasks/app/components/shared/list/ListRow.tsx +159 -0
- package/corpus/templates/tasks/app/components/shared/list/ListRowDragHandle.tsx +52 -0
- package/corpus/templates/tasks/app/components/shared/list/ListSkeletonRows.tsx +11 -0
- package/corpus/templates/tasks/app/components/shared/list/SortableListItemShell.tsx +32 -0
- package/corpus/templates/tasks/app/components/shared/list/types.ts +1 -0
- package/corpus/templates/tasks/app/components/shared/selection/ListSelectionBar.tsx +158 -0
- package/corpus/templates/tasks/app/components/shared/selection/ListSelectionHeaderToggle.tsx +28 -0
- package/corpus/templates/tasks/app/components/shared/selection/ListSelectionToolbar.tsx +81 -0
- package/corpus/templates/tasks/app/components/shared/selection/get-list-row-selection-ui.ts +41 -0
- package/corpus/templates/tasks/app/components/shared/selection/use-list-selection.ts +196 -0
- package/corpus/templates/tasks/app/components/tasks/TaskList.tsx +333 -0
- package/corpus/templates/tasks/app/components/tasks/TaskListHeaderRow.tsx +46 -0
- package/corpus/templates/tasks/app/components/tasks/TaskListPage.tsx +115 -0
- package/corpus/templates/tasks/app/components/tasks/TaskListRow.css +49 -0
- package/corpus/templates/tasks/app/components/tasks/TaskListRow.tsx +307 -0
- package/corpus/templates/tasks/app/components/tasks/fields/TaskFieldsSidebar.tsx +102 -0
- package/corpus/templates/tasks/app/components/tasks/fields/TaskTitleSection.tsx +27 -0
- package/corpus/templates/tasks/app/components/tasks/fields/controls/DateValueControl.tsx +21 -0
- package/corpus/templates/tasks/app/components/tasks/fields/controls/FieldValueControl.tsx +76 -0
- package/corpus/templates/tasks/app/components/tasks/fields/controls/MultiSelectValueControl.tsx +52 -0
- package/corpus/templates/tasks/app/components/tasks/fields/controls/NumberValueControl.tsx +56 -0
- package/corpus/templates/tasks/app/components/tasks/fields/controls/RichTextValueControl.tsx +115 -0
- package/corpus/templates/tasks/app/components/tasks/fields/controls/SingleSelectValueControl.tsx +61 -0
- package/corpus/templates/tasks/app/components/tasks/fields/controls/TextValueControl.tsx +20 -0
- package/corpus/templates/tasks/app/components/tasks/use-task-row-completion-animation.ts +181 -0
- package/corpus/templates/tasks/app/components/ui/accordion.tsx +56 -0
- package/corpus/templates/tasks/app/components/ui/alert-dialog.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/alert.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/aspect-ratio.tsx +5 -0
- package/corpus/templates/tasks/app/components/ui/avatar.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/badge.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/breadcrumb.tsx +115 -0
- package/corpus/templates/tasks/app/components/ui/button.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/calendar.tsx +70 -0
- package/corpus/templates/tasks/app/components/ui/card.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/carousel.tsx +260 -0
- package/corpus/templates/tasks/app/components/ui/chart.tsx +379 -0
- package/corpus/templates/tasks/app/components/ui/checkbox.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/collapsible.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/command.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/context-menu.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/dialog.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/drawer.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/dropdown-menu.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/form.tsx +177 -0
- package/corpus/templates/tasks/app/components/ui/hover-card.tsx +27 -0
- package/corpus/templates/tasks/app/components/ui/input-otp.tsx +69 -0
- package/corpus/templates/tasks/app/components/ui/input.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/label.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/menubar.tsx +254 -0
- package/corpus/templates/tasks/app/components/ui/navigation-menu.tsx +128 -0
- package/corpus/templates/tasks/app/components/ui/pagination.tsx +121 -0
- package/corpus/templates/tasks/app/components/ui/popover.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/progress.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/radio-group.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/resizable.tsx +43 -0
- package/corpus/templates/tasks/app/components/ui/scroll-area.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/select.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/separator.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/sheet.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/sidebar.tsx +782 -0
- package/corpus/templates/tasks/app/components/ui/skeleton.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/slider.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/sonner.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/spinner.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/switch.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/table.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/tabs.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/textarea.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/toast.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/toaster.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/toggle-group.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/toggle.tsx +43 -0
- package/corpus/templates/tasks/app/components/ui/tooltip.tsx +1 -0
- package/corpus/templates/tasks/app/components/ui/use-toast.ts +3 -0
- package/corpus/templates/tasks/app/entry.client.tsx +19 -0
- package/corpus/templates/tasks/app/entry.server.tsx +10 -0
- package/corpus/templates/tasks/app/global.css +93 -0
- package/corpus/templates/tasks/app/hooks/cache.ts +31 -0
- package/corpus/templates/tasks/app/hooks/use-custom-fields.ts +93 -0
- package/corpus/templates/tasks/app/hooks/use-inbox-items.ts +196 -0
- package/corpus/templates/tasks/app/hooks/use-mobile.tsx +21 -0
- package/corpus/templates/tasks/app/hooks/use-navigation-state.ts +40 -0
- package/corpus/templates/tasks/app/hooks/use-tasks.ts +276 -0
- package/corpus/templates/tasks/app/hooks/use-toast.ts +188 -0
- package/corpus/templates/tasks/app/hooks/use-visible-task-fields.ts +140 -0
- package/corpus/templates/tasks/app/lib/app-config.ts +11 -0
- package/corpus/templates/tasks/app/lib/tab-id.ts +1 -0
- package/corpus/templates/tasks/app/lib/utils.ts +1 -0
- package/corpus/templates/tasks/app/root.tsx +130 -0
- package/corpus/templates/tasks/app/routes/_index.tsx +22 -0
- package/corpus/templates/tasks/app/routes/extensions.$id.$slug.tsx +2 -0
- package/corpus/templates/tasks/app/routes/extensions.$id.tsx +11 -0
- package/corpus/templates/tasks/app/routes/extensions._index.tsx +11 -0
- package/corpus/templates/tasks/app/routes/extensions.tsx +5 -0
- package/corpus/templates/tasks/app/routes/fields.tsx +16 -0
- package/corpus/templates/tasks/app/routes/inbox.tsx +16 -0
- package/corpus/templates/tasks/app/routes/tasks.tsx +17 -0
- package/corpus/templates/tasks/app/routes/team.tsx +17 -0
- package/corpus/templates/tasks/app/routes.ts +4 -0
- package/corpus/templates/tasks/app/vite-env.d.ts +6 -0
- package/corpus/templates/tasks/components.json +20 -0
- package/corpus/templates/tasks/data/sync-config.json +1 -0
- package/corpus/templates/tasks/docs/features/README.md +81 -0
- package/corpus/templates/tasks/docs/features/f1-tasks.mdx +67 -0
- package/corpus/templates/tasks/docs/features/f2-custom-fields.mdx +68 -0
- package/corpus/templates/tasks/docs/features/f3-projects.mdx +33 -0
- package/corpus/templates/tasks/docs/features/f4-inbox.mdx +55 -0
- package/corpus/templates/tasks/docs/features/f5-views.mdx +65 -0
- package/corpus/templates/tasks/docs/features/f6-search.mdx +43 -0
- package/corpus/templates/tasks/docs/features/f7-first-run.mdx +66 -0
- package/corpus/templates/tasks/docs/features/f8-chat.mdx +120 -0
- package/corpus/templates/tasks/e2e/global-setup.ts +42 -0
- package/corpus/templates/tasks/e2e/helpers/inbox.ts +71 -0
- package/corpus/templates/tasks/e2e/helpers/tasks.ts +99 -0
- package/corpus/templates/tasks/learnings.defaults.md +5 -0
- package/corpus/templates/tasks/netlify.toml +10 -0
- package/corpus/templates/tasks/package.json +104 -0
- package/corpus/templates/tasks/playwright.config.ts +34 -0
- package/corpus/templates/tasks/public/agent-native-icon-dark.svg +10 -0
- package/corpus/templates/tasks/public/agent-native-icon-light.svg +10 -0
- package/corpus/templates/tasks/public/agent-native-logo-dark.svg +21 -0
- package/corpus/templates/tasks/public/agent-native-logo-light.svg +21 -0
- package/corpus/templates/tasks/public/favicon.svg +1 -0
- package/corpus/templates/tasks/public/icon-180.svg +1 -0
- package/corpus/templates/tasks/public/icon-192.svg +1 -0
- package/corpus/templates/tasks/public/icon-512.svg +1 -0
- package/corpus/templates/tasks/public/manifest.json +21 -0
- package/corpus/templates/tasks/react-router.config.ts +7 -0
- package/corpus/templates/tasks/server/custom-fields/normalize.ts +163 -0
- package/corpus/templates/tasks/server/custom-fields/parse.ts +146 -0
- package/corpus/templates/tasks/server/custom-fields/schema.ts +147 -0
- package/corpus/templates/tasks/server/custom-fields/store.ts +425 -0
- package/corpus/templates/tasks/server/custom-fields/task-fields.ts +104 -0
- package/corpus/templates/tasks/server/custom-fields/types.ts +98 -0
- package/corpus/templates/tasks/server/custom-fields/validate.ts +210 -0
- package/corpus/templates/tasks/server/custom-fields/values/store.ts +386 -0
- package/corpus/templates/tasks/server/db/bulk-write.ts +30 -0
- package/corpus/templates/tasks/server/db/index.ts +5 -0
- package/corpus/templates/tasks/server/db/record-utils.ts +7 -0
- package/corpus/templates/tasks/server/db/schema.ts +67 -0
- package/corpus/templates/tasks/server/db/test-tasks-table.ts +76 -0
- package/corpus/templates/tasks/server/db/transaction.ts +6 -0
- package/corpus/templates/tasks/server/errors.ts +31 -0
- package/corpus/templates/tasks/server/inbox/store.ts +216 -0
- package/corpus/templates/tasks/server/middleware/auth.ts +15 -0
- package/corpus/templates/tasks/server/plugins/agent-chat.ts +46 -0
- package/corpus/templates/tasks/server/plugins/auth.ts +15 -0
- package/corpus/templates/tasks/server/plugins/db.ts +90 -0
- package/corpus/templates/tasks/server/routes/[...page].get.ts +5 -0
- package/corpus/templates/tasks/server/stored-items/store.ts +548 -0
- package/corpus/templates/tasks/server/tasks/store.ts +306 -0
- package/corpus/templates/tasks/server/user-config/store.ts +138 -0
- package/corpus/templates/tasks/shared/app-state-tabs.ts +15 -0
- package/corpus/templates/tasks/shared/boolean-param.ts +22 -0
- package/corpus/templates/tasks/shared/bulk-limits.ts +7 -0
- package/corpus/templates/tasks/shared/list-screen-snapshot.ts +90 -0
- package/corpus/templates/tasks/shared/navigation.ts +104 -0
- package/corpus/templates/tasks/shared/visible-task-fields.ts +2 -0
- package/corpus/templates/tasks/ssr-entry.ts +15 -0
- package/corpus/templates/tasks/tsconfig.json +24 -0
- package/corpus/templates/tasks/vite.config.ts +19 -0
- package/corpus/templates/tasks/vitest.config.ts +8 -0
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +13 -0
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/client/agent-page/AgentTabsPage.js +1 -1
- package/dist/client/agent-page/AgentTabsPage.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +2 -1
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +5 -5
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# HTML wireframe quality — single source of truth
|
|
2
|
+
|
|
3
|
+
This file is the canonical quality bar for HTML wireframes / `<Screen>` /
|
|
4
|
+
`WireframeBlock` content, shared word for word by `/visual-plan` and
|
|
5
|
+
`/visual-recap`. Read it in full before authoring ANY wireframe; do not
|
|
6
|
+
author wireframes from memory or paraphrase these rules per command.
|
|
7
|
+
|
|
8
|
+
<!-- SHARED-CORE:wireframe-quality START -->
|
|
9
|
+
|
|
10
|
+
**A wireframe is an HTML mockup. The renderer owns the look; you write the
|
|
11
|
+
content.** Set `data.html` to a self-contained, semantic HTML fragment of the
|
|
12
|
+
screen and set `data.surface`. The renderer owns the surface footprint/aspect,
|
|
13
|
+
the dark/light theme, the hand-drawn font, and the rough.js sketch overlay — you
|
|
14
|
+
never write `<html>`/`<body>`/`<script>`/`<style>` tags or any
|
|
15
|
+
width/height/coordinates. You write real HTML layout and real product
|
|
16
|
+
content; the renderer styles and roughens it.
|
|
17
|
+
|
|
18
|
+
**A wireframe block's data is an HTML screen plus a surface:**
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"surface": "browser",
|
|
23
|
+
"html": "<div style=\"display:flex;flex-direction:column;gap:10px;padding:16px;height:100%\"><h1>Sign in</h1><p class=\"wf-muted\">Use your work email to continue.</p><div class=\"wf-card\" style=\"display:flex;flex-direction:column;gap:10px\"><label>Email<input value=\"jane@acme.co\" /></label><label>Password<input value=\"••••••••\" /></label><label style=\"display:flex;align-items:center;gap:8px\"><input type=\"checkbox\" checked /> Remember me</label><button class=\"primary\">Sign in</button></div><a href=\"#\">Forgot password?</a></div>"
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Write PLAIN semantic HTML and let the renderer style it.** Bare elements
|
|
28
|
+
(`h1`/`h2`/`h3`, `p`, `button`, `input`, `<input type="checkbox">`, `a`, `hr`)
|
|
29
|
+
are auto-themed — no classes needed. Helper classes carry the rest:
|
|
30
|
+
|
|
31
|
+
- `.wf-card` / `.wf-box` — a bordered, padded container (a panel, a list item).
|
|
32
|
+
- `.wf-pill` / `.wf-chip` — a rounded tag or filter; add `.accent`
|
|
33
|
+
(`<span class="wf-pill accent">`) for the accent-filled variant.
|
|
34
|
+
- `.wf-muted` — secondary/muted text (or use `<small>`).
|
|
35
|
+
- `button.primary` or any element with `[data-primary]` — the accent-filled
|
|
36
|
+
primary button.
|
|
37
|
+
|
|
38
|
+
**No decorative shadows around mockups.** Do not put `box-shadow`, `filter:
|
|
39
|
+
drop-shadow(...)`, Tailwind `shadow-*` classes, or other fake depth effects on a
|
|
40
|
+
wireframe frame, root container, `.wf-card` / `.wf-box`, or canvas artboard.
|
|
41
|
+
Mockups should read as flat, bordered surfaces; use spacing, borders, labels,
|
|
42
|
+
and annotations for separation. Only show a shadow when the real product UI
|
|
43
|
+
already has that shadow and it is essential to the change being reviewed.
|
|
44
|
+
|
|
45
|
+
**Use renderer icons, not visible icon words.** For icon-only buttons or leading
|
|
46
|
+
icons inside fields, chips, menu items, and toolbars, write an empty marker such
|
|
47
|
+
as `<span data-icon="mail" aria-label="Email"></span>` or
|
|
48
|
+
`<i data-icon="lock"></i>`. The renderer replaces it with a Tabler-style SVG and
|
|
49
|
+
the `.wf-icon` class sizes it to the surrounding text. Supported names and
|
|
50
|
+
aliases: `mail`/`email`, `lock`/`password`, `search`, `plus`/`add`, `x`/`close`,
|
|
51
|
+
`check`, `chevronDown`, `chevronUp`, `chevronLeft`, `chevronRight`, `dots`/`more`,
|
|
52
|
+
`chevron`/`caret`/`dropdown` (down chevron), `user`, `settings`, `calendar`,
|
|
53
|
+
`bell`, `send`, `edit`, `arrowLeft`, and `arrowRight`. Do not put visible words
|
|
54
|
+
like "email", "lock", "search", "chevron", or "more" where the product UI would
|
|
55
|
+
show an icon; use text only when it is a real label a user would read.
|
|
56
|
+
|
|
57
|
+
**Use the `--wf-*` tokens for any custom color, never hex.** The renderer flips
|
|
58
|
+
these on light/dark, so reading them is what keeps a mockup correct in both
|
|
59
|
+
themes. For any inline border, background, or text color, reference a token:
|
|
60
|
+
`style="border:1.4px solid var(--wf-line)"`. The tokens are `--wf-ink` (text),
|
|
61
|
+
`--wf-muted` (secondary text), `--wf-line` (borders/dividers), `--wf-paper`
|
|
62
|
+
(page background), `--wf-card` (container surface), `--wf-accent` /
|
|
63
|
+
`--wf-accent-fg` / `--wf-accent-soft` (brand action), `--wf-warn`, `--wf-ok`,
|
|
64
|
+
and `--wf-radius`. Never hard-code a hex color and never set `font-family` — the
|
|
65
|
+
renderer owns the sketch/clean font.
|
|
66
|
+
|
|
67
|
+
**Lay out with inline `style` flex/grid.** You write the real layout —
|
|
68
|
+
`display:flex; flex-direction:column; gap:10px; padding:16px` and so on — and the
|
|
69
|
+
renderer never repositions anything. Compose the actual product: reproduce the
|
|
70
|
+
current screen, then show the modification. Real labels, real counts, real dates,
|
|
71
|
+
real button text grounded in the screen you read; not lorem or gray bars.
|
|
72
|
+
|
|
73
|
+
**Surface presets — match the real footprint, never default to desktop+mobile.**
|
|
74
|
+
Pick the `surface` that matches what the user will actually see:
|
|
75
|
+
|
|
76
|
+
- `browser`: a web page that needs a browser chrome frame around it.
|
|
77
|
+
- `desktop`: a full desktop app page or app shell.
|
|
78
|
+
- `mobile`: a phone screen, only when the work is genuinely mobile.
|
|
79
|
+
- `popover`: a small floating menu, dropdown, or inline popover.
|
|
80
|
+
- `panel`: a side panel, inspector, or sidebar widget.
|
|
81
|
+
|
|
82
|
+
A sidebar popover renders as a small surface, not a desktop page and a phone
|
|
83
|
+
frame. Do not emit `desktop` + `mobile` variants unless responsive behavior
|
|
84
|
+
actually changes the layout. For a component or widget, show one broader
|
|
85
|
+
app-context frame only when placement affects understanding, then the focused
|
|
86
|
+
component states.
|
|
87
|
+
|
|
88
|
+
**Model the actual component shell for small surfaces.** A rendered UI change
|
|
89
|
+
belongs in a wireframe; reserve `diagram` for architecture, dependency, state,
|
|
90
|
+
or data-flow relationships. Popovers, dropdown menus, command palettes, and
|
|
91
|
+
context menus use `surface: "popover"` unless the surrounding page placement is
|
|
92
|
+
the point of the change. Dialogs, sheets, inspectors, sidebars, and long
|
|
93
|
+
property panels use the matching `panel` / `desktop` surface as appropriate.
|
|
94
|
+
Show the real chrome: trigger or anchor when it matters, title/header row,
|
|
95
|
+
top-right actions, separators, fields, options, selected states, body content,
|
|
96
|
+
and footer actions that are visible in the workflow.
|
|
97
|
+
|
|
98
|
+
**Modify, don't redesign.** When the task changes an existing screen, reproduce
|
|
99
|
+
the current screen's real layout and footprint FIRST, then change only the delta
|
|
100
|
+
and call it out with a single annotation. Do not restack the page into a new
|
|
101
|
+
layout. For net-new surfaces, compose from the real app shell. Inspect the
|
|
102
|
+
actual app components before drawing an existing product: sidebar density,
|
|
103
|
+
toolbar actions, overflow menus, property panels, and framework chrome should
|
|
104
|
+
match the product unless the plan intentionally changes them.
|
|
105
|
+
|
|
106
|
+
**Keep product screens pure.** A product wireframe shows the app state a user
|
|
107
|
+
would actually see. Do not embed file contracts, architecture arrows, repo pills,
|
|
108
|
+
mode explanations, or implementation callouts inside the screen just to explain
|
|
109
|
+
the plan. Put those in canvas annotations, a separate diagram, or the document
|
|
110
|
+
body. Secondary UI such as properties, history, sync, export, or agent controls
|
|
111
|
+
should appear where the real product would put them: an overflow popover, sheet,
|
|
112
|
+
panel, or separate framework sidebar state, not a generic permanent right
|
|
113
|
+
inspector unless that inspector is the actual design.
|
|
114
|
+
|
|
115
|
+
**Classify mockup scope before implementation.** Before turning a plan mockup
|
|
116
|
+
into source code, decide whether each artboard represents the whole page/app
|
|
117
|
+
shell, a route body inside an existing shell, or a component/sub-surface. If an
|
|
118
|
+
artboard includes navigation, sidebars, auth banners, or a signup/login form,
|
|
119
|
+
map those pieces to the real shared shell/auth components instead of nesting the
|
|
120
|
+
entire mockup inside the current page. When a mockup references the product's
|
|
121
|
+
standard signup/login page, find and reuse that existing implementation; do not
|
|
122
|
+
approximate it from the wireframe.
|
|
123
|
+
|
|
124
|
+
**Zoom in on sub-surfaces, don't redraw the page.** For a small sub-surface (a
|
|
125
|
+
popover, menu, dialog, toast), show the full screen once, then add a small
|
|
126
|
+
separate artboard whose `html` contains ONLY that sub-surface — do not re-draw
|
|
127
|
+
the whole page around it, and do not scale a duplicate up. Pick the matching
|
|
128
|
+
`surface` (e.g. `popover`) so the footprint is right; never widen a popover to
|
|
129
|
+
page width.
|
|
130
|
+
|
|
131
|
+
**Loading / skeleton states.** Set `data.skeleton: true` on the wireframe and
|
|
132
|
+
fill the `html` with neutral, textless placeholder geometry — boxes and bars
|
|
133
|
+
built as `<div>`s with `background:var(--wf-line)` and explicit heights/widths,
|
|
134
|
+
no labels or copy. The renderer drops borders, sketch, and color into the
|
|
135
|
+
skeleton register automatically. Never escape to a `custom-html` document block
|
|
136
|
+
to fake a loader.
|
|
137
|
+
|
|
138
|
+
**Editing an existing mockup.** In hosted mode, to change one element, text, or
|
|
139
|
+
color in an existing html mockup, do not regenerate the frame — call
|
|
140
|
+
`update-visual-plan` with
|
|
141
|
+
`contentPatches: [{ op: "patch-wireframe-html", blockId, edits: [{ find,
|
|
142
|
+
replace }] }]`. Each `find` is a unique snippet of the current html (read it
|
|
143
|
+
first with `get-visual-plan`); set `all: true` on an edit to replace every
|
|
144
|
+
occurrence. The result is re-sanitized. In local-files privacy mode, do not call
|
|
145
|
+
hosted Plan tools; edit the local MDX source directly and rerun the local
|
|
146
|
+
check/serve or verify command for `<plan-dir>`.
|
|
147
|
+
|
|
148
|
+
**Treat the wireframe border as part of the visible design.** Always wrap HTML
|
|
149
|
+
wireframe content in a root container with real inner padding before drawing
|
|
150
|
+
cards, fields, pills, labels, or controls. Use at least 14-16px of padding,
|
|
151
|
+
`box-sizing: border-box`, `height: 100%`, and `gap` between child rows so the
|
|
152
|
+
first row never sits flush against the screen border. Keep text away from
|
|
153
|
+
borders: every container, field, button, menu item, and annotation needs enough
|
|
154
|
+
padding and line-height to read cleanly in the rendered Plan view.
|
|
155
|
+
|
|
156
|
+
**Lay out children safely so they never collide.** Use HTML flex/grid with
|
|
157
|
+
`gap`, `min-width: 0`, and sensible overflow. Avoid negative margins, absolute
|
|
158
|
+
positioning, or fixed child widths that can collide when the renderer switches
|
|
159
|
+
between light/dark, sketch/clean, or different zoom levels.
|
|
160
|
+
|
|
161
|
+
**Do not wrap intentionally single-line labels.** For toolbars, tab rails,
|
|
162
|
+
breadcrumbs, chip/filter rows, branch and file names, file chips, and code
|
|
163
|
+
filenames — any deliberately single-line row — do not let long text wrap. Put
|
|
164
|
+
`white-space: nowrap` on the row (and `overflow: hidden; text-overflow: ellipsis`
|
|
165
|
+
on the individual labels that can grow), so the wireframe demonstrates the actual
|
|
166
|
+
layout behavior instead of producing ugly stacked or vertical text. Use
|
|
167
|
+
horizontally scrollable or clipped rails for overflow.
|
|
168
|
+
|
|
169
|
+
**Fill the frame; keep labels short.** Each artboard is a fixed-size surface — compose enough realistic HTML to fill it top to bottom with even vertical rhythm; never leave a large empty band. On desktop/app-shell sidebars, let the nav stack flex to fill (`flex:1`) and add any persistent bottom action/status after it so the rail reads complete in taller frames. On mobile especially, flow real rows down the whole screen (status bar, header, then list/detail content) rather than a header floating above a gap. Keep every label short enough to sit on one line within its column — shorten the copy rather than relying on the frame to absorb it (long labels wrap or clip).
|
|
170
|
+
|
|
171
|
+
**Persistent chrome bars span the full frame width.** Top bars, app headers,
|
|
172
|
+
toolbars, and bottom tab/nav bars are full-width chrome, not centered content.
|
|
173
|
+
Lay each one out as a single flex row that fills the frame
|
|
174
|
+
(`style="display:flex;align-items:center;width:100%"`) and push trailing actions
|
|
175
|
+
to the right edge with a flex spacer (`<div style="flex:1"></div>`) between the
|
|
176
|
+
leading group and the trailing group — never center a bar inside a narrow,
|
|
177
|
+
centered block, and never let it collapse to the width of its contents. In a
|
|
178
|
+
Before/After pair the bar stays full-width in BOTH states even when one state has
|
|
179
|
+
fewer controls; the spacer absorbs the difference so the remaining controls hold
|
|
180
|
+
their edge alignment instead of sliding to the center.
|
|
181
|
+
|
|
182
|
+
**Pin bottom bars to the bottom of the frame.** For mobile tab bars, footers, and
|
|
183
|
+
any persistent bottom action row, make the frame itself a flex column at
|
|
184
|
+
`height:100%` (`style="display:flex;flex-direction:column;height:100%"`), give the
|
|
185
|
+
scrolling body `flex:1` so it absorbs the slack, and place the bar as the LAST
|
|
186
|
+
child of the frame (or set `margin-top:auto` on it). The bar then sits flush at
|
|
187
|
+
the bottom of the surface instead of floating directly under the content with an
|
|
188
|
+
empty band beneath it.
|
|
189
|
+
|
|
190
|
+
**Before / after must be comparable.** When showing a state change, preserve the
|
|
191
|
+
unchanged controls in both states so the reviewer can see exactly what moved or
|
|
192
|
+
appeared; do not show an added control as a generic box floating elsewhere in
|
|
193
|
+
the surface. Place the new/changed affordance where the implementation puts it —
|
|
194
|
+
for example, a new `Edit with AI` action in a popover header belongs in the
|
|
195
|
+
top-right header slot, aligned with the title, not in the body or footer. Use
|
|
196
|
+
the same frame size, scale, outer padding, border radius, and visual density on
|
|
197
|
+
both sides unless the change itself alters those properties, and let the frame
|
|
198
|
+
height fit the content rather than leaving a tall empty lower half.
|
|
199
|
+
|
|
200
|
+
**Name the states with the column header, never inside the frame.** For
|
|
201
|
+
document-body wireframes (recaps), put the two
|
|
202
|
+
states in a `columns` block and set each column's `label` to `Before` and
|
|
203
|
+
`After` — the renderer draws that label as an `h4` heading above each frame. Do
|
|
204
|
+
NOT bake a `Before`/`After` pill, title, or heading into the wireframe `html`: a
|
|
205
|
+
label placed inside reads as part of the product UI, lands in a random corner,
|
|
206
|
+
and clutters the comparison. The column header is the one and only place the
|
|
207
|
+
state name belongs. On a canvas, place the two state artboards as neighbors with
|
|
208
|
+
frame labels — never encode Before/After inside the html.
|
|
209
|
+
|
|
210
|
+
**Let the surface choose side-by-side vs. stacked.** For document-body
|
|
211
|
+
wireframes (recaps), the `columns` renderer lays
|
|
212
|
+
narrow surfaces (`mobile`, `popover`, `panel`) out side by side, and
|
|
213
|
+
automatically stacks wide surfaces (`desktop`, `browser`) vertically at full
|
|
214
|
+
document width so a large frame is never crushed into a half-width column and
|
|
215
|
+
cropped. Author both wireframes with the real `surface` and the matching
|
|
216
|
+
`Before`/`After` column labels; do not hand-stack the pair into separate
|
|
217
|
+
top-level wireframes or duplicate the state name as body content.
|
|
218
|
+
|
|
219
|
+
**Good example — a contacts list, surface `browser`.** A small, real screen
|
|
220
|
+
composed from the helper classes and tokens, layout in inline flex, no fonts or
|
|
221
|
+
hex colors:
|
|
222
|
+
|
|
223
|
+
```html
|
|
224
|
+
<div
|
|
225
|
+
style="display:flex;flex-direction:column;gap:12px;padding:16px;height:100%"
|
|
226
|
+
>
|
|
227
|
+
<div style="display:flex;align-items:center;justify-content:space-between">
|
|
228
|
+
<h1>Contacts</h1>
|
|
229
|
+
<button class="primary">New contact</button>
|
|
230
|
+
</div>
|
|
231
|
+
<div style="display:flex;gap:6px">
|
|
232
|
+
<span class="wf-pill accent">All 128</span>
|
|
233
|
+
<span class="wf-pill">Favorites</span>
|
|
234
|
+
<span class="wf-pill">Archived</span>
|
|
235
|
+
</div>
|
|
236
|
+
<div
|
|
237
|
+
class="wf-card"
|
|
238
|
+
style="display:flex;flex-direction:column;gap:0;padding:0"
|
|
239
|
+
>
|
|
240
|
+
<div
|
|
241
|
+
style="display:flex;align-items:center;gap:10px;padding:10px 12px;border-bottom:1.4px solid var(--wf-line)"
|
|
242
|
+
>
|
|
243
|
+
<div
|
|
244
|
+
style="width:32px;height:32px;border-radius:999px;background:var(--wf-accent-soft)"
|
|
245
|
+
></div>
|
|
246
|
+
<div style="flex:1">
|
|
247
|
+
<strong>Jane Cooper</strong><br /><small>jane@acme.co</small>
|
|
248
|
+
</div>
|
|
249
|
+
<span class="wf-pill">Lead</span>
|
|
250
|
+
</div>
|
|
251
|
+
<div style="display:flex;align-items:center;gap:10px;padding:10px 12px">
|
|
252
|
+
<div
|
|
253
|
+
style="width:32px;height:32px;border-radius:999px;background:var(--wf-accent-soft)"
|
|
254
|
+
></div>
|
|
255
|
+
<div style="flex:1">
|
|
256
|
+
<strong>Marcus Lee</strong><br /><small>marcus@globex.io</small>
|
|
257
|
+
</div>
|
|
258
|
+
<span class="wf-pill">Customer</span>
|
|
259
|
+
</div>
|
|
260
|
+
</div>
|
|
261
|
+
</div>
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
<!-- SHARED-CORE:wireframe-quality END -->
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create an interactive Agent-Native visual plan for the current task.
|
|
3
|
+
argument-hint: [optional request or scope]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Use the visual-plan skill for this task. Treat any arguments as the user's
|
|
7
|
+
requested plan scope or focus:
|
|
8
|
+
|
|
9
|
+
$ARGUMENTS
|
|
File without changes
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# tasks — Agent Guide
|
|
2
|
+
|
|
3
|
+
Tasks is a task-list-first agent-native app. The task list at `/tasks` is the default home; chat stays available for capture and agent operations. Actions are the contract shared by UI, chat, HTTP, MCP, A2A, and CLI.
|
|
4
|
+
|
|
5
|
+
## Core Rules
|
|
6
|
+
|
|
7
|
+
- Never hardcode API keys, tokens, webhook URLs, signing secrets, private Builder/internal data, customer data, or credential-looking literals. Use secrets/OAuth/runtime configuration and obvious placeholders in examples.
|
|
8
|
+
- Follow the root framework contract: data in SQL, actions first, application state for navigation/selection, and shared agent chat for AI work.
|
|
9
|
+
- Use actions for app operations and keep frontend/API parity.
|
|
10
|
+
- Prefer improving the action surface before adding new pages. The task list is the primary durable UI for MVP.
|
|
11
|
+
- Keep the action surface small: task CRUD actions plus `reorder-tasks`, `view-screen`, and `navigate`.
|
|
12
|
+
- Do not use `db-query` for normal task operations.
|
|
13
|
+
- Call `view-screen` first when the user's visible task context matters (especially on `/tasks`).
|
|
14
|
+
|
|
15
|
+
## Actions
|
|
16
|
+
|
|
17
|
+
| Action | Method | Purpose |
|
|
18
|
+
| ---------------------------- | ------ | -------------------------------------------------------------------------------------------- |
|
|
19
|
+
| `list-tasks` | GET | List current user's tasks; `includeDone` and `includeFields` default to false |
|
|
20
|
+
| `create-task` | POST | Create a task with `title` |
|
|
21
|
+
| `update-task` | POST | Patch `title`, `done`, and/or `fieldValues` by `taskId` |
|
|
22
|
+
| `delete-task` | POST | Delete a task by `taskId` (confirm with user first) |
|
|
23
|
+
| `bulk-update-tasks` | POST | Patch `title` and/or `done` on multiple tasks by id |
|
|
24
|
+
| `bulk-delete-tasks` | POST | Delete multiple tasks by id (confirm with user first) |
|
|
25
|
+
| `reorder-tasks` | POST | Reorder visible tasks by id list top-to-bottom |
|
|
26
|
+
| `list-inbox-items` | GET | List current user's inbox items |
|
|
27
|
+
| `create-inbox-item` | POST | Create a not-ready inbox item with `title` (default chat capture) |
|
|
28
|
+
| `update-inbox-item` | POST | Patch inbox item `title` by `inboxItemId` |
|
|
29
|
+
| `delete-inbox-item` | POST | Delete an inbox item (confirm with user first) |
|
|
30
|
+
| `mark-inbox-item-ready` | POST | Promote inbox item to an incomplete task |
|
|
31
|
+
| `reorder-inbox-items` | POST | Reorder inbox items by id list top-to-bottom |
|
|
32
|
+
| `list-custom-fields` | GET | List custom field definitions |
|
|
33
|
+
| `create-custom-field` | POST | Create a custom field definition with `title`, `type`, and optional `config` |
|
|
34
|
+
| `update-custom-field` | POST | Patch a field definition `title` and/or type-compatible `config`; type is immutable |
|
|
35
|
+
| `delete-custom-field` | POST | Delete a field definition and its values on every task (confirm with user first) |
|
|
36
|
+
| `reorder-custom-fields` | POST | Reorder custom field definitions by id list top-to-bottom |
|
|
37
|
+
| `list-visible-task-fields` | GET | List custom field ids shown on task cards for the current user |
|
|
38
|
+
| `update-visible-task-fields` | POST | Replace which custom fields appear on task cards (max 3) |
|
|
39
|
+
| `view-screen` | — | Read navigation, UI bulk selection, visible tasks, and inbox snapshot |
|
|
40
|
+
| `navigate` | — | Move UI to a view: `tasks`, `inbox`, `fields`, `extensions`, `team` (`home`/`ask` → `tasks`) |
|
|
41
|
+
|
|
42
|
+
## Store Functions And Transactions
|
|
43
|
+
|
|
44
|
+
Every store in `server/**/store.ts` exposes full CRUD for its entity: `create`,
|
|
45
|
+
`get` + `list`, `update`, `delete`. Naming follows three rules:
|
|
46
|
+
|
|
47
|
+
- **Unsuffixed means "by ids."** `deleteCustomFieldValues({ ids })` deletes by
|
|
48
|
+
value id. Any other selector is explicit: `deleteCustomFieldValuesByTaskIds`,
|
|
49
|
+
`deleteCustomFieldValuesByFieldIds`, `updateCustomFieldValuesByTaskId`.
|
|
50
|
+
- **The plural is the implementation; the singular delegates to it** with a
|
|
51
|
+
one-element id list. `deleteTask` calls `deleteTasks`, `updateCustomFieldValue`
|
|
52
|
+
calls `updateCustomFieldValues`. Never write the same query twice.
|
|
53
|
+
- **`list` takes every selector as optional** rather than splitting into `ByX`
|
|
54
|
+
variants — `listStoredItems({ ids?, includeDone? })`,
|
|
55
|
+
`listCustomFieldValues({ ids?, taskIds?, fieldIds? })`.
|
|
56
|
+
|
|
57
|
+
Where a patch is genuinely per-row (custom field title/config, a task's field
|
|
58
|
+
values), the bulk form takes one entry per id instead of one patch across ids.
|
|
59
|
+
Upsert counts as create; do not add a separate `create` for upserted rows.
|
|
60
|
+
|
|
61
|
+
Action names are a separate public surface and do not follow this convention:
|
|
62
|
+
the `bulk-delete-tasks` action still exists and calls `deleteTasks`.
|
|
63
|
+
|
|
64
|
+
Every function takes the database handle as an **optional trailing argument**,
|
|
65
|
+
so it runs standalone or joins a caller's transaction. The handle is defined
|
|
66
|
+
once, in `server/db/transaction.ts`:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
export type DbHandle = Pick<
|
|
70
|
+
ReturnType<typeof getDb>,
|
|
71
|
+
"select" | "insert" | "update" | "delete" | "transaction"
|
|
72
|
+
>;
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Commit Message Conventions
|
|
76
|
+
|
|
77
|
+
- Never include `Made-with: Cursor` in commit messages. Remove it if it appears
|
|
78
|
+
in a generated message.
|
|
79
|
+
- Use one of these prefixes:
|
|
80
|
+
- `feature: ...` or `feature(PROJECT): ...`
|
|
81
|
+
- `fix: ...` or `fix(PROJECT): ...`
|
|
82
|
+
- `refactor: ...` or `refactor(PROJECT): ...`
|
|
83
|
+
- `technical: ...` or `technical(PROJECT): ...`
|
|
84
|
+
- `chore: ...` or `chore(PROJECT): ...`
|
|
85
|
+
- `PROJECT` is optional. If provided, it must be one of `generator` or `web`.
|
|
86
|
+
- Before creating any commit, always:
|
|
87
|
+
- ask for confirmation,
|
|
88
|
+
- show the proposed commit message first,
|
|
89
|
+
- commit only after explicit user approval.
|
|
90
|
+
|
|
91
|
+
## Commit Message Conventions
|
|
92
|
+
|
|
93
|
+
- Never include `Made-with: Cursor` in commit messages. Remove it if it appears
|
|
94
|
+
in a generated message.
|
|
95
|
+
- Use one of these prefixes:
|
|
96
|
+
- `feature: ...` or `feature(PROJECT): ...`
|
|
97
|
+
- `fix: ...` or `fix(PROJECT): ...`
|
|
98
|
+
- `refactor: ...` or `refactor(PROJECT): ...`
|
|
99
|
+
- `technical: ...` or `technical(PROJECT): ...`
|
|
100
|
+
- `chore: ...` or `chore(PROJECT): ...`
|
|
101
|
+
- `PROJECT` is optional. If provided, it must be one of `generator` or `web`.
|
|
102
|
+
- Before creating any commit, always:
|
|
103
|
+
- ask for confirmation,
|
|
104
|
+
- show the proposed commit message first,
|
|
105
|
+
- commit only after explicit user approval.
|
|
106
|
+
|
|
107
|
+
## Application State
|
|
108
|
+
|
|
109
|
+
Default navigation shape on `/tasks`:
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"view": "tasks",
|
|
114
|
+
"path": "/tasks",
|
|
115
|
+
"includeDone": false,
|
|
116
|
+
"taskId": "optional-selected-id",
|
|
117
|
+
"fieldId": "optional-selected-field-id"
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
- `includeDone` mirrors the task-list filter toggle (incomplete only vs show all).
|
|
122
|
+
- `taskId` highlights a row when opened from a deep link; MVP has no detail page.
|
|
123
|
+
- `fieldId` highlights a custom field when opened from a deep link; the Fields page manages definitions.
|
|
124
|
+
- Chat lives at `/chat`. Root `/` redirects to `/tasks`.
|
|
125
|
+
|
|
126
|
+
## Agent behavior (MVP)
|
|
127
|
+
|
|
128
|
+
- Capture in chat → `create-inbox-item` by default; use `create-task` only when the user asks to add directly to the task list.
|
|
129
|
+
- Call `view-screen` before ambiguous edits when the user says "this task", "these tasks", "this inbox item", or "the list".
|
|
130
|
+
- On `/tasks` or `/inbox`, `view-screen` returns `list` (with `items`), optional `selectedItem` (`inListSnapshot`), and optional `selection` (`selectedItems`, `selectedIdsNotInVisibleList`) when bulk-select is active.
|
|
131
|
+
- Prefer `selection.selectedItems` when the user has UI rows selected; fall back to `selectedItem` for a single deep-link highlight.
|
|
132
|
+
- `delete-task`, `bulk-delete-tasks`, and `delete-inbox-item` only after explicit user confirmation in chat.
|
|
133
|
+
- Use `navigation.includeDone` and `list` from `view-screen` to match what the user sees on `/tasks`.
|
|
134
|
+
- Use `reorder-tasks` with the same `includeDone` flag when moving tasks in the visible list.
|
|
135
|
+
- Use `list-custom-fields`, `create-custom-field`, `update-custom-field`, and `delete-custom-field` for field definitions.
|
|
136
|
+
- Use `reorder-custom-fields` with every field id in the desired order when moving fields in the Fields list.
|
|
137
|
+
- Use `list-visible-task-fields` and `update-visible-task-fields` to read or change which fields appear on task cards (max 3, persisted per user in SQL).
|
|
138
|
+
- Use `list-tasks` with `includeFields` to read per-task custom values and `update-task` with `fieldValues` to set or clear them; empty values clear the stored row.
|
|
139
|
+
- On `/tasks`, `view-screen` includes `visibleTaskFields` from stored prefs for the custom fields currently shown on task cards and `selectedTaskFields` for a highlighted task.
|
|
140
|
+
- On `/fields`, `view-screen` returns the field-definition list and `selectedItem` when a field is highlighted.
|
|
141
|
+
- Custom field types are `text`, `rich_text`, `number`, `percent`, `currency`, `single_select`, `multi_select`, and `date`.
|
|
142
|
+
- Number, percent, and currency field `precision` limits decimal places; `precision: 0` means whole numbers only. Number fields also support optional `positiveOnly`.
|
|
143
|
+
- Select option colors are named tokens: `red`, `orange`, `yellow`, `green`, `blue`, `purple`, `pink`, and `gray`.
|
|
144
|
+
- `delete-custom-field` only after explicit user confirmation; warn that deleting the definition removes its values on every task.
|
|
145
|
+
- After code changes, include the **Change summary** from the `change-summary` skill (Code / Tests / Config / Docs with line counts).
|
|
146
|
+
|
|
147
|
+
## Skills
|
|
148
|
+
|
|
149
|
+
Read the relevant root skill before implementation: `adding-a-feature`, `actions`, `agent-native-docs`, `change-summary`, `storing-data`, `real-time-sync`, `security`, `delegate-to-agent`, `frontend-design`, `shadcn-ui`, and `self-modifying-code`.
|
|
150
|
+
|
|
151
|
+
<!-- BEGIN @agent-native/skills -->
|
|
152
|
+
|
|
153
|
+
When operating as Claude Fable, use the /efficient-fable skill always.
|
|
154
|
+
When using a high-cost frontier model for codebase-heavy work, use the /efficient-frontier skill always.
|
|
155
|
+
When writing final response status indicators, use the /quick-recap skill always.
|
|
156
|
+
When long-running or parallel work needs usage-limit checks, use the /stay-within-limits skill always.
|
|
157
|
+
|
|
158
|
+
<!-- END @agent-native/skills -->
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# tasks — Development Guide
|
|
2
|
+
|
|
3
|
+
This guide is for development-mode agents editing this app's source code. For app operations and tools, see AGENTS.md.
|
|
4
|
+
|
|
5
|
+
## Tech Stack
|
|
6
|
+
|
|
7
|
+
- **Framework:** @agent-native/core + React Router v7 (framework mode)
|
|
8
|
+
- **Frontend:** React 18, Vite, TailwindCSS, shadcn/ui
|
|
9
|
+
- **Routing:** File-based via `flatRoutes()` — SSR shell + client rendering
|
|
10
|
+
- **Backend:** Nitro (via @agent-native/core) — file-based API routing, server plugins, deploy-anywhere presets
|
|
11
|
+
- **State:** SQL-backed (SSE for real-time updates)
|
|
12
|
+
|
|
13
|
+
## Commands
|
|
14
|
+
|
|
15
|
+
- **Dev:** `pnpm dev` (Vite dev server with both React Router + Nitro plugins)
|
|
16
|
+
- **Build:** `pnpm build` (React Router build — client + SSR + Nitro server)
|
|
17
|
+
- **Start:** `node .output/server/index.mjs` (production)
|
|
18
|
+
|
|
19
|
+
## Directory Structure
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
app/ # React frontend
|
|
23
|
+
root.tsx # HTML shell + global providers
|
|
24
|
+
entry.client.tsx # Client hydration entry
|
|
25
|
+
routes.ts # Route config — flatRoutes()
|
|
26
|
+
routes/ # File-based page routes (auto-discovered)
|
|
27
|
+
_index.tsx # / (chat page)
|
|
28
|
+
components/ # UI components
|
|
29
|
+
hooks/ # React hooks
|
|
30
|
+
lib/ # Utilities (cn, etc)
|
|
31
|
+
|
|
32
|
+
server/ # Nitro API server
|
|
33
|
+
routes/
|
|
34
|
+
api/ # Route-only endpoints (uploads, webhooks, OAuth, streaming)
|
|
35
|
+
[...page].get.ts # SSR catch-all (delegates to React Router)
|
|
36
|
+
plugins/ # Server plugins (startup logic)
|
|
37
|
+
lib/ # Shared server modules
|
|
38
|
+
|
|
39
|
+
shared/ # Isomorphic code (imported by both client & server)
|
|
40
|
+
|
|
41
|
+
actions/ # Shared app operations (defineAction; UI uses action hooks)
|
|
42
|
+
run.ts # Script dispatcher
|
|
43
|
+
*.ts # Individual actions (pnpm action <name>)
|
|
44
|
+
|
|
45
|
+
data/ # Local development database fallback
|
|
46
|
+
|
|
47
|
+
react-router.config.ts # React Router framework config
|
|
48
|
+
.agents/skills/ # Agent skills — detailed guidance for each rule
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Framework Basics
|
|
52
|
+
|
|
53
|
+
**SSR-first framework, CSR-by-default content:** This app uses React Router v7 framework mode with `ssr: true`. But virtually every route renders only an SSR shell (loading spinner + meta tags). Normal app data fetching happens on the client via action hooks. Server-side data fetching is the exception — only used for public pages that need SEO/OG tags.
|
|
54
|
+
|
|
55
|
+
## Chat-First Shape
|
|
56
|
+
|
|
57
|
+
The `/` route is the app's primary chat surface. Keep it on
|
|
58
|
+
`AgentChatSurface` unless you are intentionally replacing the whole chat
|
|
59
|
+
experience. The left sidebar owns the durable thread list through
|
|
60
|
+
`useChatThreads`; app-specific screens can be added alongside it as nav items
|
|
61
|
+
when they become useful.
|
|
62
|
+
|
|
63
|
+
For a headless app that later needs UI, this template is the intended landing
|
|
64
|
+
zone: bring the existing actions over, keep their names stable, and let the chat
|
|
65
|
+
call them before adding extra screens. For a custom agent backend, keep the app
|
|
66
|
+
shell and swap the chat runtime with an `AgentChatRuntime` connector instead of
|
|
67
|
+
rewriting the composer/transcript UI.
|
|
68
|
+
|
|
69
|
+
## Adding a Page
|
|
70
|
+
|
|
71
|
+
Create a file in `app/routes/`. The filename determines the URL path:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
app/routes/_index.tsx → /
|
|
75
|
+
app/routes/settings.tsx → /settings
|
|
76
|
+
app/routes/inbox.tsx → /inbox
|
|
77
|
+
app/routes/inbox.$threadId.tsx → /inbox/:threadId
|
|
78
|
+
app/routes/$id.tsx → /:id (dynamic param)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Each route file exports a default component, optional `meta()`, and optional `HydrateFallback()`:
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
import MyPage from "@/pages/MyPage";
|
|
85
|
+
|
|
86
|
+
export function meta() {
|
|
87
|
+
return [{ title: "My Page" }];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function HydrateFallback() {
|
|
91
|
+
return (
|
|
92
|
+
<div className="flex items-center justify-center h-screen">
|
|
93
|
+
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-foreground" />
|
|
94
|
+
</div>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export default function MyPageRoute() {
|
|
99
|
+
return <MyPage />;
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Do NOT fetch data server-side** in route loaders unless the page genuinely needs SEO/OG content. The standard pattern is: SSR renders the shell, client hydrates, and React reads/writes normal app data through actions with `useActionQuery` / `useActionMutation`.
|
|
104
|
+
|
|
105
|
+
## Adding App Data
|
|
106
|
+
|
|
107
|
+
Normal app data starts as an action, not a custom route. Add `actions/<verb>-<resource>.ts` with `defineAction`, mark reads with `http: { method: "GET" }`, and call reads/writes from React with `useActionQuery` / `useActionMutation` from `@agent-native/core/client`. This keeps the UI and agent on one contract and lets mutating actions refresh action-backed queries automatically.
|
|
108
|
+
|
|
109
|
+
## Adding a Route-Only Endpoint
|
|
110
|
+
|
|
111
|
+
Use `server/routes/api/` only for protocols that cannot be modeled as JSON actions: multipart uploads, streaming/SSE/WebSocket, webhooks, OAuth callbacks/redirects, public SEO/OG endpoints, or binary/static asset serving. Do not add `/api/*` routes for normal CRUD, data queries, or pass-through wrappers around actions; the action endpoint already exists at `/_agent-native/actions/:name`.
|
|
112
|
+
|
|
113
|
+
Each route-only endpoint still exports a default `defineEventHandler`, but keep shared app logic in actions or server libraries so agent and UI behavior do not fork.
|
|
114
|
+
|
|
115
|
+
## Adding a Server Plugin
|
|
116
|
+
|
|
117
|
+
Startup logic (auth, SSE, etc.) lives in `server/plugins/`. Use `defineNitroPlugin` from core:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
import { defineNitroPlugin } from "@agent-native/core";
|
|
121
|
+
|
|
122
|
+
export default defineNitroPlugin(async (nitroApp) => {
|
|
123
|
+
// Runs once at server startup
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Key Imports from `@agent-native/core`
|
|
128
|
+
|
|
129
|
+
| Import | Purpose |
|
|
130
|
+
| -------------------------------------------- | -------------------------------------------------------------------------- |
|
|
131
|
+
| `defineNitroPlugin` | Define a server plugin (re-exported from Nitro) |
|
|
132
|
+
| `createDefaultSSEHandler` | Create SSE endpoint for DB change events (server) |
|
|
133
|
+
| `readAppState`, `writeAppState` | Read/write application state (from `@agent-native/core/application-state`) |
|
|
134
|
+
| `readSetting`, `writeSetting` | Read/write settings (from `@agent-native/core/settings`) |
|
|
135
|
+
| `defineEventHandler`, `readBody`, `getQuery` | H3 route handler utilities (re-exported) |
|
|
136
|
+
| `sendToAgentChat` | Send messages to agent from UI (client-side) |
|
|
137
|
+
| `agentChat` | Send messages to agent from scripts (server-side) |
|
|
138
|
+
|
|
139
|
+
## Adding an Action
|
|
140
|
+
|
|
141
|
+
Create `actions/<verb>-<resource>.ts` with `defineAction`. Run with `pnpm action <name> --id value`; React callers should use `useActionQuery` for GET actions and `useActionMutation` for mutating actions, not a matching `/api/*` wrapper.
|
|
142
|
+
|
|
143
|
+
**Sending to agent chat from UI:**
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
import { sendToAgentChat } from "@agent-native/core/client";
|
|
147
|
+
sendToAgentChat({
|
|
148
|
+
message: "Generate something",
|
|
149
|
+
context: "...",
|
|
150
|
+
submit: true,
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Sending to agent chat from scripts:**
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
import { agentChat } from "@agent-native/core";
|
|
158
|
+
agentChat.submit("Generate something");
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Database & Environment Variables
|
|
162
|
+
|
|
163
|
+
Local development defaults to a SQLite file at `data/app.db`. That local file is for development; containers, previews, and serverless deploys can reset their filesystem. For production/cloud deployment, set `DATABASE_URL` to point to a persistent SQL database. Turso is optional, not required; common choices include Neon, Supabase, Turso/libSQL, plain Postgres, durable SQLite, D1 bindings, and Builder.io-managed environments when available.
|
|
164
|
+
|
|
165
|
+
Real credential values belong only in local `.env` files, deployment configuration, or registered secrets/settings UI. Never commit, document, log, return, paste, or include real keys, tokens, webhook URLs, signing secrets, or private data in examples; use empty values or obvious placeholders.
|
|
166
|
+
|
|
167
|
+
When adding app data, define tables with `@agent-native/core/db/schema` helpers and use Drizzle's query builder for reads/writes. Do not import dialect-specific schema helpers from `drizzle-orm/sqlite-core` or `drizzle-orm/pg-core`, and do not write raw SQL in normal actions or handlers when Drizzle can express the query. Raw SQL belongs in additive migrations, health checks, or carefully scoped maintenance.
|
|
168
|
+
|
|
169
|
+
| Variable | Required | Description |
|
|
170
|
+
| --------------------- | ------------------------------- | -------------------------------------------------------------------------- |
|
|
171
|
+
| `DATABASE_URL` | Production yes, local dev no | Persistent SQL connection string (local dev default: `file:./data/app.db`) |
|
|
172
|
+
| `DATABASE_AUTH_TOKEN` | Only when the provider needs it | Auth token for providers such as Turso/libSQL |
|
|
173
|
+
| `AUTH_DISABLED` | Optional | Set to `true` or `1` to skip login/signup (local dev/preview only) |
|
|
174
|
+
|
|
175
|
+
## Extensions (Framework Feature)
|
|
176
|
+
|
|
177
|
+
The framework provides **Extensions** — mini sandboxed Alpine.js apps that run inside iframes. Extensions let users (or the agent) create interactive widgets, dashboards, and utilities without modifying the app's source code. They appear in the sidebar under an "Extensions" section. (Distinct from LLM tools — the function-calling primitives the agent invokes.)
|
|
178
|
+
|
|
179
|
+
- **Creating extensions**: Via the sidebar "+" button, agent chat, or `POST /_agent-native/extensions`
|
|
180
|
+
- **API calls**: Extensions use `extensionFetch()` (legacy alias `toolFetch`) which proxies requests through the server with `${keys.NAME}` secret injection
|
|
181
|
+
- **Styling**: Extensions inherit the main app's Tailwind v4 theme automatically
|
|
182
|
+
- **Sharing**: Private by default, shareable with org or specific users (same model as other ownable resources)
|
|
183
|
+
- **Security**: Iframe sandbox + CSP + SSRF protection on the proxy
|
|
184
|
+
|
|
185
|
+
See the `extensions` skill in `.agents/skills/extensions/SKILL.md` for full implementation details.
|