@agent-native/core 0.102.2 → 0.103.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.
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +12 -0
- package/corpus/core/docs/content/local-file-mode.mdx +99 -489
- package/corpus/core/docs/content/locales/ar-SA/local-file-mode.mdx +35 -490
- package/corpus/core/docs/content/locales/ar-SA/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/de-DE/local-file-mode.mdx +37 -491
- package/corpus/core/docs/content/locales/de-DE/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/es-ES/local-file-mode.mdx +35 -493
- package/corpus/core/docs/content/locales/es-ES/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/fr-FR/local-file-mode.mdx +38 -491
- package/corpus/core/docs/content/locales/fr-FR/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/hi-IN/local-file-mode.mdx +33 -492
- package/corpus/core/docs/content/locales/hi-IN/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/ja-JP/local-file-mode.mdx +36 -492
- package/corpus/core/docs/content/locales/ja-JP/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/ko-KR/local-file-mode.mdx +35 -490
- package/corpus/core/docs/content/locales/ko-KR/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/pt-BR/local-file-mode.mdx +35 -493
- package/corpus/core/docs/content/locales/pt-BR/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/zh-CN/local-file-mode.mdx +31 -489
- package/corpus/core/docs/content/locales/zh-CN/template-content.mdx +9 -24
- package/corpus/core/docs/content/locales/zh-TW/local-file-mode.mdx +31 -489
- package/corpus/core/docs/content/locales/zh-TW/template-content.mdx +9 -24
- package/corpus/core/docs/content/template-content.mdx +26 -42
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/cli/content-local.ts +86 -18
- package/corpus/core/src/cli/index.ts +2 -2
- package/corpus/core/src/cli/skills-content/content-skill.ts +36 -25
- package/corpus/core/src/cli/skills.ts +47 -13
- package/corpus/core/src/local-artifacts/index.ts +65 -0
- package/corpus/core/src/vite/client.ts +2 -0
- package/corpus/templates/assets/app/components/library/GenerationPresetsPanel.tsx +325 -0
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +12 -0
- package/corpus/templates/assets/app/i18n/zh-TW.ts +21 -0
- package/corpus/templates/assets/app/i18n-data.ts +215 -0
- package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +19 -479
- package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +1 -1
- package/corpus/templates/assets/app/routes/brand-kits.$id_.settings.tsx +446 -0
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +12 -2
- package/corpus/templates/clips/app/components/player/settings-panel.tsx +30 -12
- package/corpus/templates/clips/app/components/player/video-player.tsx +5 -1
- package/corpus/templates/clips/app/components/recorder/microphone-visualizer.tsx +22 -3
- package/corpus/templates/clips/app/i18n/ar-SA.ts +3 -2
- package/corpus/templates/clips/app/i18n/de-DE.ts +4 -2
- package/corpus/templates/clips/app/i18n/en-US.ts +3 -2
- package/corpus/templates/clips/app/i18n/es-ES.ts +4 -2
- package/corpus/templates/clips/app/i18n/fr-FR.ts +3 -2
- package/corpus/templates/clips/app/i18n/hi-IN.ts +3 -2
- package/corpus/templates/clips/app/i18n/ja-JP.ts +4 -1
- package/corpus/templates/clips/app/i18n/ko-KR.ts +3 -2
- package/corpus/templates/clips/app/i18n/pt-BR.ts +4 -2
- package/corpus/templates/clips/app/i18n/zh-CN.ts +3 -2
- package/corpus/templates/clips/app/i18n/zh-TW.ts +3 -2
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +27 -1
- package/corpus/templates/clips/server/lib/share-password.ts +6 -3
- package/corpus/templates/content/.agents/skills/content/SKILL.md +26 -39
- package/corpus/templates/content/AGENTS.md +25 -30
- package/corpus/templates/content/actions/_builder-docs-client.ts +23 -0
- package/corpus/templates/content/actions/_content-database-source-adapters.ts +21 -3
- package/corpus/templates/content/actions/_content-files.ts +338 -0
- package/corpus/templates/content/actions/_content-space-access.ts +135 -0
- package/corpus/templates/content/actions/_content-spaces.ts +640 -0
- package/corpus/templates/content/actions/_database-source-utils.ts +90 -7
- package/corpus/templates/content/actions/_database-utils.ts +7 -1
- package/corpus/templates/content/actions/_local-file-documents.ts +0 -9
- package/corpus/templates/content/actions/_local-folder-source.ts +53 -0
- package/corpus/templates/content/actions/_property-utils.ts +9 -4
- package/corpus/templates/content/actions/add-database-item.ts +108 -65
- package/corpus/templates/content/actions/backfill-content-files.ts +22 -0
- package/corpus/templates/content/actions/connect-local-folder-source.ts +221 -0
- package/corpus/templates/content/actions/create-content-database.ts +129 -3
- package/corpus/templates/content/actions/create-document.ts +65 -55
- package/corpus/templates/content/actions/create-inline-content-database.ts +6 -1
- package/corpus/templates/content/actions/delete-content-database.ts +3 -0
- package/corpus/templates/content/actions/delete-document.ts +7 -11
- package/corpus/templates/content/actions/disconnect-local-folder-source.ts +175 -0
- package/corpus/templates/content/actions/duplicate-database-item.ts +10 -0
- package/corpus/templates/content/actions/duplicate-database-items.ts +13 -0
- package/corpus/templates/content/actions/edit-document.ts +2 -28
- package/corpus/templates/content/actions/ensure-content-spaces.ts +26 -0
- package/corpus/templates/content/actions/export-content-source.ts +47 -9
- package/corpus/templates/content/actions/get-document.ts +0 -14
- package/corpus/templates/content/actions/import-content-source.ts +43 -3
- package/corpus/templates/content/actions/list-content-spaces.ts +103 -0
- package/corpus/templates/content/actions/list-documents.ts +12 -9
- package/corpus/templates/content/actions/move-document.ts +3 -14
- package/corpus/templates/content/actions/pull-document.ts +0 -23
- package/corpus/templates/content/actions/remove-local-file-source.ts +50 -29
- package/corpus/templates/content/actions/resolve-local-folder-conflict.ts +442 -0
- package/corpus/templates/content/actions/reveal-local-source-file.ts +6 -17
- package/corpus/templates/content/actions/search-documents.ts +0 -34
- package/corpus/templates/content/actions/share-local-file-document.ts +25 -1
- package/corpus/templates/content/actions/submit-content-database-form.ts +12 -0
- package/corpus/templates/content/actions/sync-local-folder-source.ts +731 -0
- package/corpus/templates/content/actions/sync-manifest-local-folder-source.ts +123 -0
- package/corpus/templates/content/actions/update-content-database-view.ts +10 -1
- package/corpus/templates/content/actions/update-document.ts +0 -15
- package/corpus/templates/content/actions/view-screen.ts +2 -50
- package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +76 -62
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +70 -22
- package/corpus/templates/content/app/components/editor/database/grouping.ts +2 -1
- package/corpus/templates/content/app/components/editor/database/settings.tsx +23 -20
- package/corpus/templates/content/app/components/editor/database/shared.tsx +2 -0
- package/corpus/templates/content/app/components/editor/database/sidebar.tsx +330 -0
- package/corpus/templates/content/app/components/editor/database/types.ts +1 -0
- package/corpus/templates/content/app/components/editor/database/view-config.ts +3 -1
- package/corpus/templates/content/app/components/layout/Layout.tsx +25 -1
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +209 -113
- package/corpus/templates/content/app/components/sidebar/select-content-space.ts +31 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +16 -0
- package/corpus/templates/content/app/hooks/use-content-spaces.ts +39 -0
- package/corpus/templates/content/app/i18n/zh-TW.ts +11 -0
- package/corpus/templates/content/app/i18n-data.ts +75 -0
- package/corpus/templates/content/app/routes/_app.local-files.tsx +174 -65
- package/corpus/templates/content/changelog/2026-07-16-content-callouts-can-now-be-reviewed-and-published-to-builder.md +6 -0
- package/corpus/templates/content/changelog/2026-07-16-heading-5-and-heading-6-are-available-from-the-editor-slash-.md +6 -0
- package/corpus/templates/content/changelog/2026-07-16-organize-every-workspace-through-a-customizable-files-databa.md +6 -0
- package/corpus/templates/content/parity/matrix.md +2 -1
- package/corpus/templates/content/parity/matrix.ts +37 -1
- package/corpus/templates/content/scripts/dev-database.mjs +7 -5
- package/corpus/templates/content/server/db/schema.ts +113 -40
- package/corpus/templates/content/server/lib/document-context.ts +15 -1
- package/corpus/templates/content/server/lib/notion-sync.ts +6 -0
- package/corpus/templates/content/server/plugins/db.ts +153 -0
- package/corpus/templates/content/shared/api.ts +17 -3
- package/corpus/templates/content/shared/builder-mdx.ts +163 -16
- package/corpus/templates/design/.agents/skills/design-templates/SKILL.md +59 -0
- package/corpus/templates/design/AGENTS.md +6 -1
- package/corpus/templates/design/actions/create-design-from-template.ts +19 -7
- package/corpus/templates/design/actions/list-design-templates.ts +69 -21
- package/corpus/templates/design/actions/navigate.ts +2 -2
- package/corpus/templates/design/actions/view-screen.ts +15 -2
- package/corpus/templates/design/agent-native.app-skill.json +5 -0
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +281 -56
- package/corpus/templates/design/app/components/templates/TemplatePreview.tsx +14 -2
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +3 -2
- package/corpus/templates/design/app/i18n/zh-TW.ts +3 -3
- package/corpus/templates/design/app/i18n-data.ts +21 -2
- package/corpus/templates/design/app/i18n-template-feature.ts +218 -10
- package/corpus/templates/design/app/pages/Index.tsx +195 -24
- package/corpus/templates/design/app/pages/Templates.tsx +144 -55
- package/corpus/templates/design/app/pages/design-editor/generation-prompt-directives.ts +12 -1
- package/corpus/templates/design/changelog/2026-07-14-templates-now-appear-in-the-new-design-picker-with-previews-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-15-templates-now-open-immediately-after-copying-even-while-the-.md +6 -0
- package/corpus/templates/design/server/plugins/agent-chat.ts +1 -1
- package/corpus/templates/mail/AGENTS.md +23 -18
- package/corpus/templates/mail/actions/bulk-archive.ts +32 -28
- package/corpus/templates/mail/actions/mark-read.ts +131 -20
- package/corpus/templates/mail/actions/mark-thread-read.ts +1 -1
- package/corpus/templates/mail/actions/move-email.ts +30 -24
- package/corpus/templates/mail/actions/send-email.ts +73 -68
- package/corpus/templates/mail/changelog/2026-07-15-unread-inbox-cleanup-now-completes-reliably.md +6 -0
- package/corpus/templates/mail/server/handlers/emails.ts +218 -209
- package/corpus/templates/mail/server/lib/bulk-mark-read.ts +30 -0
- package/corpus/templates/mail/server/lib/email-state.ts +198 -113
- package/corpus/templates/mail/server/lib/google-auth.ts +218 -25
- package/corpus/templates/mail/server/lib/jobs.ts +69 -74
- package/corpus/templates/mail/server/lib/local-email-store.ts +265 -0
- package/corpus/templates/mail/server/plugins/agent-chat.ts +6 -0
- package/dist/cli/content-local.d.ts +1 -0
- package/dist/cli/content-local.d.ts.map +1 -1
- package/dist/cli/content-local.js +75 -17
- package/dist/cli/content-local.js.map +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/skills-content/content-skill.d.ts +1 -1
- package/dist/cli/skills-content/content-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/content-skill.js +36 -25
- package/dist/cli/skills-content/content-skill.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +47 -14
- package/dist/cli/skills.js.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/local-artifacts/index.d.ts +10 -0
- package/dist/local-artifacts/index.d.ts.map +1 -1
- package/dist/local-artifacts/index.js +39 -0
- package/dist/local-artifacts/index.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +2 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/local-file-mode.mdx +99 -489
- package/docs/content/locales/ar-SA/local-file-mode.mdx +35 -490
- package/docs/content/locales/ar-SA/template-content.mdx +10 -24
- package/docs/content/locales/de-DE/local-file-mode.mdx +37 -491
- package/docs/content/locales/de-DE/template-content.mdx +10 -24
- package/docs/content/locales/es-ES/local-file-mode.mdx +35 -493
- package/docs/content/locales/es-ES/template-content.mdx +10 -24
- package/docs/content/locales/fr-FR/local-file-mode.mdx +38 -491
- package/docs/content/locales/fr-FR/template-content.mdx +10 -24
- package/docs/content/locales/hi-IN/local-file-mode.mdx +33 -492
- package/docs/content/locales/hi-IN/template-content.mdx +10 -24
- package/docs/content/locales/ja-JP/local-file-mode.mdx +36 -492
- package/docs/content/locales/ja-JP/template-content.mdx +10 -24
- package/docs/content/locales/ko-KR/local-file-mode.mdx +35 -490
- package/docs/content/locales/ko-KR/template-content.mdx +10 -24
- package/docs/content/locales/pt-BR/local-file-mode.mdx +35 -493
- package/docs/content/locales/pt-BR/template-content.mdx +10 -24
- package/docs/content/locales/zh-CN/local-file-mode.mdx +31 -489
- package/docs/content/locales/zh-CN/template-content.mdx +9 -24
- package/docs/content/locales/zh-TW/local-file-mode.mdx +31 -489
- package/docs/content/locales/zh-TW/template-content.mdx +9 -24
- package/docs/content/template-content.mdx +26 -42
- package/package.json +1 -1
- package/corpus/templates/assets/app/components/library/EditLibraryDialog.tsx +0 -126
|
@@ -15,7 +15,7 @@ This generated matrix tracks whether high-value Content UI operations use the sa
|
|
|
15
15
|
| editor.document-body-and-title | editor | Edit document title, body, icon, image alt text, and precise text | action-backed | `edit-document`, `pull-document`, `set-image-alt-text`, `transcribe-media`, `update-document` | `app/components/editor/DocumentEditor.tsx`, `app/components/editor/DocumentDatabase.tsx`, `app/components/editor/extensions/ImageBlock.tsx`, `app/components/editor/SlashCommandMenu.tsx` | Document content, title, icon, image metadata, and text replacements are saved to the same document source. | - | - | P0 | covered | `actions/content-database-lifecycle.db.test.ts`, `actions/_local-file-documents.test.ts` | `document-search-edit` | - |
|
|
16
16
|
| local-files.components-workspace | local-files | Register, list, and write local MDX component workspaces | host-only | `list-local-component-files`, `register-local-component-workspace`, `write-local-component-file` | `app/routes/_app.local-files.tsx`, `actions/register-local-component-workspace.ts`, `actions/list-local-component-files.ts`, `actions/write-local-component-file.ts` | Trusted local component workspace registration and component file reads/writes support local MDX previews. | Workspace registration depends on a trusted Desktop folder path and is intentionally hidden with agentTool: false. | - | P1 | seeded | - | - | Local folder exception/docs PR |
|
|
17
17
|
| local-files.host-folder-handles | local-files | Choose, persist, remove, and write trusted local folder handles | host-only | - | `app/routes/_app.local-files.tsx` | Host directory handles and browser/Desktop write permissions are managed outside SQL action state. | Mounted local folders require browser/Desktop host handles that agents cannot safely or portably hold as normal tools. | - | P0 | none | - | - | Local folder exception/docs PR |
|
|
18
|
-
| local-files.import-export-mounted-folder | local-files | Import, check, export, push, and remove local folder source files | action-backed | `export-content-source`, `import-content-source`, `remove-local-file-source`
|
|
18
|
+
| local-files.import-export-mounted-folder | local-files | Import, check, export, push, and remove local folder source files | action-backed | `connect-local-folder-source`, `disconnect-local-folder-source`, `export-content-source`, `import-content-source`, `remove-local-file-source`, `resolve-local-folder-conflict`, `sync-local-folder-source`, `sync-manifest-local-folder-source` | `app/routes/_app.local-files.tsx`, `actions/import-content-source.ts`, `actions/export-content-source.ts` | Local Markdown/MDX source files are imported into Content documents, editable Content documents are exported back to source-friendly files, and imported source entries can be removed without deleting files on disk. | - | - | P0 | covered | `actions/_local-file-documents.test.ts`, `actions/local-folder-source.db.test.ts` | `local-file-source-truth` | - |
|
|
19
19
|
| notion.route-backed-document-sync | source-sync | Notion document sync status, link, unlink, pull, push, resolve, create, search, and disconnect | action-backed | `connect-notion-status`, `create-and-link-notion-page`, `disconnect-notion`, `link-notion-page`, `list-notion-links`, `pull-notion-page`, `push-notion-page`, `refresh-notion-sync-status`, `resolve-notion-sync-conflict`, `search-notion-pages`, `sync-notion-comments`, `unlink-notion-page` | `app/hooks/use-notion.ts`, `app/components/editor/DocumentToolbar.tsx`, `app/components/editor/NotionSyncBar.tsx`, `app/components/editor/DocumentEditor.tsx` | Notion connection state, page search, link metadata, and local/remote document body sync state are read or mutated through Content actions. | Notion OAuth auth-url and callback routes remain route-shaped because they initiate and receive browser redirects rather than normal app data mutations. | - | P0 | covered | `parity/__tests__/matrix-route-gap-classify.test.ts` | - | - |
|
|
20
20
|
| sharing.document-discoverability-and-export | sharing | Share, hide from search, export, and reveal documents | action-backed | `export-document`, `reveal-local-source-file`, `set-document-discoverability`, `share-local-file-document` | `app/components/editor/DocumentToolbar.tsx`, `app/hooks/use-documents.ts` | Search discoverability, shareable copies, exports, and OS reveal requests are managed through Content actions. | - | - | P0 | covered | `actions/_local-file-documents.test.ts` | `local-file-source-truth` | - |
|
|
21
21
|
| sharing.os-reveal-local-source | sharing | Reveal a local source file in the system file manager | host-only | `reveal-local-source-file` | `app/components/editor/DocumentToolbar.tsx`, `actions/reveal-local-source-file.ts` | - | OS reveal depends on trusted local host capabilities and should not spend agent tool surface or imply portable hosted behavior. | - | P2 | seeded | - | - | Local folder exception/docs PR |
|
|
@@ -29,3 +29,4 @@ This generated matrix tracks whether high-value Content UI operations use the sa
|
|
|
29
29
|
| source-sync.database-source-bindings | source-sync | Attach, inspect, refresh, disconnect, join, and bind database sources | action-backed | `add-content-database-source-field-property`, `attach-content-database-source`, `bind-content-database-source-field`, `change-content-database-source-role`, `disconnect-content-database-source`, `get-content-database-source`, `list-builder-cms-models`, `list-notion-database-sources`, `refresh-content-database-source`, `suggest-source-join-key` | `app/components/editor/DocumentDatabase.tsx`, `app/components/editor/DocumentProperties.tsx`, `app/components/editor/database/DatabaseView.tsx`, `app/hooks/use-content-database.ts` | Mounted database source metadata, fields, source role, join keys, and source-field/property bindings are stored and refreshed. | - | - | 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` | - |
|
|
30
30
|
| source-sync.provider-api-and-staged-datasets | source-sync | Inspect provider APIs and stage/query/delete large provider datasets | action-backed | `delete-staged-dataset`, `list-staged-datasets`, `provider-api-catalog`, `provider-api-docs`, `provider-api-request`, `query-staged-dataset` | `actions/provider-api-catalog.ts`, `actions/provider-api-docs.ts`, `actions/provider-api-request.ts`, `actions/query-staged-dataset.ts` | Provider API metadata and staged dataset scratch storage support scoped agent/source analysis. | - | - | P1 | seeded | - | - | - |
|
|
31
31
|
| versions.history-and-restore | versions | Open version history and restore a previous document version | action-backed | `list-document-versions`, `restore-document-version` | `app/components/editor/VersionHistoryPanel.tsx`, `app/hooks/use-document-versions.ts` | Document versions are listed and selected versions can restore the document while snapshotting current state. | - | - | P0 | seeded | - | - | - |
|
|
32
|
+
| workspace.spaces-and-files-catalog | workspace | Provision and navigate Content spaces through Files and Workspaces | action-backed | `backfill-content-files`, `ensure-content-spaces`, `list-content-spaces` | `app/components/sidebar/DocumentSidebar.tsx`, `app/hooks/use-content-spaces.ts` | Personal and organization spaces, their canonical Files databases, and the personal Workspaces catalog are provisioned and reconciled in SQL. | - | - | P0 | covered | `actions/content-spaces.db.test.ts`, `actions/content-files.db.test.ts` | - | - |
|
|
@@ -35,6 +35,34 @@ export const parityMatrix: ParityRow[] = [
|
|
|
35
35
|
],
|
|
36
36
|
evalScenarioIds: ["document-search-edit"],
|
|
37
37
|
},
|
|
38
|
+
{
|
|
39
|
+
id: "workspace.spaces-and-files-catalog",
|
|
40
|
+
surface: "workspace",
|
|
41
|
+
label: "Provision and navigate Content spaces through Files and Workspaces",
|
|
42
|
+
uiEntrypoints: [
|
|
43
|
+
"app/components/sidebar/DocumentSidebar.tsx",
|
|
44
|
+
"app/hooks/use-content-spaces.ts",
|
|
45
|
+
],
|
|
46
|
+
durableEffect:
|
|
47
|
+
"Personal and organization spaces, their canonical Files databases, and the personal Workspaces catalog are provisioned and reconciled in SQL.",
|
|
48
|
+
uiImplementation:
|
|
49
|
+
"The app sidebar calls the shared space actions and renders the selected Files database through a saved sidebar view.",
|
|
50
|
+
status: "action-backed",
|
|
51
|
+
actions: [
|
|
52
|
+
"backfill-content-files",
|
|
53
|
+
"ensure-content-spaces",
|
|
54
|
+
"list-content-spaces",
|
|
55
|
+
],
|
|
56
|
+
exception: null,
|
|
57
|
+
reliabilityRisk: "none",
|
|
58
|
+
spinePriority: "P0",
|
|
59
|
+
testCoverage: "covered",
|
|
60
|
+
followUpPR: null,
|
|
61
|
+
coverageRefs: [
|
|
62
|
+
"actions/content-spaces.db.test.ts",
|
|
63
|
+
"actions/content-files.db.test.ts",
|
|
64
|
+
],
|
|
65
|
+
},
|
|
38
66
|
{
|
|
39
67
|
id: "sidebar.navigation-and-screen-context",
|
|
40
68
|
surface: "sidebar",
|
|
@@ -537,16 +565,24 @@ export const parityMatrix: ParityRow[] = [
|
|
|
537
565
|
"UI reads/writes browser or Desktop folder handles around import/export actions.",
|
|
538
566
|
status: "action-backed",
|
|
539
567
|
actions: [
|
|
568
|
+
"connect-local-folder-source",
|
|
569
|
+
"disconnect-local-folder-source",
|
|
540
570
|
"export-content-source",
|
|
541
571
|
"import-content-source",
|
|
542
572
|
"remove-local-file-source",
|
|
573
|
+
"resolve-local-folder-conflict",
|
|
574
|
+
"sync-local-folder-source",
|
|
575
|
+
"sync-manifest-local-folder-source",
|
|
543
576
|
],
|
|
544
577
|
exception: null,
|
|
545
578
|
reliabilityRisk: "none",
|
|
546
579
|
spinePriority: "P0",
|
|
547
580
|
testCoverage: "covered",
|
|
548
581
|
followUpPR: null,
|
|
549
|
-
coverageRefs: [
|
|
582
|
+
coverageRefs: [
|
|
583
|
+
"actions/_local-file-documents.test.ts",
|
|
584
|
+
"actions/local-folder-source.db.test.ts",
|
|
585
|
+
],
|
|
550
586
|
evalScenarioIds: ["local-file-source-truth"],
|
|
551
587
|
},
|
|
552
588
|
{
|
|
@@ -37,8 +37,8 @@ function ensureLocalEnv() {
|
|
|
37
37
|
const values = parseEnv(existing);
|
|
38
38
|
let changed = false;
|
|
39
39
|
|
|
40
|
-
if (values.get("AGENT_NATIVE_MODE")
|
|
41
|
-
values.
|
|
40
|
+
if (values.get("AGENT_NATIVE_MODE") === "database") {
|
|
41
|
+
values.delete("AGENT_NATIVE_MODE");
|
|
42
42
|
changed = true;
|
|
43
43
|
}
|
|
44
44
|
const authSecret = values.get("BETTER_AUTH_SECRET") ?? "";
|
|
@@ -49,15 +49,17 @@ function ensureLocalEnv() {
|
|
|
49
49
|
|
|
50
50
|
if (changed) {
|
|
51
51
|
writeFileSync(envPath, serializeEnv(values));
|
|
52
|
-
console.log("[content dev]
|
|
52
|
+
console.log("[content dev] Updated local Content env in .env.local");
|
|
53
53
|
}
|
|
54
54
|
return values;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
const envValues = ensureLocalEnv();
|
|
58
|
+
const baseEnv = { ...process.env };
|
|
59
|
+
delete baseEnv.AGENT_NATIVE_MODE;
|
|
60
|
+
delete baseEnv.AGENT_NATIVE_DATA_MODE;
|
|
58
61
|
const childEnv = {
|
|
59
|
-
...
|
|
60
|
-
AGENT_NATIVE_MODE: "database",
|
|
62
|
+
...baseEnv,
|
|
61
63
|
BETTER_AUTH_SECRET:
|
|
62
64
|
process.env.BETTER_AUTH_SECRET || envValues.get("BETTER_AUTH_SECRET"),
|
|
63
65
|
};
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
|
|
12
12
|
export const documents = table("documents", {
|
|
13
13
|
id: text("id").primaryKey(),
|
|
14
|
+
spaceId: text("space_id"),
|
|
14
15
|
parentId: text("parent_id"),
|
|
15
16
|
title: text("title").notNull().default("Untitled"),
|
|
16
17
|
content: text("content").notNull().default(""),
|
|
@@ -31,6 +32,58 @@ export const documents = table("documents", {
|
|
|
31
32
|
...ownableColumns(),
|
|
32
33
|
});
|
|
33
34
|
|
|
35
|
+
export const contentSpaces = table(
|
|
36
|
+
"content_spaces",
|
|
37
|
+
{
|
|
38
|
+
id: text("id").primaryKey(),
|
|
39
|
+
name: text("name").notNull(),
|
|
40
|
+
kind: text("kind").notNull(),
|
|
41
|
+
ownerEmail: text("owner_email").notNull(),
|
|
42
|
+
orgId: text("org_id"),
|
|
43
|
+
filesDatabaseId: text("files_database_id").notNull(),
|
|
44
|
+
createdBy: text("created_by").notNull(),
|
|
45
|
+
archivedAt: text("archived_at"),
|
|
46
|
+
createdAt: text("created_at").notNull().default(now()),
|
|
47
|
+
updatedAt: text("updated_at").notNull().default(now()),
|
|
48
|
+
},
|
|
49
|
+
(space) => [
|
|
50
|
+
uniqueIndex("content_spaces_files_database_unique").on(
|
|
51
|
+
space.filesDatabaseId,
|
|
52
|
+
),
|
|
53
|
+
index("content_spaces_owner_org_idx").on(space.ownerEmail, space.orgId),
|
|
54
|
+
index("content_spaces_org_idx").on(space.orgId),
|
|
55
|
+
],
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
export const contentSpaceCatalogItems = table(
|
|
59
|
+
"content_space_catalog_items",
|
|
60
|
+
{
|
|
61
|
+
id: text("id").primaryKey(),
|
|
62
|
+
ownerEmail: text("owner_email").notNull(),
|
|
63
|
+
catalogDatabaseId: text("catalog_database_id").notNull(),
|
|
64
|
+
databaseItemId: text("database_item_id").notNull(),
|
|
65
|
+
documentId: text("document_id").notNull(),
|
|
66
|
+
spaceId: text("space_id").notNull(),
|
|
67
|
+
createdAt: text("created_at").notNull().default(now()),
|
|
68
|
+
updatedAt: text("updated_at").notNull().default(now()),
|
|
69
|
+
},
|
|
70
|
+
(catalogItem) => [
|
|
71
|
+
uniqueIndex("content_space_catalog_items_catalog_space_unique").on(
|
|
72
|
+
catalogItem.catalogDatabaseId,
|
|
73
|
+
catalogItem.spaceId,
|
|
74
|
+
),
|
|
75
|
+
uniqueIndex("content_space_catalog_items_catalog_item_unique").on(
|
|
76
|
+
catalogItem.catalogDatabaseId,
|
|
77
|
+
catalogItem.databaseItemId,
|
|
78
|
+
),
|
|
79
|
+
index("content_space_catalog_items_owner_catalog_idx").on(
|
|
80
|
+
catalogItem.ownerEmail,
|
|
81
|
+
catalogItem.catalogDatabaseId,
|
|
82
|
+
),
|
|
83
|
+
index("content_space_catalog_items_space_idx").on(catalogItem.spaceId),
|
|
84
|
+
],
|
|
85
|
+
);
|
|
86
|
+
|
|
34
87
|
export const documentVersions = table("document_versions", {
|
|
35
88
|
id: text("id").primaryKey(),
|
|
36
89
|
ownerEmail: text("owner_email").notNull().default("local@localhost"),
|
|
@@ -160,47 +213,67 @@ export const documentPropertyDefinitions = table(
|
|
|
160
213
|
},
|
|
161
214
|
);
|
|
162
215
|
|
|
163
|
-
export const contentDatabases = table(
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
216
|
+
export const contentDatabases = table(
|
|
217
|
+
"content_databases",
|
|
218
|
+
{
|
|
219
|
+
id: text("id").primaryKey(),
|
|
220
|
+
spaceId: text("space_id"),
|
|
221
|
+
ownerEmail: text("owner_email").notNull().default("local@localhost"),
|
|
222
|
+
orgId: text("org_id"),
|
|
223
|
+
documentId: text("document_id").notNull(),
|
|
224
|
+
ownerDocumentId: text("owner_document_id"),
|
|
225
|
+
ownerBlockId: text("owner_block_id"),
|
|
226
|
+
title: text("title").notNull().default("Untitled database"),
|
|
227
|
+
systemRole: text("system_role"),
|
|
228
|
+
viewConfigJson: text("view_config_json").notNull().default("{}"),
|
|
229
|
+
// Single source of truth for the primary "Content" Blocks field — the one
|
|
230
|
+
// backed by `documents.content`. A DB-enforced single-primary invariant: at
|
|
231
|
+
// most one property id lives here, so two concurrent seeds can never produce
|
|
232
|
+
// two aliasing primaries. NULL means there is currently no primary Blocks
|
|
233
|
+
// field (never seeded, or the primary was intentionally deleted).
|
|
234
|
+
primaryBlocksPropertyId: text("primary_blocks_property_id"),
|
|
235
|
+
// 1 once a database has been seeded with its primary Blocks field at least
|
|
236
|
+
// once. Distinguishes "never seeded" (legacy database needing backfill) from
|
|
237
|
+
// "primary intentionally deleted" (seeded once, then removed — must NOT be
|
|
238
|
+
// reseeded). See delete-document-property.
|
|
239
|
+
blocksSeeded: integer("blocks_seeded").notNull().default(0),
|
|
240
|
+
deletedAt: text("deleted_at"),
|
|
241
|
+
createdAt: text("created_at").notNull().default(now()),
|
|
242
|
+
updatedAt: text("updated_at").notNull().default(now()),
|
|
243
|
+
},
|
|
244
|
+
(database) => [
|
|
245
|
+
uniqueIndex("content_databases_space_system_role_unique").on(
|
|
246
|
+
database.spaceId,
|
|
247
|
+
database.systemRole,
|
|
248
|
+
),
|
|
249
|
+
],
|
|
250
|
+
);
|
|
187
251
|
|
|
188
|
-
export const contentDatabaseItems = table(
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
.notNull()
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
252
|
+
export const contentDatabaseItems = table(
|
|
253
|
+
"content_database_items",
|
|
254
|
+
{
|
|
255
|
+
id: text("id").primaryKey(),
|
|
256
|
+
ownerEmail: text("owner_email").notNull().default("local@localhost"),
|
|
257
|
+
orgId: text("org_id"),
|
|
258
|
+
databaseId: text("database_id").notNull(),
|
|
259
|
+
documentId: text("document_id").notNull(),
|
|
260
|
+
position: integer("position").notNull().default(0),
|
|
261
|
+
bodyHydrationStatus: text("body_hydration_status")
|
|
262
|
+
.notNull()
|
|
263
|
+
.default("hydrated"),
|
|
264
|
+
bodyHydrationAttemptedAt: text("body_hydration_attempted_at"),
|
|
265
|
+
bodyHydrationError: text("body_hydration_error"),
|
|
266
|
+
bodyHydrationVersion: text("body_hydration_version"),
|
|
267
|
+
createdAt: text("created_at").notNull().default(now()),
|
|
268
|
+
updatedAt: text("updated_at").notNull().default(now()),
|
|
269
|
+
},
|
|
270
|
+
(item) => [
|
|
271
|
+
uniqueIndex("content_database_items_database_document_unique").on(
|
|
272
|
+
item.databaseId,
|
|
273
|
+
item.documentId,
|
|
274
|
+
),
|
|
275
|
+
],
|
|
276
|
+
);
|
|
204
277
|
|
|
205
278
|
export const contentDatabaseBodyHydrationQueue = table(
|
|
206
279
|
"content_database_body_hydration_queue",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolveAccess } from "@agent-native/core/sharing";
|
|
2
|
-
import { and, eq, isNull } from "drizzle-orm";
|
|
2
|
+
import { and, asc, eq, isNull, sql } from "drizzle-orm";
|
|
3
3
|
|
|
4
4
|
import { getDb, schema } from "../db/index.js";
|
|
5
5
|
|
|
@@ -55,9 +55,23 @@ export async function getDocumentContextPath(
|
|
|
55
55
|
eq(schema.contentDatabaseItems.documentId, document.id),
|
|
56
56
|
isNull(schema.contentDatabases.deletedAt),
|
|
57
57
|
),
|
|
58
|
+
)
|
|
59
|
+
.orderBy(
|
|
60
|
+
sql`CASE WHEN ${schema.contentDatabases.systemRole} IS NULL THEN 0 ELSE 1 END`,
|
|
61
|
+
asc(schema.contentDatabases.id),
|
|
62
|
+
);
|
|
63
|
+
const [backingDatabase] = await db
|
|
64
|
+
.select({ id: schema.contentDatabases.id })
|
|
65
|
+
.from(schema.contentDatabases)
|
|
66
|
+
.where(
|
|
67
|
+
and(
|
|
68
|
+
eq(schema.contentDatabases.documentId, document.id),
|
|
69
|
+
isNull(schema.contentDatabases.deletedAt),
|
|
70
|
+
),
|
|
58
71
|
);
|
|
59
72
|
if (
|
|
60
73
|
membership &&
|
|
74
|
+
!(membership.database.systemRole && backingDatabase) &&
|
|
61
75
|
!path.some((entry) => entry.id === membership.database.id)
|
|
62
76
|
) {
|
|
63
77
|
const databaseDocumentAccess = await resolveAccess(
|
|
@@ -5,6 +5,7 @@ import crypto from "node:crypto";
|
|
|
5
5
|
import { and, eq, inArray, isNull, lt, or } from "drizzle-orm";
|
|
6
6
|
import type { InferSelectModel } from "drizzle-orm";
|
|
7
7
|
|
|
8
|
+
import { ensureDocumentFilesMembership } from "../../actions/_content-files.js";
|
|
8
9
|
import type { DocumentSyncStatus } from "../../shared/api.js";
|
|
9
10
|
import { canonicalizeNfm, nfmToDoc, type PMNode } from "../../shared/nfm.js";
|
|
10
11
|
import { getDb, schema } from "../db/index.js";
|
|
@@ -492,11 +493,15 @@ async function createLinkedChildDocument(args: {
|
|
|
492
493
|
const db = getDb();
|
|
493
494
|
const now = nowIso();
|
|
494
495
|
const id = nanoid();
|
|
496
|
+
if (!args.parent.spaceId) {
|
|
497
|
+
throw new Error("Parent document does not belong to a Content space.");
|
|
498
|
+
}
|
|
495
499
|
|
|
496
500
|
let inserted = false;
|
|
497
501
|
try {
|
|
498
502
|
await db.insert(schema.documents).values({
|
|
499
503
|
id,
|
|
504
|
+
spaceId: args.parent.spaceId,
|
|
500
505
|
ownerEmail: args.parent.ownerEmail,
|
|
501
506
|
orgId: args.parent.orgId,
|
|
502
507
|
parentId: args.parent.id,
|
|
@@ -511,6 +516,7 @@ async function createLinkedChildDocument(args: {
|
|
|
511
516
|
updatedAt: now,
|
|
512
517
|
});
|
|
513
518
|
inserted = true;
|
|
519
|
+
await ensureDocumentFilesMembership(db, id, now);
|
|
514
520
|
await inheritShares(args.parent.id, id, now);
|
|
515
521
|
await upsertSyncLink({
|
|
516
522
|
owner: args.owner,
|
|
@@ -694,6 +694,159 @@ const runContentMigrations = runMigrations(
|
|
|
694
694
|
owner_email
|
|
695
695
|
)`,
|
|
696
696
|
},
|
|
697
|
+
{
|
|
698
|
+
version: 70,
|
|
699
|
+
name: "content-spaces-table",
|
|
700
|
+
sql: `CREATE TABLE IF NOT EXISTS content_spaces (
|
|
701
|
+
id TEXT PRIMARY KEY,
|
|
702
|
+
name TEXT NOT NULL,
|
|
703
|
+
kind TEXT NOT NULL,
|
|
704
|
+
owner_email TEXT NOT NULL,
|
|
705
|
+
org_id TEXT,
|
|
706
|
+
files_database_id TEXT NOT NULL,
|
|
707
|
+
created_by TEXT NOT NULL,
|
|
708
|
+
archived_at TEXT,
|
|
709
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
710
|
+
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
711
|
+
)`,
|
|
712
|
+
},
|
|
713
|
+
{
|
|
714
|
+
version: 71,
|
|
715
|
+
name: "content-space-catalog-items-table",
|
|
716
|
+
sql: `CREATE TABLE IF NOT EXISTS content_space_catalog_items (
|
|
717
|
+
id TEXT PRIMARY KEY,
|
|
718
|
+
owner_email TEXT NOT NULL,
|
|
719
|
+
catalog_database_id TEXT NOT NULL,
|
|
720
|
+
database_item_id TEXT NOT NULL,
|
|
721
|
+
document_id TEXT NOT NULL,
|
|
722
|
+
space_id TEXT NOT NULL,
|
|
723
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
724
|
+
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
725
|
+
)`,
|
|
726
|
+
},
|
|
727
|
+
{
|
|
728
|
+
version: 72,
|
|
729
|
+
name: "content-space-columns",
|
|
730
|
+
sql: `ALTER TABLE documents ADD COLUMN IF NOT EXISTS space_id TEXT;
|
|
731
|
+
ALTER TABLE content_databases ADD COLUMN IF NOT EXISTS space_id TEXT;
|
|
732
|
+
ALTER TABLE content_databases ADD COLUMN IF NOT EXISTS system_role TEXT`,
|
|
733
|
+
},
|
|
734
|
+
{
|
|
735
|
+
version: 73,
|
|
736
|
+
name: "content-space-hot-path-indexes",
|
|
737
|
+
sql: `CREATE UNIQUE INDEX IF NOT EXISTS content_spaces_files_database_unique ON content_spaces (files_database_id);
|
|
738
|
+
CREATE INDEX IF NOT EXISTS content_spaces_owner_org_idx ON content_spaces (owner_email, org_id);
|
|
739
|
+
CREATE INDEX IF NOT EXISTS content_spaces_org_idx ON content_spaces (org_id);
|
|
740
|
+
CREATE UNIQUE INDEX IF NOT EXISTS content_space_catalog_items_catalog_space_unique ON content_space_catalog_items (catalog_database_id, space_id);
|
|
741
|
+
CREATE UNIQUE INDEX IF NOT EXISTS content_space_catalog_items_catalog_item_unique ON content_space_catalog_items (catalog_database_id, database_item_id);
|
|
742
|
+
CREATE INDEX IF NOT EXISTS content_space_catalog_items_owner_catalog_idx ON content_space_catalog_items (owner_email, catalog_database_id);
|
|
743
|
+
CREATE INDEX IF NOT EXISTS content_space_catalog_items_space_idx ON content_space_catalog_items (space_id);
|
|
744
|
+
CREATE INDEX IF NOT EXISTS documents_space_idx ON documents (space_id);
|
|
745
|
+
CREATE INDEX IF NOT EXISTS content_databases_space_idx ON content_databases (space_id);
|
|
746
|
+
CREATE UNIQUE INDEX IF NOT EXISTS content_databases_space_system_role_unique ON content_databases (space_id, system_role)`,
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
version: 74,
|
|
750
|
+
name: "content-database-items-canonical-membership",
|
|
751
|
+
sql: `DROP INDEX IF EXISTS content_space_catalog_items_catalog_item_unique;
|
|
752
|
+
DROP INDEX IF EXISTS content_database_body_hydration_queue_item_idx;
|
|
753
|
+
UPDATE content_space_catalog_items
|
|
754
|
+
SET database_item_id = (
|
|
755
|
+
SELECT MIN(canonical.id)
|
|
756
|
+
FROM content_database_items original
|
|
757
|
+
INNER JOIN content_database_items canonical
|
|
758
|
+
ON canonical.database_id = original.database_id
|
|
759
|
+
AND canonical.document_id = original.document_id
|
|
760
|
+
WHERE original.id = content_space_catalog_items.database_item_id
|
|
761
|
+
)
|
|
762
|
+
WHERE EXISTS (
|
|
763
|
+
SELECT 1
|
|
764
|
+
FROM content_database_items original
|
|
765
|
+
INNER JOIN content_database_items canonical
|
|
766
|
+
ON canonical.database_id = original.database_id
|
|
767
|
+
AND canonical.document_id = original.document_id
|
|
768
|
+
WHERE original.id = content_space_catalog_items.database_item_id
|
|
769
|
+
AND canonical.id < original.id
|
|
770
|
+
);
|
|
771
|
+
UPDATE content_database_body_hydration_queue
|
|
772
|
+
SET database_item_id = (
|
|
773
|
+
SELECT MIN(canonical.id)
|
|
774
|
+
FROM content_database_items original
|
|
775
|
+
INNER JOIN content_database_items canonical
|
|
776
|
+
ON canonical.database_id = original.database_id
|
|
777
|
+
AND canonical.document_id = original.document_id
|
|
778
|
+
WHERE original.id = content_database_body_hydration_queue.database_item_id
|
|
779
|
+
)
|
|
780
|
+
WHERE EXISTS (
|
|
781
|
+
SELECT 1
|
|
782
|
+
FROM content_database_items original
|
|
783
|
+
INNER JOIN content_database_items canonical
|
|
784
|
+
ON canonical.database_id = original.database_id
|
|
785
|
+
AND canonical.document_id = original.document_id
|
|
786
|
+
WHERE original.id = content_database_body_hydration_queue.database_item_id
|
|
787
|
+
AND canonical.id < original.id
|
|
788
|
+
);
|
|
789
|
+
UPDATE content_database_source_rows
|
|
790
|
+
SET database_item_id = (
|
|
791
|
+
SELECT MIN(canonical.id)
|
|
792
|
+
FROM content_database_items original
|
|
793
|
+
INNER JOIN content_database_items canonical
|
|
794
|
+
ON canonical.database_id = original.database_id
|
|
795
|
+
AND canonical.document_id = original.document_id
|
|
796
|
+
WHERE original.id = content_database_source_rows.database_item_id
|
|
797
|
+
)
|
|
798
|
+
WHERE EXISTS (
|
|
799
|
+
SELECT 1
|
|
800
|
+
FROM content_database_items original
|
|
801
|
+
INNER JOIN content_database_items canonical
|
|
802
|
+
ON canonical.database_id = original.database_id
|
|
803
|
+
AND canonical.document_id = original.document_id
|
|
804
|
+
WHERE original.id = content_database_source_rows.database_item_id
|
|
805
|
+
AND canonical.id < original.id
|
|
806
|
+
);
|
|
807
|
+
UPDATE content_database_source_change_sets
|
|
808
|
+
SET database_item_id = (
|
|
809
|
+
SELECT MIN(canonical.id)
|
|
810
|
+
FROM content_database_items original
|
|
811
|
+
INNER JOIN content_database_items canonical
|
|
812
|
+
ON canonical.database_id = original.database_id
|
|
813
|
+
AND canonical.document_id = original.document_id
|
|
814
|
+
WHERE original.id = content_database_source_change_sets.database_item_id
|
|
815
|
+
)
|
|
816
|
+
WHERE EXISTS (
|
|
817
|
+
SELECT 1
|
|
818
|
+
FROM content_database_items original
|
|
819
|
+
INNER JOIN content_database_items canonical
|
|
820
|
+
ON canonical.database_id = original.database_id
|
|
821
|
+
AND canonical.document_id = original.document_id
|
|
822
|
+
WHERE original.id = content_database_source_change_sets.database_item_id
|
|
823
|
+
AND canonical.id < original.id
|
|
824
|
+
);
|
|
825
|
+
DELETE FROM content_space_catalog_items
|
|
826
|
+
WHERE id NOT IN (
|
|
827
|
+
SELECT MIN(id)
|
|
828
|
+
FROM content_space_catalog_items
|
|
829
|
+
GROUP BY catalog_database_id, database_item_id
|
|
830
|
+
);
|
|
831
|
+
DELETE FROM content_database_body_hydration_queue
|
|
832
|
+
WHERE id NOT IN (
|
|
833
|
+
SELECT MIN(id)
|
|
834
|
+
FROM content_database_body_hydration_queue
|
|
835
|
+
GROUP BY database_item_id
|
|
836
|
+
);
|
|
837
|
+
CREATE UNIQUE INDEX IF NOT EXISTS content_space_catalog_items_catalog_item_unique
|
|
838
|
+
ON content_space_catalog_items (catalog_database_id, database_item_id);
|
|
839
|
+
CREATE UNIQUE INDEX IF NOT EXISTS content_database_body_hydration_queue_item_idx
|
|
840
|
+
ON content_database_body_hydration_queue (database_item_id);
|
|
841
|
+
DELETE FROM content_database_items
|
|
842
|
+
WHERE id NOT IN (
|
|
843
|
+
SELECT MIN(id)
|
|
844
|
+
FROM content_database_items
|
|
845
|
+
GROUP BY database_id, document_id
|
|
846
|
+
);
|
|
847
|
+
CREATE UNIQUE INDEX IF NOT EXISTS content_database_items_database_document_unique
|
|
848
|
+
ON content_database_items (database_id, document_id)`,
|
|
849
|
+
},
|
|
697
850
|
],
|
|
698
851
|
{ table: "content_migrations" },
|
|
699
852
|
);
|
|
@@ -96,6 +96,7 @@ export interface ResolveDocumentSyncConflictRequest {
|
|
|
96
96
|
|
|
97
97
|
export interface DocumentCreateRequest {
|
|
98
98
|
id?: string;
|
|
99
|
+
spaceId?: string;
|
|
99
100
|
title?: string;
|
|
100
101
|
parentId?: string | null;
|
|
101
102
|
content?: string;
|
|
@@ -289,7 +290,8 @@ export type ContentDatabaseViewType =
|
|
|
289
290
|
| "gallery"
|
|
290
291
|
| "calendar"
|
|
291
292
|
| "timeline"
|
|
292
|
-
| "form"
|
|
293
|
+
| "form"
|
|
294
|
+
| "sidebar";
|
|
293
295
|
|
|
294
296
|
export type ContentDatabaseRowDensity = "compact" | "default" | "comfortable";
|
|
295
297
|
export type ContentDatabaseFilterMode = "and" | "or";
|
|
@@ -414,7 +416,12 @@ export type ContentDatabaseSourceType =
|
|
|
414
416
|
| "mock-local"
|
|
415
417
|
| "builder-cms"
|
|
416
418
|
| "local-table"
|
|
417
|
-
| "notion-database"
|
|
419
|
+
| "notion-database"
|
|
420
|
+
| "local-folder";
|
|
421
|
+
export type ContentDatabaseSourceTruthPolicy =
|
|
422
|
+
| "database_primary"
|
|
423
|
+
| "source_primary"
|
|
424
|
+
| "reviewed_bidirectional";
|
|
418
425
|
export type ContentDatabaseSourceSyncState =
|
|
419
426
|
| "idle"
|
|
420
427
|
| "linked"
|
|
@@ -433,7 +440,7 @@ export type ContentDatabaseSourceWriteMode =
|
|
|
433
440
|
| "publish_updates";
|
|
434
441
|
export type BuilderCmsPublicationTransitionIntent = "publish" | "unpublish";
|
|
435
442
|
export const BUILDER_CMS_SAFE_WRITE_MODEL = "agent-native-blog-article-test";
|
|
436
|
-
export type ContentDatabaseSourceChangeDirection = "outbound";
|
|
443
|
+
export type ContentDatabaseSourceChangeDirection = "incoming" | "outbound";
|
|
437
444
|
export type ContentDatabaseSourceChangeState =
|
|
438
445
|
| "proposed"
|
|
439
446
|
| "pending_push"
|
|
@@ -471,6 +478,9 @@ export interface ContentDatabaseSourceCapabilities {
|
|
|
471
478
|
canStageLocalRevision: boolean;
|
|
472
479
|
liveWritesEnabled: boolean;
|
|
473
480
|
readOnlyRefresh: boolean;
|
|
481
|
+
canRename?: boolean;
|
|
482
|
+
canReveal?: boolean;
|
|
483
|
+
canUseLocalComponents?: boolean;
|
|
474
484
|
}
|
|
475
485
|
|
|
476
486
|
export interface ContentDatabaseSourceFieldMapping {
|
|
@@ -640,6 +650,9 @@ export interface ContentDatabaseSource {
|
|
|
640
650
|
allowPublicationTransitions?: boolean;
|
|
641
651
|
notes?: string | null;
|
|
642
652
|
readMode?: "fixture" | "builder-api" | string | null;
|
|
653
|
+
connectionId?: string | null;
|
|
654
|
+
connectionLabel?: string | null;
|
|
655
|
+
truthPolicy?: ContentDatabaseSourceTruthPolicy;
|
|
643
656
|
liveReadConfigured?: boolean;
|
|
644
657
|
lastReadEntryCount?: number;
|
|
645
658
|
lastReadMatchedRowCount?: number;
|
|
@@ -764,6 +777,7 @@ export interface ContentDatabaseSourceFieldPropertyResponse {
|
|
|
764
777
|
|
|
765
778
|
export interface CreateDatabaseRequest {
|
|
766
779
|
documentId?: string;
|
|
780
|
+
spaceId?: string;
|
|
767
781
|
parentId?: string | null;
|
|
768
782
|
title?: string;
|
|
769
783
|
description?: string;
|