dineway 0.1.49 → 0.2.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 (434) hide show
  1. package/dist/activity-DUaz_w7p.mjs +79 -0
  2. package/dist/{activity-events-CwM7yxPW.mjs → activity-events-CJDvE2uc.mjs} +5 -113
  3. package/dist/actor-0QJ1Gbtf.mjs +37 -0
  4. package/dist/after-BfniwgIf.mjs +9 -0
  5. package/dist/{allowed-origins-CyGnbgBd.mjs → allowed-origins--OwHHiY8.mjs} +1 -1
  6. package/dist/api/route-utils.d.mts +9 -10
  7. package/dist/api/route-utils.mjs +16 -13
  8. package/dist/api/schemas/index.d.mts +2 -2
  9. package/dist/api/schemas/index.mjs +5 -4
  10. package/dist/{api-BMIxRIEN.mjs → api-B4PHIF4V.mjs} +93 -41
  11. package/dist/{api-tokens-DtvdtIkm.mjs → api-tokens-tbK_sORH.mjs} +6 -2
  12. package/dist/{apply-D_RlTYtC.mjs → apply-DjTqq6Ae.mjs} +117 -77
  13. package/dist/astro/image-endpoint.d.mts +7 -0
  14. package/dist/astro/image-endpoint.mjs +54 -0
  15. package/dist/astro/index.d.mts +34 -11
  16. package/dist/astro/index.mjs +163 -24
  17. package/dist/astro/integration/shims/use-sync-external-store-with-selector.js +71 -0
  18. package/dist/astro/integration/shims/use-sync-external-store.js +1 -0
  19. package/dist/astro/middleware/auth.d.mts +8 -18
  20. package/dist/astro/middleware/auth.mjs +42 -24
  21. package/dist/astro/middleware/redirect.mjs +13 -4
  22. package/dist/astro/middleware/request-context.mjs +8 -5
  23. package/dist/astro/middleware/seed.d.mts +1 -1
  24. package/dist/astro/middleware/seed.mjs +2 -2
  25. package/dist/astro/middleware/setup.mjs +1 -1
  26. package/dist/astro/middleware.mjs +389 -206
  27. package/dist/astro/routes/admin.astro +6 -1
  28. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +7 -6
  29. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +7 -6
  30. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +4 -4
  31. package/dist/astro/routes/api/admin/api-tokens/index.mjs +6 -6
  32. package/dist/astro/routes/api/admin/briefing.mjs +21 -17
  33. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +4 -4
  34. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +9 -8
  35. package/dist/astro/routes/api/admin/byline-fields/index.mjs +9 -8
  36. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +9 -8
  37. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +17 -14
  38. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +17 -14
  39. package/dist/astro/routes/api/admin/bylines/index.mjs +17 -14
  40. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +14 -12
  41. package/dist/astro/routes/api/admin/comments/_id_.mjs +6 -5
  42. package/dist/astro/routes/api/admin/comments/bulk.mjs +11 -9
  43. package/dist/astro/routes/api/admin/comments/counts.mjs +6 -5
  44. package/dist/astro/routes/api/admin/comments/index.mjs +11 -9
  45. package/dist/astro/routes/api/admin/context/_id_/history.mjs +27 -24
  46. package/dist/astro/routes/api/admin/context/_id_/index.mjs +27 -24
  47. package/dist/astro/routes/api/admin/context/_id_/review.mjs +32 -28
  48. package/dist/astro/routes/api/admin/context/_id_/supersede.mjs +32 -28
  49. package/dist/astro/routes/api/admin/context/diff.mjs +31 -27
  50. package/dist/astro/routes/api/admin/context/index.mjs +32 -28
  51. package/dist/astro/routes/api/admin/context/stale.mjs +31 -27
  52. package/dist/astro/routes/api/admin/hitl-requests/_id_/index.mjs +27 -24
  53. package/dist/astro/routes/api/admin/hitl-requests/_id_/resolve.mjs +31 -27
  54. package/dist/astro/routes/api/admin/hitl-requests/index.mjs +31 -27
  55. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +28 -25
  56. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +3 -3
  57. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +6 -6
  58. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +6 -6
  59. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +56 -51
  60. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +56 -51
  61. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +47 -43
  62. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +54 -49
  63. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +53 -48
  64. package/dist/astro/routes/api/admin/plugins/index.mjs +47 -43
  65. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +2 -2
  66. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +46 -42
  67. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +53 -48
  68. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +46 -42
  69. package/dist/astro/routes/api/admin/plugins/updates.mjs +46 -42
  70. package/dist/astro/routes/api/admin/review-requests/_id_/index.mjs +5 -5
  71. package/dist/astro/routes/api/admin/review-requests/_id_/resolve.mjs +32 -63
  72. package/dist/astro/routes/api/admin/review-requests/index.d.mts +2 -1
  73. package/dist/astro/routes/api/admin/review-requests/index.mjs +58 -10
  74. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +46 -42
  75. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +2 -2
  76. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +46 -42
  77. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +3 -3
  78. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +2 -2
  79. package/dist/astro/routes/api/admin/users/_id_/index.mjs +8 -7
  80. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +4 -4
  81. package/dist/astro/routes/api/admin/users/index.mjs +7 -6
  82. package/dist/astro/routes/api/auth/dev-bypass.mjs +4 -4
  83. package/dist/astro/routes/api/auth/invite/accept.mjs +2 -2
  84. package/dist/astro/routes/api/auth/invite/complete.mjs +12 -11
  85. package/dist/astro/routes/api/auth/invite/index.mjs +9 -8
  86. package/dist/astro/routes/api/auth/invite/register-options.mjs +11 -10
  87. package/dist/astro/routes/api/auth/logout.mjs +2 -2
  88. package/dist/astro/routes/api/auth/magic-link/send.mjs +11 -10
  89. package/dist/astro/routes/api/auth/magic-link/verify.mjs +3 -3
  90. package/dist/astro/routes/api/auth/me.mjs +9 -8
  91. package/dist/astro/routes/api/auth/mode.mjs +1 -1
  92. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +3 -3
  93. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  94. package/dist/astro/routes/api/auth/passkey/_id_.mjs +6 -5
  95. package/dist/astro/routes/api/auth/passkey/index.mjs +1 -1
  96. package/dist/astro/routes/api/auth/passkey/options.mjs +12 -11
  97. package/dist/astro/routes/api/auth/passkey/register/options.mjs +10 -9
  98. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +11 -10
  99. package/dist/astro/routes/api/auth/passkey/verify.mjs +11 -10
  100. package/dist/astro/routes/api/auth/setup-token/index.mjs +5 -5
  101. package/dist/astro/routes/api/auth/setup-token/verify.mjs +2 -2
  102. package/dist/astro/routes/api/auth/signup/complete.mjs +12 -11
  103. package/dist/astro/routes/api/auth/signup/request.mjs +11 -10
  104. package/dist/astro/routes/api/auth/signup/verify.mjs +2 -2
  105. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +15 -13
  106. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.d.mts +8 -0
  107. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +160 -0
  108. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +2 -2
  109. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +6 -5
  110. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +6 -5
  111. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +6 -5
  112. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +11 -10
  113. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +49 -20
  114. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +6 -5
  115. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +2 -2
  116. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +67 -32
  117. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +16 -14
  118. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +2 -2
  119. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +6 -5
  120. package/dist/astro/routes/api/content/_collection_/_id_.mjs +11 -9
  121. package/dist/astro/routes/api/content/_collection_/authors.mjs +2 -2
  122. package/dist/astro/routes/api/content/_collection_/index.mjs +11 -9
  123. package/dist/astro/routes/api/content/_collection_/trash.mjs +7 -6
  124. package/dist/astro/routes/api/dashboard.mjs +9 -8
  125. package/dist/astro/routes/api/dev/emails.mjs +2 -2
  126. package/dist/astro/routes/api/health.mjs +1 -1
  127. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  128. package/dist/astro/routes/api/import/probe.mjs +22 -10
  129. package/dist/astro/routes/api/import/wordpress/analyze.mjs +9 -6
  130. package/dist/astro/routes/api/import/wordpress/execute.d.mts +18 -1
  131. package/dist/astro/routes/api/import/wordpress/execute.mjs +85 -37
  132. package/dist/astro/routes/api/import/wordpress/media.d.mts +12 -1
  133. package/dist/astro/routes/api/import/wordpress/media.mjs +20 -14
  134. package/dist/astro/routes/api/import/wordpress/prepare.mjs +36 -32
  135. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +17 -1
  136. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +121 -100
  137. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  138. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +24 -12
  139. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +55 -2
  140. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +284 -55
  141. package/dist/astro/routes/api/manifest.mjs +14 -5
  142. package/dist/astro/routes/api/mcp.mjs +753 -170
  143. package/dist/astro/routes/api/media/_id_/confirm.mjs +38 -10
  144. package/dist/astro/routes/api/media/_id_.mjs +11 -7
  145. package/dist/astro/routes/api/media/file/_...key_.mjs +1 -1
  146. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +2 -2
  147. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +2 -2
  148. package/dist/astro/routes/api/media/providers/index.mjs +2 -2
  149. package/dist/astro/routes/api/media/upload-url.mjs +11 -10
  150. package/dist/astro/routes/api/media.mjs +28 -35
  151. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +32 -28
  152. package/dist/astro/routes/api/menus/_name_/items.mjs +32 -28
  153. package/dist/astro/routes/api/menus/_name_/reorder.mjs +32 -28
  154. package/dist/astro/routes/api/menus/_name_/translations.mjs +32 -28
  155. package/dist/astro/routes/api/menus/_name_.mjs +32 -28
  156. package/dist/astro/routes/api/menus/index.mjs +32 -28
  157. package/dist/astro/routes/api/oauth/authorize.mjs +7 -7
  158. package/dist/astro/routes/api/oauth/device/authorize.mjs +6 -6
  159. package/dist/astro/routes/api/oauth/device/code.mjs +9 -9
  160. package/dist/astro/routes/api/oauth/device/token.mjs +8 -8
  161. package/dist/astro/routes/api/oauth/register.mjs +4 -4
  162. package/dist/astro/routes/api/oauth/token/refresh.mjs +6 -6
  163. package/dist/astro/routes/api/oauth/token/revoke.mjs +6 -6
  164. package/dist/astro/routes/api/oauth/token.mjs +6 -6
  165. package/dist/astro/routes/api/openapi.json.mjs +4 -3
  166. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +46 -31
  167. package/dist/astro/routes/api/redirects/404s/index.mjs +11 -10
  168. package/dist/astro/routes/api/redirects/404s/summary.mjs +11 -10
  169. package/dist/astro/routes/api/redirects/_id_.mjs +33 -29
  170. package/dist/astro/routes/api/redirects/index.mjs +33 -29
  171. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +2 -2
  172. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +2 -2
  173. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +48 -43
  174. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +48 -43
  175. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +48 -43
  176. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +48 -43
  177. package/dist/astro/routes/api/schema/collections/index.mjs +48 -43
  178. package/dist/astro/routes/api/schema/index.mjs +14 -15
  179. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +46 -42
  180. package/dist/astro/routes/api/schema/orphans/index.mjs +46 -42
  181. package/dist/astro/routes/api/search/enable.mjs +11 -10
  182. package/dist/astro/routes/api/search/index.mjs +10 -9
  183. package/dist/astro/routes/api/search/rebuild.mjs +11 -10
  184. package/dist/astro/routes/api/search/stats.mjs +6 -6
  185. package/dist/astro/routes/api/search/suggest.mjs +10 -9
  186. package/dist/astro/routes/api/sections/_slug_.mjs +32 -28
  187. package/dist/astro/routes/api/sections/index.mjs +32 -28
  188. package/dist/astro/routes/api/settings/email.mjs +4 -4
  189. package/dist/astro/routes/api/settings.mjs +32 -28
  190. package/dist/astro/routes/api/setup/admin-verify.mjs +14 -13
  191. package/dist/astro/routes/api/setup/admin.mjs +12 -11
  192. package/dist/astro/routes/api/setup/dev-bypass.mjs +31 -25
  193. package/dist/astro/routes/api/setup/dev-reset.mjs +2 -2
  194. package/dist/astro/routes/api/setup/index.mjs +29 -25
  195. package/dist/astro/routes/api/setup/status.mjs +3 -3
  196. package/dist/astro/routes/api/snapshot.mjs +8 -7
  197. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +35 -31
  198. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +35 -31
  199. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +35 -31
  200. package/dist/astro/routes/api/taxonomies/index.mjs +35 -31
  201. package/dist/astro/routes/api/themes/preview.mjs +5 -5
  202. package/dist/astro/routes/api/typegen.mjs +4 -4
  203. package/dist/astro/routes/api/well-known/auth.mjs +3 -3
  204. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +3 -3
  205. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +3 -3
  206. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +31 -27
  207. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +32 -28
  208. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +32 -28
  209. package/dist/astro/routes/api/widget-areas/_name_.mjs +29 -26
  210. package/dist/astro/routes/api/widget-areas/index.mjs +32 -28
  211. package/dist/astro/routes/api/widget-components.mjs +2 -2
  212. package/dist/astro/routes/robots.txt.mjs +8 -7
  213. package/dist/astro/routes/sitemap-_collection_.xml.mjs +23 -14
  214. package/dist/astro/routes/sitemap.xml.mjs +9 -8
  215. package/dist/astro/session-driver.d.mts +1 -1
  216. package/dist/astro/session-driver.mjs +2 -2
  217. package/dist/astro/types.d.mts +22 -13
  218. package/dist/{audit-BeNsSyfU.mjs → audit-B2pRxZ20.mjs} +1 -1
  219. package/dist/auth/providers/github.d.mts +1 -1
  220. package/dist/auth/providers/google.d.mts +1 -1
  221. package/dist/{auth-control-guard-Dr14I98m.mjs → auth-control-guard-D71jourk.mjs} +1 -1
  222. package/dist/{authorize-BLO0m7fW.mjs → authorize-ZXPGPwKn.mjs} +1 -1
  223. package/dist/{briefing-CkTee1ex.mjs → briefing-0rf-su3-.mjs} +90 -28
  224. package/dist/{briefing-DJX6irto.mjs → briefing-kRhegBoF.mjs} +2 -1
  225. package/dist/bundle-CEcdUa1s.mjs +602 -0
  226. package/dist/{byline-BVC1lV6G.mjs → byline-7xR185Ly.mjs} +30 -62
  227. package/dist/{byline-fields-Cj39WhXC.mjs → byline-fields-BKzA0fJU.mjs} +1 -1
  228. package/dist/{byline-fields-uJlygdzM.d.mts → byline-fields-Ckeqd1OY.d.mts} +88 -35
  229. package/dist/{byline-fields-cNrLJVRs.mjs → byline-fields-WN7RQT4q.mjs} +10 -4
  230. package/dist/{byline-registry-4v6tXMNX.mjs → byline-registry-Ba54M74c.mjs} +2 -2
  231. package/dist/{bylines-LN9XISRo.mjs → bylines-C-EL6dh3.mjs} +9 -3
  232. package/dist/{bylines-DwokOFj6.mjs → bylines-CmZFCMr0.mjs} +5 -5
  233. package/dist/{cache-Bac05gBd.mjs → cache-DkVCKGio.mjs} +2 -2
  234. package/dist/{chunks-CuUt7K50.mjs → chunks-ChGNDY8r.mjs} +1 -1
  235. package/dist/cli/index.d.mts +29 -1
  236. package/dist/cli/index.mjs +1466 -1763
  237. package/dist/cli/plugin-kit.d.mts +75 -0
  238. package/dist/cli/plugin-kit.mjs +4 -0
  239. package/dist/client/external-auth-headers.d.mts +1 -1
  240. package/dist/client/index.d.mts +27 -52
  241. package/dist/client/index.mjs +34 -6
  242. package/dist/client-factory-BDD9azPJ.mjs +233 -0
  243. package/dist/{comment-Beue8-15.mjs → comment-DFALgsJD.mjs} +13 -3
  244. package/dist/comment-reaction-C37bf99u.mjs +58 -0
  245. package/dist/{comments-DcjFIfqX.mjs → comments-B3NwDBxl.mjs} +1 -1
  246. package/dist/{content-CBxYGWfL.mjs → content-DJcAYFhz.mjs} +51 -34
  247. package/dist/content-refresh-B4ZCmxgd.mjs +1576 -0
  248. package/dist/{context-Df1xVYyr.mjs → context-DnpXcp6Y.mjs} +2 -2
  249. package/dist/{context-CQVNZaR8.mjs → context-fSCYLL3c.mjs} +125 -53
  250. package/dist/{context-route-helpers-B9wj8Rmh.mjs → context-route-helpers-CI8XzcsK.mjs} +2 -1
  251. package/dist/{cron-DxCAU_Sn.mjs → cron-B1SL_lsb.mjs} +7 -3
  252. package/dist/{dashboard-B7ZUNuyF.mjs → dashboard-D0nj5oWg.mjs} +4 -4
  253. package/dist/db/index.d.mts +3 -3
  254. package/dist/db/index.mjs +1 -1
  255. package/dist/db/libsql.d.mts +1 -1
  256. package/dist/db/postgres.d.mts +1 -1
  257. package/dist/db/sqlite.d.mts +1 -1
  258. package/dist/{device-flow-BZVGftqi.mjs → device-flow-BJe6VEhP.mjs} +5 -5
  259. package/dist/{placeholder-d54Qr_7n.mjs → enrich-Ck9tfMqe.mjs} +36 -9
  260. package/dist/{error-DCSuUAZW.mjs → error-CSVaQNZy.mjs} +5 -0
  261. package/dist/{experimental-workflows-CSMffP6q.mjs → experimental-workflows-GVhUgzEs.mjs} +1 -1
  262. package/dist/field-defs-cache-DL-T2XVS.mjs +49 -0
  263. package/dist/forgeway-seo-client-G5ddhVHd.mjs +456 -0
  264. package/dist/{fts-manager-B5l_qwrA.mjs → fts-manager-ewTGohf4.mjs} +1 -1
  265. package/dist/{hitl-requests-7NlzVeUA.mjs → hitl-requests-DEFj8e6u.mjs} +2 -2
  266. package/dist/{hitl-route-helpers-k---_H3-.mjs → hitl-route-helpers-C23JHaWz.mjs} +5 -4
  267. package/dist/import-CXXL5pip.mjs +1354 -0
  268. package/dist/index-DcnOCD1e.d.mts +375 -0
  269. package/dist/index.d.mts +15 -16
  270. package/dist/index.mjs +85 -70
  271. package/dist/{jsonld-DZ67souc.d.mts → jsonld-DzKbhRZ4.d.mts} +8 -4
  272. package/dist/{load-D9OiGr2m.mjs → load-CFtJRT3c.mjs} +1 -1
  273. package/dist/{loader--GOYux8M.mjs → loader-aWkkc1_o.mjs} +117 -31
  274. package/dist/{manifest-schema-qh2P7RDX.mjs → manifest-schema-uA6pRFXi.mjs} +38 -1
  275. package/dist/mcp-reviewed-executor-Dn52L_yY.mjs +558 -0
  276. package/dist/media/image-endpoint.d.mts +32 -0
  277. package/dist/media/image-endpoint.mjs +111 -0
  278. package/dist/media/index.d.mts +27 -2
  279. package/dist/media/index.mjs +5 -3
  280. package/dist/media/local-runtime.d.mts +15 -11
  281. package/dist/media/local-runtime.mjs +9 -7
  282. package/dist/{media-CbKyYukG.mjs → media-CVMOoywq.mjs} +3 -1
  283. package/dist/{media-allowlist-BYxJIcTO.mjs → media-allowlist-zDNJmXCo.mjs} +1 -1
  284. package/dist/media-url-BdoLPvg8.mjs +20 -0
  285. package/dist/{menus-C7F0sCrC.mjs → menus-CCG2z5um.mjs} +80 -15
  286. package/dist/{menus-BZbXf-ej.mjs → menus-CmyIkRG5.mjs} +19 -5
  287. package/dist/{normalize-ByemhhfW.mjs → normalize-Cyt7JdF7.mjs} +8 -1
  288. package/dist/{oauth-authorization-DF-LCsIA.mjs → oauth-authorization-B9H7X85L.mjs} +5 -5
  289. package/dist/{oauth-clients-Du-V0fEm.mjs → oauth-clients-Dwl32-Uj.mjs} +2 -2
  290. package/dist/object-cache/memory.d.mts +14 -0
  291. package/dist/object-cache/memory.mjs +55 -0
  292. package/dist/object-cache-D51qOseS.mjs +419 -0
  293. package/dist/output-DhBe5_Pi.mjs +68 -0
  294. package/dist/page/index.d.mts +10 -3
  295. package/dist/page/index.mjs +2 -2
  296. package/dist/{parse-CneSgl7-.mjs → parse-i15EFSAE.mjs} +1 -1
  297. package/dist/{parser-DxfsARXL.mjs → parser-06LLLL4E.mjs} +151 -9
  298. package/dist/{placeholder-CXfoCtCd.d.mts → placeholder-DkWkXfDI.d.mts} +12 -4
  299. package/dist/plugin-utils.d.mts +8 -9
  300. package/dist/plugins/adapt-sandbox-entry.d.mts +8 -9
  301. package/dist/plugins/adapt-sandbox-entry.mjs +13 -2
  302. package/dist/{plugins-DzfqRREq.mjs → plugins-CPA2PtfY.mjs} +919 -66
  303. package/dist/{transport-LSdZVXHF.mjs → portable-text-BASHceim.mjs} +1 -134
  304. package/dist/portable-text-E79LyjGo.d.mts +45 -0
  305. package/dist/{preview-C-3YTX2U.mjs → preview-BjedZm8G.mjs} +4 -3
  306. package/dist/process-cache-CCDgti7j.mjs +106 -0
  307. package/dist/project-env-DKibmuP8.mjs +95 -0
  308. package/dist/{provider-loader-9it4vd6L.d.mts → provider-loader-DC2JdWeO.d.mts} +1 -1
  309. package/dist/{public-url-B4xV4rGa.d.mts → public-url-DQJCnYi9.d.mts} +1 -1
  310. package/dist/publication-authorization-RKiHXKtq.mjs +985 -0
  311. package/dist/{query-CZ3TH_Uu.mjs → query-C2U5u5_p.mjs} +11 -6
  312. package/dist/{query-Ds0EnMFX.mjs → query-DEv5x6yB.mjs} +281 -76
  313. package/dist/{rate-limit-i0G3IAOX.mjs → rate-limit-DglsAJSw.mjs} +2 -2
  314. package/dist/{redirect-CEACczxo.mjs → redirect-ubhEqQCQ.mjs} +2 -2
  315. package/dist/{redirects-ocRJmQHP.mjs → redirects-Bhpm8bRe.mjs} +35 -19
  316. package/dist/{redirects-DYj1yPxs.mjs → redirects-xs2yahLq.mjs} +47 -24
  317. package/dist/{registry-D7HACema.mjs → registry-BYYyb2tF.mjs} +148 -81
  318. package/dist/request-context.d.mts +2 -0
  319. package/dist/{request-meta-DAb6xaP9.mjs → request-meta-CFe1tW2M.mjs} +1 -1
  320. package/dist/review-payload-BysRWpxS.mjs +111 -0
  321. package/dist/{review-requests-BW2NxY-l.mjs → review-requests-CTWGnWUt.mjs} +1 -1
  322. package/dist/review-requests-D42VEP1l.mjs +142 -0
  323. package/dist/review-route-helpers-C31vO6SI.mjs +41 -0
  324. package/dist/runner-BgmttQmD.mjs +7444 -0
  325. package/dist/{runner-09sTqtv0.d.mts → runner-D6hzs8L9.d.mts} +1 -1
  326. package/dist/runtime.d.mts +9 -10
  327. package/dist/runtime.mjs +3 -3
  328. package/dist/schema-DUtnZxjZ.mjs +8 -0
  329. package/dist/{search-Gdrqj582.mjs → search-DUKgZUlm.mjs} +5 -3
  330. package/dist/{secrets-CeGpBFV2.mjs → secrets-ZV5rd8yV.mjs} +14 -11
  331. package/dist/{sections-BOjU13Y-.mjs → sections-DvFgsnda.mjs} +2 -2
  332. package/dist/seed/index.d.mts +2 -2
  333. package/dist/seed/index.mjs +21 -18
  334. package/dist/seo/index.d.mts +1 -1
  335. package/dist/seo/index.mjs +3 -12
  336. package/dist/{seo-5lJOtB5J.mjs → seo-BLszyJxd.mjs} +22 -4
  337. package/dist/{seo-CLj8lS7Q.mjs → seo-BU8MLCS9.mjs} +5 -2
  338. package/dist/{seo-contributions-CqVvReEj.mjs → seo-contributions-GnCuL1ML.mjs} +11 -3
  339. package/dist/{service-jGlhrICs.mjs → service-FL3fB0Rx.mjs} +2 -2
  340. package/dist/session-user-Ct6GBLvn.mjs +22 -0
  341. package/dist/{settings-CUXOxzsT.mjs → settings-BECcAIRH.mjs} +28 -55
  342. package/dist/{settings-DlBsT2VS.mjs → settings-EzADu-dd.mjs} +2 -2
  343. package/dist/{setup-complete-BRrdPYjZ.mjs → setup-complete-Da0axZEE.mjs} +1 -1
  344. package/dist/{site-activity-DONFrMBJ.mjs → site-activity-h8smOlYI.mjs} +1 -1
  345. package/dist/{site-context-C8Az_P_I.mjs → site-context-B8T1kpUP.mjs} +337 -530
  346. package/dist/{site-url-DIMD68go.mjs → site-url-DJEid0ml.mjs} +1 -1
  347. package/dist/stable-hash-DshcXvRE.mjs +19 -0
  348. package/dist/status-NqWOSFAD.mjs +21 -0
  349. package/dist/storage/local.d.mts +1 -1
  350. package/dist/storage/local.mjs +1 -1
  351. package/dist/storage/s3.d.mts +1 -1
  352. package/dist/storage/s3.mjs +1 -1
  353. package/dist/{taxonomies-D9Sw4wWM.mjs → taxonomies-BiM9NtgW.mjs} +36 -29
  354. package/dist/taxonomies-DSnY5nOa.mjs +443 -0
  355. package/dist/{taxonomy-B169Nm6B.mjs → taxonomy-0k_vRVsD.mjs} +44 -9
  356. package/dist/transport-C46KHLMP.mjs +134 -0
  357. package/dist/types-A8fPOJnl.mjs +69 -0
  358. package/dist/types-BLQCz46p.d.mts +118 -0
  359. package/dist/{types-CwawBUTa.d.mts → types-B_FlxIIl.d.mts} +4 -1
  360. package/dist/{types-CSgR9nQB.mjs → types-ChxYDRvx.mjs} +1 -1
  361. package/dist/{types-GaCtZ1k9.d.mts → types-Cw0PeCT_.d.mts} +18 -0
  362. package/dist/types-DuQn1G7-.d.mts +2973 -0
  363. package/dist/{runtime-C4-2lSFg.d.mts → types-DwoUifGE.d.mts} +5668 -3000
  364. package/dist/{types-DRIKLmJI.d.mts → types-opjX_kz6.d.mts} +17 -2
  365. package/dist/ui/server-runtime.d.mts +13 -15
  366. package/dist/ui/server-runtime.mjs +24 -20
  367. package/dist/url-guoXQQcV.mjs +33 -0
  368. package/dist/{user-DTLoZs16.mjs → user-BH-n01y3.mjs} +2 -2
  369. package/dist/{utils-B8hBJ9Oz.mjs → utils-D1SrKGtP.mjs} +129 -7
  370. package/dist/{validate-DzjCdy6v.d.mts → validate-CbVFoJgc.d.mts} +65 -8
  371. package/dist/{validate-DWmPO6oj.mjs → validate-D1HL-oLR.mjs} +11 -6
  372. package/dist/version-C3iVRuaF.mjs +6 -0
  373. package/dist/{widgets-BpJ8EpPd.mjs → widgets-BZrLrNgS.mjs} +46 -43
  374. package/dist/{wordpress-slugs-DHNR9LpG.mjs → wordpress-slugs-C3PWcowq.mjs} +1 -1
  375. package/dist/{zod-generator-K91-g665.mjs → zod-generator-C7AsLpSB.mjs} +42 -14
  376. package/package.json +38 -8
  377. package/src/components/Block.astro +50 -0
  378. package/src/components/Comments.astro +143 -1
  379. package/src/components/DinewayHead.astro +19 -2
  380. package/src/components/DinewayImage.astro +66 -33
  381. package/src/components/DinewayMedia.astro +1 -2
  382. package/src/components/Image.astro +85 -40
  383. package/src/components/InlinePortableTextEditor.tsx +12 -2
  384. package/src/components/JsonLdScript.astro +9 -0
  385. package/src/components/LiveSearch.astro +40 -4
  386. package/src/components/index.ts +4 -0
  387. package/src/components/live-search-routing.ts +30 -0
  388. package/src/components/portable-text-text-align.ts +15 -0
  389. package/src/ui.ts +2 -0
  390. package/dist/entity-aliases-4y93Yjuc.mjs +0 -51
  391. package/dist/import-4YBXbDkI.mjs +0 -684
  392. package/dist/index-CZiWCQDp.d.mts +0 -227
  393. package/dist/review-requests-Qum4713s.mjs +0 -79
  394. package/dist/runner-DzIpHGND.mjs +0 -2836
  395. package/dist/schema-Bsi-VpYv.mjs +0 -8
  396. package/dist/taxonomies-CZ-_DitR.mjs +0 -327
  397. package/dist/types-CuJOqHfM.d.mts +0 -758
  398. package/dist/types-DSPGWjxO.d.mts +0 -1247
  399. package/dist/types-nP9vGUFq.d.mts +0 -56
  400. package/dist/version-C4gfn0PJ.mjs +0 -6
  401. /package/dist/{adapters-OQCImOL7.d.mts → adapters-BiRymx02.d.mts} +0 -0
  402. /package/dist/{api-tokens-CYUoFGo7.mjs → api-tokens-Ypaly90d.mjs} +0 -0
  403. /package/dist/{challenge-store-DFxX0_15.mjs → challenge-store-D5pSY2S1.mjs} +0 -0
  404. /package/dist/{components--pg6zBvu.mjs → components-DImzlLhb.mjs} +0 -0
  405. /package/dist/{context-types-r8oFvyOq.mjs → context-types-eBuMDAg-.mjs} +0 -0
  406. /package/dist/{default-B6iaLvP7.mjs → default-D4Vygcy_.mjs} +0 -0
  407. /package/dist/{email-console-BOVqIYpB.mjs → email-console-Bp0r68iF.mjs} +0 -0
  408. /package/dist/{escape-BDgouFFY.mjs → escape-DN4Qmjsl.mjs} +0 -0
  409. /package/dist/{hash-BPmX6P8I.mjs → hash-mxxx2oPW.mjs} +0 -0
  410. /package/dist/{mime-CbKsKDCB.mjs → mime-C0vOHFm7.mjs} +0 -0
  411. /package/dist/{mode-CZqCF9dZ.mjs → mode-C8yZnIlR.mjs} +0 -0
  412. /package/dist/{oauth-state-store-qncPB_IU.mjs → oauth-state-store-CndT35iw.mjs} +0 -0
  413. /package/dist/{oauth-user-lookup-BFjWF8wK.mjs → oauth-user-lookup-CMehAaKs.mjs} +0 -0
  414. /package/dist/{options-LsPjZlqD.mjs → options-DQPTH5n0.mjs} +0 -0
  415. /package/dist/{passkey-config-DzHQK90v.mjs → passkey-config-NYukYGed.mjs} +0 -0
  416. /package/dist/{patterns-DKAX6oqN.mjs → patterns-CoqlXUvk.mjs} +0 -0
  417. /package/dist/{provider-loader-DzUxejk7.mjs → provider-loader-BtfrrzfD.mjs} +0 -0
  418. /package/dist/{public-url-B_m9IwdV.mjs → public-url-Cp6hyjVR.mjs} +0 -0
  419. /package/dist/{redirect-BjIBtDWY.mjs → redirect-DrbEmU9a.mjs} +0 -0
  420. /package/dist/{request-cache-ho99schz.mjs → request-cache-CBFjCwSt.mjs} +0 -0
  421. /package/dist/{resolve-DTuDyYKs.mjs → resolve-DE71WcL9.mjs} +0 -0
  422. /package/dist/{setup-nonce-pyGfc9hV.mjs → setup-nonce-BtkKnvxQ.mjs} +0 -0
  423. /package/dist/{sidecar-client-mJxwayYN.mjs → sidecar-client-Ctzfyyp-.mjs} +0 -0
  424. /package/dist/{slugify-BqebcqBg.mjs → slugify-KSsVD_D3.mjs} +0 -0
  425. /package/dist/{ssrf-DiKqWd3N.mjs → ssrf-FJqwQzj4.mjs} +0 -0
  426. /package/dist/{tokens-SLmgowfd.mjs → tokens-BDQU29Vd.mjs} +0 -0
  427. /package/dist/{transaction-CFLhEOuH.mjs → transaction-0LEAAy8R.mjs} +0 -0
  428. /package/dist/{transport-BnsNxh2l.d.mts → transport-D9pKAzFP.d.mts} +0 -0
  429. /package/dist/{trusted-proxy-BgIIcbsN.mjs → trusted-proxy-Dm7Mxvt6.mjs} +0 -0
  430. /package/dist/{types-CJ8DkL0q.mjs → types-B7TDDFMG.mjs} +0 -0
  431. /package/dist/{types-Dryvv7LH.d.mts → types-g0zMtraY.d.mts} +0 -0
  432. /package/dist/{types-Cg276-3z.mjs → types-mVVgRPaU.mjs} +0 -0
  433. /package/dist/{types-DZpT-PnG.d.mts → types-wFu80FrO.d.mts} +0 -0
  434. /package/dist/{url-w7Mp5qAD.mjs → url-EMAguGVk.mjs} +0 -0
@@ -1,38 +1,359 @@
1
1
  import "../../../dialect-helpers-fk43GbDb.mjs";
2
2
  import "../../../base64-F8-DUraK.mjs";
3
- import "../../../types-CSgR9nQB.mjs";
4
- import "../../../loader--GOYux8M.mjs";
5
- import "../../../content-CBxYGWfL.mjs";
6
- import "../../../media-CbKyYukG.mjs";
7
- import "../../../options-LsPjZlqD.mjs";
8
- import "../../../site-activity-DONFrMBJ.mjs";
9
- import { t as ReviewRequestRepository } from "../../../review-requests-BW2NxY-l.mjs";
10
- import "../../../entity-aliases-4y93Yjuc.mjs";
11
- import "../../../request-cache-ho99schz.mjs";
12
- import { a as ContextRepository, i as parseSiteBriefingScope, r as formatSiteBriefingText, t as SiteBriefingAssembler } from "../../../briefing-CkTee1ex.mjs";
13
- import { t as SITE_CONTEXT_TYPES } from "../../../context-types-r8oFvyOq.mjs";
14
- import "../../../fts-manager-B5l_qwrA.mjs";
15
- import "../../../registry-D7HACema.mjs";
16
- import "../../../settings-CUXOxzsT.mjs";
17
- import { n as VERSION } from "../../../version-C4gfn0PJ.mjs";
18
- import "../../../query-CZ3TH_Uu.mjs";
19
- import "../../../zod-generator-K91-g665.mjs";
20
- import "../../../schema-Bsi-VpYv.mjs";
21
- import { t as apiError } from "../../../error-DCSuUAZW.mjs";
22
- import { P as settingsUpdateBody, Sn as contentBylineInputSchema, sn as contentSeoInput } from "../../../redirects-ocRJmQHP.mjs";
23
- import "../../../byline-fields-cNrLJVRs.mjs";
3
+ import "../../../types-ChxYDRvx.mjs";
4
+ import "../../../loader-aWkkc1_o.mjs";
5
+ import "../../../object-cache-D51qOseS.mjs";
6
+ import "../../../content-DJcAYFhz.mjs";
7
+ import "../../../media-CVMOoywq.mjs";
8
+ import "../../../options-DQPTH5n0.mjs";
9
+ import "../../../site-activity-h8smOlYI.mjs";
10
+ import { t as ReviewRequestRepository } from "../../../review-requests-CTWGnWUt.mjs";
11
+ import { a as HITL_REQUEST_STATUSES, i as HITL_REQUEST_PRIORITIES, o as HitlRequestRepository, r as ReleasePayloadBuilder, t as PublicationAuthorizationError } from "../../../publication-authorization-RKiHXKtq.mjs";
12
+ import { C as ASSIGNMENT_STATUSES, S as ASSIGNMENT_PRIORITIES, _ as toPublicContextDiff, a as EntityResolver, b as HitlRequestService, d as SettingsHitlPayloadBuilder, g as RiskPolicyEvaluator, h as SchemaHitlPayloadBuilder, i as ActorExpertiseService, n as AssignmentService, r as HandoffSnapshotStore, t as WorkflowHitlCoordinator, v as toPublicContextEntry, x as ASSIGNMENT_ACTOR_TYPES, y as toPublicContextEntryPage } from "../../../site-context-B8T1kpUP.mjs";
13
+ import "../../../request-cache-CBFjCwSt.mjs";
14
+ import { a as ContextRepository, i as parseSiteBriefingScope, r as formatSiteBriefingText, t as SiteBriefingAssembler } from "../../../briefing-0rf-su3-.mjs";
15
+ import { t as SITE_CONTEXT_TYPES } from "../../../context-types-eBuMDAg-.mjs";
16
+ import "../../../content-refresh-B4ZCmxgd.mjs";
17
+ import "../../../fts-manager-ewTGohf4.mjs";
18
+ import "../../../registry-BYYyb2tF.mjs";
19
+ import { a as getSiteSettingsWithDb } from "../../../settings-BECcAIRH.mjs";
20
+ import { t as ReviewPayloadBuilder } from "../../../review-payload-BysRWpxS.mjs";
21
+ import { n as VERSION } from "../../../version-C3iVRuaF.mjs";
22
+ import "../../../query-C2U5u5_p.mjs";
23
+ import "../../../zod-generator-C7AsLpSB.mjs";
24
+ import "../../../schema-DUtnZxjZ.mjs";
25
+ import { t as apiError } from "../../../error-CSVaQNZy.mjs";
26
+ import { Cn as contentBylineInputSchema, P as settingsUpdateBody, _n as bylineCreateBody, cn as contentSeoInput, xn as bylineUpdateBody } from "../../../redirects-Bhpm8bRe.mjs";
27
+ import "../../../byline-fields-WN7RQT4q.mjs";
28
+ import "../../../status-NqWOSFAD.mjs";
24
29
  import "../../../api/schemas/index.mjs";
25
- import "../../../utils-B8hBJ9Oz.mjs";
26
- import "../../../search-Gdrqj582.mjs";
27
- import { i as hasScope } from "../../../api-tokens-CYUoFGo7.mjs";
28
- import { C as HITL_REQUEST_STATUSES, E as ASSIGNMENT_STATUSES, S as HITL_REQUEST_PRIORITIES, T as ASSIGNMENT_PRIORITIES, _ as RiskPolicyEvaluator, a as ActorExpertiseService, b as toPublicContextEntry, f as SettingsHitlPayloadBuilder, g as SchemaHitlPayloadBuilder, i as HandoffSnapshotStore, n as HitlRequestService, o as EntityResolver, r as AssignmentService, t as WorkflowHitlCoordinator, v as ReviewPayloadBuilder, w as ASSIGNMENT_ACTOR_TYPES, x as toPublicContextEntryPage, y as toPublicContextDiff } from "../../../site-context-C8Az_P_I.mjs";
29
- import { T as resolveActorIdentity, b as schemaMcpToolSource, d as logSchemaActivity, o as logContentActivity, p as logSiteActivitySafely, r as contentMcpToolSource, t as activityChangedKeys } from "../../../activity-events-CwM7yxPW.mjs";
30
+ import { i as hasScope } from "../../../api-tokens-Ypaly90d.mjs";
31
+ import { r as registerPluginMcpRegistry, t as createReviewedPluginMcpCommandExecutor } from "../../../mcp-reviewed-executor-Dn52L_yY.mjs";
32
+ import { n as resolveActorIdentity } from "../../../actor-0QJ1Gbtf.mjs";
33
+ import "../../../activity-DUaz_w7p.mjs";
34
+ import { d as logSchemaActivity, o as logContentActivity, p as logSiteActivitySafely, r as contentMcpToolSource, t as activityChangedKeys, x as schemaMcpToolSource } from "../../../activity-events-CJDvE2uc.mjs";
35
+ import "../../../utils-D1SrKGtP.mjs";
36
+ import "../../../search-DUKgZUlm.mjs";
37
+ import { n as SeoProviderEvidenceService, t as ForgewaySeoGatewayClient } from "../../../forgeway-seo-client-G5ddhVHd.mjs";
38
+ import { n as convertDataForWrite, t as convertDataForRead } from "../../../portable-text-BASHceim.mjs";
30
39
  import { z } from "zod";
31
40
  import { Role, canActOnOwn, hasPermission } from "@dineway-ai/auth";
32
- import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
33
41
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
34
42
  import { ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js";
43
+ import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
35
44
 
45
+ //#region src/mcp/seo-provider-tools.ts
46
+ const annotations = {
47
+ readOnlyHint: true,
48
+ destructiveHint: false,
49
+ idempotentHint: false,
50
+ openWorldHint: true
51
+ };
52
+ const forceRefreshInput = { force_refresh: z.boolean().optional().describe("Bypass the managed provider cache") };
53
+ const dataForSeoCommonInput = {
54
+ location_code: z.number().int().min(1).max(1e7).optional(),
55
+ language_code: z.string().trim().min(1).max(20).optional(),
56
+ device: z.enum(["desktop", "mobile"]).optional(),
57
+ ...forceRefreshInput
58
+ };
59
+ function serviceOrThrow(service) {
60
+ if (!service) throw new Error("Dineway hosted SEO provider evidence is unavailable in this runtime.");
61
+ return service;
62
+ }
63
+ function jsonResult$1(data) {
64
+ return { content: [{
65
+ type: "text",
66
+ text: JSON.stringify(data, null, 2)
67
+ }] };
68
+ }
69
+ function errorResult$1(error) {
70
+ return {
71
+ content: [{
72
+ type: "text",
73
+ text: error instanceof Error ? error.message : "SEO provider evidence request failed."
74
+ }],
75
+ isError: true
76
+ };
77
+ }
78
+ function registerSeoProviderTools(server, options) {
79
+ server.registerTool("seo_firecrawl_scrape", {
80
+ title: "Scrape URL with Firecrawl",
81
+ description: "Fetch bounded managed-provider evidence for one HTTP(S) URL. Returns raw evidence without interpretation or persistence.",
82
+ inputSchema: z.object({
83
+ url: z.string().trim().min(1).max(2048),
84
+ formats: z.array(z.string().trim().min(1).max(50)).min(1).max(10).optional(),
85
+ only_main_content: z.boolean().optional(),
86
+ timeout_ms: z.number().int().min(1e3).max(12e4).optional(),
87
+ ...forceRefreshInput
88
+ }),
89
+ annotations
90
+ }, async (args, extra) => {
91
+ options.authorize(extra);
92
+ try {
93
+ return jsonResult$1(await serviceOrThrow(options.service).firecrawlScrape({
94
+ url: args.url,
95
+ formats: args.formats,
96
+ onlyMainContent: args.only_main_content,
97
+ timeoutMs: args.timeout_ms,
98
+ forceRefresh: args.force_refresh
99
+ }));
100
+ } catch (error) {
101
+ return errorResult$1(error);
102
+ }
103
+ });
104
+ server.registerTool("seo_firecrawl_map", {
105
+ title: "Map URLs with Firecrawl",
106
+ description: "Discover a bounded URL map for one HTTP(S) origin through the managed provider bridge.",
107
+ inputSchema: z.object({
108
+ url: z.string().trim().min(1).max(2048),
109
+ search: z.string().trim().min(1).max(500).optional(),
110
+ sitemap: z.enum([
111
+ "skip",
112
+ "include",
113
+ "only"
114
+ ]).optional(),
115
+ limit: z.number().int().min(1).max(1e3).optional(),
116
+ include_subdomains: z.boolean().optional(),
117
+ ignore_query_parameters: z.boolean().optional(),
118
+ ...forceRefreshInput
119
+ }),
120
+ annotations
121
+ }, async (args, extra) => {
122
+ options.authorize(extra);
123
+ try {
124
+ return jsonResult$1(await serviceOrThrow(options.service).firecrawlMap({
125
+ url: args.url,
126
+ search: args.search,
127
+ sitemap: args.sitemap,
128
+ limit: args.limit,
129
+ includeSubdomains: args.include_subdomains,
130
+ ignoreQueryParameters: args.ignore_query_parameters,
131
+ forceRefresh: args.force_refresh
132
+ }));
133
+ } catch (error) {
134
+ return errorResult$1(error);
135
+ }
136
+ });
137
+ server.registerTool("seo_firecrawl_crawl_start", {
138
+ title: "Start Firecrawl Crawl",
139
+ description: "Start one bounded managed crawl and return the raw provider task payload. Does not create a Dineway workflow task.",
140
+ inputSchema: z.object({
141
+ url: z.string().trim().min(1).max(2048),
142
+ limit: z.number().int().min(1).max(1e3).optional(),
143
+ max_discovery_depth: z.number().int().min(0).max(20).optional(),
144
+ allow_external_links: z.boolean().optional(),
145
+ allow_subdomains: z.boolean().optional(),
146
+ scrape_formats: z.array(z.string().trim().min(1).max(50)).min(1).max(10).optional(),
147
+ ...forceRefreshInput
148
+ }),
149
+ annotations
150
+ }, async (args, extra) => {
151
+ options.authorize(extra);
152
+ try {
153
+ return jsonResult$1(await serviceOrThrow(options.service).firecrawlCrawlStart({
154
+ url: args.url,
155
+ limit: args.limit,
156
+ maxDiscoveryDepth: args.max_discovery_depth,
157
+ allowExternalLinks: args.allow_external_links,
158
+ allowSubdomains: args.allow_subdomains,
159
+ scrapeFormats: args.scrape_formats,
160
+ forceRefresh: args.force_refresh
161
+ }));
162
+ } catch (error) {
163
+ return errorResult$1(error);
164
+ }
165
+ });
166
+ server.registerTool("seo_firecrawl_crawl_status", {
167
+ title: "Get Firecrawl Crawl Status",
168
+ description: "Read the raw status of one managed crawl by its provider crawl ID.",
169
+ inputSchema: z.object({ id: z.string().trim().min(1).max(500) }),
170
+ annotations
171
+ }, async (args, extra) => {
172
+ options.authorize(extra);
173
+ try {
174
+ return jsonResult$1(await serviceOrThrow(options.service).firecrawlCrawlStatus({ id: args.id }));
175
+ } catch (error) {
176
+ return errorResult$1(error);
177
+ }
178
+ });
179
+ server.registerTool("seo_firecrawl_search", {
180
+ title: "Search with Firecrawl",
181
+ description: "Return bounded raw web-search evidence through the managed provider bridge.",
182
+ inputSchema: z.object({
183
+ query: z.string().trim().min(1).max(1e3),
184
+ limit: z.number().int().min(1).max(1e3).optional(),
185
+ scrape: z.boolean().optional(),
186
+ ...forceRefreshInput
187
+ }),
188
+ annotations
189
+ }, async (args, extra) => {
190
+ options.authorize(extra);
191
+ try {
192
+ return jsonResult$1(await serviceOrThrow(options.service).firecrawlSearch({
193
+ query: args.query,
194
+ limit: args.limit,
195
+ scrape: args.scrape,
196
+ forceRefresh: args.force_refresh
197
+ }));
198
+ } catch (error) {
199
+ return errorResult$1(error);
200
+ }
201
+ });
202
+ server.registerTool("seo_dataforseo_serp", {
203
+ title: "Get Organic SERP Evidence",
204
+ description: "Return bounded raw Google organic SERP evidence for one keyword.",
205
+ inputSchema: z.object({
206
+ keyword: z.string().trim().min(1).max(1e3),
207
+ depth: z.number().int().min(1).max(100).optional(),
208
+ ...dataForSeoCommonInput
209
+ }),
210
+ annotations
211
+ }, async (args, extra) => {
212
+ options.authorize(extra);
213
+ try {
214
+ return jsonResult$1(await serviceOrThrow(options.service).dataForSeoSerp({
215
+ keyword: args.keyword,
216
+ depth: args.depth,
217
+ locationCode: args.location_code,
218
+ languageCode: args.language_code,
219
+ device: args.device,
220
+ forceRefresh: args.force_refresh
221
+ }));
222
+ } catch (error) {
223
+ return errorResult$1(error);
224
+ }
225
+ });
226
+ server.registerTool("seo_dataforseo_maps", {
227
+ title: "Get Maps SERP Evidence",
228
+ description: "Return bounded raw Google Maps SERP evidence for one keyword.",
229
+ inputSchema: z.object({
230
+ keyword: z.string().trim().min(1).max(1e3),
231
+ depth: z.number().int().min(1).max(100).optional(),
232
+ ...dataForSeoCommonInput
233
+ }),
234
+ annotations
235
+ }, async (args, extra) => {
236
+ options.authorize(extra);
237
+ try {
238
+ return jsonResult$1(await serviceOrThrow(options.service).dataForSeoMaps({
239
+ keyword: args.keyword,
240
+ depth: args.depth,
241
+ locationCode: args.location_code,
242
+ languageCode: args.language_code,
243
+ device: args.device,
244
+ forceRefresh: args.force_refresh
245
+ }));
246
+ } catch (error) {
247
+ return errorResult$1(error);
248
+ }
249
+ });
250
+ server.registerTool("seo_dataforseo_keywords", {
251
+ title: "Get Keyword Evidence",
252
+ description: "Return bounded raw keyword suggestions for one seed keyword.",
253
+ inputSchema: z.object({
254
+ keyword: z.string().trim().min(1).max(1e3),
255
+ limit: z.number().int().min(1).max(1e3).optional(),
256
+ ...dataForSeoCommonInput
257
+ }),
258
+ annotations
259
+ }, async (args, extra) => {
260
+ options.authorize(extra);
261
+ try {
262
+ return jsonResult$1(await serviceOrThrow(options.service).dataForSeoKeywords({
263
+ keyword: args.keyword,
264
+ limit: args.limit,
265
+ locationCode: args.location_code,
266
+ languageCode: args.language_code,
267
+ device: args.device,
268
+ forceRefresh: args.force_refresh
269
+ }));
270
+ } catch (error) {
271
+ return errorResult$1(error);
272
+ }
273
+ });
274
+ server.registerTool("seo_dataforseo_competitors", {
275
+ title: "Get Competitor Domain Evidence",
276
+ description: "Return bounded raw competitor-domain evidence for one target domain.",
277
+ inputSchema: z.object({
278
+ domain: z.string().trim().min(1).max(253),
279
+ limit: z.number().int().min(1).max(1e3).optional(),
280
+ ...dataForSeoCommonInput
281
+ }),
282
+ annotations
283
+ }, async (args, extra) => {
284
+ options.authorize(extra);
285
+ try {
286
+ return jsonResult$1(await serviceOrThrow(options.service).dataForSeoCompetitors({
287
+ domain: args.domain,
288
+ limit: args.limit,
289
+ locationCode: args.location_code,
290
+ languageCode: args.language_code,
291
+ device: args.device,
292
+ forceRefresh: args.force_refresh
293
+ }));
294
+ } catch (error) {
295
+ return errorResult$1(error);
296
+ }
297
+ });
298
+ server.registerTool("seo_dataforseo_ai_scrape", {
299
+ title: "Get Managed AI Result Evidence",
300
+ description: "Return raw managed AI-result evidence for one keyword. This does not replace direct user-account observations.",
301
+ inputSchema: z.object({
302
+ keyword: z.string().trim().min(1).max(1e3),
303
+ platform: z.enum([
304
+ "chat_gpt",
305
+ "gemini",
306
+ "perplexity"
307
+ ]).optional(),
308
+ ...dataForSeoCommonInput
309
+ }),
310
+ annotations
311
+ }, async (args, extra) => {
312
+ options.authorize(extra);
313
+ try {
314
+ return jsonResult$1(await serviceOrThrow(options.service).dataForSeoAiScrape({
315
+ keyword: args.keyword,
316
+ platform: args.platform,
317
+ locationCode: args.location_code,
318
+ languageCode: args.language_code,
319
+ device: args.device,
320
+ forceRefresh: args.force_refresh
321
+ }));
322
+ } catch (error) {
323
+ return errorResult$1(error);
324
+ }
325
+ });
326
+ server.registerTool("seo_dataforseo_ai_mentions", {
327
+ title: "Get Managed AI Mention Evidence",
328
+ description: "Return bounded raw managed mention evidence for a domain, keyword, or both. This does not generate visibility conclusions.",
329
+ inputSchema: z.object({
330
+ domain: z.string().trim().min(1).max(253).optional(),
331
+ keyword: z.string().trim().min(1).max(1e3).optional(),
332
+ platform: z.enum(["google", "chat_gpt"]).optional(),
333
+ limit: z.number().int().min(1).max(1e3).optional(),
334
+ ...dataForSeoCommonInput
335
+ }),
336
+ annotations
337
+ }, async (args, extra) => {
338
+ options.authorize(extra);
339
+ try {
340
+ return jsonResult$1(await serviceOrThrow(options.service).dataForSeoAiMentions({
341
+ domain: args.domain,
342
+ keyword: args.keyword,
343
+ platform: args.platform,
344
+ limit: args.limit,
345
+ locationCode: args.location_code,
346
+ languageCode: args.language_code,
347
+ device: args.device,
348
+ forceRefresh: args.force_refresh
349
+ }));
350
+ } catch (error) {
351
+ return errorResult$1(error);
352
+ }
353
+ });
354
+ }
355
+
356
+ //#endregion
36
357
  //#region src/mcp/server.ts
37
358
  const COLLECTION_SLUG_PATTERN = /^[a-z][a-z0-9_]*$/;
38
359
  const ENTITY_RESOLVE_TYPES = [
@@ -101,6 +422,28 @@ function getExtra(extra) {
101
422
  function getDineway(extra) {
102
423
  return getExtra(extra).dineway;
103
424
  }
425
+ async function getCollectionFields(dineway, collection) {
426
+ try {
427
+ const { SchemaRegistry } = await import("../../../schema-DUtnZxjZ.mjs").then((n) => n.t);
428
+ return (await new SchemaRegistry(dineway.db).getCollectionWithFields(collection))?.fields ?? null;
429
+ } catch {
430
+ return null;
431
+ }
432
+ }
433
+ async function convertWriteData(dineway, collection, data) {
434
+ const fields = await getCollectionFields(dineway, collection);
435
+ if (!fields) return data;
436
+ return convertDataForWrite(data, fields);
437
+ }
438
+ async function applyReadMarkdown(dineway, collection, items) {
439
+ const fields = await getCollectionFields(dineway, collection);
440
+ if (!fields) return;
441
+ for (const item of items) if (item.data && typeof item.data === "object") item.data = convertDataForRead(item.data, fields, false);
442
+ }
443
+ async function invalidateBylines() {
444
+ const { invalidateBylineCache } = await import("../../../bylines-CmZFCMr0.mjs").then((n) => n.t);
445
+ invalidateBylineCache();
446
+ }
104
447
  function canReadDrafts(extra) {
105
448
  return hasPermission({ role: getExtra(extra).userRole }, "content:read_drafts");
106
449
  }
@@ -240,7 +583,8 @@ function scopeReadableForExpertise(payload, scope) {
240
583
  case "menu": return contentDiffReadableForHandoff(payload);
241
584
  case "collection":
242
585
  case "site": return contentDiffReadableForHandoff(payload) || schemaReadableForHandoff(payload) || pluginsReadableForHandoff(payload);
243
- case "plugin": return pluginsReadableForHandoff(payload);
586
+ case "plugin":
587
+ case "plugin_extension": return pluginsReadableForHandoff(payload);
244
588
  }
245
589
  } catch {
246
590
  return false;
@@ -275,27 +619,83 @@ function allowedEntityResolveTypes(payload, requestedTypes) {
275
619
  if (disallowed.length > 0) throw new McpError(ErrorCode.InvalidRequest, `Insufficient scope or role for entity types: ${disallowed.join(", ")}`);
276
620
  return requestedTypes;
277
621
  }
278
- function contentPublishReviewRequired(extra) {
279
- const payload = getExtra(extra);
280
- const actor = resolveActorIdentity(actorLocals(payload));
281
- return new RiskPolicyEvaluator({
282
- db: payload.dineway.db,
283
- handlers: payload.dineway
284
- }).requiresContentPublishReview(actor);
622
+ function contentPublicationService(payload) {
623
+ return payload.dineway.createPublicationAuthorizationService();
285
624
  }
286
- async function requireApprovedContentPublishReview(extra, collection, id, reviewRequestId) {
287
- const payload = getExtra(extra);
625
+ function contentPublicationError(error) {
626
+ return error instanceof PublicationAuthorizationError ? errorResult(`[${error.code}] ${error.message}`) : errorResult(error);
627
+ }
628
+ async function ensureContentReleaseRequest(payload, input) {
288
629
  const actor = resolveActorIdentity(actorLocals(payload));
289
- const decision = await new RiskPolicyEvaluator({
290
- db: payload.dineway.db,
291
- handlers: payload.dineway
292
- }).evaluateContentPublishReview({
293
- actor,
294
- collection,
295
- id,
296
- reviewRequestId
630
+ const settings = await getSiteSettingsWithDb(payload.dineway.db);
631
+ const release = await new ReleasePayloadBuilder({
632
+ handlers: payload.dineway,
633
+ reviewRequests: new ReviewRequestRepository(payload.dineway.db)
634
+ }).buildContentReleasePayload({
635
+ collection: input.collection,
636
+ id: input.id,
637
+ operation: input.operation,
638
+ editorialReviewRequestId: input.editorialReviewRequestId,
639
+ publishedAt: input.publishedAt,
640
+ scheduledAt: input.scheduledAt,
641
+ siteTimezone: settings.timezone?.trim() || "UTC"
642
+ });
643
+ const repository = new HitlRequestRepository(payload.dineway.db);
644
+ const existing = (await repository.list({
645
+ scope: release.scope,
646
+ statuses: ["pending", "approved"],
647
+ actionType: release.actionType,
648
+ targetRefType: "content",
649
+ targetRefId: release.entryId,
650
+ requestedByActorType: actor.actorType,
651
+ requestedByActorId: actor.actorId,
652
+ limit: 100
653
+ })).items.find((request) => request.metadata.actionHash === release.actionHash);
654
+ if (existing) return {
655
+ created: false,
656
+ request: existing
657
+ };
658
+ const request = await repository.create({
659
+ scope: release.scope,
660
+ actionType: release.actionType,
661
+ title: `${input.operation === "publish" ? "Publish" : "Schedule"} ${release.collection}/${release.entryId}`,
662
+ summary: `Authorize exact ${input.operation} release for reviewed Draft`,
663
+ riskReason: "Agent-authenticated content release requires explicit approval.",
664
+ reviewPayload: release.releasePayload,
665
+ targetRefType: "content",
666
+ targetRefId: release.entryId,
667
+ requestedByActorType: actor.actorType,
668
+ requestedByActorId: actor.actorId,
669
+ requestedAuthMetadata: actor.authMetadata,
670
+ metadata: {
671
+ actionHash: release.actionHash,
672
+ editorialReviewRequestId: release.editorialReviewRequestId,
673
+ operation: release.operation,
674
+ scheduledAt: release.scheduledAt,
675
+ publishedAt: release.publishedAt
676
+ }
297
677
  });
298
- if (!decision.allowed) throw new McpError(ErrorCode.InvalidRequest, decision.message);
678
+ await logSiteActivitySafely(payload.dineway.db, actorLocals(payload), {
679
+ actionType: "hitl.submitted",
680
+ subjectType: "hitl_request",
681
+ subjectId: request.id,
682
+ scope: request.scope,
683
+ sourceType: "mcp_tool",
684
+ sourceName: "content_release_request",
685
+ resultStatus: "pending",
686
+ summary: `Submitted release request for ${release.actionType}`,
687
+ detail: {
688
+ collection: release.collection,
689
+ entryId: release.entryId,
690
+ operation: release.operation,
691
+ editorialReviewRequestId: release.editorialReviewRequestId,
692
+ actionHash: release.actionHash
693
+ }
694
+ });
695
+ return {
696
+ created: true,
697
+ request
698
+ };
299
699
  }
300
700
  async function ensureWorkflowHitlRequest(extra, action) {
301
701
  const payload = getExtra(extra);
@@ -426,11 +826,18 @@ async function logMcpContentActivity(dineway, locals, collection, entryId, actio
426
826
  function experimentalWorkflowDescription(description) {
427
827
  return "Experimental: this deferred Site Context workflow surface exists on the current branch but is not part of the approved baseline contract. " + description;
428
828
  }
429
- function createMcpServer() {
829
+ function createMcpServer(options = {}) {
430
830
  const server = new McpServer({
431
831
  name: "dineway",
432
832
  version: VERSION
433
833
  }, { capabilities: { logging: {} } });
834
+ registerSeoProviderTools(server, {
835
+ service: options.seoProviderService,
836
+ authorize: (extra) => {
837
+ requireScope(extra, "seo:read");
838
+ requireRole(extra, Role.AUTHOR);
839
+ }
840
+ });
434
841
  server.registerTool("site_briefing_get", {
435
842
  title: "Get Site Briefing",
436
843
  description: "Build a read-only Site Context Engine briefing for a site, collection, content item, plugin, taxonomy, or menu scope. The briefing includes inherited scopes, authorized schema, recent activity, active plugin capabilities, curated settings/SEO, and forward-compatible context/review/staleness sections.",
@@ -457,6 +864,7 @@ function createMcpServer() {
457
864
  db: ec.db,
458
865
  storage: ec.storage,
459
866
  configuredPlugins: ec.configuredPlugins,
867
+ sandboxedPluginEntries: ec.sandboxedPluginEntries,
460
868
  marketplaceUrl: ec.config.marketplace,
461
869
  permissions: briefingPermissions(payload)
462
870
  }).assemble({
@@ -859,7 +1267,7 @@ function createMcpServer() {
859
1267
  });
860
1268
  server.registerTool("assignment_create", {
861
1269
  title: "Create Assignment",
862
- description: experimentalWorkflowDescription("Create a workflow assignment attached to a Dineway scope. Assignments are durable human-agent handoffs and must use explicit lifecycle transitions instead of ad hoc status patches."),
1270
+ description: "Create a workflow assignment attached to a Dineway scope. Assignments are durable human-agent handoffs and must use explicit lifecycle transitions instead of ad hoc status patches.",
863
1271
  inputSchema: z.object({
864
1272
  scope: z.string().describe("Assignment scope string."),
865
1273
  assignment_type: z.string().describe("Workflow-specific assignment type label."),
@@ -911,7 +1319,7 @@ function createMcpServer() {
911
1319
  });
912
1320
  server.registerTool("assignment_get", {
913
1321
  title: "Get Assignment",
914
- description: experimentalWorkflowDescription("Fetch one workflow assignment by id."),
1322
+ description: "Fetch one workflow assignment by id.",
915
1323
  inputSchema: z.object({ id: z.string().describe("Assignment id.") }),
916
1324
  annotations: { readOnlyHint: true }
917
1325
  }, async (args, extra) => {
@@ -926,7 +1334,7 @@ function createMcpServer() {
926
1334
  });
927
1335
  server.registerTool("assignment_list", {
928
1336
  title: "List Assignments",
929
- description: experimentalWorkflowDescription("List workflow assignments visible to the current actor. Non-editor actors are automatically limited to assignments they assigned or were assigned."),
1337
+ description: "List workflow assignments visible to the current actor. Non-editor actors are automatically limited to assignments they assigned or were assigned.",
930
1338
  inputSchema: z.object({
931
1339
  scope: z.string().optional().describe("Optional exact scope filter."),
932
1340
  statuses: z.array(z.enum(ASSIGNMENT_STATUSES)).optional().describe("Optional assignment status filters."),
@@ -960,7 +1368,7 @@ function createMcpServer() {
960
1368
  });
961
1369
  server.registerTool("assignment_accept", {
962
1370
  title: "Accept Assignment",
963
- description: experimentalWorkflowDescription("Accept a pending workflow assignment."),
1371
+ description: "Accept a pending workflow assignment.",
964
1372
  inputSchema: z.object({ id: z.string().describe("Assignment id.") })
965
1373
  }, async (args, extra) => {
966
1374
  requireWorkflowWrite(extra);
@@ -992,7 +1400,7 @@ function createMcpServer() {
992
1400
  });
993
1401
  server.registerTool("assignment_start", {
994
1402
  title: "Start Assignment",
995
- description: experimentalWorkflowDescription("Move an assignment into in_progress. When the assignment is currently blocked, this acts as the validated resume transition."),
1403
+ description: "Move an assignment into in_progress. When the assignment is currently blocked, this acts as the validated resume transition.",
996
1404
  inputSchema: z.object({ id: z.string().describe("Assignment id.") })
997
1405
  }, async (args, extra) => {
998
1406
  requireWorkflowWrite(extra);
@@ -1024,7 +1432,7 @@ function createMcpServer() {
1024
1432
  });
1025
1433
  server.registerTool("assignment_complete", {
1026
1434
  title: "Complete Assignment",
1027
- description: experimentalWorkflowDescription("Mark a workflow assignment complete."),
1435
+ description: "Mark a workflow assignment complete.",
1028
1436
  inputSchema: z.object({
1029
1437
  id: z.string().describe("Assignment id."),
1030
1438
  completion_note: z.string().optional().describe("Optional completion note.")
@@ -1061,7 +1469,7 @@ function createMcpServer() {
1061
1469
  });
1062
1470
  server.registerTool("assignment_decline", {
1063
1471
  title: "Decline Assignment",
1064
- description: experimentalWorkflowDescription("Decline a workflow assignment."),
1472
+ description: "Decline a workflow assignment.",
1065
1473
  inputSchema: z.object({
1066
1474
  id: z.string().describe("Assignment id."),
1067
1475
  reason: z.string().optional().describe("Optional decline reason.")
@@ -1098,7 +1506,7 @@ function createMcpServer() {
1098
1506
  });
1099
1507
  server.registerTool("assignment_block", {
1100
1508
  title: "Block Assignment",
1101
- description: experimentalWorkflowDescription("Mark a workflow assignment blocked and record why."),
1509
+ description: "Mark a workflow assignment blocked and record why.",
1102
1510
  inputSchema: z.object({
1103
1511
  id: z.string().describe("Assignment id."),
1104
1512
  reason: z.string().optional().describe("Optional blocking reason.")
@@ -1135,7 +1543,7 @@ function createMcpServer() {
1135
1543
  });
1136
1544
  server.registerTool("assignment_cancel", {
1137
1545
  title: "Cancel Assignment",
1138
- description: experimentalWorkflowDescription("Cancel a workflow assignment that should no longer continue."),
1546
+ description: "Cancel a workflow assignment that should no longer continue.",
1139
1547
  inputSchema: z.object({
1140
1548
  id: z.string().describe("Assignment id."),
1141
1549
  reason: z.string().optional().describe("Optional cancellation reason.")
@@ -1378,7 +1786,7 @@ function createMcpServer() {
1378
1786
  });
1379
1787
  server.registerTool("agent_handoff_capture", {
1380
1788
  title: "Capture Agent Handoff",
1381
- description: experimentalWorkflowDescription("Capture the current agent objective, reasoning, findings, touched objects, and pending actions before pausing or handing work off."),
1789
+ description: "Capture the current agent objective, reasoning, findings, touched objects, and pending actions before pausing or handing work off.",
1382
1790
  inputSchema: z.object({
1383
1791
  scope: z.string().describe("Scope string: site, collection:{slug}, content:{collection}:{id}, or plugin:{id}."),
1384
1792
  objective: z.string().min(1).describe("Current objective or outcome the agent was pursuing."),
@@ -1483,7 +1891,7 @@ function createMcpServer() {
1483
1891
  });
1484
1892
  server.registerTool("agent_handoff_resume", {
1485
1893
  title: "Resume Agent Handoff",
1486
- description: experimentalWorkflowDescription("Resume from a stored handoff snapshot and return a deterministic diff of activity, context, and review changes since capture time."),
1894
+ description: "Resume from a stored handoff snapshot and return a deterministic diff of activity, context, and review changes since capture time.",
1487
1895
  inputSchema: z.object({
1488
1896
  snapshot_id: z.string().describe("Handoff snapshot id returned by agent_handoff_capture."),
1489
1897
  activity_limit: z.number().int().min(1).max(100).optional().describe("Maximum activity rows to include in the diff. Defaults to 25."),
@@ -1536,21 +1944,30 @@ function createMcpServer() {
1536
1944
  cursor: z.string().optional().describe("Pagination cursor from a previous response"),
1537
1945
  orderBy: z.string().optional().describe("Field to sort by (e.g. 'created_at', 'updated_at')"),
1538
1946
  order: z.enum(["asc", "desc"]).optional().describe("Sort direction (default 'desc')"),
1539
- locale: z.string().optional().describe("Filter by locale (e.g. 'en', 'fr'). Only relevant when i18n is enabled.")
1947
+ locale: z.string().optional().describe("Filter by locale (e.g. 'en', 'fr'). Only relevant when i18n is enabled."),
1948
+ markdown: z.boolean().optional().describe("Return rich text (portableText) fields as Markdown strings instead of Portable Text arrays (default false).")
1540
1949
  }),
1541
1950
  annotations: { readOnlyHint: true }
1542
1951
  }, async (args, extra) => {
1543
1952
  requireScope(extra, "content:read");
1544
1953
  const ec = getDineway(extra);
1545
1954
  const status = canReadDrafts(extra) ? args.status : "published";
1546
- return unwrap(await ec.handleContentList(args.collection, {
1955
+ const result = await ec.handleContentList(args.collection, {
1547
1956
  status,
1548
1957
  limit: args.limit,
1549
1958
  cursor: args.cursor,
1550
1959
  orderBy: args.orderBy,
1551
1960
  order: args.order,
1552
1961
  locale: args.locale
1553
- }));
1962
+ });
1963
+ if (result.success && args.markdown) {
1964
+ const data = result.data;
1965
+ if (data && typeof data === "object" && "items" in data && Array.isArray(data.items)) {
1966
+ const items = data.items.filter((item) => typeof item === "object" && item !== null);
1967
+ await applyReadMarkdown(ec, args.collection, items);
1968
+ }
1969
+ }
1970
+ return unwrap(result);
1554
1971
  });
1555
1972
  server.registerTool("content_get", {
1556
1973
  title: "Get Content",
@@ -1558,28 +1975,32 @@ function createMcpServer() {
1558
1975
  inputSchema: z.object({
1559
1976
  collection: z.string().describe("Collection slug (e.g. 'posts', 'pages')"),
1560
1977
  id: z.string().describe("Content item ID (ULID) or slug"),
1561
- locale: z.string().optional().describe("Locale to scope slug lookup (e.g. 'fr'). Only affects slug resolution; IDs are globally unique.")
1978
+ locale: z.string().optional().describe("Locale to scope slug lookup (e.g. 'fr'). Only affects slug resolution; IDs are globally unique."),
1979
+ markdown: z.boolean().optional().describe("Return rich text (portableText) fields as Markdown strings instead of Portable Text arrays (default false).")
1562
1980
  }),
1563
1981
  annotations: { readOnlyHint: true }
1564
1982
  }, async (args, extra) => {
1565
1983
  requireScope(extra, "content:read");
1566
- const result = await getDineway(extra).handleContentGet(args.collection, args.id, args.locale);
1984
+ const ec = getDineway(extra);
1985
+ const result = await ec.handleContentGet(args.collection, args.id, args.locale);
1567
1986
  if (result.success && !canReadDrafts(extra)) {
1568
1987
  const data = result.data && typeof result.data === "object" ? result.data : {};
1569
1988
  if (!isPublishedRecord("item" in data ? data.item : data)) return errorResult("Content not found");
1570
1989
  }
1990
+ if (result.success && args.markdown && result.data?.item) await applyReadMarkdown(ec, args.collection, [result.data.item]);
1571
1991
  return unwrap(result);
1572
1992
  });
1573
1993
  server.registerTool("content_create", {
1574
1994
  title: "Create Content",
1575
- description: "Create a new content item in a collection. The 'data' object should contain field values matching the collection's schema (use schema_get_collection to check). Rich text fields accept Portable Text JSON arrays. A slug is auto-generated if not provided. Items are created as 'draft' by default — use content_publish to make them live.",
1995
+ description: "Create a new content item in a collection. The 'data' object should contain field values matching the collection's schema (use schema_get_collection to check). For rich text (portableText) fields, pass a Markdown string — converted to Portable Text automatically; prefer this. Pass a Portable Text JSON array only for complex content Markdown can't express. A slug is auto-generated if not provided. Items are created as 'draft' by default — use content_publish to make them live.",
1576
1996
  inputSchema: z.object({
1577
1997
  collection: z.string().describe("Collection slug (e.g. 'posts', 'pages')"),
1578
1998
  data: z.record(z.string(), z.unknown()).describe("Field values as key-value pairs matching the collection schema"),
1579
1999
  slug: z.string().optional().describe("URL slug (auto-generated from title if omitted)"),
1580
- status: z.enum(["draft", "published"]).optional().describe("Initial status (default 'draft'). Requires publish permission."),
2000
+ status: z.literal("draft").optional().describe("Initial status. Content creation is draft-only."),
1581
2001
  locale: z.string().optional().describe("Locale for this content (e.g. 'fr'). Defaults to default locale."),
1582
- translationOf: z.string().optional().describe("ID of the content item this is a translation of. Links items in the same translation group.")
2002
+ translationOf: z.string().optional().describe("ID of the content item this is a translation of. Links items in the same translation group."),
2003
+ bylines: z.array(contentBylineInputSchema).optional().describe("Bylines to credit. Each entry references an existing byline by id, with an optional roleLabel. The first entry becomes the primary byline.")
1583
2004
  }),
1584
2005
  annotations: { destructiveHint: false }
1585
2006
  }, async (args, extra) => {
@@ -1593,40 +2014,14 @@ function createMcpServer() {
1593
2014
  if (!source.success) return unwrap(source);
1594
2015
  requireOwnership(extra, extractContentAuthorId(source.data), "content:edit_own", "content:edit_any");
1595
2016
  }
1596
- if (args.status === "published") {
1597
- if (!hasPermission({
1598
- id: userId,
1599
- role: getExtra(extra).userRole
1600
- }, "content:publish_own")) throw new McpError(ErrorCode.InvalidRequest, "Insufficient permissions: publishing requires content:publish_own");
1601
- if (contentPublishReviewRequired(extra)) throw new McpError(ErrorCode.InvalidRequest, "Token-authenticated content creation with immediate publish is review-gated. Create a draft first, submit review_request_submit, resolve it as approved, then call content_publish with review_request_id.");
1602
- const result = await dineway.handleContentCreate(args.collection, {
1603
- data: args.data,
1604
- slug: args.slug,
1605
- authorId: userId,
1606
- locale: args.locale,
1607
- translationOf: args.translationOf
1608
- });
1609
- if (!result.success) return unwrap(result);
1610
- const itemId = extractContentId(result.data);
1611
- if (itemId) {
1612
- await logMcpContentActivity(dineway, locals, args.collection, itemId, "created", "content_create", {
1613
- changedFields: activityChangedKeys(args.data),
1614
- slugProvided: args.slug !== void 0,
1615
- locale: args.locale ?? null,
1616
- translationOf: args.translationOf ?? null
1617
- });
1618
- const publishResult = await dineway.handleContentPublish(args.collection, itemId);
1619
- if (publishResult.success) await logMcpContentActivity(dineway, locals, args.collection, itemId, "published", "content_create");
1620
- return unwrap(publishResult);
1621
- }
1622
- return unwrap(result);
1623
- }
2017
+ const data = await convertWriteData(dineway, args.collection, args.data);
1624
2018
  const result = await dineway.handleContentCreate(args.collection, {
1625
- data: args.data,
2019
+ data,
1626
2020
  slug: args.slug,
1627
2021
  authorId: userId,
1628
2022
  locale: args.locale,
1629
- translationOf: args.translationOf
2023
+ translationOf: args.translationOf,
2024
+ bylines: args.bylines
1630
2025
  });
1631
2026
  if (result.success) {
1632
2027
  const itemId = extractContentId(result.data);
@@ -1641,22 +2036,21 @@ function createMcpServer() {
1641
2036
  });
1642
2037
  server.registerTool("content_update", {
1643
2038
  title: "Update Content",
1644
- description: "Update an existing content item. Only include fields you want to change in the 'data' object — unspecified fields are left unchanged. Pass the _rev token from content_get to enable optimistic concurrency checking (the update fails if the item was modified since you read it). `seo` and `bylines` are persisted alongside field updates. `publishedAt` requires content:publish_any permission and is useful for content imports.",
2039
+ description: "Update an existing content item. Only include fields you want to change in the 'data' object — unspecified fields are left unchanged. Rich text (portableText) fields accept a Markdown string (recommended, converted automatically); use a Portable Text JSON array only for complex content Markdown can't express. Pass the _rev token from content_get to enable optimistic concurrency checking (the update fails if the item was modified since you read it). `seo` and `bylines` are persisted alongside field updates. `publishedAt` requires content:publish_any permission and is useful for content imports.",
1645
2040
  inputSchema: z.object({
1646
2041
  collection: z.string().describe("Collection slug"),
1647
2042
  id: z.string().describe("Content item ID or slug"),
1648
2043
  locale: z.string().optional().describe("Locale to scope slug lookup. Only affects slug resolution; IDs are globally unique."),
1649
2044
  data: z.record(z.string(), z.unknown()).optional().describe("Field values to update (only include changed fields)"),
1650
2045
  slug: z.string().optional().describe("New URL slug"),
1651
- status: z.enum(["draft", "published"]).optional().describe("New status. Setting to 'published' requires publish permission. Setting to 'draft' unpublishes the item and also requires publish permission."),
2046
+ status: z.literal("draft").optional().describe("Set to 'draft' to unpublish the item. Publishing uses content_publish."),
1652
2047
  seo: contentSeoInput.optional().describe("Per-content SEO metadata. Only valid for collections with SEO enabled."),
1653
2048
  bylines: z.array(contentBylineInputSchema).optional().describe("Replace the byline list for this item. The first entry becomes the primary byline."),
1654
2049
  publishedAt: z.iso.datetime({
1655
2050
  offset: true,
1656
2051
  message: "must be an ISO 8601 datetime"
1657
2052
  }).nullish().describe("Override the publication timestamp. Requires content:publish_any permission. Pass null to clear."),
1658
- _rev: z.string().optional().describe("Revision token from content_get for conflict detection"),
1659
- review_request_id: z.string().optional().describe("Approved review request id required for token-authenticated content.publish actions.")
2053
+ _rev: z.string().optional().describe("Revision token from content_get for conflict detection")
1660
2054
  })
1661
2055
  }, async (args, extra) => {
1662
2056
  requireScope(extra, "content:write");
@@ -1676,39 +2070,12 @@ function createMcpServer() {
1676
2070
  }, "content:publish_any")) return errorResult("[INSUFFICIENT_PERMISSIONS] Setting publishedAt requires content:publish_any permission");
1677
2071
  }
1678
2072
  const hasInlineUpdates = args.data || args.slug || args.seo !== void 0 || args.bylines !== void 0 || args.publishedAt !== void 0;
1679
- if (args.status === "published") {
1680
- requireOwnership(extra, ownerId, "content:publish_own", "content:publish_any");
1681
- if (contentPublishReviewRequired(extra) && hasInlineUpdates) throw new McpError(ErrorCode.InvalidRequest, "Token-authenticated publish with inline content changes is review-gated. Save the draft first, submit review_request_submit, resolve it as approved, then publish with review_request_id.");
1682
- if (hasInlineUpdates) {
1683
- const updateResult = await dineway.handleContentUpdate(args.collection, resolvedId, {
1684
- data: args.data,
1685
- slug: args.slug,
1686
- authorId: userId,
1687
- locale: args.locale,
1688
- seo: args.seo,
1689
- bylines: args.bylines,
1690
- publishedAt: args.publishedAt,
1691
- _rev: args._rev
1692
- });
1693
- if (!updateResult.success) return unwrap(updateResult);
1694
- await logMcpContentActivity(dineway, locals, args.collection, resolvedId, "updated", "content_update", {
1695
- changedFields: activityChangedKeys(args.data),
1696
- slugChanged: args.slug !== void 0,
1697
- seoChanged: args.seo !== void 0,
1698
- bylinesChanged: args.bylines !== void 0,
1699
- publishedAtChanged: args.publishedAt !== void 0
1700
- });
1701
- }
1702
- await requireApprovedContentPublishReview(extra, args.collection, resolvedId, args.review_request_id);
1703
- const publishResult = await dineway.handleContentPublish(args.collection, resolvedId);
1704
- if (publishResult.success) await logMcpContentActivity(dineway, locals, args.collection, resolvedId, "published", "content_update", { reviewRequestId: args.review_request_id ?? null });
1705
- return unwrap(publishResult);
1706
- }
2073
+ const data = args.data ? await convertWriteData(dineway, args.collection, args.data) : args.data;
1707
2074
  if (args.status === "draft") {
1708
2075
  requireOwnership(extra, ownerId, "content:publish_own", "content:publish_any");
1709
2076
  if (hasInlineUpdates) {
1710
2077
  const updateResult = await dineway.handleContentUpdate(args.collection, resolvedId, {
1711
- data: args.data,
2078
+ data,
1712
2079
  slug: args.slug,
1713
2080
  authorId: userId,
1714
2081
  locale: args.locale,
@@ -1731,7 +2098,7 @@ function createMcpServer() {
1731
2098
  return unwrap(unpublishResult);
1732
2099
  }
1733
2100
  const result = await dineway.handleContentUpdate(args.collection, resolvedId, {
1734
- data: args.data,
2101
+ data,
1735
2102
  slug: args.slug,
1736
2103
  authorId: userId,
1737
2104
  locale: args.locale,
@@ -1812,6 +2179,43 @@ function createMcpServer() {
1812
2179
  if (result.success) await logMcpContentActivity(ec, locals, args.collection, resolvedId, "permanently_deleted", "content_permanent_delete");
1813
2180
  return unwrap(result);
1814
2181
  });
2182
+ server.registerTool("content_release_request", {
2183
+ title: "Request Content Release Authorization",
2184
+ description: "Create or reuse an exact HITL request for publishing or scheduling an approved Draft. The server derives the action hash from current content, review, time, Site Settings, and policies.",
2185
+ inputSchema: z.object({
2186
+ collection: z.string().describe("Collection slug"),
2187
+ id: z.string().describe("Content item ID or slug"),
2188
+ operation: z.enum(["publish", "schedule"]).describe("Release operation"),
2189
+ review_request_id: z.string().describe("Approved editorial Review Request bound to the exact Draft"),
2190
+ publishedAt: z.iso.datetime({
2191
+ offset: true,
2192
+ message: "must be an ISO 8601 datetime"
2193
+ }).optional().describe("Optional publication timestamp for a publish release"),
2194
+ scheduledAt: z.iso.datetime({
2195
+ offset: true,
2196
+ message: "must be an ISO 8601 datetime"
2197
+ }).optional().describe("Required exact publication time for a schedule release")
2198
+ }).strict()
2199
+ }, async (args, extra) => {
2200
+ requireScope(extra, "content:write");
2201
+ requireRole(extra, Role.AUTHOR);
2202
+ const payload = getExtra(extra);
2203
+ const existing = await payload.dineway.handleContentGet(args.collection, args.id);
2204
+ if (!existing.success) return unwrap(existing);
2205
+ requireOwnership(extra, extractContentAuthorId(existing.data), "content:publish_own", "content:publish_any");
2206
+ try {
2207
+ return jsonResult(await ensureContentReleaseRequest(payload, {
2208
+ collection: args.collection,
2209
+ id: extractContentId(existing.data) ?? args.id,
2210
+ operation: args.operation,
2211
+ editorialReviewRequestId: args.review_request_id,
2212
+ publishedAt: args.publishedAt,
2213
+ scheduledAt: args.scheduledAt
2214
+ }));
2215
+ } catch (error) {
2216
+ return contentPublicationError(error);
2217
+ }
2218
+ });
1815
2219
  server.registerTool("content_publish", {
1816
2220
  title: "Publish Content",
1817
2221
  description: "Publish a content item, making it live on the site. Creates a published revision from the current draft. Further edits create a new draft without affecting the live version until re-published. Pass `publishedAt` to backdate imported or historical content; this requires content:publish_any.",
@@ -1822,7 +2226,8 @@ function createMcpServer() {
1822
2226
  offset: true,
1823
2227
  message: "must be an ISO 8601 datetime"
1824
2228
  }).optional().describe("Override publication timestamp. Requires content:publish_any permission."),
1825
- review_request_id: z.string().optional().describe("Approved review request id required for token-authenticated publish actions.")
2229
+ review_request_id: z.string().describe("Approved editorial Review Request bound to the exact Draft."),
2230
+ release_authorization_id: z.string().optional().describe("Approved exact release HITL request required for token actors.")
1826
2231
  })
1827
2232
  }, async (args, extra) => {
1828
2233
  requireScope(extra, "content:write");
@@ -1840,13 +2245,20 @@ function createMcpServer() {
1840
2245
  role: userRole
1841
2246
  }, "content:publish_any")) return errorResult("[INSUFFICIENT_PERMISSIONS] Setting publishedAt requires content:publish_any permission");
1842
2247
  }
1843
- await requireApprovedContentPublishReview(extra, args.collection, resolvedId, args.review_request_id);
1844
- const result = await ec.handleContentPublish(args.collection, resolvedId, { publishedAt: args.publishedAt });
1845
- if (result.success) await logMcpContentActivity(ec, locals, args.collection, resolvedId, "published", "content_publish", {
1846
- reviewRequestId: args.review_request_id ?? null,
1847
- publishedAt: args.publishedAt ?? null
1848
- });
1849
- return unwrap(result);
2248
+ try {
2249
+ return unwrap((await contentPublicationService(payload).publishAuthorizedContent({
2250
+ actor: resolveActorIdentity(locals),
2251
+ collection: args.collection,
2252
+ id: resolvedId,
2253
+ editorialReviewRequestId: args.review_request_id,
2254
+ releaseHitlRequestId: args.release_authorization_id,
2255
+ publishedAt: args.publishedAt,
2256
+ sourceType: "mcp_tool",
2257
+ sourceName: "content_publish"
2258
+ })).result);
2259
+ } catch (error) {
2260
+ return contentPublicationError(error);
2261
+ }
1850
2262
  });
1851
2263
  server.registerTool("content_unpublish", {
1852
2264
  title: "Unpublish Content",
@@ -1875,7 +2287,9 @@ function createMcpServer() {
1875
2287
  inputSchema: z.object({
1876
2288
  collection: z.string().describe("Collection slug"),
1877
2289
  id: z.string().describe("Content item ID or slug"),
1878
- scheduledAt: z.string().describe("ISO 8601 datetime for publication (e.g. '2025-06-01T09:00:00Z')")
2290
+ scheduledAt: z.string().describe("ISO 8601 datetime for publication (e.g. '2025-06-01T09:00:00Z')"),
2291
+ review_request_id: z.string().describe("Approved editorial Review Request bound to the exact Draft."),
2292
+ release_authorization_id: z.string().optional().describe("Approved exact release HITL request required for token actors.")
1879
2293
  })
1880
2294
  }, async (args, extra) => {
1881
2295
  requireScope(extra, "content:write");
@@ -1887,9 +2301,20 @@ function createMcpServer() {
1887
2301
  if (!existing.success) return unwrap(existing);
1888
2302
  requireOwnership(extra, extractContentAuthorId(existing.data), "content:publish_own", "content:publish_any");
1889
2303
  const resolvedId = extractContentId(existing.data) ?? args.id;
1890
- const result = await ec.handleContentSchedule(args.collection, resolvedId, args.scheduledAt);
1891
- if (result.success) await logMcpContentActivity(ec, locals, args.collection, resolvedId, "scheduled", "content_schedule", { scheduledAt: args.scheduledAt });
1892
- return unwrap(result);
2304
+ try {
2305
+ return unwrap((await contentPublicationService(payload).scheduleAuthorizedContent({
2306
+ actor: resolveActorIdentity(locals),
2307
+ collection: args.collection,
2308
+ id: resolvedId,
2309
+ editorialReviewRequestId: args.review_request_id,
2310
+ releaseHitlRequestId: args.release_authorization_id,
2311
+ scheduledAt: args.scheduledAt,
2312
+ sourceType: "mcp_tool",
2313
+ sourceName: "content_schedule"
2314
+ })).result);
2315
+ } catch (error) {
2316
+ return contentPublicationError(error);
2317
+ }
1893
2318
  });
1894
2319
  server.registerTool("content_unschedule", {
1895
2320
  title: "Cancel Scheduled Publication",
@@ -1908,9 +2333,17 @@ function createMcpServer() {
1908
2333
  if (!existing.success) return unwrap(existing);
1909
2334
  requireOwnership(extra, extractContentAuthorId(existing.data), "content:publish_own", "content:publish_any");
1910
2335
  const resolvedId = extractContentId(existing.data) ?? args.id;
1911
- const result = await ec.handleContentUnschedule(args.collection, resolvedId);
1912
- if (result.success) await logMcpContentActivity(ec, locals, args.collection, resolvedId, "unscheduled", "content_unschedule");
1913
- return unwrap(result);
2336
+ try {
2337
+ return unwrap((await contentPublicationService(payload).unscheduleAuthorizedContent({
2338
+ actor: resolveActorIdentity(locals),
2339
+ collection: args.collection,
2340
+ id: resolvedId,
2341
+ sourceType: "mcp_tool",
2342
+ sourceName: "content_unschedule"
2343
+ })).result);
2344
+ } catch (error) {
2345
+ return contentPublicationError(error);
2346
+ }
1914
2347
  });
1915
2348
  server.registerTool("content_compare", {
1916
2349
  title: "Compare Live vs Draft",
@@ -2018,7 +2451,7 @@ function createMcpServer() {
2018
2451
  requireRole(extra, Role.EDITOR);
2019
2452
  const ec = getDineway(extra);
2020
2453
  try {
2021
- const { SchemaRegistry } = await import("../../../schema-Bsi-VpYv.mjs").then((n) => n.t);
2454
+ const { SchemaRegistry } = await import("../../../schema-DUtnZxjZ.mjs").then((n) => n.t);
2022
2455
  return jsonResult({ items: await new SchemaRegistry(ec.db).listCollections() });
2023
2456
  } catch (error) {
2024
2457
  return errorResult(error);
@@ -2034,7 +2467,7 @@ function createMcpServer() {
2034
2467
  requireRole(extra, Role.EDITOR);
2035
2468
  const ec = getDineway(extra);
2036
2469
  try {
2037
- const { SchemaRegistry } = await import("../../../schema-Bsi-VpYv.mjs").then((n) => n.t);
2470
+ const { SchemaRegistry } = await import("../../../schema-DUtnZxjZ.mjs").then((n) => n.t);
2038
2471
  const collection = await new SchemaRegistry(ec.db).getCollectionWithFields(args.slug);
2039
2472
  if (!collection) return errorResult(`Collection '${args.slug}' not found`);
2040
2473
  return jsonResult(collection);
@@ -2064,7 +2497,7 @@ function createMcpServer() {
2064
2497
  requireRole(extra, Role.ADMIN);
2065
2498
  const ec = getDineway(extra);
2066
2499
  try {
2067
- const { SchemaRegistry } = await import("../../../schema-Bsi-VpYv.mjs").then((n) => n.t);
2500
+ const { SchemaRegistry } = await import("../../../schema-DUtnZxjZ.mjs").then((n) => n.t);
2068
2501
  const collection = await new SchemaRegistry(ec.db).createCollection({
2069
2502
  slug: args.slug,
2070
2503
  label: args.label,
@@ -2128,7 +2561,7 @@ function createMcpServer() {
2128
2561
  request
2129
2562
  });
2130
2563
  }
2131
- const { SchemaRegistry } = await import("../../../schema-Bsi-VpYv.mjs").then((n) => n.t);
2564
+ const { SchemaRegistry } = await import("../../../schema-DUtnZxjZ.mjs").then((n) => n.t);
2132
2565
  await new SchemaRegistry(ec.db).deleteCollection(args.slug, { force: args.force });
2133
2566
  ec.invalidateManifest();
2134
2567
  await logSchemaActivity(ec.db, locals, {
@@ -2192,7 +2625,7 @@ function createMcpServer() {
2192
2625
  requireRole(extra, Role.ADMIN);
2193
2626
  const ec = getDineway(extra);
2194
2627
  try {
2195
- const { SchemaRegistry } = await import("../../../schema-Bsi-VpYv.mjs").then((n) => n.t);
2628
+ const { SchemaRegistry } = await import("../../../schema-DUtnZxjZ.mjs").then((n) => n.t);
2196
2629
  const field = await new SchemaRegistry(ec.db).createField(args.collection, {
2197
2630
  slug: args.slug,
2198
2631
  label: args.label,
@@ -2261,7 +2694,7 @@ function createMcpServer() {
2261
2694
  request
2262
2695
  });
2263
2696
  }
2264
- const { SchemaRegistry } = await import("../../../schema-Bsi-VpYv.mjs").then((n) => n.t);
2697
+ const { SchemaRegistry } = await import("../../../schema-DUtnZxjZ.mjs").then((n) => n.t);
2265
2698
  await new SchemaRegistry(ec.db).deleteField(args.collection, args.fieldSlug);
2266
2699
  ec.invalidateManifest();
2267
2700
  await logSchemaActivity(ec.db, locals, {
@@ -2394,7 +2827,7 @@ function createMcpServer() {
2394
2827
  requireScope(extra, "content:read");
2395
2828
  const ec = getDineway(extra);
2396
2829
  try {
2397
- const { searchWithDb } = await import("../../../search-Gdrqj582.mjs").then((n) => n.t);
2830
+ const { searchWithDb } = await import("../../../search-DUKgZUlm.mjs").then((n) => n.t);
2398
2831
  return jsonResult(await searchWithDb(ec.db, args.query, {
2399
2832
  collections: args.collections,
2400
2833
  locale: args.locale,
@@ -2404,6 +2837,124 @@ function createMcpServer() {
2404
2837
  return errorResult(error);
2405
2838
  }
2406
2839
  });
2840
+ server.registerTool("byline_list", {
2841
+ title: "List Bylines",
2842
+ description: "List bylines (author/contributor credits) with optional filtering and pagination. Bylines are standalone records referenced by content items; use the returned id with content_create/content_update or byline_get. Use the nextCursor value from the response to fetch the next page.",
2843
+ inputSchema: z.object({
2844
+ search: z.string().optional().describe("Filter by display name or slug substring"),
2845
+ isGuest: z.boolean().optional().describe("Filter by guest byline state"),
2846
+ userId: z.string().optional().describe("Filter to the byline linked to a Dineway user ID"),
2847
+ locale: z.string().optional().describe("Filter by locale (omit for all)"),
2848
+ limit: z.number().int().min(1).max(100).optional().describe("Max items (default 50)"),
2849
+ cursor: z.string().min(1).max(2048).optional().describe("Pagination cursor")
2850
+ }),
2851
+ annotations: { readOnlyHint: true }
2852
+ }, async (args, extra) => {
2853
+ requireScope(extra, "content:read");
2854
+ const ec = getDineway(extra);
2855
+ try {
2856
+ const { BylineRepository } = await import("../../../byline-7xR185Ly.mjs").then((n) => n.n);
2857
+ return jsonResult(await new BylineRepository(ec.db).findMany({
2858
+ search: args.search,
2859
+ isGuest: args.isGuest,
2860
+ userId: args.userId,
2861
+ locale: args.locale,
2862
+ limit: args.limit,
2863
+ cursor: args.cursor
2864
+ }));
2865
+ } catch (error) {
2866
+ return errorResult(error);
2867
+ }
2868
+ });
2869
+ server.registerTool("byline_get", {
2870
+ title: "Get Byline",
2871
+ description: "Get a single byline by its ID, including bio, avatar, website, linked user, and any custom fields.",
2872
+ inputSchema: z.object({ id: z.string().describe("Byline ID") }),
2873
+ annotations: { readOnlyHint: true }
2874
+ }, async (args, extra) => {
2875
+ requireScope(extra, "content:read");
2876
+ const ec = getDineway(extra);
2877
+ try {
2878
+ const { BylineRepository } = await import("../../../byline-7xR185Ly.mjs").then((n) => n.n);
2879
+ const byline = await new BylineRepository(ec.db).findById(args.id);
2880
+ if (!byline) return errorResult(`Byline '${args.id}' not found`);
2881
+ return jsonResult(byline);
2882
+ } catch (error) {
2883
+ return errorResult(error);
2884
+ }
2885
+ });
2886
+ server.registerTool("byline_create", {
2887
+ title: "Create Byline",
2888
+ description: "Create a new byline (author/contributor credit). The slug must be unique and contain only lowercase letters, digits, and hyphens. Link the byline to a Dineway user via userId, or leave it as a standalone guest credit. The returned id can then be passed to content_create/content_update bylines.",
2889
+ inputSchema: z.object({ ...bylineCreateBody.shape }),
2890
+ annotations: { destructiveHint: false }
2891
+ }, async (args, extra) => {
2892
+ requireScope(extra, "content:write");
2893
+ requireRole(extra, Role.EDITOR);
2894
+ const ec = getDineway(extra);
2895
+ try {
2896
+ const { handleBylineCreate } = await import("../../../bylines-C-EL6dh3.mjs").then((n) => n.t);
2897
+ const result = await handleBylineCreate(ec.db, args);
2898
+ if (result.success) await invalidateBylines();
2899
+ return unwrap(result);
2900
+ } catch (error) {
2901
+ return errorResult(error);
2902
+ }
2903
+ });
2904
+ server.registerTool("byline_update", {
2905
+ title: "Update Byline",
2906
+ description: "Update an existing byline. Any field can be omitted to leave it unchanged. Renaming the slug must not collide with another byline.",
2907
+ inputSchema: z.object({
2908
+ id: z.string().describe("Byline ID to update"),
2909
+ ...bylineUpdateBody.shape
2910
+ })
2911
+ }, async (args, extra) => {
2912
+ requireScope(extra, "content:write");
2913
+ requireRole(extra, Role.EDITOR);
2914
+ const ec = getDineway(extra);
2915
+ try {
2916
+ const { handleBylineUpdate } = await import("../../../bylines-C-EL6dh3.mjs").then((n) => n.t);
2917
+ const { id, ...input } = args;
2918
+ const result = await handleBylineUpdate(ec.db, id, input);
2919
+ if (result.success) await invalidateBylines();
2920
+ return unwrap(result);
2921
+ } catch (error) {
2922
+ return errorResult(error);
2923
+ }
2924
+ });
2925
+ server.registerTool("byline_delete", {
2926
+ title: "Delete Byline",
2927
+ description: "Permanently delete a byline. Any content crediting this byline loses the association, and it is cleared as a primary byline where set.",
2928
+ inputSchema: z.object({ id: z.string().describe("Byline ID to delete") }),
2929
+ annotations: { destructiveHint: true }
2930
+ }, async (args, extra) => {
2931
+ requireScope(extra, "content:write");
2932
+ requireRole(extra, Role.EDITOR);
2933
+ const ec = getDineway(extra);
2934
+ try {
2935
+ const { BylineRepository } = await import("../../../byline-7xR185Ly.mjs").then((n) => n.n);
2936
+ if (!await new BylineRepository(ec.db).delete(args.id)) return errorResult(`Byline '${args.id}' not found`);
2937
+ await invalidateBylines();
2938
+ return jsonResult({ deleted: args.id });
2939
+ } catch (error) {
2940
+ return errorResult(error);
2941
+ }
2942
+ });
2943
+ server.registerTool("byline_translations", {
2944
+ title: "List Byline Translations",
2945
+ description: "Return every locale variant of a byline, identified via its shared translation group.",
2946
+ inputSchema: z.object({ id: z.string().describe("Byline ID") }),
2947
+ annotations: { readOnlyHint: true }
2948
+ }, async (args, extra) => {
2949
+ requireScope(extra, "content:read");
2950
+ const ec = getDineway(extra);
2951
+ try {
2952
+ const { handleBylineTranslations } = await import("../../../bylines-C-EL6dh3.mjs").then((n) => n.t);
2953
+ return unwrap(await handleBylineTranslations(ec.db, args.id));
2954
+ } catch (error) {
2955
+ return errorResult(error);
2956
+ }
2957
+ });
2407
2958
  server.registerTool("taxonomy_list", {
2408
2959
  title: "List Taxonomies",
2409
2960
  description: "List all taxonomy definitions (e.g. categories, tags). Taxonomies are classification systems applied to content. Each has a name, label, and can be hierarchical (categories) or flat (tags). Optionally filter by locale.",
@@ -2413,7 +2964,7 @@ function createMcpServer() {
2413
2964
  requireScope(extra, "content:read");
2414
2965
  const ec = getDineway(extra);
2415
2966
  try {
2416
- const { handleTaxonomyList } = await import("../../../taxonomies-D9Sw4wWM.mjs").then((n) => n.l);
2967
+ const { handleTaxonomyList } = await import("../../../taxonomies-BiM9NtgW.mjs").then((n) => n.l);
2417
2968
  return unwrap(await handleTaxonomyList(ec.db, { locale: args.locale }));
2418
2969
  } catch (error) {
2419
2970
  return errorResult(error);
@@ -2433,12 +2984,12 @@ function createMcpServer() {
2433
2984
  requireScope(extra, "content:read");
2434
2985
  const ec = getDineway(extra);
2435
2986
  try {
2436
- const { handleTaxonomyList } = await import("../../../taxonomies-D9Sw4wWM.mjs").then((n) => n.l);
2987
+ const { handleTaxonomyList } = await import("../../../taxonomies-BiM9NtgW.mjs").then((n) => n.l);
2437
2988
  const listResult = await handleTaxonomyList(ec.db, { locale: args.locale });
2438
2989
  if (!listResult.success) return unwrap(listResult);
2439
2990
  if (!listResult.data.taxonomies.find((t) => t.name === args.taxonomy)) return errorResult(`Taxonomy '${args.taxonomy}' not found`);
2440
- const { TaxonomyRepository } = await import("../../../taxonomy-B169Nm6B.mjs").then((n) => n.n);
2441
- const { decodeCursor, encodeCursor } = await import("../../../types-CSgR9nQB.mjs").then((n) => n.a);
2991
+ const { TaxonomyRepository } = await import("../../../taxonomy-0k_vRVsD.mjs").then((n) => n.n);
2992
+ const { decodeCursor, encodeCursor } = await import("../../../types-ChxYDRvx.mjs").then((n) => n.a);
2442
2993
  const repo = new TaxonomyRepository(ec.db);
2443
2994
  const limit = Math.min(args.limit ?? 50, 100);
2444
2995
  const terms = await repo.findByName(args.taxonomy, { locale: args.locale });
@@ -2487,7 +3038,7 @@ function createMcpServer() {
2487
3038
  requireRole(extra, Role.EDITOR);
2488
3039
  const ec = getDineway(extra);
2489
3040
  try {
2490
- const { handleTermCreate } = await import("../../../taxonomies-D9Sw4wWM.mjs").then((n) => n.l);
3041
+ const { handleTermCreate } = await import("../../../taxonomies-BiM9NtgW.mjs").then((n) => n.l);
2491
3042
  return unwrap(await handleTermCreate(ec.db, args.taxonomy, {
2492
3043
  slug: args.slug,
2493
3044
  label: args.label,
@@ -2517,7 +3068,7 @@ function createMcpServer() {
2517
3068
  requireRole(extra, Role.EDITOR);
2518
3069
  const ec = getDineway(extra);
2519
3070
  try {
2520
- const { handleTermUpdate } = await import("../../../taxonomies-D9Sw4wWM.mjs").then((n) => n.l);
3071
+ const { handleTermUpdate } = await import("../../../taxonomies-BiM9NtgW.mjs").then((n) => n.l);
2521
3072
  return unwrap(await handleTermUpdate(ec.db, args.taxonomy, args.termSlug, {
2522
3073
  slug: args.slug,
2523
3074
  label: args.label,
@@ -2542,7 +3093,7 @@ function createMcpServer() {
2542
3093
  requireRole(extra, Role.EDITOR);
2543
3094
  const ec = getDineway(extra);
2544
3095
  try {
2545
- const { handleTermDelete } = await import("../../../taxonomies-D9Sw4wWM.mjs").then((n) => n.l);
3096
+ const { handleTermDelete } = await import("../../../taxonomies-BiM9NtgW.mjs").then((n) => n.l);
2546
3097
  return unwrap(await handleTermDelete(ec.db, args.taxonomy, args.termSlug, { locale: args.locale }));
2547
3098
  } catch (error) {
2548
3099
  return errorResult(error);
@@ -2557,7 +3108,7 @@ function createMcpServer() {
2557
3108
  requireScope(extra, "content:read");
2558
3109
  const ec = getDineway(extra);
2559
3110
  try {
2560
- const { handleTermTranslations } = await import("../../../taxonomies-D9Sw4wWM.mjs").then((n) => n.l);
3111
+ const { handleTermTranslations } = await import("../../../taxonomies-BiM9NtgW.mjs").then((n) => n.l);
2561
3112
  return unwrap(await handleTermTranslations(ec.db, args.id));
2562
3113
  } catch (error) {
2563
3114
  return errorResult(error);
@@ -2572,7 +3123,7 @@ function createMcpServer() {
2572
3123
  requireScope(extra, "content:read");
2573
3124
  const ec = getDineway(extra);
2574
3125
  try {
2575
- const { handleMenuList } = await import("../../../menus-BZbXf-ej.mjs").then((n) => n.d);
3126
+ const { handleMenuList } = await import("../../../menus-CmyIkRG5.mjs").then((n) => n.d);
2576
3127
  return unwrap(await handleMenuList(ec.db, { locale: args.locale }));
2577
3128
  } catch (error) {
2578
3129
  return errorResult(error);
@@ -2590,7 +3141,7 @@ function createMcpServer() {
2590
3141
  requireScope(extra, "content:read");
2591
3142
  const ec = getDineway(extra);
2592
3143
  try {
2593
- const { handleMenuGet } = await import("../../../menus-BZbXf-ej.mjs").then((n) => n.d);
3144
+ const { handleMenuGet } = await import("../../../menus-CmyIkRG5.mjs").then((n) => n.d);
2594
3145
  return unwrap(await handleMenuGet(ec.db, args.name, { locale: args.locale }));
2595
3146
  } catch (error) {
2596
3147
  return errorResult(error);
@@ -2605,7 +3156,7 @@ function createMcpServer() {
2605
3156
  requireScope(extra, "content:read");
2606
3157
  const ec = getDineway(extra);
2607
3158
  try {
2608
- const { handleMenuTranslations } = await import("../../../menus-BZbXf-ej.mjs").then((n) => n.d);
3159
+ const { handleMenuTranslations } = await import("../../../menus-CmyIkRG5.mjs").then((n) => n.d);
2609
3160
  return unwrap(await handleMenuTranslations(ec.db, args.id));
2610
3161
  } catch (error) {
2611
3162
  return errorResult(error);
@@ -2625,7 +3176,7 @@ function createMcpServer() {
2625
3176
  requireRole(extra, Role.EDITOR);
2626
3177
  const ec = getDineway(extra);
2627
3178
  try {
2628
- const { handleMenuCreate } = await import("../../../menus-BZbXf-ej.mjs").then((n) => n.d);
3179
+ const { handleMenuCreate } = await import("../../../menus-CmyIkRG5.mjs").then((n) => n.d);
2629
3180
  return unwrap(await handleMenuCreate(ec.db, {
2630
3181
  name: args.name,
2631
3182
  label: args.label,
@@ -2649,7 +3200,7 @@ function createMcpServer() {
2649
3200
  requireRole(extra, Role.EDITOR);
2650
3201
  const ec = getDineway(extra);
2651
3202
  try {
2652
- const { handleMenuUpdate } = await import("../../../menus-BZbXf-ej.mjs").then((n) => n.d);
3203
+ const { handleMenuUpdate } = await import("../../../menus-CmyIkRG5.mjs").then((n) => n.d);
2653
3204
  return unwrap(await handleMenuUpdate(ec.db, args.name, {
2654
3205
  label: args.label,
2655
3206
  locale: args.locale
@@ -2671,7 +3222,7 @@ function createMcpServer() {
2671
3222
  requireRole(extra, Role.EDITOR);
2672
3223
  const ec = getDineway(extra);
2673
3224
  try {
2674
- const { handleMenuDelete } = await import("../../../menus-BZbXf-ej.mjs").then((n) => n.d);
3225
+ const { handleMenuDelete } = await import("../../../menus-CmyIkRG5.mjs").then((n) => n.d);
2675
3226
  return unwrap(await handleMenuDelete(ec.db, args.name, { locale: args.locale }));
2676
3227
  } catch (error) {
2677
3228
  return errorResult(error);
@@ -2706,7 +3257,7 @@ function createMcpServer() {
2706
3257
  requireRole(extra, Role.EDITOR);
2707
3258
  const ec = getDineway(extra);
2708
3259
  try {
2709
- const { handleMenuSetItems } = await import("../../../menus-BZbXf-ej.mjs").then((n) => n.d);
3260
+ const { handleMenuSetItems } = await import("../../../menus-CmyIkRG5.mjs").then((n) => n.d);
2710
3261
  return unwrap(await handleMenuSetItems(ec.db, args.name, args.items, { locale: args.locale }));
2711
3262
  } catch (error) {
2712
3263
  return errorResult(error);
@@ -2753,7 +3304,7 @@ function createMcpServer() {
2753
3304
  requireRole(extra, Role.ADMIN);
2754
3305
  const ec = getDineway(extra);
2755
3306
  try {
2756
- const { handleSettingsGet } = await import("../../../settings-DlBsT2VS.mjs").then((n) => n.r);
3307
+ const { handleSettingsGet } = await import("../../../settings-EzADu-dd.mjs").then((n) => n.r);
2757
3308
  return unwrap(await handleSettingsGet(ec.db, ec.storage));
2758
3309
  } catch (error) {
2759
3310
  return errorResult(error);
@@ -2790,7 +3341,7 @@ function createMcpServer() {
2790
3341
  request
2791
3342
  });
2792
3343
  }
2793
- const { handleSettingsUpdate } = await import("../../../settings-DlBsT2VS.mjs").then((n) => n.r);
3344
+ const { handleSettingsUpdate } = await import("../../../settings-EzADu-dd.mjs").then((n) => n.r);
2794
3345
  const result = await handleSettingsUpdate(ec.db, ec.storage, settingsInput);
2795
3346
  if (!result.success) return unwrap(result);
2796
3347
  await logSiteActivitySafely(ec.db, locals, {
@@ -2812,8 +3363,36 @@ function createMcpServer() {
2812
3363
  return errorResult(error);
2813
3364
  }
2814
3365
  });
3366
+ if (options.pluginMcpRegistry) registerPluginMcpRegistry(server, options.pluginMcpRegistry, {
3367
+ resolveContext: resolvePluginMcpExecutionContext,
3368
+ authorizeTarget: options.authorizePluginMcpTarget,
3369
+ authorizeSensitiveOutput: options.authorizePluginMcpSensitiveOutput,
3370
+ executeCommand: options.executePluginMcpCommand
3371
+ });
2815
3372
  return server;
2816
3373
  }
3374
+ function resolvePluginMcpExecutionContext(plugin, requestExtra) {
3375
+ if (!isMcpRequestExtra(requestExtra)) throw new Error("Dineway MCP request context is unavailable");
3376
+ const payload = getExtra(requestExtra);
3377
+ const resolvedActor = resolveActorIdentity(actorLocals(payload));
3378
+ return {
3379
+ plugin,
3380
+ actor: {
3381
+ type: resolvedActor.actorType,
3382
+ id: resolvedActor.actorId,
3383
+ userId: payload.userId || null,
3384
+ role: payload.userRole,
3385
+ authMethod: payload.authToken?.type ?? "session",
3386
+ tokenScopes: payload.tokenScopes
3387
+ },
3388
+ db: payload.dineway.db,
3389
+ storage: payload.dineway.storage,
3390
+ http: typeof payload.dineway.getPluginHttpAccess === "function" ? payload.dineway.getPluginHttpAccess(plugin.id) : void 0
3391
+ };
3392
+ }
3393
+ function isMcpRequestExtra(value) {
3394
+ return typeof value === "object" && value !== null;
3395
+ }
2817
3396
 
2818
3397
  //#endregion
2819
3398
  //#region src/astro/routes/api/mcp.ts
@@ -2834,7 +3413,11 @@ const POST = async ({ request, locals }) => {
2834
3413
  const { dineway, user } = locals;
2835
3414
  if (!dineway) return apiError("NOT_CONFIGURED", "Dineway is not initialized", 500);
2836
3415
  if (!user) return apiError("UNAUTHORIZED", "Authentication required", 401);
2837
- const server = createMcpServer();
3416
+ const server = createMcpServer({
3417
+ seoProviderService: new SeoProviderEvidenceService(new ForgewaySeoGatewayClient()),
3418
+ pluginMcpRegistry: dineway.getPluginMcpRegistry(),
3419
+ executePluginMcpCommand: createReviewedPluginMcpCommandExecutor()
3420
+ });
2838
3421
  try {
2839
3422
  const transport = new WebStandardStreamableHTTPServerTransport({ sessionIdGenerator: void 0 });
2840
3423
  await server.connect(transport);