pi-orq
v0.1.9
Published
CLI multi-agent refactoring orchestrator powered by Pi Coding Agent and OpenRouter
Maintainers
Readme
pi-orq — Multi-Agent Refactoring Orchestrator with Git Isolation
npm CLI tool that lets users select project files via an interactive terminal tree view, configure N simultaneous Pi Coding Agent instances via OpenRouter, and run parallel refactoring with Git worktree isolation, real-time feedback, and auditable integration. Uses LangChain.js with ReAct pattern for intelligent branch naming.
Overview
Run npx pi-orq at the root of a Git project. The Ink interface presents a collapsible directory/file tree with checkboxes. Select the files to refactor, choose a model, define how many simultaneous agents will run, and provide a refactoring prompt.
The orchestrator:
- executa um preflight validando repositorio Git, branch base, commit base, remote e capacidade de push; working tree suja gera warning, nao bloqueio;
- cria uma worktree de integracao dedicada no inicio da run;
- para cada agente, cria uma branch propria e uma worktree propria derivadas do mesmo
baseCommit; - cada sessao Pi Agent roda exclusivamente dentro da sua worktree;
- ao terminar, o orquestrador valida, commita, tenta fazer push da branch e remove a worktree local;
- um agente final de integracao faz merge de todas as branches na worktree principal;
- apos integracao, a worktree de integracao e removida — apenas a branch permanece como artefato;
- um dashboard Ink exibe todo o ciclo em tempo real.
Architecture
┌─────────────────────────────────────────────────────────────┐
│ PREFLIGHT │
│ Valida repo Git, branch base, commit base, remote/push │
└─────────────────┬───────────────────────────────────────────┘
│
┌─────────────────┴───────────────────────────────────────────┐
│ RUN MANIFEST │
│ runId, baseBranch, baseCommit, agentEntries[], status │
└─────────────────┬───────────────────────────────────────────┘
│
┌─────────────────┴───────────────────────────────────────────┐
│ WORKTREE SETUP │
│ │
│ Integration worktree: pi-orq/<runId>/integration │
│ Agent 1 worktree: pi-orq/<runId>/agent-1 │
│ Agent N worktree: pi-orq/<runId>/agent-N │
└─────────────────┬───────────────────────────────────────────┘
│
┌─────────────────┴───────────────────────────────────────────┐
│ TASK POOL (continuous pull) │
│ │
│ 1 file = 1 task. Pool keeps N agents active at all times. │
│ When an agent finishes, the next task is pulled from queue. │
│ │
│ Wave 1: independent files (no cross-deps) │
│ Wave 2: dependent files (imports from selected files) │
│ │
│ Cada agente: │
│ session_starting → streaming → tool_running → finalizing │
│ → validating → committing → pushing → cleaning_up → done │
└─────────────────┬───────────────────────────────────────────┘
│
┌─────────────────┴───────────────────────────────────────────┐
│ INTEGRATION │
│ │
│ Semantic branch name generated via LLM (ReAct/LangChain.js)│
│ Deterministic merge (wave ASC, agentId ASC) │
│ Conflicts → integration agent resolves in worktree │
│ Final commit on integration branch │
│ Agent branches deleted │
│ Integration worktree removed — branch preserved as artifact │
└─────────────────┬───────────────────────────────────────────┘
│
┌─────────────────┴───────────────────────────────────────────┐
│ REPORT │
│ Branches, SHAs, pushes, merges, conflicts, cost, tokens │
└─────────────────────────────────────────────────────────────┘Installation
# Global install
npm install -g pi-orq
# Or via npx (no install)
npx pi-orqPrerequisites
- Node.js >= 20
- Git >= 2.20 (suporte a worktrees)
- Repositorio Git valido; working tree suja e permitida, mas arquivos nao committed nao ficam visiveis para os agentes
- API key do OpenRouter
Usage
# Run at the root of a Git project
npx pi-orqNo estado atual, a CLI e totalmente interativa. O entry point nao faz parsing de flags como --key, --model ou --instances.
Fluxo
- Setup — configure OpenRouter API key (globally persisted to
~/.pi-orq/config.json) and choose model via interactive selector (per-run) - File Select — select files via interactive tree view
- Confirm — define number of agents and refactoring prompt
- Dashboard — monitor execution in real time with startup progress, Kanban board, and live logs
- Report — review branches, commits, merges, and cost
Configuration Model
| Tecla | Acao |
|-------|------|
| q | Sair |
| p | Pausar todos os agentes |
| r | Retomar execucao |
| Tab | Focar proximo agente |
| f | Alternar filtro de logs entre agente focado e todos |
| 1-9 | Filtrar logs diretamente por agent ID |
| 0 | Voltar a mostrar todos os logs |
Dashboard Shortcuts
| Key | Action |
|-----|--------|
| q | Quit |
| p | Pause all agents |
| r | Resume execution |
| Tab | Focus next agent |
| f | Toggle log filter for focused agent |
| 0-9 | Filter logs by agent ID (0 = all) |
Dashboard Layout
The dashboard shows:
- Header: run ID, wave progress, elapsed time, agent count, status
- Cost bar: real-time cost tracking against the hard cap
- Startup progress: checklist of initialization phases (preflight, manifest, worktrees, wave planning) — visible before agents populate
- Kanban board: 3-column layout (TODO / DOING / DONE) with colored headers, progress bar, per-agent token/cost tracking, and compact cards for terminal agents
- Live logs: timestamped entries with semantic phase categories (setup/work/finish/git/cleanup), filterable by agent
- Footer: keyboard shortcuts and current filter state
Project Structure
pi-orq/
├── src/
│ ├── cli.tsx # CLI entry point
│ ├── app.tsx # Root component + screen flow
│ │
│ ├── git/ # Deterministic Git layer
│ │ ├── preflight.ts # Pre-run repository validation
│ │ ├── git-client.ts # Git CLI wrapper
│ │ ├── branch-namer.ts # Deterministic branch/worktree naming
│ │ ├── worktree-manager.ts # Worktree lifecycle
│ │ └── integration-merge.ts # Deterministic branch merge
│ │
│ ├── orchestrator/ # Orchestration engine
│ │ ├── index.ts # Main Orchestrator class
│ │ ├── run-manifest.ts # Run manifest (runId, branches, status)
│ │ ├── run-event-bus.ts # Full lifecycle event bus
│ │ ├── run-logger.ts # Dual-format persistent logger (JSONL + readable)
│ │ ├── agent-spawner.ts # Pi Agent session spawning per worktree
│ │ ├── agent-finalizer.ts # Commit, push, cleanup per agent
│ │ ├── integration-agent.ts # Final integration agent
│ │ ├── agents-md-generator.ts # Dynamic system prompt per agent
│ │ ├── branch-name-generator.ts # LLM-powered semantic branch naming (ReAct/LangChain.js)
│ │ ├── event-collector.ts # Pi SDK event normalization
│ │ ├── health-monitor.ts # Health check and auto-compaction
│ │ ├── cost-tracker.ts # Token and cost accumulation
│ │ ├── cost-guard.ts # Cost hard cap
│ │ ├── timeout-guard.ts # Timeout + steer + abort
│ │ ├── retry-handler.ts # Retry with exponential backoff
│ │ ├── task-decomposer.ts # 1 file = 1 task decomposition
│ │ ├── task-redistributor.ts # Orphaned task redistribution
│ │ └── wave-planner.ts # Wave planning
│ │
│ ├── merge/ # Consolidation and reporting
│ │ ├── diff-collector.ts # Diff collection per branch
│ │ ├── conflict-detector.ts # Overlap detection
│ │ ├── patch-applier.ts # Patch application (legacy)
│ │ └── report-generator.ts # REFACTOR_REPORT.md
│ │
│ ├── prompts/ # Prompt templates
│ │ ├── base-system.ts # Global guardrails
│ │ ├── refactor-task.ts # Refactoring prompts per wave
│ │ ├── integration-task.ts # Integration agent prompt
│ │ ├── compact-context.ts # Compaction prompts
│ │ └── reporting.ts # Synthesis prompts
│ │
│ ├── screens/ # Ink screens
│ │ ├── setup.tsx # API key management + model selection
│ │ ├── file-select.tsx # File selection
│ │ ├── confirm.tsx # Pre-execution confirmation
│ │ ├── dashboard.tsx # Real-time dashboard with Kanban + logs
│ │ └── report.tsx # Final Git-first report
│ │
│ ├── components/ # Componentes Ink
│ │ ├── kanban-board.tsx # Board TODO/DOING/DONE por fase do agente
│ │ ├── kanban-card.tsx # Card visual por agente com fase, status e ultimo contexto
│ │ ├── log-area.tsx # Logs recentes com filtro por agente e contexto inline
│ │ ├── cost-bar.tsx # Barra de custo
│ │ ├── tree-view.tsx # Arvore de arquivos
│ │ ├── file-filter.tsx # Filtro por extensao
│ │ ├── instance-selector.tsx # Seletor de instancias
│ │ ├── refactor-prompt.tsx # Input de prompt
│ │ ├── selection-summary.tsx # Sumario de selecao
│ │ ├── agent-panel.tsx # Painel legado, nao usado no dashboard atual
│ │ └── agent-panel-compact.tsx # Indicador legado, nao usado no dashboard atual
│ │
│ ├── hooks/
│ │ └── use-orchestrator.ts # React hook for reactive state
│ │
│ └── lib/ # Utilidades core
│ ├── types.ts # Tipos centrais do dominio
│ ├── config.ts # Persistencia local em `.pi-orq.json`
│ ├── model-factory.ts # Factory de modelo Pi
│ ├── openrouter.ts # Integracao OpenRouter
│ └── file-scanner.ts # Scan recursivo
│
├── package.json
├── tsconfig.json
├── ROADMAP.md # Detailed execution plan
└── PROBLEMS.md # Known problems and tech debtDomain Model
RunManifest
Each execution produces a manifest recording:
runId: unique run identifierbaseBranch/baseCommit: starting pointintegrationBranch/integrationWorktreePath: integration worktreeagentEntries[]: one entry per agent with branch, worktree, commit SHA, push status, cleanup status
The manifest is persisted to .pi-orq-worktrees/<runId>/manifest.json for post-run auditability.
AgentLifecyclePhase
Each agent passes through explicit operational phases:
pending → worktree_creating → worktree_ready → session_starting →
streaming → tool_running → finalizing → validating → committing →
pushing → cleaning_up → done | no_changes | errorTask Model
Each selected file becomes exactly one task (1 file = 1 task). The orchestrator's worker pool controls concurrency: it keeps up to instanceCount agents active at all times. When an agent finishes its session, the slot is freed and the next pending task is pulled from the queue immediately.
Kanban Phase Groups
The dashboard groups agents into 3 semantic columns:
| Column | Phases | Color | |--------|--------|-------| | TODO | pending, worktree_creating, worktree_ready, session_starting | Yellow | | DOING | streaming, tool_running | Cyan | | DONE | finalizing, validating, committing, pushing, cleaning_up, done, no_changes, error | Green |
Branch Lifecycle
After integration merge, all agent branches are automatically deleted. Only the integration branch (pi-orq/<runId>/integration) remains as the final artifact.
Deterministic Naming
Branch: pi-orq/<runId>/agent-<agentId>
Worktree: <repoRoot>/.pi-orq-worktrees/<runId>/agent-<agentId>
Integration Branch: pi-orq/<runId>/integration
Integration Worktree: <repoRoot>/.pi-orq-worktrees/<runId>/integrationLogging & Auditability
- Operacoes Git sao do orquestrador — agentes nao executam comandos git
- Isolamento por worktree — cada agente tem filesystem proprio
- Fail closed onde importa — repo invalido, detached HEAD e merge inconsistente bloqueiam a run; working tree suja gera warning e push indisponivel degrada para branch local
- Eventos explicitos — toda transicao gera evento para UI, logs e manifesto
- Branch como artefato — cada branch fica disponivel mesmo apos cleanup da worktree
- No-changes e valido — agentes sem mudancas terminam com estado explicito, sem falso sucesso
- Observabilidade persistente — a UI mostra a janela operacional recente, e a trilha completa da run fica salva em disco
| File | Format | Purpose |
|------|--------|---------|
| run.jsonl | JSONL | Machine-readable event stream with sequence numbers, elapsed times, and full context |
| run.log | Text | Human-readable log with elapsed timestamps, level, agent ID, phase, and compact context |
| summary.json | JSON | Structured run summary with cost, tokens, duration, and file paths |
| manifest.json | JSON | Complete run manifest with per-agent branches, commits, and push status |
Log timestamps use elapsed time from run start (+MM:SS.s) for easier correlation. The JSONL includes both ISO timestamps and elapsed milliseconds for programmatic analysis.
Architecture Principles
- Git operations belong to the orchestrator — agents do not execute git commands
- Worktree isolation — each agent has its own filesystem
- Fail closed — dirty repo, unavailable push, or inconsistent merge block the run
- Explicit events — every transition generates events for UI, logs, and manifest
- Branch as artifact — each branch remains available even after worktree cleanup
- No-changes is valid — agents with no modifications end with explicit state, not false success
- Key-only persistence — only the API key is globally saved; everything else is per-run
Observabilidade e Logs
O dashboard mostra a visao operacional recente da execucao: estado agregado, Kanban por fase, custo acumulado e logs filtraveis por agente.
Para auditoria da execucao principal, cada run tambem grava artefatos persistentes em:
<repoRoot>/.pi-orq-worktrees/<runId>/run.log— trilha legivel para debugging humano<repoRoot>/.pi-orq-worktrees/<runId>/run.jsonl— stream estruturado para analise programatica
Esses arquivos incluem timestamps, agentId, fase, nivel de log e contexto adicional quando disponivel. O preflight inicial e registrado antes da inicializacao do runId final, entao a trilha persistida da run final cobre principalmente a execucao orquestrada apos esse ponto.
Persistencia da Configuracao
No estado atual, a configuracao e salva localmente no diretorio corrente de execucao em .pi-orq.json.
apiKeye persistida de forma criptografadamodelIde persistido junto com a chave- a tela inicial tenta recarregar essa configuracao e revalidar automaticamente na proxima execucao
Se PI_ORQ_SECRET nao estiver definido, a criptografia usa um fallback de desenvolvimento. Para uso real, defina PI_ORQ_SECRET no ambiente.
Configuracao
| Parameter | Default | Description |
|-----------|---------|-------------|
| API key | — | OpenRouter API key (globally persisted to ~/.pi-orq/config.json) |
| Model | anthropic/claude-sonnet-4 | Model ID (per-run, not persisted) |
| Cost cap | $5.00 | Total run cost limit |
| Max instances | 8 | Maximum simultaneous agents |
| Timeout (no output) | 120s | Time without output before steer |
| Timeout (after steer) | 60s | Time after steer before abort |
| Max retries | 3 | Attempts per failed agent |
Development
# Install dependencies
npm install
# Dev with watch
npm run dev
# Build
npm run build
# Link locally
npm run linkSemantic Branch Naming (LangChain.js + ReAct)
The integration branch is named using an LLM via LangChain.js with the ReAct (Reasoning + Acting) pattern. Instead of generic pi-orq/<runId>/integration, the branch gets a descriptive name like pi-orq/<runId>/refactor-auth-middleware.
- Architecture: ReAct loop (Thought → Action → Observation) using
@langchain/openaiwith OpenRouter - Tool:
analyze_files— provides file list and refactoring context to the LLM - Fallback: deterministic name from file paths if LLM is unavailable
- Model: uses the same OpenRouter model configured for the run
- Max iterations: 3 (prevents runaway token costs)
The ReAct architecture is designed for future expansion — additional tools (git log analysis, codebase search, dependency analysis) can be plugged into the loop without changing the core structure.
See: src/orchestrator/branch-name-generator.ts, docs/langchain/ReAct-langchain-tec-guide.md
Commit Message Format
Agent commits use a descriptive format focused on what was changed:
refactor: update auth-middleware.ts, validation-utils.ts
- src/auth/auth-middleware.ts
- src/utils/validation-utils.ts
agent-id: 1
wave: 1
run-id: abc123The title describes the file changes. Agent and task metadata are in the footer, not the title.
Prompt Engineering
All prompts follow best practices from docs/general/prompt-engineering.md:
- Under 300 words of instruction per prompt
- XML tags for structured sections (
<task>,<constraints>,<files>) - Concrete steps instead of generic "think step by step"
- Sandwich method — critical rules at start and end
- No role prompting for accuracy — instructions over persona
- Static content at top for prompt caching compatibility
Related Documents
- ROADMAP.md — detailed execution plan with stories, dependencies, and criteria
- PROBLEMS.md — known problems, tech debt, and limitations
- docs/langchain/ReAct-langchain-tec-guide.md — ReAct pattern technical guide for LangChain.js
- docs/langchain/langchain-langgraph-production.md — LangChain.js production guide
- docs/general/prompt-engineering.md — Prompt engineering best practices 2025-2026
- docs/general/prompts-guide.md — System prompts guide for LLM automation
