Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
*.sh text eol=lf
*.bash text eol=lf
*.bats text eol=lf
hooks/run-hook.cmd text eol=lf
hooks/*.cmd text eol=lf
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to this project are documented in this file.

## Unreleased

## v1.3.0 (2026-02-21)

- **Subagent-aware blocking rules** (Claude Code only): `.block` files can now scope protection rules to specific subagent types using new `agents` and `disable_main_agent` configuration keys. For example, `{"agents": ["Explore"], "disable_main_agent": true}` blocks only Explore subagents while allowing the main agent and other subagent types. Rules are backward-compatible — existing `.block` files without agent keys continue to block all agents. Agent fields are inherited through hierarchical and same-directory merges with child/local overrides. (PR #26)

## v1.2.1 (2026-02-19)

- Added `CHANGELOG.md` documenting all releases from v1.0.2 through v1.2.0.
Expand Down
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,35 @@ Keep Claude focused on specific directories during feature work:
}
```

### Agent-Specific Rules (Claude Code only)

Scope protection to specific subagent types. For example, block a code-review agent from modifying source files:

```text
src/
└── .block → {"agents": ["code-reviewer"]}
```

This blocks the `code-reviewer` subagent from writing to `src/`. Other subagents and the main agent are unaffected — the `.block` file is skipped for them.

| Key | Type | Description |
|-----|------|-------------|
| `agents` | `string[]` | Subagent types this `.block` file applies to (others are skipped). Main agent is always skipped. |
| `disable_main_agent` | `bool` | When `true`, the main agent is skipped (for use without `agents`) |

**Truth table:**

*"Skipped" means this `.block` file is skipped — other `.block` files may still block.*

| Config | Main agent | Listed subagents | Other subagents |
|--------|-----------|-----------------|-----------------|
| No agent keys | Blocked | Blocked | Blocked |
| `agents: ["TestCreator"]` | Skipped | Blocked | Skipped |
| `disable_main_agent: true` | Skipped | Blocked | Blocked |
| Both keys set | Skipped | Blocked | Skipped |
| `agents: []` | Skipped | Skipped | Skipped |


## Pattern Syntax

| Pattern | Description |
Expand Down Expand Up @@ -231,7 +260,9 @@ pytest tests/ -v --cov=hooks --cov-report=term-missing
block/
├── hooks/
│ ├── protect_directories.py # Main protection logic (Python)
│ └── run-hook.cmd # Cross-platform entry point (Claude Code)
│ ├── subagent_tracker.py # Subagent event tracker (Claude Code)
│ ├── run-hook.cmd # Cross-platform entry point (Claude Code)
│ └── run-subagent-hook.cmd # Subagent hook entry point (Claude Code)
├── opencode/
│ ├── index.ts # OpenCode plugin entry point
│ └── package.json # npm package metadata
Expand Down
24 changes: 24 additions & 0 deletions hooks/hooks.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,30 @@
}
]
}
],
"SubagentStart": [
{
"matcher": ".*",
"hooks": [
{
"type": "command",
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-subagent-hook.cmd\"",
"timeout": 3000
}
]
}
],
"SubagentStop": [
{
"matcher": ".*",
"hooks": [
{
"type": "command",
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-subagent-hook.cmd\"",
"timeout": 3000
}
]
}
]
}
}
Loading