diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..9c0e9d1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,5 @@ +[submodule "skills-external/gstack"] + path = skills-external/gstack + url = https://github.com/garrytan/gstack.git + branch = main + shallow = true diff --git a/README.md b/README.md index b7e7ed2..9665c3a 100644 --- a/README.md +++ b/README.md @@ -10,64 +10,77 @@ This repo is your personal Claude Code setup, versioned and reproducible across ``` claude-config/ -├── CLAUDE.md # Global coding preferences (style, rules, workflow) -├── settings.json # Global permissions (deny/ask/allow + enabledPlugins) -├── install-plugins.sh # One-shot installer: prerequisites + all plugins -├── link.sh # Symlinks this repo into ~/.claude/ +├── CLAUDE.md # Global coding preferences (style, rules, workflow) +├── settings.json # Global permissions + SessionStart hook +├── install-plugins.sh # One-shot installer: prerequisites + all plugins +├── link.sh # Symlinks this repo into ~/.claude/ +├── .gitmodules # Submodule declaration (GStack) ├── hooks/ -│ └── session-start.sh # Shows toggle plugin status at every session start +│ └── session-start.sh # Shows toggle plugin status at every session start +├── skills-external/ +│ └── gstack/ # Git submodule — garrytan/gstack +│ (symlinked → ~/.claude/skills/gstack) ├── agents/ -│ ├── analyzer.md # Factual codebase analysis (read-only) -│ ├── interviewer.md # Project questionnaire → PROJECT BRIEF -│ ├── plugin-advisor.md # Plugin check: detect mismatches, recommend actions -│ ├── readme-updater.md # Update README from git history + codebase -│ ├── refactorer.md # Surgical refactoring with norm enforcement -│ └── scaffolder.md # Full project generation (CLAUDE.md, README, code) +│ ├── analyzer.md # Factual codebase analysis (read-only) +│ ├── git-workflow.md # Branch setup, commits, PR creation, conflict resolution +│ ├── interviewer.md # Project questionnaire → PROJECT BRIEF +│ ├── plugin-advisor.md # Detect plugin mismatches, recommend actions +│ ├── readme-updater.md # CREATE / SYNC / AUDIT README (3 modes) +│ ├── refactorer.md # Surgical refactoring with norm enforcement +│ └── scaffolder.md # Project skeleton (CLAUDE.md, settings, structure) ├── skills/ -│ ├── analyze/ # /analyze — deep factual analysis -│ ├── init-project/ # /init-project — full project initialization -│ ├── plugin-check/ # /plugin-check — check plugin config vs project needs -│ ├── readme/ # /readme — update README from current state -│ ├── refactor/ # /refactor — improve code without changing behavior -│ └── ship-feature/ # /ship-feature — ship a feature end-to-end +│ ├── analyze/ # /analyze — deep factual analysis +│ ├── git-pr/ # /git-pr — commit, push, open draft PR/MR +│ ├── init-project/ # /init-project — full project initialization +│ ├── plugin-check/ # /plugin-check — check plugin config vs project needs +│ ├── readme/ # /readme — full README audit + update +│ ├── refactor/ # /refactor — improve code without changing behavior +│ └── ship-feature/ # /ship-feature — ship a feature end-to-end └── templates/ - ├── project-CLAUDE.md # Template for per-project CLAUDE.md + ├── project-CLAUDE.md # Template for per-project CLAUDE.md └── settings/ - ├── home-settings.json # Template for ~/.claude/settings.json - ├── settings.json # Template for project .claude/settings.json - ├── settings.local.json # Template for personal .claude/settings.local.json - ├── .claudeignore # Template for project .claudeignore - └── SETTINGS.md # Full settings reference + ├── home-settings.json # Template for ~/.claude/settings.json + ├── settings.json # Template for project .claude/settings.json + ├── settings.local.json# Template for personal .claude/settings.local.json + ├── .claudeignore # Template for project .claudeignore + └── SETTINGS.md # Full settings reference ``` -**Architecture principle:** +**Architecture:** - `skills/` = entry points you invoke via `/skill-name` -- `agents/` = execution units called by skills (never invoked directly by user) +- `agents/` = execution units called by skills (never invoked directly) - Custom skills use **Superpowers** agents for implementation phases -- **Plugins** (Superpowers, GStack, GSD, etc.) install separately and complement custom skills +- **Plugins** (Superpowers, GStack, GSD, etc.) install separately via `install-plugins.sh` --- ## Fresh install (new machine) ```bash -# 1. Clone this repo -git clone git@github.com:youruser/claude-config.git ~/claude-config +# 1. Clone with submodules (GStack is a git submodule) +git clone --recurse-submodules git@github.com:youruser/claude-config.git ~/claude-config # 2. Symlink into ~/.claude/ cd ~/claude-config && bash link.sh -# 3. Install prerequisites + all plugins (detects OS, installs git/Node/Rust/Python) +# 3. Install prerequisites + all plugins +# Handles: git, Node.js 22, Rust/Cargo, Python 3, gh CLI, glab CLI, +# RTK, GStack (submodule), GSD, all marketplace plugins bash ~/claude-config/install-plugins.sh -# 4. Add Context7 API key (free at context7.com) — manual step +# 4. Authenticate git provider CLIs (for /git-pr) +gh auth login # GitHub +glab auth login # GitLab +# Gogs/Gitea: see "Git setup" section below + +# 5. Add Context7 API key (free at context7.com) claude mcp add --scope user context7 -- npx -y @upstash/context7-mcp --api-key YOUR_KEY -# 5. Restart Claude Code then run /reload-plugins +# 6. Restart Claude Code → /reload-plugins ``` -The install script handles: git, Node.js 22, Rust/Cargo, Python 3, RTK, GStack, GSD, -and all marketplace plugins on Linux (apt/dnf/pacman) and macOS (brew). +All `claude plugin install` calls use `--scope user` — always installs +to `~/.claude/plugins/` regardless of working directory. --- @@ -81,6 +94,7 @@ and all marketplace plugins on Linux (apt/dnf/pacman) and macOS (brew). | `/refactor` | Improve code quality without changing behavior (strict norms) | | `/readme` | Full README audit — diff vs codebase, mandatory stop, surgical updates | | `/plugin-check` | Check active plugins vs project needs — recommend enable/disable | +| `/git-pr` | Commit all changes, push, open draft PR/MR (GitHub/GitLab/Gogs/Gitea) | | `/init-project` | Initialize a complete project from scratch (full orchestrator) | | `/ship-feature` | Ship a feature end-to-end with validation gates (full orchestrator) | @@ -95,10 +109,11 @@ and all marketplace plugins on Linux (apt/dnf/pacman) and macOS (brew). | `test-driven-development` | Auto — when implementing | | `requesting-code-review` | Auto — after a feature step | -### GStack skills (Garry Tan — full-product projects only) +### GStack skills (full-product projects only) -> Install: `git clone https://github.com/garrytan/gstack ~/.claude/skills/gstack && cd ~/.claude/skills/gstack && ./setup` -> **Use when:** project has UI + design + deploy + browser QA. Skip for backend/lib/CLI projects. +> Submodule at `skills-external/gstack/`, symlinked to `~/.claude/skills/gstack/`. +> **Use when:** project has UI + design + deploy + browser QA. +> Skip for backend-only, libs, CLI, scripts. | Command | Description | |---|---| @@ -115,12 +130,12 @@ and all marketplace plugins on Linux (apt/dnf/pacman) and macOS (brew). | `/careful` | Activate safety guardrails | | `/freeze` | Lock edits to current directory | | `/retro` | Engineering retrospective | -| `/gstack-upgrade` | Self-update GStack | +| `/gstack-upgrade` | Self-update GStack to latest | -### GSD skills (glittercowboy — multi-session large features) +### GSD skills (multi-session large features) -> Install: `npx get-shit-done-cc --claude --global` -> **Use when:** feature spans multiple days/sessions. Each session starts fresh with full context from previous phases. +> Installed globally via `npx get-shit-done-cc --claude --global` (done by install-plugins.sh). +> **Use when:** feature spans multiple days/sessions. | Command | Description | |---|---| @@ -144,29 +159,30 @@ and all marketplace plugins on Linux (apt/dnf/pacman) and macOS (brew). ### `/init-project` Same rigor as `/ship-feature`. Two validation gates. Full TDD subagent pipeline for v1 features. -The Scaffolder only creates the skeleton (no features, no README). -readme-updater handles the README in two passes: CREATE then SYNC. +Scaffolder creates only the skeleton. readme-updater handles README in two passes (CREATE + SYNC). +Always works on a feature branch — never on main/master. ``` /init-project │ - ├── STEP 0: PLUGIN CHECK (plugin-advisor) ← blocks if wrong plugins + ├── STEP 0a: BRANCH SETUP (git-workflow) ← create feature branch from main + │ or sync existing branch + ├── STEP 0b: PLUGIN CHECK (plugin-advisor) ← blocks if wrong plugins ├── STEP 1: INTERVIEWER (custom) → PROJECT BRIEF ├── STEP 2: ANALYZER (custom) → ANALYSIS REPORT ├── STEP 3: superpowers:brainstorming → VALIDATED DESIGN ├── STEP 4: VALIDATION GATE #1 → approve architecture - ├── STEP 5: SCAFFOLDER (custom) → skeleton only (CLAUDE.md + - │ settings + structure + - │ empty entry points, NO features, - │ NO README) - ├── STEP 5b: README-UPDATER create mode (custom) → CREATE README from CLAUDE.md + ├── STEP 5: SCAFFOLDER (custom) → skeleton (CLAUDE.md + settings + + │ structure + empty entry points, + │ NO features, NO README) + ├── STEP 5b: README-UPDATER create mode → CREATE README from CLAUDE.md ├── STEP 6: superpowers:writing-plans → decompose v1 features into tasks ├── STEP 7: VALIDATION GATE #2 → approve task plan - ├── STEP 8: superpowers:subagent-driven (TDD) → implement each feature (isolated) + ├── STEP 8: superpowers:subagent-driven (TDD) → implement each feature ├── STEP 9: ANALYZER (custom) → regression + deviation check ├── STEP 10: superpowers:requesting-review → full code review ├── STEP 11: superpowers:finishing-branch → cleanup + build + tests - └── STEP 12: README-UPDATER sync mode (custom) → sync README with implementation + └── STEP 12: README-UPDATER sync mode → sync README with implementation ``` ### `/ship-feature` @@ -174,81 +190,289 @@ readme-updater handles the README in two passes: CREATE then SYNC. ``` /ship-feature │ - ├── STEP 0: PLUGIN CHECK (plugin-advisor) ← blocks if wrong plugins active - ├── STEP 1: superpowers:brainstorming → VALIDATED DESIGN - ├── STEP 2: superpowers:writing-plans → task plan - ├── STEP 3: VALIDATION GATE → user approval required - ├── STEP 4: superpowers:subagent-driven → implementation (TDD) - ├── STEP 5: ANALYZER (custom) → regression / deviation check - ├── STEP 6: superpowers:requesting-review → code review - └── STEP 7: superpowers:finishing-branch → cleanup + ├── STEP 0a: BRANCH SETUP (git-workflow) ← create/sync feature branch + ├── STEP 0b: PLUGIN CHECK (plugin-advisor) ← blocks if wrong plugins + ├── STEP 1: superpowers:brainstorming → VALIDATED DESIGN + ├── STEP 2: superpowers:writing-plans → task plan + ├── STEP 3: VALIDATION GATE → user approval required + ├── STEP 4: superpowers:subagent-driven (TDD) → implementation + ├── STEP 5: ANALYZER (custom) → regression / deviation check + ├── STEP 6: superpowers:requesting-review → code review + ├── STEP 7: superpowers:finishing-branch → cleanup + ├── STEP 8: README-UPDATER sync mode → update README + └── STEP 9: CREATE PR (optional gate) → /git-pr if user approves ``` +### `/git-pr` + +Works on any provider. Retroactive — `git diff ...HEAD` sees ALL changes since +branch creation, regardless of session count. Creates a **draft PR** — you control the merge. + +``` +/git-pr [optional title] + │ + ├── PHASE 0: Detect provider (GitHub/GitLab/Gogs/Gitea) + │ Check CLI: gh / glab / API fallback + ├── PHASE 1: Analyze branch (retroactive) + │ git diff ...HEAD — ALL changes since branch start + │ Categorize: config / model / core / api / ui / test / docs / infra + ├── PHASE 2: Propose commit plan (conventional commits) + │ [VALIDATION GATE] — user approves before any commit + ├── PHASE 3: Execute commits (staged per logical group) + ├── PHASE 4: Push (with conflict-safe rebase if rejected) + └── PHASE 5: Create draft PR/MR + GitHub → gh pr create --draft (or API) + GitLab → glab mr create --draft (or API) + Gogs → POST /api/v1/repos/{owner}/{repo}/pulls + Gitea → same API format as Gogs +``` + +**Branch → base mapping:** +| Branch prefix | Default base | Commit type | +|---|---|---| +| `feature/*`, `feat/*` | `develop` or `main` | `feat:` | +| `bugfix/*`, `fix/*` | `develop` | `fix:` | +| `hotfix/*` | `main` | `fix:` | +| `release/*` | `main` | `chore(release):` | + ### `/plugin-check` -Standalone command you can run at any time to audit your plugin config -against what you're about to do. Also embedded as STEP 0 in both orchestrators. +Standalone — run before any significant work. Also auto-runs as STEP 0b +in `/init-project` and `/ship-feature`. ``` -/plugin-check "I want to build a React + FastAPI SaaS" - +/plugin-check "React + FastAPI SaaS with auth" → Detects active plugins → Analyzes signals: frontend? design? QA? multi-session? fast-evolving libs? → Produces recommendation table -→ Blocks with OPTIONS if critical plugins are missing -→ Or confirms "proceed" if config is optimal +→ Blocks if critical plugins missing, or confirms "proceed" +``` + +--- + +## Git setup for `/git-pr` + +`/git-pr` auto-detects your provider from the remote URL and uses the best available +authentication method. Here is how to set up each provider. + +--- + +### GitHub + +**Option A — gh CLI (recommended)** + +```bash +# Install (done by install-plugins.sh) +brew install gh # macOS +sudo apt install gh # Linux + +# Authenticate (interactive — opens browser) +gh auth login +# Choose: GitHub.com → HTTPS → authenticate with browser + +# Verify +gh auth status +``` + +**Option B — Personal Access Token (for CI or headless)** + +1. Go to **github.com → Settings → Developer settings → Personal access tokens → Tokens (classic)** +2. Click **Generate new token** +3. Required scopes: `repo` (full), `read:org` (if org repo) +4. Copy the token + +```bash +# Set in environment +export GITHUB_TOKEN="ghp_xxxxxxxxxxxx" +echo 'export GITHUB_TOKEN="ghp_xxxxxxxxxxxx"' >> ~/.zshrc # persist + +# Claude Code reads GITHUB_TOKEN automatically for gh CLI fallback +``` + +--- + +### GitLab + +**Option A — glab CLI (recommended)** + +```bash +# Install (done by install-plugins.sh) +brew install glab # macOS + +# Authenticate +glab auth login +# Choose: gitlab.com → Token or browser + +# For self-hosted GitLab +glab auth login --hostname gitlab.yourcompany.com + +# Verify +glab auth status +``` + +**Option B — Personal Access Token** + +1. Go to **gitlab.com → User Settings → Access Tokens** (or your instance) +2. Click **Add new token** +3. Required scopes: `api`, `read_repository`, `write_repository` +4. Copy the token + +```bash +export GITLAB_TOKEN="glpat-xxxxxxxxxxxx" +echo 'export GITLAB_TOKEN="glpat-xxxxxxxxxxxx"' >> ~/.zshrc + +# For self-hosted +export GITLAB_HOST="https://gitlab.yourcompany.com" +``` + +--- + +### Gogs + +Gogs has no official CLI. `/git-pr` uses the REST API directly. + +**Create an API token:** + +1. Log in to your Gogs instance +2. Go to **User Settings (top-right avatar) → Applications** +3. Under **Token Name**, enter `claude-code` +4. Click **Generate Token** +5. Copy the token (shown only once) + +```bash +# Set in environment +export GOGS_TOKEN="your-token-here" +echo 'export GOGS_TOKEN="your-token-here"' >> ~/.zshrc + +# Verify the API works +curl -H "Authorization: token $GOGS_TOKEN" \ + https://your-gogs-server/api/v1/user +# Should return your user JSON +``` + +**Required API permissions:** read/write on repos (tokens in Gogs have full API access by default). + +--- + +### Gitea + +Same API format as Gogs. Gitea is a Gogs fork. + +**Create an API token:** + +1. Log in to your Gitea instance +2. Go to **User Settings → Applications → Manage Access Tokens** +3. Enter token name `claude-code` +4. Select permissions: `Issues: Read/Write`, `Repository: Read/Write` +5. Click **Generate Token** and copy it + +```bash +export GITEA_TOKEN="your-token-here" +echo 'export GITEA_TOKEN="your-token-here"' >> ~/.zshrc + +# Verify +curl -H "Authorization: token $GITEA_TOKEN" \ + https://your-gitea-server/api/v1/user +``` + +--- + +### Self-hosted GitHub Enterprise + +```bash +# Configure gh for your instance +gh config set -h github.yourcompany.com git_protocol https +gh auth login --hostname github.yourcompany.com + +# Verify +gh auth status --hostname github.yourcompany.com +``` + +--- + +### Self-hosted GitLab + +```bash +glab auth login --hostname gitlab.yourcompany.com --token glpat-xxxx +``` + +--- + +### Token security + +- **Never commit tokens** to git — they go in `~/.zshrc`, `~/.bashrc`, or a secrets manager +- **Rotate tokens** when they expire or are compromised +- **Minimum scopes** — only grant what `/git-pr` needs (repo read/write) +- Claude Code reads env vars securely — tokens are never written to disk by Claude + +--- + +### Verify your setup + +```bash +# Run inside Claude Code to verify everything +/git-pr check-auth +# → Detects provider from current repo remote +# → Tests authentication +# → Reports status per provider +``` + +Or manually: +```bash +git remote get-url origin # see which provider +gh auth status # GitHub CLI status +glab auth status # GitLab CLI status +curl -s -H "Authorization: token $GOGS_TOKEN" \ + /api/v1/user | jq .login # Gogs/Gitea ``` --- ## Plugins reference -All plugins below are installed by `install-plugins.sh`. +All plugins installed by `install-plugins.sh`. -### Quick reference +### At-a-glance: always on vs toggle -The mechanism: Claude Code loads every active skill's **description** into a shared context budget -at session start (default 8000 chars). Even if you never invoke the skill, its description -is already consuming tokens. **Disabling a plugin prevents its descriptions from loading entirely.** +The mechanism: Claude Code loads every active skill's **description** at session start +into a shared budget (8000 chars). Even if never invoked, the description costs tokens. +Disabling a plugin → descriptions never load. -A `hooks/session-start.sh` hook shows the current toggle status at the start of every session. -Run `/plugin-check` anytime to get a full recommendation for the current project type. +A `hooks/session-start.sh` hook shows toggle status at every session start. +Run `/plugin-check` for a full recommendation for the current project type. -| Plugin | Status | Passive cost | When to toggle ON | Installed by | +| Plugin | Status | Cost/session | When to enable | Installed by | |---|---|---|---|---| -| **security-guidance** | ✅ ALWAYS ON | 0 tokens (hook only) | — | marketplace | -| **RTK** | ✅ ALWAYS ON | 0 tokens (hook only) | — | cargo + rtk init | -| **Superpowers** | ✅ ALWAYS ON | ~600–1000 tokens | — auto-activates when relevant | marketplace | -| **skill-creator** | ✅ ALWAYS ON | ~100 tokens | — | marketplace | -| **pr-review-toolkit** | ✅ ALWAYS ON | ~300 tokens | — use `/pr-review-toolkit:review-pr` | marketplace | -| **GStack** | 🔄 TOGGLE | ~2500–3000 tokens | Full-product: UI + design + deploy + browser QA | git clone | -| **GSD** | 🔄 TOGGLE | ~500–800 tokens | Feature spanning multiple days/sessions | npx | -| **frontend-design** | 🔄 TOGGLE | ~200 tokens | Any project with a UI | marketplace | -| **ui-ux-pro-max** | 🔄 TOGGLE | ~400 tokens | Design system, color/typography choices | marketplace | -| **Context7 MCP** | 🔄 TOGGLE | ~200 tokens | Fast-evolving libs (Next.js, React, Prisma…) | MCP manual | +| **security-guidance** | ✅ ALWAYS ON | 0 (hook only) | — | marketplace | +| **RTK** | ✅ ALWAYS ON | 0 (hook only) | — | cargo + rtk init | +| **Superpowers** | ✅ ALWAYS ON | ~600–1000 | — auto-activates | marketplace | +| **skill-creator** | ✅ ALWAYS ON | ~100 | — | marketplace | +| **pr-review-toolkit** | ✅ ALWAYS ON | ~300 | — `/pr-review-toolkit:review-pr` | marketplace | +| **GStack** | 🔄 TOGGLE | ~2500–3000 | Full-product: UI + design + deploy + QA browser | submodule | +| **GSD** | 🔄 TOGGLE | ~500–800 | Feature spanning multiple days/sessions | npx | +| **frontend-design** | 🔄 TOGGLE | ~200 | Any project with a UI | marketplace | +| **ui-ux-pro-max** | 🔄 TOGGLE | ~400 | Design system, color/typography | marketplace | +| **Context7 MCP** | 🔄 TOGGLE | ~200 | Fast-evolving libs (Next.js, React, Prisma…) | MCP manual | -**Rule:** toggle plugins are OFF by default. `/plugin-check` signals when to enable them. -If you use `/init-project` or `/ship-feature`, plugin-check runs automatically as STEP 0. +Toggle plugins start **OFF**. `/plugin-check` signals when to enable them. +`/init-project` and `/ship-feature` run plugin-check automatically as STEP 0b. -### Disabling a plugin for a specific project +### Disable a plugin for a specific project ```bash -# In Claude Code -/plugin -# → Find the plugin → toggle off for this scope +/plugin # inside Claude Code → toggle off ``` -Or in the project's `.claude/settings.json`: +Or in `.claude/settings.json`: ```json { "enabledPlugins": { - "gstack@gstack": false, - "gsd@gsd": false + "gstack@gstack": false } } ``` -### Enabling a plugin for a specific project (so teammates can install it) +### Enable a plugin for a project (share with teammates) ```json { @@ -257,10 +481,7 @@ Or in the project's `.claude/settings.json`: }, "extraKnownMarketplaces": { "ui-ux-pro-max-skill": { - "source": { - "source": "github", - "repo": "nextlevelbuilder/ui-ux-pro-max-skill" - } + "source": { "source": "github", "repo": "nextlevelbuilder/ui-ux-pro-max-skill" } } } } @@ -285,7 +506,19 @@ DENY always wins over ALLOW at any level. .claudeignore applies independently of all permission rules. ``` -### Global settings (this repo's `settings.json`) +### Global `settings.json` (this repo) + +Contains global deny/ask/allow rules AND a SessionStart hook: + +```json +"hooks": { + "SessionStart": [ + { "hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/session-start.sh" }] } + ] +} +``` + +The hook prints toggle plugin status at every session start — zero API calls, filesystem only. | Section | Purpose | |---|---| @@ -300,20 +533,19 @@ DENY always wins over ALLOW at any level. ### Per-project setup ```bash -cd your-project -mkdir -p .claude +cd your-project && mkdir -p .claude -# Project settings (commit to project git) +# Project settings (commit) cp ~/claude-config/templates/settings/settings.json .claude/settings.json -# Personal overrides (never commit — gitignore it) +# Personal overrides (never commit) cp ~/claude-config/templates/settings/settings.local.json .claude/settings.local.json echo ".claude/settings.local.json" >> .gitignore -# Hard file exclusions (commit to project git) +# Hard file exclusions (commit) cp ~/claude-config/templates/settings/.claudeignore .claudeignore -# Project CLAUDE.md (commit to project git) +# Project CLAUDE.md (commit) cp ~/claude-config/templates/project-CLAUDE.md .claude/CLAUDE.md ``` @@ -324,24 +556,31 @@ cp ~/claude-config/templates/project-CLAUDE.md .claude/CLAUDE.md ### This repo ```bash cd ~/claude-config && git pull -# Symlinks → changes active immediately +# Symlinks → changes active immediately, no restart needed ``` -### GStack +### GStack (submodule) ```bash -/gstack-upgrade # inside Claude Code -# or manually: -git -C ~/.claude/skills/gstack pull && cd ~/.claude/skills/gstack && ./setup +# Option A — from Claude Code +/gstack-upgrade + +# Option B — via submodule (pins version in your repo) +cd ~/claude-config +git submodule update --remote skills-external/gstack +cd skills-external/gstack && ./setup +git add skills-external/gstack +git commit -m "chore: update gstack" ``` ### Marketplace plugins ```bash -/plugin marketplace update # inside Claude Code +/plugin marketplace update ``` ### RTK ```bash cargo install --git https://github.com/rtk-ai/rtk --force +rtk init -g --auto-patch # re-apply hook if needed ``` --- @@ -373,9 +612,8 @@ $ARGUMENTS ## Per-project agent overrides -Override any global agent for a specific project: - ```bash +# Override an agent for a specific project cp ~/claude-config/agents/refactorer.md .claude/agents/refactorer.md -# Edit .claude/agents/refactorer.md — the local version takes precedence +# Edit — the local version takes precedence over global ``` diff --git a/agents/git-workflow.md b/agents/git-workflow.md new file mode 100644 index 0000000..0a42731 --- /dev/null +++ b/agents/git-workflow.md @@ -0,0 +1,473 @@ +--- +name: git-workflow +description: Analyze all changes since branch start (retroactive, session-agnostic), create logical commits, push, and open a PR/MR on GitHub, GitLab, Gogs, or Gitea. Never merges — creates a draft PR for user validation. +tools: Read, Bash, Grep, Glob +model: sonnet +--- + +# GIT WORKFLOW + +## ROLE +Turn all work done on a branch into a clean, reviewed set of commits +and an open PR/MR — regardless of how many sessions it took. + +## GOAL +- Stage and commit all uncommitted changes in logical groups +- Push the branch to the remote +- Create a PR/MR on the right platform +- Never merge — the user validates the PR + +--- + +## BRANCH SETUP (called by init-project and ship-feature) + +This procedure runs before any code is written. +It ensures work always happens on a proper branch, never on main/master/develop. + +### 1. Check current branch + +```bash +CURRENT=$(git branch --show-current) +echo "Current branch: $CURRENT" +``` + +### 2. Determine protected branches + +Protected branches (never commit directly): +- `main`, `master`, `develop`, `dev`, `staging`, `production`, `prod` + +```bash +PROTECTED="main master develop dev staging production prod" +``` + +### 3. If on a protected branch → create a feature branch + +```bash +# Derive branch name from context: +# - init-project: feature/ +# - ship-feature: feature/ +# Slugify: lowercase, replace spaces with hyphens, max 50 chars + +BRANCH_NAME="feature/" + +# Ensure main is up to date before branching +git fetch origin +git pull origin $CURRENT --ff-only 2>/dev/null || true + +# Create and checkout the feature branch +git checkout -b $BRANCH_NAME + +echo "✅ Created branch: $BRANCH_NAME (from $CURRENT)" +``` + +### 4. If already on a feature/bugfix/hotfix branch → sync with base + +```bash +BASE=$(git merge-base HEAD origin/main 2>/dev/null || git merge-base HEAD origin/master 2>/dev/null) + +# Check if the base branch has new commits the feature branch doesn't have +git fetch origin +BEHIND=$(git rev-list HEAD..origin/ --count 2>/dev/null || echo "0") +``` + +If `BEHIND > 0`: +``` +⚠️ Your branch is behind by $BEHIND commit(s). +Rebasing to sync... +``` +Run the CONFLICT-SAFE REBASE procedure below. + +If `BEHIND = 0`: print `✅ Branch is up to date` and continue. + +### 5. Branch naming conventions + +| Context | Branch format | Example | +|---|---|---| +| New project (init-project) | `feature/` | `feature/zenquality-website` | +| New feature (ship-feature) | `feature/` | `feature/user-authentication` | +| Bug on a feature branch | `bugfix/` from feature | `bugfix/fix-login-redirect` | +| Urgent production fix | `hotfix/` from main | `hotfix/patch-csrf-vulnerability` | +| Release prep | `release/` from main | `release/v1.2.0` | + +--- + +## CONFLICT-SAFE REBASE + +Use this whenever rebasing a branch against its base. + +```bash +git rebase origin/ +``` + +**If rebase exits cleanly:** done. + +**If conflicts are detected:** + +```bash +# List conflicted files +git diff --name-only --diff-filter=U +``` + +For each conflicted file: +1. Read the file — identify the conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`) +2. Analyze both versions: + - `HEAD` (ours) = the feature branch code + - `origin/` (theirs) = what's on the base branch +3. Resolve using this priority: + - **New feature code** (ours) takes precedence for new functions/logic + - **Base branch changes** (theirs) take precedence for config, dependencies, global state + - **Both changes** are merged when they affect different parts of the same file +4. Write the resolved file (no conflict markers left) +5. Stage it: `git add ` +6. Continue: `git rebase --continue` + +**If a conflict cannot be auto-resolved** (same lines modified with incompatible logic): +``` +⚠️ CONFLICT — manual resolution required +File: +Ours: +Theirs: + +How should this be resolved? + A) Keep our version (feature branch) + B) Keep their version (base branch) + C) I'll resolve manually — pause here +``` +**STOP — wait for user choice.** + +After user responds: +- A or B → apply, `git add `, `git rebase --continue` +- C → `git rebase --abort` and hand back control to user + +**After all conflicts resolved:** +```bash +git log --oneline ..HEAD +echo "✅ Rebase complete — branch is clean" +``` + +--- + +## PHASE 0 — DETECT GIT PROVIDER + +Run: +```bash +git remote get-url origin 2>/dev/null || git remote get-url upstream 2>/dev/null +``` + +Parse the URL to determine the provider: + +| URL pattern | Provider | CLI available? | +|---|---|---| +| `github.com` | GitHub | check `gh auth status` | +| `gitlab.com` or `gitlab.*` | GitLab | check `glab auth status` | +| anything else | Gogs / Gitea | API only (no official CLI) | + +Extract: +- `REMOTE_URL` — full remote URL +- `PROVIDER` — github / gitlab / gogs-gitea +- `BASE_URL` — for Gogs/Gitea: `https://hostname` (strip path) +- `OWNER` — repo owner/organization +- `REPO` — repo name +- `CLI_AVAILABLE` — gh / glab / none + +For Gogs/Gitea, check for an API token in env: +```bash +echo "${GOGS_TOKEN:-${GITEA_TOKEN:-not-set}}" +``` +If not set, print: +``` +⚠️ Gogs/Gitea detected. Set one of these env vars: + export GOGS_TOKEN="your-token" + export GITEA_TOKEN="your-token" + Then re-run /git-pr +``` +And STOP. + +--- + +## PHASE 1 — ANALYZE BRANCH STATE + +### 1a. Identify current branch and base + +```bash +git branch --show-current +``` + +Determine the base branch from the branch name: +| Branch prefix | Default base | PR type | +|---|---|---| +| `feature/*` | `develop` (or `main` if no develop) | Feature | +| `feat/*` | `develop` (or `main`) | Feature | +| `bugfix/*` | `develop` | Bug fix | +| `fix/*` | `develop` | Bug fix | +| `hotfix/*` | `main` | Hotfix | +| `release/*` | `main` | Release | +| `chore/*` | `develop` (or `main`) | Chore | +| anything else | `main` | General | + +Verify the base branch exists: +```bash +git rev-parse --verify 2>/dev/null +``` + +### 1b. Retroactive diff — ALL changes since branch start + +```bash +# All committed changes on this branch (retroactive, session-agnostic) +git log --oneline ..HEAD + +# All uncommitted changes +git status --short + +# Full diff of everything: committed + uncommitted vs base +git diff ...HEAD --name-status + +# Stats +git diff ...HEAD --stat +``` + +The `git diff ...HEAD` (three dots) shows everything since +the branch diverged from base — not just since last commit. +This is the source of truth regardless of session count. + +### 1c. Build the CHANGE MAP + +Categorize every changed file: +- `config` — package.json, Cargo.toml, go.mod, requirements.txt, docker-compose.yml, Makefile, CI files +- `model` — data models, schemas, migrations, types +- `core` — business logic, services, domain +- `api` / `routes` — endpoints, controllers, handlers +- `ui` — components, pages, styles, assets +- `test` — all test files +- `docs` — README, CLAUDE.md, markdown docs +- `infra` — Dockerfile, deploy scripts, k8s, terraform + +--- + +## PHASE 2 — PROPOSE COMMITS + +Group the changes from the CHANGE MAP into logical commits. +Order: config → model → core → api/routes → ui → test → docs → infra + +For each group, propose a commit using Conventional Commits: +``` +(): + +Types: feat, fix, chore, refactor, test, docs, style, ci, build, perf +Scope: optional, matches the module/directory +``` + +Present the proposed commit plan: +``` +================================================================ +GIT WORKFLOW — COMMIT PLAN +================================================================ + +BRANCH : +BASE : +PROVIDER : + +CHANGES SINCE BRANCH START +--------------------------- + + +PROPOSED COMMITS +---------------- + 1. chore(deps): update dependencies — [package.json, go.mod] + 2. feat(auth): add user model and migration — [models/user.go, migrations/001_users.sql] + 3. feat(auth): implement login and JWT handlers — [handlers/auth.go, services/auth.go] + 4. test(auth): add unit tests for auth service — [tests/auth_test.go] + 5. docs: update README with auth setup — [README.md] + +UNCOMMITTED CHANGES (will be staged in their respective commit) +--------------------------------------------------------------- + + +================================================================ +Approve this commit plan? (yes / modify / cancel) +================================================================ +``` + +**MANDATORY STOP — wait for user approval.** + +IF modify → user describes changes → adjust plan → re-present +IF cancel → stop, no changes made +IF yes → proceed to PHASE 3 + +--- + +## PHASE 3 — EXECUTE COMMITS + +For each proposed commit, in order: + +```bash +# Stage the specific files for this commit +git add + +# Commit with the proposed message +git commit -m "(): " +``` + +If a file has both committed and uncommitted changes: +- Stage only the uncommitted portion +- Include it in the appropriate commit group + +After all commits: +```bash +git log --oneline ..HEAD +``` +Show the final commit list for confirmation. + +--- + +## PHASE 4 — PUSH + +```bash +# Push, setting upstream if branch is new +git push --set-upstream origin +``` + +**If push is rejected** (remote has diverged): +1. Run the CONFLICT-SAFE REBASE procedure: + ```bash + git fetch origin + git rebase origin/ + ``` +2. Resolve any conflicts as described in CONFLICT-SAFE REBASE +3. Push again: `git push origin ` + +**If the push is still rejected after rebase:** +```bash +git log --oneline origin/..HEAD +``` +Show the commits that haven't been pushed and ask the user: +``` +⚠️ Push still rejected after rebase. + Local commits not on remote: + Options: + A) Force push (overwrites remote — use only if remote is yours) + B) Investigate manually +``` +**STOP — wait for user choice. Never force push without explicit approval.** + +--- + +## PHASE 5 — CREATE PR / MR + +Build the PR body from: +- `git log ..HEAD --format="- %s"` — commit list +- Modified file categories (from CHANGE MAP) +- CLAUDE.md project context + +PR body template: +```markdown +## Summary + +<2-3 sentence description derived from branch name and commit messages> + +## Changes + + + +## Modified areas + + + +## Testing + + + +--- +*Created by /git-pr — validate then merge* +``` + +### GitHub + +```bash +# With gh CLI (preferred) +gh pr create \ + --base \ + --head \ + --title ": " \ + --body "" \ + --draft + +# Without gh CLI — print URL for manual creation +echo "Create PR at: https://github.com///compare/..." +``` + +### GitLab + +```bash +# With glab CLI (preferred) +glab mr create \ + --source-branch \ + --target-branch \ + --title ": " \ + --description "" \ + --draft + +# Without glab CLI +echo "Create MR at: https://gitlab.com///-/merge_requests/new?merge_request[source_branch]=" +``` + +### Gogs / Gitea + +Use the API directly (both use GitHub API v3-compatible format): + +```bash +curl -s -X POST \ + "${BASE_URL}/api/v1/repos/${OWNER}/${REPO}/pulls" \ + -H "Authorization: token ${GOGS_TOKEN:-$GITEA_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "{ + \"title\": \": \", + \"body\": \"\", + \"head\": \"\", + \"base\": \"\" + }" +``` + +If the API call returns an error, print the full response and suggest +creating the PR manually via the web UI. + +--- + +## PHASE 6 — FINAL REPORT + +``` +================================================================ +PR CREATED +================================================================ + +BRANCH : +COMMITS : commits pushed +PLATFORM : + +COMMITS +------- + + +PR / MR +------- +URL : "> +Type : Draft — awaiting your review and merge + +NEXT STEPS +---------- +1. Review the PR at the URL above +2. Request reviews if needed +3. Merge when approved +================================================================ +``` + +--- + +## RULES + +- Never merge, never rebase main/master/develop +- Never force push unless explicitly asked +- Never create commits on main, master, or develop directly +- If on main/master — STOP and ask user to checkout a feature branch first +- Draft PR by default — user controls merge +- If no CLI tool and no API token — print manual instructions, do not fail silently diff --git a/install-plugins.sh b/install-plugins.sh index bf5c9dc..a8b6567 100644 --- a/install-plugins.sh +++ b/install-plugins.sh @@ -2,83 +2,321 @@ # ============================================================ # Claude Code — Plugin installer # Run this after a fresh clone to reinstall all plugins +# and their prerequisites on a new machine. +# +# Supports: Linux (apt/dnf/pacman), macOS (brew) # ============================================================ set -euo pipefail -echo "=== Claude Code Plugin Installer ===" -echo "" +RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m' +ok() { echo -e "${GREEN}✓${NC} $1"; } +warn() { echo -e "${YELLOW}⚠${NC} $1"; } +info() { echo -e "${BLUE}→${NC} $1"; } +err() { echo -e "${RED}✗${NC} $1"; } -# ---- Marketplace officielle (already registered by default) ---- -echo ">> Installing official Anthropic plugins..." -claude plugin install security-guidance@claude-plugins-official -claude plugin install frontend-design@claude-plugins-official -claude plugin install skill-creator@claude-plugins-official -claude plugin install pr-review-toolkit@claude-plugins-official +REPO="$(cd "$(dirname "$0")" && pwd)" -# ---- Superpowers ---- -echo "" -echo ">> Installing Superpowers..." -claude plugin marketplace add obra/superpowers-marketplace 2>/dev/null || true -claude plugin install superpowers@superpowers-marketplace - -# ---- UI/UX Pro Max ---- -echo "" -echo ">> Installing UI/UX Pro Max..." -claude plugin marketplace add nextlevelbuilder/ui-ux-pro-max-skill 2>/dev/null || true -claude plugin install ui-ux-pro-max@ui-ux-pro-max-skill - -# ---- GSD ---- -echo "" -echo ">> Installing GSD (get-shit-done)..." -npx get-shit-done-cc --claude --global --auto - -# ---- GStack ---- -echo "" -echo ">> Installing GStack (Garry Tan)..." -if [ ! -d "$HOME/.claude/skills/gstack" ]; then - git clone --single-branch --depth 1 \ - https://github.com/garrytan/gstack.git \ - "$HOME/.claude/skills/gstack" +# ============================================================ +# DETECT OS +# ============================================================ +OS="unknown" +PKG="" +if [[ "$OSTYPE" == "darwin"* ]]; then + OS="macos" +elif command -v apt-get &>/dev/null; then + OS="linux-apt"; PKG="apt-get" +elif command -v dnf &>/dev/null; then + OS="linux-dnf"; PKG="dnf" +elif command -v pacman &>/dev/null; then + OS="linux-pacman"; PKG="pacman" fi -cd "$HOME/.claude/skills/gstack" && ./setup -cd - -# ---- RTK ---- echo "" -echo ">> Installing RTK (token compression)..." -if ! command -v rtk &>/dev/null; then +echo "╔══════════════════════════════════════════════════════════╗" +echo "║ Claude Code — Plugin & Tool Installer ║" +echo "╚══════════════════════════════════════════════════════════╝" +echo "" +info "OS: $OS | Repo: $REPO" +echo "" + +# ============================================================ +# STEP 1 — PREREQUISITES +# ============================================================ +echo "── Step 1: Prerequisites ───────────────────────────────────" +echo "" + +# --- git --- +if command -v git &>/dev/null; then + ok "git $(git --version | awk '{print $3}')" +else + info "Installing git..." + case $OS in + macos) brew install git ;; + linux-apt) sudo apt-get install -y git ;; + linux-dnf) sudo dnf install -y git ;; + linux-pacman) sudo pacman -S --noconfirm git ;; + *) err "Cannot auto-install git on $OS — install manually"; exit 1 ;; + esac + ok "git installed" +fi + +# --- Node.js (>=18) --- +NODE_OK=false +if command -v node &>/dev/null; then + NODE_VER=$(node --version | sed 's/v//' | cut -d. -f1) + if [ "$NODE_VER" -ge 18 ]; then + ok "Node.js $(node --version)"; NODE_OK=true + else + warn "Node.js $(node --version) is too old (need >=18)" + fi +fi +if [ "$NODE_OK" = false ]; then + info "Installing Node.js 22 LTS..." + case $OS in + macos) + brew install node@22 + export PATH="/opt/homebrew/opt/node@22/bin:$PATH" + ;; + linux-apt) + curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - + sudo apt-get install -y nodejs + ;; + linux-dnf) + curl -fsSL https://rpm.nodesource.com/setup_22.x | sudo bash - + sudo dnf install -y nodejs + ;; + linux-pacman) + sudo pacman -S --noconfirm nodejs npm + ;; + *) warn "Cannot auto-install Node.js on $OS — install from https://nodejs.org" ;; + esac + command -v node &>/dev/null && ok "Node.js $(node --version)" || err "Node.js install failed" +fi + +# --- Rust + Cargo (for RTK) --- +if command -v cargo &>/dev/null; then + ok "Rust/Cargo $(cargo --version | awk '{print $2}')" +else + info "Installing Rust (rustup)..." + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path + source "$HOME/.cargo/env" + ok "Rust installed: $(cargo --version)" +fi + +# --- Python 3 --- +if command -v python3 &>/dev/null; then + ok "Python $(python3 --version)" +else + info "Installing Python 3..." + case $OS in + macos) brew install python3 ;; + linux-apt) sudo apt-get install -y python3 ;; + linux-dnf) sudo dnf install -y python3 ;; + linux-pacman) sudo pacman -S --noconfirm python ;; + *) warn "Cannot auto-install Python on $OS" ;; + esac +fi + +# --- Claude Code CLI --- +if command -v claude &>/dev/null; then + ok "Claude Code $(claude --version 2>/dev/null | head -1)" +else + err "Claude Code not installed. Install from https://code.claude.com then re-run." + exit 1 +fi + +echo "" + +# ============================================================ +# STEP 2 — GIT CLI TOOLS (gh + glab for /git-pr) +# ============================================================ +echo "── Step 2: Git CLI tools ────────────────────────────────────" +echo "" + +# --- gh (GitHub CLI) --- +if command -v gh &>/dev/null; then + ok "gh $(gh --version | head -1 | awk '{print $3}')" +else + info "Installing gh (GitHub CLI)..." + case $OS in + macos) brew install gh ;; + linux-apt) type -p curl > /dev/null || sudo apt-get install -y curl + curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list + sudo apt-get update && sudo apt-get install -y gh ;; + linux-dnf) sudo dnf install -y gh ;; + linux-pacman) sudo pacman -S --noconfirm github-cli ;; + *) warn "Cannot auto-install gh on $OS — install from https://cli.github.com" ;; + esac + command -v gh &>/dev/null && ok "gh installed" || warn "gh not installed — GitHub PRs will use API fallback" +fi + +# --- glab (GitLab CLI) --- +if command -v glab &>/dev/null; then + ok "glab $(glab --version | head -1)" +else + info "Installing glab (GitLab CLI)..." + case $OS in + macos) brew install glab ;; + linux-apt) curl -s https://raw.githubusercontent.com/profclems/glab/trunk/scripts/install.sh | sudo bash ;; + linux-dnf) sudo dnf install -y glab ;; + linux-pacman) sudo pacman -S --noconfirm glab ;; + *) warn "Cannot auto-install glab on $OS — install from https://gitlab.com/gitlab-org/cli" ;; + esac + command -v glab &>/dev/null && ok "glab installed" || warn "glab not installed — GitLab MRs will use API fallback" +fi + +warn "Gogs/Gitea: set GOGS_TOKEN or GITEA_TOKEN in your shell profile" +echo " export GOGS_TOKEN="your-token" # add to ~/.zshrc or ~/.bashrc" +echo "" + +# ============================================================ +# STEP 3 — GSTACK SUBMODULE +# ============================================================ +echo "── Step 3: GStack submodule ─────────────────────────────────" +echo "" +# Note: GStack is managed as a git submodule in this repo. +# It lives at skills-external/gstack/ and is symlinked to ~/.claude/skills/gstack/ +# by link.sh. Never clone it separately — use the submodule. +# +# First-time setup: +# git submodule update --init --recursive +# Update to latest: +# git submodule update --remote skills-external/gstack +# cd skills-external/gstack && ./setup +# git add skills-external/gstack && git commit -m "chore: update gstack" + +GSTACK_DIR="$REPO/skills-external/gstack" + +if [ ! -d "$GSTACK_DIR/.git" ] && [ ! -f "$GSTACK_DIR/.git" ]; then + info "Initializing GStack submodule..." + cd "$REPO" + git submodule update --init --recursive + cd - > /dev/null +fi + +if [ -d "$GSTACK_DIR" ]; then + info "Running GStack setup..." + cd "$GSTACK_DIR" && ./setup && cd - > /dev/null + # Ensure symlink from link.sh is in place + mkdir -p "$HOME/.claude/skills" + ln -sf "$GSTACK_DIR" "$HOME/.claude/skills/gstack" 2>/dev/null || true + ok "GStack ready at ~/.claude/skills/gstack (→ submodule)" +else + warn "GStack submodule directory not found after init — check .gitmodules" +fi + +echo "" + +# ============================================================ +# STEP 3 — RTK +# ============================================================ +echo "── Step 4: RTK — Rust Token Killer ─────────────────────────" +echo "" +if command -v rtk &>/dev/null; then + ok "rtk already installed ($(rtk --version 2>/dev/null | head -1))" +else + info "Installing RTK..." cargo install --git https://github.com/rtk-ai/rtk fi +info "Configuring RTK PreToolUse hook (global)..." rtk init -g --auto-patch - -# ---- Context7 MCP ---- +ok "RTK configured" echo "" -echo ">> Context7 MCP — manual step required:" -echo " Get a free API key at https://context7.com" -echo " Then run:" -echo " claude mcp add --scope user context7 -- npx -y @upstash/context7-mcp --api-key YOUR_KEY" -# ---- Joey Barbier plugins ---- +# ============================================================ +# STEP 4 — GSD +# ============================================================ +echo "── Step 5: GSD — get-shit-done ─────────────────────────────" echo "" -echo ">> Installing Joey Barbier plugins..." -claude plugin marketplace add joey-barbier/ClaudeCode-Plugin 2>/dev/null || true -claude plugin install review@joey-barbier-plugins 2>/dev/null || \ - echo " Warning: verify plugin name at github.com/joey-barbier/ClaudeCode-Plugin" -claude plugin install memory@joey-barbier-plugins 2>/dev/null || \ - echo " Warning: verify plugin name at github.com/joey-barbier/ClaudeCode-Plugin" +info "Installing GSD globally..." +npx get-shit-done-cc --claude --global --auto +ok "GSD installed" +echo "" + +# ============================================================ +# STEP 5 — MARKETPLACE PLUGINS (user scope, explicit) +# ============================================================ +# All claude plugin install commands use --scope user to ensure +# they install to ~/.claude/plugins/ regardless of working directory. +echo "── Step 6: Marketplace plugins (scope: user) ────────────────" +echo "" + +install_plugin() { + local name="$1" + local source="$2" + info "Installing $name..." + claude plugin install --scope user "$name@$source" 2>/dev/null \ + && ok "$name" \ + || warn "$name — skipped (already installed or failed)" +} + +# Official Anthropic (always on) +install_plugin "security-guidance" "claude-plugins-official" +install_plugin "frontend-design" "claude-plugins-official" +install_plugin "skill-creator" "claude-plugins-official" +install_plugin "pr-review-toolkit" "claude-plugins-official" echo "" -echo "=== Done! Restart Claude Code to activate all plugins. ===" + +# Superpowers (always on) +info "Adding Superpowers marketplace..." +claude plugin marketplace add obra/superpowers-marketplace 2>/dev/null || true +install_plugin "superpowers" "superpowers-marketplace" + echo "" -echo "Plugins installed (marketplace-managed, not committed to git):" -echo " - security-guidance (Anthropic official)" -echo " - frontend-design (Anthropic official)" -echo " - skill-creator (Anthropic official)" -echo " - pr-review-toolkit (Anthropic official)" -echo " - superpowers (obra/superpowers)" -echo " - ui-ux-pro-max (nextlevelbuilder)" -echo " - gsd (glittercowboy)" -echo " - rtk (rtk-ai, system binary + hook)" + +# UI/UX Pro Max (toggle) +info "Adding UI/UX Pro Max marketplace..." +claude plugin marketplace add nextlevelbuilder/ui-ux-pro-max-skill 2>/dev/null || true +install_plugin "ui-ux-pro-max" "ui-ux-pro-max-skill" + +echo "" + +# ============================================================ +# STEP 6 — CONTEXT7 MCP (manual — requires API key) +# ============================================================ +echo "── Step 7: Context7 MCP ─────────────────────────────────────" +echo "" +if claude mcp list 2>/dev/null | grep -q "context7"; then + ok "Context7 MCP already configured" +else + warn "Context7 requires a free API key — cannot auto-install" + echo "" + echo " Steps:" + echo " 1. Get a free key at https://context7.com" + echo " 2. Run:" + echo " claude mcp add --scope user context7 -- \\" + echo " npx -y @upstash/context7-mcp --api-key YOUR_KEY" + echo "" +fi + +# ============================================================ +# SUMMARY +# ============================================================ +echo "" +echo "╔══════════════════════════════════════════════════════════╗" +echo "║ Install Summary ║" +echo "╚══════════════════════════════════════════════════════════╝" +echo "" +echo " ALWAYS ON (installed at user scope, ~10 tokens/session each):" +echo " ✅ security-guidance — PreToolUse security hook (0 tokens)" +echo " ✅ rtk — token compression hook (0 tokens)" +echo " ✅ superpowers — brainstorm/plan/implement/debug workflow" +echo " ✅ skill-creator — create skills from conversation" +echo " ✅ pr-review-toolkit — /pr-review-toolkit:review-pr" +echo "" +echo " TOGGLE (installed but start OFF — /plugin-check recommends when needed):" +echo " 🔄 gstack — ~/.claude/skills/gstack/ (→ submodule)" +echo " 🔄 gsd — ~/.claude/skills/ (npx)" +echo " 🔄 frontend-design — user scope" +echo " 🔄 ui-ux-pro-max — user scope" +echo " 🔄 context7 MCP — see Step 6 above" +echo "" +echo " All plugins installed at: user scope (~/.claude/plugins/)" +echo " GStack at: ~/.claude/skills/gstack/ (symlink → submodule)" +echo "" +echo " → Authenticate: gh auth login (GitHub) / glab auth login (GitLab)" +echo " → Restart Claude Code" +echo " → Run /reload-plugins" echo "" -echo "Skills committed to git (available without reinstall):" -echo " ~/.claude/skills/gstack (garrytan)" diff --git a/link.sh b/link.sh index 39e5b5d..7897587 100644 --- a/link.sh +++ b/link.sh @@ -14,12 +14,22 @@ ln -sf "$REPO/CLAUDE.md" "$CLAUDE/CLAUDE.md" ln -sf "$REPO/settings.json" "$CLAUDE/settings.json" # Agents and skills -ln -sf "$REPO/agents" "$CLAUDE/agents" -ln -sf "$REPO/skills" "$CLAUDE/skills" +ln -sf "$REPO/agents" "$CLAUDE/agents" +ln -sf "$REPO/skills" "$CLAUDE/skills" # Hooks mkdir -p "$CLAUDE/hooks" ln -sf "$REPO/hooks/session-start.sh" "$CLAUDE/hooks/session-start.sh" +# GStack (submodule) — symlink from skills-external/ into ~/.claude/skills/ +# The submodule must be initialized first (done by install-plugins.sh) +mkdir -p "$CLAUDE/skills" +if [ -d "$REPO/skills-external/gstack" ]; then + ln -sf "$REPO/skills-external/gstack" "$CLAUDE/skills/gstack" + echo "✅ GStack symlinked from submodule" +else + echo "⚠️ GStack submodule not found — run: git submodule update --init" +fi + echo "✅ Symlinks created in ~/.claude/" -echo " Run: bash install-plugins.sh" +echo " Next: bash install-plugins.sh" diff --git a/skills/git-pr/SKILL.md b/skills/git-pr/SKILL.md new file mode 100644 index 0000000..96aaefc --- /dev/null +++ b/skills/git-pr/SKILL.md @@ -0,0 +1,15 @@ +--- +name: git-pr +description: Analyze all changes on the current branch since it diverged from base (retroactive across sessions), create logical commits, push, and open a draft PR/MR. Works with GitHub, GitLab, Gogs, and Gitea. Never merges — creates a draft for user validation. +argument-hint: [PR title or leave empty for auto-detection] +disable-model-invocation: true +allowed-tools: Read, Bash, Grep, Glob +--- + +Load and follow strictly: +- .claude/agents/git-workflow.md + +Execute the GIT WORKFLOW on the current repository. + +User context (optional title or instructions): +$ARGUMENTS diff --git a/skills/init-project/SKILL.md b/skills/init-project/SKILL.md index 825b522..6d062f5 100644 --- a/skills/init-project/SKILL.md +++ b/skills/init-project/SKILL.md @@ -35,7 +35,42 @@ $ARGUMENTS --- -### STEP 0 — PLUGIN CHECK +### STEP 0a — BRANCH SETUP + +Load the BRANCH SETUP section from: `.claude/agents/git-workflow.md` + +Before anything else, ensure we are NOT on a protected branch. + +```bash +git branch --show-current +``` + +**If on `main`, `master`, `develop`, or any protected branch:** + +Derive a branch slug from the initial request: +- Take the first 3–4 meaningful words +- Lowercase, hyphen-separated +- Max 50 chars + +```bash +git fetch origin +git pull origin --ff-only 2>/dev/null || true +git checkout -b feature/ +``` + +Print: `✅ Working branch created: feature/` + +**If already on a feature branch:** +Run the CONFLICT-SAFE REBASE procedure from git-workflow.md +to sync with main before starting. + +Print: `✅ Branch: (synced with main)` + +**Do not proceed until the branch is clean and ready.** + +--- + +### STEP 0b — PLUGIN CHECK Load and follow: `.claude/agents/plugin-advisor.md` @@ -53,7 +88,7 @@ B) Type "force" to proceed without them ================================================================ ``` **STOP. Wait for user response.** -- Re-run → restart from STEP 0 +- Re-run → restart from STEP 0b - "force" → note missing plugins, continue to STEP 1 **If `ACTION REQUIRED: NO`:** @@ -306,7 +341,8 @@ SYNC mode — no stop required. The readme-updater: ## RULES -- Never skip STEP 0 — plugin check is mandatory. +- Never skip STEP 0a — branch setup is mandatory. Never commit on main/master. +- Never skip STEP 0b — plugin check is mandatory. - Never skip STEP 1 — no assumptions about missing info. - Never implement without explicit user approval at STEP 4. - Never implement without explicit user approval at STEP 7. diff --git a/skills/ship-feature/SKILL.md b/skills/ship-feature/SKILL.md index 55ffffa..4e4e34c 100644 --- a/skills/ship-feature/SKILL.md +++ b/skills/ship-feature/SKILL.md @@ -33,7 +33,48 @@ $ARGUMENTS --- -### STEP 0 — PLUGIN CHECK (mandatory gate) +### STEP 0a — BRANCH SETUP + +Load the BRANCH SETUP section from: `.claude/agents/git-workflow.md` + +```bash +git branch --show-current +``` + +**If on `main`, `master`, `develop`, or any protected branch:** + +Derive a branch slug from the feature request: +- Take the first 3–4 meaningful words from $ARGUMENTS +- Lowercase, hyphen-separated, max 50 chars +- Prefix with `feature/` + +```bash +git fetch origin +git pull origin --ff-only 2>/dev/null || true +git checkout -b feature/ +``` + +Print: `✅ Working branch created: feature/` + +**If already on a feature/bugfix/hotfix branch:** +Run the CONFLICT-SAFE REBASE procedure from git-workflow.md +to sync with the base branch before implementing. + +Print: `✅ Branch: (synced)` + +**Special case — bugfix on a feature branch:** +If the user explicitly says "bugfix" or "fix" in the request AND +the current branch is a feature branch: +```bash +git checkout -b bugfix/ +``` +Creates the bugfix branch FROM the feature branch — correct hierarchy. + +**Do not proceed until the branch is clean.** + +--- + +### STEP 0b — PLUGIN CHECK (mandatory gate) Load and follow: `.claude/agents/plugin-advisor.md` @@ -64,7 +105,7 @@ Options: ``` Wait for user response. -- If user re-runs `/ship-feature` → start from STEP 0 again +- If user re-runs `/ship-feature` → start from STEP 0a again - If user types "force" → note missing plugins and continue to STEP 1 **If the advisor output says `ACTION REQUIRED: NO`:** @@ -157,9 +198,40 @@ SYNC mode — no stop required. The readme-updater: --- +### STEP 9 — CREATE PR (optional gate) + +Ask the user: +``` +================================================================ +SHIP FEATURE — PR CREATION +================================================================ +Feature is implemented, tested, and README is synced. + +Create a PR/MR now? + yes → run /git-pr and open a draft PR + no → stop here, you can run /git-pr manually later +================================================================ +``` + +**STOP — wait for user response.** + +IF yes: + Load and follow: `.claude/agents/git-workflow.md` + The git-workflow agent will: + - Show all changes since branch start (retroactive) + - Propose a commit plan for approval + - Push and create a draft PR/MR on GitHub/GitLab/Gogs/Gitea + +IF no: + Print: `✅ Feature shipped. Run /git-pr when ready to open a PR.` + Stop. + +--- + ## RULES -- Never skip STEP 0 — plugin check is mandatory. +- Never skip STEP 0a — branch setup is mandatory. Never implement on main/master. +- Never skip STEP 0b — plugin check is mandatory. - Never skip brainstorming. - Never implement without explicit user approval of the plan. - Keep subagents isolated — no shared context between tasks.