@agent-native/core 0.82.0 → 0.83.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +6 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/client/CommandMenu.tsx +34 -12
  5. package/corpus/templates/analytics/actions/hubspot-deals.ts +64 -4
  6. package/corpus/templates/content/.env.local.example +6 -0
  7. package/corpus/templates/content/AGENTS.md +10 -1
  8. package/corpus/templates/content/actions/_builder-cms-read-client.ts +14 -1
  9. package/corpus/templates/content/actions/_builder-cms-source-adapter.ts +43 -0
  10. package/corpus/templates/content/actions/_builder-cms-write-adapter.ts +79 -7
  11. package/corpus/templates/content/actions/_database-source-utils.ts +987 -22
  12. package/corpus/templates/content/actions/_database-utils.ts +41 -0
  13. package/corpus/templates/content/actions/_local-file-documents.ts +74 -1
  14. package/corpus/templates/content/actions/attach-content-database-source.ts +33 -8
  15. package/corpus/templates/content/actions/change-content-database-source-role.ts +14 -0
  16. package/corpus/templates/content/actions/disconnect-content-database-source.ts +3 -0
  17. package/corpus/templates/content/actions/execute-builder-source-execution.ts +71 -3
  18. package/corpus/templates/content/actions/list-content-databases.ts +41 -33
  19. package/corpus/templates/content/actions/process-builder-body-hydration.ts +47 -0
  20. package/corpus/templates/content/actions/update-document.ts +93 -0
  21. package/corpus/templates/content/app/blocks/SourceComponentBlock.tsx +277 -0
  22. package/corpus/templates/content/app/blocks/contentBlockRegistry.tsx +2 -0
  23. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +45 -4
  24. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +5 -1
  25. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +92 -0
  26. package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +5 -3
  27. package/corpus/templates/content/app/components/editor/extensions/registryBlocks.ts +41 -0
  28. package/corpus/templates/content/app/components/editor/registrySlashItems.ts +4 -0
  29. package/corpus/templates/content/app/global.css +10 -3
  30. package/corpus/templates/content/app/hooks/use-content-database.ts +24 -0
  31. package/corpus/templates/content/app/i18n/zh-TW.ts +24 -0
  32. package/corpus/templates/content/app/i18n-data.ts +212 -0
  33. package/corpus/templates/content/app/lib/content-command-search.ts +64 -0
  34. package/corpus/templates/content/app/root.tsx +236 -8
  35. package/corpus/templates/content/changelog/2026-06-29-builder-cms-sources-now-sync-article-bodies-through-content.md +6 -0
  36. package/corpus/templates/content/changelog/2026-06-30-builder-article-media-now-render-as-images-and-embeds-when-r.md +6 -0
  37. package/corpus/templates/content/changelog/2026-06-30-builder-source-components-now-render-as-preserved-preview-bl.md +6 -0
  38. package/corpus/templates/content/changelog/2026-06-30-cmd-k-search-now-opens-from-the-editor-and-finds-real-content.md +6 -0
  39. package/corpus/templates/content/package.json +3 -1
  40. package/corpus/templates/content/scripts/check-native-deps.mjs +57 -0
  41. package/corpus/templates/content/scripts/dev-database.mjs +83 -0
  42. package/corpus/templates/content/scripts/seed-demo-user.mjs +107 -0
  43. package/corpus/templates/content/server/db/schema.ts +27 -0
  44. package/corpus/templates/content/server/plugins/db.ts +33 -0
  45. package/corpus/templates/content/shared/api.ts +45 -0
  46. package/corpus/templates/content/shared/builder-mdx.ts +905 -5
  47. package/corpus/templates/content/shared/nfm-registry.ts +2 -0
  48. package/corpus/templates/content/shared/source-component-block.ts +141 -0
  49. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +5 -1
  50. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +229 -131
  51. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +103 -6
  52. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +6 -3
  53. package/corpus/templates/design/app/pages/DesignEditor.tsx +382 -72
  54. package/corpus/templates/design/changelog/2026-06-30-canvas-editing-now-keeps-undo-redo-and-cross-screen-layer-mo.md +6 -0
  55. package/dist/client/CommandMenu.d.ts +6 -2
  56. package/dist/client/CommandMenu.d.ts.map +1 -1
  57. package/dist/client/CommandMenu.js +25 -14
  58. package/dist/client/CommandMenu.js.map +1 -1
  59. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  60. package/dist/notifications/routes.d.ts +2 -2
  61. package/dist/observability/routes.d.ts +8 -8
  62. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  63. package/package.json +1 -1
@@ -575,9 +575,11 @@ export function BuilderSourceReviewDialog({
575
575
  <div className="font-medium">
576
576
  {row.bodyChange.summary}
577
577
  </div>
578
- <div className="mt-1 text-muted-foreground">
579
- {t("database.builderBodyEditsNeedSaferPath")}
580
- </div>
578
+ {row.bodyChange.warnings?.length ? (
579
+ <div className="mt-1 text-muted-foreground">
580
+ {row.bodyChange.warnings.join(" ")}
581
+ </div>
582
+ ) : null}
581
583
  </div>
582
584
  ) : null}
583
585
  {showConflict ? (
@@ -1,4 +1,6 @@
1
1
  import { createRegistryBlockNode } from "@agent-native/core/client";
2
+ import { Extension } from "@tiptap/core";
3
+ import { Plugin, PluginKey } from "@tiptap/pm/state";
2
4
 
3
5
  /* -------------------------------------------------------------------------- */
4
6
  /* Content's registry-block Tiptap node — a thin wrapper over the core node. */
@@ -46,4 +48,43 @@ export const RegistryBlockNode = createRegistryBlockNode({
46
48
  mintId: createContentBlockId,
47
49
  });
48
50
 
51
+ function sourceComponentIdCounts(doc: { descendants: (fn: any) => void }) {
52
+ const counts = new Map<string, number>();
53
+ doc.descendants((node: any) => {
54
+ if (
55
+ node.type?.name === "registryBlock" &&
56
+ node.attrs?.blockType === "source-component" &&
57
+ typeof node.attrs.blockId === "string" &&
58
+ node.attrs.blockId
59
+ ) {
60
+ counts.set(node.attrs.blockId, (counts.get(node.attrs.blockId) ?? 0) + 1);
61
+ }
62
+ return true;
63
+ });
64
+ return counts;
65
+ }
66
+
67
+ export const LockedSourceComponentBlocks = Extension.create({
68
+ name: "lockedSourceComponentBlocks",
69
+
70
+ addProseMirrorPlugins() {
71
+ return [
72
+ new Plugin({
73
+ key: new PluginKey("lockedSourceComponentBlocks"),
74
+ filterTransaction(transaction, state) {
75
+ if (!transaction.docChanged) return true;
76
+ const before = sourceComponentIdCounts(state.doc);
77
+ if (before.size === 0) return true;
78
+ const after = sourceComponentIdCounts(transaction.doc);
79
+ if (after.size !== before.size) return false;
80
+ for (const [id, count] of before) {
81
+ if (after.get(id) !== count) return false;
82
+ }
83
+ return true;
84
+ },
85
+ }),
86
+ ];
87
+ },
88
+ });
89
+
49
90
  export default RegistryBlockNode;
@@ -102,6 +102,9 @@ export function buildRegistrySlashItems(
102
102
  // not a content-authoring block.
103
103
  // - `inline-database` is registered in Phase 2 for render/round-trip
104
104
  // compatibility; Phase 3 owns the `/database` insertion flow.
105
+ // - `source-component` is emitted by provider hydration to preserve
106
+ // source-native blocks; users should not author raw preservation
107
+ // markers by hand.
105
108
  // The genuinely document-friendly rich blocks (callout, decision, diagram,
106
109
  // wireframe, and the dev-doc/structured set) ARE offered.
107
110
  includeSpec: (spec) =>
@@ -110,6 +113,7 @@ export function buildRegistrySlashItems(
110
113
  "question-form",
111
114
  "visual-questions",
112
115
  "inline-database",
116
+ "source-component",
113
117
  ].includes(spec.type),
114
118
  toItem: (spec, insert) => ({
115
119
  title: spec.label,
@@ -2298,25 +2298,32 @@ audio.media-block__content {
2298
2298
 
2299
2299
  /* ===== Collaboration cursors ===== */
2300
2300
  .notion-editor .collaboration-cursor__selection {
2301
- background-color: hsl(210 100% 52% / 0.14) !important;
2301
+ background-color: currentColor !important;
2302
2302
  border-radius: 2px;
2303
2303
  box-decoration-break: clone;
2304
2304
  -webkit-box-decoration-break: clone;
2305
+ opacity: 0.16;
2305
2306
  }
2306
2307
 
2307
- .collaboration-cursor__caret {
2308
+ .notion-editor .collaboration-cursor__caret {
2308
2309
  border-left: 2px solid;
2309
2310
  border-color: currentColor;
2311
+ display: inline;
2310
2312
  margin-left: -1px;
2311
2313
  margin-right: -1px;
2312
2314
  position: relative;
2313
2315
  word-break: normal;
2314
2316
  pointer-events: none;
2317
+ line-height: 1;
2315
2318
  }
2316
- .collaboration-cursor__label {
2319
+ .notion-editor .collaboration-cursor__label {
2317
2320
  position: absolute;
2318
2321
  top: -1.4em;
2319
2322
  left: -1px;
2323
+ display: inline-block;
2324
+ max-width: min(180px, 50vw);
2325
+ overflow: hidden;
2326
+ text-overflow: ellipsis;
2320
2327
  font-size: 11px;
2321
2328
  font-weight: 600;
2322
2329
  line-height: 1;
@@ -22,6 +22,8 @@ import type {
22
22
  PrepareBuilderSourceExecutionRequest,
23
23
  PrepareBuilderSourceReviewRequest,
24
24
  PrepareBuilderSourceReviewResponse,
25
+ ProcessBuilderBodyHydrationRequest,
26
+ ProcessBuilderBodyHydrationResponse,
25
27
  RefreshContentDatabaseSourceRequest,
26
28
  ReviewContentDatabaseSourceChangeSetRequest,
27
29
  SetContentDatabaseSourceWriteModeRequest,
@@ -408,6 +410,28 @@ export function useRefreshContentDatabaseSource(documentId: string) {
408
410
  });
409
411
  }
410
412
 
413
+ export function useProcessBuilderBodyHydration(documentId: string) {
414
+ const queryClient = useQueryClient();
415
+ return useActionMutation<
416
+ ProcessBuilderBodyHydrationResponse,
417
+ ProcessBuilderBodyHydrationRequest
418
+ >("process-builder-body-hydration", {
419
+ onSuccess: (_data, variables) => {
420
+ queryClient.invalidateQueries({
421
+ queryKey: contentDatabaseQueryKey(documentId),
422
+ });
423
+ queryClient.invalidateQueries({
424
+ queryKey: ["action", "get-content-database-source", { documentId }],
425
+ });
426
+ if (variables?.documentId) {
427
+ queryClient.invalidateQueries({
428
+ queryKey: ["action", "get-document", { id: variables.documentId }],
429
+ });
430
+ }
431
+ },
432
+ });
433
+ }
434
+
411
435
  export function useDisconnectContentDatabaseSource(documentId: string) {
412
436
  const queryClient = useQueryClient();
413
437
  return useActionMutation<
@@ -2,6 +2,16 @@ const messages = {
2
2
  root: {
3
3
  commandContent: "內容",
4
4
  commandSearchDocuments: "搜尋檔案",
5
+ commandSearchHeading: "搜尋",
6
+ commandSearchPlaceholder: "搜尋文件和資料庫...",
7
+ commandSearchLoading: "搜尋中...",
8
+ commandSearchError: "搜尋目前無法使用。",
9
+ commandSearchPartialError: "部分結果無法載入。",
10
+ commandSearchEmpty: "沒有相符的文件或資料庫。",
11
+ commandDocumentsHeading: "文件",
12
+ commandDatabasesHeading: "資料庫",
13
+ commandLocalFilesHeading: "本機檔案",
14
+ commandDatabaseResultDescription: "開啟資料庫頁面",
5
15
  commandAppearance: "外觀",
6
16
  toggleTheme: "切換主題",
7
17
  metaTitle:
@@ -154,6 +164,14 @@ const messages = {
154
164
  pathMissing: "引用路徑缺失",
155
165
  selfReference: "此引用指向目前文件。",
156
166
  },
167
+ sourceComponent: {
168
+ defaultTitle: "來源元件",
169
+ noPreviewRows: "沒有預覽列",
170
+ previewAvailable: "可預覽",
171
+ previewTruncated: "預覽已截斷",
172
+ previewUnavailable: "無法預覽",
173
+ needsAttention: "需要注意",
174
+ },
157
175
  media: {
158
176
  addAltTextDescription: "新增替代文字來描述該圖片。",
159
177
  addAudio: "新增音訊",
@@ -585,6 +603,11 @@ const messages = {
585
603
  builderSpace: "Builder 空間",
586
604
  builderUpdateFailed: "Builder 更新失敗",
587
605
  builderWriteModeWasNotChanged: "Builder 寫入模式未更改",
606
+ builderBodiesReadyLocally: "Builder 文章正文已在本機準備好。",
607
+ builderBodiesQueued: "{{count}} 個排隊中",
608
+ builderBodySync: "正文同步",
609
+ builderBodySyncFailed: "{{count}} 個失敗",
610
+ builderBodiesHydrated: "已同步 {{hydrated}} / {{total}} 個正文",
588
611
  closeDatabaseSettings: "關閉資料庫設定",
589
612
  closeSearch: "關閉搜尋",
590
613
  databaseRowsAndLocalPropertiesWereKeptIntact: "資料庫行和本機屬性已保留。",
@@ -754,6 +777,7 @@ const messages = {
754
777
  readOnly: "唯讀",
755
778
  removeThisSource: "移除此來源",
756
779
  renameView: "重新命名檢視",
780
+ resume: "繼續",
757
781
  retry: "Retry",
758
782
  reviewBeforeTheyReachBuilder: "在傳送到 Builder 前審核。",
759
783
  reviewDiff: "審核差異",
@@ -28,6 +28,11 @@ const databaseMessages = {
28
28
  builderSpace: "Builder space",
29
29
  builderUpdateFailed: "Builder update failed",
30
30
  builderWriteModeWasNotChanged: "Builder write mode was not changed",
31
+ builderBodiesReadyLocally: "Builder article bodies are ready locally.",
32
+ builderBodiesQueued: "{{count}} queued",
33
+ builderBodySync: "Body sync",
34
+ builderBodySyncFailed: "{{count}} failed",
35
+ builderBodiesHydrated: "{{hydrated}} of {{total}} bodies hydrated",
31
36
  checkingForMatchingFields: "Checking for matching fields...",
32
37
  checkingHowTheseRecordsMatch: "Checking how these records match...",
33
38
  chooseFields: "Choose fields",
@@ -213,6 +218,7 @@ const databaseMessages = {
213
218
  "Recommended when this collection describes existing rows.",
214
219
  removeThisSource: "Remove this source",
215
220
  renameView: "Rename view",
221
+ resume: "Resume",
216
222
  retry: "Retry",
217
223
  reviewBeforeTheyReachBuilder: "Review before they reach Builder.",
218
224
  reviewDiff: "Review diff",
@@ -2141,6 +2147,16 @@ const enUS = {
2141
2147
  root: {
2142
2148
  commandContent: "Content",
2143
2149
  commandSearchDocuments: "Search documents",
2150
+ commandSearchHeading: "Search",
2151
+ commandSearchPlaceholder: "Search documents and databases...",
2152
+ commandSearchLoading: "Searching...",
2153
+ commandSearchError: "Search is unavailable right now.",
2154
+ commandSearchPartialError: "Some results could not load.",
2155
+ commandSearchEmpty: "No matching documents or databases.",
2156
+ commandDocumentsHeading: "Documents",
2157
+ commandDatabasesHeading: "Databases",
2158
+ commandLocalFilesHeading: "Local files",
2159
+ commandDatabaseResultDescription: "Open database page",
2144
2160
  commandAppearance: "Appearance",
2145
2161
  toggleTheme: "Toggle theme",
2146
2162
  metaTitle:
@@ -2299,6 +2315,14 @@ const enUS = {
2299
2315
  pathMissing: "Reference path missing",
2300
2316
  selfReference: "This reference points to the current document.",
2301
2317
  },
2318
+ sourceComponent: {
2319
+ defaultTitle: "Source component",
2320
+ noPreviewRows: "No preview rows",
2321
+ previewAvailable: "Preview available",
2322
+ previewTruncated: "Preview truncated",
2323
+ previewUnavailable: "Preview unavailable",
2324
+ needsAttention: "Needs attention",
2325
+ },
2302
2326
  media: editorMediaMessages,
2303
2327
  properties: editorPropertiesMessages,
2304
2328
  slash: editorSlashMessages,
@@ -7378,11 +7402,23 @@ export const messagesByLocale = {
7378
7402
  database: {
7379
7403
  ...databaseMessagesByLocale["zh-CN"],
7380
7404
  ...databaseExactEnglishMessagesByLocale["zh-CN"],
7405
+ builderBodiesReadyLocally: "Builder 文章正文已在本地准备就绪。",
7406
+ builderBodySync: "正文同步",
7381
7407
  },
7382
7408
  localFiles: localFilesMessagesByLocale["zh-CN"],
7383
7409
  root: {
7384
7410
  commandContent: "内容",
7385
7411
  commandSearchDocuments: "搜索文档",
7412
+ commandSearchHeading: "搜索",
7413
+ commandSearchPlaceholder: "搜索文档和数据库...",
7414
+ commandSearchLoading: "正在搜索...",
7415
+ commandSearchError: "搜索当前不可用。",
7416
+ commandSearchPartialError: "部分结果无法加载。",
7417
+ commandSearchEmpty: "没有匹配的文档或数据库。",
7418
+ commandDocumentsHeading: "文档",
7419
+ commandDatabasesHeading: "数据库",
7420
+ commandLocalFilesHeading: "本地文件",
7421
+ commandDatabaseResultDescription: "打开数据库页面",
7386
7422
  commandAppearance: "外观",
7387
7423
  toggleTheme: "切换主题",
7388
7424
  },
@@ -7430,6 +7466,14 @@ export const messagesByLocale = {
7430
7466
  },
7431
7467
  editor: {
7432
7468
  ...editorMessagesByLocale["zh-CN"],
7469
+ sourceComponent: {
7470
+ defaultTitle: "源组件",
7471
+ noPreviewRows: "没有预览行",
7472
+ previewAvailable: "可预览",
7473
+ previewTruncated: "预览已截断",
7474
+ previewUnavailable: "无法预览",
7475
+ needsAttention: "需要注意",
7476
+ },
7433
7477
  bold: "加粗",
7434
7478
  italic: "斜体",
7435
7479
  strikethrough: "删除线",
@@ -7491,11 +7535,24 @@ export const messagesByLocale = {
7491
7535
  database: {
7492
7536
  ...databaseMessagesByLocale["es-ES"],
7493
7537
  ...databaseExactEnglishMessagesByLocale["es-ES"],
7538
+ builderBodiesReadyLocally:
7539
+ "Los cuerpos de los artículos de Builder están listos localmente.",
7540
+ builderBodySync: "Sincronización del cuerpo",
7494
7541
  },
7495
7542
  localFiles: localFilesMessagesByLocale["es-ES"],
7496
7543
  root: {
7497
7544
  commandContent: "Contenido",
7498
7545
  commandSearchDocuments: "Buscar documentos",
7546
+ commandSearchHeading: "Buscar",
7547
+ commandSearchPlaceholder: "Buscar documentos y bases de datos...",
7548
+ commandSearchLoading: "Buscando...",
7549
+ commandSearchError: "La búsqueda no está disponible ahora.",
7550
+ commandSearchPartialError: "No se pudieron cargar algunos resultados.",
7551
+ commandSearchEmpty: "No hay documentos ni bases de datos coincidentes.",
7552
+ commandDocumentsHeading: "Documentos",
7553
+ commandDatabasesHeading: "Bases de datos",
7554
+ commandLocalFilesHeading: "Archivos locales",
7555
+ commandDatabaseResultDescription: "Abrir página de base de datos",
7499
7556
  commandAppearance: "Apariencia",
7500
7557
  toggleTheme: "Cambiar tema",
7501
7558
  },
@@ -7551,6 +7608,14 @@ export const messagesByLocale = {
7551
7608
  },
7552
7609
  editor: {
7553
7610
  ...editorMessagesByLocale["es-ES"],
7611
+ sourceComponent: {
7612
+ defaultTitle: "Componente de origen",
7613
+ noPreviewRows: "No hay filas de vista previa",
7614
+ previewAvailable: "Vista previa disponible",
7615
+ previewTruncated: "Vista previa truncada",
7616
+ previewUnavailable: "Vista previa no disponible",
7617
+ needsAttention: "Requiere atención",
7618
+ },
7554
7619
  bold: "Negrita",
7555
7620
  italic: "Cursiva",
7556
7621
  strikethrough: "Tachado",
@@ -7614,11 +7679,25 @@ export const messagesByLocale = {
7614
7679
  database: {
7615
7680
  ...databaseMessagesByLocale["fr-FR"],
7616
7681
  ...databaseExactEnglishMessagesByLocale["fr-FR"],
7682
+ builderBodiesReadyLocally:
7683
+ "Les corps d’articles Builder sont prêts localement.",
7684
+ builderBodySync: "Synchronisation du corps",
7617
7685
  },
7618
7686
  localFiles: localFilesMessagesByLocale["fr-FR"],
7619
7687
  root: {
7620
7688
  commandContent: "Contenu",
7621
7689
  commandSearchDocuments: "Rechercher des documents",
7690
+ commandSearchHeading: "Rechercher",
7691
+ commandSearchPlaceholder:
7692
+ "Rechercher des documents et bases de données...",
7693
+ commandSearchLoading: "Recherche...",
7694
+ commandSearchError: "La recherche est indisponible pour le moment.",
7695
+ commandSearchPartialError: "Certains résultats n'ont pas pu se charger.",
7696
+ commandSearchEmpty: "Aucun document ou base de données correspondant.",
7697
+ commandDocumentsHeading: "Documents",
7698
+ commandDatabasesHeading: "Bases de données",
7699
+ commandLocalFilesHeading: "Fichiers locaux",
7700
+ commandDatabaseResultDescription: "Ouvrir la page de base de données",
7622
7701
  commandAppearance: "Apparence",
7623
7702
  toggleTheme: "Changer de thème",
7624
7703
  },
@@ -7677,6 +7756,14 @@ export const messagesByLocale = {
7677
7756
  },
7678
7757
  editor: {
7679
7758
  ...editorMessagesByLocale["fr-FR"],
7759
+ sourceComponent: {
7760
+ defaultTitle: "Composant source",
7761
+ noPreviewRows: "Aucune ligne d’aperçu",
7762
+ previewAvailable: "Aperçu disponible",
7763
+ previewTruncated: "Aperçu tronqué",
7764
+ previewUnavailable: "Aperçu indisponible",
7765
+ needsAttention: "Attention requise",
7766
+ },
7680
7767
  bold: "Gras",
7681
7768
  italic: "Italique",
7682
7769
  strikethrough: "Barré",
@@ -7740,11 +7827,24 @@ export const messagesByLocale = {
7740
7827
  database: {
7741
7828
  ...databaseMessagesByLocale["de-DE"],
7742
7829
  ...databaseExactEnglishMessagesByLocale["de-DE"],
7830
+ builderBodiesReadyLocally: "Builder-Artikelinhalte sind lokal bereit.",
7831
+ builderBodySync: "Inhaltssynchronisierung",
7743
7832
  },
7744
7833
  localFiles: localFilesMessagesByLocale["de-DE"],
7745
7834
  root: {
7746
7835
  commandContent: "Inhalt",
7747
7836
  commandSearchDocuments: "Dokumente suchen",
7837
+ commandSearchHeading: "Suchen",
7838
+ commandSearchPlaceholder: "Dokumente und Datenbanken suchen...",
7839
+ commandSearchLoading: "Suche...",
7840
+ commandSearchError: "Die Suche ist derzeit nicht verfügbar.",
7841
+ commandSearchPartialError:
7842
+ "Einige Ergebnisse konnten nicht geladen werden.",
7843
+ commandSearchEmpty: "Keine passenden Dokumente oder Datenbanken.",
7844
+ commandDocumentsHeading: "Dokumente",
7845
+ commandDatabasesHeading: "Datenbanken",
7846
+ commandLocalFilesHeading: "Lokale Dateien",
7847
+ commandDatabaseResultDescription: "Datenbankseite öffnen",
7748
7848
  commandAppearance: "Darstellung",
7749
7849
  toggleTheme: "Theme wechseln",
7750
7850
  },
@@ -7803,6 +7903,14 @@ export const messagesByLocale = {
7803
7903
  },
7804
7904
  editor: {
7805
7905
  ...editorMessagesByLocale["de-DE"],
7906
+ sourceComponent: {
7907
+ defaultTitle: "Quellkomponente",
7908
+ noPreviewRows: "Keine Vorschauzeilen",
7909
+ previewAvailable: "Vorschau verfügbar",
7910
+ previewTruncated: "Vorschau gekürzt",
7911
+ previewUnavailable: "Vorschau nicht verfügbar",
7912
+ needsAttention: "Aufmerksamkeit erforderlich",
7913
+ },
7806
7914
  bold: "Fett",
7807
7915
  italic: "Kursiv",
7808
7916
  strikethrough: "Durchgestrichen",
@@ -7866,11 +7974,25 @@ export const messagesByLocale = {
7866
7974
  database: {
7867
7975
  ...databaseMessagesByLocale["ja-JP"],
7868
7976
  ...databaseExactEnglishMessagesByLocale["ja-JP"],
7977
+ builderBodiesReadyLocally:
7978
+ "Builder の記事本文はローカルで準備できています。",
7979
+ builderBodySync: "本文同期",
7869
7980
  },
7870
7981
  localFiles: localFilesMessagesByLocale["ja-JP"],
7871
7982
  root: {
7872
7983
  commandContent: "コンテンツ",
7873
7984
  commandSearchDocuments: "ドキュメントを検索",
7985
+ commandSearchHeading: "検索",
7986
+ commandSearchPlaceholder: "ドキュメントとデータベースを検索...",
7987
+ commandSearchLoading: "検索中...",
7988
+ commandSearchError: "現在、検索を利用できません。",
7989
+ commandSearchPartialError: "一部の結果を読み込めませんでした。",
7990
+ commandSearchEmpty:
7991
+ "一致するドキュメントまたはデータベースはありません。",
7992
+ commandDocumentsHeading: "ドキュメント",
7993
+ commandDatabasesHeading: "データベース",
7994
+ commandLocalFilesHeading: "ローカルファイル",
7995
+ commandDatabaseResultDescription: "データベースページを開く",
7874
7996
  commandAppearance: "外観",
7875
7997
  toggleTheme: "テーマを切り替え",
7876
7998
  },
@@ -7926,6 +8048,14 @@ export const messagesByLocale = {
7926
8048
  },
7927
8049
  editor: {
7928
8050
  ...editorMessagesByLocale["ja-JP"],
8051
+ sourceComponent: {
8052
+ defaultTitle: "ソースコンポーネント",
8053
+ noPreviewRows: "プレビュー行はありません",
8054
+ previewAvailable: "プレビュー可能",
8055
+ previewTruncated: "プレビューは切り詰められました",
8056
+ previewUnavailable: "プレビューできません",
8057
+ needsAttention: "確認が必要",
8058
+ },
7929
8059
  bold: "太字",
7930
8060
  italic: "斜体",
7931
8061
  strikethrough: "取り消し線",
@@ -7988,11 +8118,23 @@ export const messagesByLocale = {
7988
8118
  database: {
7989
8119
  ...databaseMessagesByLocale["ko-KR"],
7990
8120
  ...databaseExactEnglishMessagesByLocale["ko-KR"],
8121
+ builderBodiesReadyLocally: "Builder 문서 본문이 로컬에서 준비되었습니다.",
8122
+ builderBodySync: "본문 동기화",
7991
8123
  },
7992
8124
  localFiles: localFilesMessagesByLocale["ko-KR"],
7993
8125
  root: {
7994
8126
  commandContent: "콘텐츠",
7995
8127
  commandSearchDocuments: "문서 검색",
8128
+ commandSearchHeading: "검색",
8129
+ commandSearchPlaceholder: "문서와 데이터베이스 검색...",
8130
+ commandSearchLoading: "검색 중...",
8131
+ commandSearchError: "지금은 검색을 사용할 수 없습니다.",
8132
+ commandSearchPartialError: "일부 결과를 불러오지 못했습니다.",
8133
+ commandSearchEmpty: "일치하는 문서나 데이터베이스가 없습니다.",
8134
+ commandDocumentsHeading: "문서",
8135
+ commandDatabasesHeading: "데이터베이스",
8136
+ commandLocalFilesHeading: "로컬 파일",
8137
+ commandDatabaseResultDescription: "데이터베이스 페이지 열기",
7996
8138
  commandAppearance: "모양",
7997
8139
  toggleTheme: "테마 전환",
7998
8140
  },
@@ -8042,6 +8184,14 @@ export const messagesByLocale = {
8042
8184
  },
8043
8185
  editor: {
8044
8186
  ...editorMessagesByLocale["ko-KR"],
8187
+ sourceComponent: {
8188
+ defaultTitle: "소스 컴포넌트",
8189
+ noPreviewRows: "미리보기 행 없음",
8190
+ previewAvailable: "미리보기 가능",
8191
+ previewTruncated: "미리보기 잘림",
8192
+ previewUnavailable: "미리보기 불가",
8193
+ needsAttention: "주의 필요",
8194
+ },
8045
8195
  bold: "굵게",
8046
8196
  italic: "기울임",
8047
8197
  strikethrough: "취소선",
@@ -8103,11 +8253,25 @@ export const messagesByLocale = {
8103
8253
  database: {
8104
8254
  ...databaseMessagesByLocale["pt-BR"],
8105
8255
  ...databaseExactEnglishMessagesByLocale["pt-BR"],
8256
+ builderBodiesReadyLocally:
8257
+ "Os corpos dos artigos do Builder estão prontos localmente.",
8258
+ builderBodySync: "Sincronização do corpo",
8106
8259
  },
8107
8260
  localFiles: localFilesMessagesByLocale["pt-BR"],
8108
8261
  root: {
8109
8262
  commandContent: "Conteúdo",
8110
8263
  commandSearchDocuments: "Buscar documentos",
8264
+ commandSearchHeading: "Buscar",
8265
+ commandSearchPlaceholder: "Buscar documentos e bancos de dados...",
8266
+ commandSearchLoading: "Buscando...",
8267
+ commandSearchError: "A busca não está disponível agora.",
8268
+ commandSearchPartialError:
8269
+ "Alguns resultados não puderam ser carregados.",
8270
+ commandSearchEmpty: "Nenhum documento ou banco de dados correspondente.",
8271
+ commandDocumentsHeading: "Documentos",
8272
+ commandDatabasesHeading: "Bancos de dados",
8273
+ commandLocalFilesHeading: "Arquivos locais",
8274
+ commandDatabaseResultDescription: "Abrir página do banco de dados",
8111
8275
  commandAppearance: "Aparência",
8112
8276
  toggleTheme: "Alternar tema",
8113
8277
  },
@@ -8166,6 +8330,14 @@ export const messagesByLocale = {
8166
8330
  },
8167
8331
  editor: {
8168
8332
  ...editorMessagesByLocale["pt-BR"],
8333
+ sourceComponent: {
8334
+ defaultTitle: "Componente de origem",
8335
+ noPreviewRows: "Sem linhas de prévia",
8336
+ previewAvailable: "Prévia disponível",
8337
+ previewTruncated: "Prévia truncada",
8338
+ previewUnavailable: "Prévia indisponível",
8339
+ needsAttention: "Requer atenção",
8340
+ },
8169
8341
  bold: "Negrito",
8170
8342
  italic: "Itálico",
8171
8343
  strikethrough: "Tachado",
@@ -8228,11 +8400,23 @@ export const messagesByLocale = {
8228
8400
  database: {
8229
8401
  ...databaseMessagesByLocale["hi-IN"],
8230
8402
  ...databaseExactEnglishMessagesByLocale["hi-IN"],
8403
+ builderBodiesReadyLocally: "Builder लेखों की बॉडी स्थानीय रूप से तैयार है।",
8404
+ builderBodySync: "बॉडी सिंक",
8231
8405
  },
8232
8406
  localFiles: localFilesMessagesByLocale["hi-IN"],
8233
8407
  root: {
8234
8408
  commandContent: "कॉन्टेंट",
8235
8409
  commandSearchDocuments: "दस्तावेज़ खोजें",
8410
+ commandSearchHeading: "खोजें",
8411
+ commandSearchPlaceholder: "दस्तावेज़ और डेटाबेस खोजें...",
8412
+ commandSearchLoading: "खोजा जा रहा है...",
8413
+ commandSearchError: "खोज अभी उपलब्ध नहीं है।",
8414
+ commandSearchPartialError: "कुछ परिणाम लोड नहीं हो सके।",
8415
+ commandSearchEmpty: "कोई मिलता-जुलता दस्तावेज़ या डेटाबेस नहीं मिला।",
8416
+ commandDocumentsHeading: "दस्तावेज़",
8417
+ commandDatabasesHeading: "डेटाबेस",
8418
+ commandLocalFilesHeading: "स्थानीय फ़ाइलें",
8419
+ commandDatabaseResultDescription: "डेटाबेस पेज खोलें",
8236
8420
  commandAppearance: "रूप",
8237
8421
  toggleTheme: "थीम बदलें",
8238
8422
  },
@@ -8281,6 +8465,14 @@ export const messagesByLocale = {
8281
8465
  },
8282
8466
  editor: {
8283
8467
  ...editorMessagesByLocale["hi-IN"],
8468
+ sourceComponent: {
8469
+ defaultTitle: "स्रोत कंपोनेंट",
8470
+ noPreviewRows: "कोई पूर्वावलोकन पंक्ति नहीं",
8471
+ previewAvailable: "पूर्वावलोकन उपलब्ध है",
8472
+ previewTruncated: "पूर्वावलोकन छोटा किया गया",
8473
+ previewUnavailable: "पूर्वावलोकन उपलब्ध नहीं",
8474
+ needsAttention: "ध्यान चाहिए",
8475
+ },
8284
8476
  bold: "बोल्ड",
8285
8477
  italic: "इटैलिक",
8286
8478
  strikethrough: "स्ट्राइकथ्रू",
@@ -8342,11 +8534,23 @@ export const messagesByLocale = {
8342
8534
  database: {
8343
8535
  ...databaseMessagesByLocale["ar-SA"],
8344
8536
  ...databaseExactEnglishMessagesByLocale["ar-SA"],
8537
+ builderBodiesReadyLocally: "أصبحت نصوص مقالات Builder جاهزة محليًا.",
8538
+ builderBodySync: "مزامنة النص",
8345
8539
  },
8346
8540
  localFiles: localFilesMessagesByLocale["ar-SA"],
8347
8541
  root: {
8348
8542
  commandContent: "المحتوى",
8349
8543
  commandSearchDocuments: "بحث في المستندات",
8544
+ commandSearchHeading: "بحث",
8545
+ commandSearchPlaceholder: "ابحث في المستندات وقواعد البيانات...",
8546
+ commandSearchLoading: "جارٍ البحث...",
8547
+ commandSearchError: "البحث غير متاح الآن.",
8548
+ commandSearchPartialError: "تعذر تحميل بعض النتائج.",
8549
+ commandSearchEmpty: "لا توجد مستندات أو قواعد بيانات مطابقة.",
8550
+ commandDocumentsHeading: "المستندات",
8551
+ commandDatabasesHeading: "قواعد البيانات",
8552
+ commandLocalFilesHeading: "الملفات المحلية",
8553
+ commandDatabaseResultDescription: "فتح صفحة قاعدة البيانات",
8350
8554
  commandAppearance: "المظهر",
8351
8555
  toggleTheme: "تبديل السمة",
8352
8556
  },
@@ -8399,6 +8603,14 @@ export const messagesByLocale = {
8399
8603
  },
8400
8604
  editor: {
8401
8605
  ...editorMessagesByLocale["ar-SA"],
8606
+ sourceComponent: {
8607
+ defaultTitle: "مكوّن المصدر",
8608
+ noPreviewRows: "لا توجد صفوف معاينة",
8609
+ previewAvailable: "المعاينة متاحة",
8610
+ previewTruncated: "تم اقتطاع المعاينة",
8611
+ previewUnavailable: "المعاينة غير متاحة",
8612
+ needsAttention: "يحتاج إلى انتباه",
8613
+ },
8402
8614
  bold: "غامق",
8403
8615
  italic: "مائل",
8404
8616
  strikethrough: "يتوسطه خط",
@@ -0,0 +1,64 @@
1
+ import type { ContentDatabaseSummary } from "@shared/api";
2
+
3
+ export interface CommandSearchDocumentResult {
4
+ id: string;
5
+ parentId: string | null;
6
+ title: string;
7
+ icon: string | null;
8
+ snippet: string;
9
+ contentLength: number;
10
+ hideFromSearch: boolean;
11
+ updatedAt: string;
12
+ }
13
+
14
+ export interface CommandSearchDocumentsResponse {
15
+ documents: CommandSearchDocumentResult[];
16
+ }
17
+
18
+ export interface ContentCommandSearchGroups {
19
+ documents: CommandSearchDocumentResult[];
20
+ databases: ContentDatabaseSummary[];
21
+ localFiles: CommandSearchDocumentResult[];
22
+ }
23
+
24
+ export function isLocalFileSearchResult(
25
+ document: Pick<CommandSearchDocumentResult, "id">,
26
+ ) {
27
+ return (
28
+ document.id.startsWith("local-file:") ||
29
+ document.id.startsWith("local-folder:")
30
+ );
31
+ }
32
+
33
+ export function contentCommandDocumentPath(documentId: string) {
34
+ return `/page/${documentId}`;
35
+ }
36
+
37
+ export function groupContentCommandSearchResults(args: {
38
+ documents: CommandSearchDocumentResult[];
39
+ databases: ContentDatabaseSummary[];
40
+ query: string;
41
+ }): ContentCommandSearchGroups {
42
+ const needle = args.query.trim().toLowerCase();
43
+ const visibleDocuments = args.documents.filter(
44
+ (document) => !document.hideFromSearch,
45
+ );
46
+ const matchingDatabases = needle
47
+ ? args.databases
48
+ .filter((database) => database.title.toLowerCase().includes(needle))
49
+ .slice(0, 6)
50
+ : [];
51
+ const databaseDocumentIds = new Set(
52
+ matchingDatabases.map((database) => database.documentId),
53
+ );
54
+
55
+ return {
56
+ documents: visibleDocuments.filter(
57
+ (document) =>
58
+ !isLocalFileSearchResult(document) &&
59
+ !databaseDocumentIds.has(document.id),
60
+ ),
61
+ databases: matchingDatabases,
62
+ localFiles: visibleDocuments.filter(isLocalFileSearchResult),
63
+ };
64
+ }