---
description: "Select the active stack(s) for this repo by enabling the matching marketplace plugin(s) in .claude/settings.json. Multi-select: pass several stacks (ios backend) or pick them in the native picker. Use when a repo's stack changed or the wrong plugins are enabled for it."
description-tr: "Bu repo için aktif stack'leri seçer: eşleşen marketplace plugin'lerini .claude/settings.json'da etkinleştirir. Çoklu seçim: birden fazla stack yazılabilir (ios backend) ya da native picker'dan seçilir."
argument-hint: "[ios|android|frontend|web|backend|mobile|fullstack|all ...]"
allowed-tools: Bash, Read, Edit, Write, AskUserQuestion
---

# multi-agent stack  -  Select Stack(s) via Plugin Enablement

Stack skills ship as plugins in the `{owner}/multi-agent-plugins` marketplace. Selecting a stack = **enabling the matching plugin(s)** in the current repo's `.claude/settings.json` `enabledPlugins`. Two toolkits are stack-independent and always enabled alongside the stack plugin(s): `ai-common-toolkit` (accessibility audit, humanizer, Firebase) and `ai-analyst-toolkit` (GitHub and package-registry evidence, community signal for analysis work).

On Claude Code the marketplace plugins are the ONLY source of stack skills - nothing is copied into `~/.claude/skills` anymore. A stack that is not enabled here is simply absent from the session. Copilot CLI and Codex CLI have no plugin loader; they receive a local copy filtered to the enabled stacks at install time, which is why step 5 below offers to refresh those copies after a change.

This replaces the old `stack-swap.sh` mechanic that physically moved skill directories in `~/.claude/skills/`. There is no SessionStart hook and no directory shuffling - enablement is declarative, per-repo, and versioned.

## Usage

```bash
/multi-agent:stack                 # no arg → native multi-select picker (current state pre-noted)
/multi-agent:stack ios             # SwiftUI toolkit + common
/multi-agent:stack ios backend     # any combination, space-separated
/multi-agent:stack android         # Compose toolkit + common
/multi-agent:stack mobile          # alias: ios + android + common
/multi-agent:stack backend         # Python / Node spec-driven toolkit + common
/multi-agent:stack frontend        # React / TSX toolkit + common (alias: web)
/multi-agent:stack fullstack       # alias: frontend + backend + common
/multi-agent:stack all             # all four stack toolkits + common
```

## Stack → plugin map

| Stack | Plugins enabled (all `@multi-agent-plugins`) |
|---|---|
| `ios` | `ai-common-toolkit`, `ai-analyst-toolkit`, `ai-ios-toolkit` |
| `android` | `ai-common-toolkit`, `ai-analyst-toolkit`, `ai-android-toolkit` |
| `frontend` / `web` | `ai-common-toolkit`, `ai-analyst-toolkit`, `ai-frontend-toolkit` |
| `backend` | `ai-common-toolkit`, `ai-analyst-toolkit`, `ai-backend-toolkit` |
| `mobile` | common + `ai-ios-toolkit` + `ai-android-toolkit` |
| `fullstack` | common + `ai-frontend-toolkit` + `ai-backend-toolkit` |
| `all` | common + all four stack toolkits |

Multiple args union their plugin sets: `ios backend` → common + iOS + backend.

## Behaviour

1. **No arg → native multi-select picker.** Read `.claude/settings.json` (repo) + `~/.claude/settings.json` (global) to learn the current state, then ask with `AskUserQuestion` (`multiSelect: true`) - NEVER a numbered text menu:
   - `question` (in `outputLanguage`): which stacks should be active in this repo, noting the currently enabled ones
   - `header`: "Stacks" (English, UI contract)
   - `options` (4): `ios` / `android` / `frontend (web)` / `backend`, each `description` (in `outputLanguage`) naming the plugin it enables and marking the ones already enabled with "(currently on)" / "(şu an açık)"
   - Map each selected label back to its canonical arg before step 2: the token before any parenthesis (`frontend (web)` → `frontend`).
   - Empty selection or cancel → **status mode**: print the currently enabled `@multi-agent-plugins` plugins and exit without modifying anything. Status mode never runs the Implementation block below - that block is enable-mode only.
2. **Arg(s) present → enable mode.** Accept multiple space-separated stacks. Resolve each through the alias table (`web`→`frontend`, `mobile`→`ios android`, `fullstack`→`frontend backend`, `all`→every stack), union the plugin sets, then write the **current repo's** `.claude/settings.json`.
3. **Write rules:**
   - every plugin in the union is set to `true`
   - every stack toolkit **not** in the union is set to `false` (leave non-`@multi-agent-plugins` entries untouched)
   - `ai-common-toolkit@multi-agent-plugins` and `ai-analyst-toolkit@multi-agent-plugins` are always `true`
   - **legacy-key cleanup**: delete any `ai-*-engineering-toolkit@multi-agent-plugins` keys - those plugin names were retired by the `ai-<stack>-toolkit` rename and a stale `true` there enables a plugin that no longer exists in the marketplace
4. **Unknown arg** → show the table above; do not guess.
5. **Copilot/Codex refresh offer.** Their local skill copies are filtered to the enabled stacks at install time, so after a change ask (single `AskUserQuestion`, not silent): "Refresh Copilot/Codex local copies now?" - Yes runs `node <pipelineRepo>/install.js --copilot --codex`, No leaves them stale with a one-line warning naming the command to run later. Skip this question entirely when neither `~/.copilot` nor `~/.codex` exists.

## Implementation

```bash
REPO_SETTINGS=".claude/settings.json"
MP="multi-agent-plugins"

# --- ensure the marketplace is known (idempotent) -------------------------
if ! claude marketplace list 2>/dev/null | grep -q "$MP"; then
  claude marketplace add {owner}/multi-agent-plugins 2>/dev/null \
    || echo "note: add the marketplace once with: claude marketplace add {owner}/multi-agent-plugins"
fi

COMMON="ai-common-toolkit@${MP}"
ANALYST="ai-analyst-toolkit@${MP}"
IOS="ai-ios-toolkit@${MP}"
ANDROID="ai-android-toolkit@${MP}"
FRONTEND="ai-frontend-toolkit@${MP}"
BACKEND="ai-backend-toolkit@${MP}"

# Enable-mode only: with zero args the write rules below would set every stack
# toolkit to false (nothing but the always-on pair is in $ON), silently wiping the repo's
# selection. No args belongs to the picker / status path (Behaviour step 1).
if [ "$#" -eq 0 ]; then
  echo "No stack given - nothing changed. Pass stacks (ios backend ...) or use the picker."
  exit 0
fi

# resolve every arg through the alias table, union the ON set
ON="$COMMON $ANALYST"
for ARG in "$@"; do
  case "$ARG" in
    ios)              ON="$ON $IOS" ;;
    android)          ON="$ON $ANDROID" ;;
    frontend|web)     ON="$ON $FRONTEND" ;;
    "frontend (web)") ON="$ON $FRONTEND" ;;
    backend)          ON="$ON $BACKEND" ;;
    mobile)           ON="$ON $IOS $ANDROID" ;;
    fullstack)        ON="$ON $FRONTEND $BACKEND" ;;
    all)              ON="$ON $IOS $ANDROID $FRONTEND $BACKEND" ;;
    *) echo "Unknown stack '$ARG'. One of: ios android mobile backend frontend web fullstack all"; exit 1 ;;
  esac
done
```

After resolving `$ON`, edit `.claude/settings.json` (create `{ "enabledPlugins": {} }` if absent) so that:
- every plugin in `$ON` is set to `true`,
- every stack toolkit **not** in `$ON` is set to `false` (leave non-`@multi-agent-plugins` entries untouched),
- `ai-common-toolkit@multi-agent-plugins` and `ai-analyst-toolkit@multi-agent-plugins` are always `true`,
- every `ai-*-engineering-toolkit@multi-agent-plugins` key is **deleted** (retired names).

Use the Read + Edit/Write tools (JSON must stay valid). Then print the resulting `enabledPlugins` block and run step 5 (Copilot/Codex refresh offer).

## Notes

- Enablement is per-repo and declarative - commit `.claude/settings.json` so teammates get the same stack.
- Restart the conversation (or reload the window) for Claude Code to pick up newly enabled plugins.
- Pipeline Phase 1 stack detection is independent (it reads project files); `stack` only sets which plugin skill set is active.
- The old `stack-swap.sh` skill-dir swap has been removed; stack selection is entirely plugin enablement.
