@bevel-software/platform-core-backend 0.11.0 → 0.11.2
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/dist/core/create-core-services.d.ts +1 -1
- package/dist/core/create-core-services.d.ts.map +1 -1
- package/dist/core/create-core-services.js +2 -2
- package/dist/core/create-core-services.js.map +1 -1
- package/dist/modules/access/access-control.service.d.ts +1 -253
- package/dist/modules/access/access-control.service.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.js +3 -632
- package/dist/modules/access/access-control.service.js.map +1 -1
- package/dist/modules/access/access-declarations.d.ts +2 -2
- package/dist/modules/access/access-declarations.d.ts.map +1 -1
- package/dist/modules/access/access-declarations.js +2 -2
- package/dist/modules/access/access-declarations.js.map +1 -1
- package/dist/modules/access/access-mutation.service.d.ts +3 -3
- package/dist/modules/access/access-mutation.service.d.ts.map +1 -1
- package/dist/modules/access/access-mutation.service.js +3 -3
- package/dist/modules/access/access-mutation.service.js.map +1 -1
- package/dist/modules/access/access.routes.js +4 -4
- package/dist/modules/access/access.routes.js.map +1 -1
- package/dist/modules/access/admin-locked-commit.d.ts +2 -2
- package/dist/modules/access/admin-locked-commit.d.ts.map +1 -1
- package/dist/modules/access/admin-locked-commit.js +2 -2
- package/dist/modules/access/admin-locked-commit.js.map +1 -1
- package/dist/modules/access/admin-route-helpers.js +1 -1
- package/dist/modules/access/admin-route-helpers.js.map +1 -1
- package/dist/modules/access/capability-registry.js +1 -1
- package/dist/modules/access/capability-registry.js.map +1 -1
- package/dist/modules/access/creator-access.d.ts +1 -45
- package/dist/modules/access/creator-access.d.ts.map +1 -1
- package/dist/modules/access/creator-access.js +4 -24
- package/dist/modules/access/creator-access.js.map +1 -1
- package/dist/modules/access/groups-admin.routes.js +1 -1
- package/dist/modules/access/groups-admin.routes.js.map +1 -1
- package/dist/modules/access/groups-admin.service.d.ts +1 -1
- package/dist/modules/access/groups-admin.service.d.ts.map +1 -1
- package/dist/modules/access/groups-admin.service.js +6 -5
- package/dist/modules/access/groups-admin.service.js.map +1 -1
- package/dist/modules/access/groups-edit.js +2 -2
- package/dist/modules/access/groups-edit.js.map +1 -1
- package/dist/modules/access/reference-scan.js +1 -1
- package/dist/modules/access/reference-scan.js.map +1 -1
- package/dist/modules/access/roles-admin.service.d.ts +1 -1
- package/dist/modules/access/roles-admin.service.d.ts.map +1 -1
- package/dist/modules/access/roles-admin.service.js +8 -7
- package/dist/modules/access/roles-admin.service.js.map +1 -1
- package/dist/modules/access/roles-edit.js +1 -1
- package/dist/modules/access/roles-edit.js.map +1 -1
- package/dist/modules/access/synced-groups-committer.js +4 -4
- package/dist/modules/access/synced-groups-committer.js.map +1 -1
- package/dist/modules/access/synced-groups-writer.js +2 -2
- package/dist/modules/access/synced-groups-writer.js.map +1 -1
- package/dist/modules/access-model/access-errors.d.ts +34 -0
- package/dist/modules/access-model/access-errors.d.ts.map +1 -0
- package/dist/modules/access-model/access-errors.js +40 -0
- package/dist/modules/access-model/access-errors.js.map +1 -0
- package/dist/modules/access-model/access-grammar.d.ts +266 -0
- package/dist/modules/access-model/access-grammar.d.ts.map +1 -0
- package/dist/modules/access-model/access-grammar.js +644 -0
- package/dist/modules/access-model/access-grammar.js.map +1 -0
- package/dist/modules/access-model/access-splice.d.ts +140 -0
- package/dist/modules/access-model/access-splice.d.ts.map +1 -0
- package/dist/modules/access-model/access-splice.js +389 -0
- package/dist/modules/access-model/access-splice.js.map +1 -0
- package/dist/modules/access-model/creator.d.ts +54 -0
- package/dist/modules/access-model/creator.d.ts.map +1 -0
- package/dist/modules/access-model/creator.js +30 -0
- package/dist/modules/access-model/creator.js.map +1 -0
- package/dist/modules/access-model/group-files.d.ts +83 -0
- package/dist/modules/access-model/group-files.d.ts.map +1 -0
- package/dist/modules/access-model/group-files.js +167 -0
- package/dist/modules/access-model/group-files.js.map +1 -0
- package/dist/modules/access-model/kb-read-filter.d.ts +41 -0
- package/dist/modules/access-model/kb-read-filter.d.ts.map +1 -0
- package/dist/modules/access-model/kb-read-filter.js +60 -0
- package/dist/modules/access-model/kb-read-filter.js.map +1 -0
- package/dist/modules/access-model/render-roles-yaml.d.ts +22 -0
- package/dist/modules/access-model/render-roles-yaml.d.ts.map +1 -0
- package/dist/modules/access-model/render-roles-yaml.js +56 -0
- package/dist/modules/access-model/render-roles-yaml.js.map +1 -0
- package/dist/modules/access-model/roles-yaml-guard.d.ts +56 -0
- package/dist/modules/access-model/roles-yaml-guard.d.ts.map +1 -0
- package/dist/modules/access-model/roles-yaml-guard.js +79 -0
- package/dist/modules/access-model/roles-yaml-guard.js.map +1 -0
- package/dist/modules/admin/admin-access.service.d.ts.map +1 -1
- package/dist/modules/admin/admin-access.service.js +1 -1
- package/dist/modules/admin/admin-access.service.js.map +1 -1
- package/dist/modules/diff/diff.routes.js +4 -4
- package/dist/modules/diff/diff.routes.js.map +1 -1
- package/dist/modules/diff/diff.service.d.ts +1 -1
- package/dist/modules/diff/diff.service.d.ts.map +1 -1
- package/dist/modules/kb-fs/branch-name.d.ts +10 -0
- package/dist/modules/kb-fs/branch-name.d.ts.map +1 -0
- package/dist/modules/kb-fs/branch-name.js +76 -0
- package/dist/modules/kb-fs/branch-name.js.map +1 -0
- package/dist/modules/kb-fs/clone-config.d.ts +61 -0
- package/dist/modules/kb-fs/clone-config.d.ts.map +1 -0
- package/dist/modules/kb-fs/clone-config.js +69 -0
- package/dist/modules/kb-fs/clone-config.js.map +1 -0
- package/dist/modules/kb-fs/file-change-notifier.d.ts +38 -0
- package/dist/modules/kb-fs/file-change-notifier.d.ts.map +1 -0
- package/dist/modules/kb-fs/file-change-notifier.js +22 -0
- package/dist/modules/kb-fs/file-change-notifier.js.map +1 -0
- package/dist/modules/kb-fs/locking-filesystem.d.ts +137 -0
- package/dist/modules/kb-fs/locking-filesystem.d.ts.map +1 -0
- package/dist/modules/kb-fs/locking-filesystem.js +553 -0
- package/dist/modules/kb-fs/locking-filesystem.js.map +1 -0
- package/dist/modules/kb-fs/mutex.d.ts +11 -0
- package/dist/modules/kb-fs/mutex.d.ts.map +1 -0
- package/dist/modules/kb-fs/mutex.js +23 -0
- package/dist/modules/kb-fs/mutex.js.map +1 -0
- package/dist/modules/kb-fs/read-only-filesystem.d.ts +24 -0
- package/dist/modules/kb-fs/read-only-filesystem.d.ts.map +1 -0
- package/dist/modules/kb-fs/read-only-filesystem.js +39 -0
- package/dist/modules/kb-fs/read-only-filesystem.js.map +1 -0
- package/dist/modules/plugins/join-proposals.d.ts +1 -1
- package/dist/modules/plugins/join-proposals.d.ts.map +1 -1
- package/dist/modules/plugins/join-proposals.js +1 -1
- package/dist/modules/plugins/join-proposals.js.map +1 -1
- package/dist/modules/plugins/join-requests.service.d.ts.map +1 -1
- package/dist/modules/plugins/join-requests.service.js +1 -1
- package/dist/modules/plugins/join-requests.service.js.map +1 -1
- package/dist/modules/plugins/plugin-provision.service.js +3 -3
- package/dist/modules/plugins/plugin-provision.service.js.map +1 -1
- package/dist/modules/plugins/plugins.routes.js +2 -2
- package/dist/modules/plugins/plugins.routes.js.map +1 -1
- package/dist/modules/plugins/plugins.service.js +1 -1
- package/dist/modules/plugins/plugins.service.js.map +1 -1
- package/dist/modules/secrets-vault/secrets-vault.routes.js +1 -1
- package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -1
- package/dist/modules/skills/pending-skills.service.d.ts.map +1 -1
- package/dist/modules/skills/pending-skills.service.js +1 -1
- package/dist/modules/skills/pending-skills.service.js.map +1 -1
- package/dist/modules/skills/skills.service.js +1 -1
- package/dist/modules/skills/skills.service.js.map +1 -1
- package/dist/modules/tool-helpers/tool-context.d.ts +2 -2
- package/dist/modules/tool-helpers/tool-context.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool-context.js +4 -4
- package/dist/modules/tool-helpers/tool-context.js.map +1 -1
- package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts +1 -1
- package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts.map +1 -1
- package/dist/modules/tool-manuals/mcp-server-edit.service.js +1 -1
- package/dist/modules/tool-manuals/mcp-server-edit.service.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.routes.d.ts +1 -1
- package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.routes.js +1 -1
- package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.service.js +1 -1
- package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.tools.js +1 -1
- package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.js +1 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
- package/dist/modules/workflow/file-lock.service.js +1 -1
- package/dist/modules/workflow/file-lock.service.js.map +1 -1
- package/dist/modules/workflow/git/git.service.d.ts +2 -2
- package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
- package/dist/modules/workflow/git/git.service.js +5 -5
- package/dist/modules/workflow/git/git.service.js.map +1 -1
- package/dist/modules/workflow/git/pull-request.service.js +1 -1
- package/dist/modules/workflow/git/pull-request.service.js.map +1 -1
- package/dist/modules/workflow/review-workflow/review-workflow.service.js +2 -2
- package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -1
- package/dist/modules/workflow/session-ontology.service.js +1 -1
- package/dist/modules/workflow/session-ontology.service.js.map +1 -1
- package/dist/modules/workflow/workflow.routes.js +2 -2
- package/dist/modules/workflow/workflow.routes.js.map +1 -1
- package/dist/modules/workflow/workflow.service.d.ts +1 -1
- package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.service.js +4 -4
- package/dist/modules/workflow/workflow.service.js.map +1 -1
- package/dist/modules/workspace/startup/kb-startup-runner.js +1 -1
- package/dist/modules/workspace/startup/kb-startup-runner.js.map +1 -1
- package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js +1 -1
- package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js.map +1 -1
- package/dist/modules/workspace/startup/steps/roles-yaml.step.d.ts +1 -1
- package/dist/modules/workspace/startup/steps/roles-yaml.step.js +2 -2
- package/dist/modules/workspace/startup/steps/roles-yaml.step.js.map +1 -1
- package/dist/modules/workspace/startup/steps/seed-tree.js +1 -1
- package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -1
- package/dist/modules/workspace/workspace.routes.d.ts +1 -1
- package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.routes.js +5 -4
- package/dist/modules/workspace/workspace.routes.js.map +1 -1
- package/dist/modules/workspace/workspace.service.d.ts +2 -9
- package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.service.js +14 -15
- package/dist/modules/workspace/workspace.service.js.map +1 -1
- package/dist/modules/workspace/workspace.tools.js +3 -3
- package/dist/modules/workspace/workspace.tools.js.map +1 -1
- package/dist/shared/domain-errors.d.ts +202 -0
- package/dist/shared/domain-errors.d.ts.map +1 -0
- package/dist/shared/domain-errors.js +303 -0
- package/dist/shared/domain-errors.js.map +1 -0
- package/dist/shared/workspace-id.d.ts +27 -0
- package/dist/shared/workspace-id.d.ts.map +1 -0
- package/dist/shared/workspace-id.js +36 -0
- package/dist/shared/workspace-id.js.map +1 -0
- package/package.json +3 -3
- package/src/core/create-core-services.ts +2 -2
- package/src/modules/access/__tests__/access-control.service.test.ts +1 -1
- package/src/modules/access/__tests__/access-groups.test.ts +6 -5
- package/src/modules/access/__tests__/access-md-format.test.ts +3 -3
- package/src/modules/access/__tests__/access-mutation.service.test.ts +1 -1
- package/src/modules/access/__tests__/admin-locked-commit.test.ts +1 -1
- package/src/modules/access/__tests__/admin-route-helpers.test.ts +1 -1
- package/src/modules/access/__tests__/roles-admin.service.test.ts +2 -2
- package/src/modules/access/__tests__/roles-edit.test.ts +1 -1
- package/src/modules/access/__tests__/synced-groups-committer.test.ts +1 -1
- package/src/modules/access/__tests__/synced-groups-writer.test.ts +1 -1
- package/src/modules/access/access-control.service.ts +23 -768
- package/src/modules/access/access-declarations.ts +2 -2
- package/src/modules/access/access-mutation.service.ts +3 -3
- package/src/modules/access/access.routes.ts +5 -5
- package/src/modules/access/admin-locked-commit.ts +2 -2
- package/src/modules/access/admin-route-helpers.ts +1 -1
- package/src/modules/access/capability-registry.ts +1 -1
- package/src/modules/access/creator-access.ts +9 -72
- package/src/modules/access/groups-admin.routes.ts +1 -1
- package/src/modules/access/groups-admin.service.ts +6 -7
- package/src/modules/access/groups-edit.ts +2 -2
- package/src/modules/access/reference-scan.ts +1 -1
- package/src/modules/access/roles-admin.service.ts +8 -8
- package/src/modules/access/roles-edit.ts +1 -1
- package/src/modules/access/synced-groups-committer.ts +4 -4
- package/src/modules/access/synced-groups-writer.ts +2 -2
- package/src/modules/access-model/__tests__/access-grammar.test.ts +31 -0
- package/src/modules/{access → access-model}/__tests__/access-splice.test.ts +268 -268
- package/src/modules/{access → access-model}/access-errors.ts +1 -1
- package/src/modules/access-model/access-grammar.ts +778 -0
- package/src/modules/{access → access-model}/access-splice.ts +1 -1
- package/src/modules/access-model/creator.ts +79 -0
- package/src/modules/{access → access-model}/group-files.ts +1 -1
- package/src/modules/{access → access-model}/render-roles-yaml.ts +1 -1
- package/src/modules/{access → access-model}/roles-yaml-guard.ts +2 -2
- package/src/modules/admin/admin-access.service.ts +2 -1
- package/src/modules/diff/__tests__/diff.routes.rejectPathsLocked.test.ts +2 -2
- package/src/modules/diff/__tests__/diff.service.seed-atomicity.test.ts +3 -2
- package/src/modules/diff/__tests__/diff.service.test.ts +3 -2
- package/src/modules/diff/diff.routes.ts +4 -4
- package/src/modules/diff/diff.service.ts +1 -1
- package/src/modules/{workflow/git → kb-fs}/__tests__/branch-name.test.ts +1 -1
- package/src/modules/{workflow → kb-fs}/__tests__/locking-filesystem.test.ts +1 -1
- package/src/modules/{workflow/git → kb-fs}/branch-name.ts +1 -1
- package/src/modules/{workflow → kb-fs}/locking-filesystem.ts +2 -2
- package/src/modules/plugins/__tests__/join-requests.service.test.ts +2 -4
- package/src/modules/plugins/__tests__/plugin-index.service.test.ts +1 -1
- package/src/modules/plugins/__tests__/plugins.routes.test.ts +1 -1
- package/src/modules/plugins/join-proposals.ts +1 -1
- package/src/modules/plugins/join-requests.service.ts +2 -1
- package/src/modules/plugins/plugin-provision.service.ts +3 -3
- package/src/modules/plugins/plugins.routes.ts +2 -2
- package/src/modules/plugins/plugins.service.ts +1 -1
- package/src/modules/secrets-vault/secrets-vault.routes.ts +1 -1
- package/src/modules/skills/__tests__/skills.service.test.ts +1 -1
- package/src/modules/skills/pending-skills.service.ts +2 -1
- package/src/modules/skills/skills.service.ts +1 -1
- package/src/modules/tool-helpers/tool-context.ts +6 -5
- package/src/modules/tool-manuals/__tests__/mcp-server-edit.service.test.ts +1 -1
- package/src/modules/tool-manuals/__tests__/tool-manuals.archive.route.test.ts +1 -1
- package/src/modules/tool-manuals/__tests__/tool-manuals.detail.route.test.ts +1 -1
- package/src/modules/tool-manuals/__tests__/tool-manuals.mcp-oauth.test.ts +1 -1
- package/src/modules/tool-manuals/__tests__/tool-manuals.service.test.ts +1 -1
- package/src/modules/tool-manuals/mcp-server-edit.service.ts +2 -1
- package/src/modules/tool-manuals/tool-manuals.routes.ts +2 -1
- package/src/modules/tool-manuals/tool-manuals.service.ts +1 -1
- package/src/modules/tool-manuals/tool-manuals.tools.ts +1 -1
- package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +1 -1
- package/src/modules/workflow/__tests__/workflow.service.commitFileWhileLocked.test.ts +1 -1
- package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +1 -1
- package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +1 -1
- package/src/modules/workflow/agent-tools/workflow.tools.ts +1 -1
- package/src/modules/workflow/file-lock.service.ts +1 -1
- package/src/modules/workflow/git/__tests__/git.service.accessGating.test.ts +1 -1
- package/src/modules/workflow/git/__tests__/git.service.deleteBranch.test.ts +1 -1
- package/src/modules/workflow/git/__tests__/git.service.diffFileAtCommit.test.ts +1 -1
- package/src/modules/workflow/git/__tests__/git.service.diffFileBetweenBranches.test.ts +1 -1
- package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +1 -1
- package/src/modules/workflow/git/git.service.ts +5 -5
- package/src/modules/workflow/git/pull-request.service.ts +1 -1
- package/src/modules/workflow/review-workflow/__tests__/cancel-pr.test.ts +1 -1
- package/src/modules/workflow/review-workflow/review-workflow.service.ts +2 -2
- package/src/modules/workflow/session-ontology.service.ts +1 -1
- package/src/modules/workflow/workflow.routes.ts +2 -2
- package/src/modules/workflow/workflow.service.ts +5 -5
- package/src/modules/workspace/__tests__/workspace.routes.create-grant.test.ts +1 -1
- package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +1 -1
- package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +2 -2
- package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +1 -1
- package/src/modules/workspace/__tests__/workspace.service.read-filter.test.ts +2 -5
- package/src/modules/workspace/__tests__/workspace.service.test.ts +13 -1
- package/src/modules/workspace/__tests__/workspace.tools.test.ts +1 -1
- package/src/modules/workspace/startup/kb-startup-runner.ts +1 -1
- package/src/modules/workspace/startup/steps/__tests__/steps.test.ts +1 -1
- package/src/modules/workspace/startup/steps/groups-to-plugins.step.ts +1 -1
- package/src/modules/workspace/startup/steps/roles-yaml.step.ts +2 -2
- package/src/modules/workspace/startup/steps/seed-tree.ts +1 -1
- package/src/modules/workspace/workspace.routes.ts +6 -5
- package/src/modules/workspace/workspace.service.ts +14 -18
- package/src/modules/workspace/workspace.tools.ts +3 -3
- package/src/shared/__tests__/join-request.test.ts +1 -1
- package/src/shared/__tests__/workspace-id.test.ts +17 -0
- package/src/{modules/workflow/workflow.errors.ts → shared/domain-errors.ts} +6 -1
- package/src/shared/workspace-id.ts +36 -0
- /package/src/modules/{access → access-model}/__tests__/kb-read-filter.test.ts +0 -0
- /package/src/modules/{access → access-model}/__tests__/roles-yaml-guard.test.ts +0 -0
- /package/src/modules/{access → access-model}/kb-read-filter.ts +0 -0
- /package/src/modules/{workflow/git → kb-fs}/__tests__/clone-config.test.ts +0 -0
- /package/src/modules/{workflow → kb-fs}/__tests__/file-change-notifier.test.ts +0 -0
- /package/src/modules/{workflow/git → kb-fs}/__tests__/mutex.test.ts +0 -0
- /package/src/modules/{workflow/git → kb-fs}/clone-config.ts +0 -0
- /package/src/modules/{workflow → kb-fs}/file-change-notifier.ts +0 -0
- /package/src/modules/{workflow/git → kb-fs}/mutex.ts +0 -0
- /package/src/modules/{workflow → kb-fs}/read-only-filesystem.ts +0 -0
|
@@ -15,9 +15,9 @@ import type {
|
|
|
15
15
|
import type { WorkspaceService } from '../../workspace/workspace.service.js';
|
|
16
16
|
import type { WorkflowHooks, CommitValidationContext } from '../workflow-hooks.js';
|
|
17
17
|
import type { IAccessControl } from '../../access/access-control.interface.js';
|
|
18
|
-
import { AccessDeniedError } from '../../access/access-errors.js';
|
|
19
|
-
import { WorkspaceMutex } from '
|
|
20
|
-
import { cloneTrackingConfigArgs, SAFE_IMPLICIT_FETCH_ARGS } from '
|
|
18
|
+
import { AccessDeniedError } from '../../access-model/access-errors.js';
|
|
19
|
+
import { WorkspaceMutex } from '../../kb-fs/mutex.js';
|
|
20
|
+
import { cloneTrackingConfigArgs, SAFE_IMPLICIT_FETCH_ARGS } from '../../kb-fs/clone-config.js';
|
|
21
21
|
import {
|
|
22
22
|
assertValidBranchName,
|
|
23
23
|
assertValidRelativePath,
|
|
@@ -25,13 +25,13 @@ import {
|
|
|
25
25
|
isOwnSuggestionsBranch,
|
|
26
26
|
isProtectedBranch,
|
|
27
27
|
PROTECTED_BRANCHES,
|
|
28
|
-
} from '
|
|
28
|
+
} from '../../kb-fs/branch-name.js';
|
|
29
29
|
import {
|
|
30
30
|
BranchAuthorshipError,
|
|
31
31
|
WorkflowValidationError,
|
|
32
32
|
ProtectedBranchError,
|
|
33
33
|
PullRebaseConflictError,
|
|
34
|
-
} from '
|
|
34
|
+
} from '../../../shared/domain-errors.js';
|
|
35
35
|
|
|
36
36
|
const execFileAsync = promisify(execFile);
|
|
37
37
|
|
|
@@ -13,7 +13,7 @@ import { changeRequests } from '../../database/schema.js';
|
|
|
13
13
|
import type { WorkspaceService } from '../../workspace/workspace.service.js';
|
|
14
14
|
import type { IAccessControl } from '../../access/access-control.interface.js';
|
|
15
15
|
import type { GitService } from './git.service.js';
|
|
16
|
-
import { WorkflowValidationError } from '
|
|
16
|
+
import { WorkflowValidationError } from '../../../shared/domain-errors.js';
|
|
17
17
|
import { hashEmail } from '../../../shared/hash-email.js';
|
|
18
18
|
|
|
19
19
|
const LIST_PR_CACHE_TTL_MS = 30_000;
|
|
@@ -6,7 +6,7 @@ import type { WorkspaceService } from '../../../workspace/workspace.service.js';
|
|
|
6
6
|
import type { GitService } from '../../git/git.service.js';
|
|
7
7
|
import type { IAccessControl } from '../../../access/access-control.interface.js';
|
|
8
8
|
import { hashEmail } from '../../../../shared/hash-email.js';
|
|
9
|
-
import { WorkflowValidationError } from '
|
|
9
|
+
import { WorkflowValidationError } from '../../../../shared/domain-errors.js';
|
|
10
10
|
|
|
11
11
|
// Cancel is now a DB state flip (no `gh`): `update(change_requests) … WHERE
|
|
12
12
|
// number = ? AND state = 'open'`. This spy stands in for the update's
|
|
@@ -13,13 +13,13 @@ import type {
|
|
|
13
13
|
import type { Database } from '../../database/connection.js';
|
|
14
14
|
import { changeRequests, prComments, prFileApprovals, prMergeLog } from '../../database/schema.js';
|
|
15
15
|
import type { IAccessControl } from '../../access/access-control.interface.js';
|
|
16
|
-
import { isAccessMdPath } from '../../access/access-
|
|
16
|
+
import { isAccessMdPath } from '../../access-model/access-grammar.js';
|
|
17
17
|
import type { GitService } from '../git/git.service.js';
|
|
18
18
|
import {
|
|
19
19
|
ChangeRequestConflictsError,
|
|
20
20
|
WorkflowDomainError,
|
|
21
21
|
WorkflowValidationError,
|
|
22
|
-
} from '
|
|
22
|
+
} from '../../../shared/domain-errors.js';
|
|
23
23
|
import type { WorkspaceService } from '../../workspace/workspace.service.js';
|
|
24
24
|
import { hashEmail } from '../../../shared/hash-email.js';
|
|
25
25
|
import type {
|
|
@@ -37,7 +37,7 @@ import { ontologyOf } from '../../shared/kb-layout.js';
|
|
|
37
37
|
import type { Database } from '../database/connection.js';
|
|
38
38
|
import { sessionOntologyTouches } from '../database/schema.js';
|
|
39
39
|
import { recordTouch, decideWrite, type WriteDecision } from './session-ontology.policy.js';
|
|
40
|
-
import { WorkspaceMutex } from '
|
|
40
|
+
import { WorkspaceMutex } from '../kb-fs/mutex.js';
|
|
41
41
|
|
|
42
42
|
export type OperationDecision =
|
|
43
43
|
| { allow: true; touched: string[] }
|
|
@@ -27,9 +27,9 @@ import type {
|
|
|
27
27
|
} from '@bevel-software/platform-shared';
|
|
28
28
|
import type { AuthService } from '../auth/auth.service.js';
|
|
29
29
|
import type { WorkspaceService } from '../workspace/workspace.service.js';
|
|
30
|
-
import { branchForWorkspaceId } from '
|
|
30
|
+
import { branchForWorkspaceId } from '../../shared/workspace-id.js';
|
|
31
31
|
import type { WorkflowEventBus } from './event-bus.js';
|
|
32
|
-
import { WorkflowDomainError } from '
|
|
32
|
+
import { WorkflowDomainError } from '../../shared/domain-errors.js';
|
|
33
33
|
import '../auth/auth.middleware.js'; // Express Request augmentation
|
|
34
34
|
|
|
35
35
|
function toHttpError(
|
|
@@ -49,14 +49,14 @@ import type { GitService } from './git/git.service.js';
|
|
|
49
49
|
import type { PullRequestService } from './git/pull-request.service.js';
|
|
50
50
|
import type { IReviewWorkflowService } from './review-workflow/review-workflow.interface.js';
|
|
51
51
|
import type { WorkspaceService } from '../workspace/workspace.service.js';
|
|
52
|
-
import { workspaceIdForBranch } from '
|
|
52
|
+
import { workspaceIdForBranch } from '../../shared/workspace-id.js';
|
|
53
53
|
import type { IAccessControl } from '../access/access-control.interface.js';
|
|
54
54
|
import { FileLockService } from './file-lock.service.js';
|
|
55
55
|
import { PendingCommitsService } from './pending-commits.service.js';
|
|
56
56
|
import type { WorkflowEventBus } from './event-bus.js';
|
|
57
|
-
import type { FileChangeNotifier } from '
|
|
57
|
+
import type { FileChangeNotifier } from '../kb-fs/file-change-notifier.js';
|
|
58
58
|
import { WorkflowHooks } from './workflow-hooks.js';
|
|
59
|
-
import { WorkspaceMutex } from '
|
|
59
|
+
import { WorkspaceMutex } from '../kb-fs/mutex.js';
|
|
60
60
|
import { hashEmail } from '../../shared/hash-email.js';
|
|
61
61
|
import {
|
|
62
62
|
ChangeRequestConflictsError,
|
|
@@ -66,9 +66,9 @@ import {
|
|
|
66
66
|
PushNeedsAgentResolutionError,
|
|
67
67
|
WorkflowDomainError,
|
|
68
68
|
WorkflowValidationError,
|
|
69
|
-
} from '
|
|
69
|
+
} from '../../shared/domain-errors.js';
|
|
70
70
|
import { RECOVERY_BOT_EMAIL, RECOVERY_BOT_NAME } from './recovery-bot.js';
|
|
71
|
-
import { AccessDeniedError } from '../access/access-errors.js';
|
|
71
|
+
import { AccessDeniedError } from '../access-model/access-errors.js';
|
|
72
72
|
|
|
73
73
|
const execFileAsync = promisify(execFile);
|
|
74
74
|
|
|
@@ -4,7 +4,7 @@ import express from 'express';
|
|
|
4
4
|
import { describe, it, expect, afterEach, vi } from 'vitest';
|
|
5
5
|
import type { IWorkflowService } from '@bevel-software/platform-shared';
|
|
6
6
|
import type { IAccessControl } from '../../access/access-control.interface.js';
|
|
7
|
-
import type { ICreatorAccess } from '../../access/creator
|
|
7
|
+
import type { ICreatorAccess } from '../../access-model/creator.js';
|
|
8
8
|
import type { WorkflowEventBus } from '../../workflow/event-bus.js';
|
|
9
9
|
import type { AuthService } from '../../auth/auth.service.js';
|
|
10
10
|
import type { IAdminAccessService } from '../../admin/admin.interface.js';
|
|
@@ -11,7 +11,7 @@ import type { WorkflowEventBus } from '../../workflow/event-bus.js';
|
|
|
11
11
|
import type { AuthService } from '../../auth/auth.service.js';
|
|
12
12
|
import type { IAdminAccessService } from '../../admin/admin.interface.js';
|
|
13
13
|
import { createWorkspaceRoutes } from '../workspace.routes.js';
|
|
14
|
-
import type { ICreatorAccess } from '../../access/creator
|
|
14
|
+
import type { ICreatorAccess } from '../../access-model/creator.js';
|
|
15
15
|
import type { WorkspaceService } from '../workspace.service.js';
|
|
16
16
|
|
|
17
17
|
const stubCreatorAccess: ICreatorAccess = {
|
|
@@ -6,10 +6,10 @@ import type { IWorkflowService } from '@bevel-software/platform-shared';
|
|
|
6
6
|
import type { IAccessControl } from '../../access/access-control.interface.js';
|
|
7
7
|
import type { WorkflowEventBus } from '../../workflow/event-bus.js';
|
|
8
8
|
import type { AuthService } from '../../auth/auth.service.js';
|
|
9
|
-
import { AccessConfigError } from '../../access/access-errors.js';
|
|
9
|
+
import { AccessConfigError } from '../../access-model/access-errors.js';
|
|
10
10
|
import type { IAdminAccessService } from '../../admin/admin.interface.js';
|
|
11
11
|
import { createWorkspaceRoutes } from '../workspace.routes.js';
|
|
12
|
-
import type { ICreatorAccess } from '../../access/creator
|
|
12
|
+
import type { ICreatorAccess } from '../../access-model/creator.js';
|
|
13
13
|
import { FolderTooLargeError, type WorkspaceService } from '../workspace.service.js';
|
|
14
14
|
|
|
15
15
|
const stubCreatorAccess: ICreatorAccess = {
|
|
@@ -4,7 +4,7 @@ import express from 'express';
|
|
|
4
4
|
import { describe, it, expect, afterEach, vi } from 'vitest';
|
|
5
5
|
import type { IWorkflowService } from '@bevel-software/platform-shared';
|
|
6
6
|
import type { IAccessControl } from '../../access/access-control.interface.js';
|
|
7
|
-
import type { ICreatorAccess } from '../../access/creator
|
|
7
|
+
import type { ICreatorAccess } from '../../access-model/creator.js';
|
|
8
8
|
import type { IAdminAccessService } from '../../admin/admin.interface.js';
|
|
9
9
|
import type { WorkflowEventBus } from '../../workflow/event-bus.js';
|
|
10
10
|
import type { AuthService } from '../../auth/auth.service.js';
|
|
@@ -2,11 +2,8 @@ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
|
2
2
|
import fs from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import os from 'node:os';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
workspaceIdForBranch,
|
|
8
|
-
type ReadTreeFilter,
|
|
9
|
-
} from '../workspace.service.js';
|
|
5
|
+
import { WorkspaceService, type ReadTreeFilter } from '../workspace.service.js';
|
|
6
|
+
import { workspaceIdForBranch } from '../../../shared/workspace-id.js';
|
|
10
7
|
|
|
11
8
|
const KB = 'knowledge-base';
|
|
12
9
|
|
|
@@ -4,7 +4,8 @@ import { promisify } from 'node:util';
|
|
|
4
4
|
import fs from 'node:fs/promises';
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import os from 'node:os';
|
|
7
|
-
import { WorkspaceService
|
|
7
|
+
import { WorkspaceService } from '../workspace.service.js';
|
|
8
|
+
import { workspaceIdForBranch } from '../../../shared/workspace-id.js';
|
|
8
9
|
|
|
9
10
|
const execFileAsync = promisify(execFile);
|
|
10
11
|
|
|
@@ -62,6 +63,17 @@ describe('WorkspaceService — branch-keyed identity', () => {
|
|
|
62
63
|
expect(workspaceIdForBranch('alice/feature')).toBe('alice%2Ffeature');
|
|
63
64
|
});
|
|
64
65
|
|
|
66
|
+
it('a malformed workspace id (bad percent-escape) rejects as a 400 BranchNameError, not a 500', async () => {
|
|
67
|
+
const svc = new WorkspaceService(root, 'https://github.com/Bevel-Software/knowledge-base.git', 'knowledge-base');
|
|
68
|
+
// `%zz` fails decodeURIComponent, falls back to itself, and `%` never
|
|
69
|
+
// passes the branch-name rules — the cold-path bootstrap must surface
|
|
70
|
+
// that as the status-carrying domain error, not a wrapped plain Error.
|
|
71
|
+
await expect(svc.readFile('%zz', 'roles.yaml')).rejects.toMatchObject({
|
|
72
|
+
name: 'BranchNameError',
|
|
73
|
+
status: 400,
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
65
77
|
it('returns workspace info derived from the branch — no .workspace.json on disk', async () => {
|
|
66
78
|
const { workspaceId, workspaceDir } = await seedBranchWorkspace(root, 'target-company-state');
|
|
67
79
|
const svc = new WorkspaceService(root, 'https://github.com/Bevel-Software/knowledge-base.git', 'knowledge-base');
|
|
@@ -16,7 +16,7 @@ import { RoutineWritePolicyService } from '../routine-write-policy.js';
|
|
|
16
16
|
import { WorkflowHooks } from '../../workflow/workflow-hooks.js';
|
|
17
17
|
import { SpillStore } from '../spill-store.js';
|
|
18
18
|
import type { IAccessControl } from '../../access/access-control.interface.js';
|
|
19
|
-
import { assertValidBranchName } from '../../
|
|
19
|
+
import { assertValidBranchName } from '../../kb-fs/branch-name.js';
|
|
20
20
|
|
|
21
21
|
const KB_DIR = 'knowledge-base';
|
|
22
22
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { isBranchModelConfigured } from '@bevel-software/platform-shared';
|
|
4
|
-
import { workspaceIdForBranch } from '
|
|
4
|
+
import { workspaceIdForBranch } from '../../../shared/workspace-id.js';
|
|
5
5
|
import type { KbBranch, OnServerStart, ServerStartContext } from './on-server-start.js';
|
|
6
6
|
import { git, lsRemoteHeads, redactSecret, stampIdentity, withTempDir } from './kb-git.js';
|
|
7
7
|
|
|
@@ -8,7 +8,7 @@ import { KbStartupRunner } from '../../kb-startup-runner.js';
|
|
|
8
8
|
import type { OnServerStart, ServerStartContext, StepResult } from '../../on-server-start.js';
|
|
9
9
|
import { GroupsToPluginsStep } from '../groups-to-plugins.step.js';
|
|
10
10
|
import { RolesYamlStep } from '../roles-yaml.step.js';
|
|
11
|
-
import { renderRolesYaml } from '../../../../access/render-roles-yaml.js';
|
|
11
|
+
import { renderRolesYaml } from '../../../../access-model/render-roles-yaml.js';
|
|
12
12
|
import { TemplateFilesStep } from '../template-files.step.js';
|
|
13
13
|
import { buildSeedTree } from '../seed-tree.js';
|
|
14
14
|
import { defaultKbTemplateDir } from '../../../../../assets.js';
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from '@bevel-software/platform-shared';
|
|
14
14
|
import type { ToolManualDescriptor } from '../../../tool-manuals/tool-manuals.contract.js';
|
|
15
15
|
import { normalizeToolManual } from '../../../tool-manuals/tool-manuals.service.js';
|
|
16
|
-
import { parseOwnAccessEntries } from '../../../access/access-
|
|
16
|
+
import { parseOwnAccessEntries } from '../../../access-model/access-grammar.js';
|
|
17
17
|
import { containsVariableReference } from '../../../../shared/variable-refs.js';
|
|
18
18
|
import { IGNORE_FILENAME } from '../../bevel-ignore.js';
|
|
19
19
|
import type { KbBranch, OnServerStart, ServerStartContext, StepResult } from '../on-server-start.js';
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { renderRolesYaml } from '../../../access/render-roles-yaml.js';
|
|
3
|
+
import { renderRolesYaml } from '../../../access-model/render-roles-yaml.js';
|
|
4
4
|
import type { OnServerStart, ServerStartContext, StepResult } from '../on-server-start.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Write `roles.yaml` on any protected branch missing it, generated from the
|
|
8
8
|
* configured seed admins (`ADMIN_EMAIL`) via the shared validated renderer
|
|
9
|
-
* (../../../access/render-roles-yaml.ts — a malformed email stops the boot
|
|
9
|
+
* (../../../access-model/render-roles-yaml.ts — a malformed email stops the boot
|
|
10
10
|
* with a message naming the fix). Never part of the template: a template copy
|
|
11
11
|
* would seed repos with a stale hard-coded Admin list.
|
|
12
12
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { renderRolesYaml } from '../../../access/render-roles-yaml.js';
|
|
3
|
+
import { renderRolesYaml } from '../../../access-model/render-roles-yaml.js';
|
|
4
4
|
import { TEMPLATE_SOURCE_FALLBACKS, reservedRootDirs, templateSource } from './template-files.step.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -13,15 +13,16 @@ import {
|
|
|
13
13
|
PIPELINES_DIR,
|
|
14
14
|
PLUGINS_DIR,
|
|
15
15
|
} from '@bevel-software/platform-shared';
|
|
16
|
-
import {
|
|
16
|
+
import { FolderTooLargeError, type ReadTreeFilter } from './workspace.service.js';
|
|
17
|
+
import { branchForWorkspaceId } from '../../shared/workspace-id.js';
|
|
17
18
|
import type { WorkspaceService } from './workspace.service.js';
|
|
18
19
|
import type { AuthService } from '../auth/auth.service.js';
|
|
19
20
|
import type { IAccessControl } from '../access/access-control.interface.js';
|
|
20
|
-
import { resolveReadableMap, toKbRelative } from '../access/kb-read-filter.js';
|
|
21
|
-
import type { ICreatorAccess } from '../access/creator
|
|
22
|
-
import { isRolesYamlPath, assertRolesYamlParsable } from '../access/roles-yaml-guard.js';
|
|
21
|
+
import { resolveReadableMap, toKbRelative } from '../access-model/kb-read-filter.js';
|
|
22
|
+
import type { ICreatorAccess } from '../access-model/creator.js';
|
|
23
|
+
import { isRolesYamlPath, assertRolesYamlParsable } from '../access-model/roles-yaml-guard.js';
|
|
23
24
|
import type { WorkflowEventBus } from '../workflow/event-bus.js';
|
|
24
|
-
import { WorkflowDomainError } from '
|
|
25
|
+
import { WorkflowDomainError } from '../../shared/domain-errors.js';
|
|
25
26
|
import '../auth/auth.middleware.js'; // Express Request augmentation
|
|
26
27
|
|
|
27
28
|
const MAX_UPLOAD_BYTES = 50 * 1024 * 1024; // 50 MB
|
|
@@ -6,8 +6,10 @@ import AdmZip from 'adm-zip';
|
|
|
6
6
|
import type { AuthUser, IWorkspaceService, WorkspaceInfo, FileTreeEntry } from '@bevel-software/platform-shared';
|
|
7
7
|
import { assertValidRelativePath, validateFilename, DEFAULT_BRANCH } from '@bevel-software/platform-shared';
|
|
8
8
|
import { BevelIgnoreStack } from './bevel-ignore.js';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
9
|
+
import { workspaceIdForBranch, branchForWorkspaceId } from '../../shared/workspace-id.js';
|
|
10
|
+
import { WorkflowDomainError } from '../../shared/domain-errors.js';
|
|
11
|
+
import { assertValidBranchName } from '../kb-fs/branch-name.js';
|
|
12
|
+
import { cloneTrackingConfigArgs, SAFE_IMPLICIT_FETCH_ARGS } from '../kb-fs/clone-config.js';
|
|
11
13
|
import type { IDiffService } from '../diff/diff.interface.js';
|
|
12
14
|
|
|
13
15
|
/**
|
|
@@ -85,25 +87,12 @@ function redactError(err: unknown): string {
|
|
|
85
87
|
|
|
86
88
|
const FETCH_CACHE_TTL_MS = 30_000;
|
|
87
89
|
|
|
88
|
-
/**
|
|
89
|
-
* Map a branch name to the directory that contains its workspace clone.
|
|
90
|
-
* `encodeURIComponent` handles `/` in branch names (e.g. `alice/foo`) by
|
|
91
|
-
* encoding it to `%2F` — single-segment-safe on every supported filesystem.
|
|
92
|
-
*/
|
|
93
|
-
export function workspaceIdForBranch(branch: string): string {
|
|
94
|
-
return encodeURIComponent(branch);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function branchForWorkspaceId(workspaceId: string): string {
|
|
98
|
-
return decodeURIComponent(workspaceId);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
90
|
/**
|
|
102
91
|
* Per-directory read filter for the file tree. Given a batch of
|
|
103
92
|
* workspace-relative entry paths (e.g. `staging-repo/Product/Knowledge/x.md`),
|
|
104
93
|
* returns a verdict map keyed by those paths (`path → readable`). Injected by
|
|
105
94
|
* the route from the access service so `WorkspaceService` stays access-agnostic
|
|
106
|
-
* (it gets a function, not the access module). See `modules/access/kb-read-filter.ts`.
|
|
95
|
+
* (it gets a function, not the access module). See `modules/access-model/kb-read-filter.ts`.
|
|
107
96
|
*/
|
|
108
97
|
export type ReadTreeFilter = (wsRelPaths: string[]) => Promise<Map<string, boolean>>;
|
|
109
98
|
|
|
@@ -408,7 +397,7 @@ export class WorkspaceService implements IWorkspaceService {
|
|
|
408
397
|
|
|
409
398
|
/**
|
|
410
399
|
* Collapse the clone's tracking config to a single fetch refspec and a single
|
|
411
|
-
* upstream ref for `branch` (see `
|
|
400
|
+
* upstream ref for `branch` (see `kb-fs/clone-config.ts`). A clone that
|
|
412
401
|
* accumulated a second `remote.origin.fetch` refspec or `branch.<b>.merge`
|
|
413
402
|
* value makes git refuse to refresh it — "Cannot rebase onto multiple
|
|
414
403
|
* branches" — which is how a post-merge pull of the target branch fails.
|
|
@@ -724,7 +713,7 @@ export class WorkspaceService implements IWorkspaceService {
|
|
|
724
713
|
|
|
725
714
|
// This driver runs outside the git layer's per-workspace mutex, so it may
|
|
726
715
|
// only run the safe implicit-fetch shape — see `SAFE_IMPLICIT_FETCH_ARGS`
|
|
727
|
-
// in `
|
|
716
|
+
// in `kb-fs/clone-config.ts` for the full rationale.
|
|
728
717
|
const promise = execFileAsync(
|
|
729
718
|
'git',
|
|
730
719
|
['-C', repoDir, ...SAFE_IMPLICIT_FETCH_ARGS],
|
|
@@ -1268,6 +1257,13 @@ export class WorkspaceService implements IWorkspaceService {
|
|
|
1268
1257
|
// Bootstrap reported success but didn't register — defensive fallback.
|
|
1269
1258
|
return workspaceDir;
|
|
1270
1259
|
} catch (err) {
|
|
1260
|
+
// Domain errors pass through intact: they carry the status the routes
|
|
1261
|
+
// map (BranchNameError → 400), which is how a malformed or bogus
|
|
1262
|
+
// workspace id stays a client error instead of the wrap below erasing
|
|
1263
|
+
// the type and surfacing as a 500. A malformed id (bad percent-escape)
|
|
1264
|
+
// decodes to itself, and `%` never passes the branch-name rules, so it
|
|
1265
|
+
// lands here as a BranchNameError like any other invalid name.
|
|
1266
|
+
if (err instanceof WorkflowDomainError) throw err;
|
|
1271
1267
|
const reason = err instanceof Error ? err.message : String(err);
|
|
1272
1268
|
throw new Error(`Invalid workspace ID "${workspaceId}": ${reason}`);
|
|
1273
1269
|
}
|
|
@@ -16,13 +16,13 @@ import {
|
|
|
16
16
|
import type { IRoutineWritePolicy } from './routine-write-policy.js';
|
|
17
17
|
import type { ToolHandlerFactory } from '../tool-helpers/tool-handler.js';
|
|
18
18
|
import { requireInternalSource, requireExternalSource } from '../tool-auth/tool-auth.middleware.js';
|
|
19
|
-
import { workspaceIdForBranch } from '
|
|
19
|
+
import { workspaceIdForBranch } from '../../shared/workspace-id.js';
|
|
20
20
|
// Leaf-level shared primitive (same exception `workspace.service.ts` already
|
|
21
21
|
// relies on) — not a workflow service, so this stays inside the module boundary.
|
|
22
|
-
import { assertValidBranchName } from '../
|
|
22
|
+
import { assertValidBranchName } from '../kb-fs/branch-name.js';
|
|
23
23
|
import type { ISessionSink } from './session-sink.js';
|
|
24
24
|
import type { IAccessControl } from '../access/access-control.interface.js';
|
|
25
|
-
import { toKbRelative, resolveReadableMap } from '../access/kb-read-filter.js';
|
|
25
|
+
import { toKbRelative, resolveReadableMap } from '../access-model/kb-read-filter.js';
|
|
26
26
|
import type { SpillStore } from './spill-store.js';
|
|
27
27
|
|
|
28
28
|
/** A directory entry as returned by `LocalFilesystem.readdir`. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
2
|
import { isJoinBranchFor, joinBranchFor, kebabPluginName } from '@bevel-software/platform-shared';
|
|
3
|
-
import { assertValidBranchName } from '../../modules/
|
|
3
|
+
import { assertValidBranchName } from '../../modules/kb-fs/branch-name.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* The join-branch convention. Two properties matter, and they pull in
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { branchForWorkspaceId, workspaceIdForBranch } from '../workspace-id.js';
|
|
3
|
+
|
|
4
|
+
describe('workspace-id mapping', () => {
|
|
5
|
+
it('round-trips branch names, slashes included', () => {
|
|
6
|
+
for (const branch of ['current-company-state', 'alice/draft', 'a b', '100%']) {
|
|
7
|
+
expect(branchForWorkspaceId(workspaceIdForBranch(branch))).toBe(branch);
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('never throws on a malformed id — it names a branch that does not exist', () => {
|
|
12
|
+
for (const malformed of ['%', '100%', '%2', '%zz', 'a%2Gb']) {
|
|
13
|
+
expect(() => branchForWorkspaceId(malformed)).not.toThrow();
|
|
14
|
+
expect(branchForWorkspaceId(malformed)).toBe(malformed);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Workflow domain errors. This is the single source of truth — every error
|
|
3
|
-
* raised by the workflow
|
|
3
|
+
* raised by the workflow domain (branches, changes, change requests, access
|
|
4
4
|
* control, locks) lives here. Route handlers shape responses via the
|
|
5
5
|
* `.status` + `.payload` contract on the base class.
|
|
6
6
|
*
|
|
7
|
+
* Lives in `src/shared` (not `modules/workflow`) because the classes are
|
|
8
|
+
* consumed across module boundaries — access, diff, plugins and workspace all
|
|
9
|
+
* catch or raise them — and `src/shared` is the layer with no module imports.
|
|
10
|
+
* Only a type from `@bevel-software/platform-shared` comes in; nothing else.
|
|
11
|
+
*
|
|
7
12
|
* Naming: classes use workflow vocabulary. `WorkflowDomainError` is the
|
|
8
13
|
* abstract base; specific subclasses describe the workflow concept that
|
|
9
14
|
* went wrong (`BranchNameError`, `ProtectedBranchError`, etc.). Where a
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The branch ↔ workspace-directory naming convention. Workspaces are
|
|
3
|
+
* per-branch (one on-disk clone per branch name), and the workspace id IS the
|
|
4
|
+
* URL-encoded branch name — deterministic both ways, so every caller
|
|
5
|
+
* (backend, frontend, agent) can compute one from the other without a DB
|
|
6
|
+
* round-trip. Consumed by nearly every module that touches a workspace, so it
|
|
7
|
+
* lives in `backend/src/shared` rather than inside the workspace module.
|
|
8
|
+
*
|
|
9
|
+
* Pure string handling — no IO, no DB.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Map a branch name to the directory that contains its workspace clone.
|
|
14
|
+
* `encodeURIComponent` handles `/` in branch names (e.g. `alice/foo`) by
|
|
15
|
+
* encoding it to `%2F` — single-segment-safe on every supported filesystem.
|
|
16
|
+
*/
|
|
17
|
+
export function workspaceIdForBranch(branch: string): string {
|
|
18
|
+
return encodeURIComponent(branch);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Map a workspace id back to its branch name. Workspace ids come in from
|
|
23
|
+
* request paths and from directory names on disk, so malformed input (a lone
|
|
24
|
+
* `%`, `%` without two hex digits) must not throw — `decodeURIComponent`
|
|
25
|
+
* would raise a `URIError` that surfaces as an unhandled 500 in every route
|
|
26
|
+
* that resolves an id. A malformed id can never equal a valid encoding, so
|
|
27
|
+
* returning it unchanged is safe: it simply names a branch that does not
|
|
28
|
+
* exist, and the caller's own lookup fails with its normal not-found path.
|
|
29
|
+
*/
|
|
30
|
+
export function branchForWorkspaceId(workspaceId: string): string {
|
|
31
|
+
try {
|
|
32
|
+
return decodeURIComponent(workspaceId);
|
|
33
|
+
} catch {
|
|
34
|
+
return workspaceId;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|