pullfrog 0.1.42 → 0.1.44
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/cli.mjs +111 -300
- package/dist/index.js +110 -299
- package/dist/internal.js +59 -248
- package/dist/modes.d.ts +0 -1
- package/dist/toolState.d.ts +1 -0
- package/package.json +1 -1
package/dist/internal.js
CHANGED
|
@@ -635,32 +635,27 @@ var REVIEWER_AGENT_NAME = "reviewfrog";
|
|
|
635
635
|
// modes.ts
|
|
636
636
|
var PR_SUMMARY_FORMAT = `### Default format
|
|
637
637
|
|
|
638
|
-
The body has at most three parts in this
|
|
638
|
+
The body has at most three parts, in this order:
|
|
639
639
|
|
|
640
|
-
1. **Reviewed changes preamble** \u2014
|
|
641
|
-
2. **Cross-cutting issue sections** (zero or more) \u2014 one \`###
|
|
642
|
-
3. **\`### \u2139\uFE0F Nitpicks\`** at the very bottom
|
|
640
|
+
1. **Reviewed changes preamble** \u2014 a bolded \`**Reviewed changes**\` lead-in with one sentence on what was reviewed in this run (for \`IncrementalReview\`: what changed since the prior pullfrog review), then a bullet list of the substantive changes \u2014 short bolded title, one sentence each. A reviewer should understand the full reviewed scope from this list alone. Close the preamble with the metadata comment below.
|
|
641
|
+
2. **Cross-cutting issue sections** (zero or more) \u2014 one \`### {emoji} {what's wrong, not what to do}\` heading per concern.
|
|
642
|
+
3. **\`### \u2139\uFE0F Nitpicks\`** at the very bottom, if any \u2014 a flat bullet list, no technical-details block.
|
|
643
643
|
|
|
644
|
-
Inline
|
|
644
|
+
**Inline vs. body.** Concerns that anchor to a specific line go inline (the \`comments\` parameter), even when their implications are broad. Body \`### \` sections are reserved for concerns that have **no line to anchor to** \u2014 *absence* (something the diff should have done but didn't), *sequencing* (rollout / deletion / migration order), *design decisions only the human can make*, or *scope questions the diff raises but doesn't address*. With no non-anchorable concerns, the body is just the preamble + metadata.
|
|
645
645
|
|
|
646
|
-
|
|
646
|
+
**Severity emoji** on every \`### \` heading, and nowhere else: \u{1F6A8} critical (blocks merge \u2014 data loss, security, broken core flow) \xB7 \u26A0\uFE0F important (must address before merging) \xB7 \u2139\uFE0F informational (mergeable as-is).
|
|
647
647
|
|
|
648
|
-
|
|
648
|
+
**Blank line between every block-level element.** GitHub's markdown parser requires one before and after HTML tags (\`<details>\`, \`<summary>\`, \`<sub>\`, \`<br/>\`) \u2014 without it GitHub treats what follows as a continuation of the HTML block and renders your markdown as literal text. This is a parser quirk, not a style preference, and it permanently breaks the posted review.
|
|
649
649
|
|
|
650
|
-
|
|
651
|
-
**Reviewed changes** \u2014 one sentence on what was reviewed in this run. For Review (initial), this is what the PR does and why. For IncrementalReview, this is what changed since the prior pullfrog review. Focus on intent, not mechanics.
|
|
650
|
+
## Metadata comment
|
|
652
651
|
|
|
653
|
-
|
|
652
|
+
Fill every field from the \`checkout_pr\` response \u2014 never count files or commits by hand. For \`IncrementalReview\`, fill \`Prior pullfrog review\` from \`list_pull_request_reviews\`.
|
|
654
653
|
|
|
654
|
+
\`\`\`
|
|
655
655
|
<!--
|
|
656
|
-
Pullfrog review metadata
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
{head_sha_short}; if new commits have landed on {head_ref} since this review
|
|
660
|
-
was submitted, treat any specific bug, file, or line callout as POTENTIALLY
|
|
661
|
-
STALE \u2014 re-diff against {head_sha_short} (or trigger a fresh review) and
|
|
662
|
-
factor commits past {head_sha_short} into your understanding of the current
|
|
663
|
-
state before acting on findings.
|
|
656
|
+
Pullfrog review metadata. These findings were written against {head_sha_short};
|
|
657
|
+
if commits have landed on {head_ref} since, treat every specific bug, file, or
|
|
658
|
+
line callout as POTENTIALLY STALE and re-diff before acting on it.
|
|
664
659
|
|
|
665
660
|
- Mode: Review (initial) or IncrementalReview (delta against prior pullfrog review)
|
|
666
661
|
- Files reviewed: {file_count}
|
|
@@ -669,111 +664,36 @@ state before acting on findings.
|
|
|
669
664
|
- Head: {head_ref} ({head_sha_short})
|
|
670
665
|
- Reviewed commits:
|
|
671
666
|
- {sha_short} \u2014 {commit_subject}
|
|
672
|
-
- ...
|
|
673
667
|
- Prior pullfrog review: none or {prior_sha_short} ({prior_review_html_url})
|
|
674
|
-
- Submitted at: {iso_timestamp}
|
|
675
668
|
-->
|
|
676
669
|
\`\`\`
|
|
677
670
|
|
|
678
|
-
|
|
671
|
+
## Technical details
|
|
679
672
|
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
For each cross-cutting concern, one \`### \` section. Use this exact shape:
|
|
673
|
+
Every body \`### \` section carries one; an inline comment carries one when its fix is non-trivial or spans files. The visible part above it states the PROBLEM in 2-3 sentences \u2014 what's broken and what the blast radius is. Asks, fixes, and open questions live inside the block, which a downstream fix-agent pulls down as its brief, so \`file:line\` refs and identifier density belong here.
|
|
683
674
|
|
|
684
675
|
\`\`\`
|
|
685
|
-
### {emoji} {short, descriptive title \u2014 what's wrong, not what to do}
|
|
686
|
-
|
|
687
|
-
{Human-readable problem write-up. Describes the PROBLEM only \u2014 what's broken, what the symptom is, what the blast radius is. NO asks, NO suggested fixes, NO "the right thing to do is...". Asks and fixes live in the technical-details block below; the visible part is for the human to *understand* the problem, not to implement it.}
|
|
688
|
-
|
|
689
676
|
<details><summary>Technical details</summary>
|
|
690
677
|
|
|
691
678
|
\\\`\\\`\\\`\\\`markdown
|
|
692
|
-
# {title
|
|
679
|
+
# {title}
|
|
693
680
|
|
|
694
681
|
## Affected sites
|
|
695
682
|
- {file path:line} \u2014 {what's wrong there}
|
|
696
|
-
- ...
|
|
697
683
|
|
|
698
684
|
## Required outcome
|
|
699
685
|
- {what the fix needs to achieve, not how to achieve it}
|
|
700
|
-
- ...
|
|
701
686
|
|
|
702
687
|
## Suggested approach (optional)
|
|
703
|
-
{When the fix shape is non-obvious, sketch one or more reasonable directions. Skip when the outcome alone makes the fix obvious.}
|
|
704
|
-
|
|
705
688
|
## Open questions for the human (optional)
|
|
706
|
-
- {Any decision an implementing agent shouldn't make unilaterally \u2014 pricing thresholds, breaking-change policy, naming, scope of follow-up.}
|
|
707
689
|
\\\`\\\`\\\`\\\`
|
|
708
690
|
|
|
709
691
|
</details>
|
|
710
692
|
\`\`\`
|
|
711
693
|
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
\`\`\`
|
|
715
|
-
### \u2139\uFE0F Legacy \`opencode.ts\` has no documented deletion plan
|
|
716
|
-
|
|
717
|
-
The v2 harness lands alongside the v1 file and imports one helper from it. Worth a follow-up issue or a TODO so the next maintainer doesn't have to re-derive the cleanup plan.
|
|
718
|
-
\`\`\`
|
|
719
|
-
|
|
720
|
-
The example's value is its *shape*: a finding about absence (no deletion plan), not a line-anchored bug. Body sections live or die on whether the concern genuinely doesn't fit on a line.
|
|
721
|
-
|
|
722
|
-
**Heading severity emoji** \u2014 every \`### \` heading carries one:
|
|
723
|
-
|
|
724
|
-
- \u{1F6A8} critical \u2014 blocks merge (data loss, security, broken core flow)
|
|
725
|
-
- \u26A0\uFE0F important \u2014 must address before merging (regression, missing validation, incorrect behavior)
|
|
726
|
-
- \u2139\uFE0F informational \u2014 surfaced for awareness; mergeable as-is
|
|
727
|
-
|
|
728
|
-
**Visible problem write-up rules:**
|
|
729
|
-
|
|
730
|
-
- **No asks, no suggested fixes** in the visible part. The visible portion describes the problem; the technical-details block describes the fix shape and any open questions. The exception: a fix so self-evident that NOT stating it would be weird (e.g. "the typo is missing an 'r'") \u2014 in that case, fold it into the problem statement and skip the suggested-approach block in technical details too.
|
|
731
|
-
- **Never two successive plain paragraphs.** Every transition between block-level elements must alternate prose with structure: paragraph \u2192 bullet list \u2192 paragraph; paragraph \u2192 code fence \u2192 bullet list; paragraph \u2192 table \u2192 paragraph. Two consecutive paragraphs in a row create a wall of text that's impossible to digest. If you catch yourself writing one, find a way to split it: pull a list out of it, drop a 2-3 line code fence between them, or merge them into a single tighter paragraph.
|
|
732
|
-
- **Per-paragraph budget:** ~3 sentences max. Past that, you're explaining where you should be structuring.
|
|
733
|
-
- **Identifier discipline still applies** in the visible part. Lead with behavior in plain English; name an identifier only when it's the subject of the concern or a public surface a reader would recognize. The technical-details block is where dense identifier references belong.
|
|
734
|
-
|
|
735
|
-
**Technical-details block rules:**
|
|
736
|
-
|
|
737
|
-
- Wrapped in a 4-backtick markdown fence (\`\\\`\\\`\\\`\\\`markdown ... \\\`\\\`\\\`\\\`\`) so it's visually distinct, one-click copyable, and can contain its own 3-backtick code fences without escape gymnastics. The contents are agent-readable \u2014 a fix-agent will pull the body down and use this block as the brief.
|
|
738
|
-
- File paths and \`file:line\` refs are encouraged (and necessary) \u2014 the next agent uses these to navigate. Identifier density is fine here.
|
|
739
|
-
- Slightly more verbose than the absolute minimum is OK when it materially helps the next agent: a small code snippet showing the symptom, a short table of mismatched key/column pairs, a one-paragraph "why CI doesn't catch it" note. Skip massive regression-test scaffolding or full route rewrites \u2014 the implementing agent writes those.
|
|
740
|
-
- Use the four standard sections (\`Affected sites\`, \`Required outcome\`, optional \`Suggested approach\`, optional \`Open questions for the human\`). Skip the optional sections when they wouldn't add anything.
|
|
741
|
-
|
|
742
|
-
## Inline technical details
|
|
743
|
-
|
|
744
|
-
Inline comments are short (~2-3 sentences) by default. When an inline finding has broader implications worth recording for a fix-agent \u2014 e.g. a localized bug whose proper fix requires touching several files, or where the right fix depends on a design decision the human needs to make \u2014 append a collapsed \`<details><summary>Technical details</summary>\` block to the inline comment's body. Same shape as the body-section technical-details block (4-backtick fenced markdown, \`## Affected sites\` / \`## Required outcome\` / optional \`## Suggested approach\` / optional \`## Open questions for the human\`).
|
|
745
|
-
|
|
746
|
-
GitHub renders the same markdown parser in inline comments as in the review body, so the collapsed-details affordance works the same way. The visible part of the inline comment stays scannable; the depth is one click away for any agent that needs it.
|
|
747
|
-
|
|
748
|
-
## 3. \`### \u2139\uFE0F Nitpicks\` (optional, last section)
|
|
749
|
-
|
|
750
|
-
Only when there are nits that for some reason can't be inlined. Filepaths in nit text are fine \u2014 these are simple enough that a human or agent reads once and acts. No technical-details block.
|
|
751
|
-
|
|
752
|
-
\`\`\`
|
|
753
|
-
### \u2139\uFE0F Nitpicks
|
|
754
|
-
|
|
755
|
-
- {nit, with file path inline if useful, \u2264 ~200 chars}
|
|
756
|
-
- ...
|
|
757
|
-
\`\`\`
|
|
758
|
-
|
|
759
|
-
## Inline comment shape
|
|
694
|
+
The 4-backtick fence lets the block hold its own 3-backtick fences and stay one-click copyable. Skip the optional sections when they'd add nothing.
|
|
760
695
|
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
- **Lead with a 1-2 sentence problem statement.** The reader is looking at the line in question, so don't restate what the line says \u2014 describe what's wrong with it. Optionally prefix the visible line with a severity emoji (\u{1F6A8} / \u26A0\uFE0F / \u2139\uFE0F) when severity isn't obvious from context.
|
|
764
|
-
- **Optional \`<details><summary>Technical details</summary>...</details>\` collapsible** for findings whose technical context (longer file:line references, related-code snippets, suggested approach, regression-risk notes) would overwhelm the human-readable lead-in. Same agent-readable purpose, same 4-backtick fence shape, and same 4-section structure as the body's technical-details block \u2014 see *Inline technical details* above. Encouraged whenever the depth helps a downstream fix-agent; don't force one when the inline lead-in already says everything.
|
|
765
|
-
- **Visible portion \u2264 2-3 sentences.** If you find yourself writing more, that's the cue to split the depth into the \`Technical details\` collapsible.
|
|
766
|
-
|
|
767
|
-
## Body-wide rules
|
|
768
|
-
|
|
769
|
-
- **Inline-vs-body discipline (repeated for emphasis):** anything that anchors to a specific line goes inline (with a \`<details>Technical details</details>\` block when the implications are broad). The body is for non-anchorable concerns only \u2014 absence, sequencing, design decisions, scope questions, architectural risk.
|
|
770
|
-
- **No \`### Issues found\` heading** above the issue sections \u2014 each \`### \` heading IS the issue.
|
|
771
|
-
- **Severity emoji on every \`### \` heading** (\u{1F6A8} / \u26A0\uFE0F / \u2139\uFE0F). No emoji on the preamble lead-in or anywhere else.
|
|
772
|
-
- **GitHub block-level rendering**: GitHub's markdown parser requires a blank line between ALL block-level elements (HTML tags like \`<br/>\`, \`<sub>\`, \`<details>\`, \`<b>\` and markdown syntax like headings, lists, blockquotes, code fences, paragraphs). Without a blank line, GitHub treats following content as a continuation of the HTML block and renders markdown syntax as literal text. ALWAYS separate block-level elements with a blank line.
|
|
773
|
-
- **Backtick-wrap** every variable, identifier, or file name when you mention one (in either visible or technical-details portions).
|
|
774
|
-
- **Don't repeat diff content**, don't include raw \`+123 / -45\` stats, don't include a changelog section, don't use horizontal rules (\`---\`).
|
|
775
|
-
- **Pull file/commit counts from \`checkout_pr\` metadata** \u2014 never count manually.
|
|
776
|
-
- **Legacy headings REMOVED.** Do not use \`### Key changes\`, \`### Issues found\`, \`<b>TL;DR</b>\`, or \`<sub><b>Summary</b>\`. The new structure subsumes them.`;
|
|
696
|
+
Backtick-wrap identifiers and file names. Don't repeat diff content, don't include raw \`+123 / -45\` stats, no changelog, no horizontal rules, and no \`### Key changes\` / \`### Issues found\` / \`<b>TL;DR</b>\` heading \u2014 each \`### \` heading IS the issue.`;
|
|
777
697
|
function computeModes(agentId, signedCommits = false) {
|
|
778
698
|
const t = (toolName) => formatMcpToolRef(agentId, toolName);
|
|
779
699
|
const commitStep = signedCommits ? `commit via \`${t("commit_changes")}\` \u2014 it lands a GitHub-signed commit directly on the remote branch (no push step)` : `commit locally via shell (\`git add . && git commit -m "..."\`)`;
|
|
@@ -797,58 +717,15 @@ function computeModes(agentId, signedCommits = false) {
|
|
|
797
717
|
- plan your approach before writing code: identify which files need to change, key design decisions, and edge cases. for non-trivial changes, consider whether there's a more elegant approach.
|
|
798
718
|
- run relevant tests/lints before committing
|
|
799
719
|
|
|
800
|
-
5. **self-review**:
|
|
801
|
-
|
|
802
|
-
Skip self-review (commit directly) when the diff is **genuinely trivial**:
|
|
803
|
-
- doc typos, comment-only edits, whitespace/format-only, import reordering
|
|
804
|
-
- lockfile or generated-code regeneration, mechanical rename whose only effect is import-path updates (size of diff is irrelevant \u2014 read the *shape*, not the line count)
|
|
805
|
-
- low-risk dep patch bump from a trusted source
|
|
806
|
-
|
|
807
|
-
Run self-review when the diff has **any behavioral surface, however small**:
|
|
808
|
-
- 1-line changes to SQL operators / comparison logic / regexes / redirects / HTTP methods / response codes
|
|
809
|
-
- any change to money / tax / currency / billing / fee / refund / payout calculations or constants
|
|
810
|
-
- any change to auth / permissions / roles / sessions / tokens / signature verification
|
|
811
|
-
- any change to feature-flag defaults, retry counts, timeouts, rate limits, batch sizes
|
|
812
|
-
- new endpoints, new code paths, new error branches \u2014 even small ones
|
|
813
|
-
- mixed diffs (whitespace + a single semantic line) \u2014 the semantic line still triggers self-review
|
|
814
|
-
- anything you're uncertain about
|
|
815
|
-
|
|
816
|
-
Tie-breaker: when in doubt, run self-review. One false-positive subagent dispatch costs cents; one false-negative shipped bug costs much more. There's no value in dispatching for a typo, but there's also no excuse for skipping on a 1-line change to a billing path.
|
|
817
|
-
|
|
818
|
-
Otherwise delegate the \`${REVIEWER_AGENT_NAME}\` subagent to review your diff with fresh eyes against YOUR TASK. The subagent's baked-in system prompt enforces a non-mutative + non-recursive contract: read-only file/search/web tools and read-only MCP queries only; no writes, shell side effects, state-changing MCP calls, or nested subagent dispatch. Enforcement is prose-only \u2014 restate the constraint in your dispatch instructions and do not relax it.
|
|
819
|
-
|
|
820
|
-
Before dispatching, ensure \`origin/<base>\` is locally available \u2014 the runner is often a shallow single-branch \`actions/checkout\` (depth=1, head-only refspec), and the reviewer's \`git diff --merge-base origin/<base>\` will fail with \`ambiguous argument\` or \`no merge base\` otherwise. Run \`git fetch --no-tags --deepen=1000 origin <base>:refs/remotes/origin/<base>\` once (the explicit destination refspec is required \u2014 a shallow single-branch checkout configures a head-only refspec, so a bare \`origin <base>\` only updates \`FETCH_HEAD\` and never creates the \`origin/<base>\` tracking ref); it's a no-op if the ref already has enough history. (The reviewer is read-only by contract, so it cannot do this itself \u2014 fetching is the orchestrator's job.)
|
|
821
|
-
|
|
822
|
-
Compose your \`${REVIEWER_AGENT_NAME}\` dispatch prompt using this template verbatim, substituting the \`<...>\` placeholders. The preamble aligns the orchestrator side of the dispatch contract with the reviewer's baked-in system prompt \u2014 both ends say the same thing about where the work lives and what to do on an empty diff.
|
|
823
|
-
|
|
824
|
-
\`\`\`
|
|
825
|
-
## What you're reviewing
|
|
826
|
-
This is a PRE-COMMIT Build-mode self-review. The work to review lives in the working tree (uncommitted), NOT in committed history.
|
|
827
|
-
|
|
828
|
-
Branch: <branch> (off <base>)
|
|
829
|
-
Canonical diff command: git diff --merge-base origin/<base>
|
|
830
|
-
|
|
831
|
-
Use \`--merge-base\` (single MCP \`git\` call, no shell substitution required). NOT bare \`git diff origin/<base>\` or two-dot \`git diff origin/<base>..HEAD\` \u2014 the symmetric forms include the inverse of every commit landed on \`<base>\` since this branch forked, which is noise (and the git tool will reject those forms when the divergence is detected). \`origin/<base>...HEAD\` (three-dot) and \`--cached\` both miss the uncommitted edits self-review runs on, so they're also wrong here.
|
|
832
|
-
|
|
833
|
-
If the merge-base diff returns empty, treat it as "no changes \u2014 nothing to review" and stop per your system prompt. Do not search for the work elsewhere.
|
|
834
|
-
|
|
835
|
-
## Your task
|
|
836
|
-
<YOUR TASK content>
|
|
720
|
+
5. **self-review**: unless the diff has no behavioral surface at all \u2014 docs, comments, whitespace, import reordering, lockfile or generated-code regeneration, a mechanical rename, a trusted dep patch bump \u2014 dispatch the \`${REVIEWER_AGENT_NAME}\` subagent to review it with fresh eyes against YOUR TASK. Line count is not the signal: a one-line change to auth, money, SQL, a comparison operator, a redirect, or a config default earns a pass. When in doubt, run it \u2014 a false-positive dispatch costs cents, a missed bug costs much more.
|
|
837
721
|
|
|
838
|
-
|
|
839
|
-
<tight summary \u2014 what broke, root cause, the fix \u2014 or "no build-phase failures">
|
|
840
|
-
\`\`\`
|
|
722
|
+
Before dispatching, make \`origin/<base>\` available: \`git fetch --no-tags --deepen=1000 origin <base>:refs/remotes/origin/<base>\`. The explicit destination refspec is required \u2014 a shallow single-branch checkout otherwise only updates \`FETCH_HEAD\` and never creates the tracking ref. The reviewer is read-only by contract, so fetching is your job.
|
|
841
723
|
|
|
842
|
-
|
|
724
|
+
In the dispatch prompt: say this is a PRE-COMMIT self-review whose work is uncommitted in the working tree, give the branch and base, name \`git diff --merge-base origin/<base>\` as the canonical diff command, paste YOUR TASK, and summarize any build-phase failures. If that diff comes back empty, there is nothing to review \u2014 stop.
|
|
843
725
|
|
|
844
|
-
|
|
845
|
-
- Do NOT summarize what you implemented \u2014 that biases the subagent toward validating the shape of your solution rather than questioning it.
|
|
846
|
-
- Do NOT curate a reading list of files. Let the subagent discover scope from the diff and codebase.
|
|
847
|
-
- Do NOT pre-shape output with a severity / category schema. That leaks your hypotheses; severity is your call during evaluation.
|
|
848
|
-
- Do NOT defect-hunt the diff yourself in parallel with the subagent. Your role is dispatch + evaluation; doing the review yourself reintroduces the implementation bias the subagent is meant to mitigate.
|
|
849
|
-
- For diffs that rely on third-party API contracts, SDK semantics, framework directives, or DB engine specifics, instruct the subagent to verify load-bearing claims via web search and quote source URLs rather than trust training data \u2014 this is the single most common review-quality failure mode.
|
|
726
|
+
Give it the diff and the task, nothing else. Do not summarize what you implemented, curate a reading list of files, or pre-shape the output with a severity schema \u2014 each biases the reviewer toward validating your solution instead of questioning it. Where the diff rests on third-party API, SDK, framework, or DB-engine semantics, tell it to verify load-bearing claims by web search and quote sources.
|
|
850
727
|
|
|
851
|
-
|
|
728
|
+
Treat what comes back as hypotheses, not directives: verify each against the code before applying, and reject findings that would add ceremony without correctness \u2014 defensive checks for cases that cannot happen, single-use abstractions, comments restating code, tautological tests. After applying what you accept, re-read your own diff and revert anything that turned out to be bloat. Then ${commitStep}.
|
|
852
729
|
|
|
853
730
|
6. **finalize**:
|
|
854
731
|
- ${finalizeStep} (see *SYSTEM* Git rules if this fails \u2014 prepush errors are usually the repo's tests/lint, not infra timeouts)
|
|
@@ -916,76 +793,28 @@ For simple, well-defined tasks, skip the plan phase and go straight to build.`
|
|
|
916
793
|
|
|
917
794
|
3. **triage**: orient yourself on the PR \u2014 identify *what kind of thing this is* (domain it touches, seams it crosses, external contracts it depends on, user-facing surfaces it changes). pull as much context as you need to render a confident, well-grounded review: read related files, grep for callers of changed symbols, check tests that exercise the touched paths, fetch related GitHub state. **you are the synthesizer** \u2014 never delegate understanding to subagents.
|
|
918
795
|
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
-
|
|
926
|
-
|
|
927
|
-
"
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
-
|
|
935
|
-
-
|
|
936
|
-
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
Route the **minimum number of \`${REVIEWER_AGENT_NAME}\` specialists** needed to cover those unresolved hypotheses. Most reviews need **0 or 1**:
|
|
943
|
-
- dispatch 0 when you can resolve every disposition-changing question directly
|
|
944
|
-
- dispatch 1 when exactly one falsifiable, load-bearing hypothesis warrants independent investigation
|
|
945
|
-
- dispatch 2+ in parallel when multiple orthogonal load-bearing hypotheses remain, or when the user explicitly requests an exhaustive or multi-angle review
|
|
946
|
-
|
|
947
|
-
**There is NO one-specialist cap or fixed maximum.** Cover every orthogonal load-bearing hypothesis that remains; do not collapse multiple real questions into one broad prompt just to reduce the count. There is also no file-count, line-count, schema, quota, or hard-budget threshold \u2014 diff size is not a proxy for review uncertainty.
|
|
948
|
-
|
|
949
|
-
The primary reviewer remains responsible for reading the complete raw diff, investigating surrounding code, validating every returned finding, and synthesizing the final review. Specialist reads supplement that work; they never replace it or satisfy the primary's diff-coverage obligation.
|
|
950
|
-
|
|
951
|
-
Specialist hypotheses can draw on two kinds of framing:
|
|
952
|
-
- **themed lenses** \u2014 a perspective applied across the whole diff (correctness, security, user-journey, performance, etc.).
|
|
953
|
-
- **subsystem lenses** \u2014 a domain-scoped frame for high-stakes subsystems the PR touches (e.g. "the auth lens", "the billing lens", "the schema-migration lens"). **for high-stakes domains, lead with the subsystem lens rather than the generic themed equivalent** \u2014 "billing-subsystem" outperforms "correctness on billing code" because the framing primes the subagent to remember domain-specific failure modes (double-charges, refund races, currency rounding, dispute flows) the generic lens misses.
|
|
954
|
-
|
|
955
|
-
starter menu for identifying hypotheses (combine, omit, or invent your own; do not dispatch a bare menu label without a falsifiable question):
|
|
956
|
-
- **correctness & invariants** \u2014 bugs, races, error handling, edge cases, state-machine boundaries
|
|
957
|
-
- **impact** \u2014 stale references in code/tests/docs/configs/UI after rename/remove
|
|
958
|
-
- **research-validated assumptions** \u2014 third-party API contracts, SDK semantics, framework directives, version-gated behavior. **only pick when the PR's correctness depends on the contract behaving a specific way** \u2014 not when the API is merely used. The bar is "if the third-party contract differs from what the diff assumes, the PR is incorrect." When dispatched, the subagent must verify load-bearing claims via web search and quote source URLs.
|
|
959
|
-
- **security** \u2014 new endpoints, authZ, input validation, secrets handling, replay/CSRF/injection, cross-tenant isolation
|
|
960
|
-
- **user-journey** \u2014 UX-touching flows: walk through happy path and failure modes as a user
|
|
961
|
-
- **operational readiness** \u2014 observability, alerting, migrations (forward + rollback), feature flags, on-call burden
|
|
962
|
-
- **integration & cross-cutting** \u2014 API contracts between modules, backward-compat of public surfaces, multi-service ordering
|
|
963
|
-
- **test integrity** \u2014 meaningful coverage for the changed behavior; deterministic; no shared-state pollution
|
|
964
|
-
- **performance** \u2014 N+1 queries, hot-path allocation, latency budgets, index coverage
|
|
965
|
-
- **holistic** \u2014 does the PR make sense as a whole? symmetric flows (delete for every create, rollback for every migration)?
|
|
966
|
-
- **subsystem lenses** (invent as the PR demands) \u2014 auth, billing, payments, schema migration, webhooks, secrets, RBAC, multi-tenant isolation, cron/scheduling, etc.
|
|
967
|
-
|
|
968
|
-
The only subagent type is \`${REVIEWER_AGENT_NAME}\` \u2014 used for lens judgment work ("is this safe / correct / well-tested?"), runs on a mid-tier model.
|
|
969
|
-
|
|
970
|
-
5. **dispatch specialists (only if step 4 found unresolved hypotheses)**: dispatch one \`${REVIEWER_AGENT_NAME}\` for one hypothesis. For 2+ hypotheses, emit every Task tool_use block **IN A SINGLE ASSISTANT TURN** before reading any result so the investigations run in parallel rather than serially.
|
|
971
|
-
|
|
972
|
-
\u2705 Right multi-specialist pattern: one assistant turn with N Task tool_use blocks \u2192 wait \u2192 N results arrive together \u2192 aggregate.
|
|
973
|
-
\u274C Wrong multi-specialist pattern: Task(hypothesis A) \u2192 wait for A \u2192 Task(hypothesis B).
|
|
974
|
-
|
|
975
|
-
You can also include your own \`read\` / \`grep\` / \`webfetch\` calls in the SAME turn as the parallel \`${REVIEWER_AGENT_NAME}\` dispatches \u2014 concurrent context-pulling on the orchestrator side runs in parallel with the lens fan-out and costs zero extra wall time.
|
|
976
|
-
|
|
977
|
-
if a specialist errors out, times out, or returns nothing usable, retry it once with the same hypothesis. if it still fails, attempt to resolve the hypothesis yourself; if it remains disposition-changing and unresolved, surface the limitation and do not approve. each specialist gets:
|
|
978
|
-
- **the absolute \`diffPath\` (and \`incrementalDiffPath\` if available) from step 2's \`${t("checkout_pr")}\` return, named verbatim in the dispatch prompt** (e.g. \`diffPath: /tmp/pullfrog-XXXX/pr-NNN-SHA.diff\`). the reviewer's baked-in system prompt selects its FIRST action on this token \u2014 paraphrasing ("review the diff", "look at this PR") sends it down the \`git diff origin/<base>\` fallback, which fails on shallow GHA checkouts. the subagent \`read\`s those files for scope; it must NOT re-derive the diff via \`git diff\` (bare \`git diff origin/<base>\` is symmetric and pulls in the inverse of any commits that landed on \`<base>\` since the branch forked \u2014 pure noise, and the git tool rejects it). reading and codebase exploration are still its job.
|
|
979
|
-
- **exactly one falsifiable hypothesis with explicit scope boundaries** \u2014 ask for evidence that supports or refutes it, never a broad "review for X, Y, and Z" prompt
|
|
980
|
-
- **a Task \`description\` set to a short hypothesis label** (e.g. \`"webhook-replay"\`, \`"billing-rounding"\`) \u2014 the harness reads this field to label the subagent's log lines so parallel runs can be told apart in CI output. without it, every subagent shows up as \`subagent#N\`.
|
|
981
|
-
- if the lens touches external contracts, instruct the subagent to verify load-bearing claims via web search rather than trust training data, and to quote source URLs in its reasoning. action runs are non-interactive \u2014 there's no human in the loop to catch "I'm pretty sure Stripe does X."
|
|
982
|
-
- ask the subagent to report findings with file paths and NEW line numbers from the diff so you can validate and anchor them. you must still read the complete diff yourself.
|
|
983
|
-
|
|
984
|
-
delegation discipline:
|
|
985
|
-
- do NOT summarize the PR for them (a lossy summary biases toward a validation frame; the raw diff is the source)
|
|
986
|
-
- do NOT hand them a curated reading list (let them discover scope)
|
|
987
|
-
- do NOT pre-shape their output with a finding schema
|
|
988
|
-
- do NOT mention the other lenses (independence is the point \u2014 overlapping findings are a strong signal)
|
|
796
|
+
when the diff adds or changes a test, check that it can actually fail: a test that would still pass with the bug present is theatre, not coverage. the usual tell is a loose assertion standing where an exact one belongs \u2014 \`>=\` or a truthiness check over an expected value, or a snapshot that absorbs whatever it is handed. read the assertion against the behavior it claims to pin, not against whether it currently passes.
|
|
797
|
+
|
|
798
|
+
skip the deeper pass and submit a \`No new issues found.\` review per step 7 only when the diff has **no behavioral surface at all** \u2014 doc typos, whitespace/formatting, lockfile or generated-code regeneration, a mechanical rename whose only effect is import-path updates. line count is not the signal: a one-line change to auth, money, SQL, a comparison operator, a redirect, or a config default is not trivial.
|
|
799
|
+
|
|
800
|
+
4. **specialist decision**: after reading the complete diff, name the questions you still cannot answer confidently yourself, and dispatch one \`${REVIEWER_AGENT_NAME}\` specialist per question. a question qualifies only when a specialist could return evidence that **changes your disposition** on the PR \u2014 generic requests for another look, extra confidence, or polish do not. most reviews need zero or one; some need several.
|
|
801
|
+
|
|
802
|
+
**There is NO one-specialist cap or fixed maximum.** cover every orthogonal question that remains; do not collapse several real questions into one broad prompt just to reduce the count. there is no file-count, line-count, or budget threshold either \u2014 diff size is not a proxy for review uncertainty.
|
|
803
|
+
|
|
804
|
+
frame each question through the lens that primes the right failure modes. for high-stakes subsystems, lead with the **domain** ("the billing lens", "the auth lens", "the schema-migration lens") rather than the generic equivalent ("correctness on billing code") \u2014 the domain framing makes the subagent recall double-charges, refund races, currency rounding, and dispute flows that a generic lens misses.
|
|
805
|
+
|
|
806
|
+
you remain the synthesizer: reading the complete raw diff, investigating surrounding code, validating every returned finding, and writing the review are yours. specialist reads supplement that work; they never satisfy your own coverage obligation.
|
|
807
|
+
|
|
808
|
+
5. **dispatch specialists (only if step 4 found unresolved questions)**: for 2+ questions, emit every Task tool_use block **IN A SINGLE ASSISTANT TURN** before reading any result, so the investigations run in parallel rather than serially. your own \`read\` / \`grep\` / \`webfetch\` calls can ride in that same turn at zero extra wall time.
|
|
809
|
+
|
|
810
|
+
if a specialist errors out, times out, or returns nothing usable, retry it once. if it still fails, resolve the question yourself; if it remains disposition-changing and unresolved, surface the limitation and do not approve. each dispatch carries:
|
|
811
|
+
- **the absolute \`diffPath\` (and \`incrementalDiffPath\` if available) from step 2's \`${t("checkout_pr")}\` return, named verbatim in the dispatch prompt** (e.g. \`diffPath: /tmp/pullfrog-XXXX/pr-NNN-SHA.diff\`). the reviewer's baked-in system prompt selects its FIRST action on this token \u2014 paraphrasing ("review the diff", "look at this PR") sends it down a \`git diff origin/<base>\` fallback that fails on shallow GHA checkouts. it \`read\`s those files for scope and must NOT re-derive the diff itself; reading and codebase exploration are still its job.
|
|
812
|
+
- **exactly one falsifiable question with explicit scope boundaries** \u2014 ask for evidence that supports or refutes it, never a broad "review for X, Y, and Z" prompt.
|
|
813
|
+
- **a Task \`description\` set to a short hypothesis label** (e.g. \`"webhook-replay"\`, \`"billing-rounding"\`) \u2014 the harness reads this field to label the subagent's log lines so parallel runs can be told apart. without it, every subagent shows up as \`subagent#N\`.
|
|
814
|
+
- if the question touches third-party API, SDK, or framework contracts, instruct the subagent to verify load-bearing claims via web search and quote source URLs rather than trust training data. action runs are non-interactive \u2014 nobody is in the loop to catch "I'm pretty sure Stripe does X."
|
|
815
|
+
- ask for findings with file paths and NEW line numbers from the diff so you can validate and anchor them.
|
|
816
|
+
|
|
817
|
+
delegation discipline: do NOT summarize the PR for them (a lossy summary biases toward a validation frame; the raw diff is the source), do NOT hand them a curated reading list, do NOT pre-shape their output with a finding schema, and do NOT mention the other specialists \u2014 independence is the point, and overlapping findings are a strong signal.
|
|
989
818
|
|
|
990
819
|
6. **aggregate & draft**: when specialist results land, merge findings; de-dup overlaps (two specialists catching the same issue = higher-confidence signal); trace each finding yourself before accepting it. drop praise, style preferences, speculative/unverified claims, findings about pre-existing code unrelated to the PR (heuristic: if the finding's root cause lives in lines this PR added or modified, it's in scope; otherwise drop unless the PR plausibly introduced or amplified the regression), and anything not actionable. also drop **bloat-shaped findings** \u2014 proposed fixes that would add defensive checks for cases that can't happen, abstractions used once, comments restating obvious code, tests asserting tautologies, or "just-in-case" guards. subagents are fallible and bias toward recommending changes; the bar for an actionable inline comment is sound + correct + elegant. recommending a change that improves only one of the three (or worse, degrades elegance to nominally improve correctness) makes the codebase worse, not better.
|
|
991
820
|
|
|
@@ -1055,46 +884,28 @@ ${PR_SUMMARY_FORMAT}`
|
|
|
1055
884
|
|
|
1056
885
|
5. **triage**: orient on the *incremental* changes \u2014 domain, seams, external contracts, user-facing surfaces. pull as much context as you need to render a confident review: read related files, grep for callers of changed symbols, check tests that exercise the touched paths. **you are the synthesizer.**
|
|
1057
886
|
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
"Genuinely trivial" (skip): formatting/comment tweaks, import reordering, lockfile regen, mechanical rename of import paths, whitespace-only.
|
|
1061
|
-
"Looks trivial but isn't" (do NOT skip \u2014 same anti-patterns as Review mode): 1-line changes to SQL/regex/auth/billing/permissions/signature-verification code; flipping feature-flag defaults or retry/timeout constants; money/tax/HTTP-method/redirect changes; tightening or loosening a comparison operator; mixed diffs with a semantic line buried in formatting.
|
|
1062
|
-
When unsure, treat as non-trivial.
|
|
1063
|
-
|
|
1064
|
-
6. **specialist decision \u2014 minimum hypothesis coverage**.
|
|
887
|
+
a test added or changed in this delta must be able to fail \u2014 one that would still pass with the bug present is theatre, not coverage. the tell is a loose assertion where an exact one belongs (\`>=\` or a truthiness check over an expected value, a snapshot that absorbs whatever it is handed).
|
|
1065
888
|
|
|
1066
|
-
|
|
889
|
+
skip the deeper pass and jump to step 10's non-substantive path (do NOT submit a review) only when the incremental changes have **no behavioral surface at all** \u2014 formatting, comment tweaks, import reordering, lockfile regen, a mechanical rename of import paths. line count is not the signal: a one-line change to auth, money, SQL, a comparison operator, a redirect, or a config default is not trivial.
|
|
1067
890
|
|
|
1068
|
-
|
|
1069
|
-
- dispatch 0 when you can resolve every disposition-changing question directly
|
|
1070
|
-
- dispatch 1 when exactly one falsifiable, load-bearing hypothesis warrants independent investigation
|
|
1071
|
-
- dispatch 2+ in parallel when multiple orthogonal load-bearing hypotheses remain, or when the user explicitly requests an exhaustive or multi-angle review
|
|
891
|
+
6. **specialist decision**: after covering the incremental and full diffs, name the questions about the new changes that you still cannot answer confidently yourself, and dispatch one \`${REVIEWER_AGENT_NAME}\` specialist per question. a question qualifies only when a specialist could return evidence that **changes your disposition** on the PR \u2014 generic requests for another look, extra confidence, or polish do not. most incremental reviews need zero or one, especially thread-reply re-reviews; some need several.
|
|
1072
892
|
|
|
1073
|
-
**There is NO one-specialist cap or fixed maximum.**
|
|
893
|
+
**There is NO one-specialist cap or fixed maximum.** cover every orthogonal question that remains; do not collapse several real questions into one broad prompt just to reduce the count. there is no file-count, line-count, or budget threshold either \u2014 diff size is not a proxy for review uncertainty.
|
|
1074
894
|
|
|
1075
|
-
|
|
895
|
+
frame each question through the lens that primes the right failure modes. for high-stakes subsystems, lead with the **domain** ("the billing lens", "the auth lens", "the schema-migration lens") rather than the generic equivalent \u2014 the domain framing makes the subagent recall failure modes a generic lens misses.
|
|
1076
896
|
|
|
1077
|
-
|
|
897
|
+
you remain the synthesizer: reading the complete raw full diff plus the incremental diff, investigating surrounding code, validating every returned finding, and writing the review are yours. specialist reads supplement that work; they never satisfy your own coverage obligation.
|
|
1078
898
|
|
|
1079
|
-
7. **dispatch specialists (only if step 6 found unresolved
|
|
899
|
+
7. **dispatch specialists (only if step 6 found unresolved questions)**: for 2+ questions, emit every Task tool_use block **IN A SINGLE ASSISTANT TURN** before reading any result, so the investigations run in parallel rather than serially. your own \`read\` / \`grep\` / \`webfetch\` calls can ride in that same turn.
|
|
1080
900
|
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
You can also include your own \`read\` / \`grep\` / \`webfetch\` calls in the SAME turn as the parallel \`${REVIEWER_AGENT_NAME}\` dispatches.
|
|
1085
|
-
|
|
1086
|
-
if a specialist errors out, times out, or returns nothing usable, retry it once with the same hypothesis. if it still fails, attempt to resolve the hypothesis yourself; if it remains disposition-changing and unresolved, surface the limitation and do not approve. each specialist gets:
|
|
1087
|
-
- **the absolute diff path(s) from step 2's \`${t("checkout_pr")}\` return, named verbatim in the dispatch prompt.** when \`incrementalDiffPath\` is present, name BOTH (\`incrementalDiffPath: /tmp/.../pr-NNN-SHA-incremental.diff\` then \`diffPath: /tmp/.../pr-NNN-SHA.diff\`) \u2014 the reviewer's baked-in prompt reads incremental first and uses full for context; when only \`diffPath\` exists, name it alone. the subagent \`read\`s those files; it must NOT re-derive via \`git diff\` (bare \`git diff origin/<base>\` is symmetric and pulls in the inverse of base-branch progress \u2014 pure noise, and the git tool rejects it), and paraphrasing ("review the new commits") sends it down that fallback, which also fails on shallow GHA checkouts. do NOT tell them to skip pre-existing issues \u2014 that suppresses regressions the new commits amplified; the "issues must be NEW" filter lives at aggregation time (step 8), not in the subagent prompt.
|
|
1088
|
-
- **exactly one falsifiable hypothesis with explicit scope boundaries** \u2014 ask for evidence that supports or refutes it, never a broad "review for X, Y, and Z" prompt
|
|
901
|
+
if a specialist errors out, times out, or returns nothing usable, retry it once. if it still fails, resolve the question yourself; if it remains disposition-changing and unresolved, surface the limitation and do not approve. each dispatch carries:
|
|
902
|
+
- **the absolute diff path(s) from step 2's \`${t("checkout_pr")}\` return, named verbatim in the dispatch prompt.** when \`incrementalDiffPath\` is present, name BOTH (\`incrementalDiffPath: /tmp/.../pr-NNN-SHA-incremental.diff\` then \`diffPath: /tmp/.../pr-NNN-SHA.diff\`) \u2014 the reviewer's baked-in prompt reads incremental first and uses full for context; when only \`diffPath\` exists, name it alone. it \`read\`s those files and must NOT re-derive the diff itself; paraphrasing ("review the new commits") sends it down a \`git diff\` fallback that fails on shallow GHA checkouts. do NOT tell them to skip pre-existing issues \u2014 that suppresses regressions the new commits amplified; the "issues must be NEW" filter lives at aggregation time (step 8), not in the subagent prompt.
|
|
903
|
+
- **exactly one falsifiable question with explicit scope boundaries** \u2014 ask for evidence that supports or refutes it, never a broad "review for X, Y, and Z" prompt.
|
|
1089
904
|
- **a Task \`description\` set to a short hypothesis label** \u2014 the harness reads this field to label log lines so parallel runs can be told apart.
|
|
1090
|
-
- if the
|
|
1091
|
-
- ask
|
|
1092
|
-
|
|
1093
|
-
delegation discipline:
|
|
1094
|
-
- do NOT summarize the changes for them (a lossy summary biases toward a validation frame; the raw diff is the source)
|
|
1095
|
-
- do NOT hand them a curated reading list (let them discover scope)
|
|
1096
|
-
- do NOT pre-shape their output with a finding schema
|
|
1097
|
-
- do NOT mention the other lenses (independence is the point)
|
|
905
|
+
- if the question touches third-party API, SDK, or framework contracts, instruct the subagent to verify load-bearing claims via web search and quote source URLs.
|
|
906
|
+
- ask for findings with file paths and NEW line numbers from the full PR diff so you can validate and anchor them.
|
|
907
|
+
|
|
908
|
+
delegation discipline: do NOT summarize the changes for them (a lossy summary biases toward a validation frame; the raw diff is the source), do NOT hand them a curated reading list, do NOT pre-shape their output with a finding schema, and do NOT mention the other specialists \u2014 independence is the point.
|
|
1098
909
|
|
|
1099
910
|
8. **aggregate, draft, self-critique**: merge findings (yours + output from every specialist you dispatched); de-dup overlaps; trace each finding yourself. drop praise, style preferences, speculative/unverified claims, findings about pre-existing code unrelated to the new commits, anything not actionable, and anything that re-states prior review feedback (heuristic: if the finding's root cause lives in lines the *new commits* added or modified, it's in scope; otherwise drop). also drop **bloat-shaped findings** \u2014 proposed fixes that would add defensive checks for cases that can't happen, abstractions used once, comments restating obvious code, tests asserting tautologies, or "just-in-case" guards. subagents are fallible and bias toward recommending changes; the bar for an actionable inline comment is sound + correct + elegant. recommending a change that improves only one of the three (or degrades elegance to nominally improve correctness) makes the codebase worse, not better. To compute "lines the new commits added or modified": if \`incrementalDiffPath\` from step 2 is present, use it directly. Otherwise, take the prior Pullfrog review's \`commit_id\` (returned alongside each entry from \`${t("list_pull_request_reviews")}\` in step 4) and run \`git diff <prior-review-sha>..HEAD\` to isolate the lines added since that review.
|
|
1100
911
|
|
package/dist/modes.d.ts
CHANGED
|
@@ -4,7 +4,6 @@ export interface Mode {
|
|
|
4
4
|
description: string;
|
|
5
5
|
prompt?: string | undefined;
|
|
6
6
|
}
|
|
7
|
-
export declare const PR_SUMMARY_FORMAT = "### Default format\n\nThe body has at most three parts in this exact order:\n\n1. **Reviewed changes preamble** \u2014 one bolded inline lead-in describing what was reviewed in this run, a bullet list of the substantive changes, and an HTML comment carrying review metadata for downstream agents.\n2. **Cross-cutting issue sections** (zero or more) \u2014 one `### ` heading per concern, with a human-readable problem write-up and a collapsed `<details>Technical details</details>` block underneath.\n3. **`### \u2139\uFE0F Nitpicks`** at the very bottom (only if there are nits worth surfacing in the body) \u2014 a flat bullet list, no technical-details block.\n\nInline-vs-body split: concerns that anchor to a specific line go inline (use the `comments` parameter). Body `### ` sections are reserved for concerns that **have no line to anchor to** \u2014 typically because the concern is about *absence* (something the diff should have done but didn't), *sequencing* (rollout / deletion / migration order), *design decisions only the human can make*, or *scope questions the diff implicitly raises but doesn't address*. A concern that anchors to a line but has broad implications still goes inline (use the technical-details block there to capture the implications \u2014 see Inline technical details below). If you found no non-anchorable concerns, the body has zero `### ` issue sections \u2014 just the preamble + metadata.\n\n## 1. Reviewed changes preamble\n\nOpen with a single bolded inline lead-in followed immediately by the bullet list (no `### Key changes` heading, no `<b>TL;DR</b>`):\n\n```\n**Reviewed changes** \u2014 one sentence on what was reviewed in this run. For Review (initial), this is what the PR does and why. For IncrementalReview, this is what changed since the prior pullfrog review. Focus on intent, not mechanics.\n\n- **Short human-readable title** \u2014 1 sentence per substantive change. Write a short prose phrase; when you name a file, type, or function, put that name in backticks (e.g. **Add \\`TodoTracker\\` for live checklists**). A reviewer should understand the full reviewed scope from this list alone \u2014 this IS the dispassionate \"what was reviewed and what changed\" overview, so cover the substantive changes, not just the loudest ones.\n\n<!--\nPullfrog review metadata \u2014 for any agent (or human-with-agent) reading this\nreview. Incorporate the fields below into your understanding of the context\nthis review was made in. The findings below were written against\n{head_sha_short}; if new commits have landed on {head_ref} since this review\nwas submitted, treat any specific bug, file, or line callout as POTENTIALLY\nSTALE \u2014 re-diff against {head_sha_short} (or trigger a fresh review) and\nfactor commits past {head_sha_short} into your understanding of the current\nstate before acting on findings.\n\n- Mode: Review (initial) or IncrementalReview (delta against prior pullfrog review)\n- Files reviewed: {file_count}\n- Commits reviewed: {commit_count}\n- Base: {base_ref} ({base_sha_short})\n- Head: {head_ref} ({head_sha_short})\n- Reviewed commits:\n - {sha_short} \u2014 {commit_subject}\n - ...\n- Prior pullfrog review: none or {prior_sha_short} ({prior_review_html_url})\n- Submitted at: {iso_timestamp}\n-->\n```\n\nPull every metadata field from the `checkout_pr` tool's response \u2014 file count, commit count, base/head ref + SHA, the commit list. For `IncrementalReview` runs, populate `Prior pullfrog review` with the prior review's commit_id (short SHA) and `html_url` from `list_pull_request_reviews`.\n\n## 2. Cross-cutting issue sections (zero or more)\n\nFor each cross-cutting concern, one `### ` section. Use this exact shape:\n\n```\n### {emoji} {short, descriptive title \u2014 what's wrong, not what to do}\n\n{Human-readable problem write-up. Describes the PROBLEM only \u2014 what's broken, what the symptom is, what the blast radius is. NO asks, NO suggested fixes, NO \"the right thing to do is...\". Asks and fixes live in the technical-details block below; the visible part is for the human to *understand* the problem, not to implement it.}\n\n<details><summary>Technical details</summary>\n\n\\`\\`\\`\\`markdown\n# {title repeated}\n\n## Affected sites\n- {file path:line} \u2014 {what's wrong there}\n- ...\n\n## Required outcome\n- {what the fix needs to achieve, not how to achieve it}\n- ...\n\n## Suggested approach (optional)\n{When the fix shape is non-obvious, sketch one or more reasonable directions. Skip when the outcome alone makes the fix obvious.}\n\n## Open questions for the human (optional)\n- {Any decision an implementing agent shouldn't make unilaterally \u2014 pricing thresholds, breaking-change policy, naming, scope of follow-up.}\n\\`\\`\\`\\`\n\n</details>\n```\n\nConcrete example of the visible part of a non-anchored section (technical-details block unchanged from the template above):\n\n```\n### \u2139\uFE0F Legacy `opencode.ts` has no documented deletion plan\n\nThe v2 harness lands alongside the v1 file and imports one helper from it. Worth a follow-up issue or a TODO so the next maintainer doesn't have to re-derive the cleanup plan.\n```\n\nThe example's value is its *shape*: a finding about absence (no deletion plan), not a line-anchored bug. Body sections live or die on whether the concern genuinely doesn't fit on a line.\n\n**Heading severity emoji** \u2014 every `### ` heading carries one:\n\n- \uD83D\uDEA8 critical \u2014 blocks merge (data loss, security, broken core flow)\n- \u26A0\uFE0F important \u2014 must address before merging (regression, missing validation, incorrect behavior)\n- \u2139\uFE0F informational \u2014 surfaced for awareness; mergeable as-is\n\n**Visible problem write-up rules:**\n\n- **No asks, no suggested fixes** in the visible part. The visible portion describes the problem; the technical-details block describes the fix shape and any open questions. The exception: a fix so self-evident that NOT stating it would be weird (e.g. \"the typo is missing an 'r'\") \u2014 in that case, fold it into the problem statement and skip the suggested-approach block in technical details too.\n- **Never two successive plain paragraphs.** Every transition between block-level elements must alternate prose with structure: paragraph \u2192 bullet list \u2192 paragraph; paragraph \u2192 code fence \u2192 bullet list; paragraph \u2192 table \u2192 paragraph. Two consecutive paragraphs in a row create a wall of text that's impossible to digest. If you catch yourself writing one, find a way to split it: pull a list out of it, drop a 2-3 line code fence between them, or merge them into a single tighter paragraph.\n- **Per-paragraph budget:** ~3 sentences max. Past that, you're explaining where you should be structuring.\n- **Identifier discipline still applies** in the visible part. Lead with behavior in plain English; name an identifier only when it's the subject of the concern or a public surface a reader would recognize. The technical-details block is where dense identifier references belong.\n\n**Technical-details block rules:**\n\n- Wrapped in a 4-backtick markdown fence (`\\`\\`\\`\\`markdown ... \\`\\`\\`\\``) so it's visually distinct, one-click copyable, and can contain its own 3-backtick code fences without escape gymnastics. The contents are agent-readable \u2014 a fix-agent will pull the body down and use this block as the brief.\n- File paths and `file:line` refs are encouraged (and necessary) \u2014 the next agent uses these to navigate. Identifier density is fine here.\n- Slightly more verbose than the absolute minimum is OK when it materially helps the next agent: a small code snippet showing the symptom, a short table of mismatched key/column pairs, a one-paragraph \"why CI doesn't catch it\" note. Skip massive regression-test scaffolding or full route rewrites \u2014 the implementing agent writes those.\n- Use the four standard sections (`Affected sites`, `Required outcome`, optional `Suggested approach`, optional `Open questions for the human`). Skip the optional sections when they wouldn't add anything.\n\n## Inline technical details\n\nInline comments are short (~2-3 sentences) by default. When an inline finding has broader implications worth recording for a fix-agent \u2014 e.g. a localized bug whose proper fix requires touching several files, or where the right fix depends on a design decision the human needs to make \u2014 append a collapsed `<details><summary>Technical details</summary>` block to the inline comment's body. Same shape as the body-section technical-details block (4-backtick fenced markdown, `## Affected sites` / `## Required outcome` / optional `## Suggested approach` / optional `## Open questions for the human`).\n\nGitHub renders the same markdown parser in inline comments as in the review body, so the collapsed-details affordance works the same way. The visible part of the inline comment stays scannable; the depth is one click away for any agent that needs it.\n\n## 3. `### \u2139\uFE0F Nitpicks` (optional, last section)\n\nOnly when there are nits that for some reason can't be inlined. Filepaths in nit text are fine \u2014 these are simple enough that a human or agent reads once and acts. No technical-details block.\n\n```\n### \u2139\uFE0F Nitpicks\n\n- {nit, with file path inline if useful, \u2264 ~200 chars}\n- ...\n```\n\n## Inline comment shape\n\nInline comments use the same severity framing as body `### ` sections, scaled down for line-anchored use:\n\n- **Lead with a 1-2 sentence problem statement.** The reader is looking at the line in question, so don't restate what the line says \u2014 describe what's wrong with it. Optionally prefix the visible line with a severity emoji (\uD83D\uDEA8 / \u26A0\uFE0F / \u2139\uFE0F) when severity isn't obvious from context.\n- **Optional `<details><summary>Technical details</summary>...</details>` collapsible** for findings whose technical context (longer file:line references, related-code snippets, suggested approach, regression-risk notes) would overwhelm the human-readable lead-in. Same agent-readable purpose, same 4-backtick fence shape, and same 4-section structure as the body's technical-details block \u2014 see *Inline technical details* above. Encouraged whenever the depth helps a downstream fix-agent; don't force one when the inline lead-in already says everything.\n- **Visible portion \u2264 2-3 sentences.** If you find yourself writing more, that's the cue to split the depth into the `Technical details` collapsible.\n\n## Body-wide rules\n\n- **Inline-vs-body discipline (repeated for emphasis):** anything that anchors to a specific line goes inline (with a `<details>Technical details</details>` block when the implications are broad). The body is for non-anchorable concerns only \u2014 absence, sequencing, design decisions, scope questions, architectural risk.\n- **No `### Issues found` heading** above the issue sections \u2014 each `### ` heading IS the issue.\n- **Severity emoji on every `### ` heading** (\uD83D\uDEA8 / \u26A0\uFE0F / \u2139\uFE0F). No emoji on the preamble lead-in or anywhere else.\n- **GitHub block-level rendering**: GitHub's markdown parser requires a blank line between ALL block-level elements (HTML tags like `<br/>`, `<sub>`, `<details>`, `<b>` and markdown syntax like headings, lists, blockquotes, code fences, paragraphs). Without a blank line, GitHub treats following content as a continuation of the HTML block and renders markdown syntax as literal text. ALWAYS separate block-level elements with a blank line.\n- **Backtick-wrap** every variable, identifier, or file name when you mention one (in either visible or technical-details portions).\n- **Don't repeat diff content**, don't include raw `+123 / -45` stats, don't include a changelog section, don't use horizontal rules (`---`).\n- **Pull file/commit counts from `checkout_pr` metadata** \u2014 never count manually.\n- **Legacy headings REMOVED.** Do not use `### Key changes`, `### Issues found`, `<b>TL;DR</b>`, or `<sub><b>Summary</b>`. The new structure subsumes them.";
|
|
8
7
|
export declare function computeModes(agentId: AgentId, signedCommits?: boolean): Mode[];
|
|
9
8
|
export declare const modes: Mode[];
|
|
10
9
|
/**
|
package/dist/toolState.d.ts
CHANGED