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.
- package/LICENSE +21 -0
- package/README.md +177 -0
- package/bin/commands/config.js +145 -0
- package/bin/commands/login.js +313 -0
- package/bin/commands/logout.js +75 -0
- package/bin/commands/status.js +197 -0
- package/bin/commands/whoami.js +161 -0
- package/bin/configure-claude.js +298 -0
- package/bin/mstro.js +581 -0
- package/bin/postinstall.js +45 -0
- package/bin/release.sh +110 -0
- package/dist/server/cli/headless/claude-invoker.d.ts +17 -0
- package/dist/server/cli/headless/claude-invoker.d.ts.map +1 -0
- package/dist/server/cli/headless/claude-invoker.js +311 -0
- package/dist/server/cli/headless/claude-invoker.js.map +1 -0
- package/dist/server/cli/headless/index.d.ts +13 -0
- package/dist/server/cli/headless/index.d.ts.map +1 -0
- package/dist/server/cli/headless/index.js +10 -0
- package/dist/server/cli/headless/index.js.map +1 -0
- package/dist/server/cli/headless/mcp-config.d.ts +11 -0
- package/dist/server/cli/headless/mcp-config.d.ts.map +1 -0
- package/dist/server/cli/headless/mcp-config.js +76 -0
- package/dist/server/cli/headless/mcp-config.js.map +1 -0
- package/dist/server/cli/headless/output-utils.d.ts +33 -0
- package/dist/server/cli/headless/output-utils.d.ts.map +1 -0
- package/dist/server/cli/headless/output-utils.js +101 -0
- package/dist/server/cli/headless/output-utils.js.map +1 -0
- package/dist/server/cli/headless/prompt-utils.d.ts +21 -0
- package/dist/server/cli/headless/prompt-utils.d.ts.map +1 -0
- package/dist/server/cli/headless/prompt-utils.js +84 -0
- package/dist/server/cli/headless/prompt-utils.js.map +1 -0
- package/dist/server/cli/headless/runner.d.ts +24 -0
- package/dist/server/cli/headless/runner.d.ts.map +1 -0
- package/dist/server/cli/headless/runner.js +99 -0
- package/dist/server/cli/headless/runner.js.map +1 -0
- package/dist/server/cli/headless/types.d.ts +106 -0
- package/dist/server/cli/headless/types.d.ts.map +1 -0
- package/dist/server/cli/headless/types.js +4 -0
- package/dist/server/cli/headless/types.js.map +1 -0
- package/dist/server/cli/improvisation-session-manager.d.ts +155 -0
- package/dist/server/cli/improvisation-session-manager.d.ts.map +1 -0
- package/dist/server/cli/improvisation-session-manager.js +415 -0
- package/dist/server/cli/improvisation-session-manager.js.map +1 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +386 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/mcp/bouncer-cli.d.ts +3 -0
- package/dist/server/mcp/bouncer-cli.d.ts.map +1 -0
- package/dist/server/mcp/bouncer-cli.js +99 -0
- package/dist/server/mcp/bouncer-cli.js.map +1 -0
- package/dist/server/mcp/bouncer-integration.d.ts +36 -0
- package/dist/server/mcp/bouncer-integration.d.ts.map +1 -0
- package/dist/server/mcp/bouncer-integration.js +301 -0
- package/dist/server/mcp/bouncer-integration.js.map +1 -0
- package/dist/server/mcp/security-audit.d.ts +52 -0
- package/dist/server/mcp/security-audit.d.ts.map +1 -0
- package/dist/server/mcp/security-audit.js +118 -0
- package/dist/server/mcp/security-audit.js.map +1 -0
- package/dist/server/mcp/security-patterns.d.ts +73 -0
- package/dist/server/mcp/security-patterns.d.ts.map +1 -0
- package/dist/server/mcp/security-patterns.js +247 -0
- package/dist/server/mcp/security-patterns.js.map +1 -0
- package/dist/server/mcp/server.d.ts +3 -0
- package/dist/server/mcp/server.d.ts.map +1 -0
- package/dist/server/mcp/server.js +146 -0
- package/dist/server/mcp/server.js.map +1 -0
- package/dist/server/routes/files.d.ts +9 -0
- package/dist/server/routes/files.d.ts.map +1 -0
- package/dist/server/routes/files.js +24 -0
- package/dist/server/routes/files.js.map +1 -0
- package/dist/server/routes/improvise.d.ts +3 -0
- package/dist/server/routes/improvise.d.ts.map +1 -0
- package/dist/server/routes/improvise.js +72 -0
- package/dist/server/routes/improvise.js.map +1 -0
- package/dist/server/routes/index.d.ts +10 -0
- package/dist/server/routes/index.d.ts.map +1 -0
- package/dist/server/routes/index.js +12 -0
- package/dist/server/routes/index.js.map +1 -0
- package/dist/server/routes/instances.d.ts +10 -0
- package/dist/server/routes/instances.d.ts.map +1 -0
- package/dist/server/routes/instances.js +47 -0
- package/dist/server/routes/instances.js.map +1 -0
- package/dist/server/routes/notifications.d.ts +3 -0
- package/dist/server/routes/notifications.d.ts.map +1 -0
- package/dist/server/routes/notifications.js +136 -0
- package/dist/server/routes/notifications.js.map +1 -0
- package/dist/server/services/analytics.d.ts +56 -0
- package/dist/server/services/analytics.d.ts.map +1 -0
- package/dist/server/services/analytics.js +240 -0
- package/dist/server/services/analytics.js.map +1 -0
- package/dist/server/services/auth.d.ts +26 -0
- package/dist/server/services/auth.d.ts.map +1 -0
- package/dist/server/services/auth.js +71 -0
- package/dist/server/services/auth.js.map +1 -0
- package/dist/server/services/client-id.d.ts +10 -0
- package/dist/server/services/client-id.d.ts.map +1 -0
- package/dist/server/services/client-id.js +61 -0
- package/dist/server/services/client-id.js.map +1 -0
- package/dist/server/services/credentials.d.ts +39 -0
- package/dist/server/services/credentials.d.ts.map +1 -0
- package/dist/server/services/credentials.js +110 -0
- package/dist/server/services/credentials.js.map +1 -0
- package/dist/server/services/files.d.ts +119 -0
- package/dist/server/services/files.d.ts.map +1 -0
- package/dist/server/services/files.js +560 -0
- package/dist/server/services/files.js.map +1 -0
- package/dist/server/services/instances.d.ts +52 -0
- package/dist/server/services/instances.d.ts.map +1 -0
- package/dist/server/services/instances.js +241 -0
- package/dist/server/services/instances.js.map +1 -0
- package/dist/server/services/pathUtils.d.ts +47 -0
- package/dist/server/services/pathUtils.d.ts.map +1 -0
- package/dist/server/services/pathUtils.js +124 -0
- package/dist/server/services/pathUtils.js.map +1 -0
- package/dist/server/services/platform.d.ts +72 -0
- package/dist/server/services/platform.d.ts.map +1 -0
- package/dist/server/services/platform.js +368 -0
- package/dist/server/services/platform.js.map +1 -0
- package/dist/server/services/sentry.d.ts +5 -0
- package/dist/server/services/sentry.d.ts.map +1 -0
- package/dist/server/services/sentry.js +71 -0
- package/dist/server/services/sentry.js.map +1 -0
- package/dist/server/services/terminal/pty-manager.d.ts +149 -0
- package/dist/server/services/terminal/pty-manager.d.ts.map +1 -0
- package/dist/server/services/terminal/pty-manager.js +377 -0
- package/dist/server/services/terminal/pty-manager.js.map +1 -0
- package/dist/server/services/terminal/tmux-manager.d.ts +82 -0
- package/dist/server/services/terminal/tmux-manager.d.ts.map +1 -0
- package/dist/server/services/terminal/tmux-manager.js +352 -0
- package/dist/server/services/terminal/tmux-manager.js.map +1 -0
- package/dist/server/services/websocket/autocomplete.d.ts +50 -0
- package/dist/server/services/websocket/autocomplete.d.ts.map +1 -0
- package/dist/server/services/websocket/autocomplete.js +361 -0
- package/dist/server/services/websocket/autocomplete.js.map +1 -0
- package/dist/server/services/websocket/file-utils.d.ts +44 -0
- package/dist/server/services/websocket/file-utils.d.ts.map +1 -0
- package/dist/server/services/websocket/file-utils.js +272 -0
- package/dist/server/services/websocket/file-utils.js.map +1 -0
- package/dist/server/services/websocket/handler.d.ts +246 -0
- package/dist/server/services/websocket/handler.d.ts.map +1 -0
- package/dist/server/services/websocket/handler.js +1771 -0
- package/dist/server/services/websocket/handler.js.map +1 -0
- package/dist/server/services/websocket/index.d.ts +11 -0
- package/dist/server/services/websocket/index.d.ts.map +1 -0
- package/dist/server/services/websocket/index.js +14 -0
- package/dist/server/services/websocket/index.js.map +1 -0
- package/dist/server/services/websocket/types.d.ts +214 -0
- package/dist/server/services/websocket/types.d.ts.map +1 -0
- package/dist/server/services/websocket/types.js +4 -0
- package/dist/server/services/websocket/types.js.map +1 -0
- package/dist/server/utils/agent-manager.d.ts +69 -0
- package/dist/server/utils/agent-manager.d.ts.map +1 -0
- package/dist/server/utils/agent-manager.js +269 -0
- package/dist/server/utils/agent-manager.js.map +1 -0
- package/dist/server/utils/paths.d.ts +25 -0
- package/dist/server/utils/paths.d.ts.map +1 -0
- package/dist/server/utils/paths.js +38 -0
- package/dist/server/utils/paths.js.map +1 -0
- package/dist/server/utils/port-manager.d.ts +10 -0
- package/dist/server/utils/port-manager.d.ts.map +1 -0
- package/dist/server/utils/port-manager.js +60 -0
- package/dist/server/utils/port-manager.js.map +1 -0
- package/dist/server/utils/port.d.ts +26 -0
- package/dist/server/utils/port.d.ts.map +1 -0
- package/dist/server/utils/port.js +83 -0
- package/dist/server/utils/port.js.map +1 -0
- package/hooks/bouncer.sh +138 -0
- package/package.json +74 -0
- package/server/README.md +191 -0
- package/server/cli/headless/claude-invoker.ts +415 -0
- package/server/cli/headless/index.ts +39 -0
- package/server/cli/headless/mcp-config.ts +87 -0
- package/server/cli/headless/output-utils.ts +109 -0
- package/server/cli/headless/prompt-utils.ts +108 -0
- package/server/cli/headless/runner.ts +133 -0
- package/server/cli/headless/types.ts +118 -0
- package/server/cli/improvisation-session-manager.ts +531 -0
- package/server/index.ts +456 -0
- package/server/mcp/README.md +122 -0
- package/server/mcp/bouncer-cli.ts +127 -0
- package/server/mcp/bouncer-integration.ts +430 -0
- package/server/mcp/security-audit.ts +180 -0
- package/server/mcp/security-patterns.ts +290 -0
- package/server/mcp/server.ts +174 -0
- package/server/routes/files.ts +29 -0
- package/server/routes/improvise.ts +82 -0
- package/server/routes/index.ts +13 -0
- package/server/routes/instances.ts +54 -0
- package/server/routes/notifications.ts +158 -0
- package/server/services/analytics.ts +277 -0
- package/server/services/auth.ts +80 -0
- package/server/services/client-id.ts +68 -0
- package/server/services/credentials.ts +134 -0
- package/server/services/files.ts +710 -0
- package/server/services/instances.ts +275 -0
- package/server/services/pathUtils.ts +158 -0
- package/server/services/platform.test.ts +1314 -0
- package/server/services/platform.ts +435 -0
- package/server/services/sentry.ts +81 -0
- package/server/services/terminal/pty-manager.ts +464 -0
- package/server/services/terminal/tmux-manager.ts +426 -0
- package/server/services/websocket/autocomplete.ts +438 -0
- package/server/services/websocket/file-utils.ts +305 -0
- package/server/services/websocket/handler.test.ts +20 -0
- package/server/services/websocket/handler.ts +2047 -0
- package/server/services/websocket/index.ts +40 -0
- package/server/services/websocket/types.ts +339 -0
- package/server/tsconfig.json +19 -0
- package/server/utils/agent-manager.ts +323 -0
- package/server/utils/paths.ts +45 -0
- package/server/utils/port-manager.ts +70 -0
- 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
|
+
};
|