@graypark/loophaus 3.4.1 → 3.5.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 +81 -17
- package/README.md +69 -15
- package/dist/.claude-plugin/plugin.json +11 -0
- package/dist/LICENSE +21 -0
- package/dist/README.ko.md +422 -0
- package/dist/README.md +336 -0
- package/dist/bin/install.d.ts +3 -0
- package/dist/bin/install.d.ts.map +1 -0
- package/{bin/install.mjs → dist/bin/install.js} +3 -5
- package/dist/bin/install.js.map +1 -0
- package/dist/bin/loophaus.d.ts +3 -0
- package/dist/bin/loophaus.d.ts.map +1 -0
- package/dist/bin/loophaus.js +654 -0
- package/dist/bin/loophaus.js.map +1 -0
- package/dist/bin/uninstall.d.ts +8 -0
- package/dist/bin/uninstall.d.ts.map +1 -0
- package/dist/bin/uninstall.js +209 -0
- package/dist/bin/uninstall.js.map +1 -0
- package/dist/codex/commands/cancel-ralph.md +30 -0
- package/dist/codex/commands/ralph-loop.md +73 -0
- package/dist/commands/cancel-ralph.md +23 -0
- package/dist/commands/help.md +96 -0
- package/dist/commands/loop-plan.md +257 -0
- package/dist/commands/loop-pulse.md +38 -0
- package/dist/commands/loop-stop.md +29 -0
- package/dist/commands/loop.md +17 -0
- package/dist/commands/ralph-loop.md +18 -0
- package/dist/core/cost-tracker.d.ts +33 -0
- package/dist/core/cost-tracker.d.ts.map +1 -0
- package/dist/core/cost-tracker.js +41 -0
- package/dist/core/cost-tracker.js.map +1 -0
- package/dist/core/engine.d.ts +4 -0
- package/dist/core/engine.d.ts.map +1 -0
- package/dist/core/engine.js +109 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/event-logger.d.ts +5 -0
- package/dist/core/event-logger.d.ts.map +1 -0
- package/dist/core/event-logger.js +48 -0
- package/dist/core/event-logger.js.map +1 -0
- package/dist/core/events.d.ts +34 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/events.js +44 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/io-helpers.d.ts +3 -0
- package/dist/core/io-helpers.d.ts.map +1 -0
- package/dist/core/io-helpers.js +65 -0
- package/dist/core/io-helpers.js.map +1 -0
- package/dist/core/loop-registry.d.ts +10 -0
- package/dist/core/loop-registry.d.ts.map +1 -0
- package/dist/core/loop-registry.js +37 -0
- package/dist/core/loop-registry.js.map +1 -0
- package/dist/core/merge-strategy.d.ts +7 -0
- package/dist/core/merge-strategy.d.ts.map +1 -0
- package/dist/core/merge-strategy.js +82 -0
- package/dist/core/merge-strategy.js.map +1 -0
- package/dist/core/parallel-runner.d.ts +32 -0
- package/dist/core/parallel-runner.d.ts.map +1 -0
- package/dist/core/parallel-runner.js +88 -0
- package/dist/core/parallel-runner.js.map +1 -0
- package/dist/core/policy.d.ts +22 -0
- package/dist/core/policy.d.ts.map +1 -0
- package/dist/core/policy.js +54 -0
- package/dist/core/policy.js.map +1 -0
- package/dist/core/quality-scorer.d.ts +40 -0
- package/dist/core/quality-scorer.d.ts.map +1 -0
- package/dist/core/quality-scorer.js +128 -0
- package/dist/core/quality-scorer.js.map +1 -0
- package/dist/core/refine-loop.d.ts +16 -0
- package/dist/core/refine-loop.d.ts.map +1 -0
- package/dist/core/refine-loop.js +26 -0
- package/dist/core/refine-loop.js.map +1 -0
- package/dist/core/session.d.ts +27 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +67 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/trace-analyzer.d.ts +28 -0
- package/dist/core/trace-analyzer.d.ts.map +1 -0
- package/dist/core/trace-analyzer.js +46 -0
- package/dist/core/trace-analyzer.js.map +1 -0
- package/dist/core/types.d.ts +99 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/validate.d.ts +7 -0
- package/dist/core/validate.d.ts.map +1 -0
- package/dist/core/validate.js +55 -0
- package/dist/core/validate.js.map +1 -0
- package/dist/core/worktree.d.ts +13 -0
- package/dist/core/worktree.d.ts.map +1 -0
- package/dist/core/worktree.js +108 -0
- package/dist/core/worktree.js.map +1 -0
- package/dist/hooks/hooks.json +15 -0
- package/dist/hooks/stop-hook.mjs +111 -0
- package/dist/lib/paths.d.ts +18 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +74 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/stop-hook-core.d.ts +19 -0
- package/dist/lib/stop-hook-core.d.ts.map +1 -0
- package/dist/lib/stop-hook-core.js +36 -0
- package/dist/lib/stop-hook-core.js.map +1 -0
- package/dist/package.json +61 -0
- package/dist/platforms/claude-code/adapter.mjs +20 -0
- package/dist/platforms/claude-code/installer.d.mts +3 -0
- package/dist/platforms/claude-code/installer.mjs +173 -0
- package/dist/platforms/codex-cli/adapter.mjs +20 -0
- package/dist/platforms/codex-cli/installer.d.mts +2 -0
- package/dist/platforms/codex-cli/installer.mjs +247 -0
- package/dist/platforms/kiro-cli/adapter.mjs +21 -0
- package/dist/platforms/kiro-cli/installer.d.mts +3 -0
- package/dist/platforms/kiro-cli/installer.mjs +257 -0
- package/dist/scripts/setup-ralph-loop.sh +145 -0
- package/dist/skills/ralph-claude-cancel/SKILL.md +23 -0
- package/dist/skills/ralph-claude-interview/SKILL.md +184 -0
- package/dist/skills/ralph-claude-loop/SKILL.md +101 -0
- package/dist/skills/ralph-claude-orchestrator/SKILL.md +129 -0
- package/dist/skills/ralph-interview/SKILL.md +275 -0
- package/dist/skills/ralph-orchestrator/SKILL.md +254 -0
- package/dist/store/state-store.d.ts +17 -0
- package/dist/store/state-store.d.ts.map +1 -0
- package/dist/store/state-store.js +108 -0
- package/dist/store/state-store.js.map +1 -0
- package/hooks/stop-hook.mjs +6 -6
- package/package.json +11 -7
- package/platforms/claude-code/installer.d.mts +3 -0
- package/platforms/claude-code/installer.mjs +2 -2
- package/platforms/codex-cli/installer.d.mts +2 -0
- package/platforms/codex-cli/installer.mjs +1 -1
- package/platforms/kiro-cli/installer.d.mts +3 -0
- package/bin/loophaus.mjs +0 -521
- package/bin/uninstall.mjs +0 -255
- package/core/cost-tracker.mjs +0 -44
- package/core/engine.mjs +0 -123
- package/core/event-logger.mjs +0 -37
- package/core/events.mjs +0 -48
- package/core/io-helpers.mjs +0 -33
- package/core/loop-registry.mjs +0 -37
- package/core/loop.schema.json +0 -29
- package/core/merge-strategy.mjs +0 -72
- package/core/parallel-runner.mjs +0 -94
- package/core/policy.mjs +0 -58
- package/core/quality-scorer.mjs +0 -136
- package/core/refine-loop.mjs +0 -29
- package/core/session.mjs +0 -66
- package/core/state.schema.json +0 -24
- package/core/trace-analyzer.mjs +0 -51
- package/core/validate.mjs +0 -54
- package/core/worktree.mjs +0 -97
- package/lib/paths.mjs +0 -99
- package/lib/stop-hook-core.mjs +0 -42
- package/store/state-store.mjs +0 -106
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// core/quality-scorer.ts
|
|
2
|
+
// Quality scoring for story implementations (autoresearch pattern: val_bpb -> quality score)
|
|
3
|
+
import { execFile } from "node:child_process";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
import { readFile, stat } from "node:fs/promises";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
const execFileAsync = promisify(execFile);
|
|
8
|
+
const CRITERIA = {
|
|
9
|
+
tests: { weight: 3, max: 10 },
|
|
10
|
+
typecheck: { weight: 2, max: 10 },
|
|
11
|
+
lint: { weight: 1, max: 10 },
|
|
12
|
+
verify: { weight: 2, max: 10 },
|
|
13
|
+
diff: { weight: 1, max: 10 },
|
|
14
|
+
custom: { weight: 1, max: 10 },
|
|
15
|
+
};
|
|
16
|
+
export function scoreStory(results) {
|
|
17
|
+
let totalWeight = 0;
|
|
18
|
+
let weightedSum = 0;
|
|
19
|
+
const breakdown = {};
|
|
20
|
+
for (const [key, config] of Object.entries(CRITERIA)) {
|
|
21
|
+
if (results[key] === undefined || results[key] === null)
|
|
22
|
+
continue;
|
|
23
|
+
const raw = results[key];
|
|
24
|
+
const value = typeof raw === "number" ? raw : (raw.score ?? 0);
|
|
25
|
+
const clamped = Math.max(0, Math.min(config.max, value));
|
|
26
|
+
breakdown[key] = clamped;
|
|
27
|
+
weightedSum += clamped * config.weight;
|
|
28
|
+
totalWeight += config.max * config.weight;
|
|
29
|
+
}
|
|
30
|
+
const score = totalWeight > 0 ? Math.round((weightedSum / totalWeight) * 100) : 0;
|
|
31
|
+
const grade = score >= 90 ? "A" : score >= 80 ? "B" : score >= 70 ? "C" : score >= 60 ? "D" : "F";
|
|
32
|
+
return { score, grade, breakdown };
|
|
33
|
+
}
|
|
34
|
+
export async function evaluateStory(storyId, cwd, config = {}) {
|
|
35
|
+
const results = {};
|
|
36
|
+
if (config.testCommand) {
|
|
37
|
+
try {
|
|
38
|
+
await execFileAsync("sh", ["-c", config.testCommand], { cwd, timeout: 120_000 });
|
|
39
|
+
results.tests = 10;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
results.tests = 0;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (config.typecheckCommand) {
|
|
46
|
+
try {
|
|
47
|
+
await execFileAsync("sh", ["-c", config.typecheckCommand], { cwd, timeout: 60_000 });
|
|
48
|
+
results.typecheck = 10;
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
const errorCount = (err.stdout || "").split("\n").filter(l => l.includes("error")).length;
|
|
52
|
+
results.typecheck = Math.max(0, 10 - errorCount);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (config.lintCommand) {
|
|
56
|
+
try {
|
|
57
|
+
await execFileAsync("sh", ["-c", config.lintCommand], { cwd, timeout: 60_000 });
|
|
58
|
+
results.lint = 10;
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
const warnings = (err.stdout || "").split("\n").filter(l => l.includes("warning") || l.includes("error")).length;
|
|
62
|
+
results.lint = Math.max(0, 10 - warnings);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (config.verifyScript) {
|
|
66
|
+
try {
|
|
67
|
+
await execFileAsync("sh", ["-c", config.verifyScript], { cwd, timeout: 60_000 });
|
|
68
|
+
results.verify = 10;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
results.verify = 0;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
const { stdout } = await execFileAsync("git", ["diff", "--stat", "HEAD~1"], { cwd, timeout: 10_000 });
|
|
76
|
+
const lines = stdout.trim().split("\n");
|
|
77
|
+
const lastLine = lines[lines.length - 1] || "";
|
|
78
|
+
const match = lastLine.match(/(\d+) insertion.+?(\d+) deletion/);
|
|
79
|
+
if (match) {
|
|
80
|
+
const total = parseInt(match[1]) + parseInt(match[2]);
|
|
81
|
+
results.diff = total < 100 ? 10 : total < 300 ? 8 : total < 500 ? 6 : total < 1000 ? 4 : 2;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// No git diff available
|
|
86
|
+
}
|
|
87
|
+
const customPath = join(cwd, ".loophaus", "quality.mjs");
|
|
88
|
+
try {
|
|
89
|
+
await stat(customPath);
|
|
90
|
+
const mod = await import(customPath);
|
|
91
|
+
if (typeof mod.evaluate === "function") {
|
|
92
|
+
const customResult = await mod.evaluate(storyId, cwd);
|
|
93
|
+
results.custom = typeof customResult === "number" ? customResult : (customResult?.score ?? 0);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// No custom evaluator
|
|
98
|
+
}
|
|
99
|
+
return { storyId, results, ...scoreStory(results) };
|
|
100
|
+
}
|
|
101
|
+
export async function logResult(entry, cwd) {
|
|
102
|
+
const { appendFile, mkdir } = await import("node:fs/promises");
|
|
103
|
+
const tsvPath = join(cwd || process.cwd(), ".loophaus", "results.tsv");
|
|
104
|
+
await mkdir(join(cwd || process.cwd(), ".loophaus"), { recursive: true });
|
|
105
|
+
try {
|
|
106
|
+
await stat(tsvPath);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
await appendFile(tsvPath, "story_id\tattempt\tscore\tstatus\tdescription\tcommit\n", "utf-8");
|
|
110
|
+
}
|
|
111
|
+
const line = `${entry.storyId}\t${entry.attempt}\t${entry.score}\t${entry.status}\t${entry.description}\t${entry.commit || ""}\n`;
|
|
112
|
+
await appendFile(tsvPath, line, "utf-8");
|
|
113
|
+
}
|
|
114
|
+
export async function readResults(cwd) {
|
|
115
|
+
const tsvPath = join(cwd || process.cwd(), ".loophaus", "results.tsv");
|
|
116
|
+
try {
|
|
117
|
+
const raw = await readFile(tsvPath, "utf-8");
|
|
118
|
+
const lines = raw.trim().split("\n").slice(1);
|
|
119
|
+
return lines.map(line => {
|
|
120
|
+
const [storyId, attempt, score, status, description, commit] = line.split("\t");
|
|
121
|
+
return { storyId, attempt: parseInt(attempt), score: parseInt(score), status, description, commit };
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return [];
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=quality-scorer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quality-scorer.js","sourceRoot":"","sources":["../../core/quality-scorer.ts"],"names":[],"mappings":"AAAA,yBAAyB;AACzB,6FAA6F;AAE7F,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAO1C,MAAM,QAAQ,GAAoC;IAChD,KAAK,EAAM,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IACjC,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IACjC,IAAI,EAAO,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IACjC,MAAM,EAAK,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IACjC,IAAI,EAAO,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IACjC,MAAM,EAAK,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;CAClC,CAAC;AAUF,MAAM,UAAU,UAAU,CAAC,OAAoC;IAC7D,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,MAAM,SAAS,GAA2B,EAAE,CAAC;IAE7C,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrD,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI;YAAE,SAAS;QAClE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAA0B,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;QACvF,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QACzD,SAAS,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;QACzB,WAAW,IAAI,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC;QACvC,WAAW,IAAI,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC;IAC5C,CAAC;IAED,MAAM,KAAK,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClF,MAAM,KAAK,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAElG,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AACrC,CAAC;AAcD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe,EAAE,GAAW,EAAE,SAAyB,EAAE;IAC3F,MAAM,OAAO,GAA2B,EAAE,CAAC;IAE3C,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YACjF,OAAO,CAAC,KAAK,GAAG,EAAE,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,gBAAgB,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YACrF,OAAO,CAAC,SAAS,GAAG,EAAE,CAAC;QACzB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,UAAU,GAAG,CAAE,GAA2B,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;YACnH,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,UAAU,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAChF,OAAO,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,QAAQ,GAAG,CAAE,GAA2B,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;YAC1I,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,QAAQ,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YACjF,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACtG,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/C,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACjE,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7F,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;IAC1B,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;IACzD,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC;QACvB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,UAAU,CAA0F,CAAC;QAC9H,IAAI,OAAO,GAAG,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;YACvC,MAAM,YAAY,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YACtD,OAAO,CAAC,MAAM,GAAG,OAAO,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAE,YAAmC,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC;QACxH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,sBAAsB;IACxB,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;AACtD,CAAC;AAWD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAe,EAAE,GAAY;IAC3D,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;IACvE,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1E,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,UAAU,CAAC,OAAO,EAAE,yDAAyD,EAAE,OAAO,CAAC,CAAC;IAChG,CAAC;IAED,MAAM,IAAI,GAAG,GAAG,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC,MAAM,IAAI,EAAE,IAAI,CAAC;IAClI,MAAM,UAAU,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC;AAWD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAY;IAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;IACvE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9C,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;YACtB,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAChF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;QACtG,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
interface Evaluation {
|
|
2
|
+
storyId: string;
|
|
3
|
+
score: number;
|
|
4
|
+
grade: string;
|
|
5
|
+
breakdown: Record<string, number>;
|
|
6
|
+
}
|
|
7
|
+
interface PreviousAttempt {
|
|
8
|
+
attempt: number;
|
|
9
|
+
score: number;
|
|
10
|
+
status: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function shouldKeep(newScore: number, baselineScore: number): boolean;
|
|
13
|
+
export declare function generateFeedback(evaluation: Evaluation, previousAttempts?: PreviousAttempt[]): string;
|
|
14
|
+
export declare function identifyRefinementTargets(evaluations: Evaluation[], threshold?: number): Evaluation[];
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=refine-loop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refine-loop.d.ts","sourceRoot":"","sources":["../../core/refine-loop.ts"],"names":[],"mappings":"AAGA,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAE3E;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,gBAAgB,GAAE,eAAe,EAAO,GAAG,MAAM,CAezG;AAED,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,SAAS,GAAE,MAAW,GAAG,UAAU,EAAE,CAIzG"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// core/refine-loop.ts
|
|
2
|
+
// autoresearch keep/discard pattern for code quality improvement
|
|
3
|
+
export function shouldKeep(newScore, baselineScore) {
|
|
4
|
+
return newScore > baselineScore;
|
|
5
|
+
}
|
|
6
|
+
export function generateFeedback(evaluation, previousAttempts = []) {
|
|
7
|
+
const { storyId, score, grade, breakdown } = evaluation;
|
|
8
|
+
const failedCriteria = Object.entries(breakdown)
|
|
9
|
+
.filter(([_, v]) => v < 7)
|
|
10
|
+
.map(([k, v]) => `${k}: ${v}/10`);
|
|
11
|
+
let prompt = `Story ${storyId} quality: ${score}/100 (${grade}).\n`;
|
|
12
|
+
if (failedCriteria.length > 0) {
|
|
13
|
+
prompt += `Weak areas: ${failedCriteria.join(", ")}.\n`;
|
|
14
|
+
}
|
|
15
|
+
if (previousAttempts.length > 0) {
|
|
16
|
+
prompt += `Previous attempts: ${previousAttempts.map(a => `attempt ${a.attempt}: ${a.score} (${a.status})`).join(", ")}.\n`;
|
|
17
|
+
}
|
|
18
|
+
prompt += `Improve the implementation. Focus on the weak areas. Try a different approach if the same strategy keeps failing.`;
|
|
19
|
+
return prompt;
|
|
20
|
+
}
|
|
21
|
+
export function identifyRefinementTargets(evaluations, threshold = 80) {
|
|
22
|
+
return evaluations
|
|
23
|
+
.filter(e => e.score < threshold)
|
|
24
|
+
.sort((a, b) => a.score - b.score);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=refine-loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refine-loop.js","sourceRoot":"","sources":["../../core/refine-loop.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,iEAAiE;AAejE,MAAM,UAAU,UAAU,CAAC,QAAgB,EAAE,aAAqB;IAChE,OAAO,QAAQ,GAAG,aAAa,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,UAAsB,EAAE,mBAAsC,EAAE;IAC/F,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC;IACxD,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;SAC7C,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;SACzB,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAEpC,IAAI,MAAM,GAAG,SAAS,OAAO,aAAa,KAAK,SAAS,KAAK,MAAM,CAAC;IACpE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,eAAe,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;IAC1D,CAAC;IACD,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,sBAAsB,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;IAC9H,CAAC;IACD,MAAM,IAAI,mHAAmH,CAAC;IAC9H,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,WAAyB,EAAE,YAAoB,EAAE;IACzF,OAAO,WAAW;SACf,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,SAAS,CAAC;SAChC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
interface CheckpointData {
|
|
2
|
+
[key: string]: unknown;
|
|
3
|
+
}
|
|
4
|
+
interface Checkpoint extends CheckpointData {
|
|
5
|
+
sessionId: string;
|
|
6
|
+
savedAt: string;
|
|
7
|
+
}
|
|
8
|
+
interface SessionData {
|
|
9
|
+
savedAt: string;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
export declare function saveCheckpoint(sessionId: string, data: CheckpointData, cwd?: string): Promise<Checkpoint>;
|
|
13
|
+
export declare function loadCheckpoint(sessionId: string, cwd?: string): Promise<Checkpoint | null>;
|
|
14
|
+
export declare function listSessions(cwd?: string): Promise<SessionData[]>;
|
|
15
|
+
interface ResumedState {
|
|
16
|
+
active: boolean;
|
|
17
|
+
prompt: string;
|
|
18
|
+
completionPromise: string;
|
|
19
|
+
maxIterations: number;
|
|
20
|
+
currentIteration: number;
|
|
21
|
+
sessionId: string;
|
|
22
|
+
name: string;
|
|
23
|
+
startedAt: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function resumeSession(sessionId: string, cwd?: string): Promise<ResumedState | null>;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../core/session.ts"],"names":[],"mappings":"AAGA,UAAU,cAAc;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,UAAU,UAAW,SAAQ,cAAc;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAMD,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAU/G;AAED,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAQhG;AAED,wBAAsB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAiBvE;AAYD,UAAU,YAAY;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAkBjG"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { readFile, writeFile, readdir, mkdir } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
function getSessionsDir(cwd) {
|
|
4
|
+
return join(cwd || process.cwd(), ".loophaus", "sessions");
|
|
5
|
+
}
|
|
6
|
+
export async function saveCheckpoint(sessionId, data, cwd) {
|
|
7
|
+
const dir = getSessionsDir(cwd);
|
|
8
|
+
await mkdir(dir, { recursive: true });
|
|
9
|
+
const checkpoint = {
|
|
10
|
+
sessionId,
|
|
11
|
+
savedAt: new Date().toISOString(),
|
|
12
|
+
...data,
|
|
13
|
+
};
|
|
14
|
+
await writeFile(join(dir, `${sessionId}.json`), JSON.stringify(checkpoint, null, 2), "utf-8");
|
|
15
|
+
return checkpoint;
|
|
16
|
+
}
|
|
17
|
+
export async function loadCheckpoint(sessionId, cwd) {
|
|
18
|
+
const dir = getSessionsDir(cwd);
|
|
19
|
+
try {
|
|
20
|
+
const raw = await readFile(join(dir, `${sessionId}.json`), "utf-8");
|
|
21
|
+
return JSON.parse(raw);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export async function listSessions(cwd) {
|
|
28
|
+
const dir = getSessionsDir(cwd);
|
|
29
|
+
try {
|
|
30
|
+
const files = await readdir(dir);
|
|
31
|
+
const sessions = [];
|
|
32
|
+
for (const file of files) {
|
|
33
|
+
if (!file.endsWith(".json"))
|
|
34
|
+
continue;
|
|
35
|
+
try {
|
|
36
|
+
const raw = await readFile(join(dir, file), "utf-8");
|
|
37
|
+
const data = JSON.parse(raw);
|
|
38
|
+
sessions.push(data);
|
|
39
|
+
}
|
|
40
|
+
catch { /* skip malformed */ }
|
|
41
|
+
}
|
|
42
|
+
return sessions.sort((a, b) => new Date(b.savedAt).getTime() - new Date(a.savedAt).getTime());
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export async function resumeSession(sessionId, cwd) {
|
|
49
|
+
const checkpoint = await loadCheckpoint(sessionId, cwd);
|
|
50
|
+
if (!checkpoint)
|
|
51
|
+
return null;
|
|
52
|
+
const stateStore = await import("../store/state-store.js");
|
|
53
|
+
const write = stateStore.write;
|
|
54
|
+
const state = {
|
|
55
|
+
active: true,
|
|
56
|
+
prompt: checkpoint.prompt || "",
|
|
57
|
+
completionPromise: checkpoint.completionPromise || "TADA",
|
|
58
|
+
maxIterations: checkpoint.maxIterations || 20,
|
|
59
|
+
currentIteration: checkpoint.currentIteration || 0,
|
|
60
|
+
sessionId: checkpoint.sessionId,
|
|
61
|
+
name: checkpoint.name || "",
|
|
62
|
+
startedAt: checkpoint.startedAt || new Date().toISOString(),
|
|
63
|
+
};
|
|
64
|
+
await write(state, cwd, checkpoint.name);
|
|
65
|
+
return state;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../core/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { LoopEvent } from "./types.js";
|
|
2
|
+
import type { EventSummary } from "./events.js";
|
|
3
|
+
export interface TraceAnalysis extends EventSummary {
|
|
4
|
+
iterations: number;
|
|
5
|
+
stops: number;
|
|
6
|
+
errors: number;
|
|
7
|
+
storiesCompleted: number;
|
|
8
|
+
totalCost: number;
|
|
9
|
+
lastStopReason: string | null;
|
|
10
|
+
avgIterationMs: number;
|
|
11
|
+
}
|
|
12
|
+
export interface TraceComparison {
|
|
13
|
+
trace1: TraceAnalysis;
|
|
14
|
+
trace2: TraceAnalysis;
|
|
15
|
+
diff: {
|
|
16
|
+
iterations: number;
|
|
17
|
+
totalCost: number;
|
|
18
|
+
durationMs: number;
|
|
19
|
+
storiesCompleted: number;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export interface ReplayEvent extends LoopEvent {
|
|
23
|
+
relativeMs: number;
|
|
24
|
+
}
|
|
25
|
+
export declare function analyzeTrace(events: LoopEvent[]): TraceAnalysis;
|
|
26
|
+
export declare function compareTraces(trace1: LoopEvent[], trace2: LoopEvent[]): TraceComparison;
|
|
27
|
+
export declare function replayTrace(events: LoopEvent[], speed?: number): ReplayEvent[];
|
|
28
|
+
//# sourceMappingURL=trace-analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-analyzer.d.ts","sourceRoot":"","sources":["../../core/trace-analyzer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE;QACJ,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAED,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,aAAa,CAqB/D;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,eAAe,CAcvF;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,GAAE,MAAU,GAAG,WAAW,EAAE,CAOjF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Pure functions for trace analysis
|
|
2
|
+
import { EventType, filterByType, summarizeEvents } from "./events.js";
|
|
3
|
+
export function analyzeTrace(events) {
|
|
4
|
+
const summary = summarizeEvents(events);
|
|
5
|
+
const iterations = filterByType(events, EventType.ITERATION);
|
|
6
|
+
const stops = filterByType(events, EventType.STOP);
|
|
7
|
+
const errors = filterByType(events, EventType.ERROR);
|
|
8
|
+
const stories = filterByType(events, EventType.STORY_COMPLETE);
|
|
9
|
+
const costs = filterByType(events, EventType.COST);
|
|
10
|
+
const totalCost = costs.reduce((s, e) => s + (e.totalCost || 0), 0);
|
|
11
|
+
const lastStop = stops[stops.length - 1];
|
|
12
|
+
return {
|
|
13
|
+
...summary,
|
|
14
|
+
iterations: iterations.length,
|
|
15
|
+
stops: stops.length,
|
|
16
|
+
errors: errors.length,
|
|
17
|
+
storiesCompleted: stories.length,
|
|
18
|
+
totalCost,
|
|
19
|
+
lastStopReason: lastStop?.reason || null,
|
|
20
|
+
avgIterationMs: iterations.length > 1 ? summary.durationMs / iterations.length : 0,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function compareTraces(trace1, trace2) {
|
|
24
|
+
const a1 = analyzeTrace(trace1);
|
|
25
|
+
const a2 = analyzeTrace(trace2);
|
|
26
|
+
return {
|
|
27
|
+
trace1: a1,
|
|
28
|
+
trace2: a2,
|
|
29
|
+
diff: {
|
|
30
|
+
iterations: a2.iterations - a1.iterations,
|
|
31
|
+
totalCost: a2.totalCost - a1.totalCost,
|
|
32
|
+
durationMs: a2.durationMs - a1.durationMs,
|
|
33
|
+
storiesCompleted: a2.storiesCompleted - a1.storiesCompleted,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function replayTrace(events, speed = 1) {
|
|
38
|
+
if (events.length === 0)
|
|
39
|
+
return [];
|
|
40
|
+
const firstTs = new Date(events[0].ts).getTime();
|
|
41
|
+
return events.map(e => ({
|
|
42
|
+
...e,
|
|
43
|
+
relativeMs: Math.round((new Date(e.ts).getTime() - firstTs) / speed),
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=trace-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-analyzer.js","sourceRoot":"","sources":["../../core/trace-analyzer.ts"],"names":[],"mappings":"AAAA,oCAAoC;AAGpC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AA4BvE,MAAM,UAAU,YAAY,CAAC,MAAmB;IAC9C,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IAEnD,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAE,CAAC,CAAC,SAAoB,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAChF,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEzC,OAAO;QACL,GAAG,OAAO;QACV,UAAU,EAAE,UAAU,CAAC,MAAM;QAC7B,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,gBAAgB,EAAE,OAAO,CAAC,MAAM;QAChC,SAAS;QACT,cAAc,EAAG,QAAQ,EAAE,MAAiB,IAAI,IAAI;QACpD,cAAc,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;KACnF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAmB,EAAE,MAAmB;IACpE,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAEhC,OAAO;QACL,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,EAAE;QACV,IAAI,EAAE;YACJ,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,UAAU;YACzC,SAAS,EAAE,EAAE,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS;YACtC,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,UAAU;YACzC,gBAAgB,EAAE,EAAE,CAAC,gBAAgB,GAAG,EAAE,CAAC,gBAAgB;SAC5D;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAmB,EAAE,QAAgB,CAAC;IAChE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAY,CAAC,CAAC,OAAO,EAAE,CAAC;IAC3D,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACtB,GAAG,CAAC;QACJ,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAY,CAAC,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,GAAG,KAAK,CAAC;KAC/E,CAAC,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
export interface LoopState {
|
|
2
|
+
active: boolean;
|
|
3
|
+
prompt: string;
|
|
4
|
+
completionPromise: string;
|
|
5
|
+
maxIterations: number;
|
|
6
|
+
currentIteration: number;
|
|
7
|
+
sessionId: string;
|
|
8
|
+
verifyScript: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
startedAt?: string;
|
|
11
|
+
qualityThreshold?: number;
|
|
12
|
+
maxRefineAttempts?: number;
|
|
13
|
+
qualityConfig?: QualityConfig | null;
|
|
14
|
+
}
|
|
15
|
+
export interface StopHookInput {
|
|
16
|
+
last_assistant_text: string;
|
|
17
|
+
stop_hook_active: boolean;
|
|
18
|
+
has_pending_stories: boolean;
|
|
19
|
+
session_id: string;
|
|
20
|
+
transcript_path?: string;
|
|
21
|
+
policy_result?: PolicyResult;
|
|
22
|
+
verify_result?: VerifyResult;
|
|
23
|
+
test_results?: TestResult[];
|
|
24
|
+
}
|
|
25
|
+
export interface StopHookResult {
|
|
26
|
+
decision: "allow" | "block";
|
|
27
|
+
nextState: LoopState;
|
|
28
|
+
events: LoopEvent[];
|
|
29
|
+
output: StopHookOutput | null;
|
|
30
|
+
message?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface StopHookOutput {
|
|
33
|
+
decision: "block";
|
|
34
|
+
reason: string;
|
|
35
|
+
systemMessage?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface LoopEvent {
|
|
38
|
+
event: string;
|
|
39
|
+
[key: string]: unknown;
|
|
40
|
+
}
|
|
41
|
+
export interface PolicyResult {
|
|
42
|
+
shouldStop: boolean;
|
|
43
|
+
violations: PolicyViolation[];
|
|
44
|
+
}
|
|
45
|
+
export interface PolicyViolation {
|
|
46
|
+
type: string;
|
|
47
|
+
current: number;
|
|
48
|
+
limit: number;
|
|
49
|
+
}
|
|
50
|
+
export interface VerifyResult {
|
|
51
|
+
passed: boolean;
|
|
52
|
+
output?: string;
|
|
53
|
+
}
|
|
54
|
+
export interface TestResult {
|
|
55
|
+
storyId: string;
|
|
56
|
+
passed: boolean;
|
|
57
|
+
}
|
|
58
|
+
export interface QualityScore {
|
|
59
|
+
story: string;
|
|
60
|
+
tests: number;
|
|
61
|
+
typecheck: number;
|
|
62
|
+
lint: number;
|
|
63
|
+
verify: number;
|
|
64
|
+
diff: number;
|
|
65
|
+
custom: number;
|
|
66
|
+
total: number;
|
|
67
|
+
grade: string;
|
|
68
|
+
}
|
|
69
|
+
export interface QualityConfig {
|
|
70
|
+
weights?: Partial<Record<"tests" | "typecheck" | "lint" | "verify" | "diff" | "custom", number>>;
|
|
71
|
+
}
|
|
72
|
+
export interface RefineResult {
|
|
73
|
+
keep: boolean;
|
|
74
|
+
reason: string;
|
|
75
|
+
}
|
|
76
|
+
export interface MergeResult {
|
|
77
|
+
branch: string;
|
|
78
|
+
status: string;
|
|
79
|
+
error?: string;
|
|
80
|
+
commits?: number;
|
|
81
|
+
}
|
|
82
|
+
export interface WorktreeInfo {
|
|
83
|
+
name: string;
|
|
84
|
+
path: string;
|
|
85
|
+
branch: string;
|
|
86
|
+
head?: string;
|
|
87
|
+
}
|
|
88
|
+
export interface TraceEvent {
|
|
89
|
+
ts: string;
|
|
90
|
+
event: string;
|
|
91
|
+
[key: string]: unknown;
|
|
92
|
+
}
|
|
93
|
+
export interface CostEstimate {
|
|
94
|
+
inputTokens: number;
|
|
95
|
+
outputTokens: number;
|
|
96
|
+
totalCost: number;
|
|
97
|
+
model: string;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../core/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../core/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface ValidationResult {
|
|
2
|
+
valid: boolean;
|
|
3
|
+
errors: string[];
|
|
4
|
+
}
|
|
5
|
+
export declare function validateState(obj: unknown): ValidationResult;
|
|
6
|
+
export declare function validateLoopConfig(obj: unknown): ValidationResult;
|
|
7
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../core/validate.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,CAsB5D;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,CAUjE"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// core/validate.ts — Zero-dep runtime schema validation
|
|
2
|
+
const STATE_REQUIRED = {
|
|
3
|
+
active: "boolean",
|
|
4
|
+
prompt: "string",
|
|
5
|
+
maxIterations: "number",
|
|
6
|
+
currentIteration: "number",
|
|
7
|
+
};
|
|
8
|
+
const STATE_OPTIONAL = {
|
|
9
|
+
completionPromise: "string",
|
|
10
|
+
sessionId: "string",
|
|
11
|
+
name: "string",
|
|
12
|
+
verifyScript: "string",
|
|
13
|
+
startedAt: "string",
|
|
14
|
+
cost: "object",
|
|
15
|
+
qualityThreshold: "number",
|
|
16
|
+
maxRefineAttempts: "number",
|
|
17
|
+
qualityConfig: "object",
|
|
18
|
+
};
|
|
19
|
+
export function validateState(obj) {
|
|
20
|
+
const errors = [];
|
|
21
|
+
if (typeof obj !== "object" || obj === null) {
|
|
22
|
+
return { valid: false, errors: ["State must be an object"] };
|
|
23
|
+
}
|
|
24
|
+
const record = obj;
|
|
25
|
+
for (const [key, type] of Object.entries(STATE_REQUIRED)) {
|
|
26
|
+
if (!(key in record))
|
|
27
|
+
errors.push(`Missing required field: ${key}`);
|
|
28
|
+
else if (typeof record[key] !== type)
|
|
29
|
+
errors.push(`${key} must be ${type}, got ${typeof record[key]}`);
|
|
30
|
+
}
|
|
31
|
+
for (const [key, type] of Object.entries(STATE_OPTIONAL)) {
|
|
32
|
+
if (key in record && record[key] !== undefined && record[key] !== null && typeof record[key] !== type) {
|
|
33
|
+
errors.push(`${key} must be ${type}, got ${typeof record[key]}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (typeof record.maxIterations === "number" && record.maxIterations < 0) {
|
|
37
|
+
errors.push("maxIterations must be >= 0");
|
|
38
|
+
}
|
|
39
|
+
if (typeof record.currentIteration === "number" && record.currentIteration < 0) {
|
|
40
|
+
errors.push("currentIteration must be >= 0");
|
|
41
|
+
}
|
|
42
|
+
return { valid: errors.length === 0, errors };
|
|
43
|
+
}
|
|
44
|
+
export function validateLoopConfig(obj) {
|
|
45
|
+
const errors = [];
|
|
46
|
+
if (typeof obj !== "object" || obj === null) {
|
|
47
|
+
return { valid: false, errors: ["Config must be an object"] };
|
|
48
|
+
}
|
|
49
|
+
const record = obj;
|
|
50
|
+
if (record.protocol_version && record.protocol_version !== "1.0") {
|
|
51
|
+
errors.push(`Unsupported protocol version: ${record.protocol_version}`);
|
|
52
|
+
}
|
|
53
|
+
return { valid: errors.length === 0, errors };
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../core/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { WorktreeInfo } from "./types.js";
|
|
2
|
+
export declare function getRepoRoot(): Promise<string | null>;
|
|
3
|
+
export declare function createWorktree(name: string, baseBranch?: string): Promise<{
|
|
4
|
+
name: string;
|
|
5
|
+
path: string;
|
|
6
|
+
branch: string;
|
|
7
|
+
}>;
|
|
8
|
+
export declare function removeWorktree(name: string): Promise<{
|
|
9
|
+
name: string;
|
|
10
|
+
removed: boolean;
|
|
11
|
+
}>;
|
|
12
|
+
export declare function listWorktrees(): Promise<WorktreeInfo[]>;
|
|
13
|
+
//# sourceMappingURL=worktree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../core/worktree.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAQ/C,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAO1D;AASD,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,GAAE,MAAe,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAiBvI;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAmB9F;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAmC7D"}
|