mstro-app 0.1.47

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 (213) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +177 -0
  3. package/bin/commands/config.js +145 -0
  4. package/bin/commands/login.js +313 -0
  5. package/bin/commands/logout.js +75 -0
  6. package/bin/commands/status.js +197 -0
  7. package/bin/commands/whoami.js +161 -0
  8. package/bin/configure-claude.js +298 -0
  9. package/bin/mstro.js +581 -0
  10. package/bin/postinstall.js +45 -0
  11. package/bin/release.sh +110 -0
  12. package/dist/server/cli/headless/claude-invoker.d.ts +17 -0
  13. package/dist/server/cli/headless/claude-invoker.d.ts.map +1 -0
  14. package/dist/server/cli/headless/claude-invoker.js +311 -0
  15. package/dist/server/cli/headless/claude-invoker.js.map +1 -0
  16. package/dist/server/cli/headless/index.d.ts +13 -0
  17. package/dist/server/cli/headless/index.d.ts.map +1 -0
  18. package/dist/server/cli/headless/index.js +10 -0
  19. package/dist/server/cli/headless/index.js.map +1 -0
  20. package/dist/server/cli/headless/mcp-config.d.ts +11 -0
  21. package/dist/server/cli/headless/mcp-config.d.ts.map +1 -0
  22. package/dist/server/cli/headless/mcp-config.js +76 -0
  23. package/dist/server/cli/headless/mcp-config.js.map +1 -0
  24. package/dist/server/cli/headless/output-utils.d.ts +33 -0
  25. package/dist/server/cli/headless/output-utils.d.ts.map +1 -0
  26. package/dist/server/cli/headless/output-utils.js +101 -0
  27. package/dist/server/cli/headless/output-utils.js.map +1 -0
  28. package/dist/server/cli/headless/prompt-utils.d.ts +21 -0
  29. package/dist/server/cli/headless/prompt-utils.d.ts.map +1 -0
  30. package/dist/server/cli/headless/prompt-utils.js +84 -0
  31. package/dist/server/cli/headless/prompt-utils.js.map +1 -0
  32. package/dist/server/cli/headless/runner.d.ts +24 -0
  33. package/dist/server/cli/headless/runner.d.ts.map +1 -0
  34. package/dist/server/cli/headless/runner.js +99 -0
  35. package/dist/server/cli/headless/runner.js.map +1 -0
  36. package/dist/server/cli/headless/types.d.ts +106 -0
  37. package/dist/server/cli/headless/types.d.ts.map +1 -0
  38. package/dist/server/cli/headless/types.js +4 -0
  39. package/dist/server/cli/headless/types.js.map +1 -0
  40. package/dist/server/cli/improvisation-session-manager.d.ts +155 -0
  41. package/dist/server/cli/improvisation-session-manager.d.ts.map +1 -0
  42. package/dist/server/cli/improvisation-session-manager.js +415 -0
  43. package/dist/server/cli/improvisation-session-manager.js.map +1 -0
  44. package/dist/server/index.d.ts +2 -0
  45. package/dist/server/index.d.ts.map +1 -0
  46. package/dist/server/index.js +386 -0
  47. package/dist/server/index.js.map +1 -0
  48. package/dist/server/mcp/bouncer-cli.d.ts +3 -0
  49. package/dist/server/mcp/bouncer-cli.d.ts.map +1 -0
  50. package/dist/server/mcp/bouncer-cli.js +99 -0
  51. package/dist/server/mcp/bouncer-cli.js.map +1 -0
  52. package/dist/server/mcp/bouncer-integration.d.ts +36 -0
  53. package/dist/server/mcp/bouncer-integration.d.ts.map +1 -0
  54. package/dist/server/mcp/bouncer-integration.js +301 -0
  55. package/dist/server/mcp/bouncer-integration.js.map +1 -0
  56. package/dist/server/mcp/security-audit.d.ts +52 -0
  57. package/dist/server/mcp/security-audit.d.ts.map +1 -0
  58. package/dist/server/mcp/security-audit.js +118 -0
  59. package/dist/server/mcp/security-audit.js.map +1 -0
  60. package/dist/server/mcp/security-patterns.d.ts +73 -0
  61. package/dist/server/mcp/security-patterns.d.ts.map +1 -0
  62. package/dist/server/mcp/security-patterns.js +247 -0
  63. package/dist/server/mcp/security-patterns.js.map +1 -0
  64. package/dist/server/mcp/server.d.ts +3 -0
  65. package/dist/server/mcp/server.d.ts.map +1 -0
  66. package/dist/server/mcp/server.js +146 -0
  67. package/dist/server/mcp/server.js.map +1 -0
  68. package/dist/server/routes/files.d.ts +9 -0
  69. package/dist/server/routes/files.d.ts.map +1 -0
  70. package/dist/server/routes/files.js +24 -0
  71. package/dist/server/routes/files.js.map +1 -0
  72. package/dist/server/routes/improvise.d.ts +3 -0
  73. package/dist/server/routes/improvise.d.ts.map +1 -0
  74. package/dist/server/routes/improvise.js +72 -0
  75. package/dist/server/routes/improvise.js.map +1 -0
  76. package/dist/server/routes/index.d.ts +10 -0
  77. package/dist/server/routes/index.d.ts.map +1 -0
  78. package/dist/server/routes/index.js +12 -0
  79. package/dist/server/routes/index.js.map +1 -0
  80. package/dist/server/routes/instances.d.ts +10 -0
  81. package/dist/server/routes/instances.d.ts.map +1 -0
  82. package/dist/server/routes/instances.js +47 -0
  83. package/dist/server/routes/instances.js.map +1 -0
  84. package/dist/server/routes/notifications.d.ts +3 -0
  85. package/dist/server/routes/notifications.d.ts.map +1 -0
  86. package/dist/server/routes/notifications.js +136 -0
  87. package/dist/server/routes/notifications.js.map +1 -0
  88. package/dist/server/services/analytics.d.ts +56 -0
  89. package/dist/server/services/analytics.d.ts.map +1 -0
  90. package/dist/server/services/analytics.js +240 -0
  91. package/dist/server/services/analytics.js.map +1 -0
  92. package/dist/server/services/auth.d.ts +26 -0
  93. package/dist/server/services/auth.d.ts.map +1 -0
  94. package/dist/server/services/auth.js +71 -0
  95. package/dist/server/services/auth.js.map +1 -0
  96. package/dist/server/services/client-id.d.ts +10 -0
  97. package/dist/server/services/client-id.d.ts.map +1 -0
  98. package/dist/server/services/client-id.js +61 -0
  99. package/dist/server/services/client-id.js.map +1 -0
  100. package/dist/server/services/credentials.d.ts +39 -0
  101. package/dist/server/services/credentials.d.ts.map +1 -0
  102. package/dist/server/services/credentials.js +110 -0
  103. package/dist/server/services/credentials.js.map +1 -0
  104. package/dist/server/services/files.d.ts +119 -0
  105. package/dist/server/services/files.d.ts.map +1 -0
  106. package/dist/server/services/files.js +560 -0
  107. package/dist/server/services/files.js.map +1 -0
  108. package/dist/server/services/instances.d.ts +52 -0
  109. package/dist/server/services/instances.d.ts.map +1 -0
  110. package/dist/server/services/instances.js +241 -0
  111. package/dist/server/services/instances.js.map +1 -0
  112. package/dist/server/services/pathUtils.d.ts +47 -0
  113. package/dist/server/services/pathUtils.d.ts.map +1 -0
  114. package/dist/server/services/pathUtils.js +124 -0
  115. package/dist/server/services/pathUtils.js.map +1 -0
  116. package/dist/server/services/platform.d.ts +72 -0
  117. package/dist/server/services/platform.d.ts.map +1 -0
  118. package/dist/server/services/platform.js +368 -0
  119. package/dist/server/services/platform.js.map +1 -0
  120. package/dist/server/services/sentry.d.ts +5 -0
  121. package/dist/server/services/sentry.d.ts.map +1 -0
  122. package/dist/server/services/sentry.js +71 -0
  123. package/dist/server/services/sentry.js.map +1 -0
  124. package/dist/server/services/terminal/pty-manager.d.ts +149 -0
  125. package/dist/server/services/terminal/pty-manager.d.ts.map +1 -0
  126. package/dist/server/services/terminal/pty-manager.js +377 -0
  127. package/dist/server/services/terminal/pty-manager.js.map +1 -0
  128. package/dist/server/services/terminal/tmux-manager.d.ts +82 -0
  129. package/dist/server/services/terminal/tmux-manager.d.ts.map +1 -0
  130. package/dist/server/services/terminal/tmux-manager.js +352 -0
  131. package/dist/server/services/terminal/tmux-manager.js.map +1 -0
  132. package/dist/server/services/websocket/autocomplete.d.ts +50 -0
  133. package/dist/server/services/websocket/autocomplete.d.ts.map +1 -0
  134. package/dist/server/services/websocket/autocomplete.js +361 -0
  135. package/dist/server/services/websocket/autocomplete.js.map +1 -0
  136. package/dist/server/services/websocket/file-utils.d.ts +44 -0
  137. package/dist/server/services/websocket/file-utils.d.ts.map +1 -0
  138. package/dist/server/services/websocket/file-utils.js +272 -0
  139. package/dist/server/services/websocket/file-utils.js.map +1 -0
  140. package/dist/server/services/websocket/handler.d.ts +246 -0
  141. package/dist/server/services/websocket/handler.d.ts.map +1 -0
  142. package/dist/server/services/websocket/handler.js +1771 -0
  143. package/dist/server/services/websocket/handler.js.map +1 -0
  144. package/dist/server/services/websocket/index.d.ts +11 -0
  145. package/dist/server/services/websocket/index.d.ts.map +1 -0
  146. package/dist/server/services/websocket/index.js +14 -0
  147. package/dist/server/services/websocket/index.js.map +1 -0
  148. package/dist/server/services/websocket/types.d.ts +214 -0
  149. package/dist/server/services/websocket/types.d.ts.map +1 -0
  150. package/dist/server/services/websocket/types.js +4 -0
  151. package/dist/server/services/websocket/types.js.map +1 -0
  152. package/dist/server/utils/agent-manager.d.ts +69 -0
  153. package/dist/server/utils/agent-manager.d.ts.map +1 -0
  154. package/dist/server/utils/agent-manager.js +269 -0
  155. package/dist/server/utils/agent-manager.js.map +1 -0
  156. package/dist/server/utils/paths.d.ts +25 -0
  157. package/dist/server/utils/paths.d.ts.map +1 -0
  158. package/dist/server/utils/paths.js +38 -0
  159. package/dist/server/utils/paths.js.map +1 -0
  160. package/dist/server/utils/port-manager.d.ts +10 -0
  161. package/dist/server/utils/port-manager.d.ts.map +1 -0
  162. package/dist/server/utils/port-manager.js +60 -0
  163. package/dist/server/utils/port-manager.js.map +1 -0
  164. package/dist/server/utils/port.d.ts +26 -0
  165. package/dist/server/utils/port.d.ts.map +1 -0
  166. package/dist/server/utils/port.js +83 -0
  167. package/dist/server/utils/port.js.map +1 -0
  168. package/hooks/bouncer.sh +138 -0
  169. package/package.json +74 -0
  170. package/server/README.md +191 -0
  171. package/server/cli/headless/claude-invoker.ts +415 -0
  172. package/server/cli/headless/index.ts +39 -0
  173. package/server/cli/headless/mcp-config.ts +87 -0
  174. package/server/cli/headless/output-utils.ts +109 -0
  175. package/server/cli/headless/prompt-utils.ts +108 -0
  176. package/server/cli/headless/runner.ts +133 -0
  177. package/server/cli/headless/types.ts +118 -0
  178. package/server/cli/improvisation-session-manager.ts +531 -0
  179. package/server/index.ts +456 -0
  180. package/server/mcp/README.md +122 -0
  181. package/server/mcp/bouncer-cli.ts +127 -0
  182. package/server/mcp/bouncer-integration.ts +430 -0
  183. package/server/mcp/security-audit.ts +180 -0
  184. package/server/mcp/security-patterns.ts +290 -0
  185. package/server/mcp/server.ts +174 -0
  186. package/server/routes/files.ts +29 -0
  187. package/server/routes/improvise.ts +82 -0
  188. package/server/routes/index.ts +13 -0
  189. package/server/routes/instances.ts +54 -0
  190. package/server/routes/notifications.ts +158 -0
  191. package/server/services/analytics.ts +277 -0
  192. package/server/services/auth.ts +80 -0
  193. package/server/services/client-id.ts +68 -0
  194. package/server/services/credentials.ts +134 -0
  195. package/server/services/files.ts +710 -0
  196. package/server/services/instances.ts +275 -0
  197. package/server/services/pathUtils.ts +158 -0
  198. package/server/services/platform.test.ts +1314 -0
  199. package/server/services/platform.ts +435 -0
  200. package/server/services/sentry.ts +81 -0
  201. package/server/services/terminal/pty-manager.ts +464 -0
  202. package/server/services/terminal/tmux-manager.ts +426 -0
  203. package/server/services/websocket/autocomplete.ts +438 -0
  204. package/server/services/websocket/file-utils.ts +305 -0
  205. package/server/services/websocket/handler.test.ts +20 -0
  206. package/server/services/websocket/handler.ts +2047 -0
  207. package/server/services/websocket/index.ts +40 -0
  208. package/server/services/websocket/types.ts +339 -0
  209. package/server/tsconfig.json +19 -0
  210. package/server/utils/agent-manager.ts +323 -0
  211. package/server/utils/paths.ts +45 -0
  212. package/server/utils/port-manager.ts +70 -0
  213. package/server/utils/port.ts +102 -0
@@ -0,0 +1,386 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+ /**
4
+ * Mstro Server (Node.js + Hono)
5
+ */
6
+ import { randomBytes } from 'node:crypto';
7
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
8
+ import { basename, join } from 'node:path';
9
+ import { serve } from '@hono/node-server';
10
+ import { Hono } from 'hono';
11
+ import { cors } from 'hono/cors';
12
+ import { logger } from 'hono/logger';
13
+ import { WebSocketServer } from 'ws';
14
+ // Import route creators
15
+ import { createFileRoutes, createImproviseRoutes, createInstanceRoutes, createNotificationRoutes, createShutdownRoute } from './routes/index.js';
16
+ import { AnalyticsEvents, initAnalytics, shutdownAnalytics, trackEvent } from './services/analytics.js';
17
+ import { AuthService } from './services/auth.js';
18
+ import { FileService } from './services/files.js';
19
+ import { InstanceRegistry } from './services/instances.js';
20
+ import { PlatformConnection } from './services/platform.js';
21
+ import { captureException, flushSentry, initSentry } from './services/sentry.js';
22
+ import { getPTYManager } from './services/terminal/pty-manager.js';
23
+ import { WebSocketImproviseHandler } from './services/websocket/index.js';
24
+ import { findAvailablePort } from './utils/port.js';
25
+ /**
26
+ * Set the terminal tab title
27
+ * Format: "mstro: directory_name"
28
+ * Uses ANSI escape sequence: ESC ] 0 ; title BEL
29
+ */
30
+ function setTerminalTitle(directory) {
31
+ const dirName = basename(directory) || directory;
32
+ const title = `mstro: ${dirName}`;
33
+ // ESC ] 0 ; title BEL - sets both window title and tab title
34
+ process.stdout.write(`\x1b]0;${title}\x07`);
35
+ }
36
+ // Create Hono app with type inference
37
+ const app = new Hono();
38
+ // Configuration
39
+ const DEFAULT_PORT = 4101;
40
+ const REQUESTED_PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : DEFAULT_PORT;
41
+ const WORKING_DIR = process.env.MSTRO_WORKING_DIR || process.env.WORKING_DIR || process.cwd();
42
+ const IS_PRODUCTION = process.env.NODE_ENV === 'production';
43
+ /**
44
+ * Ensure .claude/settings.json exists with recommended settings
45
+ * for optimal Claude Code performance with Mstro
46
+ */
47
+ function ensureClaudeSettings(workingDir) {
48
+ const claudeDir = join(workingDir, '.claude');
49
+ const settingsPath = join(claudeDir, 'settings.json');
50
+ // Create .claude directory if it doesn't exist
51
+ if (!existsSync(claudeDir)) {
52
+ mkdirSync(claudeDir, { recursive: true });
53
+ }
54
+ // Recommended settings for Mstro
55
+ const recommendedSettings = {
56
+ env: {
57
+ CLAUDE_CODE_MAX_OUTPUT_TOKENS: "64000",
58
+ DISABLE_NONESSENTIAL_TRAFFIC: "1"
59
+ }
60
+ };
61
+ // If settings.json doesn't exist, create it
62
+ if (!existsSync(settingsPath)) {
63
+ writeFileSync(settingsPath, JSON.stringify(recommendedSettings, null, 2));
64
+ console.log(`📝 Created .claude/settings.json with recommended settings`);
65
+ }
66
+ else {
67
+ // If it exists, check if our env settings are present and merge if needed
68
+ try {
69
+ const existingSettings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
70
+ let updated = false;
71
+ // Ensure env object exists
72
+ if (!existingSettings.env) {
73
+ existingSettings.env = {};
74
+ updated = true;
75
+ }
76
+ // Add our recommended env settings if they don't exist
77
+ if (!existingSettings.env.CLAUDE_CODE_MAX_OUTPUT_TOKENS) {
78
+ existingSettings.env.CLAUDE_CODE_MAX_OUTPUT_TOKENS = "64000";
79
+ updated = true;
80
+ }
81
+ if (!existingSettings.env.DISABLE_NONESSENTIAL_TRAFFIC) {
82
+ existingSettings.env.DISABLE_NONESSENTIAL_TRAFFIC = "1";
83
+ updated = true;
84
+ }
85
+ if (updated) {
86
+ writeFileSync(settingsPath, JSON.stringify(existingSettings, null, 2));
87
+ console.log(`📝 Updated .claude/settings.json with recommended env settings`);
88
+ }
89
+ }
90
+ catch (_e) {
91
+ // If we can't parse the existing file, don't overwrite it
92
+ console.warn(`⚠️ Could not parse existing .claude/settings.json, skipping update`);
93
+ }
94
+ }
95
+ }
96
+ // Ensure Claude settings on startup
97
+ ensureClaudeSettings(WORKING_DIR);
98
+ // Set terminal tab title to show mstro is running and which directory
99
+ setTerminalTitle(WORKING_DIR);
100
+ // Initialize services
101
+ const authService = new AuthService();
102
+ const instanceRegistry = new InstanceRegistry();
103
+ const fileService = new FileService(WORKING_DIR);
104
+ const wsHandler = new WebSocketImproviseHandler();
105
+ // Instance registration deferred to startServer() when port is known
106
+ let _currentInstance;
107
+ // Global middleware
108
+ // In production, restrict CORS to block cross-origin browser requests to localhost.
109
+ // In dev, allow localhost origins on any port for local frontend dev servers.
110
+ app.use('*', cors({
111
+ origin: (origin) => {
112
+ if (!origin)
113
+ return 'http://localhost';
114
+ try {
115
+ const url = new URL(origin);
116
+ if (url.hostname === 'localhost' || url.hostname === '127.0.0.1') {
117
+ return origin;
118
+ }
119
+ }
120
+ catch { }
121
+ return 'http://localhost';
122
+ }
123
+ }));
124
+ app.use('*', logger());
125
+ // ========================================
126
+ // Authentication Middleware
127
+ // ========================================
128
+ const authMiddleware = async (c, next) => {
129
+ // Skip auth for health check and config
130
+ const publicPaths = ['/health', '/api/config'];
131
+ if (publicPaths.some(path => c.req.path.startsWith(path))) {
132
+ return next();
133
+ }
134
+ // Require the local session token for localhost security.
135
+ // This prevents other local processes or malicious websites from
136
+ // calling the API without the session token from ~/.mstro/session-token.
137
+ const token = c.req.header('x-session-token');
138
+ if (!token || !authService.validateLocalToken(token)) {
139
+ return c.json({ error: 'Unauthorized' }, 401);
140
+ }
141
+ return next();
142
+ };
143
+ app.use('/api/*', authMiddleware);
144
+ // ========================================
145
+ // Health & Configuration
146
+ // ========================================
147
+ // Read version from package.json once at startup
148
+ const PKG_VERSION = (() => {
149
+ try {
150
+ const pkg = JSON.parse(readFileSync(join(import.meta.dirname || '.', '..', 'package.json'), 'utf-8'));
151
+ return pkg.version || '0.0.0';
152
+ }
153
+ catch {
154
+ return '0.0.0';
155
+ }
156
+ })();
157
+ app.get('/health', (c) => {
158
+ return c.json({
159
+ status: 'ok',
160
+ timestamp: new Date().toISOString(),
161
+ version: PKG_VERSION
162
+ });
163
+ });
164
+ app.get('/api/config', (c) => {
165
+ return c.json({
166
+ version: PKG_VERSION
167
+ });
168
+ });
169
+ // ========================================
170
+ // Mount Routes
171
+ // ========================================
172
+ app.route('/api/instances', createInstanceRoutes(instanceRegistry));
173
+ app.route('/api/shutdown', createShutdownRoute(instanceRegistry));
174
+ app.route('/api/improvise', createImproviseRoutes(WORKING_DIR));
175
+ app.route('/api/files', createFileRoutes(fileService));
176
+ app.route('/api/notifications', createNotificationRoutes(WORKING_DIR));
177
+ // ========================================
178
+ // Static File Serving (Production Only)
179
+ // ========================================
180
+ if (IS_PRODUCTION) {
181
+ // For production static file serving, use a reverse proxy like nginx
182
+ // or implement a simple static file middleware if needed
183
+ console.log('Production mode: serve static files via nginx or similar');
184
+ }
185
+ // ========================================
186
+ // 404 & Error Handlers
187
+ // ========================================
188
+ app.notFound((c) => {
189
+ return c.json({ error: 'Not found' }, 404);
190
+ });
191
+ app.onError((err, c) => {
192
+ const errorId = randomBytes(4).toString('hex');
193
+ console.error(`Server error [${errorId}]:`, err);
194
+ captureException(err, { errorId, path: c.req.path, method: c.req.method });
195
+ return c.json({
196
+ error: 'Internal server error',
197
+ errorId,
198
+ message: 'Something went wrong. If this persists, report this error ID to support.'
199
+ }, 500);
200
+ });
201
+ // ========================================
202
+ // Node.js Server with WebSocket Support
203
+ // ========================================
204
+ /**
205
+ * Wrap a ws WebSocket to match our WSContext interface
206
+ */
207
+ function wrapWebSocket(ws, workingDir) {
208
+ return {
209
+ send: (data) => ws.send(data),
210
+ close: () => ws.close(),
211
+ readyState: ws.readyState,
212
+ _workingDir: workingDir,
213
+ _ws: ws
214
+ };
215
+ }
216
+ /**
217
+ * Create a virtual WebSocket context that sends responses through the platform relay
218
+ * This allows messages from the web (via platform) to be handled by the same wsHandler
219
+ */
220
+ function createPlatformRelayContext(platformSend, workingDir) {
221
+ return {
222
+ send: (data) => {
223
+ // Parse the response and send through platform relay
224
+ try {
225
+ const response = typeof data === 'string' ? JSON.parse(data) : JSON.parse(data.toString());
226
+ platformSend(response);
227
+ }
228
+ catch (e) {
229
+ // If not JSON, send as-is (shouldn't happen with our protocol)
230
+ console.error('[PlatformRelay] Failed to parse response:', e);
231
+ }
232
+ },
233
+ close: () => {
234
+ // No-op for platform relay - connection is managed by PlatformConnection
235
+ },
236
+ readyState: 1, // WebSocket.OPEN
237
+ _workingDir: workingDir,
238
+ _isPlatformRelay: true
239
+ };
240
+ }
241
+ // Start server with dynamic port selection
242
+ async function startServer() {
243
+ // Initialize error tracking (must be first)
244
+ initSentry();
245
+ // Initialize analytics (fetches config from platform)
246
+ await initAnalytics();
247
+ const PORT = await findAvailablePort(REQUESTED_PORT, 20);
248
+ if (PORT !== REQUESTED_PORT) {
249
+ console.log(`⚠️ Port ${REQUESTED_PORT} in use, using port ${PORT}`);
250
+ }
251
+ _currentInstance = instanceRegistry.register(PORT, WORKING_DIR);
252
+ // Create HTTP server with Hono
253
+ const server = serve({
254
+ fetch: app.fetch,
255
+ port: PORT
256
+ });
257
+ // Create WebSocket server attached to the HTTP server
258
+ const wss = new WebSocketServer({ server: server });
259
+ wss.on('connection', (ws, req) => {
260
+ const url = new URL(req.url || '/', `http://localhost:${PORT}`);
261
+ // Only handle /ws endpoint
262
+ if (url.pathname !== '/ws') {
263
+ ws.close(1008, 'Invalid WebSocket path');
264
+ return;
265
+ }
266
+ // Require local session token for WebSocket connections
267
+ const wsToken = url.searchParams.get('token');
268
+ if (!wsToken || !authService.validateLocalToken(wsToken)) {
269
+ ws.close(4001, 'Unauthorized');
270
+ return;
271
+ }
272
+ // Always use the server's working directory — don't allow clients to override
273
+ const workingDir = WORKING_DIR;
274
+ const wrappedWs = wrapWebSocket(ws, workingDir);
275
+ wsHandler.handleConnection(wrappedWs, workingDir);
276
+ ws.on('message', (data) => {
277
+ const message = typeof data === 'string' ? data : data.toString('utf-8');
278
+ wsHandler.handleMessage(wrappedWs, message, workingDir);
279
+ });
280
+ ws.on('close', () => {
281
+ wsHandler.handleClose(wrappedWs);
282
+ });
283
+ ws.on('error', (error) => {
284
+ console.error('[WebSocket] Error:', error);
285
+ captureException(error, { context: 'websocket.connection' });
286
+ });
287
+ });
288
+ console.log(`🚀 Mstro Server (Node.js + Hono) on port ${PORT}`);
289
+ console.log(`📁 Working directory: ${WORKING_DIR}`);
290
+ console.log(`Runtime: Node.js ${process.version}`);
291
+ console.log(`Framework: Hono`);
292
+ // Track server started event
293
+ trackEvent(AnalyticsEvents.SERVER_STARTED, { port: PORT });
294
+ // Create a virtual WebSocket context for platform relay
295
+ // This allows messages from the web (via platform) to use the same wsHandler
296
+ let platformRelayContext = null;
297
+ // Queue for messages that arrive before relay context is ready
298
+ // This handles race conditions where initTab arrives before web_connected
299
+ let pendingRelayMessages = [];
300
+ // Connect to platform
301
+ const platformConnection = new PlatformConnection(WORKING_DIR, {
302
+ onConnected: (_connectionId) => {
303
+ console.log(`🎵 Orchestra ready: ${basename(WORKING_DIR)}`);
304
+ // Set up usage reporter to send token usage to platform
305
+ wsHandler.setUsageReporter((report) => {
306
+ platformConnection.send({
307
+ type: 'reportUsage',
308
+ data: report
309
+ });
310
+ });
311
+ },
312
+ onWebConnected: () => {
313
+ // Create the relay context when web connects
314
+ platformRelayContext = createPlatformRelayContext((message) => platformConnection.send(message), WORKING_DIR);
315
+ // Initialize the connection for the wsHandler
316
+ wsHandler.handleConnection(platformRelayContext, WORKING_DIR);
317
+ // Process any messages that arrived before relay context was ready
318
+ if (pendingRelayMessages.length > 0) {
319
+ for (const message of pendingRelayMessages) {
320
+ wsHandler.handleMessage(platformRelayContext, JSON.stringify(message), WORKING_DIR);
321
+ }
322
+ pendingRelayMessages = [];
323
+ }
324
+ },
325
+ onWebDisconnected: () => {
326
+ // Clean up when web disconnects
327
+ if (platformRelayContext) {
328
+ wsHandler.handleClose(platformRelayContext);
329
+ platformRelayContext = null;
330
+ }
331
+ // Clear any pending messages
332
+ pendingRelayMessages = [];
333
+ },
334
+ onRelayedMessage: (message) => {
335
+ // Forward messages from web (via platform) to the wsHandler
336
+ if (platformRelayContext) {
337
+ wsHandler.handleMessage(platformRelayContext, JSON.stringify(message), WORKING_DIR);
338
+ }
339
+ else {
340
+ // Queue the message - it will be processed when web_connected arrives
341
+ pendingRelayMessages.push(message);
342
+ }
343
+ }
344
+ });
345
+ platformConnection.connect();
346
+ // Catch unhandled errors at process level
347
+ process.on('uncaughtException', (err) => {
348
+ console.error('[Server] Uncaught exception:', err);
349
+ captureException(err, { context: 'uncaughtException' });
350
+ });
351
+ process.on('unhandledRejection', (reason) => {
352
+ console.error('[Server] Unhandled rejection:', reason);
353
+ captureException(reason instanceof Error ? reason : new Error(String(reason)), { context: 'unhandledRejection' });
354
+ });
355
+ // Cleanup on exit
356
+ process.on('SIGINT', async () => {
357
+ trackEvent(AnalyticsEvents.SERVER_STOPPED);
358
+ await Promise.all([shutdownAnalytics(), flushSentry()]);
359
+ platformConnection.disconnect();
360
+ instanceRegistry.unregister();
361
+ // Close all non-persistent terminal sessions (PTY processes)
362
+ // Note: Persistent (tmux) sessions are intentionally left running
363
+ getPTYManager().closeAll();
364
+ wss.close();
365
+ console.log('\n\n👋 Shutting down gracefully...\n');
366
+ process.exit(0);
367
+ });
368
+ process.on('SIGTERM', async () => {
369
+ trackEvent(AnalyticsEvents.SERVER_STOPPED);
370
+ await Promise.all([shutdownAnalytics(), flushSentry()]);
371
+ platformConnection.disconnect();
372
+ instanceRegistry.unregister();
373
+ // Close all non-persistent terminal sessions (PTY processes)
374
+ // Note: Persistent (tmux) sessions are intentionally left running
375
+ getPTYManager().closeAll();
376
+ wss.close();
377
+ console.log('\n\n👋 Shutting down gracefully...\n');
378
+ process.exit(0);
379
+ });
380
+ // Periodic cleanup
381
+ setInterval(() => {
382
+ wsHandler.cleanupStaleSessions();
383
+ }, 5 * 60 * 1000); // Every 5 minutes
384
+ }
385
+ startServer();
386
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=bouncer-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bouncer-cli.d.ts","sourceRoot":"","sources":["../../../server/mcp/bouncer-cli.ts"],"names":[],"mappings":""}
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env node
2
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
3
+ // Licensed under the MIT License. See LICENSE file for details.
4
+ /**
5
+ * Bouncer CLI - Shell-callable wrapper for Mstro security bouncer
6
+ *
7
+ * This CLI reads Claude Code hook input from stdin and returns a security decision.
8
+ * It's designed to be called from bouncer.sh.
9
+ *
10
+ * Input (stdin): Claude Code PreToolUse hook JSON payload
11
+ * Output (stdout): JSON decision { decision: "allow"|"deny", reason: string }
12
+ *
13
+ * The hook payload includes conversation context that we pass to the bouncer
14
+ * so it can make context-aware decisions.
15
+ */
16
+ import { reviewOperation } from './bouncer-integration.js';
17
+ /**
18
+ * Read all data from stdin (Node.js compatible)
19
+ */
20
+ async function readStdin() {
21
+ return new Promise((resolve, reject) => {
22
+ const chunks = [];
23
+ process.stdin.on('data', (chunk) => chunks.push(chunk));
24
+ process.stdin.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8').trim()));
25
+ process.stdin.on('error', reject);
26
+ });
27
+ }
28
+ function buildOperationString(toolName, toolInput) {
29
+ if (toolName === 'Bash' && toolInput.command) {
30
+ return `${toolName}: ${toolInput.command}`;
31
+ }
32
+ if (['Write', 'Edit', 'Read'].includes(toolName)) {
33
+ const filePath = toolInput.file_path || toolInput.filePath || toolInput.path;
34
+ return filePath ? `${toolName}: ${filePath}` : `${toolName}: ${JSON.stringify(toolInput)}`;
35
+ }
36
+ return `${toolName}: ${JSON.stringify(toolInput)}`;
37
+ }
38
+ function extractConversationContext(hookInput) {
39
+ const lastUserMessage = hookInput.conversation?.last_user_message;
40
+ if (lastUserMessage)
41
+ return `User's request: "${lastUserMessage}"`;
42
+ const recentMessages = hookInput.conversation?.messages?.slice(-5);
43
+ if (recentMessages?.length) {
44
+ return `Recent conversation:\n${recentMessages.map(m => `${m.role}: ${m.content}`).join('\n')}`;
45
+ }
46
+ return undefined;
47
+ }
48
+ async function main() {
49
+ const inputStr = await readStdin();
50
+ if (!inputStr) {
51
+ console.log(JSON.stringify({ decision: 'allow', reason: 'Empty input, allowing' }));
52
+ process.exit(0);
53
+ }
54
+ let hookInput;
55
+ try {
56
+ hookInput = JSON.parse(inputStr);
57
+ }
58
+ catch (e) {
59
+ console.error('[bouncer-cli] Failed to parse input JSON:', e);
60
+ console.log(JSON.stringify({ decision: 'allow', reason: 'Invalid JSON input, allowing' }));
61
+ process.exit(0);
62
+ }
63
+ const toolName = hookInput.tool_name || hookInput.toolName || 'unknown';
64
+ const toolInput = hookInput.input || hookInput.toolInput || {};
65
+ const userRequestContext = extractConversationContext(hookInput);
66
+ const lastUserMessage = hookInput.conversation?.last_user_message;
67
+ const recentMessages = hookInput.conversation?.messages?.slice(-5);
68
+ const bouncerRequest = {
69
+ operation: buildOperationString(toolName, toolInput),
70
+ context: {
71
+ purpose: userRequestContext || 'Tool use request from Claude',
72
+ workingDirectory: hookInput.working_directory || process.cwd(),
73
+ toolName,
74
+ toolInput,
75
+ userRequest: lastUserMessage,
76
+ conversationHistory: recentMessages?.map(m => `${m.role}: ${m.content}`),
77
+ sessionId: hookInput.session_id,
78
+ },
79
+ };
80
+ try {
81
+ const decision = await reviewOperation(bouncerRequest);
82
+ console.log(JSON.stringify({
83
+ decision: decision.decision === 'deny' ? 'deny' : 'allow',
84
+ reason: decision.reasoning,
85
+ confidence: decision.confidence,
86
+ threatLevel: decision.threatLevel,
87
+ alternative: decision.alternative,
88
+ }));
89
+ }
90
+ catch (error) {
91
+ console.error('[bouncer-cli] Error:', error.message);
92
+ console.log(JSON.stringify({
93
+ decision: 'allow',
94
+ reason: `Bouncer error: ${error.message}. Allowing to avoid blocking.`
95
+ }));
96
+ }
97
+ }
98
+ main();
99
+ //# sourceMappingURL=bouncer-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bouncer-cli.js","sourceRoot":"","sources":["../../../server/mcp/bouncer-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ export interface BouncerReviewRequest {
2
+ operation: string;
3
+ context?: {
4
+ purpose?: string;
5
+ workingDirectory?: string;
6
+ affectedFiles?: string[];
7
+ alternatives?: string;
8
+ userRequest?: string;
9
+ conversationHistory?: string[];
10
+ sessionId?: string;
11
+ [key: string]: any;
12
+ };
13
+ }
14
+ export interface BouncerDecision {
15
+ decision: 'allow' | 'deny' | 'warn_allow';
16
+ confidence: number;
17
+ reasoning: string;
18
+ threatLevel?: 'low' | 'medium' | 'high' | 'critical';
19
+ alternative?: string;
20
+ suggestedCommand?: string;
21
+ enforceable?: boolean;
22
+ }
23
+ /**
24
+ * Main bouncer review function - 2-layer hybrid system
25
+ */
26
+ export declare function reviewOperation(request: BouncerReviewRequest): Promise<BouncerDecision>;
27
+ /**
28
+ * Export risk classification utility
29
+ */
30
+ export { classifyRisk as classifyOperationRisk } from './security-patterns.js';
31
+ /**
32
+ * Launch bouncer agent (legacy compatibility)
33
+ * Redirects to reviewOperation for backward compatibility
34
+ */
35
+ export declare function launchBouncerAgent(request: BouncerReviewRequest, useAI?: boolean): Promise<BouncerDecision>;
36
+ //# sourceMappingURL=bouncer-integration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bouncer-integration.d.ts","sourceRoot":"","sources":["../../../server/mcp/bouncer-integration.ts"],"names":[],"mappings":"AA2CA,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,YAAY,CAAC,EAAE,MAAM,CAAC;QAEtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,YAAY,CAAC;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAyKD;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,eAAe,CAAC,CAwK7F;AAED;;GAEG;AACH,OAAO,EAAE,YAAY,IAAI,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE/E;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,oBAAoB,EAC7B,KAAK,GAAE,OAAc,GACpB,OAAO,CAAC,eAAe,CAAC,CAS1B"}