@graypark/loophaus 3.4.0 → 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
package/lib/paths.mjs
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { homedir } from "node:os";
|
|
2
|
-
import { join, dirname } from "node:path";
|
|
3
|
-
import { readFileSync } from "node:fs";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
-
|
|
6
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
-
const __dirname = dirname(__filename);
|
|
8
|
-
|
|
9
|
-
let _cachedVersion = null;
|
|
10
|
-
export function getPackageVersion() {
|
|
11
|
-
if (_cachedVersion) return _cachedVersion;
|
|
12
|
-
try {
|
|
13
|
-
const pkg = JSON.parse(
|
|
14
|
-
readFileSync(join(__dirname, "..", "package.json"), "utf-8"),
|
|
15
|
-
);
|
|
16
|
-
_cachedVersion = pkg.version;
|
|
17
|
-
} catch {
|
|
18
|
-
_cachedVersion = "0.0.0";
|
|
19
|
-
}
|
|
20
|
-
return _cachedVersion;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function isWindows() {
|
|
24
|
-
return process.platform === "win32";
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// --- Codex CLI paths (legacy ~/.codex + new ~/.agents) ---
|
|
28
|
-
|
|
29
|
-
export function getCodexHome() {
|
|
30
|
-
if (process.env.CODEX_HOME) {
|
|
31
|
-
return process.env.CODEX_HOME;
|
|
32
|
-
}
|
|
33
|
-
return join(homedir(), ".codex");
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function getAgentsHome() {
|
|
37
|
-
return join(homedir(), ".agents");
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export function getAgentsSkillsDir() {
|
|
41
|
-
return join(getAgentsHome(), "skills");
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function getHooksJsonPath() {
|
|
45
|
-
return join(getCodexHome(), "hooks.json");
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function getPluginInstallDir() {
|
|
49
|
-
return join(getCodexHome(), "plugins", "loophaus");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function getSkillsDir() {
|
|
53
|
-
return join(getCodexHome(), "skills");
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export function getLocalCodexDir() {
|
|
57
|
-
return join(process.cwd(), ".codex");
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export function getLocalPluginDir() {
|
|
61
|
-
return join(getLocalCodexDir(), "plugins", "loophaus");
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export function getLocalHooksJsonPath() {
|
|
65
|
-
return join(getLocalCodexDir(), "hooks.json");
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export function getLocalSkillsDir() {
|
|
69
|
-
return join(getLocalCodexDir(), "skills");
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// --- Claude Code paths ---
|
|
73
|
-
|
|
74
|
-
export function getClaudeHome() {
|
|
75
|
-
return join(homedir(), ".claude");
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function getClaudePluginsDir() {
|
|
79
|
-
return join(getClaudeHome(), "plugins");
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export function getClaudePluginCacheDir(version) {
|
|
83
|
-
const v = version || getPackageVersion();
|
|
84
|
-
return join(
|
|
85
|
-
getClaudePluginsDir(),
|
|
86
|
-
"cache",
|
|
87
|
-
"loophaus-marketplace",
|
|
88
|
-
"loophaus",
|
|
89
|
-
v,
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export function getClaudeSettingsPath() {
|
|
94
|
-
return join(getClaudeHome(), "settings.json");
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function getClaudeInstalledPluginsPath() {
|
|
98
|
-
return join(getClaudePluginsDir(), "installed_plugins.json");
|
|
99
|
-
}
|
package/lib/stop-hook-core.mjs
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { evaluateStopHook, extractPromise } from "../core/engine.mjs";
|
|
2
|
-
import { getLastAssistantText, hasPendingStories } from "../core/io-helpers.mjs";
|
|
3
|
-
|
|
4
|
-
export { extractPromise, getLastAssistantText, hasPendingStories };
|
|
5
|
-
|
|
6
|
-
export async function processStopHook(hookInput, readStateFn, writeStateFn) {
|
|
7
|
-
const state = await readStateFn();
|
|
8
|
-
|
|
9
|
-
if (!state.active) {
|
|
10
|
-
return { exitCode: 0, stdout: "", stderr: "" };
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
if (state.sessionId && hookInput.session_id && state.sessionId !== hookInput.session_id) {
|
|
14
|
-
return { exitCode: 0, stdout: "", stderr: "" };
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const lastText = hookInput.last_assistant_message ||
|
|
18
|
-
await getLastAssistantText(hookInput.transcript_path || null);
|
|
19
|
-
const pending = await hasPendingStories(hookInput.cwd || process.cwd());
|
|
20
|
-
|
|
21
|
-
const input = {
|
|
22
|
-
...hookInput,
|
|
23
|
-
last_assistant_text: lastText,
|
|
24
|
-
has_pending_stories: pending,
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const result = evaluateStopHook(input, state);
|
|
28
|
-
|
|
29
|
-
await writeStateFn(result.nextState);
|
|
30
|
-
|
|
31
|
-
const stderrParts = [];
|
|
32
|
-
if (result.message) stderrParts.push(result.message);
|
|
33
|
-
for (const ev of result.events || []) {
|
|
34
|
-
if (ev.event === "continue" && ev.reason === "pending_stories") {
|
|
35
|
-
stderrParts.push("Loop: stop_hook_active=true, pending stories found. Continuing.");
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
const stderr = stderrParts.length ? stderrParts.join("\n") + "\n" : "";
|
|
39
|
-
const stdout = result.output ? JSON.stringify(result.output) : "";
|
|
40
|
-
|
|
41
|
-
return { exitCode: 0, stdout, stderr };
|
|
42
|
-
}
|
package/store/state-store.mjs
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { readFile, writeFile, mkdir, rename } from "node:fs/promises";
|
|
2
|
-
import { join, dirname } from "node:path";
|
|
3
|
-
import { validateState } from "../core/validate.mjs";
|
|
4
|
-
|
|
5
|
-
const DEFAULT_STATE = {
|
|
6
|
-
active: false,
|
|
7
|
-
prompt: "",
|
|
8
|
-
completionPromise: "TADA",
|
|
9
|
-
maxIterations: 20,
|
|
10
|
-
currentIteration: 0,
|
|
11
|
-
sessionId: "",
|
|
12
|
-
qualityThreshold: 80,
|
|
13
|
-
maxRefineAttempts: 3,
|
|
14
|
-
qualityConfig: null,
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export function getStatePath(cwd, name) {
|
|
18
|
-
if (process.env.LOOPHAUS_STATE_FILE) return process.env.LOOPHAUS_STATE_FILE;
|
|
19
|
-
if (process.env.RALPH_STATE_FILE) return process.env.RALPH_STATE_FILE;
|
|
20
|
-
const base = cwd || process.cwd();
|
|
21
|
-
if (name) return join(base, ".loophaus", "loops", name, "state.json");
|
|
22
|
-
return join(base, ".loophaus", "state.json");
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const LEGACY_PATHS = [
|
|
26
|
-
(cwd) => join(cwd, ".codex", "ralph-loop.state.json"),
|
|
27
|
-
(cwd) => join(cwd, ".claude", "ralph-loop.local.md"),
|
|
28
|
-
];
|
|
29
|
-
|
|
30
|
-
export async function read(cwd, name) {
|
|
31
|
-
const primary = getStatePath(cwd, name);
|
|
32
|
-
|
|
33
|
-
try {
|
|
34
|
-
const raw = await readFile(primary, "utf-8");
|
|
35
|
-
const state = { ...DEFAULT_STATE, ...JSON.parse(raw) };
|
|
36
|
-
const result = validateState(state);
|
|
37
|
-
if (!result.valid) {
|
|
38
|
-
process.stderr.write(`loophaus: state validation warning: ${result.errors.join(", ")}\n`);
|
|
39
|
-
}
|
|
40
|
-
return state;
|
|
41
|
-
} catch {
|
|
42
|
-
// Primary not found, try legacy paths
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const dir = cwd || process.cwd();
|
|
46
|
-
for (const pathFn of LEGACY_PATHS) {
|
|
47
|
-
const legacyPath = pathFn(dir);
|
|
48
|
-
try {
|
|
49
|
-
const raw = await readFile(legacyPath, "utf-8");
|
|
50
|
-
if (legacyPath.endsWith(".md")) {
|
|
51
|
-
return migrateMdFormat(raw);
|
|
52
|
-
}
|
|
53
|
-
return { ...DEFAULT_STATE, ...JSON.parse(raw) };
|
|
54
|
-
} catch {
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return { ...DEFAULT_STATE };
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export async function write(state, cwd, name) {
|
|
63
|
-
const result = validateState(state);
|
|
64
|
-
if (!result.valid) {
|
|
65
|
-
process.stderr.write(`loophaus: writing invalid state: ${result.errors.join(", ")}\n`);
|
|
66
|
-
}
|
|
67
|
-
const statePath = getStatePath(cwd, name);
|
|
68
|
-
await mkdir(dirname(statePath), { recursive: true });
|
|
69
|
-
const tmp = statePath + ".tmp";
|
|
70
|
-
await writeFile(tmp, JSON.stringify(state, null, 2), "utf-8");
|
|
71
|
-
await rename(tmp, statePath);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export async function reset(cwd) {
|
|
75
|
-
await write({ ...DEFAULT_STATE }, cwd);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function migrateMdFormat(raw) {
|
|
79
|
-
const state = { ...DEFAULT_STATE };
|
|
80
|
-
const lines = raw.split("\n");
|
|
81
|
-
for (const line of lines) {
|
|
82
|
-
const match = line.match(/^(\w+):\s*(.+)$/);
|
|
83
|
-
if (!match) continue;
|
|
84
|
-
const [, key, value] = match;
|
|
85
|
-
if (key === "active") state.active = value.trim() === "true";
|
|
86
|
-
else if (key === "iteration") state.currentIteration = parseInt(value.trim(), 10) || 0;
|
|
87
|
-
else if (key === "max_iterations") state.maxIterations = parseInt(value.trim(), 10) || 20;
|
|
88
|
-
else if (key === "completion_promise") state.completionPromise = value.trim();
|
|
89
|
-
else if (key === "prompt") state.prompt = value.trim();
|
|
90
|
-
else if (key === "session_id") state.sessionId = value.trim();
|
|
91
|
-
}
|
|
92
|
-
return state;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Backward-compatible exports (matching lib/state.mjs interface)
|
|
96
|
-
export async function readState(cwd) { return read(cwd); }
|
|
97
|
-
export async function writeState(state, cwd) { return write(state, cwd); }
|
|
98
|
-
export async function resetState(cwd) { return reset(cwd); }
|
|
99
|
-
export async function incrementIteration(cwd) {
|
|
100
|
-
const state = await read(cwd);
|
|
101
|
-
state.currentIteration += 1;
|
|
102
|
-
await write(state, cwd);
|
|
103
|
-
return state;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export { DEFAULT_STATE };
|