emdash 0.40.1 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1240) hide show
  1. package/dist/action-token-CbKDcPJi.mjs +26 -0
  2. package/dist/action-token-CbKDcPJi.mjs.map +1 -0
  3. package/dist/activation-PtniBLt9.mjs +382 -0
  4. package/dist/activation-PtniBLt9.mjs.map +1 -0
  5. package/dist/adapters-C_Tf5x90.d.mts +171 -0
  6. package/dist/adapters-C_Tf5x90.d.mts.map +1 -0
  7. package/dist/allowed-origins-U1z4TdEZ.mjs +116 -0
  8. package/dist/allowed-origins-U1z4TdEZ.mjs.map +1 -0
  9. package/dist/api/route-utils.d.mts +4 -4
  10. package/dist/api/route-utils.mjs +46 -45
  11. package/dist/api/route-utils.mjs.map +1 -1
  12. package/dist/api/schemas/index.d.mts +2 -2
  13. package/dist/api/schemas/index.mjs +10 -10
  14. package/dist/api-CXwQkV_m.mjs +5122 -0
  15. package/dist/api-CXwQkV_m.mjs.map +1 -0
  16. package/dist/api-tokens-89WlohEN.mjs +166 -0
  17. package/dist/api-tokens-89WlohEN.mjs.map +1 -0
  18. package/dist/apply-Do3KNnUk.mjs +1659 -0
  19. package/dist/apply-Do3KNnUk.mjs.map +1 -0
  20. package/dist/approvals-CAX9Yw33.mjs +460 -0
  21. package/dist/approvals-CAX9Yw33.mjs.map +1 -0
  22. package/dist/artifact-fetch-B9W4CEST.mjs +659 -0
  23. package/dist/artifact-fetch-B9W4CEST.mjs.map +1 -0
  24. package/dist/astro/index.d.mts +14 -14
  25. package/dist/astro/index.mjs +20 -24
  26. package/dist/astro/index.mjs.map +1 -1
  27. package/dist/astro/middleware/auth.d.mts +12 -12
  28. package/dist/astro/middleware/auth.mjs +10 -10
  29. package/dist/astro/middleware/media-usage-write-fence.mjs +5 -5
  30. package/dist/astro/middleware/redirect.mjs +7 -7
  31. package/dist/astro/middleware/request-context.mjs +3 -3
  32. package/dist/astro/middleware/setup.mjs +1 -1
  33. package/dist/astro/middleware.d.mts +12 -12
  34. package/dist/astro/middleware.mjs +109 -106
  35. package/dist/astro/middleware.mjs.map +1 -1
  36. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +14 -14
  37. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +14 -14
  38. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +6 -6
  39. package/dist/astro/routes/api/admin/api-tokens/index.mjs +7 -7
  40. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +7 -7
  41. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +17 -17
  42. package/dist/astro/routes/api/admin/byline-fields/index.mjs +17 -17
  43. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +17 -17
  44. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +23 -23
  45. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +23 -23
  46. package/dist/astro/routes/api/admin/bylines/index.mjs +23 -23
  47. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +18 -18
  48. package/dist/astro/routes/api/admin/comments/_id_.mjs +7 -7
  49. package/dist/astro/routes/api/admin/comments/bulk.mjs +17 -17
  50. package/dist/astro/routes/api/admin/comments/counts.mjs +7 -7
  51. package/dist/astro/routes/api/admin/comments/index.mjs +17 -17
  52. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -6
  53. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -5
  54. package/dist/astro/routes/api/admin/media-usage/activation.mjs +20 -20
  55. package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +22 -22
  56. package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +22 -22
  57. package/dist/astro/routes/api/admin/media-usage/progress.mjs +25 -25
  58. package/dist/astro/routes/api/admin/media-usage/repair.mjs +31 -31
  59. package/dist/astro/routes/api/admin/media-usage/work/index.mjs +22 -22
  60. package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +22 -22
  61. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +6 -6
  62. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +6 -6
  63. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +8 -8
  64. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +8 -8
  65. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +72 -68
  66. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  67. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +7 -7
  68. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +71 -67
  69. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
  70. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +72 -68
  71. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  72. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +82 -78
  73. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  74. package/dist/astro/routes/api/admin/plugins/index.mjs +72 -68
  75. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  76. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +5 -5
  77. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +71 -67
  78. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  79. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +81 -77
  80. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  81. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +71 -67
  82. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  83. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +72 -68
  84. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
  85. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +83 -79
  86. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
  87. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +9 -9
  88. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +74 -70
  89. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  90. package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.mjs +7 -7
  91. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +72 -68
  92. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -1
  93. package/dist/astro/routes/api/admin/plugins/updates.mjs +71 -67
  94. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  95. package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.mjs +6 -6
  96. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +71 -67
  97. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  98. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +5 -5
  99. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +71 -67
  100. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  101. package/dist/astro/routes/api/admin/transfer/_...path_.mjs +4 -4
  102. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs +40 -40
  103. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs +40 -40
  104. package/dist/astro/routes/api/admin/transfer/approvals/index.mjs +42 -42
  105. package/dist/astro/routes/api/admin/transfer/capabilities.mjs +42 -42
  106. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs +42 -42
  107. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs +43 -43
  108. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs +43 -43
  109. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs +42 -42
  110. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs +43 -43
  111. package/dist/astro/routes/api/admin/transfer/exports/index.mjs +44 -44
  112. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs +42 -42
  113. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs +42 -42
  114. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs +44 -44
  115. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs +42 -42
  116. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs +44 -44
  117. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs +42 -42
  118. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs +42 -42
  119. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs +44 -44
  120. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs +42 -42
  121. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs +42 -42
  122. package/dist/astro/routes/api/admin/transfer/imports/index.mjs +44 -44
  123. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +5 -5
  124. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +4 -4
  125. package/dist/astro/routes/api/admin/users/_id_/index.mjs +15 -15
  126. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +6 -6
  127. package/dist/astro/routes/api/admin/users/index.mjs +14 -14
  128. package/dist/astro/routes/api/auth/dev-bypass.mjs +6 -6
  129. package/dist/astro/routes/api/auth/invite/accept.mjs +4 -4
  130. package/dist/astro/routes/api/auth/invite/complete.mjs +18 -18
  131. package/dist/astro/routes/api/auth/invite/index.mjs +16 -16
  132. package/dist/astro/routes/api/auth/invite/register-options.mjs +17 -17
  133. package/dist/astro/routes/api/auth/logout.mjs +5 -5
  134. package/dist/astro/routes/api/auth/magic-link/send.mjs +18 -18
  135. package/dist/astro/routes/api/auth/magic-link/verify.mjs +14 -14
  136. package/dist/astro/routes/api/auth/me.mjs +15 -15
  137. package/dist/astro/routes/api/auth/mode.mjs +5 -5
  138. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +3 -3
  139. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  140. package/dist/astro/routes/api/auth/passkey/_id_.mjs +14 -14
  141. package/dist/astro/routes/api/auth/passkey/index.mjs +4 -4
  142. package/dist/astro/routes/api/auth/passkey/options.mjs +19 -19
  143. package/dist/astro/routes/api/auth/passkey/register/options.mjs +17 -17
  144. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +18 -18
  145. package/dist/astro/routes/api/auth/passkey/verify.mjs +18 -18
  146. package/dist/astro/routes/api/auth/signup/complete.mjs +18 -18
  147. package/dist/astro/routes/api/auth/signup/request.mjs +17 -17
  148. package/dist/astro/routes/api/auth/signup/verify.mjs +4 -4
  149. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +12 -12
  150. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +18 -18
  151. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +5 -5
  152. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +17 -17
  153. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +5 -5
  154. package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs +17 -17
  155. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +5 -5
  156. package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs +11 -11
  157. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +31 -31
  158. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +17 -17
  159. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts +1 -2
  160. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts.map +1 -1
  161. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +42 -53
  162. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
  163. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +34 -29
  164. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
  165. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +5 -5
  166. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +5 -5
  167. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +17 -17
  168. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +25 -24
  169. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
  170. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +5 -5
  171. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +17 -17
  172. package/dist/astro/routes/api/content/_collection_/_id_.d.mts.map +1 -1
  173. package/dist/astro/routes/api/content/_collection_/_id_.mjs +18 -18
  174. package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
  175. package/dist/astro/routes/api/content/_collection_/authors.mjs +5 -5
  176. package/dist/astro/routes/api/content/_collection_/index.mjs +15 -15
  177. package/dist/astro/routes/api/content/_collection_/trash.mjs +15 -15
  178. package/dist/astro/routes/api/dashboard.mjs +10 -9
  179. package/dist/astro/routes/api/dashboard.mjs.map +1 -1
  180. package/dist/astro/routes/api/dev/emails.mjs +5 -5
  181. package/dist/astro/routes/api/health.mjs +6 -6
  182. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  183. package/dist/astro/routes/api/import/probe.mjs +23 -23
  184. package/dist/astro/routes/api/import/wordpress/analyze.mjs +6 -6
  185. package/dist/astro/routes/api/import/wordpress/execute.d.mts +13 -13
  186. package/dist/astro/routes/api/import/wordpress/execute.mjs +16 -16
  187. package/dist/astro/routes/api/import/wordpress/media.d.mts +12 -12
  188. package/dist/astro/routes/api/import/wordpress/media.mjs +19 -19
  189. package/dist/astro/routes/api/import/wordpress/prepare.mjs +18 -18
  190. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +13 -13
  191. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +28 -28
  192. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  193. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +23 -23
  194. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +13 -13
  195. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +34 -34
  196. package/dist/astro/routes/api/manifest.mjs +6 -6
  197. package/dist/astro/routes/api/mcp.mjs +91 -91
  198. package/dist/astro/routes/api/media/_id_/confirm.mjs +19 -19
  199. package/dist/astro/routes/api/media/_id_/replace.mjs +16 -16
  200. package/dist/astro/routes/api/media/_id_/upload.mjs +9 -9
  201. package/dist/astro/routes/api/media/_id_/usage.mjs +33 -33
  202. package/dist/astro/routes/api/media/_id_.mjs +31 -31
  203. package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs +6 -6
  204. package/dist/astro/routes/api/media/file/_...key_.mjs +9 -9
  205. package/dist/astro/routes/api/media/folders/_id_.mjs +16 -16
  206. package/dist/astro/routes/api/media/folders/index.mjs +16 -16
  207. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +5 -5
  208. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +5 -5
  209. package/dist/astro/routes/api/media/providers/index.mjs +5 -5
  210. package/dist/astro/routes/api/media/upload-url.mjs +18 -18
  211. package/dist/astro/routes/api/media.mjs +35 -35
  212. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +17 -17
  213. package/dist/astro/routes/api/menus/_name_/items.mjs +17 -17
  214. package/dist/astro/routes/api/menus/_name_/reorder.mjs +17 -17
  215. package/dist/astro/routes/api/menus/_name_/translations.mjs +17 -17
  216. package/dist/astro/routes/api/menus/_name_.mjs +17 -17
  217. package/dist/astro/routes/api/menus/index.mjs +17 -17
  218. package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
  219. package/dist/astro/routes/api/oauth/device/authorize.d.mts +2 -1
  220. package/dist/astro/routes/api/oauth/device/authorize.d.mts.map +1 -1
  221. package/dist/astro/routes/api/oauth/device/authorize.mjs +23 -9
  222. package/dist/astro/routes/api/oauth/device/authorize.mjs.map +1 -1
  223. package/dist/astro/routes/api/oauth/device/code.mjs +11 -11
  224. package/dist/astro/routes/api/oauth/device/token.mjs +10 -10
  225. package/dist/astro/routes/api/oauth/register.mjs +5 -5
  226. package/dist/astro/routes/api/oauth/token/refresh.mjs +8 -8
  227. package/dist/astro/routes/api/oauth/token/revoke.mjs +8 -8
  228. package/dist/astro/routes/api/oauth/token.mjs +8 -8
  229. package/dist/astro/routes/api/openapi.json.mjs +20 -20
  230. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +11 -11
  231. package/dist/astro/routes/api/redirects/404s/index.mjs +19 -19
  232. package/dist/astro/routes/api/redirects/404s/summary.mjs +19 -19
  233. package/dist/astro/routes/api/redirects/_id_.mjs +19 -19
  234. package/dist/astro/routes/api/redirects/index.mjs +19 -19
  235. package/dist/astro/routes/api/relations/_id_/index.mjs +34 -29
  236. package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
  237. package/dist/astro/routes/api/relations/index.mjs +36 -31
  238. package/dist/astro/routes/api/relations/index.mjs.map +1 -1
  239. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +5 -5
  240. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +5 -5
  241. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs +71 -67
  242. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs.map +1 -1
  243. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs +71 -67
  244. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs.map +1 -1
  245. package/dist/astro/routes/api/schema/block-types/index.mjs +71 -67
  246. package/dist/astro/routes/api/schema/block-types/index.mjs.map +1 -1
  247. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +73 -69
  248. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  249. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +71 -67
  250. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  251. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +71 -67
  252. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  253. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +71 -67
  254. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  255. package/dist/astro/routes/api/schema/collections/index.mjs +71 -67
  256. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  257. package/dist/astro/routes/api/schema/collections/reorder.mjs +71 -67
  258. package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
  259. package/dist/astro/routes/api/schema/index.mjs +16 -16
  260. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +71 -67
  261. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  262. package/dist/astro/routes/api/schema/orphans/index.mjs +71 -67
  263. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  264. package/dist/astro/routes/api/search/enable.mjs +19 -19
  265. package/dist/astro/routes/api/search/index.mjs +18 -18
  266. package/dist/astro/routes/api/search/rebuild.mjs +19 -19
  267. package/dist/astro/routes/api/search/stats.mjs +9 -9
  268. package/dist/astro/routes/api/search/suggest.mjs +18 -18
  269. package/dist/astro/routes/api/sections/_slug_.mjs +18 -18
  270. package/dist/astro/routes/api/sections/index.mjs +18 -18
  271. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +7 -7
  272. package/dist/astro/routes/api/settings/backups/archives/index.mjs +7 -7
  273. package/dist/astro/routes/api/settings/backups/export.mjs +7 -7
  274. package/dist/astro/routes/api/settings/backups/index.mjs +8 -8
  275. package/dist/astro/routes/api/settings/email.mjs +6 -6
  276. package/dist/astro/routes/api/settings.mjs +21 -21
  277. package/dist/astro/routes/api/setup/admin-verify.mjs +19 -19
  278. package/dist/astro/routes/api/setup/admin.mjs +18 -18
  279. package/dist/astro/routes/api/setup/dev-bypass.mjs +45 -39
  280. package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
  281. package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
  282. package/dist/astro/routes/api/setup/index.mjs +50 -44
  283. package/dist/astro/routes/api/setup/index.mjs.map +1 -1
  284. package/dist/astro/routes/api/setup/status.mjs +6 -6
  285. package/dist/astro/routes/api/snapshot.mjs +8 -8
  286. package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +23 -23
  287. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +23 -23
  288. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +23 -23
  289. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +23 -23
  290. package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +22 -22
  291. package/dist/astro/routes/api/taxonomies/_name_.mjs +23 -23
  292. package/dist/astro/routes/api/taxonomies/bulk-tag.mjs +36 -35
  293. package/dist/astro/routes/api/taxonomies/bulk-tag.mjs.map +1 -1
  294. package/dist/astro/routes/api/taxonomies/index.mjs +23 -23
  295. package/dist/astro/routes/api/themes/preview.mjs +6 -6
  296. package/dist/astro/routes/api/typegen.mjs +8 -8
  297. package/dist/astro/routes/api/visual-editing/action-token.mjs +6 -6
  298. package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs +19 -19
  299. package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs +4 -4
  300. package/dist/astro/routes/api/well-known/auth.mjs +1 -1
  301. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
  302. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
  303. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +16 -16
  304. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +19 -19
  305. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +19 -19
  306. package/dist/astro/routes/api/widget-areas/_name_.mjs +9 -9
  307. package/dist/astro/routes/api/widget-areas/index.mjs +19 -19
  308. package/dist/astro/routes/api/widget-components.mjs +5 -5
  309. package/dist/astro/routes/robots.txt.mjs +6 -6
  310. package/dist/astro/routes/sitemap-_collection_.xml.mjs +9 -9
  311. package/dist/astro/routes/sitemap.xml.mjs +7 -7
  312. package/dist/astro/types.d.mts +24 -18
  313. package/dist/astro/types.d.mts.map +1 -1
  314. package/dist/audit-CrgmE9LE.mjs +127 -0
  315. package/dist/audit-CrgmE9LE.mjs.map +1 -0
  316. package/dist/auth/providers/github.d.mts +1 -1
  317. package/dist/auth/providers/google.d.mts +1 -1
  318. package/dist/authoritative-records-C2YzIdbu.mjs +5172 -0
  319. package/dist/authoritative-records-C2YzIdbu.mjs.map +1 -0
  320. package/dist/authorize-WgdKF8QY.mjs +49 -0
  321. package/dist/authorize-WgdKF8QY.mjs.map +1 -0
  322. package/dist/backup-Ck8_lMO3.mjs +246 -0
  323. package/dist/backup-Ck8_lMO3.mjs.map +1 -0
  324. package/dist/block-types-BQ90asVI.mjs +132 -0
  325. package/dist/block-types-BQ90asVI.mjs.map +1 -0
  326. package/dist/block-values-ACFqgB1D.mjs +175 -0
  327. package/dist/block-values-ACFqgB1D.mjs.map +1 -0
  328. package/dist/bundle-Db1iNMv_.mjs +667 -0
  329. package/dist/bundle-Db1iNMv_.mjs.map +1 -0
  330. package/dist/byline-BayaYGoj.mjs +909 -0
  331. package/dist/byline-BayaYGoj.mjs.map +1 -0
  332. package/dist/byline-fields-B8HH-35f.mjs +254 -0
  333. package/dist/byline-fields-B8HH-35f.mjs.map +1 -0
  334. package/dist/byline-fields-hMPjf6Eu.mjs +123 -0
  335. package/dist/byline-fields-hMPjf6Eu.mjs.map +1 -0
  336. package/dist/byline-registry-B_EK_TQf.mjs +406 -0
  337. package/dist/byline-registry-B_EK_TQf.mjs.map +1 -0
  338. package/dist/bylines-DFAaFXWi.mjs +214 -0
  339. package/dist/bylines-DFAaFXWi.mjs.map +1 -0
  340. package/dist/bylines-DkIxUxmr.mjs +232 -0
  341. package/dist/bylines-DkIxUxmr.mjs.map +1 -0
  342. package/dist/cache-DkvhQ8XE.mjs +108 -0
  343. package/dist/cache-DkvhQ8XE.mjs.map +1 -0
  344. package/dist/canonical-CcSuuTlH.mjs +174 -0
  345. package/dist/canonical-CcSuuTlH.mjs.map +1 -0
  346. package/dist/capture-triggers-DJEoOTOq.mjs +362 -0
  347. package/dist/capture-triggers-DJEoOTOq.mjs.map +1 -0
  348. package/dist/challenge-store-CvBl81AQ.mjs +51 -0
  349. package/dist/challenge-store-CvBl81AQ.mjs.map +1 -0
  350. package/dist/checksum-CClweQzI.mjs +162 -0
  351. package/dist/checksum-CClweQzI.mjs.map +1 -0
  352. package/dist/chrome-tags-D5caJwwp.mjs +24 -0
  353. package/dist/chrome-tags-D5caJwwp.mjs.map +1 -0
  354. package/dist/chunks-DwBaj8aT.mjs +25 -0
  355. package/dist/chunks-DwBaj8aT.mjs.map +1 -0
  356. package/dist/cli/index.mjs +374 -761
  357. package/dist/cli/index.mjs.map +1 -1
  358. package/dist/client/cf-access.d.mts +1 -1
  359. package/dist/client/index.d.mts +32 -32
  360. package/dist/client/index.mjs +2 -2
  361. package/dist/collection-deletion-CLCdXsnV.mjs +436 -0
  362. package/dist/collection-deletion-CLCdXsnV.mjs.map +1 -0
  363. package/dist/collection-deletion-processor-hNw8x01F.mjs +217 -0
  364. package/dist/collection-deletion-processor-hNw8x01F.mjs.map +1 -0
  365. package/dist/collection-slugs-cache-CUuiduLq.mjs +85 -0
  366. package/dist/collection-slugs-cache-CUuiduLq.mjs.map +1 -0
  367. package/dist/comment-D2uvL63j.mjs +313 -0
  368. package/dist/comment-D2uvL63j.mjs.map +1 -0
  369. package/dist/comment-reaction-DevUuzg4.mjs +85 -0
  370. package/dist/comment-reaction-DevUuzg4.mjs.map +1 -0
  371. package/dist/comments-Cq0s7_hO.mjs +195 -0
  372. package/dist/comments-Cq0s7_hO.mjs.map +1 -0
  373. package/dist/comments-M4EDYAHw.mjs +99 -0
  374. package/dist/comments-M4EDYAHw.mjs.map +1 -0
  375. package/dist/components-CuIGwXMs.mjs +108 -0
  376. package/dist/components-CuIGwXMs.mjs.map +1 -0
  377. package/dist/config-52Ea5IWt.d.mts +39 -0
  378. package/dist/config-52Ea5IWt.d.mts.map +1 -0
  379. package/dist/config-CCz3xOLc.mjs +242 -0
  380. package/dist/config-CCz3xOLc.mjs.map +1 -0
  381. package/dist/config-D3d5Qudq.d.mts +6669 -0
  382. package/dist/config-D3d5Qudq.d.mts.map +1 -0
  383. package/dist/content-CbnufDsM.mjs +2018 -0
  384. package/dist/content-CbnufDsM.mjs.map +1 -0
  385. package/dist/content-list-query-D_7B1FE5.d.mts +26 -0
  386. package/dist/content-list-query-D_7B1FE5.d.mts.map +1 -0
  387. package/dist/content-policy-CYu6K1KB.mjs +46 -0
  388. package/dist/content-policy-CYu6K1KB.mjs.map +1 -0
  389. package/dist/content-repair-DlDUgFGp.mjs +442 -0
  390. package/dist/content-repair-DlDUgFGp.mjs.map +1 -0
  391. package/dist/context-CGQLA1-a.mjs +1922 -0
  392. package/dist/context-CGQLA1-a.mjs.map +1 -0
  393. package/dist/cron-c4D5C5Fx.mjs +284 -0
  394. package/dist/cron-c4D5C5Fx.mjs.map +1 -0
  395. package/dist/dashboard-CBq9kmOn.mjs +151 -0
  396. package/dist/dashboard-CBq9kmOn.mjs.map +1 -0
  397. package/dist/db/index.d.mts +3 -3
  398. package/dist/db/index.mjs +1 -1
  399. package/dist/db/libsql-migrations.d.mts +1 -1
  400. package/dist/db/libsql-migrations.mjs +4 -4
  401. package/dist/db/libsql.d.mts +1 -1
  402. package/dist/db/postgres-migrations.d.mts +1 -1
  403. package/dist/db/postgres-migrations.mjs +4 -4
  404. package/dist/db/postgres.d.mts +1 -1
  405. package/dist/db/sqlite-migrations.d.mts +1 -1
  406. package/dist/db/sqlite-migrations.mjs +4 -4
  407. package/dist/db/sqlite.d.mts +1 -1
  408. package/dist/db/sqlite.mjs +1 -1
  409. package/dist/default-DPsys51U.mjs +81 -0
  410. package/dist/default-DPsys51U.mjs.map +1 -0
  411. package/dist/deferred-tasks-CZ7rzBdo.d.mts +9 -0
  412. package/dist/deferred-tasks-CZ7rzBdo.d.mts.map +1 -0
  413. package/dist/dev-typegen-HRxwLRcT.mjs +29 -0
  414. package/dist/dev-typegen-HRxwLRcT.mjs.map +1 -0
  415. package/dist/device-flow-OcSqE9uY.mjs +521 -0
  416. package/dist/device-flow-OcSqE9uY.mjs.map +1 -0
  417. package/dist/digest-DVZ--cE9.mjs +194 -0
  418. package/dist/digest-DVZ--cE9.mjs.map +1 -0
  419. package/dist/direct-executor-DyjAqkpT.mjs +104 -0
  420. package/dist/direct-executor-DyjAqkpT.mjs.map +1 -0
  421. package/dist/dist-FPR93_xf.mjs +810 -0
  422. package/dist/dist-FPR93_xf.mjs.map +1 -0
  423. package/dist/email-console-DyQIgEnz.mjs +50 -0
  424. package/dist/email-console-DyQIgEnz.mjs.map +1 -0
  425. package/dist/email-locale-BYb16rVd.mjs +25 -0
  426. package/dist/email-locale-BYb16rVd.mjs.map +1 -0
  427. package/dist/emdash-runtime-CrzxJFmF.mjs +4214 -0
  428. package/dist/emdash-runtime-CrzxJFmF.mjs.map +1 -0
  429. package/dist/enrich-DBtCncE2.mjs +194 -0
  430. package/dist/enrich-DBtCncE2.mjs.map +1 -0
  431. package/dist/entry-lock-BN5y4YbO.d.mts +4481 -0
  432. package/dist/entry-lock-BN5y4YbO.d.mts.map +1 -0
  433. package/dist/entry-lock-BaRBHCsH.mjs +1173 -0
  434. package/dist/entry-lock-BaRBHCsH.mjs.map +1 -0
  435. package/dist/entry-lock-C6NcnZPV.mjs +163 -0
  436. package/dist/entry-lock-C6NcnZPV.mjs.map +1 -0
  437. package/dist/entry-locks-BTyQLdbC.mjs +167 -0
  438. package/dist/entry-locks-BTyQLdbC.mjs.map +1 -0
  439. package/dist/error-BfsNNrIE.mjs +90 -0
  440. package/dist/error-BfsNNrIE.mjs.map +1 -0
  441. package/dist/errors-BN1QAnEY.mjs +460 -0
  442. package/dist/errors-BN1QAnEY.mjs.map +1 -0
  443. package/dist/errors-Bt3goF8I.mjs +120 -0
  444. package/dist/errors-Bt3goF8I.mjs.map +1 -0
  445. package/dist/escape-BveidMa2.mjs +9 -0
  446. package/dist/escape-BveidMa2.mjs.map +1 -0
  447. package/dist/fence-Bb_IbCxI.mjs +162 -0
  448. package/dist/fence-Bb_IbCxI.mjs.map +1 -0
  449. package/dist/field-defs-cache-CsZctvbu.mjs +77 -0
  450. package/dist/field-defs-cache-CsZctvbu.mjs.map +1 -0
  451. package/dist/field-map-6m9rF49t.mjs +83 -0
  452. package/dist/field-map-6m9rF49t.mjs.map +1 -0
  453. package/dist/focal-point-CZ3d1wK5.mjs +23 -0
  454. package/dist/focal-point-CZ3d1wK5.mjs.map +1 -0
  455. package/dist/fts-manager-CCaZTp8y.mjs +443 -0
  456. package/dist/fts-manager-CCaZTp8y.mjs.map +1 -0
  457. package/dist/gc-xowRjczI.mjs +75 -0
  458. package/dist/gc-xowRjczI.mjs.map +1 -0
  459. package/dist/hash-COVK27Pc.mjs +37 -0
  460. package/dist/hash-COVK27Pc.mjs.map +1 -0
  461. package/dist/hook-result-CYSk0XFe.d.mts +31 -0
  462. package/dist/hook-result-CYSk0XFe.d.mts.map +1 -0
  463. package/dist/hreflang-CChPV7jx.mjs +105 -0
  464. package/dist/hreflang-CChPV7jx.mjs.map +1 -0
  465. package/dist/hreflang-DRslq3QI.d.mts +50 -0
  466. package/dist/hreflang-DRslq3QI.d.mts.map +1 -0
  467. package/dist/http-route-dispatch-CAdp2onn.mjs +339 -0
  468. package/dist/http-route-dispatch-CAdp2onn.mjs.map +1 -0
  469. package/dist/identity-NVTOOQyq.mjs +35 -0
  470. package/dist/identity-NVTOOQyq.mjs.map +1 -0
  471. package/dist/import-wpSO2N0x.mjs +2020 -0
  472. package/dist/import-wpSO2N0x.mjs.map +1 -0
  473. package/dist/index-CDs2wq4X.d.mts +623 -0
  474. package/dist/index-CDs2wq4X.d.mts.map +1 -0
  475. package/dist/index.d.mts +24 -24
  476. package/dist/index.mjs +103 -101
  477. package/dist/install-finalization-D9R9R-W8.mjs +58 -0
  478. package/dist/install-finalization-D9R9R-W8.mjs.map +1 -0
  479. package/dist/keys-Bck6LBfF.mjs +61 -0
  480. package/dist/keys-Bck6LBfF.mjs.map +1 -0
  481. package/dist/kinds-CYmRESWj.mjs +974 -0
  482. package/dist/kinds-CYmRESWj.mjs.map +1 -0
  483. package/dist/lifecycle-C815ZQfV.mjs +25 -0
  484. package/dist/lifecycle-C815ZQfV.mjs.map +1 -0
  485. package/dist/load-D99axixL.mjs +28 -0
  486. package/dist/load-D99axixL.mjs.map +1 -0
  487. package/dist/loader-CrRPfkHS.mjs +1197 -0
  488. package/dist/loader-CrRPfkHS.mjs.map +1 -0
  489. package/dist/loops-DMKlygqX.mjs +203 -0
  490. package/dist/loops-DMKlygqX.mjs.map +1 -0
  491. package/dist/manifest-builder-BQzCHNgB.mjs +189 -0
  492. package/dist/manifest-builder-BQzCHNgB.mjs.map +1 -0
  493. package/dist/manifest-schema-Ci2gmd0u.mjs +492 -0
  494. package/dist/manifest-schema-Ci2gmd0u.mjs.map +1 -0
  495. package/dist/media/image-endpoint.mjs +1 -1
  496. package/dist/media/index.d.mts +1 -1
  497. package/dist/media/index.mjs +4 -4
  498. package/dist/media/local-runtime.d.mts +14 -14
  499. package/dist/media/local-runtime.mjs +6 -6
  500. package/dist/media-BUQePMxP.mjs +373 -0
  501. package/dist/media-BUQePMxP.mjs.map +1 -0
  502. package/dist/media-DH8ibNlY.mjs +294 -0
  503. package/dist/media-DH8ibNlY.mjs.map +1 -0
  504. package/dist/media-OEIQ3bVc.mjs +408 -0
  505. package/dist/media-OEIQ3bVc.mjs.map +1 -0
  506. package/dist/media-allowlist-pYtaBA95.mjs +44 -0
  507. package/dist/media-allowlist-pYtaBA95.mjs.map +1 -0
  508. package/dist/media-folders-Bf8_s4de.mjs +210 -0
  509. package/dist/media-folders-Bf8_s4de.mjs.map +1 -0
  510. package/dist/media-url-C6klEuNd.mjs +43 -0
  511. package/dist/media-url-C6klEuNd.mjs.map +1 -0
  512. package/dist/media-usage-D7Y64m6v.mjs +1629 -0
  513. package/dist/media-usage-D7Y64m6v.mjs.map +1 -0
  514. package/dist/media-usage-activation-DrqbmgLA.mjs +78 -0
  515. package/dist/media-usage-activation-DrqbmgLA.mjs.map +1 -0
  516. package/dist/media-usage-work-DommYhYA.mjs +152 -0
  517. package/dist/media-usage-work-DommYhYA.mjs.map +1 -0
  518. package/dist/media-usage-work-HU63hNDu.mjs +586 -0
  519. package/dist/media-usage-work-HU63hNDu.mjs.map +1 -0
  520. package/dist/menus-BQfusWEC.mjs +3608 -0
  521. package/dist/menus-BQfusWEC.mjs.map +1 -0
  522. package/dist/menus-BtwjQt5s.mjs +753 -0
  523. package/dist/menus-BtwjQt5s.mjs.map +1 -0
  524. package/dist/menus-p_M1V7J_.mjs +139 -0
  525. package/dist/menus-p_M1V7J_.mjs.map +1 -0
  526. package/dist/migrations/index.d.mts +1 -1
  527. package/dist/migrations/index.mjs +3 -3
  528. package/dist/mime-C94qBG-P.mjs +36 -0
  529. package/dist/mime-C94qBG-P.mjs.map +1 -0
  530. package/dist/mode-DpYW3w6U.mjs +23 -0
  531. package/dist/mode-DpYW3w6U.mjs.map +1 -0
  532. package/dist/node-sqlite-compat-pWFw0lcc.mjs +46 -0
  533. package/dist/node-sqlite-compat-pWFw0lcc.mjs.map +1 -0
  534. package/dist/normalize-DduyxBjf.mjs +191 -0
  535. package/dist/normalize-DduyxBjf.mjs.map +1 -0
  536. package/dist/oauth-authorization-DAXsH1H9.mjs +274 -0
  537. package/dist/oauth-authorization-DAXsH1H9.mjs.map +1 -0
  538. package/dist/oauth-clients-DENiDQri.mjs +266 -0
  539. package/dist/oauth-clients-DENiDQri.mjs.map +1 -0
  540. package/dist/oauth-state-store-y8mEYVq9.mjs +50 -0
  541. package/dist/oauth-state-store-y8mEYVq9.mjs.map +1 -0
  542. package/dist/oauth-user-lookup-CtTYAy-O.mjs +26 -0
  543. package/dist/oauth-user-lookup-CtTYAy-O.mjs.map +1 -0
  544. package/dist/object-cache/memory.d.mts +1 -1
  545. package/dist/options-BYa1FgIM.d.mts +81 -0
  546. package/dist/options-BYa1FgIM.d.mts.map +1 -0
  547. package/dist/page/index.d.mts +2 -2
  548. package/dist/page/index.mjs +5 -5
  549. package/dist/parse-CORGGhHf.mjs +81 -0
  550. package/dist/parse-CORGGhHf.mjs.map +1 -0
  551. package/dist/parse-avNM1xWV.d.mts +168 -0
  552. package/dist/parse-avNM1xWV.d.mts.map +1 -0
  553. package/dist/passkey-config-Dih5YeIS.mjs +46 -0
  554. package/dist/passkey-config-Dih5YeIS.mjs.map +1 -0
  555. package/dist/paths-d51RFm8M.mjs +77 -0
  556. package/dist/paths-d51RFm8M.mjs.map +1 -0
  557. package/dist/patterns-CoqlXUvk.mjs +145 -0
  558. package/dist/patterns-CoqlXUvk.mjs.map +1 -0
  559. package/dist/placeholder-D2aksPMF.d.mts +306 -0
  560. package/dist/placeholder-D2aksPMF.d.mts.map +1 -0
  561. package/dist/plan-DqeZKuaR.mjs +135 -0
  562. package/dist/plan-DqeZKuaR.mjs.map +1 -0
  563. package/dist/plugin-test-runtime.d.mts +14 -14
  564. package/dist/plugin-test-runtime.mjs +110 -107
  565. package/dist/plugin-types.d.mts +2 -2
  566. package/dist/plugin-utils.d.mts +12 -12
  567. package/dist/plugins/adapt-sandbox-entry.d.mts +12 -12
  568. package/dist/plugins/adapt-sandbox-entry.mjs +3 -3
  569. package/dist/plugins/host.d.mts +5 -5
  570. package/dist/plugins/host.mjs +42 -41
  571. package/dist/plugins-Bb7oqjQA.mjs +277 -0
  572. package/dist/plugins-Bb7oqjQA.mjs.map +1 -0
  573. package/dist/policy-BcEqut3n.mjs +45 -0
  574. package/dist/policy-BcEqut3n.mjs.map +1 -0
  575. package/dist/portable-text-DXE8ymtD.mjs +307 -0
  576. package/dist/portable-text-DXE8ymtD.mjs.map +1 -0
  577. package/dist/preview-DEDWbwA_.mjs +107 -0
  578. package/dist/preview-DEDWbwA_.mjs.map +1 -0
  579. package/dist/protocol-BJbTzvwl.d.mts +61 -0
  580. package/dist/protocol-BJbTzvwl.d.mts.map +1 -0
  581. package/dist/public-submission-D9c9S14m.mjs +250 -0
  582. package/dist/public-submission-D9c9S14m.mjs.map +1 -0
  583. package/dist/public-url-CIRe-2T6.mjs +101 -0
  584. package/dist/public-url-CIRe-2T6.mjs.map +1 -0
  585. package/dist/query-BzifXlPS.mjs +1156 -0
  586. package/dist/query-BzifXlPS.mjs.map +1 -0
  587. package/dist/query-OzMJ6vJP.mjs +41 -0
  588. package/dist/query-OzMJ6vJP.mjs.map +1 -0
  589. package/dist/rate-limit-Csp60Vik.mjs +120 -0
  590. package/dist/rate-limit-Csp60Vik.mjs.map +1 -0
  591. package/dist/receipt-B-aU4hpJ.mjs +43 -0
  592. package/dist/receipt-B-aU4hpJ.mjs.map +1 -0
  593. package/dist/redirect-CDSw1sU3.mjs +17 -0
  594. package/dist/redirect-CDSw1sU3.mjs.map +1 -0
  595. package/dist/redirect-D1ArbO85.mjs +411 -0
  596. package/dist/redirect-D1ArbO85.mjs.map +1 -0
  597. package/dist/redirects-BjTwDTsV.mjs +148 -0
  598. package/dist/redirects-BjTwDTsV.mjs.map +1 -0
  599. package/dist/redirects-Ck50kH3n.mjs +446 -0
  600. package/dist/redirects-Ck50kH3n.mjs.map +1 -0
  601. package/dist/registry/testing.mjs +3 -3
  602. package/dist/registry-CFcNCayZ.mjs +6754 -0
  603. package/dist/registry-CFcNCayZ.mjs.map +1 -0
  604. package/dist/relations-Cfaa1fDl.mjs +776 -0
  605. package/dist/relations-Cfaa1fDl.mjs.map +1 -0
  606. package/dist/request-cache-iHRlHx1d.mjs +104 -0
  607. package/dist/request-cache-iHRlHx1d.mjs.map +1 -0
  608. package/dist/request-context.d.mts +1 -1
  609. package/dist/request-meta-D47mqyev.mjs +141 -0
  610. package/dist/request-meta-D47mqyev.mjs.map +1 -0
  611. package/dist/resolve-BPE8sMvx.mjs +99 -0
  612. package/dist/resolve-BPE8sMvx.mjs.map +1 -0
  613. package/dist/resolve-C0s1E_fH.mjs +199 -0
  614. package/dist/resolve-C0s1E_fH.mjs.map +1 -0
  615. package/dist/revision-j1p4-bOj.mjs +302 -0
  616. package/dist/revision-j1p4-bOj.mjs.map +1 -0
  617. package/dist/route-wire-C9PJV9aL.mjs +197 -0
  618. package/dist/route-wire-C9PJV9aL.mjs.map +1 -0
  619. package/dist/routes-lyYw0mMf.mjs +272 -0
  620. package/dist/routes-lyYw0mMf.mjs.map +1 -0
  621. package/dist/runner-B3eyB9Gb.mjs +6121 -0
  622. package/dist/runner-B3eyB9Gb.mjs.map +1 -0
  623. package/dist/runner-DoYH2Jcu.d.mts +68 -0
  624. package/dist/runner-DoYH2Jcu.d.mts.map +1 -0
  625. package/dist/runtime.d.mts +13 -13
  626. package/dist/runtime.mjs +3 -3
  627. package/dist/schema-BAayK46S.mjs +13 -0
  628. package/dist/schema-BAayK46S.mjs.map +1 -0
  629. package/dist/schema-Gqcl-8G4.mjs +815 -0
  630. package/dist/schema-Gqcl-8G4.mjs.map +1 -0
  631. package/dist/scopes-BqPOKoKf.mjs +34 -0
  632. package/dist/scopes-BqPOKoKf.mjs.map +1 -0
  633. package/dist/search-YJKPIEV6.mjs +448 -0
  634. package/dist/search-YJKPIEV6.mjs.map +1 -0
  635. package/dist/sections-BR_e-wK5.mjs +346 -0
  636. package/dist/sections-BR_e-wK5.mjs.map +1 -0
  637. package/dist/seed/index.d.mts +2 -2
  638. package/dist/seed/index.mjs +37 -31
  639. package/dist/seo/index.d.mts +3 -3
  640. package/dist/seo/index.mjs +22 -21
  641. package/dist/seo/index.mjs.map +1 -1
  642. package/dist/seo-Dsj8hy3j.mjs +114 -0
  643. package/dist/seo-Dsj8hy3j.mjs.map +1 -0
  644. package/dist/seo-XvH4LNNp.mjs +133 -0
  645. package/dist/seo-XvH4LNNp.mjs.map +1 -0
  646. package/dist/service-BsVG05gS.mjs +150 -0
  647. package/dist/service-BsVG05gS.mjs.map +1 -0
  648. package/dist/session-user-DgKbYrlj.mjs +51 -0
  649. package/dist/session-user-DgKbYrlj.mjs.map +1 -0
  650. package/dist/settings-CNPUntkh.mjs +51 -0
  651. package/dist/settings-CNPUntkh.mjs.map +1 -0
  652. package/dist/settings-D5EHi0Tk.mjs +439 -0
  653. package/dist/settings-D5EHi0Tk.mjs.map +1 -0
  654. package/dist/settings-DSfE7wOa.mjs +61 -0
  655. package/dist/settings-DSfE7wOa.mjs.map +1 -0
  656. package/dist/setup-complete-B8W8sJ9v.mjs +26 -0
  657. package/dist/setup-complete-B8W8sJ9v.mjs.map +1 -0
  658. package/dist/setup-nonce-DnSBP260.mjs +25 -0
  659. package/dist/setup-nonce-DnSBP260.mjs.map +1 -0
  660. package/dist/site-settings-NGzdrt7O.mjs +50 -0
  661. package/dist/site-settings-NGzdrt7O.mjs.map +1 -0
  662. package/dist/site-url-D6JB7tLW.mjs +16 -0
  663. package/dist/site-url-D6JB7tLW.mjs.map +1 -0
  664. package/dist/snapshot-CdcwwWAf.mjs +414 -0
  665. package/dist/snapshot-CdcwwWAf.mjs.map +1 -0
  666. package/dist/ssrf-Dv0_tRpo.mjs +406 -0
  667. package/dist/ssrf-Dv0_tRpo.mjs.map +1 -0
  668. package/dist/stage-CUjhED3P.mjs +662 -0
  669. package/dist/stage-CUjhED3P.mjs.map +1 -0
  670. package/dist/staged-C36IWXff.mjs +659 -0
  671. package/dist/staged-C36IWXff.mjs.map +1 -0
  672. package/dist/state-CKouMCSY.mjs +153 -0
  673. package/dist/state-CKouMCSY.mjs.map +1 -0
  674. package/dist/status-lzyj4Uu7.mjs +30 -0
  675. package/dist/status-lzyj4Uu7.mjs.map +1 -0
  676. package/dist/storage/local.d.mts +1 -1
  677. package/dist/storage/local.mjs +1 -1
  678. package/dist/storage/s3.d.mts +1 -1
  679. package/dist/storage/s3.mjs +1 -1
  680. package/dist/storage-query-B-cWcTjJ.d.mts +1594 -0
  681. package/dist/storage-query-B-cWcTjJ.d.mts.map +1 -0
  682. package/dist/tar-DsTXX6ch.mjs +449 -0
  683. package/dist/tar-DsTXX6ch.mjs.map +1 -0
  684. package/dist/target-DLQCwp_Z.mjs +27 -0
  685. package/dist/target-DLQCwp_Z.mjs.map +1 -0
  686. package/dist/taxonomies-BlAjr4BL.mjs +697 -0
  687. package/dist/taxonomies-BlAjr4BL.mjs.map +1 -0
  688. package/dist/taxonomies-Byyo7LOZ.mjs +939 -0
  689. package/dist/taxonomies-Byyo7LOZ.mjs.map +1 -0
  690. package/dist/taxonomy-CKDwM61Y.mjs +525 -0
  691. package/dist/taxonomy-CKDwM61Y.mjs.map +1 -0
  692. package/dist/tokens-BojXlk49.mjs +171 -0
  693. package/dist/tokens-BojXlk49.mjs.map +1 -0
  694. package/dist/transaction-DLPQWik1.mjs +29 -0
  695. package/dist/transaction-DLPQWik1.mjs.map +1 -0
  696. package/dist/transfer-XSTh2BCr.mjs +8706 -0
  697. package/dist/transfer-XSTh2BCr.mjs.map +1 -0
  698. package/dist/transfer-download-DkoCDA9d.mjs +33 -0
  699. package/dist/transfer-download-DkoCDA9d.mjs.map +1 -0
  700. package/dist/transfer-iQ26J-RT.mjs +166 -0
  701. package/dist/transfer-iQ26J-RT.mjs.map +1 -0
  702. package/dist/transformations-C7RQabKQ.mjs +196 -0
  703. package/dist/transformations-C7RQabKQ.mjs.map +1 -0
  704. package/dist/transport-D3RulfD6.mjs +136 -0
  705. package/dist/transport-D3RulfD6.mjs.map +1 -0
  706. package/dist/transport-DhlZlf4D.d.mts +42 -0
  707. package/dist/transport-DhlZlf4D.d.mts.map +1 -0
  708. package/dist/trusted-proxy-B6ECOZJc.mjs +51 -0
  709. package/dist/trusted-proxy-B6ECOZJc.mjs.map +1 -0
  710. package/dist/turnstile-lqUiY7lP.mjs +53 -0
  711. package/dist/turnstile-lqUiY7lP.mjs.map +1 -0
  712. package/dist/types-4Dn9bZhu.mjs +77 -0
  713. package/dist/types-4Dn9bZhu.mjs.map +1 -0
  714. package/dist/types-5LSo7PPx.d.mts +85 -0
  715. package/dist/types-5LSo7PPx.d.mts.map +1 -0
  716. package/dist/types-BQ3hwYJT.d.mts +896 -0
  717. package/dist/types-BQ3hwYJT.d.mts.map +1 -0
  718. package/dist/types-BYEk7qo3.d.mts +198 -0
  719. package/dist/types-BYEk7qo3.d.mts.map +1 -0
  720. package/dist/types-CJKsWVFR.mjs +199 -0
  721. package/dist/types-CJKsWVFR.mjs.map +1 -0
  722. package/dist/types-Ca_w8mmY.d.mts +363 -0
  723. package/dist/types-Ca_w8mmY.d.mts.map +1 -0
  724. package/dist/types-CkE41ZAG.mjs +18 -0
  725. package/dist/types-CkE41ZAG.mjs.map +1 -0
  726. package/dist/types-D0aJW2uR.d.mts +1641 -0
  727. package/dist/types-D0aJW2uR.d.mts.map +1 -0
  728. package/dist/types-DbpN4Qto.d.mts +372 -0
  729. package/dist/types-DbpN4Qto.d.mts.map +1 -0
  730. package/dist/types-ILDI1sdY.mjs +16 -0
  731. package/dist/types-ILDI1sdY.mjs.map +1 -0
  732. package/dist/types-OC5c-edM.mjs +22 -0
  733. package/dist/types-OC5c-edM.mjs.map +1 -0
  734. package/dist/types-aOOxRSx6.mjs +103 -0
  735. package/dist/types-aOOxRSx6.mjs.map +1 -0
  736. package/dist/types-m1WbUffD.d.mts +198 -0
  737. package/dist/types-m1WbUffD.d.mts.map +1 -0
  738. package/dist/types-uxLoPBio.d.mts +124 -0
  739. package/dist/types-uxLoPBio.d.mts.map +1 -0
  740. package/dist/types-we5uR-tV.d.mts +287 -0
  741. package/dist/types-we5uR-tV.d.mts.map +1 -0
  742. package/dist/upload-attempts-DduMy6B0.mjs +32 -0
  743. package/dist/upload-attempts-DduMy6B0.mjs.map +1 -0
  744. package/dist/url-pattern-B3EwxAAk.mjs +33 -0
  745. package/dist/url-pattern-B3EwxAAk.mjs.map +1 -0
  746. package/dist/user-ElwQjTQT.mjs +171 -0
  747. package/dist/user-ElwQjTQT.mjs.map +1 -0
  748. package/dist/utils-BlAXmfOG.mjs +439 -0
  749. package/dist/utils-BlAXmfOG.mjs.map +1 -0
  750. package/dist/validate-CH0X5b2c.d.mts +468 -0
  751. package/dist/validate-CH0X5b2c.d.mts.map +1 -0
  752. package/dist/validate-CfgRpcjA.mjs +492 -0
  753. package/dist/validate-CfgRpcjA.mjs.map +1 -0
  754. package/dist/validation-DvYJtv4k.mjs +218 -0
  755. package/dist/validation-DvYJtv4k.mjs.map +1 -0
  756. package/dist/version-DgYjhTud.mjs +9 -0
  757. package/dist/version-DgYjhTud.mjs.map +1 -0
  758. package/dist/version-Dq71scUb.mjs +7 -0
  759. package/dist/version-Dq71scUb.mjs.map +1 -0
  760. package/dist/widgets-ChFIj0be.mjs +126 -0
  761. package/dist/widgets-ChFIj0be.mjs.map +1 -0
  762. package/dist/wxr-taxonomies-CBZMp2YX.mjs +372 -0
  763. package/dist/wxr-taxonomies-CBZMp2YX.mjs.map +1 -0
  764. package/dist/wxr-taxonomies-DlKDpWN1.d.mts +34 -0
  765. package/dist/wxr-taxonomies-DlKDpWN1.d.mts.map +1 -0
  766. package/dist/zod-generator-DmTKI-Ig.mjs +426 -0
  767. package/dist/zod-generator-DmTKI-Ig.mjs.map +1 -0
  768. package/package.json +7 -6
  769. package/src/api/handlers/content.ts +593 -16
  770. package/src/api/handlers/device-flow.ts +74 -21
  771. package/src/api/handlers/manifest.ts +79 -5
  772. package/src/api/handlers/relations.ts +638 -157
  773. package/src/api/handlers/revision.ts +30 -0
  774. package/src/api/handlers/schema.ts +403 -1
  775. package/src/api/handlers/staged-references.ts +142 -0
  776. package/src/api/handlers/validate-references.ts +146 -0
  777. package/src/api/schemas/content.ts +13 -0
  778. package/src/api/schemas/relations.ts +54 -44
  779. package/src/api/schemas/schema.ts +14 -0
  780. package/src/astro/integration/routes.ts +15 -19
  781. package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/children.ts +11 -54
  782. package/src/astro/routes/api/content/[collection]/[id].ts +3 -1
  783. package/src/astro/routes/api/oauth/device/authorize.ts +33 -4
  784. package/src/astro/routes/api/relations/index.ts +4 -4
  785. package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +6 -2
  786. package/src/astro/types.ts +5 -0
  787. package/src/cli/commands/export-seed.ts +510 -89
  788. package/src/components/WidgetArea.astro +3 -2
  789. package/src/database/migrations/086_relations_structural.ts +197 -0
  790. package/src/database/migrations/087_reference_field_relations.ts +407 -0
  791. package/src/database/migrations/runner.ts +4 -0
  792. package/src/database/reference-backfill.ts +141 -0
  793. package/src/database/repositories/content.ts +43 -8
  794. package/src/database/repositories/relation.ts +620 -208
  795. package/src/database/repositories/revision.ts +16 -0
  796. package/src/database/repositories/types.ts +38 -0
  797. package/src/database/transaction.ts +12 -1
  798. package/src/database/types.ts +14 -5
  799. package/src/emdash-runtime.ts +86 -11
  800. package/src/index.ts +10 -0
  801. package/src/loader.ts +169 -22
  802. package/src/query.ts +455 -25
  803. package/src/references/field-map.ts +115 -0
  804. package/src/references/resolve.ts +160 -0
  805. package/src/references/staged.ts +117 -0
  806. package/src/references/types.ts +16 -0
  807. package/src/registry/artifact-fetch.ts +45 -271
  808. package/src/schema/registry.ts +99 -24
  809. package/src/schema/types.ts +58 -0
  810. package/src/schema/zod-generator.ts +67 -1
  811. package/src/seed/apply.ts +519 -62
  812. package/src/seed/types.ts +36 -2
  813. package/src/seed/validate.ts +78 -2
  814. package/src/transfer/analyze/unique-keys.ts +3 -12
  815. package/src/transfer/analyze/validate.ts +65 -39
  816. package/src/transfer/analyze/values.ts +12 -1
  817. package/src/transfer/export/readers.ts +12 -8
  818. package/src/transfer/format/columns.ts +26 -6
  819. package/src/transfer/format/kinds.ts +21 -5
  820. package/src/transfer/import/context.ts +8 -1
  821. package/src/transfer/ops/package-index.ts +1 -1
  822. package/dist/action-token-DYwe4Pk0.mjs +0 -26
  823. package/dist/action-token-DYwe4Pk0.mjs.map +0 -1
  824. package/dist/activation-LOkDM5WT.mjs +0 -382
  825. package/dist/activation-LOkDM5WT.mjs.map +0 -1
  826. package/dist/adapters-B64LbYcB.d.mts +0 -171
  827. package/dist/adapters-B64LbYcB.d.mts.map +0 -1
  828. package/dist/allowed-origins-CHB8oZNM.mjs +0 -116
  829. package/dist/allowed-origins-CHB8oZNM.mjs.map +0 -1
  830. package/dist/api-CuyNEHZG.mjs +0 -4718
  831. package/dist/api-CuyNEHZG.mjs.map +0 -1
  832. package/dist/api-tokens-s4i4aUp_.mjs +0 -166
  833. package/dist/api-tokens-s4i4aUp_.mjs.map +0 -1
  834. package/dist/apply-npY1TAhG.mjs +0 -1366
  835. package/dist/apply-npY1TAhG.mjs.map +0 -1
  836. package/dist/approvals-CqMfNxak.mjs +0 -460
  837. package/dist/approvals-CqMfNxak.mjs.map +0 -1
  838. package/dist/artifact-fetch-DZMOGZ3-.mjs +0 -818
  839. package/dist/artifact-fetch-DZMOGZ3-.mjs.map +0 -1
  840. package/dist/astro/routes/api/relations/_id_/translations.d.mts +0 -8
  841. package/dist/astro/routes/api/relations/_id_/translations.d.mts.map +0 -1
  842. package/dist/astro/routes/api/relations/_id_/translations.mjs +0 -47
  843. package/dist/astro/routes/api/relations/_id_/translations.mjs.map +0 -1
  844. package/dist/audit-RfCugiSB.mjs +0 -127
  845. package/dist/audit-RfCugiSB.mjs.map +0 -1
  846. package/dist/authoritative-records-CoJvBXAD.mjs +0 -5172
  847. package/dist/authoritative-records-CoJvBXAD.mjs.map +0 -1
  848. package/dist/authorize-seCifOMJ.mjs +0 -49
  849. package/dist/authorize-seCifOMJ.mjs.map +0 -1
  850. package/dist/backup-BQRj3afm.mjs +0 -246
  851. package/dist/backup-BQRj3afm.mjs.map +0 -1
  852. package/dist/block-type-registry-DUI_3KxT.mjs +0 -6709
  853. package/dist/block-type-registry-DUI_3KxT.mjs.map +0 -1
  854. package/dist/block-types-BmZmLmAD.mjs +0 -132
  855. package/dist/block-types-BmZmLmAD.mjs.map +0 -1
  856. package/dist/block-values-C_VIPr5t.mjs +0 -175
  857. package/dist/block-values-C_VIPr5t.mjs.map +0 -1
  858. package/dist/byline-DYmkXqvo.mjs +0 -909
  859. package/dist/byline-DYmkXqvo.mjs.map +0 -1
  860. package/dist/byline-fields-D28AT-Fh.mjs +0 -123
  861. package/dist/byline-fields-D28AT-Fh.mjs.map +0 -1
  862. package/dist/byline-registry-gnKscbQX.mjs +0 -406
  863. package/dist/byline-registry-gnKscbQX.mjs.map +0 -1
  864. package/dist/bylines-BPwJqoYH.mjs +0 -232
  865. package/dist/bylines-BPwJqoYH.mjs.map +0 -1
  866. package/dist/bylines-ukLaYpVZ.mjs +0 -214
  867. package/dist/bylines-ukLaYpVZ.mjs.map +0 -1
  868. package/dist/cache-m7UEkRFV.mjs +0 -108
  869. package/dist/cache-m7UEkRFV.mjs.map +0 -1
  870. package/dist/canonical-YhEQezjg.mjs +0 -174
  871. package/dist/canonical-YhEQezjg.mjs.map +0 -1
  872. package/dist/capture-triggers-kJyl_yyM.mjs +0 -362
  873. package/dist/capture-triggers-kJyl_yyM.mjs.map +0 -1
  874. package/dist/challenge-store-ppU6Uv13.mjs +0 -51
  875. package/dist/challenge-store-ppU6Uv13.mjs.map +0 -1
  876. package/dist/checksum-B2IINIlN.mjs +0 -162
  877. package/dist/checksum-B2IINIlN.mjs.map +0 -1
  878. package/dist/chrome-tags-DApCQSIk.mjs +0 -24
  879. package/dist/chrome-tags-DApCQSIk.mjs.map +0 -1
  880. package/dist/chunks-Dms7Uxbt.mjs +0 -25
  881. package/dist/chunks-Dms7Uxbt.mjs.map +0 -1
  882. package/dist/collection-deletion-BIm28mo3.mjs +0 -436
  883. package/dist/collection-deletion-BIm28mo3.mjs.map +0 -1
  884. package/dist/collection-deletion-processor-Br6rxs3u.mjs +0 -217
  885. package/dist/collection-deletion-processor-Br6rxs3u.mjs.map +0 -1
  886. package/dist/collection-slugs-cache-CjGk__zp.mjs +0 -85
  887. package/dist/collection-slugs-cache-CjGk__zp.mjs.map +0 -1
  888. package/dist/comment-CrBl22OF.mjs +0 -313
  889. package/dist/comment-CrBl22OF.mjs.map +0 -1
  890. package/dist/comment-reaction-JEQ2Fpd8.mjs +0 -85
  891. package/dist/comment-reaction-JEQ2Fpd8.mjs.map +0 -1
  892. package/dist/comments-2ah9du9y.mjs +0 -195
  893. package/dist/comments-2ah9du9y.mjs.map +0 -1
  894. package/dist/comments-fHZ8ON9O.mjs +0 -99
  895. package/dist/comments-fHZ8ON9O.mjs.map +0 -1
  896. package/dist/components-CXbq7CSM.mjs +0 -108
  897. package/dist/components-CXbq7CSM.mjs.map +0 -1
  898. package/dist/config-BjEm_3xL.d.mts +0 -6537
  899. package/dist/config-BjEm_3xL.d.mts.map +0 -1
  900. package/dist/config-IhybvkIQ.mjs +0 -242
  901. package/dist/config-IhybvkIQ.mjs.map +0 -1
  902. package/dist/config-Py43JK9r.d.mts +0 -39
  903. package/dist/config-Py43JK9r.d.mts.map +0 -1
  904. package/dist/content-DFaIEDj9.mjs +0 -2281
  905. package/dist/content-DFaIEDj9.mjs.map +0 -1
  906. package/dist/content-list-query-Dra4Dalc.d.mts +0 -26
  907. package/dist/content-list-query-Dra4Dalc.d.mts.map +0 -1
  908. package/dist/content-policy-DFNw91-d.mjs +0 -46
  909. package/dist/content-policy-DFNw91-d.mjs.map +0 -1
  910. package/dist/content-repair-Q8IUrpLL.mjs +0 -442
  911. package/dist/content-repair-Q8IUrpLL.mjs.map +0 -1
  912. package/dist/context-BV_7t-Ua.mjs +0 -1921
  913. package/dist/context-BV_7t-Ua.mjs.map +0 -1
  914. package/dist/cron-7DCJwPXq.mjs +0 -284
  915. package/dist/cron-7DCJwPXq.mjs.map +0 -1
  916. package/dist/dashboard-BP-iJqpd.mjs +0 -151
  917. package/dist/dashboard-BP-iJqpd.mjs.map +0 -1
  918. package/dist/default-DQ6vsviu.mjs +0 -81
  919. package/dist/default-DQ6vsviu.mjs.map +0 -1
  920. package/dist/deferred-tasks-BPxXUB4x.d.mts +0 -9
  921. package/dist/deferred-tasks-BPxXUB4x.d.mts.map +0 -1
  922. package/dist/dev-typegen-CZaPLl3V.mjs +0 -29
  923. package/dist/dev-typegen-CZaPLl3V.mjs.map +0 -1
  924. package/dist/device-flow-CRd6DXmW.mjs +0 -466
  925. package/dist/device-flow-CRd6DXmW.mjs.map +0 -1
  926. package/dist/digest-BarSh-pN.mjs +0 -194
  927. package/dist/digest-BarSh-pN.mjs.map +0 -1
  928. package/dist/direct-executor-D2lNadwo.mjs +0 -104
  929. package/dist/direct-executor-D2lNadwo.mjs.map +0 -1
  930. package/dist/dist-BNwANFJR.mjs +0 -810
  931. package/dist/dist-BNwANFJR.mjs.map +0 -1
  932. package/dist/email-console-bJn3ctqA.mjs +0 -50
  933. package/dist/email-console-bJn3ctqA.mjs.map +0 -1
  934. package/dist/email-locale-CN6WAMx0.mjs +0 -25
  935. package/dist/email-locale-CN6WAMx0.mjs.map +0 -1
  936. package/dist/emdash-runtime-CtfnZmPi.mjs +0 -4186
  937. package/dist/emdash-runtime-CtfnZmPi.mjs.map +0 -1
  938. package/dist/enrich-Dl3kZ-lP.mjs +0 -194
  939. package/dist/enrich-Dl3kZ-lP.mjs.map +0 -1
  940. package/dist/entry-lock-BJYdBfXb.mjs +0 -1097
  941. package/dist/entry-lock-BJYdBfXb.mjs.map +0 -1
  942. package/dist/entry-lock-Cf5OoIgN.d.mts +0 -4368
  943. package/dist/entry-lock-Cf5OoIgN.d.mts.map +0 -1
  944. package/dist/entry-lock-DHQOxN7R.mjs +0 -163
  945. package/dist/entry-lock-DHQOxN7R.mjs.map +0 -1
  946. package/dist/entry-locks-D0foLdjQ.mjs +0 -167
  947. package/dist/entry-locks-D0foLdjQ.mjs.map +0 -1
  948. package/dist/error-CfvOHP0M.mjs +0 -90
  949. package/dist/error-CfvOHP0M.mjs.map +0 -1
  950. package/dist/errors-BF0_LFhW.mjs +0 -460
  951. package/dist/errors-BF0_LFhW.mjs.map +0 -1
  952. package/dist/errors-DgE1zJGG.mjs +0 -120
  953. package/dist/errors-DgE1zJGG.mjs.map +0 -1
  954. package/dist/escape-CuaZhZvL.mjs +0 -9
  955. package/dist/escape-CuaZhZvL.mjs.map +0 -1
  956. package/dist/fence-CMDXJYc_.mjs +0 -162
  957. package/dist/fence-CMDXJYc_.mjs.map +0 -1
  958. package/dist/field-defs-cache-HIgBbqZZ.mjs +0 -77
  959. package/dist/field-defs-cache-HIgBbqZZ.mjs.map +0 -1
  960. package/dist/focal-point-Gr34o-4o.mjs +0 -23
  961. package/dist/focal-point-Gr34o-4o.mjs.map +0 -1
  962. package/dist/fts-manager-S-K0laoS.mjs +0 -443
  963. package/dist/fts-manager-S-K0laoS.mjs.map +0 -1
  964. package/dist/gc-DjKY0Ay1.mjs +0 -75
  965. package/dist/gc-DjKY0Ay1.mjs.map +0 -1
  966. package/dist/hash-SDAW6zC-.mjs +0 -37
  967. package/dist/hash-SDAW6zC-.mjs.map +0 -1
  968. package/dist/hook-result-B5bXDgS2.d.mts +0 -31
  969. package/dist/hook-result-B5bXDgS2.d.mts.map +0 -1
  970. package/dist/hreflang-CbVI4paR.mjs +0 -105
  971. package/dist/hreflang-CbVI4paR.mjs.map +0 -1
  972. package/dist/hreflang-D5uNnsGJ.d.mts +0 -50
  973. package/dist/hreflang-D5uNnsGJ.d.mts.map +0 -1
  974. package/dist/http-route-dispatch-BitqzwMy.mjs +0 -339
  975. package/dist/http-route-dispatch-BitqzwMy.mjs.map +0 -1
  976. package/dist/identity-Be5kzutJ.mjs +0 -35
  977. package/dist/identity-Be5kzutJ.mjs.map +0 -1
  978. package/dist/import-YzfKCaco.mjs +0 -2020
  979. package/dist/import-YzfKCaco.mjs.map +0 -1
  980. package/dist/index-D-hdtLe8.d.mts +0 -623
  981. package/dist/index-D-hdtLe8.d.mts.map +0 -1
  982. package/dist/install-finalization-DfM1fj5x.mjs +0 -58
  983. package/dist/install-finalization-DfM1fj5x.mjs.map +0 -1
  984. package/dist/keys-yxLm5l35.mjs +0 -61
  985. package/dist/keys-yxLm5l35.mjs.map +0 -1
  986. package/dist/kinds-CRu_T5T5.mjs +0 -961
  987. package/dist/kinds-CRu_T5T5.mjs.map +0 -1
  988. package/dist/lifecycle-BzeGPeQ-.mjs +0 -25
  989. package/dist/lifecycle-BzeGPeQ-.mjs.map +0 -1
  990. package/dist/load-XgJiE6_3.mjs +0 -28
  991. package/dist/load-XgJiE6_3.mjs.map +0 -1
  992. package/dist/loader-BzqeR1ZN.mjs +0 -1086
  993. package/dist/loader-BzqeR1ZN.mjs.map +0 -1
  994. package/dist/loops-BQSzv5Zn.mjs +0 -203
  995. package/dist/loops-BQSzv5Zn.mjs.map +0 -1
  996. package/dist/manifest-builder-BmSAOOEF.mjs +0 -189
  997. package/dist/manifest-builder-BmSAOOEF.mjs.map +0 -1
  998. package/dist/manifest-schema-CY3zng_M.mjs +0 -492
  999. package/dist/manifest-schema-CY3zng_M.mjs.map +0 -1
  1000. package/dist/media-CPXTbb1R.mjs +0 -373
  1001. package/dist/media-CPXTbb1R.mjs.map +0 -1
  1002. package/dist/media-JXRWDhw3.mjs +0 -294
  1003. package/dist/media-JXRWDhw3.mjs.map +0 -1
  1004. package/dist/media-Pu1L6xir.mjs +0 -408
  1005. package/dist/media-Pu1L6xir.mjs.map +0 -1
  1006. package/dist/media-allowlist-BSoa9Vvm.mjs +0 -44
  1007. package/dist/media-allowlist-BSoa9Vvm.mjs.map +0 -1
  1008. package/dist/media-folders-BE0oo2eX.mjs +0 -210
  1009. package/dist/media-folders-BE0oo2eX.mjs.map +0 -1
  1010. package/dist/media-url-jArBpzIG.mjs +0 -43
  1011. package/dist/media-url-jArBpzIG.mjs.map +0 -1
  1012. package/dist/media-usage-De-zeR9E.mjs +0 -1629
  1013. package/dist/media-usage-De-zeR9E.mjs.map +0 -1
  1014. package/dist/media-usage-activation-HKp7zk7W.mjs +0 -78
  1015. package/dist/media-usage-activation-HKp7zk7W.mjs.map +0 -1
  1016. package/dist/media-usage-work-C2OZLCAd.mjs +0 -586
  1017. package/dist/media-usage-work-C2OZLCAd.mjs.map +0 -1
  1018. package/dist/media-usage-work-DwUNbgvS.mjs +0 -152
  1019. package/dist/media-usage-work-DwUNbgvS.mjs.map +0 -1
  1020. package/dist/menus-BM7BPLOb.mjs +0 -139
  1021. package/dist/menus-BM7BPLOb.mjs.map +0 -1
  1022. package/dist/menus-Cm68rsAq.mjs +0 -3608
  1023. package/dist/menus-Cm68rsAq.mjs.map +0 -1
  1024. package/dist/menus-ITeAbcIF.mjs +0 -753
  1025. package/dist/menus-ITeAbcIF.mjs.map +0 -1
  1026. package/dist/mime-ChLqYwDk.mjs +0 -36
  1027. package/dist/mime-ChLqYwDk.mjs.map +0 -1
  1028. package/dist/mode-CCuKXUci.mjs +0 -23
  1029. package/dist/mode-CCuKXUci.mjs.map +0 -1
  1030. package/dist/node-sqlite-compat-CONMsl-x.mjs +0 -46
  1031. package/dist/node-sqlite-compat-CONMsl-x.mjs.map +0 -1
  1032. package/dist/normalize-CO2P8-iE.mjs +0 -191
  1033. package/dist/normalize-CO2P8-iE.mjs.map +0 -1
  1034. package/dist/oauth-authorization-DlMIL5_h.mjs +0 -274
  1035. package/dist/oauth-authorization-DlMIL5_h.mjs.map +0 -1
  1036. package/dist/oauth-clients-Djq9r_KP.mjs +0 -266
  1037. package/dist/oauth-clients-Djq9r_KP.mjs.map +0 -1
  1038. package/dist/oauth-state-store-BbjnZXNC.mjs +0 -50
  1039. package/dist/oauth-state-store-BbjnZXNC.mjs.map +0 -1
  1040. package/dist/oauth-user-lookup-vue9a64A.mjs +0 -26
  1041. package/dist/oauth-user-lookup-vue9a64A.mjs.map +0 -1
  1042. package/dist/options-SQCHQCPH.d.mts +0 -81
  1043. package/dist/options-SQCHQCPH.d.mts.map +0 -1
  1044. package/dist/parse-CVgO-Qai.d.mts +0 -168
  1045. package/dist/parse-CVgO-Qai.d.mts.map +0 -1
  1046. package/dist/parse-DY6OD1j_.mjs +0 -81
  1047. package/dist/parse-DY6OD1j_.mjs.map +0 -1
  1048. package/dist/passkey-config-X_H8128a.mjs +0 -46
  1049. package/dist/passkey-config-X_H8128a.mjs.map +0 -1
  1050. package/dist/paths-JxokKIbr.mjs +0 -77
  1051. package/dist/paths-JxokKIbr.mjs.map +0 -1
  1052. package/dist/patterns-BhAvqO0S.mjs +0 -145
  1053. package/dist/patterns-BhAvqO0S.mjs.map +0 -1
  1054. package/dist/placeholder-MSEd8gty.d.mts +0 -306
  1055. package/dist/placeholder-MSEd8gty.d.mts.map +0 -1
  1056. package/dist/plan-xjcWrAah.mjs +0 -135
  1057. package/dist/plan-xjcWrAah.mjs.map +0 -1
  1058. package/dist/plugins-DUXUt8B9.mjs +0 -277
  1059. package/dist/plugins-DUXUt8B9.mjs.map +0 -1
  1060. package/dist/policy-CUvwAARc.mjs +0 -45
  1061. package/dist/policy-CUvwAARc.mjs.map +0 -1
  1062. package/dist/portable-text-5O_ZGUjB.mjs +0 -307
  1063. package/dist/portable-text-5O_ZGUjB.mjs.map +0 -1
  1064. package/dist/preview-CIUcPYr6.mjs +0 -107
  1065. package/dist/preview-CIUcPYr6.mjs.map +0 -1
  1066. package/dist/protocol-B97DZaFr.d.mts +0 -61
  1067. package/dist/protocol-B97DZaFr.d.mts.map +0 -1
  1068. package/dist/public-submission-BFBUrqst.mjs +0 -250
  1069. package/dist/public-submission-BFBUrqst.mjs.map +0 -1
  1070. package/dist/public-url-Bn7U0D7-.mjs +0 -101
  1071. package/dist/public-url-Bn7U0D7-.mjs.map +0 -1
  1072. package/dist/query-B48peoRT.mjs +0 -890
  1073. package/dist/query-B48peoRT.mjs.map +0 -1
  1074. package/dist/query-C4IH0uhR.mjs +0 -41
  1075. package/dist/query-C4IH0uhR.mjs.map +0 -1
  1076. package/dist/rate-limit-BZ6nybgc.mjs +0 -120
  1077. package/dist/rate-limit-BZ6nybgc.mjs.map +0 -1
  1078. package/dist/receipt-B4wJj5Jq.mjs +0 -43
  1079. package/dist/receipt-B4wJj5Jq.mjs.map +0 -1
  1080. package/dist/redirect-B29UjdUn.mjs +0 -411
  1081. package/dist/redirect-B29UjdUn.mjs.map +0 -1
  1082. package/dist/redirect-Cd1E7VUt.mjs +0 -17
  1083. package/dist/redirect-Cd1E7VUt.mjs.map +0 -1
  1084. package/dist/redirects-Ca2MPfEG.mjs +0 -446
  1085. package/dist/redirects-Ca2MPfEG.mjs.map +0 -1
  1086. package/dist/redirects-Cv9apQKj.mjs +0 -148
  1087. package/dist/redirects-Cv9apQKj.mjs.map +0 -1
  1088. package/dist/relation-M4NUCb0b.mjs +0 -334
  1089. package/dist/relation-M4NUCb0b.mjs.map +0 -1
  1090. package/dist/relations-CCif47Oq.mjs +0 -403
  1091. package/dist/relations-CCif47Oq.mjs.map +0 -1
  1092. package/dist/relations-CK9CYUyr.mjs +0 -310
  1093. package/dist/relations-CK9CYUyr.mjs.map +0 -1
  1094. package/dist/request-cache-DzLYKm_x.mjs +0 -104
  1095. package/dist/request-cache-DzLYKm_x.mjs.map +0 -1
  1096. package/dist/request-meta-sZXt3sRo.mjs +0 -141
  1097. package/dist/request-meta-sZXt3sRo.mjs.map +0 -1
  1098. package/dist/resolve-2WbQsCvT.mjs +0 -199
  1099. package/dist/resolve-2WbQsCvT.mjs.map +0 -1
  1100. package/dist/route-wire--1hLuACz.mjs +0 -197
  1101. package/dist/route-wire--1hLuACz.mjs.map +0 -1
  1102. package/dist/routes-vrR95WR6.mjs +0 -272
  1103. package/dist/routes-vrR95WR6.mjs.map +0 -1
  1104. package/dist/runner-1y4J9fJB.mjs +0 -5742
  1105. package/dist/runner-1y4J9fJB.mjs.map +0 -1
  1106. package/dist/runner-D5_LzKXI.d.mts +0 -68
  1107. package/dist/runner-D5_LzKXI.d.mts.map +0 -1
  1108. package/dist/schema-BABiRdsH.mjs +0 -13
  1109. package/dist/schema-BABiRdsH.mjs.map +0 -1
  1110. package/dist/schema-Du3MzCG0.mjs +0 -446
  1111. package/dist/schema-Du3MzCG0.mjs.map +0 -1
  1112. package/dist/scopes-Dbk-ElhT.mjs +0 -34
  1113. package/dist/scopes-Dbk-ElhT.mjs.map +0 -1
  1114. package/dist/search-Bt1PL1jf.mjs +0 -448
  1115. package/dist/search-Bt1PL1jf.mjs.map +0 -1
  1116. package/dist/sections-Ddptx_o9.mjs +0 -346
  1117. package/dist/sections-Ddptx_o9.mjs.map +0 -1
  1118. package/dist/seo-CZT2oLtT.mjs +0 -114
  1119. package/dist/seo-CZT2oLtT.mjs.map +0 -1
  1120. package/dist/seo-D5w3-Azy.mjs +0 -133
  1121. package/dist/seo-D5w3-Azy.mjs.map +0 -1
  1122. package/dist/service-DuykXPyW.mjs +0 -150
  1123. package/dist/service-DuykXPyW.mjs.map +0 -1
  1124. package/dist/session-user-BhaVp8w0.mjs +0 -51
  1125. package/dist/session-user-BhaVp8w0.mjs.map +0 -1
  1126. package/dist/settings-B4vDl1fK.mjs +0 -439
  1127. package/dist/settings-B4vDl1fK.mjs.map +0 -1
  1128. package/dist/settings-DYidIB26.mjs +0 -61
  1129. package/dist/settings-DYidIB26.mjs.map +0 -1
  1130. package/dist/settings-Dyj6v8C4.mjs +0 -51
  1131. package/dist/settings-Dyj6v8C4.mjs.map +0 -1
  1132. package/dist/setup-complete-bOogcHWG.mjs +0 -26
  1133. package/dist/setup-complete-bOogcHWG.mjs.map +0 -1
  1134. package/dist/setup-nonce-0EGuKM4s.mjs +0 -25
  1135. package/dist/setup-nonce-0EGuKM4s.mjs.map +0 -1
  1136. package/dist/site-settings-DOgRUoFX.mjs +0 -50
  1137. package/dist/site-settings-DOgRUoFX.mjs.map +0 -1
  1138. package/dist/site-url-BU_bbxwj.mjs +0 -16
  1139. package/dist/site-url-BU_bbxwj.mjs.map +0 -1
  1140. package/dist/snapshot-PawoX-WG.mjs +0 -414
  1141. package/dist/snapshot-PawoX-WG.mjs.map +0 -1
  1142. package/dist/ssrf-CJUnJymJ.mjs +0 -406
  1143. package/dist/ssrf-CJUnJymJ.mjs.map +0 -1
  1144. package/dist/stage-DgrBz_du.mjs +0 -662
  1145. package/dist/stage-DgrBz_du.mjs.map +0 -1
  1146. package/dist/state-DDiPySSG.mjs +0 -153
  1147. package/dist/state-DDiPySSG.mjs.map +0 -1
  1148. package/dist/status-DZKIG4a9.mjs +0 -30
  1149. package/dist/status-DZKIG4a9.mjs.map +0 -1
  1150. package/dist/storage-query-FXJH5pI8.d.mts +0 -1581
  1151. package/dist/storage-query-FXJH5pI8.d.mts.map +0 -1
  1152. package/dist/tar-_1AgTYFu.mjs +0 -449
  1153. package/dist/tar-_1AgTYFu.mjs.map +0 -1
  1154. package/dist/target-_7pn2Gbg.mjs +0 -27
  1155. package/dist/target-_7pn2Gbg.mjs.map +0 -1
  1156. package/dist/taxonomies-C1IwNe8Q.mjs +0 -697
  1157. package/dist/taxonomies-C1IwNe8Q.mjs.map +0 -1
  1158. package/dist/taxonomies-C_XMoRcX.mjs +0 -939
  1159. package/dist/taxonomies-C_XMoRcX.mjs.map +0 -1
  1160. package/dist/taxonomy-C3Fu1YeH.mjs +0 -525
  1161. package/dist/taxonomy-C3Fu1YeH.mjs.map +0 -1
  1162. package/dist/tokens-u78jETkX.mjs +0 -171
  1163. package/dist/tokens-u78jETkX.mjs.map +0 -1
  1164. package/dist/transaction-BcJO4Tmc.mjs +0 -29
  1165. package/dist/transaction-BcJO4Tmc.mjs.map +0 -1
  1166. package/dist/transfer-DIGvR9Af.mjs +0 -166
  1167. package/dist/transfer-DIGvR9Af.mjs.map +0 -1
  1168. package/dist/transfer-DgeCvHnj.mjs +0 -8675
  1169. package/dist/transfer-DgeCvHnj.mjs.map +0 -1
  1170. package/dist/transfer-download-Pml7RMio.mjs +0 -33
  1171. package/dist/transfer-download-Pml7RMio.mjs.map +0 -1
  1172. package/dist/transformations-9gfpwY65.mjs +0 -196
  1173. package/dist/transformations-9gfpwY65.mjs.map +0 -1
  1174. package/dist/transport-BIfH7_hx.d.mts +0 -42
  1175. package/dist/transport-BIfH7_hx.d.mts.map +0 -1
  1176. package/dist/transport-DKWIq53q.mjs +0 -136
  1177. package/dist/transport-DKWIq53q.mjs.map +0 -1
  1178. package/dist/trusted-proxy-tKiVtyTD.mjs +0 -51
  1179. package/dist/trusted-proxy-tKiVtyTD.mjs.map +0 -1
  1180. package/dist/turnstile-DpsoyOfg.mjs +0 -53
  1181. package/dist/turnstile-DpsoyOfg.mjs.map +0 -1
  1182. package/dist/types-B4sUC2p1.d.mts +0 -198
  1183. package/dist/types-B4sUC2p1.d.mts.map +0 -1
  1184. package/dist/types-B7Lmsh1E.d.mts +0 -887
  1185. package/dist/types-B7Lmsh1E.d.mts.map +0 -1
  1186. package/dist/types-BZakh7Ym.mjs +0 -22
  1187. package/dist/types-BZakh7Ym.mjs.map +0 -1
  1188. package/dist/types-B_CppEmv.d.mts +0 -264
  1189. package/dist/types-B_CppEmv.d.mts.map +0 -1
  1190. package/dist/types-BcrBrE6-.mjs +0 -159
  1191. package/dist/types-BcrBrE6-.mjs.map +0 -1
  1192. package/dist/types-BkUg2yHx.mjs +0 -92
  1193. package/dist/types-BkUg2yHx.mjs.map +0 -1
  1194. package/dist/types-CAZgq9fO.d.mts +0 -124
  1195. package/dist/types-CAZgq9fO.d.mts.map +0 -1
  1196. package/dist/types-Cd-O03VG.d.mts +0 -363
  1197. package/dist/types-Cd-O03VG.d.mts.map +0 -1
  1198. package/dist/types-Cr-Kg-3D.d.mts +0 -1641
  1199. package/dist/types-Cr-Kg-3D.d.mts.map +0 -1
  1200. package/dist/types-D2fvWd1i.d.mts +0 -359
  1201. package/dist/types-D2fvWd1i.d.mts.map +0 -1
  1202. package/dist/types-D7HUsguf.mjs +0 -77
  1203. package/dist/types-D7HUsguf.mjs.map +0 -1
  1204. package/dist/types-DA1Te3Oy.d.mts +0 -198
  1205. package/dist/types-DA1Te3Oy.d.mts.map +0 -1
  1206. package/dist/types-DhV6Q5bP.mjs +0 -18
  1207. package/dist/types-DhV6Q5bP.mjs.map +0 -1
  1208. package/dist/types-DnnVSl6Y.d.mts +0 -85
  1209. package/dist/types-DnnVSl6Y.d.mts.map +0 -1
  1210. package/dist/types-VT4-BugW.mjs +0 -16
  1211. package/dist/types-VT4-BugW.mjs.map +0 -1
  1212. package/dist/upload-attempts-B68ZGNu9.mjs +0 -32
  1213. package/dist/upload-attempts-B68ZGNu9.mjs.map +0 -1
  1214. package/dist/url-pattern-CCeZMGOh.mjs +0 -33
  1215. package/dist/url-pattern-CCeZMGOh.mjs.map +0 -1
  1216. package/dist/user-DDSL-sGw.mjs +0 -171
  1217. package/dist/user-DDSL-sGw.mjs.map +0 -1
  1218. package/dist/utils-DdhmO9w9.mjs +0 -439
  1219. package/dist/utils-DdhmO9w9.mjs.map +0 -1
  1220. package/dist/validate-CHosPEhs.mjs +0 -453
  1221. package/dist/validate-CHosPEhs.mjs.map +0 -1
  1222. package/dist/validate-CM79QXYE.d.mts +0 -432
  1223. package/dist/validate-CM79QXYE.d.mts.map +0 -1
  1224. package/dist/validation-BFecQczG.mjs +0 -218
  1225. package/dist/validation-BFecQczG.mjs.map +0 -1
  1226. package/dist/version-BRZXVifl.mjs +0 -9
  1227. package/dist/version-BRZXVifl.mjs.map +0 -1
  1228. package/dist/version-DXsxRrob.mjs +0 -7
  1229. package/dist/version-DXsxRrob.mjs.map +0 -1
  1230. package/dist/widgets-WdV72brA.mjs +0 -126
  1231. package/dist/widgets-WdV72brA.mjs.map +0 -1
  1232. package/dist/wxr-taxonomies-BHTdqkmZ.d.mts +0 -34
  1233. package/dist/wxr-taxonomies-BHTdqkmZ.d.mts.map +0 -1
  1234. package/dist/wxr-taxonomies-DP6ESgMN.mjs +0 -372
  1235. package/dist/wxr-taxonomies-DP6ESgMN.mjs.map +0 -1
  1236. package/dist/zod-generator-D6uE4WiS.mjs +0 -389
  1237. package/dist/zod-generator-D6uE4WiS.mjs.map +0 -1
  1238. package/src/astro/routes/api/relations/[id]/translations.ts +0 -33
  1239. /package/dist/{api-tokens-CE1ECIg0.mjs → api-tokens-FaG1zPsj.mjs} +0 -0
  1240. /package/dist/{ssrf-DpBH7aOt.mjs → ssrf-DZOt8Qof.mjs} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["findProjectRoot","listCommand","getCommand","createCommand","deleteCommand","publishCommand","readPackageJson","fileExists","fileExists","isRecord","parseToml","parse","fileExists","readPackageJson","listCommand","getCommand","deleteCommand","listCommand","getCommand","isRecord","moduleExport","defaultDependencies","fileExists","capabilitiesToDeclaredAccess","declaredAccessToCapabilities","formatBytes","fileExists","formatBytes","fileExists","listCommand","commonArgs","consola","consola"],"sources":["../../src/cli/commands/auth.ts","../../src/cli/credentials.ts","../../src/cli/client-factory.ts","../../src/cli/output.ts","../../src/cli/commands/content.ts","../../src/database/connection.ts","../../src/cli/commands/dev.ts","../../src/cli/commands/doctor.ts","../../src/cli/commands/export-seed.ts","../../src/cli/commands/init.ts","../../src/cli/commands/login.ts","../../src/cli/commands/media.ts","../../src/cli/commands/menu.ts","../../src/migrations/config-loader.ts","../../src/cli/commands/migrate.ts","../../src/cli/commands/bundle-utils.ts","../../src/cli/commands/bundle.ts","../../src/cli/commands/plugin-init.ts","../../src/cli/commands/plugin-validate.ts","../../src/cli/commands/publish.ts","../../src/cli/commands/plugin.ts","../../src/cli/commands/schema.ts","../../src/cli/commands/search-cmd.ts","../../src/cli/commands/secrets.ts","../../src/cli/commands/seed.ts","../../src/cli/site/archive.ts","../../src/cli/site/shared.ts","../../src/cli/site/export.ts","../../src/cli/site/import.ts","../../src/cli/commands/site.ts","../../src/cli/commands/taxonomy.ts","../../src/cli/commands/types.ts","../../src/cli/index.ts"],"sourcesContent":["/**\n * Auth CLI commands (deprecated)\n *\n * Kept as a deprecated alias for backwards compatibility. The original\n * `emdash auth secret` was documented in published docs and is plausibly\n * scripted in user CI (e.g. `npx emdash auth secret >> .env`). Removing\n * it outright would break those scripts on minor-version upgrade.\n *\n * The command still emits an `EMDASH_AUTH_SECRET=<32-byte-base64url>`\n * line, unchanged. `EMDASH_AUTH_SECRET` itself is now legacy: it's only\n * read as a fallback source for the commenter-IP hash salt so installs\n * upgrading from a prior version keep stable IP hashes (and therefore\n * stable rate-limit buckets). New installs don't need to set it.\n *\n * The deprecation note steers users toward `emdash secrets generate`\n * (which emits a different, versioned `emdash_enc_v1_*` value for\n * `EMDASH_ENCRYPTION_KEY` — used to encrypt plugin secrets at rest).\n *\n * Will be removed in a future minor.\n */\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\nimport pc from \"picocolors\";\n\nimport { encodeBase64url } from \"../../utils/base64.js\";\n\nfunction generateAuthSecret(): string {\n\tconst bytes = new Uint8Array(32);\n\tcrypto.getRandomValues(bytes);\n\treturn encodeBase64url(bytes);\n}\n\nconst secretCommand = defineCommand({\n\tmeta: {\n\t\tname: \"secret\",\n\t\tdescription: \"[DEPRECATED] Generate a value for legacy EMDASH_AUTH_SECRET\",\n\t},\n\trun() {\n\t\tconst secret = generateAuthSecret();\n\n\t\t// Match the original behavior verbatim: pretty-printed name=value\n\t\t// on stdout (most scripts piped this to a file expecting that shape).\n\t\tconsola.log(\"\");\n\t\tconsola.log(pc.bold(\"Generated auth secret:\"));\n\t\tconsola.log(\"\");\n\t\tconsola.log(` ${pc.cyan(\"EMDASH_AUTH_SECRET\")}=${pc.green(secret)}`);\n\t\tconsola.log(\"\");\n\t\tconsola.log(pc.dim(\"Add this to your environment variables.\"));\n\t\tconsola.log(\"\");\n\t\t// Deprecation note on stderr so it doesn't break stdout consumers.\n\t\tprocess.stderr.write(\n\t\t\t`${pc.yellow(\"Note:\")} ${pc.bold(\"emdash auth secret\")} is deprecated and will be removed in a future minor. ` +\n\t\t\t\t`${pc.cyan(\"EMDASH_AUTH_SECRET\")} itself is now optional — it's only used as a legacy fallback for the commenter-IP hash salt. ` +\n\t\t\t\t`For encrypting plugin secrets at rest, use ${pc.bold(\"emdash secrets generate\")} (a different secret: ${pc.cyan(\"EMDASH_ENCRYPTION_KEY\")}).\\n`,\n\t\t);\n\t},\n});\n\nexport const authCommand = defineCommand({\n\tmeta: {\n\t\tname: \"auth\",\n\t\tdescription: \"[DEPRECATED] Authentication utilities (use `emdash secrets` for new flows)\",\n\t},\n\tsubCommands: {\n\t\tsecret: secretCommand,\n\t},\n});\n","/**\n * Credential storage for CLI auth tokens.\n *\n * Stores OAuth tokens in ~/.config/emdash/auth.json.\n * Remote URLs are keyed by origin, local dev by project path.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface StoredCredential {\n\taccessToken: string;\n\trefreshToken: string;\n\texpiresAt: string;\n\turl?: string; // For local dev: the localhost URL\n\t/** Custom headers to send with every request (e.g. CF Access service token) */\n\tcustomHeaders?: Record<string, string>;\n\tuser?: {\n\t\temail: string;\n\t\trole: string;\n\t};\n}\n\n/** Credential for marketplace auth (GitHub OAuth JWT, no refresh token) */\nexport interface MarketplaceCredential {\n\ttoken: string;\n\texpiresAt: string;\n\tauthor?: {\n\t\tid: string;\n\t\tname: string;\n\t};\n}\n\ntype CredentialStore = Record<string, StoredCredential | MarketplaceCredential>;\n\n// ---------------------------------------------------------------------------\n// Paths\n// ---------------------------------------------------------------------------\n\nfunction getConfigDir(): string {\n\t// XDG_CONFIG_HOME or ~/.config\n\tconst xdg = process.env[\"XDG_CONFIG_HOME\"];\n\tif (xdg) return join(xdg, \"emdash\");\n\treturn join(homedir(), \".config\", \"emdash\");\n}\n\nfunction getCredentialPath(): string {\n\treturn join(getConfigDir(), \"auth.json\");\n}\n\n// ---------------------------------------------------------------------------\n// Key resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the credential key for a given URL.\n *\n * Remote URLs are keyed by origin (e.g. \"https://my-site.pages.dev\").\n * Local dev instances are keyed by project path (e.g. \"path:/Users/matt/sites/blog\").\n */\nexport function resolveCredentialKey(baseUrl: string): string {\n\ttry {\n\t\tconst url = new URL(baseUrl);\n\t\tconst isLocal =\n\t\t\turl.hostname === \"localhost\" || url.hostname === \"127.0.0.1\" || url.hostname === \"[::1]\";\n\n\t\tif (isLocal) {\n\t\t\t// For local dev, key by project path\n\t\t\tconst projectPath = findProjectRoot(process.cwd());\n\t\t\tif (projectPath) {\n\t\t\t\treturn `path:${projectPath}`;\n\t\t\t}\n\t\t\t// Fallback to URL if no project root found\n\t\t\treturn url.origin;\n\t\t}\n\n\t\treturn url.origin;\n\t} catch {\n\t\treturn baseUrl;\n\t}\n}\n\n/**\n * Walk up from cwd to find the project root (directory containing astro.config.*).\n */\nfunction findProjectRoot(from: string): string | null {\n\tlet dir = resolve(from);\n\tconst root = resolve(\"/\");\n\n\twhile (dir !== root) {\n\t\tfor (const name of [\n\t\t\t\"astro.config.ts\",\n\t\t\t\"astro.config.mts\",\n\t\t\t\"astro.config.js\",\n\t\t\t\"astro.config.mjs\",\n\t\t]) {\n\t\t\tif (existsSync(join(dir, name))) {\n\t\t\t\treturn dir;\n\t\t\t}\n\t\t}\n\t\tconst parent = resolve(dir, \"..\");\n\t\tif (parent === dir) break;\n\t\tdir = parent;\n\t}\n\n\treturn null;\n}\n\n// ---------------------------------------------------------------------------\n// Read/write\n// ---------------------------------------------------------------------------\n\nfunction readStore(): CredentialStore {\n\tconst path = getCredentialPath();\n\ttry {\n\t\tif (existsSync(path)) {\n\t\t\tconst content = readFileSync(path, \"utf-8\");\n\t\t\treturn JSON.parse(content) as CredentialStore;\n\t\t}\n\t} catch {\n\t\t// Corrupt file — start fresh\n\t}\n\treturn {};\n}\n\nfunction writeStore(store: CredentialStore): void {\n\tconst dir = getConfigDir();\n\tmkdirSync(dir, { recursive: true, mode: 0o700 });\n\n\tconst path = getCredentialPath();\n\twriteFileSync(path, JSON.stringify(store, null, \"\\t\"), {\n\t\tencoding: \"utf-8\",\n\t\tmode: 0o600, // Owner read/write only\n\t});\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Get stored credentials for a URL.\n */\nexport function getCredentials(baseUrl: string): StoredCredential | null {\n\tconst key = resolveCredentialKey(baseUrl);\n\tconst store = readStore();\n\tconst cred = store[key];\n\tif (!cred || !(\"accessToken\" in cred)) return null;\n\treturn cred;\n}\n\n/**\n * Save credentials for a URL.\n */\nexport function saveCredentials(baseUrl: string, cred: StoredCredential): void {\n\tconst key = resolveCredentialKey(baseUrl);\n\tconst store = readStore();\n\tstore[key] = cred;\n\twriteStore(store);\n}\n\n/**\n * Remove credentials for a URL.\n */\nexport function removeCredentials(baseUrl: string): boolean {\n\tconst key = resolveCredentialKey(baseUrl);\n\tconst store = readStore();\n\tif (key in store) {\n\t\tdelete store[key];\n\t\twriteStore(store);\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/**\n * List all stored credential keys.\n */\nexport function listCredentialKeys(): string[] {\n\tconst store = readStore();\n\treturn Object.keys(store);\n}\n\n// ---------------------------------------------------------------------------\n// Marketplace credentials\n// ---------------------------------------------------------------------------\n\nfunction marketplaceKey(registryUrl: string): string {\n\ttry {\n\t\treturn `marketplace:${new URL(registryUrl).origin}`;\n\t} catch {\n\t\treturn `marketplace:${registryUrl}`;\n\t}\n}\n\n/**\n * Get stored marketplace credential for a registry URL.\n */\nexport function getMarketplaceCredential(registryUrl: string): MarketplaceCredential | null {\n\tconst key = marketplaceKey(registryUrl);\n\tconst store = readStore();\n\tconst cred = store[key];\n\tif (!cred || !(\"token\" in cred)) return null;\n\t// Check expiry\n\tif (new Date(cred.expiresAt) < new Date()) return null;\n\treturn cred;\n}\n\n/**\n * Save marketplace credential for a registry URL.\n */\nexport function saveMarketplaceCredential(registryUrl: string, cred: MarketplaceCredential): void {\n\tconst key = marketplaceKey(registryUrl);\n\tconst store = readStore();\n\tstore[key] = cred;\n\twriteStore(store);\n}\n\n/**\n * Remove marketplace credential for a registry URL.\n */\nexport function removeMarketplaceCredential(registryUrl: string): boolean {\n\tconst key = marketplaceKey(registryUrl);\n\tconst store = readStore();\n\tif (key in store) {\n\t\tdelete store[key];\n\t\twriteStore(store);\n\t\treturn true;\n\t}\n\treturn false;\n}\n","import { customHeadersInterceptor, resolveCustomHeaders } from \"../client/cf-access.js\";\nimport { EmDashClient } from \"../client/index.js\";\nimport type { Interceptor } from \"../client/transport.js\";\nimport { getCredentials, saveCredentials } from \"./credentials.js\";\n\nexport interface ClientArgs {\n\turl?: string;\n\ttoken?: string;\n}\n\n/**\n * Shared connection args for all CLI commands that talk to an EmDash instance.\n * Spread into each command's `args` definition.\n */\nexport const connectionArgs = {\n\turl: {\n\t\ttype: \"string\" as const,\n\t\talias: \"u\",\n\t\tdescription: \"EmDash instance URL\",\n\t},\n\ttoken: {\n\t\ttype: \"string\" as const,\n\t\talias: \"t\",\n\t\tdescription: \"Auth token\",\n\t},\n\theader: {\n\t\ttype: \"string\" as const,\n\t\talias: \"H\",\n\t\tdescription: 'Custom header \"Name: Value\" (repeatable, or use EMDASH_HEADERS env)',\n\t},\n\tjson: {\n\t\ttype: \"boolean\" as const,\n\t\tdescription: \"Output as JSON\",\n\t},\n};\n\n/** The instance URL from `--url`, `EMDASH_URL`, or the local dev default. */\nexport function resolveBaseUrl(args: ClientArgs): string {\n\treturn args.url || process.env[\"EMDASH_URL\"] || \"http://localhost:4321\";\n}\n\n/**\n * Create an EmDashClient from CLI args, env vars, and stored credentials.\n *\n * Auth resolution order:\n * 1. --token flag\n * 2. EMDASH_TOKEN env var\n * 3. Stored credentials (~/.config/emdash/auth.json)\n * 4. Dev bypass (if URL is localhost)\n *\n * Custom headers are merged from (in priority order):\n * 1. Stored credentials (persisted during `emdash login --header`)\n * 2. EMDASH_HEADERS env var\n * 3. --header CLI flags\n */\nexport function createClientFromArgs(args: ClientArgs): EmDashClient {\n\tconst baseUrl = resolveBaseUrl(args);\n\tlet token = args.token || process.env[\"EMDASH_TOKEN\"];\n\n\tconst isLocal = baseUrl.includes(\"localhost\") || baseUrl.includes(\"127.0.0.1\");\n\tconst cred = !token ? getCredentials(baseUrl) : null;\n\n\t// Merge custom headers: stored credentials < env var < CLI flags\n\tconst customHeaders = {\n\t\t...cred?.customHeaders,\n\t\t...resolveCustomHeaders(),\n\t};\n\n\tconst extraInterceptors: Interceptor[] = [];\n\tif (Object.keys(customHeaders).length > 0) {\n\t\textraInterceptors.push(customHeadersInterceptor(customHeaders));\n\t}\n\n\t// Check stored credentials if no explicit token\n\tif (!token && cred) {\n\t\t// Check if access token is expired\n\t\tif (new Date(cred.expiresAt) > new Date()) {\n\t\t\ttoken = cred.accessToken;\n\t\t} else {\n\t\t\t// Token expired — use the refresh interceptor in the client\n\t\t\t// Pass the refresh token so the client can auto-refresh\n\t\t\treturn new EmDashClient({\n\t\t\t\tbaseUrl,\n\t\t\t\ttoken: cred.accessToken,\n\t\t\t\trefreshToken: cred.refreshToken,\n\t\t\t\tonTokenRefresh: (newAccessToken, expiresIn) => {\n\t\t\t\t\tsaveCredentials(baseUrl, {\n\t\t\t\t\t\t...cred,\n\t\t\t\t\t\taccessToken: newAccessToken,\n\t\t\t\t\t\texpiresAt: new Date(Date.now() + expiresIn * 1000).toISOString(),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tinterceptors: extraInterceptors,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn new EmDashClient({\n\t\tbaseUrl,\n\t\ttoken,\n\t\tdevBypass: !token && isLocal,\n\t\tinterceptors: extraInterceptors,\n\t});\n}\n","import { consola } from \"consola\";\n\ninterface OutputArgs {\n\tjson?: boolean;\n}\n\n/**\n * Redirect consola output to stderr so it doesn't pollute JSON on stdout.\n *\n * Call this early in any command that uses `output()` with `--json`.\n * Safe to call multiple times — only applies the redirect once.\n */\nexport function configureOutputMode(args: OutputArgs): void {\n\tif (args.json || !process.stdout.isTTY) {\n\t\t// Send all consola output to stderr so stdout is clean JSON\n\t\tconsola.options.stdout = process.stderr;\n\t\tconsola.options.stderr = process.stderr;\n\t}\n}\n\n/**\n * Output data as JSON or pretty-printed.\n *\n * If stdout is not a TTY or --json is set, outputs JSON.\n * Otherwise, outputs a formatted representation.\n */\nexport function output(data: unknown, args: OutputArgs): void {\n\tconst useJson = args.json || !process.stdout.isTTY;\n\n\tif (useJson) {\n\t\t// JSON output to stdout for piping\n\t\tprocess.stdout.write(JSON.stringify(data, null, 2) + \"\\n\");\n\t} else {\n\t\t// Pretty output via consola\n\t\tprettyPrint(data);\n\t}\n}\n\nfunction prettyPrint(data: unknown, indent: number = 0): void {\n\tif (data === null || data === undefined) {\n\t\tconsola.log(\"(empty)\");\n\t\treturn;\n\t}\n\n\tif (Array.isArray(data)) {\n\t\tif (data.length === 0) {\n\t\t\tconsola.log(\"(no items)\");\n\t\t\treturn;\n\t\t}\n\t\tfor (const item of data) {\n\t\t\tprettyPrint(item, indent);\n\t\t\tif (indent === 0) consola.log(\"---\");\n\t\t}\n\t\treturn;\n\t}\n\n\tif (typeof data === \"object\") {\n\t\tconst obj = Object(data) as Record<string, unknown>;\n\n\t\t// Check if it's a list result with items\n\t\tif (\"items\" in obj && Array.isArray(obj.items)) {\n\t\t\tprettyPrint(obj.items, indent);\n\t\t\tif (typeof obj.nextCursor === \"string\") {\n\t\t\t\tconsola.log(`\\nNext cursor: ${obj.nextCursor}`);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Print object fields\n\t\tconst prefix = \" \".repeat(indent);\n\t\tfor (const [key, value] of Object.entries(obj)) {\n\t\t\tif (value === null || value === undefined) continue;\n\t\t\tif (typeof value === \"object\" && !Array.isArray(value)) {\n\t\t\t\tconsola.log(`${prefix}${key}:`);\n\t\t\t\tprettyPrint(value, indent + 1);\n\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\tconsola.log(`${prefix}${key}: [${value.length} items]`);\n\t\t\t} else {\n\t\t\t\tconst str = typeof value === \"string\" ? value : JSON.stringify(value);\n\t\t\t\t// Truncate long values\n\t\t\t\tconst display = str.length > 80 ? str.slice(0, 77) + \"...\" : str;\n\t\t\t\tconsola.log(`${prefix}${key}: ${display}`);\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\n\tconsola.log(typeof data === \"string\" ? data : JSON.stringify(data));\n}\n","/**\n * emdash content\n *\n * CRUD commands for managing content items via the EmDash REST API.\n */\n\nimport { readFile } from \"node:fs/promises\";\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\n\nimport { convertDataForRead } from \"../../client/portable-text.js\";\nimport { connectionArgs, createClientFromArgs } from \"../client-factory.js\";\nimport { configureOutputMode, output } from \"../output.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Read content data from --data, --file, or --stdin */\nasync function readInputData(args: {\n\tdata?: string;\n\tfile?: string;\n\tstdin?: boolean;\n}): Promise<Record<string, unknown>> {\n\tif (args.data) {\n\t\ttry {\n\t\t\treturn JSON.parse(args.data) as Record<string, unknown>;\n\t\t} catch {\n\t\t\tthrow new Error(\"Invalid JSON in --data argument\");\n\t\t}\n\t}\n\n\tif (args.file) {\n\t\ttry {\n\t\t\tconst content = await readFile(args.file, \"utf-8\");\n\t\t\treturn JSON.parse(content) as Record<string, unknown>;\n\t\t} catch (error) {\n\t\t\tif (error instanceof SyntaxError) {\n\t\t\t\tthrow new Error(`Invalid JSON in file: ${args.file}`, { cause: error });\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tif (args.stdin) {\n\t\tconst chunks: Buffer[] = [];\n\t\tfor await (const chunk of process.stdin) {\n\t\t\tchunks.push(chunk as Buffer);\n\t\t}\n\t\tconst content = Buffer.concat(chunks).toString(\"utf-8\");\n\t\ttry {\n\t\t\treturn JSON.parse(content) as Record<string, unknown>;\n\t\t} catch {\n\t\t\tthrow new Error(\"Invalid JSON from stdin\");\n\t\t}\n\t}\n\n\tthrow new Error(\"Provide content data via --data, --file, or --stdin\");\n}\n\n// ---------------------------------------------------------------------------\n// Subcommands\n// ---------------------------------------------------------------------------\n\nconst listCommand = defineCommand({\n\tmeta: { name: \"list\", description: \"List content items\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tstatus: { type: \"string\", description: \"Filter by status\" },\n\t\tlocale: { type: \"string\", description: \"Filter by locale\" },\n\t\tlimit: { type: \"string\", description: \"Maximum items to return\" },\n\t\tcursor: { type: \"string\", description: \"Pagination cursor\" },\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst result = await client.list(args.collection, {\n\t\t\t\tstatus: args.status,\n\t\t\t\tlocale: args.locale,\n\t\t\t\tlimit: args.limit ? parseInt(args.limit, 10) : undefined,\n\t\t\t\tcursor: args.cursor,\n\t\t\t});\n\t\t\t// Summarize items — strip heavy data fields for readable output\n\t\t\tconst summary = {\n\t\t\t\titems: result.items.map((item) => ({\n\t\t\t\t\tid: item.id,\n\t\t\t\t\tslug: item.slug,\n\t\t\t\t\tlocale: item.locale,\n\t\t\t\t\tstatus: item.status,\n\t\t\t\t\ttitle: typeof item.data?.title === \"string\" ? item.data.title : undefined,\n\t\t\t\t\tupdatedAt: item.updatedAt,\n\t\t\t\t})),\n\t\t\t\tnextCursor: result.nextCursor,\n\t\t\t};\n\t\t\toutput(summary, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst getCommand = defineCommand({\n\tmeta: { name: \"get\", description: \"Get a single content item\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Content item ID or slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tlocale: { type: \"string\", description: \"Locale for slug resolution\" },\n\t\traw: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Return raw Portable Text (skip markdown conversion)\",\n\t\t},\n\t\tpublished: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Return published data only (ignore pending draft)\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst item = await client.get(args.collection, args.id, {\n\t\t\t\traw: args.raw,\n\t\t\t\tlocale: args.locale,\n\t\t\t});\n\n\t\t\t// If a draft exists, overlay draft data unless --published\n\t\t\tif (!args.published && item.draftRevisionId) {\n\t\t\t\tconst comparison = await client.compare(args.collection, args.id);\n\t\t\t\tif (comparison.hasChanges && comparison.draft) {\n\t\t\t\t\titem.data = comparison.draft;\n\t\t\t\t\t// The comparison endpoint returns raw PT data. Apply the same\n\t\t\t\t\t// PT-to-markdown conversion that `client.get` does, unless --raw.\n\t\t\t\t\tif (!args.raw && item.data) {\n\t\t\t\t\t\tconst col = await client.collection(args.collection);\n\t\t\t\t\t\tconst fields = col.fields.map((f) => ({ slug: f.slug, type: f.type }));\n\t\t\t\t\t\titem.data = convertDataForRead(item.data, fields, false);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\toutput(item, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst createCommand = defineCommand({\n\tmeta: { name: \"create\", description: \"Create a content item\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tdata: { type: \"string\", description: \"Content data as JSON string\" },\n\t\tfile: { type: \"string\", description: \"Read content data from a JSON file\" },\n\t\tstdin: { type: \"boolean\", description: \"Read content data from stdin\" },\n\t\tslug: { type: \"string\", description: \"Content slug\" },\n\t\tlocale: { type: \"string\", description: \"Content locale\" },\n\t\t\"translation-of\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"ID of content item to link as translation\",\n\t\t},\n\t\tdraft: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Keep as draft instead of auto-publishing\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst data = await readInputData(args);\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst item = await client.create(args.collection, {\n\t\t\t\tdata,\n\t\t\t\tslug: args.slug,\n\t\t\t\tlocale: args.locale,\n\t\t\t\ttranslationOf: args[\"translation-of\"],\n\t\t\t});\n\n\t\t\t// Auto-publish unless --draft is set\n\t\t\tif (!args.draft) {\n\t\t\t\tawait client.publish(args.collection, item.id);\n\t\t\t}\n\n\t\t\t// Re-fetch to return the current state\n\t\t\tconst result = await client.get(args.collection, item.id);\n\t\t\toutput(result, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst updateCommand = defineCommand({\n\tmeta: { name: \"update\", description: \"Update a content item\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Content item ID or slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tdata: { type: \"string\", description: \"Content data as JSON string\" },\n\t\tfile: { type: \"string\", description: \"Read content data from a JSON file\" },\n\t\trev: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Revision token from get (prevents overwriting unseen changes)\",\n\t\t\trequired: true,\n\t\t},\n\t\tlocale: { type: \"string\", description: \"Locale for slug resolution\" },\n\t\tdraft: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Keep as draft instead of auto-publishing\",\n\t\t},\n\t\t\"override-lock\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Write even though another editor holds this entry's edit lock\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst data = await readInputData(args);\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst updated = await client.update(args.collection, args.id, {\n\t\t\t\tdata,\n\t\t\t\t_rev: args.rev,\n\t\t\t\tlocale: args.locale,\n\t\t\t\toverrideLock: args[\"override-lock\"],\n\t\t\t});\n\n\t\t\t// Auto-publish unless --draft is set.\n\t\t\t// Only publish if the update created a draft revision (i.e. the\n\t\t\t// collection supports revisions and data went to a draft).\n\t\t\tif (!args.draft && updated.draftRevisionId) {\n\t\t\t\tawait client.publish(args.collection, updated.id, {\n\t\t\t\t\toverrideLock: args[\"override-lock\"],\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Re-fetch to return the current state\n\t\t\tconst item = await client.get(args.collection, updated.id);\n\t\t\toutput(item, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst deleteCommand = defineCommand({\n\tmeta: { name: \"delete\", description: \"Delete a content item\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Content item ID or slug\",\n\t\t\trequired: true,\n\t\t},\n\t\t\"override-lock\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Write even though another editor holds this entry's edit lock\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tawait client.delete(args.collection, args.id, { overrideLock: args[\"override-lock\"] });\n\t\t\toutput({ success: true }, args);\n\t\t\tconsola.success(`Deleted ${args.collection}/${args.id}`);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst publishCommand = defineCommand({\n\tmeta: { name: \"publish\", description: \"Publish a content item\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Content item ID or slug\",\n\t\t\trequired: true,\n\t\t},\n\t\t\"override-lock\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Write even though another editor holds this entry's edit lock\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tawait client.publish(args.collection, args.id, { overrideLock: args[\"override-lock\"] });\n\t\t\toutput({ success: true }, args);\n\t\t\tconsola.success(`Published ${args.collection}/${args.id}`);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst unpublishCommand = defineCommand({\n\tmeta: { name: \"unpublish\", description: \"Unpublish a content item\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Content item ID or slug\",\n\t\t\trequired: true,\n\t\t},\n\t\t\"override-lock\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Write even though another editor holds this entry's edit lock\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tawait client.unpublish(args.collection, args.id, { overrideLock: args[\"override-lock\"] });\n\t\t\toutput({ success: true }, args);\n\t\t\tconsola.success(`Unpublished ${args.collection}/${args.id}`);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst scheduleCommand = defineCommand({\n\tmeta: { name: \"schedule\", description: \"Schedule content for publishing\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Content item ID or slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tat: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"ISO 8601 datetime with Z or an explicit UTC offset to publish at\",\n\t\t\trequired: true,\n\t\t},\n\t\t\"override-lock\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Write even though another editor holds this entry's edit lock\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tawait client.schedule(args.collection, args.id, {\n\t\t\t\tat: args.at,\n\t\t\t\toverrideLock: args[\"override-lock\"],\n\t\t\t});\n\t\t\toutput({ success: true }, args);\n\t\t\tconsola.success(`Scheduled ${args.collection}/${args.id} for ${args.at}`);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst restoreCommand = defineCommand({\n\tmeta: { name: \"restore\", description: \"Restore a trashed content item\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Content item ID or slug\",\n\t\t\trequired: true,\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tawait client.restore(args.collection, args.id);\n\t\t\toutput({ success: true }, args);\n\t\t\tconsola.success(`Restored ${args.collection}/${args.id}`);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst translationsCommand = defineCommand({\n\tmeta: { name: \"translations\", description: \"List translations for a content item\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Content item ID or slug\",\n\t\t\trequired: true,\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst translations = await client.translations(args.collection, args.id);\n\t\t\toutput(translations, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\n// ---------------------------------------------------------------------------\n// Export\n// ---------------------------------------------------------------------------\n\nexport const contentCommand = defineCommand({\n\tmeta: { name: \"content\", description: \"Manage content\" },\n\tsubCommands: {\n\t\tlist: listCommand,\n\t\tget: getCommand,\n\t\tcreate: createCommand,\n\t\tupdate: updateCommand,\n\t\tdelete: deleteCommand,\n\t\tpublish: publishCommand,\n\t\tunpublish: unpublishCommand,\n\t\tschedule: scheduleCommand,\n\t\trestore: restoreCommand,\n\t\ttranslations: translationsCommand,\n\t},\n});\n","import { Kysely, SqliteDialect } from \"kysely\";\n\nimport { openNodeSqliteDatabase } from \"../db/node-sqlite-compat.js\";\nimport { EmDashDatabaseError } from \"./errors.js\";\nimport { kyselyLogOption } from \"./instrumentation.js\";\nimport type { Database } from \"./types.js\";\n\nexport { EmDashDatabaseError };\n\nexport interface DatabaseConfig {\n\turl: string;\n\tauthToken?: string;\n\treadOnly?: boolean;\n}\n\n/**\n * Creates a Kysely database instance\n * Supports:\n * - file:./path/to/db.sqlite (local SQLite)\n * - :memory: (in-memory SQLite for testing)\n * - libsql://... (Turso/libSQL with auth token) - TODO\n */\nexport function createDatabase(config: DatabaseConfig): Kysely<Database> {\n\ttry {\n\t\t// Handle file-based SQLite\n\t\tif (config.url.startsWith(\"file:\") || config.url === \":memory:\") {\n\t\t\tconst dbPath = config.url === \":memory:\" ? \":memory:\" : config.url.replace(\"file:\", \"\");\n\n\t\t\tconst sqlite = openNodeSqliteDatabase(dbPath, {\n\t\t\t\tjournalMode: \"wal\",\n\t\t\t\treadOnly: config.readOnly,\n\t\t\t});\n\n\t\t\tconst dialect = new SqliteDialect({\n\t\t\t\tdatabase: sqlite,\n\t\t\t});\n\n\t\t\treturn new Kysely<Database>({ dialect, log: kyselyLogOption() });\n\t\t}\n\n\t\t// Handle libSQL (Turso)\n\t\tif (config.url.startsWith(\"libsql:\")) {\n\t\t\tif (!config.authToken) {\n\t\t\t\tthrow new EmDashDatabaseError(\"Auth token required for remote libSQL database\");\n\t\t\t}\n\t\t\t// LibSQL implementation would use @libsql/kysely-libsql\n\t\t\tthrow new EmDashDatabaseError(\"LibSQL not yet implemented\");\n\t\t}\n\n\t\tthrow new EmDashDatabaseError(`Unsupported database URL scheme: ${config.url}`);\n\t} catch (error) {\n\t\tif (error instanceof EmDashDatabaseError) {\n\t\t\tthrow error;\n\t\t}\n\t\tthrow new EmDashDatabaseError(\"Failed to create database\", error);\n\t}\n}\n","/**\n * emdash dev\n *\n * Start development server with optional schema sync from remote\n */\n\nimport { spawn } from \"node:child_process\";\nimport { access, readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport consola from \"consola\";\n\nimport { createDatabase } from \"../../database/connection.js\";\nimport { runMigrations } from \"../../database/migrations/runner.js\";\n\ninterface PackageJson {\n\tname?: string;\n\tscripts?: Record<string, string>;\n\temdash?: {\n\t\turl?: string;\n\t\tdatabase?: string;\n\t};\n}\n\nasync function readPackageJson(cwd: string): Promise<PackageJson | null> {\n\tconst pkgPath = resolve(cwd, \"package.json\");\n\ttry {\n\t\tconst content = await readFile(pkgPath, \"utf-8\");\n\t\treturn JSON.parse(content);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport const DEV_DEPRECATION_MESSAGE =\n\t\"`emdash dev` is deprecated and will be removed in a future release.\\n\\n\" +\n\t\"Use your project's dev script instead (for example, `pnpm dev`), or run `astro dev` directly.\";\n\nexport const devCommand = defineCommand({\n\tmeta: {\n\t\tname: \"dev\",\n\t\tdescription: \"Start dev server with local database\",\n\t\thidden: true,\n\t},\n\targs: {\n\t\tdatabase: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"d\",\n\t\t\tdescription: \"Database path (default: ./data.db)\",\n\t\t\tdefault: \"./data.db\",\n\t\t},\n\t\ttypes: {\n\t\t\ttype: \"boolean\",\n\t\t\talias: \"t\",\n\t\t\tdescription: \"Generate types from remote before starting\",\n\t\t\tdefault: false,\n\t\t},\n\t\tport: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"p\",\n\t\t\tdescription: \"Port for dev server\",\n\t\t\tdefault: \"4321\",\n\t\t},\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Working directory\",\n\t\t\tdefault: process.cwd(),\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconsola.box({\n\t\t\ttitle: \"DEPRECATED COMMAND\",\n\t\t\tmessage: DEV_DEPRECATION_MESSAGE,\n\t\t});\n\n\t\tconst cwd = resolve(args.cwd);\n\t\tconst pkg = await readPackageJson(cwd);\n\n\t\tif (!pkg) {\n\t\t\tconsola.error(\"No package.json found\");\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconst dbPath = resolve(cwd, args.database);\n\n\t\t// Run migrations if database doesn't exist\n\t\tconst dbExists = await fileExists(dbPath);\n\t\tif (!dbExists) {\n\t\t\tconsola.start(\"Database not found, initializing...\");\n\t\t}\n\n\t\t// Always run migrations (they're idempotent)\n\t\tconst db = createDatabase({ url: `file:${dbPath}` });\n\t\ttry {\n\t\t\tconsola.start(\"Checking database migrations...\");\n\t\t\tconst { applied } = await runMigrations(db);\n\t\t\tif (applied.length > 0) {\n\t\t\t\tconsola.success(`Applied ${applied.length} migrations`);\n\t\t\t} else {\n\t\t\t\tconsola.info(\"Database up to date\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Migration failed:\", error);\n\t\t\tawait db.destroy();\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tawait db.destroy();\n\n\t\t// Generate types from remote if requested\n\t\tif (args.types) {\n\t\t\tconst remoteUrl = pkg.emdash?.url || process.env.EMDASH_URL;\n\n\t\t\tif (!remoteUrl) {\n\t\t\t\tconsola.warn(\"No remote URL configured. Set EMDASH_URL or emdash.url in package.json\");\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tconst { createClientFromArgs } = await import(\"../client-factory.js\");\n\t\t\t\t\tconst client = createClientFromArgs({ url: remoteUrl });\n\t\t\t\t\tconst schema = await client.schemaExport();\n\t\t\t\t\tconst types = await client.schemaTypes();\n\n\t\t\t\t\tconst { mkdir, writeFile } = await import(\"node:fs/promises\");\n\t\t\t\t\tconst { dirname, resolve: resolvePath } = await import(\"node:path\");\n\t\t\t\t\tconst outputPath = resolvePath(cwd, \".emdash/types.ts\");\n\t\t\t\t\tawait mkdir(dirname(outputPath), { recursive: true });\n\t\t\t\t\tawait writeFile(outputPath, types, \"utf-8\");\n\t\t\t\t\tawait writeFile(\n\t\t\t\t\t\tresolvePath(dirname(outputPath), \"schema.json\"),\n\t\t\t\t\t\tJSON.stringify(schema, null, 2),\n\t\t\t\t\t\t\"utf-8\",\n\t\t\t\t\t);\n\t\t\t\t\tconsola.success(`Generated types for ${schema.collections.length} collections`);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsola.warn(\"Type generation failed:\", error instanceof Error ? error.message : error);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Start Astro dev server\n\t\tconsola.start(\"Starting Astro dev server...\");\n\n\t\tconst astroArgs = [\"astro\", \"dev\", \"--port\", args.port];\n\n\t\t// Check if using pnpm, npm, or yarn\n\t\tconst pnpmLockExists = await fileExists(resolve(cwd, \"pnpm-lock.yaml\"));\n\t\tconst yarnLockExists = await fileExists(resolve(cwd, \"yarn.lock\"));\n\n\t\tlet cmd: string;\n\t\tlet cmdArgs: string[];\n\n\t\tif (pnpmLockExists) {\n\t\t\tcmd = \"pnpm\";\n\t\t\tcmdArgs = astroArgs;\n\t\t} else if (yarnLockExists) {\n\t\t\tcmd = \"yarn\";\n\t\t\tcmdArgs = astroArgs;\n\t\t} else {\n\t\t\tcmd = \"npx\";\n\t\t\tcmdArgs = astroArgs;\n\t\t}\n\n\t\tconsola.info(`Running: ${cmd} ${cmdArgs.join(\" \")}`);\n\n\t\tconst child = spawn(cmd, cmdArgs, {\n\t\t\tcwd,\n\t\t\tstdio: \"inherit\",\n\t\t\tenv: {\n\t\t\t\t...process.env,\n\t\t\t\t// Pass database path to Astro\n\t\t\t\tEMDASH_DATABASE_URL: `file:${dbPath}`,\n\t\t\t},\n\t\t});\n\n\t\tchild.on(\"error\", (error) => {\n\t\t\tconsola.error(\"Failed to start dev server:\", error);\n\t\t\tprocess.exit(1);\n\t\t});\n\n\t\tchild.on(\"exit\", (code) => {\n\t\t\tprocess.exit(code ?? 0);\n\t\t});\n\n\t\t// Handle termination signals\n\t\tconst cleanup = () => {\n\t\t\tchild.kill(\"SIGTERM\");\n\t\t};\n\n\t\tprocess.on(\"SIGINT\", cleanup);\n\t\tprocess.on(\"SIGTERM\", cleanup);\n\t},\n});\n","/**\n * emdash doctor\n *\n * Diagnose database health (connection, migrations, schema integrity) and\n * Cloudflare Worker scheduler wiring (Cron Trigger + scheduled() handler).\n */\n\nimport { access, readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport consola from \"consola\";\nimport { parse, printParseErrorCode, type ParseError } from \"jsonc-parser\";\nimport { parse as parseToml } from \"smol-toml\";\n\nimport { createDatabase } from \"../../database/connection.js\";\nimport {\n\tformatDatetimeStorageReport,\n\tscanDatetimeStorage,\n} from \"../../database/datetime-storage.js\";\nimport { listTablesLike } from \"../../database/dialect-helpers.js\";\nimport { getMigrationStatus } from \"../../database/migrations/runner.js\";\n\nexport interface CheckResult {\n\tname: string;\n\tstatus: \"pass\" | \"warn\" | \"fail\";\n\tmessage: string;\n}\n\nconst WRANGLER_CONFIG_FILES = [\"wrangler.jsonc\", \"wrangler.json\", \"wrangler.toml\"] as const;\nconst CLOUDFLARE_WORKER_MODULE = \"@emdash-cms/cloudflare/worker\";\nconst WORKER_FIX = `export { default, PluginBridge } from \"${CLOUDFLARE_WORKER_MODULE}\";`;\nconst MAIN_FIX_JSONC = `\"main\": \"./src/worker.ts\"`;\nconst MAIN_FIX_TOML = `main = \"./src/worker.ts\"`;\nconst TRIGGER_FIX_JSONC = `\"triggers\": { \"crons\": [\"* * * * *\"] }`;\nconst TRIGGER_FIX_TOML = `[triggers]\\ncrons = [\"* * * * *\"]`;\nconst SCHEDULED_HANDLER_PATTERN = /\\bscheduled\\s*:\\s*createScheduledHandler\\s*\\(/m;\n\nfunction triggerFix(configPath: string): string {\n\treturn configPath.endsWith(\".toml\") ? TRIGGER_FIX_TOML : TRIGGER_FIX_JSONC;\n}\n\nfunction mainFix(configPath: string): string {\n\treturn configPath.endsWith(\".toml\") ? MAIN_FIX_TOML : MAIN_FIX_JSONC;\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction sourcePosition(source: string, offset: number): { line: number; column: number } {\n\tconst prefix = source.slice(0, offset);\n\treturn {\n\t\tline: prefix.split(\"\\n\").length,\n\t\tcolumn: offset - prefix.lastIndexOf(\"\\n\"),\n\t};\n}\n\nasync function findWranglerConfig(cwd: string): Promise<string | null> {\n\tfor (const filename of WRANGLER_CONFIG_FILES) {\n\t\tconst path = resolve(cwd, filename);\n\t\tif (await fileExists(path)) return path;\n\t}\n\treturn null;\n}\n\nfunction workerExportsScheduledMaintenance(source: string): boolean {\n\tconst modulePattern = CLOUDFLARE_WORKER_MODULE.replaceAll(\"/\", \"\\\\/\");\n\tconst reExportsWorker = new RegExp(\n\t\t`export\\\\s*\\\\{[^}]*\\\\bdefault\\\\b[^}]*\\\\}\\\\s*from\\\\s*[\"']${modulePattern}[\"']`,\n\t\t\"m\",\n\t);\n\tconst importsFactory = new RegExp(\n\t\t`import\\\\s+[^;]*\\\\{[^}]*\\\\bcreateScheduledHandler\\\\b[^}]*\\\\}\\\\s*from\\\\s*[\"']${modulePattern}[\"']`,\n\t\t\"m\",\n\t);\n\treturn (\n\t\treExportsWorker.test(source) ||\n\t\t(importsFactory.test(source) && SCHEDULED_HANDLER_PATTERN.test(source))\n\t);\n}\n\nexport async function checkSchedulerWiring(cwd: string): Promise<CheckResult[]> {\n\tconst configPath = await findWranglerConfig(cwd);\n\tif (!configPath) return [];\n\treturn checkSchedulerWiringAtPath(cwd, configPath);\n}\n\nasync function checkSchedulerWiringAtPath(cwd: string, configPath: string): Promise<CheckResult[]> {\n\tconst configSource = await readFile(configPath, \"utf8\");\n\tlet parsed: unknown;\n\tif (configPath.endsWith(\".toml\")) {\n\t\ttry {\n\t\t\tparsed = parseToml(configSource);\n\t\t} catch (error) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tname: \"scheduler config\",\n\t\t\t\t\tstatus: \"fail\",\n\t\t\t\t\tmessage: `could not parse ${configPath}: ${error instanceof Error ? error.message : \"invalid TOML\"} — fix the Wrangler configuration syntax`,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t} else {\n\t\tconst parseErrors: ParseError[] = [];\n\t\tparsed = parse(configSource, parseErrors, {\n\t\t\tallowTrailingComma: true,\n\t\t\tdisallowComments: false,\n\t\t});\n\t\tif (parseErrors.length > 0) {\n\t\t\tconst error = parseErrors[0];\n\t\t\tconst { line, column } = sourcePosition(configSource, error.offset);\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tname: \"scheduler config\",\n\t\t\t\t\tstatus: \"fail\",\n\t\t\t\t\tmessage: `could not parse ${configPath}: ${printParseErrorCode(error.error)} at line ${line}, column ${column} — fix the Wrangler configuration syntax`,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t}\n\tif (!isRecord(parsed)) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tname: \"scheduler config\",\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tmessage: `could not parse ${configPath}: expected an object — fix the Wrangler configuration syntax`,\n\t\t\t},\n\t\t];\n\t}\n\n\tconst triggers = isRecord(parsed.triggers) ? parsed.triggers : null;\n\tconst hasCronTrigger =\n\t\tArray.isArray(triggers?.crons) &&\n\t\ttriggers.crons.some((cron) => typeof cron === \"string\" && cron.trim().length > 0);\n\tconst main = typeof parsed.main === \"string\" && parsed.main.trim() ? parsed.main : null;\n\tif (!main) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tname: \"scheduler handler\",\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tmessage: `Wrangler configuration has no Worker entry to inspect — add ${mainFix(configPath)}, then export: ${WORKER_FIX}`,\n\t\t\t},\n\t\t];\n\t}\n\n\tconst workerPath = resolve(cwd, main);\n\tlet hasScheduledHandler = false;\n\ttry {\n\t\tconst workerSource = await readFile(workerPath, \"utf8\");\n\t\thasScheduledHandler = workerExportsScheduledMaintenance(workerSource);\n\t} catch (error) {\n\t\tconst code = isRecord(error) && typeof error.code === \"string\" ? error.code : null;\n\t\tif (code !== \"ENOENT\") {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tname: \"scheduler handler\",\n\t\t\t\t\tstatus: \"fail\",\n\t\t\t\t\tmessage: `could not read Worker entry ${workerPath}: ${error instanceof Error ? error.message : \"unknown I/O error\"} — check the file path and permissions`,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t\treturn [\n\t\t\t{\n\t\t\t\tname: \"scheduler handler\",\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tmessage: `Worker entry not found at ${workerPath} — create it with: ${WORKER_FIX}`,\n\t\t\t},\n\t\t];\n\t}\n\n\tif (hasCronTrigger && !hasScheduledHandler) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tname: \"scheduler handler\",\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tmessage: `Cron Trigger is configured, but ${main} does not export EmDash scheduled() maintenance — replace its Worker export with: ${WORKER_FIX}`,\n\t\t\t},\n\t\t];\n\t}\n\n\tif (hasScheduledHandler && !hasCronTrigger) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tname: \"scheduler trigger\",\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tmessage: `EmDash scheduled() handler is exported, but no Cron Trigger is configured — add this to ${configPath}: ${triggerFix(configPath)}`,\n\t\t\t},\n\t\t];\n\t}\n\n\tif (!hasCronTrigger && !hasScheduledHandler) {\n\t\treturn [];\n\t}\n\n\treturn [\n\t\t{\n\t\t\tname: \"scheduler wiring\",\n\t\t\tstatus: \"pass\",\n\t\t\tmessage: `Cron Trigger and scheduled() handler found (${main})`,\n\t\t},\n\t];\n}\n\nexport async function checkDoctor(cwd: string, dbPath: string): Promise<CheckResult[]> {\n\tconst results = await checkDatabase(dbPath);\n\tconst configPath = await findWranglerConfig(cwd);\n\tif (configPath) results.push(...(await checkSchedulerWiringAtPath(cwd, configPath)));\n\n\treturn results;\n}\n\nfunction printResult(result: CheckResult): void {\n\tconst color =\n\t\tresult.status === \"pass\"\n\t\t\t? consola.success\n\t\t\t: result.status === \"warn\"\n\t\t\t\t? consola.warn\n\t\t\t\t: consola.error;\n\tcolor(`${result.name}: ${result.message}`);\n}\n\nasync function checkDatabase(dbPath: string): Promise<CheckResult[]> {\n\tconst results: CheckResult[] = [];\n\n\t// Check database file exists\n\tif (!(await fileExists(dbPath))) {\n\t\tresults.push({\n\t\t\tname: \"database\",\n\t\t\tstatus: \"fail\",\n\t\t\tmessage: `not found at ${dbPath} — run \"emdash init\"`,\n\t\t});\n\t\treturn results;\n\t}\n\n\tresults.push({\n\t\tname: \"database\",\n\t\tstatus: \"pass\",\n\t\tmessage: dbPath,\n\t});\n\n\t// Connect and check migrations\n\tlet db;\n\ttry {\n\t\tdb = createDatabase({ url: `file:${dbPath}` });\n\n\t\tconst { applied, pending } = await getMigrationStatus(db);\n\t\tif (pending.length === 0) {\n\t\t\tresults.push({\n\t\t\t\tname: \"migrations\",\n\t\t\t\tstatus: \"pass\",\n\t\t\t\tmessage: `${applied.length} applied, none pending`,\n\t\t\t});\n\t\t} else {\n\t\t\tresults.push({\n\t\t\t\tname: \"migrations\",\n\t\t\t\tstatus: \"warn\",\n\t\t\t\tmessage: `${applied.length} applied, ${pending.length} pending — run \"emdash init\"`,\n\t\t\t});\n\t\t}\n\n\t\tconst { sql } = await import(\"kysely\");\n\n\t\t// Check collections exist\n\t\ttry {\n\t\t\tconst collectionsResult = await sql<{\n\t\t\t\tcount: number;\n\t\t\t}>`SELECT COUNT(id) as count FROM _emdash_collections`.execute(db);\n\t\t\tconst count = collectionsResult.rows[0]?.count ?? 0;\n\t\t\tresults.push({\n\t\t\t\tname: \"collections\",\n\t\t\t\tstatus: count > 0 ? \"pass\" : \"warn\",\n\t\t\t\tmessage:\n\t\t\t\t\tcount > 0 ? `${count} collections defined` : \"no collections — seed or create via admin\",\n\t\t\t});\n\t\t} catch {\n\t\t\tresults.push({\n\t\t\t\tname: \"collections\",\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tmessage: \"could not query collections table — migrations may not have run\",\n\t\t\t});\n\t\t}\n\n\t\t// Check for orphaned ec_ tables without matching collection records\n\t\ttry {\n\t\t\tconst tableNames = await listTablesLike(db, \"ec_%\");\n\t\t\tconst collectionsResult = await sql<{\n\t\t\t\tslug: string;\n\t\t\t}>`SELECT slug FROM _emdash_collections`.execute(db);\n\t\t\tconst registeredSlugs = new Set(collectionsResult.rows.map((r) => `ec_${r.slug}`));\n\t\t\tconst orphaned = tableNames.filter((name) => !registeredSlugs.has(name));\n\n\t\t\tif (orphaned.length > 0) {\n\t\t\t\tresults.push({\n\t\t\t\t\tname: \"orphaned tables\",\n\t\t\t\t\tstatus: \"warn\",\n\t\t\t\t\tmessage: `found ${orphaned.length}: ${orphaned.join(\", \")}`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst report = await scanDatetimeStorage(db);\n\t\t\t\tconst clean =\n\t\t\t\t\treport.noncanonicalCount === 0 &&\n\t\t\t\t\treport.manualReviewCount === 0 &&\n\t\t\t\t\treport.inspectionErrorCount === 0;\n\t\t\t\tresults.push({\n\t\t\t\t\tname: \"datetime storage\",\n\t\t\t\t\tstatus: clean ? \"pass\" : \"fail\",\n\t\t\t\t\tmessage: clean\n\t\t\t\t\t\t? `all stored content datetimes are canonical (${report.timezone})`\n\t\t\t\t\t\t: formatDatetimeStorageReport(report),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tresults.push({\n\t\t\t\t\tname: \"datetime storage\",\n\t\t\t\t\tstatus: \"fail\",\n\t\t\t\t\tmessage: `could not inspect stored datetimes: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t} catch {\n\t\t\t// Non-critical — tables may not exist on fresh DB\n\t\t}\n\n\t\t// Check users exist\n\t\ttry {\n\t\t\tconst usersResult = await sql<{\n\t\t\t\tcount: number;\n\t\t\t}>`SELECT COUNT(id) as count FROM users`.execute(db);\n\t\t\tconst count = usersResult.rows[0]?.count ?? 0;\n\t\t\tresults.push({\n\t\t\t\tname: \"users\",\n\t\t\t\tstatus: count > 0 ? \"pass\" : \"warn\",\n\t\t\t\tmessage:\n\t\t\t\t\tcount > 0 ? `${count} users` : \"no users — complete setup wizard at /_emdash/admin\",\n\t\t\t});\n\t\t} catch {\n\t\t\tresults.push({\n\t\t\t\tname: \"users\",\n\t\t\t\tstatus: \"warn\",\n\t\t\t\tmessage: \"could not query users table\",\n\t\t\t});\n\t\t}\n\t} catch (error) {\n\t\tresults.push({\n\t\t\tname: \"database connection\",\n\t\t\tstatus: \"fail\",\n\t\t\tmessage: error instanceof Error ? error.message : \"failed to connect\",\n\t\t});\n\t} finally {\n\t\tif (db) {\n\t\t\tawait db.destroy();\n\t\t}\n\t}\n\n\treturn results;\n}\n\nexport const doctorCommand = defineCommand({\n\tmeta: {\n\t\tname: \"doctor\",\n\t\tdescription: \"Check database health, scheduler wiring, and diagnose issues\",\n\t},\n\targs: {\n\t\tdatabase: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"d\",\n\t\t\tdescription: \"Database path (default: ./data.db)\",\n\t\t\tdefault: \"./data.db\",\n\t\t},\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Working directory\",\n\t\t\tdefault: process.cwd(),\n\t\t},\n\t\tjson: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output results as JSON\",\n\t\t\tdefault: false,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst cwd = resolve(args.cwd);\n\t\tconst dbPath = resolve(cwd, args.database);\n\n\t\tconst results = await checkDoctor(cwd, dbPath);\n\t\tconst fails = results.filter((result) => result.status === \"fail\");\n\n\t\tif (args.json) {\n\t\t\tprocess.stdout.write(JSON.stringify(results, null, 2) + \"\\n\");\n\t\t\tif (fails.length > 0) process.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\n\t\tconsola.start(\"EmDash Doctor\\n\");\n\n\t\tfor (const result of results) {\n\t\t\tprintResult(result);\n\t\t}\n\n\t\t// Summary\n\t\tconst warns = results.filter((r) => r.status === \"warn\");\n\n\t\tconsola.log(\"\");\n\t\tif (fails.length === 0 && warns.length === 0) {\n\t\t\tconsola.success(\"All checks passed\");\n\t\t} else if (fails.length === 0) {\n\t\t\tconsola.info(`All critical checks passed (${warns.length} warnings)`);\n\t\t} else {\n\t\t\tconsola.error(`${fails.length} issues found`);\n\t\t\tprocess.exitCode = 1;\n\t\t}\n\t},\n});\n","/**\n * emdash export-seed\n *\n * Export current database schema (and optionally content) as a seed file\n */\n\nimport { resolve } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport consola from \"consola\";\nimport type { Kysely } from \"kysely\";\nimport { sql } from \"kysely\";\n\nimport { createDatabase } from \"../../database/connection.js\";\nimport { getExactMigrationStatus } from \"../../database/migrations/runner.js\";\nimport { BylineRepository } from \"../../database/repositories/byline.js\";\nimport { ContentRepository } from \"../../database/repositories/content.js\";\nimport { MediaRepository } from \"../../database/repositories/media.js\";\nimport { OptionsRepository } from \"../../database/repositories/options.js\";\nimport {\n\tparseTaxonomyCollections,\n\tselectTaxonomyDefs,\n} from \"../../database/repositories/taxonomy-def.js\";\nimport { TaxonomyRepository } from \"../../database/repositories/taxonomy.js\";\nimport type { ContentItem } from \"../../database/repositories/types.js\";\nimport type { Database } from \"../../database/types.js\";\nimport { validateIdentifier } from \"../../database/validate.js\";\nimport { getI18nConfig, isI18nEnabled } from \"../../i18n/config.js\";\nimport { BlockTypeRegistry } from \"../../schema/block-type-registry.js\";\nimport { SchemaRegistry } from \"../../schema/registry.js\";\nimport type { FieldType } from \"../../schema/types.js\";\nimport type {\n\tSeedFile,\n\tSeedCollection,\n\tSeedField,\n\tSeedTaxonomy,\n\tSeedTaxonomyTerm,\n\tSeedMenu,\n\tSeedMenuItem,\n\tSeedWidgetArea,\n\tSeedWidget,\n\tSeedContentEntry,\n\tSeedByline,\n\tSeedBylineCredit,\n\tSeedBlockType,\n} from \"../../seed/types.js\";\nimport { isMissingTableError } from \"../../utils/db-errors.js\";\nimport { slugify } from \"../../utils/slugify.js\";\n\nconst SETTINGS_PREFIX = \"site:\";\n\nexport const exportSeedCommand = defineCommand({\n\tmeta: {\n\t\tname: \"export-seed\",\n\t\tdescription: \"Export database schema and content as a seed file\",\n\t},\n\targs: {\n\t\tdatabase: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"d\",\n\t\t\tdescription: \"Database path\",\n\t\t\tdefault: \"./data.db\",\n\t\t},\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Working directory\",\n\t\t\tdefault: process.cwd(),\n\t\t},\n\t\t\"with-content\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Include content (all or comma-separated collection names)\",\n\t\t\trequired: false,\n\t\t},\n\t\tpretty: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Pretty print JSON output\",\n\t\t\tdefault: true,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst cwd = resolve(args.cwd);\n\n\t\t// Connect to database\n\t\tconst dbPath = resolve(cwd, args.database);\n\t\t// The seed document is this command's stdout payload, so anything else\n\t\t// written there corrupts `emdash export-seed > seed.json`. Diagnostics\n\t\t// go to stderr, where a redirect leaves them visible.\n\t\tprocess.stderr.write(`Database: ${dbPath}\\n`);\n\n\t\tconst db = createDatabase({ url: `file:${dbPath}`, readOnly: true });\n\n\t\ttry {\n\t\t\tconst { pending, unknownApplied } = await getExactMigrationStatus(db);\n\t\t\tif (unknownApplied.length > 0) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"The database was migrated by a newer EmDash version. Upgrade EmDash before exporting it.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (pending.length > 0) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`The database has ${pending.length} pending migration${pending.length === 1 ? \"\" : \"s\"}. Run \\`emdash migrate\\` before exporting it.`,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Export requires a current database schema:\", error);\n\t\t\tawait db.destroy();\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\ttry {\n\t\t\tconst seed = await exportSeed(db, args[\"with-content\"]);\n\n\t\t\t// Output to stdout\n\t\t\tconst output = args.pretty ? JSON.stringify(seed, null, \"\\t\") : JSON.stringify(seed);\n\n\t\t\tconsole.log(output);\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Export failed:\", error);\n\t\t\tawait db.destroy();\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tawait db.destroy();\n\t},\n});\n\n/**\n * Export database to seed file format\n */\nexport async function exportSeed(db: Kysely<Database>, withContent?: string): Promise<SeedFile> {\n\tconst seed: SeedFile = {\n\t\t$schema: \"https://emdashcms.com/seed.schema.json\",\n\t\tversion: \"1\",\n\t\tmeta: {\n\t\t\tname: \"Exported Seed\",\n\t\t\tdescription: \"Exported from existing EmDash database\",\n\t\t},\n\t};\n\n\t// 1. Export settings\n\tseed.settings = await exportSettings(db);\n\n\t// 2. Export block types before collections that reference them\n\tseed.blockTypes = await exportBlockTypes(db);\n\n\t// 3. Export collections and fields\n\tseed.collections = await exportCollections(db);\n\n\t// Decide locale-awareness from the data. The runtime sets the i18n config via\n\t// middleware, but the CLI never does, so `isI18nEnabled()` is always false\n\t// under `emdash export-seed` (#1330). Detecting multiple locales in the data\n\t// keeps the export locale-aware without the runtime flag.\n\tconst { i18nEnabled, defaultLocale } = await detectLocaleInfo(db, seed.collections);\n\n\t// Self-describe the default locale so a non-`en` single-locale project\n\t// survives the round-trip: `emdash seed` runs outside the runtime and would\n\t// otherwise backfill omitted locales as `en` (#1421).\n\tif (defaultLocale) seed.defaultLocale = defaultLocale;\n\n\t// 3. Export taxonomy definitions and terms\n\tseed.taxonomies = await exportTaxonomies(db, i18nEnabled);\n\n\t// 4. Export menus\n\tseed.menus = await exportMenus(db, i18nEnabled);\n\n\t// 5. Export widget areas\n\tseed.widgetAreas = await exportWidgetAreas(db);\n\n\t// 6. Export byline profiles. The returned map (translation_group -> seed-local\n\t// id) lets content credits below reference the same ids the root list emits.\n\tconst { bylines, groupToSeedId } = await exportBylines(db);\n\tif (bylines.length > 0) {\n\t\tseed.bylines = bylines;\n\t}\n\n\t// 7. Export content (if requested)\n\tif (withContent !== undefined) {\n\t\t// Treat \"all\" as a synonym for the bare flag and \"true\". The args help\n\t\t// text documents `all` as a valid value, but without this the literal\n\t\t// string is read as a collection name and matches no collection (#1329).\n\t\tconst includeAll = withContent === \"\" || withContent === \"true\" || withContent === \"all\";\n\t\tconst collections = includeAll\n\t\t\t? null // all collections\n\t\t\t: withContent\n\t\t\t\t\t.split(\",\")\n\t\t\t\t\t.map((s) => s.trim())\n\t\t\t\t\t.filter(Boolean);\n\n\t\tseed.content = await exportContent(\n\t\t\tdb,\n\t\t\tseed.collections || [],\n\t\t\tcollections,\n\t\t\tgroupToSeedId,\n\t\t\ti18nEnabled,\n\t\t);\n\t}\n\n\treturn seed;\n}\n\n/**\n * Export byline profiles as root-level `bylines[]`.\n *\n * `SeedByline` has no locale axis, so locale siblings of the same byline\n * (sharing a `translation_group`) collapse to a single profile. The returned\n * `groupToSeedId` map keys on `translation_group` — the value stored in\n * `_emdash_content_bylines.byline_id` — so content credits can resolve to the\n * emitted seed id.\n */\nasync function exportBylines(\n\tdb: Kysely<Database>,\n): Promise<{ bylines: SeedByline[]; groupToSeedId: Map<string, string> }> {\n\tconst bylineRepo = new BylineRepository(db);\n\tconst bylines: SeedByline[] = [];\n\tconst groupToSeedId = new Map<string, string>();\n\tconst usedSeedIds = new Set<string>();\n\n\tlet cursor: string | undefined;\n\tdo {\n\t\tconst result = await bylineRepo.findMany({ limit: 100, cursor });\n\t\tfor (const byline of result.items) {\n\t\t\tconst group = byline.translationGroup ?? byline.id;\n\t\t\t// One seed entry per translation group; first row seen wins.\n\t\t\tif (groupToSeedId.has(group)) continue;\n\n\t\t\tlet seedId = `byline:${byline.slug}`;\n\t\t\t// Disambiguate the rare case of two distinct groups sharing a slug\n\t\t\t// (slug is unique per-locale, not globally) so seed ids stay unique.\n\t\t\tif (usedSeedIds.has(seedId)) seedId = `byline:${byline.slug}:${group}`;\n\t\t\tusedSeedIds.add(seedId);\n\t\t\tgroupToSeedId.set(group, seedId);\n\n\t\t\tbylines.push({\n\t\t\t\tid: seedId,\n\t\t\t\tslug: byline.slug,\n\t\t\t\tdisplayName: byline.displayName,\n\t\t\t\tbio: byline.bio || undefined,\n\t\t\t\twebsiteUrl: byline.websiteUrl || undefined,\n\t\t\t\tisGuest: byline.isGuest || undefined,\n\t\t\t});\n\t\t}\n\t\tcursor = result.nextCursor;\n\t} while (cursor);\n\n\treturn { bylines, groupToSeedId };\n}\n\n/**\n * Determine locale-awareness and the data's default locale for the export.\n *\n * The runtime initializes the i18n config in middleware, but the CLI never does,\n * so `isI18nEnabled()` is always false under `emdash export-seed` (#1330). When\n * the flag is unset, fall back to the data: a project is multi-locale when its\n * i18n-aware tables hold rows in more than one distinct locale. `locale` is\n * NOT NULL (defaulting to the site's default locale), so a per-row presence\n * check is not enough — only the *count* of distinct locales distinguishes a\n * genuinely single-locale project from a multi-locale one. This keeps\n * single-locale exports on bare ids and gives multi-locale exports the\n * per-locale suffix they need to avoid duplicate seed ids.\n *\n * `defaultLocale` self-describes the single-locale case so a non-`en` default\n * survives the round-trip (#1421). When more than one locale is present every\n * row already carries its own `locale`, so no fallback is needed and we leave it\n * undefined rather than guess which locale is the \"default\" without the runtime\n * config.\n */\nasync function detectLocaleInfo(\n\tdb: Kysely<Database>,\n\tcollections: SeedCollection[],\n): Promise<{ i18nEnabled: boolean; defaultLocale: string | undefined }> {\n\tconst config = getI18nConfig();\n\tif (isI18nEnabled() && config) {\n\t\treturn { i18nEnabled: true, defaultLocale: config.defaultLocale };\n\t}\n\n\tconst locales = new Set<string>();\n\tconst collectDistinctLocales = async (tableRef: ReturnType<typeof sql.ref>): Promise<void> => {\n\t\tconst result = await sql<{ locale: string | null }>`\n\t\t\tSELECT DISTINCT locale FROM ${tableRef}\n\t\t`.execute(db);\n\t\tfor (const row of result.rows) {\n\t\t\tif (row.locale) locales.add(row.locale);\n\t\t}\n\t};\n\n\tawait collectDistinctLocales(sql.ref(\"_emdash_taxonomy_defs\"));\n\tawait collectDistinctLocales(sql.ref(\"_emdash_menus\"));\n\n\tfor (const collection of collections) {\n\t\tvalidateIdentifier(collection.slug, \"collection slug\");\n\t\t// On D1, deleteCollection is non-atomic, so a collection row can outlive\n\t\t// its ec_* table. Skip missing tables rather than crashing the export.\n\t\ttry {\n\t\t\tawait collectDistinctLocales(sql.ref(`ec_${collection.slug}`));\n\t\t} catch (error) {\n\t\t\tif (!isMissingTableError(error)) throw error;\n\t\t}\n\t}\n\n\treturn {\n\t\ti18nEnabled: locales.size > 1,\n\t\tdefaultLocale: locales.size === 1 ? [...locales][0] : undefined,\n\t};\n}\n\n/**\n * Export site settings\n */\nasync function exportSettings(db: Kysely<Database>): Promise<SeedFile[\"settings\"]> {\n\tconst options = new OptionsRepository(db);\n\tconst allOptions = await options.getByPrefix(SETTINGS_PREFIX);\n\n\tconst settings: Record<string, unknown> = {};\n\tfor (const [key, value] of allOptions) {\n\t\tconst settingKey = key.replace(SETTINGS_PREFIX, \"\");\n\t\tsettings[settingKey] = value;\n\t}\n\n\treturn Object.keys(settings).length > 0 ? settings : undefined;\n}\n\nasync function exportBlockTypes(db: Kysely<Database>): Promise<SeedBlockType[]> {\n\tconst blockTypes = await new BlockTypeRegistry(db).listBlockTypes();\n\treturn blockTypes.map((blockType) => ({\n\t\tslug: blockType.slug,\n\t\tlabel: blockType.label,\n\t\tdescription: blockType.description,\n\t\ticon: blockType.icon,\n\t\tcategory: blockType.category,\n\t\tcurrentVersion: blockType.currentVersion,\n\t\tversions: blockType.versions.map((version) => ({\n\t\t\tversion: version.version,\n\t\t\tfields: version.fields,\n\t\t})),\n\t}));\n}\n\n/**\n * Export collections and their fields\n */\nasync function exportCollections(db: Kysely<Database>): Promise<SeedCollection[]> {\n\tconst registry = new SchemaRegistry(db);\n\tconst collections = await registry.listCollections();\n\tconst result: SeedCollection[] = [];\n\n\tfor (const collection of collections) {\n\t\tconst fields = await registry.listFields(collection.id);\n\n\t\tconst seedCollection: SeedCollection = {\n\t\t\tslug: collection.slug,\n\t\t\tlabel: collection.label,\n\t\t\tlabelSingular: collection.labelSingular || undefined,\n\t\t\tdescription: collection.description || undefined,\n\t\t\ticon: collection.icon || undefined,\n\t\t\tadmin: collection.admin,\n\t\t\tsupports: collection.supports.length > 0 ? collection.supports : undefined,\n\t\t\turlPattern: collection.urlPattern || undefined,\n\t\t\troutable: collection.routable === false ? false : undefined,\n\t\t\teditLocking: collection.editLocking === false ? false : undefined,\n\t\t\thidden: collection.hidden || undefined,\n\t\t\tsortOrder: collection.sortOrder,\n\t\t\tgroup: collection.group,\n\t\t\tfields: fields.map(\n\t\t\t\t(field): SeedField => ({\n\t\t\t\t\tslug: field.slug,\n\t\t\t\t\tlabel: field.label,\n\t\t\t\t\ttype: field.type,\n\t\t\t\t\trequired: field.required || undefined,\n\t\t\t\t\tunique: field.unique || undefined,\n\t\t\t\t\tsearchable: field.searchable || undefined,\n\t\t\t\t\tindexed: field.indexed || undefined,\n\t\t\t\t\tdefaultValue: field.defaultValue,\n\t\t\t\t\tvalidation: field.validation ? { ...field.validation } : undefined,\n\t\t\t\t\twidget: field.widget || undefined,\n\t\t\t\t\toptions: field.options || undefined,\n\t\t\t\t}),\n\t\t\t),\n\t\t};\n\n\t\tresult.push(seedCollection);\n\t}\n\n\treturn result;\n}\n\n/**\n * Export taxonomy definitions and terms\n */\nasync function exportTaxonomies(\n\tdb: Kysely<Database>,\n\ti18nEnabled: boolean,\n): Promise<SeedTaxonomy[]> {\n\t// Mirrors the content export pattern: one entry per (name, locale), stable\n\t// seed-local id, translations linked via `translationOf` to the anchor's id.\n\tconst defs = await selectTaxonomyDefs(db)\n\t\t// Chained, not `orderBy([\"name\", \"locale\"])`: kysely deprecated the array\n\t\t// form and announces it with `console.log`, which lands in the seed\n\t\t// document this command writes to stdout.\n\t\t.orderBy(\"d.name\")\n\t\t.orderBy(\"d.locale\")\n\t\t.execute();\n\n\tconst result: SeedTaxonomy[] = [];\n\tconst termRepo = new TaxonomyRepository(db);\n\n\t// Taxonomy name -> seed-local id of the first def emitted for it. Every locale\n\t// of a name is one taxonomy, whatever translation_group its rows carry.\n\tconst anchorByName = new Map<string, string>();\n\n\tfor (const def of defs) {\n\t\tconst defSeedId =\n\t\t\ti18nEnabled && def.locale ? `tax:${def.name}:${def.locale}` : `tax:${def.name}`;\n\n\t\t// Terms in this def's locale.\n\t\tconst terms = await termRepo.findByName(def.name, { locale: def.locale });\n\n\t\t// translation_group -> slug for parent resolution within this locale.\n\t\t// `parentId` stores the parent's translation_group, not a row id.\n\t\tconst groupToSlug = new Map<string, string>();\n\t\tfor (const term of terms) groupToSlug.set(term.translationGroup ?? term.id, term.slug);\n\n\t\t// translation_group -> seed id of the anchor term.\n\t\tconst termGroupToSeedId = new Map<string, string>();\n\n\t\tconst seedTerms: SeedTaxonomyTerm[] = [];\n\t\tfor (const term of terms) {\n\t\t\tconst termSeedId =\n\t\t\t\ti18nEnabled && term.locale\n\t\t\t\t\t? `term:${def.name}:${term.slug}:${term.locale}`\n\t\t\t\t\t: `term:${def.name}:${term.slug}`;\n\n\t\t\tconst seedTerm: SeedTaxonomyTerm = {\n\t\t\t\tid: termSeedId,\n\t\t\t\tslug: term.slug,\n\t\t\t\tlabel: term.label,\n\t\t\t\tdescription: typeof term.data?.description === \"string\" ? term.data.description : undefined,\n\t\t\t};\n\n\t\t\tif (term.parentId) seedTerm.parent = groupToSlug.get(term.parentId);\n\n\t\t\tif (i18nEnabled && term.locale) {\n\t\t\t\tseedTerm.locale = term.locale;\n\t\t\t\tif (term.translationGroup) {\n\t\t\t\t\tconst anchor = termGroupToSeedId.get(term.translationGroup);\n\t\t\t\t\tif (anchor) seedTerm.translationOf = anchor;\n\t\t\t\t\telse termGroupToSeedId.set(term.translationGroup, termSeedId);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tseedTerms.push(seedTerm);\n\t\t}\n\n\t\t// Anchors first so import can resolve `translationOf`.\n\t\tseedTerms.sort((a, b) => Number(!!a.translationOf) - Number(!!b.translationOf));\n\n\t\tconst taxonomy: SeedTaxonomy = {\n\t\t\tid: defSeedId,\n\t\t\tname: def.name,\n\t\t\tlabel: def.label,\n\t\t\tlabelSingular: def.label_singular || undefined,\n\t\t};\n\n\t\tif (i18nEnabled && def.locale) {\n\t\t\ttaxonomy.locale = def.locale;\n\t\t\tconst anchor = anchorByName.get(def.name);\n\t\t\tif (anchor) taxonomy.translationOf = anchor;\n\t\t\telse anchorByName.set(def.name, defSeedId);\n\t\t}\n\n\t\t// The structure is the taxonomy's, so only the entry translations point at carries it.\n\t\tif (!taxonomy.translationOf) {\n\t\t\ttaxonomy.hierarchical = def.hierarchical === 1;\n\t\t\ttaxonomy.collections = parseTaxonomyCollections(def.collections);\n\t\t}\n\n\t\tif (seedTerms.length > 0) taxonomy.terms = seedTerms;\n\n\t\tresult.push(taxonomy);\n\t}\n\n\t// Anchors first at def level too.\n\tresult.sort((a, b) => Number(!!a.translationOf) - Number(!!b.translationOf));\n\n\treturn result;\n}\n\n/**\n * Export menus with their items\n */\nasync function exportMenus(db: Kysely<Database>, i18nEnabled: boolean): Promise<SeedMenu[]> {\n\tconst menus = await db\n\t\t.selectFrom(\"_emdash_menus\")\n\t\t.selectAll()\n\t\t// Chained, not `orderBy([\"name\", \"locale\"])`: kysely deprecated the array\n\t\t// form and announces it with `console.log`, which lands in the seed\n\t\t// document this command writes to stdout.\n\t\t.orderBy(\"name\")\n\t\t.orderBy(\"locale\")\n\t\t.execute();\n\n\tconst result: SeedMenu[] = [];\n\t// translation_group -> seed-local id of the anchor menu in that group.\n\tconst groupToSeedId = new Map<string, string>();\n\t// Shared across menus: translated items reference anchor items in sibling menus.\n\tconst itemGroupToSeedId = new Map<string, string>();\n\tconst usedItemSeedIds = new Set<string>();\n\n\tfor (const menu of menus) {\n\t\tconst seedId =\n\t\t\ti18nEnabled && menu.locale ? `menu:${menu.name}:${menu.locale}` : `menu:${menu.name}`;\n\n\t\tconst items = await db\n\t\t\t.selectFrom(\"_emdash_menu_items\")\n\t\t\t.selectAll()\n\t\t\t.where(\"menu_id\", \"=\", menu.id)\n\t\t\t.orderBy(\"sort_order\", \"asc\")\n\t\t\t.execute();\n\n\t\tconst seedItems = buildMenuItemTree(items, {\n\t\t\ti18nEnabled,\n\t\t\tmenuName: menu.name,\n\t\t\tmenuLocale: menu.locale ?? null,\n\t\t\titemGroupToSeedId,\n\t\t\tusedItemSeedIds,\n\t\t});\n\n\t\tconst seedMenu: SeedMenu = {\n\t\t\tid: seedId,\n\t\t\tname: menu.name,\n\t\t\tlabel: menu.label,\n\t\t\titems: seedItems,\n\t\t};\n\n\t\tif (i18nEnabled && menu.locale) {\n\t\t\tseedMenu.locale = menu.locale;\n\t\t\tif (menu.translation_group) {\n\t\t\t\tconst anchor = groupToSeedId.get(menu.translation_group);\n\t\t\t\tif (anchor) seedMenu.translationOf = anchor;\n\t\t\t\telse groupToSeedId.set(menu.translation_group, seedId);\n\t\t\t}\n\t\t}\n\n\t\tresult.push(seedMenu);\n\t}\n\n\t// Anchors first so import can resolve `translationOf`.\n\tresult.sort((a, b) => Number(!!a.translationOf) - Number(!!b.translationOf));\n\n\treturn result;\n}\n\n/** Type guard for valid widget types */\nfunction isWidgetType(t: string): t is SeedWidget[\"type\"] {\n\treturn t === \"content\" || t === \"menu\" || t === \"component\";\n}\n\n/**\n * Build hierarchical menu item tree from flat array\n */\nfunction buildMenuItemTree(\n\titems: Array<{\n\t\tid: string;\n\t\tparent_id: string | null;\n\t\ttype: string;\n\t\tlabel: string;\n\t\tcustom_url: string | null;\n\t\treference_collection: string | null;\n\t\treference_id: string | null;\n\t\ttarget: string | null;\n\t\ttitle_attr: string | null;\n\t\tcss_classes: string | null;\n\t\tlocale?: string | null;\n\t\ttranslation_group?: string | null;\n\t}>,\n\ti18nCtx: {\n\t\ti18nEnabled: boolean;\n\t\tmenuName: string;\n\t\tmenuLocale: string | null;\n\t\t// translation_group -> seed-local id of the anchor item in that group.\n\t\titemGroupToSeedId: Map<string, string>;\n\t\tusedItemSeedIds: Set<string>;\n\t},\n): SeedMenuItem[] {\n\t// Build parent -> children map\n\tconst childMap = new Map<string | null, typeof items>();\n\n\tfor (const item of items) {\n\t\tconst parentId = item.parent_id;\n\t\tif (!childMap.has(parentId)) {\n\t\t\tchildMap.set(parentId, []);\n\t\t}\n\t\tchildMap.get(parentId)!.push(item);\n\t}\n\n\tfunction makeSeedId(item: (typeof items)[number]): string {\n\t\tconst base = slugify(item.label || \"\") || item.id;\n\t\tconst locale = i18nCtx.i18nEnabled ? (item.locale ?? i18nCtx.menuLocale) : null;\n\t\tconst candidate = locale\n\t\t\t? `item:${i18nCtx.menuName}:${base}:${locale}`\n\t\t\t: `item:${i18nCtx.menuName}:${base}`;\n\t\tif (!i18nCtx.usedItemSeedIds.has(candidate)) {\n\t\t\ti18nCtx.usedItemSeedIds.add(candidate);\n\t\t\treturn candidate;\n\t\t}\n\t\t// Collision fallback: append DB id to disambiguate duplicate labels.\n\t\tconst fallback = locale\n\t\t\t? `item:${i18nCtx.menuName}:${base}:${item.id}:${locale}`\n\t\t\t: `item:${i18nCtx.menuName}:${base}:${item.id}`;\n\t\ti18nCtx.usedItemSeedIds.add(fallback);\n\t\treturn fallback;\n\t}\n\n\t// Recursively build tree\n\tfunction buildLevel(parentId: string | null): SeedMenuItem[] {\n\t\tconst children = childMap.get(parentId) || [];\n\t\tconst result = children.map((item) => {\n\t\t\tconst seedItem: SeedMenuItem = {\n\t\t\t\ttype: item.type,\n\t\t\t\tlabel: item.label || undefined,\n\t\t\t};\n\n\t\t\tif (item.type === \"custom\") {\n\t\t\t\tseedItem.url = item.custom_url || undefined;\n\t\t\t} else {\n\t\t\t\tseedItem.ref = item.reference_id || undefined;\n\t\t\t\tseedItem.collection = item.reference_collection || undefined;\n\t\t\t}\n\n\t\t\tif (item.target === \"_blank\") {\n\t\t\t\tseedItem.target = \"_blank\";\n\t\t\t}\n\t\t\tif (item.title_attr) {\n\t\t\t\tseedItem.titleAttr = item.title_attr;\n\t\t\t}\n\t\t\tif (item.css_classes) {\n\t\t\t\tseedItem.cssClasses = item.css_classes;\n\t\t\t}\n\n\t\t\tif (i18nCtx.i18nEnabled) {\n\t\t\t\tconst itemLocale = item.locale ?? i18nCtx.menuLocale;\n\t\t\t\tconst seedId = makeSeedId(item);\n\t\t\t\tseedItem.id = seedId;\n\t\t\t\tif (itemLocale) seedItem.locale = itemLocale;\n\t\t\t\tif (item.translation_group) {\n\t\t\t\t\tconst anchor = i18nCtx.itemGroupToSeedId.get(item.translation_group);\n\t\t\t\t\tif (anchor && anchor !== seedId) seedItem.translationOf = anchor;\n\t\t\t\t\telse if (!anchor) i18nCtx.itemGroupToSeedId.set(item.translation_group, seedId);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add children\n\t\t\tconst itemChildren = buildLevel(item.id);\n\t\t\tif (itemChildren.length > 0) {\n\t\t\t\tseedItem.children = itemChildren;\n\t\t\t}\n\n\t\t\treturn seedItem;\n\t\t});\n\n\t\t// Sibling order is preserved (maps to sort_order on import). Cross-menu\n\t\t// `translationOf` already resolves because exportMenus sorts anchors first.\n\t\treturn result;\n\t}\n\n\treturn buildLevel(null);\n}\n\n/**\n * Export widget areas with their widgets\n */\nasync function exportWidgetAreas(db: Kysely<Database>): Promise<SeedWidgetArea[]> {\n\t// Get all widget areas\n\tconst areas = await db.selectFrom(\"_emdash_widget_areas\").selectAll().execute();\n\n\tconst result: SeedWidgetArea[] = [];\n\n\tfor (const area of areas) {\n\t\t// Get widgets for this area\n\t\tconst widgets = await db\n\t\t\t.selectFrom(\"_emdash_widgets\")\n\t\t\t.selectAll()\n\t\t\t.where(\"area_id\", \"=\", area.id)\n\t\t\t.orderBy(\"sort_order\", \"asc\")\n\t\t\t.execute();\n\n\t\tconst seedWidgets: SeedWidget[] = widgets\n\t\t\t.filter((w) => isWidgetType(w.type))\n\t\t\t.map((widget) => {\n\t\t\t\tconst wType: SeedWidget[\"type\"] = isWidgetType(widget.type) ? widget.type : \"content\";\n\t\t\t\tconst seedWidget: SeedWidget = {\n\t\t\t\t\ttype: wType,\n\t\t\t\t};\n\n\t\t\t\tif (widget.title) {\n\t\t\t\t\tseedWidget.title = widget.title;\n\t\t\t\t}\n\n\t\t\t\tif (widget.type === \"content\" && widget.content) {\n\t\t\t\t\tseedWidget.content = JSON.parse(widget.content);\n\t\t\t\t} else if (widget.type === \"menu\" && widget.menu_name) {\n\t\t\t\t\tseedWidget.menuName = widget.menu_name;\n\t\t\t\t} else if (widget.type === \"component\") {\n\t\t\t\t\tif (widget.component_id) {\n\t\t\t\t\t\tseedWidget.componentId = widget.component_id;\n\t\t\t\t\t}\n\t\t\t\t\tif (widget.component_props) {\n\t\t\t\t\t\tseedWidget.props = JSON.parse(widget.component_props);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn seedWidget;\n\t\t\t});\n\n\t\tresult.push({\n\t\t\tname: area.name,\n\t\t\tlabel: area.label,\n\t\t\tdescription: area.description || undefined,\n\t\t\twidgets: seedWidgets,\n\t\t});\n\t}\n\n\treturn result;\n}\n\n/** An entry read for export, paired with the seed id it will be written under. */\ninterface CollectedEntry {\n\titem: ContentItem;\n\tseedId: string;\n}\n\n/** A reference field holds a single entry id or an array of them. */\nfunction referenceValues(value: unknown): string[] {\n\tif (typeof value === \"string\") return [value];\n\tif (Array.isArray(value)) return value.filter((v): v is string => typeof v === \"string\");\n\treturn [];\n}\n\n/**\n * For each exported collection, the other exported collections its entries\n * point into. Read from the values rather than a field's declared target so a\n * `reference` field without `options.collection` is still accounted for.\n */\nfunction referenceTargets(\n\tcollected: Map<string, CollectedEntry[]>,\n\tcollectionsBySlug: Map<string, SeedCollection>,\n\tentryIdToCollection: Map<string, string>,\n): Map<string, Set<string>> {\n\tconst targets = new Map<string, Set<string>>();\n\n\tfor (const [slug, items] of collected) {\n\t\tconst referenceFields = (collectionsBySlug.get(slug)?.fields ?? [])\n\t\t\t.filter((field) => field.type === \"reference\")\n\t\t\t.map((field) => field.slug);\n\t\tif (referenceFields.length === 0) continue;\n\n\t\tconst found = new Set<string>();\n\t\tfor (const { item } of items) {\n\t\t\tfor (const fieldSlug of referenceFields) {\n\t\t\t\tfor (const value of referenceValues(item.data[fieldSlug])) {\n\t\t\t\t\tconst target = entryIdToCollection.get(value);\n\t\t\t\t\tif (target && target !== slug) found.add(target);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (found.size > 0) targets.set(slug, found);\n\t}\n\n\treturn targets;\n}\n\n/**\n * Order collections so a reference's target is written before the entry that\n * points at it. `applySeed` fills its seed-id map as it walks the file, so a\n * `$ref` into a collection further down resolves to nothing and is stored\n * verbatim.\n *\n * Depth-first, with the caller's order as the tie-break so an export without\n * references keeps the collection order it had. A cycle has no valid order;\n * the collections on it stay where they were rather than failing the export.\n */\nfunction orderByReferenceTargets(slugs: string[], targets: Map<string, Set<string>>): string[] {\n\tconst exported = new Set(slugs);\n\tconst ordered: string[] = [];\n\tconst placed = new Set<string>();\n\tconst visiting = new Set<string>();\n\n\tconst visit = (slug: string): void => {\n\t\tif (placed.has(slug) || visiting.has(slug)) return;\n\t\tvisiting.add(slug);\n\t\tfor (const target of targets.get(slug) ?? []) {\n\t\t\tif (exported.has(target)) visit(target);\n\t\t}\n\t\tvisiting.delete(slug);\n\t\tplaced.add(slug);\n\t\tordered.push(slug);\n\t};\n\n\tfor (const slug of slugs) visit(slug);\n\treturn ordered;\n}\n\n/**\n * Export content from collections\n */\nasync function exportContent(\n\tdb: Kysely<Database>,\n\tcollections: SeedCollection[],\n\tincludeCollections: string[] | null,\n\tbylineGroupToSeedId: Map<string, string>,\n\ti18nEnabled: boolean,\n): Promise<Record<string, SeedContentEntry[]>> {\n\tconst content: Record<string, SeedContentEntry[]> = {};\n\tconst contentRepo = new ContentRepository(db);\n\tconst taxonomyRepo = new TaxonomyRepository(db);\n\tconst mediaRepo = new MediaRepository(db);\n\n\t// Build media id -> info map for $media conversion\n\tconst mediaMap = new Map<\n\t\tstring,\n\t\t{ url: string; filename: string; alt?: string; caption?: string }\n\t>();\n\ttry {\n\t\tlet cursor: string | undefined;\n\t\tdo {\n\t\t\tconst result = await mediaRepo.findMany({\n\t\t\t\tlimit: 100,\n\t\t\t\tcursor,\n\t\t\t\tstatus: \"all\",\n\t\t\t});\n\t\t\tfor (const media of result.items) {\n\t\t\t\tmediaMap.set(media.id, {\n\t\t\t\t\turl: `/_emdash/api/media/file/${media.storageKey}`,\n\t\t\t\t\tfilename: media.filename,\n\t\t\t\t\talt: media.alt || undefined,\n\t\t\t\t\tcaption: media.caption || undefined,\n\t\t\t\t});\n\t\t\t}\n\t\t\tcursor = result.nextCursor;\n\t\t} while (cursor);\n\t} catch {\n\t\t// Media table might not exist or be empty\n\t}\n\n\t// Read every entry and assign its seed id before processing any data. A\n\t// `reference` value holds a row id whose target can sit in a collection this\n\t// loop has not reached yet, so the row id -> seed id map has to be complete\n\t// before the first conversion.\n\tconst collected = new Map<string, CollectedEntry[]>();\n\tconst entryIdToSeedId = new Map<string, string>();\n\tconst entryIdToCollection = new Map<string, string>();\n\n\tfor (const collection of collections) {\n\t\t// Skip if not in include list\n\t\tif (includeCollections && !includeCollections.includes(collection.slug)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst items: CollectedEntry[] = [];\n\t\tlet cursor: string | undefined;\n\n\t\t// Paginate through all entries\n\t\tdo {\n\t\t\tconst result = await contentRepo.findMany(collection.slug, {\n\t\t\t\tlimit: 100,\n\t\t\t\tcursor,\n\t\t\t});\n\n\t\t\tfor (const item of result.items) {\n\t\t\t\t// Generate seed ID from collection:slug:locale for stable references\n\t\t\t\tconst seedId = item.slug\n\t\t\t\t\t? i18nEnabled && item.locale\n\t\t\t\t\t\t? `${collection.slug}:${item.slug}:${item.locale}`\n\t\t\t\t\t\t: `${collection.slug}:${item.slug}`\n\t\t\t\t\t: item.id;\n\n\t\t\t\titems.push({ item, seedId });\n\t\t\t\tentryIdToSeedId.set(item.id, seedId);\n\t\t\t\tentryIdToCollection.set(item.id, collection.slug);\n\t\t\t}\n\n\t\t\tcursor = result.nextCursor;\n\t\t} while (cursor);\n\n\t\tcollected.set(collection.slug, items);\n\t}\n\n\tconst collectionsBySlug = new Map(collections.map((c) => [c.slug, c]));\n\tconst orderedSlugs = orderByReferenceTargets(\n\t\t[...collected.keys()],\n\t\treferenceTargets(collected, collectionsBySlug, entryIdToCollection),\n\t);\n\n\tfor (const slug of orderedSlugs) {\n\t\tconst collection = collectionsBySlug.get(slug);\n\t\tconst items = collected.get(slug);\n\t\tif (!collection || !items) continue;\n\n\t\tconst entries: SeedContentEntry[] = [];\n\n\t\t// When i18n is enabled, track translation_group -> seed ID so that\n\t\t// translations can reference the source entry's seed-local ID.\n\t\t// Key: EmDash translation_group ULID, Value: seed-local ID of the first entry in that group\n\t\tconst translationGroupToSeedId = new Map<string, string>();\n\n\t\tfor (const { item, seedId } of items) {\n\t\t\t// Process data fields for $media and $ref conversion\n\t\t\tconst processedData = processDataForExport(\n\t\t\t\titem.data,\n\t\t\t\tcollection.fields,\n\t\t\t\tmediaMap,\n\t\t\t\tentryIdToSeedId,\n\t\t\t);\n\n\t\t\tconst entry: SeedContentEntry = {\n\t\t\t\tid: seedId,\n\t\t\t\tslug: item.slug?.trim() ? item.slug : collection.routable === false ? undefined : item.id,\n\t\t\t\tstatus: item.status === \"published\" || item.status === \"draft\" ? item.status : undefined,\n\t\t\t\tdata: processedData,\n\t\t\t};\n\n\t\t\t// Add i18n fields when enabled\n\t\t\tif (i18nEnabled && item.locale) {\n\t\t\t\tentry.locale = item.locale;\n\n\t\t\t\tif (item.translationGroup) {\n\t\t\t\t\tconst sourceSeedId = translationGroupToSeedId.get(item.translationGroup);\n\t\t\t\t\tif (sourceSeedId) {\n\t\t\t\t\t\t// This is a translation — reference the source entry\n\t\t\t\t\t\tentry.translationOf = sourceSeedId;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// First entry in this translation group — track it\n\t\t\t\t\t\ttranslationGroupToSeedId.set(item.translationGroup, seedId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Get taxonomy assignments\n\t\t\tconst taxonomies = await getTaxonomyAssignments(taxonomyRepo, collection.slug, item.id);\n\t\t\tif (Object.keys(taxonomies).length > 0) {\n\t\t\t\tentry.taxonomies = taxonomies;\n\t\t\t}\n\n\t\t\t// Get byline credits. Read the junction directly: its `byline_id`\n\t\t\t// stores the translation_group, which is exactly the key in\n\t\t\t// `bylineGroupToSeedId`. This is locale-agnostic (one row per\n\t\t\t// credit) and avoids the locale-sibling fan-out a hydrated read\n\t\t\t// would produce.\n\t\t\tconst bylines = await getBylineCredits(db, collection.slug, item.id, bylineGroupToSeedId);\n\t\t\tif (bylines.length > 0) {\n\t\t\t\tentry.bylines = bylines;\n\t\t\t}\n\n\t\t\tentries.push(entry);\n\t\t}\n\n\t\tif (i18nEnabled && entries.length > 0) {\n\t\t\t// Sort entries so source locale entries appear before their translations.\n\t\t\t// Entries without translationOf come first; entries with translationOf come after.\n\t\t\tentries.sort((a, b) => {\n\t\t\t\tif (a.translationOf && !b.translationOf) return 1;\n\t\t\t\tif (!a.translationOf && b.translationOf) return -1;\n\t\t\t\treturn 0;\n\t\t\t});\n\t\t}\n\n\t\tif (entries.length > 0) {\n\t\t\tcontent[collection.slug] = entries;\n\t\t}\n\t}\n\n\treturn content;\n}\n\n/**\n * Process content data for export, converting image fields to $media syntax\n */\nfunction processDataForExport(\n\tdata: Record<string, unknown>,\n\tfields: SeedField[],\n\tmediaMap: Map<string, { url: string; filename: string; alt?: string; caption?: string }>,\n\tentryIdToSeedId: Map<string, string>,\n): Record<string, unknown> {\n\tconst result: Record<string, unknown> = {};\n\n\t// Create field type lookup\n\tconst fieldTypes = new Map<string, FieldType>();\n\tfor (const field of fields) {\n\t\tfieldTypes.set(field.slug, field.type);\n\t}\n\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tconst fieldType = fieldTypes.get(key);\n\n\t\tif (fieldType === \"image\" && value && typeof value === \"object\") {\n\t\t\t// Convert image field to $media syntax\n\t\t\tconst imageValue = value as { id?: string; src?: string; alt?: string };\n\t\t\tif (imageValue.id) {\n\t\t\t\tconst mediaInfo = mediaMap.get(imageValue.id);\n\t\t\t\tif (mediaInfo) {\n\t\t\t\t\tresult[key] = {\n\t\t\t\t\t\t$media: {\n\t\t\t\t\t\t\turl: mediaInfo.url,\n\t\t\t\t\t\t\tfilename: mediaInfo.filename,\n\t\t\t\t\t\t\talt: imageValue.alt || mediaInfo.alt,\n\t\t\t\t\t\t\tcaption: mediaInfo.caption,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Fallback: keep as-is if no media info found\n\t\t\tresult[key] = value;\n\t\t} else if (fieldType === \"reference\" && typeof value === \"string\") {\n\t\t\t// Convert reference to $ref syntax, naming the target by the seed id\n\t\t\t// this export assigns it. The stored value is a row id, and `seed`\n\t\t\t// renumbers rows on insert, so a row id matches nothing in the\n\t\t\t// restored database and gets written to the column verbatim.\n\t\t\tresult[key] = `$ref:${entryIdToSeedId.get(value) ?? value}`;\n\t\t} else if (Array.isArray(value)) {\n\t\t\t// Process arrays (could contain references or images)\n\t\t\tresult[key] = value.map((item) => {\n\t\t\t\tif (typeof item === \"string\" && fieldType === \"reference\") {\n\t\t\t\t\treturn `$ref:${entryIdToSeedId.get(item) ?? item}`;\n\t\t\t\t}\n\t\t\t\treturn item;\n\t\t\t});\n\t\t} else {\n\t\t\tresult[key] = value;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Get ordered byline credits for a content entry as `SeedBylineCredit[]`.\n *\n * The `_emdash_content_bylines.byline_id` column stores the credited byline's\n * `translation_group`, so it maps straight through `groupToSeedId`. Credits\n * whose group wasn't emitted in the root `bylines[]` are skipped (defensive;\n * shouldn't happen for a consistent DB).\n */\nasync function getBylineCredits(\n\tdb: Kysely<Database>,\n\tcollection: string,\n\tentryId: string,\n\tgroupToSeedId: Map<string, string>,\n): Promise<SeedBylineCredit[]> {\n\tconst rows = await db\n\t\t.selectFrom(\"_emdash_content_bylines\")\n\t\t.select([\"byline_id\", \"role_label\"])\n\t\t.where(\"collection_slug\", \"=\", collection)\n\t\t.where(\"content_id\", \"=\", entryId)\n\t\t.orderBy(\"sort_order\", \"asc\")\n\t\t.execute();\n\n\tconst credits: SeedBylineCredit[] = [];\n\tfor (const row of rows) {\n\t\tconst seedId = groupToSeedId.get(row.byline_id);\n\t\tif (!seedId) continue;\n\t\tconst credit: SeedBylineCredit = { byline: seedId };\n\t\tif (row.role_label) credit.roleLabel = row.role_label;\n\t\tcredits.push(credit);\n\t}\n\n\treturn credits;\n}\n\n/**\n * Get taxonomy term assignments for a content entry\n */\nasync function getTaxonomyAssignments(\n\ttaxonomyRepo: TaxonomyRepository,\n\tcollection: string,\n\tentryId: string,\n): Promise<Record<string, string[]>> {\n\tconst terms = await taxonomyRepo.getTermsForEntry(collection, entryId);\n\tconst result: Record<string, string[]> = {};\n\n\tfor (const term of terms) {\n\t\tif (!result[term.name]) {\n\t\t\tresult[term.name] = [];\n\t\t}\n\t\tresult[term.name].push(term.slug);\n\t}\n\n\treturn result;\n}\n","/**\n * emdash init\n *\n * Initialize database from template config in package.json\n */\n\nimport { readFile, access } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport consola from \"consola\";\nimport { sql } from \"kysely\";\n\nimport { createDatabase } from \"../../database/connection.js\";\nimport { runMigrations } from \"../../database/migrations/runner.js\";\n\nexport interface EmDashConfig {\n\tlabel?: string;\n\tschema?: string;\n\tseed?: string;\n}\n\ninterface PackageJson {\n\tname?: string;\n\temdash?: EmDashConfig;\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function readPackageJson(cwd: string): Promise<PackageJson | null> {\n\tconst pkgPath = resolve(cwd, \"package.json\");\n\ttry {\n\t\tconst content = await readFile(pkgPath, \"utf-8\");\n\t\treturn JSON.parse(content);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function runSqlFile(db: ReturnType<typeof createDatabase>, filePath: string): Promise<void> {\n\tconst contents = await readFile(filePath, \"utf-8\");\n\n\t// Remove single-line comments\n\tconst withoutComments = contents\n\t\t.split(\"\\n\")\n\t\t.filter((line) => !line.trim().startsWith(\"--\"))\n\t\t.join(\"\\n\");\n\n\t// Split on semicolons, filter empty statements\n\tconst statements = withoutComments\n\t\t.split(\";\")\n\t\t.map((s) => s.trim())\n\t\t.filter((s) => s.length > 0);\n\n\tfor (const statement of statements) {\n\t\tawait db.executeQuery(sql.raw(statement).compile(db));\n\t}\n}\n\n/**\n * Check if database has already been initialized with template schema\n */\nasync function isAlreadyInitialized(db: ReturnType<typeof createDatabase>): Promise<boolean> {\n\ttry {\n\t\t// Use raw SQL since this runs on an untyped database connection\n\t\tconst result = await sql<{\n\t\t\tcount: number;\n\t\t}>`SELECT COUNT(id) as count FROM _emdash_collections`.execute(db);\n\t\tconst row = result.rows[0];\n\t\treturn row ? row.count > 0 : false;\n\t} catch {\n\t\t// Table doesn't exist yet\n\t\treturn false;\n\t}\n}\n\nexport const initCommand = defineCommand({\n\tmeta: {\n\t\tname: \"init\",\n\t\tdescription: \"Initialize database from template config\",\n\t},\n\targs: {\n\t\tdatabase: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"d\",\n\t\t\tdescription: \"Database path (default: ./data.db)\",\n\t\t\tdefault: \"./data.db\",\n\t\t},\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Working directory\",\n\t\t\tdefault: process.cwd(),\n\t\t},\n\t\tforce: {\n\t\t\ttype: \"boolean\",\n\t\t\talias: \"f\",\n\t\t\tdescription: \"Force re-initialization\",\n\t\t\tdefault: false,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst cwd = resolve(args.cwd);\n\t\tconsola.start(\"Initializing EmDash...\");\n\n\t\t// 1. Read package.json\n\t\tconst pkg = await readPackageJson(cwd);\n\t\tif (!pkg) {\n\t\t\tconsola.error(\"No package.json found in\", cwd);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconst config = pkg.emdash;\n\t\tconsola.info(`Project: ${pkg.name || \"unknown\"}`);\n\n\t\tif (config?.label) {\n\t\t\tconsola.info(`Template: ${config.label}`);\n\t\t}\n\n\t\t// 2. Create/connect to database\n\t\tconst dbPath = resolve(cwd, args.database);\n\t\tconsola.info(`Database: ${dbPath}`);\n\n\t\tconst db = createDatabase({ url: `file:${dbPath}` });\n\n\t\t// 3. Run core migrations (always run - they're idempotent)\n\t\tconsola.start(\"Running migrations...\");\n\t\ttry {\n\t\t\tconst { applied } = await runMigrations(db);\n\t\t\tif (applied.length > 0) {\n\t\t\t\tconsola.success(`Applied ${applied.length} migrations`);\n\t\t\t\tfor (const name of applied) {\n\t\t\t\t\tconsola.info(` - ${name}`);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconsola.info(\"Migrations already up to date\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Migration failed:\", error);\n\t\t\tawait db.destroy();\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// 4. Check if already initialized (has collections)\n\t\tconst alreadyInitialized = await isAlreadyInitialized(db);\n\t\tif (alreadyInitialized && !args.force) {\n\t\t\tawait db.destroy();\n\t\t\tconsola.success(\"Already initialized. Use --force to re-run schema/seed.\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (alreadyInitialized && args.force) {\n\t\t\tconsola.warn(\"Re-initializing (--force)...\");\n\t\t}\n\n\t\t// 5. Run template schema.sql if present\n\t\tif (config?.schema) {\n\t\t\tconst schemaPath = resolve(cwd, config.schema);\n\t\t\tif (await fileExists(schemaPath)) {\n\t\t\t\tconsola.start(`Running schema: ${config.schema}`);\n\t\t\t\ttry {\n\t\t\t\t\tawait runSqlFile(db, schemaPath);\n\t\t\t\t\tconsola.success(\"Schema applied\");\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsola.error(\"Schema failed:\", error);\n\t\t\t\t\tawait db.destroy();\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconsola.warn(`Schema file not found: ${config.schema}`);\n\t\t\t}\n\t\t}\n\n\t\t// 6. JSON seed files are now handled by `emdash seed` command\n\t\t// The bootstrap script runs `emdash init && emdash seed`\n\t\t// Legacy SQL seed files (seed.sql) could be handled here if needed\n\n\t\tawait db.destroy();\n\t\tconsola.success(\"EmDash initialized successfully!\");\n\t\tconsola.info(\"Run `pnpm dev` to start the development server\");\n\t},\n});\n","/**\n * Login/logout/whoami CLI commands\n *\n * Login uses the OAuth Device Flow (RFC 8628):\n * 1. POST /oauth/device/code → get device_code + user_code\n * 2. Display URL + code to user\n * 3. Poll POST /oauth/device/token until authorized\n * 4. Save tokens to ~/.config/emdash/auth.json\n *\n * Custom headers (--header / EMDASH_HEADERS) are sent with every request\n * and persisted to credentials so subsequent commands inherit them.\n * This supports sites behind reverse proxies like Cloudflare Access.\n */\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\nimport pc from \"picocolors\";\n\nimport {\n\tcreateHeaderAwareFetch,\n\tgetCachedAccessToken,\n\tisAccessRedirect,\n\tresolveCustomHeaders,\n\trunCloudflaredLogin,\n} from \"../../client/cf-access.js\";\nimport {\n\tgetCredentials,\n\tremoveCredentials,\n\tresolveCredentialKey,\n\tsaveCredentials,\n} from \"../credentials.js\";\nimport { configureOutputMode } from \"../output.js\";\n\n// ---------------------------------------------------------------------------\n// Types for discovery + device flow responses\n// ---------------------------------------------------------------------------\n\ninterface DiscoveryResponse {\n\tinstance?: { name?: string };\n\tauth?: {\n\t\tmode?: string;\n\t\tmethods?: {\n\t\t\tdevice_flow?: {\n\t\t\t\tdevice_authorization_endpoint: string;\n\t\t\t\ttoken_endpoint: string;\n\t\t\t};\n\t\t\tapi_tokens?: boolean;\n\t\t};\n\t};\n}\n\ninterface DeviceCodeResponse {\n\tdevice_code: string;\n\tuser_code: string;\n\tverification_uri: string;\n\texpires_in: number;\n\tinterval: number;\n}\n\ninterface TokenResponse {\n\taccess_token: string;\n\trefresh_token: string;\n\ttoken_type: string;\n\texpires_in: number;\n\tscope: string;\n}\n\n// ---------------------------------------------------------------------------\n// Device Flow polling\n// ---------------------------------------------------------------------------\n\nasync function pollForToken(\n\ttokenEndpoint: string,\n\tdeviceCode: string,\n\tinterval: number,\n\texpiresIn: number,\n\tfetchFn: typeof fetch,\n): Promise<TokenResponse> {\n\tconst deadline = Date.now() + expiresIn * 1000;\n\tlet currentInterval = interval;\n\n\twhile (Date.now() < deadline) {\n\t\tawait new Promise((resolve) => setTimeout(resolve, currentInterval * 1000));\n\n\t\tconst res = await fetchFn(tokenEndpoint, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify({\n\t\t\t\tdevice_code: deviceCode,\n\t\t\t\tgrant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n\t\t\t}),\n\t\t});\n\n\t\tif (res.ok) {\n\t\t\tconst body = (await res.json()) as { data: TokenResponse };\n\t\t\treturn body.data;\n\t\t}\n\n\t\tconst body = (await res.json()) as { error?: string; interval?: number };\n\n\t\tif (body.error === \"authorization_pending\") {\n\t\t\t// Keep polling\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (body.error === \"slow_down\") {\n\t\t\t// Use server-provided interval, or fall back to incrementing by 5s\n\t\t\tcurrentInterval = body.interval ?? currentInterval + 5;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (body.error === \"expired_token\") {\n\t\t\tthrow new Error(\"Device code expired. Please try again.\");\n\t\t}\n\n\t\tif (body.error === \"access_denied\") {\n\t\t\tthrow new Error(\"Authorization was denied.\");\n\t\t}\n\n\t\t// Unknown error\n\t\tthrow new Error(`Token exchange failed: ${body.error || res.statusText}`);\n\t}\n\n\tthrow new Error(\"Device code expired (timeout). Please try again.\");\n}\n\n// ---------------------------------------------------------------------------\n// Cloudflare Access handling\n// ---------------------------------------------------------------------------\n\n/**\n * Handle a Cloudflare Access redirect during login.\n *\n * 1. Try `cloudflared access token` for a cached JWT\n * 2. Try `cloudflared access login` to do the browser flow\n * 3. If cloudflared isn't available, print instructions for service tokens\n *\n * Returns the Access JWT, or null if auth couldn't be resolved.\n */\nasync function handleAccessRedirect(baseUrl: string): Promise<string | null> {\n\tconsola.info(\"This site is behind Cloudflare Access.\");\n\n\t// Try cached token first\n\tconst cached = await getCachedAccessToken(baseUrl);\n\tif (cached) {\n\t\tconsola.success(\"Using cached Cloudflare Access token from cloudflared.\");\n\t\treturn cached;\n\t}\n\n\t// Try interactive login via cloudflared\n\tconsola.info(\"Launching browser for Cloudflare Access login...\");\n\tconst loginOk = await runCloudflaredLogin(baseUrl);\n\n\tif (loginOk) {\n\t\tconst token = await getCachedAccessToken(baseUrl);\n\t\tif (token) {\n\t\t\tconsola.success(\"Cloudflare Access authentication successful.\");\n\t\t\treturn token;\n\t\t}\n\t}\n\n\t// cloudflared not available or login failed — guide the user\n\tconsole.log();\n\tconsola.info(\"Could not authenticate with Cloudflare Access automatically.\");\n\tconsola.info(\"You have two options:\");\n\tconsole.log();\n\tconsola.info(` ${pc.bold(\"Option 1:\")} Install cloudflared and run:`);\n\tconsole.log(` ${pc.cyan(`cloudflared access login ${baseUrl}`)}`);\n\tconsole.log(` ${pc.cyan(`emdash login --url ${baseUrl}`)}`);\n\tconsole.log();\n\tconsola.info(` ${pc.bold(\"Option 2:\")} Use a service token:`);\n\tconsole.log(\n\t\t` ${pc.cyan(`emdash login --url ${baseUrl} -H \"CF-Access-Client-Id: <id>\" -H \"CF-Access-Client-Secret: <secret>\"`)}`,\n\t);\n\tconsole.log();\n\n\treturn null;\n}\n\n// ---------------------------------------------------------------------------\n// Commands\n// ---------------------------------------------------------------------------\n\nexport const loginCommand = defineCommand({\n\tmeta: { name: \"login\", description: \"Log in to an EmDash instance\" },\n\targs: {\n\t\turl: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"u\",\n\t\t\tdescription: \"EmDash instance URL\",\n\t\t\tdefault: \"http://localhost:4321\",\n\t\t},\n\t\theader: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"H\",\n\t\t\tdescription: 'Custom header \"Name: Value\" (repeatable, or use EMDASH_HEADERS env)',\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst baseUrl = args.url || \"http://localhost:4321\";\n\t\tconsola.start(`Connecting to ${baseUrl}...`);\n\n\t\t// Resolve custom headers from --header flags and EMDASH_HEADERS env\n\t\tconst customHeaders = resolveCustomHeaders();\n\t\tlet headerFetch = createHeaderAwareFetch(customHeaders);\n\n\t\ttry {\n\t\t\t// Step 1: Fetch auth discovery.\n\t\t\t// Use redirect: \"manual\" to detect Cloudflare Access.\n\t\t\tconst discoveryUrl = new URL(\"/_emdash/.well-known/auth\", baseUrl);\n\t\t\tlet res = await headerFetch(discoveryUrl, { redirect: \"manual\" });\n\n\t\t\t// Handle Cloudflare Access\n\t\t\tif (isAccessRedirect(res)) {\n\t\t\t\tconst accessToken = await handleAccessRedirect(baseUrl);\n\t\t\t\tif (!accessToken) {\n\t\t\t\t\treturn; // handleAccessRedirect printed instructions\n\t\t\t\t}\n\t\t\t\t// Add the Access token to our custom headers and rebuild the fetch wrapper\n\t\t\t\tcustomHeaders[\"cf-access-token\"] = accessToken;\n\t\t\t\theaderFetch = createHeaderAwareFetch(customHeaders);\n\t\t\t\tres = await headerFetch(discoveryUrl);\n\t\t\t} else if (res.status === 301 || res.status === 302) {\n\t\t\t\t// Non-Access redirect — follow it normally\n\t\t\t\tres = await headerFetch(discoveryUrl);\n\t\t\t}\n\n\t\t\tif (!res.ok) {\n\t\t\t\tif (res.status === 404) {\n\t\t\t\t\tconst isLocal = baseUrl.includes(\"localhost\") || baseUrl.includes(\"127.0.0.1\");\n\t\t\t\t\tif (isLocal) {\n\t\t\t\t\t\tconsola.info(\"Auth discovery not available. Trying dev bypass...\");\n\t\t\t\t\t\tconst bypassRes = await fetch(new URL(\"/_emdash/api/auth/dev-bypass\", baseUrl), {\n\t\t\t\t\t\t\tredirect: \"manual\",\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (bypassRes.status === 302 || bypassRes.ok) {\n\t\t\t\t\t\t\tconsola.success(\"Dev bypass available. Client will authenticate automatically.\");\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsola.error(\"Could not authenticate. Is the dev server running?\");\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsola.error(\"Auth discovery endpoint not found. Is this an EmDash instance?\");\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconsola.error(`Discovery failed: ${res.status} ${res.statusText}`);\n\t\t\t\tprocess.exit(2);\n\t\t\t}\n\n\t\t\tconst discovery = (await res.json()) as DiscoveryResponse;\n\t\t\tconsola.success(`Connected to ${discovery.instance?.name || \"EmDash\"}`);\n\n\t\t\tconst deviceFlow = discovery.auth?.methods?.device_flow;\n\n\t\t\tif (!deviceFlow) {\n\t\t\t\t// No device flow available (external auth mode)\n\t\t\t\tconsola.info(\"Device Flow is not available for this instance.\");\n\t\t\t\tconsola.info(\"Generate an API token in Settings > API Tokens\");\n\t\t\t\tconsola.info(`Then run: ${pc.cyan(`emdash --token <token> --url ${baseUrl}`)}`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Step 2: Request device code\n\t\t\tconst codeUrl = new URL(deviceFlow.device_authorization_endpoint, baseUrl);\n\t\t\tconst codeRes = await headerFetch(codeUrl, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\"X-EmDash-Request\": \"1\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tclient_id: \"emdash-cli\",\n\t\t\t\t\tscope: \"admin\",\n\t\t\t\t}),\n\t\t\t});\n\n\t\t\tif (!codeRes.ok) {\n\t\t\t\tconsola.error(`Failed to request device code: ${codeRes.status}`);\n\t\t\t\tprocess.exit(2);\n\t\t\t}\n\n\t\t\tconst deviceCodeBody = (await codeRes.json()) as { data: DeviceCodeResponse };\n\t\t\tconst deviceCode = deviceCodeBody.data;\n\n\t\t\t// Step 3: Display instructions\n\t\t\tconsole.log();\n\t\t\tconsola.info(`Open your browser to:`);\n\t\t\tconsole.log(` ${pc.cyan(pc.bold(deviceCode.verification_uri))}`);\n\t\t\tconsole.log();\n\t\t\tconsola.info(`Enter code: ${pc.yellow(pc.bold(deviceCode.user_code))}`);\n\t\t\tconsole.log();\n\n\t\t\t// Try to open browser (best-effort)\n\t\t\ttry {\n\t\t\t\tconst { execFile } = await import(\"node:child_process\");\n\t\t\t\tif (process.platform === \"darwin\") {\n\t\t\t\t\texecFile(\"open\", [deviceCode.verification_uri]);\n\t\t\t\t} else if (process.platform === \"win32\") {\n\t\t\t\t\texecFile(\"cmd\", [\"/c\", \"start\", \"\", deviceCode.verification_uri]);\n\t\t\t\t} else {\n\t\t\t\t\texecFile(\"xdg-open\", [deviceCode.verification_uri]);\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Ignore — user can open manually\n\t\t\t}\n\n\t\t\t// Step 4: Poll for token\n\t\t\tconsola.start(\"Waiting for authorization...\");\n\n\t\t\tconst tokenUrl = new URL(deviceFlow.token_endpoint, baseUrl);\n\t\t\tconst tokenResult = await pollForToken(\n\t\t\t\ttokenUrl.toString(),\n\t\t\t\tdeviceCode.device_code,\n\t\t\t\tdeviceCode.interval,\n\t\t\t\tdeviceCode.expires_in,\n\t\t\t\theaderFetch,\n\t\t\t);\n\n\t\t\t// Step 5: Fetch user info\n\t\t\tlet userEmail = \"unknown\";\n\t\t\tlet userRole = \"unknown\";\n\t\t\ttry {\n\t\t\t\tconst meRes = await headerFetch(new URL(\"/_emdash/api/auth/me\", baseUrl), {\n\t\t\t\t\theaders: { Authorization: `Bearer ${tokenResult.access_token}` },\n\t\t\t\t});\n\t\t\t\tif (meRes.ok) {\n\t\t\t\t\tconst meJson = (await meRes.json()) as {\n\t\t\t\t\t\tdata: { email?: string; role?: number };\n\t\t\t\t\t};\n\t\t\t\t\tconst me = meJson.data;\n\t\t\t\t\tuserEmail = me.email || \"unknown\";\n\t\t\t\t\t// Map role number to name\n\t\t\t\t\tconst roleNames: Record<number, string> = {\n\t\t\t\t\t\t10: \"subscriber\",\n\t\t\t\t\t\t20: \"contributor\",\n\t\t\t\t\t\t30: \"author\",\n\t\t\t\t\t\t40: \"editor\",\n\t\t\t\t\t\t50: \"admin\",\n\t\t\t\t\t};\n\t\t\t\t\tuserRole = (me.role ? roleNames[me.role] : undefined) || \"unknown\";\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Non-critical\n\t\t\t}\n\n\t\t\t// Step 6: Save credentials (persist custom headers so subsequent commands inherit them)\n\t\t\tconst expiresAt = new Date(Date.now() + tokenResult.expires_in * 1000).toISOString();\n\t\t\tconst hasCustomHeaders = Object.keys(customHeaders).length > 0;\n\t\t\tsaveCredentials(baseUrl, {\n\t\t\t\taccessToken: tokenResult.access_token,\n\t\t\t\trefreshToken: tokenResult.refresh_token,\n\t\t\t\texpiresAt,\n\t\t\t\t...(hasCustomHeaders ? { customHeaders } : {}),\n\t\t\t\tuser: { email: userEmail, role: userRole },\n\t\t\t});\n\n\t\t\tconsola.success(`Logged in as ${pc.bold(userEmail)} (${userRole})`);\n\t\t\tconsola.info(`Token saved to ${pc.dim(resolveCredentialKey(baseUrl))}`);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Login failed\");\n\t\t\tprocess.exit(2);\n\t\t}\n\t},\n});\n\nexport const logoutCommand = defineCommand({\n\tmeta: { name: \"logout\", description: \"Log out of an EmDash instance\" },\n\targs: {\n\t\turl: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"u\",\n\t\t\tdescription: \"EmDash instance URL\",\n\t\t\tdefault: \"http://localhost:4321\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst baseUrl = args.url || \"http://localhost:4321\";\n\n\t\t// Get stored credentials\n\t\tconst cred = getCredentials(baseUrl);\n\n\t\tif (!cred) {\n\t\t\tconsola.info(\"No stored credentials found for this instance.\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst headerFetch = createHeaderAwareFetch(cred.customHeaders ?? {});\n\n\t\t// Revoke tokens server-side (best-effort)\n\t\ttry {\n\t\t\t// Revoke the refresh token (which also revokes associated access tokens)\n\t\t\tawait headerFetch(new URL(\"/_emdash/api/oauth/token/revoke\", baseUrl), {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify({ token: cred.refreshToken }),\n\t\t\t});\n\t\t} catch {\n\t\t\t// Non-critical — the local removal still works\n\t\t}\n\n\t\t// Remove local credentials\n\t\tremoveCredentials(baseUrl);\n\t\tconsola.success(\"Logged out successfully.\");\n\t},\n});\n\nexport const whoamiCommand = defineCommand({\n\tmeta: {\n\t\tname: \"whoami\",\n\t\tdescription: \"Show current user and auth method\",\n\t},\n\targs: {\n\t\turl: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"u\",\n\t\t\tdescription: \"EmDash instance URL\",\n\t\t\tdefault: \"http://localhost:4321\",\n\t\t},\n\t\ttoken: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"t\",\n\t\t\tdescription: \"Auth token\",\n\t\t},\n\t\tjson: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output as JSON\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\tconst baseUrl = args.url || \"http://localhost:4321\";\n\n\t\t// Resolve token: --token flag > EMDASH_TOKEN env > stored credentials\n\t\tlet token = args.token || process.env[\"EMDASH_TOKEN\"];\n\t\tlet authMethod = token ? \"token\" : \"none\";\n\t\tlet storedHeaders: Record<string, string> = {};\n\n\t\tif (!token) {\n\t\t\tconst cred = getCredentials(baseUrl);\n\t\t\tif (cred) {\n\t\t\t\ttoken = cred.accessToken;\n\t\t\t\tauthMethod = \"stored\";\n\t\t\t\tstoredHeaders = cred.customHeaders ?? {};\n\n\t\t\t\t// Check if expired\n\t\t\t\tif (new Date(cred.expiresAt) < new Date()) {\n\t\t\t\t\tconst headerFetch = createHeaderAwareFetch(storedHeaders);\n\t\t\t\t\t// Try to refresh\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst refreshRes = await headerFetch(\n\t\t\t\t\t\t\tnew URL(\"/_emdash/api/oauth/token/refresh\", baseUrl),\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\t\t\t\trefresh_token: cred.refreshToken,\n\t\t\t\t\t\t\t\t\tgrant_type: \"refresh_token\",\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (refreshRes.ok) {\n\t\t\t\t\t\t\tconst json = (await refreshRes.json()) as Record<string, unknown>;\n\t\t\t\t\t\t\t// Token endpoint wraps response in { data: ... } via apiSuccess.\n\t\t\t\t\t\t\t// Handle both wrapped and bare shapes for robustness.\n\t\t\t\t\t\t\tconst refreshed = (\n\t\t\t\t\t\t\t\tjson.data && typeof json.data === \"object\" && \"access_token\" in json.data\n\t\t\t\t\t\t\t\t\t? json.data\n\t\t\t\t\t\t\t\t\t: json\n\t\t\t\t\t\t\t) as TokenResponse;\n\t\t\t\t\t\t\ttoken = refreshed.access_token;\n\t\t\t\t\t\t\tsaveCredentials(baseUrl, {\n\t\t\t\t\t\t\t\t...cred,\n\t\t\t\t\t\t\t\taccessToken: refreshed.access_token,\n\t\t\t\t\t\t\t\texpiresAt: new Date(Date.now() + refreshed.expires_in * 1000).toISOString(),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsola.warn(\"Stored token expired and refresh failed. Run: emdash login\");\n\t\t\t\t\t\t\tprocess.exit(2);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tconsola.warn(\"Stored token expired. Run: emdash login\");\n\t\t\t\t\t\tprocess.exit(2);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!token) {\n\t\t\t// Try dev bypass for local\n\t\t\tconst isLocal = baseUrl.includes(\"localhost\") || baseUrl.includes(\"127.0.0.1\");\n\t\t\tif (isLocal) {\n\t\t\t\tauthMethod = \"dev-bypass\";\n\t\t\t\tconsola.info(`Auth method: ${pc.cyan(\"dev-bypass\")}`);\n\t\t\t\tconsola.info(\"No stored credentials. Client will use dev bypass for localhost.\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconsola.error(\"Not logged in. Run: emdash login\");\n\t\t\tprocess.exit(2);\n\t\t}\n\n\t\tconst headerFetch = createHeaderAwareFetch(storedHeaders);\n\n\t\ttry {\n\t\t\tconst meRes = await headerFetch(new URL(\"/_emdash/api/auth/me\", baseUrl), {\n\t\t\t\theaders: { Authorization: `Bearer ${token}` },\n\t\t\t});\n\n\t\t\tif (!meRes.ok) {\n\t\t\t\tif (meRes.status === 401) {\n\t\t\t\t\tconsola.error(\"Token is invalid or expired. Run: emdash login\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconsola.error(`Failed to fetch user info: ${meRes.status}`);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconst raw = (await meRes.json()) as {\n\t\t\t\tdata: {\n\t\t\t\t\tid: string;\n\t\t\t\t\temail: string;\n\t\t\t\t\tname: string | null;\n\t\t\t\t\trole: number;\n\t\t\t\t};\n\t\t\t};\n\t\t\tconst me = raw.data;\n\n\t\t\tconst roleNames: Record<number, string> = {\n\t\t\t\t10: \"subscriber\",\n\t\t\t\t20: \"contributor\",\n\t\t\t\t30: \"author\",\n\t\t\t\t40: \"editor\",\n\t\t\t\t50: \"admin\",\n\t\t\t};\n\n\t\t\tif (args.json) {\n\t\t\t\tconsole.log(\n\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\tid: me.id,\n\t\t\t\t\t\temail: me.email,\n\t\t\t\t\t\tname: me.name,\n\t\t\t\t\t\trole: roleNames[me.role] || `unknown (${me.role})`,\n\t\t\t\t\t\tauthMethod,\n\t\t\t\t\t\turl: baseUrl,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconsola.info(`Email: ${pc.bold(me.email)}`);\n\t\t\t\tif (me.name) consola.info(`Name: ${me.name}`);\n\t\t\t\tconsola.info(`Role: ${pc.cyan(roleNames[me.role] || `unknown (${me.role})`)}`);\n\t\t\t\tconsola.info(`Auth: ${pc.dim(authMethod)}`);\n\t\t\t\tconsola.info(`URL: ${pc.dim(baseUrl)}`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n","/**\n * emdash media\n *\n * Manage media items via the EmDash API\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { basename } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\n\nimport type { MediaUsageRepairInput, MediaUsageRepairResponse } from \"../../client/index.js\";\nimport { connectionArgs, createClientFromArgs } from \"../client-factory.js\";\nimport { configureOutputMode, output } from \"../output.js\";\n\nconst repairScopeError = \"Specify exactly one of --collection or --all\";\n\nconst listCommand = defineCommand({\n\tmeta: {\n\t\tname: \"list\",\n\t\tdescription: \"List media items\",\n\t},\n\targs: {\n\t\t...connectionArgs,\n\t\tmime: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Filter by MIME type (e.g., image/png)\",\n\t\t},\n\t\tlimit: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Number of items to return\",\n\t\t},\n\t\tcursor: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Pagination cursor\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\tconst client = createClientFromArgs(args);\n\n\t\ttry {\n\t\t\tconst result = await client.mediaList({\n\t\t\t\tmimeType: args.mime,\n\t\t\t\tlimit: args.limit ? Number(args.limit) : undefined,\n\t\t\t\tcursor: args.cursor,\n\t\t\t});\n\n\t\t\toutput(result, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Failed to list media:\", error instanceof Error ? error.message : error);\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst uploadCommand = defineCommand({\n\tmeta: {\n\t\tname: \"upload\",\n\t\tdescription: \"Upload a media file\",\n\t},\n\targs: {\n\t\tfile: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Path to the file to upload\",\n\t\t\trequired: true,\n\t\t},\n\t\t...connectionArgs,\n\t\talt: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Alt text for the media item\",\n\t\t},\n\t\tcaption: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Caption for the media item\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\tconst client = createClientFromArgs(args);\n\t\tconst filename = basename(args.file);\n\n\t\tconsola.start(`Uploading ${filename}...`);\n\n\t\ttry {\n\t\t\tconst buffer = await readFile(args.file);\n\t\t\tconst result = await client.mediaUpload(buffer, filename, {\n\t\t\t\talt: args.alt,\n\t\t\t\tcaption: args.caption,\n\t\t\t});\n\n\t\t\tconsola.success(`Uploaded ${filename}`);\n\t\t\toutput(result, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Failed to upload:\", error instanceof Error ? error.message : error);\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst getCommand = defineCommand({\n\tmeta: {\n\t\tname: \"get\",\n\t\tdescription: \"Get a media item\",\n\t},\n\targs: {\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Media item ID\",\n\t\t\trequired: true,\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\tconst client = createClientFromArgs(args);\n\n\t\ttry {\n\t\t\tconst result = await client.mediaGet(args.id);\n\t\t\toutput(result, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Failed to get media:\", error instanceof Error ? error.message : error);\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst deleteCommand = defineCommand({\n\tmeta: {\n\t\tname: \"delete\",\n\t\tdescription: \"Delete a media item\",\n\t},\n\targs: {\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Media item ID\",\n\t\t\trequired: true,\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\tconst client = createClientFromArgs(args);\n\n\t\ttry {\n\t\t\tawait client.mediaDelete(args.id);\n\n\t\t\tif (args.json) {\n\t\t\t\toutput({ deleted: true }, args);\n\t\t\t} else {\n\t\t\t\tconsola.success(`Deleted media item ${args.id}`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Failed to delete media:\", error instanceof Error ? error.message : error);\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst repairUsageCommand = defineCommand({\n\tmeta: {\n\t\tname: \"repair-usage\",\n\t\tdescription:\n\t\t\t\"Repair content media usage indexes. partial/stale exit 0; automation should use --json and parse status.\",\n\t},\n\targs: {\n\t\t...connectionArgs,\n\t\tcollection: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"c\",\n\t\t\tdescription: \"Repair one content collection\",\n\t\t},\n\t\tall: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Repair every content collection\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\n\t\tconst hasCollectionArg = args.collection !== undefined;\n\t\tconst hasCollection = typeof args.collection === \"string\";\n\t\tconst hasAll = args.all === true;\n\t\tif ((hasCollectionArg && !hasCollection) || hasCollection === hasAll) {\n\t\t\tconsola.error(repairScopeError);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconst client = createClientFromArgs(args);\n\n\t\ttry {\n\t\t\tconst repairInput: MediaUsageRepairInput = hasCollection\n\t\t\t\t? { scope: \"collection\", collection: args.collection }\n\t\t\t\t: { scope: \"all\" };\n\t\t\tconst result = await client.mediaRepairUsage(repairInput);\n\n\t\t\tif (args.json || !process.stdout.isTTY) {\n\t\t\t\toutput(result, args);\n\t\t\t} else {\n\t\t\t\tprintRepairUsageSummary(result, repairInput);\n\t\t\t}\n\n\t\t\tif (result.status === \"failed\") {\n\t\t\t\tprocess.exitCode = 1;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsola.error(\n\t\t\t\t\"Failed to repair media usage:\",\n\t\t\t\terror instanceof Error ? error.message : error,\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\ntype RepairUsageSummary = {\n\tlevel: \"success\" | \"warn\";\n\tmessage: string;\n};\n\nexport function formatRepairUsageSummary(\n\tresult: MediaUsageRepairResponse,\n\tinput: MediaUsageRepairInput,\n): RepairUsageSummary {\n\tconst counts = `indexed ${result.indexedSourceCount}, failed ${result.failedSourceCount}, skipped ${result.skippedSourceCount}, deleted ${result.deletedSourceCount}`;\n\tconst scope =\n\t\tinput.scope === \"collection\"\n\t\t\t? `collection ${input.collection}`\n\t\t\t: `all content (${formatCollectionCount(result.collections.length)})`;\n\n\tif (result.status === \"complete\") {\n\t\treturn {\n\t\t\tlevel: \"success\",\n\t\t\tmessage: `Media usage repair complete for ${scope} (${counts}).`,\n\t\t};\n\t}\n\n\tconst details = result.collections\n\t\t.filter((collection) => collection.status !== \"complete\")\n\t\t.map((collection) => {\n\t\t\tconst error = collection.lastErrorCode ? `, ${collection.lastErrorCode}` : \"\";\n\t\t\treturn `${collection.collection}: ${collection.status}${error}`;\n\t\t})\n\t\t.join(\"; \");\n\tconst suffix = details ? ` ${details}.` : \"\";\n\n\tif (result.status === \"stale\") {\n\t\treturn {\n\t\t\tlevel: \"warn\",\n\t\t\tmessage: `Media usage repair is stale for ${scope}; trustworthy complete coverage was not established because another writer, repair, or stale marker won the race. Rerun when writes are quiet (${counts}).${suffix}`,\n\t\t};\n\t}\n\n\tif (result.status === \"partial\") {\n\t\treturn {\n\t\t\tlevel: \"warn\",\n\t\t\tmessage: `Media usage repair is partial for ${scope}; some sources or collections need attention (${counts}).${suffix}`,\n\t\t};\n\t}\n\n\treturn {\n\t\tlevel: \"warn\",\n\t\tmessage: `Media usage repair failed for ${scope} (${counts}).${suffix}`,\n\t};\n}\n\nfunction printRepairUsageSummary(\n\tresult: MediaUsageRepairResponse,\n\tinput: MediaUsageRepairInput,\n): void {\n\tconst summary = formatRepairUsageSummary(result, input);\n\tif (summary.level === \"success\") {\n\t\tconsola.success(summary.message);\n\t} else {\n\t\tconsola.warn(summary.message);\n\t}\n}\n\nfunction formatCollectionCount(count: number): string {\n\treturn `${count} collection${count === 1 ? \"\" : \"s\"}`;\n}\n\nexport const mediaCommand = defineCommand({\n\tmeta: {\n\t\tname: \"media\",\n\t\tdescription: \"Manage media items\",\n\t},\n\tsubCommands: {\n\t\tlist: listCommand,\n\t\tupload: uploadCommand,\n\t\tget: getCommand,\n\t\tdelete: deleteCommand,\n\t\t\"repair-usage\": repairUsageCommand,\n\t},\n});\n","/**\n * emdash menu\n *\n * Manage menus via the EmDash REST API.\n */\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\n\nimport { connectionArgs, createClientFromArgs } from \"../client-factory.js\";\nimport { configureOutputMode, output } from \"../output.js\";\n\nconst listCommand = defineCommand({\n\tmeta: {\n\t\tname: \"list\",\n\t\tdescription: \"List all menus\",\n\t},\n\targs: {\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst menus = await client.menus();\n\t\t\toutput(menus, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst getCommand = defineCommand({\n\tmeta: {\n\t\tname: \"get\",\n\t\tdescription: \"Get a menu with its items\",\n\t},\n\targs: {\n\t\tname: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Menu name\",\n\t\t\trequired: true,\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst menu = await client.menu(args.name);\n\t\t\toutput(menu, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nexport const menuCommand = defineCommand({\n\tmeta: {\n\t\tname: \"menu\",\n\t\tdescription: \"Manage menus\",\n\t},\n\tsubCommands: {\n\t\tlist: listCommand,\n\t\tget: getCommand,\n\t},\n});\n","import { access } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { isAbsolute, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport type { AstroI18nInput } from \"../i18n/normalize.js\";\nimport { normalizeAstroI18n } from \"../i18n/normalize.js\";\nimport type { CoreMigrationIdentity } from \"./identity.js\";\nimport {\n\tgetMigrationIntegrationMetadata,\n\tMIGRATION_CONFIG_SYMBOL,\n} from \"./integration-metadata.js\";\nimport { buildMigrationManifest } from \"./manifest-builder.js\";\nimport type { MigrationManifestV1 } from \"./manifest.js\";\n\nconst ASTRO_CONFIG_FILENAMES = [\n\t\"astro.config.mjs\",\n\t\"astro.config.js\",\n\t\"astro.config.ts\",\n\t\"astro.config.mts\",\n] as const;\n\ninterface EvaluatedAstroConfig {\n\tintegrations?: unknown[];\n\ti18n?: AstroI18nInput | null;\n}\n\nexport interface BuildMigrationManifestFromConfigOptions {\n\tprojectRoot: string;\n\tconfigFile?: string;\n}\n\nexport interface MigrationConfigLoaderDependencies {\n\tfindConfigFile: (projectRoot: string, configFile?: string) => Promise<string>;\n\tloadConfig: (projectRoot: string, configFile: string) => Promise<unknown>;\n\tloadIdentity: (projectRoot: string) => Promise<CoreMigrationIdentity>;\n}\n\nexport class MigrationConfigLoaderError extends Error {\n\tconstructor(message: string, options?: ErrorOptions) {\n\t\tsuper(message, options);\n\t\tthis.name = \"MigrationConfigLoaderError\";\n\t}\n}\n\nasync function isAccessible(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport async function findAstroConfigFile(\n\tprojectRoot: string,\n\tconfigFile?: string,\n): Promise<string> {\n\tconst root = resolve(projectRoot);\n\tif (configFile) {\n\t\tconst explicitPath = isAbsolute(configFile) ? configFile : resolve(root, configFile);\n\t\tif (await isAccessible(explicitPath)) return explicitPath;\n\t\tthrow new MigrationConfigLoaderError(`Astro config file not found: ${explicitPath}`);\n\t}\n\n\tfor (const filename of ASTRO_CONFIG_FILENAMES) {\n\t\tconst candidate = resolve(root, filename);\n\t\tif (await isAccessible(candidate)) return candidate;\n\t}\n\n\tthrow new MigrationConfigLoaderError(`No Astro config file found in ${root}`);\n}\n\nfunction projectRequire(projectRoot: string) {\n\treturn createRequire(resolve(projectRoot, \"package.json\"));\n}\n\nasync function importModule(path: string): Promise<unknown> {\n\treturn import(pathToFileURL(path).href);\n}\n\nfunction isRecord(value: unknown): value is Record<PropertyKey, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction moduleExport(module: unknown, name: string): unknown {\n\tif (!isRecord(module)) return undefined;\n\tconst direct = module[name];\n\tif (direct !== undefined) return direct;\n\tconst defaultExport = module.default;\n\treturn isRecord(defaultExport) ? defaultExport[name] : undefined;\n}\n\nfunction isCoreMigrationIdentity(value: unknown): value is CoreMigrationIdentity {\n\treturn (\n\t\tisRecord(value) &&\n\t\ttypeof value.emdashVersion === \"string\" &&\n\t\tArray.isArray(value.names) &&\n\t\tvalue.names.every((name) => typeof name === \"string\") &&\n\t\ttypeof value.fingerprint === \"string\"\n\t);\n}\n\nasync function loadProjectConfig(projectRoot: string, configFile: string): Promise<unknown> {\n\tlet viteEntrypoint: string;\n\ttry {\n\t\tconst require = projectRequire(projectRoot);\n\t\tconst astroEntrypoint = require.resolve(\"astro\");\n\t\tviteEntrypoint = createRequire(astroEntrypoint).resolve(\"vite\");\n\t} catch (error) {\n\t\tthrow new MigrationConfigLoaderError(\n\t\t\t\"Could not resolve Vite through the project's Astro installation\",\n\t\t\t{ cause: error },\n\t\t);\n\t}\n\n\tconst vite = await importModule(viteEntrypoint);\n\tconst loadConfigFromFile = moduleExport(vite, \"loadConfigFromFile\");\n\tif (typeof loadConfigFromFile !== \"function\") {\n\t\tthrow new MigrationConfigLoaderError(\n\t\t\t\"The Vite installation used by project-local Astro does not export loadConfigFromFile\",\n\t\t);\n\t}\n\tconst loaded: unknown = await Reflect.apply(loadConfigFromFile, undefined, [\n\t\t{ command: \"build\", mode: \"production\" },\n\t\tconfigFile,\n\t\tprojectRoot,\n\t\t\"silent\",\n\t]);\n\tif (!isRecord(loaded) || !Object.hasOwn(loaded, \"config\")) {\n\t\tthrow new MigrationConfigLoaderError(`Vite could not load Astro config: ${configFile}`);\n\t}\n\treturn loaded.config;\n}\n\nasync function loadProjectIdentity(projectRoot: string): Promise<CoreMigrationIdentity> {\n\tlet identityEntrypoint: string;\n\ttry {\n\t\tidentityEntrypoint = projectRequire(projectRoot).resolve(\"emdash/migrations\");\n\t} catch (error) {\n\t\tthrow new MigrationConfigLoaderError(\"Could not resolve emdash/migrations from the project\", {\n\t\t\tcause: error,\n\t\t});\n\t}\n\n\tconst module = await importModule(identityEntrypoint);\n\tconst getIdentity = moduleExport(module, \"getCoreMigrationIdentity\");\n\tif (typeof getIdentity !== \"function\") {\n\t\tthrow new MigrationConfigLoaderError(\n\t\t\t\"The project-local emdash/migrations module does not export getCoreMigrationIdentity\",\n\t\t);\n\t}\n\tconst identity: unknown = await Reflect.apply(getIdentity, undefined, []);\n\tif (!isCoreMigrationIdentity(identity)) {\n\t\tthrow new MigrationConfigLoaderError(\n\t\t\t\"The project-local emdash/migrations module returned an invalid migration identity\",\n\t\t);\n\t}\n\treturn identity;\n}\n\nconst defaultDependencies: MigrationConfigLoaderDependencies = {\n\tfindConfigFile: findAstroConfigFile,\n\tloadConfig: loadProjectConfig,\n\tloadIdentity: loadProjectIdentity,\n};\n\nfunction asAstroConfig(value: unknown): EvaluatedAstroConfig {\n\tif (typeof value !== \"object\" || value === null) {\n\t\tthrow new MigrationConfigLoaderError(\"Astro config must export an object\");\n\t}\n\treturn value;\n}\n\nexport async function buildMigrationManifestFromConfig(\n\toptions: BuildMigrationManifestFromConfigOptions,\n\tdependencies: MigrationConfigLoaderDependencies = defaultDependencies,\n): Promise<MigrationManifestV1> {\n\tconst projectRoot = resolve(options.projectRoot);\n\tconst configFile = await dependencies.findConfigFile(projectRoot, options.configFile);\n\tconst config = asAstroConfig(await dependencies.loadConfig(projectRoot, configFile));\n\tconst integrations = Array.isArray(config.integrations) ? config.integrations : [];\n\tconst matchingIntegrations = integrations.filter(\n\t\t(integration) => getMigrationIntegrationMetadata(integration) !== undefined,\n\t);\n\tif (matchingIntegrations.length !== 1) {\n\t\tthrow new MigrationConfigLoaderError(\n\t\t\t`Expected exactly one EmDash integration with migration metadata (${String(MIGRATION_CONFIG_SYMBOL)}), found ${matchingIntegrations.length}`,\n\t\t);\n\t}\n\n\tconst metadata = getMigrationIntegrationMetadata(matchingIntegrations[0]);\n\tif (!metadata?.database) {\n\t\tthrow new MigrationConfigLoaderError(\n\t\t\t\"The EmDash integration does not provide database migration metadata\",\n\t\t);\n\t}\n\tconst identity = await dependencies.loadIdentity(projectRoot);\n\n\treturn buildMigrationManifest({\n\t\tidentity,\n\t\ti18n: normalizeAstroI18n(config.i18n),\n\t\tdatabase: metadata.database,\n\t});\n}\n","import { readFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { dirname, isAbsolute, parse, resolve } from \"node:path\";\nimport { createInterface } from \"node:readline/promises\";\nimport { pathToFileURL } from \"node:url\";\n\nimport { defineCommand } from \"citty\";\n\nimport { busyLockHeldSince, migrationLockHeldMessage } from \"../../database/migration-lock.js\";\nimport { buildMigrationManifestFromConfig } from \"../../migrations/config-loader.js\";\nimport type { CoreMigrationIdentity } from \"../../migrations/identity.js\";\nimport type { MigrationManifestV1 } from \"../../migrations/manifest.js\";\nimport {\n\tMigrationManifestValidationError,\n\tvalidateMigrationManifest,\n} from \"../../migrations/manifest.js\";\nimport type {\n\tMigrationExecutor,\n\tMigrationExecutorFactory,\n\tMigrationReport,\n\tMigrationRequest,\n\tMigrationTarget,\n\tMigrationTargetOverrides,\n} from \"../../migrations/protocol.js\";\n\nconst FINGERPRINT_PATTERN = /^[0-9a-f]{64}$/;\nconst SAFE_TARGET_KIND_PATTERN = /^[a-z][a-z0-9_-]*$/;\nconst SAFE_MIGRATION_NAME_PATTERN = /^[A-Za-z0-9_.-]+$/;\nconst CREDENTIAL_URL_PATTERN = /:\\/\\/[^/\\s]+@/;\nconst CREDENTIAL_QUERY_PATTERN = /[?&](?:auth|credential|key|password|secret|signature|token)=/i;\nconst LOCK_ID_PATTERN = /^[1-9]\\d{0,15}$/;\nconst ISO_TIMESTAMP_PATTERN = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/;\nconst MAX_DATE_MS = 8.64e15;\n\nexport const MIGRATE_EXIT_CODES = Object.freeze({\n\tsuccess: 0,\n\terror: 1,\n\tpending: 2,\n\tunknownApplied: 3,\n\tconfirmation: 4,\n\tinterrupted: 130,\n} as const);\n\nexport type MigrationSignal = \"SIGINT\" | \"SIGTERM\";\n\nexport interface MigrateCommandOptions extends MigrationTargetOverrides {\n\tmanifest?: string;\n\tfromConfig?: boolean;\n\tconfig?: string;\n\tcheck?: boolean;\n\tstatus?: boolean;\n\tjson?: boolean;\n\texpectedTargetFingerprint?: string;\n\treleaseLock?: string;\n}\n\nexport interface MigrateCommandDependencies {\n\tcwd: string;\n\tenv: Readonly<Record<string, string | undefined>>;\n\tinteractive: boolean;\n\tfindProjectRoot: (start: string) => Promise<string>;\n\treadManifest: (path: string, isDefault: boolean) => Promise<unknown>;\n\tbuildManifestFromConfig: (projectRoot: string, configFile?: string) => Promise<unknown>;\n\tloadProjectIdentity: (projectRoot: string) => Promise<CoreMigrationIdentity>;\n\tloadProjectExecutor: (\n\t\tprojectRoot: string,\n\t\tentrypoint: string,\n\t) => Promise<MigrationExecutorFactory>;\n\tconfirm: (message: string) => Promise<boolean>;\n\twriteStdout: (value: string) => void;\n\twriteStderr: (value: string) => void;\n\tonSignal: (signal: MigrationSignal, handler: () => Promise<void>) => () => void;\n\tcleanupTimeoutMs: number;\n}\n\nclass MigrateCommandError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"MigrateCommandError\";\n\t}\n}\n\nfunction isRecord(value: unknown): value is Record<PropertyKey, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction moduleExport(module: unknown, name: string): unknown {\n\tif (!isRecord(module)) return undefined;\n\tconst direct = Reflect.get(module, name);\n\tif (direct !== undefined) return direct;\n\tconst defaultExport = Reflect.get(module, \"default\");\n\treturn isRecord(defaultExport) ? Reflect.get(defaultExport, name) : undefined;\n}\n\nasync function importProjectModule(projectRoot: string, specifier: string): Promise<unknown> {\n\tlet resolvedEntrypoint: string;\n\ttry {\n\t\tresolvedEntrypoint = createRequire(resolve(projectRoot, \"package.json\")).resolve(specifier);\n\t} catch {\n\t\tthrow new MigrateCommandError(`Could not resolve ${specifier} from the project.`);\n\t}\n\treturn import(pathToFileURL(resolvedEntrypoint).href);\n}\n\nfunction validateIdentity(value: unknown): CoreMigrationIdentity {\n\tif (\n\t\t!isRecord(value) ||\n\t\ttypeof value.emdashVersion !== \"string\" ||\n\t\t!Array.isArray(value.names) ||\n\t\t!value.names.every((name) => typeof name === \"string\") ||\n\t\ttypeof value.fingerprint !== \"string\" ||\n\t\t!FINGERPRINT_PATTERN.test(value.fingerprint)\n\t) {\n\t\tthrow new MigrateCommandError(\n\t\t\t\"The project-local emdash/migrations module returned an invalid migration identity.\",\n\t\t);\n\t}\n\treturn {\n\t\temdashVersion: value.emdashVersion,\n\t\tnames: [...value.names],\n\t\tfingerprint: value.fingerprint,\n\t};\n}\n\nexport async function loadProjectMigrationIdentity(\n\tprojectRoot: string,\n): Promise<CoreMigrationIdentity> {\n\tconst loaded = await importProjectModule(projectRoot, \"emdash/migrations\");\n\tconst getIdentity = moduleExport(loaded, \"getCoreMigrationIdentity\");\n\tif (typeof getIdentity !== \"function\") {\n\t\tthrow new MigrateCommandError(\n\t\t\t\"The project-local emdash/migrations module does not export getCoreMigrationIdentity.\",\n\t\t);\n\t}\n\treturn validateIdentity(await Reflect.apply(getIdentity, undefined, []));\n}\n\nexport async function loadProjectMigrationExecutor(\n\tprojectRoot: string,\n\tentrypoint: string,\n): Promise<MigrationExecutorFactory> {\n\tconst loaded = await importProjectModule(projectRoot, entrypoint);\n\tconst factory = moduleExport(loaded, \"createMigrationExecutor\");\n\tif (typeof factory !== \"function\") {\n\t\tthrow new MigrateCommandError(\n\t\t\t`The project-local ${entrypoint} module does not export createMigrationExecutor.`,\n\t\t);\n\t}\n\treturn (manifestConfig, context) => Reflect.apply(factory, undefined, [manifestConfig, context]);\n}\n\nasync function findProjectRoot(start: string): Promise<string> {\n\tlet current = resolve(start);\n\tconst filesystemRoot = parse(current).root;\n\tfor (;;) {\n\t\ttry {\n\t\t\tawait readFile(resolve(current, \"package.json\"), \"utf8\");\n\t\t\treturn current;\n\t\t} catch (error) {\n\t\t\tif (isRecord(error) && error.code !== \"ENOENT\" && error.code !== \"ENOTDIR\") {\n\t\t\t\tthrow new MigrateCommandError(\"Could not read the project package.json.\");\n\t\t\t}\n\t\t}\n\t\tif (current === filesystemRoot) break;\n\t\tcurrent = dirname(current);\n\t}\n\tthrow new MigrateCommandError(\"Could not find a project root containing package.json.\");\n}\n\nexport async function readMigrationManifestFile(\n\tpath: string,\n\tisDefault: boolean,\n): Promise<unknown> {\n\tlet source: string;\n\ttry {\n\t\tsource = await readFile(path, \"utf8\");\n\t} catch (error) {\n\t\tif (isDefault && isRecord(error) && (error.code === \"ENOENT\" || error.code === \"ENOTDIR\")) {\n\t\t\tthrow new MigrateCommandError(\n\t\t\t\t`No migration manifest found at ${path}. Build the project or use --from-config.`,\n\t\t\t);\n\t\t}\n\t\tthrow new MigrateCommandError(`Could not read migration manifest: ${path}`);\n\t}\n\ttry {\n\t\treturn JSON.parse(source);\n\t} catch {\n\t\tthrow new MigrateCommandError(`Migration manifest is not valid JSON: ${path}`);\n\t}\n}\n\nasync function confirmWithReadline(message: string): Promise<boolean> {\n\tconst prompt = createInterface({ input: process.stdin, output: process.stderr });\n\ttry {\n\t\tconst answer = await prompt.question(`${message} [y/N] `);\n\t\treturn answer.trim().toLowerCase() === \"y\" || answer.trim().toLowerCase() === \"yes\";\n\t} finally {\n\t\tprompt.close();\n\t}\n}\n\nfunction onProcessSignal(signal: MigrationSignal, handler: () => Promise<void>): () => void {\n\tconst listener = () => {\n\t\tvoid handler().finally(() => process.exit(MIGRATE_EXIT_CODES.interrupted));\n\t};\n\tprocess.once(signal, listener);\n\treturn () => process.removeListener(signal, listener);\n}\n\nconst defaultDependencies: MigrateCommandDependencies = {\n\tcwd: process.cwd(),\n\tenv: process.env,\n\tinteractive: Boolean(process.stdin.isTTY && process.stdout.isTTY),\n\tfindProjectRoot,\n\treadManifest: readMigrationManifestFile,\n\tbuildManifestFromConfig: (projectRoot, configFile) =>\n\t\tbuildMigrationManifestFromConfig({ projectRoot, configFile }),\n\tloadProjectIdentity: loadProjectMigrationIdentity,\n\tloadProjectExecutor: loadProjectMigrationExecutor,\n\tconfirm: confirmWithReadline,\n\twriteStdout: (value) => process.stdout.write(`${value}\\n`),\n\twriteStderr: (value) => process.stderr.write(`${value}\\n`),\n\tonSignal: onProcessSignal,\n\tcleanupTimeoutMs: 2_000,\n};\n\nfunction validateOptions(options: MigrateCommandOptions): void {\n\tif (options.manifest && options.fromConfig) {\n\t\tthrow new MigrateCommandError(\"--manifest and --from-config cannot be used together.\");\n\t}\n\tif (options.config && !options.fromConfig) {\n\t\tthrow new MigrateCommandError(\"--config requires --from-config.\");\n\t}\n\tif (options.check && options.status) {\n\t\tthrow new MigrateCommandError(\"--check and --status cannot be used together.\");\n\t}\n\tif (options.releaseLock !== undefined) {\n\t\tif (options.check || options.status) {\n\t\t\tthrow new MigrateCommandError(\"--release-lock cannot be used with --check or --status.\");\n\t\t}\n\t\tif (!LOCK_ID_PATTERN.test(options.releaseLock)) {\n\t\t\tthrow new MigrateCommandError(\"--release-lock requires the lock id shown by --status.\");\n\t\t}\n\t}\n\tif (\n\t\toptions.expectedTargetFingerprint &&\n\t\t!FINGERPRINT_PATTERN.test(options.expectedTargetFingerprint)\n\t) {\n\t\tthrow new MigrateCommandError(\"--expected-target-fingerprint must be a SHA-256 fingerprint.\");\n\t}\n}\n\nfunction hasControlCharacter(value: string): boolean {\n\tfor (let index = 0; index < value.length; index++) {\n\t\tconst code = value.charCodeAt(index);\n\t\tif (code <= 0x1f || code === 0x7f) return true;\n\t}\n\treturn false;\n}\n\nfunction targetField(value: unknown, name: string): string | undefined {\n\tif (value === undefined) return undefined;\n\tif (\n\t\ttypeof value !== \"string\" ||\n\t\tvalue.length === 0 ||\n\t\thasControlCharacter(value) ||\n\t\tCREDENTIAL_URL_PATTERN.test(value) ||\n\t\tCREDENTIAL_QUERY_PATTERN.test(value)\n\t) {\n\t\tthrow new MigrateCommandError(`The executor returned an unsafe migration target ${name}.`);\n\t}\n\treturn value;\n}\n\nfunction immutableTarget(value: unknown): Readonly<MigrationTarget> {\n\tif (!isRecord(value)) {\n\t\tthrow new MigrateCommandError(\"The executor returned an invalid migration target.\");\n\t}\n\tconst kind = targetField(value.kind, \"kind\");\n\tconst label = targetField(value.label, \"label\");\n\tconst fingerprint = targetField(value.fingerprint, \"fingerprint\");\n\tif (\n\t\t!kind ||\n\t\t!SAFE_TARGET_KIND_PATTERN.test(kind) ||\n\t\t!label ||\n\t\t!fingerprint ||\n\t\t!FINGERPRINT_PATTERN.test(fingerprint)\n\t) {\n\t\tthrow new MigrateCommandError(\"The executor returned an invalid migration target.\");\n\t}\n\tconst target: MigrationTarget = { kind, label, fingerprint };\n\tconst accountId = targetField(value.accountId, \"accountId\");\n\tconst environment = targetField(value.environment, \"environment\");\n\tconst resourceId = targetField(value.resourceId, \"resourceId\");\n\tif (accountId) target.accountId = accountId;\n\tif (environment) target.environment = environment;\n\tif (resourceId) target.resourceId = resourceId;\n\treturn Object.freeze(target);\n}\n\nfunction safeMigrationNames(value: unknown, field: string): string[] {\n\tif (\n\t\t!Array.isArray(value) ||\n\t\t!value.every((name) => typeof name === \"string\" && SAFE_MIGRATION_NAME_PATTERN.test(name))\n\t) {\n\t\tthrow new MigrateCommandError(`The migration executor returned an invalid ${field} report.`);\n\t}\n\treturn [...value];\n}\n\nfunction safeReport(value: unknown, target: Readonly<MigrationTarget>): MigrationReport {\n\tif (!isRecord(value)) {\n\t\tthrow new MigrateCommandError(\"The migration executor returned an invalid report.\");\n\t}\n\tconst reportTarget = immutableTarget(value.target);\n\tif (\n\t\treportTarget.kind !== target.kind ||\n\t\treportTarget.label !== target.label ||\n\t\treportTarget.fingerprint !== target.fingerprint ||\n\t\treportTarget.accountId !== target.accountId ||\n\t\treportTarget.environment !== target.environment ||\n\t\treportTarget.resourceId !== target.resourceId\n\t) {\n\t\tthrow new MigrateCommandError(\n\t\t\t\"The migration executor report target does not match the confirmed target.\",\n\t\t);\n\t}\n\tconst report: MigrationReport = {\n\t\ttarget: { ...reportTarget },\n\t\tknownApplied: safeMigrationNames(value.knownApplied, \"knownApplied\"),\n\t\tpending: safeMigrationNames(value.pending, \"pending\"),\n\t\tunknownApplied: safeMigrationNames(value.unknownApplied, \"unknownApplied\"),\n\t\texecuted: safeMigrationNames(value.executed, \"executed\"),\n\t};\n\tif (value.lock !== undefined) {\n\t\tconst lock = value.lock;\n\t\tif (\n\t\t\t!isRecord(lock) ||\n\t\t\ttypeof lock.id !== \"string\" ||\n\t\t\t!LOCK_ID_PATTERN.test(lock.id) ||\n\t\t\ttypeof lock.heldSince !== \"string\" ||\n\t\t\t!ISO_TIMESTAMP_PATTERN.test(lock.heldSince)\n\t\t) {\n\t\t\tthrow new MigrateCommandError(\"The migration executor returned an invalid lock report.\");\n\t\t}\n\t\treport.lock = { id: lock.id, heldSince: lock.heldSince };\n\t}\n\treturn report;\n}\n\nfunction printTarget(target: Readonly<MigrationTarget>, write: (value: string) => void): void {\n\twrite(`Migration target: ${target.kind} ${target.label}`);\n\tif (target.accountId) write(`Account: ${target.accountId}`);\n\tif (target.environment) write(`Environment: ${target.environment}`);\n\tif (target.resourceId) write(`Resource: ${target.resourceId}`);\n\twrite(`Target fingerprint: ${target.fingerprint}`);\n}\n\nfunction printNameSet(\n\tlabel: string,\n\tnames: readonly string[],\n\twrite: (value: string) => void,\n): void {\n\twrite(`${label}: ${names.length === 0 ? \"none\" : names.join(\", \")}`);\n}\n\nfunction printHumanReport(report: MigrationReport, write: (value: string) => void): void {\n\tif (report.lock) {\n\t\twrite(`Migration lock: held since ${report.lock.heldSince} (id ${report.lock.id})`);\n\t}\n\tprintNameSet(\"Known applied\", report.knownApplied, write);\n\tprintNameSet(\"Pending\", report.pending, write);\n\tprintNameSet(\"Unknown applied\", report.unknownApplied, write);\n\tprintNameSet(\"Executed\", report.executed, write);\n}\n\nfunction reportExitCode(options: MigrateCommandOptions, report: MigrationReport): number {\n\tif (!options.check) return MIGRATE_EXIT_CODES.success;\n\tif (report.unknownApplied.length > 0) return MIGRATE_EXIT_CODES.unknownApplied;\n\tif (report.pending.length > 0) return MIGRATE_EXIT_CODES.pending;\n\treturn MIGRATE_EXIT_CODES.success;\n}\n\nfunction createOverrides(options: MigrateCommandOptions): MigrationTargetOverrides {\n\treturn {\n\t\tdatabase: options.database,\n\t\tdatabaseUrlEnv: options.databaseUrlEnv,\n\t\td1: options.d1,\n\t\taccountId: options.accountId,\n\t\twranglerConfig: options.wranglerConfig,\n\t\twranglerEnv: options.wranglerEnv,\n\t};\n}\n\nfunction bounded(\n\toperation: Promise<void>,\n\ttimeoutMs: number,\n): Promise<\"complete\" | \"failed\" | \"timeout\"> {\n\tlet timer: ReturnType<typeof setTimeout>;\n\tconst timeout = new Promise<\"timeout\">((resolveTimeout) => {\n\t\ttimer = setTimeout(resolveTimeout, timeoutMs, \"timeout\");\n\t});\n\tconst completion = operation.then<\"complete\", \"failed\">(\n\t\t() => \"complete\",\n\t\t() => \"failed\",\n\t);\n\treturn Promise.race([completion, timeout]).finally(() => clearTimeout(timer));\n}\n\nasync function loadManifest(\n\toptions: MigrateCommandOptions,\n\tprojectRoot: string,\n\tdependencies: MigrateCommandDependencies,\n): Promise<unknown> {\n\tif (options.fromConfig) {\n\t\tdependencies.writeStderr(\n\t\t\t`Using trusted evaluated Astro configuration${options.config ? `: ${options.config}` : \".\"}`,\n\t\t);\n\t\treturn dependencies.buildManifestFromConfig(projectRoot, options.config);\n\t}\n\tconst isDefault = !options.manifest;\n\tconst path = options.manifest\n\t\t? isAbsolute(options.manifest)\n\t\t\t? options.manifest\n\t\t\t: resolve(projectRoot, options.manifest)\n\t\t: resolve(projectRoot, \".emdash/migrations.json\");\n\treturn dependencies.readManifest(path, isDefault);\n}\n\nfunction redactExecutorMessage(\n\tmessage: string,\n\tenv: Readonly<Record<string, string | undefined>>,\n): string {\n\tlet redacted = message\n\t\t.replace(/[A-Za-z][A-Za-z0-9+.-]*:\\/\\/\\S+/g, \"[REDACTED_URL]\")\n\t\t.replace(\n\t\t\t/\\b(auth|credential|key|password|secret|signature|token)\\s*[=:]\\s*\\S+/gi,\n\t\t\t\"$1=[REDACTED]\",\n\t\t);\n\tfor (const value of Object.values(env)) {\n\t\tif (value && value.length >= 4) redacted = redacted.replaceAll(value, \"[REDACTED]\");\n\t}\n\treturn redacted.replaceAll(/[\\r\\n\\t]/g, \" \").slice(0, 1_000);\n}\n\nfunction safeCommandMessage(\n\terror: unknown,\n\tenv: Readonly<Record<string, string | undefined>>,\n): string {\n\tif (error instanceof MigrateCommandError || error instanceof MigrationManifestValidationError) {\n\t\treturn error.message;\n\t}\n\t// Redaction would strip the docs link and could rewrite digits of the lock\n\t// id that match an environment value, so the message is rebuilt instead.\n\tif (error instanceof Error && error.name === \"MigrationLockHeldError\") {\n\t\tconst heldSince = busyLockHeldSince(error);\n\t\tif (heldSince !== undefined && Number.isSafeInteger(heldSince) && heldSince <= MAX_DATE_MS) {\n\t\t\treturn migrationLockHeldMessage(heldSince);\n\t\t}\n\t}\n\tif (error instanceof Error && error.message) return redactExecutorMessage(error.message, env);\n\treturn \"Migration command failed. Check the project configuration, target, and credentials.\";\n}\n\nexport async function runMigrateCommand(\n\toptions: MigrateCommandOptions,\n\tdependencies: MigrateCommandDependencies = defaultDependencies,\n): Promise<number> {\n\tlet executor: MigrationExecutor | undefined;\n\tlet disposePromise: Promise<void> | undefined;\n\tlet interrupted = false;\n\tlet primaryFailure = false;\n\tlet exitCode: number = MIGRATE_EXIT_CODES.error;\n\tconst interruptedResult = Symbol(\"interrupted\");\n\tlet resolveInterruption: (() => void) | undefined;\n\tconst interruption = new Promise<typeof interruptedResult>((resolveInterrupted) => {\n\t\tresolveInterruption = () => resolveInterrupted(interruptedResult);\n\t});\n\tconst dispose = () => {\n\t\tdisposePromise ??= executor?.dispose?.() ?? Promise.resolve();\n\t\treturn disposePromise;\n\t};\n\tconst removeSignalHandlers: (() => void)[] = [];\n\n\tconst execute = async (): Promise<number> => {\n\t\ttry {\n\t\t\tvalidateOptions(options);\n\t\t\tconst projectRoot = await dependencies.findProjectRoot(dependencies.cwd);\n\t\t\tconst unvalidatedManifest = await loadManifest(options, projectRoot, dependencies);\n\t\t\tconst identity = await dependencies.loadProjectIdentity(projectRoot);\n\t\t\tconst manifest: MigrationManifestV1 = await validateMigrationManifest(\n\t\t\t\tunvalidatedManifest,\n\t\t\t\tidentity,\n\t\t\t);\n\t\t\tconst factory = await dependencies.loadProjectExecutor(\n\t\t\t\tprojectRoot,\n\t\t\t\tmanifest.database.executorEntrypoint,\n\t\t\t);\n\t\t\texecutor = await factory(manifest.database.executorConfig, {\n\t\t\t\tprojectRoot,\n\t\t\t\tenv: dependencies.env,\n\t\t\t\toverrides: createOverrides(options),\n\t\t\t});\n\t\t\tconst target = immutableTarget(executor.target);\n\t\t\tprintTarget(target, dependencies.writeStderr);\n\n\t\t\tconst onSignal = async () => {\n\t\t\t\tinterrupted = true;\n\t\t\t\tawait bounded(dispose(), dependencies.cleanupTimeoutMs);\n\t\t\t\tresolveInterruption?.();\n\t\t\t};\n\t\t\tremoveSignalHandlers.push(\n\t\t\t\tdependencies.onSignal(\"SIGINT\", onSignal),\n\t\t\t\tdependencies.onSignal(\"SIGTERM\", onSignal),\n\t\t\t);\n\n\t\t\tconst releasing = options.releaseLock !== undefined;\n\t\t\tconst applying = !options.check && !options.status && !releasing;\n\t\t\tif (applying || releasing) {\n\t\t\t\tconst operation = releasing ? \"lock release\" : \"apply\";\n\t\t\t\tconst question = releasing\n\t\t\t\t\t? `Release migration lock ${options.releaseLock} on ${target.label}? Release it only when no migration is running.`\n\t\t\t\t\t: `Apply EmDash migrations to ${target.label}?`;\n\t\t\t\tif (options.expectedTargetFingerprint) {\n\t\t\t\t\tif (options.expectedTargetFingerprint !== target.fingerprint) {\n\t\t\t\t\t\tdependencies.writeStderr(\"Expected target fingerprint does not match the target.\");\n\t\t\t\t\t\texitCode = MIGRATE_EXIT_CODES.confirmation;\n\t\t\t\t\t\treturn exitCode;\n\t\t\t\t\t}\n\t\t\t\t} else if (!dependencies.interactive || options.json) {\n\t\t\t\t\tdependencies.writeStderr(\n\t\t\t\t\t\t`Noninteractive ${operation} requires --expected-target-fingerprint with the displayed fingerprint.`,\n\t\t\t\t\t);\n\t\t\t\t\texitCode = MIGRATE_EXIT_CODES.confirmation;\n\t\t\t\t\treturn exitCode;\n\t\t\t\t} else if (!(await dependencies.confirm(question))) {\n\t\t\t\t\tdependencies.writeStderr(releasing ? \"Lock release cancelled.\" : \"Migration cancelled.\");\n\t\t\t\t\texitCode = MIGRATE_EXIT_CODES.confirmation;\n\t\t\t\t\treturn exitCode;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst request: MigrationRequest = {\n\t\t\t\taction: \"check\",\n\t\t\t\ti18n: manifest.i18n,\n\t\t\t\tartifact: {\n\t\t\t\t\temdashVersion: manifest.emdashVersion,\n\t\t\t\t\tmigrationSetFingerprint: manifest.migrationSet.fingerprint,\n\t\t\t\t},\n\t\t\t};\n\t\t\tif (applying) request.action = \"apply\";\n\t\t\tif (releasing) {\n\t\t\t\trequest.action = \"release-lock\";\n\t\t\t\trequest.lockId = options.releaseLock;\n\t\t\t}\n\t\t\tconst rawReport = await Promise.race([executor.execute(request), interruption]);\n\t\t\tif (rawReport === interruptedResult || interrupted) {\n\t\t\t\texitCode = MIGRATE_EXIT_CODES.interrupted;\n\t\t\t\treturn exitCode;\n\t\t\t}\n\t\t\tconst report = safeReport(rawReport, target);\n\t\t\tif (options.json) {\n\t\t\t\tdependencies.writeStdout(JSON.stringify(report));\n\t\t\t} else {\n\t\t\t\tif (releasing) dependencies.writeStdout(`Released migration lock ${options.releaseLock}.`);\n\t\t\t\tprintHumanReport(report, dependencies.writeStdout);\n\t\t\t}\n\t\t\texitCode = reportExitCode(options, report);\n\t\t\treturn exitCode;\n\t\t} catch (error) {\n\t\t\tprimaryFailure = true;\n\t\t\tdependencies.writeStderr(safeCommandMessage(error, dependencies.env));\n\t\t\texitCode = interrupted ? MIGRATE_EXIT_CODES.interrupted : MIGRATE_EXIT_CODES.error;\n\t\t\treturn exitCode;\n\t\t}\n\t};\n\n\ttry {\n\t\texitCode = await execute();\n\t} finally {\n\t\tfor (const remove of removeSignalHandlers) remove();\n\t\tif (executor) {\n\t\t\tconst cleanup = await bounded(dispose(), dependencies.cleanupTimeoutMs);\n\t\t\tif (cleanup !== \"complete\" && !primaryFailure && !interrupted) {\n\t\t\t\tdependencies.writeStderr(\"Migration executor cleanup failed.\");\n\t\t\t\texitCode = MIGRATE_EXIT_CODES.error;\n\t\t\t}\n\t\t}\n\t}\n\treturn exitCode;\n}\n\nexport const migrateCommand = defineCommand({\n\tmeta: {\n\t\tname: \"migrate\",\n\t\tdescription: \"Check or apply deployment-managed EmDash migrations\",\n\t},\n\targs: {\n\t\tmanifest: { type: \"string\", description: \"Migration manifest path\" },\n\t\t\"from-config\": { type: \"boolean\", description: \"Build the manifest from Astro config\" },\n\t\tconfig: { type: \"string\", description: \"Astro config path (requires --from-config)\" },\n\t\tcheck: { type: \"boolean\", description: \"Check for pending or unknown migrations\" },\n\t\tstatus: { type: \"boolean\", description: \"Report all migration status sets\" },\n\t\tjson: { type: \"boolean\", description: \"Print the stable JSON report\" },\n\t\t\"expected-target-fingerprint\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Required target fingerprint for noninteractive apply or lock release\",\n\t\t},\n\t\t\"release-lock\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Release the migration lock with the id shown by --status\",\n\t\t},\n\t\tdatabase: { type: \"string\", description: \"Override the SQLite database path\" },\n\t\t\"database-url-env\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Override the database URL environment-variable name\",\n\t\t},\n\t\td1: { type: \"string\", description: \"Override the D1 database UUID or name\" },\n\t\t\"account-id\": { type: \"string\", description: \"Override the Cloudflare account ID\" },\n\t\t\"wrangler-config\": { type: \"string\", description: \"Override the Wrangler config path\" },\n\t\t\"wrangler-env\": { type: \"string\", description: \"Override the Wrangler environment\" },\n\t},\n\tasync run({ args }) {\n\t\tprocess.exitCode = await runMigrateCommand({\n\t\t\tmanifest: args.manifest,\n\t\t\tfromConfig: args[\"from-config\"],\n\t\t\tconfig: args.config,\n\t\t\tcheck: args.check,\n\t\t\tstatus: args.status,\n\t\t\tjson: args.json,\n\t\t\texpectedTargetFingerprint: args[\"expected-target-fingerprint\"],\n\t\t\treleaseLock: args[\"release-lock\"],\n\t\t\tdatabase: args.database,\n\t\t\tdatabaseUrlEnv: args[\"database-url-env\"],\n\t\t\td1: args.d1,\n\t\t\taccountId: args[\"account-id\"],\n\t\t\twranglerConfig: args[\"wrangler-config\"],\n\t\t\twranglerEnv: args[\"wrangler-env\"],\n\t\t});\n\t},\n});\n","/**\n * Bundle utility functions\n *\n * Shared logic extracted from the bundle command so it can be tested\n * without the CLI harness and tsdown dependency.\n */\n\nimport { createWriteStream } from \"node:fs\";\nimport { readdir, stat, access } from \"node:fs/promises\";\nimport { resolve, join } from \"node:path\";\nimport { pipeline } from \"node:stream/promises\";\nimport { pathToFileURL } from \"node:url\";\n\nimport { extractManifestRoute, isJsonPostRouteContract } from \"@emdash-cms/plugin-types\";\nimport { imageSize } from \"image-size\";\nimport { packTar } from \"modern-tar/fs\";\nimport { z } from \"zod\";\n\nimport { capabilitiesToDeclaredAccess, declaredAccessToCapabilities } from \"../../plugins/types.js\";\nimport type {\n\tPluginManifest,\n\tResolvedPlugin,\n\tHookName,\n\tManifestHookEntry,\n\tManifestMcpTool,\n\tManifestRouteEntry,\n} from \"../../plugins/types.js\";\n\n// ── Constants ────────────────────────────────────────────────────────────────\n\n// Bundle size caps per RFC 0001 §\"Bundle size limits\". These are decompressed\n// sizes; the gzipped tarball is typically a fraction of MAX_BUNDLE_SIZE.\nexport const MAX_BUNDLE_SIZE = 256 * 1024;\nexport const MAX_FILE_SIZE = 128 * 1024;\nexport const MAX_FILE_COUNT = 20;\n\nexport const MAX_SCREENSHOTS = 5;\nexport const MAX_SCREENSHOT_WIDTH = 1920;\nexport const MAX_SCREENSHOT_HEIGHT = 1080;\nexport const ICON_SIZE = 256;\nconst MCP_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;\n\n// ── Regex patterns (module-scope to avoid re-compilation) ────────────────────\n\n/**\n * Matches Node.js built-in imports in bundled output:\n * - require(\"node:xxx\") / require(\"xxx\")\n * - import(\"node:xxx\") / import(\"xxx\")\n * - import X from \"node:xxx\" / import { X } from \"node:xxx\"\n * - import * as X from \"node:xxx\"\n * - export { X } from \"node:xxx\"\n * Captures the base module name (e.g. \"fs\" from \"node:fs/promises\").\n */\nconst NODE_BUILTIN_IMPORT_RE =\n\t/(?:import|export|require)\\s*(?:\\(|[^(]*?\\bfrom\\s+)[\"'](?:node:)?([a-z_]+)(?:\\/[^\"']*)?\\s*[\"']\\)?/g;\nconst LEADING_DOT_SLASH_RE = /^\\.\\//;\nconst DIST_PREFIX_RE = /^dist\\//;\nconst MJS_EXT_RE = /\\.m?js$/;\nconst TS_TO_TSX_RE = /\\.ts$/;\n\n/** Node.js built-in modules that shouldn't appear in sandbox code */\nconst NODE_BUILTINS = new Set([\n\t\"assert\",\n\t\"buffer\",\n\t\"child_process\",\n\t\"cluster\",\n\t\"crypto\",\n\t\"dgram\",\n\t\"dns\",\n\t\"domain\",\n\t\"events\",\n\t\"fs\",\n\t\"http\",\n\t\"http2\",\n\t\"https\",\n\t\"inspector\",\n\t\"module\",\n\t\"net\",\n\t\"os\",\n\t\"path\",\n\t\"perf_hooks\",\n\t\"process\",\n\t\"punycode\",\n\t\"querystring\",\n\t\"readline\",\n\t\"repl\",\n\t\"stream\",\n\t\"string_decoder\",\n\t\"sys\",\n\t\"timers\",\n\t\"tls\",\n\t\"trace_events\",\n\t\"tty\",\n\t\"url\",\n\t\"util\",\n\t\"v8\",\n\t\"vm\",\n\t\"wasi\",\n\t\"worker_threads\",\n\t\"zlib\",\n]);\n\n// ── File helpers ─────────────────────────────────────────────────────────────\n\nexport async function fileExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/** Convert an absolute build artifact path into a portable ESM import specifier. */\nexport function toFileImportSpecifier(path: string): string {\n\treturn pathToFileURL(path).href;\n}\n\n// ── Image dimension readers ──────────────────────────────────────────────────\n\n/**\n * Read image dimensions from a buffer.\n * Returns [width, height] or null if the format is unrecognized.\n */\nexport function readImageDimensions(buf: Uint8Array): [number, number] | null {\n\ttry {\n\t\tconst result = imageSize(buf);\n\t\tif (result.width != null && result.height != null) {\n\t\t\treturn [result.width, result.height];\n\t\t}\n\t\treturn null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n// ── Manifest extraction ──────────────────────────────────────────────────────\n\n/**\n * Extract manifest metadata from a ResolvedPlugin.\n * Strips functions (hooks, route handlers) and keeps only serializable metadata.\n */\nexport function extractManifest(plugin: ResolvedPlugin): PluginManifest {\n\tif ((plugin.admin.pages?.length ?? 0) > 0 || (plugin.admin.widgets?.length ?? 0) > 0) {\n\t\tconst adminRoute = plugin.routes.admin;\n\t\tif (adminRoute && (adminRoute.public === true || !isJsonPostRouteContract(adminRoute))) {\n\t\t\tthrow new Error(\"Block Kit admin route must accept POST JSON requests and return JSON\");\n\t\t}\n\t}\n\tconst declaredAccess = capabilitiesToDeclaredAccess(plugin.capabilities, plugin.allowedHosts);\n\tconst enforcedAccess = declaredAccessToCapabilities(declaredAccess);\n\t// Build hook entries preserving exclusive/priority/timeout metadata.\n\t// Plain HookName strings are emitted for hooks with default settings;\n\t// structured ManifestHookEntry objects are emitted when metadata differs.\n\tconst hooks: Array<ManifestHookEntry | HookName> = [];\n\tfor (const [name, resolved] of Object.entries(plugin.hooks)) {\n\t\tif (!resolved) continue;\n\t\tconst hasMetadata =\n\t\t\tresolved.exclusive || resolved.priority !== 100 || resolved.timeout !== 5000;\n\t\tif (hasMetadata) {\n\t\t\tconst entry: ManifestHookEntry = { name };\n\t\t\tif (resolved.exclusive) entry.exclusive = true;\n\t\t\tif (resolved.priority !== 100) entry.priority = resolved.priority;\n\t\t\tif (resolved.timeout !== 5000) entry.timeout = resolved.timeout;\n\t\t\thooks.push(entry);\n\t\t} else {\n\t\t\thooks.push(name as HookName);\n\t\t}\n\t}\n\n\tconst routes: Array<ManifestRouteEntry | string> = Object.entries(plugin.routes).map(\n\t\t([name, route]) => extractManifestRoute(name, route),\n\t);\n\tconst tools: ManifestMcpTool[] = Object.entries(plugin.mcp?.tools ?? {}).map(([name, tool]) => {\n\t\tif (!MCP_TOOL_NAME_PATTERN.test(name)) throw new Error(`Invalid MCP tool name \"${name}\"`);\n\t\tconst route = plugin.routes[tool.route];\n\t\tif (!route?.permission || route.public || route.response === \"raw\") {\n\t\t\tthrow new Error(`MCP tool \"${name}\" must reference a private route with a permission`);\n\t\t}\n\t\tif (!isJsonPostRouteContract(route)) {\n\t\t\tthrow new Error(`MCP tool \"${name}\" must reference a POST-compatible JSON route`);\n\t\t}\n\t\treturn {\n\t\t\tname,\n\t\t\tdescription: tool.description,\n\t\t\troute: tool.route,\n\t\t\tpermission: route.permission,\n\t\t\tdestructive: tool.destructive ?? false,\n\t\t\tinputSchema: z.toJSONSchema(tool.input, { target: \"draft-7\" }),\n\t\t\t...(tool.output\n\t\t\t\t? {\n\t\t\t\t\t\toutputSchema: z.toJSONSchema(tool.output, { target: \"draft-7\" }),\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t};\n\t});\n\n\treturn {\n\t\tid: plugin.id,\n\t\tversion: plugin.version,\n\t\tdeclaredAccess,\n\t\tcapabilities: enforcedAccess.capabilities,\n\t\tallowedHosts: plugin.allowedHosts,\n\t\tstorage: plugin.storage,\n\t\thooks,\n\t\troutes,\n\t\t...(tools.length > 0 ? { mcp: { tools } } : {}),\n\t\tadmin: {\n\t\t\t// Omit entry (it's a module specifier for the host, not relevant in bundles)\n\t\t\tsettingsSchema: plugin.admin.settingsSchema,\n\t\t\tpages: plugin.admin.pages,\n\t\t\twidgets: plugin.admin.widgets,\n\t\t\teditorPanels: plugin.admin.editorPanels,\n\t\t\teditorActions: plugin.admin.editorActions,\n\t\t},\n\t};\n}\n\n// ── Node.js built-in detection ───────────────────────────────────────────────\n\n/**\n * Scan bundled code for Node.js built-in imports.\n * Matches require(\"node:xxx\"), require(\"xxx\"), import(\"node:xxx\") — the patterns\n * that appear in bundled ESM/CJS output (not source-level named imports).\n * Returns deduplicated array of built-in module names found.\n */\nexport function findNodeBuiltinImports(code: string): string[] {\n\tconst found: string[] = [];\n\tNODE_BUILTIN_IMPORT_RE.lastIndex = 0;\n\tlet match;\n\twhile ((match = NODE_BUILTIN_IMPORT_RE.exec(code)) !== null) {\n\t\tconst mod = match[1];\n\t\tif (NODE_BUILTINS.has(mod)) {\n\t\t\tfound.push(mod);\n\t\t}\n\t}\n\treturn [...new Set(found)];\n}\n\n// ── Path resolution ──────────────────────────────────────────────────────────\n\n/**\n * Find a build output file by base name, checking common extensions.\n * tsdown may output .mjs, .js, or .cjs depending on format and config.\n */\nexport async function findBuildOutput(dir: string, baseName: string): Promise<string | undefined> {\n\tfor (const ext of [\".mjs\", \".js\", \".cjs\"]) {\n\t\tconst candidate = join(dir, `${baseName}${ext}`);\n\t\tif (await fileExists(candidate)) return candidate;\n\t}\n\treturn undefined;\n}\n\n/**\n * Resolve a dist/built path back to its source .ts/.tsx equivalent.\n * E.g., \"./dist/index.mjs\" → \"src/index.ts\"\n */\nexport async function resolveSourceEntry(\n\tpluginDir: string,\n\tdistPath: string,\n): Promise<string | undefined> {\n\tconst cleaned = distPath.replace(LEADING_DOT_SLASH_RE, \"\");\n\n\t// Prefer source over dist — dist/foo.mjs → src/foo.ts\n\tconst srcPath = cleaned.replace(DIST_PREFIX_RE, \"src/\").replace(MJS_EXT_RE, \".ts\");\n\tconst srcFull = resolve(pluginDir, srcPath);\n\tif (await fileExists(srcFull)) return srcFull;\n\n\t// Try .tsx\n\tconst tsxPath = srcPath.replace(TS_TO_TSX_RE, \".tsx\");\n\tconst tsxFull = resolve(pluginDir, tsxPath);\n\tif (await fileExists(tsxFull)) return tsxFull;\n\n\t// Fall back to direct path (might be source already, or pre-compiled plugin)\n\tconst direct = resolve(pluginDir, cleaned);\n\tif (await fileExists(direct)) return direct;\n\n\treturn undefined;\n}\n\n// ── Export validation ───────────────────────────────────────────────────────\n\nconst TS_SOURCE_EXPORT_RE = /\\.(?:ts|tsx|mts|cts|jsx)$/;\n\n/**\n * Find package.json exports that point to source files instead of built output.\n * Returns an array of `{ exportPath, resolvedPath }` for each offending export.\n */\nexport function findSourceExports(\n\texports: Record<string, unknown>,\n): Array<{ exportPath: string; resolvedPath: string }> {\n\tconst issues: Array<{ exportPath: string; resolvedPath: string }> = [];\n\tfor (const [exportPath, exportValue] of Object.entries(exports)) {\n\t\tconst resolved =\n\t\t\ttypeof exportValue === \"string\"\n\t\t\t\t? exportValue\n\t\t\t\t: exportValue && typeof exportValue === \"object\" && \"import\" in exportValue\n\t\t\t\t\t? (exportValue as { import: string }).import\n\t\t\t\t\t: null;\n\t\tif (resolved && TS_SOURCE_EXPORT_RE.test(resolved)) {\n\t\t\tissues.push({ exportPath, resolvedPath: resolved });\n\t\t}\n\t}\n\treturn issues;\n}\n\n// ── Directory helpers ────────────────────────────────────────────────────────\n\n/**\n * One file in a bundle: a tarball-relative path and its byte length.\n * Produced by `collectBundleEntries` (from a staging dir) or by the publish\n * flow (from tarball entries); consumed by `validateBundleSize`.\n */\nexport interface BundleFileEntry {\n\tname: string;\n\tbytes: number;\n}\n\n/**\n * Recursively walk a staging directory and return a flat list of all files\n * with sizes. Names are relative to `dir` so they match what would appear\n * as the tarball entry name.\n */\nexport async function collectBundleEntries(dir: string): Promise<BundleFileEntry[]> {\n\tconst entries: BundleFileEntry[] = [];\n\tawait walkBundle(dir, \"\", entries);\n\treturn entries;\n}\n\nasync function walkBundle(dir: string, prefix: string, into: BundleFileEntry[]): Promise<void> {\n\tconst items = await readdir(dir, { withFileTypes: true });\n\tfor (const item of items) {\n\t\tconst fullPath = join(dir, item.name);\n\t\tconst relPath = prefix ? `${prefix}/${item.name}` : item.name;\n\t\tif (item.isFile()) {\n\t\t\tconst s = await stat(fullPath);\n\t\t\tinto.push({ name: relPath, bytes: s.size });\n\t\t} else if (item.isDirectory()) {\n\t\t\tawait walkBundle(fullPath, relPath, into);\n\t\t}\n\t}\n}\n\n/**\n * Sum the byte sizes of all entries.\n */\nexport function totalBundleBytes(entries: readonly BundleFileEntry[]): number {\n\tlet total = 0;\n\tfor (const e of entries) total += e.bytes;\n\treturn total;\n}\n\n/**\n * Check a bundle against the three size caps from RFC 0001:\n * - total decompressed ≤ MAX_BUNDLE_SIZE\n * - per-file decompressed ≤ MAX_FILE_SIZE\n * - file count ≤ MAX_FILE_COUNT\n *\n * Returns a list of violation messages (empty if the bundle is within all\n * caps). Messages are deterministic per input — the total/count violations\n * come first, then oversized files in alphabetical order — so the same\n * bundle always produces the same error text.\n */\nexport function validateBundleSize(entries: readonly BundleFileEntry[]): string[] {\n\tconst violations: string[] = [];\n\tconst total = totalBundleBytes(entries);\n\tif (total > MAX_BUNDLE_SIZE) {\n\t\tviolations.push(\n\t\t\t`Bundle size ${formatBytes(total)} exceeds maximum of ${formatBytes(MAX_BUNDLE_SIZE)}.`,\n\t\t);\n\t}\n\tif (entries.length > MAX_FILE_COUNT) {\n\t\tviolations.push(\n\t\t\t`Bundle contains ${entries.length} files, exceeds maximum of ${MAX_FILE_COUNT}.`,\n\t\t);\n\t}\n\tconst oversized = entries\n\t\t.filter((e) => e.bytes > MAX_FILE_SIZE)\n\t\t.toSorted((a, b) => a.name.localeCompare(b.name));\n\tfor (const e of oversized) {\n\t\tviolations.push(\n\t\t\t`File ${e.name} is ${formatBytes(e.bytes)}, exceeds per-file maximum of ${formatBytes(MAX_FILE_SIZE)}.`,\n\t\t);\n\t}\n\treturn violations;\n}\n\n/**\n * Render a byte count as a human-friendly string (e.g. \"256.0 KB\").\n */\nexport function formatBytes(n: number): string {\n\tif (n < 1024) return `${n} B`;\n\tif (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n\treturn `${(n / 1024 / 1024).toFixed(2)} MB`;\n}\n\n// ── Tarball creation ─────────────────────────────────────────────────────────\n\n/**\n * Create a gzipped tarball from a directory.\n */\nexport async function createTarball(sourceDir: string, outputPath: string): Promise<void> {\n\tconst { createGzip } = await import(\"node:zlib\");\n\tconst tarStream = packTar(sourceDir);\n\tconst gzip = createGzip({ level: 9 });\n\tconst out = createWriteStream(outputPath);\n\tawait pipeline(tarStream, gzip, out);\n}\n","/**\n * emdash plugin bundle\n *\n * Produces a publishable plugin tarball from a plugin source directory.\n *\n * Steps:\n * 1. Resolve plugin entrypoint (finds definePlugin() export)\n * 2. Bundle backend code with tsdown → backend.js (single ES module, tree-shaken)\n * 3. Bundle admin code if present → admin.js\n * 4. Extract manifest from definePlugin() → manifest.json\n * 5. Collect assets (README.md, icon.png, screenshots/)\n * 6. Validate bundle (manifest schema, size limits, no Node.js builtins)\n * 7. Create tarball ({id}-{version}.tar.gz)\n */\n\nimport { createHash } from \"node:crypto\";\nimport { readFile, stat, mkdir, writeFile, rm, copyFile, symlink, readdir } from \"node:fs/promises\";\nimport { resolve, join, extname, basename } from \"node:path\";\n\nimport { extractRouteOptions } from \"@emdash-cms/plugin-types\";\nimport { defineCommand } from \"citty\";\nimport consola from \"consola\";\n\nimport { CAPABILITY_RENAMES, isDeprecatedCapability } from \"../../plugins/types.js\";\nimport type { ResolvedPlugin } from \"../../plugins/types.js\";\nimport {\n\tcollectBundleEntries,\n\tcreateTarball,\n\textractManifest,\n\tfileExists,\n\tfindBuildOutput,\n\tfindNodeBuiltinImports,\n\tfindSourceExports,\n\tformatBytes,\n\tICON_SIZE,\n\tMAX_SCREENSHOTS,\n\tMAX_SCREENSHOT_WIDTH,\n\tMAX_SCREENSHOT_HEIGHT,\n\treadImageDimensions,\n\tresolveSourceEntry,\n\ttoFileImportSpecifier,\n\ttotalBundleBytes,\n\tvalidateBundleSize,\n} from \"./bundle-utils.js\";\n\nconst TS_EXT_RE = /\\.(tsx?|[mc]?js)$/;\nconst SLASH_RE = /\\//g;\nconst LEADING_AT_RE = /^@/;\nconst emdash_SCOPE_RE = /^@emdash-cms\\//;\n\nexport const bundleCommand = defineCommand({\n\tmeta: {\n\t\tname: \"bundle\",\n\t\tdescription: \"Bundle a plugin for marketplace distribution\",\n\t},\n\targs: {\n\t\tdir: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Plugin directory (default: current directory)\",\n\t\t\tdefault: process.cwd(),\n\t\t},\n\t\toutDir: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"o\",\n\t\t\tdescription: \"Output directory for the tarball (default: ./dist)\",\n\t\t\tdefault: \"dist\",\n\t\t},\n\t\tvalidateOnly: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Run validation only, skip tarball creation\",\n\t\t\tdefault: false,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst pluginDir = resolve(args.dir);\n\t\tconst outDir = resolve(pluginDir, args.outDir);\n\t\tconst validateOnly = args.validateOnly;\n\n\t\tconsola.start(validateOnly ? \"Validating plugin...\" : \"Bundling plugin...\");\n\n\t\t// ── Step 1: Read package.json and resolve entrypoints ──\n\n\t\tconst pkgPath = join(pluginDir, \"package.json\");\n\t\tif (!(await fileExists(pkgPath))) {\n\t\t\tconsola.error(\"No package.json found in\", pluginDir);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconst pkg = JSON.parse(await readFile(pkgPath, \"utf-8\")) as {\n\t\t\tname?: string;\n\t\t\tmain?: string;\n\t\t\texports?: Record<string, unknown>;\n\t\t};\n\n\t\t// Find the sandbox entrypoint — look for ./sandbox export first, then main\n\t\tlet backendEntry: string | undefined;\n\t\tlet adminEntry: string | undefined;\n\n\t\tif (pkg.exports) {\n\t\t\t// Check for explicit sandbox export\n\t\t\tconst sandboxExport = pkg.exports[\"./sandbox\"];\n\t\t\tif (typeof sandboxExport === \"string\") {\n\t\t\t\tbackendEntry = await resolveSourceEntry(pluginDir, sandboxExport);\n\t\t\t} else if (sandboxExport && typeof sandboxExport === \"object\" && \"import\" in sandboxExport) {\n\t\t\t\tbackendEntry = await resolveSourceEntry(\n\t\t\t\t\tpluginDir,\n\t\t\t\t\t(sandboxExport as { import: string }).import,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Check for admin export\n\t\t\tconst adminExport = pkg.exports[\"./admin\"];\n\t\t\tif (typeof adminExport === \"string\") {\n\t\t\t\tadminEntry = await resolveSourceEntry(pluginDir, adminExport);\n\t\t\t} else if (adminExport && typeof adminExport === \"object\" && \"import\" in adminExport) {\n\t\t\t\tadminEntry = await resolveSourceEntry(\n\t\t\t\t\tpluginDir,\n\t\t\t\t\t(adminExport as { import: string }).import,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// If no sandbox export, look for src/sandbox-entry.ts\n\t\tif (!backendEntry) {\n\t\t\tconst defaultSandbox = join(pluginDir, \"src/sandbox-entry.ts\");\n\t\t\tif (await fileExists(defaultSandbox)) {\n\t\t\t\tbackendEntry = defaultSandbox;\n\t\t\t}\n\t\t}\n\n\t\t// Find the main entry for manifest extraction\n\t\tlet mainEntry: string | undefined;\n\t\tif (pkg.exports?.[\".\"] !== undefined) {\n\t\t\tconst mainExport = pkg.exports[\".\"];\n\t\t\tif (typeof mainExport === \"string\") {\n\t\t\t\tmainEntry = await resolveSourceEntry(pluginDir, mainExport);\n\t\t\t} else if (mainExport && typeof mainExport === \"object\" && \"import\" in mainExport) {\n\t\t\t\tmainEntry = await resolveSourceEntry(pluginDir, (mainExport as { import: string }).import);\n\t\t\t}\n\t\t}\n\t\tif (!mainEntry && pkg.main) {\n\t\t\tmainEntry = await resolveSourceEntry(pluginDir, pkg.main);\n\t\t}\n\t\tif (!mainEntry) {\n\t\t\tconst defaultMain = join(pluginDir, \"src/index.ts\");\n\t\t\tif (await fileExists(defaultMain)) {\n\t\t\t\tmainEntry = defaultMain;\n\t\t\t}\n\t\t}\n\n\t\tif (!mainEntry) {\n\t\t\tconsola.error(\n\t\t\t\t\"Cannot find plugin entrypoint. Expected src/index.ts or main/exports in package.json\",\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconsola.info(`Main entry: ${mainEntry}`);\n\t\tif (backendEntry) consola.info(`Backend entry: ${backendEntry}`);\n\t\tif (adminEntry) consola.info(`Admin entry: ${adminEntry}`);\n\n\t\t// ── Step 2: Extract manifest by importing the plugin ──\n\n\t\tconsola.start(\"Extracting plugin manifest...\");\n\n\t\t// Build the main entry first so we can import it\n\t\tconst { build } = await import(\"tsdown\");\n\t\tconst tmpDir = join(pluginDir, \".emdash-bundle-tmp\");\n\n\t\ttry {\n\t\t\t// Clean up any stale temp directory from a previous failed run\n\t\t\tawait rm(tmpDir, { recursive: true, force: true });\n\t\t\tawait mkdir(tmpDir, { recursive: true });\n\n\t\t\t// Build main entry to extract manifest.\n\t\t\t// Externalize emdash and sibling packages — they'll resolve\n\t\t\t// via the symlinked node_modules below.\n\t\t\tconst mainOutDir = join(tmpDir, \"main\");\n\t\t\tawait build({\n\t\t\t\tconfig: false,\n\t\t\t\tentry: [mainEntry],\n\t\t\t\tformat: \"esm\",\n\t\t\t\toutDir: mainOutDir,\n\t\t\t\tdts: false,\n\t\t\t\tplatform: \"node\",\n\t\t\t\texternal: [\"emdash\", emdash_SCOPE_RE],\n\t\t\t});\n\n\t\t\t// Symlink plugin's node_modules so the built module can resolve\n\t\t\t// external dependencies (emdash, @emdash-cms/*, etc.)\n\t\t\tconst pluginNodeModules = join(pluginDir, \"node_modules\");\n\t\t\tconst tmpNodeModules = join(mainOutDir, \"node_modules\");\n\t\t\tif (await fileExists(pluginNodeModules)) {\n\t\t\t\tawait symlink(pluginNodeModules, tmpNodeModules, \"junction\");\n\t\t\t}\n\n\t\t\t// Import the built module to get the resolved plugin\n\t\t\tconst mainBaseName = basename(mainEntry).replace(TS_EXT_RE, \"\");\n\t\t\tconst mainOutputPath = await findBuildOutput(mainOutDir, mainBaseName);\n\n\t\t\tif (!mainOutputPath) {\n\t\t\t\tconsola.error(\"Failed to build main entry — no output found in\", mainOutDir);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Dynamic import of the built plugin\n\t\t\tconst pluginModule = (await import(toFileImportSpecifier(mainOutputPath))) as Record<\n\t\t\t\tstring,\n\t\t\t\tunknown\n\t\t\t>;\n\n\t\t\t// Extract manifest from the imported module.\n\t\t\t// Supports three patterns:\n\t\t\t// 1. Native: createPlugin() export -> ResolvedPlugin\n\t\t\t// 2. Native: default export that is/returns a ResolvedPlugin (has id+version)\n\t\t\t// 3. Standard: descriptor factory function (returns { id, version, ... })\n\t\t\tlet resolvedPlugin: ResolvedPlugin | undefined;\n\n\t\t\tif (typeof pluginModule.createPlugin === \"function\") {\n\t\t\t\tresolvedPlugin = pluginModule.createPlugin() as ResolvedPlugin;\n\t\t\t} else if (typeof pluginModule.default === \"function\") {\n\t\t\t\tresolvedPlugin = pluginModule.default() as ResolvedPlugin;\n\t\t\t} else if (typeof pluginModule.default === \"object\" && pluginModule.default !== null) {\n\t\t\t\tconst defaultExport = pluginModule.default as Record<string, unknown>;\n\t\t\t\tif (\"id\" in defaultExport && \"version\" in defaultExport) {\n\t\t\t\t\tresolvedPlugin = defaultExport as unknown as ResolvedPlugin;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Standard format: no createPlugin, no default with id/version.\n\t\t\t// Look for a descriptor factory -- any named export function that\n\t\t\t// returns an object with { id, version }.\n\t\t\tif (!resolvedPlugin) {\n\t\t\t\tfor (const [key, value] of Object.entries(pluginModule)) {\n\t\t\t\t\tif (key === \"default\" || typeof value !== \"function\") continue;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = (value as () => unknown)() as Record<string, unknown> | null;\n\t\t\t\t\t\tif (result && typeof result === \"object\" && \"id\" in result && \"version\" in result) {\n\t\t\t\t\t\t\tresolvedPlugin = {\n\t\t\t\t\t\t\t\tid: result.id,\n\t\t\t\t\t\t\t\tversion: result.version,\n\t\t\t\t\t\t\t\tcapabilities: result.capabilities ?? [],\n\t\t\t\t\t\t\t\tallowedHosts: result.allowedHosts ?? [],\n\t\t\t\t\t\t\t\tstorage: result.storage ?? {},\n\t\t\t\t\t\t\t\thooks: {},\n\t\t\t\t\t\t\t\troutes: {},\n\t\t\t\t\t\t\t\tadmin: {\n\t\t\t\t\t\t\t\t\tpages: result.adminPages,\n\t\t\t\t\t\t\t\t\twidgets: result.adminWidgets,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t} as ResolvedPlugin;\n\n\t\t\t\t\t\t\t// If there's a sandbox entry, build and import it\n\t\t\t\t\t\t\t// to get hook/route names for the manifest.\n\t\t\t\t\t\t\tif (backendEntry) {\n\t\t\t\t\t\t\t\tconst backendProbeDir = join(tmpDir, \"backend-probe\");\n\t\t\t\t\t\t\t\tconst probeShimDir = join(tmpDir, \"probe-shims\");\n\t\t\t\t\t\t\t\tawait mkdir(probeShimDir, { recursive: true });\n\t\t\t\t\t\t\t\tawait writeFile(\n\t\t\t\t\t\t\t\t\tjoin(probeShimDir, \"emdash.mjs\"),\n\t\t\t\t\t\t\t\t\t\"export const definePlugin = (d) => d;\\n\",\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tawait build({\n\t\t\t\t\t\t\t\t\tconfig: false,\n\t\t\t\t\t\t\t\t\tentry: [backendEntry],\n\t\t\t\t\t\t\t\t\tformat: \"esm\",\n\t\t\t\t\t\t\t\t\toutDir: backendProbeDir,\n\t\t\t\t\t\t\t\t\tdts: false,\n\t\t\t\t\t\t\t\t\tplatform: \"neutral\",\n\t\t\t\t\t\t\t\t\texternal: [],\n\t\t\t\t\t\t\t\t\talias: { emdash: join(probeShimDir, \"emdash.mjs\") },\n\t\t\t\t\t\t\t\t\ttreeshake: true,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tconst backendBaseName = basename(backendEntry).replace(TS_EXT_RE, \"\");\n\t\t\t\t\t\t\t\tconst backendProbePath = await findBuildOutput(backendProbeDir, backendBaseName);\n\t\t\t\t\t\t\t\tif (backendProbePath) {\n\t\t\t\t\t\t\t\t\tconst backendModule = (await import(\n\t\t\t\t\t\t\t\t\t\ttoFileImportSpecifier(backendProbePath)\n\t\t\t\t\t\t\t\t\t)) as Record<string, unknown>;\n\t\t\t\t\t\t\t\t\tconst standardDef = (backendModule.default ?? {}) as Record<string, unknown>;\n\t\t\t\t\t\t\t\t\tconst hooks = standardDef.hooks as Record<string, unknown> | undefined;\n\t\t\t\t\t\t\t\t\tconst routes = standardDef.routes as Record<string, unknown> | undefined;\n\t\t\t\t\t\t\t\t\tif (hooks) {\n\t\t\t\t\t\t\t\t\t\tfor (const hookName of Object.keys(hooks)) {\n\t\t\t\t\t\t\t\t\t\t\tconst hookEntry = hooks[hookName];\n\t\t\t\t\t\t\t\t\t\t\tconst isConfig =\n\t\t\t\t\t\t\t\t\t\t\t\ttypeof hookEntry === \"object\" &&\n\t\t\t\t\t\t\t\t\t\t\t\thookEntry !== null &&\n\t\t\t\t\t\t\t\t\t\t\t\t\"handler\" in hookEntry;\n\t\t\t\t\t\t\t\t\t\t\tconst config = isConfig ? (hookEntry as Record<string, unknown>) : {};\n\t\t\t\t\t\t\t\t\t\t\t(resolvedPlugin.hooks as Record<string, unknown>)[hookName] = {\n\t\t\t\t\t\t\t\t\t\t\t\thandler: isConfig\n\t\t\t\t\t\t\t\t\t\t\t\t\t? (hookEntry as Record<string, unknown>).handler\n\t\t\t\t\t\t\t\t\t\t\t\t\t: hookEntry,\n\t\t\t\t\t\t\t\t\t\t\t\tpriority: (config.priority as number) ?? 100,\n\t\t\t\t\t\t\t\t\t\t\t\ttimeout: (config.timeout as number) ?? 5000,\n\t\t\t\t\t\t\t\t\t\t\t\tdependencies: (config.dependencies as string[]) ?? [],\n\t\t\t\t\t\t\t\t\t\t\t\terrorPolicy: (config.errorPolicy as string) ?? \"abort\",\n\t\t\t\t\t\t\t\t\t\t\t\texclusive: (config.exclusive as boolean) ?? false,\n\t\t\t\t\t\t\t\t\t\t\t\tpluginId: result.id,\n\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (routes) {\n\t\t\t\t\t\t\t\t\t\tfor (const [name, route] of Object.entries(routes)) {\n\t\t\t\t\t\t\t\t\t\t\tconst routeObj =\n\t\t\t\t\t\t\t\t\t\t\t\ttypeof route === \"object\" && route !== null\n\t\t\t\t\t\t\t\t\t\t\t\t\t? (route as Record<string, unknown>)\n\t\t\t\t\t\t\t\t\t\t\t\t\t: {};\n\t\t\t\t\t\t\t\t\t\t\t(resolvedPlugin.routes as Record<string, unknown>)[name] = {\n\t\t\t\t\t\t\t\t\t\t\t\thandler: typeof route === \"function\" ? route : routeObj.handler,\n\t\t\t\t\t\t\t\t\t\t\t\t...extractRouteOptions(route),\n\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (resolvedPlugin) throw error;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!resolvedPlugin?.id || !resolvedPlugin?.version) {\n\t\t\t\tconsola.error(\n\t\t\t\t\t\"Could not extract plugin definition. Expected one of:\\n\" +\n\t\t\t\t\t\t\" - createPlugin() export (native format)\\n\" +\n\t\t\t\t\t\t\" - Descriptor factory function returning { id, version, ... } (standard format)\",\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconst manifest = extractManifest(resolvedPlugin);\n\n\t\t\t// Validate format consistency: bundled plugins are for the marketplace\n\t\t\t// (sandboxed), so they must be standard format without trusted-only features.\n\t\t\tif (resolvedPlugin.admin?.entry) {\n\t\t\t\tconsola.error(\n\t\t\t\t\t`Plugin declares adminEntry — React admin components require native/trusted mode. ` +\n\t\t\t\t\t\t`Use Block Kit for sandboxed admin pages, or remove adminEntry.`,\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tresolvedPlugin.admin?.portableTextBlocks &&\n\t\t\t\tresolvedPlugin.admin.portableTextBlocks.length > 0\n\t\t\t) {\n\t\t\t\tconsola.error(\n\t\t\t\t\t`Plugin declares portableTextBlocks — these require native/trusted mode ` +\n\t\t\t\t\t\t`and cannot be bundled for the marketplace.`,\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconsola.success(`Plugin: ${manifest.id}@${manifest.version}`);\n\t\t\tconsola.info(\n\t\t\t\t` Capabilities: ${manifest.capabilities.length > 0 ? manifest.capabilities.join(\", \") : \"(none)\"}`,\n\t\t\t);\n\t\t\tconsola.info(\n\t\t\t\t` Hooks: ${manifest.hooks.length > 0 ? manifest.hooks.map((h) => (typeof h === \"string\" ? h : h.name)).join(\", \") : \"(none)\"}`,\n\t\t\t);\n\t\t\tconsola.info(\n\t\t\t\t` Routes: ${manifest.routes.length > 0 ? manifest.routes.map((r) => (typeof r === \"string\" ? r : r.name)).join(\", \") : \"(none)\"}`,\n\t\t\t);\n\n\t\t\t// ── Step 3: Bundle backend.js ──\n\n\t\t\tconst bundleDir = join(tmpDir, \"bundle\");\n\t\t\tawait mkdir(bundleDir, { recursive: true });\n\n\t\t\tif (backendEntry) {\n\t\t\t\tconsola.start(\"Bundling backend...\");\n\n\t\t\t\t// Create a shim for emdash so the sandbox entry doesn't pull in the\n\t\t\t\t// entire core package. definePlugin is an identity function for standard\n\t\t\t\t// format, and PluginContext is a type-only import that disappears.\n\t\t\t\tconst shimDir = join(tmpDir, \"shims\");\n\t\t\t\tawait mkdir(shimDir, { recursive: true });\n\t\t\t\tawait writeFile(join(shimDir, \"emdash.mjs\"), \"export const definePlugin = (d) => d;\\n\");\n\n\t\t\t\tawait build({\n\t\t\t\t\tconfig: false,\n\t\t\t\t\tentry: [backendEntry],\n\t\t\t\t\tformat: \"esm\",\n\t\t\t\t\toutDir: join(tmpDir, \"backend\"),\n\t\t\t\t\tdts: false,\n\t\t\t\t\tplatform: \"neutral\",\n\t\t\t\t\t// Bundle everything for a self-contained sandbox file,\n\t\t\t\t\t// but alias emdash to our shim so we don't pull in the core.\n\t\t\t\t\texternal: [],\n\t\t\t\t\talias: { emdash: join(shimDir, \"emdash.mjs\") },\n\t\t\t\t\tminify: true,\n\t\t\t\t\ttreeshake: true,\n\t\t\t\t});\n\n\t\t\t\tconst backendBaseName = basename(backendEntry).replace(TS_EXT_RE, \"\");\n\t\t\t\tconst backendOutputPath = await findBuildOutput(join(tmpDir, \"backend\"), backendBaseName);\n\n\t\t\t\tif (backendOutputPath) {\n\t\t\t\t\tawait copyFile(backendOutputPath, join(bundleDir, \"backend.js\"));\n\t\t\t\t\tconsola.success(\"Built backend.js\");\n\t\t\t\t} else {\n\t\t\t\t\tconsola.error(\"Backend build produced no output\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconsola.warn(\"No sandbox entry found — bundle will have no backend.js\");\n\t\t\t\tconsola.warn(' Add a \"sandbox-entry.ts\" in src/ or a \"./sandbox\" export in package.json');\n\t\t\t}\n\n\t\t\t// ── Step 4: Bundle admin.js ──\n\n\t\t\tif (adminEntry) {\n\t\t\t\tconsola.start(\"Bundling admin...\");\n\t\t\t\tawait build({\n\t\t\t\t\tconfig: false,\n\t\t\t\t\tentry: [adminEntry],\n\t\t\t\t\tformat: \"esm\",\n\t\t\t\t\toutDir: join(tmpDir, \"admin\"),\n\t\t\t\t\tdts: false,\n\t\t\t\t\tplatform: \"neutral\",\n\t\t\t\t\texternal: [],\n\t\t\t\t\tminify: true,\n\t\t\t\t\ttreeshake: true,\n\t\t\t\t});\n\n\t\t\t\tconst adminBaseName = basename(adminEntry).replace(TS_EXT_RE, \"\");\n\t\t\t\tconst adminOutputPath = await findBuildOutput(join(tmpDir, \"admin\"), adminBaseName);\n\n\t\t\t\tif (adminOutputPath) {\n\t\t\t\t\tawait copyFile(adminOutputPath, join(bundleDir, \"admin.js\"));\n\t\t\t\t\tconsola.success(\"Built admin.js\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// ── Step 5: Write manifest.json ──\n\n\t\t\tawait writeFile(join(bundleDir, \"manifest.json\"), JSON.stringify(manifest, null, 2));\n\n\t\t\t// ── Step 6: Collect assets ──\n\n\t\t\tconsola.start(\"Collecting assets...\");\n\n\t\t\t// README.md\n\t\t\tconst readmePath = join(pluginDir, \"README.md\");\n\t\t\tif (await fileExists(readmePath)) {\n\t\t\t\tawait copyFile(readmePath, join(bundleDir, \"README.md\"));\n\t\t\t\tconsola.success(\"Included README.md\");\n\t\t\t}\n\n\t\t\t// icon.png\n\t\t\tconst iconPath = join(pluginDir, \"icon.png\");\n\t\t\tif (await fileExists(iconPath)) {\n\t\t\t\tconst iconBuf = await readFile(iconPath);\n\t\t\t\tconst dims = readImageDimensions(iconBuf);\n\t\t\t\tif (!dims) {\n\t\t\t\t\tconsola.warn(\"icon.png is not a valid PNG — skipping\");\n\t\t\t\t} else if (dims[0] !== ICON_SIZE || dims[1] !== ICON_SIZE) {\n\t\t\t\t\tconsola.warn(\n\t\t\t\t\t\t`icon.png is ${dims[0]}x${dims[1]}, expected ${ICON_SIZE}x${ICON_SIZE} — including anyway`,\n\t\t\t\t\t);\n\t\t\t\t\tawait copyFile(iconPath, join(bundleDir, \"icon.png\"));\n\t\t\t\t} else {\n\t\t\t\t\tawait copyFile(iconPath, join(bundleDir, \"icon.png\"));\n\t\t\t\t\tconsola.success(\"Included icon.png\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// screenshots/\n\t\t\tconst screenshotsDir = join(pluginDir, \"screenshots\");\n\t\t\tif (await fileExists(screenshotsDir)) {\n\t\t\t\tconst screenshotFiles = (await readdir(screenshotsDir))\n\t\t\t\t\t.filter((f) => {\n\t\t\t\t\t\tconst ext = extname(f).toLowerCase();\n\t\t\t\t\t\treturn ext === \".png\" || ext === \".jpg\" || ext === \".jpeg\";\n\t\t\t\t\t})\n\t\t\t\t\t.toSorted()\n\t\t\t\t\t.slice(0, MAX_SCREENSHOTS);\n\n\t\t\t\tif (screenshotFiles.length > 0) {\n\t\t\t\t\tawait mkdir(join(bundleDir, \"screenshots\"), { recursive: true });\n\n\t\t\t\t\tfor (const file of screenshotFiles) {\n\t\t\t\t\t\tconst filePath = join(screenshotsDir, file);\n\t\t\t\t\t\tconst buf = await readFile(filePath);\n\n\t\t\t\t\t\tconst dims = readImageDimensions(buf);\n\n\t\t\t\t\t\tif (!dims) {\n\t\t\t\t\t\t\tconsola.warn(`screenshots/${file} — cannot read dimensions, skipping`);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (dims[0] > MAX_SCREENSHOT_WIDTH || dims[1] > MAX_SCREENSHOT_HEIGHT) {\n\t\t\t\t\t\t\tconsola.warn(\n\t\t\t\t\t\t\t\t`screenshots/${file} is ${dims[0]}x${dims[1]}, max ${MAX_SCREENSHOT_WIDTH}x${MAX_SCREENSHOT_HEIGHT} — including anyway`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait copyFile(filePath, join(bundleDir, \"screenshots\", file));\n\t\t\t\t\t}\n\n\t\t\t\t\tconsola.success(`Included ${screenshotFiles.length} screenshot(s)`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// ── Step 7: Validation ──\n\n\t\t\tconsola.start(\"Validating bundle...\");\n\t\t\tlet hasErrors = false;\n\n\t\t\t// Check that package.json exports point to built files, not source.\n\t\t\t// Plugins published to npm with source exports will break site builds\n\t\t\t// because the sandbox module generator embeds the resolved file as-is.\n\t\t\tif (pkg.exports) {\n\t\t\t\tfor (const issue of findSourceExports(pkg.exports)) {\n\t\t\t\t\tconsola.error(\n\t\t\t\t\t\t`Export \"${issue.exportPath}\" points to source (${issue.resolvedPath}). ` +\n\t\t\t\t\t\t\t`Package exports must point to built files (e.g. dist/*.mjs). ` +\n\t\t\t\t\t\t\t`Add a build step and update the exports map.`,\n\t\t\t\t\t);\n\t\t\t\t\thasErrors = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check for Node.js builtins in backend.js\n\t\t\tconst backendPath = join(bundleDir, \"backend.js\");\n\t\t\tif (await fileExists(backendPath)) {\n\t\t\t\tconst backendCode = await readFile(backendPath, \"utf-8\");\n\t\t\t\tconst builtins = findNodeBuiltinImports(backendCode);\n\t\t\t\tif (builtins.length > 0) {\n\t\t\t\t\tconsola.error(`backend.js imports Node.js built-in modules: ${builtins.join(\", \")}`);\n\t\t\t\t\tconsola.error(\"Sandboxed plugins cannot use Node.js APIs\");\n\t\t\t\t\thasErrors = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check capabilities warnings — use canonical names. Deprecated\n\t\t\t// names are accepted (and warned about separately below) so we\n\t\t\t// also check the legacy aliases here for the duration of the\n\t\t\t// deprecation window.\n\t\t\tconst declaresUnrestricted =\n\t\t\t\tmanifest.capabilities.includes(\"network:request:unrestricted\") ||\n\t\t\t\tmanifest.capabilities.includes(\"network:fetch:any\");\n\t\t\tconst declaresHostRestricted =\n\t\t\t\tmanifest.capabilities.includes(\"network:request\") ||\n\t\t\t\tmanifest.capabilities.includes(\"network:fetch\");\n\t\t\tif (declaresUnrestricted) {\n\t\t\t\tconsola.warn(\n\t\t\t\t\t\"Plugin declares unrestricted network access (network:request:unrestricted) — it can make requests to any host\",\n\t\t\t\t);\n\t\t\t} else if (declaresHostRestricted && manifest.allowedHosts.length === 0) {\n\t\t\t\tconsola.warn(\n\t\t\t\t\t\"Plugin declares network:request capability but no allowedHosts — all requests will be blocked\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Warn for each deprecated capability used. The warning points\n\t\t\t// to the new name so the fix is mechanical. We continue (not\n\t\t\t// error) here — the hard fail lives in `publish` so authors\n\t\t\t// can still build and test locally.\n\t\t\tconst deprecatedCaps = manifest.capabilities.filter(isDeprecatedCapability);\n\t\t\tif (deprecatedCaps.length > 0) {\n\t\t\t\tconsola.warn(\"Plugin uses deprecated capability names. Rename them before publishing:\");\n\t\t\t\tfor (const cap of deprecatedCaps) {\n\t\t\t\t\tconst replacement = CAPABILITY_RENAMES[cap];\n\t\t\t\t\tconsola.warn(` ${cap} → ${replacement}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check for features that won't work in sandboxed mode\n\t\t\tif (\n\t\t\t\tresolvedPlugin.admin?.portableTextBlocks &&\n\t\t\t\tresolvedPlugin.admin.portableTextBlocks.length > 0\n\t\t\t) {\n\t\t\t\tconsola.warn(\n\t\t\t\t\t\"Plugin declares portableTextBlocks — these require trusted mode and will be ignored in sandboxed plugins\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (resolvedPlugin.admin?.entry) {\n\t\t\t\tconsola.warn(\n\t\t\t\t\t\"Plugin declares admin.entry — custom React components require trusted mode. Use Block Kit for sandboxed admin pages\",\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Check for page:fragments hook — trusted-only, not allowed in sandbox\n\t\t\tif (resolvedPlugin.hooks[\"page:fragments\"]) {\n\t\t\t\tconsola.warn(\n\t\t\t\t\t\"Plugin declares page:fragments hook — this is trusted-only and will not work in sandboxed mode\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Check: if plugin declares admin pages or widgets, it must have an \"admin\" route\n\t\t\tconst hasAdminPages = (manifest.admin?.pages?.length ?? 0) > 0;\n\t\t\tconst hasAdminWidgets = (manifest.admin?.widgets?.length ?? 0) > 0;\n\t\t\tif (hasAdminPages || hasAdminWidgets) {\n\t\t\t\tconst routeNames = manifest.routes.map((r: string | { name: string }) =>\n\t\t\t\t\ttypeof r === \"string\" ? r : r.name,\n\t\t\t\t);\n\t\t\t\tif (!routeNames.includes(\"admin\")) {\n\t\t\t\t\tconsola.error(\n\t\t\t\t\t\t`Plugin declares ${hasAdminPages ? \"adminPages\" : \"\"}${hasAdminPages && hasAdminWidgets ? \" and \" : \"\"}${hasAdminWidgets ? \"adminWidgets\" : \"\"} ` +\n\t\t\t\t\t\t\t`but the sandbox entry has no \"admin\" route. ` +\n\t\t\t\t\t\t\t`Add an admin route handler to serve Block Kit pages.`,\n\t\t\t\t\t);\n\t\t\t\t\thasErrors = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Bundle size caps (RFC 0001 §\"Bundle size limits\").\n\t\t\tconst bundleEntries = await collectBundleEntries(bundleDir);\n\t\t\tconst sizeViolations = validateBundleSize(bundleEntries);\n\t\t\tif (sizeViolations.length > 0) {\n\t\t\t\tfor (const v of sizeViolations) consola.error(v);\n\t\t\t\thasErrors = true;\n\t\t\t} else {\n\t\t\t\tconsola.info(\n\t\t\t\t\t`Bundle size: ${formatBytes(totalBundleBytes(bundleEntries))} across ${bundleEntries.length} file${bundleEntries.length === 1 ? \"\" : \"s\"}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (hasErrors) {\n\t\t\t\tconsola.error(\"Bundle validation failed\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconsola.success(\"Validation passed\");\n\n\t\t\tif (validateOnly) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// ── Step 8: Create tarball ──\n\n\t\t\tawait mkdir(outDir, { recursive: true });\n\t\t\tconst tarballName = `${manifest.id.replace(SLASH_RE, \"-\").replace(LEADING_AT_RE, \"\")}-${manifest.version}.tar.gz`;\n\t\t\tconst tarballPath = join(outDir, tarballName);\n\n\t\t\tconsola.start(\"Creating tarball...\");\n\t\t\tawait createTarball(bundleDir, tarballPath);\n\n\t\t\tconst tarballStat = await stat(tarballPath);\n\t\t\tconst tarballSizeKB = (tarballStat.size / 1024).toFixed(1);\n\n\t\t\t// Calculate checksum\n\t\t\tconst tarballBuf = await readFile(tarballPath);\n\t\t\tconst checksum = createHash(\"sha256\").update(tarballBuf).digest(\"hex\");\n\n\t\t\tconsola.success(`Created ${tarballName} (${tarballSizeKB}KB)`);\n\t\t\tconsola.info(` SHA-256: ${checksum}`);\n\t\t\tconsola.info(` Path: ${tarballPath}`);\n\t\t} finally {\n\t\t\tif (tmpDir.endsWith(\".emdash-bundle-tmp\")) {\n\t\t\t\tawait rm(tmpDir, { recursive: true, force: true });\n\t\t\t}\n\t\t}\n\t},\n});\n","/**\n * emdash plugin init\n *\n * Scaffold a new EmDash plugin. Generates the sandboxed-format boilerplate:\n * src/index.ts -- descriptor factory\n * src/sandbox-entry.ts -- definePlugin({ hooks, routes })\n * package.json\n * tsconfig.json\n *\n * Use --format=native (or --native) to generate native-format boilerplate\n * instead (createPlugin + React admin). When neither is passed and stdout\n * is a TTY, the user is prompted to choose.\n *\n */\n\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { resolve, join, basename } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport consola from \"consola\";\n\nimport { fileExists } from \"./bundle-utils.js\";\n\nconst SLUG_RE = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;\nconst SCOPE_RE = /^@[^/]+\\//;\n\ntype PluginFormat = \"standard\" | \"native\";\n\nexport const pluginInitCommand = defineCommand({\n\tmeta: {\n\t\tname: \"init\",\n\t\tdescription: \"Scaffold a new plugin\",\n\t},\n\targs: {\n\t\tdir: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Directory to create the plugin in (default: current directory)\",\n\t\t\tdefault: \".\",\n\t\t},\n\t\tname: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Plugin name/id (e.g. my-plugin or @org/my-plugin)\",\n\t\t},\n\t\tformat: {\n\t\t\ttype: \"string\",\n\t\t\tdescription:\n\t\t\t\t\"Plugin format: sandboxed or native. Prompts when running interactively if not set.\",\n\t\t\tvalueHint: \"sandboxed|native\",\n\t\t},\n\t\tnative: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Shortcut for --format=native\",\n\t\t\tdefault: false,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst targetDir = resolve(args.dir);\n\n\t\tconst format = await resolveFormat(args.format, args.native);\n\t\tif (!format) {\n\t\t\tconsola.info(\"Cancelled\");\n\t\t\treturn;\n\t\t}\n\t\tconst isNative = format === \"native\";\n\n\t\t// Derive plugin name from --name or directory name\n\t\tlet pluginName = args.name || basename(targetDir);\n\t\tif (!pluginName || pluginName === \".\") {\n\t\t\tpluginName = basename(resolve(\".\"));\n\t\t}\n\n\t\t// Strip scope for the slug\n\t\tconst slug = pluginName.replace(SCOPE_RE, \"\");\n\t\tif (!SLUG_RE.test(slug)) {\n\t\t\tconsola.error(\n\t\t\t\t`Invalid plugin name \"${pluginName}\". ` +\n\t\t\t\t\t\"Use lowercase letters, numbers, and hyphens (e.g. my-plugin).\",\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// Check if directory already has files\n\t\tconst srcDir = join(targetDir, \"src\");\n\t\tconst pkgPath = join(targetDir, \"package.json\");\n\t\tif (await fileExists(pkgPath)) {\n\t\t\tconsola.error(`package.json already exists in ${targetDir}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconsola.start(`Scaffolding ${isNative ? \"native\" : \"sandboxed\"} plugin: ${pluginName}`);\n\n\t\tawait mkdir(srcDir, { recursive: true });\n\n\t\tif (isNative) {\n\t\t\tawait scaffoldNative(targetDir, srcDir, pluginName, slug);\n\t\t} else {\n\t\t\tawait scaffoldStandard(targetDir, srcDir, pluginName, slug);\n\t\t}\n\n\t\tconsola.success(`Plugin scaffolded in ${targetDir}`);\n\t\tconsola.info(\"Next steps:\");\n\t\tconst steps: string[] = [];\n\t\tif (args.dir !== \".\") steps.push(`cd ${args.dir}`);\n\t\tsteps.push(\"pnpm install\");\n\t\tsteps.push(\n\t\t\tisNative\n\t\t\t\t? \"Edit src/index.ts to add hooks and routes\"\n\t\t\t\t: \"Edit src/sandbox-entry.ts to add hooks and routes\",\n\t\t);\n\t\tsteps.push(\"pnpm build\");\n\t\tif (!isNative) steps.push(\"emdash plugin validate --dir .\");\n\t\tsteps.forEach((step, i) => consola.info(` ${i + 1}. ${step}`));\n\t},\n});\n\nasync function resolveFormat(\n\tformatArg: string | undefined,\n\tnativeFlag: boolean,\n): Promise<PluginFormat | null> {\n\tif (formatArg) {\n\t\tconst normalized = formatArg.toLowerCase();\n\t\tlet parsed: PluginFormat;\n\t\tif (normalized === \"native\") {\n\t\t\tparsed = \"native\";\n\t\t} else if (normalized === \"sandboxed\" || normalized === \"standard\") {\n\t\t\tparsed = \"standard\";\n\t\t} else {\n\t\t\tconsola.error(`Invalid --format \"${formatArg}\". Use \"sandboxed\" or \"native\".`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tif (nativeFlag && parsed !== \"native\") {\n\t\t\tconsola.error(`Conflicting flags: --native and --format=${formatArg}. Pass only one.`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t\treturn parsed;\n\t}\n\tif (nativeFlag) return \"native\";\n\n\tif (!process.stdout.isTTY) return \"standard\";\n\n\tconst choice = await consola.prompt(\"Which plugin format?\", {\n\t\ttype: \"select\",\n\t\tinitial: \"standard\",\n\t\toptions: [\n\t\t\t{\n\t\t\t\tlabel: \"Sandboxed\",\n\t\t\t\tvalue: \"standard\",\n\t\t\t\thint: \"runs in an isolated sandbox; safe to install from the marketplace\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: \"Native\",\n\t\t\t\tvalue: \"native\",\n\t\t\t\thint: \"full runtime access; install from npm\",\n\t\t\t},\n\t\t],\n\t\tcancel: \"null\",\n\t});\n\tif (choice === null) return null;\n\treturn choice as PluginFormat;\n}\n\nfunction camelCase(slug: string): string {\n\treturn slug\n\t\t.split(\"-\")\n\t\t.map((s, i) => (i === 0 ? s : s[0].toUpperCase() + s.slice(1)))\n\t\t.join(\"\");\n}\n\nfunction pascalCase(slug: string): string {\n\treturn slug\n\t\t.split(\"-\")\n\t\t.map((s) => s[0].toUpperCase() + s.slice(1))\n\t\t.join(\"\");\n}\n\nconst TSCONFIG = {\n\tcompilerOptions: {\n\t\ttarget: \"ES2022\",\n\t\tmodule: \"preserve\",\n\t\tmoduleResolution: \"bundler\",\n\t\tstrict: true,\n\t\tesModuleInterop: true,\n\t\tdeclaration: true,\n\t\toutDir: \"./dist\",\n\t\trootDir: \"./src\",\n\t},\n\tinclude: [\"src/**/*\"],\n\texclude: [\"node_modules\", \"dist\"],\n} as const;\n\nconst TSDOWN_VERSION = \"^0.20.0\";\nconst TYPESCRIPT_VERSION = \"^5.9.0\";\n\n// ── Sandboxed format scaffolding ─────────────────────────────────\n\nasync function scaffoldStandard(\n\ttargetDir: string,\n\tsrcDir: string,\n\tpluginName: string,\n\tslug: string,\n): Promise<void> {\n\tconst fnName = camelCase(slug);\n\n\tawait writeFile(\n\t\tjoin(targetDir, \"package.json\"),\n\t\tJSON.stringify(\n\t\t\t{\n\t\t\t\tname: pluginName,\n\t\t\t\tversion: \"0.1.0\",\n\t\t\t\ttype: \"module\",\n\t\t\t\tmain: \"./dist/index.mjs\",\n\t\t\t\texports: {\n\t\t\t\t\t\".\": {\n\t\t\t\t\t\ttypes: \"./dist/index.d.mts\",\n\t\t\t\t\t\timport: \"./dist/index.mjs\",\n\t\t\t\t\t},\n\t\t\t\t\t\"./sandbox\": {\n\t\t\t\t\t\ttypes: \"./dist/sandbox-entry.d.mts\",\n\t\t\t\t\t\timport: \"./dist/sandbox-entry.mjs\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tfiles: [\"dist\"],\n\t\t\t\tscripts: {\n\t\t\t\t\tbuild: \"tsdown src/index.ts src/sandbox-entry.ts --format esm --dts --clean\",\n\t\t\t\t\tdev: \"tsdown src/index.ts src/sandbox-entry.ts --format esm --dts --watch\",\n\t\t\t\t\ttypecheck: \"tsc --noEmit\",\n\t\t\t\t},\n\t\t\t\tkeywords: [\"emdash\", \"emdash-plugin\"],\n\t\t\t\tlicense: \"MIT\",\n\t\t\t\tpeerDependencies: {\n\t\t\t\t\temdash: \"*\",\n\t\t\t\t},\n\t\t\t\tdevDependencies: {\n\t\t\t\t\temdash: \"*\",\n\t\t\t\t\ttsdown: TSDOWN_VERSION,\n\t\t\t\t\ttypescript: TYPESCRIPT_VERSION,\n\t\t\t\t},\n\t\t\t},\n\t\t\tnull,\n\t\t\t\"\\t\",\n\t\t) + \"\\n\",\n\t);\n\n\tawait writeFile(join(targetDir, \"tsconfig.json\"), JSON.stringify(TSCONFIG, null, \"\\t\") + \"\\n\");\n\n\tawait writeFile(\n\t\tjoin(srcDir, \"index.ts\"),\n\t\t`import type { PluginDescriptor } from \"emdash\";\n\nexport function ${fnName}Plugin(): PluginDescriptor {\n\\treturn {\n\\t\\tid: \"${slug}\",\n\\t\\tversion: \"0.1.0\",\n\\t\\tformat: \"standard\",\n\\t\\tentrypoint: \"${pluginName}/sandbox\",\n\n\\t\\tcapabilities: [\"content:read\"],\n\\t\\tstorage: {\n\\t\\t\\tevents: { indexes: [\"timestamp\"] },\n\\t\\t},\n\\t};\n}\n`,\n\t);\n\n\tawait writeFile(\n\t\tjoin(srcDir, \"sandbox-entry.ts\"),\n\t\t`import { definePlugin } from \"emdash\";\nimport type { PluginContext } from \"emdash\";\n\ninterface ContentSaveEvent {\n\\tcollection: string;\n\\tcontent: { id: string };\n\\tisNew: boolean;\n}\n\nexport default definePlugin({\n\\thooks: {\n\\t\\t\"content:afterSave\": {\n\\t\\t\\thandler: async (event: ContentSaveEvent, ctx: PluginContext) => {\n\\t\\t\\t\\tctx.log.info(\"Content saved\", {\n\\t\\t\\t\\t\\tcollection: event.collection,\n\\t\\t\\t\\t\\tid: event.content.id,\n\\t\\t\\t\\t});\n\n\\t\\t\\t\\tawait ctx.storage.events.put(\\`save-\\${Date.now()}\\`, {\n\\t\\t\\t\\t\\ttimestamp: new Date().toISOString(),\n\\t\\t\\t\\t\\tcollection: event.collection,\n\\t\\t\\t\\t\\tcontentId: event.content.id,\n\\t\\t\\t\\t});\n\\t\\t\\t},\n\\t\\t},\n\\t},\n\n\\troutes: {\n\\t\\trecent: {\n\\t\\t\\thandler: async (_routeCtx, ctx: PluginContext) => {\n\\t\\t\\t\\tconst result = await ctx.storage.events.query({\n\\t\\t\\t\\t\\torderBy: { timestamp: \"desc\" },\n\\t\\t\\t\\t\\tlimit: 10,\n\\t\\t\\t\\t});\n\\t\\t\\t\\treturn { events: result.items };\n\\t\\t\\t},\n\\t\\t},\n\\t},\n});\n`,\n\t);\n}\n\n// ── Native format scaffolding ────────────────────────────────────\n\nasync function scaffoldNative(\n\ttargetDir: string,\n\tsrcDir: string,\n\tpluginName: string,\n\tslug: string,\n): Promise<void> {\n\tconst fnName = camelCase(slug);\n\tconst typeName = pascalCase(slug);\n\n\tawait writeFile(\n\t\tjoin(targetDir, \"package.json\"),\n\t\tJSON.stringify(\n\t\t\t{\n\t\t\t\tname: pluginName,\n\t\t\t\tversion: \"0.1.0\",\n\t\t\t\ttype: \"module\",\n\t\t\t\tmain: \"./dist/index.mjs\",\n\t\t\t\texports: {\n\t\t\t\t\t\".\": {\n\t\t\t\t\t\ttypes: \"./dist/index.d.mts\",\n\t\t\t\t\t\timport: \"./dist/index.mjs\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tfiles: [\"dist\"],\n\t\t\t\tscripts: {\n\t\t\t\t\tbuild: \"tsdown src/index.ts --format esm --dts --clean\",\n\t\t\t\t\tdev: \"tsdown src/index.ts --format esm --dts --watch\",\n\t\t\t\t\ttypecheck: \"tsc --noEmit\",\n\t\t\t\t},\n\t\t\t\tkeywords: [\"emdash\", \"emdash-plugin\"],\n\t\t\t\tlicense: \"MIT\",\n\t\t\t\tpeerDependencies: {\n\t\t\t\t\temdash: \"*\",\n\t\t\t\t},\n\t\t\t\tdevDependencies: {\n\t\t\t\t\temdash: \"*\",\n\t\t\t\t\ttsdown: TSDOWN_VERSION,\n\t\t\t\t\ttypescript: TYPESCRIPT_VERSION,\n\t\t\t\t},\n\t\t\t},\n\t\t\tnull,\n\t\t\t\"\\t\",\n\t\t) + \"\\n\",\n\t);\n\n\tawait writeFile(join(targetDir, \"tsconfig.json\"), JSON.stringify(TSCONFIG, null, \"\\t\") + \"\\n\");\n\n\tawait writeFile(\n\t\tjoin(srcDir, \"index.ts\"),\n\t\t`import { definePlugin } from \"emdash\";\nimport type { PluginDescriptor } from \"emdash\";\n\nexport interface ${typeName}Options {\n\\tenabled?: boolean;\n}\n\nexport function ${fnName}Plugin(options: ${typeName}Options = {}): PluginDescriptor<${typeName}Options> {\n\\treturn {\n\\t\\tid: \"${slug}\",\n\\t\\tversion: \"0.1.0\",\n\\t\\tformat: \"native\",\n\\t\\tentrypoint: \"${pluginName}\",\n\\t\\toptions,\n\\t};\n}\n\nexport function createPlugin(options: ${typeName}Options = {}) {\n\\treturn definePlugin({\n\\t\\tid: \"${slug}\",\n\\t\\tversion: \"0.1.0\",\n\n\\t\\tcapabilities: [\"content:read\"],\n\\t\\tstorage: {\n\\t\\t\\tevents: { indexes: [\"createdAt\"] },\n\\t\\t},\n\n\\t\\thooks: {\n\\t\\t\\t\"content:afterSave\": async (event, ctx) => {\n\\t\\t\\t\\tif (options.enabled === false) return;\n\\t\\t\\t\\tawait ctx.storage.events.put(\\`evt_\\${Date.now()}\\`, {\n\\t\\t\\t\\t\\tcollection: event.collection,\n\\t\\t\\t\\t\\tcontentId: event.content.id,\n\\t\\t\\t\\t\\tcreatedAt: new Date().toISOString(),\n\\t\\t\\t\\t});\n\\t\\t\\t},\n\\t\\t},\n\n\\t\\troutes: {\n\\t\\t\\trecent: {\n\\t\\t\\t\\thandler: async (ctx) => {\n\\t\\t\\t\\t\\tconst result = await ctx.storage.events.query({\n\\t\\t\\t\\t\\t\\torderBy: { createdAt: \"desc\" },\n\\t\\t\\t\\t\\t\\tlimit: 10,\n\\t\\t\\t\\t\\t});\n\\t\\t\\t\\t\\treturn { events: result.items };\n\\t\\t\\t\\t},\n\\t\\t\\t},\n\\t\\t},\n\\t});\n}\n\nexport default createPlugin;\n`,\n\t);\n}\n","/**\n * emdash plugin validate\n *\n * Runs bundle validation without producing a tarball.\n * Thin wrapper around `emdash plugin bundle --validate-only`.\n *\n */\n\nimport { defineCommand, runCommand } from \"citty\";\n\nimport { bundleCommand } from \"./bundle.js\";\n\nexport const pluginValidateCommand = defineCommand({\n\tmeta: {\n\t\tname: \"validate\",\n\t\tdescription: \"Validate a plugin without producing a tarball (same checks as bundle)\",\n\t},\n\targs: {\n\t\tdir: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Plugin directory (default: current directory)\",\n\t\t\tdefault: \".\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\t// Delegate to the bundle command with validateOnly flag\n\t\tawait runCommand(bundleCommand, {\n\t\t\trawArgs: [\"--dir\", args.dir, \"--validateOnly\"],\n\t\t});\n\t},\n});\n","/**\n * emdash plugin publish\n *\n * Publishes a plugin tarball to the EmDash Marketplace.\n *\n * Flow:\n * 1. Resolve tarball (from --tarball path, or build via `emdash plugin bundle`)\n * 2. Read manifest.json from tarball to show summary\n * 3. Authenticate (stored credential or GitHub device flow)\n * 4. Pre-publish validation (check plugin exists, version not published)\n * 5. Upload via multipart POST\n * 6. Display audit results\n */\n\nimport { readFile, stat } from \"node:fs/promises\";\nimport { resolve, basename } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport consola from \"consola\";\nimport { createGzipDecoder, unpackTar } from \"modern-tar\";\nimport pc from \"picocolors\";\n\nimport { pluginManifestBaseSchema } from \"../../plugins/manifest-schema.js\";\nimport { CAPABILITY_RENAMES, isDeprecatedCapability } from \"../../plugins/types.js\";\nimport {\n\tgetMarketplaceCredential,\n\tsaveMarketplaceCredential,\n\tremoveMarketplaceCredential,\n} from \"../credentials.js\";\n\nconst DEFAULT_REGISTRY = \"https://marketplace.emdashcms.com\";\n\n// ── GitHub Device Flow ──────────────────────────────────────────\n\ninterface DeviceCodeResponse {\n\tdevice_code: string;\n\tuser_code: string;\n\tverification_uri: string;\n\texpires_in: number;\n\tinterval: number;\n}\n\ninterface GitHubTokenResponse {\n\taccess_token?: string;\n\ttoken_type?: string;\n\terror?: string;\n\terror_description?: string;\n\tinterval?: number;\n}\n\ninterface MarketplaceAuthResponse {\n\ttoken: string;\n\tauthor: {\n\t\tid: string;\n\t\tname: string;\n\t\tavatarUrl: string;\n\t};\n}\n\ninterface AuthDiscovery {\n\tgithub: {\n\t\tclientId: string;\n\t\tdeviceAuthorizationEndpoint: string;\n\t\ttokenEndpoint: string;\n\t};\n\tmarketplace: {\n\t\tdeviceTokenEndpoint: string;\n\t};\n}\n\n/**\n * Authenticate with the marketplace via GitHub Device Flow.\n * Returns the marketplace JWT and author info.\n */\nasync function authenticateViaDeviceFlow(registryUrl: string): Promise<MarketplaceAuthResponse> {\n\t// Step 1: Fetch auth discovery to get GitHub client_id\n\tconsola.start(\"Fetching auth configuration...\");\n\tconst discoveryRes = await fetch(new URL(\"/api/v1/auth/discovery\", registryUrl));\n\tif (!discoveryRes.ok) {\n\t\tthrow new Error(`Marketplace unreachable: ${discoveryRes.status} ${discoveryRes.statusText}`);\n\t}\n\tconst discovery = (await discoveryRes.json()) as AuthDiscovery;\n\n\t// Step 2: Request device code from GitHub\n\tconst deviceRes = await fetch(discovery.github.deviceAuthorizationEndpoint, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAccept: \"application/json\",\n\t\t},\n\t\tbody: JSON.stringify({\n\t\t\tclient_id: discovery.github.clientId,\n\t\t\tscope: \"read:user user:email\",\n\t\t}),\n\t});\n\n\tif (!deviceRes.ok) {\n\t\tthrow new Error(`GitHub device flow failed: ${deviceRes.status}`);\n\t}\n\n\tconst deviceCode = (await deviceRes.json()) as DeviceCodeResponse;\n\n\t// Step 3: Display instructions\n\tconsole.log();\n\tconsola.info(\"Open your browser to:\");\n\tconsole.log(` ${pc.cyan(pc.bold(deviceCode.verification_uri))}`);\n\tconsole.log();\n\tconsola.info(`Enter code: ${pc.yellow(pc.bold(deviceCode.user_code))}`);\n\tconsole.log();\n\n\t// Try to open browser\n\ttry {\n\t\tconst { execFile } = await import(\"node:child_process\");\n\t\tif (process.platform === \"darwin\") {\n\t\t\texecFile(\"open\", [deviceCode.verification_uri]);\n\t\t} else if (process.platform === \"win32\") {\n\t\t\texecFile(\"cmd\", [\"/c\", \"start\", \"\", deviceCode.verification_uri]);\n\t\t} else {\n\t\t\texecFile(\"xdg-open\", [deviceCode.verification_uri]);\n\t\t}\n\t} catch {\n\t\t// User can open manually\n\t}\n\n\t// Step 4: Poll GitHub for access token\n\tconsola.start(\"Waiting for authorization...\");\n\tconst githubToken = await pollGitHubDeviceFlow(\n\t\tdiscovery.github.tokenEndpoint,\n\t\tdiscovery.github.clientId,\n\t\tdeviceCode.device_code,\n\t\tdeviceCode.interval,\n\t\tdeviceCode.expires_in,\n\t);\n\n\t// Step 5: Exchange GitHub token for marketplace JWT\n\tconsola.start(\"Authenticating with marketplace...\");\n\tconst deviceTokenUrl = new URL(discovery.marketplace.deviceTokenEndpoint, registryUrl);\n\tconst authRes = await fetch(deviceTokenUrl, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\tbody: JSON.stringify({ access_token: githubToken }),\n\t});\n\n\tif (!authRes.ok) {\n\t\tconst body = (await authRes.json().catch(() => ({}))) as { error?: string };\n\t\tthrow new Error(`Marketplace auth failed: ${body.error ?? authRes.statusText}`);\n\t}\n\n\treturn (await authRes.json()) as MarketplaceAuthResponse;\n}\n\nasync function pollGitHubDeviceFlow(\n\ttokenEndpoint: string,\n\tclientId: string,\n\tdeviceCode: string,\n\tinterval: number,\n\texpiresIn: number,\n): Promise<string> {\n\tconst deadline = Date.now() + expiresIn * 1000;\n\tlet currentInterval = interval;\n\n\twhile (Date.now() < deadline) {\n\t\tawait new Promise((r) => setTimeout(r, currentInterval * 1000));\n\n\t\tconst res = await fetch(tokenEndpoint, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\tAccept: \"application/json\",\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\tclient_id: clientId,\n\t\t\t\tdevice_code: deviceCode,\n\t\t\t\tgrant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n\t\t\t}),\n\t\t});\n\n\t\tconst body = (await res.json()) as GitHubTokenResponse;\n\n\t\tif (body.access_token) {\n\t\t\treturn body.access_token;\n\t\t}\n\n\t\tif (body.error === \"authorization_pending\") continue;\n\t\tif (body.error === \"slow_down\") {\n\t\t\tcurrentInterval = body.interval ?? currentInterval + 5;\n\t\t\tcontinue;\n\t\t}\n\t\tif (body.error === \"expired_token\") {\n\t\t\tthrow new Error(\"Device code expired. Please try again.\");\n\t\t}\n\t\tif (body.error === \"access_denied\") {\n\t\t\tthrow new Error(\"Authorization was denied.\");\n\t\t}\n\n\t\tthrow new Error(`GitHub token exchange failed: ${body.error ?? \"unknown error\"}`);\n\t}\n\n\tthrow new Error(\"Device code expired (timeout). Please try again.\");\n}\n\n// ── Tarball reading ─────────────────────────────────────────────\n\nconst manifestSummarySchema = pluginManifestBaseSchema.pick({\n\tid: true,\n\tversion: true,\n\tcapabilities: true,\n\tallowedHosts: true,\n});\n\ntype ManifestSummary = typeof manifestSummarySchema._zod.output;\n\n/**\n * Read manifest.json from a tarball without fully extracting it.\n */\nasync function readManifestFromTarball(tarballPath: string): Promise<ManifestSummary> {\n\tconst data = await readFile(tarballPath);\n\tconst stream = new ReadableStream<Uint8Array>({\n\t\tstart(controller) {\n\t\t\tcontroller.enqueue(new Uint8Array(data.buffer, data.byteOffset, data.byteLength));\n\t\t\tcontroller.close();\n\t\t},\n\t});\n\n\tconst entries = await unpackTar(stream.pipeThrough(createGzipDecoder()), {\n\t\tfilter: (header) => header.name === \"manifest.json\",\n\t});\n\n\tconst manifest = entries.find((e) => e.header.name === \"manifest.json\");\n\tif (!manifest?.data) {\n\t\tthrow new Error(\"Tarball does not contain manifest.json\");\n\t}\n\n\tconst content = new TextDecoder().decode(manifest.data);\n\tconst parsed: unknown = JSON.parse(content);\n\tconst result = manifestSummarySchema.safeParse(parsed);\n\tif (!result.success) {\n\t\tthrow new Error(`Invalid manifest.json: ${result.error.message}`);\n\t}\n\treturn result.data;\n}\n\n// ── Audit polling helpers ───────────────────────────────────────\n\nconst POLL_INTERVAL_MS = 3000;\nconst POLL_TIMEOUT_MS = 120_000; // 2 minutes\n\ninterface VersionStatusResponse {\n\tversion: string;\n\tstatus: string;\n\taudit_verdict?: string | null;\n\taudit_id?: string | null;\n\timage_audit_verdict?: string | null;\n}\n\n/**\n * Poll the version endpoint until status leaves \"pending\" or timeout.\n * Returns the final version data, or null on timeout.\n */\nasync function pollVersionStatus(\n\tversionUrl: string,\n\ttoken: string,\n): Promise<VersionStatusResponse | null> {\n\tconst deadline = Date.now() + POLL_TIMEOUT_MS;\n\n\twhile (Date.now() < deadline) {\n\t\tawait new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));\n\n\t\ttry {\n\t\t\tconst res = await fetch(versionUrl, {\n\t\t\t\theaders: { Authorization: `Bearer ${token}` },\n\t\t\t});\n\n\t\t\tif (!res.ok) continue;\n\n\t\t\tconst data = (await res.json()) as VersionStatusResponse;\n\t\t\tif (data.status !== \"pending\") {\n\t\t\t\treturn data;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Network error — retry\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction displayAuditResults(version: VersionStatusResponse): void {\n\tconst statusColor =\n\t\tversion.status === \"published\" ? pc.green : version.status === \"flagged\" ? pc.yellow : pc.red;\n\tconsola.info(` Status: ${statusColor(version.status)}`);\n\n\tif (version.audit_verdict) {\n\t\tconst verdictColor =\n\t\t\tversion.audit_verdict === \"pass\"\n\t\t\t\t? pc.green\n\t\t\t\t: version.audit_verdict === \"warn\"\n\t\t\t\t\t? pc.yellow\n\t\t\t\t\t: pc.red;\n\t\tconsola.info(` Audit: ${verdictColor(version.audit_verdict)}`);\n\t}\n\n\tif (version.image_audit_verdict) {\n\t\tconst verdictColor =\n\t\t\tversion.image_audit_verdict === \"pass\"\n\t\t\t\t? pc.green\n\t\t\t\t: version.image_audit_verdict === \"warn\"\n\t\t\t\t\t? pc.yellow\n\t\t\t\t\t: pc.red;\n\t\tconsola.info(` Image audit: ${verdictColor(version.image_audit_verdict)}`);\n\t}\n}\n\nfunction displayInlineAuditResults(\n\taudit: {\n\t\tverdict: string;\n\t\triskScore: number;\n\t\tsummary: string;\n\t\tfindings: { category: string; severity: string; description: string }[];\n\t},\n\timageAudit: { verdict: string } | null,\n): void {\n\tconst verdictColor =\n\t\taudit.verdict === \"pass\" ? pc.green : audit.verdict === \"warn\" ? pc.yellow : pc.red;\n\tconsola.info(` Audit: ${verdictColor(audit.verdict)} (risk: ${audit.riskScore}/100)`);\n\tif (audit.findings.length > 0) {\n\t\tfor (const finding of audit.findings) {\n\t\t\tconst icon = finding.severity === \"high\" ? pc.red(\"!\") : pc.yellow(\"~\");\n\t\t\tconsola.info(` ${icon} [${finding.category}] ${finding.description}`);\n\t\t}\n\t}\n\n\tif (imageAudit) {\n\t\tconst imgColor =\n\t\t\timageAudit.verdict === \"pass\" ? pc.green : imageAudit.verdict === \"warn\" ? pc.yellow : pc.red;\n\t\tconsola.info(` Image audit: ${imgColor(imageAudit.verdict)}`);\n\t}\n}\n\n// ── Publish command ─────────────────────────────────────────────\n\nexport const publishCommand = defineCommand({\n\tmeta: {\n\t\tname: \"publish\",\n\t\tdescription: \"Publish a plugin to the EmDash Marketplace\",\n\t},\n\targs: {\n\t\ttarball: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Path to plugin tarball (default: build first via `emdash plugin bundle`)\",\n\t\t},\n\t\tdir: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Plugin directory (used with --build, default: current directory)\",\n\t\t\tdefault: process.cwd(),\n\t\t},\n\t\tbuild: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Build the plugin before publishing\",\n\t\t\tdefault: false,\n\t\t},\n\t\tregistry: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Marketplace registry URL\",\n\t\t\tdefault: DEFAULT_REGISTRY,\n\t\t},\n\t\t\"no-wait\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Exit immediately after upload without waiting for audit (useful for CI)\",\n\t\t\tdefault: false,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst registryUrl = args.registry;\n\n\t\t// ── Step 1: Resolve tarball ──\n\n\t\tlet tarballPath: string;\n\n\t\tif (args.tarball) {\n\t\t\ttarballPath = resolve(args.tarball);\n\t\t} else if (args.build) {\n\t\t\t// Build first, then find the output tarball\n\t\t\tconsola.start(\"Building plugin...\");\n\t\t\tconst pluginDir = resolve(args.dir);\n\t\t\ttry {\n\t\t\t\tconst { runCommand } = await import(\"citty\");\n\t\t\t\tconst { bundleCommand } = await import(\"./bundle.js\");\n\t\t\t\tawait runCommand(bundleCommand, {\n\t\t\t\t\trawArgs: [\"--dir\", pluginDir],\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\tconsola.error(\"Build failed\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Find the tarball in dist/\n\t\t\tconst { readdir } = await import(\"node:fs/promises\");\n\t\t\tconst distDir = resolve(pluginDir, \"dist\");\n\t\t\tconst files = await readdir(distDir);\n\t\t\tconst tarball = files.find((f) => f.endsWith(\".tar.gz\"));\n\t\t\tif (!tarball) {\n\t\t\t\tconsola.error(\"Build succeeded but no .tar.gz found in dist/\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\ttarballPath = resolve(distDir, tarball);\n\t\t} else {\n\t\t\t// Look for an existing tarball in dist/\n\t\t\tconst pluginDir = resolve(args.dir);\n\t\t\tconst { readdir } = await import(\"node:fs/promises\");\n\t\t\ttry {\n\t\t\t\tconst distDir = resolve(pluginDir, \"dist\");\n\t\t\t\tconst files = await readdir(distDir);\n\t\t\t\tconst tarball = files.find((f) => f.endsWith(\".tar.gz\"));\n\t\t\t\tif (tarball) {\n\t\t\t\t\ttarballPath = resolve(distDir, tarball);\n\t\t\t\t} else {\n\t\t\t\t\tconsola.error(\"No tarball found. Run `emdash plugin bundle` first or use --build.\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\tconsola.error(\"No dist/ directory found. Run `emdash plugin bundle` first or use --build.\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t}\n\n\t\tconst tarballStat = await stat(tarballPath);\n\t\tconst sizeKB = (tarballStat.size / 1024).toFixed(1);\n\t\tconsola.info(`Tarball: ${pc.dim(tarballPath)} (${sizeKB}KB)`);\n\n\t\t// ── Step 2: Read manifest from tarball ──\n\n\t\tconst manifest = await readManifestFromTarball(tarballPath);\n\t\tconsole.log();\n\t\tconsola.info(`Plugin: ${pc.bold(`${manifest.id}@${manifest.version}`)}`);\n\t\tif (manifest.capabilities.length > 0) {\n\t\t\tconsola.info(`Capabilities: ${manifest.capabilities.join(\", \")}`);\n\t\t}\n\t\tif (manifest.allowedHosts?.length) {\n\t\t\tconsola.info(`Allowed hosts: ${manifest.allowedHosts.join(\", \")}`);\n\t\t}\n\t\tconsole.log();\n\n\t\t// ── Step 2.5: Hard-fail on deprecated capability names ──\n\t\t//\n\t\t// Refusing to publish manifests that use deprecated capability names\n\t\t// keeps the marketplace clean while the deprecation window is open.\n\t\t// The fix is mechanical and entirely in the author's hands — they\n\t\t// rename, re-bundle, and republish. Better to refuse 5 publishes\n\t\t// than ship 500 deprecated manifests. We check before authentication\n\t\t// so authors don't burn a device-flow login on a doomed publish.\n\t\tconst deprecatedCaps = manifest.capabilities.filter(isDeprecatedCapability);\n\t\tif (deprecatedCaps.length > 0) {\n\t\t\tconsola.error(\n\t\t\t\t\"Plugin declares deprecated capability names. Rename them and re-bundle before publishing:\",\n\t\t\t);\n\t\t\tfor (const cap of deprecatedCaps) {\n\t\t\t\tconst replacement = CAPABILITY_RENAMES[cap];\n\t\t\t\tconsola.error(` ${cap} → ${replacement}`);\n\t\t\t}\n\t\t\tconsola.error(\n\t\t\t\t\"See https://emdashcms.com/docs/plugins/overview#capabilities for the full rename table.\",\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// ── Step 3: Authenticate ──\n\t\t//\n\t\t// Priority: EMDASH_MARKETPLACE_TOKEN env var > stored credential > interactive device flow.\n\t\t// The env var enables CI pipelines (including seed token auth) without interactive login.\n\n\t\tlet token: string;\n\t\tconst envToken = process.env.EMDASH_MARKETPLACE_TOKEN;\n\t\tconst stored = !envToken ? getMarketplaceCredential(registryUrl) : null;\n\n\t\tif (envToken) {\n\t\t\ttoken = envToken;\n\t\t\tconsola.info(\"Using EMDASH_MARKETPLACE_TOKEN for authentication\");\n\t\t} else if (stored) {\n\t\t\ttoken = stored.token;\n\t\t\tconsola.info(`Authenticated as ${pc.bold(stored.author?.name ?? \"unknown\")}`);\n\t\t} else {\n\t\t\tconsola.info(\"Not logged in to marketplace. Starting GitHub authentication...\");\n\t\t\tconst result = await authenticateViaDeviceFlow(registryUrl);\n\t\t\ttoken = result.token;\n\n\t\t\t// Save for next time\n\t\t\tsaveMarketplaceCredential(registryUrl, {\n\t\t\t\ttoken: result.token,\n\t\t\t\texpiresAt: new Date(Date.now() + 30 * 86400 * 1000).toISOString(), // 30 days\n\t\t\t\tauthor: { id: result.author.id, name: result.author.name },\n\t\t\t});\n\n\t\t\tconsola.success(`Authenticated as ${pc.bold(result.author.name)}`);\n\t\t}\n\n\t\t// ── Step 4: Pre-publish validation ──\n\n\t\tconsola.start(\"Checking marketplace...\");\n\n\t\t// Check if plugin exists\n\t\tconst pluginRes = await fetch(new URL(`/api/v1/plugins/${manifest.id}`, registryUrl));\n\n\t\tif (pluginRes.status === 404 && !envToken) {\n\t\t\t// Plugin doesn't exist — register it first.\n\t\t\t// When using env token (seed), the server auto-registers on publish.\n\t\t\tconsola.info(`Plugin ${pc.bold(manifest.id)} not found in marketplace. Registering...`);\n\n\t\t\tconst createRes = await fetch(new URL(\"/api/v1/plugins\", registryUrl), {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tid: manifest.id,\n\t\t\t\t\tname: manifest.id, // Use ID as name initially\n\t\t\t\t\tcapabilities: manifest.capabilities,\n\t\t\t\t}),\n\t\t\t});\n\n\t\t\tif (!createRes.ok) {\n\t\t\t\tconst body = (await createRes.json().catch(() => ({}))) as { error?: string };\n\t\t\t\tif (createRes.status === 401) {\n\t\t\t\t\t// Token expired — clear and retry\n\t\t\t\t\tremoveMarketplaceCredential(registryUrl);\n\t\t\t\t\tconsola.error(\n\t\t\t\t\t\t\"Authentication expired. Please run `emdash plugin publish` again to re-authenticate.\",\n\t\t\t\t\t);\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconsola.error(`Failed to register plugin: ${body.error ?? createRes.statusText}`);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconsola.success(`Registered ${pc.bold(manifest.id)}`);\n\t\t} else if (pluginRes.status === 404 && envToken) {\n\t\t\t// Using env token — server handles auto-registration on publish\n\t\t\tconsola.info(`Plugin ${pc.bold(manifest.id)} will be auto-registered on publish`);\n\t\t} else if (!pluginRes.ok) {\n\t\t\tconsola.error(`Marketplace error: ${pluginRes.status}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// ── Step 5: Upload ──\n\n\t\tconsola.start(`Publishing ${manifest.id}@${manifest.version}...`);\n\n\t\tconst tarballData = await readFile(tarballPath);\n\t\tconst formData = new FormData();\n\t\tformData.append(\n\t\t\t\"bundle\",\n\t\t\tnew Blob([tarballData], { type: \"application/gzip\" }),\n\t\t\tbasename(tarballPath),\n\t\t);\n\n\t\tconst uploadUrl = new URL(`/api/v1/plugins/${manifest.id}/versions`, registryUrl);\n\t\tconst uploadRes = await fetch(uploadUrl, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t},\n\t\t\tbody: formData,\n\t\t});\n\n\t\tif (!uploadRes.ok && uploadRes.status !== 202) {\n\t\t\tconst body = (await uploadRes.json().catch(() => ({}))) as {\n\t\t\t\terror?: string;\n\t\t\t\tlatestVersion?: string;\n\t\t\t\taudit?: { verdict: string; summary: string; findings: unknown[] };\n\t\t\t};\n\n\t\t\tif (uploadRes.status === 401) {\n\t\t\t\tif (envToken) {\n\t\t\t\t\tconsola.error(\"EMDASH_MARKETPLACE_TOKEN was rejected by the marketplace.\");\n\t\t\t\t} else {\n\t\t\t\t\tremoveMarketplaceCredential(registryUrl);\n\t\t\t\t\tconsola.error(\"Authentication expired. Please run `emdash plugin publish` again.\");\n\t\t\t\t}\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tif (uploadRes.status === 409) {\n\t\t\t\tif (body.latestVersion) {\n\t\t\t\t\tconsola.error(`Version ${manifest.version} must be greater than ${body.latestVersion}`);\n\t\t\t\t} else {\n\t\t\t\t\tconsola.error(body.error ?? \"Version conflict\");\n\t\t\t\t}\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tif (uploadRes.status === 422 && body.audit) {\n\t\t\t\t// Failed security audit\n\t\t\t\tconsola.error(\"Plugin failed security audit:\");\n\t\t\t\tconsola.error(` Verdict: ${pc.red(body.audit.verdict)}`);\n\t\t\t\tconsola.error(` Summary: ${body.audit.summary}`);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconsola.error(`Publish failed: ${body.error ?? uploadRes.statusText}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// ── Step 6: Handle response ──\n\n\t\tconst result = (await uploadRes.json()) as {\n\t\t\tversion: string;\n\t\t\tbundleSize: number;\n\t\t\tchecksum: string;\n\t\t\tpublishedAt: string;\n\t\t\tstatus?: string;\n\t\t\tworkflowId?: string;\n\t\t\taudit?: {\n\t\t\t\tverdict: string;\n\t\t\t\triskScore: number;\n\t\t\t\tsummary: string;\n\t\t\t\tfindings: { category: string; severity: string; description: string }[];\n\t\t\t};\n\t\t\timageAudit?: {\n\t\t\t\tverdict: string;\n\t\t\t} | null;\n\t\t};\n\n\t\tconsole.log();\n\t\tconsola.success(`Uploaded ${pc.bold(`${manifest.id}@${result.version}`)}`);\n\t\tconsola.info(` Checksum: ${pc.dim(result.checksum)}`);\n\t\tconsola.info(` Size: ${(result.bundleSize / 1024).toFixed(1)}KB`);\n\n\t\t// Async audit flow (202 Accepted)\n\t\tif (uploadRes.status === 202) {\n\t\t\tconsola.info(` Status: ${pc.yellow(\"pending\")} (audit running in background)`);\n\n\t\t\tif (args[\"no-wait\"]) {\n\t\t\t\tconsola.info(\"Skipping audit wait (--no-wait). Check status later.\");\n\t\t\t\tconsole.log();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Poll version endpoint for audit completion\n\t\t\tconsola.start(\"Waiting for security audit to complete...\");\n\t\t\tconst versionUrl = new URL(\n\t\t\t\t`/api/v1/plugins/${manifest.id}/versions/${manifest.version}`,\n\t\t\t\tregistryUrl,\n\t\t\t);\n\t\t\tconst finalStatus = await pollVersionStatus(versionUrl.toString(), token);\n\n\t\t\tif (finalStatus) {\n\t\t\t\tdisplayAuditResults(finalStatus);\n\t\t\t} else {\n\t\t\t\tconsola.warn(\"Audit did not complete within timeout. Check status later with:\");\n\t\t\t\tconsola.info(` ${pc.dim(`curl ${versionUrl.toString()}`)}`);\n\t\t\t}\n\t\t} else {\n\t\t\t// Synchronous response (201 or legacy)\n\t\t\tif (result.audit) {\n\t\t\t\tdisplayInlineAuditResults(result.audit, result.imageAudit ?? null);\n\t\t\t}\n\t\t\tconsola.info(` Status: ${pc.green(result.status ?? \"published\")}`);\n\t\t}\n\n\t\tconsole.log();\n\t},\n});\n\n// ── Marketplace auth subcommands ────────────────────────────────\n\nexport const marketplaceLoginCommand = defineCommand({\n\tmeta: {\n\t\tname: \"login\",\n\t\tdescription: \"Log in to the EmDash Marketplace via GitHub\",\n\t},\n\targs: {\n\t\tregistry: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Marketplace registry URL\",\n\t\t\tdefault: DEFAULT_REGISTRY,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst registryUrl = args.registry;\n\n\t\tconst existing = getMarketplaceCredential(registryUrl);\n\t\tif (existing) {\n\t\t\tconsola.info(`Already logged in as ${pc.bold(existing.author?.name ?? \"unknown\")}`);\n\t\t\tconsola.info(\"Use `emdash plugin logout` to log out first.\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst result = await authenticateViaDeviceFlow(registryUrl);\n\n\t\tsaveMarketplaceCredential(registryUrl, {\n\t\t\ttoken: result.token,\n\t\t\texpiresAt: new Date(Date.now() + 30 * 86400 * 1000).toISOString(),\n\t\t\tauthor: { id: result.author.id, name: result.author.name },\n\t\t});\n\n\t\tconsola.success(`Logged in as ${pc.bold(result.author.name)}`);\n\t},\n});\n\nexport const marketplaceLogoutCommand = defineCommand({\n\tmeta: {\n\t\tname: \"logout\",\n\t\tdescription: \"Log out of the EmDash Marketplace\",\n\t},\n\targs: {\n\t\tregistry: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Marketplace registry URL\",\n\t\t\tdefault: DEFAULT_REGISTRY,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst removed = removeMarketplaceCredential(args.registry);\n\t\tif (removed) {\n\t\t\tconsola.success(\"Logged out of marketplace.\");\n\t\t} else {\n\t\t\tconsola.info(\"No marketplace credentials found.\");\n\t\t}\n\t},\n});\n","/**\n * emdash plugin\n *\n * Plugin management commands grouped under a single namespace.\n *\n * Subcommands:\n * - init: Scaffold a new plugin\n * - bundle: Bundle a plugin for marketplace distribution\n * - validate: Run bundle validation without producing a tarball\n * - publish: Publish a plugin to the marketplace\n * - login: Log in to the marketplace via GitHub\n * - logout: Log out of the marketplace\n *\n */\n\nimport { defineCommand } from \"citty\";\n\nimport { bundleCommand } from \"./bundle.js\";\nimport { pluginInitCommand } from \"./plugin-init.js\";\nimport { pluginValidateCommand } from \"./plugin-validate.js\";\nimport { publishCommand, marketplaceLoginCommand, marketplaceLogoutCommand } from \"./publish.js\";\n\nexport const pluginCommand = defineCommand({\n\tmeta: { name: \"plugin\", description: \"Manage plugins\" },\n\tsubCommands: {\n\t\tinit: pluginInitCommand,\n\t\tbundle: bundleCommand,\n\t\tvalidate: pluginValidateCommand,\n\t\tpublish: publishCommand,\n\t\tlogin: marketplaceLoginCommand,\n\t\tlogout: marketplaceLogoutCommand,\n\t},\n});\n","/**\n * emdash schema\n *\n * Manage collections and fields via the remote API\n */\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\n\nimport { connectionArgs as commonArgs, createClientFromArgs } from \"../client-factory.js\";\nimport { configureOutputMode, output } from \"../output.js\";\n\nconst listCommand = defineCommand({\n\tmeta: {\n\t\tname: \"list\",\n\t\tdescription: \"List all collections\",\n\t},\n\targs: {\n\t\t...commonArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst collections = await client.collections();\n\t\t\toutput(collections, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst getCommand = defineCommand({\n\tmeta: {\n\t\tname: \"get\",\n\t\tdescription: \"Get collection with fields\",\n\t},\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\t...commonArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst collection = await client.collection(args.collection);\n\t\t\toutput(collection, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst createCommand = defineCommand({\n\tmeta: {\n\t\tname: \"create\",\n\t\tdescription: \"Create a collection\",\n\t},\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tlabel: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Collection label\",\n\t\t\trequired: true,\n\t\t},\n\t\t\"label-singular\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Singular label (defaults to label)\",\n\t\t},\n\t\tdescription: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Collection description\",\n\t\t},\n\t\t...commonArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst data = await client.createCollection({\n\t\t\t\tslug: args.collection,\n\t\t\t\tlabel: args.label,\n\t\t\t\tlabelSingular: args[\"label-singular\"] || args.label,\n\t\t\t\tdescription: args.description,\n\t\t\t});\n\t\t\tconsola.success(`Created collection \"${args.collection}\"`);\n\t\t\toutput(data, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst deleteCommand = defineCommand({\n\tmeta: {\n\t\tname: \"delete\",\n\t\tdescription: \"Delete a collection\",\n\t},\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tforce: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Skip confirmation\",\n\t\t},\n\t\t...commonArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tif (!args.force) {\n\t\t\t\tconst confirmed = await consola.prompt(`Delete collection \"${args.collection}\"?`, {\n\t\t\t\t\ttype: \"confirm\",\n\t\t\t\t});\n\t\t\t\tif (!confirmed) {\n\t\t\t\t\tconsola.info(\"Cancelled\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tawait client.deleteCollection(args.collection);\n\t\t\tconsola.success(`Deleted collection \"${args.collection}\"`);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst addFieldCommand = defineCommand({\n\tmeta: {\n\t\tname: \"add-field\",\n\t\tdescription: \"Add a field to a collection\",\n\t},\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tfield: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Field slug\",\n\t\t\trequired: true,\n\t\t},\n\t\ttype: {\n\t\t\ttype: \"string\",\n\t\t\tdescription:\n\t\t\t\t\"Field type (string, text, number, integer, boolean, datetime, image, reference, portableText, json)\",\n\t\t\trequired: true,\n\t\t},\n\t\tlabel: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Field label\",\n\t\t},\n\t\trequired: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Whether the field is required\",\n\t\t},\n\t\t...commonArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst data = await client.createField(args.collection, {\n\t\t\t\tslug: args.field,\n\t\t\t\ttype: args.type,\n\t\t\t\tlabel: args.label || args.field,\n\t\t\t\trequired: args.required,\n\t\t\t});\n\t\t\tconsola.success(`Added field \"${args.field}\" to \"${args.collection}\"`);\n\t\t\toutput(data, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst removeFieldCommand = defineCommand({\n\tmeta: {\n\t\tname: \"remove-field\",\n\t\tdescription: \"Remove a field from a collection\",\n\t},\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tfield: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Field slug\",\n\t\t\trequired: true,\n\t\t},\n\t\t...commonArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tawait client.deleteField(args.collection, args.field);\n\t\t\tconsola.success(`Removed field \"${args.field}\" from \"${args.collection}\"`);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nexport const schemaCommand = defineCommand({\n\tmeta: {\n\t\tname: \"schema\",\n\t\tdescription: \"Manage collections and fields\",\n\t},\n\tsubCommands: {\n\t\tlist: listCommand,\n\t\tget: getCommand,\n\t\tcreate: createCommand,\n\t\tdelete: deleteCommand,\n\t\t\"add-field\": addFieldCommand,\n\t\t\"remove-field\": removeFieldCommand,\n\t},\n});\n","/**\n * emdash search\n *\n * Full-text search across content\n */\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\n\nimport { connectionArgs, createClientFromArgs } from \"../client-factory.js\";\nimport { configureOutputMode, output } from \"../output.js\";\n\nexport const searchCommand = defineCommand({\n\tmeta: {\n\t\tname: \"search\",\n\t\tdescription: \"Full-text search across content\",\n\t},\n\targs: {\n\t\tquery: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Search query\",\n\t\t\trequired: true,\n\t\t},\n\t\tcollection: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"c\",\n\t\t\tdescription: \"Filter by collection\",\n\t\t},\n\t\tlocale: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Filter by locale\",\n\t\t},\n\t\tlimit: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"l\",\n\t\t\tdescription: \"Maximum results to return\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst results = await client.search(args.query, {\n\t\t\t\tcollection: args.collection,\n\t\t\t\tlocale: args.locale,\n\t\t\t\tlimit: args.limit ? parseInt(args.limit, 10) : undefined,\n\t\t\t});\n\t\t\toutput(results, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n","/**\n * Secrets CLI commands\n *\n * Pure (no-DB) commands for working with EmDash secrets:\n *\n * - `emdash secrets generate` — emits a fresh `EMDASH_ENCRYPTION_KEY`.\n * Optionally writes it to a local-secrets file (`.env`).\n * - `emdash secrets fingerprint <key>` — prints the kid for a key,\n * useful in CI for verifying what's been deployed without exposing\n * the raw value.\n *\n * DB-touching commands (`status`, `migrate`, `rotate`) live elsewhere:\n * the CLI process can't open the production D1/Postgres binding from\n * the operator's machine, so those operations ship as admin HTTP\n * endpoints in a later PR. A thin `--site <url>` wrapper for those\n * endpoints can land alongside.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\nimport pc from \"picocolors\";\n\nimport { EmDashSecretsError, fingerprintKey, generateEncryptionKey } from \"../../config/secrets.js\";\n\nconst KEY_VAR_NAME = \"EMDASH_ENCRYPTION_KEY\";\n/** Matches a populated entry — `KEY=<at least one char>`. */\nconst POPULATED_KEY_LINE_PATTERN = /^EMDASH_ENCRYPTION_KEY=.+$/m;\n/**\n * Matches any line starting `KEY=` including `KEY=` with empty value.\n * Used for in-place replacement when the entry exists but has no value.\n */\nconst ANY_KEY_LINE_PATTERN = /^EMDASH_ENCRYPTION_KEY=.*$/m;\n\n/**\n * Append (or replace) `EMDASH_ENCRYPTION_KEY` in a dotenv-style file.\n *\n * Idempotent: if the entry exists with a populated value, leaves it alone\n * (returns `\"skipped\"`) unless `force` is set. An entry with an empty\n * value (`EMDASH_ENCRYPTION_KEY=`) is treated as \"not set\" and gets\n * replaced — placeholder lines aren't a reason to refuse.\n *\n * Always ends the resulting file with a trailing newline. Doesn't touch\n * other variables.\n *\n * Exported for tests.\n */\nexport function writeEncryptionKeyToFile(\n\ttargetPath: string,\n\tvalue: string,\n\tforce: boolean,\n): \"wrote\" | \"skipped\" {\n\tconst exists = existsSync(targetPath);\n\tconst existing = exists ? readFileSync(targetPath, \"utf-8\") : \"\";\n\n\tconst hasPopulatedKey = POPULATED_KEY_LINE_PATTERN.test(existing);\n\tif (hasPopulatedKey && !force) {\n\t\treturn \"skipped\";\n\t}\n\n\tconst newLine = `${KEY_VAR_NAME}=${value}`;\n\tlet next: string;\n\tif (ANY_KEY_LINE_PATTERN.test(existing)) {\n\t\t// In-place replace handles both populated-and-forced and empty-value\n\t\t// cases. Then ensure trailing newline.\n\t\tnext = existing.replace(ANY_KEY_LINE_PATTERN, newLine);\n\t\tif (!next.endsWith(\"\\n\")) next += \"\\n\";\n\t} else {\n\t\t// Append. Insert a separating newline only if the file has content\n\t\t// not already ending in one.\n\t\tconst sep = existing.length === 0 ? \"\" : existing.endsWith(\"\\n\") ? \"\" : \"\\n\";\n\t\tnext = `${existing}${sep}${newLine}\\n`;\n\t}\n\n\twriteFileSync(targetPath, next);\n\treturn \"wrote\";\n}\n\nconst generateCommand = defineCommand({\n\tmeta: {\n\t\tname: \"generate\",\n\t\tdescription: \"Generate a new EmDash encryption key\",\n\t},\n\targs: {\n\t\twrite: {\n\t\t\ttype: \"string\",\n\t\t\tdescription:\n\t\t\t\t\"Optional path to write the key to (e.g. .env). \" +\n\t\t\t\t\"Won't overwrite an existing entry without --force.\",\n\t\t},\n\t\tforce: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"When used with --write, overwrite an existing entry\",\n\t\t\tdefault: false,\n\t\t},\n\t},\n\trun({ args }) {\n\t\tconst value = generateEncryptionKey();\n\n\t\tif (args.write) {\n\t\t\tconst targetPath = resolve(process.cwd(), args.write);\n\t\t\tconst result = writeEncryptionKeyToFile(targetPath, value, args.force);\n\t\t\tif (result === \"skipped\") {\n\t\t\t\t// Idempotent no-op: entry already populated. Exit 0 so chained\n\t\t\t\t// scripts (`emdash secrets generate --write && pnpm dev`) don't\n\t\t\t\t// break. Pass --force to replace, with full awareness that\n\t\t\t\t// existing encrypted secrets become unreadable.\n\t\t\t\tconsola.info(\n\t\t\t\t\t`${KEY_VAR_NAME} already set in ${pc.cyan(args.write)}; leaving it alone. ` +\n\t\t\t\t\t\t`Pass ${pc.bold(\"--force\")} to replace it.`,\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconsola.log(\"\");\n\t\t\tconsola.log(`${pc.bold(\"Wrote\")} ${pc.cyan(KEY_VAR_NAME)} to ${pc.cyan(args.write)}`);\n\t\t\tconsola.log(\"\");\n\t\t\tconsola.log(\n\t\t\t\tpc.yellow(\n\t\t\t\t\t\"Keep this file out of version control. Losing the key means losing every secret encrypted with it.\",\n\t\t\t\t),\n\t\t\t);\n\t\t\tconsola.log(\"\");\n\t\t\treturn;\n\t\t}\n\n\t\t// Print the key to stdout (one line, no decoration) so it can be\n\t\t// piped into env files or secret-management tools without scraping.\n\t\t// Explanatory text goes to stderr so it doesn't pollute the pipe.\n\t\tprocess.stdout.write(`${value}\\n`);\n\t\tconst guidance = [\n\t\t\t\"\",\n\t\t\tpc.bold(\"EmDash encryption key generated.\"),\n\t\t\t\"\",\n\t\t\t`Set ${pc.cyan(KEY_VAR_NAME)} in your environment.`,\n\t\t\t\"For Cloudflare deployments, push it to your Worker's secrets.\",\n\t\t\t\"For Node deployments, add it to your process environment or .env file.\",\n\t\t\t\"\",\n\t\t\tpc.yellow(\"Keep this value secret. Losing it means losing every secret encrypted with it.\"),\n\t\t\t\"\",\n\t\t].join(\"\\n\");\n\t\tprocess.stderr.write(`${guidance}\\n`);\n\t},\n});\n\nconst fingerprintCommand = defineCommand({\n\tmeta: {\n\t\tname: \"fingerprint\",\n\t\tdescription: \"Print the kid (8-char fingerprint) for an encryption key\",\n\t},\n\targs: {\n\t\tkey: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"The full key value (with the emdash_enc_v1_ prefix)\",\n\t\t\trequired: true,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\ttry {\n\t\t\tconst kid = await fingerprintKey(args.key);\n\t\t\t// Newline-only on stdout so it pipes cleanly into env/CI logs\n\t\t\t// without leaking the raw key.\n\t\t\tprocess.stdout.write(`${kid}\\n`);\n\t\t} catch (error) {\n\t\t\tconsola.error(\n\t\t\t\terror instanceof EmDashSecretsError ? error.message : \"Failed to fingerprint key\",\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nexport const secretsCommand = defineCommand({\n\tmeta: {\n\t\tname: \"secrets\",\n\t\tdescription: \"Manage EmDash secrets (generate, inspect)\",\n\t},\n\tsubCommands: {\n\t\tgenerate: generateCommand,\n\t\tfingerprint: fingerprintCommand,\n\t},\n});\n","/**\n * emdash seed\n *\n * Apply a seed file to the database\n */\n\nimport { readFile, access, mkdir } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport consola from \"consola\";\n\nimport { createDatabase } from \"../../database/connection.js\";\nimport { runMigrations } from \"../../database/migrations/runner.js\";\nimport { applySeed } from \"../../seed/apply.js\";\nimport type { SeedFile, SeedApplyOptions } from \"../../seed/types.js\";\nimport { validateSeed } from \"../../seed/validate.js\";\nimport { LocalStorage } from \"../../storage/local.js\";\n\ninterface PackageJson {\n\tname?: string;\n\temdash?: {\n\t\tseed?: string;\n\t};\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function readPackageJson(cwd: string): Promise<PackageJson | null> {\n\tconst pkgPath = resolve(cwd, \"package.json\");\n\ttry {\n\t\tconst content = await readFile(pkgPath, \"utf-8\");\n\t\treturn JSON.parse(content);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Resolve seed file path from:\n * 1. Positional argument (if provided)\n * 2. .emdash/seed.json (convention)\n * 3. package.json emdash.seed (config)\n */\nasync function resolveSeedPath(cwd: string, positional?: string): Promise<string | null> {\n\t// 1. Positional argument\n\tif (positional) {\n\t\tconst resolved = resolve(cwd, positional);\n\t\tif (await fileExists(resolved)) {\n\t\t\treturn resolved;\n\t\t}\n\t\tconsola.error(`Seed file not found: ${positional}`);\n\t\treturn null;\n\t}\n\n\t// 2. Convention: .emdash/seed.json\n\tconst conventionPath = resolve(cwd, \".emdash\", \"seed.json\");\n\tif (await fileExists(conventionPath)) {\n\t\treturn conventionPath;\n\t}\n\n\t// 3. package.json emdash.seed\n\tconst pkg = await readPackageJson(cwd);\n\tif (pkg?.emdash?.seed) {\n\t\tconst pkgSeedPath = resolve(cwd, pkg.emdash.seed);\n\t\tif (await fileExists(pkgSeedPath)) {\n\t\t\treturn pkgSeedPath;\n\t\t}\n\t\tconsola.warn(`Seed file from package.json not found: ${pkg.emdash.seed}`);\n\t}\n\n\treturn null;\n}\n\nexport const seedCommand = defineCommand({\n\tmeta: {\n\t\tname: \"seed\",\n\t\tdescription: \"Apply a seed file to the database\",\n\t},\n\targs: {\n\t\tpath: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Path to seed file (default: .emdash/seed.json)\",\n\t\t\trequired: false,\n\t\t},\n\t\tdatabase: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"d\",\n\t\t\tdescription: \"Database path\",\n\t\t\tdefault: \"./data.db\",\n\t\t},\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Working directory\",\n\t\t\tdefault: process.cwd(),\n\t\t},\n\t\tvalidate: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Validate only, don't apply\",\n\t\t\tdefault: false,\n\t\t},\n\t\t\"no-content\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Skip sample data (content entries, bylines, taxonomy terms)\",\n\t\t\tdefault: false,\n\t\t},\n\t\t\"on-conflict\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Conflict handling: skip, update, error\",\n\t\t\tdefault: \"skip\",\n\t\t},\n\t\t\"uploads-dir\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Directory for media uploads\",\n\t\t\tdefault: \"./uploads\",\n\t\t},\n\t\t\"media-base-url\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Base URL for media files\",\n\t\t\tdefault: \"/_emdash/api/media/file\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst cwd = resolve(args.cwd);\n\t\tconsola.start(\"Loading seed file...\");\n\n\t\t// Resolve seed file path\n\t\tconst seedPath = await resolveSeedPath(cwd, args.path);\n\t\tif (!seedPath) {\n\t\t\tconsola.error(\"No seed file found\");\n\t\t\tconsola.info(\"Provide a path, create .emdash/seed.json, or set emdash.seed in package.json\");\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconsola.info(`Seed file: ${seedPath}`);\n\n\t\t// Load and parse seed file\n\t\tlet seed: SeedFile;\n\t\ttry {\n\t\t\tconst content = await readFile(seedPath, \"utf-8\");\n\t\t\tseed = JSON.parse(content);\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Failed to parse seed file:\", error);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// Validate seed\n\t\tconsola.start(\"Validating seed file...\");\n\t\tconst validation = validateSeed(seed);\n\n\t\tif (validation.warnings.length > 0) {\n\t\t\tfor (const warning of validation.warnings) {\n\t\t\t\tconsola.warn(warning);\n\t\t\t}\n\t\t}\n\n\t\tif (!validation.valid) {\n\t\t\tconsola.error(\"Seed validation failed:\");\n\t\t\tfor (const error of validation.errors) {\n\t\t\t\tconsola.error(` - ${error}`);\n\t\t\t}\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconsola.success(\"Seed file is valid\");\n\n\t\t// If validate-only mode, exit here\n\t\tif (args.validate) {\n\t\t\tconsola.success(\"Validation complete\");\n\t\t\treturn;\n\t\t}\n\n\t\t// Connect to database\n\t\tconst dbPath = resolve(cwd, args.database);\n\t\tconsola.info(`Database: ${dbPath}`);\n\n\t\tconst db = createDatabase({ url: `file:${dbPath}` });\n\n\t\t// Run migrations\n\t\tconsola.start(\"Running migrations...\");\n\t\ttry {\n\t\t\tconst { applied } = await runMigrations(db);\n\t\t\tif (applied.length > 0) {\n\t\t\t\tconsola.success(`Applied ${applied.length} migrations`);\n\t\t\t} else {\n\t\t\t\tconsola.info(\"Database up to date\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Migration failed:\", error);\n\t\t\tawait db.destroy();\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// Set up storage for $media resolution\n\t\tconst uploadsDir = resolve(cwd, args[\"uploads-dir\"]);\n\t\tawait mkdir(uploadsDir, { recursive: true });\n\n\t\tconst storage = new LocalStorage({\n\t\t\tdirectory: uploadsDir,\n\t\t\tbaseUrl: args[\"media-base-url\"],\n\t\t});\n\n\t\t// Prepare apply options\n\t\tconst onConflictRaw = args[\"on-conflict\"];\n\t\tif (onConflictRaw !== \"skip\" && onConflictRaw !== \"update\" && onConflictRaw !== \"error\") {\n\t\t\tconsola.error(`Invalid --on-conflict value: ${onConflictRaw}`);\n\t\t\tconsola.info(\"Use: skip, update, or error\");\n\t\t\tawait db.destroy();\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconst options: SeedApplyOptions = {\n\t\t\tincludeContent: !args[\"no-content\"],\n\t\t\tonConflict: onConflictRaw,\n\t\t\tstorage,\n\t\t};\n\n\t\t// Apply seed\n\t\tconsola.start(\"Applying seed...\");\n\t\ttry {\n\t\t\tconst result = await applySeed(db, seed, options);\n\n\t\t\tconsola.success(\"Seed applied successfully!\");\n\t\t\tconsola.log(\"\");\n\n\t\t\t// Print summary\n\t\t\tif (result.settings.applied > 0) {\n\t\t\t\tconsola.info(`Settings: ${result.settings.applied} applied`);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tresult.collections.created > 0 ||\n\t\t\t\tresult.collections.skipped > 0 ||\n\t\t\t\tresult.collections.updated > 0\n\t\t\t) {\n\t\t\t\tconsola.info(\n\t\t\t\t\t`Collections: ${result.collections.created} created, ${result.collections.skipped} skipped, ${result.collections.updated} updated`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (result.fields.created > 0 || result.fields.skipped > 0 || result.fields.updated > 0) {\n\t\t\t\tconsola.info(\n\t\t\t\t\t`Fields: ${result.fields.created} created, ${result.fields.skipped} skipped, ${result.fields.updated} updated`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tresult.taxonomies.created > 0 ||\n\t\t\t\tresult.taxonomies.skipped > 0 ||\n\t\t\t\tresult.taxonomies.terms > 0\n\t\t\t) {\n\t\t\t\tconsola.info(\n\t\t\t\t\t`Taxonomies: ${result.taxonomies.created} created, ${result.taxonomies.skipped} skipped, ${result.taxonomies.terms} terms`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (result.bylines.created > 0 || result.bylines.skipped > 0 || result.bylines.updated > 0) {\n\t\t\t\tconsola.info(\n\t\t\t\t\t`Bylines: ${result.bylines.created} created, ${result.bylines.skipped} skipped, ${result.bylines.updated} updated`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (result.menus.created > 0 || result.menus.items > 0) {\n\t\t\t\tconsola.info(`Menus: ${result.menus.created} created, ${result.menus.items} items`);\n\t\t\t}\n\t\t\tif (result.widgetAreas.created > 0 || result.widgetAreas.widgets > 0) {\n\t\t\t\tconsola.info(\n\t\t\t\t\t`Widget Areas: ${result.widgetAreas.created} created, ${result.widgetAreas.widgets} widgets`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (result.content.created > 0 || result.content.skipped > 0 || result.content.updated > 0) {\n\t\t\t\tconsola.info(\n\t\t\t\t\t`Content: ${result.content.created} created, ${result.content.skipped} skipped, ${result.content.updated} updated`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (result.media.created > 0 || result.media.skipped > 0) {\n\t\t\t\tconsola.info(`Media: ${result.media.created} created, ${result.media.skipped} skipped`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Seed failed:\", error instanceof Error ? error.message : error);\n\t\t\tawait db.destroy();\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tawait db.destroy();\n\t\tconsola.success(\"Done!\");\n\t},\n});\n","/**\n * Reading and writing `.emdash` site package files on disk.\n *\n * Reading never trusts the archive: every entry is hashed and checked\n * against the manifest and the index chunks it pins before anything is\n * uploaded, so a damaged or tampered package fails locally.\n */\n\nimport { createReadStream, createWriteStream } from \"node:fs\";\nimport { rename, rm, stat } from \"node:fs/promises\";\nimport { Readable, Writable } from \"node:stream\";\n\nimport {\n\tpackSitePackage,\n\tunpackSitePackage,\n\ttype PackageFileSource,\n\ttype UnpackedPackageFile,\n} from \"../../transfer/container/tar.js\";\nimport { TransferError } from \"../../transfer/errors.js\";\nimport {\n\tcreateSha256,\n\tpackageDigest,\n\tsha256Hex,\n\ttype Sha256Digest,\n} from \"../../transfer/format/digest.js\";\nimport {\n\tdecodeUtf8,\n\tparseIndexLine,\n\tparseManifest,\n\ttype PackageFileEntry,\n\ttype SitePackageManifest,\n} from \"../../transfer/format/manifest.js\";\n\nexport interface LocalPackageFile {\n\tbytes: number;\n\tsha256: string;\n}\n\nexport interface ScannedSitePackage {\n\tmanifestBytes: Uint8Array;\n\tmanifest: SitePackageManifest;\n\tpackageDigest: Sha256Digest;\n\t/** Every file except the manifest: index chunks, record chunks, media blobs. */\n\tfiles: Map<string, LocalPackageFile>;\n\t/** Index chunk path → the record and media paths it lists. */\n\tindexEntries: Map<string, string[]>;\n\t/** Record or media path → the index chunk that lists it. */\n\tindexOf: Map<string, string>;\n\ttotalBytes: number;\n}\n\n/** Split an index chunk into its entries. */\nexport function parseIndexChunk(bytes: Uint8Array): PackageFileEntry[] {\n\tconst text = decodeUtf8(bytes, \"TRANSFER_MANIFEST_INVALID\");\n\tif (text.length > 0 && !text.endsWith(\"\\n\")) {\n\t\tthrow new TransferError(\"TRANSFER_MANIFEST_INVALID\", \"Index chunk must end with a newline\");\n\t}\n\treturn text\n\t\t.split(\"\\n\")\n\t\t.slice(0, -1)\n\t\t.map((line) => parseIndexLine(line));\n}\n\nexport function openArchive(path: string): ReadableStream<Uint8Array> {\n\treturn Readable.toWeb(createReadStream(path)) as ReadableStream<Uint8Array>;\n}\n\nexport async function readBody(body: ReadableStream<Uint8Array>): Promise<Uint8Array> {\n\treturn new Uint8Array(await new Response(body).arrayBuffer());\n}\n\nfunction mismatch(path: string, kind: \"digest\" | \"size\"): TransferError {\n\treturn kind === \"digest\"\n\t\t? new TransferError(\"TRANSFER_FILE_DIGEST_MISMATCH\", \"File does not match its digest\", {\n\t\t\t\tdetail: { path },\n\t\t\t})\n\t\t: new TransferError(\"TRANSFER_FILE_SIZE_MISMATCH\", \"File does not have its declared size\", {\n\t\t\t\tdetail: { path },\n\t\t\t});\n}\n\n/** Check bytes against a declared size and digest. */\nexport async function assertFileMatches(\n\tpath: string,\n\tbytes: Uint8Array,\n\texpected: LocalPackageFile,\n): Promise<void> {\n\tif (bytes.byteLength !== expected.bytes) throw mismatch(path, \"size\");\n\tif ((await sha256Hex(bytes)) !== expected.sha256) throw mismatch(path, \"digest\");\n}\n\nasync function hashBody(body: ReadableStream<Uint8Array>): Promise<LocalPackageFile> {\n\tconst hasher = await createSha256();\n\tlet bytes = 0;\n\tawait body.pipeTo(\n\t\tnew WritableStream<Uint8Array>({\n\t\t\twrite(chunk) {\n\t\t\t\tbytes += chunk.byteLength;\n\t\t\t\thasher.update(chunk);\n\t\t\t},\n\t\t}),\n\t);\n\treturn { bytes, sha256: await hasher.digest() };\n}\n\n/** Whether the file at `diskPath` exists and has exactly the expected size and digest. */\nexport async function diskFileMatches(\n\tdiskPath: string,\n\texpected: LocalPackageFile,\n): Promise<boolean> {\n\tlet info;\n\ttry {\n\t\tinfo = await stat(diskPath);\n\t} catch {\n\t\treturn false;\n\t}\n\tif (!info.isFile() || info.size !== expected.bytes) return false;\n\treturn (await hashBody(openArchive(diskPath))).sha256 === expected.sha256;\n}\n\n/**\n * Stream `body` to `diskPath`, verifying it against the package file `path`\n * declares. The file appears at `diskPath` only once it is complete and\n * verified.\n */\nexport async function saveVerifiedFile(\n\tpath: string,\n\tbody: ReadableStream<Uint8Array>,\n\texpected: LocalPackageFile,\n\tdiskPath: string,\n): Promise<void> {\n\tconst temporary = `${diskPath}.download`;\n\tconst hasher = await createSha256();\n\tlet bytes = 0;\n\tconst verify = new TransformStream<Uint8Array, Uint8Array>({\n\t\ttransform(chunk, controller) {\n\t\t\tbytes += chunk.byteLength;\n\t\t\tif (bytes > expected.bytes) throw mismatch(path, \"size\");\n\t\t\thasher.update(chunk);\n\t\t\tcontroller.enqueue(chunk);\n\t\t},\n\t});\n\ttry {\n\t\tawait body\n\t\t\t.pipeThrough(verify)\n\t\t\t.pipeTo(Writable.toWeb(createWriteStream(temporary)) as WritableStream<Uint8Array>);\n\t\tif (bytes !== expected.bytes) throw mismatch(path, \"size\");\n\t\tif ((await hasher.digest()) !== expected.sha256) throw mismatch(path, \"digest\");\n\t\tawait rename(temporary, diskPath);\n\t} catch (error) {\n\t\tawait rm(temporary, { force: true });\n\t\tthrow error;\n\t}\n}\n\n/**\n * Read a package file end to end and verify it: the manifest, every index\n * chunk the manifest pins, and every file the index lists, each by size and\n * SHA-256. Fails with a `TransferError` naming the first bad path.\n */\nexport async function scanSitePackage(archivePath: string): Promise<ScannedSitePackage> {\n\tlet manifestBytes: Uint8Array | undefined;\n\tlet manifest: SitePackageManifest | undefined;\n\tconst indexRefs = new Map<string, LocalPackageFile>();\n\tconst declared = new Map<string, LocalPackageFile>();\n\tconst indexEntries = new Map<string, string[]>();\n\tconst indexOf = new Map<string, string>();\n\tconst seen = new Map<string, LocalPackageFile>();\n\n\tawait unpackSitePackage(\n\t\topenArchive(archivePath),\n\t\tasync (file: UnpackedPackageFile) => {\n\t\t\tif (file.parsed.type === \"manifest\") {\n\t\t\t\tmanifestBytes = await readBody(file.body);\n\t\t\t\tmanifest = parseManifest(manifestBytes);\n\t\t\t\tfor (const ref of manifest.index) {\n\t\t\t\t\tindexRefs.set(ref.path, { bytes: ref.bytes, sha256: ref.sha256 });\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (file.parsed.type === \"index\") {\n\t\t\t\tconst expected = indexRefs.get(file.path);\n\t\t\t\tif (!expected) {\n\t\t\t\t\tthrow new TransferError(\"TRANSFER_FILE_NOT_DECLARED\", \"Index chunk is not listed\", {\n\t\t\t\t\t\tdetail: { path: file.path },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (file.bytes !== expected.bytes) throw mismatch(file.path, \"size\");\n\t\t\t\tconst bytes = await readBody(file.body);\n\t\t\t\tawait assertFileMatches(file.path, bytes, expected);\n\t\t\t\tconst paths: string[] = [];\n\t\t\t\tfor (const entry of parseIndexChunk(bytes)) {\n\t\t\t\t\tif (declared.has(entry.path)) {\n\t\t\t\t\t\tthrow new TransferError(\"TRANSFER_MANIFEST_INVALID\", \"File is listed twice\", {\n\t\t\t\t\t\t\tdetail: { path: entry.path },\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tdeclared.set(entry.path, { bytes: entry.bytes, sha256: entry.sha256 });\n\t\t\t\t\tindexOf.set(entry.path, file.path);\n\t\t\t\t\tpaths.push(entry.path);\n\t\t\t\t}\n\t\t\t\tindexEntries.set(file.path, paths);\n\t\t\t\tseen.set(file.path, expected);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tseen.set(file.path, await hashBody(file.body));\n\t\t},\n\t\t{\n\t\t\texpectedBytes: (path) => indexRefs.get(path)?.bytes ?? declared.get(path)?.bytes,\n\t\t},\n\t);\n\n\tif (!manifest || !manifestBytes) {\n\t\tthrow new TransferError(\"TRANSFER_CONTAINER_INVALID\", \"The package has no manifest\");\n\t}\n\tfor (const [path, expected] of [...indexRefs, ...declared]) {\n\t\tconst actual = seen.get(path);\n\t\tif (!actual) {\n\t\t\tthrow new TransferError(\"TRANSFER_FILE_MISSING\", \"The package is missing a file\", {\n\t\t\t\tdetail: { path },\n\t\t\t});\n\t\t}\n\t\tif (actual.bytes !== expected.bytes) throw mismatch(path, \"size\");\n\t\tif (actual.sha256 !== expected.sha256) throw mismatch(path, \"digest\");\n\t}\n\tfor (const path of seen.keys()) {\n\t\tif (!indexRefs.has(path) && !declared.has(path)) {\n\t\t\tthrow new TransferError(\"TRANSFER_FILE_NOT_DECLARED\", \"File is not listed by the package\", {\n\t\t\t\tdetail: { path },\n\t\t\t});\n\t\t}\n\t}\n\n\tlet totalBytes = manifestBytes.byteLength;\n\tfor (const file of seen.values()) totalBytes += file.bytes;\n\treturn {\n\t\tmanifestBytes,\n\t\tmanifest,\n\t\tpackageDigest: await packageDigest(manifest),\n\t\tfiles: seen,\n\t\tindexEntries,\n\t\tindexOf,\n\t\ttotalBytes,\n\t};\n}\n\n/**\n * Stream `files` into a package file at `outputPath`. Writes go to a\n * sibling `.partial` file that replaces `outputPath` only once the whole\n * archive is written; on failure the partial file is removed.\n */\nexport async function writeSitePackage(\n\toutputPath: string,\n\tfiles: AsyncIterable<PackageFileSource>,\n): Promise<{ bytes: number }> {\n\tconst partialPath = `${outputPath}.partial`;\n\tlet bytes = 0;\n\tconst counter = new TransformStream<Uint8Array, Uint8Array>({\n\t\ttransform(chunk, controller) {\n\t\t\tbytes += chunk.byteLength;\n\t\t\tcontroller.enqueue(chunk);\n\t\t},\n\t});\n\tconst sink = Writable.toWeb(createWriteStream(partialPath)) as WritableStream<Uint8Array>;\n\ttry {\n\t\tawait packSitePackage(files).pipeThrough(counter).pipeTo(sink);\n\t\tawait rename(partialPath, outputPath);\n\t} catch (error) {\n\t\tawait rm(partialPath, { force: true });\n\t\tthrow error;\n\t}\n\treturn { bytes };\n}\n","/**\n * Shared pieces of `emdash site`: errors, their user-facing messages,\n * retries, and progress reporting.\n */\n\nimport { EmDashApiError } from \"../../client/index.js\";\nimport { isTransferError } from \"../../transfer/errors.js\";\nimport type {\n\tExportTransformationCode,\n\tImportTransformationCode,\n} from \"../../transfer/format/transformations.js\";\n\n/** A failure the CLI reports with a stable code, like an API error. */\nexport class SiteTransferCliError extends Error {\n\tconstructor(\n\t\treadonly code: string,\n\t\tmessage: string,\n\t\treadonly details?: Record<string, unknown>,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"SiteTransferCliError\";\n\t}\n}\n\nexport interface CliErrorInfo {\n\tcode: string;\n\tmessage: string;\n}\n\nconst TRANSFER_MESSAGES: Readonly<Record<string, string>> = {\n\tTRANSFER_TARGET_NOT_EMPTY:\n\t\t\"This site already has content. A site package can only be imported into an empty site.\",\n\tTRANSFER_IMPORT_IN_PROGRESS:\n\t\t\"Another import is in progress on this site, or an unfinished import is still blocking writes. Check it with `emdash site import status <operation-id>`.\",\n\tTRANSFER_EXPORT_CONCURRENT_WRITES:\n\t\t\"The site kept changing while it was being exported. Run the export again when the site is quiet.\",\n\tTRANSFER_OPERATION_NOT_FOUND: \"No transfer operation with that id exists on this site.\",\n\tTRANSFER_EXPIRED:\n\t\t\"This transfer has expired and its files were removed. Start a new export or import.\",\n\tTRANSFER_IDEMPOTENCY_CONFLICT:\n\t\t\"This site already has an import started from a different package with the same key.\",\n\tTRANSFER_MANIFEST_INVALID: \"The package manifest is invalid.\",\n\tTRANSFER_UNSUPPORTED_FORMAT:\n\t\t\"This package uses a format version this site does not support. Upgrade EmDash on this site.\",\n\tTRANSFER_UNSUPPORTED_FEATURE:\n\t\t\"This package needs features this site does not support. Upgrade EmDash on this site.\",\n\tTRANSFER_CONTAINER_INVALID: \"The file is not a valid .emdash site package.\",\n\tTRANSFER_FILE_DIGEST_MISMATCH:\n\t\t\"A package file does not match its recorded digest. The package is damaged or was modified.\",\n\tTRANSFER_FILE_SIZE_MISMATCH:\n\t\t\"A package file does not have its recorded size. The package is damaged or was modified.\",\n\tTRANSFER_FILE_MISSING: \"The package is missing files its manifest lists.\",\n\tTRANSFER_FILE_NOT_DECLARED: \"The package contains a file its manifest does not list.\",\n\tTRANSFER_LIMIT_EXCEEDED: \"The package exceeds a limit this site enforces.\",\n\tTRANSFER_PACKAGE_DIGEST_MISMATCH:\n\t\t\"This is not the package that was analyzed. Analyze this package with `--analyze` first.\",\n\tTRANSFER_PLAN_DIGEST_MISMATCH:\n\t\t\"The plan changed since it was reviewed. Run `emdash site import <file> --analyze` again and confirm the new plan digest.\",\n\tTRANSFER_PLAN_BLOCKED:\n\t\t\"The import plan has blockers. Run `emdash site import <file> --analyze` to see them.\",\n\tTRANSFER_DECISIONS_INVALID: \"The import decisions are invalid.\",\n\tTRANSFER_VERIFICATION_FAILED:\n\t\t\"The imported site did not verify against the package, so no receipt was issued. Do not use this site; import into a fresh one.\",\n};\n\nconst TRANSFORMATION_LABELS: Readonly<\n\tRecord<ExportTransformationCode | ImportTransformationCode, string>\n> = {\n\tsoft_orphan_dropped: \"Unused references were left out\",\n\tavatar_nulled: \"Some byline avatars were left out\",\n\tredirect_duplicate_dropped: \"Duplicate redirects were left out\",\n\tmedia_not_ready_dropped: \"Unfinished media uploads were left out\",\n\tmedia_url_relativized: \"Media links were made relative\",\n\torphan_dropped: \"Records without a parent were left out\",\n\torphan_reference_nulled: \"Broken references were cleared\",\n\tmedia_ref_unlinked: \"Some media links could not be matched to files\",\n\tunknown_storage_key:\n\t\t\"Some content links to media files the source site doesn't have; those links won't work\",\n\tprincipal_mapped: \"Authors will be assigned to users on this site\",\n\tprincipal_unmapped: \"Some content will have no author\",\n\tseeded_scaffold_removed: \"Starter content will be removed\",\n\tredirect_loop_disabled: \"Redirects that loop will be imported turned off\",\n\tsearch_unsupported: \"Search will be turned off for some collections\",\n\tfloat4_rounded: \"Some decimal numbers will be rounded\",\n\tlocale_recased: \"Locales will use this site's capitalization\",\n};\n\n/** A plain-language description of a plan transformation code. */\nexport function transformationLabel(code: string): string {\n\tconst labels: Readonly<Record<string, string>> = TRANSFORMATION_LABELS;\n\treturn (Object.hasOwn(labels, code) ? labels[code] : undefined) ?? code;\n}\n\nfunction withServerDetail(friendly: string, serverMessage: string): string {\n\treturn serverMessage && !friendly.includes(serverMessage)\n\t\t? `${friendly} (${serverMessage})`\n\t\t: friendly;\n}\n\n/** The code and user-facing message for any error `emdash site` can hit. */\nexport function describeError(error: unknown): CliErrorInfo {\n\tif (error instanceof EmDashApiError) {\n\t\tconst friendly = TRANSFER_MESSAGES[error.code];\n\t\treturn {\n\t\t\tcode: error.code,\n\t\t\tmessage: friendly ? withServerDetail(friendly, error.message) : error.message,\n\t\t};\n\t}\n\tif (error instanceof SiteTransferCliError) {\n\t\treturn { code: error.code, message: error.message };\n\t}\n\tif (isTransferError(error)) {\n\t\tconst friendly = TRANSFER_MESSAGES[error.code];\n\t\tconst path = typeof error.detail?.path === \"string\" ? ` [${error.detail.path}]` : \"\";\n\t\treturn {\n\t\t\tcode: error.code,\n\t\t\tmessage: `${friendly ? withServerDetail(friendly, error.message) : error.message}${path}`,\n\t\t};\n\t}\n\treturn {\n\t\tcode: \"UNKNOWN_ERROR\",\n\t\tmessage: error instanceof Error ? error.message : String(error),\n\t};\n}\n\n/** Describe a failed operation from its recorded error. */\nexport function operationError(operation: {\n\tid: string;\n\tstate: string;\n\terrorCode: string | null;\n\terrorDetail: Record<string, unknown> | null;\n}): SiteTransferCliError {\n\tconst code = operation.errorCode ?? \"TRANSFER_OPERATION_FAILED\";\n\tconst friendly = TRANSFER_MESSAGES[code];\n\tconst base = friendly ?? `Operation ${operation.id} ended as ${operation.state}.`;\n\treturn new SiteTransferCliError(\n\t\tcode,\n\t\tfriendly ? `${base} (operation ${operation.id} is ${operation.state})` : base,\n\t\toperation.errorDetail ?? undefined,\n\t);\n}\n\nexport interface Reporter {\n\t/** A progress or status line for humans (stderr). */\n\tinfo(message: string): void;\n\t/** Something the user should notice but that does not stop the command. */\n\twarn(message: string): void;\n}\n\nexport interface RetryOptions {\n\t/** Attempts including the first (default 5). */\n\tattempts?: number;\n\t/** First backoff delay in ms, doubled per retry up to 8 s (default 500). */\n\tbaseDelayMs?: number;\n}\n\nexport interface TransferRuntime {\n\treporter: Reporter;\n\tretry?: RetryOptions;\n\t/** Waits between polls and retries; tests replace it. */\n\tsleep?: (ms: number) => Promise<void>;\n}\n\nexport function sleepFor(runtime: TransferRuntime, ms: number): Promise<void> {\n\tif (ms <= 0) return Promise.resolve();\n\tif (runtime.sleep) return runtime.sleep(ms);\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nconst MAX_BACKOFF_MS = 8000;\n\n/** Network failures, timeouts, rate limits, and server errors are worth another try. */\nexport function isTransient(error: unknown): boolean {\n\tif (error instanceof EmDashApiError) {\n\t\tif (error.code === \"TRANSFER_IMPORT_IN_PROGRESS\") return false;\n\t\treturn error.status === 408 || error.status === 429 || error.status >= 500;\n\t}\n\tif (error instanceof SiteTransferCliError || isTransferError(error)) return false;\n\treturn error instanceof TypeError || (error instanceof Error && error.name === \"AbortError\");\n}\n\n/** Run `fn`, retrying transient failures with exponential backoff. */\nexport async function withRetry<T>(\n\truntime: TransferRuntime,\n\tlabel: string,\n\tfn: () => Promise<T>,\n): Promise<T> {\n\tconst attempts = runtime.retry?.attempts ?? 5;\n\tconst base = runtime.retry?.baseDelayMs ?? 500;\n\tfor (let attempt = 1; ; attempt++) {\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} catch (error) {\n\t\t\tif (attempt >= attempts || !isTransient(error)) throw error;\n\t\t\tconst delay = Math.min(base * 2 ** (attempt - 1), MAX_BACKOFF_MS);\n\t\t\truntime.reporter.warn(\n\t\t\t\t`${label} failed (${describeError(error).message}); retrying in ${Math.round(delay / 100) / 10}s`,\n\t\t\t);\n\t\t\tawait sleepFor(runtime, delay);\n\t\t}\n\t}\n}\n\n/** Emits a progress line at most once per interval, and always when the label changes. */\nexport function createProgressLogger(\n\truntime: TransferRuntime,\n\tintervalMs = 2000,\n): (label: string, detail?: string) => void {\n\tlet lastLabel: string | undefined;\n\tlet lastAt = 0;\n\treturn (label, detail) => {\n\t\tconst now = Date.now();\n\t\tif (label === lastLabel && now - lastAt < intervalMs) return;\n\t\tlastLabel = label;\n\t\tlastAt = now;\n\t\truntime.reporter.info(detail ? `${label}: ${detail}` : label);\n\t};\n}\n\nexport function formatBytes(bytes: number): string {\n\tif (bytes < 1024) return `${bytes} B`;\n\tconst units = [\"KiB\", \"MiB\", \"GiB\", \"TiB\"];\n\tlet value = bytes / 1024;\n\tlet unit = 0;\n\twhile (value >= 1024 && unit < units.length - 1) {\n\t\tvalue /= 1024;\n\t\tunit++;\n\t}\n\treturn `${value.toFixed(1)} ${units[unit]}`;\n}\n\nexport function formatProgress(\n\tprogress: { done: number; total: number; bytesDone?: number; bytesTotal?: number } | null,\n): string | undefined {\n\tif (!progress) return undefined;\n\tconst bytes =\n\t\tprogress.bytesTotal !== undefined && progress.bytesDone !== undefined\n\t\t\t? ` (${formatBytes(progress.bytesDone)} / ${formatBytes(progress.bytesTotal)})`\n\t\t\t: \"\";\n\treturn `${progress.done}/${progress.total}${bytes}`;\n}\n","/**\n * `emdash site export`: drive a server-side export to completion, then\n * download its files one by one and assemble the `.emdash` package locally.\n *\n * A sidecar `<output>.partial.json` holds the idempotency key and operation\n * id, so re-running the same command after a crash or disconnect resumes the\n * same export instead of starting another. Downloaded files are kept in\n * `<output>.parts/` until the package is assembled, so a re-run only\n * downloads the files it does not have yet.\n */\n\nimport { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ulid } from \"ulidx\";\nimport { z } from \"zod\";\n\nimport type { EmDashClient, TransferOperation } from \"../../client/index.js\";\nimport { EmDashApiError } from \"../../client/index.js\";\nimport type { PackageFileSource } from \"../../transfer/container/tar.js\";\nimport { packageDigest, type Sha256Digest } from \"../../transfer/format/digest.js\";\nimport { parseManifest, type PackageFileEntry } from \"../../transfer/format/manifest.js\";\nimport { MANIFEST_PATH } from \"../../transfer/format/paths.js\";\nimport {\n\tdiskFileMatches,\n\topenArchive,\n\tparseIndexChunk,\n\tsaveVerifiedFile,\n\twriteSitePackage,\n} from \"./archive.js\";\nimport {\n\tcreateProgressLogger,\n\tformatBytes,\n\tformatProgress,\n\toperationError,\n\tSiteTransferCliError,\n\tsleepFor,\n\twithRetry,\n\ttype TransferRuntime,\n} from \"./shared.js\";\n\nconst DOWNLOAD_CONCURRENCY = 4;\n\nconst sidecarSchema = z.object({\n\tversion: z.literal(1),\n\tbaseUrl: z.string(),\n\tcomments: z.boolean(),\n\tidempotencyKey: z.string(),\n\toperationId: z.string().nullable(),\n});\n\ntype Sidecar = z.infer<typeof sidecarSchema>;\n\nexport function exportSidecarPath(outputPath: string): string {\n\treturn `${outputPath}.partial.json`;\n}\n\nasync function readSidecar(path: string): Promise<Sidecar | null> {\n\tlet text: string;\n\ttry {\n\t\ttext = await readFile(path, \"utf8\");\n\t} catch {\n\t\treturn null;\n\t}\n\ttry {\n\t\tconst parsed = sidecarSchema.safeParse(JSON.parse(text));\n\t\treturn parsed.success ? parsed.data : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function writeSidecar(path: string, sidecar: Sidecar): Promise<void> {\n\tawait writeFile(path, `${JSON.stringify(sidecar, null, \"\\t\")}\\n`);\n}\n\nexport interface SiteExportInput {\n\tclient: EmDashClient;\n\t/** Instance URL; a sidecar left by an export from another site is ignored. */\n\tbaseUrl: string;\n\toutputPath: string;\n\tcomments: boolean;\n}\n\nexport interface SiteExportResult {\n\toperationId: string;\n\toutput: string;\n\tpackageDigest: Sha256Digest;\n\tfiles: number;\n\tbytes: number;\n\tresumed: boolean;\n}\n\nasync function startOrResume(\n\tinput: SiteExportInput,\n\truntime: TransferRuntime,\n): Promise<{ operation: TransferOperation; resumed: boolean }> {\n\tconst sidecarPath = exportSidecarPath(input.outputPath);\n\tlet sidecar = await readSidecar(sidecarPath);\n\tif (sidecar && (sidecar.baseUrl !== input.baseUrl || sidecar.comments !== input.comments)) {\n\t\truntime.reporter.warn(\n\t\t\t`Ignoring ${sidecarPath}: it belongs to an export with different options or from another site.`,\n\t\t);\n\t\tsidecar = null;\n\t}\n\n\tif (sidecar?.operationId) {\n\t\tconst operationId = sidecar.operationId;\n\t\tconst existing = await withRetry(runtime, \"Reading the export\", () =>\n\t\t\tinput.client.transferExportGet(operationId),\n\t\t).catch((error: unknown) => {\n\t\t\tif (error instanceof EmDashApiError && error.code === \"TRANSFER_OPERATION_NOT_FOUND\") {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tthrow error;\n\t\t});\n\t\tconst operation = existing?.operation;\n\t\tif (operation && operation.state !== \"failed\" && operation.state !== \"expired\") {\n\t\t\tif (operation.state !== \"complete\" || operation.stagingCollectedAt === null) {\n\t\t\t\truntime.reporter.info(`Resuming export ${operation.id}`);\n\t\t\t\treturn { operation, resumed: true };\n\t\t\t}\n\t\t}\n\t\truntime.reporter.warn(\n\t\t\toperation\n\t\t\t\t? `Export ${operation.id} ${operation.state === \"failed\" ? `failed (${operation.errorCode ?? \"unknown error\"})` : \"expired\"}; starting a new export.`\n\t\t\t\t: `Export ${operationId} no longer exists; starting a new export.`,\n\t\t);\n\t\tsidecar = null;\n\t}\n\n\tconst state: Sidecar = sidecar ?? {\n\t\tversion: 1,\n\t\tbaseUrl: input.baseUrl,\n\t\tcomments: input.comments,\n\t\tidempotencyKey: `emdash-cli-export-${ulid()}`,\n\t\toperationId: null,\n\t};\n\tawait writeSidecar(sidecarPath, state);\n\tconst created = await withRetry(runtime, \"Starting the export\", () =>\n\t\tinput.client.transferExportCreate(input.comments ? {} : { comments: false }, {\n\t\t\tidempotencyKey: state.idempotencyKey,\n\t\t}),\n\t);\n\tawait writeSidecar(sidecarPath, { ...state, operationId: created.operation.id });\n\truntime.reporter.info(\n\t\t`${created.created ? \"Started\" : \"Resuming\"} export ${created.operation.id}`,\n\t);\n\treturn { operation: created.operation, resumed: !created.created };\n}\n\n/** Advance an export until it ends; returns the complete operation. */\nexport async function driveExport(\n\tclient: EmDashClient,\n\toperation: TransferOperation,\n\truntime: TransferRuntime,\n): Promise<TransferOperation> {\n\tconst progress = createProgressLogger(runtime);\n\tlet current = operation;\n\twhile (current.state === \"pending\" || current.state === \"running\") {\n\t\tconst step = await withRetry(runtime, \"Export step\", () =>\n\t\t\tclient.transferExportAdvance(current.id),\n\t\t);\n\t\tcurrent = step.operation;\n\t\tprogress(`Exporting (${current.stage ?? current.state})`, formatProgress(current.progress));\n\t\tif (step.nextRequestInMs === null) break;\n\t\tawait sleepFor(runtime, step.nextRequestInMs);\n\t}\n\tif (current.state !== \"complete\") throw operationError(current);\n\treturn current;\n}\n\n/**\n * Directory next to the output where downloaded files are kept, by digest,\n * until the package is assembled. A re-run reuses every file there that\n * still verifies.\n */\nexport function exportPartsPath(outputPath: string): string {\n\treturn `${outputPath}.parts`;\n}\n\ninterface DownloadedFile {\n\tpath: string;\n\tbytes: number;\n\tsha256: string;\n}\n\n/**\n * Run `task` over `items` with at most `limit` in flight. After a failure no\n * new item starts, the ones in flight finish, and the first failure is\n * thrown.\n */\nasync function forEachConcurrently<T>(\n\titems: readonly T[],\n\tlimit: number,\n\ttask: (item: T) => Promise<void>,\n): Promise<void> {\n\tlet next = 0;\n\tlet failure: { error: unknown } | undefined;\n\tconst worker = async () => {\n\t\twhile (!failure && next < items.length) {\n\t\t\tconst item = items[next++];\n\t\t\ttry {\n\t\t\t\tawait task(item);\n\t\t\t} catch (error) {\n\t\t\t\tfailure ??= { error };\n\t\t\t}\n\t\t}\n\t};\n\tawait Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker));\n\tif (failure) throw failure.error;\n}\n\n/**\n * Download a complete export file by file and write it as a package file.\n * The manifest must hash to the export's package digest.\n */\nexport async function downloadExport(\n\tclient: EmDashClient,\n\toperation: TransferOperation,\n\toutputPath: string,\n\truntime: TransferRuntime,\n): Promise<{ packageDigest: Sha256Digest; files: number; bytes: number }> {\n\tconst operationId = operation.id;\n\tconst manifestBytes = await withRetry(runtime, \"Downloading the manifest\", () =>\n\t\tclient.transferExportManifest(operationId),\n\t);\n\tconst manifest = parseManifest(manifestBytes);\n\tconst digest = await packageDigest(manifest);\n\tif (digest !== operation.packageDigest) {\n\t\tthrow new SiteTransferCliError(\n\t\t\t\"TRANSFER_PACKAGE_DIGEST_MISMATCH\",\n\t\t\t`The downloaded manifest does not match export ${operationId}. Run the export again.`,\n\t\t);\n\t}\n\tconst partsDir = exportPartsPath(outputPath);\n\tawait mkdir(partsDir, { recursive: true });\n\tconst partOf = (file: DownloadedFile) => join(partsDir, file.sha256);\n\n\tlet kept = 0;\n\tconst fetchPart = async (file: DownloadedFile): Promise<void> => {\n\t\tif (await diskFileMatches(partOf(file), file)) {\n\t\t\tkept++;\n\t\t\treturn;\n\t\t}\n\t\tawait withRetry(runtime, `Downloading ${file.path}`, async () => {\n\t\t\tconst download = await client.transferExportFile(operationId, file.path);\n\t\t\tawait saveVerifiedFile(file.path, download.body, file, partOf(file));\n\t\t});\n\t};\n\n\tconst indexChunks: DownloadedFile[] = manifest.index.map((ref) => ({\n\t\tpath: ref.path,\n\t\tbytes: ref.bytes,\n\t\tsha256: ref.sha256,\n\t}));\n\tconst entries: PackageFileEntry[] = [];\n\tfor (const chunk of indexChunks) {\n\t\tawait fetchPart(chunk);\n\t\tentries.push(...parseIndexChunk(await readFile(partOf(chunk))));\n\t}\n\n\tconst unique = [...new Map(entries.map((entry) => [entry.sha256, entry])).values()];\n\tconst total = unique.reduce((sum, entry) => sum + entry.bytes, 0);\n\tconst progress = createProgressLogger(runtime);\n\tlet done = 0;\n\tlet count = 0;\n\tawait forEachConcurrently(unique, DOWNLOAD_CONCURRENCY, async (entry) => {\n\t\tawait fetchPart(entry);\n\t\tdone += entry.bytes;\n\t\tcount++;\n\t\tprogress(\n\t\t\t\"Downloading\",\n\t\t\t`${count}/${unique.length} files (${formatBytes(done)} / ${formatBytes(total)})`,\n\t\t);\n\t});\n\tif (kept > 0) runtime.reporter.info(`Reused ${kept} files downloaded by an earlier run`);\n\n\tasync function* files(): AsyncGenerator<PackageFileSource> {\n\t\tyield { path: MANIFEST_PATH, bytes: manifestBytes.byteLength, body: () => manifestBytes };\n\t\tfor (const file of [...indexChunks, ...entries]) {\n\t\t\tyield { path: file.path, bytes: file.bytes, body: () => openArchive(partOf(file)) };\n\t\t}\n\t}\n\tconst written = await writeSitePackage(outputPath, files());\n\tawait rm(partsDir, { recursive: true, force: true });\n\treturn {\n\t\tpackageDigest: digest,\n\t\tfiles: 1 + indexChunks.length + entries.length,\n\t\tbytes: written.bytes,\n\t};\n}\n\nexport async function runSiteExport(\n\tinput: SiteExportInput,\n\truntime: TransferRuntime,\n): Promise<SiteExportResult> {\n\tconst { operation, resumed } = await startOrResume(input, runtime);\n\tconst complete = await driveExport(input.client, operation, runtime);\n\truntime.reporter.info(`Export ${complete.id} is complete; downloading`);\n\tconst downloaded = await downloadExport(input.client, complete, input.outputPath, runtime);\n\tawait rm(exportSidecarPath(input.outputPath), { force: true });\n\treturn {\n\t\toperationId: complete.id,\n\t\toutput: input.outputPath,\n\t\tpackageDigest: downloaded.packageDigest,\n\t\tfiles: downloaded.files,\n\t\tbytes: downloaded.bytes,\n\t\tresumed,\n\t};\n}\n","/**\n * `emdash site import`: verify a local package, upload what the target is\n * missing, analyze it into a plan, and execute a confirmed plan.\n *\n * Every step is resumable. The import is created with the package digest as\n * its idempotency key and found again by digest, uploads skip files the\n * target already verified, and analysis and execution are server-side state\n * machines the CLI only advances.\n */\n\nimport {\n\tEmDashApiError,\n\ttype EmDashClient,\n\ttype SiteImportDecisionsInput,\n\ttype SiteImportPlan,\n\ttype SiteImportReceipt,\n\ttype TransferOperation,\n\ttype TransferPackageFile,\n} from \"../../client/index.js\";\nimport { unpackSitePackage } from \"../../transfer/container/tar.js\";\nimport { verifyReceiptDigest } from \"../../transfer/format/receipt.js\";\nimport {\n\tassertFileMatches,\n\topenArchive,\n\treadBody,\n\tscanSitePackage,\n\ttype ScannedSitePackage,\n} from \"./archive.js\";\nimport {\n\tcreateProgressLogger,\n\tformatBytes,\n\tformatProgress,\n\toperationError,\n\tSiteTransferCliError,\n\tsleepFor,\n\twithRetry,\n\ttype TransferRuntime,\n} from \"./shared.js\";\n\nconst UPLOAD_CONCURRENCY = 4;\n/** Buffered upload bytes allowed in flight; one larger file may exceed it. */\nconst UPLOAD_BUFFER_BYTES = 64 * 1024 * 1024;\nconst MISSING_PAGE = 100;\nconst IMPORT_LOOKUP_PAGES = 5;\nconst SHA256_DIGEST_PATTERN = /^sha256:[0-9a-f]{64}$/;\nconst SHA256_HEX_PATTERN = /^[0-9a-f]{64}$/;\n\nconst ENDED_WITHOUT_RECEIPT = new Set([\"failed\", \"cancelled\", \"abandoned\", \"expired\"]);\n\n/** Whether an import is executing: requested (`planned` at stage `reserve`), running, or verifying. */\nexport function isExecuting(operation: Pick<TransferOperation, \"state\" | \"stage\">): boolean {\n\treturn (\n\t\toperation.state === \"running\" ||\n\t\toperation.state === \"verifying\" ||\n\t\t(operation.state === \"planned\" && operation.stage === \"reserve\")\n\t);\n}\n\n/** Normalize a plan digest given as `sha256:<hex>` or bare hex. */\nexport function normalizePlanDigest(value: string): string {\n\tconst trimmed = value.trim().toLowerCase();\n\tif (SHA256_DIGEST_PATTERN.test(trimmed)) return trimmed;\n\tif (SHA256_HEX_PATTERN.test(trimmed)) return `sha256:${trimmed}`;\n\tthrow new SiteTransferCliError(\n\t\t\"INVALID_ARGUMENT\",\n\t\t\"--plan must be a plan digest like sha256:<64 hex characters>\",\n\t);\n}\n\n// ── Finding or creating the import ─────────────────────────────\n\nasync function findImportByDigest(\n\tclient: EmDashClient,\n\tdigest: string,\n\truntime: TransferRuntime,\n): Promise<TransferOperation | null> {\n\tlet cursor: string | undefined;\n\tfor (let page = 0; page < IMPORT_LOOKUP_PAGES; page++) {\n\t\tconst result = await withRetry(runtime, \"Listing imports\", () =>\n\t\t\tclient.transferImportList({ limit: 100, cursor }),\n\t\t);\n\t\tconst match = result.items.find((item) => item.packageDigest === digest);\n\t\tif (match) return ENDED_WITHOUT_RECEIPT.has(match.state) ? null : match;\n\t\tif (!result.nextCursor) return null;\n\t\tcursor = result.nextCursor;\n\t}\n\treturn null;\n}\n\n/** Import states that keep blocking site writes once the import has written. */\nconst BLOCKING_AFTER_WRITE = new Set([\"failed\", \"cancelled\"]);\n\nfunction occupiesTarget(operation: TransferOperation): boolean {\n\tif (!ENDED_WITHOUT_RECEIPT.has(operation.state) && operation.state !== \"complete\") return true;\n\treturn operation.mutationStartedAt !== null && BLOCKING_AFTER_WRITE.has(operation.state);\n}\n\n/**\n * When the site refuses a new import because an earlier import wrote to it\n * and then stopped, say which import and what to do about it; otherwise\n * return `error` unchanged.\n */\nasync function explainOccupiedTarget(\n\tclient: EmDashClient,\n\terror: unknown,\n\truntime: TransferRuntime,\n): Promise<unknown> {\n\tif (\n\t\t!(error instanceof EmDashApiError) ||\n\t\t(error.code !== \"TRANSFER_TARGET_NOT_EMPTY\" && error.code !== \"TRANSFER_IMPORT_IN_PROGRESS\")\n\t) {\n\t\treturn error;\n\t}\n\tconst { items } = await withRetry(runtime, \"Listing imports\", () =>\n\t\tclient.transferImportList({ limit: 100 }),\n\t).catch(() => ({ items: [] as TransferOperation[] }));\n\tconst occupying = items.find(occupiesTarget);\n\tif (occupying) {\n\t\tif (!BLOCKING_AFTER_WRITE.has(occupying.state)) return error;\n\t\tconst ended = occupying.state === \"failed\" ? \"failed\" : \"was cancelled\";\n\t\treturn new SiteTransferCliError(\n\t\t\terror.code,\n\t\t\t`Import ${occupying.id} ${ended} after it started writing, so this site holds partial data from it and blocks writes. Abandon it with \\`emdash site import abandon ${occupying.id}\\`, then reset this site or set up a new one before importing again.`,\n\t\t\t{ operationId: occupying.id, state: occupying.state },\n\t\t);\n\t}\n\tconst abandoned = items.find(\n\t\t(item) => item.state === \"abandoned\" && item.mutationStartedAt !== null,\n\t);\n\tif (error.code === \"TRANSFER_TARGET_NOT_EMPTY\" && abandoned) {\n\t\treturn new SiteTransferCliError(\n\t\t\terror.code,\n\t\t\t`Import ${abandoned.id} wrote partial data to this site before it was abandoned. Reset this site or set up a new one before importing again.`,\n\t\t\t{ operationId: abandoned.id, state: abandoned.state },\n\t\t);\n\t}\n\treturn error;\n}\n\nexport interface OpenedImport {\n\toperation: TransferOperation;\n\t/** True when every package file still has to be uploaded. */\n\tfresh: boolean;\n}\n\n/**\n * Find the import of this package on the target, or create it. An earlier\n * import of the same package that ended without a receipt is left alone and\n * a new one is started.\n */\nexport async function openImport(\n\tclient: EmDashClient,\n\tscan: ScannedSitePackage,\n\truntime: TransferRuntime,\n): Promise<OpenedImport> {\n\tconst existing = await findImportByDigest(client, scan.packageDigest, runtime);\n\tif (existing) {\n\t\truntime.reporter.info(`Resuming import ${existing.id} (${existing.state})`);\n\t\treturn { operation: existing, fresh: false };\n\t}\n\tconst create = (idempotencyKey: string) =>\n\t\twithRetry(runtime, \"Creating the import\", () =>\n\t\t\tclient.transferImportCreate(scan.manifestBytes, { idempotencyKey }),\n\t\t).catch(async (error: unknown) => {\n\t\t\tthrow await explainOccupiedTarget(client, error, runtime);\n\t\t});\n\tlet created = await create(scan.packageDigest);\n\tif (ENDED_WITHOUT_RECEIPT.has(created.operation.state)) {\n\t\truntime.reporter.warn(\n\t\t\t`An earlier import of this package (${created.operation.id}) ended as ${created.operation.state}; starting a new one.`,\n\t\t);\n\t\tcreated = await create(`${scan.packageDigest}/${Date.now().toString(36)}`);\n\t}\n\truntime.reporter.info(\n\t\t`${created.created ? \"Created\" : \"Resuming\"} import ${created.operation.id} (${created.operation.state})`,\n\t);\n\treturn { operation: created.operation, fresh: created.created };\n}\n\n// ── Uploading ──────────────────────────────────────────────────\n\nasync function listMissing(\n\tclient: EmDashClient,\n\toperationId: string,\n\truntime: TransferRuntime,\n): Promise<TransferPackageFile[]> {\n\tconst files: TransferPackageFile[] = [];\n\tlet cursor: string | undefined;\n\tdo {\n\t\tconst page = await withRetry(runtime, \"Listing missing files\", () =>\n\t\t\tclient.transferImportMissing(operationId, { limit: MISSING_PAGE, cursor }),\n\t\t);\n\t\tfiles.push(...page.items);\n\t\tcursor = page.nextCursor;\n\t} while (cursor);\n\treturn files;\n}\n\nclass UploadPool {\n\tprivate readonly inFlight = new Set<Promise<void>>();\n\tprivate bytes = 0;\n\tprivate failure: unknown;\n\n\tconstructor(\n\t\tprivate readonly concurrency: number,\n\t\tprivate readonly maxBytes: number,\n\t) {}\n\n\tasync add(size: number, task: () => Promise<void>): Promise<void> {\n\t\twhile (\n\t\t\tthis.inFlight.size > 0 &&\n\t\t\t(this.inFlight.size >= this.concurrency || this.bytes + size > this.maxBytes)\n\t\t) {\n\t\t\tawait Promise.race(this.inFlight);\n\t\t}\n\t\tthis.rethrow();\n\t\tthis.bytes += size;\n\t\tconst promise: Promise<void> = task()\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tthis.failure ??= error;\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tthis.bytes -= size;\n\t\t\t\tthis.inFlight.delete(promise);\n\t\t\t});\n\t\tthis.inFlight.add(promise);\n\t}\n\n\tasync drain(): Promise<void> {\n\t\tawait Promise.all(this.inFlight);\n\t\tthis.rethrow();\n\t}\n\n\t/** Wait for uploads in flight without surfacing their failures. */\n\tasync settle(): Promise<void> {\n\t\tawait Promise.allSettled(this.inFlight);\n\t}\n\n\tprivate rethrow(): void {\n\t\tif (this.failure !== undefined) throw this.failure;\n\t}\n}\n\nexport interface UploadSummary {\n\tuploaded: number;\n\tbytes: number;\n}\n\n/**\n * Upload every package file the import has not verified yet. Index chunks go\n * first because uploading one declares the files it lists; a file whose\n * index chunk is not uploaded yet waits for the next pass over the archive.\n */\nexport async function uploadPackage(\n\tclient: EmDashClient,\n\tarchivePath: string,\n\tscan: ScannedSitePackage,\n\toperation: OpenedImport,\n\truntime: TransferRuntime,\n): Promise<UploadSummary> {\n\tconst operationId = operation.operation.id;\n\tconst progress = createProgressLogger(runtime);\n\tconst summary: UploadSummary = { uploaded: 0, bytes: 0 };\n\tlet pending: Set<string> | null = operation.fresh ? new Set(scan.files.keys()) : null;\n\n\tfor (;;) {\n\t\tif (!pending) {\n\t\t\tconst missing = await listMissing(client, operationId, runtime);\n\t\t\tfor (const file of missing) {\n\t\t\t\tconst local = scan.files.get(file.path);\n\t\t\t\tif (!local) {\n\t\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\t\"TRANSFER_FILE_MISSING\",\n\t\t\t\t\t\t`The site expects ${file.path}, which is not in this package file`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (local.bytes !== file.bytes || local.sha256 !== file.sha256) {\n\t\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\t\"TRANSFER_FILE_DIGEST_MISMATCH\",\n\t\t\t\t\t\t`The site expects different contents for ${file.path}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tpending = new Set(missing.map((file) => file.path));\n\t\t\tfor (const file of missing) {\n\t\t\t\tfor (const path of scan.indexEntries.get(file.path) ?? []) pending.add(path);\n\t\t\t}\n\t\t}\n\t\tif (pending.size === 0) return summary;\n\n\t\tconst total = pending.size;\n\t\tconst uploadedIndexes = new Set<string>();\n\t\tconst pool = new UploadPool(UPLOAD_CONCURRENCY, UPLOAD_BUFFER_BYTES);\n\t\tlet passUploaded = 0;\n\t\tconst upload = async (path: string, bytes: Uint8Array) => {\n\t\t\tawait withRetry(runtime, `Uploading ${path}`, () =>\n\t\t\t\tclient.transferImportUploadFile(operationId, path, bytes, bytes.byteLength),\n\t\t\t);\n\t\t\tpassUploaded++;\n\t\t\tsummary.uploaded++;\n\t\t\tsummary.bytes += bytes.byteLength;\n\t\t\tprogress(\n\t\t\t\t\"Uploading\",\n\t\t\t\t`${passUploaded}/${total} files (${formatBytes(summary.bytes)} this run)`,\n\t\t\t);\n\t\t};\n\n\t\tconst passPending = pending;\n\t\ttry {\n\t\t\tawait unpackSitePackage(openArchive(archivePath), async (file) => {\n\t\t\t\tif (!passPending.has(file.path)) return;\n\t\t\t\tconst index = scan.indexOf.get(file.path);\n\t\t\t\tif (index && passPending.has(index) && !uploadedIndexes.has(index)) return;\n\t\t\t\tconst expected = scan.files.get(file.path);\n\t\t\t\tif (!expected) return;\n\t\t\t\tconst bytes = await readBody(file.body);\n\t\t\t\tawait assertFileMatches(file.path, bytes, expected);\n\t\t\t\tif (file.parsed.type === \"index\") {\n\t\t\t\t\tawait upload(file.path, bytes);\n\t\t\t\t\tuploadedIndexes.add(file.path);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tawait pool.add(bytes.byteLength, () => upload(file.path, bytes));\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tawait pool.settle();\n\t\t\tthrow error;\n\t\t}\n\t\tawait pool.drain();\n\n\t\tif (passUploaded === 0) {\n\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\"TRANSFER_FILE_MISSING\",\n\t\t\t\t\"The site still expects files that could not be uploaded from this package\",\n\t\t\t);\n\t\t}\n\t\tpending = null;\n\t}\n}\n\n// ── Analysis ───────────────────────────────────────────────────\n\nexport interface PlannedImport {\n\toperation: TransferOperation;\n\tplan: SiteImportPlan;\n\tplanDigest: string;\n}\n\n/** Advance analysis until the import is planned. */\nexport async function driveAnalysis(\n\tclient: EmDashClient,\n\toperation: TransferOperation,\n\truntime: TransferRuntime,\n): Promise<PlannedImport> {\n\tconst progress = createProgressLogger(runtime);\n\tfor (;;) {\n\t\tconst step = await withRetry(runtime, \"Analysis step\", () =>\n\t\t\tclient.transferImportAnalyze(operation.id),\n\t\t).catch(async (error: unknown) => {\n\t\t\tif (error instanceof EmDashApiError && error.code === \"TRANSFER_INVALID_STATE\") {\n\t\t\t\tconst { operation: current } = await client.transferImportGet(operation.id);\n\t\t\t\tif (ENDED_WITHOUT_RECEIPT.has(current.state)) throw operationError(current);\n\t\t\t}\n\t\t\tthrow error;\n\t\t});\n\t\tconst current = step.operation;\n\t\tif (step.nextRequestInMs === null) {\n\t\t\tif (current.state !== \"planned\" || !step.plan || !step.planDigest) {\n\t\t\t\tthrow operationError(current);\n\t\t\t}\n\t\t\treturn { operation: current, plan: step.plan, planDigest: step.planDigest };\n\t\t}\n\t\tprogress(`Analyzing (${current.stage ?? current.state})`, formatProgress(current.progress));\n\t\tawait sleepFor(runtime, step.nextRequestInMs);\n\t}\n}\n\n/** Submit decisions for a planned import; returns the resulting plan. */\nexport async function applyDecisions(\n\tclient: EmDashClient,\n\toperationId: string,\n\tdecisions: SiteImportDecisionsInput,\n\truntime: TransferRuntime,\n): Promise<PlannedImport> {\n\tconst decided = await withRetry(runtime, \"Applying decisions\", () =>\n\t\tclient.transferImportAnalyze(operationId, decisions),\n\t);\n\tif (!decided.plan || !decided.planDigest) throw operationError(decided.operation);\n\treturn { operation: decided.operation, plan: decided.plan, planDigest: decided.planDigest };\n}\n\n// ── Decisions from flags ───────────────────────────────────────\n\nexport interface DecisionFlags {\n\t/** Raw `--map-principal` values: `<principal id|email>=<user id|email|none>`. */\n\tmapPrincipal: string[];\n\tuseTargetTitle: boolean;\n\tuseTargetTagline: boolean;\n}\n\nexport function hasDecisions(flags: DecisionFlags): boolean {\n\treturn flags.mapPrincipal.length > 0 || flags.useTargetTitle || flags.useTargetTagline;\n}\n\nconst USER_PAGES = 50;\n\nasync function targetUsersByEmail(\n\tclient: EmDashClient,\n\truntime: TransferRuntime,\n): Promise<Map<string, string[]>> {\n\tconst byEmail = new Map<string, string[]>();\n\tlet cursor: string | undefined;\n\tfor (let page = 0; page < USER_PAGES; page++) {\n\t\tconst result = await withRetry(runtime, \"Listing users\", () =>\n\t\t\tclient.users({ limit: 100, cursor }),\n\t\t);\n\t\tfor (const user of result.items) {\n\t\t\tconst key = user.email.toLowerCase();\n\t\t\tbyEmail.set(key, [...(byEmail.get(key) ?? []), user.id]);\n\t\t}\n\t\tif (!result.nextCursor) break;\n\t\tcursor = result.nextCursor;\n\t}\n\treturn byEmail;\n}\n\n/**\n * Turn decision flags into plan decisions. Principals are matched by id, or\n * by email (case-insensitive); target users by id, by email through the\n * users API, or `none` to leave the references unassigned.\n */\nexport async function resolveDecisions(\n\tclient: EmDashClient,\n\tplan: SiteImportPlan,\n\tflags: DecisionFlags,\n\truntime: TransferRuntime,\n): Promise<SiteImportDecisionsInput> {\n\tconst decisions: SiteImportDecisionsInput = {};\n\tif (flags.useTargetTitle) decisions.siteTitle = \"target\";\n\tif (flags.useTargetTagline) decisions.siteTagline = \"target\";\n\tif (flags.mapPrincipal.length === 0) return decisions;\n\n\tlet users: Map<string, string[]> | undefined;\n\tconst mappings: Record<string, string | null> = {};\n\tfor (const raw of flags.mapPrincipal) {\n\t\tconst separator = raw.lastIndexOf(\"=\");\n\t\tconst from = separator > 0 ? raw.slice(0, separator).trim() : \"\";\n\t\tconst to = separator > 0 ? raw.slice(separator + 1).trim() : \"\";\n\t\tif (!from || !to) {\n\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t`--map-principal expects <principal id or email>=<user id, email, or none>, got \"${raw}\"`,\n\t\t\t);\n\t\t}\n\t\tconst principal =\n\t\t\tplan.principals.find((candidate) => candidate.id === from) ??\n\t\t\tmatchOne(\n\t\t\t\tplan.principals.filter(\n\t\t\t\t\t(candidate) => candidate.email?.toLowerCase() === from.toLowerCase(),\n\t\t\t\t),\n\t\t\t\t`principal ${from}`,\n\t\t\t);\n\t\tif (!principal) {\n\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t`The package has no principal ${from}. Principals: ${plan.principals.map((p) => p.id).join(\", \") || \"none\"}`,\n\t\t\t);\n\t\t}\n\n\t\tlet target: string | null;\n\t\tif (to.toLowerCase() === \"none\") {\n\t\t\ttarget = null;\n\t\t} else if (to.includes(\"@\")) {\n\t\t\tusers ??= await targetUsersByEmail(client, runtime);\n\t\t\tconst ids = users.get(to.toLowerCase()) ?? [];\n\t\t\tif (ids.length !== 1) {\n\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t\tids.length === 0\n\t\t\t\t\t\t? `No user on this site has the email ${to}`\n\t\t\t\t\t\t: `More than one user on this site has the email ${to}; map by user id instead`,\n\t\t\t\t);\n\t\t\t}\n\t\t\ttarget = ids[0];\n\t\t} else {\n\t\t\ttarget = to;\n\t\t}\n\t\tmappings[principal.id] = target;\n\t}\n\tdecisions.principalMappings = mappings;\n\treturn decisions;\n}\n\nfunction matchOne<T>(matches: T[], label: string): T | undefined {\n\tif (matches.length > 1) {\n\t\tthrow new SiteTransferCliError(\n\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t`More than one ${label} matches; map by principal id instead`,\n\t\t);\n\t}\n\treturn matches[0];\n}\n\n// ── Execution ──────────────────────────────────────────────────\n\nexport interface CompletedImport {\n\toperationId: string;\n\tstate: \"complete\";\n\treceipt: SiteImportReceipt;\n\treceiptDigestValid: boolean;\n}\n\n/** Advance an executing import until it ends; returns the complete operation. */\nexport async function driveExecution(\n\tclient: EmDashClient,\n\toperation: TransferOperation,\n\truntime: TransferRuntime,\n): Promise<TransferOperation> {\n\tconst progress = createProgressLogger(runtime);\n\tlet current = operation;\n\twhile (isExecuting(current)) {\n\t\tconst step = await withRetry(runtime, \"Import step\", () =>\n\t\t\tclient.transferImportAdvance(current.id),\n\t\t);\n\t\tcurrent = step.operation;\n\t\tprogress(`Importing (${current.stage ?? current.state})`, formatProgress(current.progress));\n\t\tif (step.nextRequestInMs === null) break;\n\t\tawait sleepFor(runtime, step.nextRequestInMs);\n\t}\n\tif (current.state !== \"complete\") throw operationError(current);\n\treturn current;\n}\n\nexport async function fetchReceipt(\n\tclient: EmDashClient,\n\toperationId: string,\n\truntime: TransferRuntime,\n): Promise<CompletedImport> {\n\tconst { receipt } = await withRetry(runtime, \"Reading the receipt\", () =>\n\t\tclient.transferImportReceipt(operationId),\n\t);\n\treturn {\n\t\toperationId,\n\t\tstate: \"complete\",\n\t\treceipt,\n\t\treceiptDigestValid: await verifyReceiptDigest(receipt),\n\t};\n}\n\n/**\n * Execute a planned import after checking the reviewed plan digest, then\n * advance it to completion.\n */\nexport async function executeImport(\n\tclient: EmDashClient,\n\toperation: TransferOperation,\n\tplanDigest: string,\n\truntime: TransferRuntime,\n): Promise<CompletedImport> {\n\tlet current = operation;\n\tif (current.planDigest !== planDigest) {\n\t\tthrow new SiteTransferCliError(\n\t\t\t\"TRANSFER_PLAN_DIGEST_MISMATCH\",\n\t\t\t`The plan changed since it was reviewed: the current plan digest is ${current.planDigest ?? \"none\"}. Run with --analyze again and confirm the new digest.`,\n\t\t);\n\t}\n\tif (current.state === \"planned\" && current.stage !== \"reserve\") {\n\t\tif (!current.packageDigest) throw operationError(current);\n\t\tconst packageDigest = current.packageDigest;\n\t\tcurrent = (\n\t\t\tawait withRetry(runtime, \"Starting the import\", () =>\n\t\t\t\tclient.transferImportExecute(current.id, { packageDigest, planDigest }),\n\t\t\t)\n\t\t).operation;\n\t\truntime.reporter.info(`Executing import ${current.id}`);\n\t}\n\tconst complete = await driveExecution(client, current, runtime);\n\treturn fetchReceipt(client, complete.id, runtime);\n}\n\n// ── Commands ───────────────────────────────────────────────────\n\nexport interface AnalyzeOutcome extends PlannedImport {\n\tpackageDigest: string;\n}\n\n/** Scan, upload, and analyze a package, applying any decisions. */\nexport async function analyzePackage(\n\tclient: EmDashClient,\n\tarchivePath: string,\n\tflags: DecisionFlags,\n\truntime: TransferRuntime,\n): Promise<AnalyzeOutcome | CompletedImport | { operation: TransferOperation }> {\n\tconst { scan, opened } = await prepareImport(client, archivePath, runtime);\n\treturn continueToPlan(client, archivePath, scan, opened, flags, runtime);\n}\n\nasync function prepareImport(\n\tclient: EmDashClient,\n\tarchivePath: string,\n\truntime: TransferRuntime,\n): Promise<{ scan: ScannedSitePackage; opened: OpenedImport }> {\n\truntime.reporter.info(`Verifying ${archivePath}`);\n\tconst scan = await scanSitePackage(archivePath);\n\truntime.reporter.info(\n\t\t`Package ${scan.packageDigest}: ${scan.files.size + 1} files, ${formatBytes(scan.totalBytes)}`,\n\t);\n\tconst opened = await openImport(client, scan, runtime);\n\treturn { scan, opened };\n}\n\nasync function continueToPlan(\n\tclient: EmDashClient,\n\tarchivePath: string | null,\n\tscan: ScannedSitePackage | null,\n\topened: OpenedImport,\n\tflags: DecisionFlags,\n\truntime: TransferRuntime,\n): Promise<AnalyzeOutcome | CompletedImport | { operation: TransferOperation }> {\n\tconst operation = opened.operation;\n\tif (isExecuting(operation)) return { operation };\n\tswitch (operation.state) {\n\t\tcase \"uploading\": {\n\t\t\tif (!archivePath || !scan) {\n\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\"PACKAGE_FILE_REQUIRED\",\n\t\t\t\t\t`Import ${operation.id} is still uploading. Pass the package file to resume it: emdash site import resume ${operation.id} <file>`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst uploaded = await uploadPackage(client, archivePath, scan, opened, runtime);\n\t\t\truntime.reporter.info(`Uploaded ${uploaded.uploaded} files (${formatBytes(uploaded.bytes)})`);\n\t\t\treturn planWithDecisions(client, operation, flags, runtime);\n\t\t}\n\t\tcase \"analyzing\":\n\t\tcase \"planned\":\n\t\t\treturn planWithDecisions(client, operation, flags, runtime);\n\t\tcase \"complete\":\n\t\t\truntime.reporter.info(`Import ${operation.id} is already complete`);\n\t\t\treturn fetchReceipt(client, operation.id, runtime);\n\t\tdefault:\n\t\t\treturn { operation };\n\t}\n}\n\nasync function planWithDecisions(\n\tclient: EmDashClient,\n\toperation: TransferOperation,\n\tflags: DecisionFlags,\n\truntime: TransferRuntime,\n): Promise<AnalyzeOutcome> {\n\tlet planned = await driveAnalysis(client, operation, runtime);\n\tif (hasDecisions(flags)) {\n\t\tconst decisions = await resolveDecisions(client, planned.plan, flags, runtime);\n\t\tplanned = await applyDecisions(client, planned.operation.id, decisions, runtime);\n\t}\n\treturn { ...planned, packageDigest: planned.plan.packageDigest };\n}\n\n/** Scan, upload, and analyze if needed, then execute the confirmed plan. */\nexport async function confirmPackage(\n\tclient: EmDashClient,\n\tarchivePath: string,\n\tplanDigest: string,\n\truntime: TransferRuntime,\n): Promise<CompletedImport> {\n\tconst { scan, opened } = await prepareImport(client, archivePath, runtime);\n\treturn confirmOperation(client, archivePath, scan, opened, planDigest, runtime);\n}\n\nasync function confirmOperation(\n\tclient: EmDashClient,\n\tarchivePath: string | null,\n\tscan: ScannedSitePackage | null,\n\topened: OpenedImport,\n\tplanDigest: string,\n\truntime: TransferRuntime,\n): Promise<CompletedImport> {\n\tconst operation = opened.operation;\n\tif (operation.state === \"complete\") {\n\t\tif (operation.planDigest !== planDigest) {\n\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\"TRANSFER_PLAN_DIGEST_MISMATCH\",\n\t\t\t\t`Import ${operation.id} already completed with a different plan (${operation.planDigest ?? \"none\"})`,\n\t\t\t);\n\t\t}\n\t\treturn fetchReceipt(client, operation.id, runtime);\n\t}\n\tif (isExecuting(operation)) {\n\t\treturn executeImport(client, operation, planDigest, runtime);\n\t}\n\tconst outcome = await continueToPlan(\n\t\tclient,\n\t\tarchivePath,\n\t\tscan,\n\t\topened,\n\t\t{ mapPrincipal: [], useTargetTitle: false, useTargetTagline: false },\n\t\truntime,\n\t);\n\tif (!(\"plan\" in outcome)) {\n\t\tif (\"receipt\" in outcome) return outcome;\n\t\tthrow operationError(outcome.operation);\n\t}\n\tif (outcome.plan.blockers.length > 0) {\n\t\tthrow new SiteTransferCliError(\n\t\t\t\"TRANSFER_PLAN_BLOCKED\",\n\t\t\t`The import plan has ${outcome.plan.blockers.length} blocker(s). Run with --analyze to see them.`,\n\t\t);\n\t}\n\treturn executeImport(client, outcome.operation, planDigest, runtime);\n}\n\nexport async function importStatus(\n\tclient: EmDashClient,\n\toperationId: string,\n\truntime: TransferRuntime,\n): Promise<{ operation: TransferOperation; files: { declared: number; verified: number } }> {\n\treturn withRetry(runtime, \"Reading the import\", () => client.transferImportGet(operationId));\n}\n\n/**\n * Continue an import from whatever state it is in: upload what is missing\n * (needs the package file), finish analysis, or finish execution.\n */\nexport async function resumeImport(\n\tclient: EmDashClient,\n\toperationId: string,\n\tarchivePath: string | null,\n\truntime: TransferRuntime,\n): Promise<AnalyzeOutcome | CompletedImport | { operation: TransferOperation }> {\n\tconst { operation } = await importStatus(client, operationId, runtime);\n\tif (isExecuting(operation)) {\n\t\tconst complete = await driveExecution(client, operation, runtime);\n\t\treturn fetchReceipt(client, complete.id, runtime);\n\t}\n\tlet scan: ScannedSitePackage | null = null;\n\tif (operation.state === \"uploading\" && archivePath) {\n\t\truntime.reporter.info(`Verifying ${archivePath}`);\n\t\tscan = await scanSitePackage(archivePath);\n\t\tif (scan.packageDigest !== operation.packageDigest) {\n\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\"TRANSFER_PACKAGE_DIGEST_MISMATCH\",\n\t\t\t\t`${archivePath} is not the package import ${operation.id} was created from`,\n\t\t\t);\n\t\t}\n\t}\n\treturn continueToPlan(\n\t\tclient,\n\t\tarchivePath,\n\t\tscan,\n\t\t{ operation, fresh: false },\n\t\t{ mapPrincipal: [], useTargetTitle: false, useTargetTagline: false },\n\t\truntime,\n\t);\n}\n\nexport async function importReceipt(\n\tclient: EmDashClient,\n\toperationId: string,\n\truntime: TransferRuntime,\n): Promise<CompletedImport> {\n\treturn fetchReceipt(client, operationId, runtime);\n}\n\n/**\n * Resolve a refused cancel or abandon: a retry of a request whose response\n * was lost finds the import already in `state`.\n */\nasync function settledAs(\n\tclient: EmDashClient,\n\toperationId: string,\n\terror: unknown,\n\tstate: \"cancelled\" | \"abandoned\",\n\truntime: TransferRuntime,\n): Promise<TransferOperation> {\n\tif (!(error instanceof EmDashApiError) || error.code !== \"TRANSFER_INVALID_STATE\") throw error;\n\tconst { operation } = await importStatus(client, operationId, runtime);\n\tif (operation.state === state) return operation;\n\tthrow new SiteTransferCliError(\n\t\t\"TRANSFER_INVALID_STATE\",\n\t\tstate === \"abandoned\"\n\t\t\t? `Only a failed or cancelled import can be abandoned; import ${operationId} is ${operation.state}.`\n\t\t\t: `Import ${operationId} has already ended as ${operation.state}.`,\n\t);\n}\n\n/**\n * Cancel an import. An import no request is working on is cancelled at\n * once; one mid-step stops after its current batch.\n */\nexport async function cancelImport(\n\tclient: EmDashClient,\n\toperationId: string,\n\truntime: TransferRuntime,\n): Promise<TransferOperation> {\n\treturn withRetry(runtime, \"Cancelling the import\", () =>\n\t\tclient.transferImportCancel(operationId),\n\t).then(\n\t\t(result) => result.operation,\n\t\t(error: unknown) => settledAs(client, operationId, error, \"cancelled\", runtime),\n\t);\n}\n\n/** Abandon a failed or cancelled import: lift its write block, keeping what it wrote. */\nexport async function abandonImport(\n\tclient: EmDashClient,\n\toperationId: string,\n\truntime: TransferRuntime,\n): Promise<TransferOperation> {\n\treturn withRetry(runtime, \"Abandoning the import\", () =>\n\t\tclient.transferImportAbandon(operationId),\n\t).then(\n\t\t(result) => result.operation,\n\t\t(error: unknown) => settledAs(client, operationId, error, \"abandoned\", runtime),\n\t);\n}\n","/**\n * emdash site\n *\n * Export a whole site to a portable `.emdash` package, and import one into an\n * empty site.\n */\n\nimport { resolve } from \"node:path\";\nimport { createInterface } from \"node:readline/promises\";\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\n\nimport type { SiteImportPlan, TransferOperation } from \"../../client/index.js\";\nimport { connectionArgs, createClientFromArgs, resolveBaseUrl } from \"../client-factory.js\";\nimport { configureOutputMode, output } from \"../output.js\";\nimport { runSiteExport } from \"../site/export.js\";\nimport {\n\tabandonImport,\n\tanalyzePackage,\n\tcancelImport,\n\tconfirmPackage,\n\timportReceipt,\n\timportStatus,\n\tisExecuting,\n\tnormalizePlanDigest,\n\tresumeImport,\n\ttype AnalyzeOutcome,\n\ttype CompletedImport,\n\ttype DecisionFlags,\n} from \"../site/import.js\";\nimport {\n\tdescribeError,\n\tformatBytes,\n\tformatProgress,\n\tSiteTransferCliError,\n\ttransformationLabel,\n\ttype TransferRuntime,\n} from \"../site/shared.js\";\n\n/** Exit status when analysis produced a plan with blockers. */\nexport const EXIT_PLAN_BLOCKED = 2;\n\nconst IMPORT_ACTIONS = new Set([\"status\", \"resume\", \"receipt\", \"cancel\", \"abandon\"]);\n\n/** Import states `import status` reports with exit status 1. */\nconst UNSUCCESSFUL_STATES = new Set([\"failed\", \"cancelled\", \"abandoned\", \"expired\"]);\n\ninterface OutputArgs {\n\tjson?: boolean;\n}\n\nfunction wantsJson(args: OutputArgs): boolean {\n\treturn Boolean(args.json) || !process.stdout.isTTY;\n}\n\nfunction runtimeFor(): TransferRuntime {\n\tconst progress = consola.create({ stdout: process.stderr, stderr: process.stderr });\n\treturn {\n\t\treporter: {\n\t\t\tinfo: (message) => progress.info(message),\n\t\t\twarn: (message) => progress.warn(message),\n\t\t},\n\t};\n}\n\nasync function confirmOnTerminal(question: string): Promise<boolean> {\n\tconst prompt = createInterface({ input: process.stdin, output: process.stderr });\n\ttry {\n\t\tconst answer = (await prompt.question(`${question} [y/N] `)).trim().toLowerCase();\n\t\treturn answer === \"y\" || answer === \"yes\";\n\t} finally {\n\t\tprompt.close();\n\t}\n}\n\n/**\n * Ask before a cancel or abandon unless `--yes` or JSON output was chosen.\n * Without a terminal to ask on, the command needs `--yes`.\n */\nasync function confirmed(\n\targs: OutputArgs & { yes?: boolean },\n\taction: string,\n\toperationId: string,\n\tquestion: string,\n): Promise<boolean> {\n\tif (args.yes || wantsJson(args)) return true;\n\tif (!process.stdin.isTTY) {\n\t\tthrow new SiteTransferCliError(\n\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t`Pass --yes to ${action} import ${operationId} without a confirmation prompt`,\n\t\t);\n\t}\n\treturn confirmOnTerminal(question);\n}\n\nfunction fail(error: unknown, args: OutputArgs): void {\n\tconst info = describeError(error);\n\tif (wantsJson(args)) {\n\t\toutput({ error: info }, args);\n\t} else {\n\t\tconsola.error(info.message);\n\t}\n\tprocess.exitCode = 1;\n}\n\n/** Every value of a repeatable string flag, from the raw arguments. */\nexport function collectFlag(rawArgs: readonly string[], name: string): string[] {\n\tconst values: string[] = [];\n\tfor (let i = 0; i < rawArgs.length; i++) {\n\t\tconst arg = rawArgs[i];\n\t\tif (arg === `--${name}`) {\n\t\t\tconst next = rawArgs[i + 1];\n\t\t\tif (next !== undefined && !next.startsWith(\"--\")) {\n\t\t\t\tvalues.push(next);\n\t\t\t\ti++;\n\t\t\t} else {\n\t\t\t\tthrow new SiteTransferCliError(\"INVALID_ARGUMENT\", `--${name} needs a value`);\n\t\t\t}\n\t\t} else if (arg.startsWith(`--${name}=`)) {\n\t\t\tvalues.push(arg.slice(name.length + 3));\n\t\t}\n\t}\n\treturn values;\n}\n\n// ── Output shapes ──────────────────────────────────────────────\n\nexport function planJson(outcome: AnalyzeOutcome) {\n\treturn {\n\t\toperationId: outcome.operation.id,\n\t\tstate: outcome.operation.state,\n\t\tpackageDigest: outcome.packageDigest,\n\t\tplanDigest: outcome.planDigest,\n\t\texecutable: outcome.plan.blockers.length === 0,\n\t\tplan: outcome.plan,\n\t};\n}\n\nexport function operationJson(operation: TransferOperation) {\n\treturn { operationId: operation.id, state: operation.state, operation };\n}\n\nfunction printPlan(outcome: AnalyzeOutcome, archivePath: string | null): void {\n\tconst { plan } = outcome;\n\tconsola.log(`Import ${outcome.operation.id}`);\n\tconsola.log(` Package digest: ${outcome.packageDigest}`);\n\tconsola.log(` Plan digest: ${outcome.planDigest}`);\n\tconsola.log(\n\t\t` Origin: site ${plan.origin.siteId}, exported ${plan.origin.createdAt} by EmDash ${plan.origin.createdByEmDashVersion}`,\n\t);\n\tconst counts = Object.entries(plan.counts)\n\t\t.map(([kind, count]) => `${kind} ${count}`)\n\t\t.join(\", \");\n\tconsola.log(` Records: ${counts || \"none\"}`);\n\tconsola.log(\n\t\t` Size: records ${formatBytes(plan.bytes.records)}, media ${formatBytes(plan.bytes.media)}`,\n\t);\n\tprintSetting(\"Site title\", plan.settings.title, plan.decisions.siteTitle);\n\tprintSetting(\"Tagline\", plan.settings.tagline, plan.decisions.siteTagline);\n\n\tif (plan.principals.length > 0) {\n\t\tconsola.log(\" Principals (package users; map them with --map-principal <id>=<user|none>):\");\n\t\tfor (const principal of plan.principals) {\n\t\t\tconst mapped = plan.decisions.principalMappings[principal.id];\n\t\t\tconst target = mapped ? `user ${mapped}` : \"unassigned\";\n\t\t\tconst suggested =\n\t\t\t\tprincipal.suggestedUserId && principal.suggestedUserId !== mapped\n\t\t\t\t\t? `, suggested user ${principal.suggestedUserId}`\n\t\t\t\t\t: \"\";\n\t\t\tconst email = principal.email ? ` <${principal.email}>` : \"\";\n\t\t\tconsola.log(\n\t\t\t\t` ${principal.id} ${principal.displayName}${email}, ${principal.references} references -> ${target}${suggested}`,\n\t\t\t);\n\t\t}\n\t}\n\tprintTransformations(plan.transformations);\n\tprintIssues(\"Warnings\", plan.warnings);\n\tprintIssues(\"Blockers\", plan.blockers);\n\n\tif (plan.blockers.length > 0) {\n\t\tconsola.error(`The plan has ${plan.blockers.length} blocker(s); it cannot be executed.`);\n\t\treturn;\n\t}\n\tconst file = archivePath ?? \"<file>\";\n\tconsola.success(\n\t\t`Ready. To import, run:\\n emdash site import ${file} --plan ${outcome.planDigest} --confirm`,\n\t);\n}\n\nfunction printSetting(\n\tlabel: string,\n\tvalues: SiteImportPlan[\"settings\"][\"title\"],\n\tchoice: \"package\" | \"target\",\n): void {\n\tconst value = choice === \"package\" ? values.package : values.target;\n\tconsola.log(\n\t\t` ${`${label}:`.padEnd(16)}${JSON.stringify(value ?? \"\")} (from the ${choice}; package ${JSON.stringify(values.package ?? \"\")}, this site ${JSON.stringify(values.target ?? \"\")})`,\n\t);\n}\n\n/** Every declared difference from the source site, one line per code. */\nfunction printTransformations(transformations: SiteImportPlan[\"transformations\"]): void {\n\tconst groups = new Map<string, { count: number; kinds: Set<string>; details: string[] }>();\n\tfor (const transformation of transformations) {\n\t\tconst group = groups.get(transformation.code) ?? {\n\t\t\tcount: 0,\n\t\t\tkinds: new Set<string>(),\n\t\t\tdetails: [],\n\t\t};\n\t\tif (\"count\" in transformation) group.count += transformation.count;\n\t\telse if (\"ids\" in transformation) group.count += transformation.ids.length;\n\t\telse group.count += transformation.locales.length;\n\t\tif (\"kind\" in transformation) group.kinds.add(transformation.kind);\n\t\tif (\"locales\" in transformation) {\n\t\t\tfor (const { from, to } of transformation.locales) group.details.push(`${from} -> ${to}`);\n\t\t}\n\t\tif (\"items\" in transformation) {\n\t\t\tconst types = new Map<string, number>();\n\t\t\tfor (const item of transformation.items)\n\t\t\t\ttypes.set(item.type, (types.get(item.type) ?? 0) + 1);\n\t\t\tgroup.details.push(Array.from(types, ([type, count]) => `${type} ${count}`).join(\", \"));\n\t\t}\n\t\tgroups.set(transformation.code, group);\n\t}\n\tif (groups.size === 0) return;\n\tconsola.log(` Differences from the source site (${groups.size}):`);\n\tfor (const [code, group] of groups) {\n\t\tconst kinds = group.kinds.size > 0 ? ` [${[...group.kinds].join(\", \")}]` : \"\";\n\t\tconsola.log(` ${code}${kinds} x${group.count}: ${transformationLabel(code)}`);\n\t\tfor (const detail of group.details) consola.log(` ${detail}`);\n\t}\n}\n\nfunction printIssues(\n\tlabel: string,\n\tissues: ReadonlyArray<{ code: string; message: string; kind?: string; count?: number }>,\n): void {\n\tif (issues.length === 0) return;\n\tconsola.log(` ${label} (${issues.length}):`);\n\tfor (const issue of issues) {\n\t\tconst where = issue.kind ? ` [${issue.kind}]` : \"\";\n\t\tconst count = issue.count !== undefined ? ` x${issue.count}` : \"\";\n\t\tconsola.log(` ${issue.code}${where}${count}: ${issue.message}`);\n\t}\n}\n\nfunction printReceipt(result: CompletedImport): void {\n\tconst { receipt } = result;\n\tconsola.success(`Import ${result.operationId} is complete and verified.`);\n\tconsola.log(\n\t\t` Receipt digest: ${receipt.receiptDigest}${result.receiptDigestValid ? \"\" : \" (INVALID)\"}`,\n\t);\n\tconsola.log(` Package digest: ${receipt.packageDigest}`);\n\tconsola.log(` Plan digest: ${receipt.planDigest}`);\n\tconsola.log(` Logical digest: ${receipt.logicalDigest}`);\n\tconsola.log(` Completed: ${receipt.completedAt}`);\n\tconst counts = Object.entries(receipt.counts)\n\t\t.map(([kind, count]) => `${kind} ${count}`)\n\t\t.join(\", \");\n\tconsola.log(` Counts: ${counts || \"none\"}`);\n\tfor (const warning of receipt.warnings) consola.warn(`${warning.code}: ${warning.message}`);\n}\n\nfunction printOperation(\n\toperation: TransferOperation,\n\tfiles?: { declared: number; verified: number },\n): void {\n\tconsola.log(\n\t\t`Import ${operation.id}: ${operation.state}${operation.stage ? ` (${operation.stage})` : \"\"}`,\n\t);\n\tconst progress = formatProgress(operation.progress);\n\tif (progress) consola.log(` Progress: ${progress}`);\n\tif (files)\n\t\tconsola.log(` Files: ${files.verified} uploaded, ${files.declared} still missing`);\n\tif (operation.packageDigest) consola.log(` Package digest: ${operation.packageDigest}`);\n\tif (operation.planDigest) consola.log(` Plan digest: ${operation.planDigest}`);\n\tif (operation.errorCode) {\n\t\tconsola.warn(\n\t\t\t` Error: ${operation.errorCode}${operation.errorDetail ? ` ${JSON.stringify(operation.errorDetail)}` : \"\"}`,\n\t\t);\n\t}\n\tif (blocksWritesUntilAbandoned(operation)) {\n\t\tconsola.info(\n\t\t\t`It wrote to this site before it stopped, so site writes stay blocked until you abandon it: emdash site import abandon ${operation.id}`,\n\t\t);\n\t}\n}\n\nfunction blocksWritesUntilAbandoned(operation: TransferOperation): boolean {\n\treturn (\n\t\toperation.mutationStartedAt !== null &&\n\t\t(operation.state === \"failed\" || operation.state === \"cancelled\")\n\t);\n}\n\nfunction printCancelled(operation: TransferOperation): void {\n\tif (operation.state !== \"cancelled\") {\n\t\tconsola.success(\n\t\t\t`Cancellation requested. Import ${operation.id} stops after its current batch; check it with: emdash site import status ${operation.id}`,\n\t\t);\n\t\treturn;\n\t}\n\tconsola.success(`Import ${operation.id} is cancelled.`);\n\tif (blocksWritesUntilAbandoned(operation)) {\n\t\tconsola.info(\n\t\t\t`It had started writing to this site. The data it wrote stays, and site writes stay blocked until you abandon it: emdash site import abandon ${operation.id}`,\n\t\t);\n\t} else {\n\t\tconsola.info(\"It had not written anything to this site.\");\n\t}\n}\n\nfunction printAbandoned(operation: TransferOperation): void {\n\tconsola.success(`Import ${operation.id} is abandoned. The site accepts writes again.`);\n\tif (operation.mutationStartedAt !== null) {\n\t\tconsola.info(\n\t\t\t\"Data the import already wrote was not removed. Reset this site or set up a new one before importing again.\",\n\t\t);\n\t}\n}\n\n/** Print whatever an import command ended with and set the exit status. */\nfunction report(\n\toutcome: AnalyzeOutcome | CompletedImport | { operation: TransferOperation },\n\targs: OutputArgs,\n\tarchivePath: string | null,\n): void {\n\tif (\"receipt\" in outcome) {\n\t\tif (wantsJson(args)) output(outcome, args);\n\t\telse printReceipt(outcome);\n\t\tif (!outcome.receiptDigestValid) process.exitCode = 1;\n\t\treturn;\n\t}\n\tif (\"plan\" in outcome) {\n\t\tif (wantsJson(args)) output(planJson(outcome), args);\n\t\telse printPlan(outcome, archivePath);\n\t\tif (outcome.plan.blockers.length > 0) process.exitCode = EXIT_PLAN_BLOCKED;\n\t\treturn;\n\t}\n\tif (wantsJson(args)) {\n\t\toutput(operationJson(outcome.operation), args);\n\t} else {\n\t\tprintOperation(outcome.operation);\n\t\tif (isExecuting(outcome.operation)) {\n\t\t\tconsola.info(`Continue it with: emdash site import resume ${outcome.operation.id}`);\n\t\t}\n\t}\n\tif (!isExecuting(outcome.operation)) process.exitCode = 1;\n}\n\n// ── Commands ───────────────────────────────────────────────────\n\nconst exportCommand = defineCommand({\n\tmeta: {\n\t\tname: \"export\",\n\t\tdescription: \"Export the whole site to a .emdash package file\",\n\t},\n\targs: {\n\t\t...connectionArgs,\n\t\toutput: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"o\",\n\t\t\tdescription: \"Package file to write (e.g. site.emdash)\",\n\t\t\trequired: true,\n\t\t},\n\t\tcomments: {\n\t\t\ttype: \"boolean\",\n\t\t\tdefault: true,\n\t\t\tdescription: \"Include comments and reactions (--no-comments leaves them out)\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst result = await runSiteExport(\n\t\t\t\t{\n\t\t\t\t\tclient,\n\t\t\t\t\tbaseUrl: resolveBaseUrl(args),\n\t\t\t\t\toutputPath: resolve(args.output),\n\t\t\t\t\tcomments: args.comments !== false,\n\t\t\t\t},\n\t\t\t\truntimeFor(),\n\t\t\t);\n\t\t\tif (wantsJson(args)) {\n\t\t\t\toutput(result, args);\n\t\t\t} else {\n\t\t\t\tconsola.success(\n\t\t\t\t\t`Exported ${result.files} files (${formatBytes(result.bytes)}) to ${result.output}`,\n\t\t\t\t);\n\t\t\t\tconsola.log(` Package digest: ${result.packageDigest}`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tfail(error, args);\n\t\t}\n\t},\n});\n\nconst importCommand = defineCommand({\n\tmeta: {\n\t\tname: \"import\",\n\t\tdescription: [\n\t\t\t\"Import a .emdash package into an empty site: `import <file> --analyze`, then `import <file> --plan <digest> --confirm`.\",\n\t\t\t\"Manage an import with `import status|resume|receipt|cancel|abandon <operation-id>`. `cancel` stops the import after its current batch. `abandon` lifts the write block that a failed or cancelled import leaves on the site; it does not delete what the import wrote.\",\n\t\t\t\"Exit codes: 0 success, and for `status` an import in progress or complete; 1 an error, a declined prompt, or for `status` an import that failed, was cancelled or abandoned, or expired; 2 the import plan has blockers.\",\n\t\t].join(\"\\n\\n\"),\n\t},\n\targs: {\n\t\ttarget: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Package file, or status | resume | receipt | cancel | abandon\",\n\t\t\trequired: true,\n\t\t},\n\t\t...connectionArgs,\n\t\tanalyze: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Upload and analyze the package, then print the import plan\",\n\t\t},\n\t\t\"map-principal\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription:\n\t\t\t\t\"With --analyze: map a package user to a site user, <principal id|email>=<user id|email|none> (repeatable)\",\n\t\t},\n\t\t\"use-target-title\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"With --analyze: keep this site's title instead of the package's\",\n\t\t},\n\t\t\"use-target-tagline\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"With --analyze: keep this site's tagline instead of the package's\",\n\t\t},\n\t\tplan: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Plan digest printed by --analyze; required with --confirm\",\n\t\t},\n\t\tconfirm: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Execute the import plan given by --plan\",\n\t\t},\n\t\tyes: {\n\t\t\ttype: \"boolean\",\n\t\t\talias: \"y\",\n\t\t\tdescription: \"With cancel or abandon: skip the confirmation prompt\",\n\t\t},\n\t},\n\tasync run({ args, rawArgs }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst positionals = args._.map(String);\n\t\t\tconst action = IMPORT_ACTIONS.has(args.target) ? args.target : null;\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst runtime = runtimeFor();\n\n\t\t\tif (action) {\n\t\t\t\tconst operationId = positionals[1];\n\t\t\t\tif (!operationId) {\n\t\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t\t\t`Usage: emdash site import ${action} <operation-id>`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (action === \"status\") {\n\t\t\t\t\tconst status = await importStatus(client, operationId, runtime);\n\t\t\t\t\tif (wantsJson(args)) output(status, args);\n\t\t\t\t\telse printOperation(status.operation, status.files);\n\t\t\t\t\tif (UNSUCCESSFUL_STATES.has(status.operation.state)) process.exitCode = 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"cancel\" || action === \"abandon\") {\n\t\t\t\t\tconst question =\n\t\t\t\t\t\taction === \"cancel\"\n\t\t\t\t\t\t\t? `Cancel import ${operationId}? A running import stops after its current batch. Anything it already wrote stays on the site.`\n\t\t\t\t\t\t\t: `Abandon import ${operationId}? Site writes are unblocked, but data the import already wrote is not deleted.`;\n\t\t\t\t\tif (!(await confirmed(args, action, operationId, question))) {\n\t\t\t\t\t\tconsola.info(\"Nothing was changed.\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst operation =\n\t\t\t\t\t\taction === \"cancel\"\n\t\t\t\t\t\t\t? await cancelImport(client, operationId, runtime)\n\t\t\t\t\t\t\t: await abandonImport(client, operationId, runtime);\n\t\t\t\t\tif (wantsJson(args)) output(operationJson(operation), args);\n\t\t\t\t\telse if (action === \"cancel\") printCancelled(operation);\n\t\t\t\t\telse printAbandoned(operation);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"receipt\") {\n\t\t\t\t\treport(await importReceipt(client, operationId, runtime), args, null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst archive = positionals[2] ? resolve(positionals[2]) : null;\n\t\t\t\treport(await resumeImport(client, operationId, archive, runtime), args, archive);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst archivePath = resolve(args.target);\n\t\t\tconst mapPrincipal = collectFlag(rawArgs, \"map-principal\");\n\t\t\tconst flags: DecisionFlags = {\n\t\t\t\tmapPrincipal,\n\t\t\t\tuseTargetTitle: Boolean(args[\"use-target-title\"]),\n\t\t\t\tuseTargetTagline: Boolean(args[\"use-target-tagline\"]),\n\t\t\t};\n\t\t\tif (args.confirm && !args.plan) {\n\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t\t\"--confirm needs --plan <digest>: review the plan with --analyze first\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (args.plan && !args.confirm) {\n\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t\t\"--plan executes an import only together with --confirm\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (args.plan && args.analyze) {\n\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t\t\"Use either --analyze or --plan <digest> --confirm, not both\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (args.plan) {\n\t\t\t\tif (mapPrincipal.length > 0 || flags.useTargetTitle || flags.useTargetTagline) {\n\t\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t\t\t\"Decisions can only be changed with --analyze; they change the plan digest\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst planDigest = normalizePlanDigest(args.plan);\n\t\t\t\treport(await confirmPackage(client, archivePath, planDigest, runtime), args, archivePath);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!args.analyze) {\n\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t\t\"Choose --analyze to review the import plan, or --plan <digest> --confirm to run it\",\n\t\t\t\t);\n\t\t\t}\n\t\t\treport(await analyzePackage(client, archivePath, flags, runtime), args, archivePath);\n\t\t} catch (error) {\n\t\t\tfail(error, args);\n\t\t}\n\t},\n});\n\nexport const siteCommand = defineCommand({\n\tmeta: {\n\t\tname: \"site\",\n\t\tdescription: \"Export or import a whole site as a .emdash package\",\n\t},\n\tsubCommands: {\n\t\texport: exportCommand,\n\t\timport: importCommand,\n\t},\n});\n","/**\n * emdash taxonomy\n *\n * Manage taxonomies and terms via the EmDash REST API.\n */\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\n\nimport { connectionArgs, createClientFromArgs } from \"../client-factory.js\";\nimport { configureOutputMode, output } from \"../output.js\";\n\n/** Pattern to replace whitespace with hyphens for slug generation */\nconst WHITESPACE_PATTERN = /\\s+/g;\n\nconst listCommand = defineCommand({\n\tmeta: {\n\t\tname: \"list\",\n\t\tdescription: \"List all taxonomies\",\n\t},\n\targs: {\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst taxonomies = await client.taxonomies();\n\t\t\toutput(taxonomies, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst termsCommand = defineCommand({\n\tmeta: {\n\t\tname: \"terms\",\n\t\tdescription: \"List terms in a taxonomy\",\n\t},\n\targs: {\n\t\tname: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Taxonomy name\",\n\t\t\trequired: true,\n\t\t},\n\t\tlimit: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"l\",\n\t\t\tdescription: \"Maximum terms to return\",\n\t\t},\n\t\tcursor: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Pagination cursor\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst result = await client.terms(args.name, {\n\t\t\t\tlimit: args.limit ? parseInt(args.limit, 10) : undefined,\n\t\t\t\tcursor: args.cursor,\n\t\t\t});\n\t\t\toutput(result, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst addTermCommand = defineCommand({\n\tmeta: {\n\t\tname: \"add-term\",\n\t\tdescription: \"Create a term in a taxonomy\",\n\t},\n\targs: {\n\t\ttaxonomy: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Taxonomy name\",\n\t\t\trequired: true,\n\t\t},\n\t\tname: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Term label\",\n\t\t\trequired: true,\n\t\t},\n\t\tslug: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Term slug (defaults to slugified name)\",\n\t\t},\n\t\tparent: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Parent term ID\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst label = args.name;\n\t\t\tconst slug = args.slug || label.toLowerCase().replace(WHITESPACE_PATTERN, \"-\");\n\t\t\tconst term = await client.createTerm(args.taxonomy, {\n\t\t\t\tslug,\n\t\t\t\tlabel,\n\t\t\t\tparentId: args.parent,\n\t\t\t});\n\t\t\tconsola.success(`Created term \"${label}\" in ${args.taxonomy}`);\n\t\t\toutput(term, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nexport const taxonomyCommand = defineCommand({\n\tmeta: {\n\t\tname: \"taxonomy\",\n\t\tdescription: \"Manage taxonomies and terms\",\n\t},\n\tsubCommands: {\n\t\tlist: listCommand,\n\t\tterms: termsCommand,\n\t\t\"add-term\": addTermCommand,\n\t},\n});\n","/**\n * emdash types\n *\n * Fetch schema from an EmDash instance and generate TypeScript types\n */\n\nimport { writeFile, mkdir } from \"node:fs/promises\";\nimport { resolve, dirname } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport consola from \"consola\";\n\nimport { connectionArgs, createClientFromArgs } from \"../client-factory.js\";\n\nexport const typesCommand = defineCommand({\n\tmeta: {\n\t\tname: \"types\",\n\t\tdescription: \"Generate TypeScript types from schema\",\n\t},\n\targs: {\n\t\t...connectionArgs,\n\t\toutput: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"o\",\n\t\t\tdescription: \"Output path for generated types\",\n\t\t\tdefault: \".emdash/types.ts\",\n\t\t},\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Working directory\",\n\t\t\tdefault: process.cwd(),\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst cwd = resolve(args.cwd);\n\t\tconsola.start(\"Fetching schema...\");\n\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\n\t\t\t// Fetch JSON schema\n\t\t\tconst schema = await client.schemaExport();\n\t\t\tconsola.success(`Found ${schema.collections.length} collections`);\n\n\t\t\t// Fetch TypeScript types\n\t\t\tconst types = await client.schemaTypes();\n\n\t\t\t// Write types file\n\t\t\tconst outputPath = resolve(cwd, args.output);\n\t\t\tawait mkdir(dirname(outputPath), { recursive: true });\n\t\t\tawait writeFile(outputPath, types, \"utf-8\");\n\t\t\tconsola.success(`Generated ${args.output}`);\n\n\t\t\t// Also write a schema.json for reference\n\t\t\tconst schemaJsonPath = resolve(dirname(outputPath), \"schema.json\");\n\t\t\tawait writeFile(schemaJsonPath, JSON.stringify(schema, null, 2), \"utf-8\");\n\t\t\tconsola.info(`Schema version: ${schema.version}`);\n\n\t\t\tconsola.box({\n\t\t\t\ttitle: \"Types generated\",\n\t\t\t\tmessage: `${schema.collections.length} collections\\n\\nTypes: ${args.output}\\nSchema: .emdash/schema.json`,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Failed to fetch schema:\", error instanceof Error ? error.message : error);\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n","#!/usr/bin/env node\n\nimport { defineCommand, runMain } from \"citty\";\n\nimport { authCommand } from \"./commands/auth.js\";\nimport { contentCommand } from \"./commands/content.js\";\nimport { devCommand } from \"./commands/dev.js\";\nimport { doctorCommand } from \"./commands/doctor.js\";\nimport { exportSeedCommand } from \"./commands/export-seed.js\";\nimport { initCommand } from \"./commands/init.js\";\nimport { loginCommand, logoutCommand, whoamiCommand } from \"./commands/login.js\";\nimport { mediaCommand } from \"./commands/media.js\";\nimport { menuCommand } from \"./commands/menu.js\";\nimport { migrateCommand } from \"./commands/migrate.js\";\nimport { pluginCommand } from \"./commands/plugin.js\";\nimport { schemaCommand } from \"./commands/schema.js\";\nimport { searchCommand } from \"./commands/search-cmd.js\";\nimport { secretsCommand } from \"./commands/secrets.js\";\nimport { seedCommand } from \"./commands/seed.js\";\nimport { siteCommand } from \"./commands/site.js\";\nimport { taxonomyCommand } from \"./commands/taxonomy.js\";\nimport { typesCommand } from \"./commands/types.js\";\n\nconst main = defineCommand({\n\tmeta: {\n\t\tname: \"emdash\",\n\t\tversion: \"0.0.0\",\n\t\tdescription: \"CLI for EmDash CMS\",\n\t},\n\tsubCommands: {\n\t\tinit: initCommand,\n\t\ttypes: typesCommand,\n\t\tdev: devCommand,\n\t\tdoctor: doctorCommand,\n\t\tseed: seedCommand,\n\t\tmigrate: migrateCommand,\n\t\t\"export-seed\": exportSeedCommand,\n\t\tsecrets: secretsCommand,\n\t\t// Deprecated alias kept for backwards compat; will be removed in a future minor.\n\t\tauth: authCommand,\n\t\tlogin: loginCommand,\n\t\tlogout: logoutCommand,\n\t\twhoami: whoamiCommand,\n\t\tcontent: contentCommand,\n\t\tschema: schemaCommand,\n\t\tmedia: mediaCommand,\n\t\tsearch: searchCommand,\n\t\ttaxonomy: taxonomyCommand,\n\t\tmenu: menuCommand,\n\t\tplugin: pluginCommand,\n\t\tsite: siteCommand,\n\t},\n});\n\nvoid runMain(main);\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["findProjectRoot","listCommand","getCommand","createCommand","deleteCommand","publishCommand","readPackageJson","fileExists","fileExists","isRecord","parseToml","parse","fileExists","readPackageJson","listCommand","getCommand","deleteCommand","listCommand","getCommand","isRecord","moduleExport","defaultDependencies","fileExists","listCommand","commonArgs","consola","consola"],"sources":["../../src/cli/commands/auth.ts","../../src/cli/credentials.ts","../../src/cli/client-factory.ts","../../src/cli/output.ts","../../src/cli/commands/content.ts","../../src/database/connection.ts","../../src/cli/commands/dev.ts","../../src/cli/commands/doctor.ts","../../src/cli/commands/export-seed.ts","../../src/cli/commands/init.ts","../../src/cli/commands/login.ts","../../src/cli/commands/media.ts","../../src/cli/commands/menu.ts","../../src/migrations/config-loader.ts","../../src/cli/commands/migrate.ts","../../src/cli/commands/plugin-init.ts","../../src/cli/commands/plugin-validate.ts","../../src/cli/commands/publish.ts","../../src/cli/commands/plugin.ts","../../src/cli/commands/schema.ts","../../src/cli/commands/search-cmd.ts","../../src/cli/commands/secrets.ts","../../src/cli/commands/seed.ts","../../src/cli/site/archive.ts","../../src/cli/site/shared.ts","../../src/cli/site/export.ts","../../src/cli/site/import.ts","../../src/cli/commands/site.ts","../../src/cli/commands/taxonomy.ts","../../src/cli/commands/types.ts","../../src/cli/index.ts"],"sourcesContent":["/**\n * Auth CLI commands (deprecated)\n *\n * Kept as a deprecated alias for backwards compatibility. The original\n * `emdash auth secret` was documented in published docs and is plausibly\n * scripted in user CI (e.g. `npx emdash auth secret >> .env`). Removing\n * it outright would break those scripts on minor-version upgrade.\n *\n * The command still emits an `EMDASH_AUTH_SECRET=<32-byte-base64url>`\n * line, unchanged. `EMDASH_AUTH_SECRET` itself is now legacy: it's only\n * read as a fallback source for the commenter-IP hash salt so installs\n * upgrading from a prior version keep stable IP hashes (and therefore\n * stable rate-limit buckets). New installs don't need to set it.\n *\n * The deprecation note steers users toward `emdash secrets generate`\n * (which emits a different, versioned `emdash_enc_v1_*` value for\n * `EMDASH_ENCRYPTION_KEY` — used to encrypt plugin secrets at rest).\n *\n * Will be removed in a future minor.\n */\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\nimport pc from \"picocolors\";\n\nimport { encodeBase64url } from \"../../utils/base64.js\";\n\nfunction generateAuthSecret(): string {\n\tconst bytes = new Uint8Array(32);\n\tcrypto.getRandomValues(bytes);\n\treturn encodeBase64url(bytes);\n}\n\nconst secretCommand = defineCommand({\n\tmeta: {\n\t\tname: \"secret\",\n\t\tdescription: \"[DEPRECATED] Generate a value for legacy EMDASH_AUTH_SECRET\",\n\t},\n\trun() {\n\t\tconst secret = generateAuthSecret();\n\n\t\t// Match the original behavior verbatim: pretty-printed name=value\n\t\t// on stdout (most scripts piped this to a file expecting that shape).\n\t\tconsola.log(\"\");\n\t\tconsola.log(pc.bold(\"Generated auth secret:\"));\n\t\tconsola.log(\"\");\n\t\tconsola.log(` ${pc.cyan(\"EMDASH_AUTH_SECRET\")}=${pc.green(secret)}`);\n\t\tconsola.log(\"\");\n\t\tconsola.log(pc.dim(\"Add this to your environment variables.\"));\n\t\tconsola.log(\"\");\n\t\t// Deprecation note on stderr so it doesn't break stdout consumers.\n\t\tprocess.stderr.write(\n\t\t\t`${pc.yellow(\"Note:\")} ${pc.bold(\"emdash auth secret\")} is deprecated and will be removed in a future minor. ` +\n\t\t\t\t`${pc.cyan(\"EMDASH_AUTH_SECRET\")} itself is now optional — it's only used as a legacy fallback for the commenter-IP hash salt. ` +\n\t\t\t\t`For encrypting plugin secrets at rest, use ${pc.bold(\"emdash secrets generate\")} (a different secret: ${pc.cyan(\"EMDASH_ENCRYPTION_KEY\")}).\\n`,\n\t\t);\n\t},\n});\n\nexport const authCommand = defineCommand({\n\tmeta: {\n\t\tname: \"auth\",\n\t\tdescription: \"[DEPRECATED] Authentication utilities (use `emdash secrets` for new flows)\",\n\t},\n\tsubCommands: {\n\t\tsecret: secretCommand,\n\t},\n});\n","/**\n * Credential storage for CLI auth tokens.\n *\n * Stores OAuth tokens in ~/.config/emdash/auth.json.\n * Remote URLs are keyed by origin, local dev by project path.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface StoredCredential {\n\taccessToken: string;\n\trefreshToken: string;\n\texpiresAt: string;\n\turl?: string; // For local dev: the localhost URL\n\t/** Custom headers to send with every request (e.g. CF Access service token) */\n\tcustomHeaders?: Record<string, string>;\n\tuser?: {\n\t\temail: string;\n\t\trole: string;\n\t};\n}\n\n/** Credential for marketplace auth (GitHub OAuth JWT, no refresh token) */\nexport interface MarketplaceCredential {\n\ttoken: string;\n\texpiresAt: string;\n\tauthor?: {\n\t\tid: string;\n\t\tname: string;\n\t};\n}\n\ntype CredentialStore = Record<string, StoredCredential | MarketplaceCredential>;\n\n// ---------------------------------------------------------------------------\n// Paths\n// ---------------------------------------------------------------------------\n\nfunction getConfigDir(): string {\n\t// XDG_CONFIG_HOME or ~/.config\n\tconst xdg = process.env[\"XDG_CONFIG_HOME\"];\n\tif (xdg) return join(xdg, \"emdash\");\n\treturn join(homedir(), \".config\", \"emdash\");\n}\n\nfunction getCredentialPath(): string {\n\treturn join(getConfigDir(), \"auth.json\");\n}\n\n// ---------------------------------------------------------------------------\n// Key resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the credential key for a given URL.\n *\n * Remote URLs are keyed by origin (e.g. \"https://my-site.pages.dev\").\n * Local dev instances are keyed by project path (e.g. \"path:/Users/matt/sites/blog\").\n */\nexport function resolveCredentialKey(baseUrl: string): string {\n\ttry {\n\t\tconst url = new URL(baseUrl);\n\t\tconst isLocal =\n\t\t\turl.hostname === \"localhost\" || url.hostname === \"127.0.0.1\" || url.hostname === \"[::1]\";\n\n\t\tif (isLocal) {\n\t\t\t// For local dev, key by project path\n\t\t\tconst projectPath = findProjectRoot(process.cwd());\n\t\t\tif (projectPath) {\n\t\t\t\treturn `path:${projectPath}`;\n\t\t\t}\n\t\t\t// Fallback to URL if no project root found\n\t\t\treturn url.origin;\n\t\t}\n\n\t\treturn url.origin;\n\t} catch {\n\t\treturn baseUrl;\n\t}\n}\n\n/**\n * Walk up from cwd to find the project root (directory containing astro.config.*).\n */\nfunction findProjectRoot(from: string): string | null {\n\tlet dir = resolve(from);\n\tconst root = resolve(\"/\");\n\n\twhile (dir !== root) {\n\t\tfor (const name of [\n\t\t\t\"astro.config.ts\",\n\t\t\t\"astro.config.mts\",\n\t\t\t\"astro.config.js\",\n\t\t\t\"astro.config.mjs\",\n\t\t]) {\n\t\t\tif (existsSync(join(dir, name))) {\n\t\t\t\treturn dir;\n\t\t\t}\n\t\t}\n\t\tconst parent = resolve(dir, \"..\");\n\t\tif (parent === dir) break;\n\t\tdir = parent;\n\t}\n\n\treturn null;\n}\n\n// ---------------------------------------------------------------------------\n// Read/write\n// ---------------------------------------------------------------------------\n\nfunction readStore(): CredentialStore {\n\tconst path = getCredentialPath();\n\ttry {\n\t\tif (existsSync(path)) {\n\t\t\tconst content = readFileSync(path, \"utf-8\");\n\t\t\treturn JSON.parse(content) as CredentialStore;\n\t\t}\n\t} catch {\n\t\t// Corrupt file — start fresh\n\t}\n\treturn {};\n}\n\nfunction writeStore(store: CredentialStore): void {\n\tconst dir = getConfigDir();\n\tmkdirSync(dir, { recursive: true, mode: 0o700 });\n\n\tconst path = getCredentialPath();\n\twriteFileSync(path, JSON.stringify(store, null, \"\\t\"), {\n\t\tencoding: \"utf-8\",\n\t\tmode: 0o600, // Owner read/write only\n\t});\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Get stored credentials for a URL.\n */\nexport function getCredentials(baseUrl: string): StoredCredential | null {\n\tconst key = resolveCredentialKey(baseUrl);\n\tconst store = readStore();\n\tconst cred = store[key];\n\tif (!cred || !(\"accessToken\" in cred)) return null;\n\treturn cred;\n}\n\n/**\n * Save credentials for a URL.\n */\nexport function saveCredentials(baseUrl: string, cred: StoredCredential): void {\n\tconst key = resolveCredentialKey(baseUrl);\n\tconst store = readStore();\n\tstore[key] = cred;\n\twriteStore(store);\n}\n\n/**\n * Remove credentials for a URL.\n */\nexport function removeCredentials(baseUrl: string): boolean {\n\tconst key = resolveCredentialKey(baseUrl);\n\tconst store = readStore();\n\tif (key in store) {\n\t\tdelete store[key];\n\t\twriteStore(store);\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/**\n * List all stored credential keys.\n */\nexport function listCredentialKeys(): string[] {\n\tconst store = readStore();\n\treturn Object.keys(store);\n}\n\n// ---------------------------------------------------------------------------\n// Marketplace credentials\n// ---------------------------------------------------------------------------\n\nfunction marketplaceKey(registryUrl: string): string {\n\ttry {\n\t\treturn `marketplace:${new URL(registryUrl).origin}`;\n\t} catch {\n\t\treturn `marketplace:${registryUrl}`;\n\t}\n}\n\n/**\n * Get stored marketplace credential for a registry URL.\n */\nexport function getMarketplaceCredential(registryUrl: string): MarketplaceCredential | null {\n\tconst key = marketplaceKey(registryUrl);\n\tconst store = readStore();\n\tconst cred = store[key];\n\tif (!cred || !(\"token\" in cred)) return null;\n\t// Check expiry\n\tif (new Date(cred.expiresAt) < new Date()) return null;\n\treturn cred;\n}\n\n/**\n * Save marketplace credential for a registry URL.\n */\nexport function saveMarketplaceCredential(registryUrl: string, cred: MarketplaceCredential): void {\n\tconst key = marketplaceKey(registryUrl);\n\tconst store = readStore();\n\tstore[key] = cred;\n\twriteStore(store);\n}\n\n/**\n * Remove marketplace credential for a registry URL.\n */\nexport function removeMarketplaceCredential(registryUrl: string): boolean {\n\tconst key = marketplaceKey(registryUrl);\n\tconst store = readStore();\n\tif (key in store) {\n\t\tdelete store[key];\n\t\twriteStore(store);\n\t\treturn true;\n\t}\n\treturn false;\n}\n","import { customHeadersInterceptor, resolveCustomHeaders } from \"../client/cf-access.js\";\nimport { EmDashClient } from \"../client/index.js\";\nimport type { Interceptor } from \"../client/transport.js\";\nimport { getCredentials, saveCredentials } from \"./credentials.js\";\n\nexport interface ClientArgs {\n\turl?: string;\n\ttoken?: string;\n}\n\n/**\n * Shared connection args for all CLI commands that talk to an EmDash instance.\n * Spread into each command's `args` definition.\n */\nexport const connectionArgs = {\n\turl: {\n\t\ttype: \"string\" as const,\n\t\talias: \"u\",\n\t\tdescription: \"EmDash instance URL\",\n\t},\n\ttoken: {\n\t\ttype: \"string\" as const,\n\t\talias: \"t\",\n\t\tdescription: \"Auth token\",\n\t},\n\theader: {\n\t\ttype: \"string\" as const,\n\t\talias: \"H\",\n\t\tdescription: 'Custom header \"Name: Value\" (repeatable, or use EMDASH_HEADERS env)',\n\t},\n\tjson: {\n\t\ttype: \"boolean\" as const,\n\t\tdescription: \"Output as JSON\",\n\t},\n};\n\n/** The instance URL from `--url`, `EMDASH_URL`, or the local dev default. */\nexport function resolveBaseUrl(args: ClientArgs): string {\n\treturn args.url || process.env[\"EMDASH_URL\"] || \"http://localhost:4321\";\n}\n\n/**\n * Create an EmDashClient from CLI args, env vars, and stored credentials.\n *\n * Auth resolution order:\n * 1. --token flag\n * 2. EMDASH_TOKEN env var\n * 3. Stored credentials (~/.config/emdash/auth.json)\n * 4. Dev bypass (if URL is localhost)\n *\n * Custom headers are merged from (in priority order):\n * 1. Stored credentials (persisted during `emdash login --header`)\n * 2. EMDASH_HEADERS env var\n * 3. --header CLI flags\n */\nexport function createClientFromArgs(args: ClientArgs): EmDashClient {\n\tconst baseUrl = resolveBaseUrl(args);\n\tlet token = args.token || process.env[\"EMDASH_TOKEN\"];\n\n\tconst isLocal = baseUrl.includes(\"localhost\") || baseUrl.includes(\"127.0.0.1\");\n\tconst cred = !token ? getCredentials(baseUrl) : null;\n\n\t// Merge custom headers: stored credentials < env var < CLI flags\n\tconst customHeaders = {\n\t\t...cred?.customHeaders,\n\t\t...resolveCustomHeaders(),\n\t};\n\n\tconst extraInterceptors: Interceptor[] = [];\n\tif (Object.keys(customHeaders).length > 0) {\n\t\textraInterceptors.push(customHeadersInterceptor(customHeaders));\n\t}\n\n\t// Check stored credentials if no explicit token\n\tif (!token && cred) {\n\t\t// Check if access token is expired\n\t\tif (new Date(cred.expiresAt) > new Date()) {\n\t\t\ttoken = cred.accessToken;\n\t\t} else {\n\t\t\t// Token expired — use the refresh interceptor in the client\n\t\t\t// Pass the refresh token so the client can auto-refresh\n\t\t\treturn new EmDashClient({\n\t\t\t\tbaseUrl,\n\t\t\t\ttoken: cred.accessToken,\n\t\t\t\trefreshToken: cred.refreshToken,\n\t\t\t\tonTokenRefresh: (newAccessToken, expiresIn) => {\n\t\t\t\t\tsaveCredentials(baseUrl, {\n\t\t\t\t\t\t...cred,\n\t\t\t\t\t\taccessToken: newAccessToken,\n\t\t\t\t\t\texpiresAt: new Date(Date.now() + expiresIn * 1000).toISOString(),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tinterceptors: extraInterceptors,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn new EmDashClient({\n\t\tbaseUrl,\n\t\ttoken,\n\t\tdevBypass: !token && isLocal,\n\t\tinterceptors: extraInterceptors,\n\t});\n}\n","import { consola } from \"consola\";\n\ninterface OutputArgs {\n\tjson?: boolean;\n}\n\n/**\n * Redirect consola output to stderr so it doesn't pollute JSON on stdout.\n *\n * Call this early in any command that uses `output()` with `--json`.\n * Safe to call multiple times — only applies the redirect once.\n */\nexport function configureOutputMode(args: OutputArgs): void {\n\tif (args.json || !process.stdout.isTTY) {\n\t\t// Send all consola output to stderr so stdout is clean JSON\n\t\tconsola.options.stdout = process.stderr;\n\t\tconsola.options.stderr = process.stderr;\n\t}\n}\n\n/**\n * Output data as JSON or pretty-printed.\n *\n * If stdout is not a TTY or --json is set, outputs JSON.\n * Otherwise, outputs a formatted representation.\n */\nexport function output(data: unknown, args: OutputArgs): void {\n\tconst useJson = args.json || !process.stdout.isTTY;\n\n\tif (useJson) {\n\t\t// JSON output to stdout for piping\n\t\tprocess.stdout.write(JSON.stringify(data, null, 2) + \"\\n\");\n\t} else {\n\t\t// Pretty output via consola\n\t\tprettyPrint(data);\n\t}\n}\n\nfunction prettyPrint(data: unknown, indent: number = 0): void {\n\tif (data === null || data === undefined) {\n\t\tconsola.log(\"(empty)\");\n\t\treturn;\n\t}\n\n\tif (Array.isArray(data)) {\n\t\tif (data.length === 0) {\n\t\t\tconsola.log(\"(no items)\");\n\t\t\treturn;\n\t\t}\n\t\tfor (const item of data) {\n\t\t\tprettyPrint(item, indent);\n\t\t\tif (indent === 0) consola.log(\"---\");\n\t\t}\n\t\treturn;\n\t}\n\n\tif (typeof data === \"object\") {\n\t\tconst obj = Object(data) as Record<string, unknown>;\n\n\t\t// Check if it's a list result with items\n\t\tif (\"items\" in obj && Array.isArray(obj.items)) {\n\t\t\tprettyPrint(obj.items, indent);\n\t\t\tif (typeof obj.nextCursor === \"string\") {\n\t\t\t\tconsola.log(`\\nNext cursor: ${obj.nextCursor}`);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Print object fields\n\t\tconst prefix = \" \".repeat(indent);\n\t\tfor (const [key, value] of Object.entries(obj)) {\n\t\t\tif (value === null || value === undefined) continue;\n\t\t\tif (typeof value === \"object\" && !Array.isArray(value)) {\n\t\t\t\tconsola.log(`${prefix}${key}:`);\n\t\t\t\tprettyPrint(value, indent + 1);\n\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\tconsola.log(`${prefix}${key}: [${value.length} items]`);\n\t\t\t} else {\n\t\t\t\tconst str = typeof value === \"string\" ? value : JSON.stringify(value);\n\t\t\t\t// Truncate long values\n\t\t\t\tconst display = str.length > 80 ? str.slice(0, 77) + \"...\" : str;\n\t\t\t\tconsola.log(`${prefix}${key}: ${display}`);\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\n\tconsola.log(typeof data === \"string\" ? data : JSON.stringify(data));\n}\n","/**\n * emdash content\n *\n * CRUD commands for managing content items via the EmDash REST API.\n */\n\nimport { readFile } from \"node:fs/promises\";\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\n\nimport { convertDataForRead } from \"../../client/portable-text.js\";\nimport { connectionArgs, createClientFromArgs } from \"../client-factory.js\";\nimport { configureOutputMode, output } from \"../output.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Read content data from --data, --file, or --stdin */\nasync function readInputData(args: {\n\tdata?: string;\n\tfile?: string;\n\tstdin?: boolean;\n}): Promise<Record<string, unknown>> {\n\tif (args.data) {\n\t\ttry {\n\t\t\treturn JSON.parse(args.data) as Record<string, unknown>;\n\t\t} catch {\n\t\t\tthrow new Error(\"Invalid JSON in --data argument\");\n\t\t}\n\t}\n\n\tif (args.file) {\n\t\ttry {\n\t\t\tconst content = await readFile(args.file, \"utf-8\");\n\t\t\treturn JSON.parse(content) as Record<string, unknown>;\n\t\t} catch (error) {\n\t\t\tif (error instanceof SyntaxError) {\n\t\t\t\tthrow new Error(`Invalid JSON in file: ${args.file}`, { cause: error });\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tif (args.stdin) {\n\t\tconst chunks: Buffer[] = [];\n\t\tfor await (const chunk of process.stdin) {\n\t\t\tchunks.push(chunk as Buffer);\n\t\t}\n\t\tconst content = Buffer.concat(chunks).toString(\"utf-8\");\n\t\ttry {\n\t\t\treturn JSON.parse(content) as Record<string, unknown>;\n\t\t} catch {\n\t\t\tthrow new Error(\"Invalid JSON from stdin\");\n\t\t}\n\t}\n\n\tthrow new Error(\"Provide content data via --data, --file, or --stdin\");\n}\n\n// ---------------------------------------------------------------------------\n// Subcommands\n// ---------------------------------------------------------------------------\n\nconst listCommand = defineCommand({\n\tmeta: { name: \"list\", description: \"List content items\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tstatus: { type: \"string\", description: \"Filter by status\" },\n\t\tlocale: { type: \"string\", description: \"Filter by locale\" },\n\t\tlimit: { type: \"string\", description: \"Maximum items to return\" },\n\t\tcursor: { type: \"string\", description: \"Pagination cursor\" },\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst result = await client.list(args.collection, {\n\t\t\t\tstatus: args.status,\n\t\t\t\tlocale: args.locale,\n\t\t\t\tlimit: args.limit ? parseInt(args.limit, 10) : undefined,\n\t\t\t\tcursor: args.cursor,\n\t\t\t});\n\t\t\t// Summarize items — strip heavy data fields for readable output\n\t\t\tconst summary = {\n\t\t\t\titems: result.items.map((item) => ({\n\t\t\t\t\tid: item.id,\n\t\t\t\t\tslug: item.slug,\n\t\t\t\t\tlocale: item.locale,\n\t\t\t\t\tstatus: item.status,\n\t\t\t\t\ttitle: typeof item.data?.title === \"string\" ? item.data.title : undefined,\n\t\t\t\t\tupdatedAt: item.updatedAt,\n\t\t\t\t})),\n\t\t\t\tnextCursor: result.nextCursor,\n\t\t\t};\n\t\t\toutput(summary, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst getCommand = defineCommand({\n\tmeta: { name: \"get\", description: \"Get a single content item\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Content item ID or slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tlocale: { type: \"string\", description: \"Locale for slug resolution\" },\n\t\traw: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Return raw Portable Text (skip markdown conversion)\",\n\t\t},\n\t\tpublished: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Return published data only (ignore pending draft)\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst item = await client.get(args.collection, args.id, {\n\t\t\t\traw: args.raw,\n\t\t\t\tlocale: args.locale,\n\t\t\t});\n\n\t\t\t// If a draft exists, overlay draft data unless --published\n\t\t\tif (!args.published && item.draftRevisionId) {\n\t\t\t\tconst comparison = await client.compare(args.collection, args.id);\n\t\t\t\tif (comparison.hasChanges && comparison.draft) {\n\t\t\t\t\titem.data = comparison.draft;\n\t\t\t\t\t// The comparison endpoint returns raw PT data. Apply the same\n\t\t\t\t\t// PT-to-markdown conversion that `client.get` does, unless --raw.\n\t\t\t\t\tif (!args.raw && item.data) {\n\t\t\t\t\t\tconst col = await client.collection(args.collection);\n\t\t\t\t\t\tconst fields = col.fields.map((f) => ({ slug: f.slug, type: f.type }));\n\t\t\t\t\t\titem.data = convertDataForRead(item.data, fields, false);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\toutput(item, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst createCommand = defineCommand({\n\tmeta: { name: \"create\", description: \"Create a content item\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tdata: { type: \"string\", description: \"Content data as JSON string\" },\n\t\tfile: { type: \"string\", description: \"Read content data from a JSON file\" },\n\t\tstdin: { type: \"boolean\", description: \"Read content data from stdin\" },\n\t\tslug: { type: \"string\", description: \"Content slug\" },\n\t\tlocale: { type: \"string\", description: \"Content locale\" },\n\t\t\"translation-of\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"ID of content item to link as translation\",\n\t\t},\n\t\tdraft: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Keep as draft instead of auto-publishing\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst data = await readInputData(args);\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst item = await client.create(args.collection, {\n\t\t\t\tdata,\n\t\t\t\tslug: args.slug,\n\t\t\t\tlocale: args.locale,\n\t\t\t\ttranslationOf: args[\"translation-of\"],\n\t\t\t});\n\n\t\t\t// Auto-publish unless --draft is set\n\t\t\tif (!args.draft) {\n\t\t\t\tawait client.publish(args.collection, item.id);\n\t\t\t}\n\n\t\t\t// Re-fetch to return the current state\n\t\t\tconst result = await client.get(args.collection, item.id);\n\t\t\toutput(result, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst updateCommand = defineCommand({\n\tmeta: { name: \"update\", description: \"Update a content item\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Content item ID or slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tdata: { type: \"string\", description: \"Content data as JSON string\" },\n\t\tfile: { type: \"string\", description: \"Read content data from a JSON file\" },\n\t\trev: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Revision token from get (prevents overwriting unseen changes)\",\n\t\t\trequired: true,\n\t\t},\n\t\tlocale: { type: \"string\", description: \"Locale for slug resolution\" },\n\t\tdraft: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Keep as draft instead of auto-publishing\",\n\t\t},\n\t\t\"override-lock\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Write even though another editor holds this entry's edit lock\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst data = await readInputData(args);\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst updated = await client.update(args.collection, args.id, {\n\t\t\t\tdata,\n\t\t\t\t_rev: args.rev,\n\t\t\t\tlocale: args.locale,\n\t\t\t\toverrideLock: args[\"override-lock\"],\n\t\t\t});\n\n\t\t\t// Auto-publish unless --draft is set.\n\t\t\t// Only publish if the update created a draft revision (i.e. the\n\t\t\t// collection supports revisions and data went to a draft).\n\t\t\tif (!args.draft && updated.draftRevisionId) {\n\t\t\t\tawait client.publish(args.collection, updated.id, {\n\t\t\t\t\toverrideLock: args[\"override-lock\"],\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Re-fetch to return the current state\n\t\t\tconst item = await client.get(args.collection, updated.id);\n\t\t\toutput(item, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst deleteCommand = defineCommand({\n\tmeta: { name: \"delete\", description: \"Delete a content item\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Content item ID or slug\",\n\t\t\trequired: true,\n\t\t},\n\t\t\"override-lock\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Write even though another editor holds this entry's edit lock\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tawait client.delete(args.collection, args.id, { overrideLock: args[\"override-lock\"] });\n\t\t\toutput({ success: true }, args);\n\t\t\tconsola.success(`Deleted ${args.collection}/${args.id}`);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst publishCommand = defineCommand({\n\tmeta: { name: \"publish\", description: \"Publish a content item\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Content item ID or slug\",\n\t\t\trequired: true,\n\t\t},\n\t\t\"override-lock\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Write even though another editor holds this entry's edit lock\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tawait client.publish(args.collection, args.id, { overrideLock: args[\"override-lock\"] });\n\t\t\toutput({ success: true }, args);\n\t\t\tconsola.success(`Published ${args.collection}/${args.id}`);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst unpublishCommand = defineCommand({\n\tmeta: { name: \"unpublish\", description: \"Unpublish a content item\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Content item ID or slug\",\n\t\t\trequired: true,\n\t\t},\n\t\t\"override-lock\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Write even though another editor holds this entry's edit lock\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tawait client.unpublish(args.collection, args.id, { overrideLock: args[\"override-lock\"] });\n\t\t\toutput({ success: true }, args);\n\t\t\tconsola.success(`Unpublished ${args.collection}/${args.id}`);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst scheduleCommand = defineCommand({\n\tmeta: { name: \"schedule\", description: \"Schedule content for publishing\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Content item ID or slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tat: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"ISO 8601 datetime with Z or an explicit UTC offset to publish at\",\n\t\t\trequired: true,\n\t\t},\n\t\t\"override-lock\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Write even though another editor holds this entry's edit lock\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tawait client.schedule(args.collection, args.id, {\n\t\t\t\tat: args.at,\n\t\t\t\toverrideLock: args[\"override-lock\"],\n\t\t\t});\n\t\t\toutput({ success: true }, args);\n\t\t\tconsola.success(`Scheduled ${args.collection}/${args.id} for ${args.at}`);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst restoreCommand = defineCommand({\n\tmeta: { name: \"restore\", description: \"Restore a trashed content item\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Content item ID or slug\",\n\t\t\trequired: true,\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tawait client.restore(args.collection, args.id);\n\t\t\toutput({ success: true }, args);\n\t\t\tconsola.success(`Restored ${args.collection}/${args.id}`);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst translationsCommand = defineCommand({\n\tmeta: { name: \"translations\", description: \"List translations for a content item\" },\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Content item ID or slug\",\n\t\t\trequired: true,\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst translations = await client.translations(args.collection, args.id);\n\t\t\toutput(translations, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\n// ---------------------------------------------------------------------------\n// Export\n// ---------------------------------------------------------------------------\n\nexport const contentCommand = defineCommand({\n\tmeta: { name: \"content\", description: \"Manage content\" },\n\tsubCommands: {\n\t\tlist: listCommand,\n\t\tget: getCommand,\n\t\tcreate: createCommand,\n\t\tupdate: updateCommand,\n\t\tdelete: deleteCommand,\n\t\tpublish: publishCommand,\n\t\tunpublish: unpublishCommand,\n\t\tschedule: scheduleCommand,\n\t\trestore: restoreCommand,\n\t\ttranslations: translationsCommand,\n\t},\n});\n","import { Kysely, SqliteDialect } from \"kysely\";\n\nimport { openNodeSqliteDatabase } from \"../db/node-sqlite-compat.js\";\nimport { EmDashDatabaseError } from \"./errors.js\";\nimport { kyselyLogOption } from \"./instrumentation.js\";\nimport type { Database } from \"./types.js\";\n\nexport { EmDashDatabaseError };\n\nexport interface DatabaseConfig {\n\turl: string;\n\tauthToken?: string;\n\treadOnly?: boolean;\n}\n\n/**\n * Creates a Kysely database instance\n * Supports:\n * - file:./path/to/db.sqlite (local SQLite)\n * - :memory: (in-memory SQLite for testing)\n * - libsql://... (Turso/libSQL with auth token) - TODO\n */\nexport function createDatabase(config: DatabaseConfig): Kysely<Database> {\n\ttry {\n\t\t// Handle file-based SQLite\n\t\tif (config.url.startsWith(\"file:\") || config.url === \":memory:\") {\n\t\t\tconst dbPath = config.url === \":memory:\" ? \":memory:\" : config.url.replace(\"file:\", \"\");\n\n\t\t\tconst sqlite = openNodeSqliteDatabase(dbPath, {\n\t\t\t\tjournalMode: \"wal\",\n\t\t\t\treadOnly: config.readOnly,\n\t\t\t});\n\n\t\t\tconst dialect = new SqliteDialect({\n\t\t\t\tdatabase: sqlite,\n\t\t\t});\n\n\t\t\treturn new Kysely<Database>({ dialect, log: kyselyLogOption() });\n\t\t}\n\n\t\t// Handle libSQL (Turso)\n\t\tif (config.url.startsWith(\"libsql:\")) {\n\t\t\tif (!config.authToken) {\n\t\t\t\tthrow new EmDashDatabaseError(\"Auth token required for remote libSQL database\");\n\t\t\t}\n\t\t\t// LibSQL implementation would use @libsql/kysely-libsql\n\t\t\tthrow new EmDashDatabaseError(\"LibSQL not yet implemented\");\n\t\t}\n\n\t\tthrow new EmDashDatabaseError(`Unsupported database URL scheme: ${config.url}`);\n\t} catch (error) {\n\t\tif (error instanceof EmDashDatabaseError) {\n\t\t\tthrow error;\n\t\t}\n\t\tthrow new EmDashDatabaseError(\"Failed to create database\", error);\n\t}\n}\n","/**\n * emdash dev\n *\n * Start development server with optional schema sync from remote\n */\n\nimport { spawn } from \"node:child_process\";\nimport { access, readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport consola from \"consola\";\n\nimport { createDatabase } from \"../../database/connection.js\";\nimport { runMigrations } from \"../../database/migrations/runner.js\";\n\ninterface PackageJson {\n\tname?: string;\n\tscripts?: Record<string, string>;\n\temdash?: {\n\t\turl?: string;\n\t\tdatabase?: string;\n\t};\n}\n\nasync function readPackageJson(cwd: string): Promise<PackageJson | null> {\n\tconst pkgPath = resolve(cwd, \"package.json\");\n\ttry {\n\t\tconst content = await readFile(pkgPath, \"utf-8\");\n\t\treturn JSON.parse(content);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport const DEV_DEPRECATION_MESSAGE =\n\t\"`emdash dev` is deprecated and will be removed in a future release.\\n\\n\" +\n\t\"Use your project's dev script instead (for example, `pnpm dev`), or run `astro dev` directly.\";\n\nexport const devCommand = defineCommand({\n\tmeta: {\n\t\tname: \"dev\",\n\t\tdescription: \"Start dev server with local database\",\n\t\thidden: true,\n\t},\n\targs: {\n\t\tdatabase: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"d\",\n\t\t\tdescription: \"Database path (default: ./data.db)\",\n\t\t\tdefault: \"./data.db\",\n\t\t},\n\t\ttypes: {\n\t\t\ttype: \"boolean\",\n\t\t\talias: \"t\",\n\t\t\tdescription: \"Generate types from remote before starting\",\n\t\t\tdefault: false,\n\t\t},\n\t\tport: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"p\",\n\t\t\tdescription: \"Port for dev server\",\n\t\t\tdefault: \"4321\",\n\t\t},\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Working directory\",\n\t\t\tdefault: process.cwd(),\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconsola.box({\n\t\t\ttitle: \"DEPRECATED COMMAND\",\n\t\t\tmessage: DEV_DEPRECATION_MESSAGE,\n\t\t});\n\n\t\tconst cwd = resolve(args.cwd);\n\t\tconst pkg = await readPackageJson(cwd);\n\n\t\tif (!pkg) {\n\t\t\tconsola.error(\"No package.json found\");\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconst dbPath = resolve(cwd, args.database);\n\n\t\t// Run migrations if database doesn't exist\n\t\tconst dbExists = await fileExists(dbPath);\n\t\tif (!dbExists) {\n\t\t\tconsola.start(\"Database not found, initializing...\");\n\t\t}\n\n\t\t// Always run migrations (they're idempotent)\n\t\tconst db = createDatabase({ url: `file:${dbPath}` });\n\t\ttry {\n\t\t\tconsola.start(\"Checking database migrations...\");\n\t\t\tconst { applied } = await runMigrations(db);\n\t\t\tif (applied.length > 0) {\n\t\t\t\tconsola.success(`Applied ${applied.length} migrations`);\n\t\t\t} else {\n\t\t\t\tconsola.info(\"Database up to date\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Migration failed:\", error);\n\t\t\tawait db.destroy();\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tawait db.destroy();\n\n\t\t// Generate types from remote if requested\n\t\tif (args.types) {\n\t\t\tconst remoteUrl = pkg.emdash?.url || process.env.EMDASH_URL;\n\n\t\t\tif (!remoteUrl) {\n\t\t\t\tconsola.warn(\"No remote URL configured. Set EMDASH_URL or emdash.url in package.json\");\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tconst { createClientFromArgs } = await import(\"../client-factory.js\");\n\t\t\t\t\tconst client = createClientFromArgs({ url: remoteUrl });\n\t\t\t\t\tconst schema = await client.schemaExport();\n\t\t\t\t\tconst types = await client.schemaTypes();\n\n\t\t\t\t\tconst { mkdir, writeFile } = await import(\"node:fs/promises\");\n\t\t\t\t\tconst { dirname, resolve: resolvePath } = await import(\"node:path\");\n\t\t\t\t\tconst outputPath = resolvePath(cwd, \".emdash/types.ts\");\n\t\t\t\t\tawait mkdir(dirname(outputPath), { recursive: true });\n\t\t\t\t\tawait writeFile(outputPath, types, \"utf-8\");\n\t\t\t\t\tawait writeFile(\n\t\t\t\t\t\tresolvePath(dirname(outputPath), \"schema.json\"),\n\t\t\t\t\t\tJSON.stringify(schema, null, 2),\n\t\t\t\t\t\t\"utf-8\",\n\t\t\t\t\t);\n\t\t\t\t\tconsola.success(`Generated types for ${schema.collections.length} collections`);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsola.warn(\"Type generation failed:\", error instanceof Error ? error.message : error);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Start Astro dev server\n\t\tconsola.start(\"Starting Astro dev server...\");\n\n\t\tconst astroArgs = [\"astro\", \"dev\", \"--port\", args.port];\n\n\t\t// Check if using pnpm, npm, or yarn\n\t\tconst pnpmLockExists = await fileExists(resolve(cwd, \"pnpm-lock.yaml\"));\n\t\tconst yarnLockExists = await fileExists(resolve(cwd, \"yarn.lock\"));\n\n\t\tlet cmd: string;\n\t\tlet cmdArgs: string[];\n\n\t\tif (pnpmLockExists) {\n\t\t\tcmd = \"pnpm\";\n\t\t\tcmdArgs = astroArgs;\n\t\t} else if (yarnLockExists) {\n\t\t\tcmd = \"yarn\";\n\t\t\tcmdArgs = astroArgs;\n\t\t} else {\n\t\t\tcmd = \"npx\";\n\t\t\tcmdArgs = astroArgs;\n\t\t}\n\n\t\tconsola.info(`Running: ${cmd} ${cmdArgs.join(\" \")}`);\n\n\t\tconst child = spawn(cmd, cmdArgs, {\n\t\t\tcwd,\n\t\t\tstdio: \"inherit\",\n\t\t\tenv: {\n\t\t\t\t...process.env,\n\t\t\t\t// Pass database path to Astro\n\t\t\t\tEMDASH_DATABASE_URL: `file:${dbPath}`,\n\t\t\t},\n\t\t});\n\n\t\tchild.on(\"error\", (error) => {\n\t\t\tconsola.error(\"Failed to start dev server:\", error);\n\t\t\tprocess.exit(1);\n\t\t});\n\n\t\tchild.on(\"exit\", (code) => {\n\t\t\tprocess.exit(code ?? 0);\n\t\t});\n\n\t\t// Handle termination signals\n\t\tconst cleanup = () => {\n\t\t\tchild.kill(\"SIGTERM\");\n\t\t};\n\n\t\tprocess.on(\"SIGINT\", cleanup);\n\t\tprocess.on(\"SIGTERM\", cleanup);\n\t},\n});\n","/**\n * emdash doctor\n *\n * Diagnose database health (connection, migrations, schema integrity) and\n * Cloudflare Worker scheduler wiring (Cron Trigger + scheduled() handler).\n */\n\nimport { access, readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport consola from \"consola\";\nimport { parse, printParseErrorCode, type ParseError } from \"jsonc-parser\";\nimport { parse as parseToml } from \"smol-toml\";\n\nimport { createDatabase } from \"../../database/connection.js\";\nimport {\n\tformatDatetimeStorageReport,\n\tscanDatetimeStorage,\n} from \"../../database/datetime-storage.js\";\nimport { listTablesLike } from \"../../database/dialect-helpers.js\";\nimport { getMigrationStatus } from \"../../database/migrations/runner.js\";\n\nexport interface CheckResult {\n\tname: string;\n\tstatus: \"pass\" | \"warn\" | \"fail\";\n\tmessage: string;\n}\n\nconst WRANGLER_CONFIG_FILES = [\"wrangler.jsonc\", \"wrangler.json\", \"wrangler.toml\"] as const;\nconst CLOUDFLARE_WORKER_MODULE = \"@emdash-cms/cloudflare/worker\";\nconst WORKER_FIX = `export { default, PluginBridge } from \"${CLOUDFLARE_WORKER_MODULE}\";`;\nconst MAIN_FIX_JSONC = `\"main\": \"./src/worker.ts\"`;\nconst MAIN_FIX_TOML = `main = \"./src/worker.ts\"`;\nconst TRIGGER_FIX_JSONC = `\"triggers\": { \"crons\": [\"* * * * *\"] }`;\nconst TRIGGER_FIX_TOML = `[triggers]\\ncrons = [\"* * * * *\"]`;\nconst SCHEDULED_HANDLER_PATTERN = /\\bscheduled\\s*:\\s*createScheduledHandler\\s*\\(/m;\n\nfunction triggerFix(configPath: string): string {\n\treturn configPath.endsWith(\".toml\") ? TRIGGER_FIX_TOML : TRIGGER_FIX_JSONC;\n}\n\nfunction mainFix(configPath: string): string {\n\treturn configPath.endsWith(\".toml\") ? MAIN_FIX_TOML : MAIN_FIX_JSONC;\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction sourcePosition(source: string, offset: number): { line: number; column: number } {\n\tconst prefix = source.slice(0, offset);\n\treturn {\n\t\tline: prefix.split(\"\\n\").length,\n\t\tcolumn: offset - prefix.lastIndexOf(\"\\n\"),\n\t};\n}\n\nasync function findWranglerConfig(cwd: string): Promise<string | null> {\n\tfor (const filename of WRANGLER_CONFIG_FILES) {\n\t\tconst path = resolve(cwd, filename);\n\t\tif (await fileExists(path)) return path;\n\t}\n\treturn null;\n}\n\nfunction workerExportsScheduledMaintenance(source: string): boolean {\n\tconst modulePattern = CLOUDFLARE_WORKER_MODULE.replaceAll(\"/\", \"\\\\/\");\n\tconst reExportsWorker = new RegExp(\n\t\t`export\\\\s*\\\\{[^}]*\\\\bdefault\\\\b[^}]*\\\\}\\\\s*from\\\\s*[\"']${modulePattern}[\"']`,\n\t\t\"m\",\n\t);\n\tconst importsFactory = new RegExp(\n\t\t`import\\\\s+[^;]*\\\\{[^}]*\\\\bcreateScheduledHandler\\\\b[^}]*\\\\}\\\\s*from\\\\s*[\"']${modulePattern}[\"']`,\n\t\t\"m\",\n\t);\n\treturn (\n\t\treExportsWorker.test(source) ||\n\t\t(importsFactory.test(source) && SCHEDULED_HANDLER_PATTERN.test(source))\n\t);\n}\n\nexport async function checkSchedulerWiring(cwd: string): Promise<CheckResult[]> {\n\tconst configPath = await findWranglerConfig(cwd);\n\tif (!configPath) return [];\n\treturn checkSchedulerWiringAtPath(cwd, configPath);\n}\n\nasync function checkSchedulerWiringAtPath(cwd: string, configPath: string): Promise<CheckResult[]> {\n\tconst configSource = await readFile(configPath, \"utf8\");\n\tlet parsed: unknown;\n\tif (configPath.endsWith(\".toml\")) {\n\t\ttry {\n\t\t\tparsed = parseToml(configSource);\n\t\t} catch (error) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tname: \"scheduler config\",\n\t\t\t\t\tstatus: \"fail\",\n\t\t\t\t\tmessage: `could not parse ${configPath}: ${error instanceof Error ? error.message : \"invalid TOML\"} — fix the Wrangler configuration syntax`,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t} else {\n\t\tconst parseErrors: ParseError[] = [];\n\t\tparsed = parse(configSource, parseErrors, {\n\t\t\tallowTrailingComma: true,\n\t\t\tdisallowComments: false,\n\t\t});\n\t\tif (parseErrors.length > 0) {\n\t\t\tconst error = parseErrors[0];\n\t\t\tconst { line, column } = sourcePosition(configSource, error.offset);\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tname: \"scheduler config\",\n\t\t\t\t\tstatus: \"fail\",\n\t\t\t\t\tmessage: `could not parse ${configPath}: ${printParseErrorCode(error.error)} at line ${line}, column ${column} — fix the Wrangler configuration syntax`,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t}\n\tif (!isRecord(parsed)) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tname: \"scheduler config\",\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tmessage: `could not parse ${configPath}: expected an object — fix the Wrangler configuration syntax`,\n\t\t\t},\n\t\t];\n\t}\n\n\tconst triggers = isRecord(parsed.triggers) ? parsed.triggers : null;\n\tconst hasCronTrigger =\n\t\tArray.isArray(triggers?.crons) &&\n\t\ttriggers.crons.some((cron) => typeof cron === \"string\" && cron.trim().length > 0);\n\tconst main = typeof parsed.main === \"string\" && parsed.main.trim() ? parsed.main : null;\n\tif (!main) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tname: \"scheduler handler\",\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tmessage: `Wrangler configuration has no Worker entry to inspect — add ${mainFix(configPath)}, then export: ${WORKER_FIX}`,\n\t\t\t},\n\t\t];\n\t}\n\n\tconst workerPath = resolve(cwd, main);\n\tlet hasScheduledHandler = false;\n\ttry {\n\t\tconst workerSource = await readFile(workerPath, \"utf8\");\n\t\thasScheduledHandler = workerExportsScheduledMaintenance(workerSource);\n\t} catch (error) {\n\t\tconst code = isRecord(error) && typeof error.code === \"string\" ? error.code : null;\n\t\tif (code !== \"ENOENT\") {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tname: \"scheduler handler\",\n\t\t\t\t\tstatus: \"fail\",\n\t\t\t\t\tmessage: `could not read Worker entry ${workerPath}: ${error instanceof Error ? error.message : \"unknown I/O error\"} — check the file path and permissions`,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t\treturn [\n\t\t\t{\n\t\t\t\tname: \"scheduler handler\",\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tmessage: `Worker entry not found at ${workerPath} — create it with: ${WORKER_FIX}`,\n\t\t\t},\n\t\t];\n\t}\n\n\tif (hasCronTrigger && !hasScheduledHandler) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tname: \"scheduler handler\",\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tmessage: `Cron Trigger is configured, but ${main} does not export EmDash scheduled() maintenance — replace its Worker export with: ${WORKER_FIX}`,\n\t\t\t},\n\t\t];\n\t}\n\n\tif (hasScheduledHandler && !hasCronTrigger) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tname: \"scheduler trigger\",\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tmessage: `EmDash scheduled() handler is exported, but no Cron Trigger is configured — add this to ${configPath}: ${triggerFix(configPath)}`,\n\t\t\t},\n\t\t];\n\t}\n\n\tif (!hasCronTrigger && !hasScheduledHandler) {\n\t\treturn [];\n\t}\n\n\treturn [\n\t\t{\n\t\t\tname: \"scheduler wiring\",\n\t\t\tstatus: \"pass\",\n\t\t\tmessage: `Cron Trigger and scheduled() handler found (${main})`,\n\t\t},\n\t];\n}\n\nexport async function checkDoctor(cwd: string, dbPath: string): Promise<CheckResult[]> {\n\tconst results = await checkDatabase(dbPath);\n\tconst configPath = await findWranglerConfig(cwd);\n\tif (configPath) results.push(...(await checkSchedulerWiringAtPath(cwd, configPath)));\n\n\treturn results;\n}\n\nfunction printResult(result: CheckResult): void {\n\tconst color =\n\t\tresult.status === \"pass\"\n\t\t\t? consola.success\n\t\t\t: result.status === \"warn\"\n\t\t\t\t? consola.warn\n\t\t\t\t: consola.error;\n\tcolor(`${result.name}: ${result.message}`);\n}\n\nasync function checkDatabase(dbPath: string): Promise<CheckResult[]> {\n\tconst results: CheckResult[] = [];\n\n\t// Check database file exists\n\tif (!(await fileExists(dbPath))) {\n\t\tresults.push({\n\t\t\tname: \"database\",\n\t\t\tstatus: \"fail\",\n\t\t\tmessage: `not found at ${dbPath} — run \"emdash init\"`,\n\t\t});\n\t\treturn results;\n\t}\n\n\tresults.push({\n\t\tname: \"database\",\n\t\tstatus: \"pass\",\n\t\tmessage: dbPath,\n\t});\n\n\t// Connect and check migrations\n\tlet db;\n\ttry {\n\t\tdb = createDatabase({ url: `file:${dbPath}` });\n\n\t\tconst { applied, pending } = await getMigrationStatus(db);\n\t\tif (pending.length === 0) {\n\t\t\tresults.push({\n\t\t\t\tname: \"migrations\",\n\t\t\t\tstatus: \"pass\",\n\t\t\t\tmessage: `${applied.length} applied, none pending`,\n\t\t\t});\n\t\t} else {\n\t\t\tresults.push({\n\t\t\t\tname: \"migrations\",\n\t\t\t\tstatus: \"warn\",\n\t\t\t\tmessage: `${applied.length} applied, ${pending.length} pending — run \"emdash init\"`,\n\t\t\t});\n\t\t}\n\n\t\tconst { sql } = await import(\"kysely\");\n\n\t\t// Check collections exist\n\t\ttry {\n\t\t\tconst collectionsResult = await sql<{\n\t\t\t\tcount: number;\n\t\t\t}>`SELECT COUNT(id) as count FROM _emdash_collections`.execute(db);\n\t\t\tconst count = collectionsResult.rows[0]?.count ?? 0;\n\t\t\tresults.push({\n\t\t\t\tname: \"collections\",\n\t\t\t\tstatus: count > 0 ? \"pass\" : \"warn\",\n\t\t\t\tmessage:\n\t\t\t\t\tcount > 0 ? `${count} collections defined` : \"no collections — seed or create via admin\",\n\t\t\t});\n\t\t} catch {\n\t\t\tresults.push({\n\t\t\t\tname: \"collections\",\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tmessage: \"could not query collections table — migrations may not have run\",\n\t\t\t});\n\t\t}\n\n\t\t// Check for orphaned ec_ tables without matching collection records\n\t\ttry {\n\t\t\tconst tableNames = await listTablesLike(db, \"ec_%\");\n\t\t\tconst collectionsResult = await sql<{\n\t\t\t\tslug: string;\n\t\t\t}>`SELECT slug FROM _emdash_collections`.execute(db);\n\t\t\tconst registeredSlugs = new Set(collectionsResult.rows.map((r) => `ec_${r.slug}`));\n\t\t\tconst orphaned = tableNames.filter((name) => !registeredSlugs.has(name));\n\n\t\t\tif (orphaned.length > 0) {\n\t\t\t\tresults.push({\n\t\t\t\t\tname: \"orphaned tables\",\n\t\t\t\t\tstatus: \"warn\",\n\t\t\t\t\tmessage: `found ${orphaned.length}: ${orphaned.join(\", \")}`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst report = await scanDatetimeStorage(db);\n\t\t\t\tconst clean =\n\t\t\t\t\treport.noncanonicalCount === 0 &&\n\t\t\t\t\treport.manualReviewCount === 0 &&\n\t\t\t\t\treport.inspectionErrorCount === 0;\n\t\t\t\tresults.push({\n\t\t\t\t\tname: \"datetime storage\",\n\t\t\t\t\tstatus: clean ? \"pass\" : \"fail\",\n\t\t\t\t\tmessage: clean\n\t\t\t\t\t\t? `all stored content datetimes are canonical (${report.timezone})`\n\t\t\t\t\t\t: formatDatetimeStorageReport(report),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tresults.push({\n\t\t\t\t\tname: \"datetime storage\",\n\t\t\t\t\tstatus: \"fail\",\n\t\t\t\t\tmessage: `could not inspect stored datetimes: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t} catch {\n\t\t\t// Non-critical — tables may not exist on fresh DB\n\t\t}\n\n\t\t// Check users exist\n\t\ttry {\n\t\t\tconst usersResult = await sql<{\n\t\t\t\tcount: number;\n\t\t\t}>`SELECT COUNT(id) as count FROM users`.execute(db);\n\t\t\tconst count = usersResult.rows[0]?.count ?? 0;\n\t\t\tresults.push({\n\t\t\t\tname: \"users\",\n\t\t\t\tstatus: count > 0 ? \"pass\" : \"warn\",\n\t\t\t\tmessage:\n\t\t\t\t\tcount > 0 ? `${count} users` : \"no users — complete setup wizard at /_emdash/admin\",\n\t\t\t});\n\t\t} catch {\n\t\t\tresults.push({\n\t\t\t\tname: \"users\",\n\t\t\t\tstatus: \"warn\",\n\t\t\t\tmessage: \"could not query users table\",\n\t\t\t});\n\t\t}\n\t} catch (error) {\n\t\tresults.push({\n\t\t\tname: \"database connection\",\n\t\t\tstatus: \"fail\",\n\t\t\tmessage: error instanceof Error ? error.message : \"failed to connect\",\n\t\t});\n\t} finally {\n\t\tif (db) {\n\t\t\tawait db.destroy();\n\t\t}\n\t}\n\n\treturn results;\n}\n\nexport const doctorCommand = defineCommand({\n\tmeta: {\n\t\tname: \"doctor\",\n\t\tdescription: \"Check database health, scheduler wiring, and diagnose issues\",\n\t},\n\targs: {\n\t\tdatabase: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"d\",\n\t\t\tdescription: \"Database path (default: ./data.db)\",\n\t\t\tdefault: \"./data.db\",\n\t\t},\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Working directory\",\n\t\t\tdefault: process.cwd(),\n\t\t},\n\t\tjson: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output results as JSON\",\n\t\t\tdefault: false,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst cwd = resolve(args.cwd);\n\t\tconst dbPath = resolve(cwd, args.database);\n\n\t\tconst results = await checkDoctor(cwd, dbPath);\n\t\tconst fails = results.filter((result) => result.status === \"fail\");\n\n\t\tif (args.json) {\n\t\t\tprocess.stdout.write(JSON.stringify(results, null, 2) + \"\\n\");\n\t\t\tif (fails.length > 0) process.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\n\t\tconsola.start(\"EmDash Doctor\\n\");\n\n\t\tfor (const result of results) {\n\t\t\tprintResult(result);\n\t\t}\n\n\t\t// Summary\n\t\tconst warns = results.filter((r) => r.status === \"warn\");\n\n\t\tconsola.log(\"\");\n\t\tif (fails.length === 0 && warns.length === 0) {\n\t\t\tconsola.success(\"All checks passed\");\n\t\t} else if (fails.length === 0) {\n\t\t\tconsola.info(`All critical checks passed (${warns.length} warnings)`);\n\t\t} else {\n\t\t\tconsola.error(`${fails.length} issues found`);\n\t\t\tprocess.exitCode = 1;\n\t\t}\n\t},\n});\n","/**\n * emdash export-seed\n *\n * Export current database schema (and optionally content) as a seed file\n */\n\nimport { resolve } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport consola from \"consola\";\nimport type { Kysely } from \"kysely\";\nimport { sql } from \"kysely\";\n\nimport { createDatabase } from \"../../database/connection.js\";\nimport { getExactMigrationStatus } from \"../../database/migrations/runner.js\";\nimport { BylineRepository } from \"../../database/repositories/byline.js\";\nimport { ContentRepository } from \"../../database/repositories/content.js\";\nimport { MediaRepository } from \"../../database/repositories/media.js\";\nimport { OptionsRepository } from \"../../database/repositories/options.js\";\nimport {\n\tparseTaxonomyCollections,\n\tselectTaxonomyDefs,\n} from \"../../database/repositories/taxonomy-def.js\";\nimport { TaxonomyRepository } from \"../../database/repositories/taxonomy.js\";\nimport type { ContentItem } from \"../../database/repositories/types.js\";\nimport type { Database } from \"../../database/types.js\";\nimport { validateIdentifier } from \"../../database/validate.js\";\nimport { getI18nConfig, isI18nEnabled } from \"../../i18n/config.js\";\nimport { BlockTypeRegistry } from \"../../schema/block-type-registry.js\";\nimport { SchemaRegistry } from \"../../schema/registry.js\";\nimport type { FieldType } from \"../../schema/types.js\";\nimport type {\n\tSeedFile,\n\tSeedCollection,\n\tSeedField,\n\tSeedRelation,\n\tSeedTaxonomy,\n\tSeedTaxonomyTerm,\n\tSeedMenu,\n\tSeedMenuItem,\n\tSeedRedirect,\n\tSeedSection,\n\tSeedWidgetArea,\n\tSeedWidget,\n\tSeedContentEntry,\n\tSeedByline,\n\tSeedBylineCredit,\n\tSeedBlockType,\n} from \"../../seed/types.js\";\nimport { isMissingTableError } from \"../../utils/db-errors.js\";\nimport { slugify } from \"../../utils/slugify.js\";\n\nconst SETTINGS_PREFIX = \"site:\";\n\nconst TRAILING_SLASHES = /\\/+$/;\n\nexport const exportSeedCommand = defineCommand({\n\tmeta: {\n\t\tname: \"export-seed\",\n\t\tdescription: \"Export database schema and content as a seed file\",\n\t},\n\targs: {\n\t\tdatabase: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"d\",\n\t\t\tdescription: \"Database path\",\n\t\t\tdefault: \"./data.db\",\n\t\t},\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Working directory\",\n\t\t\tdefault: process.cwd(),\n\t\t},\n\t\t\"with-content\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Include content (all or comma-separated collection names)\",\n\t\t\trequired: false,\n\t\t},\n\t\tpretty: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Pretty print JSON output\",\n\t\t\tdefault: true,\n\t\t},\n\t\t\"media-base-url\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Public URL of the site, used to write absolute media URLs\",\n\t\t\trequired: false,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst cwd = resolve(args.cwd);\n\n\t\t// Connect to database\n\t\tconst dbPath = resolve(cwd, args.database);\n\t\t// The seed document is this command's stdout payload, so anything else\n\t\t// written there corrupts `emdash export-seed > seed.json`. Diagnostics\n\t\t// go to stderr, where a redirect leaves them visible.\n\t\tprocess.stderr.write(`Database: ${dbPath}\\n`);\n\n\t\tconst db = createDatabase({ url: `file:${dbPath}`, readOnly: true });\n\n\t\ttry {\n\t\t\tconst { pending, unknownApplied } = await getExactMigrationStatus(db);\n\t\t\tif (unknownApplied.length > 0) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"The database was migrated by a newer EmDash version. Upgrade EmDash before exporting it.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (pending.length > 0) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`The database has ${pending.length} pending migration${pending.length === 1 ? \"\" : \"s\"}. Run \\`emdash migrate\\` before exporting it.`,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Export requires a current database schema:\", error);\n\t\t\tawait db.destroy();\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\ttry {\n\t\t\tconst seed = await exportSeed(db, args[\"with-content\"], {\n\t\t\t\tmediaBaseUrl: args[\"media-base-url\"],\n\t\t\t\twarn: (message) => process.stderr.write(`Warning: ${message}\\n`),\n\t\t\t});\n\n\t\t\t// Output to stdout\n\t\t\tconst output = args.pretty ? JSON.stringify(seed, null, \"\\t\") : JSON.stringify(seed);\n\n\t\t\tconsole.log(output);\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Export failed:\", error);\n\t\t\tawait db.destroy();\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tawait db.destroy();\n\t},\n});\n\nexport interface ExportSeedOptions {\n\t/**\n\t * Public origin (optionally with a base path) of the site the database\n\t * belongs to. `$media` URLs are written relative to it; without it they are\n\t * site-relative paths, which `applySeed` cannot download.\n\t */\n\tmediaBaseUrl?: string;\n\t/** Receives messages about data the seed cannot carry. */\n\twarn?: (message: string) => void;\n}\n\n/**\n * Export database to seed file format\n */\nexport async function exportSeed(\n\tdb: Kysely<Database>,\n\twithContent?: string,\n\toptions: ExportSeedOptions = {},\n): Promise<SeedFile> {\n\tconst warn = options.warn ?? (() => {});\n\tconst mediaUrlPrefix = mediaFileUrlPrefix(options.mediaBaseUrl);\n\n\tconst seed: SeedFile = {\n\t\t$schema: \"https://emdashcms.com/seed.schema.json\",\n\t\tversion: \"1\",\n\t\tmeta: {\n\t\t\tname: \"Exported Seed\",\n\t\t\tdescription: \"Exported from existing EmDash database\",\n\t\t},\n\t};\n\n\t// 1. Export settings\n\tseed.settings = await exportSettings(db);\n\n\t// 2. Export block types before collections that reference them\n\tseed.blockTypes = await exportBlockTypes(db);\n\n\t// 3. Export collections and fields\n\tseed.collections = await exportCollections(db);\n\n\t// 3. Export the relations reference fields bind to. Emitted even when no\n\t// field binds one: a relation outlives the fields that viewed it.\n\tconst relations = await exportRelations(db);\n\tif (relations.length > 0) {\n\t\tseed.relations = relations;\n\t}\n\n\t// Decide locale-awareness from the data. The runtime sets the i18n config via\n\t// middleware, but the CLI never does, so `isI18nEnabled()` is always false\n\t// under `emdash export-seed`. Detecting multiple locales in the data\n\t// keeps the export locale-aware without the runtime flag.\n\tconst { i18nEnabled, defaultLocale } = await detectLocaleInfo(db, seed.collections);\n\n\t// Self-describe the default locale so a non-`en` single-locale project\n\t// survives the round-trip: `emdash seed` runs outside the runtime and would\n\t// otherwise backfill omitted locales as `en`.\n\tif (defaultLocale) seed.defaultLocale = defaultLocale;\n\n\t// 4. Export taxonomy definitions and terms\n\tseed.taxonomies = await exportTaxonomies(db, i18nEnabled);\n\n\t// Byline profiles. The returned map (translation_group -> seed-local id)\n\t// lets content credits reference the same ids the root list emits.\n\tconst { bylines, groupToSeedId } = await exportBylines(db);\n\n\t// Content is read before menus so menu items can name their targets by\n\t// seed id.\n\tlet exportedContent: ExportedContent | undefined;\n\tif (withContent !== undefined) {\n\t\t// Treat \"all\" as a synonym for the bare flag and \"true\". The args help\n\t\t// text documents `all` as a valid value, but without this the literal\n\t\t// string is read as a collection name and matches no collection.\n\t\tconst includeAll = withContent === \"\" || withContent === \"true\" || withContent === \"all\";\n\t\tconst collections = includeAll\n\t\t\t? null // all collections\n\t\t\t: withContent\n\t\t\t\t\t.split(\",\")\n\t\t\t\t\t.map((s) => s.trim())\n\t\t\t\t\t.filter(Boolean);\n\n\t\texportedContent = await exportContent(\n\t\t\tdb,\n\t\t\tseed.collections || [],\n\t\t\tcollections,\n\t\t\tgroupToSeedId,\n\t\t\ti18nEnabled,\n\t\t\tmediaUrlPrefix,\n\t\t);\n\t}\n\n\tseed.menus = await exportMenus(db, i18nEnabled, exportedContent?.groupSeedIds ?? new Map());\n\n\tconst redirects = await exportRedirects(db, warn);\n\tif (redirects.length > 0) {\n\t\tseed.redirects = redirects;\n\t}\n\n\tseed.widgetAreas = await exportWidgetAreas(db);\n\n\tconst sections = await exportSections(db, warn);\n\tif (sections.length > 0) {\n\t\tseed.sections = sections;\n\t}\n\n\tif (bylines.length > 0) {\n\t\tseed.bylines = bylines;\n\t}\n\n\tif (exportedContent) {\n\t\tseed.content = exportedContent.content;\n\t\tif (exportedContent.mediaCount > 0 && !options.mediaBaseUrl) {\n\t\t\twarn(\n\t\t\t\t`${exportedContent.mediaCount} media reference(s) use site-relative URLs, which \\`emdash seed\\` cannot download. Pass --media-base-url with the site's public URL to make them importable.`,\n\t\t\t);\n\t\t}\n\t}\n\n\treturn seed;\n}\n\nconst MEDIA_FILE_PATH = \"/_emdash/api/media/file/\";\n\n/**\n * Prefix for `$media` URLs: the site's base URL (without a trailing slash)\n * plus the public media route, or the bare route when no base is given.\n */\nfunction mediaFileUrlPrefix(mediaBaseUrl: string | undefined): string {\n\tif (mediaBaseUrl === undefined) return MEDIA_FILE_PATH;\n\tlet base: URL;\n\ttry {\n\t\tbase = new URL(mediaBaseUrl);\n\t} catch {\n\t\tthrow new Error(`Invalid media base URL: ${mediaBaseUrl}`);\n\t}\n\tif (base.protocol !== \"http:\" && base.protocol !== \"https:\") {\n\t\tthrow new Error(`Media base URL must use http or https: ${mediaBaseUrl}`);\n\t}\n\treturn `${base.origin}${base.pathname.replace(TRAILING_SLASHES, \"\")}${MEDIA_FILE_PATH}`;\n}\n\n/**\n * Export byline profiles as root-level `bylines[]`.\n *\n * `SeedByline` has no locale axis, so locale siblings of the same byline\n * (sharing a `translation_group`) collapse to a single profile. The returned\n * `groupToSeedId` map keys on `translation_group` — the value stored in\n * `_emdash_content_bylines.byline_id` — so content credits can resolve to the\n * emitted seed id.\n */\nasync function exportBylines(\n\tdb: Kysely<Database>,\n): Promise<{ bylines: SeedByline[]; groupToSeedId: Map<string, string> }> {\n\tconst bylineRepo = new BylineRepository(db);\n\tconst bylines: SeedByline[] = [];\n\tconst groupToSeedId = new Map<string, string>();\n\tconst usedSeedIds = new Set<string>();\n\n\tlet cursor: string | undefined;\n\tdo {\n\t\tconst result = await bylineRepo.findMany({ limit: 100, cursor });\n\t\tfor (const byline of result.items) {\n\t\t\tconst group = byline.translationGroup ?? byline.id;\n\t\t\t// One seed entry per translation group; first row seen wins.\n\t\t\tif (groupToSeedId.has(group)) continue;\n\n\t\t\tlet seedId = `byline:${byline.slug}`;\n\t\t\t// Disambiguate the rare case of two distinct groups sharing a slug\n\t\t\t// (slug is unique per-locale, not globally) so seed ids stay unique.\n\t\t\tif (usedSeedIds.has(seedId)) seedId = `byline:${byline.slug}:${group}`;\n\t\t\tusedSeedIds.add(seedId);\n\t\t\tgroupToSeedId.set(group, seedId);\n\n\t\t\tbylines.push({\n\t\t\t\tid: seedId,\n\t\t\t\tslug: byline.slug,\n\t\t\t\tdisplayName: byline.displayName,\n\t\t\t\tbio: byline.bio || undefined,\n\t\t\t\twebsiteUrl: byline.websiteUrl || undefined,\n\t\t\t\tisGuest: byline.isGuest || undefined,\n\t\t\t});\n\t\t}\n\t\tcursor = result.nextCursor;\n\t} while (cursor);\n\n\treturn { bylines, groupToSeedId };\n}\n\n/**\n * Determine locale-awareness and the data's default locale for the export.\n *\n * The runtime initializes the i18n config in middleware, but the CLI never does,\n * so `isI18nEnabled()` is always false under `emdash export-seed`. When\n * the flag is unset, fall back to the data: a project is multi-locale when its\n * i18n-aware tables hold rows in more than one distinct locale. `locale` is\n * NOT NULL (defaulting to the site's default locale), so a per-row presence\n * check is not enough — only the *count* of distinct locales distinguishes a\n * genuinely single-locale project from a multi-locale one. This keeps\n * single-locale exports on bare ids and gives multi-locale exports the\n * per-locale suffix they need to avoid duplicate seed ids.\n *\n * `defaultLocale` self-describes the single-locale case so a non-`en` default\n * survives the round-trip. When more than one locale is present every\n * row already carries its own `locale`, so no fallback is needed and we leave it\n * undefined rather than guess which locale is the \"default\" without the runtime\n * config.\n */\nasync function detectLocaleInfo(\n\tdb: Kysely<Database>,\n\tcollections: SeedCollection[],\n): Promise<{ i18nEnabled: boolean; defaultLocale: string | undefined }> {\n\tconst config = getI18nConfig();\n\tif (isI18nEnabled() && config) {\n\t\treturn { i18nEnabled: true, defaultLocale: config.defaultLocale };\n\t}\n\n\tconst locales = new Set<string>();\n\tconst collectDistinctLocales = async (tableRef: ReturnType<typeof sql.ref>): Promise<void> => {\n\t\tconst result = await sql<{ locale: string | null }>`\n\t\t\tSELECT DISTINCT locale FROM ${tableRef}\n\t\t`.execute(db);\n\t\tfor (const row of result.rows) {\n\t\t\tif (row.locale) locales.add(row.locale);\n\t\t}\n\t};\n\n\tawait collectDistinctLocales(sql.ref(\"_emdash_taxonomy_defs\"));\n\tawait collectDistinctLocales(sql.ref(\"_emdash_menus\"));\n\n\tfor (const collection of collections) {\n\t\tvalidateIdentifier(collection.slug, \"collection slug\");\n\t\t// On D1, deleteCollection is non-atomic, so a collection row can outlive\n\t\t// its ec_* table. Skip missing tables rather than crashing the export.\n\t\ttry {\n\t\t\tawait collectDistinctLocales(sql.ref(`ec_${collection.slug}`));\n\t\t} catch (error) {\n\t\t\tif (!isMissingTableError(error)) throw error;\n\t\t}\n\t}\n\n\treturn {\n\t\ti18nEnabled: locales.size > 1,\n\t\tdefaultLocale: locales.size === 1 ? [...locales][0] : undefined,\n\t};\n}\n\n/**\n * Export site settings\n */\nasync function exportSettings(db: Kysely<Database>): Promise<SeedFile[\"settings\"]> {\n\tconst options = new OptionsRepository(db);\n\tconst allOptions = await options.getByPrefix(SETTINGS_PREFIX);\n\n\tconst settings: Record<string, unknown> = {};\n\tfor (const [key, value] of allOptions) {\n\t\tconst settingKey = key.replace(SETTINGS_PREFIX, \"\");\n\t\tsettings[settingKey] = value;\n\t}\n\n\treturn Object.keys(settings).length > 0 ? settings : undefined;\n}\n\nasync function exportBlockTypes(db: Kysely<Database>): Promise<SeedBlockType[]> {\n\tconst blockTypes = await new BlockTypeRegistry(db).listBlockTypes();\n\treturn blockTypes.map((blockType) => ({\n\t\tslug: blockType.slug,\n\t\tlabel: blockType.label,\n\t\tdescription: blockType.description,\n\t\ticon: blockType.icon,\n\t\tcategory: blockType.category,\n\t\tcurrentVersion: blockType.currentVersion,\n\t\tversions: blockType.versions.map((version) => ({\n\t\t\tversion: version.version,\n\t\t\tfields: version.fields,\n\t\t})),\n\t}));\n}\n\n/**\n * Export collections and their fields\n */\nasync function exportCollections(db: Kysely<Database>): Promise<SeedCollection[]> {\n\tconst registry = new SchemaRegistry(db);\n\tconst collections = await registry.listCollections();\n\tconst result: SeedCollection[] = [];\n\n\tfor (const collection of collections) {\n\t\tconst fields = await registry.listFields(collection.id);\n\n\t\tconst seedCollection: SeedCollection = {\n\t\t\tslug: collection.slug,\n\t\t\tlabel: collection.label,\n\t\t\tlabelSingular: collection.labelSingular || undefined,\n\t\t\tdescription: collection.description || undefined,\n\t\t\ticon: collection.icon || undefined,\n\t\t\tadmin: collection.admin,\n\t\t\tsupports: collection.supports.length > 0 ? collection.supports : undefined,\n\t\t\turlPattern: collection.urlPattern || undefined,\n\t\t\troutable: collection.routable === false ? false : undefined,\n\t\t\teditLocking: collection.editLocking === false ? false : undefined,\n\t\t\thidden: collection.hidden || undefined,\n\t\t\tsortOrder: collection.sortOrder,\n\t\t\tgroup: collection.group,\n\t\t\tcommentsEnabled: collection.commentsEnabled || undefined,\n\t\t\ttitleField: collection.titleField,\n\t\t\tdateField: collection.dateField,\n\t\t\tfields: fields.map(\n\t\t\t\t(field): SeedField => ({\n\t\t\t\t\tslug: field.slug,\n\t\t\t\t\tlabel: field.label,\n\t\t\t\t\ttype: field.type,\n\t\t\t\t\trequired: field.required || undefined,\n\t\t\t\t\tunique: field.unique || undefined,\n\t\t\t\t\tsearchable: field.searchable || undefined,\n\t\t\t\t\tindexed: field.indexed || undefined,\n\t\t\t\t\ttranslatable: field.translatable === false ? false : undefined,\n\t\t\t\t\tdefaultValue: field.defaultValue,\n\t\t\t\t\tvalidation: field.validation ? { ...field.validation } : undefined,\n\t\t\t\t\twidget: field.widget || undefined,\n\t\t\t\t\toptions: field.options || undefined,\n\t\t\t\t}),\n\t\t\t),\n\t\t};\n\n\t\tresult.push(seedCollection);\n\t}\n\n\treturn result;\n}\n\n/**\n * Export relations as root-level `relations[]`.\n *\n * A reference field's `validation.relation` names a relation by slug, and the\n * field's validation is exported verbatim, so re-applying the seed binds the\n * field to this relation rather than creating another one.\n */\nasync function exportRelations(db: Kysely<Database>): Promise<SeedRelation[]> {\n\tconst rows = await db\n\t\t.selectFrom(\"_emdash_relations\")\n\t\t.select([\n\t\t\t\"slug\",\n\t\t\t\"parent_collection\",\n\t\t\t\"child_collection\",\n\t\t\t\"parent_label\",\n\t\t\t\"parent_label_singular\",\n\t\t\t\"child_label\",\n\t\t\t\"child_label_singular\",\n\t\t\t\"max_children_per_parent\",\n\t\t\t\"max_parents_per_child\",\n\t\t])\n\t\t.orderBy(\"slug\", \"asc\")\n\t\t.execute();\n\n\treturn rows.map((row) => ({\n\t\tslug: row.slug,\n\t\tparentCollection: row.parent_collection,\n\t\tchildCollection: row.child_collection,\n\t\tparentLabel: row.parent_label,\n\t\tparentLabelSingular: row.parent_label_singular ?? undefined,\n\t\tchildLabel: row.child_label,\n\t\tchildLabelSingular: row.child_label_singular ?? undefined,\n\t\tmaxChildrenPerParent: row.max_children_per_parent,\n\t\tmaxParentsPerChild: row.max_parents_per_child,\n\t}));\n}\n\n/**\n * Export taxonomy definitions and terms\n */\nasync function exportTaxonomies(\n\tdb: Kysely<Database>,\n\ti18nEnabled: boolean,\n): Promise<SeedTaxonomy[]> {\n\t// Mirrors the content export pattern: one entry per (name, locale), stable\n\t// seed-local id, translations linked via `translationOf` to the anchor's id.\n\tconst defs = await selectTaxonomyDefs(db)\n\t\t// Chained, not `orderBy([\"name\", \"locale\"])`: kysely deprecated the array\n\t\t// form and announces it with `console.log`, which lands in the seed\n\t\t// document this command writes to stdout.\n\t\t.orderBy(\"d.name\")\n\t\t.orderBy(\"d.locale\")\n\t\t.execute();\n\n\tconst result: SeedTaxonomy[] = [];\n\tconst termRepo = new TaxonomyRepository(db);\n\n\t// Taxonomy name -> seed-local id of the first def emitted for it. Every locale\n\t// of a name is one taxonomy, whatever translation_group its rows carry.\n\tconst anchorByName = new Map<string, string>();\n\n\tfor (const def of defs) {\n\t\tconst defSeedId =\n\t\t\ti18nEnabled && def.locale ? `tax:${def.name}:${def.locale}` : `tax:${def.name}`;\n\n\t\t// Terms in this def's locale.\n\t\tconst terms = await termRepo.findByName(def.name, { locale: def.locale });\n\n\t\t// translation_group -> slug for parent resolution within this locale.\n\t\t// `parentId` stores the parent's translation_group, not a row id.\n\t\tconst groupToSlug = new Map<string, string>();\n\t\tfor (const term of terms) groupToSlug.set(term.translationGroup ?? term.id, term.slug);\n\n\t\t// translation_group -> seed id of the anchor term.\n\t\tconst termGroupToSeedId = new Map<string, string>();\n\n\t\tconst seedTerms: SeedTaxonomyTerm[] = [];\n\t\tfor (const term of terms) {\n\t\t\tconst termSeedId =\n\t\t\t\ti18nEnabled && term.locale\n\t\t\t\t\t? `term:${def.name}:${term.slug}:${term.locale}`\n\t\t\t\t\t: `term:${def.name}:${term.slug}`;\n\n\t\t\tconst seedTerm: SeedTaxonomyTerm = {\n\t\t\t\tid: termSeedId,\n\t\t\t\tslug: term.slug,\n\t\t\t\tlabel: term.label,\n\t\t\t\tdescription: typeof term.data?.description === \"string\" ? term.data.description : undefined,\n\t\t\t};\n\n\t\t\tif (term.parentId) seedTerm.parent = groupToSlug.get(term.parentId);\n\n\t\t\tif (i18nEnabled && term.locale) {\n\t\t\t\tseedTerm.locale = term.locale;\n\t\t\t\tif (term.translationGroup) {\n\t\t\t\t\tconst anchor = termGroupToSeedId.get(term.translationGroup);\n\t\t\t\t\tif (anchor) seedTerm.translationOf = anchor;\n\t\t\t\t\telse termGroupToSeedId.set(term.translationGroup, termSeedId);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tseedTerms.push(seedTerm);\n\t\t}\n\n\t\t// Anchors first so import can resolve `translationOf`.\n\t\tseedTerms.sort((a, b) => Number(!!a.translationOf) - Number(!!b.translationOf));\n\n\t\tconst taxonomy: SeedTaxonomy = {\n\t\t\tid: defSeedId,\n\t\t\tname: def.name,\n\t\t\tlabel: def.label,\n\t\t\tlabelSingular: def.label_singular || undefined,\n\t\t};\n\n\t\tif (i18nEnabled && def.locale) {\n\t\t\ttaxonomy.locale = def.locale;\n\t\t\tconst anchor = anchorByName.get(def.name);\n\t\t\tif (anchor) taxonomy.translationOf = anchor;\n\t\t\telse anchorByName.set(def.name, defSeedId);\n\t\t}\n\n\t\t// The structure is the taxonomy's, so only the entry translations point at carries it.\n\t\tif (!taxonomy.translationOf) {\n\t\t\ttaxonomy.hierarchical = def.hierarchical === 1;\n\t\t\ttaxonomy.collections = parseTaxonomyCollections(def.collections);\n\t\t}\n\n\t\tif (seedTerms.length > 0) taxonomy.terms = seedTerms;\n\n\t\tresult.push(taxonomy);\n\t}\n\n\t// Anchors first at def level too.\n\tresult.sort((a, b) => Number(!!a.translationOf) - Number(!!b.translationOf));\n\n\treturn result;\n}\n\n/**\n * Export menus with their items\n */\nasync function exportMenus(\n\tdb: Kysely<Database>,\n\ti18nEnabled: boolean,\n\tcontentGroupSeedIds: ContentGroupSeedIds,\n): Promise<SeedMenu[]> {\n\tconst menus = await db\n\t\t.selectFrom(\"_emdash_menus\")\n\t\t.selectAll()\n\t\t// Chained, not `orderBy([\"name\", \"locale\"])`: kysely deprecated the array\n\t\t// form and announces it with `console.log`, which lands in the seed\n\t\t// document this command writes to stdout.\n\t\t.orderBy(\"name\")\n\t\t.orderBy(\"locale\")\n\t\t.execute();\n\n\tconst result: SeedMenu[] = [];\n\t// translation_group -> seed-local id of the anchor menu in that group.\n\tconst groupToSeedId = new Map<string, string>();\n\t// Shared across menus: translated items reference anchor items in sibling menus.\n\tconst itemGroupToSeedId = new Map<string, string>();\n\tconst usedItemSeedIds = new Set<string>();\n\n\tfor (const menu of menus) {\n\t\tconst seedId =\n\t\t\ti18nEnabled && menu.locale ? `menu:${menu.name}:${menu.locale}` : `menu:${menu.name}`;\n\n\t\tconst items = await db\n\t\t\t.selectFrom(\"_emdash_menu_items\")\n\t\t\t.selectAll()\n\t\t\t.where(\"menu_id\", \"=\", menu.id)\n\t\t\t.orderBy(\"sort_order\", \"asc\")\n\t\t\t.execute();\n\n\t\tconst seedItems = buildMenuItemTree(items, {\n\t\t\ti18nEnabled,\n\t\t\tmenuName: menu.name,\n\t\t\tmenuLocale: menu.locale ?? null,\n\t\t\titemGroupToSeedId,\n\t\t\tusedItemSeedIds,\n\t\t\tcontentGroupSeedIds,\n\t\t});\n\n\t\tconst seedMenu: SeedMenu = {\n\t\t\tid: seedId,\n\t\t\tname: menu.name,\n\t\t\tlabel: menu.label,\n\t\t\titems: seedItems,\n\t\t};\n\n\t\tif (i18nEnabled && menu.locale) {\n\t\t\tseedMenu.locale = menu.locale;\n\t\t\tif (menu.translation_group) {\n\t\t\t\tconst anchor = groupToSeedId.get(menu.translation_group);\n\t\t\t\tif (anchor) seedMenu.translationOf = anchor;\n\t\t\t\telse groupToSeedId.set(menu.translation_group, seedId);\n\t\t\t}\n\t\t}\n\n\t\tresult.push(seedMenu);\n\t}\n\n\t// Anchors first so import can resolve `translationOf`.\n\tresult.sort((a, b) => Number(!!a.translationOf) - Number(!!b.translationOf));\n\n\treturn result;\n}\n\n/** Type guard for valid widget types */\nfunction isWidgetType(t: string): t is SeedWidget[\"type\"] {\n\treturn t === \"content\" || t === \"menu\" || t === \"component\";\n}\n\n/**\n * Build hierarchical menu item tree from flat array\n */\nfunction buildMenuItemTree(\n\titems: Array<{\n\t\tid: string;\n\t\tparent_id: string | null;\n\t\ttype: string;\n\t\tlabel: string;\n\t\tcustom_url: string | null;\n\t\treference_collection: string | null;\n\t\treference_id: string | null;\n\t\ttarget: string | null;\n\t\ttitle_attr: string | null;\n\t\tcss_classes: string | null;\n\t\tlocale?: string | null;\n\t\ttranslation_group?: string | null;\n\t}>,\n\ti18nCtx: {\n\t\ti18nEnabled: boolean;\n\t\tmenuName: string;\n\t\tmenuLocale: string | null;\n\t\t// translation_group -> seed-local id of the anchor item in that group.\n\t\titemGroupToSeedId: Map<string, string>;\n\t\tusedItemSeedIds: Set<string>;\n\t\tcontentGroupSeedIds: ContentGroupSeedIds;\n\t},\n): SeedMenuItem[] {\n\t// Build parent -> children map\n\tconst childMap = new Map<string | null, typeof items>();\n\n\tfor (const item of items) {\n\t\tconst parentId = item.parent_id;\n\t\tif (!childMap.has(parentId)) {\n\t\t\tchildMap.set(parentId, []);\n\t\t}\n\t\tchildMap.get(parentId)!.push(item);\n\t}\n\n\tfunction makeSeedId(item: (typeof items)[number]): string {\n\t\tconst base = slugify(item.label || \"\") || item.id;\n\t\tconst locale = i18nCtx.i18nEnabled ? (item.locale ?? i18nCtx.menuLocale) : null;\n\t\tconst candidate = locale\n\t\t\t? `item:${i18nCtx.menuName}:${base}:${locale}`\n\t\t\t: `item:${i18nCtx.menuName}:${base}`;\n\t\tif (!i18nCtx.usedItemSeedIds.has(candidate)) {\n\t\t\ti18nCtx.usedItemSeedIds.add(candidate);\n\t\t\treturn candidate;\n\t\t}\n\t\t// Collision fallback: append DB id to disambiguate duplicate labels.\n\t\tconst fallback = locale\n\t\t\t? `item:${i18nCtx.menuName}:${base}:${item.id}:${locale}`\n\t\t\t: `item:${i18nCtx.menuName}:${base}:${item.id}`;\n\t\ti18nCtx.usedItemSeedIds.add(fallback);\n\t\treturn fallback;\n\t}\n\n\t// Recursively build tree\n\tfunction buildLevel(parentId: string | null): SeedMenuItem[] {\n\t\tconst children = childMap.get(parentId) || [];\n\t\tconst result = children.map((item) => {\n\t\t\tconst seedItem: SeedMenuItem = {\n\t\t\t\ttype: item.type,\n\t\t\t\tlabel: item.label || undefined,\n\t\t\t};\n\n\t\t\tif (item.type === \"custom\") {\n\t\t\t\tseedItem.url = item.custom_url || undefined;\n\t\t\t} else {\n\t\t\t\t// `reference_id` holds the target's translation_group. Content\n\t\t\t\t// targets are named by the seed id `applySeed` maps back to a row;\n\t\t\t\t// anything this export did not include keeps the stored value.\n\t\t\t\tconst contentSeedId =\n\t\t\t\t\titem.type !== \"taxonomy\" && item.reference_id\n\t\t\t\t\t\t? i18nCtx.contentGroupSeedIds.get(item.reference_id)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tseedItem.ref = contentSeedId ?? (item.reference_id || undefined);\n\t\t\t\tseedItem.collection = item.reference_collection || undefined;\n\t\t\t}\n\n\t\t\tif (item.target === \"_blank\") {\n\t\t\t\tseedItem.target = \"_blank\";\n\t\t\t}\n\t\t\tif (item.title_attr) {\n\t\t\t\tseedItem.titleAttr = item.title_attr;\n\t\t\t}\n\t\t\tif (item.css_classes) {\n\t\t\t\tseedItem.cssClasses = item.css_classes;\n\t\t\t}\n\n\t\t\tif (i18nCtx.i18nEnabled) {\n\t\t\t\tconst itemLocale = item.locale ?? i18nCtx.menuLocale;\n\t\t\t\tconst seedId = makeSeedId(item);\n\t\t\t\tseedItem.id = seedId;\n\t\t\t\tif (itemLocale) seedItem.locale = itemLocale;\n\t\t\t\tif (item.translation_group) {\n\t\t\t\t\tconst anchor = i18nCtx.itemGroupToSeedId.get(item.translation_group);\n\t\t\t\t\tif (anchor && anchor !== seedId) seedItem.translationOf = anchor;\n\t\t\t\t\telse if (!anchor) i18nCtx.itemGroupToSeedId.set(item.translation_group, seedId);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add children\n\t\t\tconst itemChildren = buildLevel(item.id);\n\t\t\tif (itemChildren.length > 0) {\n\t\t\t\tseedItem.children = itemChildren;\n\t\t\t}\n\n\t\t\treturn seedItem;\n\t\t});\n\n\t\t// Sibling order is preserved (maps to sort_order on import). Cross-menu\n\t\t// `translationOf` already resolves because exportMenus sorts anchors first.\n\t\treturn result;\n\t}\n\n\treturn buildLevel(null);\n}\n\n/**\n * Export widget areas with their widgets\n */\nasync function exportWidgetAreas(db: Kysely<Database>): Promise<SeedWidgetArea[]> {\n\t// Get all widget areas\n\tconst areas = await db.selectFrom(\"_emdash_widget_areas\").selectAll().execute();\n\n\tconst result: SeedWidgetArea[] = [];\n\n\tfor (const area of areas) {\n\t\t// Get widgets for this area\n\t\tconst widgets = await db\n\t\t\t.selectFrom(\"_emdash_widgets\")\n\t\t\t.selectAll()\n\t\t\t.where(\"area_id\", \"=\", area.id)\n\t\t\t.orderBy(\"sort_order\", \"asc\")\n\t\t\t.execute();\n\n\t\tconst seedWidgets: SeedWidget[] = widgets\n\t\t\t.filter((w) => isWidgetType(w.type))\n\t\t\t.map((widget) => {\n\t\t\t\tconst wType: SeedWidget[\"type\"] = isWidgetType(widget.type) ? widget.type : \"content\";\n\t\t\t\tconst seedWidget: SeedWidget = {\n\t\t\t\t\ttype: wType,\n\t\t\t\t};\n\n\t\t\t\tif (widget.title) {\n\t\t\t\t\tseedWidget.title = widget.title;\n\t\t\t\t}\n\n\t\t\t\tif (widget.type === \"content\" && widget.content) {\n\t\t\t\t\tseedWidget.content = JSON.parse(widget.content);\n\t\t\t\t} else if (widget.type === \"menu\" && widget.menu_name) {\n\t\t\t\t\tseedWidget.menuName = widget.menu_name;\n\t\t\t\t} else if (widget.type === \"component\") {\n\t\t\t\t\tif (widget.component_id) {\n\t\t\t\t\t\tseedWidget.componentId = widget.component_id;\n\t\t\t\t\t}\n\t\t\t\t\tif (widget.component_props) {\n\t\t\t\t\t\tseedWidget.props = JSON.parse(widget.component_props);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn seedWidget;\n\t\t\t});\n\n\t\tresult.push({\n\t\t\tname: area.name,\n\t\t\tlabel: area.label,\n\t\t\tdescription: area.description || undefined,\n\t\t\twidgets: seedWidgets,\n\t\t});\n\t}\n\n\treturn result;\n}\n\nfunction isSeedRedirectType(type: number): type is NonNullable<SeedRedirect[\"type\"]> {\n\treturn type === 301 || type === 302 || type === 307 || type === 308;\n}\n\n/**\n * Export redirect rules. Terminal rules (410/451) have no seed representation\n * and are reported through `warn` instead.\n *\n * Databases migrated from before the source guard can hold several rows for\n * one source; only the guarded row is exported, since a seed rejects duplicate\n * sources.\n */\nasync function exportRedirects(\n\tdb: Kysely<Database>,\n\twarn: (message: string) => void,\n): Promise<SeedRedirect[]> {\n\tconst rows = await db\n\t\t.selectFrom(\"_emdash_redirects\")\n\t\t.select([\"source\", \"destination\", \"type\", \"enabled\", \"group_name\", \"source_guard\"])\n\t\t.orderBy(\"created_at\")\n\t\t.orderBy(\"id\")\n\t\t.execute();\n\n\tconst guardedRows = new Map<string, (typeof rows)[number]>();\n\tfor (const row of rows) {\n\t\tconst current = guardedRows.get(row.source);\n\t\tif (!current || (row.source_guard === 1 && current.source_guard !== 1)) {\n\t\t\tguardedRows.set(row.source, row);\n\t\t}\n\t}\n\n\tconst result: SeedRedirect[] = [];\n\tfor (const row of rows) {\n\t\tif (guardedRows.get(row.source) !== row) {\n\t\t\twarn(`Skipping duplicate rule for \"${row.source}\" -> \"${row.destination}\".`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!isSeedRedirectType(row.type)) {\n\t\t\twarn(`Skipping ${row.type} rule for \"${row.source}\": seeds only carry 301/302/307/308.`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst redirect: SeedRedirect = {\n\t\t\tsource: row.source,\n\t\t\tdestination: row.destination,\n\t\t\ttype: row.type,\n\t\t};\n\t\tif (row.enabled === 0) redirect.enabled = false;\n\t\tif (row.group_name) redirect.groupName = row.group_name;\n\t\tresult.push(redirect);\n\t}\n\treturn result;\n}\n\nfunction isSeedSectionSource(source: string): source is NonNullable<SeedSection[\"source\"]> {\n\treturn source === \"theme\" || source === \"user\" || source === \"import\";\n}\n\n/** Section slugs a seed accepts. The WordPress importer can store others. */\nconst SEED_SECTION_SLUG_PATTERN = /^[a-z0-9-]+$/;\n\nasync function exportSections(\n\tdb: Kysely<Database>,\n\twarn: (message: string) => void,\n): Promise<SeedSection[]> {\n\tconst rows = await db\n\t\t.selectFrom(\"_emdash_sections\")\n\t\t.select([\"slug\", \"title\", \"description\", \"keywords\", \"content\", \"source\"])\n\t\t.orderBy(\"slug\")\n\t\t.execute();\n\n\tconst result: SeedSection[] = [];\n\tfor (const row of rows) {\n\t\tif (!SEED_SECTION_SLUG_PATTERN.test(row.slug)) {\n\t\t\twarn(\n\t\t\t\t`Skipping section \"${row.slug}\": seed section slugs may only contain lowercase letters, digits, and hyphens.`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tconst section: SeedSection = {\n\t\t\tslug: row.slug,\n\t\t\ttitle: row.title,\n\t\t\tcontent: JSON.parse(row.content),\n\t\t};\n\t\tif (row.description) section.description = row.description;\n\t\tif (row.keywords) section.keywords = JSON.parse(row.keywords);\n\t\tif (isSeedSectionSource(row.source)) section.source = row.source;\n\t\tresult.push(section);\n\t}\n\treturn result;\n}\n\n/** An entry read for export, paired with the seed id it will be written under. */\ninterface CollectedEntry {\n\titem: ContentItem;\n\tseedId: string;\n}\n\n/** A relation, by the slug a reference field addresses it under. */\ntype RelationsBySlug = Map<\n\tstring,\n\t{ id: string; childCollection: string; maxChildrenPerParent: number | null }\n>;\n\nasync function loadRelations(db: Kysely<Database>): Promise<RelationsBySlug> {\n\tconst rows = await db\n\t\t.selectFrom(\"_emdash_relations\")\n\t\t.select([\"id\", \"slug\", \"child_collection\", \"max_children_per_parent\"])\n\t\t.execute();\n\treturn new Map(\n\t\trows.map((row) => [\n\t\t\trow.slug,\n\t\t\t{\n\t\t\t\tid: row.id,\n\t\t\t\tchildCollection: row.child_collection,\n\t\t\t\tmaxChildrenPerParent: row.max_children_per_parent,\n\t\t\t},\n\t\t]),\n\t);\n}\n\n/** A legacy reference column holds a single entry id or an array of them. */\nfunction legacyReferenceValues(value: unknown): string[] {\n\tif (typeof value === \"string\") return [value];\n\tif (Array.isArray(value)) return value.filter((v): v is string => typeof v === \"string\");\n\treturn [];\n}\n\n/**\n * For each exported collection, the other exported collections its entries\n * point into.\n *\n * A field bound to a relation names its target in the relation, and its links\n * are not in `data` to be read. A field with no relation still holds entry ids\n * in its own column; those are read from the values rather than from a declared\n * target, so a field without `options.collection` is still accounted for.\n */\nfunction referenceTargets(\n\tcollected: Map<string, CollectedEntry[]>,\n\tcollectionsBySlug: Map<string, SeedCollection>,\n\tentryIdToCollection: Map<string, string>,\n\trelations: RelationsBySlug,\n): Map<string, Set<string>> {\n\tconst targets = new Map<string, Set<string>>();\n\n\tfor (const [slug, items] of collected) {\n\t\tconst referenceFields = (collectionsBySlug.get(slug)?.fields ?? []).filter(\n\t\t\t(field) => field.type === \"reference\",\n\t\t);\n\t\tif (referenceFields.length === 0) continue;\n\n\t\tconst found = new Set<string>();\n\t\tconst add = (target: string | undefined): void => {\n\t\t\tif (target && target !== slug) found.add(target);\n\t\t};\n\n\t\tfor (const field of referenceFields) {\n\t\t\tconst relationSlug = field.validation?.relation;\n\t\t\tif (typeof relationSlug !== \"string\") continue;\n\t\t\tif (field.validation?.relationSide === \"child\") continue;\n\t\t\tadd(relations.get(relationSlug)?.childCollection);\n\t\t}\n\n\t\tconst columnFields = referenceFields\n\t\t\t.filter((field) => typeof field.validation?.relation !== \"string\")\n\t\t\t.map((field) => field.slug);\n\t\tif (columnFields.length > 0) {\n\t\t\tfor (const { item } of items) {\n\t\t\t\tfor (const fieldSlug of columnFields) {\n\t\t\t\t\tfor (const value of legacyReferenceValues(item.data[fieldSlug])) {\n\t\t\t\t\t\tadd(entryIdToCollection.get(value));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (found.size > 0) targets.set(slug, found);\n\t}\n\n\treturn targets;\n}\n\n/**\n * Order collections so a reference's target is written before the entry that\n * points at it. `applySeed` fills its seed-id map as it walks the file, so a\n * `$ref` into a collection further down resolves to nothing and is stored\n * verbatim.\n *\n * Depth-first, with the caller's order as the tie-break so an export without\n * references keeps the collection order it had. A cycle has no valid order;\n * the collections on it stay where they were rather than failing the export.\n */\nfunction orderByReferenceTargets(slugs: string[], targets: Map<string, Set<string>>): string[] {\n\tconst exported = new Set(slugs);\n\tconst ordered: string[] = [];\n\tconst placed = new Set<string>();\n\tconst visiting = new Set<string>();\n\n\tconst visit = (slug: string): void => {\n\t\tif (placed.has(slug) || visiting.has(slug)) return;\n\t\tvisiting.add(slug);\n\t\tfor (const target of targets.get(slug) ?? []) {\n\t\t\tif (exported.has(target)) visit(target);\n\t\t}\n\t\tvisiting.delete(slug);\n\t\tplaced.add(slug);\n\t\tordered.push(slug);\n\t};\n\n\tfor (const slug of slugs) visit(slug);\n\treturn ordered;\n}\n\n/** translation_group -> seed id of the entry anchoring that group */\ntype ContentGroupSeedIds = Map<string, string>;\n\ninterface MediaInfo {\n\turl: string;\n\tfilename: string;\n\talt?: string;\n\tcaption?: string;\n}\n\ninterface ExportedContent {\n\tcontent: Record<string, SeedContentEntry[]>;\n\tgroupSeedIds: ContentGroupSeedIds;\n\t/** Number of `$media` references written. */\n\tmediaCount: number;\n}\n\n/**\n * Export content from collections\n */\nasync function exportContent(\n\tdb: Kysely<Database>,\n\tcollections: SeedCollection[],\n\tincludeCollections: string[] | null,\n\tbylineGroupToSeedId: Map<string, string>,\n\ti18nEnabled: boolean,\n\tmediaUrlPrefix: string,\n): Promise<ExportedContent> {\n\tconst content: Record<string, SeedContentEntry[]> = {};\n\tconst mediaCounter = { count: 0 };\n\tconst contentRepo = new ContentRepository(db);\n\tconst taxonomyRepo = new TaxonomyRepository(db);\n\tconst mediaRepo = new MediaRepository(db);\n\n\t// Build media id -> info map for $media conversion\n\tconst mediaMap = new Map<string, MediaInfo>();\n\ttry {\n\t\tlet cursor: string | undefined;\n\t\tdo {\n\t\t\tconst result = await mediaRepo.findMany({\n\t\t\t\tlimit: 100,\n\t\t\t\tcursor,\n\t\t\t\tstatus: \"all\",\n\t\t\t});\n\t\t\tfor (const media of result.items) {\n\t\t\t\tmediaMap.set(media.id, {\n\t\t\t\t\turl: `${mediaUrlPrefix}${media.storageKey}`,\n\t\t\t\t\tfilename: media.filename,\n\t\t\t\t\talt: media.alt || undefined,\n\t\t\t\t\tcaption: media.caption || undefined,\n\t\t\t\t});\n\t\t\t}\n\t\t\tcursor = result.nextCursor;\n\t\t} while (cursor);\n\t} catch {\n\t\t// Media table might not exist or be empty\n\t}\n\n\t// Read every entry and assign its seed id before emitting any of them. A\n\t// reference can point at a collection the emit loop has not reached yet, so\n\t// both seed-id maps have to be complete before the first conversion — and the\n\t// collection order itself is derived from what points where.\n\t//\n\t// Keyed two ways: links are keyed by translation group, while a legacy\n\t// reference column holding one entry id is not.\n\tconst collected = new Map<string, CollectedEntry[]>();\n\tconst entryIdToSeedId = new Map<string, string>();\n\tconst entryIdToCollection = new Map<string, string>();\n\tconst groupToSeedId = new Map<string, string>();\n\tconst exported: ExportedEntry[] = [];\n\n\tfor (const collection of collections) {\n\t\t// Skip if not in include list\n\t\tif (includeCollections && !includeCollections.includes(collection.slug)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst items: CollectedEntry[] = [];\n\t\tlet cursor: string | undefined;\n\n\t\t// Paginate through all entries\n\t\tdo {\n\t\t\tconst result = await contentRepo.findMany(collection.slug, {\n\t\t\t\tlimit: 100,\n\t\t\t\tcursor,\n\t\t\t});\n\n\t\t\tfor (const item of result.items) {\n\t\t\t\t// Generate seed ID from collection:slug:locale for stable references\n\t\t\t\tconst seedId = item.slug\n\t\t\t\t\t? i18nEnabled && item.locale\n\t\t\t\t\t\t? `${collection.slug}:${item.slug}:${item.locale}`\n\t\t\t\t\t\t: `${collection.slug}:${item.slug}`\n\t\t\t\t\t: item.id;\n\n\t\t\t\titems.push({ item, seedId });\n\t\t\t\tentryIdToSeedId.set(item.id, seedId);\n\t\t\t\tentryIdToCollection.set(item.id, collection.slug);\n\t\t\t\t// The first entry of a group is the one written without\n\t\t\t\t// `translationOf`, so `applySeed` gives it the group's id.\n\t\t\t\tconst group = item.translationGroup ?? item.id;\n\t\t\t\tif (!groupToSeedId.has(group)) groupToSeedId.set(group, seedId);\n\t\t\t}\n\n\t\t\tcursor = result.nextCursor;\n\t\t} while (cursor);\n\n\t\tcollected.set(collection.slug, items);\n\t}\n\n\tconst relations = await loadRelations(db);\n\tconst collectionsBySlug = new Map(collections.map((c) => [c.slug, c]));\n\tconst orderedSlugs = orderByReferenceTargets(\n\t\t[...collected.keys()],\n\t\treferenceTargets(collected, collectionsBySlug, entryIdToCollection, relations),\n\t);\n\n\tfor (const slug of orderedSlugs) {\n\t\tconst collection = collectionsBySlug.get(slug);\n\t\tconst items = collected.get(slug);\n\t\tif (!collection || !items) continue;\n\n\t\tconst entries: SeedContentEntry[] = [];\n\n\t\t// When i18n is enabled, track translation_group -> seed ID so that\n\t\t// translations can reference the source entry's seed-local ID.\n\t\t// Key: EmDash translation_group ULID, Value: seed-local ID of the first entry in that group\n\t\tconst translationGroupToSeedId = new Map<string, string>();\n\n\t\tfor (const { item, seedId } of items) {\n\t\t\t// Process data fields for $media conversion\n\t\t\tconst processedData = processDataForExport(\n\t\t\t\titem.data,\n\t\t\t\tcollection.fields,\n\t\t\t\tmediaMap,\n\t\t\t\tmediaCounter,\n\t\t\t);\n\n\t\t\tconst entry: SeedContentEntry = {\n\t\t\t\tid: seedId,\n\t\t\t\tslug: item.slug?.trim() ? item.slug : collection.routable === false ? undefined : item.id,\n\t\t\t\t// Seeds carry no schedule, and `applySeed` publishes an entry with\n\t\t\t\t// no status, so every unpublished state (including scheduled) is a\n\t\t\t\t// draft.\n\t\t\t\tstatus: item.status === \"published\" ? \"published\" : \"draft\",\n\t\t\t\tdata: processedData,\n\t\t\t};\n\n\t\t\t// Add i18n fields when enabled\n\t\t\tif (i18nEnabled && item.locale) {\n\t\t\t\tentry.locale = item.locale;\n\n\t\t\t\tif (item.translationGroup) {\n\t\t\t\t\tconst sourceSeedId = translationGroupToSeedId.get(item.translationGroup);\n\t\t\t\t\tif (sourceSeedId) {\n\t\t\t\t\t\t// This is a translation — reference the source entry\n\t\t\t\t\t\tentry.translationOf = sourceSeedId;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// First entry in this translation group — track it\n\t\t\t\t\t\ttranslationGroupToSeedId.set(item.translationGroup, seedId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Get taxonomy assignments\n\t\t\tconst taxonomies = await getTaxonomyAssignments(taxonomyRepo, collection.slug, item.id);\n\t\t\tif (Object.keys(taxonomies).length > 0) {\n\t\t\t\tentry.taxonomies = taxonomies;\n\t\t\t}\n\n\t\t\t// Get byline credits. Read the junction directly: its `byline_id`\n\t\t\t// stores the translation_group, which is exactly the key in\n\t\t\t// `bylineGroupToSeedId`. This is locale-agnostic (one row per\n\t\t\t// credit) and avoids the locale-sibling fan-out a hydrated read\n\t\t\t// would produce.\n\t\t\tconst bylines = await getBylineCredits(db, collection.slug, item.id, bylineGroupToSeedId);\n\t\t\tif (bylines.length > 0) {\n\t\t\t\tentry.bylines = bylines;\n\t\t\t}\n\n\t\t\texported.push({\n\t\t\t\tcollection,\n\t\t\t\tentry,\n\t\t\t\ttranslationGroup: item.translationGroup ?? null,\n\t\t\t\treferenceValues: item.data,\n\t\t\t});\n\n\t\t\tentries.push(entry);\n\t\t}\n\n\t\tif (i18nEnabled && entries.length > 0) {\n\t\t\t// Sort entries so source locale entries appear before their translations.\n\t\t\t// Entries without translationOf come first; entries with translationOf come after.\n\t\t\tentries.sort((a, b) => {\n\t\t\t\tif (a.translationOf && !b.translationOf) return 1;\n\t\t\t\tif (!a.translationOf && b.translationOf) return -1;\n\t\t\t\treturn 0;\n\t\t\t});\n\t\t}\n\n\t\tif (entries.length > 0) {\n\t\t\tcontent[collection.slug] = entries;\n\t\t}\n\t}\n\n\tawait addReferenceLinks(db, exported, relations, groupToSeedId, entryIdToSeedId);\n\n\treturn { content, groupSeedIds: groupToSeedId, mediaCount: mediaCounter.count };\n}\n\ninterface ExportedEntry {\n\tcollection: SeedCollection;\n\tentry: SeedContentEntry;\n\ttranslationGroup: string | null;\n\t/** The entry's stored `data`, which a reference field's column value is read from. */\n\treferenceValues: Record<string, unknown>;\n}\n\n/**\n * Write each entry's reference selection into its `data` as `$ref:` values, which\n * the seed's own content ids resolve on apply.\n *\n * A field bound to a relation takes its selection from the link table. Only the\n * parent side is emitted: both sides view one link set, so a child-side field\n * would restate links the parent side already carries, and `setReferenceChildren`\n * accepts them only from the parent. A field with no relation takes the entry id\n * in its column instead.\n *\n * Runs after every collection has been emitted, so the seed id of any target is\n * known. A target that was not exported has none: a link is then dropped, since\n * nothing in the seed owns it, while a column value keeps its `$ref:` prefix\n * around the raw row id. Stripping the prefix there would write a row id that no\n * restored row carries into the column, and the restore would report success.\n */\nasync function addReferenceLinks(\n\tdb: Kysely<Database>,\n\texported: ExportedEntry[],\n\trelations: RelationsBySlug,\n\tgroupToSeedId: Map<string, string>,\n\tentryIdToSeedId: Map<string, string>,\n): Promise<void> {\n\tif (exported.length === 0) return;\n\n\t// Relation id -> parent group -> ordered child groups.\n\tconst linksByRelation = new Map<string, Map<string, string[]>>();\n\tif (relations.size > 0) {\n\t\tconst edges = await db\n\t\t\t.selectFrom(\"_emdash_content_references\")\n\t\t\t.select([\"relation_id\", \"parent_group\", \"child_group\"])\n\t\t\t.orderBy(\"sort_order\", \"asc\")\n\t\t\t.execute();\n\t\tfor (const edge of edges) {\n\t\t\tconst byParent = linksByRelation.get(edge.relation_id) ?? new Map<string, string[]>();\n\t\t\tconst children = byParent.get(edge.parent_group) ?? [];\n\t\t\tchildren.push(edge.child_group);\n\t\t\tbyParent.set(edge.parent_group, children);\n\t\t\tlinksByRelation.set(edge.relation_id, byParent);\n\t\t}\n\t}\n\n\tfor (const { collection, entry, translationGroup, referenceValues } of exported) {\n\t\tfor (const field of collection.fields) {\n\t\t\tif (field.type !== \"reference\") continue;\n\t\t\tconst slug = field.validation?.relation;\n\n\t\t\tif (typeof slug !== \"string\") {\n\t\t\t\t// No relation: the field keeps its own column, holding one entry id or\n\t\t\t\t// a JSON array of them.\n\t\t\t\tconst stored = referenceValues[field.slug];\n\t\t\t\tconst ids = (Array.isArray(stored) ? stored : [stored]).filter(\n\t\t\t\t\t(id): id is string => typeof id === \"string\" && id.length > 0,\n\t\t\t\t);\n\t\t\t\tconst refs = ids.map((id) => `$ref:${entryIdToSeedId.get(id) ?? id}`);\n\t\t\t\tif (refs.length === 0) continue;\n\t\t\t\tentry.data[field.slug] = Array.isArray(stored) ? refs : refs[0];\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (field.validation?.relationSide === \"child\") continue;\n\n\t\t\tconst relation = relations.get(slug);\n\t\t\tif (!relation || !translationGroup) continue;\n\n\t\t\tconst childGroups = linksByRelation.get(relation.id)?.get(translationGroup) ?? [];\n\t\t\tconst refs = childGroups\n\t\t\t\t.map((group) => groupToSeedId.get(group))\n\t\t\t\t.filter((seedId): seedId is string => seedId !== undefined)\n\t\t\t\t.map((seedId) => `$ref:${seedId}`);\n\t\t\tif (refs.length === 0) continue;\n\n\t\t\tentry.data[field.slug] = relation.maxChildrenPerParent === 1 ? refs[0] : refs;\n\t\t}\n\t}\n}\n\n/**\n * Convert a stored media value (image or file) to `$media` syntax. Values that\n * don't point at a known media row are kept as they are.\n */\nfunction toSeedMedia(\n\tvalue: unknown,\n\tmediaMap: Map<string, MediaInfo>,\n\tmediaCounter: { count: number },\n): unknown {\n\tif (!value || typeof value !== \"object\") return value;\n\tconst mediaValue = value as { id?: unknown; alt?: unknown };\n\tconst mediaInfo = typeof mediaValue.id === \"string\" ? mediaMap.get(mediaValue.id) : undefined;\n\tif (!mediaInfo) return value;\n\n\tmediaCounter.count++;\n\treturn {\n\t\t$media: {\n\t\t\turl: mediaInfo.url,\n\t\t\tfilename: mediaInfo.filename,\n\t\t\talt: (typeof mediaValue.alt === \"string\" && mediaValue.alt) || mediaInfo.alt,\n\t\t\tcaption: mediaInfo.caption,\n\t\t},\n\t};\n}\n\n/** Slugs of a repeater field's `image` sub-fields. */\nfunction repeaterImageSubFields(field: SeedField): Set<string> {\n\tconst subFields = field.validation?.subFields;\n\tconst slugs = new Set<string>();\n\tif (!Array.isArray(subFields)) return slugs;\n\tfor (const subField of subFields) {\n\t\tif (\n\t\t\tsubField &&\n\t\t\ttypeof subField === \"object\" &&\n\t\t\tsubField.type === \"image\" &&\n\t\t\ttypeof subField.slug === \"string\"\n\t\t) {\n\t\t\tslugs.add(subField.slug);\n\t\t}\n\t}\n\treturn slugs;\n}\n\n/**\n * Process content data for export: media values become `$media` references\n * and reference values become `$ref:` seed ids.\n */\nfunction processDataForExport(\n\tdata: Record<string, unknown>,\n\tfields: SeedField[],\n\tmediaMap: Map<string, MediaInfo>,\n\tmediaCounter: { count: number },\n): Record<string, unknown> {\n\tconst result: Record<string, unknown> = {};\n\n\tconst fieldsBySlug = new Map<string, SeedField>();\n\tfor (const field of fields) {\n\t\tfieldsBySlug.set(field.slug, field);\n\t}\n\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tconst field = fieldsBySlug.get(key);\n\t\tconst fieldType: FieldType | undefined = field?.type;\n\n\t\tif (fieldType === \"image\" || fieldType === \"file\") {\n\t\t\tresult[key] = toSeedMedia(value, mediaMap, mediaCounter);\n\t\t} else if (field && fieldType === \"repeater\" && Array.isArray(value)) {\n\t\t\tconst imageSubFields = repeaterImageSubFields(field);\n\t\t\tresult[key] = value.map((row: unknown) => {\n\t\t\t\tif (!row || typeof row !== \"object\" || Array.isArray(row)) return row;\n\t\t\t\tconst exportedRow: Record<string, unknown> = {};\n\t\t\t\tfor (const [subKey, subValue] of Object.entries(row)) {\n\t\t\t\t\texportedRow[subKey] = imageSubFields.has(subKey)\n\t\t\t\t\t\t? toSeedMedia(subValue, mediaMap, mediaCounter)\n\t\t\t\t\t\t: subValue;\n\t\t\t\t}\n\t\t\t\treturn exportedRow;\n\t\t\t});\n\t\t} else if (fieldType === \"reference\") {\n\t\t\t// Left for `addReferenceLinks`, which knows the seed id each entry was\n\t\t\t// emitted under. A `$ref:` built here from a raw entry id resolves\n\t\t\t// against nothing on apply.\n\t\t\tcontinue;\n\t\t} else {\n\t\t\tresult[key] = value;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Get ordered byline credits for a content entry as `SeedBylineCredit[]`.\n *\n * The `_emdash_content_bylines.byline_id` column stores the credited byline's\n * `translation_group`, so it maps straight through `groupToSeedId`. Credits\n * whose group wasn't emitted in the root `bylines[]` are skipped (defensive;\n * shouldn't happen for a consistent DB).\n */\nasync function getBylineCredits(\n\tdb: Kysely<Database>,\n\tcollection: string,\n\tentryId: string,\n\tgroupToSeedId: Map<string, string>,\n): Promise<SeedBylineCredit[]> {\n\tconst rows = await db\n\t\t.selectFrom(\"_emdash_content_bylines\")\n\t\t.select([\"byline_id\", \"role_label\"])\n\t\t.where(\"collection_slug\", \"=\", collection)\n\t\t.where(\"content_id\", \"=\", entryId)\n\t\t.orderBy(\"sort_order\", \"asc\")\n\t\t.execute();\n\n\tconst credits: SeedBylineCredit[] = [];\n\tfor (const row of rows) {\n\t\tconst seedId = groupToSeedId.get(row.byline_id);\n\t\tif (!seedId) continue;\n\t\tconst credit: SeedBylineCredit = { byline: seedId };\n\t\tif (row.role_label) credit.roleLabel = row.role_label;\n\t\tcredits.push(credit);\n\t}\n\n\treturn credits;\n}\n\n/**\n * Get taxonomy term assignments for a content entry\n */\nasync function getTaxonomyAssignments(\n\ttaxonomyRepo: TaxonomyRepository,\n\tcollection: string,\n\tentryId: string,\n): Promise<Record<string, string[]>> {\n\tconst terms = await taxonomyRepo.getTermsForEntry(collection, entryId);\n\tconst result: Record<string, string[]> = {};\n\n\tfor (const term of terms) {\n\t\tif (!result[term.name]) {\n\t\t\tresult[term.name] = [];\n\t\t}\n\t\tresult[term.name].push(term.slug);\n\t}\n\n\treturn result;\n}\n","/**\n * emdash init\n *\n * Initialize database from template config in package.json\n */\n\nimport { readFile, access } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport consola from \"consola\";\nimport { sql } from \"kysely\";\n\nimport { createDatabase } from \"../../database/connection.js\";\nimport { runMigrations } from \"../../database/migrations/runner.js\";\n\nexport interface EmDashConfig {\n\tlabel?: string;\n\tschema?: string;\n\tseed?: string;\n}\n\ninterface PackageJson {\n\tname?: string;\n\temdash?: EmDashConfig;\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function readPackageJson(cwd: string): Promise<PackageJson | null> {\n\tconst pkgPath = resolve(cwd, \"package.json\");\n\ttry {\n\t\tconst content = await readFile(pkgPath, \"utf-8\");\n\t\treturn JSON.parse(content);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function runSqlFile(db: ReturnType<typeof createDatabase>, filePath: string): Promise<void> {\n\tconst contents = await readFile(filePath, \"utf-8\");\n\n\t// Remove single-line comments\n\tconst withoutComments = contents\n\t\t.split(\"\\n\")\n\t\t.filter((line) => !line.trim().startsWith(\"--\"))\n\t\t.join(\"\\n\");\n\n\t// Split on semicolons, filter empty statements\n\tconst statements = withoutComments\n\t\t.split(\";\")\n\t\t.map((s) => s.trim())\n\t\t.filter((s) => s.length > 0);\n\n\tfor (const statement of statements) {\n\t\tawait db.executeQuery(sql.raw(statement).compile(db));\n\t}\n}\n\n/**\n * Check if database has already been initialized with template schema\n */\nasync function isAlreadyInitialized(db: ReturnType<typeof createDatabase>): Promise<boolean> {\n\ttry {\n\t\t// Use raw SQL since this runs on an untyped database connection\n\t\tconst result = await sql<{\n\t\t\tcount: number;\n\t\t}>`SELECT COUNT(id) as count FROM _emdash_collections`.execute(db);\n\t\tconst row = result.rows[0];\n\t\treturn row ? row.count > 0 : false;\n\t} catch {\n\t\t// Table doesn't exist yet\n\t\treturn false;\n\t}\n}\n\nexport const initCommand = defineCommand({\n\tmeta: {\n\t\tname: \"init\",\n\t\tdescription: \"Initialize database from template config\",\n\t},\n\targs: {\n\t\tdatabase: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"d\",\n\t\t\tdescription: \"Database path (default: ./data.db)\",\n\t\t\tdefault: \"./data.db\",\n\t\t},\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Working directory\",\n\t\t\tdefault: process.cwd(),\n\t\t},\n\t\tforce: {\n\t\t\ttype: \"boolean\",\n\t\t\talias: \"f\",\n\t\t\tdescription: \"Force re-initialization\",\n\t\t\tdefault: false,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst cwd = resolve(args.cwd);\n\t\tconsola.start(\"Initializing EmDash...\");\n\n\t\t// 1. Read package.json\n\t\tconst pkg = await readPackageJson(cwd);\n\t\tif (!pkg) {\n\t\t\tconsola.error(\"No package.json found in\", cwd);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconst config = pkg.emdash;\n\t\tconsola.info(`Project: ${pkg.name || \"unknown\"}`);\n\n\t\tif (config?.label) {\n\t\t\tconsola.info(`Template: ${config.label}`);\n\t\t}\n\n\t\t// 2. Create/connect to database\n\t\tconst dbPath = resolve(cwd, args.database);\n\t\tconsola.info(`Database: ${dbPath}`);\n\n\t\tconst db = createDatabase({ url: `file:${dbPath}` });\n\n\t\t// 3. Run core migrations (always run - they're idempotent)\n\t\tconsola.start(\"Running migrations...\");\n\t\ttry {\n\t\t\tconst { applied } = await runMigrations(db);\n\t\t\tif (applied.length > 0) {\n\t\t\t\tconsola.success(`Applied ${applied.length} migrations`);\n\t\t\t\tfor (const name of applied) {\n\t\t\t\t\tconsola.info(` - ${name}`);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconsola.info(\"Migrations already up to date\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Migration failed:\", error);\n\t\t\tawait db.destroy();\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// 4. Check if already initialized (has collections)\n\t\tconst alreadyInitialized = await isAlreadyInitialized(db);\n\t\tif (alreadyInitialized && !args.force) {\n\t\t\tawait db.destroy();\n\t\t\tconsola.success(\"Already initialized. Use --force to re-run schema/seed.\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (alreadyInitialized && args.force) {\n\t\t\tconsola.warn(\"Re-initializing (--force)...\");\n\t\t}\n\n\t\t// 5. Run template schema.sql if present\n\t\tif (config?.schema) {\n\t\t\tconst schemaPath = resolve(cwd, config.schema);\n\t\t\tif (await fileExists(schemaPath)) {\n\t\t\t\tconsola.start(`Running schema: ${config.schema}`);\n\t\t\t\ttry {\n\t\t\t\t\tawait runSqlFile(db, schemaPath);\n\t\t\t\t\tconsola.success(\"Schema applied\");\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsola.error(\"Schema failed:\", error);\n\t\t\t\t\tawait db.destroy();\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconsola.warn(`Schema file not found: ${config.schema}`);\n\t\t\t}\n\t\t}\n\n\t\t// 6. JSON seed files are now handled by `emdash seed` command\n\t\t// The bootstrap script runs `emdash init && emdash seed`\n\t\t// Legacy SQL seed files (seed.sql) could be handled here if needed\n\n\t\tawait db.destroy();\n\t\tconsola.success(\"EmDash initialized successfully!\");\n\t\tconsola.info(\"Run `pnpm dev` to start the development server\");\n\t},\n});\n","/**\n * Login/logout/whoami CLI commands\n *\n * Login uses the OAuth Device Flow (RFC 8628):\n * 1. POST /oauth/device/code → get device_code + user_code\n * 2. Display URL + code to user\n * 3. Poll POST /oauth/device/token until authorized\n * 4. Save tokens to ~/.config/emdash/auth.json\n *\n * Custom headers (--header / EMDASH_HEADERS) are sent with every request\n * and persisted to credentials so subsequent commands inherit them.\n * This supports sites behind reverse proxies like Cloudflare Access.\n */\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\nimport pc from \"picocolors\";\n\nimport {\n\tcreateHeaderAwareFetch,\n\tgetCachedAccessToken,\n\tisAccessRedirect,\n\tresolveCustomHeaders,\n\trunCloudflaredLogin,\n} from \"../../client/cf-access.js\";\nimport {\n\tgetCredentials,\n\tremoveCredentials,\n\tresolveCredentialKey,\n\tsaveCredentials,\n} from \"../credentials.js\";\nimport { configureOutputMode } from \"../output.js\";\n\n// ---------------------------------------------------------------------------\n// Types for discovery + device flow responses\n// ---------------------------------------------------------------------------\n\ninterface DiscoveryResponse {\n\tinstance?: { name?: string };\n\tauth?: {\n\t\tmode?: string;\n\t\tmethods?: {\n\t\t\tdevice_flow?: {\n\t\t\t\tdevice_authorization_endpoint: string;\n\t\t\t\ttoken_endpoint: string;\n\t\t\t};\n\t\t\tapi_tokens?: boolean;\n\t\t};\n\t};\n}\n\ninterface DeviceCodeResponse {\n\tdevice_code: string;\n\tuser_code: string;\n\tverification_uri: string;\n\texpires_in: number;\n\tinterval: number;\n}\n\ninterface TokenResponse {\n\taccess_token: string;\n\trefresh_token: string;\n\ttoken_type: string;\n\texpires_in: number;\n\tscope: string;\n}\n\n// ---------------------------------------------------------------------------\n// Device Flow polling\n// ---------------------------------------------------------------------------\n\nasync function pollForToken(\n\ttokenEndpoint: string,\n\tdeviceCode: string,\n\tinterval: number,\n\texpiresIn: number,\n\tfetchFn: typeof fetch,\n): Promise<TokenResponse> {\n\tconst deadline = Date.now() + expiresIn * 1000;\n\tlet currentInterval = interval;\n\n\twhile (Date.now() < deadline) {\n\t\tawait new Promise((resolve) => setTimeout(resolve, currentInterval * 1000));\n\n\t\tconst res = await fetchFn(tokenEndpoint, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify({\n\t\t\t\tdevice_code: deviceCode,\n\t\t\t\tgrant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n\t\t\t}),\n\t\t});\n\n\t\tif (res.ok) {\n\t\t\tconst body = (await res.json()) as { data: TokenResponse };\n\t\t\treturn body.data;\n\t\t}\n\n\t\tconst body = (await res.json()) as { error?: string; interval?: number };\n\n\t\tif (body.error === \"authorization_pending\") {\n\t\t\t// Keep polling\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (body.error === \"slow_down\") {\n\t\t\t// Use server-provided interval, or fall back to incrementing by 5s\n\t\t\tcurrentInterval = body.interval ?? currentInterval + 5;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (body.error === \"expired_token\") {\n\t\t\tthrow new Error(\"Device code expired. Please try again.\");\n\t\t}\n\n\t\tif (body.error === \"access_denied\") {\n\t\t\tthrow new Error(\"Authorization was denied.\");\n\t\t}\n\n\t\t// Unknown error\n\t\tthrow new Error(`Token exchange failed: ${body.error || res.statusText}`);\n\t}\n\n\tthrow new Error(\"Device code expired (timeout). Please try again.\");\n}\n\n// ---------------------------------------------------------------------------\n// Cloudflare Access handling\n// ---------------------------------------------------------------------------\n\n/**\n * Handle a Cloudflare Access redirect during login.\n *\n * 1. Try `cloudflared access token` for a cached JWT\n * 2. Try `cloudflared access login` to do the browser flow\n * 3. If cloudflared isn't available, print instructions for service tokens\n *\n * Returns the Access JWT, or null if auth couldn't be resolved.\n */\nasync function handleAccessRedirect(baseUrl: string): Promise<string | null> {\n\tconsola.info(\"This site is behind Cloudflare Access.\");\n\n\t// Try cached token first\n\tconst cached = await getCachedAccessToken(baseUrl);\n\tif (cached) {\n\t\tconsola.success(\"Using cached Cloudflare Access token from cloudflared.\");\n\t\treturn cached;\n\t}\n\n\t// Try interactive login via cloudflared\n\tconsola.info(\"Launching browser for Cloudflare Access login...\");\n\tconst loginOk = await runCloudflaredLogin(baseUrl);\n\n\tif (loginOk) {\n\t\tconst token = await getCachedAccessToken(baseUrl);\n\t\tif (token) {\n\t\t\tconsola.success(\"Cloudflare Access authentication successful.\");\n\t\t\treturn token;\n\t\t}\n\t}\n\n\t// cloudflared not available or login failed — guide the user\n\tconsole.log();\n\tconsola.info(\"Could not authenticate with Cloudflare Access automatically.\");\n\tconsola.info(\"You have two options:\");\n\tconsole.log();\n\tconsola.info(` ${pc.bold(\"Option 1:\")} Install cloudflared and run:`);\n\tconsole.log(` ${pc.cyan(`cloudflared access login ${baseUrl}`)}`);\n\tconsole.log(` ${pc.cyan(`emdash login --url ${baseUrl}`)}`);\n\tconsole.log();\n\tconsola.info(` ${pc.bold(\"Option 2:\")} Use a service token:`);\n\tconsole.log(\n\t\t` ${pc.cyan(`emdash login --url ${baseUrl} -H \"CF-Access-Client-Id: <id>\" -H \"CF-Access-Client-Secret: <secret>\"`)}`,\n\t);\n\tconsole.log();\n\n\treturn null;\n}\n\n// ---------------------------------------------------------------------------\n// Commands\n// ---------------------------------------------------------------------------\n\nexport const loginCommand = defineCommand({\n\tmeta: { name: \"login\", description: \"Log in to an EmDash instance\" },\n\targs: {\n\t\turl: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"u\",\n\t\t\tdescription: \"EmDash instance URL\",\n\t\t\tdefault: \"http://localhost:4321\",\n\t\t},\n\t\theader: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"H\",\n\t\t\tdescription: 'Custom header \"Name: Value\" (repeatable, or use EMDASH_HEADERS env)',\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst baseUrl = args.url || \"http://localhost:4321\";\n\t\tconsola.start(`Connecting to ${baseUrl}...`);\n\n\t\t// Resolve custom headers from --header flags and EMDASH_HEADERS env\n\t\tconst customHeaders = resolveCustomHeaders();\n\t\tlet headerFetch = createHeaderAwareFetch(customHeaders);\n\n\t\ttry {\n\t\t\t// Step 1: Fetch auth discovery.\n\t\t\t// Use redirect: \"manual\" to detect Cloudflare Access.\n\t\t\tconst discoveryUrl = new URL(\"/_emdash/.well-known/auth\", baseUrl);\n\t\t\tlet res = await headerFetch(discoveryUrl, { redirect: \"manual\" });\n\n\t\t\t// Handle Cloudflare Access\n\t\t\tif (isAccessRedirect(res)) {\n\t\t\t\tconst accessToken = await handleAccessRedirect(baseUrl);\n\t\t\t\tif (!accessToken) {\n\t\t\t\t\treturn; // handleAccessRedirect printed instructions\n\t\t\t\t}\n\t\t\t\t// Add the Access token to our custom headers and rebuild the fetch wrapper\n\t\t\t\tcustomHeaders[\"cf-access-token\"] = accessToken;\n\t\t\t\theaderFetch = createHeaderAwareFetch(customHeaders);\n\t\t\t\tres = await headerFetch(discoveryUrl);\n\t\t\t} else if (res.status === 301 || res.status === 302) {\n\t\t\t\t// Non-Access redirect — follow it normally\n\t\t\t\tres = await headerFetch(discoveryUrl);\n\t\t\t}\n\n\t\t\tif (!res.ok) {\n\t\t\t\tif (res.status === 404) {\n\t\t\t\t\tconst isLocal = baseUrl.includes(\"localhost\") || baseUrl.includes(\"127.0.0.1\");\n\t\t\t\t\tif (isLocal) {\n\t\t\t\t\t\tconsola.info(\"Auth discovery not available. Trying dev bypass...\");\n\t\t\t\t\t\tconst bypassRes = await fetch(new URL(\"/_emdash/api/auth/dev-bypass\", baseUrl), {\n\t\t\t\t\t\t\tredirect: \"manual\",\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (bypassRes.status === 302 || bypassRes.ok) {\n\t\t\t\t\t\t\tconsola.success(\"Dev bypass available. Client will authenticate automatically.\");\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsola.error(\"Could not authenticate. Is the dev server running?\");\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsola.error(\"Auth discovery endpoint not found. Is this an EmDash instance?\");\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconsola.error(`Discovery failed: ${res.status} ${res.statusText}`);\n\t\t\t\tprocess.exit(2);\n\t\t\t}\n\n\t\t\tconst discovery = (await res.json()) as DiscoveryResponse;\n\t\t\tconsola.success(`Connected to ${discovery.instance?.name || \"EmDash\"}`);\n\n\t\t\tconst deviceFlow = discovery.auth?.methods?.device_flow;\n\n\t\t\tif (!deviceFlow) {\n\t\t\t\t// No device flow available (external auth mode)\n\t\t\t\tconsola.info(\"Device Flow is not available for this instance.\");\n\t\t\t\tconsola.info(\"Generate an API token in Settings > API Tokens\");\n\t\t\t\tconsola.info(`Then run: ${pc.cyan(`emdash --token <token> --url ${baseUrl}`)}`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Step 2: Request device code\n\t\t\tconst codeUrl = new URL(deviceFlow.device_authorization_endpoint, baseUrl);\n\t\t\tconst codeRes = await headerFetch(codeUrl, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\"X-EmDash-Request\": \"1\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tclient_id: \"emdash-cli\",\n\t\t\t\t\tscope: \"admin\",\n\t\t\t\t}),\n\t\t\t});\n\n\t\t\tif (!codeRes.ok) {\n\t\t\t\tconsola.error(`Failed to request device code: ${codeRes.status}`);\n\t\t\t\tprocess.exit(2);\n\t\t\t}\n\n\t\t\tconst deviceCodeBody = (await codeRes.json()) as { data: DeviceCodeResponse };\n\t\t\tconst deviceCode = deviceCodeBody.data;\n\n\t\t\t// Step 3: Display instructions\n\t\t\tconsole.log();\n\t\t\tconsola.info(`Open your browser to:`);\n\t\t\tconsole.log(` ${pc.cyan(pc.bold(deviceCode.verification_uri))}`);\n\t\t\tconsole.log();\n\t\t\tconsola.info(`Enter code: ${pc.yellow(pc.bold(deviceCode.user_code))}`);\n\t\t\tconsole.log();\n\n\t\t\t// Try to open browser (best-effort)\n\t\t\ttry {\n\t\t\t\tconst { execFile } = await import(\"node:child_process\");\n\t\t\t\tif (process.platform === \"darwin\") {\n\t\t\t\t\texecFile(\"open\", [deviceCode.verification_uri]);\n\t\t\t\t} else if (process.platform === \"win32\") {\n\t\t\t\t\texecFile(\"cmd\", [\"/c\", \"start\", \"\", deviceCode.verification_uri]);\n\t\t\t\t} else {\n\t\t\t\t\texecFile(\"xdg-open\", [deviceCode.verification_uri]);\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Ignore — user can open manually\n\t\t\t}\n\n\t\t\t// Step 4: Poll for token\n\t\t\tconsola.start(\"Waiting for authorization...\");\n\n\t\t\tconst tokenUrl = new URL(deviceFlow.token_endpoint, baseUrl);\n\t\t\tconst tokenResult = await pollForToken(\n\t\t\t\ttokenUrl.toString(),\n\t\t\t\tdeviceCode.device_code,\n\t\t\t\tdeviceCode.interval,\n\t\t\t\tdeviceCode.expires_in,\n\t\t\t\theaderFetch,\n\t\t\t);\n\n\t\t\t// Step 5: Fetch user info\n\t\t\tlet userEmail = \"unknown\";\n\t\t\tlet userRole = \"unknown\";\n\t\t\ttry {\n\t\t\t\tconst meRes = await headerFetch(new URL(\"/_emdash/api/auth/me\", baseUrl), {\n\t\t\t\t\theaders: { Authorization: `Bearer ${tokenResult.access_token}` },\n\t\t\t\t});\n\t\t\t\tif (meRes.ok) {\n\t\t\t\t\tconst meJson = (await meRes.json()) as {\n\t\t\t\t\t\tdata: { email?: string; role?: number };\n\t\t\t\t\t};\n\t\t\t\t\tconst me = meJson.data;\n\t\t\t\t\tuserEmail = me.email || \"unknown\";\n\t\t\t\t\t// Map role number to name\n\t\t\t\t\tconst roleNames: Record<number, string> = {\n\t\t\t\t\t\t10: \"subscriber\",\n\t\t\t\t\t\t20: \"contributor\",\n\t\t\t\t\t\t30: \"author\",\n\t\t\t\t\t\t40: \"editor\",\n\t\t\t\t\t\t50: \"admin\",\n\t\t\t\t\t};\n\t\t\t\t\tuserRole = (me.role ? roleNames[me.role] : undefined) || \"unknown\";\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Non-critical\n\t\t\t}\n\n\t\t\t// Step 6: Save credentials (persist custom headers so subsequent commands inherit them)\n\t\t\tconst expiresAt = new Date(Date.now() + tokenResult.expires_in * 1000).toISOString();\n\t\t\tconst hasCustomHeaders = Object.keys(customHeaders).length > 0;\n\t\t\tsaveCredentials(baseUrl, {\n\t\t\t\taccessToken: tokenResult.access_token,\n\t\t\t\trefreshToken: tokenResult.refresh_token,\n\t\t\t\texpiresAt,\n\t\t\t\t...(hasCustomHeaders ? { customHeaders } : {}),\n\t\t\t\tuser: { email: userEmail, role: userRole },\n\t\t\t});\n\n\t\t\tconsola.success(`Logged in as ${pc.bold(userEmail)} (${userRole})`);\n\t\t\tconsola.info(`Token saved to ${pc.dim(resolveCredentialKey(baseUrl))}`);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Login failed\");\n\t\t\tprocess.exit(2);\n\t\t}\n\t},\n});\n\nexport const logoutCommand = defineCommand({\n\tmeta: { name: \"logout\", description: \"Log out of an EmDash instance\" },\n\targs: {\n\t\turl: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"u\",\n\t\t\tdescription: \"EmDash instance URL\",\n\t\t\tdefault: \"http://localhost:4321\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst baseUrl = args.url || \"http://localhost:4321\";\n\n\t\t// Get stored credentials\n\t\tconst cred = getCredentials(baseUrl);\n\n\t\tif (!cred) {\n\t\t\tconsola.info(\"No stored credentials found for this instance.\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst headerFetch = createHeaderAwareFetch(cred.customHeaders ?? {});\n\n\t\t// Revoke tokens server-side (best-effort)\n\t\ttry {\n\t\t\t// Revoke the refresh token (which also revokes associated access tokens)\n\t\t\tawait headerFetch(new URL(\"/_emdash/api/oauth/token/revoke\", baseUrl), {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify({ token: cred.refreshToken }),\n\t\t\t});\n\t\t} catch {\n\t\t\t// Non-critical — the local removal still works\n\t\t}\n\n\t\t// Remove local credentials\n\t\tremoveCredentials(baseUrl);\n\t\tconsola.success(\"Logged out successfully.\");\n\t},\n});\n\nexport const whoamiCommand = defineCommand({\n\tmeta: {\n\t\tname: \"whoami\",\n\t\tdescription: \"Show current user and auth method\",\n\t},\n\targs: {\n\t\turl: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"u\",\n\t\t\tdescription: \"EmDash instance URL\",\n\t\t\tdefault: \"http://localhost:4321\",\n\t\t},\n\t\ttoken: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"t\",\n\t\t\tdescription: \"Auth token\",\n\t\t},\n\t\tjson: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output as JSON\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\tconst baseUrl = args.url || \"http://localhost:4321\";\n\n\t\t// Resolve token: --token flag > EMDASH_TOKEN env > stored credentials\n\t\tlet token = args.token || process.env[\"EMDASH_TOKEN\"];\n\t\tlet authMethod = token ? \"token\" : \"none\";\n\t\tlet storedHeaders: Record<string, string> = {};\n\n\t\tif (!token) {\n\t\t\tconst cred = getCredentials(baseUrl);\n\t\t\tif (cred) {\n\t\t\t\ttoken = cred.accessToken;\n\t\t\t\tauthMethod = \"stored\";\n\t\t\t\tstoredHeaders = cred.customHeaders ?? {};\n\n\t\t\t\t// Check if expired\n\t\t\t\tif (new Date(cred.expiresAt) < new Date()) {\n\t\t\t\t\tconst headerFetch = createHeaderAwareFetch(storedHeaders);\n\t\t\t\t\t// Try to refresh\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst refreshRes = await headerFetch(\n\t\t\t\t\t\t\tnew URL(\"/_emdash/api/oauth/token/refresh\", baseUrl),\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\t\t\t\trefresh_token: cred.refreshToken,\n\t\t\t\t\t\t\t\t\tgrant_type: \"refresh_token\",\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (refreshRes.ok) {\n\t\t\t\t\t\t\tconst json = (await refreshRes.json()) as Record<string, unknown>;\n\t\t\t\t\t\t\t// Token endpoint wraps response in { data: ... } via apiSuccess.\n\t\t\t\t\t\t\t// Handle both wrapped and bare shapes for robustness.\n\t\t\t\t\t\t\tconst refreshed = (\n\t\t\t\t\t\t\t\tjson.data && typeof json.data === \"object\" && \"access_token\" in json.data\n\t\t\t\t\t\t\t\t\t? json.data\n\t\t\t\t\t\t\t\t\t: json\n\t\t\t\t\t\t\t) as TokenResponse;\n\t\t\t\t\t\t\ttoken = refreshed.access_token;\n\t\t\t\t\t\t\tsaveCredentials(baseUrl, {\n\t\t\t\t\t\t\t\t...cred,\n\t\t\t\t\t\t\t\taccessToken: refreshed.access_token,\n\t\t\t\t\t\t\t\texpiresAt: new Date(Date.now() + refreshed.expires_in * 1000).toISOString(),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsola.warn(\"Stored token expired and refresh failed. Run: emdash login\");\n\t\t\t\t\t\t\tprocess.exit(2);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tconsola.warn(\"Stored token expired. Run: emdash login\");\n\t\t\t\t\t\tprocess.exit(2);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!token) {\n\t\t\t// Try dev bypass for local\n\t\t\tconst isLocal = baseUrl.includes(\"localhost\") || baseUrl.includes(\"127.0.0.1\");\n\t\t\tif (isLocal) {\n\t\t\t\tauthMethod = \"dev-bypass\";\n\t\t\t\tconsola.info(`Auth method: ${pc.cyan(\"dev-bypass\")}`);\n\t\t\t\tconsola.info(\"No stored credentials. Client will use dev bypass for localhost.\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconsola.error(\"Not logged in. Run: emdash login\");\n\t\t\tprocess.exit(2);\n\t\t}\n\n\t\tconst headerFetch = createHeaderAwareFetch(storedHeaders);\n\n\t\ttry {\n\t\t\tconst meRes = await headerFetch(new URL(\"/_emdash/api/auth/me\", baseUrl), {\n\t\t\t\theaders: { Authorization: `Bearer ${token}` },\n\t\t\t});\n\n\t\t\tif (!meRes.ok) {\n\t\t\t\tif (meRes.status === 401) {\n\t\t\t\t\tconsola.error(\"Token is invalid or expired. Run: emdash login\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconsola.error(`Failed to fetch user info: ${meRes.status}`);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconst raw = (await meRes.json()) as {\n\t\t\t\tdata: {\n\t\t\t\t\tid: string;\n\t\t\t\t\temail: string;\n\t\t\t\t\tname: string | null;\n\t\t\t\t\trole: number;\n\t\t\t\t};\n\t\t\t};\n\t\t\tconst me = raw.data;\n\n\t\t\tconst roleNames: Record<number, string> = {\n\t\t\t\t10: \"subscriber\",\n\t\t\t\t20: \"contributor\",\n\t\t\t\t30: \"author\",\n\t\t\t\t40: \"editor\",\n\t\t\t\t50: \"admin\",\n\t\t\t};\n\n\t\t\tif (args.json) {\n\t\t\t\tconsole.log(\n\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\tid: me.id,\n\t\t\t\t\t\temail: me.email,\n\t\t\t\t\t\tname: me.name,\n\t\t\t\t\t\trole: roleNames[me.role] || `unknown (${me.role})`,\n\t\t\t\t\t\tauthMethod,\n\t\t\t\t\t\turl: baseUrl,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconsola.info(`Email: ${pc.bold(me.email)}`);\n\t\t\t\tif (me.name) consola.info(`Name: ${me.name}`);\n\t\t\t\tconsola.info(`Role: ${pc.cyan(roleNames[me.role] || `unknown (${me.role})`)}`);\n\t\t\t\tconsola.info(`Auth: ${pc.dim(authMethod)}`);\n\t\t\t\tconsola.info(`URL: ${pc.dim(baseUrl)}`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n","/**\n * emdash media\n *\n * Manage media items via the EmDash API\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { basename } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\n\nimport type { MediaUsageRepairInput, MediaUsageRepairResponse } from \"../../client/index.js\";\nimport { connectionArgs, createClientFromArgs } from \"../client-factory.js\";\nimport { configureOutputMode, output } from \"../output.js\";\n\nconst repairScopeError = \"Specify exactly one of --collection or --all\";\n\nconst listCommand = defineCommand({\n\tmeta: {\n\t\tname: \"list\",\n\t\tdescription: \"List media items\",\n\t},\n\targs: {\n\t\t...connectionArgs,\n\t\tmime: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Filter by MIME type (e.g., image/png)\",\n\t\t},\n\t\tlimit: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Number of items to return\",\n\t\t},\n\t\tcursor: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Pagination cursor\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\tconst client = createClientFromArgs(args);\n\n\t\ttry {\n\t\t\tconst result = await client.mediaList({\n\t\t\t\tmimeType: args.mime,\n\t\t\t\tlimit: args.limit ? Number(args.limit) : undefined,\n\t\t\t\tcursor: args.cursor,\n\t\t\t});\n\n\t\t\toutput(result, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Failed to list media:\", error instanceof Error ? error.message : error);\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst uploadCommand = defineCommand({\n\tmeta: {\n\t\tname: \"upload\",\n\t\tdescription: \"Upload a media file\",\n\t},\n\targs: {\n\t\tfile: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Path to the file to upload\",\n\t\t\trequired: true,\n\t\t},\n\t\t...connectionArgs,\n\t\talt: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Alt text for the media item\",\n\t\t},\n\t\tcaption: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Caption for the media item\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\tconst client = createClientFromArgs(args);\n\t\tconst filename = basename(args.file);\n\n\t\tconsola.start(`Uploading ${filename}...`);\n\n\t\ttry {\n\t\t\tconst buffer = await readFile(args.file);\n\t\t\tconst result = await client.mediaUpload(buffer, filename, {\n\t\t\t\talt: args.alt,\n\t\t\t\tcaption: args.caption,\n\t\t\t});\n\n\t\t\tconsola.success(`Uploaded ${filename}`);\n\t\t\toutput(result, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Failed to upload:\", error instanceof Error ? error.message : error);\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst getCommand = defineCommand({\n\tmeta: {\n\t\tname: \"get\",\n\t\tdescription: \"Get a media item\",\n\t},\n\targs: {\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Media item ID\",\n\t\t\trequired: true,\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\tconst client = createClientFromArgs(args);\n\n\t\ttry {\n\t\t\tconst result = await client.mediaGet(args.id);\n\t\t\toutput(result, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Failed to get media:\", error instanceof Error ? error.message : error);\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst deleteCommand = defineCommand({\n\tmeta: {\n\t\tname: \"delete\",\n\t\tdescription: \"Delete a media item\",\n\t},\n\targs: {\n\t\tid: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Media item ID\",\n\t\t\trequired: true,\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\tconst client = createClientFromArgs(args);\n\n\t\ttry {\n\t\t\tawait client.mediaDelete(args.id);\n\n\t\t\tif (args.json) {\n\t\t\t\toutput({ deleted: true }, args);\n\t\t\t} else {\n\t\t\t\tconsola.success(`Deleted media item ${args.id}`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Failed to delete media:\", error instanceof Error ? error.message : error);\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst repairUsageCommand = defineCommand({\n\tmeta: {\n\t\tname: \"repair-usage\",\n\t\tdescription:\n\t\t\t\"Repair content media usage indexes. partial/stale exit 0; automation should use --json and parse status.\",\n\t},\n\targs: {\n\t\t...connectionArgs,\n\t\tcollection: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"c\",\n\t\t\tdescription: \"Repair one content collection\",\n\t\t},\n\t\tall: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Repair every content collection\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\n\t\tconst hasCollectionArg = args.collection !== undefined;\n\t\tconst hasCollection = typeof args.collection === \"string\";\n\t\tconst hasAll = args.all === true;\n\t\tif ((hasCollectionArg && !hasCollection) || hasCollection === hasAll) {\n\t\t\tconsola.error(repairScopeError);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconst client = createClientFromArgs(args);\n\n\t\ttry {\n\t\t\tconst repairInput: MediaUsageRepairInput = hasCollection\n\t\t\t\t? { scope: \"collection\", collection: args.collection }\n\t\t\t\t: { scope: \"all\" };\n\t\t\tconst result = await client.mediaRepairUsage(repairInput);\n\n\t\t\tif (args.json || !process.stdout.isTTY) {\n\t\t\t\toutput(result, args);\n\t\t\t} else {\n\t\t\t\tprintRepairUsageSummary(result, repairInput);\n\t\t\t}\n\n\t\t\tif (result.status === \"failed\") {\n\t\t\t\tprocess.exitCode = 1;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsola.error(\n\t\t\t\t\"Failed to repair media usage:\",\n\t\t\t\terror instanceof Error ? error.message : error,\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\ntype RepairUsageSummary = {\n\tlevel: \"success\" | \"warn\";\n\tmessage: string;\n};\n\nexport function formatRepairUsageSummary(\n\tresult: MediaUsageRepairResponse,\n\tinput: MediaUsageRepairInput,\n): RepairUsageSummary {\n\tconst counts = `indexed ${result.indexedSourceCount}, failed ${result.failedSourceCount}, skipped ${result.skippedSourceCount}, deleted ${result.deletedSourceCount}`;\n\tconst scope =\n\t\tinput.scope === \"collection\"\n\t\t\t? `collection ${input.collection}`\n\t\t\t: `all content (${formatCollectionCount(result.collections.length)})`;\n\n\tif (result.status === \"complete\") {\n\t\treturn {\n\t\t\tlevel: \"success\",\n\t\t\tmessage: `Media usage repair complete for ${scope} (${counts}).`,\n\t\t};\n\t}\n\n\tconst details = result.collections\n\t\t.filter((collection) => collection.status !== \"complete\")\n\t\t.map((collection) => {\n\t\t\tconst error = collection.lastErrorCode ? `, ${collection.lastErrorCode}` : \"\";\n\t\t\treturn `${collection.collection}: ${collection.status}${error}`;\n\t\t})\n\t\t.join(\"; \");\n\tconst suffix = details ? ` ${details}.` : \"\";\n\n\tif (result.status === \"stale\") {\n\t\treturn {\n\t\t\tlevel: \"warn\",\n\t\t\tmessage: `Media usage repair is stale for ${scope}; trustworthy complete coverage was not established because another writer, repair, or stale marker won the race. Rerun when writes are quiet (${counts}).${suffix}`,\n\t\t};\n\t}\n\n\tif (result.status === \"partial\") {\n\t\treturn {\n\t\t\tlevel: \"warn\",\n\t\t\tmessage: `Media usage repair is partial for ${scope}; some sources or collections need attention (${counts}).${suffix}`,\n\t\t};\n\t}\n\n\treturn {\n\t\tlevel: \"warn\",\n\t\tmessage: `Media usage repair failed for ${scope} (${counts}).${suffix}`,\n\t};\n}\n\nfunction printRepairUsageSummary(\n\tresult: MediaUsageRepairResponse,\n\tinput: MediaUsageRepairInput,\n): void {\n\tconst summary = formatRepairUsageSummary(result, input);\n\tif (summary.level === \"success\") {\n\t\tconsola.success(summary.message);\n\t} else {\n\t\tconsola.warn(summary.message);\n\t}\n}\n\nfunction formatCollectionCount(count: number): string {\n\treturn `${count} collection${count === 1 ? \"\" : \"s\"}`;\n}\n\nexport const mediaCommand = defineCommand({\n\tmeta: {\n\t\tname: \"media\",\n\t\tdescription: \"Manage media items\",\n\t},\n\tsubCommands: {\n\t\tlist: listCommand,\n\t\tupload: uploadCommand,\n\t\tget: getCommand,\n\t\tdelete: deleteCommand,\n\t\t\"repair-usage\": repairUsageCommand,\n\t},\n});\n","/**\n * emdash menu\n *\n * Manage menus via the EmDash REST API.\n */\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\n\nimport { connectionArgs, createClientFromArgs } from \"../client-factory.js\";\nimport { configureOutputMode, output } from \"../output.js\";\n\nconst listCommand = defineCommand({\n\tmeta: {\n\t\tname: \"list\",\n\t\tdescription: \"List all menus\",\n\t},\n\targs: {\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst menus = await client.menus();\n\t\t\toutput(menus, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst getCommand = defineCommand({\n\tmeta: {\n\t\tname: \"get\",\n\t\tdescription: \"Get a menu with its items\",\n\t},\n\targs: {\n\t\tname: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Menu name\",\n\t\t\trequired: true,\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst menu = await client.menu(args.name);\n\t\t\toutput(menu, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nexport const menuCommand = defineCommand({\n\tmeta: {\n\t\tname: \"menu\",\n\t\tdescription: \"Manage menus\",\n\t},\n\tsubCommands: {\n\t\tlist: listCommand,\n\t\tget: getCommand,\n\t},\n});\n","import { access } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { isAbsolute, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport type { AstroI18nInput } from \"../i18n/normalize.js\";\nimport { normalizeAstroI18n } from \"../i18n/normalize.js\";\nimport type { CoreMigrationIdentity } from \"./identity.js\";\nimport {\n\tgetMigrationIntegrationMetadata,\n\tMIGRATION_CONFIG_SYMBOL,\n} from \"./integration-metadata.js\";\nimport { buildMigrationManifest } from \"./manifest-builder.js\";\nimport type { MigrationManifestV1 } from \"./manifest.js\";\n\nconst ASTRO_CONFIG_FILENAMES = [\n\t\"astro.config.mjs\",\n\t\"astro.config.js\",\n\t\"astro.config.ts\",\n\t\"astro.config.mts\",\n] as const;\n\ninterface EvaluatedAstroConfig {\n\tintegrations?: unknown[];\n\ti18n?: AstroI18nInput | null;\n}\n\nexport interface BuildMigrationManifestFromConfigOptions {\n\tprojectRoot: string;\n\tconfigFile?: string;\n}\n\nexport interface MigrationConfigLoaderDependencies {\n\tfindConfigFile: (projectRoot: string, configFile?: string) => Promise<string>;\n\tloadConfig: (projectRoot: string, configFile: string) => Promise<unknown>;\n\tloadIdentity: (projectRoot: string) => Promise<CoreMigrationIdentity>;\n}\n\nexport class MigrationConfigLoaderError extends Error {\n\tconstructor(message: string, options?: ErrorOptions) {\n\t\tsuper(message, options);\n\t\tthis.name = \"MigrationConfigLoaderError\";\n\t}\n}\n\nasync function isAccessible(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport async function findAstroConfigFile(\n\tprojectRoot: string,\n\tconfigFile?: string,\n): Promise<string> {\n\tconst root = resolve(projectRoot);\n\tif (configFile) {\n\t\tconst explicitPath = isAbsolute(configFile) ? configFile : resolve(root, configFile);\n\t\tif (await isAccessible(explicitPath)) return explicitPath;\n\t\tthrow new MigrationConfigLoaderError(`Astro config file not found: ${explicitPath}`);\n\t}\n\n\tfor (const filename of ASTRO_CONFIG_FILENAMES) {\n\t\tconst candidate = resolve(root, filename);\n\t\tif (await isAccessible(candidate)) return candidate;\n\t}\n\n\tthrow new MigrationConfigLoaderError(`No Astro config file found in ${root}`);\n}\n\nfunction projectRequire(projectRoot: string) {\n\treturn createRequire(resolve(projectRoot, \"package.json\"));\n}\n\nasync function importModule(path: string): Promise<unknown> {\n\treturn import(pathToFileURL(path).href);\n}\n\nfunction isRecord(value: unknown): value is Record<PropertyKey, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction moduleExport(module: unknown, name: string): unknown {\n\tif (!isRecord(module)) return undefined;\n\tconst direct = module[name];\n\tif (direct !== undefined) return direct;\n\tconst defaultExport = module.default;\n\treturn isRecord(defaultExport) ? defaultExport[name] : undefined;\n}\n\nfunction isCoreMigrationIdentity(value: unknown): value is CoreMigrationIdentity {\n\treturn (\n\t\tisRecord(value) &&\n\t\ttypeof value.emdashVersion === \"string\" &&\n\t\tArray.isArray(value.names) &&\n\t\tvalue.names.every((name) => typeof name === \"string\") &&\n\t\ttypeof value.fingerprint === \"string\"\n\t);\n}\n\nasync function loadProjectConfig(projectRoot: string, configFile: string): Promise<unknown> {\n\tlet viteEntrypoint: string;\n\ttry {\n\t\tconst require = projectRequire(projectRoot);\n\t\tconst astroEntrypoint = require.resolve(\"astro\");\n\t\tviteEntrypoint = createRequire(astroEntrypoint).resolve(\"vite\");\n\t} catch (error) {\n\t\tthrow new MigrationConfigLoaderError(\n\t\t\t\"Could not resolve Vite through the project's Astro installation\",\n\t\t\t{ cause: error },\n\t\t);\n\t}\n\n\tconst vite = await importModule(viteEntrypoint);\n\tconst loadConfigFromFile = moduleExport(vite, \"loadConfigFromFile\");\n\tif (typeof loadConfigFromFile !== \"function\") {\n\t\tthrow new MigrationConfigLoaderError(\n\t\t\t\"The Vite installation used by project-local Astro does not export loadConfigFromFile\",\n\t\t);\n\t}\n\tconst loaded: unknown = await Reflect.apply(loadConfigFromFile, undefined, [\n\t\t{ command: \"build\", mode: \"production\" },\n\t\tconfigFile,\n\t\tprojectRoot,\n\t\t\"silent\",\n\t]);\n\tif (!isRecord(loaded) || !Object.hasOwn(loaded, \"config\")) {\n\t\tthrow new MigrationConfigLoaderError(`Vite could not load Astro config: ${configFile}`);\n\t}\n\treturn loaded.config;\n}\n\nasync function loadProjectIdentity(projectRoot: string): Promise<CoreMigrationIdentity> {\n\tlet identityEntrypoint: string;\n\ttry {\n\t\tidentityEntrypoint = projectRequire(projectRoot).resolve(\"emdash/migrations\");\n\t} catch (error) {\n\t\tthrow new MigrationConfigLoaderError(\"Could not resolve emdash/migrations from the project\", {\n\t\t\tcause: error,\n\t\t});\n\t}\n\n\tconst module = await importModule(identityEntrypoint);\n\tconst getIdentity = moduleExport(module, \"getCoreMigrationIdentity\");\n\tif (typeof getIdentity !== \"function\") {\n\t\tthrow new MigrationConfigLoaderError(\n\t\t\t\"The project-local emdash/migrations module does not export getCoreMigrationIdentity\",\n\t\t);\n\t}\n\tconst identity: unknown = await Reflect.apply(getIdentity, undefined, []);\n\tif (!isCoreMigrationIdentity(identity)) {\n\t\tthrow new MigrationConfigLoaderError(\n\t\t\t\"The project-local emdash/migrations module returned an invalid migration identity\",\n\t\t);\n\t}\n\treturn identity;\n}\n\nconst defaultDependencies: MigrationConfigLoaderDependencies = {\n\tfindConfigFile: findAstroConfigFile,\n\tloadConfig: loadProjectConfig,\n\tloadIdentity: loadProjectIdentity,\n};\n\nfunction asAstroConfig(value: unknown): EvaluatedAstroConfig {\n\tif (typeof value !== \"object\" || value === null) {\n\t\tthrow new MigrationConfigLoaderError(\"Astro config must export an object\");\n\t}\n\treturn value;\n}\n\nexport async function buildMigrationManifestFromConfig(\n\toptions: BuildMigrationManifestFromConfigOptions,\n\tdependencies: MigrationConfigLoaderDependencies = defaultDependencies,\n): Promise<MigrationManifestV1> {\n\tconst projectRoot = resolve(options.projectRoot);\n\tconst configFile = await dependencies.findConfigFile(projectRoot, options.configFile);\n\tconst config = asAstroConfig(await dependencies.loadConfig(projectRoot, configFile));\n\tconst integrations = Array.isArray(config.integrations) ? config.integrations : [];\n\tconst matchingIntegrations = integrations.filter(\n\t\t(integration) => getMigrationIntegrationMetadata(integration) !== undefined,\n\t);\n\tif (matchingIntegrations.length !== 1) {\n\t\tthrow new MigrationConfigLoaderError(\n\t\t\t`Expected exactly one EmDash integration with migration metadata (${String(MIGRATION_CONFIG_SYMBOL)}), found ${matchingIntegrations.length}`,\n\t\t);\n\t}\n\n\tconst metadata = getMigrationIntegrationMetadata(matchingIntegrations[0]);\n\tif (!metadata?.database) {\n\t\tthrow new MigrationConfigLoaderError(\n\t\t\t\"The EmDash integration does not provide database migration metadata\",\n\t\t);\n\t}\n\tconst identity = await dependencies.loadIdentity(projectRoot);\n\n\treturn buildMigrationManifest({\n\t\tidentity,\n\t\ti18n: normalizeAstroI18n(config.i18n),\n\t\tdatabase: metadata.database,\n\t});\n}\n","import { readFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { dirname, isAbsolute, parse, resolve } from \"node:path\";\nimport { createInterface } from \"node:readline/promises\";\nimport { pathToFileURL } from \"node:url\";\n\nimport { defineCommand } from \"citty\";\n\nimport { busyLockHeldSince, migrationLockHeldMessage } from \"../../database/migration-lock.js\";\nimport { buildMigrationManifestFromConfig } from \"../../migrations/config-loader.js\";\nimport type { CoreMigrationIdentity } from \"../../migrations/identity.js\";\nimport type { MigrationManifestV1 } from \"../../migrations/manifest.js\";\nimport {\n\tMigrationManifestValidationError,\n\tvalidateMigrationManifest,\n} from \"../../migrations/manifest.js\";\nimport type {\n\tMigrationExecutor,\n\tMigrationExecutorFactory,\n\tMigrationReport,\n\tMigrationRequest,\n\tMigrationTarget,\n\tMigrationTargetOverrides,\n} from \"../../migrations/protocol.js\";\n\nconst FINGERPRINT_PATTERN = /^[0-9a-f]{64}$/;\nconst SAFE_TARGET_KIND_PATTERN = /^[a-z][a-z0-9_-]*$/;\nconst SAFE_MIGRATION_NAME_PATTERN = /^[A-Za-z0-9_.-]+$/;\nconst CREDENTIAL_URL_PATTERN = /:\\/\\/[^/\\s]+@/;\nconst CREDENTIAL_QUERY_PATTERN = /[?&](?:auth|credential|key|password|secret|signature|token)=/i;\nconst LOCK_ID_PATTERN = /^[1-9]\\d{0,15}$/;\nconst ISO_TIMESTAMP_PATTERN = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/;\nconst MAX_DATE_MS = 8.64e15;\n\nexport const MIGRATE_EXIT_CODES = Object.freeze({\n\tsuccess: 0,\n\terror: 1,\n\tpending: 2,\n\tunknownApplied: 3,\n\tconfirmation: 4,\n\tinterrupted: 130,\n} as const);\n\nexport type MigrationSignal = \"SIGINT\" | \"SIGTERM\";\n\nexport interface MigrateCommandOptions extends MigrationTargetOverrides {\n\tmanifest?: string;\n\tfromConfig?: boolean;\n\tconfig?: string;\n\tcheck?: boolean;\n\tstatus?: boolean;\n\tjson?: boolean;\n\texpectedTargetFingerprint?: string;\n\treleaseLock?: string;\n}\n\nexport interface MigrateCommandDependencies {\n\tcwd: string;\n\tenv: Readonly<Record<string, string | undefined>>;\n\tinteractive: boolean;\n\tfindProjectRoot: (start: string) => Promise<string>;\n\treadManifest: (path: string, isDefault: boolean) => Promise<unknown>;\n\tbuildManifestFromConfig: (projectRoot: string, configFile?: string) => Promise<unknown>;\n\tloadProjectIdentity: (projectRoot: string) => Promise<CoreMigrationIdentity>;\n\tloadProjectExecutor: (\n\t\tprojectRoot: string,\n\t\tentrypoint: string,\n\t) => Promise<MigrationExecutorFactory>;\n\tconfirm: (message: string) => Promise<boolean>;\n\twriteStdout: (value: string) => void;\n\twriteStderr: (value: string) => void;\n\tonSignal: (signal: MigrationSignal, handler: () => Promise<void>) => () => void;\n\tcleanupTimeoutMs: number;\n}\n\nclass MigrateCommandError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"MigrateCommandError\";\n\t}\n}\n\nfunction isRecord(value: unknown): value is Record<PropertyKey, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction moduleExport(module: unknown, name: string): unknown {\n\tif (!isRecord(module)) return undefined;\n\tconst direct = Reflect.get(module, name);\n\tif (direct !== undefined) return direct;\n\tconst defaultExport = Reflect.get(module, \"default\");\n\treturn isRecord(defaultExport) ? Reflect.get(defaultExport, name) : undefined;\n}\n\nasync function importProjectModule(projectRoot: string, specifier: string): Promise<unknown> {\n\tlet resolvedEntrypoint: string;\n\ttry {\n\t\tresolvedEntrypoint = createRequire(resolve(projectRoot, \"package.json\")).resolve(specifier);\n\t} catch {\n\t\tthrow new MigrateCommandError(`Could not resolve ${specifier} from the project.`);\n\t}\n\treturn import(pathToFileURL(resolvedEntrypoint).href);\n}\n\nfunction validateIdentity(value: unknown): CoreMigrationIdentity {\n\tif (\n\t\t!isRecord(value) ||\n\t\ttypeof value.emdashVersion !== \"string\" ||\n\t\t!Array.isArray(value.names) ||\n\t\t!value.names.every((name) => typeof name === \"string\") ||\n\t\ttypeof value.fingerprint !== \"string\" ||\n\t\t!FINGERPRINT_PATTERN.test(value.fingerprint)\n\t) {\n\t\tthrow new MigrateCommandError(\n\t\t\t\"The project-local emdash/migrations module returned an invalid migration identity.\",\n\t\t);\n\t}\n\treturn {\n\t\temdashVersion: value.emdashVersion,\n\t\tnames: [...value.names],\n\t\tfingerprint: value.fingerprint,\n\t};\n}\n\nexport async function loadProjectMigrationIdentity(\n\tprojectRoot: string,\n): Promise<CoreMigrationIdentity> {\n\tconst loaded = await importProjectModule(projectRoot, \"emdash/migrations\");\n\tconst getIdentity = moduleExport(loaded, \"getCoreMigrationIdentity\");\n\tif (typeof getIdentity !== \"function\") {\n\t\tthrow new MigrateCommandError(\n\t\t\t\"The project-local emdash/migrations module does not export getCoreMigrationIdentity.\",\n\t\t);\n\t}\n\treturn validateIdentity(await Reflect.apply(getIdentity, undefined, []));\n}\n\nexport async function loadProjectMigrationExecutor(\n\tprojectRoot: string,\n\tentrypoint: string,\n): Promise<MigrationExecutorFactory> {\n\tconst loaded = await importProjectModule(projectRoot, entrypoint);\n\tconst factory = moduleExport(loaded, \"createMigrationExecutor\");\n\tif (typeof factory !== \"function\") {\n\t\tthrow new MigrateCommandError(\n\t\t\t`The project-local ${entrypoint} module does not export createMigrationExecutor.`,\n\t\t);\n\t}\n\treturn (manifestConfig, context) => Reflect.apply(factory, undefined, [manifestConfig, context]);\n}\n\nasync function findProjectRoot(start: string): Promise<string> {\n\tlet current = resolve(start);\n\tconst filesystemRoot = parse(current).root;\n\tfor (;;) {\n\t\ttry {\n\t\t\tawait readFile(resolve(current, \"package.json\"), \"utf8\");\n\t\t\treturn current;\n\t\t} catch (error) {\n\t\t\tif (isRecord(error) && error.code !== \"ENOENT\" && error.code !== \"ENOTDIR\") {\n\t\t\t\tthrow new MigrateCommandError(\"Could not read the project package.json.\");\n\t\t\t}\n\t\t}\n\t\tif (current === filesystemRoot) break;\n\t\tcurrent = dirname(current);\n\t}\n\tthrow new MigrateCommandError(\"Could not find a project root containing package.json.\");\n}\n\nexport async function readMigrationManifestFile(\n\tpath: string,\n\tisDefault: boolean,\n): Promise<unknown> {\n\tlet source: string;\n\ttry {\n\t\tsource = await readFile(path, \"utf8\");\n\t} catch (error) {\n\t\tif (isDefault && isRecord(error) && (error.code === \"ENOENT\" || error.code === \"ENOTDIR\")) {\n\t\t\tthrow new MigrateCommandError(\n\t\t\t\t`No migration manifest found at ${path}. Build the project or use --from-config.`,\n\t\t\t);\n\t\t}\n\t\tthrow new MigrateCommandError(`Could not read migration manifest: ${path}`);\n\t}\n\ttry {\n\t\treturn JSON.parse(source);\n\t} catch {\n\t\tthrow new MigrateCommandError(`Migration manifest is not valid JSON: ${path}`);\n\t}\n}\n\nasync function confirmWithReadline(message: string): Promise<boolean> {\n\tconst prompt = createInterface({ input: process.stdin, output: process.stderr });\n\ttry {\n\t\tconst answer = await prompt.question(`${message} [y/N] `);\n\t\treturn answer.trim().toLowerCase() === \"y\" || answer.trim().toLowerCase() === \"yes\";\n\t} finally {\n\t\tprompt.close();\n\t}\n}\n\nfunction onProcessSignal(signal: MigrationSignal, handler: () => Promise<void>): () => void {\n\tconst listener = () => {\n\t\tvoid handler().finally(() => process.exit(MIGRATE_EXIT_CODES.interrupted));\n\t};\n\tprocess.once(signal, listener);\n\treturn () => process.removeListener(signal, listener);\n}\n\nconst defaultDependencies: MigrateCommandDependencies = {\n\tcwd: process.cwd(),\n\tenv: process.env,\n\tinteractive: Boolean(process.stdin.isTTY && process.stdout.isTTY),\n\tfindProjectRoot,\n\treadManifest: readMigrationManifestFile,\n\tbuildManifestFromConfig: (projectRoot, configFile) =>\n\t\tbuildMigrationManifestFromConfig({ projectRoot, configFile }),\n\tloadProjectIdentity: loadProjectMigrationIdentity,\n\tloadProjectExecutor: loadProjectMigrationExecutor,\n\tconfirm: confirmWithReadline,\n\twriteStdout: (value) => process.stdout.write(`${value}\\n`),\n\twriteStderr: (value) => process.stderr.write(`${value}\\n`),\n\tonSignal: onProcessSignal,\n\tcleanupTimeoutMs: 2_000,\n};\n\nfunction validateOptions(options: MigrateCommandOptions): void {\n\tif (options.manifest && options.fromConfig) {\n\t\tthrow new MigrateCommandError(\"--manifest and --from-config cannot be used together.\");\n\t}\n\tif (options.config && !options.fromConfig) {\n\t\tthrow new MigrateCommandError(\"--config requires --from-config.\");\n\t}\n\tif (options.check && options.status) {\n\t\tthrow new MigrateCommandError(\"--check and --status cannot be used together.\");\n\t}\n\tif (options.releaseLock !== undefined) {\n\t\tif (options.check || options.status) {\n\t\t\tthrow new MigrateCommandError(\"--release-lock cannot be used with --check or --status.\");\n\t\t}\n\t\tif (!LOCK_ID_PATTERN.test(options.releaseLock)) {\n\t\t\tthrow new MigrateCommandError(\"--release-lock requires the lock id shown by --status.\");\n\t\t}\n\t}\n\tif (\n\t\toptions.expectedTargetFingerprint &&\n\t\t!FINGERPRINT_PATTERN.test(options.expectedTargetFingerprint)\n\t) {\n\t\tthrow new MigrateCommandError(\"--expected-target-fingerprint must be a SHA-256 fingerprint.\");\n\t}\n}\n\nfunction hasControlCharacter(value: string): boolean {\n\tfor (let index = 0; index < value.length; index++) {\n\t\tconst code = value.charCodeAt(index);\n\t\tif (code <= 0x1f || code === 0x7f) return true;\n\t}\n\treturn false;\n}\n\nfunction targetField(value: unknown, name: string): string | undefined {\n\tif (value === undefined) return undefined;\n\tif (\n\t\ttypeof value !== \"string\" ||\n\t\tvalue.length === 0 ||\n\t\thasControlCharacter(value) ||\n\t\tCREDENTIAL_URL_PATTERN.test(value) ||\n\t\tCREDENTIAL_QUERY_PATTERN.test(value)\n\t) {\n\t\tthrow new MigrateCommandError(`The executor returned an unsafe migration target ${name}.`);\n\t}\n\treturn value;\n}\n\nfunction immutableTarget(value: unknown): Readonly<MigrationTarget> {\n\tif (!isRecord(value)) {\n\t\tthrow new MigrateCommandError(\"The executor returned an invalid migration target.\");\n\t}\n\tconst kind = targetField(value.kind, \"kind\");\n\tconst label = targetField(value.label, \"label\");\n\tconst fingerprint = targetField(value.fingerprint, \"fingerprint\");\n\tif (\n\t\t!kind ||\n\t\t!SAFE_TARGET_KIND_PATTERN.test(kind) ||\n\t\t!label ||\n\t\t!fingerprint ||\n\t\t!FINGERPRINT_PATTERN.test(fingerprint)\n\t) {\n\t\tthrow new MigrateCommandError(\"The executor returned an invalid migration target.\");\n\t}\n\tconst target: MigrationTarget = { kind, label, fingerprint };\n\tconst accountId = targetField(value.accountId, \"accountId\");\n\tconst environment = targetField(value.environment, \"environment\");\n\tconst resourceId = targetField(value.resourceId, \"resourceId\");\n\tif (accountId) target.accountId = accountId;\n\tif (environment) target.environment = environment;\n\tif (resourceId) target.resourceId = resourceId;\n\treturn Object.freeze(target);\n}\n\nfunction safeMigrationNames(value: unknown, field: string): string[] {\n\tif (\n\t\t!Array.isArray(value) ||\n\t\t!value.every((name) => typeof name === \"string\" && SAFE_MIGRATION_NAME_PATTERN.test(name))\n\t) {\n\t\tthrow new MigrateCommandError(`The migration executor returned an invalid ${field} report.`);\n\t}\n\treturn [...value];\n}\n\nfunction safeReport(value: unknown, target: Readonly<MigrationTarget>): MigrationReport {\n\tif (!isRecord(value)) {\n\t\tthrow new MigrateCommandError(\"The migration executor returned an invalid report.\");\n\t}\n\tconst reportTarget = immutableTarget(value.target);\n\tif (\n\t\treportTarget.kind !== target.kind ||\n\t\treportTarget.label !== target.label ||\n\t\treportTarget.fingerprint !== target.fingerprint ||\n\t\treportTarget.accountId !== target.accountId ||\n\t\treportTarget.environment !== target.environment ||\n\t\treportTarget.resourceId !== target.resourceId\n\t) {\n\t\tthrow new MigrateCommandError(\n\t\t\t\"The migration executor report target does not match the confirmed target.\",\n\t\t);\n\t}\n\tconst report: MigrationReport = {\n\t\ttarget: { ...reportTarget },\n\t\tknownApplied: safeMigrationNames(value.knownApplied, \"knownApplied\"),\n\t\tpending: safeMigrationNames(value.pending, \"pending\"),\n\t\tunknownApplied: safeMigrationNames(value.unknownApplied, \"unknownApplied\"),\n\t\texecuted: safeMigrationNames(value.executed, \"executed\"),\n\t};\n\tif (value.lock !== undefined) {\n\t\tconst lock = value.lock;\n\t\tif (\n\t\t\t!isRecord(lock) ||\n\t\t\ttypeof lock.id !== \"string\" ||\n\t\t\t!LOCK_ID_PATTERN.test(lock.id) ||\n\t\t\ttypeof lock.heldSince !== \"string\" ||\n\t\t\t!ISO_TIMESTAMP_PATTERN.test(lock.heldSince)\n\t\t) {\n\t\t\tthrow new MigrateCommandError(\"The migration executor returned an invalid lock report.\");\n\t\t}\n\t\treport.lock = { id: lock.id, heldSince: lock.heldSince };\n\t}\n\treturn report;\n}\n\nfunction printTarget(target: Readonly<MigrationTarget>, write: (value: string) => void): void {\n\twrite(`Migration target: ${target.kind} ${target.label}`);\n\tif (target.accountId) write(`Account: ${target.accountId}`);\n\tif (target.environment) write(`Environment: ${target.environment}`);\n\tif (target.resourceId) write(`Resource: ${target.resourceId}`);\n\twrite(`Target fingerprint: ${target.fingerprint}`);\n}\n\nfunction printNameSet(\n\tlabel: string,\n\tnames: readonly string[],\n\twrite: (value: string) => void,\n): void {\n\twrite(`${label}: ${names.length === 0 ? \"none\" : names.join(\", \")}`);\n}\n\nfunction printHumanReport(report: MigrationReport, write: (value: string) => void): void {\n\tif (report.lock) {\n\t\twrite(`Migration lock: held since ${report.lock.heldSince} (id ${report.lock.id})`);\n\t}\n\tprintNameSet(\"Known applied\", report.knownApplied, write);\n\tprintNameSet(\"Pending\", report.pending, write);\n\tprintNameSet(\"Unknown applied\", report.unknownApplied, write);\n\tprintNameSet(\"Executed\", report.executed, write);\n}\n\nfunction reportExitCode(options: MigrateCommandOptions, report: MigrationReport): number {\n\tif (!options.check) return MIGRATE_EXIT_CODES.success;\n\tif (report.unknownApplied.length > 0) return MIGRATE_EXIT_CODES.unknownApplied;\n\tif (report.pending.length > 0) return MIGRATE_EXIT_CODES.pending;\n\treturn MIGRATE_EXIT_CODES.success;\n}\n\nfunction createOverrides(options: MigrateCommandOptions): MigrationTargetOverrides {\n\treturn {\n\t\tdatabase: options.database,\n\t\tdatabaseUrlEnv: options.databaseUrlEnv,\n\t\td1: options.d1,\n\t\taccountId: options.accountId,\n\t\twranglerConfig: options.wranglerConfig,\n\t\twranglerEnv: options.wranglerEnv,\n\t};\n}\n\nfunction bounded(\n\toperation: Promise<void>,\n\ttimeoutMs: number,\n): Promise<\"complete\" | \"failed\" | \"timeout\"> {\n\tlet timer: ReturnType<typeof setTimeout>;\n\tconst timeout = new Promise<\"timeout\">((resolveTimeout) => {\n\t\ttimer = setTimeout(resolveTimeout, timeoutMs, \"timeout\");\n\t});\n\tconst completion = operation.then<\"complete\", \"failed\">(\n\t\t() => \"complete\",\n\t\t() => \"failed\",\n\t);\n\treturn Promise.race([completion, timeout]).finally(() => clearTimeout(timer));\n}\n\nasync function loadManifest(\n\toptions: MigrateCommandOptions,\n\tprojectRoot: string,\n\tdependencies: MigrateCommandDependencies,\n): Promise<unknown> {\n\tif (options.fromConfig) {\n\t\tdependencies.writeStderr(\n\t\t\t`Using trusted evaluated Astro configuration${options.config ? `: ${options.config}` : \".\"}`,\n\t\t);\n\t\treturn dependencies.buildManifestFromConfig(projectRoot, options.config);\n\t}\n\tconst isDefault = !options.manifest;\n\tconst path = options.manifest\n\t\t? isAbsolute(options.manifest)\n\t\t\t? options.manifest\n\t\t\t: resolve(projectRoot, options.manifest)\n\t\t: resolve(projectRoot, \".emdash/migrations.json\");\n\treturn dependencies.readManifest(path, isDefault);\n}\n\nfunction redactExecutorMessage(\n\tmessage: string,\n\tenv: Readonly<Record<string, string | undefined>>,\n): string {\n\tlet redacted = message\n\t\t.replace(/[A-Za-z][A-Za-z0-9+.-]*:\\/\\/\\S+/g, \"[REDACTED_URL]\")\n\t\t.replace(\n\t\t\t/\\b(auth|credential|key|password|secret|signature|token)\\s*[=:]\\s*\\S+/gi,\n\t\t\t\"$1=[REDACTED]\",\n\t\t);\n\tfor (const value of Object.values(env)) {\n\t\tif (value && value.length >= 4) redacted = redacted.replaceAll(value, \"[REDACTED]\");\n\t}\n\treturn redacted.replaceAll(/[\\r\\n\\t]/g, \" \").slice(0, 1_000);\n}\n\nfunction safeCommandMessage(\n\terror: unknown,\n\tenv: Readonly<Record<string, string | undefined>>,\n): string {\n\tif (error instanceof MigrateCommandError || error instanceof MigrationManifestValidationError) {\n\t\treturn error.message;\n\t}\n\t// Redaction would strip the docs link and could rewrite digits of the lock\n\t// id that match an environment value, so the message is rebuilt instead.\n\tif (error instanceof Error && error.name === \"MigrationLockHeldError\") {\n\t\tconst heldSince = busyLockHeldSince(error);\n\t\tif (heldSince !== undefined && Number.isSafeInteger(heldSince) && heldSince <= MAX_DATE_MS) {\n\t\t\treturn migrationLockHeldMessage(heldSince);\n\t\t}\n\t}\n\tif (error instanceof Error && error.message) return redactExecutorMessage(error.message, env);\n\treturn \"Migration command failed. Check the project configuration, target, and credentials.\";\n}\n\nexport async function runMigrateCommand(\n\toptions: MigrateCommandOptions,\n\tdependencies: MigrateCommandDependencies = defaultDependencies,\n): Promise<number> {\n\tlet executor: MigrationExecutor | undefined;\n\tlet disposePromise: Promise<void> | undefined;\n\tlet interrupted = false;\n\tlet primaryFailure = false;\n\tlet exitCode: number = MIGRATE_EXIT_CODES.error;\n\tconst interruptedResult = Symbol(\"interrupted\");\n\tlet resolveInterruption: (() => void) | undefined;\n\tconst interruption = new Promise<typeof interruptedResult>((resolveInterrupted) => {\n\t\tresolveInterruption = () => resolveInterrupted(interruptedResult);\n\t});\n\tconst dispose = () => {\n\t\tdisposePromise ??= executor?.dispose?.() ?? Promise.resolve();\n\t\treturn disposePromise;\n\t};\n\tconst removeSignalHandlers: (() => void)[] = [];\n\n\tconst execute = async (): Promise<number> => {\n\t\ttry {\n\t\t\tvalidateOptions(options);\n\t\t\tconst projectRoot = await dependencies.findProjectRoot(dependencies.cwd);\n\t\t\tconst unvalidatedManifest = await loadManifest(options, projectRoot, dependencies);\n\t\t\tconst identity = await dependencies.loadProjectIdentity(projectRoot);\n\t\t\tconst manifest: MigrationManifestV1 = await validateMigrationManifest(\n\t\t\t\tunvalidatedManifest,\n\t\t\t\tidentity,\n\t\t\t);\n\t\t\tconst factory = await dependencies.loadProjectExecutor(\n\t\t\t\tprojectRoot,\n\t\t\t\tmanifest.database.executorEntrypoint,\n\t\t\t);\n\t\t\texecutor = await factory(manifest.database.executorConfig, {\n\t\t\t\tprojectRoot,\n\t\t\t\tenv: dependencies.env,\n\t\t\t\toverrides: createOverrides(options),\n\t\t\t});\n\t\t\tconst target = immutableTarget(executor.target);\n\t\t\tprintTarget(target, dependencies.writeStderr);\n\n\t\t\tconst onSignal = async () => {\n\t\t\t\tinterrupted = true;\n\t\t\t\tawait bounded(dispose(), dependencies.cleanupTimeoutMs);\n\t\t\t\tresolveInterruption?.();\n\t\t\t};\n\t\t\tremoveSignalHandlers.push(\n\t\t\t\tdependencies.onSignal(\"SIGINT\", onSignal),\n\t\t\t\tdependencies.onSignal(\"SIGTERM\", onSignal),\n\t\t\t);\n\n\t\t\tconst releasing = options.releaseLock !== undefined;\n\t\t\tconst applying = !options.check && !options.status && !releasing;\n\t\t\tif (applying || releasing) {\n\t\t\t\tconst operation = releasing ? \"lock release\" : \"apply\";\n\t\t\t\tconst question = releasing\n\t\t\t\t\t? `Release migration lock ${options.releaseLock} on ${target.label}? Release it only when no migration is running.`\n\t\t\t\t\t: `Apply EmDash migrations to ${target.label}?`;\n\t\t\t\tif (options.expectedTargetFingerprint) {\n\t\t\t\t\tif (options.expectedTargetFingerprint !== target.fingerprint) {\n\t\t\t\t\t\tdependencies.writeStderr(\"Expected target fingerprint does not match the target.\");\n\t\t\t\t\t\texitCode = MIGRATE_EXIT_CODES.confirmation;\n\t\t\t\t\t\treturn exitCode;\n\t\t\t\t\t}\n\t\t\t\t} else if (!dependencies.interactive || options.json) {\n\t\t\t\t\tdependencies.writeStderr(\n\t\t\t\t\t\t`Noninteractive ${operation} requires --expected-target-fingerprint with the displayed fingerprint.`,\n\t\t\t\t\t);\n\t\t\t\t\texitCode = MIGRATE_EXIT_CODES.confirmation;\n\t\t\t\t\treturn exitCode;\n\t\t\t\t} else if (!(await dependencies.confirm(question))) {\n\t\t\t\t\tdependencies.writeStderr(releasing ? \"Lock release cancelled.\" : \"Migration cancelled.\");\n\t\t\t\t\texitCode = MIGRATE_EXIT_CODES.confirmation;\n\t\t\t\t\treturn exitCode;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst request: MigrationRequest = {\n\t\t\t\taction: \"check\",\n\t\t\t\ti18n: manifest.i18n,\n\t\t\t\tartifact: {\n\t\t\t\t\temdashVersion: manifest.emdashVersion,\n\t\t\t\t\tmigrationSetFingerprint: manifest.migrationSet.fingerprint,\n\t\t\t\t},\n\t\t\t};\n\t\t\tif (applying) request.action = \"apply\";\n\t\t\tif (releasing) {\n\t\t\t\trequest.action = \"release-lock\";\n\t\t\t\trequest.lockId = options.releaseLock;\n\t\t\t}\n\t\t\tconst rawReport = await Promise.race([executor.execute(request), interruption]);\n\t\t\tif (rawReport === interruptedResult || interrupted) {\n\t\t\t\texitCode = MIGRATE_EXIT_CODES.interrupted;\n\t\t\t\treturn exitCode;\n\t\t\t}\n\t\t\tconst report = safeReport(rawReport, target);\n\t\t\tif (options.json) {\n\t\t\t\tdependencies.writeStdout(JSON.stringify(report));\n\t\t\t} else {\n\t\t\t\tif (releasing) dependencies.writeStdout(`Released migration lock ${options.releaseLock}.`);\n\t\t\t\tprintHumanReport(report, dependencies.writeStdout);\n\t\t\t}\n\t\t\texitCode = reportExitCode(options, report);\n\t\t\treturn exitCode;\n\t\t} catch (error) {\n\t\t\tprimaryFailure = true;\n\t\t\tdependencies.writeStderr(safeCommandMessage(error, dependencies.env));\n\t\t\texitCode = interrupted ? MIGRATE_EXIT_CODES.interrupted : MIGRATE_EXIT_CODES.error;\n\t\t\treturn exitCode;\n\t\t}\n\t};\n\n\ttry {\n\t\texitCode = await execute();\n\t} finally {\n\t\tfor (const remove of removeSignalHandlers) remove();\n\t\tif (executor) {\n\t\t\tconst cleanup = await bounded(dispose(), dependencies.cleanupTimeoutMs);\n\t\t\tif (cleanup !== \"complete\" && !primaryFailure && !interrupted) {\n\t\t\t\tdependencies.writeStderr(\"Migration executor cleanup failed.\");\n\t\t\t\texitCode = MIGRATE_EXIT_CODES.error;\n\t\t\t}\n\t\t}\n\t}\n\treturn exitCode;\n}\n\nexport const migrateCommand = defineCommand({\n\tmeta: {\n\t\tname: \"migrate\",\n\t\tdescription: \"Check or apply deployment-managed EmDash migrations\",\n\t},\n\targs: {\n\t\tmanifest: { type: \"string\", description: \"Migration manifest path\" },\n\t\t\"from-config\": { type: \"boolean\", description: \"Build the manifest from Astro config\" },\n\t\tconfig: { type: \"string\", description: \"Astro config path (requires --from-config)\" },\n\t\tcheck: { type: \"boolean\", description: \"Check for pending or unknown migrations\" },\n\t\tstatus: { type: \"boolean\", description: \"Report all migration status sets\" },\n\t\tjson: { type: \"boolean\", description: \"Print the stable JSON report\" },\n\t\t\"expected-target-fingerprint\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Required target fingerprint for noninteractive apply or lock release\",\n\t\t},\n\t\t\"release-lock\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Release the migration lock with the id shown by --status\",\n\t\t},\n\t\tdatabase: { type: \"string\", description: \"Override the SQLite database path\" },\n\t\t\"database-url-env\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Override the database URL environment-variable name\",\n\t\t},\n\t\td1: { type: \"string\", description: \"Override the D1 database UUID or name\" },\n\t\t\"account-id\": { type: \"string\", description: \"Override the Cloudflare account ID\" },\n\t\t\"wrangler-config\": { type: \"string\", description: \"Override the Wrangler config path\" },\n\t\t\"wrangler-env\": { type: \"string\", description: \"Override the Wrangler environment\" },\n\t},\n\tasync run({ args }) {\n\t\tprocess.exitCode = await runMigrateCommand({\n\t\t\tmanifest: args.manifest,\n\t\t\tfromConfig: args[\"from-config\"],\n\t\t\tconfig: args.config,\n\t\t\tcheck: args.check,\n\t\t\tstatus: args.status,\n\t\t\tjson: args.json,\n\t\t\texpectedTargetFingerprint: args[\"expected-target-fingerprint\"],\n\t\t\treleaseLock: args[\"release-lock\"],\n\t\t\tdatabase: args.database,\n\t\t\tdatabaseUrlEnv: args[\"database-url-env\"],\n\t\t\td1: args.d1,\n\t\t\taccountId: args[\"account-id\"],\n\t\t\twranglerConfig: args[\"wrangler-config\"],\n\t\t\twranglerEnv: args[\"wrangler-env\"],\n\t\t});\n\t},\n});\n","/**\n * emdash plugin init\n *\n * Scaffold a new EmDash plugin. Generates the sandboxed-format boilerplate:\n * src/index.ts -- descriptor factory\n * src/sandbox-entry.ts -- definePlugin({ hooks, routes })\n * package.json\n * tsconfig.json\n *\n * Use --format=native (or --native) to generate native-format boilerplate\n * instead (createPlugin + React admin). When neither is passed and stdout\n * is a TTY, the user is prompted to choose.\n *\n */\n\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { resolve, join, basename } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport consola from \"consola\";\n\nimport { fileExists } from \"./bundle-utils.js\";\n\nconst SLUG_RE = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;\nconst SCOPE_RE = /^@[^/]+\\//;\n\ntype PluginFormat = \"standard\" | \"native\";\n\nexport const pluginInitCommand = defineCommand({\n\tmeta: {\n\t\tname: \"init\",\n\t\tdescription: \"Scaffold a new plugin\",\n\t},\n\targs: {\n\t\tdir: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Directory to create the plugin in (default: current directory)\",\n\t\t\tdefault: \".\",\n\t\t},\n\t\tname: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Plugin name/id (e.g. my-plugin or @org/my-plugin)\",\n\t\t},\n\t\tformat: {\n\t\t\ttype: \"string\",\n\t\t\tdescription:\n\t\t\t\t\"Plugin format: sandboxed or native. Prompts when running interactively if not set.\",\n\t\t\tvalueHint: \"sandboxed|native\",\n\t\t},\n\t\tnative: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Shortcut for --format=native\",\n\t\t\tdefault: false,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst targetDir = resolve(args.dir);\n\n\t\tconst format = await resolveFormat(args.format, args.native);\n\t\tif (!format) {\n\t\t\tconsola.info(\"Cancelled\");\n\t\t\treturn;\n\t\t}\n\t\tconst isNative = format === \"native\";\n\n\t\t// Derive plugin name from --name or directory name\n\t\tlet pluginName = args.name || basename(targetDir);\n\t\tif (!pluginName || pluginName === \".\") {\n\t\t\tpluginName = basename(resolve(\".\"));\n\t\t}\n\n\t\t// Strip scope for the slug\n\t\tconst slug = pluginName.replace(SCOPE_RE, \"\");\n\t\tif (!SLUG_RE.test(slug)) {\n\t\t\tconsola.error(\n\t\t\t\t`Invalid plugin name \"${pluginName}\". ` +\n\t\t\t\t\t\"Use lowercase letters, numbers, and hyphens (e.g. my-plugin).\",\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// Check if directory already has files\n\t\tconst srcDir = join(targetDir, \"src\");\n\t\tconst pkgPath = join(targetDir, \"package.json\");\n\t\tif (await fileExists(pkgPath)) {\n\t\t\tconsola.error(`package.json already exists in ${targetDir}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconsola.start(`Scaffolding ${isNative ? \"native\" : \"sandboxed\"} plugin: ${pluginName}`);\n\n\t\tawait mkdir(srcDir, { recursive: true });\n\n\t\tif (isNative) {\n\t\t\tawait scaffoldNative(targetDir, srcDir, pluginName, slug);\n\t\t} else {\n\t\t\tawait scaffoldStandard(targetDir, srcDir, pluginName, slug);\n\t\t}\n\n\t\tconsola.success(`Plugin scaffolded in ${targetDir}`);\n\t\tconsola.info(\"Next steps:\");\n\t\tconst steps: string[] = [];\n\t\tif (args.dir !== \".\") steps.push(`cd ${args.dir}`);\n\t\tsteps.push(\"pnpm install\");\n\t\tsteps.push(\n\t\t\tisNative\n\t\t\t\t? \"Edit src/index.ts to add hooks and routes\"\n\t\t\t\t: \"Edit src/sandbox-entry.ts to add hooks and routes\",\n\t\t);\n\t\tsteps.push(\"pnpm build\");\n\t\tif (!isNative) steps.push(\"emdash plugin validate --dir .\");\n\t\tsteps.forEach((step, i) => consola.info(` ${i + 1}. ${step}`));\n\t},\n});\n\nasync function resolveFormat(\n\tformatArg: string | undefined,\n\tnativeFlag: boolean,\n): Promise<PluginFormat | null> {\n\tif (formatArg) {\n\t\tconst normalized = formatArg.toLowerCase();\n\t\tlet parsed: PluginFormat;\n\t\tif (normalized === \"native\") {\n\t\t\tparsed = \"native\";\n\t\t} else if (normalized === \"sandboxed\" || normalized === \"standard\") {\n\t\t\tparsed = \"standard\";\n\t\t} else {\n\t\t\tconsola.error(`Invalid --format \"${formatArg}\". Use \"sandboxed\" or \"native\".`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tif (nativeFlag && parsed !== \"native\") {\n\t\t\tconsola.error(`Conflicting flags: --native and --format=${formatArg}. Pass only one.`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t\treturn parsed;\n\t}\n\tif (nativeFlag) return \"native\";\n\n\tif (!process.stdout.isTTY) return \"standard\";\n\n\tconst choice = await consola.prompt(\"Which plugin format?\", {\n\t\ttype: \"select\",\n\t\tinitial: \"standard\",\n\t\toptions: [\n\t\t\t{\n\t\t\t\tlabel: \"Sandboxed\",\n\t\t\t\tvalue: \"standard\",\n\t\t\t\thint: \"runs in an isolated sandbox; safe to install from the marketplace\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: \"Native\",\n\t\t\t\tvalue: \"native\",\n\t\t\t\thint: \"full runtime access; install from npm\",\n\t\t\t},\n\t\t],\n\t\tcancel: \"null\",\n\t});\n\tif (choice === null) return null;\n\treturn choice as PluginFormat;\n}\n\nfunction camelCase(slug: string): string {\n\treturn slug\n\t\t.split(\"-\")\n\t\t.map((s, i) => (i === 0 ? s : s[0].toUpperCase() + s.slice(1)))\n\t\t.join(\"\");\n}\n\nfunction pascalCase(slug: string): string {\n\treturn slug\n\t\t.split(\"-\")\n\t\t.map((s) => s[0].toUpperCase() + s.slice(1))\n\t\t.join(\"\");\n}\n\nconst TSCONFIG = {\n\tcompilerOptions: {\n\t\ttarget: \"ES2022\",\n\t\tmodule: \"preserve\",\n\t\tmoduleResolution: \"bundler\",\n\t\tstrict: true,\n\t\tesModuleInterop: true,\n\t\tdeclaration: true,\n\t\toutDir: \"./dist\",\n\t\trootDir: \"./src\",\n\t},\n\tinclude: [\"src/**/*\"],\n\texclude: [\"node_modules\", \"dist\"],\n} as const;\n\nconst TSDOWN_VERSION = \"^0.20.0\";\nconst TYPESCRIPT_VERSION = \"^5.9.0\";\n\n// ── Sandboxed format scaffolding ─────────────────────────────────\n\nasync function scaffoldStandard(\n\ttargetDir: string,\n\tsrcDir: string,\n\tpluginName: string,\n\tslug: string,\n): Promise<void> {\n\tconst fnName = camelCase(slug);\n\n\tawait writeFile(\n\t\tjoin(targetDir, \"package.json\"),\n\t\tJSON.stringify(\n\t\t\t{\n\t\t\t\tname: pluginName,\n\t\t\t\tversion: \"0.1.0\",\n\t\t\t\ttype: \"module\",\n\t\t\t\tmain: \"./dist/index.mjs\",\n\t\t\t\texports: {\n\t\t\t\t\t\".\": {\n\t\t\t\t\t\ttypes: \"./dist/index.d.mts\",\n\t\t\t\t\t\timport: \"./dist/index.mjs\",\n\t\t\t\t\t},\n\t\t\t\t\t\"./sandbox\": {\n\t\t\t\t\t\ttypes: \"./dist/sandbox-entry.d.mts\",\n\t\t\t\t\t\timport: \"./dist/sandbox-entry.mjs\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tfiles: [\"dist\"],\n\t\t\t\tscripts: {\n\t\t\t\t\tbuild: \"tsdown src/index.ts src/sandbox-entry.ts --format esm --dts --clean\",\n\t\t\t\t\tdev: \"tsdown src/index.ts src/sandbox-entry.ts --format esm --dts --watch\",\n\t\t\t\t\ttypecheck: \"tsc --noEmit\",\n\t\t\t\t},\n\t\t\t\tkeywords: [\"emdash\", \"emdash-plugin\"],\n\t\t\t\tlicense: \"MIT\",\n\t\t\t\tpeerDependencies: {\n\t\t\t\t\temdash: \"*\",\n\t\t\t\t},\n\t\t\t\tdevDependencies: {\n\t\t\t\t\temdash: \"*\",\n\t\t\t\t\ttsdown: TSDOWN_VERSION,\n\t\t\t\t\ttypescript: TYPESCRIPT_VERSION,\n\t\t\t\t},\n\t\t\t},\n\t\t\tnull,\n\t\t\t\"\\t\",\n\t\t) + \"\\n\",\n\t);\n\n\tawait writeFile(join(targetDir, \"tsconfig.json\"), JSON.stringify(TSCONFIG, null, \"\\t\") + \"\\n\");\n\n\tawait writeFile(\n\t\tjoin(srcDir, \"index.ts\"),\n\t\t`import type { PluginDescriptor } from \"emdash\";\n\nexport function ${fnName}Plugin(): PluginDescriptor {\n\\treturn {\n\\t\\tid: \"${slug}\",\n\\t\\tversion: \"0.1.0\",\n\\t\\tformat: \"standard\",\n\\t\\tentrypoint: \"${pluginName}/sandbox\",\n\n\\t\\tcapabilities: [\"content:read\"],\n\\t\\tstorage: {\n\\t\\t\\tevents: { indexes: [\"timestamp\"] },\n\\t\\t},\n\\t};\n}\n`,\n\t);\n\n\tawait writeFile(\n\t\tjoin(srcDir, \"sandbox-entry.ts\"),\n\t\t`import { definePlugin } from \"emdash\";\nimport type { PluginContext } from \"emdash\";\n\ninterface ContentSaveEvent {\n\\tcollection: string;\n\\tcontent: { id: string };\n\\tisNew: boolean;\n}\n\nexport default definePlugin({\n\\thooks: {\n\\t\\t\"content:afterSave\": {\n\\t\\t\\thandler: async (event: ContentSaveEvent, ctx: PluginContext) => {\n\\t\\t\\t\\tctx.log.info(\"Content saved\", {\n\\t\\t\\t\\t\\tcollection: event.collection,\n\\t\\t\\t\\t\\tid: event.content.id,\n\\t\\t\\t\\t});\n\n\\t\\t\\t\\tawait ctx.storage.events.put(\\`save-\\${Date.now()}\\`, {\n\\t\\t\\t\\t\\ttimestamp: new Date().toISOString(),\n\\t\\t\\t\\t\\tcollection: event.collection,\n\\t\\t\\t\\t\\tcontentId: event.content.id,\n\\t\\t\\t\\t});\n\\t\\t\\t},\n\\t\\t},\n\\t},\n\n\\troutes: {\n\\t\\trecent: {\n\\t\\t\\thandler: async (_routeCtx, ctx: PluginContext) => {\n\\t\\t\\t\\tconst result = await ctx.storage.events.query({\n\\t\\t\\t\\t\\torderBy: { timestamp: \"desc\" },\n\\t\\t\\t\\t\\tlimit: 10,\n\\t\\t\\t\\t});\n\\t\\t\\t\\treturn { events: result.items };\n\\t\\t\\t},\n\\t\\t},\n\\t},\n});\n`,\n\t);\n}\n\n// ── Native format scaffolding ────────────────────────────────────\n\nasync function scaffoldNative(\n\ttargetDir: string,\n\tsrcDir: string,\n\tpluginName: string,\n\tslug: string,\n): Promise<void> {\n\tconst fnName = camelCase(slug);\n\tconst typeName = pascalCase(slug);\n\n\tawait writeFile(\n\t\tjoin(targetDir, \"package.json\"),\n\t\tJSON.stringify(\n\t\t\t{\n\t\t\t\tname: pluginName,\n\t\t\t\tversion: \"0.1.0\",\n\t\t\t\ttype: \"module\",\n\t\t\t\tmain: \"./dist/index.mjs\",\n\t\t\t\texports: {\n\t\t\t\t\t\".\": {\n\t\t\t\t\t\ttypes: \"./dist/index.d.mts\",\n\t\t\t\t\t\timport: \"./dist/index.mjs\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tfiles: [\"dist\"],\n\t\t\t\tscripts: {\n\t\t\t\t\tbuild: \"tsdown src/index.ts --format esm --dts --clean\",\n\t\t\t\t\tdev: \"tsdown src/index.ts --format esm --dts --watch\",\n\t\t\t\t\ttypecheck: \"tsc --noEmit\",\n\t\t\t\t},\n\t\t\t\tkeywords: [\"emdash\", \"emdash-plugin\"],\n\t\t\t\tlicense: \"MIT\",\n\t\t\t\tpeerDependencies: {\n\t\t\t\t\temdash: \"*\",\n\t\t\t\t},\n\t\t\t\tdevDependencies: {\n\t\t\t\t\temdash: \"*\",\n\t\t\t\t\ttsdown: TSDOWN_VERSION,\n\t\t\t\t\ttypescript: TYPESCRIPT_VERSION,\n\t\t\t\t},\n\t\t\t},\n\t\t\tnull,\n\t\t\t\"\\t\",\n\t\t) + \"\\n\",\n\t);\n\n\tawait writeFile(join(targetDir, \"tsconfig.json\"), JSON.stringify(TSCONFIG, null, \"\\t\") + \"\\n\");\n\n\tawait writeFile(\n\t\tjoin(srcDir, \"index.ts\"),\n\t\t`import { definePlugin } from \"emdash\";\nimport type { PluginDescriptor } from \"emdash\";\n\nexport interface ${typeName}Options {\n\\tenabled?: boolean;\n}\n\nexport function ${fnName}Plugin(options: ${typeName}Options = {}): PluginDescriptor<${typeName}Options> {\n\\treturn {\n\\t\\tid: \"${slug}\",\n\\t\\tversion: \"0.1.0\",\n\\t\\tformat: \"native\",\n\\t\\tentrypoint: \"${pluginName}\",\n\\t\\toptions,\n\\t};\n}\n\nexport function createPlugin(options: ${typeName}Options = {}) {\n\\treturn definePlugin({\n\\t\\tid: \"${slug}\",\n\\t\\tversion: \"0.1.0\",\n\n\\t\\tcapabilities: [\"content:read\"],\n\\t\\tstorage: {\n\\t\\t\\tevents: { indexes: [\"createdAt\"] },\n\\t\\t},\n\n\\t\\thooks: {\n\\t\\t\\t\"content:afterSave\": async (event, ctx) => {\n\\t\\t\\t\\tif (options.enabled === false) return;\n\\t\\t\\t\\tawait ctx.storage.events.put(\\`evt_\\${Date.now()}\\`, {\n\\t\\t\\t\\t\\tcollection: event.collection,\n\\t\\t\\t\\t\\tcontentId: event.content.id,\n\\t\\t\\t\\t\\tcreatedAt: new Date().toISOString(),\n\\t\\t\\t\\t});\n\\t\\t\\t},\n\\t\\t},\n\n\\t\\troutes: {\n\\t\\t\\trecent: {\n\\t\\t\\t\\thandler: async (ctx) => {\n\\t\\t\\t\\t\\tconst result = await ctx.storage.events.query({\n\\t\\t\\t\\t\\t\\torderBy: { createdAt: \"desc\" },\n\\t\\t\\t\\t\\t\\tlimit: 10,\n\\t\\t\\t\\t\\t});\n\\t\\t\\t\\t\\treturn { events: result.items };\n\\t\\t\\t\\t},\n\\t\\t\\t},\n\\t\\t},\n\\t});\n}\n\nexport default createPlugin;\n`,\n\t);\n}\n","/**\n * emdash plugin validate\n *\n * Runs bundle validation without producing a tarball.\n * Thin wrapper around `emdash plugin bundle --validate-only`.\n *\n */\n\nimport { defineCommand, runCommand } from \"citty\";\n\nimport { bundleCommand } from \"./bundle.js\";\n\nexport const pluginValidateCommand = defineCommand({\n\tmeta: {\n\t\tname: \"validate\",\n\t\tdescription: \"Validate a plugin without producing a tarball (same checks as bundle)\",\n\t},\n\targs: {\n\t\tdir: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Plugin directory (default: current directory)\",\n\t\t\tdefault: \".\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\t// Delegate to the bundle command with validateOnly flag\n\t\tawait runCommand(bundleCommand, {\n\t\t\trawArgs: [\"--dir\", args.dir, \"--validateOnly\"],\n\t\t});\n\t},\n});\n","/**\n * emdash plugin publish\n *\n * Publishes a plugin tarball to the EmDash Marketplace.\n *\n * Flow:\n * 1. Resolve tarball (from --tarball path, or build via `emdash plugin bundle`)\n * 2. Read manifest.json from tarball to show summary\n * 3. Authenticate (stored credential or GitHub device flow)\n * 4. Pre-publish validation (check plugin exists, version not published)\n * 5. Upload via multipart POST\n * 6. Display audit results\n */\n\nimport { readFile, stat } from \"node:fs/promises\";\nimport { resolve, basename } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport consola from \"consola\";\nimport { createGzipDecoder, unpackTar } from \"modern-tar\";\nimport pc from \"picocolors\";\n\nimport { pluginManifestBaseSchema } from \"../../plugins/manifest-schema.js\";\nimport { CAPABILITY_RENAMES, isDeprecatedCapability } from \"../../plugins/types.js\";\nimport {\n\tgetMarketplaceCredential,\n\tsaveMarketplaceCredential,\n\tremoveMarketplaceCredential,\n} from \"../credentials.js\";\n\nconst DEFAULT_REGISTRY = \"https://marketplace.emdashcms.com\";\n\n// ── GitHub Device Flow ──────────────────────────────────────────\n\ninterface DeviceCodeResponse {\n\tdevice_code: string;\n\tuser_code: string;\n\tverification_uri: string;\n\texpires_in: number;\n\tinterval: number;\n}\n\ninterface GitHubTokenResponse {\n\taccess_token?: string;\n\ttoken_type?: string;\n\terror?: string;\n\terror_description?: string;\n\tinterval?: number;\n}\n\ninterface MarketplaceAuthResponse {\n\ttoken: string;\n\tauthor: {\n\t\tid: string;\n\t\tname: string;\n\t\tavatarUrl: string;\n\t};\n}\n\ninterface AuthDiscovery {\n\tgithub: {\n\t\tclientId: string;\n\t\tdeviceAuthorizationEndpoint: string;\n\t\ttokenEndpoint: string;\n\t};\n\tmarketplace: {\n\t\tdeviceTokenEndpoint: string;\n\t};\n}\n\n/**\n * Authenticate with the marketplace via GitHub Device Flow.\n * Returns the marketplace JWT and author info.\n */\nasync function authenticateViaDeviceFlow(registryUrl: string): Promise<MarketplaceAuthResponse> {\n\t// Step 1: Fetch auth discovery to get GitHub client_id\n\tconsola.start(\"Fetching auth configuration...\");\n\tconst discoveryRes = await fetch(new URL(\"/api/v1/auth/discovery\", registryUrl));\n\tif (!discoveryRes.ok) {\n\t\tthrow new Error(`Marketplace unreachable: ${discoveryRes.status} ${discoveryRes.statusText}`);\n\t}\n\tconst discovery = (await discoveryRes.json()) as AuthDiscovery;\n\n\t// Step 2: Request device code from GitHub\n\tconst deviceRes = await fetch(discovery.github.deviceAuthorizationEndpoint, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAccept: \"application/json\",\n\t\t},\n\t\tbody: JSON.stringify({\n\t\t\tclient_id: discovery.github.clientId,\n\t\t\tscope: \"read:user user:email\",\n\t\t}),\n\t});\n\n\tif (!deviceRes.ok) {\n\t\tthrow new Error(`GitHub device flow failed: ${deviceRes.status}`);\n\t}\n\n\tconst deviceCode = (await deviceRes.json()) as DeviceCodeResponse;\n\n\t// Step 3: Display instructions\n\tconsole.log();\n\tconsola.info(\"Open your browser to:\");\n\tconsole.log(` ${pc.cyan(pc.bold(deviceCode.verification_uri))}`);\n\tconsole.log();\n\tconsola.info(`Enter code: ${pc.yellow(pc.bold(deviceCode.user_code))}`);\n\tconsole.log();\n\n\t// Try to open browser\n\ttry {\n\t\tconst { execFile } = await import(\"node:child_process\");\n\t\tif (process.platform === \"darwin\") {\n\t\t\texecFile(\"open\", [deviceCode.verification_uri]);\n\t\t} else if (process.platform === \"win32\") {\n\t\t\texecFile(\"cmd\", [\"/c\", \"start\", \"\", deviceCode.verification_uri]);\n\t\t} else {\n\t\t\texecFile(\"xdg-open\", [deviceCode.verification_uri]);\n\t\t}\n\t} catch {\n\t\t// User can open manually\n\t}\n\n\t// Step 4: Poll GitHub for access token\n\tconsola.start(\"Waiting for authorization...\");\n\tconst githubToken = await pollGitHubDeviceFlow(\n\t\tdiscovery.github.tokenEndpoint,\n\t\tdiscovery.github.clientId,\n\t\tdeviceCode.device_code,\n\t\tdeviceCode.interval,\n\t\tdeviceCode.expires_in,\n\t);\n\n\t// Step 5: Exchange GitHub token for marketplace JWT\n\tconsola.start(\"Authenticating with marketplace...\");\n\tconst deviceTokenUrl = new URL(discovery.marketplace.deviceTokenEndpoint, registryUrl);\n\tconst authRes = await fetch(deviceTokenUrl, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\tbody: JSON.stringify({ access_token: githubToken }),\n\t});\n\n\tif (!authRes.ok) {\n\t\tconst body = (await authRes.json().catch(() => ({}))) as { error?: string };\n\t\tthrow new Error(`Marketplace auth failed: ${body.error ?? authRes.statusText}`);\n\t}\n\n\treturn (await authRes.json()) as MarketplaceAuthResponse;\n}\n\nasync function pollGitHubDeviceFlow(\n\ttokenEndpoint: string,\n\tclientId: string,\n\tdeviceCode: string,\n\tinterval: number,\n\texpiresIn: number,\n): Promise<string> {\n\tconst deadline = Date.now() + expiresIn * 1000;\n\tlet currentInterval = interval;\n\n\twhile (Date.now() < deadline) {\n\t\tawait new Promise((r) => setTimeout(r, currentInterval * 1000));\n\n\t\tconst res = await fetch(tokenEndpoint, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\tAccept: \"application/json\",\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\tclient_id: clientId,\n\t\t\t\tdevice_code: deviceCode,\n\t\t\t\tgrant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n\t\t\t}),\n\t\t});\n\n\t\tconst body = (await res.json()) as GitHubTokenResponse;\n\n\t\tif (body.access_token) {\n\t\t\treturn body.access_token;\n\t\t}\n\n\t\tif (body.error === \"authorization_pending\") continue;\n\t\tif (body.error === \"slow_down\") {\n\t\t\tcurrentInterval = body.interval ?? currentInterval + 5;\n\t\t\tcontinue;\n\t\t}\n\t\tif (body.error === \"expired_token\") {\n\t\t\tthrow new Error(\"Device code expired. Please try again.\");\n\t\t}\n\t\tif (body.error === \"access_denied\") {\n\t\t\tthrow new Error(\"Authorization was denied.\");\n\t\t}\n\n\t\tthrow new Error(`GitHub token exchange failed: ${body.error ?? \"unknown error\"}`);\n\t}\n\n\tthrow new Error(\"Device code expired (timeout). Please try again.\");\n}\n\n// ── Tarball reading ─────────────────────────────────────────────\n\nconst manifestSummarySchema = pluginManifestBaseSchema.pick({\n\tid: true,\n\tversion: true,\n\tcapabilities: true,\n\tallowedHosts: true,\n});\n\ntype ManifestSummary = typeof manifestSummarySchema._zod.output;\n\n/**\n * Read manifest.json from a tarball without fully extracting it.\n */\nasync function readManifestFromTarball(tarballPath: string): Promise<ManifestSummary> {\n\tconst data = await readFile(tarballPath);\n\tconst stream = new ReadableStream<Uint8Array>({\n\t\tstart(controller) {\n\t\t\tcontroller.enqueue(new Uint8Array(data.buffer, data.byteOffset, data.byteLength));\n\t\t\tcontroller.close();\n\t\t},\n\t});\n\n\tconst entries = await unpackTar(stream.pipeThrough(createGzipDecoder()), {\n\t\tfilter: (header) => header.name === \"manifest.json\",\n\t});\n\n\tconst manifest = entries.find((e) => e.header.name === \"manifest.json\");\n\tif (!manifest?.data) {\n\t\tthrow new Error(\"Tarball does not contain manifest.json\");\n\t}\n\n\tconst content = new TextDecoder().decode(manifest.data);\n\tconst parsed: unknown = JSON.parse(content);\n\tconst result = manifestSummarySchema.safeParse(parsed);\n\tif (!result.success) {\n\t\tthrow new Error(`Invalid manifest.json: ${result.error.message}`);\n\t}\n\treturn result.data;\n}\n\n// ── Audit polling helpers ───────────────────────────────────────\n\nconst POLL_INTERVAL_MS = 3000;\nconst POLL_TIMEOUT_MS = 120_000; // 2 minutes\n\ninterface VersionStatusResponse {\n\tversion: string;\n\tstatus: string;\n\taudit_verdict?: string | null;\n\taudit_id?: string | null;\n\timage_audit_verdict?: string | null;\n}\n\n/**\n * Poll the version endpoint until status leaves \"pending\" or timeout.\n * Returns the final version data, or null on timeout.\n */\nasync function pollVersionStatus(\n\tversionUrl: string,\n\ttoken: string,\n): Promise<VersionStatusResponse | null> {\n\tconst deadline = Date.now() + POLL_TIMEOUT_MS;\n\n\twhile (Date.now() < deadline) {\n\t\tawait new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));\n\n\t\ttry {\n\t\t\tconst res = await fetch(versionUrl, {\n\t\t\t\theaders: { Authorization: `Bearer ${token}` },\n\t\t\t});\n\n\t\t\tif (!res.ok) continue;\n\n\t\t\tconst data = (await res.json()) as VersionStatusResponse;\n\t\t\tif (data.status !== \"pending\") {\n\t\t\t\treturn data;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Network error — retry\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction displayAuditResults(version: VersionStatusResponse): void {\n\tconst statusColor =\n\t\tversion.status === \"published\" ? pc.green : version.status === \"flagged\" ? pc.yellow : pc.red;\n\tconsola.info(` Status: ${statusColor(version.status)}`);\n\n\tif (version.audit_verdict) {\n\t\tconst verdictColor =\n\t\t\tversion.audit_verdict === \"pass\"\n\t\t\t\t? pc.green\n\t\t\t\t: version.audit_verdict === \"warn\"\n\t\t\t\t\t? pc.yellow\n\t\t\t\t\t: pc.red;\n\t\tconsola.info(` Audit: ${verdictColor(version.audit_verdict)}`);\n\t}\n\n\tif (version.image_audit_verdict) {\n\t\tconst verdictColor =\n\t\t\tversion.image_audit_verdict === \"pass\"\n\t\t\t\t? pc.green\n\t\t\t\t: version.image_audit_verdict === \"warn\"\n\t\t\t\t\t? pc.yellow\n\t\t\t\t\t: pc.red;\n\t\tconsola.info(` Image audit: ${verdictColor(version.image_audit_verdict)}`);\n\t}\n}\n\nfunction displayInlineAuditResults(\n\taudit: {\n\t\tverdict: string;\n\t\triskScore: number;\n\t\tsummary: string;\n\t\tfindings: { category: string; severity: string; description: string }[];\n\t},\n\timageAudit: { verdict: string } | null,\n): void {\n\tconst verdictColor =\n\t\taudit.verdict === \"pass\" ? pc.green : audit.verdict === \"warn\" ? pc.yellow : pc.red;\n\tconsola.info(` Audit: ${verdictColor(audit.verdict)} (risk: ${audit.riskScore}/100)`);\n\tif (audit.findings.length > 0) {\n\t\tfor (const finding of audit.findings) {\n\t\t\tconst icon = finding.severity === \"high\" ? pc.red(\"!\") : pc.yellow(\"~\");\n\t\t\tconsola.info(` ${icon} [${finding.category}] ${finding.description}`);\n\t\t}\n\t}\n\n\tif (imageAudit) {\n\t\tconst imgColor =\n\t\t\timageAudit.verdict === \"pass\" ? pc.green : imageAudit.verdict === \"warn\" ? pc.yellow : pc.red;\n\t\tconsola.info(` Image audit: ${imgColor(imageAudit.verdict)}`);\n\t}\n}\n\n// ── Publish command ─────────────────────────────────────────────\n\nexport const publishCommand = defineCommand({\n\tmeta: {\n\t\tname: \"publish\",\n\t\tdescription: \"Publish a plugin to the EmDash Marketplace\",\n\t},\n\targs: {\n\t\ttarball: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Path to plugin tarball (default: build first via `emdash plugin bundle`)\",\n\t\t},\n\t\tdir: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Plugin directory (used with --build, default: current directory)\",\n\t\t\tdefault: process.cwd(),\n\t\t},\n\t\tbuild: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Build the plugin before publishing\",\n\t\t\tdefault: false,\n\t\t},\n\t\tregistry: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Marketplace registry URL\",\n\t\t\tdefault: DEFAULT_REGISTRY,\n\t\t},\n\t\t\"no-wait\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Exit immediately after upload without waiting for audit (useful for CI)\",\n\t\t\tdefault: false,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst registryUrl = args.registry;\n\n\t\t// ── Step 1: Resolve tarball ──\n\n\t\tlet tarballPath: string;\n\n\t\tif (args.tarball) {\n\t\t\ttarballPath = resolve(args.tarball);\n\t\t} else if (args.build) {\n\t\t\t// Build first, then find the output tarball\n\t\t\tconsola.start(\"Building plugin...\");\n\t\t\tconst pluginDir = resolve(args.dir);\n\t\t\ttry {\n\t\t\t\tconst { runCommand } = await import(\"citty\");\n\t\t\t\tconst { bundleCommand } = await import(\"./bundle.js\");\n\t\t\t\tawait runCommand(bundleCommand, {\n\t\t\t\t\trawArgs: [\"--dir\", pluginDir],\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\tconsola.error(\"Build failed\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Find the tarball in dist/\n\t\t\tconst { readdir } = await import(\"node:fs/promises\");\n\t\t\tconst distDir = resolve(pluginDir, \"dist\");\n\t\t\tconst files = await readdir(distDir);\n\t\t\tconst tarball = files.find((f) => f.endsWith(\".tar.gz\"));\n\t\t\tif (!tarball) {\n\t\t\t\tconsola.error(\"Build succeeded but no .tar.gz found in dist/\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\ttarballPath = resolve(distDir, tarball);\n\t\t} else {\n\t\t\t// Look for an existing tarball in dist/\n\t\t\tconst pluginDir = resolve(args.dir);\n\t\t\tconst { readdir } = await import(\"node:fs/promises\");\n\t\t\ttry {\n\t\t\t\tconst distDir = resolve(pluginDir, \"dist\");\n\t\t\t\tconst files = await readdir(distDir);\n\t\t\t\tconst tarball = files.find((f) => f.endsWith(\".tar.gz\"));\n\t\t\t\tif (tarball) {\n\t\t\t\t\ttarballPath = resolve(distDir, tarball);\n\t\t\t\t} else {\n\t\t\t\t\tconsola.error(\"No tarball found. Run `emdash plugin bundle` first or use --build.\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\tconsola.error(\"No dist/ directory found. Run `emdash plugin bundle` first or use --build.\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t}\n\n\t\tconst tarballStat = await stat(tarballPath);\n\t\tconst sizeKB = (tarballStat.size / 1024).toFixed(1);\n\t\tconsola.info(`Tarball: ${pc.dim(tarballPath)} (${sizeKB}KB)`);\n\n\t\t// ── Step 2: Read manifest from tarball ──\n\n\t\tconst manifest = await readManifestFromTarball(tarballPath);\n\t\tconsole.log();\n\t\tconsola.info(`Plugin: ${pc.bold(`${manifest.id}@${manifest.version}`)}`);\n\t\tif (manifest.capabilities.length > 0) {\n\t\t\tconsola.info(`Capabilities: ${manifest.capabilities.join(\", \")}`);\n\t\t}\n\t\tif (manifest.allowedHosts?.length) {\n\t\t\tconsola.info(`Allowed hosts: ${manifest.allowedHosts.join(\", \")}`);\n\t\t}\n\t\tconsole.log();\n\n\t\t// ── Step 2.5: Hard-fail on deprecated capability names ──\n\t\t//\n\t\t// Refusing to publish manifests that use deprecated capability names\n\t\t// keeps the marketplace clean while the deprecation window is open.\n\t\t// The fix is mechanical and entirely in the author's hands — they\n\t\t// rename, re-bundle, and republish. Better to refuse 5 publishes\n\t\t// than ship 500 deprecated manifests. We check before authentication\n\t\t// so authors don't burn a device-flow login on a doomed publish.\n\t\tconst deprecatedCaps = manifest.capabilities.filter(isDeprecatedCapability);\n\t\tif (deprecatedCaps.length > 0) {\n\t\t\tconsola.error(\n\t\t\t\t\"Plugin declares deprecated capability names. Rename them and re-bundle before publishing:\",\n\t\t\t);\n\t\t\tfor (const cap of deprecatedCaps) {\n\t\t\t\tconst replacement = CAPABILITY_RENAMES[cap];\n\t\t\t\tconsola.error(` ${cap} → ${replacement}`);\n\t\t\t}\n\t\t\tconsola.error(\n\t\t\t\t\"See https://emdashcms.com/docs/plugins/overview#capabilities for the full rename table.\",\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// ── Step 3: Authenticate ──\n\t\t//\n\t\t// Priority: EMDASH_MARKETPLACE_TOKEN env var > stored credential > interactive device flow.\n\t\t// The env var enables CI pipelines (including seed token auth) without interactive login.\n\n\t\tlet token: string;\n\t\tconst envToken = process.env.EMDASH_MARKETPLACE_TOKEN;\n\t\tconst stored = !envToken ? getMarketplaceCredential(registryUrl) : null;\n\n\t\tif (envToken) {\n\t\t\ttoken = envToken;\n\t\t\tconsola.info(\"Using EMDASH_MARKETPLACE_TOKEN for authentication\");\n\t\t} else if (stored) {\n\t\t\ttoken = stored.token;\n\t\t\tconsola.info(`Authenticated as ${pc.bold(stored.author?.name ?? \"unknown\")}`);\n\t\t} else {\n\t\t\tconsola.info(\"Not logged in to marketplace. Starting GitHub authentication...\");\n\t\t\tconst result = await authenticateViaDeviceFlow(registryUrl);\n\t\t\ttoken = result.token;\n\n\t\t\t// Save for next time\n\t\t\tsaveMarketplaceCredential(registryUrl, {\n\t\t\t\ttoken: result.token,\n\t\t\t\texpiresAt: new Date(Date.now() + 30 * 86400 * 1000).toISOString(), // 30 days\n\t\t\t\tauthor: { id: result.author.id, name: result.author.name },\n\t\t\t});\n\n\t\t\tconsola.success(`Authenticated as ${pc.bold(result.author.name)}`);\n\t\t}\n\n\t\t// ── Step 4: Pre-publish validation ──\n\n\t\tconsola.start(\"Checking marketplace...\");\n\n\t\t// Check if plugin exists\n\t\tconst pluginRes = await fetch(new URL(`/api/v1/plugins/${manifest.id}`, registryUrl));\n\n\t\tif (pluginRes.status === 404 && !envToken) {\n\t\t\t// Plugin doesn't exist — register it first.\n\t\t\t// When using env token (seed), the server auto-registers on publish.\n\t\t\tconsola.info(`Plugin ${pc.bold(manifest.id)} not found in marketplace. Registering...`);\n\n\t\t\tconst createRes = await fetch(new URL(\"/api/v1/plugins\", registryUrl), {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tid: manifest.id,\n\t\t\t\t\tname: manifest.id, // Use ID as name initially\n\t\t\t\t\tcapabilities: manifest.capabilities,\n\t\t\t\t}),\n\t\t\t});\n\n\t\t\tif (!createRes.ok) {\n\t\t\t\tconst body = (await createRes.json().catch(() => ({}))) as { error?: string };\n\t\t\t\tif (createRes.status === 401) {\n\t\t\t\t\t// Token expired — clear and retry\n\t\t\t\t\tremoveMarketplaceCredential(registryUrl);\n\t\t\t\t\tconsola.error(\n\t\t\t\t\t\t\"Authentication expired. Please run `emdash plugin publish` again to re-authenticate.\",\n\t\t\t\t\t);\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconsola.error(`Failed to register plugin: ${body.error ?? createRes.statusText}`);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconsola.success(`Registered ${pc.bold(manifest.id)}`);\n\t\t} else if (pluginRes.status === 404 && envToken) {\n\t\t\t// Using env token — server handles auto-registration on publish\n\t\t\tconsola.info(`Plugin ${pc.bold(manifest.id)} will be auto-registered on publish`);\n\t\t} else if (!pluginRes.ok) {\n\t\t\tconsola.error(`Marketplace error: ${pluginRes.status}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// ── Step 5: Upload ──\n\n\t\tconsola.start(`Publishing ${manifest.id}@${manifest.version}...`);\n\n\t\tconst tarballData = await readFile(tarballPath);\n\t\tconst formData = new FormData();\n\t\tformData.append(\n\t\t\t\"bundle\",\n\t\t\tnew Blob([tarballData], { type: \"application/gzip\" }),\n\t\t\tbasename(tarballPath),\n\t\t);\n\n\t\tconst uploadUrl = new URL(`/api/v1/plugins/${manifest.id}/versions`, registryUrl);\n\t\tconst uploadRes = await fetch(uploadUrl, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t},\n\t\t\tbody: formData,\n\t\t});\n\n\t\tif (!uploadRes.ok && uploadRes.status !== 202) {\n\t\t\tconst body = (await uploadRes.json().catch(() => ({}))) as {\n\t\t\t\terror?: string;\n\t\t\t\tlatestVersion?: string;\n\t\t\t\taudit?: { verdict: string; summary: string; findings: unknown[] };\n\t\t\t};\n\n\t\t\tif (uploadRes.status === 401) {\n\t\t\t\tif (envToken) {\n\t\t\t\t\tconsola.error(\"EMDASH_MARKETPLACE_TOKEN was rejected by the marketplace.\");\n\t\t\t\t} else {\n\t\t\t\t\tremoveMarketplaceCredential(registryUrl);\n\t\t\t\t\tconsola.error(\"Authentication expired. Please run `emdash plugin publish` again.\");\n\t\t\t\t}\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tif (uploadRes.status === 409) {\n\t\t\t\tif (body.latestVersion) {\n\t\t\t\t\tconsola.error(`Version ${manifest.version} must be greater than ${body.latestVersion}`);\n\t\t\t\t} else {\n\t\t\t\t\tconsola.error(body.error ?? \"Version conflict\");\n\t\t\t\t}\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tif (uploadRes.status === 422 && body.audit) {\n\t\t\t\t// Failed security audit\n\t\t\t\tconsola.error(\"Plugin failed security audit:\");\n\t\t\t\tconsola.error(` Verdict: ${pc.red(body.audit.verdict)}`);\n\t\t\t\tconsola.error(` Summary: ${body.audit.summary}`);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconsola.error(`Publish failed: ${body.error ?? uploadRes.statusText}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// ── Step 6: Handle response ──\n\n\t\tconst result = (await uploadRes.json()) as {\n\t\t\tversion: string;\n\t\t\tbundleSize: number;\n\t\t\tchecksum: string;\n\t\t\tpublishedAt: string;\n\t\t\tstatus?: string;\n\t\t\tworkflowId?: string;\n\t\t\taudit?: {\n\t\t\t\tverdict: string;\n\t\t\t\triskScore: number;\n\t\t\t\tsummary: string;\n\t\t\t\tfindings: { category: string; severity: string; description: string }[];\n\t\t\t};\n\t\t\timageAudit?: {\n\t\t\t\tverdict: string;\n\t\t\t} | null;\n\t\t};\n\n\t\tconsole.log();\n\t\tconsola.success(`Uploaded ${pc.bold(`${manifest.id}@${result.version}`)}`);\n\t\tconsola.info(` Checksum: ${pc.dim(result.checksum)}`);\n\t\tconsola.info(` Size: ${(result.bundleSize / 1024).toFixed(1)}KB`);\n\n\t\t// Async audit flow (202 Accepted)\n\t\tif (uploadRes.status === 202) {\n\t\t\tconsola.info(` Status: ${pc.yellow(\"pending\")} (audit running in background)`);\n\n\t\t\tif (args[\"no-wait\"]) {\n\t\t\t\tconsola.info(\"Skipping audit wait (--no-wait). Check status later.\");\n\t\t\t\tconsole.log();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Poll version endpoint for audit completion\n\t\t\tconsola.start(\"Waiting for security audit to complete...\");\n\t\t\tconst versionUrl = new URL(\n\t\t\t\t`/api/v1/plugins/${manifest.id}/versions/${manifest.version}`,\n\t\t\t\tregistryUrl,\n\t\t\t);\n\t\t\tconst finalStatus = await pollVersionStatus(versionUrl.toString(), token);\n\n\t\t\tif (finalStatus) {\n\t\t\t\tdisplayAuditResults(finalStatus);\n\t\t\t} else {\n\t\t\t\tconsola.warn(\"Audit did not complete within timeout. Check status later with:\");\n\t\t\t\tconsola.info(` ${pc.dim(`curl ${versionUrl.toString()}`)}`);\n\t\t\t}\n\t\t} else {\n\t\t\t// Synchronous response (201 or legacy)\n\t\t\tif (result.audit) {\n\t\t\t\tdisplayInlineAuditResults(result.audit, result.imageAudit ?? null);\n\t\t\t}\n\t\t\tconsola.info(` Status: ${pc.green(result.status ?? \"published\")}`);\n\t\t}\n\n\t\tconsole.log();\n\t},\n});\n\n// ── Marketplace auth subcommands ────────────────────────────────\n\nexport const marketplaceLoginCommand = defineCommand({\n\tmeta: {\n\t\tname: \"login\",\n\t\tdescription: \"Log in to the EmDash Marketplace via GitHub\",\n\t},\n\targs: {\n\t\tregistry: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Marketplace registry URL\",\n\t\t\tdefault: DEFAULT_REGISTRY,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst registryUrl = args.registry;\n\n\t\tconst existing = getMarketplaceCredential(registryUrl);\n\t\tif (existing) {\n\t\t\tconsola.info(`Already logged in as ${pc.bold(existing.author?.name ?? \"unknown\")}`);\n\t\t\tconsola.info(\"Use `emdash plugin logout` to log out first.\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst result = await authenticateViaDeviceFlow(registryUrl);\n\n\t\tsaveMarketplaceCredential(registryUrl, {\n\t\t\ttoken: result.token,\n\t\t\texpiresAt: new Date(Date.now() + 30 * 86400 * 1000).toISOString(),\n\t\t\tauthor: { id: result.author.id, name: result.author.name },\n\t\t});\n\n\t\tconsola.success(`Logged in as ${pc.bold(result.author.name)}`);\n\t},\n});\n\nexport const marketplaceLogoutCommand = defineCommand({\n\tmeta: {\n\t\tname: \"logout\",\n\t\tdescription: \"Log out of the EmDash Marketplace\",\n\t},\n\targs: {\n\t\tregistry: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Marketplace registry URL\",\n\t\t\tdefault: DEFAULT_REGISTRY,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst removed = removeMarketplaceCredential(args.registry);\n\t\tif (removed) {\n\t\t\tconsola.success(\"Logged out of marketplace.\");\n\t\t} else {\n\t\t\tconsola.info(\"No marketplace credentials found.\");\n\t\t}\n\t},\n});\n","/**\n * emdash plugin\n *\n * Plugin management commands grouped under a single namespace.\n *\n * Subcommands:\n * - init: Scaffold a new plugin\n * - bundle: Bundle a plugin for marketplace distribution\n * - validate: Run bundle validation without producing a tarball\n * - publish: Publish a plugin to the marketplace\n * - login: Log in to the marketplace via GitHub\n * - logout: Log out of the marketplace\n *\n */\n\nimport { defineCommand } from \"citty\";\n\nimport { bundleCommand } from \"./bundle.js\";\nimport { pluginInitCommand } from \"./plugin-init.js\";\nimport { pluginValidateCommand } from \"./plugin-validate.js\";\nimport { publishCommand, marketplaceLoginCommand, marketplaceLogoutCommand } from \"./publish.js\";\n\nexport const pluginCommand = defineCommand({\n\tmeta: { name: \"plugin\", description: \"Manage plugins\" },\n\tsubCommands: {\n\t\tinit: pluginInitCommand,\n\t\tbundle: bundleCommand,\n\t\tvalidate: pluginValidateCommand,\n\t\tpublish: publishCommand,\n\t\tlogin: marketplaceLoginCommand,\n\t\tlogout: marketplaceLogoutCommand,\n\t},\n});\n","/**\n * emdash schema\n *\n * Manage collections and fields via the remote API\n */\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\n\nimport { connectionArgs as commonArgs, createClientFromArgs } from \"../client-factory.js\";\nimport { configureOutputMode, output } from \"../output.js\";\n\nconst listCommand = defineCommand({\n\tmeta: {\n\t\tname: \"list\",\n\t\tdescription: \"List all collections\",\n\t},\n\targs: {\n\t\t...commonArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst collections = await client.collections();\n\t\t\toutput(collections, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst getCommand = defineCommand({\n\tmeta: {\n\t\tname: \"get\",\n\t\tdescription: \"Get collection with fields\",\n\t},\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\t...commonArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst collection = await client.collection(args.collection);\n\t\t\toutput(collection, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst createCommand = defineCommand({\n\tmeta: {\n\t\tname: \"create\",\n\t\tdescription: \"Create a collection\",\n\t},\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tlabel: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Collection label\",\n\t\t\trequired: true,\n\t\t},\n\t\t\"label-singular\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Singular label (defaults to label)\",\n\t\t},\n\t\tdescription: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Collection description\",\n\t\t},\n\t\t...commonArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst data = await client.createCollection({\n\t\t\t\tslug: args.collection,\n\t\t\t\tlabel: args.label,\n\t\t\t\tlabelSingular: args[\"label-singular\"] || args.label,\n\t\t\t\tdescription: args.description,\n\t\t\t});\n\t\t\tconsola.success(`Created collection \"${args.collection}\"`);\n\t\t\toutput(data, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst deleteCommand = defineCommand({\n\tmeta: {\n\t\tname: \"delete\",\n\t\tdescription: \"Delete a collection\",\n\t},\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tforce: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Skip confirmation\",\n\t\t},\n\t\t...commonArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tif (!args.force) {\n\t\t\t\tconst confirmed = await consola.prompt(`Delete collection \"${args.collection}\"?`, {\n\t\t\t\t\ttype: \"confirm\",\n\t\t\t\t});\n\t\t\t\tif (!confirmed) {\n\t\t\t\t\tconsola.info(\"Cancelled\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tawait client.deleteCollection(args.collection);\n\t\t\tconsola.success(`Deleted collection \"${args.collection}\"`);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst addFieldCommand = defineCommand({\n\tmeta: {\n\t\tname: \"add-field\",\n\t\tdescription: \"Add a field to a collection\",\n\t},\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tfield: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Field slug\",\n\t\t\trequired: true,\n\t\t},\n\t\ttype: {\n\t\t\ttype: \"string\",\n\t\t\tdescription:\n\t\t\t\t\"Field type (string, text, number, integer, boolean, datetime, image, reference, portableText, json)\",\n\t\t\trequired: true,\n\t\t},\n\t\tlabel: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Field label\",\n\t\t},\n\t\trequired: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Whether the field is required\",\n\t\t},\n\t\t...commonArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst data = await client.createField(args.collection, {\n\t\t\t\tslug: args.field,\n\t\t\t\ttype: args.type,\n\t\t\t\tlabel: args.label || args.field,\n\t\t\t\trequired: args.required,\n\t\t\t});\n\t\t\tconsola.success(`Added field \"${args.field}\" to \"${args.collection}\"`);\n\t\t\toutput(data, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst removeFieldCommand = defineCommand({\n\tmeta: {\n\t\tname: \"remove-field\",\n\t\tdescription: \"Remove a field from a collection\",\n\t},\n\targs: {\n\t\tcollection: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Collection slug\",\n\t\t\trequired: true,\n\t\t},\n\t\tfield: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Field slug\",\n\t\t\trequired: true,\n\t\t},\n\t\t...commonArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tawait client.deleteField(args.collection, args.field);\n\t\t\tconsola.success(`Removed field \"${args.field}\" from \"${args.collection}\"`);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nexport const schemaCommand = defineCommand({\n\tmeta: {\n\t\tname: \"schema\",\n\t\tdescription: \"Manage collections and fields\",\n\t},\n\tsubCommands: {\n\t\tlist: listCommand,\n\t\tget: getCommand,\n\t\tcreate: createCommand,\n\t\tdelete: deleteCommand,\n\t\t\"add-field\": addFieldCommand,\n\t\t\"remove-field\": removeFieldCommand,\n\t},\n});\n","/**\n * emdash search\n *\n * Full-text search across content\n */\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\n\nimport { connectionArgs, createClientFromArgs } from \"../client-factory.js\";\nimport { configureOutputMode, output } from \"../output.js\";\n\nexport const searchCommand = defineCommand({\n\tmeta: {\n\t\tname: \"search\",\n\t\tdescription: \"Full-text search across content\",\n\t},\n\targs: {\n\t\tquery: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Search query\",\n\t\t\trequired: true,\n\t\t},\n\t\tcollection: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"c\",\n\t\t\tdescription: \"Filter by collection\",\n\t\t},\n\t\tlocale: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Filter by locale\",\n\t\t},\n\t\tlimit: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"l\",\n\t\t\tdescription: \"Maximum results to return\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst results = await client.search(args.query, {\n\t\t\t\tcollection: args.collection,\n\t\t\t\tlocale: args.locale,\n\t\t\t\tlimit: args.limit ? parseInt(args.limit, 10) : undefined,\n\t\t\t});\n\t\t\toutput(results, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n","/**\n * Secrets CLI commands\n *\n * Pure (no-DB) commands for working with EmDash secrets:\n *\n * - `emdash secrets generate` — emits a fresh `EMDASH_ENCRYPTION_KEY`.\n * Optionally writes it to a local-secrets file (`.env`).\n * - `emdash secrets fingerprint <key>` — prints the kid for a key,\n * useful in CI for verifying what's been deployed without exposing\n * the raw value.\n *\n * DB-touching commands (`status`, `migrate`, `rotate`) live elsewhere:\n * the CLI process can't open the production D1/Postgres binding from\n * the operator's machine, so those operations ship as admin HTTP\n * endpoints in a later PR. A thin `--site <url>` wrapper for those\n * endpoints can land alongside.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\nimport pc from \"picocolors\";\n\nimport { EmDashSecretsError, fingerprintKey, generateEncryptionKey } from \"../../config/secrets.js\";\n\nconst KEY_VAR_NAME = \"EMDASH_ENCRYPTION_KEY\";\n/** Matches a populated entry — `KEY=<at least one char>`. */\nconst POPULATED_KEY_LINE_PATTERN = /^EMDASH_ENCRYPTION_KEY=.+$/m;\n/**\n * Matches any line starting `KEY=` including `KEY=` with empty value.\n * Used for in-place replacement when the entry exists but has no value.\n */\nconst ANY_KEY_LINE_PATTERN = /^EMDASH_ENCRYPTION_KEY=.*$/m;\n\n/**\n * Append (or replace) `EMDASH_ENCRYPTION_KEY` in a dotenv-style file.\n *\n * Idempotent: if the entry exists with a populated value, leaves it alone\n * (returns `\"skipped\"`) unless `force` is set. An entry with an empty\n * value (`EMDASH_ENCRYPTION_KEY=`) is treated as \"not set\" and gets\n * replaced — placeholder lines aren't a reason to refuse.\n *\n * Always ends the resulting file with a trailing newline. Doesn't touch\n * other variables.\n *\n * Exported for tests.\n */\nexport function writeEncryptionKeyToFile(\n\ttargetPath: string,\n\tvalue: string,\n\tforce: boolean,\n): \"wrote\" | \"skipped\" {\n\tconst exists = existsSync(targetPath);\n\tconst existing = exists ? readFileSync(targetPath, \"utf-8\") : \"\";\n\n\tconst hasPopulatedKey = POPULATED_KEY_LINE_PATTERN.test(existing);\n\tif (hasPopulatedKey && !force) {\n\t\treturn \"skipped\";\n\t}\n\n\tconst newLine = `${KEY_VAR_NAME}=${value}`;\n\tlet next: string;\n\tif (ANY_KEY_LINE_PATTERN.test(existing)) {\n\t\t// In-place replace handles both populated-and-forced and empty-value\n\t\t// cases. Then ensure trailing newline.\n\t\tnext = existing.replace(ANY_KEY_LINE_PATTERN, newLine);\n\t\tif (!next.endsWith(\"\\n\")) next += \"\\n\";\n\t} else {\n\t\t// Append. Insert a separating newline only if the file has content\n\t\t// not already ending in one.\n\t\tconst sep = existing.length === 0 ? \"\" : existing.endsWith(\"\\n\") ? \"\" : \"\\n\";\n\t\tnext = `${existing}${sep}${newLine}\\n`;\n\t}\n\n\twriteFileSync(targetPath, next);\n\treturn \"wrote\";\n}\n\nconst generateCommand = defineCommand({\n\tmeta: {\n\t\tname: \"generate\",\n\t\tdescription: \"Generate a new EmDash encryption key\",\n\t},\n\targs: {\n\t\twrite: {\n\t\t\ttype: \"string\",\n\t\t\tdescription:\n\t\t\t\t\"Optional path to write the key to (e.g. .env). \" +\n\t\t\t\t\"Won't overwrite an existing entry without --force.\",\n\t\t},\n\t\tforce: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"When used with --write, overwrite an existing entry\",\n\t\t\tdefault: false,\n\t\t},\n\t},\n\trun({ args }) {\n\t\tconst value = generateEncryptionKey();\n\n\t\tif (args.write) {\n\t\t\tconst targetPath = resolve(process.cwd(), args.write);\n\t\t\tconst result = writeEncryptionKeyToFile(targetPath, value, args.force);\n\t\t\tif (result === \"skipped\") {\n\t\t\t\t// Idempotent no-op: entry already populated. Exit 0 so chained\n\t\t\t\t// scripts (`emdash secrets generate --write && pnpm dev`) don't\n\t\t\t\t// break. Pass --force to replace, with full awareness that\n\t\t\t\t// existing encrypted secrets become unreadable.\n\t\t\t\tconsola.info(\n\t\t\t\t\t`${KEY_VAR_NAME} already set in ${pc.cyan(args.write)}; leaving it alone. ` +\n\t\t\t\t\t\t`Pass ${pc.bold(\"--force\")} to replace it.`,\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconsola.log(\"\");\n\t\t\tconsola.log(`${pc.bold(\"Wrote\")} ${pc.cyan(KEY_VAR_NAME)} to ${pc.cyan(args.write)}`);\n\t\t\tconsola.log(\"\");\n\t\t\tconsola.log(\n\t\t\t\tpc.yellow(\n\t\t\t\t\t\"Keep this file out of version control. Losing the key means losing every secret encrypted with it.\",\n\t\t\t\t),\n\t\t\t);\n\t\t\tconsola.log(\"\");\n\t\t\treturn;\n\t\t}\n\n\t\t// Print the key to stdout (one line, no decoration) so it can be\n\t\t// piped into env files or secret-management tools without scraping.\n\t\t// Explanatory text goes to stderr so it doesn't pollute the pipe.\n\t\tprocess.stdout.write(`${value}\\n`);\n\t\tconst guidance = [\n\t\t\t\"\",\n\t\t\tpc.bold(\"EmDash encryption key generated.\"),\n\t\t\t\"\",\n\t\t\t`Set ${pc.cyan(KEY_VAR_NAME)} in your environment.`,\n\t\t\t\"For Cloudflare deployments, push it to your Worker's secrets.\",\n\t\t\t\"For Node deployments, add it to your process environment or .env file.\",\n\t\t\t\"\",\n\t\t\tpc.yellow(\"Keep this value secret. Losing it means losing every secret encrypted with it.\"),\n\t\t\t\"\",\n\t\t].join(\"\\n\");\n\t\tprocess.stderr.write(`${guidance}\\n`);\n\t},\n});\n\nconst fingerprintCommand = defineCommand({\n\tmeta: {\n\t\tname: \"fingerprint\",\n\t\tdescription: \"Print the kid (8-char fingerprint) for an encryption key\",\n\t},\n\targs: {\n\t\tkey: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"The full key value (with the emdash_enc_v1_ prefix)\",\n\t\t\trequired: true,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\ttry {\n\t\t\tconst kid = await fingerprintKey(args.key);\n\t\t\t// Newline-only on stdout so it pipes cleanly into env/CI logs\n\t\t\t// without leaking the raw key.\n\t\t\tprocess.stdout.write(`${kid}\\n`);\n\t\t} catch (error) {\n\t\t\tconsola.error(\n\t\t\t\terror instanceof EmDashSecretsError ? error.message : \"Failed to fingerprint key\",\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nexport const secretsCommand = defineCommand({\n\tmeta: {\n\t\tname: \"secrets\",\n\t\tdescription: \"Manage EmDash secrets (generate, inspect)\",\n\t},\n\tsubCommands: {\n\t\tgenerate: generateCommand,\n\t\tfingerprint: fingerprintCommand,\n\t},\n});\n","/**\n * emdash seed\n *\n * Apply a seed file to the database\n */\n\nimport { readFile, access, mkdir } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport consola from \"consola\";\n\nimport { createDatabase } from \"../../database/connection.js\";\nimport { runMigrations } from \"../../database/migrations/runner.js\";\nimport { applySeed } from \"../../seed/apply.js\";\nimport type { SeedFile, SeedApplyOptions } from \"../../seed/types.js\";\nimport { validateSeed } from \"../../seed/validate.js\";\nimport { LocalStorage } from \"../../storage/local.js\";\n\ninterface PackageJson {\n\tname?: string;\n\temdash?: {\n\t\tseed?: string;\n\t};\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function readPackageJson(cwd: string): Promise<PackageJson | null> {\n\tconst pkgPath = resolve(cwd, \"package.json\");\n\ttry {\n\t\tconst content = await readFile(pkgPath, \"utf-8\");\n\t\treturn JSON.parse(content);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Resolve seed file path from:\n * 1. Positional argument (if provided)\n * 2. .emdash/seed.json (convention)\n * 3. package.json emdash.seed (config)\n */\nasync function resolveSeedPath(cwd: string, positional?: string): Promise<string | null> {\n\t// 1. Positional argument\n\tif (positional) {\n\t\tconst resolved = resolve(cwd, positional);\n\t\tif (await fileExists(resolved)) {\n\t\t\treturn resolved;\n\t\t}\n\t\tconsola.error(`Seed file not found: ${positional}`);\n\t\treturn null;\n\t}\n\n\t// 2. Convention: .emdash/seed.json\n\tconst conventionPath = resolve(cwd, \".emdash\", \"seed.json\");\n\tif (await fileExists(conventionPath)) {\n\t\treturn conventionPath;\n\t}\n\n\t// 3. package.json emdash.seed\n\tconst pkg = await readPackageJson(cwd);\n\tif (pkg?.emdash?.seed) {\n\t\tconst pkgSeedPath = resolve(cwd, pkg.emdash.seed);\n\t\tif (await fileExists(pkgSeedPath)) {\n\t\t\treturn pkgSeedPath;\n\t\t}\n\t\tconsola.warn(`Seed file from package.json not found: ${pkg.emdash.seed}`);\n\t}\n\n\treturn null;\n}\n\nexport const seedCommand = defineCommand({\n\tmeta: {\n\t\tname: \"seed\",\n\t\tdescription: \"Apply a seed file to the database\",\n\t},\n\targs: {\n\t\tpath: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Path to seed file (default: .emdash/seed.json)\",\n\t\t\trequired: false,\n\t\t},\n\t\tdatabase: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"d\",\n\t\t\tdescription: \"Database path\",\n\t\t\tdefault: \"./data.db\",\n\t\t},\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Working directory\",\n\t\t\tdefault: process.cwd(),\n\t\t},\n\t\tvalidate: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Validate only, don't apply\",\n\t\t\tdefault: false,\n\t\t},\n\t\t\"no-content\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Skip sample data (content entries, bylines, taxonomy terms)\",\n\t\t\tdefault: false,\n\t\t},\n\t\t\"on-conflict\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Conflict handling: skip, update, error\",\n\t\t\tdefault: \"skip\",\n\t\t},\n\t\t\"uploads-dir\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Directory for media uploads\",\n\t\t\tdefault: \"./uploads\",\n\t\t},\n\t\t\"media-base-url\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Base URL for media files\",\n\t\t\tdefault: \"/_emdash/api/media/file\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst cwd = resolve(args.cwd);\n\t\tconsola.start(\"Loading seed file...\");\n\n\t\t// Resolve seed file path\n\t\tconst seedPath = await resolveSeedPath(cwd, args.path);\n\t\tif (!seedPath) {\n\t\t\tconsola.error(\"No seed file found\");\n\t\t\tconsola.info(\"Provide a path, create .emdash/seed.json, or set emdash.seed in package.json\");\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconsola.info(`Seed file: ${seedPath}`);\n\n\t\t// Load and parse seed file\n\t\tlet seed: SeedFile;\n\t\ttry {\n\t\t\tconst content = await readFile(seedPath, \"utf-8\");\n\t\t\tseed = JSON.parse(content);\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Failed to parse seed file:\", error);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// Validate seed\n\t\tconsola.start(\"Validating seed file...\");\n\t\tconst validation = validateSeed(seed);\n\n\t\tif (validation.warnings.length > 0) {\n\t\t\tfor (const warning of validation.warnings) {\n\t\t\t\tconsola.warn(warning);\n\t\t\t}\n\t\t}\n\n\t\tif (!validation.valid) {\n\t\t\tconsola.error(\"Seed validation failed:\");\n\t\t\tfor (const error of validation.errors) {\n\t\t\t\tconsola.error(` - ${error}`);\n\t\t\t}\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconsola.success(\"Seed file is valid\");\n\n\t\t// If validate-only mode, exit here\n\t\tif (args.validate) {\n\t\t\tconsola.success(\"Validation complete\");\n\t\t\treturn;\n\t\t}\n\n\t\t// Connect to database\n\t\tconst dbPath = resolve(cwd, args.database);\n\t\tconsola.info(`Database: ${dbPath}`);\n\n\t\tconst db = createDatabase({ url: `file:${dbPath}` });\n\n\t\t// Run migrations\n\t\tconsola.start(\"Running migrations...\");\n\t\ttry {\n\t\t\tconst { applied } = await runMigrations(db);\n\t\t\tif (applied.length > 0) {\n\t\t\t\tconsola.success(`Applied ${applied.length} migrations`);\n\t\t\t} else {\n\t\t\t\tconsola.info(\"Database up to date\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Migration failed:\", error);\n\t\t\tawait db.destroy();\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// Set up storage for $media resolution\n\t\tconst uploadsDir = resolve(cwd, args[\"uploads-dir\"]);\n\t\tawait mkdir(uploadsDir, { recursive: true });\n\n\t\tconst storage = new LocalStorage({\n\t\t\tdirectory: uploadsDir,\n\t\t\tbaseUrl: args[\"media-base-url\"],\n\t\t});\n\n\t\t// Prepare apply options\n\t\tconst onConflictRaw = args[\"on-conflict\"];\n\t\tif (onConflictRaw !== \"skip\" && onConflictRaw !== \"update\" && onConflictRaw !== \"error\") {\n\t\t\tconsola.error(`Invalid --on-conflict value: ${onConflictRaw}`);\n\t\t\tconsola.info(\"Use: skip, update, or error\");\n\t\t\tawait db.destroy();\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconst options: SeedApplyOptions = {\n\t\t\tincludeContent: !args[\"no-content\"],\n\t\t\tonConflict: onConflictRaw,\n\t\t\tstorage,\n\t\t};\n\n\t\t// Apply seed\n\t\tconsola.start(\"Applying seed...\");\n\t\ttry {\n\t\t\tconst result = await applySeed(db, seed, options);\n\n\t\t\tconsola.success(\"Seed applied successfully!\");\n\t\t\tconsola.log(\"\");\n\n\t\t\t// Print summary\n\t\t\tif (result.settings.applied > 0) {\n\t\t\t\tconsola.info(`Settings: ${result.settings.applied} applied`);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tresult.collections.created > 0 ||\n\t\t\t\tresult.collections.skipped > 0 ||\n\t\t\t\tresult.collections.updated > 0\n\t\t\t) {\n\t\t\t\tconsola.info(\n\t\t\t\t\t`Collections: ${result.collections.created} created, ${result.collections.skipped} skipped, ${result.collections.updated} updated`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (result.fields.created > 0 || result.fields.skipped > 0 || result.fields.updated > 0) {\n\t\t\t\tconsola.info(\n\t\t\t\t\t`Fields: ${result.fields.created} created, ${result.fields.skipped} skipped, ${result.fields.updated} updated`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tresult.taxonomies.created > 0 ||\n\t\t\t\tresult.taxonomies.skipped > 0 ||\n\t\t\t\tresult.taxonomies.terms > 0\n\t\t\t) {\n\t\t\t\tconsola.info(\n\t\t\t\t\t`Taxonomies: ${result.taxonomies.created} created, ${result.taxonomies.skipped} skipped, ${result.taxonomies.terms} terms`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (result.bylines.created > 0 || result.bylines.skipped > 0 || result.bylines.updated > 0) {\n\t\t\t\tconsola.info(\n\t\t\t\t\t`Bylines: ${result.bylines.created} created, ${result.bylines.skipped} skipped, ${result.bylines.updated} updated`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (result.menus.created > 0 || result.menus.items > 0) {\n\t\t\t\tconsola.info(`Menus: ${result.menus.created} created, ${result.menus.items} items`);\n\t\t\t}\n\t\t\tif (result.widgetAreas.created > 0 || result.widgetAreas.widgets > 0) {\n\t\t\t\tconsola.info(\n\t\t\t\t\t`Widget Areas: ${result.widgetAreas.created} created, ${result.widgetAreas.widgets} widgets`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (result.content.created > 0 || result.content.skipped > 0 || result.content.updated > 0) {\n\t\t\t\tconsola.info(\n\t\t\t\t\t`Content: ${result.content.created} created, ${result.content.skipped} skipped, ${result.content.updated} updated`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (result.media.created > 0 || result.media.skipped > 0) {\n\t\t\t\tconsola.info(`Media: ${result.media.created} created, ${result.media.skipped} skipped`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Seed failed:\", error instanceof Error ? error.message : error);\n\t\t\tawait db.destroy();\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tawait db.destroy();\n\t\tconsola.success(\"Done!\");\n\t},\n});\n","/**\n * Reading and writing `.emdash` site package files on disk.\n *\n * Reading never trusts the archive: every entry is hashed and checked\n * against the manifest and the index chunks it pins before anything is\n * uploaded, so a damaged or tampered package fails locally.\n */\n\nimport { createReadStream, createWriteStream } from \"node:fs\";\nimport { rename, rm, stat } from \"node:fs/promises\";\nimport { Readable, Writable } from \"node:stream\";\n\nimport {\n\tpackSitePackage,\n\tunpackSitePackage,\n\ttype PackageFileSource,\n\ttype UnpackedPackageFile,\n} from \"../../transfer/container/tar.js\";\nimport { TransferError } from \"../../transfer/errors.js\";\nimport {\n\tcreateSha256,\n\tpackageDigest,\n\tsha256Hex,\n\ttype Sha256Digest,\n} from \"../../transfer/format/digest.js\";\nimport {\n\tdecodeUtf8,\n\tparseIndexLine,\n\tparseManifest,\n\ttype PackageFileEntry,\n\ttype SitePackageManifest,\n} from \"../../transfer/format/manifest.js\";\n\nexport interface LocalPackageFile {\n\tbytes: number;\n\tsha256: string;\n}\n\nexport interface ScannedSitePackage {\n\tmanifestBytes: Uint8Array;\n\tmanifest: SitePackageManifest;\n\tpackageDigest: Sha256Digest;\n\t/** Every file except the manifest: index chunks, record chunks, media blobs. */\n\tfiles: Map<string, LocalPackageFile>;\n\t/** Index chunk path → the record and media paths it lists. */\n\tindexEntries: Map<string, string[]>;\n\t/** Record or media path → the index chunk that lists it. */\n\tindexOf: Map<string, string>;\n\ttotalBytes: number;\n}\n\n/** Split an index chunk into its entries. */\nexport function parseIndexChunk(bytes: Uint8Array): PackageFileEntry[] {\n\tconst text = decodeUtf8(bytes, \"TRANSFER_MANIFEST_INVALID\");\n\tif (text.length > 0 && !text.endsWith(\"\\n\")) {\n\t\tthrow new TransferError(\"TRANSFER_MANIFEST_INVALID\", \"Index chunk must end with a newline\");\n\t}\n\treturn text\n\t\t.split(\"\\n\")\n\t\t.slice(0, -1)\n\t\t.map((line) => parseIndexLine(line));\n}\n\nexport function openArchive(path: string): ReadableStream<Uint8Array> {\n\treturn Readable.toWeb(createReadStream(path)) as ReadableStream<Uint8Array>;\n}\n\nexport async function readBody(body: ReadableStream<Uint8Array>): Promise<Uint8Array> {\n\treturn new Uint8Array(await new Response(body).arrayBuffer());\n}\n\nfunction mismatch(path: string, kind: \"digest\" | \"size\"): TransferError {\n\treturn kind === \"digest\"\n\t\t? new TransferError(\"TRANSFER_FILE_DIGEST_MISMATCH\", \"File does not match its digest\", {\n\t\t\t\tdetail: { path },\n\t\t\t})\n\t\t: new TransferError(\"TRANSFER_FILE_SIZE_MISMATCH\", \"File does not have its declared size\", {\n\t\t\t\tdetail: { path },\n\t\t\t});\n}\n\n/** Check bytes against a declared size and digest. */\nexport async function assertFileMatches(\n\tpath: string,\n\tbytes: Uint8Array,\n\texpected: LocalPackageFile,\n): Promise<void> {\n\tif (bytes.byteLength !== expected.bytes) throw mismatch(path, \"size\");\n\tif ((await sha256Hex(bytes)) !== expected.sha256) throw mismatch(path, \"digest\");\n}\n\nasync function hashBody(body: ReadableStream<Uint8Array>): Promise<LocalPackageFile> {\n\tconst hasher = await createSha256();\n\tlet bytes = 0;\n\tawait body.pipeTo(\n\t\tnew WritableStream<Uint8Array>({\n\t\t\twrite(chunk) {\n\t\t\t\tbytes += chunk.byteLength;\n\t\t\t\thasher.update(chunk);\n\t\t\t},\n\t\t}),\n\t);\n\treturn { bytes, sha256: await hasher.digest() };\n}\n\n/** Whether the file at `diskPath` exists and has exactly the expected size and digest. */\nexport async function diskFileMatches(\n\tdiskPath: string,\n\texpected: LocalPackageFile,\n): Promise<boolean> {\n\tlet info;\n\ttry {\n\t\tinfo = await stat(diskPath);\n\t} catch {\n\t\treturn false;\n\t}\n\tif (!info.isFile() || info.size !== expected.bytes) return false;\n\treturn (await hashBody(openArchive(diskPath))).sha256 === expected.sha256;\n}\n\n/**\n * Stream `body` to `diskPath`, verifying it against the package file `path`\n * declares. The file appears at `diskPath` only once it is complete and\n * verified.\n */\nexport async function saveVerifiedFile(\n\tpath: string,\n\tbody: ReadableStream<Uint8Array>,\n\texpected: LocalPackageFile,\n\tdiskPath: string,\n): Promise<void> {\n\tconst temporary = `${diskPath}.download`;\n\tconst hasher = await createSha256();\n\tlet bytes = 0;\n\tconst verify = new TransformStream<Uint8Array, Uint8Array>({\n\t\ttransform(chunk, controller) {\n\t\t\tbytes += chunk.byteLength;\n\t\t\tif (bytes > expected.bytes) throw mismatch(path, \"size\");\n\t\t\thasher.update(chunk);\n\t\t\tcontroller.enqueue(chunk);\n\t\t},\n\t});\n\ttry {\n\t\tawait body\n\t\t\t.pipeThrough(verify)\n\t\t\t.pipeTo(Writable.toWeb(createWriteStream(temporary)) as WritableStream<Uint8Array>);\n\t\tif (bytes !== expected.bytes) throw mismatch(path, \"size\");\n\t\tif ((await hasher.digest()) !== expected.sha256) throw mismatch(path, \"digest\");\n\t\tawait rename(temporary, diskPath);\n\t} catch (error) {\n\t\tawait rm(temporary, { force: true });\n\t\tthrow error;\n\t}\n}\n\n/**\n * Read a package file end to end and verify it: the manifest, every index\n * chunk the manifest pins, and every file the index lists, each by size and\n * SHA-256. Fails with a `TransferError` naming the first bad path.\n */\nexport async function scanSitePackage(archivePath: string): Promise<ScannedSitePackage> {\n\tlet manifestBytes: Uint8Array | undefined;\n\tlet manifest: SitePackageManifest | undefined;\n\tconst indexRefs = new Map<string, LocalPackageFile>();\n\tconst declared = new Map<string, LocalPackageFile>();\n\tconst indexEntries = new Map<string, string[]>();\n\tconst indexOf = new Map<string, string>();\n\tconst seen = new Map<string, LocalPackageFile>();\n\n\tawait unpackSitePackage(\n\t\topenArchive(archivePath),\n\t\tasync (file: UnpackedPackageFile) => {\n\t\t\tif (file.parsed.type === \"manifest\") {\n\t\t\t\tmanifestBytes = await readBody(file.body);\n\t\t\t\tmanifest = parseManifest(manifestBytes);\n\t\t\t\tfor (const ref of manifest.index) {\n\t\t\t\t\tindexRefs.set(ref.path, { bytes: ref.bytes, sha256: ref.sha256 });\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (file.parsed.type === \"index\") {\n\t\t\t\tconst expected = indexRefs.get(file.path);\n\t\t\t\tif (!expected) {\n\t\t\t\t\tthrow new TransferError(\"TRANSFER_FILE_NOT_DECLARED\", \"Index chunk is not listed\", {\n\t\t\t\t\t\tdetail: { path: file.path },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (file.bytes !== expected.bytes) throw mismatch(file.path, \"size\");\n\t\t\t\tconst bytes = await readBody(file.body);\n\t\t\t\tawait assertFileMatches(file.path, bytes, expected);\n\t\t\t\tconst paths: string[] = [];\n\t\t\t\tfor (const entry of parseIndexChunk(bytes)) {\n\t\t\t\t\tif (declared.has(entry.path)) {\n\t\t\t\t\t\tthrow new TransferError(\"TRANSFER_MANIFEST_INVALID\", \"File is listed twice\", {\n\t\t\t\t\t\t\tdetail: { path: entry.path },\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tdeclared.set(entry.path, { bytes: entry.bytes, sha256: entry.sha256 });\n\t\t\t\t\tindexOf.set(entry.path, file.path);\n\t\t\t\t\tpaths.push(entry.path);\n\t\t\t\t}\n\t\t\t\tindexEntries.set(file.path, paths);\n\t\t\t\tseen.set(file.path, expected);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tseen.set(file.path, await hashBody(file.body));\n\t\t},\n\t\t{\n\t\t\texpectedBytes: (path) => indexRefs.get(path)?.bytes ?? declared.get(path)?.bytes,\n\t\t},\n\t);\n\n\tif (!manifest || !manifestBytes) {\n\t\tthrow new TransferError(\"TRANSFER_CONTAINER_INVALID\", \"The package has no manifest\");\n\t}\n\tfor (const [path, expected] of [...indexRefs, ...declared]) {\n\t\tconst actual = seen.get(path);\n\t\tif (!actual) {\n\t\t\tthrow new TransferError(\"TRANSFER_FILE_MISSING\", \"The package is missing a file\", {\n\t\t\t\tdetail: { path },\n\t\t\t});\n\t\t}\n\t\tif (actual.bytes !== expected.bytes) throw mismatch(path, \"size\");\n\t\tif (actual.sha256 !== expected.sha256) throw mismatch(path, \"digest\");\n\t}\n\tfor (const path of seen.keys()) {\n\t\tif (!indexRefs.has(path) && !declared.has(path)) {\n\t\t\tthrow new TransferError(\"TRANSFER_FILE_NOT_DECLARED\", \"File is not listed by the package\", {\n\t\t\t\tdetail: { path },\n\t\t\t});\n\t\t}\n\t}\n\n\tlet totalBytes = manifestBytes.byteLength;\n\tfor (const file of seen.values()) totalBytes += file.bytes;\n\treturn {\n\t\tmanifestBytes,\n\t\tmanifest,\n\t\tpackageDigest: await packageDigest(manifest),\n\t\tfiles: seen,\n\t\tindexEntries,\n\t\tindexOf,\n\t\ttotalBytes,\n\t};\n}\n\n/**\n * Stream `files` into a package file at `outputPath`. Writes go to a\n * sibling `.partial` file that replaces `outputPath` only once the whole\n * archive is written; on failure the partial file is removed.\n */\nexport async function writeSitePackage(\n\toutputPath: string,\n\tfiles: AsyncIterable<PackageFileSource>,\n): Promise<{ bytes: number }> {\n\tconst partialPath = `${outputPath}.partial`;\n\tlet bytes = 0;\n\tconst counter = new TransformStream<Uint8Array, Uint8Array>({\n\t\ttransform(chunk, controller) {\n\t\t\tbytes += chunk.byteLength;\n\t\t\tcontroller.enqueue(chunk);\n\t\t},\n\t});\n\tconst sink = Writable.toWeb(createWriteStream(partialPath)) as WritableStream<Uint8Array>;\n\ttry {\n\t\tawait packSitePackage(files).pipeThrough(counter).pipeTo(sink);\n\t\tawait rename(partialPath, outputPath);\n\t} catch (error) {\n\t\tawait rm(partialPath, { force: true });\n\t\tthrow error;\n\t}\n\treturn { bytes };\n}\n","/**\n * Shared pieces of `emdash site`: errors, their user-facing messages,\n * retries, and progress reporting.\n */\n\nimport { EmDashApiError } from \"../../client/index.js\";\nimport { isTransferError } from \"../../transfer/errors.js\";\nimport type {\n\tExportTransformationCode,\n\tImportTransformationCode,\n} from \"../../transfer/format/transformations.js\";\n\n/** A failure the CLI reports with a stable code, like an API error. */\nexport class SiteTransferCliError extends Error {\n\tconstructor(\n\t\treadonly code: string,\n\t\tmessage: string,\n\t\treadonly details?: Record<string, unknown>,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"SiteTransferCliError\";\n\t}\n}\n\nexport interface CliErrorInfo {\n\tcode: string;\n\tmessage: string;\n}\n\nconst TRANSFER_MESSAGES: Readonly<Record<string, string>> = {\n\tTRANSFER_TARGET_NOT_EMPTY:\n\t\t\"This site already has content. A site package can only be imported into an empty site.\",\n\tTRANSFER_IMPORT_IN_PROGRESS:\n\t\t\"Another import is in progress on this site, or an unfinished import is still blocking writes. Check it with `emdash site import status <operation-id>`.\",\n\tTRANSFER_EXPORT_CONCURRENT_WRITES:\n\t\t\"The site kept changing while it was being exported. Run the export again when the site is quiet.\",\n\tTRANSFER_OPERATION_NOT_FOUND: \"No transfer operation with that id exists on this site.\",\n\tTRANSFER_EXPIRED:\n\t\t\"This transfer has expired and its files were removed. Start a new export or import.\",\n\tTRANSFER_IDEMPOTENCY_CONFLICT:\n\t\t\"This site already has an import started from a different package with the same key.\",\n\tTRANSFER_MANIFEST_INVALID: \"The package manifest is invalid.\",\n\tTRANSFER_UNSUPPORTED_FORMAT:\n\t\t\"This package uses a format version this site does not support. Upgrade EmDash on this site.\",\n\tTRANSFER_UNSUPPORTED_FEATURE:\n\t\t\"This package needs features this site does not support. Upgrade EmDash on this site.\",\n\tTRANSFER_CONTAINER_INVALID: \"The file is not a valid .emdash site package.\",\n\tTRANSFER_FILE_DIGEST_MISMATCH:\n\t\t\"A package file does not match its recorded digest. The package is damaged or was modified.\",\n\tTRANSFER_FILE_SIZE_MISMATCH:\n\t\t\"A package file does not have its recorded size. The package is damaged or was modified.\",\n\tTRANSFER_FILE_MISSING: \"The package is missing files its manifest lists.\",\n\tTRANSFER_FILE_NOT_DECLARED: \"The package contains a file its manifest does not list.\",\n\tTRANSFER_LIMIT_EXCEEDED: \"The package exceeds a limit this site enforces.\",\n\tTRANSFER_PACKAGE_DIGEST_MISMATCH:\n\t\t\"This is not the package that was analyzed. Analyze this package with `--analyze` first.\",\n\tTRANSFER_PLAN_DIGEST_MISMATCH:\n\t\t\"The plan changed since it was reviewed. Run `emdash site import <file> --analyze` again and confirm the new plan digest.\",\n\tTRANSFER_PLAN_BLOCKED:\n\t\t\"The import plan has blockers. Run `emdash site import <file> --analyze` to see them.\",\n\tTRANSFER_DECISIONS_INVALID: \"The import decisions are invalid.\",\n\tTRANSFER_VERIFICATION_FAILED:\n\t\t\"The imported site did not verify against the package, so no receipt was issued. Do not use this site; import into a fresh one.\",\n};\n\nconst TRANSFORMATION_LABELS: Readonly<\n\tRecord<ExportTransformationCode | ImportTransformationCode, string>\n> = {\n\tsoft_orphan_dropped: \"Unused references were left out\",\n\tavatar_nulled: \"Some byline avatars were left out\",\n\tredirect_duplicate_dropped: \"Duplicate redirects were left out\",\n\tmedia_not_ready_dropped: \"Unfinished media uploads were left out\",\n\tmedia_url_relativized: \"Media links were made relative\",\n\torphan_dropped: \"Records without a parent were left out\",\n\torphan_reference_nulled: \"Broken references were cleared\",\n\tmedia_ref_unlinked: \"Some media links could not be matched to files\",\n\tunknown_storage_key:\n\t\t\"Some content links to media files the source site doesn't have; those links won't work\",\n\tprincipal_mapped: \"Authors will be assigned to users on this site\",\n\tprincipal_unmapped: \"Some content will have no author\",\n\tseeded_scaffold_removed: \"Starter content will be removed\",\n\tredirect_loop_disabled: \"Redirects that loop will be imported turned off\",\n\tsearch_unsupported: \"Search will be turned off for some collections\",\n\tfloat4_rounded: \"Some decimal numbers will be rounded\",\n\tlocale_recased: \"Locales will use this site's capitalization\",\n};\n\n/** A plain-language description of a plan transformation code. */\nexport function transformationLabel(code: string): string {\n\tconst labels: Readonly<Record<string, string>> = TRANSFORMATION_LABELS;\n\treturn (Object.hasOwn(labels, code) ? labels[code] : undefined) ?? code;\n}\n\nfunction withServerDetail(friendly: string, serverMessage: string): string {\n\treturn serverMessage && !friendly.includes(serverMessage)\n\t\t? `${friendly} (${serverMessage})`\n\t\t: friendly;\n}\n\n/** The code and user-facing message for any error `emdash site` can hit. */\nexport function describeError(error: unknown): CliErrorInfo {\n\tif (error instanceof EmDashApiError) {\n\t\tconst friendly = TRANSFER_MESSAGES[error.code];\n\t\treturn {\n\t\t\tcode: error.code,\n\t\t\tmessage: friendly ? withServerDetail(friendly, error.message) : error.message,\n\t\t};\n\t}\n\tif (error instanceof SiteTransferCliError) {\n\t\treturn { code: error.code, message: error.message };\n\t}\n\tif (isTransferError(error)) {\n\t\tconst friendly = TRANSFER_MESSAGES[error.code];\n\t\tconst path = typeof error.detail?.path === \"string\" ? ` [${error.detail.path}]` : \"\";\n\t\treturn {\n\t\t\tcode: error.code,\n\t\t\tmessage: `${friendly ? withServerDetail(friendly, error.message) : error.message}${path}`,\n\t\t};\n\t}\n\treturn {\n\t\tcode: \"UNKNOWN_ERROR\",\n\t\tmessage: error instanceof Error ? error.message : String(error),\n\t};\n}\n\n/** Describe a failed operation from its recorded error. */\nexport function operationError(operation: {\n\tid: string;\n\tstate: string;\n\terrorCode: string | null;\n\terrorDetail: Record<string, unknown> | null;\n}): SiteTransferCliError {\n\tconst code = operation.errorCode ?? \"TRANSFER_OPERATION_FAILED\";\n\tconst friendly = TRANSFER_MESSAGES[code];\n\tconst base = friendly ?? `Operation ${operation.id} ended as ${operation.state}.`;\n\treturn new SiteTransferCliError(\n\t\tcode,\n\t\tfriendly ? `${base} (operation ${operation.id} is ${operation.state})` : base,\n\t\toperation.errorDetail ?? undefined,\n\t);\n}\n\nexport interface Reporter {\n\t/** A progress or status line for humans (stderr). */\n\tinfo(message: string): void;\n\t/** Something the user should notice but that does not stop the command. */\n\twarn(message: string): void;\n}\n\nexport interface RetryOptions {\n\t/** Attempts including the first (default 5). */\n\tattempts?: number;\n\t/** First backoff delay in ms, doubled per retry up to 8 s (default 500). */\n\tbaseDelayMs?: number;\n}\n\nexport interface TransferRuntime {\n\treporter: Reporter;\n\tretry?: RetryOptions;\n\t/** Waits between polls and retries; tests replace it. */\n\tsleep?: (ms: number) => Promise<void>;\n}\n\nexport function sleepFor(runtime: TransferRuntime, ms: number): Promise<void> {\n\tif (ms <= 0) return Promise.resolve();\n\tif (runtime.sleep) return runtime.sleep(ms);\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nconst MAX_BACKOFF_MS = 8000;\n\n/** Network failures, timeouts, rate limits, and server errors are worth another try. */\nexport function isTransient(error: unknown): boolean {\n\tif (error instanceof EmDashApiError) {\n\t\tif (error.code === \"TRANSFER_IMPORT_IN_PROGRESS\") return false;\n\t\treturn error.status === 408 || error.status === 429 || error.status >= 500;\n\t}\n\tif (error instanceof SiteTransferCliError || isTransferError(error)) return false;\n\treturn error instanceof TypeError || (error instanceof Error && error.name === \"AbortError\");\n}\n\n/** Run `fn`, retrying transient failures with exponential backoff. */\nexport async function withRetry<T>(\n\truntime: TransferRuntime,\n\tlabel: string,\n\tfn: () => Promise<T>,\n): Promise<T> {\n\tconst attempts = runtime.retry?.attempts ?? 5;\n\tconst base = runtime.retry?.baseDelayMs ?? 500;\n\tfor (let attempt = 1; ; attempt++) {\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} catch (error) {\n\t\t\tif (attempt >= attempts || !isTransient(error)) throw error;\n\t\t\tconst delay = Math.min(base * 2 ** (attempt - 1), MAX_BACKOFF_MS);\n\t\t\truntime.reporter.warn(\n\t\t\t\t`${label} failed (${describeError(error).message}); retrying in ${Math.round(delay / 100) / 10}s`,\n\t\t\t);\n\t\t\tawait sleepFor(runtime, delay);\n\t\t}\n\t}\n}\n\n/** Emits a progress line at most once per interval, and always when the label changes. */\nexport function createProgressLogger(\n\truntime: TransferRuntime,\n\tintervalMs = 2000,\n): (label: string, detail?: string) => void {\n\tlet lastLabel: string | undefined;\n\tlet lastAt = 0;\n\treturn (label, detail) => {\n\t\tconst now = Date.now();\n\t\tif (label === lastLabel && now - lastAt < intervalMs) return;\n\t\tlastLabel = label;\n\t\tlastAt = now;\n\t\truntime.reporter.info(detail ? `${label}: ${detail}` : label);\n\t};\n}\n\nexport function formatBytes(bytes: number): string {\n\tif (bytes < 1024) return `${bytes} B`;\n\tconst units = [\"KiB\", \"MiB\", \"GiB\", \"TiB\"];\n\tlet value = bytes / 1024;\n\tlet unit = 0;\n\twhile (value >= 1024 && unit < units.length - 1) {\n\t\tvalue /= 1024;\n\t\tunit++;\n\t}\n\treturn `${value.toFixed(1)} ${units[unit]}`;\n}\n\nexport function formatProgress(\n\tprogress: { done: number; total: number; bytesDone?: number; bytesTotal?: number } | null,\n): string | undefined {\n\tif (!progress) return undefined;\n\tconst bytes =\n\t\tprogress.bytesTotal !== undefined && progress.bytesDone !== undefined\n\t\t\t? ` (${formatBytes(progress.bytesDone)} / ${formatBytes(progress.bytesTotal)})`\n\t\t\t: \"\";\n\treturn `${progress.done}/${progress.total}${bytes}`;\n}\n","/**\n * `emdash site export`: drive a server-side export to completion, then\n * download its files one by one and assemble the `.emdash` package locally.\n *\n * A sidecar `<output>.partial.json` holds the idempotency key and operation\n * id, so re-running the same command after a crash or disconnect resumes the\n * same export instead of starting another. Downloaded files are kept in\n * `<output>.parts/` until the package is assembled, so a re-run only\n * downloads the files it does not have yet.\n */\n\nimport { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ulid } from \"ulidx\";\nimport { z } from \"zod\";\n\nimport type { EmDashClient, TransferOperation } from \"../../client/index.js\";\nimport { EmDashApiError } from \"../../client/index.js\";\nimport type { PackageFileSource } from \"../../transfer/container/tar.js\";\nimport { packageDigest, type Sha256Digest } from \"../../transfer/format/digest.js\";\nimport { parseManifest, type PackageFileEntry } from \"../../transfer/format/manifest.js\";\nimport { MANIFEST_PATH } from \"../../transfer/format/paths.js\";\nimport {\n\tdiskFileMatches,\n\topenArchive,\n\tparseIndexChunk,\n\tsaveVerifiedFile,\n\twriteSitePackage,\n} from \"./archive.js\";\nimport {\n\tcreateProgressLogger,\n\tformatBytes,\n\tformatProgress,\n\toperationError,\n\tSiteTransferCliError,\n\tsleepFor,\n\twithRetry,\n\ttype TransferRuntime,\n} from \"./shared.js\";\n\nconst DOWNLOAD_CONCURRENCY = 4;\n\nconst sidecarSchema = z.object({\n\tversion: z.literal(1),\n\tbaseUrl: z.string(),\n\tcomments: z.boolean(),\n\tidempotencyKey: z.string(),\n\toperationId: z.string().nullable(),\n});\n\ntype Sidecar = z.infer<typeof sidecarSchema>;\n\nexport function exportSidecarPath(outputPath: string): string {\n\treturn `${outputPath}.partial.json`;\n}\n\nasync function readSidecar(path: string): Promise<Sidecar | null> {\n\tlet text: string;\n\ttry {\n\t\ttext = await readFile(path, \"utf8\");\n\t} catch {\n\t\treturn null;\n\t}\n\ttry {\n\t\tconst parsed = sidecarSchema.safeParse(JSON.parse(text));\n\t\treturn parsed.success ? parsed.data : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function writeSidecar(path: string, sidecar: Sidecar): Promise<void> {\n\tawait writeFile(path, `${JSON.stringify(sidecar, null, \"\\t\")}\\n`);\n}\n\nexport interface SiteExportInput {\n\tclient: EmDashClient;\n\t/** Instance URL; a sidecar left by an export from another site is ignored. */\n\tbaseUrl: string;\n\toutputPath: string;\n\tcomments: boolean;\n}\n\nexport interface SiteExportResult {\n\toperationId: string;\n\toutput: string;\n\tpackageDigest: Sha256Digest;\n\tfiles: number;\n\tbytes: number;\n\tresumed: boolean;\n}\n\nasync function startOrResume(\n\tinput: SiteExportInput,\n\truntime: TransferRuntime,\n): Promise<{ operation: TransferOperation; resumed: boolean }> {\n\tconst sidecarPath = exportSidecarPath(input.outputPath);\n\tlet sidecar = await readSidecar(sidecarPath);\n\tif (sidecar && (sidecar.baseUrl !== input.baseUrl || sidecar.comments !== input.comments)) {\n\t\truntime.reporter.warn(\n\t\t\t`Ignoring ${sidecarPath}: it belongs to an export with different options or from another site.`,\n\t\t);\n\t\tsidecar = null;\n\t}\n\n\tif (sidecar?.operationId) {\n\t\tconst operationId = sidecar.operationId;\n\t\tconst existing = await withRetry(runtime, \"Reading the export\", () =>\n\t\t\tinput.client.transferExportGet(operationId),\n\t\t).catch((error: unknown) => {\n\t\t\tif (error instanceof EmDashApiError && error.code === \"TRANSFER_OPERATION_NOT_FOUND\") {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tthrow error;\n\t\t});\n\t\tconst operation = existing?.operation;\n\t\tif (operation && operation.state !== \"failed\" && operation.state !== \"expired\") {\n\t\t\tif (operation.state !== \"complete\" || operation.stagingCollectedAt === null) {\n\t\t\t\truntime.reporter.info(`Resuming export ${operation.id}`);\n\t\t\t\treturn { operation, resumed: true };\n\t\t\t}\n\t\t}\n\t\truntime.reporter.warn(\n\t\t\toperation\n\t\t\t\t? `Export ${operation.id} ${operation.state === \"failed\" ? `failed (${operation.errorCode ?? \"unknown error\"})` : \"expired\"}; starting a new export.`\n\t\t\t\t: `Export ${operationId} no longer exists; starting a new export.`,\n\t\t);\n\t\tsidecar = null;\n\t}\n\n\tconst state: Sidecar = sidecar ?? {\n\t\tversion: 1,\n\t\tbaseUrl: input.baseUrl,\n\t\tcomments: input.comments,\n\t\tidempotencyKey: `emdash-cli-export-${ulid()}`,\n\t\toperationId: null,\n\t};\n\tawait writeSidecar(sidecarPath, state);\n\tconst created = await withRetry(runtime, \"Starting the export\", () =>\n\t\tinput.client.transferExportCreate(input.comments ? {} : { comments: false }, {\n\t\t\tidempotencyKey: state.idempotencyKey,\n\t\t}),\n\t);\n\tawait writeSidecar(sidecarPath, { ...state, operationId: created.operation.id });\n\truntime.reporter.info(\n\t\t`${created.created ? \"Started\" : \"Resuming\"} export ${created.operation.id}`,\n\t);\n\treturn { operation: created.operation, resumed: !created.created };\n}\n\n/** Advance an export until it ends; returns the complete operation. */\nexport async function driveExport(\n\tclient: EmDashClient,\n\toperation: TransferOperation,\n\truntime: TransferRuntime,\n): Promise<TransferOperation> {\n\tconst progress = createProgressLogger(runtime);\n\tlet current = operation;\n\twhile (current.state === \"pending\" || current.state === \"running\") {\n\t\tconst step = await withRetry(runtime, \"Export step\", () =>\n\t\t\tclient.transferExportAdvance(current.id),\n\t\t);\n\t\tcurrent = step.operation;\n\t\tprogress(`Exporting (${current.stage ?? current.state})`, formatProgress(current.progress));\n\t\tif (step.nextRequestInMs === null) break;\n\t\tawait sleepFor(runtime, step.nextRequestInMs);\n\t}\n\tif (current.state !== \"complete\") throw operationError(current);\n\treturn current;\n}\n\n/**\n * Directory next to the output where downloaded files are kept, by digest,\n * until the package is assembled. A re-run reuses every file there that\n * still verifies.\n */\nexport function exportPartsPath(outputPath: string): string {\n\treturn `${outputPath}.parts`;\n}\n\ninterface DownloadedFile {\n\tpath: string;\n\tbytes: number;\n\tsha256: string;\n}\n\n/**\n * Run `task` over `items` with at most `limit` in flight. After a failure no\n * new item starts, the ones in flight finish, and the first failure is\n * thrown.\n */\nasync function forEachConcurrently<T>(\n\titems: readonly T[],\n\tlimit: number,\n\ttask: (item: T) => Promise<void>,\n): Promise<void> {\n\tlet next = 0;\n\tlet failure: { error: unknown } | undefined;\n\tconst worker = async () => {\n\t\twhile (!failure && next < items.length) {\n\t\t\tconst item = items[next++];\n\t\t\ttry {\n\t\t\t\tawait task(item);\n\t\t\t} catch (error) {\n\t\t\t\tfailure ??= { error };\n\t\t\t}\n\t\t}\n\t};\n\tawait Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker));\n\tif (failure) throw failure.error;\n}\n\n/**\n * Download a complete export file by file and write it as a package file.\n * The manifest must hash to the export's package digest.\n */\nexport async function downloadExport(\n\tclient: EmDashClient,\n\toperation: TransferOperation,\n\toutputPath: string,\n\truntime: TransferRuntime,\n): Promise<{ packageDigest: Sha256Digest; files: number; bytes: number }> {\n\tconst operationId = operation.id;\n\tconst manifestBytes = await withRetry(runtime, \"Downloading the manifest\", () =>\n\t\tclient.transferExportManifest(operationId),\n\t);\n\tconst manifest = parseManifest(manifestBytes);\n\tconst digest = await packageDigest(manifest);\n\tif (digest !== operation.packageDigest) {\n\t\tthrow new SiteTransferCliError(\n\t\t\t\"TRANSFER_PACKAGE_DIGEST_MISMATCH\",\n\t\t\t`The downloaded manifest does not match export ${operationId}. Run the export again.`,\n\t\t);\n\t}\n\tconst partsDir = exportPartsPath(outputPath);\n\tawait mkdir(partsDir, { recursive: true });\n\tconst partOf = (file: DownloadedFile) => join(partsDir, file.sha256);\n\n\tlet kept = 0;\n\tconst fetchPart = async (file: DownloadedFile): Promise<void> => {\n\t\tif (await diskFileMatches(partOf(file), file)) {\n\t\t\tkept++;\n\t\t\treturn;\n\t\t}\n\t\tawait withRetry(runtime, `Downloading ${file.path}`, async () => {\n\t\t\tconst download = await client.transferExportFile(operationId, file.path);\n\t\t\tawait saveVerifiedFile(file.path, download.body, file, partOf(file));\n\t\t});\n\t};\n\n\tconst indexChunks: DownloadedFile[] = manifest.index.map((ref) => ({\n\t\tpath: ref.path,\n\t\tbytes: ref.bytes,\n\t\tsha256: ref.sha256,\n\t}));\n\tconst entries: PackageFileEntry[] = [];\n\tfor (const chunk of indexChunks) {\n\t\tawait fetchPart(chunk);\n\t\tentries.push(...parseIndexChunk(await readFile(partOf(chunk))));\n\t}\n\n\tconst unique = [...new Map(entries.map((entry) => [entry.sha256, entry])).values()];\n\tconst total = unique.reduce((sum, entry) => sum + entry.bytes, 0);\n\tconst progress = createProgressLogger(runtime);\n\tlet done = 0;\n\tlet count = 0;\n\tawait forEachConcurrently(unique, DOWNLOAD_CONCURRENCY, async (entry) => {\n\t\tawait fetchPart(entry);\n\t\tdone += entry.bytes;\n\t\tcount++;\n\t\tprogress(\n\t\t\t\"Downloading\",\n\t\t\t`${count}/${unique.length} files (${formatBytes(done)} / ${formatBytes(total)})`,\n\t\t);\n\t});\n\tif (kept > 0) runtime.reporter.info(`Reused ${kept} files downloaded by an earlier run`);\n\n\tasync function* files(): AsyncGenerator<PackageFileSource> {\n\t\tyield { path: MANIFEST_PATH, bytes: manifestBytes.byteLength, body: () => manifestBytes };\n\t\tfor (const file of [...indexChunks, ...entries]) {\n\t\t\tyield { path: file.path, bytes: file.bytes, body: () => openArchive(partOf(file)) };\n\t\t}\n\t}\n\tconst written = await writeSitePackage(outputPath, files());\n\tawait rm(partsDir, { recursive: true, force: true });\n\treturn {\n\t\tpackageDigest: digest,\n\t\tfiles: 1 + indexChunks.length + entries.length,\n\t\tbytes: written.bytes,\n\t};\n}\n\nexport async function runSiteExport(\n\tinput: SiteExportInput,\n\truntime: TransferRuntime,\n): Promise<SiteExportResult> {\n\tconst { operation, resumed } = await startOrResume(input, runtime);\n\tconst complete = await driveExport(input.client, operation, runtime);\n\truntime.reporter.info(`Export ${complete.id} is complete; downloading`);\n\tconst downloaded = await downloadExport(input.client, complete, input.outputPath, runtime);\n\tawait rm(exportSidecarPath(input.outputPath), { force: true });\n\treturn {\n\t\toperationId: complete.id,\n\t\toutput: input.outputPath,\n\t\tpackageDigest: downloaded.packageDigest,\n\t\tfiles: downloaded.files,\n\t\tbytes: downloaded.bytes,\n\t\tresumed,\n\t};\n}\n","/**\n * `emdash site import`: verify a local package, upload what the target is\n * missing, analyze it into a plan, and execute a confirmed plan.\n *\n * Every step is resumable. The import is created with the package digest as\n * its idempotency key and found again by digest, uploads skip files the\n * target already verified, and analysis and execution are server-side state\n * machines the CLI only advances.\n */\n\nimport {\n\tEmDashApiError,\n\ttype EmDashClient,\n\ttype SiteImportDecisionsInput,\n\ttype SiteImportPlan,\n\ttype SiteImportReceipt,\n\ttype TransferOperation,\n\ttype TransferPackageFile,\n} from \"../../client/index.js\";\nimport { unpackSitePackage } from \"../../transfer/container/tar.js\";\nimport { verifyReceiptDigest } from \"../../transfer/format/receipt.js\";\nimport {\n\tassertFileMatches,\n\topenArchive,\n\treadBody,\n\tscanSitePackage,\n\ttype ScannedSitePackage,\n} from \"./archive.js\";\nimport {\n\tcreateProgressLogger,\n\tformatBytes,\n\tformatProgress,\n\toperationError,\n\tSiteTransferCliError,\n\tsleepFor,\n\twithRetry,\n\ttype TransferRuntime,\n} from \"./shared.js\";\n\nconst UPLOAD_CONCURRENCY = 4;\n/** Buffered upload bytes allowed in flight; one larger file may exceed it. */\nconst UPLOAD_BUFFER_BYTES = 64 * 1024 * 1024;\nconst MISSING_PAGE = 100;\nconst IMPORT_LOOKUP_PAGES = 5;\nconst SHA256_DIGEST_PATTERN = /^sha256:[0-9a-f]{64}$/;\nconst SHA256_HEX_PATTERN = /^[0-9a-f]{64}$/;\n\nconst ENDED_WITHOUT_RECEIPT = new Set([\"failed\", \"cancelled\", \"abandoned\", \"expired\"]);\n\n/** Whether an import is executing: requested (`planned` at stage `reserve`), running, or verifying. */\nexport function isExecuting(operation: Pick<TransferOperation, \"state\" | \"stage\">): boolean {\n\treturn (\n\t\toperation.state === \"running\" ||\n\t\toperation.state === \"verifying\" ||\n\t\t(operation.state === \"planned\" && operation.stage === \"reserve\")\n\t);\n}\n\n/** Normalize a plan digest given as `sha256:<hex>` or bare hex. */\nexport function normalizePlanDigest(value: string): string {\n\tconst trimmed = value.trim().toLowerCase();\n\tif (SHA256_DIGEST_PATTERN.test(trimmed)) return trimmed;\n\tif (SHA256_HEX_PATTERN.test(trimmed)) return `sha256:${trimmed}`;\n\tthrow new SiteTransferCliError(\n\t\t\"INVALID_ARGUMENT\",\n\t\t\"--plan must be a plan digest like sha256:<64 hex characters>\",\n\t);\n}\n\n// ── Finding or creating the import ─────────────────────────────\n\nasync function findImportByDigest(\n\tclient: EmDashClient,\n\tdigest: string,\n\truntime: TransferRuntime,\n): Promise<TransferOperation | null> {\n\tlet cursor: string | undefined;\n\tfor (let page = 0; page < IMPORT_LOOKUP_PAGES; page++) {\n\t\tconst result = await withRetry(runtime, \"Listing imports\", () =>\n\t\t\tclient.transferImportList({ limit: 100, cursor }),\n\t\t);\n\t\tconst match = result.items.find((item) => item.packageDigest === digest);\n\t\tif (match) return ENDED_WITHOUT_RECEIPT.has(match.state) ? null : match;\n\t\tif (!result.nextCursor) return null;\n\t\tcursor = result.nextCursor;\n\t}\n\treturn null;\n}\n\n/** Import states that keep blocking site writes once the import has written. */\nconst BLOCKING_AFTER_WRITE = new Set([\"failed\", \"cancelled\"]);\n\nfunction occupiesTarget(operation: TransferOperation): boolean {\n\tif (!ENDED_WITHOUT_RECEIPT.has(operation.state) && operation.state !== \"complete\") return true;\n\treturn operation.mutationStartedAt !== null && BLOCKING_AFTER_WRITE.has(operation.state);\n}\n\n/**\n * When the site refuses a new import because an earlier import wrote to it\n * and then stopped, say which import and what to do about it; otherwise\n * return `error` unchanged.\n */\nasync function explainOccupiedTarget(\n\tclient: EmDashClient,\n\terror: unknown,\n\truntime: TransferRuntime,\n): Promise<unknown> {\n\tif (\n\t\t!(error instanceof EmDashApiError) ||\n\t\t(error.code !== \"TRANSFER_TARGET_NOT_EMPTY\" && error.code !== \"TRANSFER_IMPORT_IN_PROGRESS\")\n\t) {\n\t\treturn error;\n\t}\n\tconst { items } = await withRetry(runtime, \"Listing imports\", () =>\n\t\tclient.transferImportList({ limit: 100 }),\n\t).catch(() => ({ items: [] as TransferOperation[] }));\n\tconst occupying = items.find(occupiesTarget);\n\tif (occupying) {\n\t\tif (!BLOCKING_AFTER_WRITE.has(occupying.state)) return error;\n\t\tconst ended = occupying.state === \"failed\" ? \"failed\" : \"was cancelled\";\n\t\treturn new SiteTransferCliError(\n\t\t\terror.code,\n\t\t\t`Import ${occupying.id} ${ended} after it started writing, so this site holds partial data from it and blocks writes. Abandon it with \\`emdash site import abandon ${occupying.id}\\`, then reset this site or set up a new one before importing again.`,\n\t\t\t{ operationId: occupying.id, state: occupying.state },\n\t\t);\n\t}\n\tconst abandoned = items.find(\n\t\t(item) => item.state === \"abandoned\" && item.mutationStartedAt !== null,\n\t);\n\tif (error.code === \"TRANSFER_TARGET_NOT_EMPTY\" && abandoned) {\n\t\treturn new SiteTransferCliError(\n\t\t\terror.code,\n\t\t\t`Import ${abandoned.id} wrote partial data to this site before it was abandoned. Reset this site or set up a new one before importing again.`,\n\t\t\t{ operationId: abandoned.id, state: abandoned.state },\n\t\t);\n\t}\n\treturn error;\n}\n\nexport interface OpenedImport {\n\toperation: TransferOperation;\n\t/** True when every package file still has to be uploaded. */\n\tfresh: boolean;\n}\n\n/**\n * Find the import of this package on the target, or create it. An earlier\n * import of the same package that ended without a receipt is left alone and\n * a new one is started.\n */\nexport async function openImport(\n\tclient: EmDashClient,\n\tscan: ScannedSitePackage,\n\truntime: TransferRuntime,\n): Promise<OpenedImport> {\n\tconst existing = await findImportByDigest(client, scan.packageDigest, runtime);\n\tif (existing) {\n\t\truntime.reporter.info(`Resuming import ${existing.id} (${existing.state})`);\n\t\treturn { operation: existing, fresh: false };\n\t}\n\tconst create = (idempotencyKey: string) =>\n\t\twithRetry(runtime, \"Creating the import\", () =>\n\t\t\tclient.transferImportCreate(scan.manifestBytes, { idempotencyKey }),\n\t\t).catch(async (error: unknown) => {\n\t\t\tthrow await explainOccupiedTarget(client, error, runtime);\n\t\t});\n\tlet created = await create(scan.packageDigest);\n\tif (ENDED_WITHOUT_RECEIPT.has(created.operation.state)) {\n\t\truntime.reporter.warn(\n\t\t\t`An earlier import of this package (${created.operation.id}) ended as ${created.operation.state}; starting a new one.`,\n\t\t);\n\t\tcreated = await create(`${scan.packageDigest}/${Date.now().toString(36)}`);\n\t}\n\truntime.reporter.info(\n\t\t`${created.created ? \"Created\" : \"Resuming\"} import ${created.operation.id} (${created.operation.state})`,\n\t);\n\treturn { operation: created.operation, fresh: created.created };\n}\n\n// ── Uploading ──────────────────────────────────────────────────\n\nasync function listMissing(\n\tclient: EmDashClient,\n\toperationId: string,\n\truntime: TransferRuntime,\n): Promise<TransferPackageFile[]> {\n\tconst files: TransferPackageFile[] = [];\n\tlet cursor: string | undefined;\n\tdo {\n\t\tconst page = await withRetry(runtime, \"Listing missing files\", () =>\n\t\t\tclient.transferImportMissing(operationId, { limit: MISSING_PAGE, cursor }),\n\t\t);\n\t\tfiles.push(...page.items);\n\t\tcursor = page.nextCursor;\n\t} while (cursor);\n\treturn files;\n}\n\nclass UploadPool {\n\tprivate readonly inFlight = new Set<Promise<void>>();\n\tprivate bytes = 0;\n\tprivate failure: unknown;\n\n\tconstructor(\n\t\tprivate readonly concurrency: number,\n\t\tprivate readonly maxBytes: number,\n\t) {}\n\n\tasync add(size: number, task: () => Promise<void>): Promise<void> {\n\t\twhile (\n\t\t\tthis.inFlight.size > 0 &&\n\t\t\t(this.inFlight.size >= this.concurrency || this.bytes + size > this.maxBytes)\n\t\t) {\n\t\t\tawait Promise.race(this.inFlight);\n\t\t}\n\t\tthis.rethrow();\n\t\tthis.bytes += size;\n\t\tconst promise: Promise<void> = task()\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tthis.failure ??= error;\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tthis.bytes -= size;\n\t\t\t\tthis.inFlight.delete(promise);\n\t\t\t});\n\t\tthis.inFlight.add(promise);\n\t}\n\n\tasync drain(): Promise<void> {\n\t\tawait Promise.all(this.inFlight);\n\t\tthis.rethrow();\n\t}\n\n\t/** Wait for uploads in flight without surfacing their failures. */\n\tasync settle(): Promise<void> {\n\t\tawait Promise.allSettled(this.inFlight);\n\t}\n\n\tprivate rethrow(): void {\n\t\tif (this.failure !== undefined) throw this.failure;\n\t}\n}\n\nexport interface UploadSummary {\n\tuploaded: number;\n\tbytes: number;\n}\n\n/**\n * Upload every package file the import has not verified yet. Index chunks go\n * first because uploading one declares the files it lists; a file whose\n * index chunk is not uploaded yet waits for the next pass over the archive.\n */\nexport async function uploadPackage(\n\tclient: EmDashClient,\n\tarchivePath: string,\n\tscan: ScannedSitePackage,\n\toperation: OpenedImport,\n\truntime: TransferRuntime,\n): Promise<UploadSummary> {\n\tconst operationId = operation.operation.id;\n\tconst progress = createProgressLogger(runtime);\n\tconst summary: UploadSummary = { uploaded: 0, bytes: 0 };\n\tlet pending: Set<string> | null = operation.fresh ? new Set(scan.files.keys()) : null;\n\n\tfor (;;) {\n\t\tif (!pending) {\n\t\t\tconst missing = await listMissing(client, operationId, runtime);\n\t\t\tfor (const file of missing) {\n\t\t\t\tconst local = scan.files.get(file.path);\n\t\t\t\tif (!local) {\n\t\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\t\"TRANSFER_FILE_MISSING\",\n\t\t\t\t\t\t`The site expects ${file.path}, which is not in this package file`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (local.bytes !== file.bytes || local.sha256 !== file.sha256) {\n\t\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\t\"TRANSFER_FILE_DIGEST_MISMATCH\",\n\t\t\t\t\t\t`The site expects different contents for ${file.path}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tpending = new Set(missing.map((file) => file.path));\n\t\t\tfor (const file of missing) {\n\t\t\t\tfor (const path of scan.indexEntries.get(file.path) ?? []) pending.add(path);\n\t\t\t}\n\t\t}\n\t\tif (pending.size === 0) return summary;\n\n\t\tconst total = pending.size;\n\t\tconst uploadedIndexes = new Set<string>();\n\t\tconst pool = new UploadPool(UPLOAD_CONCURRENCY, UPLOAD_BUFFER_BYTES);\n\t\tlet passUploaded = 0;\n\t\tconst upload = async (path: string, bytes: Uint8Array) => {\n\t\t\tawait withRetry(runtime, `Uploading ${path}`, () =>\n\t\t\t\tclient.transferImportUploadFile(operationId, path, bytes, bytes.byteLength),\n\t\t\t);\n\t\t\tpassUploaded++;\n\t\t\tsummary.uploaded++;\n\t\t\tsummary.bytes += bytes.byteLength;\n\t\t\tprogress(\n\t\t\t\t\"Uploading\",\n\t\t\t\t`${passUploaded}/${total} files (${formatBytes(summary.bytes)} this run)`,\n\t\t\t);\n\t\t};\n\n\t\tconst passPending = pending;\n\t\ttry {\n\t\t\tawait unpackSitePackage(openArchive(archivePath), async (file) => {\n\t\t\t\tif (!passPending.has(file.path)) return;\n\t\t\t\tconst index = scan.indexOf.get(file.path);\n\t\t\t\tif (index && passPending.has(index) && !uploadedIndexes.has(index)) return;\n\t\t\t\tconst expected = scan.files.get(file.path);\n\t\t\t\tif (!expected) return;\n\t\t\t\tconst bytes = await readBody(file.body);\n\t\t\t\tawait assertFileMatches(file.path, bytes, expected);\n\t\t\t\tif (file.parsed.type === \"index\") {\n\t\t\t\t\tawait upload(file.path, bytes);\n\t\t\t\t\tuploadedIndexes.add(file.path);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tawait pool.add(bytes.byteLength, () => upload(file.path, bytes));\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tawait pool.settle();\n\t\t\tthrow error;\n\t\t}\n\t\tawait pool.drain();\n\n\t\tif (passUploaded === 0) {\n\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\"TRANSFER_FILE_MISSING\",\n\t\t\t\t\"The site still expects files that could not be uploaded from this package\",\n\t\t\t);\n\t\t}\n\t\tpending = null;\n\t}\n}\n\n// ── Analysis ───────────────────────────────────────────────────\n\nexport interface PlannedImport {\n\toperation: TransferOperation;\n\tplan: SiteImportPlan;\n\tplanDigest: string;\n}\n\n/** Advance analysis until the import is planned. */\nexport async function driveAnalysis(\n\tclient: EmDashClient,\n\toperation: TransferOperation,\n\truntime: TransferRuntime,\n): Promise<PlannedImport> {\n\tconst progress = createProgressLogger(runtime);\n\tfor (;;) {\n\t\tconst step = await withRetry(runtime, \"Analysis step\", () =>\n\t\t\tclient.transferImportAnalyze(operation.id),\n\t\t).catch(async (error: unknown) => {\n\t\t\tif (error instanceof EmDashApiError && error.code === \"TRANSFER_INVALID_STATE\") {\n\t\t\t\tconst { operation: current } = await client.transferImportGet(operation.id);\n\t\t\t\tif (ENDED_WITHOUT_RECEIPT.has(current.state)) throw operationError(current);\n\t\t\t}\n\t\t\tthrow error;\n\t\t});\n\t\tconst current = step.operation;\n\t\tif (step.nextRequestInMs === null) {\n\t\t\tif (current.state !== \"planned\" || !step.plan || !step.planDigest) {\n\t\t\t\tthrow operationError(current);\n\t\t\t}\n\t\t\treturn { operation: current, plan: step.plan, planDigest: step.planDigest };\n\t\t}\n\t\tprogress(`Analyzing (${current.stage ?? current.state})`, formatProgress(current.progress));\n\t\tawait sleepFor(runtime, step.nextRequestInMs);\n\t}\n}\n\n/** Submit decisions for a planned import; returns the resulting plan. */\nexport async function applyDecisions(\n\tclient: EmDashClient,\n\toperationId: string,\n\tdecisions: SiteImportDecisionsInput,\n\truntime: TransferRuntime,\n): Promise<PlannedImport> {\n\tconst decided = await withRetry(runtime, \"Applying decisions\", () =>\n\t\tclient.transferImportAnalyze(operationId, decisions),\n\t);\n\tif (!decided.plan || !decided.planDigest) throw operationError(decided.operation);\n\treturn { operation: decided.operation, plan: decided.plan, planDigest: decided.planDigest };\n}\n\n// ── Decisions from flags ───────────────────────────────────────\n\nexport interface DecisionFlags {\n\t/** Raw `--map-principal` values: `<principal id|email>=<user id|email|none>`. */\n\tmapPrincipal: string[];\n\tuseTargetTitle: boolean;\n\tuseTargetTagline: boolean;\n}\n\nexport function hasDecisions(flags: DecisionFlags): boolean {\n\treturn flags.mapPrincipal.length > 0 || flags.useTargetTitle || flags.useTargetTagline;\n}\n\nconst USER_PAGES = 50;\n\nasync function targetUsersByEmail(\n\tclient: EmDashClient,\n\truntime: TransferRuntime,\n): Promise<Map<string, string[]>> {\n\tconst byEmail = new Map<string, string[]>();\n\tlet cursor: string | undefined;\n\tfor (let page = 0; page < USER_PAGES; page++) {\n\t\tconst result = await withRetry(runtime, \"Listing users\", () =>\n\t\t\tclient.users({ limit: 100, cursor }),\n\t\t);\n\t\tfor (const user of result.items) {\n\t\t\tconst key = user.email.toLowerCase();\n\t\t\tbyEmail.set(key, [...(byEmail.get(key) ?? []), user.id]);\n\t\t}\n\t\tif (!result.nextCursor) break;\n\t\tcursor = result.nextCursor;\n\t}\n\treturn byEmail;\n}\n\n/**\n * Turn decision flags into plan decisions. Principals are matched by id, or\n * by email (case-insensitive); target users by id, by email through the\n * users API, or `none` to leave the references unassigned.\n */\nexport async function resolveDecisions(\n\tclient: EmDashClient,\n\tplan: SiteImportPlan,\n\tflags: DecisionFlags,\n\truntime: TransferRuntime,\n): Promise<SiteImportDecisionsInput> {\n\tconst decisions: SiteImportDecisionsInput = {};\n\tif (flags.useTargetTitle) decisions.siteTitle = \"target\";\n\tif (flags.useTargetTagline) decisions.siteTagline = \"target\";\n\tif (flags.mapPrincipal.length === 0) return decisions;\n\n\tlet users: Map<string, string[]> | undefined;\n\tconst mappings: Record<string, string | null> = {};\n\tfor (const raw of flags.mapPrincipal) {\n\t\tconst separator = raw.lastIndexOf(\"=\");\n\t\tconst from = separator > 0 ? raw.slice(0, separator).trim() : \"\";\n\t\tconst to = separator > 0 ? raw.slice(separator + 1).trim() : \"\";\n\t\tif (!from || !to) {\n\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t`--map-principal expects <principal id or email>=<user id, email, or none>, got \"${raw}\"`,\n\t\t\t);\n\t\t}\n\t\tconst principal =\n\t\t\tplan.principals.find((candidate) => candidate.id === from) ??\n\t\t\tmatchOne(\n\t\t\t\tplan.principals.filter(\n\t\t\t\t\t(candidate) => candidate.email?.toLowerCase() === from.toLowerCase(),\n\t\t\t\t),\n\t\t\t\t`principal ${from}`,\n\t\t\t);\n\t\tif (!principal) {\n\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t`The package has no principal ${from}. Principals: ${plan.principals.map((p) => p.id).join(\", \") || \"none\"}`,\n\t\t\t);\n\t\t}\n\n\t\tlet target: string | null;\n\t\tif (to.toLowerCase() === \"none\") {\n\t\t\ttarget = null;\n\t\t} else if (to.includes(\"@\")) {\n\t\t\tusers ??= await targetUsersByEmail(client, runtime);\n\t\t\tconst ids = users.get(to.toLowerCase()) ?? [];\n\t\t\tif (ids.length !== 1) {\n\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t\tids.length === 0\n\t\t\t\t\t\t? `No user on this site has the email ${to}`\n\t\t\t\t\t\t: `More than one user on this site has the email ${to}; map by user id instead`,\n\t\t\t\t);\n\t\t\t}\n\t\t\ttarget = ids[0];\n\t\t} else {\n\t\t\ttarget = to;\n\t\t}\n\t\tmappings[principal.id] = target;\n\t}\n\tdecisions.principalMappings = mappings;\n\treturn decisions;\n}\n\nfunction matchOne<T>(matches: T[], label: string): T | undefined {\n\tif (matches.length > 1) {\n\t\tthrow new SiteTransferCliError(\n\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t`More than one ${label} matches; map by principal id instead`,\n\t\t);\n\t}\n\treturn matches[0];\n}\n\n// ── Execution ──────────────────────────────────────────────────\n\nexport interface CompletedImport {\n\toperationId: string;\n\tstate: \"complete\";\n\treceipt: SiteImportReceipt;\n\treceiptDigestValid: boolean;\n}\n\n/** Advance an executing import until it ends; returns the complete operation. */\nexport async function driveExecution(\n\tclient: EmDashClient,\n\toperation: TransferOperation,\n\truntime: TransferRuntime,\n): Promise<TransferOperation> {\n\tconst progress = createProgressLogger(runtime);\n\tlet current = operation;\n\twhile (isExecuting(current)) {\n\t\tconst step = await withRetry(runtime, \"Import step\", () =>\n\t\t\tclient.transferImportAdvance(current.id),\n\t\t);\n\t\tcurrent = step.operation;\n\t\tprogress(`Importing (${current.stage ?? current.state})`, formatProgress(current.progress));\n\t\tif (step.nextRequestInMs === null) break;\n\t\tawait sleepFor(runtime, step.nextRequestInMs);\n\t}\n\tif (current.state !== \"complete\") throw operationError(current);\n\treturn current;\n}\n\nexport async function fetchReceipt(\n\tclient: EmDashClient,\n\toperationId: string,\n\truntime: TransferRuntime,\n): Promise<CompletedImport> {\n\tconst { receipt } = await withRetry(runtime, \"Reading the receipt\", () =>\n\t\tclient.transferImportReceipt(operationId),\n\t);\n\treturn {\n\t\toperationId,\n\t\tstate: \"complete\",\n\t\treceipt,\n\t\treceiptDigestValid: await verifyReceiptDigest(receipt),\n\t};\n}\n\n/**\n * Execute a planned import after checking the reviewed plan digest, then\n * advance it to completion.\n */\nexport async function executeImport(\n\tclient: EmDashClient,\n\toperation: TransferOperation,\n\tplanDigest: string,\n\truntime: TransferRuntime,\n): Promise<CompletedImport> {\n\tlet current = operation;\n\tif (current.planDigest !== planDigest) {\n\t\tthrow new SiteTransferCliError(\n\t\t\t\"TRANSFER_PLAN_DIGEST_MISMATCH\",\n\t\t\t`The plan changed since it was reviewed: the current plan digest is ${current.planDigest ?? \"none\"}. Run with --analyze again and confirm the new digest.`,\n\t\t);\n\t}\n\tif (current.state === \"planned\" && current.stage !== \"reserve\") {\n\t\tif (!current.packageDigest) throw operationError(current);\n\t\tconst packageDigest = current.packageDigest;\n\t\tcurrent = (\n\t\t\tawait withRetry(runtime, \"Starting the import\", () =>\n\t\t\t\tclient.transferImportExecute(current.id, { packageDigest, planDigest }),\n\t\t\t)\n\t\t).operation;\n\t\truntime.reporter.info(`Executing import ${current.id}`);\n\t}\n\tconst complete = await driveExecution(client, current, runtime);\n\treturn fetchReceipt(client, complete.id, runtime);\n}\n\n// ── Commands ───────────────────────────────────────────────────\n\nexport interface AnalyzeOutcome extends PlannedImport {\n\tpackageDigest: string;\n}\n\n/** Scan, upload, and analyze a package, applying any decisions. */\nexport async function analyzePackage(\n\tclient: EmDashClient,\n\tarchivePath: string,\n\tflags: DecisionFlags,\n\truntime: TransferRuntime,\n): Promise<AnalyzeOutcome | CompletedImport | { operation: TransferOperation }> {\n\tconst { scan, opened } = await prepareImport(client, archivePath, runtime);\n\treturn continueToPlan(client, archivePath, scan, opened, flags, runtime);\n}\n\nasync function prepareImport(\n\tclient: EmDashClient,\n\tarchivePath: string,\n\truntime: TransferRuntime,\n): Promise<{ scan: ScannedSitePackage; opened: OpenedImport }> {\n\truntime.reporter.info(`Verifying ${archivePath}`);\n\tconst scan = await scanSitePackage(archivePath);\n\truntime.reporter.info(\n\t\t`Package ${scan.packageDigest}: ${scan.files.size + 1} files, ${formatBytes(scan.totalBytes)}`,\n\t);\n\tconst opened = await openImport(client, scan, runtime);\n\treturn { scan, opened };\n}\n\nasync function continueToPlan(\n\tclient: EmDashClient,\n\tarchivePath: string | null,\n\tscan: ScannedSitePackage | null,\n\topened: OpenedImport,\n\tflags: DecisionFlags,\n\truntime: TransferRuntime,\n): Promise<AnalyzeOutcome | CompletedImport | { operation: TransferOperation }> {\n\tconst operation = opened.operation;\n\tif (isExecuting(operation)) return { operation };\n\tswitch (operation.state) {\n\t\tcase \"uploading\": {\n\t\t\tif (!archivePath || !scan) {\n\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\"PACKAGE_FILE_REQUIRED\",\n\t\t\t\t\t`Import ${operation.id} is still uploading. Pass the package file to resume it: emdash site import resume ${operation.id} <file>`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst uploaded = await uploadPackage(client, archivePath, scan, opened, runtime);\n\t\t\truntime.reporter.info(`Uploaded ${uploaded.uploaded} files (${formatBytes(uploaded.bytes)})`);\n\t\t\treturn planWithDecisions(client, operation, flags, runtime);\n\t\t}\n\t\tcase \"analyzing\":\n\t\tcase \"planned\":\n\t\t\treturn planWithDecisions(client, operation, flags, runtime);\n\t\tcase \"complete\":\n\t\t\truntime.reporter.info(`Import ${operation.id} is already complete`);\n\t\t\treturn fetchReceipt(client, operation.id, runtime);\n\t\tdefault:\n\t\t\treturn { operation };\n\t}\n}\n\nasync function planWithDecisions(\n\tclient: EmDashClient,\n\toperation: TransferOperation,\n\tflags: DecisionFlags,\n\truntime: TransferRuntime,\n): Promise<AnalyzeOutcome> {\n\tlet planned = await driveAnalysis(client, operation, runtime);\n\tif (hasDecisions(flags)) {\n\t\tconst decisions = await resolveDecisions(client, planned.plan, flags, runtime);\n\t\tplanned = await applyDecisions(client, planned.operation.id, decisions, runtime);\n\t}\n\treturn { ...planned, packageDigest: planned.plan.packageDigest };\n}\n\n/** Scan, upload, and analyze if needed, then execute the confirmed plan. */\nexport async function confirmPackage(\n\tclient: EmDashClient,\n\tarchivePath: string,\n\tplanDigest: string,\n\truntime: TransferRuntime,\n): Promise<CompletedImport> {\n\tconst { scan, opened } = await prepareImport(client, archivePath, runtime);\n\treturn confirmOperation(client, archivePath, scan, opened, planDigest, runtime);\n}\n\nasync function confirmOperation(\n\tclient: EmDashClient,\n\tarchivePath: string | null,\n\tscan: ScannedSitePackage | null,\n\topened: OpenedImport,\n\tplanDigest: string,\n\truntime: TransferRuntime,\n): Promise<CompletedImport> {\n\tconst operation = opened.operation;\n\tif (operation.state === \"complete\") {\n\t\tif (operation.planDigest !== planDigest) {\n\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\"TRANSFER_PLAN_DIGEST_MISMATCH\",\n\t\t\t\t`Import ${operation.id} already completed with a different plan (${operation.planDigest ?? \"none\"})`,\n\t\t\t);\n\t\t}\n\t\treturn fetchReceipt(client, operation.id, runtime);\n\t}\n\tif (isExecuting(operation)) {\n\t\treturn executeImport(client, operation, planDigest, runtime);\n\t}\n\tconst outcome = await continueToPlan(\n\t\tclient,\n\t\tarchivePath,\n\t\tscan,\n\t\topened,\n\t\t{ mapPrincipal: [], useTargetTitle: false, useTargetTagline: false },\n\t\truntime,\n\t);\n\tif (!(\"plan\" in outcome)) {\n\t\tif (\"receipt\" in outcome) return outcome;\n\t\tthrow operationError(outcome.operation);\n\t}\n\tif (outcome.plan.blockers.length > 0) {\n\t\tthrow new SiteTransferCliError(\n\t\t\t\"TRANSFER_PLAN_BLOCKED\",\n\t\t\t`The import plan has ${outcome.plan.blockers.length} blocker(s). Run with --analyze to see them.`,\n\t\t);\n\t}\n\treturn executeImport(client, outcome.operation, planDigest, runtime);\n}\n\nexport async function importStatus(\n\tclient: EmDashClient,\n\toperationId: string,\n\truntime: TransferRuntime,\n): Promise<{ operation: TransferOperation; files: { declared: number; verified: number } }> {\n\treturn withRetry(runtime, \"Reading the import\", () => client.transferImportGet(operationId));\n}\n\n/**\n * Continue an import from whatever state it is in: upload what is missing\n * (needs the package file), finish analysis, or finish execution.\n */\nexport async function resumeImport(\n\tclient: EmDashClient,\n\toperationId: string,\n\tarchivePath: string | null,\n\truntime: TransferRuntime,\n): Promise<AnalyzeOutcome | CompletedImport | { operation: TransferOperation }> {\n\tconst { operation } = await importStatus(client, operationId, runtime);\n\tif (isExecuting(operation)) {\n\t\tconst complete = await driveExecution(client, operation, runtime);\n\t\treturn fetchReceipt(client, complete.id, runtime);\n\t}\n\tlet scan: ScannedSitePackage | null = null;\n\tif (operation.state === \"uploading\" && archivePath) {\n\t\truntime.reporter.info(`Verifying ${archivePath}`);\n\t\tscan = await scanSitePackage(archivePath);\n\t\tif (scan.packageDigest !== operation.packageDigest) {\n\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\"TRANSFER_PACKAGE_DIGEST_MISMATCH\",\n\t\t\t\t`${archivePath} is not the package import ${operation.id} was created from`,\n\t\t\t);\n\t\t}\n\t}\n\treturn continueToPlan(\n\t\tclient,\n\t\tarchivePath,\n\t\tscan,\n\t\t{ operation, fresh: false },\n\t\t{ mapPrincipal: [], useTargetTitle: false, useTargetTagline: false },\n\t\truntime,\n\t);\n}\n\nexport async function importReceipt(\n\tclient: EmDashClient,\n\toperationId: string,\n\truntime: TransferRuntime,\n): Promise<CompletedImport> {\n\treturn fetchReceipt(client, operationId, runtime);\n}\n\n/**\n * Resolve a refused cancel or abandon: a retry of a request whose response\n * was lost finds the import already in `state`.\n */\nasync function settledAs(\n\tclient: EmDashClient,\n\toperationId: string,\n\terror: unknown,\n\tstate: \"cancelled\" | \"abandoned\",\n\truntime: TransferRuntime,\n): Promise<TransferOperation> {\n\tif (!(error instanceof EmDashApiError) || error.code !== \"TRANSFER_INVALID_STATE\") throw error;\n\tconst { operation } = await importStatus(client, operationId, runtime);\n\tif (operation.state === state) return operation;\n\tthrow new SiteTransferCliError(\n\t\t\"TRANSFER_INVALID_STATE\",\n\t\tstate === \"abandoned\"\n\t\t\t? `Only a failed or cancelled import can be abandoned; import ${operationId} is ${operation.state}.`\n\t\t\t: `Import ${operationId} has already ended as ${operation.state}.`,\n\t);\n}\n\n/**\n * Cancel an import. An import no request is working on is cancelled at\n * once; one mid-step stops after its current batch.\n */\nexport async function cancelImport(\n\tclient: EmDashClient,\n\toperationId: string,\n\truntime: TransferRuntime,\n): Promise<TransferOperation> {\n\treturn withRetry(runtime, \"Cancelling the import\", () =>\n\t\tclient.transferImportCancel(operationId),\n\t).then(\n\t\t(result) => result.operation,\n\t\t(error: unknown) => settledAs(client, operationId, error, \"cancelled\", runtime),\n\t);\n}\n\n/** Abandon a failed or cancelled import: lift its write block, keeping what it wrote. */\nexport async function abandonImport(\n\tclient: EmDashClient,\n\toperationId: string,\n\truntime: TransferRuntime,\n): Promise<TransferOperation> {\n\treturn withRetry(runtime, \"Abandoning the import\", () =>\n\t\tclient.transferImportAbandon(operationId),\n\t).then(\n\t\t(result) => result.operation,\n\t\t(error: unknown) => settledAs(client, operationId, error, \"abandoned\", runtime),\n\t);\n}\n","/**\n * emdash site\n *\n * Export a whole site to a portable `.emdash` package, and import one into an\n * empty site.\n */\n\nimport { resolve } from \"node:path\";\nimport { createInterface } from \"node:readline/promises\";\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\n\nimport type { SiteImportPlan, TransferOperation } from \"../../client/index.js\";\nimport { connectionArgs, createClientFromArgs, resolveBaseUrl } from \"../client-factory.js\";\nimport { configureOutputMode, output } from \"../output.js\";\nimport { runSiteExport } from \"../site/export.js\";\nimport {\n\tabandonImport,\n\tanalyzePackage,\n\tcancelImport,\n\tconfirmPackage,\n\timportReceipt,\n\timportStatus,\n\tisExecuting,\n\tnormalizePlanDigest,\n\tresumeImport,\n\ttype AnalyzeOutcome,\n\ttype CompletedImport,\n\ttype DecisionFlags,\n} from \"../site/import.js\";\nimport {\n\tdescribeError,\n\tformatBytes,\n\tformatProgress,\n\tSiteTransferCliError,\n\ttransformationLabel,\n\ttype TransferRuntime,\n} from \"../site/shared.js\";\n\n/** Exit status when analysis produced a plan with blockers. */\nexport const EXIT_PLAN_BLOCKED = 2;\n\nconst IMPORT_ACTIONS = new Set([\"status\", \"resume\", \"receipt\", \"cancel\", \"abandon\"]);\n\n/** Import states `import status` reports with exit status 1. */\nconst UNSUCCESSFUL_STATES = new Set([\"failed\", \"cancelled\", \"abandoned\", \"expired\"]);\n\ninterface OutputArgs {\n\tjson?: boolean;\n}\n\nfunction wantsJson(args: OutputArgs): boolean {\n\treturn Boolean(args.json) || !process.stdout.isTTY;\n}\n\nfunction runtimeFor(): TransferRuntime {\n\tconst progress = consola.create({ stdout: process.stderr, stderr: process.stderr });\n\treturn {\n\t\treporter: {\n\t\t\tinfo: (message) => progress.info(message),\n\t\t\twarn: (message) => progress.warn(message),\n\t\t},\n\t};\n}\n\nasync function confirmOnTerminal(question: string): Promise<boolean> {\n\tconst prompt = createInterface({ input: process.stdin, output: process.stderr });\n\ttry {\n\t\tconst answer = (await prompt.question(`${question} [y/N] `)).trim().toLowerCase();\n\t\treturn answer === \"y\" || answer === \"yes\";\n\t} finally {\n\t\tprompt.close();\n\t}\n}\n\n/**\n * Ask before a cancel or abandon unless `--yes` or JSON output was chosen.\n * Without a terminal to ask on, the command needs `--yes`.\n */\nasync function confirmed(\n\targs: OutputArgs & { yes?: boolean },\n\taction: string,\n\toperationId: string,\n\tquestion: string,\n): Promise<boolean> {\n\tif (args.yes || wantsJson(args)) return true;\n\tif (!process.stdin.isTTY) {\n\t\tthrow new SiteTransferCliError(\n\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t`Pass --yes to ${action} import ${operationId} without a confirmation prompt`,\n\t\t);\n\t}\n\treturn confirmOnTerminal(question);\n}\n\nfunction fail(error: unknown, args: OutputArgs): void {\n\tconst info = describeError(error);\n\tif (wantsJson(args)) {\n\t\toutput({ error: info }, args);\n\t} else {\n\t\tconsola.error(info.message);\n\t}\n\tprocess.exitCode = 1;\n}\n\n/** Every value of a repeatable string flag, from the raw arguments. */\nexport function collectFlag(rawArgs: readonly string[], name: string): string[] {\n\tconst values: string[] = [];\n\tfor (let i = 0; i < rawArgs.length; i++) {\n\t\tconst arg = rawArgs[i];\n\t\tif (arg === `--${name}`) {\n\t\t\tconst next = rawArgs[i + 1];\n\t\t\tif (next !== undefined && !next.startsWith(\"--\")) {\n\t\t\t\tvalues.push(next);\n\t\t\t\ti++;\n\t\t\t} else {\n\t\t\t\tthrow new SiteTransferCliError(\"INVALID_ARGUMENT\", `--${name} needs a value`);\n\t\t\t}\n\t\t} else if (arg.startsWith(`--${name}=`)) {\n\t\t\tvalues.push(arg.slice(name.length + 3));\n\t\t}\n\t}\n\treturn values;\n}\n\n// ── Output shapes ──────────────────────────────────────────────\n\nexport function planJson(outcome: AnalyzeOutcome) {\n\treturn {\n\t\toperationId: outcome.operation.id,\n\t\tstate: outcome.operation.state,\n\t\tpackageDigest: outcome.packageDigest,\n\t\tplanDigest: outcome.planDigest,\n\t\texecutable: outcome.plan.blockers.length === 0,\n\t\tplan: outcome.plan,\n\t};\n}\n\nexport function operationJson(operation: TransferOperation) {\n\treturn { operationId: operation.id, state: operation.state, operation };\n}\n\nfunction printPlan(outcome: AnalyzeOutcome, archivePath: string | null): void {\n\tconst { plan } = outcome;\n\tconsola.log(`Import ${outcome.operation.id}`);\n\tconsola.log(` Package digest: ${outcome.packageDigest}`);\n\tconsola.log(` Plan digest: ${outcome.planDigest}`);\n\tconsola.log(\n\t\t` Origin: site ${plan.origin.siteId}, exported ${plan.origin.createdAt} by EmDash ${plan.origin.createdByEmDashVersion}`,\n\t);\n\tconst counts = Object.entries(plan.counts)\n\t\t.map(([kind, count]) => `${kind} ${count}`)\n\t\t.join(\", \");\n\tconsola.log(` Records: ${counts || \"none\"}`);\n\tconsola.log(\n\t\t` Size: records ${formatBytes(plan.bytes.records)}, media ${formatBytes(plan.bytes.media)}`,\n\t);\n\tprintSetting(\"Site title\", plan.settings.title, plan.decisions.siteTitle);\n\tprintSetting(\"Tagline\", plan.settings.tagline, plan.decisions.siteTagline);\n\n\tif (plan.principals.length > 0) {\n\t\tconsola.log(\" Principals (package users; map them with --map-principal <id>=<user|none>):\");\n\t\tfor (const principal of plan.principals) {\n\t\t\tconst mapped = plan.decisions.principalMappings[principal.id];\n\t\t\tconst target = mapped ? `user ${mapped}` : \"unassigned\";\n\t\t\tconst suggested =\n\t\t\t\tprincipal.suggestedUserId && principal.suggestedUserId !== mapped\n\t\t\t\t\t? `, suggested user ${principal.suggestedUserId}`\n\t\t\t\t\t: \"\";\n\t\t\tconst email = principal.email ? ` <${principal.email}>` : \"\";\n\t\t\tconsola.log(\n\t\t\t\t` ${principal.id} ${principal.displayName}${email}, ${principal.references} references -> ${target}${suggested}`,\n\t\t\t);\n\t\t}\n\t}\n\tprintTransformations(plan.transformations);\n\tprintIssues(\"Warnings\", plan.warnings);\n\tprintIssues(\"Blockers\", plan.blockers);\n\n\tif (plan.blockers.length > 0) {\n\t\tconsola.error(`The plan has ${plan.blockers.length} blocker(s); it cannot be executed.`);\n\t\treturn;\n\t}\n\tconst file = archivePath ?? \"<file>\";\n\tconsola.success(\n\t\t`Ready. To import, run:\\n emdash site import ${file} --plan ${outcome.planDigest} --confirm`,\n\t);\n}\n\nfunction printSetting(\n\tlabel: string,\n\tvalues: SiteImportPlan[\"settings\"][\"title\"],\n\tchoice: \"package\" | \"target\",\n): void {\n\tconst value = choice === \"package\" ? values.package : values.target;\n\tconsola.log(\n\t\t` ${`${label}:`.padEnd(16)}${JSON.stringify(value ?? \"\")} (from the ${choice}; package ${JSON.stringify(values.package ?? \"\")}, this site ${JSON.stringify(values.target ?? \"\")})`,\n\t);\n}\n\n/** Every declared difference from the source site, one line per code. */\nfunction printTransformations(transformations: SiteImportPlan[\"transformations\"]): void {\n\tconst groups = new Map<string, { count: number; kinds: Set<string>; details: string[] }>();\n\tfor (const transformation of transformations) {\n\t\tconst group = groups.get(transformation.code) ?? {\n\t\t\tcount: 0,\n\t\t\tkinds: new Set<string>(),\n\t\t\tdetails: [],\n\t\t};\n\t\tif (\"count\" in transformation) group.count += transformation.count;\n\t\telse if (\"ids\" in transformation) group.count += transformation.ids.length;\n\t\telse group.count += transformation.locales.length;\n\t\tif (\"kind\" in transformation) group.kinds.add(transformation.kind);\n\t\tif (\"locales\" in transformation) {\n\t\t\tfor (const { from, to } of transformation.locales) group.details.push(`${from} -> ${to}`);\n\t\t}\n\t\tif (\"items\" in transformation) {\n\t\t\tconst types = new Map<string, number>();\n\t\t\tfor (const item of transformation.items)\n\t\t\t\ttypes.set(item.type, (types.get(item.type) ?? 0) + 1);\n\t\t\tgroup.details.push(Array.from(types, ([type, count]) => `${type} ${count}`).join(\", \"));\n\t\t}\n\t\tgroups.set(transformation.code, group);\n\t}\n\tif (groups.size === 0) return;\n\tconsola.log(` Differences from the source site (${groups.size}):`);\n\tfor (const [code, group] of groups) {\n\t\tconst kinds = group.kinds.size > 0 ? ` [${[...group.kinds].join(\", \")}]` : \"\";\n\t\tconsola.log(` ${code}${kinds} x${group.count}: ${transformationLabel(code)}`);\n\t\tfor (const detail of group.details) consola.log(` ${detail}`);\n\t}\n}\n\nfunction printIssues(\n\tlabel: string,\n\tissues: ReadonlyArray<{ code: string; message: string; kind?: string; count?: number }>,\n): void {\n\tif (issues.length === 0) return;\n\tconsola.log(` ${label} (${issues.length}):`);\n\tfor (const issue of issues) {\n\t\tconst where = issue.kind ? ` [${issue.kind}]` : \"\";\n\t\tconst count = issue.count !== undefined ? ` x${issue.count}` : \"\";\n\t\tconsola.log(` ${issue.code}${where}${count}: ${issue.message}`);\n\t}\n}\n\nfunction printReceipt(result: CompletedImport): void {\n\tconst { receipt } = result;\n\tconsola.success(`Import ${result.operationId} is complete and verified.`);\n\tconsola.log(\n\t\t` Receipt digest: ${receipt.receiptDigest}${result.receiptDigestValid ? \"\" : \" (INVALID)\"}`,\n\t);\n\tconsola.log(` Package digest: ${receipt.packageDigest}`);\n\tconsola.log(` Plan digest: ${receipt.planDigest}`);\n\tconsola.log(` Logical digest: ${receipt.logicalDigest}`);\n\tconsola.log(` Completed: ${receipt.completedAt}`);\n\tconst counts = Object.entries(receipt.counts)\n\t\t.map(([kind, count]) => `${kind} ${count}`)\n\t\t.join(\", \");\n\tconsola.log(` Counts: ${counts || \"none\"}`);\n\tfor (const warning of receipt.warnings) consola.warn(`${warning.code}: ${warning.message}`);\n}\n\nfunction printOperation(\n\toperation: TransferOperation,\n\tfiles?: { declared: number; verified: number },\n): void {\n\tconsola.log(\n\t\t`Import ${operation.id}: ${operation.state}${operation.stage ? ` (${operation.stage})` : \"\"}`,\n\t);\n\tconst progress = formatProgress(operation.progress);\n\tif (progress) consola.log(` Progress: ${progress}`);\n\tif (files)\n\t\tconsola.log(` Files: ${files.verified} uploaded, ${files.declared} still missing`);\n\tif (operation.packageDigest) consola.log(` Package digest: ${operation.packageDigest}`);\n\tif (operation.planDigest) consola.log(` Plan digest: ${operation.planDigest}`);\n\tif (operation.errorCode) {\n\t\tconsola.warn(\n\t\t\t` Error: ${operation.errorCode}${operation.errorDetail ? ` ${JSON.stringify(operation.errorDetail)}` : \"\"}`,\n\t\t);\n\t}\n\tif (blocksWritesUntilAbandoned(operation)) {\n\t\tconsola.info(\n\t\t\t`It wrote to this site before it stopped, so site writes stay blocked until you abandon it: emdash site import abandon ${operation.id}`,\n\t\t);\n\t}\n}\n\nfunction blocksWritesUntilAbandoned(operation: TransferOperation): boolean {\n\treturn (\n\t\toperation.mutationStartedAt !== null &&\n\t\t(operation.state === \"failed\" || operation.state === \"cancelled\")\n\t);\n}\n\nfunction printCancelled(operation: TransferOperation): void {\n\tif (operation.state !== \"cancelled\") {\n\t\tconsola.success(\n\t\t\t`Cancellation requested. Import ${operation.id} stops after its current batch; check it with: emdash site import status ${operation.id}`,\n\t\t);\n\t\treturn;\n\t}\n\tconsola.success(`Import ${operation.id} is cancelled.`);\n\tif (blocksWritesUntilAbandoned(operation)) {\n\t\tconsola.info(\n\t\t\t`It had started writing to this site. The data it wrote stays, and site writes stay blocked until you abandon it: emdash site import abandon ${operation.id}`,\n\t\t);\n\t} else {\n\t\tconsola.info(\"It had not written anything to this site.\");\n\t}\n}\n\nfunction printAbandoned(operation: TransferOperation): void {\n\tconsola.success(`Import ${operation.id} is abandoned. The site accepts writes again.`);\n\tif (operation.mutationStartedAt !== null) {\n\t\tconsola.info(\n\t\t\t\"Data the import already wrote was not removed. Reset this site or set up a new one before importing again.\",\n\t\t);\n\t}\n}\n\n/** Print whatever an import command ended with and set the exit status. */\nfunction report(\n\toutcome: AnalyzeOutcome | CompletedImport | { operation: TransferOperation },\n\targs: OutputArgs,\n\tarchivePath: string | null,\n): void {\n\tif (\"receipt\" in outcome) {\n\t\tif (wantsJson(args)) output(outcome, args);\n\t\telse printReceipt(outcome);\n\t\tif (!outcome.receiptDigestValid) process.exitCode = 1;\n\t\treturn;\n\t}\n\tif (\"plan\" in outcome) {\n\t\tif (wantsJson(args)) output(planJson(outcome), args);\n\t\telse printPlan(outcome, archivePath);\n\t\tif (outcome.plan.blockers.length > 0) process.exitCode = EXIT_PLAN_BLOCKED;\n\t\treturn;\n\t}\n\tif (wantsJson(args)) {\n\t\toutput(operationJson(outcome.operation), args);\n\t} else {\n\t\tprintOperation(outcome.operation);\n\t\tif (isExecuting(outcome.operation)) {\n\t\t\tconsola.info(`Continue it with: emdash site import resume ${outcome.operation.id}`);\n\t\t}\n\t}\n\tif (!isExecuting(outcome.operation)) process.exitCode = 1;\n}\n\n// ── Commands ───────────────────────────────────────────────────\n\nconst exportCommand = defineCommand({\n\tmeta: {\n\t\tname: \"export\",\n\t\tdescription: \"Export the whole site to a .emdash package file\",\n\t},\n\targs: {\n\t\t...connectionArgs,\n\t\toutput: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"o\",\n\t\t\tdescription: \"Package file to write (e.g. site.emdash)\",\n\t\t\trequired: true,\n\t\t},\n\t\tcomments: {\n\t\t\ttype: \"boolean\",\n\t\t\tdefault: true,\n\t\t\tdescription: \"Include comments and reactions (--no-comments leaves them out)\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst result = await runSiteExport(\n\t\t\t\t{\n\t\t\t\t\tclient,\n\t\t\t\t\tbaseUrl: resolveBaseUrl(args),\n\t\t\t\t\toutputPath: resolve(args.output),\n\t\t\t\t\tcomments: args.comments !== false,\n\t\t\t\t},\n\t\t\t\truntimeFor(),\n\t\t\t);\n\t\t\tif (wantsJson(args)) {\n\t\t\t\toutput(result, args);\n\t\t\t} else {\n\t\t\t\tconsola.success(\n\t\t\t\t\t`Exported ${result.files} files (${formatBytes(result.bytes)}) to ${result.output}`,\n\t\t\t\t);\n\t\t\t\tconsola.log(` Package digest: ${result.packageDigest}`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tfail(error, args);\n\t\t}\n\t},\n});\n\nconst importCommand = defineCommand({\n\tmeta: {\n\t\tname: \"import\",\n\t\tdescription: [\n\t\t\t\"Import a .emdash package into an empty site: `import <file> --analyze`, then `import <file> --plan <digest> --confirm`.\",\n\t\t\t\"Manage an import with `import status|resume|receipt|cancel|abandon <operation-id>`. `cancel` stops the import after its current batch. `abandon` lifts the write block that a failed or cancelled import leaves on the site; it does not delete what the import wrote.\",\n\t\t\t\"Exit codes: 0 success, and for `status` an import in progress or complete; 1 an error, a declined prompt, or for `status` an import that failed, was cancelled or abandoned, or expired; 2 the import plan has blockers.\",\n\t\t].join(\"\\n\\n\"),\n\t},\n\targs: {\n\t\ttarget: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Package file, or status | resume | receipt | cancel | abandon\",\n\t\t\trequired: true,\n\t\t},\n\t\t...connectionArgs,\n\t\tanalyze: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Upload and analyze the package, then print the import plan\",\n\t\t},\n\t\t\"map-principal\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription:\n\t\t\t\t\"With --analyze: map a package user to a site user, <principal id|email>=<user id|email|none> (repeatable)\",\n\t\t},\n\t\t\"use-target-title\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"With --analyze: keep this site's title instead of the package's\",\n\t\t},\n\t\t\"use-target-tagline\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"With --analyze: keep this site's tagline instead of the package's\",\n\t\t},\n\t\tplan: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Plan digest printed by --analyze; required with --confirm\",\n\t\t},\n\t\tconfirm: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Execute the import plan given by --plan\",\n\t\t},\n\t\tyes: {\n\t\t\ttype: \"boolean\",\n\t\t\talias: \"y\",\n\t\t\tdescription: \"With cancel or abandon: skip the confirmation prompt\",\n\t\t},\n\t},\n\tasync run({ args, rawArgs }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst positionals = args._.map(String);\n\t\t\tconst action = IMPORT_ACTIONS.has(args.target) ? args.target : null;\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst runtime = runtimeFor();\n\n\t\t\tif (action) {\n\t\t\t\tconst operationId = positionals[1];\n\t\t\t\tif (!operationId) {\n\t\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t\t\t`Usage: emdash site import ${action} <operation-id>`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (action === \"status\") {\n\t\t\t\t\tconst status = await importStatus(client, operationId, runtime);\n\t\t\t\t\tif (wantsJson(args)) output(status, args);\n\t\t\t\t\telse printOperation(status.operation, status.files);\n\t\t\t\t\tif (UNSUCCESSFUL_STATES.has(status.operation.state)) process.exitCode = 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"cancel\" || action === \"abandon\") {\n\t\t\t\t\tconst question =\n\t\t\t\t\t\taction === \"cancel\"\n\t\t\t\t\t\t\t? `Cancel import ${operationId}? A running import stops after its current batch. Anything it already wrote stays on the site.`\n\t\t\t\t\t\t\t: `Abandon import ${operationId}? Site writes are unblocked, but data the import already wrote is not deleted.`;\n\t\t\t\t\tif (!(await confirmed(args, action, operationId, question))) {\n\t\t\t\t\t\tconsola.info(\"Nothing was changed.\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst operation =\n\t\t\t\t\t\taction === \"cancel\"\n\t\t\t\t\t\t\t? await cancelImport(client, operationId, runtime)\n\t\t\t\t\t\t\t: await abandonImport(client, operationId, runtime);\n\t\t\t\t\tif (wantsJson(args)) output(operationJson(operation), args);\n\t\t\t\t\telse if (action === \"cancel\") printCancelled(operation);\n\t\t\t\t\telse printAbandoned(operation);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"receipt\") {\n\t\t\t\t\treport(await importReceipt(client, operationId, runtime), args, null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst archive = positionals[2] ? resolve(positionals[2]) : null;\n\t\t\t\treport(await resumeImport(client, operationId, archive, runtime), args, archive);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst archivePath = resolve(args.target);\n\t\t\tconst mapPrincipal = collectFlag(rawArgs, \"map-principal\");\n\t\t\tconst flags: DecisionFlags = {\n\t\t\t\tmapPrincipal,\n\t\t\t\tuseTargetTitle: Boolean(args[\"use-target-title\"]),\n\t\t\t\tuseTargetTagline: Boolean(args[\"use-target-tagline\"]),\n\t\t\t};\n\t\t\tif (args.confirm && !args.plan) {\n\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t\t\"--confirm needs --plan <digest>: review the plan with --analyze first\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (args.plan && !args.confirm) {\n\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t\t\"--plan executes an import only together with --confirm\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (args.plan && args.analyze) {\n\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t\t\"Use either --analyze or --plan <digest> --confirm, not both\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (args.plan) {\n\t\t\t\tif (mapPrincipal.length > 0 || flags.useTargetTitle || flags.useTargetTagline) {\n\t\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t\t\t\"Decisions can only be changed with --analyze; they change the plan digest\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst planDigest = normalizePlanDigest(args.plan);\n\t\t\t\treport(await confirmPackage(client, archivePath, planDigest, runtime), args, archivePath);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!args.analyze) {\n\t\t\t\tthrow new SiteTransferCliError(\n\t\t\t\t\t\"INVALID_ARGUMENT\",\n\t\t\t\t\t\"Choose --analyze to review the import plan, or --plan <digest> --confirm to run it\",\n\t\t\t\t);\n\t\t\t}\n\t\t\treport(await analyzePackage(client, archivePath, flags, runtime), args, archivePath);\n\t\t} catch (error) {\n\t\t\tfail(error, args);\n\t\t}\n\t},\n});\n\nexport const siteCommand = defineCommand({\n\tmeta: {\n\t\tname: \"site\",\n\t\tdescription: \"Export or import a whole site as a .emdash package\",\n\t},\n\tsubCommands: {\n\t\texport: exportCommand,\n\t\timport: importCommand,\n\t},\n});\n","/**\n * emdash taxonomy\n *\n * Manage taxonomies and terms via the EmDash REST API.\n */\n\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\n\nimport { connectionArgs, createClientFromArgs } from \"../client-factory.js\";\nimport { configureOutputMode, output } from \"../output.js\";\n\n/** Pattern to replace whitespace with hyphens for slug generation */\nconst WHITESPACE_PATTERN = /\\s+/g;\n\nconst listCommand = defineCommand({\n\tmeta: {\n\t\tname: \"list\",\n\t\tdescription: \"List all taxonomies\",\n\t},\n\targs: {\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst taxonomies = await client.taxonomies();\n\t\t\toutput(taxonomies, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst termsCommand = defineCommand({\n\tmeta: {\n\t\tname: \"terms\",\n\t\tdescription: \"List terms in a taxonomy\",\n\t},\n\targs: {\n\t\tname: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Taxonomy name\",\n\t\t\trequired: true,\n\t\t},\n\t\tlimit: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"l\",\n\t\t\tdescription: \"Maximum terms to return\",\n\t\t},\n\t\tcursor: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Pagination cursor\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst result = await client.terms(args.name, {\n\t\t\t\tlimit: args.limit ? parseInt(args.limit, 10) : undefined,\n\t\t\t\tcursor: args.cursor,\n\t\t\t});\n\t\t\toutput(result, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nconst addTermCommand = defineCommand({\n\tmeta: {\n\t\tname: \"add-term\",\n\t\tdescription: \"Create a term in a taxonomy\",\n\t},\n\targs: {\n\t\ttaxonomy: {\n\t\t\ttype: \"positional\",\n\t\t\tdescription: \"Taxonomy name\",\n\t\t\trequired: true,\n\t\t},\n\t\tname: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Term label\",\n\t\t\trequired: true,\n\t\t},\n\t\tslug: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Term slug (defaults to slugified name)\",\n\t\t},\n\t\tparent: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Parent term ID\",\n\t\t},\n\t\t...connectionArgs,\n\t},\n\tasync run({ args }) {\n\t\tconfigureOutputMode(args);\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\t\t\tconst label = args.name;\n\t\t\tconst slug = args.slug || label.toLowerCase().replace(WHITESPACE_PATTERN, \"-\");\n\t\t\tconst term = await client.createTerm(args.taxonomy, {\n\t\t\t\tslug,\n\t\t\t\tlabel,\n\t\t\t\tparentId: args.parent,\n\t\t\t});\n\t\t\tconsola.success(`Created term \"${label}\" in ${args.taxonomy}`);\n\t\t\toutput(term, args);\n\t\t} catch (error) {\n\t\t\tconsola.error(error instanceof Error ? error.message : \"Unknown error\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n\nexport const taxonomyCommand = defineCommand({\n\tmeta: {\n\t\tname: \"taxonomy\",\n\t\tdescription: \"Manage taxonomies and terms\",\n\t},\n\tsubCommands: {\n\t\tlist: listCommand,\n\t\tterms: termsCommand,\n\t\t\"add-term\": addTermCommand,\n\t},\n});\n","/**\n * emdash types\n *\n * Fetch schema from an EmDash instance and generate TypeScript types\n */\n\nimport { writeFile, mkdir } from \"node:fs/promises\";\nimport { resolve, dirname } from \"node:path\";\n\nimport { defineCommand } from \"citty\";\nimport consola from \"consola\";\n\nimport { connectionArgs, createClientFromArgs } from \"../client-factory.js\";\n\nexport const typesCommand = defineCommand({\n\tmeta: {\n\t\tname: \"types\",\n\t\tdescription: \"Generate TypeScript types from schema\",\n\t},\n\targs: {\n\t\t...connectionArgs,\n\t\toutput: {\n\t\t\ttype: \"string\",\n\t\t\talias: \"o\",\n\t\t\tdescription: \"Output path for generated types\",\n\t\t\tdefault: \".emdash/types.ts\",\n\t\t},\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Working directory\",\n\t\t\tdefault: process.cwd(),\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst cwd = resolve(args.cwd);\n\t\tconsola.start(\"Fetching schema...\");\n\n\t\ttry {\n\t\t\tconst client = createClientFromArgs(args);\n\n\t\t\t// Fetch JSON schema\n\t\t\tconst schema = await client.schemaExport();\n\t\t\tconsola.success(`Found ${schema.collections.length} collections`);\n\n\t\t\t// Fetch TypeScript types\n\t\t\tconst types = await client.schemaTypes();\n\n\t\t\t// Write types file\n\t\t\tconst outputPath = resolve(cwd, args.output);\n\t\t\tawait mkdir(dirname(outputPath), { recursive: true });\n\t\t\tawait writeFile(outputPath, types, \"utf-8\");\n\t\t\tconsola.success(`Generated ${args.output}`);\n\n\t\t\t// Also write a schema.json for reference\n\t\t\tconst schemaJsonPath = resolve(dirname(outputPath), \"schema.json\");\n\t\t\tawait writeFile(schemaJsonPath, JSON.stringify(schema, null, 2), \"utf-8\");\n\t\t\tconsola.info(`Schema version: ${schema.version}`);\n\n\t\t\tconsola.box({\n\t\t\t\ttitle: \"Types generated\",\n\t\t\t\tmessage: `${schema.collections.length} collections\\n\\nTypes: ${args.output}\\nSchema: .emdash/schema.json`,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsola.error(\"Failed to fetch schema:\", error instanceof Error ? error.message : error);\n\t\t\tprocess.exit(1);\n\t\t}\n\t},\n});\n","#!/usr/bin/env node\n\nimport { defineCommand, runMain } from \"citty\";\n\nimport { authCommand } from \"./commands/auth.js\";\nimport { contentCommand } from \"./commands/content.js\";\nimport { devCommand } from \"./commands/dev.js\";\nimport { doctorCommand } from \"./commands/doctor.js\";\nimport { exportSeedCommand } from \"./commands/export-seed.js\";\nimport { initCommand } from \"./commands/init.js\";\nimport { loginCommand, logoutCommand, whoamiCommand } from \"./commands/login.js\";\nimport { mediaCommand } from \"./commands/media.js\";\nimport { menuCommand } from \"./commands/menu.js\";\nimport { migrateCommand } from \"./commands/migrate.js\";\nimport { pluginCommand } from \"./commands/plugin.js\";\nimport { schemaCommand } from \"./commands/schema.js\";\nimport { searchCommand } from \"./commands/search-cmd.js\";\nimport { secretsCommand } from \"./commands/secrets.js\";\nimport { seedCommand } from \"./commands/seed.js\";\nimport { siteCommand } from \"./commands/site.js\";\nimport { taxonomyCommand } from \"./commands/taxonomy.js\";\nimport { typesCommand } from \"./commands/types.js\";\n\nconst main = defineCommand({\n\tmeta: {\n\t\tname: \"emdash\",\n\t\tversion: \"0.0.0\",\n\t\tdescription: \"CLI for EmDash CMS\",\n\t},\n\tsubCommands: {\n\t\tinit: initCommand,\n\t\ttypes: typesCommand,\n\t\tdev: devCommand,\n\t\tdoctor: doctorCommand,\n\t\tseed: seedCommand,\n\t\tmigrate: migrateCommand,\n\t\t\"export-seed\": exportSeedCommand,\n\t\tsecrets: secretsCommand,\n\t\t// Deprecated alias kept for backwards compat; will be removed in a future minor.\n\t\tauth: authCommand,\n\t\tlogin: loginCommand,\n\t\tlogout: logoutCommand,\n\t\twhoami: whoamiCommand,\n\t\tcontent: contentCommand,\n\t\tschema: schemaCommand,\n\t\tmedia: mediaCommand,\n\t\tsearch: searchCommand,\n\t\ttaxonomy: taxonomyCommand,\n\t\tmenu: menuCommand,\n\t\tplugin: pluginCommand,\n\t\tsite: siteCommand,\n\t},\n});\n\nvoid runMain(main);\n"],"mappings":"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"}