@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,88 @@
1
+ import { mkdir, readdir, readFile, rename, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import process from 'node:process';
4
+ import { NotFoundError } from '@braidhq/core';
5
+ import { SourceUnitObservation as SourceUnitObservationSchema } from '@braidhq/schema';
6
+ import { sourceUnitObservationDir, sourceUnitObservationFilePath, sourceUnitObservationSourceDir } from '../_shared/paths.js';
7
+ /**
8
+ * Filesystem-backed `SourceUnitObservationRepository`. Each entity maps to,
9
+ * `artifacts/source-unit-state/<sourceId>/<encoded-path>.json`, one file each,
10
+ * matching the file-per-entity pattern used by proposals / clarifications.
11
+ *
12
+ * The file body is exactly the `SourceUnitObservation` shape,
13
+ * with no wrapper or envelope.
14
+ * In a future SQLite or Postgres store,
15
+ * each file becomes one row keyed by `(workspaceId, sourceId, path)`.
16
+ */
17
+ export class FsSourceUnitObservationRepository {
18
+ options;
19
+ constructor(options) {
20
+ this.options = options;
21
+ }
22
+ async find(workspaceId, sourceId, path) {
23
+ const root = await this.resolveRoot(workspaceId);
24
+ const file = sourceUnitObservationFilePath(root, sourceId, path);
25
+ try {
26
+ const raw = await readFile(file, 'utf-8');
27
+ return SourceUnitObservationSchema.parse(JSON.parse(raw));
28
+ }
29
+ catch (error) {
30
+ if (error.code === 'ENOENT')
31
+ return null;
32
+ throw error;
33
+ }
34
+ }
35
+ async save(state) {
36
+ const root = await this.resolveRoot(state.workspaceId);
37
+ const file = sourceUnitObservationFilePath(root, state.sourceId, state.path);
38
+ await mkdir(sourceUnitObservationSourceDir(root, state.sourceId), { recursive: true });
39
+ const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
40
+ await writeFile(tmp, `${JSON.stringify(state, null, 2)}\n`, 'utf-8');
41
+ await rename(tmp, file);
42
+ }
43
+ async listByWorkspace(workspaceId) {
44
+ const root = await this.resolveRoot(workspaceId);
45
+ const baseDir = sourceUnitObservationDir(root);
46
+ const sourceDirs = await safeReaddir(baseDir);
47
+ const all = [];
48
+ for (const sourceDir of sourceDirs) {
49
+ if (!sourceDir.isDirectory())
50
+ continue;
51
+ all.push(...await readEntriesIn(join(baseDir, sourceDir.name)));
52
+ }
53
+ return all;
54
+ }
55
+ async listBySource(workspaceId, sourceId) {
56
+ const root = await this.resolveRoot(workspaceId);
57
+ return readEntriesIn(sourceUnitObservationSourceDir(root, sourceId));
58
+ }
59
+ async resolveRoot(workspaceId) {
60
+ const roots = await this.options.workspaceRoots();
61
+ const root = roots.get(workspaceId);
62
+ if (!root)
63
+ throw new NotFoundError(`Workspace "${workspaceId}" has no registered root path`);
64
+ return root;
65
+ }
66
+ }
67
+ async function safeReaddir(dir) {
68
+ try {
69
+ return await readdir(dir, { withFileTypes: true });
70
+ }
71
+ catch (error) {
72
+ if (error.code === 'ENOENT')
73
+ return [];
74
+ throw error;
75
+ }
76
+ }
77
+ async function readEntriesIn(dir) {
78
+ const entries = await safeReaddir(dir);
79
+ const results = [];
80
+ for (const entry of entries) {
81
+ if (!entry.isFile() || !entry.name.endsWith('.json'))
82
+ continue;
83
+ const raw = await readFile(join(dir, entry.name), 'utf-8');
84
+ results.push(SourceUnitObservationSchema.parse(JSON.parse(raw)));
85
+ }
86
+ return results;
87
+ }
88
+ //# sourceMappingURL=FsSourceUnitObservationRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FsSourceUnitObservationRepository.js","sourceRoot":"","sources":["../../../src/infrastructure/source/FsSourceUnitObservationRepository.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC9E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,qBAAqB,IAAI,2BAA2B,EAAE,MAAM,iBAAiB,CAAA;AACtF,OAAO,EAAE,wBAAwB,EAAE,6BAA6B,EAAE,8BAA8B,EAAE,MAAM,qBAAqB,CAAA;AAY7H;;;;;;;;;GASG;AACH,MAAM,OAAO,iCAAiC;IACf;IAA7B,YAA6B,OAAiD;QAAjD,YAAO,GAAP,OAAO,CAA0C;IAAG,CAAC;IAElF,KAAK,CAAC,IAAI,CAAC,WAAwB,EAAE,QAAkB,EAAE,IAAY;QACnE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAA;QAChD,MAAM,IAAI,GAAG,6BAA6B,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;QAChE,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;YACzC,OAAO,2BAA2B,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;QAC3D,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACb,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;gBACpD,OAAO,IAAI,CAAA;YACb,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAA4B;QACrC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;QACtD,MAAM,IAAI,GAAG,6BAA6B,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QAC5E,MAAM,KAAK,CAAC,8BAA8B,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACtF,MAAM,GAAG,GAAG,GAAG,IAAI,QAAQ,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAA;QACtD,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QACpE,MAAM,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACzB,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,WAAwB;QAC5C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAA;QAChD,MAAM,OAAO,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAA;QAC9C,MAAM,UAAU,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAA;QAC7C,MAAM,GAAG,GAA4B,EAAE,CAAA;QACvC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE;gBAC1B,SAAQ;YACV,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjE,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,WAAwB,EAAE,QAAkB;QAC7D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAA;QAChD,OAAO,aAAa,CAAC,8BAA8B,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAA;IACtE,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,WAAwB;QAChD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAA;QACjD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QACnC,IAAI,CAAC,IAAI;YACP,MAAM,IAAI,aAAa,CAAC,cAAc,WAAW,+BAA+B,CAAC,CAAA;QACnF,OAAO,IAAI,CAAA;IACb,CAAC;CACF;AAED,KAAK,UAAU,WAAW,CAAC,GAAW;IACpC,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;IACpD,CAAC;IACD,OAAO,KAAK,EAAE,CAAC;QACb,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YACpD,OAAO,EAAE,CAAA;QACX,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,GAAW;IACtC,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAA;IACtC,MAAM,OAAO,GAA4B,EAAE,CAAA;IAC3C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YAClD,SAAQ;QACV,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAA;QAC1D,OAAO,CAAC,IAAI,CAAC,2BAA2B,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAClE,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { Workspace } from '@braidhq/core';
2
+ export interface IntentItem {
3
+ readonly value: string;
4
+ readonly label: string;
5
+ readonly sourceId: string;
6
+ readonly sourceName: string;
7
+ }
8
+ /**
9
+ * Shared by the Studio source picker and BatchService,
10
+ * so both see the same per-doc granularity.
11
+ */
12
+ export declare function listIntentItems(workspace: Workspace): Promise<IntentItem[]>;
13
+ //# sourceMappingURL=intentScan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intentScan.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/source/intentScan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAM9C,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAcjF"}
@@ -0,0 +1,137 @@
1
+ import { readdir } from 'node:fs/promises';
2
+ import { isAbsolute, join } from 'node:path';
3
+ const INTENT_FILE_EXTENSIONS = new Set(['.md', '.mdx', '.markdown', '.txt', '.rst']);
4
+ /**
5
+ * Shared by the Studio source picker and BatchService,
6
+ * so both see the same per-doc granularity.
7
+ */
8
+ export async function listIntentItems(workspace) {
9
+ const items = [];
10
+ for (const source of workspace.sources) {
11
+ if (source.role !== 'intent')
12
+ continue;
13
+ if (source.kind !== 'filesystem')
14
+ // MCP intent sources aren't directory-listable, future enhancement.
15
+ continue;
16
+ const absoluteRoot = isAbsolute(source.path)
17
+ ? source.path
18
+ : join(workspace.rootPath, source.path);
19
+ items.push(...await listIntentEntries(absoluteRoot, source.id, source.name));
20
+ }
21
+ return items;
22
+ }
23
+ async function listIntentEntries(root, sourceId, sourceName) {
24
+ const items = [];
25
+ let topEntries;
26
+ try {
27
+ topEntries = await readdir(root, { withFileTypes: true });
28
+ }
29
+ catch {
30
+ return items;
31
+ }
32
+ for (const entry of topEntries) {
33
+ if (entry.name.startsWith('.'))
34
+ continue;
35
+ if (entry.isDirectory()) {
36
+ const folder = join(root, entry.name);
37
+ // A flat directory of loose markdown files gives one unit per file,
38
+ // so downstream skills run per-document rather than over the bag all at once.
39
+ // Such layouts include a github loader's issues tree,
40
+ // or a hand-curated prd folder of onboarding docs.
41
+ // A directory with its own sub-structure stays a single unit,
42
+ // since that structure is the unit's own organisation.
43
+ const flatFiles = await listFlatDocumentFiles(folder);
44
+ if (flatFiles) {
45
+ for (const name of flatFiles) {
46
+ items.push({
47
+ value: `${entry.name}/${name}`,
48
+ label: `${entry.name}/${stripExtension(name)}`,
49
+ sourceId,
50
+ sourceName,
51
+ });
52
+ }
53
+ continue;
54
+ }
55
+ if (await containsDocument(folder, 4)) {
56
+ items.push({
57
+ value: `${entry.name}/`,
58
+ label: entry.name,
59
+ sourceId,
60
+ sourceName,
61
+ });
62
+ }
63
+ continue;
64
+ }
65
+ if (entry.isFile() && isIntentDocument(entry.name)) {
66
+ items.push({
67
+ value: entry.name,
68
+ label: stripExtension(entry.name),
69
+ sourceId,
70
+ sourceName,
71
+ });
72
+ }
73
+ }
74
+ return items.sort((a, b) => a.label.localeCompare(b.label));
75
+ }
76
+ // A flat document directory has every visible entry a markdown file,
77
+ // with no subdirectories.
78
+ // For one, returns the sorted list of filenames.
79
+ // Returns `undefined` otherwise, so the caller falls back to treating,
80
+ // the directory as a single unit.
81
+ // "Visible" here excludes dotfiles,
82
+ // so sync state like `.braid-github-cursor.json` doesn't disqualify it.
83
+ async function listFlatDocumentFiles(dir) {
84
+ let entries;
85
+ try {
86
+ entries = await readdir(dir, { withFileTypes: true });
87
+ }
88
+ catch {
89
+ return undefined;
90
+ }
91
+ const docs = [];
92
+ for (const entry of entries) {
93
+ if (entry.name.startsWith('.'))
94
+ continue;
95
+ if (entry.isDirectory())
96
+ return undefined;
97
+ if (!entry.isFile())
98
+ continue;
99
+ if (!isIntentDocument(entry.name))
100
+ return undefined;
101
+ docs.push(entry.name);
102
+ }
103
+ if (docs.length === 0)
104
+ return undefined;
105
+ return docs.sort((a, b) => a.localeCompare(b));
106
+ }
107
+ async function containsDocument(dir, maxDepth) {
108
+ if (maxDepth < 0)
109
+ return false;
110
+ let entries;
111
+ try {
112
+ entries = await readdir(dir, { withFileTypes: true });
113
+ }
114
+ catch {
115
+ return false;
116
+ }
117
+ for (const entry of entries) {
118
+ if (entry.name.startsWith('.'))
119
+ continue;
120
+ if (entry.isFile() && isIntentDocument(entry.name))
121
+ return true;
122
+ if (entry.isDirectory() && await containsDocument(join(dir, entry.name), maxDepth - 1))
123
+ return true;
124
+ }
125
+ return false;
126
+ }
127
+ function isIntentDocument(filename) {
128
+ const dot = filename.lastIndexOf('.');
129
+ if (dot < 0)
130
+ return false;
131
+ return INTENT_FILE_EXTENSIONS.has(filename.slice(dot).toLowerCase());
132
+ }
133
+ function stripExtension(filename) {
134
+ const dot = filename.lastIndexOf('.');
135
+ return dot < 0 ? filename : filename.slice(0, dot);
136
+ }
137
+ //# sourceMappingURL=intentScan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intentScan.js","sourceRoot":"","sources":["../../../src/infrastructure/source/intentScan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { UserAuthor, UserDirectory } from '@braidhq/core';
2
+ import type { UserId } from '@braidhq/schema';
3
+ import type { UserRegistryFile } from './UserRegistryFile.js';
4
+ /**
5
+ * Adapt the file-backed user roster to the core `UserDirectory` port.
6
+ * Returns `null` for unknown ids (such as bootstrap or `braid-skill`),
7
+ * so the git layer falls back to its synthetic author for those rows.
8
+ */
9
+ export declare class UserDirectoryFromRegistry implements UserDirectory {
10
+ private readonly registry;
11
+ constructor(registry: UserRegistryFile);
12
+ resolve(userId: UserId): Promise<UserAuthor | null>;
13
+ }
14
+ //# sourceMappingURL=UserDirectoryFromRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserDirectoryFromRegistry.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/users/UserDirectoryFromRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAE7D;;;;GAIG;AACH,qBAAa,yBAA0B,YAAW,aAAa;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,gBAAgB;IAEjD,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;CAS1D"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Adapt the file-backed user roster to the core `UserDirectory` port.
3
+ * Returns `null` for unknown ids (such as bootstrap or `braid-skill`),
4
+ * so the git layer falls back to its synthetic author for those rows.
5
+ */
6
+ export class UserDirectoryFromRegistry {
7
+ registry;
8
+ constructor(registry) {
9
+ this.registry = registry;
10
+ }
11
+ async resolve(userId) {
12
+ const user = await this.registry.get(userId);
13
+ if (!user)
14
+ return null;
15
+ return {
16
+ displayName: user.displayName,
17
+ ...(user.email ? { email: user.email } : {}),
18
+ };
19
+ }
20
+ }
21
+ //# sourceMappingURL=UserDirectoryFromRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserDirectoryFromRegistry.js","sourceRoot":"","sources":["../../../src/infrastructure/users/UserDirectoryFromRegistry.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,OAAO,yBAAyB;IACP;IAA7B,YAA6B,QAA0B;QAA1B,aAAQ,GAAR,QAAQ,CAAkB;IAAG,CAAC;IAE3D,KAAK,CAAC,OAAO,CAAC,MAAc;QAC1B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAC5C,IAAI,CAAC,IAAI;YACP,OAAO,IAAI,CAAA;QACb,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7C,CAAA;IACH,CAAC;CACF"}
@@ -0,0 +1,22 @@
1
+ import type { UserId as UserIdType, UserUpdate as UserPatchType, User as UserType } from '@braidhq/schema';
2
+ /**
3
+ * Persists the user registry to a JSON file at `${BRAID_HOME}/users.json`.
4
+ * Source of truth across server restarts, in-memory data is a derivation.
5
+ *
6
+ * Auth and ACL are server-side concerns, never part of a workspace's git history.
7
+ * Keep this file under `~/.braid/`, not inside any workspace dir.
8
+ */
9
+ export declare class UserRegistryFile {
10
+ private readonly filePath;
11
+ constructor(filePath: string);
12
+ list(): Promise<UserType[]>;
13
+ get(id: UserIdType): Promise<UserType | undefined>;
14
+ getByGoogleSub(sub: string): Promise<UserType | undefined>;
15
+ getByEmail(email: string): Promise<UserType | undefined>;
16
+ create(user: UserType): Promise<UserType>;
17
+ update(id: UserIdType, patch: UserPatchType): Promise<UserType>;
18
+ delete(id: UserIdType): Promise<void>;
19
+ private read;
20
+ private write;
21
+ }
22
+ //# sourceMappingURL=UserRegistryFile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserRegistryFile.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/users/UserRegistryFile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,UAAU,IAAI,aAAa,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAa1G;;;;;;GAMG;AACH,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM;IAEvC,IAAI,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAK3B,GAAG,CAAC,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAKlD,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAK1D,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAMxD,MAAM,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAWzC,MAAM,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC;IAkB/D,MAAM,CAAC,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;YAQ7B,IAAI;YAeJ,KAAK;CAIpB"}
@@ -0,0 +1,89 @@
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { dirname } from 'node:path';
3
+ import { NotFoundError, ValidationError } from '@braidhq/core';
4
+ import { User } from '@braidhq/schema';
5
+ import { z } from 'zod';
6
+ const RegistryContent = z.object({
7
+ users: z.array(User).default([]),
8
+ });
9
+ /**
10
+ * Persists the user registry to a JSON file at `${BRAID_HOME}/users.json`.
11
+ * Source of truth across server restarts, in-memory data is a derivation.
12
+ *
13
+ * Auth and ACL are server-side concerns, never part of a workspace's git history.
14
+ * Keep this file under `~/.braid/`, not inside any workspace dir.
15
+ */
16
+ export class UserRegistryFile {
17
+ filePath;
18
+ constructor(filePath) {
19
+ this.filePath = filePath;
20
+ }
21
+ async list() {
22
+ const content = await this.read();
23
+ return content.users;
24
+ }
25
+ async get(id) {
26
+ const content = await this.read();
27
+ return content.users.find(u => u.id === id);
28
+ }
29
+ async getByGoogleSub(sub) {
30
+ const content = await this.read();
31
+ return content.users.find(u => u.googleSub === sub);
32
+ }
33
+ async getByEmail(email) {
34
+ const content = await this.read();
35
+ const lowered = email.toLowerCase();
36
+ return content.users.find(u => u.email?.toLowerCase() === lowered);
37
+ }
38
+ async create(user) {
39
+ const content = await this.read();
40
+ if (content.users.some(existing => existing.id === user.id))
41
+ throw new ValidationError(`User "${user.id}" already exists`);
42
+ if (user.googleSub && content.users.some(existing => existing.googleSub === user.googleSub))
43
+ throw new ValidationError(`User with googleSub "${user.googleSub}" already exists`);
44
+ content.users.push(user);
45
+ await this.write(content);
46
+ return user;
47
+ }
48
+ async update(id, patch) {
49
+ const content = await this.read();
50
+ const idx = content.users.findIndex(u => u.id === id);
51
+ if (idx < 0)
52
+ throw new NotFoundError(`User "${id}" not found`);
53
+ const current = content.users[idx];
54
+ // Drop undefined keys, so `{ displayName: undefined }` doesn't blow away the existing displayName.
55
+ // Zod's `.partial()` widens every field to optional,
56
+ // but the persisted User schema still requires the non-optional fields.
57
+ const defined = Object.fromEntries(Object.entries(patch).filter(([, v]) => v !== undefined));
58
+ const merged = { ...current, ...defined };
59
+ content.users[idx] = merged;
60
+ await this.write(content);
61
+ return merged;
62
+ }
63
+ async delete(id) {
64
+ const content = await this.read();
65
+ const filtered = content.users.filter(u => u.id !== id);
66
+ if (filtered.length === content.users.length)
67
+ return;
68
+ await this.write({ users: filtered });
69
+ }
70
+ async read() {
71
+ try {
72
+ const raw = await readFile(this.filePath, 'utf-8');
73
+ const parsed = RegistryContent.safeParse(JSON.parse(raw));
74
+ if (!parsed.success)
75
+ throw new ValidationError(`Invalid user registry at "${this.filePath}": ${parsed.error.message}`);
76
+ return parsed.data;
77
+ }
78
+ catch (error) {
79
+ if (error.code === 'ENOENT')
80
+ return { users: [] };
81
+ throw error;
82
+ }
83
+ }
84
+ async write(content) {
85
+ await mkdir(dirname(this.filePath), { recursive: true });
86
+ await writeFile(this.filePath, `${JSON.stringify(content, null, 2)}\n`, 'utf-8');
87
+ }
88
+ }
89
+ //# sourceMappingURL=UserRegistryFile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserRegistryFile.js","sourceRoot":"","sources":["../../../src/infrastructure/users/UserRegistryFile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { UserId } from '@braidhq/schema';
2
+ import type { WorkspaceRegistryFile } from '../workspace/WorkspaceRegistryFile.js';
3
+ /**
4
+ * Give every ownerless workspace a default owner.
5
+ * A workspace registered before the member model has an empty `members[]`.
6
+ * Single-tenant seeds `defaultOwner` so the install keeps working untouched.
7
+ * Multi-tenant passes null, where an ownerless workspace is a fault,
8
+ * every workspace there is created with an explicit owner, so this throws.
9
+ * Idempotent, workspaces that already have members are left alone.
10
+ */
11
+ export declare function ensureWorkspaceOwners(registry: WorkspaceRegistryFile, defaultOwner: UserId | null): Promise<void>;
12
+ //# sourceMappingURL=ensureWorkspaceOwners.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ensureWorkspaceOwners.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/users/ensureWorkspaceOwners.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAA;AAElF;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,qBAAqB,EAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,GAC1B,OAAO,CAAC,IAAI,CAAC,CAef"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Give every ownerless workspace a default owner.
3
+ * A workspace registered before the member model has an empty `members[]`.
4
+ * Single-tenant seeds `defaultOwner` so the install keeps working untouched.
5
+ * Multi-tenant passes null, where an ownerless workspace is a fault,
6
+ * every workspace there is created with an explicit owner, so this throws.
7
+ * Idempotent, workspaces that already have members are left alone.
8
+ */
9
+ export async function ensureWorkspaceOwners(registry, defaultOwner) {
10
+ const rootPaths = await registry.list();
11
+ const now = new Date().toISOString();
12
+ for (const rootPath of rootPaths) {
13
+ const members = await registry.listMembers(rootPath);
14
+ if (members.length > 0)
15
+ continue;
16
+ if (defaultOwner === null)
17
+ throw new Error(`Workspace at ${rootPath} has no owner, a multi-tenant server requires an explicit owner.`);
18
+ await registry.addMember(rootPath, {
19
+ userId: defaultOwner,
20
+ role: 'owner',
21
+ joinedAt: now,
22
+ });
23
+ }
24
+ }
25
+ //# sourceMappingURL=ensureWorkspaceOwners.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ensureWorkspaceOwners.js","sourceRoot":"","sources":["../../../src/infrastructure/users/ensureWorkspaceOwners.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,QAA+B,EAC/B,YAA2B;IAE3B,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;IACvC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAe,CAAA;IACjD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAA;QACpD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YACpB,SAAQ;QACV,IAAI,YAAY,KAAK,IAAI;YACvB,MAAM,IAAI,KAAK,CAAC,gBAAgB,QAAQ,kEAAkE,CAAC,CAAA;QAC7G,MAAM,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE;YACjC,MAAM,EAAE,YAAY;YACpB,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,GAAG;SACd,CAAC,CAAA;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FsWorkspaceRepository.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/workspace/FsWorkspaceRepository.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAGvE,OAAO,EAAgD,SAAS,EAAE,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACjH,OAAO,EAAE,YAAY,EAAgC,MAAM,iBAAiB,CAAA;AAM5E,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAA;CACzC;AAED,qBAAa,qBAAsB,YAAW,mBAAmB;IAGnD,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;gBAE9B,IAAI,EAAE,yBAAyB;IAOtD,IAAI,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAc5B,IAAI,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC;IAShD,IAAI,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAKzC,MAAM,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD,UAAU,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;YAI1B,YAAY;YAcZ,qBAAqB;YAerB,YAAY;IAY1B,OAAO,CAAC,aAAa;CAOtB"}
@@ -1,20 +1,31 @@
1
1
  import { readFile, stat } from 'node:fs/promises';
2
2
  import { resolve } from 'node:path';
3
- import { NotFoundError, ValidationError, Workspace } from '@braidhq/core';
3
+ import { createLogger, NotFoundError, ValidationError, Workspace } from '@braidhq/core';
4
4
  import { AbsolutePath, ProductManifest, WorkspaceId } from '@braidhq/schema';
5
- import { parseMarkdownFrontmatter } from './frontmatter.js';
6
- import { workspaceProductManifestPath } from './paths.js';
5
+ import { parseMarkdownFrontmatter } from '../_shared/frontmatter.js';
6
+ import { workspaceProductManifestPath } from '../_shared/paths.js';
7
+ const log = createLogger('server').child({ mod: 'workspace-repo' });
7
8
  export class FsWorkspaceRepository {
8
9
  deps;
9
10
  cache = new Map();
10
11
  constructor(deps) {
11
12
  this.deps = deps;
12
13
  }
14
+ // One unreadable rootPath, a deleted dir or a broken PRODUCT.md,
15
+ // must not starve the rest.
16
+ // The asymmetry with `load()` is deliberate.
17
+ // Aggregate views recover,
18
+ // whereas a single-entity lookup must tell present apart from absent.
13
19
  async list() {
14
20
  const rootPaths = await this.deps.registry.list();
15
21
  const workspaces = [];
16
22
  for (const rootPath of rootPaths) {
17
- workspaces.push(await this.load(rootPath));
23
+ try {
24
+ workspaces.push(await this.load(rootPath));
25
+ }
26
+ catch (err) {
27
+ log.warn({ err, rootPath }, 'skipping unreadable registry entry');
28
+ }
18
29
  }
19
30
  return workspaces;
20
31
  }
@@ -47,7 +58,6 @@ export class FsWorkspaceRepository {
47
58
  id: WorkspaceId.parse(productManifest.name),
48
59
  rootPath: AbsolutePath.parse(resolve(rootPath)),
49
60
  productManifest,
50
- pluginConfig: { plugins: [] },
51
61
  };
52
62
  return new Workspace(data);
53
63
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FsWorkspaceRepository.js","sourceRoot":"","sources":["../../../src/infrastructure/workspace/FsWorkspaceRepository.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,SAAS,EAA4B,MAAM,eAAe,CAAA;AACjH,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AACpE,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAA;AAElE,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAC,CAAA;AAMnE,MAAM,OAAO,qBAAqB;IAGH;IAFZ,KAAK,GAAG,IAAI,GAAG,EAA2B,CAAA;IAE3D,YAA6B,IAA+B;QAA/B,SAAI,GAAJ,IAAI,CAA2B;IAAG,CAAC;IAEhE,iEAAiE;IACjE,4BAA4B;IAC5B,6CAA6C;IAC7C,2BAA2B;IAC3B,sEAAsE;IACtE,KAAK,CAAC,IAAI;QACR,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAA;QACjD,MAAM,UAAU,GAAgB,EAAE,CAAA;QAClC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC;gBACH,UAAU,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;YAC5C,CAAC;YACD,OAAO,GAAG,EAAE,CAAC;gBACX,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,oCAAoC,CAAC,CAAA;YACnE,CAAC;QACH,CAAC;QACD,OAAO,UAAU,CAAA;IACnB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAAsB;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QACvC,IAAI,MAAM;YACR,OAAO,MAAM,CAAA;QACf,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;QACnD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;QACnC,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAoB;QAC7B,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;QAChD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;IAC/C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,QAAsB;QACjC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACzC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAC7B,CAAC;IAED,UAAU,CAAC,QAAsB;QAC/B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAC7B,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,QAAsB;QAC/C,MAAM,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAA;QAC1C,MAAM,YAAY,GAAG,4BAA4B,CAAC,QAAQ,CAAC,CAAA;QAC3D,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAA;QACjD,MAAM,EAAE,WAAW,EAAE,GAAG,wBAAwB,CAAU,GAAG,CAAC,CAAA;QAC9D,MAAM,eAAe,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,YAAY,CAAC,CAAA;QACrE,MAAM,IAAI,GAAkB;YAC1B,EAAE,EAAE,WAAW,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC;YAC3C,QAAQ,EAAE,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC/C,eAAe;SAChB,CAAA;QACD,OAAO,IAAI,SAAS,CAAC,IAAI,CAAC,CAAA;IAC5B,CAAC;IAEO,KAAK,CAAC,qBAAqB,CAAC,QAAsB;QACxD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAA;YAClC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACzB,MAAM,IAAI,eAAe,CAAC,mBAAmB,QAAQ,sBAAsB,CAAC,CAAA;YAC9E,CAAC;QACH,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACb,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,MAAM,IAAI,aAAa,CAAC,wBAAwB,QAAQ,aAAa,CAAC,CAAA;YACxE,CAAC;YACD,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,YAAoB;QAC7C,IAAI,CAAC;YACH,OAAO,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;QAC9C,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACb,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,MAAM,IAAI,aAAa,CAAC,4BAA4B,YAAY,GAAG,CAAC,CAAA;YACtE,CAAC;YACD,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;IAEO,aAAa,CAAC,GAAY,EAAE,YAAoB;QACtD,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QAC7C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,eAAe,CAAC,0BAA0B,YAAY,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QAC/F,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAA;IACpB,CAAC;CACF"}
@@ -0,0 +1,18 @@
1
+ import type { WorkspaceService } from '@braidhq/core';
2
+ import type { AbsolutePath } from '@braidhq/schema';
3
+ /**
4
+ * Walk `<workspacesRoot>/*` and register with the WorkspaceService,
5
+ * every subdirectory that owns a `PRODUCT.md`.
6
+ * It is idempotent,
7
+ * an already-registered workspace is a no-op against the FS registry.
8
+ * We run it on server boot,
9
+ * so CLI-created or hand-copied workspaces surface in Studio,
10
+ * without any explicit `register` step.
11
+ *
12
+ * A per-entry error, a corrupt PRODUCT.md or bad permissions,
13
+ * is logged and skipped.
14
+ * The server must still come up,
15
+ * so the user can fix the outlier and re-boot.
16
+ */
17
+ export declare function discoverCanonicalWorkspaces(workspacesRoot: AbsolutePath, workspaceService: WorkspaceService): Promise<void>;
18
+ //# sourceMappingURL=WorkspaceDiscovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkspaceDiscovery.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/workspace/WorkspaceDiscovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAKnD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,2BAA2B,CAC/C,cAAc,EAAE,YAAY,EAC5B,gBAAgB,EAAE,gBAAgB,GACjC,OAAO,CAAC,IAAI,CAAC,CAgCf"}
@@ -0,0 +1,50 @@
1
+ import { readdir, stat } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { createLogger } from '@braidhq/core';
4
+ /**
5
+ * Walk `<workspacesRoot>/*` and register with the WorkspaceService,
6
+ * every subdirectory that owns a `PRODUCT.md`.
7
+ * It is idempotent,
8
+ * an already-registered workspace is a no-op against the FS registry.
9
+ * We run it on server boot,
10
+ * so CLI-created or hand-copied workspaces surface in Studio,
11
+ * without any explicit `register` step.
12
+ *
13
+ * A per-entry error, a corrupt PRODUCT.md or bad permissions,
14
+ * is logged and skipped.
15
+ * The server must still come up,
16
+ * so the user can fix the outlier and re-boot.
17
+ */
18
+ export async function discoverCanonicalWorkspaces(workspacesRoot, workspaceService) {
19
+ const log = createLogger('server').child({ mod: 'workspace-discovery' });
20
+ let entries;
21
+ try {
22
+ entries = await readdir(workspacesRoot);
23
+ }
24
+ catch (err) {
25
+ // ENOENT on first boot is expected,
26
+ // the dir is created lazily by the first scaffold.
27
+ // Any other error, such as bad permissions, we log and continue.
28
+ // The server still boots.
29
+ if (err.code !== 'ENOENT')
30
+ log.warn({ err, workspacesRoot }, 'failed to read workspaces root');
31
+ return;
32
+ }
33
+ for (const entry of entries) {
34
+ const rootPath = join(workspacesRoot, entry);
35
+ try {
36
+ const dirStat = await stat(rootPath);
37
+ if (!dirStat.isDirectory())
38
+ continue;
39
+ const manifestStat = await stat(join(rootPath, 'PRODUCT.md')).catch(() => undefined);
40
+ if (!manifestStat?.isFile())
41
+ continue;
42
+ const workspace = await workspaceService.load(rootPath);
43
+ await workspaceService.save(workspace);
44
+ }
45
+ catch (err) {
46
+ log.warn({ err, rootPath }, 'skipping unreadable workspace dir');
47
+ }
48
+ }
49
+ }
50
+ //# sourceMappingURL=WorkspaceDiscovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkspaceDiscovery.js","sourceRoot":"","sources":["../../../src/infrastructure/workspace/WorkspaceDiscovery.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,cAA4B,EAC5B,gBAAkC;IAElC,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,qBAAqB,EAAE,CAAC,CAAA;IACxE,IAAI,OAAiB,CAAA;IACrB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,CAAA;IACzC,CAAC;IACD,OAAO,GAAG,EAAE,CAAC;QACX,oCAAoC;QACpC,mDAAmD;QACnD,iEAAiE;QACjE,0BAA0B;QAC1B,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAClD,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,EAAE,gCAAgC,CAAC,CAAA;QACrE,OAAM;IACR,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,KAAK,CAAiB,CAAA;QAC5D,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAA;YACpC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;gBACxB,SAAQ;YACV,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;YACpF,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE;gBACzB,SAAQ;YACV,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YACvD,MAAM,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACxC,CAAC;QACD,OAAO,GAAG,EAAE,CAAC;YACX,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,mCAAmC,CAAC,CAAA;QAClE,CAAC;IACH,CAAC;AACH,CAAC"}