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,101 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+ /**
4
+ * Output Utilities
5
+ *
6
+ * Utilities for processing and parsing Claude CLI output.
7
+ */
8
+ /**
9
+ * Extract clean output from Claude response
10
+ */
11
+ export function extractCleanOutput(rawOutput) {
12
+ // When using stream-json format, filter out all JSON lines
13
+ // since we already streamed the actual content via callbacks
14
+ const lines = rawOutput.split('\n');
15
+ const cleanLines = lines.filter(line => {
16
+ const trimmed = line.trim();
17
+ // Filter out JSON lines (system, stream_event, assistant, user, result)
18
+ if (trimmed.startsWith('{') && trimmed.includes('"type"')) {
19
+ return false;
20
+ }
21
+ return trimmed.length > 0;
22
+ });
23
+ return cleanLines.join('\n')
24
+ .replace(/\x1b\[[0-9;]*m/g, '') // ANSI color codes
25
+ .replace(/\r\n/g, '\n') // Normalize line endings
26
+ .trim();
27
+ }
28
+ /**
29
+ * Estimate tokens from output
30
+ */
31
+ export function estimateTokensFromOutput(output) {
32
+ return Math.floor(output.length / 4);
33
+ }
34
+ /**
35
+ * Extract modified files from output (simplified)
36
+ */
37
+ export function extractModifiedFiles(output) {
38
+ // This is a simplified version. In production, would parse actual file operations
39
+ const filePattern = /(?:wrote|modified|created|edited)\s+(?:file\s+)?['"]?([^\s'"]+\.[a-z0-9]+)['"]?/gi;
40
+ const matches = output.matchAll(filePattern);
41
+ const files = new Set();
42
+ for (const match of matches) {
43
+ files.add(match[1]);
44
+ }
45
+ return Array.from(files);
46
+ }
47
+ /**
48
+ * Error patterns for detecting Claude Code errors in stderr
49
+ */
50
+ export const ERROR_PATTERNS = [
51
+ // Authentication errors - most common user-facing issue
52
+ { pattern: /not logged in|login required|must be authenticated|session.*expired|token.*invalid|token.*expired/i,
53
+ message: 'Claude Code authentication required. Please run "claude login" in your terminal to authenticate.',
54
+ errorCode: 'AUTH_REQUIRED' },
55
+ { pattern: /account.*not.*found|user.*not.*found/i,
56
+ message: 'Claude account not found. Please verify your account at claude.ai.',
57
+ errorCode: 'ACCOUNT_NOT_FOUND' },
58
+ // API/subscription errors
59
+ { pattern: /api key|invalid key|unauthorized|forbidden.*api/i,
60
+ message: 'API key error. Please check your Claude Code configuration.',
61
+ errorCode: 'API_KEY_INVALID' },
62
+ { pattern: /quota exceeded|usage.*limit|billing.*issue|payment.*required|subscription.*expired/i,
63
+ message: 'Usage quota or subscription issue. Please check your account billing at claude.ai.',
64
+ errorCode: 'QUOTA_EXCEEDED' },
65
+ { pattern: /rate limit|too many requests|429|throttl/i,
66
+ message: 'Rate limit exceeded. Please wait a moment before trying again.',
67
+ errorCode: 'RATE_LIMITED' },
68
+ // Network errors
69
+ { pattern: /no internet|network error|connection refused|ENOTFOUND|ECONNREFUSED|ETIMEDOUT|socket hang up/i,
70
+ message: 'Network error. Please check your internet connection.',
71
+ errorCode: 'NETWORK_ERROR' },
72
+ { pattern: /SSL|certificate|TLS|CERT_/i,
73
+ message: 'SSL/TLS certificate error. Please check your network configuration.',
74
+ errorCode: 'SSL_ERROR' },
75
+ // Model/service errors
76
+ { pattern: /model not found|model unavailable|service unavailable|503|502|504/i,
77
+ message: 'Claude service temporarily unavailable. Please try again in a few moments.',
78
+ errorCode: 'SERVICE_UNAVAILABLE' },
79
+ { pattern: /internal server error|500/i,
80
+ message: 'Claude service encountered an internal error. Please try again.',
81
+ errorCode: 'INTERNAL_ERROR' },
82
+ // Context/session errors
83
+ { pattern: /context.*too.*long|context.*limit|token.*limit.*exceeded/i,
84
+ message: 'Context too long. Please start a new session or reduce prompt size.',
85
+ errorCode: 'CONTEXT_TOO_LONG' },
86
+ { pattern: /session.*not.*found|invalid.*session/i,
87
+ message: 'Session not found. Starting a new session may help.',
88
+ errorCode: 'SESSION_NOT_FOUND' },
89
+ ];
90
+ /**
91
+ * Check stderr for known error patterns and return the first match
92
+ */
93
+ export function detectErrorInStderr(stderrBuffer) {
94
+ for (const { pattern, message, errorCode } of ERROR_PATTERNS) {
95
+ if (pattern.test(stderrBuffer)) {
96
+ return { message, errorCode };
97
+ }
98
+ }
99
+ return null;
100
+ }
101
+ //# sourceMappingURL=output-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-utils.js","sourceRoot":"","sources":["../../../../server/cli/headless/output-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Prompt Utilities
3
+ *
4
+ * Utilities for enriching prompts with context from previous conversation.
5
+ */
6
+ import type { ImageAttachment, PromptContext } from './types.js';
7
+ /**
8
+ * Enrich prompt with context from previous conversation
9
+ */
10
+ export declare function enrichPromptWithContext(prompt: string, context: PromptContext): string;
11
+ /**
12
+ * Detect if a prompt is an approval or continuation
13
+ */
14
+ export declare function isApprovalPrompt(prompt: string): boolean;
15
+ /**
16
+ * Build a multimodal message for stream-json input format.
17
+ * This constructs a JSON message with image content blocks followed by text.
18
+ * Format: {"type":"user","message":{"role":"user","content":[{image blocks...},{type:"text",text:"..."}]}}
19
+ */
20
+ export declare function buildMultimodalMessage(textPrompt: string, imageAttachments: ImageAttachment[]): string;
21
+ //# sourceMappingURL=prompt-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-utils.d.ts","sourceRoot":"","sources":["../../../../server/cli/headless/prompt-utils.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEjE;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAqBtF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAwBxD;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE,eAAe,EAAE,GAAG,MAAM,CAoCtG"}
@@ -0,0 +1,84 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+ /**
4
+ * Enrich prompt with context from previous conversation
5
+ */
6
+ export function enrichPromptWithContext(prompt, context) {
7
+ let enriched = prompt;
8
+ // Detect if this is a continuation/approval prompt
9
+ const isApprovalOrContinuation = isApprovalPrompt(prompt);
10
+ // Add accumulated knowledge from previous prompts
11
+ if (context.accumulatedKnowledge) {
12
+ if (isApprovalOrContinuation) {
13
+ enriched = `## Context from Previous Work\n${context.accumulatedKnowledge}\n\n## User Response\nThe user has responded with: "${prompt}"\n\nThis is a continuation/approval of the previous conversation. If you asked a question or requested approval in the previous movement, the user is responding to that question. Please proceed accordingly without asking the same question again.`;
14
+ }
15
+ else {
16
+ enriched = `## Context from Previous Work\n${context.accumulatedKnowledge}\n\n## Current Task\n${prompt}`;
17
+ }
18
+ }
19
+ // Add files modified so far
20
+ if (context.filesModified && context.filesModified.length > 0) {
21
+ enriched += `\n\n## Files Modified in This Session\n${context.filesModified.join('\n')}`;
22
+ }
23
+ return enriched;
24
+ }
25
+ /**
26
+ * Detect if a prompt is an approval or continuation
27
+ */
28
+ export function isApprovalPrompt(prompt) {
29
+ const lower = prompt.toLowerCase().trim();
30
+ // Short affirmative responses
31
+ if (['yes', 'y', 'ok', 'okay', 'sure', 'go', 'proceed', 'continue'].includes(lower)) {
32
+ return true;
33
+ }
34
+ // Approval phrases
35
+ const approvalPatterns = [
36
+ /^yes[,\s]/,
37
+ /^y[,\s]/,
38
+ /^okay[,\s]/,
39
+ /^ok[,\s]/,
40
+ /^sure[,\s]/,
41
+ /^go ahead/,
42
+ /^proceed/,
43
+ /^continue/,
44
+ /^from the (first|previous|last)/i,
45
+ /approval/i,
46
+ /approved/i
47
+ ];
48
+ return approvalPatterns.some(pattern => pattern.test(lower));
49
+ }
50
+ /**
51
+ * Build a multimodal message for stream-json input format.
52
+ * This constructs a JSON message with image content blocks followed by text.
53
+ * Format: {"type":"user","message":{"role":"user","content":[{image blocks...},{type:"text",text:"..."}]}}
54
+ */
55
+ export function buildMultimodalMessage(textPrompt, imageAttachments) {
56
+ // Build content array with images first, then text
57
+ const content = [];
58
+ // Add each image as a content block
59
+ for (const attachment of imageAttachments) {
60
+ content.push({
61
+ type: 'image',
62
+ source: {
63
+ type: 'base64',
64
+ media_type: attachment.mimeType || 'image/png',
65
+ data: attachment.content
66
+ }
67
+ });
68
+ }
69
+ // Add the text prompt
70
+ content.push({
71
+ type: 'text',
72
+ text: textPrompt
73
+ });
74
+ // Construct the message in Claude API format
75
+ const message = {
76
+ type: 'user',
77
+ message: {
78
+ role: 'user',
79
+ content
80
+ }
81
+ };
82
+ return JSON.stringify(message);
83
+ }
84
+ //# sourceMappingURL=prompt-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-utils.js","sourceRoot":"","sources":["../../../../server/cli/headless/prompt-utils.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,gEAAgE;AAUhE;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAc,EAAE,OAAsB;IAC5E,IAAI,QAAQ,GAAG,MAAM,CAAC;IAEtB,mDAAmD;IACnD,MAAM,wBAAwB,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAE1D,kDAAkD;IAClD,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;QACjC,IAAI,wBAAwB,EAAE,CAAC;YAC7B,QAAQ,GAAG,kCAAkC,OAAO,CAAC,oBAAoB,uDAAuD,MAAM,wPAAwP,CAAC;QACjY,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,kCAAkC,OAAO,CAAC,oBAAoB,wBAAwB,MAAM,EAAE,CAAC;QAC5G,CAAC;IACH,CAAC;IAED,4BAA4B;IAC5B,IAAI,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9D,QAAQ,IAAI,0CAA0C,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC3F,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAE1C,8BAA8B;IAC9B,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACpF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mBAAmB;IACnB,MAAM,gBAAgB,GAAG;QACvB,WAAW;QACX,SAAS;QACT,YAAY;QACZ,UAAU;QACV,YAAY;QACZ,WAAW;QACX,UAAU;QACV,WAAW;QACX,kCAAkC;QAClC,WAAW;QACX,WAAW;KACZ,CAAC;IAEF,OAAO,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,UAAkB,EAAE,gBAAmC;IAC5F,mDAAmD;IACnD,MAAM,OAAO,GAIR,EAAE,CAAC;IAER,oCAAoC;IACpC,KAAK,MAAM,UAAU,IAAI,gBAAgB,EAAE,CAAC;QAC1C,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,OAAO;YACb,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,UAAU,CAAC,QAAQ,IAAI,WAAW;gBAC9C,IAAI,EAAE,UAAU,CAAC,OAAO;aACzB;SACF,CAAC,CAAC;IACL,CAAC;IAED,sBAAsB;IACtB,OAAO,CAAC,IAAI,CAAC;QACX,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,UAAU;KACjB,CAAC,CAAC;IAEH,6CAA6C;IAC7C,MAAM,OAAO,GAAG;QACd,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE;YACP,IAAI,EAAE,MAAM;YACZ,OAAO;SACR;KACF,CAAC;IAEF,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { HeadlessConfig, SessionResult } from './types.js';
2
+ export type { HeadlessConfig, ImageAttachment, SessionResult, SessionState, ToolUseEvent } from './types.js';
3
+ export declare class HeadlessRunner {
4
+ private config;
5
+ private runningProcesses;
6
+ constructor(config: Partial<HeadlessConfig>);
7
+ /**
8
+ * Run direct prompt execution
9
+ */
10
+ run(): Promise<SessionResult>;
11
+ /**
12
+ * Execute a direct prompt without score file I/O
13
+ */
14
+ private runDirectPrompt;
15
+ /**
16
+ * Execute a single prompt via Claude CLI
17
+ */
18
+ private executePromptCommand;
19
+ /**
20
+ * Cleanup on exit
21
+ */
22
+ cleanup(): void;
23
+ }
24
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../../server/cli/headless/runner.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,cAAc,EAGd,aAAa,EACd,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE7G,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,gBAAgB,CAAwC;gBAEpD,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC;IAsB3C;;OAEG;IACG,GAAG,IAAI,OAAO,CAAC,aAAa,CAAC;IAcnC;;OAEG;YACW,eAAe;IAqC7B;;OAEG;YACW,oBAAoB;IAalC;;OAEG;IACH,OAAO,IAAI,IAAI;CAMhB"}
@@ -0,0 +1,99 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+ import { executeClaudeCommand } from './claude-invoker.js';
4
+ import { estimateTokensFromOutput } from './output-utils.js';
5
+ import { enrichPromptWithContext } from './prompt-utils.js';
6
+ export class HeadlessRunner {
7
+ config;
8
+ runningProcesses = new Map();
9
+ constructor(config) {
10
+ this.config = {
11
+ workingDir: config.workingDir || process.cwd(),
12
+ tokenBudgetThreshold: config.tokenBudgetThreshold || 170000,
13
+ maxSessions: config.maxSessions || 50,
14
+ maxRetries: config.maxRetries || 3,
15
+ claudeCommand: config.claudeCommand || process.env.CLAUDE_COMMAND || 'claude',
16
+ verbose: config.verbose || false,
17
+ noColor: config.noColor || false,
18
+ improvisationMode: config.improvisationMode || false,
19
+ movementNumber: config.movementNumber ?? 0,
20
+ outputCallback: config.outputCallback,
21
+ thinkingCallback: config.thinkingCallback,
22
+ toolUseCallback: config.toolUseCallback,
23
+ continueSession: config.continueSession,
24
+ claudeSessionId: config.claudeSessionId,
25
+ directPrompt: config.directPrompt || '',
26
+ promptContext: config.promptContext || { accumulatedKnowledge: '', filesModified: [] },
27
+ imageAttachments: config.imageAttachments
28
+ };
29
+ }
30
+ /**
31
+ * Run direct prompt execution
32
+ */
33
+ async run() {
34
+ if (this.config.directPrompt) {
35
+ return await this.runDirectPrompt(this.config.directPrompt, this.config.promptContext);
36
+ }
37
+ return {
38
+ completed: false,
39
+ needsHandoff: false,
40
+ totalTokens: 0,
41
+ sessionId: '',
42
+ error: 'No prompt provided. Use directPrompt in improvise mode.'
43
+ };
44
+ }
45
+ /**
46
+ * Execute a direct prompt without score file I/O
47
+ */
48
+ async runDirectPrompt(userPrompt, context) {
49
+ const sessionId = `direct-${Date.now()}`;
50
+ const enrichedPrompt = context
51
+ ? enrichPromptWithContext(userPrompt, context)
52
+ : userPrompt;
53
+ const result = await this.executePromptCommand(enrichedPrompt, 'main', 1);
54
+ if (result.exitCode !== 0) {
55
+ return {
56
+ completed: false,
57
+ needsHandoff: false,
58
+ totalTokens: 0,
59
+ sessionId,
60
+ error: result.error || 'Execution failed',
61
+ assistantResponse: result.assistantResponse,
62
+ thinkingOutput: result.thinkingOutput,
63
+ toolUseHistory: result.toolUseHistory,
64
+ claudeSessionId: result.claudeSessionId
65
+ };
66
+ }
67
+ const tokens = estimateTokensFromOutput(result.output);
68
+ return {
69
+ completed: true,
70
+ needsHandoff: false,
71
+ totalTokens: tokens,
72
+ sessionId,
73
+ assistantResponse: result.assistantResponse,
74
+ thinkingOutput: result.thinkingOutput,
75
+ toolUseHistory: result.toolUseHistory,
76
+ claudeSessionId: result.claudeSessionId
77
+ };
78
+ }
79
+ /**
80
+ * Execute a single prompt via Claude CLI
81
+ */
82
+ async executePromptCommand(prompt, promptId, sessionNumber) {
83
+ const invokerOptions = {
84
+ config: this.config,
85
+ runningProcesses: this.runningProcesses
86
+ };
87
+ return executeClaudeCommand(prompt, promptId, sessionNumber, invokerOptions);
88
+ }
89
+ /**
90
+ * Cleanup on exit
91
+ */
92
+ cleanup() {
93
+ for (const [_pid, process] of this.runningProcesses) {
94
+ process.kill();
95
+ }
96
+ this.runningProcesses.clear();
97
+ }
98
+ }
99
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../../server/cli/headless/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Headless Runner Types
3
+ *
4
+ * Shared type definitions for the headless execution system.
5
+ */
6
+ export interface PromptContext {
7
+ previousMovements?: string[];
8
+ accumulatedKnowledge: string;
9
+ filesModified: string[];
10
+ }
11
+ export interface ToolUseEvent {
12
+ type: 'tool_start' | 'tool_input_delta' | 'tool_complete' | 'tool_result';
13
+ toolName?: string;
14
+ toolId?: string;
15
+ index?: number;
16
+ partialJson?: string;
17
+ completeInput?: any;
18
+ result?: string;
19
+ isError?: boolean;
20
+ }
21
+ export interface ImageAttachment {
22
+ fileName: string;
23
+ filePath: string;
24
+ content: string;
25
+ isImage: boolean;
26
+ mimeType?: string;
27
+ }
28
+ export interface HeadlessConfig {
29
+ workingDir: string;
30
+ tokenBudgetThreshold: number;
31
+ maxSessions: number;
32
+ maxRetries: number;
33
+ claudeCommand: string;
34
+ verbose: boolean;
35
+ noColor: boolean;
36
+ improvisationMode?: boolean;
37
+ movementNumber?: number;
38
+ outputCallback?: (text: string) => void;
39
+ thinkingCallback?: (text: string) => void;
40
+ toolUseCallback?: (event: ToolUseEvent) => void;
41
+ directPrompt?: string;
42
+ promptContext?: PromptContext;
43
+ continueSession?: boolean;
44
+ claudeSessionId?: string;
45
+ imageAttachments?: ImageAttachment[];
46
+ }
47
+ export interface SessionState {
48
+ sessionId: string;
49
+ sessionNumber: number;
50
+ tokensUsed: number;
51
+ checkpointPath: string;
52
+ handoffGenerated: boolean;
53
+ retryCount: number;
54
+ status: 'running' | 'completed' | 'failed' | 'handoff';
55
+ }
56
+ export interface SessionResult {
57
+ completed: boolean;
58
+ needsHandoff: boolean;
59
+ totalTokens: number;
60
+ sessionId: string;
61
+ error?: string;
62
+ conflicts?: Array<{
63
+ filePath: string;
64
+ modifiedBy: string[];
65
+ backupPath?: string;
66
+ }>;
67
+ assistantResponse?: string;
68
+ thinkingOutput?: string;
69
+ toolUseHistory?: Array<{
70
+ toolName: string;
71
+ toolId: string;
72
+ toolInput: Record<string, unknown>;
73
+ result?: string;
74
+ isError?: boolean;
75
+ duration?: number;
76
+ }>;
77
+ claudeSessionId?: string;
78
+ }
79
+ export interface ToolUseAccumulator {
80
+ toolName: string;
81
+ toolId: string;
82
+ toolInput: Record<string, unknown>;
83
+ result?: string;
84
+ isError?: boolean;
85
+ startTime: number;
86
+ duration?: number;
87
+ }
88
+ export interface ExecutionResult {
89
+ output: string;
90
+ error?: string;
91
+ exitCode: number;
92
+ assistantResponse?: string;
93
+ thinkingOutput?: string;
94
+ toolUseHistory?: ToolUseAccumulator[];
95
+ claudeSessionId?: string;
96
+ }
97
+ /** Resolved config with all defaults applied */
98
+ export type ResolvedHeadlessConfig = Omit<Required<HeadlessConfig>, 'outputCallback' | 'thinkingCallback' | 'toolUseCallback' | 'continueSession' | 'claudeSessionId' | 'imageAttachments'> & {
99
+ outputCallback?: (text: string) => void;
100
+ thinkingCallback?: (text: string) => void;
101
+ toolUseCallback?: (event: ToolUseEvent) => void;
102
+ continueSession?: boolean;
103
+ claudeSessionId?: string;
104
+ imageAttachments?: ImageAttachment[];
105
+ };
106
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../server/cli/headless/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+ export {};
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../server/cli/headless/types.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,gEAAgE"}
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Improvisation Session Manager v2
3
+ *
4
+ * Optimized for fast, direct prompt execution in Improvise mode.
5
+ * For complex multi-part prompts with parallel/sequential movements, use Compose tab instead.
6
+ */
7
+ import { EventEmitter } from 'node:events';
8
+ export interface ImprovisationOptions {
9
+ workingDir: string;
10
+ sessionId: string;
11
+ tokenBudgetThreshold: number;
12
+ maxSessions: number;
13
+ verbose: boolean;
14
+ noColor: boolean;
15
+ }
16
+ export interface FileAttachment {
17
+ fileName: string;
18
+ filePath: string;
19
+ content: string;
20
+ isImage: boolean;
21
+ mimeType?: string;
22
+ }
23
+ export interface ToolUseRecord {
24
+ toolName: string;
25
+ toolId: string;
26
+ toolInput: Record<string, unknown>;
27
+ result?: string;
28
+ isError?: boolean;
29
+ duration?: number;
30
+ }
31
+ export interface MovementRecord {
32
+ id: string;
33
+ sequenceNumber: number;
34
+ userPrompt: string;
35
+ timestamp: string;
36
+ tokensUsed: number;
37
+ summary: string;
38
+ filesModified: string[];
39
+ assistantResponse?: string;
40
+ thinkingOutput?: string;
41
+ toolUseHistory?: ToolUseRecord[];
42
+ errorOutput?: string;
43
+ }
44
+ export interface SessionHistory {
45
+ sessionId: string;
46
+ startedAt: string;
47
+ lastActivityAt: string;
48
+ totalTokens: number;
49
+ movements: MovementRecord[];
50
+ claudeSessionId?: string;
51
+ }
52
+ export declare class ImprovisationSessionManager extends EventEmitter {
53
+ private sessionId;
54
+ private improviseDir;
55
+ private historyPath;
56
+ private history;
57
+ private currentRunner;
58
+ private options;
59
+ private pendingApproval?;
60
+ private outputQueue;
61
+ private queueTimer;
62
+ private isFirstPrompt;
63
+ private claudeSessionId;
64
+ private isResumedSession;
65
+ accumulatedKnowledge: string;
66
+ /**
67
+ * Resume from a historical session.
68
+ * Creates a new session manager that continues the conversation from a previous session.
69
+ * The first prompt will include context from the historical session.
70
+ */
71
+ static resumeFromHistory(workingDir: string, historicalSessionId: string): ImprovisationSessionManager;
72
+ constructor(options?: Partial<ImprovisationOptions>);
73
+ /**
74
+ * Start background queue processor that flushes output immediately
75
+ */
76
+ private startQueueProcessor;
77
+ /**
78
+ * Queue output for immediate processing
79
+ */
80
+ private queueOutput;
81
+ /**
82
+ * Flush all queued output immediately
83
+ */
84
+ private flushOutputQueue;
85
+ /**
86
+ * Build prompt with text file attachments prepended
87
+ * Format: each text file is shown as @path followed by content in code block
88
+ */
89
+ private buildPromptWithAttachments;
90
+ /**
91
+ * Execute a user prompt directly (Improvise mode - no score decomposition)
92
+ * Uses persistent Claude sessions via --resume <sessionId> for conversation continuity
93
+ * Each tab maintains its own claudeSessionId for proper isolation
94
+ * Supports file attachments: text files prepended to prompt, images via stream-json multimodal
95
+ */
96
+ executePrompt(userPrompt: string, attachments?: FileAttachment[]): Promise<MovementRecord>;
97
+ /**
98
+ * Build historical context for resuming a session.
99
+ * This creates a summary of the previous conversation that will be injected
100
+ * into the first prompt of a resumed session.
101
+ */
102
+ private buildHistoricalContext;
103
+ /**
104
+ * Load history from disk
105
+ */
106
+ private loadHistory;
107
+ /**
108
+ * Save history to disk
109
+ */
110
+ private saveHistory;
111
+ /**
112
+ * Get session history
113
+ */
114
+ getHistory(): SessionHistory;
115
+ /**
116
+ * Cancel current execution
117
+ */
118
+ cancel(): void;
119
+ /**
120
+ * Cleanup queue processor on shutdown
121
+ */
122
+ destroy(): void;
123
+ /**
124
+ * Clear session history and reset to fresh Claude session
125
+ * This resets the isFirstPrompt flag and claudeSessionId so the next prompt starts a new session
126
+ */
127
+ clearHistory(): void;
128
+ /**
129
+ * Request user approval for a plan
130
+ * Returns a promise that resolves when the user approves/rejects
131
+ */
132
+ requestApproval(plan: any): Promise<boolean>;
133
+ /**
134
+ * Respond to approval request
135
+ */
136
+ respondToApproval(approved: boolean): void;
137
+ /**
138
+ * Get session metadata
139
+ */
140
+ getSessionInfo(): {
141
+ sessionId: string;
142
+ startTime: string;
143
+ workingDir: string;
144
+ totalTokens: number;
145
+ tokenBudgetThreshold: number;
146
+ movementCount: number;
147
+ };
148
+ /**
149
+ * Start a new session with fresh context
150
+ * Creates a completely new session manager with isFirstPrompt=true and no claudeSessionId,
151
+ * ensuring the next prompt starts a fresh Claude conversation (proper tab isolation)
152
+ */
153
+ startNewSession(): ImprovisationSessionManager;
154
+ }
155
+ //# sourceMappingURL=improvisation-session-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"improvisation-session-manager.d.ts","sourceRoot":"","sources":["../../../server/cli/improvisation-session-manager.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAK3C,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAGD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,EAAE,CAAC;IAExB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,2BAA4B,SAAQ,YAAY;IAC3D,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,eAAe,CAAC,CAGtB;IACF,OAAO,CAAC,WAAW,CAAkD;IACrE,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,gBAAgB,CAAkB;IAC1C,oBAAoB,EAAE,MAAM,CAAM;IAElC;;;;OAIG;IACH,MAAM,CAAC,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,GAAG,2BAA2B;gBA0C1F,OAAO,GAAE,OAAO,CAAC,oBAAoB,CAAM;IA4BvD;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IASxB;;;OAGG;IACH,OAAO,CAAC,0BAA0B;IAoBlC;;;;;OAKG;IACG,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC;IAwIhG;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IA2C9B;;OAEG;IACH,OAAO,CAAC,WAAW;IAmBnB;;OAEG;IACH,OAAO,CAAC,WAAW;IAKnB;;OAEG;IACH,UAAU,IAAI,cAAc;IAI5B;;OAEG;IACH,MAAM,IAAI,IAAI;IASd;;OAEG;IACH,OAAO,IAAI,IAAI;IAQf;;;OAGG;IACH,YAAY,IAAI,IAAI;IAUpB;;;OAGG;IACG,eAAe,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC;IAOlD;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAO1C;;OAEG;IACH,cAAc;;;;;;;;IAWd;;;;OAIG;IACH,eAAe,IAAI,2BAA2B;CAe/C"}