Files
skill-repo/vendor/claude-code/plugins/git-manager/commands/setup.md
T
Henner M. Kruse 1d0b66df2e Add opt-in raw-git nudge hook, independent of anti-chaining hook
Forces a normal confirmation prompt (never a silent block, never a silent
allow) when Bash runs raw git instead of git_cmd.sh, worded more
insistently when the subcommand is one the wrapper already supports.
Raw git stays a valid fallback for unsupported subcommands and
unregistered repos - a hard deny would remove that fallback entirely.

Also documents in SKILL.md that repo ambiguity (which registered repo is
meant, or none at all) must be resolved by asking the user rather than
guessing - a hook only sees the literal command string, not the
conversation, so that judgment can't live in the hook itself.
2026-08-04 13:58:30 +00:00

109 lines
5.4 KiB
Markdown

---
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. As part of the `git-manager` plugin, this
command is automatically namespaced by Claude Code and invoked as
`/git-manager:setup`.
Almost everything about this setup — reading/writing the skill's config,
merging permissions and the hook into settings.json, setting executable
bits — happens inside one bundled script, `scripts/setup.sh`, which you run
as a **single** Bash call. That script also copies the wrapper script(s) it
needs to a stable, self-controlled location
(`~/.agent-skills/git-manager/bin/`) before writing any permissions, so the
permission rule never has to change again across future plugin updates —
only this first run (and, optionally, a re-run after a plugin update) needs
to locate the plugin itself.
## 1. Ask the user — three selectable questions first, repo path last
**1a. First turn: four questions via the selection UI, fixed options for
all four:**
- Whether to register any repos at all: yes/no.
- Settings scope: `project` (`.claude/settings.json` in the current
project) or `user` (`~/.claude/settings.json`). Mention: if they work
across many separate repos/projects, `user` avoids repeating setup per
project.
- Anti-chaining hook: yes/no, after explaining it never silently blocks or
silently allows anything, it only forces the *normal* confirmation
prompt when a Bash command contains shell chaining operators (`&&`, `;`,
`|`, backticks, `$(...)`), as a safety net given Claude Code's Bash
allow-list matching has had bugs around compound commands (see
`hooks/force-ask-on-chaining.sh` for details).
- Ask-before-raw-git hook: yes/no, after explaining it never silently
blocks or silently allows anything either — it only forces the normal
confirmation prompt when a Bash command runs raw `git` instead of the
`git_cmd.sh` wrapper. It never fully blocks raw git (that stays a valid
fallback for subcommands the wrapper deliberately doesn't support, e.g.
`stash`/`merge`/`rebase`/`reset`, or for repos that aren't registered
yet) — it just makes sure raw git use is always a visible, confirmed
choice rather than something that slips through unnoticed (see
`hooks/force-ask-on-raw-git.sh` for details). Independent of the
anti-chaining hook — either, both, or neither can be installed.
**1b. Only if the answer to "register any repos" was yes: a second turn,
plain chat message, no tool call.** Ask exactly: "Which repos should
git-manager know about? Provide as `name=path` pairs." End your turn right
after asking this, with nothing else queued up, so the user's reply is
what actually gets collected before you continue. (Only a tool call
reliably pauses for a reply in this environment; plain text followed
immediately by a tool call in the same turn does not wait — that's what
caused this question to appear skipped in an earlier version of this
command.) If the answer to "register any repos" was no, skip this
sub-step entirely — don't ask it at all.
## 2. Run the setup script — one command
Claude Code installs plugins added from a local marketplace at
`~/.claude/plugins/cache/<marketplace-name>/<plugin-name>/<plugin-version>/`.
For this repo's marketplace (`skill-repo`) and this plugin's current
version (`1.0.0` — check this plugin's own `.claude-plugin/plugin.json` if
this has since changed), that's:
```bash
~/.claude/plugins/cache/skill-repo/git-manager/1.0.0/scripts/setup.sh \
--settings-scope <project|user> \
[--project-dir <path>] \
[--repo <name>=<path> ...] \
[--install-hook] \
[--install-raw-git-hook]
```
Include `--repo name=path` once per repo from step 1, `--install-hook` and
`--install-raw-git-hook` only for the ones the user opted into (they're
independent flags), and `--project-dir` only if `--settings-scope
project` and the project isn't the current working directory. Try this
path directly first — don't `find`/`ls` preemptively.
If that exact path doesn't exist (installed version differs from `1.0.0`,
differently named marketplace, or a future Claude Code cache layout
change), fall back to exactly one bounded lookup instead of guessing
further:
```bash
find ~/.claude/plugins/cache/skill-repo/git-manager -maxdepth 2 -type d 2>/dev/null
```
and construct the same `scripts/setup.sh` call using whatever version
directory that reveals. This is expected to prompt for approval the first
time — there's no way to pre-whitelist it before the setup that establishes
the whitelist has run.
## 3. Relay the result
The script prints a JSON summary (stable script location, settings file
written, config file, whether the hook was installed, repos registered,
the exact permission rules added, and a note about session reload).
Present that summary to the user in plain language — don't re-read any of
those files yourself to "double check"; the script's own output already
reflects exactly what's on disk.
Do **not** follow this with a test invocation of `git_cmd.sh` — Claude Code
loads permissions at session start and doesn't always pick up changes made
by its own file edits within the same session, so an immediate test can
prompt (or not) in a way that doesn't reliably indicate success either way.
If a real command later still prompts, the fix is a fresh session, not
re-running this setup — the configuration is already correctly saved.