@litmers/cursorflow-orchestrator 0.1.20 → 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.
Files changed (224) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/commands/cursorflow-clean.md +19 -0
  3. package/commands/cursorflow-runs.md +59 -0
  4. package/commands/cursorflow-stop.md +55 -0
  5. package/dist/cli/clean.js +171 -0
  6. package/dist/cli/clean.js.map +1 -1
  7. package/dist/cli/index.js +7 -0
  8. package/dist/cli/index.js.map +1 -1
  9. package/dist/cli/init.js +1 -1
  10. package/dist/cli/init.js.map +1 -1
  11. package/dist/cli/logs.js +83 -42
  12. package/dist/cli/logs.js.map +1 -1
  13. package/dist/cli/monitor.d.ts +7 -0
  14. package/dist/cli/monitor.js +1007 -189
  15. package/dist/cli/monitor.js.map +1 -1
  16. package/dist/cli/prepare.js +4 -3
  17. package/dist/cli/prepare.js.map +1 -1
  18. package/dist/cli/resume.js +188 -236
  19. package/dist/cli/resume.js.map +1 -1
  20. package/dist/cli/run.js +8 -3
  21. package/dist/cli/run.js.map +1 -1
  22. package/dist/cli/runs.d.ts +5 -0
  23. package/dist/cli/runs.js +214 -0
  24. package/dist/cli/runs.js.map +1 -0
  25. package/dist/cli/setup-commands.js +0 -0
  26. package/dist/cli/signal.js +1 -1
  27. package/dist/cli/signal.js.map +1 -1
  28. package/dist/cli/stop.d.ts +5 -0
  29. package/dist/cli/stop.js +215 -0
  30. package/dist/cli/stop.js.map +1 -0
  31. package/dist/cli/tasks.d.ts +10 -0
  32. package/dist/cli/tasks.js +165 -0
  33. package/dist/cli/tasks.js.map +1 -0
  34. package/dist/core/auto-recovery.d.ts +212 -0
  35. package/dist/core/auto-recovery.js +737 -0
  36. package/dist/core/auto-recovery.js.map +1 -0
  37. package/dist/core/failure-policy.d.ts +156 -0
  38. package/dist/core/failure-policy.js +488 -0
  39. package/dist/core/failure-policy.js.map +1 -0
  40. package/dist/core/orchestrator.d.ts +15 -2
  41. package/dist/core/orchestrator.js +392 -15
  42. package/dist/core/orchestrator.js.map +1 -1
  43. package/dist/core/reviewer.d.ts +2 -0
  44. package/dist/core/reviewer.js +2 -0
  45. package/dist/core/reviewer.js.map +1 -1
  46. package/dist/core/runner.d.ts +33 -10
  47. package/dist/core/runner.js +321 -146
  48. package/dist/core/runner.js.map +1 -1
  49. package/dist/services/logging/buffer.d.ts +67 -0
  50. package/dist/services/logging/buffer.js +309 -0
  51. package/dist/services/logging/buffer.js.map +1 -0
  52. package/dist/services/logging/console.d.ts +89 -0
  53. package/dist/services/logging/console.js +169 -0
  54. package/dist/services/logging/console.js.map +1 -0
  55. package/dist/services/logging/file-writer.d.ts +71 -0
  56. package/dist/services/logging/file-writer.js +516 -0
  57. package/dist/services/logging/file-writer.js.map +1 -0
  58. package/dist/services/logging/formatter.d.ts +39 -0
  59. package/dist/services/logging/formatter.js +227 -0
  60. package/dist/services/logging/formatter.js.map +1 -0
  61. package/dist/services/logging/index.d.ts +11 -0
  62. package/dist/services/logging/index.js +30 -0
  63. package/dist/services/logging/index.js.map +1 -0
  64. package/dist/services/logging/parser.d.ts +31 -0
  65. package/dist/services/logging/parser.js +222 -0
  66. package/dist/services/logging/parser.js.map +1 -0
  67. package/dist/services/process/index.d.ts +59 -0
  68. package/dist/services/process/index.js +257 -0
  69. package/dist/services/process/index.js.map +1 -0
  70. package/dist/types/agent.d.ts +20 -0
  71. package/dist/types/agent.js +6 -0
  72. package/dist/types/agent.js.map +1 -0
  73. package/dist/types/config.d.ts +65 -0
  74. package/dist/types/config.js +6 -0
  75. package/dist/types/config.js.map +1 -0
  76. package/dist/types/events.d.ts +125 -0
  77. package/dist/types/events.js +6 -0
  78. package/dist/types/events.js.map +1 -0
  79. package/dist/types/index.d.ts +12 -0
  80. package/dist/types/index.js +37 -0
  81. package/dist/types/index.js.map +1 -0
  82. package/dist/types/lane.d.ts +43 -0
  83. package/dist/types/lane.js +6 -0
  84. package/dist/types/lane.js.map +1 -0
  85. package/dist/types/logging.d.ts +71 -0
  86. package/dist/types/logging.js +16 -0
  87. package/dist/types/logging.js.map +1 -0
  88. package/dist/types/review.d.ts +17 -0
  89. package/dist/types/review.js +6 -0
  90. package/dist/types/review.js.map +1 -0
  91. package/dist/types/run.d.ts +32 -0
  92. package/dist/types/run.js +6 -0
  93. package/dist/types/run.js.map +1 -0
  94. package/dist/types/task.d.ts +71 -0
  95. package/dist/types/task.js +6 -0
  96. package/dist/types/task.js.map +1 -0
  97. package/dist/ui/components.d.ts +134 -0
  98. package/dist/ui/components.js +389 -0
  99. package/dist/ui/components.js.map +1 -0
  100. package/dist/ui/log-viewer.d.ts +49 -0
  101. package/dist/ui/log-viewer.js +449 -0
  102. package/dist/ui/log-viewer.js.map +1 -0
  103. package/dist/utils/checkpoint.d.ts +87 -0
  104. package/dist/utils/checkpoint.js +317 -0
  105. package/dist/utils/checkpoint.js.map +1 -0
  106. package/dist/utils/config.d.ts +4 -0
  107. package/dist/utils/config.js +11 -2
  108. package/dist/utils/config.js.map +1 -1
  109. package/dist/utils/cursor-agent.js.map +1 -1
  110. package/dist/utils/dependency.d.ts +74 -0
  111. package/dist/utils/dependency.js +420 -0
  112. package/dist/utils/dependency.js.map +1 -0
  113. package/dist/utils/doctor.js +10 -5
  114. package/dist/utils/doctor.js.map +1 -1
  115. package/dist/utils/enhanced-logger.d.ts +10 -33
  116. package/dist/utils/enhanced-logger.js +94 -9
  117. package/dist/utils/enhanced-logger.js.map +1 -1
  118. package/dist/utils/git.d.ts +121 -0
  119. package/dist/utils/git.js +322 -2
  120. package/dist/utils/git.js.map +1 -1
  121. package/dist/utils/health.d.ts +91 -0
  122. package/dist/utils/health.js +556 -0
  123. package/dist/utils/health.js.map +1 -0
  124. package/dist/utils/lock.d.ts +95 -0
  125. package/dist/utils/lock.js +332 -0
  126. package/dist/utils/lock.js.map +1 -0
  127. package/dist/utils/log-buffer.d.ts +17 -0
  128. package/dist/utils/log-buffer.js +14 -0
  129. package/dist/utils/log-buffer.js.map +1 -0
  130. package/dist/utils/log-constants.d.ts +23 -0
  131. package/dist/utils/log-constants.js +28 -0
  132. package/dist/utils/log-constants.js.map +1 -0
  133. package/dist/utils/log-formatter.d.ts +9 -0
  134. package/dist/utils/log-formatter.js +113 -70
  135. package/dist/utils/log-formatter.js.map +1 -1
  136. package/dist/utils/log-service.d.ts +19 -0
  137. package/dist/utils/log-service.js +47 -0
  138. package/dist/utils/log-service.js.map +1 -0
  139. package/dist/utils/logger.d.ts +46 -27
  140. package/dist/utils/logger.js +82 -60
  141. package/dist/utils/logger.js.map +1 -1
  142. package/dist/utils/process-manager.d.ts +21 -0
  143. package/dist/utils/process-manager.js +138 -0
  144. package/dist/utils/process-manager.js.map +1 -0
  145. package/dist/utils/retry.d.ts +121 -0
  146. package/dist/utils/retry.js +374 -0
  147. package/dist/utils/retry.js.map +1 -0
  148. package/dist/utils/run-service.d.ts +88 -0
  149. package/dist/utils/run-service.js +412 -0
  150. package/dist/utils/run-service.js.map +1 -0
  151. package/dist/utils/state.d.ts +58 -2
  152. package/dist/utils/state.js +306 -3
  153. package/dist/utils/state.js.map +1 -1
  154. package/dist/utils/task-service.d.ts +82 -0
  155. package/dist/utils/task-service.js +348 -0
  156. package/dist/utils/task-service.js.map +1 -0
  157. package/dist/utils/types.d.ts +2 -272
  158. package/dist/utils/types.js +16 -0
  159. package/dist/utils/types.js.map +1 -1
  160. package/package.json +38 -23
  161. package/scripts/ai-security-check.js +0 -1
  162. package/scripts/local-security-gate.sh +0 -0
  163. package/scripts/monitor-lanes.sh +94 -0
  164. package/scripts/patches/test-cursor-agent.js +0 -1
  165. package/scripts/release.sh +0 -0
  166. package/scripts/setup-security.sh +0 -0
  167. package/scripts/stream-logs.sh +72 -0
  168. package/scripts/verify-and-fix.sh +0 -0
  169. package/src/cli/clean.ts +180 -0
  170. package/src/cli/index.ts +7 -0
  171. package/src/cli/init.ts +1 -1
  172. package/src/cli/logs.ts +79 -42
  173. package/src/cli/monitor.ts +1815 -899
  174. package/src/cli/prepare.ts +4 -3
  175. package/src/cli/resume.ts +220 -277
  176. package/src/cli/run.ts +9 -3
  177. package/src/cli/runs.ts +212 -0
  178. package/src/cli/setup-commands.ts +0 -0
  179. package/src/cli/signal.ts +1 -1
  180. package/src/cli/stop.ts +209 -0
  181. package/src/cli/tasks.ts +154 -0
  182. package/src/core/auto-recovery.ts +909 -0
  183. package/src/core/failure-policy.ts +592 -0
  184. package/src/core/orchestrator.ts +1131 -675
  185. package/src/core/reviewer.ts +4 -0
  186. package/src/core/runner.ts +388 -162
  187. package/src/services/logging/buffer.ts +326 -0
  188. package/src/services/logging/console.ts +193 -0
  189. package/src/services/logging/file-writer.ts +526 -0
  190. package/src/services/logging/formatter.ts +268 -0
  191. package/src/services/logging/index.ts +16 -0
  192. package/src/services/logging/parser.ts +232 -0
  193. package/src/services/process/index.ts +261 -0
  194. package/src/types/agent.ts +24 -0
  195. package/src/types/config.ts +79 -0
  196. package/src/types/events.ts +156 -0
  197. package/src/types/index.ts +29 -0
  198. package/src/types/lane.ts +56 -0
  199. package/src/types/logging.ts +96 -0
  200. package/src/types/review.ts +20 -0
  201. package/src/types/run.ts +37 -0
  202. package/src/types/task.ts +79 -0
  203. package/src/ui/components.ts +430 -0
  204. package/src/ui/log-viewer.ts +485 -0
  205. package/src/utils/checkpoint.ts +374 -0
  206. package/src/utils/config.ts +11 -2
  207. package/src/utils/cursor-agent.ts +1 -1
  208. package/src/utils/dependency.ts +482 -0
  209. package/src/utils/doctor.ts +11 -5
  210. package/src/utils/enhanced-logger.ts +108 -49
  211. package/src/utils/git.ts +374 -2
  212. package/src/utils/health.ts +596 -0
  213. package/src/utils/lock.ts +346 -0
  214. package/src/utils/log-buffer.ts +28 -0
  215. package/src/utils/log-constants.ts +26 -0
  216. package/src/utils/log-formatter.ts +120 -37
  217. package/src/utils/log-service.ts +49 -0
  218. package/src/utils/logger.ts +100 -51
  219. package/src/utils/process-manager.ts +100 -0
  220. package/src/utils/retry.ts +413 -0
  221. package/src/utils/run-service.ts +433 -0
  222. package/src/utils/state.ts +369 -3
  223. package/src/utils/task-service.ts +370 -0
  224. package/src/utils/types.ts +2 -315
@@ -14,12 +14,11 @@
14
14
  import * as fs from 'fs';
15
15
  import * as path from 'path';
16
16
  import { Transform, TransformCallback } from 'stream';
17
- import { EnhancedLogConfig } from './types';
17
+ import * as logger from './logger';
18
+ import { EnhancedLogConfig, ParsedMessage, JsonLogEntry, LogSession } from '../types';
19
+ export { EnhancedLogConfig, ParsedMessage, JsonLogEntry, LogSession };
18
20
  import { safeJoin } from './path';
19
21
 
20
- // Re-export for backwards compatibility
21
- export { EnhancedLogConfig } from './types';
22
-
23
22
  export const DEFAULT_LOG_CONFIG: EnhancedLogConfig = {
24
23
  enabled: true,
25
24
  stripAnsi: true,
@@ -27,6 +26,8 @@ export const DEFAULT_LOG_CONFIG: EnhancedLogConfig = {
27
26
  maxFileSize: 50 * 1024 * 1024, // 50MB
28
27
  maxFiles: 5,
29
28
  keepRawLogs: true,
29
+ keepAbsoluteRawLogs: false,
30
+ raw: false,
30
31
  writeJsonLog: true,
31
32
  timestampFormat: 'iso',
32
33
  };
@@ -208,14 +209,6 @@ export class StreamingMessageParser {
208
209
  }
209
210
  }
210
211
 
211
- export interface ParsedMessage {
212
- type: 'system' | 'user' | 'assistant' | 'tool' | 'tool_result' | 'result' | 'thinking';
213
- role: string;
214
- content: string;
215
- timestamp: number;
216
- metadata?: Record<string, any>;
217
- }
218
-
219
212
  /**
220
213
  * ANSI escape sequence regex pattern
221
214
  * Matches:
@@ -276,35 +269,12 @@ export function formatTimestamp(format: 'iso' | 'relative' | 'short', startTime?
276
269
  }
277
270
 
278
271
  /**
279
- * JSON log entry structure
280
- */
281
- export interface JsonLogEntry {
282
- timestamp: string;
283
- level: 'stdout' | 'stderr' | 'info' | 'error' | 'debug' | 'session';
284
- source?: string;
285
- task?: string;
286
- lane?: string;
287
- message: string;
288
- raw?: string;
289
- metadata?: Record<string, any>;
290
- }
291
-
292
- /**
293
- * Session context for logging
294
- */
295
- export interface LogSession {
296
- id: string;
297
- laneName: string;
298
- taskName?: string;
299
- model?: string;
300
- startTime: number;
301
- metadata?: Record<string, any>;
302
- }
303
-
304
- /**
305
- * 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]
306
276
  */
307
- const EXISTING_TIMESTAMP_REGEX = /^\[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/;
277
+ const EXISTING_TIMESTAMP_REGEX = /^\[(\d{4}-\d{2}-\d{2}T)?\d{2}:\d{2}:\d{2}/;
308
278
 
309
279
  /**
310
280
  * Check if a line already has a timestamp
@@ -388,16 +358,19 @@ export class EnhancedLogManager {
388
358
 
389
359
  private cleanLogPath: string;
390
360
  private rawLogPath: string;
361
+ private absoluteRawLogPath: string;
391
362
  private jsonLogPath: string;
392
363
  private readableLogPath: string;
393
364
 
394
365
  private cleanLogFd: number | null = null;
395
366
  private rawLogFd: number | null = null;
367
+ private absoluteRawLogFd: number | null = null;
396
368
  private jsonLogFd: number | null = null;
397
369
  private readableLogFd: number | null = null;
398
370
 
399
371
  private cleanLogSize: number = 0;
400
372
  private rawLogSize: number = 0;
373
+ private absoluteRawLogSize: number = 0;
401
374
 
402
375
  private cleanTransform: CleanLogTransform | null = null;
403
376
  private streamingParser: StreamingMessageParser | null = null;
@@ -406,6 +379,12 @@ export class EnhancedLogManager {
406
379
 
407
380
  constructor(logDir: string, session: LogSession, config: Partial<EnhancedLogConfig> = {}, onParsedMessage?: (msg: ParsedMessage) => void) {
408
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
+
409
388
  this.session = session;
410
389
  this.logDir = logDir;
411
390
  this.onParsedMessage = onParsedMessage;
@@ -416,8 +395,13 @@ export class EnhancedLogManager {
416
395
  // Set up log file paths
417
396
  this.cleanLogPath = safeJoin(logDir, 'terminal.log');
418
397
  this.rawLogPath = safeJoin(logDir, 'terminal-raw.log');
398
+ this.absoluteRawLogPath = safeJoin(logDir, 'terminal-absolute-raw.log');
419
399
  this.jsonLogPath = safeJoin(logDir, 'terminal.jsonl');
420
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
+ }
421
405
 
422
406
  // Initialize log files
423
407
  this.initLogFiles();
@@ -432,6 +416,9 @@ export class EnhancedLogManager {
432
416
  if (this.config.keepRawLogs) {
433
417
  this.rotateIfNeeded(this.rawLogPath, 'raw');
434
418
  }
419
+ if (this.config.keepAbsoluteRawLogs) {
420
+ this.rotateIfNeeded(this.absoluteRawLogPath, 'raw');
421
+ }
435
422
 
436
423
  // Open file descriptors
437
424
  this.cleanLogFd = fs.openSync(this.cleanLogPath, 'a');
@@ -439,6 +426,10 @@ export class EnhancedLogManager {
439
426
  if (this.config.keepRawLogs) {
440
427
  this.rawLogFd = fs.openSync(this.rawLogPath, 'a');
441
428
  }
429
+
430
+ if (this.config.keepAbsoluteRawLogs) {
431
+ this.absoluteRawLogFd = fs.openSync(this.absoluteRawLogPath, 'a');
432
+ }
442
433
 
443
434
  if (this.config.writeJsonLog) {
444
435
  this.jsonLogFd = fs.openSync(this.jsonLogPath, 'a');
@@ -453,9 +444,13 @@ export class EnhancedLogManager {
453
444
  if (this.config.keepRawLogs) {
454
445
  this.rawLogSize = fs.statSync(this.rawLogPath).size;
455
446
  }
447
+ if (this.config.keepAbsoluteRawLogs) {
448
+ this.absoluteRawLogSize = fs.statSync(this.absoluteRawLogPath).size;
449
+ }
456
450
  } catch {
457
451
  this.cleanLogSize = 0;
458
452
  this.rawLogSize = 0;
453
+ this.absoluteRawLogSize = 0;
459
454
  }
460
455
 
461
456
  // Write session header
@@ -676,6 +671,25 @@ export class EnhancedLogManager {
676
671
  }
677
672
  }
678
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
+
679
693
  /**
680
694
  * Write a JSON log entry
681
695
  */
@@ -692,6 +706,11 @@ export class EnhancedLogManager {
692
706
  public writeStdout(data: Buffer | string): void {
693
707
  const text = data.toString();
694
708
 
709
+ // Write absolute raw log
710
+ if (this.config.keepAbsoluteRawLogs) {
711
+ this.writeToAbsoluteRawLog(data);
712
+ }
713
+
695
714
  // Write raw log
696
715
  if (this.config.keepRawLogs) {
697
716
  this.writeToRawLog(text);
@@ -711,7 +730,7 @@ export class EnhancedLogManager {
711
730
  const cleanLine = stripAnsi(line).trim();
712
731
  if (!cleanLine) continue;
713
732
 
714
- // Handle streaming JSON messages (for boxes, etc. in readable log)
733
+ // Handle streaming JSON messages
715
734
  if (cleanLine.startsWith('{')) {
716
735
  if (this.streamingParser) {
717
736
  this.streamingParser.parseLine(cleanLine);
@@ -763,6 +782,25 @@ export class EnhancedLogManager {
763
782
  // Not valid JSON or error, fall through to regular logging
764
783
  }
765
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
+ }
766
804
  }
767
805
 
768
806
  // Also include significant info/status lines in readable log (compact)
@@ -812,6 +850,11 @@ export class EnhancedLogManager {
812
850
  public writeStderr(data: Buffer | string): void {
813
851
  const text = data.toString();
814
852
 
853
+ // Write absolute raw log
854
+ if (this.config.keepAbsoluteRawLogs) {
855
+ this.writeToAbsoluteRawLog(data);
856
+ }
857
+
815
858
  // Write raw log
816
859
  if (this.config.keepRawLogs) {
817
860
  this.writeToRawLog(text);
@@ -856,7 +899,7 @@ export class EnhancedLogManager {
856
899
  */
857
900
  public log(level: 'info' | 'error' | 'debug', message: string, metadata?: Record<string, any>): void {
858
901
  const ts = formatTimestamp(this.config.timestampFormat, this.session.startTime);
859
- const prefix = level.toUpperCase().padEnd(5);
902
+ const prefix = level.toUpperCase().padEnd(8);
860
903
 
861
904
  const line = `[${ts}] [${prefix}] ${message}\n`;
862
905
  this.writeToCleanLog(line);
@@ -865,6 +908,10 @@ export class EnhancedLogManager {
865
908
  this.writeToRawLog(line);
866
909
  }
867
910
 
911
+ if (this.config.keepAbsoluteRawLogs) {
912
+ this.writeToAbsoluteRawLog(line);
913
+ }
914
+
868
915
  // Write to readable log (compact)
869
916
  if (this.readableLogFd !== null) {
870
917
  const typeLabel = level === 'error' ? '❌ ERROR' : level === 'info' ? 'ℹ️ INFO' : '🔍 DEBUG';
@@ -897,6 +944,9 @@ export class EnhancedLogManager {
897
944
  if (this.config.keepRawLogs) {
898
945
  this.writeToRawLog(line);
899
946
  }
947
+ if (this.config.keepAbsoluteRawLogs) {
948
+ this.writeToAbsoluteRawLog(line);
949
+ }
900
950
 
901
951
  // Write to readable log (compact)
902
952
  if (this.readableLogFd !== null) {
@@ -954,10 +1004,11 @@ export class EnhancedLogManager {
954
1004
  /**
955
1005
  * Get paths to all log files
956
1006
  */
957
- public getLogPaths(): { clean: string; raw?: string; json?: string; readable: string } {
1007
+ public getLogPaths(): { clean: string; raw?: string; absoluteRaw?: string; json?: string; readable: string } {
958
1008
  return {
959
1009
  clean: this.cleanLogPath,
960
1010
  raw: this.config.keepRawLogs ? this.rawLogPath : undefined,
1011
+ absoluteRaw: this.config.keepAbsoluteRawLogs ? this.absoluteRawLogPath : undefined,
961
1012
  json: this.config.writeJsonLog ? this.jsonLogPath : undefined,
962
1013
  readable: this.readableLogPath,
963
1014
  };
@@ -1011,6 +1062,11 @@ export class EnhancedLogManager {
1011
1062
  this.rawLogFd = null;
1012
1063
  }
1013
1064
 
1065
+ if (this.absoluteRawLogFd !== null) {
1066
+ fs.closeSync(this.absoluteRawLogFd);
1067
+ this.absoluteRawLogFd = null;
1068
+ }
1069
+
1014
1070
  if (this.jsonLogFd !== null) {
1015
1071
  this.writeJsonEntry({
1016
1072
  timestamp: new Date().toISOString(),
@@ -1171,8 +1227,10 @@ function exportToMarkdown(jsonLogPath: string, cleanLogPath: string): string {
1171
1227
  md += `### Task: ${task}\n\n`;
1172
1228
  md += '```\n';
1173
1229
  for (const entry of taskEntries) {
1174
- if (entry.level !== 'session') {
1175
- md += `[${entry.timestamp}] [${entry.level.toUpperCase()}] ${entry.message}\n`;
1230
+ const level = entry.level || 'info';
1231
+ const message = entry.message || '';
1232
+ if (level !== 'session') {
1233
+ md += `[${entry.timestamp}] [${level.toUpperCase()}] ${message}\n`;
1176
1234
  }
1177
1235
  }
1178
1236
  md += '```\n\n';
@@ -1211,11 +1269,13 @@ function exportToHtml(jsonLogPath: string, cleanLogPath: string): string {
1211
1269
  `;
1212
1270
 
1213
1271
  for (const entry of entries) {
1214
- html += ` <div class="entry ${entry.level}">
1272
+ const level = entry.level || 'info';
1273
+ const message = entry.message || '';
1274
+ html += ` <div class="entry ${level}">
1215
1275
  <span class="timestamp">${entry.timestamp}</span>
1216
- <span class="level">[${entry.level}]</span>
1276
+ <span class="level">[${level}]</span>
1217
1277
  ${entry.task ? `<span class="task">[${entry.task}]</span>` : ''}
1218
- <pre>${escapeHtml(entry.message)}</pre>
1278
+ <pre>${escapeHtml(message)}</pre>
1219
1279
  </div>\n`;
1220
1280
  }
1221
1281
 
@@ -1231,4 +1291,3 @@ function escapeHtml(text: string): string {
1231
1291
  .replace(/"/g, '&quot;')
1232
1292
  .replace(/'/g, '&#039;');
1233
1293
  }
1234
-