CLAUDE CODE — Plugins | Team management in the AI Era -5 Final
Everyone who works with Claude Code faces a problem sooner or later: as the project grows, CLAUDE.md, agents, skills, hooks, and MCP…
CLAUDE CODE — Plugins | Team management in the AI Era -5 Final

Everyone who works with Claude Code faces a problem sooner or later: as the project grows, CLAUDE.md, agents, skills, hooks, and MCP definitions turn into a messy, unrepeatable pile specific to only one project. When you move to a new project, you either set up everything from scratch or copy-paste from the old project. The plugin system exists exactly to solve this problem.
What is a Plugin?
In Claude Code, a plugin is a structure that collects multiple extension mechanisms (agents, skills, hooks, MCP server definitions, slash commands) under a single folder into a versionable and distributable package.
What separates a plugin from a classic “prompt template” is that it is a behavior package. It contains not just text, but also code triggered at runtime (hooks), isolated working areas (agent isolation), and gates opening to the outside world (MCP).
Why do you need a plugin when working with a real team?
- a) The Consistency Problem: Five different agents all need to know the same rules, like “use Clean Architecture,” “do not use state management other than
flutter_bloc," and "do not make direct requests to 3rd party APIs from the client." If you write this into every agent file separately, you have to update it in five places when a rule changes. In a plugin, these rules are kept centrally underCLAUDE.mdand sharedskills/. - b) The Context Bloat Problem: If a “manager” agent tries to do all the work in its main context, Flutter code + Firestore schema + design decisions + security findings all pile up in the same context window, and token costs explode. The
isolation: worktreefeature of Agent Teams allows expert agents to work in their isolated git worktree copies and return only the result to the manager — just like in a real team, where an engineer shares only the PR summary, not the process details. - c) The Portability Problem: Today you set up this team structure in one project, and tomorrow you want to use the same team in another Flutter project. Ad-hoc setup is open to copy-paste and synchronization errors. A plugin becomes portable to another project with a single command using
claude /plugin marketplace addandclaude /plugin install.
In short: a plugin is not necessary for a single agent + single project; but when multiple agents + repeatable rules + multiple projects are involved, a plugin becomes the only practical solution to prevent chaos.
What does cross-mobil-team-plugin do?
This plugin simulates an end-to-end team for Flutter mobile development. It enforces Clean Architecture as the architectural standard, only flutter_bloc (Cubit/BLoC) for state management, and the Firebase Cloud Functions proxy pattern for backend access (the client never sees the 3rd party API key).

Team Structure: Manager + Teammate Model
The most notable part of this package is that it uses Claude Code’s experimental Agent Teams feature (CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1). When this mode is active, agents can take on different roles relative to each other:
- Manager (
mobile-lead): Stays in the main conversation thread, talks directly with the user, and distributes tasks to experts. - Teammates (the other 5 agents): Do the work in their isolated working areas (
isolation: worktree) and return the result to the manager — without bloating the manager's main context.
Every agent file has two fields defining this in its frontmatter:

**isolation:**none/worktree.nonemeans the agent works in the main context (onlymobile-lead).worktreemeans the agent works isolated in its own git worktree copy and returns the result.**memory:**project/task.projectmeans memory lasts throughout the project (onlymobile-lead).taskmeans memory is specific only to that task and resets when the task finishes.
These two fields are not included in Claude Code’s official static documentation yet — it is an experimental feature. When CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS is turned off, these fields remain as harmless extra frontmatter, and the agents continue to work normally. So, this plugin makes a design choice that both actively uses the experimental feature and is backward-compatible.
mobile-lead does not write code itself. It analyzes the request, delegates it to the right expert, and reviews the delivered work against Clean Architecture/flutter_bloc/Cloud Functions-proxy rules. The delegation map is clear: Flutter code ➔ flutter-developer, Firebase/backend ➔ backend-engineer, design ➔ ui-ux-designer, security ➔ security-engineer, ASO ➔ aso-marketing.
Skills: Shared Expertise Library
The domain knowledge every agent needs is kept in separate SKILL.md files instead of being embedded inside the agent file. For example, the clean-architecture skill looks like this:
features/<feature_name>/
├── domain/
│ ├── entities/ # Framework-independent plain Dart classes
│ ├── repositories/ # Abstract interfaces only
│ └── usecases/ # Single-responsibility classes with a single `call()` method
├── data/
│ ├── models/ # DTOs, fromJson/toJson
│ ├── datasources/ # Remote (Cloud Functions/Firestore) and local (cache)
│ └── repositories/ # Implements domain interfaces
└── presentation/
├── cubit/ or bloc/
├── pages/
└── widgets/
Other skills include: flutter-bloc-cubit (Cubit/BLoC selection rules, bloc_test patterns), firebase-cloud-functions (2nd gen Cloud Functions, proxy pattern, Firestore schema+rules), design-system, mobile-security-review (OWASP MASVS based checklist), and aso-keyword-research (including App Store character limits).
Hooks: Token Savings and Architectural Discipline Automation
Hooks in this package serve two different purposes: reducing token costs and automatically checking architectural rules. Five hooks are defined inside hooks/hooks.json:
{
"hooks": {
"SessionStart": [{ "hooks": [{ "type": "command", "command": "echo '...' >&2" }] }],
"PreToolUse": [
{
"matcher": "Read",
"hooks": [{ "type": "command", "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/token-savings/large-file-read-guard.sh\"" }]
}
],
"PostToolUse": [
{
"matcher": "Edit|Write|MultiEdit",
"hooks": [{ "type": "command", "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/layer-violation-check.sh\"" }]
},
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/token-savings/bash-output-summarizer.sh\"" },
{ "type": "command", "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/pre-commit-secret-scan.sh\"", "if": "Bash(git commit:*)" }
]
}
],
"Stop": [{ "hooks": [{ "type": "command", "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/token-savings/session-cost-log.sh\"" }] }]
}
}
Let’s look closely at two hooks:
1. large-file-read-guard.sh: This triggers when an agent tries to read a 500+ line file without giving a limit parameter:
LINE_COUNT=$(wc -l < "$FILE_PATH" 2>/dev/null || echo 0)
if [[ "$LINE_COUNT" -gt 500 && "$LIMIT_SET" == "False" ]]; then
echo "This file has $LINE_COUNT lines. Instead of loading all of it into context, read it piece by piece with offset/limit, or search targeted with Grep." >&2
exit 2
fi
exit 2 is critical here: it stops the tool call and feeds the message back to the agent. The agent can then change its strategy in the next attempt. This is a simple but effective way to work with large files without bloating the context window.
2. layer-violation-check.sh: When a .dart file is edited, if the file is under presentation/ and directly imports the data/ module, it gives a warning:
if [[ "$FILE_PATH" == *"/presentation/"* ]]; then
if grep -qE "^\s*import\s+'.*\/data\/" "$FILE_PATH"; then
echo "Warning: $FILE_PATH (presentation) directly imports a 'data/' module. In Clean Architecture, presentation must only depend on domain." >&2
exit 2
fi
fi
This turns the architectural rule from a simple “please don’t do this” prompt instruction into an automated rule checked after every edit.
The other two hooks focus on token cost: bash-output-summarizer.sh writes the full log under .claude/logs/ when the output of commands like flutter test or flutter analyze exceeds 80 lines, and returns only a summary containing error/fail/warning lines to the context. session-cost-log.sh adds a timestamp to the .claude/logs/session-cost.log file at the end of the session to provide minimal cost awareness.
MCP Servers
.mcp.json defines three servers:
{
"context7": { "type": "http", "url": "https://mcp.context7.com/mcp" },
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": { "Authorization": "Bearer ${GITHUB_TOKEN}" }
},
"firebase": {
"type": "stdio",
"command": "npx",
"args": ["-y", "firebase-tools@latest", "experimental:mcp"],
"env": { "GOOGLE_APPLICATION_CREDENTIALS": "${FIREBASE_SERVICE_ACCOUNT_PATH}" }
}
}
**context7:** Up-to-date access to Flutter/Dart package documentation (model knowledge can be old/deprecated); main users areflutter-developerandbackend-engineer. No authentication required.**github:** PR/issue workflow; main user ismobile-lead. RequiresGITHUB_TOKEN.**firebase:** Access to Firestore, Cloud Functions, Auth, Remote Config, and Crashlytics; main user isbackend-engineer.security-engineeruses it only for reading purposes (to inspect Firestore rules). RequiresFIREBASE_SERVICE_ACCOUNT_PATH.
5. Installation: Step by Step
Installation is done from the parent directory containing the plugin folder; not from the folder itself.
# 1) Add the plugin to Claude Code as a local marketplace.
# <path-to-parent> = the parent directory CONTAINING this folder (not the folder itself).
claude /plugin marketplace add <path-to-parent>
claude /plugin install cross-mobil-team-plugin
# 2) Activate the Agent Teams feature for this project.
# This creates .claude/settings.json in the project root (backup your existing file if available).
mkdir -p .claude
cat > .claude/settings.json <<'EOF'
{
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
},
"teammateMode": "auto"
}
EOF
# 3) Define environment variables required by MCP servers.
# Add real values to your shell profile (.zshrc/.bashrc) or an .env manager,
# never commit them to the repo.
export GITHUB_TOKEN="ghp_xxx..." # For GitHub MCP
export FIREBASE_SERVICE_ACCOUNT_PATH="/path/to/service-account.json" # For Firebase MCP
# 4) Make sure hook scripts are executable
# (permissions can sometimes reset when the repo is cloned).
chmod +x hooks/*.sh hooks/token-savings/*.sh
# 5) Verify the installation: open a new chat in Claude Code and type:
# @mobile-lead hello, introduce the team
Ready-made .sh file for installation:
#!/usr/bin/env bash
set -euo pipefail
claude /plugin marketplace add "$(pwd)"
claude /plugin install cross-mobil-team-plugin
mkdir -p .claude
cat > .claude/settings.json <<'SETTINGS'
{
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
},
"teammateMode": "auto"
}
SETTINGS
export GITHUB_TOKEN="ghp_xxx..."
export FIREBASE_SERVICE_ACCOUNT_PATH="/path/to/service-account.json"
chmod +x cross-mobil-team-plugin/hooks/*.sh cross-mobil-team-plugin/hooks/token-savings/*.shFinal
Final
With this article, we complete our five-part series: starting from subagents, expanding to Agent Teams, opening to the outside world with MCP, gaining discipline with hooks, and finally gathering everything into a single package with plugins. The cross-mobil-team-plugin repository became a live example showing how all these five parts work together in a real Flutter project.
Thank you for reading — if you have any questions or experiences with your own plugin setups, let’s meet in the comments.
github: https://github.com/OnyxUP/cross-mobil-team-plugin linkedin: https://www.linkedin.com/in/haliilylmaaz/
메타데이터
- post_id
- 2ee87aea6691
- slug
- claude-code-plugins-team-management-in-the-ai-era-5-final-2ee87aea6691
- url
- https://medium.com/@haliilylmaaz/claude-code-plugins-team-management-in-the-ai-era-5-final-2ee87aea6691
- canonical_url
- https://medium.com/@haliilylmaaz/claude-code-plugins-team-management-in-the-ai-era-5-final-2ee87aea6691
- author_url
- https://medium.com/@haliilylmaaz
- status
- ok
- fetched_at
- 2026-07-08 18:29:56