@braidhq/server 0.1.0 → 0.2.1

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 (401) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -106
  3. package/dist/app.d.ts +7 -15
  4. package/dist/app.d.ts.map +1 -1
  5. package/dist/app.js +74 -45
  6. package/dist/app.js.map +1 -1
  7. package/dist/authMode.d.ts +39 -0
  8. package/dist/authMode.d.ts.map +1 -0
  9. package/dist/authMode.js +50 -0
  10. package/dist/authMode.js.map +1 -0
  11. package/dist/composeApp.d.ts +80 -0
  12. package/dist/composeApp.d.ts.map +1 -0
  13. package/dist/composeApp.js +137 -0
  14. package/dist/composeApp.js.map +1 -0
  15. package/dist/composeFsApp.d.ts +27 -0
  16. package/dist/composeFsApp.d.ts.map +1 -0
  17. package/dist/{composeFs.js → composeFsApp.js} +127 -126
  18. package/dist/composeFsApp.js.map +1 -0
  19. package/dist/index.d.ts +3 -2
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +3 -2
  22. package/dist/index.js.map +1 -1
  23. package/dist/infrastructure/_shared/env.d.ts +10 -0
  24. package/dist/infrastructure/_shared/env.d.ts.map +1 -0
  25. package/dist/infrastructure/{env.js → _shared/env.js} +5 -6
  26. package/dist/infrastructure/_shared/env.js.map +1 -0
  27. package/dist/infrastructure/_shared/frontmatter.d.ts +13 -0
  28. package/dist/infrastructure/_shared/frontmatter.d.ts.map +1 -0
  29. package/dist/infrastructure/{fs → _shared}/frontmatter.js +5 -5
  30. package/dist/infrastructure/_shared/frontmatter.js.map +1 -0
  31. package/dist/infrastructure/_shared/jsonFileStore.d.ts.map +1 -0
  32. package/dist/infrastructure/_shared/jsonFileStore.js.map +1 -0
  33. package/dist/infrastructure/{fs → _shared}/paths.d.ts +17 -10
  34. package/dist/infrastructure/_shared/paths.d.ts.map +1 -0
  35. package/dist/infrastructure/{fs → _shared}/paths.js +27 -20
  36. package/dist/infrastructure/_shared/paths.js.map +1 -0
  37. package/dist/infrastructure/auth/AccessPolicy.d.ts +33 -58
  38. package/dist/infrastructure/auth/AccessPolicy.d.ts.map +1 -1
  39. package/dist/infrastructure/auth/AccessPolicy.js +35 -42
  40. package/dist/infrastructure/auth/AccessPolicy.js.map +1 -1
  41. package/dist/infrastructure/auth/SessionStore.d.ts +22 -12
  42. package/dist/infrastructure/auth/SessionStore.d.ts.map +1 -1
  43. package/dist/infrastructure/auth/SessionStore.js +20 -20
  44. package/dist/infrastructure/auth/SessionStore.js.map +1 -1
  45. package/dist/infrastructure/batch/FsBatchPlanRepository.d.ts +14 -0
  46. package/dist/infrastructure/batch/FsBatchPlanRepository.d.ts.map +1 -0
  47. package/dist/infrastructure/{fs → batch}/FsBatchPlanRepository.js +9 -7
  48. package/dist/infrastructure/batch/FsBatchPlanRepository.js.map +1 -0
  49. package/dist/infrastructure/history/GitWorkspaceHistory.d.ts.map +1 -0
  50. package/dist/infrastructure/{git → history}/GitWorkspaceHistory.js +31 -24
  51. package/dist/infrastructure/history/GitWorkspaceHistory.js.map +1 -0
  52. package/dist/infrastructure/history/commitMessage.d.ts.map +1 -0
  53. package/dist/infrastructure/history/commitMessage.js +90 -0
  54. package/dist/infrastructure/history/commitMessage.js.map +1 -0
  55. package/dist/infrastructure/hitl/FsClarificationRepository.d.ts +13 -0
  56. package/dist/infrastructure/hitl/FsClarificationRepository.d.ts.map +1 -0
  57. package/dist/infrastructure/hitl/FsClarificationRepository.js +40 -0
  58. package/dist/infrastructure/hitl/FsClarificationRepository.js.map +1 -0
  59. package/dist/infrastructure/hitl/FsProposalRepository.d.ts.map +1 -0
  60. package/dist/infrastructure/{fs → hitl}/FsProposalRepository.js +8 -8
  61. package/dist/infrastructure/hitl/FsProposalRepository.js.map +1 -0
  62. package/dist/infrastructure/hitl/StatusedJsonStore.d.ts +30 -0
  63. package/dist/infrastructure/hitl/StatusedJsonStore.d.ts.map +1 -0
  64. package/dist/infrastructure/{fs/FsStatusedJsonRepository.js → hitl/StatusedJsonStore.js} +3 -3
  65. package/dist/infrastructure/hitl/StatusedJsonStore.js.map +1 -0
  66. package/dist/infrastructure/model/FsModelSerializer.d.ts +94 -0
  67. package/dist/infrastructure/model/FsModelSerializer.d.ts.map +1 -0
  68. package/dist/infrastructure/{fs/FsGraphSerializer.js → model/FsModelSerializer.js} +11 -11
  69. package/dist/infrastructure/model/FsModelSerializer.js.map +1 -0
  70. package/dist/infrastructure/oauth/GoogleOAuth.d.ts +20 -38
  71. package/dist/infrastructure/oauth/GoogleOAuth.d.ts.map +1 -1
  72. package/dist/infrastructure/oauth/GoogleOAuth.js +21 -22
  73. package/dist/infrastructure/oauth/GoogleOAuth.js.map +1 -1
  74. package/dist/infrastructure/reactor/FsReactorCycleRepository.d.ts +29 -0
  75. package/dist/infrastructure/reactor/FsReactorCycleRepository.d.ts.map +1 -0
  76. package/dist/infrastructure/reactor/FsReactorCycleRepository.js +94 -0
  77. package/dist/infrastructure/reactor/FsReactorCycleRepository.js.map +1 -0
  78. package/dist/infrastructure/secrets/SecretStore.d.ts +11 -14
  79. package/dist/infrastructure/secrets/SecretStore.d.ts.map +1 -1
  80. package/dist/infrastructure/secrets/SecretStore.js +4 -4
  81. package/dist/infrastructure/secrets/SecretStore.js.map +1 -1
  82. package/dist/infrastructure/{fs → skill}/FsRunRepository.d.ts +5 -3
  83. package/dist/infrastructure/skill/FsRunRepository.d.ts.map +1 -0
  84. package/dist/infrastructure/{fs → skill}/FsRunRepository.js +11 -9
  85. package/dist/infrastructure/skill/FsRunRepository.js.map +1 -0
  86. package/dist/infrastructure/{fs → skill}/FsSkillRegistry.d.ts +4 -13
  87. package/dist/infrastructure/skill/FsSkillRegistry.d.ts.map +1 -0
  88. package/dist/infrastructure/{fs → skill}/FsSkillRegistry.js +28 -20
  89. package/dist/infrastructure/skill/FsSkillRegistry.js.map +1 -0
  90. package/dist/infrastructure/skill/SubprocessSkillRunner.d.ts +52 -0
  91. package/dist/infrastructure/skill/SubprocessSkillRunner.d.ts.map +1 -0
  92. package/dist/infrastructure/{agent → skill}/SubprocessSkillRunner.js +107 -55
  93. package/dist/infrastructure/skill/SubprocessSkillRunner.js.map +1 -0
  94. package/dist/infrastructure/skill/asyncQueue.d.ts +20 -0
  95. package/dist/infrastructure/skill/asyncQueue.d.ts.map +1 -0
  96. package/dist/infrastructure/{agent → skill}/asyncQueue.js +2 -3
  97. package/dist/infrastructure/{agent → skill}/asyncQueue.js.map +1 -1
  98. package/dist/infrastructure/skill/lineBuffer.d.ts +15 -0
  99. package/dist/infrastructure/skill/lineBuffer.d.ts.map +1 -0
  100. package/dist/infrastructure/{agent/streamJsonParser.js → skill/lineBuffer.js} +5 -17
  101. package/dist/infrastructure/skill/lineBuffer.js.map +1 -0
  102. package/dist/infrastructure/skill/orphanReaper.d.ts +20 -0
  103. package/dist/infrastructure/skill/orphanReaper.d.ts.map +1 -0
  104. package/dist/infrastructure/{orphanReaper.js → skill/orphanReaper.js} +7 -5
  105. package/dist/infrastructure/skill/orphanReaper.js.map +1 -0
  106. package/dist/infrastructure/skill/subprocessEventStream.d.ts +16 -0
  107. package/dist/infrastructure/skill/subprocessEventStream.d.ts.map +1 -0
  108. package/dist/infrastructure/skill/subprocessEventStream.js +29 -0
  109. package/dist/infrastructure/skill/subprocessEventStream.js.map +1 -0
  110. package/dist/infrastructure/source/FsSourceUnitDigest.d.ts +19 -0
  111. package/dist/infrastructure/source/FsSourceUnitDigest.d.ts.map +1 -0
  112. package/dist/infrastructure/{fs → source}/FsSourceUnitDigest.js +9 -9
  113. package/dist/infrastructure/source/FsSourceUnitDigest.js.map +1 -0
  114. package/dist/infrastructure/source/FsSourceUnitObservationRepository.d.ts +31 -0
  115. package/dist/infrastructure/source/FsSourceUnitObservationRepository.d.ts.map +1 -0
  116. package/dist/infrastructure/{fs/FsSourceUnitStateRepository.js → source/FsSourceUnitObservationRepository.js} +18 -17
  117. package/dist/infrastructure/source/FsSourceUnitObservationRepository.js.map +1 -0
  118. package/dist/infrastructure/source/unitScan.d.ts +11 -0
  119. package/dist/infrastructure/source/unitScan.d.ts.map +1 -0
  120. package/dist/infrastructure/{fs/intentScan.js → source/unitScan.js} +36 -27
  121. package/dist/infrastructure/source/unitScan.js.map +1 -0
  122. package/dist/infrastructure/users/UserDirectoryFromRegistry.d.ts +2 -2
  123. package/dist/infrastructure/users/UserDirectoryFromRegistry.d.ts.map +1 -1
  124. package/dist/infrastructure/users/UserDirectoryFromRegistry.js +3 -2
  125. package/dist/infrastructure/users/UserDirectoryFromRegistry.js.map +1 -1
  126. package/dist/infrastructure/users/UserRegistryFile.d.ts +4 -5
  127. package/dist/infrastructure/users/UserRegistryFile.d.ts.map +1 -1
  128. package/dist/infrastructure/users/UserRegistryFile.js +6 -8
  129. package/dist/infrastructure/users/UserRegistryFile.js.map +1 -1
  130. package/dist/infrastructure/users/ensureWorkspaceOwners.d.ts +9 -6
  131. package/dist/infrastructure/users/ensureWorkspaceOwners.d.ts.map +1 -1
  132. package/dist/infrastructure/users/ensureWorkspaceOwners.js +10 -7
  133. package/dist/infrastructure/users/ensureWorkspaceOwners.js.map +1 -1
  134. package/dist/infrastructure/workspace/FsWorkspaceRepository.d.ts.map +1 -0
  135. package/dist/infrastructure/{fs → workspace}/FsWorkspaceRepository.js +7 -6
  136. package/dist/infrastructure/workspace/FsWorkspaceRepository.js.map +1 -0
  137. package/dist/infrastructure/workspace/WorkspaceDiscovery.d.ts +18 -0
  138. package/dist/infrastructure/workspace/WorkspaceDiscovery.d.ts.map +1 -0
  139. package/dist/infrastructure/{fs → workspace}/WorkspaceDiscovery.js +15 -11
  140. package/dist/infrastructure/workspace/WorkspaceDiscovery.js.map +1 -0
  141. package/dist/infrastructure/{fs → workspace}/WorkspaceRegistryFile.d.ts +10 -9
  142. package/dist/infrastructure/workspace/WorkspaceRegistryFile.d.ts.map +1 -0
  143. package/dist/infrastructure/{fs → workspace}/WorkspaceRegistryFile.js +15 -17
  144. package/dist/infrastructure/workspace/WorkspaceRegistryFile.js.map +1 -0
  145. package/dist/infrastructure/workspace/productManifestWriter.d.ts +24 -0
  146. package/dist/infrastructure/workspace/productManifestWriter.d.ts.map +1 -0
  147. package/dist/infrastructure/{fs → workspace}/productManifestWriter.js +14 -26
  148. package/dist/infrastructure/workspace/productManifestWriter.js.map +1 -0
  149. package/dist/middleware/auth.d.ts +27 -17
  150. package/dist/middleware/auth.d.ts.map +1 -1
  151. package/dist/middleware/auth.js +69 -53
  152. package/dist/middleware/auth.js.map +1 -1
  153. package/dist/middleware/cors.d.ts.map +1 -1
  154. package/dist/middleware/cors.js +4 -1
  155. package/dist/middleware/cors.js.map +1 -1
  156. package/dist/middleware/error.d.ts.map +1 -1
  157. package/dist/middleware/error.js +15 -13
  158. package/dist/middleware/error.js.map +1 -1
  159. package/dist/middleware/workspaceAccess.d.ts +23 -19
  160. package/dist/middleware/workspaceAccess.d.ts.map +1 -1
  161. package/dist/middleware/workspaceAccess.js +31 -26
  162. package/dist/middleware/workspaceAccess.js.map +1 -1
  163. package/dist/policy/CapabilityCheck.d.ts +5 -5
  164. package/dist/policy/PermissionRegistry.d.ts +11 -9
  165. package/dist/policy/PermissionRegistry.d.ts.map +1 -1
  166. package/dist/policy/PermissionRegistry.js +10 -8
  167. package/dist/policy/PermissionRegistry.js.map +1 -1
  168. package/dist/policy/ViewerContext.d.ts +13 -11
  169. package/dist/policy/ViewerContext.d.ts.map +1 -1
  170. package/dist/policy/checks.d.ts +9 -9
  171. package/dist/policy/checks.d.ts.map +1 -1
  172. package/dist/policy/checks.js +14 -11
  173. package/dist/policy/checks.js.map +1 -1
  174. package/dist/policy/defaultRegistry.d.ts +3 -4
  175. package/dist/policy/defaultRegistry.d.ts.map +1 -1
  176. package/dist/policy/defaultRegistry.js +3 -4
  177. package/dist/policy/defaultRegistry.js.map +1 -1
  178. package/dist/policy/index.d.ts +2 -2
  179. package/dist/policy/index.d.ts.map +1 -1
  180. package/dist/policy/index.js +1 -1
  181. package/dist/policy/index.js.map +1 -1
  182. package/dist/policy/resolveViewer.d.ts +9 -9
  183. package/dist/policy/resolveViewer.js +9 -9
  184. package/dist/routes/_shared.d.ts +93 -153
  185. package/dist/routes/_shared.d.ts.map +1 -1
  186. package/dist/routes/_shared.js +9 -5
  187. package/dist/routes/_shared.js.map +1 -1
  188. package/dist/routes/admin.d.ts +1 -1
  189. package/dist/routes/admin.d.ts.map +1 -1
  190. package/dist/routes/admin.js +13 -12
  191. package/dist/routes/admin.js.map +1 -1
  192. package/dist/routes/auth.d.ts +12 -10
  193. package/dist/routes/auth.d.ts.map +1 -1
  194. package/dist/routes/auth.js +32 -34
  195. package/dist/routes/auth.js.map +1 -1
  196. package/dist/routes/clarifications.d.ts +8 -0
  197. package/dist/routes/clarifications.d.ts.map +1 -0
  198. package/dist/routes/clarifications.js +246 -0
  199. package/dist/routes/clarifications.js.map +1 -0
  200. package/dist/routes/edges.d.ts.map +1 -1
  201. package/dist/routes/edges.js +2 -6
  202. package/dist/routes/edges.js.map +1 -1
  203. package/dist/routes/history.d.ts.map +1 -1
  204. package/dist/routes/history.js +12 -10
  205. package/dist/routes/history.js.map +1 -1
  206. package/dist/routes/nodes.d.ts.map +1 -1
  207. package/dist/routes/nodes.js +4 -8
  208. package/dist/routes/nodes.js.map +1 -1
  209. package/dist/routes/oauth.d.ts +6 -7
  210. package/dist/routes/oauth.d.ts.map +1 -1
  211. package/dist/routes/oauth.js +6 -7
  212. package/dist/routes/oauth.js.map +1 -1
  213. package/dist/routes/ontologies.d.ts +7 -0
  214. package/dist/routes/ontologies.d.ts.map +1 -0
  215. package/dist/routes/ontologies.js +29 -0
  216. package/dist/routes/ontologies.js.map +1 -0
  217. package/dist/routes/ontology.d.ts.map +1 -1
  218. package/dist/routes/ontology.js +2 -1
  219. package/dist/routes/ontology.js.map +1 -1
  220. package/dist/routes/proposals.d.ts +2 -2
  221. package/dist/routes/proposals.d.ts.map +1 -1
  222. package/dist/routes/proposals.js +35 -30
  223. package/dist/routes/proposals.js.map +1 -1
  224. package/dist/routes/reactorCycles.d.ts +7 -0
  225. package/dist/routes/reactorCycles.d.ts.map +1 -0
  226. package/dist/routes/reactorCycles.js +60 -0
  227. package/dist/routes/reactorCycles.js.map +1 -0
  228. package/dist/routes/runs.d.ts.map +1 -1
  229. package/dist/routes/runs.js +22 -19
  230. package/dist/routes/runs.js.map +1 -1
  231. package/dist/routes/skillInputOptions.d.ts +2 -2
  232. package/dist/routes/skillInputOptions.d.ts.map +1 -1
  233. package/dist/routes/skillInputOptions.js +53 -53
  234. package/dist/routes/skillInputOptions.js.map +1 -1
  235. package/dist/routes/skills.d.ts +19 -1
  236. package/dist/routes/skills.d.ts.map +1 -1
  237. package/dist/routes/skills.js +141 -7
  238. package/dist/routes/skills.js.map +1 -1
  239. package/dist/routes/sourceLoaders.d.ts.map +1 -1
  240. package/dist/routes/sourceLoaders.js +1 -0
  241. package/dist/routes/sourceLoaders.js.map +1 -1
  242. package/dist/routes/sourceUnitObservations.d.ts +20 -0
  243. package/dist/routes/sourceUnitObservations.d.ts.map +1 -0
  244. package/dist/routes/sourceUnitObservations.js +80 -0
  245. package/dist/routes/sourceUnitObservations.js.map +1 -0
  246. package/dist/routes/sourceWebhooks.d.ts +26 -0
  247. package/dist/routes/sourceWebhooks.d.ts.map +1 -0
  248. package/dist/routes/sourceWebhooks.js +301 -0
  249. package/dist/routes/sourceWebhooks.js.map +1 -0
  250. package/dist/routes/users.d.ts +0 -2
  251. package/dist/routes/users.d.ts.map +1 -1
  252. package/dist/routes/users.js +15 -33
  253. package/dist/routes/users.js.map +1 -1
  254. package/dist/routes/workspaceEvents.d.ts +5 -4
  255. package/dist/routes/workspaceEvents.d.ts.map +1 -1
  256. package/dist/routes/workspaceEvents.js +7 -6
  257. package/dist/routes/workspaceEvents.js.map +1 -1
  258. package/dist/routes/workspaceMembers.d.ts +1 -1
  259. package/dist/routes/workspaceMembers.d.ts.map +1 -1
  260. package/dist/routes/workspaceMembers.js +2 -2
  261. package/dist/routes/workspaceMembers.js.map +1 -1
  262. package/dist/routes/workspaces.d.ts +21 -10
  263. package/dist/routes/workspaces.d.ts.map +1 -1
  264. package/dist/routes/workspaces.js +95 -69
  265. package/dist/routes/workspaces.js.map +1 -1
  266. package/dist/server.js +6 -70
  267. package/dist/server.js.map +1 -1
  268. package/dist/serviceAccounts.d.ts +13 -0
  269. package/dist/serviceAccounts.d.ts.map +1 -0
  270. package/dist/serviceAccounts.js +26 -0
  271. package/dist/serviceAccounts.js.map +1 -0
  272. package/dist/startServer.d.ts +17 -0
  273. package/dist/startServer.d.ts.map +1 -0
  274. package/dist/startServer.js +81 -0
  275. package/dist/startServer.js.map +1 -0
  276. package/dist/startup.d.ts +28 -0
  277. package/dist/startup.d.ts.map +1 -0
  278. package/dist/startup.js +94 -0
  279. package/dist/startup.js.map +1 -0
  280. package/package.json +35 -40
  281. package/dist/composeFs.d.ts +0 -55
  282. package/dist/composeFs.d.ts.map +0 -1
  283. package/dist/composeFs.js.map +0 -1
  284. package/dist/composition.d.ts +0 -133
  285. package/dist/composition.d.ts.map +0 -1
  286. package/dist/composition.js +0 -113
  287. package/dist/composition.js.map +0 -1
  288. package/dist/infrastructure/agent/SubprocessSkillRunner.d.ts +0 -75
  289. package/dist/infrastructure/agent/SubprocessSkillRunner.d.ts.map +0 -1
  290. package/dist/infrastructure/agent/SubprocessSkillRunner.js.map +0 -1
  291. package/dist/infrastructure/agent/asyncQueue.d.ts +0 -22
  292. package/dist/infrastructure/agent/asyncQueue.d.ts.map +0 -1
  293. package/dist/infrastructure/agent/mcpConfig.d.ts +0 -38
  294. package/dist/infrastructure/agent/mcpConfig.d.ts.map +0 -1
  295. package/dist/infrastructure/agent/mcpConfig.js +0 -55
  296. package/dist/infrastructure/agent/mcpConfig.js.map +0 -1
  297. package/dist/infrastructure/agent/streamJsonParser.d.ts +0 -20
  298. package/dist/infrastructure/agent/streamJsonParser.d.ts.map +0 -1
  299. package/dist/infrastructure/agent/streamJsonParser.js.map +0 -1
  300. package/dist/infrastructure/agent/subprocessEventStream.d.ts +0 -26
  301. package/dist/infrastructure/agent/subprocessEventStream.d.ts.map +0 -1
  302. package/dist/infrastructure/agent/subprocessEventStream.js +0 -112
  303. package/dist/infrastructure/agent/subprocessEventStream.js.map +0 -1
  304. package/dist/infrastructure/auth/ensureApprovedEmails.d.ts +0 -16
  305. package/dist/infrastructure/auth/ensureApprovedEmails.d.ts.map +0 -1
  306. package/dist/infrastructure/auth/ensureApprovedEmails.js +0 -20
  307. package/dist/infrastructure/auth/ensureApprovedEmails.js.map +0 -1
  308. package/dist/infrastructure/env.d.ts +0 -11
  309. package/dist/infrastructure/env.d.ts.map +0 -1
  310. package/dist/infrastructure/env.js.map +0 -1
  311. package/dist/infrastructure/fs/FsBatchPlanRepository.d.ts +0 -300
  312. package/dist/infrastructure/fs/FsBatchPlanRepository.d.ts.map +0 -1
  313. package/dist/infrastructure/fs/FsBatchPlanRepository.js.map +0 -1
  314. package/dist/infrastructure/fs/FsClarifyTicketRepository.d.ts +0 -13
  315. package/dist/infrastructure/fs/FsClarifyTicketRepository.d.ts.map +0 -1
  316. package/dist/infrastructure/fs/FsClarifyTicketRepository.js +0 -39
  317. package/dist/infrastructure/fs/FsClarifyTicketRepository.js.map +0 -1
  318. package/dist/infrastructure/fs/FsDecisionRepository.d.ts +0 -13
  319. package/dist/infrastructure/fs/FsDecisionRepository.d.ts.map +0 -1
  320. package/dist/infrastructure/fs/FsDecisionRepository.js +0 -56
  321. package/dist/infrastructure/fs/FsDecisionRepository.js.map +0 -1
  322. package/dist/infrastructure/fs/FsGraphSerializer.d.ts +0 -629
  323. package/dist/infrastructure/fs/FsGraphSerializer.d.ts.map +0 -1
  324. package/dist/infrastructure/fs/FsGraphSerializer.js.map +0 -1
  325. package/dist/infrastructure/fs/FsProposalRepository.d.ts.map +0 -1
  326. package/dist/infrastructure/fs/FsProposalRepository.js.map +0 -1
  327. package/dist/infrastructure/fs/FsRunRepository.d.ts.map +0 -1
  328. package/dist/infrastructure/fs/FsRunRepository.js.map +0 -1
  329. package/dist/infrastructure/fs/FsSkillRegistry.d.ts.map +0 -1
  330. package/dist/infrastructure/fs/FsSkillRegistry.js.map +0 -1
  331. package/dist/infrastructure/fs/FsSourceUnitDigest.d.ts +0 -19
  332. package/dist/infrastructure/fs/FsSourceUnitDigest.d.ts.map +0 -1
  333. package/dist/infrastructure/fs/FsSourceUnitDigest.js.map +0 -1
  334. package/dist/infrastructure/fs/FsSourceUnitStateRepository.d.ts +0 -30
  335. package/dist/infrastructure/fs/FsSourceUnitStateRepository.d.ts.map +0 -1
  336. package/dist/infrastructure/fs/FsSourceUnitStateRepository.js.map +0 -1
  337. package/dist/infrastructure/fs/FsStatusedJsonRepository.d.ts +0 -35
  338. package/dist/infrastructure/fs/FsStatusedJsonRepository.d.ts.map +0 -1
  339. package/dist/infrastructure/fs/FsStatusedJsonRepository.js.map +0 -1
  340. package/dist/infrastructure/fs/FsWorkspaceRepository.d.ts.map +0 -1
  341. package/dist/infrastructure/fs/FsWorkspaceRepository.js.map +0 -1
  342. package/dist/infrastructure/fs/WorkspaceDiscovery.d.ts +0 -15
  343. package/dist/infrastructure/fs/WorkspaceDiscovery.d.ts.map +0 -1
  344. package/dist/infrastructure/fs/WorkspaceDiscovery.js.map +0 -1
  345. package/dist/infrastructure/fs/WorkspaceRegistryFile.d.ts.map +0 -1
  346. package/dist/infrastructure/fs/WorkspaceRegistryFile.js.map +0 -1
  347. package/dist/infrastructure/fs/frontmatter.d.ts +0 -13
  348. package/dist/infrastructure/fs/frontmatter.d.ts.map +0 -1
  349. package/dist/infrastructure/fs/frontmatter.js.map +0 -1
  350. package/dist/infrastructure/fs/intentScan.d.ts +0 -9
  351. package/dist/infrastructure/fs/intentScan.d.ts.map +0 -1
  352. package/dist/infrastructure/fs/intentScan.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.map +0 -1
  356. package/dist/infrastructure/fs/paths.js.map +0 -1
  357. package/dist/infrastructure/fs/productManifestWriter.d.ts +0 -22
  358. package/dist/infrastructure/fs/productManifestWriter.d.ts.map +0 -1
  359. package/dist/infrastructure/fs/productManifestWriter.js.map +0 -1
  360. package/dist/infrastructure/git/GitWorkspaceHistory.d.ts.map +0 -1
  361. package/dist/infrastructure/git/GitWorkspaceHistory.js.map +0 -1
  362. package/dist/infrastructure/git/commitMessage.d.ts.map +0 -1
  363. package/dist/infrastructure/git/commitMessage.js +0 -71
  364. package/dist/infrastructure/git/commitMessage.js.map +0 -1
  365. package/dist/infrastructure/orphanReaper.d.ts +0 -18
  366. package/dist/infrastructure/orphanReaper.d.ts.map +0 -1
  367. package/dist/infrastructure/orphanReaper.js.map +0 -1
  368. package/dist/infrastructure/users/ensureLocalUser.d.ts +0 -15
  369. package/dist/infrastructure/users/ensureLocalUser.d.ts.map +0 -1
  370. package/dist/infrastructure/users/ensureLocalUser.js +0 -38
  371. package/dist/infrastructure/users/ensureLocalUser.js.map +0 -1
  372. package/dist/middleware/requireAdmin.d.ts +0 -10
  373. package/dist/middleware/requireAdmin.d.ts.map +0 -1
  374. package/dist/middleware/requireAdmin.js +0 -24
  375. package/dist/middleware/requireAdmin.js.map +0 -1
  376. package/dist/middleware/userId.d.ts +0 -16
  377. package/dist/middleware/userId.d.ts.map +0 -1
  378. package/dist/middleware/userId.js +0 -27
  379. package/dist/middleware/userId.js.map +0 -1
  380. package/dist/policy/Capability.d.ts +0 -12
  381. package/dist/policy/Capability.d.ts.map +0 -1
  382. package/dist/policy/Capability.js +0 -31
  383. package/dist/policy/Capability.js.map +0 -1
  384. package/dist/routes/clarify.d.ts +0 -9
  385. package/dist/routes/clarify.d.ts.map +0 -1
  386. package/dist/routes/clarify.js +0 -274
  387. package/dist/routes/clarify.js.map +0 -1
  388. package/dist/routes/decisions.d.ts +0 -7
  389. package/dist/routes/decisions.d.ts.map +0 -1
  390. package/dist/routes/decisions.js +0 -68
  391. package/dist/routes/decisions.js.map +0 -1
  392. package/dist/routes/sourceUnitStates.d.ts +0 -7
  393. package/dist/routes/sourceUnitStates.d.ts.map +0 -1
  394. package/dist/routes/sourceUnitStates.js +0 -45
  395. package/dist/routes/sourceUnitStates.js.map +0 -1
  396. /package/dist/infrastructure/{fs → _shared}/jsonFileStore.d.ts +0 -0
  397. /package/dist/infrastructure/{fs → _shared}/jsonFileStore.js +0 -0
  398. /package/dist/infrastructure/{git → history}/GitWorkspaceHistory.d.ts +0 -0
  399. /package/dist/infrastructure/{git → history}/commitMessage.d.ts +0 -0
  400. /package/dist/infrastructure/{fs → hitl}/FsProposalRepository.d.ts +0 -0
  401. /package/dist/infrastructure/{fs → workspace}/FsWorkspaceRepository.d.ts +0 -0
@@ -3,9 +3,9 @@ import { join } from 'node:path';
3
3
  export const PROPOSAL_STATUSES = ['pending', 'applied', 'rejected'];
4
4
  export const CLARIFY_STATUSES = ['pending', 'answered', 'applied', 'skipped'];
5
5
  /**
6
- * Path-prefix containment check. Both inputs must be absolute. Handles
7
- * the `/foo/bar-evil` vs `/foo/bar/` aliasing gotcha by normalising the
8
- * parent with a trailing slash before `startsWith`.
6
+ * Path-prefix containment check. Both inputs must be absolute.
7
+ * Handles the `/foo/bar-evil` vs `/foo/bar/` aliasing gotcha,
8
+ * normalising the parent with a trailing slash before `startsWith`.
9
9
  */
10
10
  export function isUnder(candidate, parent) {
11
11
  const normalisedParent = parent.endsWith('/') ? parent : `${parent}/`;
@@ -25,33 +25,31 @@ export function workspaceArtifactsDir(workspaceRoot) {
25
25
  return join(workspaceRoot, 'artifacts');
26
26
  }
27
27
  export function graphJsonPath(workspaceRoot) {
28
- return join(workspaceArtifactsDir(workspaceRoot), 'graph.json');
28
+ return join(workspaceArtifactsDir(workspaceRoot), 'model.json');
29
29
  }
30
30
  export function batchPlanPath(workspaceRoot) {
31
31
  return join(workspaceArtifactsDir(workspaceRoot), 'batch-plan.json');
32
32
  }
33
- export function sourceUnitStateDir(workspaceRoot) {
33
+ export function sourceUnitObservationDir(workspaceRoot) {
34
34
  return join(workspaceArtifactsDir(workspaceRoot), 'source-unit-state');
35
35
  }
36
- export function sourceUnitStateFilePath(workspaceRoot, sourceId, relativePath) {
37
- // Drop trailing slash from folder units so file name doesn't end in
38
- // `/.json`. Replace path separators inside the unit name with `__`
39
- // so a multi-level folder unit still maps to one file.
36
+ export function sourceUnitObservationFilePath(workspaceRoot, sourceId, relativePath) {
37
+ // Drop the trailing slash from folder units,
38
+ // so the file name doesn't end in `/.json`.
39
+ // In the unit name,
40
+ // replace path separators with `__`, so a nested unit maps to one file.
40
41
  const trimmed = relativePath.endsWith('/') ? relativePath.slice(0, -1) : relativePath;
41
42
  const flattened = trimmed.replace(/\//g, '__');
42
- return join(sourceUnitStateDir(workspaceRoot), sourceId, `${flattened}.json`);
43
+ return join(sourceUnitObservationDir(workspaceRoot), sourceId, `${flattened}.json`);
43
44
  }
44
- export function sourceUnitStateSourceDir(workspaceRoot, sourceId) {
45
- return join(sourceUnitStateDir(workspaceRoot), sourceId);
45
+ export function sourceUnitObservationSourceDir(workspaceRoot, sourceId) {
46
+ return join(sourceUnitObservationDir(workspaceRoot), sourceId);
46
47
  }
47
48
  export function proposalsDir(workspaceRoot, status) {
48
49
  return join(workspaceArtifactsDir(workspaceRoot), 'proposals', status);
49
50
  }
50
- export function clarifyDir(workspaceRoot, status) {
51
- return join(workspaceArtifactsDir(workspaceRoot), 'clarify', status);
52
- }
53
- export function decisionsDir(workspaceRoot) {
54
- return join(workspaceArtifactsDir(workspaceRoot), 'decisions');
51
+ export function clarificationDir(workspaceRoot, status) {
52
+ return join(workspaceArtifactsDir(workspaceRoot), 'clarifications', status);
55
53
  }
56
54
  export function viewsDir(workspaceRoot, kind) {
57
55
  return join(workspaceArtifactsDir(workspaceRoot), 'views', kind);
@@ -59,6 +57,12 @@ export function viewsDir(workspaceRoot, kind) {
59
57
  export function runsDir(workspaceRoot) {
60
58
  return join(workspaceArtifactsDir(workspaceRoot), 'runs');
61
59
  }
60
+ export function reactorCyclesDir(workspaceRoot) {
61
+ return join(workspaceArtifactsDir(workspaceRoot), 'reactor-cycles');
62
+ }
63
+ export function reactorCycleFilePath(workspaceRoot, cycleId) {
64
+ return join(reactorCyclesDir(workspaceRoot), `${cycleId}.json`);
65
+ }
62
66
  export function runIndexPath(workspaceRoot) {
63
67
  return join(runsDir(workspaceRoot), 'index.jsonl');
64
68
  }
@@ -68,9 +72,12 @@ export function runEventsPath(workspaceRoot, runId) {
68
72
  export function runSessionsMetadataPath(workspaceRoot) {
69
73
  return join(runsDir(workspaceRoot), 'sessions.jsonl');
70
74
  }
71
- // claude stores conversation memory keyed by cwd, so resume must spawn from
72
- // the same dir as the first turn. Putting it inside the workspace (not /tmp)
73
- // keeps the path derivable from runId and lets it survive a server restart.
75
+ /**
76
+ * claude stores conversation memory keyed by cwd,
77
+ * so resume must spawn from the same dir as the first turn.
78
+ * Keeping it in the workspace, not /tmp, stays derivable from runId,
79
+ * and survives a server restart.
80
+ */
74
81
  export function sessionsDir(workspaceRoot) {
75
82
  return join(workspaceRoot, '.braid-sessions');
76
83
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/infrastructure/_shared/paths.ts"],"names":[],"mappings":"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"}
@@ -1,61 +1,36 @@
1
1
  import { z } from 'zod';
2
2
  declare const Invite: z.ZodObject<{
3
- email: z.ZodEffects<z.ZodString, string, string>;
3
+ email: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
4
4
  invitedAt: z.ZodString;
5
- /**
6
- * Initial server role to apply when the invite is redeemed. Defaults
7
- * to `user` so an admin who invites someone is making a deliberate
8
- * choice when they pick `admin`.
9
- */
10
- serverRole: z.ZodDefault<z.ZodEnum<["admin", "user"]>>;
11
- }, "strip", z.ZodTypeAny, {
12
- email: string;
13
- serverRole: "user" | "admin";
14
- invitedAt: string;
15
- }, {
16
- email: string;
17
- invitedAt: string;
18
- serverRole?: "user" | "admin" | undefined;
19
- }>;
5
+ serverRole: z.ZodDefault<z.ZodEnum<{
6
+ admin: "admin";
7
+ user: "user";
8
+ }>>;
9
+ }, z.core.$strip>;
20
10
  export type Invite = z.infer<typeof Invite>;
21
11
  export interface AccessDecision {
22
12
  readonly allow: boolean;
23
- /**
24
- * Human-readable reason. Surfaced to the user when access is denied
25
- * so they can self-diagnose ("not in allowlist", "no invite found").
26
- * Suppressed when `allow=true`.
27
- */
28
13
  readonly reason?: string;
29
- /**
30
- * For allowed access, whether this user's email matched an invite.
31
- * When true, the caller redeems the invite via `consumeInvite` after
32
- * creating the user record.
33
- */
34
14
  readonly viaInvite?: Invite;
35
15
  }
36
16
  export interface AccessPolicyConfig {
37
- /** Comma-separated list of allowed email domains (e.g. "kdanmobile.com,example.com"). */
38
17
  readonly allowedDomains?: readonly string[];
39
- /** Comma-separated allowlist of specific emails (per-user, not domain-based). */
40
18
  readonly allowedEmails?: readonly string[];
41
- /** Comma-separated list of admin email addresses. Matched users get serverRole='admin'. */
42
19
  readonly adminEmails?: readonly string[];
43
20
  }
44
21
  /**
45
- * Gate 1: decides whether a Google account is allowed to log in to this
46
- * Braid server. Composed of two layers:
22
+ * Gate 1 decides whether a Google account may log in to this Braid server.
23
+ * It composes two layers.
47
24
  *
48
- * 1. **Static allowlist**: `BRAID_ALLOWED_DOMAINS` / `BRAID_ALLOWED_EMAILS`
49
- * env vars. Domain matches (`@kdanmobile.com`) auto-pass, email
50
- * matches (`alice@example.com`) auto-pass. Free to leave both
51
- * unset on a public instance; combined with an empty invite list
52
- * this rejects everyone (fail closed).
25
+ * The static allowlist reads the `BRAID_ALLOWED_DOMAINS` and `BRAID_ALLOWED_EMAILS` env vars.
26
+ * Domain matches (`@kdanmobile.com`) and email matches (`alice@example.com`) auto-pass.
27
+ * Both may be left unset on a public instance,
28
+ * combined with an empty invite list this rejects everyone (fail closed).
53
29
  *
54
- * 2. **Invite list**: `${BRAID_HOME}/access.json` maintained by admin
55
- * via `/admin/invites` (Phase B/C admin UI). One invite per email;
56
- * consumed on first successful login.
30
+ * The invite list lives at `${BRAID_HOME}/access.json`, maintained by an admin via `/admin/invites`.
31
+ * One invite per email, consumed on first successful login.
57
32
  *
58
- * The policy is open for either path: domain pass OR invite present.
33
+ * The policy is open for either path, a domain pass OR an invite present.
59
34
  * That matches the "hybrid" Gate 1 the design picked.
60
35
  */
61
36
  export declare class AccessPolicy {
@@ -65,17 +40,16 @@ export declare class AccessPolicy {
65
40
  private readonly adminEmails;
66
41
  constructor(invitesPath: string, config?: AccessPolicyConfig);
67
42
  /**
68
- * Evaluate against the current allowlist + invite file. Reads the
69
- * invite file every call: invite mgmt is low-frequency and a stale
70
- * cache would create a frustrating race (admin invites Bob, Bob
71
- * logs in, server still says "no").
43
+ * Evaluate against the current allowlist and invite file.
44
+ * Reads the invite file every call, since invite management is low-frequency,
45
+ * and a stale cache would create a frustrating race,
46
+ * where an admin invites Bob, Bob logs in, and the server still says "no".
72
47
  */
73
48
  decide(email: string): Promise<AccessDecision>;
74
49
  /**
75
- * Whether the email should be marked `serverRole='admin'` on the
76
- * resulting user record. Independent of `decide`: invites carry
77
- * their own role override, and an admin email might also be the
78
- * allowlist path with no invite.
50
+ * Whether the email should be marked `serverRole='admin'` on the resulting user record.
51
+ * Independent of `decide`, since invites carry their own role override,
52
+ * and an admin email might take the allowlist path with no invite.
79
53
  */
80
54
  isAdmin(email: string): boolean;
81
55
  listInvites(): Promise<Invite[]>;
@@ -85,22 +59,23 @@ export declare class AccessPolicy {
85
59
  }): Promise<Invite>;
86
60
  removeInvite(email: string): Promise<void>;
87
61
  /**
88
- * Consume an invite once the user record exists: remove from invites,
89
- * add to approvedEmails so the user can sign in again without the
90
- * admin re-inviting them. Idempotent.
62
+ * Consume an invite once the user record exists.
63
+ * Remove it from invites,
64
+ * add to approvedEmails so the user can sign in again without the admin re-inviting them.
65
+ * Idempotent.
91
66
  */
92
67
  consumeInvite(email: string): Promise<void>;
93
68
  /**
94
- * Add an email to the persistent allowlist directly (without going
95
- * through the invite step). Used by the bootstrap migration that
96
- * back-fills approvedEmails for users who registered before this
97
- * field existed.
69
+ * Add an email to the persistent allowlist directly, without going through the invite step.
70
+ * Used by the bootstrap migration that back-fills approvedEmails,
71
+ * for users who registered before this field existed.
98
72
  */
99
73
  approveEmail(email: string): Promise<void>;
100
74
  /**
101
- * Drop an email from the persistent allowlist. Called when an admin
102
- * deletes a user so the underlying email can't sneak back in without
103
- * a fresh invite. Idempotent.
75
+ * Drop an email from the persistent allowlist.
76
+ * Called when an admin deletes a user,
77
+ * so the underlying email can't sneak back in without a fresh invite.
78
+ * Idempotent.
104
79
  */
105
80
  revokeApproval(email: string): Promise<void>;
106
81
  listApprovedEmails(): Promise<string[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"AccessPolicy.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/auth/AccessPolicy.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,QAAA,MAAM,MAAM;;;IAGV;;;;OAIG;;;;;;;;;;EAEH,CAAA;AACF,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAA;AAgB3C,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,yFAAyF;IACzF,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3C,iFAAiF;IACjF,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1C,2FAA2F;IAC3F,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACzC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,YAAY;IAMrB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAL9B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;gBAG9B,WAAW,EAAE,MAAM,EACpC,MAAM,GAAE,kBAAuB;IAOjC;;;;;OAKG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAsBpD;;;;;OAKG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIzB,WAAW,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIhC,SAAS,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAenF,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAShD;;;;OAIG;IACG,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYjD;;;;;OAKG;IACG,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWhD;;;;OAIG;IACG,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS5C,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YAI/B,WAAW;YAIX,WAAW;YAeX,YAAY;CAI3B"}
1
+ {"version":3,"file":"AccessPolicy.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/auth/AccessPolicy.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,QAAA,MAAM,MAAM;;;;;;;iBAMV,CAAA;AACF,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAA;AAc3C,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IAIvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IAGxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,kBAAkB;IAEjC,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAE3C,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAE1C,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACzC;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAY;IAMrB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAL9B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;gBAG9B,WAAW,EAAE,MAAM,EACpC,MAAM,GAAE,kBAAuB;IAOjC;;;;;OAKG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAsBpD;;;;OAIG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIzB,WAAW,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIhC,SAAS,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAenF,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAShD;;;;;OAKG;IACG,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYjD;;;;OAIG;IACG,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWhD;;;;;OAKG;IACG,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS5C,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YAI/B,WAAW;YAIX,WAAW;YAeX,YAAY;CAI3B"}
@@ -5,40 +5,33 @@ import { z } from 'zod';
5
5
  const Invite = z.object({
6
6
  email: z.string().email().transform(s => s.toLowerCase()),
7
7
  invitedAt: z.string().datetime({ offset: true }),
8
- /**
9
- * Initial server role to apply when the invite is redeemed. Defaults
10
- * to `user` so an admin who invites someone is making a deliberate
11
- * choice when they pick `admin`.
12
- */
8
+ // Initial server role applied when the invite is redeemed.
9
+ // Defaults to `user`, so an admin who picks `admin` is making a deliberate choice.
13
10
  serverRole: z.enum(['admin', 'user']).default('user'),
14
11
  });
15
12
  const Content = z.object({
16
13
  invites: z.array(Invite).default([]),
17
- /**
18
- * Emails that have already redeemed an invite (or been approved
19
- * directly) and are persistently allowed to sign in. Without this,
20
- * an invite would be a one-shot ticket: after the first login the
21
- * invite is gone and the user gets locked out on the second login.
22
- * Treat this as the "dynamic allowlist" that grows as invites get
23
- * consumed; revoking a user removes their entry here.
24
- */
14
+ // Emails that have already redeemed an invite (or been approved directly),
15
+ // and are persistently allowed to sign in.
16
+ // Without this, an invite would be a one-shot ticket,
17
+ // gone after the first login, locking the user out on the second.
18
+ // Treat this as the "dynamic allowlist" that grows as invites get consumed,
19
+ // revoking a user removes their entry here.
25
20
  approvedEmails: z.array(z.string().email().transform(s => s.toLowerCase())).default([]),
26
21
  });
27
22
  /**
28
- * Gate 1: decides whether a Google account is allowed to log in to this
29
- * Braid server. Composed of two layers:
23
+ * Gate 1 decides whether a Google account may log in to this Braid server.
24
+ * It composes two layers.
30
25
  *
31
- * 1. **Static allowlist**: `BRAID_ALLOWED_DOMAINS` / `BRAID_ALLOWED_EMAILS`
32
- * env vars. Domain matches (`@kdanmobile.com`) auto-pass, email
33
- * matches (`alice@example.com`) auto-pass. Free to leave both
34
- * unset on a public instance; combined with an empty invite list
35
- * this rejects everyone (fail closed).
26
+ * The static allowlist reads the `BRAID_ALLOWED_DOMAINS` and `BRAID_ALLOWED_EMAILS` env vars.
27
+ * Domain matches (`@kdanmobile.com`) and email matches (`alice@example.com`) auto-pass.
28
+ * Both may be left unset on a public instance,
29
+ * combined with an empty invite list this rejects everyone (fail closed).
36
30
  *
37
- * 2. **Invite list**: `${BRAID_HOME}/access.json` maintained by admin
38
- * via `/admin/invites` (Phase B/C admin UI). One invite per email;
39
- * consumed on first successful login.
31
+ * The invite list lives at `${BRAID_HOME}/access.json`, maintained by an admin via `/admin/invites`.
32
+ * One invite per email, consumed on first successful login.
40
33
  *
41
- * The policy is open for either path: domain pass OR invite present.
34
+ * The policy is open for either path, a domain pass OR an invite present.
42
35
  * That matches the "hybrid" Gate 1 the design picked.
43
36
  */
44
37
  export class AccessPolicy {
@@ -53,10 +46,10 @@ export class AccessPolicy {
53
46
  this.adminEmails = new Set((config.adminEmails ?? []).map(s => s.toLowerCase()));
54
47
  }
55
48
  /**
56
- * Evaluate against the current allowlist + invite file. Reads the
57
- * invite file every call: invite mgmt is low-frequency and a stale
58
- * cache would create a frustrating race (admin invites Bob, Bob
59
- * logs in, server still says "no").
49
+ * Evaluate against the current allowlist and invite file.
50
+ * Reads the invite file every call, since invite management is low-frequency,
51
+ * and a stale cache would create a frustrating race,
52
+ * where an admin invites Bob, Bob logs in, and the server still says "no".
60
53
  */
61
54
  async decide(email) {
62
55
  const lower = email.toLowerCase();
@@ -78,10 +71,9 @@ export class AccessPolicy {
78
71
  };
79
72
  }
80
73
  /**
81
- * Whether the email should be marked `serverRole='admin'` on the
82
- * resulting user record. Independent of `decide`: invites carry
83
- * their own role override, and an admin email might also be the
84
- * allowlist path with no invite.
74
+ * Whether the email should be marked `serverRole='admin'` on the resulting user record.
75
+ * Independent of `decide`, since invites carry their own role override,
76
+ * and an admin email might take the allowlist path with no invite.
85
77
  */
86
78
  isAdmin(email) {
87
79
  return this.adminEmails.has(email.toLowerCase());
@@ -112,9 +104,10 @@ export class AccessPolicy {
112
104
  await this.writeContent({ ...content, invites: filtered });
113
105
  }
114
106
  /**
115
- * Consume an invite once the user record exists: remove from invites,
116
- * add to approvedEmails so the user can sign in again without the
117
- * admin re-inviting them. Idempotent.
107
+ * Consume an invite once the user record exists.
108
+ * Remove it from invites,
109
+ * add to approvedEmails so the user can sign in again without the admin re-inviting them.
110
+ * Idempotent.
118
111
  */
119
112
  async consumeInvite(email) {
120
113
  const lower = email.toLowerCase();
@@ -128,10 +121,9 @@ export class AccessPolicy {
128
121
  await this.writeContent({ invites, approvedEmails });
129
122
  }
130
123
  /**
131
- * Add an email to the persistent allowlist directly (without going
132
- * through the invite step). Used by the bootstrap migration that
133
- * back-fills approvedEmails for users who registered before this
134
- * field existed.
124
+ * Add an email to the persistent allowlist directly, without going through the invite step.
125
+ * Used by the bootstrap migration that back-fills approvedEmails,
126
+ * for users who registered before this field existed.
135
127
  */
136
128
  async approveEmail(email) {
137
129
  const lower = email.toLowerCase();
@@ -144,9 +136,10 @@ export class AccessPolicy {
144
136
  });
145
137
  }
146
138
  /**
147
- * Drop an email from the persistent allowlist. Called when an admin
148
- * deletes a user so the underlying email can't sneak back in without
149
- * a fresh invite. Idempotent.
139
+ * Drop an email from the persistent allowlist.
140
+ * Called when an admin deletes a user,
141
+ * so the underlying email can't sneak back in without a fresh invite.
142
+ * Idempotent.
150
143
  */
151
144
  async revokeApproval(email) {
152
145
  const lower = email.toLowerCase();
@@ -1 +1 @@
1
- {"version":3,"file":"AccessPolicy.js","sourceRoot":"","sources":["../../../src/infrastructure/auth/AccessPolicy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AccessPolicy.js","sourceRoot":"","sources":["../../../src/infrastructure/auth/AccessPolicy.ts"],"names":[],"mappings":"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"}
@@ -8,28 +8,38 @@ export interface ResolvedSession {
8
8
  readonly userId: UserId;
9
9
  readonly expiresAt?: string;
10
10
  }
11
+ /**
12
+ * The port. A hosted deployment swaps the file-backed impl for a shared store,
13
+ * such as Redis or Postgres, behind this interface.
14
+ */
15
+ export interface SessionStore {
16
+ issue: (userId: UserId, options?: {
17
+ ttlSeconds?: number;
18
+ }) => Promise<IssuedSession>;
19
+ resolve: (token: string) => Promise<ResolvedSession | null>;
20
+ revoke: (token: string) => Promise<void>;
21
+ revokeAllForUser: (userId: UserId) => Promise<void>;
22
+ }
11
23
  /**
12
24
  * Hashed session tokens persisted to `${BRAID_HOME}/sessions.json`.
25
+ * Token format is 32 random bytes encoded as `base64url` (43 chars).
26
+ * The plain text is returned once at issuance time, the server stores SHA-256 of it.
27
+ * A leaked sessions.json therefore cannot be replayed as a Bearer header.
13
28
  *
14
- * Token format: 32 random bytes encoded as `base64url` (43 chars). The
15
- * plain text is returned exactly once at issuance time; the server
16
- * stores SHA-256 of it. A leaked sessions.json therefore cannot be
17
- * replayed as a Bearer header.
18
- *
19
- * No rotation, no rolling expiry, no per-device tracking: this is the
20
- * minimum useful surface for v0.2. Phase D / future remote-server work
21
- * can revisit if needed.
29
+ * No rotation, no rolling expiry, no per-device tracking,
30
+ * this is the minimum useful surface for v0.2.
31
+ * Future remote-server work can revisit if needed.
22
32
  */
23
- export declare class SessionStore {
33
+ export declare class FsSessionStore implements SessionStore {
24
34
  private readonly filePath;
25
35
  constructor(filePath: string);
26
36
  issue(userId: UserId, options?: {
27
37
  ttlSeconds?: number;
28
38
  }): Promise<IssuedSession>;
29
39
  /**
30
- * Resolve a Bearer token to its session. Updates `lastUsedAt` as a
31
- * side effect; not strictly required for correctness but useful for
32
- * the future "active sessions" admin view.
40
+ * Resolve a Bearer token to its session.
41
+ * Updates `lastUsedAt` as a side effect,
42
+ * not required for correctness but useful for the future "active sessions" admin view.
33
43
  */
34
44
  resolve(token: string): Promise<ResolvedSession | null>;
35
45
  revoke(token: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"SessionStore.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/auth/SessionStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AA4B7C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM;IAEvC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,aAAa,CAAC;IAa1F;;;;OAIG;IACG,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAevD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASpC,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAQvC,IAAI;YAeJ,KAAK;CAIpB"}
1
+ {"version":3,"file":"SessionStore.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/auth/SessionStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AA2B7C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,aAAa,CAAC,CAAA;IACpF,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAA;IAC3D,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACxC,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACpD;AAED;;;;;;;;;GASG;AACH,qBAAa,cAAe,YAAW,YAAY;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM;IAEvC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,aAAa,CAAC;IAgB1F;;;;OAIG;IACG,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAevD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASpC,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAQvC,IAAI;YAeJ,KAAK;CAIpB"}
@@ -4,12 +4,11 @@ import { dirname } from 'node:path';
4
4
  import { ValidationError } from '@braidhq/core';
5
5
  import { z } from 'zod';
6
6
  const SessionRow = z.object({
7
- /**
8
- * SHA-256 hex of the actual token. The plaintext is shown to the
9
- * client exactly once at issuance time; the server only ever sees
10
- * the hash thereafter. Constant-time compare is unnecessary for a
11
- * pre-image lookup on hex strings, which is what `findByToken` does.
12
- */
7
+ // SHA-256 hex of the actual token.
8
+ // The plaintext is shown to the client once at issuance time,
9
+ // the server only ever sees the hash thereafter.
10
+ // Constant-time compare is unnecessary for a pre-image lookup on hex strings,
11
+ // which is what `findByToken` does.
13
12
  tokenHash: z.string().length(64),
14
13
  userId: z.string().min(1),
15
14
  createdAt: z.string().datetime({ offset: true }),
@@ -21,17 +20,15 @@ const StoreContent = z.object({
21
20
  });
22
21
  /**
23
22
  * Hashed session tokens persisted to `${BRAID_HOME}/sessions.json`.
23
+ * Token format is 32 random bytes encoded as `base64url` (43 chars).
24
+ * The plain text is returned once at issuance time, the server stores SHA-256 of it.
25
+ * A leaked sessions.json therefore cannot be replayed as a Bearer header.
24
26
  *
25
- * Token format: 32 random bytes encoded as `base64url` (43 chars). The
26
- * plain text is returned exactly once at issuance time; the server
27
- * stores SHA-256 of it. A leaked sessions.json therefore cannot be
28
- * replayed as a Bearer header.
29
- *
30
- * No rotation, no rolling expiry, no per-device tracking: this is the
31
- * minimum useful surface for v0.2. Phase D / future remote-server work
32
- * can revisit if needed.
27
+ * No rotation, no rolling expiry, no per-device tracking,
28
+ * this is the minimum useful surface for v0.2.
29
+ * Future remote-server work can revisit if needed.
33
30
  */
34
- export class SessionStore {
31
+ export class FsSessionStore {
35
32
  filePath;
36
33
  constructor(filePath) {
37
34
  this.filePath = filePath;
@@ -40,18 +37,21 @@ export class SessionStore {
40
37
  const content = await this.read();
41
38
  const token = randomBytes(32).toString('base64url');
42
39
  const tokenHash = sha256Hex(token);
43
- const createdAt = new Date().toISOString();
40
+ const now = Date.now();
41
+ const createdAt = new Date(now).toISOString();
44
42
  const expiresAt = options.ttlSeconds
45
- ? new Date(Date.now() + options.ttlSeconds * 1000).toISOString()
43
+ ? new Date(now + options.ttlSeconds * 1000).toISOString()
46
44
  : undefined;
45
+ // Drop already-expired rows so short-lived service tokens do not accumulate.
46
+ content.sessions = content.sessions.filter(s => !s.expiresAt || Date.parse(s.expiresAt) >= now);
47
47
  content.sessions.push({ tokenHash, userId, createdAt, ...(expiresAt ? { expiresAt } : {}) });
48
48
  await this.write(content);
49
49
  return { token, userId, ...(expiresAt ? { expiresAt } : {}) };
50
50
  }
51
51
  /**
52
- * Resolve a Bearer token to its session. Updates `lastUsedAt` as a
53
- * side effect; not strictly required for correctness but useful for
54
- * the future "active sessions" admin view.
52
+ * Resolve a Bearer token to its session.
53
+ * Updates `lastUsedAt` as a side effect,
54
+ * not required for correctness but useful for the future "active sessions" admin view.
55
55
  */
56
56
  async resolve(token) {
57
57
  if (!token || token.length === 0)
@@ -1 +1 @@
1
- {"version":3,"file":"SessionStore.js","sourceRoot":"","sources":["../../../src/infrastructure/auth/SessionStore.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;IAChC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAChD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC3D,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC7D,CAAC,CAAA;AAIF,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC1C,CAAC,CAAA;AAcF;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,YAAY;IACM;IAA7B,YAA6B,QAAgB;QAAhB,aAAQ,GAAR,QAAQ,CAAQ;IAAG,CAAC;IAEjD,KAAK,CAAC,KAAK,CAAC,MAAc,EAAE,UAAmC,EAAE;QAC/D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;QACjC,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;QACnD,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;QAClC,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QAC1C,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU;YAClC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE;YAChE,CAAC,CAAC,SAAS,CAAA;QACb,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;QAC5F,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACzB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAA;IAC/D,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,KAAa;QACzB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAC9B,OAAO,IAAI,CAAA;QACb,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;QAClC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;QACjC,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAA;QACjE,IAAI,CAAC,GAAG;YACN,OAAO,IAAI,CAAA;QACb,IAAI,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE;YACzD,OAAO,IAAI,CAAA;QACb,GAAG,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QACzC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACzB,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAgB,EAAE,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAA;IACjG,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa;QACxB,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;QAClC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;QACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAA;QACxE,IAAI,QAAQ,CAAC,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,MAAM;YAC7C,OAAM;QACR,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAA;IAC1C,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,MAAc;QACnC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;QACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAA;QAClE,IAAI,QAAQ,CAAC,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,MAAM;YAC7C,OAAM;QACR,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAA;IAC1C,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YAClD,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;YACtD,IAAI,CAAC,MAAM,CAAC,OAAO;gBACjB,MAAM,IAAI,eAAe,CAAC,6BAA6B,IAAI,CAAC,QAAQ,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;YACnG,OAAO,MAAM,CAAC,IAAI,CAAA;QACpB,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACb,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;gBACpD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAA;YACzB,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,KAAK,CAAC,OAAqB;QACvC,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACxD,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAClF,CAAC;CACF;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AACzD,CAAC"}
1
+ {"version":3,"file":"SessionStore.js","sourceRoot":"","sources":["../../../src/infrastructure/auth/SessionStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { BatchPlanRepository, Workspace } from '@braidhq/core';
2
+ import { BatchPlan } from '@braidhq/core';
3
+ import { z } from 'zod';
4
+ export declare const BATCH_PLAN_VERSION = 2;
5
+ export declare const BatchPlanFile: z.ZodObject<{
6
+ version: z.ZodNumber;
7
+ plan: z.ZodUnknown;
8
+ }, z.core.$strip>;
9
+ export declare class FsBatchPlanRepository implements BatchPlanRepository {
10
+ load(workspace: Workspace): Promise<BatchPlan | null>;
11
+ save(workspace: Workspace, plan: BatchPlan): Promise<void>;
12
+ clear(workspace: Workspace): Promise<void>;
13
+ }
14
+ //# sourceMappingURL=FsBatchPlanRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FsBatchPlanRepository.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/batch/FsBatchPlanRepository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAGnE,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAEzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,kBAAkB,IAAI,CAAA;AAGnC,eAAO,MAAM,aAAa;;;iBAGxB,CAAA;AAEF,qBAAa,qBAAsB,YAAW,mBAAmB;IACzD,IAAI,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAmBrD,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAU1D,KAAK,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CAGjD"}
@@ -3,11 +3,13 @@ import process from 'node:process';
3
3
  import { BatchPlan } from '@braidhq/core';
4
4
  import { BatchPlan as BatchPlanData } from '@braidhq/schema';
5
5
  import { z } from 'zod';
6
- import { batchPlanPath, workspaceArtifactsDir } from './paths.js';
7
- export const BATCH_PLAN_VERSION = 1;
6
+ import { batchPlanPath, workspaceArtifactsDir } from '../_shared/paths.js';
7
+ // On-disk envelope version. Bumped only when the plan payload shape changes.
8
+ export const BATCH_PLAN_VERSION = 2;
9
+ // Envelope only. The plan itself is validated by its schema below.
8
10
  export const BatchPlanFile = z.object({
9
11
  version: z.number().int(),
10
- plan: BatchPlanData,
12
+ plan: z.unknown(),
11
13
  });
12
14
  export class FsBatchPlanRepository {
13
15
  async load(workspace) {
@@ -20,11 +22,11 @@ export class FsBatchPlanRepository {
20
22
  return null;
21
23
  throw error;
22
24
  }
23
- const parsed = BatchPlanFile.parse(JSON.parse(raw));
24
- if (parsed.version !== BATCH_PLAN_VERSION) {
25
- throw new Error(`batch-plan.json version mismatch in ${workspace.rootPath}: expected ${BATCH_PLAN_VERSION}, got ${parsed.version}`);
25
+ const file = BatchPlanFile.parse(JSON.parse(raw));
26
+ if (file.version > BATCH_PLAN_VERSION) {
27
+ throw new Error(`batch-plan.json in ${workspace.rootPath} is version ${file.version}, newer than supported ${BATCH_PLAN_VERSION}`);
26
28
  }
27
- return new BatchPlan(parsed.plan);
29
+ return new BatchPlan(BatchPlanData.parse(file.plan));
28
30
  }
29
31
  async save(workspace, plan) {
30
32
  const path = batchPlanPath(workspace.rootPath);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FsBatchPlanRepository.js","sourceRoot":"","sources":["../../../src/infrastructure/batch/FsBatchPlanRepository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACzE,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACzC,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC5D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAE1E,6EAA6E;AAC7E,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAA;AAEnC,mEAAmE;AACnE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACzB,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE;CAClB,CAAC,CAAA;AAEF,MAAM,OAAO,qBAAqB;IAChC,KAAK,CAAC,IAAI,CAAC,SAAoB;QAC7B,IAAI,GAAW,CAAA;QACf,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAA;QAClE,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACb,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;gBACpD,OAAO,IAAI,CAAA;YACb,MAAM,KAAK,CAAA;QACb,CAAC;QACD,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;QACjD,IAAI,IAAI,CAAC,OAAO,GAAG,kBAAkB,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CACb,sBAAsB,SAAS,CAAC,QAAQ,eAAe,IAAI,CAAC,OAAO,0BAA0B,kBAAkB,EAAE,CAClH,CAAA;QACH,CAAC;QACD,OAAO,IAAI,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IACtD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAoB,EAAE,IAAe;QAC9C,MAAM,IAAI,GAAG,aAAa,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;QAC9C,MAAM,KAAK,CAAC,qBAAqB,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAC3E,MAAM,OAAO,GAAG,EAAE,OAAO,EAAE,kBAAkB,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAA;QACpE,oEAAoE;QACpE,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,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QACtE,MAAM,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACzB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,SAAoB;QAC9B,MAAM,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IAC9D,CAAC;CACF"}