@bevel-software/platform-core-backend 0.7.5 → 0.9.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/LICENSE +202 -202
- package/THIRD-PARTY-NOTICES.md +428 -454
- package/dist/core/core-ports.d.ts +8 -1
- 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 +75 -18
- package/dist/core/create-core-server.js.map +1 -1
- package/dist/core/create-core-services.d.ts +12 -5
- package/dist/core/create-core-services.d.ts.map +1 -1
- package/dist/core/create-core-services.js +69 -36
- package/dist/core/create-core-services.js.map +1 -1
- package/dist/modules/access/access-control.interface.d.ts +8 -7
- package/dist/modules/access/access-control.interface.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.d.ts +1 -1
- package/dist/modules/access/access-control.service.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.js +6 -6
- package/dist/modules/access/access-control.service.js.map +1 -1
- package/dist/modules/access/access-declarations.d.ts +5 -5
- package/dist/modules/access/access-declarations.js +3 -3
- 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-splice.js +4 -4
- package/dist/modules/access/access-splice.js.map +1 -1
- package/dist/modules/access/access.routes.d.ts +3 -1
- package/dist/modules/access/access.routes.d.ts.map +1 -1
- package/dist/modules/access/access.routes.js +22 -20
- package/dist/modules/access/access.routes.js.map +1 -1
- package/dist/modules/access/creator-access.d.ts +2 -2
- package/dist/modules/access/creator-access.js +5 -5
- package/dist/modules/access/creator-access.js.map +1 -1
- package/dist/modules/access/render-roles-yaml.d.ts +22 -0
- package/dist/modules/access/render-roles-yaml.d.ts.map +1 -0
- package/dist/modules/access/render-roles-yaml.js +56 -0
- package/dist/modules/access/render-roles-yaml.js.map +1 -0
- package/dist/modules/access/roles-admin.service.d.ts +33 -5
- package/dist/modules/access/roles-admin.service.d.ts.map +1 -1
- package/dist/modules/access/roles-admin.service.js +44 -19
- package/dist/modules/access/roles-admin.service.js.map +1 -1
- package/dist/modules/code-mode/code-mode-names.d.ts +5 -13
- package/dist/modules/code-mode/code-mode-names.d.ts.map +1 -1
- package/dist/modules/code-mode/code-mode-names.js +5 -27
- package/dist/modules/code-mode/code-mode-names.js.map +1 -1
- package/dist/modules/code-mode/code-mode.tool.d.ts.map +1 -1
- package/dist/modules/code-mode/code-mode.tool.js +29 -7
- package/dist/modules/code-mode/code-mode.tool.js.map +1 -1
- package/dist/modules/mcp/mcp.service.d.ts +11 -52
- package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
- package/dist/modules/mcp/mcp.service.js +33 -395
- package/dist/modules/mcp/mcp.service.js.map +1 -1
- package/dist/modules/plugins/index.d.ts +7 -0
- package/dist/modules/plugins/index.d.ts.map +1 -0
- package/dist/modules/plugins/index.js +6 -0
- package/dist/modules/plugins/index.js.map +1 -0
- package/dist/modules/plugins/join-proposals.d.ts +53 -0
- package/dist/modules/plugins/join-proposals.d.ts.map +1 -0
- package/dist/modules/plugins/join-proposals.js +67 -0
- package/dist/modules/plugins/join-proposals.js.map +1 -0
- package/dist/modules/plugins/join-requests.service.d.ts +81 -0
- package/dist/modules/plugins/join-requests.service.d.ts.map +1 -0
- package/dist/modules/plugins/join-requests.service.js +135 -0
- package/dist/modules/plugins/join-requests.service.js.map +1 -0
- package/dist/modules/plugins/plugin-provision.service.d.ts +134 -0
- package/dist/modules/plugins/plugin-provision.service.d.ts.map +1 -0
- package/dist/modules/plugins/plugin-provision.service.js +344 -0
- package/dist/modules/plugins/plugin-provision.service.js.map +1 -0
- package/dist/modules/plugins/plugins.contract.d.ts +106 -0
- package/dist/modules/plugins/plugins.contract.d.ts.map +1 -0
- package/dist/modules/plugins/plugins.contract.js +36 -0
- package/dist/modules/plugins/plugins.contract.js.map +1 -0
- package/dist/modules/plugins/plugins.routes.d.ts +42 -0
- package/dist/modules/plugins/plugins.routes.d.ts.map +1 -0
- package/dist/modules/plugins/plugins.routes.js +379 -0
- package/dist/modules/plugins/plugins.routes.js.map +1 -0
- package/dist/modules/plugins/plugins.service.d.ts +60 -0
- package/dist/modules/plugins/plugins.service.d.ts.map +1 -0
- package/dist/modules/plugins/plugins.service.js +172 -0
- package/dist/modules/plugins/plugins.service.js.map +1 -0
- package/dist/modules/settings/setup.routes.d.ts +10 -1
- package/dist/modules/settings/setup.routes.d.ts.map +1 -1
- package/dist/modules/settings/setup.routes.js +111 -6
- package/dist/modules/settings/setup.routes.js.map +1 -1
- package/dist/modules/skills/pending-skills.service.d.ts +2 -2
- package/dist/modules/skills/pending-skills.service.js +7 -7
- package/dist/modules/skills/pending-skills.service.js.map +1 -1
- package/dist/modules/skills/skills.contract.d.ts +4 -4
- 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.service.js +5 -5
- package/dist/modules/skills/skills.service.js.map +1 -1
- package/dist/modules/tool-manuals/mcp-json-discovery.d.ts +65 -0
- package/dist/modules/tool-manuals/mcp-json-discovery.d.ts.map +1 -0
- package/dist/modules/tool-manuals/mcp-json-discovery.js +276 -0
- package/dist/modules/tool-manuals/mcp-json-discovery.js.map +1 -0
- package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts +92 -0
- package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts.map +1 -0
- package/dist/modules/tool-manuals/mcp-server-edit.service.js +328 -0
- package/dist/modules/tool-manuals/mcp-server-edit.service.js.map +1 -0
- package/dist/modules/tool-manuals/tool-manuals.contract.d.ts +38 -12
- 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 +13 -2
- package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.routes.js +233 -2
- package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.service.js +74 -37
- package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.tools.js +6 -3
- package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
- package/dist/modules/workflow/git/git.service.js +2 -2
- package/dist/modules/workflow/git/git.service.js.map +1 -1
- package/dist/modules/workspace/kb-seed.service.d.ts +2 -2
- package/dist/modules/workspace/kb-seed.service.d.ts.map +1 -1
- package/dist/modules/workspace/kb-seed.service.js +43 -10
- package/dist/modules/workspace/kb-seed.service.js.map +1 -1
- package/dist/modules/workspace/plugins-migration.d.ts +50 -0
- package/dist/modules/workspace/plugins-migration.d.ts.map +1 -0
- package/dist/modules/workspace/plugins-migration.js +379 -0
- package/dist/modules/workspace/plugins-migration.js.map +1 -0
- package/dist/modules/workspace/startup/kb-git.d.ts +23 -0
- package/dist/modules/workspace/startup/kb-git.d.ts.map +1 -0
- package/dist/modules/workspace/startup/kb-git.js +86 -0
- package/dist/modules/workspace/startup/kb-git.js.map +1 -0
- package/dist/modules/workspace/startup/kb-startup-runner.d.ts +74 -0
- package/dist/modules/workspace/startup/kb-startup-runner.d.ts.map +1 -0
- package/dist/modules/workspace/startup/kb-startup-runner.js +528 -0
- package/dist/modules/workspace/startup/kb-startup-runner.js.map +1 -0
- package/dist/modules/workspace/startup/on-server-start.d.ts +105 -0
- package/dist/modules/workspace/startup/on-server-start.d.ts.map +1 -0
- package/dist/modules/workspace/startup/on-server-start.js +21 -0
- package/dist/modules/workspace/startup/on-server-start.js.map +1 -0
- package/dist/modules/workspace/startup/steps/groups-to-plugins.step.d.ts +46 -0
- package/dist/modules/workspace/startup/steps/groups-to-plugins.step.d.ts.map +1 -0
- package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js +492 -0
- package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js.map +1 -0
- package/dist/modules/workspace/startup/steps/roles-yaml.step.d.ts +23 -0
- package/dist/modules/workspace/startup/steps/roles-yaml.step.d.ts.map +1 -0
- package/dist/modules/workspace/startup/steps/roles-yaml.step.js +69 -0
- package/dist/modules/workspace/startup/steps/roles-yaml.step.js.map +1 -0
- package/dist/modules/workspace/startup/steps/seed-tree.d.ts +17 -0
- package/dist/modules/workspace/startup/steps/seed-tree.d.ts.map +1 -0
- package/dist/modules/workspace/startup/steps/seed-tree.js +109 -0
- package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -0
- package/dist/modules/workspace/startup/steps/template-files.step.d.ts +103 -0
- package/dist/modules/workspace/startup/steps/template-files.step.d.ts.map +1 -0
- package/dist/modules/workspace/startup/steps/template-files.step.js +337 -0
- package/dist/modules/workspace/startup/steps/template-files.step.js.map +1 -0
- package/dist/modules/workspace/workspace.routes.js +3 -3
- package/dist/modules/workspace/workspace.routes.js.map +1 -1
- package/dist/modules/workspace/workspace.service.d.ts +0 -9
- package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.service.js +2 -30
- package/dist/modules/workspace/workspace.service.js.map +1 -1
- package/dist/shared/kb-layout.test.js +3 -3
- package/dist/shared/kb-layout.test.js.map +1 -1
- package/dist/shared/utcp-namespace.d.ts +6 -27
- package/dist/shared/utcp-namespace.d.ts.map +1 -1
- package/dist/shared/utcp-namespace.js +6 -63
- package/dist/shared/utcp-namespace.js.map +1 -1
- package/dist/shared/variable-refs.d.ts +42 -0
- package/dist/shared/variable-refs.d.ts.map +1 -0
- package/dist/shared/variable-refs.js +60 -0
- package/dist/shared/variable-refs.js.map +1 -0
- package/kb-template/.bevelignore +1 -1
- package/kb-template/AGENTS.md +88 -35
- package/kb-template/KnowledgeBase/How to get started.md +10 -10
- package/kb-template/access.md +36 -36
- package/kb-template/gitignore.template +16 -0
- package/migrations/meta/0000_snapshot.json +1479 -1479
- package/package.json +5 -4
- package/src/assets.ts +25 -25
- package/src/core/core-ports.ts +113 -106
- package/src/core/create-core-server.ts +85 -20
- package/src/core/create-core-services.ts +83 -42
- package/src/index.ts +69 -69
- package/src/modules/access/__tests__/access-control.atref-batch.test.ts +98 -98
- package/src/modules/access/__tests__/access-declarations.test.ts +28 -28
- package/src/modules/access/__tests__/access-md-format.test.ts +18 -18
- package/src/modules/access/__tests__/access-mutation.service.test.ts +5 -5
- package/src/modules/access/__tests__/access-splice.test.ts +2 -2
- package/src/modules/access/__tests__/access.routes.overrides.test.ts +16 -16
- package/src/modules/access/__tests__/grant-sources.test.ts +12 -12
- package/src/modules/access/__tests__/roles-admin.service.test.ts +36 -2
- package/src/modules/access/access-control.interface.ts +8 -7
- package/src/modules/access/access-control.service.ts +7 -7
- package/src/modules/access/access-declarations.ts +5 -5
- package/src/modules/access/access-mutation.service.ts +3 -3
- package/src/modules/access/access-splice.ts +4 -4
- package/src/modules/access/access.routes.ts +23 -20
- package/src/modules/access/creator-access.ts +5 -5
- package/src/modules/access/render-roles-yaml.ts +65 -0
- package/src/modules/access/roles-admin.service.ts +45 -16
- package/src/modules/admin/admin-access.routes.ts +29 -29
- package/src/modules/auth/__tests__/auth.routes.test.ts +91 -91
- package/src/modules/auth/__tests__/rate-limit.test.ts +36 -36
- package/src/modules/auth/rate-limit.ts +45 -45
- package/src/modules/code-mode/__tests__/code-mode.tool.test.ts +67 -0
- package/src/modules/code-mode/code-mode-names.ts +10 -36
- package/src/modules/code-mode/code-mode.tool.ts +27 -7
- package/src/modules/database/connection.ts +15 -15
- package/src/modules/database/schema.ts +11 -11
- package/src/modules/diff/__tests__/diff.routes.rejectPathsLocked.test.ts +150 -150
- package/src/modules/mcp/mcp.service.ts +57 -435
- package/src/modules/{groups → plugins}/__tests__/join-proposals.test.ts +1 -1
- package/src/modules/{groups → plugins}/__tests__/join-requests.service.test.ts +7 -7
- package/src/modules/{groups/__tests__/group-index.service.test.ts → plugins/__tests__/plugin-index.service.test.ts} +41 -41
- package/src/modules/plugins/__tests__/plugin-provision.service.test.ts +312 -0
- package/src/modules/{groups/__tests__/groups.routes.test.ts → plugins/__tests__/plugins.routes.test.ts} +100 -100
- package/src/modules/plugins/index.ts +17 -0
- package/src/modules/{groups → plugins}/join-proposals.ts +2 -2
- package/src/modules/{groups → plugins}/join-requests.service.ts +8 -8
- package/src/modules/{groups/group-provision.service.ts → plugins/plugin-provision.service.ts} +139 -69
- package/src/modules/{groups/groups.contract.ts → plugins/plugins.contract.ts} +26 -26
- package/src/modules/{groups/groups.routes.ts → plugins/plugins.routes.ts} +102 -102
- package/src/modules/{groups/groups.service.ts → plugins/plugins.service.ts} +43 -43
- package/src/modules/secrets-vault/__tests__/tool-owner-gate.route.test.ts +143 -143
- package/src/modules/settings/__tests__/setup.routes.test.ts +124 -3
- package/src/modules/settings/setup.routes.ts +112 -5
- package/src/modules/skills/__tests__/pending-skills.service.test.ts +14 -14
- package/src/modules/skills/__tests__/skills.service.test.ts +13 -13
- package/src/modules/skills/pending-skills.service.ts +7 -7
- package/src/modules/skills/skills.contract.ts +4 -4
- package/src/modules/skills/skills.service.ts +5 -5
- package/src/modules/tool-auth/llm-usage-meter.ts +19 -19
- package/src/modules/tool-manuals/__tests__/mcp-json-discovery.test.ts +198 -0
- package/src/modules/tool-manuals/__tests__/mcp-server-edit.service.test.ts +346 -0
- package/src/modules/tool-manuals/__tests__/tool-manuals.archive.route.test.ts +101 -0
- package/src/modules/tool-manuals/__tests__/tool-manuals.detail.route.test.ts +3 -3
- 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 +27 -27
- package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +3 -3
- package/src/modules/tool-manuals/mcp-json-discovery.ts +328 -0
- package/src/modules/tool-manuals/mcp-server-edit.service.ts +434 -0
- package/src/modules/tool-manuals/tool-manuals.contract.ts +35 -12
- package/src/modules/tool-manuals/tool-manuals.routes.ts +222 -1
- package/src/modules/tool-manuals/tool-manuals.service.ts +82 -42
- package/src/modules/tool-manuals/tool-manuals.tools.ts +6 -3
- package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +1 -1
- package/src/modules/workflow/git/__tests__/branch-name.test.ts +3 -3
- package/src/modules/workflow/git/__tests__/git.service.accessGating.test.ts +3 -3
- package/src/modules/workflow/git/__tests__/git.service.commitFile.test.ts +13 -8
- package/src/modules/workflow/git/__tests__/git.service.deleteBranch.test.ts +1 -1
- package/src/modules/workflow/git/__tests__/pull-request.service.test.ts +1 -1
- package/src/modules/workflow/git/git.service.ts +2 -2
- package/src/modules/workflow/review-workflow/__tests__/approval-states.test.ts +1 -1
- package/src/modules/workflow/review-workflow/__tests__/cancel-pr.test.ts +1 -1
- package/src/modules/workflow/workflow-hooks.ts +101 -101
- package/src/modules/workspace/__tests__/session-ontology.gate.test.ts +237 -237
- package/src/modules/workspace/__tests__/workspace.routes.create-grant.test.ts +236 -236
- package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +179 -179
- package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +320 -320
- package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +337 -337
- package/src/modules/workspace/__tests__/workspace.service.test.ts +27 -0
- package/src/modules/workspace/bevel-ignore.ts +66 -66
- package/src/modules/workspace/session-sink.ts +25 -25
- package/src/modules/workspace/startup/__tests__/kb-startup-runner.test.ts +495 -0
- package/src/modules/workspace/startup/kb-git.ts +94 -0
- package/src/modules/workspace/startup/kb-startup-runner.ts +597 -0
- package/src/modules/workspace/startup/on-server-start.ts +97 -0
- package/src/modules/workspace/startup/steps/__tests__/steps.test.ts +636 -0
- package/src/modules/workspace/startup/steps/groups-to-plugins.step.ts +561 -0
- package/src/modules/workspace/startup/steps/roles-yaml.step.ts +71 -0
- package/src/modules/workspace/startup/steps/seed-tree.ts +115 -0
- package/src/modules/workspace/startup/steps/template-files.step.ts +360 -0
- package/src/modules/workspace/workspace.routes.ts +3 -3
- package/src/modules/workspace/workspace.service.ts +2 -35
- package/src/modules/workspace/workspace.tools.ts +922 -922
- package/src/shared/__tests__/join-request.test.ts +13 -13
- package/src/shared/__tests__/kb-layout.plugin.test.ts +45 -0
- package/src/shared/kb-layout.test.ts +3 -3
- package/src/shared/utcp-namespace.ts +10 -68
- package/src/shared/variable-refs.ts +64 -0
- package/src/modules/groups/__tests__/group-provision.service.test.ts +0 -247
- package/src/modules/groups/index.ts +0 -17
- package/src/modules/workspace/__tests__/kb-seed.service.test.ts +0 -444
- package/src/modules/workspace/kb-seed.interface.ts +0 -36
- package/src/modules/workspace/kb-seed.service.ts +0 -555
- package/src/shared/__tests__/kb-layout.group.test.ts +0 -45
- /package/kb-template/{Groups → Plugins}/.gitkeep +0 -0
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { HEXIS_EXTENSION_NS, HEXIS_TOOLS_DIR, LEGACY_GROUPS_DIR, PLUGINS_DIR, PLUGIN_MANIFEST_FILE, PLUGIN_MCP_FILE, PLUGIN_MCP_SCHEMA, PLUGIN_SKILLS_DIR, renderPluginManifest, } from '@bevel-software/platform-shared';
|
|
4
|
+
import { normalizeToolManual } from '../tool-manuals/tool-manuals.service.js';
|
|
5
|
+
import { parseOwnAccessEntries } from '../access/access-control.service.js';
|
|
6
|
+
import { containsVariableReference } from '../../shared/variable-refs.js';
|
|
7
|
+
import { IGNORE_FILENAME } from './bevel-ignore.js';
|
|
8
|
+
// lstat, both helpers: SYMLINKS ARE NOT SUPPORTED IN PLUGINS, anywhere, so a
|
|
9
|
+
// link never counts as the thing it points at — following one here would let
|
|
10
|
+
// a symlinked directory pull files from outside the plugin into the sweep
|
|
11
|
+
// (and delete them from wherever they really live).
|
|
12
|
+
async function exists(p) {
|
|
13
|
+
try {
|
|
14
|
+
await fs.lstat(p);
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
async function isDir(p) {
|
|
22
|
+
try {
|
|
23
|
+
return (await fs.lstat(p)).isDirectory();
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Move `from` to `to`, creating the parent. Never overwrites: a destination
|
|
31
|
+
* that already exists means a previous run got there first (or a human did),
|
|
32
|
+
* and clobbering it would destroy the newer copy.
|
|
33
|
+
*/
|
|
34
|
+
async function moveIfAbsent(from, to) {
|
|
35
|
+
if (await exists(to))
|
|
36
|
+
return false;
|
|
37
|
+
await fs.mkdir(path.dirname(to), { recursive: true });
|
|
38
|
+
await fs.rename(from, to);
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A header value referencing a vault variable rather than carrying a literal.
|
|
43
|
+
* The substitutor's own grammar decides (shared/variable-refs.ts): both
|
|
44
|
+
* spellings it expands — `${VAR}` and bare `$VAR`, digit-leading names
|
|
45
|
+
* included — count, because either one copied into mcp.json would be
|
|
46
|
+
* transmitted verbatim by a conformant client. That means a prose `$5` in a
|
|
47
|
+
* header routes to the non-portable half too: over-classifying costs a header
|
|
48
|
+
* its portability, under-classifying leaks whatever `$5TOKEN` expands to.
|
|
49
|
+
*/
|
|
50
|
+
const isCredentialReference = containsVariableReference;
|
|
51
|
+
/** Split a manual's headers into what mcp.json may carry and what may not. */
|
|
52
|
+
function splitHeaders(headers) {
|
|
53
|
+
const literal = {};
|
|
54
|
+
const credential = {};
|
|
55
|
+
for (const [k, v] of Object.entries(headers ?? {})) {
|
|
56
|
+
(isCredentialReference(v) ? credential : literal)[k] = v;
|
|
57
|
+
}
|
|
58
|
+
return { literal, credential };
|
|
59
|
+
}
|
|
60
|
+
/** Read+parse a JSON file, or `null` when absent or unparsable. */
|
|
61
|
+
async function readJson(p) {
|
|
62
|
+
try {
|
|
63
|
+
const parsed = JSON.parse(await fs.readFile(p, 'utf-8'));
|
|
64
|
+
return typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)
|
|
65
|
+
? parsed
|
|
66
|
+
: null;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async function foldIntoPluginFiles(pluginDir, folderName, manuals, notes) {
|
|
73
|
+
if (manuals.length === 0)
|
|
74
|
+
return false;
|
|
75
|
+
const mcpPath = path.join(pluginDir, PLUGIN_MCP_FILE);
|
|
76
|
+
const mcp = (await readJson(mcpPath)) ?? { $schema: PLUGIN_MCP_SCHEMA, mcpServers: {} };
|
|
77
|
+
// An array (or any non-object) here would take property assignments and then
|
|
78
|
+
// drop them at stringify — normalize to an object before merging into it.
|
|
79
|
+
if (typeof mcp.mcpServers !== 'object' || mcp.mcpServers === null || Array.isArray(mcp.mcpServers)) {
|
|
80
|
+
mcp.mcpServers = {};
|
|
81
|
+
}
|
|
82
|
+
const servers = mcp.mcpServers;
|
|
83
|
+
const manifestPath = path.join(pluginDir, PLUGIN_MANIFEST_FILE);
|
|
84
|
+
const manifest = await readJson(manifestPath);
|
|
85
|
+
if (manifest === null) {
|
|
86
|
+
console.warn(`[plugins-migration] ${folderName}/${PLUGIN_MANIFEST_FILE} is missing or unparsable — ` +
|
|
87
|
+
'mcp manuals convert only when they carry NOTHING for the extensions block; any ' +
|
|
88
|
+
'non-portable half (auth headers, variables, a description, or the local-only flag) ' +
|
|
89
|
+
'keeps the manual a `.tool` until the manifest is fixed.');
|
|
90
|
+
}
|
|
91
|
+
let wroteMcp = false;
|
|
92
|
+
let wroteManifest = false;
|
|
93
|
+
const folded = [];
|
|
94
|
+
for (const item of manuals.sort((a, b) => a.manual.name.localeCompare(b.manual.name))) {
|
|
95
|
+
const m = item.manual;
|
|
96
|
+
const { literal, credential } = splitHeaders(m.headers);
|
|
97
|
+
// A manual whose non-portable half (auth headers, variables, local flag)
|
|
98
|
+
// has nowhere to go — the manifest is missing or unparsable — is NOT
|
|
99
|
+
// converted at all: writing only its portable half and deleting the
|
|
100
|
+
// source would silently discard the credential wiring. It stays a
|
|
101
|
+
// `.tool` until the manifest is fixed.
|
|
102
|
+
const extEntryPreview = {
|
|
103
|
+
...(Object.keys(credential).length > 0 ? { headers: credential } : {}),
|
|
104
|
+
...(m.variables && m.variables.length > 0 ? { variables: m.variables } : {}),
|
|
105
|
+
...(typeof m.description === 'string' ? { description: m.description } : {}),
|
|
106
|
+
...(m.remote === false ? { local: true } : {}),
|
|
107
|
+
};
|
|
108
|
+
if (manifest === null && Object.keys(extEntryPreview).length > 0) {
|
|
109
|
+
notes.push(`${folderName}: ${item.note} NOT converted — ${PLUGIN_MANIFEST_FILE} is missing/unparsable ` +
|
|
110
|
+
'and the manual carries declarations (auth headers, variables, a description, or the ' +
|
|
111
|
+
'local-only flag) that would be lost; fix the manifest first.');
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
folded.push(item);
|
|
115
|
+
// Own-property check: `in` sees `constructor` and friends on the prototype,
|
|
116
|
+
// which would silently skip a legitimately named server.
|
|
117
|
+
if (!Object.prototype.hasOwnProperty.call(servers, m.name)) {
|
|
118
|
+
servers[m.name] = {
|
|
119
|
+
type: 'streamable-http',
|
|
120
|
+
url: m.url,
|
|
121
|
+
...(Object.keys(literal).length > 0 ? { headers: literal } : {}),
|
|
122
|
+
};
|
|
123
|
+
wroteMcp = true;
|
|
124
|
+
notes.push(`${folderName}: ${m.name} → ${PLUGIN_MCP_FILE}`);
|
|
125
|
+
}
|
|
126
|
+
// The non-portable half: auth headers, variable declarations, local-only.
|
|
127
|
+
const extEntry = extEntryPreview;
|
|
128
|
+
if (manifest !== null && Object.keys(extEntry).length > 0) {
|
|
129
|
+
// Normalize each level: a parseable manifest can still carry a string or
|
|
130
|
+
// array where an object belongs, and mutating that would throw mid-run.
|
|
131
|
+
if (typeof manifest.extensions !== 'object' || manifest.extensions === null || Array.isArray(manifest.extensions)) {
|
|
132
|
+
manifest.extensions = {};
|
|
133
|
+
}
|
|
134
|
+
const ext = manifest.extensions;
|
|
135
|
+
if (typeof ext[HEXIS_EXTENSION_NS] !== 'object' || ext[HEXIS_EXTENSION_NS] === null || Array.isArray(ext[HEXIS_EXTENSION_NS])) {
|
|
136
|
+
ext[HEXIS_EXTENSION_NS] = {};
|
|
137
|
+
}
|
|
138
|
+
const ns = ext[HEXIS_EXTENSION_NS];
|
|
139
|
+
if (typeof ns.mcpServers !== 'object' || ns.mcpServers === null || Array.isArray(ns.mcpServers)) {
|
|
140
|
+
ns.mcpServers = {};
|
|
141
|
+
}
|
|
142
|
+
const extServers = ns.mcpServers;
|
|
143
|
+
if (!Object.prototype.hasOwnProperty.call(extServers, m.name)) {
|
|
144
|
+
extServers[m.name] = extEntry;
|
|
145
|
+
wroteManifest = true;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (wroteMcp)
|
|
150
|
+
await fs.writeFile(mcpPath, `${JSON.stringify(mcp, null, 2)}\n`, 'utf8');
|
|
151
|
+
if (wroteManifest) {
|
|
152
|
+
await fs.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
|
|
153
|
+
notes.push(`${folderName}: wrote mcp-server declarations into ${PLUGIN_MANIFEST_FILE}`);
|
|
154
|
+
}
|
|
155
|
+
// Sources go LAST, once everything they carried is on disk elsewhere. A
|
|
156
|
+
// failure anywhere above leaves every `.tool` in place for the next run —
|
|
157
|
+
// which re-converts idempotently, since the fold never clobbers a key.
|
|
158
|
+
for (const item of folded) {
|
|
159
|
+
await fs.rm(item.abs, { force: true });
|
|
160
|
+
notes.push(`${folderName}: ${item.note} converted to an ${PLUGIN_MCP_FILE} entry`);
|
|
161
|
+
}
|
|
162
|
+
return wroteMcp || wroteManifest || folded.length > 0;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Parse a `.tool`; a convertible MCP manual (has a url) parses to a
|
|
166
|
+
* descriptor. A non-candidate (other types, a file that will not parse)
|
|
167
|
+
* is `null` and moves as a plain `.tool`; an MCP manual REFUSED conversion
|
|
168
|
+
* comes back as the reason string, so the migration log distinguishes a
|
|
169
|
+
* deliberately-retained integration from one that silently failed — the
|
|
170
|
+
* same courtesy the manifest-missing refusal already extends.
|
|
171
|
+
*/
|
|
172
|
+
async function asMcpManual(abs, repoRel) {
|
|
173
|
+
try {
|
|
174
|
+
const content = await fs.readFile(abs, 'utf-8');
|
|
175
|
+
const d = normalizeToolManual(path.basename(abs).replace(/\.tool$/i, ''), repoRel, content);
|
|
176
|
+
// The mcp.json loader accepts only names it can serve as a namespace and
|
|
177
|
+
// route slug — converting a manual whose id fails that shape would DELETE
|
|
178
|
+
// a working integration and write an entry discovery then skips. Such a
|
|
179
|
+
// manual stays a `.tool`.
|
|
180
|
+
if (d.type !== 'mcp' || !d.url)
|
|
181
|
+
return null;
|
|
182
|
+
if (!/^[a-z0-9][a-z0-9_-]*$/.test(d.name)) {
|
|
183
|
+
return `its id "${d.name}" is not a valid mcp.json server name`;
|
|
184
|
+
}
|
|
185
|
+
// Same refusal for the url: the mcp.json loader accepts only a directly
|
|
186
|
+
// parseable http(s) url, so a templated one (`${BASE}/mcp` — legal in a
|
|
187
|
+
// `.tool`, where the substitutor expands it) would convert into an entry
|
|
188
|
+
// discovery then skips, with the source already deleted. And a parseable
|
|
189
|
+
// url carrying `user:pass@` may not land in the PORTABLE file at all —
|
|
190
|
+
// stripping it would break the server, so the manual keeps its `.tool`
|
|
191
|
+
// form, where the credential stays platform-internal.
|
|
192
|
+
let url;
|
|
193
|
+
try {
|
|
194
|
+
url = new URL(d.url);
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
return 'its url is not directly parseable (a templated url only a .tool can carry)';
|
|
198
|
+
}
|
|
199
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
|
|
200
|
+
return `its url scheme "${url.protocol}" cannot land in mcp.json (http(s) only)`;
|
|
201
|
+
}
|
|
202
|
+
if (url.username || url.password) {
|
|
203
|
+
return 'its url embeds credentials, which may not land in the portable mcp.json';
|
|
204
|
+
}
|
|
205
|
+
// A `.tool` can gate ITSELF with frontmatter access verbs, read by the
|
|
206
|
+
// access resolver from the file's own path. An mcp.json entry has no
|
|
207
|
+
// per-server home for those — the file's ACL governs every server in it —
|
|
208
|
+
// so converting would silently widen who may configure and run the
|
|
209
|
+
// server. Such a manual stays a `.tool`, verbs and all.
|
|
210
|
+
if (parseOwnAccessEntries(content) !== null) {
|
|
211
|
+
return 'it gates itself with frontmatter access verbs, which mcp.json cannot carry';
|
|
212
|
+
}
|
|
213
|
+
return d;
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/** Reorganise ONE plugin folder in place. Returns notes + whether files changed. */
|
|
220
|
+
async function migratePluginFolder(pluginDir, folderName) {
|
|
221
|
+
const notes = [];
|
|
222
|
+
let changed = false;
|
|
223
|
+
if (!(await exists(path.join(pluginDir, PLUGIN_MANIFEST_FILE)))) {
|
|
224
|
+
await fs.writeFile(path.join(pluginDir, PLUGIN_MANIFEST_FILE), renderPluginManifest(folderName), 'utf8');
|
|
225
|
+
notes.push(`${folderName}: wrote ${PLUGIN_MANIFEST_FILE}`);
|
|
226
|
+
changed = true;
|
|
227
|
+
}
|
|
228
|
+
const entries = await fs.readdir(pluginDir, { withFileTypes: true });
|
|
229
|
+
const converted = [];
|
|
230
|
+
const convertOrMove = async (abs, name, note) => {
|
|
231
|
+
const manual = await asMcpManual(abs, `${PLUGINS_DIR}/${folderName}/${name}`);
|
|
232
|
+
if (manual !== null && typeof manual !== 'string') {
|
|
233
|
+
// QUEUED for conversion — the `.tool` is deleted only AFTER its entry
|
|
234
|
+
// has actually landed in the output files (see foldIntoPluginFiles).
|
|
235
|
+
// Deleting first left a window where a failed fold stranded the
|
|
236
|
+
// non-portable half (auth headers, variables) with no source to retry
|
|
237
|
+
// from: the file IS the recovery path until the fold succeeds.
|
|
238
|
+
converted.push({ manual, abs, note });
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (typeof manual === 'string') {
|
|
242
|
+
// The operator's answer to "why is this integration not in mcp.json":
|
|
243
|
+
// a refused conversion must read as the deliberate retention it is.
|
|
244
|
+
notes.push(`${folderName}: ${note} NOT converted — ${manual}; kept as a .tool`);
|
|
245
|
+
}
|
|
246
|
+
const dest = path.join(pluginDir, ...HEXIS_TOOLS_DIR.split('/'), path.basename(abs));
|
|
247
|
+
if (abs !== dest && (await moveIfAbsent(abs, dest))) {
|
|
248
|
+
notes.push(`${folderName}: ${note} → ${HEXIS_TOOLS_DIR}/${path.basename(abs)}`);
|
|
249
|
+
changed = true;
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
for (const entry of entries) {
|
|
253
|
+
if (entry.name.startsWith('.'))
|
|
254
|
+
continue;
|
|
255
|
+
if (entry.name === PLUGIN_SKILLS_DIR || entry.name === PLUGIN_MANIFEST_FILE)
|
|
256
|
+
continue;
|
|
257
|
+
if (entry.name === PLUGIN_MCP_FILE || entry.name === 'access.md')
|
|
258
|
+
continue;
|
|
259
|
+
if (entry.name === HEXIS_TOOLS_DIR.split('/')[0])
|
|
260
|
+
continue;
|
|
261
|
+
const abs = path.join(pluginDir, entry.name);
|
|
262
|
+
// A skill is a folder carrying SKILL.md — the same rule the catalog uses.
|
|
263
|
+
if (entry.isDirectory() && (await exists(path.join(abs, 'SKILL.md')))) {
|
|
264
|
+
const dest = path.join(pluginDir, PLUGIN_SKILLS_DIR, entry.name);
|
|
265
|
+
if (await moveIfAbsent(abs, dest)) {
|
|
266
|
+
notes.push(`${folderName}: ${entry.name}/ → ${PLUGIN_SKILLS_DIR}/${entry.name}/`);
|
|
267
|
+
changed = true;
|
|
268
|
+
}
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
if (entry.isFile() && entry.name.toLowerCase().endsWith('.tool')) {
|
|
272
|
+
await convertOrMove(abs, entry.name, entry.name);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
// Second sweep: mcp `.tool`s an EARLIER run moved into the extension dir
|
|
276
|
+
// (when mcp.json was a projection, not the authority). Converting them here
|
|
277
|
+
// is what makes the migration complete itself rather than strand a twin.
|
|
278
|
+
// `isDir` is lstat-based, so a SYMLINK planted at this path is not swept:
|
|
279
|
+
// this sweep DELETES what it converts, and following a link would delete
|
|
280
|
+
// `.tool` files from wherever the link really points.
|
|
281
|
+
const extToolsDir = path.join(pluginDir, ...HEXIS_TOOLS_DIR.split('/'));
|
|
282
|
+
if (await isDir(extToolsDir)) {
|
|
283
|
+
for (const entry of await fs.readdir(extToolsDir, { withFileTypes: true })) {
|
|
284
|
+
if (!entry.isFile() || !entry.name.toLowerCase().endsWith('.tool'))
|
|
285
|
+
continue;
|
|
286
|
+
const abs = path.join(extToolsDir, entry.name);
|
|
287
|
+
const manual = await asMcpManual(abs, `${PLUGINS_DIR}/${folderName}/${HEXIS_TOOLS_DIR}/${entry.name}`);
|
|
288
|
+
// A refusal reason here is a SETTLED resident of the tools dir — it
|
|
289
|
+
// was named the run it moved in, and this sweep repeats every boot,
|
|
290
|
+
// so re-noting it would be log spam. Only a convertible manual queues.
|
|
291
|
+
if (manual !== null && typeof manual !== 'string') {
|
|
292
|
+
converted.push({ manual, abs, note: `${HEXIS_TOOLS_DIR}/${entry.name}` });
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
changed = (await foldIntoPluginFiles(pluginDir, folderName, converted, notes)) || changed;
|
|
297
|
+
return { notes, changed };
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Rewrite the KB's `.bevelignore` rule for the renamed root: the exact line
|
|
301
|
+
* `Groups/` becomes `Plugins/`. Without this a migrated KB is left with a
|
|
302
|
+
* stale rule for a folder that no longer exists and NO rule for the new one,
|
|
303
|
+
* so plugin internals start showing up in the file tree and agent view.
|
|
304
|
+
*
|
|
305
|
+
* The file is the operator's — this touches ONE line, the one the platform's
|
|
306
|
+
* own rename invalidated, and only when `Plugins/` is not already listed
|
|
307
|
+
* (in which case the stale line is harmlessly dead and left alone).
|
|
308
|
+
*/
|
|
309
|
+
async function rewriteIgnoreRootRule(repoDir, notes) {
|
|
310
|
+
const ignorePath = path.join(repoDir, IGNORE_FILENAME);
|
|
311
|
+
let current;
|
|
312
|
+
try {
|
|
313
|
+
current = await fs.readFile(ignorePath, 'utf-8');
|
|
314
|
+
}
|
|
315
|
+
catch {
|
|
316
|
+
return false; // no ignore file — nothing went stale
|
|
317
|
+
}
|
|
318
|
+
const legacyRule = `${LEGACY_GROUPS_DIR}/`;
|
|
319
|
+
const newRule = `${PLUGINS_DIR}/`;
|
|
320
|
+
const lines = current.split('\n');
|
|
321
|
+
if (lines.some((l) => l.trim() === newRule))
|
|
322
|
+
return false;
|
|
323
|
+
const idx = lines.findIndex((l) => l.trim() === legacyRule);
|
|
324
|
+
if (idx === -1)
|
|
325
|
+
return false;
|
|
326
|
+
lines[idx] = newRule;
|
|
327
|
+
await fs.writeFile(ignorePath, lines.join('\n'), 'utf-8');
|
|
328
|
+
notes.push(`${IGNORE_FILENAME}: ${legacyRule} → ${newRule}`);
|
|
329
|
+
return true;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Migrate `repoDir` in place. Safe to call on every top-up.
|
|
333
|
+
*
|
|
334
|
+
* Returns `migrated: false` when no FILE changed — which is the steady state,
|
|
335
|
+
* so the caller commits nothing. Advisory `notes` may still be present (a
|
|
336
|
+
* manual that refuses to convert reports itself every run) and set nothing.
|
|
337
|
+
*/
|
|
338
|
+
export async function migrateGroupsToPlugins(repoDir) {
|
|
339
|
+
const legacyDir = path.join(repoDir, LEGACY_GROUPS_DIR);
|
|
340
|
+
const pluginsDir = path.join(repoDir, PLUGINS_DIR);
|
|
341
|
+
const notes = [];
|
|
342
|
+
const hasLegacy = await isDir(legacyDir);
|
|
343
|
+
const hasPlugins = await isDir(pluginsDir);
|
|
344
|
+
if (hasLegacy && hasPlugins) {
|
|
345
|
+
// Both present: somebody is mid-migration by hand, or two branches merged
|
|
346
|
+
// badly. Merging them here would guess at which copy of a same-named
|
|
347
|
+
// plugin wins, so we refuse and say so — loudly, because the KB is in a
|
|
348
|
+
// state a human needs to look at.
|
|
349
|
+
console.warn(`[plugins-migration] both ${LEGACY_GROUPS_DIR}/ and ${PLUGINS_DIR}/ exist — leaving both alone. ` +
|
|
350
|
+
`Merge ${LEGACY_GROUPS_DIR}/ into ${PLUGINS_DIR}/ by hand; nothing is being migrated automatically.`);
|
|
351
|
+
return { migrated: false, renamed: false, ignoreRewritten: false, notes };
|
|
352
|
+
}
|
|
353
|
+
let renamed = false;
|
|
354
|
+
let ignoreRewritten = false;
|
|
355
|
+
if (hasLegacy) {
|
|
356
|
+
await fs.rename(legacyDir, pluginsDir);
|
|
357
|
+
renamed = true;
|
|
358
|
+
notes.push(`${LEGACY_GROUPS_DIR}/ → ${PLUGINS_DIR}/`);
|
|
359
|
+
// Rides WITH the rename, not on every run: the rename is what turned the
|
|
360
|
+
// ignore rule stale, so the run that renames is the run that heals it.
|
|
361
|
+
ignoreRewritten = await rewriteIgnoreRootRule(repoDir, notes);
|
|
362
|
+
}
|
|
363
|
+
else if (!hasPlugins) {
|
|
364
|
+
return { migrated: false, renamed: false, ignoreRewritten: false, notes };
|
|
365
|
+
}
|
|
366
|
+
// Runs whether or not the rename just happened, so a KB already on
|
|
367
|
+
// `Plugins/` still gets missing manifests and any half-done reorganisation
|
|
368
|
+
// finished. That is what makes this idempotent rather than once-only.
|
|
369
|
+
let changed = renamed || ignoreRewritten;
|
|
370
|
+
for (const entry of await fs.readdir(pluginsDir, { withFileTypes: true })) {
|
|
371
|
+
if (!entry.isDirectory() || entry.name.startsWith('.'))
|
|
372
|
+
continue;
|
|
373
|
+
const folder = await migratePluginFolder(path.join(pluginsDir, entry.name), entry.name);
|
|
374
|
+
notes.push(...folder.notes);
|
|
375
|
+
changed = changed || folder.changed;
|
|
376
|
+
}
|
|
377
|
+
return { migrated: changed, renamed, ignoreRewritten, notes };
|
|
378
|
+
}
|
|
379
|
+
//# sourceMappingURL=plugins-migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins-migration.js","sourceRoot":"","sources":["../../../src/modules/workspace/plugins-migration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The startup phase's own git plumbing — the runner owns every remote and
|
|
3
|
+
* repository operation of the phase (steps only declare buffered ops), so
|
|
4
|
+
* this is deliberately small and self-contained rather than borrowed from
|
|
5
|
+
* the runtime workspace service.
|
|
6
|
+
*/
|
|
7
|
+
/** Fallback committer identity; workflow commits override with `--author`. */
|
|
8
|
+
export declare const BOT_NAME = "Bevel Workflow";
|
|
9
|
+
export declare const BOT_EMAIL = "bevel-workflow@bevel.software";
|
|
10
|
+
/**
|
|
11
|
+
* Scrub credentials from anything that reaches a log or an error message:
|
|
12
|
+
* the configured token wherever it appears, and URL userinfo — a remote
|
|
13
|
+
* spelled `https://user:pass@host` would otherwise leak `pass` verbatim
|
|
14
|
+
* through every git failure that quotes the URL back.
|
|
15
|
+
*/
|
|
16
|
+
export declare function redactSecret(text: string): string;
|
|
17
|
+
export declare function git(cwd: string, gitUsername: string, args: string[]): Promise<string>;
|
|
18
|
+
export declare function stampIdentity(repo: string, gitUsername: string): Promise<void>;
|
|
19
|
+
/** Branch names present on the remote, from `ls-remote --heads`. */
|
|
20
|
+
export declare function lsRemoteHeads(repoUrl: string, gitUsername: string): Promise<Set<string>>;
|
|
21
|
+
/** A temp dir that is always removed, success or failure. */
|
|
22
|
+
export declare function withTempDir<T>(fn: (dir: string) => Promise<T>): Promise<T>;
|
|
23
|
+
//# sourceMappingURL=kb-git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kb-git.d.ts","sourceRoot":"","sources":["../../../../src/modules/workspace/startup/kb-git.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AAEH,8EAA8E;AAC9E,eAAO,MAAM,QAAQ,mBAAmB,CAAC;AACzC,eAAO,MAAM,SAAS,kCAAkC,CAAC;AAEzD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIjD;AAkBD,wBAAsB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAoB3F;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGpF;AAED,oEAAoE;AACpE,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAQ9F;AAED,6DAA6D;AAC7D,wBAAsB,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAOhF"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { execFile } from 'node:child_process';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
6
|
+
const execFileAsync = promisify(execFile);
|
|
7
|
+
/**
|
|
8
|
+
* The startup phase's own git plumbing — the runner owns every remote and
|
|
9
|
+
* repository operation of the phase (steps only declare buffered ops), so
|
|
10
|
+
* this is deliberately small and self-contained rather than borrowed from
|
|
11
|
+
* the runtime workspace service.
|
|
12
|
+
*/
|
|
13
|
+
/** Fallback committer identity; workflow commits override with `--author`. */
|
|
14
|
+
export const BOT_NAME = 'Bevel Workflow';
|
|
15
|
+
export const BOT_EMAIL = 'bevel-workflow@bevel.software';
|
|
16
|
+
/**
|
|
17
|
+
* Scrub credentials from anything that reaches a log or an error message:
|
|
18
|
+
* the configured token wherever it appears, and URL userinfo — a remote
|
|
19
|
+
* spelled `https://user:pass@host` would otherwise leak `pass` verbatim
|
|
20
|
+
* through every git failure that quotes the URL back.
|
|
21
|
+
*/
|
|
22
|
+
export function redactSecret(text) {
|
|
23
|
+
const token = process.env.GITHUB_TOKEN;
|
|
24
|
+
const scrubbed = token ? text.replaceAll(token, '***') : text;
|
|
25
|
+
return scrubbed.replace(/:\/\/[^/@\s]+@/g, '://***@');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Per-invocation `-c` config. Long paths always (Windows checkouts of deep
|
|
29
|
+
* KB trees); when a token is present, an inline credential helper that reads
|
|
30
|
+
* it from the environment at call time — the secret never appears in argv.
|
|
31
|
+
*/
|
|
32
|
+
function credArgs(gitUsername) {
|
|
33
|
+
const args = ['-c', 'core.longpaths=true'];
|
|
34
|
+
if (process.env.GITHUB_TOKEN) {
|
|
35
|
+
args.push('-c', `credential.helper=!f() { echo "username=${gitUsername}"; echo "password=$GITHUB_TOKEN"; }; f`);
|
|
36
|
+
}
|
|
37
|
+
return args;
|
|
38
|
+
}
|
|
39
|
+
export async function git(cwd, gitUsername, args) {
|
|
40
|
+
try {
|
|
41
|
+
const { stdout } = await execFileAsync('git', [...credArgs(gitUsername), ...args], {
|
|
42
|
+
cwd,
|
|
43
|
+
// A stalled remote must FAIL the phase, not hang the boot forever —
|
|
44
|
+
// fail-closed (and KB_SAFE_BOOT's demotion) can only engage on an error
|
|
45
|
+
// that actually arrives. 10 minutes is generous for the largest clone.
|
|
46
|
+
timeout: 600_000,
|
|
47
|
+
// The 1MiB default truncates `ls-remote --heads` on remotes with very
|
|
48
|
+
// many branches, which would silently drop heads from the phase's view.
|
|
49
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
50
|
+
// A credential prompt must fail the phase, not hang the boot forever
|
|
51
|
+
// waiting on a terminal nobody is watching.
|
|
52
|
+
env: { ...process.env, GIT_TERMINAL_PROMPT: '0' },
|
|
53
|
+
});
|
|
54
|
+
return stdout.toString();
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
58
|
+
throw new Error(redactSecret(`git ${args[0]} failed: ${msg}`));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export async function stampIdentity(repo, gitUsername) {
|
|
62
|
+
await git(repo, gitUsername, ['config', 'user.name', BOT_NAME]);
|
|
63
|
+
await git(repo, gitUsername, ['config', 'user.email', BOT_EMAIL]);
|
|
64
|
+
}
|
|
65
|
+
/** Branch names present on the remote, from `ls-remote --heads`. */
|
|
66
|
+
export async function lsRemoteHeads(repoUrl, gitUsername) {
|
|
67
|
+
const out = await git(os.tmpdir(), gitUsername, ['ls-remote', '--heads', repoUrl]);
|
|
68
|
+
const heads = new Set();
|
|
69
|
+
for (const line of out.split('\n')) {
|
|
70
|
+
const m = /\srefs\/heads\/(.+)$/.exec(line.trim());
|
|
71
|
+
if (m)
|
|
72
|
+
heads.add(m[1]);
|
|
73
|
+
}
|
|
74
|
+
return heads;
|
|
75
|
+
}
|
|
76
|
+
/** A temp dir that is always removed, success or failure. */
|
|
77
|
+
export async function withTempDir(fn) {
|
|
78
|
+
const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'kb-startup-'));
|
|
79
|
+
try {
|
|
80
|
+
return await fn(dir);
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
await fs.rm(dir, { recursive: true, force: true }).catch(() => { });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=kb-git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kb-git.js","sourceRoot":"","sources":["../../../../src/modules/workspace/startup/kb-git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { OnServerStart } from './on-server-start.js';
|
|
2
|
+
/**
|
|
3
|
+
* The KB startup phase: run every registered {@link OnServerStart} step, in
|
|
4
|
+
* order, against lazily-cloned branch handles, then land one commit per
|
|
5
|
+
* dirty branch. Invoked at the deployment's two quiet moments — boot (before
|
|
6
|
+
* routes mount) and first-time setup completion (the app is gated shut until
|
|
7
|
+
* then) — and never again while the process serves.
|
|
8
|
+
*
|
|
9
|
+
* Fully fail-closed: any failure this phase cannot DECLARE (an unhandled
|
|
10
|
+
* step throw, an unreachable remote, a clone that will not come down, a
|
|
11
|
+
* refused write) throws out of `runAll` and stops the boot. The container's
|
|
12
|
+
* restart policy is the retry — each attempt at boot time on quiet trees —
|
|
13
|
+
* so an environmental failure converges without a human the moment the
|
|
14
|
+
* environment returns. The one carve-out: a push rejected because a
|
|
15
|
+
* concurrent replica won rolls back and continues; the winner already landed
|
|
16
|
+
* the same idempotent changes, and stopping the loser would make every
|
|
17
|
+
* multi-replica deploy flappy by design.
|
|
18
|
+
*
|
|
19
|
+
* `KB_SAFE_BOOT=1` is the break-glass demotion: on the first failure the
|
|
20
|
+
* phase resets every uncommitted tree, abandons the rest of the phase, and
|
|
21
|
+
* lets the server boot UNMAINTAINED so an admin can get in and rescue —
|
|
22
|
+
* loudly, at boot and in the log, because an env var outlives the emergency.
|
|
23
|
+
*/
|
|
24
|
+
export interface KbStartupRunnerOptions {
|
|
25
|
+
kbRepoUrl: () => string;
|
|
26
|
+
gitUsername: () => string;
|
|
27
|
+
workspacesRoot: string;
|
|
28
|
+
kbDirName: string;
|
|
29
|
+
templateDir: string;
|
|
30
|
+
defaultBranch: () => string;
|
|
31
|
+
protectedBranches: () => readonly string[];
|
|
32
|
+
/** Admins written into a freshly-seeded repo's roles.yaml (`ADMIN_EMAIL`). */
|
|
33
|
+
seedAdminEmails: readonly string[];
|
|
34
|
+
/** The ordered step chain — core's steps plus whatever the distribution appends. */
|
|
35
|
+
steps: readonly OnServerStart[];
|
|
36
|
+
/** The empty-remote seed commit builder (template tree + roles.yaml), injected
|
|
37
|
+
so the runner stays free of template knowledge. Receives the temp dir to
|
|
38
|
+
fill; the runner handles init/commit/push around it. Resolves to the
|
|
39
|
+
repo-relative paths the builder GENERATED itself (rather than copied from
|
|
40
|
+
the template) — the runner force-adds them after `git add -A`, so a
|
|
41
|
+
template `.gitignore` rule can never silently drop a required seed file
|
|
42
|
+
from the commit. */
|
|
43
|
+
buildSeedTree: (dir: string) => Promise<string[]>;
|
|
44
|
+
}
|
|
45
|
+
export declare class KbStartupRunner {
|
|
46
|
+
private readonly opts;
|
|
47
|
+
constructor(opts: KbStartupRunnerOptions);
|
|
48
|
+
/**
|
|
49
|
+
* Run the whole phase. Throws to stop the boot; returns normally when the
|
|
50
|
+
* KB is fully maintained (or safe boot abandoned the phase, loudly).
|
|
51
|
+
*/
|
|
52
|
+
runAll(): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Remote preparation — runner machinery, not a step, because every remote
|
|
55
|
+
* failure mode here is the runner's to own: an EMPTY remote gets the full
|
|
56
|
+
* seed commit pushed to every protected branch; missing protected refs are
|
|
57
|
+
* created from the best base. Returns the remote's head names (post-seed).
|
|
58
|
+
*/
|
|
59
|
+
private ensureRemote;
|
|
60
|
+
private buildContext;
|
|
61
|
+
/**
|
|
62
|
+
* The branch's working copy at the runtime layout
|
|
63
|
+
* (`<workspacesRoot>/<id>/<kbDirName>`), so the workspace service finds it
|
|
64
|
+
* on disk afterwards. A surviving clone is fast-forwarded to origin when
|
|
65
|
+
* that is a pure fast-forward; a clone that is AHEAD (a crash before push
|
|
66
|
+
* left committed work) is left alone — maintenance lands on top and the
|
|
67
|
+
* push either carries both or rejects and rolls back, and the pending-
|
|
68
|
+
* commit recovery owns that work, not this phase.
|
|
69
|
+
*/
|
|
70
|
+
private ensureClone;
|
|
71
|
+
/** One commit per dirty branch; push; the replica carve-out on rejection. */
|
|
72
|
+
private finalize;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=kb-startup-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kb-startup-runner.d.ts","sourceRoot":"","sources":["../../../../src/modules/workspace/startup/kb-startup-runner.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAY,aAAa,EAAsB,MAAM,sBAAsB,CAAC;AAGxF;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,SAAS,MAAM,EAAE,CAAC;IAC3C,8EAA8E;IAC9E,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,oFAAoF;IACpF,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IAChC;;;;;;2BAMuB;IACvB,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CACnD;AAED,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,sBAAsB;IAEzD;;;OAGG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IA+G7B;;;;;OAKG;YACW,YAAY;IAyE1B,OAAO,CAAC,YAAY;IAkBpB;;;;;;;;OAQG;YACW,WAAW;IA0BzB,6EAA6E;YAC/D,QAAQ;CAoFvB"}
|