Thank you for your interest in contributing to ICR! This guide will help you get started with contributing to the project.
Acknowledgement: ICR is inspired by the YouTube video "The AI Failure Mode Nobody Warned You About (And how to prevent it from happening)". Before contributing, we recommend watching this video to understand the core problem ICR solves.
- Getting Started
- Development Setup
- Code Style Guidelines
- Making Changes
- Testing Your Changes
- Submitting Changes
- Types of Contributions
- Getting Help
Before contributing, make sure you have:
- Git installed and configured
- jq installed (version 1.6 or higher)
- Claude Code installed for testing
- ShellCheck installed (optional, for linting)
- A text editor with Bash and JSON support
Before making changes, please read:
- ARCHITECTURE.md - Understand the big picture
- DEVELOPER_GUIDE.md - Learn implementation details
- ICR_PLUGIN_SPEC.md - Full specification
Good first issues include:
- Adding new severity patterns
- Improving error messages
- Adding documentation
- Writing tests
- Fixing typos
git clone <repository-url>
cd icr# Check jq
jq --version
# Should output: jq-1.6 or higher
# Check ShellCheck (optional but recommended)
shellcheck --versionchmod +x scripts/*.sh
chmod +x scripts/lib/*.shCreate a symlink to your plugins directory:
# macOS/Linux
ln -s $(pwd) ~/.claude/plugins/icr-dev
# Or copy for testing
cp -r . ~/.claude/plugins/icr-devStart Claude Code and run:
/icr:statsYou should see the statistics output.
Every script should start with:
#!/bin/bash
# Brief description of what this script does
# Additional context if needed
set -euo pipefail# Local variables: snake_case
local my_variable="value"
# Environment variables: UPPER_SNAKE_CASE
export ICR_CONFIG_PATH="/path/to/config"
# Constants (readonly): UPPER_SNAKE_CASE
readonly MAX_RETRIES=3# Functions: snake_case
calculate_confidence() {
# ...
}
# Private/internal functions: prefix with underscore
_internal_helper() {
# ...
}Always quote variables to prevent word splitting:
# Good
echo "$my_variable"
local result="$other_variable"
# Bad
echo $my_variable
local result=$other_variable# Use set -e to exit on errors
set -euo pipefail
# Check command success explicitly when needed
if ! result=$(some_command); then
log_error "Command failed"
return 1
fi
# Provide fallback for optional commands
value=$(risky_command 2>/dev/null || echo "default")# Single-line comment for brief explanations
# Multi-line comments for complex logic:
# This section handles the edge case where
# the user has specified a custom threshold
# that conflicts with trust mode settings.
# TODO: Add feature X
# FIXME: Handle edge case YUse 2-space indentation:
{
"key": "value",
"nested": {
"inner": "value"
},
"array": [
"item1",
"item2"
]
}All JSON files should be valid. Check with:
jq . filename.json > /dev/nullFollow this structure:
---
description: Brief description for help text
user_invocable: true
---
# Command Name
One paragraph explaining what the command does.
## Usage
- `/icr:command` - Basic usage
- `/icr:command arg` - With argument
## Examples
[Include practical examples]
## Notes
[Any important notes or warnings]git checkout -b feature/my-feature
# or
git checkout -b fix/my-bugfixEdit the relevant files. Keep changes focused - one feature or fix per branch.
# Lint bash scripts
shellcheck scripts/*.sh
shellcheck scripts/lib/*.sh
# Validate JSON files
jq . config/defaults.json > /dev/null
jq . schemas/*.json > /dev/null
# Test individual scripts
echo '{"tool_name": "Bash"}' | bash scripts/lib/severity.shIf your changes affect user-facing behavior:
- Update the relevant command documentation in
commands/ - Update
USER_GUIDE.mdif needed - Update
DEVELOPER_GUIDE.mdif you changed implementation details - Add an entry to
CHANGELOG.md
Write clear commit messages:
# Good
git commit -m "Add severity rule for 'sudo' commands
- Adds CRITICAL severity for Bash commands containing 'sudo'
- Updates defaults.json with new pattern
- Adds documentation in USER_GUIDE.md"
# Bad
git commit -m "fixed stuff"# Test severity classification
echo '{"tool_name": "Bash", "tool_input": {"command": "sudo rm"}}' | \
bash scripts/lib/severity.sh
# Expected output includes severity: "CRITICAL"# Test the main hook
echo '{
"tool_name": "Bash",
"tool_input": {"command": "ls -la"},
"session_id": "test-123",
"user_prompt": "list files"
}' | bash scripts/pre-tool-check.sh-
Start Claude Code with your development plugin:
claude --plugin-dir ./
-
Test various scenarios:
- Low-risk actions (should auto-approve)
- High-risk actions (should prompt)
- Slash commands (
/icr:stats,/icr:receipts)
Before submitting, run all checks:
# Create a simple test script
#!/bin/bash
set -e
echo "Linting scripts..."
shellcheck scripts/*.sh scripts/lib/*.sh
echo "Validating JSON..."
for f in config/*.json schemas/*.json; do
jq . "$f" > /dev/null
echo " $f OK"
done
echo "Testing severity classification..."
result=$(echo '{"tool_name": "Read"}' | bash scripts/lib/severity.sh)
echo "$result" | jq -e '.severity == "LOW"' > /dev/null
echo " Severity test OK"
echo "All checks passed!"Ensure:
- All scripts pass ShellCheck (or have documented exceptions)
- All JSON files are valid
- You've tested your changes manually
- Documentation is updated
- CHANGELOG.md has an entry for your change
- Commit messages are clear and descriptive
-
Title: Clear, concise description
- Good: "Add CRITICAL severity for sudo commands"
- Bad: "Fixed issue"
-
Description: Explain what and why
## What Added automatic CRITICAL classification for Bash commands containing 'sudo'. ## Why sudo commands can make system-wide changes and should always require human review. ## Testing - Tested with `echo '{"tool_name": "Bash", "tool_input": {"command": "sudo apt install"}}' | bash scripts/lib/severity.sh` - Verified CRITICAL severity is returned ## Documentation - Updated USER_GUIDE.md with new pattern - Added CHANGELOG entry
-
Keep it focused: One feature/fix per PR
- Describe the bug in an issue first
- Reference the issue in your PR
- Add a test case that would have caught the bug
- Discuss the feature in an issue first
- Get agreement on the approach
- Implement with tests and documentation
- Fix typos or unclear explanations
- Add examples
- Improve tutorials
- Translate documentation
Add to config/defaults.json:
{
"severity": {
"userRules": [
{
"pattern": "ToolName",
"condition": "args.property === 'dangerous'",
"severity": "CRITICAL",
"reason": "Why this pattern is critical"
}
]
}
}- Create
commands/mycommand.md - Add to
plugin.json - Document in
USER_GUIDE.md - Add to
CHANGELOG.md
- Check existing documentation first
- Look at similar code in the codebase
- Ask in project discussions/issues
- Check if it's already reported
- Create a new issue with:
- Steps to reproduce
- Expected behavior
- Actual behavior
- Environment details
- Check if it's already proposed
- Create an issue describing:
- The problem you're solving
- Your proposed solution
- Alternatives considered
- Be respectful and inclusive
- Focus on constructive feedback
- Help others learn
- Assume good intentions
Contributors are recognized in:
- CHANGELOG.md for each release
- Contributors list in README.md
Thank you for contributing to ICR!