Why use it: add the skill /impeccable + design hook to your project's AI harness, in exactly the scope you want (project, not machine).
What it generates: skill directories in the provider dirs (.claude/skills/impeccable/, .cursor/skills/impeccable/, ...), agent file impeccable-*.md, and optionally a hook manifest.
⚠️ Read first: the two traps of install
Trap 1 — install --help does not print help, it actually installs
The version currently published on npm (impeccable@3.6.1) does not have the branch handling --help for the subcommand. The router only recognizes install and then runs it immediately:
// cli/bin/commands/skills.mjs (bản npm 3.6.1) — không hề có SUBCOMMAND_HELP
} else if (sub === 'install') {
await install(args.slice(1));
The branch SUBCOMMAND_HELP (actually prints help) exists in git main but has not been published — both sides carry the number 3.6.1 but with different contents.
# ĐỪNG gõ cái này: nó cài thật, không in help
npx impeccable install --help
Trap 2 — without a TTY the default is global, not project
// cli/bin/commands/skills.mjs:1169-1180
if (yes) return 'project';
...
const answer = await ask(`Install location: project (...) or global (...)? [${fallback === 'user' ? 'global' : fallback}] `);
if (!answer) return fallback; // stdin EOF ⇒ nhận fallback
In a script / CI / agent (stdin is not a TTY), ask() receives an empty string and falls back to defaultInstallScope(). On a machine that already has ~/.claude, ~/.cursor... the fallback is global, and Impeccable writes into 13 directories in $HOME.
Safety rule: in every non-interactive context, always explicitly declare all three things:
npx impeccable install -y --scope=project --providers=claude
Path 1 — CLI installer (recommended)
cd /đường/dẫn/dự-án
npx impeccable install -y --scope=project --providers=claude,cursor
Actual output (run with --providers=claude --no-hooks):
Downloading impeccable skills...
Installed impeccable into: .claude (project)
Installed Claude Code agents into: <project>/.claude/agents
Done! Now type /impeccable init in your AI coding agent's chat (not in this terminal) to set up design context.
Result: 168 files under .claude/ — SKILL.md, scripts/ (~50 scripts .mjs), reference/ (documentation for each command), and 4 agent files.
Flags worth remembering (read from SUBCOMMAND_HELP in git main, all of them are install() accepted by the npm version):
| Flag | Effect |
|---|---|
-y, --yes |
Accepts the default, forces the scope to project |
--scope=project|global |
Choose the scope explicitly |
--project / --user / --global |
Short form of --scope |
--providers=<tên,tên> |
claude, cursor, codex, gemini, grok, hermes, github, opencode, pi, kiro, qoder, trae, trae-cn, rovo-dev, vibe, veto, antigravity |
--no-hooks |
Do not install the provider's hook manifest |
--force |
Overwrite an existing installation |
Requires network: the skill bundle is downloaded from
https://impeccable.style, it is not in the npm tarball.
Path 2 — Git submodule (vendor, updated via git)
git submodule add https://github.com/pbakaus/impeccable .impeccable
npx impeccable link --source=.impeccable --providers=claude,cursor
git add .gitmodules .impeccable .claude .cursor
link creates a symlink from .impeccable/dist/universal/ to the provider's skill directory; a real skill directory that already exists is kept as is unless there is --force.
Update:
git submodule update --remote .impeccable
npx impeccable link --source=.impeccable --providers=claude,cursor
Path 3 — Plugin (Claude Code / Grok Build only)
# Claude Code — sau đó mở /plugin và chọn Impeccable trong danh sách
/plugin marketplace add pbakaus/impeccable
# Grok Build
grok plugin install pbakaus/impeccable#plugin --trust
Check and update
npx impeccable check # rc 0
npx impeccable update -y --scope=project
check prints the version of skill bundle, different from the CLI version:
Checking for updates...
Skills are up to date (v4.1.3).
The two version lines are independent of each other:
| Item | Version | Source |
|---|---|---|
CLI (npx impeccable) |
3.6.1 | npm |
Bundle skill (SKILL.md, scripts) |
4.1.3 | downloaded from impeccable.style |
update --helphits exactly trap 1 likeinstall --help. Don't type; useupdate -y --scope=project.
Hook: what gets written where
install/update (when there is no --no-hooks) write the hook manifest per provider:
| Harness | File | Script run |
|---|---|---|
| Claude Code | .claude/settings.local.json (gitignored) |
.claude/skills/impeccable/scripts/hook.mjs |
| Cursor | .cursor/hooks.json |
.cursor/skills/impeccable/scripts/hook-before-edit.mjs |
| Codex | .codex/hooks.json |
.agents/skills/impeccable/scripts/hook.mjs |
| GitHub Copilot | .github/hooks/impeccable.json |
.github/skills/impeccable/scripts/hook.mjs |
| Grok Build | .grok/hooks/impeccable.json |
.grok/skills/impeccable/scripts/hook.mjs |
Mandatory manual steps per harness:
- Codex: open
/hooksafter installing/updating and then approve the project's hook. Codex tracks trust by hook content, so every time.codex/hooks.jsonchanges you must re-approve. - Grok Build: requires folder trust (
/hooks-trustor run with--trust).
Enable/disable hooks after installing (no need to reinstall):
node .claude/skills/impeccable/scripts/hook-admin.mjs status
node .claude/skills/impeccable/scripts/hook-admin.mjs off
node .claude/skills/impeccable/scripts/hook-admin.mjs on
node .claude/skills/impeccable/scripts/hook-admin.mjs reset # xoá toàn bộ config + cache
.gitignore: what to commit, what to skip
Impeccable writes working files under .impeccable/. Commit those files that are shared project artifacts:
.impeccable/config.json— shared config (detector ignores, hook).impeccable/live/config.json— wiring for live mode with the framework.impeccable/design.json— shared design spec.impeccable/surfaces/*.md,.impeccable/critique/*.md
Skip temporary and per-dev parts — paste this block into .gitignore of the project (patterns intentionally not anchored at line start, because in a monorepo .impeccable/ is usually under apps/web/):
# impeccable-ignore-start
.impeccable/config.local.json
.impeccable/hook.cache.json
.impeccable/hook.pending.json
.impeccable/*.png
.impeccable/review/
.impeccable/questions/
.impeccable/live/server.json
.impeccable/live/sessions/
.impeccable/live/previews/
.impeccable/live/annotations/
.impeccable/live/cache/
.impeccable/live/manual-edit-apply-transaction.json
.impeccable/live/manual-edit-events.jsonl
.impeccable/live/manual-edit-evidence/
.impeccable/live/pending-manual-edits.json
.impeccable/live/deferred-svelte-component-accepts.json
.impeccable/live/*.png
# impeccable-ignore-end
Clean removal (even if you accidentally installed globally)
There is no uninstallcommand. Remove manually — these are all the targets that install --scope=global can touch:
# skill (13 provider)
rm -rf ~/.claude/skills/impeccable ~/.cursor/skills/impeccable ~/.agents/skills/impeccable \
~/.gemini/skills/impeccable ~/.gemini/config/skills/impeccable ~/.grok/skills/impeccable \
~/.hermes/skills/impeccable ~/.kiro/skills/impeccable ~/.qoder/skills/impeccable \
~/.rovodev/skills/impeccable ~/.vibe/skills/impeccable ~/.pi/agent/skills/impeccable \
~/.config/opencode/skills/impeccable
# agent
rm -f ~/.claude/agents/impeccable-*.md ~/.cursor/agents/impeccable-*.md
Check again before deleting (list everything named impeccable in home, with mtime to know which were just created):
python3 - <<'PY'
import os, glob, time
home = os.path.expanduser('~')
for d in sorted(os.listdir(home)):
base = os.path.join(home, d)
if not (d.startswith('.') and os.path.isdir(base)): continue
for pat in ('skills/impeccable*', 'config/skills/impeccable*', 'agent/skills/impeccable*', 'agents/impeccable-*'):
for p in glob.glob(os.path.join(base, pat)):
print(time.strftime('%Y-%m-%d %H:%M', time.localtime(os.stat(p).st_mtime)), p)
PY
For a project-scope install you only need to delete .claude/skills/impeccable, .claude/agents/impeccable-*.md and the corresponding hook manifest.
Note on global scope: if $OPENCODE_CONFIG_DIR is set (Orca sets this variable), OpenCode is detected via that path rather than ~/.opencode — see cli/bin/commands/skills.mjs:80-84. This same mechanism breaks contributors' test suite, see 06.
Next steps
Once installed, open the AI agent and type /impeccable init in chat — not in the terminal. Typing npx impeccable init will be intentionally blocked:
"init" is not a CLI command. Type /impeccable init in your AI coding agent's chat (Claude Code, Cursor, Codex, ...), not in this terminal.
(rc = 1). Details on init and the 23 chat commands: see 05-chat-commands.md.