@braidhq/server 0.0.1 → 0.2.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.
- package/README.md +164 -0
- package/dist/app.d.ts +12 -3
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +154 -9
- package/dist/app.js.map +1 -1
- package/dist/authMode.d.ts +39 -0
- package/dist/authMode.d.ts.map +1 -0
- package/dist/authMode.js +50 -0
- package/dist/authMode.js.map +1 -0
- package/dist/composeApp.d.ts +79 -0
- package/dist/composeApp.d.ts.map +1 -0
- package/dist/composeApp.js +136 -0
- package/dist/composeApp.js.map +1 -0
- package/dist/composeFsApp.d.ts +27 -0
- package/dist/composeFsApp.d.ts.map +1 -0
- package/dist/composeFsApp.js +309 -0
- package/dist/composeFsApp.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/_shared/env.d.ts +10 -0
- package/dist/infrastructure/_shared/env.d.ts.map +1 -0
- package/dist/infrastructure/_shared/env.js +19 -0
- package/dist/infrastructure/_shared/env.js.map +1 -0
- package/dist/infrastructure/_shared/frontmatter.d.ts +13 -0
- package/dist/infrastructure/_shared/frontmatter.d.ts.map +1 -0
- package/dist/infrastructure/{fs → _shared}/frontmatter.js +5 -5
- package/dist/infrastructure/_shared/frontmatter.js.map +1 -0
- package/dist/infrastructure/_shared/jsonFileStore.d.ts.map +1 -0
- package/dist/infrastructure/_shared/jsonFileStore.js.map +1 -0
- package/dist/infrastructure/_shared/paths.d.ts +43 -0
- package/dist/infrastructure/_shared/paths.d.ts.map +1 -0
- package/dist/infrastructure/_shared/paths.js +96 -0
- package/dist/infrastructure/_shared/paths.js.map +1 -0
- package/dist/infrastructure/auth/AccessPolicy.d.ts +87 -0
- package/dist/infrastructure/auth/AccessPolicy.d.ts.map +1 -0
- package/dist/infrastructure/auth/AccessPolicy.js +177 -0
- package/dist/infrastructure/auth/AccessPolicy.js.map +1 -0
- package/dist/infrastructure/auth/SessionStore.d.ts +50 -0
- package/dist/infrastructure/auth/SessionStore.d.ts.map +1 -0
- package/dist/infrastructure/auth/SessionStore.js +104 -0
- package/dist/infrastructure/auth/SessionStore.js.map +1 -0
- package/dist/infrastructure/batch/FsBatchPlanRepository.d.ts +79 -0
- package/dist/infrastructure/batch/FsBatchPlanRepository.d.ts.map +1 -0
- package/dist/infrastructure/batch/FsBatchPlanRepository.js +42 -0
- package/dist/infrastructure/batch/FsBatchPlanRepository.js.map +1 -0
- package/dist/infrastructure/history/GitWorkspaceHistory.d.ts +18 -0
- package/dist/infrastructure/history/GitWorkspaceHistory.d.ts.map +1 -0
- package/dist/infrastructure/history/GitWorkspaceHistory.js +310 -0
- package/dist/infrastructure/history/GitWorkspaceHistory.js.map +1 -0
- package/dist/infrastructure/history/commitMessage.d.ts +4 -0
- package/dist/infrastructure/history/commitMessage.d.ts.map +1 -0
- package/dist/infrastructure/history/commitMessage.js +90 -0
- package/dist/infrastructure/history/commitMessage.js.map +1 -0
- package/dist/infrastructure/hitl/FsClarificationRepository.d.ts +13 -0
- package/dist/infrastructure/hitl/FsClarificationRepository.d.ts.map +1 -0
- package/dist/infrastructure/hitl/FsClarificationRepository.js +39 -0
- package/dist/infrastructure/hitl/FsClarificationRepository.js.map +1 -0
- package/dist/infrastructure/hitl/FsProposalRepository.d.ts.map +1 -0
- package/dist/infrastructure/{fs → hitl}/FsProposalRepository.js +10 -3
- package/dist/infrastructure/hitl/FsProposalRepository.js.map +1 -0
- package/dist/infrastructure/hitl/StatusedJsonStore.d.ts +30 -0
- package/dist/infrastructure/hitl/StatusedJsonStore.d.ts.map +1 -0
- package/dist/infrastructure/{fs/FsStatusedJsonRepository.js → hitl/StatusedJsonStore.js} +3 -3
- package/dist/infrastructure/hitl/StatusedJsonStore.js.map +1 -0
- package/dist/infrastructure/model/FsModelSerializer.d.ts +96 -0
- package/dist/infrastructure/model/FsModelSerializer.d.ts.map +1 -0
- package/dist/infrastructure/model/FsModelSerializer.js +60 -0
- package/dist/infrastructure/model/FsModelSerializer.js.map +1 -0
- package/dist/infrastructure/oauth/GoogleOAuth.d.ts +43 -14
- package/dist/infrastructure/oauth/GoogleOAuth.d.ts.map +1 -1
- package/dist/infrastructure/oauth/GoogleOAuth.js +78 -11
- package/dist/infrastructure/oauth/GoogleOAuth.js.map +1 -1
- package/dist/infrastructure/reactor/FsReactorCycleRepository.d.ts +29 -0
- package/dist/infrastructure/reactor/FsReactorCycleRepository.d.ts.map +1 -0
- package/dist/infrastructure/reactor/FsReactorCycleRepository.js +94 -0
- package/dist/infrastructure/reactor/FsReactorCycleRepository.js.map +1 -0
- package/dist/infrastructure/secrets/SecretStore.d.ts +11 -14
- package/dist/infrastructure/secrets/SecretStore.d.ts.map +1 -1
- package/dist/infrastructure/secrets/SecretStore.js +4 -4
- package/dist/infrastructure/secrets/SecretStore.js.map +1 -1
- package/dist/infrastructure/{fs → skill}/FsRunRepository.d.ts +9 -4
- package/dist/infrastructure/skill/FsRunRepository.d.ts.map +1 -0
- package/dist/infrastructure/skill/FsRunRepository.js +162 -0
- package/dist/infrastructure/skill/FsRunRepository.js.map +1 -0
- package/dist/infrastructure/{fs → skill}/FsSkillRegistry.d.ts +4 -13
- package/dist/infrastructure/skill/FsSkillRegistry.d.ts.map +1 -0
- package/dist/infrastructure/{fs → skill}/FsSkillRegistry.js +38 -18
- package/dist/infrastructure/skill/FsSkillRegistry.js.map +1 -0
- package/dist/infrastructure/{agent → skill}/SubprocessSkillRunner.d.ts +13 -15
- package/dist/infrastructure/skill/SubprocessSkillRunner.d.ts.map +1 -0
- package/dist/infrastructure/{agent → skill}/SubprocessSkillRunner.js +124 -40
- package/dist/infrastructure/skill/SubprocessSkillRunner.js.map +1 -0
- package/dist/infrastructure/skill/asyncQueue.d.ts +20 -0
- package/dist/infrastructure/skill/asyncQueue.d.ts.map +1 -0
- package/dist/infrastructure/{agent → skill}/asyncQueue.js +2 -3
- package/dist/infrastructure/{agent → skill}/asyncQueue.js.map +1 -1
- package/dist/infrastructure/skill/lineBuffer.d.ts +15 -0
- package/dist/infrastructure/skill/lineBuffer.d.ts.map +1 -0
- package/dist/infrastructure/{agent/streamJsonParser.js → skill/lineBuffer.js} +5 -17
- package/dist/infrastructure/skill/lineBuffer.js.map +1 -0
- package/dist/infrastructure/skill/orphanReaper.d.ts +20 -0
- package/dist/infrastructure/skill/orphanReaper.d.ts.map +1 -0
- package/dist/infrastructure/{orphanReaper.js → skill/orphanReaper.js} +7 -5
- package/dist/infrastructure/skill/orphanReaper.js.map +1 -0
- package/dist/infrastructure/skill/subprocessEventStream.d.ts +16 -0
- package/dist/infrastructure/skill/subprocessEventStream.d.ts.map +1 -0
- package/dist/infrastructure/skill/subprocessEventStream.js +29 -0
- package/dist/infrastructure/skill/subprocessEventStream.js.map +1 -0
- package/dist/infrastructure/source/FsSourceUnitDigest.d.ts +19 -0
- package/dist/infrastructure/source/FsSourceUnitDigest.d.ts.map +1 -0
- package/dist/infrastructure/source/FsSourceUnitDigest.js +58 -0
- package/dist/infrastructure/source/FsSourceUnitDigest.js.map +1 -0
- package/dist/infrastructure/source/FsSourceUnitObservationRepository.d.ts +31 -0
- package/dist/infrastructure/source/FsSourceUnitObservationRepository.d.ts.map +1 -0
- package/dist/infrastructure/source/FsSourceUnitObservationRepository.js +88 -0
- package/dist/infrastructure/source/FsSourceUnitObservationRepository.js.map +1 -0
- package/dist/infrastructure/source/intentScan.d.ts +13 -0
- package/dist/infrastructure/source/intentScan.d.ts.map +1 -0
- package/dist/infrastructure/source/intentScan.js +137 -0
- package/dist/infrastructure/source/intentScan.js.map +1 -0
- package/dist/infrastructure/users/UserDirectoryFromRegistry.d.ts +14 -0
- package/dist/infrastructure/users/UserDirectoryFromRegistry.d.ts.map +1 -0
- package/dist/infrastructure/users/UserDirectoryFromRegistry.js +21 -0
- package/dist/infrastructure/users/UserDirectoryFromRegistry.js.map +1 -0
- package/dist/infrastructure/users/UserRegistryFile.d.ts +22 -0
- package/dist/infrastructure/users/UserRegistryFile.d.ts.map +1 -0
- package/dist/infrastructure/users/UserRegistryFile.js +89 -0
- package/dist/infrastructure/users/UserRegistryFile.js.map +1 -0
- package/dist/infrastructure/users/ensureWorkspaceOwners.d.ts +12 -0
- package/dist/infrastructure/users/ensureWorkspaceOwners.d.ts.map +1 -0
- package/dist/infrastructure/users/ensureWorkspaceOwners.js +25 -0
- package/dist/infrastructure/users/ensureWorkspaceOwners.js.map +1 -0
- package/dist/infrastructure/workspace/FsWorkspaceRepository.d.ts.map +1 -0
- package/dist/infrastructure/{fs → workspace}/FsWorkspaceRepository.js +15 -5
- package/dist/infrastructure/workspace/FsWorkspaceRepository.js.map +1 -0
- package/dist/infrastructure/workspace/WorkspaceDiscovery.d.ts +18 -0
- package/dist/infrastructure/workspace/WorkspaceDiscovery.d.ts.map +1 -0
- package/dist/infrastructure/workspace/WorkspaceDiscovery.js +50 -0
- package/dist/infrastructure/workspace/WorkspaceDiscovery.js.map +1 -0
- package/dist/infrastructure/workspace/WorkspaceRegistryFile.d.ts +42 -0
- package/dist/infrastructure/workspace/WorkspaceRegistryFile.d.ts.map +1 -0
- package/dist/infrastructure/workspace/WorkspaceRegistryFile.js +160 -0
- package/dist/infrastructure/workspace/WorkspaceRegistryFile.js.map +1 -0
- package/dist/infrastructure/workspace/productManifestWriter.d.ts +24 -0
- package/dist/infrastructure/workspace/productManifestWriter.d.ts.map +1 -0
- package/dist/infrastructure/{fs → workspace}/productManifestWriter.js +14 -28
- package/dist/infrastructure/workspace/productManifestWriter.js.map +1 -0
- package/dist/middleware/auth.d.ts +39 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +87 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/cors.d.ts.map +1 -1
- package/dist/middleware/cors.js +5 -2
- package/dist/middleware/cors.js.map +1 -1
- package/dist/middleware/error.d.ts.map +1 -1
- package/dist/middleware/error.js +15 -13
- package/dist/middleware/error.js.map +1 -1
- package/dist/middleware/workspaceAccess.d.ts +51 -0
- package/dist/middleware/workspaceAccess.d.ts.map +1 -0
- package/dist/middleware/workspaceAccess.js +91 -0
- package/dist/middleware/workspaceAccess.js.map +1 -0
- package/dist/policy/CapabilityCheck.d.ts +14 -0
- package/dist/policy/CapabilityCheck.d.ts.map +1 -0
- package/dist/policy/CapabilityCheck.js +2 -0
- package/dist/policy/CapabilityCheck.js.map +1 -0
- package/dist/policy/PermissionRegistry.d.ts +25 -0
- package/dist/policy/PermissionRegistry.d.ts.map +1 -0
- package/dist/policy/PermissionRegistry.js +29 -0
- package/dist/policy/PermissionRegistry.js.map +1 -0
- package/dist/policy/ViewerContext.d.ts +29 -0
- package/dist/policy/ViewerContext.d.ts.map +1 -0
- package/dist/policy/ViewerContext.js +2 -0
- package/dist/policy/ViewerContext.js.map +1 -0
- package/dist/policy/checks.d.ts +15 -0
- package/dist/policy/checks.d.ts.map +1 -0
- package/dist/policy/checks.js +55 -0
- package/dist/policy/checks.js.map +1 -0
- package/dist/policy/defaultRegistry.d.ts +9 -0
- package/dist/policy/defaultRegistry.d.ts.map +1 -0
- package/dist/policy/defaultRegistry.js +15 -0
- package/dist/policy/defaultRegistry.js.map +1 -0
- package/dist/policy/index.d.ts +8 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +5 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/resolveViewer.d.ts +16 -0
- package/dist/policy/resolveViewer.d.ts.map +1 -0
- package/dist/policy/resolveViewer.js +37 -0
- package/dist/policy/resolveViewer.js.map +1 -0
- package/dist/routes/_shared.d.ts +138 -0
- package/dist/routes/_shared.d.ts.map +1 -0
- package/dist/routes/_shared.js +33 -0
- package/dist/routes/_shared.js.map +1 -0
- package/dist/routes/admin.d.ts +13 -0
- package/dist/routes/admin.d.ts.map +1 -0
- package/dist/routes/admin.js +228 -0
- package/dist/routes/admin.js.map +1 -0
- package/dist/routes/auth.d.ts +35 -0
- package/dist/routes/auth.d.ts.map +1 -0
- package/dist/routes/auth.js +168 -0
- package/dist/routes/auth.js.map +1 -0
- package/dist/routes/batch.d.ts +7 -0
- package/dist/routes/batch.d.ts.map +1 -0
- package/dist/routes/batch.js +47 -0
- package/dist/routes/batch.js.map +1 -0
- package/dist/routes/clarifications.d.ts +8 -0
- package/dist/routes/clarifications.d.ts.map +1 -0
- package/dist/routes/clarifications.js +243 -0
- package/dist/routes/clarifications.js.map +1 -0
- package/dist/routes/edges.d.ts +2 -2
- package/dist/routes/edges.d.ts.map +1 -1
- package/dist/routes/edges.js +34 -16
- package/dist/routes/edges.js.map +1 -1
- package/dist/routes/health.d.ts +2 -2
- package/dist/routes/health.d.ts.map +1 -1
- package/dist/routes/health.js +21 -3
- package/dist/routes/health.js.map +1 -1
- package/dist/routes/history.d.ts +7 -0
- package/dist/routes/history.d.ts.map +1 -0
- package/dist/routes/history.js +90 -0
- package/dist/routes/history.js.map +1 -0
- package/dist/routes/model.d.ts +2 -2
- package/dist/routes/model.d.ts.map +1 -1
- package/dist/routes/model.js +20 -4
- package/dist/routes/model.js.map +1 -1
- package/dist/routes/nodes.d.ts +2 -2
- package/dist/routes/nodes.d.ts.map +1 -1
- package/dist/routes/nodes.js +77 -25
- package/dist/routes/nodes.js.map +1 -1
- package/dist/routes/oauth.d.ts +6 -7
- package/dist/routes/oauth.d.ts.map +1 -1
- package/dist/routes/oauth.js +6 -7
- package/dist/routes/oauth.js.map +1 -1
- package/dist/routes/ontology.d.ts +2 -2
- package/dist/routes/ontology.d.ts.map +1 -1
- package/dist/routes/ontology.js +22 -5
- package/dist/routes/ontology.js.map +1 -1
- package/dist/routes/proposals.d.ts +5 -4
- package/dist/routes/proposals.d.ts.map +1 -1
- package/dist/routes/proposals.js +176 -45
- package/dist/routes/proposals.js.map +1 -1
- package/dist/routes/reactorCycles.d.ts +7 -0
- package/dist/routes/reactorCycles.d.ts.map +1 -0
- package/dist/routes/reactorCycles.js +60 -0
- package/dist/routes/reactorCycles.js.map +1 -0
- package/dist/routes/runs.d.ts.map +1 -1
- package/dist/routes/runs.js +66 -12
- package/dist/routes/runs.js.map +1 -1
- package/dist/routes/skillInputOptions.d.ts +10 -0
- package/dist/routes/skillInputOptions.d.ts.map +1 -0
- package/dist/routes/skillInputOptions.js +159 -0
- package/dist/routes/skillInputOptions.js.map +1 -0
- package/dist/routes/skills.d.ts +21 -3
- package/dist/routes/skills.d.ts.map +1 -1
- package/dist/routes/skills.js +223 -21
- package/dist/routes/skills.js.map +1 -1
- package/dist/routes/sourceLoaders.d.ts +7 -0
- package/dist/routes/sourceLoaders.d.ts.map +1 -0
- package/dist/routes/sourceLoaders.js +30 -0
- package/dist/routes/sourceLoaders.js.map +1 -0
- package/dist/routes/sourceUnitObservations.d.ts +20 -0
- package/dist/routes/sourceUnitObservations.d.ts.map +1 -0
- package/dist/routes/sourceUnitObservations.js +80 -0
- package/dist/routes/sourceUnitObservations.js.map +1 -0
- package/dist/routes/sourceWebhooks.d.ts +26 -0
- package/dist/routes/sourceWebhooks.d.ts.map +1 -0
- package/dist/routes/sourceWebhooks.js +301 -0
- package/dist/routes/sourceWebhooks.js.map +1 -0
- package/dist/routes/users.d.ts +7 -0
- package/dist/routes/users.d.ts.map +1 -0
- package/dist/routes/users.js +109 -0
- package/dist/routes/users.js.map +1 -0
- package/dist/routes/workspaceEvents.d.ts +5 -4
- package/dist/routes/workspaceEvents.d.ts.map +1 -1
- package/dist/routes/workspaceEvents.js +7 -6
- package/dist/routes/workspaceEvents.js.map +1 -1
- package/dist/routes/workspaceMembers.d.ts +11 -0
- package/dist/routes/workspaceMembers.d.ts.map +1 -0
- package/dist/routes/workspaceMembers.js +81 -0
- package/dist/routes/workspaceMembers.js.map +1 -0
- package/dist/routes/workspaces.d.ts +30 -1
- package/dist/routes/workspaces.d.ts.map +1 -1
- package/dist/routes/workspaces.js +207 -63
- package/dist/routes/workspaces.js.map +1 -1
- package/dist/server.js +9 -29
- package/dist/server.js.map +1 -1
- package/dist/startServer.d.ts +17 -0
- package/dist/startServer.d.ts.map +1 -0
- package/dist/startServer.js +81 -0
- package/dist/startServer.js.map +1 -0
- package/dist/startup.d.ts +28 -0
- package/dist/startup.d.ts.map +1 -0
- package/dist/startup.js +94 -0
- package/dist/startup.js.map +1 -0
- package/package.json +49 -32
- package/LICENSE +0 -21
- package/dist/composeFs.d.ts +0 -20
- package/dist/composeFs.d.ts.map +0 -1
- package/dist/composeFs.js +0 -134
- package/dist/composeFs.js.map +0 -1
- package/dist/composition.d.ts +0 -49
- package/dist/composition.d.ts.map +0 -1
- package/dist/composition.js +0 -43
- package/dist/composition.js.map +0 -1
- package/dist/infrastructure/agent/ClaudeCodeAgentBinding.d.ts +0 -8
- package/dist/infrastructure/agent/ClaudeCodeAgentBinding.d.ts.map +0 -1
- package/dist/infrastructure/agent/ClaudeCodeAgentBinding.js +0 -62
- package/dist/infrastructure/agent/ClaudeCodeAgentBinding.js.map +0 -1
- package/dist/infrastructure/agent/SubprocessSkillRunner.d.ts.map +0 -1
- package/dist/infrastructure/agent/SubprocessSkillRunner.js.map +0 -1
- package/dist/infrastructure/agent/asyncQueue.d.ts +0 -22
- package/dist/infrastructure/agent/asyncQueue.d.ts.map +0 -1
- package/dist/infrastructure/agent/mcpConfig.d.ts +0 -18
- package/dist/infrastructure/agent/mcpConfig.d.ts.map +0 -1
- package/dist/infrastructure/agent/mcpConfig.js +0 -47
- package/dist/infrastructure/agent/mcpConfig.js.map +0 -1
- package/dist/infrastructure/agent/streamJsonParser.d.ts +0 -20
- package/dist/infrastructure/agent/streamJsonParser.d.ts.map +0 -1
- package/dist/infrastructure/agent/streamJsonParser.js.map +0 -1
- package/dist/infrastructure/agent/subprocessEventStream.d.ts +0 -26
- package/dist/infrastructure/agent/subprocessEventStream.d.ts.map +0 -1
- package/dist/infrastructure/agent/subprocessEventStream.js +0 -112
- package/dist/infrastructure/agent/subprocessEventStream.js.map +0 -1
- package/dist/infrastructure/fs/FsClarifyTicketRepository.d.ts +0 -13
- package/dist/infrastructure/fs/FsClarifyTicketRepository.d.ts.map +0 -1
- package/dist/infrastructure/fs/FsClarifyTicketRepository.js +0 -33
- package/dist/infrastructure/fs/FsClarifyTicketRepository.js.map +0 -1
- package/dist/infrastructure/fs/FsDecisionRepository.d.ts +0 -13
- package/dist/infrastructure/fs/FsDecisionRepository.d.ts.map +0 -1
- package/dist/infrastructure/fs/FsDecisionRepository.js +0 -56
- package/dist/infrastructure/fs/FsDecisionRepository.js.map +0 -1
- package/dist/infrastructure/fs/FsProposalRepository.d.ts.map +0 -1
- package/dist/infrastructure/fs/FsProposalRepository.js.map +0 -1
- package/dist/infrastructure/fs/FsRunRepository.d.ts.map +0 -1
- package/dist/infrastructure/fs/FsRunRepository.js +0 -88
- package/dist/infrastructure/fs/FsRunRepository.js.map +0 -1
- package/dist/infrastructure/fs/FsSkillRegistry.d.ts.map +0 -1
- package/dist/infrastructure/fs/FsSkillRegistry.js.map +0 -1
- package/dist/infrastructure/fs/FsStatusedJsonRepository.d.ts +0 -35
- package/dist/infrastructure/fs/FsStatusedJsonRepository.d.ts.map +0 -1
- package/dist/infrastructure/fs/FsStatusedJsonRepository.js.map +0 -1
- package/dist/infrastructure/fs/FsWorkspaceRepository.d.ts.map +0 -1
- package/dist/infrastructure/fs/FsWorkspaceRepository.js.map +0 -1
- package/dist/infrastructure/fs/WorkspaceRegistryFile.d.ts +0 -17
- package/dist/infrastructure/fs/WorkspaceRegistryFile.d.ts.map +0 -1
- package/dist/infrastructure/fs/WorkspaceRegistryFile.js +0 -58
- package/dist/infrastructure/fs/WorkspaceRegistryFile.js.map +0 -1
- package/dist/infrastructure/fs/frontmatter.d.ts +0 -13
- package/dist/infrastructure/fs/frontmatter.d.ts.map +0 -1
- package/dist/infrastructure/fs/frontmatter.js.map +0 -1
- package/dist/infrastructure/fs/jsonFileStore.d.ts.map +0 -1
- package/dist/infrastructure/fs/jsonFileStore.js.map +0 -1
- package/dist/infrastructure/fs/paths.d.ts +0 -22
- package/dist/infrastructure/fs/paths.d.ts.map +0 -1
- package/dist/infrastructure/fs/paths.js +0 -46
- package/dist/infrastructure/fs/paths.js.map +0 -1
- package/dist/infrastructure/fs/productManifestWriter.d.ts +0 -22
- package/dist/infrastructure/fs/productManifestWriter.d.ts.map +0 -1
- package/dist/infrastructure/fs/productManifestWriter.js.map +0 -1
- package/dist/infrastructure/orphanReaper.d.ts +0 -18
- package/dist/infrastructure/orphanReaper.d.ts.map +0 -1
- package/dist/infrastructure/orphanReaper.js.map +0 -1
- package/dist/routes/clarify.d.ts +0 -8
- package/dist/routes/clarify.d.ts.map +0 -1
- package/dist/routes/clarify.js +0 -84
- package/dist/routes/clarify.js.map +0 -1
- package/dist/routes/decisions.d.ts +0 -7
- package/dist/routes/decisions.d.ts.map +0 -1
- package/dist/routes/decisions.js +0 -30
- package/dist/routes/decisions.js.map +0 -1
- /package/dist/infrastructure/{fs → _shared}/jsonFileStore.d.ts +0 -0
- /package/dist/infrastructure/{fs → _shared}/jsonFileStore.js +0 -0
- /package/dist/infrastructure/{fs → hitl}/FsProposalRepository.d.ts +0 -0
- /package/dist/infrastructure/{fs → workspace}/FsWorkspaceRepository.d.ts +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { AbsolutePath, UserId, WorkspaceMember, WorkspaceRole } from '@braidhq/schema';
|
|
2
|
+
/**
|
|
3
|
+
* Persists the list of registered workspace rootPaths to a JSON file.
|
|
4
|
+
* Default location is `${BRAID_HOME}/workspaces.json`, set by the caller.
|
|
5
|
+
* Acts as the source of truth across server restarts,
|
|
6
|
+
* the in-memory `FsWorkspaceRepository` cache rebuilds from it on cold start.
|
|
7
|
+
*/
|
|
8
|
+
export declare class WorkspaceRegistryFile {
|
|
9
|
+
private readonly filePath;
|
|
10
|
+
constructor(filePath: string);
|
|
11
|
+
list(): Promise<AbsolutePath[]>;
|
|
12
|
+
add(rootPath: AbsolutePath, initialOwner?: WorkspaceMember): Promise<void>;
|
|
13
|
+
remove(rootPath: AbsolutePath): Promise<void>;
|
|
14
|
+
listMembers(rootPath: AbsolutePath): Promise<WorkspaceMember[]>;
|
|
15
|
+
/**
|
|
16
|
+
* All entries with their members in one read. An admin view can then,
|
|
17
|
+
* invert to a user-to-workspaces map, with no N+1 reads of the file.
|
|
18
|
+
*/
|
|
19
|
+
listAllWithMembers(): Promise<ReadonlyArray<{
|
|
20
|
+
rootPath: AbsolutePath;
|
|
21
|
+
members: readonly WorkspaceMember[];
|
|
22
|
+
}>>;
|
|
23
|
+
getMember(rootPath: AbsolutePath, userId: UserId): Promise<WorkspaceMember | undefined>;
|
|
24
|
+
addMember(rootPath: AbsolutePath, member: WorkspaceMember): Promise<void>;
|
|
25
|
+
updateMember(rootPath: AbsolutePath, userId: UserId, patch: {
|
|
26
|
+
role?: WorkspaceRole;
|
|
27
|
+
skillOverrides?: WorkspaceMember['skillOverrides'];
|
|
28
|
+
}): Promise<WorkspaceMember>;
|
|
29
|
+
removeMember(rootPath: AbsolutePath, userId: UserId): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* In one atomic write, demote the current owner to maintainer,
|
|
32
|
+
* and promote `newOwnerId` to owner.
|
|
33
|
+
* If the target is not yet a maintainer here, this throws.
|
|
34
|
+
* We never auto-add the target,
|
|
35
|
+
* so the caller must add them first when that is needed.
|
|
36
|
+
*/
|
|
37
|
+
transferOwnership(rootPath: AbsolutePath, newOwnerId: UserId): Promise<void>;
|
|
38
|
+
private requireEntry;
|
|
39
|
+
private read;
|
|
40
|
+
private write;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=WorkspaceRegistryFile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkspaceRegistryFile.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/workspace/WorkspaceRegistryFile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AA2B3F;;;;;GAKG;AACH,qBAAa,qBAAqB;IACpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM;IAEvC,IAAI,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAK/B,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAW1E,MAAM,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ7C,WAAW,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAKrE;;;OAGG;IACG,kBAAkB,IAAI,OAAO,CAAC,aAAa,CAAC;QAAE,QAAQ,EAAE,YAAY,CAAC;QAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAA;KAAE,CAAC,CAAC;IAK7G,SAAS,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAKvF,SAAS,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAazE,YAAY,CAChB,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;QAAE,IAAI,CAAC,EAAE,aAAa,CAAC;QAAC,cAAc,CAAC,EAAE,eAAe,CAAC,gBAAgB,CAAC,CAAA;KAAE,GAClF,OAAO,CAAC,eAAe,CAAC;IAoBrB,YAAY,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAczE;;;;;;OAMG;IACG,iBAAiB,CAAC,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAiBpE,YAAY;YAQZ,IAAI;YAgBJ,KAAK;CAIpB"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { NotFoundError, ValidationError } from '@braidhq/core';
|
|
4
|
+
import { AbsolutePath as AbsolutePathSchema, WorkspaceMember as WorkspaceMemberSchema, } from '@braidhq/schema';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
// The registry stores a per-workspace `members[]` list alongside `rootPath`.
|
|
7
|
+
// Old shapes carrying only `rootPath` are accepted by `.default([])`,
|
|
8
|
+
// then lazily upgraded on the next write.
|
|
9
|
+
// `ensureWorkspaceOwners` in `composeFsApp` seeds the default owner,
|
|
10
|
+
// so the single-tenant install keeps working without any manual migration.
|
|
11
|
+
const RegistryEntry = z.object({
|
|
12
|
+
rootPath: AbsolutePathSchema,
|
|
13
|
+
members: z.array(WorkspaceMemberSchema).default([]),
|
|
14
|
+
});
|
|
15
|
+
const RegistryContent = z.object({
|
|
16
|
+
workspaces: z.array(RegistryEntry).default([]),
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* Persists the list of registered workspace rootPaths to a JSON file.
|
|
20
|
+
* Default location is `${BRAID_HOME}/workspaces.json`, set by the caller.
|
|
21
|
+
* Acts as the source of truth across server restarts,
|
|
22
|
+
* the in-memory `FsWorkspaceRepository` cache rebuilds from it on cold start.
|
|
23
|
+
*/
|
|
24
|
+
export class WorkspaceRegistryFile {
|
|
25
|
+
filePath;
|
|
26
|
+
constructor(filePath) {
|
|
27
|
+
this.filePath = filePath;
|
|
28
|
+
}
|
|
29
|
+
async list() {
|
|
30
|
+
const content = await this.read();
|
|
31
|
+
return content.workspaces.map(entry => entry.rootPath);
|
|
32
|
+
}
|
|
33
|
+
async add(rootPath, initialOwner) {
|
|
34
|
+
const content = await this.read();
|
|
35
|
+
if (content.workspaces.some(entry => entry.rootPath === rootPath))
|
|
36
|
+
return;
|
|
37
|
+
content.workspaces.push({
|
|
38
|
+
rootPath,
|
|
39
|
+
members: initialOwner ? [initialOwner] : [],
|
|
40
|
+
});
|
|
41
|
+
await this.write(content);
|
|
42
|
+
}
|
|
43
|
+
async remove(rootPath) {
|
|
44
|
+
const content = await this.read();
|
|
45
|
+
const filtered = content.workspaces.filter(entry => entry.rootPath !== rootPath);
|
|
46
|
+
if (filtered.length === content.workspaces.length)
|
|
47
|
+
return;
|
|
48
|
+
await this.write({ workspaces: filtered });
|
|
49
|
+
}
|
|
50
|
+
async listMembers(rootPath) {
|
|
51
|
+
const entry = await this.requireEntry(rootPath);
|
|
52
|
+
return entry.members;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* All entries with their members in one read. An admin view can then,
|
|
56
|
+
* invert to a user-to-workspaces map, with no N+1 reads of the file.
|
|
57
|
+
*/
|
|
58
|
+
async listAllWithMembers() {
|
|
59
|
+
const content = await this.read();
|
|
60
|
+
return content.workspaces.map(e => ({ rootPath: e.rootPath, members: e.members }));
|
|
61
|
+
}
|
|
62
|
+
async getMember(rootPath, userId) {
|
|
63
|
+
const entry = await this.requireEntry(rootPath);
|
|
64
|
+
return entry.members.find(m => m.userId === userId);
|
|
65
|
+
}
|
|
66
|
+
async addMember(rootPath, member) {
|
|
67
|
+
const content = await this.read();
|
|
68
|
+
const entry = content.workspaces.find(e => e.rootPath === rootPath);
|
|
69
|
+
if (!entry)
|
|
70
|
+
throw new NotFoundError(`Workspace at "${rootPath}" not registered`);
|
|
71
|
+
if (entry.members.some(m => m.userId === member.userId))
|
|
72
|
+
throw new ValidationError(`User "${member.userId}" is already a member of this workspace`);
|
|
73
|
+
if (member.role === 'owner' && entry.members.some(m => m.role === 'owner'))
|
|
74
|
+
throw new ValidationError(`Workspace already has an owner; use transferOwnership instead`);
|
|
75
|
+
entry.members.push(member);
|
|
76
|
+
await this.write(content);
|
|
77
|
+
}
|
|
78
|
+
async updateMember(rootPath, userId, patch) {
|
|
79
|
+
const content = await this.read();
|
|
80
|
+
const entry = content.workspaces.find(e => e.rootPath === rootPath);
|
|
81
|
+
if (!entry)
|
|
82
|
+
throw new NotFoundError(`Workspace at "${rootPath}" not registered`);
|
|
83
|
+
const idx = entry.members.findIndex(m => m.userId === userId);
|
|
84
|
+
if (idx < 0)
|
|
85
|
+
throw new NotFoundError(`User "${userId}" is not a member of this workspace`);
|
|
86
|
+
if (patch.role === 'owner' && entry.members.some(m => m.role === 'owner' && m.userId !== userId))
|
|
87
|
+
throw new ValidationError(`Workspace already has an owner; use transferOwnership to swap`);
|
|
88
|
+
const next = { ...entry.members[idx] };
|
|
89
|
+
if (patch.role !== undefined)
|
|
90
|
+
next.role = patch.role;
|
|
91
|
+
if (patch.skillOverrides !== undefined)
|
|
92
|
+
next.skillOverrides = patch.skillOverrides;
|
|
93
|
+
entry.members[idx] = next;
|
|
94
|
+
await this.write(content);
|
|
95
|
+
return next;
|
|
96
|
+
}
|
|
97
|
+
async removeMember(rootPath, userId) {
|
|
98
|
+
const content = await this.read();
|
|
99
|
+
const entry = content.workspaces.find(e => e.rootPath === rootPath);
|
|
100
|
+
if (!entry)
|
|
101
|
+
return;
|
|
102
|
+
const target = entry.members.find(m => m.userId === userId);
|
|
103
|
+
if (!target)
|
|
104
|
+
return;
|
|
105
|
+
if (target.role === 'owner')
|
|
106
|
+
throw new ValidationError(`Cannot remove the workspace owner; transfer ownership first`);
|
|
107
|
+
entry.members = entry.members.filter(m => m.userId !== userId);
|
|
108
|
+
await this.write(content);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* In one atomic write, demote the current owner to maintainer,
|
|
112
|
+
* and promote `newOwnerId` to owner.
|
|
113
|
+
* If the target is not yet a maintainer here, this throws.
|
|
114
|
+
* We never auto-add the target,
|
|
115
|
+
* so the caller must add them first when that is needed.
|
|
116
|
+
*/
|
|
117
|
+
async transferOwnership(rootPath, newOwnerId) {
|
|
118
|
+
const content = await this.read();
|
|
119
|
+
const entry = content.workspaces.find(e => e.rootPath === rootPath);
|
|
120
|
+
if (!entry)
|
|
121
|
+
throw new NotFoundError(`Workspace at "${rootPath}" not registered`);
|
|
122
|
+
const currentOwner = entry.members.find(m => m.role === 'owner');
|
|
123
|
+
const target = entry.members.find(m => m.userId === newOwnerId);
|
|
124
|
+
if (!target)
|
|
125
|
+
throw new NotFoundError(`User "${newOwnerId}" is not a member of this workspace`);
|
|
126
|
+
if (target.userId === currentOwner?.userId)
|
|
127
|
+
return;
|
|
128
|
+
if (currentOwner)
|
|
129
|
+
currentOwner.role = 'maintainer';
|
|
130
|
+
target.role = 'owner';
|
|
131
|
+
await this.write(content);
|
|
132
|
+
}
|
|
133
|
+
async requireEntry(rootPath) {
|
|
134
|
+
const content = await this.read();
|
|
135
|
+
const entry = content.workspaces.find(e => e.rootPath === rootPath);
|
|
136
|
+
if (!entry)
|
|
137
|
+
throw new NotFoundError(`Workspace at "${rootPath}" not registered`);
|
|
138
|
+
return entry;
|
|
139
|
+
}
|
|
140
|
+
async read() {
|
|
141
|
+
try {
|
|
142
|
+
const raw = await readFile(this.filePath, 'utf-8');
|
|
143
|
+
const parsed = RegistryContent.safeParse(JSON.parse(raw));
|
|
144
|
+
if (!parsed.success) {
|
|
145
|
+
throw new ValidationError(`Invalid workspace registry at "${this.filePath}": ${parsed.error.message}`);
|
|
146
|
+
}
|
|
147
|
+
return parsed.data;
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
if (error.code === 'ENOENT')
|
|
151
|
+
return { workspaces: [] };
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async write(content) {
|
|
156
|
+
await mkdir(dirname(this.filePath), { recursive: true });
|
|
157
|
+
await writeFile(this.filePath, `${JSON.stringify(content, null, 2)}\n`, 'utf-8');
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=WorkspaceRegistryFile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkspaceRegistryFile.js","sourceRoot":"","sources":["../../../src/infrastructure/workspace/WorkspaceRegistryFile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ProductManifest, ProductManifestCreate } from '@braidhq/schema';
|
|
2
|
+
/**
|
|
3
|
+
* Take a user-provided `ProductManifestCreate` and fill in the structure,
|
|
4
|
+
* such as the storage block, so the result is a complete `ProductManifest`,
|
|
5
|
+
* that Zod will accept.
|
|
6
|
+
* Throws if the user's own input is inconsistent.
|
|
7
|
+
*/
|
|
8
|
+
export declare function fillManifestDefaults(draft: ProductManifestCreate): ProductManifest;
|
|
9
|
+
/**
|
|
10
|
+
* Render a `ProductManifest` as YAML-frontmatter markdown,
|
|
11
|
+
* then write it to `<workspaceRoot>/PRODUCT.md`.
|
|
12
|
+
* A missing parent directory is created first,
|
|
13
|
+
* and an existing PRODUCT.md is overwritten.
|
|
14
|
+
*/
|
|
15
|
+
export declare function writeProductManifest(workspaceRoot: string, manifest: ProductManifest, bodyTitle?: string): Promise<string>;
|
|
16
|
+
/**
|
|
17
|
+
* Replace the YAML frontmatter of an existing PRODUCT.md,
|
|
18
|
+
* preserving the markdown body underneath.
|
|
19
|
+
* Workspace mutation endpoints call this,
|
|
20
|
+
* so user prose below the frontmatter survives an update.
|
|
21
|
+
* The file must exist, otherwise this throws.
|
|
22
|
+
*/
|
|
23
|
+
export declare function updateProductManifest(workspaceRoot: string, manifest: ProductManifest): Promise<string>;
|
|
24
|
+
//# sourceMappingURL=productManifestWriter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"productManifestWriter.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/workspace/productManifestWriter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EAGtB,MAAM,iBAAiB,CAAA;AAcxB;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,qBAAqB,GAAG,eAAe,CAWlF;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAShI;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ7G"}
|
|
@@ -2,30 +2,17 @@ import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { OntologyId, ProductManifest as ProductManifestSchema } from '@braidhq/schema';
|
|
4
4
|
import { stringify as stringifyYaml } from 'yaml';
|
|
5
|
-
import { parseMarkdownFrontmatter } from '
|
|
5
|
+
import { parseMarkdownFrontmatter } from '../_shared/frontmatter.js';
|
|
6
6
|
const FRONTMATTER_DELIMITER = '---';
|
|
7
|
-
const DEFAULT_AGENT_BINDING = {
|
|
8
|
-
id: 'claude-default',
|
|
9
|
-
kind: 'claude-code',
|
|
10
|
-
model: 'opus',
|
|
11
|
-
effort: 'high',
|
|
12
|
-
extraArgs: [],
|
|
13
|
-
env: {},
|
|
14
|
-
};
|
|
15
|
-
const DEFAULT_AGENTS = {
|
|
16
|
-
default: 'claude-default',
|
|
17
|
-
tasks: {},
|
|
18
|
-
};
|
|
19
7
|
const DEFAULT_STORAGE = {
|
|
20
8
|
kind: 'kuzu',
|
|
21
9
|
config: {},
|
|
22
10
|
};
|
|
23
|
-
const DEFAULT_CHANNELS = [];
|
|
24
11
|
/**
|
|
25
|
-
* Take a user-provided `
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* inconsistent.
|
|
12
|
+
* Take a user-provided `ProductManifestCreate` and fill in the structure,
|
|
13
|
+
* such as the storage block, so the result is a complete `ProductManifest`,
|
|
14
|
+
* that Zod will accept.
|
|
15
|
+
* Throws if the user's own input is inconsistent.
|
|
29
16
|
*/
|
|
30
17
|
export function fillManifestDefaults(draft) {
|
|
31
18
|
const manifest = {
|
|
@@ -35,17 +22,15 @@ export function fillManifestDefaults(draft) {
|
|
|
35
22
|
ontologyId: draft.ontologyId ?? OntologyId.parse('ddd'),
|
|
36
23
|
sources: draft.sources,
|
|
37
24
|
mcpServers: draft.mcpServers,
|
|
38
|
-
agents: draft.agents ?? DEFAULT_AGENTS,
|
|
39
|
-
agentBindings: draft.agentBindings ?? [DEFAULT_AGENT_BINDING],
|
|
40
25
|
storage: draft.storage ?? DEFAULT_STORAGE,
|
|
41
|
-
channels: draft.channels ?? [...DEFAULT_CHANNELS],
|
|
42
26
|
};
|
|
43
27
|
return ProductManifestSchema.parse(manifest);
|
|
44
28
|
}
|
|
45
29
|
/**
|
|
46
|
-
* Render a `ProductManifest` as YAML-frontmatter markdown
|
|
47
|
-
* to `<workspaceRoot>/PRODUCT.md`.
|
|
48
|
-
* missing
|
|
30
|
+
* Render a `ProductManifest` as YAML-frontmatter markdown,
|
|
31
|
+
* then write it to `<workspaceRoot>/PRODUCT.md`.
|
|
32
|
+
* A missing parent directory is created first,
|
|
33
|
+
* and an existing PRODUCT.md is overwritten.
|
|
49
34
|
*/
|
|
50
35
|
export async function writeProductManifest(workspaceRoot, manifest, bodyTitle) {
|
|
51
36
|
await mkdir(workspaceRoot, { recursive: true });
|
|
@@ -58,10 +43,11 @@ export async function writeProductManifest(workspaceRoot, manifest, bodyTitle) {
|
|
|
58
43
|
return path;
|
|
59
44
|
}
|
|
60
45
|
/**
|
|
61
|
-
* Replace the YAML frontmatter of an existing PRODUCT.md
|
|
62
|
-
* markdown body underneath.
|
|
63
|
-
*
|
|
64
|
-
*
|
|
46
|
+
* Replace the YAML frontmatter of an existing PRODUCT.md,
|
|
47
|
+
* preserving the markdown body underneath.
|
|
48
|
+
* Workspace mutation endpoints call this,
|
|
49
|
+
* so user prose below the frontmatter survives an update.
|
|
50
|
+
* The file must exist, otherwise this throws.
|
|
65
51
|
*/
|
|
66
52
|
export async function updateProductManifest(workspaceRoot, manifest) {
|
|
67
53
|
const path = join(workspaceRoot, 'PRODUCT.md');
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"productManifestWriter.js","sourceRoot":"","sources":["../../../src/infrastructure/workspace/productManifestWriter.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,UAAU,EAAE,eAAe,IAAI,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AACtF,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,MAAM,CAAA;AACjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AAEpE,MAAM,qBAAqB,GAAG,KAAK,CAAA;AAEnC,MAAM,eAAe,GAAsB;IACzC,IAAI,EAAE,MAAqB;IAC3B,MAAM,EAAE,EAAE;CACX,CAAA;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAA4B;IAC/D,MAAM,QAAQ,GAAG;QACf,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,OAAO;QACjC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC;QACvD,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,eAAe;KAC1C,CAAA;IACD,OAAO,qBAAqB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;AAC9C,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,aAAqB,EAAE,QAAyB,EAAE,SAAkB;IAC7G,MAAM,KAAK,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC/C,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAA;IACzE,MAAM,OAAO,GAAG,SAAS,IAAI,QAAQ,CAAC,IAAI,CAAA;IAC1C,MAAM,IAAI,GAAG,OAAO,OAAO,IAAI,CAAA;IAC/B,MAAM,OAAO,GAAG,GAAG,qBAAqB,KAAK,IAAI,KAAK,qBAAqB,KAAK,IAAI,EAAE,CAAA;IACtF,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAA;IAC9C,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACvC,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,aAAqB,EAAE,QAAyB;IAC1F,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAA;IAC9C,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAC9C,MAAM,EAAE,IAAI,EAAE,GAAG,wBAAwB,CAAU,QAAQ,CAAC,CAAA;IAC5D,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAA;IACzE,MAAM,OAAO,GAAG,GAAG,qBAAqB,KAAK,IAAI,KAAK,qBAAqB,KAAK,IAAI,EAAE,CAAA;IACtF,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACvC,OAAO,IAAI,CAAA;AACb,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { UserId as UserIdType } from '@braidhq/schema';
|
|
2
|
+
import type { Context, MiddlewareHandler } from 'hono';
|
|
3
|
+
import type { SessionStore } from '../infrastructure/auth/SessionStore.js';
|
|
4
|
+
declare module 'hono' {
|
|
5
|
+
interface ContextVariableMap {
|
|
6
|
+
userId: UserIdType;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export interface AuthMiddlewareOptions {
|
|
10
|
+
readonly sessionStore?: SessionStore;
|
|
11
|
+
readonly requireAuth: boolean;
|
|
12
|
+
readonly defaultPrincipal: UserIdType | null;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Pull a Bearer token off the request,
|
|
16
|
+
* returning `undefined` when the header is missing or malformed.
|
|
17
|
+
* Route handlers use this to forward the caller's identity,
|
|
18
|
+
* reaching spawned skill subprocesses without reparsing.
|
|
19
|
+
*/
|
|
20
|
+
export declare function extractBearerToken(context: {
|
|
21
|
+
req: {
|
|
22
|
+
header: (name: string) => string | undefined;
|
|
23
|
+
};
|
|
24
|
+
}): string | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* Establish the caller's identity, and gate when auth is enforced.
|
|
27
|
+
* The single place a request's `userId` is resolved.
|
|
28
|
+
*
|
|
29
|
+
* Under local trust, identity comes from `X-Braid-User`, else the default
|
|
30
|
+
* principal, on every path so public routes like `/auth/whoami` see the caller.
|
|
31
|
+
* Nothing is rejected.
|
|
32
|
+
*
|
|
33
|
+
* When auth is enforced, identity comes only from a valid Bearer session, and a
|
|
34
|
+
* missing or invalid token on a non-public route is a 401. The header is never
|
|
35
|
+
* read here, so it cannot impersonate an authenticated caller.
|
|
36
|
+
*/
|
|
37
|
+
export declare function authMiddleware(options: AuthMiddlewareOptions): MiddlewareHandler;
|
|
38
|
+
export declare function getUserId(context: Context): UserIdType;
|
|
39
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAA;AAI1E,OAAO,QAAQ,MAAM,CAAC;IACpB,UAAU,kBAAkB;QAC1B,MAAM,EAAE,UAAU,CAAA;KACnB;CACF;AAoBD,MAAM,WAAW,qBAAqB;IAEpC,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAA;IAEpC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAE7B,QAAQ,CAAC,gBAAgB,EAAE,UAAU,GAAG,IAAI,CAAA;CAC7C;AAWD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAAE,GAAG,EAAE;QAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;KAAE,CAAA;CAAE,GAAG,MAAM,GAAG,SAAS,CAMzH;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,iBAAiB,CAkChF;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAEtD"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { UnauthorizedError } from '@braidhq/core';
|
|
2
|
+
import { UserId } from '@braidhq/schema';
|
|
3
|
+
// Routes the auth middleware never gates,
|
|
4
|
+
// since bootstrapping the login flow needs anonymous access.
|
|
5
|
+
// `/openapi.json` follows the convention that OpenAPI reads publicly,
|
|
6
|
+
// honored by Swagger UI, codegen, and MCP gateways.
|
|
7
|
+
// It documents shape and not data, so exposing it to anonymous callers is safe.
|
|
8
|
+
const PUBLIC_EXACT_PATHS = new Set(['/openapi.json']);
|
|
9
|
+
// Each `/webhooks/<provider>/` prefix is anonymous,
|
|
10
|
+
// because the provider authenticates via a per-source HMAC,
|
|
11
|
+
// checked inside the handler rather than via a Bearer token.
|
|
12
|
+
// Listing providers one by one, rather than the broad `/webhooks/`,
|
|
13
|
+
// keeps a future admin or metrics webhook from inheriting the bypass.
|
|
14
|
+
const PUBLIC_PATH_PREFIXES = ['/auth/', '/health', '/webhooks/github/'];
|
|
15
|
+
// Header naming the caller under local trust, a dev and multi-persona convenience.
|
|
16
|
+
// Read only when auth is not enforced, never on an authenticated deployment,
|
|
17
|
+
// so it can never impersonate a caller behind real auth.
|
|
18
|
+
const USER_HEADER = 'X-Braid-User';
|
|
19
|
+
// EventSource (browser SSE) cannot send custom Authorization headers,
|
|
20
|
+
// so live-update endpoints also accept a `token` query parameter,
|
|
21
|
+
// treated as a Bearer token.
|
|
22
|
+
// Limited to paths ending in `/events`,
|
|
23
|
+
// so the lenient path never applies to mutating routes.
|
|
24
|
+
function isSseEventsPath(path) {
|
|
25
|
+
return path.endsWith('/events');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Pull a Bearer token off the request,
|
|
29
|
+
* returning `undefined` when the header is missing or malformed.
|
|
30
|
+
* Route handlers use this to forward the caller's identity,
|
|
31
|
+
* reaching spawned skill subprocesses without reparsing.
|
|
32
|
+
*/
|
|
33
|
+
export function extractBearerToken(context) {
|
|
34
|
+
const header = context.req.header('Authorization');
|
|
35
|
+
if (!header || !header.startsWith('Bearer '))
|
|
36
|
+
return undefined;
|
|
37
|
+
const token = header.slice('Bearer '.length).trim();
|
|
38
|
+
return token.length > 0 ? token : undefined;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Establish the caller's identity, and gate when auth is enforced.
|
|
42
|
+
* The single place a request's `userId` is resolved.
|
|
43
|
+
*
|
|
44
|
+
* Under local trust, identity comes from `X-Braid-User`, else the default
|
|
45
|
+
* principal, on every path so public routes like `/auth/whoami` see the caller.
|
|
46
|
+
* Nothing is rejected.
|
|
47
|
+
*
|
|
48
|
+
* When auth is enforced, identity comes only from a valid Bearer session, and a
|
|
49
|
+
* missing or invalid token on a non-public route is a 401. The header is never
|
|
50
|
+
* read here, so it cannot impersonate an authenticated caller.
|
|
51
|
+
*/
|
|
52
|
+
export function authMiddleware(options) {
|
|
53
|
+
return async (context, next) => {
|
|
54
|
+
const path = context.req.path;
|
|
55
|
+
if (!options.requireAuth) {
|
|
56
|
+
const header = context.req.header(USER_HEADER);
|
|
57
|
+
const fromHeader = header && header.length > 0 ? UserId.parse(header) : null;
|
|
58
|
+
const resolved = fromHeader ?? options.defaultPrincipal;
|
|
59
|
+
if (resolved)
|
|
60
|
+
context.set('userId', resolved);
|
|
61
|
+
await next();
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
// Public routes bootstrap the login flow, so pass them through ungated,
|
|
65
|
+
// and without reading the header, they must never carry a caller.
|
|
66
|
+
if (PUBLIC_EXACT_PATHS.has(path) || PUBLIC_PATH_PREFIXES.some(prefix => path.startsWith(prefix))) {
|
|
67
|
+
await next();
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
let token = extractBearerToken(context);
|
|
71
|
+
if (!token && isSseEventsPath(path))
|
|
72
|
+
token = context.req.query('token') || undefined;
|
|
73
|
+
if (!token)
|
|
74
|
+
throw new UnauthorizedError('Missing or invalid Authorization header. Sign in to continue.');
|
|
75
|
+
// The composition root always wires sessionStore alongside requireAuth.
|
|
76
|
+
const session = await options.sessionStore.resolve(token);
|
|
77
|
+
if (!session)
|
|
78
|
+
throw new UnauthorizedError('Session expired or revoked. Sign in again.');
|
|
79
|
+
context.set('userId', session.userId);
|
|
80
|
+
await next();
|
|
81
|
+
return undefined;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export function getUserId(context) {
|
|
85
|
+
return context.get('userId');
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AAW7C,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAC5C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,WAAgB,GAAG,iBAAiB,CAkB3E"}
|
package/dist/middleware/cors.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
// Vite dev (5173) and preview (4173) ports, on both loopback hostnames,
|
|
2
|
+
// which browsers treat as distinct origins.
|
|
1
3
|
const DEFAULT_DEV_ORIGINS = [
|
|
2
|
-
'http://localhost:5173',
|
|
3
4
|
'http://localhost:4173',
|
|
5
|
+
'http://localhost:5173',
|
|
6
|
+
'http://127.0.0.1:4173',
|
|
4
7
|
'http://127.0.0.1:5173',
|
|
5
8
|
];
|
|
6
9
|
/**
|
|
@@ -19,7 +22,7 @@ export function corsMiddleware(options = {}) {
|
|
|
19
22
|
}
|
|
20
23
|
if (context.req.method === 'OPTIONS') {
|
|
21
24
|
context.header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS');
|
|
22
|
-
context.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
|
25
|
+
context.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Braid-User');
|
|
23
26
|
context.header('Access-Control-Max-Age', '86400');
|
|
24
27
|
return context.body(null, 204);
|
|
25
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cors.js","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAEA,MAAM,mBAAmB,GAAG;IAC1B,uBAAuB;IACvB,uBAAuB;IACvB,uBAAuB;CACxB,CAAA;AAMD;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,UAAuB,EAAE;IACtD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,cAAc,IAAI,mBAAmB,CAAC,CAAA;IACtE,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAC3C,IAAI,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,MAAM,CAAC,6BAA6B,EAAE,MAAM,CAAC,CAAA;YACrD,OAAO,CAAC,MAAM,CAAC,kCAAkC,EAAE,MAAM,CAAC,CAAA;YAC1D,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QAClC,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACrC,OAAO,CAAC,MAAM,CAAC,8BAA8B,EAAE,wCAAwC,CAAC,CAAA;YACxF,OAAO,CAAC,MAAM,CAAC,8BAA8B,EAAE,
|
|
1
|
+
{"version":3,"file":"cors.js","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAEA,wEAAwE;AACxE,4CAA4C;AAC5C,MAAM,mBAAmB,GAAG;IAC1B,uBAAuB;IACvB,uBAAuB;IACvB,uBAAuB;IACvB,uBAAuB;CACxB,CAAA;AAMD;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,UAAuB,EAAE;IACtD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,cAAc,IAAI,mBAAmB,CAAC,CAAA;IACtE,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAC3C,IAAI,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,MAAM,CAAC,6BAA6B,EAAE,MAAM,CAAC,CAAA;YACrD,OAAO,CAAC,MAAM,CAAC,kCAAkC,EAAE,MAAM,CAAC,CAAA;YAC1D,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QAClC,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACrC,OAAO,CAAC,MAAM,CAAC,8BAA8B,EAAE,wCAAwC,CAAC,CAAA;YACxF,OAAO,CAAC,MAAM,CAAC,8BAA8B,EAAE,2CAA2C,CAAC,CAAA;YAC3F,OAAO,CAAC,MAAM,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAA;YACjD,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAChC,CAAC;QACD,MAAM,IAAI,EAAE,CAAA;QACZ,OAAO,SAAS,CAAA;IAClB,CAAC,CAAA;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/middleware/error.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/middleware/error.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AA4CxC,eAAO,MAAM,YAAY,EAAE,YAkB1B,CAAA"}
|
package/dist/middleware/error.js
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
import { BraidError,
|
|
1
|
+
import { BraidError, ValidationError } from '@braidhq/core';
|
|
2
2
|
import { ZodError } from 'zod';
|
|
3
3
|
const PROBLEM_BASE_URL = 'https://braid.dev/errors';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
// The HTTP status per error code, keyed by the closed BraidErrorCode enum,
|
|
5
|
+
// so a new code fails to compile until it is mapped here.
|
|
6
|
+
const STATUS_BY_CODE = {
|
|
7
|
+
'BRAID-VALIDATION': 400,
|
|
8
|
+
'BRAID-UNAUTHORIZED': 401,
|
|
9
|
+
'BRAID-NOT-FOUND': 404,
|
|
10
|
+
'BRAID-CONFLICT': 409,
|
|
11
|
+
'BRAID-FORBIDDEN': 403,
|
|
12
|
+
'BRAID-UNAVAILABLE': 503,
|
|
13
|
+
'BRAID-INTERNAL': 500,
|
|
14
|
+
};
|
|
13
15
|
function problemFromBraidError(error) {
|
|
14
16
|
const problem = {
|
|
15
17
|
type: `${PROBLEM_BASE_URL}/${error.code.toLowerCase()}`,
|
|
16
18
|
title: error.name,
|
|
17
|
-
status:
|
|
19
|
+
status: STATUS_BY_CODE[error.code],
|
|
18
20
|
code: error.code,
|
|
19
21
|
detail: error.message,
|
|
20
22
|
};
|
|
@@ -24,10 +26,10 @@ function problemFromBraidError(error) {
|
|
|
24
26
|
}
|
|
25
27
|
function problemFromZodError(error) {
|
|
26
28
|
return {
|
|
27
|
-
type: `${PROBLEM_BASE_URL}/braid-
|
|
29
|
+
type: `${PROBLEM_BASE_URL}/braid-validation`,
|
|
28
30
|
title: 'ValidationError',
|
|
29
31
|
status: 400,
|
|
30
|
-
code: 'BRAID-
|
|
32
|
+
code: 'BRAID-VALIDATION',
|
|
31
33
|
detail: error.issues.map(issue => `${issue.path.join('.')}: ${issue.message}`).join('; '),
|
|
32
34
|
};
|
|
33
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/middleware/error.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/middleware/error.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAA;AAE9B,MAAM,gBAAgB,GAAG,0BAA0B,CAAA;AAEnD,2EAA2E;AAC3E,0DAA0D;AAC1D,MAAM,cAAc,GAAmC;IACrD,kBAAkB,EAAE,GAAG;IACvB,oBAAoB,EAAE,GAAG;IACzB,iBAAiB,EAAE,GAAG;IACtB,gBAAgB,EAAE,GAAG;IACrB,iBAAiB,EAAE,GAAG;IACtB,mBAAmB,EAAE,GAAG;IACxB,gBAAgB,EAAE,GAAG;CACtB,CAAA;AAED,SAAS,qBAAqB,CAAC,KAAiB;IAC9C,MAAM,OAAO,GAAqB;QAChC,IAAI,EAAE,GAAG,gBAAgB,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,EAA8B;QACnF,KAAK,EAAE,KAAK,CAAC,IAAI;QACjB,MAAM,EAAE,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC;QAClC,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,MAAM,EAAE,KAAK,CAAC,OAAO;KACtB,CAAA;IACD,IAAI,KAAK,YAAY,eAAe,IAAI,KAAK,CAAC,MAAM;QAClD,OAAO,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAA;IACpC,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAe;IAC1C,OAAO;QACL,IAAI,EAAE,GAAG,gBAAgB,mBAA+C;QACxE,KAAK,EAAE,iBAAiB;QACxB,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,kBAAkB;QACxB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;KAC1F,CAAA;AACH,CAAC;AAED,MAAM,oBAAoB,GAAG,EAAE,cAAc,EAAE,0BAA0B,EAAW,CAAA;AAEpF,MAAM,CAAC,MAAM,YAAY,GAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IAC3D,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAA;QAC5C,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,MAA8B,EAAE,oBAAoB,CAAC,CAAA;IAC5F,CAAC;IAED,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAA;QAC1C,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,MAA8B,EAAE,oBAAoB,CAAC,CAAA;IAC5F,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC;QAClB,IAAI,EAAE,GAAG,gBAAgB,WAAW;QACpC,KAAK,EAAE,eAAe;QACtB,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,gBAAgB;QACtB,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;KACjE,EAAE,GAAG,EAAE,oBAAoB,CAAC,CAAA;AAC/B,CAAC,CAAA"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { WorkspaceService } from '@braidhq/core';
|
|
2
|
+
import type { Context, MiddlewareHandler } from 'hono';
|
|
3
|
+
import type { UserRegistryFile } from '../infrastructure/users/UserRegistryFile.js';
|
|
4
|
+
import type { WorkspaceRegistryFile } from '../infrastructure/workspace/WorkspaceRegistryFile.js';
|
|
5
|
+
import type { Capability, ViewerContext } from '../policy/index.js';
|
|
6
|
+
/**
|
|
7
|
+
* Server-scope capability guard for actions without a workspace context,
|
|
8
|
+
* such as workspace creation.
|
|
9
|
+
* Builds a viewer with an absent member,
|
|
10
|
+
* so non-admin users resolve to a null effectiveRole,
|
|
11
|
+
* and fail every check by construction.
|
|
12
|
+
*
|
|
13
|
+
* Skips the gate when userRegistry is absent,
|
|
14
|
+
* so in-memory test compositions stay open.
|
|
15
|
+
* Production deployments always pass it.
|
|
16
|
+
*/
|
|
17
|
+
export declare function requireServerCapability(capability: Capability, userRegistry: UserRegistryFile | undefined): MiddlewareHandler;
|
|
18
|
+
declare module 'hono' {
|
|
19
|
+
interface ContextVariableMap {
|
|
20
|
+
viewerContext: ViewerContext;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export interface WorkspaceAccessOptions {
|
|
24
|
+
readonly registry: WorkspaceRegistryFile;
|
|
25
|
+
readonly workspaceService: WorkspaceService;
|
|
26
|
+
readonly userRegistry: UserRegistryFile;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolves the caller's ViewerContext for this workspace,
|
|
30
|
+
* and stashes it on the Hono context for every downstream layer to read.
|
|
31
|
+
* Composes after `workspaceIdMiddleware` and `authMiddleware`.
|
|
32
|
+
* Outsiders get 403 here, meaning no member row and not a server admin.
|
|
33
|
+
*
|
|
34
|
+
* The actual policy decisions live in `policy/`.
|
|
35
|
+
* This middleware only builds the viewer,
|
|
36
|
+
* and rejects unauthenticated outsiders.
|
|
37
|
+
*/
|
|
38
|
+
export declare function workspaceAccessMiddleware(options: WorkspaceAccessOptions): MiddlewareHandler;
|
|
39
|
+
export declare function getViewerContext(context: Context): ViewerContext | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Mutation guard.
|
|
42
|
+
* Returns 403 when the viewer cannot perform the given capability.
|
|
43
|
+
* Optional `buildResource` lets a capability such as `skill.run`
|
|
44
|
+
* attach per-request data the check needs.
|
|
45
|
+
*
|
|
46
|
+
* Compositions that don't mount `workspaceAccessMiddleware`,
|
|
47
|
+
* such as in-memory tests or the headless server, skip the gate.
|
|
48
|
+
* Production deployments always mount it, so the gate is real.
|
|
49
|
+
*/
|
|
50
|
+
export declare function requirePermission(capability: Capability, buildResource?: (context: Context) => Promise<ViewerContext['resource']>): MiddlewareHandler;
|
|
51
|
+
//# sourceMappingURL=workspaceAccess.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspaceAccess.d.ts","sourceRoot":"","sources":["../../src/middleware/workspaceAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAA;AACnF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sDAAsD,CAAA;AACjG,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAMnE;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,gBAAgB,GAAG,SAAS,GACzC,iBAAiB,CAgBnB;AAED,OAAO,QAAQ,MAAM,CAAC;IACpB,UAAU,kBAAkB;QAC1B,aAAa,EAAE,aAAa,CAAA;KAC7B;CACF;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAA;IACxC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAA;IAC3C,QAAQ,CAAC,YAAY,EAAE,gBAAgB,CAAA;CACxC;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,sBAAsB,GAAG,iBAAiB,CAgB5F;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,GAAG,SAAS,CAE5E;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,UAAU,EACtB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,GACvE,iBAAiB,CAcnB"}
|