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
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Session manager for CLI executables.
|
|
4
|
+
* Generates runtime module code for managing named sessions
|
|
5
|
+
* stored in ~/.frontmcp/apps/{appName}/sessions/.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.generateSessionManagerSource = generateSessionManagerSource;
|
|
9
|
+
/**
|
|
10
|
+
* Generate the session-manager runtime module source for embedding in CLI bundle.
|
|
11
|
+
*/
|
|
12
|
+
function generateSessionManagerSource(appName) {
|
|
13
|
+
return `
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
var os = require('os');
|
|
17
|
+
var path = require('path');
|
|
18
|
+
var fs = require('fs');
|
|
19
|
+
|
|
20
|
+
var APP_NAME = ${JSON.stringify(appName)};
|
|
21
|
+
var SESSION_DIR = path.join(os.homedir(), '.frontmcp', 'apps', APP_NAME, 'sessions');
|
|
22
|
+
var ACTIVE_FILE = path.join(SESSION_DIR, '.active');
|
|
23
|
+
|
|
24
|
+
function ensureSessionDir() {
|
|
25
|
+
fs.mkdirSync(SESSION_DIR, { recursive: true });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function sessionPath(name) {
|
|
29
|
+
return path.join(SESSION_DIR, name + '.json');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function readSession(name) {
|
|
33
|
+
try {
|
|
34
|
+
var data = fs.readFileSync(sessionPath(name), 'utf8');
|
|
35
|
+
return JSON.parse(data);
|
|
36
|
+
} catch (_) { return null; }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function writeSession(session) {
|
|
40
|
+
ensureSessionDir();
|
|
41
|
+
fs.writeFileSync(sessionPath(session.name), JSON.stringify(session, null, 2), { mode: 0o600 });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function getActiveSessionName() {
|
|
45
|
+
try {
|
|
46
|
+
return fs.readFileSync(ACTIVE_FILE, 'utf8').trim() || 'default';
|
|
47
|
+
} catch (_) { return 'default'; }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function setActiveSession(name) {
|
|
51
|
+
ensureSessionDir();
|
|
52
|
+
fs.writeFileSync(ACTIVE_FILE, name, { mode: 0o600 });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function getOrCreateSession(name) {
|
|
56
|
+
name = name || getActiveSessionName();
|
|
57
|
+
var session = readSession(name);
|
|
58
|
+
if (!session) {
|
|
59
|
+
session = {
|
|
60
|
+
name: name,
|
|
61
|
+
createdAt: new Date().toISOString(),
|
|
62
|
+
lastUsedAt: new Date().toISOString(),
|
|
63
|
+
isActive: true
|
|
64
|
+
};
|
|
65
|
+
writeSession(session);
|
|
66
|
+
if (name === 'default' || !fs.existsSync(ACTIVE_FILE)) {
|
|
67
|
+
setActiveSession(name);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return session;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function touchSession(name) {
|
|
74
|
+
var session = readSession(name);
|
|
75
|
+
if (session) {
|
|
76
|
+
session.lastUsedAt = new Date().toISOString();
|
|
77
|
+
writeSession(session);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function listSessions() {
|
|
82
|
+
ensureSessionDir();
|
|
83
|
+
var active = getActiveSessionName();
|
|
84
|
+
try {
|
|
85
|
+
return fs.readdirSync(SESSION_DIR)
|
|
86
|
+
.filter(function(f) { return f.endsWith('.json'); })
|
|
87
|
+
.map(function(f) {
|
|
88
|
+
var name = f.replace(/\\.json$/, '');
|
|
89
|
+
var session = readSession(name);
|
|
90
|
+
return session ? Object.assign({}, session, { isActive: name === active }) : null;
|
|
91
|
+
})
|
|
92
|
+
.filter(Boolean);
|
|
93
|
+
} catch (_) { return []; }
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function deleteSession(name) {
|
|
97
|
+
try {
|
|
98
|
+
fs.unlinkSync(sessionPath(name));
|
|
99
|
+
if (getActiveSessionName() === name) {
|
|
100
|
+
setActiveSession('default');
|
|
101
|
+
}
|
|
102
|
+
return true;
|
|
103
|
+
} catch (_) { return false; }
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function switchSession(name) {
|
|
107
|
+
var session = getOrCreateSession(name);
|
|
108
|
+
setActiveSession(name);
|
|
109
|
+
return session;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
module.exports = {
|
|
113
|
+
getOrCreateSession: getOrCreateSession,
|
|
114
|
+
touchSession: touchSession,
|
|
115
|
+
listSessions: listSessions,
|
|
116
|
+
deleteSession: deleteSession,
|
|
117
|
+
switchSession: switchSession,
|
|
118
|
+
getActiveSessionName: getActiveSessionName
|
|
119
|
+
};
|
|
120
|
+
`.trim();
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=session-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../../../../../src/commands/build/exec/cli-runtime/session-manager.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAaH,oEA6GC;AAhHD;;GAEG;AACH,SAAgB,4BAA4B,CAAC,OAAe;IAC1D,OAAO;;;;;;;iBAOQ,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoGvC,CAAC,IAAI,EAAE,CAAC;AACT,CAAC","sourcesContent":["/**\n * Session manager for CLI executables.\n * Generates runtime module code for managing named sessions\n * stored in ~/.frontmcp/apps/{appName}/sessions/.\n */\n\nexport interface SessionInfo {\n name: string;\n user?: string;\n createdAt: string;\n lastUsedAt: string;\n isActive: boolean;\n}\n\n/**\n * Generate the session-manager runtime module source for embedding in CLI bundle.\n */\nexport function generateSessionManagerSource(appName: string): string {\n return `\n'use strict';\n\nvar os = require('os');\nvar path = require('path');\nvar fs = require('fs');\n\nvar APP_NAME = ${JSON.stringify(appName)};\nvar SESSION_DIR = path.join(os.homedir(), '.frontmcp', 'apps', APP_NAME, 'sessions');\nvar ACTIVE_FILE = path.join(SESSION_DIR, '.active');\n\nfunction ensureSessionDir() {\n fs.mkdirSync(SESSION_DIR, { recursive: true });\n}\n\nfunction sessionPath(name) {\n return path.join(SESSION_DIR, name + '.json');\n}\n\nfunction readSession(name) {\n try {\n var data = fs.readFileSync(sessionPath(name), 'utf8');\n return JSON.parse(data);\n } catch (_) { return null; }\n}\n\nfunction writeSession(session) {\n ensureSessionDir();\n fs.writeFileSync(sessionPath(session.name), JSON.stringify(session, null, 2), { mode: 0o600 });\n}\n\nfunction getActiveSessionName() {\n try {\n return fs.readFileSync(ACTIVE_FILE, 'utf8').trim() || 'default';\n } catch (_) { return 'default'; }\n}\n\nfunction setActiveSession(name) {\n ensureSessionDir();\n fs.writeFileSync(ACTIVE_FILE, name, { mode: 0o600 });\n}\n\nfunction getOrCreateSession(name) {\n name = name || getActiveSessionName();\n var session = readSession(name);\n if (!session) {\n session = {\n name: name,\n createdAt: new Date().toISOString(),\n lastUsedAt: new Date().toISOString(),\n isActive: true\n };\n writeSession(session);\n if (name === 'default' || !fs.existsSync(ACTIVE_FILE)) {\n setActiveSession(name);\n }\n }\n return session;\n}\n\nfunction touchSession(name) {\n var session = readSession(name);\n if (session) {\n session.lastUsedAt = new Date().toISOString();\n writeSession(session);\n }\n}\n\nfunction listSessions() {\n ensureSessionDir();\n var active = getActiveSessionName();\n try {\n return fs.readdirSync(SESSION_DIR)\n .filter(function(f) { return f.endsWith('.json'); })\n .map(function(f) {\n var name = f.replace(/\\\\.json$/, '');\n var session = readSession(name);\n return session ? Object.assign({}, session, { isActive: name === active }) : null;\n })\n .filter(Boolean);\n } catch (_) { return []; }\n}\n\nfunction deleteSession(name) {\n try {\n fs.unlinkSync(sessionPath(name));\n if (getActiveSessionName() === name) {\n setActiveSession('default');\n }\n return true;\n } catch (_) { return false; }\n}\n\nfunction switchSession(name) {\n var session = getOrCreateSession(name);\n setActiveSession(name);\n return session;\n}\n\nmodule.exports = {\n getOrCreateSession: getOrCreateSession,\n touchSession: touchSession,\n listSessions: listSessions,\n deleteSession: deleteSession,\n switchSession: switchSession,\n getActiveSessionName: getActiveSessionName\n};\n`.trim();\n}\n"]}
|
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
* frontmcp.config.js/json schema and loader.
|
|
3
3
|
*/
|
|
4
4
|
import { SetupDefinition } from './setup';
|
|
5
|
+
export interface OAuthConfig {
|
|
6
|
+
serverUrl?: string;
|
|
7
|
+
clientId?: string;
|
|
8
|
+
defaultScope?: string;
|
|
9
|
+
portRange?: [number, number];
|
|
10
|
+
defaultPort?: number;
|
|
11
|
+
timeout?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface CliConfig {
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
outputDefault?: 'text' | 'json';
|
|
16
|
+
authRequired?: boolean;
|
|
17
|
+
description?: string;
|
|
18
|
+
excludeTools?: string[];
|
|
19
|
+
nativeDeps?: {
|
|
20
|
+
brew?: string[];
|
|
21
|
+
apt?: string[];
|
|
22
|
+
npm?: string[];
|
|
23
|
+
};
|
|
24
|
+
oauth?: OAuthConfig;
|
|
25
|
+
}
|
|
5
26
|
export interface FrontmcpExecConfig {
|
|
6
27
|
name: string;
|
|
7
28
|
version?: string;
|
|
@@ -26,6 +47,10 @@ export interface FrontmcpExecConfig {
|
|
|
26
47
|
minify?: boolean;
|
|
27
48
|
};
|
|
28
49
|
setup?: SetupDefinition;
|
|
50
|
+
cli?: CliConfig;
|
|
51
|
+
sea?: {
|
|
52
|
+
enabled?: boolean;
|
|
53
|
+
};
|
|
29
54
|
}
|
|
30
55
|
/**
|
|
31
56
|
* Load frontmcp.config.js/json from the given directory.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../../src/commands/build/exec/config.ts"],"names":[],"mappings":";AAAA;;GAEG;;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../../src/commands/build/exec/config.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAsEH,wCA6BC;AAKD,0CAgBC;;AAtHD,mDAA6B;AAC7B,+CAAyB;AAwDzB,MAAM,gBAAgB,GAAG;IACvB,oBAAoB;IACpB,sBAAsB;IACtB,qBAAqB;IACrB,qBAAqB;CACtB,CAAC;AAEF;;;GAGG;AACI,KAAK,UAAU,cAAc,CAAC,GAAW;IAC9C,KAAK,MAAM,QAAQ,IAAI,gBAAgB,EAAE,CAAC;QACxC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC5C,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC/B,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBACrD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAuB,CAAC;YACnD,CAAC;YACD,iCAAiC;YAEjC,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAuB,CAAC;QACpD,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAC/C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,kGAAkG,CACnG,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1D,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAC9D,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,OAAO;QAC/B,KAAK,EAAE,GAAG,CAAC,IAAI;KAChB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,MAA0B;IAIxD,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CACb,sBAAsB,MAAM,CAAC,IAAI,wCAAwC,CAC1E,CAAC;IACJ,CAAC;IAED,OAAO;QACL,GAAG,MAAM;QACT,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,OAAO;QAClC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,UAAU;KAC9C,CAAC;AACJ,CAAC","sourcesContent":["/**\n * frontmcp.config.js/json schema and loader.\n */\n\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport { SetupDefinition } from './setup';\n\nexport interface OAuthConfig {\n serverUrl?: string;\n clientId?: string;\n defaultScope?: string;\n portRange?: [number, number];\n defaultPort?: number;\n timeout?: number;\n}\n\nexport interface CliConfig {\n enabled: boolean;\n outputDefault?: 'text' | 'json';\n authRequired?: boolean;\n description?: string;\n excludeTools?: string[];\n nativeDeps?: {\n brew?: string[];\n apt?: string[];\n npm?: string[];\n };\n oauth?: OAuthConfig;\n}\n\nexport interface FrontmcpExecConfig {\n name: string;\n version?: string;\n entry?: string;\n storage?: {\n type: 'sqlite' | 'redis' | 'none';\n required?: boolean;\n };\n network?: {\n defaultPort?: number;\n supportsSocket?: boolean;\n };\n dependencies?: {\n system?: string[];\n nativeAddons?: string[];\n };\n nodeVersion?: string;\n esbuild?: {\n external?: string[];\n define?: Record<string, string>;\n target?: string;\n minify?: boolean;\n };\n setup?: SetupDefinition;\n cli?: CliConfig;\n sea?: {\n enabled?: boolean;\n };\n}\n\nconst CONFIG_FILENAMES = [\n 'frontmcp.config.js',\n 'frontmcp.config.json',\n 'frontmcp.config.mjs',\n 'frontmcp.config.cjs',\n];\n\n/**\n * Load frontmcp.config.js/json from the given directory.\n * Falls back to deriving minimal config from package.json.\n */\nexport async function loadExecConfig(cwd: string): Promise<FrontmcpExecConfig> {\n for (const filename of CONFIG_FILENAMES) {\n const configPath = path.join(cwd, filename);\n if (fs.existsSync(configPath)) {\n if (filename.endsWith('.json')) {\n const content = fs.readFileSync(configPath, 'utf-8');\n return JSON.parse(content) as FrontmcpExecConfig;\n }\n // JS/MJS/CJS config — require it\n \n const mod = require(configPath);\n return (mod.default || mod) as FrontmcpExecConfig;\n }\n }\n\n // Fallback: derive from package.json\n const pkgPath = path.join(cwd, 'package.json');\n if (!fs.existsSync(pkgPath)) {\n throw new Error(\n 'No frontmcp.config.js/json found and no package.json. Create a frontmcp.config.js to use --exec.',\n );\n }\n\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));\n return {\n name: pkg.name?.replace(/^@[^/]+\\//, '') || path.basename(cwd),\n version: pkg.version || '1.0.0',\n entry: pkg.main,\n };\n}\n\n/**\n * Validate config and return normalized version.\n */\nexport function normalizeConfig(config: FrontmcpExecConfig): Required<\n Pick<FrontmcpExecConfig, 'name' | 'version' | 'nodeVersion'>\n> &\n FrontmcpExecConfig {\n if (!config.name || !/^[a-zA-Z0-9._-]+$/.test(config.name)) {\n throw new Error(\n `Invalid app name: \"${config.name}\". Must be alphanumeric with .-_ only.`,\n );\n }\n\n return {\n ...config,\n name: config.name,\n version: config.version || '1.0.0',\n nodeVersion: config.nodeVersion || '>=22.0.0',\n };\n}\n"]}
|
|
@@ -7,5 +7,8 @@ export interface BundleResult {
|
|
|
7
7
|
bundlePath: string;
|
|
8
8
|
bundleSize: number;
|
|
9
9
|
}
|
|
10
|
-
export declare function bundleWithEsbuild(entryPath: string, outDir: string, config: FrontmcpExecConfig
|
|
10
|
+
export declare function bundleWithEsbuild(entryPath: string, outDir: string, config: FrontmcpExecConfig, options?: {
|
|
11
|
+
selfContained?: boolean;
|
|
12
|
+
outputName?: string;
|
|
13
|
+
}): Promise<BundleResult>;
|
|
11
14
|
export declare function formatSize(bytes: number): string;
|
|
@@ -8,30 +8,49 @@ exports.bundleWithEsbuild = bundleWithEsbuild;
|
|
|
8
8
|
exports.formatSize = formatSize;
|
|
9
9
|
const tslib_1 = require("tslib");
|
|
10
10
|
const path = tslib_1.__importStar(require("path"));
|
|
11
|
-
// Default
|
|
11
|
+
// Default packages that must be kept external:
|
|
12
|
+
// - native addons that cannot be bundled
|
|
13
|
+
// - optional/lazy-required peer dependencies
|
|
12
14
|
const DEFAULT_EXTERNALS = [
|
|
13
15
|
'better-sqlite3',
|
|
14
16
|
'fsevents',
|
|
15
17
|
'@swc/core',
|
|
16
18
|
'esbuild',
|
|
19
|
+
'@vercel/kv',
|
|
20
|
+
'@frontmcp/storage-sqlite',
|
|
21
|
+
'@enclave-vm/core',
|
|
22
|
+
// Externalize FrontMCP packages for single-copy semantics
|
|
23
|
+
// (required for schema extraction — bundled copies create separate Symbol tokens)
|
|
24
|
+
'@frontmcp/sdk',
|
|
25
|
+
'@frontmcp/di',
|
|
26
|
+
'@frontmcp/utils',
|
|
27
|
+
'@frontmcp/auth',
|
|
28
|
+
'@frontmcp/adapters',
|
|
29
|
+
'@frontmcp/plugins',
|
|
30
|
+
'reflect-metadata',
|
|
17
31
|
];
|
|
18
|
-
async function bundleWithEsbuild(entryPath, outDir, config) {
|
|
32
|
+
async function bundleWithEsbuild(entryPath, outDir, config, options) {
|
|
19
33
|
// Lazy-load esbuild
|
|
20
34
|
let esbuild;
|
|
21
35
|
try {
|
|
22
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
23
36
|
esbuild = require('esbuild');
|
|
24
37
|
}
|
|
25
38
|
catch {
|
|
26
39
|
throw new Error('esbuild is required for --exec builds. Install it: npm install -D esbuild');
|
|
27
40
|
}
|
|
28
|
-
const bundleName = `${config.name}.bundle.js`;
|
|
41
|
+
const bundleName = `${options?.outputName || config.name}.bundle.js`;
|
|
29
42
|
const bundlePath = path.join(outDir, bundleName);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
43
|
+
// In self-contained mode (SEA), only keep true native addons external
|
|
44
|
+
const external = options?.selfContained
|
|
45
|
+
? [
|
|
46
|
+
...DEFAULT_EXTERNALS,
|
|
47
|
+
...(config.dependencies?.nativeAddons || []),
|
|
48
|
+
]
|
|
49
|
+
: [
|
|
50
|
+
...DEFAULT_EXTERNALS,
|
|
51
|
+
...(config.dependencies?.nativeAddons || []),
|
|
52
|
+
...(config.esbuild?.external || []),
|
|
53
|
+
];
|
|
35
54
|
await esbuild.build({
|
|
36
55
|
entryPoints: [entryPath],
|
|
37
56
|
bundle: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"esbuild-bundler.js","sourceRoot":"","sources":["../../../../../src/commands/build/exec/esbuild-bundler.ts"],"names":[],"mappings":";AAAA;;;GAGG;;
|
|
1
|
+
{"version":3,"file":"esbuild-bundler.js","sourceRoot":"","sources":["../../../../../src/commands/build/exec/esbuild-bundler.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAgCH,8CAyDC;AAED,gCAIC;;AA7FD,mDAA6B;AAG7B,+CAA+C;AAC/C,yCAAyC;AACzC,6CAA6C;AAC7C,MAAM,iBAAiB,GAAG;IACxB,gBAAgB;IAChB,UAAU;IACV,WAAW;IACX,SAAS;IACT,YAAY;IACZ,0BAA0B;IAC1B,kBAAkB;IAClB,0DAA0D;IAC1D,kFAAkF;IAClF,eAAe;IACf,cAAc;IACd,iBAAiB;IACjB,gBAAgB;IAChB,oBAAoB;IACpB,mBAAmB;IACnB,kBAAkB;CACnB,CAAC;AAOK,KAAK,UAAU,iBAAiB,CACrC,SAAiB,EACjB,MAAc,EACd,MAA0B,EAC1B,OAA0D;IAE1D,oBAAoB;IACpB,IAAI,OAAiC,CAAC;IACtC,IAAI,CAAC;QAEH,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,2EAA2E,CAC5E,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,GAAG,OAAO,EAAE,UAAU,IAAI,MAAM,CAAC,IAAI,YAAY,CAAC;IACrE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAEjD,sEAAsE;IACtE,MAAM,QAAQ,GAAG,OAAO,EAAE,aAAa;QACrC,CAAC,CAAC;YACE,GAAG,iBAAiB;YACpB,GAAG,CAAC,MAAM,CAAC,YAAY,EAAE,YAAY,IAAI,EAAE,CAAC;SAC7C;QACH,CAAC,CAAC;YACE,GAAG,iBAAiB;YACpB,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,SAAS,CAAC;QACxB,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,EAAE,8CAA8C;QAC/D,WAAW,EAAE,IAAI;QACjB,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,KAAK;QACvC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM;QAC9B,SAAS,EAAE,KAAK;QAChB,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,SAAS;KACpB,CAAC,CAAC;IAEH,wBAAwB;IACxB,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;AAED,SAAgB,UAAU,CAAC,KAAa;IACtC,IAAI,KAAK,GAAG,IAAI;QAAE,OAAO,GAAG,KAAK,IAAI,CAAC;IACtC,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IAClE,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AACpD,CAAC","sourcesContent":["/**\n * esbuild bundling for executable builds.\n * Produces a single CJS file for distribution.\n */\n\nimport * as path from 'path';\nimport { FrontmcpExecConfig } from './config';\n\n// Default packages that must be kept external:\n// - native addons that cannot be bundled\n// - optional/lazy-required peer dependencies\nconst DEFAULT_EXTERNALS = [\n 'better-sqlite3',\n 'fsevents',\n '@swc/core',\n 'esbuild',\n '@vercel/kv',\n '@frontmcp/storage-sqlite',\n '@enclave-vm/core',\n // Externalize FrontMCP packages for single-copy semantics\n // (required for schema extraction — bundled copies create separate Symbol tokens)\n '@frontmcp/sdk',\n '@frontmcp/di',\n '@frontmcp/utils',\n '@frontmcp/auth',\n '@frontmcp/adapters',\n '@frontmcp/plugins',\n 'reflect-metadata',\n];\n\nexport interface BundleResult {\n bundlePath: string;\n bundleSize: number;\n}\n\nexport async function bundleWithEsbuild(\n entryPath: string,\n outDir: string,\n config: FrontmcpExecConfig,\n options?: { selfContained?: boolean; outputName?: string },\n): Promise<BundleResult> {\n // Lazy-load esbuild\n let esbuild: typeof import('esbuild');\n try {\n\n esbuild = require('esbuild');\n } catch {\n throw new Error(\n 'esbuild is required for --exec builds. Install it: npm install -D esbuild',\n );\n }\n\n const bundleName = `${options?.outputName || config.name}.bundle.js`;\n const bundlePath = path.join(outDir, bundleName);\n\n // In self-contained mode (SEA), only keep true native addons external\n const external = options?.selfContained\n ? [\n ...DEFAULT_EXTERNALS,\n ...(config.dependencies?.nativeAddons || []),\n ]\n : [\n ...DEFAULT_EXTERNALS,\n ...(config.dependencies?.nativeAddons || []),\n ...(config.esbuild?.external || []),\n ];\n\n await esbuild.build({\n entryPoints: [entryPath],\n bundle: true,\n platform: 'node',\n format: 'cjs',\n target: config.esbuild?.target || 'node22',\n outfile: bundlePath,\n external,\n keepNames: true, // preserve class names for decorator metadata\n treeShaking: true,\n minify: config.esbuild?.minify ?? false,\n define: config.esbuild?.define,\n sourcemap: false,\n metafile: true,\n logLevel: 'warning',\n });\n\n // Calculate bundle size\n const fs = require('fs');\n const stat = fs.statSync(bundlePath);\n\n return {\n bundlePath,\n bundleSize: stat.size,\n };\n}\n\nexport function formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n"]}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* buildExec() orchestrator — produces a distributable bundle from a FrontMCP app.
|
|
3
3
|
*
|
|
4
|
-
* Output:
|
|
4
|
+
* Output (server-only mode):
|
|
5
5
|
* dist/{name}.bundle.js — esbuild single-file bundle
|
|
6
6
|
* dist/{name}.manifest.json — app metadata (runtime reqs, setup questions)
|
|
7
7
|
* dist/{name} — bash runner script
|
|
8
8
|
* dist/install-{name}.sh — bash installer script
|
|
9
|
+
*
|
|
10
|
+
* Output (CLI mode, --cli flag):
|
|
11
|
+
* All of the above, plus:
|
|
12
|
+
* dist/{name}-cli.bundle.js — CLI executable bundle (commander.js)
|
|
13
|
+
* dist/{name} — bash runner dispatches to CLI bundle
|
|
9
14
|
*/
|
|
10
|
-
import { ParsedArgs } from '../../../args';
|
|
15
|
+
import { ParsedArgs } from '../../../core/args';
|
|
11
16
|
export declare function buildExec(opts: ParsedArgs): Promise<void>;
|
|
@@ -2,19 +2,24 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* buildExec() orchestrator — produces a distributable bundle from a FrontMCP app.
|
|
4
4
|
*
|
|
5
|
-
* Output:
|
|
5
|
+
* Output (server-only mode):
|
|
6
6
|
* dist/{name}.bundle.js — esbuild single-file bundle
|
|
7
7
|
* dist/{name}.manifest.json — app metadata (runtime reqs, setup questions)
|
|
8
8
|
* dist/{name} — bash runner script
|
|
9
9
|
* dist/install-{name}.sh — bash installer script
|
|
10
|
+
*
|
|
11
|
+
* Output (CLI mode, --cli flag):
|
|
12
|
+
* All of the above, plus:
|
|
13
|
+
* dist/{name}-cli.bundle.js — CLI executable bundle (commander.js)
|
|
14
|
+
* dist/{name} — bash runner dispatches to CLI bundle
|
|
10
15
|
*/
|
|
11
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
17
|
exports.buildExec = buildExec;
|
|
13
18
|
const tslib_1 = require("tslib");
|
|
14
19
|
const path = tslib_1.__importStar(require("path"));
|
|
15
20
|
const fs = tslib_1.__importStar(require("fs"));
|
|
16
|
-
const colors_1 = require("../../../colors");
|
|
17
|
-
const fs_1 = require("../../../
|
|
21
|
+
const colors_1 = require("../../../core/colors");
|
|
22
|
+
const fs_1 = require("../../../shared/fs");
|
|
18
23
|
const config_1 = require("./config");
|
|
19
24
|
const esbuild_bundler_1 = require("./esbuild-bundler");
|
|
20
25
|
const manifest_1 = require("./manifest");
|
|
@@ -22,7 +27,7 @@ const runner_script_1 = require("./runner-script");
|
|
|
22
27
|
const installer_script_1 = require("./installer-script");
|
|
23
28
|
const setup_1 = require("./setup");
|
|
24
29
|
const utils_1 = require("@frontmcp/utils");
|
|
25
|
-
const tsconfig_1 = require("../../../tsconfig");
|
|
30
|
+
const tsconfig_1 = require("../../../core/tsconfig");
|
|
26
31
|
async function buildExec(opts) {
|
|
27
32
|
const cwd = process.cwd();
|
|
28
33
|
const outDir = path.resolve(cwd, opts.outDir || 'dist');
|
|
@@ -30,8 +35,16 @@ async function buildExec(opts) {
|
|
|
30
35
|
// 1. Load config
|
|
31
36
|
const rawConfig = await (0, config_1.loadExecConfig)(cwd);
|
|
32
37
|
const config = (0, config_1.normalizeConfig)(rawConfig);
|
|
38
|
+
const cliEnabled = opts.cli || config.cli?.enabled;
|
|
39
|
+
const seaEnabled = opts.sea || config.sea?.enabled;
|
|
33
40
|
console.log(`${(0, colors_1.c)('cyan', '[build:exec]')} name: ${config.name}`);
|
|
34
41
|
console.log(`${(0, colors_1.c)('cyan', '[build:exec]')} version: ${config.version}`);
|
|
42
|
+
if (cliEnabled) {
|
|
43
|
+
console.log(`${(0, colors_1.c)('cyan', '[build:exec]')} CLI mode: enabled`);
|
|
44
|
+
}
|
|
45
|
+
if (seaEnabled) {
|
|
46
|
+
console.log(`${(0, colors_1.c)('cyan', '[build:exec]')} SEA mode: enabled (single executable)`);
|
|
47
|
+
}
|
|
35
48
|
// 2. Resolve entry
|
|
36
49
|
const entry = await (0, fs_1.resolveEntry)(cwd, config.entry || opts.entry);
|
|
37
50
|
console.log(`${(0, colors_1.c)('cyan', '[build:exec]')} entry: ${path.relative(cwd, entry)}`);
|
|
@@ -74,30 +87,147 @@ async function buildExec(opts) {
|
|
|
74
87
|
// 5. Bundle with esbuild
|
|
75
88
|
console.log(`${(0, colors_1.c)('cyan', '[build:exec]')} bundling with esbuild...`);
|
|
76
89
|
const compiledEntry = path.join(outDir, path.basename(entry).replace(/\.tsx?$/, '.js'));
|
|
90
|
+
// Always build non-self-contained first (schema extraction needs host SDK)
|
|
77
91
|
const bundleResult = await (0, esbuild_bundler_1.bundleWithEsbuild)(compiledEntry, outDir, config);
|
|
78
92
|
console.log(`${(0, colors_1.c)('green', '[build:exec]')} bundle created: ${path.relative(cwd, bundleResult.bundlePath)} (${(0, esbuild_bundler_1.formatSize)(bundleResult.bundleSize)})`);
|
|
79
93
|
// 6. Generate manifest
|
|
80
94
|
const bundleFilename = `${config.name}.bundle.js`;
|
|
81
95
|
const manifest = (0, manifest_1.generateManifest)(config, bundleFilename);
|
|
96
|
+
// 7. CLI build step (if enabled)
|
|
97
|
+
let cliBundlePath;
|
|
98
|
+
if (cliEnabled) {
|
|
99
|
+
console.log(`${(0, colors_1.c)('cyan', '[build:exec]')} extracting schemas for CLI...`);
|
|
100
|
+
const { extractSchemas, SYSTEM_TOOL_NAMES } = await import('./cli-runtime/schema-extractor.js');
|
|
101
|
+
const { generateCliEntry, resolveToolCommandName } = await import('./cli-runtime/generate-cli-entry.js');
|
|
102
|
+
const { generateOutputFormatterSource } = await import('./cli-runtime/output-formatter.js');
|
|
103
|
+
const { generateSessionManagerSource } = await import('./cli-runtime/session-manager.js');
|
|
104
|
+
const { generateCredentialStoreSource } = await import('./cli-runtime/credential-store.js');
|
|
105
|
+
const { generateOAuthHelperSource } = await import('./cli-runtime/oauth-helper.js');
|
|
106
|
+
const { generateDaemonClientSource } = await import('./cli-runtime/daemon-client.js');
|
|
107
|
+
const { bundleCliWithEsbuild } = await import('./cli-runtime/cli-bundler.js');
|
|
108
|
+
// Extract schemas from server bundle
|
|
109
|
+
const schema = await extractSchemas(bundleResult.bundlePath);
|
|
110
|
+
const capabilities = schema.capabilities;
|
|
111
|
+
const userToolCount = schema.tools.filter((t) => !SYSTEM_TOOL_NAMES.has(t.name)).length;
|
|
112
|
+
console.log(`${(0, colors_1.c)('cyan', '[build:exec]')} extracted: ${schema.tools.length} tools (${userToolCount} user), ${schema.resources.length} resources, ${schema.resourceTemplates.length} templates, ${schema.prompts.length} prompts`);
|
|
113
|
+
if (capabilities.skills)
|
|
114
|
+
console.log(`${(0, colors_1.c)('cyan', '[build:exec]')} capability: skills`);
|
|
115
|
+
if (capabilities.jobs)
|
|
116
|
+
console.log(`${(0, colors_1.c)('cyan', '[build:exec]')} capability: jobs`);
|
|
117
|
+
if (capabilities.workflows)
|
|
118
|
+
console.log(`${(0, colors_1.c)('cyan', '[build:exec]')} capability: workflows`);
|
|
119
|
+
// Log tool name conflicts
|
|
120
|
+
const cliConfig = config.cli || { enabled: true };
|
|
121
|
+
const excludeTools = cliConfig.excludeTools || [];
|
|
122
|
+
schema.tools
|
|
123
|
+
.filter((t) => !excludeTools.includes(t.name))
|
|
124
|
+
.forEach((t) => {
|
|
125
|
+
const { wasRenamed, cmdName } = resolveToolCommandName(t.name);
|
|
126
|
+
if (wasRenamed) {
|
|
127
|
+
console.log(`${(0, colors_1.c)('yellow', '[build:exec]')} Tool "${t.name}" conflicts with built-in command, mapped to "${cmdName}"`);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
// Generate runtime modules
|
|
131
|
+
const outputDefault = cliConfig.outputDefault || 'text';
|
|
132
|
+
const authRequired = cliConfig.authRequired ?? false;
|
|
133
|
+
const nativeDeps = cliConfig.nativeDeps || {};
|
|
134
|
+
const oauthConfig = cliConfig.oauth;
|
|
135
|
+
// Write runtime modules to temp files for bundling
|
|
136
|
+
const tempDir = path.join(outDir, '__cli_temp');
|
|
137
|
+
fs.mkdirSync(tempDir, { recursive: true });
|
|
138
|
+
fs.writeFileSync(path.join(tempDir, 'output-formatter.js'), generateOutputFormatterSource());
|
|
139
|
+
fs.writeFileSync(path.join(tempDir, 'session-manager.js'), generateSessionManagerSource(config.name));
|
|
140
|
+
fs.writeFileSync(path.join(tempDir, 'credential-store.js'), generateCredentialStoreSource(config.name));
|
|
141
|
+
fs.writeFileSync(path.join(tempDir, 'oauth-helper.js'), generateOAuthHelperSource(config.name));
|
|
142
|
+
fs.writeFileSync(path.join(tempDir, 'daemon-client.js'), generateDaemonClientSource());
|
|
143
|
+
// Generate CLI entry
|
|
144
|
+
const cliEntrySource = generateCliEntry({
|
|
145
|
+
appName: config.name,
|
|
146
|
+
appVersion: config.version || '1.0.0',
|
|
147
|
+
description: cliConfig.description || `${config.name} CLI`,
|
|
148
|
+
serverBundleFilename: bundleFilename,
|
|
149
|
+
outputDefault,
|
|
150
|
+
authRequired,
|
|
151
|
+
excludeTools,
|
|
152
|
+
nativeDeps,
|
|
153
|
+
schema,
|
|
154
|
+
oauthConfig,
|
|
155
|
+
selfContained: !!seaEnabled,
|
|
156
|
+
});
|
|
157
|
+
const cliEntryPath = path.join(tempDir, 'cli-entry.js');
|
|
158
|
+
fs.writeFileSync(cliEntryPath, cliEntrySource);
|
|
159
|
+
// Bundle CLI
|
|
160
|
+
console.log(`${(0, colors_1.c)('cyan', '[build:exec]')} bundling CLI...`);
|
|
161
|
+
const cliResult = await bundleCliWithEsbuild(cliEntryPath, outDir, config, {
|
|
162
|
+
selfContained: !!seaEnabled,
|
|
163
|
+
});
|
|
164
|
+
cliBundlePath = cliResult.bundlePath;
|
|
165
|
+
console.log(`${(0, colors_1.c)('green', '[build:exec]')} CLI bundle: ${path.relative(cwd, cliResult.bundlePath)} (${(0, esbuild_bundler_1.formatSize)(cliResult.bundleSize)})`);
|
|
166
|
+
// Clean temp
|
|
167
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
168
|
+
// Extend manifest with CLI metadata
|
|
169
|
+
manifest.cli = {
|
|
170
|
+
enabled: true,
|
|
171
|
+
cliBundle: `${config.name}-cli.bundle.js`,
|
|
172
|
+
outputDefault,
|
|
173
|
+
authRequired,
|
|
174
|
+
toolCount: userToolCount,
|
|
175
|
+
resourceCount: schema.resources.length,
|
|
176
|
+
templateCount: schema.resourceTemplates.length,
|
|
177
|
+
promptCount: schema.prompts.length,
|
|
178
|
+
oauthEnabled: !!oauthConfig,
|
|
179
|
+
skillsEnabled: capabilities.skills || undefined,
|
|
180
|
+
jobsEnabled: capabilities.jobs || undefined,
|
|
181
|
+
workflowsEnabled: capabilities.workflows || undefined,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
// 8. Build SEA binaries if enabled
|
|
185
|
+
let seaServerResult;
|
|
186
|
+
let seaCliResult;
|
|
187
|
+
if (seaEnabled) {
|
|
188
|
+
const { buildSea } = await import('./sea-builder.js');
|
|
189
|
+
// Rebuild server bundle as self-contained for SEA (inlines all deps)
|
|
190
|
+
// Use a temp filename so the original non-self-contained bundle is preserved
|
|
191
|
+
const seaTempName = `${config.name}.sea-temp`;
|
|
192
|
+
console.log(`${(0, colors_1.c)('cyan', '[build:sea]')} rebuilding server bundle (self-contained)...`);
|
|
193
|
+
const seaBundle = await (0, esbuild_bundler_1.bundleWithEsbuild)(compiledEntry, outDir, config, {
|
|
194
|
+
selfContained: true,
|
|
195
|
+
outputName: seaTempName,
|
|
196
|
+
});
|
|
197
|
+
console.log(`${(0, colors_1.c)('cyan', '[build:sea]')} building server SEA binary...`);
|
|
198
|
+
seaServerResult = await buildSea(seaBundle.bundlePath, outDir, config.name);
|
|
199
|
+
// Clean up temp self-contained bundle
|
|
200
|
+
fs.unlinkSync(seaBundle.bundlePath);
|
|
201
|
+
console.log(`${(0, colors_1.c)('green', '[build:sea]')} server binary: ${path.relative(cwd, seaServerResult.executablePath)} (${(0, esbuild_bundler_1.formatSize)(seaServerResult.executableSize)})`);
|
|
202
|
+
if (cliBundlePath) {
|
|
203
|
+
console.log(`${(0, colors_1.c)('cyan', '[build:sea]')} building CLI SEA binary...`);
|
|
204
|
+
seaCliResult = await buildSea(cliBundlePath, outDir, `${config.name}-cli`);
|
|
205
|
+
console.log(`${(0, colors_1.c)('green', '[build:sea]')} CLI binary: ${path.relative(cwd, seaCliResult.executablePath)} (${(0, esbuild_bundler_1.formatSize)(seaCliResult.executableSize)})`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// 9. Write manifest
|
|
82
209
|
const manifestPath = path.join(outDir, `${config.name}.manifest.json`);
|
|
83
210
|
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');
|
|
84
211
|
console.log(`${(0, colors_1.c)('green', '[build:exec]')} manifest: ${path.relative(cwd, manifestPath)}`);
|
|
85
|
-
//
|
|
86
|
-
const runnerContent = (0, runner_script_1.generateRunnerScript)(config);
|
|
212
|
+
// 10. Generate runner script (dispatches to CLI bundle or SEA binary)
|
|
213
|
+
const runnerContent = (0, runner_script_1.generateRunnerScript)(config, !!cliEnabled, !!seaEnabled);
|
|
87
214
|
const runnerPath = path.join(outDir, config.name);
|
|
88
215
|
fs.writeFileSync(runnerPath, runnerContent, { mode: 0o755 });
|
|
89
216
|
console.log(`${(0, colors_1.c)('green', '[build:exec]')} runner: ${path.relative(cwd, runnerPath)}`);
|
|
90
|
-
//
|
|
217
|
+
// 10. Generate installer script
|
|
91
218
|
const installerContent = (0, installer_script_1.generateInstallerScript)(config);
|
|
92
219
|
const installerPath = path.join(outDir, `install-${config.name}.sh`);
|
|
93
220
|
fs.writeFileSync(installerPath, installerContent, { mode: 0o755 });
|
|
94
221
|
console.log(`${(0, colors_1.c)('green', '[build:exec]')} installer: ${path.relative(cwd, installerPath)}`);
|
|
95
|
-
//
|
|
222
|
+
// 12. Clean up intermediate compiled files
|
|
96
223
|
const keepFiles = new Set([
|
|
97
224
|
`${config.name}.bundle.js`,
|
|
225
|
+
`${config.name}-cli.bundle.js`,
|
|
98
226
|
`${config.name}.manifest.json`,
|
|
99
227
|
config.name,
|
|
100
228
|
`install-${config.name}.sh`,
|
|
229
|
+
`${config.name}-bin`,
|
|
230
|
+
`${config.name}-cli-bin`,
|
|
101
231
|
]);
|
|
102
232
|
const allFiles = fs.readdirSync(outDir);
|
|
103
233
|
let cleaned = 0;
|
|
@@ -114,13 +244,33 @@ async function buildExec(opts) {
|
|
|
114
244
|
if (cleaned > 0) {
|
|
115
245
|
console.log(`${(0, colors_1.c)('gray', '[build:exec]')} cleaned ${cleaned} intermediate file(s)`);
|
|
116
246
|
}
|
|
247
|
+
// 13. Print summary
|
|
117
248
|
console.log(`\n${(0, colors_1.c)('green', 'Executable build completed.')}`);
|
|
118
249
|
console.log(`\n${(0, colors_1.c)('bold', 'Output:')}`);
|
|
119
250
|
console.log(` ${path.relative(cwd, bundleResult.bundlePath)} ${(0, colors_1.c)('gray', `(${(0, esbuild_bundler_1.formatSize)(bundleResult.bundleSize)})`)}`);
|
|
251
|
+
if (cliBundlePath) {
|
|
252
|
+
const cliStat = fs.statSync(cliBundlePath);
|
|
253
|
+
console.log(` ${path.relative(cwd, cliBundlePath)} ${(0, colors_1.c)('gray', `(${(0, esbuild_bundler_1.formatSize)(cliStat.size)})`)}`);
|
|
254
|
+
}
|
|
255
|
+
if (seaServerResult) {
|
|
256
|
+
console.log(` ${path.relative(cwd, seaServerResult.executablePath)} ${(0, colors_1.c)('gray', `(${(0, esbuild_bundler_1.formatSize)(seaServerResult.executableSize)})`)}`);
|
|
257
|
+
}
|
|
258
|
+
if (seaCliResult) {
|
|
259
|
+
console.log(` ${path.relative(cwd, seaCliResult.executablePath)} ${(0, colors_1.c)('gray', `(${(0, esbuild_bundler_1.formatSize)(seaCliResult.executableSize)})`)}`);
|
|
260
|
+
}
|
|
120
261
|
console.log(` ${path.relative(cwd, manifestPath)}`);
|
|
121
262
|
console.log(` ${path.relative(cwd, runnerPath)}`);
|
|
122
263
|
console.log(` ${path.relative(cwd, installerPath)}`);
|
|
123
|
-
|
|
264
|
+
if (cliEnabled) {
|
|
265
|
+
console.log(`\n${(0, colors_1.c)('gray', 'Run the CLI:')} ./${path.relative(cwd, runnerPath)} --help`);
|
|
266
|
+
console.log(`${(0, colors_1.c)('gray', 'Start server:')} ./${path.relative(cwd, runnerPath)} serve`);
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
console.log(`\n${(0, colors_1.c)('gray', 'Run the server:')} ./${path.relative(cwd, runnerPath)}`);
|
|
270
|
+
}
|
|
271
|
+
if (seaServerResult || seaCliResult) {
|
|
272
|
+
console.log(`\n${(0, colors_1.c)('yellow', 'Note:')} SEA binaries are native executables. Run directly (not via bash).`);
|
|
273
|
+
}
|
|
124
274
|
console.log(`${(0, colors_1.c)('gray', 'Install to system:')} bash ./${path.relative(cwd, installerPath)}`);
|
|
125
275
|
}
|
|
126
276
|
//# sourceMappingURL=index.js.map
|