A/B /reconcile headless — BEFORE requests=18 output=12374 thinking=3135 effort={'high'} duration_ms=96518 / AFTER requests=15 output=9038 thinking=2248 effort={'low'} duration_ms=78410
8.2 KiB
name, effort, description, argument-hint, allowed-tools
| name | effort | description | argument-hint | allowed-tools | ||
|---|---|---|---|---|---|---|
| profile | low | Partition Claude skills by purpose: design, dev, qa, audit, minimal. Toggles symlinks between skills/ and skills-disabled/ to keep only the skills relevant to the current kind of work. Trigger: "profile", "skill profile", "design profile", "qa profile", "switch to design", "set profile", "active profile", "quel profil", "profil design", "active les skills design", "désactive gstack", "réduire le bruit gstack". | list | show <name> | current | apply <name> | set <name> | reset | gstack on|off | diff <a> <b> |
|
profile
Activate a curated subset of skills for a specific kind of work — instead of carrying every gstack + personal skill in every session.
When to invoke
- User asks to switch profile (
set design,profile dev,quel profil actif). - User wants to see what's in a profile (
profile show qa). - User wants to compare profiles (
profile diff design qa). - User asks to "reduce gstack noise" or "only design skills".
Profiles available
| Profile | Use case |
|---|---|
web |
Public website work — frontend + content + light dev |
seo |
SEO + GEO + W3C audit — search/AI indexability + standards |
web-full |
Production website end-to-end — web + seo combined |
full |
Default — everything the other profiles carry, minus broken or doctrine-breaking gstack |
max |
Everything — full + parked tools (make-pdf, diagram, 21st generation trio) + pr-review-toolkit |
backend |
Backend / API / system dev — no design, no SEO |
design |
Visual QA, design systems, mockups, polish |
dev |
Daily code work — features, fixes, refactor, ship (any stack) |
qa |
Site testing, perf, canary, validation |
audit |
Comprehensive audit — security + SEO + GEO + W3C + perf + health |
minimal |
Strip all gstack skills (quiet session) |
Mechanism
Each profile is a plain-text file under lib/profiles/<name>.profile that
lists items + types:
| Type | Toggle mechanism |
|---|---|
gstack |
symlink move skills/ ↔ skills-disabled/gstack__<name> |
personal |
symlink move skills/ ↔ skills-disabled/<name> (no prefix) |
external |
symlink move skills/ ↔ skills-disabled/<name> |
plugin@<marketplace> |
claude plugin enable|disable <name>@<marketplace> (auto) |
mcp |
advisory — prints manual claude mcp add … command (no server is managed today: MANAGED_MCPS is empty since 21st.dev moved to a CLI) |
cli |
advisory only — reports installed/not-installed |
Always-on plugins (security-guidance) and the vendored superpowers
skills are never toggled by a profile — set will refuse to disable the
plugin even if the profile omits it, and the 7 superpowers skills are
linked outside any profile.
Managed plugins that set may disable when not in profile:
ui-ux-pro-max@ui-ux-pro-max-skill, plugin-dev@claude-code-plugins,
pr-review-toolkit@claude-code-plugins. Other plugins are never auto-toggled.
Managed externals (emil-design-eng, frontend-design,
design-motion-principles, impeccable, and the five 21st design skills
21st-ui-build, 21st-ui-explore, 21st-ui-review, 21st-cli-use,
21st-ai) follow the same symmetry (BDR-079): set enables them when the
profile lists them (from parked state, or from skills-external/ if the
symlink never existed) and parks them when it does not — e.g. set backend
after design work turns emil and the 21st pack off. darwin-skill,
21st-registry, 21st-design-sync and any other unlisted external are never
auto-touched. gstack works the same
all the way down: a profile listing gstack skills while the whole pack is
off (via toggle-external.sh) re-enables JUST those skills on demand.
Default profile: full is in force whenever .active-profile is
absent, empty, or the legacy none (statusline, current, gstack off,
reset all resolve it the same way). reset applies it (set full,
exclusive); a fresh make plugin applies it too when nothing has ever
been selected.
Commands
# List available profiles
bash "$HOME/.claude/lib/profile.sh" list
# Show profile contents + per-skill status
bash "$HOME/.claude/lib/profile.sh" show <name>
# Report the active profile (label + match %)
bash "$HOME/.claude/lib/profile.sh" current
# Enable skills in profile (additive — keeps others enabled)
bash "$HOME/.claude/lib/profile.sh" apply <name>
# Enable only skills in profile (disables non-listed gstack skills)
bash "$HOME/.claude/lib/profile.sh" set <name>
# Go to the default profile (full) — exclusive, same as `set full`
bash "$HOME/.claude/lib/profile.sh" reset
# Toggle gstack only, keeping the active-profile label intact
bash "$HOME/.claude/lib/profile.sh" gstack on # restore parked gstack skills on top of the current profile
bash "$HOME/.claude/lib/profile.sh" gstack off # disable gstack skills not in the active profile
# Compare two profiles
bash "$HOME/.claude/lib/profile.sh" diff <a> <b>
Execution
Run lib/profile.sh with the user's arguments. If user passed nothing, default
to list. If user named a profile without a verb (e.g. "profile design"),
treat it as set <name> — but confirm first because set disables other gstack
skills.
bash "$HOME/.claude/lib/profile.sh" $ARGUMENTS
Failure modes
| Trigger | First move | If still stuck |
|---|---|---|
lib/profile.sh absent (foreign machine, links broken) |
test -f "$HOME/.claude/lib/profile.sh" before any verb; missing → propose bash link.sh from the config repo |
STOP — never hand-move symlinks to emulate the script |
Unknown profile name (rc=1, ✗ Profile not found) |
Show list output + the closest existing name ("desing → did you mean design?") |
Let the user pick — never guess-and-set |
| Unknown verb (rc=1 + usage) | Re-map the request to the argument-hint verbs, retry once | Show usage, ask |
set/apply exits nonzero MID-TOGGLE (permission, plugin CLI failure) |
State may be PARTIAL. Run current to show what actually took; name the failed item from the script's output |
run current, then re-run set <name> or reset (both are full exclusive applies, not an always-safe undo) |
| Plugin/MCP leg fails (marketplace/network) while symlink leg succeeded | Report the split state explicitly + print the manual claude plugin/claude mcp command for the failed leg |
— |
current names a profile other than the one just set |
Cache (.active-profile) was written by another tool or hand-edited — show the raw script output to the user |
Never hand-patch .active-profile — re-run set <name> (or reset) to force it back |
Output policy
- After
set/apply/reset/gstack on|off: show the count of skills moved + tell the user to start a new Claude session to pick up the changes (Claude scansskills/at session start). - After
current: report the active profile + match %;default — not applied yetmeans the default profile is in force but not yet applied — point the user atreset. - After
show: render the grouped output directly — no extra commentary unless the user asks.
Tradeoffs to mention if asked
- gstack skills still depend on
~/.claude/skills/gstack/bin/for telemetry, update-check, learnings — script doesn't touch that infra. Disabled skills are just hidden from Claude Code's scanner; the gstack repo stays installed. - Profile changes DO toggle the managed Claude Code plugins (ui-ux-pro-max,
plugin-dev, pr-review-toolkit) and the managed external packs
(emil-design-eng, frontend-design, design-motion-principles, impeccable,
the 21st design skills) — in BOTH directions:
setenables what the profile lists and disables the managed leftovers it doesn't (BDR-008, BDR-079). Anything outside those allowlists stays manual:claude plugin enable|disable,bash lib/toggle-external.sh enable|disable <tool>. setis destructive in the sense that it disables non-listed gstack skills. Useapplyif the user wants additive behavior.