Skip to content

Commit 05c0f69

Browse files
lenucksiclaude
andcommitted
BACK-494 - Add OpenCode plugin and update setup docs for both Claude Code and OpenCode
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 8ee6739 commit 05c0f69

5 files changed

Lines changed: 511 additions & 68 deletions

File tree

.codex/skills/backlog-guard-setup/SKILL.md

Lines changed: 70 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
---
22
name: backlog-guard-setup
3-
description: Configure the backlog-guard PreToolUse hook for this project. Auto-detects
4-
the backlog directory, creates the .backlog-guard config file, writes the hook entry
5-
into .claude/settings.json or settings.local.json, and optionally adds mcp__backlog__*
6-
permissions to the allowlist.
3+
description: Configure the backlog-guard hook for this project in Claude Code and/or
4+
OpenCode. Auto-detects the backlog directory, creates the .backlog-guard config file,
5+
writes the Claude Code hook entry into settings.json, and sets up the OpenCode plugin.
6+
Optionally adds mcp__backlog__* permissions to the allowlist.
77
---
88

99
# Backlog Guard Setup
1010

11-
Install the `backlog-guard` PreToolUse hook, which hard-blocks direct
12-
`Read`/`Edit`/`Write`/`Bash` access to Backlog.md data directories and redirects
13-
agents to the correct MCP tool or CLI command.
11+
Install `backlog-guard`, which hard-blocks direct `Read`/`Edit`/`Write`/`Bash` access
12+
to Backlog.md data directories and redirects agents to the correct MCP tool or CLI
13+
command.
14+
15+
Supports both **Claude Code** (PreToolUse hook via `guard.sh`) and **OpenCode**
16+
(plugin via `opencode-plugin.js`). Run this skill once; it handles both if both are
17+
in use.
1418

1519
## Steps
1620

@@ -23,17 +27,17 @@ If no `backlog/config.yml` is found, ask the user:
2327
> "I couldn't find a backlog directory automatically. Please provide the path(s)
2428
> to the directory (or directories) that agents should not access directly."
2529
26-
### 2. Locate the hook script (`guard.sh`)
30+
### 2. Locate the hook files
2731

28-
Check these locations in order:
32+
Check these locations in order for both `guard.sh` and `opencode-plugin.js`:
2933

30-
1. `<git-root>/hooks/backlog-guard/guard.sh` — running from the Backlog.md source tree
31-
2. `$(npm root -g 2>/dev/null)/backlog.md/hooks/backlog-guard/guard.sh` — global npm install
32-
3. `$(~/.bun/bin/backlog --prefix 2>/dev/null)/hooks/backlog-guard/guard.sh` — bun global install
34+
1. `<git-root>/hooks/backlog-guard/` — running from the Backlog.md source tree
35+
2. `$(npm root -g 2>/dev/null)/backlog.md/hooks/backlog-guard/` — global npm install
36+
3. `~/.bun/lib/node_modules/backlog.md/hooks/backlog-guard/` — bun global install
3337

34-
If none resolves, ask the user:
35-
> "I couldn't locate guard.sh automatically. Please provide the absolute path to
36-
> the guard.sh file from the backlog-guard hook."
38+
If neither resolves, ask the user:
39+
> "I couldn't locate the backlog-guard hook files automatically. Please provide the
40+
> absolute path to the `hooks/backlog-guard/` directory."
3741
3842
### 3. Create `.backlog-guard` config file
3943

@@ -51,24 +55,26 @@ Use the relative path from the git root for each directory.
5155
If the file already exists, read it first and merge new directories rather than
5256
overwriting. Confirm any changes with the user before writing.
5357
54-
### 4. Determine the settings target
58+
### 4. Claude Code — determine settings target
5559
5660
Ask:
57-
> "Should I add the hook to the project-local settings (`.claude/settings.local.json`)
58-
> or your user-global settings (`~/.claude/settings.json`)?
59-
> Project-local is recommended for backlog-specific repos."
61+
> "Should I add the Claude Code hook to the project-local settings
62+
> (`.claude/settings.local.json`) or your user-global settings
63+
> (`~/.claude/settings.json`)?
64+
> Project-local is recommended for backlog-specific repos; global applies to all
65+
> your projects."
6066

6167
Default: project-local.
6268

63-
### 5. Write the hook entry
69+
### 5. Claude Code — write the hook entry
6470

6571
Read the target settings file. If it does not exist, start with `{}`.
6672

6773
Merge the following into `hooks.PreToolUse` (append, do not replace existing entries):
6874

6975
```json
7076
{
71-
" "matcher": "Read|Edit|Write|Bash|Grep",",
77+
"matcher": "Read|Edit|Write|Bash|Grep",
7278
"hooks": [
7379
{
7480
"type": "command",
@@ -86,7 +92,7 @@ The hook discovers `.backlog-guard` automatically at runtime via `git rev-parse
8692
--show-toplevel`, so no path or environment variable needs to be embedded in the
8793
command string.
8894

89-
### 6. Offer to add MCP tool permissions
95+
### 6. Claude Code — offer to add MCP tool permissions
9096

9197
Ask:
9298
> "Should I also add `mcp__backlog__*` tool permissions to the settings allowlist?
@@ -121,20 +127,57 @@ If yes, merge the following into `permissions.allow` in the same settings file:
121127

122128
Deduplicate against any existing entries before writing.
123129

124-
### 7. Confirm and report
130+
### 7. OpenCode — install the plugin
131+
132+
Ask:
133+
> "Are you also using OpenCode in this project? If yes, should I install the
134+
> backlog-guard plugin globally (for all projects) or per-project only?"
135+
136+
**Global install** — symlink into OpenCode's global plugins directory:
137+
138+
```bash
139+
mkdir -p ~/.config/opencode/plugins
140+
ln -sf <absolute-path-to-opencode-plugin.js> ~/.config/opencode/plugins/backlog-guard.js
141+
```
142+
143+
OpenCode auto-loads all `.js` files in `~/.config/opencode/plugins/` — no config
144+
file changes needed.
145+
146+
**Per-project install** — add to `opencode.json` in the project root:
147+
148+
Read `opencode.json` (or start with `{"$schema":"https://opencode.ai/config.json"}`
149+
if missing). Merge the plugin path into the `plugin` array:
150+
151+
```json
152+
{
153+
"plugin": ["<absolute-or-relative-path-to-opencode-plugin.js>"]
154+
}
155+
```
156+
157+
Use a relative path (e.g. `./hooks/backlog-guard/opencode-plugin.js`) when running
158+
from the Backlog.md source tree; use an absolute path otherwise.
159+
160+
The plugin discovers `.backlog-guard` automatically at runtime — no additional config
161+
is needed in `opencode.json`.
162+
163+
### 8. Confirm and report
125164

126165
Show the user a summary of what was written:
127166
- Path of `.backlog-guard` and its contents
128-
- Target settings file and the hook entry added
129-
- MCP permissions added (if any)
167+
- Claude Code: target settings file and the hook entry added; MCP permissions added (if any)
168+
- OpenCode: plugin path symlinked or added to `opencode.json` (if applicable)
130169

131170
Remind the user:
132-
> "Reload Claude Code (or open a new session) for the hook to take effect."
171+
> "Reload Claude Code and/or OpenCode (or open a new session) for the changes to
172+
> take effect."
133173

134174
### Verification
135175

136-
To confirm the hook is active, ask Claude Code to:
176+
**Claude Code** — ask Claude to:
137177
```
138178
Read backlog/tasks/<any-task-file>.md
139179
```
140180
The hook should deny the request and suggest `mcp__backlog__task_view` instead.
181+
182+
**OpenCode** — attempt a read on a backlog file. The plugin should block it and
183+
display the task ID and MCP tool suggestion.

backlog/tasks/back-494 - Backlog-Guard-PreToolUse-hook-to-enforce-MCP-CLI-access-to-backlog-directories.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,30 @@ All 5 files created via Serena (serena-guard blocked direct Write on .sh/.py):
121121
Branch: feature/back-494-backlog-guard-hook
122122
Commit: 59308c6
123123
PR: https://github.com/MrLesk/Backlog.md/pull/649
124+
125+
### OpenCode support (added post-initial-implementation)
126+
127+
OpenCode does NOT have Claude Code-style declarative shell-script hooks. Verified
128+
against https://opencode.ai/docs. The equivalent mechanism is a JS plugin with a
129+
`tool.execute.before` handler that throws an Error to hard-block a tool call.
130+
131+
Added `hooks/backlog-guard/opencode-plugin.js`:
132+
- Mirrors check.py logic entirely in JavaScript (no external deps — YAML parsed
133+
with a targeted regex since the format is self-authored)
134+
- Config discovery uses the same 4-step order as check.py (git root → CWD walk →
135+
auto-detect → no-op)
136+
- Cache (`_cache` sentinel) avoids re-running `git rev-parse` + FS walk on every
137+
tool call within a long OpenCode session
138+
- Block method: `throw new Error(message)` vs check.py's JSON stdout protocol
139+
140+
Updated README.md and SKILL.md to cover both tools:
141+
- README: global/per-project install matrix for both Claude Code and OpenCode,
142+
mechanism comparison table
143+
- SKILL.md: added Steps 7–8 for OpenCode (global symlink to
144+
`~/.config/opencode/plugins/` or per-project `plugin` array in opencode.json)
145+
146+
Also added `opencode.json` at repo root for use when developing Backlog.md itself
147+
with OpenCode (MCP server + plugin wired up together).
124148
<!-- SECTION:NOTES:END -->
125149

126150
## Final Summary

0 commit comments

Comments
 (0)