mstro-app 0.2.0 → 0.3.0
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/PRIVACY.md +126 -0
- package/README.md +24 -23
- package/bin/commands/login.js +79 -49
- package/bin/mstro.js +240 -37
- package/dist/server/cli/headless/claude-invoker.d.ts.map +1 -1
- package/dist/server/cli/headless/claude-invoker.js +133 -27
- package/dist/server/cli/headless/claude-invoker.js.map +1 -1
- package/dist/server/cli/headless/runner.d.ts.map +1 -1
- package/dist/server/cli/headless/runner.js +23 -0
- package/dist/server/cli/headless/runner.js.map +1 -1
- package/dist/server/cli/headless/stall-assessor.d.ts +3 -1
- package/dist/server/cli/headless/stall-assessor.d.ts.map +1 -1
- package/dist/server/cli/headless/stall-assessor.js +20 -1
- package/dist/server/cli/headless/stall-assessor.js.map +1 -1
- package/dist/server/cli/headless/tool-watchdog.d.ts +4 -1
- package/dist/server/cli/headless/tool-watchdog.d.ts.map +1 -1
- package/dist/server/cli/headless/tool-watchdog.js +30 -24
- package/dist/server/cli/headless/tool-watchdog.js.map +1 -1
- package/dist/server/cli/headless/types.d.ts +19 -1
- package/dist/server/cli/headless/types.d.ts.map +1 -1
- package/dist/server/cli/improvisation-session-manager.d.ts +28 -1
- package/dist/server/cli/improvisation-session-manager.d.ts.map +1 -1
- package/dist/server/cli/improvisation-session-manager.js +221 -29
- package/dist/server/cli/improvisation-session-manager.js.map +1 -1
- package/dist/server/index.js +0 -3
- package/dist/server/index.js.map +1 -1
- package/dist/server/services/analytics.d.ts.map +1 -1
- package/dist/server/services/analytics.js +13 -1
- package/dist/server/services/analytics.js.map +1 -1
- package/dist/server/services/platform.d.ts.map +1 -1
- package/dist/server/services/platform.js +13 -1
- package/dist/server/services/platform.js.map +1 -1
- package/dist/server/services/terminal/pty-manager.d.ts +2 -0
- package/dist/server/services/terminal/pty-manager.d.ts.map +1 -1
- package/dist/server/services/terminal/pty-manager.js +50 -3
- package/dist/server/services/terminal/pty-manager.js.map +1 -1
- package/dist/server/services/websocket/file-explorer-handlers.d.ts +5 -0
- package/dist/server/services/websocket/file-explorer-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/file-explorer-handlers.js +518 -0
- package/dist/server/services/websocket/file-explorer-handlers.js.map +1 -0
- package/dist/server/services/websocket/git-handlers.d.ts +36 -0
- package/dist/server/services/websocket/git-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/git-handlers.js +797 -0
- package/dist/server/services/websocket/git-handlers.js.map +1 -0
- package/dist/server/services/websocket/git-pr-handlers.d.ts +4 -0
- package/dist/server/services/websocket/git-pr-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/git-pr-handlers.js +299 -0
- package/dist/server/services/websocket/git-pr-handlers.js.map +1 -0
- package/dist/server/services/websocket/git-worktree-handlers.d.ts +4 -0
- package/dist/server/services/websocket/git-worktree-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/git-worktree-handlers.js +353 -0
- package/dist/server/services/websocket/git-worktree-handlers.js.map +1 -0
- package/dist/server/services/websocket/handler-context.d.ts +32 -0
- package/dist/server/services/websocket/handler-context.d.ts.map +1 -0
- package/dist/server/services/websocket/handler-context.js +4 -0
- package/dist/server/services/websocket/handler-context.js.map +1 -0
- package/dist/server/services/websocket/handler.d.ts +27 -359
- package/dist/server/services/websocket/handler.d.ts.map +1 -1
- package/dist/server/services/websocket/handler.js +67 -2328
- package/dist/server/services/websocket/handler.js.map +1 -1
- package/dist/server/services/websocket/index.d.ts +1 -1
- package/dist/server/services/websocket/index.d.ts.map +1 -1
- package/dist/server/services/websocket/index.js.map +1 -1
- package/dist/server/services/websocket/session-handlers.d.ts +10 -0
- package/dist/server/services/websocket/session-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/session-handlers.js +507 -0
- package/dist/server/services/websocket/session-handlers.js.map +1 -0
- package/dist/server/services/websocket/settings-handlers.d.ts +6 -0
- package/dist/server/services/websocket/settings-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/settings-handlers.js +125 -0
- package/dist/server/services/websocket/settings-handlers.js.map +1 -0
- package/dist/server/services/websocket/tab-handlers.d.ts +10 -0
- package/dist/server/services/websocket/tab-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/tab-handlers.js +131 -0
- package/dist/server/services/websocket/tab-handlers.js.map +1 -0
- package/dist/server/services/websocket/terminal-handlers.d.ts +9 -0
- package/dist/server/services/websocket/terminal-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/terminal-handlers.js +220 -0
- package/dist/server/services/websocket/terminal-handlers.js.map +1 -0
- package/dist/server/services/websocket/types.d.ts +63 -2
- package/dist/server/services/websocket/types.d.ts.map +1 -1
- package/package.json +4 -2
- package/server/README.md +176 -159
- package/server/cli/headless/claude-invoker.ts +155 -31
- package/server/cli/headless/output-utils.test.ts +225 -0
- package/server/cli/headless/runner.ts +25 -0
- package/server/cli/headless/stall-assessor.test.ts +165 -0
- package/server/cli/headless/stall-assessor.ts +25 -0
- package/server/cli/headless/tool-watchdog.test.ts +429 -0
- package/server/cli/headless/tool-watchdog.ts +33 -25
- package/server/cli/headless/types.ts +10 -1
- package/server/cli/improvisation-session-manager.ts +277 -30
- package/server/index.ts +0 -4
- package/server/mcp/README.md +59 -67
- package/server/mcp/bouncer-integration.test.ts +161 -0
- package/server/mcp/security-patterns.test.ts +258 -0
- package/server/services/analytics.ts +13 -1
- package/server/services/platform.ts +12 -1
- package/server/services/terminal/pty-manager.ts +53 -3
- package/server/services/websocket/autocomplete.test.ts +194 -0
- package/server/services/websocket/file-explorer-handlers.ts +587 -0
- package/server/services/websocket/git-handlers.ts +924 -0
- package/server/services/websocket/git-pr-handlers.ts +363 -0
- package/server/services/websocket/git-worktree-handlers.ts +403 -0
- package/server/services/websocket/handler-context.ts +44 -0
- package/server/services/websocket/handler.test.ts +1 -1
- package/server/services/websocket/handler.ts +83 -2678
- package/server/services/websocket/index.ts +1 -1
- package/server/services/websocket/session-handlers.ts +574 -0
- package/server/services/websocket/settings-handlers.ts +150 -0
- package/server/services/websocket/tab-handlers.ts +150 -0
- package/server/services/websocket/terminal-handlers.ts +277 -0
- package/server/services/websocket/types.ts +135 -0
- package/bin/release.sh +0 -110
|
@@ -86,6 +86,11 @@ export interface HeadlessConfig {
|
|
|
86
86
|
outputCallback?: (text: string) => void;
|
|
87
87
|
thinkingCallback?: (text: string) => void;
|
|
88
88
|
toolUseCallback?: (event: ToolUseEvent) => void;
|
|
89
|
+
/** Called with cumulative API token counts as they arrive from the stream */
|
|
90
|
+
tokenUsageCallback?: (usage: {
|
|
91
|
+
inputTokens: number;
|
|
92
|
+
outputTokens: number;
|
|
93
|
+
}) => void;
|
|
89
94
|
directPrompt?: string;
|
|
90
95
|
promptContext?: PromptContext;
|
|
91
96
|
continueSession?: boolean;
|
|
@@ -124,6 +129,8 @@ export interface SessionResult {
|
|
|
124
129
|
totalTokens: number;
|
|
125
130
|
sessionId: string;
|
|
126
131
|
error?: string;
|
|
132
|
+
/** Signal name if Claude process was killed (e.g., 'SIGTERM', 'SIGKILL') */
|
|
133
|
+
signalName?: string;
|
|
127
134
|
conflicts?: Array<{
|
|
128
135
|
filePath: string;
|
|
129
136
|
modifiedBy: string[];
|
|
@@ -164,6 +171,8 @@ export interface ExecutionResult {
|
|
|
164
171
|
output: string;
|
|
165
172
|
error?: string;
|
|
166
173
|
exitCode: number;
|
|
174
|
+
/** Signal name if process was killed (e.g., 'SIGTERM', 'SIGKILL') */
|
|
175
|
+
signalName?: string;
|
|
167
176
|
assistantResponse?: string;
|
|
168
177
|
thinkingOutput?: string;
|
|
169
178
|
toolUseHistory?: ToolUseAccumulator[];
|
|
@@ -176,12 +185,21 @@ export interface ExecutionResult {
|
|
|
176
185
|
/** Assistant text buffered during resume assessment — held back until thinking/tool activity
|
|
177
186
|
* confirms Claude has context. Undefined when not in resume mode or buffer was flushed. */
|
|
178
187
|
resumeBufferedOutput?: string;
|
|
188
|
+
/** Actual API token usage from Claude Code stream events (summed across all turns) */
|
|
189
|
+
apiTokenUsage?: {
|
|
190
|
+
inputTokens: number;
|
|
191
|
+
outputTokens: number;
|
|
192
|
+
};
|
|
179
193
|
}
|
|
180
194
|
/** Resolved config with all defaults applied */
|
|
181
|
-
export type ResolvedHeadlessConfig = Omit<Required<HeadlessConfig>, 'outputCallback' | 'thinkingCallback' | 'toolUseCallback' | 'continueSession' | 'claudeSessionId' | 'imageAttachments' | 'model' | 'toolTimeoutProfiles' | 'onToolTimeout' | 'sandboxed'> & {
|
|
195
|
+
export type ResolvedHeadlessConfig = Omit<Required<HeadlessConfig>, 'outputCallback' | 'thinkingCallback' | 'toolUseCallback' | 'tokenUsageCallback' | 'continueSession' | 'claudeSessionId' | 'imageAttachments' | 'model' | 'toolTimeoutProfiles' | 'onToolTimeout' | 'sandboxed'> & {
|
|
182
196
|
outputCallback?: (text: string) => void;
|
|
183
197
|
thinkingCallback?: (text: string) => void;
|
|
184
198
|
toolUseCallback?: (event: ToolUseEvent) => void;
|
|
199
|
+
tokenUsageCallback?: (usage: {
|
|
200
|
+
inputTokens: number;
|
|
201
|
+
outputTokens: number;
|
|
202
|
+
}) => void;
|
|
185
203
|
continueSession?: boolean;
|
|
186
204
|
claudeSessionId?: string;
|
|
187
205
|
imageAttachments?: ImageAttachment[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../server/cli/headless/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../server/cli/headless/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -43,6 +43,7 @@ export interface MovementRecord {
|
|
|
43
43
|
toolUseHistory?: ToolUseRecord[];
|
|
44
44
|
errorOutput?: string;
|
|
45
45
|
durationMs?: number;
|
|
46
|
+
retryLog?: RetryLogEntry[];
|
|
46
47
|
}
|
|
47
48
|
export interface SessionHistory {
|
|
48
49
|
sessionId: string;
|
|
@@ -52,6 +53,14 @@ export interface SessionHistory {
|
|
|
52
53
|
movements: MovementRecord[];
|
|
53
54
|
claudeSessionId?: string;
|
|
54
55
|
}
|
|
56
|
+
/** Entry in the retry log for debugging recovery paths */
|
|
57
|
+
interface RetryLogEntry {
|
|
58
|
+
retryNumber: number;
|
|
59
|
+
path: string;
|
|
60
|
+
reason: string;
|
|
61
|
+
timestamp: number;
|
|
62
|
+
durationMs?: number;
|
|
63
|
+
}
|
|
55
64
|
export declare class ImprovisationSessionManager extends EventEmitter {
|
|
56
65
|
private sessionId;
|
|
57
66
|
private improviseDir;
|
|
@@ -72,6 +81,8 @@ export declare class ImprovisationSessionManager extends EventEmitter {
|
|
|
72
81
|
private _executionStartTimestamp;
|
|
73
82
|
/** Buffered events during current execution, for replay on reconnect */
|
|
74
83
|
private executionEventLog;
|
|
84
|
+
/** Set by cancel() to signal the retry loop to exit */
|
|
85
|
+
private _cancelled;
|
|
75
86
|
/**
|
|
76
87
|
* Resume from a historical session.
|
|
77
88
|
* Creates a new session manager that continues the conversation from a previous session.
|
|
@@ -113,7 +124,10 @@ export declare class ImprovisationSessionManager extends EventEmitter {
|
|
|
113
124
|
*/
|
|
114
125
|
executePrompt(userPrompt: string, attachments?: FileAttachment[], options?: {
|
|
115
126
|
sandboxed?: boolean;
|
|
127
|
+
workingDir?: string;
|
|
116
128
|
}): Promise<MovementRecord>;
|
|
129
|
+
private handleCancelledExecution;
|
|
130
|
+
private runRetryLoop;
|
|
117
131
|
/** Prepare prompt with attachments and limit image count */
|
|
118
132
|
private preparePromptAndAttachments;
|
|
119
133
|
/** Determine whether to use --resume and which session ID */
|
|
@@ -132,7 +146,10 @@ export declare class ImprovisationSessionManager extends EventEmitter {
|
|
|
132
146
|
private flushPostTimeoutOutput;
|
|
133
147
|
/** Check if context loss recovery should trigger a retry. Returns true if loop should continue. */
|
|
134
148
|
private shouldRetryContextLoss;
|
|
135
|
-
/** Accumulate completed tool results from a run into the retry state
|
|
149
|
+
/** Accumulate completed tool results from a run into the retry state.
|
|
150
|
+
* Caps at MAX_ACCUMULATED_RESULTS to prevent recovery prompts from exceeding context limits.
|
|
151
|
+
* When the cap is reached, older results are evicted (FIFO) to make room for newer ones. */
|
|
152
|
+
private static readonly MAX_ACCUMULATED_RESULTS;
|
|
136
153
|
private accumulateToolResults;
|
|
137
154
|
/** Handle inter-movement context loss recovery (resume session expired) */
|
|
138
155
|
private applyInterMovementRecovery;
|
|
@@ -140,6 +157,15 @@ export declare class ImprovisationSessionManager extends EventEmitter {
|
|
|
140
157
|
private applyNativeTimeoutRecovery;
|
|
141
158
|
/** Handle tool timeout checkpoint. Returns true if loop should continue. */
|
|
142
159
|
private applyToolTimeoutRetry;
|
|
160
|
+
/**
|
|
161
|
+
* Detect and retry after a signal crash (e.g., SIGTERM exit code 143).
|
|
162
|
+
* When the Claude process is killed externally (OOM, system signal, internal timeout
|
|
163
|
+
* that bypasses our watchdog), no existing recovery path catches it because contextLost
|
|
164
|
+
* is never set and no checkpoint is created. This adds a dedicated recovery path.
|
|
165
|
+
*/
|
|
166
|
+
private shouldRetrySignalCrash;
|
|
167
|
+
/** Build a recovery prompt after signal crash */
|
|
168
|
+
private buildSignalCrashRecoveryPrompt;
|
|
143
169
|
/** Select the best result across retries using Haiku assessment */
|
|
144
170
|
private selectBestResult;
|
|
145
171
|
/** Fallback best result selection using numeric scoring */
|
|
@@ -278,4 +304,5 @@ export declare class ImprovisationSessionManager extends EventEmitter {
|
|
|
278
304
|
*/
|
|
279
305
|
startNewSession(overrides?: Partial<ImprovisationOptions>): ImprovisationSessionManager;
|
|
280
306
|
}
|
|
307
|
+
export {};
|
|
281
308
|
//# sourceMappingURL=improvisation-session-manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"improvisation-session-manager.d.ts","sourceRoot":"","sources":["../../../server/cli/improvisation-session-manager.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQ3C,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,6FAA6F;IAC7F,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAGD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,EAAE,CAAC;IAExB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"improvisation-session-manager.d.ts","sourceRoot":"","sources":["../../../server/cli/improvisation-session-manager.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQ3C,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,6FAA6F;IAC7F,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAGD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,EAAE,CAAC;IAExB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAGD,0DAA0D;AAC1D,UAAU,aAAa;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA2BD,qBAAa,2BAA4B,SAAQ,YAAY;IAC3D,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,eAAe,CAAC,CAGtB;IACF,OAAO,CAAC,WAAW,CAAkD;IACrE,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,gBAAgB,CAAkB;IAC1C,oBAAoB,EAAE,MAAM,CAAM;IAElC,8CAA8C;IAC9C,OAAO,CAAC,YAAY,CAAkB;IACtC,6FAA6F;IAC7F,OAAO,CAAC,wBAAwB,CAAqB;IACrD,wEAAwE;IACxE,OAAO,CAAC,iBAAiB,CAA6D;IACtF,uDAAuD;IACvD,OAAO,CAAC,UAAU,CAAkB;IAEpC;;;;OAIG;IACH,MAAM,CAAC,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG,2BAA2B;gBA2CrI,OAAO,GAAE,OAAO,CAAC,oBAAoB,CAAM;IA6BvD;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IASxB;;;OAGG;IACH,OAAO,CAAC,0BAA0B;IA2BlC;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAuB1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAY1B;;;;;OAKG;IACG,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,cAAc,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC;IAwFxJ,OAAO,CAAC,wBAAwB;YAuClB,YAAY;IAwC1B,4DAA4D;IAC5D,OAAO,CAAC,2BAA2B;IAqBnC,6DAA6D;IAC7D,OAAO,CAAC,uBAAuB;IAmB/B,oDAAoD;IACpD,OAAO,CAAC,qBAAqB;IAkD7B,iFAAiF;IACjF,OAAO,CAAC,mBAAmB;IAM3B,kCAAkC;IAClC,OAAO,CAAC,gBAAgB;IAMxB,uEAAuE;IACvE,OAAO,CAAC,uBAAuB;IA0B/B,kFAAkF;YACpE,8BAA8B;IA2C5C,uDAAuD;IACvD,OAAO,CAAC,sBAAsB;IAO9B,mGAAmG;IACnG,OAAO,CAAC,sBAAsB;IA4B9B;;iGAE6F;IAC7F,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAM;IAErD,OAAO,CAAC,qBAAqB;IAqB7B,2EAA2E;IAC3E,OAAO,CAAC,0BAA0B;IAsBlC,mFAAmF;IACnF,OAAO,CAAC,0BAA0B;IAgClC,4EAA4E;IAC5E,OAAO,CAAC,qBAAqB;IAsD7B;;;;;OAKG;IACH,OAAO,CAAC,sBAAsB;IAyE9B,iDAAiD;IACjD,OAAO,CAAC,8BAA8B;IAyCtC,mEAAmE;YACrD,gBAAgB;IAyC9B,2DAA2D;IAC3D,OAAO,CAAC,kBAAkB;IAU1B,0DAA0D;IAC1D,OAAO,CAAC,oBAAoB;IAK5B,+DAA+D;IAC/D,OAAO,CAAC,8BAA8B;IAWtC,mDAAmD;IACnD,OAAO,CAAC,mBAAmB;IA+B3B,kDAAkD;IAClD,OAAO,CAAC,eAAe;IAYvB,kCAAkC;IAClC,OAAO,CAAC,eAAe;IAMvB,oDAAoD;IACpD,OAAO,CAAC,oBAAoB;IAiB5B;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IA2C9B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IA8CxB;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IA6B9B;;;;OAIG;IACH,OAAO,CAAC,0BAA0B;IAqBlC;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAiChC;;;;OAIG;IACH,OAAO,CAAC,4BAA4B;IAuBpC;;;;OAIG;IACH,OAAO,CAAC,gCAAgC;IAwBxC,0DAA0D;IAC1D,OAAO,CAAC,kBAAkB;IAQ1B,yDAAyD;IACzD,OAAO,CAAC,mBAAmB;IAU3B,0DAA0D;IAC1D,OAAO,CAAC,oBAAoB;IAW5B,iDAAiD;IACjD,OAAO,CAAC,qBAAqB;IAU7B,oEAAoE;IACpE,OAAO,CAAC,iBAAiB;IAgBzB,uDAAuD;IACvD,OAAO,CAAC,yBAAyB;IAkBjC;;OAEG;IACH,OAAO,CAAC,WAAW;IAmBnB;;OAEG;IACH,OAAO,CAAC,WAAW;IAKnB;;OAEG;IACH,UAAU,IAAI,cAAc;IAI5B;;OAEG;IACH,MAAM,IAAI,IAAI;IAUd;;OAEG;IACH,OAAO,IAAI,IAAI;IAQf;;;OAGG;IACH,YAAY,IAAI,IAAI;IAWpB;;;OAGG;IACG,eAAe,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC;IAOlD;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAO1C;;OAEG;IACH,cAAc;;;;;;;;IAWd;;OAEG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;OAEG;IACH,IAAI,uBAAuB,IAAI,MAAM,GAAG,SAAS,CAEhD;IAED;;;OAGG;IACH,oBAAoB,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,GAAG,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAI7E;;;;OAIG;IACH,eAAe,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG,2BAA2B;CAgBxF"}
|
|
@@ -39,6 +39,8 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
39
39
|
_executionStartTimestamp;
|
|
40
40
|
/** Buffered events during current execution, for replay on reconnect */
|
|
41
41
|
executionEventLog = [];
|
|
42
|
+
/** Set by cancel() to signal the retry loop to exit */
|
|
43
|
+
_cancelled = false;
|
|
42
44
|
/**
|
|
43
45
|
* Resume from a historical session.
|
|
44
46
|
* Creates a new session manager that continues the conversation from a previous session.
|
|
@@ -199,6 +201,7 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
199
201
|
async executePrompt(userPrompt, attachments, options) {
|
|
200
202
|
const _execStart = Date.now();
|
|
201
203
|
this._isExecuting = true;
|
|
204
|
+
this._cancelled = false;
|
|
202
205
|
this._executionStartTimestamp = _execStart;
|
|
203
206
|
this.executionEventLog = [];
|
|
204
207
|
const sequenceNumber = this.history.movements.length + 1;
|
|
@@ -230,34 +233,21 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
230
233
|
lastWatchdogCheckpoint: null,
|
|
231
234
|
timedOutTools: [],
|
|
232
235
|
bestResult: null,
|
|
236
|
+
retryLog: [],
|
|
233
237
|
};
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
this.resetIterationState(state);
|
|
239
|
-
const { useResume, resumeSessionId } = this.determineResumeStrategy(state);
|
|
240
|
-
const runner = this.createExecutionRunner(state, sequenceNumber, useResume, resumeSessionId, imageAttachments, options?.sandboxed);
|
|
241
|
-
this.currentRunner = runner;
|
|
242
|
-
result = await runner.run();
|
|
243
|
-
this.currentRunner = null;
|
|
244
|
-
this.updateBestResult(state, result);
|
|
245
|
-
const nativeTimeouts = result.nativeTimeoutCount ?? 0;
|
|
246
|
-
this.detectResumeContextLoss(result, state, useResume, maxRetries, nativeTimeouts);
|
|
247
|
-
await this.detectNativeTimeoutContextLoss(result, state, maxRetries, nativeTimeouts);
|
|
248
|
-
this.flushPostTimeoutOutput(result, state);
|
|
249
|
-
if (this.shouldRetryContextLoss(result, state, useResume, nativeTimeouts, maxRetries, promptWithAttachments))
|
|
250
|
-
continue;
|
|
251
|
-
if (this.applyToolTimeoutRetry(state, maxRetries, promptWithAttachments))
|
|
252
|
-
continue;
|
|
253
|
-
break;
|
|
238
|
+
let result = await this.runRetryLoop(state, sequenceNumber, promptWithAttachments, imageAttachments, options?.sandboxed, options?.workingDir);
|
|
239
|
+
// If cancelled, emit a minimal movement and return early
|
|
240
|
+
if (this._cancelled) {
|
|
241
|
+
return this.handleCancelledExecution(result, userPrompt, sequenceNumber, _execStart);
|
|
254
242
|
}
|
|
255
243
|
if (state.contextLost)
|
|
256
244
|
this.claudeSessionId = undefined;
|
|
245
|
+
// result is guaranteed assigned here: the loop always runs at least once (if _cancelled was
|
|
246
|
+
// true before the loop, we returned in the block above; otherwise runner.run() assigned it).
|
|
257
247
|
result = await this.selectBestResult(state, result, userPrompt);
|
|
258
248
|
this.captureSessionAndSurfaceErrors(result);
|
|
259
249
|
this.isFirstPrompt = false;
|
|
260
|
-
const movement = this.buildMovementRecord(result, userPrompt, sequenceNumber, _execStart);
|
|
250
|
+
const movement = this.buildMovementRecord(result, userPrompt, sequenceNumber, _execStart, state.retryLog);
|
|
261
251
|
this.handleConflicts(result);
|
|
262
252
|
this.persistMovement(movement);
|
|
263
253
|
this._isExecuting = false;
|
|
@@ -287,6 +277,70 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
287
277
|
}
|
|
288
278
|
}
|
|
289
279
|
// ========== Extracted helpers for executePrompt ==========
|
|
280
|
+
handleCancelledExecution(result, userPrompt, sequenceNumber, execStart) {
|
|
281
|
+
this._isExecuting = false;
|
|
282
|
+
this._executionStartTimestamp = undefined;
|
|
283
|
+
this.executionEventLog = [];
|
|
284
|
+
this.currentRunner = null;
|
|
285
|
+
const cancelledMovement = {
|
|
286
|
+
id: `prompt-${sequenceNumber}`,
|
|
287
|
+
sequenceNumber,
|
|
288
|
+
userPrompt,
|
|
289
|
+
timestamp: new Date().toISOString(),
|
|
290
|
+
tokensUsed: result ? result.totalTokens : 0,
|
|
291
|
+
summary: '',
|
|
292
|
+
filesModified: [],
|
|
293
|
+
assistantResponse: result?.assistantResponse,
|
|
294
|
+
thinkingOutput: result?.thinkingOutput,
|
|
295
|
+
toolUseHistory: result?.toolUseHistory?.map(t => ({
|
|
296
|
+
toolName: t.toolName,
|
|
297
|
+
toolId: t.toolId,
|
|
298
|
+
toolInput: t.toolInput,
|
|
299
|
+
result: t.result,
|
|
300
|
+
})),
|
|
301
|
+
errorOutput: 'Execution cancelled by user',
|
|
302
|
+
durationMs: Date.now() - execStart,
|
|
303
|
+
};
|
|
304
|
+
this.persistMovement(cancelledMovement);
|
|
305
|
+
const fallbackResult = {
|
|
306
|
+
completed: false, needsHandoff: false, totalTokens: 0, sessionId: '',
|
|
307
|
+
output: '', exitCode: 1, signalName: 'SIGTERM',
|
|
308
|
+
};
|
|
309
|
+
this.emitMovementComplete(cancelledMovement, result ?? fallbackResult, execStart, sequenceNumber);
|
|
310
|
+
return cancelledMovement;
|
|
311
|
+
}
|
|
312
|
+
async runRetryLoop(state, sequenceNumber, promptWithAttachments, imageAttachments, sandboxed, workingDirOverride) {
|
|
313
|
+
const maxRetries = 3;
|
|
314
|
+
let result;
|
|
315
|
+
// eslint-disable-next-line no-constant-condition
|
|
316
|
+
while (true) {
|
|
317
|
+
if (this._cancelled)
|
|
318
|
+
break;
|
|
319
|
+
this.resetIterationState(state);
|
|
320
|
+
const { useResume, resumeSessionId } = this.determineResumeStrategy(state);
|
|
321
|
+
const runner = this.createExecutionRunner(state, sequenceNumber, useResume, resumeSessionId, imageAttachments, sandboxed, workingDirOverride);
|
|
322
|
+
this.currentRunner = runner;
|
|
323
|
+
result = await runner.run();
|
|
324
|
+
this.currentRunner = null;
|
|
325
|
+
if (this._cancelled)
|
|
326
|
+
break;
|
|
327
|
+
this.updateBestResult(state, result);
|
|
328
|
+
const nativeTimeouts = result.nativeTimeoutCount ?? 0;
|
|
329
|
+
this.detectResumeContextLoss(result, state, useResume, maxRetries, nativeTimeouts);
|
|
330
|
+
await this.detectNativeTimeoutContextLoss(result, state, maxRetries, nativeTimeouts);
|
|
331
|
+
this.flushPostTimeoutOutput(result, state);
|
|
332
|
+
// Signal crashes checked first: they use --resume (lighter), and context loss
|
|
333
|
+
// recovery would clear the session ID, preventing future --resume attempts.
|
|
334
|
+
if (this.shouldRetrySignalCrash(result, state, maxRetries, promptWithAttachments))
|
|
335
|
+
continue;
|
|
336
|
+
if (this.shouldRetryContextLoss(result, state, useResume, nativeTimeouts, maxRetries, promptWithAttachments))
|
|
337
|
+
continue;
|
|
338
|
+
if (this.applyToolTimeoutRetry(state, maxRetries, promptWithAttachments))
|
|
339
|
+
continue;
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
return result;
|
|
343
|
+
}
|
|
290
344
|
/** Prepare prompt with attachments and limit image count */
|
|
291
345
|
preparePromptAndAttachments(userPrompt, attachments) {
|
|
292
346
|
const diskPaths = attachments ? this.persistAttachments(attachments) : [];
|
|
@@ -321,9 +375,9 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
321
375
|
return { useResume: false, resumeSessionId: undefined };
|
|
322
376
|
}
|
|
323
377
|
/** Create HeadlessRunner for one retry iteration */
|
|
324
|
-
createExecutionRunner(state, sequenceNumber, useResume, resumeSessionId, imageAttachments, sandboxed) {
|
|
378
|
+
createExecutionRunner(state, sequenceNumber, useResume, resumeSessionId, imageAttachments, sandboxed, workingDirOverride) {
|
|
325
379
|
return new HeadlessRunner({
|
|
326
|
-
workingDir: this.options.workingDir,
|
|
380
|
+
workingDir: workingDirOverride || this.options.workingDir,
|
|
327
381
|
tokenBudgetThreshold: this.options.tokenBudgetThreshold,
|
|
328
382
|
maxSessions: this.options.maxSessions,
|
|
329
383
|
verbose: this.options.verbose,
|
|
@@ -348,6 +402,9 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
348
402
|
this.emit('onToolUse', event);
|
|
349
403
|
this.flushOutputQueue();
|
|
350
404
|
},
|
|
405
|
+
tokenUsageCallback: (usage) => {
|
|
406
|
+
this.emit('onTokenUsage', usage);
|
|
407
|
+
},
|
|
351
408
|
directPrompt: state.currentPrompt,
|
|
352
409
|
imageAttachments,
|
|
353
410
|
promptContext: (state.retryNumber === 0 && this.isResumedSession && this.isFirstPrompt)
|
|
@@ -399,7 +456,16 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
399
456
|
async detectNativeTimeoutContextLoss(result, state, maxRetries, nativeTimeouts) {
|
|
400
457
|
if (state.contextLost)
|
|
401
458
|
return;
|
|
402
|
-
|
|
459
|
+
// Deduplicate by toolId: if a toolId has at least one entry with a result,
|
|
460
|
+
// its orphaned duplicates are Claude Code internal retries, not actual timeouts.
|
|
461
|
+
const succeededIds = new Set();
|
|
462
|
+
const allIds = new Set();
|
|
463
|
+
for (const t of result.toolUseHistory ?? []) {
|
|
464
|
+
allIds.add(t.toolId);
|
|
465
|
+
if (t.result !== undefined)
|
|
466
|
+
succeededIds.add(t.toolId);
|
|
467
|
+
}
|
|
468
|
+
const toolsWithoutResult = [...allIds].filter(id => !succeededIds.has(id)).length;
|
|
403
469
|
const effectiveTimeouts = Math.max(nativeTimeouts, toolsWithoutResult);
|
|
404
470
|
if (effectiveTimeouts === 0 || !result.assistantResponse || state.checkpointRef.value || state.retryNumber >= maxRetries) {
|
|
405
471
|
return;
|
|
@@ -434,6 +500,13 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
434
500
|
}
|
|
435
501
|
this.accumulateToolResults(result, state);
|
|
436
502
|
state.retryNumber++;
|
|
503
|
+
const path = (useResume && nativeTimeouts === 0) ? 'InterMovementRecovery' : 'NativeTimeoutRecovery';
|
|
504
|
+
state.retryLog.push({
|
|
505
|
+
retryNumber: state.retryNumber,
|
|
506
|
+
path,
|
|
507
|
+
reason: `Context lost (${nativeTimeouts} timeouts, ${state.accumulatedToolResults.length} tools preserved)`,
|
|
508
|
+
timestamp: Date.now(),
|
|
509
|
+
});
|
|
437
510
|
if (useResume && nativeTimeouts === 0) {
|
|
438
511
|
this.applyInterMovementRecovery(state, promptWithAttachments);
|
|
439
512
|
}
|
|
@@ -442,7 +515,10 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
442
515
|
}
|
|
443
516
|
return true;
|
|
444
517
|
}
|
|
445
|
-
/** Accumulate completed tool results from a run into the retry state
|
|
518
|
+
/** Accumulate completed tool results from a run into the retry state.
|
|
519
|
+
* Caps at MAX_ACCUMULATED_RESULTS to prevent recovery prompts from exceeding context limits.
|
|
520
|
+
* When the cap is reached, older results are evicted (FIFO) to make room for newer ones. */
|
|
521
|
+
static MAX_ACCUMULATED_RESULTS = 50;
|
|
446
522
|
accumulateToolResults(result, state) {
|
|
447
523
|
if (!result.toolUseHistory)
|
|
448
524
|
return;
|
|
@@ -458,10 +534,17 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
458
534
|
});
|
|
459
535
|
}
|
|
460
536
|
}
|
|
537
|
+
// Evict oldest results if over the cap
|
|
538
|
+
const cap = ImprovisationSessionManager.MAX_ACCUMULATED_RESULTS;
|
|
539
|
+
if (state.accumulatedToolResults.length > cap) {
|
|
540
|
+
state.accumulatedToolResults = state.accumulatedToolResults.slice(-cap);
|
|
541
|
+
}
|
|
461
542
|
}
|
|
462
543
|
/** Handle inter-movement context loss recovery (resume session expired) */
|
|
463
544
|
applyInterMovementRecovery(state, promptWithAttachments) {
|
|
464
|
-
|
|
545
|
+
// Preserve session ID so --resume remains available on subsequent retries.
|
|
546
|
+
// The fresh recovery prompt will be used, but if this attempt also fails,
|
|
547
|
+
// the next retry can still try --resume via shouldRetrySignalCrash.
|
|
465
548
|
const historicalResults = this.extractHistoricalToolResults();
|
|
466
549
|
const allResults = [...historicalResults, ...state.accumulatedToolResults];
|
|
467
550
|
this.emit('onAutoRetry', {
|
|
@@ -495,7 +578,7 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
495
578
|
this.queueOutput(`\n[[MSTRO_CONTEXT_RECOVERY]] Continuing with fresh context — ${completedCount} preserved results injected (retry ${state.retryNumber}/3).\n`);
|
|
496
579
|
this.flushOutputQueue();
|
|
497
580
|
state.freshRecoveryMode = true;
|
|
498
|
-
state.currentPrompt = this.buildFreshRecoveryPrompt(promptWithAttachments, state.accumulatedToolResults);
|
|
581
|
+
state.currentPrompt = this.buildFreshRecoveryPrompt(promptWithAttachments, state.accumulatedToolResults, state.timedOutTools);
|
|
499
582
|
}
|
|
500
583
|
}
|
|
501
584
|
/** Handle tool timeout checkpoint. Returns true if loop should continue. */
|
|
@@ -511,6 +594,12 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
511
594
|
timeoutMs: cp.hungTool.timeoutMs,
|
|
512
595
|
});
|
|
513
596
|
const canResumeSession = cp.inProgressTools.length === 0 && !!cp.claudeSessionId;
|
|
597
|
+
state.retryLog.push({
|
|
598
|
+
retryNumber: state.retryNumber,
|
|
599
|
+
path: 'ToolTimeout',
|
|
600
|
+
reason: `${cp.hungTool.toolName} timed out after ${cp.hungTool.timeoutMs}ms, ${cp.completedTools.length} tools completed, ${canResumeSession ? 'resuming' : 'fresh start'}`,
|
|
601
|
+
timestamp: Date.now(),
|
|
602
|
+
});
|
|
514
603
|
this.emit('onAutoRetry', {
|
|
515
604
|
retryNumber: state.retryNumber,
|
|
516
605
|
maxRetries,
|
|
@@ -533,6 +622,104 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
533
622
|
this.flushOutputQueue();
|
|
534
623
|
return true;
|
|
535
624
|
}
|
|
625
|
+
/**
|
|
626
|
+
* Detect and retry after a signal crash (e.g., SIGTERM exit code 143).
|
|
627
|
+
* When the Claude process is killed externally (OOM, system signal, internal timeout
|
|
628
|
+
* that bypasses our watchdog), no existing recovery path catches it because contextLost
|
|
629
|
+
* is never set and no checkpoint is created. This adds a dedicated recovery path.
|
|
630
|
+
*/
|
|
631
|
+
shouldRetrySignalCrash(result, state, maxRetries, promptWithAttachments) {
|
|
632
|
+
// Only trigger for signal-killed processes (exit code 128+) that weren't already
|
|
633
|
+
// handled by context-loss or tool-timeout recovery paths.
|
|
634
|
+
// Must have an actual signal name — regular errors (e.g., auth failures, exit code 1)
|
|
635
|
+
// should NOT be retried as signal crashes.
|
|
636
|
+
const isSignalCrash = !!result.signalName;
|
|
637
|
+
const exitCodeSignal = !result.completed && !result.signalName && result.error?.match(/exited with code (1[2-9]\d|[2-9]\d{2})/);
|
|
638
|
+
if ((!isSignalCrash && !exitCodeSignal) || state.retryNumber >= maxRetries) {
|
|
639
|
+
return false;
|
|
640
|
+
}
|
|
641
|
+
// Don't re-trigger if tool timeout watchdog already handled this iteration
|
|
642
|
+
// (contextLost is NOT checked here — signal crash takes priority over context loss
|
|
643
|
+
// because it uses --resume which is lighter and avoids re-sending accumulated results)
|
|
644
|
+
if (state.checkpointRef.value) {
|
|
645
|
+
return false;
|
|
646
|
+
}
|
|
647
|
+
this.accumulateToolResults(result, state);
|
|
648
|
+
state.retryNumber++;
|
|
649
|
+
const completedCount = state.accumulatedToolResults.length;
|
|
650
|
+
const signalInfo = result.signalName || 'unknown signal';
|
|
651
|
+
const useResume = !!result.claudeSessionId && state.retryNumber === 1;
|
|
652
|
+
state.retryLog.push({
|
|
653
|
+
retryNumber: state.retryNumber,
|
|
654
|
+
path: 'SignalCrash',
|
|
655
|
+
reason: `Process killed (${signalInfo}), ${completedCount} tools preserved, ${useResume ? 'resuming' : 'fresh start'}`,
|
|
656
|
+
timestamp: Date.now(),
|
|
657
|
+
});
|
|
658
|
+
this.emit('onAutoRetry', {
|
|
659
|
+
retryNumber: state.retryNumber,
|
|
660
|
+
maxRetries,
|
|
661
|
+
toolName: `SignalCrash(${signalInfo})`,
|
|
662
|
+
completedCount,
|
|
663
|
+
});
|
|
664
|
+
trackEvent(AnalyticsEvents.IMPROVISE_AUTO_RETRY, {
|
|
665
|
+
retry_number: state.retryNumber,
|
|
666
|
+
hung_tool: `signal_crash:${signalInfo}`,
|
|
667
|
+
completed_tools: completedCount,
|
|
668
|
+
resume_attempted: useResume,
|
|
669
|
+
});
|
|
670
|
+
// If we have a session ID, try resuming first (preserves full context)
|
|
671
|
+
if (useResume) {
|
|
672
|
+
this.queueOutput(`\n[[MSTRO_SIGNAL_RECOVERY]] Process killed (${signalInfo}) — resuming session with ${completedCount} preserved results (retry ${state.retryNumber}/${maxRetries}).\n`);
|
|
673
|
+
this.flushOutputQueue();
|
|
674
|
+
state.contextRecoverySessionId = result.claudeSessionId;
|
|
675
|
+
this.claudeSessionId = result.claudeSessionId;
|
|
676
|
+
state.currentPrompt = this.buildSignalCrashRecoveryPrompt(promptWithAttachments, true);
|
|
677
|
+
}
|
|
678
|
+
else {
|
|
679
|
+
// Fresh start with accumulated results injected
|
|
680
|
+
this.queueOutput(`\n[[MSTRO_SIGNAL_RECOVERY]] Process killed (${signalInfo}) — restarting with ${completedCount} preserved results (retry ${state.retryNumber}/${maxRetries}).\n`);
|
|
681
|
+
this.flushOutputQueue();
|
|
682
|
+
state.freshRecoveryMode = true;
|
|
683
|
+
const allResults = [...this.extractHistoricalToolResults(), ...state.accumulatedToolResults];
|
|
684
|
+
state.currentPrompt = this.buildSignalCrashRecoveryPrompt(promptWithAttachments, false, allResults);
|
|
685
|
+
}
|
|
686
|
+
return true;
|
|
687
|
+
}
|
|
688
|
+
/** Build a recovery prompt after signal crash */
|
|
689
|
+
buildSignalCrashRecoveryPrompt(originalPrompt, isResume, toolResults) {
|
|
690
|
+
const parts = [];
|
|
691
|
+
if (isResume) {
|
|
692
|
+
parts.push('Your previous execution was interrupted by a system signal (the process was killed externally).');
|
|
693
|
+
parts.push('Your full conversation history is preserved — including all successful tool results.');
|
|
694
|
+
parts.push('');
|
|
695
|
+
parts.push('Review your conversation history above and continue from where you left off.');
|
|
696
|
+
}
|
|
697
|
+
else {
|
|
698
|
+
parts.push('## AUTOMATIC RETRY — Previous Execution Interrupted');
|
|
699
|
+
parts.push('');
|
|
700
|
+
parts.push('The previous execution was interrupted by a system signal (process killed).');
|
|
701
|
+
if (toolResults && toolResults.length > 0) {
|
|
702
|
+
parts.push(`${toolResults.length} tool results were preserved from prior work.`);
|
|
703
|
+
parts.push('');
|
|
704
|
+
parts.push('### Preserved results:');
|
|
705
|
+
for (const t of toolResults.slice(-20)) {
|
|
706
|
+
const inputSummary = JSON.stringify(t.toolInput).slice(0, 120);
|
|
707
|
+
const resultPreview = (t.result ?? '').slice(0, 200);
|
|
708
|
+
parts.push(`- **${t.toolName}**(${inputSummary}): ${resultPreview}`);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
parts.push('');
|
|
713
|
+
parts.push('### Original task:');
|
|
714
|
+
parts.push(originalPrompt);
|
|
715
|
+
parts.push('');
|
|
716
|
+
parts.push('INSTRUCTIONS:');
|
|
717
|
+
parts.push('1. Use the results above -- do not re-fetch content you already have');
|
|
718
|
+
parts.push('2. Continue from where you left off');
|
|
719
|
+
parts.push('3. Prefer multiple small, focused tool calls over single large ones');
|
|
720
|
+
parts.push('4. Do NOT spawn Task subagents — do work inline to avoid further interruptions');
|
|
721
|
+
return parts.join('\n');
|
|
722
|
+
}
|
|
536
723
|
/** Select the best result across retries using Haiku assessment */
|
|
537
724
|
async selectBestResult(state, result, userPrompt) {
|
|
538
725
|
if (!state.bestResult || state.bestResult === result || state.retryNumber === 0) {
|
|
@@ -598,7 +785,7 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
598
785
|
}
|
|
599
786
|
}
|
|
600
787
|
/** Build a MovementRecord from execution result */
|
|
601
|
-
buildMovementRecord(result, userPrompt, sequenceNumber, execStart) {
|
|
788
|
+
buildMovementRecord(result, userPrompt, sequenceNumber, execStart, retryLog) {
|
|
602
789
|
return {
|
|
603
790
|
id: `prompt-${sequenceNumber}`,
|
|
604
791
|
sequenceNumber,
|
|
@@ -619,6 +806,7 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
619
806
|
})),
|
|
620
807
|
errorOutput: result.error,
|
|
621
808
|
durationMs: Date.now() - execStart,
|
|
809
|
+
retryLog: retryLog && retryLog.length > 0 ? retryLog : undefined,
|
|
622
810
|
};
|
|
623
811
|
}
|
|
624
812
|
/** Handle file conflicts from execution result */
|
|
@@ -786,7 +974,7 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
786
974
|
* Injects all accumulated tool results from previous attempts so Claude can continue
|
|
787
975
|
* the task without re-fetching data it already gathered.
|
|
788
976
|
*/
|
|
789
|
-
buildFreshRecoveryPrompt(originalPrompt, toolResults) {
|
|
977
|
+
buildFreshRecoveryPrompt(originalPrompt, toolResults, timedOutTools) {
|
|
790
978
|
const parts = [
|
|
791
979
|
'## CONTINUING LONG-RUNNING TASK',
|
|
792
980
|
'',
|
|
@@ -794,6 +982,9 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
794
982
|
'Below are all results gathered before the interruption. Continue the task using these results.',
|
|
795
983
|
'',
|
|
796
984
|
];
|
|
985
|
+
if (timedOutTools && timedOutTools.length > 0) {
|
|
986
|
+
parts.push(...this.formatTimedOutTools(timedOutTools), '');
|
|
987
|
+
}
|
|
797
988
|
parts.push(...this.formatToolResults(toolResults));
|
|
798
989
|
parts.push('### Original task:');
|
|
799
990
|
parts.push(originalPrompt);
|
|
@@ -975,6 +1166,7 @@ export class ImprovisationSessionManager extends EventEmitter {
|
|
|
975
1166
|
* Cancel current execution
|
|
976
1167
|
*/
|
|
977
1168
|
cancel() {
|
|
1169
|
+
this._cancelled = true;
|
|
978
1170
|
if (this.currentRunner) {
|
|
979
1171
|
this.currentRunner.cleanup();
|
|
980
1172
|
this.currentRunner = null;
|