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,45 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+
4
+ /**
5
+ * Path Utilities for Mstro Package
6
+ *
7
+ * Provides consistent path resolution for installed npm package.
8
+ * Works correctly whether running from source or installed globally.
9
+ */
10
+
11
+ import { dirname, resolve } from 'node:path';
12
+ import { fileURLToPath } from 'node:url';
13
+
14
+ // ES module equivalent of __dirname for this file
15
+ const __filename = fileURLToPath(import.meta.url);
16
+ const __dirname = dirname(__filename);
17
+
18
+ /**
19
+ * Root directory of the mstro package installation.
20
+ * This is the directory containing package.json.
21
+ *
22
+ * Structure: /path/to/mstro/server/utils/paths.ts
23
+ * So we go up 2 levels: utils -> server -> mstro root
24
+ */
25
+ export const MSTRO_ROOT = resolve(__dirname, '../..');
26
+
27
+ /**
28
+ * Path to the MCP bouncer server script
29
+ */
30
+ export const MCP_SERVER_PATH = resolve(MSTRO_ROOT, 'server/mcp/server.ts');
31
+
32
+ /**
33
+ * Path to the MCP bouncer configuration template
34
+ */
35
+ export const MCP_CONFIG_TEMPLATE_PATH = resolve(MSTRO_ROOT, 'mstro-bouncer-mcp.json');
36
+
37
+ /**
38
+ * Path to the hooks directory
39
+ */
40
+ export const HOOKS_DIR = resolve(MSTRO_ROOT, 'hooks');
41
+
42
+ /**
43
+ * Path to the bouncer hook script
44
+ */
45
+ export const BOUNCER_HOOK = resolve(HOOKS_DIR, 'bouncer.sh');
@@ -0,0 +1,70 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+
4
+ /**
5
+ * Port Manager - Finds available ports for Mstro instances
6
+ *
7
+ * Handles port discovery when multiple Mstro instances run on the same machine.
8
+ * Tries a range of ports starting from the default until an available one is found.
9
+ */
10
+
11
+ import { createServer } from 'node:net'
12
+
13
+ const DEFAULT_PORT = 3001
14
+ const MAX_PORT_ATTEMPTS = 10
15
+
16
+ /**
17
+ * Check if a port is available
18
+ */
19
+ async function isPortAvailable(port: number): Promise<boolean> {
20
+ return new Promise((resolve) => {
21
+ const server = createServer()
22
+
23
+ server.once('error', (err: any) => {
24
+ if (err.code === 'EADDRINUSE') {
25
+ resolve(false)
26
+ } else {
27
+ resolve(false)
28
+ }
29
+ })
30
+
31
+ server.once('listening', () => {
32
+ server.close()
33
+ resolve(true)
34
+ })
35
+
36
+ server.listen(port)
37
+ })
38
+ }
39
+
40
+ /**
41
+ * Find an available port starting from the default port
42
+ * Tries ports: 3001, 3002, 3003, ... up to 3010
43
+ */
44
+ export async function findAvailablePort(startPort: number = DEFAULT_PORT): Promise<number> {
45
+ for (let i = 0; i < MAX_PORT_ATTEMPTS; i++) {
46
+ const port = startPort + i
47
+ const available = await isPortAvailable(port)
48
+
49
+ if (available) {
50
+ return port
51
+ }
52
+
53
+ }
54
+
55
+ throw new Error(`Could not find available port after ${MAX_PORT_ATTEMPTS} attempts (tried ${startPort}-${startPort + MAX_PORT_ATTEMPTS - 1})`)
56
+ }
57
+
58
+ /**
59
+ * Get the default port from environment or use 3001
60
+ */
61
+ export function getDefaultPort(): number {
62
+ const envPort = process.env.PORT
63
+ if (envPort) {
64
+ const parsed = parseInt(envPort, 10)
65
+ if (!Number.isNaN(parsed) && parsed > 0 && parsed < 65536) {
66
+ return parsed
67
+ }
68
+ }
69
+ return DEFAULT_PORT
70
+ }
@@ -0,0 +1,102 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+
4
+ /**
5
+ * Port utilities for finding available ports
6
+ *
7
+ * Convention: Frontend uses EVEN ports (3000, 3002, 3004...)
8
+ * Backend uses ODD ports (3001, 3003, 3005...)
9
+ * This ensures they never compete for the same port.
10
+ */
11
+
12
+ import { createServer } from 'node:net'
13
+
14
+ /**
15
+ * Check if a port is available by trying to bind to it
16
+ * Uses '::' (IPv6 any) which also binds IPv4 on most systems,
17
+ * ensuring we detect servers listening on any interface.
18
+ */
19
+ export function isPortAvailable(port: number): Promise<boolean> {
20
+ return new Promise((resolve) => {
21
+ const server = createServer()
22
+
23
+ server.once('error', () => {
24
+ server.close()
25
+ resolve(false) // Port is in use
26
+ })
27
+
28
+ server.once('listening', () => {
29
+ server.close()
30
+ resolve(true) // Port is available
31
+ })
32
+
33
+ // Use '::' to bind on all interfaces (IPv4 + IPv6)
34
+ // This ensures we detect servers on any interface
35
+ server.listen(port, '::')
36
+ })
37
+ }
38
+
39
+ /**
40
+ * Check multiple ports in parallel and return the first available one
41
+ */
42
+ export async function findFirstAvailablePort(ports: number[]): Promise<number | null> {
43
+ const results = await Promise.all(
44
+ ports.map(async (port) => ({ port, available: await isPortAvailable(port) }))
45
+ )
46
+ const available = results.find(r => r.available)
47
+ return available ? available.port : null
48
+ }
49
+
50
+ /**
51
+ * Find an available port starting from startPort
52
+ */
53
+ export async function findAvailablePort(startPort: number, maxTries: number = 20): Promise<number> {
54
+ // Check all ports in parallel for speed
55
+ const ports = Array.from({ length: maxTries }, (_, i) => startPort + i)
56
+ const port = await findFirstAvailablePort(ports)
57
+ if (port !== null) {
58
+ return port
59
+ }
60
+ throw new Error(`No available ports found between ${startPort} and ${startPort + maxTries}`)
61
+ }
62
+
63
+ /**
64
+ * Find an available port pair for frontend and backend
65
+ * Frontend = EVEN port (3000, 3002, 3004...)
66
+ * Backend = ODD port (3001, 3003, 3005...)
67
+ *
68
+ * Checks all candidate ports in parallel for fast detection.
69
+ */
70
+ export async function findAvailablePortPair(startPort: number = 3000, maxPairs: number = 20): Promise<{ frontend: number; backend: number }> {
71
+ // Ensure startPort is even
72
+ const basePort = startPort % 2 === 0 ? startPort : startPort + 1
73
+
74
+ // Generate all candidate pairs
75
+ const pairs: { frontend: number; backend: number }[] = []
76
+ for (let i = 0; i < maxPairs; i++) {
77
+ pairs.push({
78
+ frontend: basePort + (i * 2), // 3000, 3002, 3004...
79
+ backend: basePort + (i * 2) + 1 // 3001, 3003, 3005...
80
+ })
81
+ }
82
+
83
+ // Check all ports in parallel (both frontend and backend ports)
84
+ const allPorts = pairs.flatMap(p => [p.frontend, p.backend])
85
+ const results = await Promise.all(
86
+ allPorts.map(async (port) => ({ port, available: await isPortAvailable(port) }))
87
+ )
88
+
89
+ // Build a set of available ports for O(1) lookup
90
+ const availablePorts = new Set(
91
+ results.filter(r => r.available).map(r => r.port)
92
+ )
93
+
94
+ // Find first pair where both ports are available
95
+ for (const pair of pairs) {
96
+ if (availablePorts.has(pair.frontend) && availablePorts.has(pair.backend)) {
97
+ return pair
98
+ }
99
+ }
100
+
101
+ throw new Error(`No available port pairs found starting from ${startPort}`)
102
+ }