@tokenoftrust/storefront-runner 2.0.2 → 2.0.4

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 (254) hide show
  1. package/apps/storefront/.astro/content.d.ts +159 -0
  2. package/apps/storefront/.astro/integrations/_astrojs_cloudflare/cloudflare.d.ts +1 -0
  3. package/apps/storefront/.astro/types.d.ts +3 -0
  4. package/apps/storefront/node_modules/.bin/acorn +43 -0
  5. package/apps/storefront/node_modules/.bin/astro +43 -0
  6. package/apps/storefront/node_modules/.bin/astro-check +43 -0
  7. package/apps/storefront/node_modules/.bin/browserslist +43 -0
  8. package/apps/storefront/node_modules/.bin/cf-wrangler +43 -0
  9. package/apps/storefront/node_modules/.bin/depcruise +43 -0
  10. package/apps/storefront/node_modules/.bin/depcruise-baseline +43 -0
  11. package/apps/storefront/node_modules/.bin/depcruise-fmt +43 -0
  12. package/apps/storefront/node_modules/.bin/depcruise-wrap-stream-in-html +43 -0
  13. package/apps/storefront/node_modules/.bin/dependency-cruise +43 -0
  14. package/apps/storefront/node_modules/.bin/dependency-cruiser +43 -0
  15. package/apps/storefront/node_modules/.bin/drizzle-kit +43 -0
  16. package/apps/storefront/node_modules/.bin/esbuild +43 -0
  17. package/apps/storefront/node_modules/.bin/jiti +43 -0
  18. package/apps/storefront/node_modules/.bin/playwright +43 -0
  19. package/apps/storefront/node_modules/.bin/playwright-core +43 -0
  20. package/apps/storefront/node_modules/.bin/prettier +43 -0
  21. package/apps/storefront/node_modules/.bin/rollup +43 -0
  22. package/apps/storefront/node_modules/.bin/tsc +43 -0
  23. package/apps/storefront/node_modules/.bin/tsserver +43 -0
  24. package/apps/storefront/node_modules/.bin/tsx +43 -0
  25. package/apps/storefront/node_modules/.bin/vite +43 -0
  26. package/apps/storefront/node_modules/.bin/vitest +43 -0
  27. package/apps/storefront/node_modules/.bin/workerd +43 -0
  28. package/apps/storefront/node_modules/.bin/wrangler +43 -0
  29. package/apps/storefront/node_modules/.bin/wrangler2 +43 -0
  30. package/apps/storefront/node_modules/.bin/yaml +43 -0
  31. package/apps/storefront/node_modules/.vite/deps/@astrojs_preact_client__js.js +58 -0
  32. package/apps/storefront/node_modules/.vite/deps/@astrojs_preact_client__js.js.map +1 -0
  33. package/apps/storefront/node_modules/.vite/deps/@astrojs_preact_n_@preact_signals.js +741 -0
  34. package/apps/storefront/node_modules/.vite/deps/@astrojs_preact_n_@preact_signals.js.map +1 -0
  35. package/apps/storefront/node_modules/.vite/deps/@astrojs_preact_server__js.js +2549 -0
  36. package/apps/storefront/node_modules/.vite/deps/@astrojs_preact_server__js.js.map +1 -0
  37. package/apps/storefront/node_modules/.vite/deps/_metadata.json +150 -0
  38. package/apps/storefront/node_modules/.vite/deps/astro-BIHuWFxm.js +434 -0
  39. package/apps/storefront/node_modules/.vite/deps/astro-BIHuWFxm.js.map +1 -0
  40. package/apps/storefront/node_modules/.vite/deps/astro_n_aria-query.js +6390 -0
  41. package/apps/storefront/node_modules/.vite/deps/astro_n_aria-query.js.map +1 -0
  42. package/apps/storefront/node_modules/.vite/deps/astro_n_axobject-query.js +2705 -0
  43. package/apps/storefront/node_modules/.vite/deps/astro_n_axobject-query.js.map +1 -0
  44. package/apps/storefront/node_modules/.vite/deps/astro_n_html-escaper.js +65 -0
  45. package/apps/storefront/node_modules/.vite/deps/astro_n_html-escaper.js.map +1 -0
  46. package/apps/storefront/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +455 -0
  47. package/apps/storefront/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +1 -0
  48. package/apps/storefront/node_modules/.vite/deps/audit-DKDpcdEI.js +1535 -0
  49. package/apps/storefront/node_modules/.vite/deps/audit-DKDpcdEI.js.map +1 -0
  50. package/apps/storefront/node_modules/.vite/deps/highlight-B9UoX1wa.js +48 -0
  51. package/apps/storefront/node_modules/.vite/deps/highlight-B9UoX1wa.js.map +1 -0
  52. package/apps/storefront/node_modules/.vite/deps/icons-BWi2wI9n.js +42 -0
  53. package/apps/storefront/node_modules/.vite/deps/icons-BWi2wI9n.js.map +1 -0
  54. package/apps/storefront/node_modules/.vite/deps/package.json +3 -0
  55. package/apps/storefront/node_modules/.vite/deps/preact.js +310 -0
  56. package/apps/storefront/node_modules/.vite/deps/preact.js.map +1 -0
  57. package/apps/storefront/node_modules/.vite/deps/preact_compat.js +420 -0
  58. package/apps/storefront/node_modules/.vite/deps/preact_compat.js.map +1 -0
  59. package/apps/storefront/node_modules/.vite/deps/preact_compat_jsx-runtime.js +4 -0
  60. package/apps/storefront/node_modules/.vite/deps/preact_debug.js +236 -0
  61. package/apps/storefront/node_modules/.vite/deps/preact_debug.js.map +1 -0
  62. package/apps/storefront/node_modules/.vite/deps/preact_devtools.js +12 -0
  63. package/apps/storefront/node_modules/.vite/deps/preact_devtools.js.map +1 -0
  64. package/apps/storefront/node_modules/.vite/deps/preact_hooks.js +192 -0
  65. package/apps/storefront/node_modules/.vite/deps/preact_hooks.js.map +1 -0
  66. package/apps/storefront/node_modules/.vite/deps/preact_jsx-dev-runtime.js +3 -0
  67. package/apps/storefront/node_modules/.vite/deps/preact_jsx-runtime.js +92 -0
  68. package/apps/storefront/node_modules/.vite/deps/preact_jsx-runtime.js.map +1 -0
  69. package/apps/storefront/node_modules/.vite/deps/preact_test-utils.js +59 -0
  70. package/apps/storefront/node_modules/.vite/deps/preact_test-utils.js.map +1 -0
  71. package/apps/storefront/node_modules/.vite/deps/rolldown-runtime-BPOCksWG.js +24 -0
  72. package/apps/storefront/node_modules/.vite/deps/settings-BVDV0Roj.js +189 -0
  73. package/apps/storefront/node_modules/.vite/deps/settings-BVDV0Roj.js.map +1 -0
  74. package/apps/storefront/node_modules/.vite/deps/static-html-DveYqwMo.js +13 -0
  75. package/apps/storefront/node_modules/.vite/deps/static-html-DveYqwMo.js.map +1 -0
  76. package/apps/storefront/node_modules/.vite/deps/toolbar-B3VIHCXg.js +458 -0
  77. package/apps/storefront/node_modules/.vite/deps/toolbar-B3VIHCXg.js.map +1 -0
  78. package/apps/storefront/node_modules/.vite/deps/ui-library-BK6ricUd.js +1016 -0
  79. package/apps/storefront/node_modules/.vite/deps/ui-library-BK6ricUd.js.map +1 -0
  80. package/apps/storefront/node_modules/.vite/deps/window-BvxDenKN.js +32 -0
  81. package/apps/storefront/node_modules/.vite/deps/window-BvxDenKN.js.map +1 -0
  82. package/apps/storefront/node_modules/.vite/deps/xray-YFiRUU0Z.js +113 -0
  83. package/apps/storefront/node_modules/.vite/deps/xray-YFiRUU0Z.js.map +1 -0
  84. package/apps/storefront/node_modules/.vite/deps_ssr/_metadata.json +8 -0
  85. package/apps/storefront/node_modules/.vite/deps_ssr/package.json +3 -0
  86. package/apps/storefront/src/layouts/Layout.astro +1 -1
  87. package/apps/storefront/src/lib/apps/registryAccess.ts +45 -0
  88. package/apps/storefront/src/lib/auth/adminEntry.ts +4 -4
  89. package/apps/storefront/src/lib/shared/capability.ts +68 -0
  90. package/apps/storefront/src/lib/shared/developerInvites.ts +1250 -0
  91. package/apps/storefront/src/lib/shared/invitePreflight.ts +123 -0
  92. package/apps/storefront/src/lib/webhooks/deliveryEngine.ts +38 -4
  93. package/apps/storefront/src/lib/webhooks/emit.ts +1 -1
  94. package/apps/storefront/src/lib/webhooks/getDispatcher.ts +1 -1
  95. package/apps/storefront/src/pages/api/auth/magic-exchange.ts +1 -1
  96. package/apps/storefront/src/pages/index.astro +1 -1
  97. package/apps/storefront/src/pages/products/[handle].astro +1 -1
  98. package/package.json +1 -1
  99. package/packages/public-runtime/node_modules/.bin/tsc +43 -0
  100. package/packages/public-runtime/node_modules/.bin/tsserver +43 -0
  101. package/packages/public-runtime/node_modules/.bin/vitest +43 -0
  102. package/pnpm-workspace.yaml +3 -0
  103. package/scripts/lib/tenant-dirs.mjs +80 -0
  104. package/scripts/tenant/lint-embeds.mjs +180 -0
  105. package/scripts/tenant/materialize-tenant-content.mjs +533 -0
  106. package/scripts/tenant/validate.mjs +837 -0
  107. package/apps/storefront/scripts/build-v84-clean-clone-standalone.mjs +0 -68
  108. package/apps/storefront/scripts/deny-v84-clean-clone-standalone-capabilities.mjs +0 -111
  109. package/apps/storefront/scripts/deny-v84-dogfood-capabilities.mjs +0 -2
  110. package/apps/storefront/scripts/deny-v84-lifecycle-capabilities.mjs +0 -247
  111. package/apps/storefront/scripts/dogfood-v84-nonportable-routes.ts +0 -73
  112. package/apps/storefront/scripts/fixed-v84-native-install-producer.ts +0 -79
  113. package/apps/storefront/scripts/generated/v84-clean-clone-replay.bundle.mjs +0 -10982
  114. package/apps/storefront/scripts/import-v84-through-ws2.ts +0 -38
  115. package/apps/storefront/scripts/initialize-v84-lifecycle-tooling-dependency.ts +0 -2
  116. package/apps/storefront/scripts/initialize-v84-lifecycle-tooling.ts +0 -4
  117. package/apps/storefront/scripts/install-v84-native-through-ws1.ts +0 -185
  118. package/apps/storefront/scripts/prove-clone-isolation.ts +0 -506
  119. package/apps/storefront/scripts/replay-v84-clean-clone-pass.ts +0 -148
  120. package/apps/storefront/scripts/replay-v84-clean-clone-standalone.ts +0 -35
  121. package/apps/storefront/scripts/replay-v84-clean-clone.ts +0 -214
  122. package/apps/storefront/scripts/run-fixed-v84-native-install-producer.mjs +0 -18
  123. package/apps/storefront/scripts/run-v84-clone-isolation-proof.mjs +0 -18
  124. package/apps/storefront/scripts/run-v84-clone-lifecycle-proof.mjs +0 -18
  125. package/apps/storefront/scripts/run-v84-import-through-ws2-proof.mjs +0 -17
  126. package/apps/storefront/scripts/run-v84-nonportable-route-dogfood.mjs +0 -15
  127. package/apps/storefront/scripts/sanitize-v84-proof-environment.mjs +0 -21
  128. package/apps/storefront/scripts/v84CleanCloneGraphPin.ts +0 -42
  129. package/apps/storefront/scripts/v84CleanCloneSourceGraph.ts +0 -145
  130. package/apps/storefront/scripts/validate-v84-clone-lifecycle.ts +0 -18
  131. package/apps/storefront/src/components/admin/AdminAIWorkflowsTab.astro +0 -531
  132. package/apps/storefront/src/components/admin/AdminBlogDetailRail.astro +0 -878
  133. package/apps/storefront/src/components/admin/AdminBlogTab.astro +0 -1435
  134. package/apps/storefront/src/components/admin/AdminCheckoutSettingsPanel.astro +0 -226
  135. package/apps/storefront/src/components/admin/AdminCustomersTab.astro +0 -593
  136. package/apps/storefront/src/components/admin/AdminFulfillmentTab.astro +0 -465
  137. package/apps/storefront/src/components/admin/AdminIntegrationsTab.astro +0 -105
  138. package/apps/storefront/src/components/admin/AdminProductsTab.astro +0 -901
  139. package/apps/storefront/src/components/admin/AdminPublishTab.astro +0 -2983
  140. package/apps/storefront/src/components/admin/AdminReportingTab.astro +0 -435
  141. package/apps/storefront/src/components/admin/AdminSettingsTab.astro +0 -782
  142. package/apps/storefront/src/components/admin/AdminSubscriptionsTab.astro +0 -611
  143. package/apps/storefront/src/components/admin/orders/OrdersWorkspace.astro +0 -1223
  144. package/apps/storefront/src/lib/apps/adminService.ts +0 -116
  145. package/apps/storefront/src/lib/apps/adminSession.ts +0 -214
  146. package/apps/storefront/src/lib/apps/apiAuth.ts +0 -91
  147. package/apps/storefront/src/lib/apps/apiRoute.ts +0 -35
  148. package/apps/storefront/src/lib/apps/catalogMapper.ts +0 -39
  149. package/apps/storefront/src/lib/apps/consentConfigStore.ts +0 -228
  150. package/apps/storefront/src/lib/apps/gtmMigrationInstall.ts +0 -447
  151. package/apps/storefront/src/lib/apps/gtmMigrationReport.ts +0 -367
  152. package/apps/storefront/src/lib/apps/gtmMigrationTab.ts +0 -315
  153. package/apps/storefront/src/lib/apps/healthAggregate.ts +0 -66
  154. package/apps/storefront/src/lib/apps/integrationLifecycle.ts +0 -614
  155. package/apps/storefront/src/lib/apps/integrationLifecycleController.ts +0 -125
  156. package/apps/storefront/src/lib/apps/integrationReadModel.ts +0 -563
  157. package/apps/storefront/src/lib/apps/integrationsTab.ts +0 -547
  158. package/apps/storefront/src/lib/apps/integrationsView.ts +0 -106
  159. package/apps/storefront/src/lib/apps/managedAnalyticsService.ts +0 -599
  160. package/apps/storefront/src/lib/apps/tenantIntegrationMaterialization.ts +0 -170
  161. package/apps/storefront/src/lib/apps/tokenIssuer.ts +0 -121
  162. package/apps/storefront/src/lib/apps/tokenVerifier.ts +0 -148
  163. package/apps/storefront/src/lib/apps/v84CleanCloneReplayContext.ts +0 -16
  164. package/apps/storefront/src/lib/apps/v84CloneLifecycleCacheEvidence.ts +0 -105
  165. package/apps/storefront/src/lib/apps/v84CloneLifecycleEvidence.ts +0 -177
  166. package/apps/storefront/src/lib/apps/v84CloneLifecycleMaterialization.ts +0 -251
  167. package/apps/storefront/src/lib/apps/v84CloneLifecycleSemantics.ts +0 -241
  168. package/apps/storefront/src/lib/apps/v84CloneMigrationEvidence.ts +0 -211
  169. package/apps/storefront/src/lib/apps/v84CloneNativeInstallEvidence.ts +0 -409
  170. package/apps/storefront/src/lib/apps/v84NonportableCodeCoaching.ts +0 -368
  171. package/apps/storefront/src/lib/apps/v84NonportableRouteContract.ts +0 -188
  172. package/apps/storefront/src/lib/apps/v84NonportableRouteDogfood.ts +0 -291
  173. package/apps/storefront/src/lib/apps/ws1ManagedAnalyticsClient.ts +0 -95
  174. package/apps/storefront/src/lib/content-edit/applyDiff.ts +0 -91
  175. package/apps/storefront/src/lib/content-edit/client.ts +0 -286
  176. package/apps/storefront/src/lib/content-edit/index.ts +0 -14
  177. package/apps/storefront/src/lib/content-edit/route.ts +0 -25
  178. package/apps/storefront/src/lib/content-edit/types.ts +0 -19
  179. package/apps/storefront/src/lib/dev/cockpitStore.ts +0 -57
  180. package/apps/storefront/src/lib/publish/adminPublishTab.ts +0 -4625
  181. package/apps/storefront/src/lib/publish/apex-readiness.ts +0 -360
  182. package/apps/storefront/src/lib/publish/buildStream.ts +0 -269
  183. package/apps/storefront/src/lib/publish/collapsePersistence.ts +0 -72
  184. package/apps/storefront/src/lib/publish/dispatchHealth.ts +0 -267
  185. package/apps/storefront/src/lib/publish/domainState.ts +0 -360
  186. package/apps/storefront/src/lib/publish/lifecycleState.ts +0 -369
  187. package/apps/storefront/src/lib/publish/liveReleaseSummary.ts +0 -29
  188. package/apps/storefront/src/lib/publish/mergeDoctorOnFailure.ts +0 -78
  189. package/apps/storefront/src/lib/publish/mergeHealthBanner.ts +0 -62
  190. package/apps/storefront/src/lib/publish/mergeRowFindings.ts +0 -124
  191. package/apps/storefront/src/lib/publish/mergeSupportEscalation.ts +0 -75
  192. package/apps/storefront/src/lib/publish/panelPolling.ts +0 -78
  193. package/apps/storefront/src/lib/publish/publish-guard.ts +0 -88
  194. package/apps/storefront/src/lib/publish/publishFormat.ts +0 -165
  195. package/apps/storefront/src/lib/publish/publishHero.ts +0 -177
  196. package/apps/storefront/src/lib/publish/reviewRelease/changeState.ts +0 -66
  197. package/apps/storefront/src/lib/publish/reviewRelease/copy.ts +0 -141
  198. package/apps/storefront/src/lib/publish/reviewRelease/index.ts +0 -41
  199. package/apps/storefront/src/lib/publish/reviewRelease/permissions.ts +0 -47
  200. package/apps/storefront/src/lib/publish/reviewRelease/releaseState.ts +0 -42
  201. package/apps/storefront/src/lib/publish/reviewRelease/types.ts +0 -59
  202. package/apps/storefront/src/lib/publish/reviewRelease/viewModel.ts +0 -440
  203. package/apps/storefront/src/lib/publish/reviewReleaseWorkspace/actions.ts +0 -161
  204. package/apps/storefront/src/lib/publish/reviewReleaseWorkspace/controller.ts +0 -325
  205. package/apps/storefront/src/lib/publish/reviewReleaseWorkspace/render.ts +0 -241
  206. package/apps/storefront/src/lib/publish/shipWorkspace.ts +0 -439
  207. package/apps/storefront/src/lib/publish/sseRoute.ts +0 -119
  208. package/apps/storefront/src/lib/publish/stageBundleUpload.ts +0 -215
  209. package/apps/storefront/src/lib/publish/streamLogConsole.ts +0 -142
  210. package/apps/storefront/src/lib/publish/versionNumber.ts +0 -52
  211. package/apps/storefront/src/pages/admin/ops-timeline.astro +0 -420
  212. package/apps/storefront/src/pages/admin/review-release.astro +0 -265
  213. package/apps/storefront/src/pages/admin/select.astro +0 -96
  214. package/apps/storefront/src/pages/admin.astro +0 -570
  215. package/apps/storefront/src/pages/api/apps/admin/credentials/rotate.ts +0 -86
  216. package/apps/storefront/src/pages/api/apps/admin/gtm-migration-install.ts +0 -174
  217. package/apps/storefront/src/pages/api/apps/admin/gtm-migration.ts +0 -96
  218. package/apps/storefront/src/pages/api/apps/admin/health.ts +0 -44
  219. package/apps/storefront/src/pages/api/apps/admin/install.ts +0 -125
  220. package/apps/storefront/src/pages/api/apps/admin/integration-lifecycle.ts +0 -118
  221. package/apps/storefront/src/pages/api/apps/admin/integrations.ts +0 -89
  222. package/apps/storefront/src/pages/api/apps/admin/list.ts +0 -26
  223. package/apps/storefront/src/pages/api/apps/admin/platform-adapters.ts +0 -85
  224. package/apps/storefront/src/pages/api/apps/admin/resume.ts +0 -79
  225. package/apps/storefront/src/pages/api/apps/admin/suspend.ts +0 -80
  226. package/apps/storefront/src/pages/api/apps/admin/uninstall.ts +0 -98
  227. package/apps/storefront/src/pages/api/apps/admin/update.ts +0 -126
  228. package/apps/storefront/src/pages/api/apps/admin/webhooks/deliveries/[deliveryId]/replay.ts +0 -70
  229. package/apps/storefront/src/pages/api/apps/admin/webhooks/deliveries.ts +0 -51
  230. package/apps/storefront/src/pages/api/apps/internal/order-forward.ts +0 -255
  231. package/apps/storefront/src/pages/api/apps/oauth/token.ts +0 -87
  232. package/apps/storefront/src/pages/api/apps/v1/attribution.ts +0 -162
  233. package/apps/storefront/src/pages/api/apps/v1/catalog/products/[handle].ts +0 -39
  234. package/apps/storefront/src/pages/api/apps/v1/catalog/products.ts +0 -49
  235. package/apps/storefront/src/pages/api/apps/v1/health.ts +0 -32
  236. package/apps/storefront/src/pages/api/apps/v1/inventory.ts +0 -59
  237. package/apps/storefront/src/pages/api/apps/v1/orders/[id].ts +0 -48
  238. package/apps/storefront/src/pages/api/apps/v1/orders.ts +0 -73
  239. package/apps/storefront/src/pages/api/apps/v1/reports.ts +0 -21
  240. package/apps/storefront/src/pages/api/apps/v1/webhooks/deliveries/[deliveryId]/replay.ts +0 -74
  241. package/apps/storefront/src/pages/api/apps/v1/webhooks/deliveries.ts +0 -47
  242. package/apps/storefront/src/pages/api/cache-purge.ts +0 -55
  243. package/apps/storefront/src/pages/api/compliance/tamper.ts +0 -88
  244. package/apps/storefront/src/pages/api/content-edit/ai-edit.ts +0 -164
  245. package/apps/storefront/src/pages/api/dashboard/enter-vendor.ts +0 -154
  246. package/apps/storefront/src/pages/api/dashboard/vendor-search.ts +0 -120
  247. package/apps/storefront/src/pages/api/integrations/v1/[operation].ts +0 -108
  248. package/apps/storefront/src/pages/api/publish/stage-bundle.ts +0 -70
  249. package/apps/storefront/src/pages/api/test/dev-session.ts +0 -133
  250. package/apps/storefront/src/pages/cockpit.astro +0 -1548
  251. package/apps/storefront/src/pages/dashboard/[appDomain]/apps/index.astro +0 -119
  252. package/apps/storefront/src/pages/dashboard/[appDomain]/index.astro +0 -105
  253. package/apps/storefront/src/pages/dashboard/[appDomain]/team.astro +0 -177
  254. package/apps/storefront/src/pages/dashboard/index.astro +0 -160
@@ -1,286 +0,0 @@
1
- /**
2
- * JsonRpcContentEditClient — the storefront's server-to-server caller for
3
- * tot-mcp's `content_edit` tool (the inline-AI edit loop, WS5 G1). Mirrors
4
- * {@link JsonRpcChangeClient} exactly (same transport, same session-validation,
5
- * same tool-result unwrap, same typed errors) — reusing the forge seam's
6
- * exported transport + error types so there is ONE wire contract, not two.
7
- *
8
- * AUTH SHAPE (Option A, `content-edit-machine-identity` — mirrors change/B3):
9
- * the storefront backend calls `content_edit` with the SAME machine-identity
10
- * APP token the change/forge clients use — a `client_credentials` +
11
- * `private_key_jwt` token minted against the MCP's OAuth token endpoint via
12
- * {@link AppTokenProvider}, attached as Bearer at `initialize` and on every
13
- * request by {@link FetchTransport} — NOT the retired `credential_validate`
14
- * handshake and NOT a human `TOT_ACCESS_TOKEN`. Developer-level authorization
15
- * is, and remains, the caller's job: `/dev`'s own `readViewerSession()` +
16
- * capability check (BEFORE this client is ever constructed) derives the
17
- * tenant from the signed-in developer's OWN session, never from a
18
- * caller-supplied value — tenant isolation is enforced there, unaffected by
19
- * this change. This client only proves "a legitimate storefront backend
20
- * (machine identity) is asking", the same trust boundary
21
- * `/api/changes/accept` already relies on post-B3.
22
- */
23
- import {
24
- FetchTransport,
25
- ForgeAuthError,
26
- ForgeConfigError,
27
- ForgeTransportError,
28
- SESSION_HEADER,
29
- AppTokenProvider,
30
- deriveMcpOauthEndpoints,
31
- type McpTransport,
32
- type JsonRpcRequest,
33
- type TotCredentials,
34
- type TransportResponse,
35
- type BearerProvider,
36
- } from "@/lib/forge";
37
- import { mapForgeError } from "@/lib/forge/errors.js";
38
- import { readEnv } from "@/lib/env";
39
- import type { ContentEditFile, ContentEditResult } from "./types.js";
40
-
41
- export const CONTENT_EDIT_TOOL = {
42
- /**
43
- * Session-validation tool for the NON-OAuth (api-key/secret) construction —
44
- * kept ONLY for backward-compatible test-transport injection (no
45
- * bearerProvider). The deployed path never calls this — see the module
46
- * header.
47
- */
48
- validate: "credential_validate",
49
- edit: "content_edit",
50
- } as const;
51
-
52
- export { SESSION_HEADER } from "@/lib/forge";
53
-
54
- // --- MCP tool-result envelope (mirrors the change client) -------------------
55
-
56
- interface McpToolResult {
57
- content?: Array<{ type?: string; text?: string }>;
58
- structuredContent?: unknown;
59
- isError?: boolean;
60
- }
61
-
62
- function parseTextContent(content: McpToolResult["content"]): unknown {
63
- const text = content?.find((c) => c.type === "text" || c.text != null)?.text;
64
- if (text == null) return undefined;
65
- try {
66
- return JSON.parse(text);
67
- } catch {
68
- return text;
69
- }
70
- }
71
-
72
- function unwrapToolResult<T>(result: unknown): T {
73
- const env = (result ?? {}) as McpToolResult;
74
- const payload =
75
- env.structuredContent !== undefined
76
- ? env.structuredContent
77
- : parseTextContent(env.content);
78
-
79
- if (env.isError) {
80
- const p = (payload ?? {}) as Record<string, unknown>;
81
- throw mapForgeError({
82
- code: typeof p.code === "number" ? p.code : undefined,
83
- message: typeof p.message === "string" ? p.message : "content_edit tool error",
84
- data: (p.data as Record<string, unknown>) ?? p,
85
- });
86
- }
87
- return payload as T;
88
- }
89
-
90
- // --- Config -------------------------------------------------------------
91
-
92
- export interface JsonRpcContentEditClientConfig {
93
- /** MCP base URL (the `POST /mcp` endpoint). */
94
- baseUrl: string;
95
- /** Storefront's ToT credentials for the legacy `credential_validate` path. */
96
- credentials: TotCredentials;
97
- /** Transport override (defaults to fetch). Injected by tests. */
98
- transport?: McpTransport;
99
- /**
100
- * Machine-identity app-token source (mirrors forge's B2 / change's B3,
101
- * binding `c0-forge-auth-supersede`). When present, the client
102
- * authenticates PURELY via a `client_credentials` + `private_key_jwt` app
103
- * token — attached as Bearer at `initialize` and on every request by
104
- * {@link FetchTransport}, re-minted on expiry/401 — and NEVER calls the
105
- * retired `credential_validate` handshake. Built by
106
- * {@link createContentEditClient} from `MCP_BASE_URL`; tests may inject
107
- * their own {@link BearerProvider}.
108
- */
109
- bearerProvider?: BearerProvider;
110
- }
111
-
112
- // --- The client -----------------------------------------------------------
113
-
114
- export class JsonRpcContentEditClient {
115
- private readonly baseUrl: string;
116
- private readonly credentials: TotCredentials;
117
- private readonly transport: McpTransport;
118
- private nextId = 1;
119
- /** Cached session validation — validate once, reuse (lazily). */
120
- private sessionPromise?: Promise<string | undefined>;
121
- /** True when a machine-identity app token authenticates the session (mirrors forge B2 / change B3). */
122
- private readonly usesServiceAuth: boolean;
123
-
124
- constructor(config: JsonRpcContentEditClientConfig) {
125
- if (!config.baseUrl) {
126
- throw new ForgeConfigError("content-edit: MCP_BASE_URL is not configured");
127
- }
128
- if (!config.credentials?.apiKey) {
129
- throw new ForgeConfigError(
130
- "content-edit: storefront ToT credentials are not configured",
131
- );
132
- }
133
- this.baseUrl = config.baseUrl;
134
- this.credentials = config.credentials;
135
- this.usesServiceAuth = config.bearerProvider != null;
136
- this.transport =
137
- config.transport ?? new FetchTransport(config.baseUrl, config.bearerProvider);
138
- }
139
-
140
- async editContent(
141
- prompt: string,
142
- files: readonly ContentEditFile[],
143
- ): Promise<ContentEditResult> {
144
- const sessionId = await this.ensureSession();
145
- const result = await this.rpc(
146
- "tools/call",
147
- { name: CONTENT_EDIT_TOOL.edit, arguments: { prompt, files } },
148
- sessionId,
149
- );
150
- return unwrapToolResult<ContentEditResult>(result);
151
- }
152
-
153
- // --- internals (mirror JsonRpcChangeClient) --------------------------------
154
-
155
- private ensureSession(): Promise<string | undefined> {
156
- // Service-auth (mirrors forge B2 / change B3 / binding
157
- // `c0-forge-auth-supersede`): the app token is attached as Bearer at the
158
- // transport layer (initialize + every request), so the legacy
159
- // `credential_validate` round-trip is skipped entirely — it was retired
160
- // MCP-side and would now be rejected. FetchTransport still threads the
161
- // real `Mcp-Session-Id` the Bearer-authed handshake minted, so a session
162
- // id is never needed from here. Without a bearerProvider (e.g. an
163
- // injected mock transport in unit tests) the legacy validate path is kept.
164
- this.sessionPromise ??= this.usesServiceAuth
165
- ? Promise.resolve(undefined)
166
- : this.validateSession();
167
- return this.sessionPromise;
168
- }
169
-
170
- private async validateSession(): Promise<string | undefined> {
171
- const args = this.credentialArgs();
172
- let res: TransportResponse;
173
- try {
174
- res = await this.rpcRaw(
175
- "tools/call",
176
- { name: CONTENT_EDIT_TOOL.validate, arguments: args },
177
- undefined,
178
- );
179
- } catch (err) {
180
- this.sessionPromise = undefined; // let a later call retry
181
- throw err;
182
- }
183
- if (res.body.error) {
184
- this.sessionPromise = undefined;
185
- throw new ForgeAuthError(
186
- res.body.error.message ?? "content-edit: credential validation failed",
187
- );
188
- }
189
- try {
190
- const validated = unwrapToolResult<{ session?: string; sessionId?: string }>(
191
- res.body.result,
192
- );
193
- return (
194
- res.sessionId ?? validated?.session ?? validated?.sessionId ?? undefined
195
- );
196
- } catch (err) {
197
- this.sessionPromise = undefined;
198
- throw err instanceof ForgeAuthError
199
- ? err
200
- : new ForgeAuthError("content-edit: credential validation was rejected", {
201
- cause: err,
202
- });
203
- }
204
- }
205
-
206
- /** Build the credential payload; omits absent secrets. Never logged. */
207
- private credentialArgs(): Record<string, unknown> {
208
- const c = this.credentials;
209
- const out: Record<string, unknown> = { apiKey: c.apiKey };
210
- if (c.secretKey) out.secretKey = c.secretKey;
211
- if (c.accessToken) out.accessToken = c.accessToken;
212
- return out;
213
- }
214
-
215
- private async rpc(
216
- method: string,
217
- params: unknown,
218
- sessionId: string | undefined,
219
- ): Promise<unknown> {
220
- const res = await this.rpcRaw(method, params, sessionId);
221
- if (res.body.error) throw mapForgeError(res.body.error);
222
- return res.body.result;
223
- }
224
-
225
- private async rpcRaw(
226
- method: string,
227
- params: unknown,
228
- sessionId: string | undefined,
229
- ): Promise<TransportResponse> {
230
- const headers: Record<string, string> = {};
231
- if (sessionId) headers[SESSION_HEADER] = sessionId;
232
- const body: JsonRpcRequest = {
233
- jsonrpc: "2.0",
234
- id: this.nextId++,
235
- method,
236
- params,
237
- };
238
- try {
239
- return await this.transport.post({ body, headers });
240
- } catch (err) {
241
- if (err instanceof ForgeTransportError) throw err;
242
- throw new ForgeTransportError(
243
- `content-edit: transport failure calling ${method}`,
244
- { cause: err },
245
- );
246
- }
247
- }
248
- }
249
-
250
- // --- Factory ----------------------------------------------------------------
251
-
252
- /**
253
- * Build a {@link JsonRpcContentEditClient} from the runtime env — the SAME env
254
- * the change client reads:
255
- * - `MCP_BASE_URL` — the `POST /mcp` endpoint (its ORIGIN also hosts the OAuth
256
- * token endpoint + resource the app token binds to; already `…/storefront`
257
- * per B4, so the app token's resource + this RPC endpoint match).
258
- * - `TOT_API_KEY` (+ optional `TOT_SECRET_KEY`) — storefront's OWN ToT
259
- * credentials (retained for legacy/local paths; the deployed content-edit
260
- * session no longer uses them for auth).
261
- *
262
- * Machine identity (mirrors forge B2 / change B3 / binding
263
- * `c0-forge-auth-supersede`): the content-edit session authenticates with a
264
- * `client_credentials` + `private_key_jwt` APP token minted against the MCP's
265
- * OAuth token endpoint via {@link AppTokenProvider} — NOT a human
266
- * `TOT_ACCESS_TOKEN` and NOT a shared secret. `TOT_ACCESS_TOKEN` is
267
- * deliberately NOT read here.
268
- *
269
- * Throws {@link ForgeConfigError} when the base URL or api key is missing.
270
- * Secrets are read via {@link readEnv} and never logged.
271
- */
272
- export async function createContentEditClient(
273
- overrides: Partial<JsonRpcContentEditClientConfig> = {},
274
- ): Promise<JsonRpcContentEditClient> {
275
- const baseUrl = overrides.baseUrl ?? (await readEnv("MCP_BASE_URL")) ?? "";
276
- const credentials =
277
- overrides.credentials ??
278
- ({
279
- apiKey: (await readEnv("TOT_API_KEY")) ?? "",
280
- secretKey: await readEnv("TOT_SECRET_KEY"),
281
- } satisfies TotCredentials);
282
- const bearerProvider =
283
- overrides.bearerProvider ??
284
- (baseUrl ? new AppTokenProvider(deriveMcpOauthEndpoints(baseUrl)) : undefined);
285
- return new JsonRpcContentEditClient({ ...overrides, baseUrl, credentials, bearerProvider });
286
- }
@@ -1,14 +0,0 @@
1
- /**
2
- * content_edit integration — public barrel. Import the typed client and its
3
- * route helper from here (`@/lib/content-edit`) so call sites never reach into
4
- * individual files.
5
- */
6
- export type { ContentEditFile, ContentEditFileDiff, ContentEditResult } from "./types.js";
7
- export {
8
- JsonRpcContentEditClient,
9
- createContentEditClient,
10
- CONTENT_EDIT_TOOL,
11
- SESSION_HEADER,
12
- } from "./client.js";
13
- export type { JsonRpcContentEditClientConfig } from "./client.js";
14
- export { getContentEditClient } from "./route.js";
@@ -1,25 +0,0 @@
1
- /**
2
- * Route helper for `/api/content-edit/ai-edit` — mirrors `@/lib/change/route/route.ts`'s
3
- * `getChangeClient`: build the env-configured client, or a 503 Response when
4
- * the MCP integration isn't configured (missing `MCP_BASE_URL`/credentials).
5
- */
6
- import { ForgeError } from "@/lib/forge";
7
- import { createContentEditClient } from "./client.js";
8
- import { json } from "@/lib/grants/route.js";
9
-
10
- /**
11
- * Build a content-edit client over the real MCP from env, or return a 503
12
- * Response when the integration is not configured. Never leaks secret values.
13
- */
14
- export async function getContentEditClient(): Promise<
15
- Awaited<ReturnType<typeof createContentEditClient>> | Response
16
- > {
17
- try {
18
- return await createContentEditClient();
19
- } catch (err) {
20
- if (err instanceof ForgeError && err.kind === "config") {
21
- return json({ error: "content_edit integration not configured" }, 503);
22
- }
23
- throw err;
24
- }
25
- }
@@ -1,19 +0,0 @@
1
- /** Wire shape for tot-mcp's `content_edit` tool — mirrors tot-mcp's own
2
- * ContentFile/ContentFileDiff/ContentEditResult (src/services/content-editor.ts). */
3
-
4
- export interface ContentEditFile {
5
- /** e.g. "content/home.html" or "theme.json" — content_edit's own allowlist. */
6
- path: string;
7
- content: string;
8
- }
9
-
10
- export interface ContentEditFileDiff {
11
- path: string;
12
- /** Unified diff (`--- a/<path>` / `+++ b/<path>`) against the given content. */
13
- diff: string;
14
- }
15
-
16
- export interface ContentEditResult {
17
- diffs: ContentEditFileDiff[];
18
- summary: string;
19
- }
@@ -1,57 +0,0 @@
1
- /**
2
- * "Which store is this cockpit request about?" — the ONE resolver the hosted
3
- * cockpit page, its /api/dev/* routes, and the CLI sign-in-code mint all share, so
4
- * they never disagree about the developer's store.
5
- *
6
- * Rule: the URL wins WHEN THE VIEWER CAN ACCESS IT. The middleware has already
7
- * resolved the request's host/path to `locals.tenant` (the trusted, authenticated
8
- * store seam — never client body input), so when that is a SPECIFIC store (not the
9
- * public marketing home) and the signed-in developer holds a membership for it (or a
10
- * live staff admission), that store is authoritative. Otherwise we fall back to the
11
- * session's own first store (the generic-host `/cockpit` case), and for an
12
- * anonymous viewer to the path store's branding, else the caller-supplied `?tenant=`.
13
- *
14
- * Access is gated with the SAME primitive (`viewerCanAccess`) the vendor dashboard
15
- * uses, so a developer can never steer the mint at a store they don't belong to; a
16
- * store they can't access simply falls through to their own.
17
- */
18
- import type { APIContext } from "astro";
19
- import type { SessionRecord } from "@/lib/auth/session";
20
- import { PUBLIC_HOME_TENANT_ID } from "@/lib/auth/loginGate";
21
- import { viewerCanAccess, type StaffAdmission } from "@/lib/dashboard/tenantSelection";
22
-
23
- /** The request's host/path-resolved store resource, or "" when it's the marketing home. */
24
- function pathStoreResource(context: Pick<APIContext, "locals">): string {
25
- const t = context.locals?.tenant;
26
- if (!t || t.tenant_id === PUBLIC_HOME_TENANT_ID) return "";
27
- return (t.appDomain || t.tenant_id || "").toLowerCase();
28
- }
29
-
30
- /**
31
- * Resolve the store this cockpit request is scoped to, as a lowercased resource
32
- * (appDomain/tenant_id). Empty string when nothing resolves (e.g. anonymous on the
33
- * generic host with no `?tenant=`).
34
- */
35
- export function resolveCockpitStoreResource(
36
- context: Pick<APIContext, "locals" | "url">,
37
- session: SessionRecord | null,
38
- ): string {
39
- const pathStore = pathStoreResource(context);
40
-
41
- if (session) {
42
- // The URL wins when the signed-in developer can actually access that store.
43
- if (pathStore) {
44
- const staff: StaffAdmission | undefined = session.staffSelection
45
- ? { selection: session.staffSelection, nowSeconds: Math.floor(Date.now() / 1000) }
46
- : undefined;
47
- if (viewerCanAccess(session.tenants, pathStore, staff)) return pathStore;
48
- }
49
- // Generic host, or a store the viewer doesn't belong to: their own first store.
50
- return (session.tenants?.[0]?.resource ?? session.resource ?? "").toLowerCase();
51
- }
52
-
53
- // Anonymous: the path store is just branding (no privileged mint happens), else the
54
- // caller-supplied preview hint. Never overrides a signed-in developer (handled above).
55
- if (pathStore) return pathStore;
56
- return (context.url?.searchParams.get("tenant") ?? "").toLowerCase();
57
- }