@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
@@ -1,39 +1,109 @@
1
- import { SkillId as SkillIdSchema } from '@braidhq/schema';
2
- import { zValidator } from '@hono/zod-validator';
3
- import { Hono } from 'hono';
4
- import { z } from 'zod';
1
+ import { SkillId as SkillIdSchema, SkillManifest, SkillRunId } from '@braidhq/schema';
2
+ import { createRoute, OpenAPIHono, z } from '@hono/zod-openapi';
3
+ import { extractBearerToken } from '../middleware/auth.js';
4
+ import { requirePermission } from '../middleware/workspaceAccess.js';
5
5
  import { getWorkspaceId } from '../middleware/workspaceId.js';
6
+ import { NotFoundResponse, WorkspaceIdParam } from './_shared.js';
6
7
  import { loadWorkspaceById } from './helpers.js';
7
- const RunBodySchema = z.object({
8
+ const RunBody = z.object({
8
9
  args: z.string().default(''),
9
10
  /** Continue an existing claude conversation (from a prior session-started event). */
10
11
  resumeSessionId: z.string().min(1).optional(),
12
+ }).openapi('SkillRunBody');
13
+ const SkillIdParam = WorkspaceIdParam.extend({
14
+ skillId: SkillIdSchema.openapi({ param: { name: 'skillId', in: 'path' } }),
15
+ });
16
+ const SkillListResponse = z.object({
17
+ items: z.array(SkillManifest),
18
+ }).openapi('SkillListResponse');
19
+ const RunCreatedResponse = z.object({
20
+ runId: SkillRunId,
21
+ }).openapi('RunCreatedResponse');
22
+ const listSkillsRoute = createRoute({
23
+ method: 'get',
24
+ path: '/',
25
+ operationId: 'listSkills',
26
+ summary: 'List skills available in a workspace (builtin + plugin + workspace + extension overlays).',
27
+ tags: ['skills'],
28
+ request: { params: WorkspaceIdParam },
29
+ responses: {
30
+ 200: {
31
+ description: 'The skill list.',
32
+ content: { 'application/json': { schema: SkillListResponse } },
33
+ },
34
+ },
35
+ });
36
+ const getSkillRoute = createRoute({
37
+ method: 'get',
38
+ path: '/{skillId}',
39
+ operationId: 'getSkill',
40
+ summary: 'Fetch a single skill manifest by id.',
41
+ tags: ['skills'],
42
+ request: { params: SkillIdParam },
43
+ responses: {
44
+ 200: {
45
+ description: 'The skill manifest.',
46
+ content: { 'application/json': { schema: SkillManifest } },
47
+ },
48
+ 404: NotFoundResponse,
49
+ },
50
+ });
51
+ const runSkillRoute = createRoute({
52
+ method: 'post',
53
+ path: '/{skillId}/run',
54
+ operationId: 'runSkill',
55
+ summary: 'Fire-and-forget run of a skill. Returns the runId to subscribe to via SSE.',
56
+ description: 'The subprocess + event drain runs in the background; events are persisted to JSONL and broadcast to subscribers regardless of whether the client stays connected. Tail progress via GET /workspaces/{workspaceId}/runs/{runId}/events.',
57
+ tags: ['skills'],
58
+ request: {
59
+ params: SkillIdParam,
60
+ body: { content: { 'application/json': { schema: RunBody } } },
61
+ },
62
+ responses: {
63
+ 202: {
64
+ description: 'The accepted run id.',
65
+ content: { 'application/json': { schema: RunCreatedResponse } },
66
+ },
67
+ 403: {
68
+ description: 'Caller is not permitted to run this skill in this workspace.',
69
+ content: { 'application/problem+json': { schema: z.object({}).passthrough() } },
70
+ },
71
+ 404: NotFoundResponse,
72
+ },
11
73
  });
12
74
  export function createSkillsRouter(deps) {
13
- const router = new Hono();
14
- router.get('/', async (context) => {
75
+ const router = new OpenAPIHono();
76
+ // skill.run is the only capability that needs a per-request resource
77
+ // (the skill manifest). The resource builder fetches the workspace +
78
+ // manifest once and hands the result to the policy check.
79
+ router.use('/:skillId/run', requirePermission('skill.run', async (context) => {
80
+ const workspace = await loadWorkspaceById(getWorkspaceId(context), deps.workspaceRepository);
81
+ const skillId = SkillIdSchema.parse(context.req.param('skillId'));
82
+ const manifest = await deps.skillRegistry.get(workspace, skillId);
83
+ return { skill: manifest.toData().frontmatter, skillId };
84
+ }));
85
+ router.openapi(listSkillsRoute, async (context) => {
15
86
  const workspace = await loadWorkspaceById(getWorkspaceId(context), deps.workspaceRepository);
16
87
  const manifests = await deps.skillRegistry.list(workspace);
17
88
  return context.json({
18
89
  items: manifests.map(manifest => manifest.toData()),
19
- });
90
+ }, 200);
20
91
  });
21
- router.get('/:skillId', async (context) => {
92
+ router.openapi(getSkillRoute, async (context) => {
22
93
  const workspace = await loadWorkspaceById(getWorkspaceId(context), deps.workspaceRepository);
23
- const skillId = SkillIdSchema.parse(context.req.param('skillId'));
94
+ const { skillId } = context.req.valid('param');
24
95
  const manifest = await deps.skillRegistry.get(workspace, skillId);
25
- return context.json(manifest.toData());
96
+ return context.json(manifest.toData(), 200);
26
97
  });
27
- // Fire-and-forget run. The subprocess + event drain runs in the background;
28
- // events are persisted to JSONL and broadcast to subscribers regardless of
29
- // whether the client stays connected. The client tails progress via
30
- // `GET /workspaces/:ws/runs/:runId/events`, which can be opened and closed
31
- // freely without affecting the run.
32
- router.post('/:skillId/run', zValidator('json', RunBodySchema), async (context) => {
98
+ router.openapi(runSkillRoute, async (context) => {
33
99
  const workspace = await loadWorkspaceById(getWorkspaceId(context), deps.workspaceRepository);
34
- const skillId = SkillIdSchema.parse(context.req.param('skillId'));
100
+ const { skillId } = context.req.valid('param');
35
101
  const { args, resumeSessionId } = context.req.valid('json');
36
- const options = resumeSessionId ? { resumeSessionId } : undefined;
102
+ const callerToken = extractBearerToken(context);
103
+ const options = {
104
+ ...(resumeSessionId ? { resumeSessionId } : {}),
105
+ ...(callerToken ? { callerToken } : {}),
106
+ };
37
107
  const runId = await deps.skillRunner.start(workspace, skillId, args, options);
38
108
  return context.json({ runId }, 202);
39
109
  });
@@ -1 +1 @@
1
- {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/routes/skills.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/routes/skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { PluginRegistry } from '@braidhq/core';
2
+ import { OpenAPIHono } from '@hono/zod-openapi';
3
+ export interface SourceLoadersRouterDeps {
4
+ pluginRegistry: PluginRegistry;
5
+ }
6
+ export declare function createSourceLoadersRouter(deps: SourceLoadersRouterDeps): OpenAPIHono;
7
+ //# sourceMappingURL=sourceLoaders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceLoaders.d.ts","sourceRoot":"","sources":["../../src/routes/sourceLoaders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAEnD,OAAO,EAAe,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE5D,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,cAAc,CAAA;CAC/B;AAiBD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,uBAAuB,GAAG,WAAW,CAapF"}
@@ -0,0 +1,29 @@
1
+ import { ListSourceLoadersResponse } from '@braidhq/schema';
2
+ import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
3
+ const listSourceLoadersRoute = createRoute({
4
+ method: 'get',
5
+ path: '/',
6
+ operationId: 'listSourceLoaders',
7
+ summary: 'List source-loader plugins registered on this server.',
8
+ description: 'Studio uses this to populate its loader dropdown without hardcoding `git / github / gdrive`. The list reflects what `composeFsApp` registered plus any `extraSourceLoaderPlugins` the caller passed in. The `manual` choice in the Studio UI is not a plugin and is not returned here.',
9
+ tags: ['plugins'],
10
+ responses: {
11
+ 200: {
12
+ description: 'Source-loader plugins currently registered.',
13
+ content: { 'application/json': { schema: ListSourceLoadersResponse } },
14
+ },
15
+ },
16
+ });
17
+ export function createSourceLoadersRouter(deps) {
18
+ const router = new OpenAPIHono();
19
+ router.openapi(listSourceLoadersRoute, (context) => {
20
+ const plugins = deps.pluginRegistry.sourceLoaders();
21
+ const loaders = plugins.map(plugin => ({
22
+ kind: plugin.kind,
23
+ pluginId: plugin.id,
24
+ }));
25
+ return context.json(ListSourceLoadersResponse.parse({ loaders }), 200);
26
+ });
27
+ return router;
28
+ }
29
+ //# sourceMappingURL=sourceLoaders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceLoaders.js","sourceRoot":"","sources":["../../src/routes/sourceLoaders.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAM5D,MAAM,sBAAsB,GAAG,WAAW,CAAC;IACzC,MAAM,EAAE,KAAK;IACb,IAAI,EAAE,GAAG;IACT,WAAW,EAAE,mBAAmB;IAChC,OAAO,EAAE,uDAAuD;IAChE,WAAW,EAAE,wRAAwR;IACrS,IAAI,EAAE,CAAC,SAAS,CAAC;IACjB,SAAS,EAAE;QACT,GAAG,EAAE;YACH,WAAW,EAAE,6CAA6C;YAC1D,OAAO,EAAE,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,yBAAyB,EAAE,EAAE;SACvE;KACF;CACF,CAAC,CAAA;AAEF,MAAM,UAAU,yBAAyB,CAAC,IAA6B;IACrE,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAA;IAEhC,MAAM,CAAC,OAAO,CAAC,sBAAsB,EAAE,CAAC,OAAO,EAAE,EAAE;QACjD,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,CAAA;QACnD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACrC,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,QAAQ,EAAE,MAAM,CAAC,EAAE;SACpB,CAAC,CAAC,CAAA;QACH,OAAO,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,CAAC,CAAA;IACxE,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { SourceUnitStateService } from '@braidhq/core';
2
+ import { OpenAPIHono } from '@hono/zod-openapi';
3
+ export interface SourceUnitStatesRouterDeps {
4
+ sourceUnitStateService: SourceUnitStateService;
5
+ }
6
+ export declare function createSourceUnitStatesRouter(deps: SourceUnitStatesRouterDeps): OpenAPIHono;
7
+ //# sourceMappingURL=sourceUnitStates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceUnitStates.d.ts","sourceRoot":"","sources":["../../src/routes/sourceUnitStates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAE3D,OAAO,EAAe,WAAW,EAAK,MAAM,mBAAmB,CAAA;AAY/D,MAAM,WAAW,0BAA0B;IACzC,sBAAsB,EAAE,sBAAsB,CAAA;CAC/C;AAyBD,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,0BAA0B,GAAG,WAAW,CAa1F"}
@@ -0,0 +1,45 @@
1
+ import { SourceId, SourceUnitState } from '@braidhq/schema';
2
+ import { createRoute, OpenAPIHono, z } from '@hono/zod-openapi';
3
+ import { getWorkspaceId } from '../middleware/workspaceId.js';
4
+ import { ValidationFailureResponse, WorkspaceIdParam } from './_shared.js';
5
+ const ListQuery = z.object({
6
+ sourceId: SourceId.optional().openapi({ description: 'Restrict to one source.' }),
7
+ });
8
+ const ListResponse = z.object({
9
+ items: z.array(SourceUnitState),
10
+ }).openapi('SourceUnitStateListResponse');
11
+ const listRoute = createRoute({
12
+ method: 'get',
13
+ path: '/',
14
+ operationId: 'listSourceUnitStates',
15
+ summary: 'List recorded observations per source unit for a workspace.',
16
+ description: 'Returns the framework\'s current view of each source unit '
17
+ + 'last seen by an extract run. One entry per (sourceId, path). Used '
18
+ + 'by Studio to display per-unit freshness and by Reactor to compute '
19
+ + 'what needs re-extraction.',
20
+ tags: ['source-unit-states'],
21
+ request: {
22
+ params: WorkspaceIdParam,
23
+ query: ListQuery,
24
+ },
25
+ responses: {
26
+ 200: {
27
+ description: 'The recorded observations.',
28
+ content: { 'application/json': { schema: ListResponse } },
29
+ },
30
+ 400: ValidationFailureResponse,
31
+ },
32
+ });
33
+ export function createSourceUnitStatesRouter(deps) {
34
+ const router = new OpenAPIHono();
35
+ router.openapi(listRoute, async (context) => {
36
+ const workspaceId = getWorkspaceId(context);
37
+ const { sourceId } = context.req.valid('query');
38
+ const items = sourceId
39
+ ? await deps.sourceUnitStateService.listBySource(workspaceId, sourceId)
40
+ : await deps.sourceUnitStateService.listByWorkspace(workspaceId);
41
+ return context.json({ items: [...items] }, 200);
42
+ });
43
+ return router;
44
+ }
45
+ //# sourceMappingURL=sourceUnitStates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceUnitStates.js","sourceRoot":"","sources":["../../src/routes/sourceUnitStates.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAE1E,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC;CAClF,CAAC,CAAA;AAEF,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC;CAChC,CAAC,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAA;AAMzC,MAAM,SAAS,GAAG,WAAW,CAAC;IAC5B,MAAM,EAAE,KAAK;IACb,IAAI,EAAE,GAAG;IACT,WAAW,EAAE,sBAAsB;IACnC,OAAO,EAAE,6DAA6D;IACtE,WAAW,EAAE,4DAA4D;UACrE,oEAAoE;UACpE,oEAAoE;UACpE,2BAA2B;IAC/B,IAAI,EAAE,CAAC,oBAAoB,CAAC;IAC5B,OAAO,EAAE;QACP,MAAM,EAAE,gBAAgB;QACxB,KAAK,EAAE,SAAS;KACjB;IACD,SAAS,EAAE;QACT,GAAG,EAAE;YACH,WAAW,EAAE,4BAA4B;YACzC,OAAO,EAAE,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE;SAC1D;QACD,GAAG,EAAE,yBAAyB;KAC/B;CACF,CAAC,CAAA;AAEF,MAAM,UAAU,4BAA4B,CAAC,IAAgC;IAC3E,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAA;IAEhC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC1C,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QAC3C,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAC/C,MAAM,KAAK,GAAG,QAAQ;YACpB,CAAC,CAAC,MAAM,IAAI,CAAC,sBAAsB,CAAC,YAAY,CAAC,WAAW,EAAE,QAAQ,CAAC;YACvE,CAAC,CAAC,MAAM,IAAI,CAAC,sBAAsB,CAAC,eAAe,CAAC,WAAW,CAAC,CAAA;QAClE,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;IACjD,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { Clock } from '@braidhq/core';
2
+ import type { UserRegistryFile } from '../infrastructure/users/UserRegistryFile.js';
3
+ import { OpenAPIHono } from '@hono/zod-openapi';
4
+ export interface UsersRouterDeps {
5
+ userRegistry: UserRegistryFile;
6
+ clock: Clock;
7
+ }
8
+ export declare function createUsersRouter(deps: UsersRouterDeps): OpenAPIHono;
9
+ //# sourceMappingURL=users.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../src/routes/users.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAA;AAGnF,OAAO,EAAe,WAAW,EAAK,MAAM,mBAAmB,CAAA;AAY/D,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,gBAAgB,CAAA;IAC9B,KAAK,EAAE,KAAK,CAAA;CACb;AAoFD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,WAAW,CA2CpE"}
@@ -0,0 +1,127 @@
1
+ import { newUserId, NotFoundError } from '@braidhq/core';
2
+ import { User, UserDraft, UserId, UserPatch } from '@braidhq/schema';
3
+ import { createRoute, OpenAPIHono, z } from '@hono/zod-openapi';
4
+ import { getUserId } from '../middleware/userId.js';
5
+ import { NotFoundResponse, ValidationFailureResponse } from './_shared.js';
6
+ const UserIdParam = z.object({
7
+ userId: UserId.openapi({ param: { name: 'userId', in: 'path' } }),
8
+ });
9
+ const UserListResponse = z.object({
10
+ items: z.array(User),
11
+ }).openapi('UserListResponse');
12
+ const listUsersRoute = createRoute({
13
+ method: 'get',
14
+ path: '/',
15
+ operationId: 'listUsers',
16
+ summary: 'List all users on this server.',
17
+ tags: ['users'],
18
+ responses: {
19
+ 200: {
20
+ description: 'A list of users.',
21
+ content: { 'application/json': { schema: UserListResponse } },
22
+ },
23
+ },
24
+ });
25
+ const getMeRoute = createRoute({
26
+ method: 'get',
27
+ path: '/me',
28
+ operationId: 'getMe',
29
+ summary: 'Return the user identified by the current request context.',
30
+ tags: ['users'],
31
+ responses: {
32
+ 200: {
33
+ description: 'The current user.',
34
+ content: { 'application/json': { schema: User } },
35
+ },
36
+ 404: NotFoundResponse,
37
+ },
38
+ });
39
+ const getUserRoute = createRoute({
40
+ method: 'get',
41
+ path: '/{userId}',
42
+ operationId: 'getUser',
43
+ summary: 'Fetch a single user by id.',
44
+ tags: ['users'],
45
+ request: { params: UserIdParam },
46
+ responses: {
47
+ 200: {
48
+ description: 'The requested user.',
49
+ content: { 'application/json': { schema: User } },
50
+ },
51
+ 404: NotFoundResponse,
52
+ },
53
+ });
54
+ const createUserRoute = createRoute({
55
+ method: 'post',
56
+ path: '/',
57
+ operationId: 'createUser',
58
+ summary: 'Create a user. Phase A: any caller; Phase B/C will gate by Admin role.',
59
+ tags: ['users'],
60
+ request: {
61
+ body: { content: { 'application/json': { schema: UserDraft } } },
62
+ },
63
+ responses: {
64
+ 201: {
65
+ description: 'The created user.',
66
+ content: { 'application/json': { schema: User } },
67
+ },
68
+ 400: ValidationFailureResponse,
69
+ },
70
+ });
71
+ const updateUserRoute = createRoute({
72
+ method: 'patch',
73
+ path: '/{userId}',
74
+ operationId: 'updateUser',
75
+ summary: 'Patch a user record. Phase A: any caller; Phase B/C will gate by Admin role.',
76
+ tags: ['users'],
77
+ request: {
78
+ params: UserIdParam,
79
+ body: { content: { 'application/json': { schema: UserPatch } } },
80
+ },
81
+ responses: {
82
+ 200: {
83
+ description: 'The updated user.',
84
+ content: { 'application/json': { schema: User } },
85
+ },
86
+ 404: NotFoundResponse,
87
+ },
88
+ });
89
+ export function createUsersRouter(deps) {
90
+ const router = new OpenAPIHono();
91
+ router.openapi(listUsersRoute, async (context) => {
92
+ const users = await deps.userRegistry.list();
93
+ return context.json({ items: users }, 200);
94
+ });
95
+ router.openapi(getMeRoute, async (context) => {
96
+ const userId = getUserId(context);
97
+ const user = await deps.userRegistry.get(userId);
98
+ if (!user)
99
+ throw new NotFoundError(`Current user "${userId}" not found in registry`);
100
+ return context.json(user, 200);
101
+ });
102
+ router.openapi(getUserRoute, async (context) => {
103
+ const { userId } = context.req.valid('param');
104
+ const user = await deps.userRegistry.get(userId);
105
+ if (!user)
106
+ throw new NotFoundError(`User "${userId}" not found`);
107
+ return context.json(user, 200);
108
+ });
109
+ router.openapi(createUserRoute, async (context) => {
110
+ const draft = context.req.valid('json');
111
+ const created = await deps.userRegistry.create({
112
+ id: newUserId(),
113
+ ...draft,
114
+ serverRole: draft.serverRole ?? 'user',
115
+ createdAt: deps.clock.now(),
116
+ });
117
+ return context.json(created, 201);
118
+ });
119
+ router.openapi(updateUserRoute, async (context) => {
120
+ const { userId } = context.req.valid('param');
121
+ const patch = context.req.valid('json');
122
+ const updated = await deps.userRegistry.update(userId, patch);
123
+ return context.json(updated, 200);
124
+ });
125
+ return router;
126
+ }
127
+ //# sourceMappingURL=users.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/routes/users.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { Clock, WorkspaceService } from '@braidhq/core';
2
+ import type { WorkspaceRegistryFile } from '../infrastructure/fs/WorkspaceRegistryFile.js';
3
+ import { Hono } from 'hono';
4
+ export interface WorkspaceMembersRouterDeps {
5
+ workspaceService: WorkspaceService;
6
+ registry: WorkspaceRegistryFile;
7
+ clock: Clock;
8
+ }
9
+ export declare function createWorkspaceMembersRouter(deps: WorkspaceMembersRouterDeps): Hono;
10
+ export declare function createTransferOwnershipRouter(deps: WorkspaceMembersRouterDeps): Hono;
11
+ //# sourceMappingURL=workspaceMembers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaceMembers.d.ts","sourceRoot":"","sources":["../../src/routes/workspaceMembers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAE5D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+CAA+C,CAAA;AAI1F,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAqB3B,MAAM,WAAW,0BAA0B;IACzC,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,QAAQ,EAAE,qBAAqB,CAAA;IAC/B,KAAK,EAAE,KAAK,CAAA;CACb;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,0BAA0B,GAAG,IAAI,CAoDnF;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,0BAA0B,GAAG,IAAI,CAWpF"}
@@ -0,0 +1,81 @@
1
+ import { NotFoundError } from '@braidhq/core';
2
+ import { SkillPermission, UserId, WorkspaceRole } from '@braidhq/schema';
3
+ import { zValidator } from '@hono/zod-validator';
4
+ import { Hono } from 'hono';
5
+ import { z } from 'zod';
6
+ import { requirePermission } from '../middleware/workspaceAccess.js';
7
+ import { getWorkspaceId } from '../middleware/workspaceId.js';
8
+ const AddMemberBody = z.object({
9
+ userId: UserId,
10
+ role: WorkspaceRole.default('guest'),
11
+ });
12
+ const PatchMemberBody = z.object({
13
+ role: WorkspaceRole.optional(),
14
+ skillOverrides: z.record(z.string().min(1), SkillPermission).optional(),
15
+ }).refine(body => Object.keys(body).length > 0, {
16
+ message: 'PATCH body must include role and/or skillOverrides',
17
+ });
18
+ const TransferBody = z.object({
19
+ newOwnerId: UserId,
20
+ });
21
+ export function createWorkspaceMembersRouter(deps) {
22
+ const router = new Hono();
23
+ const ownerOnly = requirePermission('workspace.write');
24
+ // List is open to every member of the workspace. The access
25
+ // middleware upstream already enforced membership.
26
+ router.get('/', async (context) => {
27
+ const workspaceId = getWorkspaceId(context);
28
+ const workspace = await deps.workspaceService.findById(workspaceId);
29
+ const members = await deps.registry.listMembers(workspace.rootPath);
30
+ return context.json({ items: members });
31
+ });
32
+ router.post('/', ownerOnly, zValidator('json', AddMemberBody), async (context) => {
33
+ const workspaceId = getWorkspaceId(context);
34
+ const { userId, role } = context.req.valid('json');
35
+ const workspace = await deps.workspaceService.findById(workspaceId);
36
+ const member = {
37
+ userId,
38
+ role,
39
+ joinedAt: deps.clock.now(),
40
+ };
41
+ await deps.registry.addMember(workspace.rootPath, member);
42
+ return context.json(member, 201);
43
+ });
44
+ router.patch('/:memberUserId', ownerOnly, zValidator('json', PatchMemberBody), async (context) => {
45
+ const workspaceId = getWorkspaceId(context);
46
+ const memberUserId = UserId.parse(context.req.param('memberUserId'));
47
+ const patch = context.req.valid('json');
48
+ const workspace = await deps.workspaceService.findById(workspaceId);
49
+ const next = await deps.registry.updateMember(workspace.rootPath, memberUserId, {
50
+ ...(patch.role ? { role: patch.role } : {}),
51
+ ...(patch.skillOverrides
52
+ ? { skillOverrides: patch.skillOverrides }
53
+ : {}),
54
+ });
55
+ return context.json(next);
56
+ });
57
+ router.delete('/:memberUserId', ownerOnly, async (context) => {
58
+ const workspaceId = getWorkspaceId(context);
59
+ const memberUserId = UserId.parse(context.req.param('memberUserId'));
60
+ const workspace = await deps.workspaceService.findById(workspaceId);
61
+ const exists = await deps.registry.getMember(workspace.rootPath, memberUserId);
62
+ if (!exists)
63
+ throw new NotFoundError(`User "${memberUserId}" is not a member of this workspace`);
64
+ await deps.registry.removeMember(workspace.rootPath, memberUserId);
65
+ return context.body(null, 204);
66
+ });
67
+ return router;
68
+ }
69
+ export function createTransferOwnershipRouter(deps) {
70
+ const router = new Hono();
71
+ router.post('/', requirePermission('workspace.write'), zValidator('json', TransferBody), async (context) => {
72
+ const workspaceId = getWorkspaceId(context);
73
+ const { newOwnerId } = context.req.valid('json');
74
+ const workspace = await deps.workspaceService.findById(workspaceId);
75
+ await deps.registry.transferOwnership(workspace.rootPath, newOwnerId);
76
+ const members = await deps.registry.listMembers(workspace.rootPath);
77
+ return context.json({ items: members });
78
+ });
79
+ return router;
80
+ }
81
+ //# sourceMappingURL=workspaceMembers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaceMembers.js","sourceRoot":"","sources":["../../src/routes/workspaceMembers.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,26 @@
1
- import type { SourceLoaderRunner, WorkspaceService } from '@braidhq/core';
1
+ import type { SourceLoaderRunner, WorkspaceBootstrap, WorkspaceService } from '@braidhq/core';
2
+ import type { AbsolutePath } from '@braidhq/schema';
3
+ import type { WorkspaceRegistryFile } from '../infrastructure/fs/WorkspaceRegistryFile.js';
4
+ import type { UserRegistryFile } from '../infrastructure/users/UserRegistryFile.js';
2
5
  import { Hono } from 'hono';
3
6
  export interface WorkspacesRouterDeps {
4
7
  workspaceService: WorkspaceService;
5
8
  sourceLoaderRunner: SourceLoaderRunner;
9
+ workspacesRoot: AbsolutePath;
10
+ bootstrap?: WorkspaceBootstrap;
11
+ /**
12
+ * Optional: when present, `GET /workspaces` filters to ones the
13
+ * current user is a member of, and newly registered workspaces
14
+ * stamp the caller as owner. Absent in tests that don't exercise
15
+ * membership.
16
+ */
17
+ workspaceRegistry?: WorkspaceRegistryFile;
18
+ /**
19
+ * Optional: when present, server admins see every workspace
20
+ * regardless of membership. Without this, only direct membership
21
+ * controls visibility.
22
+ */
23
+ userRegistry?: UserRegistryFile;
6
24
  }
7
25
  export declare function createWorkspacesRouter(deps: WorkspacesRouterDeps): Hono;
8
26
  //# sourceMappingURL=workspaces.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../../src/routes/workspaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAa,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAiBpF,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAwB3B,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,kBAAkB,EAAE,kBAAkB,CAAA;CACvC;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAuIvE"}
1
+ {"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../../src/routes/workspaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAa,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACxG,OAAO,KAAK,EAAE,YAAY,EAAgD,MAAM,iBAAiB,CAAA;AAEjG,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+CAA+C,CAAA;AAC1F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAA;AAenF,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAwC3B,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,kBAAkB,EAAE,kBAAkB,CAAA;IACtC,cAAc,EAAE,YAAY,CAAA;IAC5B,SAAS,CAAC,EAAE,kBAAkB,CAAA;IAC9B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,qBAAqB,CAAA;IACzC;;;;OAIG;IACH,YAAY,CAAC,EAAE,gBAAgB,CAAA;CAChC;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI,CA0OvE"}