@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
@@ -42,7 +42,7 @@ function registerReachabilityRoutes(server, options) {
42
42
  }
43
43
  }, { optionalAuth: true });
44
44
  server.post('/v1/signal/nodes/:nodeId/sessions', async (request, response, params) => {
45
- const access = resolveSessionAccess(request, params.nodeId);
45
+ const access = await resolveSessionAccess(request, params.nodeId, options, 'node');
46
46
  if (!access.allowed) {
47
47
  sendJson(response, access.status, { error: access.error });
48
48
  return;
@@ -119,7 +119,7 @@ function registerReachabilityRoutes(server, options) {
119
119
  sendJson(response, 400, { error: 'kind must be p2p or relay' });
120
120
  });
121
121
  server.get('/v1/signal/nodes/:nodeId/sessions', async (request, response, params) => {
122
- const access = resolveSessionAccess(request, params.nodeId);
122
+ const access = await resolveSessionAccess(request, params.nodeId, options, 'node');
123
123
  if (!access.allowed) {
124
124
  sendJson(response, access.status, { error: access.error });
125
125
  return;
@@ -137,7 +137,7 @@ function registerReachabilityRoutes(server, options) {
137
137
  }
138
138
  });
139
139
  server.get('/v1/signal/nodes/:nodeId/sessions/:sessionId', async (request, response, params) => {
140
- const access = resolveSessionAccess(request, params.nodeId);
140
+ const access = await resolveSessionAccess(request, params.nodeId, options, 'session');
141
141
  if (!access.allowed) {
142
142
  sendJson(response, access.status, { error: access.error });
143
143
  return;
@@ -155,7 +155,7 @@ function registerReachabilityRoutes(server, options) {
155
155
  }
156
156
  });
157
157
  server.post('/v1/signal/nodes/:nodeId/sessions/:sessionId/candidates', async (request, response, params) => {
158
- const access = resolveSessionAccess(request, params.nodeId);
158
+ const access = await resolveSessionAccess(request, params.nodeId, options, 'session');
159
159
  if (!access.allowed) {
160
160
  sendJson(response, access.status, { error: access.error });
161
161
  return;
@@ -214,14 +214,16 @@ function resolveAccess(request, nodeId) {
214
214
  if (auth.nodeId !== nodeId) {
215
215
  return { allowed: false, status: 403, error: 'Node token cannot access another node' };
216
216
  }
217
- return { allowed: true, audience: 'managed' };
217
+ // The node asking about itself stands on its own host, which is the one place its
218
+ // `local-only` loopback access point is usable (`docs/multi-channel-access.md`).
219
+ return { allowed: true, audience: 'local' };
218
220
  }
219
221
  if ((0, AuthContext_1.isServiceAuth)(auth)) {
220
222
  return { allowed: true, audience: 'managed' };
221
223
  }
222
224
  return { allowed: true, audience: 'public' };
223
225
  }
224
- function resolveSessionAccess(request, nodeId) {
226
+ async function resolveSessionAccess(request, nodeId, options, target) {
225
227
  const auth = request.auth;
226
228
  if (!auth) {
227
229
  return { allowed: false, status: 401, error: 'Authentication required' };
@@ -233,9 +235,26 @@ function resolveSessionAccess(request, nodeId) {
233
235
  return { allowed: true, kind: 'node', nodeId: auth.nodeId };
234
236
  }
235
237
  if ((0, AuthContext_1.isServiceAuth)(auth)) {
238
+ // Service principals act for the deployment, so they must carry the scope that
239
+ // covers reachability sessions instead of being trusted by principal type alone.
240
+ if (!(0, AuthContext_1.hasScope)(auth, 'network:write')) {
241
+ return { allowed: false, status: 403, error: 'Creating a reachability session requires network:write' };
242
+ }
236
243
  return { allowed: true, kind: 'service' };
237
244
  }
238
245
  if ((0, AuthContext_1.isSolidAuth)(auth)) {
246
+ // Node-wide operations need a resolvable relationship to the node (Pod ownership or
247
+ // an explicit grant): being logged in says nothing about this node. Operations on one
248
+ // session are gated by session ownership instead, so the owner keeps access to their
249
+ // own session even when node-wide discovery is not available to them.
250
+ if (target === 'node') {
251
+ const permitted = options.canAccessNode
252
+ ? await options.canAccessNode(nodeId, auth.webId)
253
+ : false;
254
+ if (!permitted) {
255
+ return { allowed: false, status: 403, error: 'WebID is not authorized for this node' };
256
+ }
257
+ }
239
258
  return { allowed: true, kind: 'solid', webId: auth.webId };
240
259
  }
241
260
  return { allowed: false, status: 403, error: 'Unsupported reachability session credentials' };
@@ -2,7 +2,12 @@ import type { NetworkConfigurationPatch, NetworkConfigurationStore, NetworkDesir
2
2
  type Env = Record<string, string | undefined>;
3
3
  export interface NetworkEnvironmentConfigurationStoreOptions {
4
4
  read(): Env | Promise<Env>;
5
- write(patch: Record<string, string>): void | Promise<void>;
5
+ /**
6
+ * Persists a patch. `removals` lists keys that must be deleted from the environment
7
+ * instead of overwritten — deleting a profile has to take its credential with it,
8
+ * otherwise the leftover secret rebuilds the tunnel the user just closed.
9
+ */
10
+ write(patch: Record<string, string>, removals?: string[]): void | Promise<void>;
6
11
  }
7
12
  export declare class NetworkEnvironmentConfigurationStore implements NetworkConfigurationStore {
8
13
  private readonly options;
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NetworkEnvironmentConfigurationStore = void 0;
4
+ const TunnelProfiles_1 = require("../../tunnel/TunnelProfiles");
5
+ const TunnelProviderCatalog_1 = require("../../tunnel/TunnelProviderCatalog");
4
6
  class NetworkEnvironmentConfigurationStore {
5
7
  constructor(options) {
6
8
  this.options = options;
@@ -10,9 +12,13 @@ class NetworkEnvironmentConfigurationStore {
10
12
  }
11
13
  async update(patch) {
12
14
  const current = await this.options.read();
13
- const envPatch = environmentPatch(patch, current);
14
- await this.options.write(envPatch);
15
- return configurationFromEnv({ ...current, ...envPatch });
15
+ const { envPatch, removals } = environmentPatch(patch, current);
16
+ await this.options.write(envPatch, removals);
17
+ const next = { ...current, ...envPatch };
18
+ for (const key of removals) {
19
+ delete next[key];
20
+ }
21
+ return configurationFromEnv(next);
16
22
  }
17
23
  }
18
24
  exports.NetworkEnvironmentConfigurationStore = NetworkEnvironmentConfigurationStore;
@@ -35,7 +41,12 @@ function configurationFromEnv(env) {
35
41
  ...(env.XPOD_HTTPS_KEY_PATH ? { certificateKeyPath: env.XPOD_HTTPS_KEY_PATH } : {}),
36
42
  renewBeforeDays: positiveInteger(env.XPOD_ACME_RENEW_BEFORE_DAYS, 30),
37
43
  },
38
- tunnelProfiles: { activeProfileId: env.XPOD_TUNNEL_ACTIVE_PROFILE_ID ?? '', profiles },
44
+ tunnelProfiles: {
45
+ activeProfileId: env.XPOD_TUNNEL_ACTIVE_PROFILE_ID !== undefined
46
+ ? (env.XPOD_TUNNEL_ACTIVE_PROFILE_ID.trim() || TunnelProfiles_1.TUNNEL_ACTIVE_PROFILE_NONE)
47
+ : '',
48
+ profiles,
49
+ },
39
50
  p2p: {
40
51
  enabled: env.XPOD_P2P_ENABLED === 'true',
41
52
  signalService: env.XPOD_P2P_SIGNAL_SERVICE ?? '',
@@ -45,6 +56,7 @@ function configurationFromEnv(env) {
45
56
  }
46
57
  function environmentPatch(patch, current) {
47
58
  const output = {};
59
+ const removals = new Set();
48
60
  if (patch.domainDns) {
49
61
  assign(output, 'XPOD_DNS_DOMAIN', patch.domainDns.domain);
50
62
  assign(output, 'XPOD_DDNS_ENABLED', boolString(patch.domainDns.ddnsEnabled));
@@ -57,8 +69,10 @@ function environmentPatch(patch, current) {
57
69
  assign(output, 'XPOD_HTTPS_MODE', patch.https.enabled === undefined ? undefined : patch.https.enabled ? 'acme' : 'off');
58
70
  assign(output, 'XPOD_ACME_EMAIL', patch.https.acmeEmail);
59
71
  assign(output, 'XPOD_ACME_DOMAINS', patch.https.domains?.join(','));
60
- assign(output, 'XPOD_HTTPS_CERT_PATH', patch.https.certificatePath);
61
- assign(output, 'XPOD_HTTPS_KEY_PATH', patch.https.certificateKeyPath);
72
+ // The runtime reads the ACME key names; the settings page used to write
73
+ // XPOD_HTTPS_* which nothing consumed.
74
+ assign(output, 'XPOD_ACME_CERTIFICATE_PATH', patch.https.certificatePath);
75
+ assign(output, 'XPOD_ACME_CERTIFICATE_KEY_PATH', patch.https.certificateKeyPath);
62
76
  assign(output, 'XPOD_ACME_RENEW_BEFORE_DAYS', numberString(patch.https.renewBeforeDays));
63
77
  }
64
78
  if (patch.p2p) {
@@ -67,19 +81,38 @@ function environmentPatch(patch, current) {
67
81
  assign(output, 'XPOD_P2P_FALLBACK_POLICY', patch.p2p.fallbackPolicy);
68
82
  }
69
83
  if (patch.tunnelProfiles) {
70
- assign(output, 'XPOD_TUNNEL_ACTIVE_PROFILE_ID', patch.tunnelProfiles.activeProfileId);
84
+ // An empty selection is the explicit off decision, stored as its own value so the
85
+ // runtime can tell it apart from "never configured".
86
+ assign(output, 'XPOD_TUNNEL_ACTIVE_PROFILE_ID', patch.tunnelProfiles.activeProfileId === ''
87
+ ? TunnelProfiles_1.TUNNEL_ACTIVE_PROFILE_NONE
88
+ : patch.tunnelProfiles.activeProfileId);
71
89
  if (patch.tunnelProfiles.profiles) {
72
- const serialized = patch.tunnelProfiles.profiles.map(({ credential, ...profile }) => profile);
90
+ const serialized = patch.tunnelProfiles.profiles.map(({ credential, publicEndpoint, ...profile }) => ({
91
+ ...profile,
92
+ // Canonical field name: the runtime reads publicUrl.
93
+ ...(profile.publicUrl ?? publicEndpoint ? { publicUrl: profile.publicUrl ?? publicEndpoint } : {}),
94
+ }));
73
95
  output.XPOD_TUNNEL_PROFILES = JSON.stringify(serialized);
74
- for (const profile of patch.tunnelProfiles.profiles)
75
- if (profile.credential !== undefined)
76
- output[tunnelCredentialKey(profile.provider)] = profile.credential;
96
+ for (const profile of patch.tunnelProfiles.profiles) {
97
+ if (profile.credential !== undefined && profile.credential !== '') {
98
+ output[(0, TunnelProfiles_1.tunnelProfileCredentialEnvKey)(profile.id)] = profile.credential;
99
+ }
100
+ }
101
+ // Credentials of profiles that are gone must go with them.
102
+ for (const key of Object.keys(current)) {
103
+ if (!(0, TunnelProviderCatalog_1.isTunnelProfileCredentialEnvKey)(key)) {
104
+ continue;
105
+ }
106
+ if (!patch.tunnelProfiles.profiles.some((profile) => (0, TunnelProfiles_1.tunnelProfileCredentialEnvKey)(profile.id) === key)) {
107
+ removals.add(key);
108
+ }
109
+ }
77
110
  }
78
111
  }
79
- return output;
112
+ return { envPatch: output, removals: [...removals] };
80
113
  }
81
114
  function parseProfiles(raw, env) {
82
- if (!raw)
115
+ if (raw === undefined)
83
116
  return [];
84
117
  try {
85
118
  const values = JSON.parse(raw);
@@ -89,21 +122,44 @@ function parseProfiles(raw, env) {
89
122
  if (!value || typeof value !== 'object' || Array.isArray(value))
90
123
  return [];
91
124
  const item = value;
92
- if (typeof item.id !== 'string' || typeof item.label !== 'string' || !['ngrok', 'cloudflare', 'frp'].includes(String(item.provider)))
125
+ if (typeof item.id !== 'string' || typeof item.label !== 'string' || !(0, TunnelProviderCatalog_1.isTunnelProviderId)(item.provider))
93
126
  return [];
94
127
  const provider = item.provider;
95
- return [{ id: item.id, provider, label: item.label, ...(typeof item.publicEndpoint === 'string' ? { publicEndpoint: item.publicEndpoint } : {}), credentialConfigured: Boolean(env[tunnelCredentialKey(provider)]), ...(plainStringRecord(item.parameters) ? { parameters: item.parameters } : {}) }];
128
+ const publicUrl = firstString(item.publicUrl, item.publicEndpoint);
129
+ const credentialKey = resolveCredentialKey(item.id, provider, env);
130
+ return [{
131
+ id: item.id,
132
+ provider,
133
+ label: item.label,
134
+ ...(publicUrl ? { publicUrl } : {}),
135
+ credentialConfigured: Boolean(env[credentialKey]),
136
+ ...(plainStringRecord(item.parameters) ? { parameters: item.parameters } : {}),
137
+ }];
96
138
  });
97
139
  }
98
140
  catch {
99
141
  return [];
100
142
  }
101
143
  }
144
+ /** Profile-scoped credential first; a provider-global key still serves legacy setups. */
145
+ function resolveCredentialKey(profileId, provider, env) {
146
+ const scopedKey = (0, TunnelProfiles_1.tunnelProfileCredentialEnvKey)(profileId);
147
+ if (env[scopedKey])
148
+ return scopedKey;
149
+ const legacyKey = (0, TunnelProviderCatalog_1.tunnelProviderDescriptor)(provider)?.legacyCredentialEnvKey;
150
+ return legacyKey && env[legacyKey] ? legacyKey : scopedKey;
151
+ }
152
+ function firstString(...values) {
153
+ for (const value of values) {
154
+ if (typeof value === 'string' && value.trim())
155
+ return value.trim();
156
+ }
157
+ return undefined;
158
+ }
102
159
  function splitList(value) { return value?.split(',').map((item) => item.trim()).filter(Boolean) ?? []; }
103
160
  function positiveInteger(value, fallback) { const parsed = Number(value); return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback; }
104
161
  function dnsCredential(env, provider) { return env[dnsCredentialKey(provider)]; }
105
162
  function dnsCredentialKey(provider) { return provider === 'tencent' ? 'XPOD_TENCENT_DNS_TOKEN' : provider === 'cloudflare' ? 'CLOUDFLARE_API_TOKEN' : 'XPOD_DNS_PROVIDER_TOKEN'; }
106
- function tunnelCredentialKey(provider) { return provider === 'ngrok' ? 'NGROK_AUTHTOKEN' : provider === 'cloudflare' ? 'CLOUDFLARE_TUNNEL_TOKEN' : 'FRP_TUNNEL_TOKEN'; }
107
163
  function p2pFallback(value) { return value === 'never' || value === 'prefer-p2p' ? value : 'when-direct-unavailable'; }
108
164
  function plainStringRecord(value) { return Boolean(value) && typeof value === 'object' && !Array.isArray(value) && Object.values(value).every((item) => typeof item === 'string'); }
109
165
  function boolString(value) { return value === undefined ? undefined : String(value); }
@@ -18,4 +18,22 @@ export interface ApiServiceHandle {
18
18
  stop: () => Promise<void>;
19
19
  }
20
20
  export declare function autoProvisionFirstRunLocal(config: ApiContainerConfig, logger: ReturnType<typeof getLoggerFor>): Promise<ApiContainerConfig>;
21
+ /**
22
+ * Port a managed tunnel forwards to.
23
+ *
24
+ * It must be the Gateway's ingress listener rather than the gateway port itself:
25
+ * a tunnel terminating on the gateway port reaches the Gateway from loopback and
26
+ * would let forwarded remote requests inherit local trust. Falls back to the
27
+ * historical gateway port only when no ingress listener was provisioned.
28
+ */
29
+ /**
30
+ * The port a remote tunnel forwards to: the Gateway's tunnel entry.
31
+ *
32
+ * The runtime records the listener it actually bound in `XPOD_GATEWAY_INGRESS_PORT`, and the
33
+ * Gateway's own port is only the fallback for an embedding that started no tunnel entry. The
34
+ * gate is structural - anything arriving on that listener is remote whatever it claims - so a
35
+ * tunnel pointed at the Gateway port by mistake still has the forwarding-header check behind
36
+ * it rather than inheriting local trust.
37
+ */
38
+ export declare function resolveTunnelIngressPort(env?: NodeJS.ProcessEnv): number;
21
39
  export declare function startApiService(options?: StartApiServiceOptions): Promise<ApiServiceHandle>;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.autoProvisionFirstRunLocal = autoProvisionFirstRunLocal;
4
+ exports.resolveTunnelIngressPort = resolveTunnelIngressPort;
4
5
  exports.startApiService = startApiService;
5
6
  const awilix_1 = require("awilix");
6
7
  const global_logger_factory_1 = require("global-logger-factory");
@@ -314,6 +315,32 @@ async function reconcileLocalOwnerRoles(container, config, logger) {
314
315
  logger.error(`Failed to reconcile local owner roles: ${error}`);
315
316
  }
316
317
  }
318
+ /**
319
+ * Port a managed tunnel forwards to.
320
+ *
321
+ * It must be the Gateway's ingress listener rather than the gateway port itself:
322
+ * a tunnel terminating on the gateway port reaches the Gateway from loopback and
323
+ * would let forwarded remote requests inherit local trust. Falls back to the
324
+ * historical gateway port only when no ingress listener was provisioned.
325
+ */
326
+ /**
327
+ * The port a remote tunnel forwards to: the Gateway's tunnel entry.
328
+ *
329
+ * The runtime records the listener it actually bound in `XPOD_GATEWAY_INGRESS_PORT`, and the
330
+ * Gateway's own port is only the fallback for an embedding that started no tunnel entry. The
331
+ * gate is structural - anything arriving on that listener is remote whatever it claims - so a
332
+ * tunnel pointed at the Gateway port by mistake still has the forwarding-header check behind
333
+ * it rather than inheriting local trust.
334
+ */
335
+ function resolveTunnelIngressPort(env = process.env) {
336
+ for (const value of [env.XPOD_GATEWAY_INGRESS_PORT, env.XPOD_MAIN_PORT, env.XPOD_PORT, env.PORT]) {
337
+ const parsed = Number.parseInt(value ?? '', 10);
338
+ if (Number.isFinite(parsed) && parsed > 0) {
339
+ return parsed;
340
+ }
341
+ }
342
+ return 3000;
343
+ }
317
344
  async function startBackgroundServices(container, logger) {
318
345
  try {
319
346
  const localNetworkManager = container.resolve('localNetworkManager', { allowUnregistered: true });
@@ -338,10 +365,9 @@ async function startBackgroundServices(container, logger) {
338
365
  const localTunnelProvider = container.resolve('localTunnelProvider', { allowUnregistered: true });
339
366
  if (localTunnelProvider) {
340
367
  logger.info('Starting local tunnel provider...');
341
- const localPort = Number.parseInt(process.env.XPOD_MAIN_PORT ?? process.env.CSS_PORT ?? process.env.PORT ?? '3000', 10);
342
368
  const config = await localTunnelProvider.setup({
343
369
  subdomain: 'local',
344
- localPort: Number.isFinite(localPort) && localPort > 0 ? localPort : 3000,
370
+ localPort: resolveTunnelIngressPort(),
345
371
  localProtocol: 'http',
346
372
  });
347
373
  await localTunnelProvider.start(config);
@@ -1,4 +1,4 @@
1
- import { type AiClientModelReference } from '@undefineds.co/ai-connections-core/client-config';
1
+ import { type AiClientModelReference } from '@undefineds.co/ai-connections/client-config';
2
2
  import type { AuthContext } from '../auth/AuthContext';
3
3
  export type AiClientId = 'codex' | 'claude-code' | 'pi' | 'codebuddy';
4
4
  export interface AiClientConfigurationCapabilityDescriptor {
@@ -10,7 +10,7 @@ const node_crypto_1 = require("node:crypto");
10
10
  const node_path_1 = __importDefault(require("node:path"));
11
11
  const node_fs_1 = require("node:fs");
12
12
  const node_child_process_1 = require("node:child_process");
13
- const client_config_1 = require("@undefineds.co/ai-connections-core/client-config");
13
+ const client_config_1 = require("@undefineds.co/ai-connections/client-config");
14
14
  const PLAN_SECRET_PLACEHOLDER = '[redacted]';
15
15
  const MANUAL_INSTRUCTIONS = 'Manual client setup is available when this host cannot safely write local coding-client files.';
16
16
  const CLIENT_LABELS = {
@@ -10,12 +10,37 @@ interface StartArgs {
10
10
  seedConfig?: string;
11
11
  }
12
12
  export declare const startCommand: CommandModule<object, StartArgs>;
13
+ /**
14
+ * Where remote-forwarded traffic lands on this machine.
15
+ *
16
+ * Order: explicit `XPOD_GATEWAY_INGRESS_PORT` → the active SakuraFrp tunnel's assigned local
17
+ * port → an OS-assigned loopback port. The first two are strict, because a tunnel that
18
+ * forwards to a specific port cannot follow us somewhere else.
19
+ */
20
+ /**
21
+ * The port a remote tunnel forwards to: the Gateway's tunnel entry.
22
+ *
23
+ * It is derived from the Gateway port by the same rule the runtime uses, so the CLI can hand
24
+ * it to the managed edge agent before the runtime binds it. A console that forwards somewhere
25
+ * else is a mismatch the tunnel provider reports from its own read-back - the runtime never
26
+ * moves its gate to match a console.
27
+ */
28
+ export declare function resolveIngressPort(provisionedConfig: {
29
+ tunnelProfiles?: Array<{
30
+ id: string;
31
+ provider: string;
32
+ credentialEnvKey?: string;
33
+ }>;
34
+ tunnelActiveProfileId?: string;
35
+ }, mainPort: number): Promise<number>;
13
36
  export declare function resolveCliOidcIssuer(env: Record<string, string | undefined>, provisionedIssuer?: string, edition?: string): string | undefined;
14
- export declare function resolveManagedEdgeAgentConfig(config: Pick<ReturnType<typeof loadConfigFromEnv>, 'cloudApiEndpoint' | 'nodeId' | 'nodeToken'>, gatewayPort: number): {
37
+ export declare function resolveManagedEdgeAgentConfig(config: Pick<ReturnType<typeof loadConfigFromEnv>, 'cloudApiEndpoint' | 'nodeId' | 'nodeToken'>, gatewayPort: number, ingressPort?: number, runtimeEnv?: Record<string, string | undefined>): {
15
38
  signalEndpoint: string;
16
39
  nodeId: string;
17
40
  nodeToken: string;
18
41
  targetBaseUrl: string;
42
+ lanBaseUrl: string;
43
+ p2pEnabled: boolean;
19
44
  } | undefined;
20
45
  export declare function resolveChildDatabaseUrl(value: string, childCwd: string): string;
21
46
  export declare function resolveCanonicalRuntimeBaseUrl(provisionedPublicUrl: string | undefined, configuredBaseUrl: string | undefined, localFallbackUrl: string): string;
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.startCommand = void 0;
7
+ exports.resolveIngressPort = resolveIngressPort;
7
8
  exports.resolveCliOidcIssuer = resolveCliOidcIssuer;
8
9
  exports.resolveManagedEdgeAgentConfig = resolveManagedEdgeAgentConfig;
9
10
  exports.resolveChildDatabaseUrl = resolveChildDatabaseUrl;
@@ -15,6 +16,7 @@ const fs_1 = __importDefault(require("fs"));
15
16
  const global_logger_factory_1 = require("global-logger-factory");
16
17
  const supervisor_1 = require("../../supervisor");
17
18
  const runtime_1 = require("../../runtime");
19
+ const SakuraFrpTunnelProvider_1 = require("../../tunnel/SakuraFrpTunnelProvider");
18
20
  const css_process_1 = require("../../runtime/css-process");
19
21
  const oidc_issuer_1 = require("../../runtime/oidc-issuer");
20
22
  const AuthMode_1 = require("../../authorization/AuthMode");
@@ -70,6 +72,10 @@ exports.startCommand = {
70
72
  process.env[key] ??= value;
71
73
  }
72
74
  process.env.XPOD_ENV_FILE = envPath;
75
+ // The settings API persists to XPOD_ENV_PATH (falling back to `<cwd>/.env.local`).
76
+ // Without this, a deployment started with `-e custom.env` saved its configuration
77
+ // into a file the runtime never reads.
78
+ process.env.XPOD_ENV_PATH ??= envPath;
73
79
  }
74
80
  else if (argv.env || process.env.XPOD_ENV_FILE) {
75
81
  console.warn(`Env file not found: ${envPath}`);
@@ -101,6 +107,19 @@ exports.startCommand = {
101
107
  const cssPort = await (0, runtime_1.getFreePortForWildcard)(requestedCssPort);
102
108
  const requestedApiPort = resolveServicePort(process.env.API_PORT, cssPort + 1, new Set([mainPort, cssPort]));
103
109
  const apiPort = await (0, runtime_1.getFreePortForWildcard)(requestedApiPort);
110
+ // Remote forwarding (managed tunnels, P2P data plane) terminates on this machine, so
111
+ // its origin is a dedicated ingress port instead of the gateway port: the Gateway
112
+ // never treats requests accepted there as local. An explicit override is honoured;
113
+ // otherwise the OS assigns a loopback port, because neighbouring ports may already
114
+ // belong to another service this deployment planned.
115
+ // The port is a fact of whichever tunnel forwards to us: an explicit override pins it,
116
+ // and the SakuraFrp console's own 本地端口 is read back from the provider, so the
117
+ // operator never types the same number twice. Only an unmanaged ingress is ephemeral.
118
+ // A pinned port is taken as-is: silently moving it would leave the tunnel pointing at a
119
+ // port nobody listens on.
120
+ const ingressPort = await resolveIngressPort(provisionedConfig, mainPort);
121
+ // Published so the API can tell the operator which address a tunnel must forward to.
122
+ process.env.XPOD_GATEWAY_INGRESS_PORT = String(ingressPort);
104
123
  const runtimeRoot = path_1.default.join(process.cwd(), '.xpod/runtime/legacy-css');
105
124
  const identityDbUrl = resolveChildDatabaseUrl(process.env.CSS_IDENTITY_DB_URL ?? process.env.DATABASE_URL ?? 'sqlite:./data/identity.sqlite', runtimeRoot);
106
125
  process.env.CSS_IDENTITY_DB_URL = identityDbUrl;
@@ -135,7 +154,7 @@ exports.startCommand = {
135
154
  authMode,
136
155
  externalOidcIssuer,
137
156
  });
138
- const managedEdge = resolveManagedEdgeAgentConfig(provisionedConfig, mainPort);
157
+ const managedEdge = resolveManagedEdgeAgentConfig(provisionedConfig, mainPort, ingressPort, process.env);
139
158
  const cssArgs = (0, css_process_1.buildCssArgs)({
140
159
  cssBinary: '__internal-css',
141
160
  configPath: cssRuntimeConfig.configPath,
@@ -169,6 +188,7 @@ exports.startCommand = {
169
188
  apiPort,
170
189
  mainPort,
171
190
  cssPort,
191
+ ingressPort,
172
192
  baseUrl,
173
193
  rdfIndexPath,
174
194
  authMode,
@@ -180,6 +200,7 @@ exports.startCommand = {
180
200
  exitOnStop: true,
181
201
  baseUrl,
182
202
  internalAdminAuthSecret: gatewayAdminProxyAuthSecret,
203
+ ingressPort,
183
204
  });
184
205
  proxy.setTargets({
185
206
  css: `http://localhost:${cssPort}`,
@@ -195,8 +216,9 @@ exports.startCommand = {
195
216
  nodeToken: managedEdge.nodeToken,
196
217
  baseUrl,
197
218
  p2p: {
198
- enabled: true,
219
+ enabled: managedEdge.p2pEnabled,
199
220
  targetBaseUrl: managedEdge.targetBaseUrl,
221
+ lanBaseUrl: managedEdge.lanBaseUrl,
200
222
  },
201
223
  });
202
224
  }
@@ -210,20 +232,62 @@ exports.startCommand = {
210
232
  process.on('SIGINT', () => shutdown('SIGINT'));
211
233
  },
212
234
  };
235
+ /**
236
+ * Where remote-forwarded traffic lands on this machine.
237
+ *
238
+ * Order: explicit `XPOD_GATEWAY_INGRESS_PORT` → the active SakuraFrp tunnel's assigned local
239
+ * port → an OS-assigned loopback port. The first two are strict, because a tunnel that
240
+ * forwards to a specific port cannot follow us somewhere else.
241
+ */
242
+ /**
243
+ * The port a remote tunnel forwards to: the Gateway's tunnel entry.
244
+ *
245
+ * It is derived from the Gateway port by the same rule the runtime uses, so the CLI can hand
246
+ * it to the managed edge agent before the runtime binds it. A console that forwards somewhere
247
+ * else is a mismatch the tunnel provider reports from its own read-back - the runtime never
248
+ * moves its gate to match a console.
249
+ */
250
+ async function resolveIngressPort(provisionedConfig, mainPort) {
251
+ const port = await (0, runtime_1.findGatewayIngressPort)(mainPort);
252
+ const active = provisionedConfig.tunnelProfiles?.find((profile) => profile.id === provisionedConfig.tunnelActiveProfileId) ?? provisionedConfig.tunnelProfiles?.find((profile) => profile.provider === 'sakura_frp');
253
+ if (active?.provider === 'sakura_frp') {
254
+ const credential = active.credentialEnvKey
255
+ ? process.env[active.credentialEnvKey] ?? process.env.SAKURA_TUNNEL_TOKEN
256
+ : process.env.SAKURA_TUNNEL_TOKEN;
257
+ const assigned = await (0, SakuraFrpTunnelProvider_1.resolveSakuraAssignedLocalPort)(credential);
258
+ if (assigned !== undefined && assigned !== port) {
259
+ (0, global_logger_factory_1.getLoggerFor)('XpodStart').warn(`The Sakura console forwards to local port ${assigned}, but this runtime's tunnel entry is ${port}; `
260
+ + `update the tunnel's local port in the console to ${port}`);
261
+ }
262
+ }
263
+ return port;
264
+ }
213
265
  function resolveCliOidcIssuer(env, provisionedIssuer, edition) {
214
266
  return (0, oidc_issuer_1.resolveExternalOidcIssuer)(env)
215
267
  ?? (0, oidc_issuer_1.resolveExternalOidcIssuer)({ SOLID_OIDC_ISSUER: provisionedIssuer })
216
268
  ?? (edition === 'local' ? oidc_issuer_1.DEFAULT_LOCAL_OIDC_ISSUER : undefined);
217
269
  }
218
- function resolveManagedEdgeAgentConfig(config, gatewayPort) {
270
+ function resolveManagedEdgeAgentConfig(config, gatewayPort, ingressPort, runtimeEnv = {}) {
219
271
  if (!config.cloudApiEndpoint || !config.nodeId || !config.nodeToken) {
220
272
  return undefined;
221
273
  }
274
+ const gatewayBaseUrl = `http://127.0.0.1:${gatewayPort}/`;
275
+ // The settings page owns these two decisions; the managed node identity only supplies
276
+ // the signal endpoint they run against.
277
+ const declaredSignalService = runtimeEnv.XPOD_P2P_SIGNAL_SERVICE?.trim();
278
+ const p2pDisabled = runtimeEnv.XPOD_P2P_ENABLED?.trim().toLowerCase() === 'false';
222
279
  return {
223
- signalEndpoint: new URL('/v1/signal', config.cloudApiEndpoint).toString(),
280
+ signalEndpoint: declaredSignalService
281
+ || new URL('/v1/signal', config.cloudApiEndpoint).toString(),
224
282
  nodeId: config.nodeId,
225
283
  nodeToken: config.nodeToken,
226
- targetBaseUrl: `http://127.0.0.1:${gatewayPort}/`,
284
+ // Forwarded peer traffic enters through the ingress listener, which never counts
285
+ // as local. LAN clients keep addressing the gateway listener, which they can reach.
286
+ targetBaseUrl: ingressPort === undefined ? gatewayBaseUrl : `http://127.0.0.1:${ingressPort}/`,
287
+ lanBaseUrl: gatewayBaseUrl,
288
+ // Peer-to-peer transport is off by default unless the deployment asked for it; an
289
+ // explicit false must actually stop it.
290
+ p2pEnabled: !p2pDisabled && runtimeEnv.XPOD_P2P_ENABLED?.trim().toLowerCase() === 'true',
227
291
  };
228
292
  }
229
293
  function resolveChildDatabaseUrl(value, childCwd) {
@@ -31,7 +31,6 @@
31
31
  "undefineds:dist/logging/ConfigurableLoggerFactory.jsonld",
32
32
  "undefineds:dist/storage/SparqlUpdateResourceStore.jsonld",
33
33
  "undefineds:dist/http/SubgraphSparqlHttpHandler.jsonld",
34
- "undefineds:dist/http/InternalPodDataHttpHandler.jsonld",
35
34
  "undefineds:dist/http/quota/QuotaAdminHttpHandler.jsonld",
36
35
  "undefineds:dist/http/ClusterIngressRouter.jsonld",
37
36
  "undefineds:dist/http/ClusterWebSocketConfigurator.jsonld",
@@ -134,6 +133,7 @@
134
133
  "undefineds:dist/api/reconciler/WakeAgentQueue.jsonld",
135
134
  "undefineds:dist/api/reconciler/ServerGroupReconcilerService.jsonld",
136
135
  "undefineds:dist/edge/reachability/types.jsonld",
136
+ "undefineds:dist/edge/reachability/RouteSetBuilder.jsonld",
137
137
  "undefineds:dist/edge/reachability/ReachabilitySessionService.jsonld",
138
138
  "undefineds:dist/edge/reachability/ManagedRouteSelector.jsonld",
139
139
  "undefineds:dist/edge/reachability/CanonicalFetch.jsonld",