@npabisz/claude-setup
v0.1.0
Published
Interactive installer for curated ECC skills, rules, agents and commands into a project's .claude/ directory
Readme
@npabisz/claude-setup
Interactive terminal UI that installs a curated subset of ECC
(skills, rules, agents, commands) into a project's .claude/ directory, based on what you are building.
Instead of ECC's all-or-nothing modules, you get only the pieces that match your stack
(e.g. Laravel → PHP rules, laravel-* skills, PHP reviewer agent), plus a lock file so the
install can be updated later.
Install
npx @npabisz/claude-setup # run once without installing (in a new or existing project)
npm install -g @npabisz/claude-setup # or install; the command is `claude-setup`The unscoped npm package
claude-setupis a different, unrelated tool:npx claude-setupruns that one. With npx always use the scoped name, e.g.npx @npabisz/claude-setup update.
Working on this repo: npm run build && npm link makes claude-setup point at your local build.
Usage
# in a new or existing project
claude-setup- Existing files (only shown when found): ECC files the project already has — copied by hand, installed by ECC's own installer, or from an older ECC layout — are recognised and taken over. See Existing projects.
- Stack: the presets detected from
composer.json,package.json,Cargo.toml,go.mod,pyproject.toml, compose files,.env.example, … are pre-ticked. Toggle stacks and extras. - Items: fine-tune individual skills, rules, agents and commands (tabs,
/filter,sselected only). The right panel shows what each item is, why it's selected, and its files. - Review: see what will be written. Items that already exist with different content are kept unless you mark them to overwrite.
Non-interactive:
claude-setup --yes # core + detected presets
claude-setup --yes --preset laravel,docker # explicit presets (core is always added unless --no-core)
claude-setup --yes --add skill:redis-patterns --remove command:aside --dry-run
claude-setup --yes --hooks minimal # also install ECC hooks
claude-setup presets # list presetsOther options: --ref v2.2.3 (pin an ECC release, default latest), --ecc-dir <path> (use a local
ECC checkout), --cwd <dir>, --overwrite. See claude-setup --help.
Existing projects
init checks .claude/{skills,rules,agents,commands} against ECC's full git history (a small,
contents-free clone cached in ~/.cache/claude-setup/ecc/history.git):
- Unedited copies are matched exactly, at any version and in any place (also renamed dirs or
rules copied ECC-README style to
.claude/rules/<lang>/), and simply updated to the new release. - Edited copies (same name, similar content) are compared with every historical version; the closest one (released versions win ties) becomes the merge base, so your edits are merged with ECC's changes, and overlapping edits become conflicts you decide on (with a diff).
- Files outside claude-setup's layout are moved into it (e.g.
.claude/rules/php/→.claude/rules/ecc/php/). - Everything else is your own and never touched. You can also leave any found item alone.
- Safeguards against false matches: edited copies need ≥ 80% similarity over meaningful lines (blank
lines and markup don't count) and the same frontmatter
name; exact copies found elsewhere must keep their file name and be more than tiny. Everything is checked again right before writing; moves are undone if one fails. - Non-interactive (
--yes): unedited copies are taken over automatically, edited ones only with--adopt-edited(their merge would otherwise happen unreviewed).--overwriteonly replaces unrecognised files, never adopted copies.
Updating
claude-setup update # interactive review
claude-setup update --yes --dry-run # just show what would change
claude-setup update --yes --conflicts keep # non-interactive (keep | theirs | markers)update compares three versions of every installed file: your copy, the release recorded in the
lock, and the new release (latest, or --ref).
| Your copy | ECC | Result |
|-----------|------------|-------------------------------------------------------------------------|
| untouched | changed | updated |
| edited | unchanged | your edits stay |
| edited | changed | 3-way merged (git merge-file); overlapping edits are a conflict: keep mine / take ECC / write conflict markers |
| deleted | – | drop it from the selection, or restore it |
| – | removed / deselected | deleted if untouched; edited files are kept (untracked) unless you choose delete |
Newly selected items (or items a preset now includes) are added. In the TUI, d shows a diff of
any item and e lets you change the selection (stacks and items) before applying.
What gets installed where
| ECC source | Project destination |
|---------------------|----------------------------|
| skills/<id>/ | .claude/skills/<id>/ |
| rules/<lang>/ | .claude/rules/ecc/<lang>/|
| agents/<id>.md | .claude/agents/<id>.md |
| commands/<id>.md | .claude/commands/<id>.md |
- Rules live under
rules/ecc/so they never mix with your own. ECC rules are path-scoped (paths:frontmatter), so e.g. PHP rules only load when Claude works on PHP files. - Dependencies are followed automatically: links in a file's intro (before the first
##heading) are hard dependencies, e.g.rules/phpextendsrules/common, andorch-*skills needorch-pipeline. Later "see also" links are only shown as related. - Relative links between installed files are rewritten to match the new layout.
- ECC's plugin-scoped names (
ecc:planner,/ecc:ecc-guide) in rules, agents and commands are rewritten to the plain project names (planner,/ecc-guide). - Items that need ECC's own script runtime (
scripts/*.js) are shown but can't be selected.
Hooks (optional)
ECC's hooks need ECC's script runtime, so they are installed by ECC's own installer, pinned to
the ECC version in your lock: npx ecc-universal@<version> (--target claude-project --modules
hooks-runtime, npm install scripts disabled). Pick a profile in step 3 of init, or any time:
claude-setup hooks # interactive
claude-setup hooks minimal --yes # minimal | standard | strict
claude-setup hooks off # remove them- minimal: session start/end summaries, session evaluation, cost tracking.
- standard (ECC's default): adds GateGuard (blocks the first Bash/Edit of each session until Claude states what it is doing), config protection, MCP health checks, format/type-check and console.log checks at stop, desktop notifications.
- strict: standard plus the few checks ECC reserves for strict.
ECC discloses that its hook runtime may modify source files, rewrite/terminate commands, send
transcript-derived text to an external LLM, manage MCP processes, block edits/commands, and persist
session/cost records. Enabling always requires an explicit choice (the TUI step, or --yes).
What it changes: the runtime goes to .claude/scripts/ (+ .claude/hooks/, state in .claude/ecc/),
hook entries are merged into .claude/settings.json and ECC_HOOK_PROFILE is set in its env. ECC
embeds this machine's absolute path in every hook command; claude-setup rewrites that to
$CLAUDE_PROJECT_DIR, so settings.json can be committed. Your own hooks, permissions and other
settings are kept, and ECC's unrelated includeCoAuthoredBy: false is reverted to what you had.
update reinstalls the hooks from the new ECC version.
Commit .claude/ecc/ (ECC's install record) together with .claude/scripts/, .claude/hooks/ and
settings.json. Without the record ECC still works after a reinstall, but treats the existing runtime
files as not its own and leaves them behind when hooks are turned off. ECC runs time out after 10
minutes, Ctrl+C cancels a running hooks install, and a failed hooks step never undoes the skills
install/update (retry with claude-setup hooks <profile> --yes). Note that npm does not record which
git commit ecc-universal was published from, so the hooks runtime cannot be cross-checked against the
locked commit; it is pinned by version and npm verifies the package integrity.
Lock file
.claude/ecc.lock.json records the ECC release (tag + commit), your selection (presets plus manual
additions/removals), a SHA-256 hash of the upstream content of every installed file (so a
mismatch on disk means you edited it), and unmanaged items whose pre-existing local copy you chose
to keep. Commit it together with .claude/.
ECC releases are cached (sparse checkout of skills/, rules/, agents/, commands/) in
~/.cache/claude-setup/ecc/<tag> (override with CLAUDE_SETUP_CACHE or XDG_CACHE_HOME).
Requires Node ≥ 22 and git (plus npx for hooks).
Development
npm install
npm run build # bundles to dist/cli.js
npm test # unit tests against test/fixtures/ecc
ECC_DIR=~/.cache/claude-setup/ecc/v2.2.3 npm test # also validates presets against a real release
node dist/cli.js --cwd /path/to/project