@agent-native/core-corpus 0.201.0-nightly-20261005153421 → 0.201.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 (235) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/security/SKILL.md +9 -2
  3. package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +14 -4
  4. package/corpus/templates/analytics/.agents/skills/storing-data/SKILL.md +12 -7
  5. package/corpus/templates/analytics/CHANGELOG.md +6 -0
  6. package/corpus/templates/analytics/README.md +2 -2
  7. package/corpus/templates/analytics/changelog/2026-10-02-events-with-a-very-long-name-app-or-page-path-no-longer-caus.md +6 -0
  8. package/corpus/templates/analytics/package.json +1 -0
  9. package/corpus/templates/analytics/server/handlers/first-party-analytics.ts +9 -19
  10. package/corpus/templates/analytics/server/handlers/session-replay.ts +34 -47
  11. package/corpus/templates/analytics/server/lib/first-party-analytics-rollups.ts +9 -6
  12. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +57 -36
  13. package/corpus/templates/analytics/server/lib/indexed-text.ts +53 -0
  14. package/corpus/templates/analytics/server/lib/request-errors.ts +73 -0
  15. package/corpus/templates/analytics/server/lib/session-event-index.ts +6 -16
  16. package/corpus/templates/analytics/server/lib/session-replay.ts +12 -2
  17. package/corpus/templates/analytics/server/plugins/auth.ts +2 -1
  18. package/corpus/templates/analytics/server/plugins/otel.ts +6 -0
  19. package/corpus/templates/assets/.agents/skills/security/SKILL.md +9 -2
  20. package/corpus/templates/assets/.agents/skills/storing-data/SKILL.md +12 -7
  21. package/corpus/templates/assets/CHANGELOG.md +7 -0
  22. package/corpus/templates/assets/README.md +2 -2
  23. package/corpus/templates/assets/package.json +1 -0
  24. package/corpus/templates/assets/server/plugins/auth.ts +2 -1
  25. package/corpus/templates/assets/server/plugins/otel.ts +6 -0
  26. package/corpus/templates/brain/.agents/skills/brain/RUNBOOK.md +2 -1
  27. package/corpus/templates/brain/.agents/skills/brain/SKILL.md +5 -4
  28. package/corpus/templates/brain/.agents/skills/security/SKILL.md +9 -2
  29. package/corpus/templates/brain/.agents/skills/storing-data/SKILL.md +12 -7
  30. package/corpus/templates/brain/CHANGELOG.md +6 -0
  31. package/corpus/templates/brain/README.md +12 -8
  32. package/corpus/templates/brain/changelog/2026-10-05-private-slack-channels-are-searchable-org-wide.md +6 -0
  33. package/corpus/templates/brain/package.json +1 -0
  34. package/corpus/templates/brain/server/lib/audiences.ts +1 -98
  35. package/corpus/templates/brain/server/lib/connectors.ts +2 -166
  36. package/corpus/templates/brain/server/plugins/otel.ts +6 -0
  37. package/corpus/templates/calendar/.agents/skills/security/SKILL.md +9 -2
  38. package/corpus/templates/calendar/.agents/skills/storing-data/SKILL.md +12 -7
  39. package/corpus/templates/calendar/CHANGELOG.md +7 -0
  40. package/corpus/templates/calendar/README.md +2 -2
  41. package/corpus/templates/calendar/package.json +1 -0
  42. package/corpus/templates/calendar/server/plugins/auth.ts +2 -1
  43. package/corpus/templates/calendar/server/plugins/otel.ts +6 -0
  44. package/corpus/templates/chat/.agents/skills/security/SKILL.md +9 -2
  45. package/corpus/templates/chat/.agents/skills/storing-data/SKILL.md +12 -7
  46. package/corpus/templates/chat/README.md +2 -2
  47. package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +9 -0
  48. package/corpus/templates/clips/.agents/skills/security/SKILL.md +9 -2
  49. package/corpus/templates/clips/CHANGELOG.md +24 -0
  50. package/corpus/templates/clips/README.md +2 -2
  51. package/corpus/templates/clips/actions/lib/audio-chunk-list.ts +23 -0
  52. package/corpus/templates/clips/actions/lib/audio-only-transcription.ts +187 -292
  53. package/corpus/templates/clips/actions/lib/chunked-transcription.ts +151 -0
  54. package/corpus/templates/clips/actions/lib/recording-audio-source.ts +191 -0
  55. package/corpus/templates/clips/actions/request-transcript.ts +81 -135
  56. package/corpus/templates/clips/actions/search-recordings.ts +19 -5
  57. package/corpus/templates/clips/app/components/clips-command-menu.tsx +5 -0
  58. package/corpus/templates/clips/app/components/library/library-layout.tsx +3 -1
  59. package/corpus/templates/clips/app/components/library/search-bar.tsx +5 -0
  60. package/corpus/templates/clips/app/hooks/use-library.ts +1 -0
  61. package/corpus/templates/clips/app/lib/local-recording-upload.ts +13 -6
  62. package/corpus/templates/clips/app/lib/recording-section.ts +1 -1
  63. package/corpus/templates/clips/app/routes/_app.r.$recordingId.tsx +7 -5
  64. package/corpus/templates/clips/app/routes/record.tsx +16 -6
  65. package/corpus/templates/clips/changelog/2026-10-02-long-uploads-an-hour-or-more-now-transcribe-reliably-instead.md +6 -0
  66. package/corpus/templates/clips/changelog/2026-10-05-confirming-discard-recording-now-returns-you-to-your-library.md +6 -0
  67. package/corpus/templates/clips/changelog/2026-10-05-discarding-a-recording-now-removes-its-failed-upload-card-fr.md +6 -0
  68. package/corpus/templates/clips/changelog/2026-10-05-discarding-a-recovered-recording-no-longer-warns-that-it-s-o.md +6 -0
  69. package/corpus/templates/clips/changelog/2026-10-05-search-results-identify-recordings-in-trash-and-open-them-wi.md +6 -0
  70. package/corpus/templates/clips/package.json +1 -0
  71. package/corpus/templates/clips/server/lib/builder-cdn.ts +5 -0
  72. package/corpus/templates/clips/server/lib/builder-media-compression.ts +2 -2
  73. package/corpus/templates/clips/server/plugins/auth.ts +2 -1
  74. package/corpus/templates/clips/server/plugins/otel.ts +6 -0
  75. package/corpus/templates/clips/shared/transcript-failure.ts +5 -0
  76. package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +8 -2
  77. package/corpus/templates/content/.agents/skills/security/SKILL.md +9 -2
  78. package/corpus/templates/content/.agents/skills/storing-data/SKILL.md +12 -7
  79. package/corpus/templates/content/CHANGELOG.md +41 -0
  80. package/corpus/templates/content/README.md +2 -2
  81. package/corpus/templates/content/actions/_database-navigation.ts +523 -344
  82. package/corpus/templates/content/actions/_database-row-mutation.ts +44 -10
  83. package/corpus/templates/content/actions/_database-setup-discovery.ts +9 -3
  84. package/corpus/templates/content/actions/_database-utils.ts +299 -271
  85. package/corpus/templates/content/actions/_property-utils.ts +293 -190
  86. package/corpus/templates/content/actions/_relation-values.ts +3 -1
  87. package/corpus/templates/content/actions/get-content-database.ts +1 -0
  88. package/corpus/templates/content/actions/query-content-database-items.ts +32 -5
  89. package/corpus/templates/content/actions/set-document-property.ts +17 -11
  90. package/corpus/templates/content/app/components/editor/DocumentBlockFields.tsx +21 -6
  91. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +127 -43
  92. package/corpus/templates/content/app/components/editor/DocumentEditorSkeleton.tsx +159 -50
  93. package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +12 -28
  94. package/corpus/templates/content/app/components/editor/PageDraftRecovery.tsx +6 -1
  95. package/corpus/templates/content/app/components/editor/TableHoverControls.tsx +139 -70
  96. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +16 -1
  97. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +180 -75
  98. package/corpus/templates/content/app/components/editor/database/DatabaseViewSkeleton.tsx +76 -0
  99. package/corpus/templates/content/app/components/editor/database/navigation-state.ts +60 -2
  100. package/corpus/templates/content/app/components/editor/database/sidebar.tsx +41 -42
  101. package/corpus/templates/content/app/components/editor/document-editor-layout.ts +18 -0
  102. package/corpus/templates/content/app/components/editor/extensions/NotionExtensions.tsx +11 -3
  103. package/corpus/templates/content/app/components/editor/suggestions/draft-session.ts +15 -7
  104. package/corpus/templates/content/app/components/editor/suggestions/model.ts +13 -0
  105. package/corpus/templates/content/app/components/editor/suggestions/read-only-blocks.ts +136 -0
  106. package/corpus/templates/content/app/components/editor/table-view.ts +73 -0
  107. package/corpus/templates/content/app/components/layout/ContentStartupShell.tsx +1 -1
  108. package/corpus/templates/content/app/components/layout/Layout.tsx +5 -1
  109. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +57 -16
  110. package/corpus/templates/content/app/components/sidebar/MovePageDialog.tsx +4 -4
  111. package/corpus/templates/content/app/components/sidebar/SidebarNavigationRow.tsx +34 -10
  112. package/corpus/templates/content/app/global.css +16 -8
  113. package/corpus/templates/content/app/hooks/content-action-refresh.ts +14 -13
  114. package/corpus/templates/content/app/hooks/use-content-database.ts +72 -9
  115. package/corpus/templates/content/app/hooks/use-content-personal-navigation.ts +7 -3
  116. package/corpus/templates/content/app/hooks/use-documents.ts +27 -0
  117. package/corpus/templates/content/app/i18n-data.ts +3 -2
  118. package/corpus/templates/content/app/lib/content-landing.ts +3 -31
  119. package/corpus/templates/content/app/lib/files-navigation.ts +182 -10
  120. package/corpus/templates/content/app/lib/files-root-hint.ts +20 -32
  121. package/corpus/templates/content/app/lib/page-startup-hints.ts +108 -0
  122. package/corpus/templates/content/app/lib/private-link-redirect.ts +25 -0
  123. package/corpus/templates/content/app/lib/sidebar-layout-hint.ts +34 -1
  124. package/corpus/templates/content/app/lib/startup-timing.ts +2 -0
  125. package/corpus/templates/content/app/root.tsx +3 -1
  126. package/corpus/templates/content/app/routes/_app.home.tsx +10 -19
  127. package/corpus/templates/content/app/routes/p.$id.tsx +23 -5
  128. package/corpus/templates/content/changelog/2026-10-02-a-page-link-you-cant-open-now-says-so-instead-of-opening-an.md +6 -0
  129. package/corpus/templates/content/changelog/2026-10-02-after-a-refresh-the-files-sidebar-shows-the-open-page-s-fold.md +6 -0
  130. package/corpus/templates/content/changelog/2026-10-02-large-collections-open-faster.md +6 -0
  131. package/corpus/templates/content/changelog/2026-10-02-pages-stay-inside-the-window-at-every-width-long-inline-code.md +6 -0
  132. package/corpus/templates/content/changelog/2026-10-02-pages-with-open-comments-and-collections-with-sorted-or-filt.md +6 -0
  133. package/corpus/templates/content/changelog/2026-10-02-suggest-edits-works-on-pages-written-by-agents-including-pag.md +6 -0
  134. package/corpus/templates/content/changelog/2026-10-02-while-you-suggest-edits-tables-and-other-blocks-that-suggest.md +6 -0
  135. package/corpus/templates/content/changelog/2026-10-05-collection-view-context-now-survives-quick-page-changes-when.md +6 -0
  136. package/corpus/templates/content/changelog/2026-10-05-collection-views-keep-their-saved-rows-accurate-during-refre.md +6 -0
  137. package/corpus/templates/content/changelog/2026-10-05-exact-saved-view-links-keep-collection-retry-available.md +6 -0
  138. package/corpus/templates/content/changelog/2026-10-05-expanding-a-files-folder-now-shares-one-navigation-read-acro.md +6 -0
  139. package/corpus/templates/content/changelog/2026-10-05-files-navigation-retries-temporary-failures-consistently.md +6 -0
  140. package/corpus/templates/content/changelog/2026-10-05-shared-page-owners-keep-edit-and-manage-controls-in-files-an.md +6 -0
  141. package/corpus/templates/content/changelog/2026-10-05-tagging-an-ai-in-a-comment-works-again-instead-of-failing-ri.md +6 -0
  142. package/corpus/templates/content/changelog/2026-10-05-the-home-loading-shell-keeps-the-layout-of-your-last-opened-.md +6 -0
  143. package/corpus/templates/content/changelog/2026-10-05-typing-and-a-space-or-inserting-a-toggle-or-callout-no-longe.md +6 -0
  144. package/corpus/templates/content/docs/product/capabilities/content.workspace.session-restore.md +4 -1
  145. package/corpus/templates/content/e2e/playwright.config.ts +1 -1
  146. package/corpus/templates/content/package.json +2 -1
  147. package/corpus/templates/content/scripts/seed-perf-database.mjs +600 -0
  148. package/corpus/templates/content/scripts/trace-startup.mjs +25 -3
  149. package/corpus/templates/content/server/db/index.ts +1 -1
  150. package/corpus/templates/content/server/lib/suggested-edits.ts +23 -26
  151. package/corpus/templates/content/server/plugins/auth.ts +2 -1
  152. package/corpus/templates/content/server/plugins/otel.ts +6 -0
  153. package/corpus/templates/content/shared/api.ts +17 -0
  154. package/corpus/templates/content/shared/suggestion-diff.ts +124 -38
  155. package/corpus/templates/content/shared/suggestion-formatting.ts +134 -3
  156. package/corpus/templates/crm/.agents/skills/security/SKILL.md +9 -2
  157. package/corpus/templates/crm/.agents/skills/storing-data/SKILL.md +12 -7
  158. package/corpus/templates/crm/package.json +1 -0
  159. package/corpus/templates/crm/server/plugins/otel.ts +6 -0
  160. package/corpus/templates/design/.agents/skills/security/SKILL.md +9 -2
  161. package/corpus/templates/design/.agents/skills/storing-data/SKILL.md +12 -7
  162. package/corpus/templates/design/CHANGELOG.md +41 -0
  163. package/corpus/templates/design/README.md +2 -2
  164. package/corpus/templates/design/actions/list-designs.ts +11 -4
  165. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +110 -32
  166. package/corpus/templates/design/app/components/design/multi-screen/cross-screen-drop.ts +28 -0
  167. package/corpus/templates/design/app/components/design/multi-screen/types.ts +1 -0
  168. package/corpus/templates/design/app/components/home/DesignHomeLibrary.tsx +79 -0
  169. package/corpus/templates/design/app/components/layout/Header.tsx +2 -4
  170. package/corpus/templates/design/app/components/ui/tabs.tsx +59 -1
  171. package/corpus/templates/design/app/global.css +1 -34
  172. package/corpus/templates/design/app/i18n/en-US.ts +4 -0
  173. package/corpus/templates/design/app/lib/design-filter.ts +4 -2
  174. package/corpus/templates/design/app/pages/Index.tsx +91 -59
  175. package/corpus/templates/design/app/pages/design-editor/commands/cross-screen-element-drop.ts +58 -17
  176. package/corpus/templates/design/changelog/2026-10-01-filter-designs-by-owner.md +6 -0
  177. package/corpus/templates/design/changelog/2026-10-03-layers-dropped-into-visible-canvas-space-beyond-a-screen-now.md +6 -0
  178. package/corpus/templates/design/changelog/2026-10-03-visible-screen-overflow-no-longer-routes-drops-to-the-canvas.md +6 -0
  179. package/corpus/templates/design/changelog/2026-10-05-the-recent-tab-shows-loading-placeholders-until-your-designs.md +6 -0
  180. package/corpus/templates/design/package.json +1 -0
  181. package/corpus/templates/design/server/plugins/auth.ts +2 -1
  182. package/corpus/templates/design/server/plugins/otel.ts +6 -0
  183. package/corpus/templates/dispatch/.agents/skills/security/SKILL.md +9 -2
  184. package/corpus/templates/dispatch/.agents/skills/storing-data/SKILL.md +12 -7
  185. package/corpus/templates/dispatch/README.md +2 -2
  186. package/corpus/templates/dispatch/package.json +1 -0
  187. package/corpus/templates/dispatch/server/plugins/otel.ts +6 -0
  188. package/corpus/templates/dispatch/server/plugins/setup-dispatch.ts +2 -1
  189. package/corpus/templates/factory/.agents/skills/security/SKILL.md +9 -2
  190. package/corpus/templates/factory/.agents/skills/storing-data/SKILL.md +12 -7
  191. package/corpus/templates/factory/package.json +1 -0
  192. package/corpus/templates/factory/server/plugins/otel.ts +6 -0
  193. package/corpus/templates/forms/.agents/skills/security/SKILL.md +9 -2
  194. package/corpus/templates/forms/.agents/skills/storing-data/SKILL.md +12 -7
  195. package/corpus/templates/forms/README.md +2 -2
  196. package/corpus/templates/forms/package.json +1 -0
  197. package/corpus/templates/forms/server/plugins/auth.ts +2 -1
  198. package/corpus/templates/forms/server/plugins/otel.ts +6 -0
  199. package/corpus/templates/mail/.agents/skills/security/SKILL.md +9 -2
  200. package/corpus/templates/mail/.agents/skills/storing-data/SKILL.md +12 -7
  201. package/corpus/templates/mail/CHANGELOG.md +6 -0
  202. package/corpus/templates/mail/README.md +2 -2
  203. package/corpus/templates/mail/package.json +1 -0
  204. package/corpus/templates/mail/server/plugins/auth.ts +2 -1
  205. package/corpus/templates/mail/server/plugins/otel.ts +6 -0
  206. package/corpus/templates/plan/.agents/skills/security/SKILL.md +9 -2
  207. package/corpus/templates/plan/.agents/skills/storing-data/SKILL.md +12 -7
  208. package/corpus/templates/plan/CHANGELOG.md +1 -0
  209. package/corpus/templates/plan/README.md +2 -2
  210. package/corpus/templates/plan/package.json +1 -0
  211. package/corpus/templates/plan/server/plugins/auth.ts +2 -1
  212. package/corpus/templates/plan/server/plugins/otel.ts +6 -0
  213. package/corpus/templates/slides/.agents/skills/security/SKILL.md +9 -2
  214. package/corpus/templates/slides/.agents/skills/storing-data/SKILL.md +12 -7
  215. package/corpus/templates/slides/CHANGELOG.md +23 -0
  216. package/corpus/templates/slides/README.md +2 -2
  217. package/corpus/templates/slides/actions/list-decks.ts +11 -4
  218. package/corpus/templates/slides/app/components/deck/DeckFilterMenu.tsx +44 -36
  219. package/corpus/templates/slides/app/components/home/SlidesHomeLibrary.tsx +79 -0
  220. package/corpus/templates/slides/app/components/layout/Header.tsx +2 -15
  221. package/corpus/templates/slides/app/components/ui/tabs.tsx +59 -0
  222. package/corpus/templates/slides/app/global.css +3 -54
  223. package/corpus/templates/slides/app/i18n/en-US.ts +4 -0
  224. package/corpus/templates/slides/app/lib/deck-filter.ts +5 -2
  225. package/corpus/templates/slides/app/pages/Index.tsx +102 -88
  226. package/corpus/templates/slides/changelog/2026-10-01-filter-decks-by-owner.md +6 -0
  227. package/corpus/templates/slides/changelog/2026-10-02-hide-recent-until-decks-available.md +6 -0
  228. package/corpus/templates/slides/changelog/2026-10-05-the-recent-tab-shows-loading-placeholders-until-your-decks-a.md +6 -0
  229. package/corpus/templates/slides/package.json +1 -0
  230. package/corpus/templates/slides/server/handlers/request-auth-context.ts +8 -0
  231. package/corpus/templates/slides/server/plugins/auth.ts +2 -1
  232. package/corpus/templates/slides/server/plugins/otel.ts +6 -0
  233. package/corpus/templates/tasks/.agents/skills/security/SKILL.md +9 -2
  234. package/corpus/templates/tasks/.agents/skills/storing-data/SKILL.md +12 -7
  235. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  export const DESIGN_FILTER_STORAGE_KEY = "design:design-filter";
2
2
 
3
- export type DesignFilter = "all" | "mine";
3
+ export type DesignFilter = "all" | "mine" | "not-mine";
4
4
 
5
5
  function getLocalStorage(): Pick<Storage, "getItem" | "setItem"> | null {
6
6
  if (typeof window === "undefined") return null;
@@ -20,7 +20,9 @@ export function readStoredDesignFilter(
20
20
 
21
21
  try {
22
22
  const stored = storage.getItem(DESIGN_FILTER_STORAGE_KEY);
23
- return stored === "all" || stored === "mine" ? stored : undefined;
23
+ return stored === "all" || stored === "mine" || stored === "not-mine"
24
+ ? stored
25
+ : undefined;
24
26
  } catch {
25
27
  // coercion-ok: localStorage failures intentionally fall back to the default filter.
26
28
  return undefined;
@@ -24,11 +24,8 @@ import {
24
24
  } from "@agent-native/toolkit/agentkit";
25
25
  import {
26
26
  PromptHome,
27
- PromptHomeLibrary,
28
27
  TemplateLibraryGrid,
29
- type PromptHomeLibraryTab,
30
28
  useHomeSearchShortcut,
31
- useSetHeaderActions,
32
29
  useSetPageTitle,
33
30
  } from "@agent-native/toolkit/app-shell";
34
31
  import { BuilderSetupCard } from "@agent-native/toolkit/app/chat/chat/run-recovery";
@@ -46,8 +43,8 @@ import { FULL_APP_BUILDING_LAB } from "@shared/labs";
46
43
  import { derivePromptTitle } from "@shared/prompt-title";
47
44
  import {
48
45
  IconArrowRight,
49
- IconFilter,
50
46
  IconChecks,
47
+ IconChevronDown,
51
48
  IconChevronLeft,
52
49
  IconChevronRight,
53
50
  IconPlus,
@@ -73,6 +70,10 @@ import type {
73
70
  PromptTemplateOption,
74
71
  UploadedFile,
75
72
  } from "@/components/editor/PromptDialog";
73
+ import {
74
+ DesignHomeLibrary,
75
+ type DesignHomeLibraryTab,
76
+ } from "@/components/home/DesignHomeLibrary";
76
77
  import { QueryErrorState } from "@/components/QueryErrorState";
77
78
  import { DesignTemplateLibrary } from "@/components/templates/DesignTemplateLibrary";
78
79
  import {
@@ -142,25 +143,6 @@ interface DesignListResult {
142
143
  }
143
144
 
144
145
  const DESIGN_PAGE_SIZE = 50;
145
- const HOME_LIBRARY_TAB_STORAGE_KEY = "design:home-library-tab";
146
-
147
- function readStoredHomeLibraryTab(): PromptHomeLibraryTab | undefined {
148
- try {
149
- const tab = window.localStorage.getItem(HOME_LIBRARY_TAB_STORAGE_KEY);
150
- return tab === "templates" || tab === "recent" ? tab : undefined;
151
- } catch {
152
- // coercion-ok: the tab preference is optional when browser storage is unavailable.
153
- return undefined;
154
- }
155
- }
156
-
157
- function writeStoredHomeLibraryTab(tab: PromptHomeLibraryTab): void {
158
- try {
159
- window.localStorage.setItem(HOME_LIBRARY_TAB_STORAGE_KEY, tab);
160
- } catch {
161
- // coercion-ok: an unavailable preference store preserves the in-memory selection.
162
- }
163
- }
164
146
 
165
147
  interface HomeSuggestion {
166
148
  id?: string;
@@ -178,7 +160,6 @@ type HomeSuggestionsResult =
178
160
 
179
161
  export default function Index() {
180
162
  const t = useT();
181
- useHomeSearchShortcut(true);
182
163
  const navigate = useNavigate();
183
164
  const [searchParams, setSearchParams] = useSearchParams();
184
165
  const queryClient = useQueryClient();
@@ -192,13 +173,9 @@ export default function Index() {
192
173
  const [selectedDesignIds, setSelectedDesignIds] = useState<Set<string>>(
193
174
  () => new Set(),
194
175
  );
195
- const storedHomeLibraryTab = readStoredHomeLibraryTab();
196
- const [homeSection, setHomeSection] = useState<PromptHomeLibraryTab>(
197
- storedHomeLibraryTab ?? "templates",
198
- );
199
- const homeLibraryTabWasSelectedRef = useRef(
200
- storedHomeLibraryTab !== undefined,
201
- );
176
+ const [homeSection, setHomeSection] =
177
+ useState<DesignHomeLibraryTab>("templates");
178
+ const homeLibraryTabWasSelectedRef = useRef(false);
202
179
  const designFilterWasSelectedRef = useRef(false);
203
180
  const composerRef = useRef<TiptapComposerHandle>(null);
204
181
  const [quickStartPending, setQuickStartPending] = useState(false);
@@ -229,7 +206,12 @@ export default function Index() {
229
206
  () => ({
230
207
  page,
231
208
  pageSize: DESIGN_PAGE_SIZE,
232
- createdBy: designFilter === "mine" ? "me" : "all",
209
+ createdBy:
210
+ designFilter === "mine"
211
+ ? "me"
212
+ : designFilter === "not-mine"
213
+ ? "not-me"
214
+ : "all",
233
215
  search: normalizedSearch || undefined,
234
216
  includePreview: "true",
235
217
  }),
@@ -262,16 +244,30 @@ export default function Index() {
262
244
  includePreview: "false",
263
245
  });
264
246
  const hasSearchResultsSection = normalizedSearch.length > 0;
247
+ const recentVisible =
248
+ accessibleDesignsSummary.isSuccess &&
249
+ (accessibleDesignsSummary.data?.totalCount ?? 0) > 0;
250
+ const revealRecentSearch = useCallback(() => {
251
+ if (!recentVisible) return false;
252
+ homeLibraryTabWasSelectedRef.current = true;
253
+ setHomeSection("recent");
254
+ return true;
255
+ }, [recentVisible]);
256
+ useHomeSearchShortcut(true, revealRecentSearch);
265
257
  useEffect(() => {
266
- if (
267
- accessibleDesignsSummary.isSuccess &&
268
- (accessibleDesignsSummary.data?.totalCount ?? 0) > 0 &&
269
- !homeLibraryTabWasSelectedRef.current
270
- ) {
271
- setHomeSection("recent");
272
- writeStoredHomeLibraryTab("recent");
273
- homeLibraryTabWasSelectedRef.current = true;
258
+ if (!accessibleDesignsSummary.isSuccess) return;
259
+
260
+ const hasAccessibleDesigns =
261
+ (accessibleDesignsSummary.data?.totalCount ?? 0) > 0;
262
+ if (!hasAccessibleDesigns) {
263
+ setHomeSection("templates");
264
+ homeLibraryTabWasSelectedRef.current = false;
265
+ return;
274
266
  }
267
+ if (homeLibraryTabWasSelectedRef.current) return;
268
+
269
+ setHomeSection("recent");
270
+ homeLibraryTabWasSelectedRef.current = true;
275
271
  }, [
276
272
  accessibleDesignsSummary.data?.totalCount,
277
273
  accessibleDesignsSummary.isSuccess,
@@ -460,7 +456,12 @@ export default function Index() {
460
456
  ? chosenDesignSystemId
461
457
  : templateDesignSystemId;
462
458
 
463
- const showAuthors = designFilter === "all";
459
+ const ownerFilterLabels: Record<DesignFilter, string> = {
460
+ all: t("home.ownedByAnyone"),
461
+ mine: t("home.ownedByMe"),
462
+ "not-mine": t("home.sharedWithMe"),
463
+ };
464
+ const showAuthors = designFilter !== "mine";
464
465
  const selectedDesignCount = selectedDesignIds.size;
465
466
  const isSelectingDesigns = selectedDesignCount > 0;
466
467
  const allVisibleSelected =
@@ -583,7 +584,7 @@ export default function Index() {
583
584
  }, []);
584
585
 
585
586
  const handleDesignFilterChange = useCallback((next: string) => {
586
- if (next !== "all" && next !== "mine") return;
587
+ if (next !== "all" && next !== "mine" && next !== "not-mine") return;
587
588
  designFilterWasSelectedRef.current = true;
588
589
  const nextFilter: DesignFilter = next;
589
590
  setDesignFilter(nextFilter);
@@ -1141,8 +1142,8 @@ export default function Index() {
1141
1142
 
1142
1143
  useSetPageTitle(t("home.pageTitle"));
1143
1144
 
1144
- useSetHeaderActions(
1145
- <div className="relative w-full">
1145
+ const searchInput = (
1146
+ <div className="relative w-full min-w-0 sm:w-64 sm:shrink-0">
1146
1147
  <IconSearch className="pointer-events-none absolute start-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" />
1147
1148
  <Input
1148
1149
  size="sm"
@@ -1151,9 +1152,9 @@ export default function Index() {
1151
1152
  placeholder={t("home.searchPlaceholder")}
1152
1153
  aria-label={t("home.searchPlaceholder")}
1153
1154
  data-home-search="true"
1154
- className="w-full pe-3 ps-8"
1155
+ className="h-9 w-full pe-3 ps-8"
1155
1156
  />
1156
- </div>,
1157
+ </div>
1157
1158
  );
1158
1159
 
1159
1160
  return (
@@ -1307,11 +1308,15 @@ export default function Index() {
1307
1308
  />
1308
1309
  ) : null}
1309
1310
  <ClientOnly>
1310
- <PromptHomeLibrary
1311
- value={homeSection}
1311
+ <DesignHomeLibrary
1312
+ recentVisible={recentVisible}
1313
+ value={
1314
+ recentVisible && !homeLibraryTabWasSelectedRef.current
1315
+ ? "recent"
1316
+ : homeSection
1317
+ }
1312
1318
  onValueChange={(value) => {
1313
1319
  homeLibraryTabWasSelectedRef.current = true;
1314
- writeStoredHomeLibraryTab(value);
1315
1320
  setHomeSection(value);
1316
1321
  }}
1317
1322
  labels={{
@@ -1326,28 +1331,49 @@ export default function Index() {
1326
1331
  </Link>
1327
1332
  </Button>
1328
1333
  }
1334
+ search={searchInput}
1329
1335
  recentActions={
1330
1336
  <DropdownMenu>
1331
1337
  <DropdownMenuTrigger asChild>
1332
1338
  <Button
1339
+ type="button"
1333
1340
  variant="outline"
1334
1341
  size="sm"
1335
- aria-label={t("home.designFilter")}
1342
+ aria-label={ownerFilterLabels[designFilter]}
1343
+ className="h-9 shrink-0 gap-2"
1336
1344
  >
1337
- <IconFilter />
1338
- {designFilter === "mine" ? t("home.mine") : t("home.all")}
1345
+ <span className="grid">
1346
+ {Object.entries(ownerFilterLabels).map(
1347
+ ([filter, label]) => (
1348
+ <span
1349
+ key={filter}
1350
+ aria-hidden="true"
1351
+ className="invisible col-start-1 row-start-1 whitespace-nowrap"
1352
+ >
1353
+ {label}
1354
+ </span>
1355
+ ),
1356
+ )}
1357
+ <span className="col-start-1 row-start-1 whitespace-nowrap">
1358
+ {ownerFilterLabels[designFilter]}
1359
+ </span>
1360
+ </span>
1361
+ <IconChevronDown className="size-4" aria-hidden="true" />
1339
1362
  </Button>
1340
1363
  </DropdownMenuTrigger>
1341
- <DropdownMenuContent align="end">
1364
+ <DropdownMenuContent align="start">
1342
1365
  <DropdownMenuRadioGroup
1343
1366
  value={designFilter}
1344
1367
  onValueChange={handleDesignFilterChange}
1345
1368
  >
1346
- <DropdownMenuRadioItem value="mine">
1347
- {t("home.mine")}
1369
+ <DropdownMenuRadioItem value="all" indicator="check">
1370
+ {ownerFilterLabels.all}
1371
+ </DropdownMenuRadioItem>
1372
+ <DropdownMenuRadioItem value="mine" indicator="check">
1373
+ {ownerFilterLabels.mine}
1348
1374
  </DropdownMenuRadioItem>
1349
- <DropdownMenuRadioItem value="all">
1350
- {t("home.all")}
1375
+ <DropdownMenuRadioItem value="not-mine" indicator="check">
1376
+ {ownerFilterLabels["not-mine"]}
1351
1377
  </DropdownMenuRadioItem>
1352
1378
  </DropdownMenuRadioGroup>
1353
1379
  </DropdownMenuContent>
@@ -1370,7 +1396,7 @@ export default function Index() {
1370
1396
  }
1371
1397
  recent={
1372
1398
  <>
1373
- {isLoading ? (
1399
+ {isLoading || (isFetching && designs.length === 0) ? (
1374
1400
  <LoadingSkeleton />
1375
1401
  ) : isError ? (
1376
1402
  <QueryErrorState
@@ -1378,7 +1404,13 @@ export default function Index() {
1378
1404
  retrying={isFetching}
1379
1405
  />
1380
1406
  ) : designs.length === 0 ? (
1381
- <SearchEmptyState />
1407
+ normalizedSearch ? (
1408
+ <SearchEmptyState />
1409
+ ) : (
1410
+ <div className="rounded-xl bg-card p-6 text-center text-sm text-muted-foreground">
1411
+ {t("home.noDesignsMatchFilter")}
1412
+ </div>
1413
+ )
1382
1414
  ) : (
1383
1415
  <>
1384
1416
  {isSelectingDesigns ? (
@@ -122,6 +122,33 @@ export function absolutePlacePointForDrop(args: {
122
122
  return absoluteDropPoint(args.targetLocalPoint, args.targetAnchorRect);
123
123
  }
124
124
 
125
+ export function authoredTargetPointForDrop(args: {
126
+ boardFileId?: string;
127
+ targetScreenId: string;
128
+ targetOutsideBoardRenderGeometry?: boolean;
129
+ targetAnchorNodeId?: string;
130
+ targetAnchorPendingNodeId?: string;
131
+ targetAnchorSelector?: string;
132
+ targetCanvasPoint?: { x: number; y: number };
133
+ targetLocalPoint?: { x: number; y: number };
134
+ }): { x: number; y: number } | undefined {
135
+ const hasAnchor = Boolean(
136
+ args.targetAnchorNodeId ||
137
+ args.targetAnchorPendingNodeId ||
138
+ args.targetAnchorSelector,
139
+ );
140
+ if (
141
+ !hasAnchor &&
142
+ args.boardFileId &&
143
+ args.targetScreenId === args.boardFileId &&
144
+ args.targetOutsideBoardRenderGeometry === true &&
145
+ args.targetCanvasPoint
146
+ ) {
147
+ return args.targetCanvasPoint;
148
+ }
149
+ return args.targetLocalPoint;
150
+ }
151
+
125
152
  export function releaseCrossScreenDropAdmission(
126
153
  pendingTransactionRef: RefObject<string | null> | undefined,
127
154
  transactionId: string | undefined,
@@ -348,6 +375,8 @@ export function runCrossScreenElementDrop(
348
375
  targetDropMode,
349
376
  targetGridPlacement,
350
377
  targetAnchorRect,
378
+ targetCanvasPoint,
379
+ targetOutsideBoardRenderGeometry,
351
380
  targetLocalPoint,
352
381
  sourcePointerOffset,
353
382
  sourceComputedSize,
@@ -382,6 +411,7 @@ export function runCrossScreenElementDrop(
382
411
  height: number;
383
412
  };
384
413
  targetCanvasPoint?: { x: number; y: number };
414
+ targetOutsideBoardRenderGeometry?: boolean;
385
415
  targetLocalPoint?: { x: number; y: number };
386
416
  sourcePointerOffset?: { x: number; y: number };
387
417
  sourceComputedSize?: { width?: number; height?: number };
@@ -400,6 +430,16 @@ export function runCrossScreenElementDrop(
400
430
  targetAnchorPlacement,
401
431
  targetDropMode,
402
432
  });
433
+ const targetPositionPoint = authoredTargetPointForDrop({
434
+ boardFileId,
435
+ targetScreenId,
436
+ targetAnchorNodeId,
437
+ targetAnchorPendingNodeId,
438
+ targetAnchorSelector,
439
+ targetCanvasPoint,
440
+ targetOutsideBoardRenderGeometry,
441
+ targetLocalPoint,
442
+ });
403
443
  if (styleSnapshotCaptureFailed) {
404
444
  trace("drop", "refused", {
405
445
  reason:
@@ -575,14 +615,14 @@ export function runCrossScreenElementDrop(
575
615
  targetAnchorNodeId || targetAnchorPendingNodeId || targetAnchorSelector,
576
616
  );
577
617
  const placeAbsolute =
578
- Boolean(targetLocalPoint) &&
618
+ Boolean(targetPositionPoint) &&
579
619
  (!hasAnchor || targetDropMode === "absolute-container");
580
620
  const absolutePosition =
581
- placeAbsolute && targetLocalPoint
621
+ placeAbsolute && targetPositionPoint
582
622
  ? absolutePlacePointForDrop({
583
623
  placeAbsoluteOnEmptyScreen: false,
584
624
  targetAnchorRect,
585
- targetLocalPoint,
625
+ targetLocalPoint: targetPositionPoint,
586
626
  })
587
627
  : undefined;
588
628
  const prepared = prepareClonedHtmlLayersForLiveInsert(
@@ -666,14 +706,14 @@ export function runCrossScreenElementDrop(
666
706
  targetAnchorNodeId || targetAnchorPendingNodeId || targetAnchorSelector,
667
707
  );
668
708
  const placeAbsolute =
669
- Boolean(targetLocalPoint) &&
709
+ Boolean(targetPositionPoint) &&
670
710
  (!hasAnchor || targetDropMode === "absolute-container");
671
711
  const absolutePosition =
672
- placeAbsolute && targetLocalPoint
712
+ placeAbsolute && targetPositionPoint
673
713
  ? absolutePlacePointForDrop({
674
714
  placeAbsoluteOnEmptyScreen: false,
675
715
  targetAnchorRect,
676
- targetLocalPoint,
716
+ targetLocalPoint: targetPositionPoint,
677
717
  })
678
718
  : undefined;
679
719
  const prepared = prepareClonedHtmlLayersForLiveInsert(
@@ -784,14 +824,14 @@ export function runCrossScreenElementDrop(
784
824
  ];
785
825
  const hasAnchor = anchorSelectors.length > 0;
786
826
  const placeAbsolute =
787
- Boolean(targetLocalPoint) &&
827
+ Boolean(targetPositionPoint) &&
788
828
  (!hasAnchor || targetDropMode === "absolute-container");
789
829
  const absolutePosition =
790
- placeAbsolute && targetLocalPoint
830
+ placeAbsolute && targetPositionPoint
791
831
  ? absolutePlacePointForDrop({
792
832
  placeAbsoluteOnEmptyScreen: false,
793
833
  targetAnchorRect,
794
- targetLocalPoint,
834
+ targetLocalPoint: targetPositionPoint,
795
835
  })
796
836
  : undefined;
797
837
  const nextContent = insertClonedHtmlLayers(
@@ -942,10 +982,10 @@ export function runCrossScreenElementDrop(
942
982
  const destHtml = getScreenContent(targetScreenId);
943
983
  const placeAbsoluteOnEmptyScreen = shouldAbsolutePlaceOnEmptyScreen({
944
984
  destHtml,
945
- targetLocalPoint,
985
+ targetLocalPoint: targetPositionPoint,
946
986
  });
947
987
  const positioned =
948
- targetLocalPoint &&
988
+ targetPositionPoint &&
949
989
  (placeAbsoluteOnEmptyScreen ||
950
990
  (targetDropMode === "absolute-container" && targetAnchorRect))
951
991
  ? setAbsolutePositioningForNodeInHtml(
@@ -954,7 +994,7 @@ export function runCrossScreenElementDrop(
954
994
  absolutePlacePointForDrop({
955
995
  placeAbsoluteOnEmptyScreen,
956
996
  targetAnchorRect,
957
- targetLocalPoint,
997
+ targetLocalPoint: targetPositionPoint,
958
998
  }),
959
999
  sourcePointerOffset,
960
1000
  sourceComputedSize,
@@ -1179,7 +1219,7 @@ export function runCrossScreenElementDrop(
1179
1219
  );
1180
1220
  const placeAbsoluteOnEmptyScreen = shouldAbsolutePlaceOnEmptyScreen({
1181
1221
  destHtml: destContent,
1182
- targetLocalPoint,
1222
+ targetLocalPoint: targetPositionPoint,
1183
1223
  });
1184
1224
  const placed = ((): { content: string; branch: string } => {
1185
1225
  const absolute = (point: { x: number; y: number }, branch: string) => ({
@@ -1199,17 +1239,17 @@ export function runCrossScreenElementDrop(
1199
1239
  ),
1200
1240
  branch: "anchored-flow-insert",
1201
1241
  };
1202
- if (!targetLocalPoint) {
1242
+ if (!targetPositionPoint) {
1203
1243
  if (targetAnchorAttrId && targetDropMode !== "absolute-container") {
1204
1244
  return flowInsert;
1205
1245
  }
1206
1246
  return { content: stylePreservedDest, branch: "rooted-no-point" };
1207
1247
  }
1208
1248
  if (placeAbsoluteOnEmptyScreen) {
1209
- return absolute(targetLocalPoint, "empty-screen-absolute");
1249
+ return absolute(targetPositionPoint, "empty-screen-absolute");
1210
1250
  }
1211
1251
  if (!targetAnchorAttrId) {
1212
- return absolute(targetLocalPoint, "rooted-absolute");
1252
+ return absolute(targetPositionPoint, "rooted-absolute");
1213
1253
  }
1214
1254
  if (targetDropMode === "absolute-container") {
1215
1255
  if (!targetAnchorRect) {
@@ -1222,7 +1262,7 @@ export function runCrossScreenElementDrop(
1222
1262
  absolutePlacePointForDrop({
1223
1263
  placeAbsoluteOnEmptyScreen,
1224
1264
  targetAnchorRect,
1225
- targetLocalPoint,
1265
+ targetLocalPoint: targetPositionPoint,
1226
1266
  }),
1227
1267
  "anchored-absolute",
1228
1268
  );
@@ -1237,6 +1277,7 @@ export function runCrossScreenElementDrop(
1237
1277
  `${placed.branch} node=${destNodeAttrId} target=${targetScreenId}` +
1238
1278
  ` anchor=${targetAnchorAttrId ?? "none"} mode=${targetDropMode ?? "none"}` +
1239
1279
  ` local=${point(targetLocalPoint)}` +
1280
+ ` authored=${point(targetPositionPoint)}` +
1240
1281
  ` anchorRect=${targetAnchorRect ? `${Math.round(targetAnchorRect.left)},${Math.round(targetAnchorRect.top)}` : "none"}` +
1241
1282
  ` grab=${point(sourcePointerOffset)}`,
1242
1283
  );
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-10-01
4
+ ---
5
+
6
+ The Design home opens on Recent when designs are available, hides the empty Recent tab, and distinguishes designs you own from those shared with you.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-10-03
4
+ ---
5
+
6
+ Layers dropped into visible canvas space beyond a Screen now stay on the board.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-10-03
4
+ ---
5
+
6
+ Visible Screen overflow no longer routes drops to the canvas
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-10-05
4
+ ---
5
+
6
+ The Recent tab shows loading placeholders until your designs are ready.
@@ -28,6 +28,7 @@
28
28
  "dependencies": {
29
29
  "@agent-native/core": "workspace:*",
30
30
  "@agent-native/creative-context": "workspace:*",
31
+ "@agent-native/otel": "workspace:*",
31
32
  "@agent-native/toolkit": "workspace:*",
32
33
  "@electric-sql/pglite": "^0.5.8",
33
34
  "@fontsource-variable/inter": "^5.2.8",
@@ -7,7 +7,8 @@ export default createAuthPlugin({
7
7
  workspaceAppPublicPaths: ["/", "/visual-edit", "/design", "/present"],
8
8
  marketing: {
9
9
  appName: "Design",
10
- learnMoreUrl: "https://agent-native.com/apps/design",
10
+ learnMoreUrl:
11
+ "https://agent-native.com/apps/design?utm_source=app&utm_medium=product&utm_content=onboarding-learn-more",
11
12
  tagline:
12
13
  "Design and prototype by describing what you want. The AI agent turns your ideas into interactive, fully responsive designs in seconds.",
13
14
  features: [
@@ -0,0 +1,6 @@
1
+ import { defineNitroPlugin } from "@agent-native/core/server";
2
+ import { startAgentNativeOtel } from "@agent-native/otel";
3
+
4
+ export default defineNitroPlugin(() => {
5
+ startAgentNativeOtel();
6
+ });
@@ -290,9 +290,16 @@ export default defineEventHandler(async (event) => {
290
290
 
291
291
  ## Data Scoping
292
292
 
293
- In production, the framework automatically restricts all agent SQL queries to the current user's data using temporary views. This is enforced at the SQL level — the agent cannot bypass it.
293
+ In production, the framework automatically restricts all agent SQL queries to the current user's data using temporary views, and checks every statement before it runs so it can only reach those views.
294
294
 
295
- The `db-query` / `db-exec` tools (and the extension SQL bridge, which shares the same path) reject schema-qualified table references like `public.<table>` — a qualified name resolves to the base table and would skip the temp view. Use bare table names; scoping is applied automatically.
295
+ The `db-query` / `db-exec` / `db-patch` tools (and the extension SQL bridge, which shares the same path) read each statement the way Postgres does and refuse anything that could reach data around the temp views:
296
+
297
+ - schema- or database-qualified names like `public.<table>`, which resolve to the base table;
298
+ - names that resolve to anything other than the current user's temp views, such as materialized views or tables the scoping does not cover;
299
+ - app-defined SQL or PL/pgSQL functions and operators, whose bodies read tables without the views;
300
+ - built-ins that run SQL text, change session settings, or reach outside the database (`query_to_xml`, `set_config`, `dblink`, most `pg_*` functions).
301
+
302
+ `db-query` runs in a read-only transaction, and an `INSERT` must list its columns when the table has access-control columns. Use bare table names and plain expressions; scoping is applied automatically. When the agent needs data the views do not expose, add an app action with its own access checks.
296
303
 
297
304
  ### Per-User Scoping (`owner_email`)
298
305
 
@@ -75,10 +75,11 @@ state their PostgreSQL types directly.
75
75
 
76
76
  Member offboarding and email changes refuse to run while any column named
77
77
  `email`, `*_email`, `*scope_id`, `created_by`, `updated_by`, `invited_by`,
78
- `owner`, `principal_id`, `session_id`, or `user_id` has no policy. `owner_email`
79
- and `createSharesTable()` tables are handled for you. Declare every other one,
80
- including columns that are not member identities, from the app's database
81
- plugin graph (Clips does it in `server/db/index.ts`):
78
+ `owner`, `principal_id`, `session_id`, or `user_id` has no policy.
79
+ `createSharesTable()` tables are handled for you, and undeclared `owner_email`
80
+ columns transfer to the successor, which is right only for owned content.
81
+ Declare every other one, including columns that are not member identities, from
82
+ the app's database plugin graph (Clips does it in `server/db/index.ts`):
82
83
 
83
84
  ```ts
84
85
  import { registerIdentityColumns } from "@agent-native/core/org";
@@ -88,13 +89,17 @@ registerIdentityColumns([
88
89
  { table: "space_members", column: "email", emailChange: "rekey", offboard: "delete", orgScope: { column: "space_id", references: { table: "spaces", column: "id", orgColumn: "org_id" } }, reason: "Space membership grants access." },
89
90
  // Someone else's address: never rewritten.
90
91
  { table: "meeting_participants", column: "email", emailChange: "retain", offboard: "retain", reason: "Attendee address from the calendar provider." },
92
+ // A credential in an owner_email table: never handed to the successor.
93
+ { table: "api_keys", column: "owner_email", emailChange: "rekey", offboard: "revoke", reason: "Bearer keys act as their owner." },
91
94
  ]);
92
95
  ```
93
96
 
94
- Choose `delete` for grants, credentials, and pending tokens; `retain` for
97
+ Choose `delete` for grants, credentials, and pending tokens, or `revoke` (sets
98
+ `revoked_at`) when a reader treats a missing row as "not revoked"; `retain` for
95
99
  attribution, history, and third-party addresses; `transfer` only for owned
96
- data. A table without `org_id` needs `orgScope` or an organization-scoped
97
- removal leaves its rows alone.
100
+ data. Declare `owner_email` tables that hold credentials or grants, or
101
+ offboarding hands them to the successor. A table without `org_id` needs
102
+ `orgScope` or an organization-scoped removal leaves its rows alone.
98
103
 
99
104
  | Template | Tables |
100
105
  | ------------ | --------------------------------------------- |
@@ -4,7 +4,7 @@ The agent-native workspace control plane — a central Slack/Telegram inbox, a
4
4
  secrets vault, scheduled jobs, approvals, and an orchestrator agent that delegates
5
5
  work to the right specialist app over A2A.
6
6
 
7
- **Live app: [dispatch.agent-native.com](https://dispatch.agent-native.com)**
7
+ **Live app: [dispatch.agent-native.com](https://dispatch.agent-native.com?utm_source=github&utm_medium=referral&utm_content=dispatch-readme)**
8
8
 
9
9
  Where other templates are domain apps (Mail, Calendar, Analytics, Brain),
10
10
  Dispatch is the app you run _alongside_ them to coordinate everything. It routes
@@ -31,4 +31,4 @@ pnpm install
31
31
  pnpm dev
32
32
  ```
33
33
 
34
- Full docs: [agent-native.com/docs/template-dispatch](https://agent-native.com/docs/template-dispatch).
34
+ Full docs: [agent-native.com/docs/template-dispatch](https://agent-native.com/docs/template-dispatch?utm_source=github&utm_medium=referral&utm_content=dispatch-readme).
@@ -16,6 +16,7 @@
16
16
  "dependencies": {
17
17
  "@agent-native/core": "workspace:*",
18
18
  "@agent-native/dispatch": "workspace:*",
19
+ "@agent-native/otel": "workspace:*",
19
20
  "@agent-native/toolkit": "workspace:*",
20
21
  "@ai-sdk/openai": "^3.0.53",
21
22
  "@electric-sql/pglite": "^0.5.8",
@@ -0,0 +1,6 @@
1
+ import { defineNitroPlugin } from "@agent-native/core/server";
2
+ import { startAgentNativeOtel } from "@agent-native/otel";
3
+
4
+ export default defineNitroPlugin(() => {
5
+ startAgentNativeOtel();
6
+ });
@@ -3,7 +3,8 @@ import { setupDispatch } from "@agent-native/dispatch/server";
3
3
  export default setupDispatch({
4
4
  auth: {
5
5
  marketing: {
6
- learnMoreUrl: "https://agent-native.com/apps/dispatch",
6
+ learnMoreUrl:
7
+ "https://agent-native.com/apps/dispatch?utm_source=app&utm_medium=product&utm_content=onboarding-learn-more",
7
8
  },
8
9
  publicPaths: [
9
10
  "/_agent-native/identity/availability",