mirror of
https://github.com/anthropics/claude-code.git
synced 2026-04-19 10:02:42 +00:00
Compare commits
1 Commits
claude/sla
...
claude/sla
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
411381bf3e |
68
CHANGELOG.md
68
CHANGELOG.md
@@ -1,71 +1,5 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 2.0.74
|
|
||||||
|
|
||||||
- Added LSP (Language Server Protocol) tool for code intelligence features like go-to-definition, find references, and hover documentation
|
|
||||||
- Added `/terminal-setup` support for Kitty, Alacritty, Zed, and Warp terminals
|
|
||||||
- Added ctrl+t shortcut in `/theme` to toggle syntax highlighting on/off
|
|
||||||
- Added syntax highlighting info to theme picker
|
|
||||||
- Added guidance for macOS users when Alt shortcuts fail due to terminal configuration
|
|
||||||
- Fixed skill `allowed-tools` not being applied to tools invoked by the skill
|
|
||||||
- Fixed Opus 4.5 tip incorrectly showing when user was already using Opus
|
|
||||||
- Fixed a potential crash when syntax highlighting isn't initialized correctly
|
|
||||||
- Fixed visual bug in `/plugins discover` where list selection indicator showed while search box was focused
|
|
||||||
- Fixed macOS keyboard shortcuts to display 'opt' instead of 'alt'
|
|
||||||
- Improved `/context` command visualization with grouped skills and agents by source, slash commands, and sorted token count
|
|
||||||
- [Windows] Fixed issue with improper rendering
|
|
||||||
- [VSCode] Added gift tag pictogram for year-end promotion message
|
|
||||||
|
|
||||||
## 2.0.73
|
|
||||||
|
|
||||||
- Added clickable `[Image #N]` links that open attached images in the default viewer
|
|
||||||
- Added alt-y yank-pop to cycle through kill ring history after ctrl-y yank
|
|
||||||
- Added search filtering to the plugin discover screen (type to filter by name, description, or marketplace)
|
|
||||||
- Added support for custom session IDs when forking sessions with `--session-id` combined with `--resume` or `--continue` and `--fork-session`
|
|
||||||
- Fixed slow input history cycling and race condition that could overwrite text after message submission
|
|
||||||
- Improved `/theme` command to open theme picker directly
|
|
||||||
- Improved theme picker UI
|
|
||||||
- Improved search UX across resume session, permissions, and plugins screens with a unified SearchBox component
|
|
||||||
- [VSCode] Added tab icon badges showing pending permissions (blue) and unread completions (orange)
|
|
||||||
|
|
||||||
## 2.0.72
|
|
||||||
|
|
||||||
- Added Claude in Chrome (Beta) feature that works with the Chrome extension (https://claude.ai/chrome) to let you control your browser directly from Claude Code
|
|
||||||
- Reduced terminal flickering
|
|
||||||
- Added scannable QR code to mobile app tip for quick app downloads
|
|
||||||
- Added loading indicator when resuming conversations for better feedback
|
|
||||||
- Fixed `/context` command not respecting custom system prompts in non-interactive mode
|
|
||||||
- Fixed order of consecutive Ctrl+K lines when pasting with Ctrl+Y
|
|
||||||
- Improved @ mention file suggestion speed (~3x faster in git repositories)
|
|
||||||
- Improved file suggestion performance in repos with `.ignore` or `.rgignore` files
|
|
||||||
- Improved settings validation errors to be more prominent
|
|
||||||
- Changed thinking toggle from Tab to Alt+T to avoid accidental triggers
|
|
||||||
|
|
||||||
## 2.0.71
|
|
||||||
|
|
||||||
- Added /config toggle to enable/disable prompt suggestions
|
|
||||||
- Added `/settings` as an alias for the `/config` command
|
|
||||||
- Fixed @ file reference suggestions incorrectly triggering when cursor is in the middle of a path
|
|
||||||
- Fixed MCP servers from `.mcp.json` not loading when using `--dangerously-skip-permissions`
|
|
||||||
- Fixed permission rules incorrectly rejecting valid bash commands containing shell glob patterns (e.g., `ls *.txt`, `for f in *.png`)
|
|
||||||
- Bedrock: Environment variable `ANTHROPIC_BEDROCK_BASE_URL` is now respected for token counting and inference profile listing
|
|
||||||
- New syntax highlighting engine for native build
|
|
||||||
|
|
||||||
## 2.0.70
|
|
||||||
|
|
||||||
- Added Enter key to accept and submit prompt suggestions immediately (tab still accepts for editing)
|
|
||||||
- Added wildcard syntax `mcp__server__*` for MCP tool permissions to allow or deny all tools from a server
|
|
||||||
- Added auto-update toggle for plugin marketplaces, allowing per-marketplace control over automatic updates
|
|
||||||
- Added `current_usage` field to status line input, enabling accurate context window percentage calculations
|
|
||||||
- Fixed input being cleared when processing queued commands while the user was typing
|
|
||||||
- Fixed prompt suggestions replacing typed input when pressing Tab
|
|
||||||
- Fixed diff view not updating when terminal is resized
|
|
||||||
- Improved memory usage by 3x for large conversations
|
|
||||||
- Improved resolution of stats screenshots copied to clipboard (Ctrl+S) for crisper images
|
|
||||||
- Removed # shortcut for quick memory entry (tell Claude to edit your CLAUDE.md instead)
|
|
||||||
- Fix thinking mode toggle in /config not persisting correctly
|
|
||||||
- Improve UI for file creation permission dialog
|
|
||||||
|
|
||||||
## 2.0.69
|
## 2.0.69
|
||||||
|
|
||||||
- Minor bugfixes
|
- Minor bugfixes
|
||||||
@@ -370,7 +304,7 @@
|
|||||||
|
|
||||||
## 2.0.20
|
## 2.0.20
|
||||||
|
|
||||||
- Added support for Claude Skills. Skills are a new feature that provide specialized capabilities and domain knowledge to Claude. The internal "Skill" tool also handles slash command invocation (previously done by the "SlashCommand" tool) - this is an internal change to how Claude invokes your slash commands, not a replacement of slash commands. Slash commands continue to work exactly the same way for users.
|
- Added support for Claude Skills
|
||||||
|
|
||||||
## 2.0.19
|
## 2.0.19
|
||||||
|
|
||||||
|
|||||||
@@ -22,29 +22,23 @@ Performs automated code review on a pull request using multiple specialized agen
|
|||||||
- **Agent #4**: Analyze git blame/history for context-based issues
|
- **Agent #4**: Analyze git blame/history for context-based issues
|
||||||
5. Scores each issue 0-100 for confidence level
|
5. Scores each issue 0-100 for confidence level
|
||||||
6. Filters out issues below 80 confidence threshold
|
6. Filters out issues below 80 confidence threshold
|
||||||
7. Outputs review (to terminal by default, or as PR comment with `--comment` flag)
|
7. Posts review comment with high-confidence issues only
|
||||||
|
|
||||||
**Usage:**
|
**Usage:**
|
||||||
```bash
|
```bash
|
||||||
/code-review [--comment]
|
/code-review
|
||||||
```
|
```
|
||||||
|
|
||||||
**Options:**
|
|
||||||
- `--comment`: Post the review as a comment on the pull request (default: outputs to terminal only)
|
|
||||||
|
|
||||||
**Example workflow:**
|
**Example workflow:**
|
||||||
```bash
|
```bash
|
||||||
# On a PR branch, run locally (outputs to terminal):
|
# On a PR branch, run:
|
||||||
/code-review
|
/code-review
|
||||||
|
|
||||||
# Post review as PR comment:
|
|
||||||
/code-review --comment
|
|
||||||
|
|
||||||
# Claude will:
|
# Claude will:
|
||||||
# - Launch 4 review agents in parallel
|
# - Launch 4 review agents in parallel
|
||||||
# - Score each issue for confidence
|
# - Score each issue for confidence
|
||||||
# - Output issues ≥80 confidence (to terminal or PR depending on flag)
|
# - Post comment with issues ≥80 confidence
|
||||||
# - Skip if no high-confidence issues found
|
# - Skip posting if no high-confidence issues found
|
||||||
```
|
```
|
||||||
|
|
||||||
**Features:**
|
**Features:**
|
||||||
@@ -120,23 +114,17 @@ This plugin is included in the Claude Code repository. The command is automatica
|
|||||||
### Standard PR review workflow:
|
### Standard PR review workflow:
|
||||||
```bash
|
```bash
|
||||||
# Create PR with changes
|
# Create PR with changes
|
||||||
# Run local review (outputs to terminal)
|
|
||||||
/code-review
|
/code-review
|
||||||
|
|
||||||
# Review the automated feedback
|
# Review the automated feedback
|
||||||
# Make any necessary fixes
|
# Make any necessary fixes
|
||||||
|
|
||||||
# Optionally post as PR comment
|
|
||||||
/code-review --comment
|
|
||||||
|
|
||||||
# Merge when ready
|
# Merge when ready
|
||||||
```
|
```
|
||||||
|
|
||||||
### As part of CI/CD:
|
### As part of CI/CD:
|
||||||
```bash
|
```bash
|
||||||
# Trigger on PR creation or update
|
# Trigger on PR creation or update
|
||||||
# Use --comment flag to post review comments
|
# Automatically posts review comments
|
||||||
/code-review --comment
|
|
||||||
# Skip if review already exists
|
# Skip if review already exists
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
allowed-tools: Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(gh pr comment:*), Bash(gh pr diff:*), Bash(gh pr view:*), Bash(gh pr list:*), mcp__github_inline_comment__create_inline_comment
|
allowed-tools: Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(gh pr comment:*), Bash(gh pr diff:*), Bash(gh pr view:*), Bash(gh pr list:*)
|
||||||
description: Code review a pull request
|
description: Code review a pull request
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ To do this, follow these steps precisely:
|
|||||||
- The pull request is closed
|
- The pull request is closed
|
||||||
- The pull request is a draft
|
- The pull request is a draft
|
||||||
- The pull request does not need code review (e.g. automated PR, trivial change that is obviously correct)
|
- The pull request does not need code review (e.g. automated PR, trivial change that is obviously correct)
|
||||||
- Claude has already commented on this PR (check `gh pr view <PR> --comments` for comments left by claude)
|
- You have already submitted a code review on this pull request
|
||||||
|
|
||||||
If any condition is true, stop and do not proceed.
|
If any condition is true, stop and do not proceed.
|
||||||
|
|
||||||
@@ -52,30 +52,12 @@ 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.
|
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. Finally, comment on the pull request.
|
||||||
|
When writing your comment, follow these guidelines:
|
||||||
If NO issues were found, post a summary comment using `gh pr comment` (if `--comment` argument is provided):
|
a. Keep your output brief
|
||||||
"No issues found. Checked for bugs and CLAUDE.md compliance."
|
b. Avoid emojis
|
||||||
|
c. Link and cite relevant code, files, and URLs for each issue
|
||||||
8. Post inline comments for each issue using `mcp__github_inline_comment__create_inline_comment`:
|
d. When citing CLAUDE.md violations, you MUST quote the exact text from CLAUDE.md that is being violated (e.g., CLAUDE.md says: "Use snake_case for variable names")
|
||||||
- `path`: the file path
|
|
||||||
- `line` (and `startLine` for ranges): select the buggy lines so the user sees them
|
|
||||||
- `body`: Brief description of the issue (no "Bug:" prefix). For small fixes (up to 5 lines changed), include a committable suggestion:
|
|
||||||
```suggestion
|
|
||||||
corrected code here
|
|
||||||
```
|
|
||||||
|
|
||||||
**Suggestions must be COMPLETE.** If a fix requires additional changes elsewhere (e.g., renaming a variable requires updating all usages), do NOT use a suggestion block. The author should be able to click "Commit suggestion" and have a working fix - no followup work required.
|
|
||||||
|
|
||||||
For larger fixes (6+ lines, structural changes, or changes spanning multiple locations), do NOT use suggestion blocks. Instead:
|
|
||||||
1. Describe what the issue is
|
|
||||||
2. Explain the suggested fix at a high level
|
|
||||||
3. Include a copyable prompt for Claude Code that the user can use to fix the issue, formatted as:
|
|
||||||
```
|
|
||||||
Fix [file:line]: [brief description of issue and suggested fix]
|
|
||||||
```
|
|
||||||
|
|
||||||
**IMPORTANT: Only post ONE comment per unique issue. Do not post duplicate comments.**
|
|
||||||
|
|
||||||
Use this list when evaluating issues in Steps 4 and 5 (these are false positives, do NOT flag):
|
Use this list when evaluating issues in Steps 4 and 5 (these are false positives, do NOT flag):
|
||||||
|
|
||||||
@@ -90,18 +72,40 @@ Notes:
|
|||||||
|
|
||||||
- Use gh CLI to interact with GitHub (e.g., fetch pull requests, create comments). Do not use web fetch.
|
- 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.
|
- 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).
|
- You must cite and link each issue (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:
|
- For your final comment, follow the following format precisely (assuming for this example that you found 3 issues):
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Code review
|
## Code review
|
||||||
|
|
||||||
|
Found 3 issues:
|
||||||
|
|
||||||
|
1. <brief description of bug> (CLAUDE.md says: "<exact quote from CLAUDE.md>")
|
||||||
|
|
||||||
|
<link to file and line with full sha1 + line range for context, eg. https://github.com/anthropics/claude-code/blob/1d54823877c4de72b2316a64032a54afc404e619/README.md#L13-L17>
|
||||||
|
|
||||||
|
2. <brief description of bug> (some/other/CLAUDE.md says: "<exact quote from CLAUDE.md>")
|
||||||
|
|
||||||
|
<link to file and line with full sha1 + line range for context>
|
||||||
|
|
||||||
|
3. <brief description of bug> (bug due to <file and code snippet>)
|
||||||
|
|
||||||
|
<link to file and line with full sha1 + line range for context>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- Or, if you found no issues:
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Auto code review
|
||||||
|
|
||||||
No issues found. Checked for bugs and CLAUDE.md compliance.
|
No issues found. Checked for bugs and CLAUDE.md compliance.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
- When linking to code in inline comments, follow the following format precisely, otherwise the Markdown preview won't render correctly: https://github.com/anthropics/claude-code/blob/c21d3c10bc8e898b7ac1a2d745bdc9bc4e423afe/package.json#L10-L15
|
- When linking to code, follow the following format precisely, otherwise the Markdown preview won't render correctly: https://github.com/anthropics/claude-code/blob/c21d3c10bc8e898b7ac1a2d745bdc9bc4e423afe/package.json#L10-L15
|
||||||
- Requires full git sha
|
- Requires full git sha
|
||||||
- You must provide the full sha. Commands like `https://github.com/owner/repo/blob/$(git rev-parse HEAD)/foo/bar` will not work, since your comment will be directly rendered in Markdown.
|
- You must provide the full sha. Commands like `https://github.com/owner/repo/blob/$(git rev-parse HEAD)/foo/bar` will not work, since your comment will be directly rendered in Markdown.
|
||||||
- Repo name must match the repo you're code reviewing
|
- Repo name must match the repo you're code reviewing
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
"hooks": {
|
"hooks": {
|
||||||
"SessionStart": [
|
"SessionStart": [
|
||||||
{
|
{
|
||||||
|
"matcher": "*",
|
||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
"hooks": {
|
"hooks": {
|
||||||
"PreToolUse": [
|
"PreToolUse": [
|
||||||
{
|
{
|
||||||
|
"matcher": "*",
|
||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
@@ -14,6 +15,7 @@
|
|||||||
],
|
],
|
||||||
"PostToolUse": [
|
"PostToolUse": [
|
||||||
{
|
{
|
||||||
|
"matcher": "*",
|
||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
@@ -25,6 +27,7 @@
|
|||||||
],
|
],
|
||||||
"Stop": [
|
"Stop": [
|
||||||
{
|
{
|
||||||
|
"matcher": "*",
|
||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
@@ -36,6 +39,7 @@
|
|||||||
],
|
],
|
||||||
"UserPromptSubmit": [
|
"UserPromptSubmit": [
|
||||||
{
|
{
|
||||||
|
"matcher": "*",
|
||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
"hooks": {
|
"hooks": {
|
||||||
"SessionStart": [
|
"SessionStart": [
|
||||||
{
|
{
|
||||||
|
"matcher": "*",
|
||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
|
|||||||
@@ -40,7 +40,27 @@ echo ""
|
|||||||
echo "Checking root structure..."
|
echo "Checking root structure..."
|
||||||
VALID_EVENTS=("PreToolUse" "PostToolUse" "UserPromptSubmit" "Stop" "SubagentStop" "SessionStart" "SessionEnd" "PreCompact" "Notification")
|
VALID_EVENTS=("PreToolUse" "PostToolUse" "UserPromptSubmit" "Stop" "SubagentStop" "SessionStart" "SessionEnd" "PreCompact" "Notification")
|
||||||
|
|
||||||
for event in $(jq -r 'keys[]' "$HOOKS_FILE"); do
|
# Detect format: plugin format has { description?, hooks: {...} } wrapper
|
||||||
|
# Settings format has events directly at root level
|
||||||
|
is_plugin_format=false
|
||||||
|
if jq -e '.hooks' "$HOOKS_FILE" >/dev/null 2>&1; then
|
||||||
|
is_plugin_format=true
|
||||||
|
HOOKS_PATH=".hooks"
|
||||||
|
echo "Detected plugin format (with 'hooks' wrapper)"
|
||||||
|
|
||||||
|
# Validate allowed root keys for plugin format
|
||||||
|
for key in $(jq -r 'keys[]' "$HOOKS_FILE"); do
|
||||||
|
if [ "$key" != "hooks" ] && [ "$key" != "description" ]; then
|
||||||
|
echo "⚠️ Unknown root key in plugin format: $key (expected: 'hooks', 'description')"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
HOOKS_PATH="."
|
||||||
|
echo "Detected settings format (events at root)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Validate event types
|
||||||
|
for event in $(jq -r "$HOOKS_PATH | keys[]" "$HOOKS_FILE"); do
|
||||||
found=false
|
found=false
|
||||||
for valid_event in "${VALID_EVENTS[@]}"; do
|
for valid_event in "${VALID_EVENTS[@]}"; do
|
||||||
if [ "$event" = "$valid_event" ]; then
|
if [ "$event" = "$valid_event" ]; then
|
||||||
@@ -62,12 +82,12 @@ echo "Validating individual hooks..."
|
|||||||
error_count=0
|
error_count=0
|
||||||
warning_count=0
|
warning_count=0
|
||||||
|
|
||||||
for event in $(jq -r 'keys[]' "$HOOKS_FILE"); do
|
for event in $(jq -r "$HOOKS_PATH | keys[]" "$HOOKS_FILE"); do
|
||||||
hook_count=$(jq -r ".\"$event\" | length" "$HOOKS_FILE")
|
hook_count=$(jq -r "$HOOKS_PATH.\"$event\" | length" "$HOOKS_FILE")
|
||||||
|
|
||||||
for ((i=0; i<hook_count; i++)); do
|
for ((i=0; i<hook_count; i++)); do
|
||||||
# Check matcher exists
|
# Check matcher exists
|
||||||
matcher=$(jq -r ".\"$event\"[$i].matcher // empty" "$HOOKS_FILE")
|
matcher=$(jq -r "$HOOKS_PATH.\"$event\"[$i].matcher // empty" "$HOOKS_FILE")
|
||||||
if [ -z "$matcher" ]; then
|
if [ -z "$matcher" ]; then
|
||||||
echo "❌ $event[$i]: Missing 'matcher' field"
|
echo "❌ $event[$i]: Missing 'matcher' field"
|
||||||
((error_count++))
|
((error_count++))
|
||||||
@@ -75,7 +95,7 @@ for event in $(jq -r 'keys[]' "$HOOKS_FILE"); do
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Check hooks array exists
|
# Check hooks array exists
|
||||||
hooks=$(jq -r ".\"$event\"[$i].hooks // empty" "$HOOKS_FILE")
|
hooks=$(jq -r "$HOOKS_PATH.\"$event\"[$i].hooks // empty" "$HOOKS_FILE")
|
||||||
if [ -z "$hooks" ] || [ "$hooks" = "null" ]; then
|
if [ -z "$hooks" ] || [ "$hooks" = "null" ]; then
|
||||||
echo "❌ $event[$i]: Missing 'hooks' array"
|
echo "❌ $event[$i]: Missing 'hooks' array"
|
||||||
((error_count++))
|
((error_count++))
|
||||||
@@ -83,10 +103,10 @@ for event in $(jq -r 'keys[]' "$HOOKS_FILE"); do
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Validate each hook in the array
|
# Validate each hook in the array
|
||||||
hook_array_count=$(jq -r ".\"$event\"[$i].hooks | length" "$HOOKS_FILE")
|
hook_array_count=$(jq -r "$HOOKS_PATH.\"$event\"[$i].hooks | length" "$HOOKS_FILE")
|
||||||
|
|
||||||
for ((j=0; j<hook_array_count; j++)); do
|
for ((j=0; j<hook_array_count; j++)); do
|
||||||
hook_type=$(jq -r ".\"$event\"[$i].hooks[$j].type // empty" "$HOOKS_FILE")
|
hook_type=$(jq -r "$HOOKS_PATH.\"$event\"[$i].hooks[$j].type // empty" "$HOOKS_FILE")
|
||||||
|
|
||||||
if [ -z "$hook_type" ]; then
|
if [ -z "$hook_type" ]; then
|
||||||
echo "❌ $event[$i].hooks[$j]: Missing 'type' field"
|
echo "❌ $event[$i].hooks[$j]: Missing 'type' field"
|
||||||
@@ -102,7 +122,7 @@ for event in $(jq -r 'keys[]' "$HOOKS_FILE"); do
|
|||||||
|
|
||||||
# Check type-specific fields
|
# Check type-specific fields
|
||||||
if [ "$hook_type" = "command" ]; then
|
if [ "$hook_type" = "command" ]; then
|
||||||
command=$(jq -r ".\"$event\"[$i].hooks[$j].command // empty" "$HOOKS_FILE")
|
command=$(jq -r "$HOOKS_PATH.\"$event\"[$i].hooks[$j].command // empty" "$HOOKS_FILE")
|
||||||
if [ -z "$command" ]; then
|
if [ -z "$command" ]; then
|
||||||
echo "❌ $event[$i].hooks[$j]: Command hooks must have 'command' field"
|
echo "❌ $event[$i].hooks[$j]: Command hooks must have 'command' field"
|
||||||
((error_count++))
|
((error_count++))
|
||||||
@@ -114,7 +134,7 @@ for event in $(jq -r 'keys[]' "$HOOKS_FILE"); do
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
elif [ "$hook_type" = "prompt" ]; then
|
elif [ "$hook_type" = "prompt" ]; then
|
||||||
prompt=$(jq -r ".\"$event\"[$i].hooks[$j].prompt // empty" "$HOOKS_FILE")
|
prompt=$(jq -r "$HOOKS_PATH.\"$event\"[$i].hooks[$j].prompt // empty" "$HOOKS_FILE")
|
||||||
if [ -z "$prompt" ]; then
|
if [ -z "$prompt" ]; then
|
||||||
echo "❌ $event[$i].hooks[$j]: Prompt hooks must have 'prompt' field"
|
echo "❌ $event[$i].hooks[$j]: Prompt hooks must have 'prompt' field"
|
||||||
((error_count++))
|
((error_count++))
|
||||||
@@ -128,7 +148,7 @@ for event in $(jq -r 'keys[]' "$HOOKS_FILE"); do
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Check timeout
|
# Check timeout
|
||||||
timeout=$(jq -r ".\"$event\"[$i].hooks[$j].timeout // empty" "$HOOKS_FILE")
|
timeout=$(jq -r "$HOOKS_PATH.\"$event\"[$i].hooks[$j].timeout // empty" "$HOOKS_FILE")
|
||||||
if [ -n "$timeout" ] && [ "$timeout" != "null" ]; then
|
if [ -n "$timeout" ] && [ "$timeout" != "null" ]; then
|
||||||
if ! [[ "$timeout" =~ ^[0-9]+$ ]]; then
|
if ! [[ "$timeout" =~ ^[0-9]+$ ]]; then
|
||||||
echo "❌ $event[$i].hooks[$j]: Timeout must be a number"
|
echo "❌ $event[$i].hooks[$j]: Timeout must be a number"
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
"hooks": {
|
"hooks": {
|
||||||
"Stop": [
|
"Stop": [
|
||||||
{
|
{
|
||||||
|
"matcher": "*",
|
||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
|
|||||||
49
scripts/validate-all-hooks.sh
Executable file
49
scripts/validate-all-hooks.sh
Executable file
@@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Validate all hooks.json files in the repository
|
||||||
|
# This script can be run in CI to ensure all plugins have valid hook configurations
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REPO_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||||
|
VALIDATOR="$REPO_ROOT/plugins/plugin-dev/skills/hook-development/scripts/validate-hook-schema.sh"
|
||||||
|
|
||||||
|
echo "🔍 Validating all hooks.json files in the repository..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Find all hooks.json files
|
||||||
|
mapfile -t HOOKS_FILES < <(find "$REPO_ROOT/plugins" -name "hooks.json" -type f 2>/dev/null)
|
||||||
|
|
||||||
|
if [ ${#HOOKS_FILES[@]} -eq 0 ]; then
|
||||||
|
echo "No hooks.json files found"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Found ${#HOOKS_FILES[@]} hooks.json file(s)"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
errors=0
|
||||||
|
for hooks_file in "${HOOKS_FILES[@]}"; do
|
||||||
|
relative_path="${hooks_file#$REPO_ROOT/}"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo "📄 $relative_path"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if bash "$VALIDATOR" "$hooks_file"; then
|
||||||
|
echo ""
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
((errors++))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ $errors -eq 0 ]; then
|
||||||
|
echo "✅ All ${#HOOKS_FILES[@]} hooks.json file(s) are valid!"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "❌ $errors hooks.json file(s) have validation errors"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user