Conversation
- New CLI: story <pr-or-branch> [--compare branch] [--output file]
- PR mode: fetch PR info, commits, files; LLM narrative + features + changelog
- Branch mode: commit history only (getBranchCommitHistory) for single branch
- Two-branch mode: --compare <branch> (name, owner/repo@branch, or tree URL);
prefer primary branch (URL) as newer ref; story from oldest to newest
- GitHub API: getPRFiles, getDefaultBranch, getBranchComparison,
getBranchCommitHistory, getBranchComparisonEitherDirection,
getBranchComparisonWithFallback; parseBranchSpec + normalizeCompareBranch
- Logging: initOutputLog({ prefix: 'story' }) → story-output.log, story-prompts.log
- buildCommitSummary: fix overlap when total <= maxCommits; add Removed to changelog prompts
- README: document story usage (PR, branch, --compare)
Made-with: Cursor
- tools/story/README.md: full docs, modes table, options, log files, WHYs - Main README: story section updated, link to tools/story/README.md - CHANGELOG: Added (2026-03) story tool with WHYs for design choices - JSDoc/WHY in story cli, index, run; github api/types; shared logger Made-with: Cursor
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…line fix - Gate submitReview on PRR_SUBMIT_REVIEW=true (set only for workflow_dispatch) - Server: add submit_review input and PRR_SUBMIT_REVIEW env - Client: inline server steps so job has runs-on (fix validator) - Dedup: reject GROUP lines that mix line numbers; re-split by line to keep valid same-line merges; add debug log when re-splitting Made-with: Cursor
- run-prr-client: use vars.PRR_REVIEWER_LOGIN in job if (env not available there) - Add lint-workflows.yml: actionlint on push/PR for .github/workflows - npm run lint:workflows for local audit (requires actionlint in PATH) Made-with: Cursor
There was a problem hiding this comment.
Pull request overview
This PR introduces a new CLI tool called story that generates narratives, feature catalogs, and changelogs (Added/Changed/Fixed/Removed) from GitHub PRs or branches using an LLM. It supports three modes: PR analysis (using title/body + commits + files), single-branch analysis (commit history only), and two-branch comparison (--compare). It also includes a bug fix for null-safe access in parseMarkdownReviewIssues and adds prefix support to the shared logger.
Changes:
- Adds the
storytool with CLI parsing, runner logic, and documentation, reusing existingGitHubAPIandLLMClientinfrastructure from theprrtool. - Extends
GitHubAPIwith new methods (getPRFiles,getBranchCommitHistory,getBranchComparison,getBranchComparisonEitherDirection, etc.) and addsparseBranchSpec/normalizeCompareBranchtotypes.ts. - Adds logger prefix support so
storywrites tostory-output.log/story-prompts.loginstead of overwritingprr's log files.
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
tsconfig.json |
Adds tools/story/**/* to TypeScript compilation includes |
tools/story/run.ts |
Main story runner: fetches data, builds prompts, calls LLM |
tools/story/index.ts |
Entry point: CLI wiring, config load, output handling |
tools/story/cli.ts |
CLI definition and argument parsing for the story tool |
tools/story/README.md |
Documentation for the story tool |
tools/prr/github/types.ts |
Adds parseBranchSpec and normalizeCompareBranch parsing functions |
tools/prr/github/api.ts |
Adds GitHub API methods for branch/PR data; fixes null-safe access in parseMarkdownReviewIssues |
shared/logger.ts |
Adds prefix support to initOutputLog for tool-specific log files |
package.json |
Registers story as a CLI binary |
README.md |
Adds story tool documentation to the main README |
CHANGELOG.md |
Documents the story tool addition |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| export function parseBranchSpec(input: string): { owner: string; repo: string; branch: string } | null { | ||
| const trimmed = input.trim(); | ||
| const shorthandAt = trimmed.match(/^([^\/]+)\/([^@:]+)@([^@]+)$/); | ||
| if (shorthandAt) { | ||
| return { owner: shorthandAt[1], repo: shorthandAt[2], branch: shorthandAt[3] }; | ||
| } | ||
| const shorthandColon = trimmed.match(/^([^\/]+)\/([^@:]+):([^@:]+)$/); | ||
| if (shorthandColon) { | ||
| return { owner: shorthandColon[1], repo: shorthandColon[2], branch: shorthandColon[3] }; | ||
| } | ||
| const treeMatch = trimmed.match(/(?:https?:\/\/)?github\.com\/([^\/]+)\/([^\/]+)\/tree\/(.+?)(?:[?#]|$)/); | ||
| if (treeMatch) { | ||
| const branch = treeMatch[3].replace(/\/+$/, '').trim(); | ||
| if (branch) { | ||
| return { owner: treeMatch[1], repo: treeMatch[2], branch }; | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| /** | ||
| * Normalize a --compare value to a branch name for the GitHub API. | ||
| * Accepts: plain branch name (e.g. v1-develop), owner/repo@branch, or tree URL. | ||
| * When currentOwner/currentRepo are set, parsed repo must match (same-repo comparison only). | ||
| * WHY: Compare API expects ref names; passing a tree URL as ref causes 404. We parse and pass only the branch name. | ||
| */ | ||
| export function normalizeCompareBranch( | ||
| value: string, | ||
| currentOwner?: string, | ||
| currentRepo?: string | ||
| ): string { | ||
| const trimmed = value.trim(); | ||
| const parsed = parseBranchSpec(trimmed); | ||
| if (parsed) { | ||
| if (currentOwner != null && currentRepo != null && (parsed.owner !== currentOwner || parsed.repo !== currentRepo)) { | ||
| throw new Error( | ||
| `--compare repo (${parsed.owner}/${parsed.repo}) does not match branch repo (${currentOwner}/${currentRepo}). Use the same repository.` | ||
| ); | ||
| } | ||
| return parsed.branch; | ||
| } | ||
| if (!/github\.com|@|^[^\/]+\/[^\/]+:/.test(trimmed)) { | ||
| return trimmed; | ||
| } | ||
| throw new Error( | ||
| `Invalid --compare value: "${value}". Use a branch name (e.g. v1-develop), owner/repo@branch, or a tree URL.` | ||
| ); | ||
| } |
There was a problem hiding this comment.
No tests were added for the new parseBranchSpec and normalizeCompareBranch functions. Given that parseMarkdownReviewIssues (exported from a nearby module) has tests in tests/github-api-parser.test.ts, these new parsing functions — which contain non-trivial regex logic and multiple input format handling — should also have test coverage for edge cases like branch names with /, tree URLs with query/fragments, mismatched repos in normalizeCompareBranch, and plain branch name pass-through.
Made-with: Cursor
Made-with: Cursor
- Workflows: add Configure Git step (github-actions[bot] name/email) before Run PRR - ensureGitIdentity() in git-merge: set local user.name/email in repo before merge when unset; use bot identity in GITHUB_ACTIONS else PRR/prr@local for local runs Made-with: Cursor
- On setup early exit: run error cleanup so user sees 'Exit: Error' and details - Process exits with code 1 when exitReason is error/init_failed/merge_conflicts/sync_failed - Push: always use one-shot auth URL when githubToken provided (fix CI 'could not read Password') Made-with: Cursor
- git-push: when using auth URL, add -c credential.helper= and GIT_TERMINAL_PROMPT=0 so git uses URL credentials only (fix CI 'could not read Password') - api: handle 422/404 from check-runs and combined-status APIs (assume no checks/success) - workflows: comment that output.log/prompts.log are uploaded as artifacts Made-with: Cursor
… for other repos - git-push: build auth URL as https://x-access-token:TOKEN@... (GitHub convention, fixes CI push) - docs: INSTALL-WORKFLOW-OTHER-REPO.md for developers adding PRR workflow to their repo Made-with: Cursor
…ame-line - utils: single-issue prompt adds explicit 'ONLY file' line when one allowed path (Cycle 21) - llm/client: batch verify BAD example for ## Fix N format; parser accepts ## Fix N: YES|NO (Cycle 22) - issue-analysis: dedup prompt reinforces same-line check before replying - AUDIT-CYCLES: add Cycle 21 (output.log), Cycle 22 (prompts.log) Made-with: Cursor
- workflows: contents: write so GITHUB_TOKEN can push (fix 403) - base-merge: use shared push() with githubToken for merge-commit push (fix 'could not read Password' in CI) - run-setup-phase: pass config.githubToken to checkAndMergeBaseBranch - AUDIT-CYCLES: add Cycle 23 (prr-logs-5 #5) - reporter: when GITHUB_ACTIONS=true, print tip to share logs via gh run download Made-with: Cursor
Iteration 1 prr-fix:prrc_kwdoq_yy5c6txlbj
Iteration 1 prr-fix:prrc_kwdoq_yy5c6txlbq
Iteration 1 prr-fix:prrc_kwdoq_yy5c6txlbz
- run-prr-client: optional pr_number; add branch input, resolve via REST API (head=owner:branch for same-repo and fork PRs) - workflows: add pull-requests: write so PR review submit works (fix 403) - client: pass PRR_PR_NUMBER into Run PRR step; reporter uses it in Actions tip so artifact name shows prr-logs-5 not prr-logs-<PR> Made-with: Cursor
- workflow: require PR number only, remove branch input and resolve step - AUDIT-CYCLES: add Cycle 25 (prompts.log eliza#6562), record cycles 25 - issue-analysis: dedup prompt add same-line verification step before reply - push-iteration-loop: clearer exit when 0 issues and nothing to commit Made-with: Cursor
|
@coderabbitai review |
Iteration 4 prr-fix:prrc_kwdoq_yy5c6txlbj
Changes: - README.md: The story section (lines 209-231) is inserted inside the prr `bash` code bloc...
Avoid duplicate 'PRR run summary' on PR (review + comment). Made-with: Cursor
PRR: - Inject catalog context in verifier (batchCheckIssuesExist) and fixer prompts when outdated model-id advice matches (prevents wrong gpt-5-mini → gpt-4o-mini flips) - Extend parseModelRenameAdvice for CodeRabbit typo-heading + later use/recommended - Dismiss merge-closing meta comments in assessSolvability (0a3b) - pathsWrittenByRunner + reconcile note when runner wrote but git is clean - gitRecoveredVerificationCount for prune log context; trim auto-heal debug noise Pill: - Align chunk budget with shared CHARS_PER_TOKEN; enforce max chunk chars; docs Tests/docs: - outdated-model-advice tests; eval benchmarks and runner; scenarios & test-utils - split-exec / split-rewrite-plan git operation tests - CHANGELOG, AUDIT-CYCLES (cycle 63), MODELS, AGENTS, pill README CI & tooling: - GitHub workflows for test and eval; tools/eval; package.json scripts Made-with: Cursor
…t and pill docs Session model skip (PRR_SESSION_MODEL_SKIP_FAILURES) and diminishing-returns warning (PRR_DIMINISHING_RETURNS_ITERATIONS). Canonical path-unresolved vs missing-file via path-utils + solvability; legacy state normalization. scanCommittedFixes in-process cache (workdir/branch/HEAD); recovery skips redundant markVerified. Clone fetches additionalBranches on preserve path with optional ref verification (split-exec disables). Rate limit restores full concurrency after 429 window. State overlap cleanup on load; markVerified short-circuit; dirty/unmergeable PR warn without --merge-base. pushWithRetry conflict file warnings; runner detect debug; empty LLM body ERROR + PROMPTLOG_EMPTY_BODY; commit subject truncation; catalog/config warnings. Pill chunking and audit caps; nested conflict parsing tests. Documentation: CHANGELOG, DEVELOPMENT pill triage, README env section, AGENTS pill note, ROADMAP follow-ups. Note: pill-output.md is gitignored and was not committed. Made-with: Cursor
- PRR_ELIZACLOUD_EXTRA_SKIP_MODELS: merge extra skip ids with built-in list - recoverVerificationState: markVerified with PRR_GIT_RECOVERY_VERIFIED_MARKER - runFinalAudit: warn on verified∩dismissed overlap - determineScope: fallback to first path segment (e.g. src) vs misc - checkForConflicts: document in-progress-merge limitation; fetch timeout hygiene - AGENTS: Path resolution rules subsection; extra skip env in model blurb - README: operator env quick-reference table; .env.example + CHANGELOG - DEVELOPMENT: clarify generic src/ in example JSON - rotation.ts: mention PRR_ELIZACLOUD_EXTRA_SKIP_MODELS in skip warning Made-with: Cursor
- run-orchestrator: push dismissal-comment commit via git-push.ts auth (credential.helper / extraheader) instead of simple-git push() - cleanup-mode: same for cleanup push — avoids CI 'could not read Password' Made-with: Cursor
Git treats helper values starting with ! as shell-command helpers; credential.helper=! broke CI with 'get: not found' and still prompted. Made-with: Cursor
- model-context-limits: 48k char cap for qwen-3-14b variants; fuzzy model id match; 24576 token table; tighter char estimate for <=32k models - client: detect gateway-wrapped context errors; no 500 backoff; call lowerModelMaxPromptChars for next iteration Made-with: Cursor
- model-context-limits: ELIZACLOUD_MODEL_CONTEXT (maxContextTokens per model), aliases/patterns, unknown default; derive fix char caps from spec - client: on ElizaCloud server-class errors log expectedMaxContextTokens, expectedMaxFixPromptChars, request char totals, canonical id / unknown flag; same on retry backoff and context-overflow path - docs/MODELS.md + re-exports from tools/prr/llm/model-context-limits Made-with: Cursor
- Push: embed githubToken in push URL when origin is HTTPS (git-push-auth-url) - Pill: tool-repo scope filter (tool-repo-scope.ts) + docs - PRR: latent merge probe, fetch/branch safety, state/catalog/conflict UX - Docs: CHANGELOG [Unreleased], DEVELOPMENT, README, AGENTS, ROADMAP - Tests: git-push-auth-url, latent merge, fetch timeout, branch ref, etc. Made-with: Cursor
…lper - LLMClient.complete: reject when system+user > getMaxElizacloudLlmCompleteInputChars; skip pointless 5xx retries; debug adds expectedMaxTotalInputChars - model-context-limits: ELIZACLOUD_LLM_COMPLETE_INPUT_OVERHEAD_CHARS + tests - github: shared github-api-errors.ts, api.ts refactor, github-api-errors.test.ts - git: git-lock-files / git-conflict-resolve / has-conflict-markers tests - docs: CHANGELOG, AUDIT-CYCLES, CONFLICT-RESOLUTION; final-cleanup tweak Made-with: Cursor
…tHubApiFailure with 404 Made-with: Cursor
- finalAudit: effectiveMaxContextChars from getMaxElizacloudLlmCompleteInputChars(auditModel) (min with 90k) so batches match LLMClient.complete; structureSlack for markdown overhead - CHANGELOG: Final audit (ElizaCloud) entry Made-with: Cursor
GitHub installation tokens (ghs_*) and fine-grained PATs require x-access-token:<token> (username:password); token-as-username-only causes git to prompt for a password in CI. Classic PATs also accept this format, so it works universally. Made-with: Cursor
…batch estimates - buildFinalAuditBatchPrompt + binary search max snippet length under hardCap - Larger structureSlack and ISSUE_HEADER_APPROX so planned batches match markup - CHANGELOG: truncation fallback when batch still exceeds model cap Made-with: Cursor
- shared/prr-runtime-meta: package version, PRR_GIT_SHA/PRR_SOURCE_COMMIT, git rev-parse only when .git exists in prr root; shouldSuggestPrrGitShaInCi - index: first tee'd lines after initOutputLog show PRR x.y.z (sha) - README, .env.example, CHANGELOG; tests/prr-runtime-meta.test.ts Made-with: Cursor
- Add npm run build (tsc); workflows use it for emitting dist/; document in AGENTS.md - PRR_ELIZACLOUD_SERVER_ERROR_RETRIES (0–15); default 4 inner retries when CI=true - Clearer startup hint when prr subfolder has no .git (vs host repo) - ElizaCloud: log estimated input tokens + default max-out vs context; cap max_completion_tokens so estimated input + reserve fits maxContextTokens (fixes opaque 500s on qwen-3-14b-sized windows) - Tests: elizacloud-server-error-retries, model-context-limits estimates Made-with: Cursor
…ight getMaxElizacloudLlmCompleteInputChars now min(legacy fix+14k, unified budget) for ≤32k windows: floor((maxContext - max_completion - reserve) * 1.6) for system+user. Legacy double-counted tokens so ~32k chars passed while Qwen still 500'd; batch check splits smaller. Batch-2-sized prompts still 500ing are likely gateway/model, not this char ceiling. Made-with: Cursor
- getElizacloudGatewayFallbackModels: ordered chain from env PRR_ELIZACLOUD_GATEWAY_FALLBACK_MODELS (off disables) or defaults; respects skip list + INCLUDE_MODELS - LLMClient.complete: on 2 consecutive server-class errors, switch request model and retry without burning backoff slot (attempt504--) - Log prompts with actual requestModel after fallback; import chalk - Tests, README, .env.example, CHANGELOG Made-with: Cursor
- Final audit: skip adversarial LLM for (PR comment), empty paths, and path fragments (shouldSkipFinalAuditLlmForPath); ElizaCloud batching/truncation and debug noise cap in LLMClient - prompts.log: requestId on PROMPT/RESPONSE/ERROR for interleaved pairing; debugPromptError includes requestId in debug output; pill-prompts.log parity - llm-api: line-anchored or head excerpt when file exceeds size/line caps - reporter: clarify final-audit re-queue count vs Remaining when they differ - thread-replies: drop chronic-failure from reply-eligible set; align docs; formatNumber on 422 stop message - issue-analysis: LLM dedup via system prompt; GROUP+NONE comment - fix-verification / client: verify window and truncation improvements - pill: extractJsonLenient retries, orchestrator wiring; path-utils tests - Docs: AGENTS, THREAD-REPLIES, CHANGELOG, AUDIT-CYCLES (cycles 67–69), DEVELOPMENT Made-with: Cursor
… cache - Filter non-review issue bodies before markdown parse; collapse duplicate ic-* rows per author/path (Jaccard + line proximity) before snippet work. - stripSeverityFraming + wordSetJaccard for symbol/similarity; llmDedup for two cross-author same-symbol items; crossFileDedup when ≥5 survivors; persist dedupCache with schema dedup-v2. - Path resolution: stripGitDiffPathPrefix in path-utils and solvability; .mts/.cts extension variants; related tests. - Pill: optional PILL_AUDIT_CHUNK_CONCURRENCY for parallel audit chunks. - Logger: include phase in empty prompts.log body warning when present. - Document in CHANGELOG, README, DEVELOPMENT, AGENTS, ROADMAP; WHY comments. Made-with: Cursor
…able - Add alibaba/qwen-3-14b and Qwen/Qwen3-14B to ELIZACLOUD_SKIP_MODEL_IDS with zero-fix-rate reasons (small context, weak verify, audit churn). Re-enable via PRR_ELIZACLOUD_INCLUDE_MODELS. - openAiChatCompletionContentToString: handle array-shaped message.content. - console.warn when ElizaCloud returns empty body after success (pairs with prompts.log ERROR). - docs/MODELS.md: full skip snapshot table, last reviewed, override habits. - CHANGELOG, AGENTS include example; tests/openai-chat-content.test.ts. Made-with: Cursor
…erpts - getFullFileForAudit(workdir, path, line?, body?): line-centered excerpt when file exceeds cap; keyword anchor from comment; clearer no-anchor fallback. - runFinalAudit passes path+line+body into full-file callback. - finalAudit: rule 10, [n] UNCERTAIN response, finalAuditSnippetLooksTruncatedOrExcerpt demotion when UNFIXED lacks line+code cite or hedges visibility on partial snippets. - Tests for snippet helper and getFullFileForAudit; AGENTS + CHANGELOG. Made-with: Cursor
- Add bot-author-normalize.ts; GitHubAPI.normalizeBotName delegates to it. - Dedup buckets and output authors use same labels; other issue comments normalized when applicable. - debug() includes removedIdsSample (up to 20) when merges occur. - Tests; ROADMAP section removed (done); CHANGELOG, AGENTS, DEVELOPMENT. Made-with: Cursor
- resolveTrackedPathWithPrFiles ties ambiguous basenames to the unique PR diff path; findUnresolvedIssues and checkEmptyIssues repopulate use it for resolvedPath (avoids wrong-file skips and BUG DETECTED repopulate loops). - No-change ALREADY_FIXED dismisses full LLM dedup clusters via getDuplicateClusterCommentIds; analysis cache stores changedFiles for pre-iteration checks. - AAR: suppress boilerplate / autoVerifiedFrom duplicate lines with honest counts. - Final audit: uncertain-path handling (final-audit-uncertain, git-path-at-head), analysis wiring; optional PRR_STRICT_FINAL_AUDIT_UNCERTAIN in .env.example. - Thread replies: PRR_THREAD_REPLY_INCLUDE_CHRONIC_FAILURE; docs and tests. - Lessons: path forbid in retrieve, prune behavior; small API/resolver/index hooks. - CHANGELOG, README, DEVELOPMENT, AGENTS, ROADMAP; AUDIT-CYCLES cycle 70. - Tests: resolve-tracked-path-pr-files, duplicate-cluster-ids, and related. Made-with: Cursor
- recovery trySingleIssueFix: add getRenameTargetPath and issueRequestsTests __tests__/ co-located hint (mirror getAllowedPathsForIssues). - REPO_TOP_LEVEL: e2e, playwright, cypress, fixtures, integration, wdio so isPathAllowedForFix does not strip common test trees. - path-utils.test.ts, CHANGELOG [Unreleased], ROADMAP single-issue status. Made-with: Cursor
- printFinalSummary: show Final audit re-queued count after fixed/dismissed; single auditOverridesThisRun binding for follow-up messages. - DEVELOPMENT: state repair quick ref; clarify final-audit summary placement. - CHANGELOG [Unreleased]. (pill-output.md triage updated locally; file gitignored.) Made-with: Cursor
- PRR_SESSION_MODEL_SKIP_RESET_AFTER_FIX_ITERATIONS: clear rotationSession skippedModelKeys every N fix iterations (rotation.ts, push-iteration-loop). - PRR_THINKING_BUDGET clamp at 500k with warn (config load typo guard). - docs/MODELS.md: document session reset with skip table maintenance. - README, DEVELOPMENT, AGENTS (no git-hooks in tree), .env.example, CHANGELOG. - tests/session-model-skip.test.ts for periodic reset. Made-with: Cursor
…ed README - validateAndFilterModels: warn when ≤3 ElizaCloud models remain after skip+API. - README troubleshooting: overlap cleanup vs delete state / --clean-state. - shared/README: constants skip list, MODELS link, thinking cap, no git-hooks. - CHANGELOG [Unreleased]. (pill-output.md statuses refreshed locally; file gitignored.) Made-with: Cursor
… model Connect historical log findings to current state/path/rotation/summary behavior; state explicit residual risk and operator cross-checks. Made-with: Cursor
Split large modules along natural seams with backward-compatible re-exports so behavior and import paths stay stable for existing callers. LLM: Extract verification-heuristics, provider-probes, and error-helpers from client.ts; LLMClient stays in client.ts and re-exports helpers for a stable surface (rotation, split-plan, tests). Issue analysis: Add snippet-helpers, snippets, dedup, and context modules; findUnresolvedIssues remains the orchestrator in issue-analysis.ts with barrel re-exports for resolver-proc and tests. Shared: Add timing.ts and token-tracking.ts (re-exported from logger.ts). Split constants into shared/constants/* with index barrel and constants.ts shim. Run pill via tools/pill/after-close-logs.ts after closeOutputLog from prr, split-exec, split-plan, and story so shared/ does not import tools/pill. Resolver: resolver-proc.ts is re-export-only; implement post-push wait and checkForNewBotReviews in workflow/bot-wait.ts and executeBailOut in workflow/bailout.ts. Other: Remove unused VerificationResult from analyzer/types (state keeps the active type). Document layout, WHYs, and follow-ups in CHANGELOG, DEVELOPMENT, README, AGENTS, and docs/ROADMAP. Made-with: Cursor
- git-clone-core: reset remote.origin fetch branches via set-branches (avoid stale accumulated names); keep verifyAdditionalRemoteRefs behavior aligned with split-exec only needing target_branch vs source_branch. - split-exec: fetch only target_branch when it differs from source_branch; parse and rewrite-plan updates so New PR branch titles do not break clone/fetch. - split-plan / split-rewrite-plan: substantial run.ts improvements. - vitest.config.ts: small config tweak. - AGENTS.md: minor edit. - Add tools/pill/apply-pill-status-triage.mjs to backfill pill-output.md Status lines (pill-output.md stays gitignored). Made-with: Cursor
No description provided.