@agent-native/core 0.101.7 → 0.101.11

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 (219) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +28 -0
  3. package/corpus/core/docs/content/deployment.mdx +9 -7
  4. package/corpus/core/docs/content/locales/ar-SA/deployment.mdx +9 -7
  5. package/corpus/core/docs/content/locales/de-DE/deployment.mdx +9 -7
  6. package/corpus/core/docs/content/locales/es-ES/deployment.mdx +9 -7
  7. package/corpus/core/docs/content/locales/fr-FR/deployment.mdx +9 -7
  8. package/corpus/core/docs/content/locales/hi-IN/deployment.mdx +9 -7
  9. package/corpus/core/docs/content/locales/ja-JP/deployment.mdx +9 -7
  10. package/corpus/core/docs/content/locales/ko-KR/deployment.mdx +9 -7
  11. package/corpus/core/docs/content/locales/pt-BR/deployment.mdx +9 -7
  12. package/corpus/core/docs/content/locales/zh-CN/deployment.mdx +9 -7
  13. package/corpus/core/docs/content/locales/zh-TW/deployment.mdx +9 -7
  14. package/corpus/core/package.json +1 -1
  15. package/corpus/core/src/a2a/client.ts +23 -1
  16. package/corpus/core/src/a2a/handlers.ts +65 -1
  17. package/corpus/core/src/a2a/server.ts +124 -0
  18. package/corpus/core/src/a2a/task-store.ts +253 -0
  19. package/corpus/core/src/a2a/types.ts +26 -0
  20. package/corpus/core/src/agent/production-agent.ts +5 -2
  21. package/corpus/core/src/client/review/ReviewCommentComposer.tsx +9 -1
  22. package/corpus/core/src/client/review/ReviewThreadPanel.tsx +17 -2
  23. package/corpus/core/src/client/settings/SettingsPanel.tsx +41 -21
  24. package/corpus/core/src/client/settings/useBuilderStatus.ts +28 -9
  25. package/corpus/core/src/client/setup-connections/BuilderConnectCard.tsx +2 -7
  26. package/corpus/core/src/mcp/builtin-tools.ts +25 -1
  27. package/corpus/core/src/scripts/call-agent.ts +22 -3
  28. package/corpus/core/src/server/agent-chat-plugin.ts +86 -1
  29. package/corpus/core/src/server/auth.ts +25 -1
  30. package/corpus/core/src/server/builder-browser.ts +353 -1
  31. package/corpus/core/src/server/core-routes-plugin.ts +601 -223
  32. package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +25 -0
  33. package/corpus/templates/calendar/app/components/calendar/DayView.tsx +80 -1
  34. package/corpus/templates/calendar/app/components/calendar/EventCard.tsx +28 -3
  35. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +5 -1
  36. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +30 -3
  37. package/corpus/templates/calendar/app/components/calendar/OutOfOfficeEvent.tsx +196 -0
  38. package/corpus/templates/calendar/app/components/calendar/WeekView.tsx +115 -1
  39. package/corpus/templates/calendar/app/lib/out-of-office.ts +45 -0
  40. package/corpus/templates/calendar/changelog/2026-07-14-out-of-office-blocks-now-sit-behind-meetings-and-event-stack.md +6 -0
  41. package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +23 -0
  42. package/corpus/templates/content/AGENTS.md +3 -2
  43. package/corpus/templates/content/actions/_builder-cms-intent-lookup.ts +87 -0
  44. package/corpus/templates/content/actions/_builder-cms-read-client.ts +173 -25
  45. package/corpus/templates/content/actions/_builder-cms-source-adapter.ts +1 -0
  46. package/corpus/templates/content/actions/_builder-cms-write-adapter.ts +427 -18
  47. package/corpus/templates/content/actions/_builder-cms-write-client.ts +17 -73
  48. package/corpus/templates/content/actions/_builder-cms-write-settings.ts +27 -7
  49. package/corpus/templates/content/actions/_builder-source-execution-claim.ts +124 -0
  50. package/corpus/templates/content/actions/_builder-source-execution-preservation.ts +21 -0
  51. package/corpus/templates/content/actions/_builder-source-timings.ts +57 -0
  52. package/corpus/templates/content/actions/_database-source-utils.ts +1041 -154
  53. package/corpus/templates/content/actions/_database-utils.ts +89 -12
  54. package/corpus/templates/content/actions/_preview-document-draft.ts +31 -0
  55. package/corpus/templates/content/actions/cancel-prepared-builder-source-update.ts +309 -0
  56. package/corpus/templates/content/actions/execute-builder-source-batch.ts +120 -49
  57. package/corpus/templates/content/actions/execute-builder-source-execution.ts +608 -264
  58. package/corpus/templates/content/actions/get-preview-document-draft.ts +26 -0
  59. package/corpus/templates/content/actions/materialize-builder-required-fields.ts +550 -0
  60. package/corpus/templates/content/actions/prepare-builder-source-execution.ts +112 -65
  61. package/corpus/templates/content/actions/prepare-builder-source-review.ts +463 -170
  62. package/corpus/templates/content/actions/preview-builder-source-review.ts +99 -0
  63. package/corpus/templates/content/actions/set-content-database-source-write-mode.ts +2 -2
  64. package/corpus/templates/content/actions/update-preview-document-draft.ts +153 -0
  65. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +27 -15
  66. package/corpus/templates/content/app/components/editor/MathRenderer.tsx +43 -0
  67. package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +260 -4
  68. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +57 -5
  69. package/corpus/templates/content/app/components/editor/body-hydration.ts +27 -0
  70. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +2353 -576
  71. package/corpus/templates/content/app/components/editor/database/settings.tsx +13 -10
  72. package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +358 -75
  73. package/corpus/templates/content/app/components/editor/extensions/NotionExtensions.tsx +78 -0
  74. package/corpus/templates/content/app/components/editor/previewDocumentSaveController.ts +124 -29
  75. package/corpus/templates/content/app/components/editor/previewDocumentSaveRegistry.ts +2 -0
  76. package/corpus/templates/content/app/global.css +71 -1
  77. package/corpus/templates/content/app/hooks/use-content-database.ts +68 -0
  78. package/corpus/templates/content/app/hooks/use-documents.ts +53 -4
  79. package/corpus/templates/content/app/i18n/zh-TW.ts +38 -0
  80. package/corpus/templates/content/app/i18n-data.ts +450 -0
  81. package/corpus/templates/content/app/root.tsx +2 -0
  82. package/corpus/templates/content/changelog/2026-07-10-builder-backed-preview-edits-are-preserved-when-article-bodi.md +6 -0
  83. package/corpus/templates/content/changelog/2026-07-10-builder-cms-sources-can-now-be-enabled-for-guarded-staged-or.md +6 -0
  84. package/corpus/templates/content/changelog/2026-07-13-builder-connection-setup-is-now-available-directly-from-conn.md +6 -0
  85. package/corpus/templates/content/changelog/2026-07-13-builder-reviews-now-hide-already-applied-writes-detect-nativ.md +6 -0
  86. package/corpus/templates/content/changelog/2026-07-13-required-builder-publishing-fields-can-now-be-added-directly.md +6 -0
  87. package/corpus/templates/content/changelog/2026-07-13-you-can-now-cancel-a-prepared-builder-update-safely-before-i.md +6 -0
  88. package/corpus/templates/content/changelog/2026-07-14-builder-account-connection-now-remains-available-when-branch.md +6 -0
  89. package/corpus/templates/content/changelog/2026-07-14-builder-backed-articles-now-preserve-fifth-and-sixth-level-h.md +6 -0
  90. package/corpus/templates/content/changelog/2026-07-14-builder-sources-now-review-and-publish-rich-article-updates-.md +6 -0
  91. package/corpus/templates/content/changelog/2026-07-14-builder-writes-now-stop-retries-when-reconciliation-is-needed.md +6 -0
  92. package/corpus/templates/content/changelog/2026-07-14-file-and-media-links-now-validate-before-saving.md +6 -0
  93. package/corpus/templates/content/changelog/2026-07-14-latex-equations-render-in-documents-public-pages-and-exports.md +6 -0
  94. package/corpus/templates/content/package.json +1 -0
  95. package/corpus/templates/content/parity/matrix.md +27 -25
  96. package/corpus/templates/content/parity/matrix.ts +50 -2
  97. package/corpus/templates/content/server/db/schema.ts +47 -0
  98. package/corpus/templates/content/server/plugins/auth.ts +1 -0
  99. package/corpus/templates/content/server/plugins/db.ts +53 -0
  100. package/corpus/templates/content/shared/api.ts +70 -1
  101. package/corpus/templates/content/shared/builder-mdx.ts +705 -15
  102. package/corpus/templates/content/shared/document-export.ts +296 -25
  103. package/corpus/templates/content/shared/inline-math.ts +128 -0
  104. package/corpus/templates/content/shared/math-rendering.ts +50 -0
  105. package/corpus/templates/content/shared/nfm.ts +20 -17
  106. package/corpus/templates/content/vite.config.ts +0 -1
  107. package/corpus/templates/design/app/components/design/ReadOnlyDesignBanner.tsx +52 -7
  108. package/corpus/templates/design/app/components/design/ReviewCommentsPanel.tsx +36 -4
  109. package/corpus/templates/design/app/components/visual-editor/ReviewCanvasPins.tsx +4 -1
  110. package/corpus/templates/design/app/i18n/ar-SA.ts +1 -0
  111. package/corpus/templates/design/app/i18n/de-DE.ts +1 -0
  112. package/corpus/templates/design/app/i18n/en-US.ts +1 -0
  113. package/corpus/templates/design/app/i18n/es-ES.ts +1 -0
  114. package/corpus/templates/design/app/i18n/fr-FR.ts +1 -0
  115. package/corpus/templates/design/app/i18n/hi-IN.ts +1 -0
  116. package/corpus/templates/design/app/i18n/ja-JP.ts +1 -0
  117. package/corpus/templates/design/app/i18n/ko-KR.ts +1 -0
  118. package/corpus/templates/design/app/i18n/pt-BR.ts +1 -0
  119. package/corpus/templates/design/app/i18n/zh-CN.ts +1 -0
  120. package/corpus/templates/design/app/i18n/zh-TW.ts +1 -0
  121. package/corpus/templates/design/app/pages/design-editor/selection-state.ts +8 -0
  122. package/corpus/templates/design/app/pages/design-editor/tool-state.ts +11 -0
  123. package/corpus/templates/design/changelog/2026-07-14-reviewers-can-now-pin-comments-from-the-canvas-toolbar-targe.md +6 -0
  124. package/corpus/templates/design/changelog/2026-07-15-viewer-comment-controls-now-sit-inside-the-read-only-notice-.md +6 -0
  125. package/corpus/templates/design/shared/review-anchor.ts +48 -0
  126. package/corpus/templates/mail/.agents/skills/email-drafts/SKILL.md +17 -0
  127. package/corpus/templates/mail/AGENTS.md +21 -19
  128. package/corpus/templates/mail/actions/create-attachment-upload.ts +49 -0
  129. package/corpus/templates/mail/changelog/2026-07-14-connected-agents-can-now-securely-upload-local-files-for-mai.md +6 -0
  130. package/corpus/templates/mail/server/handlers/media.ts +84 -61
  131. package/corpus/templates/mail/server/lib/attachment-upload-ticket.ts +234 -0
  132. package/corpus/templates/mail/server/lib/mail-connector-catalog.ts +8 -4
  133. package/corpus/templates/mail/server/lib/media-upload.ts +114 -0
  134. package/corpus/templates/mail/server/plugins/auth.ts +9 -1
  135. package/corpus/templates/mail/server/routes/api/media/attachment-upload/[uploadId].put.ts +1 -0
  136. package/corpus/templates/plan/server/plan-mdx.ts +53 -7
  137. package/dist/a2a/client.d.ts +5 -1
  138. package/dist/a2a/client.d.ts.map +1 -1
  139. package/dist/a2a/client.js +18 -1
  140. package/dist/a2a/client.js.map +1 -1
  141. package/dist/a2a/handlers.d.ts.map +1 -1
  142. package/dist/a2a/handlers.js +57 -8
  143. package/dist/a2a/handlers.js.map +1 -1
  144. package/dist/a2a/server.d.ts.map +1 -1
  145. package/dist/a2a/server.js +87 -1
  146. package/dist/a2a/server.js.map +1 -1
  147. package/dist/a2a/task-store.d.ts +27 -0
  148. package/dist/a2a/task-store.d.ts.map +1 -1
  149. package/dist/a2a/task-store.js +216 -0
  150. package/dist/a2a/task-store.js.map +1 -1
  151. package/dist/a2a/types.d.ts +24 -0
  152. package/dist/a2a/types.d.ts.map +1 -1
  153. package/dist/a2a/types.js.map +1 -1
  154. package/dist/agent/production-agent.d.ts +1 -0
  155. package/dist/agent/production-agent.d.ts.map +1 -1
  156. package/dist/agent/production-agent.js +5 -2
  157. package/dist/agent/production-agent.js.map +1 -1
  158. package/dist/client/review/ReviewCommentComposer.d.ts +2 -1
  159. package/dist/client/review/ReviewCommentComposer.d.ts.map +1 -1
  160. package/dist/client/review/ReviewCommentComposer.js +3 -3
  161. package/dist/client/review/ReviewCommentComposer.js.map +1 -1
  162. package/dist/client/review/ReviewThreadPanel.d.ts +9 -1
  163. package/dist/client/review/ReviewThreadPanel.d.ts.map +1 -1
  164. package/dist/client/review/ReviewThreadPanel.js +6 -4
  165. package/dist/client/review/ReviewThreadPanel.js.map +1 -1
  166. package/dist/client/settings/SettingsPanel.d.ts +3 -0
  167. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  168. package/dist/client/settings/SettingsPanel.js +11 -4
  169. package/dist/client/settings/SettingsPanel.js.map +1 -1
  170. package/dist/client/settings/useBuilderStatus.d.ts +8 -4
  171. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  172. package/dist/client/settings/useBuilderStatus.js +19 -6
  173. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  174. package/dist/client/setup-connections/BuilderConnectCard.d.ts.map +1 -1
  175. package/dist/client/setup-connections/BuilderConnectCard.js +2 -5
  176. package/dist/client/setup-connections/BuilderConnectCard.js.map +1 -1
  177. package/dist/collab/awareness.d.ts +2 -2
  178. package/dist/collab/awareness.d.ts.map +1 -1
  179. package/dist/collab/struct-routes.d.ts +1 -1
  180. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  181. package/dist/mcp/builtin-tools.d.ts.map +1 -1
  182. package/dist/mcp/builtin-tools.js +22 -3
  183. package/dist/mcp/builtin-tools.js.map +1 -1
  184. package/dist/notifications/routes.d.ts +3 -3
  185. package/dist/resources/handlers.d.ts +2 -2
  186. package/dist/scripts/call-agent.d.ts +1 -1
  187. package/dist/scripts/call-agent.d.ts.map +1 -1
  188. package/dist/scripts/call-agent.js +19 -1
  189. package/dist/scripts/call-agent.js.map +1 -1
  190. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  191. package/dist/server/agent-chat-plugin.js +71 -2
  192. package/dist/server/agent-chat-plugin.js.map +1 -1
  193. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  194. package/dist/server/auth.d.ts +1 -0
  195. package/dist/server/auth.d.ts.map +1 -1
  196. package/dist/server/auth.js +19 -2
  197. package/dist/server/auth.js.map +1 -1
  198. package/dist/server/builder-browser.d.ts +78 -0
  199. package/dist/server/builder-browser.d.ts.map +1 -1
  200. package/dist/server/builder-browser.js +246 -1
  201. package/dist/server/builder-browser.js.map +1 -1
  202. package/dist/server/core-routes-plugin.d.ts +41 -0
  203. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  204. package/dist/server/core-routes-plugin.js +260 -14
  205. package/dist/server/core-routes-plugin.js.map +1 -1
  206. package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +25 -0
  207. package/docs/content/deployment.mdx +9 -7
  208. package/docs/content/locales/ar-SA/deployment.mdx +9 -7
  209. package/docs/content/locales/de-DE/deployment.mdx +9 -7
  210. package/docs/content/locales/es-ES/deployment.mdx +9 -7
  211. package/docs/content/locales/fr-FR/deployment.mdx +9 -7
  212. package/docs/content/locales/hi-IN/deployment.mdx +9 -7
  213. package/docs/content/locales/ja-JP/deployment.mdx +9 -7
  214. package/docs/content/locales/ko-KR/deployment.mdx +9 -7
  215. package/docs/content/locales/pt-BR/deployment.mdx +9 -7
  216. package/docs/content/locales/zh-CN/deployment.mdx +9 -7
  217. package/docs/content/locales/zh-TW/deployment.mdx +9 -7
  218. package/package.json +2 -2
  219. package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +25 -0
@@ -44,6 +44,111 @@ export interface BuilderCmsEntryLiveState {
44
44
  id: string | null;
45
45
  }
46
46
 
47
+ export interface BuilderCmsEntryFidelitySummary {
48
+ topLevelBlockCount: number;
49
+ componentCount: number;
50
+ textBlockCount: number;
51
+ imageBlockCount: number;
52
+ htmlImageCount: number;
53
+ markdownImageSyntaxCount: number;
54
+ videoBlockCount: number;
55
+ headingCount: number;
56
+ unorderedListCount: number;
57
+ orderedListCount: number;
58
+ listItemCount: number;
59
+ linkCount: number;
60
+ tableCount: number;
61
+ escapedTableMarkupCount: number;
62
+ codeCount: number;
63
+ blockquoteCount: number;
64
+ escapedBlockquoteMarkupCount: number;
65
+ hasYouTubeLink: boolean;
66
+ }
67
+
68
+ function countMatches(value: string, pattern: RegExp) {
69
+ return value.match(pattern)?.length ?? 0;
70
+ }
71
+
72
+ export function summarizeBuilderCmsEntryFidelity(
73
+ entry: BuilderCmsSourceEntry,
74
+ ): BuilderCmsEntryFidelitySummary {
75
+ const blocks = entry.rawEntry ? builderEntryBlocks(entry.rawEntry) : [];
76
+ const summary: BuilderCmsEntryFidelitySummary = {
77
+ topLevelBlockCount: blocks.length,
78
+ componentCount: 0,
79
+ textBlockCount: 0,
80
+ imageBlockCount: 0,
81
+ htmlImageCount: 0,
82
+ markdownImageSyntaxCount: 0,
83
+ videoBlockCount: 0,
84
+ headingCount: 0,
85
+ unorderedListCount: 0,
86
+ orderedListCount: 0,
87
+ listItemCount: 0,
88
+ linkCount: 0,
89
+ tableCount: 0,
90
+ escapedTableMarkupCount: 0,
91
+ codeCount: 0,
92
+ blockquoteCount: 0,
93
+ escapedBlockquoteMarkupCount: 0,
94
+ hasYouTubeLink: false,
95
+ };
96
+ const visit = (value: unknown) => {
97
+ if (!value || typeof value !== "object") return;
98
+ if (Array.isArray(value)) {
99
+ for (const child of value) visit(child);
100
+ return;
101
+ }
102
+ const record = value as Record<string, unknown>;
103
+ const component =
104
+ record.component &&
105
+ typeof record.component === "object" &&
106
+ !Array.isArray(record.component)
107
+ ? (record.component as Record<string, unknown>)
108
+ : null;
109
+ if (component) {
110
+ summary.componentCount += 1;
111
+ const name = typeof component.name === "string" ? component.name : "";
112
+ if (name === "Image") summary.imageBlockCount += 1;
113
+ if (name === "Video") summary.videoBlockCount += 1;
114
+ if (name === "Text") {
115
+ summary.textBlockCount += 1;
116
+ const options =
117
+ component.options &&
118
+ typeof component.options === "object" &&
119
+ !Array.isArray(component.options)
120
+ ? (component.options as Record<string, unknown>)
121
+ : {};
122
+ const html = typeof options.text === "string" ? options.text : "";
123
+ summary.headingCount += countMatches(html, /<h[1-6]\b/gi);
124
+ summary.htmlImageCount += countMatches(html, /<img\b/gi);
125
+ summary.markdownImageSyntaxCount += countMatches(
126
+ html,
127
+ /!\[[^\]]*\]\(/g,
128
+ );
129
+ summary.unorderedListCount += countMatches(html, /<ul\b/gi);
130
+ summary.orderedListCount += countMatches(html, /<ol\b/gi);
131
+ summary.listItemCount += countMatches(html, /<li\b/gi);
132
+ summary.linkCount += countMatches(html, /<a\b/gi);
133
+ summary.tableCount += countMatches(html, /<table\b/gi);
134
+ summary.escapedTableMarkupCount += countMatches(html, /&lt;table\b/gi);
135
+ summary.codeCount += countMatches(html, /<code\b/gi);
136
+ summary.blockquoteCount += countMatches(html, /<blockquote\b/gi);
137
+ summary.escapedBlockquoteMarkupCount += countMatches(
138
+ html,
139
+ /&lt;blockquote\b/gi,
140
+ );
141
+ if (/youtube\.com|youtu\.be/i.test(html)) {
142
+ summary.hasYouTubeLink = true;
143
+ }
144
+ }
145
+ }
146
+ for (const child of Object.values(record)) visit(child);
147
+ };
148
+ visit(blocks);
149
+ return summary;
150
+ }
151
+
47
152
  type FetchLike = typeof fetch;
48
153
 
49
154
  type BuilderMcpContentPart = {
@@ -129,6 +234,15 @@ export function builderCmsListEntryFields(fieldPaths: readonly string[] = []) {
129
234
  const BUILDER_CMS_METADATA_ENTRY_FIELDS = builderCmsListEntryFields();
130
235
  const BUILDER_CMS_BODY_ENTRY_FIELDS = `${BUILDER_CMS_METADATA_ENTRY_FIELDS},${BUILDER_CMS_HEAVY_BODY_FIELD_PATHS.join(",")}`;
131
236
 
237
+ function applyBuilderCmsBodyEntryReadParams(url: URL, publicKey: string) {
238
+ url.searchParams.set("apiKey", publicKey);
239
+ url.searchParams.set("includeUnpublished", "true");
240
+ url.searchParams.set("enrich", "true");
241
+ url.searchParams.set("noCache", "true");
242
+ url.searchParams.set("cachebust", String(Date.now()));
243
+ url.searchParams.set("fields", BUILDER_CMS_BODY_ENTRY_FIELDS);
244
+ }
245
+
132
246
  function builderContentApiHost() {
133
247
  return (
134
248
  process.env.BUILDER_CONTENT_API_HOST ??
@@ -250,13 +364,14 @@ function sleep(ms: number) {
250
364
  async function fetchBuilderContentPage(args: {
251
365
  fetchImpl: FetchLike;
252
366
  url: URL;
367
+ privateKey?: string;
253
368
  }): Promise<Response> {
254
369
  let lastError: unknown = null;
255
370
  for (let attempt = 0; attempt <= BUILDER_CMS_READ_RETRIES; attempt += 1) {
256
371
  try {
257
- const response = await args.fetchImpl(args.url, {
258
- headers: { accept: "application/json" },
259
- });
372
+ const headers: Record<string, string> = { accept: "application/json" };
373
+ if (args.privateKey) headers.authorization = `Bearer ${args.privateKey}`;
374
+ const response = await args.fetchImpl(args.url, { headers });
260
375
  if (
261
376
  !retryableBuilderReadStatus(response.status) ||
262
377
  attempt === BUILDER_CMS_READ_RETRIES
@@ -403,6 +518,10 @@ function normalizeBuilderCmsModel(
403
518
  fieldRecord.friendlyName.trim()
404
519
  ? fieldRecord.friendlyName.trim()
405
520
  : undefined;
521
+ const model =
522
+ typeof fieldRecord.model === "string" && fieldRecord.model.trim()
523
+ ? fieldRecord.model.trim()
524
+ : undefined;
406
525
  const enumOptions = stringOptionsFromUnknown(fieldRecord.enum);
407
526
  const options = stringOptionsFromUnknown(
408
527
  fieldRecord.options ?? fieldRecord.allowedValues,
@@ -415,6 +534,7 @@ function normalizeBuilderCmsModel(
415
534
  ? fieldRecord.type.trim()
416
535
  : "unknown",
417
536
  ...(inputType ? { inputType } : {}),
537
+ ...(model ? { model } : {}),
418
538
  ...(enumOptions ? { enum: enumOptions } : {}),
419
539
  ...(options ? { options } : {}),
420
540
  required: fieldRecord.required === true,
@@ -511,6 +631,7 @@ async function initializeBuilderMcp(args: {
511
631
  async function readBuilderCmsContentEntriesViaMcp(args: {
512
632
  model: string;
513
633
  fieldPaths?: readonly string[];
634
+ rawData?: boolean;
514
635
  limit?: number;
515
636
  maxPages?: number;
516
637
  offset?: number;
@@ -531,7 +652,9 @@ async function readBuilderCmsContentEntriesViaMcp(args: {
531
652
  ? Math.max(0, Math.floor(args.offset))
532
653
  : 0;
533
654
  const contentEntries: BuilderCmsSourceEntry[] = [];
534
- const fields = builderCmsListEntryFields(args.fieldPaths);
655
+ const fields = args.rawData
656
+ ? undefined
657
+ : builderCmsListEntryFields(args.fieldPaths);
535
658
  const seenContentIds = new Set<string>();
536
659
  let pagesRead = 0;
537
660
  let hasMore = false;
@@ -556,8 +679,8 @@ async function readBuilderCmsContentEntriesViaMcp(args: {
556
679
  modelName: args.model,
557
680
  limit: pageLimit,
558
681
  offset,
559
- fields,
560
- enrich: true,
682
+ ...(fields ? { fields } : {}),
683
+ enrich: args.rawData !== true,
561
684
  },
562
685
  },
563
686
  },
@@ -663,8 +786,8 @@ async function readBuilderCmsContentEntriesViaMcp(args: {
663
786
  modelName: args.model,
664
787
  limit: 1,
665
788
  query: { id: entry.id },
666
- fields,
667
- enrich: true,
789
+ ...(fields ? { fields } : {}),
790
+ enrich: args.rawData !== true,
668
791
  },
669
792
  },
670
793
  },
@@ -697,11 +820,13 @@ async function readBuilderCmsContentEntriesViaMcp(args: {
697
820
  async function readBuilderCmsContentEntriesViaContentApi(args: {
698
821
  model: string;
699
822
  fieldPaths?: readonly string[];
823
+ rawData?: boolean;
700
824
  limit?: number;
701
825
  maxPages?: number;
702
826
  offset?: number;
703
827
  fetchImpl: FetchLike;
704
828
  publicKey: string;
829
+ privateKey?: string;
705
830
  }): Promise<BuilderCmsReadResult> {
706
831
  const fetchedAt = new Date().toISOString();
707
832
  const url = new URL(
@@ -709,12 +834,19 @@ async function readBuilderCmsContentEntriesViaContentApi(args: {
709
834
  builderContentApiHost(),
710
835
  );
711
836
  url.searchParams.set("apiKey", args.publicKey);
712
- // Enrich expands reference fields (e.g. blog-article -> blog-author) inline so
713
- // mapped source columns can show the referenced entry's name instead of a
714
- // bare reference id.
715
- url.searchParams.set("enrich", "true");
837
+ // Normal list reads enrich references and project away heavyweight bodies.
838
+ // Fidelity reads intentionally do neither: Builder's raw data object is the
839
+ // clone contract, including unresolved references and every nested field.
840
+ url.searchParams.set("enrich", args.rawData === true ? "false" : "true");
716
841
  url.searchParams.set("noCache", "true");
717
- url.searchParams.set("fields", builderCmsListEntryFields(args.fieldPaths));
842
+ url.searchParams.set(
843
+ "cachebust",
844
+ args.rawData === true ? String(Date.now()) : "true",
845
+ );
846
+ url.searchParams.set("includeUnpublished", "true");
847
+ if (args.rawData !== true) {
848
+ url.searchParams.set("fields", builderCmsListEntryFields(args.fieldPaths));
849
+ }
718
850
 
719
851
  const limit = readLimit(args.limit);
720
852
  const startOffset =
@@ -740,6 +872,7 @@ async function readBuilderCmsContentEntriesViaContentApi(args: {
740
872
  response = await fetchBuilderContentPage({
741
873
  fetchImpl: args.fetchImpl,
742
874
  url: pageUrl,
875
+ privateKey: args.privateKey,
743
876
  });
744
877
  } catch (error) {
745
878
  return {
@@ -829,9 +962,7 @@ export async function readBuilderCmsEntryLiveState(args: {
829
962
  )}`,
830
963
  builderContentApiHost(),
831
964
  );
832
- url.searchParams.set("apiKey", publicKey);
833
- url.searchParams.set("includeUnpublished", "true");
834
- url.searchParams.set("cachebust", String(Date.now()));
965
+ applyBuilderCmsBodyEntryReadParams(url, publicKey);
835
966
 
836
967
  const response = await fetchBuilderContentPage({
837
968
  fetchImpl: args.fetchImpl ?? fetch,
@@ -874,12 +1005,7 @@ export async function readBuilderCmsContentEntry(args: {
874
1005
  )}`,
875
1006
  builderContentApiHost(),
876
1007
  );
877
- url.searchParams.set("apiKey", publicKey);
878
- url.searchParams.set("includeUnpublished", "true");
879
- url.searchParams.set("enrich", "true");
880
- url.searchParams.set("noCache", "true");
881
- url.searchParams.set("cachebust", String(Date.now()));
882
- url.searchParams.set("fields", BUILDER_CMS_BODY_ENTRY_FIELDS);
1008
+ applyBuilderCmsBodyEntryReadParams(url, publicKey);
883
1009
 
884
1010
  const response = await fetchBuilderContentPage({
885
1011
  fetchImpl: args.fetchImpl ?? fetch,
@@ -984,6 +1110,8 @@ export async function readBuilderCmsModelFields(args: {
984
1110
  export async function readBuilderCmsContentEntries(args: {
985
1111
  model: string;
986
1112
  fieldPaths?: readonly string[];
1113
+ rawData?: boolean;
1114
+ requirePrivateKey?: boolean;
987
1115
  limit?: number;
988
1116
  maxPages?: number;
989
1117
  offset?: number;
@@ -993,19 +1121,38 @@ export async function readBuilderCmsContentEntries(args: {
993
1121
  const privateKey = await readBuilderPrivateKey();
994
1122
  const fetchImpl = args.fetchImpl ?? fetch;
995
1123
  const publicKey = await resolveBuilderCredential("BUILDER_PUBLIC_KEY");
1124
+ if (args.requirePrivateKey === true && !privateKey) {
1125
+ return {
1126
+ state: "unconfigured",
1127
+ entries: [],
1128
+ fetchedAt,
1129
+ message:
1130
+ "Builder CMS authenticated read skipped because BUILDER_PRIVATE_KEY is not configured.",
1131
+ progress: {
1132
+ requestedLimit: readLimit(args.limit),
1133
+ pageSize: BUILDER_CMS_PAGE_SIZE,
1134
+ startOffset: 0,
1135
+ nextOffset: 0,
1136
+ fetchedEntryCount: 0,
1137
+ hasMore: false,
1138
+ partial: false,
1139
+ readMode: "none",
1140
+ },
1141
+ };
1142
+ }
996
1143
  if (publicKey) {
997
1144
  const contentApiRead = await readBuilderCmsContentEntriesViaContentApi({
998
1145
  model: args.model,
999
1146
  fieldPaths: args.fieldPaths,
1147
+ rawData: args.rawData,
1000
1148
  limit: args.limit,
1001
1149
  maxPages: args.maxPages,
1002
1150
  offset: args.offset,
1003
1151
  fetchImpl,
1004
1152
  publicKey,
1153
+ privateKey: privateKey ?? undefined,
1005
1154
  });
1006
- if (contentApiRead.state === "live" && contentApiRead.entries.length > 0) {
1007
- return contentApiRead;
1008
- }
1155
+ if (contentApiRead.state === "live") return contentApiRead;
1009
1156
  if (!privateKey) return contentApiRead;
1010
1157
  }
1011
1158
 
@@ -1014,6 +1161,7 @@ export async function readBuilderCmsContentEntries(args: {
1014
1161
  return await readBuilderCmsContentEntriesViaMcp({
1015
1162
  model: args.model,
1016
1163
  fieldPaths: args.fieldPaths,
1164
+ rawData: args.rawData,
1017
1165
  limit: args.limit,
1018
1166
  maxPages: args.maxPages,
1019
1167
  offset: args.offset,
@@ -12,6 +12,7 @@ import {
12
12
 
13
13
  export const BUILDER_CMS_BODY_CONTENT_KEY = "__builder.body.content";
14
14
  export const BUILDER_CMS_BODY_BLOCKS_HASH_KEY = "__builder.body.blocksHash";
15
+ export const BUILDER_CMS_BODY_LAST_UPDATED_KEY = "__builder.body.lastUpdated";
15
16
  export const BUILDER_CMS_BODY_SIDECARS_KEY = "__builder.body.sidecarsJson";
16
17
  export const BUILDER_CMS_BODY_LOSSLESS_CONTENT_KEY =
17
18
  "__builder.body.losslessContent";