Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 28 additions & 4 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,23 @@ on:

jobs:
claude:
# Only run for trusted actors. Fork PRs can modify package.json
# scripts; without this gate, an @claude mention on such a PR
# would execute attacker-controlled code under our secrets and
# write permissions.
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && contains(github.event.issue.body, '@claude'))
(github.event_name == 'issue_comment' &&
contains(github.event.comment.body, '@claude') &&
contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) ||
(github.event_name == 'pull_request_review_comment' &&
contains(github.event.comment.body, '@claude') &&
contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) ||
(github.event_name == 'pull_request_review' &&
contains(github.event.review.body, '@claude') &&
contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.review.author_association)) ||
(github.event_name == 'issues' &&
contains(github.event.issue.body, '@claude') &&
contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.issue.author_association))
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
Expand All @@ -26,10 +38,20 @@ jobs:
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
# Initial checkout so GitHub Actions can resolve the local
# composite action below. The composite re-checks out the
# repo itself; this first checkout only needs the .github
# directory.
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 1
sparse-checkout: .github

# Checkout + Node + deps so Claude can run build/lint/format
# scripts when asked.
- name: Set up repo and dependencies
uses: ./.github/actions/setup

- name: Run Claude Code
id: claude
Expand All @@ -38,3 +60,5 @@ jobs:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
additional_permissions: |
actions: read
claude_args: |
--allowed-tools "Bash(npm run build:*) Bash(npm run prettier:*) Bash(npm run eslint:*)"
Comment on lines +63 to +64
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot this should be addressed now, re-check

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-checked: this is addressed in 663249f. The workflow now gates @claude execution to OWNER/MEMBER/COLLABORATOR author associations before any npm-capable Bash tools can run.

4 changes: 2 additions & 2 deletions .github/workflows/upstream-release-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ jobs:
claude_args: |
--model claude-opus-4-7
--max-turns 1000
--allowed-tools "Bash(gh:*)"
--allowed-tools "Bash(gh:*) Bash(npm run build:*) Bash(npm run prettier:*) Bash(npm run eslint:*)"
prompt: |
You are running in GitHub Actions with no interactive user. Follow
these steps exactly and do NOT ask clarifying questions -- proceed
Expand Down Expand Up @@ -752,7 +752,7 @@ jobs:
claude_args: |
--model claude-opus-4-7
--max-turns 200
--allowed-tools "Bash(gh:*)"
--allowed-tools "Bash(gh:*) Bash(npm run build:*) Bash(npm run prettier:*) Bash(npm run eslint:*)"
prompt: |
You are running in GitHub Actions with no interactive user. Follow
these steps exactly and do NOT ask clarifying questions -- proceed
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ The project uses automated tooling to enforce code quality and formatting standa

- **Pre-commit hooks**: lint-staged runs automatically on `git commit`, applying Prettier and appropriate linters to staged files.
- **GitHub Actions**: All PRs trigger automated checks (ESLint, Prettier).
- **No manual formatting needed**: The pre-commit hook handles formatting automatically - you do not need to run formatters manually.
- **Don't rely on the pre-commit hook**: lint-staged only fires on `git commit` when Node, dependencies, and husky are all set up. It silently no-ops in CI and unattended contexts (GitHub Actions, scheduled agents) and in local environments where `npm install` hasn't been run. If you edited content, run `npm run prettier:fix` and `npm run eslint:fix` yourself to avoid lint failures on PR CI.

File type to linter mapping (handled automatically by pre-commit hooks):
File type to linter mapping (run manually if the pre-commit hook doesn't fire):

- `.md` files: Prettier only
- `.mdx` files: Prettier + ESLint
Expand Down