chiefwiggum 1.3.51 → 1.3.52
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 +113 -39
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -300,6 +300,54 @@ var init_config = __esm({
|
|
|
300
300
|
});
|
|
301
301
|
|
|
302
302
|
// src/lib/claude.ts
|
|
303
|
+
function getProjectBoardContext() {
|
|
304
|
+
try {
|
|
305
|
+
const owner = (0, import_node_child_process4.execSync)("gh repo view --json owner -q .owner.login", {
|
|
306
|
+
encoding: "utf-8",
|
|
307
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
308
|
+
timeout: 3e4
|
|
309
|
+
}).trim();
|
|
310
|
+
const projectNumber = (0, import_node_child_process4.execSync)(
|
|
311
|
+
"gh repo view --json projectsV2 -q '.projectsV2.Nodes[0].number'",
|
|
312
|
+
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e4 }
|
|
313
|
+
).trim();
|
|
314
|
+
if (!projectNumber || projectNumber === "null") return null;
|
|
315
|
+
const projectId = (0, import_node_child_process4.execSync)(
|
|
316
|
+
"gh repo view --json projectsV2 -q '.projectsV2.Nodes[0].id'",
|
|
317
|
+
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e4 }
|
|
318
|
+
).trim();
|
|
319
|
+
const fieldsOutput = (0, import_node_child_process4.execSync)(
|
|
320
|
+
`gh project field-list ${projectNumber} --owner ${owner} --format json`,
|
|
321
|
+
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e4 }
|
|
322
|
+
);
|
|
323
|
+
const fields = JSON.parse(fieldsOutput);
|
|
324
|
+
const statusField = fields.fields?.find((f) => f.name === "Status");
|
|
325
|
+
if (!statusField) return null;
|
|
326
|
+
const findOption = (names) => {
|
|
327
|
+
for (const name of names) {
|
|
328
|
+
const option = statusField.options?.find(
|
|
329
|
+
(o) => o.name.toLowerCase() === name.toLowerCase()
|
|
330
|
+
);
|
|
331
|
+
if (option) return option;
|
|
332
|
+
}
|
|
333
|
+
return null;
|
|
334
|
+
};
|
|
335
|
+
const todoOption = findOption(["Todo", "To Do", "To do", "Backlog"]);
|
|
336
|
+
const inProgressOption = findOption(["In Progress", "In progress", "Doing", "Active"]);
|
|
337
|
+
const doneOption = findOption(["Done", "Completed", "Closed", "Finished"]);
|
|
338
|
+
return {
|
|
339
|
+
owner,
|
|
340
|
+
projectNumber,
|
|
341
|
+
projectId,
|
|
342
|
+
statusFieldId: statusField.id,
|
|
343
|
+
todoOptionId: todoOption?.id || "",
|
|
344
|
+
inProgressOptionId: inProgressOption?.id || "",
|
|
345
|
+
doneOptionId: doneOption?.id || ""
|
|
346
|
+
};
|
|
347
|
+
} catch {
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
303
351
|
async function runClaude(options) {
|
|
304
352
|
const { prompt, streaming = false, onOutput } = options;
|
|
305
353
|
const timeoutMs = options.timeoutMs || config.iterationTimeoutMinutes * 60 * 1e3;
|
|
@@ -422,50 +470,62 @@ IMPORTANT: Only use the root-level files above for project context. Do not read
|
|
|
422
470
|
Output: RALPH_COMPLETE
|
|
423
471
|
If no tasks remain: RALPH_ALL_DONE`;
|
|
424
472
|
}
|
|
425
|
-
function getGitHubTaskPrompt() {
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
-
|
|
431
|
-
-
|
|
432
|
-
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
5. Close the issue: gh issue close <number> --comment "Completed"
|
|
444
|
-
6. Update project board status to "Done"
|
|
445
|
-
7. Commit: git commit -m "type(scope): description (closes #<number>)"
|
|
473
|
+
function getGitHubTaskPrompt(boardContext) {
|
|
474
|
+
const boardInstructions = boardContext && boardContext.inProgressOptionId && boardContext.doneOptionId ? `
|
|
475
|
+
## Project Board Status Updates (REQUIRED)
|
|
476
|
+
|
|
477
|
+
Pre-computed values for this project:
|
|
478
|
+
- Owner: ${boardContext.owner}
|
|
479
|
+
- Project Number: ${boardContext.projectNumber}
|
|
480
|
+
- Project ID: ${boardContext.projectId}
|
|
481
|
+
- Status Field ID: ${boardContext.statusFieldId}
|
|
482
|
+
- In Progress Option ID: ${boardContext.inProgressOptionId}
|
|
483
|
+
- Done Option ID: ${boardContext.doneOptionId}
|
|
484
|
+
|
|
485
|
+
### Step 1: Get Item ID for the Issue
|
|
486
|
+
Run this to get the ITEM_ID (replace ISSUE_NUMBER with the actual issue number):
|
|
487
|
+
\`\`\`bash
|
|
488
|
+
ITEM_ID=$(gh project item-list ${boardContext.projectNumber} --owner ${boardContext.owner} --format json | jq -r '.items[] | select(.content.number == ISSUE_NUMBER) | .id')
|
|
489
|
+
echo "Item ID: $ITEM_ID"
|
|
490
|
+
\`\`\`
|
|
446
491
|
|
|
447
|
-
|
|
448
|
-
|
|
492
|
+
### Step 2: Mark In Progress (do this FIRST, before any code changes)
|
|
493
|
+
\`\`\`bash
|
|
494
|
+
gh project item-edit --project-id ${boardContext.projectId} --id $ITEM_ID --field-id ${boardContext.statusFieldId} --single-select-option-id ${boardContext.inProgressOptionId}
|
|
495
|
+
\`\`\`
|
|
449
496
|
|
|
497
|
+
### Step 3: Mark Done (do this AFTER closing the issue)
|
|
450
498
|
\`\`\`bash
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
PROJECT_NUM=$(gh repo view --json projectsV2 -q '.projectsV2.Nodes[0].number')
|
|
454
|
-
PROJECT_ID=$(gh repo view --json projectsV2 -q '.projectsV2.Nodes[0].id')
|
|
499
|
+
gh project item-edit --project-id ${boardContext.projectId} --id $ITEM_ID --field-id ${boardContext.statusFieldId} --single-select-option-id ${boardContext.doneOptionId}
|
|
500
|
+
\`\`\`
|
|
455
501
|
|
|
456
|
-
|
|
457
|
-
|
|
502
|
+
**You MUST update the board status at each step. Do not skip this.**
|
|
503
|
+
` : `
|
|
504
|
+
## Project Board Status Updates
|
|
505
|
+
No project board is linked or Status field not found. Skip board status updates.
|
|
506
|
+
`;
|
|
507
|
+
return `You are an autonomous coding agent. Complete ONE GitHub Issue.
|
|
458
508
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
509
|
+
## Before Starting (REQUIRED - Read these first)
|
|
510
|
+
1. Read specs/prd.md to understand what we're building
|
|
511
|
+
2. Read CLAUDE.md for coding conventions
|
|
512
|
+
3. List open issues: gh issue list --state open --json number,title
|
|
462
513
|
|
|
463
|
-
|
|
464
|
-
gh project item-edit --project-id $PROJECT_ID --id $ITEM_ID --field-id $FIELD_ID --single-select-option-id $STATUS_ID
|
|
465
|
-
\`\`\`
|
|
514
|
+
IMPORTANT: Only use root-level files for project context. Do not read subdirectory README files.
|
|
466
515
|
|
|
467
|
-
|
|
516
|
+
## Pick an Issue
|
|
517
|
+
Choose the issue that best aligns with the PRD priorities.
|
|
518
|
+
If unsure, pick the lowest numbered open issue.
|
|
468
519
|
|
|
520
|
+
## Workflow
|
|
521
|
+
1. Read the issue: gh issue view <number>
|
|
522
|
+
2. **Mark issue as "In Progress" on project board** (see commands below)
|
|
523
|
+
3. Implement the code following existing patterns
|
|
524
|
+
4. Test your changes work correctly
|
|
525
|
+
5. Close the issue: gh issue close <number> --comment "Completed: <brief summary>"
|
|
526
|
+
6. **Mark issue as "Done" on project board**
|
|
527
|
+
7. Commit: git add -A && git commit -m "type(scope): description (closes #<number>)"
|
|
528
|
+
${boardInstructions}
|
|
469
529
|
## Rules
|
|
470
530
|
- ONE issue per iteration
|
|
471
531
|
- Follow existing code patterns
|
|
@@ -477,8 +537,8 @@ If any step fails (no project linked, field not found), skip and continue.
|
|
|
477
537
|
Output: RALPH_COMPLETE
|
|
478
538
|
If no issues remain: RALPH_ALL_DONE`;
|
|
479
539
|
}
|
|
480
|
-
async function runTaskIteration(iteration, useGitHub = false) {
|
|
481
|
-
const taskPrompt = useGitHub ? getGitHubTaskPrompt() : getTodoTaskPrompt();
|
|
540
|
+
async function runTaskIteration(iteration, useGitHub = false, boardContext) {
|
|
541
|
+
const taskPrompt = useGitHub ? getGitHubTaskPrompt(boardContext || null) : getTodoTaskPrompt();
|
|
482
542
|
let lastResult = {
|
|
483
543
|
success: false,
|
|
484
544
|
output: "",
|
|
@@ -704,6 +764,20 @@ async function cmdLoop() {
|
|
|
704
764
|
if (isGitHub) {
|
|
705
765
|
await ensureProjectLinked();
|
|
706
766
|
}
|
|
767
|
+
let boardContext = null;
|
|
768
|
+
if (isGitHub) {
|
|
769
|
+
console.log(import_picocolors6.default.dim("Fetching project board context..."));
|
|
770
|
+
boardContext = getProjectBoardContext();
|
|
771
|
+
if (boardContext) {
|
|
772
|
+
console.log(import_picocolors6.default.green(`\u2713 Board context loaded (Project #${boardContext.projectNumber})`));
|
|
773
|
+
if (!boardContext.inProgressOptionId || !boardContext.doneOptionId) {
|
|
774
|
+
console.log(import_picocolors6.default.yellow(" \u26A0 Missing status options - status updates may not work"));
|
|
775
|
+
}
|
|
776
|
+
} else {
|
|
777
|
+
console.log(import_picocolors6.default.yellow("\u26A0 Could not fetch project board context."));
|
|
778
|
+
console.log(import_picocolors6.default.dim(" Status updates will not work. Continuing anyway..."));
|
|
779
|
+
}
|
|
780
|
+
}
|
|
707
781
|
let maxIterations;
|
|
708
782
|
let hasRemainingTasks;
|
|
709
783
|
let trackerLabel;
|
|
@@ -749,7 +823,7 @@ async function cmdLoop() {
|
|
|
749
823
|
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`));
|
|
750
824
|
cleanupStaleProcesses();
|
|
751
825
|
const startTime = Date.now();
|
|
752
|
-
const result = await runTaskIteration(i, isGitHub);
|
|
826
|
+
const result = await runTaskIteration(i, isGitHub, boardContext);
|
|
753
827
|
const duration = Math.round((Date.now() - startTime) / 1e3);
|
|
754
828
|
console.log();
|
|
755
829
|
console.log(`Completed in ${duration}s (exit: ${result.success ? 0 : 1})`);
|