@undefineds.co/xpod 0.4.13 → 0.4.15

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 (331) hide show
  1. package/config/cloud.json +0 -3
  2. package/config/components-ignore.json +11 -7
  3. package/config/local.json +0 -3
  4. package/config/xpod.base.json +0 -24
  5. package/dist/api/ai-config/AiConfigStore.d.ts +2 -2
  6. package/dist/api/ai-config/AiConfigStore.js +4 -1
  7. package/dist/api/ai-gateway/auth/CallerPodAccess.d.ts +2 -5
  8. package/dist/api/ai-gateway/auth/CallerPodAccess.js +3 -42
  9. package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.d.ts +2 -1
  10. package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.js +1 -1
  11. package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.d.ts +3 -8
  12. package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.js +9 -32
  13. package/dist/api/ai-gateway/connect/index.d.ts +3 -3
  14. package/dist/api/ai-gateway/connect/index.js +9 -38
  15. package/dist/api/ai-gateway/errors.js +2 -1
  16. package/dist/api/ai-gateway/models/PodModelSelectionRepository.d.ts +3 -3
  17. package/dist/api/ai-gateway/models/PodModelSelectionRepository.js +7 -11
  18. package/dist/api/ai-gateway/pod/HostedPodRoute.d.ts +27 -0
  19. package/dist/api/ai-gateway/pod/HostedPodRoute.js +47 -0
  20. package/dist/api/ai-gateway/pod/OwnerPodAccess.d.ts +79 -0
  21. package/dist/api/ai-gateway/pod/OwnerPodAccess.js +192 -0
  22. package/dist/api/ai-gateway/pod/PodInterfaceKeyStore.d.ts +52 -0
  23. package/dist/api/ai-gateway/pod/PodInterfaceKeyStore.js +61 -0
  24. package/dist/api/ai-gateway/providers/ProviderRegistry.js +1 -1
  25. package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.d.ts +3 -3
  26. package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.js +7 -32
  27. package/dist/api/ai-gateway/service-access/AiConnectionsServiceAccess.d.ts +1 -1
  28. package/dist/api/ai-gateway/service-access/AiConnectionsServiceAccess.js +1 -1
  29. package/dist/api/auth/ClientCredentialsAuthenticator.js +5 -28
  30. package/dist/api/auth/TokenEndpointRoute.d.ts +18 -0
  31. package/dist/api/auth/TokenEndpointRoute.js +36 -0
  32. package/dist/api/chatkit/pod-store.d.ts +4 -4
  33. package/dist/api/chatkit/pod-store.js +24 -95
  34. package/dist/api/container/common.js +36 -23
  35. package/dist/api/container/index.js +1 -0
  36. package/dist/api/container/local.js +88 -37
  37. package/dist/api/container/routes.js +41 -7
  38. package/dist/api/container/types.d.ts +4 -2
  39. package/dist/api/handlers/AdminHandler.d.ts +17 -1
  40. package/dist/api/handlers/AdminHandler.js +40 -3
  41. package/dist/api/handlers/AiGatewayManagementHandler.d.ts +6 -0
  42. package/dist/api/handlers/AiGatewayManagementHandler.js +17 -4
  43. package/dist/api/handlers/EdgeNodeSignalHandler.js +10 -2
  44. package/dist/api/handlers/NetworkSettingsHandler.d.ts +44 -5
  45. package/dist/api/handlers/NetworkSettingsHandler.js +46 -11
  46. package/dist/api/handlers/PodSettingsHandler.d.ts +3 -3
  47. package/dist/api/handlers/PodSettingsHandler.js +3 -3
  48. package/dist/api/handlers/ProvisionHandler.d.ts +35 -1
  49. package/dist/api/handlers/ProvisionHandler.js +53 -2
  50. package/dist/api/handlers/ReachabilityHandler.d.ts +6 -0
  51. package/dist/api/handlers/ReachabilityHandler.js +25 -6
  52. package/dist/api/network/NetworkEnvironmentConfigurationStore.d.ts +6 -1
  53. package/dist/api/network/NetworkEnvironmentConfigurationStore.js +72 -16
  54. package/dist/api/runtime.d.ts +18 -0
  55. package/dist/api/runtime.js +28 -2
  56. package/dist/api/service/AiClientConfigurationService.d.ts +1 -1
  57. package/dist/api/service/AiClientConfigurationService.js +1 -1
  58. package/dist/cli/commands/start.d.ts +26 -1
  59. package/dist/cli/commands/start.js +69 -5
  60. package/dist/components/components.jsonld +1 -1
  61. package/dist/components/context.jsonld +35 -42
  62. package/dist/edge/EdgeNodeAgent.d.ts +16 -0
  63. package/dist/edge/EdgeNodeAgent.js +56 -1
  64. package/dist/edge/EdgeNodeAgent.jsonld +8 -0
  65. package/dist/edge/EdgeNodeAgentInitializer.d.ts +2 -0
  66. package/dist/edge/EdgeNodeAgentInitializer.js +1 -0
  67. package/dist/edge/EdgeNodeAgentInitializer.jsonld +19 -0
  68. package/dist/edge/EdgeNodeDnsCoordinator.d.ts +11 -1
  69. package/dist/edge/EdgeNodeDnsCoordinator.js +12 -2
  70. package/dist/edge/EdgeNodeHealthProbeService.d.ts +15 -0
  71. package/dist/edge/EdgeNodeHealthProbeService.js +44 -12
  72. package/dist/edge/EdgeNodeHealthProbeService.jsonld +77 -0
  73. package/dist/edge/ProbeTargetGuard.d.ts +35 -0
  74. package/dist/edge/ProbeTargetGuard.js +142 -0
  75. package/dist/edge/reachability/NodeAccessResolver.d.ts +16 -0
  76. package/dist/edge/reachability/NodeAccessResolver.js +30 -0
  77. package/dist/edge/reachability/ReachabilitySessionService.js +4 -1
  78. package/dist/edge/reachability/RouteSetBuilder.d.ts +18 -1
  79. package/dist/edge/reachability/RouteSetBuilder.js +47 -0
  80. package/dist/edge/reachability/RouteSetBuilder.jsonld +29 -0
  81. package/dist/edge/reachability/types.d.ts +8 -2
  82. package/dist/http/SubgraphSparqlHttpHandler.d.ts +1 -25
  83. package/dist/http/SubgraphSparqlHttpHandler.js +0 -100
  84. package/dist/http/SubgraphSparqlHttpHandler.jsonld +0 -8
  85. package/dist/identity/drizzle/PodInterfaceKeyRepository.d.ts +33 -0
  86. package/dist/identity/drizzle/PodInterfaceKeyRepository.js +78 -0
  87. package/dist/identity/drizzle/db.d.ts +7 -0
  88. package/dist/identity/drizzle/db.js +30 -0
  89. package/dist/identity/drizzle/schema.pg.d.ts +9 -0
  90. package/dist/identity/drizzle/schema.pg.js +16 -1
  91. package/dist/identity/drizzle/schema.sqlite.d.ts +106 -0
  92. package/dist/identity/drizzle/schema.sqlite.js +16 -1
  93. package/dist/index.d.ts +3 -2
  94. package/dist/index.js +9 -5
  95. package/dist/main.js +7 -0
  96. package/dist/runtime/GatewayAdminProxyAuth.d.ts +1 -16
  97. package/dist/runtime/GatewayAdminProxyAuth.js +2 -71
  98. package/dist/runtime/Proxy.d.ts +32 -1
  99. package/dist/runtime/Proxy.js +125 -31
  100. package/dist/runtime/bootstrap.d.ts +21 -0
  101. package/dist/runtime/bootstrap.js +45 -1
  102. package/dist/runtime/css-process.d.ts +1 -0
  103. package/dist/runtime/css-process.js +1 -0
  104. package/dist/runtime/host/node/NodeRuntimeHost.js +6 -1
  105. package/dist/runtime/host/types.d.ts +6 -0
  106. package/dist/runtime/index.d.ts +1 -1
  107. package/dist/runtime/index.js +4 -1
  108. package/dist/runtime/js-runtime.js +10 -3
  109. package/dist/runtime/lifecycle.js +6 -4
  110. package/dist/runtime/port-finder.d.ts +26 -0
  111. package/dist/runtime/port-finder.js +64 -0
  112. package/dist/runtime/runner/node/NodeGatewayRuntimeRunner.js +1 -0
  113. package/dist/runtime/runner/types.d.ts +5 -0
  114. package/dist/runtime/runtime-types.d.ts +1 -0
  115. package/dist/test-utils/local-managed-client-p2p-e2e-smoke.js +1 -1
  116. package/dist/tunnel/AutoTunnelProvider.d.ts +56 -0
  117. package/dist/tunnel/AutoTunnelProvider.js +181 -0
  118. package/dist/tunnel/LocalTunnelProvider.d.ts +15 -0
  119. package/dist/tunnel/LocalTunnelProvider.js +87 -18
  120. package/dist/tunnel/LocalTunnelProvider.jsonld +27 -0
  121. package/dist/tunnel/NgrokTunnelProvider.d.ts +4 -0
  122. package/dist/tunnel/NgrokTunnelProvider.js +117 -43
  123. package/dist/tunnel/NgrokTunnelProvider.jsonld +4 -0
  124. package/dist/tunnel/SakuraFrpTunnelProvider.d.ts +65 -3
  125. package/dist/tunnel/SakuraFrpTunnelProvider.js +268 -25
  126. package/dist/tunnel/TunnelLifecycle.d.ts +14 -0
  127. package/dist/tunnel/TunnelLifecycle.js +34 -0
  128. package/dist/tunnel/TunnelProfiles.d.ts +33 -3
  129. package/dist/tunnel/TunnelProfiles.js +105 -78
  130. package/dist/tunnel/TunnelProvider.d.ts +15 -2
  131. package/dist/tunnel/TunnelProvider.jsonld +8 -0
  132. package/dist/tunnel/TunnelProviderCatalog.d.ts +62 -0
  133. package/dist/tunnel/TunnelProviderCatalog.js +130 -0
  134. package/dist/tunnel/index.d.ts +1 -0
  135. package/dist/tunnel/index.js +3 -1
  136. package/node_modules/@undefineds.co/ai-connections/dist/AiApiKeyPool.d.ts +1 -1
  137. package/node_modules/@undefineds.co/ai-connections/dist/AiApiKeyPool.js +1 -1
  138. package/node_modules/@undefineds.co/ai-connections/dist/AiAuthorizationActions.d.ts +1 -1
  139. package/node_modules/@undefineds.co/ai-connections/dist/AiClientConfigurationSection.d.ts +1 -1
  140. package/node_modules/@undefineds.co/ai-connections/dist/AiClientConfigurationSection.js +1 -1
  141. package/node_modules/@undefineds.co/ai-connections/dist/AiConnectDialog.d.ts +1 -1
  142. package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsPanel.d.ts +1 -1
  143. package/node_modules/@undefineds.co/ai-connections/dist/AiCredentialPoolSection.d.ts +1 -1
  144. package/node_modules/@undefineds.co/ai-connections/dist/AiCredentialRow.d.ts +1 -1
  145. package/node_modules/@undefineds.co/ai-connections/dist/AiCustomProviderDialog.d.ts +1 -1
  146. package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeyRow.d.ts +1 -1
  147. package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeysSection.d.ts +1 -1
  148. package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayModelsSection.d.ts +1 -1
  149. package/node_modules/@undefineds.co/ai-connections/dist/AiOfferingDetails.d.ts +1 -1
  150. package/node_modules/@undefineds.co/ai-connections/dist/AiProviderCard.d.ts +1 -1
  151. package/node_modules/@undefineds.co/ai-connections/dist/AiQuotaCard.d.ts +1 -1
  152. package/node_modules/@undefineds.co/ai-connections/dist/AiSortableCredentialList.d.ts +1 -1
  153. package/node_modules/@undefineds.co/ai-connections/dist/authorization-methods.d.ts +1 -1
  154. package/node_modules/@undefineds.co/ai-connections/dist/collection-runtime.d.ts +1 -1
  155. package/node_modules/@undefineds.co/ai-connections/dist/collection-runtime.js +3 -3
  156. package/node_modules/@undefineds.co/ai-connections/dist/collections.d.ts +1 -1
  157. package/node_modules/@undefineds.co/ai-connections/dist/collections.js +3 -3
  158. package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/ai-connections-client.d.ts +1 -1
  159. package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/ai-connections-client.js +1 -1
  160. package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/index.cjs +8 -8
  161. package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/index.d.ts +1 -1
  162. package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/index.js +1 -1
  163. package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/provider-catalog.cjs +3 -3
  164. package/node_modules/@undefineds.co/ai-connections/dist/controller.d.ts +1 -1
  165. package/node_modules/@undefineds.co/ai-connections/dist/controller.js +1 -1
  166. package/node_modules/@undefineds.co/ai-connections/dist/credential-labels.d.ts +1 -1
  167. package/node_modules/@undefineds.co/ai-connections/dist/display-wording.d.ts +1 -1
  168. package/node_modules/@undefineds.co/ai-connections/dist/error-wording.d.ts +1 -1
  169. package/node_modules/@undefineds.co/ai-connections/dist/error-wording.js +8 -3
  170. package/node_modules/@undefineds.co/ai-connections/dist/gateway-endpoints.js +1 -1
  171. package/node_modules/@undefineds.co/ai-connections/dist/offering-endpoints.d.ts +1 -1
  172. package/node_modules/@undefineds.co/ai-connections/dist/offering-label.d.ts +1 -1
  173. package/node_modules/@undefineds.co/ai-connections/dist/provider-visuals.d.ts +1 -1
  174. package/node_modules/@undefineds.co/ai-connections/dist/service-access.js +1 -1
  175. package/node_modules/@undefineds.co/ai-connections/dist/useAiConnectDialog.d.ts +1 -1
  176. package/node_modules/@undefineds.co/ai-connections/package.json +31 -1
  177. package/node_modules/@undefineds.co/solid-sdk/dist/access-route.cjs +230 -0
  178. package/node_modules/@undefineds.co/solid-sdk/dist/access-route.d.ts +76 -0
  179. package/node_modules/@undefineds.co/solid-sdk/dist/access-route.js +115 -0
  180. package/node_modules/@undefineds.co/solid-sdk/dist/index.cjs +89 -0
  181. package/node_modules/@undefineds.co/solid-sdk/dist/index.d.ts +1 -0
  182. package/node_modules/@undefineds.co/solid-sdk/dist/index.js +1 -0
  183. package/node_modules/@undefineds.co/solid-sdk/package.json +6 -1
  184. package/package.json +5 -6
  185. package/static/app/assets/inrupt-smoke.js +23 -23
  186. package/static/app/assets/main.css +1 -1
  187. package/static/auth-callback/assets/{AiConfigContext-DlFyEWy9.js → AiConfigContext-Bx0HCAW5.js} +1 -1
  188. package/static/auth-callback/assets/{AiConfigPage-CkYk-SFW.js → AiConfigPage-ChQImMbm.js} +1 -1
  189. package/static/auth-callback/assets/{DocumentProcessingPanel-CqIr3JqN.js → DocumentProcessingPanel-D830H4SH.js} +1 -1
  190. package/static/auth-callback/assets/{IndexLifecyclePanel-C1GKV3Vx.js → IndexLifecyclePanel-CnlkjMF8.js} +1 -1
  191. package/static/auth-callback/assets/{IndexSubjectPanel-ro9lC6XW.js → IndexSubjectPanel-CdEfg_CO.js} +1 -1
  192. package/static/auth-callback/assets/{ModelAssignmentsPanel-DxNdyKRJ.js → ModelAssignmentsPanel-D-8A8dZx.js} +1 -1
  193. package/static/auth-callback/assets/{ModelsPage-BVtWSPBU.js → ModelsPage-Cim7cubp.js} +3 -3
  194. package/static/auth-callback/assets/NetworkPage-CfK3x-pb.js +2 -0
  195. package/static/auth-callback/assets/{PaneListHeader-ByKw8ada.js → PaneListHeader-Bf_kEd4U.js} +1 -1
  196. package/static/auth-callback/assets/{SearchIndexingPanel-CulBKcYT.js → SearchIndexingPanel-4kD4RBEQ.js} +1 -1
  197. package/static/auth-callback/assets/{StatusSubjectPanel-VOcfrt8o.js → StatusSubjectPanel-Bw9AiTSf.js} +1 -1
  198. package/static/auth-callback/assets/{StatusWorkspace-Jsz6hAdE.js → StatusWorkspace-C-301H-0.js} +1 -1
  199. package/static/auth-callback/assets/{SystemSettingsPage-BFNvGAle.js → SystemSettingsPage-BbWn-eG6.js} +1 -1
  200. package/static/auth-callback/assets/{SystemSettingsSubjectPanel-DFRdrSfK.js → SystemSettingsSubjectPanel-DA4wvNSm.js} +1 -1
  201. package/static/auth-callback/assets/{XpodAiConnectionsPodStore-C6KpvHVg.js → XpodAiConnectionsPodStore-CohdyLoX.js} +1 -1
  202. package/static/auth-callback/assets/{activity-DnTlb9iM.js → activity-CCsb9Oam.js} +1 -1
  203. package/static/auth-callback/assets/ai-connections-DexTPyfC.js +1 -0
  204. package/static/auth-callback/assets/{auth-callback-D2UkK5Xj.js → auth-callback-Ds-c62W3.js} +5 -5
  205. package/static/auth-callback/assets/auth-callback-rk080mvG.css +1 -0
  206. package/static/auth-callback/assets/{badge-D7IJuuTM.js → badge-CQm5OyzR.js} +1 -1
  207. package/static/auth-callback/assets/{collection-runtime-wT1n4GS2.js → collection-runtime-DlAuU5TW.js} +1 -1
  208. package/static/auth-callback/assets/{dialog-DickLu5z.js → dialog-CnGzg5Ff.js} +1 -1
  209. package/static/auth-callback/assets/{download-kn8WnRu3.js → download-DwMONJvm.js} +1 -1
  210. package/static/auth-callback/assets/{external-link-B6B8jfSn.js → external-link-Bu5AGqCO.js} +1 -1
  211. package/static/auth-callback/assets/{index-DHF97YLP.js → index-B0T-1YO8.js} +1 -1
  212. package/static/auth-callback/assets/{index-Dz83EEHD.js → index-C8QZf_4W.js} +1 -1
  213. package/static/auth-callback/assets/index-DwIlrIDG.js +4 -0
  214. package/static/auth-callback/assets/{index-browser-CSghinyi.js → index-browser-lRsMcP_7.js} +1 -1
  215. package/static/auth-callback/assets/{key-round-ChkOx3E1.js → key-round-BDMtU57P.js} +1 -1
  216. package/static/auth-callback/assets/{rotate-ccw-B3hE-nyd.js → rotate-ccw-CoKIGCsQ.js} +1 -1
  217. package/static/auth-callback/assets/{skeleton-kEqR7tpI.js → skeleton-CPoSWHDr.js} +1 -1
  218. package/static/auth-callback/assets/{waypoints-D6Jo-SZa.js → waypoints-BeYHxqHv.js} +1 -1
  219. package/static/auth-callback/assets/{workspace-layout-BHwT_cHd.js → workspace-layout-xA5YxiK3.js} +1 -1
  220. package/static/auth-callback/auth-callback.html +2 -2
  221. package/static/dashboard/assets/{AiConfigContext-BfC3v-x2.js → AiConfigContext-rWx4TyiH.js} +1 -1
  222. package/static/dashboard/assets/{AiConfigPage-QNS3u7Ff.js → AiConfigPage-StVJpDFT.js} +1 -1
  223. package/static/dashboard/assets/{DocumentProcessingPanel-Dr4XLeT4.js → DocumentProcessingPanel-DJ5yul2O.js} +1 -1
  224. package/static/dashboard/assets/{IndexLifecyclePanel-KtM_gpeO.js → IndexLifecyclePanel-CpjtgezK.js} +1 -1
  225. package/static/dashboard/assets/{IndexSubjectPanel-DLaiKdLc.js → IndexSubjectPanel-BVKcot1_.js} +1 -1
  226. package/static/dashboard/assets/{ModelAssignmentsPanel-Bk7TvQRq.js → ModelAssignmentsPanel-BxVgWZPc.js} +1 -1
  227. package/static/dashboard/assets/{ModelsPage-Cci3vlos.js → ModelsPage-CECBwmeO.js} +3 -3
  228. package/static/dashboard/assets/NetworkPage-zQgFscEW.js +2 -0
  229. package/static/dashboard/assets/{PaneListHeader-qHME_s08.js → PaneListHeader-DIPe8pS6.js} +1 -1
  230. package/static/dashboard/assets/{SearchIndexingPanel-HZPKj8H9.js → SearchIndexingPanel-lalFJ3c8.js} +1 -1
  231. package/static/dashboard/assets/{StatusSubjectPanel-ij7IpI8d.js → StatusSubjectPanel-CpY_KU-G.js} +1 -1
  232. package/static/dashboard/assets/{StatusWorkspace-Cp02JcaN.js → StatusWorkspace-BwWCii3A.js} +1 -1
  233. package/static/dashboard/assets/{SystemSettingsPage-BSeuvb8X.js → SystemSettingsPage-BKZxX-_n.js} +1 -1
  234. package/static/dashboard/assets/{SystemSettingsSubjectPanel-CP4_luGS.js → SystemSettingsSubjectPanel-BZrqb2C5.js} +1 -1
  235. package/static/dashboard/assets/{XpodAiConnectionsPodStore-urO6zaHL.js → XpodAiConnectionsPodStore-Bbpx9dTN.js} +1 -1
  236. package/static/dashboard/assets/{activity-DxjgQNvr.js → activity-BJ15TLVP.js} +1 -1
  237. package/static/dashboard/assets/ai-connections-GG6qkTJt.js +1 -0
  238. package/static/dashboard/assets/{badge-53qCrRbl.js → badge-BBX5FlaB.js} +1 -1
  239. package/static/dashboard/assets/{collection-runtime-BPAmHG46.js → collection-runtime-UBbHBzdf.js} +1 -1
  240. package/static/dashboard/assets/{dashboard-BcT2ByXw.js → dashboard-7Y6BHyV9.js} +62 -62
  241. package/static/dashboard/assets/dashboard-rk080mvG.css +1 -0
  242. package/static/dashboard/assets/{dialog-B28YtNhS.js → dialog-QrOJ-hB0.js} +1 -1
  243. package/static/dashboard/assets/{download-DkLNceJ4.js → download-DK9x-VOP.js} +1 -1
  244. package/static/dashboard/assets/{external-link-D3TXnlo3.js → external-link-Cnkn87mJ.js} +1 -1
  245. package/static/dashboard/assets/index-B1z84it5.js +4 -0
  246. package/static/dashboard/assets/{index-CIiBu9mr.js → index-DzjauX3N.js} +1 -1
  247. package/static/dashboard/assets/{index-CFIenkeK.js → index-cIa8_efI.js} +1 -1
  248. package/static/dashboard/assets/{key-round-B5ccp6nx.js → key-round-BoS6UqKz.js} +1 -1
  249. package/static/dashboard/assets/{rotate-ccw-DUpfkNnk.js → rotate-ccw-BeWV76i0.js} +1 -1
  250. package/static/dashboard/assets/{skeleton-BRe19fO0.js → skeleton-CypcJL07.js} +1 -1
  251. package/static/dashboard/assets/{waypoints-BKDMxEvu.js → waypoints-zHOOqfhi.js} +1 -1
  252. package/static/dashboard/assets/{workspace-layout-ZTF7C16h.js → workspace-layout-DZ9JuxnM.js} +1 -1
  253. package/static/dashboard/dashboard.html +2 -2
  254. package/static/settings/assets/{AiConfigContext-DsyWgu2i.js → AiConfigContext-D3b1l_Kw.js} +1 -1
  255. package/static/settings/assets/{AiConfigPage-CSCBckKo.js → AiConfigPage-DYKw-atP.js} +1 -1
  256. package/static/settings/assets/{DocumentProcessingPanel-w9yQDbBe.js → DocumentProcessingPanel-DguRfsIV.js} +1 -1
  257. package/static/settings/assets/{IndexLifecyclePanel-CUUXI8mP.js → IndexLifecyclePanel-B85qJJA4.js} +1 -1
  258. package/static/settings/assets/{IndexSubjectPanel-BypAU5TJ.js → IndexSubjectPanel-CsN7IxaV.js} +1 -1
  259. package/static/settings/assets/{ModelAssignmentsPanel-BetgXw1G.js → ModelAssignmentsPanel-DEp9byI6.js} +1 -1
  260. package/static/settings/assets/{ModelsPage-DZpTlTZ3.js → ModelsPage-CzTnPs_G.js} +3 -3
  261. package/static/settings/assets/NetworkPage-BDVnmUU0.js +2 -0
  262. package/static/settings/assets/{PaneListHeader-BGOqGec4.js → PaneListHeader-Cpe39N76.js} +1 -1
  263. package/static/settings/assets/{SearchIndexingPanel-DYAbpZ_9.js → SearchIndexingPanel-DA9w8lLL.js} +1 -1
  264. package/static/settings/assets/{StatusSubjectPanel-CFgzeQ8Q.js → StatusSubjectPanel-BU0Aq0CS.js} +1 -1
  265. package/static/settings/assets/{StatusWorkspace-4Z6g4Jvv.js → StatusWorkspace-D1AC1i5N.js} +1 -1
  266. package/static/settings/assets/{SystemSettingsPage-C1tlrgvI.js → SystemSettingsPage-ChKvOioO.js} +1 -1
  267. package/static/settings/assets/{SystemSettingsSubjectPanel-CcURI-1L.js → SystemSettingsSubjectPanel-DyTpOnD2.js} +1 -1
  268. package/static/settings/assets/{XpodAiConnectionsPodStore-owBQc5nY.js → XpodAiConnectionsPodStore-VU5Bsz1a.js} +1 -1
  269. package/static/settings/assets/{activity-CtBc9cNy.js → activity-DGpLfsQB.js} +1 -1
  270. package/static/settings/assets/ai-connections-DexTPyfC.js +1 -0
  271. package/static/settings/assets/{badge--r-FDIhU.js → badge-_hCrrWRP.js} +1 -1
  272. package/static/settings/assets/{collection-runtime-CnhPmwAM.js → collection-runtime-E40TZ8Cl.js} +1 -1
  273. package/static/settings/assets/{dialog-B7ZRsjN7.js → dialog-DTr2JkHn.js} +1 -1
  274. package/static/settings/assets/{download-DgQ1F8QR.js → download-B_D21DDX.js} +1 -1
  275. package/static/settings/assets/{external-link-Bz7NckNO.js → external-link-BATYaM13.js} +1 -1
  276. package/static/settings/assets/index-BAlAVi-J.js +4 -0
  277. package/static/settings/assets/{index-CkGda_Pg.js → index-Ckh4h9jj.js} +1 -1
  278. package/static/settings/assets/{index-Vv-8Vslg.js → index-DOiwLF4B.js} +1 -1
  279. package/static/settings/assets/{index-browser-Dq7omlpY.js → index-browser-DFFWN3Kr.js} +1 -1
  280. package/static/settings/assets/{key-round-CvuhloKV.js → key-round-ZTVU_1O1.js} +1 -1
  281. package/static/settings/assets/{rotate-ccw-DgFKDaz7.js → rotate-ccw-DDdw8PTU.js} +1 -1
  282. package/static/settings/assets/{settings-BvqY7K96.js → settings-CyLnISOv.js} +62 -62
  283. package/static/settings/assets/settings-rk080mvG.css +1 -0
  284. package/static/settings/assets/{skeleton-D3OeFDF6.js → skeleton-DEzA3hc2.js} +1 -1
  285. package/static/settings/assets/{waypoints-C4WbspTb.js → waypoints-BSdfNvEb.js} +1 -1
  286. package/static/settings/assets/{workspace-layout-B9H1Tqrk.js → workspace-layout-BOQnl_3d.js} +1 -1
  287. package/static/settings/settings.html +2 -2
  288. package/dist/api/ai-gateway/pod/HostedPodDataAccess.d.ts +0 -31
  289. package/dist/api/ai-gateway/pod/HostedPodDataAccess.js +0 -330
  290. package/dist/http/InternalPodDataHttpHandler.d.ts +0 -57
  291. package/dist/http/InternalPodDataHttpHandler.js +0 -551
  292. package/dist/http/InternalPodDataHttpHandler.jsonld +0 -243
  293. package/node_modules/@undefineds.co/ai-connections-core/package.json +0 -61
  294. package/static/auth-callback/assets/NetworkPage-cEvxRMAl.js +0 -2
  295. package/static/auth-callback/assets/ai-connections-C6yaE6WQ.js +0 -1
  296. package/static/auth-callback/assets/auth-callback-Cx9D_1qj.css +0 -1
  297. package/static/auth-callback/assets/index-Cu0EguPo.js +0 -4
  298. package/static/dashboard/assets/NetworkPage-Ot4G2dX5.js +0 -2
  299. package/static/dashboard/assets/ai-connections-CXp5gd1J.js +0 -1
  300. package/static/dashboard/assets/dashboard-Cx9D_1qj.css +0 -1
  301. package/static/dashboard/assets/index-Gp3cLolR.js +0 -4
  302. package/static/settings/assets/NetworkPage-BVkasFGM.js +0 -2
  303. package/static/settings/assets/ai-connections-C6yaE6WQ.js +0 -1
  304. package/static/settings/assets/index-BdXwm8nh.js +0 -4
  305. package/static/settings/assets/settings-Cx9D_1qj.css +0 -1
  306. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client/normalize.d.ts +0 -0
  307. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client/normalize.js +0 -0
  308. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client/request.d.ts +0 -0
  309. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client/request.js +0 -0
  310. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client/types.d.ts +0 -0
  311. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client/types.js +0 -0
  312. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/base-adapter.d.ts +0 -0
  313. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/base-adapter.js +0 -0
  314. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/codex.d.ts +0 -0
  315. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/codex.js +0 -0
  316. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/index.d.ts +0 -0
  317. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/index.js +0 -0
  318. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/json-env-adapter.d.ts +0 -0
  319. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/json-env-adapter.js +0 -0
  320. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/pi.d.ts +0 -0
  321. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/pi.js +0 -0
  322. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/transaction.d.ts +0 -0
  323. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/transaction.js +0 -0
  324. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/types.d.ts +0 -0
  325. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/types.js +0 -0
  326. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/credential-storage.d.ts +0 -0
  327. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/credential-storage.js +0 -0
  328. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/endpoint-urls.d.ts +0 -0
  329. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/endpoint-urls.js +0 -0
  330. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/provider-catalog.d.ts +0 -0
  331. /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/provider-catalog.js +0 -0
@@ -40,7 +40,23 @@ export declare function createAdminServicesCapabilities(req: AuthenticatedReques
40
40
  };
41
41
  };
42
42
  export declare function readDurableAdminEnvironment(): Record<string, string>;
43
- export declare function writeDurableAdminEnvironmentPatch(input: Record<string, string>): void;
43
+ /**
44
+ * Tunnel profiles exactly as the runtime resolved them.
45
+ *
46
+ * `credentialEnvKey` is the profile-scoped key when one is configured, so a caller can
47
+ * write a secret where the runtime will actually read it.
48
+ */
49
+ export declare function projectTunnelProfiles(): Array<{
50
+ id: string;
51
+ provider: string;
52
+ label?: string;
53
+ publicUrl?: string;
54
+ credentialEnvKey?: string;
55
+ credentialConfigured: boolean;
56
+ active: boolean;
57
+ parameters?: Record<string, string>;
58
+ }>;
59
+ export declare function writeDurableAdminEnvironmentPatch(input: Record<string, string>, removals?: string[]): void;
44
60
  /**
45
61
  * Why a coordinated public domain cannot be served, or `null` when nothing
46
62
  * rules it out.
@@ -15,6 +15,7 @@ exports.sanitizeLogMessage = sanitizeLogMessage;
15
15
  exports.isAdminMutationAllowed = isAdminMutationAllowed;
16
16
  exports.createAdminServicesCapabilities = createAdminServicesCapabilities;
17
17
  exports.readDurableAdminEnvironment = readDurableAdminEnvironment;
18
+ exports.projectTunnelProfiles = projectTunnelProfiles;
18
19
  exports.writeDurableAdminEnvironmentPatch = writeDurableAdminEnvironmentPatch;
19
20
  exports.describeUnservedPublicRoute = describeUnservedPublicRoute;
20
21
  exports.registerAdminRoutes = registerAdminRoutes;
@@ -25,6 +26,8 @@ const fs_2 = require("fs");
25
26
  const readline_1 = require("readline");
26
27
  const runtime_1 = require("../../runtime");
27
28
  const log_file_1 = require("../../logging/log-file");
29
+ const TunnelProviderCatalog_1 = require("../../tunnel/TunnelProviderCatalog");
30
+ const TunnelProfiles_1 = require("../../tunnel/TunnelProfiles");
28
31
  const GatewayAdminProxyAuth_1 = require("../../runtime/GatewayAdminProxyAuth");
29
32
  const CONFIG_DIR = path_1.default.resolve(runtime_1.PACKAGE_ROOT, 'config');
30
33
  function getEnvFilePath() {
@@ -110,7 +113,7 @@ function sanitizeEnvForRead(env) {
110
113
  function createAllowedAdminConfigPatch(input) {
111
114
  const patch = {};
112
115
  for (const [key, value] of Object.entries(input)) {
113
- if (!ALLOWED_ADMIN_CONFIG_KEY_SET.has(key)) {
116
+ if (!ALLOWED_ADMIN_CONFIG_KEY_SET.has(key) && !(0, TunnelProviderCatalog_1.isTunnelProfileCredentialEnvKey)(key)) {
114
117
  continue;
115
118
  }
116
119
  if (isAdminSecretEnvKey(key) && !value) {
@@ -248,11 +251,40 @@ function writeEnvFile(filePath, config) {
248
251
  function readDurableAdminEnvironment() {
249
252
  return readEnvFile(getEnvFilePath());
250
253
  }
251
- function writeDurableAdminEnvironmentPatch(input) {
254
+ /**
255
+ * Tunnel profiles exactly as the runtime resolved them.
256
+ *
257
+ * `credentialEnvKey` is the profile-scoped key when one is configured, so a caller can
258
+ * write a secret where the runtime will actually read it.
259
+ */
260
+ function projectTunnelProfiles() {
261
+ const state = (0, TunnelProfiles_1.resolveTunnelProfileState)(process.env);
262
+ return state.profiles.map((profile) => ({
263
+ id: profile.id,
264
+ provider: profile.provider,
265
+ ...(profile.label ? { label: profile.label } : {}),
266
+ ...(profile.publicUrl ? { publicUrl: profile.publicUrl } : {}),
267
+ ...(profile.credentialEnvKey ? { credentialEnvKey: profile.credentialEnvKey } : {}),
268
+ credentialConfigured: profile.credentialConfigured === true,
269
+ active: state.activeProfile?.id === profile.id,
270
+ // Served to the console so an edit there cannot silently erase parameters the settings
271
+ // page wrote.
272
+ ...(profile.parameters ? { parameters: profile.parameters } : {}),
273
+ }));
274
+ }
275
+ function writeDurableAdminEnvironmentPatch(input, removals = []) {
252
276
  const filePath = getEnvFilePath();
253
277
  const current = readEnvFile(filePath);
254
278
  const patch = createAllowedAdminConfigPatch(input);
255
- writeEnvFile(filePath, { ...current, ...patch });
279
+ const next = { ...current, ...patch };
280
+ // Deleting a profile has to delete its credential: an empty secret value is filtered
281
+ // out of the patch (see createAllowedAdminConfigPatch), so removals are explicit.
282
+ for (const key of removals) {
283
+ if (ALLOWED_ADMIN_CONFIG_KEY_SET.has(key) || (0, TunnelProviderCatalog_1.isTunnelProfileCredentialEnvKey)(key)) {
284
+ delete next[key];
285
+ }
286
+ }
287
+ writeEnvFile(filePath, next);
256
288
  }
257
289
  /**
258
290
  * List available config files
@@ -411,6 +443,11 @@ function registerAdminRoutes(server, options = {}) {
411
443
  sendJson(res, 200, {
412
444
  ...sanitizeEnvForRead(env),
413
445
  configFiles: listConfigFiles(),
446
+ // Operator pages render the same provider axis the runtime honours.
447
+ providers: TunnelProviderCatalog_1.TUNNEL_PROVIDERS,
448
+ // Profiles as the runtime resolved them, including the credential key that belongs
449
+ // to each profile: the operator console must not invent its own key naming.
450
+ tunnelProfiles: projectTunnelProfiles(),
414
451
  });
415
452
  }
416
453
  catch (error) {
@@ -6,6 +6,7 @@ import type { ProviderConnectService } from '../ai-gateway/connect';
6
6
  import type { ProviderModelSelectionService } from '../ai-gateway/models/ProviderModelSelectionService';
7
7
  import type { ProviderQuotaService } from '../ai-gateway/quota';
8
8
  import { type ProviderCustomModelsService, type ProviderModelsService } from '../ai-gateway/models';
9
+ import type { PodInterfaceKeyGrant } from '../ai-gateway/pod/PodInterfaceKeyStore';
9
10
  import type { AiConnectionsInvocationKeyIssuer } from '../ai-gateway/auth/AiConnectionsInvocationKeyIssuer';
10
11
  import { type AiClientConfigurationCapabilityDescriptor } from '../service/AiClientConfigurationService';
11
12
  export interface AiGatewayManagementHandlerOptions {
@@ -25,6 +26,11 @@ export interface AiGatewayManagementHandlerOptions {
25
26
  gatewayAccessKeyRepository?: GatewayAccessKeyRepository;
26
27
  /** Reuses the configured CSS authenticator; never trusts the claimed registration owner. */
27
28
  validateClientCredential?: (apiKey: string) => Promise<AuthResult>;
29
+ /**
30
+ * Server-side Pod access for the owner. The wrapper being registered is the owner's own
31
+ * interface key, so registering it is also the moment Xpod is granted its use.
32
+ */
33
+ podInterfaceKeys?: PodInterfaceKeyGrant;
28
34
  aiClientConfiguration?: AiClientConfigurationCapabilityDescriptor;
29
35
  aiConnectionInvocationKeyIssuer?: Pick<AiConnectionsInvocationKeyIssuer, 'issue' | 'issueClientConfiguration'>;
30
36
  jsonBodyLimitBytes?: number;
@@ -5,8 +5,10 @@ const node_crypto_1 = require("node:crypto");
5
5
  const global_logger_factory_1 = require("global-logger-factory");
6
6
  const readBoundedJsonBody_1 = require("../http/readBoundedJsonBody");
7
7
  const GatewayPrincipal_1 = require("../ai-gateway/auth/GatewayPrincipal");
8
+ const AuthContext_1 = require("../auth/AuthContext");
8
9
  const models_1 = require("../ai-gateway/models");
9
10
  const AiConnectionsServiceAccess_1 = require("../ai-gateway/service-access/AiConnectionsServiceAccess");
11
+ const OwnerPodAccess_1 = require("../ai-gateway/pod/OwnerPodAccess");
10
12
  const AiClientConfigurationService_1 = require("../service/AiClientConfigurationService");
11
13
  const errors_1 = require("../ai-gateway/errors");
12
14
  const EmbeddingModelPolicy_1 = require("../../ai/service/EmbeddingModelPolicy");
@@ -117,6 +119,15 @@ function registerAiGatewayManagementRoutes(server, options) {
117
119
  sendJson(response, 403, { error: 'CSS client credential belongs to another WebID' });
118
120
  return;
119
121
  }
122
+ if ((0, AuthContext_1.hasSolidClientCredentialsAuthority)(verified.context)) {
123
+ // Sealed before the record is written, because writing the record is the first thing
124
+ // that needs it: background components reach this Pod through the standard interface
125
+ // as the owner, never through the caller's network position.
126
+ await options.podInterfaceKeys?.saveKey(owner, {
127
+ clientId: verified.context.clientId,
128
+ clientSecret: verified.context.clientSecret,
129
+ });
130
+ }
120
131
  const name = normalizeOptionalString(body.name) ?? 'Xpod API Key';
121
132
  const keyId = repository.createKeyId(owner, options.deployment);
122
133
  const createdAt = new Date();
@@ -1329,7 +1340,7 @@ function sendCredentialPoolError(response, error) {
1329
1340
  }
1330
1341
  function sendGatewayAccessKeyError(response, error) {
1331
1342
  const message = error instanceof Error ? error.message : String(error);
1332
- if (message === 'service_access_missing') {
1343
+ if ((0, OwnerPodAccess_1.isPodAccessFailure)(message)) {
1333
1344
  sendJson(response, 403, { error: 'service_access_missing' });
1334
1345
  return;
1335
1346
  }
@@ -1465,9 +1476,11 @@ function sendModelSelectionError(response, error) {
1465
1476
  model_selection_exact_update_failed: { status: 409, error: 'model_selection_conflict' },
1466
1477
  model_selection_provider_update_failed: { status: 409, error: 'model_selection_conflict' },
1467
1478
  service_access_missing: { status: 403, error: 'service_access_missing' },
1468
- hosted_pod_auth_required: { status: 401, error: 'authentication_required' },
1469
- hosted_pod_solid_principal_required: { status: 403, error: 'solid_principal_required' },
1470
- hosted_pod_owner_mismatch: { status: 403, error: 'pod_owner_mismatch' },
1479
+ pod_interface_key_missing: { status: 403, error: 'service_access_missing' },
1480
+ pod_interface_key_rejected: { status: 403, error: 'service_access_missing' },
1481
+ caller_dpop_replay_unsupported: { status: 403, error: 'service_access_missing' },
1482
+ caller_owner_mismatch: { status: 403, error: 'pod_owner_mismatch' },
1483
+ caller_pod_access_unavailable: { status: 401, error: 'authentication_required' },
1471
1484
  };
1472
1485
  const mapped = stable[message];
1473
1486
  if (mapped) {
@@ -44,8 +44,14 @@ function registerEdgeNodeSignalRoutes(server, options) {
44
44
  let metadata = mergeMetadata(existing?.metadata ?? {}, payload, now);
45
45
  // 从 DB connectivity 列注入 subdomain/ipv4,供 dnsCoordinator 使用
46
46
  const connectivityInfo = await repo.getNodeConnectivityInfo(nodeId);
47
+ // The subdomain a node may publish is assigned by the control plane, never by the
48
+ // node itself: a heartbeat must not be able to retarget another node's record.
49
+ delete metadata.subdomain;
50
+ if (isRecord(metadata.dns)) {
51
+ metadata.dns = Object.fromEntries(Object.entries(metadata.dns).filter(([key]) => key !== 'subdomain'));
52
+ }
47
53
  if (connectivityInfo) {
48
- if (connectivityInfo.subdomain && !metadata.subdomain) {
54
+ if (connectivityInfo.subdomain) {
49
55
  metadata.subdomain = connectivityInfo.subdomain;
50
56
  }
51
57
  if (connectivityInfo.ipv4 && !metadata.ipv4) {
@@ -78,7 +84,9 @@ function registerEdgeNodeSignalRoutes(server, options) {
78
84
  }
79
85
  }
80
86
  if (dnsCoordinator) {
81
- await dnsCoordinator.synchronize(nodeId, metadata);
87
+ // The control plane decides which subdomain this node owns; the coordinator gets
88
+ // that assignment explicitly instead of reading it back out of node metadata.
89
+ await dnsCoordinator.synchronize(nodeId, metadata, { subdomain: connectivityInfo?.subdomain });
82
90
  }
83
91
  logger.debug(`Signal received from node ${nodeId}`);
84
92
  sendJson(response, 200, {
@@ -1,6 +1,7 @@
1
1
  import { getLoggerFor } from 'global-logger-factory';
2
2
  import type { ApiServer } from '../ApiServer';
3
3
  import type { AuthContext } from '../auth/AuthContext';
4
+ import { type TunnelProviderDescriptor } from '../../tunnel/TunnelProviderCatalog';
4
5
  export interface NetworkSettingsStatus {
5
6
  endpoint: string;
6
7
  addresses: {
@@ -22,6 +23,21 @@ export interface NetworkSettingsStatus {
22
23
  renewCertificate: boolean;
23
24
  };
24
25
  configuration?: NetworkDesiredConfiguration;
26
+ /**
27
+ * The provider axis, served so the settings page renders the same declaration the
28
+ * runtime honours instead of keeping its own list.
29
+ */
30
+ providers?: readonly TunnelProviderDescriptor[];
31
+ /**
32
+ * The address a remote tunnel must forward to.
33
+ *
34
+ * Remotely-managed tunnels dial a port the operator typed into a provider console, so the
35
+ * page shows this value to copy rather than making the operator guess it.
36
+ */
37
+ ingress?: {
38
+ port: number;
39
+ originUrl: string;
40
+ };
25
41
  }
26
42
  export interface NetworkDesiredConfiguration {
27
43
  domainDns: {
@@ -51,12 +67,17 @@ export interface NetworkDesiredConfiguration {
51
67
  }
52
68
  export interface NetworkTunnelProfile {
53
69
  id: string;
54
- provider: 'ngrok' | 'cloudflare' | 'frp';
70
+ provider: string;
55
71
  label: string;
56
- publicEndpoint?: string;
72
+ publicUrl?: string;
57
73
  credentialConfigured: boolean;
58
74
  parameters?: Record<string, string>;
59
75
  }
76
+ /** `publicEndpoint` is the field older settings clients sent; `publicUrl` is canonical. */
77
+ export type NetworkTunnelProfilePatch = Omit<NetworkTunnelProfile, 'credentialConfigured'> & {
78
+ credential?: string;
79
+ publicEndpoint?: string;
80
+ };
60
81
  export type NetworkConfigurationPatch = {
61
82
  domainDns?: Partial<Omit<NetworkDesiredConfiguration['domainDns'], 'credentialConfigured'>> & {
62
83
  credential?: string;
@@ -64,9 +85,7 @@ export type NetworkConfigurationPatch = {
64
85
  https?: Partial<NetworkDesiredConfiguration['https']>;
65
86
  tunnelProfiles?: {
66
87
  activeProfileId?: string;
67
- profiles?: Array<Omit<NetworkTunnelProfile, 'credentialConfigured'> & {
68
- credential?: string;
69
- }>;
88
+ profiles?: NetworkTunnelProfilePatch[];
70
89
  };
71
90
  p2p?: Partial<NetworkDesiredConfiguration['p2p']>;
72
91
  };
@@ -77,6 +96,12 @@ export interface NetworkConfigurationStore {
77
96
  export interface CapabilityStatus {
78
97
  supported: boolean;
79
98
  status: string;
99
+ /** Readiness stage of the provider, when the provider reports one. */
100
+ stage?: string;
101
+ /** Endpoint the provider actually observed; distinct from a declared/configured address. */
102
+ endpoint?: string;
103
+ /** Redacted reason for a non-active status; absent when there is nothing to explain. */
104
+ detail?: string;
80
105
  }
81
106
  export type DiagnosticStatus = 'ok' | 'warning' | 'error' | 'unsupported';
82
107
  export interface NetworkDiagnosticCheckResult {
@@ -138,6 +163,20 @@ export interface NetworkSettingsHandlerOptions {
138
163
  internalAdminAuthSecret?: string;
139
164
  logger?: Pick<ReturnType<typeof getLoggerFor>, 'warn' | 'error'>;
140
165
  }
166
+ /** The ingress address this runtime listens on, when it published one. */
167
+ /**
168
+ * The address a provider console is configured with: the Gateway's tunnel entry.
169
+ *
170
+ * It is the listener that never treats a caller as local, so a tunnel reaching the runtime
171
+ * through it cannot inherit local trust whatever headers it carries. The banner the user
172
+ * copies is this one number; the Gateway's own port is what they type in a browser.
173
+ */
174
+ export declare function readIngressAddress(env?: NodeJS.ProcessEnv): {
175
+ ingress?: {
176
+ port: number;
177
+ originUrl: string;
178
+ };
179
+ };
141
180
  export declare function registerNetworkSettingsRoutes(server: ApiServer, options: NetworkSettingsHandlerOptions): void;
142
181
  export declare function createDeploymentNetworkSettingsAuthorizer(options?: NetworkSettingsIdentityAuthorizerOptions): NetworkSettingsAuthorizer;
143
182
  export declare function createAddressReaders(input: {
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readIngressAddress = readIngressAddress;
3
4
  exports.registerNetworkSettingsRoutes = registerNetworkSettingsRoutes;
4
5
  exports.createDeploymentNetworkSettingsAuthorizer = createDeploymentNetworkSettingsAuthorizer;
5
6
  exports.createAddressReaders = createAddressReaders;
@@ -13,6 +14,22 @@ const node_os_1 = require("node:os");
13
14
  const global_logger_factory_1 = require("global-logger-factory");
14
15
  const readBoundedJsonBody_1 = require("../http/readBoundedJsonBody");
15
16
  const AdminHandler_1 = require("./AdminHandler");
17
+ const TunnelProviderCatalog_1 = require("../../tunnel/TunnelProviderCatalog");
18
+ /** The ingress address this runtime listens on, when it published one. */
19
+ /**
20
+ * The address a provider console is configured with: the Gateway's tunnel entry.
21
+ *
22
+ * It is the listener that never treats a caller as local, so a tunnel reaching the runtime
23
+ * through it cannot inherit local trust whatever headers it carries. The banner the user
24
+ * copies is this one number; the Gateway's own port is what they type in a browser.
25
+ */
26
+ function readIngressAddress(env = process.env) {
27
+ const port = Number.parseInt(env.XPOD_GATEWAY_INGRESS_PORT ?? '', 10);
28
+ if (!Number.isInteger(port) || port <= 0 || port > 65535) {
29
+ return {};
30
+ }
31
+ return { ingress: { port, originUrl: `http://127.0.0.1:${port}` } };
32
+ }
16
33
  function registerNetworkSettingsRoutes(server, options) {
17
34
  const logger = options.logger ?? (0, global_logger_factory_1.getLoggerFor)('NetworkSettingsHandler');
18
35
  const authorizer = options.authorizer ?? createDeploymentNetworkSettingsAuthorizer();
@@ -23,7 +40,12 @@ function registerNetworkSettingsRoutes(server, options) {
23
40
  try {
24
41
  const status = await readNetworkStatus(options, logger);
25
42
  const configuration = await options.configurationStore?.read();
26
- sendJson(response, 200, configuration ? { ...status, configuration } : status);
43
+ sendJson(response, 200, {
44
+ ...status,
45
+ providers: TunnelProviderCatalog_1.TUNNEL_PROVIDERS,
46
+ ...readIngressAddress(),
47
+ ...(configuration ? { configuration } : {}),
48
+ });
27
49
  }
28
50
  catch (error) {
29
51
  logger.error(`Failed to read network settings status: ${redactSecretText(error)}`);
@@ -134,11 +156,16 @@ function parseNetworkConfigurationPatch(value) {
134
156
  return value;
135
157
  }
136
158
  function validTunnelProfile(value) {
137
- if (!isPlainRecord(value) || hasUnknownKeys(value, ['id', 'provider', 'label', 'publicEndpoint', 'credential', 'parameters']))
159
+ // `publicUrl` is canonical; `publicEndpoint` is what older clients sent.
160
+ if (!isPlainRecord(value) || hasUnknownKeys(value, ['id', 'provider', 'label', 'publicUrl', 'publicEndpoint', 'credential', 'parameters']))
138
161
  return false;
139
162
  if (typeof value.id !== 'string' || !value.id.trim() || typeof value.label !== 'string' || !value.label.trim())
140
163
  return false;
141
- if (!['ngrok', 'cloudflare', 'frp'].includes(String(value.provider)) || !optionalString(value.publicEndpoint) || !optionalString(value.credential))
164
+ if (!(0, TunnelProviderCatalog_1.isTunnelProviderId)(value.provider) || !optionalString(value.publicUrl) || !optionalString(value.publicEndpoint) || !optionalString(value.credential))
165
+ return false;
166
+ // A provider the local runtime cannot start must be refused here rather than stored and
167
+ // reported as "configured" while nothing can ever come up.
168
+ if ((0, TunnelProviderCatalog_1.tunnelProviderDescriptor)(value.provider)?.runtimeSupported === false)
142
169
  return false;
143
170
  return value.parameters === undefined || (isPlainRecord(value.parameters) && Object.values(value.parameters).every((item) => typeof item === 'string'));
144
171
  }
@@ -205,16 +232,20 @@ function createTunnelStatusReader(tunnelProvider) {
205
232
  return {
206
233
  read: async () => {
207
234
  const status = tunnelProvider.getStatus();
235
+ const detail = status.error ? redactSecretText(status.error) : undefined;
236
+ const observed = typeof status.endpoint === 'string' && status.endpoint ? { endpoint: status.endpoint } : {};
237
+ const stage = status.stage ? { stage: status.stage } : {};
208
238
  if (status.connected) {
209
- return { supported: true, status: 'active' };
239
+ return { supported: true, status: 'active', ...stage, ...observed };
210
240
  }
211
241
  if (status.running) {
212
- return { supported: true, status: 'starting' };
242
+ // A running process is not a published proxy: say which stage it reached.
243
+ return { supported: true, status: 'starting', ...stage, ...observed };
213
244
  }
214
- if (status.error) {
215
- return { supported: true, status: 'error' };
245
+ if (detail) {
246
+ return { supported: true, status: 'error', ...stage, ...observed, detail };
216
247
  }
217
- return { supported: true, status: 'inactive' };
248
+ return { supported: true, status: 'inactive', ...observed };
218
249
  },
219
250
  };
220
251
  }
@@ -302,11 +333,15 @@ function safeAddressList(reader, logger) {
302
333
  function buildDefaultDiagnostics(options, logger) {
303
334
  return [
304
335
  {
305
- id: 'endpoint',
306
- label: 'Endpoint',
336
+ // This check only proves that an address is configured. Reachability is a different
337
+ // fact and needs a real probe, so the result must not be rendered as one.
338
+ id: 'address-configuration',
339
+ label: 'Address configuration',
307
340
  run: async () => {
308
341
  const endpoint = normalizeEndpoint(resolveValue(options.endpoint));
309
- return endpoint ? { status: 'ok', detail: endpoint } : { status: 'unsupported', detail: 'endpoint_unavailable' };
342
+ return endpoint
343
+ ? { status: 'ok', detail: `configured: ${endpoint}` }
344
+ : { status: 'unsupported', detail: 'endpoint_unavailable' };
310
345
  },
311
346
  },
312
347
  {
@@ -2,7 +2,7 @@ import { getLoggerFor } from 'global-logger-factory';
2
2
  import type { ApiServer } from '../ApiServer';
3
3
  import type { PodLookupRepository } from '../../identity/drizzle/PodLookupRepository';
4
4
  import type { UsageRepository } from '../../storage/quota/UsageRepository';
5
- import type { InternalPodAccessTokenProvider } from '../ai-gateway/pod/HostedPodDataAccess';
5
+ import type { PodAccessFetchProvider } from '../ai-gateway/pod/OwnerPodAccess';
6
6
  export interface PodSettingsStatus {
7
7
  identity: {
8
8
  webId: string;
@@ -57,10 +57,10 @@ export interface PodSettingsHandlerOptions {
57
57
  }
58
58
  export declare function registerPodSettingsRoutes(server: ApiServer, options: PodSettingsHandlerOptions): void;
59
59
  export declare class DrizzlePodAiConnectionsStatusReader implements PodAiConnectionsStatusReader {
60
- private readonly internalPodAccess?;
60
+ private readonly podAccess?;
61
61
  private readonly deployment;
62
62
  private readonly dbFactory;
63
- constructor(internalPodAccess?: InternalPodAccessTokenProvider | undefined, deployment?: string, dbFactory?: (input: {
63
+ constructor(podAccess?: PodAccessFetchProvider | undefined, deployment?: string, dbFactory?: (input: {
64
64
  webId: string;
65
65
  podUrl: string;
66
66
  fetch: typeof fetch;
@@ -77,13 +77,13 @@ async function readStorageStatus(usageRepo, pod) {
77
77
  };
78
78
  }
79
79
  class DrizzlePodAiConnectionsStatusReader {
80
- constructor(internalPodAccess, deployment = 'local', dbFactory = createAiConnectionsStatusDb) {
81
- this.internalPodAccess = internalPodAccess;
80
+ constructor(podAccess, deployment = 'local', dbFactory = createAiConnectionsStatusDb) {
81
+ this.podAccess = podAccess;
82
82
  this.deployment = deployment;
83
83
  this.dbFactory = dbFactory;
84
84
  }
85
85
  async read({ webId, podUrl }) {
86
- const trustedFetch = await this.internalPodAccess?.getTrustedFetch(webId);
86
+ const trustedFetch = await this.podAccess?.getPodFetch(webId);
87
87
  if (!trustedFetch) {
88
88
  return { status: 'unsupported', reason: 'not_configured' };
89
89
  }
@@ -14,11 +14,12 @@
14
14
  * 返回 SP 配置状态,供 Linx 查询
15
15
  */
16
16
  import type { ApiServer } from '../ApiServer';
17
+ import type { AccessRoute } from '../../edge/reachability/types';
17
18
  import type { EdgeNodeRepository } from '../../identity/drizzle/EdgeNodeRepository';
18
19
  import type { ServiceTokenRepositoryPort } from '../../identity/drizzle/ServiceTokenRepository';
19
20
  import type { DdnsRepository } from '../../identity/drizzle/DdnsRepository';
20
21
  import type { DnsProvider } from '../../dns/DnsProvider';
21
- import type { TunnelProvider } from '../../tunnel/TunnelProvider';
22
+ import type { TunnelProvider, TunnelConfig } from '../../tunnel/TunnelProvider';
22
23
  export interface ProvisionHandlerOptions {
23
24
  repository: EdgeNodeRepository;
24
25
  ddnsRepo?: DdnsRepository;
@@ -38,6 +39,11 @@ export interface ProvisionHandlerOptions {
38
39
  serviceTokenRepository?: ServiceTokenRepositoryPort;
39
40
  }
40
41
  export declare function registerProvisionRoutes(server: ApiServer, options: ProvisionHandlerOptions): void;
42
+ export declare function readManagedTunnelConfig(metadata: Record<string, unknown> | null): {
43
+ subdomain?: string;
44
+ localPort?: number;
45
+ config: TunnelConfig;
46
+ } | undefined;
41
47
  /**
42
48
  * Local 端 SP 状态查询路由
43
49
  */
@@ -62,6 +68,25 @@ export interface ProvisionStatusOptions {
62
68
  cloudBaseUrl?: string;
63
69
  /** provisionCode(可选,由环境变量传入) */
64
70
  provisionCode?: string;
71
+ /**
72
+ * Live state of the public route, read per request.
73
+ *
74
+ * A configured tunnel is not the same thing as a reachable public route, and a
75
+ * node whose tunnel is down still owns a canonical URL that same-machine
76
+ * clients reach over the loopback access route (`docs/multi-channel-access.md`).
77
+ * Clients need to tell those apart before they decide whether a canonical
78
+ * request can leave the machine, so this is reported rather than implied.
79
+ */
80
+ readPublicRoute?: () => PublicRouteStatus | Promise<PublicRouteStatus>;
81
+ /**
82
+ * Every access point this node can currently prove it offers, read per request.
83
+ *
84
+ * A canonical URL is one identity reachable over several physical paths, and
85
+ * only the client knows which path it is standing on, so the runtime reports
86
+ * the paths themselves (canonical public route, tunnel, ...) instead of picking
87
+ * one for the client (`docs/multi-channel-access.md`).
88
+ */
89
+ readAccessRoutes?: () => AccessRoute[] | Promise<AccessRoute[]>;
65
90
  /** Persist refreshed local-only setup state to the single local setup file. */
66
91
  persistState?: (state: ProvisionStatusStateUpdate) => Promise<void> | void;
67
92
  /** 测试/调试注入 */
@@ -69,6 +94,15 @@ export interface ProvisionStatusOptions {
69
94
  now?: () => number;
70
95
  refreshGraceSeconds?: number;
71
96
  }
97
+ /** What a client can learn about reaching this node's canonical URL from outside. */
98
+ export interface PublicRouteStatus {
99
+ /** A tunnel provider is configured for this node. */
100
+ configured: boolean;
101
+ /** The provider confirmed a proxy-ready public route. */
102
+ available: boolean;
103
+ provider?: string;
104
+ endpoint?: string;
105
+ }
72
106
  export interface ProvisionStatusStateUpdate {
73
107
  nodeId: string;
74
108
  nodeToken: string;
@@ -16,10 +16,12 @@
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.registerProvisionRoutes = registerProvisionRoutes;
19
+ exports.readManagedTunnelConfig = readManagedTunnelConfig;
19
20
  exports.registerProvisionStatusRoute = registerProvisionStatusRoute;
20
21
  exports.createLocalSetupProvisionStateWriter = createLocalSetupProvisionStateWriter;
21
22
  const node_crypto_1 = require("node:crypto");
22
23
  const global_logger_factory_1 = require("global-logger-factory");
24
+ const TunnelProviderCatalog_1 = require("../../tunnel/TunnelProviderCatalog");
23
25
  const ProvisionCodeCodec_1 = require("../../provision/ProvisionCodeCodec");
24
26
  const ServiceAccessTokenCodec_1 = require("../../provision/ServiceAccessTokenCodec");
25
27
  const LocalProvisionState_1 = require("../../provision/LocalProvisionState");
@@ -421,7 +423,10 @@ function readManagedTunnelConfig(metadata) {
421
423
  const tunnelId = value.tunnelId;
422
424
  const subdomain = typeof value.subdomain === 'string' ? value.subdomain : undefined;
423
425
  const localPort = typeof value.localPort === 'number' ? value.localPort : undefined;
424
- if ((provider !== 'cloudflare' && provider !== 'frp' && provider !== 'sakura-frp')
426
+ // Provision callers historically spell Sakura with a hyphen; the catalogue owns the
427
+ // canonical id, so accept either spelling and store one.
428
+ const canonicalProvider = (0, TunnelProviderCatalog_1.parseTunnelProvider)(provider);
429
+ if ((canonicalProvider !== 'cloudflare' && canonicalProvider !== 'frp' && canonicalProvider !== 'sakura_frp')
425
430
  || typeof endpoint !== 'string') {
426
431
  return undefined;
427
432
  }
@@ -429,7 +434,7 @@ function readManagedTunnelConfig(metadata) {
429
434
  subdomain,
430
435
  localPort,
431
436
  config: {
432
- provider,
437
+ provider: canonicalProvider,
433
438
  subdomain: subdomain ?? 'local',
434
439
  endpoint,
435
440
  tunnelId: typeof tunnelId === 'string' ? tunnelId : undefined,
@@ -437,6 +442,21 @@ function readManagedTunnelConfig(metadata) {
437
442
  },
438
443
  };
439
444
  }
445
+ /**
446
+ * Only the facts a client needs to rank and use an access point are reported:
447
+ * where it points, how it is reached and whether it is currently known to work.
448
+ */
449
+ function reportableAccessRoutes(routes) {
450
+ return (routes ?? []).map((route) => ({
451
+ id: route.id,
452
+ kind: route.kind,
453
+ targetUrl: route.targetUrl,
454
+ priority: route.priority,
455
+ requiresManagedClient: route.requiresManagedClient,
456
+ visibility: route.visibility,
457
+ health: route.health,
458
+ }));
459
+ }
440
460
  function registerProvisionStatusRoute(server, options) {
441
461
  const logger = (0, global_logger_factory_1.getLoggerFor)('ProvisionStatusHandler');
442
462
  const fetchImpl = options.fetchImpl ?? fetch;
@@ -474,6 +494,37 @@ function registerProvisionStatusRoute(server, options) {
474
494
  body.cloudUrl = options.cloudUrl;
475
495
  body.oidcIssuer = normalizeUrl(options.cloudBaseUrl);
476
496
  }
497
+ // Whether the canonical URL is reachable from outside is a separate fact
498
+ // from whether it exists. A failed read is reported as unavailable, never as
499
+ // available, because guessing here would send a same-machine client to a
500
+ // public route that does not answer.
501
+ if (options.readPublicRoute) {
502
+ let publicRoute;
503
+ try {
504
+ publicRoute = await options.readPublicRoute();
505
+ }
506
+ catch (error) {
507
+ logger.warn(`Failed to read public route state: ${error}`);
508
+ }
509
+ body.publicRoute = {
510
+ configured: Boolean(publicRoute?.configured),
511
+ available: Boolean(publicRoute?.available),
512
+ ...(publicRoute?.provider ? { provider: publicRoute.provider } : {}),
513
+ ...(publicRoute?.endpoint ? { endpoint: publicRoute.endpoint } : {}),
514
+ };
515
+ }
516
+ // Access points are reported as data: which one is best depends on where the
517
+ // client stands, which only the client knows.
518
+ if (options.readAccessRoutes) {
519
+ let routes;
520
+ try {
521
+ routes = await options.readAccessRoutes();
522
+ }
523
+ catch (error) {
524
+ logger.warn(`Failed to read access routes: ${error}`);
525
+ }
526
+ body.routes = reportableAccessRoutes(routes);
527
+ }
477
528
  if (registered) {
478
529
  const canRefresh = canRefreshProvisionStatus(options, state);
479
530
  const currentNow = now();
@@ -9,5 +9,11 @@ export interface ReachabilityHandlerOptions {
9
9
  maxActiveP2PSessionsPerNode?: number;
10
10
  maxP2PCandidatesPerUpdate?: number;
11
11
  maxP2PCandidatesPerSession?: number;
12
+ /**
13
+ * Whether a Solid principal may act on a node, e.g. through Pod ownership or an
14
+ * explicit grant. Absent means "cannot prove access", which denies instead of
15
+ * handing an unrelated WebID signaling access to the node.
16
+ */
17
+ canAccessNode?: (nodeId: string, webId: string) => Promise<boolean> | boolean;
12
18
  }
13
19
  export declare function registerReachabilityRoutes(server: ApiServer, options: ReachabilityHandlerOptions): void;