Skip to content

Commit 3ae5d7e

Browse files
authored
Merge pull request #542 from Uniswap/release/next-to-main-20260625-180504
chore(release): promote next to production (2026-06-25)
2 parents 6d35d60 + 6e50003 commit 3ae5d7e

82 files changed

Lines changed: 2453 additions & 399 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude-plugin/marketplace.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
"source": "./packages/plugins/development-productivity",
3131
"description": "Documentation, research, test generation, and prompt optimization tools"
3232
},
33+
{
34+
"name": "skill-management",
35+
"source": "./packages/plugins/skill-management",
36+
"description": "Audit, map, mine, and improve your Claude Code skills, agents, and commands"
37+
},
3338
{
3439
"name": "uniswap-integrations",
3540
"source": "./packages/plugins/uniswap-integrations",
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Response Links Summary
2+
3+
## Instructions for Claude Code
4+
5+
When you finish a turn — that is, you are stopping, **not** asking the user a question and **not** mid-task — end the response with a short `## Links` block: a one-glance, copy-pasteable index of everything actionable from the turn, so the reader doesn't have to scroll back through the work to find it.
6+
7+
## Critical Rules - ALWAYS FOLLOW
8+
9+
### 1. End a stopping turn with a `## Links` block
10+
11+
Include every link that is actionable or referenceable from the turn:
12+
13+
- **PRs / branches** — any PR opened this session AND any PR referenced in-context.
14+
- **Issues / tickets / incidents** — anything touched or referenced (Jira, Linear, incident.io, GitHub issues, etc.).
15+
- **Observability** — dashboards, monitors, notebooks, SLOs, CI/build runs, or traces you cited.
16+
- **Docs / pages** — Notion, Confluence, design docs, runbooks you surfaced.
17+
18+
Group by type when there are several; omit a group that's empty. If there are genuinely no links, **skip the section entirely** — never emit an empty heading.
19+
20+
### 2. Always use full, clickable URLs — never bare IDs
21+
22+
- Render `https://github.com/<org>/<repo>/pull/1234`, not `#1234`.
23+
- Whenever you reference an external component by ID or name in a summary (a monitor, dashboard, ticket, build job, etc.), link it directly — a bare ID forces the reader to go search for it. This applies to **every** summary that names such a component, not only the on-stop block.
24+
25+
### 3. Keep it a trailing index, not the answer
26+
27+
The `## Links` block sits **below** the substantive response and is just URLs plus a few words of label. Don't let it crowd out or replace the actual answer.
28+
29+
## Why
30+
31+
Readers act on these links immediately — open the PR, check the live dashboard, read the ticket. A trailing, grouped, fully-linked index turns "scroll back and reconstruct what was touched" into one glance, and avoids the common failure of citing a bare ID that the reader then has to hunt down.

.github/REUSABLE_WORKFLOWS.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ Notify Release (_notify-release.yml)
218218
219219
| Input | Required | Default | Description |
220220
| ------------------------------- | -------- | -------------------------------- | ---------------------------------------------------------------------------------- |
221-
| `model` | No | `'claude-sonnet-4-6'` | Claude model to use (Sonnet 4.6, Opus 4.7, or Haiku 4.5) |
221+
| `model` | No | `'claude-sonnet-4-6'` | Claude model to use (Sonnet 4.6, Opus 4.8, or Haiku 4.5) |
222222
| `allowed_tools` | No | (permissive defaults, see below) | YAML string specifying which tools Claude can use (file operations, bash commands) |
223223
| `custom_instructions` | No | `'Be sure to follow rules...'` | Additional instructions for Claude beyond CLAUDE.md files |
224224
| `timeout_minutes` | No | `'10'` | Maximum execution time in minutes (prevents runaway costs) |
@@ -282,7 +282,7 @@ The following settings are intentionally fixed to ensure consistent security and
282282

283283
- **Interactive AI Assistance**: Respond to `@claude` mentions anywhere in GitHub
284284
- **Multiple Trigger Points**: Works in issue comments, PR comments, review comments, and reviews
285-
- **Configurable Model**: Choose between Sonnet 4.6 (balanced), Opus 4.7 (thorough), or Haiku 4.5 (fast)
285+
- **Configurable Model**: Choose between Sonnet 4.6 (balanced), Opus 4.8 (thorough), or Haiku 4.5 (fast)
286286
- **Flexible Tool Permissions**: Control what Claude can do (read-only, read-write, or custom)
287287
- **Custom Instructions**: Add repository-specific guidelines and standards
288288
- **Bot Filtering**: Automatically excludes bot comments to prevent loops
@@ -334,7 +334,7 @@ jobs:
334334
secrets:
335335
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
336336
with:
337-
model: 'claude-opus-4-7'
337+
model: 'claude-opus-4-8'
338338
timeout_minutes: '15' # Opus may need more time
339339
```
340340

@@ -423,7 +423,7 @@ jobs:
423423
secrets:
424424
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
425425
with:
426-
model: 'claude-opus-4-7'
426+
model: 'claude-opus-4-8'
427427
timeout_minutes: '15'
428428
```
429429

@@ -546,7 +546,7 @@ Claude says it doesn't have permission to perform action
546546
2. **Choose the Right Model**:
547547

548548
- **Sonnet 4.6** (default): Best balance of speed, capability, and cost for 90% of use cases
549-
- **Opus 4.7**: Reserve for complex architectural reviews or critical security analysis
549+
- **Opus 4.8**: Reserve for complex architectural reviews or critical security analysis
550550
- **Haiku 4.5**: Fast and cost-effective for simple questions, quick lookups, or high-volume usage
551551

552552
3. **Set Appropriate Timeouts**:
@@ -619,7 +619,7 @@ jobs:
619619
secrets:
620620
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
621621
with:
622-
model: 'claude-opus-4-7'
622+
model: 'claude-opus-4-8'
623623
timeout_minutes: '15'
624624
```
625625
@@ -640,7 +640,7 @@ claude-deep:
640640
contains(github.event.pull_request.labels.*.name, 'deep-analysis') &&
641641
# ... (rest of if condition)
642642
with:
643-
model: 'claude-opus-4-7'
643+
model: 'claude-opus-4-8'
644644
```
645645
646646
#### Integration with Other Workflows
@@ -691,7 +691,7 @@ Tips for managing Claude API costs effectively:
691691
692692
- Haiku 4.5: Most cost-effective for simple tasks
693693
- Sonnet 4.6: ~$3 per 1M input tokens, ~$15 per 1M output tokens (default, recommended)
694-
- Opus 4.7: ~$5 per 1M input tokens, ~$25 per 1M output tokens (reserve for complex tasks)
694+
- Opus 4.8: ~$5 per 1M input tokens, ~$25 per 1M output tokens (reserve for complex tasks)
695695
- Typical interaction: 5K-50K tokens (mostly input)
696696
697697
2. **Timeout Strategy**:
@@ -1022,20 +1022,20 @@ This workflow does not have outputs (reviews are submitted directly to GitHub PR
10221022
10231023
**Note**: You must provide either `ANTHROPIC_API_KEY` or `CLAUDE_CODE_OAUTH_TOKEN`. The secrets must be passed explicitly from the calling workflow.
10241024
1025-
#### Permissions Required (Fixed)
1025+
#### Permissions Required (caller must grant these)
10261026
1027-
These permissions are **fixed** in the reusable workflow and cannot be overridden:
1027+
The **calling** workflow must grant its calling job at least these permissions. A reusable workflow cannot be granted more than its caller provides, so granting fewer (for example `contents: read` here) makes GitHub reject the run with a silent `startup_failure` (a ~1s run with no logs):
10281028
10291029
```yaml
10301030
permissions:
10311031
id-token: write # Required for OIDC authentication
1032-
contents: read # Required to read repository code
1032+
contents: write # Required to read code AND push commits when auto_fix is enabled
10331033
pull-requests: write # Required to comment and submit reviews
10341034
issues: read # Required to read PR discussions
10351035
actions: read # Required to check CI status
10361036
```
10371037

1038-
**Note**: You do NOT need to specify these permissions in your calling workflow - they are automatically set by the reusable workflow.
1038+
**Note**: These must be declared on the calling job. See `.github/workflows/examples/08-claude-code-review-basic.yml` for a complete caller.
10391039

10401040
#### Fixed Settings (Cannot be Overridden)
10411041

@@ -1117,7 +1117,7 @@ jobs:
11171117
pr_number: ${{ github.event.pull_request.number }}
11181118
base_ref: ${{ github.base_ref }}
11191119
# Use Opus for PRs with 'claude-opus' label, otherwise Sonnet
1120-
model: ${{ contains(github.event.pull_request.labels.*.name, 'claude-opus') && 'claude-opus-4-7' || 'claude-sonnet-4-6' }}
1120+
model: ${{ contains(github.event.pull_request.labels.*.name, 'claude-opus') && 'claude-opus-4-8' || 'claude-sonnet-4-6' }}
11211121
max_turns: 20 # Allow more turns for thorough Opus reviews
11221122
timeout_minutes: 45 # Longer timeout for complex reviews
11231123
secrets:
@@ -1501,7 +1501,7 @@ Claude submitted multiple reviews instead of updating one
15011501
2. **Model Selection**:
15021502

15031503
- **Sonnet 4.6** (default): Best balance for most PRs (~80% of use cases)
1504-
- **Opus 4.7**: Reserve for critical code, security-sensitive changes, or complex architectures
1504+
- **Opus 4.8**: Reserve for critical code, security-sensitive changes, or complex architectures
15051505
- Use labels to let developers request deeper reviews when needed
15061506

15071507
3. **Custom Prompts**:
@@ -1596,7 +1596,7 @@ jobs:
15961596
with:
15971597
pr_number: ${{ github.event.pull_request.number }}
15981598
base_ref: ${{ github.base_ref }}
1599-
model: 'claude-opus-4-7'
1599+
model: 'claude-opus-4-8'
16001600
custom_prompt_path: '.github/prompts/security-review.md'
16011601
timeout_minutes: 60
16021602
secrets:

.github/workflows/CLAUDE.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ with:
431431
pr_number: ${{ github.event.pull_request.number }}
432432
base_ref: ${{ github.base_ref }}
433433
auto_fix: true # Enable automatic fixing of issues
434-
auto_fix_model: 'claude-opus-4-7' # Use Opus for better fixes (optional)
434+
auto_fix_model: 'claude-opus-4-8' # Use Opus for better fixes (optional)
435435
secrets:
436436
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
437437
WORKFLOW_PAT: ${{ secrets.WORKFLOW_PAT }} # Required for pushing fixes
@@ -638,7 +638,7 @@ uses: Uniswap/ai-toolkit/.github/workflows/_claude-docs-check.yml@main
638638
with:
639639
pr_number: ${{ github.event.pull_request.number }}
640640
auto_fix: true # Enable automatic fixing of documentation issues
641-
auto_fix_model: 'claude-opus-4-7' # Use Opus for better fixes (optional)
641+
auto_fix_model: 'claude-opus-4-8' # Use Opus for better fixes (optional)
642642
secrets:
643643
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
644644
WORKFLOW_PAT: ${{ secrets.WORKFLOW_PAT }} # Required for pushing fixes
@@ -950,7 +950,7 @@ If both are provided, OAuth token takes precedence. At least one authentication
950950

951951
| Input | Default | Description |
952952
| ------------------------- | ----------------- | ----------------------------------------------- |
953-
| `model` | `claude-opus-4-7` | Claude model to use |
953+
| `model` | `claude-opus-4-8` | Claude model to use |
954954
| `max_turns` | `150` | Maximum conversation turns |
955955
| `debug_mode` | `true` | Show full Claude output |
956956
| `timeout_minutes` | `60` | Job timeout |
@@ -989,7 +989,7 @@ with:
989989
issue_url: ${{ matrix.issue_url }}
990990
branch_name: ${{ matrix.branch_name }}
991991
target_branch: 'next'
992-
model: 'claude-opus-4-7'
992+
model: 'claude-opus-4-8'
993993
debug_mode: true
994994
pr_type: 'draft' # or 'published' for non-draft PRs
995995
secrets:
@@ -1009,7 +1009,7 @@ with:
10091009
issue_url: ${{ matrix.issue_url }}
10101010
branch_name: ${{ matrix.branch_name }}
10111011
target_branch: 'next'
1012-
model: 'claude-opus-4-7'
1012+
model: 'claude-opus-4-8'
10131013
debug_mode: true
10141014
pr_type: 'draft'
10151015
secrets:
@@ -1101,7 +1101,7 @@ gh workflow run update-action-versions.yml
11011101
gh workflow run update-action-versions.yml -f dry_run=true
11021102
11031103
# Use Opus model
1104-
gh workflow run update-action-versions.yml -f model=claude-opus-4-7
1104+
gh workflow run update-action-versions.yml -f model=claude-opus-4-8
11051105
```
11061106

11071107
**Usage example (API Key):**
@@ -1237,7 +1237,7 @@ gh workflow run dev-ai-newsletter.yml -f dry_run=true
12371237
gh workflow run dev-ai-newsletter.yml -f days_back=14
12381238
12391239
# Use Opus model for better quality
1240-
gh workflow run dev-ai-newsletter.yml -f model=claude-opus-4-7
1240+
gh workflow run dev-ai-newsletter.yml -f model=claude-opus-4-8
12411241
12421242
# Post to specific Slack channels
12431243
gh workflow run dev-ai-newsletter.yml -f slack_post_channel_ids="C091XE1DNP2,C094URH6C13"

.github/workflows/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ Workflows designed to be called by other workflows using `workflow_call`. These
7575

7676
- Interactive AI assistance via @claude mentions
7777
- Works in issue comments, PR comments, review comments, and reviews
78-
- Configurable models (Sonnet 4.6, Opus 4.7, Haiku 4.5)
78+
- Configurable models (Sonnet 4.6, Opus 4.8, Haiku 4.5)
7979
- Flexible tool permissions (read-only, read-write, or custom)
8080
- Custom instructions for repository-specific standards
8181
- Fixed security settings (Bullfrog scanning, immutable permissions)

.github/workflows/_claude-code-review.yml

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@ name: "[claude] Claude Code Review"
3737
# event when re-requesting reviews from bot accounts. Use the comment trigger
3838
# or manual workflow_dispatch instead.
3939
#
40-
# PERMISSIONS REQUIRED (calling workflow must grant these):
41-
# contents: read
40+
# PERMISSIONS REQUIRED (the calling workflow must grant its calling job at least these;
41+
# a reusable workflow cannot be granted more than its caller provides, so granting fewer
42+
# causes a silent startup_failure: a ~1s run with no logs):
43+
# contents: write # read code AND push commits when auto_fix is enabled
4244
# pull-requests: write
4345
# issues: read
4446
# actions: read
@@ -251,6 +253,14 @@ on:
251253
description: "Personal Access Token with repo scope. Required for: (1) resolving review threads via GraphQL API, and (2) auto-fix pushes that trigger subsequent workflow runs. Falls back to GITHUB_TOKEN if not provided, but auto-fix pushes with GITHUB_TOKEN will NOT trigger new workflow runs."
252254
required: false
253255

256+
# Disable Bun's automatic bunfig.toml loading from CWD. This workflow runs
257+
# `bun run` against post-review scripts; if a caller checks out PR head
258+
# content first, `bun run` would auto-load bunfig.toml from the checkout
259+
# root and `bunfig.toml.preload` would execute arbitrary code with the
260+
# caller's secrets. Propagates to all jobs and steps in this workflow.
261+
env:
262+
BUN_CONFIG_FILE: /dev/null
263+
254264
jobs:
255265
claude-review:
256266
runs-on: ubuntu-latest
@@ -262,7 +272,11 @@ jobs:
262272
NODE_OPTIONS: ""
263273
NPM_CONFIG_REGISTRY: ""
264274
NODE_PATH: ""
265-
# Fixed permissions (cannot be overridden by calling workflow)
275+
# Permissions the CALLING workflow must grant its calling job (matching or higher).
276+
# A reusable workflow cannot be granted more than its caller provides, so a caller that
277+
# declares fewer (e.g. contents: read when this needs contents: write for auto_fix pushes)
278+
# makes GitHub reject the run with a silent startup_failure: a ~1s run with no logs.
279+
# See .github/workflows/examples/08-claude-code-review-basic.yml for a correct caller.
266280
permissions:
267281
id-token: write # Required for OIDC
268282
contents: write # Required to read code and push fixes when auto_fix is enabled
@@ -275,22 +289,51 @@ jobs:
275289
# via attacker-controlled config files (bunfig.toml, .npmrc, etc.) in fork PRs.
276290
# If a legitimate host is missing, the workflow will fail loudly — update the
277291
# allowlist rather than switching back to audit mode.
292+
# Per .github/workflows/CLAUDE.md, bullfrog must be the FIRST step in
293+
# every job on a non-macOS runner ("no exceptions"), so it runs before
294+
# the toolkit_ref validation below. Ordering is safe: bullfrog does not
295+
# consume toolkit_ref, and the validation runs before any step that
296+
# downloads action.yml or post-*.ts content using it.
278297
- name: Security Scan
279298
uses: bullfrogsec/bullfrog@1831f79cce8ad602eef14d2163873f27081ebfb3 # v0.8.4
280299
with:
281300
egress-policy: block
301+
# Per-workflow tightened allowlist. Audit-mode sampling missed
302+
# several destinations because bullfrog v0.8.4 queues DNS *replies*
303+
# (agent/queue_audit.nft) and cached resolutions emit no further
304+
# events. Domains added below as block-mode CI failures revealed:
305+
# - raw.githubusercontent.com: build-plugin-config fetches
306+
# marketplace.json from /Uniswap/ai-toolkit/next/.claude-plugin/.
307+
# - claude.ai: Claude SDK install path (claude.ai/install.sh)
308+
# AND runtime telemetry/session lookup on API-key auth too.
282309
allowed-domains: |
283-
github.com
284-
*.github.com
285-
*.githubusercontent.com
310+
release-assets.githubusercontent.com
311+
raw.githubusercontent.com
286312
api.anthropic.com
287313
claude.ai
288-
*.claude.ai
289-
bun.sh
314+
downloads.claude.ai
290315
registry.npmjs.org
291-
*.npmjs.org
292316
enable-sudo: false
293317

318+
# Validate toolkit_ref BEFORE any downstream step uses it to download
319+
# action.yml / post-*.ts script content from the ai-toolkit repo.
320+
# Without this, an attacker-controlled ref could substitute malicious
321+
# script content that runs inside this job with access to its secrets.
322+
- name: Validate toolkit_ref
323+
env:
324+
TOOLKIT_REF: ${{ inputs.toolkit_ref }}
325+
run: |
326+
case "$TOOLKIT_REF" in
327+
main|next) ;;
328+
*)
329+
if ! printf '%s' "$TOOLKIT_REF" | grep -qE '^[0-9a-fA-F]{40}$'; then
330+
echo "::error::Invalid toolkit_ref: '$TOOLKIT_REF'. Allowed: main, next, or a full 40-char SHA."
331+
exit 1
332+
fi
333+
;;
334+
esac
335+
echo "✅ toolkit_ref validated: $TOOLKIT_REF"
336+
294337
# Checkout required before using local composite actions
295338
- name: Checkout repository
296339
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -1176,7 +1219,7 @@ jobs:
11761219
- name: Run Claude Code Review
11771220
if: steps.cache-check.outputs.cache-hit != 'true' && steps.diff-size.outputs.is_too_large != 'true'
11781221
id: claude
1179-
uses: anthropics/claude-code-action@476e359e6203e73dad705c8b322e333fabbd7416 # v1.0.119
1222+
uses: anthropics/claude-code-action@787c5a0ce96a9a6cfb050ea0c8f4c05f2447c251 # v1.0.133
11801223
with:
11811224
# Authentication: provide either API key or OAuth token (validated in earlier step)
11821225
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
@@ -1669,7 +1712,7 @@ jobs:
16691712
- name: Run Claude Auto-Fix
16701713
id: claude-fix
16711714
if: steps.auto-fix-check.outputs.should_fix == 'true' && steps.pr-branch.outputs.repo_full_name == github.repository
1672-
uses: anthropics/claude-code-action@476e359e6203e73dad705c8b322e333fabbd7416 # v1.0.119
1715+
uses: anthropics/claude-code-action@787c5a0ce96a9a6cfb050ea0c8f4c05f2447c251 # v1.0.133
16731716
with:
16741717
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
16751718
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

0 commit comments

Comments
 (0)