@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.
Files changed (334) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +24 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/cli/templates-meta.ts +12 -0
  5. package/corpus/core/src/deploy/build.ts +8 -0
  6. package/corpus/core/src/server/builder-browser.ts +76 -0
  7. package/corpus/core/src/server/core-routes-plugin.ts +15 -5
  8. package/corpus/templates/assets/app/global.css +0 -4
  9. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +195 -167
  10. package/corpus/templates/assets/changelog/2026-07-23-drafts-preview-panel-now-fills-the-full-width-with-a-large-p.md +6 -0
  11. package/corpus/templates/content/actions/_builder-cms-source-adapter.ts +1 -0
  12. package/corpus/templates/content/actions/_builder-cms-write-client.ts +55 -9
  13. package/corpus/templates/content/actions/_database-source-utils.ts +756 -182
  14. package/corpus/templates/content/actions/change-content-database-source-role.ts +21 -20
  15. package/corpus/templates/content/actions/execute-builder-source-execution.ts +49 -8
  16. package/corpus/templates/content/actions/materialize-builder-required-fields.ts +42 -9
  17. package/corpus/templates/content/actions/prepare-builder-source-review.ts +88 -90
  18. package/corpus/templates/content/actions/preview-builder-source-review.ts +4 -3
  19. package/corpus/templates/content/actions/refresh-content-database-source.ts +36 -9
  20. package/corpus/templates/content/actions/set-content-database-source-write-mode.ts +28 -24
  21. package/corpus/templates/content/app/components/editor/BubbleToolbar.tsx +62 -12
  22. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +91 -16
  23. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +15 -1
  24. package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +234 -44
  25. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +194 -16
  26. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +95 -42
  27. package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +4 -2
  28. package/corpus/templates/content/app/components/editor/extensions/CodeBlockNode.tsx +10 -166
  29. package/corpus/templates/content/app/components/editor/extensions/VideoBlock.tsx +32 -8
  30. package/corpus/templates/content/app/components/editor/extensions/VideoNode.ts +14 -0
  31. package/corpus/templates/content/app/components/editor/registrySlashItems.ts +5 -1
  32. package/corpus/templates/content/app/hooks/use-content-database.ts +59 -2
  33. package/corpus/templates/content/app/hooks/use-documents.ts +18 -26
  34. package/corpus/templates/content/app/root.tsx +1 -6
  35. package/corpus/templates/content/changelog/2026-07-24-builder-can-now-publish-approved-updates-to-entries-that-are.md +6 -0
  36. package/corpus/templates/content/changelog/2026-07-24-builder-collection-loading-no-longer-restarts-from-the-begin.md +6 -0
  37. package/corpus/templates/content/changelog/2026-07-24-builder-connections-now-complete-securely-from-netlify-deplo.md +6 -0
  38. package/corpus/templates/content/changelog/2026-07-24-builder-draft-creation-now-scopes-execution-to-the-selected-.md +6 -0
  39. package/corpus/templates/content/changelog/2026-07-24-builder-review-now-distinguishes-preparing-a-safe-dry-run-from.md +6 -0
  40. package/corpus/templates/content/changelog/2026-07-24-builder-source-imports-now-recover-from-a-transient-paginati.md +6 -0
  41. package/corpus/templates/content/changelog/2026-07-24-builder-source-refresh-now-preserves-the-provider-bound-fiel.md +6 -0
  42. package/corpus/templates/content/changelog/2026-07-24-builder-update-reviews-now-open-reliably-on-large-collection.md +6 -0
  43. package/corpus/templates/content/changelog/2026-07-24-builder-write-policy-controls-now-reflect-successful-changes.md +6 -0
  44. package/corpus/templates/content/changelog/2026-07-24-date-properties-now-save-reliably-when-selected-with-the-nat.md +6 -0
  45. package/corpus/templates/content/changelog/2026-07-24-editor-slash-search-now-keeps-multi-word-block-names-open.md +6 -0
  46. package/corpus/templates/content/changelog/2026-07-24-exact-editor-slash-commands-now-execute-on-enter-even-if-the.md +6 -0
  47. package/corpus/templates/content/changelog/2026-07-24-new-collaborative-pages-now-save-their-first-edits.md +6 -0
  48. package/corpus/templates/content/changelog/2026-07-24-new-local-builder-rows-no-longer-remain-locked-behind-a-none.md +6 -0
  49. package/corpus/templates/content/changelog/2026-07-24-opening-or-closing-a-collaborative-document-no-longer-lets-u.md +6 -0
  50. package/corpus/templates/content/changelog/2026-07-24-selected-text-now-opens-the-link-editor-with-command-k-or-co.md +6 -0
  51. package/corpus/templates/content/changelog/2026-07-24-slash-menu-block-choices-no-longer-stall-pointer-interaction.md +6 -0
  52. package/corpus/templates/content/changelog/2026-07-24-uploaded-and-embedded-media-now-stay-intact-while-collaborative-document-drafts-save.md +6 -0
  53. package/corpus/templates/content/changelog/2026-07-24-video-link-insertion-now-keeps-its-source-panel-open-while-t.md +6 -0
  54. package/corpus/templates/content/changelog/2026-07-26-builder-publishing-now-shows-safe-validation-details-instead.md +6 -0
  55. package/corpus/templates/content/changelog/2026-07-26-builder-reviews-stay-responsive-on-large-collections-and-pre.md +6 -0
  56. package/corpus/templates/content/changelog/2026-07-26-collaborative-documents-no-longer-flash-duplicated-recent-bl.md +6 -0
  57. package/corpus/templates/content/changelog/2026-07-26-corrected-builder-updates-are-now-reviewed-separately-from-f.md +6 -0
  58. package/corpus/templates/content/changelog/2026-07-26-documents-now-remain-read-only-until-their-live-collaborativ.md +6 -0
  59. package/corpus/templates/content/changelog/2026-07-26-slash-command-menus-now-stay-reachable-when-editing-near-the.md +6 -0
  60. package/corpus/templates/content/changelog/2026-07-26-the-slash-menu-now-shows-one-clear-callout-choice-instead-of.md +6 -0
  61. package/corpus/templates/content/shared/api.ts +1 -0
  62. package/corpus/templates/content/shared/builder-mdx.ts +73 -16
  63. package/corpus/templates/crm/.agents/skills/agent-native-docs/SKILL.md +115 -0
  64. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +177 -0
  65. package/corpus/templates/crm/.agents/skills/crm/SKILL.md +205 -0
  66. package/corpus/templates/crm/.agents/skills/customizing-agent-native/SKILL.md +220 -0
  67. package/corpus/templates/crm/.agents/skills/feature-flags/SKILL.md +169 -0
  68. package/corpus/templates/crm/.agents/skills/sharing/SKILL.md +228 -0
  69. package/corpus/templates/crm/.agents/skills/storing-data/SKILL.md +178 -0
  70. package/corpus/templates/crm/.agents/skills/upgrade-agent-native/SKILL.md +122 -0
  71. package/corpus/templates/crm/.env.example +5 -0
  72. package/corpus/templates/crm/AGENTS.md +82 -0
  73. package/corpus/templates/crm/CHANGELOG.md +25 -0
  74. package/corpus/templates/crm/DEVELOPING.md +66 -0
  75. package/corpus/templates/crm/README.md +122 -0
  76. package/corpus/templates/crm/_gitignore +12 -0
  77. package/corpus/templates/crm/actions/_crm-action-utils.ts +98 -0
  78. package/corpus/templates/crm/actions/_crm-attribute-utils.ts +219 -0
  79. package/corpus/templates/crm/actions/_crm-dashboard.ts +69 -0
  80. package/corpus/templates/crm/actions/_crm-data-program-actions.ts +15 -0
  81. package/corpus/templates/crm/actions/_crm-list-utils.ts +775 -0
  82. package/corpus/templates/crm/actions/_crm-signal-utils.ts +79 -0
  83. package/corpus/templates/crm/actions/add-crm-record-to-list.ts +164 -0
  84. package/corpus/templates/crm/actions/apply-crm-proposals.ts +291 -0
  85. package/corpus/templates/crm/actions/archive-crm-attribute.ts +69 -0
  86. package/corpus/templates/crm/actions/attach-call-evidence.ts +170 -0
  87. package/corpus/templates/crm/actions/configure-crm-connection.ts +126 -0
  88. package/corpus/templates/crm/actions/configure-native-crm.ts +44 -0
  89. package/corpus/templates/crm/actions/create-crm-attribute.ts +350 -0
  90. package/corpus/templates/crm/actions/create-crm-list.ts +194 -0
  91. package/corpus/templates/crm/actions/create-crm-record.ts +148 -0
  92. package/corpus/templates/crm/actions/create-crm-signal-tracker.ts +58 -0
  93. package/corpus/templates/crm/actions/delete-crm-saved-view.ts +68 -0
  94. package/corpus/templates/crm/actions/delete-staged-dataset.ts +14 -0
  95. package/corpus/templates/crm/actions/estimate-crm-enrichment.ts +229 -0
  96. package/corpus/templates/crm/actions/find-crm-duplicates.ts +87 -0
  97. package/corpus/templates/crm/actions/get-crm-automation-recipe.ts +36 -0
  98. package/corpus/templates/crm/actions/get-crm-dashboard-panel.ts +35 -0
  99. package/corpus/templates/crm/actions/get-crm-dashboard.ts +14 -0
  100. package/corpus/templates/crm/actions/get-crm-overview.ts +13 -0
  101. package/corpus/templates/crm/actions/get-crm-pipeline-data.ts +61 -0
  102. package/corpus/templates/crm/actions/get-crm-record-page.ts +287 -0
  103. package/corpus/templates/crm/actions/get-crm-record.ts +75 -0
  104. package/corpus/templates/crm/actions/get-crm-workspace.ts +364 -0
  105. package/corpus/templates/crm/actions/install-crm-pipeline-dashboard.ts +81 -0
  106. package/corpus/templates/crm/actions/list-crm-attributes.ts +71 -0
  107. package/corpus/templates/crm/actions/list-crm-connections.ts +68 -0
  108. package/corpus/templates/crm/actions/list-crm-dashboard-revisions.ts +15 -0
  109. package/corpus/templates/crm/actions/list-crm-dashboards.ts +15 -0
  110. package/corpus/templates/crm/actions/list-crm-enrichment-slots.ts +28 -0
  111. package/corpus/templates/crm/actions/list-crm-list-entries.ts +192 -0
  112. package/corpus/templates/crm/actions/list-crm-lists.ts +80 -0
  113. package/corpus/templates/crm/actions/list-crm-proposals.ts +55 -0
  114. package/corpus/templates/crm/actions/list-crm-record-field-history.ts +201 -0
  115. package/corpus/templates/crm/actions/list-crm-record-values.ts +200 -0
  116. package/corpus/templates/crm/actions/list-crm-records.ts +103 -0
  117. package/corpus/templates/crm/actions/list-crm-saved-views.ts +66 -0
  118. package/corpus/templates/crm/actions/list-crm-signal-hits.ts +43 -0
  119. package/corpus/templates/crm/actions/list-crm-signal-trackers.ts +32 -0
  120. package/corpus/templates/crm/actions/list-crm-tasks.ts +22 -0
  121. package/corpus/templates/crm/actions/list-staged-datasets.ts +14 -0
  122. package/corpus/templates/crm/actions/list-workspace-connections.ts +47 -0
  123. package/corpus/templates/crm/actions/manage-crm-attribute-option.ts +272 -0
  124. package/corpus/templates/crm/actions/manage-crm-signal-tracker.ts +87 -0
  125. package/corpus/templates/crm/actions/manage-crm-task.ts +132 -0
  126. package/corpus/templates/crm/actions/merge-crm-records.ts +691 -0
  127. package/corpus/templates/crm/actions/navigate.ts +54 -0
  128. package/corpus/templates/crm/actions/provider-api-catalog.ts +22 -0
  129. package/corpus/templates/crm/actions/provider-api-docs.ts +54 -0
  130. package/corpus/templates/crm/actions/provider-api-request.ts +92 -0
  131. package/corpus/templates/crm/actions/query-staged-dataset.ts +44 -0
  132. package/corpus/templates/crm/actions/record-crm-call-insight.ts +160 -0
  133. package/corpus/templates/crm/actions/record-crm-smart-signal.ts +150 -0
  134. package/corpus/templates/crm/actions/remove-crm-list-entry.ts +79 -0
  135. package/corpus/templates/crm/actions/restore-crm-dashboard-revision.ts +23 -0
  136. package/corpus/templates/crm/actions/review-crm-signal.ts +31 -0
  137. package/corpus/templates/crm/actions/run-crm-attribute-fill.ts +443 -0
  138. package/corpus/templates/crm/actions/run-crm-enrichment.ts +647 -0
  139. package/corpus/templates/crm/actions/run-crm-saved-view-program.ts +103 -0
  140. package/corpus/templates/crm/actions/run-crm-signal-trackers.ts +265 -0
  141. package/corpus/templates/crm/actions/run.ts +7 -0
  142. package/corpus/templates/crm/actions/save-crm-dashboard.ts +51 -0
  143. package/corpus/templates/crm/actions/save-crm-saved-view.ts +296 -0
  144. package/corpus/templates/crm/actions/sync-crm.ts +146 -0
  145. package/corpus/templates/crm/actions/update-crm-attribute.ts +111 -0
  146. package/corpus/templates/crm/actions/update-crm-list-entry.ts +102 -0
  147. package/corpus/templates/crm/actions/update-crm-list.ts +97 -0
  148. package/corpus/templates/crm/actions/update-crm-record.ts +543 -0
  149. package/corpus/templates/crm/actions/view-screen.ts +324 -0
  150. package/corpus/templates/crm/agent-native.app-skill.json +69 -0
  151. package/corpus/templates/crm/app/components/crm/CreateCrmRecordDialog.tsx +158 -0
  152. package/corpus/templates/crm/app/components/crm/CrmDashboardPanel.tsx +78 -0
  153. package/corpus/templates/crm/app/components/crm/CrmSignalsPanel.tsx +220 -0
  154. package/corpus/templates/crm/app/components/crm/IntelligenceSettings.tsx +414 -0
  155. package/corpus/templates/crm/app/components/crm/RecordActions.tsx +648 -0
  156. package/corpus/templates/crm/app/components/crm/RecordGrid.tsx +488 -0
  157. package/corpus/templates/crm/app/components/crm/RecordWorkspace.tsx +232 -0
  158. package/corpus/templates/crm/app/components/crm/SavedViewDataProgram.tsx +93 -0
  159. package/corpus/templates/crm/app/components/crm/Surface.tsx +97 -0
  160. package/corpus/templates/crm/app/components/crm/WorkOverview.tsx +180 -0
  161. package/corpus/templates/crm/app/components/crm/board/CrmBoard.tsx +988 -0
  162. package/corpus/templates/crm/app/components/crm/board/board-model.ts +399 -0
  163. package/corpus/templates/crm/app/components/crm/board/entry-filter.ts +150 -0
  164. package/corpus/templates/crm/app/components/crm/board/view-draft.ts +227 -0
  165. package/corpus/templates/crm/app/components/crm/grid/CrmGrid.tsx +1033 -0
  166. package/corpus/templates/crm/app/components/crm/grid/GridCell.tsx +620 -0
  167. package/corpus/templates/crm/app/components/crm/grid/clipboard.ts +84 -0
  168. package/corpus/templates/crm/app/components/crm/grid/model.ts +304 -0
  169. package/corpus/templates/crm/app/components/crm/grid/navigation.ts +220 -0
  170. package/corpus/templates/crm/app/components/crm/grid/query.ts +214 -0
  171. package/corpus/templates/crm/app/components/crm/record/AttributePanel.tsx +192 -0
  172. package/corpus/templates/crm/app/components/crm/record/FieldHistory.tsx +179 -0
  173. package/corpus/templates/crm/app/components/crm/record/RecordHeader.tsx +103 -0
  174. package/corpus/templates/crm/app/components/crm/record/RecordLists.tsx +235 -0
  175. package/corpus/templates/crm/app/components/crm/record/RecordTabs.tsx +206 -0
  176. package/corpus/templates/crm/app/components/crm/record/field-editors.tsx +245 -0
  177. package/corpus/templates/crm/app/components/crm/record/record-data.ts +603 -0
  178. package/corpus/templates/crm/app/components/crm/settings/AdvancedSettings.tsx +49 -0
  179. package/corpus/templates/crm/app/components/crm/settings/AttributeOptionsEditor.tsx +441 -0
  180. package/corpus/templates/crm/app/components/crm/settings/ConnectionSettings.tsx +169 -0
  181. package/corpus/templates/crm/app/components/crm/settings/FieldsSettings.tsx +935 -0
  182. package/corpus/templates/crm/app/components/crm/settings/ListsSettings.tsx +339 -0
  183. package/corpus/templates/crm/app/components/crm/settings/settings-admin.ts +377 -0
  184. package/corpus/templates/crm/app/components/crm/shared/AttributeValueParts.tsx +69 -0
  185. package/corpus/templates/crm/app/components/crm/shared/attribute-value.ts +591 -0
  186. package/corpus/templates/crm/app/components/layout/CrmCommandMenu.tsx +556 -0
  187. package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +130 -0
  188. package/corpus/templates/crm/app/components/layout/CrmSidebar.tsx +407 -0
  189. package/corpus/templates/crm/app/components/layout/command-palette-search.ts +126 -0
  190. package/corpus/templates/crm/app/components/layout/crm-ui-intents.ts +41 -0
  191. package/corpus/templates/crm/app/components/layout/sidebar-collapse.ts +40 -0
  192. package/corpus/templates/crm/app/components/layout/sidebar-lists.ts +109 -0
  193. package/corpus/templates/crm/app/components/ui/alert-dialog.tsx +1 -0
  194. package/corpus/templates/crm/app/components/ui/badge.tsx +1 -0
  195. package/corpus/templates/crm/app/components/ui/button.tsx +1 -0
  196. package/corpus/templates/crm/app/components/ui/card.tsx +1 -0
  197. package/corpus/templates/crm/app/components/ui/checkbox.tsx +1 -0
  198. package/corpus/templates/crm/app/components/ui/dialog.tsx +1 -0
  199. package/corpus/templates/crm/app/components/ui/dropdown-menu.tsx +1 -0
  200. package/corpus/templates/crm/app/components/ui/hover-card.tsx +1 -0
  201. package/corpus/templates/crm/app/components/ui/input.tsx +1 -0
  202. package/corpus/templates/crm/app/components/ui/label.tsx +1 -0
  203. package/corpus/templates/crm/app/components/ui/popover.tsx +1 -0
  204. package/corpus/templates/crm/app/components/ui/select.tsx +1 -0
  205. package/corpus/templates/crm/app/components/ui/sheet.tsx +1 -0
  206. package/corpus/templates/crm/app/components/ui/skeleton.tsx +1 -0
  207. package/corpus/templates/crm/app/components/ui/switch.tsx +1 -0
  208. package/corpus/templates/crm/app/components/ui/table.tsx +1 -0
  209. package/corpus/templates/crm/app/components/ui/tabs.tsx +1 -0
  210. package/corpus/templates/crm/app/components/ui/textarea.tsx +1 -0
  211. package/corpus/templates/crm/app/components/ui/toolkit-provider.tsx +17 -0
  212. package/corpus/templates/crm/app/components/ui/tooltip.tsx +1 -0
  213. package/corpus/templates/crm/app/design-system.ts +3 -0
  214. package/corpus/templates/crm/app/entry.client.tsx +19 -0
  215. package/corpus/templates/crm/app/entry.server.tsx +10 -0
  216. package/corpus/templates/crm/app/global.css +167 -0
  217. package/corpus/templates/crm/app/hooks/use-keyboard-shortcuts.ts +206 -0
  218. package/corpus/templates/crm/app/hooks/use-navigation-state.ts +48 -0
  219. package/corpus/templates/crm/app/i18n/en-US.ts +684 -0
  220. package/corpus/templates/crm/app/i18n/index.ts +34 -0
  221. package/corpus/templates/crm/app/lib/dashboard.ts +13 -0
  222. package/corpus/templates/crm/app/lib/navigation.ts +17 -0
  223. package/corpus/templates/crm/app/lib/tab-id.ts +1 -0
  224. package/corpus/templates/crm/app/lib/types.ts +172 -0
  225. package/corpus/templates/crm/app/lib/utils.ts +1 -0
  226. package/corpus/templates/crm/app/root.tsx +93 -0
  227. package/corpus/templates/crm/app/routes/_index.tsx +26 -0
  228. package/corpus/templates/crm/app/routes/accounts.tsx +41 -0
  229. package/corpus/templates/crm/app/routes/agent.tsx +5 -0
  230. package/corpus/templates/crm/app/routes/ask.tsx +53 -0
  231. package/corpus/templates/crm/app/routes/dashboard.tsx +118 -0
  232. package/corpus/templates/crm/app/routes/lists.tsx +228 -0
  233. package/corpus/templates/crm/app/routes/opportunities.tsx +41 -0
  234. package/corpus/templates/crm/app/routes/people.tsx +41 -0
  235. package/corpus/templates/crm/app/routes/proposals.tsx +388 -0
  236. package/corpus/templates/crm/app/routes/records.$recordId.tsx +53 -0
  237. package/corpus/templates/crm/app/routes/records.tsx +64 -0
  238. package/corpus/templates/crm/app/routes/settings.tsx +118 -0
  239. package/corpus/templates/crm/app/routes/setup.tsx +308 -0
  240. package/corpus/templates/crm/app/routes/tasks.tsx +252 -0
  241. package/corpus/templates/crm/app/routes/views.tsx +683 -0
  242. package/corpus/templates/crm/app/routes.ts +19 -0
  243. package/corpus/templates/crm/app/vite-env.d.ts +6 -0
  244. 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
  245. package/corpus/templates/crm/changelog/2026-07-26-crm-now-finds-likely-duplicate-records-and-tells-you-exactly.md +6 -0
  246. package/corpus/templates/crm/changelog/2026-07-26-enrichment-now-shows-what-a-run-will-cost-before-it-starts-g.md +6 -0
  247. package/corpus/templates/crm/changelog/2026-07-26-lists-turn-any-set-of-records-into-a-pipeline-with-its-own-s.md +6 -0
  248. package/corpus/templates/crm/changelog/2026-07-26-moving-a-record-or-list-entry-into-a-stage-that-was-retired-.md +6 -0
  249. package/corpus/templates/crm/changelog/2026-07-26-opening-a-record-now-shows-one-page-with-its-fields-the-list.md +6 -0
  250. 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
  251. package/corpus/templates/crm/changelog/2026-07-26-provider-record-edits-now-show-an-exact-before-after-diff-an.md +6 -0
  252. package/corpus/templates/crm/changelog/2026-07-26-record-page-attribute-labels-now-read-in-full-instead-of-bei.md +6 -0
  253. package/corpus/templates/crm/changelog/2026-07-26-records-now-use-typed-fields-currency-dates-ratings-status-s.md +6 -0
  254. package/corpus/templates/crm/changelog/2026-07-26-retyping-a-value-on-the-record-page-now-replaces-it-instead-.md +6 -0
  255. package/corpus/templates/crm/changelog/2026-07-26-settings-now-has-fields-and-lists-tabs-for-adding-fields-edi.md +6 -0
  256. package/corpus/templates/crm/changelog/2026-07-26-the-proposal-review-now-shows-the-field-that-actually-change.md +6 -0
  257. package/corpus/templates/crm/changelog/2026-07-26-the-record-grid-is-now-a-real-spreadsheet-filter-sort-and-pa.md +6 -0
  258. package/corpus/templates/crm/components.json +20 -0
  259. package/corpus/templates/crm/docs/architecture/crm-contract.md +214 -0
  260. package/corpus/templates/crm/docs/features/README.md +55 -0
  261. package/corpus/templates/crm/docs/features/f1-records-and-fields.mdx +52 -0
  262. package/corpus/templates/crm/docs/features/f2-lists-pipelines-and-views.mdx +48 -0
  263. package/corpus/templates/crm/docs/features/f3-work-and-record-quality.mdx +40 -0
  264. package/corpus/templates/crm/docs/features/f4-evidence-and-chat.mdx +47 -0
  265. package/corpus/templates/crm/learnings.defaults.md +5 -0
  266. package/corpus/templates/crm/netlify.toml +11 -0
  267. package/corpus/templates/crm/package.json +61 -0
  268. package/corpus/templates/crm/public/favicon.svg +1 -0
  269. package/corpus/templates/crm/public/icon-180.svg +1 -0
  270. package/corpus/templates/crm/public/manifest.json +11 -0
  271. package/corpus/templates/crm/react-router.config.ts +7 -0
  272. package/corpus/templates/crm/server/crm/adapter.ts +32 -0
  273. package/corpus/templates/crm/server/crm/crm-field-firewall.ts +64 -0
  274. package/corpus/templates/crm/server/crm/crm-mirror.ts +721 -0
  275. package/corpus/templates/crm/server/crm/field-policy-attributes.ts +48 -0
  276. package/corpus/templates/crm/server/crm/hubspot-adapter.ts +1146 -0
  277. package/corpus/templates/crm/server/crm/native-adapter.ts +1810 -0
  278. package/corpus/templates/crm/server/crm/provider-record-link.ts +264 -0
  279. package/corpus/templates/crm/server/crm/read-through.ts +207 -0
  280. package/corpus/templates/crm/server/crm/salesforce-adapter.ts +1255 -0
  281. package/corpus/templates/crm/server/db/crm-store.ts +1112 -0
  282. package/corpus/templates/crm/server/db/index.ts +191 -0
  283. package/corpus/templates/crm/server/db/schema.ts +647 -0
  284. package/corpus/templates/crm/server/lib/crm-query.ts +1558 -0
  285. package/corpus/templates/crm/server/lib/dedupe.ts +714 -0
  286. package/corpus/templates/crm/server/lib/enrichment-cost.ts +381 -0
  287. package/corpus/templates/crm/server/lib/enrichment-slots.ts +519 -0
  288. package/corpus/templates/crm/server/lib/intelligence/default-detectors.ts +65 -0
  289. package/corpus/templates/crm/server/lib/intelligence/evidence.ts +105 -0
  290. package/corpus/templates/crm/server/lib/intelligence/keyword-detector.ts +94 -0
  291. package/corpus/templates/crm/server/lib/intelligence/smart-detector.ts +39 -0
  292. package/corpus/templates/crm/server/lib/intelligence/summary.ts +19 -0
  293. package/corpus/templates/crm/server/lib/lifecycle.ts +634 -0
  294. package/corpus/templates/crm/server/lib/provider-api.ts +64 -0
  295. package/corpus/templates/crm/server/middleware/auth.ts +4 -0
  296. package/corpus/templates/crm/server/plugins/agent-chat.ts +65 -0
  297. package/corpus/templates/crm/server/plugins/auth.ts +14 -0
  298. package/corpus/templates/crm/server/plugins/core-routes.ts +17 -0
  299. package/corpus/templates/crm/server/plugins/db.ts +738 -0
  300. package/corpus/templates/crm/server/routes/[...page].get.ts +5 -0
  301. package/corpus/templates/crm/shared/crm-attributes.ts +469 -0
  302. package/corpus/templates/crm/shared/crm-automation-recipes.ts +132 -0
  303. package/corpus/templates/crm/shared/crm-contract.ts +417 -0
  304. package/corpus/templates/crm/shared/crm-navigation.ts +190 -0
  305. package/corpus/templates/crm/shared/crm-sales-config.ts +63 -0
  306. package/corpus/templates/crm/ssr-entry.ts +11 -0
  307. package/corpus/templates/crm/tsconfig.json +24 -0
  308. package/corpus/templates/crm/vite.config.ts +15 -0
  309. package/corpus/templates/crm/vitest.config.ts +5 -0
  310. package/corpus/templates/design/app/i18n-data.ts +12 -12
  311. package/corpus/templates/design/changelog/2026-07-26-apply-design-updates-from-a-centered-top-toolbar-without-cov.md +6 -0
  312. package/corpus/toolkit/CHANGELOG.md +6 -0
  313. package/corpus/toolkit/package.json +1 -1
  314. package/corpus/toolkit/src/editor/useCollabReconcile.ts +14 -1
  315. package/dist/cli/templates-meta.d.ts.map +1 -1
  316. package/dist/cli/templates-meta.js +12 -0
  317. package/dist/cli/templates-meta.js.map +1 -1
  318. package/dist/collab/routes.d.ts +2 -2
  319. package/dist/deploy/build.js +6 -0
  320. package/dist/deploy/build.js.map +1 -1
  321. package/dist/observability/routes.d.ts +3 -3
  322. package/dist/server/builder-browser.d.ts +13 -0
  323. package/dist/server/builder-browser.d.ts.map +1 -1
  324. package/dist/server/builder-browser.js +59 -0
  325. package/dist/server/builder-browser.js.map +1 -1
  326. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  327. package/dist/server/core-routes-plugin.js +10 -5
  328. package/dist/server/core-routes-plugin.js.map +1 -1
  329. package/dist/server/transcribe-voice.d.ts +1 -1
  330. package/package.json +2 -2
  331. package/src/cli/templates-meta.ts +12 -0
  332. package/src/deploy/build.ts +8 -0
  333. package/src/server/builder-browser.ts +76 -0
  334. package/src/server/core-routes-plugin.ts +15 -5
@@ -20,7 +20,7 @@ import {
20
20
  import { Decoration, DecorationSet } from "@tiptap/pm/view";
21
21
  import type { Editor } from "@tiptap/react";
22
22
  import { BubbleMenu } from "@tiptap/react/menus";
23
- import { useEffect, useState } from "react";
23
+ import { useCallback, useEffect, useState } from "react";
24
24
 
25
25
  import {
26
26
  Tooltip,
@@ -83,11 +83,35 @@ function selectionIncludesBubbleToolbarExcludedNode(
83
83
  return includesExcludedNode;
84
84
  }
85
85
 
86
+ export function shouldShowBubbleToolbar({
87
+ editor,
88
+ element,
89
+ state,
90
+ from,
91
+ to,
92
+ }: {
93
+ editor: Editor;
94
+ element: HTMLElement;
95
+ state: EditorState;
96
+ from: number;
97
+ to: number;
98
+ }) {
99
+ const focusBelongsToToolbar = element.contains(document.activeElement);
100
+ if (!editor.view.hasFocus() && !focusBelongsToToolbar) return false;
101
+ if (from === to) return false;
102
+ return !selectionIncludesBubbleToolbarExcludedNode(state, from, to);
103
+ }
104
+
86
105
  export function BubbleToolbar({ editor, onComment }: BubbleToolbarProps) {
87
106
  const t = useT();
88
107
  const [showLinkInput, setShowLinkInput] = useState(false);
89
108
  const [linkUrl, setLinkUrl] = useState("");
90
109
 
110
+ const openLinkInput = useCallback(() => {
111
+ setLinkUrl(editor.getAttributes("link").href || "");
112
+ setShowLinkInput(true);
113
+ }, [editor]);
114
+
91
115
  useEffect(() => {
92
116
  const plugin = new Plugin<SelectionFillRange | null>({
93
117
  key: selectionFillPluginKey,
@@ -105,6 +129,29 @@ export function BubbleToolbar({ editor, onComment }: BubbleToolbarProps) {
105
129
  },
106
130
  },
107
131
  props: {
132
+ handleKeyDown(_view, event) {
133
+ if (
134
+ !(event.metaKey || event.ctrlKey) ||
135
+ event.shiftKey ||
136
+ event.altKey ||
137
+ event.key.toLowerCase() !== "k"
138
+ ) {
139
+ return false;
140
+ }
141
+
142
+ const { state } = editor;
143
+ const { from, to } = state.selection;
144
+ if (
145
+ from === to ||
146
+ selectionIncludesBubbleToolbarExcludedNode(state, from, to)
147
+ ) {
148
+ return false;
149
+ }
150
+
151
+ event.preventDefault();
152
+ openLinkInput();
153
+ return true;
154
+ },
108
155
  decorations(state) {
109
156
  const range = selectionFillPluginKey.getState(state);
110
157
  if (!range || range.from === range.to) return DecorationSet.empty;
@@ -153,7 +200,7 @@ export function BubbleToolbar({ editor, onComment }: BubbleToolbarProps) {
153
200
  editor.off("blur", syncSelectionFill);
154
201
  editor.unregisterPlugin(selectionFillPluginKey);
155
202
  };
156
- }, [editor]);
203
+ }, [editor, openLinkInput]);
157
204
 
158
205
  const handleSetLink = () => {
159
206
  if (linkUrl.trim()) {
@@ -175,9 +222,7 @@ export function BubbleToolbar({ editor, onComment }: BubbleToolbarProps) {
175
222
  editor.chain().focus().unsetLink().run();
176
223
  return;
177
224
  }
178
- const previousUrl = editor.getAttributes("link").href || "";
179
- setLinkUrl(previousUrl);
180
- setShowLinkInput(true);
225
+ openLinkInput();
181
226
  };
182
227
 
183
228
  const items = [
@@ -276,12 +321,8 @@ export function BubbleToolbar({ editor, onComment }: BubbleToolbarProps) {
276
321
  <BubbleMenu
277
322
  editor={editor}
278
323
  className="bubble-toolbar"
279
- shouldShow={({ editor, state, from, to }) => {
280
- if (!editor.isFocused) return false;
281
- const isSelection = from !== to;
282
- if (!isSelection) return false;
283
- return !selectionIncludesBubbleToolbarExcludedNode(state, from, to);
284
- }}
324
+ updateDelay={0}
325
+ shouldShow={shouldShowBubbleToolbar}
285
326
  >
286
327
  {showLinkInput ? (
287
328
  <div
@@ -291,6 +332,7 @@ export function BubbleToolbar({ editor, onComment }: BubbleToolbarProps) {
291
332
  <input
292
333
  autoFocus
293
334
  type="url"
335
+ aria-label={t("editor.pasteLink")}
294
336
  placeholder={t("editor.pasteLink")}
295
337
  value={linkUrl}
296
338
  onChange={(e) => setLinkUrl(e.target.value)}
@@ -336,7 +378,15 @@ export function BubbleToolbar({ editor, onComment }: BubbleToolbarProps) {
336
378
  <Tooltip key={title}>
337
379
  <TooltipTrigger asChild>
338
380
  <button
339
- onClick={action}
381
+ onPointerDown={(event) => {
382
+ event.preventDefault();
383
+ event.stopPropagation();
384
+ action();
385
+ }}
386
+ onClick={(event) => {
387
+ if (event.detail === 0) action();
388
+ }}
389
+ aria-label={title}
340
390
  className={cn(
341
391
  "p-2 rounded",
342
392
  isActive()
@@ -145,6 +145,28 @@ export function titleMatchConfirmsSave(args: {
145
145
  );
146
146
  }
147
147
 
148
+ export function refreshUnchangedContentSaveWatermark(args: {
149
+ serverContent: string;
150
+ serverUpdatedAt: string | null;
151
+ lastSaved: ContentSaveWatermark;
152
+ }): ContentSaveWatermark {
153
+ if (
154
+ args.serverContent !== args.lastSaved.content ||
155
+ !args.serverUpdatedAt ||
156
+ (args.lastSaved.updatedAt &&
157
+ args.serverUpdatedAt <= args.lastSaved.updatedAt)
158
+ ) {
159
+ return args.lastSaved;
160
+ }
161
+
162
+ // documents.updatedAt versions the whole row, not just the body. If the
163
+ // fetched body still byte-matches our saved baseline, a newer timestamp can
164
+ // only describe a title/icon/metadata update. Advance the content CAS base so
165
+ // a local rich-text tail is not silently preflight-dropped. A concurrent body
166
+ // edit still differs here and remains protected by the server CAS.
167
+ return { ...args.lastSaved, updatedAt: args.serverUpdatedAt };
168
+ }
169
+
148
170
  function adoptConfirmedSaveWatermarks({
149
171
  saved,
150
172
  savedAt,
@@ -219,7 +241,13 @@ function DocumentUnavailable({ onOpenHome }: { onOpenHome: () => void }) {
219
241
  * an infinite spinner plus repeating 404/403 polls in the console.
220
242
  */
221
243
  export function DocumentEditor({ documentId }: DocumentEditorProps) {
222
- const { data: queriedDocument, isError } = useDocument(documentId);
244
+ const documentQuery = useDocument(documentId);
245
+ const {
246
+ data: queriedDocument,
247
+ isError,
248
+ isFetchedAfterMount,
249
+ isFetching,
250
+ } = documentQuery;
223
251
  const navigate = useNavigate();
224
252
  const document =
225
253
  queriedDocument?.id === documentId ? queriedDocument : undefined;
@@ -230,13 +258,32 @@ export function DocumentEditor({ documentId }: DocumentEditorProps) {
230
258
 
231
259
  // If we have a doc (real or optimistic from create) render the editor —
232
260
  // an `isError` blip during a just-fired create shouldn't flash "not found".
233
- if (!document) {
261
+ // A database/list snapshot can optimistically seed the document cache with a
262
+ // body that predates the latest collaborative save. Mounting ProseMirror from
263
+ // that snapshot lets reconcile briefly insert the stale tail beside the
264
+ // already-current Y.Doc. Wait only for this mount's first dedicated
265
+ // get-document response; later poll/SSE refetches remain live and reconcile
266
+ // without replacing the editor.
267
+ if (
268
+ !document ||
269
+ shouldAwaitAuthoritativeDocument({ isFetching, isFetchedAfterMount })
270
+ ) {
234
271
  return <DocumentEditorSkeleton />;
235
272
  }
236
273
 
237
274
  return <DocumentEditorBody documentId={documentId} document={document} />;
238
275
  }
239
276
 
277
+ export function shouldAwaitAuthoritativeDocument({
278
+ isFetching,
279
+ isFetchedAfterMount,
280
+ }: {
281
+ isFetching: boolean;
282
+ isFetchedAfterMount: boolean;
283
+ }) {
284
+ return isFetching && !isFetchedAfterMount;
285
+ }
286
+
240
287
  interface DocumentEditorBodyProps {
241
288
  documentId: string;
242
289
  document: Document;
@@ -262,6 +309,23 @@ type DocumentSaveResult = {
262
309
  contentPersisted: boolean;
263
310
  };
264
311
 
312
+ export function enqueueDocumentSave<T>(
313
+ queueRef: MutableRefObject<Promise<void>>,
314
+ save: () => Promise<T>,
315
+ ): Promise<T> {
316
+ // Content CAS assumes each local save starts from the result of the previous
317
+ // local save. Debounced typing and structural "save now" operations can
318
+ // otherwise overlap with the same baseUpdatedAt: the shorter request wins,
319
+ // and the later, fuller document is rejected as a conflict. Keep the safety
320
+ // guard and serialize this editor's writes instead of weakening CAS.
321
+ const queued = queueRef.current.then(save, save);
322
+ queueRef.current = queued.then(
323
+ () => undefined,
324
+ () => undefined,
325
+ );
326
+ return queued;
327
+ }
328
+
265
329
  function useMinViewportWidth(minWidth: number) {
266
330
  const [matches, setMatches] = useState(false);
267
331
 
@@ -543,6 +607,7 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
543
607
  const saveTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
544
608
  const promotedBuilderBodyRef = useRef<string | null>(null);
545
609
  const pendingDocumentSaveRef = useRef<PendingDocumentSave | null>(null);
610
+ const documentSaveQueueRef = useRef<Promise<void>>(Promise.resolve());
546
611
  // Separate freshness watermarks for title and content so that a content save
547
612
  // never suppresses adopting a newer external title and vice versa.
548
613
  const lastSavedTitleRef = useRef<{ title: string; updatedAt: string | null }>(
@@ -563,6 +628,8 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
563
628
  document.updatedAt ?? null,
564
629
  );
565
630
  documentUpdatedAtRef.current = document.updatedAt ?? null;
631
+ const documentContentRef = useRef(document.content);
632
+ documentContentRef.current = document.content;
566
633
  const handleBackgroundSaveError = useCallback(
567
634
  (error: unknown) => {
568
635
  toast.error(t("empty.genericError"), {
@@ -651,7 +718,6 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
651
718
  const {
652
719
  ydoc,
653
720
  awareness,
654
- isLoading: collabLoading,
655
721
  isSynced: collabSynced,
656
722
  activeUsers,
657
723
  agentActive,
@@ -663,12 +729,12 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
663
729
  });
664
730
  const bodyHydrationPending = documentBodyHydrationIsPending(document);
665
731
  const editorCanEdit =
666
- canEdit && !bodyHydrationPending && (isLocalFileDocument || !collabLoading);
732
+ canEdit && !bodyHydrationPending && (isLocalFileDocument || collabSynced);
667
733
  // Bind an editor's stable Y.Doc on its first mount, even while the initial
668
- // state is loading. Editability remains gated by `editorCanEdit`, and the
669
- // reconcile hook remains gated by `collabSynced`; keeping the Y.Doc binding
670
- // stable avoids a snapshot -> collab remount that can seed the same SQL body
671
- // beside freshly projected persisted CRDT content.
734
+ // state is loading. Editability and the reconcile hook share the exact
735
+ // `collabSynced` boundary; "not loading" can precede persisted Y.Doc
736
+ // projection and briefly expose duplicated blocks. Keeping the Y.Doc binding
737
+ // stable avoids a snapshot -> collab remount while the read-only editor waits.
672
738
  const collabEditorEnabled = collabEnabled && canEdit && !bodyHydrationPending;
673
739
  canEditRef.current = editorCanEdit;
674
740
 
@@ -912,6 +978,11 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
912
978
  content: string,
913
979
  options: DocumentSaveOptions = {},
914
980
  ): Promise<DocumentSaveResult> => {
981
+ lastSavedContentRef.current = refreshUnchangedContentSaveWatermark({
982
+ serverContent: documentContentRef.current,
983
+ serverUpdatedAt: documentUpdatedAtRef.current,
984
+ lastSaved: lastSavedContentRef.current,
985
+ });
915
986
  // Never clobber a newer server version (e.g. an agent edit we haven't
916
987
  // reconciled into the editor yet) with the editor's current — possibly
917
988
  // stale — content. Guard per-field using the field's own watermark.
@@ -1001,6 +1072,13 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1001
1072
  queryClient,
1002
1073
  ],
1003
1074
  );
1075
+ const queueDocumentSave = useCallback(
1076
+ (title: string, content: string, options: DocumentSaveOptions = {}) =>
1077
+ enqueueDocumentSave(documentSaveQueueRef, () =>
1078
+ saveDocumentImmediately(title, content, options),
1079
+ ),
1080
+ [saveDocumentImmediately],
1081
+ );
1004
1082
  const flushPendingDocumentSave = useCallback(
1005
1083
  (pending: PendingDocumentSave) => {
1006
1084
  if (!pending.canEditWhenQueued) return;
@@ -1019,7 +1097,7 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1019
1097
  const pending: PendingDocumentSave = {
1020
1098
  title,
1021
1099
  content,
1022
- save: saveDocumentImmediately,
1100
+ save: queueDocumentSave,
1023
1101
  canEditWhenQueued: canEditRef.current,
1024
1102
  timeout: setTimeout(() => {
1025
1103
  if (pendingDocumentSaveRef.current === pending) {
@@ -1032,7 +1110,7 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1032
1110
  pendingDocumentSaveRef.current = pending;
1033
1111
  saveTimeoutRef.current = pending.timeout;
1034
1112
  },
1035
- [flushPendingDocumentSave, saveDocumentImmediately],
1113
+ [flushPendingDocumentSave, queueDocumentSave],
1036
1114
  );
1037
1115
 
1038
1116
  useEffect(() => {
@@ -1328,13 +1406,10 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1328
1406
  }
1329
1407
  localContentRef.current = newContent;
1330
1408
  setLocalContent(newContent);
1331
- const result = await saveDocumentImmediately(
1332
- localTitleRef.current,
1333
- newContent,
1334
- );
1409
+ const result = await queueDocumentSave(localTitleRef.current, newContent);
1335
1410
  return result.contentPersisted;
1336
1411
  },
1337
- [editorCanEdit, saveDocumentImmediately],
1412
+ [editorCanEdit, queueDocumentSave],
1338
1413
  );
1339
1414
 
1340
1415
  // Comments state — pending comment from text selection
@@ -1909,7 +1984,7 @@ function DocumentEditorBody({ documentId, document }: DocumentEditorBodyProps) {
1909
1984
  {!bodyHydrationPending &&
1910
1985
  !isLocalFileDocument &&
1911
1986
  canEdit &&
1912
- collabLoading ? (
1987
+ !collabSynced ? (
1913
1988
  <div
1914
1989
  className="mt-4 inline-flex items-center gap-2 rounded-md border border-border bg-muted/40 px-3 py-2 text-xs text-muted-foreground"
1915
1990
  role="status"
@@ -2595,7 +2595,20 @@ function DateValueEditor({
2595
2595
  className="grid gap-2"
2596
2596
  onSubmit={(event) => {
2597
2597
  event.preventDefault();
2598
- void save();
2598
+ const formData = new FormData(event.currentTarget);
2599
+ const submittedStartValue = formData.get("property-start-value");
2600
+ const submittedEndValue = formData.get("property-end-value");
2601
+
2602
+ // Native date controls can update their displayed DOM value before
2603
+ // React receives the corresponding change event. Read the submitted
2604
+ // form so Save never clears a date that is visibly present.
2605
+ void save(
2606
+ buildValue(
2607
+ typeof submittedStartValue === "string" ? submittedStartValue : "",
2608
+ typeof submittedEndValue === "string" ? submittedEndValue : "",
2609
+ formData.has("property-include-time"),
2610
+ ),
2611
+ );
2599
2612
  }}
2600
2613
  >
2601
2614
  <div className="grid grid-cols-2 gap-1">
@@ -2690,6 +2703,7 @@ function DateValueEditor({
2690
2703
  </label>
2691
2704
  <label className="flex items-center gap-2 rounded-md border px-2.5 py-2 text-sm">
2692
2705
  <input
2706
+ name="property-include-time"
2693
2707
  type="checkbox"
2694
2708
  checked={includeTime}
2695
2709
  onChange={(event) => {