@braidhq/server 0.0.1 → 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 (376) hide show
  1. package/README.md +164 -0
  2. package/dist/app.d.ts +12 -3
  3. package/dist/app.d.ts.map +1 -1
  4. package/dist/app.js +154 -9
  5. package/dist/app.js.map +1 -1
  6. package/dist/authMode.d.ts +39 -0
  7. package/dist/authMode.d.ts.map +1 -0
  8. package/dist/authMode.js +50 -0
  9. package/dist/authMode.js.map +1 -0
  10. package/dist/composeApp.d.ts +79 -0
  11. package/dist/composeApp.d.ts.map +1 -0
  12. package/dist/composeApp.js +136 -0
  13. package/dist/composeApp.js.map +1 -0
  14. package/dist/composeFsApp.d.ts +27 -0
  15. package/dist/composeFsApp.d.ts.map +1 -0
  16. package/dist/composeFsApp.js +309 -0
  17. package/dist/composeFsApp.js.map +1 -0
  18. package/dist/index.d.ts +3 -2
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +3 -2
  21. package/dist/index.js.map +1 -1
  22. package/dist/infrastructure/_shared/env.d.ts +10 -0
  23. package/dist/infrastructure/_shared/env.d.ts.map +1 -0
  24. package/dist/infrastructure/_shared/env.js +19 -0
  25. package/dist/infrastructure/_shared/env.js.map +1 -0
  26. package/dist/infrastructure/_shared/frontmatter.d.ts +13 -0
  27. package/dist/infrastructure/_shared/frontmatter.d.ts.map +1 -0
  28. package/dist/infrastructure/{fs → _shared}/frontmatter.js +5 -5
  29. package/dist/infrastructure/_shared/frontmatter.js.map +1 -0
  30. package/dist/infrastructure/_shared/jsonFileStore.d.ts.map +1 -0
  31. package/dist/infrastructure/_shared/jsonFileStore.js.map +1 -0
  32. package/dist/infrastructure/_shared/paths.d.ts +43 -0
  33. package/dist/infrastructure/_shared/paths.d.ts.map +1 -0
  34. package/dist/infrastructure/_shared/paths.js +96 -0
  35. package/dist/infrastructure/_shared/paths.js.map +1 -0
  36. package/dist/infrastructure/auth/AccessPolicy.d.ts +87 -0
  37. package/dist/infrastructure/auth/AccessPolicy.d.ts.map +1 -0
  38. package/dist/infrastructure/auth/AccessPolicy.js +177 -0
  39. package/dist/infrastructure/auth/AccessPolicy.js.map +1 -0
  40. package/dist/infrastructure/auth/SessionStore.d.ts +50 -0
  41. package/dist/infrastructure/auth/SessionStore.d.ts.map +1 -0
  42. package/dist/infrastructure/auth/SessionStore.js +104 -0
  43. package/dist/infrastructure/auth/SessionStore.js.map +1 -0
  44. package/dist/infrastructure/batch/FsBatchPlanRepository.d.ts +79 -0
  45. package/dist/infrastructure/batch/FsBatchPlanRepository.d.ts.map +1 -0
  46. package/dist/infrastructure/batch/FsBatchPlanRepository.js +42 -0
  47. package/dist/infrastructure/batch/FsBatchPlanRepository.js.map +1 -0
  48. package/dist/infrastructure/history/GitWorkspaceHistory.d.ts +18 -0
  49. package/dist/infrastructure/history/GitWorkspaceHistory.d.ts.map +1 -0
  50. package/dist/infrastructure/history/GitWorkspaceHistory.js +310 -0
  51. package/dist/infrastructure/history/GitWorkspaceHistory.js.map +1 -0
  52. package/dist/infrastructure/history/commitMessage.d.ts +4 -0
  53. package/dist/infrastructure/history/commitMessage.d.ts.map +1 -0
  54. package/dist/infrastructure/history/commitMessage.js +90 -0
  55. package/dist/infrastructure/history/commitMessage.js.map +1 -0
  56. package/dist/infrastructure/hitl/FsClarificationRepository.d.ts +13 -0
  57. package/dist/infrastructure/hitl/FsClarificationRepository.d.ts.map +1 -0
  58. package/dist/infrastructure/hitl/FsClarificationRepository.js +39 -0
  59. package/dist/infrastructure/hitl/FsClarificationRepository.js.map +1 -0
  60. package/dist/infrastructure/hitl/FsProposalRepository.d.ts.map +1 -0
  61. package/dist/infrastructure/{fs → hitl}/FsProposalRepository.js +10 -3
  62. package/dist/infrastructure/hitl/FsProposalRepository.js.map +1 -0
  63. package/dist/infrastructure/hitl/StatusedJsonStore.d.ts +30 -0
  64. package/dist/infrastructure/hitl/StatusedJsonStore.d.ts.map +1 -0
  65. package/dist/infrastructure/{fs/FsStatusedJsonRepository.js → hitl/StatusedJsonStore.js} +3 -3
  66. package/dist/infrastructure/hitl/StatusedJsonStore.js.map +1 -0
  67. package/dist/infrastructure/model/FsModelSerializer.d.ts +96 -0
  68. package/dist/infrastructure/model/FsModelSerializer.d.ts.map +1 -0
  69. package/dist/infrastructure/model/FsModelSerializer.js +60 -0
  70. package/dist/infrastructure/model/FsModelSerializer.js.map +1 -0
  71. package/dist/infrastructure/oauth/GoogleOAuth.d.ts +43 -14
  72. package/dist/infrastructure/oauth/GoogleOAuth.d.ts.map +1 -1
  73. package/dist/infrastructure/oauth/GoogleOAuth.js +78 -11
  74. package/dist/infrastructure/oauth/GoogleOAuth.js.map +1 -1
  75. package/dist/infrastructure/reactor/FsReactorCycleRepository.d.ts +29 -0
  76. package/dist/infrastructure/reactor/FsReactorCycleRepository.d.ts.map +1 -0
  77. package/dist/infrastructure/reactor/FsReactorCycleRepository.js +94 -0
  78. package/dist/infrastructure/reactor/FsReactorCycleRepository.js.map +1 -0
  79. package/dist/infrastructure/secrets/SecretStore.d.ts +11 -14
  80. package/dist/infrastructure/secrets/SecretStore.d.ts.map +1 -1
  81. package/dist/infrastructure/secrets/SecretStore.js +4 -4
  82. package/dist/infrastructure/secrets/SecretStore.js.map +1 -1
  83. package/dist/infrastructure/{fs → skill}/FsRunRepository.d.ts +9 -4
  84. package/dist/infrastructure/skill/FsRunRepository.d.ts.map +1 -0
  85. package/dist/infrastructure/skill/FsRunRepository.js +162 -0
  86. package/dist/infrastructure/skill/FsRunRepository.js.map +1 -0
  87. package/dist/infrastructure/{fs → skill}/FsSkillRegistry.d.ts +4 -13
  88. package/dist/infrastructure/skill/FsSkillRegistry.d.ts.map +1 -0
  89. package/dist/infrastructure/{fs → skill}/FsSkillRegistry.js +38 -18
  90. package/dist/infrastructure/skill/FsSkillRegistry.js.map +1 -0
  91. package/dist/infrastructure/{agent → skill}/SubprocessSkillRunner.d.ts +13 -15
  92. package/dist/infrastructure/skill/SubprocessSkillRunner.d.ts.map +1 -0
  93. package/dist/infrastructure/{agent → skill}/SubprocessSkillRunner.js +124 -40
  94. package/dist/infrastructure/skill/SubprocessSkillRunner.js.map +1 -0
  95. package/dist/infrastructure/skill/asyncQueue.d.ts +20 -0
  96. package/dist/infrastructure/skill/asyncQueue.d.ts.map +1 -0
  97. package/dist/infrastructure/{agent → skill}/asyncQueue.js +2 -3
  98. package/dist/infrastructure/{agent → skill}/asyncQueue.js.map +1 -1
  99. package/dist/infrastructure/skill/lineBuffer.d.ts +15 -0
  100. package/dist/infrastructure/skill/lineBuffer.d.ts.map +1 -0
  101. package/dist/infrastructure/{agent/streamJsonParser.js → skill/lineBuffer.js} +5 -17
  102. package/dist/infrastructure/skill/lineBuffer.js.map +1 -0
  103. package/dist/infrastructure/skill/orphanReaper.d.ts +20 -0
  104. package/dist/infrastructure/skill/orphanReaper.d.ts.map +1 -0
  105. package/dist/infrastructure/{orphanReaper.js → skill/orphanReaper.js} +7 -5
  106. package/dist/infrastructure/skill/orphanReaper.js.map +1 -0
  107. package/dist/infrastructure/skill/subprocessEventStream.d.ts +16 -0
  108. package/dist/infrastructure/skill/subprocessEventStream.d.ts.map +1 -0
  109. package/dist/infrastructure/skill/subprocessEventStream.js +29 -0
  110. package/dist/infrastructure/skill/subprocessEventStream.js.map +1 -0
  111. package/dist/infrastructure/source/FsSourceUnitDigest.d.ts +19 -0
  112. package/dist/infrastructure/source/FsSourceUnitDigest.d.ts.map +1 -0
  113. package/dist/infrastructure/source/FsSourceUnitDigest.js +58 -0
  114. package/dist/infrastructure/source/FsSourceUnitDigest.js.map +1 -0
  115. package/dist/infrastructure/source/FsSourceUnitObservationRepository.d.ts +31 -0
  116. package/dist/infrastructure/source/FsSourceUnitObservationRepository.d.ts.map +1 -0
  117. package/dist/infrastructure/source/FsSourceUnitObservationRepository.js +88 -0
  118. package/dist/infrastructure/source/FsSourceUnitObservationRepository.js.map +1 -0
  119. package/dist/infrastructure/source/intentScan.d.ts +13 -0
  120. package/dist/infrastructure/source/intentScan.d.ts.map +1 -0
  121. package/dist/infrastructure/source/intentScan.js +137 -0
  122. package/dist/infrastructure/source/intentScan.js.map +1 -0
  123. package/dist/infrastructure/users/UserDirectoryFromRegistry.d.ts +14 -0
  124. package/dist/infrastructure/users/UserDirectoryFromRegistry.d.ts.map +1 -0
  125. package/dist/infrastructure/users/UserDirectoryFromRegistry.js +21 -0
  126. package/dist/infrastructure/users/UserDirectoryFromRegistry.js.map +1 -0
  127. package/dist/infrastructure/users/UserRegistryFile.d.ts +22 -0
  128. package/dist/infrastructure/users/UserRegistryFile.d.ts.map +1 -0
  129. package/dist/infrastructure/users/UserRegistryFile.js +89 -0
  130. package/dist/infrastructure/users/UserRegistryFile.js.map +1 -0
  131. package/dist/infrastructure/users/ensureWorkspaceOwners.d.ts +12 -0
  132. package/dist/infrastructure/users/ensureWorkspaceOwners.d.ts.map +1 -0
  133. package/dist/infrastructure/users/ensureWorkspaceOwners.js +25 -0
  134. package/dist/infrastructure/users/ensureWorkspaceOwners.js.map +1 -0
  135. package/dist/infrastructure/workspace/FsWorkspaceRepository.d.ts.map +1 -0
  136. package/dist/infrastructure/{fs → workspace}/FsWorkspaceRepository.js +15 -5
  137. package/dist/infrastructure/workspace/FsWorkspaceRepository.js.map +1 -0
  138. package/dist/infrastructure/workspace/WorkspaceDiscovery.d.ts +18 -0
  139. package/dist/infrastructure/workspace/WorkspaceDiscovery.d.ts.map +1 -0
  140. package/dist/infrastructure/workspace/WorkspaceDiscovery.js +50 -0
  141. package/dist/infrastructure/workspace/WorkspaceDiscovery.js.map +1 -0
  142. package/dist/infrastructure/workspace/WorkspaceRegistryFile.d.ts +42 -0
  143. package/dist/infrastructure/workspace/WorkspaceRegistryFile.d.ts.map +1 -0
  144. package/dist/infrastructure/workspace/WorkspaceRegistryFile.js +160 -0
  145. package/dist/infrastructure/workspace/WorkspaceRegistryFile.js.map +1 -0
  146. package/dist/infrastructure/workspace/productManifestWriter.d.ts +24 -0
  147. package/dist/infrastructure/workspace/productManifestWriter.d.ts.map +1 -0
  148. package/dist/infrastructure/{fs → workspace}/productManifestWriter.js +14 -28
  149. package/dist/infrastructure/workspace/productManifestWriter.js.map +1 -0
  150. package/dist/middleware/auth.d.ts +39 -0
  151. package/dist/middleware/auth.d.ts.map +1 -0
  152. package/dist/middleware/auth.js +87 -0
  153. package/dist/middleware/auth.js.map +1 -0
  154. package/dist/middleware/cors.d.ts.map +1 -1
  155. package/dist/middleware/cors.js +5 -2
  156. package/dist/middleware/cors.js.map +1 -1
  157. package/dist/middleware/error.d.ts.map +1 -1
  158. package/dist/middleware/error.js +15 -13
  159. package/dist/middleware/error.js.map +1 -1
  160. package/dist/middleware/workspaceAccess.d.ts +51 -0
  161. package/dist/middleware/workspaceAccess.d.ts.map +1 -0
  162. package/dist/middleware/workspaceAccess.js +91 -0
  163. package/dist/middleware/workspaceAccess.js.map +1 -0
  164. package/dist/policy/CapabilityCheck.d.ts +14 -0
  165. package/dist/policy/CapabilityCheck.d.ts.map +1 -0
  166. package/dist/policy/CapabilityCheck.js +2 -0
  167. package/dist/policy/CapabilityCheck.js.map +1 -0
  168. package/dist/policy/PermissionRegistry.d.ts +25 -0
  169. package/dist/policy/PermissionRegistry.d.ts.map +1 -0
  170. package/dist/policy/PermissionRegistry.js +29 -0
  171. package/dist/policy/PermissionRegistry.js.map +1 -0
  172. package/dist/policy/ViewerContext.d.ts +29 -0
  173. package/dist/policy/ViewerContext.d.ts.map +1 -0
  174. package/dist/policy/ViewerContext.js +2 -0
  175. package/dist/policy/ViewerContext.js.map +1 -0
  176. package/dist/policy/checks.d.ts +15 -0
  177. package/dist/policy/checks.d.ts.map +1 -0
  178. package/dist/policy/checks.js +55 -0
  179. package/dist/policy/checks.js.map +1 -0
  180. package/dist/policy/defaultRegistry.d.ts +9 -0
  181. package/dist/policy/defaultRegistry.d.ts.map +1 -0
  182. package/dist/policy/defaultRegistry.js +15 -0
  183. package/dist/policy/defaultRegistry.js.map +1 -0
  184. package/dist/policy/index.d.ts +8 -0
  185. package/dist/policy/index.d.ts.map +1 -0
  186. package/dist/policy/index.js +5 -0
  187. package/dist/policy/index.js.map +1 -0
  188. package/dist/policy/resolveViewer.d.ts +16 -0
  189. package/dist/policy/resolveViewer.d.ts.map +1 -0
  190. package/dist/policy/resolveViewer.js +37 -0
  191. package/dist/policy/resolveViewer.js.map +1 -0
  192. package/dist/routes/_shared.d.ts +138 -0
  193. package/dist/routes/_shared.d.ts.map +1 -0
  194. package/dist/routes/_shared.js +33 -0
  195. package/dist/routes/_shared.js.map +1 -0
  196. package/dist/routes/admin.d.ts +13 -0
  197. package/dist/routes/admin.d.ts.map +1 -0
  198. package/dist/routes/admin.js +228 -0
  199. package/dist/routes/admin.js.map +1 -0
  200. package/dist/routes/auth.d.ts +35 -0
  201. package/dist/routes/auth.d.ts.map +1 -0
  202. package/dist/routes/auth.js +168 -0
  203. package/dist/routes/auth.js.map +1 -0
  204. package/dist/routes/batch.d.ts +7 -0
  205. package/dist/routes/batch.d.ts.map +1 -0
  206. package/dist/routes/batch.js +47 -0
  207. package/dist/routes/batch.js.map +1 -0
  208. package/dist/routes/clarifications.d.ts +8 -0
  209. package/dist/routes/clarifications.d.ts.map +1 -0
  210. package/dist/routes/clarifications.js +243 -0
  211. package/dist/routes/clarifications.js.map +1 -0
  212. package/dist/routes/edges.d.ts +2 -2
  213. package/dist/routes/edges.d.ts.map +1 -1
  214. package/dist/routes/edges.js +34 -16
  215. package/dist/routes/edges.js.map +1 -1
  216. package/dist/routes/health.d.ts +2 -2
  217. package/dist/routes/health.d.ts.map +1 -1
  218. package/dist/routes/health.js +21 -3
  219. package/dist/routes/health.js.map +1 -1
  220. package/dist/routes/history.d.ts +7 -0
  221. package/dist/routes/history.d.ts.map +1 -0
  222. package/dist/routes/history.js +90 -0
  223. package/dist/routes/history.js.map +1 -0
  224. package/dist/routes/model.d.ts +2 -2
  225. package/dist/routes/model.d.ts.map +1 -1
  226. package/dist/routes/model.js +20 -4
  227. package/dist/routes/model.js.map +1 -1
  228. package/dist/routes/nodes.d.ts +2 -2
  229. package/dist/routes/nodes.d.ts.map +1 -1
  230. package/dist/routes/nodes.js +77 -25
  231. package/dist/routes/nodes.js.map +1 -1
  232. package/dist/routes/oauth.d.ts +6 -7
  233. package/dist/routes/oauth.d.ts.map +1 -1
  234. package/dist/routes/oauth.js +6 -7
  235. package/dist/routes/oauth.js.map +1 -1
  236. package/dist/routes/ontology.d.ts +2 -2
  237. package/dist/routes/ontology.d.ts.map +1 -1
  238. package/dist/routes/ontology.js +22 -5
  239. package/dist/routes/ontology.js.map +1 -1
  240. package/dist/routes/proposals.d.ts +5 -4
  241. package/dist/routes/proposals.d.ts.map +1 -1
  242. package/dist/routes/proposals.js +176 -45
  243. package/dist/routes/proposals.js.map +1 -1
  244. package/dist/routes/reactorCycles.d.ts +7 -0
  245. package/dist/routes/reactorCycles.d.ts.map +1 -0
  246. package/dist/routes/reactorCycles.js +60 -0
  247. package/dist/routes/reactorCycles.js.map +1 -0
  248. package/dist/routes/runs.d.ts.map +1 -1
  249. package/dist/routes/runs.js +66 -12
  250. package/dist/routes/runs.js.map +1 -1
  251. package/dist/routes/skillInputOptions.d.ts +10 -0
  252. package/dist/routes/skillInputOptions.d.ts.map +1 -0
  253. package/dist/routes/skillInputOptions.js +159 -0
  254. package/dist/routes/skillInputOptions.js.map +1 -0
  255. package/dist/routes/skills.d.ts +21 -3
  256. package/dist/routes/skills.d.ts.map +1 -1
  257. package/dist/routes/skills.js +223 -21
  258. package/dist/routes/skills.js.map +1 -1
  259. package/dist/routes/sourceLoaders.d.ts +7 -0
  260. package/dist/routes/sourceLoaders.d.ts.map +1 -0
  261. package/dist/routes/sourceLoaders.js +30 -0
  262. package/dist/routes/sourceLoaders.js.map +1 -0
  263. package/dist/routes/sourceUnitObservations.d.ts +20 -0
  264. package/dist/routes/sourceUnitObservations.d.ts.map +1 -0
  265. package/dist/routes/sourceUnitObservations.js +80 -0
  266. package/dist/routes/sourceUnitObservations.js.map +1 -0
  267. package/dist/routes/sourceWebhooks.d.ts +26 -0
  268. package/dist/routes/sourceWebhooks.d.ts.map +1 -0
  269. package/dist/routes/sourceWebhooks.js +301 -0
  270. package/dist/routes/sourceWebhooks.js.map +1 -0
  271. package/dist/routes/users.d.ts +7 -0
  272. package/dist/routes/users.d.ts.map +1 -0
  273. package/dist/routes/users.js +109 -0
  274. package/dist/routes/users.js.map +1 -0
  275. package/dist/routes/workspaceEvents.d.ts +5 -4
  276. package/dist/routes/workspaceEvents.d.ts.map +1 -1
  277. package/dist/routes/workspaceEvents.js +7 -6
  278. package/dist/routes/workspaceEvents.js.map +1 -1
  279. package/dist/routes/workspaceMembers.d.ts +11 -0
  280. package/dist/routes/workspaceMembers.d.ts.map +1 -0
  281. package/dist/routes/workspaceMembers.js +81 -0
  282. package/dist/routes/workspaceMembers.js.map +1 -0
  283. package/dist/routes/workspaces.d.ts +30 -1
  284. package/dist/routes/workspaces.d.ts.map +1 -1
  285. package/dist/routes/workspaces.js +207 -63
  286. package/dist/routes/workspaces.js.map +1 -1
  287. package/dist/server.js +9 -29
  288. package/dist/server.js.map +1 -1
  289. package/dist/startServer.d.ts +17 -0
  290. package/dist/startServer.d.ts.map +1 -0
  291. package/dist/startServer.js +81 -0
  292. package/dist/startServer.js.map +1 -0
  293. package/dist/startup.d.ts +28 -0
  294. package/dist/startup.d.ts.map +1 -0
  295. package/dist/startup.js +94 -0
  296. package/dist/startup.js.map +1 -0
  297. package/package.json +49 -32
  298. package/LICENSE +0 -21
  299. package/dist/composeFs.d.ts +0 -20
  300. package/dist/composeFs.d.ts.map +0 -1
  301. package/dist/composeFs.js +0 -134
  302. package/dist/composeFs.js.map +0 -1
  303. package/dist/composition.d.ts +0 -49
  304. package/dist/composition.d.ts.map +0 -1
  305. package/dist/composition.js +0 -43
  306. package/dist/composition.js.map +0 -1
  307. package/dist/infrastructure/agent/ClaudeCodeAgentBinding.d.ts +0 -8
  308. package/dist/infrastructure/agent/ClaudeCodeAgentBinding.d.ts.map +0 -1
  309. package/dist/infrastructure/agent/ClaudeCodeAgentBinding.js +0 -62
  310. package/dist/infrastructure/agent/ClaudeCodeAgentBinding.js.map +0 -1
  311. package/dist/infrastructure/agent/SubprocessSkillRunner.d.ts.map +0 -1
  312. package/dist/infrastructure/agent/SubprocessSkillRunner.js.map +0 -1
  313. package/dist/infrastructure/agent/asyncQueue.d.ts +0 -22
  314. package/dist/infrastructure/agent/asyncQueue.d.ts.map +0 -1
  315. package/dist/infrastructure/agent/mcpConfig.d.ts +0 -18
  316. package/dist/infrastructure/agent/mcpConfig.d.ts.map +0 -1
  317. package/dist/infrastructure/agent/mcpConfig.js +0 -47
  318. package/dist/infrastructure/agent/mcpConfig.js.map +0 -1
  319. package/dist/infrastructure/agent/streamJsonParser.d.ts +0 -20
  320. package/dist/infrastructure/agent/streamJsonParser.d.ts.map +0 -1
  321. package/dist/infrastructure/agent/streamJsonParser.js.map +0 -1
  322. package/dist/infrastructure/agent/subprocessEventStream.d.ts +0 -26
  323. package/dist/infrastructure/agent/subprocessEventStream.d.ts.map +0 -1
  324. package/dist/infrastructure/agent/subprocessEventStream.js +0 -112
  325. package/dist/infrastructure/agent/subprocessEventStream.js.map +0 -1
  326. package/dist/infrastructure/fs/FsClarifyTicketRepository.d.ts +0 -13
  327. package/dist/infrastructure/fs/FsClarifyTicketRepository.d.ts.map +0 -1
  328. package/dist/infrastructure/fs/FsClarifyTicketRepository.js +0 -33
  329. package/dist/infrastructure/fs/FsClarifyTicketRepository.js.map +0 -1
  330. package/dist/infrastructure/fs/FsDecisionRepository.d.ts +0 -13
  331. package/dist/infrastructure/fs/FsDecisionRepository.d.ts.map +0 -1
  332. package/dist/infrastructure/fs/FsDecisionRepository.js +0 -56
  333. package/dist/infrastructure/fs/FsDecisionRepository.js.map +0 -1
  334. package/dist/infrastructure/fs/FsProposalRepository.d.ts.map +0 -1
  335. package/dist/infrastructure/fs/FsProposalRepository.js.map +0 -1
  336. package/dist/infrastructure/fs/FsRunRepository.d.ts.map +0 -1
  337. package/dist/infrastructure/fs/FsRunRepository.js +0 -88
  338. package/dist/infrastructure/fs/FsRunRepository.js.map +0 -1
  339. package/dist/infrastructure/fs/FsSkillRegistry.d.ts.map +0 -1
  340. package/dist/infrastructure/fs/FsSkillRegistry.js.map +0 -1
  341. package/dist/infrastructure/fs/FsStatusedJsonRepository.d.ts +0 -35
  342. package/dist/infrastructure/fs/FsStatusedJsonRepository.d.ts.map +0 -1
  343. package/dist/infrastructure/fs/FsStatusedJsonRepository.js.map +0 -1
  344. package/dist/infrastructure/fs/FsWorkspaceRepository.d.ts.map +0 -1
  345. package/dist/infrastructure/fs/FsWorkspaceRepository.js.map +0 -1
  346. package/dist/infrastructure/fs/WorkspaceRegistryFile.d.ts +0 -17
  347. package/dist/infrastructure/fs/WorkspaceRegistryFile.d.ts.map +0 -1
  348. package/dist/infrastructure/fs/WorkspaceRegistryFile.js +0 -58
  349. package/dist/infrastructure/fs/WorkspaceRegistryFile.js.map +0 -1
  350. package/dist/infrastructure/fs/frontmatter.d.ts +0 -13
  351. package/dist/infrastructure/fs/frontmatter.d.ts.map +0 -1
  352. package/dist/infrastructure/fs/frontmatter.js.map +0 -1
  353. package/dist/infrastructure/fs/jsonFileStore.d.ts.map +0 -1
  354. package/dist/infrastructure/fs/jsonFileStore.js.map +0 -1
  355. package/dist/infrastructure/fs/paths.d.ts +0 -22
  356. package/dist/infrastructure/fs/paths.d.ts.map +0 -1
  357. package/dist/infrastructure/fs/paths.js +0 -46
  358. package/dist/infrastructure/fs/paths.js.map +0 -1
  359. package/dist/infrastructure/fs/productManifestWriter.d.ts +0 -22
  360. package/dist/infrastructure/fs/productManifestWriter.d.ts.map +0 -1
  361. package/dist/infrastructure/fs/productManifestWriter.js.map +0 -1
  362. package/dist/infrastructure/orphanReaper.d.ts +0 -18
  363. package/dist/infrastructure/orphanReaper.d.ts.map +0 -1
  364. package/dist/infrastructure/orphanReaper.js.map +0 -1
  365. package/dist/routes/clarify.d.ts +0 -8
  366. package/dist/routes/clarify.d.ts.map +0 -1
  367. package/dist/routes/clarify.js +0 -84
  368. package/dist/routes/clarify.js.map +0 -1
  369. package/dist/routes/decisions.d.ts +0 -7
  370. package/dist/routes/decisions.d.ts.map +0 -1
  371. package/dist/routes/decisions.js +0 -30
  372. package/dist/routes/decisions.js.map +0 -1
  373. /package/dist/infrastructure/{fs → _shared}/jsonFileStore.d.ts +0 -0
  374. /package/dist/infrastructure/{fs → _shared}/jsonFileStore.js +0 -0
  375. /package/dist/infrastructure/{fs → hitl}/FsProposalRepository.d.ts +0 -0
  376. /package/dist/infrastructure/{fs → workspace}/FsWorkspaceRepository.d.ts +0 -0
@@ -0,0 +1,301 @@
1
+ import { Buffer } from 'node:buffer';
2
+ import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
3
+ import { createLogger, NotFoundError, ServiceUnavailableError, UnauthorizedError, ValidationError } from '@braidhq/core';
4
+ import { SourceId, WorkspaceId } from '@braidhq/schema';
5
+ import { createRoute, OpenAPIHono, z } from '@hono/zod-openapi';
6
+ import { Hono } from 'hono';
7
+ import { WorkspaceIdParam } from './_shared.js';
8
+ /**
9
+ * GitHub webhook plumbing for filesystem sources,
10
+ * whose loader plugin declares a `webhook` capability.
11
+ *
12
+ * Two routers.
13
+ *
14
+ * `createGithubWebhookReceiver` is public (no Bearer auth).
15
+ * GitHub POSTs deliveries here.
16
+ * We verify the HMAC, confirm the payload names the claimed repo,
17
+ * ask the plugin whether the event is worth a `syncOne`,
18
+ * and dispatch in the background. The response returns immediately,
19
+ * so GitHub's ~10s delivery timeout never trips on a slow loader.
20
+ *
21
+ * `createSourceWebhooksAdminRouter` is workspace-scoped,
22
+ * and gated by the existing auth middleware.
23
+ * Studio uses it to display the webhook URL and rotate the secret.
24
+ *
25
+ * The receiver is loader-agnostic and does not switch on `loader.kind`.
26
+ * A new loader extends the webhook surface from its plugin definition,
27
+ * via `webhook: { repoIdentity, shouldDispatch }`.
28
+ *
29
+ * Secrets live in the existing `SecretStore`,
30
+ * under namespace `webhook-github`, keyed by `<workspaceId>--<sourceId>`.
31
+ * That mirrors the OAuth namespaces (oauth-google, oauth-github),
32
+ * which already use the same `--` separator.
33
+ */
34
+ const SECRET_NAMESPACE = 'webhook-github';
35
+ const PROVIDER = 'github';
36
+ function secretKey(workspaceId, sourceId) {
37
+ return `${workspaceId}--${sourceId}`;
38
+ }
39
+ const receiverLogger = createLogger('webhooks.github.receiver');
40
+ // Verify GitHub's `X-Hub-Signature-256` header.
41
+ // GitHub computes `sha256=<hex>` over the raw body with the secret.
42
+ // We recompute and compare in constant time.
43
+ // The prefix check is case-insensitive,
44
+ // because some proxies and WAFs normalise headers.
45
+ function verifySignature(rawBody, header, secret) {
46
+ if (!header || !header.toLowerCase().startsWith('sha256='))
47
+ return false;
48
+ // Normalise the hex digest to lowercase,
49
+ // so the timing-safe compare still accepts an uppercased hex,
50
+ // (rare but valid).
51
+ const provided = `sha256=${header.slice('sha256='.length).toLowerCase()}`;
52
+ const expected = `sha256=${createHmac('sha256', secret).update(rawBody).digest('hex')}`;
53
+ const a = Buffer.from(expected);
54
+ const b = Buffer.from(provided);
55
+ if (a.length !== b.length)
56
+ return false;
57
+ return timingSafeEqual(a, b);
58
+ }
59
+ // Look up the loader plugin's `webhook` capability for a source.
60
+ // Returns undefined when the source is not webhook-capable, never throws.
61
+ function resolveWebhookCapability(pluginRegistry, source) {
62
+ if (source.kind !== 'filesystem' || !source.loader)
63
+ return undefined;
64
+ const plugin = pluginRegistry.findSourceLoader(source.loader.kind);
65
+ if (!plugin?.webhook)
66
+ return undefined;
67
+ return { capability: plugin.webhook, config: source.loader.config };
68
+ }
69
+ // Uniform anonymous response for any pre-signature failure,
70
+ // (missing workspace, source, webhook capability, secret, or HMAC).
71
+ // Distinct error bodies would leak which pairs exist,
72
+ // and which are webhook-armed, to an unauthenticated caller.
73
+ // That recon ladder we deliberately close off.
74
+ function unauthorized() {
75
+ throw new UnauthorizedError('Invalid webhook signature.');
76
+ }
77
+ // Run the full pre-signature pipeline inside a single try/catch,
78
+ // (header presence, body read, workspace and source lookup,
79
+ // plugin webhook capability, repo identity, secret read, HMAC verify).
80
+ // Returns the trusted state on success and `undefined` on any failure.
81
+ // The caller collapses every failure mode to a 401.
82
+ async function verifyDelivery(deps, context, workspaceId, sourceId) {
83
+ try {
84
+ const signature = context.req.header('X-Hub-Signature-256');
85
+ if (!signature)
86
+ return undefined;
87
+ const rawBody = await context.req.text();
88
+ const workspace = await deps.workspaceService.findById(workspaceId);
89
+ const source = workspace.sources.find(s => s.id === sourceId);
90
+ if (!source)
91
+ return undefined;
92
+ const resolved = resolveWebhookCapability(deps.pluginRegistry, source);
93
+ if (!resolved)
94
+ return undefined;
95
+ const identity = resolved.capability.repoIdentity(resolved.config);
96
+ if (!identity || identity.provider !== PROVIDER)
97
+ return undefined;
98
+ const record = await deps.secretStore.read(SECRET_NAMESPACE, secretKey(workspaceId, sourceId));
99
+ if (!record)
100
+ return undefined;
101
+ if (!verifySignature(rawBody, signature, record.secret))
102
+ return undefined;
103
+ return { workspace, resolved, identity, rawBody };
104
+ }
105
+ catch (err) {
106
+ receiverLogger.warn({ workspaceId, sourceId, err: err instanceof Error ? err.message : String(err) }, 'webhook: pre-signature check failed');
107
+ return undefined;
108
+ }
109
+ }
110
+ export function createGithubWebhookReceiver(deps) {
111
+ const router = new Hono();
112
+ // `:workspaceId/:sourceId` is the routing identity,
113
+ // the user installs on the GitHub side.
114
+ // We accept the request, verify, and return 202 immediately.
115
+ // Sync runs in the background,
116
+ // so a slow loader never blocks GitHub's delivery worker.
117
+ // GitHub times deliveries out at ~10s.
118
+ router.post('/github/:workspaceId/:sourceId', async (context) => {
119
+ const workspaceId = WorkspaceId.parse(context.req.param('workspaceId'));
120
+ const sourceId = SourceId.parse(context.req.param('sourceId'));
121
+ // The verifyDelivery call returns either the trusted state or undefined,
122
+ // (workspace, resolved capability, repository identity, raw body).
123
+ // On undefined we always return a uniform 401,
124
+ // so distinct errors never tell an anonymous caller apart,
125
+ // "no such workspace", "no secret yet", and "bad signature".
126
+ const verified = await verifyDelivery(deps, context, workspaceId, sourceId);
127
+ if (!verified)
128
+ return unauthorized();
129
+ const { workspace, resolved, identity, rawBody } = verified;
130
+ // Parse the body only after the signature check,
131
+ // so an attacker who can't forge the HMAC, never reaches our JSON parser.
132
+ let payload;
133
+ try {
134
+ payload = JSON.parse(rawBody);
135
+ }
136
+ catch {
137
+ throw new ValidationError('Invalid JSON payload.');
138
+ }
139
+ const fullName = extractFullName(payload);
140
+ const expectedFullName = `${identity.owner}/${identity.repo}`.toLowerCase();
141
+ // GitHub repo names are case-insensitive,
142
+ // (a stored `Owner/Repo` may arrive as `owner/repo`, or vice versa).
143
+ // Compare normalised. Also REQUIRE full_name to be present.
144
+ // A verified delivery without one is rejected,
145
+ // since this receiver is per-source,
146
+ // (some org-level or installation events omit it).
147
+ if (typeof fullName !== 'string' || fullName.toLowerCase() !== expectedFullName)
148
+ throw new ValidationError(`Payload repository "${fullName ?? '(missing)'}" does not match configured "${expectedFullName}".`);
149
+ // X-GitHub-Event must be present on real deliveries.
150
+ // Treating an absent header as "unknown",
151
+ // would let a stripping proxy silently drop every event,
152
+ // since loaders default to skipping unknown events.
153
+ const event = context.req.header('X-GitHub-Event');
154
+ if (!event)
155
+ throw new ValidationError('Missing X-GitHub-Event header.');
156
+ const shouldDispatch = resolved.capability.shouldDispatch?.(resolved.config, { event, payload }) ?? true;
157
+ if (!shouldDispatch) {
158
+ // Return 202 so GitHub does not treat the delivery as a failure,
159
+ // and back off retries, deliberately accepting and dropping.
160
+ return context.json({ accepted: true, event, workspaceId, sourceId, skipped: true }, 202);
161
+ }
162
+ // Fire-and-forget. Deliveries time out at ~10s,
163
+ // and a clean repo with many issues can take minutes to poll.
164
+ // Errors are logged so a failing sync doesn't silently disappear,
165
+ // the next delivery retries.
166
+ // Concurrent deliveries are allowed to race, loaders are idempotent,
167
+ // (last-writer-wins per file) so the result still converges,
168
+ // to the latest remote state.
169
+ void deps.sourceLoaderRunner.syncOne(workspace, sourceId).catch((err) => {
170
+ receiverLogger.warn({
171
+ workspaceId,
172
+ sourceId,
173
+ err: err instanceof Error ? err.message : String(err),
174
+ }, 'background syncOne triggered by github webhook failed');
175
+ });
176
+ return context.json({ accepted: true, event, workspaceId, sourceId, skipped: false }, 202);
177
+ });
178
+ return router;
179
+ }
180
+ function extractFullName(payload) {
181
+ if (typeof payload !== 'object' || payload === null)
182
+ return undefined;
183
+ const repository = payload.repository;
184
+ if (typeof repository !== 'object' || repository === null)
185
+ return undefined;
186
+ const fullName = repository.full_name;
187
+ return typeof fullName === 'string' ? fullName : undefined;
188
+ }
189
+ const adminLogger = createLogger('webhooks.github.admin');
190
+ const SourceIdParam = WorkspaceIdParam.extend({
191
+ sourceId: SourceId.openapi({ param: { name: 'sourceId', in: 'path' } }),
192
+ });
193
+ const WebhookStatusResponse = z.object({
194
+ url: z.string(),
195
+ hasSecret: z.boolean(),
196
+ createdAt: z.string().optional(),
197
+ }).openapi('GithubWebhookStatusResponse');
198
+ const WebhookRotateResponse = z.object({
199
+ url: z.string(),
200
+ secret: z.string(),
201
+ createdAt: z.string(),
202
+ }).openapi('GithubWebhookRotateResponse');
203
+ const ErrorBody = z.object({ error: z.string() }).openapi('GithubWebhookErrorBody');
204
+ const getStatusRoute = createRoute({
205
+ method: 'get',
206
+ path: '/{sourceId}/github',
207
+ operationId: 'getGithubWebhookStatus',
208
+ summary: 'Read the GitHub webhook URL and whether a secret has been provisioned for a source.',
209
+ tags: ['source-webhooks'],
210
+ request: { params: SourceIdParam },
211
+ responses: {
212
+ 200: {
213
+ description: 'Webhook URL plus secret-presence flag (the secret itself is never returned on read).',
214
+ content: { 'application/json': { schema: WebhookStatusResponse } },
215
+ },
216
+ 400: { description: 'Source is not webhook-capable.', content: { 'application/json': { schema: ErrorBody } } },
217
+ 404: { description: 'Source not found.', content: { 'application/json': { schema: ErrorBody } } },
218
+ 503: { description: 'Server was not configured with apiUrl.', content: { 'application/json': { schema: ErrorBody } } },
219
+ },
220
+ });
221
+ const rotateRoute = createRoute({
222
+ method: 'post',
223
+ path: '/{sourceId}/github/rotate',
224
+ operationId: 'rotateGithubWebhookSecret',
225
+ summary: 'Generate a fresh 32-byte hex secret for the GitHub webhook, returning it ONCE.',
226
+ description: 'The secret is shown exactly once in the rotate response so the user can copy it into GitHub. Subsequent GET requests return only `hasSecret` + `createdAt`.',
227
+ tags: ['source-webhooks'],
228
+ request: { params: SourceIdParam },
229
+ responses: {
230
+ 200: {
231
+ description: 'New secret minted and stored.',
232
+ content: { 'application/json': { schema: WebhookRotateResponse } },
233
+ },
234
+ 400: { description: 'Source is not webhook-capable.', content: { 'application/json': { schema: ErrorBody } } },
235
+ 404: { description: 'Source not found.', content: { 'application/json': { schema: ErrorBody } } },
236
+ 503: { description: 'Server was not configured with apiUrl.', content: { 'application/json': { schema: ErrorBody } } },
237
+ },
238
+ });
239
+ export function createSourceWebhooksAdminRouter(deps) {
240
+ const router = new OpenAPIHono();
241
+ router.openapi(getStatusRoute, async (context) => {
242
+ const { workspaceId, sourceId } = context.req.valid('param');
243
+ if (!deps.apiUrl)
244
+ throw new ServiceUnavailableError('Server is not configured with a public apiUrl. Webhook URLs cannot be rendered.');
245
+ await guardWebhookSource(deps, workspaceId, sourceId);
246
+ const record = await deps.secretStore.read(SECRET_NAMESPACE, secretKey(workspaceId, sourceId));
247
+ return context.json({
248
+ url: buildWebhookUrl(deps.apiUrl, workspaceId, sourceId),
249
+ hasSecret: record !== undefined,
250
+ ...(record?.createdAt ? { createdAt: record.createdAt } : {}),
251
+ }, 200);
252
+ });
253
+ router.openapi(rotateRoute, async (context) => {
254
+ const { workspaceId, sourceId } = context.req.valid('param');
255
+ if (!deps.apiUrl)
256
+ throw new ServiceUnavailableError('Server is not configured with a public apiUrl. Webhook URLs cannot be rendered.');
257
+ await guardWebhookSource(deps, workspaceId, sourceId);
258
+ // 32 bytes is the GitHub-recommended minimum,
259
+ // matching what their own webhook setup UI generates.
260
+ const secret = randomBytes(32).toString('hex');
261
+ const createdAt = new Date().toISOString();
262
+ const record = { secret, createdAt };
263
+ await deps.secretStore.write(SECRET_NAMESPACE, secretKey(workspaceId, sourceId), record);
264
+ return context.json({
265
+ url: buildWebhookUrl(deps.apiUrl, workspaceId, sourceId),
266
+ secret,
267
+ createdAt,
268
+ }, 200);
269
+ });
270
+ return router;
271
+ }
272
+ // Shared admin precondition check.
273
+ // Returns undefined when the source is a webhook-capable github source,
274
+ // otherwise returns the 4xx the caller should surface.
275
+ // We never throw. On schema drift defineSourceLoaderPlugin's wrapper,
276
+ // may throw ZodError, which we catch and translate to 400.
277
+ async function guardWebhookSource(deps, workspaceId, sourceId) {
278
+ const workspace = await deps.workspaceService.findById(workspaceId);
279
+ const source = workspace.sources.find(s => s.id === sourceId);
280
+ if (!source)
281
+ throw new NotFoundError(`Source "${sourceId}" not found`);
282
+ const resolved = resolveWebhookCapability(deps.pluginRegistry, source);
283
+ if (!resolved)
284
+ throw new ValidationError(`Source "${sourceId}" has no webhook-capable loader.`);
285
+ try {
286
+ const identity = resolved.capability.repoIdentity(resolved.config);
287
+ if (!identity || identity.provider !== PROVIDER)
288
+ throw new ValidationError(`Source "${sourceId}" is not bound to a github repo.`);
289
+ }
290
+ catch (err) {
291
+ if (err instanceof ValidationError)
292
+ throw err;
293
+ adminLogger.warn({ workspaceId, sourceId, err: err instanceof Error ? err.message : String(err) }, 'admin: repoIdentity threw');
294
+ throw new ValidationError(`Source "${sourceId}" loader config does not match the loader's schema.`);
295
+ }
296
+ }
297
+ function buildWebhookUrl(apiUrl, workspaceId, sourceId) {
298
+ const base = apiUrl.replace(/\/$/, '');
299
+ return `${base}/webhooks/github/${workspaceId}/${sourceId}`;
300
+ }
301
+ //# sourceMappingURL=sourceWebhooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceWebhooks.js","sourceRoot":"","sources":["../../src/routes/sourceWebhooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { UserRegistryFile } from '../infrastructure/users/UserRegistryFile.js';
2
+ import { OpenAPIHono } from '@hono/zod-openapi';
3
+ export interface UsersRouterDeps {
4
+ userRegistry: UserRegistryFile;
5
+ }
6
+ export declare function createUsersRouter(deps: UsersRouterDeps): OpenAPIHono;
7
+ //# sourceMappingURL=users.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../src/routes/users.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAA;AAGnF,OAAO,EAAe,WAAW,EAAK,MAAM,mBAAmB,CAAA;AAkB/D,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,gBAAgB,CAAA;CAC/B;AAmED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,WAAW,CAmCpE"}
@@ -0,0 +1,109 @@
1
+ import { ForbiddenError, NotFoundError } from '@braidhq/core';
2
+ import { User, UserId } from '@braidhq/schema';
3
+ import { createRoute, OpenAPIHono, z } from '@hono/zod-openapi';
4
+ import { getUserId } from '../middleware/auth.js';
5
+ import { ForbiddenResponse, NotFoundResponse } from './_shared.js';
6
+ const UserIdParam = z.object({
7
+ userId: UserId.openapi({ param: { name: 'userId', in: 'path' } }),
8
+ });
9
+ const UserListResponse = z.object({
10
+ items: z.array(User),
11
+ }).openapi('UserListResponse');
12
+ // Self-service profile edit, only the display name.
13
+ // Server-role changes go through the admin-gated `/admin/users` routes.
14
+ const SelfProfileUpdate = z.object({
15
+ displayName: z.string().min(1),
16
+ });
17
+ const listUsersRoute = createRoute({
18
+ method: 'get',
19
+ path: '/',
20
+ operationId: 'listUsers',
21
+ summary: 'List all users on this server.',
22
+ tags: ['users'],
23
+ responses: {
24
+ 200: {
25
+ description: 'A list of users.',
26
+ content: { 'application/json': { schema: UserListResponse } },
27
+ },
28
+ },
29
+ });
30
+ const getMeRoute = createRoute({
31
+ method: 'get',
32
+ path: '/me',
33
+ operationId: 'getMe',
34
+ summary: 'Return the user identified by the current request context.',
35
+ tags: ['users'],
36
+ responses: {
37
+ 200: {
38
+ description: 'The current user.',
39
+ content: { 'application/json': { schema: User } },
40
+ },
41
+ 404: NotFoundResponse,
42
+ },
43
+ });
44
+ const getUserRoute = createRoute({
45
+ method: 'get',
46
+ path: '/{userId}',
47
+ operationId: 'getUser',
48
+ summary: 'Fetch a single user by id.',
49
+ tags: ['users'],
50
+ request: { params: UserIdParam },
51
+ responses: {
52
+ 200: {
53
+ description: 'The requested user.',
54
+ content: { 'application/json': { schema: User } },
55
+ },
56
+ 404: NotFoundResponse,
57
+ },
58
+ });
59
+ const updateUserRoute = createRoute({
60
+ method: 'patch',
61
+ path: '/{userId}',
62
+ operationId: 'updateUser',
63
+ summary: 'Update your own display name, role changes go through /admin.',
64
+ tags: ['users'],
65
+ request: {
66
+ params: UserIdParam,
67
+ body: { content: { 'application/json': { schema: SelfProfileUpdate } } },
68
+ },
69
+ responses: {
70
+ 200: {
71
+ description: 'The updated user.',
72
+ content: { 'application/json': { schema: User } },
73
+ },
74
+ 403: ForbiddenResponse,
75
+ 404: NotFoundResponse,
76
+ },
77
+ });
78
+ export function createUsersRouter(deps) {
79
+ const router = new OpenAPIHono();
80
+ router.openapi(listUsersRoute, async (context) => {
81
+ const users = await deps.userRegistry.list();
82
+ return context.json({ items: users }, 200);
83
+ });
84
+ router.openapi(getMeRoute, async (context) => {
85
+ const userId = getUserId(context);
86
+ const user = await deps.userRegistry.get(userId);
87
+ if (!user)
88
+ throw new NotFoundError(`Current user "${userId}" not found in registry`);
89
+ return context.json(user, 200);
90
+ });
91
+ router.openapi(getUserRoute, async (context) => {
92
+ const { userId } = context.req.valid('param');
93
+ const user = await deps.userRegistry.get(userId);
94
+ if (!user)
95
+ throw new NotFoundError(`User "${userId}" not found`);
96
+ return context.json(user, 200);
97
+ });
98
+ router.openapi(updateUserRoute, async (context) => {
99
+ const { userId } = context.req.valid('param');
100
+ // Self-service only. Server-admin edits go through the admin routes.
101
+ if (userId !== getUserId(context))
102
+ throw new ForbiddenError('You can only update your own profile.');
103
+ const patch = context.req.valid('json');
104
+ const updated = await deps.userRegistry.update(userId, patch);
105
+ return context.json(updated, 200);
106
+ });
107
+ return router;
108
+ }
109
+ //# sourceMappingURL=users.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/routes/users.ts"],"names":[],"mappings":"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"}
@@ -4,10 +4,11 @@ export interface WorkspaceEventsRouterDeps {
4
4
  readonly eventBus: WorkspaceEventBus;
5
5
  }
6
6
  /**
7
- * SSE endpoint the Studio opens once per workspace to invalidate
8
- * react-query caches in real time. Pure delivery: events are dropped if
9
- * no one is listening, and the route makes no attempt to backfill state
10
- * on connect. The client re-fetches list endpoints on `EventSource.open`
7
+ * SSE endpoint the Studio opens once per workspace,
8
+ * to invalidate react-query caches in real time.
9
+ * Delivery is best-effort, events are dropped when no one is listening,
10
+ * and the route makes no attempt to backfill state on connect.
11
+ * The client re-fetches list endpoints on `EventSource.open`,
11
12
  * so a fresh subscriber catches up.
12
13
  */
13
14
  export declare function createWorkspaceEventsRouter(deps: WorkspaceEventsRouterDeps): Hono;
@@ -1 +1 @@
1
- {"version":3,"file":"workspaceEvents.d.ts","sourceRoot":"","sources":["../../src/routes/workspaceEvents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACtE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAK3B,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,yBAAyB,GAAG,IAAI,CA0BjF"}
1
+ {"version":3,"file":"workspaceEvents.d.ts","sourceRoot":"","sources":["../../src/routes/workspaceEvents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAEtD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAK3B,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;CACrC;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,yBAAyB,GAAG,IAAI,CA0BjF"}
@@ -1,12 +1,13 @@
1
1
  import { Hono } from 'hono';
2
2
  import { streamSSE } from 'hono/streaming';
3
- import { createAsyncQueue } from '../infrastructure/agent/asyncQueue.js';
3
+ import { createAsyncQueue } from '../infrastructure/skill/asyncQueue.js';
4
4
  import { getWorkspaceId, workspaceIdMiddleware } from '../middleware/workspaceId.js';
5
5
  /**
6
- * SSE endpoint the Studio opens once per workspace to invalidate
7
- * react-query caches in real time. Pure delivery: events are dropped if
8
- * no one is listening, and the route makes no attempt to backfill state
9
- * on connect. The client re-fetches list endpoints on `EventSource.open`
6
+ * SSE endpoint the Studio opens once per workspace,
7
+ * to invalidate react-query caches in real time.
8
+ * Delivery is best-effort, events are dropped when no one is listening,
9
+ * and the route makes no attempt to backfill state on connect.
10
+ * The client re-fetches list endpoints on `EventSource.open`,
10
11
  * so a fresh subscriber catches up.
11
12
  */
12
13
  export function createWorkspaceEventsRouter(deps) {
@@ -18,7 +19,7 @@ export function createWorkspaceEventsRouter(deps) {
18
19
  const unsubscribe = deps.eventBus.subscribe(workspaceId, (event) => {
19
20
  queue.push(event);
20
21
  });
21
- // Initial comment so the client's EventSource.onopen fires
22
+ // Initial comment so the client's EventSource.onopen fires,
22
23
  // immediately even if no event has been published yet.
23
24
  await stream.writeSSE({ event: 'ready', data: JSON.stringify({ workspaceId }) });
24
25
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"workspaceEvents.js","sourceRoot":"","sources":["../../src/routes/workspaceEvents.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAA;AACxE,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AAMpF;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,CAAC,IAA+B;IACzE,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAA;IAEzB,MAAM,CAAC,GAAG,CAAC,sBAAsB,EAAE,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC1E,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QAC3C,OAAO,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACzC,MAAM,KAAK,GAAG,gBAAgB,EAAkB,CAAA;YAChD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE;gBACjE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACnB,CAAC,CAAC,CAAA;YACF,2DAA2D;YAC3D,uDAAuD;YACvD,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAA;YAChF,IAAI,CAAC;gBACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;oBAC1C,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;gBAC3E,CAAC;YACH,CAAC;oBACO,CAAC;gBACP,WAAW,EAAE,CAAA;gBACb,KAAK,CAAC,GAAG,EAAE,CAAA;YACb,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC"}
1
+ {"version":3,"file":"workspaceEvents.js","sourceRoot":"","sources":["../../src/routes/workspaceEvents.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAA;AACxE,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AAMpF;;;;;;;GAOG;AACH,MAAM,UAAU,2BAA2B,CAAC,IAA+B;IACzE,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAA;IAEzB,MAAM,CAAC,GAAG,CAAC,sBAAsB,EAAE,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC1E,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QAC3C,OAAO,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACzC,MAAM,KAAK,GAAG,gBAAgB,EAAkB,CAAA;YAChD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE;gBACjE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACnB,CAAC,CAAC,CAAA;YACF,4DAA4D;YAC5D,uDAAuD;YACvD,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAA;YAChF,IAAI,CAAC;gBACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;oBAC1C,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;gBAC3E,CAAC;YACH,CAAC;oBACO,CAAC;gBACP,WAAW,EAAE,CAAA;gBACb,KAAK,CAAC,GAAG,EAAE,CAAA;YACb,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Clock, WorkspaceService } from '@braidhq/core';
2
+ import type { WorkspaceRegistryFile } from '../infrastructure/workspace/WorkspaceRegistryFile.js';
3
+ import { Hono } from 'hono';
4
+ export interface WorkspaceMembersRouterDeps {
5
+ workspaceService: WorkspaceService;
6
+ registry: WorkspaceRegistryFile;
7
+ clock: Clock;
8
+ }
9
+ export declare function createWorkspaceMembersRouter(deps: WorkspaceMembersRouterDeps): Hono;
10
+ export declare function createTransferOwnershipRouter(deps: WorkspaceMembersRouterDeps): Hono;
11
+ //# sourceMappingURL=workspaceMembers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaceMembers.d.ts","sourceRoot":"","sources":["../../src/routes/workspaceMembers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAE5D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sDAAsD,CAAA;AAIjG,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAqB3B,MAAM,WAAW,0BAA0B;IACzC,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,QAAQ,EAAE,qBAAqB,CAAA;IAC/B,KAAK,EAAE,KAAK,CAAA;CACb;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,0BAA0B,GAAG,IAAI,CAoDnF;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,0BAA0B,GAAG,IAAI,CAWpF"}
@@ -0,0 +1,81 @@
1
+ import { NotFoundError } from '@braidhq/core';
2
+ import { SkillPermission, UserId, WorkspaceRole } from '@braidhq/schema';
3
+ import { zValidator } from '@hono/zod-validator';
4
+ import { Hono } from 'hono';
5
+ import { z } from 'zod';
6
+ import { requirePermission } from '../middleware/workspaceAccess.js';
7
+ import { getWorkspaceId } from '../middleware/workspaceId.js';
8
+ const AddMemberBody = z.object({
9
+ userId: UserId,
10
+ role: WorkspaceRole.default('guest'),
11
+ });
12
+ const PatchMemberBody = z.object({
13
+ role: WorkspaceRole.optional(),
14
+ skillOverrides: z.record(z.string().min(1), SkillPermission).optional(),
15
+ }).refine(body => Object.keys(body).length > 0, {
16
+ message: 'PATCH body must include role and/or skillOverrides',
17
+ });
18
+ const TransferBody = z.object({
19
+ newOwnerId: UserId,
20
+ });
21
+ export function createWorkspaceMembersRouter(deps) {
22
+ const router = new Hono();
23
+ const ownerOnly = requirePermission('workspace.write');
24
+ // List is open to every member of the workspace.
25
+ // The access middleware upstream already enforced membership.
26
+ router.get('/', async (context) => {
27
+ const workspaceId = getWorkspaceId(context);
28
+ const workspace = await deps.workspaceService.findById(workspaceId);
29
+ const members = await deps.registry.listMembers(workspace.rootPath);
30
+ return context.json({ items: members });
31
+ });
32
+ router.post('/', ownerOnly, zValidator('json', AddMemberBody), async (context) => {
33
+ const workspaceId = getWorkspaceId(context);
34
+ const { userId, role } = context.req.valid('json');
35
+ const workspace = await deps.workspaceService.findById(workspaceId);
36
+ const member = {
37
+ userId,
38
+ role,
39
+ joinedAt: deps.clock.now(),
40
+ };
41
+ await deps.registry.addMember(workspace.rootPath, member);
42
+ return context.json(member, 201);
43
+ });
44
+ router.patch('/:memberUserId', ownerOnly, zValidator('json', PatchMemberBody), async (context) => {
45
+ const workspaceId = getWorkspaceId(context);
46
+ const memberUserId = UserId.parse(context.req.param('memberUserId'));
47
+ const patch = context.req.valid('json');
48
+ const workspace = await deps.workspaceService.findById(workspaceId);
49
+ const next = await deps.registry.updateMember(workspace.rootPath, memberUserId, {
50
+ ...(patch.role ? { role: patch.role } : {}),
51
+ ...(patch.skillOverrides
52
+ ? { skillOverrides: patch.skillOverrides }
53
+ : {}),
54
+ });
55
+ return context.json(next);
56
+ });
57
+ router.delete('/:memberUserId', ownerOnly, async (context) => {
58
+ const workspaceId = getWorkspaceId(context);
59
+ const memberUserId = UserId.parse(context.req.param('memberUserId'));
60
+ const workspace = await deps.workspaceService.findById(workspaceId);
61
+ const exists = await deps.registry.getMember(workspace.rootPath, memberUserId);
62
+ if (!exists)
63
+ throw new NotFoundError(`User "${memberUserId}" is not a member of this workspace`);
64
+ await deps.registry.removeMember(workspace.rootPath, memberUserId);
65
+ return context.body(null, 204);
66
+ });
67
+ return router;
68
+ }
69
+ export function createTransferOwnershipRouter(deps) {
70
+ const router = new Hono();
71
+ router.post('/', requirePermission('workspace.write'), zValidator('json', TransferBody), async (context) => {
72
+ const workspaceId = getWorkspaceId(context);
73
+ const { newOwnerId } = context.req.valid('json');
74
+ const workspace = await deps.workspaceService.findById(workspaceId);
75
+ await deps.registry.transferOwnership(workspace.rootPath, newOwnerId);
76
+ const members = await deps.registry.listMembers(workspace.rootPath);
77
+ return context.json({ items: members });
78
+ });
79
+ return router;
80
+ }
81
+ //# sourceMappingURL=workspaceMembers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaceMembers.js","sourceRoot":"","sources":["../../src/routes/workspaceMembers.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAA;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAE7D,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7B,MAAM,EAAE,MAAM;IACd,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC;CACrC,CAAC,CAAA;AAEF,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/B,IAAI,EAAE,aAAa,CAAC,QAAQ,EAAE;IAC9B,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,QAAQ,EAAE;CACxE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;IAC9C,OAAO,EAAE,oDAAoD;CAC9D,CAAC,CAAA;AAEF,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM;CACnB,CAAC,CAAA;AAQF,MAAM,UAAU,4BAA4B,CAAC,IAAgC;IAC3E,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAA;IACzB,MAAM,SAAS,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,CAAA;IAEtD,iDAAiD;IACjD,8DAA8D;IAC9D,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChC,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QAC3C,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;QACnE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;QACnE,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC/E,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QAC3C,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAClD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;QACnE,MAAM,MAAM,GAAwB;YAClC,MAAM;YACN,IAAI;YACJ,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAe;SACxC,CAAA;QACD,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QACzD,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAClC,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,KAAK,CAAC,gBAAgB,EAAE,SAAS,EAAE,UAAU,CAAC,MAAM,EAAE,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC/F,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QAC3C,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAA;QACpE,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QACvC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;QACnE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,QAAQ,EAAE,YAAY,EAAE;YAC9E,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3C,GAAG,CAAC,KAAK,CAAC,cAAc;gBACtB,CAAC,CAAC,EAAE,cAAc,EAAE,KAAK,CAAC,cAA2E,EAAE;gBACvG,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CAAA;QACF,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC3D,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QAC3C,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAA;QACpE,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;QACnE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;QAC9E,IAAI,CAAC,MAAM;YACT,MAAM,IAAI,aAAa,CAAC,SAAS,YAAY,qCAAqC,CAAC,CAAA;QACrF,MAAM,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;QAClE,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IAChC,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,IAAgC;IAC5E,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAA;IACzB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,iBAAiB,CAAC,EAAE,UAAU,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACzG,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QAC3C,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAChD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;QACnE,MAAM,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QACrE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;QACnE,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;IACF,OAAO,MAAM,CAAA;AACf,CAAC"}