chiefwiggum 1.3.28 → 1.3.29
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/cli.cjs +111 -15
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -489,8 +489,8 @@ async function runClaude(options) {
|
|
|
489
489
|
});
|
|
490
490
|
});
|
|
491
491
|
}
|
|
492
|
-
|
|
493
|
-
|
|
492
|
+
function getTodoTaskPrompt() {
|
|
493
|
+
return `You are an autonomous coding agent. Complete ONE task from TODO.md.
|
|
494
494
|
|
|
495
495
|
## Before Starting
|
|
496
496
|
Read these files to understand the project:
|
|
@@ -516,6 +516,38 @@ Read these files to understand the project:
|
|
|
516
516
|
## When Done
|
|
517
517
|
Output: RALPH_COMPLETE
|
|
518
518
|
If no tasks remain: RALPH_ALL_DONE`;
|
|
519
|
+
}
|
|
520
|
+
function getGitHubTaskPrompt() {
|
|
521
|
+
return `You are an autonomous coding agent. Complete ONE GitHub Issue.
|
|
522
|
+
|
|
523
|
+
## Before Starting
|
|
524
|
+
Read these files to understand the project:
|
|
525
|
+
- CLAUDE.md \u2014 Project context and conventions
|
|
526
|
+
- specs/prd.md \u2014 What we are building
|
|
527
|
+
- specs/technical.md \u2014 How we are building it
|
|
528
|
+
|
|
529
|
+
Then list open issues: gh issue list --state open
|
|
530
|
+
|
|
531
|
+
## Workflow
|
|
532
|
+
1. Pick the FIRST open issue (lowest number)
|
|
533
|
+
2. Read the issue: gh issue view <number>
|
|
534
|
+
3. Implement the code
|
|
535
|
+
4. Close the issue: gh issue close <number> --comment "Completed"
|
|
536
|
+
5. Commit: git commit -m "type(scope): description (closes #<number>)"
|
|
537
|
+
|
|
538
|
+
## Rules
|
|
539
|
+
- ONE issue per iteration
|
|
540
|
+
- Follow existing code patterns
|
|
541
|
+
- Use conventional commits (feat, fix, docs, refactor, test, chore)
|
|
542
|
+
- Include "closes #N" in commit message to link the commit
|
|
543
|
+
- If blocked after 3 attempts, output RALPH_BLOCKED: <reason>
|
|
544
|
+
|
|
545
|
+
## When Done
|
|
546
|
+
Output: RALPH_COMPLETE
|
|
547
|
+
If no issues remain: RALPH_ALL_DONE`;
|
|
548
|
+
}
|
|
549
|
+
async function runTaskIteration(iteration, useGitHub = false) {
|
|
550
|
+
const taskPrompt = useGitHub ? getGitHubTaskPrompt() : getTodoTaskPrompt();
|
|
519
551
|
let lastResult = {
|
|
520
552
|
success: false,
|
|
521
553
|
output: "",
|
|
@@ -569,6 +601,28 @@ function hasUncheckedTasks() {
|
|
|
569
601
|
const content = (0, import_node_fs2.readFileSync)(config.todoFile, "utf-8");
|
|
570
602
|
return /^\s*-\s*\[\s\]/m.test(content);
|
|
571
603
|
}
|
|
604
|
+
function countOpenIssues() {
|
|
605
|
+
try {
|
|
606
|
+
const output = (0, import_node_child_process5.execSync)(
|
|
607
|
+
"gh issue list --state open --json number --jq 'length'",
|
|
608
|
+
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e4 }
|
|
609
|
+
);
|
|
610
|
+
return parseInt(output.trim(), 10) || 0;
|
|
611
|
+
} catch {
|
|
612
|
+
return 0;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
function hasOpenIssues() {
|
|
616
|
+
try {
|
|
617
|
+
const output = (0, import_node_child_process5.execSync)(
|
|
618
|
+
"gh issue list --state open --limit 1 --json number --jq 'length'",
|
|
619
|
+
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e4 }
|
|
620
|
+
);
|
|
621
|
+
return parseInt(output.trim(), 10) > 0;
|
|
622
|
+
} catch {
|
|
623
|
+
return false;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
572
626
|
function getCurrentCommit() {
|
|
573
627
|
try {
|
|
574
628
|
return (0, import_node_child_process5.execSync)("git rev-parse HEAD", { encoding: "utf-8" }).trim();
|
|
@@ -584,19 +638,36 @@ function pushToOrigin() {
|
|
|
584
638
|
}
|
|
585
639
|
}
|
|
586
640
|
async function cmdLoop() {
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
if (
|
|
593
|
-
|
|
594
|
-
|
|
641
|
+
const tracker = getProjectTracker();
|
|
642
|
+
const isGitHub = tracker === "github";
|
|
643
|
+
let maxIterations;
|
|
644
|
+
let hasRemainingTasks;
|
|
645
|
+
let trackerLabel;
|
|
646
|
+
if (isGitHub) {
|
|
647
|
+
maxIterations = countOpenIssues();
|
|
648
|
+
hasRemainingTasks = hasOpenIssues;
|
|
649
|
+
trackerLabel = "Issues";
|
|
650
|
+
if (maxIterations === 0) {
|
|
651
|
+
console.log(import_picocolors6.default.green("No open GitHub Issues. All done!"));
|
|
652
|
+
process.exit(0);
|
|
653
|
+
}
|
|
654
|
+
} else {
|
|
655
|
+
if (!(0, import_node_fs2.existsSync)(config.todoFile)) {
|
|
656
|
+
console.log(import_picocolors6.default.red(`Missing ${config.todoFile}`));
|
|
657
|
+
process.exit(1);
|
|
658
|
+
}
|
|
659
|
+
maxIterations = countUncheckedTasks();
|
|
660
|
+
hasRemainingTasks = hasUncheckedTasks;
|
|
661
|
+
trackerLabel = "Tasks";
|
|
662
|
+
if (maxIterations === 0) {
|
|
663
|
+
console.log(import_picocolors6.default.green(`No unchecked tasks in ${config.todoFile}. All done!`));
|
|
664
|
+
process.exit(0);
|
|
665
|
+
}
|
|
595
666
|
}
|
|
596
667
|
console.log();
|
|
597
668
|
console.log(import_picocolors6.default.green("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"));
|
|
598
669
|
console.log(import_picocolors6.default.green(" Starting Build Loop"));
|
|
599
|
-
console.log(import_picocolors6.default.green(`
|
|
670
|
+
console.log(import_picocolors6.default.green(` ${trackerLabel} remaining: ${maxIterations}`));
|
|
600
671
|
console.log(import_picocolors6.default.green(` Timeout: ${config.iterationTimeoutMinutes}m per task`));
|
|
601
672
|
console.log(import_picocolors6.default.green("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"));
|
|
602
673
|
let consecutiveFailures = 0;
|
|
@@ -607,7 +678,7 @@ async function cmdLoop() {
|
|
|
607
678
|
console.log(import_picocolors6.default.yellow(`\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Task ${i} of ${maxIterations} \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550`));
|
|
608
679
|
cleanupStaleProcesses();
|
|
609
680
|
const startTime = Date.now();
|
|
610
|
-
const result = await runTaskIteration(i);
|
|
681
|
+
const result = await runTaskIteration(i, isGitHub);
|
|
611
682
|
const duration = Math.round((Date.now() - startTime) / 1e3);
|
|
612
683
|
console.log();
|
|
613
684
|
console.log(`Completed in ${duration}s (exit: ${result.success ? 0 : 1})`);
|
|
@@ -638,10 +709,10 @@ async function cmdLoop() {
|
|
|
638
709
|
console.log(import_picocolors6.default.red(`Stopping: No commits for ${config.maxNoCommitCycles} cycles`));
|
|
639
710
|
process.exit(1);
|
|
640
711
|
}
|
|
641
|
-
if (!
|
|
712
|
+
if (!hasRemainingTasks()) {
|
|
642
713
|
console.log();
|
|
643
714
|
console.log(import_picocolors6.default.green("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"));
|
|
644
|
-
console.log(import_picocolors6.default.green(
|
|
715
|
+
console.log(import_picocolors6.default.green(` All ${trackerLabel.toLowerCase()} completed!`));
|
|
645
716
|
console.log(import_picocolors6.default.green("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"));
|
|
646
717
|
pushToOrigin();
|
|
647
718
|
process.exit(0);
|
|
@@ -689,6 +760,22 @@ function getProjectTracker() {
|
|
|
689
760
|
function getGithubProject() {
|
|
690
761
|
return getConfig().githubProject;
|
|
691
762
|
}
|
|
763
|
+
function countTodoTasks() {
|
|
764
|
+
if (!(0, import_node_fs3.existsSync)(config.todoFile)) return 0;
|
|
765
|
+
const content = (0, import_node_fs3.readFileSync)(config.todoFile, "utf-8");
|
|
766
|
+
return (content.match(/^\s*-\s*\[\s\]/gm) || []).length;
|
|
767
|
+
}
|
|
768
|
+
function countOpenGitHubIssues() {
|
|
769
|
+
try {
|
|
770
|
+
const output = (0, import_node_child_process6.execSync)(
|
|
771
|
+
"gh issue list --state open --json number --jq 'length'",
|
|
772
|
+
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e4 }
|
|
773
|
+
);
|
|
774
|
+
return parseInt(output.trim(), 10) || 0;
|
|
775
|
+
} catch {
|
|
776
|
+
return 0;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
692
779
|
var BUNDLED_TEMPLATES_DIR = (0, import_node_path2.join)(__dirname, "..", "templates");
|
|
693
780
|
var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
694
781
|
"node_modules",
|
|
@@ -777,8 +864,17 @@ async function cmdNew(planFile) {
|
|
|
777
864
|
break;
|
|
778
865
|
}
|
|
779
866
|
console.log();
|
|
867
|
+
const tracker = getProjectTracker();
|
|
868
|
+
let taskInfo;
|
|
869
|
+
if (tracker === "github") {
|
|
870
|
+
const count = countOpenGitHubIssues();
|
|
871
|
+
const projectName = getGithubProject();
|
|
872
|
+
taskInfo = projectName ? `${count} issues, ${projectName}` : `${count} issues, GitHub`;
|
|
873
|
+
} else {
|
|
874
|
+
taskInfo = `${countTodoTasks()} tasks, TODO.md`;
|
|
875
|
+
}
|
|
780
876
|
const startChoice = await select2({
|
|
781
|
-
message:
|
|
877
|
+
message: `Ready to start (${taskInfo}). What would you like to do?`,
|
|
782
878
|
options: [
|
|
783
879
|
{ value: "start", label: "Start the build loop now" },
|
|
784
880
|
{ value: "review", label: "Review files first, then start manually with 'chiefwiggum loop'" },
|