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
|
@@ -17,8 +17,15 @@ async function fetchFromGit(url, tmpDir) {
|
|
|
17
17
|
if (gitUrl.startsWith('git+')) {
|
|
18
18
|
gitUrl = gitUrl.slice(4);
|
|
19
19
|
}
|
|
20
|
+
// Validate URL scheme to prevent argument injection (e.g., --upload-pack)
|
|
21
|
+
const ALLOWED_PREFIXES = ['https://', 'http://', 'git://', 'ssh://'];
|
|
22
|
+
// scp-style SSH: user@host:path (e.g., git@github.com:org/repo.git)
|
|
23
|
+
const SCP_PATTERN = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+:/;
|
|
24
|
+
if (!ALLOWED_PREFIXES.some((prefix) => gitUrl.startsWith(prefix)) && !SCP_PATTERN.test(gitUrl)) {
|
|
25
|
+
throw new Error(`Invalid git URL. URL must start with one of: ${ALLOWED_PREFIXES.join(', ')}, or be an scp-style SSH remote (user@host:path)`);
|
|
26
|
+
}
|
|
20
27
|
const cloneDir = path.join(tmpDir, 'package');
|
|
21
|
-
await (0, utils_1.runCmd)('git', ['clone', '--depth', '1', gitUrl, cloneDir]);
|
|
28
|
+
await (0, utils_1.runCmd)('git', ['clone', '--depth', '1', '--', gitUrl, cloneDir]);
|
|
22
29
|
return cloneDir;
|
|
23
30
|
}
|
|
24
31
|
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../../../../src/commands/package/sources/git.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAKH,oCAyBC;;AA5BD,mDAA6B;AAC7B,2CAAyC;AAElC,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,MAAc;IAC5D,gBAAgB;IAChB,IAAI,MAAM,GAAG,GAAG,CAAC;IACjB,IAAI,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACnE,MAAM,GAAG,sBAAsB,IAAI,MAAM,CAAC;IAC5C,CAAC;IACD,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IAED,0EAA0E;IAC1E,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACrE,oEAAoE;IACpE,MAAM,WAAW,GAAG,mCAAmC,CAAC;IACxD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/F,MAAM,IAAI,KAAK,CACb,gDAAgD,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,kDAAkD,CAC9H,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC9C,MAAM,IAAA,cAAM,EAAC,KAAK,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEvE,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["/**\n * Git source: clone repo to temp directory.\n */\n\nimport * as path from 'path';\nimport { runCmd } from '@frontmcp/utils';\n\nexport async function fetchFromGit(url: string, tmpDir: string): Promise<string> {\n // Normalize URL\n let gitUrl = url;\n if (gitUrl.startsWith('github:')) {\n const slug = gitUrl.slice('github:'.length).replace(/\\.git$/i, '');\n gitUrl = `https://github.com/${slug}.git`;\n }\n if (gitUrl.startsWith('git+')) {\n gitUrl = gitUrl.slice(4);\n }\n\n // Validate URL scheme to prevent argument injection (e.g., --upload-pack)\n const ALLOWED_PREFIXES = ['https://', 'http://', 'git://', 'ssh://'];\n // scp-style SSH: user@host:path (e.g., git@github.com:org/repo.git)\n const SCP_PATTERN = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+:/;\n if (!ALLOWED_PREFIXES.some((prefix) => gitUrl.startsWith(prefix)) && !SCP_PATTERN.test(gitUrl)) {\n throw new Error(\n `Invalid git URL. URL must start with one of: ${ALLOWED_PREFIXES.join(', ')}, or be an scp-style SSH remote (user@host:path)`,\n );\n }\n\n const cloneDir = path.join(tmpDir, 'package');\n await runCmd('git', ['clone', '--depth', '1', '--', gitUrl, cloneDir]);\n\n return cloneDir;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local.js","sourceRoot":"","sources":["../../../../../src/commands/
|
|
1
|
+
{"version":3,"file":"local.js","sourceRoot":"","sources":["../../../../../src/commands/package/sources/local.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAMH,wCAoBC;;AAxBD,mDAA6B;AAC7B,+CAAyB;AACzB,2CAAqC;AAE9B,KAAK,UAAU,cAAc,CAAC,SAAiB,EAAE,MAAc;IACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEzC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEnC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC1C,MAAM,IAAA,UAAE,EAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,wBAAwB;IACxB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC1C,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACpE,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["/**\n * Local path source: copy directory to temp.\n */\n\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport { cp } from '@frontmcp/utils';\n\nexport async function fetchFromLocal(localPath: string, tmpDir: string): Promise<string> {\n const resolved = path.resolve(localPath);\n\n if (!fs.existsSync(resolved)) {\n throw new Error(`Local path not found: ${resolved}`);\n }\n\n const stat = fs.statSync(resolved);\n\n if (stat.isDirectory()) {\n const dest = path.join(tmpDir, 'package');\n await cp(resolved, dest, { recursive: true });\n return dest;\n }\n\n // Single file — copy it\n const dest = path.join(tmpDir, 'package');\n fs.mkdirSync(dest, { recursive: true });\n fs.copyFileSync(resolved, path.join(dest, path.basename(resolved)));\n return dest;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"npm.js","sourceRoot":"","sources":["../../../../../src/commands/
|
|
1
|
+
{"version":3,"file":"npm.js","sourceRoot":"","sources":["../../../../../src/commands/package/sources/npm.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAMH,oCA6BC;;AAjCD,mDAA6B;AAC7B,+CAAyB;AACzB,2CAAyC;AAElC,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,MAAc,EAAE,WAAoB;IAClF,uDAAuD;IACvD,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,oBAAoB,EAAE,MAAM,CAAC,CAAC;IAC7D,IAAI,WAAW,EAAE,CAAC;QAChB,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,IAAA,cAAM,EAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAE9B,uEAAuE;IACvE,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,2CAA2C,GAAG,GAAG,CAAC,CAAC;IACrE,CAAC;IAED,sFAAsF;IACtF,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACpF,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAErD,sBAAsB;IACtB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAChD,MAAM,IAAA,cAAM,EAAC,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAEpD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,kCAAkC,UAAU,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC","sourcesContent":["/**\n * npm source: pack + extract to temp directory.\n * Supports --registry for private registries.\n */\n\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport { runCmd } from '@frontmcp/utils';\n\nexport async function fetchFromNpm(pkg: string, tmpDir: string, registryUrl?: string): Promise<string> {\n // npm pack downloads a tarball to the target directory\n const packArgs = ['pack', pkg, '--pack-destination', tmpDir];\n if (registryUrl) {\n packArgs.push('--registry', registryUrl);\n }\n\n await runCmd('npm', packArgs);\n\n // Find the tarball - derive expected name from package to disambiguate\n const files = fs.readdirSync(tmpDir).filter((f: string) => f.endsWith('.tgz'));\n if (files.length === 0) {\n throw new Error(`npm pack did not produce a tarball for \"${pkg}\"`);\n }\n\n // npm pack produces tarballs like scope-name-version.tgz (@ removed, / replaced by -)\n const normalizedPkg = pkg.replace(/^@/, '').replace(/\\//g, '-').replace(/@.*$/, '');\n const match = files.find((f) => f.startsWith(normalizedPkg));\n const tarball = path.join(tmpDir, match ?? files[0]);\n\n // Extract the tarball\n const extractDir = path.join(tmpDir, 'package');\n await runCmd('tar', ['xzf', tarball, '-C', tmpDir]);\n\n if (!fs.existsSync(extractDir)) {\n throw new Error(`Extracted package not found at ${extractDir}`);\n }\n\n return extractDir;\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Install source parsing and types.
|
|
3
3
|
*/
|
|
4
|
-
export type InstallSourceType = 'npm' | 'local' | 'git';
|
|
4
|
+
export type InstallSourceType = 'npm' | 'local' | 'git' | 'esm';
|
|
5
5
|
export interface InstallSource {
|
|
6
6
|
type: InstallSourceType;
|
|
7
7
|
ref: string;
|
|
@@ -20,6 +20,12 @@ export interface FrontmcpRegistry {
|
|
|
20
20
|
type: InstallSourceType;
|
|
21
21
|
ref: string;
|
|
22
22
|
};
|
|
23
|
+
/** Resolved ESM version (for ESM-loaded apps) */
|
|
24
|
+
esmVersion?: string;
|
|
25
|
+
/** Path to cached ESM bundle */
|
|
26
|
+
esmCachePath?: string;
|
|
27
|
+
/** ISO timestamp of last update check */
|
|
28
|
+
lastUpdateCheck?: string;
|
|
23
29
|
}>;
|
|
24
30
|
}
|
|
25
31
|
/**
|
|
@@ -15,6 +15,10 @@ function parseInstallSource(source) {
|
|
|
15
15
|
if (source.startsWith('./') || source.startsWith('../') || source.startsWith('/')) {
|
|
16
16
|
return { type: 'local', ref: source };
|
|
17
17
|
}
|
|
18
|
+
// ESM sources: explicit esm.sh URL or esm: prefix (checked before git to avoid esm:...pkg.git misclassification)
|
|
19
|
+
if (source.startsWith('https://esm.sh/') || source.startsWith('esm:')) {
|
|
20
|
+
return { type: 'esm', ref: source.replace(/^esm:/, '') };
|
|
21
|
+
}
|
|
18
22
|
if (source.startsWith('github:') || source.startsWith('git+') || source.endsWith('.git')) {
|
|
19
23
|
return { type: 'git', ref: source };
|
|
20
24
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/commands/package/types.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAuCH,gDAeC;AAtBD;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAAC,MAAc;IAC/C,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAClF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IACxC,CAAC;IAED,iHAAiH;IACjH,IAAI,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACtE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;IAC3D,CAAC;IAED,IAAI,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACzF,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IACtC,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AACtC,CAAC","sourcesContent":["/**\n * Install source parsing and types.\n */\n\nexport type InstallSourceType = 'npm' | 'local' | 'git' | 'esm';\n\nexport interface InstallSource {\n type: InstallSourceType;\n ref: string;\n}\n\nexport interface FrontmcpRegistry {\n version: 1;\n apps: Record<\n string,\n {\n version: string;\n installDir: string;\n installedAt: string;\n runner: string;\n bundle: string;\n storage: 'sqlite' | 'redis' | 'none';\n port: number;\n source?: { type: InstallSourceType; ref: string };\n /** Resolved ESM version (for ESM-loaded apps) */\n esmVersion?: string;\n /** Path to cached ESM bundle */\n esmCachePath?: string;\n /** ISO timestamp of last update check */\n lastUpdateCheck?: string;\n }\n >;\n}\n\n/**\n * Parse an install source string into a typed source object.\n *\n * - Starts with `./ | ../ | /` → local\n * - Starts with `github:` or `git+` or ends with `.git` → git\n * - Everything else → npm\n */\nexport function parseInstallSource(source: string): InstallSource {\n if (source.startsWith('./') || source.startsWith('../') || source.startsWith('/')) {\n return { type: 'local', ref: source };\n }\n\n // ESM sources: explicit esm.sh URL or esm: prefix (checked before git to avoid esm:...pkg.git misclassification)\n if (source.startsWith('https://esm.sh/') || source.startsWith('esm:')) {\n return { type: 'esm', ref: source.replace(/^esm:/, '') };\n }\n\n if (source.startsWith('github:') || source.startsWith('git+') || source.endsWith('.git')) {\n return { type: 'git', ref: source };\n }\n\n return { type: 'npm', ref: source };\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { ParsedArgs } from '
|
|
1
|
+
import { ParsedArgs } from '../../core/args';
|
|
2
2
|
export declare function runUninstall(opts: ParsedArgs): Promise<void>;
|
|
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.runUninstall = runUninstall;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const fs = tslib_1.__importStar(require("fs"));
|
|
6
|
-
const colors_1 = require("
|
|
6
|
+
const colors_1 = require("../../core/colors");
|
|
7
7
|
const pm_1 = require("../pm");
|
|
8
|
-
const registry_1 = require("./
|
|
8
|
+
const registry_1 = require("./registry");
|
|
9
9
|
async function runUninstall(opts) {
|
|
10
10
|
const name = opts._[1];
|
|
11
11
|
if (!name) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../../../../src/commands/package/uninstall.ts"],"names":[],"mappings":";;AAMA,oCAkCC;;AAxCD,+CAAyB;AAEzB,8CAAsC;AACtC,8BAAuC;AACvC,yCAA6D;AAEtD,KAAK,UAAU,YAAY,CAAC,IAAgB;IACjD,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,GAAG,GAAG,IAAA,2BAAgB,EAAC,IAAI,CAAC,CAAC;IACnC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,qBAAqB,CAAC,CAAC;IACrD,CAAC;IAED,8BAA8B;IAC9B,MAAM,EAAE,GAAG,IAAI,mBAAc,EAAE,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,GAAG,IAAA,UAAC,EAAC,MAAM,EAAE,aAAa,CAAC,2BAA2B,CAAC,CAAC;IACtE,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,iDAAiD;QACjD,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACzE,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5D,OAAO,CAAC,GAAG,CAAC,GAAG,IAAA,UAAC,EAAC,MAAM,EAAE,aAAa,CAAC,YAAY,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,uBAAuB;IACvB,IAAA,wBAAa,EAAC,IAAI,CAAC,CAAC;IAEpB,OAAO,CAAC,GAAG,CAAC,GAAG,IAAA,UAAC,EAAC,OAAO,EAAE,gBAAgB,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;AACzD,CAAC","sourcesContent":["import * as fs from 'fs';\nimport { ParsedArgs } from '../../core/args';\nimport { c } from '../../core/colors';\nimport { ProcessManager } from '../pm';\nimport { getRegisteredApp, unregisterApp } from './registry';\n\nexport async function runUninstall(opts: ParsedArgs): Promise<void> {\n const name = opts._[1];\n if (!name) {\n throw new Error('Missing app name. Usage: frontmcp uninstall <name>');\n }\n\n const app = getRegisteredApp(name);\n if (!app) {\n throw new Error(`App \"${name}\" is not installed.`);\n }\n\n // Stop the process if running\n const pm = new ProcessManager();\n try {\n await pm.stop(name);\n console.log(`${c('cyan', '[uninstall]')} stopped running process.`);\n } catch (err: unknown) {\n // Only ignore \"not found\" / \"not running\" errors\n const msg = err instanceof Error ? err.message : String(err);\n if (!msg.includes('No process found') && !msg.includes('is not running')) {\n throw err;\n }\n }\n\n // Remove app directory\n if (fs.existsSync(app.installDir)) {\n fs.rmSync(app.installDir, { recursive: true, force: true });\n console.log(`${c('cyan', '[uninstall]')} removed ${app.installDir}`);\n }\n\n // Remove from registry\n unregisterApp(name);\n\n console.log(`${c('green', `Uninstalled \"${name}\".`)}`);\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Table formatting for process status / list output.
|
|
3
3
|
*/
|
|
4
|
-
import { ProcessInfo } from './
|
|
4
|
+
import { ProcessInfo } from './types';
|
|
5
5
|
export declare function formatProcessTable(processes: ProcessInfo[]): string;
|
|
6
6
|
export declare function formatUptime(startedAt: string): string;
|
|
7
7
|
export declare function formatProcessDetail(p: ProcessInfo): string;
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.formatProcessTable = formatProcessTable;
|
|
7
7
|
exports.formatUptime = formatUptime;
|
|
8
8
|
exports.formatProcessDetail = formatProcessDetail;
|
|
9
|
-
const colors_1 = require("
|
|
9
|
+
const colors_1 = require("../../core/colors");
|
|
10
10
|
function formatProcessTable(processes) {
|
|
11
11
|
if (processes.length === 0) {
|
|
12
12
|
return (0, colors_1.c)('gray', 'No managed processes found.');
|
|
@@ -94,4 +94,4 @@ function formatProcessDetail(p) {
|
|
|
94
94
|
lines.push(`${(0, colors_1.c)('bold', 'CLI Version:')} ${p.cliVersion}`);
|
|
95
95
|
return lines.join('\n');
|
|
96
96
|
}
|
|
97
|
-
//# sourceMappingURL=
|
|
97
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../../src/commands/pm/format.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Table formatting for process status / list output.\n */\n\nimport { ProcessInfo } from './types';\nimport { c } from '../../core/colors';\n\nexport function formatProcessTable(processes: ProcessInfo[]): string {\n if (processes.length === 0) {\n return c('gray', 'No managed processes found.');\n }\n\n const headers = ['Name', 'PID', 'Status', 'Port', 'Uptime', 'Restarts'];\n const rows: string[][] = processes.map((p) => [\n p.name,\n String(p.pid),\n formatStatus(p.status),\n p.port ? String(p.port) : p.socketPath ? 'socket' : '-',\n p.status === 'running' ? p.uptime : '-',\n String(p.restartCount),\n ]);\n\n return formatTable(headers, rows);\n}\n\nfunction formatStatus(status: string): string {\n switch (status) {\n case 'running':\n return c('green', 'running');\n case 'stopped':\n return c('yellow', 'stopped');\n case 'dead':\n return c('red', 'dead');\n default:\n return c('gray', status);\n }\n}\n\nexport function formatUptime(startedAt: string): string {\n const start = new Date(startedAt).getTime();\n const now = Date.now();\n const diff = now - start;\n\n const seconds = Math.floor(diff / 1000);\n if (seconds < 60) return `${seconds}s`;\n\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ${seconds % 60}s`;\n\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ${minutes % 60}m`;\n\n const days = Math.floor(hours / 24);\n return `${days}d ${hours % 24}h`;\n}\n\nfunction formatTable(headers: string[], rows: string[][]): string {\n // Calculate column widths\n const widths = headers.map((h, i) => {\n const maxRow = rows.reduce((max, row) => {\n const len = stripAnsi(row[i]).length;\n return len > max ? len : max;\n }, 0);\n return Math.max(stripAnsi(h).length, maxRow);\n });\n\n const separator = widths.map((w) => '─'.repeat(w + 2)).join('┼');\n const headerLine = headers.map((h, i) => ` ${c('bold', padRight(h, widths[i]))} `).join('│');\n\n const bodyLines = rows.map((row) => row.map((cell, i) => ` ${padRight(cell, widths[i])} `).join('│'));\n\n return [headerLine, separator, ...bodyLines].join('\\n');\n}\n\nfunction padRight(str: string, width: number): string {\n const visibleLen = stripAnsi(str).length;\n const padding = Math.max(0, width - visibleLen);\n return str + ' '.repeat(padding);\n}\n\n// eslint-disable-next-line no-control-regex\nconst ANSI_REGEX = new RegExp('\\\\x1b\\\\[[0-9;]*m', 'g');\n\nfunction stripAnsi(str: string): string {\n return str.replace(ANSI_REGEX, '');\n}\n\nexport function formatProcessDetail(p: ProcessInfo): string {\n const lines = [\n `${c('bold', 'Name:')} ${p.name}`,\n `${c('bold', 'PID:')} ${p.pid}`,\n `${c('bold', 'Supervisor:')} ${p.supervisorPid}`,\n `${c('bold', 'Status:')} ${formatStatus(p.status)}`,\n `${c('bold', 'Entry:')} ${p.entry}`,\n ];\n\n if (p.port) lines.push(`${c('bold', 'Port:')} ${p.port}`);\n if (p.socketPath) lines.push(`${c('bold', 'Socket:')} ${p.socketPath}`);\n if (p.dbPath) lines.push(`${c('bold', 'Database:')} ${p.dbPath}`);\n\n lines.push(`${c('bold', 'Started:')} ${p.startedAt}`);\n lines.push(`${c('bold', 'Uptime:')} ${p.status === 'running' ? p.uptime : '-'}`);\n lines.push(`${c('bold', 'Restarts:')} ${p.restartCount}`);\n lines.push(`${c('bold', 'CLI Version:')} ${p.cliVersion}`);\n\n return lines.join('\\n');\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../../../src/commands/pm/health.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAWH,kCA0DC;;AAnED,mDAA6B;AAS7B,SAAgB,WAAW,CAAC,IAI3B;IACC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,WAAW,GAAwB;YACvC,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,SAAS;YACf,OAAO;SACR,CAAC;QAEF,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,WAAW,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAC3C,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACrB,WAAW,CAAC,QAAQ,GAAG,WAAW,CAAC;YACnC,WAAW,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC;gBACN,OAAO,EAAE,KAAK;gBACd,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;gBAChC,KAAK,EAAE,iCAAiC;aACzC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE;YAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;YACxC,OAAO,CAAC;gBACN,OAAO,EAAE,GAAG,CAAC,UAAU,KAAK,GAAG;gBAC/B,UAAU,EAAE,GAAG,CAAC,UAAU;gBAC1B,YAAY;aACb,CAAC,CAAC;YACH,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,qBAAqB;QACrC,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACtB,OAAO,CAAC;gBACN,OAAO,EAAE,KAAK;gBACd,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;gBAChC,KAAK,EAAE,GAAG,CAAC,OAAO;aACnB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YACrB,GAAG,CAAC,OAAO,EAAE,CAAC;YACd,OAAO,CAAC;gBACN,OAAO,EAAE,KAAK;gBACd,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;gBAChC,KAAK,EAAE,wBAAwB;aAChC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,GAAG,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * HTTP health checks against running MCP servers.\n * Supports both TCP (port) and Unix socket connections.\n */\n\nimport * as http from 'http';\n\nexport interface HealthCheckResult {\n healthy: boolean;\n statusCode?: number;\n responseTime: number;\n error?: string;\n}\n\nexport function checkHealth(opts: {\n port?: number;\n socketPath?: string;\n timeout?: number;\n}): Promise<HealthCheckResult> {\n const timeout = opts.timeout ?? 5000;\n const start = Date.now();\n\n return new Promise((resolve) => {\n const requestOpts: http.RequestOptions = {\n method: 'GET',\n path: '/health',\n timeout,\n };\n\n if (opts.socketPath) {\n requestOpts.socketPath = opts.socketPath;\n } else if (opts.port) {\n requestOpts.hostname = '127.0.0.1';\n requestOpts.port = opts.port;\n } else {\n resolve({\n healthy: false,\n responseTime: Date.now() - start,\n error: 'No port or socket path provided',\n });\n return;\n }\n\n const req = http.request(requestOpts, (res) => {\n const responseTime = Date.now() - start;\n resolve({\n healthy: res.statusCode === 200,\n statusCode: res.statusCode,\n responseTime,\n });\n res.resume(); // drain the response\n });\n\n req.on('error', (err) => {\n resolve({\n healthy: false,\n responseTime: Date.now() - start,\n error: err.message,\n });\n });\n\n req.on('timeout', () => {\n req.destroy();\n resolve({\n healthy: false,\n responseTime: Date.now() - start,\n error: 'Health check timed out',\n });\n });\n\n req.end();\n });\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { ProcessManager } from './manager';
|
|
2
|
+
export { Supervisor } from './spawn';
|
|
3
|
+
export { checkHealth } from './health';
|
|
4
|
+
export { installService, uninstallService, detectPlatform, getServicePath } from './service-gen';
|
|
5
|
+
export { formatProcessTable, formatProcessDetail, formatUptime } from './format';
|
|
6
|
+
export { tailLog, followLog, createLogStreams } from './log-utils';
|
|
7
|
+
export { writePidFile, readPidFile, removePidFile, isProcessAlive, listPidFiles } from './pidfile';
|
|
8
|
+
export { PM_DIRS, pidFilePath, logFilePath, socketFilePath, appDir, ensurePmDirs } from './paths';
|
|
9
|
+
export type { PidFileData, StartOptions, StopOptions, ProcessInfo, LogsOptions, ServicePlatform } from './types';
|
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ensurePmDirs = exports.appDir = exports.socketFilePath = exports.logFilePath = exports.pidFilePath = exports.PM_DIRS = exports.listPidFiles = exports.isProcessAlive = exports.removePidFile = exports.readPidFile = exports.writePidFile = exports.createLogStreams = exports.followLog = exports.tailLog = exports.formatUptime = exports.formatProcessDetail = exports.formatProcessTable = exports.getServicePath = exports.detectPlatform = exports.uninstallService = exports.installService = exports.checkHealth = exports.Supervisor = exports.ProcessManager = void 0;
|
|
4
|
-
var
|
|
5
|
-
Object.defineProperty(exports, "ProcessManager", { enumerable: true, get: function () { return
|
|
6
|
-
var
|
|
7
|
-
Object.defineProperty(exports, "Supervisor", { enumerable: true, get: function () { return
|
|
8
|
-
var
|
|
9
|
-
Object.defineProperty(exports, "checkHealth", { enumerable: true, get: function () { return
|
|
10
|
-
var
|
|
11
|
-
Object.defineProperty(exports, "installService", { enumerable: true, get: function () { return
|
|
12
|
-
Object.defineProperty(exports, "uninstallService", { enumerable: true, get: function () { return
|
|
13
|
-
Object.defineProperty(exports, "detectPlatform", { enumerable: true, get: function () { return
|
|
14
|
-
Object.defineProperty(exports, "getServicePath", { enumerable: true, get: function () { return
|
|
15
|
-
var
|
|
16
|
-
Object.defineProperty(exports, "formatProcessTable", { enumerable: true, get: function () { return
|
|
17
|
-
Object.defineProperty(exports, "formatProcessDetail", { enumerable: true, get: function () { return
|
|
18
|
-
Object.defineProperty(exports, "formatUptime", { enumerable: true, get: function () { return
|
|
19
|
-
var
|
|
20
|
-
Object.defineProperty(exports, "tailLog", { enumerable: true, get: function () { return
|
|
21
|
-
Object.defineProperty(exports, "followLog", { enumerable: true, get: function () { return
|
|
22
|
-
Object.defineProperty(exports, "createLogStreams", { enumerable: true, get: function () { return
|
|
23
|
-
var
|
|
24
|
-
Object.defineProperty(exports, "writePidFile", { enumerable: true, get: function () { return
|
|
25
|
-
Object.defineProperty(exports, "readPidFile", { enumerable: true, get: function () { return
|
|
26
|
-
Object.defineProperty(exports, "removePidFile", { enumerable: true, get: function () { return
|
|
27
|
-
Object.defineProperty(exports, "isProcessAlive", { enumerable: true, get: function () { return
|
|
28
|
-
Object.defineProperty(exports, "listPidFiles", { enumerable: true, get: function () { return
|
|
29
|
-
var
|
|
30
|
-
Object.defineProperty(exports, "PM_DIRS", { enumerable: true, get: function () { return
|
|
31
|
-
Object.defineProperty(exports, "pidFilePath", { enumerable: true, get: function () { return
|
|
32
|
-
Object.defineProperty(exports, "logFilePath", { enumerable: true, get: function () { return
|
|
33
|
-
Object.defineProperty(exports, "socketFilePath", { enumerable: true, get: function () { return
|
|
34
|
-
Object.defineProperty(exports, "appDir", { enumerable: true, get: function () { return
|
|
35
|
-
Object.defineProperty(exports, "ensurePmDirs", { enumerable: true, get: function () { return
|
|
4
|
+
var manager_1 = require("./manager");
|
|
5
|
+
Object.defineProperty(exports, "ProcessManager", { enumerable: true, get: function () { return manager_1.ProcessManager; } });
|
|
6
|
+
var spawn_1 = require("./spawn");
|
|
7
|
+
Object.defineProperty(exports, "Supervisor", { enumerable: true, get: function () { return spawn_1.Supervisor; } });
|
|
8
|
+
var health_1 = require("./health");
|
|
9
|
+
Object.defineProperty(exports, "checkHealth", { enumerable: true, get: function () { return health_1.checkHealth; } });
|
|
10
|
+
var service_gen_1 = require("./service-gen");
|
|
11
|
+
Object.defineProperty(exports, "installService", { enumerable: true, get: function () { return service_gen_1.installService; } });
|
|
12
|
+
Object.defineProperty(exports, "uninstallService", { enumerable: true, get: function () { return service_gen_1.uninstallService; } });
|
|
13
|
+
Object.defineProperty(exports, "detectPlatform", { enumerable: true, get: function () { return service_gen_1.detectPlatform; } });
|
|
14
|
+
Object.defineProperty(exports, "getServicePath", { enumerable: true, get: function () { return service_gen_1.getServicePath; } });
|
|
15
|
+
var format_1 = require("./format");
|
|
16
|
+
Object.defineProperty(exports, "formatProcessTable", { enumerable: true, get: function () { return format_1.formatProcessTable; } });
|
|
17
|
+
Object.defineProperty(exports, "formatProcessDetail", { enumerable: true, get: function () { return format_1.formatProcessDetail; } });
|
|
18
|
+
Object.defineProperty(exports, "formatUptime", { enumerable: true, get: function () { return format_1.formatUptime; } });
|
|
19
|
+
var log_utils_1 = require("./log-utils");
|
|
20
|
+
Object.defineProperty(exports, "tailLog", { enumerable: true, get: function () { return log_utils_1.tailLog; } });
|
|
21
|
+
Object.defineProperty(exports, "followLog", { enumerable: true, get: function () { return log_utils_1.followLog; } });
|
|
22
|
+
Object.defineProperty(exports, "createLogStreams", { enumerable: true, get: function () { return log_utils_1.createLogStreams; } });
|
|
23
|
+
var pidfile_1 = require("./pidfile");
|
|
24
|
+
Object.defineProperty(exports, "writePidFile", { enumerable: true, get: function () { return pidfile_1.writePidFile; } });
|
|
25
|
+
Object.defineProperty(exports, "readPidFile", { enumerable: true, get: function () { return pidfile_1.readPidFile; } });
|
|
26
|
+
Object.defineProperty(exports, "removePidFile", { enumerable: true, get: function () { return pidfile_1.removePidFile; } });
|
|
27
|
+
Object.defineProperty(exports, "isProcessAlive", { enumerable: true, get: function () { return pidfile_1.isProcessAlive; } });
|
|
28
|
+
Object.defineProperty(exports, "listPidFiles", { enumerable: true, get: function () { return pidfile_1.listPidFiles; } });
|
|
29
|
+
var paths_1 = require("./paths");
|
|
30
|
+
Object.defineProperty(exports, "PM_DIRS", { enumerable: true, get: function () { return paths_1.PM_DIRS; } });
|
|
31
|
+
Object.defineProperty(exports, "pidFilePath", { enumerable: true, get: function () { return paths_1.pidFilePath; } });
|
|
32
|
+
Object.defineProperty(exports, "logFilePath", { enumerable: true, get: function () { return paths_1.logFilePath; } });
|
|
33
|
+
Object.defineProperty(exports, "socketFilePath", { enumerable: true, get: function () { return paths_1.socketFilePath; } });
|
|
34
|
+
Object.defineProperty(exports, "appDir", { enumerable: true, get: function () { return paths_1.appDir; } });
|
|
35
|
+
Object.defineProperty(exports, "ensurePmDirs", { enumerable: true, get: function () { return paths_1.ensurePmDirs; } });
|
|
36
36
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/commands/pm/index.ts"],"names":[],"mappings":";;;AAAA,qCAA2C;AAAlC,yGAAA,cAAc,OAAA;AACvB,iCAAqC;AAA5B,mGAAA,UAAU,OAAA;AACnB,mCAAuC;AAA9B,qGAAA,WAAW,OAAA;AACpB,6CAAiG;AAAxF,6GAAA,cAAc,OAAA;AAAE,+GAAA,gBAAgB,OAAA;AAAE,6GAAA,cAAc,OAAA;AAAE,6GAAA,cAAc,OAAA;AACzE,mCAAiF;AAAxE,4GAAA,kBAAkB,OAAA;AAAE,6GAAA,mBAAmB,OAAA;AAAE,sGAAA,YAAY,OAAA;AAC9D,yCAAmE;AAA1D,oGAAA,OAAO,OAAA;AAAE,sGAAA,SAAS,OAAA;AAAE,6GAAA,gBAAgB,OAAA;AAC7C,qCAAmG;AAA1F,uGAAA,YAAY,OAAA;AAAE,sGAAA,WAAW,OAAA;AAAE,wGAAA,aAAa,OAAA;AAAE,yGAAA,cAAc,OAAA;AAAE,uGAAA,YAAY,OAAA;AAC/E,iCAAkG;AAAzF,gGAAA,OAAO,OAAA;AAAE,oGAAA,WAAW,OAAA;AAAE,oGAAA,WAAW,OAAA;AAAE,uGAAA,cAAc,OAAA;AAAE,+FAAA,MAAM,OAAA;AAAE,qGAAA,YAAY,OAAA","sourcesContent":["export { ProcessManager } from './manager';\nexport { Supervisor } from './spawn';\nexport { checkHealth } from './health';\nexport { installService, uninstallService, detectPlatform, getServicePath } from './service-gen';\nexport { formatProcessTable, formatProcessDetail, formatUptime } from './format';\nexport { tailLog, followLog, createLogStreams } from './log-utils';\nexport { writePidFile, readPidFile, removePidFile, isProcessAlive, listPidFiles } from './pidfile';\nexport { PM_DIRS, pidFilePath, logFilePath, socketFilePath, appDir, ensurePmDirs } from './paths';\nexport type { PidFileData, StartOptions, StopOptions, ProcessInfo, LogsOptions, ServicePlatform } from './types';\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { ParsedArgs } from '
|
|
1
|
+
import { ParsedArgs } from '../../core/args';
|
|
2
2
|
export declare function runList(_opts: ParsedArgs): Promise<void>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.runList = runList;
|
|
4
|
-
const
|
|
4
|
+
const _1 = require(".");
|
|
5
5
|
async function runList(_opts) {
|
|
6
|
-
const pm = new
|
|
6
|
+
const pm = new _1.ProcessManager();
|
|
7
7
|
const all = pm.listAll();
|
|
8
|
-
console.log((0,
|
|
8
|
+
console.log((0, _1.formatProcessTable)(all));
|
|
9
9
|
}
|
|
10
10
|
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../../src/commands/pm/list.ts"],"names":[],"mappings":";;AAGA,0BAIC;AAND,wBAAuD;AAEhD,KAAK,UAAU,OAAO,CAAC,KAAiB;IAC7C,MAAM,EAAE,GAAG,IAAI,iBAAc,EAAE,CAAC;IAChC,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IACzB,OAAO,CAAC,GAAG,CAAC,IAAA,qBAAkB,EAAC,GAAG,CAAC,CAAC,CAAC;AACvC,CAAC","sourcesContent":["import { ParsedArgs } from '../../core/args';\nimport { ProcessManager, formatProcessTable } from '.';\n\nexport async function runList(_opts: ParsedArgs): Promise<void> {\n const pm = new ProcessManager();\n const all = pm.listAll();\n console.log(formatProcessTable(all));\n}\n"]}
|
|
@@ -10,13 +10,13 @@ exports.listLogFiles = listLogFiles;
|
|
|
10
10
|
const tslib_1 = require("tslib");
|
|
11
11
|
const fs = tslib_1.__importStar(require("fs"));
|
|
12
12
|
const path = tslib_1.__importStar(require("path"));
|
|
13
|
-
const
|
|
13
|
+
const paths_1 = require("./paths");
|
|
14
14
|
const MAX_LOG_SIZE = 10 * 1024 * 1024; // 10 MB
|
|
15
15
|
const MAX_ROTATED_FILES = 5;
|
|
16
16
|
function createLogStreams(name) {
|
|
17
|
-
(0,
|
|
18
|
-
const outPath = (0,
|
|
19
|
-
const errPath = (0,
|
|
17
|
+
(0, paths_1.ensurePmDirs)();
|
|
18
|
+
const outPath = (0, paths_1.logFilePath)(name);
|
|
19
|
+
const errPath = (0, paths_1.errorLogFilePath)(name);
|
|
20
20
|
rotateIfNeeded(outPath);
|
|
21
21
|
rotateIfNeeded(errPath);
|
|
22
22
|
return {
|
|
@@ -52,7 +52,7 @@ function rotateIfNeeded(filePath) {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
function tailLog(name, lines) {
|
|
55
|
-
const filePath = (0,
|
|
55
|
+
const filePath = (0, paths_1.logFilePath)(name);
|
|
56
56
|
if (!fs.existsSync(filePath))
|
|
57
57
|
return [];
|
|
58
58
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
@@ -60,8 +60,8 @@ function tailLog(name, lines) {
|
|
|
60
60
|
return allLines.slice(-lines).filter((l) => l.length > 0);
|
|
61
61
|
}
|
|
62
62
|
function followLog(name, onLine) {
|
|
63
|
-
const filePath = (0,
|
|
64
|
-
(0,
|
|
63
|
+
const filePath = (0, paths_1.logFilePath)(name);
|
|
64
|
+
(0, paths_1.ensurePmDirs)();
|
|
65
65
|
// Create the file if it doesn't exist
|
|
66
66
|
if (!fs.existsSync(filePath)) {
|
|
67
67
|
fs.writeFileSync(filePath, '', 'utf-8');
|
|
@@ -97,7 +97,7 @@ function followLog(name, onLine) {
|
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
99
|
function listLogFiles(name) {
|
|
100
|
-
const logsDir =
|
|
100
|
+
const logsDir = paths_1.PM_DIRS.logs;
|
|
101
101
|
if (!fs.existsSync(logsDir))
|
|
102
102
|
return [];
|
|
103
103
|
return fs
|
|
@@ -105,4 +105,4 @@ function listLogFiles(name) {
|
|
|
105
105
|
.filter((f) => f.startsWith(name))
|
|
106
106
|
.map((f) => path.join(logsDir, f));
|
|
107
107
|
}
|
|
108
|
-
//# sourceMappingURL=
|
|
108
|
+
//# sourceMappingURL=log-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-utils.js","sourceRoot":"","sources":["../../../../src/commands/pm/log-utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Log stream creation, rotation, tail, and follow utilities.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { logFilePath, errorLogFilePath, ensurePmDirs, PM_DIRS } from './paths';\n\nconst MAX_LOG_SIZE = 10 * 1024 * 1024; // 10 MB\nconst MAX_ROTATED_FILES = 5;\n\nexport function createLogStreams(name: string): {\n stdout: fs.WriteStream;\n stderr: fs.WriteStream;\n} {\n ensurePmDirs();\n const outPath = logFilePath(name);\n const errPath = errorLogFilePath(name);\n\n rotateIfNeeded(outPath);\n rotateIfNeeded(errPath);\n\n return {\n stdout: fs.createWriteStream(outPath, { flags: 'a' }),\n stderr: fs.createWriteStream(errPath, { flags: 'a' }),\n };\n}\n\nfunction rotateIfNeeded(filePath: string): void {\n try {\n if (!fs.existsSync(filePath)) return;\n const stat = fs.statSync(filePath);\n if (stat.size < MAX_LOG_SIZE) return;\n\n // Shift existing rotated files\n for (let i = MAX_ROTATED_FILES; i >= 1; i--) {\n const from = `${filePath}.${i}`;\n const to = `${filePath}.${i + 1}`;\n if (fs.existsSync(from)) {\n if (i === MAX_ROTATED_FILES) {\n fs.unlinkSync(from);\n } else {\n fs.renameSync(from, to);\n }\n }\n }\n\n // Rotate current file\n fs.renameSync(filePath, `${filePath}.1`);\n } catch {\n // ignore rotation errors\n }\n}\n\nexport function tailLog(name: string, lines: number): string[] {\n const filePath = logFilePath(name);\n if (!fs.existsSync(filePath)) return [];\n\n const content = fs.readFileSync(filePath, 'utf-8');\n const allLines = content.split('\\n');\n return allLines.slice(-lines).filter((l) => l.length > 0);\n}\n\nexport function followLog(name: string, onLine: (line: string) => void): () => void {\n const filePath = logFilePath(name);\n ensurePmDirs();\n\n // Create the file if it doesn't exist\n if (!fs.existsSync(filePath)) {\n fs.writeFileSync(filePath, '', 'utf-8');\n }\n\n let position = fs.statSync(filePath).size;\n\n fs.watchFile(filePath, { interval: 300 }, () => {\n try {\n const stat = fs.statSync(filePath);\n if (stat.size <= position) {\n // File was truncated or rotated\n position = 0;\n }\n if (stat.size > position) {\n const fd = fs.openSync(filePath, 'r');\n const buffer = Buffer.alloc(stat.size - position);\n fs.readSync(fd, buffer, 0, buffer.length, position);\n fs.closeSync(fd);\n position = stat.size;\n\n const chunk = buffer.toString('utf-8');\n const lines = chunk.split('\\n');\n for (const line of lines) {\n if (line.length > 0) onLine(line);\n }\n }\n } catch {\n // ignore read errors\n }\n });\n\n return () => {\n fs.unwatchFile(filePath);\n };\n}\n\nexport function listLogFiles(name: string): string[] {\n const logsDir = PM_DIRS.logs;\n if (!fs.existsSync(logsDir)) return [];\n\n return fs\n .readdirSync(logsDir)\n .filter((f: string) => f.startsWith(name))\n .map((f: string) => path.join(logsDir, f));\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { ParsedArgs } from '
|
|
1
|
+
import { ParsedArgs } from '../../core/args';
|
|
2
2
|
export declare function runLogs(opts: ParsedArgs): Promise<void>;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.runLogs = runLogs;
|
|
4
|
-
const colors_1 = require("
|
|
5
|
-
const
|
|
4
|
+
const colors_1 = require("../../core/colors");
|
|
5
|
+
const _1 = require(".");
|
|
6
6
|
async function runLogs(opts) {
|
|
7
7
|
const name = opts._[1];
|
|
8
8
|
if (!name) {
|
|
9
9
|
throw new Error('Missing process name. Usage: frontmcp logs <name> [--follow] [--lines N]');
|
|
10
10
|
}
|
|
11
|
-
const pidData = (0,
|
|
11
|
+
const pidData = (0, _1.readPidFile)(name);
|
|
12
12
|
if (!pidData) {
|
|
13
13
|
console.log((0, colors_1.c)('yellow', `No process found with name "${name}". No logs available.`));
|
|
14
14
|
return;
|
|
@@ -16,12 +16,12 @@ async function runLogs(opts) {
|
|
|
16
16
|
const lines = opts.lines ?? 50;
|
|
17
17
|
if (opts.follow) {
|
|
18
18
|
// Show recent lines first
|
|
19
|
-
const recent = (0,
|
|
19
|
+
const recent = (0, _1.tailLog)(name, lines);
|
|
20
20
|
for (const line of recent) {
|
|
21
21
|
console.log(line);
|
|
22
22
|
}
|
|
23
23
|
console.log((0, colors_1.c)('gray', `--- following logs for "${name}" (Ctrl+C to stop) ---`));
|
|
24
|
-
const stop = (0,
|
|
24
|
+
const stop = (0, _1.followLog)(name, (line) => {
|
|
25
25
|
console.log(line);
|
|
26
26
|
});
|
|
27
27
|
await new Promise((resolve) => {
|
|
@@ -36,7 +36,7 @@ async function runLogs(opts) {
|
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
else {
|
|
39
|
-
const logLines = (0,
|
|
39
|
+
const logLines = (0, _1.tailLog)(name, lines);
|
|
40
40
|
if (logLines.length === 0) {
|
|
41
41
|
console.log((0, colors_1.c)('gray', `No log output for "${name}".`));
|
|
42
42
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../../../src/commands/pm/logs.ts"],"names":[],"mappings":";;AAIA,0BA+CC;AAlDD,8CAAsC;AACtC,wBAAoD;AAE7C,KAAK,UAAU,OAAO,CAAC,IAAgB;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAC;IAC9F,CAAC;IAED,MAAM,OAAO,GAAG,IAAA,cAAW,EAAC,IAAI,CAAC,CAAC;IAClC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,IAAA,UAAC,EAAC,QAAQ,EAAE,+BAA+B,IAAI,uBAAuB,CAAC,CAAC,CAAC;QACrF,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;IAE/B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,0BAA0B;QAC1B,MAAM,MAAM,GAAG,IAAA,UAAO,EAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACpC,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,IAAA,UAAC,EAAC,MAAM,EAAE,2BAA2B,IAAI,wBAAwB,CAAC,CAAC,CAAC;QAEhF,MAAM,IAAI,GAAG,IAAA,YAAS,EAAC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;YACpC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;QAEH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAClC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;gBAC1B,IAAI,EAAE,CAAC;gBACP,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;gBAC3B,IAAI,EAAE,CAAC;gBACP,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,QAAQ,GAAG,IAAA,UAAO,EAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACtC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,IAAA,UAAC,EAAC,MAAM,EAAE,sBAAsB,IAAI,IAAI,CAAC,CAAC,CAAC;QACzD,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;gBAC5B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { ParsedArgs } from '../../core/args';\nimport { c } from '../../core/colors';\nimport { tailLog, followLog, readPidFile } from '.';\n\nexport async function runLogs(opts: ParsedArgs): Promise<void> {\n const name = opts._[1];\n if (!name) {\n throw new Error('Missing process name. Usage: frontmcp logs <name> [--follow] [--lines N]');\n }\n\n const pidData = readPidFile(name);\n if (!pidData) {\n console.log(c('yellow', `No process found with name \"${name}\". No logs available.`));\n return;\n }\n\n const lines = opts.lines ?? 50;\n\n if (opts.follow) {\n // Show recent lines first\n const recent = tailLog(name, lines);\n for (const line of recent) {\n console.log(line);\n }\n\n console.log(c('gray', `--- following logs for \"${name}\" (Ctrl+C to stop) ---`));\n\n const stop = followLog(name, (line) => {\n console.log(line);\n });\n\n await new Promise<void>((resolve) => {\n process.once('SIGINT', () => {\n stop();\n resolve();\n });\n process.once('SIGTERM', () => {\n stop();\n resolve();\n });\n });\n } else {\n const logLines = tailLog(name, lines);\n if (logLines.length === 0) {\n console.log(c('gray', `No log output for \"${name}\".`));\n } else {\n for (const line of logLines) {\n console.log(line);\n }\n }\n }\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ProcessManager class — orchestrates all PM modules.
|
|
3
3
|
*/
|
|
4
|
-
import { StartOptions, StopOptions, ProcessInfo } from './
|
|
4
|
+
import { StartOptions, StopOptions, ProcessInfo } from './types';
|
|
5
5
|
export declare class ProcessManager {
|
|
6
6
|
start(opts: StartOptions): Promise<ProcessInfo>;
|
|
7
7
|
stop(name: string, opts?: StopOptions): Promise<void>;
|
|
@@ -4,23 +4,23 @@
|
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.ProcessManager = void 0;
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
7
|
+
const pidfile_1 = require("./pidfile");
|
|
8
|
+
const format_1 = require("./format");
|
|
9
|
+
const spawn_1 = require("./spawn");
|
|
10
10
|
// Track running supervisors in this process
|
|
11
11
|
const supervisors = new Map();
|
|
12
12
|
class ProcessManager {
|
|
13
13
|
async start(opts) {
|
|
14
14
|
// Check if already running
|
|
15
|
-
const existing = (0,
|
|
16
|
-
if (existing && (0,
|
|
15
|
+
const existing = (0, pidfile_1.readPidFile)(opts.name);
|
|
16
|
+
if (existing && (0, pidfile_1.isProcessAlive)(existing.pid)) {
|
|
17
17
|
throw new Error(`Process "${opts.name}" is already running (PID: ${existing.pid}). Stop it first with: frontmcp stop ${opts.name}`);
|
|
18
18
|
}
|
|
19
19
|
// Clean up stale PID file
|
|
20
20
|
if (existing) {
|
|
21
|
-
(0,
|
|
21
|
+
(0, pidfile_1.removePidFile)(opts.name);
|
|
22
22
|
}
|
|
23
|
-
const supervisor = new
|
|
23
|
+
const supervisor = new spawn_1.Supervisor(opts);
|
|
24
24
|
await supervisor.start();
|
|
25
25
|
supervisors.set(opts.name, supervisor);
|
|
26
26
|
// Wait briefly for child to spawn
|
|
@@ -39,12 +39,12 @@ class ProcessManager {
|
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
41
41
|
// No local supervisor — try to kill by PID file
|
|
42
|
-
const pidData = (0,
|
|
42
|
+
const pidData = (0, pidfile_1.readPidFile)(name);
|
|
43
43
|
if (!pidData) {
|
|
44
44
|
throw new Error(`No process found with name "${name}"`);
|
|
45
45
|
}
|
|
46
|
-
if (!(0,
|
|
47
|
-
(0,
|
|
46
|
+
if (!(0, pidfile_1.isProcessAlive)(pidData.pid)) {
|
|
47
|
+
(0, pidfile_1.removePidFile)(name);
|
|
48
48
|
throw new Error(`Process "${name}" is not running (stale PID file removed)`);
|
|
49
49
|
}
|
|
50
50
|
// Try graceful shutdown via supervisor PID first, then process PID
|
|
@@ -70,12 +70,12 @@ class ProcessManager {
|
|
|
70
70
|
const timeout = opts.timeout ?? 10000;
|
|
71
71
|
const start = Date.now();
|
|
72
72
|
while (Date.now() - start < timeout) {
|
|
73
|
-
if (!(0,
|
|
73
|
+
if (!(0, pidfile_1.isProcessAlive)(pidData.pid))
|
|
74
74
|
break;
|
|
75
75
|
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
76
76
|
}
|
|
77
77
|
// Force kill if still alive
|
|
78
|
-
if ((0,
|
|
78
|
+
if ((0, pidfile_1.isProcessAlive)(pidData.pid)) {
|
|
79
79
|
try {
|
|
80
80
|
process.kill(pidData.pid, 'SIGKILL');
|
|
81
81
|
}
|
|
@@ -84,10 +84,10 @@ class ProcessManager {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
-
(0,
|
|
87
|
+
(0, pidfile_1.removePidFile)(name);
|
|
88
88
|
}
|
|
89
89
|
async restart(name) {
|
|
90
|
-
const pidData = (0,
|
|
90
|
+
const pidData = (0, pidfile_1.readPidFile)(name);
|
|
91
91
|
if (!pidData) {
|
|
92
92
|
throw new Error(`No process found with name "${name}". Cannot restart.`);
|
|
93
93
|
}
|
|
@@ -109,10 +109,10 @@ class ProcessManager {
|
|
|
109
109
|
});
|
|
110
110
|
}
|
|
111
111
|
getProcessInfo(name) {
|
|
112
|
-
const pidData = (0,
|
|
112
|
+
const pidData = (0, pidfile_1.readPidFile)(name);
|
|
113
113
|
if (!pidData)
|
|
114
114
|
return null;
|
|
115
|
-
const alive = (0,
|
|
115
|
+
const alive = (0, pidfile_1.isProcessAlive)(pidData.pid);
|
|
116
116
|
return {
|
|
117
117
|
name: pidData.name,
|
|
118
118
|
pid: pidData.pid,
|
|
@@ -124,14 +124,14 @@ class ProcessManager {
|
|
|
124
124
|
dbPath: pidData.dbPath,
|
|
125
125
|
startedAt: pidData.startedAt,
|
|
126
126
|
restartCount: pidData.restartCount,
|
|
127
|
-
uptime: alive ? (0,
|
|
127
|
+
uptime: alive ? (0, format_1.formatUptime)(pidData.startedAt) : '-',
|
|
128
128
|
cliVersion: pidData.cliVersion,
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
131
|
listAll() {
|
|
132
|
-
const pidFiles = (0,
|
|
132
|
+
const pidFiles = (0, pidfile_1.listPidFiles)();
|
|
133
133
|
return pidFiles.map((data) => {
|
|
134
|
-
const alive = (0,
|
|
134
|
+
const alive = (0, pidfile_1.isProcessAlive)(data.pid);
|
|
135
135
|
return {
|
|
136
136
|
name: data.name,
|
|
137
137
|
pid: data.pid,
|
|
@@ -143,11 +143,11 @@ class ProcessManager {
|
|
|
143
143
|
dbPath: data.dbPath,
|
|
144
144
|
startedAt: data.startedAt,
|
|
145
145
|
restartCount: data.restartCount,
|
|
146
|
-
uptime: alive ? (0,
|
|
146
|
+
uptime: alive ? (0, format_1.formatUptime)(data.startedAt) : '-',
|
|
147
147
|
cliVersion: data.cliVersion,
|
|
148
148
|
};
|
|
149
149
|
});
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
exports.ProcessManager = ProcessManager;
|
|
153
|
-
//# sourceMappingURL=
|
|
153
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../../src/commands/pm/manager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * ProcessManager class — orchestrates all PM modules.\n */\n\nimport { readPidFile, isProcessAlive, listPidFiles, removePidFile } from './pidfile';\nimport { formatUptime } from './format';\nimport { Supervisor } from './spawn';\nimport { StartOptions, StopOptions, ProcessInfo } from './types';\n\n// Track running supervisors in this process\nconst supervisors = new Map<string, Supervisor>();\n\nexport class ProcessManager {\n async start(opts: StartOptions): Promise<ProcessInfo> {\n // Check if already running\n const existing = readPidFile(opts.name);\n if (existing && isProcessAlive(existing.pid)) {\n throw new Error(\n `Process \"${opts.name}\" is already running (PID: ${existing.pid}). Stop it first with: frontmcp stop ${opts.name}`,\n );\n }\n\n // Clean up stale PID file\n if (existing) {\n removePidFile(opts.name);\n }\n\n const supervisor = new Supervisor(opts);\n await supervisor.start();\n supervisors.set(opts.name, supervisor);\n\n // Wait briefly for child to spawn\n await new Promise((resolve) => setTimeout(resolve, 500));\n\n const info = this.getProcessInfo(opts.name);\n if (!info) {\n throw new Error(`Failed to start process \"${opts.name}\"`);\n }\n return info;\n }\n\n async stop(name: string, opts: StopOptions = {}): Promise<void> {\n const supervisor = supervisors.get(name);\n if (supervisor) {\n await supervisor.stop(opts.force);\n supervisors.delete(name);\n return;\n }\n\n // No local supervisor — try to kill by PID file\n const pidData = readPidFile(name);\n if (!pidData) {\n throw new Error(`No process found with name \"${name}\"`);\n }\n\n if (!isProcessAlive(pidData.pid)) {\n removePidFile(name);\n throw new Error(`Process \"${name}\" is not running (stale PID file removed)`);\n }\n\n // Try graceful shutdown via supervisor PID first, then process PID\n const targetPid = pidData.supervisorPid || pidData.pid;\n\n if (opts.force) {\n try {\n process.kill(targetPid, 'SIGKILL');\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code !== 'ESRCH') throw err;\n }\n } else {\n try {\n process.kill(targetPid, 'SIGTERM');\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code !== 'ESRCH') throw err;\n }\n\n // Wait for process to exit\n const timeout = opts.timeout ?? 10000;\n const start = Date.now();\n while (Date.now() - start < timeout) {\n if (!isProcessAlive(pidData.pid)) break;\n await new Promise((resolve) => setTimeout(resolve, 200));\n }\n\n // Force kill if still alive\n if (isProcessAlive(pidData.pid)) {\n try {\n process.kill(pidData.pid, 'SIGKILL');\n } catch {\n // ignore\n }\n }\n }\n\n removePidFile(name);\n }\n\n async restart(name: string): Promise<ProcessInfo> {\n const pidData = readPidFile(name);\n if (!pidData) {\n throw new Error(`No process found with name \"${name}\". Cannot restart.`);\n }\n\n // Stop existing\n try {\n await this.stop(name);\n } catch {\n // May already be stopped\n }\n\n // Restart with same config\n return this.start({\n name: pidData.name,\n entry: pidData.entry,\n port: pidData.port,\n socketPath: pidData.socketPath,\n dbPath: pidData.dbPath,\n socket: !!pidData.socketPath,\n });\n }\n\n getProcessInfo(name: string): ProcessInfo | null {\n const pidData = readPidFile(name);\n if (!pidData) return null;\n\n const alive = isProcessAlive(pidData.pid);\n\n return {\n name: pidData.name,\n pid: pidData.pid,\n supervisorPid: pidData.supervisorPid,\n status: alive ? 'running' : 'dead',\n entry: pidData.entry,\n port: pidData.port,\n socketPath: pidData.socketPath,\n dbPath: pidData.dbPath,\n startedAt: pidData.startedAt,\n restartCount: pidData.restartCount,\n uptime: alive ? formatUptime(pidData.startedAt) : '-',\n cliVersion: pidData.cliVersion,\n };\n }\n\n listAll(): ProcessInfo[] {\n const pidFiles = listPidFiles();\n return pidFiles.map((data) => {\n const alive = isProcessAlive(data.pid);\n return {\n name: data.name,\n pid: data.pid,\n supervisorPid: data.supervisorPid,\n status: alive ? 'running' : ('dead' as const),\n entry: data.entry,\n port: data.port,\n socketPath: data.socketPath,\n dbPath: data.dbPath,\n startedAt: data.startedAt,\n restartCount: data.restartCount,\n uptime: alive ? formatUptime(data.startedAt) : '-',\n cliVersion: data.cliVersion,\n };\n });\n }\n}\n"]}
|
|
@@ -10,6 +10,7 @@ export declare const PM_DIRS: {
|
|
|
10
10
|
readonly services: string;
|
|
11
11
|
readonly apps: string;
|
|
12
12
|
readonly data: string;
|
|
13
|
+
readonly esmCache: string;
|
|
13
14
|
};
|
|
14
15
|
export declare function pidFilePath(name: string): string;
|
|
15
16
|
export declare function logFilePath(name: string): string;
|