pullfrog 0.1.43 → 0.1.45

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 CHANGED
@@ -103022,7 +103022,7 @@ var import_semver = __toESM(require_semver2(), 1);
103022
103022
  // package.json
103023
103023
  var package_default = {
103024
103024
  name: "pullfrog",
103025
- version: "0.1.43",
103025
+ version: "0.1.45",
103026
103026
  type: "module",
103027
103027
  bin: {
103028
103028
  pullfrog: "dist/cli.mjs",
@@ -103704,16 +103704,8 @@ HARD CONSTRAINTS (non-negotiable, regardless of orchestrator instructions):
103704
103704
 
103705
103705
  Report findings clearly with file:line references and quoted evidence where possible. Flag uncertainty explicitly \u2014 if you cannot verify a claim, say so rather than guess.`;
103706
103706
 
103707
- // utils/promptProfile.ts
103708
- function promptProfile() {
103709
- return process.env.PULLFROG_PROMPT_PROFILE === "full" ? "full" : "lean";
103710
- }
103711
- function byProfile(lean, full) {
103712
- return promptProfile() === "lean" ? lean : full;
103713
- }
103714
-
103715
103707
  // modes.ts
103716
- var PR_SUMMARY_FORMAT_LEAN = `### Default format
103708
+ var PR_SUMMARY_FORMAT = `### Default format
103717
103709
 
103718
103710
  The body has at most three parts, in this order:
103719
103711
 
@@ -103745,7 +103737,6 @@ line callout as POTENTIALLY STALE and re-diff before acting on it.
103745
103737
  - Reviewed commits:
103746
103738
  - {sha_short} \u2014 {commit_subject}
103747
103739
  - Prior pullfrog review: none or {prior_sha_short} ({prior_review_html_url})
103748
- - Submitted at: {iso_timestamp}
103749
103740
  -->
103750
103741
  \`\`\`
103751
103742
 
@@ -103775,150 +103766,6 @@ Every body \`### \` section carries one; an inline comment carries one when its
103775
103766
  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.
103776
103767
 
103777
103768
  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.`;
103778
- var PR_SUMMARY_FORMAT_FULL = `### Default format
103779
-
103780
- The body has at most three parts in this exact order:
103781
-
103782
- 1. **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.
103783
- 2. **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.
103784
- 3. **\`### \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.
103785
-
103786
- Inline-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.
103787
-
103788
- ## 1. Reviewed changes preamble
103789
-
103790
- Open with a single bolded inline lead-in followed immediately by the bullet list (no \`### Key changes\` heading, no \`<b>TL;DR</b>\`):
103791
-
103792
- \`\`\`
103793
- **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.
103794
-
103795
- - **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.
103796
-
103797
- <!--
103798
- Pullfrog review metadata \u2014 for any agent (or human-with-agent) reading this
103799
- review. Incorporate the fields below into your understanding of the context
103800
- this review was made in. The findings below were written against
103801
- {head_sha_short}; if new commits have landed on {head_ref} since this review
103802
- was submitted, treat any specific bug, file, or line callout as POTENTIALLY
103803
- STALE \u2014 re-diff against {head_sha_short} (or trigger a fresh review) and
103804
- factor commits past {head_sha_short} into your understanding of the current
103805
- state before acting on findings.
103806
-
103807
- - Mode: Review (initial) or IncrementalReview (delta against prior pullfrog review)
103808
- - Files reviewed: {file_count}
103809
- - Commits reviewed: {commit_count}
103810
- - Base: {base_ref} ({base_sha_short})
103811
- - Head: {head_ref} ({head_sha_short})
103812
- - Reviewed commits:
103813
- - {sha_short} \u2014 {commit_subject}
103814
- - ...
103815
- - Prior pullfrog review: none or {prior_sha_short} ({prior_review_html_url})
103816
- - Submitted at: {iso_timestamp}
103817
- -->
103818
- \`\`\`
103819
-
103820
- Pull 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\`.
103821
-
103822
- ## 2. Cross-cutting issue sections (zero or more)
103823
-
103824
- For each cross-cutting concern, one \`### \` section. Use this exact shape:
103825
-
103826
- \`\`\`
103827
- ### {emoji} {short, descriptive title \u2014 what's wrong, not what to do}
103828
-
103829
- {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.}
103830
-
103831
- <details><summary>Technical details</summary>
103832
-
103833
- \\\`\\\`\\\`\\\`markdown
103834
- # {title repeated}
103835
-
103836
- ## Affected sites
103837
- - {file path:line} \u2014 {what's wrong there}
103838
- - ...
103839
-
103840
- ## Required outcome
103841
- - {what the fix needs to achieve, not how to achieve it}
103842
- - ...
103843
-
103844
- ## Suggested approach (optional)
103845
- {When the fix shape is non-obvious, sketch one or more reasonable directions. Skip when the outcome alone makes the fix obvious.}
103846
-
103847
- ## Open questions for the human (optional)
103848
- - {Any decision an implementing agent shouldn't make unilaterally \u2014 pricing thresholds, breaking-change policy, naming, scope of follow-up.}
103849
- \\\`\\\`\\\`\\\`
103850
-
103851
- </details>
103852
- \`\`\`
103853
-
103854
- Concrete example of the visible part of a non-anchored section (technical-details block unchanged from the template above):
103855
-
103856
- \`\`\`
103857
- ### \u2139\uFE0F Legacy \`opencode.ts\` has no documented deletion plan
103858
-
103859
- 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.
103860
- \`\`\`
103861
-
103862
- 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.
103863
-
103864
- **Heading severity emoji** \u2014 every \`### \` heading carries one:
103865
-
103866
- - \u{1F6A8} critical \u2014 blocks merge (data loss, security, broken core flow)
103867
- - \u26A0\uFE0F important \u2014 must address before merging (regression, missing validation, incorrect behavior)
103868
- - \u2139\uFE0F informational \u2014 surfaced for awareness; mergeable as-is
103869
-
103870
- **Visible problem write-up rules:**
103871
-
103872
- - **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.
103873
- - **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.
103874
- - **Per-paragraph budget:** ~3 sentences max. Past that, you're explaining where you should be structuring.
103875
- - **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.
103876
-
103877
- **Technical-details block rules:**
103878
-
103879
- - 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.
103880
- - File paths and \`file:line\` refs are encouraged (and necessary) \u2014 the next agent uses these to navigate. Identifier density is fine here.
103881
- - 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.
103882
- - 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.
103883
-
103884
- ## Inline technical details
103885
-
103886
- 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\`).
103887
-
103888
- 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.
103889
-
103890
- ## 3. \`### \u2139\uFE0F Nitpicks\` (optional, last section)
103891
-
103892
- 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.
103893
-
103894
- \`\`\`
103895
- ### \u2139\uFE0F Nitpicks
103896
-
103897
- - {nit, with file path inline if useful, \u2264 ~200 chars}
103898
- - ...
103899
- \`\`\`
103900
-
103901
- ## Inline comment shape
103902
-
103903
- Inline comments use the same severity framing as body \`### \` sections, scaled down for line-anchored use:
103904
-
103905
- - **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.
103906
- - **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.
103907
- - **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.
103908
-
103909
- ## Body-wide rules
103910
-
103911
- - **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.
103912
- - **No \`### Issues found\` heading** above the issue sections \u2014 each \`### \` heading IS the issue.
103913
- - **Severity emoji on every \`### \` heading** (\u{1F6A8} / \u26A0\uFE0F / \u2139\uFE0F). No emoji on the preamble lead-in or anywhere else.
103914
- - **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.
103915
- - **Backtick-wrap** every variable, identifier, or file name when you mention one (in either visible or technical-details portions).
103916
- - **Don't repeat diff content**, don't include raw \`+123 / -45\` stats, don't include a changelog section, don't use horizontal rules (\`---\`).
103917
- - **Pull file/commit counts from \`checkout_pr\` metadata** \u2014 never count manually.
103918
- - **Legacy headings REMOVED.** Do not use \`### Key changes\`, \`### Issues found\`, \`<b>TL;DR</b>\`, or \`<sub><b>Summary</b>\`. The new structure subsumes them.`;
103919
- function prSummaryFormat() {
103920
- return byProfile(PR_SUMMARY_FORMAT_LEAN, PR_SUMMARY_FORMAT_FULL);
103921
- }
103922
103769
  function computeModes(agentId, signedCommits = false) {
103923
103770
  const t2 = (toolName) => formatMcpToolRef(agentId, toolName);
103924
103771
  const commitStep = signedCommits ? `commit via \`${t2("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 "..."\`)`;
@@ -103942,8 +103789,7 @@ function computeModes(agentId, signedCommits = false) {
103942
103789
  - 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.
103943
103790
  - run relevant tests/lints before committing
103944
103791
 
103945
- 5. **self-review**: ${byProfile(
103946
- `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.
103792
+ 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.
103947
103793
 
103948
103794
  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.
103949
103795
 
@@ -103951,60 +103797,7 @@ function computeModes(agentId, signedCommits = false) {
103951
103797
 
103952
103798
  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.
103953
103799
 
103954
- 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}.`,
103955
- `judgment call \u2014 does YOUR diff warrant a fresh-eyes pass?
103956
-
103957
- Skip self-review (commit directly) when the diff is **genuinely trivial**:
103958
- - doc typos, comment-only edits, whitespace/format-only, import reordering
103959
- - 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)
103960
- - low-risk dep patch bump from a trusted source
103961
-
103962
- Run self-review when the diff has **any behavioral surface, however small**:
103963
- - 1-line changes to SQL operators / comparison logic / regexes / redirects / HTTP methods / response codes
103964
- - any change to money / tax / currency / billing / fee / refund / payout calculations or constants
103965
- - any change to auth / permissions / roles / sessions / tokens / signature verification
103966
- - any change to feature-flag defaults, retry counts, timeouts, rate limits, batch sizes
103967
- - new endpoints, new code paths, new error branches \u2014 even small ones
103968
- - mixed diffs (whitespace + a single semantic line) \u2014 the semantic line still triggers self-review
103969
- - anything you're uncertain about
103970
-
103971
- 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.
103972
-
103973
- 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.
103974
-
103975
- 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.)
103976
-
103977
- 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.
103978
-
103979
- \`\`\`
103980
- ## What you're reviewing
103981
- This is a PRE-COMMIT Build-mode self-review. The work to review lives in the working tree (uncommitted), NOT in committed history.
103982
-
103983
- Branch: <branch> (off <base>)
103984
- Canonical diff command: git diff --merge-base origin/<base>
103985
-
103986
- 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.
103987
-
103988
- 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.
103989
-
103990
- ## Your task
103991
- <YOUR TASK content>
103992
-
103993
- ## Build-phase failures
103994
- <tight summary \u2014 what broke, root cause, the fix \u2014 or "no build-phase failures">
103995
- \`\`\`
103996
-
103997
- Follow the template with the diff content (\`git diff --merge-base origin/<base-branch>\` \u2014 single MCP \`git\` call, captures committed + staged + unstaged, excludes base-branch progress) and your task brief. Instruct the subagent to flag bugs, logic errors, missing edge cases, gaps between request and diff, and unintended changes.
103998
-
103999
- Delegation + research discipline (distilled from \`/anneal\` canonical \u2014 these are codified learnings from many review rounds, not theoretical best practices):
104000
- - Do NOT summarize what you implemented \u2014 that biases the subagent toward validating the shape of your solution rather than questioning it.
104001
- - Do NOT curate a reading list of files. Let the subagent discover scope from the diff and codebase.
104002
- - Do NOT pre-shape output with a severity / category schema. That leaks your hypotheses; severity is your call during evaluation.
104003
- - 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.
104004
- - 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.
104005
-
104006
- Be **discerning** about what comes back. The reviewer is an AI subagent and is fallible \u2014 treat every finding as a hypothesis, not a directive, and **verify each one yourself** against the diff and the code before deciding whether to apply. You are searching for a solution that is **complete, minimal, and elegant** \u2014 you may need to think hard to find it. Do not over-engineer, do not be over-defensive, **do not write AI slop**. Reviewers bias toward *recommending additions*, and that bias has a recognizable slop texture: defensive checks for cases that cannot happen, extra logging, new abstractions used once, comments restating code, tests asserting tautologies, "just-in-case" guards, error handlers for cases the type system already rules out. Reject those. For each surviving finding, ask: would applying it leave the code more sound, correct, AND elegant? Two-out-of-three means look harder for a fix that gets all three before settling. After applying the fixes you accept, re-read your diff and be discerning about what *you just changed*: if any fix turned out to be bloat in context, revert it. Then verify only intended changes are present, no debug artifacts or commented-out code remain, no unrelated files were modified. Then ${commitStep}.`
104007
- )}
103800
+ 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}.
104008
103801
 
104009
103802
  6. **finalize**:
104010
103803
  - ${finalizeStep} (see *SYSTEM* Git rules if this fails \u2014 prepush errors are usually the repo's tests/lint, not infra timeouts)
@@ -104057,7 +103850,7 @@ For simple, well-defined tasks, skip the plan phase and go straight to build.`
104057
103850
  //
104058
103851
  // Severity categorization is split across two surfaces: the opening
104059
103852
  // callout (CAUTION/IMPORTANT/ℹ️/✅) sets the review's overall tier, and
104060
- // per-bullet emoji prefixes (🚨/⚠️/ℹ️ in prSummaryFormat()) tag
103853
+ // per-bullet emoji prefixes (🚨/⚠️/ℹ️ in PR_SUMMARY_FORMAT) tag
104061
103854
  // individual points inside summary sections — scoping severity to the
104062
103855
  // specific bullet rather than the whole section keeps a section that
104063
103856
  // mixes a 🚨 and an ℹ️ from being mislabeled by either of them.
@@ -104070,8 +103863,9 @@ For simple, well-defined tasks, skip the plan phase and go straight to build.`
104070
103863
 
104071
103864
  2. **checkout**: call \`${t2("checkout_pr")}\` \u2014 this returns PR metadata, a \`diffPath\`, and a supplemental \`impactPath\` when change-impact extraction is enabled. read the complete raw diff end-to-end, beginning with the TOC and using its file line ranges as your coverage checklist. only after that, use \`impactPath\` as an explicitly incomplete list of reference leads; it never replaces raw-diff reading or establishes coverage.
104072
103865
 
104073
- ${byProfile(
104074
- `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.
103866
+ 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.
103867
+
103868
+ 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.
104075
103869
 
104076
103870
  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.
104077
103871
 
@@ -104092,80 +103886,7 @@ ${byProfile(
104092
103886
  - 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."
104093
103887
  - ask for findings with file paths and NEW line numbers from the diff so you can validate and anchor them.
104094
103888
 
104095
- 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.`,
104096
- `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.
104097
-
104098
- if the PR is **genuinely trivial**, skip specialists entirely and submit a \`No new issues found.\` review per step 7.
104099
-
104100
- "Genuinely trivial" (skip):
104101
- - single-word doc typo, whitespace/format-only, comment-only across any number of files
104102
- - lockfile or generated-code regeneration (size of diff is irrelevant \u2014 read the *shape*)
104103
- - mechanical rename whose only effect is import-path updates
104104
- - low-risk dep patch bump
104105
-
104106
- "Looks trivial but isn't" (do **NOT** skip \u2014 small diff, big blast radius):
104107
- - any 1-line change to SQL / regex / auth / billing / permission / signature-verification code
104108
- - flipping a feature-flag default, default config value, or retry/timeout constant
104109
- - changing a money/tax/currency/fee constant by any amount
104110
- - changing an HTTP method, redirect URL, response code, or status enum
104111
- - tightening or loosening a comparison operator (\`<\` \u2194 \`<=\`, \`==\` \u2194 \`!=\`)
104112
- - renaming a public API surface (still trivial in shape, but needs an impact lens)
104113
- - adding a new direct dependency (supply-chain surface)
104114
- - any "typo fix" in user-facing copy that changes meaning ("approved" \u2192 "denied")
104115
- - mixed diffs where a semantic 1-liner is buried in whitespace/formatting changes
104116
-
104117
- 4. **specialist decision \u2014 minimum hypothesis coverage**.
104118
-
104119
- After full-diff coverage and triage, identify the load-bearing questions you still cannot resolve confidently yourself. A specialist hypothesis is load-bearing only when its answer could yield an actionable finding that changes the review disposition and warrants independent investigation, and falsifiable only when the specialist can return evidence that supports or refutes it. Generic requests for extra confidence, polish, or "another look" do not qualify.
104120
-
104121
- Route the **minimum number of \`${REVIEWER_AGENT_NAME}\` specialists** needed to cover those unresolved hypotheses. Most reviews need **0 or 1**:
104122
- - dispatch 0 when you can resolve every disposition-changing question directly
104123
- - dispatch 1 when exactly one falsifiable, load-bearing hypothesis warrants independent investigation
104124
- - dispatch 2+ in parallel when multiple orthogonal load-bearing hypotheses remain, or when the user explicitly requests an exhaustive or multi-angle review
104125
-
104126
- **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.
104127
-
104128
- 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.
104129
-
104130
- Specialist hypotheses can draw on two kinds of framing:
104131
- - **themed lenses** \u2014 a perspective applied across the whole diff (correctness, security, user-journey, performance, etc.).
104132
- - **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.
104133
-
104134
- starter menu for identifying hypotheses (combine, omit, or invent your own; do not dispatch a bare menu label without a falsifiable question):
104135
- - **correctness & invariants** \u2014 bugs, races, error handling, edge cases, state-machine boundaries
104136
- - **impact** \u2014 stale references in code/tests/docs/configs/UI after rename/remove
104137
- - **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.
104138
- - **security** \u2014 new endpoints, authZ, input validation, secrets handling, replay/CSRF/injection, cross-tenant isolation
104139
- - **user-journey** \u2014 UX-touching flows: walk through happy path and failure modes as a user
104140
- - **operational readiness** \u2014 observability, alerting, migrations (forward + rollback), feature flags, on-call burden
104141
- - **integration & cross-cutting** \u2014 API contracts between modules, backward-compat of public surfaces, multi-service ordering
104142
- - **test integrity** \u2014 meaningful coverage for the changed behavior; deterministic; no shared-state pollution
104143
- - **performance** \u2014 N+1 queries, hot-path allocation, latency budgets, index coverage
104144
- - **holistic** \u2014 does the PR make sense as a whole? symmetric flows (delete for every create, rollback for every migration)?
104145
- - **subsystem lenses** (invent as the PR demands) \u2014 auth, billing, payments, schema migration, webhooks, secrets, RBAC, multi-tenant isolation, cron/scheduling, etc.
104146
-
104147
- 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.
104148
-
104149
- 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.
104150
-
104151
- \u2705 Right multi-specialist pattern: one assistant turn with N Task tool_use blocks \u2192 wait \u2192 N results arrive together \u2192 aggregate.
104152
- \u274C Wrong multi-specialist pattern: Task(hypothesis A) \u2192 wait for A \u2192 Task(hypothesis B).
104153
-
104154
- 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.
104155
-
104156
- 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:
104157
- - **the absolute \`diffPath\` (and \`incrementalDiffPath\` if available) from step 2's \`${t2("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.
104158
- - **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
104159
- - **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\`.
104160
- - 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."
104161
- - 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.
104162
-
104163
- delegation discipline:
104164
- - do NOT summarize the PR for them (a lossy summary biases toward a validation frame; the raw diff is the source)
104165
- - do NOT hand them a curated reading list (let them discover scope)
104166
- - do NOT pre-shape their output with a finding schema
104167
- - do NOT mention the other lenses (independence is the point \u2014 overlapping findings are a strong signal)`
104168
- )}
103889
+ 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.
104169
103890
 
104170
103891
  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.
104171
103892
 
@@ -104199,7 +103920,7 @@ ${byProfile(
104199
103920
  - **no actionable issues**:
104200
103921
  \`approved: true\`. Body opens with \`> \u2705 No new issues found.\\n\\n\` followed by the PR summary.
104201
103922
 
104202
- ${prSummaryFormat()}`
103923
+ ${PR_SUMMARY_FORMAT}`
104203
103924
  },
104204
103925
  // IncrementalReview shares Review's minimum hypothesis-covering specialist
104205
103926
  // routing and body format, scoped to the incremental delta against the
@@ -104233,8 +103954,9 @@ ${prSummaryFormat()}`
104233
103954
 
104234
103955
  The remaining open threads feed step 8's dedup filter \u2014 anything already flagged and unchanged by the new commits should not be re-raised. The rolling PR summary snapshot is the durable record of retire activity; you don't need to surface it in the review body.
104235
103956
 
104236
- ${byProfile(
104237
- `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.**
103957
+ 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.**
103958
+
103959
+ 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).
104238
103960
 
104239
103961
  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.
104240
103962
 
@@ -104255,50 +103977,7 @@ ${byProfile(
104255
103977
  - 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.
104256
103978
  - ask for findings with file paths and NEW line numbers from the full PR diff so you can validate and anchor them.
104257
103979
 
104258
- 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.`,
104259
- `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.**
104260
-
104261
- if the incremental changes are **genuinely trivial**, skip specialists entirely and jump to step 10's non-substantive path (do NOT submit a review).
104262
-
104263
- "Genuinely trivial" (skip): formatting/comment tweaks, import reordering, lockfile regen, mechanical rename of import paths, whitespace-only.
104264
- "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.
104265
- When unsure, treat as non-trivial.
104266
-
104267
- 6. **specialist decision \u2014 minimum hypothesis coverage**.
104268
-
104269
- After full-diff coverage and triage, identify the load-bearing questions about the incremental changes that you still cannot resolve confidently yourself. A specialist hypothesis is load-bearing only when its answer could yield an actionable new finding that changes the review disposition and warrants independent investigation, and falsifiable only when the specialist can return evidence that supports or refutes it. Generic requests for extra confidence, polish, or "another look" do not qualify.
104270
-
104271
- Route the **minimum number of \`${REVIEWER_AGENT_NAME}\` specialists** needed to cover those unresolved hypotheses. Most incremental reviews need **0 or 1**, especially thread-reply re-reviews:
104272
- - dispatch 0 when you can resolve every disposition-changing question directly
104273
- - dispatch 1 when exactly one falsifiable, load-bearing hypothesis warrants independent investigation
104274
- - dispatch 2+ in parallel when multiple orthogonal load-bearing hypotheses remain, or when the user explicitly requests an exhaustive or multi-angle review
104275
-
104276
- **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.
104277
-
104278
- The primary reviewer remains responsible for reading the complete raw full diff plus the incremental 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.
104279
-
104280
- Specialist hypotheses can draw on Review mode's themed or subsystem framings, but every dispatch must turn the framing into one falsifiable question with explicit scope boundaries.
104281
-
104282
- 7. **dispatch specialists (only if step 6 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.
104283
-
104284
- \u2705 Right multi-specialist pattern: one assistant turn with N Task tool_use blocks \u2192 wait \u2192 N results arrive together \u2192 aggregate.
104285
- \u274C Wrong multi-specialist pattern: Task(hypothesis A) \u2192 wait for A \u2192 Task(hypothesis B).
104286
-
104287
- You can also include your own \`read\` / \`grep\` / \`webfetch\` calls in the SAME turn as the parallel \`${REVIEWER_AGENT_NAME}\` dispatches.
104288
-
104289
- 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:
104290
- - **the absolute diff path(s) from step 2's \`${t2("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.
104291
- - **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
104292
- - **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.
104293
- - if the lens touches external contracts, instruct the subagent to verify load-bearing claims via web search and quote source URLs.
104294
- - ask the subagent to report findings with file paths and NEW line numbers from the full PR diff so you can validate and anchor them. you must still read the complete incremental and full diff scope yourself.
104295
-
104296
- delegation discipline:
104297
- - do NOT summarize the changes for them (a lossy summary biases toward a validation frame; the raw diff is the source)
104298
- - do NOT hand them a curated reading list (let them discover scope)
104299
- - do NOT pre-shape their output with a finding schema
104300
- - do NOT mention the other lenses (independence is the point)`
104301
- )}
103980
+ 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.
104302
103981
 
104303
103982
  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 \`${t2("list_pull_request_reviews")}\` in step 4) and run \`git diff <prior-review-sha>..HEAD\` to isolate the lines added since that review.
104304
103983
 
@@ -104321,7 +104000,7 @@ ${byProfile(
104321
104000
  - ELSE IF INFORMATIONAL OBSERVATIONS (mergeable as-is, but worth surfacing \u2014 e.g. prior feedback addressed cleanly with one minor stale doc reference, or a noteworthy positive observation): call \`${t2("create_pull_request_review")}\` with \`approved: true\`, NO inline comments, and the review body. body opens with \`> \u2705 No new issues found.\\n\\n\` (or similar friendly green opener), followed by the PR summary using the default format below. If a point is concrete enough to anchor to a line, downgrade the whole review to "minor suggestions only" (\`approved: false\`) instead \u2014 the \u2705 signals "no action needed", which contradicts an actionable anchor.
104322
104001
  - ELSE IF NO NEW ISSUES, SUBSTANTIVE CHANGES (new functionality, behavior changes, or fixes to prior review feedback): call \`${t2("create_pull_request_review")}\` to create a PR review. If all previous reviews have been properly addressed and no new issues were discovered, set \`approved: true\`. body opens with \`> \u2705 No new issues found.\\n\\n\`, followed by the PR summary using the default format below.
104323
104002
 
104324
- ${prSummaryFormat()}`
104003
+ ${PR_SUMMARY_FORMAT}`
104325
104004
  },
104326
104005
  {
104327
104006
  name: "Plan",
@@ -104425,7 +104104,8 @@ function getUnsubmittedReview(toolState, expectsReviewOutput2 = toolState.hadPro
104425
104104
  if (!expectsReviewOutput2) return null;
104426
104105
  if (mode === "Review") return toolState.review ? null : "Review";
104427
104106
  if (mode === "IncrementalReview") {
104428
- return toolState.review || toolState.finalSummaryWritten ? null : "IncrementalReview";
104107
+ const delivered = toolState.review || toolState.finalSummaryWritten || toolState.standaloneCommentId !== void 0;
104108
+ return delivered ? null : "IncrementalReview";
104429
104109
  }
104430
104110
  return null;
104431
104111
  }
@@ -160437,6 +160117,9 @@ function CreateCommentTool(ctx) {
160437
160117
  });
160438
160118
  ctx.toolState.wasUpdated = true;
160439
160119
  log.info(`\xBB created comment ${result.data.id}`);
160120
+ if (issueNumber === ctx.payload.event.issue_number) {
160121
+ ctx.toolState.standaloneCommentId = result.data.id;
160122
+ }
160440
160123
  if (commentType === "Plan") {
160441
160124
  if (result.data.node_id) {
160442
160125
  await patchWorkflowRunFields(ctx, { planCommentNodeId: result.data.node_id });
@@ -160626,6 +160309,14 @@ function ReportProgressTool(ctx) {
160626
160309
  description: 'Share progress on the associated GitHub issue/PR. The first call creates a comment; subsequent calls update it in place. Example: `report_progress({ body: "Implemented the auth check and added tests." })`. Call this at the end of every run with a brief final summary (1-3 sentences) unless the mode guidance instructs otherwise. The current task list is automatically appended in a collapsible section \u2014 do not restate individual steps.',
160627
160310
  parameters: ReportProgress,
160628
160311
  execute: execute(async (params) => {
160312
+ if (ctx.toolState.standaloneCommentId !== void 0 && !params.target_plan_comment) {
160313
+ ctx.toolState.lastProgressBody = params.body;
160314
+ return {
160315
+ success: true,
160316
+ action: "skipped",
160317
+ message: `standalone comment ${ctx.toolState.standaloneCommentId} already delivered this run's answer to this target \u2014 that comment IS the deliverable, so this call was a no-op rather than posting a second one. Nothing further is needed.`
160318
+ };
160319
+ }
160629
160320
  let body = params.body;
160630
160321
  if (!params.target_plan_comment && ctx.toolState.todoTracker) {
160631
160322
  ctx.toolState.todoTracker.cancel();
@@ -160980,10 +160671,7 @@ var CreatePullRequestReview = type({
160980
160671
  // running. required-ness is the only pressure that empirically held.
160981
160672
  // see wiki/review-approval.md.
160982
160673
  body: type.string.describe(
160983
- byProfile(
160984
- `The review summary, plus any concern that has no diff line to anchor to. Your mode guidance defines its structure. Feedback that does anchor to a line goes in the 'comments' array. ALWAYS pass this parameter \u2014 pass an empty string "" when approving with no commentary, never omit it.`,
160985
- `1-2 sentence high-level summary with urgency level, critical callouts, and feedback about code outside the diff. Specific feedback on diff lines goes in 'comments' array. ALWAYS pass this parameter \u2014 pass an empty string "" when approving with no commentary, never omit it.`
160986
- )
160674
+ `The review summary, plus any concern that has no diff line to anchor to. Your mode guidance defines its structure. Feedback that does anchor to a line goes in the 'comments' array. ALWAYS pass this parameter \u2014 pass an empty string "" when approving with no commentary, never omit it.`
160987
160675
  ),
160988
160676
  approved: type.boolean.describe(
160989
160677
  "Set to true to submit as an approval. Use for `> \u2705 No new issues found.` reviews where the PR is mergeable as-is and nothing in the body warrants code changes \u2014 approving also suppresses the Fix-button footer affordance so users don't dispatch a fix run on non-actionable feedback. Reserve approved: false for `> \u2139\uFE0F ...` (minor suggestions inline), `> [!IMPORTANT]` (recommended changes), and `> [!CAUTION]` (critical) reviews. Defaults to false (comment-only review). Mutually exclusive with request_changes. Approval is REJECTED while any unresolved Pullfrog review thread remains open on the PR (not just the latest commit's diff): resolve the threads the current code addresses (reply + resolve_review_thread) first, or submit a non-approving review if a real issue remains."
@@ -161019,10 +160707,7 @@ function CreatePullRequestReviewTool(ctx) {
161019
160707
  return tool({
161020
160708
  name: "create_pull_request_review",
161021
160709
  mutates: true,
161022
- description: 'Submit a review for an existing pull request. Example: `create_pull_request_review({ pull_number: 1234, body: "LGTM", approved: true, comments: [{ path: "src/api.ts", line: 42, body: "nit: rename" }] })`. Each call creates a permanent, visible review on the PR \u2014 NEVER submit test or diagnostic reviews. Set `approved: true` to approve, `request_changes: true` to submit a blocking review, or neither for a plain comment review (the three are mutually exclusive). Reviews with no body AND no comments are silently skipped (nothing to post). ' + byProfile(
161023
- "Feedback that anchors to a specific line goes in the 'comments' array with file paths and line numbers. The 'body' carries the review summary plus any concern with no line to anchor to; your mode guidance defines its structure. ",
161024
- "IMPORTANT: 95%+ of feedback should be in 'comments' array with file paths and line numbers. Only use 'body' for a 1-2 sentence summary with urgency and critical callouts. "
161025
- ) + `Use 'suggestion' to propose replacement code - MUST preserve exact indentation of original code. The first submission may error once with a one-time diff-coverage nudge listing unread TOC regions \u2014 retry with the same arguments and the pre-flight will not block again. Example replacing lines 42-44 (3 lines) with 5 lines: { path: 'src/api.ts', start_line: 42, line: 44, suggestion: ' const result = await fetch(url);\\n if (!result.ok) {\\n log.error(result.status);\\n throw new Error("request failed");\\n }' } CONSTRAINT: Inline comments can ONLY target files and lines that appear in the PR diff. Comments anchored outside a diff hunk are dropped automatically (with a note appended to the review body) \u2014 the rest of the review still posts.`,
160710
+ description: `Submit a review for an existing pull request. Example: \`create_pull_request_review({ pull_number: 1234, body: "LGTM", approved: true, comments: [{ path: "src/api.ts", line: 42, body: "nit: rename" }] })\`. Each call creates a permanent, visible review on the PR \u2014 NEVER submit test or diagnostic reviews. Set \`approved: true\` to approve, \`request_changes: true\` to submit a blocking review, or neither for a plain comment review (the three are mutually exclusive). Reviews with no body AND no comments are silently skipped (nothing to post). Feedback that anchors to a specific line goes in the 'comments' array with file paths and line numbers. The 'body' carries the review summary plus any concern with no line to anchor to; your mode guidance defines its structure. Use 'suggestion' to propose replacement code - MUST preserve exact indentation of original code. The first submission may error once with a one-time diff-coverage nudge listing unread TOC regions \u2014 retry with the same arguments and the pre-flight will not block again. Example replacing lines 42-44 (3 lines) with 5 lines: { path: 'src/api.ts', start_line: 42, line: 44, suggestion: ' const result = await fetch(url);\\n if (!result.ok) {\\n log.error(result.status);\\n throw new Error("request failed");\\n }' } CONSTRAINT: Inline comments can ONLY target files and lines that appear in the PR diff. Comments anchored outside a diff hunk are dropped automatically (with a note appended to the review body) \u2014 the rest of the review still posts.`,
161026
160711
  parameters: CreatePullRequestReview,
161027
160712
  execute: execute(
161028
160713
  async ({ pull_number, body, approved, request_changes, commit_id, comments = [] }) => {
@@ -164705,10 +164390,32 @@ function SelectModeTool(ctx) {
164705
164390
  description: 'Select a mode and receive step-by-step guidance on how to handle the task. Call this to understand the best workflow for the current mode. Example: `select_mode({ mode: "Review" })` or `select_mode({ mode: "Plan", issue_number: 1234 })`.',
164706
164391
  parameters: SelectModeParams,
164707
164392
  execute: execute(async (params) => {
164708
- if (ctx.toolState.selectedMode) {
164393
+ const guidanceFor = (mode) => {
164394
+ const base = buildOrchestratorGuidance(ctx, mode);
164395
+ if (!SUMMARY_MODES.has(mode.name)) return base;
164396
+ const addendum = buildSummaryAddendum(t2, ctx);
164397
+ if (addendum.length === 0) return base;
164709
164398
  return {
164710
- error: `mode already selected: "${ctx.toolState.selectedMode}". mode selection is final and cannot be changed. complete your current workflow within this mode.`
164399
+ ...base,
164400
+ orchestratorGuidance: `${base.orchestratorGuidance}
164401
+
164402
+ ${addendum}`,
164403
+ summaryFilePath: ctx.toolState.summaryFilePath
164711
164404
  };
164405
+ };
164406
+ if (ctx.toolState.selectedMode) {
164407
+ const active = ctx.toolState.selectedMode;
164408
+ const error49 = `mode already selected: "${active}". mode selection is final \u2014 this call changed NOTHING and you are still in "${active}". Do not proceed as though you switched modes. "${active}" guidance is repeated below; finish its steps. If the task genuinely belongs to another mode, do what you can within "${active}" and say so in your final summary.`;
164409
+ const activeMode = resolveMode(ctx.modes, active);
164410
+ if (!activeMode) return { error: error49 };
164411
+ if (activeMode.name === "Plan" && ctx.toolState.existingPlanCommentId !== void 0) {
164412
+ return {
164413
+ ...buildOrchestratorGuidance(ctx, activeMode, overrides.PlanEdit),
164414
+ previousPlanBody: ctx.toolState.previousPlanBody,
164415
+ error: error49
164416
+ };
164417
+ }
164418
+ return { ...guidanceFor(activeMode), error: error49 };
164712
164419
  }
164713
164420
  const modeName = params.mode;
164714
164421
  const selectedMode = resolveMode(ctx.modes, modeName);
@@ -164737,18 +164444,7 @@ function SelectModeTool(ctx) {
164737
164444
  }
164738
164445
  }
164739
164446
  }
164740
- const summaryAddendum = SUMMARY_MODES.has(selectedMode.name) ? buildSummaryAddendum(t2, ctx) : "";
164741
- const base = buildOrchestratorGuidance(ctx, selectedMode);
164742
- if (summaryAddendum.length > 0) {
164743
- return {
164744
- ...base,
164745
- orchestratorGuidance: `${base.orchestratorGuidance}
164746
-
164747
- ${summaryAddendum}`,
164748
- summaryFilePath: ctx.toolState.summaryFilePath
164749
- };
164750
- }
164751
- return base;
164447
+ return guidanceFor(selectedMode);
164752
164448
  })
164753
164449
  });
164754
164450
  }
@@ -165955,10 +165651,7 @@ You execute tasks directly using your native tools and the ${pullfrogMcpName} MC
165955
165651
 
165956
165652
  Call \`${t2("select_mode")}\` with the appropriate mode name. This returns **your workflow** \u2014 a step-by-step playbook you must follow.
165957
165653
 
165958
- ${byProfile(
165959
- `**Work through the returned steps in order.** It is the house playbook for this kind of task and it encodes what usually matters. Where the task in front of you genuinely calls for something better, do that instead and say why in your final summary.`,
165960
- `**Follow the returned guidance as your primary instruction set.** Do not improvise \u2014 the guidance defines the exact steps.`
165961
- )}
165654
+ **Work through the returned steps in order.** It is the house playbook for this kind of task and it encodes what usually matters. Where the task in front of you genuinely calls for something better, do that instead and say why in your final summary.
165962
165655
 
165963
165656
  Available modes:
165964
165657
  ${ctx.modes.map((m) => `- "${m.name}": ${m.description}`).join("\n")}
@@ -165996,18 +165689,9 @@ You are a diligent, detail-oriented, no-nonsense software engineering agent. You
165996
165689
 
165997
165690
  ## Persona
165998
165691
 
165999
- ${byProfile(
166000
- `- Careful, to-the-point, and kind. You only say things you know to be true.
166001
- - Write code that reads like the surrounding code: match its comment density, naming, and idiom.
166002
- - Do not break up sentences with hyphens. Use emdashes. Use backticks liberally for inline code (e.g. \`z.string()\`) even in headers.`,
166003
- `- Careful, to-the-point, and kind. You only say things you know to be true.
166004
- - Do not break up sentences with hyphens. Use emdashes.
166005
- - Strong bias toward minimalism: no dead code, no premature abstractions, no speculative features, and no comments that merely restate what the code does.
166006
- - Code is focused, elegant, and production-ready.
166007
- - Do not add unnecessary comments, tests, or documentation unless explicitly prompted to do so.
166008
- - Adapt your writing style to match existing patterns in the codebase (commit messages, PR descriptions, code comments) while never being unprofessional.
166009
- - Use backticks liberally for inline code (e.g. \`z.string()\`) even in headers.`
166010
- )}
165692
+ - Careful, to-the-point, and kind. You only say things you know to be true.
165693
+ - Write code that reads like the surrounding code: match its comment density, naming, and idiom. Match its style, not its defects \u2014 a neighbour's loose assertion or bare \`any\` is not a pattern to copy.
165694
+ - Do not break up sentences with hyphens. Use emdashes. Use backticks liberally for inline code (e.g. \`z.string()\`) even in headers.
166011
165695
 
166012
165696
  ## Environment
166013
165697
 
@@ -166027,10 +165711,7 @@ MCP servers provide tools you can call. Inspect your available MCP servers at st
166027
165711
 
166028
165712
  ### Git
166029
165713
 
166030
- ${byProfile(
166031
- `Use \`${t2("git")}\` for local git commands (status, log, add, commit, checkout, branch, merge, etc.). When reviewing a PR, the diffPath returned by \`${t2("checkout_pr")}\` is authoritative \u2014 read it rather than re-deriving the diff. To diff a branch against its base yourself, use \`git diff --merge-base <base>\`; the tool rejects the symmetric forms and tells you what to use instead. Note the git tool runs git directly, so \`$(\u2026)\` subshells do not interpolate. For operations requiring remote authentication, use the dedicated MCP tools:`,
166032
- `Use \`${t2("git")}\` for local git commands (status, log, add, commit, checkout, branch, merge, etc.). When reviewing a PR, do NOT re-derive the PR diff via \`git diff\` \u2014 the diffPath returned by \`${t2("checkout_pr")}\` is authoritative. If you ever do need to diff a branch against its base via \`${t2("git")}\`, use \`git diff --merge-base <base>\` (single call, includes uncommitted edits) or three-dot \`git diff <base>...HEAD\` (committed-only). Do NOT use bare \`<base>\` or two-dot \`<base>..HEAD\` \u2014 those are symmetric and include the *inverse* of every commit landed on \`<base>\` since your branch forked (the tool will reject those forms when the divergence is detected). Do NOT try \`$(git merge-base \u2026)\` subshells \u2014 the git tool runs git directly with no shell interpolation. \`git log\` and \`git diff --stat\` are fine for commit-range overview; \`git diff\` / \`git diff --cached\` are fine for inspecting your *own* uncommitted changes. For operations requiring remote authentication, use the dedicated MCP tools:`
166033
- )}
165714
+ Use \`${t2("git")}\` for local git commands (status, log, add, commit, checkout, branch, merge, etc.). When reviewing a PR, the diffPath returned by \`${t2("checkout_pr")}\` is authoritative \u2014 read it rather than re-deriving the diff. To diff a branch against its base yourself, use \`git diff --merge-base <base>\`; the tool rejects the symmetric forms and tells you what to use instead. Note the git tool runs git directly, so \`$(\u2026)\` subshells do not interpolate. For operations requiring remote authentication, use the dedicated MCP tools:
166034
165715
  - \`${t2("push_branch")}\` - push current or specified branch
166035
165716
  - \`${t2("git_fetch")}\` - fetch refs from remote
166036
165717
  - \`${t2("checkout_pr")}\` - checkout a PR branch (fetches and configures push for forks)
@@ -166069,31 +165750,15 @@ ${getStandaloneModeInstructions(ctx.payload.event.trigger, t2, ctx.outputSchema)
166069
165750
 
166070
165751
  ## Workflow
166071
165752
 
166072
- ${byProfile(
166073
- `### Efficiency
165753
+ ### Efficiency
166074
165754
 
166075
- Trust tool results \u2014 re-verify only after an actual error, or right before \`${t2("push_branch")}\`, which rejects a dirty tree (tests you ran earlier often leave untracked output). Issue independent tool calls together in one turn rather than one per turn; sequence anything that depends on prior output. Commands run synchronously, so never \`sleep\` to wait for one.`,
166076
- `### Efficiency
165755
+ Trust tool results \u2014 re-verify only after an actual error, or right before \`${t2("push_branch")}\`, which rejects a dirty tree (tests you ran earlier often leave untracked output). Commands run synchronously, so never \`sleep\` to wait for one.
166077
165756
 
166078
- Trust the tools \u2014 do not repeatedly verify file contents or git status after operations. If a tool reports success, proceed to the next step. Only verify if you encounter an actual error. Exception: right before \`${t2("push_branch")}\`, ensure the working tree is clean \u2014 that tool rejects dirty trees, and tests you ran earlier often leave untracked output.
165757
+ ### Batch your tool calls
166079
165758
 
166080
- ### Parallel tool execution
165759
+ If you can emit multiple tool calls in a single assistant turn, do it \u2014 aggressively, for every set of calls that does not depend on the others. Reading five files after a grep, running several greps, a glob plus a grep plus a read, querying several MCP tools: all one turn. The dominant waste is grep \u2192 read \u2192 read \u2192 read across separate turns when one round trip would do, and each extra turn re-sends your whole context, so turn count is what the run costs.
166081
165760
 
166082
- For maximum efficiency, whenever you need to perform multiple independent operations, invoke all relevant tools simultaneously in a single assistant turn rather than sequentially. The dominant failure mode is grep \u2192 read \u2192 read \u2192 read \u2192 read across separate turns when one round trip would do. Always parallelize when calls are independent:
166083
- - reading multiple files (especially after a grep returns candidates)
166084
- - multiple greps with different patterns
166085
- - glob + grep + read combos
166086
- - listing multiple directories
166087
- - inspecting multiple MCP tools or resources
166088
-
166089
- Do NOT parallelize operations that depend on prior output (e.g. create a file then read it), or ordered stateful mutations. Edits are not parallelizable \u2014 sequence those normally.
166090
-
166091
- Emit multiple \`tool_use\` blocks in the same assistant message for independent calls \u2014 the runtime executes them concurrently. Do not wait for one tool result before issuing the next independent call.
166092
-
166093
- ### Command execution
166094
-
166095
- Never use \`sleep\` to wait for commands to complete. Commands run synchronously \u2014 when the shell tool returns, the command has finished.`
166096
- )}
165761
+ Sequence only what genuinely needs prior output, and keep edits and ordered mutations sequential.
166097
165762
 
166098
165763
  ### Commenting style
166099
165764
 
@@ -166103,8 +165768,7 @@ Never \`@\`-mention a GitHub username unless that exact handle appears in the us
166103
165768
 
166104
165769
  When embedding images (e.g. uploaded screenshots) in comments or PR bodies, always use markdown image syntax: \`![description](url)\`. Never paste a naked URL \u2014 it will not render as an image.
166105
165770
 
166106
- ${byProfile(
166107
- `### Progress reporting
165771
+ ### Progress reporting
166108
165772
 
166109
165773
  **Your raw assistant messages are never delivered** \u2014 they exist only in the run logs. Anything the user is meant to see (an answer to a question, a mention reply, a result) MUST go through \`report_progress\` or another ${pullfrogMcpName} write tool.
166110
165774
 
@@ -166112,25 +165776,7 @@ Keep an internal task list from your mode's steps; the system renders it to the
166112
165776
 
166113
165777
  ### If you get stuck
166114
165778
 
166115
- Don't silently fail or produce incomplete work. Report what blocked you and what would unblock it, specifically enough to act on. If the same approach has failed repeatedly, step back and say what you tried and what alternatives exist rather than repeating it.`,
166116
- `### Progress reporting
166117
-
166118
- **Task list**: at the start of every run, create an internal task list based on the steps in your current mode. Update it as you complete each step. The system automatically renders this list to the progress comment \u2014 you do not need to call \`report_progress\` for this.
166119
-
166120
- **Your raw assistant messages are never delivered** \u2014 they exist only in the run logs. Anything the user is meant to see (an answer to a question, a mention reply, a result) MUST go through \`report_progress\` (or another ${pullfrogMcpName} write tool). Do not rely on returning the answer as plain text \u2014 the harness makes a best-effort attempt to recover it into the progress comment, but that is a safety net, not a substitute for calling \`report_progress\`.
166121
-
166122
- **\`report_progress\`**: call this exactly once at the end of every run with a brief final summary (1-3 sentences) unless the mode guidance instructs otherwise or a standalone comment on the current target is the task's sole requested deliverable. Never call it for intermediate status updates (e.g., "Checking for changes...", "Starting review...") \u2014 the task list handles live progress automatically. Calling \`report_progress\` replaces the task list with your summary and preserves the current task list in a collapsible section. Keep the summary concise \u2014 do not repeat what the task list already shows. Focus on the outcome (what was accomplished, links to artifacts) rather than listing individual steps. If something failed, include the tool's error text even when that makes the summary longer.
166123
-
166124
- Never use \`create_issue_comment\` for task progress or for the answer that \`report_progress\` should deliver. Use it only when the task explicitly requests a separate standalone comment or a comment on a different target. Skip \`report_progress\` only when a standalone comment on the current target is the task's sole requested deliverable; successful-run cleanup then removes the progress chrome. Plan output (initial post AND revisions) goes through \`report_progress\` \u2014 see the Plan mode guidance for details.
166125
-
166126
- ### If you get stuck
166127
-
166128
- If you cannot complete a task due to missing information, ambiguity, or an unrecoverable error:
166129
- 1. Do not silently fail or produce incomplete work
166130
- 2. Post a comment via ${pullfrogMcpName} explaining what blocked you and what information or action would unblock you
166131
- 3. Make your blocker comment specific and actionable (e.g., "I need the database schema to proceed" not "I'm stuck")
166132
- 4. If you've attempted the same fix or approach 3 or more times without progress, step back and reconsider. Report what you tried, why it failed, and what alternative approaches exist \u2014 rather than repeating failed attempts.`
166133
- )}
165779
+ Don't silently fail or produce incomplete work. Report what blocked you and what would unblock it, specifically enough to act on. If the same approach has failed repeatedly, step back and say what you tried and what alternatives exist rather than repeating it.
166134
165780
 
166135
165781
  ### Agent context files
166136
165782
 
@@ -166926,6 +166572,7 @@ async function mintProxyKey(ctx) {
166926
166572
  }
166927
166573
  }
166928
166574
  async function buildProxyTokenHeaders(ctx) {
166575
+ const fundingSource = ctx.oss ? "oss" : "router";
166929
166576
  if (ctx.oidcCredentials) {
166930
166577
  const creds = ctx.oidcCredentials;
166931
166578
  const oidcToken = await op(() => fetchIdTokenFromStash(creds), {
@@ -166933,11 +166580,17 @@ async function buildProxyTokenHeaders(ctx) {
166933
166580
  retries: [1e3, 2e3],
166934
166581
  bail: (error49) => !isTransientTokenError(error49)
166935
166582
  })();
166936
- return { Authorization: `Bearer ${oidcToken}` };
166583
+ return {
166584
+ Authorization: `Bearer ${oidcToken}`,
166585
+ "X-Pullfrog-Funding-Source": fundingSource
166586
+ };
166937
166587
  }
166938
166588
  if (isLocalApiUrl()) {
166939
166589
  log.info(`\xBB proxy: dev bypass (x-dev-repo) for ${ctx.repo.owner}/${ctx.repo.name}`);
166940
- return { "x-dev-repo": `${ctx.repo.owner}/${ctx.repo.name}` };
166590
+ return {
166591
+ "x-dev-repo": `${ctx.repo.owner}/${ctx.repo.name}`,
166592
+ "X-Pullfrog-Funding-Source": fundingSource
166593
+ };
166941
166594
  }
166942
166595
  return null;
166943
166596
  }
@@ -166948,7 +166601,11 @@ async function resolveProxyModel(ctx) {
166948
166601
  log.warning("\xBB proxy requested but no OIDC credentials available \u2014 skipping");
166949
166602
  return;
166950
166603
  }
166951
- const key = await mintProxyKey({ oidcCredentials: ctx.oidcCredentials, repo: ctx.repo });
166604
+ const key = await mintProxyKey({
166605
+ oidcCredentials: ctx.oidcCredentials,
166606
+ repo: ctx.repo,
166607
+ oss: ctx.oss
166608
+ });
166952
166609
  if (!key) return;
166953
166610
  process.env.OPENROUTER_API_KEY = key;
166954
166611
  core8.setSecret(key);
@@ -167858,7 +167515,6 @@ function logRunStartup(ctx) {
167858
167515
  log.info(`\xBB push: ${ctx.payload.push}`);
167859
167516
  log.info(`\xBB shell: ${ctx.payload.shell}`);
167860
167517
  log.info(`\xBB timeout: ${resolveTimeoutForLog(ctx.payload.timeout)}`);
167861
- log.info(`\xBB prompt: ${promptProfile()}`);
167862
167518
  }
167863
167519
 
167864
167520
  // utils/todoTracking.ts
@@ -169496,7 +169152,7 @@ async function runCli4(input) {
169496
169152
  }
169497
169153
 
169498
169154
  // cli.ts
169499
- var VERSION10 = "0.1.43";
169155
+ var VERSION10 = "0.1.45";
169500
169156
  var bin = basename2(process.argv[1] || "");
169501
169157
  var PROG = bin === "pf" || bin === "pullfrog" ? bin : "pullfrog";
169502
169158
  var rawArgs = process.argv.slice(2);