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