sequant 1.2.4 → 1.2.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.
Files changed (53) hide show
  1. package/README.md +18 -0
  2. package/dist/bin/cli.js +10 -0
  3. package/dist/bin/cli.js.map +1 -1
  4. package/dist/src/commands/doctor.d.ts.map +1 -1
  5. package/dist/src/commands/doctor.js +33 -1
  6. package/dist/src/commands/doctor.js.map +1 -1
  7. package/dist/src/commands/doctor.test.js +84 -1
  8. package/dist/src/commands/doctor.test.js.map +1 -1
  9. package/dist/src/commands/init.d.ts.map +1 -1
  10. package/dist/src/commands/init.js +5 -0
  11. package/dist/src/commands/init.js.map +1 -1
  12. package/dist/src/commands/logs.d.ts +2 -0
  13. package/dist/src/commands/logs.d.ts.map +1 -1
  14. package/dist/src/commands/logs.js +41 -0
  15. package/dist/src/commands/logs.js.map +1 -1
  16. package/dist/src/commands/run.js +5 -1
  17. package/dist/src/commands/run.js.map +1 -1
  18. package/dist/src/commands/stats.d.ts +16 -0
  19. package/dist/src/commands/stats.d.ts.map +1 -0
  20. package/dist/src/commands/stats.js +271 -0
  21. package/dist/src/commands/stats.js.map +1 -0
  22. package/dist/src/commands/stats.test.d.ts +7 -0
  23. package/dist/src/commands/stats.test.d.ts.map +1 -0
  24. package/dist/src/commands/stats.test.js +218 -0
  25. package/dist/src/commands/stats.test.js.map +1 -0
  26. package/dist/src/commands/update.d.ts.map +1 -1
  27. package/dist/src/commands/update.js +2 -2
  28. package/dist/src/commands/update.js.map +1 -1
  29. package/dist/src/lib/settings.d.ts +17 -0
  30. package/dist/src/lib/settings.d.ts.map +1 -1
  31. package/dist/src/lib/settings.js +9 -0
  32. package/dist/src/lib/settings.js.map +1 -1
  33. package/dist/src/lib/system.d.ts +26 -0
  34. package/dist/src/lib/system.d.ts.map +1 -1
  35. package/dist/src/lib/system.js +72 -1
  36. package/dist/src/lib/system.js.map +1 -1
  37. package/dist/src/lib/workflow/log-rotation.d.ts +138 -0
  38. package/dist/src/lib/workflow/log-rotation.d.ts.map +1 -0
  39. package/dist/src/lib/workflow/log-rotation.js +232 -0
  40. package/dist/src/lib/workflow/log-rotation.js.map +1 -0
  41. package/dist/src/lib/workflow/log-rotation.test.d.ts +7 -0
  42. package/dist/src/lib/workflow/log-rotation.test.d.ts.map +1 -0
  43. package/dist/src/lib/workflow/log-rotation.test.js +248 -0
  44. package/dist/src/lib/workflow/log-rotation.test.js.map +1 -0
  45. package/dist/src/lib/workflow/log-writer.d.ts +6 -0
  46. package/dist/src/lib/workflow/log-writer.d.ts.map +1 -1
  47. package/dist/src/lib/workflow/log-writer.js +12 -0
  48. package/dist/src/lib/workflow/log-writer.js.map +1 -1
  49. package/dist/src/lib/workflow/log-writer.test.js +4 -1
  50. package/dist/src/lib/workflow/log-writer.test.js.map +1 -1
  51. package/package.json +1 -1
  52. package/templates/skills/exec/SKILL.md +75 -0
  53. package/templates/skills/qa/SKILL.md +8 -0
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Log rotation management for workflow run logs
3
+ *
4
+ * Implements automatic log rotation based on size and file count thresholds.
5
+ * Deletes oldest logs first until within limits.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { rotateIfNeeded, getLogStats, manualRotate } from './log-rotation';
10
+ *
11
+ * // Auto-rotate after a run
12
+ * await rotateIfNeeded('.sequant/logs');
13
+ *
14
+ * // Get statistics
15
+ * const stats = await getLogStats('.sequant/logs');
16
+ * console.log(`${stats.fileCount} files, ${stats.totalSizeMB.toFixed(2)}MB`);
17
+ *
18
+ * // Manual rotation with dry-run
19
+ * const result = await manualRotate('.sequant/logs', { dryRun: true });
20
+ * console.log(`Would delete ${result.deletedCount} files`);
21
+ * ```
22
+ */
23
+ import * as fs from "fs";
24
+ import * as path from "path";
25
+ import * as os from "os";
26
+ /**
27
+ * Default rotation settings
28
+ */
29
+ export const DEFAULT_ROTATION_SETTINGS = {
30
+ enabled: true,
31
+ maxSizeMB: 10,
32
+ maxFiles: 100,
33
+ };
34
+ /**
35
+ * Resolve a path, replacing ~ with home directory
36
+ */
37
+ function resolvePath(logPath) {
38
+ return logPath.replace("~", os.homedir());
39
+ }
40
+ /**
41
+ * Get list of log files with metadata, sorted by modification time (oldest first)
42
+ */
43
+ export function getLogFiles(logDir) {
44
+ const resolved = resolvePath(logDir);
45
+ if (!fs.existsSync(resolved)) {
46
+ return [];
47
+ }
48
+ const files = fs
49
+ .readdirSync(resolved)
50
+ .filter((f) => f.startsWith("run-") && f.endsWith(".json"));
51
+ const fileInfos = files.map((filename) => {
52
+ const filePath = path.join(resolved, filename);
53
+ const stats = fs.statSync(filePath);
54
+ return {
55
+ filename,
56
+ filePath,
57
+ mtime: stats.mtime,
58
+ size: stats.size,
59
+ };
60
+ });
61
+ // Sort by modification time, oldest first
62
+ return fileInfos.sort((a, b) => a.mtime.getTime() - b.mtime.getTime());
63
+ }
64
+ /**
65
+ * Get statistics about the log directory
66
+ *
67
+ * @param logDir - Path to log directory
68
+ * @param settings - Rotation settings for threshold comparison
69
+ * @returns Log directory statistics
70
+ */
71
+ export function getLogStats(logDir, settings = DEFAULT_ROTATION_SETTINGS) {
72
+ const files = getLogFiles(logDir);
73
+ if (files.length === 0) {
74
+ return {
75
+ totalSizeBytes: 0,
76
+ totalSizeMB: 0,
77
+ fileCount: 0,
78
+ oldestFile: null,
79
+ newestFile: null,
80
+ exceedsSizeThreshold: false,
81
+ exceedsCountThreshold: false,
82
+ };
83
+ }
84
+ const totalSizeBytes = files.reduce((sum, f) => sum + f.size, 0);
85
+ const totalSizeMB = totalSizeBytes / (1024 * 1024);
86
+ return {
87
+ totalSizeBytes,
88
+ totalSizeMB,
89
+ fileCount: files.length,
90
+ oldestFile: files[0].filename,
91
+ newestFile: files[files.length - 1].filename,
92
+ exceedsSizeThreshold: totalSizeMB > settings.maxSizeMB,
93
+ exceedsCountThreshold: files.length > settings.maxFiles,
94
+ };
95
+ }
96
+ /**
97
+ * Calculate which files need to be deleted to meet thresholds
98
+ *
99
+ * Applies a 10% buffer (stops at 90% of threshold) to prevent
100
+ * immediate re-rotation on next run.
101
+ *
102
+ * @param logDir - Path to log directory
103
+ * @param settings - Rotation settings
104
+ * @returns List of files to delete (oldest first)
105
+ */
106
+ export function getFilesToDelete(logDir, settings) {
107
+ const files = getLogFiles(logDir);
108
+ if (files.length === 0) {
109
+ return [];
110
+ }
111
+ const stats = getLogStats(logDir, settings);
112
+ // Check if rotation is needed
113
+ if (!stats.exceedsSizeThreshold && !stats.exceedsCountThreshold) {
114
+ return [];
115
+ }
116
+ // Target thresholds with 10% buffer (stop at 90%)
117
+ const targetSizeBytes = settings.maxSizeMB * 1024 * 1024 * 0.9;
118
+ const targetCount = Math.floor(settings.maxFiles * 0.9);
119
+ const toDelete = [];
120
+ let currentSize = stats.totalSizeBytes;
121
+ let currentCount = stats.fileCount;
122
+ // Delete oldest files first until under thresholds
123
+ for (const file of files) {
124
+ const sizeOk = currentSize <= targetSizeBytes;
125
+ const countOk = currentCount <= targetCount;
126
+ if (sizeOk && countOk) {
127
+ break;
128
+ }
129
+ toDelete.push(file);
130
+ currentSize -= file.size;
131
+ currentCount--;
132
+ }
133
+ return toDelete;
134
+ }
135
+ /**
136
+ * Rotate logs if needed (automatic rotation)
137
+ *
138
+ * Called after LogWriter.finalize() to clean up old logs.
139
+ *
140
+ * @param logDir - Path to log directory
141
+ * @param settings - Rotation settings
142
+ * @returns Rotation result
143
+ */
144
+ export function rotateIfNeeded(logDir, settings = DEFAULT_ROTATION_SETTINGS) {
145
+ if (!settings.enabled) {
146
+ return {
147
+ deletedFiles: [],
148
+ deletedCount: 0,
149
+ bytesReclaimed: 0,
150
+ rotated: false,
151
+ };
152
+ }
153
+ const resolved = resolvePath(logDir);
154
+ const toDelete = getFilesToDelete(logDir, settings);
155
+ if (toDelete.length === 0) {
156
+ return {
157
+ deletedFiles: [],
158
+ deletedCount: 0,
159
+ bytesReclaimed: 0,
160
+ rotated: false,
161
+ };
162
+ }
163
+ let bytesReclaimed = 0;
164
+ const deletedFiles = [];
165
+ for (const file of toDelete) {
166
+ try {
167
+ fs.unlinkSync(file.filePath);
168
+ deletedFiles.push(file.filename);
169
+ bytesReclaimed += file.size;
170
+ }
171
+ catch (err) {
172
+ return {
173
+ deletedFiles,
174
+ deletedCount: deletedFiles.length,
175
+ bytesReclaimed,
176
+ rotated: deletedFiles.length > 0,
177
+ error: `Failed to delete ${file.filename}: ${err instanceof Error ? err.message : String(err)}`,
178
+ };
179
+ }
180
+ }
181
+ return {
182
+ deletedFiles,
183
+ deletedCount: deletedFiles.length,
184
+ bytesReclaimed,
185
+ rotated: true,
186
+ };
187
+ }
188
+ /**
189
+ * Manual rotation triggered by CLI command
190
+ *
191
+ * Supports dry-run mode to preview what would be deleted.
192
+ *
193
+ * @param logDir - Path to log directory
194
+ * @param options - Manual rotation options
195
+ * @returns Rotation result
196
+ */
197
+ export function manualRotate(logDir, options = {}) {
198
+ const settings = options.settings ?? DEFAULT_ROTATION_SETTINGS;
199
+ const toDelete = getFilesToDelete(logDir, settings);
200
+ if (toDelete.length === 0) {
201
+ return {
202
+ deletedFiles: [],
203
+ deletedCount: 0,
204
+ bytesReclaimed: 0,
205
+ rotated: false,
206
+ };
207
+ }
208
+ // Dry run - just report what would be deleted
209
+ if (options.dryRun) {
210
+ return {
211
+ deletedFiles: toDelete.map((f) => f.filename),
212
+ deletedCount: toDelete.length,
213
+ bytesReclaimed: toDelete.reduce((sum, f) => sum + f.size, 0),
214
+ rotated: false,
215
+ };
216
+ }
217
+ // Actual deletion
218
+ return rotateIfNeeded(logDir, settings);
219
+ }
220
+ /**
221
+ * Format bytes for human-readable display
222
+ */
223
+ export function formatBytes(bytes) {
224
+ if (bytes < 1024) {
225
+ return `${bytes} B`;
226
+ }
227
+ if (bytes < 1024 * 1024) {
228
+ return `${(bytes / 1024).toFixed(1)} KB`;
229
+ }
230
+ return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
231
+ }
232
+ //# sourceMappingURL=log-rotation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-rotation.js","sourceRoot":"","sources":["../../../../src/lib/workflow/log-rotation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Unit tests for log rotation
3
+ *
4
+ * Tests the log rotation system that manages disk space usage.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=log-rotation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-rotation.test.d.ts","sourceRoot":"","sources":["../../../../src/lib/workflow/log-rotation.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,248 @@
1
+ /**
2
+ * Unit tests for log rotation
3
+ *
4
+ * Tests the log rotation system that manages disk space usage.
5
+ */
6
+ import { describe, it, expect, vi, beforeEach } from "vitest";
7
+ import * as fs from "fs";
8
+ import { getLogFiles, getLogStats, getFilesToDelete, rotateIfNeeded, manualRotate, formatBytes, DEFAULT_ROTATION_SETTINGS, } from "./log-rotation.js";
9
+ // Mock fs module
10
+ vi.mock("fs", () => ({
11
+ existsSync: vi.fn(),
12
+ readdirSync: vi.fn(),
13
+ statSync: vi.fn(),
14
+ unlinkSync: vi.fn(),
15
+ }));
16
+ describe("log-rotation", () => {
17
+ beforeEach(() => {
18
+ vi.clearAllMocks();
19
+ });
20
+ describe("getLogFiles", () => {
21
+ it("should return empty array if directory does not exist", () => {
22
+ fs.existsSync.mockReturnValue(false);
23
+ const result = getLogFiles("/test/logs");
24
+ expect(result).toEqual([]);
25
+ });
26
+ it("should filter for run-*.json files only", () => {
27
+ fs.existsSync.mockReturnValue(true);
28
+ fs.readdirSync.mockReturnValue([
29
+ "run-2024-01-15-abc.json",
30
+ "run-2024-01-16-def.json",
31
+ "other-file.json",
32
+ "run-incomplete",
33
+ "settings.json",
34
+ ]);
35
+ fs.statSync.mockImplementation((path) => ({
36
+ mtime: new Date(path.includes("15") ? "2024-01-15" : "2024-01-16"),
37
+ size: 1024,
38
+ }));
39
+ const result = getLogFiles("/test/logs");
40
+ expect(result).toHaveLength(2);
41
+ expect(result[0].filename).toBe("run-2024-01-15-abc.json");
42
+ expect(result[1].filename).toBe("run-2024-01-16-def.json");
43
+ });
44
+ it("should sort files by modification time (oldest first)", () => {
45
+ fs.existsSync.mockReturnValue(true);
46
+ fs.readdirSync.mockReturnValue([
47
+ "run-new.json",
48
+ "run-old.json",
49
+ "run-mid.json",
50
+ ]);
51
+ fs.statSync.mockImplementation((path) => {
52
+ if (path.includes("old"))
53
+ return { mtime: new Date("2024-01-01"), size: 1024 };
54
+ if (path.includes("mid"))
55
+ return { mtime: new Date("2024-01-15"), size: 1024 };
56
+ return { mtime: new Date("2024-01-30"), size: 1024 };
57
+ });
58
+ const result = getLogFiles("/test/logs");
59
+ expect(result[0].filename).toBe("run-old.json");
60
+ expect(result[1].filename).toBe("run-mid.json");
61
+ expect(result[2].filename).toBe("run-new.json");
62
+ });
63
+ });
64
+ describe("getLogStats", () => {
65
+ it("should return zero stats for empty directory", () => {
66
+ fs.existsSync.mockReturnValue(true);
67
+ fs.readdirSync.mockReturnValue([]);
68
+ const stats = getLogStats("/test/logs");
69
+ expect(stats).toEqual({
70
+ totalSizeBytes: 0,
71
+ totalSizeMB: 0,
72
+ fileCount: 0,
73
+ oldestFile: null,
74
+ newestFile: null,
75
+ exceedsSizeThreshold: false,
76
+ exceedsCountThreshold: false,
77
+ });
78
+ });
79
+ it("should calculate total size correctly", () => {
80
+ fs.existsSync.mockReturnValue(true);
81
+ fs.readdirSync.mockReturnValue([
82
+ "run-1.json",
83
+ "run-2.json",
84
+ ]);
85
+ fs.statSync.mockImplementation((path) => ({
86
+ mtime: new Date(),
87
+ size: path.includes("1") ? 1024 * 1024 : 2 * 1024 * 1024, // 1MB and 2MB
88
+ }));
89
+ const stats = getLogStats("/test/logs");
90
+ expect(stats.totalSizeBytes).toBe(3 * 1024 * 1024);
91
+ expect(stats.totalSizeMB).toBe(3);
92
+ expect(stats.fileCount).toBe(2);
93
+ });
94
+ it("should detect size threshold exceeded", () => {
95
+ fs.existsSync.mockReturnValue(true);
96
+ fs.readdirSync.mockReturnValue([
97
+ "run-1.json",
98
+ ]);
99
+ fs.statSync.mockReturnValue({
100
+ mtime: new Date(),
101
+ size: 15 * 1024 * 1024, // 15MB > 10MB threshold
102
+ });
103
+ const stats = getLogStats("/test/logs");
104
+ expect(stats.exceedsSizeThreshold).toBe(true);
105
+ expect(stats.exceedsCountThreshold).toBe(false);
106
+ });
107
+ it("should detect count threshold exceeded", () => {
108
+ fs.existsSync.mockReturnValue(true);
109
+ fs.readdirSync.mockReturnValue(Array.from({ length: 105 }, (_, i) => `run-${i}.json`));
110
+ fs.statSync.mockReturnValue({
111
+ mtime: new Date(),
112
+ size: 1024, // 1KB each = 105KB total (under size limit)
113
+ });
114
+ const stats = getLogStats("/test/logs");
115
+ expect(stats.exceedsSizeThreshold).toBe(false);
116
+ expect(stats.exceedsCountThreshold).toBe(true);
117
+ });
118
+ });
119
+ describe("getFilesToDelete", () => {
120
+ it("should return empty array when under thresholds", () => {
121
+ fs.existsSync.mockReturnValue(true);
122
+ fs.readdirSync.mockReturnValue([
123
+ "run-1.json",
124
+ "run-2.json",
125
+ ]);
126
+ fs.statSync.mockReturnValue({
127
+ mtime: new Date(),
128
+ size: 1024,
129
+ });
130
+ const result = getFilesToDelete("/test/logs", DEFAULT_ROTATION_SETTINGS);
131
+ expect(result).toEqual([]);
132
+ });
133
+ it("should select oldest files for deletion when count exceeded", () => {
134
+ fs.existsSync.mockReturnValue(true);
135
+ const files = Array.from({ length: 105 }, (_, i) => `run-${i}.json`);
136
+ fs.readdirSync.mockReturnValue(files);
137
+ fs.statSync.mockImplementation((path) => {
138
+ const match = path.match(/run-(\d+)\.json/);
139
+ const idx = match ? parseInt(match[1]) : 0;
140
+ return {
141
+ mtime: new Date(Date.now() + idx * 1000), // Older files have lower index
142
+ size: 1024,
143
+ };
144
+ });
145
+ const result = getFilesToDelete("/test/logs", DEFAULT_ROTATION_SETTINGS);
146
+ // Should delete enough to get to 90 files (10% buffer = 90)
147
+ // 105 - 90 = 15 files to delete
148
+ expect(result.length).toBe(15);
149
+ // Oldest files should be first
150
+ expect(result[0].filename).toBe("run-0.json");
151
+ });
152
+ it("should delete files when size threshold exceeded", () => {
153
+ fs.existsSync.mockReturnValue(true);
154
+ fs.readdirSync.mockReturnValue([
155
+ "run-old.json",
156
+ "run-new.json",
157
+ ]);
158
+ fs.statSync.mockImplementation((path) => ({
159
+ mtime: new Date(path.includes("old") ? "2024-01-01" : "2024-01-30"),
160
+ size: 6 * 1024 * 1024, // 6MB each = 12MB total > 10MB
161
+ }));
162
+ const result = getFilesToDelete("/test/logs", DEFAULT_ROTATION_SETTINGS);
163
+ // Should delete 1 file to get under 9MB threshold
164
+ expect(result.length).toBe(1);
165
+ expect(result[0].filename).toBe("run-old.json");
166
+ });
167
+ });
168
+ describe("rotateIfNeeded", () => {
169
+ it("should not delete when disabled", () => {
170
+ const result = rotateIfNeeded("/test/logs", {
171
+ ...DEFAULT_ROTATION_SETTINGS,
172
+ enabled: false,
173
+ });
174
+ expect(result.rotated).toBe(false);
175
+ expect(result.deletedCount).toBe(0);
176
+ expect(fs.unlinkSync).not.toHaveBeenCalled();
177
+ });
178
+ it("should not delete when under thresholds", () => {
179
+ fs.existsSync.mockReturnValue(true);
180
+ fs.readdirSync.mockReturnValue([
181
+ "run-1.json",
182
+ ]);
183
+ fs.statSync.mockReturnValue({
184
+ mtime: new Date(),
185
+ size: 1024,
186
+ });
187
+ const result = rotateIfNeeded("/test/logs");
188
+ expect(result.rotated).toBe(false);
189
+ expect(fs.unlinkSync).not.toHaveBeenCalled();
190
+ });
191
+ it("should delete oldest files when threshold exceeded", () => {
192
+ fs.existsSync.mockReturnValue(true);
193
+ fs.readdirSync.mockReturnValue([
194
+ "run-old.json",
195
+ "run-new.json",
196
+ ]);
197
+ fs.statSync.mockImplementation((path) => ({
198
+ mtime: new Date(path.includes("old") ? "2024-01-01" : "2024-01-30"),
199
+ size: 6 * 1024 * 1024,
200
+ }));
201
+ const result = rotateIfNeeded("/test/logs");
202
+ expect(result.rotated).toBe(true);
203
+ expect(result.deletedCount).toBe(1);
204
+ expect(fs.unlinkSync).toHaveBeenCalledTimes(1);
205
+ });
206
+ });
207
+ describe("manualRotate", () => {
208
+ it("should support dry-run mode", () => {
209
+ fs.existsSync.mockReturnValue(true);
210
+ fs.readdirSync.mockReturnValue([
211
+ "run-old.json",
212
+ "run-new.json",
213
+ ]);
214
+ fs.statSync.mockImplementation((path) => ({
215
+ mtime: new Date(path.includes("old") ? "2024-01-01" : "2024-01-30"),
216
+ size: 6 * 1024 * 1024,
217
+ }));
218
+ const result = manualRotate("/test/logs", { dryRun: true });
219
+ expect(result.deletedCount).toBe(1);
220
+ expect(result.rotated).toBe(false); // dry-run = not actually rotated
221
+ expect(fs.unlinkSync).not.toHaveBeenCalled();
222
+ });
223
+ it("should actually delete in non-dry-run mode", () => {
224
+ fs.existsSync.mockReturnValue(true);
225
+ fs.readdirSync.mockReturnValue([
226
+ "run-old.json",
227
+ "run-new.json",
228
+ ]);
229
+ fs.statSync.mockImplementation((path) => ({
230
+ mtime: new Date(path.includes("old") ? "2024-01-01" : "2024-01-30"),
231
+ size: 6 * 1024 * 1024,
232
+ }));
233
+ const result = manualRotate("/test/logs", { dryRun: false });
234
+ expect(result.rotated).toBe(true);
235
+ expect(fs.unlinkSync).toHaveBeenCalled();
236
+ });
237
+ });
238
+ describe("formatBytes", () => {
239
+ it("should format bytes correctly", () => {
240
+ expect(formatBytes(500)).toBe("500 B");
241
+ expect(formatBytes(1024)).toBe("1.0 KB");
242
+ expect(formatBytes(1536)).toBe("1.5 KB");
243
+ expect(formatBytes(1024 * 1024)).toBe("1.00 MB");
244
+ expect(formatBytes(5.5 * 1024 * 1024)).toBe("5.50 MB");
245
+ });
246
+ });
247
+ });
248
+ //# sourceMappingURL=log-rotation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-rotation.test.js","sourceRoot":"","sources":["../../../../src/lib/workflow/log-rotation.test.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,7 @@
14
14
  * ```
15
15
  */
16
16
  import { type RunLog, type RunConfig, type PhaseLog, type Phase } from "./run-log-schema.js";
17
+ import { type RotationSettings } from "./log-rotation.js";
17
18
  export interface LogWriterOptions {
18
19
  /** Path to log directory (default: .sequant/logs in current directory) */
19
20
  logPath?: string;
@@ -21,6 +22,8 @@ export interface LogWriterOptions {
21
22
  writeToUserLogs?: boolean;
22
23
  /** Enable verbose logging */
23
24
  verbose?: boolean;
25
+ /** Log rotation settings */
26
+ rotation?: RotationSettings;
24
27
  }
25
28
  /**
26
29
  * Manages writing structured run logs to disk
@@ -31,6 +34,7 @@ export declare class LogWriter {
31
34
  private logPath;
32
35
  private writeToUserLogs;
33
36
  private verbose;
37
+ private rotation;
34
38
  constructor(options?: LogWriterOptions);
35
39
  /**
36
40
  * Initialize a new run log
@@ -59,6 +63,8 @@ export declare class LogWriter {
59
63
  /**
60
64
  * Finalize the run log and write to disk
61
65
  *
66
+ * Automatically rotates old logs if thresholds are exceeded.
67
+ *
62
68
  * @returns Path to the written log file
63
69
  */
64
70
  finalize(): Promise<string>;
@@ -1 +1 @@
1
- {"version":3,"file":"log-writer.d.ts","sourceRoot":"","sources":["../../../../src/lib/workflow/log-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,EACL,KAAK,MAAM,EACX,KAAK,SAAS,EAEd,KAAK,QAAQ,EACb,KAAK,KAAK,EAMX,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,gBAAgB;IAC/B,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,OAAO,CAAU;gBAEb,OAAO,GAAE,gBAAqB;IAM1C;;;;OAIG;IACG,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBlD;;;;;;OAMG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAmBtE;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAwBlC;;OAEG;IACH,aAAa,IAAI,IAAI;IA+BrB;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAiCjC;;OAEG;IACH,SAAS,IAAI,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,IAAI;IAI3C;;OAEG;IACH,QAAQ,IAAI,MAAM,GAAG,IAAI;IAIzB,OAAO,CAAC,WAAW;YAIL,kBAAkB;YAOlB,YAAY;CAO3B;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,IAAI,EACf,OAAO,EAAE,IAAI,EACb,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAC1B,OAAO,CAAC,EAAE,OAAO,CACf,IAAI,CACF,QAAQ,EACR,OAAO,GAAG,YAAY,GAAG,eAAe,GAAG,UAAU,GAAG,aAAa,CACtE,CACF,GACA,QAAQ,CAYV"}
1
+ {"version":3,"file":"log-writer.d.ts","sourceRoot":"","sources":["../../../../src/lib/workflow/log-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,EACL,KAAK,MAAM,EACX,KAAK,SAAS,EAEd,KAAK,QAAQ,EACb,KAAK,KAAK,EAMX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,gBAAgB;IAC/B,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AAED;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,QAAQ,CAAmB;gBAEvB,OAAO,GAAE,gBAAqB;IAO1C;;;;OAIG;IACG,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBlD;;;;;;OAMG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAmBtE;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAwBlC;;OAEG;IACH,aAAa,IAAI,IAAI;IA+BrB;;;;;;OAMG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IA2CjC;;OAEG;IACH,SAAS,IAAI,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,IAAI;IAI3C;;OAEG;IACH,QAAQ,IAAI,MAAM,GAAG,IAAI;IAIzB,OAAO,CAAC,WAAW;YAIL,kBAAkB;YAOlB,YAAY;CAO3B;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,IAAI,EACf,OAAO,EAAE,IAAI,EACb,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAC1B,OAAO,CAAC,EAAE,OAAO,CACf,IAAI,CACF,QAAQ,EACR,OAAO,GAAG,YAAY,GAAG,eAAe,GAAG,UAAU,GAAG,aAAa,CACtE,CACF,GACA,QAAQ,CAYV"}
@@ -17,6 +17,7 @@ import * as fs from "fs";
17
17
  import * as path from "path";
18
18
  import * as os from "os";
19
19
  import { createEmptyRunLog, finalizeRunLog, generateLogFilename, LOG_PATHS, } from "./run-log-schema.js";
20
+ import { rotateIfNeeded, DEFAULT_ROTATION_SETTINGS, } from "./log-rotation.js";
20
21
  /**
21
22
  * Manages writing structured run logs to disk
22
23
  */
@@ -26,10 +27,12 @@ export class LogWriter {
26
27
  logPath;
27
28
  writeToUserLogs;
28
29
  verbose;
30
+ rotation;
29
31
  constructor(options = {}) {
30
32
  this.logPath = options.logPath ?? LOG_PATHS.project;
31
33
  this.writeToUserLogs = options.writeToUserLogs ?? false;
32
34
  this.verbose = options.verbose ?? false;
35
+ this.rotation = options.rotation ?? DEFAULT_ROTATION_SETTINGS;
33
36
  }
34
37
  /**
35
38
  * Initialize a new run log
@@ -119,6 +122,8 @@ export class LogWriter {
119
122
  /**
120
123
  * Finalize the run log and write to disk
121
124
  *
125
+ * Automatically rotates old logs if thresholds are exceeded.
126
+ *
122
127
  * @returns Path to the written log file
123
128
  */
124
129
  async finalize() {
@@ -142,6 +147,13 @@ export class LogWriter {
142
147
  if (this.verbose) {
143
148
  console.log(`📝 Log written: ${projectPath}`);
144
149
  }
150
+ // Auto-rotate if needed
151
+ if (this.rotation.enabled) {
152
+ const result = rotateIfNeeded(this.logPath, this.rotation);
153
+ if (result.rotated && this.verbose) {
154
+ console.log(`📝 Rotated ${result.deletedCount} old log(s), reclaimed ${(result.bytesReclaimed / 1024).toFixed(1)} KB`);
155
+ }
156
+ }
145
157
  return projectPath;
146
158
  }
147
159
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"log-writer.js","sourceRoot":"","sources":["../../../../src/lib/workflow/log-writer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"log-writer.js","sourceRoot":"","sources":["../../../../src/lib/workflow/log-writer.ts"],"names":[],"mappings":"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"}
@@ -8,11 +8,14 @@ import * as fs from "fs";
8
8
  import * as path from "path";
9
9
  import * as os from "os";
10
10
  import { LogWriter, createPhaseLogFromTiming } from "./log-writer.js";
11
- // Mock fs module
11
+ // Mock fs module - include all functions needed by log-rotation.ts
12
12
  vi.mock("fs", () => ({
13
13
  existsSync: vi.fn(),
14
14
  mkdirSync: vi.fn(),
15
15
  writeFileSync: vi.fn(),
16
+ readdirSync: vi.fn(() => []),
17
+ statSync: vi.fn(() => ({ mtime: new Date(), size: 1024 })),
18
+ unlinkSync: vi.fn(),
16
19
  }));
17
20
  // Mock crypto.randomUUID for deterministic tests
18
21
  const mockUUID = "12345678-1234-1234-1234-123456789abc";