@bevel-software/platform-core-backend 0.4.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD-PARTY-NOTICES.md +6118 -0
- package/dist/core/core-ports.d.ts +15 -0
- package/dist/core/core-ports.d.ts.map +1 -1
- package/dist/core/core-ports.js.map +1 -1
- package/dist/core/create-core-server.d.ts.map +1 -1
- package/dist/core/create-core-server.js +40 -6
- package/dist/core/create-core-server.js.map +1 -1
- package/dist/core/create-core-services.d.ts +17 -1
- package/dist/core/create-core-services.d.ts.map +1 -1
- package/dist/core/create-core-services.js +153 -29
- package/dist/core/create-core-services.js.map +1 -1
- package/dist/core-config.d.ts +70 -21
- package/dist/core-config.d.ts.map +1 -1
- package/dist/core-config.js +134 -58
- package/dist/core-config.js.map +1 -1
- package/dist/modules/access/access-control.interface.d.ts +6 -0
- package/dist/modules/access/access-control.interface.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.d.ts +74 -5
- package/dist/modules/access/access-control.service.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.js +116 -15
- package/dist/modules/access/access-control.service.js.map +1 -1
- package/dist/modules/access/access-declarations.d.ts +93 -0
- package/dist/modules/access/access-declarations.d.ts.map +1 -0
- package/dist/modules/access/access-declarations.js +168 -0
- package/dist/modules/access/access-declarations.js.map +1 -0
- package/dist/modules/access/access-mutation.service.js +4 -4
- package/dist/modules/access/access-mutation.service.js.map +1 -1
- package/dist/modules/access/access-splice.d.ts +16 -1
- package/dist/modules/access/access-splice.d.ts.map +1 -1
- package/dist/modules/access/access-splice.js +40 -21
- package/dist/modules/access/access-splice.js.map +1 -1
- package/dist/modules/access/access.routes.d.ts.map +1 -1
- package/dist/modules/access/access.routes.js +51 -0
- package/dist/modules/access/access.routes.js.map +1 -1
- package/dist/modules/access/creator-access.d.ts +8 -0
- package/dist/modules/access/creator-access.d.ts.map +1 -1
- package/dist/modules/access/creator-access.js +21 -2
- package/dist/modules/access/creator-access.js.map +1 -1
- package/dist/modules/admin/admin-access.service.d.ts +1 -1
- package/dist/modules/admin/admin-access.service.d.ts.map +1 -1
- package/dist/modules/admin/admin-access.service.js +3 -2
- package/dist/modules/admin/admin-access.service.js.map +1 -1
- package/dist/modules/auth/auth.routes.d.ts.map +1 -1
- package/dist/modules/auth/auth.routes.js +50 -1
- package/dist/modules/auth/auth.routes.js.map +1 -1
- package/dist/modules/auth/auth.service.d.ts +39 -10
- package/dist/modules/auth/auth.service.d.ts.map +1 -1
- package/dist/modules/auth/auth.service.js +38 -16
- package/dist/modules/auth/auth.service.js.map +1 -1
- package/dist/modules/database/core-schema.d.ts +124 -0
- package/dist/modules/database/core-schema.d.ts.map +1 -1
- package/dist/modules/database/core-schema.js +45 -0
- package/dist/modules/database/core-schema.js.map +1 -1
- package/dist/modules/groups/group-provision.service.d.ts +130 -0
- package/dist/modules/groups/group-provision.service.d.ts.map +1 -0
- package/dist/modules/groups/group-provision.service.js +288 -0
- package/dist/modules/groups/group-provision.service.js.map +1 -0
- package/dist/modules/groups/groups.contract.d.ts +106 -0
- package/dist/modules/groups/groups.contract.d.ts.map +1 -0
- package/dist/modules/groups/groups.contract.js +36 -0
- package/dist/modules/groups/groups.contract.js.map +1 -0
- package/dist/modules/groups/groups.routes.d.ts +42 -0
- package/dist/modules/groups/groups.routes.d.ts.map +1 -0
- package/dist/modules/groups/groups.routes.js +379 -0
- package/dist/modules/groups/groups.routes.js.map +1 -0
- package/dist/modules/groups/groups.service.d.ts +60 -0
- package/dist/modules/groups/groups.service.d.ts.map +1 -0
- package/dist/modules/groups/groups.service.js +172 -0
- package/dist/modules/groups/groups.service.js.map +1 -0
- package/dist/modules/groups/index.d.ts +7 -0
- package/dist/modules/groups/index.d.ts.map +1 -0
- package/dist/modules/groups/index.js +6 -0
- package/dist/modules/groups/index.js.map +1 -0
- package/dist/modules/groups/join-proposals.d.ts +53 -0
- package/dist/modules/groups/join-proposals.d.ts.map +1 -0
- package/dist/modules/groups/join-proposals.js +67 -0
- package/dist/modules/groups/join-proposals.js.map +1 -0
- package/dist/modules/groups/join-requests.service.d.ts +81 -0
- package/dist/modules/groups/join-requests.service.d.ts.map +1 -0
- package/dist/modules/groups/join-requests.service.js +135 -0
- package/dist/modules/groups/join-requests.service.js.map +1 -0
- package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +20 -0
- package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -1
- package/dist/modules/secrets-vault/secrets-vault.routes.js +59 -11
- package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -1
- package/dist/modules/settings/deployment-settings.service.d.ts +129 -0
- package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -0
- package/dist/modules/settings/deployment-settings.service.js +368 -0
- package/dist/modules/settings/deployment-settings.service.js.map +1 -0
- package/dist/modules/settings/setup.routes.d.ts +49 -0
- package/dist/modules/settings/setup.routes.d.ts.map +1 -0
- package/dist/modules/settings/setup.routes.js +292 -0
- package/dist/modules/settings/setup.routes.js.map +1 -0
- package/dist/modules/skills/index.d.ts +2 -1
- package/dist/modules/skills/index.d.ts.map +1 -1
- package/dist/modules/skills/index.js +1 -0
- package/dist/modules/skills/index.js.map +1 -1
- package/dist/modules/skills/pending-skills.service.d.ts +40 -0
- package/dist/modules/skills/pending-skills.service.d.ts.map +1 -0
- package/dist/modules/skills/pending-skills.service.js +147 -0
- package/dist/modules/skills/pending-skills.service.js.map +1 -0
- package/dist/modules/skills/skills.contract.d.ts +32 -3
- package/dist/modules/skills/skills.contract.d.ts.map +1 -1
- package/dist/modules/skills/skills.contract.js +1 -1
- package/dist/modules/skills/skills.routes.d.ts +3 -2
- package/dist/modules/skills/skills.routes.d.ts.map +1 -1
- package/dist/modules/skills/skills.routes.js +18 -1
- package/dist/modules/skills/skills.routes.js.map +1 -1
- package/dist/modules/skills/skills.service.d.ts +22 -0
- package/dist/modules/skills/skills.service.d.ts.map +1 -1
- package/dist/modules/skills/skills.service.js +24 -12
- package/dist/modules/skills/skills.service.js.map +1 -1
- package/dist/modules/tool-manuals/index.d.ts +1 -1
- package/dist/modules/tool-manuals/index.d.ts.map +1 -1
- package/dist/modules/tool-manuals/index.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.contract.d.ts +47 -2
- package/dist/modules/tool-manuals/tool-manuals.contract.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.contract.js +1 -1
- package/dist/modules/tool-manuals/tool-manuals.routes.d.ts +4 -0
- package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.routes.js +23 -0
- package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.service.d.ts +3 -1
- package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.service.js +84 -17
- package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.tools.js +6 -2
- package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.js +4 -2
- package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
- package/dist/modules/workflow/event-bus.d.ts +11 -0
- package/dist/modules/workflow/event-bus.d.ts.map +1 -1
- package/dist/modules/workflow/event-bus.js +22 -0
- package/dist/modules/workflow/event-bus.js.map +1 -1
- package/dist/modules/workflow/file-lock.service.d.ts +9 -0
- package/dist/modules/workflow/file-lock.service.d.ts.map +1 -1
- package/dist/modules/workflow/file-lock.service.js +16 -0
- package/dist/modules/workflow/file-lock.service.js.map +1 -1
- package/dist/modules/workflow/git/branch-name.d.ts +1 -1
- package/dist/modules/workflow/git/branch-name.d.ts.map +1 -1
- package/dist/modules/workflow/git/branch-name.js +1 -1
- package/dist/modules/workflow/git/branch-name.js.map +1 -1
- package/dist/modules/workflow/git/git.service.d.ts +31 -2
- package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
- package/dist/modules/workflow/git/git.service.js +144 -52
- package/dist/modules/workflow/git/git.service.js.map +1 -1
- package/dist/modules/workflow/git/pull-request.service.d.ts +12 -6
- package/dist/modules/workflow/git/pull-request.service.d.ts.map +1 -1
- package/dist/modules/workflow/git/pull-request.service.js +19 -9
- package/dist/modules/workflow/git/pull-request.service.js.map +1 -1
- package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/review-workflow/review-workflow.service.js +12 -3
- package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -1
- package/dist/modules/workflow/workflow.routes.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.routes.js +95 -14
- package/dist/modules/workflow/workflow.routes.js.map +1 -1
- package/dist/modules/workflow/workflow.service.d.ts +92 -3
- package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.service.js +381 -108
- package/dist/modules/workflow/workflow.service.js.map +1 -1
- package/dist/modules/workspace/bevel-ignore.d.ts +5 -0
- package/dist/modules/workspace/bevel-ignore.d.ts.map +1 -1
- package/dist/modules/workspace/bevel-ignore.js +5 -1
- package/dist/modules/workspace/bevel-ignore.js.map +1 -1
- package/dist/modules/workspace/kb-seed.interface.d.ts +1 -1
- package/dist/modules/workspace/kb-seed.service.d.ts +60 -5
- package/dist/modules/workspace/kb-seed.service.d.ts.map +1 -1
- package/dist/modules/workspace/kb-seed.service.js +228 -51
- package/dist/modules/workspace/kb-seed.service.js.map +1 -1
- package/dist/modules/workspace/workspace.routes.d.ts +2 -1
- package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.routes.js +51 -18
- package/dist/modules/workspace/workspace.routes.js.map +1 -1
- package/dist/modules/workspace/workspace.service.d.ts +16 -4
- package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.service.js +36 -9
- package/dist/modules/workspace/workspace.service.js.map +1 -1
- package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.tools.js +8 -3
- package/dist/modules/workspace/workspace.tools.js.map +1 -1
- package/dist/shared/kb-layout.test.js +2 -2
- package/dist/test-setup.d.ts +2 -0
- package/dist/test-setup.d.ts.map +1 -0
- package/dist/test-setup.js +18 -0
- package/dist/test-setup.js.map +1 -0
- package/kb-template/.bevelignore +6 -2
- package/kb-template/AGENTS.md +272 -0
- package/kb-template/KnowledgeBase/How to get started.md +65 -0
- package/kb-template/access.md +36 -36
- package/migrations/0002_user_onboarding_done.sql +1 -0
- package/migrations/0003_deployment_settings.sql +9 -0
- package/migrations/meta/0001_snapshot.json +1486 -0
- package/migrations/meta/0002_snapshot.json +1493 -0
- package/migrations/meta/0003_snapshot.json +1552 -0
- package/migrations/meta/_journal.json +15 -1
- package/package.json +5 -4
- package/src/__tests__/branch-model.test.ts +79 -0
- package/src/__tests__/core-config.admin.test.ts +114 -0
- package/src/__tests__/database-url.test.ts +70 -0
- package/src/core/core-ports.ts +15 -0
- package/src/core/create-core-server.ts +55 -6
- package/src/core/create-core-services.ts +201 -36
- package/src/core-config.ts +139 -59
- package/src/modules/access/__tests__/access-declarations.test.ts +195 -0
- package/src/modules/access/__tests__/access-md-format.test.ts +191 -0
- package/src/modules/access/__tests__/access-splice.test.ts +21 -0
- package/src/modules/access/__tests__/access.routes.overrides.test.ts +214 -0
- package/src/modules/access/access-control.interface.ts +11 -0
- package/src/modules/access/access-control.service.ts +113 -15
- package/src/modules/access/access-declarations.ts +251 -0
- package/src/modules/access/access-mutation.service.ts +4 -4
- package/src/modules/access/access-splice.ts +64 -21
- package/src/modules/access/access.routes.ts +61 -0
- package/src/modules/access/creator-access.ts +22 -2
- package/src/modules/admin/admin-access.service.ts +4 -3
- package/src/modules/auth/__tests__/auth.service.test.ts +57 -0
- package/src/modules/auth/__tests__/onboarding-done.route.test.ts +147 -0
- package/src/modules/auth/auth.routes.ts +50 -1
- package/src/modules/auth/auth.service.ts +55 -17
- package/src/modules/database/core-schema.ts +46 -0
- package/src/modules/groups/__tests__/group-index.service.test.ts +225 -0
- package/src/modules/groups/__tests__/group-provision.service.test.ts +247 -0
- package/src/modules/groups/__tests__/groups.routes.test.ts +493 -0
- package/src/modules/groups/__tests__/join-proposals.test.ts +101 -0
- package/src/modules/groups/__tests__/join-requests.service.test.ts +175 -0
- package/src/modules/groups/group-provision.service.ts +328 -0
- package/src/modules/groups/groups.contract.ts +107 -0
- package/src/modules/groups/groups.routes.ts +433 -0
- package/src/modules/groups/groups.service.ts +193 -0
- package/src/modules/groups/index.ts +17 -0
- package/src/modules/groups/join-proposals.ts +114 -0
- package/src/modules/groups/join-requests.service.ts +185 -0
- package/src/modules/secrets-vault/__tests__/oauth-return-to.route.test.ts +283 -0
- package/src/modules/secrets-vault/secrets-vault.routes.ts +68 -12
- package/src/modules/settings/__tests__/deployment-settings.service.test.ts +256 -0
- package/src/modules/settings/__tests__/setup.routes.test.ts +201 -0
- package/src/modules/settings/deployment-settings.service.ts +419 -0
- package/src/modules/settings/setup.routes.ts +317 -0
- package/src/modules/skills/__tests__/pending-skills.service.test.ts +240 -0
- package/src/modules/skills/__tests__/skills.service.test.ts +13 -13
- package/src/modules/skills/index.ts +3 -0
- package/src/modules/skills/pending-skills.service.ts +168 -0
- package/src/modules/skills/skills.contract.ts +34 -3
- package/src/modules/skills/skills.routes.ts +23 -2
- package/src/modules/skills/skills.service.ts +24 -16
- package/src/modules/tool-manuals/__tests__/tool-manuals.detail.route.test.ts +262 -0
- package/src/modules/tool-manuals/__tests__/tool-manuals.mcp-oauth.test.ts +2 -2
- package/src/modules/tool-manuals/__tests__/tool-manuals.service.test.ts +61 -23
- package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +156 -156
- package/src/modules/tool-manuals/index.ts +2 -0
- package/src/modules/tool-manuals/tool-manuals.contract.ts +50 -2
- package/src/modules/tool-manuals/tool-manuals.routes.ts +21 -0
- package/src/modules/tool-manuals/tool-manuals.service.ts +86 -17
- package/src/modules/tool-manuals/tool-manuals.tools.ts +206 -202
- package/src/modules/workflow/__tests__/event-bus.test.ts +35 -0
- package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +251 -5
- package/src/modules/workflow/agent-tools/workflow.tools.ts +4 -2
- package/src/modules/workflow/event-bus.ts +25 -0
- package/src/modules/workflow/file-lock.service.ts +17 -0
- package/src/modules/workflow/git/__tests__/git.service.accessGating.test.ts +9 -49
- package/src/modules/workflow/git/__tests__/git.service.changedFilesForPr.test.ts +101 -0
- package/src/modules/workflow/git/__tests__/git.service.commitFile.test.ts +219 -211
- package/src/modules/workflow/git/__tests__/git.service.fileContentsAtCommit.test.ts +132 -0
- package/src/modules/workflow/git/__tests__/git.service.logForFile.test.ts +4 -2
- package/src/modules/workflow/git/__tests__/git.service.postMergePull.test.ts +275 -272
- package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +5 -0
- package/src/modules/workflow/git/__tests__/pull-request.service.viewer-can-cancel.test.ts +44 -0
- package/src/modules/workflow/git/branch-name.ts +5 -1
- package/src/modules/workflow/git/git.service.ts +159 -62
- package/src/modules/workflow/git/pull-request.service.ts +22 -11
- package/src/modules/workflow/review-workflow/__tests__/cancel-pr.test.ts +4 -1
- package/src/modules/workflow/review-workflow/review-workflow.service.ts +12 -3
- package/src/modules/workflow/workflow.routes.ts +91 -13
- package/src/modules/workflow/workflow.service.ts +353 -13
- package/src/modules/workspace/__tests__/kb-seed.service.test.ts +255 -24
- package/src/modules/workspace/__tests__/workspace.routes.create-grant.test.ts +236 -233
- package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +179 -176
- package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +320 -303
- package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +337 -276
- package/src/modules/workspace/__tests__/workspace.tools.test.ts +14 -6
- package/src/modules/workspace/bevel-ignore.ts +66 -62
- package/src/modules/workspace/kb-seed.interface.ts +1 -1
- package/src/modules/workspace/kb-seed.service.ts +247 -53
- package/src/modules/workspace/workspace.routes.ts +54 -18
- package/src/modules/workspace/workspace.service.ts +45 -7
- package/src/modules/workspace/workspace.tools.ts +922 -917
- package/src/shared/__tests__/frontmatter-id.test.ts +53 -0
- package/src/shared/__tests__/join-request.test.ts +96 -0
- package/src/shared/__tests__/kb-layout.group.test.ts +45 -0
- package/src/shared/kb-layout.test.ts +2 -2
- package/src/test-setup.ts +18 -0
- package/kb-template/Agents/README.md +0 -38
- package/kb-template/CLAUDE.md +0 -419
- package/kb-template/Data/.gitkeep +0 -0
- package/kb-template/Data/README.md +0 -39
- package/kb-template/KnowledgeBase/README.md +0 -37
- package/kb-template/Pipelines/.gitkeep +0 -0
- package/kb-template/Pipelines/README.md +0 -38
- package/kb-template/Skills/.gitkeep +0 -0
- package/kb-template/Skills/README.md +0 -32
- package/kb-template/Tools/.gitkeep +0 -0
- package/kb-template/Tools/README.md +0 -42
- /package/kb-template/{Agents → Groups}/.gitkeep +0 -0
|
@@ -15,6 +15,20 @@
|
|
|
15
15
|
"when": 1785534603355,
|
|
16
16
|
"tag": "0001_user_password_hash",
|
|
17
17
|
"breakpoints": true
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"idx": 2,
|
|
21
|
+
"version": "7",
|
|
22
|
+
"when": 1785934874039,
|
|
23
|
+
"tag": "0002_user_onboarding_done",
|
|
24
|
+
"breakpoints": true
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"idx": 3,
|
|
28
|
+
"version": "7",
|
|
29
|
+
"when": 1785943322636,
|
|
30
|
+
"tag": "0003_deployment_settings",
|
|
31
|
+
"breakpoints": true
|
|
18
32
|
}
|
|
19
33
|
]
|
|
20
|
-
}
|
|
34
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bevel-software/platform-core-backend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Open-source core backend of the Bevel platform: git-backed knowledge workspace, workflow (branches/change requests/locks/SSE), skills, tools, secrets vault, access control and the remote MCP surface.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
"dist",
|
|
23
23
|
"src",
|
|
24
24
|
"migrations",
|
|
25
|
-
"kb-template"
|
|
25
|
+
"kb-template",
|
|
26
|
+
"THIRD-PARTY-NOTICES.md"
|
|
26
27
|
],
|
|
27
28
|
"engines": {
|
|
28
29
|
"node": ">=22 <23"
|
|
@@ -45,7 +46,7 @@
|
|
|
45
46
|
"pg": "^8.20.0",
|
|
46
47
|
"yaml": "^2.9.0",
|
|
47
48
|
"zod": "^3.24.0",
|
|
48
|
-
"@bevel-software/platform-shared": "0.
|
|
49
|
+
"@bevel-software/platform-shared": "0.5.1"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"@types/adm-zip": "^0.5.8",
|
|
@@ -64,7 +65,7 @@
|
|
|
64
65
|
"license": "Apache-2.0",
|
|
65
66
|
"repository": {
|
|
66
67
|
"type": "git",
|
|
67
|
-
"url": "git+https://github.com/Bevel-Software/
|
|
68
|
+
"url": "git+https://github.com/Bevel-Software/Hexis.git",
|
|
68
69
|
"directory": "packages/core-backend"
|
|
69
70
|
},
|
|
70
71
|
"publishConfig": {
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach, beforeEach } from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
configureBranchModel,
|
|
4
|
+
isBranchModelConfigured,
|
|
5
|
+
isProtectedBranch,
|
|
6
|
+
protectedBranchDisplayName,
|
|
7
|
+
DEFAULT_BRANCH,
|
|
8
|
+
PROTECTED_BRANCHES,
|
|
9
|
+
} from '@bevel-software/platform-shared';
|
|
10
|
+
|
|
11
|
+
const PAIR = {
|
|
12
|
+
defaultBranch: 'target-company-state',
|
|
13
|
+
protectedBranches: ['current-company-state', 'target-company-state'],
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
beforeEach(() => configureBranchModel(PAIR));
|
|
17
|
+
// The model is module-global by design (that is what lets every call site keep
|
|
18
|
+
// importing a binding). Restore it so a suite that runs after this one in the
|
|
19
|
+
// same worker is not left with whatever the last case configured.
|
|
20
|
+
afterEach(() => configureBranchModel(PAIR));
|
|
21
|
+
|
|
22
|
+
describe('configureBranchModel', () => {
|
|
23
|
+
it('applies the model to every export', () => {
|
|
24
|
+
expect(isBranchModelConfigured()).toBe(true);
|
|
25
|
+
expect(DEFAULT_BRANCH).toBe('target-company-state');
|
|
26
|
+
expect([...PROTECTED_BRANCHES].sort()).toEqual([
|
|
27
|
+
'current-company-state',
|
|
28
|
+
'target-company-state',
|
|
29
|
+
]);
|
|
30
|
+
expect(isProtectedBranch('current-company-state')).toBe(true);
|
|
31
|
+
expect(isProtectedBranch('someone/draft')).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('accepts the comma/space list the environment supplies', () => {
|
|
35
|
+
configureBranchModel({ defaultBranch: 'main', protectedBranches: 'main, release' });
|
|
36
|
+
expect([...PROTECTED_BRANCHES].sort()).toEqual(['main', 'release']);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('derives display names from the slug', () => {
|
|
40
|
+
expect(protectedBranchDisplayName('target-company-state')).toBe('Target company state');
|
|
41
|
+
// Unknown names return null so the caller decides between the raw slug and
|
|
42
|
+
// hiding the affordance — it must not invent a name for a feature branch.
|
|
43
|
+
expect(protectedBranchDisplayName('someone/draft')).toBeNull();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The default branch is where users land and the default propose target. If
|
|
48
|
+
* it is not itself protected, `isProtectedBranch(DEFAULT_BRANCH)` is false and
|
|
49
|
+
* every protected-branch guard silently stops applying to the one branch that
|
|
50
|
+
* needs them most. Refused rather than shipped.
|
|
51
|
+
*/
|
|
52
|
+
it('refuses a default branch that is not protected', () => {
|
|
53
|
+
expect(() =>
|
|
54
|
+
configureBranchModel({ defaultBranch: 'main', protectedBranches: ['release'] }),
|
|
55
|
+
).toThrow(/must be one of the protected branches/);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('refuses an empty model rather than defaulting to something plausible', () => {
|
|
59
|
+
expect(() => configureBranchModel({ defaultBranch: '', protectedBranches: ['main'] })).toThrow(
|
|
60
|
+
/default branch is required/,
|
|
61
|
+
);
|
|
62
|
+
expect(() => configureBranchModel({ defaultBranch: 'main', protectedBranches: [] })).toThrow(
|
|
63
|
+
/At least one protected branch/,
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* A rejected model must not half-apply. The previous one stays in force, so a
|
|
69
|
+
* bad `/api/config` payload cannot leave the app pointing at a branch that is
|
|
70
|
+
* neither the old value nor the new one.
|
|
71
|
+
*/
|
|
72
|
+
it('leaves the previous model intact when it refuses a new one', () => {
|
|
73
|
+
expect(() =>
|
|
74
|
+
configureBranchModel({ defaultBranch: 'nope', protectedBranches: ['other'] }),
|
|
75
|
+
).toThrow();
|
|
76
|
+
expect(DEFAULT_BRANCH).toBe('target-company-state');
|
|
77
|
+
expect(isProtectedBranch('target-company-state')).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { CoreConfig } from '../core-config.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The boot contract around the deployment owner.
|
|
6
|
+
*
|
|
7
|
+
* `ADMIN_EMAIL` is required outright — it is the always-admin, the initial
|
|
8
|
+
* Admin written into a freshly seeded `roles.yaml`, and half the bootstrap
|
|
9
|
+
* credential. A deployment without one cannot be administered at all, so
|
|
10
|
+
* refusing to boot beats booting into something nobody can get into.
|
|
11
|
+
*
|
|
12
|
+
* `ADMIN_PASSWORD` is required only while password login is ENABLED. An
|
|
13
|
+
* SSO-only deployment would otherwise have to hold a shared password the
|
|
14
|
+
* server is configured to reject — an unused credential someone still has to
|
|
15
|
+
* store and rotate.
|
|
16
|
+
*/
|
|
17
|
+
const REQUIRED = {
|
|
18
|
+
KB_REPO_URL: 'https://example.com/org/kb.git',
|
|
19
|
+
ADMIN_EMAIL: 'root@example.com',
|
|
20
|
+
ADMIN_PASSWORD: 'sup3r-secret',
|
|
21
|
+
// The other two boot requirements, so a case about the admin pair fails for
|
|
22
|
+
// the reason it is testing rather than for a missing neighbour.
|
|
23
|
+
JWT_SECRET: 'test-jwt-secret',
|
|
24
|
+
SECRETS_ENC_KEY: 'kToAi8FXWDpDn3A6yQ/60O39bv05N7XzVOIu/0CJrFc=',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
let saved: NodeJS.ProcessEnv;
|
|
28
|
+
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
saved = { ...process.env };
|
|
31
|
+
// A clean slate for the keys under test; anything else the constructor reads
|
|
32
|
+
// has a default or is supplied by REQUIRED.
|
|
33
|
+
for (const key of [
|
|
34
|
+
'ADMIN_EMAIL',
|
|
35
|
+
'ADMIN_PASSWORD',
|
|
36
|
+
'LOGIN_PASSWORD',
|
|
37
|
+
'SEED_ADMIN_EMAILS',
|
|
38
|
+
'JWT_SECRET',
|
|
39
|
+
'SECRETS_ENC_KEY',
|
|
40
|
+
'CONNECTOR_CONFIG_ENC_KEY',
|
|
41
|
+
'SHAREPOINT_TOKEN_ENC_KEY',
|
|
42
|
+
]) {
|
|
43
|
+
delete process.env[key];
|
|
44
|
+
}
|
|
45
|
+
Object.assign(process.env, REQUIRED);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
afterEach(() => {
|
|
49
|
+
process.env = saved;
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('CoreConfig — the deployment owner', () => {
|
|
53
|
+
it('refuses to boot without ADMIN_EMAIL', () => {
|
|
54
|
+
delete process.env.ADMIN_EMAIL;
|
|
55
|
+
expect(() => new CoreConfig()).toThrow(/ADMIN_EMAIL is required/);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('refuses a malformed ADMIN_EMAIL rather than seeding a broken roles.yaml', () => {
|
|
59
|
+
process.env.ADMIN_EMAIL = 'not-an-email';
|
|
60
|
+
expect(() => new CoreConfig()).toThrow(/not a valid email/);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('requires ADMIN_PASSWORD while password login is enabled', () => {
|
|
64
|
+
delete process.env.ADMIN_PASSWORD;
|
|
65
|
+
expect(() => new CoreConfig()).toThrow(/ADMIN_PASSWORD is required/);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('does NOT require ADMIN_PASSWORD on an SSO-only deployment', () => {
|
|
69
|
+
delete process.env.ADMIN_PASSWORD;
|
|
70
|
+
process.env.LOGIN_PASSWORD = 'false';
|
|
71
|
+
const config = new CoreConfig();
|
|
72
|
+
expect(config.loginPasswordEnabled).toBe(false);
|
|
73
|
+
expect(config.adminPassword).toBe('');
|
|
74
|
+
// The identity is still there — "there is always an identifiable admin"
|
|
75
|
+
// holds whether or not a password exists.
|
|
76
|
+
expect(config.adminEmail).toBe('root@example.com');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('normalizes the owner address, since it is matched against sign-in emails', () => {
|
|
80
|
+
process.env.ADMIN_EMAIL = ' Root@Example.COM ';
|
|
81
|
+
expect(new CoreConfig().adminEmail).toBe('root@example.com');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Both sign what the deployment hands out — sessions, and the git credential
|
|
86
|
+
* the setup screen stores. Unset, the failure used to surface at the first
|
|
87
|
+
* login or the last step of first-run setup; a boot error naming the variable
|
|
88
|
+
* is the same information, much earlier.
|
|
89
|
+
*/
|
|
90
|
+
it('refuses to boot without JWT_SECRET', () => {
|
|
91
|
+
delete process.env.JWT_SECRET;
|
|
92
|
+
expect(() => new CoreConfig()).toThrow(/JWT_SECRET is required/);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('refuses to boot without SECRETS_ENC_KEY', () => {
|
|
96
|
+
delete process.env.SECRETS_ENC_KEY;
|
|
97
|
+
expect(() => new CoreConfig()).toThrow(/SECRETS_ENC_KEY is required/);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('still accepts the legacy encryption-key names', () => {
|
|
101
|
+
delete process.env.SECRETS_ENC_KEY;
|
|
102
|
+
process.env.CONNECTOR_CONFIG_ENC_KEY = 'kToAi8FXWDpDn3A6yQ/60O39bv05N7XzVOIu/0CJrFc=';
|
|
103
|
+
// Not just "does not throw": the legacy name has to actually supply the
|
|
104
|
+
// key, or an existing deployment boots and then cannot decrypt anything.
|
|
105
|
+
expect(new CoreConfig().secretsEncKey).toBe('kToAi8FXWDpDn3A6yQ/60O39bv05N7XzVOIu/0CJrFc=');
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('ignores a leftover SEED_ADMIN_EMAILS instead of failing on it', () => {
|
|
109
|
+
// The variable is gone, not renamed. An operator upgrading with a stale
|
|
110
|
+
// value in their env should boot, not hit an unknown-key error.
|
|
111
|
+
process.env.SEED_ADMIN_EMAILS = 'someone-else@example.com';
|
|
112
|
+
expect(() => new CoreConfig()).not.toThrow();
|
|
113
|
+
});
|
|
114
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { resolveDatabaseUrl } from '../core-config.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The connection string is composed HERE rather than in docker-compose, where
|
|
6
|
+
* it needed a nested interpolated default that deployment UIs mis-parse. Two
|
|
7
|
+
* things follow that are worth pinning.
|
|
8
|
+
*/
|
|
9
|
+
describe('resolveDatabaseUrl', () => {
|
|
10
|
+
it('uses an explicit DATABASE_URL over the parts', () => {
|
|
11
|
+
expect(
|
|
12
|
+
resolveDatabaseUrl({
|
|
13
|
+
DATABASE_URL: 'postgresql://me:pw@managed.example.com:5432/prod',
|
|
14
|
+
POSTGRES_USER: 'ignored',
|
|
15
|
+
POSTGRES_HOST: 'db',
|
|
16
|
+
} as NodeJS.ProcessEnv),
|
|
17
|
+
).toBe('postgresql://me:pw@managed.example.com:5432/prod');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('builds from the parts when none is given', () => {
|
|
21
|
+
expect(
|
|
22
|
+
resolveDatabaseUrl({
|
|
23
|
+
POSTGRES_USER: 'alice',
|
|
24
|
+
POSTGRES_PASSWORD: 's3cret',
|
|
25
|
+
POSTGRES_DB: 'kb',
|
|
26
|
+
POSTGRES_HOST: 'db',
|
|
27
|
+
} as NodeJS.ProcessEnv),
|
|
28
|
+
).toBe('postgresql://alice:s3cret@db:5432/kb');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
/** `localhost` suits `pnpm dev`; compose passes the service name instead. */
|
|
32
|
+
it('defaults to a local Postgres', () => {
|
|
33
|
+
expect(resolveDatabaseUrl({} as NodeJS.ProcessEnv)).toBe(
|
|
34
|
+
'postgresql://bevel:bevel@localhost:5432/bevel',
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The reason code beats shell interpolation for this. A password with `@`,
|
|
40
|
+
* `/` or `:` in it produced an unparseable URL — and the resulting failure
|
|
41
|
+
* named the host or the database, never the password that broke it.
|
|
42
|
+
*/
|
|
43
|
+
it('encodes credentials that would otherwise break the URL', () => {
|
|
44
|
+
const url = resolveDatabaseUrl({
|
|
45
|
+
POSTGRES_USER: 'user@corp',
|
|
46
|
+
POSTGRES_PASSWORD: 'p@ss:w/rd',
|
|
47
|
+
POSTGRES_DB: 'kb',
|
|
48
|
+
POSTGRES_HOST: 'db',
|
|
49
|
+
} as NodeJS.ProcessEnv);
|
|
50
|
+
// Parseable, and every part survives the round trip intact.
|
|
51
|
+
const parsed = new URL(url);
|
|
52
|
+
expect(parsed.hostname).toBe('db');
|
|
53
|
+
expect(decodeURIComponent(parsed.username)).toBe('user@corp');
|
|
54
|
+
expect(decodeURIComponent(parsed.password)).toBe('p@ss:w/rd');
|
|
55
|
+
expect(decodeURIComponent(parsed.pathname.slice(1))).toBe('kb');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('honours a non-default port', () => {
|
|
59
|
+
expect(
|
|
60
|
+
resolveDatabaseUrl({ POSTGRES_HOST: 'db', POSTGRES_PORT: '6432' } as NodeJS.ProcessEnv),
|
|
61
|
+
).toBe('postgresql://bevel:bevel@db:6432/bevel');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
/** Blank is not a value — an empty variable must not win over the parts. */
|
|
65
|
+
it('treats a blank DATABASE_URL as absent', () => {
|
|
66
|
+
expect(
|
|
67
|
+
resolveDatabaseUrl({ DATABASE_URL: ' ', POSTGRES_HOST: 'db' } as NodeJS.ProcessEnv),
|
|
68
|
+
).toBe('postgresql://bevel:bevel@db:5432/bevel');
|
|
69
|
+
});
|
|
70
|
+
});
|
package/src/core/core-ports.ts
CHANGED
|
@@ -76,6 +76,21 @@ export interface CorePorts {
|
|
|
76
76
|
* construction (participants are only iterated at erasure time).
|
|
77
77
|
*/
|
|
78
78
|
erasureParticipants?: IErasureParticipant[];
|
|
79
|
+
/**
|
|
80
|
+
* Root folders THIS distribution reserves in the knowledge base, on top of
|
|
81
|
+
* core's `KnowledgeBase/` + `Groups/`. Core default: `[]`.
|
|
82
|
+
*
|
|
83
|
+
* A name here does two things: the seeder guarantees the folder exists on
|
|
84
|
+
* every branch it tops up, and — because the names are already reserved in
|
|
85
|
+
* `kb-layout.ts` — the file tree keeps rendering it as its own root instead
|
|
86
|
+
* of folding it into Knowledge as stray content.
|
|
87
|
+
*
|
|
88
|
+
* The folder is created as an empty `<dir>/.gitkeep`, written rather than
|
|
89
|
+
* copied, so reserving a root does not oblige a distribution to fork the
|
|
90
|
+
* packaged template. Ship a `KB_TEMPLATE_DIR` of your own when those folders
|
|
91
|
+
* should arrive carrying READMEs.
|
|
92
|
+
*/
|
|
93
|
+
kbExtraRootDirs?: readonly string[];
|
|
79
94
|
}
|
|
80
95
|
|
|
81
96
|
/**
|
|
@@ -21,6 +21,7 @@ import { registerWorkflowTools } from '../modules/workflow/agent-tools/workflow.
|
|
|
21
21
|
import { registerWorkspaceTools } from '../modules/workspace/workspace.tools.js';
|
|
22
22
|
import { RECOVERY_BOT_EMAIL } from '../modules/workflow/recovery-bot.js';
|
|
23
23
|
import { registerSkillsTools, createSkillsRoutes } from '../modules/skills/index.js';
|
|
24
|
+
import { createGroupsRoutes } from '../modules/groups/index.js';
|
|
24
25
|
import type { SessionOntologyGate } from '../modules/workspace/session-ontology.gate.js';
|
|
25
26
|
import {
|
|
26
27
|
createSecretsVaultRoutes,
|
|
@@ -28,6 +29,8 @@ import {
|
|
|
28
29
|
} from '../modules/secrets-vault/index.js';
|
|
29
30
|
import { createAdminAccessRoutes } from '../modules/admin/admin-access.routes.js';
|
|
30
31
|
import { createAccountRoutes } from '../modules/auth/account.routes.js';
|
|
32
|
+
import { createSetupRoutes } from '../modules/settings/setup.routes.js';
|
|
33
|
+
import { DEFAULT_BRANCH, PROTECTED_BRANCHES } from '@bevel-software/platform-shared';
|
|
31
34
|
import { GIT_SHA } from '../version.js';
|
|
32
35
|
import type { CoreServices } from './create-core-services.js';
|
|
33
36
|
|
|
@@ -147,6 +150,29 @@ export async function createCoreServer(
|
|
|
147
150
|
res.json({ status: 'ok', sha: GIT_SHA, timestamp: Date.now() });
|
|
148
151
|
});
|
|
149
152
|
|
|
153
|
+
/**
|
|
154
|
+
* The handful of facts the browser needs BEFORE it can render anything, and
|
|
155
|
+
* therefore before it can authenticate: the branch model.
|
|
156
|
+
*
|
|
157
|
+
* Unauthenticated on purpose. The login screen, the router and every module
|
|
158
|
+
* that reads `DEFAULT_BRANCH` are loaded before a session exists, so a gated
|
|
159
|
+
* endpoint could not answer in time. What it discloses is two branch names —
|
|
160
|
+
* which every change request and every URL already shows to anyone who does
|
|
161
|
+
* get in — and nothing about the repository they live in.
|
|
162
|
+
*
|
|
163
|
+
* This replaces baking the values into the frontend bundle at build time.
|
|
164
|
+
* One artifact now serves any deployment, and renaming a branch no longer
|
|
165
|
+
* means a rebuild.
|
|
166
|
+
*/
|
|
167
|
+
app.get('/api/config', (_req, res) => {
|
|
168
|
+
res.json({
|
|
169
|
+
branchModel: {
|
|
170
|
+
defaultBranch: DEFAULT_BRANCH,
|
|
171
|
+
protectedBranches: [...PROTECTED_BRANCHES],
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
150
176
|
// Overlay boot-time side effects (startup reconciles, periodic sweeps).
|
|
151
177
|
await ext.onBoot?.(core);
|
|
152
178
|
|
|
@@ -225,12 +251,12 @@ export async function createCoreServer(
|
|
|
225
251
|
const sessionOntologyGate = {
|
|
226
252
|
service: core.sessionOntologyService,
|
|
227
253
|
enabled: core.config.ontologySessionBlock,
|
|
228
|
-
kbDirName: core.
|
|
254
|
+
kbDirName: core.kbDirName,
|
|
229
255
|
recoveryBotEmail: RECOVERY_BOT_EMAIL,
|
|
230
256
|
hooks: core.workflowService.hooks,
|
|
231
257
|
};
|
|
232
258
|
registerWorkflowTools(core.toolRegistry, toolsRouter, ta, th);
|
|
233
|
-
registerWorkspaceTools(core.toolRegistry, toolsRouter, ta, th, core.spillStore, core.accessControl, core.
|
|
259
|
+
registerWorkspaceTools(core.toolRegistry, toolsRouter, ta, th, core.spillStore, core.accessControl, core.kbDirName, sessionOntologyGate, core.routineWritePolicy, core.sessionSink);
|
|
234
260
|
registerSkillsTools(core.toolRegistry, toolsRouter, ta, th, core.skillService);
|
|
235
261
|
registerToolManualsTools(core.toolRegistry, toolsRouter, ta, th, core.toolManualService, {
|
|
236
262
|
accessControl: core.accessControl,
|
|
@@ -274,8 +300,9 @@ export async function createCoreServer(
|
|
|
274
300
|
core.workflowService,
|
|
275
301
|
core.eventBus,
|
|
276
302
|
core.accessControl,
|
|
277
|
-
core.
|
|
303
|
+
core.kbDirName,
|
|
278
304
|
core.creatorAccess,
|
|
305
|
+
core.adminAccess,
|
|
279
306
|
));
|
|
280
307
|
// Workflow is the only branches / changes / change-request surface. The
|
|
281
308
|
// former /git/*, /pr/*, /pr/:n/* routes are gone — every consumer goes
|
|
@@ -297,7 +324,7 @@ export async function createCoreServer(
|
|
|
297
324
|
core.authService,
|
|
298
325
|
core.workflowService,
|
|
299
326
|
core.accessControl,
|
|
300
|
-
core.
|
|
327
|
+
core.kbDirName,
|
|
301
328
|
));
|
|
302
329
|
app.use('/api', core.authMiddleware, createAccessRoutes(
|
|
303
330
|
core.accessControl,
|
|
@@ -306,9 +333,27 @@ export async function createCoreServer(
|
|
|
306
333
|
core.workflowService,
|
|
307
334
|
core.eventBus,
|
|
308
335
|
core.db,
|
|
309
|
-
core.
|
|
336
|
+
core.kbDirName,
|
|
337
|
+
));
|
|
338
|
+
app.use(
|
|
339
|
+
'/api',
|
|
340
|
+
core.authMiddleware,
|
|
341
|
+
createSkillsRoutes(core.skillService, core.pendingSkillsService),
|
|
342
|
+
);
|
|
343
|
+
// Group enumeration + join requests. Browser-only (JWT), and fail-closed
|
|
344
|
+
// like every other read surface: groups the caller cannot access (member,
|
|
345
|
+
// manager, or discoverable via the access.md file's own read grant) are
|
|
346
|
+
// absent from the list. A join request is a plain change request.
|
|
347
|
+
app.use('/api', core.authMiddleware, createGroupsRoutes(
|
|
348
|
+
core.groupIndexService,
|
|
349
|
+
core.accessControl,
|
|
350
|
+
core.workflowService,
|
|
351
|
+
core.workspaceService,
|
|
352
|
+
core.joinRequestsService,
|
|
353
|
+
core.groupProvisionService,
|
|
354
|
+
core.kbDirName,
|
|
355
|
+
async (req) => (req.userId ? ((await core.authService.getUserById(req.userId)) ?? null) : null),
|
|
310
356
|
));
|
|
311
|
-
app.use('/api', core.authMiddleware, createSkillsRoutes(core.skillService));
|
|
312
357
|
// Admin-status resolver (CORE — see the note in admin-access.routes.ts;
|
|
313
358
|
// the full admin router is an enterprise `ext.authed` extension).
|
|
314
359
|
app.use('/api', core.authMiddleware, createAdminAccessRoutes(core.adminAccess));
|
|
@@ -319,6 +364,10 @@ export async function createCoreServer(
|
|
|
319
364
|
core.adminAccess,
|
|
320
365
|
core.accountErasureService,
|
|
321
366
|
));
|
|
367
|
+
// First-run setup. Mounted with the other authed routes but touching NO
|
|
368
|
+
// workspace — it has to work on a deployment that has no knowledge base yet,
|
|
369
|
+
// which is the whole reason it exists.
|
|
370
|
+
app.use('/api', core.authMiddleware, createSetupRoutes(core.settings, core.adminAccess));
|
|
322
371
|
app.use('/api', core.authMiddleware, createToolManualsBrowserRoutes(core.toolManualService));
|
|
323
372
|
app.use('/api', core.authMiddleware, createSecretsVaultRoutes(secretsVaultRoutesDeps));
|
|
324
373
|
// The authed tail of the MCP OAuth flow: /connect calls these to describe
|