@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.
Files changed (205) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +12 -0
  3. package/corpus/core/docs/content/local-file-mode.mdx +99 -489
  4. package/corpus/core/docs/content/locales/ar-SA/local-file-mode.mdx +35 -490
  5. package/corpus/core/docs/content/locales/ar-SA/template-content.mdx +10 -24
  6. package/corpus/core/docs/content/locales/de-DE/local-file-mode.mdx +37 -491
  7. package/corpus/core/docs/content/locales/de-DE/template-content.mdx +10 -24
  8. package/corpus/core/docs/content/locales/es-ES/local-file-mode.mdx +35 -493
  9. package/corpus/core/docs/content/locales/es-ES/template-content.mdx +10 -24
  10. package/corpus/core/docs/content/locales/fr-FR/local-file-mode.mdx +38 -491
  11. package/corpus/core/docs/content/locales/fr-FR/template-content.mdx +10 -24
  12. package/corpus/core/docs/content/locales/hi-IN/local-file-mode.mdx +33 -492
  13. package/corpus/core/docs/content/locales/hi-IN/template-content.mdx +10 -24
  14. package/corpus/core/docs/content/locales/ja-JP/local-file-mode.mdx +36 -492
  15. package/corpus/core/docs/content/locales/ja-JP/template-content.mdx +10 -24
  16. package/corpus/core/docs/content/locales/ko-KR/local-file-mode.mdx +35 -490
  17. package/corpus/core/docs/content/locales/ko-KR/template-content.mdx +10 -24
  18. package/corpus/core/docs/content/locales/pt-BR/local-file-mode.mdx +35 -493
  19. package/corpus/core/docs/content/locales/pt-BR/template-content.mdx +10 -24
  20. package/corpus/core/docs/content/locales/zh-CN/local-file-mode.mdx +31 -489
  21. package/corpus/core/docs/content/locales/zh-CN/template-content.mdx +9 -24
  22. package/corpus/core/docs/content/locales/zh-TW/local-file-mode.mdx +31 -489
  23. package/corpus/core/docs/content/locales/zh-TW/template-content.mdx +9 -24
  24. package/corpus/core/docs/content/template-content.mdx +26 -42
  25. package/corpus/core/package.json +1 -1
  26. package/corpus/core/src/cli/content-local.ts +86 -18
  27. package/corpus/core/src/cli/index.ts +2 -2
  28. package/corpus/core/src/cli/skills-content/content-skill.ts +36 -25
  29. package/corpus/core/src/cli/skills.ts +47 -13
  30. package/corpus/core/src/local-artifacts/index.ts +65 -0
  31. package/corpus/core/src/vite/client.ts +2 -0
  32. package/corpus/templates/assets/app/components/library/GenerationPresetsPanel.tsx +325 -0
  33. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +12 -0
  34. package/corpus/templates/assets/app/i18n/zh-TW.ts +21 -0
  35. package/corpus/templates/assets/app/i18n-data.ts +215 -0
  36. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +19 -479
  37. package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +1 -1
  38. package/corpus/templates/assets/app/routes/brand-kits.$id_.settings.tsx +446 -0
  39. package/corpus/templates/clips/app/components/editor/editor-layout.tsx +12 -2
  40. package/corpus/templates/clips/app/components/player/settings-panel.tsx +30 -12
  41. package/corpus/templates/clips/app/components/player/video-player.tsx +5 -1
  42. package/corpus/templates/clips/app/components/recorder/microphone-visualizer.tsx +22 -3
  43. package/corpus/templates/clips/app/i18n/ar-SA.ts +3 -2
  44. package/corpus/templates/clips/app/i18n/de-DE.ts +4 -2
  45. package/corpus/templates/clips/app/i18n/en-US.ts +3 -2
  46. package/corpus/templates/clips/app/i18n/es-ES.ts +4 -2
  47. package/corpus/templates/clips/app/i18n/fr-FR.ts +3 -2
  48. package/corpus/templates/clips/app/i18n/hi-IN.ts +3 -2
  49. package/corpus/templates/clips/app/i18n/ja-JP.ts +4 -1
  50. package/corpus/templates/clips/app/i18n/ko-KR.ts +3 -2
  51. package/corpus/templates/clips/app/i18n/pt-BR.ts +4 -2
  52. package/corpus/templates/clips/app/i18n/zh-CN.ts +3 -2
  53. package/corpus/templates/clips/app/i18n/zh-TW.ts +3 -2
  54. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +27 -1
  55. package/corpus/templates/clips/server/lib/share-password.ts +6 -3
  56. package/corpus/templates/content/.agents/skills/content/SKILL.md +26 -39
  57. package/corpus/templates/content/AGENTS.md +25 -30
  58. package/corpus/templates/content/actions/_builder-docs-client.ts +23 -0
  59. package/corpus/templates/content/actions/_content-database-source-adapters.ts +21 -3
  60. package/corpus/templates/content/actions/_content-files.ts +338 -0
  61. package/corpus/templates/content/actions/_content-space-access.ts +135 -0
  62. package/corpus/templates/content/actions/_content-spaces.ts +640 -0
  63. package/corpus/templates/content/actions/_database-source-utils.ts +90 -7
  64. package/corpus/templates/content/actions/_database-utils.ts +7 -1
  65. package/corpus/templates/content/actions/_local-file-documents.ts +0 -9
  66. package/corpus/templates/content/actions/_local-folder-source.ts +53 -0
  67. package/corpus/templates/content/actions/_property-utils.ts +9 -4
  68. package/corpus/templates/content/actions/add-database-item.ts +108 -65
  69. package/corpus/templates/content/actions/backfill-content-files.ts +22 -0
  70. package/corpus/templates/content/actions/connect-local-folder-source.ts +221 -0
  71. package/corpus/templates/content/actions/create-content-database.ts +129 -3
  72. package/corpus/templates/content/actions/create-document.ts +65 -55
  73. package/corpus/templates/content/actions/create-inline-content-database.ts +6 -1
  74. package/corpus/templates/content/actions/delete-content-database.ts +3 -0
  75. package/corpus/templates/content/actions/delete-document.ts +7 -11
  76. package/corpus/templates/content/actions/disconnect-local-folder-source.ts +175 -0
  77. package/corpus/templates/content/actions/duplicate-database-item.ts +10 -0
  78. package/corpus/templates/content/actions/duplicate-database-items.ts +13 -0
  79. package/corpus/templates/content/actions/edit-document.ts +2 -28
  80. package/corpus/templates/content/actions/ensure-content-spaces.ts +26 -0
  81. package/corpus/templates/content/actions/export-content-source.ts +47 -9
  82. package/corpus/templates/content/actions/get-document.ts +0 -14
  83. package/corpus/templates/content/actions/import-content-source.ts +43 -3
  84. package/corpus/templates/content/actions/list-content-spaces.ts +103 -0
  85. package/corpus/templates/content/actions/list-documents.ts +12 -9
  86. package/corpus/templates/content/actions/move-document.ts +3 -14
  87. package/corpus/templates/content/actions/pull-document.ts +0 -23
  88. package/corpus/templates/content/actions/remove-local-file-source.ts +50 -29
  89. package/corpus/templates/content/actions/resolve-local-folder-conflict.ts +442 -0
  90. package/corpus/templates/content/actions/reveal-local-source-file.ts +6 -17
  91. package/corpus/templates/content/actions/search-documents.ts +0 -34
  92. package/corpus/templates/content/actions/share-local-file-document.ts +25 -1
  93. package/corpus/templates/content/actions/submit-content-database-form.ts +12 -0
  94. package/corpus/templates/content/actions/sync-local-folder-source.ts +731 -0
  95. package/corpus/templates/content/actions/sync-manifest-local-folder-source.ts +123 -0
  96. package/corpus/templates/content/actions/update-content-database-view.ts +10 -1
  97. package/corpus/templates/content/actions/update-document.ts +0 -15
  98. package/corpus/templates/content/actions/view-screen.ts +2 -50
  99. package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +76 -62
  100. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +70 -22
  101. package/corpus/templates/content/app/components/editor/database/grouping.ts +2 -1
  102. package/corpus/templates/content/app/components/editor/database/settings.tsx +23 -20
  103. package/corpus/templates/content/app/components/editor/database/shared.tsx +2 -0
  104. package/corpus/templates/content/app/components/editor/database/sidebar.tsx +330 -0
  105. package/corpus/templates/content/app/components/editor/database/types.ts +1 -0
  106. package/corpus/templates/content/app/components/editor/database/view-config.ts +3 -1
  107. package/corpus/templates/content/app/components/layout/Layout.tsx +25 -1
  108. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +209 -113
  109. package/corpus/templates/content/app/components/sidebar/select-content-space.ts +31 -0
  110. package/corpus/templates/content/app/hooks/use-content-database.ts +16 -0
  111. package/corpus/templates/content/app/hooks/use-content-spaces.ts +39 -0
  112. package/corpus/templates/content/app/i18n/zh-TW.ts +11 -0
  113. package/corpus/templates/content/app/i18n-data.ts +75 -0
  114. package/corpus/templates/content/app/routes/_app.local-files.tsx +174 -65
  115. package/corpus/templates/content/changelog/2026-07-16-content-callouts-can-now-be-reviewed-and-published-to-builder.md +6 -0
  116. package/corpus/templates/content/changelog/2026-07-16-heading-5-and-heading-6-are-available-from-the-editor-slash-.md +6 -0
  117. package/corpus/templates/content/changelog/2026-07-16-organize-every-workspace-through-a-customizable-files-databa.md +6 -0
  118. package/corpus/templates/content/parity/matrix.md +2 -1
  119. package/corpus/templates/content/parity/matrix.ts +37 -1
  120. package/corpus/templates/content/scripts/dev-database.mjs +7 -5
  121. package/corpus/templates/content/server/db/schema.ts +113 -40
  122. package/corpus/templates/content/server/lib/document-context.ts +15 -1
  123. package/corpus/templates/content/server/lib/notion-sync.ts +6 -0
  124. package/corpus/templates/content/server/plugins/db.ts +153 -0
  125. package/corpus/templates/content/shared/api.ts +17 -3
  126. package/corpus/templates/content/shared/builder-mdx.ts +163 -16
  127. package/corpus/templates/design/.agents/skills/design-templates/SKILL.md +59 -0
  128. package/corpus/templates/design/AGENTS.md +6 -1
  129. package/corpus/templates/design/actions/create-design-from-template.ts +19 -7
  130. package/corpus/templates/design/actions/list-design-templates.ts +69 -21
  131. package/corpus/templates/design/actions/navigate.ts +2 -2
  132. package/corpus/templates/design/actions/view-screen.ts +15 -2
  133. package/corpus/templates/design/agent-native.app-skill.json +5 -0
  134. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +281 -56
  135. package/corpus/templates/design/app/components/templates/TemplatePreview.tsx +14 -2
  136. package/corpus/templates/design/app/hooks/use-navigation-state.ts +3 -2
  137. package/corpus/templates/design/app/i18n/zh-TW.ts +3 -3
  138. package/corpus/templates/design/app/i18n-data.ts +21 -2
  139. package/corpus/templates/design/app/i18n-template-feature.ts +218 -10
  140. package/corpus/templates/design/app/pages/Index.tsx +195 -24
  141. package/corpus/templates/design/app/pages/Templates.tsx +144 -55
  142. package/corpus/templates/design/app/pages/design-editor/generation-prompt-directives.ts +12 -1
  143. package/corpus/templates/design/changelog/2026-07-14-templates-now-appear-in-the-new-design-picker-with-previews-.md +6 -0
  144. package/corpus/templates/design/changelog/2026-07-15-templates-now-open-immediately-after-copying-even-while-the-.md +6 -0
  145. package/corpus/templates/design/server/plugins/agent-chat.ts +1 -1
  146. package/corpus/templates/mail/AGENTS.md +23 -18
  147. package/corpus/templates/mail/actions/bulk-archive.ts +32 -28
  148. package/corpus/templates/mail/actions/mark-read.ts +131 -20
  149. package/corpus/templates/mail/actions/mark-thread-read.ts +1 -1
  150. package/corpus/templates/mail/actions/move-email.ts +30 -24
  151. package/corpus/templates/mail/actions/send-email.ts +73 -68
  152. package/corpus/templates/mail/changelog/2026-07-15-unread-inbox-cleanup-now-completes-reliably.md +6 -0
  153. package/corpus/templates/mail/server/handlers/emails.ts +218 -209
  154. package/corpus/templates/mail/server/lib/bulk-mark-read.ts +30 -0
  155. package/corpus/templates/mail/server/lib/email-state.ts +198 -113
  156. package/corpus/templates/mail/server/lib/google-auth.ts +218 -25
  157. package/corpus/templates/mail/server/lib/jobs.ts +69 -74
  158. package/corpus/templates/mail/server/lib/local-email-store.ts +265 -0
  159. package/corpus/templates/mail/server/plugins/agent-chat.ts +6 -0
  160. package/dist/cli/content-local.d.ts +1 -0
  161. package/dist/cli/content-local.d.ts.map +1 -1
  162. package/dist/cli/content-local.js +75 -17
  163. package/dist/cli/content-local.js.map +1 -1
  164. package/dist/cli/index.js +2 -2
  165. package/dist/cli/index.js.map +1 -1
  166. package/dist/cli/skills-content/content-skill.d.ts +1 -1
  167. package/dist/cli/skills-content/content-skill.d.ts.map +1 -1
  168. package/dist/cli/skills-content/content-skill.js +36 -25
  169. package/dist/cli/skills-content/content-skill.js.map +1 -1
  170. package/dist/cli/skills.d.ts.map +1 -1
  171. package/dist/cli/skills.js +47 -14
  172. package/dist/cli/skills.js.map +1 -1
  173. package/dist/collab/struct-routes.d.ts +1 -1
  174. package/dist/local-artifacts/index.d.ts +10 -0
  175. package/dist/local-artifacts/index.d.ts.map +1 -1
  176. package/dist/local-artifacts/index.js +39 -0
  177. package/dist/local-artifacts/index.js.map +1 -1
  178. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  179. package/dist/vite/client.d.ts.map +1 -1
  180. package/dist/vite/client.js +2 -0
  181. package/dist/vite/client.js.map +1 -1
  182. package/docs/content/local-file-mode.mdx +99 -489
  183. package/docs/content/locales/ar-SA/local-file-mode.mdx +35 -490
  184. package/docs/content/locales/ar-SA/template-content.mdx +10 -24
  185. package/docs/content/locales/de-DE/local-file-mode.mdx +37 -491
  186. package/docs/content/locales/de-DE/template-content.mdx +10 -24
  187. package/docs/content/locales/es-ES/local-file-mode.mdx +35 -493
  188. package/docs/content/locales/es-ES/template-content.mdx +10 -24
  189. package/docs/content/locales/fr-FR/local-file-mode.mdx +38 -491
  190. package/docs/content/locales/fr-FR/template-content.mdx +10 -24
  191. package/docs/content/locales/hi-IN/local-file-mode.mdx +33 -492
  192. package/docs/content/locales/hi-IN/template-content.mdx +10 -24
  193. package/docs/content/locales/ja-JP/local-file-mode.mdx +36 -492
  194. package/docs/content/locales/ja-JP/template-content.mdx +10 -24
  195. package/docs/content/locales/ko-KR/local-file-mode.mdx +35 -490
  196. package/docs/content/locales/ko-KR/template-content.mdx +10 -24
  197. package/docs/content/locales/pt-BR/local-file-mode.mdx +35 -493
  198. package/docs/content/locales/pt-BR/template-content.mdx +10 -24
  199. package/docs/content/locales/zh-CN/local-file-mode.mdx +31 -489
  200. package/docs/content/locales/zh-CN/template-content.mdx +9 -24
  201. package/docs/content/locales/zh-TW/local-file-mode.mdx +31 -489
  202. package/docs/content/locales/zh-TW/template-content.mdx +9 -24
  203. package/docs/content/template-content.mdx +26 -42
  204. package/package.json +1 -1
  205. package/corpus/templates/assets/app/components/library/EditLibraryDialog.tsx +0 -126
@@ -2750,6 +2750,8 @@ const editorSlashMessages = {
2750
2750
  heading2Description: "Medium heading",
2751
2751
  heading3Description: "Small heading",
2752
2752
  heading4Description: "Subheading",
2753
+ heading5Description: "Smaller heading",
2754
+ heading6Description: "Smallest heading",
2753
2755
  image: "Image",
2754
2756
  imageDescription: "Upload or embed image",
2755
2757
  inlineEquation: "Inline equation",
@@ -2795,6 +2797,9 @@ const localFilesMessages = {
2795
2797
  summaryUnchanged: "{{count}} unchanged",
2796
2798
  summarySkipped: "{{count}} skipped",
2797
2799
  summaryErrors: "{{count}} errors",
2800
+ summaryConflicts: "{{count}} conflicts",
2801
+ conflictNeedsReview:
2802
+ "Content and the folder both changed; review is required.",
2798
2803
  pageTitle: "Local files",
2799
2804
  foldersRemembered: "Folders remembered",
2800
2805
  linkedCount: "{{count}} linked",
@@ -2947,6 +2952,8 @@ const enUS = {
2947
2952
  heading2: "Heading 2",
2948
2953
  heading3: "Heading 3",
2949
2954
  heading4: "Heading 4",
2955
+ heading5: "Heading 5",
2956
+ heading6: "Heading 6",
2950
2957
  link: "Link",
2951
2958
  comment: "Comment",
2952
2959
  pasteLink: "Paste link...",
@@ -3107,11 +3114,14 @@ const enUS = {
3107
3114
  "“{{title}}” and all its sub-pages will be permanently deleted. This cannot be undone.",
3108
3115
  deletePageQuestion: "Delete page?",
3109
3116
  localFiles: "Local files",
3117
+ files: "Files",
3118
+ loadingFiles: "Loading files…",
3110
3119
  localFilesActions: "Local files actions",
3111
3120
  localFilesRemoved: "Local files removed",
3112
3121
  localFilesRemovedDescription: "{{count}} items removed",
3113
3122
  manageLocalFolders: "Manage folders",
3114
3123
  new: "New",
3124
+ newDatabase: "New database",
3115
3125
  newPage: "New page",
3116
3126
  nextStep: "Next step",
3117
3127
  notionConfigureOAuthAuthorize:
@@ -3143,6 +3153,7 @@ const enUS = {
3143
3153
  "Sync documents with your Notion workspace.",
3144
3154
  notionUploadCredentialsJson: "Upload credentials JSON",
3145
3155
  noFilesYet: "No files yet",
3156
+ noWorkspaces: "No workspaces yet",
3146
3157
  noLocalFilesYet: "No local files yet",
3147
3158
  noOrganizationPagesYet: "No organization pages yet",
3148
3159
  noPagesFound: "No pages found",
@@ -3168,6 +3179,7 @@ const enUS = {
3168
3179
  trash: "Trash",
3169
3180
  favorites: "Favorites",
3170
3181
  untitled: "Untitled",
3182
+ workspaces: "Workspaces",
3171
3183
  },
3172
3184
  };
3173
3185
 
@@ -5608,6 +5620,8 @@ const editorMessagesByLocale = {
5608
5620
  heading2Description: "中标题",
5609
5621
  heading3Description: "小标题",
5610
5622
  heading4Description: "副标题",
5623
+ heading5Description: "较小标题",
5624
+ heading6Description: "最小标题",
5611
5625
  image: "图片",
5612
5626
  imageDescription: "上传或嵌入图像",
5613
5627
  localComponents: "本地组件",
@@ -5944,6 +5958,8 @@ const editorMessagesByLocale = {
5944
5958
  heading2Description: "título medio",
5945
5959
  heading3Description: "título pequeño",
5946
5960
  heading4Description: "Subtítulo",
5961
+ heading5Description: "Encabezado más pequeño",
5962
+ heading6Description: "Encabezado mínimo",
5947
5963
  image: "Imagen",
5948
5964
  imageDescription: "Subir o insertar imagen",
5949
5965
  localComponents: "Componentes locales",
@@ -6292,6 +6308,8 @@ const editorMessagesByLocale = {
6292
6308
  heading2Description: "Titre moyen",
6293
6309
  heading3Description: "Petit titre",
6294
6310
  heading4Description: "Sous-titre",
6311
+ heading5Description: "Titre plus petit",
6312
+ heading6Description: "Titre le plus petit",
6295
6313
  image: "Images",
6296
6314
  imageDescription: "Télécharger ou intégrer une image",
6297
6315
  localComponents: "Composants locaux",
@@ -6640,6 +6658,8 @@ const editorMessagesByLocale = {
6640
6658
  heading2Description: "Mittlere Überschrift",
6641
6659
  heading3Description: "Kleine Überschrift",
6642
6660
  heading4Description: "Unterüberschrift",
6661
+ heading5Description: "Kleinere Überschrift",
6662
+ heading6Description: "Kleinste Überschrift",
6643
6663
  image: "Bild",
6644
6664
  imageDescription: "Bild hochladen oder einbetten",
6645
6665
  localComponents: "Lokale Komponenten",
@@ -6987,6 +7007,8 @@ const editorMessagesByLocale = {
6987
7007
  heading2Description: "中見出し",
6988
7008
  heading3Description: "小見出し",
6989
7009
  heading4Description: "小見出し",
7010
+ heading5Description: "より小さい見出し",
7011
+ heading6Description: "最小の見出し",
6990
7012
  image: "画像",
6991
7013
  imageDescription: "画像をアップロードまたは埋め込む",
6992
7014
  localComponents: "ローカルコンポーネント",
@@ -7327,6 +7349,8 @@ const editorMessagesByLocale = {
7327
7349
  heading2Description: "중간 제목",
7328
7350
  heading3Description: "작은 제목",
7329
7351
  heading4Description: "소제목",
7352
+ heading5Description: "더 작은 제목",
7353
+ heading6Description: "가장 작은 제목",
7330
7354
  image: "이미지",
7331
7355
  imageDescription: "이미지 업로드 또는 삽입",
7332
7356
  localComponents: "로컬 구성요소",
@@ -7670,6 +7694,8 @@ const editorMessagesByLocale = {
7670
7694
  heading2Description: "Título médio",
7671
7695
  heading3Description: "Título pequeno",
7672
7696
  heading4Description: "Subtítulo",
7697
+ heading5Description: "Título menor",
7698
+ heading6Description: "Título mínimo",
7673
7699
  image: "Imagem",
7674
7700
  imageDescription: "Carregar ou incorporar imagem",
7675
7701
  localComponents: "Componentes locais",
@@ -8012,6 +8038,8 @@ const editorMessagesByLocale = {
8012
8038
  heading2Description: "मध्यम शीर्षक",
8013
8039
  heading3Description: "छोटा शीर्षक",
8014
8040
  heading4Description: "उपशीर्षक",
8041
+ heading5Description: "और छोटा शीर्षक",
8042
+ heading6Description: "सबसे छोटा शीर्षक",
8015
8043
  image: "छवि",
8016
8044
  imageDescription: "छवि अपलोड या एम्बेड करें",
8017
8045
  localComponents: "स्थानीय घटक",
@@ -8348,6 +8376,8 @@ const editorMessagesByLocale = {
8348
8376
  heading2Description: "عنوان متوسط",
8349
8377
  heading3Description: "عنوان صغير",
8350
8378
  heading4Description: "عنوان فرعي",
8379
+ heading5Description: "عنوان أصغر",
8380
+ heading6Description: "أصغر عنوان",
8351
8381
  image: "صورة",
8352
8382
  imageDescription: "تحميل أو تضمين الصورة",
8353
8383
  localComponents: "المكونات المحلية",
@@ -8810,6 +8840,8 @@ export const messagesByLocale = {
8810
8840
  heading2: "标题 2",
8811
8841
  heading3: "标题 3",
8812
8842
  heading4: "标题 4",
8843
+ heading5: "标题 5",
8844
+ heading6: "标题 6",
8813
8845
  link: "链接",
8814
8846
  comment: "评论",
8815
8847
  pasteLink: "粘贴链接...",
@@ -8835,6 +8867,9 @@ export const messagesByLocale = {
8835
8867
  },
8836
8868
  sidebar: {
8837
8869
  cannotReorderPages: "无法重新排序页面",
8870
+ loadingFiles: "正在加载文件…",
8871
+ newDatabase: "新建数据库",
8872
+ noWorkspaces: "还没有工作区",
8838
8873
  collapse: "折叠侧边栏",
8839
8874
  expand: "展开侧边栏",
8840
8875
  failedCreatePage: "创建页面失败",
@@ -8994,6 +9029,8 @@ export const messagesByLocale = {
8994
9029
  heading2: "Encabezado 2",
8995
9030
  heading3: "Encabezado 3",
8996
9031
  heading4: "Encabezado 4",
9032
+ heading5: "Encabezado 5",
9033
+ heading6: "Encabezado 6",
8997
9034
  link: "Enlace",
8998
9035
  comment: "Comentario",
8999
9036
  pasteLink: "Pegar enlace...",
@@ -9020,6 +9057,9 @@ export const messagesByLocale = {
9020
9057
  },
9021
9058
  sidebar: {
9022
9059
  cannotReorderPages: "No se pueden reordenar las páginas",
9060
+ loadingFiles: "Cargando archivos…",
9061
+ newDatabase: "Nueva base de datos",
9062
+ noWorkspaces: "Aún no hay espacios de trabajo",
9023
9063
  collapse: "Contraer barra lateral",
9024
9064
  expand: "Expandir barra lateral",
9025
9065
  failedCreatePage: "No se pudo crear la página",
@@ -9180,6 +9220,8 @@ export const messagesByLocale = {
9180
9220
  heading2: "Titre 2",
9181
9221
  heading3: "Titre 3",
9182
9222
  heading4: "Titre 4",
9223
+ heading5: "Titre 5",
9224
+ heading6: "Titre 6",
9183
9225
  link: "Lien",
9184
9226
  comment: "Commentaire",
9185
9227
  pasteLink: "Coller le lien...",
@@ -9206,6 +9248,9 @@ export const messagesByLocale = {
9206
9248
  },
9207
9249
  sidebar: {
9208
9250
  cannotReorderPages: "Impossible de réordonner les pages",
9251
+ loadingFiles: "Chargement des fichiers…",
9252
+ newDatabase: "Nouvelle base de données",
9253
+ noWorkspaces: "Aucun espace de travail pour le moment",
9209
9254
  collapse: "Réduire la barre latérale",
9210
9255
  expand: "Développer la barre latérale",
9211
9256
  failedCreatePage: "Échec de la création de la page",
@@ -9364,6 +9409,8 @@ export const messagesByLocale = {
9364
9409
  heading2: "Überschrift 2",
9365
9410
  heading3: "Überschrift 3",
9366
9411
  heading4: "Überschrift 4",
9412
+ heading5: "Überschrift 5",
9413
+ heading6: "Überschrift 6",
9367
9414
  link: "Link",
9368
9415
  comment: "Kommentar",
9369
9416
  pasteLink: "Link einfügen...",
@@ -9390,6 +9437,9 @@ export const messagesByLocale = {
9390
9437
  },
9391
9438
  sidebar: {
9392
9439
  cannotReorderPages: "Seiten können nicht neu angeordnet werden",
9440
+ loadingFiles: "Dateien werden geladen…",
9441
+ newDatabase: "Neue Datenbank",
9442
+ noWorkspaces: "Noch keine Arbeitsbereiche",
9393
9443
  collapse: "Seitenleiste einklappen",
9394
9444
  expand: "Seitenleiste ausklappen",
9395
9445
  failedCreatePage: "Seite konnte nicht erstellt werden",
@@ -9548,6 +9598,8 @@ export const messagesByLocale = {
9548
9598
  heading2: "見出し 2",
9549
9599
  heading3: "見出し 3",
9550
9600
  heading4: "見出し 4",
9601
+ heading5: "見出し 5",
9602
+ heading6: "見出し 6",
9551
9603
  link: "リンク",
9552
9604
  comment: "コメント",
9553
9605
  pasteLink: "リンクを貼り付け...",
@@ -9574,6 +9626,9 @@ export const messagesByLocale = {
9574
9626
  },
9575
9627
  sidebar: {
9576
9628
  cannotReorderPages: "ページを並べ替えられません",
9629
+ loadingFiles: "ファイルを読み込んでいます…",
9630
+ newDatabase: "新しいデータベース",
9631
+ noWorkspaces: "ワークスペースはまだありません",
9577
9632
  collapse: "サイドバーを折りたたむ",
9578
9633
  expand: "サイドバーを展開",
9579
9634
  failedCreatePage: "ページを作成できませんでした",
@@ -9722,6 +9777,8 @@ export const messagesByLocale = {
9722
9777
  heading2: "제목 2",
9723
9778
  heading3: "제목 3",
9724
9779
  heading4: "제목 4",
9780
+ heading5: "제목 5",
9781
+ heading6: "제목 6",
9725
9782
  link: "링크",
9726
9783
  comment: "댓글",
9727
9784
  pasteLink: "링크 붙여넣기...",
@@ -9747,6 +9804,9 @@ export const messagesByLocale = {
9747
9804
  },
9748
9805
  sidebar: {
9749
9806
  cannotReorderPages: "페이지 순서를 변경할 수 없습니다",
9807
+ loadingFiles: "파일을 불러오는 중…",
9808
+ newDatabase: "새 데이터베이스",
9809
+ noWorkspaces: "아직 워크스페이스가 없습니다",
9750
9810
  collapse: "사이드바 접기",
9751
9811
  expand: "사이드바 펼치기",
9752
9812
  failedCreatePage: "페이지를 만들지 못했습니다",
@@ -9906,6 +9966,8 @@ export const messagesByLocale = {
9906
9966
  heading2: "Título 2",
9907
9967
  heading3: "Título 3",
9908
9968
  heading4: "Título 4",
9969
+ heading5: "Título 5",
9970
+ heading6: "Título 6",
9909
9971
  link: "Link",
9910
9972
  comment: "Comentário",
9911
9973
  pasteLink: "Cole o link...",
@@ -9932,6 +9994,9 @@ export const messagesByLocale = {
9932
9994
  },
9933
9995
  sidebar: {
9934
9996
  cannotReorderPages: "Não é possível reordenar páginas",
9997
+ loadingFiles: "Carregando arquivos…",
9998
+ newDatabase: "Novo banco de dados",
9999
+ noWorkspaces: "Ainda não há espaços de trabalho",
9935
10000
  collapse: "Recolher barra lateral",
9936
10001
  expand: "Expandir barra lateral",
9937
10002
  failedCreatePage: "Falha ao criar página",
@@ -10078,6 +10143,8 @@ export const messagesByLocale = {
10078
10143
  heading2: "शीर्षक 2",
10079
10144
  heading3: "शीर्षक 3",
10080
10145
  heading4: "शीर्षक 4",
10146
+ heading5: "शीर्षक 5",
10147
+ heading6: "शीर्षक 6",
10081
10148
  link: "लिंक",
10082
10149
  comment: "टिप्पणी",
10083
10150
  pasteLink: "लिंक चिपकाएं...",
@@ -10103,6 +10170,9 @@ export const messagesByLocale = {
10103
10170
  },
10104
10171
  sidebar: {
10105
10172
  cannotReorderPages: "पेजों को फिर से क्रमबद्ध नहीं किया जा सकता",
10173
+ loadingFiles: "फ़ाइलें लोड हो रही हैं…",
10174
+ newDatabase: "नया डेटाबेस",
10175
+ noWorkspaces: "अभी कोई कार्यस्थान नहीं है",
10106
10176
  collapse: "साइडबार संकुचित करें",
10107
10177
  expand: "साइडबार फैलाएं",
10108
10178
  failedCreatePage: "पेज नहीं बन सका",
@@ -10252,6 +10322,8 @@ export const messagesByLocale = {
10252
10322
  heading2: "عنوان 2",
10253
10323
  heading3: "عنوان 3",
10254
10324
  heading4: "عنوان 4",
10325
+ heading5: "عنوان 5",
10326
+ heading6: "عنوان 6",
10255
10327
  link: "رابط",
10256
10328
  comment: "تعليق",
10257
10329
  pasteLink: "الصق الرابط...",
@@ -10277,6 +10349,9 @@ export const messagesByLocale = {
10277
10349
  },
10278
10350
  sidebar: {
10279
10351
  cannotReorderPages: "تعذرت إعادة ترتيب الصفحات",
10352
+ loadingFiles: "جارٍ تحميل الملفات…",
10353
+ newDatabase: "قاعدة بيانات جديدة",
10354
+ noWorkspaces: "لا توجد مساحات عمل بعد",
10280
10355
  collapse: "طي الشريط الجانبي",
10281
10356
  expand: "توسيع الشريط الجانبي",
10282
10357
  failedCreatePage: "فشل إنشاء الصفحة",
@@ -15,7 +15,8 @@ import {
15
15
  IconUpload,
16
16
  } from "@tabler/icons-react";
17
17
  import { useQueryClient } from "@tanstack/react-query";
18
- import { useEffect, useMemo, useState } from "react";
18
+ import { useEffect, useMemo, useRef, useState } from "react";
19
+ import { useNavigate, useSearchParams } from "react-router";
19
20
  import { toast } from "sonner";
20
21
 
21
22
  import { Button } from "@/components/ui/button";
@@ -128,6 +129,18 @@ interface ImportContentSourceResult {
128
129
  unchanged: Array<{ id: string; path: string; title: string }>;
129
130
  skipped: Array<{ path: string; reason: string }>;
130
131
  errors: Array<{ path: string; reason: string }>;
132
+ conflicts?: Array<{ id: string; path: string; title: string }>;
133
+ }
134
+
135
+ interface LocalFolderConnectionResult {
136
+ connected: boolean;
137
+ sourceId: string | null;
138
+ spaceId: string | null;
139
+ filesDatabaseId: string | null;
140
+ }
141
+
142
+ interface ManifestFolderSyncResult extends ImportContentSourceResult {
143
+ requestedDocumentId: string | null;
131
144
  }
132
145
 
133
146
  interface RegisterLocalComponentWorkspaceResult {
@@ -234,11 +247,20 @@ function browserDirectoryId() {
234
247
  return `browser-${crypto.randomUUID()}`;
235
248
  }
236
249
 
250
+ function opaqueDesktopDirectoryId(value: string) {
251
+ let hash = 2166136261;
252
+ for (let index = 0; index < value.length; index += 1) {
253
+ hash ^= value.charCodeAt(index);
254
+ hash = Math.imul(hash, 16777619);
255
+ }
256
+ return `desktop-folder-${(hash >>> 0).toString(16).padStart(8, "0")}`;
257
+ }
258
+
237
259
  function desktopDirectoryFromFolder(
238
260
  folder: DesktopContentFilesFolder,
239
261
  directories: SelectedDirectory[] = [],
240
262
  ): SelectedDirectory {
241
- const id = folder.id ?? `desktop-${folder.path ?? folder.name}`;
263
+ const id = folder.id ?? opaqueDesktopDirectoryId(folder.path ?? folder.name);
242
264
  return {
243
265
  id,
244
266
  kind: "desktop",
@@ -694,42 +716,6 @@ function upsertDirectory(
694
716
  );
695
717
  }
696
718
 
697
- function sourcePathForDirectoryFile(
698
- directory: SelectedDirectory,
699
- filePath: string,
700
- directoryCount: number,
701
- ) {
702
- if (directoryCount <= 1) return filePath;
703
- return `${directory.sourcePrefix}/${filePath}`;
704
- }
705
-
706
- function filesForImport(
707
- directory: SelectedDirectory,
708
- files: Record<string, string>,
709
- directoryCount: number,
710
- ) {
711
- return Object.fromEntries(
712
- Object.entries(files).map(([path, content]) => [
713
- sourcePathForDirectoryFile(directory, path, directoryCount),
714
- content,
715
- ]),
716
- );
717
- }
718
-
719
- function filesForDirectoryExport(
720
- directory: SelectedDirectory,
721
- files: Record<string, string>,
722
- directoryCount: number,
723
- ) {
724
- if (directoryCount <= 1) return files;
725
- const prefix = `${directory.sourcePrefix}/`;
726
- return Object.fromEntries(
727
- Object.entries(files)
728
- .filter(([path]) => path.startsWith(prefix))
729
- .map(([path, content]) => [path.slice(prefix.length), content]),
730
- );
731
- }
732
-
733
719
  function resultSummary(
734
720
  result: ImportContentSourceResult,
735
721
  t: ReturnType<typeof useT>,
@@ -740,6 +726,7 @@ function resultSummary(
740
726
  t("localFiles.summaryUnchanged", { count: result.unchanged.length }),
741
727
  t("localFiles.summarySkipped", { count: result.skipped.length }),
742
728
  t("localFiles.summaryErrors", { count: result.errors.length }),
729
+ t("localFiles.summaryConflicts", { count: result.conflicts?.length ?? 0 }),
743
730
  ].join(" | ");
744
731
  }
745
732
 
@@ -750,12 +737,18 @@ export function meta() {
750
737
  export default function LocalFilesRoute() {
751
738
  const t = useT();
752
739
  const queryClient = useQueryClient();
740
+ const [searchParams] = useSearchParams();
741
+ const navigate = useNavigate();
742
+ const targetSpaceId = searchParams.get("spaceId") || undefined;
743
+ const manifestConnectionId = searchParams.get("connectionId") || undefined;
744
+ const manifestFile = searchParams.get("file") || undefined;
753
745
  const { data: documents = [] } = useDocuments();
754
746
  const [directories, setDirectories] = useState<SelectedDirectory[]>([]);
755
747
  const [status, setStatus] = useState<SyncStatus>({ kind: "idle" });
756
748
  const [busy, setBusy] = useState<BusyState | null>(null);
757
749
  const [restoringDirectory, setRestoringDirectory] = useState(false);
758
750
  const supported = useMemo(supportsLocalFolderSync, []);
751
+ const manifestBootstrapRef = useRef<string | null>(null);
759
752
  const documentSourceDirectories = useMemo(
760
753
  () =>
761
754
  directories.length === 0
@@ -786,6 +779,59 @@ export default function LocalFilesRoute() {
786
779
  });
787
780
  }, [localFolderRows]);
788
781
 
782
+ useEffect(() => {
783
+ if (!manifestConnectionId) return;
784
+ const key = `${manifestConnectionId}:${manifestFile ?? ""}:${targetSpaceId ?? ""}`;
785
+ if (manifestBootstrapRef.current === key) return;
786
+ manifestBootstrapRef.current = key;
787
+ setBusy("choose");
788
+ void callAction<ManifestFolderSyncResult>(
789
+ "sync-manifest-local-folder-source" as never,
790
+ {
791
+ connectionId: manifestConnectionId,
792
+ file: manifestFile,
793
+ spaceId: targetSpaceId,
794
+ dryRun: false,
795
+ } as never,
796
+ )
797
+ .then((result) => {
798
+ queryClient.invalidateQueries({
799
+ queryKey: ["action", "list-documents"],
800
+ });
801
+ queryClient.invalidateQueries({
802
+ queryKey: ["action", "list-content-spaces"],
803
+ });
804
+ setStatus(
805
+ result.conflicts?.length
806
+ ? { kind: "preview", result }
807
+ : {
808
+ kind: "success",
809
+ title: t("localFiles.foldersPulled"),
810
+ detail: resultSummary(result, t),
811
+ },
812
+ );
813
+ if (result.requestedDocumentId) {
814
+ navigate(`/page/${result.requestedDocumentId}`, { replace: true });
815
+ }
816
+ })
817
+ .catch((err) => {
818
+ manifestBootstrapRef.current = null;
819
+ setStatus({
820
+ kind: "error",
821
+ title: t("localFiles.pullFailed"),
822
+ detail: err instanceof Error ? err.message : t("localFiles.tryAgain"),
823
+ });
824
+ })
825
+ .finally(() => setBusy(null));
826
+ }, [
827
+ manifestConnectionId,
828
+ manifestFile,
829
+ navigate,
830
+ queryClient,
831
+ t,
832
+ targetSpaceId,
833
+ ]);
834
+
789
835
  useEffect(() => {
790
836
  if (!supported) return;
791
837
  let cancelled = false;
@@ -859,6 +905,23 @@ export default function LocalFilesRoute() {
859
905
  );
860
906
  }
861
907
 
908
+ async function ensureDirectoryConnection(
909
+ directory: SelectedDirectory,
910
+ dryRun = false,
911
+ ) {
912
+ return callAction<LocalFolderConnectionResult>(
913
+ "connect-local-folder-source" as never,
914
+ {
915
+ connectionId: directory.id,
916
+ label: directory.sourcePrefix || directory.name,
917
+ spaceId: targetSpaceId,
918
+ createSourceBackedSpace: !targetSpaceId,
919
+ truthPolicy: "source_primary",
920
+ dryRun,
921
+ } as never,
922
+ );
923
+ }
924
+
862
925
  async function pullDirectoryFiles(
863
926
  selected: SelectedDirectory,
864
927
  activeDirectories: SelectedDirectory[],
@@ -898,33 +961,53 @@ export default function LocalFilesRoute() {
898
961
  queryClient.invalidateQueries({ queryKey: ["resources"] });
899
962
  }
900
963
  }
901
- if (Object.keys(files).length === 0) {
964
+ const connection = await ensureDirectoryConnection(
965
+ refreshedDirectory,
966
+ dryRun,
967
+ );
968
+ if (dryRun && !connection.connected) {
969
+ const created = Object.keys(files).map((path) => ({
970
+ id: "",
971
+ path,
972
+ title:
973
+ path
974
+ .split("/")
975
+ .pop()
976
+ ?.replace(/\.mdx?$/i, "") || path,
977
+ }));
902
978
  return {
903
979
  directories: nextDirectories,
904
980
  result: {
905
- dryRun,
906
- filesSeen: 0,
907
- created: [],
981
+ dryRun: true,
982
+ filesSeen: created.length,
983
+ created,
908
984
  updated: [],
909
985
  unchanged: [],
910
986
  skipped: [],
911
987
  errors: [],
988
+ conflicts: [],
912
989
  },
913
990
  };
914
991
  }
992
+ if (!connection.sourceId) {
993
+ throw new Error("The local folder connection was not created");
994
+ }
915
995
  const result = await callAction<ImportContentSourceResult>(
916
- "import-content-source" as never,
996
+ "sync-local-folder-source" as never,
917
997
  {
918
- files: filesForImport(
919
- refreshedDirectory,
920
- files,
921
- nextDirectories.length,
922
- ),
998
+ sourceId: connection.sourceId,
999
+ files,
923
1000
  dryRun,
924
1001
  } as never,
925
1002
  );
926
1003
  if (!dryRun) {
927
1004
  queryClient.invalidateQueries({ queryKey: ["action", "list-documents"] });
1005
+ queryClient.invalidateQueries({
1006
+ queryKey: ["action", "list-content-spaces"],
1007
+ });
1008
+ queryClient.invalidateQueries({
1009
+ queryKey: ["action", "get-content-database"],
1010
+ });
928
1011
  }
929
1012
  return { directories: nextDirectories, result };
930
1013
  }
@@ -990,11 +1073,15 @@ export default function LocalFilesRoute() {
990
1073
 
991
1074
  setBusy(`pull:${selected.id}`);
992
1075
  const { result } = await pullDirectoryFiles(selected, nextDirectories);
993
- setStatus({
994
- kind: "success",
995
- title: t("localFiles.foldersPulled"),
996
- detail: resultSummary(result, t),
997
- });
1076
+ setStatus(
1077
+ result.conflicts?.length
1078
+ ? { kind: "preview", result }
1079
+ : {
1080
+ kind: "success",
1081
+ title: t("localFiles.foldersPulled"),
1082
+ detail: resultSummary(result, t),
1083
+ },
1084
+ );
998
1085
  toast.success(t("localFiles.pulledLocalFiles"));
999
1086
  await connectLocalComponentWorkspaces([selected]);
1000
1087
  } catch (err) {
@@ -1020,16 +1107,13 @@ export default function LocalFilesRoute() {
1020
1107
  ) {
1021
1108
  throw new Error(t("localFiles.writePermissionNotGranted"));
1022
1109
  }
1110
+ const connection = await ensureDirectoryConnection(directory);
1023
1111
  const bundle = await callAction<ExportContentSourceResult>(
1024
1112
  "export-content-source" as never,
1025
- {} as never,
1113
+ { sourceId: connection.sourceId } as never,
1026
1114
  { method: "GET" },
1027
1115
  );
1028
- const files = filesForDirectoryExport(
1029
- directory,
1030
- bundle.files,
1031
- directories.length,
1032
- );
1116
+ const files = bundle.files;
1033
1117
  if (directory.kind === "desktop") {
1034
1118
  const desktopFiles = getDesktopContentFiles();
1035
1119
  if (!desktopFiles) {
@@ -1099,11 +1183,15 @@ export default function LocalFilesRoute() {
1099
1183
  setBusy(`pull:${directory.id}`);
1100
1184
  try {
1101
1185
  const { result } = await pullDirectoryFiles(directory, directories);
1102
- setStatus({
1103
- kind: "success",
1104
- title: t("localFiles.pulledFromFolder"),
1105
- detail: resultSummary(result, t),
1106
- });
1186
+ setStatus(
1187
+ result.conflicts?.length
1188
+ ? { kind: "preview", result }
1189
+ : {
1190
+ kind: "success",
1191
+ title: t("localFiles.pulledFromFolder"),
1192
+ detail: resultSummary(result, t),
1193
+ },
1194
+ );
1107
1195
  toast.success(t("localFiles.pulledLocalFiles"));
1108
1196
  } catch (err) {
1109
1197
  setStatus({
@@ -1119,6 +1207,11 @@ export default function LocalFilesRoute() {
1119
1207
  async function handleRemove(directory: SelectedDirectory) {
1120
1208
  setBusy(`remove:${directory.id}`);
1121
1209
  try {
1210
+ const connection = await ensureDirectoryConnection(directory);
1211
+ await callAction(
1212
+ "disconnect-local-folder-source" as never,
1213
+ { sourceId: connection.sourceId } as never,
1214
+ );
1122
1215
  const nextDirectories = directories.filter(
1123
1216
  (candidate) => candidate.id !== directory.id,
1124
1217
  );
@@ -1132,6 +1225,12 @@ export default function LocalFilesRoute() {
1132
1225
  await persistSourceDirectories(nextDirectories);
1133
1226
  }
1134
1227
  setDirectories(nextDirectories);
1228
+ queryClient.invalidateQueries({
1229
+ queryKey: ["action", "list-content-spaces"],
1230
+ });
1231
+ queryClient.invalidateQueries({
1232
+ queryKey: ["action", "get-content-database"],
1233
+ });
1135
1234
  setStatus({
1136
1235
  kind: "success",
1137
1236
  title: t("localFiles.folderRemoved"),
@@ -1266,7 +1365,8 @@ export default function LocalFilesRoute() {
1266
1365
  </div>
1267
1366
  </div>
1268
1367
  {(status.result.skipped.length > 0 ||
1269
- status.result.errors.length > 0) && (
1368
+ status.result.errors.length > 0 ||
1369
+ (status.result.conflicts?.length ?? 0) > 0) && (
1270
1370
  <>
1271
1371
  <Separator />
1272
1372
  <div className="grid gap-1 text-xs">
@@ -1284,6 +1384,15 @@ export default function LocalFilesRoute() {
1284
1384
  </span>
1285
1385
  </div>
1286
1386
  ))}
1387
+ {status.result.conflicts?.slice(0, 6).map((item) => (
1388
+ <div key={`conflict:${item.id}`} className="min-w-0">
1389
+ <span className="font-medium">{item.path}</span>
1390
+ <span className="text-muted-foreground">
1391
+ {" "}
1392
+ - {t("localFiles.conflictNeedsReview")}
1393
+ </span>
1394
+ </div>
1395
+ ))}
1287
1396
  </div>
1288
1397
  </>
1289
1398
  )}
@@ -0,0 +1,6 @@
1
+ ---
2
+ title: Content callouts can now be reviewed and published to Builder
3
+ type: fixed
4
+ ---
5
+
6
+ Content callout blocks now convert into safe Builder text callouts instead of blocking the publication review.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-16
4
+ ---
5
+
6
+ Heading 5 and Heading 6 are available from the editor slash menu.