octocms 0.3.7 → 0.4.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 (426) hide show
  1. package/dist/admin/AdminApp.d.ts +3 -0
  2. package/dist/admin/AdminApp.d.ts.map +1 -1
  3. package/dist/admin/AdminApp.js +14 -1
  4. package/dist/admin/AdminApp.js.map +1 -1
  5. package/dist/admin/ThemeProvider.js +1 -1
  6. package/dist/admin/actions/agent.d.ts +16 -0
  7. package/dist/admin/actions/agent.d.ts.map +1 -0
  8. package/dist/admin/actions/agent.js +15 -0
  9. package/dist/admin/actions/agent.js.map +1 -0
  10. package/dist/admin/actions/build.d.ts.map +1 -1
  11. package/dist/admin/actions/build.js +7 -3
  12. package/dist/admin/actions/build.js.map +1 -1
  13. package/dist/admin/actions/diff.d.ts +22 -0
  14. package/dist/admin/actions/diff.d.ts.map +1 -0
  15. package/dist/admin/actions/diff.js +131 -0
  16. package/dist/admin/actions/diff.js.map +1 -0
  17. package/dist/admin/actions/entries.js +1 -1
  18. package/dist/admin/actions/files.d.ts.map +1 -1
  19. package/dist/admin/actions/files.js +27 -2
  20. package/dist/admin/actions/files.js.map +1 -1
  21. package/dist/admin/actions/getThemeCookie.js +1 -1
  22. package/dist/admin/actions/git.d.ts +8 -0
  23. package/dist/admin/actions/git.d.ts.map +1 -1
  24. package/dist/admin/actions/git.js +48 -1
  25. package/dist/admin/actions/git.js.map +1 -1
  26. package/dist/admin/actions/media.js +1 -1
  27. package/dist/admin/actions/schema.d.ts +53 -0
  28. package/dist/admin/actions/schema.d.ts.map +1 -0
  29. package/dist/admin/actions/schema.js +376 -0
  30. package/dist/admin/actions/schema.js.map +1 -0
  31. package/dist/admin/actions/search.js +1 -1
  32. package/dist/admin/actions/status.js +1 -1
  33. package/dist/admin/actions/utils.js +1 -1
  34. package/dist/admin/actions.d.ts +3 -0
  35. package/dist/admin/actions.d.ts.map +1 -1
  36. package/dist/admin/actions.js +3 -0
  37. package/dist/admin/actions.js.map +1 -1
  38. package/dist/admin/auth.js +1 -1
  39. package/dist/admin/consts.js +1 -1
  40. package/dist/admin/github.d.ts +31 -0
  41. package/dist/admin/github.d.ts.map +1 -1
  42. package/dist/admin/github.js +79 -1
  43. package/dist/admin/github.js.map +1 -1
  44. package/dist/admin/pages/AdminLayout.js +1 -1
  45. package/dist/admin/pages/ChatPage.d.ts +9 -0
  46. package/dist/admin/pages/ChatPage.d.ts.map +1 -0
  47. package/dist/admin/pages/ChatPage.js +26 -0
  48. package/dist/admin/pages/ChatPage.js.map +1 -0
  49. package/dist/admin/pages/CollectionPage.js +1 -1
  50. package/dist/admin/pages/ContentModelPage.d.ts +2 -0
  51. package/dist/admin/pages/ContentModelPage.d.ts.map +1 -0
  52. package/dist/admin/pages/ContentModelPage.js +23 -0
  53. package/dist/admin/pages/ContentModelPage.js.map +1 -0
  54. package/dist/admin/pages/ContentTypePage.d.ts +4 -0
  55. package/dist/admin/pages/ContentTypePage.d.ts.map +1 -0
  56. package/dist/admin/pages/ContentTypePage.js +24 -0
  57. package/dist/admin/pages/ContentTypePage.js.map +1 -0
  58. package/dist/admin/pages/DashboardPage.js +1 -1
  59. package/dist/admin/pages/EntryPage.js +1 -1
  60. package/dist/admin/pages/MediaPage.js +1 -1
  61. package/dist/admin/pages/SearchPage.js +1 -1
  62. package/dist/admin/provider.js +1 -1
  63. package/dist/admin/store/contentStore.js +1 -1
  64. package/dist/admin/store/contentStoreFetch.js +1 -1
  65. package/dist/admin/theme.js +1 -1
  66. package/dist/agent/attachments.d.ts +69 -0
  67. package/dist/agent/attachments.d.ts.map +1 -0
  68. package/dist/agent/attachments.js +158 -0
  69. package/dist/agent/attachments.js.map +1 -0
  70. package/dist/agent/chat.d.ts +70 -0
  71. package/dist/agent/chat.d.ts.map +1 -0
  72. package/dist/agent/chat.js +173 -0
  73. package/dist/agent/chat.js.map +1 -0
  74. package/dist/agent/chatApi.js +238 -0
  75. package/dist/agent/chatApi.js.map +1 -0
  76. package/dist/agent/configStore.d.ts +15 -0
  77. package/dist/agent/configStore.d.ts.map +1 -0
  78. package/dist/agent/configStore.js +13 -0
  79. package/dist/agent/configStore.js.map +1 -0
  80. package/dist/agent/defaults.js +28 -0
  81. package/dist/agent/defaults.js.map +1 -0
  82. package/dist/agent/embedText.d.ts +23 -0
  83. package/dist/agent/embedText.d.ts.map +1 -0
  84. package/dist/agent/embedText.js +37 -0
  85. package/dist/agent/embedText.js.map +1 -0
  86. package/dist/agent/embedder.d.ts +34 -0
  87. package/dist/agent/embedder.d.ts.map +1 -0
  88. package/dist/agent/embedder.js +56 -0
  89. package/dist/agent/embedder.js.map +1 -0
  90. package/dist/agent/embeddings.d.ts +96 -0
  91. package/dist/agent/embeddings.d.ts.map +1 -0
  92. package/dist/agent/embeddings.js +187 -0
  93. package/dist/agent/embeddings.js.map +1 -0
  94. package/dist/agent/embeddingsHook.d.ts +47 -0
  95. package/dist/agent/embeddingsHook.d.ts.map +1 -0
  96. package/dist/agent/embeddingsHook.js +56 -0
  97. package/dist/agent/embeddingsHook.js.map +1 -0
  98. package/dist/agent/featureFlag.d.ts +36 -0
  99. package/dist/agent/featureFlag.d.ts.map +1 -0
  100. package/dist/agent/featureFlag.js +47 -0
  101. package/dist/agent/featureFlag.js.map +1 -0
  102. package/dist/agent/index.cjs +5314 -0
  103. package/dist/agent/index.cjs.map +1 -0
  104. package/dist/agent/index.js +118 -0
  105. package/dist/agent/index.js.map +1 -0
  106. package/dist/agent/pricing.d.ts +11 -0
  107. package/dist/agent/pricing.d.ts.map +1 -0
  108. package/dist/agent/pricing.js +16 -0
  109. package/dist/agent/pricing.js.map +1 -0
  110. package/dist/agent/proposals.d.ts +82 -0
  111. package/dist/agent/proposals.d.ts.map +1 -0
  112. package/dist/agent/proposals.js +95 -0
  113. package/dist/agent/proposals.js.map +1 -0
  114. package/dist/agent/proposalsApi.js +83 -0
  115. package/dist/agent/proposalsApi.js.map +1 -0
  116. package/dist/agent/providers/anthropic.js +198 -0
  117. package/dist/agent/providers/anthropic.js.map +1 -0
  118. package/dist/agent/providers/index.js +17 -0
  119. package/dist/agent/providers/index.js.map +1 -0
  120. package/dist/agent/providers/openai.js +215 -0
  121. package/dist/agent/providers/openai.js.map +1 -0
  122. package/dist/agent/providers/types.d.ts +118 -0
  123. package/dist/agent/providers/types.d.ts.map +1 -0
  124. package/dist/agent/providers/types.js +1 -0
  125. package/dist/agent/search.d.ts +58 -0
  126. package/dist/agent/search.d.ts.map +1 -0
  127. package/dist/agent/search.js +97 -0
  128. package/dist/agent/search.js.map +1 -0
  129. package/dist/agent/storeFormat.d.ts +19 -0
  130. package/dist/agent/storeFormat.d.ts.map +1 -0
  131. package/dist/agent/storeFormat.js +35 -0
  132. package/dist/agent/storeFormat.js.map +1 -0
  133. package/dist/agent/systemPrompt.d.ts +26 -0
  134. package/dist/agent/systemPrompt.d.ts.map +1 -0
  135. package/dist/agent/systemPrompt.js +49 -0
  136. package/dist/agent/systemPrompt.js.map +1 -0
  137. package/dist/agent/tools/index.d.ts +37 -0
  138. package/dist/agent/tools/index.d.ts.map +1 -0
  139. package/dist/agent/tools/index.js +467 -0
  140. package/dist/agent/tools/index.js.map +1 -0
  141. package/dist/agent/types.d.ts +73 -0
  142. package/dist/agent/types.d.ts.map +1 -0
  143. package/dist/agent/types.js +1 -0
  144. package/dist/agent/types.js.map +1 -0
  145. package/dist/agent/usage.d.ts +32 -0
  146. package/dist/agent/usage.d.ts.map +1 -0
  147. package/dist/agent/usage.js +42 -0
  148. package/dist/agent/usage.js.map +1 -0
  149. package/dist/{agentDocs-Y3LM2CPQ.js → agentDocs-YTR2WM5C.js} +4 -3
  150. package/dist/{agentDocs-Y3LM2CPQ.js.map → agentDocs-YTR2WM5C.js.map} +1 -1
  151. package/dist/chunk-6PHFHGTZ.js +35 -0
  152. package/dist/{chunk-33PHLOAE.js.map → chunk-6PHFHGTZ.js.map} +1 -1
  153. package/dist/chunk-B5LE2OEC.js +58 -0
  154. package/dist/chunk-B5LE2OEC.js.map +1 -0
  155. package/dist/{chunk-2NMEKWO5.js → chunk-DDAAVRWG.js} +2 -15
  156. package/dist/chunk-DDAAVRWG.js.map +1 -0
  157. package/dist/{chunk-SWGXG4XK.js → chunk-VTZ2KGUU.js} +42 -1
  158. package/dist/chunk-VTZ2KGUU.js.map +1 -0
  159. package/dist/cli/index.js +37 -15
  160. package/dist/cli/index.js.map +1 -1
  161. package/dist/cli/lib/agentDocs.d.ts +15 -0
  162. package/dist/cli/lib/agentDocs.d.ts.map +1 -0
  163. package/dist/cli/lib/codegen.d.ts +70 -0
  164. package/dist/cli/lib/codegen.d.ts.map +1 -0
  165. package/dist/cli/lib/schemaDocs.d.ts +17 -0
  166. package/dist/cli/lib/schemaDocs.d.ts.map +1 -0
  167. package/dist/cli/lib/validateConfig.d.ts +17 -0
  168. package/dist/cli/lib/validateConfig.d.ts.map +1 -0
  169. package/dist/components/CMSSidebar/CMSSidebar.js +1 -1
  170. package/dist/components/Chat/ChatPage.d.ts +15 -0
  171. package/dist/components/Chat/ChatPage.d.ts.map +1 -0
  172. package/dist/components/Chat/ChatPage.js +203 -0
  173. package/dist/components/Chat/ChatPage.js.map +1 -0
  174. package/dist/components/Chat/Composer.d.ts +15 -0
  175. package/dist/components/Chat/Composer.d.ts.map +1 -0
  176. package/dist/components/Chat/Composer.js +179 -0
  177. package/dist/components/Chat/Composer.js.map +1 -0
  178. package/dist/components/Chat/Message.d.ts +10 -0
  179. package/dist/components/Chat/Message.d.ts.map +1 -0
  180. package/dist/components/Chat/Message.js +73 -0
  181. package/dist/components/Chat/Message.js.map +1 -0
  182. package/dist/components/Chat/ProposalCard.d.ts +9 -0
  183. package/dist/components/Chat/ProposalCard.d.ts.map +1 -0
  184. package/dist/components/Chat/ProposalCard.js +243 -0
  185. package/dist/components/Chat/ProposalCard.js.map +1 -0
  186. package/dist/components/Chat/ToolCallCard.d.ts +7 -0
  187. package/dist/components/Chat/ToolCallCard.d.ts.map +1 -0
  188. package/dist/components/Chat/ToolCallCard.js +90 -0
  189. package/dist/components/Chat/ToolCallCard.js.map +1 -0
  190. package/dist/components/Chat/types.d.ts +81 -0
  191. package/dist/components/Chat/types.d.ts.map +1 -0
  192. package/dist/components/Chat/types.js +1 -0
  193. package/dist/components/Chat/types.js.map +1 -0
  194. package/dist/components/Chat/useChatStream.d.ts +44 -0
  195. package/dist/components/Chat/useChatStream.d.ts.map +1 -0
  196. package/dist/components/Chat/useChatStream.js +444 -0
  197. package/dist/components/Chat/useChatStream.js.map +1 -0
  198. package/dist/components/ContentModel/ConditionalBranchesEditor.d.ts +15 -0
  199. package/dist/components/ContentModel/ConditionalBranchesEditor.d.ts.map +1 -0
  200. package/dist/components/ContentModel/ConditionalBranchesEditor.js +277 -0
  201. package/dist/components/ContentModel/ConditionalBranchesEditor.js.map +1 -0
  202. package/dist/components/ContentModel/ContentModelList.d.ts +8 -0
  203. package/dist/components/ContentModel/ContentModelList.d.ts.map +1 -0
  204. package/dist/components/ContentModel/ContentModelList.js +111 -0
  205. package/dist/components/ContentModel/ContentModelList.js.map +1 -0
  206. package/dist/components/ContentModel/ContentTypeDetail.d.ts +9 -0
  207. package/dist/components/ContentModel/ContentTypeDetail.d.ts.map +1 -0
  208. package/dist/components/ContentModel/ContentTypeDetail.js +459 -0
  209. package/dist/components/ContentModel/ContentTypeDetail.js.map +1 -0
  210. package/dist/components/ContentModel/CreateContentTypeDialog.d.ts +9 -0
  211. package/dist/components/ContentModel/CreateContentTypeDialog.d.ts.map +1 -0
  212. package/dist/components/ContentModel/CreateContentTypeDialog.js +215 -0
  213. package/dist/components/ContentModel/CreateContentTypeDialog.js.map +1 -0
  214. package/dist/components/ContentModel/DeleteContentTypeDialog.d.ts +10 -0
  215. package/dist/components/ContentModel/DeleteContentTypeDialog.d.ts.map +1 -0
  216. package/dist/components/ContentModel/DeleteContentTypeDialog.js +143 -0
  217. package/dist/components/ContentModel/DeleteContentTypeDialog.js.map +1 -0
  218. package/dist/components/ContentModel/DeleteFieldDialog.d.ts +11 -0
  219. package/dist/components/ContentModel/DeleteFieldDialog.d.ts.map +1 -0
  220. package/dist/components/ContentModel/DeleteFieldDialog.js +141 -0
  221. package/dist/components/ContentModel/DeleteFieldDialog.js.map +1 -0
  222. package/dist/components/ContentModel/EditContentTypeDialog.d.ts +12 -0
  223. package/dist/components/ContentModel/EditContentTypeDialog.d.ts.map +1 -0
  224. package/dist/components/ContentModel/EditContentTypeDialog.js +254 -0
  225. package/dist/components/ContentModel/EditContentTypeDialog.js.map +1 -0
  226. package/dist/components/ContentModel/FieldDialog.d.ts +28 -0
  227. package/dist/components/ContentModel/FieldDialog.d.ts.map +1 -0
  228. package/dist/components/ContentModel/FieldDialog.js +569 -0
  229. package/dist/components/ContentModel/FieldDialog.js.map +1 -0
  230. package/dist/components/ContentModel/RichTextOptionsEditor.d.ts +10 -0
  231. package/dist/components/ContentModel/RichTextOptionsEditor.d.ts.map +1 -0
  232. package/dist/components/ContentModel/RichTextOptionsEditor.js +422 -0
  233. package/dist/components/ContentModel/RichTextOptionsEditor.js.map +1 -0
  234. package/dist/components/ContentModel/SchemaImpactList.d.ts +19 -0
  235. package/dist/components/ContentModel/SchemaImpactList.d.ts.map +1 -0
  236. package/dist/components/ContentModel/SchemaImpactList.js +88 -0
  237. package/dist/components/ContentModel/SchemaImpactList.js.map +1 -0
  238. package/dist/components/ContentModel/SchemaOptionFieldInput.d.ts +15 -0
  239. package/dist/components/ContentModel/SchemaOptionFieldInput.d.ts.map +1 -0
  240. package/dist/components/ContentModel/SchemaOptionFieldInput.js +386 -0
  241. package/dist/components/ContentModel/SchemaOptionFieldInput.js.map +1 -0
  242. package/dist/components/ContentModel/contentTypeKey.d.ts +16 -0
  243. package/dist/components/ContentModel/contentTypeKey.d.ts.map +1 -0
  244. package/dist/components/ContentModel/contentTypeKey.js +29 -0
  245. package/dist/components/ContentModel/contentTypeKey.js.map +1 -0
  246. package/dist/components/ContentModel/fieldKey.d.ts +17 -0
  247. package/dist/components/ContentModel/fieldKey.d.ts.map +1 -0
  248. package/dist/components/ContentModel/fieldKey.js +29 -0
  249. package/dist/components/ContentModel/fieldKey.js.map +1 -0
  250. package/dist/components/ContentModel/fieldOptions.d.ts +37 -0
  251. package/dist/components/ContentModel/fieldOptions.d.ts.map +1 -0
  252. package/dist/components/ContentModel/fieldOptions.js +261 -0
  253. package/dist/components/ContentModel/fieldOptions.js.map +1 -0
  254. package/dist/components/ContentTypes.js +1 -1
  255. package/dist/components/CreateBranchDialog.js +1 -1
  256. package/dist/components/Dashboard/DashboardContent.d.ts.map +1 -1
  257. package/dist/components/Dashboard/DashboardContent.js +2 -12
  258. package/dist/components/Dashboard/DashboardContent.js.map +1 -1
  259. package/dist/components/DiffView/DiffHunk.d.ts +15 -0
  260. package/dist/components/DiffView/DiffHunk.d.ts.map +1 -0
  261. package/dist/components/DiffView/DiffHunk.js +92 -0
  262. package/dist/components/DiffView/DiffHunk.js.map +1 -0
  263. package/dist/components/DiffView/DiffView.d.ts +7 -0
  264. package/dist/components/DiffView/DiffView.d.ts.map +1 -0
  265. package/dist/components/DiffView/DiffView.js +155 -0
  266. package/dist/components/DiffView/DiffView.js.map +1 -0
  267. package/dist/components/DiffView/index.d.ts +3 -0
  268. package/dist/components/DiffView/index.d.ts.map +1 -0
  269. package/dist/components/DiffView/index.js +8 -0
  270. package/dist/components/DiffView/index.js.map +1 -0
  271. package/dist/components/EditPost/EditPost.d.ts.map +1 -1
  272. package/dist/components/EditPost/EditPost.js +161 -70
  273. package/dist/components/EditPost/EditPost.js.map +1 -1
  274. package/dist/components/FieldHintAndError.js +1 -1
  275. package/dist/components/FileExplorer/FileExplorer.js +1 -1
  276. package/dist/components/FormBooleanField.js +1 -1
  277. package/dist/components/FormColorField.js +1 -1
  278. package/dist/components/FormConditionalField.js +1 -1
  279. package/dist/components/FormDatetimeField.js +1 -1
  280. package/dist/components/FormFields.js +1 -1
  281. package/dist/components/FormImageField.js +1 -1
  282. package/dist/components/FormJsonField.js +1 -1
  283. package/dist/components/FormMarkdownField.js +1 -1
  284. package/dist/components/FormNumberField.js +1 -1
  285. package/dist/components/FormReferenceField.js +1 -1
  286. package/dist/components/FormRichTextField.js +1 -1
  287. package/dist/components/FormSelectField.js +1 -1
  288. package/dist/components/FormSlugField.js +1 -1
  289. package/dist/components/FormStringField.js +1 -1
  290. package/dist/components/FormStringListField.js +1 -1
  291. package/dist/components/FormTextField.js +1 -1
  292. package/dist/components/FormUrlField.js +1 -1
  293. package/dist/components/Header/Header.d.ts.map +1 -1
  294. package/dist/components/Header/Header.js +32 -7
  295. package/dist/components/Header/Header.js.map +1 -1
  296. package/dist/components/Header/ThemeToggle.js +1 -1
  297. package/dist/components/HistorySection/HistorySection.d.ts +6 -0
  298. package/dist/components/HistorySection/HistorySection.d.ts.map +1 -0
  299. package/dist/components/HistorySection/HistorySection.js +116 -0
  300. package/dist/components/HistorySection/HistorySection.js.map +1 -0
  301. package/dist/components/InlineEntryEditor/InlineEntryEditor.js +1 -1
  302. package/dist/components/Layout/Layout.js +1 -1
  303. package/dist/components/LinkedBySection/LinkedBySection.js +1 -1
  304. package/dist/components/Loading.js +1 -1
  305. package/dist/components/MediaManager/MediaManager.js +1 -1
  306. package/dist/components/SearchPage.js +1 -1
  307. package/dist/components/StatusBadge.js +1 -1
  308. package/dist/components/public/MarkdownContent.js +1 -1
  309. package/dist/components/public/RichTextContent.js +1 -1
  310. package/dist/components/public/SearchBox.js +1 -1
  311. package/dist/components/public/index.js +1 -1
  312. package/dist/components/richtext/ComponentEmbedEditor.js +1 -1
  313. package/dist/components/richtext/ConditionEmbedEditor.js +1 -1
  314. package/dist/components/richtext/ImageEmbedEditor.js +1 -1
  315. package/dist/components/richtext/ReferenceEmbedEditor.js +1 -1
  316. package/dist/components/richtext/SlashCommandMenu.js +1 -1
  317. package/dist/components/richtext/VariableEmbedEditor.js +1 -1
  318. package/dist/components/ui/avatar.js +1 -1
  319. package/dist/components/ui/button.js +1 -1
  320. package/dist/components/ui/card.d.ts +7 -0
  321. package/dist/components/ui/card.d.ts.map +1 -0
  322. package/dist/components/ui/card.js +53 -0
  323. package/dist/components/ui/card.js.map +1 -0
  324. package/dist/components/ui/dialog.js +1 -1
  325. package/dist/components/ui/dropdown-menu.js +1 -1
  326. package/dist/components/ui/index.d.ts +1 -0
  327. package/dist/components/ui/index.d.ts.map +1 -1
  328. package/dist/components/ui/index.js +6 -1
  329. package/dist/components/ui/index.js.map +1 -1
  330. package/dist/components/ui/input.js +1 -1
  331. package/dist/components/ui/label.js +1 -1
  332. package/dist/components/ui/select.js +1 -1
  333. package/dist/components/ui/sonner.js +1 -1
  334. package/dist/components/ui/table.js +1 -1
  335. package/dist/components/ui/tabs.js +1 -1
  336. package/dist/components/ui/toast.d.ts +1 -1
  337. package/dist/components/ui/toast.js +1 -1
  338. package/dist/components/ui/toaster.js +1 -1
  339. package/dist/config.js +1 -1
  340. package/dist/defineConfig.js +1 -1
  341. package/dist/{dev-W5U5LD4P.js → dev-B6A62PGI.js} +5 -3
  342. package/dist/{dev-W5U5LD4P.js.map → dev-B6A62PGI.js.map} +1 -1
  343. package/dist/embeddingsGen-FWXI55MC.js +349 -0
  344. package/dist/embeddingsGen-FWXI55MC.js.map +1 -0
  345. package/dist/github-Q7ABLNZF.js +698 -0
  346. package/dist/github-Q7ABLNZF.js.map +1 -0
  347. package/dist/github-public.js +1 -1
  348. package/dist/hooks/useConfig.js +1 -1
  349. package/dist/hooks/useEntryStack.js +1 -1
  350. package/dist/hooks/useFileState.js +1 -1
  351. package/dist/hooks/useToast.js +1 -1
  352. package/dist/index.js +1 -1
  353. package/dist/{init-V6THBALA.js → init-PSAF5XNZ.js} +42 -3
  354. package/dist/init-PSAF5XNZ.js.map +1 -0
  355. package/dist/lib/blogPublicPath.js +1 -1
  356. package/dist/lib/branchHistory.js +1 -1
  357. package/dist/lib/cmsServerLog.js +1 -1
  358. package/dist/lib/colorField.js +1 -1
  359. package/dist/lib/companionMarkdown.js +1 -1
  360. package/dist/lib/conditionalField.js +1 -1
  361. package/dist/lib/configStore.js +1 -1
  362. package/dist/lib/contentSourceError.js +1 -1
  363. package/dist/lib/datetimeField.js +1 -1
  364. package/dist/lib/deploymentEnv.js +1 -1
  365. package/dist/lib/entryDiff.d.ts +33 -0
  366. package/dist/lib/entryDiff.d.ts.map +1 -0
  367. package/dist/lib/entryDiff.js +75 -0
  368. package/dist/lib/entryDiff.js.map +1 -0
  369. package/dist/lib/extractImageMetadata.js +1 -1
  370. package/dist/lib/githubContentMode.js +1 -1
  371. package/dist/lib/initialEntryFields.js +1 -1
  372. package/dist/lib/jsonField.js +1 -1
  373. package/dist/lib/localReader.js +1 -1
  374. package/dist/lib/numberField.js +1 -1
  375. package/dist/lib/persistedFormFields.js +1 -1
  376. package/dist/lib/referenceKeys.js +1 -1
  377. package/dist/lib/relativeTime.d.ts +6 -0
  378. package/dist/lib/relativeTime.d.ts.map +1 -0
  379. package/dist/lib/relativeTime.js +17 -0
  380. package/dist/lib/relativeTime.js.map +1 -0
  381. package/dist/lib/resolveEntryTitle.d.ts +42 -0
  382. package/dist/lib/resolveEntryTitle.d.ts.map +1 -0
  383. package/dist/lib/resolveEntryTitle.js +84 -0
  384. package/dist/lib/resolveEntryTitle.js.map +1 -0
  385. package/dist/lib/richtext/parseRichText.js +1 -1
  386. package/dist/lib/richtextFieldConfig.js +1 -1
  387. package/dist/lib/searchIndex.js +1 -1
  388. package/dist/lib/selectField.js +1 -1
  389. package/dist/lib/slugField.js +1 -1
  390. package/dist/lib/stringListField.js +1 -1
  391. package/dist/lib/suggestedMediaTitle.js +1 -1
  392. package/dist/lib/urlField.js +1 -1
  393. package/dist/lib/utils.js +1 -1
  394. package/dist/lib/validateEntryFields.js +1 -1
  395. package/dist/query.js +1 -1
  396. package/dist/schema/diffSchema.d.ts +58 -0
  397. package/dist/schema/diffSchema.d.ts.map +1 -0
  398. package/dist/schema/fieldFormats.d.ts +24 -0
  399. package/dist/schema/fieldFormats.d.ts.map +1 -0
  400. package/dist/schema/migrateContent.d.ts +121 -0
  401. package/dist/schema/migrateContent.d.ts.map +1 -0
  402. package/dist/schema/types.d.ts +53 -0
  403. package/dist/schema/types.d.ts.map +1 -0
  404. package/dist/types.cjs.map +1 -1
  405. package/dist/types.d.ts +34 -0
  406. package/dist/types.d.ts.map +1 -1
  407. package/dist/{typesGen-RDG5SY5R.js → typesGen-EYRZAA56.js} +8 -5
  408. package/dist/typesGen-EYRZAA56.js.map +1 -0
  409. package/dist/update-B37MPMDP.js +142 -0
  410. package/dist/update-B37MPMDP.js.map +1 -0
  411. package/dist/utils/parseFileName.js +1 -1
  412. package/dist/{validate-IPA3LKXQ.js → validate-6AFW6U2X.js} +6 -4
  413. package/dist/{validate-IPA3LKXQ.js.map → validate-6AFW6U2X.js.map} +1 -1
  414. package/dist/withOctoCMS.js +1 -1
  415. package/docs/editing-schema.md +188 -0
  416. package/docs/index.md +5 -3
  417. package/docs/overview.md +13 -4
  418. package/docs/schema.md +1 -1
  419. package/package.json +28 -1
  420. package/dist/chunk-33PHLOAE.js +0 -57
  421. package/dist/chunk-SWGXG4XK.js.map +0 -1
  422. package/dist/init-V6THBALA.js.map +0 -1
  423. package/dist/typesGen-RDG5SY5R.js.map +0 -1
  424. package/dist/update-RF2HD3WJ.js +0 -56
  425. package/dist/update-RF2HD3WJ.js.map +0 -1
  426. /package/dist/{chunk-2NMEKWO5.js.map → agent/providers/types.js.map} +0 -0
@@ -11,9 +11,12 @@ type AdminAppProps = {
11
11
  *
12
12
  * Route segments map to admin pages:
13
13
  * /cms → DashboardPage
14
+ * /cms/chat → ChatPage (gated on `isAgentEnabled(agentConfig)`)
14
15
  * /cms/search → SearchPage
15
16
  * /cms/media → MediaPage (library)
16
17
  * /cms/media/<id> → MediaPage with that asset selected (detail panel)
18
+ * /cms/content-model → ContentModelPage
19
+ * /cms/content-model/<type>→ ContentTypePage
17
20
  * /cms/<type> → CollectionPage
18
21
  * /cms/<type>/<id>→ EntryPage
19
22
  */
@@ -1 +1 @@
1
- {"version":3,"file":"AdminApp.d.ts","sourceRoot":"","sources":["../../admin/AdminApp.tsx"],"names":[],"mappings":"AAQA,KAAK,aAAa,GAAG;IACnB,MAAM,EAAE,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACtC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,aAAa,2CAMjD"}
1
+ {"version":3,"file":"AdminApp.d.ts","sourceRoot":"","sources":["../../admin/AdminApp.tsx"],"names":[],"mappings":"AAWA,KAAK,aAAa,GAAG;IACnB,MAAM,EAAE,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACtC,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,aAAa,2CAMjD"}
@@ -1,7 +1,10 @@
1
- import "../chunk-2NMEKWO5.js";
1
+ import "../chunk-B5LE2OEC.js";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import { Suspense } from "react";
4
+ import { ChatPage } from "./pages/ChatPage";
4
5
  import { CollectionPage } from "./pages/CollectionPage";
6
+ import { ContentModelPage } from "./pages/ContentModelPage";
7
+ import { ContentTypePage } from "./pages/ContentTypePage";
5
8
  import { DashboardPage } from "./pages/DashboardPage";
6
9
  import { EntryPage } from "./pages/EntryPage";
7
10
  import { MediaPage } from "./pages/MediaPage";
@@ -18,10 +21,20 @@ async function AdminAppRouter({ params }) {
18
21
  if (segments[0] === "search") {
19
22
  return /* @__PURE__ */ jsx(SearchPage, {});
20
23
  }
24
+ if (segments[0] === "chat") {
25
+ return /* @__PURE__ */ jsx(ChatPage, {});
26
+ }
21
27
  if (segments[0] === "media") {
22
28
  const initialMediaId = segments.length >= 2 ? segments[1] : void 0;
23
29
  return /* @__PURE__ */ jsx(MediaPage, { initialMediaId });
24
30
  }
31
+ if (segments[0] === "content-model") {
32
+ if (segments.length === 1) {
33
+ return /* @__PURE__ */ jsx(ContentModelPage, {});
34
+ }
35
+ const [, type2] = segments;
36
+ return /* @__PURE__ */ jsx(ContentTypePage, { type: type2 });
37
+ }
25
38
  if (segments.length === 1) {
26
39
  const [type2] = segments;
27
40
  return /* @__PURE__ */ jsx(CollectionPage, { params: Promise.resolve({ type: type2 }) });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../admin/AdminApp.tsx"],"sourcesContent":["import React, { Suspense } from 'react';\n\nimport { CollectionPage } from './pages/CollectionPage';\nimport { DashboardPage } from './pages/DashboardPage';\nimport { EntryPage } from './pages/EntryPage';\nimport { MediaPage } from './pages/MediaPage';\nimport { SearchPage } from './pages/SearchPage';\n\ntype AdminAppProps = {\n params: Promise<{ path?: string[] }>;\n};\n\n/**\n * Catch-all admin router component. Mount this as the default export of a\n * Next.js optional catch-all route at `src/app/cms/[[...path]]/page.tsx`:\n *\n * export { AdminApp as default } from 'octocms/admin/AdminApp';\n *\n * Route segments map to admin pages:\n * /cms → DashboardPage\n * /cms/search → SearchPage\n * /cms/media → MediaPage (library)\n * /cms/media/<id> → MediaPage with that asset selected (detail panel)\n * /cms/<type> → CollectionPage\n * /cms/<type>/<id>→ EntryPage\n */\nexport function AdminApp({ params }: AdminAppProps) {\n return (\n <Suspense fallback={null}>\n <AdminAppRouter params={params} />\n </Suspense>\n );\n}\n\nasync function AdminAppRouter({ params }: AdminAppProps) {\n const { path } = await params;\n const segments = path ?? [];\n\n if (segments.length === 0) {\n return <DashboardPage />;\n }\n\n if (segments[0] === 'search') {\n return <SearchPage />;\n }\n\n if (segments[0] === 'media') {\n const initialMediaId = segments.length >= 2 ? segments[1] : undefined;\n return <MediaPage initialMediaId={initialMediaId} />;\n }\n\n if (segments.length === 1) {\n const [type] = segments;\n return <CollectionPage params={Promise.resolve({ type })} />;\n }\n\n const [type, id] = segments;\n return <EntryPage params={Promise.resolve({ type, id })} />;\n}\n"],"mappings":";AA6BM;AA7BN,SAAgB,gBAAgB;AAEhC,SAAS,sBAAsB;AAC/B,SAAS,qBAAqB;AAC9B,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAC1B,SAAS,kBAAkB;AAoBpB,SAAS,SAAS,EAAE,OAAO,GAAkB;AAClD,SACE,oBAAC,YAAS,UAAU,MAClB,8BAAC,kBAAe,QAAgB,GAClC;AAEJ;AAEA,eAAe,eAAe,EAAE,OAAO,GAAkB;AACvD,QAAM,EAAE,KAAK,IAAI,MAAM;AACvB,QAAM,WAAW,sBAAQ,CAAC;AAE1B,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO,oBAAC,iBAAc;AAAA,EACxB;AAEA,MAAI,SAAS,CAAC,MAAM,UAAU;AAC5B,WAAO,oBAAC,cAAW;AAAA,EACrB;AAEA,MAAI,SAAS,CAAC,MAAM,SAAS;AAC3B,UAAM,iBAAiB,SAAS,UAAU,IAAI,SAAS,CAAC,IAAI;AAC5D,WAAO,oBAAC,aAAU,gBAAgC;AAAA,EACpD;AAEA,MAAI,SAAS,WAAW,GAAG;AACzB,UAAM,CAACA,KAAI,IAAI;AACf,WAAO,oBAAC,kBAAe,QAAQ,QAAQ,QAAQ,EAAE,MAAAA,MAAK,CAAC,GAAG;AAAA,EAC5D;AAEA,QAAM,CAAC,MAAM,EAAE,IAAI;AACnB,SAAO,oBAAC,aAAU,QAAQ,QAAQ,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG;AAC3D;","names":["type"]}
1
+ {"version":3,"sources":["../../admin/AdminApp.tsx"],"sourcesContent":["import React, { Suspense } from 'react';\n\nimport { ChatPage } from './pages/ChatPage';\nimport { CollectionPage } from './pages/CollectionPage';\nimport { ContentModelPage } from './pages/ContentModelPage';\nimport { ContentTypePage } from './pages/ContentTypePage';\nimport { DashboardPage } from './pages/DashboardPage';\nimport { EntryPage } from './pages/EntryPage';\nimport { MediaPage } from './pages/MediaPage';\nimport { SearchPage } from './pages/SearchPage';\n\ntype AdminAppProps = {\n params: Promise<{ path?: string[] }>;\n};\n\n/**\n * Catch-all admin router component. Mount this as the default export of a\n * Next.js optional catch-all route at `src/app/cms/[[...path]]/page.tsx`:\n *\n * export { AdminApp as default } from 'octocms/admin/AdminApp';\n *\n * Route segments map to admin pages:\n * /cms → DashboardPage\n * /cms/chat → ChatPage (gated on `isAgentEnabled(agentConfig)`)\n * /cms/search → SearchPage\n * /cms/media → MediaPage (library)\n * /cms/media/<id> → MediaPage with that asset selected (detail panel)\n * /cms/content-model → ContentModelPage\n * /cms/content-model/<type>→ ContentTypePage\n * /cms/<type> → CollectionPage\n * /cms/<type>/<id>→ EntryPage\n */\nexport function AdminApp({ params }: AdminAppProps) {\n return (\n <Suspense fallback={null}>\n <AdminAppRouter params={params} />\n </Suspense>\n );\n}\n\nasync function AdminAppRouter({ params }: AdminAppProps) {\n const { path } = await params;\n const segments = path ?? [];\n\n if (segments.length === 0) {\n return <DashboardPage />;\n }\n\n if (segments[0] === 'search') {\n return <SearchPage />;\n }\n\n if (segments[0] === 'chat') {\n return <ChatPage />;\n }\n\n if (segments[0] === 'media') {\n const initialMediaId = segments.length >= 2 ? segments[1] : undefined;\n return <MediaPage initialMediaId={initialMediaId} />;\n }\n\n if (segments[0] === 'content-model') {\n if (segments.length === 1) {\n return <ContentModelPage />;\n }\n const [, type] = segments;\n return <ContentTypePage type={type} />;\n }\n\n if (segments.length === 1) {\n const [type] = segments;\n return <CollectionPage params={Promise.resolve({ type })} />;\n }\n\n const [type, id] = segments;\n return <EntryPage params={Promise.resolve({ type, id })} />;\n}\n"],"mappings":";AAmCM;AAnCN,SAAgB,gBAAgB;AAEhC,SAAS,gBAAgB;AACzB,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC,SAAS,uBAAuB;AAChC,SAAS,qBAAqB;AAC9B,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAC1B,SAAS,kBAAkB;AAuBpB,SAAS,SAAS,EAAE,OAAO,GAAkB;AAClD,SACE,oBAAC,YAAS,UAAU,MAClB,8BAAC,kBAAe,QAAgB,GAClC;AAEJ;AAEA,eAAe,eAAe,EAAE,OAAO,GAAkB;AACvD,QAAM,EAAE,KAAK,IAAI,MAAM;AACvB,QAAM,WAAW,sBAAQ,CAAC;AAE1B,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO,oBAAC,iBAAc;AAAA,EACxB;AAEA,MAAI,SAAS,CAAC,MAAM,UAAU;AAC5B,WAAO,oBAAC,cAAW;AAAA,EACrB;AAEA,MAAI,SAAS,CAAC,MAAM,QAAQ;AAC1B,WAAO,oBAAC,YAAS;AAAA,EACnB;AAEA,MAAI,SAAS,CAAC,MAAM,SAAS;AAC3B,UAAM,iBAAiB,SAAS,UAAU,IAAI,SAAS,CAAC,IAAI;AAC5D,WAAO,oBAAC,aAAU,gBAAgC;AAAA,EACpD;AAEA,MAAI,SAAS,CAAC,MAAM,iBAAiB;AACnC,QAAI,SAAS,WAAW,GAAG;AACzB,aAAO,oBAAC,oBAAiB;AAAA,IAC3B;AACA,UAAM,CAAC,EAAEA,KAAI,IAAI;AACjB,WAAO,oBAAC,mBAAgB,MAAMA,OAAM;AAAA,EACtC;AAEA,MAAI,SAAS,WAAW,GAAG;AACzB,UAAM,CAACA,KAAI,IAAI;AACf,WAAO,oBAAC,kBAAe,QAAQ,QAAQ,QAAQ,EAAE,MAAAA,MAAK,CAAC,GAAG;AAAA,EAC5D;AAEA,QAAM,CAAC,MAAM,EAAE,IAAI;AACnB,SAAO,oBAAC,aAAU,QAAQ,QAAQ,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG;AAC3D;","names":["type"]}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import "../chunk-2NMEKWO5.js";
2
+ import "../chunk-B5LE2OEC.js";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  import { createContext, useCallback, useContext, useEffect, useState } from "react";
5
5
  import { THEME_COOKIE } from "./theme";
@@ -0,0 +1,16 @@
1
+ export type AgentClientStatus = {
2
+ enabled: false;
3
+ } | {
4
+ enabled: true;
5
+ provider: 'anthropic' | 'openai' | 'local';
6
+ model: string;
7
+ };
8
+ /**
9
+ * Server-side check exposed to the admin client (Header nav link).
10
+ *
11
+ * Never returns the API key. Returns `{ enabled: false }` when the chat is
12
+ * disabled, so the client can hide the nav link without learning *why* —
13
+ * mirroring the route-handler 404.
14
+ */
15
+ export declare function getAgentClientStatus(): Promise<AgentClientStatus>;
16
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../admin/actions/agent.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,iBAAiB,GACzB;IAAE,OAAO,EAAE,KAAK,CAAA;CAAE,GAClB;IACE,OAAO,EAAE,IAAI,CAAC;IACd,QAAQ,EAAE,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC3C,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEN;;;;;;GAMG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAOvE"}
@@ -0,0 +1,15 @@
1
+ "use server";
2
+ import "../../chunk-B5LE2OEC.js";
3
+ import { getAgentConfig } from "../../agent/configStore";
4
+ import { getAgentStatus, isAgentEnabled } from "../../agent/featureFlag";
5
+ async function getAgentClientStatus() {
6
+ const cfg = getAgentConfig();
7
+ if (!cfg || !isAgentEnabled(cfg)) return { enabled: false };
8
+ const status = getAgentStatus(cfg);
9
+ if (!status.enabled) return { enabled: false };
10
+ return { enabled: true, provider: cfg.provider.type, model: cfg.provider.model };
11
+ }
12
+ export {
13
+ getAgentClientStatus
14
+ };
15
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../admin/actions/agent.ts"],"sourcesContent":["'use server';\n\nimport { getAgentConfig } from '../../agent/configStore';\nimport { getAgentStatus, isAgentEnabled } from '../../agent/featureFlag';\n\nexport type AgentClientStatus =\n | { enabled: false }\n | {\n enabled: true;\n provider: 'anthropic' | 'openai' | 'local';\n model: string;\n };\n\n/**\n * Server-side check exposed to the admin client (Header nav link).\n *\n * Never returns the API key. Returns `{ enabled: false }` when the chat is\n * disabled, so the client can hide the nav link without learning *why* —\n * mirroring the route-handler 404.\n */\nexport async function getAgentClientStatus(): Promise<AgentClientStatus> {\n const cfg = getAgentConfig();\n if (!cfg || !isAgentEnabled(cfg)) return { enabled: false };\n // Recompute via getAgentStatus so we exercise the same code path the route uses.\n const status = getAgentStatus(cfg);\n if (!status.enabled) return { enabled: false };\n return { enabled: true, provider: cfg.provider.type, model: cfg.provider.model };\n}\n"],"mappings":";;AAEA,SAAS,sBAAsB;AAC/B,SAAS,gBAAgB,sBAAsB;AAiB/C,eAAsB,uBAAmD;AACvE,QAAM,MAAM,eAAe;AAC3B,MAAI,CAAC,OAAO,CAAC,eAAe,GAAG,EAAG,QAAO,EAAE,SAAS,MAAM;AAE1D,QAAM,SAAS,eAAe,GAAG;AACjC,MAAI,CAAC,OAAO,QAAS,QAAO,EAAE,SAAS,MAAM;AAC7C,SAAO,EAAE,SAAS,MAAM,UAAU,IAAI,SAAS,MAAM,OAAO,IAAI,SAAS,MAAM;AACjF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../admin/actions/build.ts"],"names":[],"mappings":"AAaA,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAOjE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,2FAA2F;IAC3F,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AA0FF,eAAO,MAAM,UAAU,GAAU,kBAAkB,MAAM,EAAE,UAAU,iBAAiB,KAAG,OAAO,CAAC,YAAY,CAyB5G,CAAC"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../admin/actions/build.ts"],"names":[],"mappings":"AAaA,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAOjE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,2FAA2F;IAC3F,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AA0FF,eAAO,MAAM,UAAU,GAAU,kBAAkB,MAAM,EAAE,UAAU,iBAAiB,KAAG,OAAO,CAAC,YAAY,CAmC5G,CAAC"}
@@ -1,9 +1,9 @@
1
1
  "use server";
2
- import "../../chunk-2NMEKWO5.js";
2
+ import "../../chunk-B5LE2OEC.js";
3
3
  import fsPromises from "fs/promises";
4
4
  import path from "path";
5
5
  import { glob } from "glob";
6
- import { revalidatePath, updateTag } from "next/cache";
6
+ import { revalidatePath, revalidateTag, updateTag } from "next/cache";
7
7
  import { getConfig } from "../../lib/configStore";
8
8
  import { companionMarkdownPathsForEntry, companionRichTextPathsForEntry } from "../../lib/companionMarkdown";
9
9
  import { buildSearchIndex } from "../../lib/searchIndex";
@@ -85,7 +85,11 @@ const buildJsons = async (_editedFileName, options) => {
85
85
  var _a;
86
86
  try {
87
87
  for (const tag of PUBLIC_CACHE_TAGS) {
88
- updateTag(tag);
88
+ try {
89
+ updateTag(tag);
90
+ } catch (e) {
91
+ revalidateTag(tag, { expire: 0 });
92
+ }
89
93
  }
90
94
  revalidatePath("/", "layout");
91
95
  revalidatePath("/blog", "page");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../admin/actions/build.ts"],"sourcesContent":["'use server';\n\nimport fsPromises from 'fs/promises';\nimport path from 'path';\n\nimport { glob } from 'glob';\nimport { revalidatePath, updateTag } from 'next/cache';\n\nimport { getConfig } from '../../lib/configStore';\nimport { companionMarkdownPathsForEntry, companionRichTextPathsForEntry } from '../../lib/companionMarkdown';\nimport { buildSearchIndex, type EntryForSearch } from '../../lib/searchIndex';\n\nimport { isProductionMode, saveGitHubFile } from '../github';\nimport { actionErr, actionOk, type ActionResult } from './utils';\n\n/** Cache tags used by `getHomePage` / `getBlog` / `getPublishedPosts` in `src/app/cms/ssr/getPageContent.ts`. */\nconst PUBLIC_CACHE_TAGS = ['homePage', 'blog'] as const;\n\nconst SEARCH_INDEX_FILE_PATH = 'cms/__generated__/search-index.json';\n\nexport type BuildJsonsOptions = {\n /** Slug-based `/blog/...` paths to revalidate in addition to the dynamic route segment. */\n blogPaths?: string[];\n};\n\n/** Helper: gather all searchable entries from the filesystem. */\nasync function getEntriesForPublicSearch(): Promise<EntryForSearch[]> {\n const config = getConfig();\n const publicCollections = config.search?.publicCollections;\n if (!publicCollections || Object.keys(publicCollections).length === 0) {\n return [];\n }\n\n const files = await glob(`${config.contentFolder}/**/*.json`);\n const entries: EntryForSearch[] = [];\n\n for (const file of files) {\n const normalized = file.replace(/\\\\/g, '/');\n // Skip media entries\n if (normalized.includes('/media/')) continue;\n\n try {\n const filePath = path.join(process.cwd(), normalized);\n const data = await fsPromises.readFile(filePath, { encoding: 'utf8' });\n const content = JSON.parse(data) as Record<string, unknown>;\n const sys = content.sys as { type?: string } | undefined;\n const type = sys?.type;\n\n // Only include entries from publicCollections\n if (!type || !(type in publicCollections)) continue;\n\n // Read companion markdown/richtext files\n const companions: Record<string, string> = {};\n if (type) {\n const mdPaths = companionMarkdownPathsForEntry(normalized, type, config.collections);\n for (const [fieldName, mdPath] of Object.entries(mdPaths)) {\n try {\n const mdFilePath = path.join(process.cwd(), mdPath);\n companions[fieldName] = await fsPromises.readFile(mdFilePath, { encoding: 'utf8' });\n } catch {\n companions[fieldName] = '';\n }\n }\n const rtPaths = companionRichTextPathsForEntry(normalized, type, config.collections);\n for (const [fieldName, rtPath] of Object.entries(rtPaths)) {\n try {\n const rtFilePath = path.join(process.cwd(), rtPath);\n companions[fieldName] = await fsPromises.readFile(rtFilePath, { encoding: 'utf8' });\n } catch {\n companions[fieldName] = '';\n }\n }\n }\n\n entries.push({\n path: normalized.replace(`${config.contentFolder}/`, ''),\n content,\n companionContent: companions,\n });\n } catch {\n // Skip unreadable files\n }\n }\n\n return entries;\n}\n\n/** Build and write the public search index. */\nasync function buildAndWriteSearchIndex(): Promise<void> {\n const config = getConfig();\n const publicCollections = config.search?.publicCollections;\n if (!publicCollections || Object.keys(publicCollections).length === 0) {\n return;\n }\n\n try {\n const entries = await getEntriesForPublicSearch();\n const indexJson = buildSearchIndex(entries, config, Object.keys(publicCollections));\n\n if (isProductionMode()) {\n // Write to GitHub\n await saveGitHubFile(SEARCH_INDEX_FILE_PATH, indexJson, 'CMS: update search index');\n } else {\n // Write to local filesystem\n const filePath = path.join(process.cwd(), SEARCH_INDEX_FILE_PATH);\n await fsPromises.mkdir(path.dirname(filePath), { recursive: true });\n await fsPromises.writeFile(filePath, indexJson, 'utf8');\n }\n } catch {\n // Silently fail search index generation to not block the build\n }\n}\n\nexport const buildJsons = async (_editedFileName?: string, options?: BuildJsonsOptions): Promise<ActionResult> => {\n try {\n for (const tag of PUBLIC_CACHE_TAGS) {\n updateTag(tag);\n }\n\n revalidatePath('/', 'layout');\n revalidatePath('/blog', 'page');\n revalidatePath('/blog/[slug]', 'page');\n\n const seen = new Set<string>();\n for (const p of options?.blogPaths ?? []) {\n if (typeof p === 'string' && p.startsWith('/blog/') && !seen.has(p)) {\n seen.add(p);\n revalidatePath(p);\n }\n }\n\n // Build and write the public search index\n await buildAndWriteSearchIndex();\n\n return actionOk();\n } catch (e) {\n return actionErr(e);\n }\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../admin/actions/build.ts"],"sourcesContent":["'use server';\n\nimport fsPromises from 'fs/promises';\nimport path from 'path';\n\nimport { glob } from 'glob';\nimport { revalidatePath, revalidateTag, updateTag } from 'next/cache';\n\nimport { getConfig } from '../../lib/configStore';\nimport { companionMarkdownPathsForEntry, companionRichTextPathsForEntry } from '../../lib/companionMarkdown';\nimport { buildSearchIndex, type EntryForSearch } from '../../lib/searchIndex';\n\nimport { isProductionMode, saveGitHubFile } from '../github';\nimport { actionErr, actionOk, type ActionResult } from './utils';\n\n/** Cache tags used by `getHomePage` / `getBlog` / `getPublishedPosts` in `src/app/cms/ssr/getPageContent.ts`. */\nconst PUBLIC_CACHE_TAGS = ['homePage', 'blog'] as const;\n\nconst SEARCH_INDEX_FILE_PATH = 'cms/__generated__/search-index.json';\n\nexport type BuildJsonsOptions = {\n /** Slug-based `/blog/...` paths to revalidate in addition to the dynamic route segment. */\n blogPaths?: string[];\n};\n\n/** Helper: gather all searchable entries from the filesystem. */\nasync function getEntriesForPublicSearch(): Promise<EntryForSearch[]> {\n const config = getConfig();\n const publicCollections = config.search?.publicCollections;\n if (!publicCollections || Object.keys(publicCollections).length === 0) {\n return [];\n }\n\n const files = await glob(`${config.contentFolder}/**/*.json`);\n const entries: EntryForSearch[] = [];\n\n for (const file of files) {\n const normalized = file.replace(/\\\\/g, '/');\n // Skip media entries\n if (normalized.includes('/media/')) continue;\n\n try {\n const filePath = path.join(process.cwd(), normalized);\n const data = await fsPromises.readFile(filePath, { encoding: 'utf8' });\n const content = JSON.parse(data) as Record<string, unknown>;\n const sys = content.sys as { type?: string } | undefined;\n const type = sys?.type;\n\n // Only include entries from publicCollections\n if (!type || !(type in publicCollections)) continue;\n\n // Read companion markdown/richtext files\n const companions: Record<string, string> = {};\n if (type) {\n const mdPaths = companionMarkdownPathsForEntry(normalized, type, config.collections);\n for (const [fieldName, mdPath] of Object.entries(mdPaths)) {\n try {\n const mdFilePath = path.join(process.cwd(), mdPath);\n companions[fieldName] = await fsPromises.readFile(mdFilePath, { encoding: 'utf8' });\n } catch {\n companions[fieldName] = '';\n }\n }\n const rtPaths = companionRichTextPathsForEntry(normalized, type, config.collections);\n for (const [fieldName, rtPath] of Object.entries(rtPaths)) {\n try {\n const rtFilePath = path.join(process.cwd(), rtPath);\n companions[fieldName] = await fsPromises.readFile(rtFilePath, { encoding: 'utf8' });\n } catch {\n companions[fieldName] = '';\n }\n }\n }\n\n entries.push({\n path: normalized.replace(`${config.contentFolder}/`, ''),\n content,\n companionContent: companions,\n });\n } catch {\n // Skip unreadable files\n }\n }\n\n return entries;\n}\n\n/** Build and write the public search index. */\nasync function buildAndWriteSearchIndex(): Promise<void> {\n const config = getConfig();\n const publicCollections = config.search?.publicCollections;\n if (!publicCollections || Object.keys(publicCollections).length === 0) {\n return;\n }\n\n try {\n const entries = await getEntriesForPublicSearch();\n const indexJson = buildSearchIndex(entries, config, Object.keys(publicCollections));\n\n if (isProductionMode()) {\n // Write to GitHub\n await saveGitHubFile(SEARCH_INDEX_FILE_PATH, indexJson, 'CMS: update search index');\n } else {\n // Write to local filesystem\n const filePath = path.join(process.cwd(), SEARCH_INDEX_FILE_PATH);\n await fsPromises.mkdir(path.dirname(filePath), { recursive: true });\n await fsPromises.writeFile(filePath, indexJson, 'utf8');\n }\n } catch {\n // Silently fail search index generation to not block the build\n }\n}\n\nexport const buildJsons = async (_editedFileName?: string, options?: BuildJsonsOptions): Promise<ActionResult> => {\n try {\n for (const tag of PUBLIC_CACHE_TAGS) {\n // `updateTag` gives read-your-own-writes inside a Server Action (the\n // editor save path). When called from a Route Handler — e.g. the\n // proposal accept endpoint at `/api/agent/proposals/accept` — the\n // runtime throws (\"updateTag can only be called from within a Server\n // Action\"); fall back to `revalidateTag` with immediate expiry, which\n // is allowed everywhere and produces the same fresh-data outcome.\n try {\n updateTag(tag);\n } catch {\n revalidateTag(tag, { expire: 0 });\n }\n }\n\n revalidatePath('/', 'layout');\n revalidatePath('/blog', 'page');\n revalidatePath('/blog/[slug]', 'page');\n\n const seen = new Set<string>();\n for (const p of options?.blogPaths ?? []) {\n if (typeof p === 'string' && p.startsWith('/blog/') && !seen.has(p)) {\n seen.add(p);\n revalidatePath(p);\n }\n }\n\n // Build and write the public search index\n await buildAndWriteSearchIndex();\n\n return actionOk();\n } catch (e) {\n return actionErr(e);\n }\n};\n"],"mappings":"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","names":[]}
@@ -0,0 +1,22 @@
1
+ import { type FieldDiff } from '../../lib/entryDiff';
2
+ export type EntryDiff = {
3
+ changed: boolean;
4
+ activeBranch: string;
5
+ baseBranch: string;
6
+ /** Per-field diffs derived from the entry JSON `fields` object. */
7
+ fields: Record<string, FieldDiff>;
8
+ /** Raw before/after text for companion markdown/richtext files, keyed by field name. */
9
+ companions: Record<string, {
10
+ before: string | null;
11
+ after: string | null;
12
+ }>;
13
+ /** Resolved `/media/<uuid>.<ext>` URLs for image UUIDs appearing on either side of the diff. */
14
+ imageUrls: Record<string, string>;
15
+ };
16
+ /**
17
+ * Compute the diff between the currently active feature branch and the base branch for a
18
+ * single entry's files (JSON + companion `.md` / `.mdx`). Read-only, best-effort: any failure
19
+ * resolves to an empty diff so the UI never throws.
20
+ */
21
+ export declare const getEntryDiff: (filePath: string) => Promise<EntryDiff>;
22
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../../admin/actions/diff.ts"],"names":[],"mappings":"AAOA,OAAO,EAAmC,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAOtF,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,wFAAwF;IACxF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IAC5E,gGAAgG;IAChG,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC,CAAC;AA8CF;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,SAAS,CA0GtE,CAAC"}
@@ -0,0 +1,131 @@
1
+ "use server";
2
+ import "../../chunk-B5LE2OEC.js";
3
+ import { execFile } from "node:child_process";
4
+ import fsPromises from "node:fs/promises";
5
+ import { getConfig } from "../../lib/configStore";
6
+ import { companionFilePathsForEntry } from "../../lib/companionMarkdown";
7
+ import { diffEntryFields, safeParseEntry } from "../../lib/entryDiff";
8
+ import { logCmsServerError } from "../../lib/cmsServerLog";
9
+ import { parseFileName } from "../../utils/parseFileName";
10
+ import { getGitHubFile, isProductionMode } from "../github";
11
+ import { getBranch } from "./git";
12
+ import { getErrorMessage } from "./utils";
13
+ const emptyDiff = (activeBranch = "", baseBranch = "") => ({
14
+ changed: false,
15
+ activeBranch,
16
+ baseBranch,
17
+ fields: {},
18
+ companions: {},
19
+ imageUrls: {}
20
+ });
21
+ async function readFileAtRef(filePath, ref, isProd) {
22
+ if (isProd) {
23
+ const result = await getGitHubFile(filePath, ref);
24
+ return result ? result.content : null;
25
+ }
26
+ return await readFileAtGitRef(filePath, ref);
27
+ }
28
+ function readFileAtGitRef(filePath, ref) {
29
+ return new Promise((resolve) => {
30
+ execFile("git", ["show", `${ref}:${filePath}`], { maxBuffer: 10 * 1024 * 1024 }, (error, stdout) => {
31
+ if (error) {
32
+ resolve(null);
33
+ return;
34
+ }
35
+ resolve(stdout.toString());
36
+ });
37
+ });
38
+ }
39
+ async function readWorkingTreeFile(filePath) {
40
+ try {
41
+ return await fsPromises.readFile(filePath, "utf-8");
42
+ } catch (e) {
43
+ return null;
44
+ }
45
+ }
46
+ const getEntryDiff = async (filePath) => {
47
+ if (!filePath) return emptyDiff();
48
+ try {
49
+ const config = getConfig();
50
+ const baseBranch = config.git.baseBranch;
51
+ const activeBranch = await getBranch();
52
+ const isProd = isProductionMode();
53
+ if (!activeBranch || activeBranch === baseBranch) {
54
+ return emptyDiff(activeBranch, baseBranch);
55
+ }
56
+ const { type: collectionType } = parseFileName(filePath);
57
+ const [afterJson, beforeJson] = await Promise.all([
58
+ isProd ? readFileAtRef(filePath, activeBranch, true) : readWorkingTreeFile(filePath),
59
+ readFileAtRef(filePath, baseBranch, isProd)
60
+ ]);
61
+ const fields = diffEntryFields(safeParseEntry(beforeJson), safeParseEntry(afterJson));
62
+ const companionPaths = companionFilePathsForEntry(filePath, collectionType, config.collections);
63
+ const companionEntries = Object.entries(companionPaths);
64
+ const companionResults = await Promise.all(
65
+ companionEntries.map(async ([fieldName, compPath]) => {
66
+ const [after, before] = await Promise.all([
67
+ isProd ? readFileAtRef(compPath, activeBranch, true) : readWorkingTreeFile(compPath),
68
+ readFileAtRef(compPath, baseBranch, isProd)
69
+ ]);
70
+ return [fieldName, { before, after }];
71
+ })
72
+ );
73
+ const companions = {};
74
+ for (const [fieldName, payload] of companionResults) {
75
+ companions[fieldName] = payload;
76
+ }
77
+ const hasFieldChange = Object.values(fields).some((d) => d.kind !== "unchanged");
78
+ const hasCompanionChange = Object.values(companions).some((c) => {
79
+ var _a, _b;
80
+ return ((_a = c.before) != null ? _a : "") !== ((_b = c.after) != null ? _b : "");
81
+ });
82
+ const collectionDef = config.collections[collectionType];
83
+ const imageFieldNames = collectionDef ? Object.entries(collectionDef.fields).filter(([, f]) => f.format === "image").map(([name]) => name) : [];
84
+ const imageUuids = /* @__PURE__ */ new Set();
85
+ for (const name of imageFieldNames) {
86
+ const d = fields[name];
87
+ if (!d) continue;
88
+ if (d.kind === "added" && typeof d.after === "string") imageUuids.add(d.after);
89
+ else if (d.kind === "removed" && typeof d.before === "string") imageUuids.add(d.before);
90
+ else if (d.kind === "changed") {
91
+ if (typeof d.before === "string") imageUuids.add(d.before);
92
+ if (typeof d.after === "string") imageUuids.add(d.after);
93
+ }
94
+ }
95
+ const imageUrls = {};
96
+ if (imageUuids.size > 0) {
97
+ const mediaDir = `${config.contentFolder}/media`;
98
+ const resolvePairs = await Promise.all(
99
+ Array.from(imageUuids).map(async (uuid) => {
100
+ var _a, _b, _c;
101
+ if (!uuid || uuid.startsWith("/")) return [uuid, uuid];
102
+ let raw = (_a = await readFileAtRef(`${mediaDir}/media-${uuid}.json`, activeBranch, isProd)) != null ? _a : await readFileAtRef(`${mediaDir}/media-${uuid}.json`, baseBranch, isProd);
103
+ if (!raw) {
104
+ raw = (_b = await readFileAtRef(`${mediaDir}/${uuid}.json`, activeBranch, isProd)) != null ? _b : await readFileAtRef(`${mediaDir}/${uuid}.json`, baseBranch, isProd);
105
+ }
106
+ const parsed = safeParseEntry(raw);
107
+ const ext = parsed && typeof ((_c = parsed.fields) == null ? void 0 : _c.extension) === "string" ? parsed.fields.extension : "";
108
+ return [uuid, ext ? `/media/${uuid}.${ext}` : ""];
109
+ })
110
+ );
111
+ for (const [uuid, url] of resolvePairs) {
112
+ if (url) imageUrls[uuid] = url;
113
+ }
114
+ }
115
+ return {
116
+ changed: hasFieldChange || hasCompanionChange,
117
+ activeBranch,
118
+ baseBranch,
119
+ fields,
120
+ companions,
121
+ imageUrls
122
+ };
123
+ } catch (e) {
124
+ logCmsServerError({ operation: "getEntryDiff", message: getErrorMessage(e) });
125
+ return emptyDiff();
126
+ }
127
+ };
128
+ export {
129
+ getEntryDiff
130
+ };
131
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../admin/actions/diff.ts"],"sourcesContent":["'use server';\n\nimport { execFile } from 'node:child_process';\nimport fsPromises from 'node:fs/promises';\n\nimport { getConfig } from '../../lib/configStore';\nimport { companionFilePathsForEntry } from '../../lib/companionMarkdown';\nimport { diffEntryFields, safeParseEntry, type FieldDiff } from '../../lib/entryDiff';\nimport { logCmsServerError } from '../../lib/cmsServerLog';\nimport { parseFileName } from '../../utils/parseFileName';\nimport { getGitHubFile, isProductionMode } from '../github';\nimport { getBranch } from './git';\nimport { getErrorMessage } from './utils';\n\nexport type EntryDiff = {\n changed: boolean;\n activeBranch: string;\n baseBranch: string;\n /** Per-field diffs derived from the entry JSON `fields` object. */\n fields: Record<string, FieldDiff>;\n /** Raw before/after text for companion markdown/richtext files, keyed by field name. */\n companions: Record<string, { before: string | null; after: string | null }>;\n /** Resolved `/media/<uuid>.<ext>` URLs for image UUIDs appearing on either side of the diff. */\n imageUrls: Record<string, string>;\n};\n\nconst emptyDiff = (activeBranch = '', baseBranch = ''): EntryDiff => ({\n changed: false,\n activeBranch,\n baseBranch,\n fields: {},\n companions: {},\n imageUrls: {},\n});\n\n/**\n * Read a file at a specific git ref. Returns `null` if the file doesn't exist on that ref.\n * - Production: GitHub API via {@link getGitHubFile}.\n * - Dev: `git show <ref>:<path>` for committed content, or the working-tree file when the ref\n * matches the currently checked-out branch.\n */\nasync function readFileAtRef(filePath: string, ref: string, isProd: boolean): Promise<string | null> {\n if (isProd) {\n const result = await getGitHubFile(filePath, ref);\n return result ? result.content : null;\n }\n return await readFileAtGitRef(filePath, ref);\n}\n\nfunction readFileAtGitRef(filePath: string, ref: string): Promise<string | null> {\n return new Promise((resolve) => {\n execFile('git', ['show', `${ref}:${filePath}`], { maxBuffer: 10 * 1024 * 1024 }, (error, stdout) => {\n if (error) {\n // `git show` exits non-zero if the path doesn't exist on that ref.\n resolve(null);\n return;\n }\n resolve(stdout.toString());\n });\n });\n}\n\nasync function readWorkingTreeFile(filePath: string): Promise<string | null> {\n try {\n return await fsPromises.readFile(filePath, 'utf-8');\n } catch {\n return null;\n }\n}\n\n/**\n * Compute the diff between the currently active feature branch and the base branch for a\n * single entry's files (JSON + companion `.md` / `.mdx`). Read-only, best-effort: any failure\n * resolves to an empty diff so the UI never throws.\n */\nexport const getEntryDiff = async (filePath: string): Promise<EntryDiff> => {\n if (!filePath) return emptyDiff();\n\n try {\n const config = getConfig();\n const baseBranch = config.git.baseBranch;\n const activeBranch = await getBranch();\n const isProd = isProductionMode();\n\n // Same branch on both sides → no unmerged changes.\n if (!activeBranch || activeBranch === baseBranch) {\n return emptyDiff(activeBranch, baseBranch);\n }\n\n const { type: collectionType } = parseFileName(filePath);\n\n // --- Entry JSON ---------------------------------------------------------\n const [afterJson, beforeJson] = await Promise.all([\n isProd ? readFileAtRef(filePath, activeBranch, true) : readWorkingTreeFile(filePath),\n readFileAtRef(filePath, baseBranch, isProd),\n ]);\n\n const fields = diffEntryFields(safeParseEntry(beforeJson), safeParseEntry(afterJson));\n\n // --- Companion files ----------------------------------------------------\n const companionPaths = companionFilePathsForEntry(filePath, collectionType, config.collections);\n const companionEntries = Object.entries(companionPaths);\n\n const companionResults = await Promise.all(\n companionEntries.map(async ([fieldName, compPath]) => {\n const [after, before] = await Promise.all([\n isProd ? readFileAtRef(compPath, activeBranch, true) : readWorkingTreeFile(compPath),\n readFileAtRef(compPath, baseBranch, isProd),\n ]);\n return [fieldName, { before, after }] as const;\n }),\n );\n\n const companions: EntryDiff['companions'] = {};\n for (const [fieldName, payload] of companionResults) {\n companions[fieldName] = payload;\n }\n\n const hasFieldChange = Object.values(fields).some((d) => d.kind !== 'unchanged');\n const hasCompanionChange = Object.values(companions).some((c) => (c.before ?? '') !== (c.after ?? ''));\n\n // Resolve image UUIDs that changed on either side to `/media/<uuid>.<ext>` URLs.\n const collectionDef = (config.collections as Record<string, { fields: Record<string, { format?: string }> }>)[\n collectionType\n ];\n const imageFieldNames = collectionDef\n ? Object.entries(collectionDef.fields)\n .filter(([, f]) => f.format === 'image')\n .map(([name]) => name)\n : [];\n\n const imageUuids = new Set<string>();\n for (const name of imageFieldNames) {\n const d = fields[name];\n if (!d) continue;\n if (d.kind === 'added' && typeof d.after === 'string') imageUuids.add(d.after);\n else if (d.kind === 'removed' && typeof d.before === 'string') imageUuids.add(d.before);\n else if (d.kind === 'changed') {\n if (typeof d.before === 'string') imageUuids.add(d.before);\n if (typeof d.after === 'string') imageUuids.add(d.after);\n }\n }\n\n const imageUrls: Record<string, string> = {};\n if (imageUuids.size > 0) {\n const mediaDir = `${config.contentFolder}/media`;\n const resolvePairs = await Promise.all(\n Array.from(imageUuids).map(async (uuid) => {\n if (!uuid || uuid.startsWith('/')) return [uuid, uuid] as const;\n // Prefer the active-branch media entry; fall back to base branch.\n let raw =\n (await readFileAtRef(`${mediaDir}/media-${uuid}.json`, activeBranch, isProd)) ??\n (await readFileAtRef(`${mediaDir}/media-${uuid}.json`, baseBranch, isProd));\n if (!raw) {\n // Legacy path: {uuid}.json\n raw =\n (await readFileAtRef(`${mediaDir}/${uuid}.json`, activeBranch, isProd)) ??\n (await readFileAtRef(`${mediaDir}/${uuid}.json`, baseBranch, isProd));\n }\n const parsed = safeParseEntry(raw);\n const ext = parsed && typeof parsed.fields?.extension === 'string' ? (parsed.fields.extension as string) : '';\n return [uuid, ext ? `/media/${uuid}.${ext}` : ''] as const;\n }),\n );\n for (const [uuid, url] of resolvePairs) {\n if (url) imageUrls[uuid] = url;\n }\n }\n\n return {\n changed: hasFieldChange || hasCompanionChange,\n activeBranch,\n baseBranch,\n fields,\n companions,\n imageUrls,\n };\n } catch (e) {\n logCmsServerError({ operation: 'getEntryDiff', message: getErrorMessage(e) });\n return emptyDiff();\n }\n};\n"],"mappings":"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","names":[]}
@@ -1,5 +1,5 @@
1
1
  "use server";
2
- import "../../chunk-2NMEKWO5.js";
2
+ import "../../chunk-B5LE2OEC.js";
3
3
  import fsPromises from "fs/promises";
4
4
  import path from "path";
5
5
  import { getConfig } from "../../lib/configStore";
@@ -1 +1 @@
1
- {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../../admin/actions/files.ts"],"names":[],"mappings":"AA6BA,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,cAAc,EACpB,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAqK9C;;GAEG;AACH,eAAO,MAAM,sCAAsC,QAAa,OAAO,CAAC,IAAI,CAQ3E,CAAC;AAEF,eAAO,MAAM,4BAA4B,GAAU,UAAU,MAAM,EAAE,iBAAiB,MAAM,EAAE,UAAU,MAAM,kBAyB7G,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,aAAY,MAAa,sBA8B9D,CAAC;AAEF,eAAO,MAAM,aAAa,GAAU,SAAQ,MAAa,sBAqBxD,CAAC;AAEF,eAAO,MAAM,OAAO,GAAU,UAAU,MAAM,iBAgE7C,CAAC;AAqBF,eAAO,MAAM,QAAQ,GACnB,UAAU,GAAG,EACb,UAAU,MAAM,EAChB,UAAU;IAAE,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAE,KAC3C,OAAO,CAAC,cAAc,CAoJxB,CAAC;AAEF,eAAO,MAAM,OAAO,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,aAAa,CAiDjE,CAAC;AAEF,eAAO,MAAM,UAAU,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,YAAY,CA8DvE,CAAC"}
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../../admin/actions/files.ts"],"names":[],"mappings":"AA+BA,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,cAAc,EACpB,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AA6L9C;;GAEG;AACH,eAAO,MAAM,sCAAsC,QAAa,OAAO,CAAC,IAAI,CAQ3E,CAAC;AAEF,eAAO,MAAM,4BAA4B,GAAU,UAAU,MAAM,EAAE,iBAAiB,MAAM,EAAE,UAAU,MAAM,kBAyB7G,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,aAAY,MAAa,sBA8B9D,CAAC;AAEF,eAAO,MAAM,aAAa,GAAU,SAAQ,MAAa,sBAqBxD,CAAC;AAEF,eAAO,MAAM,OAAO,GAAU,UAAU,MAAM,iBAgE7C,CAAC;AAqBF,eAAO,MAAM,QAAQ,GACnB,UAAU,GAAG,EACb,UAAU,MAAM,EAChB,UAAU;IAAE,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAE,KAC3C,OAAO,CAAC,cAAc,CA4JxB,CAAC;AAEF,eAAO,MAAM,OAAO,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,aAAa,CAmDjE,CAAC;AAEF,eAAO,MAAM,UAAU,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,YAAY,CAgEvE,CAAC"}
@@ -2,12 +2,14 @@
2
2
  import {
3
3
  __spreadProps,
4
4
  __spreadValues
5
- } from "../../chunk-2NMEKWO5.js";
5
+ } from "../../chunk-B5LE2OEC.js";
6
6
  import fsPromises from "fs/promises";
7
7
  import path from "path";
8
8
  import { glob } from "glob";
9
9
  import { cookies } from "next/headers";
10
10
  import { getConfig } from "../../lib/configStore";
11
+ import { getAgentConfig } from "../../agent/configStore";
12
+ import { syncEmbeddingsAfterRemove, syncEmbeddingsAfterUpsert } from "../../agent/embeddingsHook";
11
13
  import { BRANCH_HISTORY_FILE_PATH, mergeHistoryContentWithAppendedEntry } from "../../lib/branchHistory";
12
14
  import { getPostBlogPublicPath } from "../../lib/blogPublicPath";
13
15
  import { companionMarkdownPathsForEntry, companionRichTextPathsForEntry } from "../../lib/companionMarkdown";
@@ -35,6 +37,17 @@ const CMS_ACTIVE_BRANCH_COOKIE = "cms-active-branch";
35
37
  function normalizeContentPath(p) {
36
38
  return p.replace(/\\/g, "/");
37
39
  }
40
+ async function syncEmbeddingsForUpsertIfEnabled(entryPath, payload, companions, branch, isProduction) {
41
+ const agentConfig = getAgentConfig();
42
+ if (!agentConfig) return;
43
+ const config = getConfig();
44
+ await syncEmbeddingsAfterUpsert({ agentConfig, config, entryPath, payload, companions, branch, isProduction });
45
+ }
46
+ async function syncEmbeddingsForRemoveIfEnabled(entryPath, branch, isProduction) {
47
+ const agentConfig = getAgentConfig();
48
+ if (!agentConfig) return;
49
+ await syncEmbeddingsAfterRemove({ agentConfig, entryPath, branch, isProduction });
50
+ }
38
51
  async function persistBranchHistoryEntryIfNeeded(activeBranch, entryPath) {
39
52
  var _a;
40
53
  if (!activeBranch) {
@@ -328,7 +341,13 @@ const saveFile = async (formData, fileName, options) => {
328
341
  }
329
342
  const strFields = {};
330
343
  for (const [k, v] of Object.entries(rawFields)) {
331
- strFields[k] = v == null ? "" : String(v);
344
+ if (v == null) {
345
+ strFields[k] = "";
346
+ } else if (typeof v === "object") {
347
+ strFields[k] = JSON.stringify(v);
348
+ } else {
349
+ strFields[k] = String(v);
350
+ }
332
351
  }
333
352
  const validated = validateEntryFields(entryType, strFields);
334
353
  if (!validated.ok) {
@@ -410,6 +429,7 @@ const saveFile = async (formData, fileName, options) => {
410
429
  });
411
430
  }
412
431
  await persistBranchHistoryEntryIfNeeded(activeBranch, fileName);
432
+ await syncEmbeddingsForUpsertIfEnabled(fileName, payload, markdownContents, activeBranch, true);
413
433
  const built2 = await buildJsons(fileName, { blogPaths });
414
434
  return built2.success ? actionOk() : built2;
415
435
  }
@@ -428,6 +448,7 @@ const saveFile = async (formData, fileName, options) => {
428
448
  await fsPromises.writeFile(path.join(process.cwd(), rtPath), rtContent, "utf8");
429
449
  }
430
450
  await persistBranchHistoryEntryIfNeeded(activeBranchDev, fileName);
451
+ await syncEmbeddingsForUpsertIfEnabled(fileName, payload, markdownContents, activeBranchDev, false);
431
452
  const built = await buildJsons(fileName, { blogPaths });
432
453
  return built.success ? actionOk() : built;
433
454
  } catch (e) {
@@ -465,6 +486,7 @@ const newFile = async (type) => {
465
486
  });
466
487
  }
467
488
  await persistBranchHistoryEntryIfNeeded(activeBranch, file);
489
+ await syncEmbeddingsForUpsertIfEnabled(file, values, {}, activeBranch, true);
468
490
  const built2 = await buildJsons(file);
469
491
  return built2.success ? { success: true, path: file } : { success: false, error: built2.error };
470
492
  }
@@ -473,6 +495,7 @@ const newFile = async (type) => {
473
495
  const filePath = path.join(process.cwd(), file);
474
496
  await fsPromises.writeFile(filePath, normalizedData, "utf8");
475
497
  await persistBranchHistoryEntryIfNeeded(activeBranchDev, file);
498
+ await syncEmbeddingsForUpsertIfEnabled(file, values, {}, activeBranchDev, false);
476
499
  const built = await buildJsons(file);
477
500
  return built.success ? { success: true, path: file } : { success: false, error: built.error };
478
501
  } catch (e) {
@@ -511,6 +534,7 @@ const removeFile = async (fileName) => {
511
534
  if (activeBranch) {
512
535
  applyMutation(activeBranch, { type: "delete", path: fileName });
513
536
  }
537
+ await syncEmbeddingsForRemoveIfEnabled(fileName, activeBranch, true);
514
538
  const built2 = await buildJsons(fileName, { blogPaths });
515
539
  return built2.success ? actionOk() : built2;
516
540
  }
@@ -522,6 +546,7 @@ const removeFile = async (fileName) => {
522
546
  } catch (e) {
523
547
  }
524
548
  }
549
+ await syncEmbeddingsForRemoveIfEnabled(fileName, void 0, false);
525
550
  const built = await buildJsons(fileName, { blogPaths });
526
551
  return built.success ? actionOk() : built;
527
552
  } catch (e) {