mstro-app 0.4.3 → 0.4.4
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/dist/server/cli/headless/claude-invoker-process.d.ts +11 -0
- package/dist/server/cli/headless/claude-invoker-process.d.ts.map +1 -0
- package/dist/server/cli/headless/claude-invoker-process.js +140 -0
- package/dist/server/cli/headless/claude-invoker-process.js.map +1 -0
- package/dist/server/cli/headless/claude-invoker-stall.d.ts +40 -0
- package/dist/server/cli/headless/claude-invoker-stall.d.ts.map +1 -0
- package/dist/server/cli/headless/claude-invoker-stall.js +98 -0
- package/dist/server/cli/headless/claude-invoker-stall.js.map +1 -0
- package/dist/server/cli/headless/claude-invoker-stream.d.ts +44 -0
- package/dist/server/cli/headless/claude-invoker-stream.d.ts.map +1 -0
- package/dist/server/cli/headless/claude-invoker-stream.js +276 -0
- package/dist/server/cli/headless/claude-invoker-stream.js.map +1 -0
- package/dist/server/cli/headless/claude-invoker-tools.d.ts +21 -0
- package/dist/server/cli/headless/claude-invoker-tools.d.ts.map +1 -0
- package/dist/server/cli/headless/claude-invoker-tools.js +137 -0
- package/dist/server/cli/headless/claude-invoker-tools.js.map +1 -0
- package/dist/server/cli/headless/claude-invoker.d.ts +6 -4
- package/dist/server/cli/headless/claude-invoker.d.ts.map +1 -1
- package/dist/server/cli/headless/claude-invoker.js +10 -807
- package/dist/server/cli/headless/claude-invoker.js.map +1 -1
- package/dist/server/cli/headless/haiku-assessments.d.ts +62 -0
- package/dist/server/cli/headless/haiku-assessments.d.ts.map +1 -0
- package/dist/server/cli/headless/haiku-assessments.js +281 -0
- package/dist/server/cli/headless/haiku-assessments.js.map +1 -0
- package/dist/server/cli/headless/headless-logger.d.ts +3 -2
- package/dist/server/cli/headless/headless-logger.d.ts.map +1 -1
- package/dist/server/cli/headless/headless-logger.js +28 -5
- package/dist/server/cli/headless/headless-logger.js.map +1 -1
- package/dist/server/cli/headless/native-timeout-detector.d.ts +44 -0
- package/dist/server/cli/headless/native-timeout-detector.d.ts.map +1 -0
- package/dist/server/cli/headless/native-timeout-detector.js +99 -0
- package/dist/server/cli/headless/native-timeout-detector.js.map +1 -0
- package/dist/server/cli/headless/stall-assessor.d.ts +2 -110
- package/dist/server/cli/headless/stall-assessor.d.ts.map +1 -1
- package/dist/server/cli/headless/stall-assessor.js +65 -457
- package/dist/server/cli/headless/stall-assessor.js.map +1 -1
- package/dist/server/cli/improvisation-attachments.d.ts +21 -0
- package/dist/server/cli/improvisation-attachments.d.ts.map +1 -0
- package/dist/server/cli/improvisation-attachments.js +116 -0
- package/dist/server/cli/improvisation-attachments.js.map +1 -0
- package/dist/server/cli/improvisation-retry.d.ts +52 -0
- package/dist/server/cli/improvisation-retry.d.ts.map +1 -0
- package/dist/server/cli/improvisation-retry.js +434 -0
- package/dist/server/cli/improvisation-retry.js.map +1 -0
- package/dist/server/cli/improvisation-session-manager.d.ts +10 -266
- package/dist/server/cli/improvisation-session-manager.d.ts.map +1 -1
- package/dist/server/cli/improvisation-session-manager.js +117 -1079
- package/dist/server/cli/improvisation-session-manager.js.map +1 -1
- package/dist/server/cli/improvisation-types.d.ts +86 -0
- package/dist/server/cli/improvisation-types.d.ts.map +1 -0
- package/dist/server/cli/improvisation-types.js +10 -0
- package/dist/server/cli/improvisation-types.js.map +1 -0
- package/dist/server/cli/prompt-builders.d.ts +68 -0
- package/dist/server/cli/prompt-builders.d.ts.map +1 -0
- package/dist/server/cli/prompt-builders.js +312 -0
- package/dist/server/cli/prompt-builders.js.map +1 -0
- package/dist/server/index.js +33 -212
- package/dist/server/index.js.map +1 -1
- package/dist/server/mcp/bouncer-haiku.d.ts +10 -0
- package/dist/server/mcp/bouncer-haiku.d.ts.map +1 -0
- package/dist/server/mcp/bouncer-haiku.js +152 -0
- package/dist/server/mcp/bouncer-haiku.js.map +1 -0
- package/dist/server/mcp/bouncer-integration.d.ts +3 -4
- package/dist/server/mcp/bouncer-integration.d.ts.map +1 -1
- package/dist/server/mcp/bouncer-integration.js +50 -196
- package/dist/server/mcp/bouncer-integration.js.map +1 -1
- package/dist/server/mcp/security-analysis.d.ts +38 -0
- package/dist/server/mcp/security-analysis.d.ts.map +1 -0
- package/dist/server/mcp/security-analysis.js +183 -0
- package/dist/server/mcp/security-analysis.js.map +1 -0
- package/dist/server/mcp/security-audit.d.ts +1 -1
- package/dist/server/mcp/security-audit.d.ts.map +1 -1
- package/dist/server/mcp/security-patterns.d.ts +1 -25
- package/dist/server/mcp/security-patterns.d.ts.map +1 -1
- package/dist/server/mcp/security-patterns.js +55 -260
- package/dist/server/mcp/security-patterns.js.map +1 -1
- package/dist/server/server-setup.d.ts +22 -0
- package/dist/server/server-setup.d.ts.map +1 -0
- package/dist/server/server-setup.js +101 -0
- package/dist/server/server-setup.js.map +1 -0
- package/dist/server/services/file-explorer-ops.d.ts +24 -0
- package/dist/server/services/file-explorer-ops.d.ts.map +1 -0
- package/dist/server/services/file-explorer-ops.js +211 -0
- package/dist/server/services/file-explorer-ops.js.map +1 -0
- package/dist/server/services/files.d.ts +2 -85
- package/dist/server/services/files.d.ts.map +1 -1
- package/dist/server/services/files.js +7 -427
- package/dist/server/services/files.js.map +1 -1
- package/dist/server/services/plan/composer.d.ts.map +1 -1
- package/dist/server/services/plan/composer.js +2 -1
- package/dist/server/services/plan/composer.js.map +1 -1
- package/dist/server/services/plan/executor.d.ts.map +1 -1
- package/dist/server/services/plan/executor.js +3 -1
- package/dist/server/services/plan/executor.js.map +1 -1
- package/dist/server/services/plan/parser-core.d.ts +20 -0
- package/dist/server/services/plan/parser-core.d.ts.map +1 -0
- package/dist/server/services/plan/parser-core.js +350 -0
- package/dist/server/services/plan/parser-core.js.map +1 -0
- package/dist/server/services/plan/parser-migration.d.ts +5 -0
- package/dist/server/services/plan/parser-migration.d.ts.map +1 -0
- package/dist/server/services/plan/parser-migration.js +124 -0
- package/dist/server/services/plan/parser-migration.js.map +1 -0
- package/dist/server/services/plan/parser.d.ts +0 -8
- package/dist/server/services/plan/parser.d.ts.map +1 -1
- package/dist/server/services/plan/parser.js +50 -569
- package/dist/server/services/plan/parser.js.map +1 -1
- package/dist/server/services/plan/review-gate.d.ts +2 -0
- package/dist/server/services/plan/review-gate.d.ts.map +1 -1
- package/dist/server/services/plan/review-gate.js +2 -2
- package/dist/server/services/plan/review-gate.js.map +1 -1
- package/dist/server/services/plan/types.d.ts +2 -0
- package/dist/server/services/plan/types.d.ts.map +1 -1
- package/dist/server/services/platform-credentials.d.ts +24 -0
- package/dist/server/services/platform-credentials.d.ts.map +1 -0
- package/dist/server/services/platform-credentials.js +68 -0
- package/dist/server/services/platform-credentials.js.map +1 -0
- package/dist/server/services/platform.d.ts +1 -31
- package/dist/server/services/platform.d.ts.map +1 -1
- package/dist/server/services/platform.js +10 -119
- package/dist/server/services/platform.js.map +1 -1
- package/dist/server/services/terminal/pty-manager.d.ts +7 -97
- package/dist/server/services/terminal/pty-manager.d.ts.map +1 -1
- package/dist/server/services/terminal/pty-manager.js +53 -266
- package/dist/server/services/terminal/pty-manager.js.map +1 -1
- package/dist/server/services/terminal/pty-utils.d.ts +57 -0
- package/dist/server/services/terminal/pty-utils.d.ts.map +1 -0
- package/dist/server/services/terminal/pty-utils.js +141 -0
- package/dist/server/services/terminal/pty-utils.js.map +1 -0
- package/dist/server/services/websocket/file-definition-handlers.d.ts +4 -0
- package/dist/server/services/websocket/file-definition-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/file-definition-handlers.js +153 -0
- package/dist/server/services/websocket/file-definition-handlers.js.map +1 -0
- package/dist/server/services/websocket/file-explorer-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/file-explorer-handlers.js +52 -391
- package/dist/server/services/websocket/file-explorer-handlers.js.map +1 -1
- package/dist/server/services/websocket/file-search-handlers.d.ts +5 -0
- package/dist/server/services/websocket/file-search-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/file-search-handlers.js +238 -0
- package/dist/server/services/websocket/file-search-handlers.js.map +1 -0
- package/dist/server/services/websocket/file-utils.js +3 -3
- package/dist/server/services/websocket/file-utils.js.map +1 -1
- package/dist/server/services/websocket/git-branch-handlers.d.ts +7 -0
- package/dist/server/services/websocket/git-branch-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/git-branch-handlers.js +110 -0
- package/dist/server/services/websocket/git-branch-handlers.js.map +1 -0
- package/dist/server/services/websocket/git-diff-handlers.d.ts +6 -0
- package/dist/server/services/websocket/git-diff-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/git-diff-handlers.js +123 -0
- package/dist/server/services/websocket/git-diff-handlers.js.map +1 -0
- package/dist/server/services/websocket/git-handlers.d.ts +2 -31
- package/dist/server/services/websocket/git-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/git-handlers.js +35 -541
- package/dist/server/services/websocket/git-handlers.js.map +1 -1
- package/dist/server/services/websocket/git-log-handlers.d.ts +6 -0
- package/dist/server/services/websocket/git-log-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/git-log-handlers.js +128 -0
- package/dist/server/services/websocket/git-log-handlers.js.map +1 -0
- package/dist/server/services/websocket/git-pr-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/git-pr-handlers.js +13 -53
- package/dist/server/services/websocket/git-pr-handlers.js.map +1 -1
- package/dist/server/services/websocket/git-tag-handlers.d.ts +6 -0
- package/dist/server/services/websocket/git-tag-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/git-tag-handlers.js +76 -0
- package/dist/server/services/websocket/git-tag-handlers.js.map +1 -0
- package/dist/server/services/websocket/git-utils.d.ts +43 -0
- package/dist/server/services/websocket/git-utils.d.ts.map +1 -0
- package/dist/server/services/websocket/git-utils.js +201 -0
- package/dist/server/services/websocket/git-utils.js.map +1 -0
- package/dist/server/services/websocket/handler.d.ts +2 -0
- package/dist/server/services/websocket/handler.d.ts.map +1 -1
- package/dist/server/services/websocket/handler.js +37 -126
- package/dist/server/services/websocket/handler.js.map +1 -1
- package/dist/server/services/websocket/plan-board-handlers.d.ts +11 -0
- package/dist/server/services/websocket/plan-board-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/plan-board-handlers.js +218 -0
- package/dist/server/services/websocket/plan-board-handlers.js.map +1 -0
- package/dist/server/services/websocket/plan-execution-handlers.d.ts +9 -0
- package/dist/server/services/websocket/plan-execution-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/plan-execution-handlers.js +142 -0
- package/dist/server/services/websocket/plan-execution-handlers.js.map +1 -0
- package/dist/server/services/websocket/plan-handlers.d.ts +7 -2
- package/dist/server/services/websocket/plan-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/plan-handlers.js +6 -925
- package/dist/server/services/websocket/plan-handlers.js.map +1 -1
- package/dist/server/services/websocket/plan-helpers.d.ts +19 -0
- package/dist/server/services/websocket/plan-helpers.d.ts.map +1 -0
- package/dist/server/services/websocket/plan-helpers.js +199 -0
- package/dist/server/services/websocket/plan-helpers.js.map +1 -0
- package/dist/server/services/websocket/plan-issue-handlers.d.ts +12 -0
- package/dist/server/services/websocket/plan-issue-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/plan-issue-handlers.js +162 -0
- package/dist/server/services/websocket/plan-issue-handlers.js.map +1 -0
- package/dist/server/services/websocket/plan-sprint-handlers.d.ts +7 -0
- package/dist/server/services/websocket/plan-sprint-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/plan-sprint-handlers.js +206 -0
- package/dist/server/services/websocket/plan-sprint-handlers.js.map +1 -0
- package/dist/server/services/websocket/quality-complexity.d.ts +14 -0
- package/dist/server/services/websocket/quality-complexity.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-complexity.js +262 -0
- package/dist/server/services/websocket/quality-complexity.js.map +1 -0
- package/dist/server/services/websocket/quality-fix-agent.d.ts +16 -0
- package/dist/server/services/websocket/quality-fix-agent.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-fix-agent.js +140 -0
- package/dist/server/services/websocket/quality-fix-agent.js.map +1 -0
- package/dist/server/services/websocket/quality-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/quality-handlers.js +34 -346
- package/dist/server/services/websocket/quality-handlers.js.map +1 -1
- package/dist/server/services/websocket/quality-linting.d.ts +9 -0
- package/dist/server/services/websocket/quality-linting.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-linting.js +178 -0
- package/dist/server/services/websocket/quality-linting.js.map +1 -0
- package/dist/server/services/websocket/quality-review-agent.d.ts +19 -0
- package/dist/server/services/websocket/quality-review-agent.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-review-agent.js +206 -0
- package/dist/server/services/websocket/quality-review-agent.js.map +1 -0
- package/dist/server/services/websocket/quality-service.d.ts +3 -51
- package/dist/server/services/websocket/quality-service.d.ts.map +1 -1
- package/dist/server/services/websocket/quality-service.js +9 -651
- package/dist/server/services/websocket/quality-service.js.map +1 -1
- package/dist/server/services/websocket/quality-tools.d.ts +23 -0
- package/dist/server/services/websocket/quality-tools.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-tools.js +208 -0
- package/dist/server/services/websocket/quality-tools.js.map +1 -0
- package/dist/server/services/websocket/quality-types.d.ts +59 -0
- package/dist/server/services/websocket/quality-types.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-types.js +101 -0
- package/dist/server/services/websocket/quality-types.js.map +1 -0
- package/dist/server/services/websocket/session-handlers.d.ts +3 -4
- package/dist/server/services/websocket/session-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/session-handlers.js +3 -378
- package/dist/server/services/websocket/session-handlers.js.map +1 -1
- package/dist/server/services/websocket/session-history.d.ts +4 -0
- package/dist/server/services/websocket/session-history.d.ts.map +1 -0
- package/dist/server/services/websocket/session-history.js +208 -0
- package/dist/server/services/websocket/session-history.js.map +1 -0
- package/dist/server/services/websocket/session-initialization.d.ts +5 -0
- package/dist/server/services/websocket/session-initialization.d.ts.map +1 -0
- package/dist/server/services/websocket/session-initialization.js +163 -0
- package/dist/server/services/websocket/session-initialization.js.map +1 -0
- package/dist/server/services/websocket/types.d.ts +12 -2
- package/dist/server/services/websocket/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/server/cli/headless/claude-invoker-process.ts +204 -0
- package/server/cli/headless/claude-invoker-stall.ts +164 -0
- package/server/cli/headless/claude-invoker-stream.ts +353 -0
- package/server/cli/headless/claude-invoker-tools.ts +187 -0
- package/server/cli/headless/claude-invoker.ts +15 -1096
- package/server/cli/headless/haiku-assessments.ts +365 -0
- package/server/cli/headless/headless-logger.ts +26 -5
- package/server/cli/headless/native-timeout-detector.ts +117 -0
- package/server/cli/headless/stall-assessor.ts +65 -618
- package/server/cli/improvisation-attachments.ts +148 -0
- package/server/cli/improvisation-retry.ts +602 -0
- package/server/cli/improvisation-session-manager.ts +140 -1349
- package/server/cli/improvisation-types.ts +98 -0
- package/server/cli/prompt-builders.ts +370 -0
- package/server/index.ts +35 -246
- package/server/mcp/bouncer-haiku.ts +182 -0
- package/server/mcp/bouncer-integration.ts +87 -248
- package/server/mcp/security-analysis.ts +217 -0
- package/server/mcp/security-audit.ts +1 -1
- package/server/mcp/security-patterns.ts +60 -283
- package/server/server-setup.ts +114 -0
- package/server/services/file-explorer-ops.ts +293 -0
- package/server/services/files.ts +20 -532
- package/server/services/plan/composer.ts +2 -1
- package/server/services/plan/executor.ts +3 -1
- package/server/services/plan/parser-core.ts +406 -0
- package/server/services/plan/parser-migration.ts +128 -0
- package/server/services/plan/parser.ts +52 -620
- package/server/services/plan/review-gate.ts +4 -2
- package/server/services/plan/types.ts +2 -0
- package/server/services/platform-credentials.ts +83 -0
- package/server/services/platform.ts +15 -141
- package/server/services/terminal/pty-manager.ts +66 -313
- package/server/services/terminal/pty-utils.ts +176 -0
- package/server/services/websocket/file-definition-handlers.ts +165 -0
- package/server/services/websocket/file-explorer-handlers.ts +37 -452
- package/server/services/websocket/file-search-handlers.ts +291 -0
- package/server/services/websocket/file-utils.ts +3 -3
- package/server/services/websocket/git-branch-handlers.ts +130 -0
- package/server/services/websocket/git-diff-handlers.ts +140 -0
- package/server/services/websocket/git-handlers.ts +40 -625
- package/server/services/websocket/git-log-handlers.ts +149 -0
- package/server/services/websocket/git-pr-handlers.ts +17 -62
- package/server/services/websocket/git-tag-handlers.ts +91 -0
- package/server/services/websocket/git-utils.ts +230 -0
- package/server/services/websocket/handler.ts +39 -126
- package/server/services/websocket/plan-board-handlers.ts +277 -0
- package/server/services/websocket/plan-execution-handlers.ts +184 -0
- package/server/services/websocket/plan-handlers.ts +8 -1114
- package/server/services/websocket/plan-helpers.ts +215 -0
- package/server/services/websocket/plan-issue-handlers.ts +204 -0
- package/server/services/websocket/plan-sprint-handlers.ts +252 -0
- package/server/services/websocket/quality-complexity.ts +294 -0
- package/server/services/websocket/quality-fix-agent.ts +181 -0
- package/server/services/websocket/quality-handlers.ts +36 -404
- package/server/services/websocket/quality-linting.ts +187 -0
- package/server/services/websocket/quality-review-agent.ts +246 -0
- package/server/services/websocket/quality-service.ts +11 -762
- package/server/services/websocket/quality-tools.ts +209 -0
- package/server/services/websocket/quality-types.ts +169 -0
- package/server/services/websocket/session-handlers.ts +5 -437
- package/server/services/websocket/session-history.ts +222 -0
- package/server/services/websocket/session-initialization.ts +209 -0
- package/server/services/websocket/types.ts +17 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// Copyright (c) 2025-present Mstro, Inc. All rights reserved.
|
|
2
|
+
// Licensed under the MIT License. See LICENSE file for details.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Types and interfaces for the Improvisation Session Manager.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { HeadlessRunner } from './headless/index.js';
|
|
9
|
+
import type { ExecutionCheckpoint } from './headless/types.js';
|
|
10
|
+
|
|
11
|
+
export interface ImprovisationOptions {
|
|
12
|
+
workingDir: string;
|
|
13
|
+
sessionId: string;
|
|
14
|
+
tokenBudgetThreshold: number;
|
|
15
|
+
maxSessions: number;
|
|
16
|
+
verbose: boolean;
|
|
17
|
+
noColor: boolean;
|
|
18
|
+
/** Claude model for main execution (e.g., 'opus', 'sonnet'). 'default' = no --model flag. */
|
|
19
|
+
model?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// File attachment for multimodal prompts (images)
|
|
23
|
+
export interface FileAttachment {
|
|
24
|
+
fileName: string; // Display name (e.g., "screenshot.png")
|
|
25
|
+
filePath: string; // Full path on disk (for context)
|
|
26
|
+
content: string; // Base64 for images
|
|
27
|
+
isImage: boolean; // True for image files
|
|
28
|
+
mimeType?: string; // MIME type for images (e.g., "image/png")
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface ToolUseRecord {
|
|
32
|
+
toolName: string;
|
|
33
|
+
toolId: string;
|
|
34
|
+
toolInput: Record<string, unknown>;
|
|
35
|
+
result?: string;
|
|
36
|
+
isError?: boolean;
|
|
37
|
+
duration?: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface MovementRecord {
|
|
41
|
+
id: string;
|
|
42
|
+
sequenceNumber: number;
|
|
43
|
+
userPrompt: string;
|
|
44
|
+
timestamp: string;
|
|
45
|
+
tokensUsed: number;
|
|
46
|
+
summary: string;
|
|
47
|
+
filesModified: string[];
|
|
48
|
+
assistantResponse?: string;
|
|
49
|
+
thinkingOutput?: string;
|
|
50
|
+
toolUseHistory?: ToolUseRecord[];
|
|
51
|
+
errorOutput?: string;
|
|
52
|
+
durationMs?: number;
|
|
53
|
+
retryLog?: RetryLogEntry[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface SessionHistory {
|
|
57
|
+
sessionId: string;
|
|
58
|
+
startedAt: string;
|
|
59
|
+
lastActivityAt: string;
|
|
60
|
+
totalTokens: number;
|
|
61
|
+
movements: MovementRecord[];
|
|
62
|
+
claudeSessionId?: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Entry in the retry log for debugging recovery paths */
|
|
66
|
+
export interface RetryLogEntry {
|
|
67
|
+
retryNumber: number;
|
|
68
|
+
path: string;
|
|
69
|
+
reason: string;
|
|
70
|
+
timestamp: number;
|
|
71
|
+
durationMs?: number;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Mutable state for the retry loop in executePrompt */
|
|
75
|
+
export interface RetryLoopState {
|
|
76
|
+
currentPrompt: string;
|
|
77
|
+
retryNumber: number;
|
|
78
|
+
checkpointRef: { value: ExecutionCheckpoint | null };
|
|
79
|
+
contextRecoverySessionId: string | undefined;
|
|
80
|
+
freshRecoveryMode: boolean;
|
|
81
|
+
accumulatedToolResults: ToolUseRecord[];
|
|
82
|
+
contextLost: boolean;
|
|
83
|
+
lastWatchdogCheckpoint: ExecutionCheckpoint | null;
|
|
84
|
+
timedOutTools: Array<{ toolName: string; input: Record<string, unknown>; timeoutMs: number }>;
|
|
85
|
+
bestResult: HeadlessRunResult | null;
|
|
86
|
+
retryLog: RetryLogEntry[];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Type alias for HeadlessRunner execution result */
|
|
90
|
+
export type HeadlessRunResult = Awaited<ReturnType<HeadlessRunner['run']>>;
|
|
91
|
+
|
|
92
|
+
/** Score a run result for best-result tracking (higher = more productive) */
|
|
93
|
+
export function scoreRunResult(r: HeadlessRunResult): number {
|
|
94
|
+
const toolCount = r.toolUseHistory?.filter(t => t.result !== undefined && !t.isError).length ?? 0;
|
|
95
|
+
const responseLen = Math.min((r.assistantResponse?.length ?? 0) / 50, 100);
|
|
96
|
+
const hasThinking = r.thinkingOutput ? 20 : 0;
|
|
97
|
+
return toolCount * 10 + responseLen + hasThinking;
|
|
98
|
+
}
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt building and formatting utilities for improvisation sessions.
|
|
3
|
+
* Extracted from ImprovisationSessionManager for Single Responsibility.
|
|
4
|
+
*
|
|
5
|
+
* These are stateless formatting functions that take their inputs as parameters.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { ExecutionCheckpoint } from './headless/types.js';
|
|
9
|
+
import type { MovementRecord, ToolUseRecord } from './improvisation-session-manager.js';
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Formatting Utilities
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
/** Summarize a tool input for display in retry prompts */
|
|
16
|
+
export function summarizeToolInput(input: Record<string, unknown>): string {
|
|
17
|
+
if (input.url) return String(input.url).slice(0, 100);
|
|
18
|
+
if (input.query) return String(input.query).slice(0, 100);
|
|
19
|
+
if (input.command) return String(input.command).slice(0, 100);
|
|
20
|
+
if (input.prompt) return String(input.prompt).slice(0, 100);
|
|
21
|
+
return JSON.stringify(input).slice(0, 100);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Format a list of timed-out tools for retry prompts */
|
|
25
|
+
export function formatTimedOutTools(tools: Array<{ toolName: string; input: Record<string, unknown>; timeoutMs: number }>): string[] {
|
|
26
|
+
const lines: string[] = [];
|
|
27
|
+
lines.push('### Tools/resources that have timed out (DO NOT retry these):');
|
|
28
|
+
for (const t of tools) {
|
|
29
|
+
const inputSummary = summarizeToolInput(t.input);
|
|
30
|
+
lines.push(`- **${t.toolName}**(${inputSummary}) — timed out after ${Math.round(t.timeoutMs / 1000)}s`);
|
|
31
|
+
}
|
|
32
|
+
return lines;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Format completed checkpoint tools for retry prompts */
|
|
36
|
+
export function formatCompletedTools(tools: Array<{ toolName: string; input: Record<string, unknown>; result: string }>, maxLen = 2000): string[] {
|
|
37
|
+
const lines: string[] = [];
|
|
38
|
+
lines.push('### Results already obtained:');
|
|
39
|
+
for (const tool of tools) {
|
|
40
|
+
const inputSummary = summarizeToolInput(tool.input);
|
|
41
|
+
const preview = tool.result.length > maxLen ? `${tool.result.slice(0, maxLen)}...` : tool.result;
|
|
42
|
+
lines.push(`- **${tool.toolName}**(${inputSummary}): ${preview}`);
|
|
43
|
+
}
|
|
44
|
+
return lines;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Format in-progress tools for retry prompts */
|
|
48
|
+
export function formatInProgressTools(tools: Array<{ toolName: string; input: Record<string, unknown> }>): string[] {
|
|
49
|
+
const lines: string[] = [];
|
|
50
|
+
lines.push('### Tools that were still running (lost when process was killed):');
|
|
51
|
+
for (const tool of tools) {
|
|
52
|
+
const inputSummary = summarizeToolInput(tool.input);
|
|
53
|
+
lines.push(`- **${tool.toolName}**(${inputSummary}) — was in progress, may need re-running`);
|
|
54
|
+
}
|
|
55
|
+
return lines;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Format tool results from ToolUseRecord[] for recovery prompts */
|
|
59
|
+
export function formatToolResults(toolResults: ToolUseRecord[], maxLen = 3000): string[] {
|
|
60
|
+
const completed = toolResults.filter(t => t.result !== undefined && !t.isError);
|
|
61
|
+
if (completed.length === 0) return [];
|
|
62
|
+
const lines: string[] = [`### ${completed.length} preserved results from prior work:`, ''];
|
|
63
|
+
for (const tool of completed) {
|
|
64
|
+
const inputSummary = summarizeToolInput(tool.toolInput);
|
|
65
|
+
const preview = tool.result && tool.result.length > maxLen
|
|
66
|
+
? `${tool.result.slice(0, maxLen)}...\n(truncated, ${tool.result.length} chars total)`
|
|
67
|
+
: tool.result || '';
|
|
68
|
+
lines.push(`**${tool.toolName}**(${inputSummary}):`);
|
|
69
|
+
lines.push(preview);
|
|
70
|
+
lines.push('');
|
|
71
|
+
}
|
|
72
|
+
return lines;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Format conversation history for recovery prompts */
|
|
76
|
+
export function formatConversationHistory(movements: MovementRecord[], maxMovements = 5): string[] {
|
|
77
|
+
const recent = movements.slice(-maxMovements);
|
|
78
|
+
if (recent.length === 0) return [];
|
|
79
|
+
const lines: string[] = ['### Conversation so far:'];
|
|
80
|
+
for (const movement of recent) {
|
|
81
|
+
const promptText = movement.userPrompt.length > 300 ? `${movement.userPrompt.slice(0, 300)}...` : movement.userPrompt;
|
|
82
|
+
lines.push(`**User (prompt ${movement.sequenceNumber}):** ${promptText}`);
|
|
83
|
+
if (movement.assistantResponse) {
|
|
84
|
+
const response = movement.assistantResponse.length > 1000
|
|
85
|
+
? `${movement.assistantResponse.slice(0, 1000)}...\n(truncated, ${movement.assistantResponse.length} chars)`
|
|
86
|
+
: movement.assistantResponse;
|
|
87
|
+
lines.push(`**Your response:** ${response}`);
|
|
88
|
+
}
|
|
89
|
+
lines.push('');
|
|
90
|
+
}
|
|
91
|
+
return lines;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ============================================================================
|
|
95
|
+
// Prompt Builders
|
|
96
|
+
// ============================================================================
|
|
97
|
+
|
|
98
|
+
/** Build historical context from prior movements (for resumed sessions or first prompt with history) */
|
|
99
|
+
export function buildHistoricalContext(movements: MovementRecord[]): string {
|
|
100
|
+
if (movements.length === 0) {
|
|
101
|
+
return '';
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const contextParts: string[] = [
|
|
105
|
+
'--- CONVERSATION HISTORY (for context, do not repeat these responses) ---',
|
|
106
|
+
''
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
for (const movement of movements) {
|
|
110
|
+
contextParts.push(`[User Prompt ${movement.sequenceNumber}]:`);
|
|
111
|
+
contextParts.push(movement.userPrompt);
|
|
112
|
+
contextParts.push('');
|
|
113
|
+
|
|
114
|
+
if (movement.assistantResponse) {
|
|
115
|
+
contextParts.push(`[Your Response ${movement.sequenceNumber}]:`);
|
|
116
|
+
const response = movement.assistantResponse.length > 2000
|
|
117
|
+
? `${movement.assistantResponse.slice(0, 2000)}\n... (response truncated for context)`
|
|
118
|
+
: movement.assistantResponse;
|
|
119
|
+
contextParts.push(response);
|
|
120
|
+
contextParts.push('');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (movement.toolUseHistory && movement.toolUseHistory.length > 0) {
|
|
124
|
+
contextParts.push(`[Tools Used in Prompt ${movement.sequenceNumber}]:`);
|
|
125
|
+
for (const tool of movement.toolUseHistory) {
|
|
126
|
+
contextParts.push(`- ${tool.toolName}`);
|
|
127
|
+
}
|
|
128
|
+
contextParts.push('');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
contextParts.push('--- END OF CONVERSATION HISTORY ---');
|
|
133
|
+
contextParts.push('');
|
|
134
|
+
contextParts.push('Continue the conversation from where we left off. The user is now asking:');
|
|
135
|
+
contextParts.push('');
|
|
136
|
+
|
|
137
|
+
return contextParts.join('\n');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Build a retry prompt from a tool timeout checkpoint.
|
|
142
|
+
* Injects completed tool results and instructs Claude to skip the failed resource.
|
|
143
|
+
*/
|
|
144
|
+
export function buildRetryPrompt(
|
|
145
|
+
checkpoint: ExecutionCheckpoint,
|
|
146
|
+
originalPrompt: string,
|
|
147
|
+
allTimedOut?: Array<{ toolName: string; input: Record<string, unknown>; timeoutMs: number }>,
|
|
148
|
+
): string {
|
|
149
|
+
const urlSuffix = checkpoint.hungTool.url ? ` while fetching: ${checkpoint.hungTool.url}` : '';
|
|
150
|
+
const parts: string[] = [
|
|
151
|
+
'## AUTOMATIC RETRY -- Previous Execution Interrupted',
|
|
152
|
+
'',
|
|
153
|
+
`The previous execution was interrupted because ${checkpoint.hungTool.toolName} timed out after ${Math.round(checkpoint.hungTool.timeoutMs / 1000)}s${urlSuffix}.`,
|
|
154
|
+
'',
|
|
155
|
+
];
|
|
156
|
+
|
|
157
|
+
if (allTimedOut && allTimedOut.length > 0) {
|
|
158
|
+
parts.push(...formatTimedOutTools(allTimedOut), '');
|
|
159
|
+
} else {
|
|
160
|
+
parts.push('This URL/resource is unreachable. DO NOT retry the same URL or query.', '');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (checkpoint.completedTools.length > 0) {
|
|
164
|
+
parts.push(...formatCompletedTools(checkpoint.completedTools), '');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (checkpoint.inProgressTools && checkpoint.inProgressTools.length > 0) {
|
|
168
|
+
parts.push(...formatInProgressTools(checkpoint.inProgressTools), '');
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (checkpoint.assistantText) {
|
|
172
|
+
const preview = checkpoint.assistantText.length > 8000
|
|
173
|
+
? `${checkpoint.assistantText.slice(0, 8000)}...\n(truncated — full response was ${checkpoint.assistantText.length} chars)`
|
|
174
|
+
: checkpoint.assistantText;
|
|
175
|
+
parts.push('### Your response before interruption:', preview, '');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
parts.push('### Original task (continue from where you left off):');
|
|
179
|
+
parts.push(originalPrompt);
|
|
180
|
+
parts.push('');
|
|
181
|
+
parts.push('INSTRUCTIONS:');
|
|
182
|
+
parts.push('1. Use the results above -- do not re-fetch content you already have');
|
|
183
|
+
parts.push('2. Find ALTERNATIVE sources for the content that timed out (different URL, different approach)');
|
|
184
|
+
parts.push('3. Re-run any in-progress tools that were lost (listed above) if their results are needed');
|
|
185
|
+
parts.push('4. If no alternative exists, proceed with the results you have and note what was unavailable');
|
|
186
|
+
|
|
187
|
+
return parts.join('\n');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Build a short retry prompt for --resume sessions.
|
|
192
|
+
*/
|
|
193
|
+
export function buildResumeRetryPrompt(
|
|
194
|
+
checkpoint: ExecutionCheckpoint,
|
|
195
|
+
allTimedOut?: Array<{ toolName: string; input: Record<string, unknown>; timeoutMs: number }>,
|
|
196
|
+
): string {
|
|
197
|
+
const parts: string[] = [];
|
|
198
|
+
|
|
199
|
+
parts.push(
|
|
200
|
+
`Your previous ${checkpoint.hungTool.toolName} call timed out after ${Math.round(checkpoint.hungTool.timeoutMs / 1000)}s${checkpoint.hungTool.url ? ` fetching: ${checkpoint.hungTool.url}` : ''}.`
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
if (allTimedOut && allTimedOut.length > 1) {
|
|
204
|
+
parts.push('');
|
|
205
|
+
parts.push('All timed-out tools/resources (DO NOT retry any of these):');
|
|
206
|
+
for (const t of allTimedOut) {
|
|
207
|
+
const inputSummary = summarizeToolInput(t.input);
|
|
208
|
+
parts.push(`- ${t.toolName}(${inputSummary})`);
|
|
209
|
+
}
|
|
210
|
+
} else {
|
|
211
|
+
parts.push('This URL/resource is unreachable. DO NOT retry the same URL or query.');
|
|
212
|
+
}
|
|
213
|
+
parts.push('Continue your task — find an alternative source or proceed with the results you already have.');
|
|
214
|
+
|
|
215
|
+
return parts.join('\n');
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** Build a recovery prompt for --resume after context loss. */
|
|
219
|
+
export function buildContextRecoveryPrompt(originalPrompt: string): string {
|
|
220
|
+
const parts: string[] = [];
|
|
221
|
+
|
|
222
|
+
parts.push('Your previous response indicated you lost context due to tool timeouts, but your full conversation history is preserved — including all successful tool results.');
|
|
223
|
+
parts.push('');
|
|
224
|
+
parts.push('Review your conversation history above. You already have results from many successful tool calls. Use those results to continue the task.');
|
|
225
|
+
parts.push('');
|
|
226
|
+
parts.push('Original task:');
|
|
227
|
+
parts.push(originalPrompt);
|
|
228
|
+
parts.push('');
|
|
229
|
+
parts.push('INSTRUCTIONS:');
|
|
230
|
+
parts.push('1. Review your conversation history — all your previous tool results are still available');
|
|
231
|
+
parts.push('2. Continue from where you left off using the results you already gathered');
|
|
232
|
+
parts.push('3. If specific tool calls timed out, skip those and work with what you have');
|
|
233
|
+
parts.push('4. Do NOT start over — build on the work already done');
|
|
234
|
+
parts.push('5. Do NOT spawn Task subagents for work that previously timed out — do it inline instead');
|
|
235
|
+
parts.push('6. Prefer multiple small, focused tool calls over single large ones to avoid further timeouts');
|
|
236
|
+
|
|
237
|
+
return parts.join('\n');
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/** Build a recovery prompt for a fresh session after repeated context loss. */
|
|
241
|
+
export function buildFreshRecoveryPrompt(
|
|
242
|
+
originalPrompt: string,
|
|
243
|
+
toolResults: ToolUseRecord[],
|
|
244
|
+
timedOutTools?: Array<{ toolName: string; input: Record<string, unknown>; timeoutMs: number }>,
|
|
245
|
+
): string {
|
|
246
|
+
const parts: string[] = [
|
|
247
|
+
'## CONTINUING LONG-RUNNING TASK',
|
|
248
|
+
'',
|
|
249
|
+
'The previous execution encountered tool timeouts and lost context.',
|
|
250
|
+
'Below are all results gathered before the interruption. Continue the task using these results.',
|
|
251
|
+
'',
|
|
252
|
+
];
|
|
253
|
+
|
|
254
|
+
if (timedOutTools && timedOutTools.length > 0) {
|
|
255
|
+
parts.push(...formatTimedOutTools(timedOutTools), '');
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
parts.push(...formatToolResults(toolResults));
|
|
259
|
+
|
|
260
|
+
parts.push('### Original task:');
|
|
261
|
+
parts.push(originalPrompt);
|
|
262
|
+
parts.push('');
|
|
263
|
+
parts.push('INSTRUCTIONS:');
|
|
264
|
+
parts.push('1. Use the preserved results above — do NOT re-fetch data you already have');
|
|
265
|
+
parts.push('2. Continue the task from where it was interrupted');
|
|
266
|
+
parts.push('3. If you need additional data, fetch it (but try alternative sources if the original timed out)');
|
|
267
|
+
parts.push('4. Complete the original task fully');
|
|
268
|
+
parts.push('5. Do NOT spawn Task subagents for work that previously timed out — do it inline instead');
|
|
269
|
+
parts.push('6. Prefer multiple small, focused tool calls over single large ones to avoid further timeouts');
|
|
270
|
+
|
|
271
|
+
return parts.join('\n');
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/** Build a recovery prompt for inter-movement context loss. */
|
|
275
|
+
export function buildInterMovementRecoveryPrompt(
|
|
276
|
+
originalPrompt: string,
|
|
277
|
+
toolResults: ToolUseRecord[],
|
|
278
|
+
movements: MovementRecord[],
|
|
279
|
+
): string {
|
|
280
|
+
const parts: string[] = [
|
|
281
|
+
'## SESSION RECOVERY — Prior Session Expired',
|
|
282
|
+
'',
|
|
283
|
+
'Your previous session expired between prompts. Below is a summary of the conversation so far and all preserved tool results.',
|
|
284
|
+
'',
|
|
285
|
+
];
|
|
286
|
+
|
|
287
|
+
parts.push(...formatConversationHistory(movements));
|
|
288
|
+
parts.push(...formatToolResults(toolResults));
|
|
289
|
+
|
|
290
|
+
parts.push('### Current user prompt:');
|
|
291
|
+
parts.push(originalPrompt);
|
|
292
|
+
parts.push('');
|
|
293
|
+
parts.push('INSTRUCTIONS:');
|
|
294
|
+
parts.push('1. Use the preserved results above — do NOT re-fetch data you already have');
|
|
295
|
+
parts.push('2. Continue the conversation naturally based on the history above');
|
|
296
|
+
parts.push('3. If you need additional data, fetch it with small focused tool calls');
|
|
297
|
+
parts.push('4. Do NOT spawn Task subagents — do work inline to avoid further timeouts');
|
|
298
|
+
parts.push('5. Prefer multiple small, focused tool calls over single large ones');
|
|
299
|
+
|
|
300
|
+
return parts.join('\n');
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/** Build a recovery prompt after signal crash */
|
|
304
|
+
export function buildSignalCrashRecoveryPrompt(
|
|
305
|
+
originalPrompt: string,
|
|
306
|
+
isResume: boolean,
|
|
307
|
+
toolResults?: ToolUseRecord[],
|
|
308
|
+
): string {
|
|
309
|
+
const parts: string[] = [];
|
|
310
|
+
|
|
311
|
+
if (isResume) {
|
|
312
|
+
parts.push('Your previous execution was interrupted by a system signal (the process was killed externally).');
|
|
313
|
+
parts.push('Your full conversation history is preserved — including all successful tool results.');
|
|
314
|
+
parts.push('');
|
|
315
|
+
parts.push('Review your conversation history above and continue from where you left off.');
|
|
316
|
+
} else {
|
|
317
|
+
parts.push('## AUTOMATIC RETRY — Previous Execution Interrupted');
|
|
318
|
+
parts.push('');
|
|
319
|
+
parts.push('The previous execution was interrupted by a system signal (process killed).');
|
|
320
|
+
if (toolResults && toolResults.length > 0) {
|
|
321
|
+
parts.push(`${toolResults.length} tool results were preserved from prior work.`);
|
|
322
|
+
parts.push('');
|
|
323
|
+
parts.push('### Preserved results:');
|
|
324
|
+
for (const t of toolResults.slice(-20)) {
|
|
325
|
+
const inputSummary = JSON.stringify(t.toolInput).slice(0, 120);
|
|
326
|
+
const resultPreview = (t.result ?? '').slice(0, 200);
|
|
327
|
+
parts.push(`- **${t.toolName}**(${inputSummary}): ${resultPreview}`);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
parts.push('');
|
|
333
|
+
parts.push('### Original task:');
|
|
334
|
+
parts.push(originalPrompt);
|
|
335
|
+
parts.push('');
|
|
336
|
+
parts.push('INSTRUCTIONS:');
|
|
337
|
+
parts.push('1. Use the results above -- do not re-fetch content you already have');
|
|
338
|
+
parts.push('2. Continue from where you left off');
|
|
339
|
+
parts.push('3. Prefer multiple small, focused tool calls over single large ones');
|
|
340
|
+
parts.push('4. Do NOT spawn Task subagents — do work inline to avoid further interruptions');
|
|
341
|
+
|
|
342
|
+
return parts.join('\n');
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Extract tool results from movements.
|
|
347
|
+
* Used for recovery to provide context from prior work.
|
|
348
|
+
*/
|
|
349
|
+
export function extractHistoricalToolResults(movements: MovementRecord[], maxMovements = 3): ToolUseRecord[] {
|
|
350
|
+
const results: ToolUseRecord[] = [];
|
|
351
|
+
const recentMovements = movements.slice(-maxMovements);
|
|
352
|
+
|
|
353
|
+
for (const movement of recentMovements) {
|
|
354
|
+
if (!movement.toolUseHistory) continue;
|
|
355
|
+
for (const tool of movement.toolUseHistory) {
|
|
356
|
+
if (tool.result !== undefined && !tool.isError) {
|
|
357
|
+
results.push({
|
|
358
|
+
toolName: tool.toolName,
|
|
359
|
+
toolId: tool.toolId,
|
|
360
|
+
toolInput: tool.toolInput,
|
|
361
|
+
result: tool.result,
|
|
362
|
+
isError: tool.isError,
|
|
363
|
+
duration: tool.duration,
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return results;
|
|
370
|
+
}
|