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.
Files changed (264) hide show
  1. package/README.md +1 -1
  2. package/package.json +6 -5
  3. package/src/commands/build/bundler.js +1 -1
  4. package/src/commands/build/bundler.js.map +1 -1
  5. package/src/commands/build/exec/cli-runtime/cli-bundler.d.ts +17 -0
  6. package/src/commands/build/exec/cli-runtime/cli-bundler.js +75 -0
  7. package/src/commands/build/exec/cli-runtime/cli-bundler.js.map +1 -0
  8. package/src/commands/build/exec/cli-runtime/credential-store.d.ts +22 -0
  9. package/src/commands/build/exec/cli-runtime/credential-store.js +140 -0
  10. package/src/commands/build/exec/cli-runtime/credential-store.js.map +1 -0
  11. package/src/commands/build/exec/cli-runtime/daemon-client.d.ts +16 -0
  12. package/src/commands/build/exec/cli-runtime/daemon-client.js +169 -0
  13. package/src/commands/build/exec/cli-runtime/daemon-client.js.map +1 -0
  14. package/src/commands/build/exec/cli-runtime/generate-cli-entry.d.ts +37 -0
  15. package/src/commands/build/exec/cli-runtime/generate-cli-entry.js +1287 -0
  16. package/src/commands/build/exec/cli-runtime/generate-cli-entry.js.map +1 -0
  17. package/src/commands/build/exec/cli-runtime/index.d.ts +9 -0
  18. package/src/commands/build/exec/cli-runtime/index.js +32 -0
  19. package/src/commands/build/exec/cli-runtime/index.js.map +1 -0
  20. package/src/commands/build/exec/cli-runtime/oauth-helper.d.ts +9 -0
  21. package/src/commands/build/exec/cli-runtime/oauth-helper.js +224 -0
  22. package/src/commands/build/exec/cli-runtime/oauth-helper.js.map +1 -0
  23. package/src/commands/build/exec/cli-runtime/output-formatter.d.ts +46 -0
  24. package/src/commands/build/exec/cli-runtime/output-formatter.js +168 -0
  25. package/src/commands/build/exec/cli-runtime/output-formatter.js.map +1 -0
  26. package/src/commands/build/exec/cli-runtime/schema-extractor.d.ts +57 -0
  27. package/src/commands/build/exec/cli-runtime/schema-extractor.js +129 -0
  28. package/src/commands/build/exec/cli-runtime/schema-extractor.js.map +1 -0
  29. package/src/commands/build/exec/cli-runtime/schema-to-commander.d.ts +38 -0
  30. package/src/commands/build/exec/cli-runtime/schema-to-commander.js +172 -0
  31. package/src/commands/build/exec/cli-runtime/schema-to-commander.js.map +1 -0
  32. package/src/commands/build/exec/cli-runtime/session-manager.d.ts +16 -0
  33. package/src/commands/build/exec/cli-runtime/session-manager.js +122 -0
  34. package/src/commands/build/exec/cli-runtime/session-manager.js.map +1 -0
  35. package/src/commands/build/exec/config.d.ts +25 -0
  36. package/src/commands/build/exec/config.js +0 -1
  37. package/src/commands/build/exec/config.js.map +1 -1
  38. package/src/commands/build/exec/esbuild-bundler.d.ts +4 -1
  39. package/src/commands/build/exec/esbuild-bundler.js +28 -9
  40. package/src/commands/build/exec/esbuild-bundler.js.map +1 -1
  41. package/src/commands/build/exec/index.d.ts +7 -2
  42. package/src/commands/build/exec/index.js +159 -9
  43. package/src/commands/build/exec/index.js.map +1 -1
  44. package/src/commands/build/exec/manifest.d.ts +14 -0
  45. package/src/commands/build/exec/manifest.js.map +1 -1
  46. package/src/commands/build/exec/runner-script.d.ts +1 -1
  47. package/src/commands/build/exec/runner-script.js +48 -5
  48. package/src/commands/build/exec/runner-script.js.map +1 -1
  49. package/src/commands/build/exec/sea-builder.d.ts +18 -0
  50. package/src/commands/build/exec/sea-builder.js +81 -0
  51. package/src/commands/build/exec/sea-builder.js.map +1 -0
  52. package/src/commands/build/exec/setup.js +0 -2
  53. package/src/commands/build/exec/setup.js.map +1 -1
  54. package/src/commands/build/index.d.ts +1 -1
  55. package/src/commands/build/index.js +3 -3
  56. package/src/commands/build/index.js.map +1 -1
  57. package/src/commands/build/register.d.ts +2 -0
  58. package/src/commands/build/register.js +21 -0
  59. package/src/commands/build/register.js.map +1 -0
  60. package/src/commands/{dev.d.ts → dev/dev.d.ts} +1 -1
  61. package/src/commands/{dev.js → dev/dev.js} +3 -3
  62. package/src/commands/dev/dev.js.map +1 -0
  63. package/src/commands/{doctor.js → dev/doctor.js} +5 -4
  64. package/src/commands/dev/doctor.js.map +1 -0
  65. package/src/commands/{inspector.js → dev/inspector.js} +1 -1
  66. package/src/commands/dev/inspector.js.map +1 -0
  67. package/src/commands/dev/register.d.ts +2 -0
  68. package/src/commands/dev/register.js +49 -0
  69. package/src/commands/dev/register.js.map +1 -0
  70. package/src/commands/{test.d.ts → dev/test.d.ts} +1 -1
  71. package/src/commands/{test.js → dev/test.js} +5 -5
  72. package/src/commands/dev/test.js.map +1 -0
  73. package/src/commands/{configure.d.ts → package/configure.d.ts} +1 -1
  74. package/src/commands/{configure.js → package/configure.js} +3 -3
  75. package/src/commands/package/configure.js.map +1 -0
  76. package/src/commands/package/esm-update.d.ts +19 -0
  77. package/src/commands/package/esm-update.js +93 -0
  78. package/src/commands/package/esm-update.js.map +1 -0
  79. package/src/commands/{install/index.d.ts → package/install.d.ts} +1 -1
  80. package/src/commands/{install/index.js → package/install.js} +8 -5
  81. package/src/commands/package/install.js.map +1 -0
  82. package/src/commands/{install → package}/questionnaire.js +2 -2
  83. package/src/commands/{install → package}/questionnaire.js.map +1 -1
  84. package/src/commands/package/register.d.ts +2 -0
  85. package/src/commands/package/register.js +35 -0
  86. package/src/commands/package/register.js.map +1 -0
  87. package/src/commands/{install → package}/registry.js +8 -6
  88. package/src/commands/package/registry.js.map +1 -0
  89. package/src/commands/{install → package}/sources/git.js +8 -1
  90. package/src/commands/package/sources/git.js.map +1 -0
  91. package/src/commands/{install → package}/sources/local.js.map +1 -1
  92. package/src/commands/{install → package}/sources/npm.js.map +1 -1
  93. package/src/commands/{install → package}/types.d.ts +7 -1
  94. package/src/commands/{install → package}/types.js +4 -0
  95. package/src/commands/package/types.js.map +1 -0
  96. package/src/commands/{uninstall.d.ts → package/uninstall.d.ts} +1 -1
  97. package/src/commands/{uninstall.js → package/uninstall.js} +2 -2
  98. package/src/commands/package/uninstall.js.map +1 -0
  99. package/src/{pm/pm.format.d.ts → commands/pm/format.d.ts} +1 -1
  100. package/src/{pm/pm.format.js → commands/pm/format.js} +2 -2
  101. package/src/commands/pm/format.js.map +1 -0
  102. package/src/{pm/pm.health.js → commands/pm/health.js} +1 -1
  103. package/src/commands/pm/health.js.map +1 -0
  104. package/src/commands/pm/index.d.ts +9 -0
  105. package/src/{pm → commands/pm}/index.js +32 -32
  106. package/src/commands/pm/index.js.map +1 -0
  107. package/src/commands/{list.d.ts → pm/list.d.ts} +1 -1
  108. package/src/commands/{list.js → pm/list.js} +3 -3
  109. package/src/commands/pm/list.js.map +1 -0
  110. package/src/{pm/pm.logs.js → commands/pm/log-utils.js} +9 -9
  111. package/src/commands/pm/log-utils.js.map +1 -0
  112. package/src/commands/{logs.d.ts → pm/logs.d.ts} +1 -1
  113. package/src/commands/{logs.js → pm/logs.js} +6 -6
  114. package/src/commands/pm/logs.js.map +1 -0
  115. package/src/{pm/pm.manager.d.ts → commands/pm/manager.d.ts} +1 -1
  116. package/src/{pm/pm.manager.js → commands/pm/manager.js} +21 -21
  117. package/src/commands/pm/manager.js.map +1 -0
  118. package/src/{pm/pm.paths.d.ts → commands/pm/paths.d.ts} +1 -0
  119. package/src/{pm/pm.paths.js → commands/pm/paths.js} +2 -1
  120. package/src/commands/pm/paths.js.map +1 -0
  121. package/src/{pm/pm.pidfile.d.ts → commands/pm/pidfile.d.ts} +1 -1
  122. package/src/{pm/pm.pidfile.js → commands/pm/pidfile.js} +8 -8
  123. package/src/commands/pm/pidfile.js.map +1 -0
  124. package/src/commands/pm/register.d.ts +2 -0
  125. package/src/commands/pm/register.js +83 -0
  126. package/src/commands/pm/register.js.map +1 -0
  127. package/src/commands/{restart.d.ts → pm/restart.d.ts} +1 -1
  128. package/src/commands/{restart.js → pm/restart.js} +4 -4
  129. package/src/commands/pm/restart.js.map +1 -0
  130. package/src/{pm/pm.service.d.ts → commands/pm/service-gen.d.ts} +1 -1
  131. package/src/{pm/pm.service.js → commands/pm/service-gen.js} +5 -5
  132. package/src/commands/pm/service-gen.js.map +1 -0
  133. package/src/commands/{service.d.ts → pm/service.d.ts} +1 -1
  134. package/src/commands/{service.js → pm/service.js} +6 -6
  135. package/src/commands/pm/service.js.map +1 -0
  136. package/src/commands/{socket.d.ts → pm/socket.d.ts} +1 -1
  137. package/src/commands/{socket.js → pm/socket.js} +3 -3
  138. package/src/commands/pm/socket.js.map +1 -0
  139. package/src/{pm/pm.spawn.d.ts → commands/pm/spawn.d.ts} +1 -1
  140. package/src/{pm/pm.spawn.js → commands/pm/spawn.js} +15 -15
  141. package/src/commands/pm/spawn.js.map +1 -0
  142. package/src/commands/{start.d.ts → pm/start.d.ts} +1 -1
  143. package/src/commands/{start.js → pm/start.js} +6 -6
  144. package/src/commands/pm/start.js.map +1 -0
  145. package/src/commands/{status.d.ts → pm/status.d.ts} +1 -1
  146. package/src/commands/{status.js → pm/status.js} +5 -5
  147. package/src/commands/pm/status.js.map +1 -0
  148. package/src/commands/{stop.d.ts → pm/stop.d.ts} +1 -1
  149. package/src/commands/{stop.js → pm/stop.js} +3 -3
  150. package/src/commands/pm/stop.js.map +1 -0
  151. package/src/{pm/pm.types.js → commands/pm/types.js} +1 -1
  152. package/src/commands/pm/types.js.map +1 -0
  153. package/src/commands/{create.js → scaffold/create.js} +91 -20
  154. package/src/commands/scaffold/create.js.map +1 -0
  155. package/src/commands/scaffold/register.d.ts +2 -0
  156. package/src/commands/scaffold/register.js +28 -0
  157. package/src/commands/scaffold/register.js.map +1 -0
  158. package/src/{args.d.ts → core/args.d.ts} +7 -1
  159. package/src/{args.js → core/args.js} +8 -0
  160. package/src/core/args.js.map +1 -0
  161. package/src/core/bridge.d.ts +9 -0
  162. package/src/core/bridge.js +75 -0
  163. package/src/core/bridge.js.map +1 -0
  164. package/src/core/cli.d.ts +8 -0
  165. package/src/core/cli.js +23 -0
  166. package/src/core/cli.js.map +1 -0
  167. package/src/core/colors.js.map +1 -0
  168. package/src/core/help.d.ts +7 -0
  169. package/src/core/help.js +83 -0
  170. package/src/core/help.js.map +1 -0
  171. package/src/core/index.d.ts +7 -0
  172. package/src/core/index.js +22 -0
  173. package/src/core/index.js.map +1 -0
  174. package/src/core/program.d.ts +2 -0
  175. package/src/core/program.js +23 -0
  176. package/src/core/program.js.map +1 -0
  177. package/src/core/tsconfig.js.map +1 -0
  178. package/src/{version.js → core/version.js} +1 -1
  179. package/src/core/version.js.map +1 -0
  180. package/src/index.d.ts +1 -1
  181. package/src/index.js +2 -5
  182. package/src/index.js.map +1 -1
  183. package/src/{utils → shared}/env.js +2 -2
  184. package/src/shared/env.js.map +1 -0
  185. package/src/{utils → shared}/fs.js +2 -2
  186. package/src/shared/fs.js.map +1 -0
  187. package/src/shared/index.d.ts +3 -0
  188. package/src/shared/index.js +14 -0
  189. package/src/shared/index.js.map +1 -0
  190. package/src/shared/prompts.js.map +1 -0
  191. package/src/args.js.map +0 -1
  192. package/src/cli.d.ts +0 -5
  193. package/src/cli.js +0 -241
  194. package/src/cli.js.map +0 -1
  195. package/src/colors.js.map +0 -1
  196. package/src/commands/configure.js.map +0 -1
  197. package/src/commands/create.js.map +0 -1
  198. package/src/commands/dev.js.map +0 -1
  199. package/src/commands/doctor.js.map +0 -1
  200. package/src/commands/inspector.js.map +0 -1
  201. package/src/commands/install/index.js.map +0 -1
  202. package/src/commands/install/registry.js.map +0 -1
  203. package/src/commands/install/sources/git.js.map +0 -1
  204. package/src/commands/install/types.js.map +0 -1
  205. package/src/commands/list.js.map +0 -1
  206. package/src/commands/logs.js.map +0 -1
  207. package/src/commands/restart.js.map +0 -1
  208. package/src/commands/service.js.map +0 -1
  209. package/src/commands/socket.js.map +0 -1
  210. package/src/commands/start.js.map +0 -1
  211. package/src/commands/status.js.map +0 -1
  212. package/src/commands/stop.js.map +0 -1
  213. package/src/commands/template.d.ts +0 -13
  214. package/src/commands/template.js +0 -193
  215. package/src/commands/template.js.map +0 -1
  216. package/src/commands/test.js.map +0 -1
  217. package/src/commands/uninstall.js.map +0 -1
  218. package/src/pm/index.d.ts +0 -9
  219. package/src/pm/index.js.map +0 -1
  220. package/src/pm/pm.format.js.map +0 -1
  221. package/src/pm/pm.health.js.map +0 -1
  222. package/src/pm/pm.logs.js.map +0 -1
  223. package/src/pm/pm.manager.js.map +0 -1
  224. package/src/pm/pm.paths.js.map +0 -1
  225. package/src/pm/pm.pidfile.js.map +0 -1
  226. package/src/pm/pm.service.js.map +0 -1
  227. package/src/pm/pm.spawn.js.map +0 -1
  228. package/src/pm/pm.types.js.map +0 -1
  229. package/src/templates/3rd-party-integration/src/http-client.d.ts +0 -20
  230. package/src/templates/3rd-party-integration/src/http-client.js +0 -105
  231. package/src/templates/3rd-party-integration/src/http-client.js.map +0 -1
  232. package/src/templates/3rd-party-integration/src/mcp-http-types.d.ts +0 -63
  233. package/src/templates/3rd-party-integration/src/mcp-http-types.js +0 -52
  234. package/src/templates/3rd-party-integration/src/mcp-http-types.js.map +0 -1
  235. package/src/templates/3rd-party-integration/src/tools/example.list.d.ts +0 -45
  236. package/src/templates/3rd-party-integration/src/tools/example.list.js +0 -85
  237. package/src/templates/3rd-party-integration/src/tools/example.list.js.map +0 -1
  238. package/src/tsconfig.js.map +0 -1
  239. package/src/utils/env.js.map +0 -1
  240. package/src/utils/fs.js.map +0 -1
  241. package/src/utils/prompts.js.map +0 -1
  242. package/src/version.js.map +0 -1
  243. /package/src/commands/{doctor.d.ts → dev/doctor.d.ts} +0 -0
  244. /package/src/commands/{inspector.d.ts → dev/inspector.d.ts} +0 -0
  245. /package/src/commands/{install → package}/questionnaire.d.ts +0 -0
  246. /package/src/commands/{install → package}/registry.d.ts +0 -0
  247. /package/src/commands/{install → package}/sources/git.d.ts +0 -0
  248. /package/src/commands/{install → package}/sources/local.d.ts +0 -0
  249. /package/src/commands/{install → package}/sources/local.js +0 -0
  250. /package/src/commands/{install → package}/sources/npm.d.ts +0 -0
  251. /package/src/commands/{install → package}/sources/npm.js +0 -0
  252. /package/src/{pm/pm.health.d.ts → commands/pm/health.d.ts} +0 -0
  253. /package/src/{pm/pm.logs.d.ts → commands/pm/log-utils.d.ts} +0 -0
  254. /package/src/{pm/pm.types.d.ts → commands/pm/types.d.ts} +0 -0
  255. /package/src/commands/{create.d.ts → scaffold/create.d.ts} +0 -0
  256. /package/src/{colors.d.ts → core/colors.d.ts} +0 -0
  257. /package/src/{colors.js → core/colors.js} +0 -0
  258. /package/src/{tsconfig.d.ts → core/tsconfig.d.ts} +0 -0
  259. /package/src/{tsconfig.js → core/tsconfig.js} +0 -0
  260. /package/src/{version.d.ts → core/version.d.ts} +0 -0
  261. /package/src/{utils → shared}/env.d.ts +0 -0
  262. /package/src/{utils → shared}/fs.d.ts +0 -0
  263. /package/src/{utils → shared}/prompts.d.ts +0 -0
  264. /package/src/{utils → shared}/prompts.js +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../../src/commands/dev/doctor.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'path';\nimport { spawn } from 'child_process';\nimport { c } from '../../core/colors';\nimport { fileExists, readJSON } from '@frontmcp/utils';\nimport { checkRequiredTsOptions } from '../../core/tsconfig';\nimport { resolveEntry } from '../../shared/fs';\n\nfunction cmpSemver(a: string, b: string): number {\n const pa = a.split('.').map((n) => parseInt(n, 10) || 0);\n const pb = b.split('.').map((n) => parseInt(n, 10) || 0);\n for (let i = 0; i < 3; i++) {\n if ((pa[i] || 0) > (pb[i] || 0)) return 1;\n if ((pa[i] || 0) < (pb[i] || 0)) return -1;\n }\n return 0;\n}\n\nexport async function runDoctor(): Promise<void> {\n const MIN_NODE = '22.0.0';\n const MIN_NPM = '10.0.0';\n const cwd = process.cwd();\n\n let ok = true;\n\n const nodeVer = process.versions.node;\n if (cmpSemver(nodeVer, MIN_NODE) >= 0) {\n console.log(`✅ Node ${nodeVer} (min ${MIN_NODE})`);\n } else {\n ok = false;\n console.log(`❌ Node ${nodeVer} — please upgrade to >= ${MIN_NODE}`);\n }\n\n let npmVer = 'unknown';\n try {\n npmVer = await new Promise<string>((resolve, reject) => {\n const child = spawn('npm', ['-v'], { shell: true });\n let out = '';\n child.stdout?.on('data', (d) => (out += String(d)));\n child.on('close', () => resolve(out.trim()));\n child.on('error', reject);\n });\n if (cmpSemver(npmVer, MIN_NPM) >= 0) {\n console.log(`✅ npm ${npmVer} (min ${MIN_NPM})`);\n } else {\n ok = false;\n console.log(`❌ npm ${npmVer} — please upgrade to >= ${MIN_NPM}`);\n }\n } catch {\n ok = false;\n console.log('❌ npm not found in PATH');\n }\n\n const tsconfigPath = path.join(cwd, 'tsconfig.json');\n if (await fileExists(tsconfigPath)) {\n console.log(`✅ tsconfig.json found`);\n const tsconfig = await readJSON<Record<string, any>>(tsconfigPath);\n const { ok: oks, issues } = checkRequiredTsOptions(tsconfig?.compilerOptions);\n for (const line of oks) console.log(c('green', ` ✓ ${line}`));\n if (issues.length) {\n ok = false;\n for (const line of issues) console.log(c('yellow', ` • ${line}`));\n console.log(c('cyan', ` -> Run \"frontmcp init\" to apply the required settings.`));\n }\n } else {\n ok = false;\n console.log(`❌ tsconfig.json not found — run ${c('cyan', 'frontmcp init')}`);\n }\n\n try {\n const entry = await resolveEntry(cwd);\n console.log(`✅ entry detected: ${path.relative(cwd, entry)}`);\n } catch (e: unknown) {\n ok = false;\n const firstLine = e instanceof Error ? (e.message.split('\\n')[0] ?? 'entry not found') : 'entry not found';\n console.log(`❌ entry not detected — ${firstLine}`);\n }\n\n if (ok) console.log(c('green', '\\nAll checks passed. You are ready to go!'));\n else console.log(c('yellow', '\\nSome checks failed. See above for fixes.'));\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.runInspector = runInspector;
4
- const colors_1 = require("../colors");
4
+ const colors_1 = require("../../core/colors");
5
5
  const utils_1 = require("@frontmcp/utils");
6
6
  async function runInspector() {
7
7
  console.log(`${(0, colors_1.c)('cyan', '[inspector]')} launching MCP Inspector...`);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspector.js","sourceRoot":"","sources":["../../../../src/commands/dev/inspector.ts"],"names":[],"mappings":";;AAGA,oCAGC;AAND,8CAAsC;AACtC,2CAAyC;AAElC,KAAK,UAAU,YAAY;IAChC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAA,UAAC,EAAC,MAAM,EAAE,aAAa,CAAC,6BAA6B,CAAC,CAAC;IACtE,MAAM,IAAA,cAAM,EAAC,KAAK,EAAE,CAAC,IAAI,EAAE,iCAAiC,CAAC,CAAC,CAAC;AACjE,CAAC","sourcesContent":["import { c } from '../../core/colors';\nimport { runCmd } from '@frontmcp/utils';\n\nexport async function runInspector(): Promise<void> {\n console.log(`${c('cyan', '[inspector]')} launching MCP Inspector...`);\n await runCmd('npx', ['-y', '@modelcontextprotocol/inspector']);\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerDevCommands(program: Command): void;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerDevCommands = registerDevCommands;
4
+ const bridge_1 = require("../../core/bridge");
5
+ function registerDevCommands(program) {
6
+ program
7
+ .command('dev')
8
+ .description('Start in development mode (tsx --watch + async type-check)')
9
+ .option('-e, --entry <path>', 'Entry file path')
10
+ .action(async (options) => {
11
+ const { runDev } = await import('./dev.js');
12
+ await runDev((0, bridge_1.toParsedArgs)('dev', [], options));
13
+ });
14
+ program
15
+ .command('test')
16
+ .description('Run E2E tests with auto-injected Jest configuration')
17
+ .argument('[patterns...]', 'Test file patterns')
18
+ .option('-i, --runInBand', 'Run tests sequentially (recommended for E2E)')
19
+ .option('-w, --watch', 'Run tests in watch mode')
20
+ .option('-v, --verbose', 'Show verbose test output')
21
+ .option('-t, --timeout <ms>', 'Set test timeout (default: 60000ms)', parseInt)
22
+ .option('-c, --coverage', 'Collect test coverage')
23
+ .action(async (patterns, options) => {
24
+ const { runTest } = await import('./test.js');
25
+ await runTest((0, bridge_1.toParsedArgs)('test', patterns, options));
26
+ });
27
+ program
28
+ .command('init')
29
+ .description('Create or fix a tsconfig.json suitable for FrontMCP')
30
+ .action(async () => {
31
+ const { runInit } = await import('../../core/tsconfig.js');
32
+ await runInit();
33
+ });
34
+ program
35
+ .command('doctor')
36
+ .description('Check Node/npm versions and tsconfig requirements')
37
+ .action(async () => {
38
+ const { runDoctor } = await import('./doctor.js');
39
+ await runDoctor();
40
+ });
41
+ program
42
+ .command('inspector')
43
+ .description('Launch MCP Inspector (npx @modelcontextprotocol/inspector)')
44
+ .action(async () => {
45
+ const { runInspector } = await import('./inspector.js');
46
+ await runInspector();
47
+ });
48
+ }
49
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../../../src/commands/dev/register.ts"],"names":[],"mappings":";;AAGA,kDA+CC;AAjDD,8CAAiD;AAEjD,SAAgB,mBAAmB,CAAC,OAAgB;IAClD,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,4DAA4D,CAAC;SACzE,MAAM,CAAC,oBAAoB,EAAE,iBAAiB,CAAC;SAC/C,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,MAAM,CAAC,IAAA,qBAAY,EAAC,KAAK,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,qDAAqD,CAAC;SAClE,QAAQ,CAAC,eAAe,EAAE,oBAAoB,CAAC;SAC/C,MAAM,CAAC,iBAAiB,EAAE,8CAA8C,CAAC;SACzE,MAAM,CAAC,aAAa,EAAE,yBAAyB,CAAC;SAChD,MAAM,CAAC,eAAe,EAAE,0BAA0B,CAAC;SACnD,MAAM,CAAC,oBAAoB,EAAE,qCAAqC,EAAE,QAAQ,CAAC;SAC7E,MAAM,CAAC,gBAAgB,EAAE,uBAAuB,CAAC;SACjD,MAAM,CAAC,KAAK,EAAE,QAAkB,EAAE,OAAO,EAAE,EAAE;QAC5C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;QAC9C,MAAM,OAAO,CAAC,IAAA,qBAAY,EAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,qDAAqD,CAAC;SAClE,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;QAC3D,MAAM,OAAO,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,mDAAmD,CAAC;SAChE,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QAClD,MAAM,SAAS,EAAE,CAAC;IACpB,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,4DAA4D,CAAC;SACzE,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACxD,MAAM,YAAY,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;AACP,CAAC","sourcesContent":["import { Command } from 'commander';\nimport { toParsedArgs } from '../../core/bridge';\n\nexport function registerDevCommands(program: Command): void {\n program\n .command('dev')\n .description('Start in development mode (tsx --watch + async type-check)')\n .option('-e, --entry <path>', 'Entry file path')\n .action(async (options) => {\n const { runDev } = await import('./dev.js');\n await runDev(toParsedArgs('dev', [], options));\n });\n\n program\n .command('test')\n .description('Run E2E tests with auto-injected Jest configuration')\n .argument('[patterns...]', 'Test file patterns')\n .option('-i, --runInBand', 'Run tests sequentially (recommended for E2E)')\n .option('-w, --watch', 'Run tests in watch mode')\n .option('-v, --verbose', 'Show verbose test output')\n .option('-t, --timeout <ms>', 'Set test timeout (default: 60000ms)', parseInt)\n .option('-c, --coverage', 'Collect test coverage')\n .action(async (patterns: string[], options) => {\n const { runTest } = await import('./test.js');\n await runTest(toParsedArgs('test', patterns, options));\n });\n\n program\n .command('init')\n .description('Create or fix a tsconfig.json suitable for FrontMCP')\n .action(async () => {\n const { runInit } = await import('../../core/tsconfig.js');\n await runInit();\n });\n\n program\n .command('doctor')\n .description('Check Node/npm versions and tsconfig requirements')\n .action(async () => {\n const { runDoctor } = await import('./doctor.js');\n await runDoctor();\n });\n\n program\n .command('inspector')\n .description('Launch MCP Inspector (npx @modelcontextprotocol/inspector)')\n .action(async () => {\n const { runInspector } = await import('./inspector.js');\n await runInspector();\n });\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { ParsedArgs } from '../args';
1
+ import { ParsedArgs } from '../../core/args';
2
2
  /**
3
3
  * Run E2E tests using Jest with auto-injected configuration.
4
4
  *
@@ -5,9 +5,9 @@ const tslib_1 = require("tslib");
5
5
  const path = tslib_1.__importStar(require("path"));
6
6
  const os = tslib_1.__importStar(require("os"));
7
7
  const child_process_1 = require("child_process");
8
- const colors_1 = require("../colors");
8
+ const colors_1 = require("../../core/colors");
9
9
  const utils_1 = require("@frontmcp/utils");
10
- const fs_1 = require("../utils/fs");
10
+ const fs_1 = require("../../shared/fs");
11
11
  /**
12
12
  * Generate Jest configuration programmatically for E2E tests.
13
13
  * This eliminates the need for projects to have their own jest.e2e.config.ts.
@@ -20,7 +20,7 @@ function generateJestConfig(cwd, opts) {
20
20
  // Root directory for tests
21
21
  rootDir: cwd,
22
22
  // Test file patterns for E2E tests
23
- testMatch: ['<rootDir>/e2e/**/*.e2e.ts', '<rootDir>/e2e/**/*.e2e.test.ts', '<rootDir>/**/*.e2e.ts'],
23
+ testMatch: ['<rootDir>/e2e/**/*.e2e.ts', '<rootDir>/e2e/**/*.e2e.spec.ts', '<rootDir>/**/*.e2e.ts'],
24
24
  // Transform TypeScript files using @swc/jest for speed
25
25
  transform: {
26
26
  '^.+\\.[tj]s$': [
@@ -66,7 +66,7 @@ function generateJestConfig(cwd, opts) {
66
66
  ? {
67
67
  coverageDirectory: '<rootDir>/coverage',
68
68
  coverageReporters: ['text', 'lcov', 'json'],
69
- collectCoverageFrom: ['<rootDir>/src/**/*.ts', '!<rootDir>/src/**/*.test.ts', '!<rootDir>/src/**/*.spec.ts'],
69
+ collectCoverageFrom: ['<rootDir>/src/**/*.ts', '!<rootDir>/src/**/*.spec.ts'],
70
70
  }
71
71
  : {}),
72
72
  // Verbose output
@@ -94,7 +94,7 @@ async function runTest(opts) {
94
94
  console.error('Expected structure:');
95
95
  console.error(' ./e2e/');
96
96
  console.error(' ├── your-test.e2e.ts');
97
- console.error(' └── another-test.e2e.test.ts');
97
+ console.error(' └── another-test.e2e.spec.ts');
98
98
  console.error('');
99
99
  console.error('Create an e2e directory with test files, then run:');
100
100
  console.error(' frontmcp test');
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../../../../src/commands/dev/test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'path';\nimport * as os from 'os';\nimport { spawn, ChildProcess } from 'child_process';\nimport { ParsedArgs } from '../../core/args';\nimport { c } from '../../core/colors';\nimport { fileExists } from '@frontmcp/utils';\nimport { fsp } from '../../shared/fs';\n\n/**\n * Generate Jest configuration programmatically for E2E tests.\n * This eliminates the need for projects to have their own jest.e2e.config.ts.\n */\nfunction generateJestConfig(cwd: string, opts: ParsedArgs): object {\n const testTimeout = opts.timeout ?? 60000;\n\n return {\n // Use Node.js environment for E2E tests\n testEnvironment: 'node',\n\n // Root directory for tests\n rootDir: cwd,\n\n // Test file patterns for E2E tests\n testMatch: ['<rootDir>/e2e/**/*.e2e.ts', '<rootDir>/e2e/**/*.e2e.spec.ts', '<rootDir>/**/*.e2e.ts'],\n\n // Transform TypeScript files using @swc/jest for speed\n transform: {\n '^.+\\\\.[tj]s$': [\n '@swc/jest',\n {\n jsc: {\n target: 'es2022',\n parser: {\n syntax: 'typescript',\n decorators: true,\n dynamicImport: true,\n },\n transform: {\n decoratorMetadata: true,\n legacyDecorator: true,\n },\n keepClassNames: true,\n externalHelpers: true,\n loose: true,\n },\n module: {\n type: 'es6',\n },\n sourceMaps: true,\n swcrc: false,\n },\n ],\n },\n\n // File extensions to consider\n moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],\n\n // Test timeout\n testTimeout,\n\n // Setup files that run after Jest is initialized\n setupFilesAfterEnv: ['@frontmcp/testing/setup'],\n\n // Transform packages that use ESM\n transformIgnorePatterns: ['node_modules/(?!(jose)/)'],\n\n // Ignore patterns\n testPathIgnorePatterns: ['/node_modules/', '/dist/'],\n\n // Coverage settings\n collectCoverage: opts.coverage ?? false,\n\n // Coverage configuration when enabled\n ...(opts.coverage\n ? {\n coverageDirectory: '<rootDir>/coverage',\n coverageReporters: ['text', 'lcov', 'json'],\n collectCoverageFrom: ['<rootDir>/src/**/*.ts', '!<rootDir>/src/**/*.spec.ts'],\n }\n : {}),\n\n // Verbose output\n verbose: opts.verbose ?? true,\n };\n}\n\n/**\n * Run E2E tests using Jest with auto-injected configuration.\n *\n * Usage:\n * frontmcp test # Run E2E tests in current directory\n * frontmcp test --runInBand # Run tests sequentially (recommended for E2E)\n * frontmcp test --watch # Run tests in watch mode\n * frontmcp test --verbose # Show verbose output\n * frontmcp test --timeout 60000 # Set test timeout (default: 60000ms)\n */\nexport async function runTest(opts: ParsedArgs): Promise<void> {\n const cwd = process.cwd();\n\n // Check for e2e directory\n const e2eDir = path.join(cwd, 'e2e');\n const hasE2EDir = await fileExists(e2eDir);\n\n if (!hasE2EDir) {\n console.error(c('red', 'No e2e directory found.'));\n console.error('');\n console.error('Expected structure:');\n console.error(' ./e2e/');\n console.error(' ├── your-test.e2e.ts');\n console.error(' └── another-test.e2e.spec.ts');\n console.error('');\n console.error('Create an e2e directory with test files, then run:');\n console.error(' frontmcp test');\n process.exit(1);\n }\n\n // Generate Jest config and write to temp file\n const config = generateJestConfig(cwd, opts);\n const tempDir = os.tmpdir();\n const configPath = path.join(tempDir, `frontmcp-jest-config-${Date.now()}.json`);\n await fsp.writeFile(configPath, JSON.stringify(config, null, 2));\n\n // Build Jest arguments\n const jestArgs: string[] = ['jest', '--config', configPath];\n\n // Add --runInBand for sequential execution (recommended for E2E tests)\n if (opts.runInBand) {\n jestArgs.push('--runInBand');\n }\n\n // Add watch mode\n if (opts.watch) {\n jestArgs.push('--watch');\n }\n\n // Add verbose flag\n if (opts.verbose) {\n jestArgs.push('--verbose');\n }\n\n // Add coverage flag\n if (opts.coverage) {\n jestArgs.push('--coverage');\n }\n\n // Add any additional positional args (e.g., test file patterns)\n const testPatterns = opts._.slice(1); // Skip 'test' command itself\n if (testPatterns.length > 0) {\n jestArgs.push(...testPatterns);\n }\n\n console.log(`${c('cyan', '[test]')} running E2E tests in ${path.relative(process.cwd(), cwd) || '.'}`);\n console.log(`${c('gray', '[test]')} using auto-injected Jest configuration`);\n\n if (opts.runInBand) {\n console.log(`${c('gray', '[test]')} running tests sequentially (--runInBand)`);\n }\n\n if (opts.watch) {\n console.log(`${c('gray', '[test]')} watch mode enabled`);\n }\n\n if (opts.coverage) {\n console.log(`${c('gray', '[test]')} coverage collection enabled`);\n }\n\n console.log(`${c('gray', 'hint:')} press Ctrl+C to stop\\n`);\n\n // Run Jest directly via node_modules/.bin or npx without shell\n // Using shell: false with explicit args array avoids escaping issues\n const jest = spawn('npx', jestArgs, {\n stdio: 'inherit',\n shell: false,\n cwd,\n });\n\n // Handle cleanup\n const cleanup = async (proc?: ChildProcess) => {\n try {\n if (proc) {\n proc.kill('SIGINT');\n }\n } catch {\n // ignore\n }\n // Clean up temp config file\n try {\n await fsp.unlink(configPath);\n } catch {\n // ignore\n }\n };\n\n process.on('SIGINT', () => {\n cleanup(jest).finally(() => {\n process.exit(0);\n });\n });\n\n // Wait for Jest to complete\n try {\n await new Promise<void>((resolve, reject) => {\n jest.on('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`Jest exited with code ${code}`));\n }\n });\n jest.on('error', (err) => {\n reject(err);\n });\n });\n } finally {\n // Clean up temp config file\n try {\n await fsp.unlink(configPath);\n } catch {\n // ignore\n }\n }\n}\n"]}
@@ -1,2 +1,2 @@
1
- import { ParsedArgs } from '../args';
1
+ import { ParsedArgs } from '../../core/args';
2
2
  export declare function runConfigure(opts: ParsedArgs): Promise<void>;
@@ -4,9 +4,9 @@ exports.runConfigure = runConfigure;
4
4
  const tslib_1 = require("tslib");
5
5
  const fs = tslib_1.__importStar(require("fs"));
6
6
  const path = tslib_1.__importStar(require("path"));
7
- const colors_1 = require("../colors");
8
- const registry_1 = require("./install/registry");
9
- const questionnaire_1 = require("./install/questionnaire");
7
+ const colors_1 = require("../../core/colors");
8
+ const registry_1 = require("./registry");
9
+ const questionnaire_1 = require("./questionnaire");
10
10
  async function runConfigure(opts) {
11
11
  const name = opts._[1];
12
12
  if (!name) {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configure.js","sourceRoot":"","sources":["../../../../src/commands/package/configure.ts"],"names":[],"mappings":";;AAQA,oCAkCC;;AA1CD,+CAAyB;AACzB,mDAA6B;AAE7B,8CAAsC;AACtC,yCAA8C;AAC9C,mDAAiE;AAG1D,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,qCAAqC;IACrC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,IAAI,gBAAgB,CAAC,CAAC;IACxE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,yBAAyB,YAAY,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAiB,CAAC;IAEpF,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChE,OAAO,CAAC,GAAG,CAAC,IAAA,UAAC,EAAC,QAAQ,EAAE,QAAQ,IAAI,+BAA+B,CAAC,CAAC,CAAC;QACtE,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,GAAG,IAAA,UAAC,EAAC,MAAM,EAAE,kBAAkB,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IAEzD,MAAM,MAAM,GAAG,MAAM,IAAA,gCAAgB,EAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE;QAC1D,MAAM,EAAE,IAAI,CAAC,GAAG;KACjB,CAAC,CAAC;IAEH,IAAA,4BAAY,EAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAEhD,OAAO,CAAC,GAAG,CAAC,KAAK,IAAA,UAAC,EAAC,OAAO,EAAE,sBAAsB,CAAC,8CAA8C,CAAC,CAAC;IACnG,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;AAC5C,CAAC","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { ParsedArgs } from '../../core/args';\nimport { c } from '../../core/colors';\nimport { getRegisteredApp } from './registry';\nimport { runQuestionnaire, writeEnvFile } from './questionnaire';\nimport { ExecManifest } from '../build/exec/manifest';\n\nexport async function runConfigure(opts: ParsedArgs): Promise<void> {\n const name = opts._[1];\n if (!name) {\n throw new Error('Missing app name. Usage: frontmcp configure <name>');\n }\n\n const app = getRegisteredApp(name);\n if (!app) {\n throw new Error(`App \"${name}\" is not installed.`);\n }\n\n // Find manifest in install directory\n const manifestPath = path.join(app.installDir, `${name}.manifest.json`);\n if (!fs.existsSync(manifestPath)) {\n throw new Error(`Manifest not found at ${manifestPath}`);\n }\n\n const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8')) as ExecManifest;\n\n if (!manifest.setup?.steps || manifest.setup.steps.length === 0) {\n console.log(c('yellow', `App \"${name}\" has no setup questionnaire.`));\n return;\n }\n\n console.log(`${c('bold', `Reconfiguring \"${name}\"`)}\\n`);\n\n const result = await runQuestionnaire(manifest.setup.steps, {\n silent: opts.yes,\n });\n\n writeEnvFile(app.installDir, result.envContent);\n\n console.log(`\\n${c('green', 'Configuration saved.')} Restart the app for changes to take effect:`);\n console.log(` frontmcp restart ${name}`);\n}\n"]}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @file esm-update.ts
3
+ * @description CLI command for checking and applying ESM package updates.
4
+ *
5
+ * Reads the registry for ESM-installed apps, checks for updates using the
6
+ * VersionPoller, downloads and caches new versions, and updates the registry.
7
+ */
8
+ import { Command } from 'commander';
9
+ /**
10
+ * Register the `esm-update` subcommand.
11
+ *
12
+ * Usage:
13
+ * frontmcp package esm-update [app-name]
14
+ *
15
+ * Options:
16
+ * --check-only Only check for updates, don't apply them
17
+ * --all Update all ESM-installed apps
18
+ */
19
+ export declare function registerEsmUpdateCommand(program: Command): void;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ /**
3
+ * @file esm-update.ts
4
+ * @description CLI command for checking and applying ESM package updates.
5
+ *
6
+ * Reads the registry for ESM-installed apps, checks for updates using the
7
+ * VersionPoller, downloads and caches new versions, and updates the registry.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.registerEsmUpdateCommand = registerEsmUpdateCommand;
11
+ const registry_1 = require("./registry");
12
+ const paths_1 = require("../pm/paths");
13
+ /**
14
+ * Register the `esm-update` subcommand.
15
+ *
16
+ * Usage:
17
+ * frontmcp package esm-update [app-name]
18
+ *
19
+ * Options:
20
+ * --check-only Only check for updates, don't apply them
21
+ * --all Update all ESM-installed apps
22
+ */
23
+ function registerEsmUpdateCommand(program) {
24
+ program
25
+ .command('esm-update [app-name]')
26
+ .description('Check and apply ESM package updates')
27
+ .option('--check-only', 'Only check for updates without applying them', false)
28
+ .option('--all', 'Update all ESM-installed apps', false)
29
+ .action(async (appName, opts) => {
30
+ const { EsmCacheManager, EsmModuleLoader, parsePackageSpecifier } = await import('@frontmcp/sdk');
31
+ const registry = (0, registry_1.readRegistry)();
32
+ if (!registry) {
33
+ console.error('No registry found. Install an app first with `frontmcp package install`.');
34
+ process.exit(1);
35
+ }
36
+ // Find ESM apps to update
37
+ const esmApps = Object.entries(registry.apps).filter(([, app]) => {
38
+ if (appName && !opts.all) {
39
+ return app.source?.type === 'esm';
40
+ }
41
+ return app.source?.type === 'esm';
42
+ });
43
+ if (appName && !opts.all) {
44
+ const filtered = esmApps.filter(([name]) => name === appName);
45
+ if (filtered.length === 0) {
46
+ console.error(`App "${appName}" not found or is not an ESM app.`);
47
+ process.exit(1);
48
+ }
49
+ }
50
+ if (esmApps.length === 0) {
51
+ console.log('No ESM apps found in registry.');
52
+ return;
53
+ }
54
+ const cache = new EsmCacheManager({ cacheDir: paths_1.PM_DIRS.esmCache });
55
+ const loader = new EsmModuleLoader({ cache });
56
+ console.log(`Checking ${esmApps.length} ESM app(s) for updates...\n`);
57
+ for (const [name, app] of esmApps) {
58
+ if (appName && !opts.all && name !== appName)
59
+ continue;
60
+ const sourceRef = app.source?.ref;
61
+ if (!sourceRef)
62
+ continue;
63
+ try {
64
+ const specifier = parsePackageSpecifier(sourceRef);
65
+ const currentVersion = app.esmVersion ?? app.version;
66
+ // Check for updates
67
+ const result = await loader.resolveVersion(specifier);
68
+ if (result === currentVersion) {
69
+ console.log(` ${name}: up to date (${currentVersion})`);
70
+ continue;
71
+ }
72
+ console.log(` ${name}: ${currentVersion} → ${result}`);
73
+ if (opts.checkOnly)
74
+ continue;
75
+ // Apply the update
76
+ const loadResult = await loader.load(specifier);
77
+ app.esmVersion = loadResult.resolvedVersion;
78
+ app.esmCachePath = paths_1.PM_DIRS.esmCache;
79
+ app.lastUpdateCheck = new Date().toISOString();
80
+ app.version = loadResult.resolvedVersion;
81
+ console.log(` Updated to ${loadResult.resolvedVersion} (source: ${loadResult.source})`);
82
+ }
83
+ catch (error) {
84
+ console.error(` ${name}: failed - ${error.message}`);
85
+ }
86
+ }
87
+ if (!opts.checkOnly) {
88
+ (0, registry_1.writeRegistry)(registry);
89
+ console.log('\nRegistry updated.');
90
+ }
91
+ });
92
+ }
93
+ //# sourceMappingURL=esm-update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"esm-update.js","sourceRoot":"","sources":["../../../../src/commands/package/esm-update.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @file esm-update.ts\n * @description CLI command for checking and applying ESM package updates.\n *\n * Reads the registry for ESM-installed apps, checks for updates using the\n * VersionPoller, downloads and caches new versions, and updates the registry.\n */\n\nimport { Command } from 'commander';\nimport { readRegistry, writeRegistry } from './registry';\nimport { PM_DIRS } from '../pm/paths';\n\n/**\n * Register the `esm-update` subcommand.\n *\n * Usage:\n * frontmcp package esm-update [app-name]\n *\n * Options:\n * --check-only Only check for updates, don't apply them\n * --all Update all ESM-installed apps\n */\nexport function registerEsmUpdateCommand(program: Command): void {\n program\n .command('esm-update [app-name]')\n .description('Check and apply ESM package updates')\n .option('--check-only', 'Only check for updates without applying them', false)\n .option('--all', 'Update all ESM-installed apps', false)\n .action(async (appName: string | undefined, opts: { checkOnly: boolean; all: boolean }) => {\n const { EsmCacheManager, EsmModuleLoader, parsePackageSpecifier } = await import('@frontmcp/sdk');\n\n const registry = readRegistry();\n if (!registry) {\n console.error('No registry found. Install an app first with `frontmcp package install`.');\n process.exit(1);\n }\n\n // Find ESM apps to update\n const esmApps = Object.entries(registry.apps).filter(([, app]) => {\n if (appName && !opts.all) {\n return app.source?.type === 'esm';\n }\n return app.source?.type === 'esm';\n });\n\n if (appName && !opts.all) {\n const filtered = esmApps.filter(([name]) => name === appName);\n if (filtered.length === 0) {\n console.error(`App \"${appName}\" not found or is not an ESM app.`);\n process.exit(1);\n }\n }\n\n if (esmApps.length === 0) {\n console.log('No ESM apps found in registry.');\n return;\n }\n\n const cache = new EsmCacheManager({ cacheDir: PM_DIRS.esmCache });\n const loader = new EsmModuleLoader({ cache });\n\n console.log(`Checking ${esmApps.length} ESM app(s) for updates...\\n`);\n\n for (const [name, app] of esmApps) {\n if (appName && !opts.all && name !== appName) continue;\n\n const sourceRef = app.source?.ref;\n if (!sourceRef) continue;\n\n try {\n const specifier = parsePackageSpecifier(sourceRef);\n const currentVersion = app.esmVersion ?? app.version;\n\n // Check for updates\n const result = await loader.resolveVersion(specifier);\n\n if (result === currentVersion) {\n console.log(` ${name}: up to date (${currentVersion})`);\n continue;\n }\n\n console.log(` ${name}: ${currentVersion} → ${result}`);\n\n if (opts.checkOnly) continue;\n\n // Apply the update\n const loadResult = await loader.load(specifier);\n app.esmVersion = loadResult.resolvedVersion;\n app.esmCachePath = PM_DIRS.esmCache;\n app.lastUpdateCheck = new Date().toISOString();\n app.version = loadResult.resolvedVersion;\n\n console.log(` Updated to ${loadResult.resolvedVersion} (source: ${loadResult.source})`);\n } catch (error) {\n console.error(` ${name}: failed - ${(error as Error).message}`);\n }\n }\n\n if (!opts.checkOnly) {\n writeRegistry(registry);\n console.log('\\nRegistry updated.');\n }\n });\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * runInstall() orchestrator — installs an MCP app from npm, local, or git source.
3
3
  */
4
- import { ParsedArgs } from '../../args';
4
+ import { ParsedArgs } from '../../core/args';
5
5
  export declare function runInstall(opts: ParsedArgs): Promise<void>;
@@ -8,8 +8,8 @@ const tslib_1 = require("tslib");
8
8
  const path = tslib_1.__importStar(require("path"));
9
9
  const fs = tslib_1.__importStar(require("fs"));
10
10
  const os = tslib_1.__importStar(require("os"));
11
- const colors_1 = require("../../colors");
12
- const pm_paths_1 = require("../../pm/pm.paths");
11
+ const colors_1 = require("../../core/colors");
12
+ const paths_1 = require("../pm/paths");
13
13
  const types_1 = require("./types");
14
14
  const registry_1 = require("./registry");
15
15
  const questionnaire_1 = require("./questionnaire");
@@ -40,6 +40,9 @@ async function runInstall(opts) {
40
40
  case 'git':
41
41
  packageDir = await (0, git_1.fetchFromGit)(source.ref, tmpDir);
42
42
  break;
43
+ case 'esm':
44
+ throw new Error('ESM sources cannot be installed via "frontmcp install". ' +
45
+ 'Use loadFrom() in your FrontMcp config to load ESM packages at runtime.');
43
46
  }
44
47
  // 2. Look for manifest
45
48
  let manifest = findManifest(packageDir);
@@ -61,8 +64,8 @@ async function runInstall(opts) {
61
64
  }
62
65
  const { data: manifestData, dir: manifestDir } = manifest;
63
66
  // 4. Install to ~/.frontmcp/apps/{name}/
64
- const installDir = (0, pm_paths_1.appDir)(manifestData.name);
65
- (0, pm_paths_1.ensurePmDirs)();
67
+ const installDir = (0, paths_1.appDir)(manifestData.name);
68
+ (0, paths_1.ensurePmDirs)();
66
69
  fs.mkdirSync(installDir, { recursive: true });
67
70
  console.log(`${(0, colors_1.c)('cyan', '[install]')} installing "${manifestData.name}" to ${installDir}`);
68
71
  // Copy bundle + manifest + runner
@@ -147,4 +150,4 @@ function copyIfExists(fromDir, toDir, filename) {
147
150
  fs.copyFileSync(src, path.join(toDir, filename));
148
151
  }
149
152
  }
150
- //# sourceMappingURL=index.js.map
153
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../../src/commands/package/install.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * runInstall() orchestrator — installs an MCP app from npm, local, or git source.\n */\n\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport { ParsedArgs } from '../../core/args';\nimport { c } from '../../core/colors';\nimport { appDir, ensurePmDirs } from '../pm/paths';\nimport { parseInstallSource } from './types';\nimport { registerApp } from './registry';\nimport { runQuestionnaire, writeEnvFile } from './questionnaire';\nimport { fetchFromNpm } from './sources/npm';\nimport { fetchFromLocal } from './sources/local';\nimport { fetchFromGit } from './sources/git';\nimport { ExecManifest } from '../build/exec/manifest';\nimport { runCmd } from '@frontmcp/utils';\n\nexport async function runInstall(opts: ParsedArgs): Promise<void> {\n const sourceStr = opts._[1];\n if (!sourceStr) {\n throw new Error('Missing install source. Usage: frontmcp install <npm-package|./local-path|github:user/repo>');\n }\n\n const source = parseInstallSource(sourceStr);\n console.log(`${c('cyan', '[install]')} source: ${source.type} → ${source.ref}`);\n\n // Create temp directory\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'frontmcp-install-'));\n\n try {\n // 1. Fetch to temp directory\n console.log(`${c('cyan', '[install]')} fetching...`);\n let packageDir: string;\n\n switch (source.type) {\n case 'npm':\n packageDir = await fetchFromNpm(source.ref, tmpDir, opts.registry);\n break;\n case 'local':\n packageDir = await fetchFromLocal(source.ref, tmpDir);\n break;\n case 'git':\n packageDir = await fetchFromGit(source.ref, tmpDir);\n break;\n case 'esm':\n throw new Error(\n 'ESM sources cannot be installed via \"frontmcp install\". ' +\n 'Use loadFrom() in your FrontMcp config to load ESM packages at runtime.',\n );\n }\n\n // 2. Look for manifest\n let manifest = findManifest(packageDir);\n\n // 3. If no manifest, check for frontmcp.config.js and build\n if (!manifest) {\n const configPath = path.join(packageDir, 'frontmcp.config.js');\n const configJsonPath = path.join(packageDir, 'frontmcp.config.json');\n\n if (fs.existsSync(configPath) || fs.existsSync(configJsonPath)) {\n console.log(`${c('cyan', '[install]')} no manifest found, building from config...`);\n await runCmd('npx', ['frontmcp', 'build', '--exec'], {\n cwd: packageDir,\n });\n manifest = findManifest(path.join(packageDir, 'dist')) || findManifest(packageDir);\n }\n }\n\n if (!manifest) {\n throw new Error(\n 'Could not find or generate a manifest. Ensure the package has a ' +\n 'frontmcp.config.js or was built with \"frontmcp build --exec\".',\n );\n }\n\n const { data: manifestData, dir: manifestDir } = manifest;\n\n // 4. Install to ~/.frontmcp/apps/{name}/\n const installDir = appDir(manifestData.name);\n ensurePmDirs();\n fs.mkdirSync(installDir, { recursive: true });\n\n console.log(`${c('cyan', '[install]')} installing \"${manifestData.name}\" to ${installDir}`);\n\n // Copy bundle + manifest + runner\n copyIfExists(manifestDir, installDir, manifestData.bundle);\n copyIfExists(manifestDir, installDir, `${manifestData.name}.manifest.json`);\n copyIfExists(manifestDir, installDir, manifestData.name);\n\n // Make runner executable\n const runnerPath = path.join(installDir, manifestData.name);\n if (fs.existsSync(runnerPath)) {\n fs.chmodSync(runnerPath, 0o755);\n }\n\n // 5. Install native addons\n if (manifestData.dependencies.nativeAddons.length > 0) {\n console.log(`${c('cyan', '[install]')} installing native dependencies...`);\n await runCmd('npm', ['init', '-y', '--silent'], { cwd: installDir });\n await runCmd('npm', ['install', ...manifestData.dependencies.nativeAddons, '--save', '--silent'], {\n cwd: installDir,\n });\n }\n\n // 6. Set up SQLite data dir if needed\n if (manifestData.storage.type === 'sqlite') {\n const dataDir = path.join(os.homedir(), '.frontmcp', 'data', manifestData.name);\n fs.mkdirSync(dataDir, { recursive: true });\n }\n\n // 7. Run setup questionnaire\n if (manifestData.setup?.steps && manifestData.setup.steps.length > 0) {\n console.log(`\\n${c('bold', 'Setup Configuration')}`);\n const result = await runQuestionnaire(manifestData.setup.steps, {\n silent: opts.yes,\n });\n writeEnvFile(installDir, result.envContent);\n console.log(`${c('green', '[install]')} configuration saved to .env`);\n }\n\n // 8. Register in registry\n const port = opts.port || manifestData.network.defaultPort;\n registerApp(manifestData.name, {\n version: manifestData.version,\n installDir,\n installedAt: new Date().toISOString(),\n runner: path.join(installDir, manifestData.name),\n bundle: path.join(installDir, manifestData.bundle),\n storage: manifestData.storage.type,\n port,\n source: { type: source.type, ref: source.ref },\n });\n\n console.log(`\\n${c('green', `Installed \"${manifestData.name}\" successfully.`)}`);\n console.log(`\\n${c('bold', 'Start with:')}`);\n console.log(` frontmcp start ${manifestData.name}`);\n console.log(`\\n${c('bold', 'Reconfigure:')}`);\n console.log(` frontmcp configure ${manifestData.name}`);\n } finally {\n // Clean up temp directory\n try {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n } catch {\n // ignore cleanup errors\n }\n }\n}\n\nfunction findManifest(dir: string): { data: ExecManifest; dir: string } | null {\n if (!fs.existsSync(dir)) return null;\n\n const files = fs.readdirSync(dir);\n const manifestFile = files.find((f: string) => f.endsWith('.manifest.json'));\n\n if (manifestFile) {\n const manifestPath = path.join(dir, manifestFile);\n const data = JSON.parse(fs.readFileSync(manifestPath, 'utf-8')) as ExecManifest;\n return { data, dir };\n }\n\n // Check dist/ subdirectory\n const distDir = path.join(dir, 'dist');\n if (fs.existsSync(distDir)) {\n return findManifest(distDir);\n }\n\n return null;\n}\n\nfunction copyIfExists(fromDir: string, toDir: string, filename: string): void {\n const src = path.join(fromDir, filename);\n if (fs.existsSync(src)) {\n fs.copyFileSync(src, path.join(toDir, filename));\n }\n}\n"]}
@@ -9,8 +9,8 @@ exports.writeEnvFile = writeEnvFile;
9
9
  const tslib_1 = require("tslib");
10
10
  const fs = tslib_1.__importStar(require("fs"));
11
11
  const path = tslib_1.__importStar(require("path"));
12
- const colors_1 = require("../../colors");
13
- const prompts_1 = require("../../utils/prompts");
12
+ const colors_1 = require("../../core/colors");
13
+ const prompts_1 = require("../../shared/prompts");
14
14
  /**
15
15
  * Run the interactive questionnaire from manifest setup steps.
16
16
  */
@@ -1 +1 @@
1
- {"version":3,"file":"questionnaire.js","sourceRoot":"","sources":["../../../../src/commands/install/questionnaire.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Interactive setup questionnaire runner.\n * Reads manifest setup steps and prompts the user via @clack/prompts.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { c } from '../../colors';\nimport { ManifestSetupStep } from '../build/exec/manifest';\nimport { clack } from '../../utils/prompts';\n\nexport interface QuestionnaireResult {\n answers: Record<string, string>;\n envContent: string;\n}\n\n/**\n * Run the interactive questionnaire from manifest setup steps.\n */\nexport async function runQuestionnaire(\n steps: ManifestSetupStep[],\n opts: { silent?: boolean } = {},\n): Promise<QuestionnaireResult> {\n const answers: Record<string, string> = {};\n\n if (opts.silent) {\n return runSilent(steps);\n }\n\n const p = await clack();\n\n let currentIndex = 0;\n const stepMap = new Map(steps.map((s, i) => [s.id, i]));\n let currentGroup = '';\n\n while (currentIndex < steps.length) {\n const step = steps[currentIndex];\n\n // Check showWhen conditions\n if (step.showWhen && !evaluateShowWhen(step.showWhen, answers)) {\n currentIndex++;\n continue;\n }\n\n // Show group header\n if (step.group && step.group !== currentGroup) {\n currentGroup = step.group;\n p.log.step(`--- ${currentGroup} ---`);\n }\n\n // Determine prompt based on schema type\n const defaultValue = getDefaultFromSchema(step.jsonSchema);\n const value = await promptStep(step, defaultValue);\n\n answers[step.id] = value;\n\n // Determine next step\n currentIndex = resolveNextStep(step, value, currentIndex, stepMap, steps.length);\n }\n\n return {\n answers,\n envContent: answersToEnv(answers, steps),\n };\n}\n\nfunction runSilent(steps: ManifestSetupStep[]): QuestionnaireResult {\n const answers: Record<string, string> = {};\n const stepMap = new Map(steps.map((s, i) => [s.id, i]));\n let currentIndex = 0;\n\n while (currentIndex < steps.length) {\n const step = steps[currentIndex];\n\n if (step.showWhen && !evaluateShowWhen(step.showWhen, answers)) {\n currentIndex++;\n continue;\n }\n\n const defaultValue = getDefaultFromSchema(step.jsonSchema);\n if (defaultValue === undefined || defaultValue === '') {\n // Check if the step is required (no default)\n const isOptional =\n step.jsonSchema.default !== undefined || (step.jsonSchema as Record<string, unknown>).nullable === true;\n\n if (!isOptional) {\n throw new Error(\n `Setup step \"${step.id}\" requires input but --yes mode cannot provide a value. ` +\n `Set a default or provide values via environment variables.`,\n );\n }\n }\n\n answers[step.id] = defaultValue ?? '';\n\n currentIndex = resolveNextStep(step, answers[step.id], currentIndex, stepMap, steps.length);\n }\n\n return {\n answers,\n envContent: answersToEnv(answers, steps),\n };\n}\n\nasync function promptStep(step: ManifestSetupStep, defaultValue: string | undefined): Promise<string> {\n const schema = step.jsonSchema;\n\n // Enum → select menu\n if (schema.enum && Array.isArray(schema.enum)) {\n return promptEnum(step, schema.enum as string[], defaultValue);\n }\n\n // Boolean → confirm\n if (schema.type === 'boolean') {\n return promptBoolean(step, defaultValue);\n }\n\n // Default → text input\n return promptText(step, defaultValue);\n}\n\nasync function promptEnum(\n step: ManifestSetupStep,\n options: string[],\n defaultValue: string | undefined,\n): Promise<string> {\n const p = await clack();\n\n const message = step.description ? `${step.prompt}\\n${c('gray', step.description)}` : step.prompt;\n\n const result = await p.select({\n message,\n options: options.map((opt) => ({ label: opt, value: opt })),\n initialValue: defaultValue ?? options[0],\n });\n\n if (p.isCancel(result)) {\n p.cancel('Cancelled.');\n process.exit(0);\n }\n\n return result;\n}\n\nasync function promptBoolean(step: ManifestSetupStep, defaultValue: string | undefined): Promise<string> {\n const p = await clack();\n\n const result = await p.confirm({\n message: step.prompt,\n initialValue: defaultValue === undefined ? false : defaultValue === 'true',\n });\n\n if (p.isCancel(result)) {\n p.cancel('Cancelled.');\n process.exit(0);\n }\n\n return result ? 'true' : 'false';\n}\n\nasync function promptText(step: ManifestSetupStep, defaultValue: string | undefined): Promise<string> {\n const p = await clack();\n\n const schema = step.jsonSchema;\n const isOptional = schema.default !== undefined || (schema as Record<string, unknown>).nullable === true;\n\n const result = await p.text({\n message: step.prompt,\n placeholder: step.description || (step.sensitive && defaultValue ? '****' : undefined),\n defaultValue,\n validate: (val) => {\n const trimmed = val.trim();\n if (!trimmed && !defaultValue && !isOptional) {\n return 'This field is required.';\n }\n if (trimmed) {\n const error = validateAgainstSchema(trimmed, step.jsonSchema);\n if (error) return error;\n }\n return undefined;\n },\n });\n\n if (p.isCancel(result)) {\n p.cancel('Cancelled.');\n process.exit(0);\n }\n\n return result.trim() || defaultValue || '';\n}\n\nfunction validateAgainstSchema(value: string, schema: Record<string, unknown>): string | null {\n if (schema.minLength && typeof schema.minLength === 'number' && value.length < schema.minLength) {\n return `Minimum length is ${schema.minLength}`;\n }\n if (schema.maxLength && typeof schema.maxLength === 'number' && value.length > schema.maxLength) {\n return `Maximum length is ${schema.maxLength}`;\n }\n if (schema.pattern && typeof schema.pattern === 'string') {\n let re: RegExp;\n try {\n re = new RegExp(schema.pattern);\n } catch {\n return `Invalid pattern in schema: ${schema.pattern}`;\n }\n if (!re.test(value)) return `Value must match pattern: ${schema.pattern}`;\n }\n if (schema.type === 'number' || schema.type === 'integer') {\n const n = Number(value);\n if (isNaN(n)) return 'Must be a number';\n if (schema.minimum !== undefined && typeof schema.minimum === 'number' && n < schema.minimum) {\n return `Minimum value is ${schema.minimum}`;\n }\n if (schema.maximum !== undefined && typeof schema.maximum === 'number' && n > schema.maximum) {\n return `Maximum value is ${schema.maximum}`;\n }\n }\n if (schema.format === 'uri') {\n try {\n new URL(value);\n } catch {\n return 'Must be a valid URL';\n }\n }\n return null;\n}\n\nfunction evaluateShowWhen(conditions: Record<string, string | string[]>, answers: Record<string, string>): boolean {\n for (const [stepId, expected] of Object.entries(conditions)) {\n const actual = answers[stepId];\n if (actual === undefined) return false;\n\n if (Array.isArray(expected)) {\n if (!expected.includes(actual)) return false;\n } else {\n if (actual !== expected) return false;\n }\n }\n return true;\n}\n\nfunction resolveNextStep(\n step: ManifestSetupStep,\n answer: string,\n currentIndex: number,\n stepMap: Map<string, number>,\n totalSteps: number,\n): number {\n if (!step.next) return currentIndex + 1;\n\n if (typeof step.next === 'string') {\n const idx = stepMap.get(step.next);\n return idx !== undefined ? idx : totalSteps; // end if target not found\n }\n\n // Record-based routing\n const target = step.next[answer];\n if (target) {\n const idx = stepMap.get(target);\n return idx !== undefined ? idx : totalSteps;\n }\n\n return currentIndex + 1;\n}\n\nfunction getDefaultFromSchema(schema: Record<string, unknown>): string | undefined {\n if (schema.default !== undefined) {\n return String(schema.default);\n }\n return undefined;\n}\n\nfunction answersToEnv(answers: Record<string, string>, steps: ManifestSetupStep[]): string {\n const lines: string[] = ['# Generated by frontmcp install'];\n\n let currentGroup = '';\n for (const step of steps) {\n const value = answers[step.id];\n if (value === undefined) continue;\n\n if (step.group && step.group !== currentGroup) {\n currentGroup = step.group;\n lines.push(`\\n# ${currentGroup}`);\n }\n\n const envName = step.env;\n // Quote values that contain special characters\n const needsQuotes = /[\\s#\"'\\\\]/.test(value) || value.includes('=');\n const quotedValue = needsQuotes ? `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"` : value;\n\n lines.push(`${envName}=${quotedValue}`);\n }\n\n return lines.join('\\n') + '\\n';\n}\n\n/**\n * Write .env file for an installed app.\n */\nexport function writeEnvFile(appDir: string, content: string): void {\n const envPath = path.join(appDir, '.env');\n fs.writeFileSync(envPath, content, 'utf-8');\n}\n"]}
1
+ {"version":3,"file":"questionnaire.js","sourceRoot":"","sources":["../../../../src/commands/package/questionnaire.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Interactive setup questionnaire runner.\n * Reads manifest setup steps and prompts the user via @clack/prompts.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { c } from '../../core/colors';\nimport { ManifestSetupStep } from '../build/exec/manifest';\nimport { clack } from '../../shared/prompts';\n\nexport interface QuestionnaireResult {\n answers: Record<string, string>;\n envContent: string;\n}\n\n/**\n * Run the interactive questionnaire from manifest setup steps.\n */\nexport async function runQuestionnaire(\n steps: ManifestSetupStep[],\n opts: { silent?: boolean } = {},\n): Promise<QuestionnaireResult> {\n const answers: Record<string, string> = {};\n\n if (opts.silent) {\n return runSilent(steps);\n }\n\n const p = await clack();\n\n let currentIndex = 0;\n const stepMap = new Map(steps.map((s, i) => [s.id, i]));\n let currentGroup = '';\n\n while (currentIndex < steps.length) {\n const step = steps[currentIndex];\n\n // Check showWhen conditions\n if (step.showWhen && !evaluateShowWhen(step.showWhen, answers)) {\n currentIndex++;\n continue;\n }\n\n // Show group header\n if (step.group && step.group !== currentGroup) {\n currentGroup = step.group;\n p.log.step(`--- ${currentGroup} ---`);\n }\n\n // Determine prompt based on schema type\n const defaultValue = getDefaultFromSchema(step.jsonSchema);\n const value = await promptStep(step, defaultValue);\n\n answers[step.id] = value;\n\n // Determine next step\n currentIndex = resolveNextStep(step, value, currentIndex, stepMap, steps.length);\n }\n\n return {\n answers,\n envContent: answersToEnv(answers, steps),\n };\n}\n\nfunction runSilent(steps: ManifestSetupStep[]): QuestionnaireResult {\n const answers: Record<string, string> = {};\n const stepMap = new Map(steps.map((s, i) => [s.id, i]));\n let currentIndex = 0;\n\n while (currentIndex < steps.length) {\n const step = steps[currentIndex];\n\n if (step.showWhen && !evaluateShowWhen(step.showWhen, answers)) {\n currentIndex++;\n continue;\n }\n\n const defaultValue = getDefaultFromSchema(step.jsonSchema);\n if (defaultValue === undefined || defaultValue === '') {\n // Check if the step is required (no default)\n const isOptional =\n step.jsonSchema.default !== undefined || (step.jsonSchema as Record<string, unknown>).nullable === true;\n\n if (!isOptional) {\n throw new Error(\n `Setup step \"${step.id}\" requires input but --yes mode cannot provide a value. ` +\n `Set a default or provide values via environment variables.`,\n );\n }\n }\n\n answers[step.id] = defaultValue ?? '';\n\n currentIndex = resolveNextStep(step, answers[step.id], currentIndex, stepMap, steps.length);\n }\n\n return {\n answers,\n envContent: answersToEnv(answers, steps),\n };\n}\n\nasync function promptStep(step: ManifestSetupStep, defaultValue: string | undefined): Promise<string> {\n const schema = step.jsonSchema;\n\n // Enum → select menu\n if (schema.enum && Array.isArray(schema.enum)) {\n return promptEnum(step, schema.enum as string[], defaultValue);\n }\n\n // Boolean → confirm\n if (schema.type === 'boolean') {\n return promptBoolean(step, defaultValue);\n }\n\n // Default → text input\n return promptText(step, defaultValue);\n}\n\nasync function promptEnum(\n step: ManifestSetupStep,\n options: string[],\n defaultValue: string | undefined,\n): Promise<string> {\n const p = await clack();\n\n const message = step.description ? `${step.prompt}\\n${c('gray', step.description)}` : step.prompt;\n\n const result = await p.select({\n message,\n options: options.map((opt) => ({ label: opt, value: opt })),\n initialValue: defaultValue ?? options[0],\n });\n\n if (p.isCancel(result)) {\n p.cancel('Cancelled.');\n process.exit(0);\n }\n\n return result;\n}\n\nasync function promptBoolean(step: ManifestSetupStep, defaultValue: string | undefined): Promise<string> {\n const p = await clack();\n\n const result = await p.confirm({\n message: step.prompt,\n initialValue: defaultValue === undefined ? false : defaultValue === 'true',\n });\n\n if (p.isCancel(result)) {\n p.cancel('Cancelled.');\n process.exit(0);\n }\n\n return result ? 'true' : 'false';\n}\n\nasync function promptText(step: ManifestSetupStep, defaultValue: string | undefined): Promise<string> {\n const p = await clack();\n\n const schema = step.jsonSchema;\n const isOptional = schema.default !== undefined || (schema as Record<string, unknown>).nullable === true;\n\n const result = await p.text({\n message: step.prompt,\n placeholder: step.description || (step.sensitive && defaultValue ? '****' : undefined),\n defaultValue,\n validate: (val) => {\n const trimmed = val.trim();\n if (!trimmed && !defaultValue && !isOptional) {\n return 'This field is required.';\n }\n if (trimmed) {\n const error = validateAgainstSchema(trimmed, step.jsonSchema);\n if (error) return error;\n }\n return undefined;\n },\n });\n\n if (p.isCancel(result)) {\n p.cancel('Cancelled.');\n process.exit(0);\n }\n\n return result.trim() || defaultValue || '';\n}\n\nfunction validateAgainstSchema(value: string, schema: Record<string, unknown>): string | null {\n if (schema.minLength && typeof schema.minLength === 'number' && value.length < schema.minLength) {\n return `Minimum length is ${schema.minLength}`;\n }\n if (schema.maxLength && typeof schema.maxLength === 'number' && value.length > schema.maxLength) {\n return `Maximum length is ${schema.maxLength}`;\n }\n if (schema.pattern && typeof schema.pattern === 'string') {\n let re: RegExp;\n try {\n re = new RegExp(schema.pattern);\n } catch {\n return `Invalid pattern in schema: ${schema.pattern}`;\n }\n if (!re.test(value)) return `Value must match pattern: ${schema.pattern}`;\n }\n if (schema.type === 'number' || schema.type === 'integer') {\n const n = Number(value);\n if (isNaN(n)) return 'Must be a number';\n if (schema.minimum !== undefined && typeof schema.minimum === 'number' && n < schema.minimum) {\n return `Minimum value is ${schema.minimum}`;\n }\n if (schema.maximum !== undefined && typeof schema.maximum === 'number' && n > schema.maximum) {\n return `Maximum value is ${schema.maximum}`;\n }\n }\n if (schema.format === 'uri') {\n try {\n new URL(value);\n } catch {\n return 'Must be a valid URL';\n }\n }\n return null;\n}\n\nfunction evaluateShowWhen(conditions: Record<string, string | string[]>, answers: Record<string, string>): boolean {\n for (const [stepId, expected] of Object.entries(conditions)) {\n const actual = answers[stepId];\n if (actual === undefined) return false;\n\n if (Array.isArray(expected)) {\n if (!expected.includes(actual)) return false;\n } else {\n if (actual !== expected) return false;\n }\n }\n return true;\n}\n\nfunction resolveNextStep(\n step: ManifestSetupStep,\n answer: string,\n currentIndex: number,\n stepMap: Map<string, number>,\n totalSteps: number,\n): number {\n if (!step.next) return currentIndex + 1;\n\n if (typeof step.next === 'string') {\n const idx = stepMap.get(step.next);\n return idx !== undefined ? idx : totalSteps; // end if target not found\n }\n\n // Record-based routing\n const target = step.next[answer];\n if (target) {\n const idx = stepMap.get(target);\n return idx !== undefined ? idx : totalSteps;\n }\n\n return currentIndex + 1;\n}\n\nfunction getDefaultFromSchema(schema: Record<string, unknown>): string | undefined {\n if (schema.default !== undefined) {\n return String(schema.default);\n }\n return undefined;\n}\n\nfunction answersToEnv(answers: Record<string, string>, steps: ManifestSetupStep[]): string {\n const lines: string[] = ['# Generated by frontmcp install'];\n\n let currentGroup = '';\n for (const step of steps) {\n const value = answers[step.id];\n if (value === undefined) continue;\n\n if (step.group && step.group !== currentGroup) {\n currentGroup = step.group;\n lines.push(`\\n# ${currentGroup}`);\n }\n\n const envName = step.env;\n // Quote values that contain special characters\n const needsQuotes = /[\\s#\"'\\\\]/.test(value) || value.includes('=');\n const quotedValue = needsQuotes ? `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"` : value;\n\n lines.push(`${envName}=${quotedValue}`);\n }\n\n return lines.join('\\n') + '\\n';\n}\n\n/**\n * Write .env file for an installed app.\n */\nexport function writeEnvFile(appDir: string, content: string): void {\n const envPath = path.join(appDir, '.env');\n fs.writeFileSync(envPath, content, 'utf-8');\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerPackageCommands(program: Command): void;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerPackageCommands = registerPackageCommands;
4
+ const bridge_1 = require("../../core/bridge");
5
+ function registerPackageCommands(program) {
6
+ program
7
+ .command('install')
8
+ .description('Install an MCP app from npm, local path, or git')
9
+ .argument('<source>', 'Package source (npm package, local path, or github:user/repo)')
10
+ .option('--registry <url>', 'npm registry URL for private packages')
11
+ .option('-y, --yes', 'Silent mode (use defaults, skip questionnaire)')
12
+ .option('-p, --port <N>', 'Override default port', parseInt)
13
+ .action(async (source, options) => {
14
+ const { runInstall } = await import('./install.js');
15
+ await runInstall((0, bridge_1.toParsedArgs)('install', [source], options));
16
+ });
17
+ program
18
+ .command('uninstall')
19
+ .description('Remove an installed MCP app')
20
+ .argument('<name>', 'App name')
21
+ .action(async (name) => {
22
+ const { runUninstall } = await import('./uninstall.js');
23
+ await runUninstall((0, bridge_1.toParsedArgs)('uninstall', [name], {}));
24
+ });
25
+ program
26
+ .command('configure')
27
+ .description('Re-run setup questionnaire for an installed app')
28
+ .argument('<name>', 'App name')
29
+ .option('-y, --yes', 'Silent mode (use defaults)')
30
+ .action(async (name, options) => {
31
+ const { runConfigure } = await import('./configure.js');
32
+ await runConfigure((0, bridge_1.toParsedArgs)('configure', [name], options));
33
+ });
34
+ }
35
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../../../src/commands/package/register.ts"],"names":[],"mappings":";;AAGA,0DA+BC;AAjCD,8CAAiD;AAEjD,SAAgB,uBAAuB,CAAC,OAAgB;IACtD,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,iDAAiD,CAAC;SAC9D,QAAQ,CAAC,UAAU,EAAE,+DAA+D,CAAC;SACrF,MAAM,CAAC,kBAAkB,EAAE,uCAAuC,CAAC;SACnE,MAAM,CAAC,WAAW,EAAE,gDAAgD,CAAC;SACrE,MAAM,CAAC,gBAAgB,EAAE,uBAAuB,EAAE,QAAQ,CAAC;SAC3D,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,OAA4D,EAAE,EAAE;QAC7F,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACpD,MAAM,UAAU,CAAC,IAAA,qBAAY,EAAC,SAAS,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,6BAA6B,CAAC;SAC1C,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;SAC9B,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE;QAC7B,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACxD,MAAM,YAAY,CAAC,IAAA,qBAAY,EAAC,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,iDAAiD,CAAC;SAC9D,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;SAC9B,MAAM,CAAC,WAAW,EAAE,4BAA4B,CAAC;SACjD,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,OAA0B,EAAE,EAAE;QACzD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACxD,MAAM,YAAY,CAAC,IAAA,qBAAY,EAAC,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACP,CAAC","sourcesContent":["import { Command } from 'commander';\nimport { toParsedArgs } from '../../core/bridge';\n\nexport function registerPackageCommands(program: Command): void {\n program\n .command('install')\n .description('Install an MCP app from npm, local path, or git')\n .argument('<source>', 'Package source (npm package, local path, or github:user/repo)')\n .option('--registry <url>', 'npm registry URL for private packages')\n .option('-y, --yes', 'Silent mode (use defaults, skip questionnaire)')\n .option('-p, --port <N>', 'Override default port', parseInt)\n .action(async (source: string, options: { registry?: string; yes?: boolean; port?: number }) => {\n const { runInstall } = await import('./install.js');\n await runInstall(toParsedArgs('install', [source], options));\n });\n\n program\n .command('uninstall')\n .description('Remove an installed MCP app')\n .argument('<name>', 'App name')\n .action(async (name: string) => {\n const { runUninstall } = await import('./uninstall.js');\n await runUninstall(toParsedArgs('uninstall', [name], {}));\n });\n\n program\n .command('configure')\n .description('Re-run setup questionnaire for an installed app')\n .argument('<name>', 'App name')\n .option('-y, --yes', 'Silent mode (use defaults)')\n .action(async (name: string, options: { yes?: boolean }) => {\n const { runConfigure } = await import('./configure.js');\n await runConfigure(toParsedArgs('configure', [name], options));\n });\n}\n"]}
@@ -11,25 +11,27 @@ exports.getRegisteredApp = getRegisteredApp;
11
11
  exports.listRegisteredApps = listRegisteredApps;
12
12
  const tslib_1 = require("tslib");
13
13
  const fs = tslib_1.__importStar(require("fs"));
14
- const pm_paths_1 = require("../../pm/pm.paths");
14
+ const paths_1 = require("../pm/paths");
15
15
  function emptyRegistry() {
16
16
  return { version: 1, apps: {} };
17
17
  }
18
18
  function readRegistry() {
19
- const filePath = (0, pm_paths_1.registryPath)();
19
+ const filePath = (0, paths_1.registryPath)();
20
20
  try {
21
21
  if (!fs.existsSync(filePath))
22
22
  return emptyRegistry();
23
23
  const content = fs.readFileSync(filePath, 'utf-8');
24
24
  return JSON.parse(content);
25
25
  }
26
- catch {
27
- return emptyRegistry();
26
+ catch (err) {
27
+ throw new Error(`Failed to read registry at ${filePath}: ${err instanceof Error ? err.message : String(err)}`, {
28
+ cause: err,
29
+ });
28
30
  }
29
31
  }
30
32
  function writeRegistry(registry) {
31
- (0, pm_paths_1.ensurePmDirs)();
32
- const filePath = (0, pm_paths_1.registryPath)();
33
+ (0, paths_1.ensurePmDirs)();
34
+ const filePath = (0, paths_1.registryPath)();
33
35
  fs.writeFileSync(filePath, JSON.stringify(registry, null, 2), 'utf-8');
34
36
  }
35
37
  function registerApp(name, data) {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../../src/commands/package/registry.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAUH,oCAWC;AAED,sCAIC;AAED,kCAIC;AAED,sCAMC;AAED,4CAGC;AAED,gDASC;;AAvDD,+CAAyB;AACzB,uCAAyD;AAGzD,SAAS,aAAa;IACpB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AAClC,CAAC;AAED,SAAgB,YAAY;IAC1B,MAAM,QAAQ,GAAG,IAAA,oBAAY,GAAE,CAAC;IAChC,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,aAAa,EAAE,CAAC;QACrD,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAqB,CAAC;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,8BAA8B,QAAQ,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE;YAC7G,KAAK,EAAE,GAAG;SACX,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,SAAgB,aAAa,CAAC,QAA0B;IACtD,IAAA,oBAAY,GAAE,CAAC;IACf,MAAM,QAAQ,GAAG,IAAA,oBAAY,GAAE,CAAC;IAChC,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACzE,CAAC;AAED,SAAgB,WAAW,CAAC,IAAY,EAAE,IAAsC;IAC9E,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3B,aAAa,CAAC,QAAQ,CAAC,CAAC;AAC1B,CAAC;AAED,SAAgB,aAAa,CAAC,IAAY;IACxC,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3B,aAAa,CAAC,QAAQ,CAAC,CAAC;IACxB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,gBAAgB,CAAC,IAAY;IAC3C,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;AACrC,CAAC;AAED,SAAgB,kBAAkB;IAIhC,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1D,IAAI;QACJ,IAAI;KACL,CAAC,CAAC,CAAC;AACN,CAAC","sourcesContent":["/**\n * ~/.frontmcp/registry.json CRUD operations.\n */\n\nimport * as fs from 'fs';\nimport { registryPath, ensurePmDirs } from '../pm/paths';\nimport { FrontmcpRegistry } from './types';\n\nfunction emptyRegistry(): FrontmcpRegistry {\n return { version: 1, apps: {} };\n}\n\nexport function readRegistry(): FrontmcpRegistry {\n const filePath = registryPath();\n try {\n if (!fs.existsSync(filePath)) return emptyRegistry();\n const content = fs.readFileSync(filePath, 'utf-8');\n return JSON.parse(content) as FrontmcpRegistry;\n } catch (err) {\n throw new Error(`Failed to read registry at ${filePath}: ${err instanceof Error ? err.message : String(err)}`, {\n cause: err,\n });\n }\n}\n\nexport function writeRegistry(registry: FrontmcpRegistry): void {\n ensurePmDirs();\n const filePath = registryPath();\n fs.writeFileSync(filePath, JSON.stringify(registry, null, 2), 'utf-8');\n}\n\nexport function registerApp(name: string, data: FrontmcpRegistry['apps'][string]): void {\n const registry = readRegistry();\n registry.apps[name] = data;\n writeRegistry(registry);\n}\n\nexport function unregisterApp(name: string): boolean {\n const registry = readRegistry();\n if (!registry.apps[name]) return false;\n delete registry.apps[name];\n writeRegistry(registry);\n return true;\n}\n\nexport function getRegisteredApp(name: string): FrontmcpRegistry['apps'][string] | null {\n const registry = readRegistry();\n return registry.apps[name] ?? null;\n}\n\nexport function listRegisteredApps(): Array<{\n name: string;\n data: FrontmcpRegistry['apps'][string];\n}> {\n const registry = readRegistry();\n return Object.entries(registry.apps).map(([name, data]) => ({\n name,\n data,\n }));\n}\n"]}