* agent & model refactor with ASKPASS git auth, UI restructure, clerk v7
Made-with: Cursor
* fix stale agent/effort refs, add tests for askpass + model resolution
- reviewCleanup.ts: payload.agent -> payload.model, remove effort
- selectMode.ts PlanEdit: remove delegation/subagent/effort references
- pullfrog.yml.ts: update env vars (drop GOOGLE_API_KEY/CURSOR_API_KEY,
add GOOGLE_GENERATIVE_AI_API_KEY/XAI_API_KEY/MOONSHOT_API_KEY/OPENCODE_API_KEY)
- FlagsSettings/RepoInstructionsSection: remove stale effort/timeout copy
- new: gitAuthServer.test.ts (10 tests — lifecycle, token delivery, tamper detection, script gen)
- new: agent.test.ts (4 tests — default opentoad, AGENT_OVERRIDE, invalid override)
- new: models.test.ts (19 tests — parseModel, resolution, registry invariants)
- update models.dev snapshot
Made-with: Cursor
* fix changed-agents.sh to filter legacy agent files from CI matrix
legacy agent files (claude.ts, codex.ts, etc.) are @ts-nocheck and not
exported from index.ts. changed-agents.sh now reads index.ts imports to
build the active agent set and treats changes to inactive files as
non-agent changes (opentoad canary only).
Made-with: Cursor
* remove MCP file tools, old agent harnesses, and obsolete security tests
ASKPASS-based git auth makes the old MCP file tool security layer unnecessary:
- token never in subprocess env, so symlink/gitattributes/hook attacks can't exfiltrate it
- agents now use native file tools (OpenCode builtin read/edit)
deleted:
- action/mcp/file.ts (file_read, file_write, file_edit, file_delete, list_directory)
- action/mcp/index.ts (dead re-export)
- agent harnesses: claude.ts, codex.ts, cursor.ts, gemini.ts, opencode.ts
- opencode-runner.ts (inlined into opentoad.ts)
- security tests that validated MCP file tool restrictions
- commented-out three-step review flow (~300 lines)
- sanitizeSchema/wrapSchema dead code from mcp/shared.ts
- OPENCODE_MODEL_MINI/MAX env vars (effort-level model overrides removed)
updated test prompts to use generic file ops instead of MCP tool names.
restored pkg-json-scripts + requirements-txt-attack (test --ignore-scripts defense).
Made-with: Cursor
* bump actions/checkout v4 → v6 (node 24)
node 20 actions deprecated june 2, 2026.
Made-with: Cursor
* temporarily disable fail-fast on agnostic tests to debug checkout@v6
Made-with: Cursor
* re-enable fail-fast on agnostic tests
Made-with: Cursor
* fix test token mismatch: mint OIDC tokens scoped to target repo
CI tests override GITHUB_REPOSITORY to pullfrog/test-repo but inherit
the runner's GITHUB_TOKEN (scoped to pullfrog/app), causing 401s on
every run-context fetch. Clear GITHUB_TOKEN in the test subprocess so
ensureGitHubToken() mints a properly scoped token via OIDC.
Also centralizes the default GITHUB_REPOSITORY in runAgentStreaming
instead of repeating it in every test file, and fixes preview-cleanup
to remove workers from all queues (not just name-matching ones).
Made-with: Cursor
* fix ensureGitHubToken to try OIDC when app credentials are absent
ensureGitHubToken only attempted token minting when GITHUB_APP_ID and
GITHUB_PRIVATE_KEY were set. In CI, OIDC is available but app creds
aren't exposed — so the guard prevented minting entirely.
Made-with: Cursor
* dead code cleanup: remove remnants of deleted agents, file tools, effort system
remove unused @anthropic-ai/claude-agent-sdk and @openai/codex-sdk deps,
orphaned file-tool security tests, dead GEMINI_MODEL passthrough, stale
opencode-runner wiki refs, deleted test file references, and MCP file tool
docs. rename docs/effort → docs/models. fix vitest setup: move dotenv to
globalSetup (runs once before forks instead of per-file, 19s → 200ms).
Made-with: Cursor
* address review feedback: remove dead code, update stale references
- remove AGENT_OVERRIDE (only opentoad exists)
- remove shellToolName plumbing (always restricted shell)
- bump action version to 0.0.179
- remove CURSOR_API_KEY from all workflows/configs
- remove OPENCODE_MODEL_MINI/MAX from workflows/docs
- delete wiki/effort.md, rewrite docs/effort.mdx as "Models"
- rewrite wiki/modes.md: orchestrator/subagent → single agent
- simplify flag system: drop builtin flag extraction (debug, effort,
timeout, agent), keep custom flag replacement only
- reserve all legacy flag names to prevent custom flag conflicts
Made-with: Cursor
* regenerate lockfile after removing claude-agent-sdk and codex-sdk
Made-with: Cursor
* fix import ordering, add lockfile check to pre-push hook
Made-with: Cursor
* remove dead debug payload field, stale packageExtensions
Made-with: Cursor
* merge proc-sandbox and token-exfil into a single test
proc-sandbox and token-exfil were duplicative — both tested that
SANDBOX_TEST_TOKEN couldn't be exfiltrated. consolidated into
token-exfil with shell:restricted (which actually exercises filterEnv)
and the /proc attack vector hints from proc-sandbox.
Made-with: Cursor
* fix wiki adversarial.md to match actual tokenExfil validator
Made-with: Cursor
* add mode instructions and restructure dashboard sidebar
- add modeInstructions JSONB field to Repo model for per-mode user instructions
- thread modeInstructions through settings API, run-context API, RepoSettings, ToolContext, and selectMode runtime
- merge user-defined mode instructions with hardcoded orchestrator guidance, with IncrementalReview inheriting from Review
- reduce visible built-in modes from 7 to 4 (Build, Review, Plan, Fix) with editable Instructions textareas
- add TRIGGERS group header to sidebar above Mentions, Pull requests, Issues
- add wiki/modes.md documenting triggers and modes conceptual model
Made-with: Cursor
* fix leaping comment deletion and address review feedback
- wrap post-createReview operations in try/finally so deleteProgressComment
runs even when updateReview or reportReviewNodeId throws
- add parseModeInstructions runtime guard to filter non-string values
from the JSONB field before passing to buildOrchestratorGuidance
- add useEffect sync for localInstructions when props change
- guard onBlur to skip save when instructions haven't changed
- update wiki/modes.md to reflect V2 is implemented (no longer "proposed")
Made-with: Cursor
* harden review cleanup, fix type cast, stabilize mode instructions state
- wrap deleteProgressComment in try/catch inside finally to prevent masking original errors
- replace `as Record<string,string>` cast with runtime parseModeInstructions + useMemo
- fix wiki dual-prompt table to reflect mode.prompt fallback status
Made-with: Cursor
* fix wiki tense and heading ambiguity from PR review
Made-with: Cursor
* fix review "edited" badge by using pending review + submit flow
create review as PENDING first (no event/body), build the footer with
the now-known review ID, then submitReview with the full body. single
atomic publish — no updateReview edit needed.
Made-with: Cursor
* add post-agent follow-up re-review dispatch
After the agent exits, check if PR HEAD moved past the reviewed commit
and dispatch a follow-up re-review. This closes the gap where push
webhooks are suppressed during in-flight reviews.
Made-with: Cursor
* add silent flag to follow-up re-review dispatch
Made-with: Cursor
* restructure dashboard for consistency and clarity
- consolidate tools into single grouped card (was 4 separate cards)
- merge coding + autofix CI into one section
- remove redundant trigger section descriptions
- add bidirectional crosslinks between modes and triggers
- inline instruction links (review/plan/build) into descriptions
- add save status indicators to all sections
- restructure flags with grouped built-in/custom cards
- flatten sidebar (remove dividers and group headers)
- tighten all descriptions
Made-with: Cursor
* update PR screenshots for new dashboard layout
Made-with: Cursor
* extend review context inline instead of dispatching new workflow
when commits are pushed during a review, the agent now handles them
inline: create_pull_request_review detects HEAD movement, returns
instructions to pull and review the incremental diff, and the agent
submits a second review covering only the new changes. this avoids
the cost of spinning up a full new workflow run.
also fixes a bug where reviewedSha was set to the submission HEAD
(current) rather than the checkout HEAD (what was actually reviewed),
which caused commits pushed between checkout and submission to be
silently missed by postReviewCleanup.
the workflow dispatch is kept as a safety net for agent timeout/error.
Made-with: Cursor
* polish dashboard UI: fix debug markers, crosslinks, title consistency, descriptions
- remove all red debug borders/labels and CM component
- remove all inline style={{}} debug outlines from crosslinks
- fix ambiguous crosslinks: Build→"Coding ↓", Plan→"Enrich issues ↓"
- add missing "Edit build instructions ↑" backlink on Auto-address reviews
- normalize card title weight to text-sm font-semibold across all cards
- rename "Default" subcard to "Setup" with broader description
- fix Mentions description to imperative tone
- broaden Flags section description to cover built-in and custom
- remove useless fragments in ModesSection and ToolsSettings
- restructure Agent section: remove ConsoleSection wrappers, add sidebar indent support
Made-with: Cursor
* extract PR quick links as standalone card, consistent with issues
- PR quick links is now its own card under Reviews (was a sub-toggle inside Review PRs disabled state)
- Review PRs OFF sets prCreated="none" instead of auto-falling back to "links"
- Review PRs card hides sub-toggles when disabled (re-review/approve don't apply)
- Both PRs and Issues now have identical Quick links card structure
Made-with: Cursor
* update reviews screenshot with standalone quick links card
Made-with: Cursor
* polish dashboard UI: revert quick links to inline toggles, fix fonts and spacing
- revert standalone PR/issue Quick Links cards back to inline toggles inside
Review PRs and Enrich Issues cards (fixes prCreated state coupling bug)
- restore original font-medium card titles across all trigger/settings cards
- fix sidebar: add CONSOLE heading, remove nested indentation, remove truncation
- right-justify Enrich Issues mode dropdown, group description with label
- move instructions links inline with behavior descriptions
- replace text save indicators with icon spinner/checkmark
- standardize section title spacing, move footer below danger zone
Made-with: Cursor
* fix formatting for biome lint
Made-with: Cursor
* address PR review feedback: cleanup guard, shared util, wiki update
- clear ctx.toolState.review after read to prevent double-execution of postReviewCleanup
- forward authorPermission in safety-net re-review dispatch
- extract parseModeInstructions to utils/schemas/modeInstructions.ts
- update wiki/modes.md: remove stale v1/v2 language, fix dashboard layout
- add typecheck to pre-push hook
Made-with: Cursor
* add action typecheck to pre-push, fix exactOptionalPropertyTypes errors
Made-with: Cursor
* fix duplicate actuallyReviewedSha from rebase
Made-with: Cursor
* remove PR screenshots
Made-with: Cursor
* add label/textarea association for mode instruction accessibility
Made-with: Cursor
---------
Co-authored-by: Colin McDonnell <colinmcd94@gmail.com>
* share GitHub rate limit tracking between the action and the worker
The action now counts all GitHub API requests and captures the latest
`x-ratelimit-remaining`/`x-ratelimit-reset` headers via a global
request hook on every Octokit instance.
On exit, the usage summary is written atomically to a path specified
by `PULLFROG_USAGE_SUMMARY_PATH`. The worker sets this env var before
sandbox execution, reads the file afterward, and feeds the data into
the Durable Object's rate limit state.
This closes the visibility gap where the worker had no insight into
API calls made by the sandboxed action process.
* address review: refactor rate limit state, randomize usage summary path
* track actual rate limit cost using x-ratelimit-remaining delta
* refactor usage summary writing to use onExitSignal API
Replace the monolithic registerUsageSummaryHandler with direct use of
onExitSignal in main.ts and a writeGitHubUsageSummaryToFile utility
in github.ts. This keeps exitHandler.ts as a pure signal handler
registry (from #299) and also writes the summary on normal exit.
* tweak
* unify
* deduplicate stuff
* improve error handling
---------
Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
* add incremental re-review on new PR commits
When new commits are pushed to a PR that Pullfrog has previously reviewed,
automatically perform a focused re-review on only the new changes. Includes
a supersede mechanism to abort stale in-flight reviews on rapid pushes, a
new IncrementalReview mode with incremental diff + prior-feedback awareness,
and a PRReview tracking model so re-review fires for both auto-reviewed and
manually-triggered PRs. Reviews now always submit (APPROVE when clean).
Co-authored-by: Cursor <cursoragent@cursor.com>
* simplify re-review eligibility and add summary to incremental reviews
Remove the path1/path2 distinction for re-review eligibility — now simply
requires prReReview=enabled and a prior Pullfrog review on the PR. Show
the re-review toggle regardless of prCreated setting. Add a top-level
summary body to incremental reviews for consistency with full reviews.
Co-authored-by: Cursor <cursoragent@cursor.com>
* replace superseded polling with server-side in-flight dedup and add prApproveEnabled setting
Made-with: Cursor
* add armstrong cursor command
Made-with: Cursor
* update armstrong
* feat: Pullfrogger game v1 (#378)
* Frogger game basis code (CC0 1.0 Unversal license).
* Initial React port.
* fix props for Sprite.
* fixed context issue in FroggerGame.
* Fixed format.
* Fixed lint issue in FroggerGame.
* Restoring LeapingLoader, using FroggerGame as a new fallback in Suspense.
* feat: Display toast when URL ready.
* Add props constraints on Sprite.
* feat: frog sprite.
* fix: zoom and alignment.
* fix: extract const.
* fix: mv types.
* fix: mv game into index.tsx file.
* fix: replacing deprecated event prop which with key.
* feat: Log sprite.
* feat: turtle sprite.
* Adjusting game colors.
* feat: sprites for the cars.
* rm primitive sprites.
* fix: bulldozer sprite position.
* Adjusting colors.
* Shape constraints.
* rm original.
* minor: naming, cleanup.
* fix: renderers dict.
* fix: adjusting and renaming racer.
* fix renderer binding for scored frogs.
* feat: responsive layout with gap below and maintained aspect ratio.
* grammar fix.
* feat: road lane dividers.
* feat: using AbortController to cleanup events.
* fix: cleanup and shortening.
* feat: extracting drawGameBackground.
* feat: initObstacleRows and updateAndDrawObstacles helpers.
* feat: initFroggers helper.
* feat: drawFroggers helper.
* feat: checkForCollision helper.
* feat: makeKeydownHandler helper.
* feat: listenToKeyboardEvents helper.
* mv cleanup into drawGameBackground.
* fix: cleanup.
* feat: better adjustBrightness helper.
* Polling on the page.tsx side, restoring timeout and fallbacks, dynamic link msg.
* FEAT: wait for workflow to complete and notify additionally with a big link (incl.db migration).
* Fix: larger title, shorter link.
* fix(hook): Writing completedAt from hook.workflow_run.updated_at according to suggestion.
* fix(loader): rm unused props from WorkflowRunClientProps as suggested.
* fix(loader): mv id=dev case into the page.
* fix(DNRY): mv PollStartedResult and PollCompletedResult types.
* fix(DNRY): reusing drawEllipse() helper in Sprite.
* fix(style): reordering methods by priority in Sprite.
* fix(frogger): rm empty rows from canvas, square game.
* feat: game canvas rounded corners.
* fix(DNRY): extracting SpriteShape type for faster reference.
* fix: rm target from links, use same window.
* add incremental re-review on new PR commits
When new commits are pushed to a PR that Pullfrog has previously reviewed,
automatically perform a focused re-review on only the new changes. Includes
a supersede mechanism to abort stale in-flight reviews on rapid pushes, a
new IncrementalReview mode with incremental diff + prior-feedback awareness,
and a PRReview tracking model so re-review fires for both auto-reviewed and
manually-triggered PRs. Reviews now always submit (APPROVE when clean).
Co-authored-by: Cursor <cursoragent@cursor.com>
* replace superseded polling with server-side in-flight dedup and add prApproveEnabled setting
Made-with: Cursor
* consolidate workflow_run completed handling and track completedAt
Removes the duplicate exported handleWorkflowRunCompleted in favor of
the private one, merges status + orphan resolution logic into a single
path, and sets completedAt on both normal completion and orphan cancel.
Made-with: Cursor
* fix rebase conflict resolution: restore eligibility logic, incremental review summaries, and exhaustiveness check
- replace deleted hasPullfrogReviewedPR call with WorkflowRun.findFirst
(the utility file was removed by the dedup improvements commit)
- restore IncrementalReview summary body in modes.ts and selectMode.ts
(lost during ca0168b conflict resolution; origin had re-added them via f98f902)
- use switch + satisfies never for workflow_run event dispatch
- lowercase comments per project conventions
Made-with: Cursor
* fix workflow-run polling architecture and improve incremental review prompts
move polling loops from server actions to client to avoid serverless timeouts
(pollForCompleted ran up to 600s in a single invocation). each server action
is now a single DB check; client drives retries. also fix misleading prompt
text about incremental diff scope and remove dead code in handleWebhook.
Made-with: Cursor
* await reportReviewNodeId to eliminate race condition and webhook sleep
- refactor reportReviewNodeId from fire-and-forget to async/awaited,
guaranteeing the dedup signal lands before the tool returns
- remove the 5-second grace period sleep in the synchronize webhook
handler (no longer needed with the awaited PATCH)
- update IncrementalReview guidance to use get_review_comments for
detailed prior line-level feedback instead of just review summaries
- remove dead fallbackUrl field from CheckStartedResult type
Made-with: Cursor
* fix rebase artifacts: broken triggeringIssue reference, review formatting, and prompt wording
Made-with: Cursor
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Anna Bocharova <robin_tail@me.com>
* Standardize on top-level `triggerer` property
- Rename `triggeringUser` → `triggerer` as the single top-level payload property
- Remove redundant `triggerer` from `FixReviewEvent`, add `approvedOnly` boolean
- Auto-apply `approved_by` filtering in `get_review_comments` when `approvedOnly` is set
- Auto-assign created PRs to the triggerer
- Simplify `AddressReviews` mode prompt
- Accept both `triggerer` and `triggeringUser` in schema for backward compat
* Address review feedback: simplify approved_only, remove addAssignees, drop approved_by param
* Fix formatting in `action/mcp/pr.ts`
* re-add triggeringUser backward-compat fallback in payload schema
* auto-assign created PRs to the triggerer
* Revert "auto-assign created PRs to the triggerer"
This reverts commit c088c425fea33793eb299a001ffd253798d2c674.
* Revert "re-add triggeringUser backward-compat fallback in payload schema"
This reverts commit ae5b3cb3f1377cd4a634b2d48962c785c31013f3.
* backend compat
* tweak prompt to ensure compat
* Address review feedback
* chore: remove triggeringUser fallback
---------
Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
Co-authored-by: Colin McDonnell <colinmcd94@gmail.com>
* add "Rerun failed job" link to error comment footer
* Remove issueNumber guard from rerun link
The rerun action only needs run_id — the issue number in the trigger
URL path is just a route segment requirement. Use 0 as a fallback
so the link is always shown when a run ID is available.
* Overload `[number]` path segment as `runId` for the rerun action
For the rerun trigger, the `[number]` path param now carries the
workflow run ID instead of an issue number. The rerun link changes
from `/trigger/o/r/ISSUE?action=rerun&run_id=RID` to
`/trigger/o/r/RID?action=rerun`.
- Remove `run_id` query param from page.tsx and searchParams type
- Add error handling around `reRunWorkflow` for invalid run IDs
- Drop `issueNumber` from `BuildErrorCommentBodyParams` and all
rerun link builders (errorReport, exitHandler, postCleanup)
* Reorder validation: action first, then rerun, then issueNumber
* address review: remove early toolState assignment, restructure rerun into dedicated block
* revert self-contained rerun block, share auth logic via issueOrRunId
* improve error handling
* normalize runid early
---------
Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
* fix: report errors to progress comment when agent fails without throwing
when an agent returns success: false without throwing (e.g., opencode exits
with code 0 despite provider errors), the catch block in main.ts is never
reached, leaving the progress comment stuck on "leaping into action."
two fixes:
- opencode: return success: false when 0 events processed and a provider
error was detected (converts silent failures to explicit failures)
- main.ts: after handleAgentResult, check if the progress comment was ever
updated — if not, report the error to the comment as a safety net
Co-authored-by: Cursor <cursoragent@cursor.com>
* address review: use result directly and force failure on unreported progress
* refactor: move safety-net logic into handleAgentResult
---------
Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Anna Bocharova <robin_tail@me.com>
When delegate() runs multiple subagents in parallel, their logs
interleave without visual distinction. Use AsyncLocalStorage to
automatically prefix every log line inside runSubagent() with the
task label in magenta (e.g. [frontend-review]).
Co-authored-by: Cursor <cursoragent@cursor.com>
Standardize orchestrator/subagent instructions on the MCP shell tool and format mode guidance as explicit checklists to make delegation flows easier to follow. Bump the action package version to 0.0.171 for this release.
Co-authored-by: Cursor <cursoragent@cursor.com>
thread mcp token into exit cleanup and drop process env mutation from token resolution so token access stays explicit and in-memory.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: replace domain-specific exit handler with generic signal handler registry
Rewrite exitHandler.ts as a generic, domain-agnostic exit signal module
that exports onExitSignal(handler) returning a dispose function.
- subprocess.ts now registers via onExitSignal instead of direct
process.on(SIGINT/SIGTERM) calls
- resolveTokens registers a signal handler that captures tokens by
closure, fixing the race condition where the exit handler would
read the wrong token after disposal
- Remove setupExitHandler and runCleanup — domain cleanup is handled
by post.ts + await using
Co-authored-by: Cursor <cursoragent@cursor.com>
* tweaks
* simplify handler installation
* extract to util
* fix race in dispose
* wrap dispose body in try/finally to ensure disposingRef always settles
---------
Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
* Stop using command-based logs for warnings and errors
Co-authored-by: Cursor <cursoragent@cursor.com>
* revert
* tweak
* de-noise
* Remove redundant ts() timestamp prefix from log calls
* Restore timestamped logging and refine debug output routing.
Bring back timestamp prefixes for standard logs and make log.debug emit via core.debug when runner debug is enabled, while still surfacing debug lines for --debug runs.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
Co-authored-by: Colin McDonnell <colinmcd94@gmail.com>
* run post action cleanup in play script after main completes
* clarify that GITHUB_RUN_ID is the actual bail-out gate in play context
* treat GITHUB_RUN_ID as optional in post cleanup
* replace dynamic import with static import of `runPostCleanup`
Export `runPostCleanup` from post.ts and guard the top-level
execution with `import.meta.url` so it only auto-runs as an
entry point. play.ts now statically imports and calls it.
* move runPostCleanup into finally block and let failures propagate
* refactor post cleanup into utility module
move post cleanup logic into a dedicated utility and keep post.ts as a pure script entrypoint. update play.ts to import the shared utility directly and normalize direct-execution detection.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
Co-authored-by: Colin McDonnell <colinmcd94@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* add workflows permission to git token and waitlist improvements
- add `workflows` to `InstallationTokenPermissions` type in both action and API token routes
- include `workflows: write` in the git token so agents can push workflow file changes
- add `githubFollowers` field to WaitlistSignup schema with migration
- add script to populate waitlist followers from GitHub API
- add frog-green-square-border logo asset
Co-authored-by: Cursor <cursoragent@cursor.com>
* improve CI, agent logging, token permissions, and delegation guardrails
- add format check and build step to root CI job
- standardize agent model/effort log lines across all agents
- fix GitHub App permissions types to match OpenAPI schema (workflows is write-only)
- improve delegation error message to prevent subagent recursion
- demote noisy OpenCode stderr to debug level
- add subagent delegation rules to resolved instructions
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix graphql partial error handling, update delegation message, add workflow_run fixtures
Co-authored-by: Cursor <cursoragent@cursor.com>
* remove module-level env var throws that break CI build
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix logging bug and type hole from PR review
- use batch-local notFound counter so per-batch log doesn't undercount
- add workflows to WorkflowTokenPermissions so wire type matches what action sends
Co-authored-by: Cursor <cursoragent@cursor.com>
* lazy-init appOctokit to fix next build without env vars
Co-authored-by: Cursor <cursoragent@cursor.com>
* drop pnpm build from CI test workflow
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix delegate-effort test regex to match actual log format, disable fail-fast for agnostic tests
the test was matching `running \w+ with effort=auto` but the actual log
line from shared.ts is `» effort: auto`. also temporarily set
fail-fast: false on action-agnostic so all failures surface at once.
Co-authored-by: Cursor <cursoragent@cursor.com>
* disable fail-fast in action workflow too, relax ci.test.ts to match
both workflow files now use fail-fast: false for agnostic tests so all
matrix jobs run to completion. the ci consistency test now checks that
the two workflows agree rather than requiring true.
Co-authored-by: Cursor <cursoragent@cursor.com>
* restore fail-fast: true now that all agnostic tests pass
Co-authored-by: Cursor <cursoragent@cursor.com>
* skip agent tests in CI when agent harness file didn't change
adds action/test/changed-agents.sh which reads the PR diff (via
dorny/paths-filter) and outputs only agents whose harness file was
modified. the action-agents matrix now uses this dynamic list instead
of a hardcoded array, so e.g. a PR touching only cursor.ts runs 6
jobs instead of 30.
Co-authored-by: Cursor <cursoragent@cursor.com>
* update ci.test.ts to validate dynamic agent matrix
the test now checks that the matrix references the changes job output
and that changed-agents.sh correctly discovers all agents.
Co-authored-by: Cursor <cursoragent@cursor.com>
* parallelize action jobs and use claude canary fallback for shared changes
runs action-agents in parallel with action-agnostic after root/changes, and updates changed-agents logic so shared or non-harness action runtime changes run only claude while harness-specific edits run only those changed agents.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
* console UI improvements and cleanup
- add verify workflow button and API endpoint for manual installation check
- move env var check into PromptBox as blocking overlay (hoisted to RepoConsole)
- extract FlagsCheatSheet modal, replace verbose flag hints everywhere
- add info popovers for repo setup / post-checkout script descriptions
- remove unused prAutoFixCiFailures schema fields and migration
- default mentionAllowNonCollaborator to disabled for safety on public repos
- update docs for triggers and getting started
Co-authored-by: Cursor <cursoragent@cursor.com>
* add diagnostic logging for push_branch bug investigation
temporary [push-debug] logs to trace why getPushDestination falls back
to origin/<localBranch> instead of using the correct remote branch name
for same-repo PRs.
Co-authored-by: Cursor <cursoragent@cursor.com>
* add git config diagnostic to verify original bug cause
Co-authored-by: Cursor <cursoragent@cursor.com>
* temporarily disable StoredPushDest to test git config path
Co-authored-by: Cursor <cursoragent@cursor.com>
* remove diagnostic logging for push_branch investigation
verified that StoredPushDest fix works correctly on preview repo.
both the stored dest path and the git config fallback resolve to the
correct remote branch in the GitHub Actions environment.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix formatting in AgentSettings and TriggersSettings
Co-authored-by: Cursor <cursoragent@cursor.com>
* pass derived env var state to PromptBox instead of raw secrets data
eliminates duplicated derivation logic between RepoConsole and PromptBox
by passing envVarMissing, envVarChecking, and agentKeyNames as props.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: prevent duplicate comment after PR review deletes progress comment
progressCommentId now uses three states: undefined (no comment yet),
number (active), null (deliberately deleted). After create_pull_request_review
deletes the progress comment, subsequent report_progress calls skip instead
of creating a new comment.
Co-authored-by: Cursor <cursoragent@cursor.com>
* effort descriptions, test ordering, husky, docs images, typo fix
- rewrote delegation effort level descriptions to per-level breakdown
- action-agents now waits for action-agnostic; action-agnostic waits for root
- added husky + lint-staged (biome check --write on staged files)
- updated triggers docs images and triggers.mdx content
- fixed "figured" → "figures" typo on landing page
- updated pnpm-lock.yaml
Co-authored-by: Cursor <cursoragent@cursor.com>
* Commit
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
the action now calls preview deployments directly via API_URL secret
(set by preview-create.ts), making the production-side forwarding
fallback unnecessary. also removes orphaned workflowRun.ts interface.
Co-authored-by: Cursor <cursoragent@cursor.com>
* test preview bypass 2
Co-authored-by: Cursor <cursoragent@cursor.com>
* add apiFetch wrapper with Vercel bypass via query param + header
the template workflow was missing VERCEL_AUTOMATION_BYPASS_SECRET,
so all action API calls to preview deployments hit Vercel's
deployment protection without bypass. this also consolidates the
bypass logic into a single fetch wrapper that applies the secret
as both a query parameter (matching server-side forwarding) and
a header for belt-and-suspenders reliability.
Co-authored-by: Cursor <cursoragent@cursor.com>
* security hardening for Vercel bypass
- redact bypass token from webhook forwarder logs and response body
- remove dead x-preview-api-forward header
- refactor getAllSecrets() to use SENSITIVE_PATTERNS instead of hardcoded list
- enforce https:// on API_URL (localhost exempt for local dev)
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
action API calls to preview deployments were getting 401'd by Vercel's
deployment protection. add x-vercel-protection-bypass header to the 3
server-to-server fetch sites when VERCEL_AUTOMATION_BYPASS_SECRET is set.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Add `comment_type: "issue"` to `IssueCommentCreatedEvent` interface and
dispatch sites so agents can distinguish issue comments from PR review
comments
- Add dedicated "Progress reporting" section to system prompt making
`report_progress` the mandatory tool for sharing results
- Update `reply_to_review_comment` description to clarify it only works
for inline review comments on PR diffs, not issue comments
Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
* Use a stable `NEXT_PUBLIC_VERCEL_BRANCH_URL` for short links
* Update JSDoc reference to NEXT_PUBLIC_VERCEL_BRANCH_URL
---------
Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
* pin all CLI installations to explicit versions and use pro models by default
- codex: pin @openai/codex to 0.101.0 (was "latest")
- opencode: pin opencode-ai to 1.1.56 (was "latest")
- gemini: pin gemini-cli to v0.28.2 via new tag param on installFromGithub
- cursor: pin to 2026.01.28-fd13201 via direct tarball download (replaces curl install script)
- add installFromDirectTarball to install.ts for versioned tarball URLs
- gemini auto effort now uses pro-preview instead of flash-preview
- test runner model overrides updated to use pro-preview consistently
Co-authored-by: Cursor <cursoragent@cursor.com>
* increase activity timeout
* fix delegation timeout
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
* Replace Date.now() with performance.now() for duration measurements
- Import performance from node:perf_hooks in all affected files
- Update Timer and ThinkingTimer classes to use performance.now()
- Update activity tracking (markActivity, getIdleMs) to use performance.now()
- Update cache duration measurements to use performance.now()
- Update agent execution timing (cursor, opencode) to use performance.now()
- Update subprocess execution timing to use performance.now()
- Update API performance monitoring to use performance.now()
- Update prep phase timing to use performance.now()
- Update timer.test.ts to mock performance.now() instead of Date.now()
Benefits:
- Monotonic clock immune to system clock adjustments
- Higher precision (microsecond vs millisecond resolution)
- Purpose-built for performance measurement
Fixes#245
* fix lint.
* Round float durations to integers in logging
Preserve original behavior by rounding performance.now() float values
to integers when displaying/logging millisecond durations.
* fix lint.
---------
Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
Co-authored-by: Robin Tail <robin_tail@me.com>
* make waitlist code field required
all existing rows have been backfilled with unique codes via the consolidation script.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix lint errors
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat(agents): add thinking time logging between tool calls
Adds a ThinkingTimer utility that tracks the gap between tool results and
the next tool call. When the gap exceeds 3 seconds, it logs the duration
with a stopwatch emoji (⏱️ 4.2s).
Uses performance.now() for high-resolution timing and Intl.NumberFormat
for rendering duration in seconds with optional fraction digits.
Integrated across all 5 agents: Claude, Codex, Cursor, Gemini, OpenCode.
Closes#127
* fix: adjusting tests for mocking performance.now.
* fix: reducing diff for claude.
* fix: rm unused args for claude.
* rm unused args for codex.
* fix: rm unused args for gemini.
* fix: rm unused args for opencode.
* mv THINKING_THRESHOLD.
* rev: I decided to pospone node:perf_hooks integration since it requires more comprehensive refactoring.
* fix: using Intl unit formatting.
* tests for ThinkingTimer.
* fix: narrow unit.
* fix: making durationFormatter a class instance property since using one agent per run.
* fix: inverting condition in markToolCall.
* thinking timer improvements and fix actions/checkout v6 auth
- thinking timer: use » chevron and "thought for X seconds" format
- thinking timer: add debug timestamps for sanity checking
- demote PID namespace isolation logs to debug
- remove redundant "setting up git authentication" log
- fix duplicate Authorization header with actions/checkout v6: clean up
includeIf credential entries that v6 persists via external config files
Co-authored-by: Cursor <cursoragent@cursor.com>
* standardize tool call log prefix to » double chevron
Co-authored-by: Cursor <cursoragent@cursor.com>
* update timer tests for new thinking log format
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
Co-authored-by: Robin Tail <robin_tail@me.com>
Co-authored-by: Colin McDonnell <colinmcd94@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat(action): Do cleanup when workflow failed or cancelled early.
* fix: avoid naming collision with get-installation-token state.
* tmp: add more logging for debugging purposes.
* fix: rm wasUpdated state.
* FIX: changing approach, separate entrypoint, using db to handle cases when main() never ran.
* fix(cleanup): revert changes to exitHandler.
* FIX: using event payload for issue and comment retrieval instead of DB.
* FIX: use installation token.
* feat(docs): wiki article explaining how it works.
* fix(docs): shortening.
* fix(docs): shortening.
* fix: no console.
* todo: DNRY for findPullfrogComment.
* FIX(DNRY): upgrading octokit/rest and reusing findInitialComment() from triggerWorkflow.ts.
* Revert "FIX(DNRY): upgrading octokit/rest and reusing findInitialComment() from triggerWorkflow.ts."
This reverts commit 7dd239ba0986c5b0aeacb6ddc9f2deddb83aee82.
* fix: rm todo.
* fix(DNRY): shortening early exit logging statements.
* FIX(API): Avoid extra call for comment body.
* feat(DNRY): extracting and reusing buildWorkflowErrorMessage() from exitHandler.ts.
* fix(DNRY): extracting more similarities into buildErrorCommentBody.
* feat: Add conditional reason check.
* fix(merge): replacing resolveInstallationToken with getJobToken.
* fix(debug): using higher severity.
* fix: Adjusting the implementation of getIsCancelled to use job status instead of workflow.
* fix: Take steps conclusion into account when job is in progress.
* fix: generic log msg.
* fix: jsdoc.
* fix(docs): Updating the wiki article according to recent changes.
* fix(post): Handling the case when current job runs within matrix.
* fix: finding the most recent comment that is ours ANS stuck.
* feat(opt): using progressCommentId from object-based prompt when present.
* fix(docs): Shortening the documentation 3 times down.
* FIX: Only using the prompt.progressCommentId but with validation that it is stuck.
Add `lint`, `lint:fix`, `format`, and `format:fix` package.json scripts
backed by biome. Add AGENTS.md rule for agents to run them after changes.
Fix all existing lint and format violations across the codebase.
Co-authored-by: Cursor <cursoragent@cursor.com>
* flatten lifecycle hooks into RepoSettings string fields
replace the separate LifecycleHook model with setupScript and
postCheckoutScript string fields directly on RepoSettings. move the UI
into the Agent settings section alongside environment variables and
custom instructions. delete the standalone lifecycle-hooks API route,
component, and schema since the existing settings PATCH endpoint
handles the new fields automatically.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: pass env to lifecycle hook spawn so scripts can use package managers
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Colin McDonnell <colinmcd94@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>