Ship lib/profile.sh + 9 profiles in lib/profiles/. A profile is a
plain-text file listing items + types (gstack | personal | external |
plugin@<marketplace> | mcp | cli). `profile set <name>` enables the
listed items and disables the rest:
- gstack/personal/external skills: symlink toggle skills/ ↔
skills-disabled/ (gstack__<name> prefix to avoid collisions; no
prefix for personal/external).
- plugins typed `plugin@<marketplace>`: actually toggled via
`claude plugin enable|disable <name>@<marketplace>`. Allowlist:
MANAGED_PLUGINS = ui-ux-pro-max, plugin-dev, pr-review-toolkit.
Denylist: PROTECTED_PLUGINS = caveman, security-guidance,
superpowers (always-on, never disabled even if absent from a
profile).
- mcp magic: delegated to lib/toggle-external.sh which already
handles the MAGIC_API_KEY env lookup. Other MCPs stay advisory.
- cli (rtk, gsd, ctx7, graphify): status-only, never auto-installed.
Profiles shipped:
web public website work — frontend + content + light dev
seo SEO + GEO + W3C audit (search/AI indexability + a11y)
web-full production website end-to-end (web ∪ seo ∪ qa-only/canary)
backend backend / API / system dev — no design, no SEO
design visual QA, design systems, mockups, polish
dev daily code work — features, fixes, refactor, ship
qa site testing, perf, canary, validation
audit comprehensive audit — security + SEO + perf + health
minimal strip all gstack skills (quiet session)
Commands:
profile list / show <name> / current / apply <name> / set <name> /
reset / diff <a> <b>
`current` heuristic returns "full" when nothing is disabled, otherwise
picks the profile with the highest available-ratio (counts both
"enabled" and "installed" — the latter for CLIs). Tiebreaker: larger
profile total wins, so web-full beats web at a 100% tie.
`reset` re-enables every gstack skill but does NOT touch plugins —
the user re-enables a managed plugin manually or via `apply <profile>`.
This is documented in the trailing info line.
Integration:
- skills/profile/SKILL.md — `/profile` slash command, lists profiles,
documents the per-type mechanism, points at lib/profile.sh.
- agents/plugin-advisor.md — DETECT phase calls `profile current`,
OUTPUT adds a PROFILE line, and TOGGLING EXTERNAL TOOLS gains a
"Skill profiles" section with a signal → profile recommendation
table.
- lib/toggle-external.sh — header pointer to profile.sh for fine-
grained activation (toggle-external still owns whole-gstack and
magic-MCP toggles).
- Makefile — `make profile cmd="set <name>"`, profile-list,
profile-current, profile-reset.
Tested end-to-end: `set web` enables ui-ux-pro-max + magic; `set seo`
disables ui-ux-pro-max; `set minimal` disables ui-ux-pro-max but
spares always-on plugins; `reset` restores all 64 skills; shellcheck
clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
49 lines
2.3 KiB
Makefile
49 lines
2.3 KiB
Makefile
.PHONY: help install plugin link doctor update new-skill profile profile-list profile-current profile-reset
|
|
|
|
help: ## Show available commands
|
|
@grep -E '^[a-zA-Z_-]+:.*##' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*## "}; {printf " make %-14s %s\n", $$1, $$2}'
|
|
|
|
install: ## First-time setup: install Claude Code + auth + symlinks + plugins
|
|
bash install.sh
|
|
|
|
plugin: ## Install prerequisites + all plugins
|
|
bash install-plugins.sh
|
|
|
|
link: ## Create/update symlinks into ~/.claude/
|
|
bash link.sh
|
|
|
|
doctor: ## Run setup diagnostic
|
|
bash doctor.sh
|
|
|
|
update: ## Update Claude Code, config, submodules, plugins, and verify
|
|
bash update-all.sh
|
|
|
|
onboard: link ## Onboard an existing project (run from the project directory)
|
|
@echo "Open Claude Code in your project directory and run: /onboard"
|
|
@echo "Or with hints: /onboard Python FastAPI monorepo"
|
|
|
|
profile: ## Run profile.sh (usage: make profile cmd="set design")
|
|
@bash lib/profile.sh $(cmd)
|
|
|
|
profile-list: ## List skill profiles (design, dev, qa, audit, minimal)
|
|
@bash lib/profile.sh list
|
|
|
|
profile-current: ## Detect which skill profile is currently active
|
|
@bash lib/profile.sh current
|
|
|
|
profile-reset: ## Re-enable all gstack skills (undo any profile set)
|
|
@bash lib/profile.sh reset
|
|
|
|
new-skill: ## Create a new skill scaffold (usage: make new-skill name=myskill)
|
|
@test -n "$(name)" || (echo "Usage: make new-skill name=myskill" && exit 1)
|
|
@mkdir -p agents skills/$(name)
|
|
@if [ ! -f agents/$(name).md ]; then \
|
|
printf -- '---\nname: $(name)\ndescription: <what this agent does — keep under 200 chars>\ntools: Read, Grep, Glob, Bash\nmodel: sonnet\n---\n\n# $(name)\n\n## ROLE\n<role>\n\n## TASKS\n- <task>\n\n## RULES\n- <rule>\n\n## OUTPUT\n```\n<format>\n```\n' > agents/$(name).md; \
|
|
echo "✅ Created agents/$(name).md"; \
|
|
else echo "⚠️ agents/$(name).md already exists"; fi
|
|
@if [ ! -f skills/$(name)/SKILL.md ]; then \
|
|
printf -- '---\nname: $(name)\ndescription: <what this skill does — front-load key use case, max 250 chars>\nargument-hint: <what to pass>\ndisable-model-invocation: true\nallowed-tools: Read, Grep, Glob, Bash\n---\n\nLoad and follow strictly:\n- .claude/agents/$(name).md\n\nExecute on:\n\n$$ARGUMENTS\n' > skills/$(name)/SKILL.md; \
|
|
echo "✅ Created skills/$(name)/SKILL.md"; \
|
|
else echo "⚠️ skills/$(name)/SKILL.md already exists"; fi
|
|
@echo " Edit both files, then run: bash link.sh"
|