@braidhq/server 0.0.1 → 0.1.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 (258) hide show
  1. package/README.md +136 -0
  2. package/dist/app.d.ts +19 -2
  3. package/dist/app.d.ts.map +1 -1
  4. package/dist/app.js +121 -3
  5. package/dist/app.js.map +1 -1
  6. package/dist/composeFs.d.ts +41 -6
  7. package/dist/composeFs.d.ts.map +1 -1
  8. package/dist/composeFs.js +234 -52
  9. package/dist/composeFs.js.map +1 -1
  10. package/dist/composition.d.ts +86 -2
  11. package/dist/composition.d.ts.map +1 -1
  12. package/dist/composition.js +71 -1
  13. package/dist/composition.js.map +1 -1
  14. package/dist/infrastructure/agent/SubprocessSkillRunner.d.ts +21 -0
  15. package/dist/infrastructure/agent/SubprocessSkillRunner.d.ts.map +1 -1
  16. package/dist/infrastructure/agent/SubprocessSkillRunner.js +35 -3
  17. package/dist/infrastructure/agent/SubprocessSkillRunner.js.map +1 -1
  18. package/dist/infrastructure/agent/mcpConfig.d.ts +25 -5
  19. package/dist/infrastructure/agent/mcpConfig.d.ts.map +1 -1
  20. package/dist/infrastructure/agent/mcpConfig.js +22 -14
  21. package/dist/infrastructure/agent/mcpConfig.js.map +1 -1
  22. package/dist/infrastructure/auth/AccessPolicy.d.ts +112 -0
  23. package/dist/infrastructure/auth/AccessPolicy.d.ts.map +1 -0
  24. package/dist/infrastructure/auth/AccessPolicy.js +184 -0
  25. package/dist/infrastructure/auth/AccessPolicy.js.map +1 -0
  26. package/dist/infrastructure/auth/SessionStore.d.ts +40 -0
  27. package/dist/infrastructure/auth/SessionStore.d.ts.map +1 -0
  28. package/dist/infrastructure/auth/SessionStore.js +107 -0
  29. package/dist/infrastructure/auth/SessionStore.js.map +1 -0
  30. package/dist/infrastructure/auth/ensureApprovedEmails.d.ts +16 -0
  31. package/dist/infrastructure/auth/ensureApprovedEmails.d.ts.map +1 -0
  32. package/dist/infrastructure/auth/ensureApprovedEmails.js +20 -0
  33. package/dist/infrastructure/auth/ensureApprovedEmails.js.map +1 -0
  34. package/dist/infrastructure/env.d.ts +11 -0
  35. package/dist/infrastructure/env.d.ts.map +1 -0
  36. package/dist/infrastructure/env.js +20 -0
  37. package/dist/infrastructure/env.js.map +1 -0
  38. package/dist/infrastructure/fs/FsBatchPlanRepository.d.ts +300 -0
  39. package/dist/infrastructure/fs/FsBatchPlanRepository.d.ts.map +1 -0
  40. package/dist/infrastructure/fs/FsBatchPlanRepository.js +42 -0
  41. package/dist/infrastructure/fs/FsBatchPlanRepository.js.map +1 -0
  42. package/dist/infrastructure/fs/FsClarifyTicketRepository.d.ts.map +1 -1
  43. package/dist/infrastructure/fs/FsClarifyTicketRepository.js +7 -1
  44. package/dist/infrastructure/fs/FsClarifyTicketRepository.js.map +1 -1
  45. package/dist/infrastructure/fs/FsGraphSerializer.d.ts +629 -0
  46. package/dist/infrastructure/fs/FsGraphSerializer.d.ts.map +1 -0
  47. package/dist/infrastructure/fs/FsGraphSerializer.js +60 -0
  48. package/dist/infrastructure/fs/FsGraphSerializer.js.map +1 -0
  49. package/dist/infrastructure/fs/FsProposalRepository.d.ts.map +1 -1
  50. package/dist/infrastructure/fs/FsProposalRepository.js +8 -0
  51. package/dist/infrastructure/fs/FsProposalRepository.js.map +1 -1
  52. package/dist/infrastructure/fs/FsRunRepository.d.ts +4 -1
  53. package/dist/infrastructure/fs/FsRunRepository.d.ts.map +1 -1
  54. package/dist/infrastructure/fs/FsRunRepository.js +75 -3
  55. package/dist/infrastructure/fs/FsRunRepository.js.map +1 -1
  56. package/dist/infrastructure/fs/FsSkillRegistry.d.ts.map +1 -1
  57. package/dist/infrastructure/fs/FsSkillRegistry.js +15 -3
  58. package/dist/infrastructure/fs/FsSkillRegistry.js.map +1 -1
  59. package/dist/infrastructure/fs/FsSourceUnitDigest.d.ts +19 -0
  60. package/dist/infrastructure/fs/FsSourceUnitDigest.d.ts.map +1 -0
  61. package/dist/infrastructure/fs/FsSourceUnitDigest.js +58 -0
  62. package/dist/infrastructure/fs/FsSourceUnitDigest.js.map +1 -0
  63. package/dist/infrastructure/fs/FsSourceUnitStateRepository.d.ts +30 -0
  64. package/dist/infrastructure/fs/FsSourceUnitStateRepository.d.ts.map +1 -0
  65. package/dist/infrastructure/fs/FsSourceUnitStateRepository.js +87 -0
  66. package/dist/infrastructure/fs/FsSourceUnitStateRepository.js.map +1 -0
  67. package/dist/infrastructure/fs/FsWorkspaceRepository.d.ts.map +1 -1
  68. package/dist/infrastructure/fs/FsWorkspaceRepository.js +12 -3
  69. package/dist/infrastructure/fs/FsWorkspaceRepository.js.map +1 -1
  70. package/dist/infrastructure/fs/WorkspaceDiscovery.d.ts +15 -0
  71. package/dist/infrastructure/fs/WorkspaceDiscovery.d.ts.map +1 -0
  72. package/dist/infrastructure/fs/WorkspaceDiscovery.js +46 -0
  73. package/dist/infrastructure/fs/WorkspaceDiscovery.js.map +1 -0
  74. package/dist/infrastructure/fs/WorkspaceRegistryFile.d.ts +26 -2
  75. package/dist/infrastructure/fs/WorkspaceRegistryFile.d.ts.map +1 -1
  76. package/dist/infrastructure/fs/WorkspaceRegistryFile.js +109 -5
  77. package/dist/infrastructure/fs/WorkspaceRegistryFile.js.map +1 -1
  78. package/dist/infrastructure/fs/intentScan.d.ts +9 -0
  79. package/dist/infrastructure/fs/intentScan.d.ts.map +1 -0
  80. package/dist/infrastructure/fs/intentScan.js +135 -0
  81. package/dist/infrastructure/fs/intentScan.js.map +1 -0
  82. package/dist/infrastructure/fs/paths.d.ts +14 -0
  83. package/dist/infrastructure/fs/paths.d.ts.map +1 -1
  84. package/dist/infrastructure/fs/paths.js +43 -0
  85. package/dist/infrastructure/fs/paths.js.map +1 -1
  86. package/dist/infrastructure/fs/productManifestWriter.d.ts +1 -1
  87. package/dist/infrastructure/fs/productManifestWriter.d.ts.map +1 -1
  88. package/dist/infrastructure/fs/productManifestWriter.js +1 -3
  89. package/dist/infrastructure/fs/productManifestWriter.js.map +1 -1
  90. package/dist/infrastructure/git/GitWorkspaceHistory.d.ts +18 -0
  91. package/dist/infrastructure/git/GitWorkspaceHistory.d.ts.map +1 -0
  92. package/dist/infrastructure/git/GitWorkspaceHistory.js +303 -0
  93. package/dist/infrastructure/git/GitWorkspaceHistory.js.map +1 -0
  94. package/dist/infrastructure/git/commitMessage.d.ts +4 -0
  95. package/dist/infrastructure/git/commitMessage.d.ts.map +1 -0
  96. package/dist/infrastructure/git/commitMessage.js +71 -0
  97. package/dist/infrastructure/git/commitMessage.js.map +1 -0
  98. package/dist/infrastructure/oauth/GoogleOAuth.d.ts +48 -1
  99. package/dist/infrastructure/oauth/GoogleOAuth.d.ts.map +1 -1
  100. package/dist/infrastructure/oauth/GoogleOAuth.js +68 -0
  101. package/dist/infrastructure/oauth/GoogleOAuth.js.map +1 -1
  102. package/dist/infrastructure/users/UserDirectoryFromRegistry.d.ts +14 -0
  103. package/dist/infrastructure/users/UserDirectoryFromRegistry.d.ts.map +1 -0
  104. package/dist/infrastructure/users/UserDirectoryFromRegistry.js +21 -0
  105. package/dist/infrastructure/users/UserDirectoryFromRegistry.js.map +1 -0
  106. package/dist/infrastructure/users/UserRegistryFile.d.ts +23 -0
  107. package/dist/infrastructure/users/UserRegistryFile.d.ts.map +1 -0
  108. package/dist/infrastructure/users/UserRegistryFile.js +91 -0
  109. package/dist/infrastructure/users/UserRegistryFile.js.map +1 -0
  110. package/dist/infrastructure/users/ensureLocalUser.d.ts +15 -0
  111. package/dist/infrastructure/users/ensureLocalUser.d.ts.map +1 -0
  112. package/dist/infrastructure/users/ensureLocalUser.js +38 -0
  113. package/dist/infrastructure/users/ensureLocalUser.js.map +1 -0
  114. package/dist/infrastructure/users/ensureWorkspaceOwners.d.ts +9 -0
  115. package/dist/infrastructure/users/ensureWorkspaceOwners.d.ts.map +1 -0
  116. package/dist/infrastructure/users/ensureWorkspaceOwners.js +22 -0
  117. package/dist/infrastructure/users/ensureWorkspaceOwners.js.map +1 -0
  118. package/dist/middleware/auth.d.ts +29 -0
  119. package/dist/middleware/auth.d.ts.map +1 -0
  120. package/dist/middleware/auth.js +81 -0
  121. package/dist/middleware/auth.js.map +1 -0
  122. package/dist/middleware/cors.js +1 -1
  123. package/dist/middleware/cors.js.map +1 -1
  124. package/dist/middleware/requireAdmin.d.ts +10 -0
  125. package/dist/middleware/requireAdmin.d.ts.map +1 -0
  126. package/dist/middleware/requireAdmin.js +24 -0
  127. package/dist/middleware/requireAdmin.js.map +1 -0
  128. package/dist/middleware/userId.d.ts +16 -0
  129. package/dist/middleware/userId.d.ts.map +1 -0
  130. package/dist/middleware/userId.js +27 -0
  131. package/dist/middleware/userId.js.map +1 -0
  132. package/dist/middleware/workspaceAccess.d.ts +47 -0
  133. package/dist/middleware/workspaceAccess.d.ts.map +1 -0
  134. package/dist/middleware/workspaceAccess.js +86 -0
  135. package/dist/middleware/workspaceAccess.js.map +1 -0
  136. package/dist/policy/Capability.d.ts +12 -0
  137. package/dist/policy/Capability.d.ts.map +1 -0
  138. package/dist/policy/Capability.js +31 -0
  139. package/dist/policy/Capability.js.map +1 -0
  140. package/dist/policy/CapabilityCheck.d.ts +14 -0
  141. package/dist/policy/CapabilityCheck.d.ts.map +1 -0
  142. package/dist/policy/CapabilityCheck.js +2 -0
  143. package/dist/policy/CapabilityCheck.js.map +1 -0
  144. package/dist/policy/PermissionRegistry.d.ts +23 -0
  145. package/dist/policy/PermissionRegistry.d.ts.map +1 -0
  146. package/dist/policy/PermissionRegistry.js +27 -0
  147. package/dist/policy/PermissionRegistry.js.map +1 -0
  148. package/dist/policy/ViewerContext.d.ts +27 -0
  149. package/dist/policy/ViewerContext.d.ts.map +1 -0
  150. package/dist/policy/ViewerContext.js +2 -0
  151. package/dist/policy/ViewerContext.js.map +1 -0
  152. package/dist/policy/checks.d.ts +15 -0
  153. package/dist/policy/checks.d.ts.map +1 -0
  154. package/dist/policy/checks.js +52 -0
  155. package/dist/policy/checks.js.map +1 -0
  156. package/dist/policy/defaultRegistry.d.ts +10 -0
  157. package/dist/policy/defaultRegistry.d.ts.map +1 -0
  158. package/dist/policy/defaultRegistry.js +16 -0
  159. package/dist/policy/defaultRegistry.js.map +1 -0
  160. package/dist/policy/index.d.ts +8 -0
  161. package/dist/policy/index.d.ts.map +1 -0
  162. package/dist/policy/index.js +5 -0
  163. package/dist/policy/index.js.map +1 -0
  164. package/dist/policy/resolveViewer.d.ts +16 -0
  165. package/dist/policy/resolveViewer.d.ts.map +1 -0
  166. package/dist/policy/resolveViewer.js +37 -0
  167. package/dist/policy/resolveViewer.js.map +1 -0
  168. package/dist/routes/_shared.d.ts +198 -0
  169. package/dist/routes/_shared.d.ts.map +1 -0
  170. package/dist/routes/_shared.js +29 -0
  171. package/dist/routes/_shared.js.map +1 -0
  172. package/dist/routes/admin.d.ts +13 -0
  173. package/dist/routes/admin.d.ts.map +1 -0
  174. package/dist/routes/admin.js +227 -0
  175. package/dist/routes/admin.js.map +1 -0
  176. package/dist/routes/auth.d.ts +33 -0
  177. package/dist/routes/auth.d.ts.map +1 -0
  178. package/dist/routes/auth.js +170 -0
  179. package/dist/routes/auth.js.map +1 -0
  180. package/dist/routes/batch.d.ts +7 -0
  181. package/dist/routes/batch.d.ts.map +1 -0
  182. package/dist/routes/batch.js +47 -0
  183. package/dist/routes/batch.js.map +1 -0
  184. package/dist/routes/clarify.d.ts +4 -3
  185. package/dist/routes/clarify.d.ts.map +1 -1
  186. package/dist/routes/clarify.js +247 -57
  187. package/dist/routes/clarify.js.map +1 -1
  188. package/dist/routes/decisions.d.ts +2 -2
  189. package/dist/routes/decisions.d.ts.map +1 -1
  190. package/dist/routes/decisions.js +50 -12
  191. package/dist/routes/decisions.js.map +1 -1
  192. package/dist/routes/edges.d.ts +2 -2
  193. package/dist/routes/edges.d.ts.map +1 -1
  194. package/dist/routes/edges.js +35 -13
  195. package/dist/routes/edges.js.map +1 -1
  196. package/dist/routes/health.d.ts +2 -2
  197. package/dist/routes/health.d.ts.map +1 -1
  198. package/dist/routes/health.js +21 -3
  199. package/dist/routes/health.js.map +1 -1
  200. package/dist/routes/history.d.ts +7 -0
  201. package/dist/routes/history.d.ts.map +1 -0
  202. package/dist/routes/history.js +88 -0
  203. package/dist/routes/history.js.map +1 -0
  204. package/dist/routes/model.d.ts +2 -2
  205. package/dist/routes/model.d.ts.map +1 -1
  206. package/dist/routes/model.js +20 -4
  207. package/dist/routes/model.js.map +1 -1
  208. package/dist/routes/nodes.d.ts +2 -2
  209. package/dist/routes/nodes.d.ts.map +1 -1
  210. package/dist/routes/nodes.js +75 -19
  211. package/dist/routes/nodes.js.map +1 -1
  212. package/dist/routes/ontology.d.ts +2 -2
  213. package/dist/routes/ontology.d.ts.map +1 -1
  214. package/dist/routes/ontology.js +22 -5
  215. package/dist/routes/ontology.js.map +1 -1
  216. package/dist/routes/proposals.d.ts +4 -3
  217. package/dist/routes/proposals.d.ts.map +1 -1
  218. package/dist/routes/proposals.js +170 -41
  219. package/dist/routes/proposals.js.map +1 -1
  220. package/dist/routes/runs.d.ts.map +1 -1
  221. package/dist/routes/runs.js +52 -1
  222. package/dist/routes/runs.js.map +1 -1
  223. package/dist/routes/skillInputOptions.d.ts +10 -0
  224. package/dist/routes/skillInputOptions.d.ts.map +1 -0
  225. package/dist/routes/skillInputOptions.js +161 -0
  226. package/dist/routes/skillInputOptions.js.map +1 -0
  227. package/dist/routes/skills.d.ts +2 -2
  228. package/dist/routes/skills.d.ts.map +1 -1
  229. package/dist/routes/skills.js +89 -19
  230. package/dist/routes/skills.js.map +1 -1
  231. package/dist/routes/sourceLoaders.d.ts +7 -0
  232. package/dist/routes/sourceLoaders.d.ts.map +1 -0
  233. package/dist/routes/sourceLoaders.js +29 -0
  234. package/dist/routes/sourceLoaders.js.map +1 -0
  235. package/dist/routes/sourceUnitStates.d.ts +7 -0
  236. package/dist/routes/sourceUnitStates.d.ts.map +1 -0
  237. package/dist/routes/sourceUnitStates.js +45 -0
  238. package/dist/routes/sourceUnitStates.js.map +1 -0
  239. package/dist/routes/users.d.ts +9 -0
  240. package/dist/routes/users.d.ts.map +1 -0
  241. package/dist/routes/users.js +127 -0
  242. package/dist/routes/users.js.map +1 -0
  243. package/dist/routes/workspaceMembers.d.ts +11 -0
  244. package/dist/routes/workspaceMembers.d.ts.map +1 -0
  245. package/dist/routes/workspaceMembers.js +81 -0
  246. package/dist/routes/workspaceMembers.js.map +1 -0
  247. package/dist/routes/workspaces.d.ts +19 -1
  248. package/dist/routes/workspaces.d.ts.map +1 -1
  249. package/dist/routes/workspaces.js +161 -45
  250. package/dist/routes/workspaces.js.map +1 -1
  251. package/dist/server.js +69 -25
  252. package/dist/server.js.map +1 -1
  253. package/package.json +48 -31
  254. package/LICENSE +0 -21
  255. package/dist/infrastructure/agent/ClaudeCodeAgentBinding.d.ts +0 -8
  256. package/dist/infrastructure/agent/ClaudeCodeAgentBinding.d.ts.map +0 -1
  257. package/dist/infrastructure/agent/ClaudeCodeAgentBinding.js +0 -62
  258. package/dist/infrastructure/agent/ClaudeCodeAgentBinding.js.map +0 -1
package/dist/composeFs.js CHANGED
@@ -1,41 +1,101 @@
1
+ import { spawn } from 'node:child_process';
1
2
  import { homedir } from 'node:os';
2
3
  import { join } from 'node:path';
3
4
  import process from 'node:process';
4
- import { builtinSkillsRoot, EvidenceValidator, InMemoryWorkspaceEventBus, NotFoundError, OntologyTypeValidator, OrphanEdgeValidator, PluginRegistry, StructuralValidator, } from '@braidhq/core';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { claudeCodeAgentPlugin } from '@braidhq/agent-claude-code';
7
+ import { builtinSkillsRoot, createLogger, NotFoundError, PluginRegistry, ValidationError, WorkspaceBootstrap, } from '@braidhq/core';
8
+ import { InMemoryWorkspaceEventBus } from '@braidhq/core/testing';
5
9
  import { dddOntology } from '@braidhq/ontology-ddd';
6
- import { GoogleDriveLoader } from '@braidhq/source-loader-gdrive';
7
- import { GitLoader } from '@braidhq/source-loader-git';
8
- import { KuzuModelRepository } from '@braidhq/storage-kuzu';
10
+ import { AgentId, AgentKind, StorageKind as StorageKindSchema } from '@braidhq/schema';
11
+ import { createGoogleDriveLoader } from '@braidhq/source-loader-gdrive';
12
+ import { gitLoader } from '@braidhq/source-loader-git';
13
+ import { createGithubLoader } from '@braidhq/source-loader-github';
14
+ import { kuzuStoragePlugin } from '@braidhq/storage-kuzu';
9
15
  import { composeApp } from './composition.js';
10
- import { ClaudeCodeAgentBinding } from './infrastructure/agent/ClaudeCodeAgentBinding.js';
11
16
  import { SubprocessSkillRunner } from './infrastructure/agent/SubprocessSkillRunner.js';
17
+ import { AccessPolicy } from './infrastructure/auth/AccessPolicy.js';
18
+ import { ensureApprovedEmails } from './infrastructure/auth/ensureApprovedEmails.js';
19
+ import { SessionStore } from './infrastructure/auth/SessionStore.js';
20
+ import { parseBoolEnv } from './infrastructure/env.js';
21
+ import { FsBatchPlanRepository } from './infrastructure/fs/FsBatchPlanRepository.js';
12
22
  import { FsClarifyTicketRepository } from './infrastructure/fs/FsClarifyTicketRepository.js';
13
23
  import { FsDecisionRepository } from './infrastructure/fs/FsDecisionRepository.js';
24
+ import { FsGraphSerializer } from './infrastructure/fs/FsGraphSerializer.js';
14
25
  import { FsProposalRepository } from './infrastructure/fs/FsProposalRepository.js';
15
26
  import { FsRunRepository } from './infrastructure/fs/FsRunRepository.js';
16
27
  import { FsSkillRegistry } from './infrastructure/fs/FsSkillRegistry.js';
28
+ import { FsSourceUnitDigest } from './infrastructure/fs/FsSourceUnitDigest.js';
29
+ import { FsSourceUnitStateRepository } from './infrastructure/fs/FsSourceUnitStateRepository.js';
17
30
  import { FsWorkspaceRepository } from './infrastructure/fs/FsWorkspaceRepository.js';
31
+ import { listIntentItems } from './infrastructure/fs/intentScan.js';
32
+ import { discoverCanonicalWorkspaces } from './infrastructure/fs/WorkspaceDiscovery.js';
18
33
  import { WorkspaceRegistryFile } from './infrastructure/fs/WorkspaceRegistryFile.js';
34
+ import { GitWorkspaceHistory } from './infrastructure/git/GitWorkspaceHistory.js';
19
35
  import { GoogleOAuth } from './infrastructure/oauth/GoogleOAuth.js';
20
36
  import { FsSecretStore } from './infrastructure/secrets/SecretStore.js';
37
+ import { ensureLocalUser } from './infrastructure/users/ensureLocalUser.js';
38
+ import { ensureWorkspaceOwners } from './infrastructure/users/ensureWorkspaceOwners.js';
39
+ import { UserDirectoryFromRegistry } from './infrastructure/users/UserDirectoryFromRegistry.js';
40
+ import { UserRegistryFile } from './infrastructure/users/UserRegistryFile.js';
21
41
  /**
22
- * Production composition root: real filesystem persistence for workspaces /
23
- * proposals / clarify / decisions, built-in skills loaded from `@braidhq/core`,
24
- * Claude Code subprocess agent. Model storage uses Kuzu (embedded, zero-infra)
25
- * per workspace at `<workspace>/.braid/model.kuzu`.
42
+ * Opinionated production composition: real filesystem persistence for
43
+ * workspaces / proposals / clarify / decisions, built-in skills loaded
44
+ * from `@braidhq/core`, and a batteries-included plugin bundle (Kuzu
45
+ * storage / DDD ontology / Git+GDrive source loaders / Claude Code
46
+ * agent).
47
+ *
48
+ * To run with a different plugin set, either:
49
+ * 1. Pass `extraXxxPlugins` to add alongside defaults + flip `storageKind`
50
+ * / `agentKind` to pick a different active one, OR
51
+ * 2. Call `composeApp` directly with a `pluginRegistry` you built yourself.
26
52
  */
27
- export function composeFsApp(options = {}) {
53
+ export async function composeFsApp(options = {}) {
28
54
  const braidHome = options.braidHome ?? process.env.BRAID_HOME ?? join(homedir(), '.braid');
29
55
  const apiUrl = options.apiUrl ?? 'http://localhost:4321';
30
56
  const secretStore = new FsSecretStore(join(braidHome, 'secrets'));
31
57
  const googleClientId = process.env.BRAID_GOOGLE_CLIENT_ID;
32
58
  const googleClientSecret = process.env.BRAID_GOOGLE_CLIENT_SECRET;
33
59
  const googleRedirect = process.env.BRAID_GOOGLE_REDIRECT_URI ?? `${apiUrl}/oauth/google/callback`;
60
+ const googleLoginRedirect = process.env.BRAID_GOOGLE_LOGIN_REDIRECT_URI ?? `${apiUrl}/auth/google/callback`;
34
61
  const googleOAuth = googleClientId && googleClientSecret
35
- ? new GoogleOAuth({ clientId: googleClientId, clientSecret: googleClientSecret, redirectUri: googleRedirect })
62
+ ? new GoogleOAuth({
63
+ clientId: googleClientId,
64
+ clientSecret: googleClientSecret,
65
+ redirectUri: googleRedirect,
66
+ loginRedirectUri: googleLoginRedirect,
67
+ })
36
68
  : undefined;
37
69
  const registry = new WorkspaceRegistryFile(join(braidHome, 'workspaces.json'));
38
70
  const workspaceRepository = new FsWorkspaceRepository({ registry });
71
+ // Server-side user roster. Distinct from any workspace's git history:
72
+ // Auth and ACL belong to the host, not to the product knowledge a
73
+ // workspace records. Single-user local installs get a `local-user`
74
+ // bootstrapped here so `userIdMiddleware`'s default actually resolves.
75
+ const userRegistry = new UserRegistryFile(join(braidHome, 'users.json'));
76
+ await ensureLocalUser(userRegistry);
77
+ // Phase B auth. Both files live next to `users.json` under `${BRAID_HOME}`;
78
+ // never inside a workspace because access control is host state, not
79
+ // workspace artifact. AccessPolicy reads env at construct time so a
80
+ // running server doesn't need to be restarted when env changes mid-flight
81
+ // — but production deployments do restart on config changes, which is
82
+ // why this is fine to read once.
83
+ const sessionStore = new SessionStore(join(braidHome, 'sessions.json'));
84
+ const accessPolicyConfig = {};
85
+ const allowedDomains = parseCsv(process.env.BRAID_ALLOWED_DOMAINS);
86
+ if (allowedDomains)
87
+ accessPolicyConfig.allowedDomains = allowedDomains;
88
+ const allowedEmails = parseCsv(process.env.BRAID_ALLOWED_EMAILS);
89
+ if (allowedEmails)
90
+ accessPolicyConfig.allowedEmails = allowedEmails;
91
+ const adminEmails = parseCsv(process.env.BRAID_ADMIN_EMAILS);
92
+ if (adminEmails)
93
+ accessPolicyConfig.adminEmails = adminEmails;
94
+ const accessPolicy = new AccessPolicy(join(braidHome, 'access.json'), accessPolicyConfig);
95
+ // Back-fill approvedEmails for any pre-existing user accounts so the
96
+ // dynamic allowlist matches the user roster on boot.
97
+ await ensureApprovedEmails(userRegistry, accessPolicy);
98
+ const studioUrl = process.env.BRAID_STUDIO_URL ?? 'http://localhost:5173';
39
99
  const workspaceRoots = async () => {
40
100
  const workspaces = await workspaceRepository.list();
41
101
  return new Map(workspaces.map(ws => [ws.id, ws.rootPath]));
@@ -43,59 +103,77 @@ export function composeFsApp(options = {}) {
43
103
  const proposalRepository = new FsProposalRepository({ workspaceRoots });
44
104
  const clarifyRepository = new FsClarifyTicketRepository({ workspaceRoots });
45
105
  const decisionRepository = new FsDecisionRepository({ workspaceRoots });
46
- const modelRepository = new KuzuModelRepository({
47
- resolveDbPath: async (workspaceId) => {
106
+ // Plugin registration. Defaults bundle first, then extras, so a caller
107
+ // that passes (e.g.) `extraOntologyPlugins: [c4]` ends up with both ddd
108
+ // and c4 registered; the active one is chosen per-workspace via
109
+ // PRODUCT.md.ontologyId.
110
+ const pluginRegistry = new PluginRegistry();
111
+ pluginRegistry.register(kuzuStoragePlugin);
112
+ for (const plugin of options.extraStoragePlugins ?? [])
113
+ pluginRegistry.register(plugin);
114
+ pluginRegistry.register(dddOntology);
115
+ for (const plugin of options.extraOntologyPlugins ?? [])
116
+ pluginRegistry.register(plugin);
117
+ pluginRegistry.register(gitLoader);
118
+ pluginRegistry.register(createGithubLoader());
119
+ for (const plugin of options.extraSourceLoaderPlugins ?? [])
120
+ pluginRegistry.register(plugin);
121
+ pluginRegistry.register(claudeCodeAgentPlugin);
122
+ for (const plugin of options.extraAgentPlugins ?? [])
123
+ pluginRegistry.register(plugin);
124
+ // The gdrive loader is always registered so a workspace declaring a
125
+ // `kind: gdrive` source doesn't crash at plugin lookup. If OAuth env
126
+ // vars aren't configured, the token resolver throws an actionable
127
+ // error at ingest time so the user knows exactly what to set.
128
+ const oauth = googleOAuth;
129
+ pluginRegistry.register(createGoogleDriveLoader({
130
+ resolveAccessToken: async ({ workspaceId, sourceId }) => {
131
+ if (!oauth) {
132
+ throw new ValidationError(`Google Drive source "${sourceId}" cannot be loaded: set BRAID_GOOGLE_CLIENT_ID and BRAID_GOOGLE_CLIENT_SECRET on the server, restart, then re-sync.`);
133
+ }
134
+ const key = `${workspaceId}--${sourceId}`;
135
+ const stored = await secretStore.read('oauth-google', key);
136
+ if (!stored) {
137
+ throw new NotFoundError(`Google Drive source "${sourceId}" on workspace "${workspaceId}" is not connected. `
138
+ + `Authorise via POST /oauth/google/start.`);
139
+ }
140
+ // 60-second skew so we don't hand out a token about to expire mid-request.
141
+ const stillValidUntil = new Date(stored.expiresAt).getTime() - 60_000;
142
+ if (Date.now() < stillValidUntil)
143
+ return stored.accessToken;
144
+ const refreshed = await oauth.refreshAccessToken(stored.refreshToken);
145
+ await secretStore.write('oauth-google', key, {
146
+ ...stored,
147
+ accessToken: refreshed.accessToken,
148
+ expiresAt: refreshed.expiresAt,
149
+ });
150
+ return refreshed.accessToken;
151
+ },
152
+ }));
153
+ // Resolve the active storage plugin and ask it for a ModelRepository.
154
+ const storageKind = StorageKindSchema.parse(options.storageKind ?? process.env.BRAID_STORAGE_KIND ?? 'kuzu');
155
+ const modelRepository = await pluginRegistry.requireStoragePlugin(storageKind).createModelRepository({ kind: storageKind, config: {} }, {
156
+ workspaceRootPath: braidHome,
157
+ logger: { info: () => { }, warn: () => { }, error: () => { } },
158
+ resolveWorkspaceRoot: async (workspaceId) => {
48
159
  const roots = await workspaceRoots();
49
160
  const root = roots.get(workspaceId);
50
161
  if (!root)
51
162
  throw new NotFoundError(`Workspace "${workspaceId}" not registered`);
52
- return join(root, '.braid', 'model.kuzu');
163
+ return root;
53
164
  },
54
165
  });
55
- const agentBinding = new ClaudeCodeAgentBinding({
56
- id: 'claude-default',
57
- kind: 'claude-code',
166
+ // Resolve the active agent plugin and build its binding.
167
+ const agentKind = AgentKind.parse(options.agentKind ?? 'claude-code');
168
+ const agentBinding = pluginRegistry.requireAgentPlugin(agentKind).createBinding({
169
+ id: AgentId.parse('default'),
170
+ kind: agentKind,
58
171
  model: options.agentModel ?? 'opus',
59
172
  effort: options.agentEffort ?? 'high',
60
173
  extraArgs: [],
61
174
  env: {},
62
175
  });
63
176
  const runRepository = new FsRunRepository();
64
- const pluginRegistry = new PluginRegistry();
65
- pluginRegistry.register(dddOntology);
66
- pluginRegistry.register(new EvidenceValidator());
67
- pluginRegistry.register(new OrphanEdgeValidator());
68
- pluginRegistry.register(new OntologyTypeValidator(dddOntology));
69
- pluginRegistry.register(new StructuralValidator(dddOntology));
70
- pluginRegistry.register(new GitLoader());
71
- if (googleOAuth) {
72
- // GoogleDriveLoader requires OAuth to be configured. We resolve the
73
- // access token per (workspaceId, sourceId): read stored tokens from
74
- // the secret store, refresh if expired, persist the rotated access
75
- // token, hand the bearer to the loader.
76
- const oauth = googleOAuth;
77
- pluginRegistry.register(new GoogleDriveLoader({
78
- resolveAccessToken: async ({ workspaceId, sourceId }) => {
79
- const key = `${workspaceId}--${sourceId}`;
80
- const stored = await secretStore.read('oauth-google', key);
81
- if (!stored) {
82
- throw new NotFoundError(`Google Drive source "${sourceId}" on workspace "${workspaceId}" is not connected. `
83
- + `Authorise via POST /oauth/google/start.`);
84
- }
85
- // 60-second skew so we don't hand out a token about to expire mid-request.
86
- const stillValidUntil = new Date(stored.expiresAt).getTime() - 60_000;
87
- if (Date.now() < stillValidUntil)
88
- return stored.accessToken;
89
- const refreshed = await oauth.refreshAccessToken(stored.refreshToken);
90
- await secretStore.write('oauth-google', key, {
91
- ...stored,
92
- accessToken: refreshed.accessToken,
93
- expiresAt: refreshed.expiresAt,
94
- });
95
- return refreshed.accessToken;
96
- },
97
- }));
98
- }
99
177
  // Built after pluginRegistry is populated so plugin-shipped SKILL.md
100
178
  // files mount under the `plugin` skill origin alongside builtins.
101
179
  const skillRegistry = new FsSkillRegistry({
@@ -103,16 +181,51 @@ export function composeFsApp(options = {}) {
103
181
  pluginRegistry,
104
182
  });
105
183
  const eventBus = new InMemoryWorkspaceEventBus();
184
+ // Built-in braid-core MCP gateway: each spawned skill gets a stdio
185
+ // entry that runs `uvx openapi-mcp-gateway` with --transport stdio.
186
+ // The gateway lifecycle tracks the claude subprocess; no separate
187
+ // long-running server. Requires `uv` to be installed on PATH; if it
188
+ // isn't, skip the entry silently — skills with
189
+ // `requiredMcpServers: ['braid-core']` will surface as not-ready
190
+ // via SkillManifest.readinessIssuesFor, with a clear pointer.
191
+ const uvxBin = await detectUvx();
192
+ if (!uvxBin) {
193
+ console.warn('[braid] `uv` not found on PATH; the built-in braid-core MCP gateway will not be available. '
194
+ + 'Install via `brew install uv` or https://docs.astral.sh/uv/ to enable.');
195
+ }
196
+ // Build the list of reference dirs symlinked into every skill session:
197
+ // - builtin `shared/` from @braidhq/core (Proposal / Clarify / Validator
198
+ // format docs, content conventions, drift-detection guidance)
199
+ // - whatever each registered plugin contributes (e.g. ontology-ddd's
200
+ // concept doc). Plugin contributions resolve `URL` -> absolute path.
201
+ const pluginReferenceDirs = pluginRegistry.pluginReferenceDirs().map((ref) => {
202
+ const dir = typeof ref.directory === 'string' ? ref.directory : fileURLToPath(ref.directory);
203
+ return { name: ref.name, path: dir };
204
+ });
106
205
  const skillRunner = new SubprocessSkillRunner({
107
206
  skillRegistry,
108
207
  agentBinding,
109
208
  apiUrl,
110
209
  runRepository,
111
210
  eventBus,
211
+ ...(uvxBin
212
+ ? { coreGateway: { specUrl: `${apiUrl}/openapi.json`, uvxBin } }
213
+ : {}),
112
214
  referenceDirs: [
113
215
  { name: 'shared', path: join(builtinSkillsRoot, 'shared') },
216
+ ...pluginReferenceDirs,
114
217
  ],
115
218
  });
219
+ // Shared by WorkspaceBootstrap (boot reconciliation) and HITLService (per-mutation commits).
220
+ const history = new GitWorkspaceHistory();
221
+ const graphSerializer = new FsGraphSerializer();
222
+ const bootstrap = new WorkspaceBootstrap({
223
+ history,
224
+ serializer: graphSerializer,
225
+ modelRepository,
226
+ });
227
+ const workspacesRoot = join(braidHome, 'workspaces');
228
+ const userDirectory = new UserDirectoryFromRegistry(userRegistry);
116
229
  const deps = composeApp({
117
230
  workspaceRepository,
118
231
  proposalRepository,
@@ -124,11 +237,80 @@ export function composeFsApp(options = {}) {
124
237
  runRepository,
125
238
  pluginRegistry,
126
239
  eventBus,
240
+ workspacesRoot,
241
+ history,
242
+ graphSerializer,
243
+ bootstrap,
244
+ batchPlanRepository: new FsBatchPlanRepository(),
245
+ intentLister: listIntentItems,
246
+ sourceUnitStateRepository: new FsSourceUnitStateRepository({ workspaceRoots }),
247
+ sourceUnitDigest: new FsSourceUnitDigest(),
248
+ userDirectory,
127
249
  });
250
+ // Pick up workspaces that exist on disk but aren't in the registry:
251
+ // CLI-created ones, scaffold-orphans, copies-from-another-machine.
252
+ // Registry add is idempotent so this is safe to run on every boot.
253
+ await discoverCanonicalWorkspaces(workspacesRoot, deps.workspaceService);
254
+ // Phase C migration: stamp `local-user` as owner of any workspace
255
+ // whose members[] is still empty (pre-Phase-C registry entries,
256
+ // freshly discovered workspaces). Owner promotion via `/members`
257
+ // routes can rewrite this later.
258
+ await ensureWorkspaceOwners(registry);
259
+ // Per-workspace failures are logged and tolerated so one bad dir doesn't block boot.
260
+ const bootstrapLog = createLogger('server').child({ mod: 'workspace-bootstrap' });
261
+ for (const workspace of await deps.workspaceService.list()) {
262
+ try {
263
+ await bootstrap.ensure(workspace);
264
+ // Mark any batch plan left running by a previous process as failed so
265
+ // the UI doesn't show a phantom spinner. Safe to call even when there
266
+ // is no plan or when the plan is already terminal.
267
+ await deps.batchService?.reconcileAfterBoot(workspace.id);
268
+ }
269
+ catch (err) {
270
+ bootstrapLog.warn({ err, workspaceId: workspace.id }, 'workspace bootstrap failed; skipping');
271
+ }
272
+ }
273
+ // Local trust is the default; production deployments opt into the
274
+ // Bearer-token gate by setting `BRAID_LOCAL_TRUST=false`. We deliberately
275
+ // DON'T flip the default just because Google OAuth env vars are
276
+ // present — those same creds are also used by the Drive source
277
+ // loader for ingest, so a local dev workspace pulling from Drive
278
+ // would otherwise get pushed into the Login flow on every reload.
279
+ const localTrust = parseBoolEnv(process.env.BRAID_LOCAL_TRUST, true);
128
280
  return {
129
281
  ...deps,
282
+ bootstrap,
130
283
  secretStore,
284
+ userRegistry,
285
+ workspaceRegistry: registry,
286
+ sessionStore,
287
+ accessPolicy,
288
+ studioUrl,
289
+ localTrust,
131
290
  ...(googleOAuth ? { googleOAuth } : {}),
132
291
  };
133
292
  }
293
+ function parseCsv(input) {
294
+ if (!input)
295
+ return undefined;
296
+ const parts = input.split(',').map(s => s.trim()).filter(s => s.length > 0);
297
+ return parts.length > 0 ? parts : undefined;
298
+ }
299
+ /**
300
+ * Resolve the `uvx` binary path by running `uvx --version`. Returns
301
+ * `'uvx'` when the call succeeds (we let `PATH` resolve it at spawn
302
+ * time so we don't bake an absolute path into mcp-config), or
303
+ * `undefined` when `uv` isn't installed. Honours `BRAID_UVX_BIN` for
304
+ * pinning a specific binary (uv in a non-PATH location, or tests
305
+ * that want to inject a stub).
306
+ */
307
+ async function detectUvx() {
308
+ const pinned = process.env.BRAID_UVX_BIN;
309
+ const command = pinned && pinned.length > 0 ? pinned : 'uvx';
310
+ return await new Promise((resolve) => {
311
+ const child = spawn(command, ['--version'], { stdio: 'ignore' });
312
+ child.once('error', () => resolve(undefined));
313
+ child.once('exit', code => resolve(code === 0 ? command : undefined));
314
+ });
315
+ }
134
316
  //# sourceMappingURL=composeFs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"composeFs.js","sourceRoot":"","sources":["../src/composeFs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"composeFs.js","sourceRoot":"","sources":["../src/composeFs.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,18 @@
1
- import type { ClarifyTicketRepository, Clock, DecisionRepository, ModelRepository, ProposalRepository, RunRepository, SkillRegistry, SkillRunner, WorkspaceEventBus, WorkspaceRepository } from '@braidhq/core';
1
+ import type { BatchPlanRepository, ClarifyTicketRepository, Clock, DecisionRepository, GraphSerializer, IntentLister, ModelRepository, ProposalRepository, RunRepository, SkillRegistry, SkillRunner, SourceUnitDigest, SourceUnitStateRepository, UserDirectory, WorkspaceBootstrap, WorkspaceEventBus, WorkspaceHistory, WorkspaceRepository } from '@braidhq/core';
2
+ import type { AbsolutePath } from '@braidhq/schema';
3
+ import type { AccessPolicy } from './infrastructure/auth/AccessPolicy.js';
4
+ import type { SessionStore } from './infrastructure/auth/SessionStore.js';
5
+ import type { WorkspaceRegistryFile } from './infrastructure/fs/WorkspaceRegistryFile.js';
2
6
  import type { GoogleOAuth } from './infrastructure/oauth/GoogleOAuth.js';
3
7
  import type { SecretStore } from './infrastructure/secrets/SecretStore.js';
4
- import { HITLService, ModelService, PluginRegistry, SourceLoaderRunner, ValidationService, WorkspaceService } from '@braidhq/core';
8
+ import type { UserRegistryFile } from './infrastructure/users/UserRegistryFile.js';
9
+ import { BatchService, HistoryService, HITLService, ModelService, PluginRegistry, SourceLoaderRunner, SourceUnitStateService, ValidationService, WorkspaceService } from '@braidhq/core';
5
10
  export interface AppDependencies {
6
11
  workspaceService: WorkspaceService;
7
12
  hitlService: HITLService;
13
+ historyService?: HistoryService;
14
+ batchService?: BatchService;
15
+ sourceUnitStateService: SourceUnitStateService;
8
16
  modelService: ModelService;
9
17
  validationService: ValidationService;
10
18
  sourceLoaderRunner: SourceLoaderRunner;
@@ -18,6 +26,12 @@ export interface AppDependencies {
18
26
  skillRegistry: SkillRegistry | undefined;
19
27
  skillRunner: SkillRunner | undefined;
20
28
  runRepository: RunRepository;
29
+ /**
30
+ * Parent directory under which name-based workspaces are scaffolded.
31
+ * `POST /workspaces/scaffold { name }` resolves to `<workspacesRoot>/<name>`.
32
+ */
33
+ workspacesRoot: AbsolutePath;
34
+ bootstrap?: WorkspaceBootstrap;
21
35
  /** OAuth secret storage (file-based; pluggable for hosted deployments). */
22
36
  secretStore?: SecretStore;
23
37
  /**
@@ -25,6 +39,45 @@ export interface AppDependencies {
25
39
  * respond with 503 in that case.
26
40
  */
27
41
  googleOAuth?: GoogleOAuth;
42
+ /**
43
+ * Server-side user roster (Phase A scaffolding). When absent the
44
+ * `/users` route is not mounted; routes that read `c.get('userId')`
45
+ * still work because `userIdMiddleware` falls back to `local-user`.
46
+ */
47
+ userRegistry?: UserRegistryFile;
48
+ /**
49
+ * Server-side workspace registry — backs the Phase C membership
50
+ * model. Required to mount `workspaceAccessMiddleware` and the
51
+ * `/workspaces/:id/members` routes; absent in pure in-memory tests
52
+ * that don't need member-gating.
53
+ */
54
+ workspaceRegistry?: WorkspaceRegistryFile;
55
+ /**
56
+ * Phase B: Bearer-token session backing. Required to mount `/auth/*`
57
+ * and the auth middleware. Absent in tests that want the pre-Phase-A
58
+ * trusted-network shape (no auth gate).
59
+ */
60
+ sessionStore?: SessionStore;
61
+ /**
62
+ * Phase B: Gate-1 allowlist + invite list. Paired with `sessionStore`
63
+ * to mount `/auth/*`.
64
+ */
65
+ accessPolicy?: AccessPolicy;
66
+ /**
67
+ * Phase B: URL the Studio bundle is served from. OAuth callback
68
+ * redirects here with `#token=...` so the SPA can capture the
69
+ * session. Defaults to the Vite dev origin in `composeFsApp`.
70
+ */
71
+ studioUrl?: string;
72
+ /**
73
+ * Phase B: when true (default in tests / local dev where Google
74
+ * OAuth isn't configured), the auth middleware lets every request
75
+ * through and `userIdMiddleware`'s fallback (`local-user`) takes
76
+ * over. composeFs computes this from the presence of Google OAuth
77
+ * env vars; production remote deployments end up with `false` and
78
+ * an enforced Bearer-token gate.
79
+ */
80
+ localTrust: boolean;
28
81
  clock: Clock;
29
82
  }
30
83
  export interface ComposeOptions {
@@ -38,12 +91,43 @@ export interface ComposeOptions {
38
91
  skillRegistry?: SkillRegistry;
39
92
  skillRunner?: SkillRunner;
40
93
  runRepository?: RunRepository;
94
+ /**
95
+ * Parent dir for name-based scaffold. composeFsApp sets this to
96
+ * `<braidHome>/workspaces`; tests using composeApp directly can leave
97
+ * it at the default unless they exercise the scaffold endpoint.
98
+ */
99
+ workspacesRoot?: AbsolutePath;
41
100
  /**
42
101
  * Pre-created event bus. Pass the same instance you wired into
43
102
  * `SubprocessSkillRunner` so subscribers see runner events. Defaults
44
103
  * to a fresh `InMemoryWorkspaceEventBus` for tests / in-memory boot.
45
104
  */
46
105
  eventBus?: WorkspaceEventBus;
106
+ history?: WorkspaceHistory;
107
+ graphSerializer?: GraphSerializer;
108
+ bootstrap?: WorkspaceBootstrap;
109
+ batchPlanRepository?: BatchPlanRepository;
110
+ intentLister?: IntentLister;
111
+ /**
112
+ * Persistence for `SourceUnitState`. Defaults to an in-memory impl
113
+ * so unit tests of unrelated services keep working without wiring;
114
+ * `composeFsApp` swaps in the fs-backed repo.
115
+ */
116
+ sourceUnitStateRepository?: SourceUnitStateRepository;
117
+ /**
118
+ * Content fingerprinter for source units. Required for batch / reactor
119
+ * / manual extract to record observations. Without it the
120
+ * `SourceUnitStateService` falls back to a no-op stub digest that
121
+ * throws on use, which is fine for tests that don't exercise observation
122
+ * recording but would break production batches.
123
+ */
124
+ sourceUnitDigest?: SourceUnitDigest;
125
+ /**
126
+ * Optional read-only user lookup used by HITLService / HistoryService
127
+ * to snapshot displayName + email into the git author when committing.
128
+ * Tests skip this so the existing `Author: <userId>` shape is preserved.
129
+ */
130
+ userDirectory?: UserDirectory;
47
131
  }
48
132
  export declare function composeApp(options?: ComposeOptions): AppDependencies;
49
133
  //# sourceMappingURL=composition.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"composition.d.ts","sourceRoot":"","sources":["../src/composition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,KAAK,EACL,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,eAAe,CAAA;AACtB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAA;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAA;AAC1E,OAAO,EACL,WAAW,EAOX,YAAY,EAEZ,cAAc,EACd,kBAAkB,EAElB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,eAAe,CAAA;AAEtB,MAAM,WAAW,eAAe;IAC9B,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,WAAW,EAAE,WAAW,CAAA;IACxB,YAAY,EAAE,YAAY,CAAA;IAC1B,iBAAiB,EAAE,iBAAiB,CAAA;IACpC,kBAAkB,EAAE,kBAAkB,CAAA;IACtC,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,cAAc,EAAE,cAAc,CAAA;IAC9B,kBAAkB,EAAE,kBAAkB,CAAA;IACtC,iBAAiB,EAAE,uBAAuB,CAAA;IAC1C,kBAAkB,EAAE,kBAAkB,CAAA;IACtC,eAAe,EAAE,eAAe,CAAA;IAChC,mBAAmB,EAAE,mBAAmB,CAAA;IACxC,aAAa,EAAE,aAAa,GAAG,SAAS,CAAA;IACxC,WAAW,EAAE,WAAW,GAAG,SAAS,CAAA;IACpC,aAAa,EAAE,aAAa,CAAA;IAC5B,2EAA2E;IAC3E,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,KAAK,EAAE,KAAK,CAAA;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,kBAAkB,CAAC,EAAE,kBAAkB,CAAA;IACvC,iBAAiB,CAAC,EAAE,uBAAuB,CAAA;IAC3C,kBAAkB,CAAC,EAAE,kBAAkB,CAAA;IACvC,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,mBAAmB,CAAC,EAAE,mBAAmB,CAAA;IACzC,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,iBAAiB,CAAA;CAC7B;AAED,wBAAgB,UAAU,CAAC,OAAO,GAAE,cAAmB,GAAG,eAAe,CA0CxE"}
1
+ {"version":3,"file":"composition.d.ts","sourceRoot":"","sources":["../src/composition.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,7 @@
1
- import { HITLService, InMemoryClarifyTicketRepository, InMemoryDecisionRepository, InMemoryModelRepository, InMemoryProposalRepository, InMemoryWorkspaceEventBus, InMemoryWorkspaceRepository, ModelService, noopRunRepository, PluginRegistry, SourceLoaderRunner, SystemClock, ValidationService, WorkspaceService, } from '@braidhq/core';
1
+ import { tmpdir } from 'node:os';
2
+ import { join } from 'node:path';
3
+ import { BatchService, HistoryService, HITLService, ModelService, PerWorkspaceLock, PluginRegistry, SourceLoaderRunner, SourceUnitStateService, SystemClock, ValidationService, WorkspaceService, } from '@braidhq/core';
4
+ import { InMemoryClarifyTicketRepository, InMemoryDecisionRepository, InMemoryModelRepository, InMemoryProposalRepository, InMemorySourceUnitStateRepository, InMemoryWorkspaceEventBus, InMemoryWorkspaceRepository, noopRunRepository, } from '@braidhq/core/testing';
2
5
  export function composeApp(options = {}) {
3
6
  const clock = options.clock ?? new SystemClock();
4
7
  const proposalRepository = options.proposalRepository ?? new InMemoryProposalRepository();
@@ -12,18 +15,68 @@ export function composeApp(options = {}) {
12
15
  const modelService = new ModelService({ modelRepository });
13
16
  const validationService = new ValidationService({ pluginRegistry });
14
17
  const sourceLoaderRunner = new SourceLoaderRunner({ pluginRegistry, clock, eventBus });
18
+ // Shared lock domain so HITL mutations and history restore exclude each other.
19
+ const workspaceLock = new PerWorkspaceLock();
15
20
  const hitlService = new HITLService({
16
21
  proposalRepository,
17
22
  clarifyRepository,
18
23
  decisionRepository,
19
24
  modelRepository,
20
25
  validationService,
26
+ workspaceService,
21
27
  clock,
22
28
  eventBus,
29
+ workspaceLock,
30
+ ...(options.history ? { history: options.history } : {}),
31
+ ...(options.graphSerializer ? { graphSerializer: options.graphSerializer } : {}),
32
+ ...(options.userDirectory ? { userDirectory: options.userDirectory } : {}),
23
33
  });
34
+ const historyService = options.history && options.bootstrap
35
+ ? new HistoryService({
36
+ history: options.history,
37
+ workspaceService,
38
+ workspaceLock,
39
+ bootstrap: options.bootstrap,
40
+ runRepository: options.runRepository ?? noopRunRepository,
41
+ ...(options.skillRunner ? { skillRunner: options.skillRunner } : {}),
42
+ ...(options.userDirectory ? { userDirectory: options.userDirectory } : {}),
43
+ eventBus,
44
+ clock,
45
+ })
46
+ : undefined;
47
+ const sourceUnitStateRepository = options.sourceUnitStateRepository ?? new InMemorySourceUnitStateRepository();
48
+ const sourceUnitDigest = options.sourceUnitDigest ?? new FailingSourceUnitDigest();
49
+ const sourceUnitStateService = new SourceUnitStateService({
50
+ repository: sourceUnitStateRepository,
51
+ digest: sourceUnitDigest,
52
+ workspaceService,
53
+ clock,
54
+ });
55
+ // Batch needs SkillRunner + HistoryService + BatchPlanRepository + intent lister; otherwise no batch surface.
56
+ const batchService = historyService && options.skillRunner && options.batchPlanRepository && options.intentLister
57
+ ? new BatchService({
58
+ workspaceService,
59
+ skillRunner: options.skillRunner,
60
+ proposalRepository,
61
+ clarifyRepository,
62
+ historyService,
63
+ hitlService,
64
+ batchPlanRepository: options.batchPlanRepository,
65
+ intentLister: options.intentLister,
66
+ pluginRegistry,
67
+ eventBus,
68
+ workspaceLock,
69
+ clock,
70
+ sourceUnitStateService,
71
+ })
72
+ : undefined;
24
73
  return {
25
74
  workspaceService,
26
75
  hitlService,
76
+ ...(historyService ? { historyService } : {}),
77
+ ...(batchService ? { batchService } : {}),
78
+ ...(options.bootstrap ? { bootstrap: options.bootstrap } : {}),
79
+ sourceUnitStateService,
27
80
  modelService,
28
81
  validationService,
29
82
  sourceLoaderRunner,
@@ -37,7 +90,24 @@ export function composeApp(options = {}) {
37
90
  skillRegistry: options.skillRegistry,
38
91
  skillRunner: options.skillRunner,
39
92
  runRepository: options.runRepository ?? noopRunRepository,
93
+ workspacesRoot: options.workspacesRoot ?? join(tmpdir(), 'braid-workspaces'),
94
+ // `composeApp` is the test / in-memory composition entry. It never
95
+ // wires sessionStore, so the auth middleware in `createApp` is
96
+ // skipped anyway — but explicit `localTrust: true` keeps the
97
+ // contract honest if a test does happen to pass sessionStore.
98
+ localTrust: true,
40
99
  clock,
41
100
  };
42
101
  }
102
+ /**
103
+ * Default `SourceUnitDigest` for in-memory `composeApp()` callers. Any
104
+ * call throws — production must wire a real impl via `composeFsApp` or
105
+ * pass one explicitly; tests that don't exercise observations stay
106
+ * happy because the digest is never reached.
107
+ */
108
+ class FailingSourceUnitDigest {
109
+ async computeSha() {
110
+ throw new Error('SourceUnitDigest is not wired. Pass `sourceUnitDigest` to composeApp() (composeFsApp does this automatically).');
111
+ }
112
+ }
43
113
  //# sourceMappingURL=composition.js.map