Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
eb80374
chore: drop bun.lockb and tsbuildinfo from tracking
passandscore Apr 18, 2026
e0ff132
feat(agents): add agents-first repo infrastructure
passandscore Apr 18, 2026
4965e2f
chore: gitignore .superset/ worktree config
passandscore Apr 18, 2026
6889c3b
refactor(repo): audit cleanup — folderize lib, clean tests dir, Zod A…
passandscore Apr 18, 2026
0346a98
test: add fuzz, integration, invariant, and ABI-drift layers
passandscore Apr 18, 2026
cec1910
test: EIP-712 hash coverage + upstream API contract snapshots
passandscore Apr 18, 2026
baf6b7e
feat(api): guard Fuul and Barter routes with upstream Zod schemas
passandscore Apr 18, 2026
f671009
test: pin Permit2 DOMAIN_SEPARATOR + doc pg-mem window-fn gap
passandscore Apr 18, 2026
208fd17
test: fork (anvil), hook (happy-dom), and mutation (Stryker) layers
passandscore Apr 18, 2026
7c1f652
ci: wire typecheck, tests, build, fork, and mutation into pipeline
passandscore Apr 18, 2026
c9627f6
ci(build): strip empty-value env lines so optional fields stay undefined
passandscore Apr 19, 2026
b7ac023
docs(readme): reflect folderized src/lib, 9-layer test suite, CI pipe…
passandscore Apr 19, 2026
7e0c38a
feat(externals): Phase A — scaffolding for vendored upstream repos
passandscore Apr 19, 2026
3a53a96
feat(externals): Phase B — sync hook + /prime and /sync-externals com…
passandscore Apr 19, 2026
e8af282
feat(externals): Phase C — external-mev-commit skill
passandscore Apr 19, 2026
5bf0976
feat(externals): Phase D — upstream drift test + externals.yml CI
passandscore Apr 19, 2026
1df65be
docs(readme): dual-purpose rewrite — project overview + agent onboarding
passandscore Apr 19, 2026
84791a1
docs: route + hook discovery indexes
passandscore Apr 19, 2026
f4a0488
docs: agent_docs/db-schema.md — app-owned Postgres reference
passandscore Apr 19, 2026
04d84c7
docs: INVARIANTS.md — load-bearing contracts, linked to the tests
passandscore Apr 19, 2026
8ac89f6
feat(lint): warn on imperative validation in API routes
passandscore Apr 19, 2026
30edd51
feat(types): flip noImplicitAny: true
passandscore Apr 19, 2026
d6c273c
docs(audit-followup): refresh with what just landed and what's left
passandscore Apr 19, 2026
b542a9e
feat(api): migrate remaining 8 input-taking routes to Zod
passandscore Apr 19, 2026
7c96d1c
feat(types): flip noUnusedLocals + noUnusedParameters, purge 77 dead …
passandscore Apr 19, 2026
97f8e9c
docs(audit-followup): mark Zod migration + noUnusedLocals flip done
passandscore Apr 19, 2026
d4f7179
refactor(swap): extract use-swap-form math → @/lib/swap/min-amount-ou…
passandscore Apr 19, 2026
aa41251
docs(audit-followup): mark use-swap-form math extraction done
passandscore Apr 19, 2026
aaec244
test(hooks): seed three more hook tests (quote-guard-config, balance-…
passandscore Apr 19, 2026
a45e0eb
test(components): seed component test pattern with SwapToast
passandscore Apr 19, 2026
6a83b73
feat(ts): flip strictNullChecks + rewrite parse.ts to discriminated u…
passandscore Apr 19, 2026
9f0915d
style: prettier-fix strictNullChecks edit fallout
passandscore Apr 19, 2026
31f407e
refactor(swap-modal): split SwapConfirmationModal into swap-confirmat…
passandscore Apr 19, 2026
242ae7d
refactor(leaderboard): extract 6 leaves from LeaderboardTable (2711→1…
passandscore Apr 19, 2026
594c823
refactor(leaderboard): phase 2 — split mode sections (1176→447 LoC)
passandscore Apr 20, 2026
ac13fc5
chore(ci): enable Dependabot and widen Stryker scope
passandscore Apr 20, 2026
4ef4f8a
feat(ts): flip strict: true (zero new errors)
passandscore Apr 20, 2026
f8ae2c7
refactor(hooks): extract useDebouncedValidating from use-swap-form
passandscore Apr 20, 2026
b39ed37
test(a11y): seed axe-core accessibility tier
passandscore Apr 20, 2026
4a02b4e
chore(commands): add /verify-ui slash command
passandscore Apr 20, 2026
f1bcfce
fix(api): spread body.data not body in fastswap proxy + strengthen sc…
passandscore Apr 20, 2026
6147b01
chore(commands): correct /verify-ui target routes
passandscore Apr 20, 2026
00840b7
test(hooks): pin use-swap-form state contracts (regression oracle)
passandscore Apr 20, 2026
a6fcf1e
test(components): seed tests for three highest-traffic extracted leaves
passandscore Apr 20, 2026
abc37e6
test(modals): pin SwapConfirmationModal orchestration + a11y fix on c…
passandscore Apr 20, 2026
b810514
Merge main: resolve early-access Zod conflict, fix /pro import path
passandscore Apr 20, 2026
ae1dd56
chore(agent-infra): merging-main skill + /realign command; align /pro…
passandscore Apr 20, 2026
f071803
feat(lint): codify folderization rename table as no-restricted-import…
passandscore Apr 20, 2026
4930503
Merge main: adopt FAST_RPC_API_TOKEN → FAST_RPC_DB_AUTH_TOKEN rename
passandscore Apr 20, 2026
7236667
feat(agentic-complete): close the four remaining gaps
passandscore Apr 20, 2026
5b11feb
feat(hooks): husky post-merge auto-runs the drift check after every m…
passandscore Apr 20, 2026
5539034
Merge main: /api/config/global-banner + miles-swap flag (PR #129)
passandscore Apr 20, 2026
fa6986d
Merge branch 'main' of github.com:primev/fastprotocolapp into agentic…
passandscore Apr 20, 2026
4757d75
Merge branch 'main' of github.com:primev/fastprotocolapp into agentic…
passandscore Apr 21, 2026
cd65fa5
Merge branch 'main' of github.com:primev/fastprotocolapp into agentic…
passandscore Apr 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
78 changes: 78 additions & 0 deletions .claude/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# `.claude/` — agent infrastructure map

This directory configures Claude Code for the Fast Protocol App. Nothing here is load-bearing for the app itself — it's a retrieval and attention-budget optimization layer.

## Layout

```
.claude/
├── README.md # You are here
├── settings.json # Hooks + permission allow/deny lists
├── skills/ # Domain skills (progressive disclosure)
│ ├── skill-creator/
│ ├── next-app-router/
│ ├── defi-swap/
│ ├── web3-wallet/
│ ├── dashboard-data/
│ ├── leaderboard-miles/
│ ├── contract-abis/
│ ├── ui-shadcn/
│ └── testing-vitest/
├── agents/ # Subagent definitions (context firewalls)
│ ├── explore-web3.md
│ ├── security-reviewer.md
│ ├── ui-verifier.md
│ └── abi-tracer.md
├── commands/ # Slash commands
│ ├── prime.md
│ ├── verify.md
│ ├── typecheck.md
│ ├── lint.md
│ ├── test.md
│ ├── new-skill.md
│ └── review-diff.md
└── hooks/ # Shell scripts invoked by settings.json hooks
├── post-edit-typecheck.sh
└── stop-format-check.sh
```

## Design principles (from the research corpus)

1. **Progressive disclosure.** SKILL.md metadata is always loaded; body loads when triggered; reference files load when explicitly needed.
2. **Silent success, loud failure.** Hooks print nothing when clean.
3. **Pointers over copies.** All content cites `src/path/file.ts:42`; nothing is inlined.
4. **Subagents as firewalls.** Reading many files happens in a subagent, not the parent context.
5. **Verification is a first-class primitive.** `/verify` is the single most important command here.

## Doc layer convention — one source of truth per topic

To prevent drift, the three doc surfaces have **non-overlapping roles**:

| Layer | Audience | Role | Loads |
|---|---|---|---|
| `.claude/skills/` | agents | HOW-TO — patterns, do/don't, code snippets | on relevance |
| `agent_docs/` | agents | MAP — pointers to code + cross-links to skills | on demand |
| `docs/` | humans | NARRATIVE — UX behavior, SQL reference, product flow | banner-gated |

Rules:
- Each topic has exactly one authoritative home. Others link, they don't duplicate.
- `docs/*.md` files carry an "Audience: humans" banner at the top pointing to the authoritative skill or agent_doc.
- Moving a skill or splitting a module → update `agent_docs/architecture.md`
first (it's the map), then skill cross-links, then any `docs/` pointers.

## Editing

- Adding a skill → use `/new-skill <name>`, which invokes `skill-creator`.
- Adding a hook → edit `settings.json` + drop a script in `hooks/`; keep it silent-on-success.
- Adding a subagent → drop a new `.md` under `agents/` with `name`/`description`/`tools`/`model` frontmatter.
- Adding a command → drop a new `.md` under `commands/`; body is the prompt.

Changes here should be reviewed for **budget impact** — every added skill/tool consumes system-prompt tokens for every future session.

## Local overrides

`.claude/settings.local.json` is gitignored. Use it for personal preferences (extra permissions, model overrides). Do not put team-shared config there.

## Plugins & MCP servers

MCP servers are user-level, not repo-level. This repo does not require any. If you connect one for work here (e.g., Linear), prune unused tools — tool descriptions are a tax on every turn. See the "instruction budget" section of the plan at `/Users/jasonschwarz/.claude/plans/inherited-herding-penguin.md`.
48 changes: 48 additions & 0 deletions .claude/agents/abi-tracer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
name: abi-tracer
description: Given a contract name, ABI function, or address, return every call site across the app grouped by layer (hook / component / server / lib). Read-only research agent for contract refactors and ABI upgrades.
tools: Read, Grep, Glob
model: sonnet
---

You are a read-only code-graph agent specialized in contract / ABI tracing.

## Goal

Given a query like "find all call sites for `Settlement.deposit`" or "where is the Permit2 address used", return a grouped list of call sites.

## Workflow

1. Start at the ABI binding (e.g., `src/lib/fast-settlement-v3-abi.ts`, `src/lib/weth-abi.ts`, `src/lib/erc20-abi.ts`, `src/lib/contract-config.tsx`).
2. `Grep` for the function name or address token across `src/`.
3. Group results by layer:
- **Hooks** (`src/hooks/`)
- **Components** (`src/components/`)
- **Server routes / actions** (`src/app/api/`, `src/actions/`)
- **Lib helpers** (`src/lib/`)
4. For each call site, note `file:line` and the enclosing function name.

## Output

```
Contract: <name>
Function: <fn>
Address config: src/lib/contract-config.tsx:<line>

Call sites:
hooks:
src/hooks/use-foo.ts:42 (inside useFoo → useWriteContract)
...
components:
...
server:
...
lib:
...
```

## Rules

- Do not open files you don't need. Grep first.
- If the function name is common (e.g., `deposit`), also check import paths to filter out same-named functions in other ABIs.
- Note ambiguity explicitly — if `deposit` appears in both `WETH_ABI` and `SomethingElseABI`, split them.
33 changes: 33 additions & 0 deletions .claude/agents/explore-web3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
name: explore-web3
description: Research-only subagent for tracing web3 call sites, hook composition, or contract usage across the codebase. Delegate here when the answer requires reading many files and you want to keep the parent context clean.
tools: Read, Grep, Glob, Bash
model: sonnet
---

You are a read-only research agent scoped to this Next.js + wagmi + viem repo. You return **condensed findings with `file:line` citations** — never raw dumps.

## Goal
Answer the parent agent's question about how web3 state, contracts, or hooks are wired in this codebase.

## Rules
- Read-only. You may not Edit, Write, or run destructive Bash.
- Prefer `Grep` / `Glob` over reading whole files. Only open a file when you need the exact lines.
- When you do read a file, note only the relevant lines and cite them.
- Cap your investigation at ~15 files read. If you need more, return what you have and note the remaining scope.

## Output format
Return a structured summary:

1. **TL;DR** — one sentence answering the question.
2. **Key files** — bulleted list of `path:line` with a one-line note each.
3. **Call graph** (if relevant) — A → B → C with paths.
4. **Open questions** — anything you can't answer from the code alone.

Do not paste code bodies. Do not summarize things the parent can look up in `agent_docs/architecture.md`.

## Typical tasks
- "Find every call site for `<contract-function>`"
- "Trace the swap flow from input to on-chain submission"
- "List all hooks that invalidate query key X"
- "Find where env var Y is consumed"
55 changes: 55 additions & 0 deletions .claude/agents/security-reviewer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
name: security-reviewer
description: Security-focused reviewer for web3 + Next.js changes in this repo. Delegate when reviewing a diff, PR, or set of files for security issues. Reviews are read-only; no code edits.
tools: Read, Grep, Glob, Bash
model: opus
---

You are a senior security engineer reviewing code in a Next.js 15 + wagmi/viem DeFi application. You do not write or edit code — you produce a review.

## Focus areas (in priority order)

1. **Secrets leakage**
- Server env vars (`env.*` via `@/env/server`) reaching a `"use client"` file
- `NEXT_PUBLIC_` vars holding anything that looks like a real secret
- `console.log` / analytics / error reporting carrying signed payloads, private keys, seed phrases, auth tokens
- Raw API keys in commits

2. **Signing and transaction safety**
- Permit2: deadline presence, nonce freshness, spender validation, amount bounds
- Slippage bounds respected in swap flow (see `src/lib/swap-constants.ts`, `quote-guard.ts`)
- No "unlimited" token approvals
- Tx errors normalized via `src/lib/transaction-errors.ts` — no raw RPC errors surfaced

3. **Server-side**
- Server actions and API routes validate input with Zod before side effects
- No `process.env` reads (only `@/env/server`)
- Cron routes gated with a bearer token
- No SSRF-inviting fetches (user-supplied URLs passed to `fetch` server-side)
- No SQL injection via `pg` (prepared statements / parameterized queries)

4. **Client-side**
- No `dangerouslySetInnerHTML` without sanitization
- No reflected URL params rendered without escaping
- No postMessage / window.ethereum direct access
- localStorage not holding secrets

5. **Dependency surface**
- New deps added? Check they're reputable, pinned, and not duplicating existing functionality.

## Output

Return a bulleted list grouped by severity:

- **High** (fix before merge)
- **Medium** (fix soon)
- **Low / nit** (worth noting)
- **Out of scope / clear** (explicit all-clears are useful for reviewer confidence)

Each finding: `path:line` + one-sentence description + suggested fix.

## Rules

- Do not edit code. Your output is the review.
- Do not re-verify things handled elsewhere (lint, typecheck) unless you find a specific gap.
- Be explicit about what you did **not** check.
30 changes: 30 additions & 0 deletions .claude/agents/ui-verifier.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
name: ui-verifier
description: Boots the dev server and verifies UI changes by loading routes, optionally taking screenshots or driving the page. Use when a UI change needs visual confirmation beyond typecheck/lint/tests.
tools: Read, Bash, Grep, Glob
model: sonnet
---

You are a UI verification agent. Your job is to prove that a rendered page matches intent — not to edit code.

## Workflow

1. Ensure nothing else is on port 3000: `lsof -i :3000 || true`.
2. Start the dev server in the background: `npm run dev &` (or use existing Bash background feature).
3. Poll `curl -sf http://localhost:3000/` until HTTP 200 (or fail after ~60s).
4. For each route under review, `curl http://localhost:3000/<route>` and check for expected markers in the HTML.
5. If the Claude-in-Chrome extension is available, drive the page and report visual state.
6. Stop the dev server when done (`kill %1` or equivalent).

## Output

- **Routes checked** — list with status (200 / 404 / 500) and any content-match result.
- **Observations** — anything surprising (missing provider, hydration warning, console error).
- **Can't verify** — explicit list of things you couldn't check (no browser, no auth, etc.).

## Rules

- Do not edit code. If you find a bug, report it — the parent fixes.
- Do not leave the dev server running. Clean up before returning.
- Do not fabricate screenshots. If the tooling isn't available, say so.
- Treat console errors as signal, not noise — include them in the report.
11 changes: 11 additions & 0 deletions .claude/commands/lint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
description: Run ESLint (next lint).
---

Run:

```bash
npm run lint
```

On success, print "lint: ok". On failure, list the rule + file + line for each violation. `eslint-plugin-only-warn` means most violations print as warnings — still surface them.
16 changes: 16 additions & 0 deletions .claude/commands/new-skill.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
description: Scaffold a new skill in .claude/skills/ following the skill-creator conventions. Pass the skill name as an argument (kebab-case).
---

Scaffold a new skill named `$ARGUMENTS`.

1. Load `.claude/skills/skill-creator/SKILL.md` and its `anatomy.md` / `checklist.md`.
2. Create `.claude/skills/$ARGUMENTS/SKILL.md` with the frontmatter template, with `name` matching the directory name and a **placeholder** description the user must fill in.
3. Leave the body as a template using the section order from `anatomy.md`.
4. Print the checklist from `.claude/skills/skill-creator/checklist.md` and ask the user for:
- the real `description` (the trigger)
- the key files this skill should point at
- any sibling reference files to scaffold
5. Do not commit. The user reviews and edits before merging.

If the directory already exists, stop and ask the user whether to replace or edit.
28 changes: 28 additions & 0 deletions .claude/commands/prime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
description: Prime a fresh session with the project mental model. Syncs external workspaces, then reads the orientation files deterministically.
---

First, sync every external workspace declared in `.claude/externals.json`.
Run:

```
.claude/hooks/externals-sync.sh
```

Surface the script's stdout to the user exactly as-is — it reports per-external state (current SHA, commits fast-forwarded, age vs freshness threshold). If it exits non-zero, stop and surface the message; don't attempt to resolve `.external/` state yourself.

Then read these files in order and summarize back to the user in 5 bullets what this project is, what matters, and how to verify work:

1. `CLAUDE.md`
2. `AGENTS.md`
3. `agent_docs/stack.md`
4. `agent_docs/architecture.md`
5. `agent_docs/verification.md`

Do **not** read skills, agent definitions, or the `docs/` folder — those are Tier-2/3 and load on demand.

Then list the available slash commands (`/verify`, `/typecheck`, `/lint`, `/test`, `/new-skill`, `/review-diff`, `/sync-externals`) and skills by name (from `.claude/skills/`). Do not load their bodies.

If `.claude/externals.json` declares any externals, also list them by name under an "External workspaces:" heading with their current short SHA and age from the sync output above.

End with: "Ready. What's the task?"
92 changes: 92 additions & 0 deletions .claude/commands/realign.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
description: Audit incoming main changes against the agentic-repo patterns and fix drift (stale imports, missing Zod, missing doc entries, etc.). Runs the merging-main skill's playbook.
---

Run the alignment pass after merging / rebasing main into this branch. The
full playbook is at `.claude/skills/merging-main/SKILL.md` — load it before
starting.

## Steps

1. **Capture what came in.**

```bash
git fetch origin main
git log $(git merge-base HEAD origin/main)..origin/main --oneline
```

Read the commit subjects. Every new route / component / hook /
lib-file needs to be traced through the alignment checklist.

2. **Stale lib imports — handled by ESLint.** The folderization rename
table is codified in `eslint.config.js` as a `no-restricted-imports`
rule. Run `npm run lint` and look for any `no-restricted-imports`
warning — the message includes the new path to move the import to.

If you're adding a new rename (e.g. you split another top-level
`src/lib/*.ts` into a subfolder), update both:
1. The `no-restricted-imports` block in `eslint.config.js`.
2. The rename table in `.claude/skills/merging-main/SKILL.md`.

3. **ESLint on new API routes.** The Zod-validation rule is scoped to
`src/app/api/**/route.ts`. A main PR that preceded that rule can
reintroduce imperative validation.

```bash
npx next lint --dir src/app/api 2>&1 | grep -B 2 "no-restricted-syntax" || echo "clean"
```

Any hit → migrate that route using `.claude/skills/next-app-router/api-routes.md`.

4. **TypeScript strictness drift.**

```bash
npx tsc --noEmit
git diff $(git merge-base HEAD origin/main)..HEAD -- src/ | grep -E "^\+.*: any\b|^\+.*as any\b|^\+.*@ts-ignore" | head
```

The second command finds new explicit `any` / `@ts-ignore` added since
the merge base. Fix each with a real type (cast through `unknown` +
interface if the source really is untyped).

5. **Doc indexes.** For every new directory main added under `src/app/`
or `src/components/`, update `agent_docs/architecture.md`. For every
new API route, update `src/app/api/README.md`. For every new hook,
update `src/hooks/README.md`. Also REMOVE entries for routes main
deleted (the skill has a concrete example from PR #109).

6. **Full verify.**

```bash
npm run typecheck
npm run lint
npm run test:run
npm run format:check
```

(`/verify` runs these in sequence.)

7. **UI smoke** on any route main touched. `/verify-ui` boots the dev
server and curls the critical pages.

## Output

Report back to the user:

- **Incoming commits** from main (short-hashes + subjects).
- **Drift caught** — each hit from steps 2–4, with file:line and the fix.
- **Docs updated** — which index files got edits, and what was added or
removed.
- **Verify result** — each step from #6 pass/fail.
- **Outstanding** — anything you flagged but didn't fix (e.g. a main-side
`any` you couldn't retype without more context; a skipped test seed).

## Rules

- Don't modify main's new code for taste or style — only fix **concrete
alignment breaks**: broken imports, ESLint rule violations, `any` that
wasn't there before, missing index entries.
- Don't `git push --force`. This branch is shared; rebases become merges.
- Don't silence the ESLint rule; migrate the route.
- Don't commit yet — return the report and wait for the user to review
before the merge commit is finalized.
Loading
Loading