Compare commits

..

362 Commits

Author SHA1 Message Date
GitHub Actions c80896ca84 chore: Update CHANGELOG.md and feed.xml 2026-06-29 23:27:25 +00:00
Roy Arsan 3c3558207e Merge pull request #72363 from anthropics/royarsan/gateway-gcp-agent-platform
Gateway GCP example: Agent Platform rebrand and README cleanup
2026-06-29 18:26:37 -05:00
Roy Arsan f605f0b68d Gateway GCP example: Agent Platform rebrand and README cleanup
- Update Vertex AI prose references to Agent Platform across the example
  (READMEs, script/terraform comments, config template). Functional
  identifiers are unchanged: the 'provider: vertex' config key,
  roles/aiplatform.user, aiplatform.googleapis.com, and the terraform
  resource label (renaming it would recreate the IAM binding in existing
  states). First mentions keep '(formerly Vertex AI)' for searchability.
- Drop the README's self-referential public-mirror link.
2026-06-29 23:13:09 +00:00
Roy Arsan 27e561ba3d Merge pull request #72361 from anthropics/royarsan/gateway-gcp-example
Add Claude Gateway on GCP example deployment assets
2026-06-29 17:45:07 -05:00
Roy Arsan 6234fa8f14 Add Claude Gateway on GCP example deployment assets
Reference artifacts accompanying the Gateway-on-GCP walkthrough
(https://code.claude.com/docs/en/claude-apps-gateway-on-gcp), including
its Terraform reference section:

- setup.sh: scripts the walkthrough end to end via gcloud (APIs, service
  account, image build/push, private-IP Cloud SQL, secrets, Cloud Run)
- Dockerfile: runtime image for the gateway; setup.sh downloads the
  public release binary and verifies it against the release manifest
- gateway.yaml.example: config template (Vertex upstream, Google
  Workspace IdP)
- terraform/: module provisioning the same architecture (Cloud Run track)

Provided as a working example to adapt, not a supported production
deployment.
2026-06-29 21:37:59 +00:00
GitHub Actions 01f1617f14 chore: Update CHANGELOG.md and feed.xml 2026-06-26 21:29:36 +00:00
GitHub Actions f0919a1a72 chore: Update CHANGELOG.md and feed.xml 2026-06-25 21:45:51 +00:00
GitHub Actions 0bd954331e chore: Update CHANGELOG.md and feed.xml 2026-06-24 21:58:06 +00:00
GitHub Actions 5c1517a21b chore: Update CHANGELOG.md and feed.xml 2026-06-24 15:53:49 +00:00
GitHub Actions 2aa6ef3d35 chore: Update CHANGELOG.md and feed.xml 2026-06-23 21:03:40 +00:00
GitHub Actions 12281998d8 chore: Update CHANGELOG.md and feed.xml 2026-06-22 20:37:27 +00:00
GitHub Actions b4073894cd chore: Update CHANGELOG.md and feed.xml 2026-06-20 20:59:12 +00:00
GitHub Actions c487902a53 chore: Update CHANGELOG.md and feed.xml 2026-06-19 01:20:44 +00:00
Ashwin Bhat baf38ddaaa Fix lock-closed-issues workflow: use search API instead of offset pagination (#69470)
The workflow has been failing daily since 2026-04-27 with HTTP 422
"Pagination with the page parameter is not supported for large
datasets" at page=100. The repo now has ~58k closed issues and the
script was paging past ~10k already-locked ones every run before
reaching any candidates.

Replace listForRepo + page=N with the search API
(is:issue is:closed is:unlocked updated:<cutoff), which returns only
the issues that actually need locking. Cap at 250/run with a 1s sleep
between locks to stay under secondary rate limits.

Claude-Session: https://claude.ai/code/session_016EWY3FKCJyfUdCAZkXfi7i
2026-06-18 17:15:49 -07:00
GitHub Actions 4fa369b5b3 chore: Update CHANGELOG.md and feed.xml 2026-06-18 22:03:35 +00:00
william qian 423563cfe3 Update frontend-design skill, bump plugin to 1.1.0 (#69226) 2026-06-17 19:25:44 -07:00
GitHub Actions 0047022a46 chore: Update CHANGELOG.md and feed.xml 2026-06-17 22:07:35 +00:00
GitHub Actions 843959fad9 chore: Update CHANGELOG.md and feed.xml 2026-06-16 20:44:34 +00:00
GitHub Actions 1b7380874c chore: Update CHANGELOG.md and feed.xml 2026-06-16 20:22:06 +00:00
GitHub Actions 64ceb97caa chore: Update CHANGELOG.md and feed.xml 2026-06-15 21:35:48 +00:00
GitHub Actions ca9f6045fc chore: Update CHANGELOG.md and feed.xml 2026-06-12 21:53:22 +00:00
GitHub Actions ee81682a72 chore: Update CHANGELOG.md and feed.xml 2026-06-12 04:23:45 +00:00
GitHub Actions 5754a8bd4f chore: Update CHANGELOG.md and feed.xml 2026-06-12 01:16:30 +00:00
GitHub Actions 3a7c736101 chore: Update CHANGELOG.md and feed.xml 2026-06-11 05:41:48 +00:00
GitHub Actions ca34f27543 chore: Update CHANGELOG.md and feed.xml 2026-06-10 20:44:09 +00:00
GitHub Actions 1c5f951a48 chore: Update CHANGELOG.md and feed.xml 2026-06-09 22:14:36 +00:00
GitHub Actions 6a9c2dbe45 chore: Update CHANGELOG.md and feed.xml 2026-06-09 17:23:03 +00:00
GitHub Actions f967b36c1b chore: Update CHANGELOG.md and feed.xml 2026-06-08 21:57:11 +00:00
GitHub Actions 72281753c2 chore: Update CHANGELOG.md and feed.xml 2026-06-06 23:41:47 +00:00
GitHub Actions c1b75cba5e chore: Update CHANGELOG.md and feed.xml 2026-06-06 01:33:29 +00:00
GitHub Actions 6988846f0f chore: Update CHANGELOG.md and feed.xml 2026-06-06 00:55:13 +00:00
GitHub Actions feabcc3c2b chore: Update CHANGELOG.md and feed.xml 2026-06-05 05:45:00 +00:00
GitHub Actions d1e174252d chore: Update CHANGELOG.md and feed.xml 2026-06-04 21:52:46 +00:00
GitHub Actions b67fa4fa2c chore: Update CHANGELOG.md and feed.xml 2026-06-03 21:31:29 +00:00
GitHub Actions 625c04c335 chore: Update CHANGELOG.md and feed.xml 2026-06-02 21:58:16 +00:00
GitHub Actions bdb04fc524 chore: Update CHANGELOG.md and feed.xml 2026-06-02 02:10:17 +00:00
GitHub Actions 8bae02d531 chore: Update CHANGELOG.md and feed.xml 2026-05-31 19:42:42 +00:00
GitHub Actions 295dee881d chore: Update CHANGELOG.md and feed.xml 2026-05-30 02:42:09 +00:00
GitHub Actions 8d0fbf451a chore: Update CHANGELOG.md and feed.xml 2026-05-29 20:20:32 +00:00
GitHub Actions 2d5c3c6c85 chore: Update CHANGELOG.md and feed.xml 2026-05-29 01:42:17 +00:00
GitHub Actions 1696f22294 chore: Update CHANGELOG.md and feed.xml 2026-05-28 18:00:48 +00:00
GitHub Actions 3bb44552af chore: Update CHANGELOG.md and feed.xml 2026-05-28 00:52:02 +00:00
GitHub Actions b7339920b6 chore: Update CHANGELOG.md and feed.xml 2026-05-27 01:30:52 +00:00
Mohamed Hegazy d08288e09f Merge pull request #62592 from mhegazy/readme-fix
Update security-guidance plugin
2026-05-26 13:21:26 -07:00
Mohamed Hegazy bf4a74d981 Update docs 2026-05-26 13:19:40 -07:00
Mohamed Hegazy ccadef7dcb Merge pull request #62586 from mhegazy/security-guidance-v2
Update security-guidance plugin
2026-05-26 13:00:53 -07:00
Mohamed Hegazy 441892ecee Update security-guidance plugin 2026-05-26 08:10:09 -07:00
GitHub Actions 39e853e407 chore: Update CHANGELOG.md and feed.xml 2026-05-23 04:03:45 +00:00
Ashwin Bhat 5ef2f06c6a Use workload identity federation for Claude auth in CI workflows (#61584)
Replace the static ANTHROPIC_API_KEY secret with Workload Identity
Federation inputs in claude.yml, claude-issue-triage.yml, and
claude-dedupe-issues.yml. The federation rule, organization, service
account, and workspace IDs are read from repository variables.
2026-05-22 15:55:40 -07:00
GitHub Actions 64e53823de chore: Update CHANGELOG.md and feed.xml 2026-05-22 22:09:22 +00:00
GitHub Actions 2194e8e090 chore: Update CHANGELOG.md and feed.xml 2026-05-22 01:16:46 +00:00
GitHub Actions 65d44eb134 chore: Update CHANGELOG.md and feed.xml 2026-05-21 23:54:12 +00:00
Sid Bidasaria efea4c38d9 Merge pull request #61319 from anthropics/remove-changelog-entry
Fix changelog
2026-05-22 00:48:05 +01:00
Claude c6b849f271 Remove changelog entry included in error
https://claude.ai/code/session_01QpYmSoWsmcQFYapvscKSwy
2026-05-21 23:23:10 +00:00
GitHub Actions 15b5d57170 chore: Update CHANGELOG.md and feed.xml 2026-05-21 20:39:15 +00:00
GitHub Actions 1573399b48 chore: Update CHANGELOG.md and feed.xml 2026-05-21 01:51:45 +00:00
GitHub Actions cc898dc369 chore: Update CHANGELOG.md and feed.xml 2026-05-19 21:31:01 +00:00
GitHub Actions b7925a81da chore: Update CHANGELOG.md and feed.xml 2026-05-19 20:38:16 +00:00
GitHub Actions 69d707009e chore: Update CHANGELOG.md and feed.xml 2026-05-19 00:48:45 +00:00
GitHub Actions 2962ecd7a9 chore: Update CHANGELOG.md and feed.xml 2026-05-18 01:52:01 +00:00
GitHub Actions 8bdbb7296d chore: Update CHANGELOG.md 2026-05-15 22:28:17 +00:00
GitHub Actions d61bfb5b56 chore: Update CHANGELOG.md 2026-05-14 22:55:04 +00:00
GitHub Actions c5712671c8 chore: Update CHANGELOG.md 2026-05-13 23:19:09 +00:00
GitHub Actions 6b070c31bc chore: Update CHANGELOG.md 2026-05-12 21:09:38 +00:00
GitHub Actions fdfbc06c7a chore: Update CHANGELOG.md 2026-05-11 18:43:36 +00:00
GitHub Actions 831608a360 chore: Update CHANGELOG.md 2026-05-09 06:33:20 +00:00
GitHub Actions 33a87addb4 chore: Update CHANGELOG.md 2026-05-09 00:10:58 +00:00
Joe Portner f7ef09f496 Merge pull request #56784 from anthropics/devsec/pin-actions
Pin GitHub Actions to commit SHAs
2026-05-08 14:51:39 -04:00
GitHub Actions 2bd8547920 chore: Update CHANGELOG.md 2026-05-08 18:39:01 +00:00
GitHub Actions 6cd790cd21 chore: Update CHANGELOG.md 2026-05-07 23:48:57 +00:00
Octavian Guzu fb063cd5e0 Update HackerOne links in SECURITY.md (#53949)
* Update HackerOne links in SECURITY.md

* Rename VDP heading to Anthropic Bug Bounty
2026-05-07 11:22:37 +01:00
GitHub Actions 60348c9536 chore: Update CHANGELOG.md 2026-05-06 22:08:08 +00:00
jportner 52b9f247d1 Pin GitHub Actions to commit SHAs 2026-05-06 18:43:58 +00:00
GitHub Actions 71135e41b4 chore: Update CHANGELOG.md 2026-05-06 07:47:49 +00:00
GitHub Actions 5c0e4f96eb chore: Update CHANGELOG.md 2026-05-06 01:40:12 +00:00
GitHub Actions 9fce4e6ed1 chore: Update CHANGELOG.md 2026-05-04 23:01:41 +00:00
GitHub Actions 5bf19945e4 chore: Update CHANGELOG.md 2026-05-01 03:11:32 +00:00
GitHub Actions a243cad119 chore: Update CHANGELOG.md 2026-05-01 02:05:18 +00:00
GitHub Actions e512ec9918 chore: Update CHANGELOG.md 2026-04-29 03:29:06 +00:00
GitHub Actions a609cfbee3 chore: Update CHANGELOG.md 2026-04-28 22:05:09 +00:00
GitHub Actions 1586204194 chore: Update CHANGELOG.md 2026-04-28 00:31:24 +00:00
orbisai0security c128568da0 fix: yaml.github-actions.security.run-shell-injection.run-shell-injection security vulnerability (#43824)
Automated security fix generated by Orbis Security AI

Co-authored-by: Ubuntu <ubuntu@ip-172-31-32-15.us-west-2.compute.internal>
2026-04-27 14:33:15 +01:00
GitHub Actions 7e936457e4 chore: Update CHANGELOG.md 2026-04-25 01:55:07 +00:00
GitHub Actions c3933441f0 chore: Update CHANGELOG.md 2026-04-25 00:14:25 +00:00
GitHub Actions ab3ce06c9a chore: Update CHANGELOG.md 2026-04-23 23:24:13 +00:00
Daisy S. Hollman a5fa36cac7 fix: point $schema at schemastore.org (URL was 404) (#52239)
The previous URL never resolved. Points at SchemaStore instead, where the
schema is being added (generated from the Zod source in claude-cli-internal).

Fixes #9686.
2026-04-23 11:27:07 -07:00
GitHub Actions 925200dffc chore: Update CHANGELOG.md 2026-04-23 00:42:15 +00:00
GitHub Actions 9afdfd7dc0 chore: Update CHANGELOG.md 2026-04-22 23:01:47 +00:00
GitHub Actions 2fa67717b8 chore: Update CHANGELOG.md 2026-04-22 00:04:35 +00:00
GitHub Actions fe53778ed9 chore: Update CHANGELOG.md 2026-04-20 22:18:23 +00:00
GitHub Actions 0385848b4e chore: Update CHANGELOG.md 2026-04-18 01:34:25 +00:00
GitHub Actions 71366ecf5d chore: Update CHANGELOG.md 2026-04-17 19:34:36 +00:00
GitHub Actions 2b53fac3b2 chore: Update CHANGELOG.md 2026-04-16 19:55:36 +00:00
GitHub Actions bf77ee65bc chore: Update CHANGELOG.md 2026-04-16 15:18:41 +00:00
GitHub Actions 5a7bf281ba chore: Update CHANGELOG.md 2026-04-16 01:24:06 +00:00
GitHub Actions 4fb8aa4e0a chore: Update CHANGELOG.md 2026-04-15 22:56:07 +00:00
GitHub Actions 45ae2f5212 chore: Update CHANGELOG.md 2026-04-15 22:07:12 +00:00
GitHub Actions f348a16da8 chore: Update CHANGELOG.md 2026-04-15 04:02:09 +00:00
GitHub Actions 5c18c787f2 chore: Update CHANGELOG.md 2026-04-14 19:11:56 +00:00
GitHub Actions 194736a4bd chore: Update CHANGELOG.md 2026-04-14 06:11:15 +00:00
GitHub Actions 550aeecc97 chore: Update CHANGELOG.md 2026-04-13 21:53:07 +00:00
GitHub Actions 9772e13f82 chore: Update CHANGELOG.md 2026-04-10 19:03:35 +00:00
GitHub Actions c5600e0b1e chore: Update CHANGELOG.md 2026-04-09 19:18:23 +00:00
ant-kurt d2b22528db Add MDM deployment example templates (#45866) 2026-04-09 11:41:10 -07:00
bogini 3c72545dfc Merge pull request #45798 from anthropics/inigo/triage-prompt-accuracy
triage: tighten invalid rule, require category label
2026-04-09 08:43:12 -07:00
inigo 54c7be5b3f Tighten invalid-label rule and require a category label on new issues 2026-04-09 08:29:23 -07:00
GitHub Actions 22fdf68049 chore: Update CHANGELOG.md 2026-04-08 21:52:30 +00:00
GitHub Actions 227817d0f2 chore: Update CHANGELOG.md 2026-04-08 04:37:31 +00:00
GitHub Actions b9fbc7796b chore: Update CHANGELOG.md 2026-04-07 21:18:46 +00:00
GitHub Actions b543a25624 chore: Update CHANGELOG.md 2026-04-04 00:41:56 +00:00
GitHub Actions 1e03cc7fc4 chore: Update CHANGELOG.md 2026-04-02 23:45:29 +00:00
GitHub Actions a50a91999b chore: Update CHANGELOG.md 2026-04-01 23:41:27 +00:00
GitHub Actions b4fa5f85f3 chore: Update CHANGELOG.md 2026-04-01 01:07:02 +00:00
GitHub Actions 66ab4ae6e0 chore: Update CHANGELOG.md 2026-03-31 14:35:56 +00:00
Octavian Guzu 4411cbae09 Read issue number from workflow event in helper scripts (#40969)
Updates edit-issue-labels.sh and comment-on-duplicates.sh to read the
issue number from GITHUB_EVENT_PATH (the workflow event payload) instead
of accepting it as a CLI argument. Simplifies the call signature and
keeps the scripts aligned with the triggering issue.

Also updates the /triage-issue and /dedupe command docs to match.

🏠 Remote-Dev: homespace
2026-03-31 12:36:59 +01:00
GitHub Actions 2d5c1bab92 chore: Update CHANGELOG.md 2026-03-30 23:53:01 +00:00
GitHub Actions 78a44f1b7d chore: Update CHANGELOG.md 2026-03-29 02:16:58 +00:00
GitHub Actions 2923bc87d1 chore: Update CHANGELOG.md 2026-03-27 21:42:05 +00:00
GitHub Actions f75b6138ef chore: Update CHANGELOG.md 2026-03-26 22:52:07 +00:00
GitHub Actions a0d9b87038 chore: Update CHANGELOG.md
Fixes #123
2026-03-26 00:30:53 +00:00
GitHub Actions a542f1b4b3 chore: Update CHANGELOG.md 2026-03-25 06:28:41 +00:00
GitHub Actions cada21c89d chore: Update CHANGELOG.md 2026-03-25 06:08:05 +00:00
GitHub Actions 6aadfbdca2 chore: Update CHANGELOG.md 2026-03-20 22:24:03 +00:00
GitHub Actions 16536693ec chore: Update CHANGELOG.md 2026-03-19 22:08:02 +00:00
GitHub Actions 5e34f198d0 chore: Update CHANGELOG.md 2026-03-18 22:28:45 +00:00
GitHub Actions a3d9426e3e chore: Update CHANGELOG.md 2026-03-17 23:42:05 +00:00
GitHub Actions 079dc856c6 chore: Update CHANGELOG.md 2026-03-17 00:27:26 +00:00
GitHub Actions 420a188467 chore: Update CHANGELOG.md 2026-03-14 01:23:05 +00:00
GitHub Actions 48b1c6c0ba chore: Update CHANGELOG.md 2026-03-13 17:16:17 +00:00
kashyap murali 2dc1e69783 Merge pull request #33472 from anthropics/kashyap/code-review-batch-output
feat(code-review): pass confirmed=true when posting inline comments
2026-03-12 00:12:36 -07:00
Kashyap Murali db8834ba1d feat(code-review): pass confirmed=true when posting inline comments
The inline-comment MCP tool now requires confirmed=true to post (otherwise
calls are buffered). This structurally prevents subagent test/probe
comments from reaching customer PRs — subagents that inherit the tool and
probe it without confirmed=true see their calls harmlessly buffered.

Backward compatible: against older versions of claude-code-action that
don't know the param, the extra field is ignored and the comment posts
as before.
2026-03-11 22:16:05 -07:00
GitHub Actions 6f049b620f chore: Update CHANGELOG.md 2026-03-12 00:33:33 +00:00
GitHub Actions 45b5430126 chore: Update CHANGELOG.md 2026-03-11 18:25:53 +00:00
GitHub Actions f6dbf44cd5 chore: Update CHANGELOG.md 2026-03-10 01:16:00 +00:00
GitHub Actions 540b61b9fd chore: Update CHANGELOG.md 2026-03-10 01:04:32 +00:00
GitHub Actions 00553dec20 chore: Update CHANGELOG.md 2026-03-10 00:42:15 +00:00
GitHub Actions 53a5f3ee07 chore: Update CHANGELOG.md 2026-03-07 00:11:59 +00:00
GitHub Actions da80366c48 chore: Update CHANGELOG.md 2026-03-06 01:19:18 +00:00
GitHub Actions 9582ad480f chore: Update CHANGELOG.md
Fixes #28334
Fixes #30185
2026-03-05 00:25:31 +00:00
GitHub Actions 0b3f7cbbbd chore: Update CHANGELOG.md 2026-03-04 10:10:30 +00:00
GitHub Actions a8335230bc chore: Update CHANGELOG.md 2026-03-04 02:23:29 +00:00
GitHub Actions 9c63e985f6 chore: Update CHANGELOG.md 2026-03-04 01:18:30 +00:00
Octavian Guzu 38281cfd46 Merge pull request #30066 from anthropics/oct/gh-wrapper-improvements
Improve gh.sh wrapper: stricter validation and better error messages
2026-03-02 16:38:29 +00:00
Octavian Guzu 26a1334ef3 Improve gh.sh wrapper: stricter validation and better error messages
- Use allowlist for issue view (numeric issue numbers only)
- Enforce zero positional args for issue list / label list
- Pin GH_HOST and GH_REPO explicitly to avoid ambient state
- Add descriptive error messages with usage examples
2026-03-02 12:22:00 +00:00
GitHub Actions cd4956871a chore: Update CHANGELOG.md 2026-02-28 03:44:47 +00:00
bogini a772bd6091 Merge pull request #29462 from anthropics/claude/remove-oncall-label-bGF7H
Remove oncall triage workflow and commands
2026-02-27 16:45:42 -08:00
Claude 35b5fe658a Remove oncall triage workflow and commands
Removes the automated action that adds the "oncall" label to issues,
along with its associated slash commands.

https://claude.ai/code/session_01KdEmZZ4sqZT4d9xJm4qbnp
2026-02-28 00:33:48 +00:00
GitHub Actions 1f48d799b9 chore: Update CHANGELOG.md 2026-02-27 01:55:28 +00:00
GitHub Actions 7ec9125c54 chore: Update CHANGELOG.md 2026-02-26 22:33:45 +00:00
Octavian Guzu 644d6eb37f Merge pull request #28967 from anthropics/oct/increase-oncall-triage-timeout
Increase oncall-triage workflow timeouts
2026-02-26 15:10:28 +00:00
Octavian Guzu e67079be1f Increase oncall-triage workflow timeouts
- Job timeout: 15 -> 25 minutes
- Claude Code step timeout: 10 -> 20 minutes
2026-02-26 12:05:23 +00:00
GitHub Actions 016734047d chore: Update CHANGELOG.md 2026-02-26 03:58:44 +00:00
GitHub Actions d6ab0eafec chore: Update CHANGELOG.md 2026-02-26 00:58:38 +00:00
Octavian Guzu 76c0cbaeb5 Merge pull request #28756 from anthropics/oct/cleanup-workflow-permissions
Remove unused id-token permission and migrate oncall-triage to gh.sh wrapper
2026-02-25 22:12:54 +00:00
Octavian Guzu 23edca9c9b Remove unused id-token permission and migrate oncall-triage to gh.sh wrapper 2026-02-25 22:08:11 +00:00
Octavian Guzu ed58789da7 Merge pull request #28533 from anthropics/oct/gh-wrapper-script
Add gh.sh wrapper for gh CLI commands in triage and dedupe workflows
2026-02-25 20:42:32 +00:00
GitHub Actions ee4ff289f0 chore: Update CHANGELOG.md 2026-02-25 19:59:14 +00:00
Octavian Guzu b2bab3b743 Add gh.sh wrapper for gh CLI commands in workflows 2026-02-25 14:35:57 +00:00
GitHub Actions db3858a558 chore: Update CHANGELOG.md 2026-02-25 06:27:03 +00:00
GitHub Actions a0128f4a40 chore: Update CHANGELOG.md 2026-02-25 03:14:59 +00:00
GitHub Actions 6e7f65eb95 chore: Update CHANGELOG.md 2026-02-25 00:12:59 +00:00
Octavian Guzu 8799bb0901 Merge pull request #28243 from anthropics/oct/non-write-users-check
Add non-write users check workflow
2026-02-24 19:47:31 +00:00
GitHub Actions 05a2bde7be chore: Update CHANGELOG.md 2026-02-24 19:16:03 +00:00
Octavian Guzu 3c917dfe50 Add non-write users check workflow 2026-02-24 18:09:41 +00:00
GitHub Actions 8f0fe03e56 chore: Update CHANGELOG.md 2026-02-24 06:39:08 +00:00
GitHub Actions baf29b882a chore: Update CHANGELOG.md 2026-02-24 02:04:23 +00:00
GitHub Actions 6aecb15d98 chore: Update CHANGELOG.md 2026-02-24 01:40:09 +00:00
Octavian Guzu 76826f2c80 Merge pull request #27911 from anthropics/oct/use-label-script-for-triage
Use wrapper script for label operations in issue triage
2026-02-23 20:07:02 +00:00
Octavian Guzu 3592c8be2a Use wrapper script for label operations in issue triage
Extract triage prompt into /triage-issue command and use a dedicated
edit-issue-labels.sh script for label operations instead of raw
gh issue edit. The script validates labels against the repo's existing
labels before applying them.
2026-02-23 15:11:01 +00:00
GitHub Actions 3ad3231f0f chore: Update CHANGELOG.md 2026-02-20 23:48:06 +00:00
GitHub Actions 65dfa9898e chore: Update CHANGELOG.md 2026-02-20 15:26:36 +00:00
GitHub Actions 0d996a7c34 chore: Update CHANGELOG.md 2026-02-19 23:55:04 +00:00
GitHub Actions b18f2e7df0 chore: Update CHANGELOG.md
Fixes #26637
2026-02-19 23:27:35 +00:00
GitHub Actions b757fc9ecd chore: Update CHANGELOG.md
Fixes #31
Fixes #17600
Fixes #22020
Fixes #23610
Fixes #25721
Fixes #25748
Fixes #25750
Fixes #25756
Fixes #25789
Fixes #25792
Fixes #25803
Fixes #25811
Fixes #25816
Fixes #25824
Fixes #25826
Fixes #25834
Fixes #25837
Fixes #25909
Fixes #25920
Fixes #25935
Fixes #25943
Fixes #25957
Fixes #25981
Fixes #25990
Fixes #26012
Fixes #26023
Fixes #26033
Fixes #26044
Fixes #26051
Fixes #26059
Fixes #26061
Fixes #26064
Fixes #26065
Fixes #26074
Fixes #26075
Fixes #26078
Fixes #26082
Fixes #26084
Fixes #26096
Fixes #26105
Fixes #26121
Fixes #26123
Fixes #26130
Fixes #26136
Fixes #26140
Fixes #26141
Fixes #26188
2026-02-18 21:37:52 +00:00
Chris Lloyd 1718a57495 Fix issues being auto-closed despite human activity (#26360)
The sweep script was closing issues based solely on when a lifecycle label
was applied, ignoring any human comments posted after the label. This caused
active issues (like #11792) to be closed even when users responded to the
stale warning.

Three changes:

1. Teach the triage bot about `stale` and `autoclose` labels so it removes
   them when a human comments on the issue.

2. Add a safety net in `closeExpired()` that checks for non-bot comments
   posted after the lifecycle label was applied — if any exist, skip closing.

3. Extend the 10-upvote protection (which previously only applied to
   enhancements) to all issue types, in both `markStale()` and
   `closeExpired()`.

Fixes #16497

## Test plan

Trace through scenarios manually:
- Issue with stale label + human comment after → triage removes label;
  sweep skips even if triage hasn't run yet (safety net)
- Issue with stale label + no human comment → closes as before
- Issue with 10+ upvotes of any type → never marked stale or closed

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-17 10:53:20 -08:00
GitHub Actions 4523c004dd chore: Update CHANGELOG.md
Fixes #21654
Fixes #22087
Fixes #23561
2026-02-17 18:53:01 +00:00
GitHub Actions 32c7ff2b6e chore: Update CHANGELOG.md 2026-02-17 13:21:46 +00:00
GitHub Actions d787369919 chore: Update CHANGELOG.md 2026-02-16 21:34:15 +00:00
Chris Lloyd 8c09097e8c Post a comment when lifecycle labels are applied to issues (#25665)
When lifecycle labels (needs-info, needs-repro, invalid, stale, autoclose)
are applied to an issue, the author currently only sees a label change with
no explanation. They then get a closing comment days later without ever
being nudged to respond.

Add a GitHub Actions workflow that triggers on issues.labeled and runs a
new lifecycle-comment.ts script to post a comment explaining what's needed
and how long before auto-close.

Extract lifecycle config (labels, timeouts, close reasons, nudge messages)
into a shared issue-lifecycle.ts so the sweep script and comment script
stay in sync. Previously the timeouts were duplicated between the sweep
script and the comment messages.

- needs-info: asks for version, OS, error messages
- needs-repro: asks for steps to trigger the issue
- invalid: links to the Claude Code repo and Anthropic support
- stale/autoclose: explains inactivity auto-close

The script no-ops for non-lifecycle labels, so the workflow fires on every
label event and lets the script decide — single source of truth.

## Test plan

Dry-run all labels locally:
GITHUB_REPOSITORY=anthropics/claude-code LABEL=needs-info ISSUE_NUMBER=12345 bun run scripts/lifecycle-comment.ts --dry-run
GITHUB_REPOSITORY=anthropics/claude-code LABEL=needs-repro ISSUE_NUMBER=12345 bun run scripts/lifecycle-comment.ts --dry-run
GITHUB_REPOSITORY=anthropics/claude-code LABEL=invalid ISSUE_NUMBER=12345 bun run scripts/lifecycle-comment.ts --dry-run
GITHUB_REPOSITORY=anthropics/claude-code LABEL=stale ISSUE_NUMBER=12345 bun run scripts/lifecycle-comment.ts --dry-run
GITHUB_REPOSITORY=anthropics/claude-code LABEL=autoclose ISSUE_NUMBER=12345 bun run scripts/lifecycle-comment.ts --dry-run

Verified sweep.ts still works:
GITHUB_TOKEN=$(gh auth token) GITHUB_REPOSITORY_OWNER=anthropics GITHUB_REPOSITORY_NAME=claude-code bun run scripts/sweep.ts --dry-run
2026-02-13 19:39:10 -08:00
Chris Lloyd edfb5437a4 Fix sweep script crashing on locked issues (#25649)
The sweep job (https://github.com/anthropics/claude-code/actions/runs/21983111029/job/63510453226)
was silently failing when closeExpired tried to comment on a locked issue,
causing a 403 from the GitHub API.

Two issues:

1. closeExpired didn't skip locked issues like markStale already does.
   Adding the same `if (issue.locked) continue` guard fixes this.

2. The error was swallowed by `main().catch(console.error)` which logs
   to stderr but exits 0, so CI reported success despite the crash.
   Replaced the main() wrapper with top-level await so unhandled errors
   properly crash the process with a non-zero exit code.

## Test plan

YOLO
2026-02-13 15:40:00 -08:00
GitHub Actions b374a30699 chore: Update CHANGELOG.md 2026-02-13 20:01:23 +00:00
GitHub Actions a01a88d5ee chore: Update CHANGELOG.md 2026-02-13 19:55:44 +00:00
GitHub Actions 42c62d73ce chore: Update CHANGELOG.md 2026-02-13 17:43:37 +00:00
GitHub Actions 1b50583382 chore: Update CHANGELOG.md 2026-02-13 06:07:54 +00:00
GitHub Actions 232213304d chore: Update CHANGELOG.md 2026-02-12 21:17:39 +00:00
Chris Lloyd a93966285e Unify issue lifecycle labeling and sweep into a single system (#25352)
* Unify issue lifecycle labeling and sweep into a single system

Consolidate issue triage, stale detection, and lifecycle enforcement into
two components: a Claude-powered triage workflow and a unified sweep script.

Triage workflow changes:
- Add issue_comment trigger so Claude can re-evaluate lifecycle labels when
  someone responds to a needs-repro/needs-info issue
- Add concurrency group per issue with cancel-in-progress to avoid pile-up
- Filter out bot comments to prevent sweep/dedupe triggering re-triage
- Hardcode allowed label whitelist to prevent label sprawl (was discovering
  labels via gh label list, leading to junk variants like 'needs repro' vs
  'needs-repro')
- Replace MCP GitHub server with gh CLI — simpler, no Docker dependency,
  chaining is caught by the action so permissions are equivalent
- Add lifecycle labels (needs-repro, needs-info) for bugs missing info
- Add invalid label for off-topic issues (Claude API, billing, etc.)
- Add anti-patterns to prevent false positives (don't require specific
  format, model behavior issues don't need traditional repro, etc.)

Sweep script changes:
- Absorb stale issue detection (was separate stale-issue-manager workflow)
- Mark issues as stale after 14 days of inactivity
- Skip assigned issues (team is working on it internally)
- Skip enhancements with 10+ thumbs up (community wants it)
- Add invalid label with 3-day timeout
- Add autoclose label support to drain 200+ legacy issues
- Drop needs-votes (stale handles inactive enhancements)
- Unify close messages into a single template with per-label reasons
- Run 2x daily instead of once

Delete stale-issue-manager.yml — its logic is now in sweep.ts.

## Test plan

Dry-run sweep locally:
GITHUB_TOKEN=$(gh auth token) GITHUB_REPOSITORY_OWNER=anthropics   GITHUB_REPOSITORY_NAME=claude-code bun run scripts/sweep.ts --dry-run

Triage workflow will be tested by opening a test issue after merge.

* Update .github/workflows/claude-issue-triage.yml

Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>

---------

Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>
2026-02-12 11:45:31 -08:00
GitHub Actions 0931fb76da chore: Update CHANGELOG.md 2026-02-12 17:25:52 +00:00
Chris Lloyd bac22cb316 Merge pull request #25210 from anthropics/chrislloyd/sweep-lifecycle-labels
Add daily sweep to enforce issue lifecycle label timeouts
2026-02-12 07:26:14 -08:00
GitHub Actions 77df0af778 chore: Update CHANGELOG.md 2026-02-12 09:24:03 +00:00
Chris Lloyd a17040212c Add daily sweep to enforce issue lifecycle label timeouts
Introduce a simple, mechanical daily sweep that closes issues with
lifecycle labels past their timeout:

- needs-repro: 7 days
- needs-info: 7 days
- needs-votes: 30 days
- stale: 30 days

The sweep checks when the label was last applied via the events API,
and closes the issue if the timeout has elapsed. No AI, no comment
checking — if the label is still there past its timeout, close it.
Removing a label (by a triager, slash command, or future AI retriage)
is what prevents closure.

Each close message directs the reporter to open a new issue rather
than engaging with the closed one.

The script supports --dry-run for local testing:
  GITHUB_TOKEN=$(gh auth token) \
  GITHUB_REPOSITORY_OWNER=anthropics \
  GITHUB_REPOSITORY_NAME=claude-code \
  bun run scripts/sweep.ts --dry-run

## Test plan

Ran --dry-run against anthropics/claude-code. Correctly identified 3
issues past their timeouts (1 needs-repro at 12d, 2 needs-info at
14d and 26d). No false positives.
2026-02-11 22:34:23 -08:00
GitHub Actions 76a2154fd5 chore: Update CHANGELOG.md 2026-02-12 05:59:28 +00:00
GitHub Actions aca4801e91 chore: Update CHANGELOG.md 2026-02-12 01:56:04 +00:00
kashyap murali f2a930799b Merge pull request #25102 from anthropics/fvolcic/code-review-comment-update
fix: Do not comment if --comment is not present
2026-02-11 23:26:35 +01:00
Franklin Volcic 6dcc7d8b76 ensure comments are not left if --comment is not present 2026-02-11 13:42:06 -08:00
GitHub Actions 0a0135f687 chore: Update CHANGELOG.md 2026-02-11 16:20:54 +00:00
GitHub Actions e74abe58ab chore: Update CHANGELOG.md 2026-02-11 16:07:18 +00:00
GitHub Actions 7a7bed74e3 chore: Update CHANGELOG.md 2026-02-11 15:54:36 +00:00
GitHub Actions 9b64827a25 chore: Update CHANGELOG.md 2026-02-11 09:49:08 +00:00
GitHub Actions 54f0b535b3 chore: Update CHANGELOG.md 2026-02-11 09:47:22 +00:00
GitHub Actions 675baffdb3 chore: Update CHANGELOG.md 2026-02-11 08:54:27 +00:00
GitHub Actions bae169824d chore: Update CHANGELOG.md 2026-02-11 08:39:40 +00:00
GitHub Actions 0b641a77ce chore: Update CHANGELOG.md 2026-02-11 08:21:20 +00:00
GitHub Actions be5d08fe5f chore: Update CHANGELOG.md 2026-02-10 23:10:48 +00:00
GitHub Actions 19bb071fe0 chore: Update CHANGELOG.md 2026-02-10 00:52:42 +00:00
GitHub Actions 85f2807991 chore: Update CHANGELOG.md 2026-02-07 19:09:18 +00:00
GitHub Actions e7f36bcdf0 chore: Update CHANGELOG.md 2026-02-07 18:01:26 +00:00
GitHub Actions 2bc62d1456 chore: Update CHANGELOG.md 2026-02-06 14:26:00 +00:00
GitHub Actions ef1e0ac098 chore: Update CHANGELOG.md 2026-02-06 01:46:32 +00:00
GitHub Actions d7e3cfb31c chore: Update CHANGELOG.md 2026-02-05 17:47:04 +00:00
GitHub Actions bd78b216ed chore: Update CHANGELOG.md 2026-02-04 00:43:28 +00:00
GitHub Actions a4e0c5b4c8 chore: Update CHANGELOG.md 2026-02-03 18:05:15 +00:00
ant-kurt 36d9ee2c2e Merge pull request #22072 from anthropics/kurt/settings-examples
docs: add examples/settings
2026-02-02 11:35:31 -08:00
ant-kurt 4936302293 Update settings-strict.json 2026-02-01 22:44:32 -08:00
ant-kurt 43d0eac708 Update settings-bash-sandbox.json 2026-02-01 22:44:11 -08:00
GitHub Actions f298d940fa chore: Update CHANGELOG.md 2026-01-31 23:37:08 +00:00
GitHub Actions 34f551fa91 chore: Update CHANGELOG.md 2026-01-31 02:30:24 +00:00
Kurt Carpenter 90c07d1c7e Stricter sandbox config 2026-01-30 16:59:39 -08:00
Kurt Carpenter f93f614768 docs: example settings files 2026-01-30 16:57:26 -08:00
GitHub Actions e58014371b chore: Update CHANGELOG.md 2026-01-30 23:06:12 +00:00
GitHub Actions 5862adf641 chore: Update CHANGELOG.md 2026-01-30 20:38:17 +00:00
GitHub Actions 38f1f93052 chore: Update CHANGELOG.md 2026-01-29 21:12:53 +00:00
GitHub Actions cf98f1d943 chore: Update CHANGELOG.md 2026-01-29 01:09:14 +00:00
GitHub Actions 266d7c8c9f chore: Update CHANGELOG.md 2026-01-29 00:58:32 +00:00
GitHub Actions 73eddfd640 chore: Update CHANGELOG.md 2026-01-28 06:59:20 +00:00
GitHub Actions 8c48d2f508 chore: Update CHANGELOG.md 2026-01-28 02:24:46 +00:00
GitHub Actions 3f9a645986 chore: Update CHANGELOG.md 2026-01-27 03:48:22 +00:00
GitHub Actions 9f6b6d17de chore: Update CHANGELOG.md 2026-01-27 01:34:59 +00:00
GitHub Actions e9a9efc121 chore: Update CHANGELOG.md 2026-01-23 21:55:58 +00:00
GitHub Actions 10e6348e77 chore: Update CHANGELOG.md 2026-01-22 21:45:53 +00:00
GitHub Actions e431f5b496 chore: Update CHANGELOG.md 2026-01-22 20:08:52 +00:00
GitHub Actions 052a1317c0 chore: Update CHANGELOG.md 2026-01-21 22:00:41 +00:00
GitHub Actions a6a8045031 chore: Update CHANGELOG.md 2026-01-20 23:09:04 +00:00
GitHub Actions 74cc597eb5 chore: Update CHANGELOG.md 2026-01-17 16:17:56 +00:00
GitHub Actions 923d727492 chore: Update CHANGELOG.md 2026-01-17 01:38:55 +00:00
GitHub Actions fb3a947cb5 chore: Update CHANGELOG.md 2026-01-16 17:12:36 +00:00
Franklin Volcic 2961ddcafe Merge pull request #18489 from anthropics/fvolcic/minor-code-review-fixes
minor code review updates
2026-01-15 21:31:02 -08:00
Franklin Volcic fd8f3801b9 minor update 2026-01-15 21:29:38 -08:00
Franklin Volcic 26315247e7 Minor code review fixes 2026-01-15 21:12:50 -08:00
GitHub Actions 5a91286a82 chore: Update CHANGELOG.md 2026-01-16 02:19:08 +00:00
GitHub Actions 3196f36cee chore: Update CHANGELOG.md 2026-01-15 23:28:44 +00:00
JB 7d22b6e167 Merge pull request #18238 from anthropics/hackyon/update-to-claude-code-action
chore: allow non-write users to trigger claude-code-action workflows
2026-01-14 18:12:25 -05:00
JB 19a829ba68 chore: allow non-write users to trigger claude-code-action workflows
Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-14 18:11:06 -05:00
JB 18979efb8d Merge pull request #18209 from anthropics/hackyon/update-to-claude-code-action
fix: add github_token input to claude-code-action workflows
2026-01-14 16:31:27 -05:00
JB f77acdf149 fix: add github_token input to claude-code-action workflows 2026-01-14 14:42:11 -05:00
JB c13cf781ef Merge pull request #18206 from anthropics/hackyon/update-to-claude-code-action
chore: add id-token write permission for claude-code-action workflows
2026-01-14 14:21:23 -05:00
JB cc70d3ab50 chore: add id-token write permission for claude-code-action workflows
The claude-code-action requires id-token: write permission for OIDC authentication.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Generated-By: Claude Code (cli/claude-opus-4-5=100%)
Claude-Steers: 3
Claude-Permission-Prompts: 3
Claude-Escapes: 0
2026-01-14 14:16:13 -05:00
JB 250b257c4e Merge pull request #18198 from anthropics/hackyon/update-to-claude-code-action
chore: migrate workflows from claude-code-base-action to claude-code-action
2026-01-14 13:51:04 -05:00
JB dec754edc9 chore: migrate workflows from claude-code-base-action to claude-code-action
Updates GitHub workflow files to use the new claude-code-action@v1 and replaces prompt_file with inline prompt parameter.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Generated-By: Claude Code (cli/claude-opus-4-5=100%)
Claude-Steers: 3
Claude-Permission-Prompts: 4
Claude-Escapes: 0
2026-01-14 13:12:00 -05:00
GitHub Actions 6a2936ab79 chore: Update CHANGELOG.md 2026-01-14 00:03:57 +00:00
GitHub Actions f860f671dc chore: Update CHANGELOG.md 2026-01-13 02:25:43 +00:00
ant-kurt 76df7eea04 Merge pull request #17797 from anthropics/docs/update-installation-instructions
docs: update installation instructions in README
2026-01-12 15:22:53 -08:00
ant-kurt a8d107f9cc Merge pull request #16459 from nelsonauner/patch-1
Fix broken doc link
2026-01-12 15:17:19 -08:00
Kurt Carpenter b640d94a49 docs: update installation instructions in README
- Add note that npm installation is deprecated
- Add link to setup documentation
- Add WinGet installation option for Windows
- Update Homebrew to indicate MacOS/Linux support
- Mark recommended installation methods
- Improve formatting with proper indentation
2026-01-12 15:12:24 -08:00
ant-kurt b17c088cdc Merge pull request #17238 from anthropics/ci/update-base-action
ci: update claude-code-base-action and claude-code-action to v1
2026-01-12 11:38:56 -08:00
GitHub Actions a856c62014 chore: Update CHANGELOG.md 2026-01-12 18:48:06 +00:00
GitHub Actions 0359f24538 chore: Update CHANGELOG.md 2026-01-11 00:28:09 +00:00
Kurt Carpenter b8497141a5 chore: upgrade claude-code actions from @beta to @v1
- Update action references from @beta to @v1
- Move allowed_tools to --allowedTools in claude_args
- Move mcp_config to --mcp-config in claude_args
- Move claude_env to step-level env block
- Replace timeout_minutes with GitHub native timeout-minutes

Claude-Generated-By: Claude Code (cli/claude-opus-4-5=100%)
Claude-Steers: 8
Claude-Permission-Prompts: 3
Claude-Escapes: 0
2026-01-09 18:54:19 -08:00
Kurt Carpenter 9cc635aac1 ci: update claude-code-base-action and claude-code-action to v1 2026-01-09 18:24:29 -08:00
GitHub Actions 4f18698a9e chore: Update CHANGELOG.md 2026-01-09 23:32:24 +00:00
GitHub Actions 553d6ffc3e chore: Update CHANGELOG.md 2026-01-09 00:04:20 +00:00
Franklin Volcic 7b600bca3b Merge pull request #16938 from fvolcic/fix-committable-suggestions-docs
refactor(code-review): improve issue flagging and agent behavior
2026-01-08 15:49:22 -05:00
Franklin Volcic 4700be03eb revert: restore marketplace.json to upstream state 2026-01-08 15:46:40 -05:00
Franklin Volcic 9b08c1010b refactor(code-review): simplify inline comment instructions and clarify issue criteria
1. Remove redundant tool parameter descriptions - MCP tool is source of truth

2. Clarify what issues to flag:
   - Compile/parse errors (syntax, types, imports, references)
   - Clear logic errors that produce wrong results regardless of inputs
   - CLAUDE.md violations

3. Clarify what NOT to flag:
   - Code style or quality concerns
   - Issues that depend on specific inputs or state
   - Subjective suggestions
2026-01-08 15:43:21 -05:00
Thariq Shihipar f34e2535b4 Merge pull request #16743 from anthropics/ThariqS-patch-1
Update CHANGELOG.md to reference IS_DEMO
2026-01-07 18:16:58 -06:00
GitHub Actions 4297e57ef1 chore: Update CHANGELOG.md 2026-01-08 00:16:11 +00:00
Thariq Shihipar 0d0221fd0a Update CHANGELOG.md to reference IS_DEMO 2026-01-07 16:14:39 -08:00
GitHub Actions 5aac2b1b6a chore: Update CHANGELOG.md 2026-01-07 21:30:49 +00:00
GitHub Actions 2bb8af55fa chore: Update CHANGELOG.md 2026-01-07 20:36:59 +00:00
Boris Cherny a19dd76dcf Merge pull request #16686 from anthropics/bcherny-patch-7
Update CHANGELOG.md
2026-01-07 12:31:21 -08:00
Boris Cherny 63eefe157a Update CHANGELOG.md 2026-01-07 12:30:35 -08:00
GitHub Actions 870624fc15 chore: Update CHANGELOG.md 2026-01-07 20:03:52 +00:00
Franklin Volcic 2c3884689b Rename marketplace to franklin-plugins for sandbox testing 2026-01-07 13:50:23 -05:00
David Dworken 03129a27b0 Merge pull request #16635 from ddworken/dworken/validate-issue-exists
fix: validate that issues exist before commenting on duplicates
2026-01-07 11:03:50 -05:00
David Dworken a3df424857 fix: validate that issues exist before commenting on duplicates
Add validation to comment-on-duplicates.sh that verifies the base issue
and all potential duplicate issues actually exist in the repo before
posting a comment.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-07 07:57:56 -08:00
Boris Cherny 0b86fdb0e0 fix(security): Remove overly broad gh api permission from dedupe command (#16549)
* fix(security): Remove overly broad gh api permission from dedupe command

Remove `Bash(gh api:*)` from dedupe.md allowed-tools to prevent potential
secret exfiltration via prompt injection. The dedupe workflow only needs
gh issue view/list/comment and gh search commands - it doesn't require
raw API access.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: Add comment-on-duplicates script for safer duplicate handling

Replace `gh issue comment:*` permission with a constrained script that:
- Only accepts validated issue numbers
- Enforces max 3 duplicates
- Uses a fixed comment format
- Prevents arbitrary comment content injection

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-07 08:46:31 +05:30
Anthony Morris c2022d3698 fix(ralph-wiggum): add :* to allowed-tools pattern to permit arguments (#16522)
The allowed-tools pattern was missing :* suffix, causing permission check
failures when arguments were passed to the setup script via ```! block.

Fixes #16398
2026-01-06 13:46:09 -08:00
sarahdeaton e515f50dff Merge pull request #16474 from anthropics/fix-data-usage-link
docs: Fix links to Claude Code docs in README.
2026-01-06 11:23:17 -08:00
Sarah Deaton 24ad98a95f docs: Fix links to Claude Code docs in README. 2026-01-06 06:47:41 -08:00
Nelson Auner 495d6a3d4b Fix broken doc link
Current doc link is dated, no longer exists
2026-01-06 05:26:23 -08:00
Anthony Morris 5c92b97cc4 fix(ralph-wiggum): move multi-line bash from command to setup script (#16320)
Fixes #12170

The ralph-wiggum slash commands had multi-line bash scripts in their
```! blocks. Claude Code's security check blocks commands with
newlines to prevent command injection, causing the error:

  "Command contains newlines that could separate multiple commands"

Changes:

ralph-loop.md:
- Remove multi-line bash from code block
- Keep single-line call to setup script
- Keep scoped allowed-tools for security

cancel-ralph.md:
- Replace multi-line bash with step-by-step instructions
- Tighten allowed-tools to specific file paths

setup-ralph-loop.sh:
- Add completion promise display logic (moved from ralph-loop.md)
- Uses COMPLETION_PROMISE variable directly instead of reading from file
2026-01-04 23:27:48 -08:00
GitHub Actions d213a74fc8 chore: Update CHANGELOG.md 2025-12-19 22:13:14 +00:00
GitHub Actions 52115592ba chore: Update CHANGELOG.md 2025-12-19 00:59:25 +00:00
Franklin Volcic 5d2df70860 Merge pull request #14527 from anthropics/fvolcic/code-review-updates
Improve code review inline comments
2025-12-18 13:52:59 -08:00
Franklin Volcic b8a2ffb38f Require committable suggestions to be complete
Suggestions must include all necessary changes. If a fix requires
additional work elsewhere (e.g., renaming a variable requires updating
usages), use the Claude Code prompt format instead of a partial suggestion.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-18 13:30:25 -08:00
Franklin Volcic 9fd556d947 Skip summary comment when posting inline comments
Only post a summary comment when no issues are found. When issues
exist, post inline comments directly without a redundant summary block.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-18 13:24:03 -08:00
Franklin Volcic b31e2fd182 Merge pull request #14385 from anthropics/fvolcic/inline-comments
Add inline comments with suggestions to code-review plugin
2025-12-17 15:55:23 -08:00
Franklin Volcic d2cb503247 Remove header, add Claude Code prompt for larger fixes 2025-12-17 15:32:23 -08:00
Franklin Volcic 5fe61207ff Allow committable suggestions up to 5 lines 2025-12-17 15:28:50 -08:00
Franklin Volcic 1ed82e6af0 Refine inline comment formatting: no Bug prefix, summary first, limit suggestion size 2025-12-17 15:27:37 -08:00
Franklin Volcic 2a61cb364c Add inline comments with suggestions to code-review plugin 2025-12-17 15:20:12 -08:00
GitHub Actions 6880bcbace chore: Update CHANGELOG.md 2025-12-17 21:55:53 +00:00
GitHub Actions 4392352687 chore: Update CHANGELOG.md 2025-12-16 22:06:07 +00:00
kashyap murali c27c6f4e4a Merge pull request #14071 from anthropics/claude/slack-make-no-comment-default-Qqha8
Make no-comment the default for /code-review
2025-12-16 12:22:18 -08:00
GitHub Actions 0dde1fef97 chore: Update CHANGELOG.md 2025-12-15 23:49:39 +00:00
Claude e4f682030b Make no-comment the default for /code-review
Change the default behavior of /code-review to output to the terminal
instead of posting a PR comment. Users can use the --comment flag to
explicitly post the review as a PR comment when desired.

This is more suitable for local development workflows where posting
comments to the PR is not always needed.
2025-12-15 17:50:32 +00:00
GitHub Actions eb87245010 chore: Update CHANGELOG.md 2025-12-13 00:59:55 +00:00
GitHub Actions 3680637065 chore: Update CHANGELOG.md 2025-12-12 23:31:50 +00:00
GitHub Actions 2192c86c20 chore: Update CHANGELOG.md 2025-12-12 01:29:45 +00:00
kashyap murali dfd3494132 Merge pull request #13739 from anthropics/claude/slack-session-01GzKi42xM3SphuxeQ4De88U
Remove footer from code-review plugin output
2025-12-11 14:42:30 -08:00
Claude e8cca9a7af Remove footer from code-review plugin output
Remove the "Generated with Claude Code" footer and feedback CTA
from the code review comment template as it adds noise without
providing value after the first viewing.
2025-12-11 22:40:32 +00:00
GitHub Actions 6358669884 chore: Update CHANGELOG.md 2025-12-11 19:07:31 +00:00
GitHub Actions ace0a82778 chore: Update CHANGELOG.md 2025-12-11 04:39:56 +00:00
GitHub Actions e095e1270a chore: Update CHANGELOG.md 2025-12-10 08:18:47 +00:00
GitHub Actions 69da5e8269 chore: Update CHANGELOG.md 2025-12-10 02:27:37 +00:00
GitHub Actions 7069a25987 chore: Update CHANGELOG.md 2025-12-09 02:08:28 +00:00
GitHub Actions de49a07679 chore: Update CHANGELOG.md 2025-12-07 10:44:43 +00:00
Franklin Volcic cbc55b7d54 Merge pull request #13177 from anthropics/fvolcic/code-review-command-updates 2025-12-05 18:22:08 -08:00
Franklin Volcic e836d4ea90 fix allowed tools list 2025-12-05 17:55:00 -08:00
Franklin Volcic 52465789e2 fix allowed tools list 2025-12-05 17:54:25 -08:00
Franklin Volcic 9babb8dbbf Update the code review prompt 2025-12-05 17:48:34 -08:00
GitHub Actions b1a46e6623 chore: Update CHANGELOG.md 2025-12-06 00:06:43 +00:00
GitHub Actions 5ef1391afc chore: Update CHANGELOG.md 2025-12-04 23:06:16 +00:00
GitHub Actions 337cc419c3 chore: Update CHANGELOG.md 2025-12-03 20:06:45 +00:00
GitHub Actions 5e98326f42 chore: Update CHANGELOG.md 2025-12-03 19:25:03 +00:00
GitHub Actions 56a3ef77c5 chore: Update CHANGELOG.md 2025-12-03 12:16:31 +00:00
GitHub Actions 5b69f85043 chore: Update CHANGELOG.md 2025-12-03 05:15:40 +00:00
Ashwin Bhat 5e3e9408fe Revert "Revert "Add stale issue management workflows" (#9304)" (#12917)
This reverts commit a6e0921729.
2025-12-02 15:19:09 -08:00
GitHub Actions 4928f2cdca chore: Update CHANGELOG.md 2025-12-02 01:31:29 +00:00
GitHub Actions 84d7b08539 chore: Update CHANGELOG.md 2025-11-26 23:57:28 +00:00
GitHub Actions 10b8736b55 chore: Update CHANGELOG.md 2025-11-26 17:22:35 +00:00
GitHub Actions 29a5fe7eca chore: Update CHANGELOG.md 2025-11-26 01:03:45 +00:00
Stephen Grider 26b5c07c59 Merge pull request #12409 from anthropics/sgrider/plugin-1125
chore: alphabetize plugins and update README with comprehensive table
2025-11-25 15:36:50 -07:00
Stephen Grider 4ae2cb4e5e chore: alphabetize plugins and update README with comprehensive table 2025-11-25 15:00:24 -07:00
GitHub Actions 3464c7955f chore: Update CHANGELOG.md 2025-11-24 23:28:19 +00:00
William Hu 5880baedc3 Merge pull request #12280 from anthropics/whu/opus-migration
Claude Opus 4.5 migration plugin
2025-11-24 11:05:28 -08:00
GitHub Actions 47d996cb4a chore: Update CHANGELOG.md 2025-11-24 18:51:46 +00:00
GitHub Actions 34dcaa13bc chore: Update CHANGELOG.md 2025-11-24 18:45:14 +00:00
William Hu a194a9d41b Claude Opus 4.5 migration plugin 2025-11-23 23:24:09 -08:00
GitHub Actions eb39543260 chore: Update CHANGELOG.md 2025-11-21 23:28:28 +00:00
GitHub Actions b83c5cfda3 chore: Update CHANGELOG.md 2025-11-21 23:13:29 +00:00
Steve M 5a17f570db docs: Update README with skills and hooks sections (#11818)
* docs: Update README with skills and hooks sections

Added sections for skills and hooks to the plugin structure per the [official documentation](https://code.claude.com/docs/en/plugins#plugin-structure-overview).

* docs: add .mcp.json

---------

Co-authored-by: Anthony Morris <amorriscode@gmail.com>
2025-11-21 01:39:58 -08:00
GitHub Actions bcda757fff chore: Update CHANGELOG.md 2025-11-21 01:28:41 +00:00
GitHub Actions 3c95987059 chore: Update CHANGELOG.md 2025-11-21 00:30:58 +00:00
GitHub Actions 021b91b5eb chore: Update CHANGELOG.md 2025-11-19 23:08:43 +00:00
GitHub Actions 13a258a3fe chore: Update CHANGELOG.md 2025-11-19 04:37:08 +00:00
GitHub Actions 68ba47859a chore: Update CHANGELOG.md 2025-11-18 16:47:22 +00:00
Daisy S. Hollman c508e59e8a Merge pull request #11780 from anthropics/daisy/plugin-dev/public-marketplace
Add plugin-dev toolkit for comprehensive plugin development
2025-11-17 22:54:12 -08:00
GitHub Actions 8f34f4744d chore: Update CHANGELOG.md 2025-11-18 00:26:04 +00:00
Daisy S. Hollman 387dc35db7 feat: Add plugin-dev toolkit for comprehensive plugin development
Adds the plugin-dev plugin to public marketplace. A comprehensive toolkit for
developing Claude Code plugins with 7 expert skills, 3 AI-assisted agents, and
extensive documentation covering the complete plugin development lifecycle.

Key features:
- 7 skills: hook-development, mcp-integration, plugin-structure, plugin-settings,
  command-development, agent-development, skill-development
- 3 agents: agent-creator (AI-assisted generation), plugin-validator (structure
  validation), skill-reviewer (quality review)
- 1 command: /plugin-dev:create-plugin (guided 8-phase workflow)
- 10 utility scripts for validation and testing
- 21 reference docs with deep-dive guidance (~11k words)
- 9 working examples demonstrating best practices

Changes for public release:
- Replaced all references to internal repositories with "Claude Code"
- Updated MCP examples: internal.company.com → api.example.com
- Updated token variables: ${INTERNAL_TOKEN} → ${API_TOKEN}
- Reframed agent-creation-system-prompt as "proven in production"
- Preserved all ${CLAUDE_PLUGIN_ROOT} references (186 total)
- Preserved valuable test blocks in core modules

Validation:
- All 3 agents validated successfully with validate-agent.sh
- All JSON files validated with jq
- Zero internal references remaining
- 59 files migrated, 21,971 lines added

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 04:09:00 -08:00
Daisy S. Hollman 31ba6e541b Merge pull request #11752 from anthropics/daisy/ralph-wiggum/public-marketplace
Add ralph-wiggum and hookify plugins to public marketplace
2025-11-17 03:28:08 -08:00
Daisy S. Hollman 59372c0921 feat: Add hookify plugin for custom hook rules via markdown
Adds the hookify plugin to public marketplace. Enables users to create custom
hooks using simple markdown configuration files instead of editing JSON.

Key features:
- Define rules with regex patterns to warn/block operations
- Create rules from explicit instructions or conversation analysis
- Pattern-based matching for bash commands, file edits, prompts, stop events
- Enable/disable rules dynamically without editing code
- Conversation analyzer agent finds problematic behaviors

Changes from internal version:
- Removed non-functional SessionStart hook (not registered in hooks.json)
- Removed all sessionstart documentation and examples
- Fixed restart documentation to consistently state "no restart needed"
- Changed license from "Internal Anthropic use only" to "MIT License"
- Kept test blocks in core modules (useful for developers)

Plugin provides:
- 4 commands: /hookify, /hookify:list, /hookify:configure, /hookify:help
- 1 agent: conversation-analyzer
- 1 skill: writing-rules
- 4 hook types: PreToolUse, PostToolUse, Stop, UserPromptSubmit
- 4 example rules ready to use

All features functional and suitable for public use.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 03:18:43 -08:00
Daisy S. Hollman 68f90e05dd feat: Add ralph-wiggum plugin for iterative self-referential development
Migrates the ralph-wiggum plugin from internal marketplace to public marketplace.
Implements Geoffrey Huntley's "Ralph Wiggum" technique using Claude Code's Stop
hook mechanism for continuous iterative development loops.

Key features:
- Interactive self-referential AI loops in current session
- Stop hook intercepts exit and feeds same prompt back
- Iteration tracking and completion promise detection
- Max iterations safety limits

Changes:
- Remove all tmux dependencies and background execution mode
- Simplify to interactive-only mode using Stop hooks
- Add comprehensive error handling with clear messages
- Fix documentation to accurately describe Stop hook mechanism
- Add input validation for all command-line arguments
- Register plugin in public marketplace

Security fixes:
- Remove eval usage (command injection vulnerability)
- Add numeric validation before arithmetic operations
- Remove silent error suppression

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 13:53:45 -08:00
GitHub Actions 5dd91a9fe2 chore: Update CHANGELOG.md 2025-11-15 00:14:00 +00:00
GitHub Actions 17945ae3d5 chore: Update CHANGELOG.md 2025-11-14 22:40:04 +00:00
GitHub Actions d594fd24b9 chore: Update CHANGELOG.md 2025-11-14 19:28:50 +00:00
Thariq Shihipar 2b535344fc Merge pull request #11518 from anthropics/add-frontend-design-plugin
feat: Add plugin.json metadata for frontend-design plugin
2025-11-12 15:04:26 -08:00
Thariq Shihipar c91a6b660d feat: Add plugin.json metadata for frontend-design plugin
Add plugin metadata configuration file with version, description, and author information for the frontend-design plugin.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-12 14:15:38 -08:00
Wanghong Yuan 0b4215d637 Merge pull request #11495 from anthropics/whyuan-code-review
update code review plugin
2025-11-12 08:50:03 -08:00
Wanghong Yuan MacBook b85cc4474f update 2025-11-12 08:43:01 -08:00
Wanghong Yuan MacBook fc3c2c26e0 update 2025-11-12 08:40:43 -08:00
Wanghong Yuan MacBook dd65bc4d16 update 2025-11-12 08:35:27 -08:00
Thariq Shihipar dfd715012f Merge pull request #11454 from anthropics/add-frontend-design-plugin
feat: Add frontend-design plugin to marketplace
2025-11-11 20:17:40 -08:00
Thariq Shihipar 62c3cbc471 feat: Add frontend-design plugin to marketplace
Add a new plugin that helps create distinctive, production-grade frontend interfaces with high design quality. The plugin includes a skill that generates creative, polished code avoiding generic AI aesthetics.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 17:31:51 -08:00
Boris Cherny 556d296786 Merge pull request #10912 from saadiq/docs/update-installation-options
docs: Update README installation options to match official docs
2025-11-11 14:34:32 -08:00
Boris Cherny 8a0bfd3687 Merge branch 'main' into docs/update-installation-options 2025-11-11 14:34:00 -08:00
Boris Cherny 5d66745e78 Merge pull request #11029 from jamestrew/plugins-hook-portable-shabang
fix: use portable shebang in plugin hooks
2025-11-11 14:30:27 -08:00
Boris Cherny 18043d7474 Merge pull request #11297 from ravshansbox/patch-1
Update installation instructions for Claude Code
2025-11-11 14:28:48 -08:00
GitHub Actions d38bde5087 chore: Update CHANGELOG.md 2025-11-11 00:18:17 +00:00
Boris Cherny 970fff49e2 Merge pull request #11326 from anthropics/bcherny-patch-6 2025-11-09 21:50:35 -08:00
Ravshan Samandarov f09b24c49a Update installation instructions for Claude Code 2025-11-09 08:47:52 +03:00
James Trew 3af8ef29be fix: use portable shebang in plugin hooks
Replace #!/bin/bash with #!/usr/bin/env bash for better portability across systems

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 20:46:10 -05:00
Saadiq Rodgers-King 1e95326e12 docs: Update README installation options to match official docs
Expands the installation section to include all available methods:
- macOS/Linux (curl installer)
- Homebrew
- Windows (PowerShell installer)
- NPM

This brings the repository README in line with the official documentation at https://docs.claude.com/en/docs/claude-code/overview
2025-11-03 09:59:16 -05:00
166 changed files with 39574 additions and 681 deletions
+94 -39
View File
@@ -1,5 +1,5 @@
{
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
"$schema": "https://json.schemastore.org/claude-code-marketplace.json",
"name": "claude-code-plugins",
"version": "1.0.0",
"description": "Bundled plugins for Claude Code including Agent SDK development tools, PR review toolkit, and commit workflows",
@@ -15,14 +15,25 @@
"category": "development"
},
{
"name": "pr-review-toolkit",
"description": "Comprehensive PR review agents specializing in comments, tests, error handling, type design, code quality, and code simplification",
"name": "claude-opus-4-5-migration",
"description": "Migrate your code and prompts from Sonnet 4.x and Opus 4.1 to Opus 4.5.",
"version": "1.0.0",
"author": {
"name": "Anthropic",
"email": "support@anthropic.com"
"name": "William Hu",
"email": "whu@anthropic.com"
},
"source": "./plugins/pr-review-toolkit",
"source": "./plugins/claude-opus-4-5-migration",
"category": "development"
},
{
"name": "code-review",
"description": "Automated code review for pull requests using multiple specialized agents with confidence-based scoring to filter false positives",
"version": "1.0.0",
"author": {
"name": "Boris Cherny",
"email": "boris@anthropic.com"
},
"source": "./plugins/code-review",
"category": "productivity"
},
{
@@ -36,6 +47,17 @@
"source": "./plugins/commit-commands",
"category": "productivity"
},
{
"name": "explanatory-output-style",
"description": "Adds educational insights about implementation choices and codebase patterns (mimics the deprecated Explanatory output style)",
"version": "1.0.0",
"author": {
"name": "Dickson Tsai",
"email": "dickson@anthropic.com"
},
"source": "./plugins/explanatory-output-style",
"category": "learning"
},
{
"name": "feature-dev",
"description": "Comprehensive feature development workflow with specialized agents for codebase exploration, architecture design, and quality review",
@@ -47,6 +69,72 @@
"source": "./plugins/feature-dev",
"category": "development"
},
{
"name": "frontend-design",
"description": "Create distinctive, production-grade frontend interfaces with high design quality. Generates creative, polished code that avoids generic AI aesthetics.",
"version": "1.1.0",
"author": {
"name": "Prithvi Rajasekaran & Alexander Bricken",
"email": "prithvi@anthropic.com"
},
"source": "./plugins/frontend-design",
"category": "development"
},
{
"name": "hookify",
"description": "Easily create custom hooks to prevent unwanted behaviors by analyzing conversation patterns or from explicit instructions. Define rules via simple markdown files.",
"version": "0.1.0",
"author": {
"name": "Daisy Hollman",
"email": "daisy@anthropic.com"
},
"source": "./plugins/hookify",
"category": "productivity"
},
{
"name": "learning-output-style",
"description": "Interactive learning mode that requests meaningful code contributions at decision points (mimics the unshipped Learning output style)",
"version": "1.0.0",
"author": {
"name": "Boris Cherny",
"email": "boris@anthropic.com"
},
"source": "./plugins/learning-output-style",
"category": "learning"
},
{
"name": "plugin-dev",
"description": "Comprehensive toolkit for developing Claude Code plugins. Includes 7 expert skills covering hooks, MCP integration, commands, agents, and best practices. AI-assisted plugin creation and validation.",
"version": "0.1.0",
"author": {
"name": "Daisy Hollman",
"email": "daisy@anthropic.com"
},
"source": "./plugins/plugin-dev",
"category": "development"
},
{
"name": "pr-review-toolkit",
"description": "Comprehensive PR review agents specializing in comments, tests, error handling, type design, code quality, and code simplification",
"version": "1.0.0",
"author": {
"name": "Anthropic",
"email": "support@anthropic.com"
},
"source": "./plugins/pr-review-toolkit",
"category": "productivity"
},
{
"name": "ralph-wiggum",
"description": "Interactive self-referential AI loops for iterative development. Claude works on the same task repeatedly, seeing its previous work, until completion.",
"version": "1.0.0",
"author": {
"name": "Daisy Hollman",
"email": "daisy@anthropic.com"
},
"source": "./plugins/ralph-wiggum",
"category": "development"
},
{
"name": "security-guidance",
"description": "Security reminder hook that warns about potential security issues when editing files, including command injection, XSS, and unsafe code patterns",
@@ -57,39 +145,6 @@
},
"source": "./plugins/security-guidance",
"category": "security"
},
{
"name": "code-review",
"description": "Automated code review for pull requests using multiple specialized agents with confidence-based scoring to filter false positives",
"version": "1.0.0",
"author": {
"name": "Boris Cherny",
"email": "boris@anthropic.com"
},
"source": "./plugins/code-review",
"category": "productivity"
},
{
"name": "explanatory-output-style",
"description": "Adds educational insights about implementation choices and codebase patterns (mimics the deprecated Explanatory output style)",
"version": "1.0.0",
"author": {
"name": "Dickson Tsai",
"email": "dickson@anthropic.com"
},
"source": "./plugins/explanatory-output-style",
"category": "learning"
},
{
"name": "learning-output-style",
"description": "Interactive learning mode that requests meaningful code contributions at decision points (mimics the unshipped Learning output style)",
"version": "1.0.0",
"author": {
"name": "Boris Cherny",
"email": "boris@anthropic.com"
},
"source": "./plugins/learning-output-style",
"category": "learning"
}
]
}
+11 -22
View File
@@ -1,5 +1,5 @@
---
allowed-tools: Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(gh api:*), Bash(gh issue comment:*)
allowed-tools: Bash(./scripts/gh.sh:*), Bash(./scripts/comment-on-duplicates.sh:*)
description: Find duplicate GitHub issues
---
@@ -11,28 +11,17 @@ To do this, follow these steps precisely:
2. Use an agent to view a Github issue, and ask the agent to return a summary of the issue
3. Then, launch 5 parallel agents to search Github for duplicates of this issue, using diverse keywords and search approaches, using the summary from #1
4. Next, feed the results from #1 and #2 into another agent, so that it can filter out false positives, that are likely not actually duplicates of the original issue. If there are no duplicates remaining, do not proceed.
5. Finally, comment back on the issue with a list of up to three duplicate issues (or zero, if there are no likely duplicates)
5. Finally, use the comment script to post duplicates:
```
./scripts/comment-on-duplicates.sh --potential-duplicates <dup1> <dup2> <dup3>
```
Notes (be sure to tell this to your agents, too):
- Use `gh` to interact with Github, rather than web fetch
- Do not use other tools, beyond `gh` (eg. don't use other MCP servers, file edit, etc.)
- Use `./scripts/gh.sh` to interact with Github, rather than web fetch or raw `gh`. Examples:
- `./scripts/gh.sh issue view 123` — view an issue
- `./scripts/gh.sh issue view 123 --comments` — view with comments
- `./scripts/gh.sh issue list --state open --limit 20` — list issues
- `./scripts/gh.sh search issues "query" --limit 10` — search for issues
- Do not use other tools, beyond `./scripts/gh.sh` and the comment script (eg. don't use other MCP servers, file edit, etc.)
- Make a todo list first
- For your comment, follow the following format precisely (assuming for this example that you found 3 suspected duplicates):
---
Found 3 possible duplicate issues:
1. <link to issue>
2. <link to issue>
3. <link to issue>
This issue will be automatically closed as a duplicate in 3 days.
- If your issue is a duplicate, please close it and 👍 the existing issue instead
- To prevent auto-closure, add a comment or 👎 this comment
🤖 Generated with [Claude Code](https://claude.ai/code)
---
-40
View File
@@ -1,40 +0,0 @@
---
allowed-tools: Bash(gh issue list:*), Bash(gh issue view:*), Bash(gh issue edit:*), TodoWrite
description: Triage GitHub issues and label critical ones for oncall
---
You're an oncall triage assistant for GitHub issues. Your task is to identify critical issues that require immediate oncall attention and apply the "oncall" label.
Repository: anthropics/claude-code
Task overview:
1. First, get all open bugs updated in the last 3 days with at least 50 engagements:
```bash
gh issue list --repo anthropics/claude-code --state open --label bug --limit 1000 --json number,title,updatedAt,comments,reactions | jq -r '.[] | select((.updatedAt >= (now - 259200 | strftime("%Y-%m-%dT%H:%M:%SZ"))) and ((.comments | length) + ([.reactions[].content] | length) >= 50)) | "\(.number)"'
```
2. Save the list of issue numbers and create a TODO list with ALL of them. This ensures you process every single one.
3. For each issue in your TODO list:
- Use `gh issue view <number> --repo anthropics/claude-code --json title,body,labels,comments` to get full details
- Read and understand the full issue content and comments to determine actual user impact
- Evaluate: Is this truly blocking users from using Claude Code?
- Consider: "crash", "stuck", "frozen", "hang", "unresponsive", "cannot use", "blocked", "broken"
- Does it prevent core functionality? Can users work around it?
- Be conservative - only flag issues that truly prevent users from getting work done
4. For issues that are truly blocking and don't already have the "oncall" label:
- Use `gh issue edit <number> --repo anthropics/claude-code --add-label "oncall"`
- Mark the issue as complete in your TODO list
5. After processing all issues, provide a summary:
- List each issue number that received the "oncall" label
- Include the issue title and brief reason why it qualified
- If no issues qualified, state that clearly
Important:
- Process ALL issues in your TODO list systematically
- Don't post any comments to issues
- Only add the "oncall" label, never remove it
- Use individual `gh issue view` commands instead of bash for loops to avoid approval prompts
+74
View File
@@ -0,0 +1,74 @@
---
allowed-tools: Bash(./scripts/gh.sh:*),Bash(./scripts/edit-issue-labels.sh:*)
description: Triage GitHub issues by analyzing and applying labels
---
You're an issue triage assistant. Analyze the issue and manage labels.
IMPORTANT: Don't post any comments or messages to the issue. Your only actions are adding or removing labels.
Context:
$ARGUMENTS
TOOLS:
- `./scripts/gh.sh` — wrapper for `gh` CLI. Only supports these subcommands and flags:
- `./scripts/gh.sh label list` — fetch all available labels
- `./scripts/gh.sh label list --limit 100` — fetch with limit
- `./scripts/gh.sh issue view 123` — read issue title, body, and labels
- `./scripts/gh.sh issue view 123 --comments` — read the conversation
- `./scripts/gh.sh issue list --state open --limit 20` — list issues
- `./scripts/gh.sh search issues "query"` — find similar or duplicate issues
- `./scripts/gh.sh search issues "query" --limit 10` — search with limit
- `./scripts/edit-issue-labels.sh --add-label LABEL --remove-label LABEL` — add or remove labels (issue number is read from the workflow event)
TASK:
1. Run `./scripts/gh.sh label list` to fetch the available labels. You may ONLY use labels from this list. Never invent new labels.
2. Run `./scripts/gh.sh issue view ISSUE_NUMBER` to read the issue details.
3. Run `./scripts/gh.sh issue view ISSUE_NUMBER --comments` to read the conversation.
**If EVENT is "issues" (new issue):**
4. First, check if this issue is actually about Claude Code.
- Look for Claude Code signals in the issue BODY: a `Claude Code Version` field or `claude --version` output, references to the `claude` CLI command, terminal sessions, the VS Code/JetBrains extensions, `CLAUDE.md` files, `.claude/` directories, MCP servers, Cowork, Remote Control, or the web UI at claude.ai/code. If ANY such signal is present, this IS a Claude Code issue — proceed to step 5.
- Only if NO Claude Code signals are present: check whether a different Anthropic product (claude.ai chat, Claude Desktop/Mobile apps, the raw Anthropic API/SDK, or account billing with no CLI involvement) is the *subject* of the complaint, not merely mentioned for context. If so, apply `invalid` and stop. If ambiguous, proceed to step 5 WITHOUT applying `invalid`.
- The body text is authoritative. If a form dropdown (e.g. Platform) contradicts evidence in the body, trust the body — dropdowns are often mis-selected.
5. Analyze and apply category labels:
- Type (bug, enhancement, question, etc.)
- Technical areas and platform
- Check for duplicates with `./scripts/gh.sh search issues`. Only mark as duplicate of OPEN issues.
6. Evaluate lifecycle labels:
- `needs-repro` (bugs only, 7 days): Bug reports without clear steps to reproduce. A good repro has specific, followable steps that someone else could use to see the same issue.
Do NOT apply if the user already provided error messages, logs, file paths, or a description of what they did. Don't require a specific format — narrative descriptions count.
For model behavior issues (e.g. "Claude does X when it should do Y"), don't require traditional repro steps — examples and patterns are sufficient.
- `needs-info` (bugs only, 7 days): The issue needs something from the community before it can progress — e.g. error messages, versions, environment details, or answers to follow-up questions. Don't apply to questions or enhancements.
Do NOT apply if the user already provided version, environment, and error details. If the issue just needs engineering investigation, that's not `needs-info`.
Issues with these labels are automatically closed after the timeout if there's no response.
The goal is to avoid issues lingering without a clear next step.
7. Apply all selected labels:
`./scripts/edit-issue-labels.sh --add-label "label1" --add-label "label2"`
**If EVENT is "issue_comment" (comment on existing issue):**
4. Evaluate lifecycle labels based on the full conversation:
- If the issue has `stale` or `autoclose`, remove the label — a new human comment means the issue is still active:
`./scripts/edit-issue-labels.sh --remove-label "stale" --remove-label "autoclose"`
- If the issue has `needs-repro` or `needs-info` and the missing information has now been provided, remove the label:
`./scripts/edit-issue-labels.sh --remove-label "needs-repro"`
- If the issue doesn't have lifecycle labels but clearly needs them (e.g., a maintainer asked for repro steps or more details), add the appropriate label.
- Comments like "+1", "me too", "same here", or emoji reactions are NOT the missing information. Only remove `needs-repro` or `needs-info` when substantive details are actually provided.
- Do NOT add or remove category labels (bug, enhancement, etc.) on comment events.
GUIDELINES:
- ONLY use labels from `./scripts/gh.sh label list` — never create or guess label names
- DO NOT post any comments to the issue
- Be conservative with lifecycle labels — only apply when clearly warranted
- Only apply lifecycle labels (`needs-repro`, `needs-info`) to bugs — never to questions or enhancements
- When in doubt, don't apply a lifecycle label — false positives are worse than missing labels
- On new issues (EVENT "issues"), always apply exactly one of `bug`, `enhancement`, `question`, `invalid`, or `duplicate`. If unsure, pick the closest fit — an imperfect category label is better than none.
- On comment events, it's okay to make no changes if nothing applies.
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 (sha-pinned)
with:
bun-version: latest
@@ -32,7 +32,7 @@ jobs:
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 (sha-pinned)
with:
bun-version: latest
+22 -9
View File
@@ -17,28 +17,40 @@ jobs:
permissions:
contents: read
issues: write
# Required to mint the OIDC token exchanged for a Claude API access token (Workload Identity Federation)
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Run Claude Code slash command
uses: anthropics/claude-code-base-action@beta
uses: anthropics/claude-code-action@v1
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CLAUDE_CODE_SCRIPT_CAPS: '{"comment-on-duplicates.sh":1}'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
allowed_non_write_users: "*"
prompt: "/dedupe ${{ github.repository }}/issues/${{ github.event.issue.number || inputs.issue_number }}"
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
# Authenticate to the Claude API via Workload Identity Federation
# (the workflow's OIDC token is exchanged for a short-lived access
# token) instead of a static API key.
anthropic_federation_rule_id: ${{ vars.ANTHROPIC_FEDERATION_RULE_ID }}
anthropic_organization_id: ${{ vars.ANTHROPIC_ORGANIZATION_ID }}
anthropic_service_account_id: ${{ vars.ANTHROPIC_SERVICE_ACCOUNT_ID }}
anthropic_workspace_id: ${{ vars.ANTHROPIC_WORKSPACE_ID }}
claude_args: "--model claude-sonnet-4-5-20250929"
claude_env: |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Log duplicate comment event to Statsig
if: always()
env:
STATSIG_API_KEY: ${{ secrets.STATSIG_API_KEY }}
ISSUE_NUMBER: ${{ github.event.issue.number || inputs.issue_number }}
REPO: ${{ github.repository }}
TRIGGERED_BY: ${{ github.event_name }}
WORKFLOW_RUN_ID: ${{ github.run_id }}
run: |
ISSUE_NUMBER=${{ github.event.issue.number || inputs.issue_number }}
REPO=${{ github.repository }}
if [ -z "$STATSIG_API_KEY" ]; then
echo "STATSIG_API_KEY not found, skipping Statsig logging"
exit 0
@@ -48,7 +60,8 @@ jobs:
EVENT_PAYLOAD=$(jq -n \
--arg issue_number "$ISSUE_NUMBER" \
--arg repo "$REPO" \
--arg triggered_by "${{ github.event_name }}" \
--arg triggered_by "$TRIGGERED_BY" \
--arg workflow_run_id "$WORKFLOW_RUN_ID" \
'{
events: [{
eventName: "github_duplicate_comment_added",
@@ -57,7 +70,7 @@ jobs:
repository: $repo,
issue_number: ($issue_number | tonumber),
triggered_by: $triggered_by,
workflow_run_id: "${{ github.run_id }}"
workflow_run_id: $workflow_run_id
},
time: (now | floor | tostring)
}]
+28 -88
View File
@@ -1,107 +1,47 @@
name: Claude Issue Triage
description: Automatically triage GitHub issues using Claude Code
on:
issues:
types: [opened]
issue_comment:
types: [created]
jobs:
triage-issue:
runs-on: ubuntu-latest
timeout-minutes: 10
if: >-
github.event_name == 'issues' ||
(github.event_name == 'issue_comment' && !github.event.issue.pull_request && github.event.comment.user.type != 'Bot')
concurrency:
group: issue-triage-${{ github.event.issue.number }}
cancel-in-progress: true
permissions:
contents: read
issues: write
# Required to mint the OIDC token exchanged for a Claude API access token (Workload Identity Federation)
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Create triage prompt
run: |
mkdir -p /tmp/claude-prompts
cat > /tmp/claude-prompts/triage-prompt.txt << 'EOF'
You're an issue triage assistant for GitHub issues. Your task is to analyze the issue and select appropriate labels from the provided list.
IMPORTANT: Don't post any comments or messages to the issue. Your only action should be to apply labels.
Issue Information:
- REPO: ${{ github.repository }}
- ISSUE_NUMBER: ${{ github.event.issue.number }}
TASK OVERVIEW:
1. First, fetch the list of labels available in this repository by running: `gh label list`. Run exactly this command with nothing else.
2. Next, use the GitHub tools to get context about the issue:
- You have access to these tools:
- mcp__github__get_issue: Use this to retrieve the current issue's details including title, description, and existing labels
- mcp__github__get_issue_comments: Use this to read any discussion or additional context provided in the comments
- mcp__github__update_issue: Use this to apply labels to the issue (do not use this for commenting)
- mcp__github__search_issues: Use this to find similar issues that might provide context for proper categorization and to identify potential duplicate issues
- mcp__github__list_issues: Use this to understand patterns in how other issues are labeled
- Start by using mcp__github__get_issue to get the issue details
3. Analyze the issue content, considering:
- The issue title and description
- The type of issue (bug report, feature request, question, etc.)
- Technical areas mentioned
- Severity or priority indicators
- User impact
- Components affected
4. Select appropriate labels from the available labels list provided above:
- Choose labels that accurately reflect the issue's nature
- Be specific but comprehensive
- Select priority labels if you can determine urgency (high-priority, med-priority, or low-priority)
- Consider platform labels (android, ios) if applicable
- If you find similar issues using mcp__github__search_issues, consider using a "duplicate" label if appropriate. Only do so if the issue is a duplicate of another OPEN issue.
5. Apply the selected labels:
- Use mcp__github__update_issue to apply your selected labels
- DO NOT post any comments explaining your decision
- DO NOT communicate directly with users
- If no labels are clearly applicable, do not apply any labels
IMPORTANT GUIDELINES:
- Be thorough in your analysis
- Only select labels from the provided list above
- DO NOT post any comments to the issue
- Your ONLY action should be to apply labels using mcp__github__update_issue
- It's okay to not add any labels if none are clearly applicable
EOF
- name: Setup GitHub MCP Server
run: |
mkdir -p /tmp/mcp-config
cat > /tmp/mcp-config/mcp-servers.json << 'EOF'
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server:sha-7aced2b"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${{ secrets.GITHUB_TOKEN }}"
}
}
}
}
EOF
- name: Run Claude Code for Issue Triage
uses: anthropics/claude-code-base-action@beta
timeout-minutes: 5
uses: anthropics/claude-code-action@v1
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
CLAUDE_CODE_SCRIPT_CAPS: '{"edit-issue-labels.sh":2}'
with:
prompt_file: /tmp/claude-prompts/triage-prompt.txt
allowed_tools: "Bash(gh label list),mcp__github__get_issue,mcp__github__get_issue_comments,mcp__github__update_issue,mcp__github__search_issues,mcp__github__list_issues"
timeout_minutes: "5"
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
mcp_config: /tmp/mcp-config/mcp-servers.json
claude_args: "--model claude-sonnet-4-5-20250929"
claude_env: |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
github_token: ${{ secrets.GITHUB_TOKEN }}
allowed_non_write_users: "*"
prompt: "/triage-issue REPO: ${{ github.repository }} ISSUE_NUMBER: ${{ github.event.issue.number }} EVENT: ${{ github.event_name }}"
# Authenticate to the Claude API via Workload Identity Federation
# (the workflow's OIDC token is exchanged for a short-lived access
# token) instead of a static API key.
anthropic_federation_rule_id: ${{ vars.ANTHROPIC_FEDERATION_RULE_ID }}
anthropic_organization_id: ${{ vars.ANTHROPIC_ORGANIZATION_ID }}
anthropic_service_account_id: ${{ vars.ANTHROPIC_SERVICE_ACCOUNT_ID }}
anthropic_workspace_id: ${{ vars.ANTHROPIC_WORKSPACE_ID }}
claude_args: |
--model claude-opus-4-6
+8 -2
View File
@@ -31,8 +31,14 @@ jobs:
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@beta
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
# Authenticate to the Claude API via Workload Identity Federation
# (the workflow's OIDC token is exchanged for a short-lived access
# token) instead of a static API key.
anthropic_federation_rule_id: ${{ vars.ANTHROPIC_FEDERATION_RULE_ID }}
anthropic_organization_id: ${{ vars.ANTHROPIC_ORGANIZATION_ID }}
anthropic_service_account_id: ${{ vars.ANTHROPIC_SERVICE_ACCOUNT_ID }}
anthropic_workspace_id: ${{ vars.ANTHROPIC_WORKSPACE_ID }}
claude_args: "--model claude-sonnet-4-5-20250929"
@@ -0,0 +1,27 @@
name: "Issue Lifecycle Comment"
on:
issues:
types: [labeled]
permissions:
issues: write
jobs:
comment:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 (sha-pinned)
with:
bun-version: latest
- name: Post lifecycle comment
run: bun run scripts/lifecycle-comment.ts
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
LABEL: ${{ github.event.label.name }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
+24 -39
View File
@@ -22,71 +22,56 @@ jobs:
script: |
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
const cutoff = sevenDaysAgo.toISOString().split('T')[0];
const lockComment = `This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.`;
let page = 1;
let hasMore = true;
const query = `repo:${context.repo.owner}/${context.repo.repo} is:issue is:closed is:unlocked updated:<${cutoff}`;
console.log(`Search query: ${query}`);
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const MAX_PER_RUN = 250;
const processed = new Set();
let totalLocked = 0;
while (hasMore) {
// Get closed issues (pagination)
const { data: issues } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'closed',
while (totalLocked < MAX_PER_RUN) {
const { data } = await github.rest.search.issuesAndPullRequests({
q: query,
sort: 'updated',
direction: 'asc',
order: 'asc',
per_page: 100,
page: page
});
if (issues.length === 0) {
hasMore = false;
break;
if (totalLocked === 0) {
console.log(`Total candidates: ${data.total_count}`);
}
for (const issue of issues) {
// Skip if already locked
if (issue.locked) continue;
// Skip pull requests
if (issue.pull_request) continue;
// Check if updated more than 7 days ago
const updatedAt = new Date(issue.updated_at);
if (updatedAt > sevenDaysAgo) {
// Since issues are sorted by updated_at ascending,
// once we hit a recent issue, all remaining will be recent too
hasMore = false;
break;
}
const fresh = data.items.filter((i) => !processed.has(i.number));
if (fresh.length === 0) break;
for (const issue of fresh) {
if (totalLocked >= MAX_PER_RUN) break;
processed.add(issue.number);
try {
// Add comment before locking
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: lockComment
body: lockComment,
});
// Lock the issue
await github.rest.issues.lock({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
lock_reason: 'resolved'
lock_reason: 'resolved',
});
totalLocked++;
console.log(`Locked issue #${issue.number}: ${issue.title}`);
await sleep(1000);
} catch (error) {
console.error(`Failed to lock issue #${issue.number}: ${error.message}`);
}
}
page++;
}
console.log(`Total issues locked: ${totalLocked}`);
@@ -0,0 +1,47 @@
name: Non-write Users Check
on:
pull_request:
paths:
- ".github/**"
permissions:
contents: read
pull-requests: write
jobs:
allowed-non-write-check:
runs-on: ubuntu-latest
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- run: |
DIFF=$(gh pr diff "$PR_NUMBER" -R "$REPO" || true)
if ! echo "$DIFF" | grep -qE '^diff --git a/\.github/.*\.ya?ml'; then
exit 0
fi
MATCHES=$(echo "$DIFF" | grep "^+.*allowed_non_write_users" || true)
if [ -z "$MATCHES" ]; then
exit 0
fi
EXISTING=$(gh pr view "$PR_NUMBER" -R "$REPO" --json comments --jq '.comments[].body' \
| grep -c "<!-- non-write-users-check -->" || true)
if [ "$EXISTING" -gt 0 ]; then
exit 0
fi
gh pr comment "$PR_NUMBER" -R "$REPO" --body '<!-- non-write-users-check -->
**`allowed_non_write_users` detected**
This PR adds or modifies `allowed_non_write_users`, which allows users without write access to trigger Claude Code Action workflows. This can introduce security risks.
If this is a new flow, please make sure you actually need `allowed_non_write_users`. If you are editing an existing workflow, double check that you are not adding new Claude permissions which might lead to a vulnerability.
See existing workflows in this repo for safe usage examples, or contact the AppSec team.'
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
-120
View File
@@ -1,120 +0,0 @@
name: Oncall Issue Triage
description: Automatically identify and label critical blocking issues requiring oncall attention
on:
push:
branches:
- add-oncall-triage-workflow # Temporary: for testing only
schedule:
# Run every 6 hours
- cron: '0 */6 * * *'
workflow_dispatch: # Allow manual trigger
jobs:
oncall-triage:
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Create oncall triage prompt
run: |
mkdir -p /tmp/claude-prompts
cat > /tmp/claude-prompts/oncall-triage-prompt.txt << 'EOF'
You're an oncall triage assistant for GitHub issues. Your task is to identify critical issues that require immediate oncall attention.
Important: Don't post any comments or messages to the issues. Your only action should be to apply the "oncall" label to qualifying issues.
Repository: ${{ github.repository }}
Task overview:
1. Fetch all open issues updated in the last 3 days:
- Use mcp__github__list_issues with:
- state="open"
- first=5 (fetch only 5 issues per page)
- orderBy="UPDATED_AT"
- direction="DESC"
- This will give you the most recently updated issues first
- For each page of results, check the updatedAt timestamp of each issue
- Add issues updated within the last 3 days (72 hours) to your TODO list as you go
- Keep paginating using the 'after' parameter until you encounter issues older than 3 days
- Once you hit issues older than 3 days, you can stop fetching (no need to fetch all open issues)
2. Build your TODO list incrementally as you fetch:
- As you fetch each page, immediately add qualifying issues to your TODO list
- One TODO item per issue number (e.g., "Evaluate issue #123")
- This allows you to start processing while still fetching more pages
3. For each issue in your TODO list:
- Use mcp__github__get_issue to read the issue details (title, body, labels)
- Use mcp__github__get_issue_comments to read all comments
- Evaluate whether this issue needs the oncall label:
a) Is it a bug? (has "bug" label or describes bug behavior)
b) Does it have at least 50 engagements? (count comments + reactions)
c) Is it truly blocking? Read and understand the full content to determine:
- Does this prevent core functionality from working?
- Can users work around it?
- Consider severity indicators: "crash", "stuck", "frozen", "hang", "unresponsive", "cannot use", "blocked", "broken"
- Be conservative - only flag issues that truly prevent users from getting work done
4. For issues that meet all criteria and do not already have the "oncall" label:
- Use mcp__github__update_issue to add the "oncall" label
- Do not post any comments
- Do not remove any existing labels
- Do not remove the "oncall" label from issues that already have it
Important guidelines:
- Use the TODO list to track your progress through ALL candidate issues
- Process issues efficiently - don't read every single issue upfront, work through your TODO list systematically
- Be conservative in your assessment - only flag truly critical blocking issues
- Do not post any comments to issues
- Your only action should be to add the "oncall" label using mcp__github__update_issue
- Mark each issue as complete in your TODO list as you process it
7. After processing all issues in your TODO list, provide a summary of your actions:
- Total number of issues processed (candidate issues evaluated)
- Number of issues that received the "oncall" label
- For each issue that got the label: list issue number, title, and brief reason why it qualified
- Close calls: List any issues that almost qualified but didn't quite meet the criteria (e.g., borderline blocking, had workarounds)
- If no issues qualified, state that clearly
- Format the summary clearly for easy reading
EOF
- name: Setup GitHub MCP Server
run: |
mkdir -p /tmp/mcp-config
cat > /tmp/mcp-config/mcp-servers.json << 'EOF'
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server:sha-7aced2b"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${{ secrets.GITHUB_TOKEN }}"
}
}
}
}
EOF
- name: Run Claude Code for Oncall Triage
uses: anthropics/claude-code-base-action@beta
with:
prompt_file: /tmp/claude-prompts/oncall-triage-prompt.txt
allowed_tools: "mcp__github__list_issues,mcp__github__get_issue,mcp__github__get_issue_comments,mcp__github__update_issue"
timeout_minutes: "10"
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
mcp_config: /tmp/mcp-config/mcp-servers.json
claude_env: |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,42 @@
name: "Remove Autoclose Label on Activity"
on:
issue_comment:
types: [created]
permissions:
issues: write
jobs:
remove-autoclose:
# Only run if the issue has the autoclose label
if: |
github.event.issue.state == 'open' &&
contains(github.event.issue.labels.*.name, 'autoclose') &&
github.event.comment.user.login != 'github-actions[bot]'
runs-on: ubuntu-latest
steps:
- name: Remove autoclose label
uses: actions/github-script@v7
with:
script: |
console.log(`Removing autoclose label from issue #${context.issue.number} due to new comment from ${context.payload.comment.user.login}`);
try {
// Remove the autoclose label
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
name: 'autoclose'
});
console.log(`Successfully removed autoclose label from issue #${context.issue.number}`);
} catch (error) {
// If the label was already removed or doesn't exist, that's fine
if (error.status === 404) {
console.log(`Autoclose label was already removed from issue #${context.issue.number}`);
} else {
throw error;
}
}
+31
View File
@@ -0,0 +1,31 @@
name: "Issue Sweep"
on:
schedule:
- cron: "0 10,22 * * *"
workflow_dispatch:
permissions:
issues: write
concurrency:
group: daily-issue-sweep
jobs:
sweep:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 (sha-pinned)
with:
bun-version: latest
- name: Enforce lifecycle timeouts
run: bun run scripts/sweep.ts
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
GITHUB_REPOSITORY_NAME: ${{ github.event.repository.name }}
+3728 -6
View File
File diff suppressed because it is too large Load Diff
+30 -5
View File
@@ -6,17 +6,42 @@
Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows -- all through natural language commands. Use it in your terminal, IDE, or tag @claude on Github.
**Learn more in the [official documentation](https://docs.anthropic.com/en/docs/claude-code/overview)**.
**Learn more in the [official documentation](https://code.claude.com/docs/en/overview)**.
<img src="./demo.gif" />
## Get started
> [!NOTE]
> Installation via npm is deprecated. Use one of the recommended methods below.
For more installation options, uninstall steps, and troubleshooting, see the [setup documentation](https://code.claude.com/docs/en/setup).
1. Install Claude Code:
```sh
npm install -g @anthropic-ai/claude-code
```
**MacOS/Linux (Recommended):**
```bash
curl -fsSL https://claude.ai/install.sh | bash
```
**Homebrew (MacOS/Linux):**
```bash
brew install --cask claude-code
```
**Windows (Recommended):**
```powershell
irm https://claude.ai/install.ps1 | iex
```
**WinGet (Windows):**
```powershell
winget install Anthropic.ClaudeCode
```
**NPM (Deprecated):**
```bash
npm install -g @anthropic-ai/claude-code
```
2. Navigate to your project directory and run `claude`.
@@ -38,7 +63,7 @@ When you use Claude Code, we collect feedback, which includes usage data (such a
### How we use your data
See our [data usage policies](https://docs.anthropic.com/en/docs/claude-code/data-usage).
See our [data usage policies](https://code.claude.com/docs/en/data-usage).
### Privacy safeguards
+3 -3
View File
@@ -5,8 +5,8 @@ Thank you for helping us keep Claude Code secure!
The security of our systems and user data is Anthropic's top priority. We appreciate the work of security researchers acting in good faith in identifying and reporting potential vulnerabilities.
Our security program is managed on HackerOne and we ask that any validated vulnerability in this functionality be reported through their [submission form](https://hackerone.com/anthropic-vdp/reports/new?type=team&report_type=vulnerability).
Our security program is managed on HackerOne and we ask that any validated vulnerability in this functionality be reported through their [submission form](https://hackerone.com/4f1f16ba-10d3-4d09-9ecc-c721aad90f24/embedded_submissions/new).
## Vulnerability Disclosure Program
## Anthropic Bug Bounty
Our Vulnerability Program Guidelines are defined on our [HackerOne program page](https://hackerone.com/anthropic-vdp).
Our Bug Bounty Program Guidelines are defined on our [HackerOne program page](https://hackerone.com/anthropic).
+13
View File
@@ -0,0 +1,13 @@
# Keep the build context to just the binary the Dockerfile COPYs. BuildKit (the
# default, selected via the Dockerfile's syntax directive) only syncs the
# referenced COPY source anyway, so this is a no-op there — it matters for the
# classic builder (DOCKER_BUILDKIT=0) and as a conventional signal that the
# .gitignore'd secrets in this directory aren't part of the image build.
terraform/
**/.terraform/
*.tfstate*
terraform.tfvars
gateway.yaml
secrets/
*.pem
client_secret_*.json
+12
View File
@@ -0,0 +1,12 @@
# Local, environment-specific config — copy gateway.yaml.example -> gateway.yaml
# (gateway.yaml.example IS committed; your filled-in gateway.yaml is not)
gateway.yaml
# Secrets / credentials — never commit
secrets/
client_secret_*.json
*.pem
# Release binary and pinned version — setup.sh downloads/writes these per release
claude
.claude-version
+35
View File
@@ -0,0 +1,35 @@
# syntax=docker/dockerfile:1
# Runtime image for `claude gateway`.
#
# This image does NOT build the binary. It expects a prebuilt native
# linux-x64 `claude` executable in the build context — the public Claude Code
# release binary, which includes the `gateway` subcommand. setup.sh places it
# at ./claude (downloading it from the public release endpoint and verifying
# it against the release manifest if missing). Override CLAUDE_BINARY to
# point at a different path.
#
# Build (with the binary at ./claude; otherwise add --build-arg CLAUDE_BINARY=<path>):
# docker build --platform=linux/amd64 --provenance=false -t claude-gateway .
#
# Run:
# docker run --rm -p 8080:8080 \
# -v "$PWD/gateway.yaml:/etc/claude/gateway.yaml:ro" \
# -e OIDC_CLIENT_SECRET -e GATEWAY_JWT_SECRET -e GATEWAY_POSTGRES_URL \
# claude-gateway
ARG CLAUDE_BINARY=./claude
# distroless/cc provides glibc + libstdc++ (required by the Bun-compiled
# native binary). The :nonroot tag runs as uid/gid 65532.
FROM gcr.io/distroless/cc-debian12:nonroot
ARG CLAUDE_BINARY
COPY --chmod=0755 ${CLAUDE_BINARY} /usr/local/bin/claude
ENV CLAUDE_CONFIG_DIR=/tmp/.claude
EXPOSE 8080
USER nonroot
ENTRYPOINT ["/usr/local/bin/claude", "gateway", "--config", "/etc/claude/gateway.yaml"]
+17
View File
@@ -0,0 +1,17 @@
# Claude Gateway on Google Cloud
Reference deployment artifacts for running Claude Gateway on GCP with Agent
Platform (formerly Vertex AI) as the upstream: Cloud Run or GKE, Cloud SQL for
PostgreSQL, Secret Manager, and service-account auth to Agent Platform.
These files are provided as a working example rather than a supported production
deployment. Adapt them to your own environment.
- **Walkthrough**: https://code.claude.com/docs/en/claude-apps-gateway-on-gcp
| File | Purpose |
|---|---|
| `setup.sh` | Scripts the walkthrough end to end via `gcloud` |
| `Dockerfile` | Runtime image for the `claude gateway` binary |
| `gateway.yaml.example` | Gateway config template, GCP-shaped (Agent Platform upstream, Google Workspace IdP) |
| `terraform/` | Provisions the full architecture (two-pass apply — see `terraform/README.md`) |
+156
View File
@@ -0,0 +1,156 @@
# gateway.yaml.example — Claude Gateway config template, GCP-shaped (walkthrough §6).
#
# Google Workspace IdP + Agent Platform (formerly Vertex AI) upstream, following
# the walkthrough at https://code.claude.com/docs/en/claude-apps-gateway-on-gcp.
# The active sections
# below are a strict subset of the full configuration reference at
# https://code.claude.com/docs/en/claude-apps-gateway; optional keys are included
# commented-out.
#
# USAGE — this is the shippable TEMPLATE. Copy it to gateway.yaml and fill it in:
# cp gateway.yaml.example gateway.yaml
# setup.sh and terraform/ read gateway.yaml (your filled-in copy, which is
# gitignored). It is published as the Secret Manager secret `gateway-config`
# (§6) and mounted at /etc/claude/gateway.yaml — the container ENTRYPOINT runs
# `claude gateway --config /etc/claude/gateway.yaml`.
#
# Secret expansion: ${ENV_VAR} reads an env var; ${file:/path} reads a mounted file.
# On Cloud Run, setup.sh injects the JWT / OIDC / Postgres secrets as ENV VARS
# (Cloud Run can't mount multiple secrets into a single directory), and mounts
# only gateway.yaml itself as a file at /etc/claude. On GKE you may use file mounts.
#
# BEFORE DEPLOY — replace every REPLACE_ME placeholder below (setup.sh refuses to
# publish the config secret while any remain), and create the referenced secrets:
# gateway-jwt-secret (setup.sh generates this)
# gateway-oidc-client-secret (from the Google Cloud Console OAuth client)
# gateway-postgres-url (setup.sh generates this)
# ── Listener ─────────────────────────────────────────────────────────────────
listen:
host: 0.0.0.0
port: 8080 # Cloud Run sets PORT=8080; leave as-is
# Required. Fixes the IdP redirect_uri, the OIDC discovery doc, and the
# gateway-token issuer so none are derived from the client-controlled Host
# header (X-Forwarded-Host/-Proto are likewise never trusted). On Cloud Run
# the run.app URL is only assigned on the first deploy, so this starts as a
# placeholder for the provisioning-only first pass (login does NOT work until
# the real URL is set). After the first deploy, setup.sh prints the run.app
# URL: set it here (or your LB hostname) and re-run; setup.sh republishes the
# config and redeploys. Register the same host's /oauth/callback on the
# Google OAuth client.
public_url: https://set-after-first-deploy.invalid
# Register this exact redirect URI on the Google OAuth client:
# https://<public_url host>/oauth/callback
#
# On Cloud Run (or behind any L7 LB) every request arrives via Google's front
# end, so the gateway sees one peer IP for all developers — set trusted_proxies
# so X-Forwarded-For from those proxies is trusted and per-IP rate limiting /
# audit IPs record the real client. 169.254.0.0/16 is Cloud Run's fixed
# link-local serving range; the proxy-only subnet is the one your internal ALB
# uses in this VPC.
# trusted_proxies:
# - 169.254.0.0/16 # Cloud Run serving proxy (link-local peer)
# - <proxy-only-subnet-cidr> # add if fronted by your internal ALB (its proxy-only subnet)
#
# Alternative — terminate TLS in the gateway itself instead of at a proxy:
# tls:
# cert: /certs/gateway.crt
# key: /certs/gateway.key
# ── Identity provider — Google Workspace ─────────────────────────────────────
oidc:
issuer: https://accounts.google.com
client_id: REPLACE_ME # Google OAuth client ID (not secret; from Cloud Console)
client_secret: ${OIDC_CLIENT_SECRET}
allowed_email_domains: [REPLACE_ME] # e.g. [example.com] — reject id_tokens outside your org
# Google ignores the default offline_access scope; these two are what actually
# yield refresh tokens (silent renewal + the deprovision leash) from Google.
scopes: [openid, profile, email]
extra_auth_params: { access_type: offline, prompt: consent }
# NOTE: Google id_tokens carry NO groups claim. For group-based RBAC with
# Google as IdP, set `google_groups` (below) and the gateway fetches each
# user's Workspace groups at login via the Admin SDK Directory API.
# Otherwise, use email_domain matching (see managed.policies below).
# google_groups:
# service_account_json_path: /secrets/google-sa.json # SA with domain-wide delegation on admin.directory.group.readonly
# admin_email: admin@example.com # a Workspace admin the SA impersonates
# groups_claim: groups # Okta=groups, Entra app roles=roles — NOT Google
# ca_cert_pem: ${file:/secrets/idp-ca.pem} # only for an IdP behind a private CA
# ── Sessions ─────────────────────────────────────────────────────────────────
session:
jwt_secret: ${GATEWAY_JWT_SECRET} # >= 32 bytes; openssl rand -base64 32
# Google issues refresh tokens (above), so sessions renew silently and this
# mainly bounds deprovision latency. 8 is a sane default; lower toward 1 for
# tighter revocation. Array form rotates keys: [new, old] (index 0 signs, all verify).
ttl_hours: 8
# ── Store (REQUIRED — the gateway refuses to boot without it) ─────────────────
store:
postgres_url: ${GATEWAY_POSTGRES_URL} # private-IP Cloud SQL; built with ?sslmode=require by setup.sh
# ── Upstreams — Agent Platform ───────────────────────────────────────────────
upstreams:
- provider: vertex
region: us-east5 # a region where the Claude models you need are published in Model Garden
project_id: REPLACE_ME # your GCP project ID for Agent Platform access
auth: {} # ADC via Cloud Run SA / GKE Workload Identity (preferred — no static keys)
# base_url: https://us-east5-aiplatform.p.googleapis.com # Private Service Connect endpoint
# Add more upstreams for failover (tried top→bottom on 5xx/timeout/501): a
# second region, or an anthropic/bedrock fallback. See
# https://code.claude.com/docs/en/claude-apps-gateway.
# ── Telemetry fan-out (OPTIONAL) ─────────────────────────────────────────────
# The CLI sends OTLP/HTTP to the gateway; the gateway fans out, stamping
# user.id/user.email/user.groups server-side. On GCP, point at an OpenTelemetry
# Collector with the googlecloud exporter (-> Cloud Trace / Managed Prometheus).
# Takes effect after the second pass (once public_url is the real URL, not the
# placeholder): when forward_to and public_url are both configured the gateway pushes
# CLAUDE_CODE_ENABLE_TELEMETRY and the OTEL exporter selectors to every client
# automatically — no per-developer config needed.
# telemetry:
# forward_to:
# - url: https://otel-collector.internal.example.com:4318
# headers:
# Authorization: ${file:/secrets/otlp-token}
# metrics: true # safe aggregate counters (default)
# logs: false # carries bash commands / tool inputs — opt in deliberately
# traces: false
# ── RBAC + managed settings (OPTIONAL; first-match-wins, top -> bottom) ───────
# With Google as IdP, match on email_domain, or on group email addresses
# (e.g. eng@example.com) once oidc.google_groups is configured above.
# managed:
# policies:
# - match: { email_domain: example.com }
# cli:
# availableModels: [claude-opus-4-8, claude-sonnet-4-6, claude-haiku-4-5]
# permissions: { deny: ["Read(./.env)", "Read(./secrets/**)"] }
# - match: {} # catch-all floor — keep LAST
# cli:
# availableModels: [claude-sonnet-4-6, claude-haiku-4-5]
# ── Admin API (OPTIONAL — enables db-mode runtime config + spend caps) ───────
# admin_groups needs a groups claim — with Google as IdP, set
# oidc.google_groups (above) so Workspace group email addresses populate the
# claim, or use the bootstrap keys below instead. Named keys for
# attribution in the audit log; 32-char minimum on key values. On Cloud Run add
# these as env vars to --set-secrets (or terraform env value_source blocks),
# same as the JWT/OIDC/Postgres secrets above; on GKE you may use ${file:...}.
# admin:
# write_keys:
# - id: terraform
# key: ${GATEWAY_ADMIN_WRITE_KEY}
# read_keys:
# - id: reporting
# key: ${GATEWAY_ADMIN_READ_KEY}
# # admin_groups: [platform-finops@example.com] # group emails via oidc.google_groups, or any groups-capable IdP
# ── Model catalog (OPTIONAL) ─────────────────────────────────────────────────
# Default true: every built-in Claude model is exposed and auto-translated per
# upstream. Set false + a models: list to pin IDs (e.g. provisioned throughput).
# auto_include_builtin_models: true
# models:
# - id: claude-opus-4-8
# label: Claude Opus 4.8
# upstream_model: { vertex: claude-opus-4-8 }
+558
View File
@@ -0,0 +1,558 @@
#!/usr/bin/env bash
#
# setup.sh — GCP setup for Claude Gateway (walkthrough §17b).
#
# Provisions, in doc order: APIs (§1), service account + IAM (§2), the gateway
# container image in Artifact Registry (§3), a Cloud SQL (PostgreSQL) backend
# with PRIVATE IP only (§4), the JWT + postgres-url secrets (§5), the
# gateway.yaml config secret (§6), and a Cloud Run deploy with Direct VPC
# egress (§7b).
#
# Private IP is required because public IP is disallowed by the org-policy constraint
# `constraints/sql.restrictPublicIp`. A Cloud SQL private IP is an address inside a VPC,
# so §4 here also provisions the prerequisite VPC + Private Services Access — the
# one-time, irreducible networking required for private IP.
#
# Section markers (§N) below map to the walkthrough:
# https://code.claude.com/docs/en/claude-apps-gateway-on-gcp
#
# Covers here: APIs (§1) -> service account + IAM (§2) -> build & push image (§3)
# -> VPC + Private Services Access -> Cloud SQL (private IP only) -> database
# + user (§4) -> jwt + postgres-url secrets (§5) -> gateway-config
# secret from gateway.yaml (§6) -> Cloud Run deploy (§7b).
# Not covered: GKE track (§7a) — Cloud Run is the lower-friction path here.
#
# Idempotent: existing resources are detected and skipped, so it is safe to re-run.
# Override any default below via environment variable, e.g. `REGION=us-east5 ./setup.sh`.
set -euo pipefail
# ---- configuration (env-overridable) ----------------------------------------
PROJECT_ID="${PROJECT_ID:-$(gcloud config get-value project 2>/dev/null)}"
REGION="${REGION:-${CLOUDSDK_COMPUTE_REGION:-us-east5}}" # guide §1 uses us-east5 (Agent Platform model region)
SA_NAME="${SA_NAME:-claude-gateway}" # §2 service account
SA_EMAIL="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
# §3 image
AR_REPO="${AR_REPO:-claude-gateway}" # Artifact Registry repository
IMAGE_NAME="${IMAGE_NAME:-gateway}"
RELEASES_URL="${RELEASES_URL:-https://downloads.claude.ai/claude-code-releases}" # public Claude Code release endpoint
VERSION="${VERSION:-}" # Claude Code release to deploy; empty = latest release (resolved below)
VERSION_FILE="${VERSION_FILE:-./.claude-version}" # pins the resolved release across re-runs; delete it (or set VERSION) to upgrade
DOCKERFILE="${DOCKERFILE:-./Dockerfile}"
CLAUDE_BINARY="${CLAUDE_BINARY:-./claude}" # linux-x64 Claude Code binary; downloaded from RELEASES_URL if missing
CLAUDE_SHA256="${CLAUDE_SHA256:-}" # optional: out-of-band sha256 pin for the downloaded binary, checked in addition to the release manifest
VPC_NETWORK="${VPC_NETWORK:-cc-gateway-vpc}"
SUBNET="${SUBNET:-cc-gateway-subnet}"
SUBNET_RANGE="${SUBNET_RANGE:-10.0.0.0/24}"
PSA_RANGE_NAME="${PSA_RANGE_NAME:-google-managed-services-${VPC_NETWORK}}"
PSA_PREFIX_LENGTH="${PSA_PREFIX_LENGTH:-16}" # /16 is GCP's recommendation; reserved, not consumed
DB_INSTANCE="${DB_INSTANCE:-claude-gateway-db}"
DB_VERSION="${DB_VERSION:-POSTGRES_16}" # PG14+ supported; 16 is the recommended default (§4)
DB_TIER="${DB_TIER:-db-g1-small}"
DB_NAME="${DB_NAME:-claude_gateway}"
DB_USER="${DB_USER:-gateway}"
SECRET_NAME="${SECRET_NAME:-gateway-postgres-url}" # §5 store.postgres_url
JWT_SECRET_NAME="${JWT_SECRET_NAME:-gateway-jwt-secret}" # §5 session.jwt_secret
GATEWAY_YAML="${GATEWAY_YAML:-./gateway.yaml}" # §6 config file
CONFIG_SECRET="${CONFIG_SECRET:-gateway-config}" # §6 mounted at /etc/claude/gateway.yaml
# §7 Cloud Run deploy
SERVICE_NAME="${SERVICE_NAME:-claude-gateway}"
OIDC_SECRET_NAME="${OIDC_SECRET_NAME:-gateway-oidc-client-secret}" # operator-created (Google OAuth client)
DEPLOY="${DEPLOY:-1}" # set DEPLOY=0 to provision only, no Cloud Run deploy
INGRESS="${INGRESS:-internal}" # internal (default; no public URL) | internal-and-cloud-load-balancing (only if you front it with your own internal ALB)
MAX_INSTANCES="${MAX_INSTANCES:-8}" # keep MAX_INSTANCES × store.max_connections (default 5) below the DB tier's max_connections (~50 on db-g1-small); raise the tier before raising this
# ---- helpers ----------------------------------------------------------------
log() { printf '\n==> %s\n' "$*"; }
skip() { printf ' (exists) %s\n' "$*"; }
curl_https() { curl --proto '=https' --proto-redir '=https' --tlsv1.2 "$@"; } # refuse plaintext/protocol-downgrade
sha_of() { openssl dgst -sha256 "$1" | awk '{print $NF}'; } # openssl avoids shasum/sha256sum portability gaps
if [[ -z "${PROJECT_ID}" ]]; then
echo "ERROR: PROJECT_ID is not set and no gcloud default project is configured." >&2
echo " Set it with: export PROJECT_ID=<your-project> (or 'gcloud config set project ...')" >&2
exit 1
fi
# VERSION tags the image and selects the public Claude Code release to download.
# The first resolved value is pinned to ${VERSION_FILE} so the documented
# re-runs (fill gateway.yaml -> re-run; set public_url -> re-run) don't silently
# build and deploy a newer release mid-bootstrap.
if [[ -z "${VERSION}" && -f "${VERSION_FILE}" ]]; then
VERSION="$(< "${VERSION_FILE}")"
log "Using release pinned in ${VERSION_FILE}: ${VERSION} (delete the file or set VERSION to change it)"
elif [[ -z "${VERSION}" ]]; then
# /latest is the channel the official installer (claude.ai/install.sh) uses.
VERSION="$(curl_https -fsSL "${RELEASES_URL}/latest" | tr -d '[:space:]' || true)"
if [[ -z "${VERSION}" ]]; then
echo "ERROR: could not resolve the latest release from ${RELEASES_URL}/latest." >&2
echo " Set VERSION to a Claude Code release version, e.g. export VERSION=2.1.195" >&2
exit 1
fi
log "VERSION not set — using latest Claude Code release: ${VERSION}"
fi
# Reject non-version content (e.g. an HTML error page served with HTTP 200)
# before it reaches the image tag and download URLs.
if [[ ! "${VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then
echo "ERROR: '${VERSION}' is not a release version (from VERSION, ${VERSION_FILE}, or ${RELEASES_URL}/latest)." >&2
exit 1
fi
printf '%s' "${VERSION}" > "${VERSION_FILE}"
IMAGE="${REGION}-docker.pkg.dev/${PROJECT_ID}/${AR_REPO}/${IMAGE_NAME}:${VERSION}"
# Claude Code only connects to a gateway whose hostname resolves to private
# addresses (a client-side /login check), so public ingress can never serve
# clients — mirror the terraform module's validation and refuse it up front.
if [[ "${INGRESS}" != "internal" && "${INGRESS}" != "internal-and-cloud-load-balancing" ]]; then
echo "ERROR: INGRESS must be 'internal' or 'internal-and-cloud-load-balancing' — Claude Code's" >&2
echo " /login only accepts gateway hosts on private addresses, so public ingress cannot serve clients." >&2
exit 1
fi
log "Project: ${PROJECT_ID} Region: ${REGION} VPC: ${VPC_NETWORK}"
# ---- 1 Project & API setup ------------------------------------------------
# walkthrough §1 list (aiplatform, artifactregistry, sqladmin, secretmanager, iamcredentials)
# plus iam/compute/servicenetworking required for the SA + private-IP networking below.
# container.googleapis.com is for the GKE track (§7a) — harmless if you stay on Cloud Run.
# We pass --project on every call rather than mutating your gcloud config.
log "Enabling required APIs (§1)"
gcloud services enable \
aiplatform.googleapis.com \
artifactregistry.googleapis.com \
sqladmin.googleapis.com \
secretmanager.googleapis.com \
iamcredentials.googleapis.com \
iam.googleapis.com \
compute.googleapis.com \
container.googleapis.com \
servicenetworking.googleapis.com \
run.googleapis.com \
--project="${PROJECT_ID}"
# ---- 2 Service account & IAM ----------------------------------------------
log "Creating service account ${SA_EMAIL} and granting project roles (§2)"
if gcloud iam service-accounts describe "${SA_EMAIL}" --project="${PROJECT_ID}" >/dev/null 2>&1; then
skip "service account ${SA_EMAIL}"
else
gcloud iam service-accounts create "${SA_NAME}" \
--display-name="Claude Gateway" --project="${PROJECT_ID}"
fi
# add-iam-policy-binding is idempotent (re-adding an existing binding is a no-op).
# --condition=None avoids the interactive condition prompt in non-interactive runs.
#
# Only aiplatform.user is granted: the gateway reaches Cloud SQL over the VPC at
# its PRIVATE IP with a password user (§4/§7b — direct TCP, not the Cloud SQL
# Auth Proxy / connector), so it never calls cloudsql.instances.connect and no
# roles/cloudsql.client grant is needed. Direct private-IP is used because the
# gateway's store is a plain postgres_url — no proxy sidecar/socket plumbing,
# one less moving part, and the connection string is portable across Cloud Run
# and GKE.
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${SA_EMAIL}" \
--role="roles/aiplatform.user" --condition=None >/dev/null # Agent Platform inference (§2)
# ---- 3 Build & push image to Artifact Registry ----------------------------
log "Ensuring Artifact Registry repo and image (§3)"
if gcloud artifacts repositories describe "${AR_REPO}" \
--location="${REGION}" --project="${PROJECT_ID}" >/dev/null 2>&1; then
skip "Artifact Registry repo ${AR_REPO}"
else
gcloud artifacts repositories create "${AR_REPO}" \
--repository-format=docker --location="${REGION}" --project="${PROJECT_ID}"
fi
# Image is the expensive, already-done step: skip the build+push entirely if the
# tag already exists in the registry.
if gcloud artifacts docker images describe "${IMAGE}" >/dev/null 2>&1; then
skip "image ${IMAGE}"
else
# The public Claude Code release includes the gateway subcommand, so the
# binary comes straight from the release endpoint, verified against the
# release manifest's sha256. A pre-existing ${CLAUDE_BINARY} (stale version,
# interrupted download, hand-placed file) is verified the same way and
# re-downloaded on mismatch, so an unverified binary can never reach the image.
manifest="$(curl_https -fsSL "${RELEASES_URL}/${VERSION}/manifest.json" | tr -d '[:space:]' || true)"
sha_re='"linux-x64"[^}]*"checksum":"([a-f0-9]{64})"' # structure-based: survives pretty-printed, minified, and one-line-per-platform manifests
if [[ ! "${manifest}" =~ ${sha_re} ]]; then
echo "ERROR: could not read the linux-x64 sha256 from ${RELEASES_URL}/${VERSION}/manifest.json — refusing to build." >&2
exit 1
fi
expected_sha="${BASH_REMATCH[1]}"
if [[ -f "${CLAUDE_BINARY}" && "$(sha_of "${CLAUDE_BINARY}")" == "${expected_sha}" ]]; then
skip "binary ${CLAUDE_BINARY} (sha256 matches release ${VERSION})"
else
if [[ -f "${CLAUDE_BINARY}" ]]; then
log "Existing ${CLAUDE_BINARY} does not match release ${VERSION} — re-downloading"
else
log "Downloading Claude Code ${VERSION} (linux-x64) from ${RELEASES_URL}"
fi
# Until verification passes, ANY exit (curl failure, set -e, signal, the
# error exit below) removes the file, so a partial download can't be
# silently picked up by a later run.
trap 'rm -f "${CLAUDE_BINARY}"' EXIT INT TERM
curl_https -fL -o "${CLAUDE_BINARY}" "${RELEASES_URL}/${VERSION}/linux-x64/claude"
actual_sha="$(sha_of "${CLAUDE_BINARY}")"
if [[ "${actual_sha}" != "${expected_sha}" ]]; then
echo "ERROR: sha256 of ${CLAUDE_BINARY} is ${actual_sha} but the release manifest says ${expected_sha} — refusing to build." >&2
exit 1
fi
trap - EXIT INT TERM
log "Verified binary sha256 ${actual_sha}"
fi
# Optional out-of-band pin, checked even for a pre-existing binary: the
# manifest shares an origin with the binary, so it can't defend against a
# compromised endpoint — CLAUDE_SHA256 can.
if [[ -n "${CLAUDE_SHA256}" && "$(sha_of "${CLAUDE_BINARY}")" != "${CLAUDE_SHA256}" ]]; then
echo "ERROR: sha256 of ${CLAUDE_BINARY} does not match CLAUDE_SHA256 (${CLAUDE_SHA256}) — refusing to build." >&2
exit 1
fi
chmod +x "${CLAUDE_BINARY}"
log "Building and pushing ${IMAGE}"
gcloud auth configure-docker "${REGION}-docker.pkg.dev" --quiet
# Cloud Run requires linux/amd64. --platform forces it (e.g. when building on an
# Apple Silicon Mac), and --provenance=false keeps buildx from wrapping the result
# in an OCI image index that Cloud Run rejects ("manifest ... must support amd64/linux").
docker build --platform=linux/amd64 --provenance=false \
-f "${DOCKERFILE}" --build-arg CLAUDE_BINARY="${CLAUDE_BINARY}" -t "${IMAGE}" .
docker push "${IMAGE}"
fi
# ---- 4 VPC + Private Services Access (private-IP prerequisite) -------------
log "Creating VPC network and subnet"
if gcloud compute networks describe "${VPC_NETWORK}" --project="${PROJECT_ID}" >/dev/null 2>&1; then
skip "network ${VPC_NETWORK}"
else
gcloud compute networks create "${VPC_NETWORK}" \
--subnet-mode=custom --project="${PROJECT_ID}"
fi
if gcloud compute networks subnets describe "${SUBNET}" \
--region="${REGION}" --project="${PROJECT_ID}" >/dev/null 2>&1; then
skip "subnet ${SUBNET}"
else
gcloud compute networks subnets create "${SUBNET}" \
--network="${VPC_NETWORK}" --region="${REGION}" \
--range="${SUBNET_RANGE}" --project="${PROJECT_ID}"
fi
log "Configuring Private Services Access (allocated range + VPC peering)"
if gcloud compute addresses describe "${PSA_RANGE_NAME}" \
--global --project="${PROJECT_ID}" >/dev/null 2>&1; then
skip "allocated range ${PSA_RANGE_NAME}"
else
gcloud compute addresses create "${PSA_RANGE_NAME}" \
--global --purpose=VPC_PEERING --prefix-length="${PSA_PREFIX_LENGTH}" \
--network="${VPC_NETWORK}" --project="${PROJECT_ID}"
fi
if gcloud services vpc-peerings list --network="${VPC_NETWORK}" --project="${PROJECT_ID}" \
--format='value(peering)' 2>/dev/null | grep -q servicenetworking; then
skip "servicenetworking VPC peering"
else
gcloud services vpc-peerings connect \
--service=servicenetworking.googleapis.com \
--ranges="${PSA_RANGE_NAME}" \
--network="${VPC_NETWORK}" --project="${PROJECT_ID}"
fi
# ---- 4 Cloud SQL instance (private IP only) -------------------------------
log "Creating Cloud SQL instance ${DB_INSTANCE} (private IP only)"
if gcloud sql instances describe "${DB_INSTANCE}" --project="${PROJECT_ID}" >/dev/null 2>&1; then
skip "instance ${DB_INSTANCE}"
else
gcloud sql instances create "${DB_INSTANCE}" \
--database-version="${DB_VERSION}" \
--tier="${DB_TIER}" \
--region="${REGION}" \
--network="projects/${PROJECT_ID}/global/networks/${VPC_NETWORK}" \
--no-assign-ip \
--project="${PROJECT_ID}"
fi
log "Creating database ${DB_NAME}"
if gcloud sql databases describe "${DB_NAME}" \
--instance="${DB_INSTANCE}" --project="${PROJECT_ID}" >/dev/null 2>&1; then
skip "database ${DB_NAME}"
else
gcloud sql databases create "${DB_NAME}" \
--instance="${DB_INSTANCE}" --project="${PROJECT_ID}"
fi
# hex (not base64) keeps the password URL-safe for the connection string below.
log "Creating database user ${DB_USER}"
DB_PASSWORD=""
if gcloud sql users list --instance="${DB_INSTANCE}" --project="${PROJECT_ID}" \
--format='value(name)' 2>/dev/null | grep -qx "${DB_USER}"; then
if gcloud secrets describe "${SECRET_NAME}" --project="${PROJECT_ID}" >/dev/null 2>&1; then
skip "user ${DB_USER} (password unchanged; secret not rewritten)"
else
# Self-heal: a previous run died after creating the user but before writing
# the connection-string secret, losing the only copy of the password. The
# secret is the password's only consumer, so resetting it is safe and keeps
# re-runs able to recover from any partial state.
log "User ${DB_USER} exists but secret ${SECRET_NAME} is missing — resetting password"
DB_PASSWORD="$(openssl rand -hex 24)"
gcloud sql users set-password "${DB_USER}" \
--instance="${DB_INSTANCE}" --password="${DB_PASSWORD}" \
--project="${PROJECT_ID}"
fi
else
DB_PASSWORD="$(openssl rand -hex 24)"
gcloud sql users create "${DB_USER}" \
--instance="${DB_INSTANCE}" --password="${DB_PASSWORD}" \
--project="${PROJECT_ID}"
fi
# ---- 5 Connection string -> Secret Manager + secretAccessor ---------------
PRIVATE_IP="$(gcloud sql instances describe "${DB_INSTANCE}" --project="${PROJECT_ID}" \
--format='value(ipAddresses[0].ipAddress)')"
if [[ -n "${DB_PASSWORD}" ]]; then
# direct private-IP form, ?sslmode=require (guide §4)
CONN="postgres://${DB_USER}:${DB_PASSWORD}@${PRIVATE_IP}:5432/${DB_NAME}?sslmode=require"
log "Storing connection string in Secret Manager secret ${SECRET_NAME}"
if gcloud secrets describe "${SECRET_NAME}" --project="${PROJECT_ID}" >/dev/null 2>&1; then
printf '%s' "${CONN}" | gcloud secrets versions add "${SECRET_NAME}" \
--data-file=- --project="${PROJECT_ID}"
else
printf '%s' "${CONN}" | gcloud secrets create "${SECRET_NAME}" \
--replication-policy=automatic --data-file=- --project="${PROJECT_ID}"
fi
else
log "Skipping secret write (user already existed, password not available this run)"
fi
if gcloud secrets describe "${SECRET_NAME}" --project="${PROJECT_ID}" >/dev/null 2>&1; then
log "Granting ${SA_EMAIL} secretAccessor on ${SECRET_NAME}"
gcloud secrets add-iam-policy-binding "${SECRET_NAME}" \
--member="serviceAccount:${SA_EMAIL}" \
--role="roles/secretmanager.secretAccessor" \
--condition=None --project="${PROJECT_ID}" >/dev/null
fi
# JWT signing secret — generated once (re-runs do NOT rotate it).
log "Ensuring JWT signing secret ${JWT_SECRET_NAME} (§5)"
if gcloud secrets describe "${JWT_SECRET_NAME}" --project="${PROJECT_ID}" >/dev/null 2>&1; then
skip "secret ${JWT_SECRET_NAME}"
else
openssl rand -base64 32 | tr -d '\n' | gcloud secrets create "${JWT_SECRET_NAME}" \
--replication-policy=automatic --data-file=- --project="${PROJECT_ID}"
fi
gcloud secrets add-iam-policy-binding "${JWT_SECRET_NAME}" \
--member="serviceAccount:${SA_EMAIL}" \
--role="roles/secretmanager.secretAccessor" \
--condition=None --project="${PROJECT_ID}" >/dev/null
# OIDC client secret — operator-created (the script can't generate it). Grant
# accessor here once it exists so the deploy step doesn't fail on permission.
if gcloud secrets describe "${OIDC_SECRET_NAME}" --project="${PROJECT_ID}" >/dev/null 2>&1; then
log "Granting ${SA_EMAIL} secretAccessor on ${OIDC_SECRET_NAME}"
gcloud secrets add-iam-policy-binding "${OIDC_SECRET_NAME}" \
--member="serviceAccount:${SA_EMAIL}" \
--role="roles/secretmanager.secretAccessor" \
--condition=None --project="${PROJECT_ID}" >/dev/null
fi
# ---- 6 gateway.yaml -> Secret Manager (gateway-config) --------------------
# Published only when fully filled in: refuse to push a config that still has
# REPLACE_ME placeholders (checked on non-comment lines so commented examples
# and this file's header don't trip the guard).
log "Publishing ${GATEWAY_YAML} as Secret Manager secret ${CONFIG_SECRET} (§6)"
if [[ ! -f "${GATEWAY_YAML}" ]]; then
echo " (skip) ${GATEWAY_YAML} not found — run 'cp gateway.yaml.example gateway.yaml', fill it in, then re-run (§6)."
elif grep -vE '^[[:space:]]*#' "${GATEWAY_YAML}" | grep -q 'REPLACE_ME'; then
echo " (skip) ${GATEWAY_YAML} still has REPLACE_ME placeholders to fill:"
grep -nE 'REPLACE_ME' "${GATEWAY_YAML}" | grep -vE '^[0-9]+:[[:space:]]*#' | sed 's/^/ /'
echo " Fill them in, then re-run to publish ${CONFIG_SECRET}."
else
if gcloud secrets describe "${CONFIG_SECRET}" --project="${PROJECT_ID}" >/dev/null 2>&1; then
gcloud secrets versions add "${CONFIG_SECRET}" \
--data-file="${GATEWAY_YAML}" --project="${PROJECT_ID}"
else
gcloud secrets create "${CONFIG_SECRET}" --replication-policy=automatic \
--data-file="${GATEWAY_YAML}" --project="${PROJECT_ID}"
fi
gcloud secrets add-iam-policy-binding "${CONFIG_SECRET}" \
--member="serviceAccount:${SA_EMAIL}" \
--role="roles/secretmanager.secretAccessor" \
--condition=None --project="${PROJECT_ID}" >/dev/null
fi
# ---- 7 Cloud Run deploy (Direct VPC egress) -------------------------------
# Direct VPC egress (--network/--subnet/--vpc-egress) puts the service on the
# VPC so it reaches the Cloud SQL PRIVATE IP directly — matching the private-IP
# connection string in the postgres-url secret. private-ranges-only keeps public
# egress (Agent Platform, accounts.google.com) off the VPC, so no Cloud NAT is needed.
# We deliberately do NOT use --add-cloudsql-instances (that's the Auth Proxy /
# socket path, which would need a different connection string).
#
# Secrets: gateway.yaml is mounted as a FILE at /etc/claude (alone in its dir).
# The JWT / OIDC / Postgres secrets are injected as ENV VARS — Cloud Run cannot
# mount multiple secrets into one directory, and gateway.yaml references them via
# ${ENV_VAR}. (See the env-var names in gateway.yaml: GATEWAY_JWT_SECRET etc.)
#
# Self-gating: deploy only once its inputs exist (config secret published + the
# operator-provided OIDC client secret). On a first run these are missing and it
# cleanly skips.
RUN_URL=""
missing=""
gcloud secrets describe "${CONFIG_SECRET}" --project="${PROJECT_ID}" >/dev/null 2>&1 || missing="${missing} ${CONFIG_SECRET}"
gcloud secrets describe "${OIDC_SECRET_NAME}" --project="${PROJECT_ID}" >/dev/null 2>&1 || missing="${missing} ${OIDC_SECRET_NAME}"
# Also gate on the postgres-url secret (referenced by --set-secrets below): if it
# is somehow absent, skip with a clear message rather than failing the deploy with
# a raw Cloud Run missing-secret error.
gcloud secrets describe "${SECRET_NAME}" --project="${PROJECT_ID}" >/dev/null 2>&1 || missing="${missing} ${SECRET_NAME}"
if [[ "${DEPLOY}" != "1" ]]; then
log "Skipping Cloud Run deploy (DEPLOY=${DEPLOY}) (§7)"
elif [[ -n "${missing// }" ]]; then
log "Skipping Cloud Run deploy — missing secret(s):${missing} (§7)"
echo " Fill ${GATEWAY_YAML} and re-run to publish ${CONFIG_SECRET}; create ${OIDC_SECRET_NAME}"
echo " from the Google OAuth client. Then re-run to deploy."
else
SECRET_MOUNTS="/etc/claude/gateway.yaml=${CONFIG_SECRET}:latest" # file mount (alone in /etc/claude)
SECRET_MOUNTS="${SECRET_MOUNTS},GATEWAY_JWT_SECRET=${JWT_SECRET_NAME}:latest" # env var
SECRET_MOUNTS="${SECRET_MOUNTS},OIDC_CLIENT_SECRET=${OIDC_SECRET_NAME}:latest" # env var
SECRET_MOUNTS="${SECRET_MOUNTS},GATEWAY_POSTGRES_URL=${SECRET_NAME}:latest" # env var
log "Deploying Cloud Run service ${SERVICE_NAME} (§7b, Direct VPC egress)"
# Deploy private (--no-allow-unauthenticated avoids the interactive prompt and
# keeps allUsers OUT of the deploy, so a Domain-Restricted-Sharing org doesn't
# fail the deploy on the IAM step). Public access is attempted separately below.
#
# --ingress is passed EXPLICITLY because it is sticky across redeploys (omitting
# it keeps the previous value). The default, internal, keeps the *.run.app URL
# off the public internet — reachable only from this VPC, or from corp networks
# with the PSC endpoint + private run.app DNS plumbing (see terraform/README.md
# "Private access"). Public ingress cannot serve clients (see the INGRESS
# guard at the top of this script), so the two-pass OAuth bootstrap has to be
# completed from inside the VPC (or a PSC-connected corp network). Use
# internal-and-cloud-load-balancing instead if you front the service with
# your own internal ALB.
#
# --timeout=3600 raises Cloud Run's default 300s request timeout, which would
# otherwise cut off long streaming /v1/messages responses mid-stream.
#
# --max-instances bounds the Postgres connection footprint: each instance
# opens a pool of up to 5 connections (store.max_connections default) and
# db-g1-small caps at ~50 max_connections, so the default ceiling of 100
# instances would crash-loop new instances under load. Keep
# max-instances × 5 below the DB tier's max_connections; raise the DB tier
# (or set store.max_connections lower) before raising this.
gcloud run deploy "${SERVICE_NAME}" \
--image="${IMAGE}" \
--region="${REGION}" \
--service-account="${SA_EMAIL}" \
--min-instances=1 \
--max-instances="${MAX_INSTANCES}" \
--port=8080 \
--timeout=3600 \
--ingress="${INGRESS}" \
--network="${VPC_NETWORK}" \
--subnet="${SUBNET}" \
--vpc-egress=private-ranges-only \
--set-secrets="${SECRET_MOUNTS}" \
--no-allow-unauthenticated \
--project="${PROJECT_ID}"
# The gateway runs its OWN OIDC, so the Cloud Run IAM layer must allow
# unauthenticated. Attempt it separately and tolerate failure: Domain Restricted
# Sharing (iam.allowedPolicyMemberDomains) blocks allUsers in hardened orgs.
log "Granting public invoker (allUsers) — required for the gateway's OIDC login"
if gcloud run services add-iam-policy-binding "${SERVICE_NAME}" \
--region="${REGION}" --member=allUsers --role=roles/run.invoker \
--project="${PROJECT_ID}" >/dev/null 2>&1; then
echo " public invoker granted."
else
echo " WARN: allUsers rejected (likely Domain Restricted Sharing). The service is"
echo " deployed but the invoker IAM check is still enabled, so requests 403"
echo " before reaching the container. Preferred fix (where available):"
echo " gcloud run services update ${SERVICE_NAME} --no-invoker-iam-check \\"
echo " --region=${REGION} --project=${PROJECT_ID}"
echo " Alternatively: request a DRS exception for ${SERVICE_NAME}, or use the GKE"
echo " track, which exposes the gateway at the network layer with no allUsers"
echo " binding. An LB is NOT a fix — it does not bypass the invoker IAM check."
fi
RUN_URL="$(gcloud run services describe "${SERVICE_NAME}" --region="${REGION}" \
--project="${PROJECT_ID}" --format='value(status.url)')"
log "Cloud Run URL: ${RUN_URL}"
# public_url is now required (config validation refuses a non-loopback bind
# without it), so the template ships a placeholder for the first pass. Once we
# know the real URL, warn on any mismatch so the operator doesn't leave the
# placeholder — or a stale hostname — in place. Normalize quotes / inline
# comments / a trailing slash so schema-equivalent spellings compare equal.
# Only checked with internal ingress, where public_url should be the run.app
# URL; behind an internal ALB it is the ALB hostname, which this script
# cannot know.
CFG_PUBLIC_URL="$(grep -E '^[[:space:]]*public_url:' "${GATEWAY_YAML}" 2>/dev/null \
| head -1 \
| sed -E 's/^[[:space:]]*public_url:[[:space:]]*//; s/[[:space:]]+#.*$//; s/[[:space:]]*$//' \
|| true)"
CFG_PUBLIC_URL="${CFG_PUBLIC_URL#[\'\"]}"; CFG_PUBLIC_URL="${CFG_PUBLIC_URL%[\'\"]}"
CFG_PUBLIC_URL="${CFG_PUBLIC_URL%/}"
if [[ "${INGRESS}" == "internal" && -n "${RUN_URL}" && "${CFG_PUBLIC_URL}" != "${RUN_URL%/}" ]]; then
echo " NOTE — ${GATEWAY_YAML} has public_url: ${CFG_PUBLIC_URL:-<unset>}"
echo " but this service's URL is ${RUN_URL}."
echo " Set listen.public_url to ${RUN_URL} (or your LB hostname) and re-run."
fi
if [[ -n "${RUN_URL}" ]]; then
# gcloud run deploy already fails the script if the revision can't boot (it
# waits for the Ready condition), so what's left to verify is that the
# gateway is serving. The OAuth discovery document below returns 200 only
# after config load, OIDC discovery, upstream construction, and Postgres
# migration all succeed, so it doubles as an end-to-end boot check (the
# readiness probe proper is GET /readyz). With internal ingress the URL is
# reachable only from inside the VPC (or a PSC-connected corp network), so
# verification is left to the operator rather than attempted from here.
log "Verify the gateway is serving (from inside the VPC, or a PSC-connected corp network):"
echo " curl -s ${RUN_URL}/.well-known/oauth-authorization-server"
echo " If it isn't responding yet, check logs:"
echo " gcloud run services logs read ${SERVICE_NAME} --region=${REGION} --project=${PROJECT_ID}"
log "Finish the OAuth bootstrap:"
echo " 1. Register this redirect URI on the Google OAuth client: ${RUN_URL}/oauth/callback"
echo " 2. Set listen.public_url in ${GATEWAY_YAML} to ${RUN_URL}, then re-run: INGRESS=${INGRESS} ./setup.sh"
echo " (republishes ${CONFIG_SECRET} and redeploys so the IdP redirect_uri matches)."
echo " With INGRESS=internal-and-cloud-load-balancing, use your internal ALB hostname"
echo " instead of the run.app URL in both steps."
fi
fi
# ---- summary ----------------------------------------------------------------
cat <<EOF
==> Done.
Service account ${SA_EMAIL}
roles: aiplatform.user, secretmanager.secretAccessor
Image ${IMAGE}
Instance ${DB_INSTANCE}
Connection name ${PROJECT_ID}:${REGION}:${DB_INSTANCE}
Private IP ${PRIVATE_IP}
Database / user ${DB_NAME} / ${DB_USER}
Secrets ${SECRET_NAME}, ${JWT_SECRET_NAME}, ${CONFIG_SECRET}
Cloud Run service ${SERVICE_NAME} -> ${RUN_URL:-(not deployed yet)} (ingress: ${INGRESS})
Next steps (see https://code.claude.com/docs/en/claude-apps-gateway-on-gcp):
- Create the one operator-provided secret (from the Google Cloud Console OAuth client):
printf '%s' "<client-secret>" | gcloud secrets create ${OIDC_SECRET_NAME} \\
--data-file=- --project="${PROJECT_ID}"
setup.sh grants ${SA_EMAIL} secretAccessor on it on the next re-run.
- Fill in the REPLACE_ME values in ${GATEWAY_YAML}, then re-run: setup.sh publishes
${CONFIG_SECRET} and deploys ${SERVICE_NAME} once both secrets exist.
- After the first deploy: set listen.public_url to the Cloud Run URL above (or your
internal ALB hostname) and register <url>/oauth/callback on the Google OAuth client,
then re-run to redeploy.
- The gateway runs its own schema migrations at boot, so ${DB_USER} needs CREATE TABLE.
EOF
+13
View File
@@ -0,0 +1,13 @@
# Never commit state (contains secrets) or local var files
*.tfstate
*.tfstate.*
.terraform/
terraform.tfvars
*.auto.tfvars
crash.log
# The lock file holds no secrets. It's ignored here so consumers who copy this
# example into their own repo generate (and commit) their own platform-complete
# lock at first init — committing one from this repo would carry only one
# platform's provider hashes.
.terraform.lock.hcl
+160
View File
@@ -0,0 +1,160 @@
# Claude Gateway — Terraform (Cloud Run)
Terraform equivalent of `../setup.sh`. Lets end-users provision and manage
the gateway with `terraform apply`. Covers the same scope ([walkthrough](https://code.claude.com/docs/en/claude-apps-gateway-on-gcp) §17): APIs →
service account + IAM → Artifact Registry repo → VPC + Private Services Access →
private-IP Cloud SQL (PG16) → secrets → Cloud Run with Direct VPC egress.
## Files
| File | Purpose |
|------|---------|
| `versions.tf` | Provider pins (google, random) |
| `variables.tf` | All inputs (defaults match `setup.sh`'s) |
| `main.tf` | Resources |
| `outputs.tf` | Service URL, OAuth redirect URI, SA, DB info |
| `terraform.tfvars.example` | Copy to `terraform.tfvars` and edit |
## Prerequisites
1. **`../gateway.yaml` created and filled in** — copy the template first:
`cp ../gateway.yaml.example ../gateway.yaml`, then replace every `REPLACE_ME`
(Terraform reads this file and enforces no `REPLACE_ME` via a precondition).
Leave `public_url` at its placeholder for the first apply; set it to the
`run.app` URL (the `service_url` output) or your LB hostname and re-apply.
`gateway.yaml` is gitignored; the committed template is `gateway.yaml.example`.
2. A **remote backend** for shared use (see below). State holds secrets — never commit it.
## Deploy
Terraform creates the Artifact Registry repo but does **not** build/push the
image, so the apply is two passes: a targeted apply to create the repo, then
build/push, then the full apply.
```bash
cp terraform.tfvars.example terraform.tfvars # edit it
terraform init
# 1. Create just the Artifact Registry repo (the -target warning is expected):
terraform apply -target=google_artifact_registry_repository.repo
# 2. Download the public Claude Code linux-x64 release binary (it includes the
# `gateway` subcommand; the Dockerfile picks it up at gcp/claude), verify its
# sha256 against the release manifest, then build and push the image:
BASE="https://downloads.claude.ai/claude-code-releases"
VERSION="$(curl -fsSL --proto '=https' "${BASE}/latest")"
curl -fL --proto '=https' --proto-redir '=https' -o ../claude \
"${BASE}/${VERSION}/linux-x64/claude"
WANT="$(curl -fsSL --proto '=https' "${BASE}/${VERSION}/manifest.json" \
| tr -d '[:space:]' | grep -oE '"linux-x64"[^}]*' | grep -oE '[a-f0-9]{64}' | head -1)"
[ "$(openssl dgst -sha256 ../claude | awk '{print $NF}')" = "${WANT}" ] \
&& echo "sha256 OK" || { echo "checksum mismatch" >&2; rm -f ../claude; }
gcloud auth configure-docker us-east5-docker.pkg.dev --quiet
docker build --platform=linux/amd64 --provenance=false \
-f ../Dockerfile -t "us-east5-docker.pkg.dev/<project>/claude-gateway/gateway:${VERSION}" ..
docker push "us-east5-docker.pkg.dev/<project>/claude-gateway/gateway:${VERSION}"
# 3. Full apply:
terraform apply
```
(`../setup.sh` §3 automates the same download-and-verify.)
Set in `terraform.tfvars`:
- `project_id`, `region`
- `image_tag` (after building/pushing — step 2 above)
- **`oidc_client_secret`** — required (the Cloud Run service mounts `latest` of
this secret; with no version the deploy fails). Terraform creates the
secret + version from it.
- `invoker_iam_disabled` / `allow_unauthenticated` — the gateway runs its own
OIDC, so the Cloud Run invoker IAM check must be opened or disabled.
**Preferred:** `invoker_iam_disabled = true` (no `allUsers` binding; works
under Domain Restricted Sharing). **Fallback:** `allow_unauthenticated = true`
grants `allUsers` `run.invoker` — fine on a normal org, but DRS orgs reject
`allUsers` (set it `false` there, since an LB does **not** bypass the IAM
check). If both paths are blocked by org policy, use the GKE track.
- `ingress` — defaults to **internal-only** (no public URL). Claude Code's `/login`
only accepts gateway hosts on private addresses, so public ingress cannot serve
clients; the two-pass OAuth bootstrap must be completed from inside the VPC (or a
PSC-connected corp network). See "Private access" below.
Tear down a trial with `terraform destroy`: set `deletion_protection = false`,
run `terraform apply` to record that in state (the provider checks the value in
**state**, not config, so destroy would still refuse otherwise), then `terraform
destroy`. The destroy will stop at the VPC network
because the Private Services Access peering is intentionally left in place
(`deletion_policy = ABANDON` — see Guard rails below); finish by deleting the
peering manually once the Cloud SQL instance is gone, then re-run destroy:
```bash
gcloud services vpc-peerings delete --service=servicenetworking.googleapis.com \
--network=cc-gateway-vpc --project=<project>
terraform destroy
```
## Guard rails
Tuned so accidental deletion is hard but greenfield teardown stays easy:
- `deletion_protection = true` (variable, default true) on Cloud SQL and Cloud Run —
blocks accidental deletion; set `false` when you intend to `terraform destroy`.
- `disable_on_destroy = false` on APIs — tearing down config never disables APIs.
- `deletion_policy = ABANDON` on the PSA peering — never tears down the
service-networking peering automatically (it's shared by every private-IP
service on the VPC). On the dedicated VPC this module creates, that means
`terraform destroy` stops at the network step; delete the peering manually
per the teardown note above.
- IAM uses non-authoritative `_member` resources, so other project/secret bindings
are never clobbered.
## Private access (internal ingress) — the default
By default the service has **no public URL** (`ingress = "INGRESS_TRAFFIC_INTERNAL_ONLY"`),
and there is no public-ingress option: Claude Code's `/login` rejects gateway hosts that
resolve to public addresses, so public exposure cannot serve clients. Reach the service
from inside the VPC, or via the private-access plumbing below.
With internal-only ingress, `public_url` stays the `run.app` URL (Google-managed cert) —
**no load balancer or your own certificate required**. But internal ingress alone does
**not** let corporate on-prem clients reach `run.app`; that needs **operator /
network-team-owned** plumbing that Cloud Run does **not** create for you (validate it's in
place before relying on internal ingress):
1. A **Private Service Connect endpoint** for Google APIs (an internal VIP in the VPC).
2. A **Cloud DNS private zone for `run.app`** resolving `*.run.app` to that endpoint IP.
3. **On-prem routing** to the endpoint over Cloud VPN / Interconnect.
This is normally managed centrally in the network/hub project, so the module does not
provision it. See [Private networking and Cloud Run](https://cloud.google.com/run/docs/securing/private-networking).
For a greenfield trial without this plumbing, complete the OAuth bootstrap from inside
the VPC — e.g. a browser proxied through an in-VPC VM (SSH SOCKS tunnel over IAP).
For a **custom internal hostname or your own TLS cert**, use
`INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER` and front the service with your own internal
Application Load Balancer (also not provisioned by this module).
## Remote state (recommended for teams)
Add a backend so state is shared and locked (and out of git):
```hcl
# backend.tf
terraform {
backend "gcs" {
bucket = "<your-tf-state-bucket>"
prefix = "claude-gateway/cloudrun"
}
}
```
## After deploy
- `terraform output service_url` / `oauth_redirect_uri`.
- Register the redirect URI on the Google OAuth client and make sure
`../gateway.yaml` `public_url` matches the host.
- Notes: Terraform does not build the image. To ship a new gateway version,
rerun the docker build/push under a new tag and bump `image_tag` — a bare
re-apply under an unchanged tag does **not** roll a new revision (Cloud Run
resolves the tag to a digest only at revision creation, and an unchanged
`image` attribute means no new revision).
+399
View File
@@ -0,0 +1,399 @@
# Claude Gateway on Cloud Run — Terraform equivalent of setup.sh.
# Section markers (§N) map to setup.sh and the walkthrough:
# https://code.claude.com/docs/en/claude-apps-gateway-on-gcp
locals {
config_path = var.gateway_config_path != "" ? var.gateway_config_path : "${path.module}/../gateway.yaml"
gateway_config = file(local.config_path)
image = "${var.region}-docker.pkg.dev/${var.project_id}/${var.ar_repo}/${var.image_name}:${var.image_tag}"
apis = [
"aiplatform.googleapis.com",
"artifactregistry.googleapis.com",
"cloudresourcemanager.googleapis.com",
"sqladmin.googleapis.com",
"secretmanager.googleapis.com",
"iamcredentials.googleapis.com",
"iam.googleapis.com",
"compute.googleapis.com",
"servicenetworking.googleapis.com",
"run.googleapis.com",
]
}
# ── 1 Project & API setup ───────────────────────────────────────────────────
resource "google_project_service" "apis" {
for_each = toset(local.apis)
project = var.project_id
service = each.value
# Don't disable APIs (or delete anything) when this config is torn down.
disable_on_destroy = false
disable_dependent_services = false
}
# ── 2 Service account & IAM (least-privilege) ───────────────────────────────
resource "google_service_account" "gateway" {
project = var.project_id
account_id = var.sa_name
display_name = "Claude Gateway"
depends_on = [google_project_service.apis]
}
# Non-authoritative (_member) so we never clobber other project bindings.
#
# Only aiplatform.user is granted: the gateway reaches Cloud SQL over the VPC at
# its private IP with a password user (direct TCP via Direct VPC egress — see §7
# below), not via the Cloud SQL Auth Proxy / connector, so it never calls
# cloudsql.instances.connect and no roles/cloudsql.client grant is needed.
# Direct private-IP keeps the gateway's store a plain postgres_url with no proxy
# sidecar/socket plumbing, and the connection string is portable across Cloud
# Run and GKE.
resource "google_project_iam_member" "vertex" {
project = var.project_id
role = "roles/aiplatform.user" # Agent Platform inference
member = "serviceAccount:${google_service_account.gateway.email}"
}
# ── 3 Artifact Registry repo ────────────────────────────────────────────────
# NOTE: image build/push is a separate step (see README) — Terraform only makes the repo.
resource "google_artifact_registry_repository" "repo" {
project = var.project_id
location = var.region
repository_id = var.ar_repo
format = "DOCKER"
description = "Claude Gateway container images"
depends_on = [google_project_service.apis]
}
# ── 4 VPC + Private Services Access ──────────────────────────────────────────
resource "google_compute_network" "vpc" {
project = var.project_id
name = var.vpc_network
auto_create_subnetworks = false
depends_on = [google_project_service.apis]
}
resource "google_compute_subnetwork" "subnet" {
project = var.project_id
name = var.subnet
region = var.region
network = google_compute_network.vpc.id
ip_cidr_range = var.subnet_range
}
resource "google_compute_global_address" "psa_range" {
project = var.project_id
name = "google-managed-services-${var.vpc_network}"
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = var.psa_prefix_length
network = google_compute_network.vpc.id
}
resource "google_service_networking_connection" "psa" {
network = google_compute_network.vpc.id
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = [google_compute_global_address.psa_range.name]
# ABANDON: on destroy, leave the producer peering in place (deleting it can hang
# and would affect any other private-IP service on this VPC).
deletion_policy = "ABANDON"
# If the peering already exists (e.g. a previous apply failed partway), patch it
# instead of failing the create.
update_on_creation_fail = true
depends_on = [google_project_service.apis]
}
# ── 4 Cloud SQL (private IP only) ───────────────────────────────────────────
resource "google_sql_database_instance" "db" {
project = var.project_id
name = var.db_instance
region = var.region
database_version = var.db_version
deletion_protection = var.deletion_protection
depends_on = [google_service_networking_connection.psa]
settings {
tier = var.db_tier
ip_configuration {
ipv4_enabled = false # private IP only (org policy: sql.restrictPublicIp)
private_network = google_compute_network.vpc.id
ssl_mode = "ENCRYPTED_ONLY"
}
}
}
resource "google_sql_database" "db" {
project = var.project_id
name = var.db_name
instance = google_sql_database_instance.db.name
}
# URL-safe (alphanumeric) so it drops cleanly into the connection string.
# nosemgrep: terraform-generic-secrets-in-state -- secrets in tfstate are inherent to TF; mitigated by the documented remote GCS backend (see README "Remote state")
resource "random_password" "db" {
length = 32
special = false
}
# nosemgrep: terraform-gcp-secrets-in-state -- secrets in tfstate are inherent to TF; mitigated by the documented remote GCS backend (see README "Remote state")
resource "google_sql_user" "gateway" {
project = var.project_id
name = var.db_user
instance = google_sql_database_instance.db.name
password = random_password.db.result
# On destroy the role owns the tables it migrated at boot, so DROP ROLE can
# fail (and races google_sql_database.db). ABANDON is harmless on the
# greenfield teardown — the whole instance is deleted anyway.
deletion_policy = "ABANDON"
}
# ── 5/6 Secrets + secretAccessor ────────────────────────────────────────────
# postgres-url: connection string built from the instance's private IP.
resource "google_secret_manager_secret" "postgres_url" {
project = var.project_id
secret_id = var.secret_name
replication {
auto {}
}
depends_on = [google_project_service.apis]
}
# nosemgrep: terraform-gcp-secrets-in-state -- secrets in tfstate are inherent to TF; mitigated by the documented remote GCS backend (see README "Remote state")
resource "google_secret_manager_secret_version" "postgres_url" {
secret = google_secret_manager_secret.postgres_url.id
secret_data = "postgres://${var.db_user}:${random_password.db.result}@${google_sql_database_instance.db.private_ip_address}:5432/${var.db_name}?sslmode=require"
}
# jwt: session signing key.
# nosemgrep: terraform-generic-secrets-in-state -- secrets in tfstate are inherent to TF; mitigated by the documented remote GCS backend (see README "Remote state")
resource "random_password" "jwt" {
length = 48
special = false
}
resource "google_secret_manager_secret" "jwt" {
project = var.project_id
secret_id = var.jwt_secret_name
replication {
auto {}
}
depends_on = [google_project_service.apis]
}
# nosemgrep: terraform-gcp-secrets-in-state -- secrets in tfstate are inherent to TF; mitigated by the documented remote GCS backend (see README "Remote state")
resource "google_secret_manager_secret_version" "jwt" {
secret = google_secret_manager_secret.jwt.id
secret_data = random_password.jwt.result
}
# oidc client secret: operator-provided (from the Google OAuth client).
resource "google_secret_manager_secret" "oidc" {
project = var.project_id
secret_id = var.oidc_secret_name
replication {
auto {}
}
depends_on = [google_project_service.apis]
}
# nosemgrep: terraform-gcp-secrets-in-state -- secrets in tfstate are inherent to TF; mitigated by the documented remote GCS backend (see README "Remote state")
resource "google_secret_manager_secret_version" "oidc" {
count = var.oidc_client_secret != "" ? 1 : 0
secret = google_secret_manager_secret.oidc.id
secret_data = var.oidc_client_secret
}
# Warn (not block) at plan time when the OIDC secret value isn't set: the Cloud
# Run service mounts gateway-oidc-client-secret:latest unconditionally, so an
# empty value with no out-of-band version means the apply fails late at
# revision creation. A warning (not a precondition) keeps the documented
# out-of-band-version mode usable.
check "oidc_client_secret_set" {
assert {
condition = var.oidc_client_secret != ""
error_message = "oidc_client_secret is empty — set it in terraform.tfvars, or add a version to the gateway-oidc-client-secret secret out-of-band before applying (the Cloud Run revision mounts it at :latest and will fail without one)."
}
}
# config: gateway.yaml. Guard mirrors the bash REPLACE_ME check (non-comment lines).
resource "google_secret_manager_secret" "config" {
project = var.project_id
secret_id = var.config_secret_name
replication {
auto {}
}
depends_on = [google_project_service.apis]
}
# nosemgrep: terraform-gcp-secrets-in-state -- secrets in tfstate are inherent to TF; mitigated by the documented remote GCS backend (see README "Remote state")
resource "google_secret_manager_secret_version" "config" {
secret = google_secret_manager_secret.config.id
secret_data = local.gateway_config
lifecycle {
precondition {
condition = length([
for line in split("\n", local.gateway_config) :
line
if !startswith(trimspace(line), "#") && strcontains(line, "REPLACE_ME")
]) == 0
error_message = "gateway.yaml still has REPLACE_ME on a non-comment line — fill it in before applying."
}
}
}
resource "google_secret_manager_secret_iam_member" "postgres_url" {
project = var.project_id
secret_id = google_secret_manager_secret.postgres_url.secret_id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${google_service_account.gateway.email}"
}
resource "google_secret_manager_secret_iam_member" "jwt" {
project = var.project_id
secret_id = google_secret_manager_secret.jwt.secret_id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${google_service_account.gateway.email}"
}
resource "google_secret_manager_secret_iam_member" "oidc" {
project = var.project_id
secret_id = google_secret_manager_secret.oidc.secret_id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${google_service_account.gateway.email}"
}
resource "google_secret_manager_secret_iam_member" "config" {
project = var.project_id
secret_id = google_secret_manager_secret.config.secret_id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${google_service_account.gateway.email}"
}
# ── 7 Cloud Run (Direct VPC egress) ─────────────────────────────────────────
resource "google_cloud_run_v2_service" "gateway" {
project = var.project_id
name = var.service_name
location = var.region
ingress = var.ingress
invoker_iam_disabled = var.invoker_iam_disabled
deletion_protection = var.deletion_protection
template {
service_account = google_service_account.gateway.email
scaling {
min_instance_count = var.min_instances
max_instance_count = var.max_instances
}
# Secrets are mounted at version=latest, so a config edit or secret
# rotation alone wouldn't diff this resource and the warm min_instances=1
# revision would keep the old values. Stamping a hash of the rendered
# config + every managed secret value forces a new revision whenever any
# of them change — without this, tainting random_password.db ALTERs the
# SQL role to the new password while the running revision keeps the old
# connection string and breaks on its next reconnect, and rotating the
# OIDC client secret leaves login failing invalid_client.
labels = {
config-sha = substr(sha256(join("", [
local.gateway_config,
random_password.db.result,
random_password.jwt.result,
var.oidc_client_secret,
])), 0, 63)
}
# Cloud Run's default 300s request timeout would cut off long streaming
# /v1/messages responses mid-stream.
timeout = "3600s"
vpc_access {
network_interfaces {
network = google_compute_network.vpc.id
subnetwork = google_compute_subnetwork.subnet.id
}
egress = "PRIVATE_RANGES_ONLY" # public egress (Agent Platform, accounts.google.com) bypasses the VPC -> no Cloud NAT needed
}
containers {
image = local.image
ports { container_port = 8080 }
# gateway.yaml mounted as a file at /etc/claude/gateway.yaml (alone in its dir).
volume_mounts {
name = "config"
mount_path = "/etc/claude"
}
# Cloud Run can't mount multiple secrets in one dir, so the rest are env vars
# (gateway.yaml references them via ${ENV_VAR}).
env {
name = "GATEWAY_JWT_SECRET"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.jwt.secret_id
version = "latest"
}
}
}
env {
name = "OIDC_CLIENT_SECRET"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.oidc.secret_id
version = "latest"
}
}
}
env {
name = "GATEWAY_POSTGRES_URL"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.postgres_url.secret_id
version = "latest"
}
}
}
}
volumes {
name = "config"
secret {
secret = google_secret_manager_secret.config.secret_id
items {
path = "gateway.yaml"
version = "latest"
}
}
}
}
depends_on = [
google_secret_manager_secret_iam_member.config,
google_secret_manager_secret_iam_member.jwt,
google_secret_manager_secret_iam_member.oidc,
google_secret_manager_secret_iam_member.postgres_url,
google_secret_manager_secret_version.config,
google_secret_manager_secret_version.postgres_url,
google_secret_manager_secret_version.jwt,
google_secret_manager_secret_version.oidc,
google_sql_database.db,
google_sql_user.gateway,
google_project_service.apis,
]
}
# Public access at the Cloud Run IAM layer — the gateway runs its own OIDC, so the
# invoker check must be opened or disabled (real auth stays the gateway's SSO):
# Preferred — disable it: invoker_iam_disabled=true on the service above. No allUsers
# binding at all, and it works under Domain Restricted Sharing.
# Fallback — open it: this allUsers run.invoker grant. Domain Restricted Sharing orgs
# reject allUsers, and an LB does NOT bypass that (ingress is network-layer; the IAM
# check still runs) — use invoker_iam_disabled, a DRS exception, or GKE.
# Skipped when invoker_iam_disabled=true (the grant would be redundant, and DRS rejects it).
resource "google_cloud_run_v2_service_iam_member" "public" {
count = var.allow_unauthenticated && !var.invoker_iam_disabled ? 1 : 0
project = var.project_id
location = var.region
name = google_cloud_run_v2_service.gateway.name
role = "roles/run.invoker"
member = "allUsers"
}
+34
View File
@@ -0,0 +1,34 @@
output "service_url" {
description = "Cloud Run service URL."
value = google_cloud_run_v2_service.gateway.uri
}
output "oauth_redirect_uri" {
description = "Register this exact URI on the Google OAuth client, and ensure gateway.yaml public_url matches the host."
value = "${google_cloud_run_v2_service.gateway.uri}/oauth/callback"
}
output "service_account_email" {
description = "Gateway runtime service account."
value = google_service_account.gateway.email
}
output "image" {
description = "Image the service runs (build/push this separately — see README)."
value = local.image
}
output "db_connection_name" {
description = "Cloud SQL instance connection name (project:region:instance)."
value = google_sql_database_instance.db.connection_name
}
output "db_private_ip" {
description = "Cloud SQL private IP."
value = google_sql_database_instance.db.private_ip_address
}
output "public_invoker_granted" {
description = "Whether the allUsers run.invoker binding was applied (false when invoker_iam_disabled handles public access instead, or on Domain-Restricted-Sharing orgs)."
value = length(google_cloud_run_v2_service_iam_member.public) > 0
}
@@ -0,0 +1,26 @@
# Copy to terraform.tfvars and edit. terraform.tfvars is gitignored (see .gitignore).
project_id = "your-gcp-project-id"
region = "us-east5"
image_tag = "<version>" # REQUIRED — the Claude Code release version you build and push as linux/amd64 (see README Deploy)
# Public access at the Cloud Run IAM layer (the gateway runs its own OIDC):
# Preferred — disable the invoker check: no allUsers binding, works under Domain
# Restricted Sharing. Needs google provider >= 6.8 and the feature enabled for your org:
# invoker_iam_disabled = true
# Fallback — grant allUsers (fine on a normal org; Domain Restricted Sharing rejects it,
# so there prefer invoker_iam_disabled, or use a DRS exception / GKE):
allow_unauthenticated = true
# Network reachability — a separate axis from the IAM choice above. Default is internal-only:
# no public URL (Claude Code's /login only accepts gateway hosts on private addresses, so
# public ingress cannot serve clients); corp on-prem reaches run.app via a PSC endpoint +
# private run.app DNS — see README "Private access" for the prerequisites. The only
# alternative to the internal-only default:
# ingress = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER" # only if you front it with your OWN internal ALB (custom hostname/cert; not provisioned here)
# Google OAuth client secret: REQUIRED — uncomment and set it (Terraform creates the
# secret version; the Cloud Run service mounts `latest`, so without a version the
# deploy fails). Leave empty only if you add the secret version out-of-band.
# oidc_client_secret = "GOCSPX-..."
+184
View File
@@ -0,0 +1,184 @@
# Inputs — mirror the env-overridable knobs in setup.sh (same defaults).
variable "project_id" {
description = "GCP project ID."
type = string
}
variable "region" {
description = "Infra region for Artifact Registry, Cloud SQL, subnet, and Cloud Run. (Agent Platform region is set separately inside gateway.yaml.)"
type = string
default = "us-east5"
}
# ── Service account (§2) ────────────────────────────────────────────────────
variable "sa_name" {
description = "Service account account_id (the part before @)."
type = string
default = "claude-gateway"
}
# ── Image (§3) ──────────────────────────────────────────────────────────────
# Terraform creates the Artifact Registry repo but does NOT build/push the image
# (that's a docker build step — see README). It references the image by tag.
variable "ar_repo" {
description = "Artifact Registry Docker repository ID."
type = string
default = "claude-gateway"
}
variable "image_name" {
description = "Image name within the repo."
type = string
default = "gateway"
}
variable "image_tag" {
description = "Image tag — the Claude Code release version you build and push (must already be pushed as linux/amd64). See the README Deploy section for the build command."
type = string
validation {
condition = can(regex("^[A-Za-z0-9_][A-Za-z0-9._-]{0,127}$", var.image_tag))
error_message = "image_tag must be a valid OCI tag — set it to the Claude Code release version you pushed (the '<version>' in terraform.tfvars.example is a placeholder)."
}
}
# ── Networking (§4) ─────────────────────────────────────────────────────────
variable "vpc_network" {
description = "Custom VPC network name."
type = string
default = "cc-gateway-vpc"
}
variable "subnet" {
description = "Subnet name (Cloud Run Direct VPC egress attaches here)."
type = string
default = "cc-gateway-subnet"
}
variable "subnet_range" {
description = "Subnet primary CIDR."
type = string
default = "10.0.0.0/24"
}
variable "psa_prefix_length" {
description = "Prefix length for the Private Services Access allocated range (/16 is GCP's recommendation)."
type = number
default = 16
}
# ── Cloud SQL (§4) ──────────────────────────────────────────────────────────
variable "db_instance" {
description = "Cloud SQL instance name."
type = string
default = "claude-gateway-db"
}
variable "db_version" {
description = "Postgres major version. The gateway supports PostgreSQL 14 or newer; 16 is the recommended default."
type = string
default = "POSTGRES_16"
}
variable "db_tier" {
description = "Cloud SQL machine tier."
type = string
default = "db-g1-small"
}
variable "db_name" {
description = "Database name."
type = string
default = "claude_gateway"
}
variable "db_user" {
description = "Database user (the gateway connects as this role)."
type = string
default = "gateway"
}
# ── Secrets (§5 / §6) ─────────────────────────────────────────────────────
variable "secret_name" {
description = "Secret Manager secret holding the Postgres connection string."
type = string
default = "gateway-postgres-url"
}
variable "jwt_secret_name" {
description = "Secret Manager secret holding the session JWT signing key."
type = string
default = "gateway-jwt-secret"
}
variable "oidc_secret_name" {
description = "Secret Manager secret holding the Google OAuth client secret."
type = string
default = "gateway-oidc-client-secret"
}
variable "config_secret_name" {
description = "Secret Manager secret holding gateway.yaml (mounted at /etc/claude/gateway.yaml)."
type = string
default = "gateway-config"
}
variable "oidc_client_secret" {
description = "Google OAuth client secret value. Leave empty to NOT manage the version via Terraform (only if you add the secret version out-of-band — without one the deploy fails)."
type = string
default = ""
sensitive = true
}
variable "gateway_config_path" {
description = "Path to gateway.yaml. Empty = ../gateway.yaml relative to this module."
type = string
default = ""
}
# ── Cloud Run (§7) ──────────────────────────────────────────────────────────
variable "service_name" {
description = "Cloud Run service name."
type = string
default = "claude-gateway"
}
variable "min_instances" {
description = "Minimum Cloud Run instances (1 avoids cold OIDC discovery)."
type = number
default = 1
}
variable "max_instances" {
description = "Maximum Cloud Run instances. Each instance opens a Postgres pool of up to 5 connections (the gateway's store.max_connections default) and db-g1-small caps at ~50 max_connections — keep max_instances × 5 below the DB tier's limit, or raise the tier before raising this."
type = number
default = 8
}
variable "ingress" {
description = "Cloud Run ingress — Claude Code's /login only accepts gateway hosts on private addresses, so public ingress cannot serve clients: INGRESS_TRAFFIC_INTERNAL_ONLY (default; no public URL — VPC-only; reaches corp on-prem only with the private-access prerequisites in the README; public_url stays the run.app URL, so no LB or custom cert needed) or INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER (front with your own internal ALB for a custom hostname/cert)."
type = string
default = "INGRESS_TRAFFIC_INTERNAL_ONLY"
validation {
condition = contains(["INGRESS_TRAFFIC_INTERNAL_ONLY", "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER"], var.ingress)
error_message = "ingress must be INGRESS_TRAFFIC_INTERNAL_ONLY or INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER — Claude Code only connects to gateways on private addresses."
}
}
variable "invoker_iam_disabled" {
description = "PREFERRED public-access path: disable the Cloud Run invoker IAM check so requests reach the container with no allUsers binding (works under Domain Restricted Sharing). Real auth stays the gateway's own OIDC. When true, the allUsers grant below is skipped. May be blocked by org policy constraints/run.managed.requireInvokerIam, or unavailable for the org (\"invoker_iam_disabled is not currently available for your organization\") — then fall back to allow_unauthenticated. Requires google provider >= 6.8."
type = bool
default = false
}
variable "allow_unauthenticated" {
description = "Fallback public-access path: grant allUsers run.invoker (the gateway needs the IAM layer open for its own OIDC). Prefer invoker_iam_disabled. Domain Restricted Sharing orgs reject allUsers — set false there and use invoker_iam_disabled, a DRS exception, or GKE."
type = bool
default = true
}
variable "deletion_protection" {
description = "Provider-level deletion protection on Cloud SQL and Cloud Run. Keep true to avoid accidental deletion of the running deployment."
type = bool
default = true
}
@@ -0,0 +1,19 @@
# Provider + version pins for the Claude Gateway Cloud Run deployment.
terraform {
required_version = ">= 1.5"
required_providers {
google = {
source = "hashicorp/google"
version = ">= 6.8, < 7.0" # 6.8 adds invoker_iam_disabled on google_cloud_run_v2_service
}
random = {
source = "hashicorp/random"
version = ">= 3.5"
}
}
}
provider "google" {
project = var.project_id
region = var.region
}
+28
View File
@@ -0,0 +1,28 @@
# MDM Deployment Examples
Example templates for deploying Claude Code [managed settings](https://code.claude.com/docs/en/settings#settings-files) through Jamf, Iru (Kandji), Intune, or Group Policy. Use these as starting points — adjust them to fit your needs.
All templates encode the same minimal example (`permissions.disableBypassPermissionsMode`). See the [settings reference](https://code.claude.com/docs/en/settings#available-settings) for the full list of keys, and [`../settings`](../settings) for more complete example configurations.
## Templates
> [!WARNING]
> These examples are community-maintained templates which may be unsupported or incorrect. You are responsible for the correctness of your own deployment configuration.
| File | Use with |
| :--- | :--- |
| [`managed-settings.json`](./managed-settings.json) | Any platform. Deploy to the [system config directory](https://code.claude.com/docs/en/settings#settings-files). |
| [`macos/com.anthropic.claudecode.plist`](./macos/com.anthropic.claudecode.plist) | Jamf or Iru (Kandji) **Custom Settings** payload. Preference domain: `com.anthropic.claudecode`. |
| [`macos/com.anthropic.claudecode.mobileconfig`](./macos/com.anthropic.claudecode.mobileconfig) | Full configuration profile for local testing or MDMs that take a complete profile. |
| [`windows/Set-ClaudeCodePolicy.ps1`](./windows/Set-ClaudeCodePolicy.ps1) | Intune **Platform scripts**. Writes `managed-settings.json` to `C:\Program Files\ClaudeCode\`. |
| [`windows/ClaudeCode.admx`](./windows/ClaudeCode.admx) + [`en-US/ClaudeCode.adml`](./windows/en-US/ClaudeCode.adml) | Group Policy or Intune **Import ADMX**. Writes `HKLM\SOFTWARE\Policies\ClaudeCode\Settings` (REG_SZ, single-line JSON). |
## Tips
- Replace the placeholder `PayloadUUID` and `PayloadOrganization` values in the `.mobileconfig` with your own (`uuidgen`)
- Before deploying to your fleet, test on a single machine and confirm `/status` lists the source under **Setting sources** — e.g. `Enterprise managed settings (plist)` on macOS or `Enterprise managed settings (HKLM)` on Windows
- Settings deployed this way sit at the top of the precedence order and cannot be overridden by users
## Full Documentation
See https://code.claude.com/docs/en/settings#settings-files for complete documentation on managed settings and settings precedence.
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadDisplayName</key>
<string>Claude Code Managed Settings</string>
<key>PayloadDescription</key>
<string>Configures managed settings for Claude Code.</string>
<key>PayloadIdentifier</key>
<string>com.anthropic.claudecode.profile</string>
<key>PayloadOrganization</key>
<string>Example Organization</string>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>DC3CBC17-3330-4CDE-94AC-D2342E9C88A3</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadDisplayName</key>
<string>Claude Code</string>
<key>PayloadIdentifier</key>
<string>com.anthropic.claudecode.profile.BEFD5F54-71FC-4012-82B2-94399A1E220B</string>
<key>PayloadType</key>
<string>com.apple.ManagedClient.preferences</string>
<key>PayloadUUID</key>
<string>BEFD5F54-71FC-4012-82B2-94399A1E220B</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadContent</key>
<dict>
<key>com.anthropic.claudecode</key>
<dict>
<key>Forced</key>
<array>
<dict>
<key>mcx_preference_settings</key>
<dict>
<key>permissions</key>
<dict>
<key>disableBypassPermissionsMode</key>
<string>disable</string>
</dict>
</dict>
</dict>
</array>
</dict>
</dict>
</dict>
</array>
</dict>
</plist>
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>permissions</key>
<dict>
<key>disableBypassPermissionsMode</key>
<string>disable</string>
</dict>
</dict>
</plist>
+5
View File
@@ -0,0 +1,5 @@
{
"permissions": {
"disableBypassPermissionsMode": "disable"
}
}
+28
View File
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<policyDefinitions xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions"
revision="1.0" schemaVersion="1.0">
<policyNamespaces>
<target prefix="claudecode" namespace="Anthropic.Policies.ClaudeCode" />
<using prefix="windows" namespace="Microsoft.Policies.Windows" />
</policyNamespaces>
<resources minRequiredRevision="1.0" />
<categories>
<category name="Cat_ClaudeCode" displayName="$(string.Cat_ClaudeCode)" />
</categories>
<policies>
<policy name="ManagedSettings"
class="Machine"
displayName="$(string.ManagedSettings)"
explainText="$(string.ManagedSettings_Explain)"
presentation="$(presentation.ManagedSettings)"
key="SOFTWARE\Policies\ClaudeCode">
<parentCategory ref="Cat_ClaudeCode" />
<supportedOn ref="windows:SUPPORTED_Windows_10_0" />
<elements>
<text id="SettingsJson" valueName="Settings" maxLength="1000000" required="true" />
</elements>
</policy>
</policies>
</policyDefinitions>
@@ -0,0 +1,28 @@
<#
Deploys Claude Code managed settings as a JSON file.
Intune: Devices > Scripts and remediations > Platform scripts > Add (Windows 10 and later).
Run this script using the logged on credentials: No
Run script in 64 bit PowerShell Host: Yes
Claude Code reads C:\Program Files\ClaudeCode\managed-settings.json at startup
and treats it as a managed policy source. Edit the JSON below to change the
deployed settings; see https://code.claude.com/docs/en/settings for available keys.
#>
$ErrorActionPreference = 'Stop'
$dir = Join-Path $env:ProgramFiles 'ClaudeCode'
New-Item -ItemType Directory -Path $dir -Force | Out-Null
$json = @'
{
"permissions": {
"disableBypassPermissionsMode": "disable"
}
}
'@
$path = Join-Path $dir 'managed-settings.json'
[System.IO.File]::WriteAllText($path, $json, (New-Object System.Text.UTF8Encoding($false)))
Write-Output "Wrote $path"
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<policyDefinitionResources xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions"
revision="1.0" schemaVersion="1.0">
<displayName>Claude Code</displayName>
<description>Claude Code policy settings</description>
<resources>
<stringTable>
<string id="Cat_ClaudeCode">Claude Code</string>
<string id="ManagedSettings">Managed settings (JSON)</string>
<string id="ManagedSettings_Explain">Configures managed settings for Claude Code.
Enter the full settings configuration as a single line of JSON. The value is stored as a REG_SZ string at HKLM\SOFTWARE\Policies\ClaudeCode\Settings and is applied at the highest precedence; users cannot override these settings.
Example:
{"permissions":{"disableBypassPermissionsMode":"disable"}}
For the list of available settings keys, see https://code.claude.com/docs/en/settings.
If your configuration is large or you prefer to manage a JSON file directly, deploy C:\Program Files\ClaudeCode\managed-settings.json instead (see Set-ClaudeCodePolicy.ps1).</string>
</stringTable>
<presentationTable>
<presentation id="ManagedSettings">
<textBox refId="SettingsJson">
<label>Settings JSON:</label>
</textBox>
</presentation>
</presentationTable>
</resources>
</policyDefinitionResources>
+35
View File
@@ -0,0 +1,35 @@
# Settings Examples
Example Claude Code settings files, primarily intended for organization-wide deployments. Use these as starting points — adjust them to fit your needs.
These may be applied at any level of the [settings hierarchy](https://code.claude.com/docs/en/settings#settings-files), though certain properties only take effect if specified in enterprise settings (e.g. `strictKnownMarketplaces`, `allowManagedHooksOnly`, `allowManagedPermissionRulesOnly`).
## Configuration Examples
> [!WARNING]
> These examples are community-maintained snippets which may be unsupported or incorrect. You are responsible for the correctness of your own settings configuration.
| Setting | [`settings-lax.json`](./settings-lax.json) | [`settings-strict.json`](./settings-strict.json) | [`settings-bash-sandbox.json`](./settings-bash-sandbox.json) |
|---------|:---:|:---:|:---:|
| Disable `--dangerously-skip-permissions` | ✅ | ✅ | |
| Block plugin marketplaces | ✅ | ✅ | |
| Block user and project-defined permission `allow` / `ask` / `deny` | | ✅ | ✅ |
| Block user and project-defined hooks | | ✅ | |
| Deny web fetch and search tools | | ✅ | |
| Bash tool requires approval | | ✅ | |
| Bash tool must run inside of sandbox | | | ✅ |
## Tips
- Consider merging snippets of the above examples to reach your desired configuration
- Settings files must be valid JSON
- Before deploying configuration files to your organization, test them locally by applying to `managed-settings.json`, `settings.json` or `settings.local.json`
- The `sandbox` property only applies to the `Bash` tool; it does not apply to other tools (like Read, Write, WebSearch, WebFetch, MCPs), hooks, or internal commands
## Deploying via MDM
To distribute these settings as enterprise-managed policy through Jamf, Iru (Kandji), Intune, or Group Policy, see the deployment templates in [`../mdm`](../mdm).
## Full Documentation
See https://code.claude.com/docs/en/settings for complete documentation on all available managed settings.
@@ -0,0 +1,18 @@
{
"allowManagedPermissionRulesOnly": true,
"sandbox": {
"enabled": true,
"autoAllowBashIfSandboxed": false,
"allowUnsandboxedCommands": false,
"excludedCommands": [],
"network": {
"allowUnixSockets": [],
"allowAllUnixSockets": false,
"allowLocalBinding": false,
"allowedDomains": [],
"httpProxyPort": null,
"socksProxyPort": null
},
"enableWeakerNestedSandbox": false
}
}
+6
View File
@@ -0,0 +1,6 @@
{
"permissions": {
"disableBypassPermissionsMode": "disable"
},
"strictKnownMarketplaces": []
}
+28
View File
@@ -0,0 +1,28 @@
{
"permissions": {
"disableBypassPermissionsMode": "disable",
"ask": [
"Bash"
],
"deny": [
"WebSearch",
"WebFetch"
]
},
"allowManagedPermissionRulesOnly": true,
"allowManagedHooksOnly": true,
"strictKnownMarketplaces": [],
"sandbox": {
"autoAllowBashIfSandboxed": false,
"excludedCommands": [],
"network": {
"allowUnixSockets": [],
"allowAllUnixSockets": false,
"allowLocalBinding": false,
"allowedDomains": [],
"httpProxyPort": null,
"socksProxyPort": null
},
"enableWeakerNestedSandbox": false
}
}
+451
View File
@@ -0,0 +1,451 @@
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md</id>
<title>Claude Code Changelog</title>
<subtitle>Release notes for Claude Code</subtitle>
<author><name>Anthropic</name></author>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md"/>
<link rel="self" type="application/atom+xml" href="https://raw.githubusercontent.com/anthropics/claude-code/main/feed.xml"/>
<updated>2026-06-29T23:27:24Z</updated>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.196</id>
<title>Claude Code v2.1.196</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.196"/>
<updated>2026-06-29T23:27:24Z</updated>
<content type="html">&lt;p&gt;• Added support for organization default models — admins set it in the org console; it shows as "Org default" (or "Role default") in /model when you haven't picked one yourself&lt;/p&gt;
&lt;p&gt;• Added readable default names for sessions at start, making them easier to identify and message&lt;/p&gt;
&lt;p&gt;• Added clickable file attachments in chat — Cmd/Ctrl-click reveals the file in Finder/Explorer&lt;/p&gt;
&lt;p&gt;• Security: claude mcp list/get no longer spawn .mcp.json servers that a repo self-approved via a committed .claude/settings.json; untrusted workspaces show ⏸ Pending approval&lt;/p&gt;
&lt;p&gt;• Fixed waking a background job permanently deleting its conversation and re-running the original prompt when the transcript probe misread a real transcript; the file is now set aside, never deleted&lt;/p&gt;
&lt;p&gt;• Fixed the rate-limit warning flickering off and rate-limit telemetry being over-counted when multiple parallel requests were in flight at the moment a usage limit was hit&lt;/p&gt;
&lt;p&gt;• Fixed duplicate recap lines after a background session's turn: a schema-rejected StructuredOutput attempt no longer renders alongside its retry&lt;/p&gt;
&lt;p&gt;• Fixed PowerShell git diff/git grep, egrep/fgrep, and quoted search patterns containing | being reported as failures when they exit 1, matching Bash behavior&lt;/p&gt;
&lt;p&gt;• Fixed multiple claude agents side panel issues: keyboard focus getting stuck when opening an agent, background jobs losing their subagent types on every open, and sessions showing incorrect status while actively running&lt;/p&gt;
&lt;p&gt;• Fixed claude agents --dangerously-skip-permissions silently falling back to auto mode instead of showing the bypass disclaimer and applying bypass mode to spawned agents&lt;/p&gt;
&lt;p&gt;• Fixed mid-turn crash recovery for Remote sessions — sessions interrupted by a server restart now auto-resume on the next worker&lt;/p&gt;
&lt;p&gt;• Fixed sessions moved with /cd reappearing in the old directory's resume list after a non-graceful exit when the old path contained special characters&lt;/p&gt;
&lt;p&gt;• Fixed claude plugin validate skipping local plugins whose source is "." and stopping after the first error class&lt;/p&gt;
&lt;p&gt;• Fixed Esc Esc at an idle prompt not opening the rewind menu (regression); use Ctrl+C or Ctrl+X Ctrl+K to stop background agents&lt;/p&gt;
&lt;p&gt;• Fixed MCP OAuth requesting the authorization server's full scopes_supported catalog when no scope is specified, causing invalid_scope failures on GitLab self-hosted and other enterprise IdPs&lt;/p&gt;
&lt;p&gt;• Fixed /context showing 0 tokens for all tool groups on Bedrock&lt;/p&gt;
&lt;p&gt;• Fixed /deep-research misreporting verifier failures as "all claims refuted" instead of unverified&lt;/p&gt;
&lt;p&gt;• Fixed plugin dependency version pins not being honored when the marketplace was added as a local folder path backed by a git repo&lt;/p&gt;
&lt;p&gt;• Fixed claude agents session status: completed rows no longer flip between "Done" and "Needs your input", stalled agents are now labeled "Needs attention", and results that mention a PR show a clickable link&lt;/p&gt;
&lt;p&gt;• Fixed voice dictation swallowing spaces and spuriously starting a recording during very fast typing when voice mode is enabled&lt;/p&gt;
&lt;p&gt;• Improved background session reliability: long-running commands and workflows now survive the session's process being stopped, restarted, or updated — including on Windows, where background shells are handed off instead of being killed&lt;/p&gt;
&lt;p&gt;• Improved background agents: workers killed by a daemon restart are now automatically resumed from where they left off the next time the agents view opens&lt;/p&gt;
&lt;p&gt;• Improved /code-review workflow: merged five cleanup finders into one, cutting token usage by roughly 25%&lt;/p&gt;
&lt;p&gt;• Reduced per-frame rendering work in the terminal UI by skipping no-op subtree walks during streaming&lt;/p&gt;
&lt;p&gt;• The streaming idle watchdog is now on by default for all providers — it aborts and retries when a response stream produces no events for 5 minutes. Set CLAUDE_ENABLE_STREAM_WATCHDOG=0 to disable.&lt;/p&gt;
&lt;p&gt;• Remote Control is now disabled when ANTHROPIC_BASE_URL points at a non-Anthropic host, matching the existing behavior under CLAUDE_CODE_USE_BEDROCK/_VERTEX/_FOUNDRY&lt;/p&gt;
&lt;p&gt;• Changed opening the agents view from a foreground session to require a single ← press instead of two, matching the behavior in background sessions&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.195</id>
<title>Claude Code v2.1.195</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.195"/>
<updated>2026-06-26T21:29:36Z</updated>
<content type="html">&lt;p&gt;• Added CLAUDE_CODE_DISABLE_MOUSE_CLICKS to disable mouse click/drag/hover in fullscreen mode while keeping wheel scroll&lt;/p&gt;
&lt;p&gt;• Fixed hook matchers with hyphenated identifiers (e.g. code-reviewer, mcp__brave-search) accidentally substring-matching — they now exact-match. Use mcp__brave-search__.* to match all tools from a hyphenated MCP server.&lt;/p&gt;
&lt;p&gt;• Fixed voice dictation on macOS capturing silence in long-running sessions after the default input device changes&lt;/p&gt;
&lt;p&gt;• Fixed voice dictation auto-submit never firing for languages written without spaces (Japanese, Chinese, Thai)&lt;/p&gt;
&lt;p&gt;• Fixed external plugins enabled only by project .claude/settings.json not requiring explicit install consent on every loader path&lt;/p&gt;
&lt;p&gt;• Fixed /plugin Enable/Disable not working when a plugin's plugin.json name differs from its marketplace entry name&lt;/p&gt;
&lt;p&gt;• Fixed background jobs disappearing from claude agents or losing data when written by a newer Claude Code version&lt;/p&gt;
&lt;p&gt;• Fixed reopening a crashed background task showing a blank screen for up to 5 seconds instead of its restart&lt;/p&gt;
&lt;p&gt;• Fixed background agent daemons running unreachable when the control socket fails to start, blocking restarts&lt;/p&gt;
&lt;p&gt;• Improved voice mode on Linux: now distinguishes "no microphone" from "SoX not installed" when SoX is present but no audio capture device exists&lt;/p&gt;
&lt;p&gt;• Improved claude agents completed list to fill available vertical space; on short terminals the header compacts so live sessions stay visible&lt;/p&gt;
&lt;p&gt;• Improved Remote session startup with a provisioning checklist while the container starts&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.193</id>
<title>Claude Code v2.1.193</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.193"/>
<updated>2026-06-25T21:45:51Z</updated>
<content type="html">&lt;p&gt;• Added autoMode.classifyAllShell setting to route all Bash/PowerShell commands through the auto-mode classifier instead of only arbitrary-code-execution patterns&lt;/p&gt;
&lt;p&gt;• Added auto-mode denial reasons to the transcript, the denial toast, and /permissions recent denials&lt;/p&gt;
&lt;p&gt;• Added claude_code.assistant_response OpenTelemetry log event containing the model's response text. Redacted unless OTEL_LOG_ASSISTANT_RESPONSES=1; when that var is unset it follows OTEL_LOG_USER_PROMPTS, so deployments that already log prompt content will start receiving response content on upgrade — set OTEL_LOG_ASSISTANT_RESPONSES=0 to keep prompts-only.&lt;/p&gt;
&lt;p&gt;• Added live file path autocomplete to bash mode (!)&lt;/p&gt;
&lt;p&gt;• Added a startup notice when MCP servers need authentication, pointing at /mcp&lt;/p&gt;
&lt;p&gt;• Added automatic memory-pressure reaping for idle background shell commands (disable with CLAUDE_CODE_DISABLE_BG_SHELL_PRESSURE_REAP=1)&lt;/p&gt;
&lt;p&gt;• Fixed /model and other client-data-gated UI showing stale/empty state immediately after /login&lt;/p&gt;
&lt;p&gt;• Fixed backgrounding (←←) spuriously cancelling with "N background tasks would be abandoned" when all running tasks carry over to the new session&lt;/p&gt;
&lt;p&gt;• Fixed pinned background agents being re-prompted to "Continue from where you left off" after every auto-update&lt;/p&gt;
&lt;p&gt;• Fixed backgrounding the main turn spawning a phantom "general-purpose (resumed)" subagent that re-ran the main conversation&lt;/p&gt;
&lt;p&gt;• Fixed agent panel hiding sibling agents when viewing a subagent&lt;/p&gt;
&lt;p&gt;• Improved background agents: the launch result no longer instructs Claude to "end your response" — it keeps working on other tasks while the agent runs&lt;/p&gt;
&lt;p&gt;• Improved MCP headersHelper auth: the helper now re-runs and reconnects automatically when a tool call returns 401/403&lt;/p&gt;
&lt;p&gt;• Improved plugin auto-rename: marketplace renames maps are now followed automatically, updating your settings to the new name&lt;/p&gt;
&lt;p&gt;• Improved /add-dir message when the directory is already a working directory&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.191</id>
<title>Claude Code v2.1.191</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.191"/>
<updated>2026-06-24T21:58:06Z</updated>
<content type="html">&lt;p&gt;• Added /rewind support for resuming a conversation from before /clear was run&lt;/p&gt;
&lt;p&gt;• Fixed scroll position jumping to the bottom while reading earlier output during a streaming response&lt;/p&gt;
&lt;p&gt;• Fixed background agents resurrecting after being stopped — stopping an agent from the tasks panel is now permanent&lt;/p&gt;
&lt;p&gt;• Fixed /voice showing a generic "not available" message when disabled by an organization's policy — it now explains the restriction&lt;/p&gt;
&lt;p&gt;• Fixed /login URL opening truncated in Windows Terminal when it wraps across lines&lt;/p&gt;
&lt;p&gt;• Fixed Cmd+click on links in fullscreen mode for Ghostty over ssh/tmux&lt;/p&gt;
&lt;p&gt;• Fixed claude agents sending builtin slash commands like /usage to background sessions as prompt text instead of showing a hint&lt;/p&gt;
&lt;p&gt;• Fixed claude agents job rows showing full filesystem paths for pasted images instead of the [Image #N] placeholder&lt;/p&gt;
&lt;p&gt;• Fixed hooks with comma-separated matchers (e.g. "Bash,PowerShell") silently never firing&lt;/p&gt;
&lt;p&gt;• Fixed /permissions Recently-denied tab: approving a denial now persists on close instead of being silently discarded&lt;/p&gt;
&lt;p&gt;• Fixed the agent panel jumping by one row when scrolling the roster past the overflow cap&lt;/p&gt;
&lt;p&gt;• Fixed the welcome splash art overflowing the default 80×24 macOS Terminal window&lt;/p&gt;
&lt;p&gt;• Fixed managed settings: forceRemoteSettingsRefresh now takes effect when set via MDM or file policy, and the fetch sends Cache-Control: no-cache to prevent proxies from serving stale responses&lt;/p&gt;
&lt;p&gt;• Improved sandbox network permission dialog: hosts you allow with "Yes" are now remembered for the rest of the session instead of re-prompting on every connection&lt;/p&gt;
&lt;p&gt;• Improved MCP server reliability: capability discovery (tools/list, prompts/list, resources/list) now retries transient network errors with short backoff&lt;/p&gt;
&lt;p&gt;• Improved MCP OAuth: discovery and token requests now retry once after transient network errors, and headless environments skip the browser popup and go straight to the paste-the-URL prompt&lt;/p&gt;
&lt;p&gt;• Improved MCP error messages: HTTP 404 errors now show the URL and point to your MCP config&lt;/p&gt;
&lt;p&gt;• Improved vim mode prompt-history search (NORMAL /) to hint how to reach slash commands&lt;/p&gt;
&lt;p&gt;• Reduced CPU usage during streaming responses by ~37% by coalescing text updates to 100ms&lt;/p&gt;
&lt;p&gt;• Reduced long-session memory growth from terminal output cache&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.190</id>
<title>Claude Code v2.1.190</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.190"/>
<updated>2026-06-24T15:53:48Z</updated>
<content type="html">&lt;p&gt;• Bug fixes and reliability improvements&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.187</id>
<title>Claude Code v2.1.187</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.187"/>
<updated>2026-06-23T21:03:40Z</updated>
<content type="html">&lt;p&gt;• Added sandbox.credentials setting to block sandboxed commands from reading credential files and secret environment variables&lt;/p&gt;
&lt;p&gt;• Added org-configured model restrictions to the model picker, --model, /model, and ANTHROPIC_MODEL, with a "restricted by your organization's settings" message when a restricted model is selected&lt;/p&gt;
&lt;p&gt;• Added mouse click support to select menus (permission prompts, /model, /config, etc.) in fullscreen mode&lt;/p&gt;
&lt;p&gt;• Fixed --resume failing with "No conversation found" when the original -p run produced no model turns&lt;/p&gt;
&lt;p&gt;• Fixed --json-schema and workflow agent({schema}) structured output: the model can no longer re-call StructuredOutput indefinitely after a successful call, and follow-up turns now reliably return structured output&lt;/p&gt;
&lt;p&gt;• Fixed remote MCP tool calls that hang with no response for 5 minutes — they now abort with an error instead of blocking indefinitely (override with CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT)&lt;/p&gt;
&lt;p&gt;• Fixed Claude Code Remote sessions taking ~2.7s longer to start after the agent proxy CA system-trust install was added&lt;/p&gt;
&lt;p&gt;• Fixed pasted Korean/CJK text turning into mojibake in terminals that deliver paste as per-byte extended-key events&lt;/p&gt;
&lt;p&gt;• Fixed /update over Remote Control hanging when a startup trust dialog would have shown&lt;/p&gt;
&lt;p&gt;• Fixed background jobs in the agents view getting stuck in "working" indefinitely when the agent ended a turn without producing structured output&lt;/p&gt;
&lt;p&gt;• Fixed channel connections dropping after navigating to the agents view and back, and after /bg, /tui, or /update&lt;/p&gt;
&lt;p&gt;• Fixed agent stop notifications not correctly attributing who stopped the agent, and improved wording ("finished"/"stopped" instead of "came to rest")&lt;/p&gt;
&lt;p&gt;• Fixed subagent depth tracking: resumed subagents now restore their original spawn depth, and forked subagents now count toward the depth cap&lt;/p&gt;
&lt;p&gt;• Fixed leaked agent worktree registrations: locked .git/worktrees/ entries from killed agents are now cleaned up automatically&lt;/p&gt;
&lt;p&gt;• Fixed Cmd+click not opening URLs in fullscreen mode in Ghostty on macOS&lt;/p&gt;
&lt;p&gt;• Fixed claude --help not listing the --bg/--background flag&lt;/p&gt;
&lt;p&gt;• Fixed Esc, Ctrl-C, and Ctrl-D not working while /share is uploading&lt;/p&gt;
&lt;p&gt;• Improved /install-github-app: GitHub Actions workflow setup is now optional — you can install just the GitHub App and skip the workflow/secret steps&lt;/p&gt;
&lt;p&gt;• Improved /btw with ←/→ arrow navigation to step through earlier answers&lt;/p&gt;
&lt;p&gt;• Improved /plugin to surface plugins you haven't used recently so you can clean them up&lt;/p&gt;
&lt;p&gt;• [VSCode] Fixed extension becoming unresponsive when resuming a large session&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.186</id>
<title>Claude Code v2.1.186</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.186"/>
<updated>2026-06-22T20:37:26Z</updated>
<content type="html">&lt;p&gt;• Added claude mcp login &amp;lt;name&amp;gt; and claude mcp logout &amp;lt;name&amp;gt; to authenticate MCP servers from the CLI without opening the interactive /mcp menu, with --no-browser stdin redirect support for completing over SSH&lt;/p&gt;
&lt;p&gt;• Added status filtering (press f) to the /workflows agent detail view&lt;/p&gt;
&lt;p&gt;• Added a "Skills" section to the /plugin Installed tab&lt;/p&gt;
&lt;p&gt;• Added teammateMode: "iterm2" setting with a warning when auto mode cannot find the it2 CLI&lt;/p&gt;
&lt;p&gt;• Added "Claude Platform on AWS - refresh credentials" option to /login when awsAuthRefresh is configured&lt;/p&gt;
&lt;p&gt;• ! bash commands now trigger Claude to respond to the output automatically; set "respondToBashCommands": false in settings.json to keep the previous context-only behavior&lt;/p&gt;
&lt;p&gt;• Fixed streaming requests failing with "Content block not found" or JSON parse errors after the machine wakes from sleep&lt;/p&gt;
&lt;p&gt;• Fixed subagent transcript scroll position bleeding into the main transcript on exit&lt;/p&gt;
&lt;p&gt;• Fixed background task previews flashing raw tool names before the agent's plan loaded&lt;/p&gt;
&lt;p&gt;• Fixed Chrome tab-group isolation not applying when the in-product permissions gate is off for concurrent CLI sessions&lt;/p&gt;
&lt;p&gt;• Fixed background session recaps being duplicated; the agent's own end-of-turn summary now shows as the recap line&lt;/p&gt;
&lt;p&gt;• Fixed opening a background session from claude agents leaving the previous screen painted behind it&lt;/p&gt;
&lt;p&gt;• Fixed Agent(type) deny rules and Agent(x,y) allowed-types restrictions not being enforced for named subagent spawns&lt;/p&gt;
&lt;p&gt;• Fixed Esc and Ctrl+C not responding while background agents are still running after the main turn ends&lt;/p&gt;
&lt;p&gt;• Fixed misaligned option numbers in permission prompts when the option text overflows&lt;/p&gt;
&lt;p&gt;• Fixed pressing x on a finished subagent in the agent panel not dismissing it&lt;/p&gt;
&lt;p&gt;• Fixed a misleading "MCP server disconnected" notice for intentionally retired tools when resuming older sessions&lt;/p&gt;
&lt;p&gt;• Fixed /plugin Installed showing a "more above" indicator when already scrolled to the top&lt;/p&gt;
&lt;p&gt;• Fixed ~~strikethrough~~ showing literal tildes in assistant messages instead of rendering as strikethrough&lt;/p&gt;
&lt;p&gt;• Fixed --tools allowing feature-gated tools to slip through before flags loaded on a cold first launch&lt;/p&gt;
&lt;p&gt;• Fixed background job status in claude agents showing a stale "needs input" message after replying&lt;/p&gt;
&lt;p&gt;• Fixed a dark-theme flash when opening a background session from claude agents on a light terminal&lt;/p&gt;
&lt;p&gt;• Fixed mouse-selected text staying highlighted after deleting it in claude agents&lt;/p&gt;
&lt;p&gt;• Fixed session cost not showing for usage-based Enterprise and Team subscribers&lt;/p&gt;
&lt;p&gt;• Fixed agent teams: teammates spawned via tmux/pane backends now inherit the leader's --effort level&lt;/p&gt;
&lt;p&gt;• Fixed Workflow agent({schema}) subagents looping forever on repeated schema validation failures instead of aborting after 5 attempts&lt;/p&gt;
&lt;p&gt;• Improved claude mcp get and claude mcp remove to suggest the closest configured server name on a typo and truncate long server lists&lt;/p&gt;
&lt;p&gt;• Improved memory: the agent is now reminded to compact its MEMORY.md index when nearing the size limit&lt;/p&gt;
&lt;p&gt;• Improved skill frontmatter: display-name, default-enabled, fallback, and metadata.* keys now accept kebab-case, snake_case, and camelCase&lt;/p&gt;
&lt;p&gt;• Improved malformed SKILL.md YAML frontmatter handling: loads the skill body with empty metadata instead of failing silently&lt;/p&gt;
&lt;p&gt;• Changed CLAUDE_CODE_MAX_RETRIES to cap at 15; for unattended sessions, use CLAUDE_CODE_RETRY_WATCHDOG instead&lt;/p&gt;
&lt;p&gt;• Changed background subagents to surface permission prompts in the main session instead of auto-denying; the dialog shows which agent is asking, and Esc denies just that tool&lt;/p&gt;
&lt;p&gt;• Changed /review &amp;lt;pr&amp;gt; to use the same review engine as /code-review medium&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.185</id>
<title>Claude Code v2.1.185</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.185"/>
<updated>2026-06-20T20:59:12Z</updated>
<content type="html">&lt;p&gt;• The stream-stall hint now reads "Waiting for API response · will retry in …" instead of "No response from API · Retrying in …", and triggers after 20s of silence instead of 10s&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.183</id>
<title>Claude Code v2.1.183</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.183"/>
<updated>2026-06-19T01:20:44Z</updated>
<content type="html">&lt;p&gt;• Improved auto mode safety: destructive git commands (git reset --hard, git checkout -- ., git clean -fd, git stash drop) are now blocked when you didn't ask to discard local work, git commit --amend is blocked when the commit wasn't made by the agent this session, and terraform destroy/pulumi destroy/cdk destroy are blocked unless you asked for the specific stack&lt;/p&gt;
&lt;p&gt;• Added a warning when the requested model is deprecated or automatically updated to a newer model, shown on stderr in print mode (-p) and now also covering models set in agent frontmatter&lt;/p&gt;
&lt;p&gt;• Added attribution.sessionUrl setting to omit the claude.ai session link from commits and PRs in web and Remote Control sessions&lt;/p&gt;
&lt;p&gt;• Added /config --help to list all available shorthand keys for /config key=value&lt;/p&gt;
&lt;p&gt;• Changed /config toggle behavior: Enter and Space both change the selected setting, and Esc now saves and closes instead of reverting&lt;/p&gt;
&lt;p&gt;• Removed the startup "setup issues" line under the logo — run /doctor to see configuration issues or use --debug&lt;/p&gt;
&lt;p&gt;• Fixed thinking.disabled.display: Extra inputs are not permitted 400 errors on subagent spawns and session-title generation for affected configurations&lt;/p&gt;
&lt;p&gt;• Fixed WebSearch returning empty results in subagents&lt;/p&gt;
&lt;p&gt;• Fixed the terminal cursor being stranded above the prompt after navigating history in vim mode with the native cursor enabled&lt;/p&gt;
&lt;p&gt;• Fixed fullscreen TUI corruption (statusline mid-screen, duplicated spinner rows, merged text) in Windows Terminal under heavy nested-subagent load&lt;/p&gt;
&lt;p&gt;• Fixed turns silently completing with no visible output when the model returned only a thinking block; Claude now re-prompts once&lt;/p&gt;
&lt;p&gt;• Fixed user-level skills appearing multiple times in slash-command autocomplete when multiple plugins are enabled&lt;/p&gt;
&lt;p&gt;• Fixed MCP servers requiring authentication exposing auth-stub tools to the model in headless/SDK mode&lt;/p&gt;
&lt;p&gt;• Fixed tmux teammate panes failing to launch when the shell has slow rc-file initialization, and keystrokes typed during agent spawn leaking into the new tmux pane instead of the leader prompt&lt;/p&gt;
&lt;p&gt;• Fixed background tasks started by a teammate being killed when the teammate finishes a turn&lt;/p&gt;
&lt;p&gt;• Fixed scheduled task and webhook trigger deliveries being treated as keyboard input; they now classify as task notifications and can no longer approve a pending action or set the session title in auto mode&lt;/p&gt;
&lt;p&gt;• Fixed focus mode showing "Ran N PostToolUse hooks" timing lines under each response&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.181</id>
<title>Claude Code v2.1.181</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.181"/>
<updated>2026-06-17T22:07:34Z</updated>
<content type="html">&lt;p&gt;• Added /config key=value syntax to set any setting from the prompt (e.g. /config thinking=false) — works in interactive, -p, and Remote Control&lt;/p&gt;
&lt;p&gt;• Added sandbox.allowAppleEvents opt-in setting that lets sandboxed commands send Apple Events on macOS&lt;/p&gt;
&lt;p&gt;• Added CLAUDE_CLIENT_PRESENCE_FILE environment variable: point it at a marker file to suppress mobile push notifications while you're at the machine&lt;/p&gt;
&lt;p&gt;• Upgraded the bundled Bun runtime to 1.4&lt;/p&gt;
&lt;p&gt;• Improved streaming of long paragraphs: text now appears line-by-line instead of waiting for the first line break&lt;/p&gt;
&lt;p&gt;• Improved auto-retry: API connection drops mid-thinking now automatically retry instead of showing "Connection closed while thinking"&lt;/p&gt;
&lt;p&gt;• Improved the subagent panel: idle subagents auto-hide after 30s, the list caps at 5 rows with scroll hints, and keyboard hints now show in the footer&lt;/p&gt;
&lt;p&gt;• Improved the MCP OAuth browser page to match Claude Code's visual style and auto-close on success&lt;/p&gt;
&lt;p&gt;• Changed fullscreen mode URL opening to require Cmd+click (macOS) / Ctrl+click, matching native terminal behavior&lt;/p&gt;
&lt;p&gt;• Changed the Improved N memories line to no longer list individual files outside verbose mode&lt;/p&gt;
&lt;p&gt;• Fixed prompt caching not reading on custom ANTHROPIC_BASE_URL and on Foundry due to a per-request attestation token changing every turn&lt;/p&gt;
&lt;p&gt;• Fixed Write/Edit producing 0-byte or truncated files on network drives and cloud-synced folders&lt;/p&gt;
&lt;p&gt;• Fixed open, osascript, and browser-based auth flows failing with error -600 on macOS by adding the Apple Events entitlement&lt;/p&gt;
&lt;p&gt;• Fixed a startup regression (~120ms per launch in fresh environments, introduced in 2.1.169): the first prompt no longer waits for the managed-settings fetch when no MCP servers are configured&lt;/p&gt;
&lt;p&gt;• Fixed startup blocking with a blank terminal for up to 15 seconds when the account settings fetch is slow on a degraded network&lt;/p&gt;
&lt;p&gt;• Fixed startup crash (TypeError: Cannot read properties of null) when .claude.json contains corrupted null project entries&lt;/p&gt;
&lt;p&gt;• Fixed macOS TUI freezing at session start (Ctrl+C unresponsive) when Spotlight is busy reindexing&lt;/p&gt;
&lt;p&gt;• Fixed long-running idle sessions losing their history when another Claude Code process ran the 30-day transcript cleanup&lt;/p&gt;
&lt;p&gt;• Fixed foreground subagents spawning unbounded nested chains; they now respect the same 5-level depth limit as background subagents&lt;/p&gt;
&lt;p&gt;• Fixed /recap and conversation forks using the previous model immediately after a model switch&lt;/p&gt;
&lt;p&gt;• Fixed subagent "Thinking" duration showing the parent agent's elapsed time instead of the subagent's own&lt;/p&gt;
&lt;p&gt;• Fixed subagents blocked on a nested agent showing a ticking elapsed time instead of "waiting" in the agent panel&lt;/p&gt;
&lt;p&gt;• Fixed the API retry indicator ("Retrying in 0s · attempt N/10") staying on screen after the retry succeeded&lt;/p&gt;
&lt;p&gt;• Fixed AWS awsCredentialExport credentials with a short remaining lifetime causing credential refreshes every minute, and now accepts the JSON shape from aws configure export-credentials&lt;/p&gt;
&lt;p&gt;• Fixed claude mcp get/list showing ✓ Connected when tools/list fails; they now show ! Connected · tools fetch failed with the error detail&lt;/p&gt;
&lt;p&gt;• Fixed /remote-control leaving a stale "connecting…" line; it now confirms in the transcript once connected&lt;/p&gt;
&lt;p&gt;• Fixed ExitWorktree refusing to remove a clean worktree with "Could not verify worktree state" when bare git cannot be resolved on Windows&lt;/p&gt;
&lt;p&gt;• Fixed settings changes (such as /effort or /model) failing with ENOENT when ~/.claude/settings.json is a relative symlink under a symlinked ~/.claude&lt;/p&gt;
&lt;p&gt;• Fixed IDE selection line numbers in context reminders being off by one (IntelliJ and VS Code)&lt;/p&gt;
&lt;p&gt;• Fixed Ctrl+C in fullscreen after a native terminal selection (modifier+drag) overwriting the clipboard with the app's prior selection&lt;/p&gt;
&lt;p&gt;• Fixed Ctrl+V showing "No image found in clipboard" instead of pasting when the clipboard contains text&lt;/p&gt;
&lt;p&gt;• Fixed agent creation failing with "EEXIST: file already exists" when the agents directory already exists (Windows/OneDrive)&lt;/p&gt;
&lt;p&gt;• Fixed AskUserQuestion preview content being cut off at the dialog edge instead of word-wrapping&lt;/p&gt;
&lt;p&gt;• Fixed AskUserQuestion multi-select questions silently dropping a typed "Other" free-text answer when submitting&lt;/p&gt;
&lt;p&gt;• Fixed /stats "Most active day" and daily token chart dates showing one day early in UTC-negative timezones&lt;/p&gt;
&lt;p&gt;• Fixed /copy and copy-on-select on Linux not detecting a clipboard utility installed after Claude Code started&lt;/p&gt;
&lt;p&gt;• Fixed tab-indented code rendering with incorrect indentation in the Write (create-file) preview&lt;/p&gt;
&lt;p&gt;• Fixed user prompts queued mid-turn not showing a full-width background highlight in the transcript&lt;/p&gt;
&lt;p&gt;• Fixed the activity spinner's pulse dwelling on the wrong glyph size in Ghostty&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.179</id>
<title>Claude Code v2.1.179</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.179"/>
<updated>2026-06-16T20:22:06Z</updated>
<content type="html">&lt;p&gt;• Fixed mid-stream connection drops: partial responses are now preserved instead of showing a raw error, and the spinner no longer gets stuck at "running tool"&lt;/p&gt;
&lt;p&gt;• Fixed mouse-wheel scrolling in WSL2 under Windows Terminal and VS Code (regression in 2.1.172)&lt;/p&gt;
&lt;p&gt;• Fixed a sandbox denyRead/allowRead glob over a large directory tree making the Bash tool description enormous and the session unusable on Linux&lt;/p&gt;
&lt;p&gt;• Fixed the feedback survey capturing a single-digit reply as a session rating immediately after a turn completes&lt;/p&gt;
&lt;p&gt;• Fixed the welcome screen stacking multiple promotional banners — at most one promo now shows per session&lt;/p&gt;
&lt;p&gt;• Fixed Ctrl+O not showing the subagent's transcript when viewing a subagent&lt;/p&gt;
&lt;p&gt;• Fixed clicking the prompt input not returning focus from the subagent/footer panel&lt;/p&gt;
&lt;p&gt;• Fixed remote session background tasks appearing stuck as "still running" between turns&lt;/p&gt;
&lt;p&gt;• Improved plugin loading performance in remote sessions&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.178</id>
<title>Claude Code v2.1.178</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.178"/>
<updated>2026-06-15T21:35:48Z</updated>
<content type="html">&lt;p&gt;• Agent teams: removed the TeamCreate and TeamDelete tools. With CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 set, every session now has one implicit team — spawn teammates directly with the Agent tool's name parameter, no setup step needed. The team_name parameter on the Agent tool is still accepted but ignored.&lt;/p&gt;
&lt;p&gt;• Added Tool(param:value) syntax for permission rules to match a tool's input parameters (with * wildcard), e.g. Agent(model:opus) to block Opus subagents&lt;/p&gt;
&lt;p&gt;• Skills in nested .claude/skills directories now load when working on files there; on a name clash, the nested skill appears as &amp;lt;dir&amp;gt;:&amp;lt;name&amp;gt; so both stay available&lt;/p&gt;
&lt;p&gt;• Nested .claude/ directories: the agent, workflow, and output-style closest to the working directory now wins when names collide; project-scope workflow saves now target the closest existing .claude/workflows/&lt;/p&gt;
&lt;p&gt;• Improved auto mode: subagent spawns are now evaluated by the classifier before launch, closing a gap where a subagent could request a blocked action without review&lt;/p&gt;
&lt;p&gt;• Improved /doctor with consistent flat tree layout across all sections, clearer section status icons, and highlighted command names&lt;/p&gt;
&lt;p&gt;• Improved the skill listing truncation warning to show how many skill descriptions are affected&lt;/p&gt;
&lt;p&gt;• Changed the workflow prompt keyword to use a purple shimmer highlight and trigger only on explicit phrases like "run a workflow" or "workflow:", not on any mention of the word&lt;/p&gt;
&lt;p&gt;• Improved Remote Control error messages: connection failures now show a persistent red "/rc failed" indicator in the footer, and the "not yet enabled" error now explains whether it's a gate, a check failure, stale entitlement, or org policy&lt;/p&gt;
&lt;p&gt;• /bug now requires a description before submitting, and no longer uses model-refusal text as the GitHub issue title&lt;/p&gt;
&lt;p&gt;• Fixed a crash (out-of-memory) when the CLI inherits a stale websocket/OAuth file-descriptor environment variable from a parent process&lt;/p&gt;
&lt;p&gt;• Fixed Claude in Chrome silently failing to connect when the OAuth token belongs to a different account than the Claude Code login&lt;/p&gt;
&lt;p&gt;• Fixed nested .claude/skills skills with directory-qualified names being blocked by permission prompts in non-interactive runs&lt;/p&gt;
&lt;p&gt;• Fixed several subagent issues: viewing a subagent's transcript now shows tool results and live progress, messages sent while it finishes its turn are no longer dropped, and backgrounding a running subagent (ctrl+b) no longer restarts it from scratch&lt;/p&gt;
&lt;p&gt;• Fixed claude agents workers failing with 401 Invalid bearer token when the daemon was started from a shell with a custom API gateway via ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN&lt;/p&gt;
&lt;p&gt;• Fixed compaction not honoring --fallback-model: compaction now falls back to the configured fallback model chain on overload or model-availability errors&lt;/p&gt;
&lt;p&gt;• Fixed model requests continuing to fail with auth errors after credentials were refreshed outside the session, due to a stale cached request configuration&lt;/p&gt;
&lt;p&gt;• Fixed background sessions created with /bg or ←← after a turn finished showing "Working" forever in the agents list&lt;/p&gt;
&lt;p&gt;• Fixed Linux sandbox failing to start when .claude/skills or .claude/hooks is a symlink&lt;/p&gt;
&lt;p&gt;• Fixed CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE=1 preventing fresh marketplace installs from cloning&lt;/p&gt;
&lt;p&gt;• Fixed MCP server-level specs (mcp__server, mcp__server__*, mcp__*) in subagent disallowedTools being silently ignored&lt;/p&gt;
&lt;p&gt;• Fixed vim mode undo: u now steps through NORMAL/VISUAL-mode commands one at a time instead of merging commands in quick succession into a single undo step&lt;/p&gt;
&lt;p&gt;• Fixed statusline links with custom URI schemes (e.g. vscode://) not opening when clicked in claude agents&lt;/p&gt;
&lt;p&gt;• [VSCode] Fixed pressing Esc to dismiss a CJK IME candidate window canceling the running Claude task&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.176</id>
<title>Claude Code v2.1.176</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.176"/>
<updated>2026-06-12T21:53:21Z</updated>
<content type="html">&lt;p&gt;• Session titles are now generated in the language of your conversation (set the language setting to pin a specific language)&lt;/p&gt;
&lt;p&gt;• Added footerLinksRegexes setting for regex-matched link badges in the footer row, configurable via user or managed settings&lt;/p&gt;
&lt;p&gt;• Improved Bedrock credential caching: credentials from awsCredentialExport are now cached until their Expiration instead of a fixed 1 hour&lt;/p&gt;
&lt;p&gt;• Fixed availableModels enforcement: alias model picks can no longer be redirected to a blocked model via ANTHROPIC_DEFAULT_*_MODEL environment variables, and /fast now refuses to toggle when it would switch to a model outside the allowlist&lt;/p&gt;
&lt;p&gt;• Fixed auto mode failing on Fable 5 for organizations without Opus 4.8 enabled — the classifier now falls back to the best available Opus model&lt;/p&gt;
&lt;p&gt;• Fixed hook if conditions for Read/Edit/Write tool paths: documented patterns like Edit(src/), Read(~/.ssh/), and Read(.env) now match correctly&lt;/p&gt;
&lt;p&gt;• Fixed Linux sandbox failing to start when .claude/settings.json is a symlink with an absolute target&lt;/p&gt;
&lt;p&gt;• Fixed /copy and mouse-selection copy not reaching the system clipboard inside tmux over SSH, and tmux paste buffer not loading on versions older than 3.2&lt;/p&gt;
&lt;p&gt;• Fixed Remote Control connecting from web/mobile silently switching the session's model&lt;/p&gt;
&lt;p&gt;• Fixed Remote Control disconnect notifications showing a bare numeric code instead of a human-readable reason, and connection failures adding a duplicate line to the conversation transcript&lt;/p&gt;
&lt;p&gt;• Fixed Remote Control sessions not disconnecting when you sign in to a different account&lt;/p&gt;
&lt;p&gt;• Fixed /cd and worktree moves leaving the session reporting the previous directory's git branch&lt;/p&gt;
&lt;p&gt;• Fixed claude agents: pressing back in one window no longer detaches other windows attached to the same session&lt;/p&gt;
&lt;p&gt;• Fixed backgrounded sessions showing "Working" forever when /bg mid-turn had nothing left to continue&lt;/p&gt;
&lt;p&gt;• Fixed background agent search by PR URL: PRs opened during scheduled wakeups or while a job was blocked now appear in claude agents search&lt;/p&gt;
&lt;p&gt;• Fixed the agents view input showing no text cursor on Windows&lt;/p&gt;
&lt;p&gt;• Fixed claude --bg -cn &amp;lt;name&amp;gt; not seeding the session name&lt;/p&gt;
&lt;p&gt;• Fixed background sessions to neutralize Windows network paths in persisted state before respawn&lt;/p&gt;
&lt;p&gt;• Fixed background-session respawn rejecting malformed resume IDs from corrupted state files&lt;/p&gt;
&lt;p&gt;• Fixed the Windows background-service daemon not starting when ~/.claude/daemon has the ReadOnly attribute set&lt;/p&gt;
&lt;p&gt;• Fixed cloud sessions failing with "Could not resolve authentication method" when idle for too long before being claimed&lt;/p&gt;
&lt;p&gt;• Background sessions now show clearer guidance when a window left open across an auto-update can't submit a reply, and claude daemon status explains version-skew behavior&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.175</id>
<title>Claude Code v2.1.175</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.175"/>
<updated>2026-06-12T04:23:45Z</updated>
<content type="html">&lt;p&gt;• Added enforceAvailableModels managed setting — when enabled, the availableModels allowlist also constrains the Default model (a Default that would resolve to a disallowed model now falls back to the first allowed model), and user or project settings can no longer widen a managed availableModels list&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.174</id>
<title>Claude Code v2.1.174</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.174"/>
<updated>2026-06-12T01:16:30Z</updated>
<content type="html">&lt;p&gt;• Added wheelScrollAccelerationEnabled setting to disable mouse-wheel scroll acceleration in fullscreen mode&lt;/p&gt;
&lt;p&gt;• Fixed the /model picker hiding the model family that Default resolves to — Opus now appears as its own row on Max/Team Premium/Enterprise plans, Sonnet on Pro/Team plans, and Opus on pay-as-you-go API accounts&lt;/p&gt;
&lt;p&gt;• Fixed /model picker showing a hardcoded Sonnet version label when ANTHROPIC_DEFAULT_SONNET_MODEL pins a different Sonnet&lt;/p&gt;
&lt;p&gt;• Fixed the "Fable 5 is now consuming usage credits" banner incorrectly showing for enterprise accounts with usage-based billing&lt;/p&gt;
&lt;p&gt;• Fixed Bedrock GovCloud regions (us-gov-*) deriving the wrong inference profile prefix (global instead of us-gov), causing 400 errors on derived model IDs&lt;/p&gt;
&lt;p&gt;• Fixed background sessions inheriting another session's ANTHROPIC_* provider env (gateway URL, custom headers, /model aliases) from the shell that started the background daemon&lt;/p&gt;
&lt;p&gt;• Fixed a 1-2 second pause when exiting Claude Code shortly after a shell command was interrupted or killed on macOS and Linux&lt;/p&gt;
&lt;p&gt;• Fixed git commit co-author attribution showing an incorrect model name for some models&lt;/p&gt;
&lt;p&gt;• Fixed the /advisor dialog pre-selecting a saved advisor model that is blocked by the availableModels allowlist&lt;/p&gt;
&lt;p&gt;• Fixed skill hot-reload re-sending the entire skill listing when a single skill changed; only changed skills are now re-announced&lt;/p&gt;
&lt;p&gt;• Fixed Workflow tool agent() subagents missing per-agent attribution headers&lt;/p&gt;
&lt;p&gt;• [VSCode] Added usage attribution to the Account &amp;amp; usage dialog (/usage) showing cache misses, long context, subagents, and per-skill/agent/plugin/MCP breakdowns over the last 24h or 7d&lt;/p&gt;
&lt;p&gt;• Fixed pre-warmed background workers failing with "Could not resolve authentication method" when claimed after sitting idle&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.173</id>
<title>Claude Code v2.1.173</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.173"/>
<updated>2026-06-11T05:41:48Z</updated>
<content type="html">&lt;p&gt;• Fixed Fable 5 model names with a [1m] suffix not being normalized — Fable 5 includes 1M context by default, so the suffix is now stripped automatically&lt;/p&gt;
&lt;p&gt;• Fixed a spurious "sandbox dependencies missing" startup warning on Windows when sandbox was enabled in settings&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.172</id>
<title>Claude Code v2.1.172</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.172"/>
<updated>2026-06-10T20:44:09Z</updated>
<content type="html">&lt;p&gt;• Sub-agents can now spawn their own sub-agents (up to 5 levels deep)&lt;/p&gt;
&lt;p&gt;• Amazon Bedrock now reads the AWS region from ~/.aws config files when AWS_REGION isn't set, matching AWS SDK precedence; /status shows where the region came from&lt;/p&gt;
&lt;p&gt;• Added a search bar when browsing a marketplace's plugins in /plugin&lt;/p&gt;
&lt;p&gt;• Added model attribute to the claude_code.lines_of_code.count OTEL metric&lt;/p&gt;
&lt;p&gt;• Fixed sessions using 1M context without usage credits getting permanently stuck — the session now automatically compacts back under the standard context limit&lt;/p&gt;
&lt;p&gt;• Fixed a repeating "an image in the conversation could not be processed and was removed" error when the conversation contained multiple images&lt;/p&gt;
&lt;p&gt;• Fixed the agents view keeping a session under Working with a busy spinner for up to 30 seconds after the worker replied&lt;/p&gt;
&lt;p&gt;• Fixed background agents potentially reading another directory's project settings (.mcp.json approvals, trust) when dispatched onto a pre-warmed worker&lt;/p&gt;
&lt;p&gt;• Fixed background-session attach failing with EAUTH for sessions started on an older version after the daemon auto-updated&lt;/p&gt;
&lt;p&gt;• Fixed a background sub-agent staying stuck as "active" in the agent panel after a nested agent it spawned was stopped&lt;/p&gt;
&lt;p&gt;• Fixed /model suggestions in the claude agents dispatch input rendering with a misleading slash prefix and showing models disabled for your org&lt;/p&gt;
&lt;p&gt;• Fixed availableModels restrictions not being applied to subagent model overrides, the agent dispatch model picker, and the advisor model&lt;/p&gt;
&lt;p&gt;• Fixed availableModels allowlists hiding the /model picker's Opus and Sonnet 1M rows when entries use version-specific IDs like claude-opus-4-8&lt;/p&gt;
&lt;p&gt;• Fixed the /model picker on Bedrock offering models the provider doesn't serve — selecting one silently switched the session model and lit the selection marker on multiple rows&lt;/p&gt;
&lt;p&gt;• Fixed model IDs getting a doubled 1M-context suffix (e.g. [1M][1m]) when ANTHROPIC_DEFAULT_OPUS_MODEL already includes one&lt;/p&gt;
&lt;p&gt;• Fixed opusplan model setting not shipping with 1M context in plan mode for entitled users; the opusplan[1m] workaround now also correctly switches to Opus in plan mode&lt;/p&gt;
&lt;p&gt;• Fixed WebFetch(domain:*.example.com) wildcard domain rules never matching subdomains in allow, deny, and ask position, and file permission rules with mid-pattern wildcards (e.g. Read(secrets-*/config.json)) being rejected at startup&lt;/p&gt;
&lt;p&gt;• Fixed up-arrow prompt history showing the main agent's prompts while a subagent's chat tab is open&lt;/p&gt;
&lt;p&gt;• Fixed memory recall not finding mounted team memory stores (CLAUDE_MEMORY_STORES) in remote sessions&lt;/p&gt;
&lt;p&gt;• Fixed workflow validation rejecting scripts whose prompt strings or comments merely mention Date.now()/Math.random()&lt;/p&gt;
&lt;p&gt;• Disable mouse tracking on Windows consoles that don't fully support it&lt;/p&gt;
&lt;p&gt;• Fixed the /plugin marketplace list losing its cursor after backing out of a long plugin list, and Esc from the plugin browser returning to the wrong tab&lt;/p&gt;
&lt;p&gt;• Improved performance in long conversations by removing redundant message normalization and avoiding full message-history transforms when streaming tool-use state is unchanged&lt;/p&gt;
&lt;p&gt;• Reduced idle CPU usage: /goal status chip no longer re-renders the terminal at 5 Hz while idle, and fewer UI re-renders while subagents run in parallel&lt;/p&gt;
&lt;p&gt;• Improved Claude in Chrome tool loading: browser tools now load in a single batched call instead of one per tool&lt;/p&gt;
&lt;p&gt;• Improved the non-interactive Usage Policy refusal message to suggest starting a new session or changing your model&lt;/p&gt;
&lt;p&gt;• /code-review now keeps the ultra option visible when you're not signed in to claude.ai, with an explanation that the cloud review requires a claude.ai account&lt;/p&gt;
&lt;p&gt;• Shortened the Remote Control footer indicator to "/rc active" and hid it on narrow terminals&lt;/p&gt;
&lt;p&gt;• Stopped promoting /loop in remote sessions, where pending loops don't keep the container alive&lt;/p&gt;
&lt;p&gt;• [VSCode] Fixed PowerShell tool calls rendering as raw JSON instead of a proper command display and permission dialog, and stripped ANSI escape codes from displayed shell output&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.170</id>
<title>Claude Code v2.1.170</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.170"/>
<updated>2026-06-09T17:23:03Z</updated>
<content type="html">&lt;p&gt;• Introducing Claude Fable 5: a Mythos-class model that weve made safe for general use. Fables capabilities exceed those of any model weve ever made generally available. Update to version 2.1.170 for access. https://www.anthropic.com/news/claude-fable-5-mythos-5&lt;/p&gt;
&lt;p&gt;• Fixed sessions not saving transcripts (and not appearing in --resume) when launched from the VS Code integrated terminal or any shell that inherited Claude Code environment variables.&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.169</id>
<title>Claude Code v2.1.169</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.169"/>
<updated>2026-06-08T21:57:10Z</updated>
<content type="html">&lt;p&gt;• Self-hosted runner: added a post-session lifecycle hook that runs after the session ends and before the workspace is deleted, so you can snapshot uncommitted work or export logs; also made the child-process SIGTERM→SIGKILL window configurable (default unchanged at 5s)&lt;/p&gt;
&lt;p&gt;• Added --safe-mode flag (and CLAUDE_CODE_SAFE_MODE) to start Claude Code with all customizations (CLAUDE.md, plugins, skills, hooks, MCP servers) disabled for troubleshooting&lt;/p&gt;
&lt;p&gt;• Added /cd command to move a session to a new working directory without breaking the prompt cache mid-session&lt;/p&gt;
&lt;p&gt;• Added a disableBundledSkills setting and CLAUDE_CODE_DISABLE_BUNDLED_SKILLS environment variable to hide bundled skills, workflows, and built-in slash commands from the model&lt;/p&gt;
&lt;p&gt;• Fixed Up/Down arrows jumping to command history past the wrapped rows of a long input line — they now move through each visual row first, and history recall enters at the near edge&lt;/p&gt;
&lt;p&gt;• Fixed enterprise managed MCP policies (allowedMcpServers/deniedMcpServers) not being enforced on reconnect, IDE-typed configs, --mcp-config servers during the first session after install, or before remote settings loaded; also fixed slow cold starts for orgs without remote settings&lt;/p&gt;
&lt;p&gt;• Fixed a ~30-50ms UI stall at the start of each turn for macOS users logged in with claude.ai credentials&lt;/p&gt;
&lt;p&gt;• Fixed claude -p being slow or appearing to hang on Windows while waiting for the slash-command/skill scan (regression in 2.1.161)&lt;/p&gt;
&lt;p&gt;• Fixed Remote Control getting stuck on "reconnecting" after resuming a session when an OAuth token refresh happened at the same time&lt;/p&gt;
&lt;p&gt;• Fixed Git Credential Manager's "Connect to GitHub" popup appearing on Windows at startup when background git commands ran without cached credentials&lt;/p&gt;
&lt;p&gt;• Fixed footer hints (e.g. "esc to interrupt") not showing for users with a custom statusline&lt;/p&gt;
&lt;p&gt;• Fixed stale permission and dialog prompts reappearing every time you reattached to a remote session whose worker had died while waiting on them&lt;/p&gt;
&lt;p&gt;• Fixed claude agents --json omitting blocked and just-dispatched background sessions; added --all to include completed sessions, plus new id and state fields&lt;/p&gt;
&lt;p&gt;• Fixed agents view leaving a stale/garbled frame after navigating back from an agent on WSL in Windows Terminal&lt;/p&gt;
&lt;p&gt;• Fixed background agents ignoring project-level settings env values (e.g. ANTHROPIC_MODEL) when dispatched onto a pre-warmed worker&lt;/p&gt;
&lt;p&gt;• Fixed MCPB plugin cache being spuriously invalidated on Windows, causing unnecessary re-extraction&lt;/p&gt;
&lt;p&gt;• Fixed plugin .in_use PID lock files accumulating without bound; stale markers from crashed sessions are now swept once per day&lt;/p&gt;
&lt;p&gt;• Fixed untrusted project settings being able to set OTEL client-certificate paths without trust confirmation&lt;/p&gt;
&lt;p&gt;• /workflows now opens immediately even while a turn is in progress&lt;/p&gt;
&lt;p&gt;• Improved TaskCreate reliability: malformed inputs are repaired automatically and validation errors for unloaded tools include the schema&lt;/p&gt;
&lt;p&gt;• Improved the error message shown when your organization has disabled API key authentication, with guidance based on where the active API key comes from&lt;/p&gt;
&lt;p&gt;• Reduced CPU usage while responses stream and during spinner animations&lt;/p&gt;
&lt;p&gt;• Restored a default 5-minute idle timeout on Vertex/Foundry so a stalled stream aborts instead of hanging indefinitely; set API_FORCE_IDLE_TIMEOUT=0 to opt out&lt;/p&gt;
&lt;p&gt;• Remote-managed settings with an invalid entry now apply their remaining valid policies and surface the validation error, instead of silently dropping the whole payload&lt;/p&gt;
&lt;p&gt;• Background sessions now preserve --ide, --chrome, --bare, --remote-control, and other flags across retire→wake, and respawn state validation was hardened&lt;/p&gt;
&lt;p&gt;• Background sessions are now told that shared-checkout edits are blocked until they enter a worktree, avoiding a wasted rejected edit before EnterWorktree&lt;/p&gt;
&lt;p&gt;• The "CLAUDE.md is too long" warning threshold now scales with the model's context window&lt;/p&gt;
&lt;p&gt;• Auto-updater on Windows now stops retrying within a session once claude.exe is held by another process&lt;/p&gt;
&lt;p&gt;• Improved color contrast for skill tags in the slash-command menu&lt;/p&gt;
&lt;p&gt;• Promo credit claims for Apple/Google-billed subscribers without a payment method now explain where to add one&lt;/p&gt;
&lt;p&gt;• Added a tip suggesting claude agents when running multiple concurrent sessions&lt;/p&gt;</content>
</entry>
<entry>
<id>https://github.com/anthropics/claude-code/releases/tag/v2.1.168</id>
<title>Claude Code v2.1.168</title>
<link rel="alternate" type="text/html" href="https://github.com/anthropics/claude-code/releases/tag/v2.1.168"/>
<updated>2026-06-06T23:41:47Z</updated>
<content type="html">&lt;p&gt;• Bug fixes and reliability improvements&lt;/p&gt;</content>
</entry>
</feed>
+20 -46
View File
@@ -10,50 +10,21 @@ Learn more in the [official plugins documentation](https://docs.claude.com/en/do
## Plugins in This Directory
### [agent-sdk-dev](./agent-sdk-dev/)
**Claude Agent SDK Development Plugin**
Streamlines the development of Claude Agent SDK applications with scaffolding commands and verification agents.
- **Command**: `/new-sdk-app` - Interactive setup for new Agent SDK projects
- **Agents**: `agent-sdk-verifier-py` and `agent-sdk-verifier-ts` - Validate SDK applications against best practices
- **Use case**: Creating and verifying Claude Agent SDK applications in Python or TypeScript
### [commit-commands](./commit-commands/)
**Git Workflow Automation Plugin**
Simplifies common git operations with streamlined commands for committing, pushing, and creating pull requests.
- **Commands**:
- `/commit` - Create a git commit with appropriate message
- `/commit-push-pr` - Commit, push, and create a PR in one command
- `/clean_gone` - Clean up stale local branches marked as [gone]
- **Use case**: Faster git workflows with less context switching
### [code-review](./code-review/)
**Automated Pull Request Code Review Plugin**
Provides automated code review for pull requests using multiple specialized agents with confidence-based scoring to filter false positives.
- **Command**:
- `/code-review` - Automated PR review workflow
- **Use case**: Automated code review on pull requests with high-confidence issue detection (threshold ≥80)
### [feature-dev](./feature-dev/)
**Comprehensive Feature Development Workflow Plugin**
Provides a structured 7-phase approach to feature development with specialized agents for exploration, architecture, and review.
- **Command**: `/feature-dev` - Guided feature development workflow
- **Agents**:
- `code-explorer` - Deeply analyzes existing codebase features
- `code-architect` - Designs feature architectures and implementation blueprints
- `code-reviewer` - Reviews code for bugs, quality issues, and project conventions
- **Use case**: Building new features with systematic codebase understanding and quality assurance
| Name | Description | Contents |
|------|-------------|----------|
| [agent-sdk-dev](./agent-sdk-dev/) | Development kit for working with the Claude Agent SDK | **Command:** `/new-sdk-app` - Interactive setup for new Agent SDK projects<br>**Agents:** `agent-sdk-verifier-py`, `agent-sdk-verifier-ts` - Validate SDK applications against best practices |
| [claude-opus-4-5-migration](./claude-opus-4-5-migration/) | Migrate code and prompts from Sonnet 4.x and Opus 4.1 to Opus 4.5 | **Skill:** `claude-opus-4-5-migration` - Automated migration of model strings, beta headers, and prompt adjustments |
| [code-review](./code-review/) | Automated PR code review using multiple specialized agents with confidence-based scoring to filter false positives | **Command:** `/code-review` - Automated PR review workflow<br>**Agents:** 5 parallel Sonnet agents for CLAUDE.md compliance, bug detection, historical context, PR history, and code comments |
| [commit-commands](./commit-commands/) | Git workflow automation for committing, pushing, and creating pull requests | **Commands:** `/commit`, `/commit-push-pr`, `/clean_gone` - Streamlined git operations |
| [explanatory-output-style](./explanatory-output-style/) | Adds educational insights about implementation choices and codebase patterns (mimics the deprecated Explanatory output style) | **Hook:** SessionStart - Injects educational context at the start of each session |
| [feature-dev](./feature-dev/) | Comprehensive feature development workflow with a structured 7-phase approach | **Command:** `/feature-dev` - Guided feature development workflow<br>**Agents:** `code-explorer`, `code-architect`, `code-reviewer` - For codebase analysis, architecture design, and quality review |
| [frontend-design](./frontend-design/) | Create distinctive, production-grade frontend interfaces that avoid generic AI aesthetics | **Skill:** `frontend-design` - Auto-invoked for frontend work, providing guidance on bold design choices, typography, animations, and visual details |
| [hookify](./hookify/) | Easily create custom hooks to prevent unwanted behaviors by analyzing conversation patterns or explicit instructions | **Commands:** `/hookify`, `/hookify:list`, `/hookify:configure`, `/hookify:help`<br>**Agent:** `conversation-analyzer` - Analyzes conversations for problematic behaviors<br>**Skill:** `writing-rules` - Guidance on hookify rule syntax |
| [learning-output-style](./learning-output-style/) | Interactive learning mode that requests meaningful code contributions at decision points (mimics the unshipped Learning output style) | **Hook:** SessionStart - Encourages users to write meaningful code (5-10 lines) at decision points while receiving educational insights |
| [plugin-dev](./plugin-dev/) | Comprehensive toolkit for developing Claude Code plugins with 7 expert skills and AI-assisted creation | **Command:** `/plugin-dev:create-plugin` - 8-phase guided workflow for building plugins<br>**Agents:** `agent-creator`, `plugin-validator`, `skill-reviewer`<br>**Skills:** Hook development, MCP integration, plugin structure, settings, commands, agents, and skill development |
| [pr-review-toolkit](./pr-review-toolkit/) | Comprehensive PR review agents specializing in comments, tests, error handling, type design, code quality, and code simplification | **Command:** `/pr-review-toolkit:review-pr` - Run with optional review aspects (comments, tests, errors, types, code, simplify, all)<br>**Agents:** `comment-analyzer`, `pr-test-analyzer`, `silent-failure-hunter`, `type-design-analyzer`, `code-reviewer`, `code-simplifier` |
| [ralph-wiggum](./ralph-wiggum/) | Interactive self-referential AI loops for iterative development. Claude works on the same task repeatedly until completion | **Commands:** `/ralph-loop`, `/cancel-ralph` - Start/stop autonomous iteration loops<br>**Hook:** Stop - Intercepts exit attempts to continue iteration |
| [security-guidance](./security-guidance/) | Security reminder hook that warns about potential security issues when editing files | **Hook:** PreToolUse - Monitors 9 security patterns including command injection, XSS, eval usage, dangerous HTML, pickle deserialization, and os.system calls |
## Installation
@@ -81,8 +52,11 @@ Each plugin follows the standard Claude Code plugin structure:
plugin-name/
├── .claude-plugin/
│ └── plugin.json # Plugin metadata
├── commands/ # Slash commands (optional)
├── agents/ # Specialized agents (optional)
├── commands/ # Slash commands (optional)
├── agents/ # Specialized agents (optional)
├── skills/ # Agent Skills (optional)
├── hooks/ # Event handlers (optional)
├── .mcp.json # External tool configuration (optional)
└── README.md # Plugin documentation
```
@@ -0,0 +1,9 @@
{
"name": "claude-opus-4-5-migration",
"version": "1.0.0",
"description": "Migrate your code and prompts from Sonnet 4.x and Opus 4.1 to Opus 4.5.",
"author": {
"name": "William Hu",
"email": "whu@anthropic.com"
}
}
@@ -0,0 +1,21 @@
# Claude Opus 4.5 Migration Plugin
Migrate your code and prompts from Sonnet 4.x and Opus 4.1 to Opus 4.5.
## Overview
This skill updates your code and prompts to be compatible with Opus 4.5. It automates the migration process, handling model strings, beta headers, and other configuration details. If you run into any issues with Opus 4.5 after migration, you can continue using this skill to adjust your prompts.
## Usage
```
"Migrate my codebase to Opus 4.5"
```
## Learn More
Refer to our [prompting guide](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-4-best-practices) for best practices on prompting Claude models.
## Authors
William Hu (whu@anthropic.com)
@@ -0,0 +1,105 @@
---
name: claude-opus-4-5-migration
description: Migrate prompts and code from Claude Sonnet 4.0, Sonnet 4.5, or Opus 4.1 to Opus 4.5. Use when the user wants to update their codebase, prompts, or API calls to use Opus 4.5. Handles model string updates and prompt adjustments for known Opus 4.5 behavioral differences. Does NOT migrate Haiku 4.5.
---
# Opus 4.5 Migration Guide
One-shot migration from Sonnet 4.0, Sonnet 4.5, or Opus 4.1 to Opus 4.5.
## Migration Workflow
1. Search codebase for model strings and API calls
2. Update model strings to Opus 4.5 (see platform-specific strings below)
3. Remove unsupported beta headers
4. Add effort parameter set to `"high"` (see `references/effort.md`)
5. Summarize all changes made
6. Tell the user: "If you encounter any issues with Opus 4.5, let me know and I can help adjust your prompts."
## Model String Updates
Identify which platform the codebase uses, then replace model strings accordingly.
### Unsupported Beta Headers
Remove the `context-1m-2025-08-07` beta header if present—it is not yet supported with Opus 4.5. Leave a comment noting this:
```python
# Note: 1M context beta (context-1m-2025-08-07) not yet supported with Opus 4.5
```
### Target Model Strings (Opus 4.5)
| Platform | Opus 4.5 Model String |
|----------|----------------------|
| Anthropic API (1P) | `claude-opus-4-5-20251101` |
| AWS Bedrock | `anthropic.claude-opus-4-5-20251101-v1:0` |
| Google Vertex AI | `claude-opus-4-5@20251101` |
| Azure AI Foundry | `claude-opus-4-5-20251101` |
### Source Model Strings to Replace
| Source Model | Anthropic API (1P) | AWS Bedrock | Google Vertex AI |
|--------------|-------------------|-------------|------------------|
| Sonnet 4.0 | `claude-sonnet-4-20250514` | `anthropic.claude-sonnet-4-20250514-v1:0` | `claude-sonnet-4@20250514` |
| Sonnet 4.5 | `claude-sonnet-4-5-20250929` | `anthropic.claude-sonnet-4-5-20250929-v1:0` | `claude-sonnet-4-5@20250929` |
| Opus 4.1 | `claude-opus-4-1-20250422` | `anthropic.claude-opus-4-1-20250422-v1:0` | `claude-opus-4-1@20250422` |
**Do NOT migrate**: Any Haiku models (e.g., `claude-haiku-4-5-20251001`).
## Prompt Adjustments
Opus 4.5 has known behavioral differences from previous models. **Only apply these fixes if the user explicitly requests them or reports a specific issue.** By default, just update model strings.
**Integration guidelines**: When adding snippets, don't just append them to prompts. Integrate them thoughtfully:
- Use XML tags (e.g., `<code_guidelines>`, `<tool_usage>`) to organize additions
- Match the style and structure of the existing prompt
- Place snippets in logical locations (e.g., coding guidelines near other coding instructions)
- If the prompt already uses XML tags, add new content within appropriate existing tags or create consistent new ones
### 1. Tool Overtriggering
Opus 4.5 is more responsive to system prompts. Aggressive language that prevented undertriggering on previous models may now cause overtriggering.
**Apply if**: User reports tools being called too frequently or unnecessarily.
**Find and soften**:
- `CRITICAL:` → remove or soften
- `You MUST...``You should...`
- `ALWAYS do X``Do X`
- `NEVER skip...``Don't skip...`
- `REQUIRED` → remove or soften
Only apply to tool-triggering instructions. Leave other uses of emphasis alone.
### 2. Over-Engineering Prevention
Opus 4.5 tends to create extra files, add unnecessary abstractions, or build unrequested flexibility.
**Apply if**: User reports unwanted files, excessive abstraction, or unrequested features. Add the snippet from `references/prompt-snippets.md`.
### 3. Code Exploration
Opus 4.5 can be overly conservative about exploring code, proposing solutions without reading files.
**Apply if**: User reports the model proposing fixes without inspecting relevant code. Add the snippet from `references/prompt-snippets.md`.
### 4. Frontend Design
**Apply if**: User requests improved frontend design quality or reports generic-looking outputs.
Add the frontend aesthetics snippet from `references/prompt-snippets.md`.
### 5. Thinking Sensitivity
When extended thinking is not enabled (the default), Opus 4.5 is particularly sensitive to the word "think" and its variants. Extended thinking is enabled only if the API request contains a `thinking` parameter.
**Apply if**: User reports issues related to "thinking" while extended thinking is not enabled (no `thinking` parameter in request).
Replace "think" with alternatives like "consider," "believe," or "evaluate."
## Reference
See `references/prompt-snippets.md` for the full text of each snippet to add.
See `references/effort.md` for configuring the effort parameter (only if user requests it).
@@ -0,0 +1,70 @@
# Effort Parameter (Beta)
**Add effort set to `"high"` during migration.** This is the default configuration for best performance with Opus 4.5.
## Overview
Effort controls how eagerly Claude spends tokens. It affects all tokens: thinking, text responses, and function calls.
| Effort | Use Case |
|--------|----------|
| `high` | Best performance, deep reasoning (default) |
| `medium` | Balance of cost/latency vs. performance |
| `low` | Simple, high-volume queries; significant token savings |
## Implementation
Requires beta flag `effort-2025-11-24` in API calls.
**Python SDK:**
```python
response = client.messages.create(
model="claude-opus-4-5-20251101",
max_tokens=1024,
betas=["effort-2025-11-24"],
output_config={
"effort": "high" # or "medium" or "low"
},
messages=[...]
)
```
**TypeScript SDK:**
```typescript
const response = await client.messages.create({
model: "claude-opus-4-5-20251101",
max_tokens: 1024,
betas: ["effort-2025-11-24"],
output_config: {
effort: "high" // or "medium" or "low"
},
messages: [...]
});
```
**Raw API:**
```json
{
"model": "claude-opus-4-5-20251101",
"max_tokens": 1024,
"anthropic-beta": "effort-2025-11-24",
"output_config": {
"effort": "high"
},
"messages": [...]
}
```
## Effort vs. Thinking Budget
Effort is independent of thinking budget:
- High effort + no thinking = more tokens, but no thinking tokens
- High effort + 32k thinking = more tokens, but thinking capped at 32k
## Recommendations
1. First determine effort level, then set thinking budget
2. Best performance: high effort + high thinking budget
3. Cost/latency optimization: medium effort
4. Simple high-volume queries: low effort
@@ -0,0 +1,106 @@
# Prompt Snippets for Opus 4.5
Only apply these snippets if the user explicitly requests them or reports a specific issue. By default, the migration should only update model strings.
## 1. Tool Overtriggering
**Problem**: Prompts designed to reduce undertriggering on previous models may cause Opus 4.5 to overtrigger.
**When to add**: User reports tools being called too frequently or unnecessarily.
**Solution**: Replace aggressive language with normal phrasing.
| Before | After |
|--------|-------|
| `CRITICAL: You MUST use this tool when...` | `Use this tool when...` |
| `ALWAYS call the search function before...` | `Call the search function before...` |
| `You are REQUIRED to...` | `You should...` |
| `NEVER skip this step` | `Don't skip this step` |
## 2. Over-Engineering Prevention
**Problem**: Opus 4.5 may create extra files, add unnecessary abstractions, or build unrequested flexibility.
**When to add**: User reports unwanted files, excessive abstraction, or unrequested features.
**Snippet to add to system prompt**:
```
- Avoid over-engineering. Only make changes that are directly requested or clearly necessary. Keep solutions simple and focused.
- Don't add features, refactor code, or make "improvements" beyond what was asked. A bug fix doesn't need surrounding code cleaned up. A simple feature doesn't need extra configurability.
- Don't add error handling, fallbacks, or validation for scenarios that can't happen. Trust internal code and framework guarantees. Only validate at system boundaries (user input, external APIs). Don't use backwards-compatibility shims when you can just change the code.
- Don't create helpers, utilities, or abstractions for one-time operations. Don't design for hypothetical future requirements. The right amount of complexity is the minimum needed for the current task. Reuse existing abstractions where possible and follow the DRY principle.
```
## 3. Code Exploration
**Problem**: Opus 4.5 may propose solutions without reading code or make assumptions about unread files.
**When to add**: User reports the model proposing fixes without inspecting relevant code.
**Snippet to add to system prompt**:
```
ALWAYS read and understand relevant files before proposing code edits. Do not speculate about code you have not inspected. If the user references a specific file/path, you MUST open and inspect it before explaining or proposing fixes. Be rigorous and persistent in searching code for key facts. Thoroughly review the style, conventions, and abstractions of the codebase before implementing new features or abstractions.
```
## 4. Frontend Design Quality
**Problem**: Default frontend outputs may look generic ("AI slop" aesthetic).
**When to add**: User requests improved frontend design quality or reports generic-looking outputs.
**Snippet to add to system prompt**:
```xml
<frontend_aesthetics>
You tend to converge toward generic, "on distribution" outputs. In frontend design, this creates what users call the "AI slop" aesthetic. Avoid this: make creative, distinctive frontends that surprise and delight.
Focus on:
- Typography: Choose fonts that are beautiful, unique, and interesting. Avoid generic fonts like Arial and Inter; opt instead for distinctive choices that elevate the frontend's aesthetics.
- Color & Theme: Commit to a cohesive aesthetic. Use CSS variables for consistency. Dominant colors with sharp accents outperform timid, evenly-distributed palettes. Draw from IDE themes and cultural aesthetics for inspiration.
- Motion: Use animations for effects and micro-interactions. Prioritize CSS-only solutions for HTML. Use Motion library for React when available. Focus on high-impact moments: one well-orchestrated page load with staggered reveals (animation-delay) creates more delight than scattered micro-interactions.
- Backgrounds: Create atmosphere and depth rather than defaulting to solid colors. Layer CSS gradients, use geometric patterns, or add contextual effects that match the overall aesthetic.
Avoid generic AI-generated aesthetics:
- Overused font families (Inter, Roboto, Arial, system fonts)
- Clichéd color schemes (particularly purple gradients on white backgrounds)
- Predictable layouts and component patterns
- Cookie-cutter design that lacks context-specific character
Interpret creatively and make unexpected choices that feel genuinely designed for the context. Vary between light and dark themes, different fonts, different aesthetics. You still tend to converge on common choices (Space Grotesk, for example) across generations. Avoid this: it is critical that you think outside the box!
</frontend_aesthetics>
```
## 5. Thinking Sensitivity
**Problem**: When extended thinking is not enabled (the default), Opus 4.5 is particularly sensitive to the word "think" and its variants.
Extended thinking is not enabled by default. It is only enabled if the API request contains a `thinking` parameter:
```json
"thinking": {
"type": "enabled",
"budget_tokens": 10000
}
```
**When to apply**: User reports issues related to "thinking" while extended thinking is not enabled (no `thinking` parameter in their request).
**Solution**: Replace "think" with alternative words.
| Before | After |
|--------|-------|
| `think about` | `consider` |
| `think through` | `evaluate` |
| `I think` | `I believe` |
| `think carefully` | `consider carefully` |
| `thinking` | `reasoning` / `considering` |
## Usage Guidelines
1. **Integrate thoughtfully** - Don't just append snippets; weave them into the existing prompt structure
2. **Use XML tags** - Wrap additions in descriptive tags (e.g., `<coding_guidelines>`, `<tool_behavior>`) that match or complement existing prompt structure
3. **Match prompt style** - If the prompt is concise, trim the snippet; if verbose, keep full detail
4. **Place logically** - Put coding snippets near other coding instructions, tool guidance near tool definitions, etc.
5. **Preserve existing content** - Insert snippets without removing functional content
6. **Summarize changes** - After migration, list all model string updates and prompt modifications made
+18 -6
View File
@@ -22,23 +22,29 @@ Performs automated code review on a pull request using multiple specialized agen
- **Agent #4**: Analyze git blame/history for context-based issues
5. Scores each issue 0-100 for confidence level
6. Filters out issues below 80 confidence threshold
7. Posts review comment with high-confidence issues only
7. Outputs review (to terminal by default, or as PR comment with `--comment` flag)
**Usage:**
```bash
/code-review
/code-review [--comment]
```
**Options:**
- `--comment`: Post the review as a comment on the pull request (default: outputs to terminal only)
**Example workflow:**
```bash
# On a PR branch, run:
# On a PR branch, run locally (outputs to terminal):
/code-review
# Post review as PR comment:
/code-review --comment
# Claude will:
# - Launch 4 review agents in parallel
# - Score each issue for confidence
# - Post comment with issues ≥80 confidence
# - Skip posting if no high-confidence issues found
# - Output issues ≥80 confidence (to terminal or PR depending on flag)
# - Skip if no high-confidence issues found
```
**Features:**
@@ -114,17 +120,23 @@ This plugin is included in the Claude Code repository. The command is automatica
### Standard PR review workflow:
```bash
# Create PR with changes
# Run local review (outputs to terminal)
/code-review
# Review the automated feedback
# Make any necessary fixes
# Optionally post as PR comment
/code-review --comment
# Merge when ready
```
### As part of CI/CD:
```bash
# Trigger on PR creation or update
# Automatically posts review comments
# Use --comment flag to post review comments
/code-review --comment
# Skip if review already exists
```
+82 -57
View File
@@ -1,83 +1,108 @@
---
allowed-tools: Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(gh pr comment:*), Bash(gh pr diff:*), Bash(gh pr view:*), Bash(gh pr review:*), Bash(gh pr list:*)
allowed-tools: Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(gh pr comment:*), Bash(gh pr diff:*), Bash(gh pr view:*), Bash(gh pr list:*), mcp__github_inline_comment__create_inline_comment
description: Code review a pull request
---
Provide a code review for the given pull request.
**Agent assumptions (applies to all agents and subagents):**
- All tools are functional and will work without error. Do not test tools or make exploratory calls. Make sure this is clear to every subagent that is launched.
- Only call a tool if it is required to complete the task. Every tool call should have a clear purpose.
To do this, follow these steps precisely:
1. Use an agent to check if the pull request (a) is closed, (b) is a draft, (c) does not need a code review (eg. because it is an automated pull request, or is very simple and obviously ok), or (d) already has a code review from you from earlier. If so, do not proceed.
2. Use another agent to give you a list of file paths to (but not the contents of) any relevant CLAUDE.md files from the codebase: the root CLAUDE.md file (if one exists), as well as any CLAUDE.md files in the directories whose files the pull request modified
3. Use an agent to view the pull request, and ask the agent to return a summary of the change
4. Then, launch 4 parallel agents to independently code review the change. The agents should do the following, then return a list of issues and the reason each issue was flagged (eg. CLAUDE.md adherence, bug, historical git context, etc.):
a. Agents #1 and #2: Independently audit the changes to make sure they compily with the CLAUDE.md
b. Agent #3: Read the file changes in the pull request, then do a shallow scan for obvious bugs. Avoid reading extra context beyond the changes, focusing just on the changes themselves. Focus on large bugs, and avoid small issues and nitpicks. Ignore likely false positives.
c. Agent #5: Read the git blame and history of the code modified, to identify any bugs in light of that historical context
5. For each issue found in #4, launch a parallel agent that takes the PR, issue description, and list of CLAUDE.md files (from step 2), and returns a score to indicate the agent's level of confidence for whether the issue is real or false positive. To do that, the agent should score each issue on a scale from 0-100, indicating its level of confidence. For issues that were flagged due to CLAUDE.md instructions, the agent should double check that the CLAUDE.md actually calls out that issue specifically. The scale is (give this rubric to the agent verbatim):
a. 0: Not confident at all. This is a false positive that doesn't stand up to light scrutiny, or is a pre-existing issue.
b. 25: Somewhat confident. This might be a real issue, but may also be a false positive. The agent wasn't able to verify that it's a real issue. If the issue is stylistic, it is one that was not explicitly called out in the relevant CLAUDE.md.
c. 50: Moderately confident. The agent was able to verify this is a real issue, but it might be a nitpick or not happen very often in practice. Relative to the rest of the PR, it's not very important.
d. 75: Highly confident. The agent double checked the issue, and verified that it is very likely it is a real issue that will be hit in practice. The existing approach in the PR is insufficient. The issue is very important and will directly impact the code's functionality, or it is an issue that is directly mentioned in the relevant CLAUDE.md.
e. 100: Absolutely certain. The agent double checked the issue, and confirmed that it is definitely a real issue, that will happen frequently in practice. The evidence directly confirms this.
6. Filter out any issues with a score less than 80. If there are no issues that meet this criteria, do not proceed.
7. Finally, comment back on the pull request with a list of issues you found. When writing your comment, keep in mind to:
a. Keep your output brief
b. Avoid emojis
c. Link and cite relevant code, files, and URLs
1. Launch a haiku agent to check if any of the following are true:
- The pull request is closed
- The pull request is a draft
- The pull request does not need code review (e.g. automated PR, trivial change that is obviously correct)
- Claude has already commented on this PR (check `gh pr view <PR> --comments` for comments left by claude)
Examples of false positives, for steps 4 and 5:
If any condition is true, stop and do not proceed.
Note: Still review Claude generated PR's.
2. Launch a haiku agent to return a list of file paths (not their contents) for all relevant CLAUDE.md files including:
- The root CLAUDE.md file, if it exists
- Any CLAUDE.md files in directories containing files modified by the pull request
3. Launch a sonnet agent to view the pull request and return a summary of the changes
4. Launch 4 agents in parallel to independently review the changes. Each agent should return the list of issues, where each issue includes a description and the reason it was flagged (e.g. "CLAUDE.md adherence", "bug"). The agents should do the following:
Agents 1 + 2: CLAUDE.md compliance sonnet agents
Audit changes for CLAUDE.md compliance in parallel. Note: When evaluating CLAUDE.md compliance for a file, you should only consider CLAUDE.md files that share a file path with the file or parents.
Agent 3: Opus bug agent (parallel subagent with agent 4)
Scan for obvious bugs. Focus only on the diff itself without reading extra context. Flag only significant bugs; ignore nitpicks and likely false positives. Do not flag issues that you cannot validate without looking at context outside of the git diff.
Agent 4: Opus bug agent (parallel subagent with agent 3)
Look for problems that exist in the introduced code. This could be security issues, incorrect logic, etc. Only look for issues that fall within the changed code.
**CRITICAL: We only want HIGH SIGNAL issues.** Flag issues where:
- The code will fail to compile or parse (syntax errors, type errors, missing imports, unresolved references)
- The code will definitely produce wrong results regardless of inputs (clear logic errors)
- Clear, unambiguous CLAUDE.md violations where you can quote the exact rule being broken
Do NOT flag:
- Code style or quality concerns
- Potential issues that depend on specific inputs or state
- Subjective suggestions or improvements
If you are not certain an issue is real, do not flag it. False positives erode trust and waste reviewer time.
In addition to the above, each subagent should be told the PR title and description. This will help provide context regarding the author's intent.
5. For each issue found in the previous step by agents 3 and 4, launch parallel subagents to validate the issue. These subagents should get the PR title and description along with a description of the issue. The agent's job is to review the issue to validate that the stated issue is truly an issue with high confidence. For example, if an issue such as "variable is not defined" was flagged, the subagent's job would be to validate that is actually true in the code. Another example would be CLAUDE.md issues. The agent should validate that the CLAUDE.md rule that was violated is scoped for this file and is actually violated. Use Opus subagents for bugs and logic issues, and sonnet agents for CLAUDE.md violations.
6. Filter out any issues that were not validated in step 5. This step will give us our list of high signal issues for our review.
7. Output a summary of the review findings to the terminal:
- If issues were found, list each issue with a brief description.
- If no issues were found, state: "No issues found. Checked for bugs and CLAUDE.md compliance."
If `--comment` argument was NOT provided, stop here. Do not post any GitHub comments.
If `--comment` argument IS provided and NO issues were found, post a summary comment using `gh pr comment` and stop.
If `--comment` argument IS provided and issues were found, continue to step 8.
8. Create a list of all comments that you plan on leaving. This is only for you to make sure you are comfortable with the comments. Do not post this list anywhere.
9. Post inline comments for each issue using `mcp__github_inline_comment__create_inline_comment` with `confirmed: true`. For each comment:
- Provide a brief description of the issue
- For small, self-contained fixes, include a committable suggestion block
- For larger fixes (6+ lines, structural changes, or changes spanning multiple locations), describe the issue and suggested fix without a suggestion block
- Never post a committable suggestion UNLESS committing the suggestion fixes the issue entirely. If follow up steps are required, do not leave a committable suggestion.
**IMPORTANT: Only post ONE comment per unique issue. Do not post duplicate comments.**
Use this list when evaluating issues in Steps 4 and 5 (these are false positives, do NOT flag):
- Pre-existing issues
- Something that looks like a bug but is not actually a bug
- Pedantic nitpicks that a senior engineer wouldn't call out
- Issues that a linter, typechecker, or test runner will catch (eg. failing tests, lint errors, type errors). Do not run these to verify; assume that they will be run as part of CI.
- General code quality issues (eg. lack of test coverage, general security issues), unless explicitly required in CLAUDE.md
- Issues that are called out in CLAUDE.md, but explicitly silenced in the code (eg. due to a lint ignore comment)
- Something that appears to be a bug but is actually correct
- Pedantic nitpicks that a senior engineer would not flag
- Issues that a linter will catch (do not run the linter to verify)
- General code quality concerns (e.g., lack of test coverage, general security issues) unless explicitly required in CLAUDE.md
- Issues mentioned in CLAUDE.md but explicitly silenced in the code (e.g., via a lint ignore comment)
Notes:
- Use `gh` to interact with Github (eg. to fetch a pull request, or to create inline comments), rather than web fetch
- Make a todo list first
- You must cite and link each bug (eg. if referring to a CLAUDE.md, you must link it)
- For your comment, follow the following format precisely (assuming for this example that you found 3 issues):
- Use gh CLI to interact with GitHub (e.g., fetch pull requests, create comments). Do not use web fetch.
- Create a todo list before starting.
- You must cite and link each issue in inline comments (e.g., if referring to a CLAUDE.md, include a link to it).
- If no issues are found and `--comment` argument is provided, post a comment with the following format:
---
## Code review
Found 3 issues:
1. <brief description of bug> (CLAUDE.md says "<...>")
<link to file and line with full sha1 + line range for context, eg. https://github.com/anthropics/claude-code/blob/1d54823877c4de72b2316a64032a54afc404e619/README.md#L13-L17>
2. <brief description of bug> (some/other/CLAUDE.md says "<...>")
<link to file and line with full sha1 + line range for context>
3. <brief description of bug> (bug due to <file and code snippet>)
<link to file and line with full sha1 + line range for context>
🤖 Generated with [Claude Code](https://claude.ai/code)
<sub>- If this code review was useful, please react with 👍. Otherwise, react with 👎.</sub>
---
- Or, if you found no issues:
---
## Auto code review
No issues found. Checked for bugs and CLAUDE.md compliance.
## 🤖 Generated with [Claude Code](https://claude.ai/code)
---
- When linking to code, follow the following format precisely, otherwise the Markdown preview won't render correctly: https://github.com/anthropics/claude-cli-internal/blob/c21d3c10bc8e898b7ac1a2d745bdc9bc4e423afe/package.json#L10-L15
- When linking to code in inline comments, follow the following format precisely, otherwise the Markdown preview won't render correctly: https://github.com/anthropics/claude-code/blob/c21d3c10bc8e898b7ac1a2d745bdc9bc4e423afe/package.json#L10-L15
- Requires full git sha
- You must provide the full sha. Commands like `https://github.com/owner/repo/blob/$(git rev-parse HEAD)/foo/bar` will not work, since your comment will be directly rendered in Markdown.
- Repo name must match the repo you're code reviewing
- # sign after the file name
- Line range format is L[start]-L[end]
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Output the explanatory mode instructions as additionalContext
# This mimics the deprecated Explanatory output style
@@ -0,0 +1,9 @@
{
"name": "frontend-design",
"version": "1.1.0",
"description": "Frontend design skill for UI/UX implementation",
"author": {
"name": "Prithvi Rajasekaran, Alexander Bricken",
"email": "prithvi@anthropic.com, alexander@anthropic.com"
}
}
+31
View File
@@ -0,0 +1,31 @@
# Frontend Design Plugin
Generates distinctive, production-grade frontend interfaces that avoid generic AI aesthetics.
## What It Does
Claude automatically uses this skill for frontend work. Creates production-ready code with:
- Bold aesthetic choices
- Distinctive typography and color palettes
- High-impact animations and visual details
- Context-aware implementation
## Usage
```
"Create a dashboard for a music streaming app"
"Build a landing page for an AI security startup"
"Design a settings panel with dark mode"
```
Claude will choose a clear aesthetic direction and implement production code with meticulous attention to detail.
## Learn More
See the [Frontend Aesthetics Cookbook](https://github.com/anthropics/claude-cookbooks/blob/main/coding/prompting_for_frontend_aesthetics.ipynb) for detailed guidance on prompting for high-quality frontend design.
## Authors
Prithvi Rajasekaran (prithvi@anthropic.com)
Alexander Bricken (alexander@anthropic.com)
@@ -0,0 +1,55 @@
---
name: frontend-design
description: Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults.
license: Complete terms in LICENSE.txt
---
# Frontend Design
Approach this as the design lead at a small studio known for giving every client a visual identity that could not be mistaken for anyone else's. This client has already rejected proposals that felt templated, and is paying for a distinctive point of view: make deliberate, opinionated choices about palette, typography, and layout that are specific to this brief, and take one real aesthetic risk you can justify.
## Ground it in the subject
If the brief does not pin down what the product or subject is, pin it yourself before designing: name one concrete subject, its audience, and the page's single job, and state your choice. If there's any information in your memory about the human's preferences, context about what they're building, or designs you've made before use that as a hint. The subject's own world, its materials, instruments, artifacts, and vernacular, is where distinctive choices come from. Build with the brief's real content and subject matter throughout.
## Design principles
For web designs, the hero is a thesis. Open with the most characteristic thing in the subject's world, in whatever form makes sense for it: a headline, an image, an animation, a live demo, an interactive moment. Be deliberate with your choice: a big number with a small label, supporting stats, and a gradient accent is the template answer, only use if that's truly the best option.
Typography carries the personality of the page. Pair the display and body faces deliberately, not the same families you would reach for on any other project, and set a clear type scale with intentional weights, widths, and spacing. Make the type treatment itself a memorable part of the design, not a neutral delivery vehicle for the content.
Structure is information. Structural devices, numbering, eyebrows, dividers, labels, should encode something true about the content, not decorate it. Many generic designs use numbered markers (01 / 02 / 03), but that's only appropriate if the content actually is a sequence - like a real process or a typed timeline where order carries information the reader needs. Question if choices like numbered markers actually make sense before incorporating them.
Leverage motion deliberately. Think about where and if animation can serve the subject: a page-load sequence, a scroll-triggered reveal, hover micro-interactions, ambient atmosphere. An orchestrated moment usually lands harder than scattered effects; choose what the direction calls for. However, sometimes less is more, and extra animation contributes to the feeling that the design is AI-generated.
Match complexity to the vision. Maximalist directions need elaborate execution; minimal directions need precision in spacing, type, and detail. Elegance is executing the chosen vision well.
Consider written content carefully. Often a design brief may not contain real content, and it's up to you to come up with copy. Copy can make a design feel as templated as the design itself. See the below section on writing for more guidance.
## Process: brainstorm, explore, plan, critique, build, critique again
For calibration: AI-generated design right now clusters around three looks: (1) a warm cream background (near #F4F1EA) with a high-contrast serif display and a terracotta accent; (2) a near-black background with a single bright acid-green or vermilion accent; (3) a broadsheet-style layout with hairline rules, zero border-radius, and dense newspaper-like columns. All three are legitimate for some briefs, but they are defaults rather than choices, and they appear regardless of subject. Where the brief pins down a visual direction, follow it exactly — the brief's own words always win, including when it asks for one of these looks. Where it leaves an axis free, don't spend that freedom on one of these defaults. Just like a human designer who's hired, there's often a careful balance between doing what you're good at and taking each project as a chance to experiment and learn.
Work in two passes. First, brainstorm a short design plan based on the human's design brief: create a compact token system with color, type, layout, and signature. Color: describe the palette as 46 named hex values. Type: the typefaces for 2+ roles (a characterful display face that's used with restraint, a complementary body face, and a utility face for captions or data if needed). Layout: a layout concept, using one-sentence prose descriptions and ASCII wireframes to ideate and compare. Signature: the single unique element this page will be remembered by that embodies the brief in an appropriate way.
Then review that plan against the brief before building: if any part of it reads like the generic default you would produce for any similar page (work through a similar prompt to see if you arrive somewhere similar) rather than a choice made for this specific brief — revise that part, say what you changed and why. Only after you've confirmed the relative uniqueness of your design plan should you start to write the code, following the revised plan exactly and deriving every color and type decision from it.
When writing the code, be careful of structuring your CSS selector specificities. It's easy to generate CSS classes that cancel each other out (especially with a type-based selector like .section and a element-based selector like .cta). This can happen often with paddings/margins between sections.
Try to do a lot of this planning and iteration in your thinking, and only show ideas to the user when you have higher confidence it'll delight them.
## Restraint and self-critique
Spend your boldness in one place. Let the signature element be the one memorable thing, keep everything around it quiet and disciplined, and cut any decoration that does not serve the brief. Not taking a risk can be a risk itself! Build to a quality floor without announcing it: responsive down to mobile, visible keyboard focus, reduced motion respected. Critique your own work as you build, taking screenshots if your environment supports it a picture is worth 1000 tokens. Consider Chanel's advice: before leaving the house, take a look in the mirror and remove one accessory. Human creators have memory and always try to do something new, so if you have a space to quickly jot down notes about what you've tried, it can help you in future passes.
## More on writing in design
Words appear in a design for one reason: to make it easier to understand, and therefore easier to use. They are design material, not decoration. Bring the same intentionality to copy that you would bring to spacing and color. Before writing anything, ask what the design needs to say, and how it can best be said to help the person navigate the experience.
Write from the end user's side of the screen. Name things by what people control and recognize, never by how the system is built. A person manages notifications, not webhook config. Describe what something does in plain terms rather than selling it. Being specific is always better than being clever.
Use active voice as default. A control should say exactly what happens when it's used: "Save changes," not "Submit." An action keeps the same name through the whole flow, so the button that says "Publish" produces a toast that says "Published." The vocabulary of an interface is the signposting for someone navigating the product. Cohesion and consistency are how people learn their way around.
Treat failure and emptiness as moments for direction, not mood. Explain what went wrong and how to fix it, in the interface's voice rather than a person's. Errors don't apologize, and they are never vague about what happened. An empty screen is an invitation to act.
Keep the register conversational and tuned: plain verbs, sentence case, no filler, with tone matched to the brand and the audience. Let each element do exactly one job. A label labels, an example demonstrates, and nothing quietly does double duty.
@@ -0,0 +1,9 @@
{
"name": "hookify",
"version": "0.1.0",
"description": "Easily create hooks to prevent unwanted behaviors by analyzing conversation patterns",
"author": {
"name": "Daisy Hollman",
"email": "daisy@anthropic.com"
}
}
+30
View File
@@ -0,0 +1,30 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
# Virtual environments
venv/
env/
ENV/
# IDE
.vscode/
.idea/
*.swp
*.swo
# OS
.DS_Store
Thumbs.db
# Testing
.pytest_cache/
.coverage
htmlcov/
# Local configuration (should not be committed)
.claude/*.local.md
.claude/*.local.json
+340
View File
@@ -0,0 +1,340 @@
# Hookify Plugin
Easily create custom hooks to prevent unwanted behaviors by analyzing conversation patterns or from explicit instructions.
## Overview
The hookify plugin makes it simple to create hooks without editing complex `hooks.json` files. Instead, you create lightweight markdown configuration files that define patterns to watch for and messages to show when those patterns match.
**Key features:**
- 🎯 Analyze conversations to find unwanted behaviors automatically
- 📝 Simple markdown configuration files with YAML frontmatter
- 🔍 Regex pattern matching for powerful rules
- 🚀 No coding required - just describe the behavior
- 🔄 Easy enable/disable without restarting
## Quick Start
### 1. Create Your First Rule
```bash
/hookify Warn me when I use rm -rf commands
```
This analyzes your request and creates `.claude/hookify.warn-rm.local.md`.
### 2. Test It Immediately
**No restart needed!** Rules take effect on the very next tool use.
Ask Claude to run a command that should trigger the rule:
```
Run rm -rf /tmp/test
```
You should see the warning message immediately!
## Usage
### Main Command: /hookify
**With arguments:**
```
/hookify Don't use console.log in TypeScript files
```
Creates a rule from your explicit instructions.
**Without arguments:**
```
/hookify
```
Analyzes recent conversation to find behaviors you've corrected or been frustrated by.
### Helper Commands
**List all rules:**
```
/hookify:list
```
**Configure rules interactively:**
```
/hookify:configure
```
Enable/disable existing rules through an interactive interface.
**Get help:**
```
/hookify:help
```
## Rule Configuration Format
### Simple Rule (Single Pattern)
`.claude/hookify.dangerous-rm.local.md`:
```markdown
---
name: block-dangerous-rm
enabled: true
event: bash
pattern: rm\s+-rf
action: block
---
⚠️ **Dangerous rm command detected!**
This command could delete important files. Please:
- Verify the path is correct
- Consider using a safer approach
- Make sure you have backups
```
**Action field:**
- `warn`: Shows warning but allows operation (default)
- `block`: Prevents operation from executing (PreToolUse) or stops session (Stop events)
### Advanced Rule (Multiple Conditions)
`.claude/hookify.sensitive-files.local.md`:
```markdown
---
name: warn-sensitive-files
enabled: true
event: file
action: warn
conditions:
- field: file_path
operator: regex_match
pattern: \.env$|credentials|secrets
- field: new_text
operator: contains
pattern: KEY
---
🔐 **Sensitive file edit detected!**
Ensure credentials are not hardcoded and file is in .gitignore.
```
**All conditions must match** for the rule to trigger.
## Event Types
- **`bash`**: Triggers on Bash tool commands
- **`file`**: Triggers on Edit, Write, MultiEdit tools
- **`stop`**: Triggers when Claude wants to stop (for completion checks)
- **`prompt`**: Triggers on user prompt submission
- **`all`**: Triggers on all events
## Pattern Syntax
Use Python regex syntax:
| Pattern | Matches | Example |
|---------|---------|---------|
| `rm\s+-rf` | rm -rf | rm -rf /tmp |
| `console\.log\(` | console.log( | console.log("test") |
| `(eval\|exec)\(` | eval( or exec( | eval("code") |
| `\.env$` | files ending in .env | .env, .env.local |
| `chmod\s+777` | chmod 777 | chmod 777 file.txt |
**Tips:**
- Use `\s` for whitespace
- Escape special chars: `\.` for literal dot
- Use `|` for OR: `(foo|bar)`
- Use `.*` to match anything
- Set `action: block` for dangerous operations
- Set `action: warn` (or omit) for informational warnings
## Examples
### Example 1: Block Dangerous Commands
```markdown
---
name: block-destructive-ops
enabled: true
event: bash
pattern: rm\s+-rf|dd\s+if=|mkfs|format
action: block
---
🛑 **Destructive operation detected!**
This command can cause data loss. Operation blocked for safety.
Please verify the exact path and use a safer approach.
```
**This rule blocks the operation** - Claude will not be allowed to execute these commands.
### Example 2: Warn About Debug Code
```markdown
---
name: warn-debug-code
enabled: true
event: file
pattern: console\.log\(|debugger;|print\(
action: warn
---
🐛 **Debug code detected**
Remember to remove debugging statements before committing.
```
**This rule warns but allows** - Claude sees the message but can still proceed.
### Example 3: Require Tests Before Stopping
```markdown
---
name: require-tests-run
enabled: false
event: stop
action: block
conditions:
- field: transcript
operator: not_contains
pattern: npm test|pytest|cargo test
---
**Tests not detected in transcript!**
Before stopping, please run tests to verify your changes work correctly.
```
**This blocks Claude from stopping** if no test commands appear in the session transcript. Enable only when you want strict enforcement.
## Advanced Usage
### Multiple Conditions
Check multiple fields simultaneously:
```markdown
---
name: api-key-in-typescript
enabled: true
event: file
conditions:
- field: file_path
operator: regex_match
pattern: \.tsx?$
- field: new_text
operator: regex_match
pattern: (API_KEY|SECRET|TOKEN)\s*=\s*["']
---
🔐 **Hardcoded credential in TypeScript!**
Use environment variables instead of hardcoded values.
```
### Operators Reference
- `regex_match`: Pattern must match (most common)
- `contains`: String must contain pattern
- `equals`: Exact string match
- `not_contains`: String must NOT contain pattern
- `starts_with`: String starts with pattern
- `ends_with`: String ends with pattern
### Field Reference
**For bash events:**
- `command`: The bash command string
**For file events:**
- `file_path`: Path to file being edited
- `new_text`: New content being added (Edit, Write)
- `old_text`: Old content being replaced (Edit only)
- `content`: File content (Write only)
**For prompt events:**
- `user_prompt`: The user's submitted prompt text
**For stop events:**
- Use general matching on session state
## Management
### Enable/Disable Rules
**Temporarily disable:**
Edit the `.local.md` file and set `enabled: false`
**Re-enable:**
Set `enabled: true`
**Or use interactive tool:**
```
/hookify:configure
```
### Delete Rules
Simply delete the `.local.md` file:
```bash
rm .claude/hookify.my-rule.local.md
```
### View All Rules
```
/hookify:list
```
## Installation
This plugin is part of the Claude Code Marketplace. It should be auto-discovered when the marketplace is installed.
**Manual testing:**
```bash
cc --plugin-dir /path/to/hookify
```
## Requirements
- Python 3.7+
- No external dependencies (uses stdlib only)
## Troubleshooting
**Rule not triggering:**
1. Check rule file exists in `.claude/` directory (in project root, not plugin directory)
2. Verify `enabled: true` in frontmatter
3. Test regex pattern separately
4. Rules should work immediately - no restart needed
5. Try `/hookify:list` to see if rule is loaded
**Import errors:**
- Ensure Python 3 is available: `python3 --version`
- Check hookify plugin is installed
**Pattern not matching:**
- Test regex: `python3 -c "import re; print(re.search(r'pattern', 'text'))"`
- Use unquoted patterns in YAML to avoid escaping issues
- Start simple, then add complexity
**Hook seems slow:**
- Keep patterns simple (avoid complex regex)
- Use specific event types (bash, file) instead of "all"
- Limit number of active rules
## Contributing
Found a useful rule pattern? Consider sharing example files via PR!
## Future Enhancements
- Severity levels (error/warning/info distinctions)
- Rule templates library
- Interactive pattern builder
- Hook testing utilities
- JSON format support (in addition to markdown)
## License
MIT License
@@ -0,0 +1,176 @@
---
name: conversation-analyzer
description: Use this agent when analyzing conversation transcripts to find behaviors worth preventing with hooks. Examples: <example>Context: User is running /hookify command without arguments\nuser: "/hookify"\nassistant: "I'll analyze the conversation to find behaviors you want to prevent"\n<commentary>The /hookify command without arguments triggers conversation analysis to find unwanted behaviors.</commentary></example><example>Context: User wants to create hooks from recent frustrations\nuser: "Can you look back at this conversation and help me create hooks for the mistakes you made?"\nassistant: "I'll use the conversation-analyzer agent to identify the issues and suggest hooks."\n<commentary>User explicitly asks to analyze conversation for mistakes that should be prevented.</commentary></example>
model: inherit
color: yellow
tools: ["Read", "Grep"]
---
You are a conversation analysis specialist that identifies problematic behaviors in Claude Code sessions that could be prevented with hooks.
**Your Core Responsibilities:**
1. Read and analyze user messages to find frustration signals
2. Identify specific tool usage patterns that caused issues
3. Extract actionable patterns that can be matched with regex
4. Categorize issues by severity and type
5. Provide structured findings for hook rule generation
**Analysis Process:**
### 1. Search for User Messages Indicating Issues
Read through user messages in reverse chronological order (most recent first). Look for:
**Explicit correction requests:**
- "Don't use X"
- "Stop doing Y"
- "Please don't Z"
- "Avoid..."
- "Never..."
**Frustrated reactions:**
- "Why did you do X?"
- "I didn't ask for that"
- "That's not what I meant"
- "That was wrong"
**Corrections and reversions:**
- User reverting changes Claude made
- User fixing issues Claude created
- User providing step-by-step corrections
**Repeated issues:**
- Same type of mistake multiple times
- User having to remind multiple times
- Pattern of similar problems
### 2. Identify Tool Usage Patterns
For each issue, determine:
- **Which tool**: Bash, Edit, Write, MultiEdit
- **What action**: Specific command or code pattern
- **When it happened**: During what task/phase
- **Why problematic**: User's stated reason or implicit concern
**Extract concrete examples:**
- For Bash: Actual command that was problematic
- For Edit/Write: Code pattern that was added
- For Stop: What was missing before stopping
### 3. Create Regex Patterns
Convert behaviors into matchable patterns:
**Bash command patterns:**
- `rm\s+-rf` for dangerous deletes
- `sudo\s+` for privilege escalation
- `chmod\s+777` for permission issues
**Code patterns (Edit/Write):**
- `console\.log\(` for debug logging
- `eval\(|new Function\(` for dangerous eval
- `innerHTML\s*=` for XSS risks
**File path patterns:**
- `\.env$` for environment files
- `/node_modules/` for dependency files
- `dist/|build/` for generated files
### 4. Categorize Severity
**High severity (should block in future):**
- Dangerous commands (rm -rf, chmod 777)
- Security issues (hardcoded secrets, eval)
- Data loss risks
**Medium severity (warn):**
- Style violations (console.log in production)
- Wrong file types (editing generated files)
- Missing best practices
**Low severity (optional):**
- Preferences (coding style)
- Non-critical patterns
### 5. Output Format
Return your findings as structured text in this format:
```
## Hookify Analysis Results
### Issue 1: Dangerous rm Commands
**Severity**: High
**Tool**: Bash
**Pattern**: `rm\s+-rf`
**Occurrences**: 3 times
**Context**: Used rm -rf on /tmp directories without verification
**User Reaction**: "Please be more careful with rm commands"
**Suggested Rule:**
- Name: warn-dangerous-rm
- Event: bash
- Pattern: rm\s+-rf
- Message: "Dangerous rm command detected. Verify path before proceeding."
---
### Issue 2: Console.log in TypeScript
**Severity**: Medium
**Tool**: Edit/Write
**Pattern**: `console\.log\(`
**Occurrences**: 2 times
**Context**: Added console.log statements to production TypeScript files
**User Reaction**: "Don't use console.log in production code"
**Suggested Rule:**
- Name: warn-console-log
- Event: file
- Pattern: console\.log\(
- Message: "Console.log detected. Use proper logging library instead."
---
[Continue for each issue found...]
## Summary
Found {N} behaviors worth preventing:
- {N} high severity
- {N} medium severity
- {N} low severity
Recommend creating rules for high and medium severity issues.
```
**Quality Standards:**
- Be specific about patterns (don't be overly broad)
- Include actual examples from conversation
- Explain why each issue matters
- Provide ready-to-use regex patterns
- Don't false-positive on discussions about what NOT to do
**Edge Cases:**
**User discussing hypotheticals:**
- "What would happen if I used rm -rf?"
- Don't treat as problematic behavior
**Teaching moments:**
- "Here's what you shouldn't do: ..."
- Context indicates explanation, not actual problem
**One-time accidents:**
- Single occurrence, already fixed
- Mention but mark as low priority
**Subjective preferences:**
- "I prefer X over Y"
- Mark as low severity, let user decide
**Return Results:**
Provide your analysis in the structured format above. The /hookify command will use this to:
1. Present findings to user
2. Ask which rules to create
3. Generate .local.md configuration files
4. Save rules to .claude directory
+128
View File
@@ -0,0 +1,128 @@
---
description: Enable or disable hookify rules interactively
allowed-tools: ["Glob", "Read", "Edit", "AskUserQuestion", "Skill"]
---
# Configure Hookify Rules
**Load hookify:writing-rules skill first** to understand rule format.
Enable or disable existing hookify rules using an interactive interface.
## Steps
### 1. Find Existing Rules
Use Glob tool to find all hookify rule files:
```
pattern: ".claude/hookify.*.local.md"
```
If no rules found, inform user:
```
No hookify rules configured yet. Use `/hookify` to create your first rule.
```
### 2. Read Current State
For each rule file:
- Read the file
- Extract `name` and `enabled` fields from frontmatter
- Build list of rules with current state
### 3. Ask User Which Rules to Toggle
Use AskUserQuestion to let user select rules:
```json
{
"questions": [
{
"question": "Which rules would you like to enable or disable?",
"header": "Configure",
"multiSelect": true,
"options": [
{
"label": "warn-dangerous-rm (currently enabled)",
"description": "Warns about rm -rf commands"
},
{
"label": "warn-console-log (currently disabled)",
"description": "Warns about console.log in code"
},
{
"label": "require-tests (currently enabled)",
"description": "Requires tests before stopping"
}
]
}
]
}
```
**Option format:**
- Label: `{rule-name} (currently {enabled|disabled})`
- Description: Brief description from rule's message or pattern
### 4. Parse User Selection
For each selected rule:
- Determine current state from label (enabled/disabled)
- Toggle state: enabled → disabled, disabled → enabled
### 5. Update Rule Files
For each rule to toggle:
- Use Read tool to read current content
- Use Edit tool to change `enabled: true` to `enabled: false` (or vice versa)
- Handle both with and without quotes
**Edit pattern for enabling:**
```
old_string: "enabled: false"
new_string: "enabled: true"
```
**Edit pattern for disabling:**
```
old_string: "enabled: true"
new_string: "enabled: false"
```
### 6. Confirm Changes
Show user what was changed:
```
## Hookify Rules Updated
**Enabled:**
- warn-console-log
**Disabled:**
- warn-dangerous-rm
**Unchanged:**
- require-tests
Changes apply immediately - no restart needed
```
## Important Notes
- Changes take effect immediately on next tool use
- You can also manually edit .claude/hookify.*.local.md files
- To permanently remove a rule, delete its .local.md file
- Use `/hookify:list` to see all configured rules
## Edge Cases
**No rules to configure:**
- Show message about using `/hookify` to create rules first
**User selects no rules:**
- Inform that no changes were made
**File read/write errors:**
- Inform user of specific error
- Suggest manual editing as fallback
+175
View File
@@ -0,0 +1,175 @@
---
description: Get help with the hookify plugin
allowed-tools: ["Read"]
---
# Hookify Plugin Help
Explain how the hookify plugin works and how to use it.
## Overview
The hookify plugin makes it easy to create custom hooks that prevent unwanted behaviors. Instead of editing `hooks.json` files, users create simple markdown configuration files that define patterns to watch for.
## How It Works
### 1. Hook System
Hookify installs generic hooks that run on these events:
- **PreToolUse**: Before any tool executes (Bash, Edit, Write, etc.)
- **PostToolUse**: After a tool executes
- **Stop**: When Claude wants to stop working
- **UserPromptSubmit**: When user submits a prompt
These hooks read configuration files from `.claude/hookify.*.local.md` and check if any rules match the current operation.
### 2. Configuration Files
Users create rules in `.claude/hookify.{rule-name}.local.md` files:
```markdown
---
name: warn-dangerous-rm
enabled: true
event: bash
pattern: rm\s+-rf
---
⚠️ **Dangerous rm command detected!**
This command could delete important files. Please verify the path.
```
**Key fields:**
- `name`: Unique identifier for the rule
- `enabled`: true/false to activate/deactivate
- `event`: bash, file, stop, prompt, or all
- `pattern`: Regex pattern to match
The message body is what Claude sees when the rule triggers.
### 3. Creating Rules
**Option A: Use /hookify command**
```
/hookify Don't use console.log in production files
```
This analyzes your request and creates the appropriate rule file.
**Option B: Create manually**
Create `.claude/hookify.my-rule.local.md` with the format above.
**Option C: Analyze conversation**
```
/hookify
```
Without arguments, hookify analyzes recent conversation to find behaviors you want to prevent.
## Available Commands
- **`/hookify`** - Create hooks from conversation analysis or explicit instructions
- **`/hookify:help`** - Show this help (what you're reading now)
- **`/hookify:list`** - List all configured hooks
- **`/hookify:configure`** - Enable/disable existing hooks interactively
## Example Use Cases
**Prevent dangerous commands:**
```markdown
---
name: block-chmod-777
enabled: true
event: bash
pattern: chmod\s+777
---
Don't use chmod 777 - it's a security risk. Use specific permissions instead.
```
**Warn about debugging code:**
```markdown
---
name: warn-console-log
enabled: true
event: file
pattern: console\.log\(
---
Console.log detected. Remember to remove debug logging before committing.
```
**Require tests before stopping:**
```markdown
---
name: require-tests
enabled: true
event: stop
pattern: .*
---
Did you run tests before finishing? Make sure `npm test` or equivalent was executed.
```
## Pattern Syntax
Use Python regex syntax:
- `\s` - whitespace
- `\.` - literal dot
- `|` - OR
- `+` - one or more
- `*` - zero or more
- `\d` - digit
- `[abc]` - character class
**Examples:**
- `rm\s+-rf` - matches "rm -rf"
- `console\.log\(` - matches "console.log("
- `(eval|exec)\(` - matches "eval(" or "exec("
- `\.env$` - matches files ending in .env
## Important Notes
**No Restart Needed**: Hookify rules (`.local.md` files) take effect immediately on the next tool use. The hookify hooks are already loaded and read your rules dynamically.
**Block or Warn**: Rules can either `block` operations (prevent execution) or `warn` (show message but allow). Set `action: block` or `action: warn` in the rule's frontmatter.
**Rule Files**: Keep rules in `.claude/hookify.*.local.md` - they should be git-ignored (add to .gitignore if needed).
**Disable Rules**: Set `enabled: false` in frontmatter or delete the file.
## Troubleshooting
**Hook not triggering:**
- Check rule file is in `.claude/` directory
- Verify `enabled: true` in frontmatter
- Confirm pattern is valid regex
- Test pattern: `python3 -c "import re; print(re.search('your_pattern', 'test_text'))"`
- Rules take effect immediately - no restart needed
**Import errors:**
- Check Python 3 is available: `python3 --version`
- Verify hookify plugin is installed correctly
**Pattern not matching:**
- Test regex separately
- Check for escaping issues (use unquoted patterns in YAML)
- Try simpler pattern first, then refine
## Getting Started
1. Create your first rule:
```
/hookify Warn me when I try to use rm -rf
```
2. Try to trigger it:
- Ask Claude to run `rm -rf /tmp/test`
- You should see the warning
4. Refine the rule by editing `.claude/hookify.warn-rm.local.md`
5. Create more rules as you encounter unwanted behaviors
For more examples, check the `${CLAUDE_PLUGIN_ROOT}/examples/` directory.
+231
View File
@@ -0,0 +1,231 @@
---
description: Create hooks to prevent unwanted behaviors from conversation analysis or explicit instructions
argument-hint: Optional specific behavior to address
allowed-tools: ["Read", "Write", "AskUserQuestion", "Task", "Grep", "TodoWrite", "Skill"]
---
# Hookify - Create Hooks from Unwanted Behaviors
**FIRST: Load the hookify:writing-rules skill** using the Skill tool to understand rule file format and syntax.
Create hook rules to prevent problematic behaviors by analyzing the conversation or from explicit user instructions.
## Your Task
You will help the user create hookify rules to prevent unwanted behaviors. Follow these steps:
### Step 1: Gather Behavior Information
**If $ARGUMENTS is provided:**
- User has given specific instructions: `$ARGUMENTS`
- Still analyze recent conversation (last 10-15 user messages) for additional context
- Look for examples of the behavior happening
**If $ARGUMENTS is empty:**
- Launch the conversation-analyzer agent to find problematic behaviors
- Agent will scan user prompts for frustration signals
- Agent will return structured findings
**To analyze conversation:**
Use the Task tool to launch conversation-analyzer agent:
```
{
"subagent_type": "general-purpose",
"description": "Analyze conversation for unwanted behaviors",
"prompt": "You are analyzing a Claude Code conversation to find behaviors the user wants to prevent.
Read user messages in the current conversation and identify:
1. Explicit requests to avoid something (\"don't do X\", \"stop doing Y\")
2. Corrections or reversions (user fixing Claude's actions)
3. Frustrated reactions (\"why did you do X?\", \"I didn't ask for that\")
4. Repeated issues (same problem multiple times)
For each issue found, extract:
- What tool was used (Bash, Edit, Write, etc.)
- Specific pattern or command
- Why it was problematic
- User's stated reason
Return findings as a structured list with:
- category: Type of issue
- tool: Which tool was involved
- pattern: Regex or literal pattern to match
- context: What happened
- severity: high/medium/low
Focus on the most recent issues (last 20-30 messages). Don't go back further unless explicitly asked."
}
```
### Step 2: Present Findings to User
After gathering behaviors (from arguments or agent), present to user using AskUserQuestion:
**Question 1: Which behaviors to hookify?**
- Header: "Create Rules"
- multiSelect: true
- Options: List each detected behavior (max 4)
- Label: Short description (e.g., "Block rm -rf")
- Description: Why it's problematic
**Question 2: For each selected behavior, ask about action:**
- "Should this block the operation or just warn?"
- Options:
- "Just warn" (action: warn - shows message but allows)
- "Block operation" (action: block - prevents execution)
**Question 3: Ask for example patterns:**
- "What patterns should trigger this rule?"
- Show detected patterns
- Allow user to refine or add more
### Step 3: Generate Rule Files
For each confirmed behavior, create a `.claude/hookify.{rule-name}.local.md` file:
**Rule naming convention:**
- Use kebab-case
- Be descriptive: `block-dangerous-rm`, `warn-console-log`, `require-tests-before-stop`
- Start with action verb: block, warn, prevent, require
**File format:**
```markdown
---
name: {rule-name}
enabled: true
event: {bash|file|stop|prompt|all}
pattern: {regex pattern}
action: {warn|block}
---
{Message to show Claude when rule triggers}
```
**Action values:**
- `warn`: Show message but allow operation (default)
- `block`: Prevent operation or stop session
**For more complex rules (multiple conditions):**
```markdown
---
name: {rule-name}
enabled: true
event: file
conditions:
- field: file_path
operator: regex_match
pattern: \.env$
- field: new_text
operator: contains
pattern: API_KEY
---
{Warning message}
```
### Step 4: Create Files and Confirm
**IMPORTANT**: Rule files must be created in the current working directory's `.claude/` folder, NOT the plugin directory.
Use the current working directory (where Claude Code was started) as the base path.
1. Check if `.claude/` directory exists in current working directory
- If not, create it first with: `mkdir -p .claude`
2. Use Write tool to create each `.claude/hookify.{name}.local.md` file
- Use relative path from current working directory: `.claude/hookify.{name}.local.md`
- The path should resolve to the project's .claude directory, not the plugin's
3. Show user what was created:
```
Created 3 hookify rules:
- .claude/hookify.dangerous-rm.local.md
- .claude/hookify.console-log.local.md
- .claude/hookify.sensitive-files.local.md
These rules will trigger on:
- dangerous-rm: Bash commands matching "rm -rf"
- console-log: Edits adding console.log statements
- sensitive-files: Edits to .env or credentials files
```
4. Verify files were created in the correct location by listing them
5. Inform user: **"Rules are active immediately - no restart needed!"**
The hookify hooks are already loaded and will read your new rules on the next tool use.
## Event Types Reference
- **bash**: Matches Bash tool commands
- **file**: Matches Edit, Write, MultiEdit tools
- **stop**: Matches when agent wants to stop (use for completion checks)
- **prompt**: Matches when user submits prompts
- **all**: Matches all events
## Pattern Writing Tips
**Bash patterns:**
- Match dangerous commands: `rm\s+-rf|chmod\s+777|dd\s+if=`
- Match specific tools: `npm\s+install\s+|pip\s+install`
**File patterns:**
- Match code patterns: `console\.log\(|eval\(|innerHTML\s*=`
- Match file paths: `\.env$|\.git/|node_modules/`
**Stop patterns:**
- Check for missing steps: (check transcript or completion criteria)
## Example Workflow
**User says**: "/hookify Don't use rm -rf without asking me first"
**Your response**:
1. Analyze: User wants to prevent rm -rf commands
2. Ask: "Should I block this command or just warn you?"
3. User selects: "Just warn"
4. Create `.claude/hookify.dangerous-rm.local.md`:
```markdown
---
name: warn-dangerous-rm
enabled: true
event: bash
pattern: rm\s+-rf
---
⚠️ **Dangerous rm command detected**
You requested to be warned before using rm -rf.
Please verify the path is correct.
```
5. Confirm: "Created hookify rule. It's active immediately - try triggering it!"
## Important Notes
- **No restart needed**: Rules take effect immediately on the next tool use
- **File location**: Create files in project's `.claude/` directory (current working directory), NOT the plugin's .claude/
- **Regex syntax**: Use Python regex syntax (raw strings, no need to escape in YAML)
- **Action types**: Rules can `warn` (default) or `block` operations
- **Testing**: Test rules immediately after creating them
## Troubleshooting
**If rule file creation fails:**
1. Check current working directory with pwd
2. Ensure `.claude/` directory exists (create with mkdir if needed)
3. Use absolute path if needed: `{cwd}/.claude/hookify.{name}.local.md`
4. Verify file was created with Glob or ls
**If rule doesn't trigger after creation:**
1. Verify file is in project `.claude/` not plugin `.claude/`
2. Check file with Read tool to ensure pattern is correct
3. Test pattern with: `python3 -c "import re; print(re.search(r'pattern', 'test text'))"`
4. Verify `enabled: true` in frontmatter
5. Remember: Rules work immediately, no restart needed
**If blocking seems too strict:**
1. Change `action: block` to `action: warn` in the rule file
2. Or adjust the pattern to be more specific
3. Changes take effect on next tool use
Use TodoWrite to track your progress through the steps.
+82
View File
@@ -0,0 +1,82 @@
---
description: List all configured hookify rules
allowed-tools: ["Glob", "Read", "Skill"]
---
# List Hookify Rules
**Load hookify:writing-rules skill first** to understand rule format.
Show all configured hookify rules in the project.
## Steps
1. Use Glob tool to find all hookify rule files:
```
pattern: ".claude/hookify.*.local.md"
```
2. For each file found:
- Use Read tool to read the file
- Extract frontmatter fields: name, enabled, event, pattern
- Extract message preview (first 100 chars)
3. Present results in a table:
```
## Configured Hookify Rules
| Name | Enabled | Event | Pattern | File |
|------|---------|-------|---------|------|
| warn-dangerous-rm | ✅ Yes | bash | rm\s+-rf | hookify.dangerous-rm.local.md |
| warn-console-log | ✅ Yes | file | console\.log\( | hookify.console-log.local.md |
| check-tests | ❌ No | stop | .* | hookify.require-tests.local.md |
**Total**: 3 rules (2 enabled, 1 disabled)
```
4. For each rule, show a brief preview:
```
### warn-dangerous-rm
**Event**: bash
**Pattern**: `rm\s+-rf`
**Message**: "⚠️ **Dangerous rm command detected!** This command could delete..."
**Status**: ✅ Active
**File**: .claude/hookify.dangerous-rm.local.md
```
5. Add helpful footer:
```
---
To modify a rule: Edit the .local.md file directly
To disable a rule: Set `enabled: false` in frontmatter
To enable a rule: Set `enabled: true` in frontmatter
To delete a rule: Remove the .local.md file
To create a rule: Use `/hookify` command
**Remember**: Changes take effect immediately - no restart needed
```
## If No Rules Found
If no hookify rules exist:
```
## No Hookify Rules Configured
You haven't created any hookify rules yet.
To get started:
1. Use `/hookify` to analyze conversation and create rules
2. Or manually create `.claude/hookify.my-rule.local.md` files
3. See `/hookify:help` for documentation
Example:
```
/hookify Warn me when I use console.log
```
Check `${CLAUDE_PLUGIN_ROOT}/examples/` for example rule files.
```
View File
+297
View File
@@ -0,0 +1,297 @@
#!/usr/bin/env python3
"""Configuration loader for hookify plugin.
Loads and parses .claude/hookify.*.local.md files.
"""
import os
import sys
import glob
import re
from typing import List, Optional, Dict, Any
from dataclasses import dataclass, field
@dataclass
class Condition:
"""A single condition for matching."""
field: str # "command", "new_text", "old_text", "file_path", etc.
operator: str # "regex_match", "contains", "equals", etc.
pattern: str # Pattern to match
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'Condition':
"""Create Condition from dict."""
return cls(
field=data.get('field', ''),
operator=data.get('operator', 'regex_match'),
pattern=data.get('pattern', '')
)
@dataclass
class Rule:
"""A hookify rule."""
name: str
enabled: bool
event: str # "bash", "file", "stop", "all", etc.
pattern: Optional[str] = None # Simple pattern (legacy)
conditions: List[Condition] = field(default_factory=list)
action: str = "warn" # "warn" or "block" (future)
tool_matcher: Optional[str] = None # Override tool matching
message: str = "" # Message body from markdown
@classmethod
def from_dict(cls, frontmatter: Dict[str, Any], message: str) -> 'Rule':
"""Create Rule from frontmatter dict and message body."""
# Handle both simple pattern and complex conditions
conditions = []
# New style: explicit conditions list
if 'conditions' in frontmatter:
cond_list = frontmatter['conditions']
if isinstance(cond_list, list):
conditions = [Condition.from_dict(c) for c in cond_list]
# Legacy style: simple pattern field
simple_pattern = frontmatter.get('pattern')
if simple_pattern and not conditions:
# Convert simple pattern to condition
# Infer field from event
event = frontmatter.get('event', 'all')
if event == 'bash':
field = 'command'
elif event == 'file':
field = 'new_text'
else:
field = 'content'
conditions = [Condition(
field=field,
operator='regex_match',
pattern=simple_pattern
)]
return cls(
name=frontmatter.get('name', 'unnamed'),
enabled=frontmatter.get('enabled', True),
event=frontmatter.get('event', 'all'),
pattern=simple_pattern,
conditions=conditions,
action=frontmatter.get('action', 'warn'),
tool_matcher=frontmatter.get('tool_matcher'),
message=message.strip()
)
def extract_frontmatter(content: str) -> tuple[Dict[str, Any], str]:
"""Extract YAML frontmatter and message body from markdown.
Returns (frontmatter_dict, message_body).
Supports multi-line dictionary items in lists by preserving indentation.
"""
if not content.startswith('---'):
return {}, content
# Split on --- markers
parts = content.split('---', 2)
if len(parts) < 3:
return {}, content
frontmatter_text = parts[1]
message = parts[2].strip()
# Simple YAML parser that handles indented list items
frontmatter = {}
lines = frontmatter_text.split('\n')
current_key = None
current_list = []
current_dict = {}
in_list = False
in_dict_item = False
for line in lines:
# Skip empty lines and comments
stripped = line.strip()
if not stripped or stripped.startswith('#'):
continue
# Check indentation level
indent = len(line) - len(line.lstrip())
# Top-level key (no indentation or minimal)
if indent == 0 and ':' in line and not line.strip().startswith('-'):
# Save previous list/dict if any
if in_list and current_key:
if in_dict_item and current_dict:
current_list.append(current_dict)
current_dict = {}
frontmatter[current_key] = current_list
in_list = False
in_dict_item = False
current_list = []
key, value = line.split(':', 1)
key = key.strip()
value = value.strip()
if not value:
# Empty value - list or nested structure follows
current_key = key
in_list = True
current_list = []
else:
# Simple key-value pair
value = value.strip('"').strip("'")
if value.lower() == 'true':
value = True
elif value.lower() == 'false':
value = False
frontmatter[key] = value
# List item (starts with -)
elif stripped.startswith('-') and in_list:
# Save previous dict item if any
if in_dict_item and current_dict:
current_list.append(current_dict)
current_dict = {}
item_text = stripped[1:].strip()
# Check if this is an inline dict (key: value on same line)
if ':' in item_text and ',' in item_text:
# Inline comma-separated dict: "- field: command, operator: regex_match"
item_dict = {}
for part in item_text.split(','):
if ':' in part:
k, v = part.split(':', 1)
item_dict[k.strip()] = v.strip().strip('"').strip("'")
current_list.append(item_dict)
in_dict_item = False
elif ':' in item_text:
# Start of multi-line dict item: "- field: command"
in_dict_item = True
k, v = item_text.split(':', 1)
current_dict = {k.strip(): v.strip().strip('"').strip("'")}
else:
# Simple list item
current_list.append(item_text.strip('"').strip("'"))
in_dict_item = False
# Continuation of dict item (indented under list item)
elif indent > 2 and in_dict_item and ':' in line:
# This is a field of the current dict item
k, v = stripped.split(':', 1)
current_dict[k.strip()] = v.strip().strip('"').strip("'")
# Save final list/dict if any
if in_list and current_key:
if in_dict_item and current_dict:
current_list.append(current_dict)
frontmatter[current_key] = current_list
return frontmatter, message
def load_rules(event: Optional[str] = None) -> List[Rule]:
"""Load all hookify rules from .claude directory.
Args:
event: Optional event filter ("bash", "file", "stop", etc.)
Returns:
List of enabled Rule objects matching the event.
"""
rules = []
# Find all hookify.*.local.md files
pattern = os.path.join('.claude', 'hookify.*.local.md')
files = glob.glob(pattern)
for file_path in files:
try:
rule = load_rule_file(file_path)
if not rule:
continue
# Filter by event if specified
if event:
if rule.event != 'all' and rule.event != event:
continue
# Only include enabled rules
if rule.enabled:
rules.append(rule)
except (IOError, OSError, PermissionError) as e:
# File I/O errors - log and continue
print(f"Warning: Failed to read {file_path}: {e}", file=sys.stderr)
continue
except (ValueError, KeyError, AttributeError, TypeError) as e:
# Parsing errors - log and continue
print(f"Warning: Failed to parse {file_path}: {e}", file=sys.stderr)
continue
except Exception as e:
# Unexpected errors - log with type details
print(f"Warning: Unexpected error loading {file_path} ({type(e).__name__}): {e}", file=sys.stderr)
continue
return rules
def load_rule_file(file_path: str) -> Optional[Rule]:
"""Load a single rule file.
Returns:
Rule object or None if file is invalid.
"""
try:
with open(file_path, 'r') as f:
content = f.read()
frontmatter, message = extract_frontmatter(content)
if not frontmatter:
print(f"Warning: {file_path} missing YAML frontmatter (must start with ---)", file=sys.stderr)
return None
rule = Rule.from_dict(frontmatter, message)
return rule
except (IOError, OSError, PermissionError) as e:
print(f"Error: Cannot read {file_path}: {e}", file=sys.stderr)
return None
except (ValueError, KeyError, AttributeError, TypeError) as e:
print(f"Error: Malformed rule file {file_path}: {e}", file=sys.stderr)
return None
except UnicodeDecodeError as e:
print(f"Error: Invalid encoding in {file_path}: {e}", file=sys.stderr)
return None
except Exception as e:
print(f"Error: Unexpected error parsing {file_path} ({type(e).__name__}): {e}", file=sys.stderr)
return None
# For testing
if __name__ == '__main__':
import sys
# Test frontmatter parsing
test_content = """---
name: test-rule
enabled: true
event: bash
pattern: "rm -rf"
---
⚠️ Dangerous command detected!
"""
fm, msg = extract_frontmatter(test_content)
print("Frontmatter:", fm)
print("Message:", msg)
rule = Rule.from_dict(fm, msg)
print("Rule:", rule)
+313
View File
@@ -0,0 +1,313 @@
#!/usr/bin/env python3
"""Rule evaluation engine for hookify plugin."""
import re
import sys
from functools import lru_cache
from typing import List, Dict, Any, Optional
# Import from local module
from hookify.core.config_loader import Rule, Condition
# Cache compiled regexes (max 128 patterns)
@lru_cache(maxsize=128)
def compile_regex(pattern: str) -> re.Pattern:
"""Compile regex pattern with caching.
Args:
pattern: Regex pattern string
Returns:
Compiled regex pattern
"""
return re.compile(pattern, re.IGNORECASE)
class RuleEngine:
"""Evaluates rules against hook input data."""
def __init__(self):
"""Initialize rule engine."""
# No need for instance cache anymore - using global lru_cache
pass
def evaluate_rules(self, rules: List[Rule], input_data: Dict[str, Any]) -> Dict[str, Any]:
"""Evaluate all rules and return combined results.
Checks all rules and accumulates matches. Blocking rules take priority
over warning rules. All matching rule messages are combined.
Args:
rules: List of Rule objects to evaluate
input_data: Hook input JSON (tool_name, tool_input, etc.)
Returns:
Response dict with systemMessage, hookSpecificOutput, etc.
Empty dict {} if no rules match.
"""
hook_event = input_data.get('hook_event_name', '')
blocking_rules = []
warning_rules = []
for rule in rules:
if self._rule_matches(rule, input_data):
if rule.action == 'block':
blocking_rules.append(rule)
else:
warning_rules.append(rule)
# If any blocking rules matched, block the operation
if blocking_rules:
messages = [f"**[{r.name}]**\n{r.message}" for r in blocking_rules]
combined_message = "\n\n".join(messages)
# Use appropriate blocking format based on event type
if hook_event == 'Stop':
return {
"decision": "block",
"reason": combined_message,
"systemMessage": combined_message
}
elif hook_event in ['PreToolUse', 'PostToolUse']:
return {
"hookSpecificOutput": {
"hookEventName": hook_event,
"permissionDecision": "deny"
},
"systemMessage": combined_message
}
else:
# For other events, just show message
return {
"systemMessage": combined_message
}
# If only warnings, show them but allow operation
if warning_rules:
messages = [f"**[{r.name}]**\n{r.message}" for r in warning_rules]
return {
"systemMessage": "\n\n".join(messages)
}
# No matches - allow operation
return {}
def _rule_matches(self, rule: Rule, input_data: Dict[str, Any]) -> bool:
"""Check if rule matches input data.
Args:
rule: Rule to evaluate
input_data: Hook input data
Returns:
True if rule matches, False otherwise
"""
# Extract tool information
tool_name = input_data.get('tool_name', '')
tool_input = input_data.get('tool_input', {})
# Check tool matcher if specified
if rule.tool_matcher:
if not self._matches_tool(rule.tool_matcher, tool_name):
return False
# If no conditions, don't match
# (Rules must have at least one condition to be valid)
if not rule.conditions:
return False
# All conditions must match
for condition in rule.conditions:
if not self._check_condition(condition, tool_name, tool_input, input_data):
return False
return True
def _matches_tool(self, matcher: str, tool_name: str) -> bool:
"""Check if tool_name matches the matcher pattern.
Args:
matcher: Pattern like "Bash", "Edit|Write", "*"
tool_name: Actual tool name
Returns:
True if matches
"""
if matcher == '*':
return True
# Split on | for OR matching
patterns = matcher.split('|')
return tool_name in patterns
def _check_condition(self, condition: Condition, tool_name: str,
tool_input: Dict[str, Any], input_data: Dict[str, Any] = None) -> bool:
"""Check if a single condition matches.
Args:
condition: Condition to check
tool_name: Tool being used
tool_input: Tool input dict
input_data: Full hook input data (for Stop events, etc.)
Returns:
True if condition matches
"""
# Extract the field value to check
field_value = self._extract_field(condition.field, tool_name, tool_input, input_data)
if field_value is None:
return False
# Apply operator
operator = condition.operator
pattern = condition.pattern
if operator == 'regex_match':
return self._regex_match(pattern, field_value)
elif operator == 'contains':
return pattern in field_value
elif operator == 'equals':
return pattern == field_value
elif operator == 'not_contains':
return pattern not in field_value
elif operator == 'starts_with':
return field_value.startswith(pattern)
elif operator == 'ends_with':
return field_value.endswith(pattern)
else:
# Unknown operator
return False
def _extract_field(self, field: str, tool_name: str,
tool_input: Dict[str, Any], input_data: Dict[str, Any] = None) -> Optional[str]:
"""Extract field value from tool input or hook input data.
Args:
field: Field name like "command", "new_text", "file_path", "reason", "transcript"
tool_name: Tool being used (may be empty for Stop events)
tool_input: Tool input dict
input_data: Full hook input (for accessing transcript_path, reason, etc.)
Returns:
Field value as string, or None if not found
"""
# Direct tool_input fields
if field in tool_input:
value = tool_input[field]
if isinstance(value, str):
return value
return str(value)
# For Stop events and other non-tool events, check input_data
if input_data:
# Stop event specific fields
if field == 'reason':
return input_data.get('reason', '')
elif field == 'transcript':
# Read transcript file if path provided
transcript_path = input_data.get('transcript_path')
if transcript_path:
try:
with open(transcript_path, 'r') as f:
return f.read()
except FileNotFoundError:
print(f"Warning: Transcript file not found: {transcript_path}", file=sys.stderr)
return ''
except PermissionError:
print(f"Warning: Permission denied reading transcript: {transcript_path}", file=sys.stderr)
return ''
except (IOError, OSError) as e:
print(f"Warning: Error reading transcript {transcript_path}: {e}", file=sys.stderr)
return ''
except UnicodeDecodeError as e:
print(f"Warning: Encoding error in transcript {transcript_path}: {e}", file=sys.stderr)
return ''
elif field == 'user_prompt':
# For UserPromptSubmit events
return input_data.get('user_prompt', '')
# Handle special cases by tool type
if tool_name == 'Bash':
if field == 'command':
return tool_input.get('command', '')
elif tool_name in ['Write', 'Edit']:
if field == 'content':
# Write uses 'content', Edit has 'new_string'
return tool_input.get('content') or tool_input.get('new_string', '')
elif field == 'new_text' or field == 'new_string':
return tool_input.get('new_string', '')
elif field == 'old_text' or field == 'old_string':
return tool_input.get('old_string', '')
elif field == 'file_path':
return tool_input.get('file_path', '')
elif tool_name == 'MultiEdit':
if field == 'file_path':
return tool_input.get('file_path', '')
elif field in ['new_text', 'content']:
# Concatenate all edits
edits = tool_input.get('edits', [])
return ' '.join(e.get('new_string', '') for e in edits)
return None
def _regex_match(self, pattern: str, text: str) -> bool:
"""Check if pattern matches text using regex.
Args:
pattern: Regex pattern
text: Text to match against
Returns:
True if pattern matches
"""
try:
# Use cached compiled regex (LRU cache with max 128 patterns)
regex = compile_regex(pattern)
return bool(regex.search(text))
except re.error as e:
print(f"Invalid regex pattern '{pattern}': {e}", file=sys.stderr)
return False
# For testing
if __name__ == '__main__':
from hookify.core.config_loader import Condition, Rule
# Test rule evaluation
rule = Rule(
name="test-rm",
enabled=True,
event="bash",
conditions=[
Condition(field="command", operator="regex_match", pattern=r"rm\s+-rf")
],
message="Dangerous rm command!"
)
engine = RuleEngine()
# Test matching input
test_input = {
"tool_name": "Bash",
"tool_input": {
"command": "rm -rf /tmp/test"
}
}
result = engine.evaluate_rules([rule], test_input)
print("Match result:", result)
# Test non-matching input
test_input2 = {
"tool_name": "Bash",
"tool_input": {
"command": "ls -la"
}
}
result2 = engine.evaluate_rules([rule], test_input2)
print("Non-match result:", result2)
@@ -0,0 +1,14 @@
---
name: warn-console-log
enabled: true
event: file
pattern: console\.log\(
action: warn
---
🔍 **Console.log detected**
You're adding a console.log statement. Please consider:
- Is this for debugging or should it be proper logging?
- Will this ship to production?
- Should this use a logging library instead?
@@ -0,0 +1,14 @@
---
name: block-dangerous-rm
enabled: true
event: bash
pattern: rm\s+-rf
action: block
---
⚠️ **Dangerous rm command detected!**
This command could delete important files. Please:
- Verify the path is correct
- Consider using a safer approach
- Make sure you have backups
@@ -0,0 +1,22 @@
---
name: require-tests-run
enabled: false
event: stop
action: block
conditions:
- field: transcript
operator: not_contains
pattern: npm test|pytest|cargo test
---
**Tests not detected in transcript!**
Before stopping, please run tests to verify your changes work correctly.
Look for test commands like:
- `npm test`
- `pytest`
- `cargo test`
**Note:** This rule blocks stopping if no test commands appear in the transcript.
Enable this rule only when you want strict test enforcement.
@@ -0,0 +1,18 @@
---
name: warn-sensitive-files
enabled: true
event: file
action: warn
conditions:
- field: file_path
operator: regex_match
pattern: \.env$|\.env\.|credentials|secrets
---
🔐 **Sensitive file detected**
You're editing a file that may contain sensitive data:
- Ensure credentials are not hardcoded
- Use environment variables for secrets
- Verify this file is in .gitignore
- Consider using a secrets manager
View File
+49
View File
@@ -0,0 +1,49 @@
{
"description": "Hookify plugin - User-configurable hooks from .local.md files",
"hooks": {
"PreToolUse": [
{
"hooks": [
{
"type": "command",
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/pretooluse.py",
"timeout": 10
}
]
}
],
"PostToolUse": [
{
"hooks": [
{
"type": "command",
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/posttooluse.py",
"timeout": 10
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/stop.py",
"timeout": 10
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/userpromptsubmit.py",
"timeout": 10
}
]
}
]
}
}
+66
View File
@@ -0,0 +1,66 @@
#!/usr/bin/env python3
"""PostToolUse hook executor for hookify plugin.
This script is called by Claude Code after a tool executes.
It reads .claude/hookify.*.local.md files and evaluates rules.
"""
import os
import sys
import json
# CRITICAL: Add plugin root to Python path for imports
PLUGIN_ROOT = os.environ.get('CLAUDE_PLUGIN_ROOT')
if PLUGIN_ROOT:
parent_dir = os.path.dirname(PLUGIN_ROOT)
if parent_dir not in sys.path:
sys.path.insert(0, parent_dir)
if PLUGIN_ROOT not in sys.path:
sys.path.insert(0, PLUGIN_ROOT)
try:
from hookify.core.config_loader import load_rules
from hookify.core.rule_engine import RuleEngine
except ImportError as e:
error_msg = {"systemMessage": f"Hookify import error: {e}"}
print(json.dumps(error_msg), file=sys.stdout)
sys.exit(0)
def main():
"""Main entry point for PostToolUse hook."""
try:
# Read input from stdin
input_data = json.load(sys.stdin)
# Determine event type based on tool
tool_name = input_data.get('tool_name', '')
event = None
if tool_name == 'Bash':
event = 'bash'
elif tool_name in ['Edit', 'Write', 'MultiEdit']:
event = 'file'
# Load rules
rules = load_rules(event=event)
# Evaluate rules
engine = RuleEngine()
result = engine.evaluate_rules(rules, input_data)
# Always output JSON (even if empty)
print(json.dumps(result), file=sys.stdout)
except Exception as e:
error_output = {
"systemMessage": f"Hookify error: {str(e)}"
}
print(json.dumps(error_output), file=sys.stdout)
finally:
# ALWAYS exit 0
sys.exit(0)
if __name__ == '__main__':
main()
+74
View File
@@ -0,0 +1,74 @@
#!/usr/bin/env python3
"""PreToolUse hook executor for hookify plugin.
This script is called by Claude Code before any tool executes.
It reads .claude/hookify.*.local.md files and evaluates rules.
"""
import os
import sys
import json
# CRITICAL: Add plugin root to Python path for imports
# We need to add the parent of the plugin directory so Python can find "hookify" package
PLUGIN_ROOT = os.environ.get('CLAUDE_PLUGIN_ROOT')
if PLUGIN_ROOT:
# Add the parent directory of the plugin
parent_dir = os.path.dirname(PLUGIN_ROOT)
if parent_dir not in sys.path:
sys.path.insert(0, parent_dir)
# Also add PLUGIN_ROOT itself in case we have other scripts
if PLUGIN_ROOT not in sys.path:
sys.path.insert(0, PLUGIN_ROOT)
try:
from hookify.core.config_loader import load_rules
from hookify.core.rule_engine import RuleEngine
except ImportError as e:
# If imports fail, allow operation and log error
error_msg = {"systemMessage": f"Hookify import error: {e}"}
print(json.dumps(error_msg), file=sys.stdout)
sys.exit(0)
def main():
"""Main entry point for PreToolUse hook."""
try:
# Read input from stdin
input_data = json.load(sys.stdin)
# Determine event type for filtering
# For PreToolUse, we use tool_name to determine "bash" vs "file" event
tool_name = input_data.get('tool_name', '')
event = None
if tool_name == 'Bash':
event = 'bash'
elif tool_name in ['Edit', 'Write', 'MultiEdit']:
event = 'file'
# Load rules
rules = load_rules(event=event)
# Evaluate rules
engine = RuleEngine()
result = engine.evaluate_rules(rules, input_data)
# Always output JSON (even if empty)
print(json.dumps(result), file=sys.stdout)
except Exception as e:
# On any error, allow the operation and log
error_output = {
"systemMessage": f"Hookify error: {str(e)}"
}
print(json.dumps(error_output), file=sys.stdout)
finally:
# ALWAYS exit 0 - never block operations due to hook errors
sys.exit(0)
if __name__ == '__main__':
main()
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env python3
"""Stop hook executor for hookify plugin.
This script is called by Claude Code when agent wants to stop.
It reads .claude/hookify.*.local.md files and evaluates stop rules.
"""
import os
import sys
import json
# CRITICAL: Add plugin root to Python path for imports
PLUGIN_ROOT = os.environ.get('CLAUDE_PLUGIN_ROOT')
if PLUGIN_ROOT:
parent_dir = os.path.dirname(PLUGIN_ROOT)
if parent_dir not in sys.path:
sys.path.insert(0, parent_dir)
if PLUGIN_ROOT not in sys.path:
sys.path.insert(0, PLUGIN_ROOT)
try:
from hookify.core.config_loader import load_rules
from hookify.core.rule_engine import RuleEngine
except ImportError as e:
error_msg = {"systemMessage": f"Hookify import error: {e}"}
print(json.dumps(error_msg), file=sys.stdout)
sys.exit(0)
def main():
"""Main entry point for Stop hook."""
try:
# Read input from stdin
input_data = json.load(sys.stdin)
# Load stop rules
rules = load_rules(event='stop')
# Evaluate rules
engine = RuleEngine()
result = engine.evaluate_rules(rules, input_data)
# Always output JSON (even if empty)
print(json.dumps(result), file=sys.stdout)
except Exception as e:
# On any error, allow the operation
error_output = {
"systemMessage": f"Hookify error: {str(e)}"
}
print(json.dumps(error_output), file=sys.stdout)
finally:
# ALWAYS exit 0
sys.exit(0)
if __name__ == '__main__':
main()
+58
View File
@@ -0,0 +1,58 @@
#!/usr/bin/env python3
"""UserPromptSubmit hook executor for hookify plugin.
This script is called by Claude Code when user submits a prompt.
It reads .claude/hookify.*.local.md files and evaluates rules.
"""
import os
import sys
import json
# CRITICAL: Add plugin root to Python path for imports
PLUGIN_ROOT = os.environ.get('CLAUDE_PLUGIN_ROOT')
if PLUGIN_ROOT:
parent_dir = os.path.dirname(PLUGIN_ROOT)
if parent_dir not in sys.path:
sys.path.insert(0, parent_dir)
if PLUGIN_ROOT not in sys.path:
sys.path.insert(0, PLUGIN_ROOT)
try:
from hookify.core.config_loader import load_rules
from hookify.core.rule_engine import RuleEngine
except ImportError as e:
error_msg = {"systemMessage": f"Hookify import error: {e}"}
print(json.dumps(error_msg), file=sys.stdout)
sys.exit(0)
def main():
"""Main entry point for UserPromptSubmit hook."""
try:
# Read input from stdin
input_data = json.load(sys.stdin)
# Load user prompt rules
rules = load_rules(event='prompt')
# Evaluate rules
engine = RuleEngine()
result = engine.evaluate_rules(rules, input_data)
# Always output JSON (even if empty)
print(json.dumps(result), file=sys.stdout)
except Exception as e:
error_output = {
"systemMessage": f"Hookify error: {str(e)}"
}
print(json.dumps(error_output), file=sys.stdout)
finally:
# ALWAYS exit 0
sys.exit(0)
if __name__ == '__main__':
main()
@@ -0,0 +1,374 @@
---
name: Writing Hookify Rules
description: This skill should be used when the user asks to "create a hookify rule", "write a hook rule", "configure hookify", "add a hookify rule", or needs guidance on hookify rule syntax and patterns.
version: 0.1.0
---
# Writing Hookify Rules
## Overview
Hookify rules are markdown files with YAML frontmatter that define patterns to watch for and messages to show when those patterns match. Rules are stored in `.claude/hookify.{rule-name}.local.md` files.
## Rule File Format
### Basic Structure
```markdown
---
name: rule-identifier
enabled: true
event: bash|file|stop|prompt|all
pattern: regex-pattern-here
---
Message to show Claude when this rule triggers.
Can include markdown formatting, warnings, suggestions, etc.
```
### Frontmatter Fields
**name** (required): Unique identifier for the rule
- Use kebab-case: `warn-dangerous-rm`, `block-console-log`
- Be descriptive and action-oriented
- Start with verb: warn, prevent, block, require, check
**enabled** (required): Boolean to activate/deactivate
- `true`: Rule is active
- `false`: Rule is disabled (won't trigger)
- Can toggle without deleting rule
**event** (required): Which hook event to trigger on
- `bash`: Bash tool commands
- `file`: Edit, Write, MultiEdit tools
- `stop`: When agent wants to stop
- `prompt`: When user submits a prompt
- `all`: All events
**action** (optional): What to do when rule matches
- `warn`: Show message but allow operation (default)
- `block`: Prevent operation (PreToolUse) or stop session (Stop events)
- If omitted, defaults to `warn`
**pattern** (simple format): Regex pattern to match
- Used for simple single-condition rules
- Matches against command (bash) or new_text (file)
- Python regex syntax
**Example:**
```yaml
event: bash
pattern: rm\s+-rf
```
### Advanced Format (Multiple Conditions)
For complex rules with multiple conditions:
```markdown
---
name: warn-env-file-edits
enabled: true
event: file
conditions:
- field: file_path
operator: regex_match
pattern: \.env$
- field: new_text
operator: contains
pattern: API_KEY
---
You're adding an API key to a .env file. Ensure this file is in .gitignore!
```
**Condition fields:**
- `field`: Which field to check
- For bash: `command`
- For file: `file_path`, `new_text`, `old_text`, `content`
- `operator`: How to match
- `regex_match`: Regex pattern matching
- `contains`: Substring check
- `equals`: Exact match
- `not_contains`: Substring must NOT be present
- `starts_with`: Prefix check
- `ends_with`: Suffix check
- `pattern`: Pattern or string to match
**All conditions must match for rule to trigger.**
## Message Body
The markdown content after frontmatter is shown to Claude when the rule triggers.
**Good messages:**
- Explain what was detected
- Explain why it's problematic
- Suggest alternatives or best practices
- Use formatting for clarity (bold, lists, etc.)
**Example:**
```markdown
⚠️ **Console.log detected!**
You're adding console.log to production code.
**Why this matters:**
- Debug logs shouldn't ship to production
- Console.log can expose sensitive data
- Impacts browser performance
**Alternatives:**
- Use a proper logging library
- Remove before committing
- Use conditional debug builds
```
## Event Type Guide
### bash Events
Match Bash command patterns:
```markdown
---
event: bash
pattern: sudo\s+|rm\s+-rf|chmod\s+777
---
Dangerous command detected!
```
**Common patterns:**
- Dangerous commands: `rm\s+-rf`, `dd\s+if=`, `mkfs`
- Privilege escalation: `sudo\s+`, `su\s+`
- Permission issues: `chmod\s+777`, `chown\s+root`
### file Events
Match Edit/Write/MultiEdit operations:
```markdown
---
event: file
pattern: console\.log\(|eval\(|innerHTML\s*=
---
Potentially problematic code pattern detected!
```
**Match on different fields:**
```markdown
---
event: file
conditions:
- field: file_path
operator: regex_match
pattern: \.tsx?$
- field: new_text
operator: regex_match
pattern: console\.log\(
---
Console.log in TypeScript file!
```
**Common patterns:**
- Debug code: `console\.log\(`, `debugger`, `print\(`
- Security risks: `eval\(`, `innerHTML\s*=`, `dangerouslySetInnerHTML`
- Sensitive files: `\.env$`, `credentials`, `\.pem$`
- Generated files: `node_modules/`, `dist/`, `build/`
### stop Events
Match when agent wants to stop (completion checks):
```markdown
---
event: stop
pattern: .*
---
Before stopping, verify:
- [ ] Tests were run
- [ ] Build succeeded
- [ ] Documentation updated
```
**Use for:**
- Reminders about required steps
- Completion checklists
- Process enforcement
### prompt Events
Match user prompt content (advanced):
```markdown
---
event: prompt
conditions:
- field: user_prompt
operator: contains
pattern: deploy to production
---
Production deployment checklist:
- [ ] Tests passing?
- [ ] Reviewed by team?
- [ ] Monitoring ready?
```
## Pattern Writing Tips
### Regex Basics
**Literal characters:** Most characters match themselves
- `rm` matches "rm"
- `console.log` matches "console.log"
**Special characters need escaping:**
- `.` (any char) → `\.` (literal dot)
- `(` `)``\(` `\)` (literal parens)
- `[` `]``\[` `\]` (literal brackets)
**Common metacharacters:**
- `\s` - whitespace (space, tab, newline)
- `\d` - digit (0-9)
- `\w` - word character (a-z, A-Z, 0-9, _)
- `.` - any character
- `+` - one or more
- `*` - zero or more
- `?` - zero or one
- `|` - OR
**Examples:**
```
rm\s+-rf Matches: rm -rf, rm -rf
console\.log\( Matches: console.log(
(eval|exec)\( Matches: eval( or exec(
chmod\s+777 Matches: chmod 777, chmod 777
API_KEY\s*= Matches: API_KEY=, API_KEY =
```
### Testing Patterns
Test regex patterns before using:
```bash
python3 -c "import re; print(re.search(r'your_pattern', 'test text'))"
```
Or use online regex testers (regex101.com with Python flavor).
### Common Pitfalls
**Too broad:**
```yaml
pattern: log # Matches "log", "login", "dialog", "catalog"
```
Better: `console\.log\(|logger\.`
**Too specific:**
```yaml
pattern: rm -rf /tmp # Only matches exact path
```
Better: `rm\s+-rf`
**Escaping issues:**
- YAML quoted strings: `"pattern"` requires double backslashes `\\s`
- YAML unquoted: `pattern: \s` works as-is
- **Recommendation**: Use unquoted patterns in YAML
## File Organization
**Location:** All rules in `.claude/` directory
**Naming:** `.claude/hookify.{descriptive-name}.local.md`
**Gitignore:** Add `.claude/*.local.md` to `.gitignore`
**Good names:**
- `hookify.dangerous-rm.local.md`
- `hookify.console-log.local.md`
- `hookify.require-tests.local.md`
- `hookify.sensitive-files.local.md`
**Bad names:**
- `hookify.rule1.local.md` (not descriptive)
- `hookify.md` (missing .local)
- `danger.local.md` (missing hookify prefix)
## Workflow
### Creating a Rule
1. Identify unwanted behavior
2. Determine which tool is involved (Bash, Edit, etc.)
3. Choose event type (bash, file, stop, etc.)
4. Write regex pattern
5. Create `.claude/hookify.{name}.local.md` file in project root
6. Test immediately - rules are read dynamically on next tool use
### Refining a Rule
1. Edit the `.local.md` file
2. Adjust pattern or message
3. Test immediately - changes take effect on next tool use
### Disabling a Rule
**Temporary:** Set `enabled: false` in frontmatter
**Permanent:** Delete the `.local.md` file
## Examples
See `${CLAUDE_PLUGIN_ROOT}/examples/` for complete examples:
- `dangerous-rm.local.md` - Block dangerous rm commands
- `console-log-warning.local.md` - Warn about console.log
- `sensitive-files-warning.local.md` - Warn about editing .env files
## Quick Reference
**Minimum viable rule:**
```markdown
---
name: my-rule
enabled: true
event: bash
pattern: dangerous_command
---
Warning message here
```
**Rule with conditions:**
```markdown
---
name: my-rule
enabled: true
event: file
conditions:
- field: file_path
operator: regex_match
pattern: \.ts$
- field: new_text
operator: contains
pattern: any
---
Warning message
```
**Event types:**
- `bash` - Bash commands
- `file` - File edits
- `stop` - Completion checks
- `prompt` - User input
- `all` - All events
**Field options:**
- Bash: `command`
- File: `file_path`, `new_text`, `old_text`, `content`
- Prompt: `user_prompt`
**Operators:**
- `regex_match`, `contains`, `equals`, `not_contains`, `starts_with`, `ends_with`
View File
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Output the learning mode instructions as additionalContext
# This combines the unshipped Learning output style with explanatory functionality
+402
View File
@@ -0,0 +1,402 @@
# Plugin Development Toolkit
A comprehensive toolkit for developing Claude Code plugins with expert guidance on hooks, MCP integration, plugin structure, and marketplace publishing.
## Overview
The plugin-dev toolkit provides seven specialized skills to help you build high-quality Claude Code plugins:
1. **Hook Development** - Advanced hooks API and event-driven automation
2. **MCP Integration** - Model Context Protocol server integration
3. **Plugin Structure** - Plugin organization and manifest configuration
4. **Plugin Settings** - Configuration patterns using .claude/plugin-name.local.md files
5. **Command Development** - Creating slash commands with frontmatter and arguments
6. **Agent Development** - Creating autonomous agents with AI-assisted generation
7. **Skill Development** - Creating skills with progressive disclosure and strong triggers
Each skill follows best practices with progressive disclosure: lean core documentation, detailed references, working examples, and utility scripts.
## Guided Workflow Command
### /plugin-dev:create-plugin
A comprehensive, end-to-end workflow command for creating plugins from scratch, similar to the feature-dev workflow.
**8-Phase Process:**
1. **Discovery** - Understand plugin purpose and requirements
2. **Component Planning** - Determine needed skills, commands, agents, hooks, MCP
3. **Detailed Design** - Specify each component and resolve ambiguities
4. **Structure Creation** - Set up directories and manifest
5. **Component Implementation** - Create each component using AI-assisted agents
6. **Validation** - Run plugin-validator and component-specific checks
7. **Testing** - Verify plugin works in Claude Code
8. **Documentation** - Finalize README and prepare for distribution
**Features:**
- Asks clarifying questions at each phase
- Loads relevant skills automatically
- Uses agent-creator for AI-assisted agent generation
- Runs validation utilities (validate-agent.sh, validate-hook-schema.sh, etc.)
- Follows plugin-dev's own proven patterns
- Guides through testing and verification
**Usage:**
```bash
/plugin-dev:create-plugin [optional description]
# Examples:
/plugin-dev:create-plugin
/plugin-dev:create-plugin A plugin for managing database migrations
```
Use this workflow for structured, high-quality plugin development from concept to completion.
## Skills
### 1. Hook Development
**Trigger phrases:** "create a hook", "add a PreToolUse hook", "validate tool use", "implement prompt-based hooks", "${CLAUDE_PLUGIN_ROOT}", "block dangerous commands"
**What it covers:**
- Prompt-based hooks (recommended) with LLM decision-making
- Command hooks for deterministic validation
- All hook events: PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification
- Hook output formats and JSON schemas
- Security best practices and input validation
- ${CLAUDE_PLUGIN_ROOT} for portable paths
**Resources:**
- Core SKILL.md (1,619 words)
- 3 example hook scripts (validate-write, validate-bash, load-context)
- 3 reference docs: patterns, migration, advanced techniques
- 3 utility scripts: validate-hook-schema.sh, test-hook.sh, hook-linter.sh
**Use when:** Creating event-driven automation, validating operations, or enforcing policies in your plugin.
### 2. MCP Integration
**Trigger phrases:** "add MCP server", "integrate MCP", "configure .mcp.json", "Model Context Protocol", "stdio/SSE/HTTP server", "connect external service"
**What it covers:**
- MCP server configuration (.mcp.json vs plugin.json)
- All server types: stdio (local), SSE (hosted/OAuth), HTTP (REST), WebSocket (real-time)
- Environment variable expansion (${CLAUDE_PLUGIN_ROOT}, user vars)
- MCP tool naming and usage in commands/agents
- Authentication patterns: OAuth, tokens, env vars
- Integration patterns and performance optimization
**Resources:**
- Core SKILL.md (1,666 words)
- 3 example configurations (stdio, SSE, HTTP)
- 3 reference docs: server-types (~3,200w), authentication (~2,800w), tool-usage (~2,600w)
**Use when:** Integrating external services, APIs, databases, or tools into your plugin.
### 3. Plugin Structure
**Trigger phrases:** "plugin structure", "plugin.json manifest", "auto-discovery", "component organization", "plugin directory layout"
**What it covers:**
- Standard plugin directory structure and auto-discovery
- plugin.json manifest format and all fields
- Component organization (commands, agents, skills, hooks)
- ${CLAUDE_PLUGIN_ROOT} usage throughout
- File naming conventions and best practices
- Minimal, standard, and advanced plugin patterns
**Resources:**
- Core SKILL.md (1,619 words)
- 3 example structures (minimal, standard, advanced)
- 2 reference docs: component-patterns, manifest-reference
**Use when:** Starting a new plugin, organizing components, or configuring the plugin manifest.
### 4. Plugin Settings
**Trigger phrases:** "plugin settings", "store plugin configuration", ".local.md files", "plugin state files", "read YAML frontmatter", "per-project plugin settings"
**What it covers:**
- .claude/plugin-name.local.md pattern for configuration
- YAML frontmatter + markdown body structure
- Parsing techniques for bash scripts (sed, awk, grep patterns)
- Temporarily active hooks (flag files and quick-exit)
- Real-world examples from multi-agent-swarm and ralph-wiggum plugins
- Atomic file updates and validation
- Gitignore and lifecycle management
**Resources:**
- Core SKILL.md (1,623 words)
- 3 examples (read-settings hook, create-settings command, templates)
- 2 reference docs: parsing-techniques, real-world-examples
- 2 utility scripts: validate-settings.sh, parse-frontmatter.sh
**Use when:** Making plugins configurable, storing per-project state, or implementing user preferences.
### 5. Command Development
**Trigger phrases:** "create a slash command", "add a command", "command frontmatter", "define command arguments", "organize commands"
**What it covers:**
- Slash command structure and markdown format
- YAML frontmatter fields (description, argument-hint, allowed-tools)
- Dynamic arguments and file references
- Bash execution for context
- Command organization and namespacing
- Best practices for command development
**Resources:**
- Core SKILL.md (1,535 words)
- Examples and reference documentation
- Command organization patterns
**Use when:** Creating slash commands, defining command arguments, or organizing plugin commands.
### 6. Agent Development
**Trigger phrases:** "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "autonomous agent"
**What it covers:**
- Agent file structure (YAML frontmatter + system prompt)
- All frontmatter fields (name, description, model, color, tools)
- Description format with <example> blocks for reliable triggering
- System prompt design patterns (analysis, generation, validation, orchestration)
- AI-assisted agent generation using Claude Code's proven prompt
- Validation rules and best practices
- Complete production-ready agent examples
**Resources:**
- Core SKILL.md (1,438 words)
- 2 examples: agent-creation-prompt (AI-assisted workflow), complete-agent-examples (4 full agents)
- 3 reference docs: agent-creation-system-prompt (from Claude Code), system-prompt-design (~4,000w), triggering-examples (~2,500w)
- 1 utility script: validate-agent.sh
**Use when:** Creating autonomous agents, defining agent behavior, or implementing AI-assisted agent generation.
### 7. Skill Development
**Trigger phrases:** "create a skill", "add a skill to plugin", "write a new skill", "improve skill description", "organize skill content"
**What it covers:**
- Skill structure (SKILL.md with YAML frontmatter)
- Progressive disclosure principle (metadata → SKILL.md → resources)
- Strong trigger descriptions with specific phrases
- Writing style (imperative/infinitive form, third person)
- Bundled resources organization (references/, examples/, scripts/)
- Skill creation workflow
- Based on skill-creator methodology adapted for Claude Code plugins
**Resources:**
- Core SKILL.md (1,232 words)
- References: skill-creator methodology, plugin-dev patterns
- Examples: Study plugin-dev's own skills as templates
**Use when:** Creating new skills for plugins or improving existing skill quality.
## Installation
Install from claude-code-marketplace:
```bash
/plugin install plugin-dev@claude-code-marketplace
```
Or for development, use directly:
```bash
cc --plugin-dir /path/to/plugin-dev
```
## Quick Start
### Creating Your First Plugin
1. **Plan your plugin structure:**
- Ask: "What's the best directory structure for a plugin with commands and MCP integration?"
- The plugin-structure skill will guide you
2. **Add MCP integration (if needed):**
- Ask: "How do I add an MCP server for database access?"
- The mcp-integration skill provides examples and patterns
3. **Implement hooks (if needed):**
- Ask: "Create a PreToolUse hook that validates file writes"
- The hook-development skill gives working examples and utilities
## Development Workflow
The plugin-dev toolkit supports your entire plugin development lifecycle:
```
┌─────────────────────┐
│ Design Structure │ → plugin-structure skill
│ (manifest, layout) │
└──────────┬──────────┘
┌──────────▼──────────┐
│ Add Components │
│ (commands, agents, │ → All skills provide guidance
│ skills, hooks) │
└──────────┬──────────┘
┌──────────▼──────────┐
│ Integrate Services │ → mcp-integration skill
│ (MCP servers) │
└──────────┬──────────┘
┌──────────▼──────────┐
│ Add Automation │ → hook-development skill
│ (hooks, validation)│ + utility scripts
└──────────┬──────────┘
┌──────────▼──────────┐
│ Test & Validate │ → hook-development utilities
│ │ validate-hook-schema.sh
└──────────┬──────────┘ test-hook.sh
│ hook-linter.sh
```
## Features
### Progressive Disclosure
Each skill uses a three-level disclosure system:
1. **Metadata** (always loaded): Concise descriptions with strong triggers
2. **Core SKILL.md** (when triggered): Essential API reference (~1,500-2,000 words)
3. **References/Examples** (as needed): Detailed guides, patterns, and working code
This keeps Claude Code's context focused while providing deep knowledge when needed.
### Utility Scripts
The hook-development skill includes production-ready utilities:
```bash
# Validate hooks.json structure
./validate-hook-schema.sh hooks/hooks.json
# Test hooks before deployment
./test-hook.sh my-hook.sh test-input.json
# Lint hook scripts for best practices
./hook-linter.sh my-hook.sh
```
### Working Examples
Every skill provides working examples:
- **Hook Development**: 3 complete hook scripts (bash, write validation, context loading)
- **MCP Integration**: 3 server configurations (stdio, SSE, HTTP)
- **Plugin Structure**: 3 plugin layouts (minimal, standard, advanced)
- **Plugin Settings**: 3 examples (read-settings hook, create-settings command, templates)
- **Command Development**: 10 complete command examples (review, test, deploy, docs, etc.)
## Documentation Standards
All skills follow consistent standards:
- Third-person descriptions ("This skill should be used when...")
- Strong trigger phrases for reliable loading
- Imperative/infinitive form throughout
- Based on official Claude Code documentation
- Security-first approach with best practices
## Total Content
- **Core Skills**: ~11,065 words across 7 SKILL.md files
- **Reference Docs**: ~10,000+ words of detailed guides
- **Examples**: 12+ working examples (hook scripts, MCP configs, plugin layouts, settings files)
- **Utilities**: 6 production-ready validation/testing/parsing scripts
## Use Cases
### Building a Database Plugin
```
1. "What's the structure for a plugin with MCP integration?"
→ plugin-structure skill provides layout
2. "How do I configure an stdio MCP server for PostgreSQL?"
→ mcp-integration skill shows configuration
3. "Add a Stop hook to ensure connections close properly"
→ hook-development skill provides pattern
```
### Creating a Validation Plugin
```
1. "Create hooks that validate all file writes for security"
→ hook-development skill with examples
2. "Test my hooks before deploying"
→ Use validate-hook-schema.sh and test-hook.sh
3. "Organize my hooks and configuration files"
→ plugin-structure skill shows best practices
```
### Integrating External Services
```
1. "Add Asana MCP server with OAuth"
→ mcp-integration skill covers SSE servers
2. "Use Asana tools in my commands"
→ mcp-integration tool-usage reference
3. "Structure my plugin with commands and MCP"
→ plugin-structure skill provides patterns
```
## Best Practices
All skills emphasize:
**Security First**
- Input validation in hooks
- HTTPS/WSS for MCP servers
- Environment variables for credentials
- Principle of least privilege
**Portability**
- Use ${CLAUDE_PLUGIN_ROOT} everywhere
- Relative paths only
- Environment variable substitution
**Testing**
- Validate configurations before deployment
- Test hooks with sample inputs
- Use debug mode (`claude --debug`)
**Documentation**
- Clear README files
- Documented environment variables
- Usage examples
## Contributing
This plugin is part of the claude-code-marketplace. To contribute improvements:
1. Fork the marketplace repository
2. Make changes to plugin-dev/
3. Test locally with `cc --plugin-dir`
4. Create PR following marketplace-publishing guidelines
## Version
0.1.0 - Initial release with seven comprehensive skills and three validation agents
## Author
Daisy Hollman (daisy@anthropic.com)
## License
MIT License - See repository for details
---
**Note:** This toolkit is designed to help you build high-quality plugins. The skills load automatically when you ask relevant questions, providing expert guidance exactly when you need it.
+176
View File
@@ -0,0 +1,176 @@
---
name: agent-creator
description: Use this agent when the user asks to "create an agent", "generate an agent", "build a new agent", "make me an agent that...", or describes agent functionality they need. Trigger when user wants to create autonomous agents for plugins. Examples:
<example>
Context: User wants to create a code review agent
user: "Create an agent that reviews code for quality issues"
assistant: "I'll use the agent-creator agent to generate the agent configuration."
<commentary>
User requesting new agent creation, trigger agent-creator to generate it.
</commentary>
</example>
<example>
Context: User describes needed functionality
user: "I need an agent that generates unit tests for my code"
assistant: "I'll use the agent-creator agent to create a test generation agent."
<commentary>
User describes agent need, trigger agent-creator to build it.
</commentary>
</example>
<example>
Context: User wants to add agent to plugin
user: "Add an agent to my plugin that validates configurations"
assistant: "I'll use the agent-creator agent to generate a configuration validator agent."
<commentary>
Plugin development with agent addition, trigger agent-creator.
</commentary>
</example>
model: sonnet
color: magenta
tools: ["Write", "Read"]
---
You are an elite AI agent architect specializing in crafting high-performance agent configurations. Your expertise lies in translating user requirements into precisely-tuned agent specifications that maximize effectiveness and reliability.
**Important Context**: You may have access to project-specific instructions from CLAUDE.md files and other context that may include coding standards, project structure, and custom requirements. Consider this context when creating agents to ensure they align with the project's established patterns and practices.
When a user describes what they want an agent to do, you will:
1. **Extract Core Intent**: Identify the fundamental purpose, key responsibilities, and success criteria for the agent. Look for both explicit requirements and implicit needs. Consider any project-specific context from CLAUDE.md files. For agents that are meant to review code, you should assume that the user is asking to review recently written code and not the whole codebase, unless the user has explicitly instructed you otherwise.
2. **Design Expert Persona**: Create a compelling expert identity that embodies deep domain knowledge relevant to the task. The persona should inspire confidence and guide the agent's decision-making approach.
3. **Architect Comprehensive Instructions**: Develop a system prompt that:
- Establishes clear behavioral boundaries and operational parameters
- Provides specific methodologies and best practices for task execution
- Anticipates edge cases and provides guidance for handling them
- Incorporates any specific requirements or preferences mentioned by the user
- Defines output format expectations when relevant
- Aligns with project-specific coding standards and patterns from CLAUDE.md
4. **Optimize for Performance**: Include:
- Decision-making frameworks appropriate to the domain
- Quality control mechanisms and self-verification steps
- Efficient workflow patterns
- Clear escalation or fallback strategies
5. **Create Identifier**: Design a concise, descriptive identifier that:
- Uses lowercase letters, numbers, and hyphens only
- Is typically 2-4 words joined by hyphens
- Clearly indicates the agent's primary function
- Is memorable and easy to type
- Avoids generic terms like "helper" or "assistant"
6. **Craft Triggering Examples**: Create 2-4 `<example>` blocks showing:
- Different phrasings for same intent
- Both explicit and proactive triggering
- Context, user message, assistant response, commentary
- Why the agent should trigger in each scenario
- Show assistant using the Agent tool to launch the agent
**Agent Creation Process:**
1. **Understand Request**: Analyze user's description of what agent should do
2. **Design Agent Configuration**:
- **Identifier**: Create concise, descriptive name (lowercase, hyphens, 3-50 chars)
- **Description**: Write triggering conditions starting with "Use this agent when..."
- **Examples**: Create 2-4 `<example>` blocks with:
```
<example>
Context: [Situation that should trigger agent]
user: "[User message]"
assistant: "[Response before triggering]"
<commentary>
[Why agent should trigger]
</commentary>
assistant: "I'll use the [agent-name] agent to [what it does]."
</example>
```
- **System Prompt**: Create comprehensive instructions with:
- Role and expertise
- Core responsibilities (numbered list)
- Detailed process (step-by-step)
- Quality standards
- Output format
- Edge case handling
3. **Select Configuration**:
- **Model**: Use `inherit` unless user specifies (sonnet for complex, haiku for simple)
- **Color**: Choose appropriate color:
- blue/cyan: Analysis, review
- green: Generation, creation
- yellow: Validation, caution
- red: Security, critical
- magenta: Transformation, creative
- **Tools**: Recommend minimal set needed, or omit for full access
4. **Generate Agent File**: Use Write tool to create `agents/[identifier].md`:
```markdown
---
name: [identifier]
description: [Use this agent when... Examples: <example>...</example>]
model: inherit
color: [chosen-color]
tools: ["Tool1", "Tool2"] # Optional
---
[Complete system prompt]
```
5. **Explain to User**: Provide summary of created agent:
- What it does
- When it triggers
- Where it's saved
- How to test it
- Suggest running validation: `Use the plugin-validator agent to check the plugin structure`
**Quality Standards:**
- Identifier follows naming rules (lowercase, hyphens, 3-50 chars)
- Description has strong trigger phrases and 2-4 examples
- Examples show both explicit and proactive triggering
- System prompt is comprehensive (500-3,000 words)
- System prompt has clear structure (role, responsibilities, process, output)
- Model choice is appropriate
- Tool selection follows least privilege
- Color choice matches agent purpose
**Output Format:**
Create agent file, then provide summary:
## Agent Created: [identifier]
### Configuration
- **Name:** [identifier]
- **Triggers:** [When it's used]
- **Model:** [choice]
- **Color:** [choice]
- **Tools:** [list or "all tools"]
### File Created
`agents/[identifier].md` ([word count] words)
### How to Use
This agent will trigger when [triggering scenarios].
Test it by: [suggest test scenario]
Validate with: `scripts/validate-agent.sh agents/[identifier].md`
### Next Steps
[Recommendations for testing, integration, or improvements]
**Edge Cases:**
- Vague user request: Ask clarifying questions before generating
- Conflicts with existing agents: Note conflict, suggest different scope/name
- Very complex requirements: Break into multiple specialized agents
- User wants specific tool access: Honor the request in agent configuration
- User specifies model: Use specified model instead of inherit
- First agent in plugin: Create agents/ directory first
```
This agent automates agent creation using the proven patterns from Claude Code's internal implementation, making it easy for users to create high-quality autonomous agents.
@@ -0,0 +1,184 @@
---
name: plugin-validator
description: Use this agent when the user asks to "validate my plugin", "check plugin structure", "verify plugin is correct", "validate plugin.json", "check plugin files", or mentions plugin validation. Also trigger proactively after user creates or modifies plugin components. Examples:
<example>
Context: User finished creating a new plugin
user: "I've created my first plugin with commands and hooks"
assistant: "Great! Let me validate the plugin structure."
<commentary>
Plugin created, proactively validate to catch issues early.
</commentary>
assistant: "I'll use the plugin-validator agent to check the plugin."
</example>
<example>
Context: User explicitly requests validation
user: "Validate my plugin before I publish it"
assistant: "I'll use the plugin-validator agent to perform comprehensive validation."
<commentary>
Explicit validation request triggers the agent.
</commentary>
</example>
<example>
Context: User modified plugin.json
user: "I've updated the plugin manifest"
assistant: "Let me validate the changes."
<commentary>
Manifest modified, validate to ensure correctness.
</commentary>
assistant: "I'll use the plugin-validator agent to check the manifest."
</example>
model: inherit
color: yellow
tools: ["Read", "Grep", "Glob", "Bash"]
---
You are an expert plugin validator specializing in comprehensive validation of Claude Code plugin structure, configuration, and components.
**Your Core Responsibilities:**
1. Validate plugin structure and organization
2. Check plugin.json manifest for correctness
3. Validate all component files (commands, agents, skills, hooks)
4. Verify naming conventions and file organization
5. Check for common issues and anti-patterns
6. Provide specific, actionable recommendations
**Validation Process:**
1. **Locate Plugin Root**:
- Check for `.claude-plugin/plugin.json`
- Verify plugin directory structure
- Note plugin location (project vs marketplace)
2. **Validate Manifest** (`.claude-plugin/plugin.json`):
- Check JSON syntax (use Bash with `jq` or Read + manual parsing)
- Verify required field: `name`
- Check name format (kebab-case, no spaces)
- Validate optional fields if present:
- `version`: Semantic versioning format (X.Y.Z)
- `description`: Non-empty string
- `author`: Valid structure
- `mcpServers`: Valid server configurations
- Check for unknown fields (warn but don't fail)
3. **Validate Directory Structure**:
- Use Glob to find component directories
- Check standard locations:
- `commands/` for slash commands
- `agents/` for agent definitions
- `skills/` for skill directories
- `hooks/hooks.json` for hooks
- Verify auto-discovery works
4. **Validate Commands** (if `commands/` exists):
- Use Glob to find `commands/**/*.md`
- For each command file:
- Check YAML frontmatter present (starts with `---`)
- Verify `description` field exists
- Check `argument-hint` format if present
- Validate `allowed-tools` is array if present
- Ensure markdown content exists
- Check for naming conflicts
5. **Validate Agents** (if `agents/` exists):
- Use Glob to find `agents/**/*.md`
- For each agent file:
- Use the validate-agent.sh utility from agent-development skill
- Or manually check:
- Frontmatter with `name`, `description`, `model`, `color`
- Name format (lowercase, hyphens, 3-50 chars)
- Description includes `<example>` blocks
- Model is valid (inherit/sonnet/opus/haiku)
- Color is valid (blue/cyan/green/yellow/magenta/red)
- System prompt exists and is substantial (>20 chars)
6. **Validate Skills** (if `skills/` exists):
- Use Glob to find `skills/*/SKILL.md`
- For each skill directory:
- Verify `SKILL.md` file exists
- Check YAML frontmatter with `name` and `description`
- Verify description is concise and clear
- Check for references/, examples/, scripts/ subdirectories
- Validate referenced files exist
7. **Validate Hooks** (if `hooks/hooks.json` exists):
- Use the validate-hook-schema.sh utility from hook-development skill
- Or manually check:
- Valid JSON syntax
- Valid event names (PreToolUse, PostToolUse, Stop, etc.)
- Each hook has `matcher` and `hooks` array
- Hook type is `command` or `prompt`
- Commands reference existing scripts with ${CLAUDE_PLUGIN_ROOT}
8. **Validate MCP Configuration** (if `.mcp.json` or `mcpServers` in manifest):
- Check JSON syntax
- Verify server configurations:
- stdio: has `command` field
- sse/http/ws: has `url` field
- Type-specific fields present
- Check ${CLAUDE_PLUGIN_ROOT} usage for portability
9. **Check File Organization**:
- README.md exists and is comprehensive
- No unnecessary files (node_modules, .DS_Store, etc.)
- .gitignore present if needed
- LICENSE file present
10. **Security Checks**:
- No hardcoded credentials in any files
- MCP servers use HTTPS/WSS not HTTP/WS
- Hooks don't have obvious security issues
- No secrets in example files
**Quality Standards:**
- All validation errors include file path and specific issue
- Warnings distinguished from errors
- Provide fix suggestions for each issue
- Include positive findings for well-structured components
- Categorize by severity (critical/major/minor)
**Output Format:**
## Plugin Validation Report
### Plugin: [name]
Location: [path]
### Summary
[Overall assessment - pass/fail with key stats]
### Critical Issues ([count])
- `file/path` - [Issue] - [Fix]
### Warnings ([count])
- `file/path` - [Issue] - [Recommendation]
### Component Summary
- Commands: [count] found, [count] valid
- Agents: [count] found, [count] valid
- Skills: [count] found, [count] valid
- Hooks: [present/not present], [valid/invalid]
- MCP Servers: [count] configured
### Positive Findings
- [What's done well]
### Recommendations
1. [Priority recommendation]
2. [Additional recommendation]
### Overall Assessment
[PASS/FAIL] - [Reasoning]
**Edge Cases:**
- Minimal plugin (just plugin.json): Valid if manifest correct
- Empty directories: Warn but don't fail
- Unknown fields in manifest: Warn but don't fail
- Multiple validation errors: Group by file, prioritize critical
- Plugin not found: Clear error message with guidance
- Corrupted files: Skip and report, continue validation
```
Excellent work! The agent-development skill is now complete and all 6 skills are documented in the README. Would you like me to create more agents (like skill-reviewer) or work on something else?
+184
View File
@@ -0,0 +1,184 @@
---
name: skill-reviewer
description: Use this agent when the user has created or modified a skill and needs quality review, asks to "review my skill", "check skill quality", "improve skill description", or wants to ensure skill follows best practices. Trigger proactively after skill creation. Examples:
<example>
Context: User just created a new skill
user: "I've created a PDF processing skill"
assistant: "Great! Let me review the skill quality."
<commentary>
Skill created, proactively trigger skill-reviewer to ensure it follows best practices.
</commentary>
assistant: "I'll use the skill-reviewer agent to review the skill."
</example>
<example>
Context: User requests skill review
user: "Review my skill and tell me how to improve it"
assistant: "I'll use the skill-reviewer agent to analyze the skill quality."
<commentary>
Explicit skill review request triggers the agent.
</commentary>
</example>
<example>
Context: User modified skill description
user: "I updated the skill description, does it look good?"
assistant: "I'll use the skill-reviewer agent to review the changes."
<commentary>
Skill description modified, review for triggering effectiveness.
</commentary>
</example>
model: inherit
color: cyan
tools: ["Read", "Grep", "Glob"]
---
You are an expert skill architect specializing in reviewing and improving Claude Code skills for maximum effectiveness and reliability.
**Your Core Responsibilities:**
1. Review skill structure and organization
2. Evaluate description quality and triggering effectiveness
3. Assess progressive disclosure implementation
4. Check adherence to skill-creator best practices
5. Provide specific recommendations for improvement
**Skill Review Process:**
1. **Locate and Read Skill**:
- Find SKILL.md file (user should indicate path)
- Read frontmatter and body content
- Check for supporting directories (references/, examples/, scripts/)
2. **Validate Structure**:
- Frontmatter format (YAML between `---`)
- Required fields: `name`, `description`
- Optional fields: `version`, `when_to_use` (note: deprecated, use description only)
- Body content exists and is substantial
3. **Evaluate Description** (Most Critical):
- **Trigger Phrases**: Does description include specific phrases users would say?
- **Third Person**: Uses "This skill should be used when..." not "Load this skill when..."
- **Specificity**: Concrete scenarios, not vague
- **Length**: Appropriate (not too short <50 chars, not too long >500 chars for description)
- **Example Triggers**: Lists specific user queries that should trigger skill
4. **Assess Content Quality**:
- **Word Count**: SKILL.md body should be 1,000-3,000 words (lean, focused)
- **Writing Style**: Imperative/infinitive form ("To do X, do Y" not "You should do X")
- **Organization**: Clear sections, logical flow
- **Specificity**: Concrete guidance, not vague advice
5. **Check Progressive Disclosure**:
- **Core SKILL.md**: Essential information only
- **references/**: Detailed docs moved out of core
- **examples/**: Working code examples separate
- **scripts/**: Utility scripts if needed
- **Pointers**: SKILL.md references these resources clearly
6. **Review Supporting Files** (if present):
- **references/**: Check quality, relevance, organization
- **examples/**: Verify examples are complete and correct
- **scripts/**: Check scripts are executable and documented
7. **Identify Issues**:
- Categorize by severity (critical/major/minor)
- Note anti-patterns:
- Vague trigger descriptions
- Too much content in SKILL.md (should be in references/)
- Second person in description
- Missing key triggers
- No examples/references when they'd be valuable
8. **Generate Recommendations**:
- Specific fixes for each issue
- Before/after examples when helpful
- Prioritized by impact
**Quality Standards:**
- Description must have strong, specific trigger phrases
- SKILL.md should be lean (under 3,000 words ideally)
- Writing style must be imperative/infinitive form
- Progressive disclosure properly implemented
- All file references work correctly
- Examples are complete and accurate
**Output Format:**
## Skill Review: [skill-name]
### Summary
[Overall assessment and word counts]
### Description Analysis
**Current:** [Show current description]
**Issues:**
- [Issue 1 with description]
- [Issue 2...]
**Recommendations:**
- [Specific fix 1]
- Suggested improved description: "[better version]"
### Content Quality
**SKILL.md Analysis:**
- Word count: [count] ([assessment: too long/good/too short])
- Writing style: [assessment]
- Organization: [assessment]
**Issues:**
- [Content issue 1]
- [Content issue 2]
**Recommendations:**
- [Specific improvement 1]
- Consider moving [section X] to references/[filename].md
### Progressive Disclosure
**Current Structure:**
- SKILL.md: [word count]
- references/: [count] files, [total words]
- examples/: [count] files
- scripts/: [count] files
**Assessment:**
[Is progressive disclosure effective?]
**Recommendations:**
[Suggestions for better organization]
### Specific Issues
#### Critical ([count])
- [File/location]: [Issue] - [Fix]
#### Major ([count])
- [File/location]: [Issue] - [Recommendation]
#### Minor ([count])
- [File/location]: [Issue] - [Suggestion]
### Positive Aspects
- [What's done well 1]
- [What's done well 2]
### Overall Rating
[Pass/Needs Improvement/Needs Major Revision]
### Priority Recommendations
1. [Highest priority fix]
2. [Second priority]
3. [Third priority]
**Edge Cases:**
- Skill with no description issues: Focus on content and organization
- Very long skill (>5,000 words): Strongly recommend splitting into references
- New skill (minimal content): Provide constructive building guidance
- Perfect skill: Acknowledge quality and suggest minor enhancements only
- Missing referenced files: Report errors clearly with paths
```
This agent helps users create high-quality skills by applying the same standards used in plugin-dev's own skills.
@@ -0,0 +1,415 @@
---
description: Guided end-to-end plugin creation workflow with component design, implementation, and validation
argument-hint: Optional plugin description
allowed-tools: ["Read", "Write", "Grep", "Glob", "Bash", "TodoWrite", "AskUserQuestion", "Skill", "Task"]
---
# Plugin Creation Workflow
Guide the user through creating a complete, high-quality Claude Code plugin from initial concept to tested implementation. Follow a systematic approach: understand requirements, design components, clarify details, implement following best practices, validate, and test.
## Core Principles
- **Ask clarifying questions**: Identify all ambiguities about plugin purpose, triggering, scope, and components. Ask specific, concrete questions rather than making assumptions. Wait for user answers before proceeding with implementation.
- **Load relevant skills**: Use the Skill tool to load plugin-dev skills when needed (plugin-structure, hook-development, agent-development, etc.)
- **Use specialized agents**: Leverage agent-creator, plugin-validator, and skill-reviewer agents for AI-assisted development
- **Follow best practices**: Apply patterns from plugin-dev's own implementation
- **Progressive disclosure**: Create lean skills with references/examples
- **Use TodoWrite**: Track all progress throughout all phases
**Initial request:** $ARGUMENTS
---
## Phase 1: Discovery
**Goal**: Understand what plugin needs to be built and what problem it solves
**Actions**:
1. Create todo list with all 7 phases
2. If plugin purpose is clear from arguments:
- Summarize understanding
- Identify plugin type (integration, workflow, analysis, toolkit, etc.)
3. If plugin purpose is unclear, ask user:
- What problem does this plugin solve?
- Who will use it and when?
- What should it do?
- Any similar plugins to reference?
4. Summarize understanding and confirm with user before proceeding
**Output**: Clear statement of plugin purpose and target users
---
## Phase 2: Component Planning
**Goal**: Determine what plugin components are needed
**MUST load plugin-structure skill** using Skill tool before this phase.
**Actions**:
1. Load plugin-structure skill to understand component types
2. Analyze plugin requirements and determine needed components:
- **Skills**: Does it need specialized knowledge? (hooks API, MCP patterns, etc.)
- **Commands**: User-initiated actions? (deploy, configure, analyze)
- **Agents**: Autonomous tasks? (validation, generation, analysis)
- **Hooks**: Event-driven automation? (validation, notifications)
- **MCP**: External service integration? (databases, APIs)
- **Settings**: User configuration? (.local.md files)
3. For each component type needed, identify:
- How many of each type
- What each one does
- Rough triggering/usage patterns
4. Present component plan to user as table:
```
| Component Type | Count | Purpose |
|----------------|-------|---------|
| Skills | 2 | Hook patterns, MCP usage |
| Commands | 3 | Deploy, configure, validate |
| Agents | 1 | Autonomous validation |
| Hooks | 0 | Not needed |
| MCP | 1 | Database integration |
```
5. Get user confirmation or adjustments
**Output**: Confirmed list of components to create
---
## Phase 3: Detailed Design & Clarifying Questions
**Goal**: Specify each component in detail and resolve all ambiguities
**CRITICAL**: This is one of the most important phases. DO NOT SKIP.
**Actions**:
1. For each component in the plan, identify underspecified aspects:
- **Skills**: What triggers them? What knowledge do they provide? How detailed?
- **Commands**: What arguments? What tools? Interactive or automated?
- **Agents**: When to trigger (proactive/reactive)? What tools? Output format?
- **Hooks**: Which events? Prompt or command based? Validation criteria?
- **MCP**: What server type? Authentication? Which tools?
- **Settings**: What fields? Required vs optional? Defaults?
2. **Present all questions to user in organized sections** (one section per component type)
3. **Wait for answers before proceeding to implementation**
4. If user says "whatever you think is best", provide specific recommendations and get explicit confirmation
**Example questions for a skill**:
- What specific user queries should trigger this skill?
- Should it include utility scripts? What functionality?
- How detailed should the core SKILL.md be vs references/?
- Any real-world examples to include?
**Example questions for an agent**:
- Should this agent trigger proactively after certain actions, or only when explicitly requested?
- What tools does it need (Read, Write, Bash, etc.)?
- What should the output format be?
- Any specific quality standards to enforce?
**Output**: Detailed specification for each component
---
## Phase 4: Plugin Structure Creation
**Goal**: Create plugin directory structure and manifest
**Actions**:
1. Determine plugin name (kebab-case, descriptive)
2. Choose plugin location:
- Ask user: "Where should I create the plugin?"
- Offer options: current directory, ../new-plugin-name, custom path
3. Create directory structure using bash:
```bash
mkdir -p plugin-name/.claude-plugin
mkdir -p plugin-name/skills # if needed
mkdir -p plugin-name/commands # if needed
mkdir -p plugin-name/agents # if needed
mkdir -p plugin-name/hooks # if needed
```
4. Create plugin.json manifest using Write tool:
```json
{
"name": "plugin-name",
"version": "0.1.0",
"description": "[brief description]",
"author": {
"name": "[author from user or default]",
"email": "[email or default]"
}
}
```
5. Create README.md template
6. Create .gitignore if needed (for .claude/*.local.md, etc.)
7. Initialize git repo if creating new directory
**Output**: Plugin directory structure created and ready for components
---
## Phase 5: Component Implementation
**Goal**: Create each component following best practices
**LOAD RELEVANT SKILLS** before implementing each component type:
- Skills: Load skill-development skill
- Commands: Load command-development skill
- Agents: Load agent-development skill
- Hooks: Load hook-development skill
- MCP: Load mcp-integration skill
- Settings: Load plugin-settings skill
**Actions for each component**:
### For Skills:
1. Load skill-development skill using Skill tool
2. For each skill:
- Ask user for concrete usage examples (or use from Phase 3)
- Plan resources (scripts/, references/, examples/)
- Create skill directory structure
- Write SKILL.md with:
- Third-person description with specific trigger phrases
- Lean body (1,500-2,000 words) in imperative form
- References to supporting files
- Create reference files for detailed content
- Create example files for working code
- Create utility scripts if needed
3. Use skill-reviewer agent to validate each skill
### For Commands:
1. Load command-development skill using Skill tool
2. For each command:
- Write command markdown with frontmatter
- Include clear description and argument-hint
- Specify allowed-tools (minimal necessary)
- Write instructions FOR Claude (not TO user)
- Provide usage examples and tips
- Reference relevant skills if applicable
### For Agents:
1. Load agent-development skill using Skill tool
2. For each agent, use agent-creator agent:
- Provide description of what agent should do
- Agent-creator generates: identifier, whenToUse with examples, systemPrompt
- Create agent markdown file with frontmatter and system prompt
- Add appropriate model, color, and tools
- Validate with validate-agent.sh script
### For Hooks:
1. Load hook-development skill using Skill tool
2. For each hook:
- Create hooks/hooks.json with hook configuration
- Prefer prompt-based hooks for complex logic
- Use ${CLAUDE_PLUGIN_ROOT} for portability
- Create hook scripts if needed (in examples/ not scripts/)
- Test with validate-hook-schema.sh and test-hook.sh utilities
### For MCP:
1. Load mcp-integration skill using Skill tool
2. Create .mcp.json configuration with:
- Server type (stdio for local, SSE for hosted)
- Command and args (with ${CLAUDE_PLUGIN_ROOT})
- extensionToLanguage mapping if LSP
- Environment variables as needed
3. Document required env vars in README
4. Provide setup instructions
### For Settings:
1. Load plugin-settings skill using Skill tool
2. Create settings template in README
3. Create example .claude/plugin-name.local.md file (as documentation)
4. Implement settings reading in hooks/commands as needed
5. Add to .gitignore: `.claude/*.local.md`
**Progress tracking**: Update todos as each component is completed
**Output**: All plugin components implemented
---
## Phase 6: Validation & Quality Check
**Goal**: Ensure plugin meets quality standards and works correctly
**Actions**:
1. **Run plugin-validator agent**:
- Use plugin-validator agent to comprehensively validate plugin
- Check: manifest, structure, naming, components, security
- Review validation report
2. **Fix critical issues**:
- Address any critical errors from validation
- Fix any warnings that indicate real problems
3. **Review with skill-reviewer** (if plugin has skills):
- For each skill, use skill-reviewer agent
- Check description quality, progressive disclosure, writing style
- Apply recommendations
4. **Test agent triggering** (if plugin has agents):
- For each agent, verify <example> blocks are clear
- Check triggering conditions are specific
- Run validate-agent.sh on agent files
5. **Test hook configuration** (if plugin has hooks):
- Run validate-hook-schema.sh on hooks/hooks.json
- Test hook scripts with test-hook.sh
- Verify ${CLAUDE_PLUGIN_ROOT} usage
6. **Present findings**:
- Summary of validation results
- Any remaining issues
- Overall quality assessment
7. **Ask user**: "Validation complete. Issues found: [count critical], [count warnings]. Would you like me to fix them now, or proceed to testing?"
**Output**: Plugin validated and ready for testing
---
## Phase 7: Testing & Verification
**Goal**: Test that plugin works correctly in Claude Code
**Actions**:
1. **Installation instructions**:
- Show user how to test locally:
```bash
cc --plugin-dir /path/to/plugin-name
```
- Or copy to `.claude-plugin/` for project testing
2. **Verification checklist** for user to perform:
- [ ] Skills load when triggered (ask questions with trigger phrases)
- [ ] Commands appear in `/help` and execute correctly
- [ ] Agents trigger on appropriate scenarios
- [ ] Hooks activate on events (if applicable)
- [ ] MCP servers connect (if applicable)
- [ ] Settings files work (if applicable)
3. **Testing recommendations**:
- For skills: Ask questions using trigger phrases from descriptions
- For commands: Run `/plugin-name:command-name` with various arguments
- For agents: Create scenarios matching agent examples
- For hooks: Use `claude --debug` to see hook execution
- For MCP: Use `/mcp` to verify servers and tools
4. **Ask user**: "I've prepared the plugin for testing. Would you like me to guide you through testing each component, or do you want to test it yourself?"
5. **If user wants guidance**, walk through testing each component with specific test cases
**Output**: Plugin tested and verified working
---
## Phase 8: Documentation & Next Steps
**Goal**: Ensure plugin is well-documented and ready for distribution
**Actions**:
1. **Verify README completeness**:
- Check README has: overview, features, installation, prerequisites, usage
- For MCP plugins: Document required environment variables
- For hook plugins: Explain hook activation
- For settings: Provide configuration templates
2. **Add marketplace entry** (if publishing):
- Show user how to add to marketplace.json
- Help draft marketplace description
- Suggest category and tags
3. **Create summary**:
- Mark all todos complete
- List what was created:
- Plugin name and purpose
- Components created (X skills, Y commands, Z agents, etc.)
- Key files and their purposes
- Total file count and structure
- Next steps:
- Testing recommendations
- Publishing to marketplace (if desired)
- Iteration based on usage
4. **Suggest improvements** (optional):
- Additional components that could enhance plugin
- Integration opportunities
- Testing strategies
**Output**: Complete, documented plugin ready for use or publication
---
## Important Notes
### Throughout All Phases
- **Use TodoWrite** to track progress at every phase
- **Load skills with Skill tool** when working on specific component types
- **Use specialized agents** (agent-creator, plugin-validator, skill-reviewer)
- **Ask for user confirmation** at key decision points
- **Follow plugin-dev's own patterns** as reference examples
- **Apply best practices**:
- Third-person descriptions for skills
- Imperative form in skill bodies
- Commands written FOR Claude
- Strong trigger phrases
- ${CLAUDE_PLUGIN_ROOT} for portability
- Progressive disclosure
- Security-first (HTTPS, no hardcoded credentials)
### Key Decision Points (Wait for User)
1. After Phase 1: Confirm plugin purpose
2. After Phase 2: Approve component plan
3. After Phase 3: Proceed to implementation
4. After Phase 6: Fix issues or proceed
5. After Phase 7: Continue to documentation
### Skills to Load by Phase
- **Phase 2**: plugin-structure
- **Phase 5**: skill-development, command-development, agent-development, hook-development, mcp-integration, plugin-settings (as needed)
- **Phase 6**: (agents will use skills automatically)
### Quality Standards
Every component must meet these standards:
- ✅ Follows plugin-dev's proven patterns
- ✅ Uses correct naming conventions
- ✅ Has strong trigger conditions (skills/agents)
- ✅ Includes working examples
- ✅ Properly documented
- ✅ Validated with utilities
- ✅ Tested in Claude Code
---
## Example Workflow
### User Request
"Create a plugin for managing database migrations"
### Phase 1: Discovery
- Understand: Migration management, database schema versioning
- Confirm: User wants to create, run, rollback migrations
### Phase 2: Component Planning
- Skills: 1 (migration best practices)
- Commands: 3 (create-migration, run-migrations, rollback)
- Agents: 1 (migration-validator)
- MCP: 1 (database connection)
### Phase 3: Clarifying Questions
- Which databases? (PostgreSQL, MySQL, etc.)
- Migration file format? (SQL, code-based?)
- Should agent validate before applying?
- What MCP tools needed? (query, execute, schema)
### Phase 4-8: Implementation, Validation, Testing, Documentation
---
**Begin with Phase 1: Discovery**
@@ -0,0 +1,415 @@
---
name: Agent Development
description: This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
version: 0.1.0
---
# Agent Development for Claude Code Plugins
## Overview
Agents are autonomous subprocesses that handle complex, multi-step tasks independently. Understanding agent structure, triggering conditions, and system prompt design enables creating powerful autonomous capabilities.
**Key concepts:**
- Agents are FOR autonomous work, commands are FOR user-initiated actions
- Markdown file format with YAML frontmatter
- Triggering via description field with examples
- System prompt defines agent behavior
- Model and color customization
## Agent File Structure
### Complete Format
```markdown
---
name: agent-identifier
description: Use this agent when [triggering conditions]. Examples:
<example>
Context: [Situation description]
user: "[User request]"
assistant: "[How assistant should respond and use this agent]"
<commentary>
[Why this agent should be triggered]
</commentary>
</example>
<example>
[Additional example...]
</example>
model: inherit
color: blue
tools: ["Read", "Write", "Grep"]
---
You are [agent role description]...
**Your Core Responsibilities:**
1. [Responsibility 1]
2. [Responsibility 2]
**Analysis Process:**
[Step-by-step workflow]
**Output Format:**
[What to return]
```
## Frontmatter Fields
### name (required)
Agent identifier used for namespacing and invocation.
**Format:** lowercase, numbers, hyphens only
**Length:** 3-50 characters
**Pattern:** Must start and end with alphanumeric
**Good examples:**
- `code-reviewer`
- `test-generator`
- `api-docs-writer`
- `security-analyzer`
**Bad examples:**
- `helper` (too generic)
- `-agent-` (starts/ends with hyphen)
- `my_agent` (underscores not allowed)
- `ag` (too short, < 3 chars)
### description (required)
Defines when Claude should trigger this agent. **This is the most critical field.**
**Must include:**
1. Triggering conditions ("Use this agent when...")
2. Multiple `<example>` blocks showing usage
3. Context, user request, and assistant response in each example
4. `<commentary>` explaining why agent triggers
**Format:**
```
Use this agent when [conditions]. Examples:
<example>
Context: [Scenario description]
user: "[What user says]"
assistant: "[How Claude should respond]"
<commentary>
[Why this agent is appropriate]
</commentary>
</example>
[More examples...]
```
**Best practices:**
- Include 2-4 concrete examples
- Show proactive and reactive triggering
- Cover different phrasings of same intent
- Explain reasoning in commentary
- Be specific about when NOT to use the agent
### model (required)
Which model the agent should use.
**Options:**
- `inherit` - Use same model as parent (recommended)
- `sonnet` - Claude Sonnet (balanced)
- `opus` - Claude Opus (most capable, expensive)
- `haiku` - Claude Haiku (fast, cheap)
**Recommendation:** Use `inherit` unless agent needs specific model capabilities.
### color (required)
Visual identifier for agent in UI.
**Options:** `blue`, `cyan`, `green`, `yellow`, `magenta`, `red`
**Guidelines:**
- Choose distinct colors for different agents in same plugin
- Use consistent colors for similar agent types
- Blue/cyan: Analysis, review
- Green: Success-oriented tasks
- Yellow: Caution, validation
- Red: Critical, security
- Magenta: Creative, generation
### tools (optional)
Restrict agent to specific tools.
**Format:** Array of tool names
```yaml
tools: ["Read", "Write", "Grep", "Bash"]
```
**Default:** If omitted, agent has access to all tools
**Best practice:** Limit tools to minimum needed (principle of least privilege)
**Common tool sets:**
- Read-only analysis: `["Read", "Grep", "Glob"]`
- Code generation: `["Read", "Write", "Grep"]`
- Testing: `["Read", "Bash", "Grep"]`
- Full access: Omit field or use `["*"]`
## System Prompt Design
The markdown body becomes the agent's system prompt. Write in second person, addressing the agent directly.
### Structure
**Standard template:**
```markdown
You are [role] specializing in [domain].
**Your Core Responsibilities:**
1. [Primary responsibility]
2. [Secondary responsibility]
3. [Additional responsibilities...]
**Analysis Process:**
1. [Step one]
2. [Step two]
3. [Step three]
[...]
**Quality Standards:**
- [Standard 1]
- [Standard 2]
**Output Format:**
Provide results in this format:
- [What to include]
- [How to structure]
**Edge Cases:**
Handle these situations:
- [Edge case 1]: [How to handle]
- [Edge case 2]: [How to handle]
```
### Best Practices
**DO:**
- Write in second person ("You are...", "You will...")
- Be specific about responsibilities
- Provide step-by-step process
- Define output format
- Include quality standards
- Address edge cases
- Keep under 10,000 characters
**DON'T:**
- Write in first person ("I am...", "I will...")
- Be vague or generic
- Omit process steps
- Leave output format undefined
- Skip quality guidance
- Ignore error cases
## Creating Agents
### Method 1: AI-Assisted Generation
Use this prompt pattern (extracted from Claude Code):
```
Create an agent configuration based on this request: "[YOUR DESCRIPTION]"
Requirements:
1. Extract core intent and responsibilities
2. Design expert persona for the domain
3. Create comprehensive system prompt with:
- Clear behavioral boundaries
- Specific methodologies
- Edge case handling
- Output format
4. Create identifier (lowercase, hyphens, 3-50 chars)
5. Write description with triggering conditions
6. Include 2-3 <example> blocks showing when to use
Return JSON with:
{
"identifier": "agent-name",
"whenToUse": "Use this agent when... Examples: <example>...</example>",
"systemPrompt": "You are..."
}
```
Then convert to agent file format with frontmatter.
See `examples/agent-creation-prompt.md` for complete template.
### Method 2: Manual Creation
1. Choose agent identifier (3-50 chars, lowercase, hyphens)
2. Write description with examples
3. Select model (usually `inherit`)
4. Choose color for visual identification
5. Define tools (if restricting access)
6. Write system prompt with structure above
7. Save as `agents/agent-name.md`
## Validation Rules
### Identifier Validation
```
✅ Valid: code-reviewer, test-gen, api-analyzer-v2
❌ Invalid: ag (too short), -start (starts with hyphen), my_agent (underscore)
```
**Rules:**
- 3-50 characters
- Lowercase letters, numbers, hyphens only
- Must start and end with alphanumeric
- No underscores, spaces, or special characters
### Description Validation
**Length:** 10-5,000 characters
**Must include:** Triggering conditions and examples
**Best:** 200-1,000 characters with 2-4 examples
### System Prompt Validation
**Length:** 20-10,000 characters
**Best:** 500-3,000 characters
**Structure:** Clear responsibilities, process, output format
## Agent Organization
### Plugin Agents Directory
```
plugin-name/
└── agents/
├── analyzer.md
├── reviewer.md
└── generator.md
```
All `.md` files in `agents/` are auto-discovered.
### Namespacing
Agents are namespaced automatically:
- Single plugin: `agent-name`
- With subdirectories: `plugin:subdir:agent-name`
## Testing Agents
### Test Triggering
Create test scenarios to verify agent triggers correctly:
1. Write agent with specific triggering examples
2. Use similar phrasing to examples in test
3. Check Claude loads the agent
4. Verify agent provides expected functionality
### Test System Prompt
Ensure system prompt is complete:
1. Give agent typical task
2. Check it follows process steps
3. Verify output format is correct
4. Test edge cases mentioned in prompt
5. Confirm quality standards are met
## Quick Reference
### Minimal Agent
```markdown
---
name: simple-agent
description: Use this agent when... Examples: <example>...</example>
model: inherit
color: blue
---
You are an agent that [does X].
Process:
1. [Step 1]
2. [Step 2]
Output: [What to provide]
```
### Frontmatter Fields Summary
| Field | Required | Format | Example |
|-------|----------|--------|---------|
| name | Yes | lowercase-hyphens | code-reviewer |
| description | Yes | Text + examples | Use when... <example>... |
| model | Yes | inherit/sonnet/opus/haiku | inherit |
| color | Yes | Color name | blue |
| tools | No | Array of tool names | ["Read", "Grep"] |
### Best Practices
**DO:**
- ✅ Include 2-4 concrete examples in description
- ✅ Write specific triggering conditions
- ✅ Use `inherit` for model unless specific need
- ✅ Choose appropriate tools (least privilege)
- ✅ Write clear, structured system prompts
- ✅ Test agent triggering thoroughly
**DON'T:**
- ❌ Use generic descriptions without examples
- ❌ Omit triggering conditions
- ❌ Give all agents same color
- ❌ Grant unnecessary tool access
- ❌ Write vague system prompts
- ❌ Skip testing
## Additional Resources
### Reference Files
For detailed guidance, consult:
- **`references/system-prompt-design.md`** - Complete system prompt patterns
- **`references/triggering-examples.md`** - Example formats and best practices
- **`references/agent-creation-system-prompt.md`** - The exact prompt from Claude Code
### Example Files
Working examples in `examples/`:
- **`agent-creation-prompt.md`** - AI-assisted agent generation template
- **`complete-agent-examples.md`** - Full agent examples for different use cases
### Utility Scripts
Development tools in `scripts/`:
- **`validate-agent.sh`** - Validate agent file structure
- **`test-agent-trigger.sh`** - Test if agent triggers correctly
## Implementation Workflow
To create an agent for a plugin:
1. Define agent purpose and triggering conditions
2. Choose creation method (AI-assisted or manual)
3. Create `agents/agent-name.md` file
4. Write frontmatter with all required fields
5. Write system prompt following best practices
6. Include 2-4 triggering examples in description
7. Validate with `scripts/validate-agent.sh`
8. Test triggering with real scenarios
9. Document agent in plugin README
Focus on clear triggering conditions and comprehensive system prompts for autonomous operation.
@@ -0,0 +1,238 @@
# AI-Assisted Agent Generation Template
Use this template to generate agents using Claude with the agent creation system prompt.
## Usage Pattern
### Step 1: Describe Your Agent Need
Think about:
- What task should the agent handle?
- When should it be triggered?
- Should it be proactive or reactive?
- What are the key responsibilities?
### Step 2: Use the Generation Prompt
Send this to Claude (with the agent-creation-system-prompt loaded):
```
Create an agent configuration based on this request: "[YOUR DESCRIPTION]"
Return ONLY the JSON object, no other text.
```
**Replace [YOUR DESCRIPTION] with your agent requirements.**
### Step 3: Claude Returns JSON
Claude will return:
```json
{
"identifier": "agent-name",
"whenToUse": "Use this agent when... Examples: <example>...</example>",
"systemPrompt": "You are... **Your Core Responsibilities:**..."
}
```
### Step 4: Convert to Agent File
Create `agents/[identifier].md`:
```markdown
---
name: [identifier from JSON]
description: [whenToUse from JSON]
model: inherit
color: [choose: blue/cyan/green/yellow/magenta/red]
tools: ["Read", "Write", "Grep"] # Optional: restrict tools
---
[systemPrompt from JSON]
```
## Example 1: Code Review Agent
**Your request:**
```
I need an agent that reviews code changes for quality issues, security vulnerabilities, and adherence to best practices. It should be called after code is written and provide specific feedback.
```
**Claude generates:**
```json
{
"identifier": "code-quality-reviewer",
"whenToUse": "Use this agent when the user has written code and needs quality review, or explicitly asks to review code changes. Examples:\n\n<example>\nContext: User just implemented a new feature\nuser: \"I've added the authentication feature\"\nassistant: \"Great! Let me review the code quality.\"\n<commentary>\nCode was written, trigger code-quality-reviewer agent for review.\n</commentary>\nassistant: \"I'll use the code-quality-reviewer agent to analyze the changes.\"\n</example>\n\n<example>\nContext: User explicitly requests review\nuser: \"Can you review my code for issues?\"\nassistant: \"I'll use the code-quality-reviewer agent to perform a thorough review.\"\n<commentary>\nExplicit review request triggers the agent.\n</commentary>\n</example>",
"systemPrompt": "You are an expert code quality reviewer specializing in identifying issues in software implementations.\n\n**Your Core Responsibilities:**\n1. Analyze code changes for quality issues (readability, maintainability, performance)\n2. Identify security vulnerabilities (injection, XSS, authentication issues)\n3. Check adherence to project best practices and coding standards\n4. Provide actionable, specific feedback with line numbers\n\n**Review Process:**\n1. Read the code changes using available tools\n2. Analyze for:\n - Code quality (duplication, complexity, clarity)\n - Security (OWASP top 10, input validation)\n - Best practices (error handling, logging, testing)\n - Project-specific standards (from CLAUDE.md)\n3. Identify issues with severity (critical/major/minor)\n4. Provide specific recommendations with examples\n\n**Output Format:**\nProvide a structured review:\n1. Summary (2-3 sentences)\n2. Critical Issues (must fix)\n3. Major Issues (should fix)\n4. Minor Issues (nice to fix)\n5. Positive observations\n6. Overall assessment\n\nInclude file names and line numbers for all findings."
}
```
**You create:**
File: `agents/code-quality-reviewer.md`
```markdown
---
name: code-quality-reviewer
description: Use this agent when the user has written code and needs quality review, or explicitly asks to review code changes. Examples:
<example>
Context: User just implemented a new feature
user: "I've added the authentication feature"
assistant: "Great! Let me review the code quality."
<commentary>
Code was written, trigger code-quality-reviewer agent for review.
</commentary>
assistant: "I'll use the code-quality-reviewer agent to analyze the changes."
</example>
<example>
Context: User explicitly requests review
user: "Can you review my code for issues?"
assistant: "I'll use the code-quality-reviewer agent to perform a thorough review."
<commentary>
Explicit review request triggers the agent.
</commentary>
</example>
model: inherit
color: blue
tools: ["Read", "Grep", "Glob"]
---
You are an expert code quality reviewer specializing in identifying issues in software implementations.
**Your Core Responsibilities:**
1. Analyze code changes for quality issues (readability, maintainability, performance)
2. Identify security vulnerabilities (injection, XSS, authentication issues)
3. Check adherence to project best practices and coding standards
4. Provide actionable, specific feedback with line numbers
**Review Process:**
1. Read the code changes using available tools
2. Analyze for:
- Code quality (duplication, complexity, clarity)
- Security (OWASP top 10, input validation)
- Best practices (error handling, logging, testing)
- Project-specific standards (from CLAUDE.md)
3. Identify issues with severity (critical/major/minor)
4. Provide specific recommendations with examples
**Output Format:**
Provide a structured review:
1. Summary (2-3 sentences)
2. Critical Issues (must fix)
3. Major Issues (should fix)
4. Minor Issues (nice to fix)
5. Positive observations
6. Overall assessment
Include file names and line numbers for all findings.
```
## Example 2: Test Generation Agent
**Your request:**
```
Create an agent that generates unit tests for code. It should analyze existing code and create comprehensive test suites following project conventions.
```
**Claude generates:**
```json
{
"identifier": "test-generator",
"whenToUse": "Use this agent when the user asks to generate tests, needs test coverage, or has written code that needs testing. Examples:\n\n<example>\nContext: User wrote new functions without tests\nuser: \"I've implemented the user authentication functions\"\nassistant: \"Great! Let me generate tests for these functions.\"\n<commentary>\nNew code without tests, proactively trigger test-generator.\n</commentary>\nassistant: \"I'll use the test-generator agent to create comprehensive tests.\"\n</example>",
"systemPrompt": "You are an expert test engineer specializing in creating comprehensive unit tests...\n\n**Your Core Responsibilities:**\n1. Analyze code to understand behavior\n2. Generate test cases covering happy paths and edge cases\n3. Follow project testing conventions\n4. Ensure high code coverage\n\n**Test Generation Process:**\n1. Read target code\n2. Identify testable units (functions, classes, methods)\n3. Design test cases (inputs, expected outputs, edge cases)\n4. Generate tests following project patterns\n5. Add assertions and error cases\n\n**Output Format:**\nGenerate complete test files with:\n- Test suite structure\n- Setup/teardown if needed\n- Descriptive test names\n- Comprehensive assertions"
}
```
**You create:** `agents/test-generator.md` with the structure above.
## Example 3: Documentation Agent
**Your request:**
```
Build an agent that writes and updates API documentation. It should analyze code and generate clear, comprehensive docs.
```
**Result:** Agent file with identifier `api-docs-writer`, appropriate examples, and system prompt for documentation generation.
## Tips for Effective Agent Generation
### Be Specific in Your Request
**Vague:**
```
"I need an agent that helps with code"
```
**Specific:**
```
"I need an agent that reviews pull requests for type safety issues in TypeScript, checking for proper type annotations, avoiding 'any', and ensuring correct generic usage"
```
### Include Triggering Preferences
Tell Claude when the agent should activate:
```
"Create an agent that generates tests. It should be triggered proactively after code is written, not just when explicitly requested."
```
### Mention Project Context
```
"Create a code review agent. This project uses React and TypeScript, so the agent should check for React best practices and TypeScript type safety."
```
### Define Output Expectations
```
"Create an agent that analyzes performance. It should provide specific recommendations with file names and line numbers, plus estimated performance impact."
```
## Validation After Generation
Always validate generated agents:
```bash
# Validate structure
./scripts/validate-agent.sh agents/your-agent.md
# Check triggering works
# Test with scenarios from examples
```
## Iterating on Generated Agents
If generated agent needs improvement:
1. Identify what's missing or wrong
2. Manually edit the agent file
3. Focus on:
- Better examples in description
- More specific system prompt
- Clearer process steps
- Better output format definition
4. Re-validate
5. Test again
## Advantages of AI-Assisted Generation
- **Comprehensive**: Claude includes edge cases and quality checks
- **Consistent**: Follows proven patterns
- **Fast**: Seconds vs manual writing
- **Examples**: Auto-generates triggering examples
- **Complete**: Provides full system prompt structure
## When to Edit Manually
Edit generated agents when:
- Need very specific project patterns
- Require custom tool combinations
- Want unique persona or style
- Integrating with existing agents
- Need precise triggering conditions
Start with generation, then refine manually for best results.
@@ -0,0 +1,427 @@
# Complete Agent Examples
Full, production-ready agent examples for common use cases. Use these as templates for your own agents.
## Example 1: Code Review Agent
**File:** `agents/code-reviewer.md`
```markdown
---
name: code-reviewer
description: Use this agent when the user has written code and needs quality review, security analysis, or best practices validation. Examples:
<example>
Context: User just implemented a new feature
user: "I've added the payment processing feature"
assistant: "Great! Let me review the implementation."
<commentary>
Code written for payment processing (security-critical). Proactively trigger
code-reviewer agent to check for security issues and best practices.
</commentary>
assistant: "I'll use the code-reviewer agent to analyze the payment code."
</example>
<example>
Context: User explicitly requests code review
user: "Can you review my code for issues?"
assistant: "I'll use the code-reviewer agent to perform a comprehensive review."
<commentary>
Explicit code review request triggers the agent.
</commentary>
</example>
<example>
Context: Before committing code
user: "I'm ready to commit these changes"
assistant: "Let me review them first."
<commentary>
Before commit, proactively review code quality.
</commentary>
assistant: "I'll use the code-reviewer agent to validate the changes."
</example>
model: inherit
color: blue
tools: ["Read", "Grep", "Glob"]
---
You are an expert code quality reviewer specializing in identifying issues, security vulnerabilities, and opportunities for improvement in software implementations.
**Your Core Responsibilities:**
1. Analyze code changes for quality issues (readability, maintainability, complexity)
2. Identify security vulnerabilities (SQL injection, XSS, authentication flaws, etc.)
3. Check adherence to project best practices and coding standards from CLAUDE.md
4. Provide specific, actionable feedback with file and line number references
5. Recognize and commend good practices
**Code Review Process:**
1. **Gather Context**: Use Glob to find recently modified files (git diff, git status)
2. **Read Code**: Use Read tool to examine changed files
3. **Analyze Quality**:
- Check for code duplication (DRY principle)
- Assess complexity and readability
- Verify error handling
- Check for proper logging
4. **Security Analysis**:
- Scan for injection vulnerabilities (SQL, command, XSS)
- Check authentication and authorization
- Verify input validation and sanitization
- Look for hardcoded secrets or credentials
5. **Best Practices**:
- Follow project-specific standards from CLAUDE.md
- Check naming conventions
- Verify test coverage
- Assess documentation
6. **Categorize Issues**: Group by severity (critical/major/minor)
7. **Generate Report**: Format according to output template
**Quality Standards:**
- Every issue includes file path and line number (e.g., `src/auth.ts:42`)
- Issues categorized by severity with clear criteria
- Recommendations are specific and actionable (not vague)
- Include code examples in recommendations when helpful
- Balance criticism with recognition of good practices
**Output Format:**
## Code Review Summary
[2-3 sentence overview of changes and overall quality]
## Critical Issues (Must Fix)
- `src/file.ts:42` - [Issue description] - [Why critical] - [How to fix]
## Major Issues (Should Fix)
- `src/file.ts:15` - [Issue description] - [Impact] - [Recommendation]
## Minor Issues (Consider Fixing)
- `src/file.ts:88` - [Issue description] - [Suggestion]
## Positive Observations
- [Good practice 1]
- [Good practice 2]
## Overall Assessment
[Final verdict and recommendations]
**Edge Cases:**
- No issues found: Provide positive validation, mention what was checked
- Too many issues (>20): Group by type, prioritize top 10 critical/major
- Unclear code intent: Note ambiguity and request clarification
- Missing context (no CLAUDE.md): Apply general best practices
- Large changeset: Focus on most impactful files first
```
## Example 2: Test Generator Agent
**File:** `agents/test-generator.md`
```markdown
---
name: test-generator
description: Use this agent when the user has written code without tests, explicitly asks for test generation, or needs test coverage improvement. Examples:
<example>
Context: User implemented functions without tests
user: "I've added the data validation functions"
assistant: "Let me generate tests for these."
<commentary>
New code without tests. Proactively trigger test-generator agent.
</commentary>
assistant: "I'll use the test-generator agent to create comprehensive tests."
</example>
<example>
Context: User explicitly requests tests
user: "Generate unit tests for my code"
assistant: "I'll use the test-generator agent to create a complete test suite."
<commentary>
Direct test generation request triggers the agent.
</commentary>
</example>
model: inherit
color: green
tools: ["Read", "Write", "Grep", "Bash"]
---
You are an expert test engineer specializing in creating comprehensive, maintainable unit tests that ensure code correctness and reliability.
**Your Core Responsibilities:**
1. Generate high-quality unit tests with excellent coverage
2. Follow project testing conventions and patterns
3. Include happy path, edge cases, and error scenarios
4. Ensure tests are maintainable and clear
**Test Generation Process:**
1. **Analyze Code**: Read implementation files to understand:
- Function signatures and behavior
- Input/output contracts
- Edge cases and error conditions
- Dependencies and side effects
2. **Identify Test Patterns**: Check existing tests for:
- Testing framework (Jest, pytest, etc.)
- File organization (test/ directory, *.test.ts, etc.)
- Naming conventions
- Setup/teardown patterns
3. **Design Test Cases**:
- Happy path (normal, expected usage)
- Boundary conditions (min/max, empty, null)
- Error cases (invalid input, exceptions)
- Edge cases (special characters, large data, etc.)
4. **Generate Tests**: Create test file with:
- Descriptive test names
- Arrange-Act-Assert structure
- Clear assertions
- Appropriate mocking if needed
5. **Verify**: Ensure tests are runnable and clear
**Quality Standards:**
- Test names clearly describe what is being tested
- Each test focuses on single behavior
- Tests are independent (no shared state)
- Mocks used appropriately (avoid over-mocking)
- Edge cases and errors covered
- Tests follow DAMP principle (Descriptive And Meaningful Phrases)
**Output Format:**
Create test file at [appropriate path] with:
```[language]
// Test suite for [module]
describe('[module name]', () => {
// Test cases with descriptive names
test('should [expected behavior] when [scenario]', () => {
// Arrange
// Act
// Assert
})
// More tests...
})
```
**Edge Cases:**
- No existing tests: Create new test file following best practices
- Existing test file: Add new tests maintaining consistency
- Unclear behavior: Add tests for observable behavior, note uncertainties
- Complex mocking: Prefer integration tests or minimal mocking
- Untestable code: Suggest refactoring for testability
```
## Example 3: Documentation Generator
**File:** `agents/docs-generator.md`
```markdown
---
name: docs-generator
description: Use this agent when the user has written code needing documentation, API endpoints requiring docs, or explicitly requests documentation generation. Examples:
<example>
Context: User implemented new public API
user: "I've added the user management API endpoints"
assistant: "Let me document these endpoints."
<commentary>
New public API needs documentation. Proactively trigger docs-generator.
</commentary>
assistant: "I'll use the docs-generator agent to create API documentation."
</example>
<example>
Context: User requests documentation
user: "Generate docs for this module"
assistant: "I'll use the docs-generator agent to create comprehensive documentation."
<commentary>
Explicit documentation request triggers the agent.
</commentary>
</example>
model: inherit
color: cyan
tools: ["Read", "Write", "Grep", "Glob"]
---
You are an expert technical writer specializing in creating clear, comprehensive documentation for software projects.
**Your Core Responsibilities:**
1. Generate accurate, clear documentation from code
2. Follow project documentation standards
3. Include examples and usage patterns
4. Ensure completeness and correctness
**Documentation Generation Process:**
1. **Analyze Code**: Read implementation to understand:
- Public interfaces and APIs
- Parameters and return values
- Behavior and side effects
- Error conditions
2. **Identify Documentation Pattern**: Check existing docs for:
- Format (Markdown, JSDoc, etc.)
- Style (terse vs verbose)
- Examples and code snippets
- Organization structure
3. **Generate Content**:
- Clear description of functionality
- Parameter documentation
- Return value documentation
- Usage examples
- Error conditions
4. **Format**: Follow project conventions
5. **Validate**: Ensure accuracy and completeness
**Quality Standards:**
- Documentation matches actual code behavior
- Examples are runnable and correct
- All public APIs documented
- Clear and concise language
- Proper formatting and structure
**Output Format:**
Create documentation in project's standard format:
- Function/method signatures
- Description of behavior
- Parameters with types and descriptions
- Return values
- Exceptions/errors
- Usage examples
- Notes or warnings if applicable
**Edge Cases:**
- Private/internal code: Document only if requested
- Complex APIs: Break into sections, provide multiple examples
- Deprecated code: Mark as deprecated with migration guide
- Unclear behavior: Document observable behavior, note assumptions
```
## Example 4: Security Analyzer
**File:** `agents/security-analyzer.md`
```markdown
---
name: security-analyzer
description: Use this agent when the user implements security-critical code (auth, payments, data handling), explicitly requests security analysis, or before deploying sensitive changes. Examples:
<example>
Context: User implemented authentication logic
user: "I've added JWT token validation"
assistant: "Let me check the security."
<commentary>
Authentication code is security-critical. Proactively trigger security-analyzer.
</commentary>
assistant: "I'll use the security-analyzer agent to review for security vulnerabilities."
</example>
<example>
Context: User requests security check
user: "Check my code for security issues"
assistant: "I'll use the security-analyzer agent to perform a thorough security review."
<commentary>
Explicit security review request triggers the agent.
</commentary>
</example>
model: inherit
color: red
tools: ["Read", "Grep", "Glob"]
---
You are an expert security analyst specializing in identifying vulnerabilities and security issues in software implementations.
**Your Core Responsibilities:**
1. Identify security vulnerabilities (OWASP Top 10 and beyond)
2. Analyze authentication and authorization logic
3. Check input validation and sanitization
4. Verify secure data handling and storage
5. Provide specific remediation guidance
**Security Analysis Process:**
1. **Identify Attack Surface**: Find user input points, APIs, database queries
2. **Check Common Vulnerabilities**:
- Injection (SQL, command, XSS, etc.)
- Authentication/authorization flaws
- Sensitive data exposure
- Security misconfiguration
- Insecure deserialization
3. **Analyze Patterns**:
- Input validation at boundaries
- Output encoding
- Parameterized queries
- Principle of least privilege
4. **Assess Risk**: Categorize by severity and exploitability
5. **Provide Remediation**: Specific fixes with examples
**Quality Standards:**
- Every vulnerability includes CVE/CWE reference when applicable
- Severity based on CVSS criteria
- Remediation includes code examples
- False positive rate minimized
**Output Format:**
## Security Analysis Report
### Summary
[High-level security posture assessment]
### Critical Vulnerabilities ([count])
- **[Vulnerability Type]** at `file:line`
- Risk: [Description of security impact]
- How to Exploit: [Attack scenario]
- Fix: [Specific remediation with code example]
### Medium/Low Vulnerabilities
[...]
### Security Best Practices Recommendations
[...]
### Overall Risk Assessment
[High/Medium/Low with justification]
**Edge Cases:**
- No vulnerabilities: Confirm security review completed, mention what was checked
- False positives: Verify before reporting
- Uncertain vulnerabilities: Mark as "potential" with caveat
- Out of scope items: Note but don't deep-dive
```
## Customization Tips
### Adapt to Your Domain
Take these templates and customize:
- Change domain expertise (e.g., "Python expert" vs "React expert")
- Adjust process steps for your specific workflow
- Modify output format to match your needs
- Add domain-specific quality standards
- Include technology-specific checks
### Adjust Tool Access
Restrict or expand based on agent needs:
- **Read-only agents**: `["Read", "Grep", "Glob"]`
- **Generator agents**: `["Read", "Write", "Grep"]`
- **Executor agents**: `["Read", "Write", "Bash", "Grep"]`
- **Full access**: Omit tools field
### Customize Colors
Choose colors that match agent purpose:
- **Blue**: Analysis, review, investigation
- **Cyan**: Documentation, information
- **Green**: Generation, creation, success-oriented
- **Yellow**: Validation, warnings, caution
- **Red**: Security, critical analysis, errors
- **Magenta**: Refactoring, transformation, creative
## Using These Templates
1. Copy template that matches your use case
2. Replace placeholders with your specifics
3. Customize process steps for your domain
4. Adjust examples to your triggering scenarios
5. Validate with `scripts/validate-agent.sh`
6. Test triggering with real scenarios
7. Iterate based on agent performance
These templates provide battle-tested starting points. Customize them for your specific needs while maintaining the proven structure.
@@ -0,0 +1,207 @@
# Agent Creation System Prompt
This is the exact system prompt used by Claude Code's agent generation feature, refined through extensive production use.
## The Prompt
```
You are an elite AI agent architect specializing in crafting high-performance agent configurations. Your expertise lies in translating user requirements into precisely-tuned agent specifications that maximize effectiveness and reliability.
**Important Context**: You may have access to project-specific instructions from CLAUDE.md files and other context that may include coding standards, project structure, and custom requirements. Consider this context when creating agents to ensure they align with the project's established patterns and practices.
When a user describes what they want an agent to do, you will:
1. **Extract Core Intent**: Identify the fundamental purpose, key responsibilities, and success criteria for the agent. Look for both explicit requirements and implicit needs. Consider any project-specific context from CLAUDE.md files. For agents that are meant to review code, you should assume that the user is asking to review recently written code and not the whole codebase, unless the user has explicitly instructed you otherwise.
2. **Design Expert Persona**: Create a compelling expert identity that embodies deep domain knowledge relevant to the task. The persona should inspire confidence and guide the agent's decision-making approach.
3. **Architect Comprehensive Instructions**: Develop a system prompt that:
- Establishes clear behavioral boundaries and operational parameters
- Provides specific methodologies and best practices for task execution
- Anticipates edge cases and provides guidance for handling them
- Incorporates any specific requirements or preferences mentioned by the user
- Defines output format expectations when relevant
- Aligns with project-specific coding standards and patterns from CLAUDE.md
4. **Optimize for Performance**: Include:
- Decision-making frameworks appropriate to the domain
- Quality control mechanisms and self-verification steps
- Efficient workflow patterns
- Clear escalation or fallback strategies
5. **Create Identifier**: Design a concise, descriptive identifier that:
- Uses lowercase letters, numbers, and hyphens only
- Is typically 2-4 words joined by hyphens
- Clearly indicates the agent's primary function
- Is memorable and easy to type
- Avoids generic terms like "helper" or "assistant"
6. **Example agent descriptions**:
- In the 'whenToUse' field of the JSON object, you should include examples of when this agent should be used.
- Examples should be of the form:
<example>
Context: The user is creating a code-review agent that should be called after a logical chunk of code is written.
user: "Please write a function that checks if a number is prime"
assistant: "Here is the relevant function: "
<function call omitted for brevity only for this example>
<commentary>
Since a logical chunk of code was written and the task was completed, now use the code-review agent to review the code.
</commentary>
assistant: "Now let me use the code-reviewer agent to review the code"
</example>
- If the user mentioned or implied that the agent should be used proactively, you should include examples of this.
- NOTE: Ensure that in the examples, you are making the assistant use the Agent tool and not simply respond directly to the task.
Your output must be a valid JSON object with exactly these fields:
{
"identifier": "A unique, descriptive identifier using lowercase letters, numbers, and hyphens (e.g., 'code-reviewer', 'api-docs-writer', 'test-generator')",
"whenToUse": "A precise, actionable description starting with 'Use this agent when...' that clearly defines the triggering conditions and use cases. Ensure you include examples as described above.",
"systemPrompt": "The complete system prompt that will govern the agent's behavior, written in second person ('You are...', 'You will...') and structured for maximum clarity and effectiveness"
}
Key principles for your system prompts:
- Be specific rather than generic - avoid vague instructions
- Include concrete examples when they would clarify behavior
- Balance comprehensiveness with clarity - every instruction should add value
- Ensure the agent has enough context to handle variations of the core task
- Make the agent proactive in seeking clarification when needed
- Build in quality assurance and self-correction mechanisms
Remember: The agents you create should be autonomous experts capable of handling their designated tasks with minimal additional guidance. Your system prompts are their complete operational manual.
```
## Usage Pattern
Use this prompt to generate agent configurations:
```markdown
**User input:** "I need an agent that reviews pull requests for code quality issues"
**You send to Claude with the system prompt above:**
Create an agent configuration based on this request: "I need an agent that reviews pull requests for code quality issues"
**Claude returns JSON:**
{
"identifier": "pr-quality-reviewer",
"whenToUse": "Use this agent when the user asks to review a pull request, check code quality, or analyze PR changes. Examples:\n\n<example>\nContext: User has created a PR and wants quality review\nuser: \"Can you review PR #123 for code quality?\"\nassistant: \"I'll use the pr-quality-reviewer agent to analyze the PR.\"\n<commentary>\nPR review request triggers the pr-quality-reviewer agent.\n</commentary>\n</example>",
"systemPrompt": "You are an expert code quality reviewer...\n\n**Your Core Responsibilities:**\n1. Analyze code changes for quality issues\n2. Check adherence to best practices\n..."
}
```
## Converting to Agent File
Take the JSON output and create the agent markdown file:
**agents/pr-quality-reviewer.md:**
```markdown
---
name: pr-quality-reviewer
description: Use this agent when the user asks to review a pull request, check code quality, or analyze PR changes. Examples:
<example>
Context: User has created a PR and wants quality review
user: "Can you review PR #123 for code quality?"
assistant: "I'll use the pr-quality-reviewer agent to analyze the PR."
<commentary>
PR review request triggers the pr-quality-reviewer agent.
</commentary>
</example>
model: inherit
color: blue
---
You are an expert code quality reviewer...
**Your Core Responsibilities:**
1. Analyze code changes for quality issues
2. Check adherence to best practices
...
```
## Customization Tips
### Adapt the System Prompt
The base prompt is excellent but can be enhanced for specific needs:
**For security-focused agents:**
```
Add after "Architect Comprehensive Instructions":
- Include OWASP top 10 security considerations
- Check for common vulnerabilities (injection, XSS, etc.)
- Validate input sanitization
```
**For test-generation agents:**
```
Add after "Optimize for Performance":
- Follow AAA pattern (Arrange, Act, Assert)
- Include edge cases and error scenarios
- Ensure test isolation and cleanup
```
**For documentation agents:**
```
Add after "Design Expert Persona":
- Use clear, concise language
- Include code examples
- Follow project documentation standards from CLAUDE.md
```
## Best Practices from Internal Implementation
### 1. Consider Project Context
The prompt specifically mentions using CLAUDE.md context:
- Agent should align with project patterns
- Follow project-specific coding standards
- Respect established practices
### 2. Proactive Agent Design
Include examples showing proactive usage:
```
<example>
Context: After writing code, agent should review proactively
user: "Please write a function..."
assistant: "[Writes function]"
<commentary>
Code written, now use review agent proactively.
</commentary>
assistant: "Now let me review this code with the code-reviewer agent"
</example>
```
### 3. Scope Assumptions
For code review agents, assume "recently written code" not entire codebase:
```
For agents that review code, assume recent changes unless explicitly
stated otherwise.
```
### 4. Output Structure
Always define clear output format in system prompt:
```
**Output Format:**
Provide results as:
1. Summary (2-3 sentences)
2. Detailed findings (bullet points)
3. Recommendations (action items)
```
## Integration with Plugin-Dev
Use this system prompt when creating agents for your plugins:
1. Take user request for agent functionality
2. Feed to Claude with this system prompt
3. Get JSON output (identifier, whenToUse, systemPrompt)
4. Convert to agent markdown file with frontmatter
5. Validate with agent validation rules
6. Test triggering conditions
7. Add to plugin's `agents/` directory
This provides AI-assisted agent generation following proven patterns from Claude Code's internal implementation.
@@ -0,0 +1,411 @@
# System Prompt Design Patterns
Complete guide to writing effective agent system prompts that enable autonomous, high-quality operation.
## Core Structure
Every agent system prompt should follow this proven structure:
```markdown
You are [specific role] specializing in [specific domain].
**Your Core Responsibilities:**
1. [Primary responsibility - the main task]
2. [Secondary responsibility - supporting task]
3. [Additional responsibilities as needed]
**[Task Name] Process:**
1. [First concrete step]
2. [Second concrete step]
3. [Continue with clear steps]
[...]
**Quality Standards:**
- [Standard 1 with specifics]
- [Standard 2 with specifics]
- [Standard 3 with specifics]
**Output Format:**
Provide results structured as:
- [Component 1]
- [Component 2]
- [Include specific formatting requirements]
**Edge Cases:**
Handle these situations:
- [Edge case 1]: [Specific handling approach]
- [Edge case 2]: [Specific handling approach]
```
## Pattern 1: Analysis Agents
For agents that analyze code, PRs, or documentation:
```markdown
You are an expert [domain] analyzer specializing in [specific analysis type].
**Your Core Responsibilities:**
1. Thoroughly analyze [what] for [specific issues]
2. Identify [patterns/problems/opportunities]
3. Provide actionable recommendations
**Analysis Process:**
1. **Gather Context**: Read [what] using available tools
2. **Initial Scan**: Identify obvious [issues/patterns]
3. **Deep Analysis**: Examine [specific aspects]:
- [Aspect 1]: Check for [criteria]
- [Aspect 2]: Verify [criteria]
- [Aspect 3]: Assess [criteria]
4. **Synthesize Findings**: Group related issues
5. **Prioritize**: Rank by [severity/impact/urgency]
6. **Generate Report**: Format according to output template
**Quality Standards:**
- Every finding includes file:line reference
- Issues categorized by severity (critical/major/minor)
- Recommendations are specific and actionable
- Positive observations included for balance
**Output Format:**
## Summary
[2-3 sentence overview]
## Critical Issues
- [file:line] - [Issue description] - [Recommendation]
## Major Issues
[...]
## Minor Issues
[...]
## Recommendations
[...]
**Edge Cases:**
- No issues found: Provide positive feedback and validation
- Too many issues: Group and prioritize top 10
- Unclear code: Request clarification rather than guessing
```
## Pattern 2: Generation Agents
For agents that create code, tests, or documentation:
```markdown
You are an expert [domain] engineer specializing in creating high-quality [output type].
**Your Core Responsibilities:**
1. Generate [what] that meets [quality standards]
2. Follow [specific conventions/patterns]
3. Ensure [correctness/completeness/clarity]
**Generation Process:**
1. **Understand Requirements**: Analyze what needs to be created
2. **Gather Context**: Read existing [code/docs/tests] for patterns
3. **Design Structure**: Plan [architecture/organization/flow]
4. **Generate Content**: Create [output] following:
- [Convention 1]
- [Convention 2]
- [Best practice 1]
5. **Validate**: Verify [correctness/completeness]
6. **Document**: Add comments/explanations as needed
**Quality Standards:**
- Follows project conventions (check CLAUDE.md)
- [Specific quality metric 1]
- [Specific quality metric 2]
- Includes error handling
- Well-documented and clear
**Output Format:**
Create [what] with:
- [Structure requirement 1]
- [Structure requirement 2]
- Clear, descriptive naming
- Comprehensive coverage
**Edge Cases:**
- Insufficient context: Ask user for clarification
- Conflicting patterns: Follow most recent/explicit pattern
- Complex requirements: Break into smaller pieces
```
## Pattern 3: Validation Agents
For agents that validate, check, or verify:
```markdown
You are an expert [domain] validator specializing in ensuring [quality aspect].
**Your Core Responsibilities:**
1. Validate [what] against [criteria]
2. Identify violations and issues
3. Provide clear pass/fail determination
**Validation Process:**
1. **Load Criteria**: Understand validation requirements
2. **Scan Target**: Read [what] needs validation
3. **Check Rules**: For each rule:
- [Rule 1]: [Validation method]
- [Rule 2]: [Validation method]
4. **Collect Violations**: Document each failure with details
5. **Assess Severity**: Categorize issues
6. **Determine Result**: Pass only if [criteria met]
**Quality Standards:**
- All violations include specific locations
- Severity clearly indicated
- Fix suggestions provided
- No false positives
**Output Format:**
## Validation Result: [PASS/FAIL]
## Summary
[Overall assessment]
## Violations Found: [count]
### Critical ([count])
- [Location]: [Issue] - [Fix]
### Warnings ([count])
- [Location]: [Issue] - [Fix]
## Recommendations
[How to fix violations]
**Edge Cases:**
- No violations: Confirm validation passed
- Too many violations: Group by type, show top 20
- Ambiguous rules: Document uncertainty, request clarification
```
## Pattern 4: Orchestration Agents
For agents that coordinate multiple tools or steps:
```markdown
You are an expert [domain] orchestrator specializing in coordinating [complex workflow].
**Your Core Responsibilities:**
1. Coordinate [multi-step process]
2. Manage [resources/tools/dependencies]
3. Ensure [successful completion/integration]
**Orchestration Process:**
1. **Plan**: Understand full workflow and dependencies
2. **Prepare**: Set up prerequisites
3. **Execute Phases**:
- Phase 1: [What] using [tools]
- Phase 2: [What] using [tools]
- Phase 3: [What] using [tools]
4. **Monitor**: Track progress and handle failures
5. **Verify**: Confirm successful completion
6. **Report**: Provide comprehensive summary
**Quality Standards:**
- Each phase completes successfully
- Errors handled gracefully
- Progress reported to user
- Final state verified
**Output Format:**
## Workflow Execution Report
### Completed Phases
- [Phase]: [Result]
### Results
- [Output 1]
- [Output 2]
### Next Steps
[If applicable]
**Edge Cases:**
- Phase failure: Attempt retry, then report and stop
- Missing dependencies: Request from user
- Timeout: Report partial completion
```
## Writing Style Guidelines
### Tone and Voice
**Use second person (addressing the agent):**
```
✅ You are responsible for...
✅ You will analyze...
✅ Your process should...
❌ The agent is responsible for...
❌ This agent will analyze...
❌ I will analyze...
```
### Clarity and Specificity
**Be specific, not vague:**
```
✅ Check for SQL injection by examining all database queries for parameterization
❌ Look for security issues
✅ Provide file:line references for each finding
❌ Show where issues are
✅ Categorize as critical (security), major (bugs), or minor (style)
❌ Rate the severity of issues
```
### Actionable Instructions
**Give concrete steps:**
```
✅ Read the file using the Read tool, then search for patterns using Grep
❌ Analyze the code
✅ Generate test file at test/path/to/file.test.ts
❌ Create tests
```
## Common Pitfalls
### ❌ Vague Responsibilities
```markdown
**Your Core Responsibilities:**
1. Help the user with their code
2. Provide assistance
3. Be helpful
```
**Why bad:** Not specific enough to guide behavior.
### ✅ Specific Responsibilities
```markdown
**Your Core Responsibilities:**
1. Analyze TypeScript code for type safety issues
2. Identify missing type annotations and improper 'any' usage
3. Recommend specific type improvements with examples
```
### ❌ Missing Process Steps
```markdown
Analyze the code and provide feedback.
```
**Why bad:** Agent doesn't know HOW to analyze.
### ✅ Clear Process
```markdown
**Analysis Process:**
1. Read code files using Read tool
2. Scan for type annotations on all functions
3. Check for 'any' type usage
4. Verify generic type parameters
5. List findings with file:line references
```
### ❌ Undefined Output
```markdown
Provide a report.
```
**Why bad:** Agent doesn't know what format to use.
### ✅ Defined Output Format
```markdown
**Output Format:**
## Type Safety Report
### Summary
[Overview of findings]
### Issues Found
- `file.ts:42` - Missing return type on `processData`
- `utils.ts:15` - Unsafe 'any' usage in parameter
### Recommendations
[Specific fixes with examples]
```
## Length Guidelines
### Minimum Viable Agent
**~500 words minimum:**
- Role description
- 3 core responsibilities
- 5-step process
- Output format
### Standard Agent
**~1,000-2,000 words:**
- Detailed role and expertise
- 5-8 responsibilities
- 8-12 process steps
- Quality standards
- Output format
- 3-5 edge cases
### Comprehensive Agent
**~2,000-5,000 words:**
- Complete role with background
- Comprehensive responsibilities
- Detailed multi-phase process
- Extensive quality standards
- Multiple output formats
- Many edge cases
- Examples within system prompt
**Avoid > 10,000 words:** Too long, diminishing returns.
## Testing System Prompts
### Test Completeness
Can the agent handle these based on system prompt alone?
- [ ] Typical task execution
- [ ] Edge cases mentioned
- [ ] Error scenarios
- [ ] Unclear requirements
- [ ] Large/complex inputs
- [ ] Empty/missing inputs
### Test Clarity
Read the system prompt and ask:
- Can another developer understand what this agent does?
- Are process steps clear and actionable?
- Is output format unambiguous?
- Are quality standards measurable?
### Iterate Based on Results
After testing agent:
1. Identify where it struggled
2. Add missing guidance to system prompt
3. Clarify ambiguous instructions
4. Add process steps for edge cases
5. Re-test
## Conclusion
Effective system prompts are:
- **Specific**: Clear about what and how
- **Structured**: Organized with clear sections
- **Complete**: Covers normal and edge cases
- **Actionable**: Provides concrete steps
- **Testable**: Defines measurable standards
Use the patterns above as templates, customize for your domain, and iterate based on agent performance.
@@ -0,0 +1,491 @@
# Agent Triggering Examples: Best Practices
Complete guide to writing effective `<example>` blocks in agent descriptions for reliable triggering.
## Example Block Format
The standard format for triggering examples:
```markdown
<example>
Context: [Describe the situation - what led to this interaction]
user: "[Exact user message or request]"
assistant: "[How Claude should respond before triggering]"
<commentary>
[Explanation of why this agent should be triggered in this scenario]
</commentary>
assistant: "[How Claude triggers the agent - usually 'I'll use the [agent-name] agent...']"
</example>
```
## Anatomy of a Good Example
### Context
**Purpose:** Set the scene - what happened before the user's message
**Good contexts:**
```
Context: User just implemented a new authentication feature
Context: User has created a PR and wants it reviewed
Context: User is debugging a test failure
Context: After writing several functions without documentation
```
**Bad contexts:**
```
Context: User needs help (too vague)
Context: Normal usage (not specific)
```
### User Message
**Purpose:** Show the exact phrasing that should trigger the agent
**Good user messages:**
```
user: "I've added the OAuth flow, can you check it?"
user: "Review PR #123"
user: "Why is this test failing?"
user: "Add docs for these functions"
```
**Vary the phrasing:**
Include multiple examples with different phrasings for the same intent:
```
Example 1: user: "Review my code"
Example 2: user: "Can you check this implementation?"
Example 3: user: "Look over my changes"
```
### Assistant Response (Before Triggering)
**Purpose:** Show what Claude says before launching the agent
**Good responses:**
```
assistant: "I'll analyze your OAuth implementation."
assistant: "Let me review that PR for you."
assistant: "I'll investigate the test failure."
```
**Proactive example:**
```
assistant: "Great! Now let me review the code quality."
<commentary>
Code was just written, proactively trigger review agent.
</commentary>
```
### Commentary
**Purpose:** Explain the reasoning - WHY this agent should trigger
**Good commentary:**
```
<commentary>
User explicitly requested code review, trigger the code-reviewer agent.
</commentary>
<commentary>
After code implementation, proactively use review agent to check quality.
</commentary>
<commentary>
PR analysis request matches pr-analyzer agent's expertise.
</commentary>
```
**Include decision logic:**
```
<commentary>
User wrote tests (Test tool used). The test-analyzer agent should check
test quality and coverage before continuing.
</commentary>
```
### Assistant Response (Triggering)
**Purpose:** Show how Claude invokes the agent
**Standard pattern:**
```
assistant: "I'll use the [agent-name] agent to [what it will do]."
```
**Examples:**
```
assistant: "I'll use the code-reviewer agent to analyze the changes."
assistant: "Let me use the test-generator agent to create comprehensive tests."
assistant: "I'll use the security-analyzer agent to check for vulnerabilities."
```
## Example Types
### Type 1: Explicit Request
User directly asks for what the agent does:
```markdown
<example>
Context: User explicitly requests security analysis
user: "Check my code for security vulnerabilities"
assistant: "I'll use the security-analyzer agent to perform a thorough security review."
<commentary>
Direct security analysis request triggers the security-analyzer agent.
</commentary>
</example>
```
### Type 2: Proactive Triggering
Agent triggers after relevant work without explicit request:
```markdown
<example>
Context: User just implemented database queries
user: "I've added the user search functionality"
assistant: "Great! Let me review it for security."
<commentary>
Database code written. Proactively trigger security-analyzer to check
for SQL injection and other database security issues.
</commentary>
assistant: "I'll use the security-analyzer agent to check the database code."
</example>
```
### Type 3: Implicit Request
User implies need without stating it directly:
```markdown
<example>
Context: User mentions code is hard to understand
user: "This code is confusing and hard to follow"
assistant: "I can help improve the code clarity."
<commentary>
User indicates complexity issues. Trigger code-simplifier agent to refactor
for better readability.
</commentary>
assistant: "I'll use the code-simplifier agent to suggest improvements."
</example>
```
### Type 4: Tool Usage Pattern
Agent triggers based on prior tool usage:
```markdown
<example>
Context: User made multiple edits to test files
user: "I've updated all the tests"
assistant: "Great! Let me verify test quality."
<commentary>
Multiple Edit tools used on test files. Proactively trigger test-quality-analyzer
to ensure tests follow best practices.
</commentary>
assistant: "I'll use the test-quality-analyzer agent to review the tests."
</example>
```
## Multiple Examples Strategy
### Cover Different Phrasings
```markdown
<example>
user: "Review my code"
[...]
</example>
<example>
user: "Can you check my implementation?"
[...]
</example>
<example>
user: "Look over these changes"
[...]
</example>
```
### Cover Proactive and Reactive
```markdown
<example>
Context: User explicitly requests review
user: "Review my code for issues"
[...]
</example>
<example>
Context: After user writes code
user: "I've implemented the feature"
assistant: "Great! Now let me review it."
<commentary>
Code written, proactively review.
</commentary>
[...]
</example>
```
### Cover Edge Cases
```markdown
<example>
Context: Typical usage
user: "Check my PR"
[...]
</example>
<example>
Context: Large PR that needs thorough analysis
user: "This is a big PR, can you do a deep review?"
[...]
<commentary>
Large PR mentioned, use thorough analysis mode.
</commentary>
</example>
```
## Common Mistakes
### ❌ Missing Context
```markdown
<example>
user: "Review my code"
assistant: "I'll use the code-reviewer agent."
</example>
```
**Why bad:** No context about what led to this request.
### ✅ With Context
```markdown
<example>
Context: User just finished implementing authentication
user: "Review my code"
assistant: "I'll use the code-reviewer agent to analyze the auth implementation."
<commentary>
Auth code written, review for security and best practices.
</commentary>
</example>
```
### ❌ No Commentary
```markdown
<example>
Context: User requests review
user: "Check my changes"
assistant: "I'll use the reviewer agent."
</example>
```
**Why bad:** Doesn't explain WHY agent triggers.
### ✅ With Commentary
```markdown
<example>
Context: User requests review after making changes
user: "Check my changes"
assistant: "I'll use the code-reviewer agent to analyze the modifications."
<commentary>
Code review request triggers agent to check quality, security, and adherence to standards.
</commentary>
</example>
```
### ❌ Agent Responds Directly
```markdown
<example>
user: "Review my code"
assistant: "I found the following issues: [lists issues]"
</example>
```
**Why bad:** Shows agent's output, not triggering.
### ✅ Shows Triggering
```markdown
<example>
user: "Review my code"
assistant: "I'll use the code-reviewer agent to perform the review."
<commentary>
Review request triggers the agent.
</commentary>
</example>
```
## How Many Examples?
### Minimum: 2 Examples
Cover at least:
1. Explicit request
2. One variation or proactive trigger
### Recommended: 3-4 Examples
Cover:
1. Explicit request (direct ask)
2. Implicit request (user implies need)
3. Proactive trigger (after relevant work)
4. Edge case or specific scenario
### Maximum: 6 Examples
More than 6 makes description too long. Focus on most important scenarios.
## Template Library
### Code Review Agent
```markdown
<example>
Context: User just implemented a new feature
user: "I've added the user registration feature"
assistant: "Great! Let me review the code quality."
<commentary>
Code written, proactively trigger code-reviewer agent.
</commentary>
assistant: "I'll use the code-reviewer agent to analyze the implementation."
</example>
<example>
Context: User explicitly requests review
user: "Can you review my changes for issues?"
assistant: "I'll use the code-reviewer agent to perform a thorough review."
<commentary>
Explicit review request triggers the agent.
</commentary>
</example>
```
### Test Generation Agent
```markdown
<example>
Context: User implemented functions without tests
user: "I've added the data processing functions"
assistant: "Great! Let me generate tests for these."
<commentary>
New code without tests, proactively trigger test-generator agent.
</commentary>
assistant: "I'll use the test-generator agent to create comprehensive tests."
</example>
<example>
Context: User explicitly asks for tests
user: "Generate tests for my code"
assistant: "I'll use the test-generator agent to create a complete test suite."
<commentary>
Direct test generation request triggers the agent.
</commentary>
</example>
```
### Documentation Agent
```markdown
<example>
Context: User added new API endpoints
user: "I've implemented the REST API endpoints"
assistant: "I'll document these endpoints."
<commentary>
New API code, proactively generate documentation.
</commentary>
assistant: "I'll use the api-docs-writer agent to create comprehensive documentation."
</example>
<example>
Context: User requests documentation
user: "Write docs for this API"
assistant: "I'll use the api-docs-writer agent to generate clear documentation."
<commentary>
Documentation request triggers the agent.
</commentary>
</example>
```
### Validation Agent
```markdown
<example>
Context: User ready to commit changes
user: "I'm ready to commit this code"
assistant: "Let me validate it first."
<commentary>
Before commit, proactively validate with validation-agent.
</commentary>
assistant: "I'll use the code-validator agent to check for issues."
</example>
<example>
Context: User asks for validation
user: "Validate my implementation"
assistant: "I'll use the code-validator agent to verify correctness."
<commentary>
Explicit validation request triggers the agent.
</commentary>
</example>
```
## Debugging Triggering Issues
### Agent Not Triggering
**Check:**
1. Examples include relevant keywords from user message
2. Context matches actual usage scenarios
3. Commentary explains triggering logic clearly
4. Assistant shows use of Agent tool in examples
**Fix:**
Add more examples covering different phrasings.
### Agent Triggers Too Often
**Check:**
1. Examples are too broad or generic
2. Triggering conditions overlap with other agents
3. Commentary doesn't distinguish when NOT to use
**Fix:**
Make examples more specific, add negative examples.
### Agent Triggers in Wrong Scenarios
**Check:**
1. Examples don't match actual intended use
2. Commentary suggests inappropriate triggering
**Fix:**
Revise examples to show only correct triggering scenarios.
## Best Practices Summary
**DO:**
- Include 2-4 concrete, specific examples
- Show both explicit and proactive triggering
- Provide clear context for each example
- Explain reasoning in commentary
- Vary user message phrasing
- Show Claude using Agent tool
**DON'T:**
- Use generic, vague examples
- Omit context or commentary
- Show only one type of triggering
- Skip the agent invocation step
- Make examples too similar
- Forget to explain why agent triggers
## Conclusion
Well-crafted examples are crucial for reliable agent triggering. Invest time in creating diverse, specific examples that clearly demonstrate when and why the agent should be used.
@@ -0,0 +1,217 @@
#!/bin/bash
# Agent File Validator
# Validates agent markdown files for correct structure and content
set -euo pipefail
# Usage
if [ $# -eq 0 ]; then
echo "Usage: $0 <path/to/agent.md>"
echo ""
echo "Validates agent file for:"
echo " - YAML frontmatter structure"
echo " - Required fields (name, description, model, color)"
echo " - Field formats and constraints"
echo " - System prompt presence and length"
echo " - Example blocks in description"
exit 1
fi
AGENT_FILE="$1"
echo "🔍 Validating agent file: $AGENT_FILE"
echo ""
# Check 1: File exists
if [ ! -f "$AGENT_FILE" ]; then
echo "❌ File not found: $AGENT_FILE"
exit 1
fi
echo "✅ File exists"
# Check 2: Starts with ---
FIRST_LINE=$(head -1 "$AGENT_FILE")
if [ "$FIRST_LINE" != "---" ]; then
echo "❌ File must start with YAML frontmatter (---)"
exit 1
fi
echo "✅ Starts with frontmatter"
# Check 3: Has closing ---
if ! tail -n +2 "$AGENT_FILE" | grep -q '^---$'; then
echo "❌ Frontmatter not closed (missing second ---)"
exit 1
fi
echo "✅ Frontmatter properly closed"
# Extract frontmatter and system prompt
FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$AGENT_FILE")
SYSTEM_PROMPT=$(awk '/^---$/{i++; next} i>=2' "$AGENT_FILE")
# Check 4: Required fields
echo ""
echo "Checking required fields..."
error_count=0
warning_count=0
# Check name field
NAME=$(echo "$FRONTMATTER" | grep '^name:' | sed 's/name: *//' | sed 's/^"\(.*\)"$/\1/')
if [ -z "$NAME" ]; then
echo "❌ Missing required field: name"
((error_count++))
else
echo "✅ name: $NAME"
# Validate name format
if ! [[ "$NAME" =~ ^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$ ]]; then
echo "❌ name must start/end with alphanumeric and contain only letters, numbers, hyphens"
((error_count++))
fi
# Validate name length
name_length=${#NAME}
if [ $name_length -lt 3 ]; then
echo "❌ name too short (minimum 3 characters)"
((error_count++))
elif [ $name_length -gt 50 ]; then
echo "❌ name too long (maximum 50 characters)"
((error_count++))
fi
# Check for generic names
if [[ "$NAME" =~ ^(helper|assistant|agent|tool)$ ]]; then
echo "⚠️ name is too generic: $NAME"
((warning_count++))
fi
fi
# Check description field
DESCRIPTION=$(echo "$FRONTMATTER" | grep '^description:' | sed 's/description: *//')
if [ -z "$DESCRIPTION" ]; then
echo "❌ Missing required field: description"
((error_count++))
else
desc_length=${#DESCRIPTION}
echo "✅ description: ${desc_length} characters"
if [ $desc_length -lt 10 ]; then
echo "⚠️ description too short (minimum 10 characters recommended)"
((warning_count++))
elif [ $desc_length -gt 5000 ]; then
echo "⚠️ description very long (over 5000 characters)"
((warning_count++))
fi
# Check for example blocks
if ! echo "$DESCRIPTION" | grep -q '<example>'; then
echo "⚠️ description should include <example> blocks for triggering"
((warning_count++))
fi
# Check for "Use this agent when" pattern
if ! echo "$DESCRIPTION" | grep -qi 'use this agent when'; then
echo "⚠️ description should start with 'Use this agent when...'"
((warning_count++))
fi
fi
# Check model field
MODEL=$(echo "$FRONTMATTER" | grep '^model:' | sed 's/model: *//')
if [ -z "$MODEL" ]; then
echo "❌ Missing required field: model"
((error_count++))
else
echo "✅ model: $MODEL"
case "$MODEL" in
inherit|sonnet|opus|haiku)
# Valid model
;;
*)
echo "⚠️ Unknown model: $MODEL (valid: inherit, sonnet, opus, haiku)"
((warning_count++))
;;
esac
fi
# Check color field
COLOR=$(echo "$FRONTMATTER" | grep '^color:' | sed 's/color: *//')
if [ -z "$COLOR" ]; then
echo "❌ Missing required field: color"
((error_count++))
else
echo "✅ color: $COLOR"
case "$COLOR" in
blue|cyan|green|yellow|magenta|red)
# Valid color
;;
*)
echo "⚠️ Unknown color: $COLOR (valid: blue, cyan, green, yellow, magenta, red)"
((warning_count++))
;;
esac
fi
# Check tools field (optional)
TOOLS=$(echo "$FRONTMATTER" | grep '^tools:' | sed 's/tools: *//')
if [ -n "$TOOLS" ]; then
echo "✅ tools: $TOOLS"
else
echo "💡 tools: not specified (agent has access to all tools)"
fi
# Check 5: System prompt
echo ""
echo "Checking system prompt..."
if [ -z "$SYSTEM_PROMPT" ]; then
echo "❌ System prompt is empty"
((error_count++))
else
prompt_length=${#SYSTEM_PROMPT}
echo "✅ System prompt: $prompt_length characters"
if [ $prompt_length -lt 20 ]; then
echo "❌ System prompt too short (minimum 20 characters)"
((error_count++))
elif [ $prompt_length -gt 10000 ]; then
echo "⚠️ System prompt very long (over 10,000 characters)"
((warning_count++))
fi
# Check for second person
if ! echo "$SYSTEM_PROMPT" | grep -q "You are\|You will\|Your"; then
echo "⚠️ System prompt should use second person (You are..., You will...)"
((warning_count++))
fi
# Check for structure
if ! echo "$SYSTEM_PROMPT" | grep -qi "responsibilities\|process\|steps"; then
echo "💡 Consider adding clear responsibilities or process steps"
fi
if ! echo "$SYSTEM_PROMPT" | grep -qi "output"; then
echo "💡 Consider defining output format expectations"
fi
fi
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
if [ $error_count -eq 0 ] && [ $warning_count -eq 0 ]; then
echo "✅ All checks passed!"
exit 0
elif [ $error_count -eq 0 ]; then
echo "⚠️ Validation passed with $warning_count warning(s)"
exit 0
else
echo "❌ Validation failed with $error_count error(s) and $warning_count warning(s)"
exit 1
fi
@@ -0,0 +1,272 @@
# Command Development Skill
Comprehensive guidance on creating Claude Code slash commands, including file format, frontmatter options, dynamic arguments, and best practices.
## Overview
This skill provides knowledge about:
- Slash command file format and structure
- YAML frontmatter configuration fields
- Dynamic arguments ($ARGUMENTS, $1, $2, etc.)
- File references with @ syntax
- Bash execution with !` syntax
- Command organization and namespacing
- Best practices for command development
- Plugin-specific features (${CLAUDE_PLUGIN_ROOT}, plugin patterns)
- Integration with plugin components (agents, skills, hooks)
- Validation patterns and error handling
## Skill Structure
### SKILL.md (~2,470 words)
Core skill content covering:
**Fundamentals:**
- Command basics and locations
- File format (Markdown with optional frontmatter)
- YAML frontmatter fields overview
- Dynamic arguments ($ARGUMENTS and positional)
- File references (@ syntax)
- Bash execution (!` syntax)
- Command organization patterns
- Best practices and common patterns
- Troubleshooting
**Plugin-Specific:**
- ${CLAUDE_PLUGIN_ROOT} environment variable
- Plugin command discovery and organization
- Plugin command patterns (configuration, template, multi-script)
- Integration with plugin components (agents, skills, hooks)
- Validation patterns (argument, file, resource, error handling)
### References
Detailed documentation:
- **frontmatter-reference.md**: Complete YAML frontmatter field specifications
- All field descriptions with types and defaults
- When to use each field
- Examples and best practices
- Validation and common errors
- **plugin-features-reference.md**: Plugin-specific command features
- Plugin command discovery and organization
- ${CLAUDE_PLUGIN_ROOT} environment variable usage
- Plugin command patterns (configuration, template, multi-script)
- Integration with plugin agents, skills, and hooks
- Validation patterns and error handling
### Examples
Practical command examples:
- **simple-commands.md**: 10 complete command examples
- Code review commands
- Testing commands
- Deployment commands
- Documentation generators
- Git integration commands
- Analysis and research commands
- **plugin-commands.md**: 10 plugin-specific command examples
- Simple plugin commands with scripts
- Multi-script workflows
- Template-based generation
- Configuration-driven deployment
- Agent and skill integration
- Multi-component workflows
- Validated input commands
- Environment-aware commands
## When This Skill Triggers
Claude Code activates this skill when users:
- Ask to "create a slash command" or "add a command"
- Need to "write a custom command"
- Want to "define command arguments"
- Ask about "command frontmatter" or YAML configuration
- Need to "organize commands" or use namespacing
- Want to create commands with file references
- Ask about "bash execution in commands"
- Need command development best practices
## Progressive Disclosure
The skill uses progressive disclosure:
1. **SKILL.md** (~2,470 words): Core concepts, common patterns, and plugin features overview
2. **References** (~13,500 words total): Detailed specifications
- frontmatter-reference.md (~1,200 words)
- plugin-features-reference.md (~1,800 words)
- interactive-commands.md (~2,500 words)
- advanced-workflows.md (~1,700 words)
- testing-strategies.md (~2,200 words)
- documentation-patterns.md (~2,000 words)
- marketplace-considerations.md (~2,200 words)
3. **Examples** (~6,000 words total): Complete working command examples
- simple-commands.md
- plugin-commands.md
Claude loads references and examples as needed based on task.
## Command Basics Quick Reference
### File Format
```markdown
---
description: Brief description
argument-hint: [arg1] [arg2]
allowed-tools: Read, Bash(git:*)
---
Command prompt content with:
- Arguments: $1, $2, or $ARGUMENTS
- Files: @path/to/file
- Bash: !`command here`
```
### Locations
- **Project**: `.claude/commands/` (shared with team)
- **Personal**: `~/.claude/commands/` (your commands)
- **Plugin**: `plugin-name/commands/` (plugin-specific)
### Key Features
**Dynamic arguments:**
- `$ARGUMENTS` - All arguments as single string
- `$1`, `$2`, `$3` - Positional arguments
**File references:**
- `@path/to/file` - Include file contents
**Bash execution:**
- `!`command`` - Execute and include output
## Frontmatter Fields Quick Reference
| Field | Purpose | Example |
|-------|---------|---------|
| `description` | Brief description for /help | `"Review code for issues"` |
| `allowed-tools` | Restrict tool access | `Read, Bash(git:*)` |
| `model` | Specify model | `sonnet`, `opus`, `haiku` |
| `argument-hint` | Document arguments | `[pr-number] [priority]` |
| `disable-model-invocation` | Manual-only command | `true` |
## Common Patterns
### Simple Review Command
```markdown
---
description: Review code for issues
---
Review this code for quality and potential bugs.
```
### Command with Arguments
```markdown
---
description: Deploy to environment
argument-hint: [environment] [version]
---
Deploy to $1 environment using version $2
```
### Command with File Reference
```markdown
---
description: Document file
argument-hint: [file-path]
---
Generate documentation for @$1
```
### Command with Bash Execution
```markdown
---
description: Show Git status
allowed-tools: Bash(git:*)
---
Current status: !`git status`
Recent commits: !`git log --oneline -5`
```
## Development Workflow
1. **Design command:**
- Define purpose and scope
- Determine required arguments
- Identify needed tools
2. **Create file:**
- Choose appropriate location
- Create `.md` file with command name
- Write basic prompt
3. **Add frontmatter:**
- Start minimal (just description)
- Add fields as needed (allowed-tools, etc.)
- Document arguments with argument-hint
4. **Test command:**
- Invoke with `/command-name`
- Verify arguments work
- Check bash execution
- Test file references
5. **Refine:**
- Improve prompt clarity
- Handle edge cases
- Add examples in comments
- Document requirements
## Best Practices Summary
1. **Single responsibility**: One command, one clear purpose
2. **Clear descriptions**: Make discoverable in `/help`
3. **Document arguments**: Always use argument-hint
4. **Minimal tools**: Use most restrictive allowed-tools
5. **Test thoroughly**: Verify all features work
6. **Add comments**: Explain complex logic
7. **Handle errors**: Consider missing arguments/files
## Status
**Completed enhancements:**
- ✓ Plugin command patterns (${CLAUDE_PLUGIN_ROOT}, discovery, organization)
- ✓ Integration patterns (agents, skills, hooks coordination)
- ✓ Validation patterns (input, file, resource validation, error handling)
**Remaining enhancements (in progress):**
- Advanced workflows (multi-step command sequences)
- Testing strategies (how to test commands effectively)
- Documentation patterns (command documentation best practices)
- Marketplace considerations (publishing and distribution)
## Maintenance
To update this skill:
1. Keep SKILL.md focused on core fundamentals
2. Move detailed specifications to references/
3. Add new examples/ for different use cases
4. Update frontmatter when new fields added
5. Ensure imperative/infinitive form throughout
6. Test examples work with current Claude Code
## Version History
**v0.1.0** (2025-01-15):
- Initial release with basic command fundamentals
- Frontmatter field reference
- 10 simple command examples
- Ready for plugin-specific pattern additions
@@ -0,0 +1,834 @@
---
name: Command Development
description: This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
version: 0.2.0
---
# Command Development for Claude Code
## Overview
Slash commands are frequently-used prompts defined as Markdown files that Claude executes during interactive sessions. Understanding command structure, frontmatter options, and dynamic features enables creating powerful, reusable workflows.
**Key concepts:**
- Markdown file format for commands
- YAML frontmatter for configuration
- Dynamic arguments and file references
- Bash execution for context
- Command organization and namespacing
## Command Basics
### What is a Slash Command?
A slash command is a Markdown file containing a prompt that Claude executes when invoked. Commands provide:
- **Reusability**: Define once, use repeatedly
- **Consistency**: Standardize common workflows
- **Sharing**: Distribute across team or projects
- **Efficiency**: Quick access to complex prompts
### Critical: Commands are Instructions FOR Claude
**Commands are written for agent consumption, not human consumption.**
When a user invokes `/command-name`, the command content becomes Claude's instructions. Write commands as directives TO Claude about what to do, not as messages TO the user.
**Correct approach (instructions for Claude):**
```markdown
Review this code for security vulnerabilities including:
- SQL injection
- XSS attacks
- Authentication issues
Provide specific line numbers and severity ratings.
```
**Incorrect approach (messages to user):**
```markdown
This command will review your code for security issues.
You'll receive a report with vulnerability details.
```
The first example tells Claude what to do. The second tells the user what will happen but doesn't instruct Claude. Always use the first approach.
### Command Locations
**Project commands** (shared with team):
- Location: `.claude/commands/`
- Scope: Available in specific project
- Label: Shown as "(project)" in `/help`
- Use for: Team workflows, project-specific tasks
**Personal commands** (available everywhere):
- Location: `~/.claude/commands/`
- Scope: Available in all projects
- Label: Shown as "(user)" in `/help`
- Use for: Personal workflows, cross-project utilities
**Plugin commands** (bundled with plugins):
- Location: `plugin-name/commands/`
- Scope: Available when plugin installed
- Label: Shown as "(plugin-name)" in `/help`
- Use for: Plugin-specific functionality
## File Format
### Basic Structure
Commands are Markdown files with `.md` extension:
```
.claude/commands/
├── review.md # /review command
├── test.md # /test command
└── deploy.md # /deploy command
```
**Simple command:**
```markdown
Review this code for security vulnerabilities including:
- SQL injection
- XSS attacks
- Authentication bypass
- Insecure data handling
```
No frontmatter needed for basic commands.
### With YAML Frontmatter
Add configuration using YAML frontmatter:
```markdown
---
description: Review code for security issues
allowed-tools: Read, Grep, Bash(git:*)
model: sonnet
---
Review this code for security vulnerabilities...
```
## YAML Frontmatter Fields
### description
**Purpose:** Brief description shown in `/help`
**Type:** String
**Default:** First line of command prompt
```yaml
---
description: Review pull request for code quality
---
```
**Best practice:** Clear, actionable description (under 60 characters)
### allowed-tools
**Purpose:** Specify which tools command can use
**Type:** String or Array
**Default:** Inherits from conversation
```yaml
---
allowed-tools: Read, Write, Edit, Bash(git:*)
---
```
**Patterns:**
- `Read, Write, Edit` - Specific tools
- `Bash(git:*)` - Bash with git commands only
- `*` - All tools (rarely needed)
**Use when:** Command requires specific tool access
### model
**Purpose:** Specify model for command execution
**Type:** String (sonnet, opus, haiku)
**Default:** Inherits from conversation
```yaml
---
model: haiku
---
```
**Use cases:**
- `haiku` - Fast, simple commands
- `sonnet` - Standard workflows
- `opus` - Complex analysis
### argument-hint
**Purpose:** Document expected arguments for autocomplete
**Type:** String
**Default:** None
```yaml
---
argument-hint: [pr-number] [priority] [assignee]
---
```
**Benefits:**
- Helps users understand command arguments
- Improves command discovery
- Documents command interface
### disable-model-invocation
**Purpose:** Prevent SlashCommand tool from programmatically calling command
**Type:** Boolean
**Default:** false
```yaml
---
disable-model-invocation: true
---
```
**Use when:** Command should only be manually invoked
## Dynamic Arguments
### Using $ARGUMENTS
Capture all arguments as single string:
```markdown
---
description: Fix issue by number
argument-hint: [issue-number]
---
Fix issue #$ARGUMENTS following our coding standards and best practices.
```
**Usage:**
```
> /fix-issue 123
> /fix-issue 456
```
**Expands to:**
```
Fix issue #123 following our coding standards...
Fix issue #456 following our coding standards...
```
### Using Positional Arguments
Capture individual arguments with `$1`, `$2`, `$3`, etc.:
```markdown
---
description: Review PR with priority and assignee
argument-hint: [pr-number] [priority] [assignee]
---
Review pull request #$1 with priority level $2.
After review, assign to $3 for follow-up.
```
**Usage:**
```
> /review-pr 123 high alice
```
**Expands to:**
```
Review pull request #123 with priority level high.
After review, assign to alice for follow-up.
```
### Combining Arguments
Mix positional and remaining arguments:
```markdown
Deploy $1 to $2 environment with options: $3
```
**Usage:**
```
> /deploy api staging --force --skip-tests
```
**Expands to:**
```
Deploy api to staging environment with options: --force --skip-tests
```
## File References
### Using @ Syntax
Include file contents in command:
```markdown
---
description: Review specific file
argument-hint: [file-path]
---
Review @$1 for:
- Code quality
- Best practices
- Potential bugs
```
**Usage:**
```
> /review-file src/api/users.ts
```
**Effect:** Claude reads `src/api/users.ts` before processing command
### Multiple File References
Reference multiple files:
```markdown
Compare @src/old-version.js with @src/new-version.js
Identify:
- Breaking changes
- New features
- Bug fixes
```
### Static File References
Reference known files without arguments:
```markdown
Review @package.json and @tsconfig.json for consistency
Ensure:
- TypeScript version matches
- Dependencies are aligned
- Build configuration is correct
```
## Bash Execution in Commands
Commands can execute bash commands inline to dynamically gather context before Claude processes the command. This is useful for including repository state, environment information, or project-specific context.
**When to use:**
- Include dynamic context (git status, environment vars, etc.)
- Gather project/repository state
- Build context-aware workflows
**Implementation details:**
For complete syntax, examples, and best practices, see `references/plugin-features-reference.md` section on bash execution. The reference includes the exact syntax and multiple working examples to avoid execution issues
## Command Organization
### Flat Structure
Simple organization for small command sets:
```
.claude/commands/
├── build.md
├── test.md
├── deploy.md
├── review.md
└── docs.md
```
**Use when:** 5-15 commands, no clear categories
### Namespaced Structure
Organize commands in subdirectories:
```
.claude/commands/
├── ci/
│ ├── build.md # /build (project:ci)
│ ├── test.md # /test (project:ci)
│ └── lint.md # /lint (project:ci)
├── git/
│ ├── commit.md # /commit (project:git)
│ └── pr.md # /pr (project:git)
└── docs/
├── generate.md # /generate (project:docs)
└── publish.md # /publish (project:docs)
```
**Benefits:**
- Logical grouping by category
- Namespace shown in `/help`
- Easier to find related commands
**Use when:** 15+ commands, clear categories
## Best Practices
### Command Design
1. **Single responsibility:** One command, one task
2. **Clear descriptions:** Self-explanatory in `/help`
3. **Explicit dependencies:** Use `allowed-tools` when needed
4. **Document arguments:** Always provide `argument-hint`
5. **Consistent naming:** Use verb-noun pattern (review-pr, fix-issue)
### Argument Handling
1. **Validate arguments:** Check for required arguments in prompt
2. **Provide defaults:** Suggest defaults when arguments missing
3. **Document format:** Explain expected argument format
4. **Handle edge cases:** Consider missing or invalid arguments
```markdown
---
argument-hint: [pr-number]
---
$IF($1,
Review PR #$1,
Please provide a PR number. Usage: /review-pr [number]
)
```
### File References
1. **Explicit paths:** Use clear file paths
2. **Check existence:** Handle missing files gracefully
3. **Relative paths:** Use project-relative paths
4. **Glob support:** Consider using Glob tool for patterns
### Bash Commands
1. **Limit scope:** Use `Bash(git:*)` not `Bash(*)`
2. **Safe commands:** Avoid destructive operations
3. **Handle errors:** Consider command failures
4. **Keep fast:** Long-running commands slow invocation
### Documentation
1. **Add comments:** Explain complex logic
2. **Provide examples:** Show usage in comments
3. **List requirements:** Document dependencies
4. **Version commands:** Note breaking changes
```markdown
---
description: Deploy application to environment
argument-hint: [environment] [version]
---
<!--
Usage: /deploy [staging|production] [version]
Requires: AWS credentials configured
Example: /deploy staging v1.2.3
-->
Deploy application to $1 environment using version $2...
```
## Common Patterns
### Review Pattern
```markdown
---
description: Review code changes
allowed-tools: Read, Bash(git:*)
---
Files changed: !`git diff --name-only`
Review each file for:
1. Code quality and style
2. Potential bugs or issues
3. Test coverage
4. Documentation needs
Provide specific feedback for each file.
```
### Testing Pattern
```markdown
---
description: Run tests for specific file
argument-hint: [test-file]
allowed-tools: Bash(npm:*)
---
Run tests: !`npm test $1`
Analyze results and suggest fixes for failures.
```
### Documentation Pattern
```markdown
---
description: Generate documentation for file
argument-hint: [source-file]
---
Generate comprehensive documentation for @$1 including:
- Function/class descriptions
- Parameter documentation
- Return value descriptions
- Usage examples
- Edge cases and errors
```
### Workflow Pattern
```markdown
---
description: Complete PR workflow
argument-hint: [pr-number]
allowed-tools: Bash(gh:*), Read
---
PR #$1 Workflow:
1. Fetch PR: !`gh pr view $1`
2. Review changes
3. Run checks
4. Approve or request changes
```
## Troubleshooting
**Command not appearing:**
- Check file is in correct directory
- Verify `.md` extension present
- Ensure valid Markdown format
- Restart Claude Code
**Arguments not working:**
- Verify `$1`, `$2` syntax correct
- Check `argument-hint` matches usage
- Ensure no extra spaces
**Bash execution failing:**
- Check `allowed-tools` includes Bash
- Verify command syntax in backticks
- Test command in terminal first
- Check for required permissions
**File references not working:**
- Verify `@` syntax correct
- Check file path is valid
- Ensure Read tool allowed
- Use absolute or project-relative paths
## Plugin-Specific Features
### CLAUDE_PLUGIN_ROOT Variable
Plugin commands have access to `${CLAUDE_PLUGIN_ROOT}`, an environment variable that resolves to the plugin's absolute path.
**Purpose:**
- Reference plugin files portably
- Execute plugin scripts
- Load plugin configuration
- Access plugin templates
**Basic usage:**
```markdown
---
description: Analyze using plugin script
allowed-tools: Bash(node:*)
---
Run analysis: !`node ${CLAUDE_PLUGIN_ROOT}/scripts/analyze.js $1`
Review results and report findings.
```
**Common patterns:**
```markdown
# Execute plugin script
!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/script.sh`
# Load plugin configuration
@${CLAUDE_PLUGIN_ROOT}/config/settings.json
# Use plugin template
@${CLAUDE_PLUGIN_ROOT}/templates/report.md
# Access plugin resources
@${CLAUDE_PLUGIN_ROOT}/docs/reference.md
```
**Why use it:**
- Works across all installations
- Portable between systems
- No hardcoded paths needed
- Essential for multi-file plugins
### Plugin Command Organization
Plugin commands discovered automatically from `commands/` directory:
```
plugin-name/
├── commands/
│ ├── foo.md # /foo (plugin:plugin-name)
│ ├── bar.md # /bar (plugin:plugin-name)
│ └── utils/
│ └── helper.md # /helper (plugin:plugin-name:utils)
└── plugin.json
```
**Namespace benefits:**
- Logical command grouping
- Shown in `/help` output
- Avoid name conflicts
- Organize related commands
**Naming conventions:**
- Use descriptive action names
- Avoid generic names (test, run)
- Consider plugin-specific prefix
- Use hyphens for multi-word names
### Plugin Command Patterns
**Configuration-based pattern:**
```markdown
---
description: Deploy using plugin configuration
argument-hint: [environment]
allowed-tools: Read, Bash(*)
---
Load configuration: @${CLAUDE_PLUGIN_ROOT}/config/$1-deploy.json
Deploy to $1 using configuration settings.
Monitor deployment and report status.
```
**Template-based pattern:**
```markdown
---
description: Generate docs from template
argument-hint: [component]
---
Template: @${CLAUDE_PLUGIN_ROOT}/templates/docs.md
Generate documentation for $1 following template structure.
```
**Multi-script pattern:**
```markdown
---
description: Complete build workflow
allowed-tools: Bash(*)
---
Build: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh`
Test: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/test.sh`
Package: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/package.sh`
Review outputs and report workflow status.
```
**See `references/plugin-features-reference.md` for detailed patterns.**
## Integration with Plugin Components
Commands can integrate with other plugin components for powerful workflows.
### Agent Integration
Launch plugin agents for complex tasks:
```markdown
---
description: Deep code review
argument-hint: [file-path]
---
Initiate comprehensive review of @$1 using the code-reviewer agent.
The agent will analyze:
- Code structure
- Security issues
- Performance
- Best practices
Agent uses plugin resources:
- ${CLAUDE_PLUGIN_ROOT}/config/rules.json
- ${CLAUDE_PLUGIN_ROOT}/checklists/review.md
```
**Key points:**
- Agent must exist in `plugin/agents/` directory
- Claude uses Task tool to launch agent
- Document agent capabilities
- Reference plugin resources agent uses
### Skill Integration
Leverage plugin skills for specialized knowledge:
```markdown
---
description: Document API with standards
argument-hint: [api-file]
---
Document API in @$1 following plugin standards.
Use the api-docs-standards skill to ensure:
- Complete endpoint documentation
- Consistent formatting
- Example quality
- Error documentation
Generate production-ready API docs.
```
**Key points:**
- Skill must exist in `plugin/skills/` directory
- Mention skill name to trigger invocation
- Document skill purpose
- Explain what skill provides
### Hook Coordination
Design commands that work with plugin hooks:
- Commands can prepare state for hooks to process
- Hooks execute automatically on tool events
- Commands should document expected hook behavior
- Guide Claude on interpreting hook output
See `references/plugin-features-reference.md` for examples of commands that coordinate with hooks
### Multi-Component Workflows
Combine agents, skills, and scripts:
```markdown
---
description: Comprehensive review workflow
argument-hint: [file]
allowed-tools: Bash(node:*), Read
---
Target: @$1
Phase 1 - Static Analysis:
!`node ${CLAUDE_PLUGIN_ROOT}/scripts/lint.js $1`
Phase 2 - Deep Review:
Launch code-reviewer agent for detailed analysis.
Phase 3 - Standards Check:
Use coding-standards skill for validation.
Phase 4 - Report:
Template: @${CLAUDE_PLUGIN_ROOT}/templates/review.md
Compile findings into report following template.
```
**When to use:**
- Complex multi-step workflows
- Leverage multiple plugin capabilities
- Require specialized analysis
- Need structured outputs
## Validation Patterns
Commands should validate inputs and resources before processing.
### Argument Validation
```markdown
---
description: Deploy with validation
argument-hint: [environment]
---
Validate environment: !`echo "$1" | grep -E "^(dev|staging|prod)$" || echo "INVALID"`
If $1 is valid environment:
Deploy to $1
Otherwise:
Explain valid environments: dev, staging, prod
Show usage: /deploy [environment]
```
### File Existence Checks
```markdown
---
description: Process configuration
argument-hint: [config-file]
---
Check file exists: !`test -f $1 && echo "EXISTS" || echo "MISSING"`
If file exists:
Process configuration: @$1
Otherwise:
Explain where to place config file
Show expected format
Provide example configuration
```
### Plugin Resource Validation
```markdown
---
description: Run plugin analyzer
allowed-tools: Bash(test:*)
---
Validate plugin setup:
- Script: !`test -x ${CLAUDE_PLUGIN_ROOT}/bin/analyze && echo "✓" || echo "✗"`
- Config: !`test -f ${CLAUDE_PLUGIN_ROOT}/config.json && echo "✓" || echo "✗"`
If all checks pass, run analysis.
Otherwise, report missing components.
```
### Error Handling
```markdown
---
description: Build with error handling
allowed-tools: Bash(*)
---
Execute build: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh 2>&1 || echo "BUILD_FAILED"`
If build succeeded:
Report success and output location
If build failed:
Analyze error output
Suggest likely causes
Provide troubleshooting steps
```
**Best practices:**
- Validate early in command
- Provide helpful error messages
- Suggest corrective actions
- Handle edge cases gracefully
---
For detailed frontmatter field specifications, see `references/frontmatter-reference.md`.
For plugin-specific features and patterns, see `references/plugin-features-reference.md`.
For command pattern examples, see `examples/` directory.
@@ -0,0 +1,557 @@
# Plugin Command Examples
Practical examples of commands designed for Claude Code plugins, demonstrating plugin-specific patterns and features.
## Table of Contents
1. [Simple Plugin Command](#1-simple-plugin-command)
2. [Script-Based Analysis](#2-script-based-analysis)
3. [Template-Based Generation](#3-template-based-generation)
4. [Multi-Script Workflow](#4-multi-script-workflow)
5. [Configuration-Driven Deployment](#5-configuration-driven-deployment)
6. [Agent Integration](#6-agent-integration)
7. [Skill Integration](#7-skill-integration)
8. [Multi-Component Workflow](#8-multi-component-workflow)
9. [Validated Input Command](#9-validated-input-command)
10. [Environment-Aware Command](#10-environment-aware-command)
---
## 1. Simple Plugin Command
**Use case:** Basic command that uses plugin script
**File:** `commands/analyze.md`
```markdown
---
description: Analyze code quality using plugin tools
argument-hint: [file-path]
allowed-tools: Bash(node:*), Read
---
Analyze @$1 using plugin's quality checker:
!`node ${CLAUDE_PLUGIN_ROOT}/scripts/quality-check.js $1`
Review the analysis output and provide:
1. Summary of findings
2. Priority issues to address
3. Suggested improvements
4. Code quality score interpretation
```
**Key features:**
- Uses `${CLAUDE_PLUGIN_ROOT}` for portable path
- Combines file reference with script execution
- Simple single-purpose command
---
## 2. Script-Based Analysis
**Use case:** Run comprehensive analysis using multiple plugin scripts
**File:** `commands/full-audit.md`
```markdown
---
description: Complete code audit using plugin suite
argument-hint: [directory]
allowed-tools: Bash(*)
model: sonnet
---
Running complete audit on $1:
**Security scan:**
!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/security-scan.sh $1`
**Performance analysis:**
!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/perf-analyze.sh $1`
**Best practices check:**
!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/best-practices.sh $1`
Analyze all results and create comprehensive report including:
- Critical issues requiring immediate attention
- Performance optimization opportunities
- Security vulnerabilities and fixes
- Overall health score and recommendations
```
**Key features:**
- Multiple script executions
- Organized output sections
- Comprehensive workflow
- Clear reporting structure
---
## 3. Template-Based Generation
**Use case:** Generate documentation following plugin template
**File:** `commands/gen-api-docs.md`
```markdown
---
description: Generate API documentation from template
argument-hint: [api-file]
---
Template structure: @${CLAUDE_PLUGIN_ROOT}/templates/api-documentation.md
API implementation: @$1
Generate complete API documentation following the template format above.
Ensure documentation includes:
- Endpoint descriptions with HTTP methods
- Request/response schemas
- Authentication requirements
- Error codes and handling
- Usage examples with curl commands
- Rate limiting information
Format output as markdown suitable for README or docs site.
```
**Key features:**
- Uses plugin template
- Combines template with source file
- Standardized output format
- Clear documentation structure
---
## 4. Multi-Script Workflow
**Use case:** Orchestrate build, test, and deploy workflow
**File:** `commands/release.md`
```markdown
---
description: Execute complete release workflow
argument-hint: [version]
allowed-tools: Bash(*), Read
---
Executing release workflow for version $1:
**Step 1 - Pre-release validation:**
!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/pre-release-check.sh $1`
**Step 2 - Build artifacts:**
!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build-release.sh $1`
**Step 3 - Run test suite:**
!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/run-tests.sh`
**Step 4 - Package release:**
!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/package.sh $1`
Review all step outputs and report:
1. Any failures or warnings
2. Build artifacts location
3. Test results summary
4. Next steps for deployment
5. Rollback plan if needed
```
**Key features:**
- Multi-step workflow
- Sequential script execution
- Clear step numbering
- Comprehensive reporting
---
## 5. Configuration-Driven Deployment
**Use case:** Deploy using environment-specific plugin configuration
**File:** `commands/deploy.md`
```markdown
---
description: Deploy application to environment
argument-hint: [environment]
allowed-tools: Read, Bash(*)
---
Deployment configuration for $1: @${CLAUDE_PLUGIN_ROOT}/config/$1-deploy.json
Current git state: !`git rev-parse --short HEAD`
Build info: !`cat package.json | grep -E '(name|version)'`
Execute deployment to $1 environment using configuration above.
Deployment checklist:
1. Validate configuration settings
2. Build application for $1
3. Run pre-deployment tests
4. Deploy to target environment
5. Run smoke tests
6. Verify deployment success
7. Update deployment log
Report deployment status and any issues encountered.
```
**Key features:**
- Environment-specific configuration
- Dynamic config file loading
- Pre-deployment validation
- Structured checklist
---
## 6. Agent Integration
**Use case:** Command that launches plugin agent for complex task
**File:** `commands/deep-review.md`
```markdown
---
description: Deep code review using plugin agent
argument-hint: [file-or-directory]
---
Initiate comprehensive code review of @$1 using the code-reviewer agent.
The agent will perform:
1. **Static analysis** - Check for code smells and anti-patterns
2. **Security audit** - Identify potential vulnerabilities
3. **Performance review** - Find optimization opportunities
4. **Best practices** - Ensure code follows standards
5. **Documentation check** - Verify adequate documentation
The agent has access to:
- Plugin's linting rules: ${CLAUDE_PLUGIN_ROOT}/config/lint-rules.json
- Security checklist: ${CLAUDE_PLUGIN_ROOT}/checklists/security.md
- Performance guidelines: ${CLAUDE_PLUGIN_ROOT}/docs/performance.md
Note: This uses the Task tool to launch the plugin's code-reviewer agent for thorough analysis.
```
**Key features:**
- Delegates to plugin agent
- Documents agent capabilities
- References plugin resources
- Clear scope definition
---
## 7. Skill Integration
**Use case:** Command that leverages plugin skill for specialized knowledge
**File:** `commands/document-api.md`
```markdown
---
description: Document API following plugin standards
argument-hint: [api-file]
---
API source code: @$1
Generate API documentation following the plugin's API documentation standards.
Use the api-documentation-standards skill to ensure:
- **OpenAPI compliance** - Follow OpenAPI 3.0 specification
- **Consistent formatting** - Use plugin's documentation style
- **Complete coverage** - Document all endpoints and schemas
- **Example quality** - Provide realistic usage examples
- **Error documentation** - Cover all error scenarios
The skill provides:
- Standard documentation templates
- API documentation best practices
- Common patterns for this codebase
- Quality validation criteria
Generate production-ready API documentation.
```
**Key features:**
- Invokes plugin skill by name
- Documents skill purpose
- Clear expectations
- Leverages skill knowledge
---
## 8. Multi-Component Workflow
**Use case:** Complex workflow using agents, skills, and scripts
**File:** `commands/complete-review.md`
```markdown
---
description: Comprehensive review using all plugin components
argument-hint: [file-path]
allowed-tools: Bash(node:*), Read
---
Target file: @$1
Execute comprehensive review workflow:
**Phase 1: Automated Analysis**
Run plugin analyzer: !`node ${CLAUDE_PLUGIN_ROOT}/scripts/analyze.js $1`
**Phase 2: Deep Review (Agent)**
Launch the code-quality-reviewer agent for detailed analysis.
Agent will examine:
- Code structure and organization
- Error handling patterns
- Testing coverage
- Documentation quality
**Phase 3: Standards Check (Skill)**
Use the coding-standards skill to validate:
- Naming conventions
- Code formatting
- Best practices adherence
- Framework-specific patterns
**Phase 4: Report Generation**
Template: @${CLAUDE_PLUGIN_ROOT}/templates/review-report.md
Compile all findings into comprehensive report following template.
**Phase 5: Recommendations**
Generate prioritized action items:
1. Critical issues (must fix)
2. Important improvements (should fix)
3. Nice-to-have enhancements (could fix)
Include specific file locations and suggested changes for each item.
```
**Key features:**
- Multi-phase workflow
- Combines scripts, agents, skills
- Template-based reporting
- Prioritized outputs
---
## 9. Validated Input Command
**Use case:** Command with input validation and error handling
**File:** `commands/build-env.md`
```markdown
---
description: Build for specific environment with validation
argument-hint: [environment]
allowed-tools: Bash(*)
---
Validate environment argument: !`echo "$1" | grep -E "^(dev|staging|prod)$" && echo "VALID" || echo "INVALID"`
Check build script exists: !`test -x ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh && echo "EXISTS" || echo "MISSING"`
Verify configuration available: !`test -f ${CLAUDE_PLUGIN_ROOT}/config/$1.json && echo "FOUND" || echo "NOT_FOUND"`
If all validations pass:
**Configuration:** @${CLAUDE_PLUGIN_ROOT}/config/$1.json
**Execute build:** !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh $1 2>&1`
**Validation results:** !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/validate-build.sh $1 2>&1`
Report build status and any issues.
If validations fail:
- Explain which validation failed
- Provide expected values/locations
- Suggest corrective actions
- Document troubleshooting steps
```
**Key features:**
- Input validation
- Resource existence checks
- Error handling
- Helpful error messages
- Graceful failure handling
---
## 10. Environment-Aware Command
**Use case:** Command that adapts behavior based on environment
**File:** `commands/run-checks.md`
```markdown
---
description: Run environment-appropriate checks
argument-hint: [environment]
allowed-tools: Bash(*), Read
---
Environment: $1
Load environment configuration: @${CLAUDE_PLUGIN_ROOT}/config/$1-checks.json
Determine check level: !`echo "$1" | grep -E "^prod$" && echo "FULL" || echo "BASIC"`
**For production environment:**
- Full test suite: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/test-full.sh`
- Security scan: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/security-scan.sh`
- Performance audit: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/perf-check.sh`
- Compliance check: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/compliance.sh`
**For non-production environments:**
- Basic tests: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/test-basic.sh`
- Quick lint: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/lint.sh`
Analyze results based on environment requirements:
**Production:** All checks must pass with zero critical issues
**Staging:** No critical issues, warnings acceptable
**Development:** Focus on blocking issues only
Report status and recommend proceed/block decision.
```
**Key features:**
- Environment-aware logic
- Conditional execution
- Different validation levels
- Appropriate reporting per environment
---
## Common Patterns Summary
### Pattern: Plugin Script Execution
```markdown
!`node ${CLAUDE_PLUGIN_ROOT}/scripts/script-name.js $1`
```
Use for: Running plugin-provided Node.js scripts
### Pattern: Plugin Configuration Loading
```markdown
@${CLAUDE_PLUGIN_ROOT}/config/config-name.json
```
Use for: Loading plugin configuration files
### Pattern: Plugin Template Usage
```markdown
@${CLAUDE_PLUGIN_ROOT}/templates/template-name.md
```
Use for: Using plugin templates for generation
### Pattern: Agent Invocation
```markdown
Launch the [agent-name] agent for [task description].
```
Use for: Delegating complex tasks to plugin agents
### Pattern: Skill Reference
```markdown
Use the [skill-name] skill to ensure [requirements].
```
Use for: Leveraging plugin skills for specialized knowledge
### Pattern: Input Validation
```markdown
Validate input: !`echo "$1" | grep -E "^pattern$" && echo "OK" || echo "ERROR"`
```
Use for: Validating command arguments
### Pattern: Resource Validation
```markdown
Check exists: !`test -f ${CLAUDE_PLUGIN_ROOT}/path/file && echo "YES" || echo "NO"`
```
Use for: Verifying required plugin files exist
---
## Development Tips
### Testing Plugin Commands
1. **Test with plugin installed:**
```bash
cd /path/to/plugin
claude /command-name args
```
2. **Verify ${CLAUDE_PLUGIN_ROOT} expansion:**
```bash
# Add debug output to command
!`echo "Plugin root: ${CLAUDE_PLUGIN_ROOT}"`
```
3. **Test across different working directories:**
```bash
cd /tmp && claude /command-name
cd /other/project && claude /command-name
```
4. **Validate resource availability:**
```bash
# Check all plugin resources exist
!`ls -la ${CLAUDE_PLUGIN_ROOT}/scripts/`
!`ls -la ${CLAUDE_PLUGIN_ROOT}/config/`
```
### Common Mistakes to Avoid
1. **Using relative paths instead of ${CLAUDE_PLUGIN_ROOT}:**
```markdown
# Wrong
!`node ./scripts/analyze.js`
# Correct
!`node ${CLAUDE_PLUGIN_ROOT}/scripts/analyze.js`
```
2. **Forgetting to allow required tools:**
```markdown
# Missing allowed-tools
!`bash script.sh` # Will fail without Bash permission
# Correct
---
allowed-tools: Bash(*)
---
!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/script.sh`
```
3. **Not validating inputs:**
```markdown
# Risky - no validation
Deploy to $1 environment
# Better - with validation
Validate: !`echo "$1" | grep -E "^(dev|staging|prod)$" || echo "INVALID"`
Deploy to $1 environment (if valid)
```
4. **Hardcoding plugin paths:**
```markdown
# Wrong - breaks on different installations
@/home/user/.claude/plugins/my-plugin/config.json
# Correct - works everywhere
@${CLAUDE_PLUGIN_ROOT}/config.json
```
---
For detailed plugin-specific features, see `references/plugin-features-reference.md`.
For general command development, see main `SKILL.md`.
@@ -0,0 +1,504 @@
# Simple Command Examples
Basic slash command patterns for common use cases.
**Important:** All examples below are written as instructions FOR Claude (agent consumption), not messages TO users. Commands tell Claude what to do, not tell users what will happen.
## Example 1: Code Review Command
**File:** `.claude/commands/review.md`
```markdown
---
description: Review code for quality and issues
allowed-tools: Read, Bash(git:*)
---
Review the code in this repository for:
1. **Code Quality:**
- Readability and maintainability
- Consistent style and formatting
- Appropriate abstraction levels
2. **Potential Issues:**
- Logic errors or bugs
- Edge cases not handled
- Performance concerns
3. **Best Practices:**
- Design patterns used correctly
- Error handling present
- Documentation adequate
Provide specific feedback with file and line references.
```
**Usage:**
```
> /review
```
---
## Example 2: Security Review Command
**File:** `.claude/commands/security-review.md`
```markdown
---
description: Review code for security vulnerabilities
allowed-tools: Read, Grep
model: sonnet
---
Perform comprehensive security review checking for:
**Common Vulnerabilities:**
- SQL injection risks
- Cross-site scripting (XSS)
- Authentication/authorization issues
- Insecure data handling
- Hardcoded secrets or credentials
**Security Best Practices:**
- Input validation present
- Output encoding correct
- Secure defaults used
- Error messages safe
- Logging appropriate (no sensitive data)
For each issue found:
- File and line number
- Severity (Critical/High/Medium/Low)
- Description of vulnerability
- Recommended fix
Prioritize issues by severity.
```
**Usage:**
```
> /security-review
```
---
## Example 3: Test Command with File Argument
**File:** `.claude/commands/test-file.md`
```markdown
---
description: Run tests for specific file
argument-hint: [test-file]
allowed-tools: Bash(npm:*), Bash(jest:*)
---
Run tests for $1:
Test execution: !`npm test $1`
Analyze results:
- Tests passed/failed
- Code coverage
- Performance issues
- Flaky tests
If failures found, suggest fixes based on error messages.
```
**Usage:**
```
> /test-file src/utils/helpers.test.ts
```
---
## Example 4: Documentation Generator
**File:** `.claude/commands/document.md`
```markdown
---
description: Generate documentation for file
argument-hint: [source-file]
---
Generate comprehensive documentation for @$1
Include:
**Overview:**
- Purpose and responsibility
- Main functionality
- Dependencies
**API Documentation:**
- Function/method signatures
- Parameter descriptions with types
- Return values with types
- Exceptions/errors thrown
**Usage Examples:**
- Basic usage
- Common patterns
- Edge cases
**Implementation Notes:**
- Algorithm complexity
- Performance considerations
- Known limitations
Format as Markdown suitable for project documentation.
```
**Usage:**
```
> /document src/api/users.ts
```
---
## Example 5: Git Status Summary
**File:** `.claude/commands/git-status.md`
```markdown
---
description: Summarize Git repository status
allowed-tools: Bash(git:*)
---
Repository Status Summary:
**Current Branch:** !`git branch --show-current`
**Status:** !`git status --short`
**Recent Commits:** !`git log --oneline -5`
**Remote Status:** !`git fetch && git status -sb`
Provide:
- Summary of changes
- Suggested next actions
- Any warnings or issues
```
**Usage:**
```
> /git-status
```
---
## Example 6: Deployment Command
**File:** `.claude/commands/deploy.md`
```markdown
---
description: Deploy to specified environment
argument-hint: [environment] [version]
allowed-tools: Bash(kubectl:*), Read
---
Deploy to $1 environment using version $2
**Pre-deployment Checks:**
1. Verify $1 configuration exists
2. Check version $2 is valid
3. Verify cluster accessibility: !`kubectl cluster-info`
**Deployment Steps:**
1. Update deployment manifest with version $2
2. Apply configuration to $1
3. Monitor rollout status
4. Verify pod health
5. Run smoke tests
**Rollback Plan:**
Document current version for rollback if issues occur.
Proceed with deployment? (yes/no)
```
**Usage:**
```
> /deploy staging v1.2.3
```
---
## Example 7: Comparison Command
**File:** `.claude/commands/compare-files.md`
```markdown
---
description: Compare two files
argument-hint: [file1] [file2]
---
Compare @$1 with @$2
**Analysis:**
1. **Differences:**
- Lines added
- Lines removed
- Lines modified
2. **Functional Changes:**
- Breaking changes
- New features
- Bug fixes
- Refactoring
3. **Impact:**
- Affected components
- Required updates elsewhere
- Migration requirements
4. **Recommendations:**
- Code review focus areas
- Testing requirements
- Documentation updates needed
Present as structured comparison report.
```
**Usage:**
```
> /compare-files src/old-api.ts src/new-api.ts
```
---
## Example 8: Quick Fix Command
**File:** `.claude/commands/quick-fix.md`
```markdown
---
description: Quick fix for common issues
argument-hint: [issue-description]
model: haiku
---
Quickly fix: $ARGUMENTS
**Approach:**
1. Identify the issue
2. Find relevant code
3. Propose fix
4. Explain solution
Focus on:
- Simple, direct solution
- Minimal changes
- Following existing patterns
- No breaking changes
Provide code changes with file paths and line numbers.
```
**Usage:**
```
> /quick-fix button not responding to clicks
> /quick-fix typo in error message
```
---
## Example 9: Research Command
**File:** `.claude/commands/research.md`
```markdown
---
description: Research best practices for topic
argument-hint: [topic]
model: sonnet
---
Research best practices for: $ARGUMENTS
**Coverage:**
1. **Current State:**
- How we currently handle this
- Existing implementations
2. **Industry Standards:**
- Common patterns
- Recommended approaches
- Tools and libraries
3. **Comparison:**
- Our approach vs standards
- Gaps or improvements needed
- Migration considerations
4. **Recommendations:**
- Concrete action items
- Priority and effort estimates
- Resources for implementation
Provide actionable guidance based on research.
```
**Usage:**
```
> /research error handling in async operations
> /research API authentication patterns
```
---
## Example 10: Explain Code Command
**File:** `.claude/commands/explain.md`
```markdown
---
description: Explain how code works
argument-hint: [file-or-function]
---
Explain @$1 in detail
**Explanation Structure:**
1. **Overview:**
- What it does
- Why it exists
- How it fits in system
2. **Step-by-Step:**
- Line-by-line walkthrough
- Key algorithms or logic
- Important details
3. **Inputs and Outputs:**
- Parameters and types
- Return values
- Side effects
4. **Edge Cases:**
- Error handling
- Special cases
- Limitations
5. **Usage Examples:**
- How to call it
- Common patterns
- Integration points
Explain at level appropriate for junior engineer.
```
**Usage:**
```
> /explain src/utils/cache.ts
> /explain AuthService.login
```
---
## Key Patterns
### Pattern 1: Read-Only Analysis
```markdown
---
allowed-tools: Read, Grep
---
Analyze but don't modify...
```
**Use for:** Code review, documentation, analysis
### Pattern 2: Git Operations
```markdown
---
allowed-tools: Bash(git:*)
---
!`git status`
Analyze and suggest...
```
**Use for:** Repository status, commit analysis
### Pattern 3: Single Argument
```markdown
---
argument-hint: [target]
---
Process $1...
```
**Use for:** File operations, targeted actions
### Pattern 4: Multiple Arguments
```markdown
---
argument-hint: [source] [target] [options]
---
Process $1 to $2 with $3...
```
**Use for:** Workflows, deployments, comparisons
### Pattern 5: Fast Execution
```markdown
---
model: haiku
---
Quick simple task...
```
**Use for:** Simple, repetitive commands
### Pattern 6: File Comparison
```markdown
Compare @$1 with @$2...
```
**Use for:** Diff analysis, migration planning
### Pattern 7: Context Gathering
```markdown
---
allowed-tools: Bash(git:*), Read
---
Context: !`git status`
Files: @file1 @file2
Analyze...
```
**Use for:** Informed decision making
## Tips for Writing Simple Commands
1. **Start basic:** Single responsibility, clear purpose
2. **Add complexity gradually:** Start without frontmatter
3. **Test incrementally:** Verify each feature works
4. **Use descriptive names:** Command name should indicate purpose
5. **Document arguments:** Always use argument-hint
6. **Provide examples:** Show usage in comments
7. **Handle errors:** Consider missing arguments or files
@@ -0,0 +1,722 @@
# Advanced Workflow Patterns
Multi-step command sequences and composition patterns for complex workflows.
## Overview
Advanced workflows combine multiple commands, coordinate state across invocations, and create sophisticated automation sequences. These patterns enable building complex functionality from simple command building blocks.
## Multi-Step Command Patterns
### Sequential Workflow Command
Commands that guide users through multi-step processes:
```markdown
---
description: Complete PR review workflow
argument-hint: [pr-number]
allowed-tools: Bash(gh:*), Read, Grep
---
# PR Review Workflow for #$1
## Step 1: Fetch PR Details
!`gh pr view $1 --json title,body,author,files`
## Step 2: Review Files
Files changed: !`gh pr diff $1 --name-only`
For each file:
- Check code quality
- Verify tests exist
- Review documentation
## Step 3: Run Checks
Test status: !`gh pr checks $1`
Verify:
- All tests passing
- No merge conflicts
- CI/CD successful
## Step 4: Provide Feedback
Summarize:
- Issues found (critical/minor)
- Suggestions for improvement
- Approval recommendation
Would you like to:
1. Approve PR
2. Request changes
3. Leave comments only
Reply with your choice and I'll help complete the action.
```
**Key features:**
- Numbered steps for clarity
- Bash execution for context
- Decision points for user input
- Next action suggestions
### State-Carrying Workflow
Commands that maintain state between invocations:
```markdown
---
description: Initialize deployment workflow
allowed-tools: Write, Bash(git:*)
---
# Initialize Deployment
Creating deployment tracking file...
Current branch: !`git branch --show-current`
Latest commit: !`git log -1 --format=%H`
Deployment state saved to `.claude/deployment-state.local.md`:
\`\`\`markdown
---
initialized: true
branch: $(git branch --show-current)
commit: $(git log -1 --format=%H)
timestamp: $(date -u +%Y-%m-%dT%H:%M:%SZ)
status: initialized
---
# Deployment Tracking
Branch: $(git branch --show-current)
Started: $(date)
Next steps:
1. Run tests: /deploy-test
2. Build: /deploy-build
3. Deploy: /deploy-execute
\`\`\`
State saved. Run `/deploy-test` to continue.
```
**Next command** (`/deploy-test`):
```markdown
---
description: Run deployment tests
allowed-tools: Read, Bash(npm:*)
---
Reading deployment state from `.claude/deployment-state.local.md`...
Running tests: !`npm test`
Updating state to 'tested'...
Tests complete. Run `/deploy-build` to continue.
```
**Pattern benefits:**
- Persistent state across commands
- Clear workflow progression
- Safety checkpoints
- Resume capability
### Conditional Workflow Branching
Commands that adapt based on conditions:
```markdown
---
description: Smart deployment workflow
argument-hint: [environment]
allowed-tools: Bash(git:*), Bash(npm:*), Read
---
# Deploy to $1
## Pre-flight Checks
Branch: !`git branch --show-current`
Status: !`git status --short`
**Checking conditions:**
1. Branch status:
- If main/master: Require approval
- If feature branch: Warning about target
- If hotfix: Fast-track process
2. Tests:
!`npm test`
- If tests fail: STOP - fix tests first
- If tests pass: Continue
3. Environment:
- If $1 = 'production': Extra validation
- If $1 = 'staging': Standard process
- If $1 = 'dev': Minimal checks
**Workflow decision:**
Based on above, proceeding with: [determined workflow]
[Conditional steps based on environment and status]
Ready to deploy? (yes/no)
```
## Command Composition Patterns
### Command Chaining
Commands designed to work together:
```markdown
---
description: Prepare for code review
---
# Prepare Code Review
Running preparation sequence:
1. Format code: /format-code
2. Run linter: /lint-code
3. Run tests: /test-all
4. Generate coverage: /coverage-report
5. Create review summary: /review-summary
This is a meta-command. After completing each step above,
I'll compile results and prepare comprehensive review materials.
Starting sequence...
```
**Individual commands** are simple:
- `/format-code` - Just formats
- `/lint-code` - Just lints
- `/test-all` - Just tests
**Composition command** orchestrates them.
### Pipeline Pattern
Commands that process output from previous commands:
```markdown
---
description: Analyze test failures
---
# Analyze Test Failures
## Step 1: Get test results
(Run /test-all first if not done)
Reading test output...
## Step 2: Categorize failures
- Flaky tests (random failures)
- Consistent failures
- New failures vs existing
## Step 3: Prioritize
Rank by:
- Impact (critical path vs edge case)
- Frequency (always fails vs sometimes)
- Effort (quick fix vs major work)
## Step 4: Generate fix plan
For each failure:
- Root cause hypothesis
- Suggested fix approach
- Estimated effort
Would you like me to:
1. Fix highest priority failure
2. Generate detailed fix plans for all
3. Create GitHub issues for each
```
### Parallel Execution Pattern
Commands that coordinate multiple simultaneous operations:
```markdown
---
description: Run comprehensive validation
allowed-tools: Bash(*), Read
---
# Comprehensive Validation
Running validations in parallel...
Starting:
- Code quality checks
- Security scanning
- Dependency audit
- Performance profiling
This will take 2-3 minutes. I'll monitor all processes
and report when complete.
[Poll each process and report progress]
All validations complete. Summary:
- Quality: PASS (0 issues)
- Security: WARN (2 minor issues)
- Dependencies: PASS
- Performance: PASS (baseline met)
Details:
[Collated results from all checks]
```
## Workflow State Management
### Using .local.md Files
Store workflow state in plugin-specific files:
```markdown
.claude/plugin-name-workflow.local.md:
---
workflow: deployment
stage: testing
started: 2025-01-15T10:30:00Z
environment: staging
branch: feature/new-api
commit: abc123def
tests_passed: false
build_complete: false
---
# Deployment Workflow State
Current stage: Testing
Started: 2025-01-15 10:30 UTC
Completed steps:
- ✅ Validation
- ✅ Branch check
- ⏳ Testing (in progress)
Pending steps:
- Build
- Deploy
- Smoke tests
```
**Reading state in commands:**
```markdown
---
description: Continue deployment workflow
allowed-tools: Read, Write
---
Reading workflow state from .claude/plugin-name-workflow.local.md...
Current stage: @.claude/plugin-name-workflow.local.md
[Parse YAML frontmatter to determine next step]
Next action based on state: [determined action]
```
### Workflow Recovery
Handle interrupted workflows:
```markdown
---
description: Resume deployment workflow
allowed-tools: Read
---
# Resume Deployment
Checking for interrupted workflow...
State file: @.claude/plugin-name-workflow.local.md
**Workflow found:**
- Started: [timestamp]
- Environment: [env]
- Last completed: [step]
**Recovery options:**
1. Resume from last step
2. Restart from beginning
3. Abort and clean up
Which would you like? (1/2/3)
```
## Workflow Coordination Patterns
### Cross-Command Communication
Commands that signal each other:
```markdown
---
description: Mark feature complete
allowed-tools: Write
---
# Mark Feature Complete
Writing completion marker...
Creating: .claude/feature-complete.flag
This signals other commands that feature is ready for:
- Integration testing (/integration-test will auto-detect)
- Documentation generation (/docs-generate will include)
- Release notes (/release-notes will add)
Feature marked complete.
```
**Other commands check for flag:**
```markdown
---
description: Generate release notes
allowed-tools: Read, Bash(git:*)
---
Checking for completed features...
if [ -f .claude/feature-complete.flag ]; then
Feature ready for release notes
fi
[Include in release notes]
```
### Workflow Locking
Prevent concurrent workflow execution:
```markdown
---
description: Start deployment
allowed-tools: Read, Write, Bash
---
# Start Deployment
Checking for active deployments...
if [ -f .claude/deployment.lock ]; then
ERROR: Deployment already in progress
Started: [timestamp from lock file]
Cannot start concurrent deployment.
Wait for completion or run /deployment-abort
Exit.
fi
Creating deployment lock...
Deployment started. Lock created.
[Proceed with deployment]
```
**Lock cleanup:**
```markdown
---
description: Complete deployment
allowed-tools: Write, Bash
---
Deployment complete.
Removing deployment lock...
rm .claude/deployment.lock
Ready for next deployment.
```
## Advanced Argument Handling
### Optional Arguments with Defaults
```markdown
---
description: Deploy with optional version
argument-hint: [environment] [version]
---
Environment: ${1:-staging}
Version: ${2:-latest}
Deploying ${2:-latest} to ${1:-staging}...
Note: Using defaults for missing arguments:
- Environment defaults to 'staging'
- Version defaults to 'latest'
```
### Argument Validation
```markdown
---
description: Deploy to validated environment
argument-hint: [environment]
---
Environment: $1
Validating environment...
valid_envs="dev staging production"
if ! echo "$valid_envs" | grep -w "$1" > /dev/null; then
ERROR: Invalid environment '$1'
Valid options: dev, staging, production
Exit.
fi
Environment validated. Proceeding...
```
### Argument Transformation
```markdown
---
description: Deploy with shorthand
argument-hint: [env-shorthand]
---
Input: $1
Expanding shorthand:
- d/dev → development
- s/stg → staging
- p/prod → production
case "$1" in
d|dev) ENV="development";;
s|stg) ENV="staging";;
p|prod) ENV="production";;
*) ENV="$1";;
esac
Deploying to: $ENV
```
## Error Handling in Workflows
### Graceful Failure
```markdown
---
description: Resilient deployment workflow
---
# Deployment Workflow
Running steps with error handling...
## Step 1: Tests
!`npm test`
if [ $? -ne 0 ]; then
ERROR: Tests failed
Options:
1. Fix tests and retry
2. Skip tests (NOT recommended)
3. Abort deployment
What would you like to do?
[Wait for user input before continuing]
fi
## Step 2: Build
[Continue only if Step 1 succeeded]
```
### Rollback on Failure
```markdown
---
description: Deployment with rollback
---
# Deploy with Rollback
Saving current state for rollback...
Previous version: !`current-version.sh`
Deploying new version...
!`deploy.sh`
if [ $? -ne 0 ]; then
DEPLOYMENT FAILED
Initiating automatic rollback...
!`rollback.sh`
Rolled back to previous version.
Check logs for failure details.
fi
Deployment complete.
```
### Checkpoint Recovery
```markdown
---
description: Workflow with checkpoints
---
# Multi-Stage Deployment
## Checkpoint 1: Validation
!`validate.sh`
echo "checkpoint:validation" >> .claude/deployment-checkpoints.log
## Checkpoint 2: Build
!`build.sh`
echo "checkpoint:build" >> .claude/deployment-checkpoints.log
## Checkpoint 3: Deploy
!`deploy.sh`
echo "checkpoint:deploy" >> .claude/deployment-checkpoints.log
If any step fails, resume with:
/deployment-resume [last-successful-checkpoint]
```
## Best Practices
### Workflow Design
1. **Clear progression**: Number steps, show current position
2. **Explicit state**: Don't rely on implicit state
3. **User control**: Provide decision points
4. **Error recovery**: Handle failures gracefully
5. **Progress indication**: Show what's done, what's pending
### Command Composition
1. **Single responsibility**: Each command does one thing well
2. **Composable design**: Commands work together easily
3. **Standard interfaces**: Consistent input/output formats
4. **Loose coupling**: Commands don't depend on each other's internals
### State Management
1. **Persistent state**: Use .local.md files
2. **Atomic updates**: Write complete state files atomically
3. **State validation**: Check state file format/completeness
4. **Cleanup**: Remove stale state files
5. **Documentation**: Document state file formats
### Error Handling
1. **Fail fast**: Detect errors early
2. **Clear messages**: Explain what went wrong
3. **Recovery options**: Provide clear next steps
4. **State preservation**: Keep state for recovery
5. **Rollback capability**: Support undoing changes
## Example: Complete Deployment Workflow
### Initialize Command
```markdown
---
description: Initialize deployment
argument-hint: [environment]
allowed-tools: Write, Bash(git:*)
---
# Initialize Deployment to $1
Creating workflow state...
\`\`\`yaml
---
workflow: deployment
environment: $1
branch: !`git branch --show-current`
commit: !`git rev-parse HEAD`
stage: initialized
timestamp: !`date -u +%Y-%m-%dT%H:%M:%SZ`
---
\`\`\`
Written to .claude/deployment-state.local.md
Next: Run /deployment-validate
```
### Validation Command
```markdown
---
description: Validate deployment
allowed-tools: Read, Bash
---
Reading state: @.claude/deployment-state.local.md
Running validation...
- Branch check: PASS
- Tests: PASS
- Build: PASS
Updating state to 'validated'...
Next: Run /deployment-execute
```
### Execution Command
```markdown
---
description: Execute deployment
allowed-tools: Read, Bash, Write
---
Reading state: @.claude/deployment-state.local.md
Executing deployment to [environment]...
!`deploy.sh [environment]`
Deployment complete.
Updating state to 'completed'...
Cleanup: /deployment-cleanup
```
### Cleanup Command
```markdown
---
description: Clean up deployment
allowed-tools: Bash
---
Removing deployment state...
rm .claude/deployment-state.local.md
Deployment workflow complete.
```
This complete workflow demonstrates state management, sequential execution, error handling, and clean separation of concerns across multiple commands.
@@ -0,0 +1,739 @@
# Command Documentation Patterns
Strategies for creating self-documenting, maintainable commands with excellent user experience.
## Overview
Well-documented commands are easier to use, maintain, and distribute. Documentation should be embedded in the command itself, making it immediately accessible to users and maintainers.
## Self-Documenting Command Structure
### Complete Command Template
```markdown
---
description: Clear, actionable description under 60 chars
argument-hint: [arg1] [arg2] [optional-arg]
allowed-tools: Read, Bash(git:*)
model: sonnet
---
<!--
COMMAND: command-name
VERSION: 1.0.0
AUTHOR: Team Name
LAST UPDATED: 2025-01-15
PURPOSE:
Detailed explanation of what this command does and why it exists.
USAGE:
/command-name arg1 arg2
ARGUMENTS:
arg1: Description of first argument (required)
arg2: Description of second argument (optional, defaults to X)
EXAMPLES:
/command-name feature-branch main
→ Compares feature-branch with main
/command-name my-branch
→ Compares my-branch with current branch
REQUIREMENTS:
- Git repository
- Branch must exist
- Permissions to read repository
RELATED COMMANDS:
/other-command - Related functionality
/another-command - Alternative approach
TROUBLESHOOTING:
- If branch not found: Check branch name spelling
- If permission denied: Check repository access
CHANGELOG:
v1.0.0 (2025-01-15): Initial release
v0.9.0 (2025-01-10): Beta version
-->
# Command Implementation
[Command prompt content here...]
[Explain what will happen...]
[Guide user through steps...]
[Provide clear output...]
```
### Documentation Comment Sections
**PURPOSE**: Why the command exists
- Problem it solves
- Use cases
- When to use vs when not to use
**USAGE**: Basic syntax
- Command invocation pattern
- Required vs optional arguments
- Default values
**ARGUMENTS**: Detailed argument documentation
- Each argument described
- Type information
- Valid values/ranges
- Defaults
**EXAMPLES**: Concrete usage examples
- Common use cases
- Edge cases
- Expected outputs
**REQUIREMENTS**: Prerequisites
- Dependencies
- Permissions
- Environmental setup
**RELATED COMMANDS**: Connections
- Similar commands
- Complementary commands
- Alternative approaches
**TROUBLESHOOTING**: Common issues
- Known problems
- Solutions
- Workarounds
**CHANGELOG**: Version history
- What changed when
- Breaking changes highlighted
- Migration guidance
## In-Line Documentation Patterns
### Commented Sections
```markdown
---
description: Complex multi-step command
---
<!-- SECTION 1: VALIDATION -->
<!-- This section checks prerequisites before proceeding -->
Checking prerequisites...
- Git repository: !`git rev-parse --git-dir 2>/dev/null`
- Branch exists: [validation logic]
<!-- SECTION 2: ANALYSIS -->
<!-- Analyzes the differences between branches -->
Analyzing differences between $1 and $2...
[Analysis logic...]
<!-- SECTION 3: RECOMMENDATIONS -->
<!-- Provides actionable recommendations -->
Based on analysis, recommend:
[Recommendations...]
<!-- END: Next steps for user -->
```
### Inline Explanations
```markdown
---
description: Deployment command with inline docs
---
# Deploy to $1
## Pre-flight Checks
<!-- We check branch status to prevent deploying from wrong branch -->
Current branch: !`git branch --show-current`
<!-- Production deploys must come from main/master -->
if [ "$1" = "production" ] && [ "$(git branch --show-current)" != "main" ]; then
⚠️ WARNING: Not on main branch for production deploy
This is unusual. Confirm this is intentional.
fi
<!-- Test status ensures we don't deploy broken code -->
Running tests: !`npm test`
✓ All checks passed
## Deployment
<!-- Actual deployment happens here -->
<!-- Uses blue-green strategy for zero-downtime -->
Deploying to $1 environment...
[Deployment steps...]
<!-- Post-deployment verification -->
Verifying deployment health...
[Health checks...]
Deployment complete!
## Next Steps
<!-- Guide user on what to do after deployment -->
1. Monitor logs: /logs $1
2. Run smoke tests: /smoke-test $1
3. Notify team: /notify-deployment $1
```
### Decision Point Documentation
```markdown
---
description: Interactive deployment command
---
# Interactive Deployment
## Configuration Review
Target: $1
Current version: !`cat version.txt`
New version: $2
<!-- DECISION POINT: User confirms configuration -->
<!-- This pause allows user to verify everything is correct -->
<!-- We can't automatically proceed because deployment is risky -->
Review the above configuration.
**Continue with deployment?**
- Reply "yes" to proceed
- Reply "no" to cancel
- Reply "edit" to modify configuration
[Await user input before continuing...]
<!-- After user confirms, we proceed with deployment -->
<!-- All subsequent steps are automated -->
Proceeding with deployment...
```
## Help Text Patterns
### Built-in Help Command
Create a help subcommand for complex commands:
```markdown
---
description: Main command with help
argument-hint: [subcommand] [args]
---
# Command Processor
if [ "$1" = "help" ] || [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
**Command Help**
USAGE:
/command [subcommand] [args]
SUBCOMMANDS:
init [name] Initialize new configuration
deploy [env] Deploy to environment
status Show current status
rollback Rollback last deployment
help Show this help
EXAMPLES:
/command init my-project
/command deploy staging
/command status
/command rollback
For detailed help on a subcommand:
/command [subcommand] --help
Exit.
fi
[Regular command processing...]
```
### Contextual Help
Provide help based on context:
```markdown
---
description: Context-aware command
argument-hint: [operation] [target]
---
# Context-Aware Operation
if [ -z "$1" ]; then
**No operation specified**
Available operations:
- analyze: Analyze target for issues
- fix: Apply automatic fixes
- report: Generate detailed report
Usage: /command [operation] [target]
Examples:
/command analyze src/
/command fix src/app.js
/command report
Run /command help for more details.
Exit.
fi
[Command continues if operation provided...]
```
## Error Message Documentation
### Helpful Error Messages
```markdown
---
description: Command with good error messages
---
# Validation Command
if [ -z "$1" ]; then
❌ ERROR: Missing required argument
The 'file-path' argument is required.
USAGE:
/validate [file-path]
EXAMPLE:
/validate src/app.js
Try again with a file path.
Exit.
fi
if [ ! -f "$1" ]; then
❌ ERROR: File not found: $1
The specified file does not exist or is not accessible.
COMMON CAUSES:
1. Typo in file path
2. File was deleted or moved
3. Insufficient permissions
SUGGESTIONS:
- Check spelling: $1
- Verify file exists: ls -la $(dirname "$1")
- Check permissions: ls -l "$1"
Exit.
fi
[Command continues if validation passes...]
```
### Error Recovery Guidance
```markdown
---
description: Command with recovery guidance
---
# Operation Command
Running operation...
!`risky-operation.sh`
if [ $? -ne 0 ]; then
❌ OPERATION FAILED
The operation encountered an error and could not complete.
WHAT HAPPENED:
The risky-operation.sh script returned a non-zero exit code.
WHAT THIS MEANS:
- Changes may be partially applied
- System may be in inconsistent state
- Manual intervention may be needed
RECOVERY STEPS:
1. Check operation logs: cat /tmp/operation.log
2. Verify system state: /check-state
3. If needed, rollback: /rollback-operation
4. Fix underlying issue
5. Retry operation: /retry-operation
NEED HELP?
- Check troubleshooting guide: /help troubleshooting
- Contact support with error code: ERR_OP_FAILED_001
Exit.
fi
```
## Usage Example Documentation
### Embedded Examples
```markdown
---
description: Command with embedded examples
---
# Feature Command
This command performs feature analysis with multiple options.
## Basic Usage
\`\`\`
/feature analyze src/
\`\`\`
Analyzes all files in src/ directory for feature usage.
## Advanced Usage
\`\`\`
/feature analyze src/ --detailed
\`\`\`
Provides detailed analysis including:
- Feature breakdown by file
- Usage patterns
- Optimization suggestions
## Use Cases
**Use Case 1: Quick overview**
\`\`\`
/feature analyze .
\`\`\`
Get high-level feature summary of entire project.
**Use Case 2: Specific directory**
\`\`\`
/feature analyze src/components
\`\`\`
Focus analysis on components directory only.
**Use Case 3: Comparison**
\`\`\`
/feature analyze src/ --compare baseline.json
\`\`\`
Compare current features against baseline.
---
Now processing your request...
[Command implementation...]
```
### Example-Driven Documentation
```markdown
---
description: Example-heavy command
---
# Transformation Command
## What This Does
Transforms data from one format to another.
## Examples First
### Example 1: JSON to YAML
**Input:** `data.json`
\`\`\`json
{"name": "test", "value": 42}
\`\`\`
**Command:** `/transform data.json yaml`
**Output:** `data.yaml`
\`\`\`yaml
name: test
value: 42
\`\`\`
### Example 2: CSV to JSON
**Input:** `data.csv`
\`\`\`csv
name,value
test,42
\`\`\`
**Command:** `/transform data.csv json`
**Output:** `data.json`
\`\`\`json
[{"name": "test", "value": "42"}]
\`\`\`
### Example 3: With Options
**Command:** `/transform data.json yaml --pretty --sort-keys`
**Result:** Formatted YAML with sorted keys
---
## Your Transformation
File: $1
Format: $2
[Perform transformation...]
```
## Maintenance Documentation
### Version and Changelog
```markdown
<!--
VERSION: 2.1.0
LAST UPDATED: 2025-01-15
AUTHOR: DevOps Team
CHANGELOG:
v2.1.0 (2025-01-15):
- Added support for YAML configuration
- Improved error messages
- Fixed bug with special characters in arguments
v2.0.0 (2025-01-01):
- BREAKING: Changed argument order
- BREAKING: Removed deprecated --old-flag
- Added new validation checks
- Migration guide: /migration-v2
v1.5.0 (2024-12-15):
- Added --verbose flag
- Improved performance by 50%
v1.0.0 (2024-12-01):
- Initial stable release
MIGRATION NOTES:
From v1.x to v2.0:
Old: /command arg1 arg2 --old-flag
New: /command arg2 arg1
The --old-flag is removed. Use --new-flag instead.
DEPRECATION WARNINGS:
- The --legacy-mode flag is deprecated as of v2.1.0
- Will be removed in v3.0.0 (estimated 2025-06-01)
- Use --modern-mode instead
KNOWN ISSUES:
- #123: Slow performance with large files (workaround: use --stream flag)
- #456: Special characters in Windows (fix planned for v2.2.0)
-->
```
### Maintenance Notes
```markdown
<!--
MAINTENANCE NOTES:
CODE STRUCTURE:
- Lines 1-50: Argument parsing and validation
- Lines 51-100: Main processing logic
- Lines 101-150: Output formatting
- Lines 151-200: Error handling
DEPENDENCIES:
- Requires git 2.x or later
- Uses jq for JSON processing
- Needs bash 4.0+ for associative arrays
PERFORMANCE:
- Fast path for small inputs (< 1MB)
- Streams large files to avoid memory issues
- Caches results in /tmp for 1 hour
SECURITY CONSIDERATIONS:
- Validates all inputs to prevent injection
- Uses allowed-tools to limit Bash access
- No credentials in command file
TESTING:
- Unit tests: tests/command-test.sh
- Integration tests: tests/integration/
- Manual test checklist: tests/manual-checklist.md
FUTURE IMPROVEMENTS:
- TODO: Add support for TOML format
- TODO: Implement parallel processing
- TODO: Add progress bar for large files
RELATED FILES:
- lib/parser.sh: Shared parsing logic
- lib/formatter.sh: Output formatting
- config/defaults.yml: Default configuration
-->
```
## README Documentation
Commands should have companion README files:
```markdown
# Command Name
Brief description of what the command does.
## Installation
This command is part of the [plugin-name] plugin.
Install with:
\`\`\`
/plugin install plugin-name
\`\`\`
## Usage
Basic usage:
\`\`\`
/command-name [arg1] [arg2]
\`\`\`
## Arguments
- `arg1`: Description (required)
- `arg2`: Description (optional, defaults to X)
## Examples
### Example 1: Basic Usage
\`\`\`
/command-name value1 value2
\`\`\`
Description of what happens.
### Example 2: Advanced Usage
\`\`\`
/command-name value1 --option
\`\`\`
Description of advanced feature.
## Configuration
Optional configuration file: `.claude/command-name.local.md`
\`\`\`markdown
---
default_arg: value
enable_feature: true
---
\`\`\`
## Requirements
- Git 2.x or later
- jq (for JSON processing)
- Node.js 14+ (optional, for advanced features)
## Troubleshooting
### Issue: Command not found
**Solution:** Ensure plugin is installed and enabled.
### Issue: Permission denied
**Solution:** Check file permissions and allowed-tools setting.
## Contributing
Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md).
## License
MIT License - See [LICENSE](LICENSE).
## Support
- Issues: https://github.com/user/plugin/issues
- Docs: https://docs.example.com
- Email: support@example.com
```
## Best Practices
### Documentation Principles
1. **Write for your future self**: Assume you'll forget details
2. **Examples before explanations**: Show, then tell
3. **Progressive disclosure**: Basic info first, details available
4. **Keep it current**: Update docs when code changes
5. **Test your docs**: Verify examples actually work
### Documentation Locations
1. **In command file**: Core usage, examples, inline explanations
2. **README**: Installation, configuration, troubleshooting
3. **Separate docs**: Detailed guides, tutorials, API reference
4. **Comments**: Implementation details for maintainers
### Documentation Style
1. **Clear and concise**: No unnecessary words
2. **Active voice**: "Run the command" not "The command can be run"
3. **Consistent terminology**: Use same terms throughout
4. **Formatted well**: Use headings, lists, code blocks
5. **Accessible**: Assume reader is beginner
### Documentation Maintenance
1. **Version everything**: Track what changed when
2. **Deprecate gracefully**: Warn before removing features
3. **Migration guides**: Help users upgrade
4. **Archive old docs**: Keep old versions accessible
5. **Review regularly**: Ensure docs match reality
## Documentation Checklist
Before releasing a command:
- [ ] Description in frontmatter is clear
- [ ] argument-hint documents all arguments
- [ ] Usage examples in comments
- [ ] Common use cases shown
- [ ] Error messages are helpful
- [ ] Requirements documented
- [ ] Related commands listed
- [ ] Changelog maintained
- [ ] Version number updated
- [ ] README created/updated
- [ ] Examples actually work
- [ ] Troubleshooting section complete
With good documentation, commands become self-service, reducing support burden and improving user experience.
@@ -0,0 +1,463 @@
# Command Frontmatter Reference
Complete reference for YAML frontmatter fields in slash commands.
## Frontmatter Overview
YAML frontmatter is optional metadata at the start of command files:
```markdown
---
description: Brief description
allowed-tools: Read, Write
model: sonnet
argument-hint: [arg1] [arg2]
---
Command prompt content here...
```
All fields are optional. Commands work without any frontmatter.
## Field Specifications
### description
**Type:** String
**Required:** No
**Default:** First line of command prompt
**Max Length:** ~60 characters recommended for `/help` display
**Purpose:** Describes what the command does, shown in `/help` output
**Examples:**
```yaml
description: Review code for security issues
```
```yaml
description: Deploy to staging environment
```
```yaml
description: Generate API documentation
```
**Best practices:**
- Keep under 60 characters for clean display
- Start with verb (Review, Deploy, Generate)
- Be specific about what command does
- Avoid redundant "command" or "slash command"
**Good:**
- ✅ "Review PR for code quality and security"
- ✅ "Deploy application to specified environment"
- ✅ "Generate comprehensive API documentation"
**Bad:**
- ❌ "This command reviews PRs" (unnecessary "This command")
- ❌ "Review" (too vague)
- ❌ "A command that reviews pull requests for code quality, security issues, and best practices" (too long)
### allowed-tools
**Type:** String or Array of strings
**Required:** No
**Default:** Inherits from conversation permissions
**Purpose:** Restrict or specify which tools command can use
**Formats:**
**Single tool:**
```yaml
allowed-tools: Read
```
**Multiple tools (comma-separated):**
```yaml
allowed-tools: Read, Write, Edit
```
**Multiple tools (array):**
```yaml
allowed-tools:
- Read
- Write
- Bash(git:*)
```
**Tool Patterns:**
**Specific tools:**
```yaml
allowed-tools: Read, Grep, Edit
```
**Bash with command filter:**
```yaml
allowed-tools: Bash(git:*) # Only git commands
allowed-tools: Bash(npm:*) # Only npm commands
allowed-tools: Bash(docker:*) # Only docker commands
```
**All tools (not recommended):**
```yaml
allowed-tools: "*"
```
**When to use:**
1. **Security:** Restrict command to safe operations
```yaml
allowed-tools: Read, Grep # Read-only command
```
2. **Clarity:** Document required tools
```yaml
allowed-tools: Bash(git:*), Read
```
3. **Bash execution:** Enable bash command output
```yaml
allowed-tools: Bash(git status:*), Bash(git diff:*)
```
**Best practices:**
- Be as restrictive as possible
- Use command filters for Bash (e.g., `git:*` not `*`)
- Only specify when different from conversation permissions
- Document why specific tools are needed
### model
**Type:** String
**Required:** No
**Default:** Inherits from conversation
**Values:** `sonnet`, `opus`, `haiku`
**Purpose:** Specify which Claude model executes the command
**Examples:**
```yaml
model: haiku # Fast, efficient for simple tasks
```
```yaml
model: sonnet # Balanced performance (default)
```
```yaml
model: opus # Maximum capability for complex tasks
```
**When to use:**
**Use `haiku` for:**
- Simple, formulaic commands
- Fast execution needed
- Low complexity tasks
- Frequent invocations
```yaml
---
description: Format code file
model: haiku
---
```
**Use `sonnet` for:**
- Standard commands (default)
- Balanced speed/quality
- Most common use cases
```yaml
---
description: Review code changes
model: sonnet
---
```
**Use `opus` for:**
- Complex analysis
- Architectural decisions
- Deep code understanding
- Critical tasks
```yaml
---
description: Analyze system architecture
model: opus
---
```
**Best practices:**
- Omit unless specific need
- Use `haiku` for speed when possible
- Reserve `opus` for genuinely complex tasks
- Test with different models to find right balance
### argument-hint
**Type:** String
**Required:** No
**Default:** None
**Purpose:** Document expected arguments for users and autocomplete
**Format:**
```yaml
argument-hint: [arg1] [arg2] [optional-arg]
```
**Examples:**
**Single argument:**
```yaml
argument-hint: [pr-number]
```
**Multiple required arguments:**
```yaml
argument-hint: [environment] [version]
```
**Optional arguments:**
```yaml
argument-hint: [file-path] [options]
```
**Descriptive names:**
```yaml
argument-hint: [source-branch] [target-branch] [commit-message]
```
**Best practices:**
- Use square brackets `[]` for each argument
- Use descriptive names (not `arg1`, `arg2`)
- Indicate optional vs required in description
- Match order to positional arguments in command
- Keep concise but clear
**Examples by pattern:**
**Simple command:**
```yaml
---
description: Fix issue by number
argument-hint: [issue-number]
---
Fix issue #$1...
```
**Multi-argument:**
```yaml
---
description: Deploy to environment
argument-hint: [app-name] [environment] [version]
---
Deploy $1 to $2 using version $3...
```
**With options:**
```yaml
---
description: Run tests with options
argument-hint: [test-pattern] [options]
---
Run tests matching $1 with options: $2
```
### disable-model-invocation
**Type:** Boolean
**Required:** No
**Default:** false
**Purpose:** Prevent SlashCommand tool from programmatically invoking command
**Examples:**
```yaml
disable-model-invocation: true
```
**When to use:**
1. **Manual-only commands:** Commands requiring user judgment
```yaml
---
description: Approve deployment to production
disable-model-invocation: true
---
```
2. **Destructive operations:** Commands with irreversible effects
```yaml
---
description: Delete all test data
disable-model-invocation: true
---
```
3. **Interactive workflows:** Commands needing user input
```yaml
---
description: Walk through setup wizard
disable-model-invocation: true
---
```
**Default behavior (false):**
- Command available to SlashCommand tool
- Claude can invoke programmatically
- Still available for manual invocation
**When true:**
- Command only invokable by user typing `/command`
- Not available to SlashCommand tool
- Safer for sensitive operations
**Best practices:**
- Use sparingly (limits Claude's autonomy)
- Document why in command comments
- Consider if command should exist if always manual
## Complete Examples
### Minimal Command
No frontmatter needed:
```markdown
Review this code for common issues and suggest improvements.
```
### Simple Command
Just description:
```markdown
---
description: Review code for issues
---
Review this code for common issues and suggest improvements.
```
### Standard Command
Description and tools:
```markdown
---
description: Review Git changes
allowed-tools: Bash(git:*), Read
---
Current changes: !`git diff --name-only`
Review each changed file for:
- Code quality
- Potential bugs
- Best practices
```
### Complex Command
All common fields:
```markdown
---
description: Deploy application to environment
argument-hint: [app-name] [environment] [version]
allowed-tools: Bash(kubectl:*), Bash(helm:*), Read
model: sonnet
---
Deploy $1 to $2 environment using version $3
Pre-deployment checks:
- Verify $2 configuration
- Check cluster status: !`kubectl cluster-info`
- Validate version $3 exists
Proceed with deployment following deployment runbook.
```
### Manual-Only Command
Restricted invocation:
```markdown
---
description: Approve production deployment
argument-hint: [deployment-id]
disable-model-invocation: true
allowed-tools: Bash(gh:*)
---
<!--
MANUAL APPROVAL REQUIRED
This command requires human judgment and cannot be automated.
-->
Review deployment $1 for production approval:
Deployment details: !`gh api /deployments/$1`
Verify:
- All tests passed
- Security scan clean
- Stakeholder approval
- Rollback plan ready
Type "APPROVED" to confirm deployment.
```
## Validation
### Common Errors
**Invalid YAML syntax:**
```yaml
---
description: Missing quote
allowed-tools: Read, Write
model: sonnet
--- # ❌ Missing closing quote above
```
**Fix:** Validate YAML syntax
**Incorrect tool specification:**
```yaml
allowed-tools: Bash # ❌ Missing command filter
```
**Fix:** Use `Bash(git:*)` format
**Invalid model name:**
```yaml
model: gpt4 # ❌ Not a valid Claude model
```
**Fix:** Use `sonnet`, `opus`, or `haiku`
### Validation Checklist
Before committing command:
- [ ] YAML syntax valid (no errors)
- [ ] Description under 60 characters
- [ ] allowed-tools uses proper format
- [ ] model is valid value if specified
- [ ] argument-hint matches positional arguments
- [ ] disable-model-invocation used appropriately
## Best Practices Summary
1. **Start minimal:** Add frontmatter only when needed
2. **Document arguments:** Always use argument-hint with arguments
3. **Restrict tools:** Use most restrictive allowed-tools that works
4. **Choose right model:** Use haiku for speed, opus for complexity
5. **Manual-only sparingly:** Only use disable-model-invocation when necessary
6. **Clear descriptions:** Make commands discoverable in `/help`
7. **Test thoroughly:** Verify frontmatter works as expected
@@ -0,0 +1,920 @@
# Interactive Command Patterns
Comprehensive guide to creating commands that gather user feedback and make decisions through the AskUserQuestion tool.
## Overview
Some commands need user input that doesn't work well with simple arguments. For example:
- Choosing between multiple complex options with trade-offs
- Selecting multiple items from a list
- Making decisions that require explanation
- Gathering preferences or configuration interactively
For these cases, use the **AskUserQuestion tool** within command execution rather than relying on command arguments.
## When to Use AskUserQuestion
### Use AskUserQuestion When:
1. **Multiple choice decisions** with explanations needed
2. **Complex options** that require context to choose
3. **Multi-select scenarios** (choosing multiple items)
4. **Preference gathering** for configuration
5. **Interactive workflows** that adapt based on answers
### Use Command Arguments When:
1. **Simple values** (file paths, numbers, names)
2. **Known inputs** user already has
3. **Scriptable workflows** that should be automatable
4. **Fast invocations** where prompting would slow down
## AskUserQuestion Basics
### Tool Parameters
```typescript
{
questions: [
{
question: "Which authentication method should we use?",
header: "Auth method", // Short label (max 12 chars)
multiSelect: false, // true for multiple selection
options: [
{
label: "OAuth 2.0",
description: "Industry standard, supports multiple providers"
},
{
label: "JWT",
description: "Stateless, good for APIs"
},
{
label: "Session",
description: "Traditional, server-side state"
}
]
}
]
}
```
**Key points:**
- Users can always choose "Other" to provide custom input (automatic)
- `multiSelect: true` allows selecting multiple options
- Options should be 2-4 choices (not more)
- Can ask 1-4 questions per tool call
## Command Pattern for User Interaction
### Basic Interactive Command
```markdown
---
description: Interactive setup command
allowed-tools: AskUserQuestion, Write
---
# Interactive Plugin Setup
This command will guide you through configuring the plugin with a series of questions.
## Step 1: Gather Configuration
Use the AskUserQuestion tool to ask:
**Question 1 - Deployment target:**
- header: "Deploy to"
- question: "Which deployment platform will you use?"
- options:
- AWS (Amazon Web Services with ECS/EKS)
- GCP (Google Cloud with GKE)
- Azure (Microsoft Azure with AKS)
- Local (Docker on local machine)
**Question 2 - Environment strategy:**
- header: "Environments"
- question: "How many environments do you need?"
- options:
- Single (Just production)
- Standard (Dev, Staging, Production)
- Complete (Dev, QA, Staging, Production)
**Question 3 - Features to enable:**
- header: "Features"
- question: "Which features do you want to enable?"
- multiSelect: true
- options:
- Auto-scaling (Automatic resource scaling)
- Monitoring (Health checks and metrics)
- CI/CD (Automated deployment pipeline)
- Backups (Automated database backups)
## Step 2: Process Answers
Based on the answers received from AskUserQuestion:
1. Parse the deployment target choice
2. Set up environment-specific configuration
3. Enable selected features
4. Generate configuration files
## Step 3: Generate Configuration
Create `.claude/plugin-name.local.md` with:
\`\`\`yaml
---
deployment_target: [answer from Q1]
environments: [answer from Q2]
features:
auto_scaling: [true if selected in Q3]
monitoring: [true if selected in Q3]
ci_cd: [true if selected in Q3]
backups: [true if selected in Q3]
---
# Plugin Configuration
Generated: [timestamp]
Target: [deployment_target]
Environments: [environments]
\`\`\`
## Step 4: Confirm and Next Steps
Confirm configuration created and guide user on next steps.
```
### Multi-Stage Interactive Workflow
```markdown
---
description: Multi-stage interactive workflow
allowed-tools: AskUserQuestion, Read, Write, Bash
---
# Multi-Stage Deployment Setup
This command walks through deployment setup in stages, adapting based on your answers.
## Stage 1: Basic Configuration
Use AskUserQuestion to ask about deployment basics.
Based on answers, determine which additional questions to ask.
## Stage 2: Advanced Options (Conditional)
If user selected "Advanced" deployment in Stage 1:
Use AskUserQuestion to ask about:
- Load balancing strategy
- Caching configuration
- Security hardening options
If user selected "Simple" deployment:
- Skip advanced questions
- Use sensible defaults
## Stage 3: Confirmation
Show summary of all selections.
Use AskUserQuestion for final confirmation:
- header: "Confirm"
- question: "Does this configuration look correct?"
- options:
- Yes (Proceed with setup)
- No (Start over)
- Modify (Let me adjust specific settings)
If "Modify", ask which specific setting to change.
## Stage 4: Execute Setup
Based on confirmed configuration, execute setup steps.
```
## Interactive Question Design
### Question Structure
**Good questions:**
```markdown
Question: "Which database should we use for this project?"
Header: "Database"
Options:
- PostgreSQL (Relational, ACID compliant, best for complex queries)
- MongoDB (Document store, flexible schema, best for rapid iteration)
- Redis (In-memory, fast, best for caching and sessions)
```
**Poor questions:**
```markdown
Question: "Database?" // Too vague
Header: "DB" // Unclear abbreviation
Options:
- Option 1 // Not descriptive
- Option 2
```
### Option Design Best Practices
**Clear labels:**
- Use 1-5 words
- Specific and descriptive
- No jargon without context
**Helpful descriptions:**
- Explain what the option means
- Mention key benefits or trade-offs
- Help user make informed decision
- Keep to 1-2 sentences
**Appropriate number:**
- 2-4 options per question
- Don't overwhelm with too many choices
- Group related options
- "Other" automatically provided
### Multi-Select Questions
**When to use multiSelect:**
```markdown
Use AskUserQuestion for enabling features:
Question: "Which features do you want to enable?"
Header: "Features"
multiSelect: true // Allow selecting multiple
Options:
- Logging (Detailed operation logs)
- Metrics (Performance monitoring)
- Alerts (Error notifications)
- Backups (Automatic backups)
```
User can select any combination: none, some, or all.
**When NOT to use multiSelect:**
```markdown
Question: "Which authentication method?"
multiSelect: false // Only one auth method makes sense
```
Mutually exclusive choices should not use multiSelect.
## Command Patterns with AskUserQuestion
### Pattern 1: Simple Yes/No Decision
```markdown
---
description: Command with confirmation
allowed-tools: AskUserQuestion, Bash
---
# Destructive Operation
This operation will delete all cached data.
Use AskUserQuestion to confirm:
Question: "This will delete all cached data. Are you sure?"
Header: "Confirm"
Options:
- Yes (Proceed with deletion)
- No (Cancel operation)
If user selects "Yes":
Execute deletion
Report completion
If user selects "No":
Cancel operation
Exit without changes
```
### Pattern 2: Multiple Configuration Questions
```markdown
---
description: Multi-question configuration
allowed-tools: AskUserQuestion, Write
---
# Project Configuration Setup
Gather configuration through multiple questions.
Use AskUserQuestion with multiple questions in one call:
**Question 1:**
- question: "Which programming language?"
- header: "Language"
- options: Python, TypeScript, Go, Rust
**Question 2:**
- question: "Which test framework?"
- header: "Testing"
- options: Jest, PyTest, Go Test, Cargo Test
(Adapt based on language from Q1)
**Question 3:**
- question: "Which CI/CD platform?"
- header: "CI/CD"
- options: GitHub Actions, GitLab CI, CircleCI
**Question 4:**
- question: "Which features do you need?"
- header: "Features"
- multiSelect: true
- options: Linting, Type checking, Code coverage, Security scanning
Process all answers together to generate cohesive configuration.
```
### Pattern 3: Conditional Question Flow
```markdown
---
description: Conditional interactive workflow
allowed-tools: AskUserQuestion, Read, Write
---
# Adaptive Configuration
## Question 1: Deployment Complexity
Use AskUserQuestion:
Question: "How complex is your deployment?"
Header: "Complexity"
Options:
- Simple (Single server, straightforward)
- Standard (Multiple servers, load balancing)
- Complex (Microservices, orchestration)
## Conditional Questions Based on Answer
If answer is "Simple":
- No additional questions
- Use minimal configuration
If answer is "Standard":
- Ask about load balancing strategy
- Ask about scaling policy
If answer is "Complex":
- Ask about orchestration platform (Kubernetes, Docker Swarm)
- Ask about service mesh (Istio, Linkerd, None)
- Ask about monitoring (Prometheus, Datadog, CloudWatch)
- Ask about logging aggregation
## Process Conditional Answers
Generate configuration appropriate for selected complexity level.
```
### Pattern 4: Iterative Collection
```markdown
---
description: Collect multiple items iteratively
allowed-tools: AskUserQuestion, Write
---
# Collect Team Members
We'll collect team member information for the project.
## Question: How many team members?
Use AskUserQuestion:
Question: "How many team members should we set up?"
Header: "Team size"
Options:
- 2 people
- 3 people
- 4 people
- 6 people
## Iterate Through Team Members
For each team member (1 to N based on answer):
Use AskUserQuestion for member details:
Question: "What role for team member [number]?"
Header: "Role"
Options:
- Frontend Developer
- Backend Developer
- DevOps Engineer
- QA Engineer
- Designer
Store each member's information.
## Generate Team Configuration
After collecting all N members, create team configuration file with all members and their roles.
```
### Pattern 5: Dependency Selection
```markdown
---
description: Select dependencies with multi-select
allowed-tools: AskUserQuestion
---
# Configure Project Dependencies
## Question: Required Libraries
Use AskUserQuestion with multiSelect:
Question: "Which libraries does your project need?"
Header: "Dependencies"
multiSelect: true
Options:
- React (UI framework)
- Express (Web server)
- TypeORM (Database ORM)
- Jest (Testing framework)
- Axios (HTTP client)
User can select any combination.
## Process Selections
For each selected library:
- Add to package.json dependencies
- Generate sample configuration
- Create usage examples
- Update documentation
```
## Best Practices for Interactive Commands
### Question Design
1. **Clear and specific**: Question should be unambiguous
2. **Concise header**: Max 12 characters for clean display
3. **Helpful options**: Labels are clear, descriptions explain trade-offs
4. **Appropriate count**: 2-4 options per question, 1-4 questions per call
5. **Logical order**: Questions flow naturally
### Error Handling
```markdown
# Handle AskUserQuestion Responses
After calling AskUserQuestion, verify answers received:
If answers are empty or invalid:
Something went wrong gathering responses.
Please try again or provide configuration manually:
[Show alternative approach]
Exit.
If answers look correct:
Process as expected
```
### Progressive Disclosure
```markdown
# Start Simple, Get Detailed as Needed
## Question 1: Setup Type
Use AskUserQuestion:
Question: "How would you like to set up?"
Header: "Setup type"
Options:
- Quick (Use recommended defaults)
- Custom (Configure all options)
- Guided (Step-by-step with explanations)
If "Quick":
Apply defaults, minimal questions
If "Custom":
Ask all available configuration questions
If "Guided":
Ask questions with extra explanation
Provide recommendations along the way
```
### Multi-Select Guidelines
**Good multi-select use:**
```markdown
Question: "Which features do you want to enable?"
multiSelect: true
Options:
- Logging
- Metrics
- Alerts
- Backups
Reason: User might want any combination
```
**Bad multi-select use:**
```markdown
Question: "Which database engine?"
multiSelect: true // ❌ Should be single-select
Reason: Can only use one database engine
```
## Advanced Patterns
### Validation Loop
```markdown
---
description: Interactive with validation
allowed-tools: AskUserQuestion, Bash
---
# Setup with Validation
## Gather Configuration
Use AskUserQuestion to collect settings.
## Validate Configuration
Check if configuration is valid:
- Required dependencies available?
- Settings compatible with each other?
- No conflicts detected?
If validation fails:
Show validation errors
Use AskUserQuestion to ask:
Question: "Configuration has issues. What would you like to do?"
Header: "Next step"
Options:
- Fix (Adjust settings to resolve issues)
- Override (Proceed despite warnings)
- Cancel (Abort setup)
Based on answer, retry or proceed or exit.
```
### Build Configuration Incrementally
```markdown
---
description: Incremental configuration builder
allowed-tools: AskUserQuestion, Write, Read
---
# Incremental Setup
## Phase 1: Core Settings
Use AskUserQuestion for core settings.
Save to `.claude/config-partial.yml`
## Phase 2: Review Core Settings
Show user the core settings:
Based on these core settings, you need to configure:
- [Setting A] (because you chose [X])
- [Setting B] (because you chose [Y])
Ready to continue?
## Phase 3: Detailed Settings
Use AskUserQuestion for settings based on Phase 1 answers.
Merge with core settings.
## Phase 4: Final Review
Present complete configuration.
Use AskUserQuestion for confirmation:
Question: "Is this configuration correct?"
Options:
- Yes (Save and apply)
- No (Start over)
- Modify (Edit specific settings)
```
### Dynamic Options Based on Context
```markdown
---
description: Context-aware questions
allowed-tools: AskUserQuestion, Bash, Read
---
# Context-Aware Setup
## Detect Current State
Check existing configuration:
- Current language: !`detect-language.sh`
- Existing frameworks: !`detect-frameworks.sh`
- Available tools: !`check-tools.sh`
## Ask Context-Appropriate Questions
Based on detected language, ask relevant questions.
If language is TypeScript:
Use AskUserQuestion:
Question: "Which TypeScript features should we enable?"
Options:
- Strict Mode (Maximum type safety)
- Decorators (Experimental decorator support)
- Path Mapping (Module path aliases)
If language is Python:
Use AskUserQuestion:
Question: "Which Python tools should we configure?"
Options:
- Type Hints (mypy for type checking)
- Black (Code formatting)
- Pylint (Linting and style)
Questions adapt to project context.
```
## Real-World Example: Multi-Agent Swarm Launch
**From multi-agent-swarm plugin:**
```markdown
---
description: Launch multi-agent swarm
allowed-tools: AskUserQuestion, Read, Write, Bash
---
# Launch Multi-Agent Swarm
## Interactive Mode (No Task List Provided)
If user didn't provide task list file, help create one interactively.
### Question 1: Agent Count
Use AskUserQuestion:
Question: "How many agents should we launch?"
Header: "Agent count"
Options:
- 2 agents (Best for simple projects)
- 3 agents (Good for medium projects)
- 4 agents (Standard team size)
- 6 agents (Large projects)
- 8 agents (Complex multi-component projects)
### Question 2: Task Definition Approach
Use AskUserQuestion:
Question: "How would you like to define tasks?"
Header: "Task setup"
Options:
- File (I have a task list file ready)
- Guided (Help me create tasks interactively)
- Custom (Other approach)
If "File":
Ask for file path
Validate file exists and has correct format
If "Guided":
Enter iterative task creation mode (see below)
### Question 3: Coordination Mode
Use AskUserQuestion:
Question: "How should agents coordinate?"
Header: "Coordination"
Options:
- Team Leader (One agent coordinates others)
- Collaborative (Agents coordinate as peers)
- Autonomous (Independent work, minimal coordination)
### Iterative Task Creation (If "Guided" Selected)
For each agent (1 to N from Question 1):
**Question A: Agent Name**
Question: "What should we call agent [number]?"
Header: "Agent name"
Options:
- auth-agent
- api-agent
- ui-agent
- db-agent
(Provide relevant suggestions based on common patterns)
**Question B: Task Type**
Question: "What task for [agent-name]?"
Header: "Task type"
Options:
- Authentication (User auth, JWT, OAuth)
- API Endpoints (REST/GraphQL APIs)
- UI Components (Frontend components)
- Database (Schema, migrations, queries)
- Testing (Test suites and coverage)
- Documentation (Docs, README, guides)
**Question C: Dependencies**
Question: "What does [agent-name] depend on?"
Header: "Dependencies"
multiSelect: true
Options:
- [List of previously defined agents]
- No dependencies
**Question D: Base Branch**
Question: "Which base branch for PR?"
Header: "PR base"
Options:
- main
- staging
- develop
Store all task information for each agent.
### Generate Task List File
After collecting all agent task details:
1. Ask for project name
2. Generate task list in proper format
3. Save to `.daisy/swarm/tasks.md`
4. Show user the file path
5. Proceed with launch using generated task list
```
## Best Practices
### Question Writing
1. **Be specific**: "Which database?" not "Choose option?"
2. **Explain trade-offs**: Describe pros/cons in option descriptions
3. **Provide context**: Question text should stand alone
4. **Guide decisions**: Help user make informed choice
5. **Keep concise**: Header max 12 chars, descriptions 1-2 sentences
### Option Design
1. **Meaningful labels**: Specific, clear names
2. **Informative descriptions**: Explain what each option does
3. **Show trade-offs**: Help user understand implications
4. **Consistent detail**: All options equally explained
5. **2-4 options**: Not too few, not too many
### Flow Design
1. **Logical order**: Questions flow naturally
2. **Build on previous**: Later questions use earlier answers
3. **Minimize questions**: Ask only what's needed
4. **Group related**: Ask related questions together
5. **Show progress**: Indicate where in flow
### User Experience
1. **Set expectations**: Tell user what to expect
2. **Explain why**: Help user understand purpose
3. **Provide defaults**: Suggest recommended options
4. **Allow escape**: Let user cancel or restart
5. **Confirm actions**: Summarize before executing
## Common Patterns
### Pattern: Feature Selection
```markdown
Use AskUserQuestion:
Question: "Which features do you need?"
Header: "Features"
multiSelect: true
Options:
- Authentication
- Authorization
- Rate Limiting
- Caching
```
### Pattern: Environment Configuration
```markdown
Use AskUserQuestion:
Question: "Which environment is this?"
Header: "Environment"
Options:
- Development (Local development)
- Staging (Pre-production testing)
- Production (Live environment)
```
### Pattern: Priority Selection
```markdown
Use AskUserQuestion:
Question: "What's the priority for this task?"
Header: "Priority"
Options:
- Critical (Must be done immediately)
- High (Important, do soon)
- Medium (Standard priority)
- Low (Nice to have)
```
### Pattern: Scope Selection
```markdown
Use AskUserQuestion:
Question: "What scope should we analyze?"
Header: "Scope"
Options:
- Current file (Just this file)
- Current directory (All files in directory)
- Entire project (Full codebase scan)
```
## Combining Arguments and Questions
### Use Both Appropriately
**Arguments for known values:**
```markdown
---
argument-hint: [project-name]
allowed-tools: AskUserQuestion, Write
---
Setup for project: $1
Now gather additional configuration...
Use AskUserQuestion for options that require explanation.
```
**Questions for complex choices:**
```markdown
Project name from argument: $1
Now use AskUserQuestion to choose:
- Architecture pattern
- Technology stack
- Deployment strategy
These require explanation, so questions work better than arguments.
```
## Troubleshooting
**Questions not appearing:**
- Verify AskUserQuestion in allowed-tools
- Check question format is correct
- Ensure options array has 2-4 items
**User can't make selection:**
- Check option labels are clear
- Verify descriptions are helpful
- Consider if too many options
- Ensure multiSelect setting is correct
**Flow feels confusing:**
- Reduce number of questions
- Group related questions
- Add explanation between stages
- Show progress through workflow
With AskUserQuestion, commands become interactive wizards that guide users through complex decisions while maintaining the clarity that simple arguments provide for straightforward inputs.

Some files were not shown because too many files have changed in this diff Show More