@phi-code-admin/phi-code 0.64.2 โ†’ 0.66.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.
@@ -467,7 +467,6 @@ export default function orchestratorExtension(pi: ExtensionAPI) {
467
467
 
468
468
  let phaseQueue: OrchestratorPhase[] = [];
469
469
  let orchestrationActive = false;
470
- let idlePollTimer: ReturnType<typeof setInterval> | null = null;
471
470
  let activeAgentPrompt: string | null = null;
472
471
  let activeAgentTools: string[] | null = null;
473
472
  let savedTools: string[] | null = null;
@@ -504,6 +503,7 @@ export default function orchestratorExtension(pi: ExtensionAPI) {
504
503
 
505
504
  /**
506
505
  * Load routing config and build phase queue with model assignments + agent definitions.
506
+ * Each phase now reads outputs from previous phases and writes structured outputs.
507
507
  */
508
508
  function buildPhases(description: string): OrchestratorPhase[] {
509
509
  const routingPath = join(homedir(), ".phi", "agent", "routing.json");
@@ -526,31 +526,195 @@ export default function orchestratorExtension(pi: ExtensionAPI) {
526
526
  const test = getModel("test");
527
527
  const review = getModel("review");
528
528
 
529
+ const ts = timestamp();
530
+
529
531
  return [
530
532
  {
531
533
  key: "explore", label: "๐Ÿ” Phase 1 โ€” EXPLORE", model: explore.preferred, fallback: explore.fallback,
532
534
  agent: loadAgentDef("explore"),
533
- instruction: `Analyze the project requirements and existing codebase. Identify what exists, what's needed, and any constraints.\n\n**Project:** ${description}\n\nList files, read key ones, check dependencies. Return a structured summary.`,
535
+ instruction: `You are the EXPLORE agent. Analyze the project requirements and existing codebase.
536
+
537
+ **Project Request:** ${description}
538
+
539
+ **Your tasks:**
540
+ 1. List all existing files and read key ones
541
+ 2. Identify tech stack, patterns, and constraints
542
+ 3. Create a STRUCTURED PROJECT BRIEF in \`.phi/plans/brief-${ts}.md\`:
543
+ - Context: what exists now
544
+ - Objective: what needs to be built
545
+ - Requirements: specific features needed
546
+ - Tech decisions: frameworks, patterns to use
547
+ - Constraints: what to NOT break
548
+
549
+ **Step 4:** Write your findings to \`.phi/plans/explore-${ts}.md\`
550
+
551
+ **Format for the project brief:**
552
+ \`\`\`markdown
553
+ ## Project Brief
554
+
555
+ ### Context
556
+ [Analyze what the user is asking for]
557
+
558
+ ### Objective
559
+ [Clear, specific goal]
560
+
561
+ ### Requirements
562
+ [Bullet list of what must be built]
563
+
564
+ ### Tech Decisions
565
+ [Frameworks, patterns, architecture choices]
566
+
567
+ ### Constraints
568
+ - Production-quality code, no placeholders
569
+ - Every function fully implemented
570
+ - Follow existing patterns if codebase exists
571
+ - [Any other specific constraints]
572
+ \`\`\``,
534
573
  },
535
574
  {
536
575
  key: "plan", label: "๐Ÿ“ Phase 2 โ€” PLAN", model: plan.preferred, fallback: plan.fallback,
537
576
  agent: loadAgentDef("plan"),
538
- instruction: `Design the architecture for this project. Define file structure, tech choices, and implementation approach.\n\n**Project:** ${description}\n\nBe specific: list every file to create with its purpose.`,
577
+ instruction: `You are the PLAN agent. Design the architecture and create a detailed task list.
578
+
579
+ **Project Request:** ${description}
580
+
581
+ **Step 1:** Read \`.phi/plans/brief-*.md\` (created by the explore phase)
582
+ **Step 2:** Read \`.phi/plans/explore-*.md\` to understand the codebase analysis
583
+ **Step 3:** Design the architecture based on findings
584
+ **Step 4:** Create a DETAILED TODO LIST in \`.phi/plans/todo-${ts}.md\`:
585
+ For each task:
586
+ - Task number and title
587
+ - Agent assignment (code/test)
588
+ - Files to create/modify
589
+ - Specific implementation details
590
+ - Dependencies on other tasks
591
+
592
+ **Format for the todo list:**
593
+ \`\`\`markdown
594
+ # TODO: Project Tasks
595
+
596
+ ## Task 1: [Task Title] [agent-type]
597
+ - [ ] Specific implementation details
598
+ - [ ] Files to create: path/to/file.ext
599
+ - [ ] Expected behavior
600
+ - Dependencies: None
601
+
602
+ ## Task 2: [Task Title] [agent-type]
603
+ - [ ] Implementation details
604
+ - Dependencies: Task 1
605
+ \`\`\``,
539
606
  },
540
607
  {
541
608
  key: "code", label: "๐Ÿ’ป Phase 3 โ€” CODE", model: code.preferred, fallback: code.fallback,
542
609
  agent: loadAgentDef("code"),
543
- instruction: `Implement the COMPLETE project. Create ALL files with production-quality code.\n\n**Project:** ${description}\n\n**Rules:**\n- Create every file needed\n- No placeholders, no TODOs, no stubs\n- Every function must be fully implemented\n- Follow the architecture from the previous planning phase`,
610
+ instruction: `You are the CODE agent. Implement the complete project.
611
+
612
+ **Project Request:** ${description}
613
+
614
+ **Step 1:** Read \`.phi/plans/brief-*.md\` for project context
615
+ **Step 2:** Read \`.phi/plans/todo-*.md\` to get your task list
616
+ **Step 3:** Implement EVERY task from the todo list, in order
617
+ **Step 4:** Write a progress report to \`.phi/plans/progress-${ts}.md\`
618
+
619
+ **Rules:**
620
+ - Create every file listed in the plan
621
+ - No placeholders, no TODOs, no stubs
622
+ - Every function must be fully implemented
623
+ - Follow the architecture from the plan
624
+ - Check off tasks in your progress report as you complete them
625
+
626
+ **Progress report format:**
627
+ \`\`\`markdown
628
+ # Progress Report
629
+
630
+ ## Completed Tasks
631
+ - [x] Task 1: Description - DONE
632
+ - [x] Task 2: Description - DONE
633
+
634
+ ## Files Created
635
+ - path/to/file1.ext - Purpose
636
+ - path/to/file2.ext - Purpose
637
+
638
+ ## Implementation Notes
639
+ [Any important decisions or changes made]
640
+ \`\`\``,
544
641
  },
545
642
  {
546
643
  key: "test", label: "๐Ÿงช Phase 4 โ€” TEST", model: test.preferred, fallback: test.fallback,
547
644
  agent: loadAgentDef("test"),
548
- instruction: `Test the implementation. Run the code, check for errors, verify it works.\n\n**Project:** ${description}\n\nFix any errors you find. Ensure the project runs correctly.`,
645
+ instruction: `You are the TEST agent. Verify the implementation.
646
+
647
+ **Project Request:** ${description}
648
+
649
+ **Step 1:** Read \`.phi/plans/todo-*.md\` to know what was planned
650
+ **Step 2:** Read \`.phi/plans/progress-*.md\` to see what was done
651
+ **Step 3:** Run the code, check for errors, test key features
652
+ **Step 4:** Fix any errors you find
653
+ **Step 5:** Write test results to \`.phi/plans/test-${ts}.md\`
654
+
655
+ **Test report format:**
656
+ \`\`\`markdown
657
+ # Test Report
658
+
659
+ ## Tests Executed
660
+ - [ ] Feature 1: Description - PASS/FAIL
661
+ - [ ] Feature 2: Description - PASS/FAIL
662
+
663
+ ## Errors Found & Fixed
664
+ - Error: Description
665
+ - Fix: What was done
666
+
667
+ ## Manual Testing
668
+ - Tested: What was manually verified
669
+ - Result: Pass/Fail with details
670
+
671
+ ## Final Status
672
+ โœ… All tests pass / โŒ Issues remain
673
+ \`\`\``,
549
674
  },
550
675
  {
551
676
  key: "review", label: "๐Ÿ” Phase 5 โ€” REVIEW", model: review.preferred, fallback: review.fallback,
552
677
  agent: loadAgentDef("review"),
553
- instruction: `Review the code quality, security, and performance. Fix any issues.\n\n**Project:** ${description}\n\nCheck: error handling, edge cases, code style, documentation.`,
678
+ instruction: `You are the REVIEW agent. Final quality review.
679
+
680
+ **Project Request:** ${description}
681
+
682
+ **Step 1:** Read all \`.phi/plans/*.md\` files
683
+ **Step 2:** Review code quality, security, performance
684
+ **Step 3:** Fix any issues found
685
+ **Step 4:** Write final report to \`.phi/plans/review-${ts}.md\`
686
+
687
+ **Review checklist:**
688
+ - Code quality: naming, structure, readability
689
+ - Security: input validation, error handling
690
+ - Performance: efficiency, resource usage
691
+ - Documentation: comments, README if needed
692
+ - Completeness: all requirements met
693
+
694
+ **Final report format:**
695
+ \`\`\`markdown
696
+ # Final Review
697
+
698
+ ## Code Quality โœ…/โŒ
699
+ - Structure: Good/Needs work
700
+ - Naming: Clear/Unclear
701
+ - Comments: Adequate/Missing
702
+
703
+ ## Security โœ…/โŒ
704
+ - Input validation: Present/Missing
705
+ - Error handling: Robust/Weak
706
+
707
+ ## Performance โœ…/โŒ
708
+ - Efficiency: Good/Could improve
709
+ - Resource usage: Optimal/Excessive
710
+
711
+ ## Completeness โœ…/โŒ
712
+ - All requirements met: Yes/No
713
+ - All files created: Yes/No
714
+
715
+ ## Final Verdict
716
+ โœ… Project ready for production / โŒ Issues need resolution
717
+ \`\`\``,
554
718
  },
555
719
  ];
556
720
  }
@@ -629,34 +793,11 @@ export default function orchestratorExtension(pi: ExtensionAPI) {
629
793
  activateAgent(phase, ctx);
630
794
  const agentName = phase.agent?.name || phase.key;
631
795
  ctx.ui.notify(`\n${phase.label} โ†’ \`${modelId}\` (agent: ${agentName})`, "info");
632
- // Wait for agent to be idle, then send the phase instruction
633
- waitForIdleThenSend(phase.instruction, ctx);
796
+ // Small delay to let the model switch settle, then send instruction
797
+ setTimeout(() => pi.sendUserMessage(phase.instruction), 500);
634
798
  });
635
799
  }
636
800
 
637
- /**
638
- * Reliable phase sending: poll isIdle() then sendUserMessage.
639
- * Retries up to 240 attempts (120 seconds).
640
- */
641
- function waitForIdleThenSend(message: string, ctx: any) {
642
- let attempts = 0;
643
- const timer = setInterval(() => {
644
- attempts++;
645
- if (attempts > 240) {
646
- clearInterval(timer);
647
- ctx.ui.notify("โš ๏ธ Orchestrator timeout โ€” agent never became idle.", "warning");
648
- setOrchestrationActive(false);
649
- phasePending = false;
650
- deactivateAgent();
651
- return;
652
- }
653
- if (ctx.isIdle()) {
654
- clearInterval(timer);
655
- setTimeout(() => pi.sendUserMessage(message), 300);
656
- }
657
- }, 500);
658
- }
659
-
660
801
  // โ”€โ”€โ”€ System Prompt Injection โ€” Agent personas โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
661
802
 
662
803
  pi.on("before_agent_start", async (event, _ctx) => {
@@ -667,42 +808,20 @@ export default function orchestratorExtension(pi: ExtensionAPI) {
667
808
  return { systemPrompt: activeAgentPrompt };
668
809
  });
669
810
 
670
- // โ”€โ”€โ”€ Output Event โ€” Phase Chaining โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
671
- // Fires on each output chunk. We use it to detect when a phase completes.
672
- // The key fix: only start ONE idle-check timer per phase, not one per chunk.
811
+ // โ”€โ”€โ”€ Agent End Event โ€” Phase Chaining โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
812
+ // "agent_end" fires when the full agent loop completes (all tool calls
813
+ // resolved, response fully generated). This is the ONLY reliable signal
814
+ // that a phase has finished.
815
+ //
816
+ // Previous approach used "output" event which DOES NOT EXIST in Pi.
817
+ // That's why phases 2-5 never executed.
673
818
 
674
- pi.on("output", async (_event, ctx) => {
819
+ pi.on("agent_end", async (_event, ctx) => {
675
820
  if (!orchestrationActive || !phasePending) return;
676
- if (phaseQueue.length === 0 && phasePending) {
677
- // Last phase in progress โ€” wait for it to finish, then complete
678
- }
679
821
 
680
- // Debounce: clear any existing timer, start fresh
681
- if (idlePollTimer) {
682
- clearInterval(idlePollTimer);
683
- idlePollTimer = null;
684
- }
685
-
686
- // After output, wait a bit then check if the agent is truly idle
687
- // Use a longer initial delay (2 seconds) to let tool calls complete
688
- idlePollTimer = setTimeout(() => {
689
- let attempts = 0;
690
- idlePollTimer = setInterval(() => {
691
- attempts++;
692
- if (attempts > 60) { // 30 seconds after last output
693
- clearInterval(idlePollTimer!);
694
- idlePollTimer = null;
695
- // Don't timeout โ€” the phase might still have tool calls
696
- return;
697
- }
698
- if (ctx.isIdle()) {
699
- clearInterval(idlePollTimer!);
700
- idlePollTimer = null;
701
- phasePending = false;
702
- sendNextPhase(ctx);
703
- }
704
- }, 500) as any;
705
- }, 2000) as any;
822
+ // Phase complete โ€” chain to next
823
+ phasePending = false;
824
+ sendNextPhase(ctx);
706
825
  });
707
826
 
708
827
  // โ”€โ”€โ”€ /plan Command โ€” Full workflow โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phi-code-admin/phi-code",
3
- "version": "0.64.2",
3
+ "version": "0.66.0",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "piConfig": {