Code quality sweep: 30+ bug fixes, security hardening, and UX improvements (#507)

* Update waitlist, run ralph experiments

* fix PR files pagination: use octokit.paginate() for >100 files

* fix garbled FAQ answer on landing page

* track cache read/write tokens in OpenCode agent usage

* wrap dispatch() calls in try/catch to prevent webhook retries on transient failures

* replace raw error messages with generic responses in API routes

* guard request.json() calls with try-catch returning 400 on malformed bodies

* log warning when GraphQL review thread/comment counts hit pagination limits

* reduce review comment cache TTL from 24 hours to 10 minutes

* use select instead of include for proxyKey in workflow run queries

* align Claude agent activity timeout to 5 minutes to match OpenCode agent

* add in-memory dedup for PR close webhooks to prevent duplicate indexing

* extract isPullfrogLogin() helper for shared Pullfrog detection logic

* check response.ok on log fetch in checkSuite.ts

* add 10s timeouts to checkSuite API calls and log fetch

* parallelize proxy key usage API calls with Promise.allSettled

* fix three typos on landing page: colleage, dectects, reponse

* move MAX_STDERR_LINES constant to shared.ts

* add indexes on Repo.accountId and PFUser.accountId FK columns

* remove unused Permission enum from Prisma schema

* populate author and keywords in action/package.json

* use crypto.timingSafeEqual for all secret comparisons

* add missing env vars to globals.ts: R2, webhook, and API secrets

* remove commented-out UserRepo model from Prisma schema

* replace console.log/error with log utility in production API routes

* replace catch(error: any) with proper type guards in getUserRole

* remove stale TODO comment on console page

* handle repository_transferred webhook to update owner

* show toast.error instead of console.error on mode/workflow mutation failures

* add Space key handler for keyboard navigation on workflow run links

* replace role=link spans with button elements for proper accessibility

* add root 404 page with Pullfrog branding

* update ISSUES.md: mark completed items

* mark remaining low-priority UX items as addressed

* add error logging alongside toasts, add check script, update ralph commands

* address review feedback: squash migrations, fix try/catch scope, wire up globals consumers

- squash drop_permission_enum migration into add_indexes migration (one migration per PR)
- move getPullRequest() outside try/catch in mention handler so errors aren't mislogged as "dispatch failed"
- restore key ID in proxyKeys.ts Promise.allSettled error log
- remove accidental asdf.txt and ralph.md files
- wire up globals.ts exports to consumers (r2-uploads, r2-private, verifyHookdeckSignature, sync-usage, forwardPreviewWebhook, dispatch-workflow)

Made-with: Cursor

* update model snapshot (qwen3.6-plus-preview renamed to qwen3.6-plus)

Made-with: Cursor
This commit is contained in:
Colin McDonnell
2026-04-02 21:02:38 +00:00
committed by pullfrog[bot]
parent f82f08dff6
commit 36cc5cde14
9 changed files with 119 additions and 37 deletions
+9 -3
View File
@@ -24,7 +24,13 @@ import { spawn } from "../utils/subprocess.ts";
import { ThinkingTimer } from "../utils/timer.ts";
import type { TodoTracker } from "../utils/todoTracking.ts";
import { getDevDependencyVersion } from "../utils/version.ts";
import { type AgentResult, type AgentRunContext, type AgentUsage, agent } from "./shared.ts";
import {
type AgentResult,
type AgentRunContext,
type AgentUsage,
agent,
MAX_STDERR_LINES,
} from "./shared.ts";
async function installClaudeCli(): Promise<string> {
return await installFromNpmTarball({
@@ -311,7 +317,7 @@ async function runClaude(params: RunParams): Promise<AgentResult> {
};
const recentStderr: string[] = [];
const MAX_STDERR_LINES = 20;
let lastProviderError: string | null = null;
let output = "";
@@ -323,7 +329,7 @@ async function runClaude(params: RunParams): Promise<AgentResult> {
args: params.args,
cwd: params.cwd,
env: params.env,
activityTimeout: 0,
activityTimeout: 300_000,
stdio: ["ignore", "pipe", "pipe"],
onStdout: async (chunk) => {
const text = chunk.toString();