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,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 @@
|
|
|
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":"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"}
|