Compare commits

..

1 Commits

Author SHA1 Message Date
Octavian Guzu
cebbc4f721 Use gh.sh wrapper for all gh commands in triage and dedupe workflows 2026-02-25 13:43:36 +00:00
23 changed files with 284 additions and 1473 deletions

View File

@@ -13,7 +13,7 @@ To do this, follow these steps precisely:
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, use the comment script to post duplicates:
```
./scripts/comment-on-duplicates.sh --potential-duplicates <dup1> <dup2> <dup3>
./scripts/comment-on-duplicates.sh --base-issue <issue-number> --potential-duplicates <dup1> <dup2> <dup3>
```
Notes (be sure to tell this to your agents, too):

View File

@@ -0,0 +1,40 @@
---
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

View File

@@ -20,7 +20,7 @@ TOOLS:
- `./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)
- `./scripts/edit-issue-labels.sh --issue NUMBER --add-label LABEL --remove-label LABEL` — add or remove labels
TASK:
@@ -30,10 +30,7 @@ TASK:
**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.
4. First, check if this issue is actually about Claude Code (the CLI/IDE tool). Issues about the Claude API, claude.ai, the Claude app, Anthropic billing, or other Anthropic products should be labeled `invalid`. If invalid, apply only that label and stop.
5. Analyze and apply category labels:
- Type (bug, enhancement, question, etc.)
@@ -51,15 +48,15 @@ TASK:
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"`
`./scripts/edit-issue-labels.sh --issue ISSUE_NUMBER --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"`
`./scripts/edit-issue-labels.sh --issue ISSUE_NUMBER --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"`
`./scripts/edit-issue-labels.sh --issue ISSUE_NUMBER --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.
@@ -70,5 +67,4 @@ GUIDELINES:
- 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.
- It's okay to not add any labels if none are clearly applicable

View File

@@ -17,6 +17,7 @@ jobs:
permissions:
contents: read
issues: write
id-token: write
steps:
- name: Checkout repository
@@ -26,7 +27,6 @@ jobs:
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: "*"

View File

@@ -18,6 +18,7 @@ jobs:
permissions:
contents: read
issues: write
id-token: write
steps:
- name: Checkout repository
@@ -28,8 +29,6 @@ jobs:
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:
github_token: ${{ secrets.GITHUB_TOKEN }}
allowed_non_write_users: "*"

118
.github/workflows/oncall-triage.yml vendored Normal file
View File

@@ -0,0 +1,118 @@
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
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- 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
timeout-minutes: 10
uses: anthropics/claude-code-action@v1
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
allowed_non_write_users: "*"
prompt: |
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
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
claude_args: |
--mcp-config /tmp/mcp-config/mcp-servers.json
--allowedTools "mcp__github__list_issues,mcp__github__get_issue,mcp__github__get_issue_comments,mcp__github__update_issue"

File diff suppressed because it is too large Load Diff

View File

@@ -1,28 +0,0 @@
# 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.

View File

@@ -1,56 +0,0 @@
<?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>

View File

@@ -1,11 +0,0 @@
<?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>

View File

@@ -1,5 +0,0 @@
{
"permissions": {
"disableBypassPermissionsMode": "disable"
}
}

View File

@@ -1,28 +0,0 @@
<?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>

View File

@@ -1,28 +0,0 @@
<#
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"

View File

@@ -1,31 +0,0 @@
<?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>

View File

@@ -1,6 +1,6 @@
# Settings Examples
Example Claude Code settings files, primarily intended for organization-wide deployments. Use these as starting points — adjust them to fit your needs.
Example Claude Code settings files, primarily intended for organization-wide deployments. Use these are 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`).
@@ -26,10 +26,6 @@ These may be applied at any level of the [settings hierarchy](https://code.claud
- 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.

View File

@@ -68,7 +68,7 @@ Note: Still review Claude generated PR's.
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:
9. Post inline comments for each issue using `mcp__github_inline_comment__create_inline_comment`. 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

View File

@@ -1,13 +1,6 @@
---
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
user: "/hookify"
assistant: "I'll analyze the conversation to find behaviors you want to prevent"
<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
user: "Can you look back at this conversation and help me create hooks for the mistakes you made?"
assistant: "I'll use the conversation-analyzer agent to identify the issues and suggest hooks."
<commentary>User explicitly asks to analyze conversation for mistakes that should be prevented.</commentary></example>
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"]

View File

@@ -1,34 +1,33 @@
---
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:
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 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 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>
<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

View File

@@ -1,36 +1,35 @@
---
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:
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 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 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>
<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
@@ -182,4 +181,4 @@ Location: [path]
- 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?
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?

View File

@@ -1,35 +1,34 @@
---
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:
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 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 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>
<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

View File

@@ -1,28 +1,22 @@
#!/usr/bin/env bash
#
# Comments on a GitHub issue with a list of potential duplicates.
# Usage: ./comment-on-duplicates.sh --potential-duplicates 456 789 101
#
# The base issue number is read from the workflow event payload.
# Usage: ./comment-on-duplicates.sh --base-issue 123 --potential-duplicates 456 789 101
#
set -euo pipefail
REPO="anthropics/claude-code"
# Read from event payload so the issue number is bound to the triggering event.
# Falls back to workflow_dispatch inputs for manual runs.
BASE_ISSUE=$(jq -r '.issue.number // .inputs.issue_number // empty' "${GITHUB_EVENT_PATH:?GITHUB_EVENT_PATH not set}")
if ! [[ "$BASE_ISSUE" =~ ^[0-9]+$ ]]; then
echo "Error: no issue number in event payload" >&2
exit 1
fi
BASE_ISSUE=""
DUPLICATES=()
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--base-issue)
BASE_ISSUE="$2"
shift 2
;;
--potential-duplicates)
shift
while [[ $# -gt 0 && ! "$1" =~ ^-- ]]; do
@@ -31,12 +25,23 @@ while [[ $# -gt 0 ]]; do
done
;;
*)
echo "Error: unknown argument (only --potential-duplicates is accepted)" >&2
echo "Unknown option: $1" >&2
exit 1
;;
esac
done
# Validate base issue
if [[ -z "$BASE_ISSUE" ]]; then
echo "Error: --base-issue is required" >&2
exit 1
fi
if ! [[ "$BASE_ISSUE" =~ ^[0-9]+$ ]]; then
echo "Error: --base-issue must be a number, got: $BASE_ISSUE" >&2
exit 1
fi
# Validate duplicates
if [[ ${#DUPLICATES[@]} -eq 0 ]]; then
echo "Error: --potential-duplicates requires at least one issue number" >&2

View File

@@ -1,27 +1,22 @@
#!/usr/bin/env bash
#
# Edits labels on a GitHub issue.
# Usage: ./edit-issue-labels.sh --add-label bug --add-label needs-triage --remove-label untriaged
#
# The issue number is read from the workflow event payload.
# Usage: ./edit-issue-labels.sh --issue 123 --add-label bug --add-label needs-triage --remove-label untriaged
#
set -euo pipefail
# Read from event payload so the issue number is bound to the triggering event.
# Falls back to workflow_dispatch inputs for manual runs.
ISSUE=$(jq -r '.issue.number // .inputs.issue_number // empty' "${GITHUB_EVENT_PATH:?GITHUB_EVENT_PATH not set}")
if ! [[ "$ISSUE" =~ ^[0-9]+$ ]]; then
echo "Error: no issue number in event payload" >&2
exit 1
fi
ISSUE=""
ADD_LABELS=()
REMOVE_LABELS=()
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--issue)
ISSUE="$2"
shift 2
;;
--add-label)
ADD_LABELS+=("$2")
shift 2
@@ -31,12 +26,20 @@ while [[ $# -gt 0 ]]; do
shift 2
;;
*)
echo "Error: unknown argument (only --add-label and --remove-label are accepted)" >&2
exit 1
;;
esac
done
# Validate issue number
if [[ -z "$ISSUE" ]]; then
exit 1
fi
if ! [[ "$ISSUE" =~ ^[0-9]+$ ]]; then
exit 1
fi
if [[ ${#ADD_LABELS[@]} -eq 0 && ${#REMOVE_LABELS[@]} -eq 0 ]]; then
exit 1
fi

View File

@@ -2,7 +2,6 @@
set -euo pipefail
# Wrapper around gh CLI that only allows specific subcommands and flags.
# All commands are scoped to the current repository via GH_REPO or GITHUB_REPOSITORY.
#
# Usage:
# ./scripts/gh.sh issue view 123
@@ -11,17 +10,7 @@ set -euo pipefail
# ./scripts/gh.sh search issues "search query" --limit 10
# ./scripts/gh.sh label list --limit 100
export GH_HOST=github.com
REPO="${GH_REPO:-${GITHUB_REPOSITORY:-}}"
if [[ -z "$REPO" || "$REPO" == */*/* || "$REPO" != */* ]]; then
echo "Error: GH_REPO or GITHUB_REPOSITORY must be set to owner/repo format (e.g., GITHUB_REPOSITORY=anthropics/claude-code)" >&2
exit 1
fi
export GH_REPO="$REPO"
ALLOWED_FLAGS=(--comments --state --limit --label)
FLAGS_WITH_VALUES=(--state --limit --label)
SUB1="${1:-}"
SUB2="${2:-}"
@@ -30,22 +19,13 @@ case "$CMD" in
"issue view"|"issue list"|"search issues"|"label list")
;;
*)
echo "Error: only 'issue view', 'issue list', 'search issues', 'label list' are allowed (e.g., ./scripts/gh.sh issue view 123)" >&2
exit 1
;;
esac
shift 2
# Separate flags from positional arguments
POSITIONAL=()
FLAGS=()
skip_next=false
for arg in "$@"; do
if [[ "$skip_next" == true ]]; then
FLAGS+=("$arg")
skip_next=false
elif [[ "$arg" == -* ]]; then
if [[ "$arg" == -* ]]; then
flag="${arg%%=*}"
matched=false
for allowed in "${ALLOWED_FLAGS[@]}"; do
@@ -55,42 +35,9 @@ for arg in "$@"; do
fi
done
if [[ "$matched" == false ]]; then
echo "Error: only --comments, --state, --limit, --label flags are allowed (e.g., ./scripts/gh.sh issue list --state open --limit 20)" >&2
exit 1
fi
FLAGS+=("$arg")
# If flag expects a value and isn't using = syntax, skip next arg
if [[ "$arg" != *=* ]]; then
for vflag in "${FLAGS_WITH_VALUES[@]}"; do
if [[ "$flag" == "$vflag" ]]; then
skip_next=true
break
fi
done
fi
else
POSITIONAL+=("$arg")
fi
done
if [[ "$CMD" == "search issues" ]]; then
QUERY="${POSITIONAL[0]:-}"
QUERY_LOWER=$(echo "$QUERY" | tr '[:upper:]' '[:lower:]')
if [[ "$QUERY_LOWER" == *"repo:"* || "$QUERY_LOWER" == *"org:"* || "$QUERY_LOWER" == *"user:"* ]]; then
echo "Error: search query must not contain repo:, org:, or user: qualifiers (e.g., ./scripts/gh.sh search issues \"bug report\" --limit 10)" >&2
exit 1
fi
gh "$SUB1" "$SUB2" "$QUERY" --repo "$REPO" "${FLAGS[@]}"
elif [[ "$CMD" == "issue view" ]]; then
if [[ ${#POSITIONAL[@]} -ne 1 ]] || ! [[ "${POSITIONAL[0]}" =~ ^[0-9]+$ ]]; then
echo "Error: issue view requires exactly one numeric issue number (e.g., ./scripts/gh.sh issue view 123)" >&2
exit 1
fi
gh "$SUB1" "$SUB2" "${POSITIONAL[0]}" "${FLAGS[@]}"
else
if [[ ${#POSITIONAL[@]} -ne 0 ]]; then
echo "Error: issue list and label list do not accept positional arguments (e.g., ./scripts/gh.sh issue list --state open, ./scripts/gh.sh label list --limit 100)" >&2
exit 1
fi
gh "$SUB1" "$SUB2" "${FLAGS[@]}"
fi
gh "$SUB1" "$SUB2" "$@"