mirror of
https://github.com/anthropics/claude-code.git
synced 2026-02-19 04:27:33 -08:00
Compare commits
20 Commits
chrislloyd
...
v2.1.47
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b757fc9ecd | ||
|
|
1718a57495 | ||
|
|
4523c004dd | ||
|
|
32c7ff2b6e | ||
|
|
d787369919 | ||
|
|
8c09097e8c | ||
|
|
edfb5437a4 | ||
|
|
b374a30699 | ||
|
|
a01a88d5ee | ||
|
|
42c62d73ce | ||
|
|
1b50583382 | ||
|
|
232213304d | ||
|
|
a93966285e | ||
|
|
0931fb76da | ||
|
|
bac22cb316 | ||
|
|
77df0af778 | ||
|
|
76a2154fd5 | ||
|
|
aca4801e91 | ||
|
|
f2a930799b | ||
|
|
6dcc7d8b76 |
127
.github/workflows/claude-issue-triage.yml
vendored
127
.github/workflows/claude-issue-triage.yml
vendored
@@ -1,13 +1,20 @@
|
||||
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
|
||||
@@ -17,30 +24,6 @@ jobs:
|
||||
- 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 Issue Triage
|
||||
timeout-minutes: 5
|
||||
uses: anthropics/claude-code-action@v1
|
||||
@@ -50,56 +33,74 @@ jobs:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
allowed_non_write_users: "*"
|
||||
prompt: |
|
||||
You're an issue triage assistant for GitHub issues. Your task is to analyze the issue and select appropriate labels from the provided list.
|
||||
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 action should be to apply labels.
|
||||
IMPORTANT: Don't post any comments or messages to the issue. Your only actions are adding or removing labels.
|
||||
|
||||
Issue Information:
|
||||
Context:
|
||||
- REPO: ${{ github.repository }}
|
||||
- ISSUE_NUMBER: ${{ github.event.issue.number }}
|
||||
- EVENT: ${{ github.event_name }}
|
||||
|
||||
TASK OVERVIEW:
|
||||
ALLOWED LABELS — you may ONLY use labels from this list. Never invent new labels.
|
||||
|
||||
1. First, fetch the list of labels available in this repository by running: `gh label list`. Run exactly this command with nothing else.
|
||||
Type: bug, enhancement, question, documentation, duplicate, invalid
|
||||
Lifecycle: needs-repro, needs-info, stale, autoclose
|
||||
Platform: platform:linux, platform:macos, platform:windows, platform:wsl, platform:ios, platform:android, platform:vscode, platform:intellij, platform:web, platform:aws-bedrock
|
||||
API: api:bedrock, api:vertex
|
||||
|
||||
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
|
||||
TOOLS:
|
||||
- `gh issue view NUMBER`: Read the issue title, body, and labels
|
||||
- `gh issue view NUMBER --comments`: Read the conversation
|
||||
- `gh search issues QUERY`: Find similar or duplicate issues
|
||||
- `gh issue edit NUMBER --add-label` / `--remove-label`: Add or remove labels
|
||||
|
||||
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
|
||||
TASK:
|
||||
|
||||
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.
|
||||
1. Run `gh issue view ${{ github.event.issue.number }}` to read the issue details.
|
||||
2. Run `gh issue view ${{ github.event.issue.number }} --comments` to read the conversation.
|
||||
|
||||
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
|
||||
**If EVENT is "issues" (new issue):**
|
||||
|
||||
IMPORTANT GUIDELINES:
|
||||
- Be thorough in your analysis
|
||||
- Only select labels from the provided list above
|
||||
3. 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.
|
||||
|
||||
4. Analyze and apply category labels:
|
||||
- Type (bug, enhancement, question, etc.)
|
||||
- Technical areas and platform
|
||||
- Check for duplicates with `gh search issues`. Only mark as duplicate of OPEN issues.
|
||||
|
||||
5. 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.
|
||||
|
||||
6. Apply all selected labels:
|
||||
`gh issue edit ${{ github.event.issue.number }} --add-label "label1" --add-label "label2"`
|
||||
|
||||
**If EVENT is "issue_comment" (comment on existing issue):**
|
||||
|
||||
3. 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:
|
||||
`gh issue edit ${{ github.event.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:
|
||||
`gh issue edit ${{ github.event.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.
|
||||
|
||||
GUIDELINES:
|
||||
- ONLY use labels from the ALLOWED LABELS list above — never create or guess label names
|
||||
- DO NOT post any comments to the issue
|
||||
- Your ONLY action should be to apply labels using mcp__github__update_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
|
||||
- It's okay to not add any labels if none are clearly applicable
|
||||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
claude_args: |
|
||||
--model claude-sonnet-4-5-20250929
|
||||
--mcp-config /tmp/mcp-config/mcp-servers.json
|
||||
--allowedTools "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"
|
||||
--model claude-opus-4-6
|
||||
--allowedTools "Bash(gh issue view:*),Bash(gh issue edit:*),Bash(gh search issues:*)"
|
||||
|
||||
27
.github/workflows/issue-lifecycle-comment.yml
vendored
Normal file
27
.github/workflows/issue-lifecycle-comment.yml
vendored
Normal file
@@ -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@v2
|
||||
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 }}
|
||||
157
.github/workflows/stale-issue-manager.yml
vendored
157
.github/workflows/stale-issue-manager.yml
vendored
@@ -1,157 +0,0 @@
|
||||
name: "Manage Stale Issues"
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# 2am Pacific = 9am UTC (10am UTC during DST)
|
||||
- cron: "0 10 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
concurrency:
|
||||
group: stale-issue-manager
|
||||
|
||||
jobs:
|
||||
manage-stale-issues:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Manage stale issues
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const oneMonthAgo = new Date();
|
||||
oneMonthAgo.setDate(oneMonthAgo.getDate() - 30);
|
||||
|
||||
const twoMonthsAgo = new Date();
|
||||
twoMonthsAgo.setDate(twoMonthsAgo.getDate() - 60);
|
||||
|
||||
const warningComment = `This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.`;
|
||||
|
||||
const closingComment = `This issue has been automatically closed due to 60 days of inactivity. If you're still experiencing this issue, please open a new issue with updated information.`;
|
||||
|
||||
let page = 1;
|
||||
let hasMore = true;
|
||||
let totalWarned = 0;
|
||||
let totalClosed = 0;
|
||||
let totalLabeled = 0;
|
||||
|
||||
while (hasMore) {
|
||||
// Get open issues sorted by last updated (oldest first)
|
||||
const { data: issues } = await github.rest.issues.listForRepo({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
state: 'open',
|
||||
sort: 'updated',
|
||||
direction: 'asc',
|
||||
per_page: 100,
|
||||
page: page
|
||||
});
|
||||
|
||||
if (issues.length === 0) {
|
||||
hasMore = false;
|
||||
break;
|
||||
}
|
||||
|
||||
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 recently than 30 days ago
|
||||
const updatedAt = new Date(issue.updated_at);
|
||||
if (updatedAt > oneMonthAgo) {
|
||||
// Since issues are sorted by updated_at ascending,
|
||||
// once we hit a recent issue, all remaining will be recent too
|
||||
hasMore = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if issue has autoclose label
|
||||
const hasAutocloseLabel = issue.labels.some(label =>
|
||||
typeof label === 'object' && label.name === 'autoclose'
|
||||
);
|
||||
|
||||
try {
|
||||
// Get comments to check for existing warning
|
||||
const { data: comments } = await github.rest.issues.listComments({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue.number,
|
||||
per_page: 100
|
||||
});
|
||||
|
||||
// Find the last comment from github-actions bot
|
||||
const botComments = comments.filter(comment =>
|
||||
comment.user && comment.user.login === 'github-actions[bot]' &&
|
||||
comment.body && comment.body.includes('inactive for 30 days')
|
||||
);
|
||||
|
||||
const lastBotComment = botComments[botComments.length - 1];
|
||||
|
||||
if (lastBotComment) {
|
||||
// Check if the bot comment is older than 30 days (total 60 days of inactivity)
|
||||
const botCommentDate = new Date(lastBotComment.created_at);
|
||||
if (botCommentDate < oneMonthAgo) {
|
||||
// Close the issue - it's been stale for 60+ days
|
||||
console.log(`Closing issue #${issue.number} (stale for 60+ days): ${issue.title}`);
|
||||
|
||||
// Post closing comment
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue.number,
|
||||
body: closingComment
|
||||
});
|
||||
|
||||
// Close the issue
|
||||
await github.rest.issues.update({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue.number,
|
||||
state: 'closed',
|
||||
state_reason: 'not_planned'
|
||||
});
|
||||
|
||||
totalClosed++;
|
||||
}
|
||||
// If bot comment exists but is recent, issue already has warning
|
||||
} else if (updatedAt < oneMonthAgo) {
|
||||
// No bot warning yet, issue is 30+ days old
|
||||
console.log(`Warning issue #${issue.number} (stale for 30+ days): ${issue.title}`);
|
||||
|
||||
// Post warning comment
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue.number,
|
||||
body: warningComment
|
||||
});
|
||||
|
||||
totalWarned++;
|
||||
|
||||
// Add autoclose label if not present
|
||||
if (!hasAutocloseLabel) {
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue.number,
|
||||
labels: ['autoclose']
|
||||
});
|
||||
totalLabeled++;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Failed to process issue #${issue.number}: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
page++;
|
||||
}
|
||||
|
||||
console.log(`Summary:`);
|
||||
console.log(`- Issues warned (30 days stale): ${totalWarned}`);
|
||||
console.log(`- Issues labeled with autoclose: ${totalLabeled}`);
|
||||
console.log(`- Issues closed (60 days stale): ${totalClosed}`);
|
||||
4
.github/workflows/sweep.yml
vendored
4
.github/workflows/sweep.yml
vendored
@@ -1,8 +1,8 @@
|
||||
name: "Daily Issue Sweep"
|
||||
name: "Issue Sweep"
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 10 * * *" # 2am Pacific
|
||||
- cron: "0 10,22 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
|
||||
132
CHANGELOG.md
132
CHANGELOG.md
@@ -1,6 +1,119 @@
|
||||
# Changelog
|
||||
|
||||
## 2.1.39
|
||||
## 2.1.47
|
||||
|
||||
- Fixed FileWriteTool line counting to preserve intentional trailing blank lines instead of stripping them with `trimEnd()`.
|
||||
- Fixed Windows terminal rendering bugs caused by `os.EOL` (`\r\n`) in display code — line counts now show correct values instead of always showing 1 on Windows.
|
||||
- Improved VS Code plan preview: auto-updates as Claude iterates, enables commenting only when the plan is ready for review, and keeps the preview open when rejecting so Claude can revise.
|
||||
- Fixed a bug where bold and colored text in markdown output could shift to the wrong characters on Windows due to `\r\n` line endings.
|
||||
- Fixed compaction failing when conversation contains many PDF documents by stripping document blocks alongside images before sending to the compaction API (anthropics/claude-code#26188)
|
||||
- Improved memory usage in long-running sessions by releasing API stream buffers, agent context, and skill state after use
|
||||
- Improved startup performance by deferring SessionStart hook execution, reducing time-to-interactive by ~500ms.
|
||||
- Fixed an issue where bash tool output was silently discarded on Windows when using MSYS2 or Cygwin shells.
|
||||
- Improved performance of `@` file mentions - file suggestions now appear faster by pre-warming the index on startup and using session-based caching with background refresh.
|
||||
- Improved memory usage by trimming agent task message history after tasks complete
|
||||
- Improved memory usage during long agent sessions by eliminating O(n²) message accumulation in progress updates
|
||||
- Fixed the bash permission classifier to validate that returned match descriptions correspond to actual input rules, preventing hallucinated descriptions from incorrectly granting permissions
|
||||
- Fixed user-defined agents only loading one file on NFS/FUSE filesystems that report zero inodes (anthropics/claude-code#26044)
|
||||
- Fixed plugin agent skills silently failing to load when referenced by bare name instead of fully-qualified plugin name (anthropics/claude-code#25834)
|
||||
- Search patterns in collapsed tool results are now displayed in quotes for clarity
|
||||
- Windows: Fixed CWD tracking temp files never being cleaned up, causing them to accumulate indefinitely (anthropics/claude-code#17600)
|
||||
- Use `ctrl+f` to kill all background agents instead of double-pressing ESC. Background agents now continue running when you press ESC to cancel the main thread, giving you more control over agent lifecycle.
|
||||
- Fixed API 400 errors ("thinking blocks cannot be modified") that occurred in sessions with concurrent agents, caused by interleaved streaming content blocks preventing proper message merging.
|
||||
- Simplified teammate navigation to use only Shift+Down (with wrapping) instead of both Shift+Up and Shift+Down.
|
||||
- Fixed an issue where a single file write/edit error would abort all other parallel file write/edit operations. Independent file mutations now complete even when a sibling fails.
|
||||
- Added `last_assistant_message` field to Stop and SubagentStop hook inputs, providing the final assistant response text so hooks can access it without parsing transcript files.
|
||||
- Fixed custom session titles set via `/rename` being lost after resuming a conversation (anthropics/claude-code#23610)
|
||||
- Fixed collapsed read/search hint text overflowing on narrow terminals by truncating from the start.
|
||||
- Fixed an issue where bash commands with backslash-newline continuation lines (e.g., long commands split across multiple lines with `\`) would produce spurious empty arguments, potentially breaking command execution.
|
||||
- Fixed built-in slash commands (`/help`, `/model`, `/compact`, etc.) being hidden from the autocomplete dropdown when many user skills are installed (anthropics/claude-code#22020)
|
||||
- Fixed MCP servers not appearing in the MCP Management Dialog after deferred loading
|
||||
- Fixed session name persisting in status bar after `/clear` command (anthropics/claude-code#26082)
|
||||
- Fixed crash when a skill's `name` or `description` in SKILL.md frontmatter is a bare number (e.g., `name: 3000`) — the value is now properly coerced to a string (anthropics/claude-code#25837)
|
||||
- Fixed /resume silently dropping sessions when the first message exceeds 16KB or uses array-format content (anthropics/claude-code#25721)
|
||||
- Added `chat:newline` keybinding action for configurable multi-line input (anthropics/claude-code#26075)
|
||||
- Added `added_dirs` to the statusline JSON `workspace` section, exposing directories added via `/add-dir` to external scripts (anthropics/claude-code#26096)
|
||||
- Fixed `claude doctor` misclassifying mise and asdf-managed installations as native installs (anthropics/claude-code#26033)
|
||||
- Fixed zsh heredoc failing with "read-only file system" error in sandboxed commands (anthropics/claude-code#25990)
|
||||
- Fixed agent progress indicator showing inflated tool use count (anthropics/claude-code#26023)
|
||||
- Fixed image pasting not working on WSL2 systems where Windows copies images as BMP format (anthropics/claude-code#25935)
|
||||
- Fixed background agent results returning raw transcript data instead of the agent's final answer (anthropics/claude-code#26012)
|
||||
- Fixed Warp terminal incorrectly prompting for Shift+Enter setup when it supports it natively (anthropics/claude-code#25957)
|
||||
- Fixed CJK wide characters causing misaligned timestamps and layout elements in the TUI (anthropics/claude-code#26084)
|
||||
- Fixed custom agent `model` field in `.claude/agents/*.md` being ignored when spawning team teammates (anthropics/claude-code#26064)
|
||||
- Fixed plan mode being lost after context compaction, causing the model to switch from planning to implementation mode (anthropics/claude-code#26061)
|
||||
- Fixed `alwaysThinkingEnabled: true` in settings.json not enabling thinking mode on Bedrock and Vertex providers (anthropics/claude-code#26074)
|
||||
- Fixed `tool_decision` OTel telemetry event not being emitted in headless/SDK mode (anthropics/claude-code#26059)
|
||||
- Fixed session name being lost after context compaction — renamed sessions now preserve their custom title through compaction (anthropics/claude-code#26121)
|
||||
- Increased initial session count in resume picker from 10 to 50 for faster session discovery (anthropics/claude-code#26123)
|
||||
- Windows: fixed worktree session matching when drive letter casing differs (anthropics/claude-code#26123)
|
||||
- Fixed `/resume <session-id>` failing to find sessions whose first message exceeds 16KB (anthropics/claude-code#25920)
|
||||
- Fixed "Always allow" on multiline bash commands creating invalid permission patterns that corrupt settings (anthropics/claude-code#25909)
|
||||
- Fixed React crash (error #31) when a skill's `argument-hint` in SKILL.md frontmatter uses YAML sequence syntax (e.g., `[topic: foo | bar]`) — the value is now properly coerced to a string (anthropics/claude-code#25826)
|
||||
- Fixed crash when using `/fork` on sessions that used web search — null entries in search results from transcript deserialization are now handled gracefully (anthropics/claude-code#25811)
|
||||
- Fixed read-only git commands triggering FSEvents file watcher loops on macOS by adding --no-optional-locks flag (anthropics/claude-code#25750)
|
||||
- Fixed custom agents and skills not being discovered when running from a git worktree — project-level `.claude/agents/` and `.claude/skills/` from the main repository are now included (anthropics/claude-code#25816)
|
||||
- Fixed non-interactive subcommands like `claude doctor` and `claude plugin validate` being blocked inside nested Claude sessions (anthropics/claude-code#25803)
|
||||
- Windows: Fixed the same CLAUDE.md file being loaded twice when drive letter casing differs between paths (anthropics/claude-code#25756)
|
||||
- Fixed inline code spans in markdown being incorrectly parsed as bash commands (anthropics/claude-code#25792)
|
||||
- Fixed teammate spinners not respecting custom spinnerVerbs from settings (anthropics/claude-code#25748)
|
||||
- Fixed shell commands permanently failing after a command deletes its own working directory (anthropics/claude-code#26136)
|
||||
- Fixed hooks (PreToolUse, PostToolUse) silently failing to execute on Windows by using Git Bash instead of cmd.exe (anthropics/claude-code#25981)
|
||||
- Fixed LSP `findReferences` and other location-based operations returning results from gitignored files (e.g., `node_modules/`, `venv/`) (anthropics/claude-code#26051)
|
||||
- Moved config backup files from home directory root to `~/.claude/backups/` to reduce home directory clutter (anthropics/claude-code#26130)
|
||||
- Fixed sessions with large first prompts (>16KB) disappearing from the /resume list (anthropics/claude-code#26140)
|
||||
- Fixed shell functions with double-underscore prefixes (e.g., `__git_ps1`) not being preserved across shell sessions (anthropics/claude-code#25824)
|
||||
- Fixed spinner showing "0 tokens" counter before any tokens have been received (anthropics/claude-code#26105)
|
||||
- VSCode: Fixed conversation messages appearing dimmed while the AskUserQuestion dialog is open (anthropics/claude-code#26078)
|
||||
- Fixed background tasks failing in git worktrees due to remote URL resolution reading from worktree-specific gitdir instead of the main repository config (anthropics/claude-code#26065)
|
||||
- Fixed Right Alt key leaving visible `[25~` escape sequence residue in the input field on Windows/Git Bash terminals (anthropics/claude-code#25943)
|
||||
- The `/rename` command now updates the terminal tab title by default (anthropics/claude-code#25789)
|
||||
- Fixed Edit tool silently corrupting Unicode curly quotes (\u201c\u201d \u2018\u2019) by replacing them with straight quotes when making edits (anthropics/claude-code#26141)
|
||||
- Fixed OSC 8 hyperlinks only being clickable on the first line when link text wraps across multiple terminal lines.
|
||||
|
||||
## 2.1.46
|
||||
|
||||
- Fixed orphaned CC processes after terminal disconnect on macOS
|
||||
- Added support for using claude.ai MCP connectors in Claude Code
|
||||
|
||||
## 2.1.45
|
||||
|
||||
- Added support for Claude Sonnet 4.6
|
||||
- Added support for reading `enabledPlugins` and `extraKnownMarketplaces` from `--add-dir` directories
|
||||
- Added `spinnerTipsOverride` setting to customize spinner tips — configure `tips` with an array of custom tip strings, and optionally set `excludeDefault: true` to show only your custom tips instead of the built-in ones
|
||||
- Added `SDKRateLimitInfo` and `SDKRateLimitEvent` types to the SDK, enabling consumers to receive rate limit status updates including utilization, reset times, and overage information
|
||||
- Fixed Agent Teams teammates failing on Bedrock, Vertex, and Foundry by propagating API provider environment variables to tmux-spawned processes (anthropics/claude-code#23561)
|
||||
- Fixed sandbox "operation not permitted" errors when writing temporary files on macOS by using the correct per-user temp directory (anthropics/claude-code#21654)
|
||||
- Fixed Task tool (backgrounded agents) crashing with a `ReferenceError` on completion (anthropics/claude-code#22087)
|
||||
- Fixed autocomplete suggestions not being accepted on Enter when images are pasted in the input
|
||||
- Fixed skills invoked by subagents incorrectly appearing in main session context after compaction
|
||||
- Fixed excessive `.claude.json.backup` files accumulating on every startup
|
||||
- Fixed plugin-provided commands, agents, and hooks not being available immediately after installation without requiring a restart
|
||||
- Improved startup performance by removing eager loading of session history for stats caching
|
||||
- Improved memory usage for shell commands that produce large output — RSS no longer grows unboundedly with command output size
|
||||
- Improved collapsed read/search groups to show the current file or search pattern being processed beneath the summary line while active
|
||||
- [VSCode] Improved permission destination choice (project/user/session) to persist across sessions
|
||||
|
||||
## 2.1.44
|
||||
|
||||
- Fixed ENAMETOOLONG errors for deeply-nested directory paths
|
||||
- Fixed auth refresh errors
|
||||
|
||||
## 2.1.43
|
||||
|
||||
- Fixed AWS auth refresh hanging indefinitely by adding a 3-minute timeout
|
||||
- Fixed spurious warnings for non-agent markdown files in `.claude/agents/` directory
|
||||
- Fixed structured-outputs beta header being sent unconditionally on Vertex/Bedrock
|
||||
|
||||
## 2.1.42
|
||||
|
||||
- Improved startup performance by deferring Zod schema construction
|
||||
- Improved prompt cache hit rates by moving date out of system prompt
|
||||
- Added one-time Opus 4.6 effort callout for eligible users
|
||||
- Fixed /resume showing interrupt messages as session titles
|
||||
- Fixed image dimension limit errors to suggest /compact
|
||||
|
||||
## 2.1.41
|
||||
|
||||
- Added guard against launching Claude Code inside another Claude Code session
|
||||
- Fixed Agent Teams using wrong model identifier for Bedrock, Vertex, and Foundry customers
|
||||
@@ -10,6 +123,23 @@
|
||||
- Fixed plugin browse showing misleading "Space to Toggle" hint for already-installed plugins
|
||||
- Fixed hook blocking errors (exit code 2) not showing stderr to the user
|
||||
- Added `speed` attribute to OTel events and trace spans for fast mode visibility
|
||||
- Added `claude auth login`, `claude auth status`, and `claude auth logout` CLI subcommands
|
||||
- Added Windows ARM64 (win32-arm64) native binary support
|
||||
- Improved `/rename` to auto-generate session name from conversation context when called without arguments
|
||||
- Improved narrow terminal layout for prompt footer
|
||||
- Fixed file resolution failing for @-mentions with anchor fragments (e.g., `@README.md#installation`)
|
||||
- Fixed FileReadTool blocking the process on FIFOs, `/dev/stdin`, and large files
|
||||
- Fixed background task notifications not being delivered in streaming Agent SDK mode
|
||||
- Fixed cursor jumping to end on each keystroke in classifier rule input
|
||||
- Fixed markdown link display text being dropped for raw URL
|
||||
- Fixed auto-compact failure error notifications being shown to users
|
||||
- Fixed permission wait time being included in subagent elapsed time display
|
||||
- Fixed proactive ticks firing while in plan mode
|
||||
- Fixed clear stale permission rules when settings change on disk
|
||||
- Fixed hook blocking errors showing stderr content in UI
|
||||
|
||||
## 2.1.39
|
||||
|
||||
- Improved terminal rendering performance
|
||||
- Fixed fatal errors being swallowed instead of displayed
|
||||
- Fixed process hanging after session close
|
||||
|
||||
@@ -56,10 +56,15 @@ Note: Still review Claude generated PR's.
|
||||
|
||||
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. If issues were found, skip to step 8 to post inline comments directly.
|
||||
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 NO issues were found, post a summary comment using `gh pr comment` (if `--comment` argument is provided):
|
||||
"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.
|
||||
|
||||
@@ -85,7 +90,7 @@ Notes:
|
||||
- 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, post a comment with the following format:
|
||||
- If no issues are found and `--comment` argument is provided, post a comment with the following format:
|
||||
|
||||
---
|
||||
|
||||
|
||||
38
scripts/issue-lifecycle.ts
Normal file
38
scripts/issue-lifecycle.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
// Single source of truth for issue lifecycle labels, timeouts, and messages.
|
||||
|
||||
export const lifecycle = [
|
||||
{
|
||||
label: "invalid",
|
||||
days: 3,
|
||||
reason: "this doesn't appear to be about Claude Code",
|
||||
nudge: "This doesn't appear to be about [Claude Code](https://github.com/anthropics/claude-code). For general Anthropic support, visit [support.anthropic.com](https://support.anthropic.com).",
|
||||
},
|
||||
{
|
||||
label: "needs-repro",
|
||||
days: 7,
|
||||
reason: "we still need reproduction steps to investigate",
|
||||
nudge: "We weren't able to reproduce this. Could you provide steps to trigger the issue — what you ran, what happened, and what you expected?",
|
||||
},
|
||||
{
|
||||
label: "needs-info",
|
||||
days: 7,
|
||||
reason: "we still need a bit more information to move forward",
|
||||
nudge: "We need more information to continue investigating. Can you make sure to include your Claude Code version (`claude --version`), OS, and any error messages or logs?",
|
||||
},
|
||||
{
|
||||
label: "stale",
|
||||
days: 14,
|
||||
reason: "inactive for too long",
|
||||
nudge: "This issue has been automatically marked as stale due to inactivity.",
|
||||
},
|
||||
{
|
||||
label: "autoclose",
|
||||
days: 14,
|
||||
reason: "inactive for too long",
|
||||
nudge: "This issue has been marked for automatic closure.",
|
||||
},
|
||||
] as const;
|
||||
|
||||
export type LifecycleLabel = (typeof lifecycle)[number]["label"];
|
||||
|
||||
export const STALE_UPVOTE_THRESHOLD = 10;
|
||||
53
scripts/lifecycle-comment.ts
Normal file
53
scripts/lifecycle-comment.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env bun
|
||||
|
||||
// Posts a comment when a lifecycle label is applied to an issue,
|
||||
// giving the author a heads-up and a chance to respond before auto-close.
|
||||
|
||||
import { lifecycle } from "./issue-lifecycle.ts";
|
||||
|
||||
const DRY_RUN = process.argv.includes("--dry-run");
|
||||
const token = process.env.GITHUB_TOKEN;
|
||||
const repo = process.env.GITHUB_REPOSITORY; // owner/repo
|
||||
const label = process.env.LABEL;
|
||||
const issueNumber = process.env.ISSUE_NUMBER;
|
||||
|
||||
if (!DRY_RUN && !token) throw new Error("GITHUB_TOKEN required");
|
||||
if (!repo) throw new Error("GITHUB_REPOSITORY required");
|
||||
if (!label) throw new Error("LABEL required");
|
||||
if (!issueNumber) throw new Error("ISSUE_NUMBER required");
|
||||
|
||||
const entry = lifecycle.find((l) => l.label === label);
|
||||
if (!entry) {
|
||||
console.log(`No lifecycle entry for label "${label}", skipping`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const body = `${entry.nudge} This issue will be closed automatically if there's no activity within ${entry.days} days.`;
|
||||
|
||||
// --
|
||||
|
||||
if (DRY_RUN) {
|
||||
console.log(`Would comment on #${issueNumber} for label "${label}":\n\n${body}`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`https://api.github.com/repos/${repo}/issues/${issueNumber}/comments`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
Accept: "application/vnd.github.v3+json",
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": "lifecycle-comment",
|
||||
},
|
||||
body: JSON.stringify({ body }),
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
const text = await response.text();
|
||||
throw new Error(`GitHub API ${response.status}: ${text}`);
|
||||
}
|
||||
|
||||
console.log(`Commented on #${issueNumber} for label "${label}"`);
|
||||
110
scripts/sweep.ts
110
scripts/sweep.ts
@@ -1,23 +1,14 @@
|
||||
#!/usr/bin/env bun
|
||||
|
||||
import { lifecycle, STALE_UPVOTE_THRESHOLD } from "./issue-lifecycle.ts";
|
||||
|
||||
// --
|
||||
|
||||
const NEW_ISSUE = "https://github.com/anthropics/claude-code/issues/new/choose";
|
||||
const DRY_RUN = process.argv.includes("--dry-run");
|
||||
|
||||
const lifecycle = [
|
||||
{ label: "needs-repro", days: 7 },
|
||||
{ label: "needs-info", days: 7 },
|
||||
{ label: "needs-votes", days: 30 },
|
||||
{ label: "stale", days: 30 },
|
||||
];
|
||||
|
||||
const closeMessages: Record<string, string> = {
|
||||
"needs-repro": `Closing — we weren't able to get the reproduction steps needed to investigate.\n\nIf this is still a problem, please [open a new issue](${NEW_ISSUE}) with steps to reproduce.`,
|
||||
"needs-info": `Closing — we didn't receive the information needed to move forward.\n\nIf this is still a problem, please [open a new issue](${NEW_ISSUE}) with the requested details.`,
|
||||
"needs-votes": `Closing this feature request — it didn't get enough community support to prioritize.\n\nIf you'd still like to see this, please [open a new feature request](${NEW_ISSUE}) with more context about the use case.`,
|
||||
stale: `Closing due to inactivity.\n\nIf this is still a problem, please [open a new issue](${NEW_ISSUE}) with up-to-date information.`,
|
||||
};
|
||||
const CLOSE_MESSAGE = (reason: string) =>
|
||||
`Closing for now — ${reason}. Please [open a new issue](${NEW_ISSUE}) if this is still relevant.`;
|
||||
|
||||
// --
|
||||
|
||||
@@ -51,17 +42,57 @@ async function githubRequest<T>(
|
||||
|
||||
// --
|
||||
|
||||
async function main() {
|
||||
const owner = process.env.GITHUB_REPOSITORY_OWNER;
|
||||
const repo = process.env.GITHUB_REPOSITORY_NAME;
|
||||
if (!owner || !repo)
|
||||
throw new Error("GITHUB_REPOSITORY_OWNER and GITHUB_REPOSITORY_NAME required");
|
||||
async function markStale(owner: string, repo: string) {
|
||||
const staleDays = lifecycle.find((l) => l.label === "stale")!.days;
|
||||
const cutoff = new Date();
|
||||
cutoff.setDate(cutoff.getDate() - staleDays);
|
||||
|
||||
if (DRY_RUN) console.log("DRY RUN — no issues will be closed\n");
|
||||
let labeled = 0;
|
||||
|
||||
console.log(`\n=== marking stale (${staleDays}d inactive) ===`);
|
||||
|
||||
for (let page = 1; page <= 10; page++) {
|
||||
const issues = await githubRequest<any[]>(
|
||||
`/repos/${owner}/${repo}/issues?state=open&sort=updated&direction=asc&per_page=100&page=${page}`
|
||||
);
|
||||
if (issues.length === 0) break;
|
||||
|
||||
for (const issue of issues) {
|
||||
if (issue.pull_request) continue;
|
||||
if (issue.locked) continue;
|
||||
if (issue.assignees?.length > 0) continue;
|
||||
|
||||
const updatedAt = new Date(issue.updated_at);
|
||||
if (updatedAt > cutoff) return labeled;
|
||||
|
||||
const alreadyStale = issue.labels?.some(
|
||||
(l: any) => l.name === "stale" || l.name === "autoclose"
|
||||
);
|
||||
if (alreadyStale) continue;
|
||||
|
||||
const thumbsUp = issue.reactions?.["+1"] ?? 0;
|
||||
if (thumbsUp >= STALE_UPVOTE_THRESHOLD) continue;
|
||||
|
||||
const base = `/repos/${owner}/${repo}/issues/${issue.number}`;
|
||||
|
||||
if (DRY_RUN) {
|
||||
const age = Math.floor((Date.now() - updatedAt.getTime()) / 86400000);
|
||||
console.log(`#${issue.number}: would label stale (${age}d inactive) — ${issue.title}`);
|
||||
} else {
|
||||
await githubRequest(`${base}/labels`, "POST", { labels: ["stale"] });
|
||||
console.log(`#${issue.number}: labeled stale — ${issue.title}`);
|
||||
}
|
||||
labeled++;
|
||||
}
|
||||
}
|
||||
|
||||
return labeled;
|
||||
}
|
||||
|
||||
async function closeExpired(owner: string, repo: string) {
|
||||
let closed = 0;
|
||||
|
||||
for (const { label, days } of lifecycle) {
|
||||
for (const { label, days, reason } of lifecycle) {
|
||||
const cutoff = new Date();
|
||||
cutoff.setDate(cutoff.getDate() - days);
|
||||
console.log(`\n=== ${label} (${days}d timeout) ===`);
|
||||
@@ -74,6 +105,11 @@ async function main() {
|
||||
|
||||
for (const issue of issues) {
|
||||
if (issue.pull_request) continue;
|
||||
if (issue.locked) continue;
|
||||
|
||||
const thumbsUp = issue.reactions?.["+1"] ?? 0;
|
||||
if (thumbsUp >= STALE_UPVOTE_THRESHOLD) continue;
|
||||
|
||||
const base = `/repos/${owner}/${repo}/issues/${issue.number}`;
|
||||
|
||||
const events = await githubRequest<any[]>(`${base}/events?per_page=100`);
|
||||
@@ -85,11 +121,27 @@ async function main() {
|
||||
|
||||
if (!labeledAt || labeledAt > cutoff) continue;
|
||||
|
||||
// Skip if a non-bot user commented after the label was applied.
|
||||
// The triage workflow should remove lifecycle labels on human
|
||||
// activity, but check here too as a safety net.
|
||||
const comments = await githubRequest<any[]>(
|
||||
`${base}/comments?since=${labeledAt.toISOString()}&per_page=100`
|
||||
);
|
||||
const hasHumanComment = comments.some(
|
||||
(c) => c.user && c.user.type !== "Bot"
|
||||
);
|
||||
if (hasHumanComment) {
|
||||
console.log(
|
||||
`#${issue.number}: skipping (human activity after ${label} label)`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (DRY_RUN) {
|
||||
const age = Math.floor((Date.now() - labeledAt.getTime()) / 86400000);
|
||||
console.log(`#${issue.number}: would close (${label}, ${age}d old) — ${issue.title}`);
|
||||
} else {
|
||||
await githubRequest(`${base}/comments`, "POST", { body: closeMessages[label] });
|
||||
await githubRequest(`${base}/comments`, "POST", { body: CLOSE_MESSAGE(reason) });
|
||||
await githubRequest(base, "PATCH", { state: "closed", state_reason: "not_planned" });
|
||||
console.log(`#${issue.number}: closed (${label})`);
|
||||
}
|
||||
@@ -98,9 +150,19 @@ async function main() {
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\nDone: ${closed} ${DRY_RUN ? "would be closed" : "closed"}`);
|
||||
return closed;
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
// --
|
||||
|
||||
export {};
|
||||
const owner = process.env.GITHUB_REPOSITORY_OWNER;
|
||||
const repo = process.env.GITHUB_REPOSITORY_NAME;
|
||||
if (!owner || !repo)
|
||||
throw new Error("GITHUB_REPOSITORY_OWNER and GITHUB_REPOSITORY_NAME required");
|
||||
|
||||
if (DRY_RUN) console.log("DRY RUN — no changes will be made\n");
|
||||
|
||||
const labeled = await markStale(owner, repo);
|
||||
const closed = await closeExpired(owner, repo);
|
||||
|
||||
console.log(`\nDone: ${labeled} ${DRY_RUN ? "would be labeled" : "labeled"} stale, ${closed} ${DRY_RUN ? "would be closed" : "closed"}`);
|
||||
|
||||
Reference in New Issue
Block a user