frontmcp 0.12.2 → 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +6 -5
- package/src/commands/build/bundler.js +1 -1
- package/src/commands/build/bundler.js.map +1 -1
- package/src/commands/build/exec/cli-runtime/cli-bundler.d.ts +17 -0
- package/src/commands/build/exec/cli-runtime/cli-bundler.js +75 -0
- package/src/commands/build/exec/cli-runtime/cli-bundler.js.map +1 -0
- package/src/commands/build/exec/cli-runtime/credential-store.d.ts +22 -0
- package/src/commands/build/exec/cli-runtime/credential-store.js +140 -0
- package/src/commands/build/exec/cli-runtime/credential-store.js.map +1 -0
- package/src/commands/build/exec/cli-runtime/daemon-client.d.ts +16 -0
- package/src/commands/build/exec/cli-runtime/daemon-client.js +169 -0
- package/src/commands/build/exec/cli-runtime/daemon-client.js.map +1 -0
- package/src/commands/build/exec/cli-runtime/generate-cli-entry.d.ts +37 -0
- package/src/commands/build/exec/cli-runtime/generate-cli-entry.js +1287 -0
- package/src/commands/build/exec/cli-runtime/generate-cli-entry.js.map +1 -0
- package/src/commands/build/exec/cli-runtime/index.d.ts +9 -0
- package/src/commands/build/exec/cli-runtime/index.js +32 -0
- package/src/commands/build/exec/cli-runtime/index.js.map +1 -0
- package/src/commands/build/exec/cli-runtime/oauth-helper.d.ts +9 -0
- package/src/commands/build/exec/cli-runtime/oauth-helper.js +224 -0
- package/src/commands/build/exec/cli-runtime/oauth-helper.js.map +1 -0
- package/src/commands/build/exec/cli-runtime/output-formatter.d.ts +46 -0
- package/src/commands/build/exec/cli-runtime/output-formatter.js +168 -0
- package/src/commands/build/exec/cli-runtime/output-formatter.js.map +1 -0
- package/src/commands/build/exec/cli-runtime/schema-extractor.d.ts +57 -0
- package/src/commands/build/exec/cli-runtime/schema-extractor.js +129 -0
- package/src/commands/build/exec/cli-runtime/schema-extractor.js.map +1 -0
- package/src/commands/build/exec/cli-runtime/schema-to-commander.d.ts +38 -0
- package/src/commands/build/exec/cli-runtime/schema-to-commander.js +172 -0
- package/src/commands/build/exec/cli-runtime/schema-to-commander.js.map +1 -0
- package/src/commands/build/exec/cli-runtime/session-manager.d.ts +16 -0
- package/src/commands/build/exec/cli-runtime/session-manager.js +122 -0
- package/src/commands/build/exec/cli-runtime/session-manager.js.map +1 -0
- package/src/commands/build/exec/config.d.ts +25 -0
- package/src/commands/build/exec/config.js +0 -1
- package/src/commands/build/exec/config.js.map +1 -1
- package/src/commands/build/exec/esbuild-bundler.d.ts +4 -1
- package/src/commands/build/exec/esbuild-bundler.js +28 -9
- package/src/commands/build/exec/esbuild-bundler.js.map +1 -1
- package/src/commands/build/exec/index.d.ts +7 -2
- package/src/commands/build/exec/index.js +159 -9
- package/src/commands/build/exec/index.js.map +1 -1
- package/src/commands/build/exec/manifest.d.ts +14 -0
- package/src/commands/build/exec/manifest.js.map +1 -1
- package/src/commands/build/exec/runner-script.d.ts +1 -1
- package/src/commands/build/exec/runner-script.js +48 -5
- package/src/commands/build/exec/runner-script.js.map +1 -1
- package/src/commands/build/exec/sea-builder.d.ts +18 -0
- package/src/commands/build/exec/sea-builder.js +81 -0
- package/src/commands/build/exec/sea-builder.js.map +1 -0
- package/src/commands/build/exec/setup.js +0 -2
- package/src/commands/build/exec/setup.js.map +1 -1
- package/src/commands/build/index.d.ts +1 -1
- package/src/commands/build/index.js +3 -3
- package/src/commands/build/index.js.map +1 -1
- package/src/commands/build/register.d.ts +2 -0
- package/src/commands/build/register.js +21 -0
- package/src/commands/build/register.js.map +1 -0
- package/src/commands/{dev.d.ts → dev/dev.d.ts} +1 -1
- package/src/commands/{dev.js → dev/dev.js} +3 -3
- package/src/commands/dev/dev.js.map +1 -0
- package/src/commands/{doctor.js → dev/doctor.js} +5 -4
- package/src/commands/dev/doctor.js.map +1 -0
- package/src/commands/{inspector.js → dev/inspector.js} +1 -1
- package/src/commands/dev/inspector.js.map +1 -0
- package/src/commands/dev/register.d.ts +2 -0
- package/src/commands/dev/register.js +49 -0
- package/src/commands/dev/register.js.map +1 -0
- package/src/commands/{test.d.ts → dev/test.d.ts} +1 -1
- package/src/commands/{test.js → dev/test.js} +5 -5
- package/src/commands/dev/test.js.map +1 -0
- package/src/commands/{configure.d.ts → package/configure.d.ts} +1 -1
- package/src/commands/{configure.js → package/configure.js} +3 -3
- package/src/commands/package/configure.js.map +1 -0
- package/src/commands/package/esm-update.d.ts +19 -0
- package/src/commands/package/esm-update.js +93 -0
- package/src/commands/package/esm-update.js.map +1 -0
- package/src/commands/{install/index.d.ts → package/install.d.ts} +1 -1
- package/src/commands/{install/index.js → package/install.js} +8 -5
- package/src/commands/package/install.js.map +1 -0
- package/src/commands/{install → package}/questionnaire.js +2 -2
- package/src/commands/{install → package}/questionnaire.js.map +1 -1
- package/src/commands/package/register.d.ts +2 -0
- package/src/commands/package/register.js +35 -0
- package/src/commands/package/register.js.map +1 -0
- package/src/commands/{install → package}/registry.js +8 -6
- package/src/commands/package/registry.js.map +1 -0
- package/src/commands/{install → package}/sources/git.js +8 -1
- package/src/commands/package/sources/git.js.map +1 -0
- package/src/commands/{install → package}/sources/local.js.map +1 -1
- package/src/commands/{install → package}/sources/npm.js.map +1 -1
- package/src/commands/{install → package}/types.d.ts +7 -1
- package/src/commands/{install → package}/types.js +4 -0
- package/src/commands/package/types.js.map +1 -0
- package/src/commands/{uninstall.d.ts → package/uninstall.d.ts} +1 -1
- package/src/commands/{uninstall.js → package/uninstall.js} +2 -2
- package/src/commands/package/uninstall.js.map +1 -0
- package/src/{pm/pm.format.d.ts → commands/pm/format.d.ts} +1 -1
- package/src/{pm/pm.format.js → commands/pm/format.js} +2 -2
- package/src/commands/pm/format.js.map +1 -0
- package/src/{pm/pm.health.js → commands/pm/health.js} +1 -1
- package/src/commands/pm/health.js.map +1 -0
- package/src/commands/pm/index.d.ts +9 -0
- package/src/{pm → commands/pm}/index.js +32 -32
- package/src/commands/pm/index.js.map +1 -0
- package/src/commands/{list.d.ts → pm/list.d.ts} +1 -1
- package/src/commands/{list.js → pm/list.js} +3 -3
- package/src/commands/pm/list.js.map +1 -0
- package/src/{pm/pm.logs.js → commands/pm/log-utils.js} +9 -9
- package/src/commands/pm/log-utils.js.map +1 -0
- package/src/commands/{logs.d.ts → pm/logs.d.ts} +1 -1
- package/src/commands/{logs.js → pm/logs.js} +6 -6
- package/src/commands/pm/logs.js.map +1 -0
- package/src/{pm/pm.manager.d.ts → commands/pm/manager.d.ts} +1 -1
- package/src/{pm/pm.manager.js → commands/pm/manager.js} +21 -21
- package/src/commands/pm/manager.js.map +1 -0
- package/src/{pm/pm.paths.d.ts → commands/pm/paths.d.ts} +1 -0
- package/src/{pm/pm.paths.js → commands/pm/paths.js} +2 -1
- package/src/commands/pm/paths.js.map +1 -0
- package/src/{pm/pm.pidfile.d.ts → commands/pm/pidfile.d.ts} +1 -1
- package/src/{pm/pm.pidfile.js → commands/pm/pidfile.js} +8 -8
- package/src/commands/pm/pidfile.js.map +1 -0
- package/src/commands/pm/register.d.ts +2 -0
- package/src/commands/pm/register.js +83 -0
- package/src/commands/pm/register.js.map +1 -0
- package/src/commands/{restart.d.ts → pm/restart.d.ts} +1 -1
- package/src/commands/{restart.js → pm/restart.js} +4 -4
- package/src/commands/pm/restart.js.map +1 -0
- package/src/{pm/pm.service.d.ts → commands/pm/service-gen.d.ts} +1 -1
- package/src/{pm/pm.service.js → commands/pm/service-gen.js} +5 -5
- package/src/commands/pm/service-gen.js.map +1 -0
- package/src/commands/{service.d.ts → pm/service.d.ts} +1 -1
- package/src/commands/{service.js → pm/service.js} +6 -6
- package/src/commands/pm/service.js.map +1 -0
- package/src/commands/{socket.d.ts → pm/socket.d.ts} +1 -1
- package/src/commands/{socket.js → pm/socket.js} +3 -3
- package/src/commands/pm/socket.js.map +1 -0
- package/src/{pm/pm.spawn.d.ts → commands/pm/spawn.d.ts} +1 -1
- package/src/{pm/pm.spawn.js → commands/pm/spawn.js} +15 -15
- package/src/commands/pm/spawn.js.map +1 -0
- package/src/commands/{start.d.ts → pm/start.d.ts} +1 -1
- package/src/commands/{start.js → pm/start.js} +6 -6
- package/src/commands/pm/start.js.map +1 -0
- package/src/commands/{status.d.ts → pm/status.d.ts} +1 -1
- package/src/commands/{status.js → pm/status.js} +5 -5
- package/src/commands/pm/status.js.map +1 -0
- package/src/commands/{stop.d.ts → pm/stop.d.ts} +1 -1
- package/src/commands/{stop.js → pm/stop.js} +3 -3
- package/src/commands/pm/stop.js.map +1 -0
- package/src/{pm/pm.types.js → commands/pm/types.js} +1 -1
- package/src/commands/pm/types.js.map +1 -0
- package/src/commands/{create.js → scaffold/create.js} +91 -20
- package/src/commands/scaffold/create.js.map +1 -0
- package/src/commands/scaffold/register.d.ts +2 -0
- package/src/commands/scaffold/register.js +28 -0
- package/src/commands/scaffold/register.js.map +1 -0
- package/src/{args.d.ts → core/args.d.ts} +7 -1
- package/src/{args.js → core/args.js} +8 -0
- package/src/core/args.js.map +1 -0
- package/src/core/bridge.d.ts +9 -0
- package/src/core/bridge.js +75 -0
- package/src/core/bridge.js.map +1 -0
- package/src/core/cli.d.ts +8 -0
- package/src/core/cli.js +23 -0
- package/src/core/cli.js.map +1 -0
- package/src/core/colors.js.map +1 -0
- package/src/core/help.d.ts +7 -0
- package/src/core/help.js +83 -0
- package/src/core/help.js.map +1 -0
- package/src/core/index.d.ts +7 -0
- package/src/core/index.js +22 -0
- package/src/core/index.js.map +1 -0
- package/src/core/program.d.ts +2 -0
- package/src/core/program.js +23 -0
- package/src/core/program.js.map +1 -0
- package/src/core/tsconfig.js.map +1 -0
- package/src/{version.js → core/version.js} +1 -1
- package/src/core/version.js.map +1 -0
- package/src/index.d.ts +1 -1
- package/src/index.js +2 -5
- package/src/index.js.map +1 -1
- package/src/{utils → shared}/env.js +2 -2
- package/src/shared/env.js.map +1 -0
- package/src/{utils → shared}/fs.js +2 -2
- package/src/shared/fs.js.map +1 -0
- package/src/shared/index.d.ts +3 -0
- package/src/shared/index.js +14 -0
- package/src/shared/index.js.map +1 -0
- package/src/shared/prompts.js.map +1 -0
- package/src/args.js.map +0 -1
- package/src/cli.d.ts +0 -5
- package/src/cli.js +0 -241
- package/src/cli.js.map +0 -1
- package/src/colors.js.map +0 -1
- package/src/commands/configure.js.map +0 -1
- package/src/commands/create.js.map +0 -1
- package/src/commands/dev.js.map +0 -1
- package/src/commands/doctor.js.map +0 -1
- package/src/commands/inspector.js.map +0 -1
- package/src/commands/install/index.js.map +0 -1
- package/src/commands/install/registry.js.map +0 -1
- package/src/commands/install/sources/git.js.map +0 -1
- package/src/commands/install/types.js.map +0 -1
- package/src/commands/list.js.map +0 -1
- package/src/commands/logs.js.map +0 -1
- package/src/commands/restart.js.map +0 -1
- package/src/commands/service.js.map +0 -1
- package/src/commands/socket.js.map +0 -1
- package/src/commands/start.js.map +0 -1
- package/src/commands/status.js.map +0 -1
- package/src/commands/stop.js.map +0 -1
- package/src/commands/template.d.ts +0 -13
- package/src/commands/template.js +0 -193
- package/src/commands/template.js.map +0 -1
- package/src/commands/test.js.map +0 -1
- package/src/commands/uninstall.js.map +0 -1
- package/src/pm/index.d.ts +0 -9
- package/src/pm/index.js.map +0 -1
- package/src/pm/pm.format.js.map +0 -1
- package/src/pm/pm.health.js.map +0 -1
- package/src/pm/pm.logs.js.map +0 -1
- package/src/pm/pm.manager.js.map +0 -1
- package/src/pm/pm.paths.js.map +0 -1
- package/src/pm/pm.pidfile.js.map +0 -1
- package/src/pm/pm.service.js.map +0 -1
- package/src/pm/pm.spawn.js.map +0 -1
- package/src/pm/pm.types.js.map +0 -1
- package/src/templates/3rd-party-integration/src/http-client.d.ts +0 -20
- package/src/templates/3rd-party-integration/src/http-client.js +0 -105
- package/src/templates/3rd-party-integration/src/http-client.js.map +0 -1
- package/src/templates/3rd-party-integration/src/mcp-http-types.d.ts +0 -63
- package/src/templates/3rd-party-integration/src/mcp-http-types.js +0 -52
- package/src/templates/3rd-party-integration/src/mcp-http-types.js.map +0 -1
- package/src/templates/3rd-party-integration/src/tools/example.list.d.ts +0 -45
- package/src/templates/3rd-party-integration/src/tools/example.list.js +0 -85
- package/src/templates/3rd-party-integration/src/tools/example.list.js.map +0 -1
- package/src/tsconfig.js.map +0 -1
- package/src/utils/env.js.map +0 -1
- package/src/utils/fs.js.map +0 -1
- package/src/utils/prompts.js.map +0 -1
- package/src/version.js.map +0 -1
- /package/src/commands/{doctor.d.ts → dev/doctor.d.ts} +0 -0
- /package/src/commands/{inspector.d.ts → dev/inspector.d.ts} +0 -0
- /package/src/commands/{install → package}/questionnaire.d.ts +0 -0
- /package/src/commands/{install → package}/registry.d.ts +0 -0
- /package/src/commands/{install → package}/sources/git.d.ts +0 -0
- /package/src/commands/{install → package}/sources/local.d.ts +0 -0
- /package/src/commands/{install → package}/sources/local.js +0 -0
- /package/src/commands/{install → package}/sources/npm.d.ts +0 -0
- /package/src/commands/{install → package}/sources/npm.js +0 -0
- /package/src/{pm/pm.health.d.ts → commands/pm/health.d.ts} +0 -0
- /package/src/{pm/pm.logs.d.ts → commands/pm/log-utils.d.ts} +0 -0
- /package/src/{pm/pm.types.d.ts → commands/pm/types.d.ts} +0 -0
- /package/src/commands/{create.d.ts → scaffold/create.d.ts} +0 -0
- /package/src/{colors.d.ts → core/colors.d.ts} +0 -0
- /package/src/{colors.js → core/colors.js} +0 -0
- /package/src/{tsconfig.d.ts → core/tsconfig.d.ts} +0 -0
- /package/src/{tsconfig.js → core/tsconfig.js} +0 -0
- /package/src/{version.d.ts → core/version.d.ts} +0 -0
- /package/src/{utils → shared}/env.d.ts +0 -0
- /package/src/{utils → shared}/fs.d.ts +0 -0
- /package/src/{utils → shared}/prompts.d.ts +0 -0
- /package/src/{utils → shared}/prompts.js +0 -0
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
[](https://github.com/agentfront/frontmcp/blob/main/LICENSE)
|
|
15
15
|
[](https://snyk.io/test/github/agentfront/frontmcp)
|
|
16
16
|
|
|
17
|
-
[Docs][docs-home] • [Quickstart][docs-quickstart] • [API Reference][docs-sdk-ref] • [Discord](https://discord.gg/
|
|
17
|
+
[Docs][docs-home] • [Quickstart][docs-quickstart] • [API Reference][docs-sdk-ref] • [Discord](https://discord.gg/53AHnJnmwR)
|
|
18
18
|
|
|
19
19
|
</div>
|
|
20
20
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "frontmcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-beta.2",
|
|
4
4
|
"description": "FrontMCP command line interface",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"homepage": "https://docs.agentfront.dev",
|
|
@@ -23,14 +23,15 @@
|
|
|
23
23
|
},
|
|
24
24
|
"main": "./src/index.js",
|
|
25
25
|
"bin": {
|
|
26
|
-
"frontmcp": "./src/cli.js"
|
|
26
|
+
"frontmcp": "./src/core/cli.js"
|
|
27
27
|
},
|
|
28
28
|
"engines": {
|
|
29
29
|
"node": ">=22.0.0"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@clack/prompts": "^0.10.0",
|
|
33
|
-
"@frontmcp/utils": "0.
|
|
33
|
+
"@frontmcp/utils": "1.0.0-beta.2",
|
|
34
|
+
"commander": "^13.0.0",
|
|
34
35
|
"tslib": "^2.3.0",
|
|
35
36
|
"@rspack/core": "^1.7.6",
|
|
36
37
|
"esbuild": "^0.27.3"
|
|
@@ -39,8 +40,8 @@
|
|
|
39
40
|
"typescript": "^5.5.3",
|
|
40
41
|
"tsx": "^4.20.6",
|
|
41
42
|
"@types/node": "^24.0.0",
|
|
42
|
-
"@modelcontextprotocol/inspector": "^0.
|
|
43
|
+
"@modelcontextprotocol/inspector": "^0.21.1"
|
|
43
44
|
},
|
|
44
|
-
"types": "./
|
|
45
|
+
"types": "./index.d.js",
|
|
45
46
|
"type": "commonjs"
|
|
46
47
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.bundleForServerless = bundleForServerless;
|
|
4
4
|
const core_1 = require("@rspack/core");
|
|
5
|
-
const colors_1 = require("../../colors");
|
|
5
|
+
const colors_1 = require("../../core/colors");
|
|
6
6
|
/**
|
|
7
7
|
* Bundle the serverless entry point into a single CJS file using rspack.
|
|
8
8
|
* This resolves ESM/CJS compatibility issues and dynamic import problems.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundler.js","sourceRoot":"","sources":["../../../../src/commands/build/bundler.ts"],"names":[],"mappings":";;AAWA,kDAoFC;AA/FD,uCAAsC;AACtC,
|
|
1
|
+
{"version":3,"file":"bundler.js","sourceRoot":"","sources":["../../../../src/commands/build/bundler.ts"],"names":[],"mappings":";;AAWA,kDAoFC;AA/FD,uCAAsC;AACtC,8CAAsC;AAEtC;;;;;;;GAOG;AACI,KAAK,UAAU,mBAAmB,CACvC,SAAiB,EACjB,MAAc,EACd,cAAsB;IAEtB,MAAM,QAAQ,GAAG,IAAA,aAAM,EAAC;QACtB,IAAI,EAAE,YAAY;QAClB,MAAM,EAAE,MAAM;QACd,KAAK,EAAE,SAAS;QAChB,MAAM,EAAE;YACN,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,cAAc;YACxB,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;YAC9B,KAAK,EAAE,KAAK;SACb;QACD,iDAAiD;QACjD,gBAAgB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;QAChC,oFAAoF;QACpF,SAAS,EAAE;YACT,WAAW,EAAE,WAAW;YACxB,QAAQ,EAAE,UAAU;YACpB,OAAO,EAAE,SAAS;YAClB,wDAAwD;YACxD,KAAK,EAAE,OAAO;YACd,WAAW,EAAE,WAAW;YACxB,kBAAkB,EAAE,kBAAkB;YACtC,mBAAmB,EAAE,mBAAmB;SACzC;QACD,OAAO,EAAE;YACP,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC;YAC5C,gGAAgG;YAChG,cAAc,EAAE,KAAK;SACtB;QACD,MAAM,EAAE;YACN,KAAK,EAAE,EAAE;YACT,MAAM,EAAE;gBACN,UAAU,EAAE;oBACV,sEAAsE;oBACtE,iDAAiD;oBACjD,iBAAiB,EAAE,OAAO;oBAC1B,mBAAmB,EAAE,KAAK;oBAC1B,sBAAsB,EAAE,KAAK;iBAC9B;aACF;SACF;QACD,uDAAuD;QACvD,YAAY,EAAE;YACZ,QAAQ,EAAE,KAAK;SAChB;QACD,wEAAwE;QACxE,cAAc,EAAE;YACd,+EAA+E;YAC/E,mEAAmE;YACnE,8EAA8E;YAC9E,gDAAgD;SACjD;QACD,0BAA0B;QAC1B,KAAK,EAAE,iBAAiB;KACzB,CAAC,CAAC;IAEH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YAC1B,IAAI,GAAG,EAAE,CAAC;gBACR,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;YACrB,CAAC;YACD,IAAI,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC;gBACvB,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC5B,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC;gBACvF,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,aAAa,EAAE,CAAC,CAAC,CAAC;YAC/D,CAAC;YACD,IAAI,KAAK,EAAE,WAAW,EAAE,EAAE,CAAC;gBACzB,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC5B,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;oBAC3B,OAAO,CAAC,GAAG,CAAC,IAAA,UAAC,EAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBACtD,CAAC,CAAC,CAAC;YACL,CAAC;YACD,QAAQ,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,EAAE;gBAC1B,IAAI,QAAQ,EAAE,CAAC;oBACb,OAAO,CAAC,GAAG,CAAC,IAAA,UAAC,EAAC,QAAQ,EAAE,+BAA+B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBAC9E,CAAC;gBACD,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { rspack } from '@rspack/core';\nimport { c } from '../../core/colors';\n\n/**\n * Bundle the serverless entry point into a single CJS file using rspack.\n * This resolves ESM/CJS compatibility issues and dynamic import problems.\n *\n * @param entryPath - Absolute path to the entry file (e.g., dist/index.js)\n * @param outDir - Output directory for the bundled file\n * @param outputFilename - Name of the output bundle (e.g., 'handler.cjs')\n */\nexport async function bundleForServerless(\n entryPath: string,\n outDir: string,\n outputFilename: string,\n): Promise<void> {\n const compiler = rspack({\n mode: 'production',\n target: 'node',\n entry: entryPath,\n output: {\n path: outDir,\n filename: outputFilename,\n library: { type: 'commonjs2' },\n clean: false,\n },\n // Use node externals preset for built-in modules\n externalsPresets: { node: true },\n // Exclude problematic optional dependencies (native binaries that can't be bundled)\n externals: {\n '@swc/core': '@swc/core',\n fsevents: 'fsevents',\n esbuild: 'esbuild',\n // React is optional - only needed for MDX/JSX rendering\n react: 'react',\n 'react-dom': 'react-dom',\n 'react-dom/server': 'react-dom/server',\n 'react/jsx-runtime': 'react/jsx-runtime',\n },\n resolve: {\n extensions: ['.js', '.mjs', '.cjs', '.json'],\n // Allow imports without file extensions (TypeScript compiles without .js but ESM requires them)\n fullySpecified: false,\n },\n module: {\n rules: [],\n parser: {\n javascript: {\n // Handle dynamic requires like require('@vercel/kv') inside functions\n // by wrapping them instead of externalizing them\n dynamicImportMode: 'eager',\n exprContextCritical: false,\n unknownContextCritical: false,\n },\n },\n },\n // Don't minimize to preserve readability for debugging\n optimization: {\n minimize: false,\n },\n // Suppress known third-party library warnings that don't affect runtime\n ignoreWarnings: [\n // Express view engine dynamic require - expected behavior, harmless at runtime\n /Critical dependency: the request of a dependency is an expression/,\n // Handlebars require.extensions - deprecated Node.js API but works at runtime\n /require\\.extensions is not supported by Rspack/,\n ],\n // Suppress verbose output\n stats: 'errors-warnings',\n });\n\n return new Promise((resolve, reject) => {\n compiler.run((err, stats) => {\n if (err) {\n return reject(err);\n }\n if (stats?.hasErrors()) {\n const info = stats.toJson();\n const errorMessages = info.errors?.map((e) => e.message).join('\\n') || 'Unknown error';\n return reject(new Error(`Bundle failed:\\n${errorMessages}`));\n }\n if (stats?.hasWarnings()) {\n const info = stats.toJson();\n info.warnings?.forEach((w) => {\n console.log(c('yellow', ` Warning: ${w.message}`));\n });\n }\n compiler.close((closeErr) => {\n if (closeErr) {\n console.log(c('yellow', ` Warning closing compiler: ${closeErr.message}`));\n }\n resolve();\n });\n });\n });\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* esbuild configuration for the CLI bundle.
|
|
3
|
+
* Bundles the generated CLI entry point with commander.js inlined.
|
|
4
|
+
*/
|
|
5
|
+
import { FrontmcpExecConfig } from '../config';
|
|
6
|
+
export interface CliBundleResult {
|
|
7
|
+
bundlePath: string;
|
|
8
|
+
bundleSize: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Bundle the generated CLI entry with esbuild.
|
|
12
|
+
* Commander.js and runtime modules are inlined; the server bundle is external
|
|
13
|
+
* unless selfContained mode is enabled (for SEA builds).
|
|
14
|
+
*/
|
|
15
|
+
export declare function bundleCliWithEsbuild(cliEntryPath: string, outDir: string, config: FrontmcpExecConfig, options?: {
|
|
16
|
+
selfContained?: boolean;
|
|
17
|
+
}): Promise<CliBundleResult>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* esbuild configuration for the CLI bundle.
|
|
4
|
+
* Bundles the generated CLI entry point with commander.js inlined.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.bundleCliWithEsbuild = bundleCliWithEsbuild;
|
|
8
|
+
const tslib_1 = require("tslib");
|
|
9
|
+
const path = tslib_1.__importStar(require("path"));
|
|
10
|
+
/**
|
|
11
|
+
* Bundle the generated CLI entry with esbuild.
|
|
12
|
+
* Commander.js and runtime modules are inlined; the server bundle is external
|
|
13
|
+
* unless selfContained mode is enabled (for SEA builds).
|
|
14
|
+
*/
|
|
15
|
+
async function bundleCliWithEsbuild(cliEntryPath, outDir, config, options) {
|
|
16
|
+
let esbuild;
|
|
17
|
+
try {
|
|
18
|
+
esbuild = require('esbuild');
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
throw new Error('esbuild is required for CLI builds. Install it: npm install -D esbuild');
|
|
22
|
+
}
|
|
23
|
+
const cliBundleName = `${config.name}-cli.bundle.js`;
|
|
24
|
+
const bundlePath = path.join(outDir, cliBundleName);
|
|
25
|
+
const selfContained = options?.selfContained ?? false;
|
|
26
|
+
// The server bundle is loaded via require() at runtime — keep external
|
|
27
|
+
// unless selfContained mode where everything is inlined for SEA
|
|
28
|
+
const serverBundleName = `${config.name}.bundle.js`;
|
|
29
|
+
const external = selfContained
|
|
30
|
+
? [
|
|
31
|
+
// Only true native addons and optional peer deps stay external in self-contained mode
|
|
32
|
+
'better-sqlite3',
|
|
33
|
+
'fsevents',
|
|
34
|
+
'@vercel/kv',
|
|
35
|
+
'@frontmcp/storage-sqlite',
|
|
36
|
+
'@enclave-vm/core',
|
|
37
|
+
...(config.dependencies?.nativeAddons || []),
|
|
38
|
+
]
|
|
39
|
+
: [
|
|
40
|
+
`./${serverBundleName}`,
|
|
41
|
+
'@frontmcp/sdk',
|
|
42
|
+
'better-sqlite3',
|
|
43
|
+
'fsevents',
|
|
44
|
+
'@vercel/kv',
|
|
45
|
+
'@frontmcp/storage-sqlite',
|
|
46
|
+
'@enclave-vm/core',
|
|
47
|
+
...(config.dependencies?.nativeAddons || []),
|
|
48
|
+
...(config.esbuild?.external || []),
|
|
49
|
+
];
|
|
50
|
+
await esbuild.build({
|
|
51
|
+
entryPoints: [cliEntryPath],
|
|
52
|
+
bundle: true,
|
|
53
|
+
platform: 'node',
|
|
54
|
+
format: 'cjs',
|
|
55
|
+
target: config.esbuild?.target || 'node22',
|
|
56
|
+
outfile: bundlePath,
|
|
57
|
+
external,
|
|
58
|
+
keepNames: true,
|
|
59
|
+
treeShaking: true,
|
|
60
|
+
minify: config.esbuild?.minify ?? false,
|
|
61
|
+
banner: {
|
|
62
|
+
js: '#!/usr/bin/env node',
|
|
63
|
+
},
|
|
64
|
+
define: config.esbuild?.define,
|
|
65
|
+
sourcemap: false,
|
|
66
|
+
logLevel: 'warning',
|
|
67
|
+
});
|
|
68
|
+
const fs = require('fs');
|
|
69
|
+
const stat = fs.statSync(bundlePath);
|
|
70
|
+
return {
|
|
71
|
+
bundlePath,
|
|
72
|
+
bundleSize: stat.size,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=cli-bundler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-bundler.js","sourceRoot":"","sources":["../../../../../../src/commands/build/exec/cli-runtime/cli-bundler.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAeH,oDAuEC;;AApFD,mDAA6B;AAQ7B;;;;GAIG;AACI,KAAK,UAAU,oBAAoB,CACxC,YAAoB,EACpB,MAAc,EACd,MAA0B,EAC1B,OAAqC;IAErC,IAAI,OAAiC,CAAC;IACtC,IAAI,CAAC;QACH,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,wEAAwE,CACzE,CAAC;IACJ,CAAC;IAED,MAAM,aAAa,GAAG,GAAG,MAAM,CAAC,IAAI,gBAAgB,CAAC;IACrD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACpD,MAAM,aAAa,GAAG,OAAO,EAAE,aAAa,IAAI,KAAK,CAAC;IAEtD,uEAAuE;IACvE,gEAAgE;IAChE,MAAM,gBAAgB,GAAG,GAAG,MAAM,CAAC,IAAI,YAAY,CAAC;IAEpD,MAAM,QAAQ,GAAG,aAAa;QAC5B,CAAC,CAAC;YACE,sFAAsF;YACtF,gBAAgB;YAChB,UAAU;YACV,YAAY;YACZ,0BAA0B;YAC1B,kBAAkB;YAClB,GAAG,CAAC,MAAM,CAAC,YAAY,EAAE,YAAY,IAAI,EAAE,CAAC;SAC7C;QACH,CAAC,CAAC;YACE,KAAK,gBAAgB,EAAE;YACvB,eAAe;YACf,gBAAgB;YAChB,UAAU;YACV,YAAY;YACZ,0BAA0B;YAC1B,kBAAkB;YAClB,GAAG,CAAC,MAAM,CAAC,YAAY,EAAE,YAAY,IAAI,EAAE,CAAC;YAC5C,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,IAAI,EAAE,CAAC;SACpC,CAAC;IAEN,MAAM,OAAO,CAAC,KAAK,CAAC;QAClB,WAAW,EAAE,CAAC,YAAY,CAAC;QAC3B,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,MAAM;QAChB,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,QAAQ;QAC1C,OAAO,EAAE,UAAU;QACnB,QAAQ;QACR,SAAS,EAAE,IAAI;QACf,WAAW,EAAE,IAAI;QACjB,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,KAAK;QACvC,MAAM,EAAE;YACN,EAAE,EAAE,qBAAqB;SAC1B;QACD,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM;QAC9B,SAAS,EAAE,KAAK;QAChB,QAAQ,EAAE,SAAS;KACpB,CAAC,CAAC;IAEH,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAErC,OAAO;QACL,UAAU;QACV,UAAU,EAAE,IAAI,CAAC,IAAI;KACtB,CAAC;AACJ,CAAC","sourcesContent":["/**\n * esbuild configuration for the CLI bundle.\n * Bundles the generated CLI entry point with commander.js inlined.\n */\n\nimport * as path from 'path';\nimport { FrontmcpExecConfig } from '../config';\n\nexport interface CliBundleResult {\n bundlePath: string;\n bundleSize: number;\n}\n\n/**\n * Bundle the generated CLI entry with esbuild.\n * Commander.js and runtime modules are inlined; the server bundle is external\n * unless selfContained mode is enabled (for SEA builds).\n */\nexport async function bundleCliWithEsbuild(\n cliEntryPath: string,\n outDir: string,\n config: FrontmcpExecConfig,\n options?: { selfContained?: boolean },\n): Promise<CliBundleResult> {\n let esbuild: typeof import('esbuild');\n try {\n esbuild = require('esbuild');\n } catch {\n throw new Error(\n 'esbuild is required for CLI builds. Install it: npm install -D esbuild',\n );\n }\n\n const cliBundleName = `${config.name}-cli.bundle.js`;\n const bundlePath = path.join(outDir, cliBundleName);\n const selfContained = options?.selfContained ?? false;\n\n // The server bundle is loaded via require() at runtime — keep external\n // unless selfContained mode where everything is inlined for SEA\n const serverBundleName = `${config.name}.bundle.js`;\n\n const external = selfContained\n ? [\n // Only true native addons and optional peer deps stay external in self-contained mode\n 'better-sqlite3',\n 'fsevents',\n '@vercel/kv',\n '@frontmcp/storage-sqlite',\n '@enclave-vm/core',\n ...(config.dependencies?.nativeAddons || []),\n ]\n : [\n `./${serverBundleName}`,\n '@frontmcp/sdk',\n 'better-sqlite3',\n 'fsevents',\n '@vercel/kv',\n '@frontmcp/storage-sqlite',\n '@enclave-vm/core',\n ...(config.dependencies?.nativeAddons || []),\n ...(config.esbuild?.external || []),\n ];\n\n await esbuild.build({\n entryPoints: [cliEntryPath],\n bundle: true,\n platform: 'node',\n format: 'cjs',\n target: config.esbuild?.target || 'node22',\n outfile: bundlePath,\n external,\n keepNames: true,\n treeShaking: true,\n minify: config.esbuild?.minify ?? false,\n banner: {\n js: '#!/usr/bin/env node',\n },\n define: config.esbuild?.define,\n sourcemap: false,\n logLevel: 'warning',\n });\n\n const fs = require('fs');\n const stat = fs.statSync(bundlePath);\n\n return {\n bundlePath,\n bundleSize: stat.size,\n };\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential store for CLI executables.
|
|
3
|
+
* Generates runtime module code for secure credential storage with
|
|
4
|
+
* platform-aware backends: macOS Keychain, Linux secret-tool, encrypted file fallback.
|
|
5
|
+
*/
|
|
6
|
+
export interface CredentialBlob {
|
|
7
|
+
token: string;
|
|
8
|
+
refreshToken?: string;
|
|
9
|
+
expiresAt?: string;
|
|
10
|
+
user?: string;
|
|
11
|
+
metadata?: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
export interface CredentialStore {
|
|
14
|
+
get(session: string): Promise<CredentialBlob | null>;
|
|
15
|
+
set(session: string, blob: CredentialBlob): Promise<void>;
|
|
16
|
+
delete(session: string): Promise<boolean>;
|
|
17
|
+
list(): Promise<string[]>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Generate the credential-store runtime module source for embedding in CLI bundle.
|
|
21
|
+
*/
|
|
22
|
+
export declare function generateCredentialStoreSource(appName: string): string;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Credential store for CLI executables.
|
|
4
|
+
* Generates runtime module code for secure credential storage with
|
|
5
|
+
* platform-aware backends: macOS Keychain, Linux secret-tool, encrypted file fallback.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.generateCredentialStoreSource = generateCredentialStoreSource;
|
|
9
|
+
/**
|
|
10
|
+
* Generate the credential-store runtime module source for embedding in CLI bundle.
|
|
11
|
+
*/
|
|
12
|
+
function generateCredentialStoreSource(appName) {
|
|
13
|
+
return `
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
var crypto = require('crypto');
|
|
17
|
+
var os = require('os');
|
|
18
|
+
var path = require('path');
|
|
19
|
+
var fs = require('fs');
|
|
20
|
+
var childProcess = require('child_process');
|
|
21
|
+
|
|
22
|
+
var APP_NAME = ${JSON.stringify(appName)};
|
|
23
|
+
var CRED_DIR = path.join(os.homedir(), '.frontmcp', 'apps', APP_NAME, 'credentials');
|
|
24
|
+
|
|
25
|
+
function ensureCredDir() {
|
|
26
|
+
fs.mkdirSync(CRED_DIR, { recursive: true });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function runCmd(cmd, args, input) {
|
|
30
|
+
return new Promise(function(resolve, reject) {
|
|
31
|
+
var proc = childProcess.spawn(cmd, args, { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
32
|
+
var stdout = '';
|
|
33
|
+
var stderr = '';
|
|
34
|
+
proc.stdout.on('data', function(d) { stdout += d; });
|
|
35
|
+
proc.stderr.on('data', function(d) { stderr += d; });
|
|
36
|
+
if (input) { proc.stdin.write(input); proc.stdin.end(); }
|
|
37
|
+
proc.on('close', function(code) {
|
|
38
|
+
if (code === 0) resolve(stdout.trim());
|
|
39
|
+
else reject(new Error(stderr.trim() || 'Command failed: ' + cmd + ' ' + args.join(' ')));
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function deriveKey() {
|
|
45
|
+
var hostname = os.hostname();
|
|
46
|
+
var salt = APP_NAME + ':' + hostname;
|
|
47
|
+
return crypto.createHash('sha256').update(salt).digest();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function encryptBlob(data) {
|
|
51
|
+
var key = deriveKey();
|
|
52
|
+
var iv = crypto.randomBytes(12);
|
|
53
|
+
var cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
|
|
54
|
+
var encrypted = Buffer.concat([cipher.update(JSON.stringify(data), 'utf8'), cipher.final()]);
|
|
55
|
+
var tag = cipher.getAuthTag();
|
|
56
|
+
return Buffer.concat([iv, tag, encrypted]).toString('base64');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function decryptBlob(encoded) {
|
|
60
|
+
var key = deriveKey();
|
|
61
|
+
var buf = Buffer.from(encoded, 'base64');
|
|
62
|
+
var iv = buf.subarray(0, 12);
|
|
63
|
+
var tag = buf.subarray(12, 28);
|
|
64
|
+
var encrypted = buf.subarray(28);
|
|
65
|
+
var decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
|
|
66
|
+
decipher.setAuthTag(tag);
|
|
67
|
+
var decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
|
|
68
|
+
return JSON.parse(decrypted.toString('utf8'));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// macOS Keychain backend
|
|
72
|
+
var KeychainStore = {
|
|
73
|
+
get: async function(session) {
|
|
74
|
+
try {
|
|
75
|
+
var encoded = await runCmd('security', ['find-generic-password', '-s', 'frontmcp.' + APP_NAME, '-a', session, '-w']);
|
|
76
|
+
return decryptBlob(encoded);
|
|
77
|
+
} catch (_) { return null; }
|
|
78
|
+
},
|
|
79
|
+
set: async function(session, blob) {
|
|
80
|
+
var encoded = encryptBlob(blob);
|
|
81
|
+
try { await runCmd('security', ['delete-generic-password', '-s', 'frontmcp.' + APP_NAME, '-a', session]); } catch (_) { /* ok */ }
|
|
82
|
+
await runCmd('security', ['add-generic-password', '-s', 'frontmcp.' + APP_NAME, '-a', session, '-w', encoded, '-U']);
|
|
83
|
+
},
|
|
84
|
+
delete: async function(session) {
|
|
85
|
+
try {
|
|
86
|
+
await runCmd('security', ['delete-generic-password', '-s', 'frontmcp.' + APP_NAME, '-a', session]);
|
|
87
|
+
return true;
|
|
88
|
+
} catch (_) { return false; }
|
|
89
|
+
},
|
|
90
|
+
list: async function() {
|
|
91
|
+
try {
|
|
92
|
+
var out = await runCmd('security', ['dump-keychain']);
|
|
93
|
+
var matches = [];
|
|
94
|
+
var re = new RegExp('"svce"<blob>="frontmcp\\\\.' + APP_NAME.replace(/[.*+?^\${}()|[\\]\\\\]/g, '\\\\$&') + '"[\\\\s\\\\S]*?"acct"<blob>="([^"]*)"', 'g');
|
|
95
|
+
var m; while ((m = re.exec(out)) !== null) { matches.push(m[1]); }
|
|
96
|
+
return [...new Set(matches)];
|
|
97
|
+
} catch (_) { return []; }
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// Encrypted file backend (fallback)
|
|
102
|
+
var FileStore = {
|
|
103
|
+
get: async function(session) {
|
|
104
|
+
var filePath = path.join(CRED_DIR, session + '.enc');
|
|
105
|
+
try {
|
|
106
|
+
var encoded = fs.readFileSync(filePath, 'utf8');
|
|
107
|
+
return decryptBlob(encoded);
|
|
108
|
+
} catch (_) { return null; }
|
|
109
|
+
},
|
|
110
|
+
set: async function(session, blob) {
|
|
111
|
+
ensureCredDir();
|
|
112
|
+
var encoded = encryptBlob(blob);
|
|
113
|
+
var filePath = path.join(CRED_DIR, session + '.enc');
|
|
114
|
+
fs.writeFileSync(filePath, encoded, { mode: 0o600 });
|
|
115
|
+
},
|
|
116
|
+
delete: async function(session) {
|
|
117
|
+
var filePath = path.join(CRED_DIR, session + '.enc');
|
|
118
|
+
try { fs.unlinkSync(filePath); return true; } catch (_) { return false; }
|
|
119
|
+
},
|
|
120
|
+
list: async function() {
|
|
121
|
+
ensureCredDir();
|
|
122
|
+
try {
|
|
123
|
+
return fs.readdirSync(CRED_DIR)
|
|
124
|
+
.filter(function(f) { return f.endsWith('.enc'); })
|
|
125
|
+
.map(function(f) { return f.replace(/\\.enc$/, ''); });
|
|
126
|
+
} catch (_) { return []; }
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
function createCredentialStore() {
|
|
131
|
+
if (process.platform === 'darwin') {
|
|
132
|
+
return KeychainStore;
|
|
133
|
+
}
|
|
134
|
+
return FileStore;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
module.exports = { createCredentialStore, encryptBlob, decryptBlob };
|
|
138
|
+
`.trim();
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=credential-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-store.js","sourceRoot":"","sources":["../../../../../../src/commands/build/exec/cli-runtime/credential-store.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAoBH,sEA+HC;AAlID;;GAEG;AACH,SAAgB,6BAA6B,CAAC,OAAe;IAC3D,OAAO;;;;;;;;;iBASQ,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoHvC,CAAC,IAAI,EAAE,CAAC;AACT,CAAC","sourcesContent":["/**\n * Credential store for CLI executables.\n * Generates runtime module code for secure credential storage with\n * platform-aware backends: macOS Keychain, Linux secret-tool, encrypted file fallback.\n */\n\nexport interface CredentialBlob {\n token: string;\n refreshToken?: string;\n expiresAt?: string;\n user?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface CredentialStore {\n get(session: string): Promise<CredentialBlob | null>;\n set(session: string, blob: CredentialBlob): Promise<void>;\n delete(session: string): Promise<boolean>;\n list(): Promise<string[]>;\n}\n\n/**\n * Generate the credential-store runtime module source for embedding in CLI bundle.\n */\nexport function generateCredentialStoreSource(appName: string): string {\n return `\n'use strict';\n\nvar crypto = require('crypto');\nvar os = require('os');\nvar path = require('path');\nvar fs = require('fs');\nvar childProcess = require('child_process');\n\nvar APP_NAME = ${JSON.stringify(appName)};\nvar CRED_DIR = path.join(os.homedir(), '.frontmcp', 'apps', APP_NAME, 'credentials');\n\nfunction ensureCredDir() {\n fs.mkdirSync(CRED_DIR, { recursive: true });\n}\n\nfunction runCmd(cmd, args, input) {\n return new Promise(function(resolve, reject) {\n var proc = childProcess.spawn(cmd, args, { stdio: ['pipe', 'pipe', 'pipe'] });\n var stdout = '';\n var stderr = '';\n proc.stdout.on('data', function(d) { stdout += d; });\n proc.stderr.on('data', function(d) { stderr += d; });\n if (input) { proc.stdin.write(input); proc.stdin.end(); }\n proc.on('close', function(code) {\n if (code === 0) resolve(stdout.trim());\n else reject(new Error(stderr.trim() || 'Command failed: ' + cmd + ' ' + args.join(' ')));\n });\n });\n}\n\nfunction deriveKey() {\n var hostname = os.hostname();\n var salt = APP_NAME + ':' + hostname;\n return crypto.createHash('sha256').update(salt).digest();\n}\n\nfunction encryptBlob(data) {\n var key = deriveKey();\n var iv = crypto.randomBytes(12);\n var cipher = crypto.createCipheriv('aes-256-gcm', key, iv);\n var encrypted = Buffer.concat([cipher.update(JSON.stringify(data), 'utf8'), cipher.final()]);\n var tag = cipher.getAuthTag();\n return Buffer.concat([iv, tag, encrypted]).toString('base64');\n}\n\nfunction decryptBlob(encoded) {\n var key = deriveKey();\n var buf = Buffer.from(encoded, 'base64');\n var iv = buf.subarray(0, 12);\n var tag = buf.subarray(12, 28);\n var encrypted = buf.subarray(28);\n var decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);\n decipher.setAuthTag(tag);\n var decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);\n return JSON.parse(decrypted.toString('utf8'));\n}\n\n// macOS Keychain backend\nvar KeychainStore = {\n get: async function(session) {\n try {\n var encoded = await runCmd('security', ['find-generic-password', '-s', 'frontmcp.' + APP_NAME, '-a', session, '-w']);\n return decryptBlob(encoded);\n } catch (_) { return null; }\n },\n set: async function(session, blob) {\n var encoded = encryptBlob(blob);\n try { await runCmd('security', ['delete-generic-password', '-s', 'frontmcp.' + APP_NAME, '-a', session]); } catch (_) { /* ok */ }\n await runCmd('security', ['add-generic-password', '-s', 'frontmcp.' + APP_NAME, '-a', session, '-w', encoded, '-U']);\n },\n delete: async function(session) {\n try {\n await runCmd('security', ['delete-generic-password', '-s', 'frontmcp.' + APP_NAME, '-a', session]);\n return true;\n } catch (_) { return false; }\n },\n list: async function() {\n try {\n var out = await runCmd('security', ['dump-keychain']);\n var matches = [];\n var re = new RegExp('\"svce\"<blob>=\"frontmcp\\\\\\\\.' + APP_NAME.replace(/[.*+?^\\${}()|[\\\\]\\\\\\\\]/g, '\\\\\\\\$&') + '\"[\\\\\\\\s\\\\\\\\S]*?\"acct\"<blob>=\"([^\"]*)\"', 'g');\n var m; while ((m = re.exec(out)) !== null) { matches.push(m[1]); }\n return [...new Set(matches)];\n } catch (_) { return []; }\n }\n};\n\n// Encrypted file backend (fallback)\nvar FileStore = {\n get: async function(session) {\n var filePath = path.join(CRED_DIR, session + '.enc');\n try {\n var encoded = fs.readFileSync(filePath, 'utf8');\n return decryptBlob(encoded);\n } catch (_) { return null; }\n },\n set: async function(session, blob) {\n ensureCredDir();\n var encoded = encryptBlob(blob);\n var filePath = path.join(CRED_DIR, session + '.enc');\n fs.writeFileSync(filePath, encoded, { mode: 0o600 });\n },\n delete: async function(session) {\n var filePath = path.join(CRED_DIR, session + '.enc');\n try { fs.unlinkSync(filePath); return true; } catch (_) { return false; }\n },\n list: async function() {\n ensureCredDir();\n try {\n return fs.readdirSync(CRED_DIR)\n .filter(function(f) { return f.endsWith('.enc'); })\n .map(function(f) { return f.replace(/\\\\.enc$/, ''); });\n } catch (_) { return []; }\n }\n};\n\nfunction createCredentialStore() {\n if (process.platform === 'darwin') {\n return KeychainStore;\n }\n return FileStore;\n}\n\nmodule.exports = { createCredentialStore, encryptBlob, decryptBlob };\n`.trim();\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight daemon client for CLI exec.
|
|
3
|
+
*
|
|
4
|
+
* Sends MCP JSON-RPC requests over a Unix socket using Node.js built-in http module.
|
|
5
|
+
* This avoids the full FrontMCP SDK initialization (~420ms) by talking to an
|
|
6
|
+
* already-running daemon process.
|
|
7
|
+
*
|
|
8
|
+
* NOTE: This file is used as a CJS runtime module — it gets bundled into the CLI
|
|
9
|
+
* output by esbuild alongside the generated CLI entry. It must remain free of
|
|
10
|
+
* TypeScript-only constructs at runtime (the .ts extension is for build-time only).
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Generate the daemon-client JavaScript source code (CJS module).
|
|
14
|
+
* This is embedded into the CLI bundle at build time.
|
|
15
|
+
*/
|
|
16
|
+
export declare function generateDaemonClientSource(): string;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Lightweight daemon client for CLI exec.
|
|
4
|
+
*
|
|
5
|
+
* Sends MCP JSON-RPC requests over a Unix socket using Node.js built-in http module.
|
|
6
|
+
* This avoids the full FrontMCP SDK initialization (~420ms) by talking to an
|
|
7
|
+
* already-running daemon process.
|
|
8
|
+
*
|
|
9
|
+
* NOTE: This file is used as a CJS runtime module — it gets bundled into the CLI
|
|
10
|
+
* output by esbuild alongside the generated CLI entry. It must remain free of
|
|
11
|
+
* TypeScript-only constructs at runtime (the .ts extension is for build-time only).
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.generateDaemonClientSource = generateDaemonClientSource;
|
|
15
|
+
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
16
|
+
/**
|
|
17
|
+
* Generate the daemon-client JavaScript source code (CJS module).
|
|
18
|
+
* This is embedded into the CLI bundle at build time.
|
|
19
|
+
*/
|
|
20
|
+
function generateDaemonClientSource() {
|
|
21
|
+
return `'use strict';
|
|
22
|
+
|
|
23
|
+
var http = require('http');
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Send a JSON-RPC request over a Unix socket.
|
|
27
|
+
* @param {string} socketPath - Path to the Unix socket file.
|
|
28
|
+
* @param {string} method - JSON-RPC method name.
|
|
29
|
+
* @param {object} [params] - Method parameters.
|
|
30
|
+
* @returns {Promise<object>} Parsed JSON-RPC result.
|
|
31
|
+
*/
|
|
32
|
+
function rpcCall(socketPath, method, params) {
|
|
33
|
+
return new Promise(function(resolve, reject) {
|
|
34
|
+
var body = JSON.stringify({
|
|
35
|
+
jsonrpc: '2.0',
|
|
36
|
+
id: Date.now(),
|
|
37
|
+
method: method,
|
|
38
|
+
params: params || {}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
var req = http.request({
|
|
42
|
+
socketPath: socketPath,
|
|
43
|
+
path: '/mcp',
|
|
44
|
+
method: 'POST',
|
|
45
|
+
headers: {
|
|
46
|
+
'Content-Type': 'application/json',
|
|
47
|
+
'Content-Length': Buffer.byteLength(body)
|
|
48
|
+
},
|
|
49
|
+
timeout: 10000
|
|
50
|
+
}, function(res) {
|
|
51
|
+
var chunks = [];
|
|
52
|
+
res.on('data', function(chunk) { chunks.push(chunk); });
|
|
53
|
+
res.on('end', function() {
|
|
54
|
+
try {
|
|
55
|
+
var json = JSON.parse(Buffer.concat(chunks).toString());
|
|
56
|
+
if (json.error) {
|
|
57
|
+
var err = new Error(json.error.message || 'RPC error');
|
|
58
|
+
err.code = json.error.code;
|
|
59
|
+
err.data = json.error.data;
|
|
60
|
+
reject(err);
|
|
61
|
+
} else {
|
|
62
|
+
resolve(json.result);
|
|
63
|
+
}
|
|
64
|
+
} catch (e) {
|
|
65
|
+
reject(new Error('Invalid JSON response from daemon'));
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
req.on('error', function(err) {
|
|
71
|
+
reject(err);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
req.on('timeout', function() {
|
|
75
|
+
req.destroy();
|
|
76
|
+
reject(new Error('Daemon request timed out'));
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
req.write(body);
|
|
80
|
+
req.end();
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Create a daemon client that implements the same interface as DirectClient.
|
|
86
|
+
* @param {string} socketPath - Path to the Unix socket file.
|
|
87
|
+
* @returns {object} Client object with MCP methods.
|
|
88
|
+
*/
|
|
89
|
+
function createDaemonClient(socketPath) {
|
|
90
|
+
function call(method, params) {
|
|
91
|
+
return rpcCall(socketPath, method, params);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
ping: function() {
|
|
96
|
+
return call('ping');
|
|
97
|
+
},
|
|
98
|
+
callTool: function(name, args) {
|
|
99
|
+
return call('tools/call', { name: name, arguments: args || {} });
|
|
100
|
+
},
|
|
101
|
+
listTools: function() {
|
|
102
|
+
return call('tools/list');
|
|
103
|
+
},
|
|
104
|
+
listResources: function() {
|
|
105
|
+
return call('resources/list');
|
|
106
|
+
},
|
|
107
|
+
readResource: function(uri) {
|
|
108
|
+
return call('resources/read', { uri: uri });
|
|
109
|
+
},
|
|
110
|
+
listResourceTemplates: function() {
|
|
111
|
+
return call('resources/templates/list');
|
|
112
|
+
},
|
|
113
|
+
listPrompts: function() {
|
|
114
|
+
return call('prompts/list');
|
|
115
|
+
},
|
|
116
|
+
getPrompt: function(name, args) {
|
|
117
|
+
return call('prompts/get', { name: name, arguments: args || {} });
|
|
118
|
+
},
|
|
119
|
+
searchSkills: function(query) {
|
|
120
|
+
return call('skills/search', { query: query || '' });
|
|
121
|
+
},
|
|
122
|
+
loadSkills: function(ids) {
|
|
123
|
+
return call('skills/load', { ids: ids });
|
|
124
|
+
},
|
|
125
|
+
listSkills: function() {
|
|
126
|
+
return call('skills/list');
|
|
127
|
+
},
|
|
128
|
+
listJobs: function() {
|
|
129
|
+
return call('jobs/list');
|
|
130
|
+
},
|
|
131
|
+
executeJob: function(name, input, opts) {
|
|
132
|
+
return call('jobs/execute', { name: name, input: input, options: opts });
|
|
133
|
+
},
|
|
134
|
+
getJobStatus: function(runId) {
|
|
135
|
+
return call('jobs/status', { runId: runId });
|
|
136
|
+
},
|
|
137
|
+
listWorkflows: function() {
|
|
138
|
+
return call('workflows/list');
|
|
139
|
+
},
|
|
140
|
+
executeWorkflow: function(name, input, opts) {
|
|
141
|
+
return call('workflows/execute', { name: name, input: input, options: opts });
|
|
142
|
+
},
|
|
143
|
+
getWorkflowStatus: function(runId) {
|
|
144
|
+
return call('workflows/status', { runId: runId });
|
|
145
|
+
},
|
|
146
|
+
subscribeResource: function(uri) {
|
|
147
|
+
return call('resources/subscribe', { uri: uri });
|
|
148
|
+
},
|
|
149
|
+
unsubscribeResource: function(uri) {
|
|
150
|
+
return call('resources/unsubscribe', { uri: uri });
|
|
151
|
+
},
|
|
152
|
+
onResourceUpdated: function() {
|
|
153
|
+
console.warn('Resource subscriptions are not supported in daemon mode (HTTP-based, no push).');
|
|
154
|
+
return function() {};
|
|
155
|
+
},
|
|
156
|
+
onNotification: function() {
|
|
157
|
+
console.warn('Notifications are not supported in daemon mode (HTTP-based, no push).');
|
|
158
|
+
return function() {};
|
|
159
|
+
},
|
|
160
|
+
close: function() {
|
|
161
|
+
return Promise.resolve();
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
exports.createDaemonClient = createDaemonClient;
|
|
167
|
+
`;
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=daemon-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon-client.js","sourceRoot":"","sources":["../../../../../../src/commands/build/exec/cli-runtime/daemon-client.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAQH,gEAoJC;AA1JD,0DAA0D;AAE1D;;;GAGG;AACH,SAAgB,0BAA0B;IACxC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkJR,CAAC;AACF,CAAC","sourcesContent":["/**\n * Lightweight daemon client for CLI exec.\n *\n * Sends MCP JSON-RPC requests over a Unix socket using Node.js built-in http module.\n * This avoids the full FrontMCP SDK initialization (~420ms) by talking to an\n * already-running daemon process.\n *\n * NOTE: This file is used as a CJS runtime module — it gets bundled into the CLI\n * output by esbuild alongside the generated CLI entry. It must remain free of\n * TypeScript-only constructs at runtime (the .ts extension is for build-time only).\n */\n\n/* eslint-disable @typescript-eslint/no-require-imports */\n\n/**\n * Generate the daemon-client JavaScript source code (CJS module).\n * This is embedded into the CLI bundle at build time.\n */\nexport function generateDaemonClientSource(): string {\n return `'use strict';\n\nvar http = require('http');\n\n/**\n * Send a JSON-RPC request over a Unix socket.\n * @param {string} socketPath - Path to the Unix socket file.\n * @param {string} method - JSON-RPC method name.\n * @param {object} [params] - Method parameters.\n * @returns {Promise<object>} Parsed JSON-RPC result.\n */\nfunction rpcCall(socketPath, method, params) {\n return new Promise(function(resolve, reject) {\n var body = JSON.stringify({\n jsonrpc: '2.0',\n id: Date.now(),\n method: method,\n params: params || {}\n });\n\n var req = http.request({\n socketPath: socketPath,\n path: '/mcp',\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Content-Length': Buffer.byteLength(body)\n },\n timeout: 10000\n }, function(res) {\n var chunks = [];\n res.on('data', function(chunk) { chunks.push(chunk); });\n res.on('end', function() {\n try {\n var json = JSON.parse(Buffer.concat(chunks).toString());\n if (json.error) {\n var err = new Error(json.error.message || 'RPC error');\n err.code = json.error.code;\n err.data = json.error.data;\n reject(err);\n } else {\n resolve(json.result);\n }\n } catch (e) {\n reject(new Error('Invalid JSON response from daemon'));\n }\n });\n });\n\n req.on('error', function(err) {\n reject(err);\n });\n\n req.on('timeout', function() {\n req.destroy();\n reject(new Error('Daemon request timed out'));\n });\n\n req.write(body);\n req.end();\n });\n}\n\n/**\n * Create a daemon client that implements the same interface as DirectClient.\n * @param {string} socketPath - Path to the Unix socket file.\n * @returns {object} Client object with MCP methods.\n */\nfunction createDaemonClient(socketPath) {\n function call(method, params) {\n return rpcCall(socketPath, method, params);\n }\n\n return {\n ping: function() {\n return call('ping');\n },\n callTool: function(name, args) {\n return call('tools/call', { name: name, arguments: args || {} });\n },\n listTools: function() {\n return call('tools/list');\n },\n listResources: function() {\n return call('resources/list');\n },\n readResource: function(uri) {\n return call('resources/read', { uri: uri });\n },\n listResourceTemplates: function() {\n return call('resources/templates/list');\n },\n listPrompts: function() {\n return call('prompts/list');\n },\n getPrompt: function(name, args) {\n return call('prompts/get', { name: name, arguments: args || {} });\n },\n searchSkills: function(query) {\n return call('skills/search', { query: query || '' });\n },\n loadSkills: function(ids) {\n return call('skills/load', { ids: ids });\n },\n listSkills: function() {\n return call('skills/list');\n },\n listJobs: function() {\n return call('jobs/list');\n },\n executeJob: function(name, input, opts) {\n return call('jobs/execute', { name: name, input: input, options: opts });\n },\n getJobStatus: function(runId) {\n return call('jobs/status', { runId: runId });\n },\n listWorkflows: function() {\n return call('workflows/list');\n },\n executeWorkflow: function(name, input, opts) {\n return call('workflows/execute', { name: name, input: input, options: opts });\n },\n getWorkflowStatus: function(runId) {\n return call('workflows/status', { runId: runId });\n },\n subscribeResource: function(uri) {\n return call('resources/subscribe', { uri: uri });\n },\n unsubscribeResource: function(uri) {\n return call('resources/unsubscribe', { uri: uri });\n },\n onResourceUpdated: function() {\n console.warn('Resource subscriptions are not supported in daemon mode (HTTP-based, no push).');\n return function() {};\n },\n onNotification: function() {\n console.warn('Notifications are not supported in daemon mode (HTTP-based, no push).');\n return function() {};\n },\n close: function() {\n return Promise.resolve();\n }\n };\n}\n\nexports.createDaemonClient = createDaemonClient;\n`;\n}\n"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates the CLI entry point TypeScript/JavaScript source code.
|
|
3
|
+
* This creates a commander.js-based CLI where each MCP tool is a subcommand.
|
|
4
|
+
*/
|
|
5
|
+
import { CliConfig, OAuthConfig } from '../config';
|
|
6
|
+
import { ExtractedSchema } from './schema-extractor';
|
|
7
|
+
export declare const RESERVED_COMMANDS: Set<string>;
|
|
8
|
+
export interface CliEntryOptions {
|
|
9
|
+
appName: string;
|
|
10
|
+
appVersion: string;
|
|
11
|
+
description: string;
|
|
12
|
+
serverBundleFilename: string;
|
|
13
|
+
outputDefault: 'text' | 'json';
|
|
14
|
+
authRequired: boolean;
|
|
15
|
+
excludeTools: string[];
|
|
16
|
+
nativeDeps: NonNullable<CliConfig['nativeDeps']>;
|
|
17
|
+
schema: ExtractedSchema;
|
|
18
|
+
oauthConfig?: OAuthConfig;
|
|
19
|
+
/** When true, generate static requires that esbuild can resolve (for SEA builds). */
|
|
20
|
+
selfContained?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Resolve tool command name, appending '-tool' suffix if it conflicts with a built-in command.
|
|
24
|
+
* Returns { cmdName, wasRenamed } so the caller can log a warning at build time.
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveToolCommandName(toolName: string): {
|
|
27
|
+
cmdName: string;
|
|
28
|
+
wasRenamed: boolean;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Generate the CLI entry source code (CJS module).
|
|
32
|
+
*/
|
|
33
|
+
export declare function generateCliEntry(options: CliEntryOptions): string;
|
|
34
|
+
/**
|
|
35
|
+
* Extract {param} placeholders from a URI template string.
|
|
36
|
+
*/
|
|
37
|
+
export declare function extractTemplateParams(uriTemplate: string): string[];
|