Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

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

## Unreleased

- **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