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,108 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+
4
+ /**
5
+ * Prompt Utilities
6
+ *
7
+ * Utilities for enriching prompts with context from previous conversation.
8
+ */
9
+
10
+ import type { ImageAttachment, PromptContext } from './types.js';
11
+
12
+ /**
13
+ * Enrich prompt with context from previous conversation
14
+ */
15
+ export function enrichPromptWithContext(prompt: string, context: PromptContext): string {
16
+ let enriched = prompt;
17
+
18
+ // Detect if this is a continuation/approval prompt
19
+ const isApprovalOrContinuation = isApprovalPrompt(prompt);
20
+
21
+ // Add accumulated knowledge from previous prompts
22
+ if (context.accumulatedKnowledge) {
23
+ if (isApprovalOrContinuation) {
24
+ 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.`;
25
+ } else {
26
+ enriched = `## Context from Previous Work\n${context.accumulatedKnowledge}\n\n## Current Task\n${prompt}`;
27
+ }
28
+ }
29
+
30
+ // Add files modified so far
31
+ if (context.filesModified && context.filesModified.length > 0) {
32
+ enriched += `\n\n## Files Modified in This Session\n${context.filesModified.join('\n')}`;
33
+ }
34
+
35
+ return enriched;
36
+ }
37
+
38
+ /**
39
+ * Detect if a prompt is an approval or continuation
40
+ */
41
+ export function isApprovalPrompt(prompt: string): boolean {
42
+ const lower = prompt.toLowerCase().trim();
43
+
44
+ // Short affirmative responses
45
+ if (['yes', 'y', 'ok', 'okay', 'sure', 'go', 'proceed', 'continue'].includes(lower)) {
46
+ return true;
47
+ }
48
+
49
+ // Approval phrases
50
+ const approvalPatterns = [
51
+ /^yes[,\s]/,
52
+ /^y[,\s]/,
53
+ /^okay[,\s]/,
54
+ /^ok[,\s]/,
55
+ /^sure[,\s]/,
56
+ /^go ahead/,
57
+ /^proceed/,
58
+ /^continue/,
59
+ /^from the (first|previous|last)/i,
60
+ /approval/i,
61
+ /approved/i
62
+ ];
63
+
64
+ return approvalPatterns.some(pattern => pattern.test(lower));
65
+ }
66
+
67
+ /**
68
+ * Build a multimodal message for stream-json input format.
69
+ * This constructs a JSON message with image content blocks followed by text.
70
+ * Format: {"type":"user","message":{"role":"user","content":[{image blocks...},{type:"text",text:"..."}]}}
71
+ */
72
+ export function buildMultimodalMessage(textPrompt: string, imageAttachments: ImageAttachment[]): string {
73
+ // Build content array with images first, then text
74
+ const content: Array<{
75
+ type: 'image' | 'text';
76
+ source?: { type: 'base64'; media_type: string; data: string };
77
+ text?: string;
78
+ }> = [];
79
+
80
+ // Add each image as a content block
81
+ for (const attachment of imageAttachments) {
82
+ content.push({
83
+ type: 'image',
84
+ source: {
85
+ type: 'base64',
86
+ media_type: attachment.mimeType || 'image/png',
87
+ data: attachment.content
88
+ }
89
+ });
90
+ }
91
+
92
+ // Add the text prompt
93
+ content.push({
94
+ type: 'text',
95
+ text: textPrompt
96
+ });
97
+
98
+ // Construct the message in Claude API format
99
+ const message = {
100
+ type: 'user',
101
+ message: {
102
+ role: 'user',
103
+ content
104
+ }
105
+ };
106
+
107
+ return JSON.stringify(message);
108
+ }
@@ -0,0 +1,133 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+
4
+ /**
5
+ * Headless Runner
6
+ *
7
+ * Executes prompts via Claude Code CLI in improvise mode.
8
+ * Uses direct prompt execution with persistent Claude sessions.
9
+ */
10
+
11
+ import type { ChildProcess } from 'node:child_process';
12
+ import { type ClaudeInvokerOptions, executeClaudeCommand } from './claude-invoker.js';
13
+ import { estimateTokensFromOutput } from './output-utils.js';
14
+ import { enrichPromptWithContext } from './prompt-utils.js';
15
+ import type {
16
+ HeadlessConfig,
17
+ PromptContext,
18
+ ResolvedHeadlessConfig,
19
+ SessionResult,
20
+ } from './types.js';
21
+
22
+ // Re-export types for backward compatibility
23
+ export type { HeadlessConfig, ImageAttachment, SessionResult, SessionState, ToolUseEvent } from './types.js';
24
+
25
+ export class HeadlessRunner {
26
+ private config: ResolvedHeadlessConfig;
27
+ private runningProcesses: Map<number, ChildProcess> = new Map();
28
+
29
+ constructor(config: Partial<HeadlessConfig>) {
30
+ this.config = {
31
+ workingDir: config.workingDir || process.cwd(),
32
+ tokenBudgetThreshold: config.tokenBudgetThreshold || 170000,
33
+ maxSessions: config.maxSessions || 50,
34
+ maxRetries: config.maxRetries || 3,
35
+ claudeCommand: config.claudeCommand || process.env.CLAUDE_COMMAND || 'claude',
36
+ verbose: config.verbose || false,
37
+ noColor: config.noColor || false,
38
+ improvisationMode: config.improvisationMode || false,
39
+ movementNumber: config.movementNumber ?? 0,
40
+ outputCallback: config.outputCallback,
41
+ thinkingCallback: config.thinkingCallback,
42
+ toolUseCallback: config.toolUseCallback,
43
+ continueSession: config.continueSession,
44
+ claudeSessionId: config.claudeSessionId,
45
+ directPrompt: config.directPrompt || '',
46
+ promptContext: config.promptContext || { accumulatedKnowledge: '', filesModified: [] },
47
+ imageAttachments: config.imageAttachments
48
+ };
49
+ }
50
+
51
+ /**
52
+ * Run direct prompt execution
53
+ */
54
+ async run(): Promise<SessionResult> {
55
+ if (this.config.directPrompt) {
56
+ return await this.runDirectPrompt(this.config.directPrompt, this.config.promptContext);
57
+ }
58
+
59
+ return {
60
+ completed: false,
61
+ needsHandoff: false,
62
+ totalTokens: 0,
63
+ sessionId: '',
64
+ error: 'No prompt provided. Use directPrompt in improvise mode.'
65
+ };
66
+ }
67
+
68
+ /**
69
+ * Execute a direct prompt without score file I/O
70
+ */
71
+ private async runDirectPrompt(userPrompt: string, context?: PromptContext): Promise<SessionResult> {
72
+ const sessionId = `direct-${Date.now()}`;
73
+
74
+ const enrichedPrompt = context
75
+ ? enrichPromptWithContext(userPrompt, context)
76
+ : userPrompt;
77
+
78
+ const result = await this.executePromptCommand(enrichedPrompt, 'main', 1);
79
+
80
+ if (result.exitCode !== 0) {
81
+ return {
82
+ completed: false,
83
+ needsHandoff: false,
84
+ totalTokens: 0,
85
+ sessionId,
86
+ error: result.error || 'Execution failed',
87
+ assistantResponse: result.assistantResponse,
88
+ thinkingOutput: result.thinkingOutput,
89
+ toolUseHistory: result.toolUseHistory,
90
+ claudeSessionId: result.claudeSessionId
91
+ };
92
+ }
93
+
94
+ const tokens = estimateTokensFromOutput(result.output);
95
+
96
+ return {
97
+ completed: true,
98
+ needsHandoff: false,
99
+ totalTokens: tokens,
100
+ sessionId,
101
+ assistantResponse: result.assistantResponse,
102
+ thinkingOutput: result.thinkingOutput,
103
+ toolUseHistory: result.toolUseHistory,
104
+ claudeSessionId: result.claudeSessionId
105
+ };
106
+ }
107
+
108
+ /**
109
+ * Execute a single prompt via Claude CLI
110
+ */
111
+ private async executePromptCommand(
112
+ prompt: string,
113
+ promptId: string,
114
+ sessionNumber: number
115
+ ) {
116
+ const invokerOptions: ClaudeInvokerOptions = {
117
+ config: this.config,
118
+ runningProcesses: this.runningProcesses
119
+ };
120
+
121
+ return executeClaudeCommand(prompt, promptId, sessionNumber, invokerOptions);
122
+ }
123
+
124
+ /**
125
+ * Cleanup on exit
126
+ */
127
+ cleanup(): void {
128
+ for (const [_pid, process] of this.runningProcesses) {
129
+ process.kill();
130
+ }
131
+ this.runningProcesses.clear();
132
+ }
133
+ }
@@ -0,0 +1,118 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+
4
+ /**
5
+ * Headless Runner Types
6
+ *
7
+ * Shared type definitions for the headless execution system.
8
+ */
9
+
10
+ export interface PromptContext {
11
+ previousMovements?: string[];
12
+ accumulatedKnowledge: string;
13
+ filesModified: string[];
14
+ }
15
+
16
+ export interface ToolUseEvent {
17
+ type: 'tool_start' | 'tool_input_delta' | 'tool_complete' | 'tool_result';
18
+ toolName?: string;
19
+ toolId?: string;
20
+ index?: number;
21
+ partialJson?: string;
22
+ completeInput?: any;
23
+ result?: string;
24
+ isError?: boolean;
25
+ }
26
+
27
+ // Image attachment for multimodal prompts
28
+ export interface ImageAttachment {
29
+ fileName: string; // Display name (e.g., "screenshot.png")
30
+ filePath: string; // Full path on disk (for context)
31
+ content: string; // Base64 encoded image data
32
+ isImage: boolean; // Should always be true
33
+ mimeType?: string; // MIME type (e.g., "image/png")
34
+ }
35
+
36
+ export interface HeadlessConfig {
37
+ workingDir: string;
38
+ tokenBudgetThreshold: number;
39
+ maxSessions: number;
40
+ maxRetries: number;
41
+ claudeCommand: string;
42
+ verbose: boolean;
43
+ noColor: boolean;
44
+ improvisationMode?: boolean;
45
+ movementNumber?: number;
46
+ outputCallback?: (text: string) => void;
47
+ thinkingCallback?: (text: string) => void;
48
+ toolUseCallback?: (event: ToolUseEvent) => void;
49
+ directPrompt?: string;
50
+ promptContext?: PromptContext;
51
+ continueSession?: boolean;
52
+ claudeSessionId?: string;
53
+ imageAttachments?: ImageAttachment[];
54
+ }
55
+
56
+ export interface SessionState {
57
+ sessionId: string;
58
+ sessionNumber: number;
59
+ tokensUsed: number;
60
+ checkpointPath: string;
61
+ handoffGenerated: boolean;
62
+ retryCount: number;
63
+ status: 'running' | 'completed' | 'failed' | 'handoff';
64
+ }
65
+
66
+ export interface SessionResult {
67
+ completed: boolean;
68
+ needsHandoff: boolean;
69
+ totalTokens: number;
70
+ sessionId: string;
71
+ error?: string;
72
+ conflicts?: Array<{
73
+ filePath: string;
74
+ modifiedBy: string[];
75
+ backupPath?: string;
76
+ }>;
77
+ assistantResponse?: string;
78
+ thinkingOutput?: string;
79
+ toolUseHistory?: Array<{
80
+ toolName: string;
81
+ toolId: string;
82
+ toolInput: Record<string, unknown>;
83
+ result?: string;
84
+ isError?: boolean;
85
+ duration?: number;
86
+ }>;
87
+ claudeSessionId?: string;
88
+ }
89
+
90
+ export interface ToolUseAccumulator {
91
+ toolName: string;
92
+ toolId: string;
93
+ toolInput: Record<string, unknown>;
94
+ result?: string;
95
+ isError?: boolean;
96
+ startTime: number;
97
+ duration?: number;
98
+ }
99
+
100
+ export interface ExecutionResult {
101
+ output: string;
102
+ error?: string;
103
+ exitCode: number;
104
+ assistantResponse?: string;
105
+ thinkingOutput?: string;
106
+ toolUseHistory?: ToolUseAccumulator[];
107
+ claudeSessionId?: string;
108
+ }
109
+
110
+ /** Resolved config with all defaults applied */
111
+ export type ResolvedHeadlessConfig = Omit<Required<HeadlessConfig>, 'outputCallback' | 'thinkingCallback' | 'toolUseCallback' | 'continueSession' | 'claudeSessionId' | 'imageAttachments'> & {
112
+ outputCallback?: (text: string) => void;
113
+ thinkingCallback?: (text: string) => void;
114
+ toolUseCallback?: (event: ToolUseEvent) => void;
115
+ continueSession?: boolean;
116
+ claudeSessionId?: string;
117
+ imageAttachments?: ImageAttachment[];
118
+ };