pm-orchestrator-runner 1.0.5 → 1.0.7
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/core/runner-core.d.ts +17 -0
- package/dist/core/runner-core.d.ts.map +1 -1
- package/dist/core/runner-core.js +46 -3
- package/dist/core/runner-core.js.map +1 -1
- package/dist/executor/recovery-executor.d.ts +101 -0
- package/dist/executor/recovery-executor.d.ts.map +1 -0
- package/dist/executor/recovery-executor.js +228 -0
- package/dist/executor/recovery-executor.js.map +1 -0
- package/dist/logging/task-log-manager.d.ts +17 -2
- package/dist/logging/task-log-manager.d.ts.map +1 -1
- package/dist/logging/task-log-manager.js +153 -63
- package/dist/logging/task-log-manager.js.map +1 -1
- package/dist/models/repl/task-log.d.ts +9 -0
- package/dist/models/repl/task-log.d.ts.map +1 -1
- package/dist/models/repl/task-log.js.map +1 -1
- package/dist/repl/commands/keys.d.ts.map +1 -1
- package/dist/repl/commands/keys.js +9 -1
- package/dist/repl/commands/keys.js.map +1 -1
- package/dist/repl/commands/logs.d.ts +3 -1
- package/dist/repl/commands/logs.d.ts.map +1 -1
- package/dist/repl/commands/logs.js +23 -3
- package/dist/repl/commands/logs.js.map +1 -1
- package/dist/repl/commands/status.d.ts +21 -3
- package/dist/repl/commands/status.d.ts.map +1 -1
- package/dist/repl/commands/status.js +205 -60
- package/dist/repl/commands/status.js.map +1 -1
- package/dist/repl/repl-interface.d.ts +98 -2
- package/dist/repl/repl-interface.d.ts.map +1 -1
- package/dist/repl/repl-interface.js +366 -34
- package/dist/repl/repl-interface.js.map +1 -1
- package/package.json +5 -2
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Recovery Executor for E2E Recovery Testing
|
|
4
|
+
*
|
|
5
|
+
* Purpose: Simulate TIMEOUT, BLOCKED, and FAIL_CLOSED scenarios
|
|
6
|
+
* to verify wrapper recovery behavior.
|
|
7
|
+
*
|
|
8
|
+
* ========================================
|
|
9
|
+
* SAFETY: TEST-ONLY COMPONENT
|
|
10
|
+
* ========================================
|
|
11
|
+
* This executor is designed ONLY for E2E testing.
|
|
12
|
+
* Production safety mechanisms:
|
|
13
|
+
* 1. Requires explicit PM_EXECUTOR_MODE=recovery-stub
|
|
14
|
+
* 2. Rejects activation when NODE_ENV=production
|
|
15
|
+
* 3. Prints warning to stdout on activation
|
|
16
|
+
* 4. All output contains mode=recovery-stub marker
|
|
17
|
+
*
|
|
18
|
+
* Activation:
|
|
19
|
+
* PM_EXECUTOR_MODE=recovery-stub
|
|
20
|
+
* PM_RECOVERY_SCENARIO=timeout|blocked|fail-closed
|
|
21
|
+
*
|
|
22
|
+
* Behaviors:
|
|
23
|
+
* TIMEOUT: Block indefinitely until watchdog kills (hard timeout)
|
|
24
|
+
* BLOCKED: Return output with interactive prompt patterns
|
|
25
|
+
* FAIL_CLOSED: Return ERROR status immediately
|
|
26
|
+
*
|
|
27
|
+
* E2E Verification Criteria:
|
|
28
|
+
* - Wrapper must recover from all scenarios
|
|
29
|
+
* - Exit code must be 0, 1, or 2 (graceful termination)
|
|
30
|
+
* - Immediate Summary must be visible (RESULT/TASK/HINT)
|
|
31
|
+
* - No RUNNING residue in session state
|
|
32
|
+
*/
|
|
33
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
+
exports.RecoveryExecutor = void 0;
|
|
35
|
+
exports.isProductionEnvironment = isProductionEnvironment;
|
|
36
|
+
exports.isRecoveryMode = isRecoveryMode;
|
|
37
|
+
exports.assertRecoveryModeAllowed = assertRecoveryModeAllowed;
|
|
38
|
+
exports.printRecoveryModeWarning = printRecoveryModeWarning;
|
|
39
|
+
exports.getRecoveryScenario = getRecoveryScenario;
|
|
40
|
+
exports.createRecoveryExecutor = createRecoveryExecutor;
|
|
41
|
+
/**
|
|
42
|
+
* Check if running in production environment
|
|
43
|
+
*/
|
|
44
|
+
function isProductionEnvironment() {
|
|
45
|
+
return process.env.NODE_ENV === 'production';
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Check if recovery mode is enabled
|
|
49
|
+
*
|
|
50
|
+
* SAFETY: Returns false if NODE_ENV=production
|
|
51
|
+
*/
|
|
52
|
+
function isRecoveryMode() {
|
|
53
|
+
// Production safety: reject recovery-stub in production
|
|
54
|
+
if (isProductionEnvironment()) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
return process.env.PM_EXECUTOR_MODE === 'recovery-stub';
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Attempt to enable recovery mode in production
|
|
61
|
+
* This will fail-closed with process.exit(1) if attempted
|
|
62
|
+
*
|
|
63
|
+
* Call this early in the process to catch production misuse
|
|
64
|
+
*/
|
|
65
|
+
function assertRecoveryModeAllowed() {
|
|
66
|
+
if (process.env.PM_EXECUTOR_MODE === 'recovery-stub' && isProductionEnvironment()) {
|
|
67
|
+
console.error('[FATAL] recovery-stub is forbidden in production (NODE_ENV=production)');
|
|
68
|
+
console.error('[FATAL] mode=recovery-stub rejected');
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Print warning when recovery mode is activated
|
|
74
|
+
* This MUST be visible in stdout for E2E verification
|
|
75
|
+
*/
|
|
76
|
+
function printRecoveryModeWarning() {
|
|
77
|
+
console.log('WARNING: recovery-stub enabled (test-only)');
|
|
78
|
+
console.log('mode=recovery-stub');
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get the current recovery scenario
|
|
82
|
+
*/
|
|
83
|
+
function getRecoveryScenario() {
|
|
84
|
+
const scenario = process.env.PM_RECOVERY_SCENARIO;
|
|
85
|
+
if (scenario === 'timeout' || scenario === 'blocked' || scenario === 'fail-closed') {
|
|
86
|
+
return scenario;
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* RecoveryExecutor - For E2E recovery testing
|
|
92
|
+
*
|
|
93
|
+
* Simulates failure scenarios that require wrapper recovery.
|
|
94
|
+
* Each scenario tests a different recovery path.
|
|
95
|
+
*
|
|
96
|
+
* SAFETY: Constructor prints warning to stdout
|
|
97
|
+
*/
|
|
98
|
+
class RecoveryExecutor {
|
|
99
|
+
scenario;
|
|
100
|
+
constructor(scenario) {
|
|
101
|
+
// Print warning on construction (visible in stdout)
|
|
102
|
+
printRecoveryModeWarning();
|
|
103
|
+
this.scenario = scenario || getRecoveryScenario() || 'timeout';
|
|
104
|
+
}
|
|
105
|
+
async isClaudeCodeAvailable() {
|
|
106
|
+
// In recovery mode, we simulate Claude Code availability
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
async execute(task) {
|
|
110
|
+
const startTime = Date.now();
|
|
111
|
+
const cwd = task.workingDir;
|
|
112
|
+
// Evidence marker for E2E verification
|
|
113
|
+
console.log(`[RecoveryExecutor] mode=recovery-stub`);
|
|
114
|
+
console.log(`[RecoveryExecutor] Scenario: ${this.scenario}, task: ${task.id}`);
|
|
115
|
+
switch (this.scenario) {
|
|
116
|
+
case 'timeout':
|
|
117
|
+
return this.simulateTimeout(task, startTime, cwd);
|
|
118
|
+
case 'blocked':
|
|
119
|
+
return this.simulateBlocked(task, startTime, cwd);
|
|
120
|
+
case 'fail-closed':
|
|
121
|
+
return this.simulateFailClosed(task, startTime, cwd);
|
|
122
|
+
default:
|
|
123
|
+
// Should never happen, but fail-closed for safety
|
|
124
|
+
return this.simulateFailClosed(task, startTime, cwd);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* TIMEOUT scenario:
|
|
129
|
+
* Block for a long time to trigger hard timeout in the wrapper.
|
|
130
|
+
* The wrapper should detect no output and terminate.
|
|
131
|
+
*/
|
|
132
|
+
async simulateTimeout(task, startTime, cwd) {
|
|
133
|
+
console.log('[RecoveryExecutor] Simulating TIMEOUT - blocking for extended period');
|
|
134
|
+
// Block for a very long time (the wrapper should kill us before this completes)
|
|
135
|
+
// Using a reasonable time that exceeds hard timeout (default 120s)
|
|
136
|
+
// For testing, we use a shorter time but longer than the test's configured timeout
|
|
137
|
+
const blockDuration = parseInt(process.env.RECOVERY_TIMEOUT_BLOCK_MS || '150000', 10);
|
|
138
|
+
await new Promise((resolve) => {
|
|
139
|
+
const timeout = setTimeout(resolve, blockDuration);
|
|
140
|
+
// Allow the timeout to be unrefd so the process can be killed
|
|
141
|
+
timeout.unref();
|
|
142
|
+
});
|
|
143
|
+
// If we reach here, the wrapper failed to terminate us (test failure case)
|
|
144
|
+
return {
|
|
145
|
+
executed: false,
|
|
146
|
+
output: '',
|
|
147
|
+
error: 'TIMEOUT simulation - wrapper failed to terminate',
|
|
148
|
+
files_modified: [],
|
|
149
|
+
duration_ms: Date.now() - startTime,
|
|
150
|
+
status: 'ERROR',
|
|
151
|
+
cwd,
|
|
152
|
+
verified_files: [],
|
|
153
|
+
unverified_files: [],
|
|
154
|
+
executor_blocked: true,
|
|
155
|
+
blocked_reason: 'TIMEOUT',
|
|
156
|
+
timeout_ms: Date.now() - startTime,
|
|
157
|
+
terminated_by: 'TIMEOUT',
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* BLOCKED scenario:
|
|
162
|
+
* Return output containing interactive prompt patterns.
|
|
163
|
+
* The wrapper should detect BLOCKED status and recover.
|
|
164
|
+
*/
|
|
165
|
+
async simulateBlocked(task, startTime, cwd) {
|
|
166
|
+
console.log('[RecoveryExecutor] Simulating BLOCKED - returning interactive prompt output');
|
|
167
|
+
// Small delay to simulate some processing
|
|
168
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
169
|
+
// Return result indicating blocked status
|
|
170
|
+
// This simulates what happens when Claude Code CLI hits an interactive prompt
|
|
171
|
+
return {
|
|
172
|
+
executed: false,
|
|
173
|
+
output: 'Would you like to continue? [Y/n]',
|
|
174
|
+
error: 'Executor blocked: INTERACTIVE_PROMPT',
|
|
175
|
+
files_modified: [],
|
|
176
|
+
duration_ms: Date.now() - startTime,
|
|
177
|
+
status: 'BLOCKED',
|
|
178
|
+
cwd,
|
|
179
|
+
verified_files: [],
|
|
180
|
+
unverified_files: [],
|
|
181
|
+
executor_blocked: true,
|
|
182
|
+
blocked_reason: 'INTERACTIVE_PROMPT',
|
|
183
|
+
timeout_ms: Date.now() - startTime,
|
|
184
|
+
terminated_by: 'REPL_FAIL_CLOSED',
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* FAIL_CLOSED scenario:
|
|
189
|
+
* Return ERROR status immediately.
|
|
190
|
+
* Simulates executor crash or unexpected termination.
|
|
191
|
+
*/
|
|
192
|
+
async simulateFailClosed(task, startTime, cwd) {
|
|
193
|
+
console.log('[RecoveryExecutor] Simulating FAIL_CLOSED - returning error immediately');
|
|
194
|
+
// Small delay to simulate some processing
|
|
195
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
196
|
+
// Return error result (simulates non-zero exit code)
|
|
197
|
+
return {
|
|
198
|
+
executed: false,
|
|
199
|
+
output: 'Fatal error: simulated crash',
|
|
200
|
+
error: 'Executor terminated unexpectedly (simulated FAIL_CLOSED)',
|
|
201
|
+
files_modified: [],
|
|
202
|
+
duration_ms: Date.now() - startTime,
|
|
203
|
+
status: 'ERROR',
|
|
204
|
+
cwd,
|
|
205
|
+
verified_files: [],
|
|
206
|
+
unverified_files: [],
|
|
207
|
+
executor_blocked: false,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
exports.RecoveryExecutor = RecoveryExecutor;
|
|
212
|
+
/**
|
|
213
|
+
* Create recovery executor if in recovery mode
|
|
214
|
+
*
|
|
215
|
+
* SAFETY: Calls assertRecoveryModeAllowed() to reject production usage
|
|
216
|
+
*/
|
|
217
|
+
function createRecoveryExecutor() {
|
|
218
|
+
// Early fail-closed for production misuse
|
|
219
|
+
assertRecoveryModeAllowed();
|
|
220
|
+
if (isRecoveryMode()) {
|
|
221
|
+
const scenario = getRecoveryScenario();
|
|
222
|
+
if (scenario) {
|
|
223
|
+
return new RecoveryExecutor(scenario);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=recovery-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-executor.js","sourceRoot":"","sources":["../../src/executor/recovery-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,7 @@ import type { BlockedReason, TerminatedBy } from '../models/enums';
|
|
|
12
12
|
/**
|
|
13
13
|
* Options for completing a task
|
|
14
14
|
* Per spec 10_REPL_UX.md Section 10: Executor blocking fields (Property 34-36)
|
|
15
|
+
* Per redesign: Visibility fields for task description, executor mode, and response
|
|
15
16
|
*/
|
|
16
17
|
export interface CompleteTaskOptions {
|
|
17
18
|
filesModified?: string[];
|
|
@@ -25,6 +26,12 @@ export interface CompleteTaskOptions {
|
|
|
25
26
|
timeoutMs?: number;
|
|
26
27
|
/** How the executor was terminated */
|
|
27
28
|
terminatedBy?: TerminatedBy;
|
|
29
|
+
/** Task description/prompt summary (per redesign: visibility) */
|
|
30
|
+
description?: string;
|
|
31
|
+
/** Executor mode used (per redesign: visibility) */
|
|
32
|
+
executorMode?: string;
|
|
33
|
+
/** Response summary from executor (per redesign: visibility) */
|
|
34
|
+
responseSummary?: string;
|
|
28
35
|
}
|
|
29
36
|
/**
|
|
30
37
|
* Log directory structure
|
|
@@ -130,8 +137,14 @@ export declare class TaskLogManager {
|
|
|
130
137
|
/**
|
|
131
138
|
* Create a task with thread/run context
|
|
132
139
|
* Per spec 13_LOGGING_AND_OBSERVABILITY.md Section 2.3
|
|
140
|
+
*
|
|
141
|
+
* @param sessionId - Session ID
|
|
142
|
+
* @param threadId - Thread ID
|
|
143
|
+
* @param runId - Run ID
|
|
144
|
+
* @param parentTaskId - Optional parent task ID
|
|
145
|
+
* @param externalTaskId - Optional external task ID (from REPL). If provided, use this instead of generating.
|
|
133
146
|
*/
|
|
134
|
-
createTaskWithContext(sessionId: string, threadId: string, runId: string, parentTaskId?: string): Promise<TaskLog>;
|
|
147
|
+
createTaskWithContext(sessionId: string, threadId: string, runId: string, parentTaskId?: string, externalTaskId?: string): Promise<TaskLog>;
|
|
135
148
|
/**
|
|
136
149
|
* Increment task count in global index
|
|
137
150
|
*/
|
|
@@ -204,12 +217,14 @@ export declare class TaskLogManager {
|
|
|
204
217
|
}>;
|
|
205
218
|
/**
|
|
206
219
|
* Format task list for REPL display (legacy)
|
|
220
|
+
* Per redesign: Shows task description for visibility
|
|
207
221
|
*/
|
|
208
222
|
formatTaskList(entries: TaskLogEntry[], sessionId: string): string;
|
|
209
223
|
/**
|
|
210
224
|
* Format task detail for REPL display (legacy)
|
|
225
|
+
* Per redesign: Shows summary section with description, executor mode, files modified, and response
|
|
211
226
|
*/
|
|
212
|
-
formatTaskDetail(taskId: string, log: TaskLog, events: LogEvent[], isFull: boolean): string;
|
|
227
|
+
formatTaskDetail(taskId: string, log: TaskLog, events: LogEvent[], isFull: boolean, entry?: TaskLogEntry): string;
|
|
213
228
|
}
|
|
214
229
|
export { LOG_DIR, INDEX_FILE, TASKS_DIR, RAW_DIR, SESSIONS_DIR, SESSION_FILE };
|
|
215
230
|
//# sourceMappingURL=task-log-manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-log-manager.d.ts","sourceRoot":"","sources":["../../src/logging/task-log-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EACL,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,eAAe,EACf,MAAM,EACN,GAAG,EACH,UAAU,EACV,SAAS,EACT,UAAU,EACV,eAAe,EAWhB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGnE
|
|
1
|
+
{"version":3,"file":"task-log-manager.d.ts","sourceRoot":"","sources":["../../src/logging/task-log-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -345,14 +345,33 @@ class TaskLogManager {
|
|
|
345
345
|
entry.executor_blocked = options.executorBlocked;
|
|
346
346
|
entry.blocked_reason = options.blockedReason;
|
|
347
347
|
}
|
|
348
|
+
// Per redesign: Record visibility fields
|
|
349
|
+
if (options?.description) {
|
|
350
|
+
entry.description = options.description;
|
|
351
|
+
}
|
|
352
|
+
if (options?.executorMode) {
|
|
353
|
+
entry.executor_mode = options.executorMode;
|
|
354
|
+
}
|
|
355
|
+
if (filesModified.length > 0) {
|
|
356
|
+
entry.files_modified = filesModified;
|
|
357
|
+
}
|
|
358
|
+
if (options?.responseSummary) {
|
|
359
|
+
entry.response_summary = options.responseSummary;
|
|
360
|
+
}
|
|
348
361
|
}
|
|
349
362
|
await this.saveSessionIndex(sessionId, index);
|
|
350
363
|
}
|
|
351
364
|
/**
|
|
352
365
|
* Create a task with thread/run context
|
|
353
366
|
* Per spec 13_LOGGING_AND_OBSERVABILITY.md Section 2.3
|
|
354
|
-
|
|
355
|
-
|
|
367
|
+
*
|
|
368
|
+
* @param sessionId - Session ID
|
|
369
|
+
* @param threadId - Thread ID
|
|
370
|
+
* @param runId - Run ID
|
|
371
|
+
* @param parentTaskId - Optional parent task ID
|
|
372
|
+
* @param externalTaskId - Optional external task ID (from REPL). If provided, use this instead of generating.
|
|
373
|
+
*/
|
|
374
|
+
async createTaskWithContext(sessionId, threadId, runId, parentTaskId, externalTaskId) {
|
|
356
375
|
await this.ensureSessionDirectories(sessionId);
|
|
357
376
|
// Validate parent task is in same thread if specified
|
|
358
377
|
if (parentTaskId) {
|
|
@@ -361,7 +380,8 @@ class TaskLogManager {
|
|
|
361
380
|
throw new Error('parent_task_id must be within same thread');
|
|
362
381
|
}
|
|
363
382
|
}
|
|
364
|
-
|
|
383
|
+
// Use external task ID if provided (from REPL), otherwise generate
|
|
384
|
+
const taskId = externalTaskId || this.generateTaskId(sessionId);
|
|
365
385
|
const log = (0, task_log_1.createTaskLog)(taskId, sessionId, threadId, runId, parentTaskId ?? null);
|
|
366
386
|
await this.saveTaskLogWithSession(log, sessionId);
|
|
367
387
|
// Update session index
|
|
@@ -646,92 +666,162 @@ class TaskLogManager {
|
|
|
646
666
|
}
|
|
647
667
|
/**
|
|
648
668
|
* Format task list for REPL display (legacy)
|
|
669
|
+
* Per redesign: Shows task description for visibility
|
|
649
670
|
*/
|
|
650
671
|
formatTaskList(entries, sessionId) {
|
|
651
672
|
if (entries.length === 0) {
|
|
652
673
|
return 'No tasks logged for this session.';
|
|
653
674
|
}
|
|
654
675
|
let output = 'Task Logs (session: ' + sessionId + '):\n\n';
|
|
655
|
-
output += ' # | Task ID | Status | Duration | Files | Tests\n';
|
|
656
|
-
output += ' --|--------------|------------|----------|-------|------\n';
|
|
657
676
|
entries.forEach((entry, index) => {
|
|
658
677
|
const duration = entry.duration_ms > 0
|
|
659
678
|
? (entry.duration_ms / 1000).toFixed(1) + 's'
|
|
660
679
|
: '-';
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
680
|
+
// Status icon
|
|
681
|
+
let statusIcon = '';
|
|
682
|
+
if (entry.status === 'COMPLETE') {
|
|
683
|
+
statusIcon = '[OK]';
|
|
684
|
+
}
|
|
685
|
+
else if (entry.status === 'ERROR') {
|
|
686
|
+
statusIcon = '[ERR]';
|
|
687
|
+
}
|
|
688
|
+
else if (entry.status === 'INCOMPLETE') {
|
|
689
|
+
statusIcon = '[INC]';
|
|
690
|
+
}
|
|
691
|
+
else {
|
|
692
|
+
statusIcon = '[...]';
|
|
693
|
+
}
|
|
694
|
+
// Task line with description
|
|
695
|
+
output += ' ' + (index + 1) + '. ' + entry.task_id + ' ' + statusIcon + '\n';
|
|
696
|
+
// Description (truncated to 60 chars)
|
|
697
|
+
if (entry.description) {
|
|
698
|
+
const truncatedDesc = entry.description.length > 60
|
|
699
|
+
? entry.description.substring(0, 57) + '...'
|
|
700
|
+
: entry.description;
|
|
701
|
+
output += ' Prompt: ' + truncatedDesc + '\n';
|
|
702
|
+
}
|
|
703
|
+
// Stats line
|
|
704
|
+
output += ' ' + duration + ' | Files: ' + entry.files_modified_count;
|
|
705
|
+
if (entry.executor_mode) {
|
|
706
|
+
output += ' | Mode: ' + entry.executor_mode;
|
|
707
|
+
}
|
|
708
|
+
if (entry.executor_blocked) {
|
|
709
|
+
output += ' | BLOCKED: ' + (entry.blocked_reason || 'unknown');
|
|
710
|
+
}
|
|
711
|
+
output += '\n';
|
|
712
|
+
// Files modified summary (if any)
|
|
713
|
+
if (entry.files_modified && entry.files_modified.length > 0) {
|
|
714
|
+
const filesDisplay = entry.files_modified.slice(0, 3).join(', ');
|
|
715
|
+
const moreCount = entry.files_modified.length > 3 ? ' +' + (entry.files_modified.length - 3) + ' more' : '';
|
|
716
|
+
output += ' Changed: ' + filesDisplay + moreCount + '\n';
|
|
717
|
+
}
|
|
718
|
+
output += '\n';
|
|
667
719
|
});
|
|
668
|
-
output += '
|
|
720
|
+
output += 'Use /logs <task-id> to view details.\n';
|
|
669
721
|
output += 'Use /logs <task-id> --full for executor-level logs.';
|
|
670
722
|
return output;
|
|
671
723
|
}
|
|
672
724
|
/**
|
|
673
725
|
* Format task detail for REPL display (legacy)
|
|
726
|
+
* Per redesign: Shows summary section with description, executor mode, files modified, and response
|
|
674
727
|
*/
|
|
675
|
-
formatTaskDetail(taskId, log, events, isFull) {
|
|
676
|
-
let output = 'Task
|
|
728
|
+
formatTaskDetail(taskId, log, events, isFull, entry) {
|
|
729
|
+
let output = '--- Task Detail: ' + taskId + ' ---\n';
|
|
677
730
|
if (isFull) {
|
|
678
|
-
output += '
|
|
679
|
-
}
|
|
680
|
-
output += '\n
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
731
|
+
output += '(Full mode - showing all executor details)\n';
|
|
732
|
+
}
|
|
733
|
+
output += '\n';
|
|
734
|
+
// Per redesign: Show summary section at top with visibility fields
|
|
735
|
+
output += '=== Summary ===\n';
|
|
736
|
+
output += 'Status: ' + (entry?.status || 'UNKNOWN') + '\n';
|
|
737
|
+
if (entry?.duration_ms && entry.duration_ms > 0) {
|
|
738
|
+
output += 'Duration: ' + (entry.duration_ms / 1000).toFixed(1) + 's\n';
|
|
739
|
+
}
|
|
740
|
+
if (entry?.executor_mode) {
|
|
741
|
+
output += 'Executor: ' + entry.executor_mode + '\n';
|
|
742
|
+
}
|
|
743
|
+
output += '\n';
|
|
744
|
+
// Prompt/Description
|
|
745
|
+
if (entry?.description) {
|
|
746
|
+
output += '=== Prompt ===\n';
|
|
747
|
+
output += entry.description + '\n\n';
|
|
748
|
+
}
|
|
749
|
+
// Files Modified
|
|
750
|
+
if (entry?.files_modified && entry.files_modified.length > 0) {
|
|
751
|
+
output += '=== Files Modified (' + entry.files_modified.length + ') ===\n';
|
|
752
|
+
for (const file of entry.files_modified) {
|
|
753
|
+
output += ' - ' + file + '\n';
|
|
696
754
|
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
755
|
+
output += '\n';
|
|
756
|
+
}
|
|
757
|
+
// Response Summary
|
|
758
|
+
if (entry?.response_summary) {
|
|
759
|
+
output += '=== Response Summary ===\n';
|
|
760
|
+
output += entry.response_summary + '\n\n';
|
|
761
|
+
}
|
|
762
|
+
// Executor Blocking Info
|
|
763
|
+
if (entry?.executor_blocked) {
|
|
764
|
+
output += '=== BLOCKED ===\n';
|
|
765
|
+
output += 'Reason: ' + (entry.blocked_reason || 'unknown') + '\n\n';
|
|
766
|
+
}
|
|
767
|
+
// Event Log
|
|
768
|
+
if (events.length > 0) {
|
|
769
|
+
output += '=== Event Log ===\n';
|
|
770
|
+
for (const event of events) {
|
|
771
|
+
const time = new Date(event.timestamp).toLocaleTimeString();
|
|
772
|
+
output += '[' + time + '] ' + event.event_type + '\n';
|
|
773
|
+
// Format content based on event type
|
|
774
|
+
if (event.content.text) {
|
|
775
|
+
output += ' "' + (0, sensitive_data_masker_1.maskSensitiveData)(event.content.text) + '"\n';
|
|
713
776
|
}
|
|
714
|
-
if (event.content.
|
|
715
|
-
output += '
|
|
777
|
+
if (event.content.question) {
|
|
778
|
+
output += ' "' + (0, sensitive_data_masker_1.maskSensitiveData)(event.content.question) + '"\n';
|
|
716
779
|
}
|
|
717
|
-
if (event.content.
|
|
718
|
-
output += '
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
780
|
+
if (event.content.action) {
|
|
781
|
+
output += ' Action: ' + event.content.action + '\n';
|
|
782
|
+
}
|
|
783
|
+
if (event.content.target_file) {
|
|
784
|
+
output += ' Target: ' + event.content.target_file + '\n';
|
|
785
|
+
}
|
|
786
|
+
if (event.content.status) {
|
|
787
|
+
output += ' Status: ' + event.content.status + '\n';
|
|
723
788
|
}
|
|
724
|
-
if (event.content.
|
|
725
|
-
output += '
|
|
789
|
+
if (event.content.files_modified && event.content.files_modified.length > 0) {
|
|
790
|
+
output += ' Files modified: ' + event.content.files_modified.join(', ') + '\n';
|
|
726
791
|
}
|
|
727
|
-
if (event.content.
|
|
728
|
-
output += '
|
|
792
|
+
if (event.content.evidence_ref) {
|
|
793
|
+
output += ' Evidence: ' + event.content.evidence_ref + '\n';
|
|
729
794
|
}
|
|
730
|
-
if (event.content.
|
|
731
|
-
output += '
|
|
795
|
+
if (event.content.error_message) {
|
|
796
|
+
output += ' Error: ' + (0, sensitive_data_masker_1.maskSensitiveData)(event.content.error_message) + '\n';
|
|
732
797
|
}
|
|
798
|
+
// Full mode specific content
|
|
799
|
+
if (isFull) {
|
|
800
|
+
if (event.content.provider) {
|
|
801
|
+
output += ' Provider: ' + event.content.provider + '\n';
|
|
802
|
+
}
|
|
803
|
+
if (event.content.model) {
|
|
804
|
+
output += ' Model: ' + event.content.model + '\n';
|
|
805
|
+
}
|
|
806
|
+
if (event.content.tokens_input !== undefined) {
|
|
807
|
+
output += ' Tokens: ' + event.content.tokens_input + ' input';
|
|
808
|
+
if (event.content.tokens_output !== undefined) {
|
|
809
|
+
output += ', ' + event.content.tokens_output + ' output';
|
|
810
|
+
}
|
|
811
|
+
output += '\n';
|
|
812
|
+
}
|
|
813
|
+
if (event.content.latency_ms !== undefined) {
|
|
814
|
+
output += ' Latency: ' + event.content.latency_ms + 'ms\n';
|
|
815
|
+
}
|
|
816
|
+
if (event.content.exit_code !== undefined) {
|
|
817
|
+
output += ' Exit code: ' + event.content.exit_code + '\n';
|
|
818
|
+
}
|
|
819
|
+
if (event.content.output_summary) {
|
|
820
|
+
output += ' Output: ' + (0, sensitive_data_masker_1.maskSensitiveData)(event.content.output_summary) + '\n';
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
output += '\n';
|
|
733
824
|
}
|
|
734
|
-
output += '\n';
|
|
735
825
|
}
|
|
736
826
|
if (!isFull) {
|
|
737
827
|
output += 'Use --full to see executor details.';
|