@agent-native/core 0.133.3 → 0.134.1

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 (221) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +62 -0
  3. package/corpus/core/docs/content/observability.mdx +41 -1
  4. package/corpus/core/docs/content/template-content-developers.mdx +1 -1
  5. package/corpus/core/docs/content/tracking.mdx +25 -0
  6. package/corpus/core/package.json +1 -1
  7. package/corpus/core/src/agent/run-manager.ts +7 -0
  8. package/corpus/core/src/client/agent-chat-adapter.ts +10 -0
  9. package/corpus/core/src/client/analytics.ts +105 -1
  10. package/corpus/core/src/deploy/build.ts +38 -1
  11. package/corpus/core/src/observability/posthog-ai.ts +294 -0
  12. package/corpus/core/src/observability/routes.ts +29 -6
  13. package/corpus/core/src/observability/traces.ts +287 -12
  14. package/corpus/core/src/observability/types.ts +11 -0
  15. package/corpus/core/src/secrets/register-framework-secrets.ts +16 -0
  16. package/corpus/core/src/server/agent-run-context.ts +21 -0
  17. package/corpus/core/src/server/capture-error.ts +8 -0
  18. package/corpus/core/src/server/core-routes-plugin.ts +75 -4
  19. package/corpus/core/src/server/deploy-environment.ts +57 -0
  20. package/corpus/core/src/server/error-noise-filter.ts +268 -0
  21. package/corpus/core/src/server/posthog-config.ts +75 -0
  22. package/corpus/core/src/server/request-context.ts +6 -0
  23. package/corpus/core/src/server/sentry-config.ts +4 -8
  24. package/corpus/core/src/server/sentry-plugin.ts +13 -29
  25. package/corpus/core/src/server/sentry.ts +13 -156
  26. package/corpus/core/src/server/ssr-handler.ts +6 -1
  27. package/corpus/core/src/shared/mcp-embed-headers.ts +1 -1
  28. package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +36 -10
  29. package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +55 -1
  30. package/corpus/core/src/tracking/error-capture.ts +44 -109
  31. package/corpus/core/src/tracking/index.ts +11 -0
  32. package/corpus/core/src/tracking/posthog-exception.ts +305 -0
  33. package/corpus/core/src/tracking/providers.ts +91 -14
  34. package/corpus/core/src/tracking/redaction.ts +105 -0
  35. package/corpus/templates/clips/changelog/2026-07-29-meeting-notes-no-longer-transcribe-the-other-side-twice-when.md +6 -0
  36. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +37 -48
  37. package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +7 -5
  38. package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +182 -106
  39. package/corpus/templates/clips/desktop/src/overlays/live-transcript.tsx +43 -14
  40. package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +3 -3
  41. package/corpus/templates/clips/desktop/src-tauri/src/echo_guard.rs +443 -0
  42. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +1 -0
  43. package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +125 -16
  44. package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +6 -4
  45. package/corpus/templates/content/actions/_database-membership-lock.ts +25 -0
  46. package/corpus/templates/content/actions/_database-row-batch.ts +6 -2
  47. package/corpus/templates/content/actions/_database-source-utils.ts +289 -129
  48. package/corpus/templates/content/actions/_database-utils.ts +12 -3
  49. package/corpus/templates/content/actions/add-content-database-source-field-property.ts +39 -21
  50. package/corpus/templates/content/actions/attach-content-database-source.ts +4 -1
  51. package/corpus/templates/content/actions/change-content-database-source-role.ts +3 -5
  52. package/corpus/templates/content/actions/duplicate-document-property.ts +59 -46
  53. package/corpus/templates/content/actions/execute-builder-source-execution.ts +77 -71
  54. package/corpus/templates/content/actions/materialize-builder-required-fields.ts +7 -0
  55. package/corpus/templates/content/actions/remove-database-items.ts +183 -0
  56. package/corpus/templates/content/actions/set-document-property.ts +57 -39
  57. package/corpus/templates/content/actions/sync-local-folder-source.ts +7 -0
  58. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +471 -329
  59. package/corpus/templates/content/app/components/editor/database/row-access.ts +45 -0
  60. package/corpus/templates/content/app/components/editor/database/shared.tsx +141 -38
  61. package/corpus/templates/content/app/hooks/use-content-database.ts +2 -2
  62. package/corpus/templates/content/app/i18n-data.ts +130 -0
  63. package/corpus/templates/content/changelog/2026-07-30-database-rows-can-now-be-removed-without-deleting-their-page.md +6 -0
  64. package/corpus/templates/content/parity/eval-scenarios.ts +2 -2
  65. package/corpus/templates/content/parity/matrix.md +1 -1
  66. package/corpus/templates/content/parity/matrix.ts +4 -5
  67. package/corpus/templates/content/shared/api.ts +4 -0
  68. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +26 -11
  69. package/corpus/templates/design/actions/take-design-screenshot.ts +7 -0
  70. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +11 -3
  71. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +4 -1
  72. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +54 -17
  73. package/corpus/templates/design/app/components/design/design-canvas/local-runtime.ts +126 -0
  74. package/corpus/templates/design/app/components/templates/TemplatePreview.tsx +2 -0
  75. package/corpus/templates/design/app/pages/Index.tsx +3 -1
  76. package/corpus/templates/design/app/pages/Present.tsx +2 -1
  77. package/corpus/templates/design/changelog/2026-07-30-a-broken-inline-script-in-a-generated-screen-is-now-caught-o.md +6 -0
  78. package/corpus/templates/design/changelog/2026-07-30-design-html-is-now-validated-with-a-spec-grade-html-parser-i.md +6 -0
  79. package/corpus/templates/design/changelog/2026-07-30-designs-now-load-their-tailwind-and-alpine-runtimes-from-the.md +6 -0
  80. package/corpus/templates/design/changelog/2026-07-30-designs-with-a-broken-alpine-expression-are-now-caught-on-sa.md +6 -0
  81. package/corpus/templates/design/changelog/2026-07-30-editing-a-design-no-longer-strips-its-styling-the-canvas-kep.md +6 -0
  82. package/corpus/templates/design/package.json +4 -0
  83. package/corpus/templates/design/shared/html-integrity.ts +802 -556
  84. package/dist/agent/run-manager.d.ts.map +1 -1
  85. package/dist/agent/run-manager.js +7 -0
  86. package/dist/agent/run-manager.js.map +1 -1
  87. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  88. package/dist/client/agent-chat-adapter.js +12 -0
  89. package/dist/client/agent-chat-adapter.js.map +1 -1
  90. package/dist/client/analytics.d.ts +8 -0
  91. package/dist/client/analytics.d.ts.map +1 -1
  92. package/dist/client/analytics.js +95 -1
  93. package/dist/client/analytics.js.map +1 -1
  94. package/dist/collab/routes.d.ts +1 -1
  95. package/dist/collab/struct-routes.d.ts +1 -1
  96. package/dist/deploy/build.d.ts.map +1 -1
  97. package/dist/deploy/build.js +38 -1
  98. package/dist/deploy/build.js.map +1 -1
  99. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  100. package/dist/notifications/routes.d.ts +1 -1
  101. package/dist/observability/posthog-ai.d.ts +126 -0
  102. package/dist/observability/posthog-ai.d.ts.map +1 -0
  103. package/dist/observability/posthog-ai.js +190 -0
  104. package/dist/observability/posthog-ai.js.map +1 -0
  105. package/dist/observability/routes.d.ts +3 -3
  106. package/dist/observability/routes.d.ts.map +1 -1
  107. package/dist/observability/routes.js +26 -6
  108. package/dist/observability/routes.js.map +1 -1
  109. package/dist/observability/traces.d.ts +9 -0
  110. package/dist/observability/traces.d.ts.map +1 -1
  111. package/dist/observability/traces.js +219 -10
  112. package/dist/observability/traces.js.map +1 -1
  113. package/dist/observability/types.d.ts +10 -0
  114. package/dist/observability/types.d.ts.map +1 -1
  115. package/dist/observability/types.js +1 -0
  116. package/dist/observability/types.js.map +1 -1
  117. package/dist/progress/routes.d.ts +1 -1
  118. package/dist/resources/handlers.d.ts +1 -1
  119. package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
  120. package/dist/secrets/register-framework-secrets.js +14 -0
  121. package/dist/secrets/register-framework-secrets.js.map +1 -1
  122. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  123. package/dist/server/agent-run-context.d.ts +8 -0
  124. package/dist/server/agent-run-context.d.ts.map +1 -1
  125. package/dist/server/agent-run-context.js +18 -0
  126. package/dist/server/agent-run-context.js.map +1 -1
  127. package/dist/server/capture-error.d.ts +8 -0
  128. package/dist/server/capture-error.d.ts.map +1 -1
  129. package/dist/server/capture-error.js.map +1 -1
  130. package/dist/server/core-routes-plugin.d.ts +0 -23
  131. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  132. package/dist/server/core-routes-plugin.js +71 -7
  133. package/dist/server/core-routes-plugin.js.map +1 -1
  134. package/dist/server/deploy-environment.d.ts +17 -0
  135. package/dist/server/deploy-environment.d.ts.map +1 -0
  136. package/dist/server/deploy-environment.js +47 -0
  137. package/dist/server/deploy-environment.js.map +1 -0
  138. package/dist/server/error-noise-filter.d.ts +80 -0
  139. package/dist/server/error-noise-filter.d.ts.map +1 -0
  140. package/dist/server/error-noise-filter.js +173 -0
  141. package/dist/server/error-noise-filter.js.map +1 -0
  142. package/dist/server/posthog-config.d.ts +28 -0
  143. package/dist/server/posthog-config.d.ts.map +1 -0
  144. package/dist/server/posthog-config.js +53 -0
  145. package/dist/server/posthog-config.js.map +1 -0
  146. package/dist/server/request-context.d.ts +6 -0
  147. package/dist/server/request-context.d.ts.map +1 -1
  148. package/dist/server/request-context.js.map +1 -1
  149. package/dist/server/sentry-config.d.ts +1 -0
  150. package/dist/server/sentry-config.d.ts.map +1 -1
  151. package/dist/server/sentry-config.js +3 -1
  152. package/dist/server/sentry-config.js.map +1 -1
  153. package/dist/server/sentry-plugin.d.ts.map +1 -1
  154. package/dist/server/sentry-plugin.js +12 -27
  155. package/dist/server/sentry-plugin.js.map +1 -1
  156. package/dist/server/sentry.d.ts.map +1 -1
  157. package/dist/server/sentry.js +8 -124
  158. package/dist/server/sentry.js.map +1 -1
  159. package/dist/server/ssr-handler.d.ts.map +1 -1
  160. package/dist/server/ssr-handler.js +6 -1
  161. package/dist/server/ssr-handler.js.map +1 -1
  162. package/dist/server/transcribe-voice.d.ts +1 -1
  163. package/dist/shared/mcp-embed-headers.d.ts +1 -1
  164. package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
  165. package/dist/shared/mcp-embed-headers.js +1 -1
  166. package/dist/shared/mcp-embed-headers.js.map +1 -1
  167. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +36 -10
  168. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +55 -1
  169. package/dist/tracking/error-capture.d.ts +7 -0
  170. package/dist/tracking/error-capture.d.ts.map +1 -1
  171. package/dist/tracking/error-capture.js +10 -73
  172. package/dist/tracking/error-capture.js.map +1 -1
  173. package/dist/tracking/index.d.ts +1 -0
  174. package/dist/tracking/index.d.ts.map +1 -1
  175. package/dist/tracking/index.js +1 -0
  176. package/dist/tracking/index.js.map +1 -1
  177. package/dist/tracking/posthog-exception.d.ts +103 -0
  178. package/dist/tracking/posthog-exception.d.ts.map +1 -0
  179. package/dist/tracking/posthog-exception.js +181 -0
  180. package/dist/tracking/posthog-exception.js.map +1 -0
  181. package/dist/tracking/providers.d.ts +14 -0
  182. package/dist/tracking/providers.d.ts.map +1 -1
  183. package/dist/tracking/providers.js +63 -11
  184. package/dist/tracking/providers.js.map +1 -1
  185. package/dist/tracking/redaction.d.ts +25 -0
  186. package/dist/tracking/redaction.d.ts.map +1 -0
  187. package/dist/tracking/redaction.js +85 -0
  188. package/dist/tracking/redaction.js.map +1 -0
  189. package/docs/content/observability.mdx +41 -1
  190. package/docs/content/template-content-developers.mdx +1 -1
  191. package/docs/content/tracking.mdx +25 -0
  192. package/package.json +1 -1
  193. package/src/agent/run-manager.ts +7 -0
  194. package/src/client/agent-chat-adapter.ts +10 -0
  195. package/src/client/analytics.ts +105 -1
  196. package/src/deploy/build.ts +38 -1
  197. package/src/observability/posthog-ai.ts +294 -0
  198. package/src/observability/routes.ts +29 -6
  199. package/src/observability/traces.ts +287 -12
  200. package/src/observability/types.ts +11 -0
  201. package/src/secrets/register-framework-secrets.ts +16 -0
  202. package/src/server/agent-run-context.ts +21 -0
  203. package/src/server/capture-error.ts +8 -0
  204. package/src/server/core-routes-plugin.ts +75 -4
  205. package/src/server/deploy-environment.ts +57 -0
  206. package/src/server/error-noise-filter.ts +268 -0
  207. package/src/server/posthog-config.ts +75 -0
  208. package/src/server/request-context.ts +6 -0
  209. package/src/server/sentry-config.ts +4 -8
  210. package/src/server/sentry-plugin.ts +13 -29
  211. package/src/server/sentry.ts +13 -156
  212. package/src/server/ssr-handler.ts +6 -1
  213. package/src/shared/mcp-embed-headers.ts +1 -1
  214. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +36 -10
  215. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +55 -1
  216. package/src/tracking/error-capture.ts +44 -109
  217. package/src/tracking/index.ts +11 -0
  218. package/src/tracking/posthog-exception.ts +305 -0
  219. package/src/tracking/providers.ts +91 -14
  220. package/src/tracking/redaction.ts +105 -0
  221. package/corpus/templates/content/actions/delete-database-items.ts +0 -89
@@ -0,0 +1,45 @@
1
+ import type { ContentDatabaseItem, ContentDatabaseSource } from "@shared/api";
2
+
3
+ export function databaseItemIsSourceBacked(
4
+ item: ContentDatabaseItem,
5
+ sources: ContentDatabaseSource[],
6
+ ) {
7
+ const membershipHydration = item.document.databaseMembership?.bodyHydration;
8
+ const hydration = item.bodyHydration ?? membershipHydration;
9
+ return (
10
+ item.sourceRecord !== undefined ||
11
+ item.document.databaseMembership?.sourceId != null ||
12
+ hydration?.version != null ||
13
+ (hydration !== undefined && hydration.status !== "hydrated") ||
14
+ sources.some((source) =>
15
+ source.rows.some((row) => row.databaseItemId === item.id),
16
+ )
17
+ );
18
+ }
19
+
20
+ export function databaseItemHasViewerAccess(item: ContentDatabaseItem) {
21
+ return item.document.canView === true;
22
+ }
23
+
24
+ export function databaseItemCanDuplicate(
25
+ item: ContentDatabaseItem,
26
+ isWorkspaceCatalog: boolean,
27
+ ) {
28
+ return !isWorkspaceCatalog && databaseItemHasViewerAccess(item);
29
+ }
30
+
31
+ export function databaseItemCanRemoveFromDatabase(args: {
32
+ item: ContentDatabaseItem;
33
+ databaseCanManage: boolean;
34
+ databaseSystemRole: string | null | undefined;
35
+ isWorkspaceCatalog: boolean;
36
+ sources: ContentDatabaseSource[];
37
+ }) {
38
+ return (
39
+ args.databaseCanManage &&
40
+ args.databaseSystemRole === null &&
41
+ databaseItemHasViewerAccess(args.item) &&
42
+ !args.isWorkspaceCatalog &&
43
+ !databaseItemIsSourceBacked(args.item, args.sources)
44
+ );
45
+ }
@@ -22,6 +22,7 @@ import {
22
22
  IconList,
23
23
  IconMinus,
24
24
  IconSearch,
25
+ IconStarOff,
25
26
  IconTable,
26
27
  IconTimeline,
27
28
  IconTrash,
@@ -53,12 +54,26 @@ import {
53
54
  DropdownMenuTrigger,
54
55
  } from "@/components/ui/dropdown-menu";
55
56
  import { Input } from "@/components/ui/input";
56
- import { useDuplicateDatabaseItem } from "@/hooks/use-content-database";
57
- import { useDeleteDocument } from "@/hooks/use-documents";
57
+ import {
58
+ isContentDatabaseUnavailable,
59
+ useContentDatabase,
60
+ useDuplicateDatabaseItem,
61
+ useRemoveDatabaseItems,
62
+ } from "@/hooks/use-content-database";
63
+ import {
64
+ useContentSpaces,
65
+ useDeleteContentSpace,
66
+ } from "@/hooks/use-content-spaces";
67
+ import { useDocument } from "@/hooks/use-documents";
58
68
  import { cn } from "@/lib/utils";
59
69
 
60
70
  import { OPTION_COLOR_CLASSES, TYPE_ICONS } from "../DocumentProperties";
61
71
  import { databaseDuplicatedItemFromResponse } from "./navigation-state";
72
+ import {
73
+ databaseItemCanDuplicate,
74
+ databaseItemCanRemoveFromDatabase,
75
+ } from "./row-access";
76
+ import { dbText } from "./text";
62
77
  import type { DatabaseBoardGroup, DatabaseDropSide } from "./types";
63
78
 
64
79
  // ---------------------------------------------------------------------------
@@ -518,13 +533,44 @@ export function RowActionsCell({
518
533
  onOpenPage: () => void;
519
534
  }) {
520
535
  const queryClient = useQueryClient();
521
- const deleteDocument = useDeleteDocument();
536
+ const contentSpaces = useContentSpaces();
537
+ const { data: databaseDocument } = useDocument(databaseDocumentId);
538
+ const databaseQuery = useContentDatabase(databaseDocumentId);
522
539
  const duplicateItem = useDuplicateDatabaseItem(databaseDocumentId);
540
+ const removeItems = useRemoveDatabaseItems(databaseDocumentId);
541
+ const deleteContentSpace = useDeleteContentSpace();
523
542
  const [menuOpen, setMenuOpen] = useState(false);
524
543
  const [confirmDeleteOpen, setConfirmDeleteOpen] = useState(false);
525
544
  const title = item.document.title || "Untitled";
545
+ const removesFavoriteMembership =
546
+ contentSpaces.data?.favoritesDocumentId === databaseDocumentId;
547
+ const isWorkspaceCatalog =
548
+ contentSpaces.data?.catalogDocumentId === databaseDocumentId;
549
+ const workspaceSpace = contentSpaces.data?.spaces.find(
550
+ (space) => space.catalogDocumentId === item.document.id,
551
+ );
552
+ const canDeleteWorkspace =
553
+ isWorkspaceCatalog && workspaceSpace?.kind === "user";
554
+ const databaseData = isContentDatabaseUnavailable(databaseQuery.data)
555
+ ? undefined
556
+ : databaseQuery.data;
557
+ const databaseSources =
558
+ databaseData?.sources ??
559
+ (databaseData?.source ? [databaseData.source] : []);
560
+ const canRemoveFromDatabase = removesFavoriteMembership
561
+ ? databaseDocument?.canEdit === true
562
+ : databaseData !== undefined &&
563
+ databaseItemCanRemoveFromDatabase({
564
+ item,
565
+ databaseCanManage: databaseDocument?.canManage === true,
566
+ databaseSystemRole: databaseData.database.systemRole,
567
+ isWorkspaceCatalog,
568
+ sources: databaseSources,
569
+ });
570
+ const canDuplicateRow = databaseItemCanDuplicate(item, isWorkspaceCatalog);
526
571
 
527
572
  async function duplicateRow() {
573
+ if (!canDuplicateRow) return;
528
574
  setMenuOpen(false);
529
575
  try {
530
576
  const response = await duplicateItem.mutateAsync({ itemId: item.id });
@@ -538,10 +584,21 @@ export function RowActionsCell({
538
584
  }
539
585
  }
540
586
 
541
- async function deleteRow() {
587
+ async function removeRowOrDeleteWorkspace() {
588
+ if (!canRemoveFromDatabase && !canDeleteWorkspace) {
589
+ setConfirmDeleteOpen(false);
590
+ return;
591
+ }
542
592
  const previewMoved = onDeletedPreviewItem?.(item) ?? false;
543
593
  try {
544
- await deleteDocument.mutateAsync({ id: item.document.id });
594
+ if (canDeleteWorkspace && workspaceSpace) {
595
+ await deleteContentSpace.mutateAsync({ spaceId: workspaceSpace.id });
596
+ } else {
597
+ await removeItems.mutateAsync({
598
+ documentId: databaseDocumentId,
599
+ documentIds: [item.document.id],
600
+ });
601
+ }
545
602
  await queryClient.invalidateQueries({
546
603
  queryKey: [
547
604
  "action",
@@ -554,10 +611,15 @@ export function RowActionsCell({
554
611
  });
555
612
  } catch (err) {
556
613
  if (previewMoved) onPreviewItem?.(item);
557
- toast.error("Failed to delete row", {
558
- description:
559
- err instanceof Error ? err.message : "Something went wrong",
560
- });
614
+ toast.error(
615
+ canDeleteWorkspace
616
+ ? "Failed to delete workspace"
617
+ : dbText("failedToRemoveRowFromDatabase"),
618
+ {
619
+ description:
620
+ err instanceof Error ? err.message : "Something went wrong",
621
+ },
622
+ );
561
623
  }
562
624
  }
563
625
 
@@ -584,48 +646,89 @@ export function RowActionsCell({
584
646
  <IconExternalLink className="mr-2 size-4 text-muted-foreground" />
585
647
  Open page
586
648
  </DropdownMenuItem>
587
- <DropdownMenuItem
588
- disabled={duplicateItem.isPending}
589
- onSelect={(event) => {
590
- event.preventDefault();
591
- void duplicateRow();
592
- }}
593
- >
594
- <IconCopy className="mr-2 size-4 text-muted-foreground" />
595
- Duplicate row
596
- </DropdownMenuItem>
597
- <DropdownMenuSeparator />
598
- <DropdownMenuItem
599
- className="text-destructive focus:bg-destructive/10 focus:text-destructive"
600
- onSelect={(event) => {
601
- event.preventDefault();
602
- setMenuOpen(false);
603
- setConfirmDeleteOpen(true);
604
- }}
605
- >
606
- <IconTrash className="mr-2 size-4" />
607
- Delete row
608
- </DropdownMenuItem>
649
+ {canDuplicateRow ? (
650
+ <DropdownMenuItem
651
+ disabled={duplicateItem.isPending}
652
+ onSelect={(event) => {
653
+ event.preventDefault();
654
+ void duplicateRow();
655
+ }}
656
+ >
657
+ <IconCopy className="mr-2 size-4 text-muted-foreground" />
658
+ Duplicate row
659
+ </DropdownMenuItem>
660
+ ) : null}
661
+ {canRemoveFromDatabase || canDeleteWorkspace ? (
662
+ <DropdownMenuSeparator />
663
+ ) : null}
664
+ {canRemoveFromDatabase || canDeleteWorkspace ? (
665
+ <DropdownMenuItem
666
+ className="text-destructive focus:bg-destructive/10 focus:text-destructive"
667
+ onSelect={(event) => {
668
+ event.preventDefault();
669
+ setMenuOpen(false);
670
+ if (removesFavoriteMembership) {
671
+ void removeRowOrDeleteWorkspace();
672
+ } else {
673
+ setConfirmDeleteOpen(true);
674
+ }
675
+ }}
676
+ >
677
+ {removesFavoriteMembership ? (
678
+ <IconStarOff className="mr-2 size-4 text-muted-foreground" />
679
+ ) : (
680
+ <IconTrash className="mr-2 size-4" />
681
+ )}
682
+ {removesFavoriteMembership
683
+ ? "Remove from favorites"
684
+ : canDeleteWorkspace
685
+ ? "Delete workspace"
686
+ : dbText("removeFromDatabase")}
687
+ </DropdownMenuItem>
688
+ ) : null}
609
689
  </DropdownMenuContent>
610
690
  </DropdownMenu>
611
691
 
612
- <AlertDialog open={confirmDeleteOpen} onOpenChange={setConfirmDeleteOpen}>
692
+ <AlertDialog
693
+ open={
694
+ !removesFavoriteMembership &&
695
+ (canRemoveFromDatabase || canDeleteWorkspace) &&
696
+ confirmDeleteOpen
697
+ }
698
+ onOpenChange={setConfirmDeleteOpen}
699
+ >
613
700
  <AlertDialogContent>
614
701
  <AlertDialogHeader>
615
- <AlertDialogTitle>Delete row?</AlertDialogTitle>
702
+ <AlertDialogTitle>
703
+ {canDeleteWorkspace
704
+ ? "Delete workspace?"
705
+ : dbText("removeFromDatabaseQuestion")}
706
+ </AlertDialogTitle>
616
707
  <AlertDialogDescription>
617
- &ldquo;{title}&rdquo; and any sub-pages will be permanently
618
- deleted. This cannot be undone.
708
+ {canDeleteWorkspace ? (
709
+ <>
710
+ &ldquo;{title}&rdquo; and every page and database inside it
711
+ will be permanently deleted. This cannot be undone.
712
+ </>
713
+ ) : (
714
+ dbText("removeFromDatabaseDescription", { title })
715
+ )}
619
716
  </AlertDialogDescription>
620
717
  </AlertDialogHeader>
621
718
  <AlertDialogFooter>
622
719
  <AlertDialogCancel>Cancel</AlertDialogCancel>
623
720
  <AlertDialogAction
624
721
  className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
625
- disabled={deleteDocument.isPending}
626
- onClick={() => void deleteRow()}
722
+ disabled={removeItems.isPending || deleteContentSpace.isPending}
723
+ onClick={() => void removeRowOrDeleteWorkspace()}
627
724
  >
628
- {deleteDocument.isPending ? "Deleting..." : "Delete"}
725
+ {removeItems.isPending || deleteContentSpace.isPending
726
+ ? canDeleteWorkspace
727
+ ? "Deleting..."
728
+ : dbText("removing")
729
+ : canDeleteWorkspace
730
+ ? "Delete"
731
+ : dbText("remove")}
629
732
  </AlertDialogAction>
630
733
  </AlertDialogFooter>
631
734
  </AlertDialogContent>
@@ -927,10 +927,10 @@ export function useDuplicateDatabaseItems(documentId: string) {
927
927
  );
928
928
  }
929
929
 
930
- export function useDeleteDatabaseItems(documentId: string) {
930
+ export function useRemoveDatabaseItems(documentId: string) {
931
931
  const queryClient = useQueryClient();
932
932
  return useActionMutation<ContentDatabaseResponse, DatabaseItemsBatchRequest>(
933
- "delete-database-items",
933
+ "remove-database-items",
934
934
  {
935
935
  onSuccess: () => {
936
936
  queryClient.invalidateQueries({
@@ -92,6 +92,9 @@ const databaseMessages = {
92
92
  failedToDeleteRow: "Failed to delete row",
93
93
  failedToDeleteSelectedRows: "Failed to delete selected rows",
94
94
  failedToDuplicateEverySelectedRow: "Failed to duplicate every selected row",
95
+ failedToRemoveEverySelectedRowFromDatabase:
96
+ "Failed to remove every selected row from the database",
97
+ failedToRemoveRowFromDatabase: "Failed to remove row from database",
95
98
  failedToDuplicateRow: "Failed to duplicate row",
96
99
  failedToMoveCard: "Failed to move card",
97
100
  failedToMoveRow: "Failed to move row",
@@ -100,6 +103,15 @@ const databaseMessages = {
100
103
  failedToSaveView: "Failed to save view",
101
104
  failedToUpdateCheckbox: "Failed to update checkbox",
102
105
  failedToUpdateEverySelectedRow: "Failed to update every selected row",
106
+ removeSelectedRowsFromDatabaseQuestion: "Remove selected rows from database?",
107
+ removeSelectedRowsFromDatabaseDescription:
108
+ "The selected pages will remain available in Files and any other databases. Values belonging only to this database will be removed.",
109
+ removeFromDatabase: "Remove from database",
110
+ removeFromDatabaseQuestion: "Remove from database?",
111
+ removeFromDatabaseDescription:
112
+ "“{{title}}” will remain available in Files and any other databases. Values belonging only to this database will be removed.",
113
+ remove: "Remove",
114
+ removing: "Removing...",
103
115
  filter: "Filter",
104
116
  filterBy: "Filter by...",
105
117
  addAdvancedFilter: "Add advanced filter",
@@ -598,6 +610,17 @@ const databaseMessagesByLocale = {
598
610
  failedToDeleteRow: "删除行失败",
599
611
  failedToDeleteSelectedRows: "删除所选行失败",
600
612
  failedToDuplicateEverySelectedRow: "未能复制所有选中行",
613
+ failedToRemoveEverySelectedRowFromDatabase: "无法从数据库中移除所有选中行",
614
+ failedToRemoveRowFromDatabase: "无法从数据库中移除该行",
615
+ removeSelectedRowsFromDatabaseQuestion: "从数据库中移除选中行?",
616
+ removeSelectedRowsFromDatabaseDescription:
617
+ "所选页面仍可在“文件”和其他数据库中使用。仅属于此数据库的值将被移除。",
618
+ removeFromDatabase: "从数据库中移除",
619
+ removeFromDatabaseQuestion: "从数据库中移除?",
620
+ removeFromDatabaseDescription:
621
+ "“{{title}}”仍可在“文件”和其他数据库中使用。仅属于此数据库的值将被移除。",
622
+ remove: "移除",
623
+ removing: "正在移除...",
601
624
  failedToDuplicateRow: "复制行失败",
602
625
  failedToMoveCard: "移动卡片失败",
603
626
  failedToMoveRow: "移动行失败",
@@ -819,6 +842,20 @@ const databaseMessagesByLocale = {
819
842
  "No se pudieron eliminar las filas seleccionadas",
820
843
  failedToDuplicateEverySelectedRow:
821
844
  "No se pudieron duplicar todas las filas seleccionadas",
845
+ failedToRemoveEverySelectedRowFromDatabase:
846
+ "No se pudieron quitar todas las filas seleccionadas de la base de datos",
847
+ failedToRemoveRowFromDatabase:
848
+ "No se pudo quitar la fila de la base de datos",
849
+ removeSelectedRowsFromDatabaseQuestion:
850
+ "¿Quitar las filas seleccionadas de la base de datos?",
851
+ removeSelectedRowsFromDatabaseDescription:
852
+ "Las páginas seleccionadas seguirán disponibles en Archivos y en otras bases de datos. Se quitarán los valores que solo pertenecen a esta base de datos.",
853
+ removeFromDatabase: "Quitar de la base de datos",
854
+ removeFromDatabaseQuestion: "¿Quitar de la base de datos?",
855
+ removeFromDatabaseDescription:
856
+ "“{{title}}” seguirá disponible en Archivos y en otras bases de datos. Se quitarán los valores que solo pertenecen a esta base de datos.",
857
+ remove: "Quitar",
858
+ removing: "Quitando...",
822
859
  failedToDuplicateRow: "No se pudo duplicar la fila",
823
860
  failedToMoveCard: "No se pudo mover la tarjeta",
824
861
  failedToMoveRow: "No se pudo mover la fila",
@@ -1043,6 +1080,20 @@ const databaseMessagesByLocale = {
1043
1080
  "Échec de la suppression des lignes sélectionnées",
1044
1081
  failedToDuplicateEverySelectedRow:
1045
1082
  "Impossible de dupliquer toutes les lignes sélectionnées",
1083
+ failedToRemoveEverySelectedRowFromDatabase:
1084
+ "Impossible de retirer toutes les lignes sélectionnées de la base de données",
1085
+ failedToRemoveRowFromDatabase:
1086
+ "Impossible de retirer la ligne de la base de données",
1087
+ removeSelectedRowsFromDatabaseQuestion:
1088
+ "Retirer les lignes sélectionnées de la base de données ?",
1089
+ removeSelectedRowsFromDatabaseDescription:
1090
+ "Les pages sélectionnées resteront disponibles dans Fichiers et dans les autres bases de données. Les valeurs propres à cette base de données seront supprimées.",
1091
+ removeFromDatabase: "Retirer de la base de données",
1092
+ removeFromDatabaseQuestion: "Retirer de la base de données ?",
1093
+ removeFromDatabaseDescription:
1094
+ "« {{title}} » restera disponible dans Fichiers et dans les autres bases de données. Les valeurs propres à cette base de données seront supprimées.",
1095
+ remove: "Retirer",
1096
+ removing: "Suppression...",
1046
1097
  failedToDuplicateRow: "Échec de la duplication de la ligne",
1047
1098
  failedToMoveCard: "Échec du déplacement de la carte",
1048
1099
  failedToMoveRow: "Échec du déplacement de la ligne",
@@ -1267,6 +1318,20 @@ const databaseMessagesByLocale = {
1267
1318
  "Ausgewählte Zeilen konnten nicht gelöscht werden",
1268
1319
  failedToDuplicateEverySelectedRow:
1269
1320
  "Nicht jede ausgewählte Zeile konnte dupliziert werden",
1321
+ failedToRemoveEverySelectedRowFromDatabase:
1322
+ "Nicht alle ausgewählten Zeilen konnten aus der Datenbank entfernt werden",
1323
+ failedToRemoveRowFromDatabase:
1324
+ "Die Zeile konnte nicht aus der Datenbank entfernt werden",
1325
+ removeSelectedRowsFromDatabaseQuestion:
1326
+ "Ausgewählte Zeilen aus der Datenbank entfernen?",
1327
+ removeSelectedRowsFromDatabaseDescription:
1328
+ "Die ausgewählten Seiten bleiben unter Dateien und in anderen Datenbanken verfügbar. Werte, die nur zu dieser Datenbank gehören, werden entfernt.",
1329
+ removeFromDatabase: "Aus Datenbank entfernen",
1330
+ removeFromDatabaseQuestion: "Aus der Datenbank entfernen?",
1331
+ removeFromDatabaseDescription:
1332
+ "„{{title}}“ bleibt unter Dateien und in anderen Datenbanken verfügbar. Werte, die nur zu dieser Datenbank gehören, werden entfernt.",
1333
+ remove: "Entfernen",
1334
+ removing: "Wird entfernt...",
1270
1335
  failedToDuplicateRow: "Zeile konnte nicht dupliziert werden",
1271
1336
  failedToMoveCard: "Karte konnte nicht verschoben werden",
1272
1337
  failedToMoveRow: "Zeile konnte nicht verschoben werden",
@@ -1486,6 +1551,19 @@ const databaseMessagesByLocale = {
1486
1551
  failedToDeleteSelectedRows: "選択した行を削除できませんでした",
1487
1552
  failedToDuplicateEverySelectedRow:
1488
1553
  "選択したすべての行を複製できませんでした",
1554
+ failedToRemoveEverySelectedRowFromDatabase:
1555
+ "選択したすべての行をデータベースから削除できませんでした",
1556
+ failedToRemoveRowFromDatabase: "行をデータベースから削除できませんでした",
1557
+ removeSelectedRowsFromDatabaseQuestion:
1558
+ "選択した行をデータベースから削除しますか?",
1559
+ removeSelectedRowsFromDatabaseDescription:
1560
+ "選択したページは引き続きファイルや他のデータベースで利用できます。このデータベースにのみ属する値は削除されます。",
1561
+ removeFromDatabase: "データベースから削除",
1562
+ removeFromDatabaseQuestion: "データベースから削除しますか?",
1563
+ removeFromDatabaseDescription:
1564
+ "「{{title}}」は引き続きファイルや他のデータベースで利用できます。このデータベースにのみ属する値は削除されます。",
1565
+ remove: "削除",
1566
+ removing: "削除中...",
1489
1567
  failedToDuplicateRow: "行を複製できませんでした",
1490
1568
  failedToMoveCard: "カードを移動できませんでした",
1491
1569
  failedToMoveRow: "行を移動できませんでした",
@@ -1701,6 +1779,19 @@ const databaseMessagesByLocale = {
1701
1779
  failedToDeleteRow: "행을 삭제하지 못했습니다",
1702
1780
  failedToDeleteSelectedRows: "선택한 행을 삭제하지 못했습니다",
1703
1781
  failedToDuplicateEverySelectedRow: "선택한 모든 행을 복제하지 못했습니다",
1782
+ failedToRemoveEverySelectedRowFromDatabase:
1783
+ "선택한 모든 행을 데이터베이스에서 제거하지 못했습니다",
1784
+ failedToRemoveRowFromDatabase: "행을 데이터베이스에서 제거하지 못했습니다",
1785
+ removeSelectedRowsFromDatabaseQuestion:
1786
+ "선택한 행을 데이터베이스에서 제거할까요?",
1787
+ removeSelectedRowsFromDatabaseDescription:
1788
+ "선택한 페이지는 파일 및 다른 데이터베이스에서 계속 사용할 수 있습니다. 이 데이터베이스에만 속한 값은 제거됩니다.",
1789
+ removeFromDatabase: "데이터베이스에서 제거",
1790
+ removeFromDatabaseQuestion: "데이터베이스에서 제거할까요?",
1791
+ removeFromDatabaseDescription:
1792
+ "“{{title}}”은(는) 파일 및 다른 데이터베이스에서 계속 사용할 수 있습니다. 이 데이터베이스에만 속한 값은 제거됩니다.",
1793
+ remove: "제거",
1794
+ removing: "제거 중...",
1704
1795
  failedToDuplicateRow: "행을 복제하지 못했습니다",
1705
1796
  failedToMoveCard: "카드를 이동하지 못했습니다",
1706
1797
  failedToMoveRow: "행을 이동하지 못했습니다",
@@ -1922,6 +2013,20 @@ const databaseMessagesByLocale = {
1922
2013
  failedToDeleteSelectedRows: "Falha ao excluir linhas selecionadas",
1923
2014
  failedToDuplicateEverySelectedRow:
1924
2015
  "Falha ao duplicar todas as linhas selecionadas",
2016
+ failedToRemoveEverySelectedRowFromDatabase:
2017
+ "Não foi possível remover todas as linhas selecionadas do banco de dados",
2018
+ failedToRemoveRowFromDatabase:
2019
+ "Não foi possível remover a linha do banco de dados",
2020
+ removeSelectedRowsFromDatabaseQuestion:
2021
+ "Remover as linhas selecionadas do banco de dados?",
2022
+ removeSelectedRowsFromDatabaseDescription:
2023
+ "As páginas selecionadas continuarão disponíveis em Arquivos e em outros bancos de dados. Os valores que pertencem somente a este banco de dados serão removidos.",
2024
+ removeFromDatabase: "Remover do banco de dados",
2025
+ removeFromDatabaseQuestion: "Remover do banco de dados?",
2026
+ removeFromDatabaseDescription:
2027
+ "“{{title}}” continuará disponível em Arquivos e em outros bancos de dados. Os valores que pertencem somente a este banco de dados serão removidos.",
2028
+ remove: "Remover",
2029
+ removing: "Removendo...",
1925
2030
  failedToDuplicateRow: "Falha ao duplicar linha",
1926
2031
  failedToMoveCard: "Falha ao mover cartão",
1927
2032
  failedToMoveRow: "Falha ao mover linha",
@@ -2135,6 +2240,18 @@ const databaseMessagesByLocale = {
2135
2240
  failedToDeleteRow: "पंक्ति हटाने में विफल",
2136
2241
  failedToDeleteSelectedRows: "चुनी गई पंक्तियां हटाने में विफल",
2137
2242
  failedToDuplicateEverySelectedRow: "हर चुनी गई पंक्ति डुप्लिकेट नहीं हो सकी",
2243
+ failedToRemoveEverySelectedRowFromDatabase:
2244
+ "डेटाबेस से सभी चुनी गई पंक्तियां नहीं हटाई जा सकीं",
2245
+ failedToRemoveRowFromDatabase: "डेटाबेस से पंक्ति नहीं हटाई जा सकी",
2246
+ removeSelectedRowsFromDatabaseQuestion: "चुनी गई पंक्तियां डेटाबेस से हटाएं?",
2247
+ removeSelectedRowsFromDatabaseDescription:
2248
+ "चुने गए पेज फ़ाइलें और अन्य डेटाबेस में उपलब्ध रहेंगे। केवल इस डेटाबेस से संबंधित मान हटा दिए जाएंगे।",
2249
+ removeFromDatabase: "डेटाबेस से हटाएं",
2250
+ removeFromDatabaseQuestion: "डेटाबेस से हटाएं?",
2251
+ removeFromDatabaseDescription:
2252
+ "“{{title}}” फ़ाइलें और अन्य डेटाबेस में उपलब्ध रहेगा। केवल इस डेटाबेस से संबंधित मान हटा दिए जाएंगे।",
2253
+ remove: "हटाएं",
2254
+ removing: "हटाया जा रहा है...",
2138
2255
  failedToDuplicateRow: "पंक्ति डुप्लिकेट करने में विफल",
2139
2256
  failedToMoveCard: "कार्ड ले जाने में विफल",
2140
2257
  failedToMoveRow: "पंक्ति ले जाने में विफल",
@@ -2343,6 +2460,19 @@ const databaseMessagesByLocale = {
2343
2460
  failedToDeleteRow: "فشل حذف الصف",
2344
2461
  failedToDeleteSelectedRows: "فشل حذف الصفوف المحددة",
2345
2462
  failedToDuplicateEverySelectedRow: "تعذر تكرار كل الصفوف المحددة",
2463
+ failedToRemoveEverySelectedRowFromDatabase:
2464
+ "تعذرت إزالة كل الصفوف المحددة من قاعدة البيانات",
2465
+ failedToRemoveRowFromDatabase: "تعذرت إزالة الصف من قاعدة البيانات",
2466
+ removeSelectedRowsFromDatabaseQuestion:
2467
+ "هل تريد إزالة الصفوف المحددة من قاعدة البيانات؟",
2468
+ removeSelectedRowsFromDatabaseDescription:
2469
+ "ستظل الصفحات المحددة متاحة في الملفات وقواعد البيانات الأخرى. ستُزال القيم التي تخص قاعدة البيانات هذه فقط.",
2470
+ removeFromDatabase: "إزالة من قاعدة البيانات",
2471
+ removeFromDatabaseQuestion: "هل تريد الإزالة من قاعدة البيانات؟",
2472
+ removeFromDatabaseDescription:
2473
+ "سيظل “{{title}}” متاحا في الملفات وقواعد البيانات الأخرى. ستُزال القيم التي تخص قاعدة البيانات هذه فقط.",
2474
+ remove: "إزالة",
2475
+ removing: "جار الإزالة...",
2346
2476
  failedToDuplicateRow: "فشل تكرار الصف",
2347
2477
  failedToMoveCard: "فشل نقل البطاقة",
2348
2478
  failedToMoveRow: "فشل نقل الصف",
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-30
4
+ ---
5
+
6
+ Database rows can now be removed without deleting their pages, and bulk actions only appear when you have permission.
@@ -22,12 +22,12 @@ export const parityEvalScenarios: ParityEvalScenario[] = [
22
22
  "Using fixture Content database rows only, duplicate multiple selected rows and delete multiple selected rows through the action surface. Report the ordered duplicated item/document IDs, deleted IDs, and the verified remaining row count. Do not loop single-row duplicate or document delete actions for the multi-row operations.",
23
23
  successSignals: [
24
24
  "Uses duplicate-database-items once for the multi-row duplicate.",
25
- "Uses delete-database-items once for the multi-row delete.",
25
+ "Uses remove-database-items once for multi-row membership removal.",
26
26
  "Reports ordered duplicated item and document IDs.",
27
27
  "Reports deleted IDs and verified remaining row count.",
28
28
  "Does not use private provider credentials.",
29
29
  ],
30
- expectedTools: ["duplicate-database-items", "delete-database-items"],
30
+ expectedTools: ["duplicate-database-items", "remove-database-items"],
31
31
  },
32
32
  {
33
33
  id: "database-source-scope",
@@ -9,7 +9,7 @@ This generated matrix tracks whether high-value Content UI operations use the sa
9
9
  | database.lifecycle-and-trash | database | Create, soft-delete, restore, list, and inspect content databases | action-backed | `create-content-database`, `create-inline-content-database`, `delete-content-database`, `get-content-database`, `list-content-databases`, `list-trashed-content-databases`, `restore-content-database` | `app/components/editor/SlashCommandMenu.tsx`, `app/hooks/use-content-database.ts`, `app/hooks/use-documents.ts` | Database pages and database records are created, read, soft-deleted, restored, and listed. | - | - | P0 | covered | `actions/content-database-lifecycle.db.test.ts` | `database-source-scope` | - |
10
10
  | database.private-preview-drafts | database | Persist and reconcile a user's private database-page preview draft | action-backed | `get-preview-document-draft`, `update-preview-document-draft` | `app/components/editor/database/DatabaseView.tsx`, `app/hooks/use-documents.ts` | A user's private preview draft is read, saved, conflict-checked, or deleted without changing the shared database page until the normal save flow applies it. | These per-user editor-state actions are intentionally hidden from agent tools because preview drafts are a private UI recovery mechanism. | - | P1 | covered | `actions/preview-document-draft.db.test.ts` | - | - |
11
11
  | database.properties-and-view-config | database | Configure properties, values, ordering, and saved views | action-backed | `configure-document-property`, `delete-document-property`, `duplicate-document-property`, `get-content-database-personal-view`, `list-document-properties`, `reorder-document-property`, `set-document-property`, `update-content-database-personal-view`, `update-content-database-view` | `app/components/editor/DocumentProperties.tsx`, `app/components/editor/DocumentDatabase.tsx`, `app/components/editor/database/DatabaseView.tsx`, `app/hooks/use-document-properties.ts` | Property schemas, property values, property order, filters, sorts, grouping, hidden columns, view type, and view settings are stored. | - | - | P0 | covered | `actions/bind-content-database-source-field.db.test.ts`, `actions/content-database-source-actions.test.ts`, `actions/resync-content-database-source.db.test.ts` | `database-source-scope` | - |
12
- | database.rows | database | Add, duplicate, move, open, and delete database rows | action-backed | `add-database-item`, `delete-database-items`, `delete-document`, `duplicate-database-items`, `duplicate-database-item`, `move-database-item`, `set-document-property` | `app/components/editor/DocumentDatabase.tsx`, `app/components/editor/database/DatabaseView.tsx` | Database row backing documents and row ordering are created, duplicated, moved, edited, and deleted. | - | - | P0 | covered | `actions/database-row-batch-actions.db.test.ts`, `parity/__tests__/database-row-batch-reliability.test.ts` | `database-bulk-row-reliability` | - |
12
+ | database.rows | database | Add, duplicate, move, open, edit, and remove database rows | action-backed | `add-database-item`, `remove-database-items`, `duplicate-database-items`, `duplicate-database-item`, `move-database-item`, `set-document-property` | `app/components/editor/DocumentDatabase.tsx`, `app/components/editor/database/DatabaseView.tsx` | Database row memberships and ordering are created, duplicated, moved, edited, and removed without deleting the backing page. | - | - | P0 | covered | `actions/database-row-batch-actions.db.test.ts`, `parity/__tests__/database-row-batch-reliability.test.ts` | `database-bulk-row-reliability` | - |
13
13
  | database.table-query-page | database | Query one constrained page while retaining database metadata | action-backed | `query-content-database-items` | `app/components/editor/database/DatabaseView.tsx`, `app/hooks/use-content-database.ts` | - | This UI-only bounded projection is intentionally hidden with agentTool: false; agents use get-content-database for the complete database contract. | - | P0 | covered | `actions/content-database-lifecycle.db.test.ts`, `app/hooks/use-content-database.test.ts` | - | - |
14
14
  | editor.agent-assist-prompts | editor | Ask AI from slash generation or comment context | client-assist | - | `app/components/editor/SlashCommandMenu.tsx`, `app/components/editor/CommentsSidebar.tsx` | No direct durable mutation; the prompt asks the agent to use document actions when it decides to write. | - | - | P1 | none | - | - | - |
15
15
  | editor.client-formatting-and-insertions | editor | Rich text formatting, selection state, slash block insertion, and copy actions | client-only-ephemeral | - | `app/components/editor/BubbleToolbar.tsx`, `app/components/editor/SlashCommandMenu.tsx`, `app/components/editor/DocumentToolbar.tsx` | - | - | - | P1 | none | - | - | - |
@@ -311,20 +311,19 @@ export const parityMatrix: ParityRow[] = [
311
311
  {
312
312
  id: "database.rows",
313
313
  surface: "database",
314
- label: "Add, duplicate, move, open, and delete database rows",
314
+ label: "Add, duplicate, move, open, edit, and remove database rows",
315
315
  uiEntrypoints: [
316
316
  "app/components/editor/DocumentDatabase.tsx",
317
317
  "app/components/editor/database/DatabaseView.tsx",
318
318
  ],
319
319
  durableEffect:
320
- "Database row backing documents and row ordering are created, duplicated, moved, edited, and deleted.",
320
+ "Database row memberships and ordering are created, duplicated, moved, edited, and removed without deleting the backing page.",
321
321
  uiImplementation:
322
- "Row controls call row actions; selected-row duplicate/delete call bounded batch actions, while bulk property edits remain a later reliability slice.",
322
+ "Row controls call row actions; selected-row duplicate/removal call bounded batch actions, while bulk property edits remain a later reliability slice.",
323
323
  status: "action-backed",
324
324
  actions: [
325
325
  "add-database-item",
326
- "delete-database-items",
327
- "delete-document",
326
+ "remove-database-items",
328
327
  "duplicate-database-items",
329
328
  "duplicate-database-item",
330
329
  "move-database-item",
@@ -29,6 +29,7 @@ export interface Document {
29
29
  notionPageUrl?: string | null;
30
30
  visibility?: "private" | "org" | "public";
31
31
  accessRole?: DocumentAccessRole;
32
+ canView?: boolean;
32
33
  canEdit?: boolean;
33
34
  canManage?: boolean;
34
35
  source?: DocumentSourceInfo;
@@ -795,6 +796,9 @@ export interface ContentDatabaseResponse {
795
796
  duplicatedDocumentIds?: string[];
796
797
  deletedItemIds?: string[];
797
798
  deletedDocumentIds?: string[];
799
+ removedItemIds?: string[];
800
+ removedDocumentIds?: string[];
801
+ removedCount?: number;
798
802
  timings?: BuilderActionTiming[];
799
803
  tableQueryMode?: "server" | "client-required";
800
804
  /** Client-only optimistic state while real provider rows are being attached. */