@agent-native/core 0.165.3 → 0.167.0

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 (249) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/secrets/SKILL.md +5 -1
  3. package/corpus/templates/analytics/.agents/skills/workspace-conventions/SKILL.md +4 -1
  4. package/corpus/templates/analytics/CHANGELOG.md +740 -2
  5. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +93 -56
  6. package/corpus/templates/analytics/app/i18n-data.ts +23 -20
  7. package/corpus/templates/analytics/app/pages/Settings.tsx +0 -1
  8. package/corpus/templates/analytics/app/pages/adhoc/explorer/index.tsx +0 -1
  9. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +1 -1
  10. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +2 -1
  11. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +0 -1
  12. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +0 -32
  13. package/corpus/templates/analytics/server/lib/session-replay.ts +1 -5
  14. package/corpus/templates/assets/.agents/skills/secrets/SKILL.md +5 -1
  15. package/corpus/templates/assets/.agents/skills/workspace-conventions/SKILL.md +4 -1
  16. package/corpus/templates/assets/CHANGELOG.md +204 -2
  17. package/corpus/templates/assets/actions/navigate.ts +2 -2
  18. package/corpus/templates/assets/actions/save-generated-image.ts +0 -5
  19. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +2 -262
  20. package/corpus/templates/assets/app/routes/library.tsx +1 -1
  21. package/corpus/templates/assets/app/routes/settings.tsx +0 -3
  22. package/corpus/templates/brain/.agents/skills/secrets/SKILL.md +5 -1
  23. package/corpus/templates/brain/.agents/skills/workspace-conventions/SKILL.md +4 -1
  24. package/corpus/templates/brain/CHANGELOG.md +145 -2
  25. package/corpus/templates/brain/actions/ask-brain.ts +0 -1
  26. package/corpus/templates/brain/actions/navigate.ts +2 -2
  27. package/corpus/templates/brain/app/routes/sources.tsx +0 -4
  28. package/corpus/templates/brain/server/lib/capture-sanitization.ts +0 -11
  29. package/corpus/templates/calendar/.agents/skills/secrets/SKILL.md +5 -1
  30. package/corpus/templates/calendar/.agents/skills/workspace-conventions/SKILL.md +4 -1
  31. package/corpus/templates/calendar/CHANGELOG.md +272 -2
  32. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +0 -20
  33. package/corpus/templates/calendar/app/pages/CalendarView.tsx +0 -1
  34. package/corpus/templates/chat/.agents/skills/secrets/SKILL.md +5 -1
  35. package/corpus/templates/chat/.agents/skills/workspace-conventions/SKILL.md +4 -1
  36. package/corpus/templates/chat/CHANGELOG.md +89 -2
  37. package/corpus/templates/chat/actions/navigate.ts +2 -2
  38. package/corpus/templates/clips/.agents/skills/secrets/SKILL.md +5 -1
  39. package/corpus/templates/clips/.agents/skills/workspace-conventions/SKILL.md +4 -1
  40. package/corpus/templates/clips/CHANGELOG.md +865 -2
  41. package/corpus/templates/clips/actions/import-loom-recording.ts +16 -4
  42. package/corpus/templates/clips/actions/navigate.ts +2 -2
  43. package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +0 -1
  44. package/corpus/templates/clips/app/components/library/space-dialogs.tsx +0 -1
  45. package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +0 -1
  46. package/corpus/templates/clips/app/components/player/clips-share-trigger.tsx +17 -0
  47. package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +3 -3
  48. package/corpus/templates/clips/app/components/player/video-player.tsx +2 -2
  49. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +0 -1
  50. package/corpus/templates/clips/app/components/settings/ai-setup-section.tsx +0 -1
  51. package/corpus/templates/clips/app/global.css +31 -0
  52. package/corpus/templates/clips/app/hooks/use-playback-position.ts +0 -2
  53. package/corpus/templates/clips/app/lib/download-release-channel.ts +10 -0
  54. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +1 -3
  55. package/corpus/templates/clips/app/routes/download.tsx +67 -44
  56. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +7 -12
  57. package/corpus/templates/clips/app/routes/record.tsx +6 -6
  58. package/corpus/templates/clips/app/routes/share.$shareId.tsx +26 -29
  59. package/corpus/templates/clips/changelog/2026-08-20-clip-viewer-share-actions.md +6 -0
  60. package/corpus/templates/clips/changelog/2026-08-20-preparing-recording-countdown-overlay.md +6 -0
  61. package/corpus/templates/clips/chrome-extension/src/background.ts +0 -13
  62. package/corpus/templates/clips/chrome-extension/src/overlay.ts +0 -1
  63. package/corpus/templates/clips/chrome-extension/src/popup.ts +0 -20
  64. package/corpus/templates/clips/desktop/src/app.tsx +6 -18
  65. package/corpus/templates/clips/desktop/src/hooks/useMediaDevices.ts +0 -1
  66. package/corpus/templates/clips/desktop/src/lib/recorder.ts +0 -8
  67. package/corpus/templates/clips/desktop/src/overlays/preparing.tsx +4 -6
  68. package/corpus/templates/clips/desktop/src/styles.css +18 -20
  69. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +9 -17
  70. package/corpus/templates/content/.agents/skills/secrets/SKILL.md +5 -1
  71. package/corpus/templates/content/.agents/skills/workspace-conventions/SKILL.md +4 -1
  72. package/corpus/templates/content/CHANGELOG.md +503 -2
  73. package/corpus/templates/content/actions/_database-source-utils.ts +0 -3
  74. package/corpus/templates/content/actions/attach-content-database-source.ts +1 -4
  75. package/corpus/templates/content/actions/navigate.ts +2 -2
  76. package/corpus/templates/content/actions/prepare-builder-source-execution.ts +1 -1
  77. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +0 -6
  78. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +0 -580
  79. package/corpus/templates/content/app/components/editor/database/FormView.tsx +2 -2
  80. package/corpus/templates/content/app/components/editor/database/filter-sort.ts +1 -1
  81. package/corpus/templates/content/app/components/editor/database/settings.tsx +0 -23
  82. package/corpus/templates/content/app/components/editor/database/sidebar.tsx +0 -1
  83. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +8 -304
  84. package/corpus/templates/content/app/hooks/use-documents.ts +0 -1
  85. package/corpus/templates/content/shared/api.ts +0 -1
  86. package/corpus/templates/content/shared/builder-mdx.ts +0 -1
  87. package/corpus/templates/content/shared/nfm.ts +1 -7
  88. package/corpus/templates/crm/.agents/skills/secrets/SKILL.md +5 -1
  89. package/corpus/templates/crm/.agents/skills/workspace-conventions/SKILL.md +4 -1
  90. package/corpus/templates/crm/CHANGELOG.md +31 -2
  91. package/corpus/templates/crm/actions/merge-crm-records.ts +0 -4
  92. package/corpus/templates/crm/app/components/crm/record/RecordLists.tsx +0 -1
  93. package/corpus/templates/crm/server/crm/hubspot-adapter.ts +0 -1
  94. package/corpus/templates/crm/server/crm/salesforce-adapter.ts +0 -1
  95. package/corpus/templates/crm/server/db/crm-store.ts +1 -1
  96. package/corpus/templates/design/.agents/skills/secrets/SKILL.md +5 -1
  97. package/corpus/templates/design/.agents/skills/workspace-conventions/SKILL.md +4 -1
  98. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +1 -14
  99. package/corpus/templates/design/AGENTS.md +2 -1
  100. package/corpus/templates/design/CHANGELOG.md +870 -2
  101. package/corpus/templates/design/actions/apply-component-prop-edit.ts +1 -5
  102. package/corpus/templates/design/actions/generate-design.ts +0 -1
  103. package/corpus/templates/design/actions/generate-screens.ts +5 -2
  104. package/corpus/templates/design/actions/go-to-main-component.ts +2 -2
  105. package/corpus/templates/design/actions/list-design-systems.ts +10 -0
  106. package/corpus/templates/design/actions/navigate.ts +2 -2
  107. package/corpus/templates/design/actions/open-component-source.ts +4 -4
  108. package/corpus/templates/design/actions/present-design-variants.ts +1 -2
  109. package/corpus/templates/design/actions/run-design-audit.ts +0 -22
  110. package/corpus/templates/design/actions/show-design-questions.ts +5 -2
  111. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +19 -8
  112. package/corpus/templates/design/app/components/design/EditPanel.tsx +11 -183
  113. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +21 -4
  114. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +1 -5
  115. package/corpus/templates/design/app/components/design/bridge/codegen.ts +1 -1
  116. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +10 -19
  117. package/corpus/templates/design/app/components/design/edit-panel/appearance-properties.tsx +1 -1
  118. package/corpus/templates/design/app/components/design/edit-panel/layout-properties.tsx +13 -3
  119. package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +38 -32
  120. package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +1 -4
  121. package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +0 -4
  122. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +15 -6
  123. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +2 -2
  124. package/corpus/templates/design/app/components/visual-editor/NodeRewriteProposal.tsx +0 -1
  125. package/corpus/templates/design/app/components/visual-editor/ReviewCanvasPins.tsx +1 -1
  126. package/corpus/templates/design/app/i18n-data.ts +122 -0
  127. package/corpus/templates/design/app/lib/clipboard-content-lineage.ts +11 -1
  128. package/corpus/templates/design/app/pages/DesignEditor.tsx +50 -254
  129. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +163 -8
  130. package/corpus/templates/design/app/pages/Index.tsx +17 -0
  131. package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +44 -32
  132. package/corpus/templates/design/app/pages/design-editor/canvas-primitives.ts +10 -0
  133. package/corpus/templates/design/app/pages/design-editor/clone-and-pen-edit.ts +49 -3
  134. package/corpus/templates/design/app/pages/design-editor/clone-idrefs.ts +31 -0
  135. package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +28 -0
  136. package/corpus/templates/design/app/pages/design-editor/commands/add-auto-layout.ts +3 -3
  137. package/corpus/templates/design/app/pages/design-editor/commands/align-selection.ts +44 -14
  138. package/corpus/templates/design/app/pages/design-editor/commands/apply-local-content-update.ts +16 -5
  139. package/corpus/templates/design/app/pages/design-editor/commands/change-selected-z-index.ts +1 -1
  140. package/corpus/templates/design/app/pages/design-editor/commands/frame-selection.ts +1 -1
  141. package/corpus/templates/design/app/pages/design-editor/commands/group-selection.ts +1 -1
  142. package/corpus/templates/design/app/pages/design-editor/commands/nudge-selection.ts +1 -1
  143. package/corpus/templates/design/app/pages/design-editor/commands/paste-selection.ts +142 -17
  144. package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-duplicate-change.ts +1 -0
  145. package/corpus/templates/design/app/pages/design-editor/commands/ungroup-selection.ts +1 -1
  146. package/corpus/templates/design/app/pages/design-editor/commands/visual-duplicate-change.ts +1 -0
  147. package/corpus/templates/design/app/pages/design-editor/cross-screen-text-color.ts +25 -9
  148. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +1 -0
  149. package/corpus/templates/design/app/pages/design-editor/measure-child-rects.ts +83 -0
  150. package/corpus/templates/design/app/pages/design-editor/paste-placement.ts +66 -0
  151. package/corpus/templates/design/server/routes/[...page].get.ts +0 -1
  152. package/corpus/templates/design/shared/code-layer.ts +120 -70
  153. package/corpus/templates/design/shared/design-surface-index.ts +0 -1
  154. package/corpus/templates/design/shared/pen-path.ts +0 -4
  155. package/corpus/templates/dispatch/.agents/skills/secrets/SKILL.md +5 -1
  156. package/corpus/templates/dispatch/.agents/skills/workspace-conventions/SKILL.md +4 -1
  157. package/corpus/templates/dispatch/CHANGELOG.md +196 -2
  158. package/corpus/templates/dispatch/app/routes/integrations.tsx +0 -109
  159. package/corpus/templates/factory/.agents/skills/secrets/SKILL.md +5 -1
  160. package/corpus/templates/factory/.agents/skills/workspace-conventions/SKILL.md +4 -1
  161. package/corpus/templates/factory/CHANGELOG.md +121 -2
  162. package/corpus/templates/factory/actions/navigate.ts +2 -2
  163. package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +0 -13
  164. package/corpus/templates/factory/app/routes/factory.tsx +0 -1
  165. package/corpus/templates/factory/server/factory-graph/store.ts +0 -1
  166. package/corpus/templates/forms/.agents/skills/secrets/SKILL.md +5 -1
  167. package/corpus/templates/forms/.agents/skills/workspace-conventions/SKILL.md +4 -1
  168. package/corpus/templates/forms/CHANGELOG.md +166 -2
  169. package/corpus/templates/macros/.agents/skills/secrets/SKILL.md +5 -1
  170. package/corpus/templates/macros/.agents/skills/workspace-conventions/SKILL.md +4 -1
  171. package/corpus/templates/macros/CHANGELOG.md +49 -2
  172. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +0 -1
  173. package/corpus/templates/mail/.agents/skills/secrets/SKILL.md +5 -1
  174. package/corpus/templates/mail/.agents/skills/workspace-conventions/SKILL.md +4 -1
  175. package/corpus/templates/mail/CHANGELOG.md +201 -2
  176. package/corpus/templates/mail/app/components/email/EmailList.tsx +0 -1
  177. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +2 -2
  178. package/corpus/templates/mail/shared/markdown.ts +3 -0
  179. package/corpus/templates/plan/.agents/skills/secrets/SKILL.md +5 -1
  180. package/corpus/templates/plan/.agents/skills/workspace-conventions/SKILL.md +4 -1
  181. package/corpus/templates/plan/CHANGELOG.md +277 -2
  182. package/corpus/templates/slides/.agents/skills/secrets/SKILL.md +5 -1
  183. package/corpus/templates/slides/.agents/skills/workspace-conventions/SKILL.md +4 -1
  184. package/corpus/templates/slides/CHANGELOG.md +437 -2
  185. package/corpus/templates/slides/actions/add-slide.ts +0 -1
  186. package/corpus/templates/slides/actions/list-decks.ts +1 -1
  187. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +1 -4
  188. package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +0 -1
  189. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +1 -1
  190. package/corpus/templates/slides/app/pages/DeckEditor.tsx +1 -6
  191. package/corpus/templates/tasks/.agents/skills/secrets/SKILL.md +5 -1
  192. package/corpus/templates/tasks/.agents/skills/workspace-conventions/SKILL.md +4 -1
  193. package/corpus/templates/tasks/CHANGELOG.md +32 -2
  194. package/corpus/templates/tasks/app/components/layout/Layout.tsx +0 -1
  195. package/corpus/templates/tasks/app/hooks/use-visible-task-fields.ts +1 -4
  196. package/corpus/templates/tasks/server/custom-fields/store.ts +1 -6
  197. package/corpus/templates/tasks/shared/list-screen-snapshot.ts +2 -2
  198. package/dist/agent/engine/registry.js +27 -14
  199. package/dist/agent/index.d.ts +1 -1
  200. package/dist/agent/production-agent.d.ts +19 -6
  201. package/dist/agent/production-agent.js +57 -16
  202. package/dist/agent/types.d.ts +3 -0
  203. package/dist/changelog/parse.d.ts +3 -3
  204. package/dist/changelog/parse.js +35 -16
  205. package/dist/client/EnvironmentBadge.d.ts +1 -0
  206. package/dist/client/EnvironmentBadge.js +7 -0
  207. package/dist/collab/awareness.d.ts +2 -2
  208. package/dist/collab/routes.d.ts +1 -1
  209. package/dist/collab/struct-routes.d.ts +1 -1
  210. package/dist/config.d.ts +11 -0
  211. package/dist/config.js +248 -0
  212. package/dist/deploy/build.js +12 -1
  213. package/dist/index.d.ts +1 -1
  214. package/dist/notifications/routes.d.ts +3 -3
  215. package/dist/observability/routes.d.ts +6 -6
  216. package/dist/resources/handlers.d.ts +2 -2
  217. package/dist/secrets/routes.d.ts +9 -9
  218. package/dist/server/agent-chat/plugin-options.d.ts +3 -2
  219. package/dist/server/agent-chat-plugin.js +5 -2
  220. package/dist/server/index.d.ts +1 -1
  221. package/dist/server/realtime-token.d.ts +1 -1
  222. package/dist/server/transcribe-voice.d.ts +1 -1
  223. package/dist/templates/chat/.agents/skills/secrets/SKILL.md +5 -1
  224. package/dist/templates/chat/.agents/skills/workspace-conventions/SKILL.md +4 -1
  225. package/dist/templates/chat/CHANGELOG.md +89 -2
  226. package/dist/templates/chat/actions/navigate.ts +2 -2
  227. package/dist/templates/default/.agents/skills/secrets/SKILL.md +5 -1
  228. package/dist/templates/default/.agents/skills/workspace-conventions/SKILL.md +4 -1
  229. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +5 -1
  230. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +5 -1
  231. package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +4 -1
  232. package/dist/vite/agent-native-config-loader.d.ts +1 -0
  233. package/dist/vite/agent-native-config-loader.js +3 -3
  234. package/dist/vite/agents-bundle-plugin.d.ts +1 -1
  235. package/dist/vite/agents-bundle-plugin.js +13 -1
  236. package/dist/vite/client.js +14 -14
  237. package/docs/content/agent-native-config.mdx +62 -11
  238. package/docs/content/agent-surfaces.mdx +6 -0
  239. package/docs/content/environment-variables.mdx +5 -2
  240. package/package.json +3 -3
  241. package/src/templates/chat/.agents/skills/secrets/SKILL.md +5 -1
  242. package/src/templates/chat/.agents/skills/workspace-conventions/SKILL.md +4 -1
  243. package/src/templates/chat/CHANGELOG.md +89 -2
  244. package/src/templates/chat/actions/navigate.ts +2 -2
  245. package/src/templates/default/.agents/skills/secrets/SKILL.md +5 -1
  246. package/src/templates/default/.agents/skills/workspace-conventions/SKILL.md +4 -1
  247. package/src/templates/headless/.agents/skills/secrets/SKILL.md +5 -1
  248. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +5 -1
  249. package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +4 -1
@@ -45,7 +45,6 @@ import {
45
45
  import {
46
46
  useEffect,
47
47
  useMemo,
48
- useRef,
49
48
  useState,
50
49
  type MouseEvent as ReactMouseEvent,
51
50
  type ReactNode,
@@ -2460,20 +2459,6 @@ function SourceChangeSetReviewCard({
2460
2459
  );
2461
2460
  }
2462
2461
 
2463
- function SourceMetadataRow({ label, value }: { label: string; value: string }) {
2464
- return (
2465
- <div className="flex min-w-0 items-start justify-between gap-3 text-xs">
2466
- <span className="shrink-0 text-muted-foreground">{label}</span>
2467
- <span
2468
- className="min-w-0 max-w-[65%] break-words text-right"
2469
- title={value}
2470
- >
2471
- {value}
2472
- </span>
2473
- </div>
2474
- );
2475
- }
2476
-
2477
2462
  function sourceRiskClass(risk: ContentDatabaseSourceChangeSet["riskLevel"]) {
2478
2463
  return cn(
2479
2464
  "rounded border px-1.5 py-0.5",
@@ -2573,14 +2558,6 @@ function formatRelativeSyncTime(value: string | null): string | null {
2573
2558
  return `${Math.floor(hours / 24)}d ago`;
2574
2559
  }
2575
2560
 
2576
- function sourceBuilderReadModeSummary(source: ContentDatabaseSource) {
2577
- if (source.metadata.liveReadConfigured) return "Builder API read-only";
2578
- if (source.metadata.readMode === "fixture") {
2579
- return "Local fixture; Builder credentials unavailable";
2580
- }
2581
- return "Local fixture";
2582
- }
2583
-
2584
2561
  function sourcePushModeLabel(
2585
2562
  mode: ContentDatabaseSource["metadata"]["pushMode"] | null | undefined,
2586
2563
  ) {
@@ -5,7 +5,6 @@ import type {
5
5
  ContentDatabasePersonalViewOverrides,
6
6
  ContentDatabaseResponse,
7
7
  ContentDatabaseViewConfig,
8
- ContentSidebarOrderMode,
9
8
  ContentSidebarViewOrder,
10
9
  } from "@shared/api";
11
10
  import {
@@ -11,28 +11,12 @@ import { useT } from "@agent-native/core/client/i18n";
11
11
  import { OrgSwitcher } from "@agent-native/core/client/org";
12
12
  import { FeedbackButton } from "@agent-native/core/client/ui";
13
13
  import { SidebarFooterActions } from "@agent-native/toolkit/app-shell";
14
- import {
15
- closestCenter,
16
- DndContext,
17
- KeyboardSensor,
18
- PointerSensor,
19
- useSensor,
20
- useSensors,
21
- type DragEndEvent,
22
- } from "@dnd-kit/core";
23
- import {
24
- arrayMove,
25
- SortableContext,
26
- sortableKeyboardCoordinates,
27
- verticalListSortingStrategy,
28
- } from "@dnd-kit/sortable";
29
14
  import type {
30
15
  ContentDatabaseItem,
31
16
  ContentDatabasePersonalViewOverrides,
32
17
  ContentDatabaseResponse,
33
18
  ContentSidebarViewOrder,
34
19
  Document,
35
- DocumentTreeNode,
36
20
  } from "@shared/api";
37
21
  import { CONTENT_DATABASE_PERSONAL_VIEW_OVERRIDES_VERSION } from "@shared/api";
38
22
  import {
@@ -49,19 +33,11 @@ import {
49
33
  IconLayoutSidebarLeftExpand,
50
34
  IconChevronDown,
51
35
  IconChevronRight,
52
- IconDots,
53
36
  IconTrash,
54
37
  IconGitBranch,
55
38
  } from "@tabler/icons-react";
56
39
  import { useQueryClient } from "@tanstack/react-query";
57
- import {
58
- useCallback,
59
- useEffect,
60
- useMemo,
61
- useRef,
62
- useState,
63
- type ReactNode,
64
- } from "react";
40
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
65
41
  import { Link, useLocation, useNavigate } from "react-router";
66
42
  import { toast } from "sonner";
67
43
 
@@ -87,7 +63,6 @@ import {
87
63
  DropdownMenuItem,
88
64
  DropdownMenuRadioGroup,
89
65
  DropdownMenuRadioItem,
90
- DropdownMenuSeparator,
91
66
  DropdownMenuTrigger,
92
67
  } from "@/components/ui/dropdown-menu";
93
68
  import { ScrollArea } from "@/components/ui/scroll-area";
@@ -121,11 +96,9 @@ import {
121
96
  useCreateDocument,
122
97
  useDeleteDocument,
123
98
  usePermanentlyDeleteDocument,
124
- useMoveDocument,
125
99
  useRestoreDocument,
126
100
  useTrashedDocuments,
127
101
  useUpdateDocument,
128
- buildDocumentTree,
129
102
  filterDocumentTreeDocuments,
130
103
  documentQueryFilter,
131
104
  rollbackOptimisticCreatedDocument,
@@ -148,11 +121,8 @@ import {
148
121
  } from "@/lib/optimistic-document";
149
122
  import { cn } from "@/lib/utils";
150
123
 
151
- import {
152
- getDocumentSidebarSections,
153
- isDirectLocalDocument,
154
- } from "./document-sidebar-sections";
155
- import { DocumentSidebarIcon, DocumentTreeItem } from "./DocumentTreeItem";
124
+ import { getDocumentSidebarSections } from "./document-sidebar-sections";
125
+ import { DocumentSidebarIcon } from "./DocumentTreeItem";
156
126
  import {
157
127
  firstLocalSourceDocumentId,
158
128
  localSourceItemIdentity,
@@ -903,13 +873,13 @@ export function DocumentSidebar({
903
873
  [t],
904
874
  );
905
875
  const documentsQuery = useDocuments();
906
- const { data: documents = [], isLoading } = documentsQuery;
876
+ const { data: documents = [] } = documentsQuery;
907
877
  const createDocument = useCreateDocument();
908
878
  const createDatabase = useCreateContentDatabase(null);
909
879
  const deleteContentDatabase = useDeleteContentDatabase();
910
880
  const deleteDocument = useDeleteDocument();
911
881
  const permanentlyDeleteDocument = usePermanentlyDeleteDocument();
912
- const moveDocument = useMoveDocument();
882
+
913
883
  const restoreDocument = useRestoreDocument();
914
884
  const { data: trashedDocuments } = useTrashedDocuments();
915
885
  const restoreContentDatabase = useRestoreContentDatabase();
@@ -1176,7 +1146,6 @@ export function DocumentSidebar({
1176
1146
  // Track user-expanded nodes only; active ancestors are derived below so they
1177
1147
  // do not stay open after navigation unless the user explicitly expanded them.
1178
1148
  const expandedIdsRef = useRef(new Set<string>());
1179
- const [, forceUpdate] = useState(0);
1180
1149
  const [isResizing, setIsResizing] = useState(false);
1181
1150
  const [storedCollapsedSections, setStoredCollapsedSections] = useLocalStorage<
1182
1151
  Partial<Record<SidebarSectionId, boolean>>
@@ -1208,14 +1177,6 @@ export function DocumentSidebar({
1208
1177
  } | null>(null);
1209
1178
  const confirmedDeleteIdRef = useRef<string | null>(null);
1210
1179
  const settingsActive = location.pathname.startsWith("/settings");
1211
- const sensors = useSensors(
1212
- useSensor(PointerSensor, {
1213
- activationConstraint: { distance: 6 },
1214
- }),
1215
- useSensor(KeyboardSensor, {
1216
- coordinateGetter: sortableKeyboardCoordinates,
1217
- }),
1218
- );
1219
1180
 
1220
1181
  const handleMouseDown = useCallback(
1221
1182
  (e: React.MouseEvent) => {
@@ -1247,20 +1208,9 @@ export function DocumentSidebar({
1247
1208
  );
1248
1209
 
1249
1210
  const treeDocuments = filterDocumentTreeDocuments(documents);
1250
- const {
1251
- localFileMode,
1252
- localSourceDocuments,
1253
- databaseDocuments,
1254
- showFavorites,
1255
- } = getDocumentSidebarSections(documents, treeDocuments);
1256
- const localFileTree = buildDocumentTree(localSourceDocuments);
1257
- const databaseTree = buildDocumentTree(databaseDocuments);
1258
- const importedLocalFileCount = localFileMode
1259
- ? 0
1260
- : localSourceDocuments.filter(
1261
- (document) => document.source?.kind !== "folder",
1262
- ).length;
1263
- const canRemoveLocalFiles = localFileMode || importedLocalFileCount > 0;
1211
+ const { localFileMode, databaseDocuments, showFavorites } =
1212
+ getDocumentSidebarSections(documents, treeDocuments);
1213
+
1264
1214
  const activeDocument = activeDocumentId
1265
1215
  ? documents.find((doc) => doc.id === activeDocumentId)
1266
1216
  : null;
@@ -1286,19 +1236,6 @@ export function DocumentSidebar({
1286
1236
  const expandedIds = new Set(expandedIdsRef.current);
1287
1237
  for (const id of activeAncestorIds) expandedIds.add(id);
1288
1238
 
1289
- const handleToggleExpanded = useCallback(
1290
- (id: string) => {
1291
- if (activeAncestorIds.has(id)) return;
1292
- if (expandedIdsRef.current.has(id)) {
1293
- expandedIdsRef.current.delete(id);
1294
- } else {
1295
- expandedIdsRef.current.add(id);
1296
- }
1297
- forceUpdate((n) => n + 1);
1298
- },
1299
- [activeAncestorIds],
1300
- );
1301
-
1302
1239
  const navigateToDocument = useCallback(
1303
1240
  (id: string) => {
1304
1241
  navigate(`/page/${id}`, { flushSync: true });
@@ -1587,89 +1524,6 @@ export function DocumentSidebar({
1587
1524
  });
1588
1525
  }, []);
1589
1526
 
1590
- const handleReorderPage = useCallback(
1591
- async (id: string, overId: string) => {
1592
- if (id === overId) return;
1593
- const current = documents.find((doc) => doc.id === id);
1594
- const target = documents.find((doc) => doc.id === overId);
1595
- if (!current || !target) return;
1596
- if (current.parentId !== target.parentId) {
1597
- return;
1598
- }
1599
-
1600
- const siblings = documents
1601
- .filter((doc) => doc.parentId === current.parentId)
1602
- .sort(compareDocumentsByPosition);
1603
- const currentIndex = siblings.findIndex((doc) => doc.id === id);
1604
- const nextIndex = siblings.findIndex((doc) => doc.id === overId);
1605
- if (currentIndex < 0 || nextIndex < 0 || currentIndex === nextIndex) {
1606
- return;
1607
- }
1608
-
1609
- const reordered = arrayMove(siblings, currentIndex, nextIndex);
1610
- const nextPositionById = new Map(
1611
- reordered.map((doc, index) => [doc.id, index]),
1612
- );
1613
- const changed = reordered.filter(
1614
- (doc) => doc.position !== nextPositionById.get(doc.id),
1615
- );
1616
- if (changed.length === 0) return;
1617
- if (changed.some((doc) => doc.canEdit === false)) {
1618
- toast.error(t("sidebar.cannotReorderPages"), {
1619
- description: t("sidebar.oneAffectedPageReadOnly"),
1620
- });
1621
- return;
1622
- }
1623
-
1624
- queryClient.setQueryData(LIST_DOCUMENTS_QUERY_KEY, (old: unknown) => {
1625
- const cachedDocs: Document[] =
1626
- (old as { documents?: Document[] })?.documents ??
1627
- (Array.isArray(old) ? old : documents);
1628
- const nextDocs = cachedDocs.map((doc) => {
1629
- const nextPosition = nextPositionById.get(doc.id);
1630
- return nextPosition === undefined
1631
- ? doc
1632
- : { ...doc, position: nextPosition };
1633
- });
1634
- return withDocumentsCacheShape(old, nextDocs);
1635
- });
1636
-
1637
- try {
1638
- await Promise.all(
1639
- changed.map((doc) =>
1640
- moveDocument.mutateAsync({
1641
- id: doc.id,
1642
- position: nextPositionById.get(doc.id)!,
1643
- }),
1644
- ),
1645
- );
1646
- } catch (err) {
1647
- queryClient.invalidateQueries({
1648
- queryKey: ["action", "list-documents"],
1649
- });
1650
- toast.error(t("sidebar.failedMovePage"), {
1651
- description:
1652
- err instanceof Error ? err.message : t("empty.genericError"),
1653
- });
1654
- }
1655
- },
1656
- [documents, moveDocument, queryClient],
1657
- );
1658
-
1659
- const handleDragEnd = useCallback(
1660
- (event: DragEndEvent) => {
1661
- const { active, over } = event;
1662
- const activeId = String(active.id);
1663
- const overId = over ? String(over.id) : null;
1664
- if (!overId || activeId === overId) return;
1665
- if (parentByDocumentId.get(activeId) !== parentByDocumentId.get(overId)) {
1666
- return;
1667
- }
1668
- void handleReorderPage(activeId, overId);
1669
- },
1670
- [handleReorderPage, parentByDocumentId],
1671
- );
1672
-
1673
1527
  const handlePinnedReorder = useCallback(
1674
1528
  (_itemIds: string[], moved: { itemId: string; position: number }) => {
1675
1529
  if (!favoritesDatabaseId) return;
@@ -1829,33 +1683,6 @@ export function DocumentSidebar({
1829
1683
  )
1830
1684
  : null;
1831
1685
 
1832
- const renderDocumentTree = (nodes: DocumentTreeNode[]) => (
1833
- <SortableContext
1834
- items={nodes.map((node) => node.id)}
1835
- strategy={verticalListSortingStrategy}
1836
- >
1837
- {nodes.map((node) => (
1838
- <DocumentTreeItem
1839
- key={node.id}
1840
- node={node}
1841
- depth={0}
1842
- sidebarWidth={width}
1843
- activeId={activeDocumentId}
1844
- expandedIds={expandedIds}
1845
- onToggleExpanded={handleToggleExpanded}
1846
- onSelect={(id) => {
1847
- navigateToDocument(id);
1848
- onNavigate?.();
1849
- }}
1850
- onCreateChildPage={(parentId) => handleCreatePage(parentId)}
1851
- onCreateChildDatabase={(parentId) => handleCreateDatabase(parentId)}
1852
- onDelete={requestDelete}
1853
- onToggleFavorite={handleToggleFavorite}
1854
- />
1855
- ))}
1856
- </SortableContext>
1857
- );
1858
-
1859
1686
  const renderNewButton = (space = selectedSpace) =>
1860
1687
  space ? (
1861
1688
  <button
@@ -1989,78 +1816,6 @@ export function DocumentSidebar({
1989
1816
  });
1990
1817
  };
1991
1818
 
1992
- const renderLocalFilesSectionActions = () => (
1993
- <DropdownMenu>
1994
- <Tooltip>
1995
- <TooltipTrigger asChild>
1996
- <DropdownMenuTrigger asChild>
1997
- <button
1998
- type="button"
1999
- aria-label={t("sidebar.localFilesActions")}
2000
- className="flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground"
2001
- >
2002
- <IconDots size={14} />
2003
- </button>
2004
- </DropdownMenuTrigger>
2005
- </TooltipTrigger>
2006
- <TooltipContent>{t("sidebar.localFilesActions")}</TooltipContent>
2007
- </Tooltip>
2008
- <DropdownMenuContent align="end" className="w-56">
2009
- <DropdownMenuItem asChild>
2010
- <Link to="/local-files">
2011
- <IconFolderOpen className="me-2 size-4" />
2012
- {t("sidebar.manageLocalFolders")}
2013
- </Link>
2014
- </DropdownMenuItem>
2015
- {canRemoveLocalFiles && (
2016
- <>
2017
- <DropdownMenuSeparator />
2018
- <DropdownMenuItem
2019
- className="text-destructive focus:text-destructive"
2020
- disabled={removeLocalFileSource.isPending}
2021
- onSelect={(event) => {
2022
- event.preventDefault();
2023
- setRemoveLocalFilesDialogOpen(true);
2024
- }}
2025
- >
2026
- <IconTrash className="me-2 size-4" />
2027
- {t("sidebar.removeLocalFilesFromSidebar")}
2028
- </DropdownMenuItem>
2029
- </>
2030
- )}
2031
- </DropdownMenuContent>
2032
- </DropdownMenu>
2033
- );
2034
-
2035
- const renderSectionHeader = (
2036
- id: SidebarSectionId,
2037
- label: string,
2038
- actions?: ReactNode,
2039
- ) => {
2040
- const collapsed = collapsedSections[id];
2041
- return (
2042
- <div className="flex min-w-0 items-center gap-1 px-1">
2043
- <button
2044
- type="button"
2045
- aria-expanded={!collapsed}
2046
- className="flex min-w-0 flex-1 items-center gap-1 rounded-md px-2 py-1.5 text-start text-[10px] font-semibold uppercase tracking-wider text-muted-foreground hover:bg-accent/40 hover:text-foreground"
2047
- onClick={() => toggleSection(id)}
2048
- >
2049
- <IconChevronRight
2050
- size={12}
2051
- className={cn(
2052
- "shrink-0 transition-transform",
2053
- !collapsed && "rotate-90",
2054
- "rtl:-scale-x-100",
2055
- )}
2056
- />
2057
- <span className="min-w-0 flex-1 truncate">{label}</span>
2058
- </button>
2059
- {actions}
2060
- </div>
2061
- );
2062
- };
2063
-
2064
1819
  const renderTreeSkeleton = () => (
2065
1820
  <div aria-hidden="true" className="grid gap-1 px-3 py-1">
2066
1821
  {[70, 55, 85, 60, 45].map((w, i) => (
@@ -2075,57 +1830,6 @@ export function DocumentSidebar({
2075
1830
  </div>
2076
1831
  );
2077
1832
 
2078
- const renderTreeSection = ({
2079
- id,
2080
- label,
2081
- nodes,
2082
- emptyLabel,
2083
- className,
2084
- headerActions,
2085
- footer,
2086
- }: {
2087
- id: SidebarSectionId;
2088
- label: string;
2089
- nodes: DocumentTreeNode[];
2090
- emptyLabel: string;
2091
- className?: string;
2092
- headerActions?: ReactNode;
2093
- footer?: ReactNode;
2094
- }) => {
2095
- const collapsed = collapsedSections[id];
2096
- return (
2097
- <div className={className}>
2098
- {renderSectionHeader(id, label, headerActions)}
2099
- {!collapsed && (
2100
- <>
2101
- <DndContext
2102
- sensors={sensors}
2103
- collisionDetection={closestCenter}
2104
- onDragEnd={handleDragEnd}
2105
- >
2106
- {isLoading ? (
2107
- renderTreeSkeleton()
2108
- ) : documentsQuery.isError ? (
2109
- <QueryErrorState
2110
- compact
2111
- onRetry={() => void documentsQuery.refetch()}
2112
- retrying={documentsQuery.isFetching}
2113
- />
2114
- ) : nodes.length === 0 ? (
2115
- <div className="px-3 py-4 text-center text-sm text-muted-foreground">
2116
- {emptyLabel}
2117
- </div>
2118
- ) : (
2119
- renderDocumentTree(nodes)
2120
- )}
2121
- </DndContext>
2122
- {footer}
2123
- </>
2124
- )}
2125
- </div>
2126
- );
2127
- };
2128
-
2129
1833
  const renderWorkspaceRoot = (
2130
1834
  space: ContentSpaceSummary,
2131
1835
  reorder?: ContentFilesSidebarRenderReorder,
@@ -23,7 +23,6 @@ import { toast } from "sonner";
23
23
  import type { DocumentUpdateConflictResponse } from "../../actions/update-document";
24
24
  import {
25
25
  documentQueryFilter,
26
- documentQueryKey,
27
26
  type DocumentQueryContext,
28
27
  } from "../lib/document-query";
29
28
  import {
@@ -1,7 +1,6 @@
1
1
  import type { BlocksFieldIdentity } from "./blocks-field-identity";
2
2
  import type {
3
3
  DocumentPropertyOptions,
4
- DocumentPropertyOption,
5
4
  DocumentPropertyType,
6
5
  DocumentPropertyValue,
7
6
  DocumentPropertyVisibility,
@@ -18,7 +18,6 @@ import {
18
18
  } from "./nfm-registry";
19
19
  import type {
20
20
  SourceComponentData,
21
- SourceComponentPreview,
22
21
  SourceComponentPreviewTable,
23
22
  } from "./source-component-block";
24
23
 
@@ -42,7 +42,7 @@
42
42
  */
43
43
 
44
44
  import { matchInlineMathAt } from "./inline-math.js";
45
- import { isRegistryBlockTag, registryBlockSpecByTag } from "./nfm-registry.js";
45
+ import { registryBlockSpecByTag } from "./nfm-registry.js";
46
46
 
47
47
  // ── Shared PM JSON types ────────────────────────────────────────────
48
48
  export interface PMMark {
@@ -945,11 +945,6 @@ function serializeBlock(node: PMNode, indent: number): string[] {
945
945
  }
946
946
  }
947
947
 
948
- function serializeChildrenAfterFirst(node: PMNode, indent: number): string[] {
949
- const children = (node.content || []).slice(1);
950
- return serializeBlocks(children, indent);
951
- }
952
-
953
948
  function serializeQuote(node: PMNode, ind: number): string[] {
954
949
  const textPara = firstParagraph(node);
955
950
  const out: string[] = [];
@@ -1998,7 +1993,6 @@ function parseContainer(
1998
1993
  return { nodes: [withIndentAttr(node)], end: start + 1 };
1999
1994
  }
2000
1995
  const closeIdx = i;
2001
- const innerEnd = closeIdx;
2002
1996
 
2003
1997
  // <details> with a <summary> on the next line.
2004
1998
  if (tagKey === "<details") {
@@ -38,7 +38,11 @@ connection exists:
38
38
  register a `kind: "oauth"` entry so the shared UI renders Connect and the
39
39
  runtime owns status, refresh, and reauthorization.
40
40
  - **Deploy- or app-level configuration** - use deployment/runtime
41
- configuration, not a per-user secret row.
41
+ configuration, not a per-user secret row. For a non-secret public setting
42
+ already represented by `AgentNativeConfig`, put the default in
43
+ `agent-native.config.ts` and use its `AGENT_NATIVE_CONFIG_<PATH>` alias only
44
+ for a deployment override. Never put a credential or provider key in that
45
+ public namespace.
42
46
  - **Account, customer, manager, or other non-secret identifier** - store it as
43
47
  scoped connection metadata or app data, not as a masked secret field.
44
48
 
@@ -55,7 +55,10 @@ Preview before `--apply`, commit `agent-native.ejections.json`, and never edit
55
55
  ZIPs, screenshots, thumbnails, session replay chunks) in configured file/blob
56
56
  storage and persist only URLs, ids, or handles.
57
57
  - Store shared runtime configuration in the workspace root `.env`; use
58
- `apps/<app>/.env` only for app-specific overrides. Never hardcode API keys,
58
+ `apps/<app>/.env` only for app-specific overrides. For public app behavior,
59
+ prefer the default in `agent-native.config.ts` and use the deterministic
60
+ `AGENT_NATIVE_CONFIG_<UPPER_SNAKE_PATH>` alias only when a non-secret value
61
+ needs a deployment override. Never hardcode API keys,
59
62
  tokens, webhook URLs, signing secrets, private Builder/internal data, customer
60
63
  data, or credential-looking literals in source, docs, prompts, fixtures,
61
64
  application state, action responses, or generated app content. Use
@@ -1,7 +1,5 @@
1
1
  # CRM changelog
2
2
 
3
- Older updates live in [the changelog folder](./changelog/) and are included in the in-app "What's new" view.
4
-
5
3
  ## 2026-08-11
6
4
 
7
5
  ### Improved
@@ -35,3 +33,34 @@ Older updates live in [the changelog folder](./changelog/) and are included in t
35
33
  ### Improved
36
34
 
37
35
  - Sidebar footers now keep Feedback, Search, and Collapse together, with language preferences available in Settings.
36
+
37
+ ## 2026-07-26
38
+
39
+ ### Added
40
+
41
+ - Any list or view can be shown as a board grouped by stage, so a pipeline can be dragged through its stages instead of edited row by row.
42
+ - CRM now finds likely duplicate records and tells you exactly why each pair matched, then merges them into the record you choose without losing anything from either side.
43
+ - Enrichment now shows what a run will cost before it starts, gathers free evidence first, and only spends on the records you approved.
44
+ - Lists turn any set of records into a pipeline with its own stage and fields, and they stay yours even when the records come from HubSpot or Salesforce.
45
+ - Opening a record now shows one page with its fields, the lists it belongs to, its activity and evidence, and the full change history of any single value.
46
+ - Press Cmd+K to jump to any record, list, view or setting, and use keyboard shortcuts to move through the grid without reaching for the mouse.
47
+ - Record reference fields like Account can now be linked from the record page: search records in a popover and see the link as a chip you can remove.
48
+ - Records now use typed fields — currency, dates, ratings, status, select, references and more — and every field remembers who changed it, when, and what it was before.
49
+ - Settings now has Fields and Lists tabs for adding fields, editing their allowed options and stage targets, and archiving what you no longer use.
50
+ - The record grid is now a real spreadsheet: filter, sort and page over the full data set, edit in place, and copy or paste ranges straight to a spreadsheet.
51
+
52
+ ### Improved
53
+
54
+ - Provider record edits now show an exact before/after diff and open the record in HubSpot or Salesforce to finish the change, instead of reporting a failure
55
+ - Record page attribute labels now read in full instead of being cut off, and the Highlights panel starts from a curated set per record type.
56
+
57
+ ### Fixed
58
+
59
+ - A half-typed number or date no longer saves as empty — the field says it cannot read the value and keeps what the record already had.
60
+ - A new pipeline board now opens with stage columns, a summable amount, and each card's values copied from the record it was added from
61
+ - Moving a record or list entry into a stage that was retired or never declared is now refused with the reason and the stages you can pick, and a stage somebody else moved in the meantime is reported instead of being overwritten
62
+ - Retyping a record field now replaces the old value instead of appending to it, wherever the field is edited.
63
+ - Retyping a value on the record page now replaces it instead of merging with the old text.
64
+ - The proposal review now shows the field that actually changed instead of reading "Empty" on both sides.
65
+
66
+ For the full list of updates, see the [changelog folder](./changelog/).
@@ -46,10 +46,6 @@ class CrmMergeError extends CrmAttributeValueError {
46
46
  }
47
47
  }
48
48
 
49
- type CrmTransaction = Parameters<
50
- Parameters<ReturnType<typeof getDb>["transaction"]>[0]
51
- >[0];
52
-
53
49
  interface StoredValue {
54
50
  stringValue: string | null;
55
51
  numberValue: number | null;
@@ -16,7 +16,6 @@ import { useState } from "react";
16
16
  import { Link } from "react-router";
17
17
  import { toast } from "sonner";
18
18
 
19
- import { Button } from "@/components/ui/button";
20
19
  import {
21
20
  Select,
22
21
  SelectContent,
@@ -13,7 +13,6 @@ import type {
13
13
  CrmFieldDefinition,
14
14
  CrmObjectDefinition,
15
15
  CrmObjectKind,
16
- CrmObjectRef,
17
16
  CrmProvenance,
18
17
  CrmRecord,
19
18
  CrmRecordRef,
@@ -14,7 +14,6 @@ import type {
14
14
  CrmFieldDefinition,
15
15
  CrmObjectDefinition,
16
16
  CrmObjectKind,
17
- CrmProvenance,
18
17
  CrmRecord,
19
18
  CrmRecordRef,
20
19
  CrmRelationship,
@@ -1,4 +1,4 @@
1
- import { accessFilter, assertAccess } from "@agent-native/core/sharing";
1
+ import { accessFilter } from "@agent-native/core/sharing";
2
2
  import { and, asc, desc, eq, exists, inArray, isNull, like } from "drizzle-orm";
3
3
 
4
4
  import type {
@@ -38,7 +38,11 @@ connection exists:
38
38
  register a `kind: "oauth"` entry so the shared UI renders Connect and the
39
39
  runtime owns status, refresh, and reauthorization.
40
40
  - **Deploy- or app-level configuration** - use deployment/runtime
41
- configuration, not a per-user secret row.
41
+ configuration, not a per-user secret row. For a non-secret public setting
42
+ already represented by `AgentNativeConfig`, put the default in
43
+ `agent-native.config.ts` and use its `AGENT_NATIVE_CONFIG_<PATH>` alias only
44
+ for a deployment override. Never put a credential or provider key in that
45
+ public namespace.
42
46
  - **Account, customer, manager, or other non-secret identifier** - store it as
43
47
  scoped connection metadata or app data, not as a masked secret field.
44
48
 
@@ -55,7 +55,10 @@ Preview before `--apply`, commit `agent-native.ejections.json`, and never edit
55
55
  ZIPs, screenshots, thumbnails, session replay chunks) in configured file/blob
56
56
  storage and persist only URLs, ids, or handles.
57
57
  - Store shared runtime configuration in the workspace root `.env`; use
58
- `apps/<app>/.env` only for app-specific overrides. Never hardcode API keys,
58
+ `apps/<app>/.env` only for app-specific overrides. For public app behavior,
59
+ prefer the default in `agent-native.config.ts` and use the deterministic
60
+ `AGENT_NATIVE_CONFIG_<UPPER_SNAKE_PATH>` alias only when a non-secret value
61
+ needs a deployment override. Never hardcode API keys,
59
62
  tokens, webhook URLs, signing secrets, private Builder/internal data, customer
60
63
  data, or credential-looking literals in source, docs, prompts, fixtures,
61
64
  application state, action responses, or generated app content. Use