@graypark/loophaus 3.5.0 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +44 -68
- package/README.md +46 -64
- package/commands/loop-plan.md +22 -0
- package/dist/README.ko.md +44 -68
- package/dist/README.md +46 -64
- package/dist/bin/loophaus.js +111 -1
- package/dist/bin/loophaus.js.map +1 -1
- package/dist/commands/loop-plan.md +22 -0
- package/dist/core/benchmark.d.ts +39 -0
- package/dist/core/benchmark.d.ts.map +1 -0
- package/dist/core/benchmark.js +208 -0
- package/dist/core/benchmark.js.map +1 -0
- package/dist/core/cleanup.d.ts +24 -0
- package/dist/core/cleanup.d.ts.map +1 -0
- package/dist/core/cleanup.js +145 -0
- package/dist/core/cleanup.js.map +1 -0
- package/dist/package.json +3 -1
- package/package.json +3 -1
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
// core/benchmark.ts
|
|
2
|
+
// Project-level quality measurement (autoresearch pattern: val_bpb → project score)
|
|
3
|
+
import { execFile } from "node:child_process";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
import { readFile, appendFile, mkdir, stat } from "node:fs/promises";
|
|
6
|
+
import { join, dirname } from "node:path";
|
|
7
|
+
const execFileAsync = promisify(execFile);
|
|
8
|
+
export function scoreBenchmark(metrics) {
|
|
9
|
+
const breakdown = {};
|
|
10
|
+
// Tests: 0-10 based on pass rate
|
|
11
|
+
const testRate = metrics.testsTotal > 0 ? metrics.testsPassed / metrics.testsTotal : 0;
|
|
12
|
+
breakdown.tests = { value: metrics.testsPassed, max: metrics.testsTotal, score: Math.round(testRate * 10) };
|
|
13
|
+
// Typecheck: 10 if 0 errors, degrade
|
|
14
|
+
const tcScore = metrics.typecheckErrors === 0 ? 10 : metrics.typecheckErrors <= 5 ? 6 : metrics.typecheckErrors <= 20 ? 3 : 0;
|
|
15
|
+
breakdown.typecheck = { value: metrics.typecheckErrors, max: 0, score: tcScore };
|
|
16
|
+
// Build: binary
|
|
17
|
+
breakdown.build = { value: metrics.buildSuccess ? 1 : 0, max: 1, score: metrics.buildSuccess ? 10 : 0 };
|
|
18
|
+
// Test time: < 2s = 10, < 5s = 8, < 10s = 6, < 30s = 4, else 2
|
|
19
|
+
const ttScore = metrics.testTimeMs < 2000 ? 10 : metrics.testTimeMs < 5000 ? 8 : metrics.testTimeMs < 10000 ? 6 : metrics.testTimeMs < 30000 ? 4 : 2;
|
|
20
|
+
breakdown.testTime = { value: metrics.testTimeMs, max: 2000, score: ttScore };
|
|
21
|
+
// Coverage: direct percentage mapping to 0-10
|
|
22
|
+
const covScore = Math.min(10, Math.round(metrics.coveragePct / 10));
|
|
23
|
+
breakdown.coverage = { value: metrics.coveragePct, max: 100, score: covScore };
|
|
24
|
+
// Package size: < 50KB = 10, < 100KB = 8, < 200KB = 6, < 500KB = 4, else 2
|
|
25
|
+
const sizeScore = metrics.pkgSizeKb < 50 ? 10 : metrics.pkgSizeKb < 100 ? 8 : metrics.pkgSizeKb < 200 ? 6 : metrics.pkgSizeKb < 500 ? 4 : 2;
|
|
26
|
+
breakdown.pkgSize = { value: metrics.pkgSizeKb, max: 50, score: sizeScore };
|
|
27
|
+
// Weighted average (tests 3x, typecheck 2.5x, build 1.5x, coverage 2x, testTime 0.5x, pkgSize 0.5x)
|
|
28
|
+
const weights = { tests: 3, typecheck: 2.5, build: 1.5, coverage: 2, testTime: 0.5, pkgSize: 0.5 };
|
|
29
|
+
let weightedSum = 0;
|
|
30
|
+
let totalWeight = 0;
|
|
31
|
+
for (const [key, w] of Object.entries(weights)) {
|
|
32
|
+
weightedSum += breakdown[key].score * w;
|
|
33
|
+
totalWeight += 10 * w;
|
|
34
|
+
}
|
|
35
|
+
const score = Math.round((weightedSum / totalWeight) * 100);
|
|
36
|
+
const grade = score >= 90 ? "A+" : score >= 85 ? "A" : score >= 80 ? "B" : score >= 70 ? "C" : score >= 60 ? "D" : "F";
|
|
37
|
+
return { score, grade, breakdown, metrics };
|
|
38
|
+
}
|
|
39
|
+
export async function runBenchmark(cwd) {
|
|
40
|
+
const dir = cwd || process.cwd();
|
|
41
|
+
const metrics = {
|
|
42
|
+
testsPassed: 0,
|
|
43
|
+
testsFailed: 0,
|
|
44
|
+
testsTotal: 0,
|
|
45
|
+
testTimeMs: 0,
|
|
46
|
+
typecheckErrors: 0,
|
|
47
|
+
buildSuccess: false,
|
|
48
|
+
coveragePct: 0,
|
|
49
|
+
pkgSizeKb: 0,
|
|
50
|
+
};
|
|
51
|
+
// 1. Tests
|
|
52
|
+
const testStart = Date.now();
|
|
53
|
+
try {
|
|
54
|
+
const { stdout } = await execFileAsync("npx", ["vitest", "run", "--reporter=json"], { cwd: dir, timeout: 120_000 });
|
|
55
|
+
metrics.testTimeMs = Date.now() - testStart;
|
|
56
|
+
try {
|
|
57
|
+
const json = JSON.parse(stdout);
|
|
58
|
+
metrics.testsPassed = json.numPassedTests ?? 0;
|
|
59
|
+
metrics.testsFailed = json.numFailedTests ?? 0;
|
|
60
|
+
metrics.testsTotal = json.numTotalTests ?? 0;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// JSON parse failed, try regex fallback
|
|
64
|
+
const passMatch = stdout.match(/(\d+) passed/);
|
|
65
|
+
const failMatch = stdout.match(/(\d+) failed/);
|
|
66
|
+
if (passMatch)
|
|
67
|
+
metrics.testsPassed = parseInt(passMatch[1]);
|
|
68
|
+
if (failMatch)
|
|
69
|
+
metrics.testsFailed = parseInt(failMatch[1]);
|
|
70
|
+
metrics.testsTotal = metrics.testsPassed + metrics.testsFailed;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
metrics.testTimeMs = Date.now() - testStart;
|
|
75
|
+
const output = err.stdout || "";
|
|
76
|
+
const passMatch = output.match(/(\d+) passed/);
|
|
77
|
+
if (passMatch)
|
|
78
|
+
metrics.testsPassed = parseInt(passMatch[1]);
|
|
79
|
+
const failMatch = output.match(/(\d+) failed/);
|
|
80
|
+
if (failMatch)
|
|
81
|
+
metrics.testsFailed = parseInt(failMatch[1]);
|
|
82
|
+
metrics.testsTotal = metrics.testsPassed + metrics.testsFailed;
|
|
83
|
+
}
|
|
84
|
+
// 2. Typecheck
|
|
85
|
+
try {
|
|
86
|
+
await execFileAsync("npx", ["tsc", "--noEmit"], { cwd: dir, timeout: 60_000 });
|
|
87
|
+
metrics.typecheckErrors = 0;
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
const output = err.stdout || err.stderr || "";
|
|
91
|
+
const errorCount = (output.match(/error TS/g) || []).length;
|
|
92
|
+
metrics.typecheckErrors = errorCount || 1;
|
|
93
|
+
}
|
|
94
|
+
// 3. Build
|
|
95
|
+
try {
|
|
96
|
+
await execFileAsync("npm", ["run", "build"], { cwd: dir, timeout: 60_000 });
|
|
97
|
+
metrics.buildSuccess = true;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
metrics.buildSuccess = false;
|
|
101
|
+
}
|
|
102
|
+
// 4. Coverage
|
|
103
|
+
try {
|
|
104
|
+
const summaryPath = join(dir, "coverage", "coverage-summary.json");
|
|
105
|
+
const raw = await readFile(summaryPath, "utf-8");
|
|
106
|
+
const summary = JSON.parse(raw);
|
|
107
|
+
metrics.coveragePct = summary.total?.lines?.pct ?? 0;
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// Run coverage if summary doesn't exist
|
|
111
|
+
try {
|
|
112
|
+
await execFileAsync("npx", ["vitest", "run", "--coverage"], { cwd: dir, timeout: 120_000 });
|
|
113
|
+
const summaryPath = join(dir, "coverage", "coverage-summary.json");
|
|
114
|
+
const raw = await readFile(summaryPath, "utf-8");
|
|
115
|
+
const summary = JSON.parse(raw);
|
|
116
|
+
metrics.coveragePct = summary.total?.lines?.pct ?? 0;
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
metrics.coveragePct = 0;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// 5. Package size
|
|
123
|
+
try {
|
|
124
|
+
const distDir = join(dir, "dist");
|
|
125
|
+
const s = await stat(distDir);
|
|
126
|
+
if (s.isDirectory()) {
|
|
127
|
+
const { stdout } = await execFileAsync("du", ["-sk", distDir], { timeout: 10_000 });
|
|
128
|
+
const match = stdout.match(/^(\d+)/);
|
|
129
|
+
metrics.pkgSizeKb = match ? parseInt(match[1]) : 0;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
metrics.pkgSizeKb = 0;
|
|
134
|
+
}
|
|
135
|
+
return scoreBenchmark(metrics);
|
|
136
|
+
}
|
|
137
|
+
function getBenchmarkPath(cwd) {
|
|
138
|
+
return join(cwd || process.cwd(), ".loophaus", "benchmark.tsv");
|
|
139
|
+
}
|
|
140
|
+
const HEADER = "ts\tcommit\tversion\tscore\tgrade\ttests_passed\ttests_total\ttest_time_ms\ttypecheck_errors\tbuild_ok\tcoverage_pct\tpkg_size_kb\n";
|
|
141
|
+
export async function logBenchmark(result, cwd) {
|
|
142
|
+
const benchPath = getBenchmarkPath(cwd);
|
|
143
|
+
await mkdir(dirname(benchPath), { recursive: true });
|
|
144
|
+
let commitHash = "unknown";
|
|
145
|
+
try {
|
|
146
|
+
const { stdout } = await execFileAsync("git", ["rev-parse", "--short", "HEAD"], { timeout: 5_000 });
|
|
147
|
+
commitHash = stdout.trim();
|
|
148
|
+
}
|
|
149
|
+
catch { /* not in git */ }
|
|
150
|
+
let version = "unknown";
|
|
151
|
+
try {
|
|
152
|
+
const pkgPath = join(cwd || process.cwd(), "package.json");
|
|
153
|
+
const pkg = JSON.parse(await readFile(pkgPath, "utf-8"));
|
|
154
|
+
version = pkg.version || "unknown";
|
|
155
|
+
}
|
|
156
|
+
catch { /* no package.json */ }
|
|
157
|
+
// Write header if file is new
|
|
158
|
+
try {
|
|
159
|
+
await stat(benchPath);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
await appendFile(benchPath, HEADER, "utf-8");
|
|
163
|
+
}
|
|
164
|
+
const m = result.metrics;
|
|
165
|
+
const line = [
|
|
166
|
+
new Date().toISOString(),
|
|
167
|
+
commitHash,
|
|
168
|
+
version,
|
|
169
|
+
result.score,
|
|
170
|
+
result.grade,
|
|
171
|
+
m.testsPassed,
|
|
172
|
+
m.testsTotal,
|
|
173
|
+
m.testTimeMs,
|
|
174
|
+
m.typecheckErrors,
|
|
175
|
+
m.buildSuccess ? 1 : 0,
|
|
176
|
+
m.coveragePct.toFixed(1),
|
|
177
|
+
m.pkgSizeKb,
|
|
178
|
+
].join("\t") + "\n";
|
|
179
|
+
await appendFile(benchPath, line, "utf-8");
|
|
180
|
+
}
|
|
181
|
+
export async function readBenchmarkHistory(cwd) {
|
|
182
|
+
const benchPath = getBenchmarkPath(cwd);
|
|
183
|
+
try {
|
|
184
|
+
const raw = await readFile(benchPath, "utf-8");
|
|
185
|
+
const lines = raw.trim().split("\n").slice(1); // skip header
|
|
186
|
+
return lines.map(line => {
|
|
187
|
+
const cols = line.split("\t");
|
|
188
|
+
return {
|
|
189
|
+
ts: cols[0] || "",
|
|
190
|
+
commit: cols[1] || "",
|
|
191
|
+
version: cols[2] || "",
|
|
192
|
+
score: parseInt(cols[3]) || 0,
|
|
193
|
+
grade: cols[4] || "",
|
|
194
|
+
testsPassed: parseInt(cols[5]) || 0,
|
|
195
|
+
testsTotal: parseInt(cols[6]) || 0,
|
|
196
|
+
testTimeMs: parseInt(cols[7]) || 0,
|
|
197
|
+
typecheckErrors: parseInt(cols[8]) || 0,
|
|
198
|
+
buildSuccess: cols[9] === "1",
|
|
199
|
+
coveragePct: parseFloat(cols[10]) || 0,
|
|
200
|
+
pkgSizeKb: parseInt(cols[11]) || 0,
|
|
201
|
+
};
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
return [];
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=benchmark.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"benchmark.js","sourceRoot":"","sources":["../../core/benchmark.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface CleanupConfig {
|
|
2
|
+
cleanup: {
|
|
3
|
+
onNewPlan: "archive" | "delete" | "keep";
|
|
4
|
+
traceRetentionDays: number;
|
|
5
|
+
sessionRetentionDays: number;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export declare function readConfig(cwd?: string): Promise<CleanupConfig>;
|
|
9
|
+
export declare function writeConfig(config: CleanupConfig, cwd?: string): Promise<void>;
|
|
10
|
+
export interface CleanResult {
|
|
11
|
+
removed: string[];
|
|
12
|
+
archived: string[];
|
|
13
|
+
skipped: string[];
|
|
14
|
+
}
|
|
15
|
+
export declare function cleanTraces(cwd?: string): Promise<CleanResult>;
|
|
16
|
+
export declare function cleanResults(cwd?: string): Promise<CleanResult>;
|
|
17
|
+
export declare function cleanSessions(options?: {
|
|
18
|
+
cwd?: string;
|
|
19
|
+
before?: Date;
|
|
20
|
+
}): Promise<CleanResult>;
|
|
21
|
+
export declare function cleanAll(cwd?: string): Promise<CleanResult>;
|
|
22
|
+
export declare function archiveCurrentData(cwd?: string): Promise<CleanResult>;
|
|
23
|
+
export declare function applyOnNewPlanPolicy(cwd?: string): Promise<CleanResult>;
|
|
24
|
+
//# sourceMappingURL=cleanup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../../core/cleanup.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE;QACP,SAAS,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;QACzC,kBAAkB,EAAE,MAAM,CAAC;QAC3B,oBAAoB,EAAE,MAAM,CAAC;KAC9B,CAAC;CACH;AAiBD,wBAAsB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAWrE;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIpF;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAsB,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAWpE;AAED,wBAAsB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAWrE;AAED,wBAAsB,aAAa,CAAC,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,IAAI,CAAA;CAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAsBnG;AAED,wBAAsB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAUjE;AAED,wBAAsB,kBAAkB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAoC3E;AAED,wBAAsB,oBAAoB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAW7E"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// core/cleanup.ts
|
|
2
|
+
// Data lifecycle management for .loophaus/ directory
|
|
3
|
+
import { readFile, writeFile, readdir, rm, rename, mkdir, stat } from "node:fs/promises";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
const DEFAULT_CONFIG = {
|
|
6
|
+
cleanup: {
|
|
7
|
+
onNewPlan: "keep",
|
|
8
|
+
traceRetentionDays: 30,
|
|
9
|
+
sessionRetentionDays: 7,
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
// Files that are NEVER deleted by any clean operation
|
|
13
|
+
const PROTECTED_FILES = new Set(["benchmark.tsv", "config.json"]);
|
|
14
|
+
function getLoophausDir(cwd) {
|
|
15
|
+
return join(cwd || process.cwd(), ".loophaus");
|
|
16
|
+
}
|
|
17
|
+
export async function readConfig(cwd) {
|
|
18
|
+
const configPath = join(getLoophausDir(cwd), "config.json");
|
|
19
|
+
try {
|
|
20
|
+
const raw = await readFile(configPath, "utf-8");
|
|
21
|
+
const parsed = JSON.parse(raw);
|
|
22
|
+
return {
|
|
23
|
+
cleanup: { ...DEFAULT_CONFIG.cleanup, ...parsed.cleanup },
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return { ...DEFAULT_CONFIG };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export async function writeConfig(config, cwd) {
|
|
31
|
+
const dir = getLoophausDir(cwd);
|
|
32
|
+
await mkdir(dir, { recursive: true });
|
|
33
|
+
await writeFile(join(dir, "config.json"), JSON.stringify(config, null, 2), "utf-8");
|
|
34
|
+
}
|
|
35
|
+
export async function cleanTraces(cwd) {
|
|
36
|
+
const dir = getLoophausDir(cwd);
|
|
37
|
+
const result = { removed: [], archived: [], skipped: [] };
|
|
38
|
+
const tracePath = join(dir, "trace.jsonl");
|
|
39
|
+
try {
|
|
40
|
+
await rm(tracePath);
|
|
41
|
+
result.removed.push("trace.jsonl");
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
result.skipped.push("trace.jsonl");
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
export async function cleanResults(cwd) {
|
|
49
|
+
const dir = getLoophausDir(cwd);
|
|
50
|
+
const result = { removed: [], archived: [], skipped: [] };
|
|
51
|
+
const resultsPath = join(dir, "results.tsv");
|
|
52
|
+
try {
|
|
53
|
+
await rm(resultsPath);
|
|
54
|
+
result.removed.push("results.tsv");
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
result.skipped.push("results.tsv");
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
export async function cleanSessions(options) {
|
|
62
|
+
const dir = join(getLoophausDir(options?.cwd), "sessions");
|
|
63
|
+
const result = { removed: [], archived: [], skipped: [] };
|
|
64
|
+
try {
|
|
65
|
+
const files = await readdir(dir);
|
|
66
|
+
for (const file of files) {
|
|
67
|
+
if (!file.endsWith(".json"))
|
|
68
|
+
continue;
|
|
69
|
+
const filePath = join(dir, file);
|
|
70
|
+
if (options?.before) {
|
|
71
|
+
const s = await stat(filePath);
|
|
72
|
+
if (s.mtime >= options.before) {
|
|
73
|
+
result.skipped.push(file);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
await rm(filePath);
|
|
78
|
+
result.removed.push(file);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// sessions/ doesn't exist
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
export async function cleanAll(cwd) {
|
|
87
|
+
const result = { removed: [], archived: [], skipped: [] };
|
|
88
|
+
const r1 = await cleanTraces(cwd);
|
|
89
|
+
const r2 = await cleanResults(cwd);
|
|
90
|
+
const r3 = await cleanSessions({ cwd });
|
|
91
|
+
result.removed.push(...r1.removed, ...r2.removed, ...r3.removed);
|
|
92
|
+
result.skipped.push(...r1.skipped, ...r2.skipped, ...r3.skipped);
|
|
93
|
+
// Explicitly note protected files
|
|
94
|
+
result.skipped.push("benchmark.tsv (protected)", "config.json (protected)");
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
export async function archiveCurrentData(cwd) {
|
|
98
|
+
const dir = getLoophausDir(cwd);
|
|
99
|
+
const result = { removed: [], archived: [], skipped: [] };
|
|
100
|
+
const dateStr = new Date().toISOString().split("T")[0];
|
|
101
|
+
const archiveDir = join(dir, "archive", dateStr);
|
|
102
|
+
await mkdir(archiveDir, { recursive: true });
|
|
103
|
+
const filesToArchive = ["trace.jsonl", "results.tsv"];
|
|
104
|
+
for (const file of filesToArchive) {
|
|
105
|
+
const src = join(dir, file);
|
|
106
|
+
const dest = join(archiveDir, file);
|
|
107
|
+
try {
|
|
108
|
+
await rename(src, dest);
|
|
109
|
+
result.archived.push(`${file} → archive/${dateStr}/${file}`);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
result.skipped.push(file);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Archive sessions
|
|
116
|
+
const sessionsDir = join(dir, "sessions");
|
|
117
|
+
try {
|
|
118
|
+
const files = await readdir(sessionsDir);
|
|
119
|
+
if (files.length > 0) {
|
|
120
|
+
const sessArchive = join(archiveDir, "sessions");
|
|
121
|
+
await mkdir(sessArchive, { recursive: true });
|
|
122
|
+
for (const file of files) {
|
|
123
|
+
await rename(join(sessionsDir, file), join(sessArchive, file));
|
|
124
|
+
result.archived.push(`sessions/${file}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// no sessions
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
export async function applyOnNewPlanPolicy(cwd) {
|
|
134
|
+
const config = await readConfig(cwd);
|
|
135
|
+
switch (config.cleanup.onNewPlan) {
|
|
136
|
+
case "archive":
|
|
137
|
+
return archiveCurrentData(cwd);
|
|
138
|
+
case "delete":
|
|
139
|
+
return cleanAll(cwd);
|
|
140
|
+
case "keep":
|
|
141
|
+
default:
|
|
142
|
+
return { removed: [], archived: [], skipped: ["policy: keep (no cleanup)"] };
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=cleanup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../../core/cleanup.ts"],"names":[],"mappings":"AAAA,kBAAkB;AAClB,qDAAqD;AAErD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAUjC,MAAM,cAAc,GAAkB;IACpC,OAAO,EAAE;QACP,SAAS,EAAE,MAAM;QACjB,kBAAkB,EAAE,EAAE;QACtB,oBAAoB,EAAE,CAAC;KACxB;CACF,CAAC;AAEF,sDAAsD;AACtD,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC,CAAC;AAElE,SAAS,cAAc,CAAC,GAAY;IAClC,OAAO,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAY;IAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC,CAAC;IAC5D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA2B,CAAC;QACzD,OAAO;YACL,OAAO,EAAE,EAAE,GAAG,cAAc,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE;SAC1D,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAqB,EAAE,GAAY;IACnE,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACtF,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAY;IAC5C,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,MAAM,GAAgB,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACvE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC;QACpB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAY;IAC7C,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,MAAM,GAAgB,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACvE,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAC7C,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,WAAW,CAAC,CAAC;QACtB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAyC;IAC3E,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAgB,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACvE,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,SAAS;YACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACjC,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;gBACpB,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC/B,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;oBAC9B,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC1B,SAAS;gBACX,CAAC;YACH,CAAC;YACD,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC;YACnB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,0BAA0B;IAC5B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAY;IACzC,MAAM,MAAM,GAAgB,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACvE,MAAM,EAAE,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IACxC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC;IACjE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC;IACjE,kCAAkC;IAClC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,2BAA2B,EAAE,yBAAyB,CAAC,CAAC;IAC5E,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,GAAY;IACnD,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,MAAM,GAAgB,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACvE,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACjD,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7C,MAAM,cAAc,GAAG,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IACtD,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACxB,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,cAAc,OAAO,IAAI,IAAI,EAAE,CAAC,CAAC;QAC/D,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAC1C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;QACzC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YACjD,MAAM,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;gBAC/D,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,cAAc;IAChB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,GAAY;IACrD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;IACrC,QAAQ,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QACjC,KAAK,SAAS;YACZ,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC;QACjC,KAAK,QAAQ;YACX,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;QACvB,KAAK,MAAM,CAAC;QACZ;YACE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,2BAA2B,CAAC,EAAE,CAAC;IACjF,CAAC;AACH,CAAC"}
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graypark/loophaus",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "loophaus — Control plane for coding agents. Iterative dev loops with multi-agent orchestration.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"postbuild": "node -e \"const fs=require('fs');const p=require('path');['platforms','hooks','codex','commands','scripts','skills','.claude-plugin'].forEach(d=>{const s=p.join(__dirname,d);const t=p.join(__dirname,'dist',d);if(fs.existsSync(s))fs.cpSync(s,t,{recursive:true})});['package.json','LICENSE','README.md','README.ko.md'].forEach(f=>{const s=p.join(__dirname,f);const t=p.join(__dirname,'dist',f);if(fs.existsSync(s))fs.cpSync(s,t)})\"",
|
|
38
38
|
"typecheck": "tsc --noEmit",
|
|
39
39
|
"test": "vitest run",
|
|
40
|
+
"test:coverage": "vitest run --coverage",
|
|
40
41
|
"postinstall": "echo 'Run: npx loophaus --help'",
|
|
41
42
|
"prepublishOnly": "npm run build",
|
|
42
43
|
"prepare": "npm run build"
|
|
@@ -55,6 +56,7 @@
|
|
|
55
56
|
],
|
|
56
57
|
"devDependencies": {
|
|
57
58
|
"@types/node": "^25.5.0",
|
|
59
|
+
"@vitest/coverage-v8": "^4.1.2",
|
|
58
60
|
"typescript": "^6.0.2",
|
|
59
61
|
"vitest": "^4.1.0"
|
|
60
62
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graypark/loophaus",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "loophaus — Control plane for coding agents. Iterative dev loops with multi-agent orchestration.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"postbuild": "node -e \"const fs=require('fs');const p=require('path');['platforms','hooks','codex','commands','scripts','skills','.claude-plugin'].forEach(d=>{const s=p.join(__dirname,d);const t=p.join(__dirname,'dist',d);if(fs.existsSync(s))fs.cpSync(s,t,{recursive:true})});['package.json','LICENSE','README.md','README.ko.md'].forEach(f=>{const s=p.join(__dirname,f);const t=p.join(__dirname,'dist',f);if(fs.existsSync(s))fs.cpSync(s,t)})\"",
|
|
38
38
|
"typecheck": "tsc --noEmit",
|
|
39
39
|
"test": "vitest run",
|
|
40
|
+
"test:coverage": "vitest run --coverage",
|
|
40
41
|
"postinstall": "echo 'Run: npx loophaus --help'",
|
|
41
42
|
"prepublishOnly": "npm run build",
|
|
42
43
|
"prepare": "npm run build"
|
|
@@ -55,6 +56,7 @@
|
|
|
55
56
|
],
|
|
56
57
|
"devDependencies": {
|
|
57
58
|
"@types/node": "^25.5.0",
|
|
59
|
+
"@vitest/coverage-v8": "^4.1.2",
|
|
58
60
|
"typescript": "^6.0.2",
|
|
59
61
|
"vitest": "^4.1.0"
|
|
60
62
|
}
|