@braidhq/server 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/LICENSE +21 -0
  2. package/dist/app.d.ts +7 -0
  3. package/dist/app.d.ts.map +1 -0
  4. package/dist/app.js +71 -0
  5. package/dist/app.js.map +1 -0
  6. package/dist/composeFs.d.ts +20 -0
  7. package/dist/composeFs.d.ts.map +1 -0
  8. package/dist/composeFs.js +134 -0
  9. package/dist/composeFs.js.map +1 -0
  10. package/dist/composition.d.ts +49 -0
  11. package/dist/composition.d.ts.map +1 -0
  12. package/dist/composition.js +43 -0
  13. package/dist/composition.js.map +1 -0
  14. package/dist/index.d.ts +5 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +5 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/infrastructure/agent/ClaudeCodeAgentBinding.d.ts +8 -0
  19. package/dist/infrastructure/agent/ClaudeCodeAgentBinding.d.ts.map +1 -0
  20. package/dist/infrastructure/agent/ClaudeCodeAgentBinding.js +62 -0
  21. package/dist/infrastructure/agent/ClaudeCodeAgentBinding.js.map +1 -0
  22. package/dist/infrastructure/agent/SubprocessSkillRunner.d.ts +54 -0
  23. package/dist/infrastructure/agent/SubprocessSkillRunner.d.ts.map +1 -0
  24. package/dist/infrastructure/agent/SubprocessSkillRunner.js +240 -0
  25. package/dist/infrastructure/agent/SubprocessSkillRunner.js.map +1 -0
  26. package/dist/infrastructure/agent/asyncQueue.d.ts +22 -0
  27. package/dist/infrastructure/agent/asyncQueue.d.ts.map +1 -0
  28. package/dist/infrastructure/agent/asyncQueue.js +43 -0
  29. package/dist/infrastructure/agent/asyncQueue.js.map +1 -0
  30. package/dist/infrastructure/agent/mcpConfig.d.ts +18 -0
  31. package/dist/infrastructure/agent/mcpConfig.d.ts.map +1 -0
  32. package/dist/infrastructure/agent/mcpConfig.js +47 -0
  33. package/dist/infrastructure/agent/mcpConfig.js.map +1 -0
  34. package/dist/infrastructure/agent/streamJsonParser.d.ts +20 -0
  35. package/dist/infrastructure/agent/streamJsonParser.d.ts.map +1 -0
  36. package/dist/infrastructure/agent/streamJsonParser.js +44 -0
  37. package/dist/infrastructure/agent/streamJsonParser.js.map +1 -0
  38. package/dist/infrastructure/agent/subprocessEventStream.d.ts +26 -0
  39. package/dist/infrastructure/agent/subprocessEventStream.d.ts.map +1 -0
  40. package/dist/infrastructure/agent/subprocessEventStream.js +112 -0
  41. package/dist/infrastructure/agent/subprocessEventStream.js.map +1 -0
  42. package/dist/infrastructure/fs/FsClarifyTicketRepository.d.ts +13 -0
  43. package/dist/infrastructure/fs/FsClarifyTicketRepository.d.ts.map +1 -0
  44. package/dist/infrastructure/fs/FsClarifyTicketRepository.js +33 -0
  45. package/dist/infrastructure/fs/FsClarifyTicketRepository.js.map +1 -0
  46. package/dist/infrastructure/fs/FsDecisionRepository.d.ts +13 -0
  47. package/dist/infrastructure/fs/FsDecisionRepository.d.ts.map +1 -0
  48. package/dist/infrastructure/fs/FsDecisionRepository.js +56 -0
  49. package/dist/infrastructure/fs/FsDecisionRepository.js.map +1 -0
  50. package/dist/infrastructure/fs/FsProposalRepository.d.ts +14 -0
  51. package/dist/infrastructure/fs/FsProposalRepository.d.ts.map +1 -0
  52. package/dist/infrastructure/fs/FsProposalRepository.js +40 -0
  53. package/dist/infrastructure/fs/FsProposalRepository.js.map +1 -0
  54. package/dist/infrastructure/fs/FsRunRepository.d.ts +21 -0
  55. package/dist/infrastructure/fs/FsRunRepository.d.ts.map +1 -0
  56. package/dist/infrastructure/fs/FsRunRepository.js +88 -0
  57. package/dist/infrastructure/fs/FsRunRepository.js.map +1 -0
  58. package/dist/infrastructure/fs/FsSkillRegistry.d.ts +34 -0
  59. package/dist/infrastructure/fs/FsSkillRegistry.d.ts.map +1 -0
  60. package/dist/infrastructure/fs/FsSkillRegistry.js +143 -0
  61. package/dist/infrastructure/fs/FsSkillRegistry.js.map +1 -0
  62. package/dist/infrastructure/fs/FsStatusedJsonRepository.d.ts +35 -0
  63. package/dist/infrastructure/fs/FsStatusedJsonRepository.d.ts.map +1 -0
  64. package/dist/infrastructure/fs/FsStatusedJsonRepository.js +79 -0
  65. package/dist/infrastructure/fs/FsStatusedJsonRepository.js.map +1 -0
  66. package/dist/infrastructure/fs/FsWorkspaceRepository.d.ts +21 -0
  67. package/dist/infrastructure/fs/FsWorkspaceRepository.d.ts.map +1 -0
  68. package/dist/infrastructure/fs/FsWorkspaceRepository.js +87 -0
  69. package/dist/infrastructure/fs/FsWorkspaceRepository.js.map +1 -0
  70. package/dist/infrastructure/fs/WorkspaceRegistryFile.d.ts +17 -0
  71. package/dist/infrastructure/fs/WorkspaceRegistryFile.d.ts.map +1 -0
  72. package/dist/infrastructure/fs/WorkspaceRegistryFile.js +58 -0
  73. package/dist/infrastructure/fs/WorkspaceRegistryFile.js.map +1 -0
  74. package/dist/infrastructure/fs/frontmatter.d.ts +13 -0
  75. package/dist/infrastructure/fs/frontmatter.d.ts.map +1 -0
  76. package/dist/infrastructure/fs/frontmatter.js +46 -0
  77. package/dist/infrastructure/fs/frontmatter.js.map +1 -0
  78. package/dist/infrastructure/fs/jsonFileStore.d.ts +5 -0
  79. package/dist/infrastructure/fs/jsonFileStore.d.ts.map +1 -0
  80. package/dist/infrastructure/fs/jsonFileStore.js +29 -0
  81. package/dist/infrastructure/fs/jsonFileStore.js.map +1 -0
  82. package/dist/infrastructure/fs/paths.d.ts +22 -0
  83. package/dist/infrastructure/fs/paths.d.ts.map +1 -0
  84. package/dist/infrastructure/fs/paths.js +46 -0
  85. package/dist/infrastructure/fs/paths.js.map +1 -0
  86. package/dist/infrastructure/fs/productManifestWriter.d.ts +22 -0
  87. package/dist/infrastructure/fs/productManifestWriter.d.ts.map +1 -0
  88. package/dist/infrastructure/fs/productManifestWriter.js +75 -0
  89. package/dist/infrastructure/fs/productManifestWriter.js.map +1 -0
  90. package/dist/infrastructure/oauth/GoogleOAuth.d.ts +60 -0
  91. package/dist/infrastructure/oauth/GoogleOAuth.d.ts.map +1 -0
  92. package/dist/infrastructure/oauth/GoogleOAuth.js +114 -0
  93. package/dist/infrastructure/oauth/GoogleOAuth.js.map +1 -0
  94. package/dist/infrastructure/orphanReaper.d.ts +18 -0
  95. package/dist/infrastructure/orphanReaper.d.ts.map +1 -0
  96. package/dist/infrastructure/orphanReaper.js +42 -0
  97. package/dist/infrastructure/orphanReaper.js.map +1 -0
  98. package/dist/infrastructure/secrets/SecretStore.d.ts +36 -0
  99. package/dist/infrastructure/secrets/SecretStore.d.ts.map +1 -0
  100. package/dist/infrastructure/secrets/SecretStore.js +44 -0
  101. package/dist/infrastructure/secrets/SecretStore.js.map +1 -0
  102. package/dist/middleware/cors.d.ts +11 -0
  103. package/dist/middleware/cors.d.ts.map +1 -0
  104. package/dist/middleware/cors.js +30 -0
  105. package/dist/middleware/cors.js.map +1 -0
  106. package/dist/middleware/error.d.ts +3 -0
  107. package/dist/middleware/error.d.ts.map +1 -0
  108. package/dist/middleware/error.js +52 -0
  109. package/dist/middleware/error.js.map +1 -0
  110. package/dist/middleware/workspaceId.d.ts +10 -0
  111. package/dist/middleware/workspaceId.d.ts.map +1 -0
  112. package/dist/middleware/workspaceId.js +9 -0
  113. package/dist/middleware/workspaceId.js.map +1 -0
  114. package/dist/routes/clarify.d.ts +8 -0
  115. package/dist/routes/clarify.d.ts.map +1 -0
  116. package/dist/routes/clarify.js +84 -0
  117. package/dist/routes/clarify.js.map +1 -0
  118. package/dist/routes/decisions.d.ts +7 -0
  119. package/dist/routes/decisions.d.ts.map +1 -0
  120. package/dist/routes/decisions.js +30 -0
  121. package/dist/routes/decisions.js.map +1 -0
  122. package/dist/routes/edges.d.ts +7 -0
  123. package/dist/routes/edges.d.ts.map +1 -0
  124. package/dist/routes/edges.js +30 -0
  125. package/dist/routes/edges.js.map +1 -0
  126. package/dist/routes/health.d.ts +3 -0
  127. package/dist/routes/health.d.ts.map +1 -0
  128. package/dist/routes/health.js +10 -0
  129. package/dist/routes/health.js.map +1 -0
  130. package/dist/routes/helpers.d.ts +5 -0
  131. package/dist/routes/helpers.d.ts.map +1 -0
  132. package/dist/routes/helpers.js +14 -0
  133. package/dist/routes/helpers.js.map +1 -0
  134. package/dist/routes/model.d.ts +7 -0
  135. package/dist/routes/model.d.ts.map +1 -0
  136. package/dist/routes/model.js +12 -0
  137. package/dist/routes/model.js.map +1 -0
  138. package/dist/routes/nodes.d.ts +7 -0
  139. package/dist/routes/nodes.d.ts.map +1 -0
  140. package/dist/routes/nodes.js +47 -0
  141. package/dist/routes/nodes.js.map +1 -0
  142. package/dist/routes/oauth.d.ts +20 -0
  143. package/dist/routes/oauth.d.ts.map +1 -0
  144. package/dist/routes/oauth.js +107 -0
  145. package/dist/routes/oauth.js.map +1 -0
  146. package/dist/routes/ontology.d.ts +8 -0
  147. package/dist/routes/ontology.d.ts.map +1 -0
  148. package/dist/routes/ontology.js +21 -0
  149. package/dist/routes/ontology.js.map +1 -0
  150. package/dist/routes/proposals.d.ts +10 -0
  151. package/dist/routes/proposals.d.ts.map +1 -0
  152. package/dist/routes/proposals.js +80 -0
  153. package/dist/routes/proposals.js.map +1 -0
  154. package/dist/routes/runs.d.ts +9 -0
  155. package/dist/routes/runs.d.ts.map +1 -0
  156. package/dist/routes/runs.js +73 -0
  157. package/dist/routes/runs.js.map +1 -0
  158. package/dist/routes/skills.d.ts +9 -0
  159. package/dist/routes/skills.d.ts.map +1 -0
  160. package/dist/routes/skills.js +42 -0
  161. package/dist/routes/skills.js.map +1 -0
  162. package/dist/routes/workspaceEvents.d.ts +14 -0
  163. package/dist/routes/workspaceEvents.d.ts.map +1 -0
  164. package/dist/routes/workspaceEvents.js +37 -0
  165. package/dist/routes/workspaceEvents.js.map +1 -0
  166. package/dist/routes/workspaces.d.ts +8 -0
  167. package/dist/routes/workspaces.d.ts.map +1 -0
  168. package/dist/routes/workspaces.js +167 -0
  169. package/dist/routes/workspaces.js.map +1 -0
  170. package/dist/server.d.ts +2 -0
  171. package/dist/server.d.ts.map +1 -0
  172. package/dist/server.js +33 -0
  173. package/dist/server.js.map +1 -0
  174. package/package.json +49 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runs.js","sourceRoot":"","sources":["../../src/routes/runs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { SkillRegistry, SkillRunner, WorkspaceRepository } from '@braidhq/core';
2
+ import { Hono } from 'hono';
3
+ export interface SkillsRouterDeps {
4
+ readonly skillRegistry: SkillRegistry;
5
+ readonly skillRunner: SkillRunner;
6
+ readonly workspaceRepository: WorkspaceRepository;
7
+ }
8
+ export declare function createSkillsRouter(deps: SkillsRouterDeps): Hono;
9
+ //# sourceMappingURL=skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/routes/skills.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACX,mBAAmB,EACpB,MAAM,eAAe,CAAA;AAItB,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAW3B,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAA;IACrC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,CAAA;CAClD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAiC/D"}
@@ -0,0 +1,42 @@
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';
5
+ import { getWorkspaceId } from '../middleware/workspaceId.js';
6
+ import { loadWorkspaceById } from './helpers.js';
7
+ const RunBodySchema = z.object({
8
+ args: z.string().default(''),
9
+ /** Continue an existing claude conversation (from a prior session-started event). */
10
+ resumeSessionId: z.string().min(1).optional(),
11
+ });
12
+ export function createSkillsRouter(deps) {
13
+ const router = new Hono();
14
+ router.get('/', async (context) => {
15
+ const workspace = await loadWorkspaceById(getWorkspaceId(context), deps.workspaceRepository);
16
+ const manifests = await deps.skillRegistry.list(workspace);
17
+ return context.json({
18
+ items: manifests.map(manifest => manifest.toData()),
19
+ });
20
+ });
21
+ router.get('/:skillId', async (context) => {
22
+ const workspace = await loadWorkspaceById(getWorkspaceId(context), deps.workspaceRepository);
23
+ const skillId = SkillIdSchema.parse(context.req.param('skillId'));
24
+ const manifest = await deps.skillRegistry.get(workspace, skillId);
25
+ return context.json(manifest.toData());
26
+ });
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) => {
33
+ const workspace = await loadWorkspaceById(getWorkspaceId(context), deps.workspaceRepository);
34
+ const skillId = SkillIdSchema.parse(context.req.param('skillId'));
35
+ const { args, resumeSessionId } = context.req.valid('json');
36
+ const options = resumeSessionId ? { resumeSessionId } : undefined;
37
+ const runId = await deps.skillRunner.start(workspace, skillId, args, options);
38
+ return context.json({ runId }, 202);
39
+ });
40
+ return router;
41
+ }
42
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/routes/skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { WorkspaceEventBus } from '@braidhq/core';
2
+ import { Hono } from 'hono';
3
+ export interface WorkspaceEventsRouterDeps {
4
+ readonly eventBus: WorkspaceEventBus;
5
+ }
6
+ /**
7
+ * SSE endpoint the Studio opens once per workspace to invalidate
8
+ * react-query caches in real time. Pure delivery: events are dropped if
9
+ * no one is listening, and the route makes no attempt to backfill state
10
+ * on connect. The client re-fetches list endpoints on `EventSource.open`
11
+ * so a fresh subscriber catches up.
12
+ */
13
+ export declare function createWorkspaceEventsRouter(deps: WorkspaceEventsRouterDeps): Hono;
14
+ //# sourceMappingURL=workspaceEvents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaceEvents.d.ts","sourceRoot":"","sources":["../../src/routes/workspaceEvents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACtE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAK3B,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,yBAAyB,GAAG,IAAI,CA0BjF"}
@@ -0,0 +1,37 @@
1
+ import { Hono } from 'hono';
2
+ import { streamSSE } from 'hono/streaming';
3
+ import { createAsyncQueue } from '../infrastructure/agent/asyncQueue.js';
4
+ import { getWorkspaceId, workspaceIdMiddleware } from '../middleware/workspaceId.js';
5
+ /**
6
+ * SSE endpoint the Studio opens once per workspace to invalidate
7
+ * react-query caches in real time. Pure delivery: events are dropped if
8
+ * no one is listening, and the route makes no attempt to backfill state
9
+ * on connect. The client re-fetches list endpoints on `EventSource.open`
10
+ * so a fresh subscriber catches up.
11
+ */
12
+ export function createWorkspaceEventsRouter(deps) {
13
+ const router = new Hono();
14
+ router.get('/:workspaceId/events', workspaceIdMiddleware, async (context) => {
15
+ const workspaceId = getWorkspaceId(context);
16
+ return streamSSE(context, async (stream) => {
17
+ const queue = createAsyncQueue();
18
+ const unsubscribe = deps.eventBus.subscribe(workspaceId, (event) => {
19
+ queue.push(event);
20
+ });
21
+ // Initial comment so the client's EventSource.onopen fires
22
+ // immediately even if no event has been published yet.
23
+ await stream.writeSSE({ event: 'ready', data: JSON.stringify({ workspaceId }) });
24
+ try {
25
+ for await (const event of queue.iterate()) {
26
+ await stream.writeSSE({ event: event.type, data: JSON.stringify(event) });
27
+ }
28
+ }
29
+ finally {
30
+ unsubscribe();
31
+ queue.end();
32
+ }
33
+ });
34
+ });
35
+ return router;
36
+ }
37
+ //# sourceMappingURL=workspaceEvents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaceEvents.js","sourceRoot":"","sources":["../../src/routes/workspaceEvents.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAA;AACxE,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AAMpF;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,CAAC,IAA+B;IACzE,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAA;IAEzB,MAAM,CAAC,GAAG,CAAC,sBAAsB,EAAE,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC1E,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QAC3C,OAAO,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACzC,MAAM,KAAK,GAAG,gBAAgB,EAAkB,CAAA;YAChD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE;gBACjE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACnB,CAAC,CAAC,CAAA;YACF,2DAA2D;YAC3D,uDAAuD;YACvD,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAA;YAChF,IAAI,CAAC;gBACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;oBAC1C,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;gBAC3E,CAAC;YACH,CAAC;oBACO,CAAC;gBACP,WAAW,EAAE,CAAA;gBACb,KAAK,CAAC,GAAG,EAAE,CAAA;YACb,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { SourceLoaderRunner, WorkspaceService } from '@braidhq/core';
2
+ import { Hono } from 'hono';
3
+ export interface WorkspacesRouterDeps {
4
+ workspaceService: WorkspaceService;
5
+ sourceLoaderRunner: SourceLoaderRunner;
6
+ }
7
+ export declare function createWorkspacesRouter(deps: WorkspacesRouterDeps): Hono;
8
+ //# sourceMappingURL=workspaces.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,167 @@
1
+ import { rm, stat } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { NotFoundError, ValidationError } from '@braidhq/core';
4
+ import { AbsolutePath, AgentRoutingConfig, ChannelDescriptor, McpServerConfig, OntologyId, ProductManifestDraft, SourceDescriptor as SourceDescriptorSchema, SourceId, StorageDescriptor, } from '@braidhq/schema';
5
+ import { zValidator } from '@hono/zod-validator';
6
+ import { Hono } from 'hono';
7
+ import { z } from 'zod';
8
+ import { fillManifestDefaults, updateProductManifest, writeProductManifest } from '../infrastructure/fs/productManifestWriter.js';
9
+ import { getWorkspaceId, workspaceIdMiddleware } from '../middleware/workspaceId.js';
10
+ const RegisterBodySchema = z.object({
11
+ rootPath: AbsolutePath,
12
+ });
13
+ const ScaffoldBodySchema = z.object({
14
+ rootPath: AbsolutePath,
15
+ manifest: ProductManifestDraft,
16
+ });
17
+ const PatchWorkspaceBodySchema = z.object({
18
+ name: z.string().min(1).optional(),
19
+ description: z.string().optional(),
20
+ ontologyId: OntologyId.optional(),
21
+ storage: StorageDescriptor.optional(),
22
+ agents: AgentRoutingConfig.optional(),
23
+ channels: z.array(ChannelDescriptor).optional(),
24
+ mcpServers: z.array(McpServerConfig).optional(),
25
+ }).refine(body => Object.keys(body).length > 0, { message: 'PATCH body must contain at least one field' });
26
+ export function createWorkspacesRouter(deps) {
27
+ const router = new Hono();
28
+ router.get('/', async (context) => {
29
+ const workspaces = await deps.workspaceService.list();
30
+ return context.json({ items: workspaces.map(workspace => workspace.toData()) });
31
+ });
32
+ router.get('/:workspaceId', workspaceIdMiddleware, async (context) => {
33
+ const workspaceId = getWorkspaceId(context);
34
+ const workspace = await deps.workspaceService.findById(workspaceId);
35
+ return context.json(workspace.toData());
36
+ });
37
+ router.post('/', zValidator('json', RegisterBodySchema), async (context) => {
38
+ const { rootPath } = context.req.valid('json');
39
+ const workspace = await deps.workspaceService.load(rootPath);
40
+ await deps.workspaceService.save(workspace);
41
+ return context.json(workspace.toData(), 201);
42
+ });
43
+ // Create a workspace from scratch: write PRODUCT.md with server-filled
44
+ // defaults, run every loader-backed source's `ingest`, then register.
45
+ // If ingest fails (wrong git branch, missing OAuth scope, etc.) we
46
+ // delete the PRODUCT.md we just wrote and drop the parse cache, so
47
+ // the user's retry sees a clean slate instead of "PRODUCT.md already
48
+ // exists" or a stale cached config.
49
+ router.post('/scaffold', zValidator('json', ScaffoldBodySchema), async (context) => {
50
+ const { rootPath, manifest: draft } = context.req.valid('json');
51
+ const productPath = join(rootPath, 'PRODUCT.md');
52
+ if (await pathExists(productPath))
53
+ throw new ValidationError(`A PRODUCT.md already exists at "${rootPath}". Use POST /workspaces to register it instead.`);
54
+ const manifest = fillManifestDefaults(draft);
55
+ await writeProductManifest(rootPath, manifest, manifest.description);
56
+ try {
57
+ const workspace = await deps.workspaceService.load(rootPath);
58
+ const ingestOutcomes = await deps.sourceLoaderRunner.ingestAll(workspace);
59
+ await deps.workspaceService.save(workspace);
60
+ return context.json({
61
+ workspace: workspace.toData(),
62
+ ingest: ingestOutcomes.map(o => ({ sourceId: o.sourceId, ...o.report })),
63
+ }, 201);
64
+ }
65
+ catch (error) {
66
+ await rm(productPath, { force: true });
67
+ deps.workspaceService.invalidate(rootPath);
68
+ throw error;
69
+ }
70
+ });
71
+ // Add a source to an existing workspace. Rewrites PRODUCT.md and runs
72
+ // `ingest` if the source is loader-backed so the local filesystem is
73
+ // populated before the user runs a skill against it.
74
+ router.post('/:workspaceId/sources', workspaceIdMiddleware, zValidator('json', SourceDescriptorSchema), async (context) => {
75
+ const workspaceId = getWorkspaceId(context);
76
+ const source = context.req.valid('json');
77
+ const workspace = await deps.workspaceService.findById(workspaceId);
78
+ if (workspace.findSource(source.name))
79
+ throw new ValidationError(`Source "${source.name}" already exists in workspace "${workspaceId}"`);
80
+ const nextManifest = withSources(workspace.productManifest, [...workspace.sources, source]);
81
+ await updateProductManifest(workspace.rootPath, nextManifest);
82
+ const updated = await reload(deps.workspaceService, workspace.rootPath);
83
+ let ingest;
84
+ if (source.kind === 'filesystem' && source.loader) {
85
+ const report = await deps.sourceLoaderRunner.syncOne(updated, source.id);
86
+ ingest = { sourceId: source.id, ...report };
87
+ }
88
+ return context.json({ workspace: updated.toData(), ...(ingest ? { ingest } : {}) }, 201);
89
+ });
90
+ // Remove a source from the manifest. Local files (e.g. cloned git repos)
91
+ // are left on disk; the user can `rm -rf` them manually if they want.
92
+ router.delete('/:workspaceId/sources/:sourceId', workspaceIdMiddleware, async (context) => {
93
+ const workspaceId = getWorkspaceId(context);
94
+ const sourceId = SourceId.parse(context.req.param('sourceId'));
95
+ const workspace = await deps.workspaceService.findById(workspaceId);
96
+ const source = workspace.sources.find(entry => entry.id === sourceId);
97
+ if (!source)
98
+ throw new NotFoundError(`Source "${sourceId}" not found in workspace "${workspaceId}"`);
99
+ const nextManifest = withSources(workspace.productManifest, workspace.sources.filter(entry => entry.id !== sourceId));
100
+ await updateProductManifest(workspace.rootPath, nextManifest);
101
+ const updated = await reload(deps.workspaceService, workspace.rootPath);
102
+ return context.json({ workspace: updated.toData() });
103
+ });
104
+ // Per-source sync. Looks up the source's loader and invokes `sync` (or
105
+ // falls back to `ingest` if the destination doesn't exist yet).
106
+ router.post('/:workspaceId/sources/:sourceId/sync', workspaceIdMiddleware, async (context) => {
107
+ const workspaceId = getWorkspaceId(context);
108
+ const sourceId = SourceId.parse(context.req.param('sourceId'));
109
+ const workspace = await deps.workspaceService.findById(workspaceId);
110
+ const report = await deps.sourceLoaderRunner.syncOne(workspace, sourceId);
111
+ return context.json(report);
112
+ });
113
+ // Update workspace-level manifest fields. Renaming changes the
114
+ // WorkspaceId (derived from `manifest.name`) so callers should re-fetch
115
+ // the workspace list after a successful rename.
116
+ router.patch('/:workspaceId', workspaceIdMiddleware, zValidator('json', PatchWorkspaceBodySchema), async (context) => {
117
+ const workspaceId = getWorkspaceId(context);
118
+ const patch = context.req.valid('json');
119
+ const workspace = await deps.workspaceService.findById(workspaceId);
120
+ const nextManifest = {
121
+ ...workspace.productManifest,
122
+ ...(patch.name !== undefined ? { name: patch.name } : {}),
123
+ ...(patch.description !== undefined ? { description: patch.description } : {}),
124
+ ...(patch.ontologyId !== undefined ? { ontologyId: patch.ontologyId } : {}),
125
+ ...(patch.storage !== undefined ? { storage: patch.storage } : {}),
126
+ ...(patch.agents !== undefined ? { agents: patch.agents } : {}),
127
+ ...(patch.channels !== undefined ? { channels: patch.channels } : {}),
128
+ ...(patch.mcpServers !== undefined ? { mcpServers: patch.mcpServers } : {}),
129
+ };
130
+ await updateProductManifest(workspace.rootPath, nextManifest);
131
+ const renamed = patch.name !== undefined && patch.name !== workspace.productManifest.name;
132
+ const updated = await reload(deps.workspaceService, workspace.rootPath);
133
+ return context.json({
134
+ workspace: updated.toData(),
135
+ ...(renamed ? { renamed: true, previousId: workspace.id, newId: updated.id } : {}),
136
+ });
137
+ });
138
+ // Unregister a workspace. Files (PRODUCT.md, .braid/, ingested sources)
139
+ // are left on disk — the user can re-register via POST /workspaces or
140
+ // delete the directory manually.
141
+ router.delete('/:workspaceId', workspaceIdMiddleware, async (context) => {
142
+ const workspaceId = getWorkspaceId(context);
143
+ const workspace = await deps.workspaceService.findById(workspaceId);
144
+ await deps.workspaceService.remove(workspace.rootPath);
145
+ return context.body(null, 204);
146
+ });
147
+ return router;
148
+ }
149
+ function withSources(manifest, sources) {
150
+ return { ...manifest, sources: [...sources] };
151
+ }
152
+ async function reload(workspaceService, rootPath) {
153
+ workspaceService.invalidate(rootPath);
154
+ const reloaded = await workspaceService.load(rootPath);
155
+ await workspaceService.save(reloaded);
156
+ return reloaded;
157
+ }
158
+ async function pathExists(path) {
159
+ try {
160
+ await stat(path);
161
+ return true;
162
+ }
163
+ catch {
164
+ return false;
165
+ }
166
+ }
167
+ //# sourceMappingURL=workspaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaces.js","sourceRoot":"","sources":["../../src/routes/workspaces.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":""}
package/dist/server.js ADDED
@@ -0,0 +1,33 @@
1
+ import process from 'node:process';
2
+ import { serve } from '@hono/node-server';
3
+ import { createApp } from './app.js';
4
+ import { composeFsApp } from './composeFs.js';
5
+ import { reapOrphanRuns } from './infrastructure/orphanReaper.js';
6
+ const port = Number(process.env.BRAID_SERVER_PORT ?? 4321);
7
+ const deps = composeFsApp({
8
+ apiUrl: `http://localhost:${port}`,
9
+ ...(process.env.BRAID_HOME ? { braidHome: process.env.BRAID_HOME } : {}),
10
+ ...(process.env.BRAID_AGENT_MODEL ? { agentModel: process.env.BRAID_AGENT_MODEL } : {}),
11
+ ...(process.env.BRAID_AGENT_EFFORT ? { agentEffort: process.env.BRAID_AGENT_EFFORT } : {}),
12
+ });
13
+ const app = createApp(deps);
14
+ serve({ fetch: app.fetch, port }, ({ port: boundPort }) => {
15
+ // eslint-disable-next-line no-console
16
+ console.log(`braid-server listening on http://localhost:${boundPort}`);
17
+ });
18
+ // Any run without a `completedAt` is from a previous server process that was
19
+ // killed mid-run. Tag those as aborted so they don't appear "active forever"
20
+ // in the Runs UI. Run after `serve()` so it doesn't delay accepting requests.
21
+ reapOrphanRuns({
22
+ workspaceRepository: deps.workspaceRepository,
23
+ runRepository: deps.runRepository,
24
+ clock: deps.clock,
25
+ }).then(({ reaped }) => {
26
+ if (reaped > 0) {
27
+ // eslint-disable-next-line no-console
28
+ console.log(`braid-server: marked ${reaped} orphan run(s) as aborted`);
29
+ }
30
+ }).catch((error) => {
31
+ console.error('orphan reaper failed:', error);
32
+ });
33
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAA;AAEjE,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,IAAI,CAAC,CAAA;AAC1D,MAAM,IAAI,GAAG,YAAY,CAAC;IACxB,MAAM,EAAE,oBAAoB,IAAI,EAAE;IAClC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACvF,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAiC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;CAC1G,CAAC,CAAA;AAEF,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;AAE3B,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE;IACxD,sCAAsC;IACtC,OAAO,CAAC,GAAG,CAAC,8CAA8C,SAAS,EAAE,CAAC,CAAA;AACxE,CAAC,CAAC,CAAA;AAEF,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,cAAc,CAAC;IACb,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;IAC7C,aAAa,EAAE,IAAI,CAAC,aAAa;IACjC,KAAK,EAAE,IAAI,CAAC,KAAK;CAClB,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;IACrB,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,sCAAsC;QACtC,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,2BAA2B,CAAC,CAAA;IACxE,CAAC;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACjB,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAA;AAC/C,CAAC,CAAC,CAAA"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@braidhq/server",
3
+ "type": "module",
4
+ "version": "0.0.1",
5
+ "description": "Braid REST + (later) MCP server. Hono on Node 20.",
6
+ "license": "MIT",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ }
12
+ },
13
+ "main": "./dist/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "files": [
16
+ "README.md",
17
+ "dist"
18
+ ],
19
+ "dependencies": {
20
+ "@hono/node-server": "^1.13.0",
21
+ "@hono/zod-validator": "^0.4.0",
22
+ "hono": "^4.6.0",
23
+ "pino": "^9.5.0",
24
+ "yaml": "^2.9.0",
25
+ "zod": "^3.24.0",
26
+ "@braidhq/core": "0.0.1",
27
+ "@braidhq/ontology-ddd": "0.0.1",
28
+ "@braidhq/schema": "0.0.1",
29
+ "@braidhq/storage-kuzu": "0.0.1",
30
+ "@braidhq/source-loader-git": "0.0.1",
31
+ "@braidhq/source-loader-gdrive": "0.0.1"
32
+ },
33
+ "devDependencies": {
34
+ "tsx": "^4.19.0",
35
+ "typescript": "^5.7.0",
36
+ "vitest": "^2.1.0"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "scripts": {
42
+ "build": "tsc -p tsconfig.json",
43
+ "typecheck": "tsc -p tsconfig.json --noEmit",
44
+ "test": "vitest run",
45
+ "test:coverage": "vitest run --coverage",
46
+ "dev": "tsx watch src/server.ts",
47
+ "clean": "rm -rf dist .turbo *.tsbuildinfo coverage"
48
+ }
49
+ }