Documentation
Complete guide to setting up and using the CUITE framework.
Prerequisites
Before installing CUITE, make sure you have the following tools available on your system:
- Claude Code CLI — the Anthropic command-line interface for Claude. CUITE orchestrates agents through Claude Code, so this is the primary runtime dependency.
- Git — used for subtree management. CUITE lives inside your repository as a git subtree at
.claude/cuite/, and all updates are pulled and pushed through git. - A project repository — CUITE attaches to an existing git repository. It does not create one for you. Initialize your repo first, then install CUITE into it.
Installation
Run the one-liner from your project root:
curl -fsSL https://cuite.quest/install.sh | bash
Or do it manually:
cd /path/to/your-project
git clone https://github.com/fentas/cuite.git /tmp/cuite
/tmp/cuite/bin/cuite init
rm -rf /tmp/cuite
Both methods do the same thing: clone cuite to a temp directory, run cuite init (which uses git subtree add to embed the framework at .claude/cuite/), and clean up.
Here is what the init command does under the hood:
- Adds a git remote named
cuitepointing to the CUITE repository. - Creates the subtree at
.claude/cuite/usinggit subtree add. - Sets up symlinks so Claude Code can find hooks, commands, and agent definitions in the locations it expects (directly under
.claude/). - Copies starter files such as
CLAUDE.md,settings.json, and template domain files into your project root and.claude/directory.
CLAUDE.md or settings.json, CUITE will skip those files and let you merge manually.
direnv Setup (optional)
If you use direnv, you can add cuite to your PATH automatically:
.claude/cuite/bin/cuite envrc
direnv allow
This creates or updates your .envrc so you can run cuite directly instead of .claude/cuite/bin/cuite. The /cuite-init command will also offer to set this up for you.
First Run
After installation, open Claude Code in your project and run the initialization command:
/cuite-init
This command triggers a full project scan. Here is what happens:
- Language detection — scans file extensions, package manifests, and build files to identify the languages and frameworks used in your project.
- Sub-project discovery — looks for monorepo patterns, separate build roots, and isolated dependency trees.
- Domain proposal — based on the scan results, CUITE proposes a set of domains (e.g.,
backend,frontend,infra) and presents them for your approval. - Configuration generation — on approval, generates
domains.md,domain-map.conf, and starter expertise files for each domain under.claude/agents/experts/.
/cuite-init at any time. It will detect new sub-projects and propose additional domains without overwriting your existing configuration.
Hybrid Layout
CUITE uses a hybrid architecture combining a git subtree for the framework itself with symlinks that bridge into the locations Claude Code expects. Your project-specific files live outside the subtree and are never touched by framework updates.
project/
CLAUDE.md # customized from template
.claude/
cuite/ # git subtree (framework)
hooks -> cuite/hooks # symlink
commands -> cuite/commands # symlink
agents/
*.md -> cuite/agents/*.md # symlinks
templates -> cuite # symlink
experts/
your-domain/ # YOUR files (never pushed)
settings.json # YOUR file
domains.md # YOUR file
domain-map.conf # YOUR file
The key insight is separation of concerns: the framework code travels via subtree, your domain expertise stays local, and symlinks make everything discoverable by Claude Code without any path hacks.
File Categories
Every file in the CUITE installation falls into one of three categories:
| Category | Location | Updated By |
|---|---|---|
| Framework | Inside .claude/cuite/ |
Updated by cuite pull |
| Project-specific | .claude/ (real files) |
Updated by you |
| Symlinks | .claude/ → .claude/cuite/ |
Refreshed by cuite link |
This three-tier approach means you can pull framework updates without worrying about your settings, domains, or expertise files being overwritten. The subtree boundary acts as a clean firewall between framework code and project-specific configuration.
Why This Works
Each architectural concern maps to a specific solution:
| Concern | Solution |
|---|---|
| Push only framework code | Subtree prefix isolates .claude/cuite/ from everything else |
| Claude Code finds hooks | Symlinks bridge .claude/hooks → .claude/cuite/hooks |
| Your settings stay yours | Real files live outside the subtree at .claude/settings.json |
| Domain experts are yours | Real directories under .claude/agents/experts/ |
| Hooks resolve paths correctly | All hook scripts use $PWD for path resolution |
domains.md
The primary domain registry lives at .claude/domains.md. This file is the single source of truth for what domains exist in your project, what they contain, and how to work with them. Every ## heading in this file defines one domain.
Commands like /do, /do-teams, and /improve read this file first when deciding which domain to target. The file uses a structured markdown format:
## backend
- **Description**: Express API server
- **Keywords**: API, endpoint, route, middleware
- **Paths**: `src/api/`, `src/server/`
- **Language**: TypeScript
- **Build**: `npm run build`
- **Test**: `npm test`
Each field serves a specific purpose:
- Description — a one-line summary that helps agents understand the domain's role in the project.
- Keywords — terms used for fuzzy matching when
/dotries to route a task to the right domain. If your task mentions "endpoint", it matches "backend" through this keyword list. - Paths — directories and file globs that belong to this domain. Used for scope enforcement and file ownership during parallel team work.
- Language — the primary language, which helps agents select the right linters, test runners, and build tools.
- Build / Test — the exact commands to build and test this domain. Agents use these directly; no guessing.
domain-map.conf
The domain map at .claude/domain-map.conf provides glob-to-domain mappings used by hooks for fast path-based domain resolution. This is the second lookup method after domains.md keywords.
Format: one mapping per line, pattern = domain.
src/api/* = backend
src/ui/* = frontend
.github/* = devops
infra/* = infrastructure
docs/* = documentation
*.proto = backend
Hooks use this file to determine which domain a file belongs to without parsing the full domains.md. This makes scope enforcement fast, even in large monorepos with hundreds of files.
* matches within one directory level. To match deeply nested files, use patterns like src/api/**.
experts/ Directory
Each domain gets its own directory at .claude/agents/experts/{domain}/. This directory contains all the knowledge and agent definitions specific to that domain.
A fully populated domain directory contains:
- tips.md — quick operational facts. Short, dense, injected first into every agent spawn. Think "cheat sheet" rather than "documentation".
- expertise.yaml — deep domain knowledge in structured YAML format. Contains patterns, anti-patterns, critical paths, known issues, and architectural decisions.
- {domain}-plan-agent.md — agent definition for the planning phase.
- {domain}-build-agent.md — agent definition for the implementation phase.
- {domain}-improve-agent.md — agent definition for the expertise improvement phase.
- {domain}-question-agent.md — agent definition for answering questions about the domain.
These files are never pushed to the CUITE framework repository. They are your project-specific knowledge and stay entirely within your project.
Domain Discovery
When a command needs to determine which domain to target, CUITE uses a 4-step fallback chain:
- Read
domains.md— match the task description against domain keywords and paths. This is the primary and most reliable method. - Read
domain-map.conf— match file path globs when the task references specific files. Fast and deterministic. - Scan
experts/directory — check which domain directories exist and inspect theirexpertise.yamlfor additional matching signals. - Fallback — if no domain matches, use the generic
build-agentfor implementation tasks or ask the user to clarify.
This layered approach means CUITE can always find the right domain, even if your configuration is incomplete. The fallback chain degrades gracefully rather than failing.
Core Agents
CUITE ships with three core agents that handle cross-domain work. These are not tied to any specific domain and can operate on any part of the codebase.
| Agent | Access | Purpose |
|---|---|---|
| build-agent | Full (Read/Write/Edit/Bash) | General-purpose implementation. Used as the fallback when no domain-specific agent matches. |
| scout-agent | Read-only | Codebase exploration and research. Reads files, searches patterns, maps dependencies. Cannot modify anything. |
| review-agent | Read-only + Task | Code review and quality gate. Analyzes implementations, checks for issues, and produces structured review reports. |
Core agents are defined in .claude/agents/ as symlinks to their framework definitions in .claude/cuite/agents/. They receive the same expertise injection as domain agents when the hook can determine which domain is relevant.
Domain Agents
For each domain, CUITE creates four specialized agents. These agents are scoped to a single domain and receive that domain's expertise on every spawn.
| Agent | Role | Description |
|---|---|---|
| {domain}-plan-agent | Planner | Read-only access. Analyzes the task, reads relevant code, and produces a detailed implementation spec. Does not write any code. |
| {domain}-build-agent | Builder | Full access. Takes the spec from the plan agent and implements it. Writes code, runs builds, executes tests. |
| {domain}-improve-agent | Improver | Read + Edit on expertise files only. Reviews what was built and learned, then updates tips.md and expertise.yaml. |
| {domain}-question-agent | Answerer | Read-only access. Answers questions about the domain using codebase context and expertise files. Fast and cheap. |
Agent definitions live at .claude/agents/experts/{domain}/ and are generated from templates during /cuite-init. You can customize them freely — they are your project files.
Models & Access
Different agent types use different models based on their complexity requirements and cost profile:
| Agent Type | Model | Access Level |
|---|---|---|
| plan-agent | sonnet | Read-only |
| build-agent | sonnet | Full (Read/Write/Edit/Bash) |
| improve-agent | sonnet | Read + Edit expertise files |
| question-agent | haiku (fast, cheap) | Read-only |
| Team leads | opus (when needed) | Can use opus for complex orchestration |
The model selection is intentional: sonnet provides the best balance of capability and cost for most work, haiku keeps question-answering cheap and fast, and opus is reserved for complex multi-domain orchestration where the additional reasoning capability justifies the cost.
/do — Single Domain
The /do command is the primary workflow for single-domain tasks. It routes your task to the appropriate domain and orchestrates a plan-build-review-improve cycle.
/do operates in three patterns depending on the nature of the task:
Pattern A: Implementation
For tasks that require writing or modifying code. This is the full cycle.
The user has two decision points: approving the plan before implementation begins, and acknowledging the review suggestions before expertise updates. This keeps you in control while the agents do the heavy lifting.
Pattern B: Question
For tasks that are questions about the codebase rather than implementation requests. The question-agent answers directly using domain expertise and codebase context. No build or review cycle is needed.
Pattern C: Simple
For tasks like running linters, formatting code, or validating configurations. The build-agent executes the task directly without a plan or review phase. These are one-shot operations.
/do-teams — Parallel Teams
The /do-teams command spawns multiple domain specialists to work in parallel. This is the workflow for tasks that span multiple domains or require coordinated changes across the codebase.
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 environment variable. This is a Claude Code experimental feature.
/do-teams operates in two patterns:
Implementation
Spawns domain specialists who each own a set of files, work in parallel, and coordinate through a shared task list.
File ownership is enforced during parallel work: each specialist can only modify files within their domain's paths. This prevents merge conflicts and ensures clean boundaries.
Council
Spawns domain analysts for independent review. Each analyst examines the task from their domain's perspective and provides an assessment. No code is written — the output is a multi-perspective analysis.
/improve — Maintenance
The /improve command is a standalone expertise update workflow. It reviews recent work and updates domain knowledge without building anything new.
When you run /improve:
- Reviews
git logfor recent changes. - Maps changed files to domains using
domain-map.conf. - Spawns an
improve-agentfor each affected domain. - Each improve-agent reviews the changes and updates
tips.mdandexpertise.yamlwith any new knowledge.
You can also target a specific domain: /improve backend will only update the backend domain's expertise.
/improve after significant manual changes or after merging a large PR. It ensures your domain expertise stays current with the actual state of the code.
The Flywheel
CUITE is designed around a self-improvement loop. Every build cycle feeds back into the expertise system, making subsequent agent spawns smarter and more effective.
The flywheel accelerates over time. Early sessions produce generic expertise. After a few cycles, your agents know your project's specific patterns, conventions, pitfalls, and non-obvious behaviors. The expertise compounds with each iteration.
tips.md vs expertise.yaml
CUITE maintains two levels of domain knowledge. Each serves a different purpose in the injection pipeline:
| Aspect | tips.md | expertise.yaml |
|---|---|---|
| Format | Markdown bullet points | Structured YAML |
| Injection order | Injected first (fast context) | Injected second (full context) |
| Size | Compact, typically under 50 lines | Comprehensive, can be hundreds of lines |
| Content | Operational facts, gotchas, exact commands | Patterns, anti-patterns, architectural decisions, critical paths |
| Update frequency | Updated frequently as new facts are discovered | Updated after significant changes or reviews |
| Analogy | Sticky notes on your monitor | The team wiki page |
The two-tier approach ensures agents get the most critical information first (tips.md loads fast and fits in early context), with deep knowledge available when needed (expertise.yaml provides full context for complex decisions).
Expertise Injection
The inject-expertise.sh hook runs on every SubagentStart event. When Claude Code spawns a sub-agent, this hook intercepts the spawn and enriches it with domain knowledge.
The injection process:
- Match agent to domain — the hook extracts the domain name from the agent name (e.g.,
backend-build-agent→backend). - Load tips.md — injected first as fast context. These are the operational facts the agent needs immediately.
- Load expertise.yaml — injected second as comprehensive context. Contains patterns, anti-patterns, and deep domain knowledge.
- Inject into agent prompt — the knowledge is prepended to the agent's system instructions so it is available from the first token.
This happens transparently. You do not need to manually pass context to agents. The hook system handles it automatically, and agents arrive at their tasks already knowing your project's conventions and gotchas.
Hooks Overview
CUITE ships with six hooks that enforce security boundaries, track domain activity, and inject expertise. Hooks run automatically on specific Claude Code lifecycle events.
| Hook | When | What It Does |
|---|---|---|
scope-enforcement.sh |
PreToolUse | Enforces project boundaries, gates network egress against domain whitelist, triggers supply chain verification for new packages. |
validate-intent.sh |
PostToolUse | Runs syntax checks on edited shell scripts. Catches broken shell before it gets committed. |
detect-injection.sh |
PostToolUse | Scans content fetched via WebFetch for prompt injection patterns. Flags suspicious content and blocks malicious domains. |
track-learnings.sh |
PostToolUse | Records which domains were touched during the session. Used by /improve to know which domains need expertise updates. |
inject-expertise.sh |
SubagentStart | Matches spawned agent to domain and injects tips.md and expertise.yaml into the agent's context. |
session-context.sh |
SessionStart | Reports active domains, recent activity, and blacklist status at the beginning of each session. |
All hooks are shell scripts located at .claude/cuite/hooks/ and symlinked to .claude/hooks/. They are registered in .claude/settings.json.
Supply Chain Verification
When CUITE hooks detect that an agent is installing a new package (via npm, pip, cargo, go get, or similar), the scope-enforcement.sh hook prints a SUPPLY_CHAIN_CHECK marker.
This marker instructs Claude to:
- Pause the installation — do not proceed until verification is complete.
- Fetch registry metadata — use WebFetch to check the package registry (npm, PyPI, crates.io, etc.) and confirm the package exists, the version is valid, and the publisher is legitimate.
- Verify the package — check download counts, publication date, maintainer identity, and look for signs of typosquatting or malicious packages.
- Proceed or block — only install the package after verification passes. If anything looks suspicious, block the install and notify the user.
Network Egress
All network calls made by agents (via WebFetch or Bash commands that access the network) are gated against a domain whitelist defined in .claude/settings.json.
The whitelist controls which external domains agents can access. Requests to domains not on the whitelist are blocked by the scope-enforcement.sh hook. This prevents agents from:
- Exfiltrating code or secrets to unknown endpoints.
- Fetching content from untrusted sources.
- Making unintended API calls to external services.
To add a domain to the whitelist, update the relevant section in .claude/settings.json. The whitelist is project-specific and never overwritten by framework updates.
Prompt Injection Detection
After every WebFetch operation, the detect-injection.sh hook instructs Claude to review the fetched content for prompt injection red flags. This includes:
- Instructions that attempt to override Claude's system prompt or behavior.
- Content that tries to make Claude ignore safety guidelines.
- Hidden text or encoded payloads designed to manipulate agent behavior.
- Social engineering patterns ("ignore previous instructions", "you are now...", etc.).
When suspicious content is detected:
- The domain is added to
.claude/.cache/blocked-domains.txt. - The user is notified about the suspicious content.
- Future requests to that domain are blocked automatically.
This defense layer is especially important when agents fetch documentation, READMEs, or API responses from the internet, where an attacker could embed injection payloads.
Adding a New Domain
You can add a new domain to your CUITE installation either manually or by re-running /cuite-init.
Manual Setup
- Create the directory:
mkdir -p .claude/agents/experts/my-domain/ - Create
expertise.yamlwith your domain knowledge. Start with the most important patterns and anti-patterns. - Create
tips.mdwith quick operational facts — exact commands, environment variables, gotchas. - Copy the 4 agent templates from
.claude/agents/templates/and rename them with your domain prefix:cp .claude/agents/templates/*-plan-agent.md .claude/agents/experts/my-domain/my-domain-plan-agent.md cp .claude/agents/templates/*-build-agent.md .claude/agents/experts/my-domain/my-domain-build-agent.md cp .claude/agents/templates/*-improve-agent.md .claude/agents/experts/my-domain/my-domain-improve-agent.md cp .claude/agents/templates/*-question-agent.md .claude/agents/experts/my-domain/my-domain-question-agent.md - Add to
domains.mdwith a new## my-domainsection containing description, keywords, paths, language, build, and test commands. - Add path mappings to
domain-map.confso hooks can resolve files to your new domain.
Automatic Setup
Run /cuite-init again. It will detect new sub-projects and propose additional domains. Existing domains are preserved.
Writing Good Expertise
The quality of your expertise files directly determines how effective your agents are. Prioritize information that is hard-won, non-obvious, or specific to your project.
What to include
- Hard-won lessons — things that cost you debugging time.
- Exact commands — not "run the tests" but
npm test -- --coverage --watchAll=false. - Non-obvious behavior — silent failures, implicit dependencies, order-sensitive operations.
- Convention decisions — why you chose X over Y, so agents do not second-guess.
- Anti-patterns — things that look right but break in your specific context.
Bad example
testing: "Make sure to test your code"
This tells the agent nothing it does not already know. It is noise in the context window.
Good example
critical_patterns:
async_error_handling: |
CRITICAL: Express error middleware requires 4 parameters.
Missing any parameter makes Express skip the handler silently.
Always use: (err, req, res, next) => { ... }
The order matters. If you write (req, res, next, err),
Express treats it as a regular middleware and errors
will fall through to the default handler.
This is specific, actionable, and describes a silent failure mode that would waste debugging time. This is the kind of knowledge that makes agents dramatically more effective.
Settings Sync
The cuite settings command compares your project's hook configuration in .claude/settings.json against the framework's template. It ensures all hooks are wired correctly while preserving your custom permissions and whitelist settings.
Run this after pulling framework updates to ensure new hooks are registered:
cuite settings
The command will report which hooks are missing, which are outdated, and apply updates with your confirmation. Your permissions, whitelist, and other custom settings are never modified.
Pulling Updates
To pull the latest CUITE framework updates into your project:
cuite pull
This command:
- Runs
git subtree pullto update.claude/cuite/with the latest framework code. - Refreshes symlinks to ensure they point to the updated files.
- Checks settings for any new hooks that need to be registered.
Your files are never touched. settings.json, domains.md, domain-map.conf, and everything under experts/ remain exactly as you left them.
Pushing Changes
If you have forked CUITE and want to contribute improvements back to the framework:
cuite push
This command uses git subtree push to extract only the .claude/cuite/ directory and push it to the remote. Your project-specific files (settings, domains, expertise) are excluded by the subtree prefix.
cuite remote, which should point to your fork.
Conflicts
Merge conflicts during a cuite pull can only happen inside .claude/cuite/. Your project-specific files are outside the subtree and cannot conflict.
If you encounter conflicts, the simplest resolution is to accept the upstream version:
git checkout --theirs .claude/cuite/
git add .claude/cuite/
git commit -m "merge cuite updates"
This is safe because .claude/cuite/ contains only framework code. If you have made local modifications to framework files, review the conflicts manually and merge as appropriate.
Common Issues
"Agent teams not available"
Agent teams are an experimental Claude Code feature. Set the environment variable before launching Claude Code:
export CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1
"Hooks not firing"
Check that the hooks section in .claude/settings.json is properly configured. Each hook needs a matching entry with the correct event type (PreToolUse, PostToolUse, SubagentStart, or SessionStart). Run cuite settings to diagnose and fix hook wiring.
"Agent doesn't know my domain"
The agent name must contain the domain keyword for expertise injection to work. If your domain is backend, the agent must be named something like backend-build-agent. Check the agent filenames under .claude/agents/experts/{domain}/.
"Expertise not injected"
Verify that expertise.yaml exists in the domain's expert directory. The inject-expertise.sh hook looks for this file by path. Also check that the inject-expertise.sh hook is registered in settings.json under the SubagentStart event.
"/do picks wrong domain"
Add more keywords to the domain's entry in domains.md. The keyword matching is the first step in domain discovery. If your task description uses terms that are not in the keyword list, /do may route to the wrong domain or fall back to the generic agent.
"/improve doesn't find changes"
The /improve command reads git log to find recent changes. If your changes are uncommitted, /improve will not see them. Commit first, then run /improve.
FAQ
Will subtree pull overwrite my domains?
No. The subtree pull only updates files inside .claude/cuite/. Your domains.md, domain-map.conf, settings.json, and everything under experts/ are outside the subtree and are never modified by pull operations.
Will subtree push include my project files?
No. The subtree push extracts only .claude/cuite/ and sends it to the remote. Your project code, settings, and domain expertise are excluded by the subtree prefix.
Do symlinks survive git clone?
Yes. Git tracks symlinks as part of the repository. When someone clones your project, the symlinks are recreated. If any symlinks break (e.g., after a framework restructuring), run cuite link to refresh them.
How do hooks resolve paths?
All hook scripts use $PWD for path resolution. This means they work correctly regardless of where the framework subtree is located, as long as Claude Code is launched from the project root. No hardcoded paths are used anywhere in the hook system.
Cost Guide
CUITE costs depend on which workflow you use and how many agents are involved. Here are approximate costs per invocation based on typical usage:
| Action | Model | Approx. Cost |
|---|---|---|
/do question |
haiku | ~$0.01 |
/do implementation |
sonnet x3 | ~$0.10–0.30 |
/do-teams 2 teammates |
sonnet x3 | ~$0.30–0.80 |
/do-teams 3 teammates |
sonnet x4–5 | ~$0.50–1.50 |
Costs scale primarily with the number of agents spawned and the complexity of the task. Questions are cheap because they use haiku and require only one agent. Full implementation cycles cost more because they involve plan, build, review, and improve phases. Team workflows multiply the cost by the number of parallel specialists.
/do with Pattern B (question) for quick lookups and Pattern C (simple) for lint/format tasks. Reserve full Pattern A (implementation) and /do-teams for substantial work where the multi-agent cycle pays for itself in quality.