@undefineds.co/xpod 0.1.7 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (350) hide show
  1. package/README.md +164 -3
  2. package/config/cli.json +9 -71
  3. package/config/cloud.json +34 -7
  4. package/config/local.json +6 -2
  5. package/config/resolver.json +11 -49
  6. package/config/runtime-open.json +22 -0
  7. package/config/xpod.base.json +32 -0
  8. package/config/xpod.cluster.json +2 -44
  9. package/config/xpod.json +5 -2
  10. package/dist/agents/AgentExecutorFactory.js +1 -1
  11. package/dist/agents/AgentExecutorFactory.js.map +1 -1
  12. package/dist/agents/AgentManager.js +1 -1
  13. package/dist/agents/AgentManager.js.map +1 -1
  14. package/dist/agents/config/agent-meta-schema.d.ts +7 -7
  15. package/dist/agents/config/agent-meta-schema.js +1 -1
  16. package/dist/agents/config/agent-meta-schema.js.map +1 -1
  17. package/dist/agents/config/resolve.js +1 -1
  18. package/dist/agents/config/resolve.js.map +1 -1
  19. package/dist/agents/schema/agent-config.d.ts +18 -18
  20. package/dist/agents/schema/agent-config.js +1 -1
  21. package/dist/agents/schema/agent-config.js.map +1 -1
  22. package/dist/agents/schema/tables.d.ts +8 -8
  23. package/dist/agents/schema/tables.js +1 -1
  24. package/dist/agents/schema/tables.js.map +1 -1
  25. package/dist/ai/schema/config.d.ts +7 -7
  26. package/dist/ai/schema/config.js +1 -1
  27. package/dist/ai/schema/config.js.map +1 -1
  28. package/dist/ai/schema/model.d.ts +13 -13
  29. package/dist/ai/schema/model.js +1 -1
  30. package/dist/ai/schema/model.js.map +1 -1
  31. package/dist/ai/schema/provider.d.ts +7 -7
  32. package/dist/ai/schema/provider.js +1 -1
  33. package/dist/ai/schema/provider.js.map +1 -1
  34. package/dist/ai/schema/vector-store.d.ts +17 -17
  35. package/dist/ai/schema/vector-store.js +1 -1
  36. package/dist/ai/schema/vector-store.js.map +1 -1
  37. package/dist/ai/service/CredentialReaderImpl.js +1 -1
  38. package/dist/ai/service/CredentialReaderImpl.js.map +1 -1
  39. package/dist/ai/service/DefaultAiConfigService.js.map +1 -1
  40. package/dist/api/ApiServer.d.ts +3 -1
  41. package/dist/api/ApiServer.js +14 -1
  42. package/dist/api/ApiServer.js.map +1 -1
  43. package/dist/api/auth/AuthContext.d.ts +12 -1
  44. package/dist/api/auth/AuthContext.js +18 -1
  45. package/dist/api/auth/AuthContext.js.map +1 -1
  46. package/dist/api/auth/ClientCredentialsAuthenticator.d.ts +0 -1
  47. package/dist/api/auth/ClientCredentialsAuthenticator.js.map +1 -1
  48. package/dist/api/auth/ServiceTokenAuthenticator.d.ts +18 -0
  49. package/dist/api/auth/ServiceTokenAuthenticator.js +50 -0
  50. package/dist/api/auth/ServiceTokenAuthenticator.js.map +1 -0
  51. package/dist/api/auth/index.d.ts +1 -0
  52. package/dist/api/auth/index.js +1 -0
  53. package/dist/api/auth/index.js.map +1 -1
  54. package/dist/api/chatkit/ai-provider.d.ts +0 -10
  55. package/dist/api/chatkit/ai-provider.js +11 -120
  56. package/dist/api/chatkit/ai-provider.js.map +1 -1
  57. package/dist/api/chatkit/default-agent.js +11 -8
  58. package/dist/api/chatkit/default-agent.js.map +1 -1
  59. package/dist/api/chatkit/pod-store.d.ts +6 -0
  60. package/dist/api/chatkit/pod-store.js +103 -36
  61. package/dist/api/chatkit/pod-store.js.map +1 -1
  62. package/dist/api/chatkit/schema.d.ts +32 -26
  63. package/dist/api/chatkit/schema.js +16 -8
  64. package/dist/api/chatkit/schema.js.map +1 -1
  65. package/dist/api/container/business-token.d.ts +9 -0
  66. package/dist/api/container/business-token.js +32 -0
  67. package/dist/api/container/business-token.js.map +1 -0
  68. package/dist/api/container/cloud.js +36 -12
  69. package/dist/api/container/cloud.js.map +1 -1
  70. package/dist/api/container/common.js +13 -5
  71. package/dist/api/container/common.js.map +1 -1
  72. package/dist/api/container/index.js +94 -14
  73. package/dist/api/container/index.js.map +1 -1
  74. package/dist/api/container/local.js +2 -1
  75. package/dist/api/container/local.js.map +1 -1
  76. package/dist/api/container/routes.js +81 -9
  77. package/dist/api/container/routes.js.map +1 -1
  78. package/dist/api/container/types.d.ts +8 -6
  79. package/dist/api/container/types.js.map +1 -1
  80. package/dist/api/handlers/AdminHandler.js +9 -9
  81. package/dist/api/handlers/AdminHandler.js.map +1 -1
  82. package/dist/api/handlers/ApiKeyHandler.js +0 -6
  83. package/dist/api/handlers/ApiKeyHandler.js.map +1 -1
  84. package/dist/api/handlers/EdgeNodeSignalHandler.d.ts +17 -0
  85. package/dist/api/handlers/EdgeNodeSignalHandler.js +171 -0
  86. package/dist/api/handlers/EdgeNodeSignalHandler.js.map +1 -0
  87. package/dist/api/handlers/PodManagementHandler.d.ts +5 -4
  88. package/dist/api/handlers/PodManagementHandler.js +11 -10
  89. package/dist/api/handlers/PodManagementHandler.js.map +1 -1
  90. package/dist/api/handlers/ProvisionHandler.d.ts +42 -0
  91. package/dist/api/handlers/ProvisionHandler.js +161 -0
  92. package/dist/api/handlers/ProvisionHandler.js.map +1 -0
  93. package/dist/api/handlers/QuotaHandler.d.ts +7 -7
  94. package/dist/api/handlers/QuotaHandler.js +143 -73
  95. package/dist/api/handlers/QuotaHandler.js.map +1 -1
  96. package/dist/api/handlers/SubdomainClientHandler.js +2 -2
  97. package/dist/api/handlers/SubdomainClientHandler.js.map +1 -1
  98. package/dist/api/handlers/SubdomainHandler.js +13 -8
  99. package/dist/api/handlers/SubdomainHandler.js.map +1 -1
  100. package/dist/api/handlers/UsageHandler.d.ts +14 -0
  101. package/dist/api/handlers/UsageHandler.js +123 -0
  102. package/dist/api/handlers/UsageHandler.js.map +1 -0
  103. package/dist/api/handlers/index.d.ts +3 -1
  104. package/dist/api/handlers/index.js +3 -1
  105. package/dist/api/handlers/index.js.map +1 -1
  106. package/dist/api/main.js +18 -0
  107. package/dist/api/main.js.map +1 -1
  108. package/dist/api/middleware/OpenAuthMiddleware.d.ts +12 -0
  109. package/dist/api/middleware/OpenAuthMiddleware.js +27 -0
  110. package/dist/api/middleware/OpenAuthMiddleware.js.map +1 -0
  111. package/dist/api/runtime.d.ts +15 -0
  112. package/dist/api/runtime.js +125 -0
  113. package/dist/api/runtime.js.map +1 -0
  114. package/dist/api/service/VectorStoreService.js +1 -1
  115. package/dist/api/service/VectorStoreService.js.map +1 -1
  116. package/dist/api/service/VercelChatService.d.ts +16 -7
  117. package/dist/api/service/VercelChatService.js +98 -178
  118. package/dist/api/service/VercelChatService.js.map +1 -1
  119. package/dist/api/store/DrizzleClientCredentialsStore.d.ts +6 -11
  120. package/dist/api/store/DrizzleClientCredentialsStore.js +9 -39
  121. package/dist/api/store/DrizzleClientCredentialsStore.js.map +1 -1
  122. package/dist/authorization/AuthModeSelector.d.ts +10 -0
  123. package/dist/authorization/AuthModeSelector.js +27 -0
  124. package/dist/authorization/AuthModeSelector.js.map +1 -0
  125. package/dist/authorization/AuthModeSelector.jsonld +81 -0
  126. package/dist/cli/commands/account.d.ts +6 -0
  127. package/dist/cli/commands/account.js +119 -0
  128. package/dist/cli/commands/account.js.map +1 -0
  129. package/dist/cli/commands/auth.js +20 -29
  130. package/dist/cli/commands/auth.js.map +1 -1
  131. package/dist/cli/commands/backup.d.ts +15 -0
  132. package/dist/cli/commands/backup.js +286 -0
  133. package/dist/cli/commands/backup.js.map +1 -0
  134. package/dist/cli/commands/config.d.ts +34 -3
  135. package/dist/cli/commands/config.js +195 -258
  136. package/dist/cli/commands/config.js.map +1 -1
  137. package/dist/cli/commands/doctor.d.ts +6 -0
  138. package/dist/cli/commands/doctor.js +94 -0
  139. package/dist/cli/commands/doctor.js.map +1 -0
  140. package/dist/cli/commands/pod.d.ts +6 -0
  141. package/dist/cli/commands/pod.js +124 -0
  142. package/dist/cli/commands/pod.js.map +1 -0
  143. package/dist/cli/commands/start.js +28 -5
  144. package/dist/cli/commands/start.js.map +1 -1
  145. package/dist/cli/index.js +9 -0
  146. package/dist/cli/index.js.map +1 -1
  147. package/dist/cli/lib/credentials-store.d.ts +17 -0
  148. package/dist/cli/lib/credentials-store.js +73 -0
  149. package/dist/cli/lib/credentials-store.js.map +1 -0
  150. package/dist/cli/lib/css-account.d.ts +17 -0
  151. package/dist/cli/lib/css-account.js +56 -0
  152. package/dist/cli/lib/css-account.js.map +1 -1
  153. package/dist/cli/lib/pod-thread-store.d.ts +57 -0
  154. package/dist/cli/lib/pod-thread-store.js +310 -0
  155. package/dist/cli/lib/pod-thread-store.js.map +1 -0
  156. package/dist/cli/lib/solid-auth.d.ts +20 -0
  157. package/dist/cli/lib/solid-auth.js +70 -0
  158. package/dist/cli/lib/solid-auth.js.map +1 -0
  159. package/dist/components/components.jsonld +5 -8
  160. package/dist/components/context.jsonld +114 -244
  161. package/dist/credential/schema/tables.d.ts +14 -14
  162. package/dist/credential/schema/tables.js +1 -1
  163. package/dist/credential/schema/tables.js.map +1 -1
  164. package/dist/edge/EdgeNodeAgent.js +2 -2
  165. package/dist/edge/EdgeNodeAgent.js.map +1 -1
  166. package/dist/edge/EdgeNodeDnsCoordinator.d.ts +1 -7
  167. package/dist/edge/EdgeNodeDnsCoordinator.js +31 -41
  168. package/dist/edge/EdgeNodeDnsCoordinator.js.map +1 -1
  169. package/dist/edge/EdgeNodeDnsCoordinator.jsonld +1 -27
  170. package/dist/edge/EdgeNodeModeDetector.d.ts +1 -1
  171. package/dist/edge/EdgeNodeModeDetector.js +9 -11
  172. package/dist/edge/EdgeNodeModeDetector.js.map +1 -1
  173. package/dist/http/ClusterIngressRouter.js +3 -3
  174. package/dist/http/ClusterIngressRouter.js.map +1 -1
  175. package/dist/http/ClusterWebSocketConfigurator.js +2 -2
  176. package/dist/http/ClusterWebSocketConfigurator.js.map +1 -1
  177. package/dist/http/PodRoutingHttpHandler.js +2 -2
  178. package/dist/http/PodRoutingHttpHandler.js.map +1 -1
  179. package/dist/http/cluster/PodMigrationHttpHandler.d.ts +1 -1
  180. package/dist/http/cluster/PodMigrationHttpHandler.js +1 -1
  181. package/dist/http/cluster/PodMigrationHttpHandler.js.map +1 -1
  182. package/dist/identity/drizzle/EdgeNodeRepository.d.ts +37 -4
  183. package/dist/identity/drizzle/EdgeNodeRepository.js +120 -128
  184. package/dist/identity/drizzle/EdgeNodeRepository.js.map +1 -1
  185. package/dist/identity/drizzle/ServiceTokenRepository.d.ts +52 -0
  186. package/dist/identity/drizzle/ServiceTokenRepository.js +142 -0
  187. package/dist/identity/drizzle/ServiceTokenRepository.js.map +1 -0
  188. package/dist/identity/drizzle/db.d.ts +9 -0
  189. package/dist/identity/drizzle/db.js +235 -3
  190. package/dist/identity/drizzle/db.js.map +1 -1
  191. package/dist/identity/drizzle/schema.pg.d.ts +5 -0
  192. package/dist/identity/drizzle/schema.pg.js +49 -20
  193. package/dist/identity/drizzle/schema.pg.js.map +1 -1
  194. package/dist/identity/drizzle/schema.sqlite.d.ts +332 -57
  195. package/dist/identity/drizzle/schema.sqlite.js +48 -18
  196. package/dist/identity/drizzle/schema.sqlite.js.map +1 -1
  197. package/dist/identity/oidc/AutoDetectIdentityProviderHandler.js +6 -4
  198. package/dist/identity/oidc/AutoDetectIdentityProviderHandler.js.map +1 -1
  199. package/dist/index.d.ts +6 -9
  200. package/dist/index.js +12 -14
  201. package/dist/index.js.map +1 -1
  202. package/dist/main.js +25 -8
  203. package/dist/main.js.map +1 -1
  204. package/dist/provision/ProvisionCodeCodec.d.ts +39 -0
  205. package/dist/provision/ProvisionCodeCodec.js +65 -0
  206. package/dist/provision/ProvisionCodeCodec.js.map +1 -0
  207. package/dist/provision/ProvisionCodeCodec.jsonld +47 -0
  208. package/dist/provision/ProvisionPodCreator.d.ts +20 -0
  209. package/dist/provision/ProvisionPodCreator.js +84 -0
  210. package/dist/provision/ProvisionPodCreator.js.map +1 -0
  211. package/dist/provision/ProvisionPodCreator.jsonld +118 -0
  212. package/dist/quota/DrizzleQuotaService.d.ts +17 -3
  213. package/dist/quota/DrizzleQuotaService.js +108 -8
  214. package/dist/quota/DrizzleQuotaService.js.map +1 -1
  215. package/dist/quota/DrizzleQuotaService.jsonld +33 -22
  216. package/dist/quota/NoopQuotaService.d.ts +7 -1
  217. package/dist/quota/NoopQuotaService.js +12 -0
  218. package/dist/quota/NoopQuotaService.js.map +1 -1
  219. package/dist/quota/NoopQuotaService.jsonld +24 -0
  220. package/dist/quota/QuotaService.d.ts +17 -0
  221. package/dist/quota/QuotaService.js +5 -0
  222. package/dist/quota/QuotaService.js.map +1 -1
  223. package/dist/quota/QuotaService.jsonld +50 -0
  224. package/dist/runtime/Proxy.d.ts +22 -4
  225. package/dist/runtime/Proxy.js +154 -35
  226. package/dist/runtime/Proxy.js.map +1 -1
  227. package/dist/runtime/XpodRuntime.d.ts +49 -0
  228. package/dist/runtime/XpodRuntime.js +374 -0
  229. package/dist/runtime/XpodRuntime.js.map +1 -0
  230. package/dist/runtime/env-utils.d.ts +2 -0
  231. package/dist/runtime/env-utils.js +55 -0
  232. package/dist/runtime/env-utils.js.map +1 -0
  233. package/dist/runtime/index.d.ts +4 -0
  234. package/dist/runtime/index.js +8 -1
  235. package/dist/runtime/index.js.map +1 -1
  236. package/dist/runtime/socket-fetch.d.ts +1 -0
  237. package/dist/runtime/socket-fetch.js +72 -0
  238. package/dist/runtime/socket-fetch.js.map +1 -0
  239. package/dist/runtime/socket-http.d.ts +1 -0
  240. package/dist/runtime/socket-http.js +142 -0
  241. package/dist/runtime/socket-http.js.map +1 -0
  242. package/dist/runtime/socket-utils.d.ts +2 -0
  243. package/dist/runtime/socket-utils.js +34 -0
  244. package/dist/runtime/socket-utils.js.map +1 -0
  245. package/dist/service/{EdgeNodeHeartbeatService.d.ts → EdgeNodeSignalClient.d.ts} +3 -3
  246. package/dist/service/{EdgeNodeHeartbeatService.js → EdgeNodeSignalClient.js} +4 -4
  247. package/dist/service/EdgeNodeSignalClient.js.map +1 -0
  248. package/dist/service/PodMigrationService.d.ts +1 -2
  249. package/dist/service/PodMigrationService.js +1 -2
  250. package/dist/service/PodMigrationService.js.map +1 -1
  251. package/dist/storage/SparqlUpdateResourceStore.js +1 -1
  252. package/dist/storage/SparqlUpdateResourceStore.js.map +1 -1
  253. package/dist/storage/accessors/MinioDataAccessor.d.ts +6 -0
  254. package/dist/storage/accessors/MinioDataAccessor.js +10 -0
  255. package/dist/storage/accessors/MinioDataAccessor.js.map +1 -1
  256. package/dist/storage/accessors/MinioDataAccessor.jsonld +4 -0
  257. package/dist/storage/accessors/MixDataAccessor.d.ts +2 -1
  258. package/dist/storage/accessors/MixDataAccessor.js +12 -1
  259. package/dist/storage/accessors/MixDataAccessor.js.map +1 -1
  260. package/dist/storage/accessors/MixDataAccessor.jsonld +19 -0
  261. package/dist/storage/locking/UrlAwareRedisLocker.d.ts +18 -0
  262. package/dist/storage/locking/UrlAwareRedisLocker.js +60 -0
  263. package/dist/storage/locking/UrlAwareRedisLocker.js.map +1 -0
  264. package/dist/storage/locking/UrlAwareRedisLocker.jsonld +123 -0
  265. package/dist/storage/quota/UsageRepository.d.ts +41 -8
  266. package/dist/storage/quota/UsageRepository.js +252 -50
  267. package/dist/storage/quota/UsageRepository.js.map +1 -1
  268. package/dist/storage/sparql/ComunicaQuintEngine.d.ts +9 -0
  269. package/dist/storage/sparql/ComunicaQuintEngine.js +50 -9
  270. package/dist/storage/sparql/ComunicaQuintEngine.js.map +1 -1
  271. package/dist/storage/sparql/QueryOptimizer.js +13 -1
  272. package/dist/storage/sparql/QueryOptimizer.js.map +1 -1
  273. package/dist/storage/sparql/QuintQuerySource.d.ts +14 -0
  274. package/dist/storage/sparql/QuintQuerySource.js +152 -1
  275. package/dist/storage/sparql/QuintQuerySource.js.map +1 -1
  276. package/dist/storage/sparql/SubgraphQueryEngine.d.ts +1 -0
  277. package/dist/storage/sparql/SubgraphQueryEngine.js +6 -2
  278. package/dist/storage/sparql/SubgraphQueryEngine.js.map +1 -1
  279. package/dist/storage/sparql/SubgraphQueryEngine.jsonld +4 -0
  280. package/dist/subdomain/SubdomainClient.d.ts +3 -3
  281. package/dist/subdomain/SubdomainClient.js +1 -1
  282. package/dist/subdomain/SubdomainClient.js.map +1 -1
  283. package/dist/subdomain/SubdomainService.d.ts +15 -16
  284. package/dist/subdomain/SubdomainService.js +80 -54
  285. package/dist/subdomain/SubdomainService.js.map +1 -1
  286. package/dist/subdomain/SubdomainService.jsonld +22 -26
  287. package/dist/supervisor/Supervisor.d.ts +7 -2
  288. package/dist/supervisor/Supervisor.js +33 -1
  289. package/dist/supervisor/Supervisor.js.map +1 -1
  290. package/dist/task/DrizzleTaskQueue.d.ts +1 -1
  291. package/dist/task/DrizzleTaskQueue.js +1 -1
  292. package/dist/task/DrizzleTaskQueue.js.map +1 -1
  293. package/dist/task/schema.d.ts +10 -10
  294. package/dist/task/schema.js +1 -1
  295. package/dist/task/schema.js.map +1 -1
  296. package/dist/test-utils/index.d.ts +4 -0
  297. package/dist/test-utils/index.js +8 -0
  298. package/dist/test-utils/index.js.map +1 -0
  299. package/dist/test-utils/no-auth-xpod.d.ts +11 -0
  300. package/dist/test-utils/no-auth-xpod.js +25 -0
  301. package/dist/test-utils/no-auth-xpod.js.map +1 -0
  302. package/dist/test-utils/seed-pod.d.ts +5 -0
  303. package/dist/test-utils/seed-pod.js +61 -0
  304. package/dist/test-utils/seed-pod.js.map +1 -0
  305. package/package.json +38 -10
  306. package/templates/identity/account/create-pod.html.ejs +110 -0
  307. package/templates/main.html.ejs +10 -0
  308. package/dist/api/handlers/DevHandler.d.ts +0 -18
  309. package/dist/api/handlers/DevHandler.js +0 -276
  310. package/dist/api/handlers/DevHandler.js.map +0 -1
  311. package/dist/api/handlers/SignalHandler.d.ts +0 -13
  312. package/dist/api/handlers/SignalHandler.js +0 -122
  313. package/dist/api/handlers/SignalHandler.js.map +0 -1
  314. package/dist/gateway/Proxy.d.ts +0 -24
  315. package/dist/gateway/Proxy.js +0 -209
  316. package/dist/gateway/Proxy.js.map +0 -1
  317. package/dist/gateway/Supervisor.d.ts +0 -2
  318. package/dist/gateway/Supervisor.js +0 -7
  319. package/dist/gateway/Supervisor.js.map +0 -1
  320. package/dist/gateway/port-finder.d.ts +0 -4
  321. package/dist/gateway/port-finder.js +0 -15
  322. package/dist/gateway/port-finder.js.map +0 -1
  323. package/dist/gateway/types.d.ts +0 -1
  324. package/dist/gateway/types.js +0 -3
  325. package/dist/gateway/types.js.map +0 -1
  326. package/dist/http/SignalInterceptHttpHandler.d.ts +0 -24
  327. package/dist/http/SignalInterceptHttpHandler.js +0 -47
  328. package/dist/http/SignalInterceptHttpHandler.js.map +0 -1
  329. package/dist/http/SignalInterceptHttpHandler.jsonld +0 -103
  330. package/dist/http/admin/EdgeNodeSignalHttpHandler.d.ts +0 -71
  331. package/dist/http/admin/EdgeNodeSignalHttpHandler.js +0 -674
  332. package/dist/http/admin/EdgeNodeSignalHttpHandler.js.map +0 -1
  333. package/dist/http/admin/EdgeNodeSignalHttpHandler.jsonld +0 -406
  334. package/dist/http/cluster/PodMigrationHttpHandler.jsonld +0 -169
  335. package/dist/quota/DefaultQuotaService.d.ts +0 -16
  336. package/dist/quota/DefaultQuotaService.js +0 -37
  337. package/dist/quota/DefaultQuotaService.js.map +0 -1
  338. package/dist/quota/DefaultQuotaService.jsonld +0 -85
  339. package/dist/service/EdgeNodeHeartbeatService.js.map +0 -1
  340. package/dist/service/PodMigrationService.jsonld +0 -76
  341. package/dist/storage/MigratableDataAccessor.d.ts +0 -63
  342. package/dist/storage/MigratableDataAccessor.js +0 -11
  343. package/dist/storage/MigratableDataAccessor.js.map +0 -1
  344. package/dist/storage/MigratableDataAccessor.jsonld +0 -60
  345. package/dist/storage/accessors/TieredMinioDataAccessor.d.ts +0 -150
  346. package/dist/storage/accessors/TieredMinioDataAccessor.js +0 -582
  347. package/dist/storage/accessors/TieredMinioDataAccessor.js.map +0 -1
  348. package/dist/storage/accessors/TieredMinioDataAccessor.jsonld +0 -333
  349. package/static/app/assets/index.css +0 -1
  350. package/static/app/assets/main.js +0 -11
@@ -1 +1 @@
1
- {"version":3,"file":"css-account.js","sourceRoot":"","sources":["../../../src/cli/lib/css-account.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CSS Account API helpers for CLI commands.\n *\n * Wraps the CSS .account/* endpoints used by login, credential management, etc.\n */\n\nexport interface AccountControls {\n pod?: string;\n clientCredentials?: string;\n webId?: string[];\n}\n\nexport interface ClientCredential {\n id: string;\n secret?: string;\n label?: string;\n webId?: string;\n}\n\nfunction resolveBaseUrl(url?: string): string {\n const raw = url ?? process.env.CSS_BASE_URL ?? 'http://localhost:3000';\n return raw.endsWith('/') ? raw : `${raw}/`;\n}\n\n/**\n * Check if the CSS server is reachable.\n */\nexport async function checkServer(baseUrl?: string): Promise<boolean> {\n try {\n const res = await fetch(`${resolveBaseUrl(baseUrl)}.account/`, {\n headers: { Accept: 'application/json' },\n });\n return res.ok;\n } catch {\n return false;\n }\n}\n\n/**\n * Login with email/password, returns a CSS account token.\n */\nexport async function login(\n email: string,\n password: string,\n baseUrl?: string,\n): Promise<string | null> {\n const base = resolveBaseUrl(baseUrl);\n try {\n const res = await fetch(`${base}.account/login/password/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: JSON.stringify({ email, password }),\n });\n if (!res.ok) return null;\n const data = (await res.json()) as { authorization?: string };\n return data.authorization ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Fetch account controls (endpoints for pod/credential management).\n */\nexport async function getAccountControls(\n token: string,\n baseUrl?: string,\n): Promise<AccountControls | null> {\n const base = resolveBaseUrl(baseUrl);\n try {\n const res = await fetch(`${base}.account/`, {\n headers: {\n Accept: 'application/json',\n Authorization: `CSS-Account-Token ${token}`,\n },\n });\n if (!res.ok) return null;\n const data = (await res.json()) as {\n controls?: {\n account?: {\n pod?: string;\n clientCredentials?: string;\n webId?: string;\n };\n };\n };\n return {\n pod: data.controls?.account?.pod,\n clientCredentials: data.controls?.account?.clientCredentials,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Create a new client credential bound to a WebID.\n */\nexport async function createClientCredentials(\n token: string,\n credentialsUrl: string,\n webId: string,\n name?: string,\n): Promise<ClientCredential | null> {\n try {\n const res = await fetch(credentialsUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n Authorization: `CSS-Account-Token ${token}`,\n },\n body: JSON.stringify({\n name: name ?? `xpod-cli-${Date.now()}`,\n webId,\n }),\n });\n if (!res.ok) return null;\n return (await res.json()) as ClientCredential;\n } catch {\n return null;\n }\n}\n\n/**\n * List all client credentials for the account.\n */\nexport async function listClientCredentials(\n token: string,\n baseUrl?: string,\n): Promise<ClientCredential[]> {\n const base = resolveBaseUrl(baseUrl);\n try {\n const res = await fetch(`${base}.account/`, {\n headers: {\n Accept: 'application/json',\n Authorization: `CSS-Account-Token ${token}`,\n },\n });\n if (!res.ok) return [];\n const data = (await res.json()) as {\n controls?: {\n account?: {\n clientCredentials?: string;\n };\n };\n clientCredentials?: Record<string, string>;\n };\n\n // CSS returns clientCredentials as { [credentialUrl]: webId }\n const creds = data.clientCredentials;\n if (!creds || typeof creds !== 'object') return [];\n\n return Object.entries(creds).map(([url, webId]) => {\n // Extract credential ID from URL (last path segment)\n const id = url.split('/').filter(Boolean).pop() ?? url;\n return { id, webId: typeof webId === 'string' ? webId : undefined };\n });\n } catch {\n return [];\n }\n}\n\n/**\n * Revoke (delete) a client credential by its ID.\n */\nexport async function revokeClientCredential(\n token: string,\n credentialId: string,\n baseUrl?: string,\n): Promise<boolean> {\n const base = resolveBaseUrl(baseUrl);\n try {\n const url = `${base}.account/client-credentials/${credentialId}/`;\n const res = await fetch(url, {\n method: 'DELETE',\n headers: {\n Authorization: `CSS-Account-Token ${token}`,\n },\n });\n return res.ok;\n } catch {\n return false;\n }\n}\n"]}
1
+ {"version":3,"file":"css-account.js","sourceRoot":"","sources":["../../../src/cli/lib/css-account.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CSS Account API helpers for CLI commands.\n *\n * Wraps the CSS .account/* endpoints used by login, credential management, etc.\n */\n\nexport interface AccountControls {\n pod?: string;\n clientCredentials?: string;\n webId?: string[];\n}\n\nexport interface AccountData {\n controls: AccountControls;\n pods: Record<string, string>;\n webIds: Record<string, string>;\n clientCredentials: Record<string, string>;\n}\n\nexport interface ClientCredential {\n id: string;\n secret?: string;\n label?: string;\n webId?: string;\n}\n\nfunction resolveBaseUrl(url?: string): string {\n const raw = url ?? process.env.CSS_BASE_URL ?? 'http://localhost:3000';\n return raw.endsWith('/') ? raw : `${raw}/`;\n}\n\n/**\n * Check if the CSS server is reachable.\n */\nexport async function checkServer(baseUrl?: string): Promise<boolean> {\n try {\n const res = await fetch(`${resolveBaseUrl(baseUrl)}.account/`, {\n headers: { Accept: 'application/json' },\n });\n return res.ok;\n } catch {\n return false;\n }\n}\n\n/**\n * Login with email/password, returns a CSS account token.\n */\nexport async function login(\n email: string,\n password: string,\n baseUrl?: string,\n): Promise<string | null> {\n const base = resolveBaseUrl(baseUrl);\n try {\n const res = await fetch(`${base}.account/login/password/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: JSON.stringify({ email, password }),\n });\n if (!res.ok) return null;\n const data = (await res.json()) as { authorization?: string };\n return data.authorization ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Fetch account controls (endpoints for pod/credential management).\n */\nexport async function getAccountControls(\n token: string,\n baseUrl?: string,\n): Promise<AccountControls | null> {\n const base = resolveBaseUrl(baseUrl);\n try {\n const res = await fetch(`${base}.account/`, {\n headers: {\n Accept: 'application/json',\n Authorization: `CSS-Account-Token ${token}`,\n },\n });\n if (!res.ok) return null;\n const data = (await res.json()) as {\n controls?: {\n account?: {\n pod?: string;\n clientCredentials?: string;\n webId?: string;\n };\n };\n };\n return {\n pod: data.controls?.account?.pod,\n clientCredentials: data.controls?.account?.clientCredentials,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Fetch full account data including pods, webIds, and credentials.\n */\nexport async function getAccountData(\n token: string,\n baseUrl?: string,\n): Promise<AccountData | null> {\n const base = resolveBaseUrl(baseUrl);\n try {\n const res = await fetch(`${base}.account/`, {\n headers: {\n Accept: 'application/json',\n Authorization: `CSS-Account-Token ${token}`,\n },\n });\n if (!res.ok) return null;\n const data = (await res.json()) as {\n controls?: {\n account?: {\n pod?: string;\n clientCredentials?: string;\n webId?: string;\n };\n };\n pods?: Record<string, string>;\n webIds?: Record<string, string>;\n clientCredentials?: Record<string, string>;\n };\n return {\n controls: {\n pod: data.controls?.account?.pod,\n clientCredentials: data.controls?.account?.clientCredentials,\n },\n pods: data.pods ?? {},\n webIds: data.webIds ?? {},\n clientCredentials: data.clientCredentials ?? {},\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Create a new pod for the account.\n */\nexport async function createPod(\n token: string,\n podEndpoint: string,\n podName: string,\n): Promise<{ podUrl: string; webId: string } | null> {\n try {\n const res = await fetch(podEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n Authorization: `CSS-Account-Token ${token}`,\n },\n body: JSON.stringify({ name: podName }),\n });\n if (!res.ok) return null;\n const data = (await res.json()) as { pod?: string; webId?: string };\n if (!data.pod || !data.webId) return null;\n return { podUrl: data.pod, webId: data.webId };\n } catch {\n return null;\n }\n}\n\n/**\n * Create a new client credential bound to a WebID.\n */\nexport async function createClientCredentials(\n token: string,\n credentialsUrl: string,\n webId: string,\n name?: string,\n): Promise<ClientCredential | null> {\n try {\n const res = await fetch(credentialsUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n Authorization: `CSS-Account-Token ${token}`,\n },\n body: JSON.stringify({\n name: name ?? `xpod-cli-${Date.now()}`,\n webId,\n }),\n });\n if (!res.ok) return null;\n return (await res.json()) as ClientCredential;\n } catch {\n return null;\n }\n}\n\n/**\n * List all client credentials for the account.\n */\nexport async function listClientCredentials(\n token: string,\n baseUrl?: string,\n): Promise<ClientCredential[]> {\n const base = resolveBaseUrl(baseUrl);\n try {\n const res = await fetch(`${base}.account/`, {\n headers: {\n Accept: 'application/json',\n Authorization: `CSS-Account-Token ${token}`,\n },\n });\n if (!res.ok) return [];\n const data = (await res.json()) as {\n controls?: {\n account?: {\n clientCredentials?: string;\n };\n };\n clientCredentials?: Record<string, string>;\n };\n\n // CSS returns clientCredentials as { [credentialUrl]: webId }\n const creds = data.clientCredentials;\n if (!creds || typeof creds !== 'object') return [];\n\n return Object.entries(creds).map(([url, webId]) => {\n // Extract credential ID from URL (last path segment)\n const id = url.split('/').filter(Boolean).pop() ?? url;\n return { id, webId: typeof webId === 'string' ? webId : undefined };\n });\n } catch {\n return [];\n }\n}\n\n/**\n * Revoke (delete) a client credential by its ID.\n */\nexport async function revokeClientCredential(\n token: string,\n credentialId: string,\n baseUrl?: string,\n): Promise<boolean> {\n const base = resolveBaseUrl(baseUrl);\n try {\n const url = `${base}.account/client-credentials/${credentialId}/`;\n const res = await fetch(url, {\n method: 'DELETE',\n headers: {\n Authorization: `CSS-Account-Token ${token}`,\n },\n });\n return res.ok;\n } catch {\n return false;\n }\n}\n"]}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Conversation thread storage backed by the user's Solid Pod.
3
+ *
4
+ * Uses drizzle-solid to operate on Chat + Thread + Message tables,
5
+ * following the same protocol as API/ChatKit.
6
+ *
7
+ * Data model:
8
+ * - Chat = 通讯录(跟谁聊):由 participants 决定,不再由 cwd hash 生成
9
+ * - Thread = 对话实例(聊什么、在哪聊):workspace 是一级字段
10
+ */
11
+ import type { Session } from '@inrupt/solid-client-authn-node';
12
+ export interface ThreadMessage {
13
+ role: 'user' | 'assistant' | 'system';
14
+ content: string;
15
+ timestamp: string;
16
+ }
17
+ export interface ThreadData {
18
+ id: string;
19
+ title?: string;
20
+ workspace?: string;
21
+ createdAt: string;
22
+ updatedAt: string;
23
+ messages: ThreadMessage[];
24
+ }
25
+ /**
26
+ * Get or create the default 1v1 Chat for CLI (user ↔ SecretaryAI).
27
+ * Returns the chatId (bare ID, not URI).
28
+ */
29
+ export declare function getOrCreateDefaultChat(session: Session): Promise<string>;
30
+ /**
31
+ * List thread IDs (most-recent first) for a given chatId.
32
+ * Uses direct SPARQL because eq() on optional uri() fields still has issues.
33
+ */
34
+ export declare function listThreads(session: Session, chatId: string): Promise<string[]>;
35
+ /**
36
+ * Load a thread by ID with all its messages.
37
+ */
38
+ export declare function loadThread(session: Session, chatId: string, threadId: string): Promise<ThreadData | null>;
39
+ /**
40
+ * Save a message to a thread.
41
+ */
42
+ export declare function saveMessage(session: Session, chatId: string, threadId: string, message: ThreadMessage): Promise<boolean>;
43
+ /**
44
+ * Save a tool call as a message with metadata.
45
+ */
46
+ export declare function saveToolCall(session: Session, chatId: string, threadId: string, toolCall: {
47
+ toolName: string;
48
+ toolCallId: string;
49
+ arguments: any;
50
+ output?: string;
51
+ status: 'pending' | 'completed' | 'failed';
52
+ }): Promise<boolean>;
53
+ /**
54
+ * Create a fresh thread.
55
+ * workspace is stored as a first-class field on Thread.
56
+ */
57
+ export declare function createThread(session: Session, chatId: string, workspace?: string, title?: string): Promise<string>;
@@ -0,0 +1,310 @@
1
+ "use strict";
2
+ /**
3
+ * Conversation thread storage backed by the user's Solid Pod.
4
+ *
5
+ * Uses drizzle-solid to operate on Chat + Thread + Message tables,
6
+ * following the same protocol as API/ChatKit.
7
+ *
8
+ * Data model:
9
+ * - Chat = 通讯录(跟谁聊):由 participants 决定,不再由 cwd hash 生成
10
+ * - Thread = 对话实例(聊什么、在哪聊):workspace 是一级字段
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.getOrCreateDefaultChat = getOrCreateDefaultChat;
14
+ exports.listThreads = listThreads;
15
+ exports.loadThread = loadThread;
16
+ exports.saveMessage = saveMessage;
17
+ exports.saveToolCall = saveToolCall;
18
+ exports.createThread = createThread;
19
+ const drizzle_solid_1 = require("@undefineds.co/drizzle-solid");
20
+ const schema_1 = require("../../api/chatkit/schema");
21
+ /** Default Chat ID for CLI 1v1 conversations with SecretaryAI */
22
+ const DEFAULT_CLI_CHAT_ID = 'cli-default';
23
+ /**
24
+ * Create a drizzle-solid database instance from an authenticated Session.
25
+ */
26
+ function createDb(session) {
27
+ return (0, drizzle_solid_1.drizzle)({
28
+ fetch: session.fetch,
29
+ info: session.info,
30
+ });
31
+ }
32
+ /**
33
+ * Get or create the default 1v1 Chat for CLI (user ↔ SecretaryAI).
34
+ * Returns the chatId (bare ID, not URI).
35
+ */
36
+ async function getOrCreateDefaultChat(session) {
37
+ const chatId = DEFAULT_CLI_CHAT_ID;
38
+ try {
39
+ const db = createDb(session);
40
+ await ensureChat(db, chatId, session.info.webId);
41
+ }
42
+ catch (error) {
43
+ console.error('Failed to ensure default chat:', error);
44
+ }
45
+ return chatId;
46
+ }
47
+ /**
48
+ * List thread IDs (most-recent first) for a given chatId.
49
+ * Uses direct SPARQL because eq() on optional uri() fields still has issues.
50
+ */
51
+ async function listThreads(session, chatId) {
52
+ try {
53
+ const podBaseUrl = session.info.webId.replace('/profile/card#me', '');
54
+ const endpoint = `${podBaseUrl}/.data/chat/-/sparql`;
55
+ const chatSubject = `<${podBaseUrl}/.data/chat/${chatId}/index.ttl#this>`;
56
+ // Note: Removed OPTIONAL to avoid filtering out threads without createdAt
57
+ // OPTIONAL in GRAPH ?g context can cause incomplete results (40 vs 57 threads)
58
+ const query = `
59
+ PREFIX sioc: <http://rdfs.org/sioc/ns#>
60
+ PREFIX udfs: <https://undefineds.co/ns#>
61
+ SELECT ?thread ?createdAt
62
+ WHERE {
63
+ ?thread a sioc:Thread ;
64
+ sioc:has_parent ${chatSubject} ;
65
+ udfs:createdAt ?createdAt .
66
+ }
67
+ ORDER BY DESC(?createdAt)
68
+ `;
69
+ const res = await session.fetch(endpoint, {
70
+ method: 'POST',
71
+ headers: {
72
+ 'Content-Type': 'application/sparql-query',
73
+ 'Accept': 'application/sparql-results+json',
74
+ },
75
+ body: query,
76
+ });
77
+ if (!res.ok)
78
+ return [];
79
+ const json = await res.json();
80
+ const bindings = json.results?.bindings || [];
81
+ // Extract thread ID from URI fragment: ...index.ttl#thread-xxx → thread-xxx
82
+ return bindings
83
+ .map((b) => {
84
+ const uri = b.thread?.value || '';
85
+ const hash = uri.lastIndexOf('#');
86
+ return hash >= 0 ? uri.slice(hash + 1) : '';
87
+ })
88
+ .filter((id) => id.length > 0);
89
+ }
90
+ catch (error) {
91
+ console.error('Failed to list threads:', error);
92
+ return [];
93
+ }
94
+ }
95
+ /**
96
+ * Load a thread by ID with all its messages.
97
+ */
98
+ async function loadThread(session, chatId, threadId) {
99
+ try {
100
+ const db = createDb(session);
101
+ const podBaseUrl = session.info.webId.replace('/profile/card#me', '');
102
+ const threadUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#${threadId}`;
103
+ // Query thread by full URI
104
+ const thread = await db.findByIri(schema_1.Thread, threadUri);
105
+ if (!thread)
106
+ return null;
107
+ // Query messages using direct SPARQL
108
+ // Note: OPTIONAL works correctly with date-grouped files (messages.ttl)
109
+ const endpoint = `${podBaseUrl}/.data/chat/-/sparql`;
110
+ const threadSubject = `<${threadUri}>`;
111
+ const messagesQuery = `
112
+ PREFIX meeting: <http://www.w3.org/ns/pim/meeting#>
113
+ PREFIX sioc: <http://rdfs.org/sioc/ns#>
114
+ PREFIX udfs: <https://undefineds.co/ns#>
115
+ SELECT ?role ?content ?createdAt
116
+ WHERE {
117
+ ?msg a meeting:Message ;
118
+ sioc:has_container ${threadSubject} .
119
+ OPTIONAL { ?msg udfs:role ?role . }
120
+ OPTIONAL { ?msg sioc:content ?content . }
121
+ OPTIONAL { ?msg udfs:createdAt ?createdAt . }
122
+ }
123
+ ORDER BY ?createdAt
124
+ `;
125
+ const messagesRes = await session.fetch(endpoint, {
126
+ method: 'POST',
127
+ headers: {
128
+ 'Content-Type': 'application/sparql-query',
129
+ 'Accept': 'application/sparql-results+json',
130
+ },
131
+ body: messagesQuery,
132
+ });
133
+ const messagesJson = messagesRes.ok ? await messagesRes.json() : { results: { bindings: [] } };
134
+ const messageBindings = messagesJson.results?.bindings || [];
135
+ // Extract bare ID from thread.id
136
+ const bareId = typeof thread.id === 'string' && thread.id.includes('#')
137
+ ? thread.id.split('#').pop() || threadId
138
+ : thread.id;
139
+ return {
140
+ id: bareId,
141
+ title: thread.title || undefined,
142
+ workspace: thread.workspace || undefined,
143
+ createdAt: thread.createdAt?.toISOString() || new Date().toISOString(),
144
+ updatedAt: thread.updatedAt?.toISOString() || new Date().toISOString(),
145
+ messages: messageBindings.map((m) => ({
146
+ role: m.role?.value || 'user',
147
+ content: m.content?.value || '',
148
+ timestamp: m.createdAt?.value || new Date().toISOString(),
149
+ })),
150
+ };
151
+ }
152
+ catch (error) {
153
+ console.error('Failed to load thread:', error);
154
+ return null;
155
+ }
156
+ }
157
+ /**
158
+ * Save a message to a thread.
159
+ */
160
+ async function saveMessage(session, chatId, threadId, message) {
161
+ try {
162
+ const db = createDb(session);
163
+ // Ensure chat exists
164
+ await ensureChat(db, chatId, session.info.webId);
165
+ // Ensure thread exists
166
+ await ensureThread(db, chatId, threadId, session.info.webId);
167
+ // 构建完整的 Thread URI(用于 RDF 引用)
168
+ const podBaseUrl = session.info.webId.replace('/profile/card#me', '');
169
+ const threadUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#${threadId}`;
170
+ // Insert message
171
+ // Note: yyyy/MM/dd are automatically extracted from createdAt by drizzle-solid
172
+ const messageId = `msg-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
173
+ await db.insert(schema_1.Message).values({
174
+ id: messageId,
175
+ chatId,
176
+ threadId: threadUri, // 传入完整 URI
177
+ maker: session.info.webId,
178
+ role: message.role,
179
+ content: message.content,
180
+ status: 'completed',
181
+ createdAt: new Date(message.timestamp),
182
+ });
183
+ return true;
184
+ }
185
+ catch (error) {
186
+ console.error('Failed to save message:', error);
187
+ return false;
188
+ }
189
+ }
190
+ /**
191
+ * Save a tool call as a message with metadata.
192
+ */
193
+ async function saveToolCall(session, chatId, threadId, toolCall) {
194
+ try {
195
+ const db = createDb(session);
196
+ // Ensure chat and thread exist
197
+ await ensureChat(db, chatId, session.info.webId);
198
+ await ensureThread(db, chatId, threadId, session.info.webId);
199
+ // 构建完整的 Thread URI(用于 RDF 引用)
200
+ const podBaseUrl = session.info.webId.replace('/profile/card#me', '');
201
+ const threadUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#${threadId}`;
202
+ // Insert tool call message
203
+ // Note: yyyy/MM/dd are automatically extracted from createdAt by drizzle-solid
204
+ const messageId = `tool-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
205
+ await db.insert(schema_1.Message).values({
206
+ id: messageId,
207
+ chatId,
208
+ threadId: threadUri, // 传入完整 URI
209
+ maker: session.info.webId,
210
+ role: 'tool_call',
211
+ content: `Executed ${toolCall.toolName}`,
212
+ status: toolCall.status,
213
+ toolName: toolCall.toolName,
214
+ toolCallId: toolCall.toolCallId,
215
+ metadata: JSON.stringify({
216
+ type: 'tool_call',
217
+ toolName: toolCall.toolName,
218
+ toolCallId: toolCall.toolCallId,
219
+ arguments: toolCall.arguments,
220
+ output: toolCall.output,
221
+ status: toolCall.status,
222
+ }),
223
+ createdAt: new Date(),
224
+ });
225
+ return true;
226
+ }
227
+ catch (error) {
228
+ console.error('Failed to save tool call:', error);
229
+ return false;
230
+ }
231
+ }
232
+ /**
233
+ * Create a fresh thread.
234
+ * workspace is stored as a first-class field on Thread.
235
+ */
236
+ async function createThread(session, chatId, workspace, title) {
237
+ const threadId = `thread-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
238
+ try {
239
+ const db = createDb(session);
240
+ // Ensure chat exists
241
+ await ensureChat(db, chatId, session.info.webId);
242
+ // Create thread with workspace as first-class field
243
+ const now = new Date();
244
+ await db.insert(schema_1.Thread).values({
245
+ id: threadId,
246
+ chatId,
247
+ title: title || 'CLI Conversation',
248
+ workspace: workspace || null,
249
+ status: 'active',
250
+ metadata: JSON.stringify({ source: 'cli' }),
251
+ createdAt: now,
252
+ updatedAt: now,
253
+ });
254
+ return threadId;
255
+ }
256
+ catch (error) {
257
+ console.error('Failed to create thread:', error);
258
+ return threadId; // Return ID anyway, will be created on first message
259
+ }
260
+ }
261
+ // ============================================================================
262
+ // Internal Helpers
263
+ // ============================================================================
264
+ async function ensureChat(db, chatId, webId) {
265
+ try {
266
+ // Use findByIri to avoid OPTIONAL bug in SPARQL queries
267
+ const podBaseUrl = webId.replace('/profile/card#me', '');
268
+ const chatUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#this`;
269
+ const chat = await db.findByIri(schema_1.Chat, chatUri);
270
+ if (!chat) {
271
+ const now = new Date();
272
+ await db.insert(schema_1.Chat).values({
273
+ id: chatId,
274
+ title: 'CLI Chat',
275
+ author: webId,
276
+ participants: [],
277
+ status: 'active',
278
+ createdAt: now,
279
+ updatedAt: now,
280
+ });
281
+ }
282
+ }
283
+ catch (error) {
284
+ // Ignore if already exists
285
+ }
286
+ }
287
+ async function ensureThread(db, chatId, threadId, webId) {
288
+ try {
289
+ // Use findByIri to avoid OPTIONAL bug in SPARQL queries
290
+ const podBaseUrl = webId.replace('/profile/card#me', '');
291
+ const threadUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#${threadId}`;
292
+ const thread = await db.findByIri(schema_1.Thread, threadUri);
293
+ if (!thread) {
294
+ const now = new Date();
295
+ await db.insert(schema_1.Thread).values({
296
+ id: threadId,
297
+ chatId,
298
+ title: 'CLI Conversation',
299
+ status: 'active',
300
+ metadata: JSON.stringify({ source: 'cli' }),
301
+ createdAt: now,
302
+ updatedAt: now,
303
+ });
304
+ }
305
+ }
306
+ catch (error) {
307
+ // Ignore if already exists
308
+ }
309
+ }
310
+ //# sourceMappingURL=pod-thread-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pod-thread-store.js","sourceRoot":"","sources":["../../../src/cli/lib/pod-thread-store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Conversation thread storage backed by the user's Solid Pod.\n *\n * Uses drizzle-solid to operate on Chat + Thread + Message tables,\n * following the same protocol as API/ChatKit.\n *\n * Data model:\n * - Chat = 通讯录(跟谁聊):由 participants 决定,不再由 cwd hash 生成\n * - Thread = 对话实例(聊什么、在哪聊):workspace 是一级字段\n */\n\nimport { drizzle, eq } from '@undefineds.co/drizzle-solid';\nimport { Chat, Thread, Message } from '../../api/chatkit/schema';\nimport type { Session } from '@inrupt/solid-client-authn-node';\n\n/** Default Chat ID for CLI 1v1 conversations with SecretaryAI */\nconst DEFAULT_CLI_CHAT_ID = 'cli-default';\n\nexport interface ThreadMessage {\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: string;\n}\n\nexport interface ThreadData {\n id: string;\n title?: string;\n workspace?: string;\n createdAt: string;\n updatedAt: string;\n messages: ThreadMessage[];\n}\n\n/**\n * Create a drizzle-solid database instance from an authenticated Session.\n */\nfunction createDb(session: Session) {\n return drizzle({\n fetch: session.fetch,\n info: session.info,\n } as any);\n}\n\n/**\n * Get or create the default 1v1 Chat for CLI (user ↔ SecretaryAI).\n * Returns the chatId (bare ID, not URI).\n */\nexport async function getOrCreateDefaultChat(session: Session): Promise<string> {\n const chatId = DEFAULT_CLI_CHAT_ID;\n try {\n const db = createDb(session);\n await ensureChat(db, chatId, session.info.webId!);\n } catch (error) {\n console.error('Failed to ensure default chat:', error);\n }\n return chatId;\n}\n\n/**\n * List thread IDs (most-recent first) for a given chatId.\n * Uses direct SPARQL because eq() on optional uri() fields still has issues.\n */\nexport async function listThreads(session: Session, chatId: string): Promise<string[]> {\n try {\n const podBaseUrl = session.info.webId!.replace('/profile/card#me', '');\n const endpoint = `${podBaseUrl}/.data/chat/-/sparql`;\n const chatSubject = `<${podBaseUrl}/.data/chat/${chatId}/index.ttl#this>`;\n\n // Note: Removed OPTIONAL to avoid filtering out threads without createdAt\n // OPTIONAL in GRAPH ?g context can cause incomplete results (40 vs 57 threads)\n const query = `\n PREFIX sioc: <http://rdfs.org/sioc/ns#>\n PREFIX udfs: <https://undefineds.co/ns#>\n SELECT ?thread ?createdAt\n WHERE {\n ?thread a sioc:Thread ;\n sioc:has_parent ${chatSubject} ;\n udfs:createdAt ?createdAt .\n }\n ORDER BY DESC(?createdAt)\n `;\n\n const res = await session.fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/sparql-query',\n 'Accept': 'application/sparql-results+json',\n },\n body: query,\n });\n\n if (!res.ok) return [];\n\n const json = await res.json();\n const bindings = json.results?.bindings || [];\n\n // Extract thread ID from URI fragment: ...index.ttl#thread-xxx → thread-xxx\n return bindings\n .map((b: any) => {\n const uri = b.thread?.value || '';\n const hash = uri.lastIndexOf('#');\n return hash >= 0 ? uri.slice(hash + 1) : '';\n })\n .filter((id: string) => id.length > 0);\n } catch (error) {\n console.error('Failed to list threads:', error);\n return [];\n }\n}\n\n/**\n * Load a thread by ID with all its messages.\n */\nexport async function loadThread(\n session: Session,\n chatId: string,\n threadId: string,\n): Promise<ThreadData | null> {\n try {\n const db = createDb(session);\n const podBaseUrl = session.info.webId!.replace('/profile/card#me', '');\n const threadUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#${threadId}`;\n\n // Query thread by full URI\n const thread = await db.findByIri(Thread, threadUri);\n if (!thread) return null;\n\n // Query messages using direct SPARQL\n // Note: OPTIONAL works correctly with date-grouped files (messages.ttl)\n const endpoint = `${podBaseUrl}/.data/chat/-/sparql`;\n const threadSubject = `<${threadUri}>`;\n\n const messagesQuery = `\n PREFIX meeting: <http://www.w3.org/ns/pim/meeting#>\n PREFIX sioc: <http://rdfs.org/sioc/ns#>\n PREFIX udfs: <https://undefineds.co/ns#>\n SELECT ?role ?content ?createdAt\n WHERE {\n ?msg a meeting:Message ;\n sioc:has_container ${threadSubject} .\n OPTIONAL { ?msg udfs:role ?role . }\n OPTIONAL { ?msg sioc:content ?content . }\n OPTIONAL { ?msg udfs:createdAt ?createdAt . }\n }\n ORDER BY ?createdAt\n `;\n\n const messagesRes = await session.fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/sparql-query',\n 'Accept': 'application/sparql-results+json',\n },\n body: messagesQuery,\n });\n\n const messagesJson = messagesRes.ok ? await messagesRes.json() : { results: { bindings: [] } };\n const messageBindings = messagesJson.results?.bindings || [];\n\n // Extract bare ID from thread.id\n const bareId = typeof thread.id === 'string' && thread.id.includes('#')\n ? thread.id.split('#').pop() || threadId\n : thread.id;\n\n return {\n id: bareId,\n title: thread.title || undefined,\n workspace: thread.workspace || undefined,\n createdAt: thread.createdAt?.toISOString() || new Date().toISOString(),\n updatedAt: thread.updatedAt?.toISOString() || new Date().toISOString(),\n messages: messageBindings.map((m: any) => ({\n role: m.role?.value || 'user',\n content: m.content?.value || '',\n timestamp: m.createdAt?.value || new Date().toISOString(),\n })),\n };\n } catch (error) {\n console.error('Failed to load thread:', error);\n return null;\n }\n}\n\n/**\n * Save a message to a thread.\n */\nexport async function saveMessage(\n session: Session,\n chatId: string,\n threadId: string,\n message: ThreadMessage,\n): Promise<boolean> {\n try {\n const db = createDb(session);\n\n // Ensure chat exists\n await ensureChat(db, chatId, session.info.webId!);\n\n // Ensure thread exists\n await ensureThread(db, chatId, threadId, session.info.webId!);\n\n // 构建完整的 Thread URI(用于 RDF 引用)\n const podBaseUrl = session.info.webId!.replace('/profile/card#me', '');\n const threadUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#${threadId}`;\n\n // Insert message\n // Note: yyyy/MM/dd are automatically extracted from createdAt by drizzle-solid\n const messageId = `msg-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n await db.insert(Message).values({\n id: messageId,\n chatId,\n threadId: threadUri, // 传入完整 URI\n maker: session.info.webId!,\n role: message.role,\n content: message.content,\n status: 'completed',\n createdAt: new Date(message.timestamp),\n });\n\n return true;\n } catch (error) {\n console.error('Failed to save message:', error);\n return false;\n }\n}\n\n/**\n * Save a tool call as a message with metadata.\n */\nexport async function saveToolCall(\n session: Session,\n chatId: string,\n threadId: string,\n toolCall: {\n toolName: string;\n toolCallId: string;\n arguments: any;\n output?: string;\n status: 'pending' | 'completed' | 'failed';\n },\n): Promise<boolean> {\n try {\n const db = createDb(session);\n\n // Ensure chat and thread exist\n await ensureChat(db, chatId, session.info.webId!);\n await ensureThread(db, chatId, threadId, session.info.webId!);\n\n // 构建完整的 Thread URI(用于 RDF 引用)\n const podBaseUrl = session.info.webId!.replace('/profile/card#me', '');\n const threadUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#${threadId}`;\n\n // Insert tool call message\n // Note: yyyy/MM/dd are automatically extracted from createdAt by drizzle-solid\n const messageId = `tool-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n await db.insert(Message).values({\n id: messageId,\n chatId,\n threadId: threadUri, // 传入完整 URI\n maker: session.info.webId!,\n role: 'tool_call',\n content: `Executed ${toolCall.toolName}`,\n status: toolCall.status,\n toolName: toolCall.toolName,\n toolCallId: toolCall.toolCallId,\n metadata: JSON.stringify({\n type: 'tool_call',\n toolName: toolCall.toolName,\n toolCallId: toolCall.toolCallId,\n arguments: toolCall.arguments,\n output: toolCall.output,\n status: toolCall.status,\n }),\n createdAt: new Date(),\n });\n\n return true;\n } catch (error) {\n console.error('Failed to save tool call:', error);\n return false;\n }\n}\n\n/**\n * Create a fresh thread.\n * workspace is stored as a first-class field on Thread.\n */\nexport async function createThread(\n session: Session,\n chatId: string,\n workspace?: string,\n title?: string,\n): Promise<string> {\n const threadId = `thread-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n\n try {\n const db = createDb(session);\n\n // Ensure chat exists\n await ensureChat(db, chatId, session.info.webId!);\n\n // Create thread with workspace as first-class field\n const now = new Date();\n await db.insert(Thread).values({\n id: threadId,\n chatId,\n title: title || 'CLI Conversation',\n workspace: workspace || null,\n status: 'active',\n metadata: JSON.stringify({ source: 'cli' }),\n createdAt: now,\n updatedAt: now,\n });\n\n return threadId;\n } catch (error) {\n console.error('Failed to create thread:', error);\n return threadId; // Return ID anyway, will be created on first message\n }\n}\n\n// ============================================================================\n// Internal Helpers\n// ============================================================================\n\nasync function ensureChat(db: any, chatId: string, webId: string): Promise<void> {\n try {\n // Use findByIri to avoid OPTIONAL bug in SPARQL queries\n const podBaseUrl = webId.replace('/profile/card#me', '');\n const chatUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#this`;\n const chat = await db.findByIri(Chat, chatUri);\n\n if (!chat) {\n const now = new Date();\n await db.insert(Chat).values({\n id: chatId,\n title: 'CLI Chat',\n author: webId,\n participants: [],\n status: 'active',\n createdAt: now,\n updatedAt: now,\n });\n }\n } catch (error) {\n // Ignore if already exists\n }\n}\n\nasync function ensureThread(db: any, chatId: string, threadId: string, webId: string): Promise<void> {\n try {\n // Use findByIri to avoid OPTIONAL bug in SPARQL queries\n const podBaseUrl = webId.replace('/profile/card#me', '');\n const threadUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#${threadId}`;\n const thread = await db.findByIri(Thread, threadUri);\n\n if (!thread) {\n const now = new Date();\n await db.insert(Thread).values({\n id: threadId,\n chatId,\n title: 'CLI Conversation',\n status: 'active',\n metadata: JSON.stringify({ source: 'cli' }),\n createdAt: now,\n updatedAt: now,\n });\n }\n } catch (error) {\n // Ignore if already exists\n }\n}\n"]}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Solid OIDC authentication helpers for CLI.
3
+ *
4
+ * Uses client_credentials grant to obtain an access token from the
5
+ * CSS OIDC token endpoint, so CLI commands can access Pod resources
6
+ * without email/password.
7
+ */
8
+ export interface SolidTokenResult {
9
+ accessToken: string;
10
+ tokenType: string;
11
+ expiresAt: Date;
12
+ }
13
+ /**
14
+ * Exchange client credentials for an access token via the OIDC token endpoint.
15
+ */
16
+ export declare function getAccessToken(clientId: string, clientSecret: string, baseUrl: string): Promise<SolidTokenResult | null>;
17
+ /**
18
+ * Perform an authenticated fetch using a Bearer access token.
19
+ */
20
+ export declare function authenticatedFetch(url: string, token: string, init?: RequestInit): Promise<Response>;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ /**
3
+ * Solid OIDC authentication helpers for CLI.
4
+ *
5
+ * Uses client_credentials grant to obtain an access token from the
6
+ * CSS OIDC token endpoint, so CLI commands can access Pod resources
7
+ * without email/password.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.getAccessToken = getAccessToken;
11
+ exports.authenticatedFetch = authenticatedFetch;
12
+ /**
13
+ * Discover the OIDC token endpoint from the server's openid-configuration.
14
+ */
15
+ async function discoverTokenEndpoint(baseUrl) {
16
+ try {
17
+ const res = await fetch(`${baseUrl}.well-known/openid-configuration`);
18
+ if (!res.ok)
19
+ return null;
20
+ const data = (await res.json());
21
+ return data.token_endpoint ?? null;
22
+ }
23
+ catch {
24
+ return null;
25
+ }
26
+ }
27
+ /**
28
+ * Exchange client credentials for an access token via the OIDC token endpoint.
29
+ */
30
+ async function getAccessToken(clientId, clientSecret, baseUrl) {
31
+ const tokenEndpoint = await discoverTokenEndpoint(baseUrl);
32
+ if (!tokenEndpoint) {
33
+ return null;
34
+ }
35
+ try {
36
+ const params = new URLSearchParams({
37
+ grant_type: 'client_credentials',
38
+ client_id: clientId,
39
+ client_secret: clientSecret,
40
+ });
41
+ const res = await fetch(tokenEndpoint, {
42
+ method: 'POST',
43
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
44
+ body: params.toString(),
45
+ });
46
+ if (!res.ok)
47
+ return null;
48
+ const data = (await res.json());
49
+ if (!data.access_token)
50
+ return null;
51
+ const expiresIn = data.expires_in ?? 3600;
52
+ return {
53
+ accessToken: data.access_token,
54
+ tokenType: data.token_type ?? 'Bearer',
55
+ expiresAt: new Date(Date.now() + expiresIn * 1000),
56
+ };
57
+ }
58
+ catch {
59
+ return null;
60
+ }
61
+ }
62
+ /**
63
+ * Perform an authenticated fetch using a Bearer access token.
64
+ */
65
+ async function authenticatedFetch(url, token, init) {
66
+ const headers = new Headers(init?.headers);
67
+ headers.set('Authorization', `Bearer ${token}`);
68
+ return fetch(url, { ...init, headers });
69
+ }
70
+ //# sourceMappingURL=solid-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solid-auth.js","sourceRoot":"","sources":["../../../src/cli/lib/solid-auth.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAyBH,wCA0CC;AAKD,gDAQC;AAxED;;GAEG;AACH,KAAK,UAAU,qBAAqB,CAAC,OAAe;IAClD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,kCAAkC,CAAC,CAAC;QACtE,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QACzB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAgC,CAAC;QAC/D,OAAO,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,cAAc,CAClC,QAAgB,EAChB,YAAoB,EACpB,OAAe;IAEf,MAAM,aAAa,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC3D,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YACjC,UAAU,EAAE,oBAAoB;YAChC,SAAS,EAAE,QAAQ;YACnB,aAAa,EAAE,YAAY;SAC5B,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,aAAa,EAAE;YACrC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;YAChE,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE;SACxB,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAEzB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAI7B,CAAC;QAEF,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE,OAAO,IAAI,CAAC;QAEpC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC;QAC1C,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,YAAY;YAC9B,SAAS,EAAE,IAAI,CAAC,UAAU,IAAI,QAAQ;YACtC,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,IAAI,CAAC;SACnD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,kBAAkB,CACtC,GAAW,EACX,KAAa,EACb,IAAkB;IAElB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,KAAK,EAAE,CAAC,CAAC;IAChD,OAAO,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAC1C,CAAC","sourcesContent":["/**\n * Solid OIDC authentication helpers for CLI.\n *\n * Uses client_credentials grant to obtain an access token from the\n * CSS OIDC token endpoint, so CLI commands can access Pod resources\n * without email/password.\n */\n\nexport interface SolidTokenResult {\n accessToken: string;\n tokenType: string;\n expiresAt: Date;\n}\n\n/**\n * Discover the OIDC token endpoint from the server's openid-configuration.\n */\nasync function discoverTokenEndpoint(baseUrl: string): Promise<string | null> {\n try {\n const res = await fetch(`${baseUrl}.well-known/openid-configuration`);\n if (!res.ok) return null;\n const data = (await res.json()) as { token_endpoint?: string };\n return data.token_endpoint ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Exchange client credentials for an access token via the OIDC token endpoint.\n */\nexport async function getAccessToken(\n clientId: string,\n clientSecret: string,\n baseUrl: string,\n): Promise<SolidTokenResult | null> {\n const tokenEndpoint = await discoverTokenEndpoint(baseUrl);\n if (!tokenEndpoint) {\n return null;\n }\n\n try {\n const params = new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: clientId,\n client_secret: clientSecret,\n });\n\n const res = await fetch(tokenEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: params.toString(),\n });\n\n if (!res.ok) return null;\n\n const data = (await res.json()) as {\n access_token?: string;\n token_type?: string;\n expires_in?: number;\n };\n\n if (!data.access_token) return null;\n\n const expiresIn = data.expires_in ?? 3600;\n return {\n accessToken: data.access_token,\n tokenType: data.token_type ?? 'Bearer',\n expiresAt: new Date(Date.now() + expiresIn * 1000),\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Perform an authenticated fetch using a Bearer access token.\n */\nexport async function authenticatedFetch(\n url: string,\n token: string,\n init?: RequestInit,\n): Promise<Response> {\n const headers = new Headers(init?.headers);\n headers.set('Authorization', `Bearer ${token}`);\n return fetch(url, { ...init, headers });\n}\n"]}
@@ -7,7 +7,6 @@
7
7
  "requireName": "@undefineds.co/xpod",
8
8
  "import": [
9
9
  "undefineds:dist/storage/sparql/SubgraphQueryEngine.jsonld",
10
- "undefineds:dist/storage/MigratableDataAccessor.jsonld",
11
10
  "undefineds:dist/dns/DnsProvider.jsonld",
12
11
  "undefineds:dist/edge/EdgeNodeCertificateProvisioner.jsonld",
13
12
  "undefineds:dist/edge/interfaces/EdgeNodeTunnelManager.jsonld",
@@ -24,12 +23,10 @@
24
23
  "undefineds:dist/storage/SparqlUpdateResourceStore.jsonld",
25
24
  "undefineds:dist/http/SubgraphSparqlHttpHandler.jsonld",
26
25
  "undefineds:dist/http/quota/QuotaAdminHttpHandler.jsonld",
27
- "undefineds:dist/http/admin/EdgeNodeSignalHttpHandler.jsonld",
28
26
  "undefineds:dist/http/ClusterIngressRouter.jsonld",
29
27
  "undefineds:dist/http/ClusterWebSocketConfigurator.jsonld",
30
28
  "undefineds:dist/http/EdgeNodeDirectDebugHttpHandler.jsonld",
31
29
  "undefineds:dist/http/EdgeNodeProxyHttpHandler.jsonld",
32
- "undefineds:dist/http/SignalInterceptHttpHandler.jsonld",
33
30
  "undefineds:dist/http/RouterHttpHandler.jsonld",
34
31
  "undefineds:dist/http/RouterHttpRoute.jsonld",
35
32
  "undefineds:dist/http/TracingHandler.jsonld",
@@ -40,7 +37,6 @@
40
37
  "undefineds:dist/storage/keyvalue/PostgresKeyValueStorage.jsonld",
41
38
  "undefineds:dist/storage/keyvalue/RedisKeyValueStorage.jsonld",
42
39
  "undefineds:dist/storage/keyvalue/SqliteKeyValueStorage.jsonld",
43
- "undefineds:dist/quota/DefaultQuotaService.jsonld",
44
40
  "undefineds:dist/quota/DrizzleQuotaService.jsonld",
45
41
  "undefineds:dist/quota/NoopQuotaService.jsonld",
46
42
  "undefineds:dist/storage/quota/PerAccountQuotaStrategy.jsonld",
@@ -58,9 +54,6 @@
58
54
  "undefineds:dist/storage/quota/UsageTrackingStore.jsonld",
59
55
  "undefineds:dist/identity/CenterNodeRegistrationService.jsonld",
60
56
  "undefineds:dist/http/PodRoutingHttpHandler.jsonld",
61
- "undefineds:dist/storage/accessors/TieredMinioDataAccessor.jsonld",
62
- "undefineds:dist/http/cluster/PodMigrationHttpHandler.jsonld",
63
- "undefineds:dist/service/PodMigrationService.jsonld",
64
57
  "undefineds:dist/identity/ReactAppViewHandler.jsonld",
65
58
  "undefineds:dist/storage/quint/types.jsonld",
66
59
  "undefineds:dist/storage/quint/SqliteQuintStore.jsonld",
@@ -83,6 +76,10 @@
83
76
  "undefineds:dist/identity/oidc/DisabledOidcHandler.jsonld",
84
77
  "undefineds:dist/identity/oidc/DisabledIdentityProviderHandler.jsonld",
85
78
  "undefineds:dist/identity/oidc/AutoDetectOidcHandler.jsonld",
86
- "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld"
79
+ "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld",
80
+ "undefineds:dist/storage/locking/UrlAwareRedisLocker.jsonld",
81
+ "undefineds:dist/provision/ProvisionPodCreator.jsonld",
82
+ "undefineds:dist/provision/ProvisionCodeCodec.jsonld",
83
+ "undefineds:dist/authorization/AuthModeSelector.jsonld"
87
84
  ]
88
85
  }