@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
|
@@ -1872,19 +1872,75 @@ function freshTextHtmlBlock(text: string, stableSource: string): unknown {
|
|
|
1872
1872
|
};
|
|
1873
1873
|
}
|
|
1874
1874
|
|
|
1875
|
-
function assertSafeFreshCalloutNode(node: MdxNode) {
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1875
|
+
function assertSafeFreshCalloutNode(node: MdxNode, raw: string) {
|
|
1876
|
+
const rootStart = node.position?.start?.offset;
|
|
1877
|
+
const visit = (candidate: MdxNode) => {
|
|
1878
|
+
for (const child of candidate.children ?? []) {
|
|
1879
|
+
const childStart = child.position?.start?.offset;
|
|
1880
|
+
const childEnd = child.position?.end?.offset;
|
|
1881
|
+
const childRaw =
|
|
1882
|
+
typeof rootStart === "number" &&
|
|
1883
|
+
typeof childStart === "number" &&
|
|
1884
|
+
typeof childEnd === "number"
|
|
1885
|
+
? raw.slice(childStart - rootStart, childEnd - rootStart).trim()
|
|
1886
|
+
: "";
|
|
1887
|
+
const emptyBlockNode =
|
|
1888
|
+
(child.type === "mdxJsxFlowElement" ||
|
|
1889
|
+
child.type === "mdxJsxTextElement") &&
|
|
1890
|
+
child.name === "empty-block";
|
|
1891
|
+
if (emptyBlockNode) {
|
|
1892
|
+
if (isEmptyEditorBlockSentinel(child, childRaw)) continue;
|
|
1893
|
+
throw new Error(
|
|
1894
|
+
"Unsupported Builder callout empty-block syntax. Only an attribute-free, self-closing Content editor sentinel can be omitted.",
|
|
1895
|
+
);
|
|
1896
|
+
}
|
|
1897
|
+
if (
|
|
1898
|
+
child.type === "mdxFlowExpression" ||
|
|
1899
|
+
child.type === "mdxTextExpression" ||
|
|
1900
|
+
child.type === "mdxjsEsm" ||
|
|
1901
|
+
child.type === "mdxJsxFlowElement" ||
|
|
1902
|
+
child.type === "mdxJsxTextElement"
|
|
1903
|
+
) {
|
|
1904
|
+
throw new Error("Unsupported dynamic syntax inside Builder callout.");
|
|
1905
|
+
}
|
|
1906
|
+
visit(child);
|
|
1885
1907
|
}
|
|
1886
|
-
|
|
1887
|
-
|
|
1908
|
+
};
|
|
1909
|
+
visit(node);
|
|
1910
|
+
}
|
|
1911
|
+
|
|
1912
|
+
function removeSafeCalloutEmptyBlockSentinels(node: MdxNode, raw: string) {
|
|
1913
|
+
const rootStart = node.position?.start?.offset;
|
|
1914
|
+
if (typeof rootStart !== "number") return raw;
|
|
1915
|
+
const ranges: Array<{ start: number; end: number }> = [];
|
|
1916
|
+
|
|
1917
|
+
const visit = (candidate: MdxNode) => {
|
|
1918
|
+
for (const child of candidate.children ?? []) {
|
|
1919
|
+
const start = child.position?.start?.offset;
|
|
1920
|
+
const end = child.position?.end?.offset;
|
|
1921
|
+
if (typeof start !== "number" || typeof end !== "number") {
|
|
1922
|
+
visit(child);
|
|
1923
|
+
continue;
|
|
1924
|
+
}
|
|
1925
|
+
const relativeStart = start - rootStart;
|
|
1926
|
+
const relativeEnd = end - rootStart;
|
|
1927
|
+
const childRaw = raw.slice(relativeStart, relativeEnd).trim();
|
|
1928
|
+
if (isEmptyEditorBlockSentinel(child, childRaw)) {
|
|
1929
|
+
ranges.push({ start: relativeStart, end: relativeEnd });
|
|
1930
|
+
continue;
|
|
1931
|
+
}
|
|
1932
|
+
visit(child);
|
|
1933
|
+
}
|
|
1934
|
+
};
|
|
1935
|
+
visit(node);
|
|
1936
|
+
|
|
1937
|
+
return ranges
|
|
1938
|
+
.sort((left, right) => right.start - left.start)
|
|
1939
|
+
.reduce(
|
|
1940
|
+
(current, range) =>
|
|
1941
|
+
`${current.slice(0, range.start)}${current.slice(range.end)}`,
|
|
1942
|
+
raw,
|
|
1943
|
+
);
|
|
1888
1944
|
}
|
|
1889
1945
|
|
|
1890
1946
|
function findMdxOpeningTagEnd(raw: string) {
|
|
@@ -1936,14 +1992,15 @@ function freshCalloutBlock(
|
|
|
1936
1992
|
`Unsupported Builder callout attribute: ${attribute.name}.`,
|
|
1937
1993
|
);
|
|
1938
1994
|
}
|
|
1939
|
-
assertSafeFreshCalloutNode(node);
|
|
1995
|
+
assertSafeFreshCalloutNode(node, raw);
|
|
1940
1996
|
|
|
1941
|
-
const
|
|
1942
|
-
const
|
|
1997
|
+
const contentRaw = removeSafeCalloutEmptyBlockSentinels(node, raw);
|
|
1998
|
+
const openingEnd = findMdxOpeningTagEnd(contentRaw);
|
|
1999
|
+
const closingStart = contentRaw.lastIndexOf("</callout>");
|
|
1943
2000
|
if (openingEnd < 0 || closingStart < openingEnd) {
|
|
1944
2001
|
throw new Error("Builder callout must have an explicit closing tag.");
|
|
1945
2002
|
}
|
|
1946
|
-
const markdown =
|
|
2003
|
+
const markdown = contentRaw
|
|
1947
2004
|
.slice(openingEnd + 1, closingStart)
|
|
1948
2005
|
.split(/\r?\n/)
|
|
1949
2006
|
.map((line) => line.replace(/^(?:\t| {2})/, ""))
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-native-docs
|
|
3
|
+
description: >-
|
|
4
|
+
How to find version-matched Agent Native framework docs and source bundled in
|
|
5
|
+
node_modules. Use before implementing or answering questions about
|
|
6
|
+
@agent-native/core APIs, generated apps, workspaces, templates, or advanced
|
|
7
|
+
features.
|
|
8
|
+
scope: dev
|
|
9
|
+
metadata:
|
|
10
|
+
internal: true
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Agent Native Docs Lookup
|
|
14
|
+
|
|
15
|
+
## Rule
|
|
16
|
+
|
|
17
|
+
Before implementing or explaining non-trivial Agent Native behavior, read the
|
|
18
|
+
version-matched docs installed with `@agent-native/core`. When examples,
|
|
19
|
+
imports, or implementation details matter, inspect the packaged source corpus
|
|
20
|
+
too.
|
|
21
|
+
|
|
22
|
+
## Why
|
|
23
|
+
|
|
24
|
+
Generated apps and workspaces may be on a different framework version than the
|
|
25
|
+
public docs or model memory. The installed package is the source that matches
|
|
26
|
+
the app in front of you. It also includes a source-only corpus of core and
|
|
27
|
+
first-party templates so agents can replicate current best-practice patterns
|
|
28
|
+
without needing the framework monorepo checkout.
|
|
29
|
+
|
|
30
|
+
## How
|
|
31
|
+
|
|
32
|
+
From a generated app directory:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pnpm action docs-search --query "<feature>"
|
|
36
|
+
pnpm action docs-search --slug <slug>
|
|
37
|
+
pnpm action docs-search --list
|
|
38
|
+
pnpm action source-search --query "<pattern>"
|
|
39
|
+
pnpm action source-search --path templates/plan/AGENTS.md
|
|
40
|
+
pnpm action source-search --path toolkit/src/index.ts
|
|
41
|
+
pnpm action source-search --list
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The headless `pnpm agent` loop and built-in app agent also expose a read-only
|
|
45
|
+
`docs-search` tool with the same `query`, `slug`, and `list` options, plus a
|
|
46
|
+
read-only `source-search` tool with `query`, `path`, and `list`.
|
|
47
|
+
|
|
48
|
+
If the action runner is unavailable, search the package directly:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
rg -n "actions|automations|a2a|sharing" node_modules/@agent-native/core/docs
|
|
52
|
+
rg -n "defineAction|useActionQuery" node_modules/@agent-native/core/corpus
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Then read `node_modules/@agent-native/core/docs/AGENTS.md` or the matching file
|
|
56
|
+
under `node_modules/@agent-native/core/docs/content/`. For source examples,
|
|
57
|
+
read files under `node_modules/@agent-native/core/corpus/core/` or
|
|
58
|
+
`node_modules/@agent-native/core/corpus/templates/`.
|
|
59
|
+
|
|
60
|
+
Toolkit source is searchable at `toolkit/` in the Core corpus and also ships as
|
|
61
|
+
readable TypeScript under `node_modules/@agent-native/toolkit/src/`. Read
|
|
62
|
+
`customizing-agent-native` before taking ownership of a shared component: inspect package
|
|
63
|
+
source as a read-only reference, then configure, compose, or eject the smallest
|
|
64
|
+
supported unit into app-owned source. Preserve public actions, application
|
|
65
|
+
state, auth, and agent-chat runtime contracts. Never edit `node_modules` or
|
|
66
|
+
deep-import its private source. Manual copying is only the fallback described by
|
|
67
|
+
an unknown third-party package's add-style blueprint.
|
|
68
|
+
|
|
69
|
+
## Reuse Proven Patterns (rg + cp)
|
|
70
|
+
|
|
71
|
+
Version-matched installed source outranks web docs or memory: it is the exact
|
|
72
|
+
code shipping with this app. `node_modules/@agent-native/core/corpus/templates/`
|
|
73
|
+
holds source for every first-party template, not just the one this app started
|
|
74
|
+
from, so a pattern from the mail template is fair game for a tasks app. Grep
|
|
75
|
+
across it, then copy a whole file as a starting point instead of writing the
|
|
76
|
+
pattern from scratch:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Find how other templates solved a similar problem
|
|
80
|
+
rg -n "drag.*drop|reorder" node_modules/@agent-native/core/corpus/templates
|
|
81
|
+
|
|
82
|
+
# Grab a proven action file as a starting point, then adapt names/schema
|
|
83
|
+
cp node_modules/@agent-native/core/corpus/templates/mail/actions/archive-email.ts \
|
|
84
|
+
actions/archive-item.ts
|
|
85
|
+
|
|
86
|
+
# Read the full framework source behind an API, not just the corpus copy
|
|
87
|
+
rg -n "defineAction" node_modules/@agent-native/core/src/action.ts
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Copying template-level app code (actions, components, skill files) is the
|
|
91
|
+
expected reuse path — templates exist to be forked. This is different from
|
|
92
|
+
copying `core`/`toolkit` **runtime internals**: for those, follow
|
|
93
|
+
`customizing-agent-native`'s configure/compose/eject ladder instead of
|
|
94
|
+
hand-duplicating framework logic.
|
|
95
|
+
|
|
96
|
+
## Useful Slugs
|
|
97
|
+
|
|
98
|
+
| Need | Slugs |
|
|
99
|
+
| ------------------------------ | ------------------------------------------------------------- |
|
|
100
|
+
| Actions and typed client calls | `actions`, `client` |
|
|
101
|
+
| SQL, auth, access, sharing | `database`, `authentication`, `security`, `sharing` |
|
|
102
|
+
| UI state visible to the agent | `context-awareness` |
|
|
103
|
+
| Headless and chat-first apps | `pure-agent-apps`, `agent-surfaces`, `using-your-agent` |
|
|
104
|
+
| Automations and schedules | `automations`, `recurring-jobs` |
|
|
105
|
+
| Cross-app and external agents | `a2a-protocol`, `external-agents`, `mcp-protocol`, `mcp-apps` |
|
|
106
|
+
| Skills and instructions | `skills-guide`, `writing-agent-instructions` |
|
|
107
|
+
|
|
108
|
+
## Don't
|
|
109
|
+
|
|
110
|
+
- Do not rely on memory for framework APIs when package docs are present.
|
|
111
|
+
- Do not add custom REST wrappers for app data before reading `actions`.
|
|
112
|
+
- Do not add inline LLM calls before reading `using-your-agent` and
|
|
113
|
+
`agent-surfaces`.
|
|
114
|
+
- Do not copy framework runtime internals when a public API or narrow UI copy
|
|
115
|
+
will do; read `customizing-agent-native` for the supported override ladder.
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-native-toolkit
|
|
3
|
+
description: >-
|
|
4
|
+
Inventory and ownership rules for shared Agent Native workspace UI. Use
|
|
5
|
+
before building app chrome, settings, navigation, sharing, collaboration,
|
|
6
|
+
setup, history, comments, chat rails, agent UX, or repeated workspace behavior.
|
|
7
|
+
scope: dev
|
|
8
|
+
metadata:
|
|
9
|
+
internal: true
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Agent-Native Toolkit
|
|
13
|
+
|
|
14
|
+
Use this skill when deciding whether app chrome, settings, collaboration,
|
|
15
|
+
sharing, navigation, organization, setup, history, comments, or agent UX should
|
|
16
|
+
be built app-locally or moved into reusable framework/toolkit pieces.
|
|
17
|
+
|
|
18
|
+
## Core Rule
|
|
19
|
+
|
|
20
|
+
Apps own domain models, domain actions, and product-specific workflows. The
|
|
21
|
+
framework and `@agent-native/toolkit` own repeated workspace behavior users
|
|
22
|
+
expect to work the same everywhere.
|
|
23
|
+
|
|
24
|
+
Move behavior into shared toolkit primitives when it is:
|
|
25
|
+
|
|
26
|
+
- workspace-wide, such as settings, nav, search, org membership, or setup
|
|
27
|
+
- agent-visible, such as context, actions, run progress, or proof-of-done
|
|
28
|
+
- governed, such as secrets, permissions, sharing, audit, or billing
|
|
29
|
+
- repeated by two or more apps
|
|
30
|
+
- not tied to one domain model
|
|
31
|
+
|
|
32
|
+
Keep behavior app-local when the abstraction would hide important domain
|
|
33
|
+
language or make a simple app-specific workflow harder to understand.
|
|
34
|
+
|
|
35
|
+
## Discover Before Building
|
|
36
|
+
|
|
37
|
+
Before creating an app-local version of repeated workspace or agent UI:
|
|
38
|
+
|
|
39
|
+
1. Check the reusable kits below and the installed package documentation.
|
|
40
|
+
2. Search installed public components and source with `docs-search` and
|
|
41
|
+
`source-search`.
|
|
42
|
+
3. Run `agent-native eject --list` to see the version-matched units published
|
|
43
|
+
by the packages installed in this app.
|
|
44
|
+
4. Read `customizing-agent-native` and configure, compose, or eject the
|
|
45
|
+
smallest unit instead of recreating shared behavior from memory.
|
|
46
|
+
|
|
47
|
+
Use public package exports at runtime. Published source and ejection manifests
|
|
48
|
+
are discovery and ownership-transfer mechanisms, not private runtime APIs.
|
|
49
|
+
|
|
50
|
+
## Design-System Boundary
|
|
51
|
+
|
|
52
|
+
Every app keeps an explicit design-system seam in `app/design-system.ts` using
|
|
53
|
+
`defineDesignSystem` from `@agent-native/toolkit/design-system`, and supplies it
|
|
54
|
+
to `ToolkitProvider`. The semantic contract contains:
|
|
55
|
+
|
|
56
|
+
- nine leaf components: `ActionButton`, `IconButton`, `TextField`, `TextArea`,
|
|
57
|
+
`Spinner`, `Skeleton`, `Status`, `Surface`, and `Avatar`
|
|
58
|
+
- eight behavior components: `Tooltip`, `Menu`, `Popover`, `Dialog`, `Picker`,
|
|
59
|
+
`Checkbox`, `Switch`, and `Tabs`
|
|
60
|
+
|
|
61
|
+
These are semantic contracts, not styling contracts. An adapter may use
|
|
62
|
+
Tailwind/shadcn, MUI-style theme providers, React Aria, CSS modules, CSS-in-JS,
|
|
63
|
+
or another React design system. Do not assume CVA, utility classes, or even a
|
|
64
|
+
`className`; behavior adapters may supply their overlay and focus
|
|
65
|
+
implementation wholesale while honoring portal, focus-restoration, keyboard,
|
|
66
|
+
dismissal, ARIA, and z-index interoperability.
|
|
67
|
+
|
|
68
|
+
Pages, routes, and domain components import ordinary controls through the app's
|
|
69
|
+
local adapter layer, usually `@/components/ui/*`. They must not import
|
|
70
|
+
`@agent-native/toolkit/ui/*` directly. Toolkit feature exports are still the
|
|
71
|
+
right home for shared workspace behavior; their presentation flows through the
|
|
72
|
+
registered semantic components, feature controller, and product-level slots.
|
|
73
|
+
|
|
74
|
+
Customer adapter packages are normal npm packages imported explicitly by the
|
|
75
|
+
app. Never auto-detect them or load React components from JSON. Run the adapter
|
|
76
|
+
against `@agent-native/toolkit/conformance` in customer CI before adopting it.
|
|
77
|
+
|
|
78
|
+
## Settings Direction
|
|
79
|
+
|
|
80
|
+
Durable settings belong in the Settings app or a registered settings route. The
|
|
81
|
+
agent sidebar should not become a second settings app. It can show contextual
|
|
82
|
+
quick controls and deep links such as:
|
|
83
|
+
|
|
84
|
+
- `/settings/ai`
|
|
85
|
+
- `/settings/connections`
|
|
86
|
+
- `/settings/secrets`
|
|
87
|
+
- `/settings/usage`
|
|
88
|
+
- `/settings/apps/:appId`
|
|
89
|
+
|
|
90
|
+
The shared Account section is the canonical profile surface at
|
|
91
|
+
`/settings#account`. It owns the editable display name and existing avatar
|
|
92
|
+
control through the authenticated `get-user-profile` and `update-user-profile`
|
|
93
|
+
actions. Shared workspace chrome such as `OrgSwitcher` should link to this
|
|
94
|
+
surface rather than creating an app-local profile page.
|
|
95
|
+
|
|
96
|
+
When adding a new API key, OAuth grant, provider connection, model selector, app
|
|
97
|
+
preference, notification preference, or usage/billing surface, register it as a
|
|
98
|
+
settings tab or app settings panel first. Only add sidebar UI when it is needed
|
|
99
|
+
in the moment of agent use.
|
|
100
|
+
|
|
101
|
+
## Reusable Kits
|
|
102
|
+
|
|
103
|
+
- **Settings kit**: a searchable settings page with account, workspace, AI
|
|
104
|
+
models, LLM keys, connections, secrets, usage, notifications, changelog, and
|
|
105
|
+
app-specific panels. Search is on by default; register a `SettingsSearchEntry`
|
|
106
|
+
per control so users find settings by name across tabs.
|
|
107
|
+
- **Collaboration kit**: Yjs docs, presence, agent presence, live cursors,
|
|
108
|
+
remote selections, recent edit highlights, real-time sync indicators, and
|
|
109
|
+
undo/redo grouping.
|
|
110
|
+
- **Sharing kit**: private/workspace/org/public-link access, invites, roles,
|
|
111
|
+
expirations, agent-readable links, and resource registration.
|
|
112
|
+
- **Navigation and command kit**: app shell, side nav, breadcrumbs, app switcher,
|
|
113
|
+
command palette entries, recent resources, pinned resources, and global search.
|
|
114
|
+
- **Organization kit**: folders, tags, favorites, archive, trash, ownership,
|
|
115
|
+
membership, and common resource metadata.
|
|
116
|
+
- **Setup and connections kit**: declarative setup requirements, model readiness,
|
|
117
|
+
missing-secret states, OAuth grants, and provider connection health.
|
|
118
|
+
- **Agent UX kit**: sidebar, composer, staged context, mentions, voice, human
|
|
119
|
+
approval, generative UI, progress, and screen-state exposure.
|
|
120
|
+
- **Chat history kit**: presentational chat lists and recent-chat rails belong
|
|
121
|
+
in Toolkit; Core keeps thread persistence, agent execution, transport, and
|
|
122
|
+
page-to-sidebar handoff. Use Toolkit's `ChatHistoryRail` for the standard
|
|
123
|
+
five-item sidebar preview and a footer row with New chat followed by an
|
|
124
|
+
ellipsis disclosure up to fifteen. Apps inject routing, labels, and domain
|
|
125
|
+
actions.
|
|
126
|
+
- **Agent page kit**: the full-page `/agent` surface (`AgentTabsPage` from
|
|
127
|
+
`@agent-native/core/client`) with Context, Files, Connections, Jobs, and
|
|
128
|
+
Access tabs plus a Personal/Organization scope toggle. The canonical home
|
|
129
|
+
for context transparency, MCP servers, A2A remote agents, recurring
|
|
130
|
+
jobs/automations, and external-client connect flows. See the `agent-page`
|
|
131
|
+
skill.
|
|
132
|
+
- **History and recovery kit**: audit log, activity feed, version history,
|
|
133
|
+
checkpoints, undo, redo, restore, and proof-of-done.
|
|
134
|
+
- **Comments and review kit**: anchored comments, pins, mentions, review
|
|
135
|
+
requests, resolved threads, agent follow-up tasks, and notifications.
|
|
136
|
+
- **Workflow and observability kit**: notifications, approvals, scheduled work,
|
|
137
|
+
background runs, recurring jobs, traces, evals, feedback, and run timelines.
|
|
138
|
+
|
|
139
|
+
## Implementation Checklist
|
|
140
|
+
|
|
141
|
+
When adding or refactoring one of these areas:
|
|
142
|
+
|
|
143
|
+
1. Search existing framework and template code for duplicated UI or actions.
|
|
144
|
+
2. Decide the shared contract: data shape, action API, feature-level headless
|
|
145
|
+
controller, default view, semantic components, and product-level render
|
|
146
|
+
slots.
|
|
147
|
+
3. Keep shared data provider-agnostic and scoped by auth/sharing rules.
|
|
148
|
+
4. Expose the same capability to the UI and agent through actions or documented
|
|
149
|
+
client helpers.
|
|
150
|
+
5. Register app-specific labels, routes, resource adapters, and settings panels
|
|
151
|
+
instead of hardcoding app names in core UI.
|
|
152
|
+
6. Update docs and relevant skills so future apps discover the shared path.
|
|
153
|
+
7. Keep the component easy to adopt piecemeal: expose props/slots first and
|
|
154
|
+
ship readable source plus a complete ejection unit so apps can take ownership
|
|
155
|
+
of the smallest feature when needed. See `customizing-agent-native` for the
|
|
156
|
+
configure → compose → eject → propose seam ladder.
|
|
157
|
+
8. Keep one controller as the source of truth for the default and custom render
|
|
158
|
+
paths. A custom design must not fork actions, analytics, async state, or
|
|
159
|
+
accessibility behavior.
|
|
160
|
+
9. Verify the default adapter and at least one non-Tailwind adapter with the
|
|
161
|
+
conformance kit, including focus and portal stacking across mixed overlay
|
|
162
|
+
implementations.
|
|
163
|
+
|
|
164
|
+
## Related Skills
|
|
165
|
+
|
|
166
|
+
Read these alongside this skill when the work touches the specific area:
|
|
167
|
+
|
|
168
|
+
- `sharing`
|
|
169
|
+
- `real-time-collab`
|
|
170
|
+
- `real-time-sync`
|
|
171
|
+
- `client-side-routing`
|
|
172
|
+
- `context-awareness`
|
|
173
|
+
- `onboarding`
|
|
174
|
+
- `secrets`
|
|
175
|
+
- `audit-log`
|
|
176
|
+
- `observability`
|
|
177
|
+
- `frontend-design`
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: crm
|
|
3
|
+
description: How to run typed CRM work — attributes and options, lists and pipelines, saved and board views, provider proposals, duplicates and merge, gated enrichment, and evidence-grounded call signals. Use for any CRM read, write, setup, or provider question.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# CRM
|
|
7
|
+
|
|
8
|
+
`AGENTS.md` owns the invariants (attribute typing, bitemporal values, list
|
|
9
|
+
authority, the provider handoff, credential and evidence boundaries). This skill
|
|
10
|
+
is the how: which action, in what order, and the traps in between. Do not
|
|
11
|
+
restate a rule here that `AGENTS.md` already states — fix it there instead.
|
|
12
|
+
|
|
13
|
+
Model source of truth: `shared/crm-contract.ts`. Type registry:
|
|
14
|
+
`shared/crm-attributes.ts`. Every field-value write goes through
|
|
15
|
+
`server/lib/record-fields.ts`.
|
|
16
|
+
|
|
17
|
+
## Pick the starting action
|
|
18
|
+
|
|
19
|
+
- `get-crm-workspace` — "what should I work on", who the caller is, whether
|
|
20
|
+
their provider owner identity resolved. Read `ownerStatus` before trusting an
|
|
21
|
+
empty book: `unmapped`, `ambiguous`, and `unreadable` are different failures,
|
|
22
|
+
and none of them mean "no records".
|
|
23
|
+
- `view-screen` — only when the request depends on the visible record,
|
|
24
|
+
selection, list, or view. `navigate` to show a view rather than describing it.
|
|
25
|
+
- `list-crm-records` / `get-crm-record` / `get-crm-record-page` — ordinary reads.
|
|
26
|
+
- `sync-crm` — one declared, bounded provider cohort. It is not an export-all,
|
|
27
|
+
and Native SQL never needs it.
|
|
28
|
+
|
|
29
|
+
## Setup and modes
|
|
30
|
+
|
|
31
|
+
- `configure-native-crm` starts a local-authoritative CRM with no provider,
|
|
32
|
+
portable across SQLite, Postgres, and D1. Then use the normal record, list,
|
|
33
|
+
task, view, and evidence actions. Never require a connection for Native SQL.
|
|
34
|
+
- After HubSpot or Salesforce is authorized in workspace Connections, register
|
|
35
|
+
it with `configure-crm-connection`. Never pass a token. HubSpot starts with
|
|
36
|
+
companies/contacts/deals; Salesforce with Account/Contact/Opportunity.
|
|
37
|
+
- `list-crm-connections` shows which object types a connection carries — read it
|
|
38
|
+
before authoring attributes on an object type.
|
|
39
|
+
- Salesforce reads are revalidated against the current connection actor and
|
|
40
|
+
field permissions. Never infer a user's access from a service-account mirror
|
|
41
|
+
or a previously visible local row; fail closed when access is ambiguous.
|
|
42
|
+
|
|
43
|
+
## Typed attributes and options
|
|
44
|
+
|
|
45
|
+
- `list-crm-attributes` before any read, write, filter, or grouping. It returns
|
|
46
|
+
the type, cardinality (`multi`), authority, and managed options.
|
|
47
|
+
- `create-crm-attribute` derives an immutable snake_case `apiSlug` from the
|
|
48
|
+
title. `update-crm-attribute` can change presentation, `required`,
|
|
49
|
+
`historyTracked`, config, `archived`, and `fillMode` — never the slug or the
|
|
50
|
+
type, because every stored value row is keyed and typed by them.
|
|
51
|
+
- `manage-crm-attribute-option` adds an option *before* a value that uses it is
|
|
52
|
+
written. Archiving an option removes it from pickers only; records already
|
|
53
|
+
holding it keep the value.
|
|
54
|
+
- `archive-crm-attribute` is a soft archive. Values and history stay. Restore
|
|
55
|
+
with `update-crm-attribute` and `archived: false`.
|
|
56
|
+
- Status options may carry `targetDays` (a stage SLA the grid shows as overrun)
|
|
57
|
+
and `celebrate`.
|
|
58
|
+
|
|
59
|
+
## Reading the grid
|
|
60
|
+
|
|
61
|
+
- `list-crm-records` returns row summaries; `list-crm-record-values` returns the
|
|
62
|
+
cells for those rows with provenance. Filter, sort, and pagination all run in
|
|
63
|
+
SQL, so a filtered page is the real result set, not one page narrowed
|
|
64
|
+
afterwards. Pass `viewId` to apply a saved view's stored filter.
|
|
65
|
+
- A filter naming an unknown or archived attribute fails rather than quietly
|
|
66
|
+
returning unfiltered rows. Do not "fix" that by dropping the filter.
|
|
67
|
+
- `get-crm-record-page` is the whole record surface in one call: attribute
|
|
68
|
+
definitions, current values with actor and time, every list the record is in
|
|
69
|
+
with that entry's values, and the provider deep link.
|
|
70
|
+
|
|
71
|
+
## Lists and pipelines
|
|
72
|
+
|
|
73
|
+
- A list is a workflow overlay over one object type; entry attributes belong to
|
|
74
|
+
the list, not the record. `create-crm-list` seeds a Stage attribute unless you
|
|
75
|
+
pass `seedStageAttribute: false`.
|
|
76
|
+
- `add-crm-record-to-list` never de-duplicates — it returns `existingEntryIds`
|
|
77
|
+
and lets you decide. Two open deals for one company are two entries.
|
|
78
|
+
- **Moving a stage is `update-crm-list-entry`.** It closes the previous value's
|
|
79
|
+
row and opens a new one, so time-in-stage is derivable from the entry's own
|
|
80
|
+
history without a separate audit table.
|
|
81
|
+
- Every `status` write goes through `server/lib/lifecycle.ts`. The enterable set
|
|
82
|
+
is the attribute's own options, so a move into an undeclared or archived stage
|
|
83
|
+
is refused with a sentence naming the values you may pick (`unknown-status`,
|
|
84
|
+
`archived-status`), and the move is claimed against the value it was decided
|
|
85
|
+
from, so a stage somebody else moved in between comes back as
|
|
86
|
+
`concurrent-transition` instead of being clobbered. Leaving any stage —
|
|
87
|
+
including a retired one — is always allowed. On a record, `update-crm-record`
|
|
88
|
+
applies the same gate to local targets; a provider target is still a proposal,
|
|
89
|
+
not a blocked transition.
|
|
90
|
+
- `remove-crm-list-entry` deletes membership and that entry's values only. It is
|
|
91
|
+
not a way to delete a record.
|
|
92
|
+
- `list-crm-record-field-history` reads either side: pass `entryId` for a stage
|
|
93
|
+
history, `recordId` for a record attribute.
|
|
94
|
+
|
|
95
|
+
## Views and boards
|
|
96
|
+
|
|
97
|
+
`save-crm-saved-view` stores filter, ordered sort, columns, `table`/`board`
|
|
98
|
+
presentation, and personal/shared audience. A board view needs a
|
|
99
|
+
`groupByAttributeId` pointing at a status attribute. Pass `expectedUpdatedAt` so
|
|
100
|
+
a concurrent edit is rejected instead of silently overwritten. A view stores
|
|
101
|
+
presentation, never provider rows. `run-crm-saved-view-program` runs the data
|
|
102
|
+
program linked to one view.
|
|
103
|
+
|
|
104
|
+
## Writes and the provider handoff
|
|
105
|
+
|
|
106
|
+
- `update-crm-record` for a scoped typed edit. Provider-owned fields become
|
|
107
|
+
revision-aware, access-checked, idempotent, audited proposals.
|
|
108
|
+
- `list-crm-proposals` then `apply-crm-proposals`: the second returns the exact
|
|
109
|
+
before/after diff and a deep link, and records the handoff. A proposal with
|
|
110
|
+
status `approved` and no `appliedAt` was prepared and handed off — present
|
|
111
|
+
that as the next step for the user, never as a failure and never as applied.
|
|
112
|
+
- The only stored delegation pack is `crm-sales-routine-local-v1`: one routine,
|
|
113
|
+
compensatable local update to one record, supplied by a trusted automation
|
|
114
|
+
trigger, never by action input.
|
|
115
|
+
|
|
116
|
+
## Duplicates and merge
|
|
117
|
+
|
|
118
|
+
`find-crm-duplicates` is read-only and never merges. It matches on exact email,
|
|
119
|
+
company domain, shared email root domain, and normalized name plus location, and
|
|
120
|
+
returns a reason and confidence per candidate. A shared company domain is a
|
|
121
|
+
signal between accounts only — colleagues are a relationship, not a duplicate.
|
|
122
|
+
|
|
123
|
+
`merge-crm-records` needs an explicit survivor. It promotes only the values the
|
|
124
|
+
survivor lacks, moves list entries, tasks, interactions, evidence, signals, and
|
|
125
|
+
relationships from both sides, and tombstones the loser with a `merged-into`
|
|
126
|
+
link instead of deleting it. It is idempotent and approval-gated for non-human
|
|
127
|
+
callers. Show the candidate reasons and let a human pick the survivor.
|
|
128
|
+
|
|
129
|
+
## Enrichment (money changes hands)
|
|
130
|
+
|
|
131
|
+
1. `list-crm-enrichment-slots` — which capability slots are usable. A slot's
|
|
132
|
+
`credential.status` of `unknown` means the lookup itself failed and is *not*
|
|
133
|
+
the same as `missing`.
|
|
134
|
+
2. `estimate-crm-enrichment` — line-item cost and period-to-date spend. Quote it
|
|
135
|
+
to the user. `spendToDate.actorUnits` is theirs and is what the cap applies
|
|
136
|
+
to; `workspaceUnits` is everyone's and is context only.
|
|
137
|
+
3. `run-crm-enrichment` with `phase: "verify"` — free evidence pass, never
|
|
138
|
+
touches contact data. A human reviews its per-record evidence.
|
|
139
|
+
4. `run-crm-enrichment` with `phase: "spend"` — requires `sourceRunId` and the
|
|
140
|
+
explicit `approvedRecordIds` from that review. The paid input set is built
|
|
141
|
+
from those approvals, so an unapproved record is never visible to the paid
|
|
142
|
+
job. Both phases refuse a duplicate in-flight run for the same scope.
|
|
143
|
+
|
|
144
|
+
A slot outcome is one of `unconfigured`, `skipped`, `ok`, `empty`, or `error` —
|
|
145
|
+
report the one you got. "We could not find out" is not "there is none".
|
|
146
|
+
|
|
147
|
+
## Agent attribute fill
|
|
148
|
+
|
|
149
|
+
`run-crm-attribute-fill` is manual only. Call it with no `values` to get the
|
|
150
|
+
brief (attribute, managed options, each record's current value and context),
|
|
151
|
+
reason over that yourself, then call again with `values`. Never call a model
|
|
152
|
+
inline. Writes merge: a human edit or a purchased value is kept and reported as
|
|
153
|
+
`kept-existing`, an equal value is not rewritten. Classifying against a
|
|
154
|
+
status/select attribute must produce one of its managed options; an unknown one
|
|
155
|
+
rejects the whole call and writes nothing.
|
|
156
|
+
|
|
157
|
+
## Evidence and signals
|
|
158
|
+
|
|
159
|
+
- `attach-call-evidence` stores only a source URL/id, bounded quote, timestamp,
|
|
160
|
+
speaker, and metadata. For Clips use a durable `/share/<id>` or `/r/<id>` page
|
|
161
|
+
URL with no access token or transcript fragment — never a `clip.created` event
|
|
162
|
+
URL.
|
|
163
|
+
- `run-crm-signal-trackers` runs only over evidence already attached to the
|
|
164
|
+
record. Keyword hits are deterministic; smart detectors and summaries are
|
|
165
|
+
delegated through agent chat, never a direct model call, and persisted with
|
|
166
|
+
`record-crm-smart-signal` or one atomic `record-crm-call-insight` batch whose
|
|
167
|
+
every quote and timestamp cites an exact stored evidence row.
|
|
168
|
+
- `create-crm-signal-tracker` / `manage-crm-signal-tracker` need editor access.
|
|
169
|
+
Enabling, disabling, and deleting a tracker are local configuration only:
|
|
170
|
+
never a model call, never a provider mutation. Their settings tab is
|
|
171
|
+
`navigate({ view: "settings", settingsSection: "intelligence" })`.
|
|
172
|
+
- `review-crm-signal` is the human confirm/dismiss step.
|
|
173
|
+
- `get-crm-automation-recipe` returns the default-off Clips review recipe for
|
|
174
|
+
one explicitly selected record. The recipe is a configuration aid, not
|
|
175
|
+
permission to activate it: show the exact Clips-owned `clip.created` trigger,
|
|
176
|
+
the selected record, and its one bounded local evidence write, then get a fresh
|
|
177
|
+
approval. The trigger must call `prepare-crm-call-evidence` with the clip id
|
|
178
|
+
and hand back only the durable `/r/<id>` reference. It cannot create tasks,
|
|
179
|
+
field updates, proposals, or provider mutations.
|
|
180
|
+
|
|
181
|
+
## Dashboards
|
|
182
|
+
|
|
183
|
+
`install-crm-pipeline-dashboard` is idempotent and owns one per-user data
|
|
184
|
+
program that calls the bounded `get-crm-pipeline-data` through `appAction`. Do
|
|
185
|
+
not reimplement that aggregate with a provider request or put CRM rows in
|
|
186
|
+
dashboard config. Edit with `save-crm-dashboard` plus `expectedUpdatedAt`;
|
|
187
|
+
inspect and roll back with `list-crm-dashboard-revisions` /
|
|
188
|
+
`restore-crm-dashboard-revision`.
|
|
189
|
+
|
|
190
|
+
## Provider API escape hatch
|
|
191
|
+
|
|
192
|
+
CRM actions are convenience workflows, not a capability ceiling. For an
|
|
193
|
+
endpoint, object, filter, pagination mode, or schema no action expresses, use
|
|
194
|
+
`provider-api-catalog`, then `provider-api-docs`, then the read-only
|
|
195
|
+
`provider-api-request`. Declare a cohort, selected fields, and a page/row budget
|
|
196
|
+
first; stage only that result and reduce it with `query-staged-dataset` or a
|
|
197
|
+
data program. Report provider, scope, filters, page/row counts, truncation, and
|
|
198
|
+
gaps. Always pass the selected workspace `connectionId` for Salesforce so its
|
|
199
|
+
actor-bound token and instance URL cannot be separated.
|
|
200
|
+
|
|
201
|
+
## Out of scope
|
|
202
|
+
|
|
203
|
+
No provider migration, no page builder, no raw provider payload or media in CRM
|
|
204
|
+
SQL. Native SQL supports the canonical CRM objects plus generic custom records; a
|
|
205
|
+
separate object-authoring engine is not part of this template.
|