Compare commits

...

21 Commits

Author SHA1 Message Date
Boris Cherny
d742413949 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>
2026-01-06 18:46:12 -08:00
Boris Cherny
817e8c1573 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>
2026-01-06 18:37:38 -08:00
Boris Cherny
128de2a75d feat: Add explanatory-output-style and learning-output-style plugins to marketplace
Added two missing plugins to the marketplace.json:
- explanatory-output-style: Adds educational insights about implementation choices
- learning-output-style: Interactive learning mode that requests code contributions

Both plugins are categorized under "learning" to help users discover educational tools.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-01 16:15:21 -07:00
Boris Cherny
b8a98a8df7 Merge pull request #10826 from anthropics/boris/rmbx
feat: Add learning-output-style plugin
2025-11-01 15:55:57 -07:00
claude[bot]
ba49573fe1 feat: Incorporate explanatory functionality into learning-output-style plugin
- Update session-start.sh to include explanatory insights alongside learning mode
- Add educational insight formatting with ★ Insight sections
- Update README.md to clarify differences from unshipped Learning output style
- Document that this plugin now combines both learning and explanatory functionality
- Address review feedback about incorporating explanatory-output-style features

Co-authored-by: Boris Cherny <bcherny@users.noreply.github.com>
2025-11-01 22:37:17 +00:00
Boris Cherny
015808d89c feat: Add learning-output-style plugin
Add interactive learning mode plugin that requests meaningful code contributions at decision points. Based on the unshipped Learning output style, this plugin engages users in active learning by having them write 5-10 lines of code for business logic, error handling, and design decisions.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-01 15:26:34 -07:00
GitHub Actions
ae411f8461 chore: Update CHANGELOG.md 2025-11-01 00:47:17 +00:00
GitHub Actions
4310085cb5 chore: Update CHANGELOG.md 2025-10-31 23:27:06 +00:00
GitHub Actions
c509821adc chore: Update CHANGELOG.md 2025-10-31 21:57:10 +00:00
GitHub Actions
d9aa4cf649 chore: Update CHANGELOG.md 2025-10-31 16:02:25 +00:00
GitHub Actions
b935da77db chore: Update CHANGELOG.md 2025-10-30 23:32:01 +00:00
Dickson Tsai
0c7d02b56f Merge pull request #10495 from anthropics/dickson/explanatory-output-style
Implement Explanatory output style as a plugin
2025-10-29 11:04:44 -07:00
Dickson Tsai
8b47e224a0 Editorial changes 2025-10-29 08:37:48 -07:00
Dickson Tsai
21bbc9f250 Merge pull request #10445 from stbenjam/lints
Add missing plugin.json files to fix claudelint errors
2025-10-29 08:19:27 -07:00
Catherine Wu
7add6863a0 Merge pull request #10076 from anthropics/add-oncall-triage-workflow
Add oncall triage slash command for issue management
2025-10-28 20:12:35 -07:00
Cat Wu
5484a86d28 Increase oncall triage engagement threshold to 50
Updates the oncall triage automation to require 50+ engagements
(comments + reactions) before applying the oncall label, making the
criteria more conservative to focus on the most critical issues.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 20:04:53 -07:00
Dickson Tsai
10e1d3fe77 Implement a plugin as alternative for deprecated Explanatory output style 2025-10-28 02:39:56 -07:00
GitHub Actions
4dc23d0275 chore: Update CHANGELOG.md 2025-10-28 00:45:49 +00:00
GitHub Actions
8077cdc68c chore: Update CHANGELOG.md 2025-10-27 21:29:34 +00:00
Stephen Benjamin
207b22de65 Add missing plugin.json files to fix claudelint errors
Added plugin metadata files for code-review and commit-commands plugins
to comply with Claude plugin structure requirements. These files were
identified as missing by the [claudelint](https://github.com/stbenjam/claudelint)
tool, which validates plugin structure and format according to the Claude
Code plugin conventions.
2025-10-27 12:49:45 -04:00
Cat Wu
5d0e5cf15f Add oncall triage slash command for issue management
Creates a new /oncall-triage command that automates the process of triaging GitHub issues and labeling critical ones for oncall attention.

The command:
- Fetches open bugs updated in last 3 days with 5+ engagements
- Systematically evaluates each issue for blocking severity
- Adds "oncall" label to truly blocking issues
- Provides summary of all issues that received the label

Includes guidance to use individual gh commands instead of bash loops to avoid approval prompts.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-21 13:44:18 -07:00
17 changed files with 461 additions and 22 deletions

View File

@@ -68,6 +68,28 @@
},
"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"
}
]
}

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(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(./scripts/comment-on-duplicates.sh:*)
description: Find duplicate GitHub issues
---
@@ -11,28 +11,13 @@ 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 --base-issue <issue-number> --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.)
- Do not use other tools, beyond `gh` 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)
---

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

@@ -54,7 +54,7 @@ jobs:
- 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 5 engagements? (count comments + reactions)
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?

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.DS_Store

View File

@@ -1,5 +1,45 @@
# Changelog
## 2.0.31
- Windows: native installation uses shift+tab as shortcut for mode switching, instead of alt+m
- Vertex: add support for Web Search on supported models
- VSCode: Adding the respectGitIgnore configuration to include .gitignored files in file searches (defaults to true)
- Fixed a bug with subagents and MCP servers related to "Tool names must be unique" error
- Fixed issue causing `/compact` to fail with `prompt_too_long` by making it respect existing compact boundaries
- Fixed plugin uninstall not removing plugins
## 2.0.30
- Added helpful hint to run `security unlock-keychain` when encountering API key errors on macOS with locked keychain
- Added `allowUnsandboxedCommands` sandbox setting to disable the dangerouslyDisableSandbox escape hatch at policy level
- Added `disallowedTools` field to custom agent definitions for explicit tool blocking
- Added prompt-based stop hooks
- VSCode: Added respectGitIgnore configuration to include .gitignored files in file searches (defaults to true)
- Enabled SSE MCP servers on native build
- Deprecated output styles. Review options in `/output-style` and use --system-prompt-file, --system-prompt, --append-system-prompt, CLAUDE.md, or plugins instead
- Removed support for custom ripgrep configuration, resolving an issue where Search returns no results and config discovery fails
- Fixed Explore agent creating unwanted .md investigation files during codebase exploration
- Fixed a bug where `/context` would sometimes fail with "max_tokens must be greater than thinking.budget_tokens" error message
- Fixed `--mcp-config` flag to correctly override file-based MCP configurations
- Fixed bug that saved session permissions to local settings
- Fixed MCP tools not being available to sub-agents
- Fixed hooks and plugins not executing when using --dangerously-skip-permissions flag
- Fixed delay when navigating through typeahead suggestions with arrow keys
- VSCode: Restored selection indicator in input footer showing current file or code selection status
## 2.0.28
- Plan mode: introduced new Plan subagent
- Subagents: claude can now choose to resume subagents
- Subagents: claude can dynamically choose the model used by its subagents
- SDK: added --max-budget-usd flag
- Discovery of custom slash commands, subagents, and output styles no longer respects .gitignore
- Stop `/terminal-setup` from adding backslash to `Shift + Enter` in VS Code
- Add branch and tag support for git-based plugins and marketplaces using fragment syntax (e.g., `owner/repo#branch`)
- Fixed a bug where macOS permission prompts would show up upon initial launch when launching from home directory
- Various other bug fixes
## 2.0.27
- New UI for permission prompts
@@ -17,6 +57,7 @@
- Fixed a bug where project-level skills were not loading when --setting-sources 'project' was specified
- Claude Code Web: Support for Web -> CLI teleport
- Sandbox: Releasing a sandbox mode for the BashTool on Linux & Mac
- Bedrock: Display awsAuthRefresh output when auth is required
## 2.0.22

View File

@@ -0,0 +1,10 @@
{
"name": "code-review",
"description": "Automated code review for pull requests using multiple specialized agents with confidence-based scoring",
"version": "1.0.0",
"author": {
"name": "Boris Cherny",
"email": "boris@anthropic.com"
}
}

View File

@@ -0,0 +1,10 @@
{
"name": "commit-commands",
"description": "Streamline your git workflow with simple commands for committing, pushing, and creating pull requests",
"version": "1.0.0",
"author": {
"name": "Anthropic",
"email": "support@anthropic.com"
}
}

View File

@@ -0,0 +1,9 @@
{
"name": "explanatory-output-style",
"version": "1.0.0",
"description": "Adds educational insights about implementation choices and codebase patterns (mimics the deprecated Explanatory output style)",
"author": {
"name": "Dickson Tsai",
"email": "dickson@anthropic.com"
}
}

View File

@@ -0,0 +1,72 @@
# Explanatory Output Style Plugin
This plugin recreates the deprecated Explanatory output style as a SessionStart
hook.
WARNING: Do not install this plugin unless you are fine with incurring the token
cost of this plugin's additional instructions and output.
## What it does
When enabled, this plugin automatically adds instructions at the start of each
session that encourage Claude to:
1. Provide educational insights about implementation choices
2. Explain codebase patterns and decisions
3. Balance task completion with learning opportunities
## How it works
The plugin uses a SessionStart hook to inject additional context into every
session. This context instructs Claude to provide brief educational explanations
before and after writing code, formatted as:
```
`★ Insight ─────────────────────────────────────`
[2-3 key educational points]
`─────────────────────────────────────────────────`
```
## Usage
Once installed, the plugin activates automatically at the start of every
session. No additional configuration is needed.
The insights focus on:
- Specific implementation choices for your codebase
- Patterns and conventions in your code
- Trade-offs and design decisions
- Codebase-specific details rather than general programming concepts
## Migration from Output Styles
This plugin replaces the deprecated "Explanatory" output style setting. If you
previously used:
```json
{
"outputStyle": "Explanatory"
}
```
You can now achieve the same behavior by installing this plugin instead.
More generally, this SessionStart hook pattern is roughly equivalent to
CLAUDE.md, but it is more flexible and allows for distribution through plugins.
Note: Output styles that involve tasks besides software development, are better
expressed as
[subagents](https://docs.claude.com/en/docs/claude-code/sub-agents), not as
SessionStart hooks. Subagents change the system prompt while SessionStart hooks
add to the default system prompt.
## Managing changes
- Disable the plugin - keep the code installed on your device
- Uninstall the plugin - remove the code from your device
- Update the plugin - create a local copy of this plugin to personalize this
plugin
- Hint: Ask Claude to read
https://docs.claude.com/en/docs/claude-code/plugins.md and set it up for
you!

View File

@@ -0,0 +1,15 @@
#!/bin/bash
# Output the explanatory mode instructions as additionalContext
# This mimics the deprecated Explanatory output style
cat << 'EOF'
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "You are in 'explanatory' output style mode, where you should provide educational insights about the codebase as you help with the user's task.\n\nYou should be clear and educational, providing helpful explanations while remaining focused on the task. Balance educational content with task completion. When providing insights, you may exceed typical length constraints, but remain focused and relevant.\n\n## Insights\nIn order to encourage learning, before and after writing code, always provide brief educational explanations about implementation choices using (with backticks):\n\"`★ Insight ─────────────────────────────────────`\n[2-3 key educational points]\n`─────────────────────────────────────────────────`\"\n\nThese insights should be included in the conversation, not in the codebase. You should generally focus on interesting insights that are specific to the codebase or the code you just wrote, rather than general programming concepts. Do not wait until the end to provide insights. Provide them as you write code."
}
}
EOF
exit 0

View File

@@ -0,0 +1,15 @@
{
"description": "Explanatory mode hook that adds educational insights instructions",
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks-handlers/session-start.sh"
}
]
}
]
}
}

View File

@@ -0,0 +1,9 @@
{
"name": "learning-output-style",
"version": "1.0.0",
"description": "Interactive learning mode that requests meaningful code contributions at decision points (mimics the unshipped Learning output style)",
"author": {
"name": "Boris Cherny",
"email": "boris@anthropic.com"
}
}

View File

@@ -0,0 +1,93 @@
# Learning Style Plugin
This plugin combines the unshipped Learning output style with explanatory functionality as a SessionStart hook.
**Note:** This plugin differs from the original unshipped Learning output style by also incorporating all functionality from the [explanatory-output-style plugin](https://github.com/anthropics/claude-code/tree/main/plugins/explanatory-output-style), providing both interactive learning and educational insights.
WARNING: Do not install this plugin unless you are fine with incurring the token cost of this plugin's additional instructions and the interactive nature of learning mode.
## What it does
When enabled, this plugin automatically adds instructions at the start of each session that encourage Claude to:
1. **Learning Mode:** Engage you in active learning by requesting meaningful code contributions at decision points
2. **Explanatory Mode:** Provide educational insights about implementation choices and codebase patterns
Instead of implementing everything automatically, Claude will:
1. Identify opportunities where you can write 5-10 lines of meaningful code
2. Focus on business logic and design choices where your input truly matters
3. Prepare the context and location for your contribution
4. Explain trade-offs and guide your implementation
5. Provide educational insights before and after writing code
## How it works
The plugin uses a SessionStart hook to inject additional context into every session. This context instructs Claude to adopt an interactive teaching approach where you actively participate in writing key parts of the code.
## When Claude requests contributions
Claude will ask you to write code for:
- Business logic with multiple valid approaches
- Error handling strategies
- Algorithm implementation choices
- Data structure decisions
- User experience decisions
- Design patterns and architecture choices
## When Claude won't request contributions
Claude will implement directly:
- Boilerplate or repetitive code
- Obvious implementations with no meaningful choices
- Configuration or setup code
- Simple CRUD operations
## Example interaction
**Claude:** I've set up the authentication middleware. The session timeout behavior is a security vs. UX trade-off - should sessions auto-extend on activity, or have a hard timeout?
In `auth/middleware.ts`, implement the `handleSessionTimeout()` function to define the timeout behavior.
Consider: auto-extending improves UX but may leave sessions open longer; hard timeouts are more secure but might frustrate active users.
**You:** [Write 5-10 lines implementing your preferred approach]
## Educational insights
In addition to interactive learning, Claude will provide educational insights about implementation choices using this format:
```
`★ Insight ─────────────────────────────────────`
[2-3 key educational points about the codebase or implementation]
`─────────────────────────────────────────────────`
```
These insights focus on:
- Specific implementation choices for your codebase
- Patterns and conventions in your code
- Trade-offs and design decisions
- Codebase-specific details rather than general programming concepts
## Usage
Once installed, the plugin activates automatically at the start of every session. No additional configuration is needed.
## Migration from Output Styles
This plugin combines the unshipped "Learning" output style with the deprecated "Explanatory" output style. It provides an interactive learning experience where you actively contribute code at meaningful decision points, while also receiving educational insights about implementation choices.
If you previously used the explanatory-output-style plugin, this learning plugin includes all of that functionality plus interactive learning features.
This SessionStart hook pattern is roughly equivalent to CLAUDE.md, but it is more flexible and allows for distribution through plugins.
## Managing changes
- Disable the plugin - keep the code installed on your device
- Uninstall the plugin - remove the code from your device
- Update the plugin - create a local copy of this plugin to personalize it
- Hint: Ask Claude to read https://docs.claude.com/en/docs/claude-code/plugins.md and set it up for you!
## Philosophy
Learning by doing is more effective than passive observation. This plugin transforms your interaction with Claude from "watch and learn" to "build and understand," ensuring you develop practical skills through hands-on coding of meaningful logic.

View File

@@ -0,0 +1,15 @@
#!/bin/bash
# Output the learning mode instructions as additionalContext
# This combines the unshipped Learning output style with explanatory functionality
cat << 'EOF'
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "You are in 'learning' output style mode, which combines interactive learning with educational explanations. This mode differs from the original unshipped Learning output style by also incorporating explanatory functionality.\n\n## Learning Mode Philosophy\n\nInstead of implementing everything yourself, identify opportunities where the user can write 5-10 lines of meaningful code that shapes the solution. Focus on business logic, design choices, and implementation strategies where their input truly matters.\n\n## When to Request User Contributions\n\nRequest code contributions for:\n- Business logic with multiple valid approaches\n- Error handling strategies\n- Algorithm implementation choices\n- Data structure decisions\n- User experience decisions\n- Design patterns and architecture choices\n\n## How to Request Contributions\n\nBefore requesting code:\n1. Create the file with surrounding context\n2. Add function signature with clear parameters/return type\n3. Include comments explaining the purpose\n4. Mark the location with TODO or clear placeholder\n\nWhen requesting:\n- Explain what you've built and WHY this decision matters\n- Reference the exact file and prepared location\n- Describe trade-offs to consider, constraints, or approaches\n- Frame it as valuable input that shapes the feature, not busy work\n- Keep requests focused (5-10 lines of code)\n\n## Example Request Pattern\n\nContext: I've set up the authentication middleware. The session timeout behavior is a security vs. UX trade-off - should sessions auto-extend on activity, or have a hard timeout? This affects both security posture and user experience.\n\nRequest: In auth/middleware.ts, implement the handleSessionTimeout() function to define the timeout behavior.\n\nGuidance: Consider: auto-extending improves UX but may leave sessions open longer; hard timeouts are more secure but might frustrate active users.\n\n## Balance\n\nDon't request contributions for:\n- Boilerplate or repetitive code\n- Obvious implementations with no meaningful choices\n- Configuration or setup code\n- Simple CRUD operations\n\nDo request contributions when:\n- There are meaningful trade-offs to consider\n- The decision shapes the feature's behavior\n- Multiple valid approaches exist\n- The user's domain knowledge would improve the solution\n\n## Explanatory Mode\n\nAdditionally, provide educational insights about the codebase as you help with tasks. Be clear and educational, providing helpful explanations while remaining focused on the task. Balance educational content with task completion.\n\n### Insights\nBefore and after writing code, provide brief educational explanations about implementation choices using:\n\n\"`★ Insight ─────────────────────────────────────`\n[2-3 key educational points]\n`─────────────────────────────────────────────────`\"\n\nThese insights should be included in the conversation, not in the codebase. Focus on interesting insights specific to the codebase or the code you just wrote, rather than general programming concepts. Provide insights as you write code, not just at the end."
}
}
EOF
exit 0

View File

@@ -0,0 +1,15 @@
{
"description": "Learning mode hook that adds interactive learning instructions",
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks-handlers/session-start.sh"
}
]
}
]
}
}

View File

@@ -0,0 +1,86 @@
#!/usr/bin/env bash
#
# Comments on a GitHub issue with a list of potential duplicates.
# Usage: ./comment-on-duplicates.sh --base-issue 123 --potential-duplicates 456 789 101
#
set -euo pipefail
REPO="anthropics/claude-code"
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
DUPLICATES+=("$1")
shift
done
;;
*)
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
exit 1
fi
if [[ ${#DUPLICATES[@]} -gt 3 ]]; then
echo "Error: --potential-duplicates accepts at most 3 issues" >&2
exit 1
fi
for dup in "${DUPLICATES[@]}"; do
if ! [[ "$dup" =~ ^[0-9]+$ ]]; then
echo "Error: duplicate issue must be a number, got: $dup" >&2
exit 1
fi
done
# Build comment body
COUNT=${#DUPLICATES[@]}
if [[ $COUNT -eq 1 ]]; then
HEADER="Found 1 possible duplicate issue:"
else
HEADER="Found $COUNT possible duplicate issues:"
fi
BODY="$HEADER"$'\n\n'
INDEX=1
for dup in "${DUPLICATES[@]}"; do
BODY+="$INDEX. https://github.com/$REPO/issues/$dup"$'\n'
((INDEX++))
done
BODY+=$'\n'"This issue will be automatically closed as a duplicate in 3 days."$'\n\n'
BODY+="- If your issue is a duplicate, please close it and 👍 the existing issue instead"$'\n'
BODY+="- To prevent auto-closure, add a comment or 👎 this comment"$'\n\n'
BODY+="🤖 Generated with [Claude Code](https://claude.ai/code)"
# Post the comment
gh issue comment "$BASE_ISSUE" --repo "$REPO" --body "$BODY"
echo "Posted duplicate comment on issue #$BASE_ISSUE"