codeharness 0.18.0 → 0.19.1
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/dist/index.js +17 -33
- package/package.json +1 -1
- package/ralph/ralph.sh +10 -0
package/dist/index.js
CHANGED
|
@@ -940,14 +940,9 @@ import { join as join5, dirname as dirname2 } from "path";
|
|
|
940
940
|
import { fileURLToPath } from "url";
|
|
941
941
|
var __dirname = dirname2(fileURLToPath(import.meta.url));
|
|
942
942
|
function readPatchFile(name) {
|
|
943
|
-
const
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
return readFileSync5(projectPath, "utf-8").trim();
|
|
947
|
-
}
|
|
948
|
-
const pkgPath = join5(__dirname, "..", "..", "patches", `${name}.md`);
|
|
949
|
-
if (existsSync5(pkgPath)) {
|
|
950
|
-
return readFileSync5(pkgPath, "utf-8").trim();
|
|
943
|
+
const patchPath = join5(__dirname, "..", "..", "patches", `${name}.md`);
|
|
944
|
+
if (existsSync5(patchPath)) {
|
|
945
|
+
return readFileSync5(patchPath, "utf-8").trim();
|
|
951
946
|
}
|
|
952
947
|
return null;
|
|
953
948
|
}
|
|
@@ -1081,28 +1076,17 @@ function installBmad(dir) {
|
|
|
1081
1076
|
patches_applied: []
|
|
1082
1077
|
};
|
|
1083
1078
|
}
|
|
1084
|
-
const cmdStr = "npx bmad-method install";
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
lastError = "";
|
|
1096
|
-
break;
|
|
1097
|
-
} catch (err) {
|
|
1098
|
-
lastError = err instanceof Error ? err.message : String(err);
|
|
1099
|
-
if (attempt < maxAttempts) {
|
|
1100
|
-
execFileSync4("sleep", ["2"]);
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
}
|
|
1104
|
-
if (lastError) {
|
|
1105
|
-
throw new BmadError(cmdStr, lastError);
|
|
1079
|
+
const cmdStr = "npx bmad-method install --yes --tools claude-code";
|
|
1080
|
+
try {
|
|
1081
|
+
execFileSync4("npx", ["bmad-method", "install", "--yes", "--tools", "claude-code"], {
|
|
1082
|
+
stdio: "pipe",
|
|
1083
|
+
timeout: 12e4,
|
|
1084
|
+
// 2 min — npx may need to download the package first time
|
|
1085
|
+
cwd: root
|
|
1086
|
+
});
|
|
1087
|
+
} catch (err) {
|
|
1088
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1089
|
+
throw new BmadError(cmdStr, message);
|
|
1106
1090
|
}
|
|
1107
1091
|
if (!isBmadInstalled(root)) {
|
|
1108
1092
|
throw new BmadError(cmdStr, "_bmad/ directory was not created after successful npx bmad-method install");
|
|
@@ -1403,7 +1387,7 @@ function getInstallCommand(stack) {
|
|
|
1403
1387
|
}
|
|
1404
1388
|
|
|
1405
1389
|
// src/commands/init.ts
|
|
1406
|
-
var HARNESS_VERSION = true ? "0.
|
|
1390
|
+
var HARNESS_VERSION = true ? "0.19.1" : "0.0.0-dev";
|
|
1407
1391
|
function getProjectName(projectDir) {
|
|
1408
1392
|
try {
|
|
1409
1393
|
const pkgPath = join7(projectDir, "package.json");
|
|
@@ -2602,7 +2586,7 @@ function buildSpawnArgs(opts) {
|
|
|
2602
2586
|
return args;
|
|
2603
2587
|
}
|
|
2604
2588
|
function registerRunCommand(program) {
|
|
2605
|
-
program.command("run").description("Execute the autonomous coding loop").option("--max-iterations <n>", "Maximum loop iterations", "50").option("--timeout <seconds>", "Total loop timeout in seconds", "14400").option("--iteration-timeout <minutes>", "Per-iteration timeout in minutes", "30").option("--live", "Show live output streaming", false).option("--calls <n>", "Max API calls per hour", "100").option("--max-story-retries <n>", "Max retries per story before flagging", "
|
|
2589
|
+
program.command("run").description("Execute the autonomous coding loop").option("--max-iterations <n>", "Maximum loop iterations", "50").option("--timeout <seconds>", "Total loop timeout in seconds", "14400").option("--iteration-timeout <minutes>", "Per-iteration timeout in minutes", "30").option("--live", "Show live output streaming", false).option("--calls <n>", "Max API calls per hour", "100").option("--max-story-retries <n>", "Max retries per story before flagging", "10").option("--reset", "Clear retry counters, flagged stories, and circuit breaker before starting", false).action(async (options, cmd) => {
|
|
2606
2590
|
const globalOpts = cmd.optsWithGlobals();
|
|
2607
2591
|
const isJson = !!globalOpts.json;
|
|
2608
2592
|
const outputOpts = { json: isJson };
|
|
@@ -7775,7 +7759,7 @@ function handleStatus(dir, isJson, filterStory) {
|
|
|
7775
7759
|
}
|
|
7776
7760
|
|
|
7777
7761
|
// src/index.ts
|
|
7778
|
-
var VERSION = true ? "0.
|
|
7762
|
+
var VERSION = true ? "0.19.1" : "0.0.0-dev";
|
|
7779
7763
|
function createProgram() {
|
|
7780
7764
|
const program = new Command();
|
|
7781
7765
|
program.name("codeharness").description("Makes autonomous coding agents produce software that actually works").version(VERSION).option("--json", "Output in machine-readable JSON format");
|
package/package.json
CHANGED
package/ralph/ralph.sh
CHANGED
|
@@ -692,6 +692,10 @@ execute_iteration() {
|
|
|
692
692
|
if grep -qi "5.*hour.*limit\|limit.*reached.*try.*back\|usage.*limit.*reached" "$output_file" 2>/dev/null; then
|
|
693
693
|
log_status "ERROR" "Claude API usage limit reached"
|
|
694
694
|
return 2
|
|
695
|
+
# Check for transient API errors (500, 529, overloaded) — don't count against story
|
|
696
|
+
elif grep -qi "Internal server error\|api_error\|overloaded\|529\|503" "$output_file" 2>/dev/null; then
|
|
697
|
+
log_status "WARN" "Transient API error (not story's fault) — will retry"
|
|
698
|
+
return 4
|
|
695
699
|
else
|
|
696
700
|
log_status "ERROR" "$(driver_display_name) execution failed (exit code: $exit_code)"
|
|
697
701
|
return 1
|
|
@@ -997,6 +1001,12 @@ main() {
|
|
|
997
1001
|
update_status "$loop_count" "$(cat "$CALL_COUNT_FILE" 2>/dev/null || echo "0")" "circuit_breaker" "halted"
|
|
998
1002
|
break
|
|
999
1003
|
;;
|
|
1004
|
+
4)
|
|
1005
|
+
# Transient API error — retry after brief pause, don't count against story
|
|
1006
|
+
consecutive_failures=0 # reset — this isn't the story's fault
|
|
1007
|
+
log_status "INFO" "Transient API error — retrying in 30s (not counting against story)"
|
|
1008
|
+
sleep 30
|
|
1009
|
+
;;
|
|
1000
1010
|
*)
|
|
1001
1011
|
# Failure (timeout or crash) — increment retry for the story that was being worked on
|
|
1002
1012
|
consecutive_failures=$((consecutive_failures + 1))
|