@litmers/cursorflow-orchestrator 0.1.18 → 0.1.26
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/CHANGELOG.md +25 -0
- package/README.md +25 -7
- package/commands/cursorflow-clean.md +19 -0
- package/commands/cursorflow-runs.md +59 -0
- package/commands/cursorflow-stop.md +55 -0
- package/dist/cli/clean.js +178 -6
- package/dist/cli/clean.js.map +1 -1
- package/dist/cli/index.js +12 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.js +8 -7
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/logs.js +126 -77
- package/dist/cli/logs.js.map +1 -1
- package/dist/cli/monitor.d.ts +7 -0
- package/dist/cli/monitor.js +1021 -202
- package/dist/cli/monitor.js.map +1 -1
- package/dist/cli/prepare.js +39 -21
- package/dist/cli/prepare.js.map +1 -1
- package/dist/cli/resume.js +268 -163
- package/dist/cli/resume.js.map +1 -1
- package/dist/cli/run.js +11 -5
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/runs.d.ts +5 -0
- package/dist/cli/runs.js +214 -0
- package/dist/cli/runs.js.map +1 -0
- package/dist/cli/setup-commands.js +0 -0
- package/dist/cli/signal.js +8 -8
- package/dist/cli/signal.js.map +1 -1
- package/dist/cli/stop.d.ts +5 -0
- package/dist/cli/stop.js +215 -0
- package/dist/cli/stop.js.map +1 -0
- package/dist/cli/tasks.d.ts +10 -0
- package/dist/cli/tasks.js +165 -0
- package/dist/cli/tasks.js.map +1 -0
- package/dist/core/auto-recovery.d.ts +212 -0
- package/dist/core/auto-recovery.js +737 -0
- package/dist/core/auto-recovery.js.map +1 -0
- package/dist/core/failure-policy.d.ts +156 -0
- package/dist/core/failure-policy.js +488 -0
- package/dist/core/failure-policy.js.map +1 -0
- package/dist/core/orchestrator.d.ts +16 -2
- package/dist/core/orchestrator.js +439 -105
- package/dist/core/orchestrator.js.map +1 -1
- package/dist/core/reviewer.d.ts +2 -0
- package/dist/core/reviewer.js +2 -0
- package/dist/core/reviewer.js.map +1 -1
- package/dist/core/runner.d.ts +33 -10
- package/dist/core/runner.js +374 -164
- package/dist/core/runner.js.map +1 -1
- package/dist/services/logging/buffer.d.ts +67 -0
- package/dist/services/logging/buffer.js +309 -0
- package/dist/services/logging/buffer.js.map +1 -0
- package/dist/services/logging/console.d.ts +89 -0
- package/dist/services/logging/console.js +169 -0
- package/dist/services/logging/console.js.map +1 -0
- package/dist/services/logging/file-writer.d.ts +71 -0
- package/dist/services/logging/file-writer.js +516 -0
- package/dist/services/logging/file-writer.js.map +1 -0
- package/dist/services/logging/formatter.d.ts +39 -0
- package/dist/services/logging/formatter.js +227 -0
- package/dist/services/logging/formatter.js.map +1 -0
- package/dist/services/logging/index.d.ts +11 -0
- package/dist/services/logging/index.js +30 -0
- package/dist/services/logging/index.js.map +1 -0
- package/dist/services/logging/parser.d.ts +31 -0
- package/dist/services/logging/parser.js +222 -0
- package/dist/services/logging/parser.js.map +1 -0
- package/dist/services/process/index.d.ts +59 -0
- package/dist/services/process/index.js +257 -0
- package/dist/services/process/index.js.map +1 -0
- package/dist/types/agent.d.ts +20 -0
- package/dist/types/agent.js +6 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/config.d.ts +65 -0
- package/dist/types/config.js +6 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/events.d.ts +125 -0
- package/dist/types/events.js +6 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.js +37 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/lane.d.ts +43 -0
- package/dist/types/lane.js +6 -0
- package/dist/types/lane.js.map +1 -0
- package/dist/types/logging.d.ts +71 -0
- package/dist/types/logging.js +16 -0
- package/dist/types/logging.js.map +1 -0
- package/dist/types/review.d.ts +17 -0
- package/dist/types/review.js +6 -0
- package/dist/types/review.js.map +1 -0
- package/dist/types/run.d.ts +32 -0
- package/dist/types/run.js +6 -0
- package/dist/types/run.js.map +1 -0
- package/dist/types/task.d.ts +71 -0
- package/dist/types/task.js +6 -0
- package/dist/types/task.js.map +1 -0
- package/dist/ui/components.d.ts +134 -0
- package/dist/ui/components.js +389 -0
- package/dist/ui/components.js.map +1 -0
- package/dist/ui/log-viewer.d.ts +49 -0
- package/dist/ui/log-viewer.js +449 -0
- package/dist/ui/log-viewer.js.map +1 -0
- package/dist/utils/checkpoint.d.ts +87 -0
- package/dist/utils/checkpoint.js +317 -0
- package/dist/utils/checkpoint.js.map +1 -0
- package/dist/utils/config.d.ts +4 -0
- package/dist/utils/config.js +18 -8
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/cursor-agent.js.map +1 -1
- package/dist/utils/dependency.d.ts +74 -0
- package/dist/utils/dependency.js +420 -0
- package/dist/utils/dependency.js.map +1 -0
- package/dist/utils/doctor.js +17 -11
- package/dist/utils/doctor.js.map +1 -1
- package/dist/utils/enhanced-logger.d.ts +10 -33
- package/dist/utils/enhanced-logger.js +108 -20
- package/dist/utils/enhanced-logger.js.map +1 -1
- package/dist/utils/git.d.ts +121 -0
- package/dist/utils/git.js +484 -11
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/health.d.ts +91 -0
- package/dist/utils/health.js +556 -0
- package/dist/utils/health.js.map +1 -0
- package/dist/utils/lock.d.ts +95 -0
- package/dist/utils/lock.js +332 -0
- package/dist/utils/lock.js.map +1 -0
- package/dist/utils/log-buffer.d.ts +17 -0
- package/dist/utils/log-buffer.js +14 -0
- package/dist/utils/log-buffer.js.map +1 -0
- package/dist/utils/log-constants.d.ts +23 -0
- package/dist/utils/log-constants.js +28 -0
- package/dist/utils/log-constants.js.map +1 -0
- package/dist/utils/log-formatter.d.ts +25 -0
- package/dist/utils/log-formatter.js +237 -0
- package/dist/utils/log-formatter.js.map +1 -0
- package/dist/utils/log-service.d.ts +19 -0
- package/dist/utils/log-service.js +47 -0
- package/dist/utils/log-service.js.map +1 -0
- package/dist/utils/logger.d.ts +46 -27
- package/dist/utils/logger.js +82 -60
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/path.d.ts +19 -0
- package/dist/utils/path.js +77 -0
- package/dist/utils/path.js.map +1 -0
- package/dist/utils/process-manager.d.ts +21 -0
- package/dist/utils/process-manager.js +138 -0
- package/dist/utils/process-manager.js.map +1 -0
- package/dist/utils/retry.d.ts +121 -0
- package/dist/utils/retry.js +374 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/run-service.d.ts +88 -0
- package/dist/utils/run-service.js +412 -0
- package/dist/utils/run-service.js.map +1 -0
- package/dist/utils/state.d.ts +62 -3
- package/dist/utils/state.js +317 -11
- package/dist/utils/state.js.map +1 -1
- package/dist/utils/task-service.d.ts +82 -0
- package/dist/utils/task-service.js +348 -0
- package/dist/utils/task-service.js.map +1 -0
- package/dist/utils/template.d.ts +14 -0
- package/dist/utils/template.js +122 -0
- package/dist/utils/template.js.map +1 -0
- package/dist/utils/types.d.ts +2 -271
- package/dist/utils/types.js +16 -0
- package/dist/utils/types.js.map +1 -1
- package/package.json +38 -23
- package/scripts/ai-security-check.js +0 -1
- package/scripts/local-security-gate.sh +0 -0
- package/scripts/monitor-lanes.sh +94 -0
- package/scripts/patches/test-cursor-agent.js +0 -1
- package/scripts/release.sh +0 -0
- package/scripts/setup-security.sh +0 -0
- package/scripts/stream-logs.sh +72 -0
- package/scripts/verify-and-fix.sh +0 -0
- package/src/cli/clean.ts +187 -6
- package/src/cli/index.ts +12 -1
- package/src/cli/init.ts +8 -7
- package/src/cli/logs.ts +124 -77
- package/src/cli/monitor.ts +1815 -898
- package/src/cli/prepare.ts +41 -21
- package/src/cli/resume.ts +753 -626
- package/src/cli/run.ts +12 -5
- package/src/cli/runs.ts +212 -0
- package/src/cli/setup-commands.ts +0 -0
- package/src/cli/signal.ts +8 -7
- package/src/cli/stop.ts +209 -0
- package/src/cli/tasks.ts +154 -0
- package/src/core/auto-recovery.ts +909 -0
- package/src/core/failure-policy.ts +592 -0
- package/src/core/orchestrator.ts +1131 -704
- package/src/core/reviewer.ts +4 -0
- package/src/core/runner.ts +444 -180
- package/src/services/logging/buffer.ts +326 -0
- package/src/services/logging/console.ts +193 -0
- package/src/services/logging/file-writer.ts +526 -0
- package/src/services/logging/formatter.ts +268 -0
- package/src/services/logging/index.ts +16 -0
- package/src/services/logging/parser.ts +232 -0
- package/src/services/process/index.ts +261 -0
- package/src/types/agent.ts +24 -0
- package/src/types/config.ts +79 -0
- package/src/types/events.ts +156 -0
- package/src/types/index.ts +29 -0
- package/src/types/lane.ts +56 -0
- package/src/types/logging.ts +96 -0
- package/src/types/review.ts +20 -0
- package/src/types/run.ts +37 -0
- package/src/types/task.ts +79 -0
- package/src/ui/components.ts +430 -0
- package/src/ui/log-viewer.ts +485 -0
- package/src/utils/checkpoint.ts +374 -0
- package/src/utils/config.ts +18 -8
- package/src/utils/cursor-agent.ts +1 -1
- package/src/utils/dependency.ts +482 -0
- package/src/utils/doctor.ts +18 -11
- package/src/utils/enhanced-logger.ts +122 -60
- package/src/utils/git.ts +517 -11
- package/src/utils/health.ts +596 -0
- package/src/utils/lock.ts +346 -0
- package/src/utils/log-buffer.ts +28 -0
- package/src/utils/log-constants.ts +26 -0
- package/src/utils/log-formatter.ts +245 -0
- package/src/utils/log-service.ts +49 -0
- package/src/utils/logger.ts +100 -51
- package/src/utils/path.ts +45 -0
- package/src/utils/process-manager.ts +100 -0
- package/src/utils/retry.ts +413 -0
- package/src/utils/run-service.ts +433 -0
- package/src/utils/state.ts +385 -11
- package/src/utils/task-service.ts +370 -0
- package/src/utils/template.ts +92 -0
- package/src/utils/types.ts +2 -314
- package/templates/basic.json +21 -0
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
import * as fs from 'fs';
|
|
15
15
|
import * as path from 'path';
|
|
16
16
|
import { Transform, TransformCallback } from 'stream';
|
|
17
|
-
import
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
import * as logger from './logger';
|
|
18
|
+
import { EnhancedLogConfig, ParsedMessage, JsonLogEntry, LogSession } from '../types';
|
|
19
|
+
export { EnhancedLogConfig, ParsedMessage, JsonLogEntry, LogSession };
|
|
20
|
+
import { safeJoin } from './path';
|
|
21
21
|
|
|
22
22
|
export const DEFAULT_LOG_CONFIG: EnhancedLogConfig = {
|
|
23
23
|
enabled: true,
|
|
@@ -26,6 +26,8 @@ export const DEFAULT_LOG_CONFIG: EnhancedLogConfig = {
|
|
|
26
26
|
maxFileSize: 50 * 1024 * 1024, // 50MB
|
|
27
27
|
maxFiles: 5,
|
|
28
28
|
keepRawLogs: true,
|
|
29
|
+
keepAbsoluteRawLogs: false,
|
|
30
|
+
raw: false,
|
|
29
31
|
writeJsonLog: true,
|
|
30
32
|
timestampFormat: 'iso',
|
|
31
33
|
};
|
|
@@ -207,14 +209,6 @@ export class StreamingMessageParser {
|
|
|
207
209
|
}
|
|
208
210
|
}
|
|
209
211
|
|
|
210
|
-
export interface ParsedMessage {
|
|
211
|
-
type: 'system' | 'user' | 'assistant' | 'tool' | 'tool_result' | 'result' | 'thinking';
|
|
212
|
-
role: string;
|
|
213
|
-
content: string;
|
|
214
|
-
timestamp: number;
|
|
215
|
-
metadata?: Record<string, any>;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
212
|
/**
|
|
219
213
|
* ANSI escape sequence regex pattern
|
|
220
214
|
* Matches:
|
|
@@ -275,35 +269,12 @@ export function formatTimestamp(format: 'iso' | 'relative' | 'short', startTime?
|
|
|
275
269
|
}
|
|
276
270
|
|
|
277
271
|
/**
|
|
278
|
-
*
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
level: 'stdout' | 'stderr' | 'info' | 'error' | 'debug' | 'session';
|
|
283
|
-
source?: string;
|
|
284
|
-
task?: string;
|
|
285
|
-
lane?: string;
|
|
286
|
-
message: string;
|
|
287
|
-
raw?: string;
|
|
288
|
-
metadata?: Record<string, any>;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* Session context for logging
|
|
293
|
-
*/
|
|
294
|
-
export interface LogSession {
|
|
295
|
-
id: string;
|
|
296
|
-
laneName: string;
|
|
297
|
-
taskName?: string;
|
|
298
|
-
model?: string;
|
|
299
|
-
startTime: number;
|
|
300
|
-
metadata?: Record<string, any>;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Regex to detect if a line already has an ISO timestamp at the start
|
|
272
|
+
* Regex to detect if a line already has a timestamp at the start
|
|
273
|
+
* Matches:
|
|
274
|
+
* - ISO format: [2024-01-01T12:34:56...]
|
|
275
|
+
* - Short format: [12:34:56]
|
|
305
276
|
*/
|
|
306
|
-
const EXISTING_TIMESTAMP_REGEX = /^\[\d{4}-\d{2}-\d{2}T
|
|
277
|
+
const EXISTING_TIMESTAMP_REGEX = /^\[(\d{4}-\d{2}-\d{2}T)?\d{2}:\d{2}:\d{2}/;
|
|
307
278
|
|
|
308
279
|
/**
|
|
309
280
|
* Check if a line already has a timestamp
|
|
@@ -387,16 +358,19 @@ export class EnhancedLogManager {
|
|
|
387
358
|
|
|
388
359
|
private cleanLogPath: string;
|
|
389
360
|
private rawLogPath: string;
|
|
361
|
+
private absoluteRawLogPath: string;
|
|
390
362
|
private jsonLogPath: string;
|
|
391
363
|
private readableLogPath: string;
|
|
392
364
|
|
|
393
365
|
private cleanLogFd: number | null = null;
|
|
394
366
|
private rawLogFd: number | null = null;
|
|
367
|
+
private absoluteRawLogFd: number | null = null;
|
|
395
368
|
private jsonLogFd: number | null = null;
|
|
396
369
|
private readableLogFd: number | null = null;
|
|
397
370
|
|
|
398
371
|
private cleanLogSize: number = 0;
|
|
399
372
|
private rawLogSize: number = 0;
|
|
373
|
+
private absoluteRawLogSize: number = 0;
|
|
400
374
|
|
|
401
375
|
private cleanTransform: CleanLogTransform | null = null;
|
|
402
376
|
private streamingParser: StreamingMessageParser | null = null;
|
|
@@ -405,6 +379,12 @@ export class EnhancedLogManager {
|
|
|
405
379
|
|
|
406
380
|
constructor(logDir: string, session: LogSession, config: Partial<EnhancedLogConfig> = {}, onParsedMessage?: (msg: ParsedMessage) => void) {
|
|
407
381
|
this.config = { ...DEFAULT_LOG_CONFIG, ...config };
|
|
382
|
+
|
|
383
|
+
// Support 'raw' as alias for 'keepAbsoluteRawLogs'
|
|
384
|
+
if (this.config.raw) {
|
|
385
|
+
this.config.keepAbsoluteRawLogs = true;
|
|
386
|
+
}
|
|
387
|
+
|
|
408
388
|
this.session = session;
|
|
409
389
|
this.logDir = logDir;
|
|
410
390
|
this.onParsedMessage = onParsedMessage;
|
|
@@ -413,10 +393,15 @@ export class EnhancedLogManager {
|
|
|
413
393
|
fs.mkdirSync(logDir, { recursive: true });
|
|
414
394
|
|
|
415
395
|
// Set up log file paths
|
|
416
|
-
this.cleanLogPath =
|
|
417
|
-
this.rawLogPath =
|
|
418
|
-
this.
|
|
419
|
-
this.
|
|
396
|
+
this.cleanLogPath = safeJoin(logDir, 'terminal.log');
|
|
397
|
+
this.rawLogPath = safeJoin(logDir, 'terminal-raw.log');
|
|
398
|
+
this.absoluteRawLogPath = safeJoin(logDir, 'terminal-absolute-raw.log');
|
|
399
|
+
this.jsonLogPath = safeJoin(logDir, 'terminal.jsonl');
|
|
400
|
+
this.readableLogPath = safeJoin(logDir, 'terminal-readable.log');
|
|
401
|
+
|
|
402
|
+
if (this.config.raw) {
|
|
403
|
+
logger.info(`[${session.laneName}] 📄 Raw data capture enabled: ${this.absoluteRawLogPath}`);
|
|
404
|
+
}
|
|
420
405
|
|
|
421
406
|
// Initialize log files
|
|
422
407
|
this.initLogFiles();
|
|
@@ -431,6 +416,9 @@ export class EnhancedLogManager {
|
|
|
431
416
|
if (this.config.keepRawLogs) {
|
|
432
417
|
this.rotateIfNeeded(this.rawLogPath, 'raw');
|
|
433
418
|
}
|
|
419
|
+
if (this.config.keepAbsoluteRawLogs) {
|
|
420
|
+
this.rotateIfNeeded(this.absoluteRawLogPath, 'raw');
|
|
421
|
+
}
|
|
434
422
|
|
|
435
423
|
// Open file descriptors
|
|
436
424
|
this.cleanLogFd = fs.openSync(this.cleanLogPath, 'a');
|
|
@@ -438,6 +426,10 @@ export class EnhancedLogManager {
|
|
|
438
426
|
if (this.config.keepRawLogs) {
|
|
439
427
|
this.rawLogFd = fs.openSync(this.rawLogPath, 'a');
|
|
440
428
|
}
|
|
429
|
+
|
|
430
|
+
if (this.config.keepAbsoluteRawLogs) {
|
|
431
|
+
this.absoluteRawLogFd = fs.openSync(this.absoluteRawLogPath, 'a');
|
|
432
|
+
}
|
|
441
433
|
|
|
442
434
|
if (this.config.writeJsonLog) {
|
|
443
435
|
this.jsonLogFd = fs.openSync(this.jsonLogPath, 'a');
|
|
@@ -452,9 +444,13 @@ export class EnhancedLogManager {
|
|
|
452
444
|
if (this.config.keepRawLogs) {
|
|
453
445
|
this.rawLogSize = fs.statSync(this.rawLogPath).size;
|
|
454
446
|
}
|
|
447
|
+
if (this.config.keepAbsoluteRawLogs) {
|
|
448
|
+
this.absoluteRawLogSize = fs.statSync(this.absoluteRawLogPath).size;
|
|
449
|
+
}
|
|
455
450
|
} catch {
|
|
456
451
|
this.cleanLogSize = 0;
|
|
457
452
|
this.rawLogSize = 0;
|
|
453
|
+
this.absoluteRawLogSize = 0;
|
|
458
454
|
}
|
|
459
455
|
|
|
460
456
|
// Write session header
|
|
@@ -620,8 +616,8 @@ export class EnhancedLogManager {
|
|
|
620
616
|
|
|
621
617
|
// Shift existing rotated files
|
|
622
618
|
for (let i = this.config.maxFiles - 1; i >= 1; i--) {
|
|
623
|
-
const oldPath =
|
|
624
|
-
const newPath =
|
|
619
|
+
const oldPath = safeJoin(dir, `${base}.${i}${ext}`);
|
|
620
|
+
const newPath = safeJoin(dir, `${base}.${i + 1}${ext}`);
|
|
625
621
|
|
|
626
622
|
if (fs.existsSync(oldPath)) {
|
|
627
623
|
if (i === this.config.maxFiles - 1) {
|
|
@@ -633,7 +629,7 @@ export class EnhancedLogManager {
|
|
|
633
629
|
}
|
|
634
630
|
|
|
635
631
|
// Rotate current to .1
|
|
636
|
-
const rotatedPath =
|
|
632
|
+
const rotatedPath = safeJoin(dir, `${base}.1${ext}`);
|
|
637
633
|
fs.renameSync(logPath, rotatedPath);
|
|
638
634
|
}
|
|
639
635
|
|
|
@@ -675,6 +671,25 @@ export class EnhancedLogManager {
|
|
|
675
671
|
}
|
|
676
672
|
}
|
|
677
673
|
|
|
674
|
+
/**
|
|
675
|
+
* Write to absolute raw log with size tracking
|
|
676
|
+
*/
|
|
677
|
+
private writeToAbsoluteRawLog(data: string | Buffer): void {
|
|
678
|
+
if (this.absoluteRawLogFd === null) return;
|
|
679
|
+
|
|
680
|
+
const buffer = typeof data === 'string' ? Buffer.from(data) : data;
|
|
681
|
+
fs.writeSync(this.absoluteRawLogFd, buffer);
|
|
682
|
+
this.absoluteRawLogSize += buffer.length;
|
|
683
|
+
|
|
684
|
+
// Check if rotation needed
|
|
685
|
+
if (this.absoluteRawLogSize >= this.config.maxFileSize) {
|
|
686
|
+
fs.closeSync(this.absoluteRawLogFd);
|
|
687
|
+
this.rotateLog(this.absoluteRawLogPath);
|
|
688
|
+
this.absoluteRawLogFd = fs.openSync(this.absoluteRawLogPath, 'a');
|
|
689
|
+
this.absoluteRawLogSize = 0;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
|
|
678
693
|
/**
|
|
679
694
|
* Write a JSON log entry
|
|
680
695
|
*/
|
|
@@ -691,6 +706,11 @@ export class EnhancedLogManager {
|
|
|
691
706
|
public writeStdout(data: Buffer | string): void {
|
|
692
707
|
const text = data.toString();
|
|
693
708
|
|
|
709
|
+
// Write absolute raw log
|
|
710
|
+
if (this.config.keepAbsoluteRawLogs) {
|
|
711
|
+
this.writeToAbsoluteRawLog(data);
|
|
712
|
+
}
|
|
713
|
+
|
|
694
714
|
// Write raw log
|
|
695
715
|
if (this.config.keepRawLogs) {
|
|
696
716
|
this.writeToRawLog(text);
|
|
@@ -710,7 +730,7 @@ export class EnhancedLogManager {
|
|
|
710
730
|
const cleanLine = stripAnsi(line).trim();
|
|
711
731
|
if (!cleanLine) continue;
|
|
712
732
|
|
|
713
|
-
// Handle streaming JSON messages
|
|
733
|
+
// Handle streaming JSON messages
|
|
714
734
|
if (cleanLine.startsWith('{')) {
|
|
715
735
|
if (this.streamingParser) {
|
|
716
736
|
this.streamingParser.parseLine(cleanLine);
|
|
@@ -724,8 +744,10 @@ export class EnhancedLogManager {
|
|
|
724
744
|
let metadata = { ...json };
|
|
725
745
|
|
|
726
746
|
// Extract cleaner text for significant AI message types
|
|
727
|
-
if (json.type === 'thinking' && json.text) {
|
|
728
|
-
displayMsg = json.text;
|
|
747
|
+
if ((json.type === 'thinking' || json.type === 'thought') && (json.text || json.thought)) {
|
|
748
|
+
displayMsg = json.text || json.thought;
|
|
749
|
+
// Clean up any double newlines at the end of deltas
|
|
750
|
+
displayMsg = displayMsg.replace(/\n+$/, '\n');
|
|
729
751
|
} else if (json.type === 'assistant' && json.message?.content) {
|
|
730
752
|
displayMsg = json.message.content
|
|
731
753
|
.filter((c: any) => c.type === 'text')
|
|
@@ -760,6 +782,25 @@ export class EnhancedLogManager {
|
|
|
760
782
|
// Not valid JSON or error, fall through to regular logging
|
|
761
783
|
}
|
|
762
784
|
}
|
|
785
|
+
} else {
|
|
786
|
+
// Parse standard text logs into ParsedMessage
|
|
787
|
+
// Format: [HH:MM:SS] [LANE] ℹ️ INFO message
|
|
788
|
+
const textLogRegex = /^\[(\d{2}:\d{2}:\d{2})\]\s+\[(.*?)\]\s+(.*?)\s+(INFO|WARN|ERROR|SUCCESS|DONE|PROGRESS)\s+(.*)/;
|
|
789
|
+
const match = cleanLine.match(textLogRegex);
|
|
790
|
+
|
|
791
|
+
if (match && this.onParsedMessage) {
|
|
792
|
+
const [, time, , emoji, level, content] = match;
|
|
793
|
+
// Convert HH:MM:SS to a timestamp for today
|
|
794
|
+
const [h, m, s] = time!.split(':').map(Number);
|
|
795
|
+
const timestamp = new Date().setHours(h!, m!, s!, 0);
|
|
796
|
+
|
|
797
|
+
this.onParsedMessage({
|
|
798
|
+
type: level!.toLowerCase().replace('done', 'result').replace('success', 'result') as any,
|
|
799
|
+
role: 'system',
|
|
800
|
+
content: `${emoji} ${content}`,
|
|
801
|
+
timestamp,
|
|
802
|
+
});
|
|
803
|
+
}
|
|
763
804
|
}
|
|
764
805
|
|
|
765
806
|
// Also include significant info/status lines in readable log (compact)
|
|
@@ -809,6 +850,11 @@ export class EnhancedLogManager {
|
|
|
809
850
|
public writeStderr(data: Buffer | string): void {
|
|
810
851
|
const text = data.toString();
|
|
811
852
|
|
|
853
|
+
// Write absolute raw log
|
|
854
|
+
if (this.config.keepAbsoluteRawLogs) {
|
|
855
|
+
this.writeToAbsoluteRawLog(data);
|
|
856
|
+
}
|
|
857
|
+
|
|
812
858
|
// Write raw log
|
|
813
859
|
if (this.config.keepRawLogs) {
|
|
814
860
|
this.writeToRawLog(text);
|
|
@@ -853,7 +899,7 @@ export class EnhancedLogManager {
|
|
|
853
899
|
*/
|
|
854
900
|
public log(level: 'info' | 'error' | 'debug', message: string, metadata?: Record<string, any>): void {
|
|
855
901
|
const ts = formatTimestamp(this.config.timestampFormat, this.session.startTime);
|
|
856
|
-
const prefix = level.toUpperCase().padEnd(
|
|
902
|
+
const prefix = level.toUpperCase().padEnd(8);
|
|
857
903
|
|
|
858
904
|
const line = `[${ts}] [${prefix}] ${message}\n`;
|
|
859
905
|
this.writeToCleanLog(line);
|
|
@@ -862,6 +908,10 @@ export class EnhancedLogManager {
|
|
|
862
908
|
this.writeToRawLog(line);
|
|
863
909
|
}
|
|
864
910
|
|
|
911
|
+
if (this.config.keepAbsoluteRawLogs) {
|
|
912
|
+
this.writeToAbsoluteRawLog(line);
|
|
913
|
+
}
|
|
914
|
+
|
|
865
915
|
// Write to readable log (compact)
|
|
866
916
|
if (this.readableLogFd !== null) {
|
|
867
917
|
const typeLabel = level === 'error' ? '❌ ERROR' : level === 'info' ? 'ℹ️ INFO' : '🔍 DEBUG';
|
|
@@ -894,6 +944,9 @@ export class EnhancedLogManager {
|
|
|
894
944
|
if (this.config.keepRawLogs) {
|
|
895
945
|
this.writeToRawLog(line);
|
|
896
946
|
}
|
|
947
|
+
if (this.config.keepAbsoluteRawLogs) {
|
|
948
|
+
this.writeToAbsoluteRawLog(line);
|
|
949
|
+
}
|
|
897
950
|
|
|
898
951
|
// Write to readable log (compact)
|
|
899
952
|
if (this.readableLogFd !== null) {
|
|
@@ -951,10 +1004,11 @@ export class EnhancedLogManager {
|
|
|
951
1004
|
/**
|
|
952
1005
|
* Get paths to all log files
|
|
953
1006
|
*/
|
|
954
|
-
public getLogPaths(): { clean: string; raw?: string; json?: string; readable: string } {
|
|
1007
|
+
public getLogPaths(): { clean: string; raw?: string; absoluteRaw?: string; json?: string; readable: string } {
|
|
955
1008
|
return {
|
|
956
1009
|
clean: this.cleanLogPath,
|
|
957
1010
|
raw: this.config.keepRawLogs ? this.rawLogPath : undefined,
|
|
1011
|
+
absoluteRaw: this.config.keepAbsoluteRawLogs ? this.absoluteRawLogPath : undefined,
|
|
958
1012
|
json: this.config.writeJsonLog ? this.jsonLogPath : undefined,
|
|
959
1013
|
readable: this.readableLogPath,
|
|
960
1014
|
};
|
|
@@ -1008,6 +1062,11 @@ export class EnhancedLogManager {
|
|
|
1008
1062
|
this.rawLogFd = null;
|
|
1009
1063
|
}
|
|
1010
1064
|
|
|
1065
|
+
if (this.absoluteRawLogFd !== null) {
|
|
1066
|
+
fs.closeSync(this.absoluteRawLogFd);
|
|
1067
|
+
this.absoluteRawLogFd = null;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1011
1070
|
if (this.jsonLogFd !== null) {
|
|
1012
1071
|
this.writeJsonEntry({
|
|
1013
1072
|
timestamp: new Date().toISOString(),
|
|
@@ -1101,8 +1160,8 @@ export function exportLogs(
|
|
|
1101
1160
|
format: 'text' | 'json' | 'markdown' | 'html',
|
|
1102
1161
|
outputPath?: string
|
|
1103
1162
|
): string {
|
|
1104
|
-
const cleanLogPath =
|
|
1105
|
-
const jsonLogPath =
|
|
1163
|
+
const cleanLogPath = safeJoin(laneRunDir, 'terminal.log');
|
|
1164
|
+
const jsonLogPath = safeJoin(laneRunDir, 'terminal.jsonl');
|
|
1106
1165
|
|
|
1107
1166
|
let output = '';
|
|
1108
1167
|
|
|
@@ -1168,8 +1227,10 @@ function exportToMarkdown(jsonLogPath: string, cleanLogPath: string): string {
|
|
|
1168
1227
|
md += `### Task: ${task}\n\n`;
|
|
1169
1228
|
md += '```\n';
|
|
1170
1229
|
for (const entry of taskEntries) {
|
|
1171
|
-
|
|
1172
|
-
|
|
1230
|
+
const level = entry.level || 'info';
|
|
1231
|
+
const message = entry.message || '';
|
|
1232
|
+
if (level !== 'session') {
|
|
1233
|
+
md += `[${entry.timestamp}] [${level.toUpperCase()}] ${message}\n`;
|
|
1173
1234
|
}
|
|
1174
1235
|
}
|
|
1175
1236
|
md += '```\n\n';
|
|
@@ -1208,11 +1269,13 @@ function exportToHtml(jsonLogPath: string, cleanLogPath: string): string {
|
|
|
1208
1269
|
`;
|
|
1209
1270
|
|
|
1210
1271
|
for (const entry of entries) {
|
|
1211
|
-
|
|
1272
|
+
const level = entry.level || 'info';
|
|
1273
|
+
const message = entry.message || '';
|
|
1274
|
+
html += ` <div class="entry ${level}">
|
|
1212
1275
|
<span class="timestamp">${entry.timestamp}</span>
|
|
1213
|
-
<span class="level">[${
|
|
1276
|
+
<span class="level">[${level}]</span>
|
|
1214
1277
|
${entry.task ? `<span class="task">[${entry.task}]</span>` : ''}
|
|
1215
|
-
<pre>${escapeHtml(
|
|
1278
|
+
<pre>${escapeHtml(message)}</pre>
|
|
1216
1279
|
</div>\n`;
|
|
1217
1280
|
}
|
|
1218
1281
|
|
|
@@ -1228,4 +1291,3 @@ function escapeHtml(text: string): string {
|
|
|
1228
1291
|
.replace(/"/g, '"')
|
|
1229
1292
|
.replace(/'/g, ''');
|
|
1230
1293
|
}
|
|
1231
|
-
|