@agent-native/core 0.123.0 → 0.123.2
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 +24 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/cli/templates-meta.ts +12 -0
- package/corpus/core/src/deploy/build.ts +8 -0
- package/corpus/core/src/server/builder-browser.ts +76 -0
- package/corpus/core/src/server/core-routes-plugin.ts +15 -5
- package/corpus/templates/assets/app/global.css +0 -4
- package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +195 -167
- package/corpus/templates/assets/changelog/2026-07-23-drafts-preview-panel-now-fills-the-full-width-with-a-large-p.md +6 -0
- package/corpus/templates/content/actions/_builder-cms-source-adapter.ts +1 -0
- package/corpus/templates/content/actions/_builder-cms-write-client.ts +55 -9
- package/corpus/templates/content/actions/_database-source-utils.ts +756 -182
- package/corpus/templates/content/actions/change-content-database-source-role.ts +21 -20
- package/corpus/templates/content/actions/execute-builder-source-execution.ts +49 -8
- package/corpus/templates/content/actions/materialize-builder-required-fields.ts +42 -9
- package/corpus/templates/content/actions/prepare-builder-source-review.ts +88 -90
- package/corpus/templates/content/actions/preview-builder-source-review.ts +4 -3
- package/corpus/templates/content/actions/refresh-content-database-source.ts +36 -9
- package/corpus/templates/content/actions/set-content-database-source-write-mode.ts +28 -24
- package/corpus/templates/content/app/components/editor/BubbleToolbar.tsx +62 -12
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +91 -16
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +15 -1
- package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +234 -44
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +194 -16
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +95 -42
- package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +4 -2
- package/corpus/templates/content/app/components/editor/extensions/CodeBlockNode.tsx +10 -166
- package/corpus/templates/content/app/components/editor/extensions/VideoBlock.tsx +32 -8
- package/corpus/templates/content/app/components/editor/extensions/VideoNode.ts +14 -0
- package/corpus/templates/content/app/components/editor/registrySlashItems.ts +5 -1
- package/corpus/templates/content/app/hooks/use-content-database.ts +59 -2
- package/corpus/templates/content/app/hooks/use-documents.ts +18 -26
- package/corpus/templates/content/app/root.tsx +1 -6
- package/corpus/templates/content/changelog/2026-07-24-builder-can-now-publish-approved-updates-to-entries-that-are.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-builder-collection-loading-no-longer-restarts-from-the-begin.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-builder-connections-now-complete-securely-from-netlify-deplo.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-builder-draft-creation-now-scopes-execution-to-the-selected-.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-builder-review-now-distinguishes-preparing-a-safe-dry-run-from.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-builder-source-imports-now-recover-from-a-transient-paginati.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-builder-source-refresh-now-preserves-the-provider-bound-fiel.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-builder-update-reviews-now-open-reliably-on-large-collection.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-builder-write-policy-controls-now-reflect-successful-changes.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-date-properties-now-save-reliably-when-selected-with-the-nat.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-editor-slash-search-now-keeps-multi-word-block-names-open.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-exact-editor-slash-commands-now-execute-on-enter-even-if-the.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-new-collaborative-pages-now-save-their-first-edits.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-new-local-builder-rows-no-longer-remain-locked-behind-a-none.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-opening-or-closing-a-collaborative-document-no-longer-lets-u.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-selected-text-now-opens-the-link-editor-with-command-k-or-co.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-slash-menu-block-choices-no-longer-stall-pointer-interaction.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-uploaded-and-embedded-media-now-stay-intact-while-collaborative-document-drafts-save.md +6 -0
- package/corpus/templates/content/changelog/2026-07-24-video-link-insertion-now-keeps-its-source-panel-open-while-t.md +6 -0
- package/corpus/templates/content/changelog/2026-07-26-builder-publishing-now-shows-safe-validation-details-instead.md +6 -0
- package/corpus/templates/content/changelog/2026-07-26-builder-reviews-stay-responsive-on-large-collections-and-pre.md +6 -0
- package/corpus/templates/content/changelog/2026-07-26-collaborative-documents-no-longer-flash-duplicated-recent-bl.md +6 -0
- package/corpus/templates/content/changelog/2026-07-26-corrected-builder-updates-are-now-reviewed-separately-from-f.md +6 -0
- package/corpus/templates/content/changelog/2026-07-26-documents-now-remain-read-only-until-their-live-collaborativ.md +6 -0
- package/corpus/templates/content/changelog/2026-07-26-slash-command-menus-now-stay-reachable-when-editing-near-the.md +6 -0
- package/corpus/templates/content/changelog/2026-07-26-the-slash-menu-now-shows-one-clear-callout-choice-instead-of.md +6 -0
- package/corpus/templates/content/shared/api.ts +1 -0
- package/corpus/templates/content/shared/builder-mdx.ts +73 -16
- package/corpus/templates/crm/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +177 -0
- package/corpus/templates/crm/.agents/skills/crm/SKILL.md +205 -0
- package/corpus/templates/crm/.agents/skills/customizing-agent-native/SKILL.md +220 -0
- package/corpus/templates/crm/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/crm/.agents/skills/sharing/SKILL.md +228 -0
- package/corpus/templates/crm/.agents/skills/storing-data/SKILL.md +178 -0
- package/corpus/templates/crm/.agents/skills/upgrade-agent-native/SKILL.md +122 -0
- package/corpus/templates/crm/.env.example +5 -0
- package/corpus/templates/crm/AGENTS.md +82 -0
- package/corpus/templates/crm/CHANGELOG.md +25 -0
- package/corpus/templates/crm/DEVELOPING.md +66 -0
- package/corpus/templates/crm/README.md +122 -0
- package/corpus/templates/crm/_gitignore +12 -0
- package/corpus/templates/crm/actions/_crm-action-utils.ts +98 -0
- package/corpus/templates/crm/actions/_crm-attribute-utils.ts +219 -0
- package/corpus/templates/crm/actions/_crm-dashboard.ts +69 -0
- package/corpus/templates/crm/actions/_crm-data-program-actions.ts +15 -0
- package/corpus/templates/crm/actions/_crm-list-utils.ts +775 -0
- package/corpus/templates/crm/actions/_crm-signal-utils.ts +79 -0
- package/corpus/templates/crm/actions/add-crm-record-to-list.ts +164 -0
- package/corpus/templates/crm/actions/apply-crm-proposals.ts +291 -0
- package/corpus/templates/crm/actions/archive-crm-attribute.ts +69 -0
- package/corpus/templates/crm/actions/attach-call-evidence.ts +170 -0
- package/corpus/templates/crm/actions/configure-crm-connection.ts +126 -0
- package/corpus/templates/crm/actions/configure-native-crm.ts +44 -0
- package/corpus/templates/crm/actions/create-crm-attribute.ts +350 -0
- package/corpus/templates/crm/actions/create-crm-list.ts +194 -0
- package/corpus/templates/crm/actions/create-crm-record.ts +148 -0
- package/corpus/templates/crm/actions/create-crm-signal-tracker.ts +58 -0
- package/corpus/templates/crm/actions/delete-crm-saved-view.ts +68 -0
- package/corpus/templates/crm/actions/delete-staged-dataset.ts +14 -0
- package/corpus/templates/crm/actions/estimate-crm-enrichment.ts +229 -0
- package/corpus/templates/crm/actions/find-crm-duplicates.ts +87 -0
- package/corpus/templates/crm/actions/get-crm-automation-recipe.ts +36 -0
- package/corpus/templates/crm/actions/get-crm-dashboard-panel.ts +35 -0
- package/corpus/templates/crm/actions/get-crm-dashboard.ts +14 -0
- package/corpus/templates/crm/actions/get-crm-overview.ts +13 -0
- package/corpus/templates/crm/actions/get-crm-pipeline-data.ts +61 -0
- package/corpus/templates/crm/actions/get-crm-record-page.ts +287 -0
- package/corpus/templates/crm/actions/get-crm-record.ts +75 -0
- package/corpus/templates/crm/actions/get-crm-workspace.ts +364 -0
- package/corpus/templates/crm/actions/install-crm-pipeline-dashboard.ts +81 -0
- package/corpus/templates/crm/actions/list-crm-attributes.ts +71 -0
- package/corpus/templates/crm/actions/list-crm-connections.ts +68 -0
- package/corpus/templates/crm/actions/list-crm-dashboard-revisions.ts +15 -0
- package/corpus/templates/crm/actions/list-crm-dashboards.ts +15 -0
- package/corpus/templates/crm/actions/list-crm-enrichment-slots.ts +28 -0
- package/corpus/templates/crm/actions/list-crm-list-entries.ts +192 -0
- package/corpus/templates/crm/actions/list-crm-lists.ts +80 -0
- package/corpus/templates/crm/actions/list-crm-proposals.ts +55 -0
- package/corpus/templates/crm/actions/list-crm-record-field-history.ts +201 -0
- package/corpus/templates/crm/actions/list-crm-record-values.ts +200 -0
- package/corpus/templates/crm/actions/list-crm-records.ts +103 -0
- package/corpus/templates/crm/actions/list-crm-saved-views.ts +66 -0
- package/corpus/templates/crm/actions/list-crm-signal-hits.ts +43 -0
- package/corpus/templates/crm/actions/list-crm-signal-trackers.ts +32 -0
- package/corpus/templates/crm/actions/list-crm-tasks.ts +22 -0
- package/corpus/templates/crm/actions/list-staged-datasets.ts +14 -0
- package/corpus/templates/crm/actions/list-workspace-connections.ts +47 -0
- package/corpus/templates/crm/actions/manage-crm-attribute-option.ts +272 -0
- package/corpus/templates/crm/actions/manage-crm-signal-tracker.ts +87 -0
- package/corpus/templates/crm/actions/manage-crm-task.ts +132 -0
- package/corpus/templates/crm/actions/merge-crm-records.ts +691 -0
- package/corpus/templates/crm/actions/navigate.ts +54 -0
- package/corpus/templates/crm/actions/provider-api-catalog.ts +22 -0
- package/corpus/templates/crm/actions/provider-api-docs.ts +54 -0
- package/corpus/templates/crm/actions/provider-api-request.ts +92 -0
- package/corpus/templates/crm/actions/query-staged-dataset.ts +44 -0
- package/corpus/templates/crm/actions/record-crm-call-insight.ts +160 -0
- package/corpus/templates/crm/actions/record-crm-smart-signal.ts +150 -0
- package/corpus/templates/crm/actions/remove-crm-list-entry.ts +79 -0
- package/corpus/templates/crm/actions/restore-crm-dashboard-revision.ts +23 -0
- package/corpus/templates/crm/actions/review-crm-signal.ts +31 -0
- package/corpus/templates/crm/actions/run-crm-attribute-fill.ts +443 -0
- package/corpus/templates/crm/actions/run-crm-enrichment.ts +647 -0
- package/corpus/templates/crm/actions/run-crm-saved-view-program.ts +103 -0
- package/corpus/templates/crm/actions/run-crm-signal-trackers.ts +265 -0
- package/corpus/templates/crm/actions/run.ts +7 -0
- package/corpus/templates/crm/actions/save-crm-dashboard.ts +51 -0
- package/corpus/templates/crm/actions/save-crm-saved-view.ts +296 -0
- package/corpus/templates/crm/actions/sync-crm.ts +146 -0
- package/corpus/templates/crm/actions/update-crm-attribute.ts +111 -0
- package/corpus/templates/crm/actions/update-crm-list-entry.ts +102 -0
- package/corpus/templates/crm/actions/update-crm-list.ts +97 -0
- package/corpus/templates/crm/actions/update-crm-record.ts +543 -0
- package/corpus/templates/crm/actions/view-screen.ts +324 -0
- package/corpus/templates/crm/agent-native.app-skill.json +69 -0
- package/corpus/templates/crm/app/components/crm/CreateCrmRecordDialog.tsx +158 -0
- package/corpus/templates/crm/app/components/crm/CrmDashboardPanel.tsx +78 -0
- package/corpus/templates/crm/app/components/crm/CrmSignalsPanel.tsx +220 -0
- package/corpus/templates/crm/app/components/crm/IntelligenceSettings.tsx +414 -0
- package/corpus/templates/crm/app/components/crm/RecordActions.tsx +648 -0
- package/corpus/templates/crm/app/components/crm/RecordGrid.tsx +488 -0
- package/corpus/templates/crm/app/components/crm/RecordWorkspace.tsx +232 -0
- package/corpus/templates/crm/app/components/crm/SavedViewDataProgram.tsx +93 -0
- package/corpus/templates/crm/app/components/crm/Surface.tsx +97 -0
- package/corpus/templates/crm/app/components/crm/WorkOverview.tsx +180 -0
- package/corpus/templates/crm/app/components/crm/board/CrmBoard.tsx +988 -0
- package/corpus/templates/crm/app/components/crm/board/board-model.ts +399 -0
- package/corpus/templates/crm/app/components/crm/board/entry-filter.ts +150 -0
- package/corpus/templates/crm/app/components/crm/board/view-draft.ts +227 -0
- package/corpus/templates/crm/app/components/crm/grid/CrmGrid.tsx +1033 -0
- package/corpus/templates/crm/app/components/crm/grid/GridCell.tsx +620 -0
- package/corpus/templates/crm/app/components/crm/grid/clipboard.ts +84 -0
- package/corpus/templates/crm/app/components/crm/grid/model.ts +304 -0
- package/corpus/templates/crm/app/components/crm/grid/navigation.ts +220 -0
- package/corpus/templates/crm/app/components/crm/grid/query.ts +214 -0
- package/corpus/templates/crm/app/components/crm/record/AttributePanel.tsx +192 -0
- package/corpus/templates/crm/app/components/crm/record/FieldHistory.tsx +179 -0
- package/corpus/templates/crm/app/components/crm/record/RecordHeader.tsx +103 -0
- package/corpus/templates/crm/app/components/crm/record/RecordLists.tsx +235 -0
- package/corpus/templates/crm/app/components/crm/record/RecordTabs.tsx +206 -0
- package/corpus/templates/crm/app/components/crm/record/field-editors.tsx +245 -0
- package/corpus/templates/crm/app/components/crm/record/record-data.ts +603 -0
- package/corpus/templates/crm/app/components/crm/settings/AdvancedSettings.tsx +49 -0
- package/corpus/templates/crm/app/components/crm/settings/AttributeOptionsEditor.tsx +441 -0
- package/corpus/templates/crm/app/components/crm/settings/ConnectionSettings.tsx +169 -0
- package/corpus/templates/crm/app/components/crm/settings/FieldsSettings.tsx +935 -0
- package/corpus/templates/crm/app/components/crm/settings/ListsSettings.tsx +339 -0
- package/corpus/templates/crm/app/components/crm/settings/settings-admin.ts +377 -0
- package/corpus/templates/crm/app/components/crm/shared/AttributeValueParts.tsx +69 -0
- package/corpus/templates/crm/app/components/crm/shared/attribute-value.ts +591 -0
- package/corpus/templates/crm/app/components/layout/CrmCommandMenu.tsx +556 -0
- package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +130 -0
- package/corpus/templates/crm/app/components/layout/CrmSidebar.tsx +407 -0
- package/corpus/templates/crm/app/components/layout/command-palette-search.ts +126 -0
- package/corpus/templates/crm/app/components/layout/crm-ui-intents.ts +41 -0
- package/corpus/templates/crm/app/components/layout/sidebar-collapse.ts +40 -0
- package/corpus/templates/crm/app/components/layout/sidebar-lists.ts +109 -0
- package/corpus/templates/crm/app/components/ui/alert-dialog.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/badge.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/button.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/card.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/checkbox.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/dialog.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/dropdown-menu.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/hover-card.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/input.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/label.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/popover.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/select.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/sheet.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/skeleton.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/switch.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/table.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/tabs.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/textarea.tsx +1 -0
- package/corpus/templates/crm/app/components/ui/toolkit-provider.tsx +17 -0
- package/corpus/templates/crm/app/components/ui/tooltip.tsx +1 -0
- package/corpus/templates/crm/app/design-system.ts +3 -0
- package/corpus/templates/crm/app/entry.client.tsx +19 -0
- package/corpus/templates/crm/app/entry.server.tsx +10 -0
- package/corpus/templates/crm/app/global.css +167 -0
- package/corpus/templates/crm/app/hooks/use-keyboard-shortcuts.ts +206 -0
- package/corpus/templates/crm/app/hooks/use-navigation-state.ts +48 -0
- package/corpus/templates/crm/app/i18n/en-US.ts +684 -0
- package/corpus/templates/crm/app/i18n/index.ts +34 -0
- package/corpus/templates/crm/app/lib/dashboard.ts +13 -0
- package/corpus/templates/crm/app/lib/navigation.ts +17 -0
- package/corpus/templates/crm/app/lib/tab-id.ts +1 -0
- package/corpus/templates/crm/app/lib/types.ts +172 -0
- package/corpus/templates/crm/app/lib/utils.ts +1 -0
- package/corpus/templates/crm/app/root.tsx +93 -0
- package/corpus/templates/crm/app/routes/_index.tsx +26 -0
- package/corpus/templates/crm/app/routes/accounts.tsx +41 -0
- package/corpus/templates/crm/app/routes/agent.tsx +5 -0
- package/corpus/templates/crm/app/routes/ask.tsx +53 -0
- package/corpus/templates/crm/app/routes/dashboard.tsx +118 -0
- package/corpus/templates/crm/app/routes/lists.tsx +228 -0
- package/corpus/templates/crm/app/routes/opportunities.tsx +41 -0
- package/corpus/templates/crm/app/routes/people.tsx +41 -0
- package/corpus/templates/crm/app/routes/proposals.tsx +388 -0
- package/corpus/templates/crm/app/routes/records.$recordId.tsx +53 -0
- package/corpus/templates/crm/app/routes/records.tsx +64 -0
- package/corpus/templates/crm/app/routes/settings.tsx +118 -0
- package/corpus/templates/crm/app/routes/setup.tsx +308 -0
- package/corpus/templates/crm/app/routes/tasks.tsx +252 -0
- package/corpus/templates/crm/app/routes/views.tsx +683 -0
- package/corpus/templates/crm/app/routes.ts +19 -0
- package/corpus/templates/crm/app/vite-env.d.ts +6 -0
- package/corpus/templates/crm/changelog/2026-07-26-any-list-or-view-can-be-shown-as-a-board-grouped-by-stage-so.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-26-crm-now-finds-likely-duplicate-records-and-tells-you-exactly.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-26-enrichment-now-shows-what-a-run-will-cost-before-it-starts-g.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-26-lists-turn-any-set-of-records-into-a-pipeline-with-its-own-s.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-26-moving-a-record-or-list-entry-into-a-stage-that-was-retired-.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-26-opening-a-record-now-shows-one-page-with-its-fields-the-list.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-26-press-cmd-k-to-jump-to-any-record-list-view-or-setting-and-u.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-26-provider-record-edits-now-show-an-exact-before-after-diff-an.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-26-record-page-attribute-labels-now-read-in-full-instead-of-bei.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-26-records-now-use-typed-fields-currency-dates-ratings-status-s.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-26-retyping-a-value-on-the-record-page-now-replaces-it-instead-.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-26-settings-now-has-fields-and-lists-tabs-for-adding-fields-edi.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-26-the-proposal-review-now-shows-the-field-that-actually-change.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-26-the-record-grid-is-now-a-real-spreadsheet-filter-sort-and-pa.md +6 -0
- package/corpus/templates/crm/components.json +20 -0
- package/corpus/templates/crm/docs/architecture/crm-contract.md +214 -0
- package/corpus/templates/crm/docs/features/README.md +55 -0
- package/corpus/templates/crm/docs/features/f1-records-and-fields.mdx +52 -0
- package/corpus/templates/crm/docs/features/f2-lists-pipelines-and-views.mdx +48 -0
- package/corpus/templates/crm/docs/features/f3-work-and-record-quality.mdx +40 -0
- package/corpus/templates/crm/docs/features/f4-evidence-and-chat.mdx +47 -0
- package/corpus/templates/crm/learnings.defaults.md +5 -0
- package/corpus/templates/crm/netlify.toml +11 -0
- package/corpus/templates/crm/package.json +61 -0
- package/corpus/templates/crm/public/favicon.svg +1 -0
- package/corpus/templates/crm/public/icon-180.svg +1 -0
- package/corpus/templates/crm/public/manifest.json +11 -0
- package/corpus/templates/crm/react-router.config.ts +7 -0
- package/corpus/templates/crm/server/crm/adapter.ts +32 -0
- package/corpus/templates/crm/server/crm/crm-field-firewall.ts +64 -0
- package/corpus/templates/crm/server/crm/crm-mirror.ts +721 -0
- package/corpus/templates/crm/server/crm/field-policy-attributes.ts +48 -0
- package/corpus/templates/crm/server/crm/hubspot-adapter.ts +1146 -0
- package/corpus/templates/crm/server/crm/native-adapter.ts +1810 -0
- package/corpus/templates/crm/server/crm/provider-record-link.ts +264 -0
- package/corpus/templates/crm/server/crm/read-through.ts +207 -0
- package/corpus/templates/crm/server/crm/salesforce-adapter.ts +1255 -0
- package/corpus/templates/crm/server/db/crm-store.ts +1112 -0
- package/corpus/templates/crm/server/db/index.ts +191 -0
- package/corpus/templates/crm/server/db/schema.ts +647 -0
- package/corpus/templates/crm/server/lib/crm-query.ts +1558 -0
- package/corpus/templates/crm/server/lib/dedupe.ts +714 -0
- package/corpus/templates/crm/server/lib/enrichment-cost.ts +381 -0
- package/corpus/templates/crm/server/lib/enrichment-slots.ts +519 -0
- package/corpus/templates/crm/server/lib/intelligence/default-detectors.ts +65 -0
- package/corpus/templates/crm/server/lib/intelligence/evidence.ts +105 -0
- package/corpus/templates/crm/server/lib/intelligence/keyword-detector.ts +94 -0
- package/corpus/templates/crm/server/lib/intelligence/smart-detector.ts +39 -0
- package/corpus/templates/crm/server/lib/intelligence/summary.ts +19 -0
- package/corpus/templates/crm/server/lib/lifecycle.ts +634 -0
- package/corpus/templates/crm/server/lib/provider-api.ts +64 -0
- package/corpus/templates/crm/server/middleware/auth.ts +4 -0
- package/corpus/templates/crm/server/plugins/agent-chat.ts +65 -0
- package/corpus/templates/crm/server/plugins/auth.ts +14 -0
- package/corpus/templates/crm/server/plugins/core-routes.ts +17 -0
- package/corpus/templates/crm/server/plugins/db.ts +738 -0
- package/corpus/templates/crm/server/routes/[...page].get.ts +5 -0
- package/corpus/templates/crm/shared/crm-attributes.ts +469 -0
- package/corpus/templates/crm/shared/crm-automation-recipes.ts +132 -0
- package/corpus/templates/crm/shared/crm-contract.ts +417 -0
- package/corpus/templates/crm/shared/crm-navigation.ts +190 -0
- package/corpus/templates/crm/shared/crm-sales-config.ts +63 -0
- package/corpus/templates/crm/ssr-entry.ts +11 -0
- package/corpus/templates/crm/tsconfig.json +24 -0
- package/corpus/templates/crm/vite.config.ts +15 -0
- package/corpus/templates/crm/vitest.config.ts +5 -0
- package/corpus/templates/design/app/i18n-data.ts +12 -12
- package/corpus/templates/design/changelog/2026-07-26-apply-design-updates-from-a-centered-top-toolbar-without-cov.md +6 -0
- package/corpus/toolkit/CHANGELOG.md +6 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/src/editor/useCollabReconcile.ts +14 -1
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +12 -0
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/collab/routes.d.ts +2 -2
- package/dist/deploy/build.js +6 -0
- package/dist/deploy/build.js.map +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/server/builder-browser.d.ts +13 -0
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +59 -0
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +10 -5
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/package.json +2 -2
- package/src/cli/templates-meta.ts +12 -0
- package/src/deploy/build.ts +8 -0
- package/src/server/builder-browser.ts +76 -0
- package/src/server/core-routes-plugin.ts +15 -5
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: storing-data
|
|
3
|
+
description: >-
|
|
4
|
+
How to store application data in agent-native apps. All data lives in SQL.
|
|
5
|
+
Use when adding data models, deciding where to store data, or reading/writing
|
|
6
|
+
application data.
|
|
7
|
+
scope: dev
|
|
8
|
+
metadata:
|
|
9
|
+
internal: true
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Storing Data — SQL is the Source of Truth
|
|
13
|
+
|
|
14
|
+
## Rule
|
|
15
|
+
|
|
16
|
+
All application data lives in **SQL** (SQLite locally, persistent database in production). The agent and UI share the same database. SQL stores structured records, metadata, references, and searchable text — not large raw file payloads. Do not store durable app data in the filesystem unless the app is explicitly running a Local File Mode artifact flow described below.
|
|
17
|
+
|
|
18
|
+
Large binary or file-like payloads (images, video/audio, PDFs, ZIPs, screenshots, session replay chunks, thumbnails, generated assets, `data:` URLs, and base64 file bodies) must go through configured file/blob storage such as `uploadFile()` or `putPrivateBlob()`. Persist only the returned URL, asset id, or opaque blob handle in SQL. If storage is unavailable in hosted or persistent-database mode, fail closed with setup guidance instead of falling back to base64 in `application_state`, `settings`, `resources`, or app tables. Local SQLite-only dev fallbacks may exist for tiny assets, but they must be capped, documented as dev-only, and kept off hot list/read paths.
|
|
19
|
+
|
|
20
|
+
**Local File Mode exception:** some artifact apps (Content, Plans, Slides, Dashboards, Designs, etc.) can intentionally use repo files as the source of truth for the artifact itself. This must be explicit via `agent-native.json`, `AGENT_NATIVE_MODE=local-files`, or an app-owned local-file action helper. In that mode, the UI and agent still go through app actions, but those actions read/write scoped files through `@agent-native/core/local-artifacts` instead of SQL rows. App state, auth, settings, credentials, collaboration metadata, and hosted database mode remain SQL. File-to-database or file-to-provider synchronization is an explicit sync step, not an implicit side effect of editing.
|
|
21
|
+
|
|
22
|
+
When you add a data model, a list, or a read path, also follow the `performance` skill: project only the columns a list renders, index the columns hot queries filter/sort on, and avoid query waterfalls — so apps stay fast as data grows.
|
|
23
|
+
|
|
24
|
+
## How It Works
|
|
25
|
+
|
|
26
|
+
Agent-native apps use Drizzle ORM over the configured SQL backend. Local development works out of the box with a SQLite file at `data/app.db`; production and shared preview deploys need a persistent `DATABASE_URL` because container/serverless filesystems can reset. The code should behave the same across backends, but the local SQLite file is not durable once deployed.
|
|
27
|
+
|
|
28
|
+
For app code, use Drizzle's schema/query DSL by default. Raw SQL is an escape hatch for additive migrations, health checks, or one-off maintenance, not the normal way to build features.
|
|
29
|
+
|
|
30
|
+
### Naming migrations
|
|
31
|
+
|
|
32
|
+
When you add an entry to a `runMigrations([...])` list (`@agent-native/core/db`), always give it a unique `name:` slug (e.g. `name: "analytics-alert-rules-table"`) alongside its `version`. Never renumber or reuse version numbers on existing entries.
|
|
33
|
+
|
|
34
|
+
Why: version numbers alone are not a safe identity. Two branches that each independently extend the same migration list can ship different DDL under the same version numbers — whichever branch deploys first "claims" those version numbers in the bookkeeping table, and the other branch's DDL is silently treated as already applied even though it never ran. This exact collision took down analytics: parallel branches both extended their migration list through v75-v83 with different DDL, so `analytics_alert_rules`, `analytics_alert_incidents`, and `session_recordings.network_error_count` never made it to production despite the bookkeeping table showing every version as applied. A `name:` slug is tracked independently of version numbers, so it applies exactly once per database regardless of what any other branch already recorded.
|
|
35
|
+
|
|
36
|
+
Existing unnamed migrations don't need to be renamed retroactively (the two gating strategies coexist), but any new entry should always carry a name.
|
|
37
|
+
|
|
38
|
+
### Core SQL Stores (auto-created, available in all templates)
|
|
39
|
+
|
|
40
|
+
| Store | Purpose | Access |
|
|
41
|
+
| ------------------- | ---------------------------------------------------- | ------------------------------------------ |
|
|
42
|
+
| `application_state` | Ephemeral UI state (compose windows, navigation) | `readAppState()` / `writeAppState()` |
|
|
43
|
+
| `settings` | Persistent KV config (preferences, app settings) | `getSetting()` / `putSetting()` |
|
|
44
|
+
| `oauth_tokens` | OAuth credentials | `@agent-native/core/oauth-tokens` |
|
|
45
|
+
| `sessions` | Auth sessions | `@agent-native/core/server` |
|
|
46
|
+
|
|
47
|
+
### Domain Data (per-template)
|
|
48
|
+
|
|
49
|
+
Define schema with the framework Drizzle helpers in `server/db/schema.ts`. Get a database instance with `const db = getDb()` from `server/db/index.ts`. All queries are async.
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { eq } from "drizzle-orm";
|
|
53
|
+
import { table, text, integer, now } from "@agent-native/core/db/schema";
|
|
54
|
+
|
|
55
|
+
export const tasks = table("tasks", {
|
|
56
|
+
id: text("id").primaryKey(),
|
|
57
|
+
title: text("title").notNull(),
|
|
58
|
+
completed: integer("completed", { mode: "boolean" })
|
|
59
|
+
.notNull()
|
|
60
|
+
.default(false),
|
|
61
|
+
createdAt: text("created_at").notNull().default(now()),
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const rows = await db.select().from(tasks).where(eq(tasks.id, taskId));
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Never import `sqliteTable` / `pgTable` or column helpers from `drizzle-orm/sqlite-core` or `drizzle-orm/pg-core` in app templates. Use `@agent-native/core/db/schema` so the same schema can run against SQLite, Postgres, libSQL/Turso, D1, and other supported backends.
|
|
68
|
+
|
|
69
|
+
| Template | Tables |
|
|
70
|
+
| ------------ | --------------------------------------------- |
|
|
71
|
+
| **Mail** | emails, labels (+ Gmail API when connected) |
|
|
72
|
+
| **Calendar** | events, bookings |
|
|
73
|
+
| **Forms** | forms, responses |
|
|
74
|
+
| **Content** | documents |
|
|
75
|
+
| **Slides** | decks (JSON stored in SQL) |
|
|
76
|
+
| **Videos** | compositions in registry + localStorage |
|
|
77
|
+
|
|
78
|
+
### Agent Access
|
|
79
|
+
|
|
80
|
+
The agent uses app-specific actions to read/write the database. Core DB scripts are for inspection and maintenance, not for implementing normal product behavior:
|
|
81
|
+
|
|
82
|
+
- `pnpm action db-schema` — Show all tables, columns, types
|
|
83
|
+
- `pnpm action db-query --sql "SELECT * FROM forms"` — Run SELECT queries
|
|
84
|
+
- `pnpm action db-exec --sql "UPDATE ..."` — Last-resort ad-hoc maintenance for short columns, multi-column writes, or computed updates when no domain action exists. For several related writes, prefer `--statements '[{"sql":"...","args":[...]}]'` so they run sequentially in one transaction. Schema changes are blocked; use reviewed additive migrations/startup code instead.
|
|
85
|
+
- `pnpm action db-patch --table <t> --column <c> --where "<clause>" --find "<old>" --replace "<new>"` — **Surgical search/replace on a large text column.** Sends the diff instead of re-transmitting the whole value, so it's dramatically more token-efficient than `db-exec UPDATE` when editing multi-kilobyte documents, slide HTML, dashboard/form JSON, etc. Targets exactly one row per call — narrow `--where` by primary key. Supports `--edits '[{find,replace},...]'` for batch edits and `--all` to replace every occurrence.
|
|
86
|
+
- App-specific actions for domain operations — **always prefer these over raw SQL when one exists.** They encode business rules, power the client action hooks, and for editor-backed tables (documents, slides) also push live Yjs updates to open collaborative editors. `db-patch` is the generic fallback for tables without a dedicated edit action.
|
|
87
|
+
|
|
88
|
+
**For one-off maintenance, how to choose between `db-exec UPDATE` and `db-patch`:**
|
|
89
|
+
|
|
90
|
+
| Scenario | Use |
|
|
91
|
+
| -------------------------------------------------------------- | ------------ |
|
|
92
|
+
| `SET status = 'published'` on one row | `db-exec` |
|
|
93
|
+
| `SET calories = calories + 50` | `db-exec` |
|
|
94
|
+
| Updating several columns at once | `db-exec` |
|
|
95
|
+
| Inserting/updating several rows as one logical operation | `db-exec --statements` |
|
|
96
|
+
| Fixing a typo in a 50KB markdown document's `content` column | `db-patch` |
|
|
97
|
+
| Changing a single key in a dashboard's JSON blob | `db-patch` |
|
|
98
|
+
| Tweaking one paragraph of slide HTML stored in `decks.data` | `db-patch` |
|
|
99
|
+
| Any edit where you'd otherwise re-send thousands of characters | `db-patch` |
|
|
100
|
+
|
|
101
|
+
All of these honor the per-user / per-org data scoping — you can't read or write rows outside the current user's data, regardless of which tool you choose.
|
|
102
|
+
|
|
103
|
+
### Frontend Access
|
|
104
|
+
|
|
105
|
+
The frontend calls actions using React Query hooks from the client API. The framework owns the HTTP transport behind these hooks, so components should not call action routes with raw `fetch`.
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { useActionQuery, useActionMutation } from "@agent-native/core/client/hooks";
|
|
109
|
+
|
|
110
|
+
// Read data
|
|
111
|
+
const { data } = useActionQuery("list-meals", { date: "2025-01-01" });
|
|
112
|
+
|
|
113
|
+
// Write data
|
|
114
|
+
const { mutate } = useActionMutation("log-meal");
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Actions are the **preferred way** for the frontend to access data. You rarely need custom `/api/` routes — only for file uploads, streaming, webhooks, or OAuth callbacks.
|
|
118
|
+
|
|
119
|
+
### Production / Cloud Deployment
|
|
120
|
+
|
|
121
|
+
Local SQLite works out of the box for development. To deploy to production or any environment where data must survive restarts:
|
|
122
|
+
|
|
123
|
+
1. Set `DATABASE_URL` to a persistent SQL database.
|
|
124
|
+
2. Set `DATABASE_AUTH_TOKEN` only when the provider requires a separate token, such as Turso/libSQL.
|
|
125
|
+
3. No code changes should be needed when the schema and queries stay portable.
|
|
126
|
+
|
|
127
|
+
Turso is one valid option, not the required option. Common choices include Neon or Supabase Postgres, Turso/libSQL, plain Postgres, durable SQLite, Cloudflare D1 bindings, and managed platform SQL environments when available.
|
|
128
|
+
|
|
129
|
+
### Real-time Sync
|
|
130
|
+
|
|
131
|
+
Polling streams database changes to the UI. When the agent writes to the database via scripts, the UI updates automatically via `useDbSync()` which invalidates React Query caches.
|
|
132
|
+
|
|
133
|
+
## Do
|
|
134
|
+
|
|
135
|
+
- Use Drizzle ORM for structured domain data (forms, bookings, documents)
|
|
136
|
+
- Use Drizzle query builder methods (`select`, `insert`, `update`, `delete`) and portable operators from `drizzle-orm` (`eq`, `and`, `or`, `inArray`, `desc`, etc.) for app reads/writes
|
|
137
|
+
- Use framework schema helpers from `@agent-native/core/db/schema`, not dialect-specific Drizzle imports
|
|
138
|
+
- Use the `settings` store for app configuration and user preferences
|
|
139
|
+
- Use `application-state` for ephemeral UI state that the agent and UI share
|
|
140
|
+
- Use `oauth-tokens` for OAuth credentials
|
|
141
|
+
- Use `uploadFile()` or `putPrivateBlob()` for large files/blob data and store only URLs, ids, or handles in SQL
|
|
142
|
+
- Use core DB scripts (`db-schema`, `db-query`, `db-exec`, `db-patch`) for ad-hoc database operations
|
|
143
|
+
- Use `db-exec --statements` instead of several separate `db-exec` calls for related writes; it is faster and rolls back the whole batch if one statement fails
|
|
144
|
+
- Reach for `db-patch` instead of `db-exec UPDATE` whenever you're making a small change to a large text/JSON column — it's much cheaper on tokens
|
|
145
|
+
|
|
146
|
+
## Don't
|
|
147
|
+
|
|
148
|
+
- Don't store structured app data as JSON files
|
|
149
|
+
- Don't store app state in localStorage, sessionStorage, or cookies (except for UI-only preferences like sidebar width)
|
|
150
|
+
- Don't keep state only in memory (server variables, global stores)
|
|
151
|
+
- Don't use Redis or any external state store for app data
|
|
152
|
+
- Don't store large files, base64 blobs, `data:` URLs, screenshots, videos, audio, PDFs, ZIPs, or session replay chunks directly in SQL rows, `application_state`, `settings`, or `resources`
|
|
153
|
+
- Don't implement product features with raw SQL or `getDbExec()` when Drizzle can express the query
|
|
154
|
+
- Don't write SQLite-only or Postgres-only SQL in app code
|
|
155
|
+
- Don't interpolate user input directly into SQL queries — use Drizzle ORM's query builder
|
|
156
|
+
|
|
157
|
+
## Security
|
|
158
|
+
|
|
159
|
+
- **SQL injection** — Use Drizzle ORM's query builder, never raw string interpolation for SQL queries
|
|
160
|
+
- **Validate before writing** — Check data shape before writing, especially for user-submitted data
|
|
161
|
+
|
|
162
|
+
## Application State and Context Awareness
|
|
163
|
+
|
|
164
|
+
When storing app-state, include **navigation state** — the agent needs to know what the user is looking at. The `application_state` table holds ephemeral UI state that both the agent and UI share. Key patterns:
|
|
165
|
+
|
|
166
|
+
- **`navigation` key** — the UI writes current view and selection on every route change. The agent reads this before acting.
|
|
167
|
+
- **`navigate` key** — the agent writes one-shot commands to navigate the UI. The UI processes and deletes them.
|
|
168
|
+
- **Domain-specific keys** (e.g., `compose-{id}`) — bidirectional state for features like email drafts.
|
|
169
|
+
|
|
170
|
+
When adding a new data model or feature, also consider what navigation and selection state needs to be exposed via application-state. See the **context-awareness** skill for the full pattern.
|
|
171
|
+
|
|
172
|
+
## Related Skills
|
|
173
|
+
|
|
174
|
+
- **context-awareness** — How to expose navigation and selection state via application-state
|
|
175
|
+
- **real-time-sync** — Set up polling so the UI updates when the database changes
|
|
176
|
+
- **actions** — Create actions with `defineAction` to query the database
|
|
177
|
+
- **client-methods** — Keep route details behind named client helpers/hooks
|
|
178
|
+
- **self-modifying-code** — The agent can also modify the app's source code
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: upgrade-agent-native
|
|
3
|
+
description: >-
|
|
4
|
+
Bring an older Agent Native app or workspace current. Use when updating
|
|
5
|
+
@agent-native/core, fixing a broken upgrade, or when tempted to patch or
|
|
6
|
+
override core/dispatch packages to make an old branch run.
|
|
7
|
+
scope: dev
|
|
8
|
+
metadata:
|
|
9
|
+
internal: true
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Upgrade Agent Native
|
|
13
|
+
|
|
14
|
+
## Rule
|
|
15
|
+
|
|
16
|
+
When an older Agent Native app/branch needs to run on current packages, use
|
|
17
|
+
`agent-native upgrade`. Never "fix" upgrade breakage with
|
|
18
|
+
`pnpm.overrides`, `patchedDependencies`, `resolutions`, local patches, or
|
|
19
|
+
edits under `node_modules/@agent-native/*` — especially not against
|
|
20
|
+
`@agent-native/core` or `@agent-native/dispatch`.
|
|
21
|
+
|
|
22
|
+
## Why
|
|
23
|
+
|
|
24
|
+
Agents often respond to a failed core bump by inventing framework patches and
|
|
25
|
+
dispatch behavior overrides. That hides the real app-level break, drifts from
|
|
26
|
+
upstream, and makes the next upgrade worse. The supported path is bump →
|
|
27
|
+
install → refresh scaffold skills → verify, then fix **app** code only.
|
|
28
|
+
|
|
29
|
+
## How
|
|
30
|
+
|
|
31
|
+
1. **Preview migration codemods first**
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx @agent-native/core@latest upgrade --codemods
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Codemods are preview-by-default: read the diff before applying it. Do not
|
|
38
|
+
manually edit imports before running this command; the migration manifest is
|
|
39
|
+
the source of truth for renamed specifiers and symbols.
|
|
40
|
+
|
|
41
|
+
2. **Apply the reviewed codemods, then run the upgrade**
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx @agent-native/core@latest upgrade --codemods --yes
|
|
45
|
+
npx @agent-native/core@latest upgrade
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Or from an already-installed CLI: `pnpm exec agent-native upgrade` /
|
|
49
|
+
`agent-native upgrade`.
|
|
50
|
+
|
|
51
|
+
What it does:
|
|
52
|
+
|
|
53
|
+
- Blocks (unless `--force`) when `@agent-native/*` overrides/patches exist
|
|
54
|
+
- Rewrites non-local `@agent-native/*` dependency pins to `latest`
|
|
55
|
+
- Runs the package manager install
|
|
56
|
+
- Runs `skills update scaffold --project`
|
|
57
|
+
- Runs `typecheck` when the project has that script
|
|
58
|
+
|
|
59
|
+
3. **Pull upstream template changes (optional, separate from the bump)**
|
|
60
|
+
|
|
61
|
+
`agent-native upgrade` moves package versions. It never touches files that
|
|
62
|
+
were copied out of a template at scaffold time, so template fixes and
|
|
63
|
+
improvements do not arrive with a bump.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
agent-native template status # recorded ref vs latest, drift counts
|
|
67
|
+
agent-native template diff # what upstream changed, read-only
|
|
68
|
+
agent-native template sync # 3-way merge it into the app
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`sync` defaults to the ref matching the installed `@agent-native/core`, so
|
|
72
|
+
run it after `upgrade`. It merges per file against a pristine baseline
|
|
73
|
+
stored in `refs/agent-native/template-baseline/<app-path>`; files upstream
|
|
74
|
+
did not touch are left alone, and real collisions get conflict markers.
|
|
75
|
+
After resolving markers, run `agent-native template accept` — the baseline
|
|
76
|
+
deliberately does not advance past an unresolved merge.
|
|
77
|
+
|
|
78
|
+
Apps scaffolded before provenance existed have no baseline. Create one
|
|
79
|
+
with `agent-native template baseline` before the first sync.
|
|
80
|
+
|
|
81
|
+
4. **If upgrade or typecheck fails**
|
|
82
|
+
|
|
83
|
+
- Read the concrete error
|
|
84
|
+
- Fix **app** source, actions, config, or env — not framework packages
|
|
85
|
+
- Re-run `agent-native upgrade` or `pnpm typecheck`
|
|
86
|
+
- Stop and ask the user if you cannot fix the app-level error
|
|
87
|
+
|
|
88
|
+
Intentional app-level UI customization is a separate workflow. Read
|
|
89
|
+
`customizing-agent-native` when the product needs to own a selectively
|
|
90
|
+
copied component; do not use that path to reproduce framework runtime
|
|
91
|
+
behavior or hide version skew.
|
|
92
|
+
|
|
93
|
+
5. **Dry-run / partial runs**
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
agent-native upgrade --dry-run
|
|
97
|
+
agent-native upgrade --skip-verify
|
|
98
|
+
agent-native upgrade --skip-install # package.json bumps only
|
|
99
|
+
agent-native doctor --only migration-manifest
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`migration-manifest` has no opt-out. Run it in CI before upgrading to find
|
|
103
|
+
imports that will break, then use `npx @agent-native/core@latest upgrade --codemods`
|
|
104
|
+
to preview the supported rewrite.
|
|
105
|
+
|
|
106
|
+
## Don't
|
|
107
|
+
|
|
108
|
+
- Don't add `pnpm.overrides`, `overrides`, `resolutions`, or
|
|
109
|
+
`patchedDependencies` for any `@agent-native/*` package
|
|
110
|
+
- Don't edit `node_modules/@agent-native/core` or
|
|
111
|
+
`node_modules/@agent-native/dispatch`
|
|
112
|
+
- Don't invent local "dispatch behavior" shims to paper over version skew
|
|
113
|
+
- Don't keep iterating with more framework patches after a failed install
|
|
114
|
+
- Don't skip `skills update scaffold --project` after a core bump (the
|
|
115
|
+
upgrade command does this for you)
|
|
116
|
+
|
|
117
|
+
## Related Skills
|
|
118
|
+
|
|
119
|
+
- **self-modifying-code** — Tier 4: framework packages are off limits
|
|
120
|
+
- **agent-native-docs** — version-matched docs after the bump
|
|
121
|
+
- **customizing-agent-native** — intentional app-owned UI copies, not upgrade patches
|
|
122
|
+
- **portability** — keep app code provider-agnostic across upgrades
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# CRM — Agent Guide
|
|
2
|
+
|
|
3
|
+
A typed, bitemporal CRM whose grid is the product. It is Native SQL or a scoped
|
|
4
|
+
HubSpot/Salesforce lens; UI and agent share actions.
|
|
5
|
+
|
|
6
|
+
## Skills
|
|
7
|
+
|
|
8
|
+
- `crm` — read before CRM work: provider/credential boundaries, lists,
|
|
9
|
+
enrichment, signals, dashboards, and Clips evidence.
|
|
10
|
+
- Before building common workspace or agent UI, read `agent-native-toolkit`;
|
|
11
|
+
read `customizing-agent-native` when extending shared framework capabilities.
|
|
12
|
+
|
|
13
|
+
Source of truth: `shared/crm-contract.ts` (vocabulary, field and write policy),
|
|
14
|
+
`shared/crm-attributes.ts` (types), `server/lib/record-fields.ts` (the only
|
|
15
|
+
sanctioned field-value write).
|
|
16
|
+
|
|
17
|
+
## Core model
|
|
18
|
+
|
|
19
|
+
- **Typed attributes**, 17 types: text, number, checkbox, currency, date,
|
|
20
|
+
timestamp, rating, status, select, record-reference, actor-reference,
|
|
21
|
+
location, domain, email-address, phone-number, plus system-only interaction
|
|
22
|
+
and personal-name. Call `list-crm-attributes` first; never guess a slug or
|
|
23
|
+
type.
|
|
24
|
+
- **Managed options.** A status/select value must already exist as an option;
|
|
25
|
+
writing an unknown one is a 422, never a silent auto-create.
|
|
26
|
+
- **Values are bitemporal.** A change closes the current row and opens a new
|
|
27
|
+
one, so stage history *is* the value history. An equal write stores nothing;
|
|
28
|
+
`historyTracked=false` means in-place updates, not "never changed".
|
|
29
|
+
- **Objects vs lists.** A list is a workflow overlay over one object type, with
|
|
30
|
+
its own entry attributes. Lists and their entries are local-authoritative on
|
|
31
|
+
*every* backend, HubSpot and Salesforce included — a pipeline never needs a
|
|
32
|
+
provider write.
|
|
33
|
+
- **Saved views** hold filter, sort, columns, audience, and a table or board
|
|
34
|
+
presentation; `"@currentUser"` in a filter resolves to the caller.
|
|
35
|
+
- **Enrichment spends in two phases**: free `verify`, then paid `spend` whose
|
|
36
|
+
input set is *built from* approved record ids.
|
|
37
|
+
|
|
38
|
+
## Hard boundaries
|
|
39
|
+
|
|
40
|
+
- Workspace Connections own provider credentials. Never request, store, log, or
|
|
41
|
+
return a provider token.
|
|
42
|
+
- The mirror is thin: unknown fields are remote-only, sensitive ones redacted,
|
|
43
|
+
only allow-listed fields mirrored. Raw payloads, transcripts, media, and
|
|
44
|
+
base64 never enter SQL — evidence is a URL/id plus a bounded quote.
|
|
45
|
+
- **A provider write is a handoff, not a write.** A provider-owned edit becomes a
|
|
46
|
+
proposal; `apply-crm-proposals` returns the exact diff and a deep link to
|
|
47
|
+
finish it upstream. CRM never completes an upstream write and never reports
|
|
48
|
+
one as applied.
|
|
49
|
+
- Ownership, amount, stage, deletion, bulk scope, and external side effects need
|
|
50
|
+
an exact preview and approval.
|
|
51
|
+
- Never merge identities from email or domain alone — that is a duplicate
|
|
52
|
+
*signal*; merging is an explicit reviewed action.
|
|
53
|
+
|
|
54
|
+
## Actions
|
|
55
|
+
|
|
56
|
+
|Action|Purpose|
|
|
57
|
+
|---|---|
|
|
58
|
+
|`get-crm-workspace` / `get-crm-overview`|Start here: identity, book of business, tasks, proposals, signals, health.|
|
|
59
|
+
|`view-screen` / `navigate`|Read the visible screen and selection; move the UI.|
|
|
60
|
+
|`configure-native-crm` / `configure-crm-connection` / `list-crm-connections` / `list-workspace-connections` / `sync-crm`|Set up Native SQL or a granted connection; refresh a cohort.|
|
|
61
|
+
|`list-crm-attributes` / `create-crm-attribute` / `update-crm-attribute` / `archive-crm-attribute` / `manage-crm-attribute-option`|Read and author the typed schema and its managed options.|
|
|
62
|
+
|`list-crm-records` / `list-crm-record-values` / `get-crm-record` / `get-crm-record-page` / `create-crm-record` / `update-crm-record`|Grid rows, grid cells, one record, the record page, create, edit.|
|
|
63
|
+
|`list-crm-record-field-history`|How one value changed: value, the window it was current, actor.|
|
|
64
|
+
|`list-crm-lists` / `create-crm-list` / `update-crm-list` / `list-crm-list-entries` / `add-crm-record-to-list` / `update-crm-list-entry` / `remove-crm-list-entry`|Lists and pipelines; a stage move is `update-crm-list-entry`.|
|
|
65
|
+
|`list-crm-saved-views` / `save-crm-saved-view` / `delete-crm-saved-view` / `run-crm-saved-view-program`|Saved table/board views and a view's data program.|
|
|
66
|
+
|`list-crm-proposals` / `apply-crm-proposals`|Review a pending provider change and record the handoff.|
|
|
67
|
+
|`find-crm-duplicates` / `merge-crm-records`|Scored duplicate candidates with reasons; merge into a survivor.|
|
|
68
|
+
|`list-crm-enrichment-slots` / `estimate-crm-enrichment` / `run-crm-enrichment`|Slot credential state; cost estimate; the gated verify/spend run.|
|
|
69
|
+
|`run-crm-attribute-fill`|Manual fill: get the brief, reason, call again with values.|
|
|
70
|
+
|`list-crm-tasks` / `manage-crm-task`|Read and manage follow-up tasks.|
|
|
71
|
+
|`attach-call-evidence` / `create-crm-signal-tracker` / `list-crm-signal-trackers` / `manage-crm-signal-tracker` / `run-crm-signal-trackers` / `list-crm-signal-hits` / `record-crm-smart-signal` / `record-crm-call-insight` / `review-crm-signal` / `get-crm-automation-recipe`|Call evidence and reviewable signals; smart detection goes through agent chat, cited to stored evidence.|
|
|
72
|
+
|`install-crm-pipeline-dashboard` / `get-crm-pipeline-data` / `get-crm-dashboard` / `get-crm-dashboard-panel` / `list-crm-dashboards` / `save-crm-dashboard` / `list-crm-dashboard-revisions` / `restore-crm-dashboard-revision`|Install, read, revision-write, restore the Pipeline dashboard.|
|
|
73
|
+
|`provider-api-catalog` / `provider-api-docs` / `provider-api-request` / `list-staged-datasets` / `query-staged-dataset` / `delete-staged-dataset`|Read-only escape hatch for an exact provider request no action expresses; stage and reduce large results.|
|
|
74
|
+
|
|
75
|
+
## Agent behavior
|
|
76
|
+
|
|
77
|
+
- Call `view-screen` when the request names the visible record, selection, or
|
|
78
|
+
view. `navigate` to a view rather than describing it.
|
|
79
|
+
- Never flatten a failure into a normal-looking value: an unreadable owner,
|
|
80
|
+
slot, or scope is reported as itself, never as empty. Read a value back before
|
|
81
|
+
reporting it done.
|
|
82
|
+
- Recover from a recoverable error rather than abandoning the task.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# CRM changelog
|
|
2
|
+
|
|
3
|
+
## 2026-07-26
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- CRM connects to HubSpot for scoped account intelligence, saved views, follow-up tasks, evidence, and approval-gated write proposals.
|
|
8
|
+
- CRM can prepare a record-scoped, default-off Clips review recipe while keeping media and transcripts in Clips.
|
|
9
|
+
- CRM can now find and review evidence-grounded call signals without storing transcripts or media.
|
|
10
|
+
- Approved sales automations can now update routine local CRM fields while provider changes remain reviewable proposals.
|
|
11
|
+
- CRM can now run as a standalone Native SQL system for accounts, people, opportunities, views, tasks, and cadence without an external provider.
|
|
12
|
+
- Pipeline now gives each CRM user a live, permission-aware view of opportunity value by stage.
|
|
13
|
+
- CRM can now connect to Salesforce alongside HubSpot for scoped account intelligence and follow-up work.
|
|
14
|
+
|
|
15
|
+
### Improved
|
|
16
|
+
|
|
17
|
+
- CRM can now manage keyword and smart call-signal trackers from Intelligence settings.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- Pipeline dashboards now install correctly from the CRM action CLI.
|
|
22
|
+
- CRM field validation now explains which fields cannot be edited instead of showing a generic error.
|
|
23
|
+
- Fixed HubSpot contact syncs missing records updated after the sync cursor.
|
|
24
|
+
- Fixed Pipeline dashboard panels so their opportunity data loads reliably.
|
|
25
|
+
- Full-page chat keeps the active conversation when moving to and from the sidebar.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# CRM — Development Guide
|
|
2
|
+
|
|
3
|
+
CRM is a React Router + Nitro Agent Native template. The UI and agent share the
|
|
4
|
+
same `actions/` contract; normal client reads and writes use action hooks, not
|
|
5
|
+
custom CRUD routes.
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
|
|
9
|
+
- `pnpm dev` — run the local app
|
|
10
|
+
- `pnpm typecheck` — run the framework typecheck
|
|
11
|
+
- `pnpm test` — run unit tests
|
|
12
|
+
- `pnpm build` — build the React Router and Nitro app
|
|
13
|
+
|
|
14
|
+
## Architecture boundaries
|
|
15
|
+
|
|
16
|
+
- `shared/crm-contract.ts` is the canonical CRM vocabulary and provider-neutral
|
|
17
|
+
contract.
|
|
18
|
+
- `actions/` contains UI/agent operations. Read actions are GET; mutations use
|
|
19
|
+
the shared action surface and must preserve access checks and audit behavior.
|
|
20
|
+
- `server/` owns provider adapters, scoped mirror lifecycle, and startup
|
|
21
|
+
plugins. Use a route only for protocols actions cannot model.
|
|
22
|
+
- `app/` owns the persistent workspace shell and domain views. Keep normal
|
|
23
|
+
data fetching client-side through `useActionQuery` and `useActionMutation`.
|
|
24
|
+
|
|
25
|
+
## Data and provider rules
|
|
26
|
+
|
|
27
|
+
CRM SQL is a thin projection, not a raw HubSpot backup. Only allow-listed
|
|
28
|
+
fields are mirrored; remote-only values are fetched ephemerally and redacted
|
|
29
|
+
values are never fetched or exposed. Store evidence as bounded references and
|
|
30
|
+
quotes only. Raw provider responses, transcripts, media, screenshots, and file
|
|
31
|
+
bodies belong in their source system or approved blob storage, never SQL.
|
|
32
|
+
|
|
33
|
+
Use workspace Connections for credentials. Never add provider tokens to source,
|
|
34
|
+
fixtures, docs, logs, or `.env.example`. Provider API actions are the escape
|
|
35
|
+
hatch for legitimate unmodeled HubSpot or Salesforce requests; stage large
|
|
36
|
+
results and reduce them via data programs instead of loading an unbounded
|
|
37
|
+
payload into chat.
|
|
38
|
+
|
|
39
|
+
## Dashboards
|
|
40
|
+
|
|
41
|
+
CRM owns its dashboard schema, revision history, access policy, data programs,
|
|
42
|
+
and panel resolvers. It composes `@agent-native/toolkit/dashboard` for cards,
|
|
43
|
+
tables, layout, and chart rendering only; never add fetching, provider tokens,
|
|
44
|
+
or direct SQL access to Toolkit components. The Pipeline dashboard is installed
|
|
45
|
+
idempotently through `install-crm-pipeline-dashboard` and reads its bounded
|
|
46
|
+
opportunity data through `get-crm-pipeline-data`.
|
|
47
|
+
|
|
48
|
+
`@agent-native/core/dashboard-storage` is instantiated per app. Keep CRM's
|
|
49
|
+
dashboard rows and revisions scoped through its store, and use the `program`
|
|
50
|
+
panel source for CRM-owned data programs. Add a provider panel source only when
|
|
51
|
+
the CRM adapter can enforce the workspace connection, field policy, and access
|
|
52
|
+
scope.
|
|
53
|
+
|
|
54
|
+
## Signals and provider writes
|
|
55
|
+
|
|
56
|
+
Call evidence is a Clips-owned artifact reference. CRM may store only bounded
|
|
57
|
+
quotes, timestamps, evidence references, confidence, detector/model metadata,
|
|
58
|
+
and review state; it must never store a transcript body, media, or provider
|
|
59
|
+
payload. Keyword trackers run locally. Smart trackers and call summaries must
|
|
60
|
+
delegate to the agent chat, then validate evidence before persisting a signal.
|
|
61
|
+
|
|
62
|
+
Keep provider mutations proposal-first. `update-crm-record` records a
|
|
63
|
+
revision-aware, idempotent proposal for provider-authoritative fields;
|
|
64
|
+
`apply-crm-proposals` is the only path that can invoke an adapter after
|
|
65
|
+
approval. Delegated policy is narrow, access-scoped, and never bypasses the
|
|
66
|
+
field firewall or destructive/bulk gates.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# CRM
|
|
2
|
+
|
|
3
|
+
An agent-native CRM built around a typed, bitemporal record grid. It runs as its
|
|
4
|
+
own system of record on plain SQL, or as a scoped, field-policy-aware companion
|
|
5
|
+
to a connected HubSpot or Salesforce workspace — without making you pick one up
|
|
6
|
+
front, and without the connected mode limiting what you can model locally.
|
|
7
|
+
|
|
8
|
+
Everything the UI does, the agent does, through the same actions and the same
|
|
9
|
+
SQL. `AGENTS.md` is the single source of truth for how the app behaves; the
|
|
10
|
+
`crm` skill is the workflow depth behind it. This README describes the product.
|
|
11
|
+
|
|
12
|
+
## What it is
|
|
13
|
+
|
|
14
|
+
- **A spreadsheet grid over typed attributes.** Seventeen attribute types —
|
|
15
|
+
text, number, checkbox, currency, date, timestamp, rating, status, select,
|
|
16
|
+
record and actor references, location, domain, email, phone, and two
|
|
17
|
+
system-owned ones. Filtering, multi-key sorting, and pagination all run in
|
|
18
|
+
SQL, so a filtered page is the real result set rather than one page narrowed
|
|
19
|
+
after the fact. Keyboard navigation and TSV copy/paste work the way a
|
|
20
|
+
spreadsheet does.
|
|
21
|
+
- **Every value keeps its history.** A field write closes the old row and opens
|
|
22
|
+
a new one with the actor and the time, so a record's stage history _is_ its
|
|
23
|
+
value history — no separate audit table, no "who changed this?" dead end. A
|
|
24
|
+
write that changes nothing stores nothing, so a sync does not inflate history.
|
|
25
|
+
- **Lists and pipelines that are always yours.** A list is a workflow overlay
|
|
26
|
+
over one object type with its own entry attributes. Lists, entries, and entry
|
|
27
|
+
values are local-authoritative on every backend, HubSpot and Salesforce
|
|
28
|
+
included — so you can run a pipeline over connected records without needing a
|
|
29
|
+
single provider write. Time-in-stage falls out of the entry's own history.
|
|
30
|
+
- **Saved views, as tables or boards.** Filter, sort, columns, and audience are
|
|
31
|
+
saved together; a board view groups by any status attribute. `@currentUser` in
|
|
32
|
+
a filter resolves per viewer, so one shared view is everyone's own pipeline.
|
|
33
|
+
- **A record page, not a form.** Typed attribute panel with per-value
|
|
34
|
+
provenance, every list the record belongs to with that entry's own values, its
|
|
35
|
+
interactions and evidence, and a change history for any single value.
|
|
36
|
+
- **Duplicates you can see the reason for.** Detection scores candidates on
|
|
37
|
+
email, company domain, shared root domain, and normalized name, and says which
|
|
38
|
+
one matched. Merge is explicit: you choose the survivor, values the survivor
|
|
39
|
+
lacks are promoted, both sides' entries/tasks/evidence/relationships move
|
|
40
|
+
over, and the loser is tombstoned and linked rather than deleted.
|
|
41
|
+
- **Enrichment behind a two-phase spend gate.** A free verify pass gathers
|
|
42
|
+
evidence; the paid pass runs only over records a human approved, and its input
|
|
43
|
+
set is built from those approvals rather than filtered down to them. Costs are
|
|
44
|
+
estimated per line item and quoted before anything is spent, and a failed
|
|
45
|
+
provider slot is reported as a failure, never as an empty answer.
|
|
46
|
+
- **Call evidence and reviewable signals.** Attach a bounded quote and source
|
|
47
|
+
reference from a Clips recording; run keyword detectors locally and delegate
|
|
48
|
+
smart moments and summaries through the agent chat. Every stored signal cites
|
|
49
|
+
an exact evidence row and waits for a human to confirm or dismiss it.
|
|
50
|
+
- **Command menu and shortcuts.** ⌘K ranks records, lists, and commands
|
|
51
|
+
together, so getting anywhere is one search away rather than a click path.
|
|
52
|
+
- **Admin in the app.** Settings has Connection, Fields, Lists, Intelligence,
|
|
53
|
+
and Advanced tabs — the attribute schema and its managed options are edited
|
|
54
|
+
where the data lives, not in a config file.
|
|
55
|
+
|
|
56
|
+
## Modes
|
|
57
|
+
|
|
58
|
+
- **Native SQL** — CRM is the system of record for accounts, people,
|
|
59
|
+
opportunities, relationships, lists, views, tasks, cadence, and every local
|
|
60
|
+
field. No provider, no sync job, no token. Portable across SQLite, Postgres,
|
|
61
|
+
and D1.
|
|
62
|
+
- **Connected (HubSpot / Salesforce)** — the source CRM stays authoritative for
|
|
63
|
+
its own fields. CRM is a scoped companion for record work, lists, views,
|
|
64
|
+
tasks, evidence, and analysis. HubSpot maps companies/contacts/deals;
|
|
65
|
+
Salesforce maps Account/Contact/Opportunity.
|
|
66
|
+
|
|
67
|
+
Either way, local attributes, lists, and entry values are yours. The `hybrid`
|
|
68
|
+
mode is deprecated: per-attribute authority expresses everything it promised.
|
|
69
|
+
|
|
70
|
+
### Provider writes are a handoff, and say so
|
|
71
|
+
|
|
72
|
+
CRM prepares a provider change as a reviewable proposal, shows the exact
|
|
73
|
+
before/after diff, and opens the record in HubSpot or Salesforce to finish it.
|
|
74
|
+
It does not complete upstream writes and never reports one as applied. That is
|
|
75
|
+
the intended flow, not an error — a proposal awaiting completion is presented as
|
|
76
|
+
the next step, not as a failure.
|
|
77
|
+
|
|
78
|
+
## Guardrails
|
|
79
|
+
|
|
80
|
+
Provider credentials live only in workspace Connections; CRM never accepts,
|
|
81
|
+
stores, or returns a token. The mirror holds configured cohorts and allow-listed
|
|
82
|
+
fields — unknown fields are remote-only, sensitive fields default to redacted.
|
|
83
|
+
Raw provider payloads, transcripts, media, and base64 bodies never enter SQL;
|
|
84
|
+
evidence is a URL or id plus a bounded quote. Ownership, amount, stage,
|
|
85
|
+
deletion, bulk scope, and external side effects always require an exact preview
|
|
86
|
+
and approval. Email and domain are matching signals, never identity keys.
|
|
87
|
+
|
|
88
|
+
Full detail: [`AGENTS.md`](AGENTS.md) for the operating rules, the
|
|
89
|
+
[`crm` skill](.agents/skills/crm/SKILL.md) for workflows, and
|
|
90
|
+
[the CRM contract](docs/architecture/crm-contract.md) for identity, field
|
|
91
|
+
policy, access scope, and the write-policy matrix.
|
|
92
|
+
|
|
93
|
+
## Set up
|
|
94
|
+
|
|
95
|
+
1. Open **Set up CRM** and choose **Start with Native SQL** to use CRM with no
|
|
96
|
+
external service.
|
|
97
|
+
2. To connect a provider, authorize HubSpot or Salesforce in shared **Settings →
|
|
98
|
+
Connections** and grant it to CRM. OAuth and refresh tokens stay in workspace
|
|
99
|
+
Connections. Salesforce production is the default; for a sandbox use
|
|
100
|
+
**Authorize the sandbox directly** on Set up CRM, and the chosen login
|
|
101
|
+
environment is retained for token refresh.
|
|
102
|
+
3. Pick the granted connection and a recent history window. HubSpot may be
|
|
103
|
+
narrowed to deal pipeline IDs; Salesforce starts with recently updated
|
|
104
|
+
Accounts, Contacts, and Opportunities.
|
|
105
|
+
4. CRM mirrors that cohort and its allow-listed fields only. Confirm the
|
|
106
|
+
connection actor's access before relying on a mirrored record.
|
|
107
|
+
|
|
108
|
+
## Local development
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
pnpm install
|
|
112
|
+
pnpm dev
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Set `DATABASE_URL` for persistent deployment storage. Native SQL needs no
|
|
116
|
+
external credentials. Connect providers from the workspace Connections surface;
|
|
117
|
+
never put provider secrets in `.env`.
|
|
118
|
+
|
|
119
|
+
For live testing, use an already-authorized shared Connection, choose a small
|
|
120
|
+
recent cohort, verify the resulting records and access scope, then exercise a
|
|
121
|
+
proposal without completing the provider change. Record only connection labels,
|
|
122
|
+
counts, and non-sensitive results.
|