@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/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # @braidhq/server
2
+
3
+ REST + SSE server for Braid. Hono-based, with an OpenAPI 3 spec
4
+ exposed at `GET /openapi.json` for any consumer that wants typed
5
+ access to the graph operations.
6
+
7
+ ## openapi-mcp-gateway Integration
8
+
9
+ Skills shipped with `@braidhq/core` and `@braidhq/ontology-ddd` invoke
10
+ the server through MCP tools, not curl. The wiring runs the gateway
11
+ as a **per-skill stdio child of claude** — no long-running HTTP
12
+ server, gateway lifecycle tracks the skill run automatically.
13
+
14
+ ```
15
+ ┌──────────────────┐ /openapi.json ┌─────────────────────┐
16
+ │ @braidhq/server │ ◀───── HTTP ────── │ openapi-mcp-gateway │
17
+ │ (this package) │ ────── REST ────▶ │ (uvx, stdio child) │
18
+ └──────────────────┘ └─────────────────────┘
19
+ ▲ stdin/stdout
20
+ │ MCP
21
+ ┌─────────────────────┐
22
+ │ spawned claude │
23
+ │ subprocess (skill) │
24
+ └─────────────────────┘
25
+ ```
26
+
27
+ ### 1. Install `uv` (one-time setup)
28
+
29
+ `openapi-mcp-gateway` is a Python package distributed via PyPI. The
30
+ gateway is launched on demand by claude via `uvx` (UV's "run an
31
+ ephemeral package" command), so the only thing you have to install
32
+ locally is the `uv` runtime itself:
33
+
34
+ ```bash
35
+ # macOS
36
+ brew install uv
37
+ # linux / windows: see https://docs.astral.sh/uv/getting-started/installation/
38
+ ```
39
+
40
+ The Braid server **preflight-checks for `uv` at boot**. If it's not
41
+ found, you'll see:
42
+
43
+ ```
44
+ [braid] `uv` not found on PATH; the built-in braid-core MCP gateway
45
+ will not be available. Install via `brew install uv` or
46
+ https://docs.astral.sh/uv/ to enable.
47
+ ```
48
+
49
+ Skills with `requiredMcpServers: ['braid-core']` will then surface
50
+ as not-ready in Studio's sidebar. Other skills keep working.
51
+
52
+ ### 2. That's it
53
+
54
+ No environment variables to set, no separate gateway process to run.
55
+ When Braid spawns a skill, the skill's mcp-config gets a stdio entry:
56
+
57
+ ```jsonc
58
+ {
59
+ "braid-core": {
60
+ "type": "stdio",
61
+ "command": "uvx",
62
+ "args": [
63
+ "openapi-mcp-gateway",
64
+ "--spec",
65
+ "http://127.0.0.1:4321/openapi.json",
66
+ "--transport",
67
+ "stdio",
68
+ "--name",
69
+ "braid-core"
70
+ ]
71
+ }
72
+ }
73
+ ```
74
+
75
+ claude spawns the gateway, the gateway pulls the spec from the
76
+ running Braid server, and the REST surface becomes MCP tools for the
77
+ duration of the skill run.
78
+
79
+ First-time runs take an extra ~1–2 seconds (uvx caches
80
+ `openapi-mcp-gateway` under `~/.cache/uv/`). Subsequent runs hit the
81
+ cache.
82
+
83
+ ### 3. Author skills against the MCP tools
84
+
85
+ Skill prompts call MCP tools by their `operationId`:
86
+
87
+ - `braid_search_nodes(workspaceId, q, type?, status?, limit?, offset?)`
88
+ - `braid_get_scope(workspaceId, nodeId, depth)`
89
+ - `braid_get_ontology(workspaceId)`
90
+ - `braid_submit_proposal(workspaceId, operations, generatedBy, rationale)`
91
+ - `braid_submit_clarify(workspaceId, question, candidates)`
92
+ - `braid_mark_clarify_applied(workspaceId, clarifyTicketId, status, userId, proposalId?)`
93
+ - …and the rest, one per operation in `/openapi.json`.
94
+
95
+ Exact tool names depend on `openapi-mcp-gateway`'s naming convention
96
+ (typically `<server-name>_<operationId>` with snake_case
97
+ normalisation). Inspect the spec or the gateway's `tools/list`
98
+ response to see live names.
99
+
100
+ ### Pinning the uv binary
101
+
102
+ For reproducibility (e.g. CI environments with multiple Python
103
+ toolchains) you can pin a specific `uvx` binary via the
104
+ `BRAID_UVX_BIN` env var. composeFs preflight-checks the pinned
105
+ binary; if it's not executable, the gateway entry is skipped same as
106
+ when `uv` is missing entirely.
107
+
108
+ ```bash
109
+ export BRAID_UVX_BIN=/opt/homebrew/bin/uvx
110
+ ```
111
+
112
+ ### Forward compatibility (hosted Braid)
113
+
114
+ When Braid grows a hosted product where the server runs remotely:
115
+
116
+ - If claude runs locally (desktop spawns it): the stdio path above
117
+ still works. The local gateway just talks HTTPS to the remote
118
+ `/openapi.json` and REST endpoints, with auth headers passed
119
+ through workspace-level MCP server config.
120
+ - If claude runs in the cloud (browser Studio): the stdio path runs
121
+ server-side, gateway loopbacks to the local server.
122
+
123
+ The `streamable-http` MCP transport stays first-class in the schema
124
+ so workspaces can declare any third-party HTTP MCP server (Redmine /
125
+ Notion / Linear / …) alongside the stdio braid-core. The two
126
+ transports are not mutually exclusive.
127
+
128
+ ## Routes That Are Not in the Spec
129
+
130
+ - SSE streams (`/workspaces/{ws}/runs/{runId}/events`,
131
+ `/workspaces/{ws}/events`) — not invocable as one-shot MCP tools.
132
+ - OAuth callbacks (`/oauth/google/callback`) — HTML response.
133
+ - Workspace management (`/workspaces/*`) — admin surface for CLI
134
+ and Studio, not for skills.
135
+
136
+ The `GET /openapi.json` test in `test/app.test.ts` pins this list.
package/dist/app.d.ts CHANGED
@@ -1,7 +1,24 @@
1
1
  import type { AppDependencies } from './composition.js';
2
- import { Hono } from 'hono';
2
+ import { OpenAPIHono } from '@hono/zod-openapi';
3
3
  export interface AppOptions {
4
4
  readonly corsOrigins?: readonly string[];
5
+ /**
6
+ * Base URL the OpenAPI spec advertises in its `servers[]` block. This
7
+ * is what downstream consumers (openapi-mcp-gateway, Swagger UI, code
8
+ * generators, …) use to dispatch REST calls. When unset, the spec is
9
+ * emitted without `servers[]`, which leaves the consumer to guess.
10
+ * composeFsApp threads its `apiUrl` through here so the gateway can
11
+ * route REST calls back to this server without an explicit
12
+ * `--base-url` flag.
13
+ */
14
+ readonly apiUrl?: string;
15
+ /**
16
+ * When true (or `BRAID_LOCAL_TRUST=true`), the auth middleware lets
17
+ * every request through and the embedded `userIdMiddleware` falls
18
+ * back to `local-user`. Set by `composeFs` for the Tauri sidecar;
19
+ * production remote servers leave it `false`.
20
+ */
21
+ readonly localTrust?: boolean;
5
22
  }
6
- export declare function createApp(deps: AppDependencies, options?: AppOptions): Hono;
23
+ export declare function createApp(deps: AppDependencies, options?: AppOptions): OpenAPIHono;
7
24
  //# sourceMappingURL=app.d.ts.map
package/dist/app.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAkB3B,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACzC;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,GAAE,UAAe,GAAG,IAAI,CA6D/E"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AA8B/C,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC;;;;;;;;OAQG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAC9B;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,GAAE,UAAe,GAAG,WAAW,CAwKtF"}
package/dist/app.js CHANGED
@@ -1,34 +1,108 @@
1
- import { Hono } from 'hono';
1
+ import { OpenAPIHono } from '@hono/zod-openapi';
2
+ import { authMiddleware } from './middleware/auth.js';
2
3
  import { corsMiddleware } from './middleware/cors.js';
3
4
  import { errorHandler } from './middleware/error.js';
5
+ import { userIdMiddleware } from './middleware/userId.js';
6
+ import { workspaceAccessMiddleware } from './middleware/workspaceAccess.js';
4
7
  import { workspaceIdMiddleware } from './middleware/workspaceId.js';
8
+ import { createAdminRouter } from './routes/admin.js';
9
+ import { createAuthRouter } from './routes/auth.js';
10
+ import { createBatchRouter } from './routes/batch.js';
5
11
  import { createClarifyRouter } from './routes/clarify.js';
6
12
  import { createDecisionsRouter } from './routes/decisions.js';
7
13
  import { createEdgesRouter } from './routes/edges.js';
8
14
  import { healthRouter } from './routes/health.js';
15
+ import { createHistoryRouter } from './routes/history.js';
9
16
  import { createModelRouter } from './routes/model.js';
10
17
  import { createNodesRouter } from './routes/nodes.js';
11
18
  import { createOAuthRouter } from './routes/oauth.js';
12
19
  import { createOntologyRouter } from './routes/ontology.js';
13
20
  import { createProposalsRouter } from './routes/proposals.js';
14
21
  import { createRunsRouter } from './routes/runs.js';
22
+ import { createSkillInputOptionsRouter } from './routes/skillInputOptions.js';
15
23
  import { createSkillsRouter } from './routes/skills.js';
24
+ import { createSourceLoadersRouter } from './routes/sourceLoaders.js';
25
+ import { createSourceUnitStatesRouter } from './routes/sourceUnitStates.js';
26
+ import { createUsersRouter } from './routes/users.js';
16
27
  import { createWorkspaceEventsRouter } from './routes/workspaceEvents.js';
28
+ import { createTransferOwnershipRouter, createWorkspaceMembersRouter } from './routes/workspaceMembers.js';
17
29
  import { createWorkspacesRouter } from './routes/workspaces.js';
18
30
  export function createApp(deps, options = {}) {
19
- const app = new Hono();
31
+ const app = new OpenAPIHono();
20
32
  app.use('*', options.corsOrigins
21
33
  ? corsMiddleware({ allowedOrigins: options.corsOrigins })
22
34
  : corsMiddleware());
35
+ // Phase B auth gate. In local-trust mode it short-circuits and lets
36
+ // the unauthenticated request through; otherwise a Bearer token is
37
+ // required (Google OAuth-issued session). Public routes — `/auth/*`,
38
+ // `/health` — are excluded inside the middleware so the login flow
39
+ // itself isn't gated.
40
+ if (deps.sessionStore) {
41
+ const localTrust = options.localTrust ?? deps.localTrust;
42
+ app.use('*', authMiddleware({
43
+ sessionStore: deps.sessionStore,
44
+ localTrust,
45
+ }));
46
+ }
47
+ // Phase A identity. Stamps `c.set('userId', ...)` from `X-Braid-User`
48
+ // when the auth layer left it empty — i.e. local-trust mode, or any
49
+ // public route. Bearer-authenticated requests already have a userId
50
+ // by the time this runs and pass through untouched.
51
+ app.use('*', userIdMiddleware);
23
52
  app.onError(errorHandler);
24
53
  app.route('/health', healthRouter);
54
+ if (deps.sessionStore && deps.accessPolicy && deps.userRegistry) {
55
+ app.route('/auth', createAuthRouter({
56
+ clock: deps.clock,
57
+ sessionStore: deps.sessionStore,
58
+ accessPolicy: deps.accessPolicy,
59
+ userRegistry: deps.userRegistry,
60
+ ...(deps.googleOAuth ? { googleOAuth: deps.googleOAuth } : {}),
61
+ studioUrl: deps.studioUrl ?? 'http://localhost:5173',
62
+ localTrust: options.localTrust ?? deps.localTrust,
63
+ }));
64
+ }
65
+ if (deps.userRegistry) {
66
+ app.route('/users', createUsersRouter({
67
+ userRegistry: deps.userRegistry,
68
+ clock: deps.clock,
69
+ }));
70
+ }
71
+ if (deps.userRegistry && deps.accessPolicy && deps.workspaceRegistry) {
72
+ app.route('/admin', createAdminRouter({
73
+ userRegistry: deps.userRegistry,
74
+ accessPolicy: deps.accessPolicy,
75
+ workspaceRegistry: deps.workspaceRegistry,
76
+ workspaceService: deps.workspaceService,
77
+ }));
78
+ }
25
79
  app.route('/workspaces', createWorkspacesRouter({
26
80
  workspaceService: deps.workspaceService,
27
81
  sourceLoaderRunner: deps.sourceLoaderRunner,
82
+ workspacesRoot: deps.workspacesRoot,
83
+ ...(deps.bootstrap ? { bootstrap: deps.bootstrap } : {}),
84
+ ...(deps.workspaceRegistry ? { workspaceRegistry: deps.workspaceRegistry } : {}),
85
+ ...(deps.userRegistry ? { userRegistry: deps.userRegistry } : {}),
28
86
  }));
29
87
  app.route('/workspaces', createWorkspaceEventsRouter({ eventBus: deps.eventBus }));
30
- const workspaceScoped = new Hono();
88
+ // Server-level plugin discovery: lets Studio render its loader dropdown
89
+ // from the active PluginRegistry rather than hardcoded strings. Not
90
+ // workspace-scoped because the answer is "what does this server have
91
+ // installed", which is identical across workspaces.
92
+ app.route('/source-loaders', createSourceLoadersRouter({ pluginRegistry: deps.pluginRegistry }));
93
+ const workspaceScoped = new OpenAPIHono();
31
94
  workspaceScoped.use('*', workspaceIdMiddleware);
95
+ // Workspace membership gate. Mounted only when both the workspace
96
+ // registry and user registry are present (i.e. composeFsApp);
97
+ // in-memory tests that compose without these stay open so existing
98
+ // routes keep behaving.
99
+ if (deps.workspaceRegistry && deps.userRegistry) {
100
+ workspaceScoped.use('*', workspaceAccessMiddleware({
101
+ registry: deps.workspaceRegistry,
102
+ workspaceService: deps.workspaceService,
103
+ userRegistry: deps.userRegistry,
104
+ }));
105
+ }
32
106
  workspaceScoped.route('/model', createModelRouter({ modelService: deps.modelService }));
33
107
  workspaceScoped.route('/nodes', createNodesRouter({ modelService: deps.modelService }));
34
108
  workspaceScoped.route('/edges', createEdgesRouter({ modelService: deps.modelService }));
@@ -37,12 +111,17 @@ export function createApp(deps, options = {}) {
37
111
  proposalRepository: deps.proposalRepository,
38
112
  modelRepository: deps.modelRepository,
39
113
  validationService: deps.validationService,
114
+ workspaceService: deps.workspaceService,
40
115
  }));
41
116
  workspaceScoped.route('/clarify', createClarifyRouter({
42
117
  hitlService: deps.hitlService,
43
118
  clarifyRepository: deps.clarifyRepository,
119
+ decisionRepository: deps.decisionRepository,
44
120
  }));
45
121
  workspaceScoped.route('/decisions', createDecisionsRouter({ decisionRepository: deps.decisionRepository }));
122
+ workspaceScoped.route('/source-unit-states', createSourceUnitStatesRouter({
123
+ sourceUnitStateService: deps.sourceUnitStateService,
124
+ }));
46
125
  workspaceScoped.route('/ontology', createOntologyRouter({
47
126
  workspaceRepository: deps.workspaceRepository,
48
127
  pluginRegistry: deps.pluginRegistry,
@@ -59,6 +138,30 @@ export function createApp(deps, options = {}) {
59
138
  workspaceRepository: deps.workspaceRepository,
60
139
  }));
61
140
  }
141
+ if (deps.historyService) {
142
+ workspaceScoped.route('/history', createHistoryRouter({ historyService: deps.historyService }));
143
+ }
144
+ if (deps.batchService) {
145
+ workspaceScoped.route('/batch', createBatchRouter({ batchService: deps.batchService }));
146
+ }
147
+ workspaceScoped.route('/skill-input-options', createSkillInputOptionsRouter({
148
+ modelRepository: deps.modelRepository,
149
+ clarifyRepository: deps.clarifyRepository,
150
+ workspaceRepository: deps.workspaceRepository,
151
+ pluginRegistry: deps.pluginRegistry,
152
+ }));
153
+ if (deps.workspaceRegistry) {
154
+ workspaceScoped.route('/members', createWorkspaceMembersRouter({
155
+ workspaceService: deps.workspaceService,
156
+ registry: deps.workspaceRegistry,
157
+ clock: deps.clock,
158
+ }));
159
+ workspaceScoped.route('/transfer-ownership', createTransferOwnershipRouter({
160
+ workspaceService: deps.workspaceService,
161
+ registry: deps.workspaceRegistry,
162
+ clock: deps.clock,
163
+ }));
164
+ }
62
165
  app.route('/workspaces/:workspaceId', workspaceScoped);
63
166
  if (deps.secretStore) {
64
167
  app.route('/oauth', createOAuthRouter({
@@ -66,6 +169,21 @@ export function createApp(deps, options = {}) {
66
169
  ...(deps.googleOAuth ? { google: deps.googleOAuth } : {}),
67
170
  }));
68
171
  }
172
+ // OpenAPI 3 spec; consumed by openapi-mcp-gateway to surface REST
173
+ // operations as MCP tools. SSE routes and the OAuth HTML callback
174
+ // are intentionally absent — they're mounted via app.route() with
175
+ // plain Hono sub-routers so they don't register with the OpenAPI
176
+ // registry. The `servers[]` block lets the gateway resolve the
177
+ // upstream API base URL without an explicit --base-url flag.
178
+ app.doc('/openapi.json', {
179
+ openapi: '3.0.0',
180
+ info: {
181
+ title: 'Braid REST API',
182
+ version: '0.0.1',
183
+ description: 'REST surface exposed by @braidhq/server. Each operation also becomes an MCP tool via openapi-mcp-gateway.',
184
+ },
185
+ ...(options.apiUrl ? { servers: [{ url: options.apiUrl }] } : {}),
186
+ });
69
187
  return app;
70
188
  }
71
189
  //# sourceMappingURL=app.js.map
package/dist/app.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,7 @@
1
- import type { AgentEffort } from '@braidhq/schema';
1
+ import type { AgentPlugin, OntologyPlugin, SourceLoaderPlugin, StoragePlugin } from '@braidhq/core';
2
+ import type { AgentEffort, StorageKind } from '@braidhq/schema';
2
3
  import type { AppDependencies } from './composition.js';
4
+ import { AgentKind } from '@braidhq/schema';
3
5
  export interface ComposeFsOptions {
4
6
  /** Where to persist registered workspace paths. Default `$BRAID_HOME` or `~/.braid`. */
5
7
  readonly braidHome?: string;
@@ -9,12 +11,45 @@ export interface ComposeFsOptions {
9
11
  readonly agentModel?: string;
10
12
  /** Coding-agent effort tier (default `high`). */
11
13
  readonly agentEffort?: AgentEffort;
14
+ /**
15
+ * Graph storage backend kind. Resolved against the StoragePlugin
16
+ * registry; default `kuzu`. Set via `BRAID_STORAGE_KIND` env to swap
17
+ * (e.g. `neo4j` once `@braidhq/storage-neo4j` is registered).
18
+ */
19
+ readonly storageKind?: StorageKind;
20
+ /** Coding-agent kind to spawn skill subprocesses with. Default `claude-code`. */
21
+ readonly agentKind?: AgentKind;
22
+ /**
23
+ * Extra plugins to register alongside the defaults bundled with this
24
+ * composition. The defaults bundle is:
25
+ * - storage: `kuzuStoragePlugin`
26
+ * - ontology: `dddOntology`
27
+ * - source-loader: `gitLoader`, `createGithubLoader()`, `createGoogleDriveLoader()`
28
+ * (gdrive throws an actionable error at ingest if OAuth env is missing;
29
+ * github falls back to anonymous if `${GH_TOKEN}` is unset, subject to
30
+ * the 60 req/h public rate limit)
31
+ * - agent: `claudeCodeAgentPlugin`
32
+ *
33
+ * `composeFsApp` is the opinionated entry that ships with batteries.
34
+ * Callers who want a different bundle should use `composeApp` directly
35
+ * with their own pluginRegistry.
36
+ */
37
+ readonly extraStoragePlugins?: readonly StoragePlugin[];
38
+ readonly extraOntologyPlugins?: readonly OntologyPlugin[];
39
+ readonly extraSourceLoaderPlugins?: readonly SourceLoaderPlugin[];
40
+ readonly extraAgentPlugins?: readonly AgentPlugin[];
12
41
  }
13
42
  /**
14
- * Production composition root: real filesystem persistence for workspaces /
15
- * proposals / clarify / decisions, built-in skills loaded from `@braidhq/core`,
16
- * Claude Code subprocess agent. Model storage uses Kuzu (embedded, zero-infra)
17
- * per workspace at `<workspace>/.braid/model.kuzu`.
43
+ * Opinionated production composition: real filesystem persistence for
44
+ * workspaces / proposals / clarify / decisions, built-in skills loaded
45
+ * from `@braidhq/core`, and a batteries-included plugin bundle (Kuzu
46
+ * storage / DDD ontology / Git+GDrive source loaders / Claude Code
47
+ * agent).
48
+ *
49
+ * To run with a different plugin set, either:
50
+ * 1. Pass `extraXxxPlugins` to add alongside defaults + flip `storageKind`
51
+ * / `agentKind` to pick a different active one, OR
52
+ * 2. Call `composeApp` directly with a `pluginRegistry` you built yourself.
18
53
  */
19
- export declare function composeFsApp(options?: ComposeFsOptions): AppDependencies;
54
+ export declare function composeFsApp(options?: ComposeFsOptions): Promise<AppDependencies>;
20
55
  //# sourceMappingURL=composeFs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"composeFs.d.ts","sourceRoot":"","sources":["../src/composeFs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,WAAW,EAAmC,MAAM,iBAAiB,CAAA;AACjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AA+BvD,MAAM,WAAW,gBAAgB;IAC/B,wFAAwF;IACxF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,qDAAqD;IACrD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,iDAAiD;IACjD,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAA;CACnC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,gBAAqB,GAAG,eAAe,CA4H5E"}
1
+ {"version":3,"file":"composeFs.d.ts","sourceRoot":"","sources":["../src/composeFs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AACnG,OAAO,KAAK,EAAgB,WAAW,EAAE,WAAW,EAAe,MAAM,iBAAiB,CAAA;AAC1F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAiBvD,OAAO,EAAW,SAAS,EAAoC,MAAM,iBAAiB,CAAA;AAgCtF,MAAM,WAAW,gBAAgB;IAC/B,wFAAwF;IACxF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,qDAAqD;IACrD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,iDAAiD;IACjD,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAA;IAClC;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAA;IAClC,iFAAiF;IACjF,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAA;IAE9B;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,SAAS,aAAa,EAAE,CAAA;IACvD,QAAQ,CAAC,oBAAoB,CAAC,EAAE,SAAS,cAAc,EAAE,CAAA;IACzD,QAAQ,CAAC,wBAAwB,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACjE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;CACpD;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAyR3F"}