Added git-manager, updated READMEs

This commit is contained in:
Henner M. Kruse
2026-08-04 10:45:25 +02:00
parent c774df7ad7
commit e485d33f00
13 changed files with 830 additions and 72 deletions
+137
View File
@@ -0,0 +1,137 @@
---
description: Set up the git-manager skill (permissions whitelist, optional anti-chaining hook)
argument-hint: [repo-name] [repo-path]
---
Set up the `git-manager` skill end to end. As part of the `git-manager`
plugin, this command is automatically namespaced by Claude Code and invoked
as `/git-manager:setup`. Follow these steps in order.
## 1. Determine the skill's install directory
This plugin's `skills/git-manager/` is a symlink into the repo's
tool-neutral `skills/git-manager/` directory (the single source of truth
for `SKILL.md` and `scripts/`, shared across all vendor adapters in this
repo). Resolve it to its real, absolute, symlink-free path:
```bash
realpath <plugin-dir>/skills/git-manager
```
This resolved path is `<SKILL_DIR>` for the rest of this setup.
## 2. Optionally register named repos
If `$ARGUMENTS` contains a repo name and path, or the user wants to
pre-register repos now (e.g. an Obsidian vault repo used alongside a code
repo), write/merge them into
`~/.agent-skills/git-manager/config.json`:
```bash
mkdir -p ~/.agent-skills/git-manager
cat > ~/.agent-skills/git-manager/config.json << 'EOF'
{
"repos": [
{"name": "<short-name>", "path": "<absolute-repo-path>"}
]
}
EOF
```
If the file already exists, merge new entries in rather than overwriting.
This step is entirely optional — the skill works without any named repos,
operating on the current working directory by default.
## 3. Generate and merge the minimal permissions whitelist
Exactly one command needs whitelisting — everything else about this skill's
safety comes from the wrapper script's own subcommand allowlist and repo
resolution, not from a long list of Bash rules:
- `Bash(<SKILL_DIR>/scripts/git_cmd.sh:*)`
- `Read(~/.agent-skills/git-manager/config.json)`
Steps:
1. Locate the target settings file: prefer the project-level
`.claude/settings.json` if a project is open, otherwise the user-level
`~/.claude/settings.json`. Ask the user which one they want if unclear —
note that if they work across many separate git repos/projects, the
user-level file avoids repeating this setup per project.
2. If the target file doesn't exist yet, create it containing just these
two entries under `permissions.allow`.
3. If it exists, read it first and merge: add only entries not already
present. Don't duplicate, don't remove or overwrite unrelated existing
permissions.
4. Show the user exactly what was added before writing.
Do **not** whitelist a generic `Bash(git:*)` or anything targeting `cd`.
Do **not** whitelist writing to the config file — that keeps prompting for
confirmation, so registering a new repo is always a visible, confirmed
action.
## 4. Offer the anti-chaining hook
Explain to the user: this hook never silently blocks and never silently
allows anything. It only ever forces the *normal* confirmation prompt
(`permissionDecision: "ask"`) when a Bash command contains shell chaining
or substitution operators (`&&`, `;`, `|`, backticks, `$(...)`). This exists
because Claude Code's own Bash allow-list matching has had bugs where
compound commands either bypass per-command checks entirely, or where a
chain of individually-allowed commands still isn't recognized as such — see
`hooks/force-ask-on-chaining.sh` for the reasoning and a link to the
relevant upstream issue. With this hook installed, if a chained command
ever gets constructed anyway (it shouldn't, since `git_cmd.sh` removes the
need for `cd`/chaining), the user will always see a normal approval prompt
for it rather than it silently going through or silently failing.
Ask the user whether to install it. If yes:
1. Locate `hooks/force-ask-on-chaining.sh` next to this plugin's
`plugin.json` and note its absolute path, `<HOOK_PATH>`.
2. Ensure it's executable: `chmod +x <HOOK_PATH>`.
3. Merge this into the same settings file chosen in step 3 (project or
user-level — ask if unclear, but note this hook is most useful applied
broadly at the user level, since it's about Bash hygiene in general, not
specific to git):
```json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "<HOOK_PATH>"
}
]
}
]
}
}
```
Merge into any existing `hooks.PreToolUse` array rather than overwriting it
— don't remove other existing PreToolUse hooks for the `Bash` matcher or
other matchers.
If the user declines, skip this step entirely; the whitelist from step 3
still works on its own, it just doesn't have this extra safety net.
## 5. Make the wrapper script executable
```bash
chmod +x <SKILL_DIR>/scripts/git_cmd.sh
```
## 6. Confirm and offer a test run
Summarize to the user:
- Any repos registered in step 2
- The exact permission entries added, and where
- Whether the anti-chaining hook was installed, and where
Then offer to run `<SKILL_DIR>/scripts/git_cmd.sh status` (against the
current directory, or a registered repo) as a quick sanity check.