@decohere/scaffold 0.0.1-dev.125 → 0.0.1-dev.18
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/package.json +9 -19
- package/src/add-api.action.ts +25 -0
- package/src/add-api.command.ts +31 -0
- package/src/add.command.ts +20 -0
- package/src/add.module.ts +11 -0
- package/src/cli.ts +4 -0
- package/src/create.command.ts +20 -0
- package/src/create.module.ts +11 -0
- package/src/domain/prompt.ts +50 -0
- package/{types/src/index.d.ts → src/index.ts} +0 -4
- package/src/models/compose.model.ts +205 -0
- package/src/models/config-yaml.model.ts +83 -0
- package/src/models/const.ts +20 -0
- package/src/models/dev-container.model.ts +136 -0
- package/src/models/docker-image.model.ts +343 -0
- package/src/models/env-file.model.ts +45 -0
- package/src/models/gitignore.model.ts +35 -0
- package/src/models/launch-json.model.ts +60 -0
- package/src/models/package-json.model.ts +169 -0
- package/src/models/project.model.ts +141 -0
- package/{types/src/models/source-file.d.ts → src/models/source-file.ts} +6 -4
- package/src/models/tsconfig.model.ts +29 -0
- package/src/models/vitest-config.model.ts +26 -0
- package/src/models/vscode-settings.model.ts +24 -0
- package/src/program.ts +63 -0
- package/{types/src/resolve-target-dir.d.ts → src/resolve-target-dir.ts} +4 -1
- package/src/services/scaffold.service.ts +89 -0
- package/src/version.ts +56 -0
- package/src/webapi/api-name.ts +73 -0
- package/src/webapi/cli-options.ts +56 -0
- package/{types/src/webapi/const.d.ts → src/webapi/const.ts} +21 -9
- package/src/webapi/create-api.ts +275 -0
- package/src/webapi/devcontainer/host-scripts.ts +35 -0
- package/src/webapi/features/auth.feature.ts +454 -0
- package/src/webapi/features/auth0-cli.ts +421 -0
- package/src/webapi/features/biome-format.ts +34 -0
- package/src/webapi/features/database.feature.ts +522 -0
- package/src/webapi/features/finalize.feature.ts +112 -0
- package/src/webapi/features/postman.feature.ts +287 -0
- package/src/webapi/models/api-package-json.model.ts +60 -0
- package/src/webapi/models/auth-config.model.ts +36 -0
- package/src/webapi/models/controller-source-file.model.ts +232 -0
- package/{es6/src/webapi/models/github-ci.model.js → src/webapi/models/github-ci.model.ts} +29 -27
- package/src/webapi/models/main-source-file.model.ts +208 -0
- package/src/webapi/models/production-dockerfile.model.ts +162 -0
- package/src/webapi/models/sample-files.model.ts +45 -0
- package/src/webapi/models/webapi-image.model.ts +21 -0
- package/src/webapi/postman/hello-openapi.ts +92 -0
- package/src/webapi/postman/local-view.ts +195 -0
- package/src/webapi/postman/openapi-to-postman.ts +208 -0
- package/src/webapi/workspace-readme.ts +192 -0
- package/src/webapi.action.ts +22 -0
- package/src/webapi.command.ts +41 -0
- package/tests/auth-postman.wiring.spec.ts +263 -0
- package/tests/auth0-cli.spec.ts +232 -0
- package/tests/biome-format.spec.ts +49 -0
- package/tests/cli.integration.spec.ts +658 -0
- package/tests/compose.model.spec.ts +51 -0
- package/tests/container-image.model.spec.ts +162 -0
- package/tests/dev-container.model.spec.ts +29 -0
- package/tests/devcontainer-base-image.spec.ts +32 -0
- package/tests/hello-di-inject.scaffold.spec.ts +18 -0
- package/tests/hello-route.contract.spec.ts +94 -0
- package/tests/package-json.order.spec.ts +59 -0
- package/tests/postman-from-openapi.spec.ts +197 -0
- package/tests/seed-devcontainer-templates.ts +40 -0
- package/tests/webapi/devcontainer/codebase-rag-mcp.spec.ts +96 -0
- package/LICENSE +0 -15
- package/commonjs/src/add-api.action.js +0 -37
- package/commonjs/src/add-api.command.js +0 -39
- package/commonjs/src/add.command.js +0 -22
- package/commonjs/src/add.module.js +0 -24
- package/commonjs/src/auth0-configure.action.js +0 -28
- package/commonjs/src/auth0-configure.command.js +0 -24
- package/commonjs/src/auth0-login.action.js +0 -28
- package/commonjs/src/auth0-login.command.js +0 -23
- package/commonjs/src/auth0.command.js +0 -22
- package/commonjs/src/auth0.module.js +0 -28
- package/commonjs/src/cli.js +0 -8
- package/commonjs/src/create.command.js +0 -22
- package/commonjs/src/create.module.js +0 -24
- package/commonjs/src/domain/prompt.js +0 -62
- package/commonjs/src/index.js +0 -48
- package/commonjs/src/models/compose.model.js +0 -258
- package/commonjs/src/models/config-yaml.model.js +0 -86
- package/commonjs/src/models/const.js +0 -30
- package/commonjs/src/models/dev-container.model.js +0 -172
- package/commonjs/src/models/docker-image.model.js +0 -277
- package/commonjs/src/models/env-file.model.js +0 -48
- package/commonjs/src/models/gitignore.model.js +0 -48
- package/commonjs/src/models/launch-json.model.js +0 -70
- package/commonjs/src/models/package-json.model.js +0 -156
- package/commonjs/src/models/project.model.js +0 -132
- package/commonjs/src/models/source-file.js +0 -4
- package/commonjs/src/models/tsconfig.model.js +0 -32
- package/commonjs/src/models/vitest-config.model.js +0 -33
- package/commonjs/src/models/vscode-settings.model.js +0 -29
- package/commonjs/src/program.js +0 -64
- package/commonjs/src/resolve-target-dir.js +0 -17
- package/commonjs/src/services/scaffold.service.js +0 -60
- package/commonjs/src/version.js +0 -55
- package/commonjs/src/webapi/api-name.js +0 -93
- package/commonjs/src/webapi/auth0-commands.js +0 -250
- package/commonjs/src/webapi/authorize-scopes.js +0 -79
- package/commonjs/src/webapi/cli-options.js +0 -99
- package/commonjs/src/webapi/const.js +0 -54
- package/commonjs/src/webapi/create-api.js +0 -265
- package/commonjs/src/webapi/devcontainer/codebase-rag-mcp.js +0 -164
- package/commonjs/src/webapi/devcontainer/codebase-rag-mcp.ts +0 -182
- package/commonjs/src/webapi/devcontainer/host-scripts.js +0 -50
- package/commonjs/src/webapi/devcontainer/templates/codebase-rag.env.example +0 -3
- package/commonjs/src/webapi/devcontainer/templates/initialize.sh +0 -169
- package/commonjs/src/webapi/devcontainer/templates/post-create.sh +0 -35
- package/commonjs/src/webapi/devcontainer/templates/post-start.sh +0 -65
- package/commonjs/src/webapi/devcontainer/templates/tty-prompt.sh +0 -38
- package/commonjs/src/webapi/features/auth.feature.js +0 -408
- package/commonjs/src/webapi/features/auth0-cli.js +0 -472
- package/commonjs/src/webapi/features/biome-format.js +0 -47
- package/commonjs/src/webapi/features/database.feature.js +0 -433
- package/commonjs/src/webapi/features/finalize.feature.js +0 -93
- package/commonjs/src/webapi/features/postman.feature.js +0 -322
- package/commonjs/src/webapi/models/api-package-json.model.js +0 -58
- package/commonjs/src/webapi/models/auth-config.model.js +0 -24
- package/commonjs/src/webapi/models/controller-source-file.model.js +0 -190
- package/commonjs/src/webapi/models/github-ci.model.js +0 -193
- package/commonjs/src/webapi/models/main-source-file.model.js +0 -165
- package/commonjs/src/webapi/models/production-dockerfile.model.js +0 -75
- package/commonjs/src/webapi/models/sample-files.model.js +0 -58
- package/commonjs/src/webapi/models/webapi-image.model.js +0 -25
- package/commonjs/src/webapi/postman/hello-openapi.js +0 -173
- package/commonjs/src/webapi/postman/local-view.js +0 -182
- package/commonjs/src/webapi/postman/openapi-to-postman.js +0 -238
- package/commonjs/src/webapi/workspace-readme.js +0 -109
- package/commonjs/src/webapi.action.js +0 -28
- package/commonjs/src/webapi.command.js +0 -43
- package/es6/src/add-api.action.js +0 -27
- package/es6/src/add-api.command.js +0 -29
- package/es6/src/add.command.js +0 -12
- package/es6/src/add.module.js +0 -14
- package/es6/src/auth0-configure.action.js +0 -18
- package/es6/src/auth0-configure.command.js +0 -14
- package/es6/src/auth0-login.action.js +0 -18
- package/es6/src/auth0-login.command.js +0 -13
- package/es6/src/auth0.command.js +0 -12
- package/es6/src/auth0.module.js +0 -18
- package/es6/src/cli.js +0 -4
- package/es6/src/create.command.js +0 -12
- package/es6/src/create.module.js +0 -14
- package/es6/src/domain/prompt.js +0 -41
- package/es6/src/index.js +0 -9
- package/es6/src/models/compose.model.js +0 -254
- package/es6/src/models/config-yaml.model.js +0 -74
- package/es6/src/models/const.js +0 -20
- package/es6/src/models/dev-container.model.js +0 -162
- package/es6/src/models/docker-image.model.js +0 -235
- package/es6/src/models/env-file.model.js +0 -44
- package/es6/src/models/gitignore.model.js +0 -38
- package/es6/src/models/launch-json.model.js +0 -60
- package/es6/src/models/package-json.model.js +0 -141
- package/es6/src/models/project.model.js +0 -117
- package/es6/src/models/source-file.js +0 -1
- package/es6/src/models/tsconfig.model.js +0 -22
- package/es6/src/models/vitest-config.model.js +0 -23
- package/es6/src/models/vscode-settings.model.js +0 -19
- package/es6/src/program.js +0 -50
- package/es6/src/resolve-target-dir.js +0 -7
- package/es6/src/services/scaffold.service.js +0 -50
- package/es6/src/version.js +0 -34
- package/es6/src/webapi/api-name.js +0 -57
- package/es6/src/webapi/auth0-commands.js +0 -185
- package/es6/src/webapi/authorize-scopes.js +0 -55
- package/es6/src/webapi/cli-options.js +0 -34
- package/es6/src/webapi/const.js +0 -21
- package/es6/src/webapi/create-api.js +0 -245
- package/es6/src/webapi/devcontainer/codebase-rag-mcp.js +0 -154
- package/es6/src/webapi/devcontainer/codebase-rag-mcp.ts +0 -182
- package/es6/src/webapi/devcontainer/host-scripts.js +0 -29
- package/es6/src/webapi/devcontainer/templates/codebase-rag.env.example +0 -3
- package/es6/src/webapi/devcontainer/templates/initialize.sh +0 -169
- package/es6/src/webapi/devcontainer/templates/post-create.sh +0 -35
- package/es6/src/webapi/devcontainer/templates/post-start.sh +0 -65
- package/es6/src/webapi/devcontainer/templates/tty-prompt.sh +0 -38
- package/es6/src/webapi/features/auth.feature.js +0 -357
- package/es6/src/webapi/features/auth0-cli.js +0 -406
- package/es6/src/webapi/features/biome-format.js +0 -40
- package/es6/src/webapi/features/database.feature.js +0 -423
- package/es6/src/webapi/features/finalize.feature.js +0 -83
- package/es6/src/webapi/features/postman.feature.js +0 -256
- package/es6/src/webapi/models/api-package-json.model.js +0 -53
- package/es6/src/webapi/models/auth-config.model.js +0 -20
- package/es6/src/webapi/models/controller-source-file.model.js +0 -181
- package/es6/src/webapi/models/main-source-file.model.js +0 -161
- package/es6/src/webapi/models/production-dockerfile.model.js +0 -66
- package/es6/src/webapi/models/sample-files.model.js +0 -40
- package/es6/src/webapi/models/webapi-image.model.js +0 -18
- package/es6/src/webapi/postman/hello-openapi.js +0 -166
- package/es6/src/webapi/postman/local-view.js +0 -167
- package/es6/src/webapi/postman/openapi-to-postman.js +0 -179
- package/es6/src/webapi/workspace-readme.js +0 -88
- package/es6/src/webapi.action.js +0 -18
- package/es6/src/webapi.command.js +0 -33
- package/types/src/add-api.action.d.ts +0 -13
- package/types/src/add-api.command.d.ts +0 -7
- package/types/src/add.command.d.ts +0 -6
- package/types/src/add.module.d.ts +0 -14
- package/types/src/auth0-configure.action.d.ts +0 -7
- package/types/src/auth0-configure.command.d.ts +0 -6
- package/types/src/auth0-login.action.d.ts +0 -4
- package/types/src/auth0-login.command.d.ts +0 -6
- package/types/src/auth0.command.d.ts +0 -6
- package/types/src/auth0.module.d.ts +0 -18
- package/types/src/cli.d.ts +0 -2
- package/types/src/create.command.d.ts +0 -6
- package/types/src/create.module.d.ts +0 -14
- package/types/src/domain/prompt.d.ts +0 -4
- package/types/src/models/compose.model.d.ts +0 -73
- package/types/src/models/config-yaml.model.d.ts +0 -27
- package/types/src/models/const.d.ts +0 -20
- package/types/src/models/dev-container.model.d.ts +0 -49
- package/types/src/models/docker-image.model.d.ts +0 -90
- package/types/src/models/env-file.model.d.ts +0 -16
- package/types/src/models/gitignore.model.d.ts +0 -9
- package/types/src/models/launch-json.model.d.ts +0 -7
- package/types/src/models/package-json.model.d.ts +0 -36
- package/types/src/models/project.model.d.ts +0 -60
- package/types/src/models/tsconfig.model.d.ts +0 -5
- package/types/src/models/vitest-config.model.d.ts +0 -5
- package/types/src/models/vscode-settings.model.d.ts +0 -7
- package/types/src/program.d.ts +0 -8
- package/types/src/services/scaffold.service.d.ts +0 -22
- package/types/src/version.d.ts +0 -6
- package/types/src/webapi/api-name.d.ts +0 -14
- package/types/src/webapi/auth0-commands.d.ts +0 -11
- package/types/src/webapi/authorize-scopes.d.ts +0 -7
- package/types/src/webapi/cli-options.d.ts +0 -6
- package/types/src/webapi/create-api.d.ts +0 -15
- package/types/src/webapi/devcontainer/codebase-rag-mcp.d.ts +0 -32
- package/types/src/webapi/devcontainer/codebase-rag-mcp.ts +0 -182
- package/types/src/webapi/devcontainer/host-scripts.d.ts +0 -7
- package/types/src/webapi/devcontainer/templates/codebase-rag.env.example +0 -3
- package/types/src/webapi/devcontainer/templates/initialize.sh +0 -169
- package/types/src/webapi/devcontainer/templates/post-create.sh +0 -35
- package/types/src/webapi/devcontainer/templates/post-start.sh +0 -65
- package/types/src/webapi/devcontainer/templates/tty-prompt.sh +0 -38
- package/types/src/webapi/features/auth.feature.d.ts +0 -10
- package/types/src/webapi/features/auth0-cli.d.ts +0 -84
- package/types/src/webapi/features/biome-format.d.ts +0 -5
- package/types/src/webapi/features/database.feature.d.ts +0 -7
- package/types/src/webapi/features/finalize.feature.d.ts +0 -2
- package/types/src/webapi/features/postman.feature.d.ts +0 -16
- package/types/src/webapi/models/api-package-json.model.d.ts +0 -18
- package/types/src/webapi/models/auth-config.model.d.ts +0 -26
- package/types/src/webapi/models/controller-source-file.model.d.ts +0 -46
- package/types/src/webapi/models/github-ci.model.d.ts +0 -9
- package/types/src/webapi/models/main-source-file.model.d.ts +0 -54
- package/types/src/webapi/models/production-dockerfile.model.d.ts +0 -18
- package/types/src/webapi/models/sample-files.model.d.ts +0 -7
- package/types/src/webapi/models/webapi-image.model.d.ts +0 -12
- package/types/src/webapi/postman/hello-openapi.d.ts +0 -19
- package/types/src/webapi/postman/local-view.d.ts +0 -17
- package/types/src/webapi/postman/openapi-to-postman.d.ts +0 -62
- package/types/src/webapi/workspace-readme.d.ts +0 -18
- package/types/src/webapi.action.d.ts +0 -14
- package/types/src/webapi.command.d.ts +0 -11
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
function _export(target, all) {
|
|
6
|
-
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
_export(exports, {
|
|
12
|
-
get WEBAPI_PROJECT_DIR () {
|
|
13
|
-
return _const1.WEBAPI_PROJECT_DIR;
|
|
14
|
-
},
|
|
15
|
-
get WEBAPI_RELEASE_ENTRY () {
|
|
16
|
-
return _const1.WEBAPI_RELEASE_ENTRY;
|
|
17
|
-
},
|
|
18
|
-
get scaffoldApi () {
|
|
19
|
-
return scaffoldApi;
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
const _nodefs = require("node:fs");
|
|
23
|
-
const _nodepath = require("node:path");
|
|
24
|
-
const _composemodel = require("../models/compose.model.js");
|
|
25
|
-
const _configyamlmodel = require("../models/config-yaml.model.js");
|
|
26
|
-
const _const = require("../models/const.js");
|
|
27
|
-
const _devcontainermodel = require("../models/dev-container.model.js");
|
|
28
|
-
const _dockerimagemodel = require("../models/docker-image.model.js");
|
|
29
|
-
const _envfilemodel = require("../models/env-file.model.js");
|
|
30
|
-
const _gitignoremodel = require("../models/gitignore.model.js");
|
|
31
|
-
const _launchjsonmodel = require("../models/launch-json.model.js");
|
|
32
|
-
const _packagejsonmodel = require("../models/package-json.model.js");
|
|
33
|
-
const _projectmodel = require("../models/project.model.js");
|
|
34
|
-
const _tsconfigmodel = require("../models/tsconfig.model.js");
|
|
35
|
-
const _vitestconfigmodel = require("../models/vitest-config.model.js");
|
|
36
|
-
const _vscodesettingsmodel = require("../models/vscode-settings.model.js");
|
|
37
|
-
const _scaffoldservice = require("../services/scaffold.service.js");
|
|
38
|
-
const _apiname = require("./api-name.js");
|
|
39
|
-
const _const1 = require("./const.js");
|
|
40
|
-
const _hostscripts = require("./devcontainer/host-scripts.js");
|
|
41
|
-
const _authfeature = require("./features/auth.feature.js");
|
|
42
|
-
const _databasefeature = require("./features/database.feature.js");
|
|
43
|
-
const _finalizefeature = require("./features/finalize.feature.js");
|
|
44
|
-
const _postmanfeature = require("./features/postman.feature.js");
|
|
45
|
-
const _apipackagejsonmodel = require("./models/api-package-json.model.js");
|
|
46
|
-
const _controllersourcefilemodel = require("./models/controller-source-file.model.js");
|
|
47
|
-
const _githubcimodel = require("./models/github-ci.model.js");
|
|
48
|
-
const _mainsourcefilemodel = require("./models/main-source-file.model.js");
|
|
49
|
-
const _productiondockerfilemodel = require("./models/production-dockerfile.model.js");
|
|
50
|
-
const _samplefilesmodel = require("./models/sample-files.model.js");
|
|
51
|
-
const _webapiimagemodel = require("./models/webapi-image.model.js");
|
|
52
|
-
const features = [
|
|
53
|
-
_databasefeature.DatabaseFeature,
|
|
54
|
-
_authfeature.AuthFeature,
|
|
55
|
-
_postmanfeature.PostmanFeature,
|
|
56
|
-
_finalizefeature.FinalizeFeature
|
|
57
|
-
];
|
|
58
|
-
async function scaffoldApi(cliOptions) {
|
|
59
|
-
const targetDir = (0, _nodepath.resolve)(cliOptions.d ?? ".");
|
|
60
|
-
const projectName = cliOptions.projectName?.trim() || process.env.DECOHERE_PROJECT_NAME?.trim() || (0, _nodepath.basename)(targetDir);
|
|
61
|
-
const names = (0, _apiname.parseApiNames)(cliOptions.names);
|
|
62
|
-
const workspace = cliOptions.add ? createAddWorkspace(targetDir, projectName, names) : createWorkspace(targetDir, projectName, names);
|
|
63
|
-
await _scaffoldservice.ScaffoldService.scaffold(workspace, {
|
|
64
|
-
...cliOptions,
|
|
65
|
-
names
|
|
66
|
-
}, features);
|
|
67
|
-
}
|
|
68
|
-
function createWorkspace(targetDir, projectName, apiNames) {
|
|
69
|
-
const monoRepo = new _projectmodel.MonoRepoScaffold();
|
|
70
|
-
monoRepo.targetDir = targetDir;
|
|
71
|
-
monoRepo.setName(projectName);
|
|
72
|
-
const name = monoRepo.name;
|
|
73
|
-
// Project-named root so Cursor Agents (and other tools) label the workspace by name.
|
|
74
|
-
const workspaceRoot = `/${name}`;
|
|
75
|
-
const compose = new _composemodel.DockerCompose().setProjectName(name).addHeaderComment("Merge .cursor/mcp.json in the service command. postStartCommand runs after Cursor's first MCP snapshot.").addNetwork(name, {
|
|
76
|
-
name: `samples-${name}`
|
|
77
|
-
}).addService("devcontainer", {
|
|
78
|
-
build: ".",
|
|
79
|
-
volumes: [
|
|
80
|
-
// Repo bind in Compose (survives CLI recreates; Cursor-only mounts do not).
|
|
81
|
-
`..:${workspaceRoot}`,
|
|
82
|
-
// Workspace-local (created by initialize.sh as the host user).
|
|
83
|
-
// Do NOT bind ${HOME}/.npm/... — Docker creates missing host paths as root.
|
|
84
|
-
"./npm-auth:/home/node/.npm-config",
|
|
85
|
-
"./gh-auth:/home/node/.config/gh",
|
|
86
|
-
`webapi-node-modules:${workspaceRoot}/node_modules`,
|
|
87
|
-
// Named volume (not a Cursor-only mount) so CLI recreates keep Up-arrow history.
|
|
88
|
-
`${_dockerimagemodel.commandHistory.volumeName}:${_dockerimagemodel.commandHistory.dir}`
|
|
89
|
-
],
|
|
90
|
-
env_file: [
|
|
91
|
-
"./gh.env"
|
|
92
|
-
],
|
|
93
|
-
environment: {
|
|
94
|
-
NPM_CONFIG_USERCONFIG: "/home/node/.npm-config/.npmrc"
|
|
95
|
-
},
|
|
96
|
-
command: `'bash -c "CODEBASE_RAG_WORKSPACE=${workspaceRoot} node --experimental-strip-types ${workspaceRoot}/.devcontainer/codebase-rag-mcp.ts merge || true && exec sleep infinity"'`,
|
|
97
|
-
networks: [
|
|
98
|
-
name
|
|
99
|
-
]
|
|
100
|
-
}).addVolume("webapi-node-modules").addVolume(_dockerimagemodel.commandHistory.volumeName);
|
|
101
|
-
const installCmd = "bash .devcontainer/post-create.sh";
|
|
102
|
-
const devContainer = new _devcontainermodel.DevContainer().setWorkspaceFolder(workspaceRoot).addExtension("biomejs.biome", "vitest.explorer").setInitializeCommand("bash .devcontainer/initialize.sh").setPostCreateCommand(installCmd).setUpdateContentCommand(installCmd).setPostStartCommand("bash .devcontainer/post-start.sh").useCompose();
|
|
103
|
-
forwardApiPorts(devContainer, apiNames, 0);
|
|
104
|
-
// Workspace-level models (repo root)
|
|
105
|
-
monoRepo.addModel(compose);
|
|
106
|
-
monoRepo.addModel(devContainer);
|
|
107
|
-
const appDevImage = new _webapiimagemodel.WebapiDevContainer();
|
|
108
|
-
appDevImage.addLayer((0, _dockerimagemodel.withWorkspaceNodeModulesOwnership)({
|
|
109
|
-
workspaceDir: workspaceRoot
|
|
110
|
-
}));
|
|
111
|
-
monoRepo.addModel(appDevImage);
|
|
112
|
-
monoRepo.addModel(new _productiondockerfilemodel.WebapiProductionDockerfile(apiNames));
|
|
113
|
-
monoRepo.addModel(new _githubcimodel.GithubCiWorkflows());
|
|
114
|
-
monoRepo.addModel(new _vscodesettingsmodel.VSCodeSettings(name));
|
|
115
|
-
monoRepo.addModel(new _launchjsonmodel.LaunchJson(apiNames));
|
|
116
|
-
monoRepo.addModel(new _tsconfigmodel.TsConfig());
|
|
117
|
-
monoRepo.addModel(new _vitestconfigmodel.VitestConfig());
|
|
118
|
-
monoRepo.addModel(new _packagejsonmodel.PackageJson(`${name}.api`, {
|
|
119
|
-
apiNames,
|
|
120
|
-
workspaceName: name
|
|
121
|
-
}));
|
|
122
|
-
monoRepo.addModel(new _configyamlmodel.ConfigYaml(_const.WELL_KNOWN_FILES.CONFIG_YAML, "config/config.yaml", ""));
|
|
123
|
-
monoRepo.addModel(new _configyamlmodel.ConfigYaml(_const.WELL_KNOWN_FILES.CONFIG_DEV_YAML, "config/config.dev.yaml", ""));
|
|
124
|
-
monoRepo.addModel(new _gitignoremodel.Gitignore());
|
|
125
|
-
monoRepo.addModel(new _envfilemodel.EnvFile());
|
|
126
|
-
monoRepo.addFile(new _hostscripts.DevContainerHostScripts());
|
|
127
|
-
// Biome formatter/linter config
|
|
128
|
-
monoRepo.addFile({
|
|
129
|
-
files: ()=>[
|
|
130
|
-
{
|
|
131
|
-
filePath: "biome.json",
|
|
132
|
-
content: JSON.stringify({
|
|
133
|
-
$schema: "https://biomejs.dev/schemas/2.0.0/schema.json",
|
|
134
|
-
files: {
|
|
135
|
-
includes: [
|
|
136
|
-
"**/*.ts",
|
|
137
|
-
"**/*.js",
|
|
138
|
-
"**/*.json",
|
|
139
|
-
"**/*.yml",
|
|
140
|
-
"**/*.yaml"
|
|
141
|
-
]
|
|
142
|
-
},
|
|
143
|
-
assist: {
|
|
144
|
-
actions: {
|
|
145
|
-
source: {
|
|
146
|
-
organizeImports: "on"
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
},
|
|
150
|
-
vcs: {
|
|
151
|
-
enabled: true,
|
|
152
|
-
clientKind: "git",
|
|
153
|
-
useIgnoreFile: true
|
|
154
|
-
},
|
|
155
|
-
formatter: {
|
|
156
|
-
enabled: true,
|
|
157
|
-
formatWithErrors: true,
|
|
158
|
-
indentStyle: "tab",
|
|
159
|
-
lineWidth: 95
|
|
160
|
-
},
|
|
161
|
-
javascript: {
|
|
162
|
-
parser: {
|
|
163
|
-
unsafeParameterDecoratorsEnabled: true
|
|
164
|
-
}
|
|
165
|
-
},
|
|
166
|
-
linter: {
|
|
167
|
-
rules: {
|
|
168
|
-
style: {
|
|
169
|
-
useConsistentMemberAccessibility: {
|
|
170
|
-
level: "error",
|
|
171
|
-
options: {
|
|
172
|
-
accessibility: "explicit"
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
},
|
|
178
|
-
overrides: [
|
|
179
|
-
{
|
|
180
|
-
includes: [
|
|
181
|
-
"**/*.json"
|
|
182
|
-
],
|
|
183
|
-
formatter: {
|
|
184
|
-
indentStyle: "space",
|
|
185
|
-
indentWidth: 2
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
]
|
|
189
|
-
}, null, 2)
|
|
190
|
-
}
|
|
191
|
-
]
|
|
192
|
-
});
|
|
193
|
-
for (const apiName of apiNames){
|
|
194
|
-
addApiProject(monoRepo, name, apiName);
|
|
195
|
-
}
|
|
196
|
-
return monoRepo;
|
|
197
|
-
}
|
|
198
|
-
function createAddWorkspace(targetDir, projectName, apiNames) {
|
|
199
|
-
if (!(0, _apiname.isDecohereWorkspace)(targetDir)) {
|
|
200
|
-
throw new _apiname.CreateCliError(`Not a Decohere workspace: ${targetDir}. Scaffold one first with \`npx @decohere/create webapi\`.`);
|
|
201
|
-
}
|
|
202
|
-
const existing = (0, _apiname.listExistingApiNames)(targetDir);
|
|
203
|
-
for (const apiName of apiNames){
|
|
204
|
-
if (existing.includes(apiName)) {
|
|
205
|
-
throw new _apiname.CreateCliError(`API "${apiName}" already exists at ${(0, _const1.webapiProjectDir)(apiName)}.`);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
const monoRepo = new _projectmodel.MonoRepoScaffold();
|
|
209
|
-
monoRepo.targetDir = targetDir;
|
|
210
|
-
monoRepo.setName(projectName);
|
|
211
|
-
const name = monoRepo.name;
|
|
212
|
-
const pkg = _packagejsonmodel.PackageJson.fromFile((0, _nodepath.join)(targetDir, "package.json"));
|
|
213
|
-
monoRepo.addModel(pkg);
|
|
214
|
-
monoRepo.addModel((0, _nodefs.existsSync)((0, _nodepath.join)(targetDir, ".env")) ? _envfilemodel.EnvFile.fromFile((0, _nodepath.join)(targetDir, ".env")) : new _envfilemodel.EnvFile());
|
|
215
|
-
monoRepo.addModel((0, _nodefs.existsSync)((0, _nodepath.join)(targetDir, "config/config.yaml")) ? _configyamlmodel.ConfigYaml.fromFile(_const.WELL_KNOWN_FILES.CONFIG_YAML, "config/config.yaml", (0, _nodepath.join)(targetDir, "config/config.yaml")) : new _configyamlmodel.ConfigYaml(_const.WELL_KNOWN_FILES.CONFIG_YAML, "config/config.yaml", ""));
|
|
216
|
-
monoRepo.addModel((0, _nodefs.existsSync)((0, _nodepath.join)(targetDir, "config/config.dev.yaml")) ? _configyamlmodel.ConfigYaml.fromFile(_const.WELL_KNOWN_FILES.CONFIG_DEV_YAML, "config/config.dev.yaml", (0, _nodepath.join)(targetDir, "config/config.dev.yaml")) : new _configyamlmodel.ConfigYaml(_const.WELL_KNOWN_FILES.CONFIG_DEV_YAML, "config/config.dev.yaml", ""));
|
|
217
|
-
// Load the workspace files features merge into, so e.g. --database on a workspace
|
|
218
|
-
// created without one adds the Postgres service instead of only the db:* scripts.
|
|
219
|
-
const compose = loadIfExists(targetDir, ".devcontainer/docker-compose.yml", (path)=>_composemodel.DockerCompose.fromFile(path));
|
|
220
|
-
if (compose) monoRepo.addModel(compose);
|
|
221
|
-
const devContainer = loadIfExists(targetDir, ".devcontainer/devcontainer.json", (path)=>_devcontainermodel.DevContainer.fromFile(path));
|
|
222
|
-
if (devContainer) {
|
|
223
|
-
forwardApiPorts(devContainer, apiNames, existing.length);
|
|
224
|
-
monoRepo.addModel(devContainer);
|
|
225
|
-
}
|
|
226
|
-
const devImage = loadIfExists(targetDir, ".devcontainer/Dockerfile", (path)=>_dockerimagemodel.DockerfileModel.fromFile(path, ".devcontainer/Dockerfile"));
|
|
227
|
-
if (devImage) monoRepo.addModel(devImage);
|
|
228
|
-
const gitignore = loadIfExists(targetDir, ".gitignore", (path)=>_gitignoremodel.Gitignore.fromFile(path));
|
|
229
|
-
if (gitignore) monoRepo.addModel(gitignore);
|
|
230
|
-
if (!pkg.hasScript("package")) {
|
|
231
|
-
pkg.addScript("package", "pnpm run build && forge package");
|
|
232
|
-
}
|
|
233
|
-
for (const [offset, apiName] of apiNames.entries()){
|
|
234
|
-
const port = (0, _const1.webapiPort)(existing.length + offset);
|
|
235
|
-
pkg.addScript(`start:${apiName}`, `node ${(0, _const1.webapiReleaseEntry)(apiName)}`);
|
|
236
|
-
pkg.addScript(`package:${apiName}`, (0, _packagejsonmodel.packageScript)(name, apiName));
|
|
237
|
-
pkg.addScript(`dev:${apiName}`, `PORT=${port} flux serve --env-file-if-exists .env --project ${(0, _const1.webapiPackageName)(name, apiName)}`);
|
|
238
|
-
addApiProject(monoRepo, name, apiName);
|
|
239
|
-
}
|
|
240
|
-
monoRepo.addModel(new _productiondockerfilemodel.WebapiProductionDockerfile(apiNames));
|
|
241
|
-
return monoRepo;
|
|
242
|
-
}
|
|
243
|
-
function addApiProject(monoRepo, workspaceName, apiName) {
|
|
244
|
-
const apiProject = new _projectmodel.ProjectScaffold((0, _const1.webapiProjectDir)(apiName));
|
|
245
|
-
apiProject.addModel(new _apipackagejsonmodel.ApiPackageJson(workspaceName, apiName));
|
|
246
|
-
apiProject.addModel(new _mainsourcefilemodel.MainSourceFile(`${workspaceName}.${apiName}`));
|
|
247
|
-
apiProject.addModel(new _controllersourcefilemodel.ControllerSourceFile());
|
|
248
|
-
apiProject.addFile(new _samplefilesmodel.SampleConfigModel());
|
|
249
|
-
apiProject.addFile(new _samplefilesmodel.SampleServiceModel());
|
|
250
|
-
monoRepo.addProject(apiProject);
|
|
251
|
-
}
|
|
252
|
-
function forwardApiPorts(devContainer, apiNames, firstIndex) {
|
|
253
|
-
for (const [offset, apiName] of apiNames.entries()){
|
|
254
|
-
const port = (0, _const1.webapiPort)(firstIndex + offset);
|
|
255
|
-
devContainer.forwardPort(port);
|
|
256
|
-
devContainer.setPortAttributes(port, {
|
|
257
|
-
label: apiName === _const1.DEFAULT_WEBAPI_NAME ? "API" : apiName,
|
|
258
|
-
requireLocalPort: true
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
function loadIfExists(targetDir, relativePath, load) {
|
|
263
|
-
const absolutePath = (0, _nodepath.join)(targetDir, relativePath);
|
|
264
|
-
return (0, _nodefs.existsSync)(absolutePath) ? load(absolutePath) : undefined;
|
|
265
|
-
}
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
Object.defineProperty(exports, "codebaseRagMcp", {
|
|
6
|
-
enumerable: true,
|
|
7
|
-
get: function() {
|
|
8
|
-
return codebaseRagMcp;
|
|
9
|
-
}
|
|
10
|
-
});
|
|
11
|
-
const _nodefs = require("node:fs");
|
|
12
|
-
const _nodepath = require("node:path");
|
|
13
|
-
const _nodeurl = require("node:url");
|
|
14
|
-
function isRecord(value) {
|
|
15
|
-
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
16
|
-
}
|
|
17
|
-
function loadDotenv(path, env) {
|
|
18
|
-
let raw;
|
|
19
|
-
try {
|
|
20
|
-
raw = (0, _nodefs.readFileSync)(path, "utf8");
|
|
21
|
-
} catch {
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
for (const line of raw.split(/\r?\n/)){
|
|
25
|
-
const trimmed = line.trim();
|
|
26
|
-
if (!trimmed || trimmed.startsWith("#") || !trimmed.includes("=")) continue;
|
|
27
|
-
const eq = trimmed.indexOf("=");
|
|
28
|
-
const key = trimmed.slice(0, eq).trim();
|
|
29
|
-
const value = trimmed.slice(eq + 1).trim().replace(/^["']|["']$/g, "");
|
|
30
|
-
if (key && env[key] === undefined) env[key] = value;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function seedFromMcpJson(raw) {
|
|
34
|
-
let data;
|
|
35
|
-
try {
|
|
36
|
-
data = JSON.parse(raw);
|
|
37
|
-
} catch {
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
if (!isRecord(data)) return null;
|
|
41
|
-
const servers = data.mcpServers;
|
|
42
|
-
if (!isRecord(servers)) return null;
|
|
43
|
-
const server = servers["codebase-rag"];
|
|
44
|
-
if (!isRecord(server)) return null;
|
|
45
|
-
const url = typeof server.url === "string" ? server.url.trim() : "";
|
|
46
|
-
const headers = isRecord(server.headers) ? server.headers : {};
|
|
47
|
-
const auth = typeof headers.Authorization === "string" ? headers.Authorization.trim() : "";
|
|
48
|
-
const token = auth.toLowerCase().startsWith("bearer ") ? auth.slice(7).trim() : "";
|
|
49
|
-
if (!url.startsWith("http") || token.length === 0) return null;
|
|
50
|
-
return {
|
|
51
|
-
url,
|
|
52
|
-
token
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
function mergeIntoMcpJson(input) {
|
|
56
|
-
const { mcpPath, url, token, hostRoot } = input;
|
|
57
|
-
if (!url || !token) {
|
|
58
|
-
return {
|
|
59
|
-
skipped: "no URL/token"
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
const xRoot = hostRoot || "${workspaceFolder}";
|
|
63
|
-
(0, _nodefs.mkdirSync)((0, _nodepath.dirname)(mcpPath), {
|
|
64
|
-
recursive: true
|
|
65
|
-
});
|
|
66
|
-
let data = {
|
|
67
|
-
mcpServers: {}
|
|
68
|
-
};
|
|
69
|
-
try {
|
|
70
|
-
if ((0, _nodefs.statSync)(mcpPath).size > 0) {
|
|
71
|
-
const loaded = JSON.parse((0, _nodefs.readFileSync)(mcpPath, "utf8"));
|
|
72
|
-
if (isRecord(loaded)) data = loaded;
|
|
73
|
-
}
|
|
74
|
-
} catch (err) {
|
|
75
|
-
const code = isRecord(err) && typeof err.code === "string" ? err.code : "";
|
|
76
|
-
if (code !== "ENOENT") {
|
|
77
|
-
console.log("codebase-rag MCP: existing mcp.json is invalid JSON; replacing rag entry only after backup");
|
|
78
|
-
(0, _nodefs.renameSync)(mcpPath, `${mcpPath}.bak`);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
const servers = isRecord(data.mcpServers) ? data.mcpServers : {};
|
|
82
|
-
data.mcpServers = servers;
|
|
83
|
-
servers["codebase-rag"] = {
|
|
84
|
-
url,
|
|
85
|
-
headers: {
|
|
86
|
-
Authorization: `Bearer ${token}`,
|
|
87
|
-
"X-Codebase-Root": xRoot
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
(0, _nodefs.writeFileSync)(mcpPath, `${JSON.stringify(data, null, 2)}\n`, "utf8");
|
|
91
|
-
try {
|
|
92
|
-
(0, _nodefs.chmodSync)(mcpPath, 0o600);
|
|
93
|
-
} catch {
|
|
94
|
-
// memfs and some hosts omit chmod
|
|
95
|
-
}
|
|
96
|
-
return {
|
|
97
|
-
path: mcpPath,
|
|
98
|
-
root: xRoot
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
function workspaceRoot(env = process.env) {
|
|
102
|
-
const fromEnv = env.CODEBASE_RAG_WORKSPACE?.trim();
|
|
103
|
-
if (fromEnv) return fromEnv;
|
|
104
|
-
// Scaffolded copy lives at <repo>/.devcontainer/codebase-rag-mcp.ts
|
|
105
|
-
return (0, _nodepath.dirname)((0, _nodepath.dirname)((0, _nodeurl.fileURLToPath)(require("url").pathToFileURL(__filename).toString())));
|
|
106
|
-
}
|
|
107
|
-
function mergeFromEnv(env = process.env) {
|
|
108
|
-
const root = workspaceRoot(env);
|
|
109
|
-
const cursorDir = (0, _nodepath.join)(root, ".cursor");
|
|
110
|
-
loadDotenv((0, _nodepath.join)(cursorDir, "codebase-rag.env"), env);
|
|
111
|
-
const url = (env.CODEBASE_RAG_MCP_URL ?? "").trim();
|
|
112
|
-
const token = (env.CODEBASE_RAG_MCP_TOKEN ?? "").trim();
|
|
113
|
-
const hostRoot = (env.CODEBASE_RAG_MCP_ROOT ?? "").trim() || root;
|
|
114
|
-
const result = mergeIntoMcpJson({
|
|
115
|
-
mcpPath: (0, _nodepath.join)(cursorDir, "mcp.json"),
|
|
116
|
-
url,
|
|
117
|
-
token,
|
|
118
|
-
hostRoot
|
|
119
|
-
});
|
|
120
|
-
if (result.skipped != null) {
|
|
121
|
-
console.log(`codebase-rag MCP: skipped (${result.skipped})`);
|
|
122
|
-
return 0;
|
|
123
|
-
}
|
|
124
|
-
console.log(`codebase-rag MCP: wrote ${result.path} url=${url} root=${result.root}`);
|
|
125
|
-
return 0;
|
|
126
|
-
}
|
|
127
|
-
function seedPrint(mcpPath) {
|
|
128
|
-
let raw;
|
|
129
|
-
try {
|
|
130
|
-
raw = (0, _nodefs.readFileSync)(mcpPath, "utf8");
|
|
131
|
-
} catch {
|
|
132
|
-
return 1;
|
|
133
|
-
}
|
|
134
|
-
const creds = seedFromMcpJson(raw);
|
|
135
|
-
if (creds == null) return 1;
|
|
136
|
-
console.log(creds.url);
|
|
137
|
-
console.log(creds.token);
|
|
138
|
-
return 0;
|
|
139
|
-
}
|
|
140
|
-
function main(argv = process.argv.slice(2)) {
|
|
141
|
-
const command = argv[0] ?? "merge";
|
|
142
|
-
if (command === "seed-print") {
|
|
143
|
-
const mcpPath = argv[1];
|
|
144
|
-
if (mcpPath == null || mcpPath.length === 0) return 1;
|
|
145
|
-
return seedPrint(mcpPath);
|
|
146
|
-
}
|
|
147
|
-
if (command === "merge") {
|
|
148
|
-
return mergeFromEnv();
|
|
149
|
-
}
|
|
150
|
-
console.error(`codebase-rag MCP: unknown command ${command}`);
|
|
151
|
-
return 1;
|
|
152
|
-
}
|
|
153
|
-
const invoked = (process.argv[1] ?? "").replaceAll("\\", "/");
|
|
154
|
-
if (invoked.endsWith("/codebase-rag-mcp.ts") || invoked.endsWith("/codebase-rag-mcp.js")) {
|
|
155
|
-
process.exit(main());
|
|
156
|
-
}
|
|
157
|
-
const codebaseRagMcp = {
|
|
158
|
-
loadDotenv,
|
|
159
|
-
seedFromMcpJson,
|
|
160
|
-
mergeIntoMcpJson,
|
|
161
|
-
mergeFromEnv,
|
|
162
|
-
seedPrint,
|
|
163
|
-
main
|
|
164
|
-
};
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
chmodSync,
|
|
3
|
-
mkdirSync,
|
|
4
|
-
readFileSync,
|
|
5
|
-
renameSync,
|
|
6
|
-
statSync,
|
|
7
|
-
writeFileSync,
|
|
8
|
-
} from "node:fs";
|
|
9
|
-
import { dirname, join } from "node:path";
|
|
10
|
-
import { fileURLToPath } from "node:url";
|
|
11
|
-
|
|
12
|
-
export type CodebaseRagCredentials = {
|
|
13
|
-
url: string;
|
|
14
|
-
token: string;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export type McpJson = {
|
|
18
|
-
mcpServers?: Record<string, unknown>;
|
|
19
|
-
[key: string]: unknown;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
23
|
-
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function loadDotenv(path: string, env: NodeJS.ProcessEnv): void {
|
|
27
|
-
let raw: string;
|
|
28
|
-
try {
|
|
29
|
-
raw = readFileSync(path, "utf8");
|
|
30
|
-
} catch {
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
for (const line of raw.split(/\r?\n/)) {
|
|
34
|
-
const trimmed = line.trim();
|
|
35
|
-
if (!trimmed || trimmed.startsWith("#") || !trimmed.includes("=")) continue;
|
|
36
|
-
const eq = trimmed.indexOf("=");
|
|
37
|
-
const key = trimmed.slice(0, eq).trim();
|
|
38
|
-
const value = trimmed
|
|
39
|
-
.slice(eq + 1)
|
|
40
|
-
.trim()
|
|
41
|
-
.replace(/^["']|["']$/g, "");
|
|
42
|
-
if (key && env[key] === undefined) env[key] = value;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function seedFromMcpJson(raw: string): CodebaseRagCredentials | null {
|
|
47
|
-
let data: unknown;
|
|
48
|
-
try {
|
|
49
|
-
data = JSON.parse(raw);
|
|
50
|
-
} catch {
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
if (!isRecord(data)) return null;
|
|
54
|
-
const servers = data.mcpServers;
|
|
55
|
-
if (!isRecord(servers)) return null;
|
|
56
|
-
const server = servers["codebase-rag"];
|
|
57
|
-
if (!isRecord(server)) return null;
|
|
58
|
-
const url = typeof server.url === "string" ? server.url.trim() : "";
|
|
59
|
-
const headers = isRecord(server.headers) ? server.headers : {};
|
|
60
|
-
const auth = typeof headers.Authorization === "string" ? headers.Authorization.trim() : "";
|
|
61
|
-
const token = auth.toLowerCase().startsWith("bearer ") ? auth.slice(7).trim() : "";
|
|
62
|
-
if (!url.startsWith("http") || token.length === 0) return null;
|
|
63
|
-
return { url, token };
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function mergeIntoMcpJson(input: {
|
|
67
|
-
mcpPath: string;
|
|
68
|
-
url: string;
|
|
69
|
-
token: string;
|
|
70
|
-
hostRoot: string;
|
|
71
|
-
}): { skipped?: string; path?: string; root?: string } {
|
|
72
|
-
const { mcpPath, url, token, hostRoot } = input;
|
|
73
|
-
if (!url || !token) {
|
|
74
|
-
return { skipped: "no URL/token" };
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const xRoot = hostRoot || "${workspaceFolder}";
|
|
78
|
-
mkdirSync(dirname(mcpPath), { recursive: true });
|
|
79
|
-
|
|
80
|
-
let data: McpJson = { mcpServers: {} };
|
|
81
|
-
try {
|
|
82
|
-
if (statSync(mcpPath).size > 0) {
|
|
83
|
-
const loaded: unknown = JSON.parse(readFileSync(mcpPath, "utf8"));
|
|
84
|
-
if (isRecord(loaded)) data = loaded as McpJson;
|
|
85
|
-
}
|
|
86
|
-
} catch (err) {
|
|
87
|
-
const code = isRecord(err) && typeof err.code === "string" ? err.code : "";
|
|
88
|
-
if (code !== "ENOENT") {
|
|
89
|
-
console.log(
|
|
90
|
-
"codebase-rag MCP: existing mcp.json is invalid JSON; replacing rag entry only after backup",
|
|
91
|
-
);
|
|
92
|
-
renameSync(mcpPath, `${mcpPath}.bak`);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const servers = isRecord(data.mcpServers) ? data.mcpServers : {};
|
|
97
|
-
data.mcpServers = servers;
|
|
98
|
-
servers["codebase-rag"] = {
|
|
99
|
-
url,
|
|
100
|
-
headers: {
|
|
101
|
-
Authorization: `Bearer ${token}`,
|
|
102
|
-
"X-Codebase-Root": xRoot,
|
|
103
|
-
},
|
|
104
|
-
};
|
|
105
|
-
writeFileSync(mcpPath, `${JSON.stringify(data, null, 2)}\n`, "utf8");
|
|
106
|
-
try {
|
|
107
|
-
chmodSync(mcpPath, 0o600);
|
|
108
|
-
} catch {
|
|
109
|
-
// memfs and some hosts omit chmod
|
|
110
|
-
}
|
|
111
|
-
return { path: mcpPath, root: xRoot };
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function workspaceRoot(env: NodeJS.ProcessEnv = process.env): string {
|
|
115
|
-
const fromEnv = env.CODEBASE_RAG_WORKSPACE?.trim();
|
|
116
|
-
if (fromEnv) return fromEnv;
|
|
117
|
-
// Scaffolded copy lives at <repo>/.devcontainer/codebase-rag-mcp.ts
|
|
118
|
-
return dirname(dirname(fileURLToPath(import.meta.url)));
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function mergeFromEnv(env: NodeJS.ProcessEnv = process.env): number {
|
|
122
|
-
const root = workspaceRoot(env);
|
|
123
|
-
const cursorDir = join(root, ".cursor");
|
|
124
|
-
loadDotenv(join(cursorDir, "codebase-rag.env"), env);
|
|
125
|
-
const url = (env.CODEBASE_RAG_MCP_URL ?? "").trim();
|
|
126
|
-
const token = (env.CODEBASE_RAG_MCP_TOKEN ?? "").trim();
|
|
127
|
-
const hostRoot = (env.CODEBASE_RAG_MCP_ROOT ?? "").trim() || root;
|
|
128
|
-
const result = mergeIntoMcpJson({
|
|
129
|
-
mcpPath: join(cursorDir, "mcp.json"),
|
|
130
|
-
url,
|
|
131
|
-
token,
|
|
132
|
-
hostRoot,
|
|
133
|
-
});
|
|
134
|
-
if (result.skipped != null) {
|
|
135
|
-
console.log(`codebase-rag MCP: skipped (${result.skipped})`);
|
|
136
|
-
return 0;
|
|
137
|
-
}
|
|
138
|
-
console.log(`codebase-rag MCP: wrote ${result.path} url=${url} root=${result.root}`);
|
|
139
|
-
return 0;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function seedPrint(mcpPath: string): number {
|
|
143
|
-
let raw: string;
|
|
144
|
-
try {
|
|
145
|
-
raw = readFileSync(mcpPath, "utf8");
|
|
146
|
-
} catch {
|
|
147
|
-
return 1;
|
|
148
|
-
}
|
|
149
|
-
const creds = seedFromMcpJson(raw);
|
|
150
|
-
if (creds == null) return 1;
|
|
151
|
-
console.log(creds.url);
|
|
152
|
-
console.log(creds.token);
|
|
153
|
-
return 0;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function main(argv = process.argv.slice(2)): number {
|
|
157
|
-
const command = argv[0] ?? "merge";
|
|
158
|
-
if (command === "seed-print") {
|
|
159
|
-
const mcpPath = argv[1];
|
|
160
|
-
if (mcpPath == null || mcpPath.length === 0) return 1;
|
|
161
|
-
return seedPrint(mcpPath);
|
|
162
|
-
}
|
|
163
|
-
if (command === "merge") {
|
|
164
|
-
return mergeFromEnv();
|
|
165
|
-
}
|
|
166
|
-
console.error(`codebase-rag MCP: unknown command ${command}`);
|
|
167
|
-
return 1;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const invoked = (process.argv[1] ?? "").replaceAll("\\", "/");
|
|
171
|
-
if (invoked.endsWith("/codebase-rag-mcp.ts") || invoked.endsWith("/codebase-rag-mcp.js")) {
|
|
172
|
-
process.exit(main());
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
export const codebaseRagMcp = {
|
|
176
|
-
loadDotenv,
|
|
177
|
-
seedFromMcpJson,
|
|
178
|
-
mergeIntoMcpJson,
|
|
179
|
-
mergeFromEnv,
|
|
180
|
-
seedPrint,
|
|
181
|
-
main,
|
|
182
|
-
};
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
function _export(target, all) {
|
|
6
|
-
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
_export(exports, {
|
|
12
|
-
get DevContainerHostScripts () {
|
|
13
|
-
return DevContainerHostScripts;
|
|
14
|
-
},
|
|
15
|
-
get codebaseRagMcpSourcePath () {
|
|
16
|
-
return codebaseRagMcpSourcePath;
|
|
17
|
-
},
|
|
18
|
-
get devcontainerTemplatePath () {
|
|
19
|
-
return devcontainerTemplatePath;
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
const _nodefs = require("node:fs");
|
|
23
|
-
const _nodeurl = require("node:url");
|
|
24
|
-
const TEMPLATE_FILES = [
|
|
25
|
-
"initialize.sh",
|
|
26
|
-
"post-create.sh",
|
|
27
|
-
"post-start.sh",
|
|
28
|
-
"tty-prompt.sh",
|
|
29
|
-
"codebase-rag.env.example"
|
|
30
|
-
];
|
|
31
|
-
function devcontainerTemplatePath(name) {
|
|
32
|
-
return (0, _nodeurl.fileURLToPath)(new URL(`./templates/${name}`, require("url").pathToFileURL(__filename).toString()));
|
|
33
|
-
}
|
|
34
|
-
function codebaseRagMcpSourcePath() {
|
|
35
|
-
return (0, _nodeurl.fileURLToPath)(new URL("./codebase-rag-mcp.ts", require("url").pathToFileURL(__filename).toString()));
|
|
36
|
-
}
|
|
37
|
-
class DevContainerHostScripts {
|
|
38
|
-
files() {
|
|
39
|
-
return [
|
|
40
|
-
...TEMPLATE_FILES.map((name)=>({
|
|
41
|
-
filePath: `.devcontainer/${name}`,
|
|
42
|
-
content: (0, _nodefs.readFileSync)(devcontainerTemplatePath(name), "utf8")
|
|
43
|
-
})),
|
|
44
|
-
{
|
|
45
|
-
filePath: ".devcontainer/codebase-rag-mcp.ts",
|
|
46
|
-
content: (0, _nodefs.readFileSync)(codebaseRagMcpSourcePath(), "utf8")
|
|
47
|
-
}
|
|
48
|
-
];
|
|
49
|
-
}
|
|
50
|
-
}
|