- Register /ralpi-run, /ralpi-plan, /ralpi-resume, /ralpi-reset as
separate Pi commands (dash namespace). /ralpi kept as back-compat
dispatcher.
- /ralpi-resume now reuses mode + loop options from loop-active.json
so interrupted loops resume non-interactively (only prompts when no
snapshot exists).
- Add finalizeCommittedWorktrees in worktree.ts; resumeLoop calls it at
start to merge already-completed task branches into main (the classic
interrupted-between-commit-and-merge crash window), leaving dirty/
conflicted worktrees for re-run.
- Switch process.cwd() -> ctx.cwd in all command handlers.
getCommitRangeDiff and getLatestCommitDiff had maxBuffer set to 1MB.
When a task produced a larger diff (common for 10+ minute tasks),
execSync threw, the catch block returned null, and the review loop
broke immediately with no message — reviews were silently skipped for
larger tasks while smaller tasks reviewed fine.
- Increase maxBuffer to 10MB in both functions (the review prompt
builder already truncates to MAX_DIFF_BYTES = 50KB before sending
to the model, so the full diff in memory is fine)
- Add a diagnostic sendChatMessage when the review loop is skipped
(baseRef undefined or no diff), so silent skips are visible
Previous flow reviewed uncommitted changes, so when a task agent
self-committed its work the review was silently skipped (no uncommitted
changes → review loop body never entered). This caused reviews to fire
inconsistently across tasks.
New review-gated flow (when autoReview is on):
1. Execute task
2. Ensure committed — commit session fallback when the agent didn't
self-commit (handles both self-commit and no-commit agents)
3. Review the COMPLETE task diff (baseRef..HEAD) captured before
execution, so the reviewer sees all commits not just the latest
4. On fail → re-execute with feedback → commit → re-review (same
baseRef, so reviewer sees complete state including fixes)
5. On pass → merge worktree (all changes already committed)
Commit is now mandated when autoReview is on (autoCommit forced true,
not asked at startup). autoCommit only asked when autoReview is off.
Add captureGitHead + getCommitRangeDiff helpers to utils.ts. Switch
review prompt from buildReviewPromptUncommitted to buildReviewPrompt
(reviewing committed changes, not uncommitted).
- Review now runs whenever autoReview is enabled (not only when both
autoCommit && autoReview). On fail, the task re-executes with review
feedback injected and loops until pass or maxReviewRetries exhausted.
- Commit after a passing review is gated by autoCommit; review-only mode
leaves changes uncommitted for manual inspection.
- Remove legacy post-commit review path and unused imports
(buildReviewPrompt, getLatestCommitDiff).
- Reorder selectLoopOptions: ask autoReview first, then saveReviews,
then autoCommit (reworded to 'commit after a passing review' when
review is enabled).
- Update types.ts doc comments and README to reflect new semantics.
Add reattemptMerge/abortMerge/completeMerge/hasMergeConflicts helpers to
worktree.ts. When a worktree merge conflicts, executeTask now defers to
batch-level resolution instead of immediately marking the task failed.
After all tasks in a batch finish, resolveConflictsSession re-attempts the
merge to recreate the conflict state, spawns an agent session with
buildConflictResolutionPrompt to resolve conflict markers and commit, then
verifies completion. This keeps parallel task slots unblocked — conflicts
are resolved sequentially at the batch boundary.
Review text was truncated to 500 chars in the chat message body with no
way to access the full content — once a review exceeded that limit it was
lost from the UI. Now the full review body is rendered in the expanded
(Ctrl+O) view like the implementation tool-call tree, and can optionally
be persisted to disk per-loop.
Changes:
- Add saveReviews config flag + reviewsDir path option
- Add loop-start prompt to opt into saving reviews to disk when
auto-review is enabled (skipped when explicitly set in YAML)
- Pass full reviewText via message details instead of inlining a slice
- Extend ralpi-progress renderer to show full review body when expanded,
dim hint to expand when collapsed
- Add saveReviewToFile() writing to .ralpi/reviews/<prdKey>/<taskId>.md,
mirroring the per-loop reflections layout so many loops don't collide
ralpi's runAgentSession was letting createAgentSession create a fresh
ModelRuntime from models.json only. This excluded extension-registered
providers like neuralwatt, whose streamSimple wrapper handles:
- 429 rate-limit header parsing (concurrent/TPM/admission/RPM)
- Rate-limit error normalization for Pi's retry logic
- Context-overflow error normalization
Without the wrapper, neuralwatt rate-limit and context-overflow errors
surfaced as raw unrecoverable errors instead of being retried by Pi's
built-in retry. Now passes ctx.modelRegistry.runtime (the underlying
ModelRuntime) through to createAgentSession.
- Cap commit diffs in review/commit prompts at 50KB to prevent
context window overflow on follow-up sessions
- Skip skills catalog (noSkills) in commit/review follow-up sessions
for leaner context
- Wire Pi's SettingsManager into runAgentSession so Pi's built-in
retry (exponential backoff, provider retry) applies to ralpi
sessions — removes ralpi's duplicate manual retry loop
- Remove maxRetries/retryDelayMs from ralpi config; rely on Pi's
retry.* settings (with manual override support)
- Remove retries field from progress.json and incrementRetry() from
ProgressTracker
- Add model failover to follow-up sessions (commit/review cycle
through the model pool on connection errors)
- Namespace reflection files by PRD key under
.ralpi/reflections/<prdKey>/ so task sets don't overwrite each
other
- Skip loop-startup prompts for config fields explicitly set in YAML
- Remove (default) annotations from loop options prompts
- Default commitTimeoutMs/reviewTimeoutMs to 0 (inherit Pi defaults)
- Persist loop-active state for widget re-instantiation after session reload
- Add YAML task file parsing and update support via yaml library
- Auto-update PRD source file checkboxes on task status changes
- Add batchRender callback for real-time parallel widget animation
- Normalize tabs-to-spaces indentation across source files
- Use padStart(2, '0') for ID formatting instead of hardcoded prefix
- Enable parallel execution for single-task DAG batches
- DAG-based task execution with dependency resolution
- Persistent progress tracking in .ralph/progress.json
- Reflection system for cross-task context
- Support for Fio README, checkbox, and YAML formats
- Retry with exponential backoff
- Parallel batch execution