jfl 0.9.6 → 0.9.7
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/commands/agents.js +1 -1
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/context-hub.d.ts.map +1 -1
- package/dist/commands/context-hub.js +77 -18
- package/dist/commands/context-hub.js.map +1 -1
- package/dist/commands/deploy.js +1 -1
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/feedback.js +1 -1
- package/dist/commands/feedback.js.map +1 -1
- package/dist/commands/hud.js +1 -1
- package/dist/commands/hud.js.map +1 -1
- package/dist/commands/init-from-service.js +1 -1
- package/dist/commands/init-from-service.js.map +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.d.ts +2 -13
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +6 -44
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/organize.d.ts +16 -0
- package/dist/commands/organize.d.ts.map +1 -0
- package/dist/commands/organize.js +334 -0
- package/dist/commands/organize.js.map +1 -0
- package/dist/commands/peter.d.ts.map +1 -1
- package/dist/commands/peter.js +273 -0
- package/dist/commands/peter.js.map +1 -1
- package/dist/commands/pi.d.ts.map +1 -1
- package/dist/commands/pi.js +8 -2
- package/dist/commands/pi.js.map +1 -1
- package/dist/commands/repair.js +1 -1
- package/dist/commands/repair.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +113 -45
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +4 -4
- package/dist/commands/status.js.map +1 -1
- package/dist/index.d.ts +0 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +60 -19
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-config.d.ts.map +1 -1
- package/dist/lib/agent-config.js +24 -2
- package/dist/lib/agent-config.js.map +1 -1
- package/dist/lib/hub-health.d.ts.map +1 -1
- package/dist/lib/hub-health.js +14 -2
- package/dist/lib/hub-health.js.map +1 -1
- package/dist/lib/resource-optimizer-middleware.d.ts.map +1 -1
- package/dist/lib/resource-optimizer-middleware.js +8 -2
- package/dist/lib/resource-optimizer-middleware.js.map +1 -1
- package/dist/lib/telemetry.d.ts.map +1 -1
- package/dist/lib/telemetry.js +13 -12
- package/dist/lib/telemetry.js.map +1 -1
- package/dist/utils/auth-status.d.ts +21 -0
- package/dist/utils/auth-status.d.ts.map +1 -0
- package/dist/utils/auth-status.js +53 -0
- package/dist/utils/auth-status.js.map +1 -0
- package/package.json +3 -2
- package/packages/pi/dist/agent-grid.d.ts +24 -0
- package/packages/pi/dist/agent-grid.d.ts.map +1 -0
- package/packages/pi/dist/agent-grid.js +162 -0
- package/packages/pi/dist/agent-grid.js.map +1 -0
- package/packages/pi/dist/agent-names.d.ts +43 -0
- package/packages/pi/dist/agent-names.d.ts.map +1 -0
- package/packages/pi/dist/agent-names.js +156 -0
- package/packages/pi/dist/agent-names.js.map +1 -0
- package/packages/pi/dist/autoresearch.d.ts +15 -0
- package/packages/pi/dist/autoresearch.d.ts.map +1 -0
- package/packages/pi/dist/autoresearch.js +372 -0
- package/packages/pi/dist/autoresearch.js.map +1 -0
- package/packages/pi/dist/bookmarks.d.ts +15 -0
- package/packages/pi/dist/bookmarks.d.ts.map +1 -0
- package/packages/pi/dist/bookmarks.js +77 -0
- package/packages/pi/dist/bookmarks.js.map +1 -0
- package/packages/pi/dist/context.d.ts +17 -0
- package/packages/pi/dist/context.d.ts.map +1 -0
- package/packages/pi/dist/context.js +152 -0
- package/packages/pi/dist/context.js.map +1 -0
- package/packages/pi/dist/crm-tool.d.ts +12 -0
- package/packages/pi/dist/crm-tool.d.ts.map +1 -0
- package/packages/pi/dist/crm-tool.js +58 -0
- package/packages/pi/dist/crm-tool.js.map +1 -0
- package/packages/pi/dist/eval-tool.d.ts +11 -0
- package/packages/pi/dist/eval-tool.d.ts.map +1 -0
- package/packages/pi/dist/eval-tool.js +188 -0
- package/packages/pi/dist/eval-tool.js.map +1 -0
- package/packages/pi/dist/eval.d.ts +12 -0
- package/packages/pi/dist/eval.d.ts.map +1 -0
- package/packages/pi/dist/eval.js +43 -0
- package/packages/pi/dist/eval.js.map +1 -0
- package/packages/pi/dist/footer.d.ts +20 -0
- package/packages/pi/dist/footer.d.ts.map +1 -0
- package/packages/pi/dist/footer.js +222 -0
- package/packages/pi/dist/footer.js.map +1 -0
- package/packages/pi/dist/header.d.ts +17 -0
- package/packages/pi/dist/header.d.ts.map +1 -0
- package/packages/pi/dist/header.js +156 -0
- package/packages/pi/dist/header.js.map +1 -0
- package/packages/pi/dist/hub-resolver.d.ts +11 -0
- package/packages/pi/dist/hub-resolver.d.ts.map +1 -0
- package/packages/pi/dist/hub-resolver.js +58 -0
- package/packages/pi/dist/hub-resolver.js.map +1 -0
- package/packages/pi/dist/hub-tools.d.ts +14 -0
- package/packages/pi/dist/hub-tools.d.ts.map +1 -0
- package/packages/pi/dist/hub-tools.js +266 -0
- package/packages/pi/dist/hub-tools.js.map +1 -0
- package/packages/pi/dist/hud-tool.d.ts +17 -0
- package/packages/pi/dist/hud-tool.d.ts.map +1 -0
- package/packages/pi/dist/hud-tool.js +297 -0
- package/packages/pi/dist/hud-tool.js.map +1 -0
- package/packages/pi/dist/index.d.ts +12 -0
- package/packages/pi/dist/index.d.ts.map +1 -0
- package/packages/pi/dist/index.js +436 -0
- package/packages/pi/dist/index.js.map +1 -0
- package/packages/pi/dist/jfl-resolve.d.ts +29 -0
- package/packages/pi/dist/jfl-resolve.d.ts.map +1 -0
- package/packages/pi/dist/jfl-resolve.js +89 -0
- package/packages/pi/dist/jfl-resolve.js.map +1 -0
- package/packages/pi/dist/journal.d.ts +23 -0
- package/packages/pi/dist/journal.d.ts.map +1 -0
- package/packages/pi/dist/journal.js +250 -0
- package/packages/pi/dist/journal.js.map +1 -0
- package/packages/pi/dist/map-bridge.d.ts +20 -0
- package/packages/pi/dist/map-bridge.d.ts.map +1 -0
- package/packages/pi/dist/map-bridge.js +181 -0
- package/packages/pi/dist/map-bridge.js.map +1 -0
- package/packages/pi/dist/memory-tool.d.ts +11 -0
- package/packages/pi/dist/memory-tool.d.ts.map +1 -0
- package/packages/pi/dist/memory-tool.js +148 -0
- package/packages/pi/dist/memory-tool.js.map +1 -0
- package/packages/pi/dist/notifications.d.ts +15 -0
- package/packages/pi/dist/notifications.d.ts.map +1 -0
- package/packages/pi/dist/notifications.js +65 -0
- package/packages/pi/dist/notifications.js.map +1 -0
- package/packages/pi/dist/onboarding-v1.d.ts +15 -0
- package/packages/pi/dist/onboarding-v1.d.ts.map +1 -0
- package/packages/pi/dist/onboarding-v1.js +417 -0
- package/packages/pi/dist/onboarding-v1.js.map +1 -0
- package/packages/pi/dist/onboarding-v2.d.ts +18 -0
- package/packages/pi/dist/onboarding-v2.d.ts.map +1 -0
- package/packages/pi/dist/onboarding-v2.js +402 -0
- package/packages/pi/dist/onboarding-v2.js.map +1 -0
- package/packages/pi/dist/onboarding-v3.d.ts +13 -0
- package/packages/pi/dist/onboarding-v3.d.ts.map +1 -0
- package/packages/pi/dist/onboarding-v3.js +581 -0
- package/packages/pi/dist/onboarding-v3.js.map +1 -0
- package/packages/pi/dist/peter-parker.d.ts +12 -0
- package/packages/pi/dist/peter-parker.d.ts.map +1 -0
- package/packages/pi/dist/peter-parker.js +162 -0
- package/packages/pi/dist/peter-parker.js.map +1 -0
- package/packages/pi/dist/pivot-tool.d.ts +11 -0
- package/packages/pi/dist/pivot-tool.d.ts.map +1 -0
- package/packages/pi/dist/pivot-tool.js +56 -0
- package/packages/pi/dist/pivot-tool.js.map +1 -0
- package/packages/pi/dist/policy-head-tool.d.ts +15 -0
- package/packages/pi/dist/policy-head-tool.d.ts.map +1 -0
- package/packages/pi/dist/policy-head-tool.js +220 -0
- package/packages/pi/dist/policy-head-tool.js.map +1 -0
- package/packages/pi/dist/portfolio-bridge.d.ts +12 -0
- package/packages/pi/dist/portfolio-bridge.d.ts.map +1 -0
- package/packages/pi/dist/portfolio-bridge.js +81 -0
- package/packages/pi/dist/portfolio-bridge.js.map +1 -0
- package/packages/pi/dist/service-skills.d.ts +15 -0
- package/packages/pi/dist/service-skills.d.ts.map +1 -0
- package/packages/pi/dist/service-skills.js +198 -0
- package/packages/pi/dist/service-skills.js.map +1 -0
- package/packages/pi/dist/session.d.ts +24 -0
- package/packages/pi/dist/session.d.ts.map +1 -0
- package/packages/pi/dist/session.js +394 -0
- package/packages/pi/dist/session.js.map +1 -0
- package/packages/pi/dist/shortcuts.d.ts +11 -0
- package/packages/pi/dist/shortcuts.d.ts.map +1 -0
- package/packages/pi/dist/shortcuts.js +231 -0
- package/packages/pi/dist/shortcuts.js.map +1 -0
- package/packages/pi/dist/startup-briefing.d.ts +13 -0
- package/packages/pi/dist/startup-briefing.d.ts.map +1 -0
- package/packages/pi/dist/startup-briefing.js +271 -0
- package/packages/pi/dist/startup-briefing.js.map +1 -0
- package/packages/pi/dist/stratus-bridge.d.ts +14 -0
- package/packages/pi/dist/stratus-bridge.d.ts.map +1 -0
- package/packages/pi/dist/stratus-bridge.js +104 -0
- package/packages/pi/dist/stratus-bridge.js.map +1 -0
- package/packages/pi/dist/subway-mesh.d.ts +88 -0
- package/packages/pi/dist/subway-mesh.d.ts.map +1 -0
- package/packages/pi/dist/subway-mesh.js +813 -0
- package/packages/pi/dist/subway-mesh.js.map +1 -0
- package/packages/pi/dist/synopsis-tool.d.ts +12 -0
- package/packages/pi/dist/synopsis-tool.d.ts.map +1 -0
- package/packages/pi/dist/synopsis-tool.js +84 -0
- package/packages/pi/dist/synopsis-tool.js.map +1 -0
- package/packages/pi/dist/tool-renderers.d.ts +55 -0
- package/packages/pi/dist/tool-renderers.d.ts.map +1 -0
- package/packages/pi/dist/tool-renderers.js +349 -0
- package/packages/pi/dist/tool-renderers.js.map +1 -0
- package/packages/pi/dist/training-buffer-tool.d.ts +16 -0
- package/packages/pi/dist/training-buffer-tool.d.ts.map +1 -0
- package/packages/pi/dist/training-buffer-tool.js +319 -0
- package/packages/pi/dist/training-buffer-tool.js.map +1 -0
- package/packages/pi/dist/types.d.ts +195 -0
- package/packages/pi/dist/types.d.ts.map +1 -0
- package/packages/pi/dist/types.js +11 -0
- package/packages/pi/dist/types.js.map +1 -0
- package/packages/pi/extensions/session.ts +115 -8
- package/packages/pi/extensions/training-buffer-tool.ts +15 -8
- package/packages/pi/extensions/types.ts +1 -0
- package/packages/pi/package.json +2 -3
package/dist/commands/peter.js
CHANGED
|
@@ -583,6 +583,274 @@ async function runWithPR(projectRoot, task) {
|
|
|
583
583
|
gitExec(["checkout", baseBranch], projectRoot);
|
|
584
584
|
console.log(chalk.green(" PP: Done\n"));
|
|
585
585
|
}
|
|
586
|
+
// ============================================================================
|
|
587
|
+
// Pickup — self-driving loop: poll backlog → pick → branch → execute → PR
|
|
588
|
+
// ============================================================================
|
|
589
|
+
function slugify(text) {
|
|
590
|
+
return text
|
|
591
|
+
.toLowerCase()
|
|
592
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
593
|
+
.replace(/^-+|-+$/g, "")
|
|
594
|
+
.slice(0, 40);
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Extract cross-repo close reference from issue body metadata.
|
|
598
|
+
* Looks for patterns like "402goose/JFL-GTM#25" in the jfl metadata block,
|
|
599
|
+
* or falls back to same-repo #N.
|
|
600
|
+
*/
|
|
601
|
+
function extractCloseRef(card) {
|
|
602
|
+
// Check for explicit cross-repo ref in metadata block
|
|
603
|
+
const metaMatch = card.description.match(/<!--\s*jfl:([\s\S]*?)-->/);
|
|
604
|
+
if (metaMatch) {
|
|
605
|
+
const meta = metaMatch[1];
|
|
606
|
+
const crossRepoMatch = meta.match(/close_ref:\s*(.+)/);
|
|
607
|
+
if (crossRepoMatch)
|
|
608
|
+
return crossRepoMatch[1].trim();
|
|
609
|
+
}
|
|
610
|
+
// Default: same-repo reference
|
|
611
|
+
return `#${card.number}`;
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Append an entry to the pickup queue for audit/tracking.
|
|
615
|
+
*/
|
|
616
|
+
function appendPickupQueue(projectRoot, entry) {
|
|
617
|
+
const queuePath = path.join(projectRoot, ".jfl", "pickup-queue.jsonl");
|
|
618
|
+
const dir = path.dirname(queuePath);
|
|
619
|
+
if (!fs.existsSync(dir))
|
|
620
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
621
|
+
fs.appendFileSync(queuePath, JSON.stringify(entry) + "\n");
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Poll jfl/backlog for source:linear issues, pick the highest priority,
|
|
625
|
+
* move to in_progress, create branch, execute, create PR, close on merge.
|
|
626
|
+
*/
|
|
627
|
+
async function runPickup(projectRoot) {
|
|
628
|
+
console.log(chalk.bold("\n Peter Parker — Backlog Pickup\n"));
|
|
629
|
+
console.log(chalk.gray(" Polling jfl/backlog for source:linear issues...\n"));
|
|
630
|
+
if (!hasPi() && !hasRalphTui()) {
|
|
631
|
+
console.log(chalk.yellow(" Neither pi nor ralph-tui is installed"));
|
|
632
|
+
console.log(chalk.gray(" Install pi: npm i -g @mariozechner/pi-coding-agent"));
|
|
633
|
+
console.log(chalk.gray(" Or ralph-tui: bun install -g ralph-tui\n"));
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
const { GitHubKanban } = await import("../lib/kanban-github.js");
|
|
637
|
+
let kb;
|
|
638
|
+
try {
|
|
639
|
+
kb = new GitHubKanban(projectRoot);
|
|
640
|
+
}
|
|
641
|
+
catch (err) {
|
|
642
|
+
console.log(chalk.red(` PP: ${err.message}`));
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
// Fetch backlog cards with source:linear
|
|
646
|
+
let cards;
|
|
647
|
+
try {
|
|
648
|
+
cards = await kb.getCards({ column: "backlog", source: "linear" });
|
|
649
|
+
}
|
|
650
|
+
catch (err) {
|
|
651
|
+
console.log(chalk.red(` PP: Failed to fetch backlog: ${err.message}`));
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
if (cards.length === 0) {
|
|
655
|
+
console.log(chalk.yellow(" No source:linear issues in jfl/backlog. Nothing to pick up.\n"));
|
|
656
|
+
return;
|
|
657
|
+
}
|
|
658
|
+
// Already sorted by priority desc from getCards
|
|
659
|
+
const card = cards[0];
|
|
660
|
+
console.log(chalk.cyan(` Picked: #${card.number} — ${card.title}`));
|
|
661
|
+
console.log(chalk.gray(` Priority: ${card.priority} Source: ${card.source}`));
|
|
662
|
+
if (card.labels.length > 0) {
|
|
663
|
+
console.log(chalk.gray(` Labels: ${card.labels.join(", ")}`));
|
|
664
|
+
}
|
|
665
|
+
console.log();
|
|
666
|
+
// Move to in_progress
|
|
667
|
+
try {
|
|
668
|
+
kb.pick(card.number, "peter-parker");
|
|
669
|
+
console.log(chalk.gray(` 📋 Issue #${card.number} → in_progress (assigned: peter-parker)`));
|
|
670
|
+
}
|
|
671
|
+
catch (err) {
|
|
672
|
+
console.log(chalk.yellow(` PP: Could not move issue: ${err.message}`));
|
|
673
|
+
// Continue anyway — don't block on label move failure
|
|
674
|
+
}
|
|
675
|
+
// Build task prompt from issue title + description
|
|
676
|
+
const taskLines = [`GitHub #${card.number}: ${card.title}`];
|
|
677
|
+
if (card.description) {
|
|
678
|
+
// Strip the jfl metadata block from the description for the prompt
|
|
679
|
+
const cleanDesc = card.description.replace(/<!--\s*jfl:[\s\S]*?-->/g, "").trim();
|
|
680
|
+
if (cleanDesc)
|
|
681
|
+
taskLines.push("", cleanDesc);
|
|
682
|
+
}
|
|
683
|
+
const task = taskLines.join("\n");
|
|
684
|
+
// Create branch
|
|
685
|
+
const baseBranch = "main";
|
|
686
|
+
const slug = slugify(card.title);
|
|
687
|
+
const branchName = `pp/issue-${card.number}-${slug}`;
|
|
688
|
+
console.log(chalk.cyan(`\n PP: Creating branch ${branchName}`));
|
|
689
|
+
gitExec(["fetch", "origin", baseBranch], projectRoot);
|
|
690
|
+
let checkout = gitExec(["checkout", "-b", branchName, `origin/${baseBranch}`], projectRoot);
|
|
691
|
+
if (!checkout.ok) {
|
|
692
|
+
checkout = gitExec(["checkout", "-b", branchName, baseBranch], projectRoot);
|
|
693
|
+
}
|
|
694
|
+
if (!checkout.ok) {
|
|
695
|
+
console.log(chalk.red(` PP: Failed to create branch ${branchName}`));
|
|
696
|
+
// Revert kanban move
|
|
697
|
+
try {
|
|
698
|
+
kb.move(card.number, "backlog");
|
|
699
|
+
}
|
|
700
|
+
catch { }
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
// Track pickup
|
|
704
|
+
appendPickupQueue(projectRoot, {
|
|
705
|
+
ts: new Date().toISOString(),
|
|
706
|
+
issue: card.number,
|
|
707
|
+
title: card.title,
|
|
708
|
+
branch: branchName,
|
|
709
|
+
source: card.source,
|
|
710
|
+
priority: card.priority,
|
|
711
|
+
status: "in_progress",
|
|
712
|
+
});
|
|
713
|
+
// Run the agent
|
|
714
|
+
console.log(chalk.cyan(` PP: Running agent on task...\n`));
|
|
715
|
+
if (hasPi()) {
|
|
716
|
+
await runAgentWithPi(projectRoot, task);
|
|
717
|
+
}
|
|
718
|
+
else {
|
|
719
|
+
await runAgentWithRalphTui(projectRoot, task);
|
|
720
|
+
}
|
|
721
|
+
// Check for changes
|
|
722
|
+
const diffCheck = gitExec(["diff", "--quiet", "HEAD"], projectRoot);
|
|
723
|
+
const untrackedResult = spawnSync("git", ["ls-files", "--others", "--exclude-standard"], {
|
|
724
|
+
cwd: projectRoot,
|
|
725
|
+
encoding: "utf-8",
|
|
726
|
+
stdio: "pipe",
|
|
727
|
+
});
|
|
728
|
+
const untracked = (untrackedResult.stdout || "").trim();
|
|
729
|
+
if (diffCheck.ok && !untracked) {
|
|
730
|
+
console.log(chalk.yellow("\n PP: No changes made, reverting to backlog"));
|
|
731
|
+
gitExec(["checkout", baseBranch], projectRoot);
|
|
732
|
+
gitExec(["branch", "-D", branchName], projectRoot);
|
|
733
|
+
try {
|
|
734
|
+
kb.move(card.number, "backlog");
|
|
735
|
+
}
|
|
736
|
+
catch { }
|
|
737
|
+
appendPickupQueue(projectRoot, {
|
|
738
|
+
ts: new Date().toISOString(),
|
|
739
|
+
issue: card.number,
|
|
740
|
+
branch: branchName,
|
|
741
|
+
status: "no_changes",
|
|
742
|
+
});
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
// Commit
|
|
746
|
+
console.log(chalk.cyan(" PP: Changes detected, committing..."));
|
|
747
|
+
const commitMsg = `fix(pp): #${card.number} ${card.title}`;
|
|
748
|
+
const commitHash = signedAgentCommit(projectRoot, commitMsg, {
|
|
749
|
+
agentId: "peter-parker",
|
|
750
|
+
sessionId: branchName,
|
|
751
|
+
});
|
|
752
|
+
if (!commitHash) {
|
|
753
|
+
console.log(chalk.red(" PP: Commit failed"));
|
|
754
|
+
gitExec(["checkout", baseBranch], projectRoot);
|
|
755
|
+
try {
|
|
756
|
+
kb.move(card.number, "backlog");
|
|
757
|
+
}
|
|
758
|
+
catch { }
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
// Push
|
|
762
|
+
console.log(chalk.cyan(" PP: Pushing branch..."));
|
|
763
|
+
const pushResult = gitExec(["push", "-u", "origin", branchName], projectRoot);
|
|
764
|
+
if (!pushResult.ok) {
|
|
765
|
+
console.log(chalk.red(" PP: Push failed"));
|
|
766
|
+
console.log(chalk.gray(` ${pushResult.output}`));
|
|
767
|
+
gitExec(["checkout", baseBranch], projectRoot);
|
|
768
|
+
try {
|
|
769
|
+
kb.move(card.number, "backlog");
|
|
770
|
+
}
|
|
771
|
+
catch { }
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
// Create PR
|
|
775
|
+
console.log(chalk.cyan(" PP: Creating PR..."));
|
|
776
|
+
const closeRef = extractCloseRef(card);
|
|
777
|
+
const prTitle = `PP: #${card.number} ${card.title.slice(0, 60)}`;
|
|
778
|
+
const prBody = [
|
|
779
|
+
"## Auto-generated by Peter Parker (Backlog Pickup)",
|
|
780
|
+
"",
|
|
781
|
+
`**Issue:** #${card.number} — ${card.title}`,
|
|
782
|
+
`**Branch:** \`${branchName}\``,
|
|
783
|
+
`**Source:** ${card.source}`,
|
|
784
|
+
"",
|
|
785
|
+
`Closes ${closeRef}`,
|
|
786
|
+
"",
|
|
787
|
+
"### Eval Suite",
|
|
788
|
+
"This PR will be evaluated by the CI eval suite.",
|
|
789
|
+
"Auto-merge will trigger if eval score improves over baseline.",
|
|
790
|
+
"",
|
|
791
|
+
"---",
|
|
792
|
+
"*Generated by JFL self-driving loop (pickup)*",
|
|
793
|
+
].join("\n");
|
|
794
|
+
let prResult = ghExec([
|
|
795
|
+
"pr", "create",
|
|
796
|
+
"--title", prTitle,
|
|
797
|
+
"--body", prBody,
|
|
798
|
+
"--base", baseBranch,
|
|
799
|
+
"--head", branchName,
|
|
800
|
+
"--label", "pp-generated",
|
|
801
|
+
], projectRoot);
|
|
802
|
+
if (!prResult.ok) {
|
|
803
|
+
prResult = ghExec([
|
|
804
|
+
"pr", "create",
|
|
805
|
+
"--title", prTitle,
|
|
806
|
+
"--body", prBody,
|
|
807
|
+
"--base", baseBranch,
|
|
808
|
+
"--head", branchName,
|
|
809
|
+
], projectRoot);
|
|
810
|
+
}
|
|
811
|
+
if (!prResult.ok) {
|
|
812
|
+
console.log(chalk.red(" PP: Failed to create PR"));
|
|
813
|
+
console.log(chalk.gray(` ${prResult.output}`));
|
|
814
|
+
}
|
|
815
|
+
else {
|
|
816
|
+
const prUrl = prResult.output;
|
|
817
|
+
console.log(chalk.green(`\n PP: PR created at ${prUrl}`));
|
|
818
|
+
// Move to eval column
|
|
819
|
+
try {
|
|
820
|
+
kb.move(card.number, "eval");
|
|
821
|
+
}
|
|
822
|
+
catch { }
|
|
823
|
+
// Track completion
|
|
824
|
+
appendPickupQueue(projectRoot, {
|
|
825
|
+
ts: new Date().toISOString(),
|
|
826
|
+
issue: card.number,
|
|
827
|
+
branch: branchName,
|
|
828
|
+
pr_url: prUrl,
|
|
829
|
+
status: "pr_created",
|
|
830
|
+
});
|
|
831
|
+
await postHubEvent(projectRoot, "peter:pickup-complete", {
|
|
832
|
+
issue: card.number,
|
|
833
|
+
title: card.title,
|
|
834
|
+
branch: branchName,
|
|
835
|
+
pr_url: prUrl,
|
|
836
|
+
source: card.source,
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
// Write journal entry
|
|
840
|
+
writeJournalEntry(projectRoot, {
|
|
841
|
+
v: 1,
|
|
842
|
+
ts: new Date().toISOString(),
|
|
843
|
+
session: branchName,
|
|
844
|
+
type: "feature",
|
|
845
|
+
status: "complete",
|
|
846
|
+
title: `Pickup: #${card.number} ${card.title}`,
|
|
847
|
+
summary: `Auto-picked source:linear issue from backlog and executed. Branch: ${branchName}`,
|
|
848
|
+
detail: `Issue: #${card.number} — ${card.title}\nSource: ${card.source}\nPriority: ${card.priority}`,
|
|
849
|
+
agent_id: "peter-parker",
|
|
850
|
+
});
|
|
851
|
+
gitExec(["checkout", baseBranch], projectRoot);
|
|
852
|
+
console.log(chalk.green(" PP: Pickup complete.\n"));
|
|
853
|
+
}
|
|
586
854
|
function buildRLState(evals, trajectoryLength, recentDeltas) {
|
|
587
855
|
const latest = evals.sort((a, b) => b.ts.localeCompare(a.ts))[0];
|
|
588
856
|
return {
|
|
@@ -2265,12 +2533,17 @@ export async function peterCommand(action, options = {}) {
|
|
|
2265
2533
|
await runReview(projectRoot);
|
|
2266
2534
|
break;
|
|
2267
2535
|
}
|
|
2536
|
+
case "pickup": {
|
|
2537
|
+
await runPickup(projectRoot);
|
|
2538
|
+
break;
|
|
2539
|
+
}
|
|
2268
2540
|
default: {
|
|
2269
2541
|
console.log(chalk.bold("\n Peter Parker - Model-Routed Agent Orchestrator\n"));
|
|
2270
2542
|
console.log(chalk.gray(" Commands:"));
|
|
2271
2543
|
console.log(" jfl peter setup [--cost|--balanced|--quality] Generate agent config");
|
|
2272
2544
|
console.log(" jfl peter run [--task <task>] Run orchestrator");
|
|
2273
2545
|
console.log(" jfl peter pr --task <task> Run + branch + PR");
|
|
2546
|
+
console.log(" jfl peter pickup Poll backlog, pick source:linear issue, execute, PR");
|
|
2274
2547
|
console.log(" jfl peter experiment Proactive: pick + execute next experiment");
|
|
2275
2548
|
console.log(" jfl peter autoresearch [--rounds N] [--budget $] [--pi]");
|
|
2276
2549
|
console.log(" Autoresearch mode with Pi runtime");
|