# Installation

> Install paths for npx install/link/update, plugin install, submodule link, provider selection, scope (project vs global), and hook consent constraints.

- Repository: pbakaus/impeccable
- GitHub: https://github.com/pbakaus/impeccable
- Human docs: https://grok-wiki.com/public/docs/pbakaus-impeccable-adadc04d8de4
- Complete Markdown: https://grok-wiki.com/public/docs/pbakaus-impeccable-adadc04d8de4/llms-full.txt

## Source Files

- `cli/bin/cli.js`
- `cli/bin/commands/skills.mjs`
- `README.md`
- `README.npm.md`
- `docs/HARNESSES.md`
- `plugin/hooks/hooks.json`
- `.claude-plugin/plugin.json`

---

---
title: "Installation"
description: "Install paths for npx install/link/update, plugin install, submodule link, provider selection, scope (project vs global), and hook consent constraints."
---

Impeccable installs as provider-compiled skill trees plus optional design-hook manifests. The CLI entrypoints are `npx impeccable install`, `link`, `update`, and `check` (also under the legacy `skills` namespace). The installer downloads the universal bundle from `https://impeccable.style/api/download/bundle/universal` and copies per-provider skill variants into harness folders such as `.claude/skills/` or `~/.claude/skills/`.

## Prerequisites

| Requirement | Detail |
|-------------|--------|
| Node.js | `>=22.18.0` (`package.json` `engines`) |
| Network | Needed for `install` / `update` / `check` unless `IMPECCABLE_BUNDLE_PATH` points at a local zip or directory |
| Project root | CLI walks up from `cwd` to the nearest `.git`; falls back to `cwd` when none exists |
| AI harness | Cursor, Claude Code, Gemini CLI, Codex CLI, Grok Build, GitHub Copilot, OpenCode, Pi, Kiro, Qoder, Trae, Trae CN, Rovo Dev, Mistral Vibe, or Antigravity |

Detector-only use (`npx impeccable detect`) does not require a skill install. Live mode, the design hook, and `/impeccable` commands need the skill payload in a harness the agent can load.

## Choose an install path

| Path | When to use | Writes skills | Writes hooks |
|------|-------------|---------------|--------------|
| CLI `install` | Default; project or global | Copy from universal bundle | Claude, Cursor, Codex, GitHub Copilot, Grok (when consented) |
| CLI `link` | Git submodule / local checkout | Symlinks into project harness dirs | No |
| Claude plugin marketplace | Claude Code only | Plugin-managed skill tree | Plugin `hooks.json` via `${CLAUDE_PLUGIN_ROOT}` |
| Grok plugin | Grok Build only | Slim `plugin/` package | `plugin/hooks/hooks.json` |
| Website ZIP / manual `cp` | Offline or custom layout | Manual | Manual (hooks optional) |

Recommended default:

```bash
npx impeccable install
```

Then reload the harness and run `/impeccable init` inside the agent session.

## CLI install (recommended)

### Commands

| Command | Role |
|---------|------|
| `npx impeccable install` | Download universal bundle; copy provider skill variants; optionally install hook manifests |
| `npx impeccable update` | Refresh existing copy installs from the same bundle API |
| `npx impeccable check` | Report whether installed skills match the remote bundle |
| `npx impeccable link` | Symlink skills from a local checkout (`dist/universal` or provider trees) |
| `npx impeccable help` | List skill commands (fetches catalog from impeccable.style) |

Legacy namespace still works: `npx impeccable skills install|link|update|check|help`. Top-level aliases route through the same handler.

### Flags

<ParamField body="--providers" type="string">
Comma-separated harness aliases (e.g. `claude,codex,cursor,grok`). Folder names like `.claude` are also accepted. Unknown names fail the install.
</ParamField>

<ParamField body="--scope" type="project | global">
Install root. Aliases: `project`/`local`/`repo`/`p` → project; `global`/`user`/`home`/`u` → user home. Also `--project`, `--local`, `--user`, `--home`, `--global`, and `--install-scope=`.
</ParamField>

<ParamField body="-y, --yes" type="boolean">
Non-interactive. With no `--providers`, uses detection or defaults (`.claude` + `.agents`). With no scope flag, installs **project** scope.
</ParamField>

<ParamField body="--no-hooks" type="boolean">
Skip hook manifests for this run only. Does **not** record a consent decision.
</ParamField>

<ParamField body="--force" type="boolean">
Reinstall skills when already present; replace malformed hook JSON after writing a `.bak`; for `link`, replace existing real skill dirs with symlinks.
</ParamField>

<ParamField body="--source" type="string">
`link` only. Checkout root (default `.impeccable`). Expects `dist/universal/` or provider skill folders at the root.
</ParamField>

### Interactive flow

Without `-y`, `install`:

1. Prints detected harnesses (project folders and global hints such as `~/.claude`, `~/.codex` → `.agents`, OpenCode config dir, Pi `~/.pi/agent/skills`).
2. Offers **Detected only** vs **Customize** provider multi-select.
3. Asks **Project** vs **Global** install location (default prefers project when project harness dirs exist).
4. Offers the design hook once (default yes) when consent is unset and hooks are not already present.
5. Downloads the universal bundle, copies per-provider skill trees (never a single shared symlink across providers), copies supported agents, and merges hook manifests when accepted.

### Non-interactive examples

<CodeGroup>
```bash title="Project install, Claude + Codex + Cursor"
npx impeccable install -y --providers=claude,codex,cursor --scope=project
```

```bash title="Global install, no hooks"
npx impeccable install -y --providers=claude,grok --scope=global --no-hooks
```

```bash title="Update project install"
npx impeccable update -y --project
```

```bash title="Update user-level install"
npx impeccable update -y --user
```
</CodeGroup>

### What gets written

**Project scope** (default): `<repo>/<provider>/skills/impeccable/` (and sibling skills from the bundle).  
**User (global) scope**: provider home layout, with overrides:

| Provider dir | Global skills path |
|--------------|--------------------|
| Most providers | `~/<provider>/skills/` |
| `.pi` | `~/.pi/agent/skills/` |
| `.opencode` | `$OPENCODE_CONFIG_DIR` or `$XDG_CONFIG_HOME/opencode` or `~/.config/opencode` → `skills/` |
| `.agent` (Antigravity) | `~/.gemini/config/skills/` |

Project scope always uses `<provider>/skills` under the project root, including for Pi / OpenCode / Antigravity.

**Hook manifests** (when hooks install) always target the **project** root (`hookRoot`), even if skills were installed globally:

| Provider | Destination | Skill script |
|----------|-------------|--------------|
| Claude Code | `.claude/settings.local.json` (from bundle `settings.json`) | `${CLAUDE_PROJECT_DIR}/.claude/skills/impeccable/scripts/hook.mjs` |
| Cursor | `.cursor/hooks.json` | `hook-before-edit.mjs` (blocks bad writes) |
| Codex | `.codex/hooks.json` (skill lives under `.agents`) | `.agents/skills/impeccable/scripts/hook.mjs` |
| GitHub Copilot | `.github/hooks/impeccable.json` | `.github/skills/impeccable/scripts/hook.mjs` |
| Grok Build | `.grok/hooks/impeccable.json` | PostToolUse + Stop deep pass |

Other harnesses get skills only; no documented hook surface.

**Native agents** (when present in the bundle): GitHub Copilot → `.github/agents/` or `~/.copilot/agents/`; Cursor → `.cursor/agents/` or `~/.cursor/agents/`. User-level Copilot agents can shadow project copies; the CLI warns when that happens.

### Bundle source

```text
https://impeccable.style/api/download/bundle/universal
```

Override for offline/CI:

```bash
IMPECCABLE_BUNDLE_PATH=/path/to/universal.zip npx impeccable install -y --providers=claude
# or a directory that already contains the extracted universal layout
```

Install deliberately copies per-provider compiled variants. It does not shell out to `npx skills add`, which can install uncompiled source or symlink every harness at one shared tree.

### Update and check

- `update` refreshes only trees that contain an `impeccable` (or legacy prefixed) skill, not arbitrary skills under the same folder.
- Linked installs are left alone: update the submodule (or source checkout), then rerun `link`.
- If both project and user installs exist and no scope is given, interactive update asks which; non-interactive (`-y`) defaults to **project** and prints how to target `--user`.
- `check` compares installed file hashes to the remote bundle after path normalization.

### Force and failure modes

| Situation | Behavior |
|-----------|----------|
| Skills already installed, no `--force` | May refresh outdated copies / missing hooks; otherwise reports up to date |
| Empty provider list after resolution | Exit 1; pass `--providers=...` |
| Bundle has no variants for targets | Exit 1: nothing installed |
| Malformed existing hook JSON | Aborts unless `--force` (backs up to `.bak`) |
| Download failure | Exit 1 with HTTP/message |
| Prompt abort | Exit 130 |

## Provider aliases

Pass any of these to `--providers=` (or the interactive selector):

| Input | Folder | Display name |
|-------|--------|--------------|
| `claude`, `claude-code` | `.claude` | Claude Code |
| `codex` | `.agents` | Codex CLI |
| `cursor` | `.cursor` | Cursor |
| `gemini` | `.gemini` | Gemini CLI |
| `github`, `copilot` | `.github` | GitHub Copilot |
| `grok`, `grok-build`, `xai` | `.grok` | Grok Build |
| `antigravity`, `agent` | `.agent` | Antigravity |
| `opencode` | `.opencode` | OpenCode |
| `pi` | `.pi` | Pi Coding Agent |
| `kiro` | `.kiro` | Kiro |
| `qoder` | `.qoder` | Qoder |
| `trae` / `trae-cn` | `.trae` / `.trae-cn` | Trae / Trae CN |
| `rovo-dev`, `rovodev` | `.rovodev` | Rovo Dev |
| `vibe` | `.vibe` | Mistral Vibe |
| `agents` | `.agents` | Codex / universal |

Detection order when `--providers` is omitted: project harness folders → global harness hints → default `[.claude, .agents]`.

## Scope: project vs global

```text
                    --scope=project (default for -y)
                    ┌─────────────────────────────┐
  repo root ───────►│ .<provider>/skills/…        │
                    │ hook manifests (project)    │
                    └─────────────────────────────┘

                    --scope=global | user | home
                    ┌─────────────────────────────┐
  $HOME ───────────►│ user skills layout (table)  │
                    │ hooks still under project   │
                    └─────────────────────────────┘
```

- Project skills are shareable in git when committed (team harness folders).
- Global skills apply across repos for that developer.
- Design hooks stay project-local so they only run where the repo is trusted.
- OpenCode global must use the config dir (`OPENCODE_CONFIG_DIR` / XDG / `~/.config/opencode`); writing only to `~/.opencode/skills` is not discoverable by OpenCode.

## Hook consent

Hook install is gated by `decideHookInstall`:

| Condition | Result |
|-----------|--------|
| `--no-hooks` | Skip this run; **no** consent written |
| `hook.consent` = `declined` in config | Skip; no prompt |
| `hook.consent` = `accepted` | Install/merge hooks |
| Hook already present for all selected providers | Treat as accepted; no prompt |
| Interactive, undecided | Explainer + `Install the design hook? (Y/n)` (default yes); write consent |
| Non-interactive (`-y` or no TTY), undecided | Install hooks (historical default); **do not** record consent |

Consent is stored under `.impeccable/config.local.json` as `hook.consent`: `"accepted"` | `"declined"`. Local config overrides shared `.impeccable/config.json`. The CLI best-effort gitignores `config.local.json` via `.git/info/exclude`.

Lifecycle knobs (quiet, disable, audit log) live under the shared `hook` key in config; see configuration reference. Change later with `/impeccable hooks on|off` inside a session that has the skill loaded.

### Provider trust after install

| Harness | Extra step |
|---------|------------|
| Codex | Open `/hooks` and approve after install/update; definition changes re-require approval; hooks disabled on Windows |
| Grok Build | Folder trust: `/hooks-trust` or launch with `--trust` |
| GitHub Copilot | Commit hook file on default branch; folder trust as required by Copilot |
| Cursor | Reload/restart if hooks do not pick up; enable Agent Skills (Nightly) as required by Cursor |
| Claude Code | Machine-local `settings.local.json`; no marketplace trust step for CLI-installed hooks |

Claude / Codex / Copilot / Grok: post-edit findings (Stop deep pass where supported). Cursor: pre-write block via `hook-before-edit.mjs`.

## Plugin install

### Claude Code marketplace

```bash
/plugin marketplace add pbakaus/impeccable
```

Then open `/plugin` and install **impeccable**. Marketplace metadata lives in `.claude-plugin/marketplace.json` with `source: "./plugin"`. The slim package under `plugin/` includes skills, agents, and `plugin/hooks/hooks.json` (commands use `${CLAUDE_PLUGIN_ROOT}`).

### Grok Build plugin

```bash
grok plugin install pbakaus/impeccable#plugin --trust
```

The `#plugin` fragment installs the slim package (not the full monorepo). Project CLI install remains valid:

```bash
npx impeccable install --providers=grok
```

That writes `.grok/skills/` and `.grok/hooks/impeccable.json`.

Plugin installs do not replace the detector CLI; use `npx impeccable detect` from the npm package separately when needed.

## Git submodule + link

```bash
git submodule add https://github.com/pbakaus/impeccable .impeccable
npx impeccable link --source=.impeccable --providers=claude,cursor
git add .gitmodules .impeccable .claude .cursor
git commit -m "Add Impeccable skills"
```

`link` resolves:

1. `<source>/dist/universal/` if present, else  
2. provider skill folders directly under `<source>`.

Behavior:

- Creates relative directory symlinks per skill under `<provider>/skills/<name>`.
- Skips existing non-matching paths unless `--force`.
- Does not install hooks; run `install`/`update` with hooks if needed, or configure manifests manually.
- Refresh: `git submodule update --remote .impeccable` then rerun `link`.

## Manual and website installs

- **Website:** download a provider ZIP from [impeccable.style](https://impeccable.style) and extract into the project.
- **From a built checkout:** copy the matching tree under `dist/<provider>/` (for example `dist/claude-code/.claude`, `dist/agents/.agents`, `dist/github/.github`).

Provider-specific enablement notes (Cursor Nightly + Agent Skills, Gemini CLI Skills setting, Trae dual config dirs, etc.) are documented in the repository README and harness matrix. Prefer `npx impeccable install` so hooks and per-provider variants stay consistent.

## Verify installation

<Steps>
<Step title="Confirm skill on disk">
Check for `impeccable/SKILL.md` under the expected skills dir, e.g. `.claude/skills/impeccable/SKILL.md` or `~/.claude/skills/impeccable/SKILL.md`.
</Step>
<Step title="Reload the harness">
Restart or reload the AI tool so it rediscovers skills and hooks.
</Step>
<Step title="Run setup in-session">
```text
/impeccable init
```
</Step>
<Step title="Optional: CLI health">
```bash
npx impeccable check
npx impeccable detect --help
```
</Step>
</Steps>

Expected post-install CLI message pattern: `Installed impeccable into: … (project|global)` and `Done! Run /impeccable init…`.

## Troubleshooting

| Symptom | Fix |
|---------|-----|
| Skills missing in OpenCode global | Install with `--scope=global --providers=opencode`; confirm path under config dir, not only `~/.opencode/skills` |
| Codex hook never runs | Approve under `/hooks`; confirm Windows is not in use for hooks |
| Grok hooks silent | Run `/hooks-trust` or start with `--trust` |
| Cursor skills invisible | Nightly channel + enable Agent Skills |
| Install says already installed | `npx impeccable update` or `install --force` |
| Link skipped existing dirs | `npx impeccable link --force --source=…` |
| Offline install | Set `IMPECCABLE_BUNDLE_PATH` to a local universal zip/dir |
| Node too old for hooks | Hooks require Node 22+ on PATH; skill text may still load without the hook |

## Next

<CardGroup>
<Card title="Quickstart" href="/quickstart">
First successful session: init, context load, a scoped design command, optional detect.
</Card>
<Card title="Provider harnesses" href="/provider-harnesses">
Harness folders, frontmatter matrix, and provider trust steps.
</Card>
<Card title="Design hook" href="/design-hook">
Hook behavior, quiet/disable controls, and native-platform skip.
</Card>
<Card title="CLI reference" href="/cli-reference">
Full flags, exit codes, detect shorthand, and ignores.
</Card>
<Card title="Plugin agents" href="/plugin-agents">
Bundled agents and plugin manifest contract for Claude and Grok.
</Card>
</CardGroup>
